Staging: rtl8192e: remove #if 0 sections
[wandboard.git] / drivers / staging / rtl8192e / r8192E_core.c
blobe9d0a69359a6b621b8075ebf676ddb6bb76910e1
1 /******************************************************************************
2 * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
3 * Linux device driver for RTL8190P / RTL8192E
5 * Based on the r8180 driver, which is:
6 * Copyright 2004-2005 Andrea Merello <andreamrl@tiscali.it>, et al.
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of version 2 of the GNU General Public License as
9 * published by the Free Software Foundation.
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
16 * You should have received a copy of the GNU General Public License along with
17 * this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
20 * The full GNU General Public License is included in this distribution in the
21 * file called LICENSE.
23 * Contact Information:
24 * Jerry chuang <wlanfae@realtek.com>
28 #undef LOOP_TEST
29 #undef RX_DONT_PASS_UL
30 #undef DEBUG_EPROM
31 #undef DEBUG_RX_VERBOSE
32 #undef DUMMY_RX
33 #undef DEBUG_ZERO_RX
34 #undef DEBUG_RX_SKB
35 #undef DEBUG_TX_FRAG
36 #undef DEBUG_RX_FRAG
37 #undef DEBUG_TX_FILLDESC
38 #undef DEBUG_TX
39 #undef DEBUG_IRQ
40 #undef DEBUG_RX
41 #undef DEBUG_RXALLOC
42 #undef DEBUG_REGISTERS
43 #undef DEBUG_RING
44 #undef DEBUG_IRQ_TASKLET
45 #undef DEBUG_TX_ALLOC
46 #undef DEBUG_TX_DESC
48 //#define CONFIG_RTL8192_IO_MAP
49 #include <asm/uaccess.h>
50 #include "r8192E_hw.h"
51 #include "r8192E.h"
52 #include "r8190_rtl8256.h" /* RTL8225 Radio frontend */
53 #include "r8180_93cx6.h" /* Card EEPROM */
54 #include "r8192E_wx.h"
55 #include "r819xE_phy.h" //added by WB 4.30.2008
56 #include "r819xE_phyreg.h"
57 #include "r819xE_cmdpkt.h"
58 #include "r8192E_dm.h"
59 //#include "r8192xU_phyreg.h"
60 //#include <linux/usb.h>
61 // FIXME: check if 2.6.7 is ok
63 #ifdef CONFIG_PM_RTL
64 #include "r8192_pm.h"
65 #endif
67 #ifdef ENABLE_DOT11D
68 #include "dot11d.h"
69 #endif
71 //set here to open your trace code. //WB
72 u32 rt_global_debug_component = \
73 // COMP_INIT |
74 // COMP_EPROM |
75 // COMP_PHY |
76 // COMP_RF |
77 COMP_FIRMWARE |
78 // COMP_TRACE |
79 // COMP_DOWN |
80 // COMP_SWBW |
81 // COMP_SEC |
82 // COMP_QOS |
83 // COMP_RATE |
84 // COMP_RECV |
85 // COMP_SEND |
86 // COMP_POWER |
87 // COMP_EVENTS |
88 // COMP_RESET |
89 // COMP_CMDPKT |
90 // COMP_POWER_TRACKING |
91 // COMP_INTR |
92 COMP_ERR ; //always open err flags on
93 #ifndef PCI_DEVICE
94 #define PCI_DEVICE(vend,dev)\
95 .vendor=(vend),.device=(dev),\
96 .subvendor=PCI_ANY_ID,.subdevice=PCI_ANY_ID
97 #endif
98 static struct pci_device_id rtl8192_pci_id_tbl[] __devinitdata = {
99 #ifdef RTL8190P
100 /* Realtek */
101 /* Dlink */
102 { PCI_DEVICE(0x10ec, 0x8190) },
103 /* Corega */
104 { PCI_DEVICE(0x07aa, 0x0045) },
105 { PCI_DEVICE(0x07aa, 0x0046) },
106 #else
107 /* Realtek */
108 { PCI_DEVICE(0x10ec, 0x8192) },
110 /* Corega */
111 { PCI_DEVICE(0x07aa, 0x0044) },
112 { PCI_DEVICE(0x07aa, 0x0047) },
113 #endif
117 static char* ifname = "wlan%d";
118 static int hwwep = 1; //default use hw. set 0 to use software security
119 static int channels = 0x3fff;
121 MODULE_LICENSE("GPL");
122 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
123 MODULE_VERSION("V 1.1");
124 #endif
125 MODULE_DEVICE_TABLE(pci, rtl8192_pci_id_tbl);
126 //MODULE_AUTHOR("Andrea Merello <andreamrl@tiscali.it>");
127 MODULE_DESCRIPTION("Linux driver for Realtek RTL819x WiFi cards");
130 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 9)
131 module_param(ifname, charp, S_IRUGO|S_IWUSR );
132 //module_param(hwseqnum,int, S_IRUGO|S_IWUSR);
133 module_param(hwwep,int, S_IRUGO|S_IWUSR);
134 module_param(channels,int, S_IRUGO|S_IWUSR);
135 #else
136 MODULE_PARM(ifname, "s");
137 //MODULE_PARM(hwseqnum,"i");
138 MODULE_PARM(hwwep,"i");
139 MODULE_PARM(channels,"i");
140 #endif
142 MODULE_PARM_DESC(ifname," Net interface name, wlan%d=default");
143 //MODULE_PARM_DESC(hwseqnum," Try to use hardware 802.11 header sequence numbers. Zero=default");
144 MODULE_PARM_DESC(hwwep," Try to use hardware WEP support. Still broken and not available on all cards");
145 MODULE_PARM_DESC(channels," Channel bitmask for specific locales. NYI");
147 static int __devinit rtl8192_pci_probe(struct pci_dev *pdev,
148 const struct pci_device_id *id);
149 static void __devexit rtl8192_pci_disconnect(struct pci_dev *pdev);
151 static struct pci_driver rtl8192_pci_driver = {
152 .name = RTL819xE_MODULE_NAME, /* Driver name */
153 .id_table = rtl8192_pci_id_tbl, /* PCI_ID table */
154 .probe = rtl8192_pci_probe, /* probe fn */
155 .remove = __devexit_p(rtl8192_pci_disconnect), /* remove fn */
156 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0)
157 #ifdef CONFIG_PM_RTL
158 .suspend = rtl8192E_suspend, /* PM suspend fn */
159 .resume = rtl8192E_resume, /* PM resume fn */
160 #else
161 .suspend = NULL, /* PM suspend fn */
162 .resume = NULL, /* PM resume fn */
163 #endif
164 #endif
167 #ifdef ENABLE_DOT11D
169 typedef struct _CHANNEL_LIST
171 u8 Channel[32];
172 u8 Len;
173 }CHANNEL_LIST, *PCHANNEL_LIST;
175 static CHANNEL_LIST ChannelPlan[] = {
176 {{1,2,3,4,5,6,7,8,9,10,11,36,40,44,48,52,56,60,64,149,153,157,161,165},24}, //FCC
177 {{1,2,3,4,5,6,7,8,9,10,11},11}, //IC
178 {{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48,52,56,60,64},21}, //ETSI
179 {{1,2,3,4,5,6,7,8,9,10,11,12,13},13}, //Spain. Change to ETSI.
180 {{1,2,3,4,5,6,7,8,9,10,11,12,13},13}, //France. Change to ETSI.
181 {{1,2,3,4,5,6,7,8,9,10,11,12,13,14,36,40,44,48,52,56,60,64},22}, //MKK //MKK
182 {{1,2,3,4,5,6,7,8,9,10,11,12,13,14,36,40,44,48,52,56,60,64},22},//MKK1
183 {{1,2,3,4,5,6,7,8,9,10,11,12,13},13}, //Israel.
184 {{1,2,3,4,5,6,7,8,9,10,11,12,13,14,36,40,44,48,52,56,60,64},22}, // For 11a , TELEC
185 {{1,2,3,4,5,6,7,8,9,10,11,12,13,14,36,40,44,48,52,56,60,64}, 22}, //MIC
186 {{1,2,3,4,5,6,7,8,9,10,11,12,13,14},14} //For Global Domain. 1-11:active scan, 12-14 passive scan. //+YJ, 080626
189 static void rtl819x_set_channel_map(u8 channel_plan, struct r8192_priv* priv)
191 int i, max_chan=-1, min_chan=-1;
192 struct ieee80211_device* ieee = priv->ieee80211;
193 switch (channel_plan)
195 case COUNTRY_CODE_FCC:
196 case COUNTRY_CODE_IC:
197 case COUNTRY_CODE_ETSI:
198 case COUNTRY_CODE_SPAIN:
199 case COUNTRY_CODE_FRANCE:
200 case COUNTRY_CODE_MKK:
201 case COUNTRY_CODE_MKK1:
202 case COUNTRY_CODE_ISRAEL:
203 case COUNTRY_CODE_TELEC:
204 case COUNTRY_CODE_MIC:
206 Dot11d_Init(ieee);
207 ieee->bGlobalDomain = false;
208 //acturally 8225 & 8256 rf chip only support B,G,24N mode
209 if ((priv->rf_chip == RF_8225) || (priv->rf_chip == RF_8256))
211 min_chan = 1;
212 max_chan = 14;
214 else
216 RT_TRACE(COMP_ERR, "unknown rf chip, can't set channel map in function:%s()\n", __FUNCTION__);
218 if (ChannelPlan[channel_plan].Len != 0){
219 // Clear old channel map
220 memset(GET_DOT11D_INFO(ieee)->channel_map, 0, sizeof(GET_DOT11D_INFO(ieee)->channel_map));
221 // Set new channel map
222 for (i=0;i<ChannelPlan[channel_plan].Len;i++)
224 if (ChannelPlan[channel_plan].Channel[i] < min_chan || ChannelPlan[channel_plan].Channel[i] > max_chan)
225 break;
226 GET_DOT11D_INFO(ieee)->channel_map[ChannelPlan[channel_plan].Channel[i]] = 1;
229 break;
231 case COUNTRY_CODE_GLOBAL_DOMAIN:
233 GET_DOT11D_INFO(ieee)->bEnabled = 0; //this flag enabled to follow 11d country IE setting, otherwise, it shall follow global domain setting
234 Dot11d_Reset(ieee);
235 ieee->bGlobalDomain = true;
236 break;
238 default:
239 break;
242 #endif
245 #define eqMacAddr(a,b) ( ((a)[0]==(b)[0] && (a)[1]==(b)[1] && (a)[2]==(b)[2] && (a)[3]==(b)[3] && (a)[4]==(b)[4] && (a)[5]==(b)[5]) ? 1:0 )
246 /* 2007/07/25 MH Defien temp tx fw info. */
247 static TX_FWINFO_T Tmp_TxFwInfo;
250 #define rx_hal_is_cck_rate(_pdrvinfo)\
251 (_pdrvinfo->RxRate == DESC90_RATE1M ||\
252 _pdrvinfo->RxRate == DESC90_RATE2M ||\
253 _pdrvinfo->RxRate == DESC90_RATE5_5M ||\
254 _pdrvinfo->RxRate == DESC90_RATE11M) &&\
255 !_pdrvinfo->RxHT\
258 void CamResetAllEntry(struct net_device *dev)
260 //u8 ucIndex;
261 u32 ulcommand = 0;
263 #if 1
264 ulcommand |= BIT31|BIT30;
265 write_nic_dword(dev, RWCAM, ulcommand);
266 #else
267 for(ucIndex=0;ucIndex<TOTAL_CAM_ENTRY;ucIndex++)
268 CAM_mark_invalid(dev, ucIndex);
269 for(ucIndex=0;ucIndex<TOTAL_CAM_ENTRY;ucIndex++)
270 CAM_empty_entry(dev, ucIndex);
271 #endif
275 void write_cam(struct net_device *dev, u8 addr, u32 data)
277 write_nic_dword(dev, WCAMI, data);
278 write_nic_dword(dev, RWCAM, BIT31|BIT16|(addr&0xff) );
280 u32 read_cam(struct net_device *dev, u8 addr)
282 write_nic_dword(dev, RWCAM, 0x80000000|(addr&0xff) );
283 return read_nic_dword(dev, 0xa8);
286 ////////////////////////////////////////////////////////////
287 #ifdef CONFIG_RTL8180_IO_MAP
289 u8 read_nic_byte(struct net_device *dev, int x)
291 return 0xff&inb(dev->base_addr +x);
294 u32 read_nic_dword(struct net_device *dev, int x)
296 return inl(dev->base_addr +x);
299 u16 read_nic_word(struct net_device *dev, int x)
301 return inw(dev->base_addr +x);
304 void write_nic_byte(struct net_device *dev, int x,u8 y)
306 outb(y&0xff,dev->base_addr +x);
309 void write_nic_word(struct net_device *dev, int x,u16 y)
311 outw(y,dev->base_addr +x);
314 void write_nic_dword(struct net_device *dev, int x,u32 y)
316 outl(y,dev->base_addr +x);
319 #else /* RTL_IO_MAP */
321 u8 read_nic_byte(struct net_device *dev, int x)
323 return 0xff&readb((u8*)dev->mem_start +x);
326 u32 read_nic_dword(struct net_device *dev, int x)
328 return readl((u8*)dev->mem_start +x);
331 u16 read_nic_word(struct net_device *dev, int x)
333 return readw((u8*)dev->mem_start +x);
336 void write_nic_byte(struct net_device *dev, int x,u8 y)
338 writeb(y,(u8*)dev->mem_start +x);
339 udelay(20);
342 void write_nic_dword(struct net_device *dev, int x,u32 y)
344 writel(y,(u8*)dev->mem_start +x);
345 udelay(20);
348 void write_nic_word(struct net_device *dev, int x,u16 y)
350 writew(y,(u8*)dev->mem_start +x);
351 udelay(20);
354 #endif /* RTL_IO_MAP */
357 ///////////////////////////////////////////////////////////
359 //u8 read_phy_cck(struct net_device *dev, u8 adr);
360 //u8 read_phy_ofdm(struct net_device *dev, u8 adr);
361 /* this might still called in what was the PHY rtl8185/rtl8192 common code
362 * plans are to possibilty turn it again in one common code...
364 inline void force_pci_posting(struct net_device *dev)
369 //warning message WB
370 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18)
371 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
372 void rtl8192_interrupt(int irq, void *netdev, struct pt_regs *regs);
373 #else
374 irqreturn_t rtl8192_interrupt(int irq, void *netdev, struct pt_regs *regs);
375 #endif
376 #else
377 irqreturn_t rtl8192_interrupt(int irq, void *netdev);
378 #endif
379 //static struct net_device_stats *rtl8192_stats(struct net_device *dev);
380 void rtl8192_commit(struct net_device *dev);
381 //void rtl8192_restart(struct net_device *dev);
382 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
383 void rtl8192_restart(struct work_struct *work);
384 //void rtl8192_rq_tx_ack(struct work_struct *work);
385 #else
386 void rtl8192_restart(struct net_device *dev);
387 // //void rtl8192_rq_tx_ack(struct net_device *dev);
388 #endif
390 void watch_dog_timer_callback(unsigned long data);
391 #ifdef ENABLE_IPS
392 void IPSEnter(struct net_device *dev);
393 void IPSLeave(struct net_device *dev);
394 void InactivePsWorkItemCallback(struct net_device *dev);
395 #endif
396 /****************************************************************************
397 -----------------------------PROCFS STUFF-------------------------
398 *****************************************************************************/
400 static struct proc_dir_entry *rtl8192_proc = NULL;
404 static int proc_get_stats_ap(char *page, char **start,
405 off_t offset, int count,
406 int *eof, void *data)
408 struct net_device *dev = data;
409 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
410 struct ieee80211_device *ieee = priv->ieee80211;
411 struct ieee80211_network *target;
413 int len = 0;
415 list_for_each_entry(target, &ieee->network_list, list) {
417 len += snprintf(page + len, count - len,
418 "%s ", target->ssid);
420 if(target->wpa_ie_len>0 || target->rsn_ie_len>0){
421 len += snprintf(page + len, count - len,
422 "WPA\n");
424 else{
425 len += snprintf(page + len, count - len,
426 "non_WPA\n");
431 *eof = 1;
432 return len;
435 static int proc_get_registers(char *page, char **start,
436 off_t offset, int count,
437 int *eof, void *data)
439 struct net_device *dev = data;
440 // struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
442 int len = 0;
443 int i,n;
445 int max=0xff;
447 /* This dump the current register page */
448 len += snprintf(page + len, count - len,
449 "\n####################page 0##################\n ");
451 for(n=0;n<=max;)
453 //printk( "\nD: %2x> ", n);
454 len += snprintf(page + len, count - len,
455 "\nD: %2x > ",n);
457 for(i=0;i<16 && n<=max;i++,n++)
458 len += snprintf(page + len, count - len,
459 "%2x ",read_nic_byte(dev,n));
461 // printk("%2x ",read_nic_byte(dev,n));
463 len += snprintf(page + len, count - len,"\n");
464 len += snprintf(page + len, count - len,
465 "\n####################page 1##################\n ");
466 for(n=0;n<=max;)
468 //printk( "\nD: %2x> ", n);
469 len += snprintf(page + len, count - len,
470 "\nD: %2x > ",n);
472 for(i=0;i<16 && n<=max;i++,n++)
473 len += snprintf(page + len, count - len,
474 "%2x ",read_nic_byte(dev,0x100|n));
476 // printk("%2x ",read_nic_byte(dev,n));
479 len += snprintf(page + len, count - len,
480 "\n####################page 3##################\n ");
481 for(n=0;n<=max;)
483 //printk( "\nD: %2x> ", n);
484 len += snprintf(page + len, count - len,
485 "\nD: %2x > ",n);
487 for(i=0;i<16 && n<=max;i++,n++)
488 len += snprintf(page + len, count - len,
489 "%2x ",read_nic_byte(dev,0x300|n));
491 // printk("%2x ",read_nic_byte(dev,n));
495 *eof = 1;
496 return len;
502 static int proc_get_stats_tx(char *page, char **start,
503 off_t offset, int count,
504 int *eof, void *data)
506 struct net_device *dev = data;
507 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
509 int len = 0;
511 len += snprintf(page + len, count - len,
512 "TX VI priority ok int: %lu\n"
513 // "TX VI priority error int: %lu\n"
514 "TX VO priority ok int: %lu\n"
515 // "TX VO priority error int: %lu\n"
516 "TX BE priority ok int: %lu\n"
517 // "TX BE priority error int: %lu\n"
518 "TX BK priority ok int: %lu\n"
519 // "TX BK priority error int: %lu\n"
520 "TX MANAGE priority ok int: %lu\n"
521 // "TX MANAGE priority error int: %lu\n"
522 "TX BEACON priority ok int: %lu\n"
523 "TX BEACON priority error int: %lu\n"
524 "TX CMDPKT priority ok int: %lu\n"
525 // "TX high priority ok int: %lu\n"
526 // "TX high priority failed error int: %lu\n"
527 // "TX queue resume: %lu\n"
528 "TX queue stopped?: %d\n"
529 "TX fifo overflow: %lu\n"
530 // "TX beacon: %lu\n"
531 // "TX VI queue: %d\n"
532 // "TX VO queue: %d\n"
533 // "TX BE queue: %d\n"
534 // "TX BK queue: %d\n"
535 // "TX HW queue: %d\n"
536 // "TX VI dropped: %lu\n"
537 // "TX VO dropped: %lu\n"
538 // "TX BE dropped: %lu\n"
539 // "TX BK dropped: %lu\n"
540 "TX total data packets %lu\n"
541 "TX total data bytes :%lu\n",
542 // "TX beacon aborted: %lu\n",
543 priv->stats.txviokint,
544 // priv->stats.txvierr,
545 priv->stats.txvookint,
546 // priv->stats.txvoerr,
547 priv->stats.txbeokint,
548 // priv->stats.txbeerr,
549 priv->stats.txbkokint,
550 // priv->stats.txbkerr,
551 priv->stats.txmanageokint,
552 // priv->stats.txmanageerr,
553 priv->stats.txbeaconokint,
554 priv->stats.txbeaconerr,
555 priv->stats.txcmdpktokint,
556 // priv->stats.txhpokint,
557 // priv->stats.txhperr,
558 // priv->stats.txresumed,
559 netif_queue_stopped(dev),
560 priv->stats.txoverflow,
561 // priv->stats.txbeacon,
562 // atomic_read(&(priv->tx_pending[VI_QUEUE])),
563 // atomic_read(&(priv->tx_pending[VO_QUEUE])),
564 // atomic_read(&(priv->tx_pending[BE_QUEUE])),
565 // atomic_read(&(priv->tx_pending[BK_QUEUE])),
566 // read_nic_byte(dev, TXFIFOCOUNT),
567 // priv->stats.txvidrop,
568 // priv->stats.txvodrop,
569 priv->ieee80211->stats.tx_packets,
570 priv->ieee80211->stats.tx_bytes
573 // priv->stats.txbedrop,
574 // priv->stats.txbkdrop
575 // priv->stats.txdatapkt
576 // priv->stats.txbeaconerr
579 *eof = 1;
580 return len;
585 static int proc_get_stats_rx(char *page, char **start,
586 off_t offset, int count,
587 int *eof, void *data)
589 struct net_device *dev = data;
590 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
592 int len = 0;
594 len += snprintf(page + len, count - len,
595 "RX packets: %lu\n"
596 "RX desc err: %lu\n"
597 "RX rx overflow error: %lu\n"
598 "RX invalid urb error: %lu\n",
599 priv->stats.rxint,
600 priv->stats.rxrdu,
601 priv->stats.rxoverflow,
602 priv->stats.rxurberr);
604 *eof = 1;
605 return len;
608 static void rtl8192_proc_module_init(void)
610 RT_TRACE(COMP_INIT, "Initializing proc filesystem");
611 #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24))
612 rtl8192_proc=create_proc_entry(RTL819xE_MODULE_NAME, S_IFDIR, proc_net);
613 #else
614 rtl8192_proc=create_proc_entry(RTL819xE_MODULE_NAME, S_IFDIR, init_net.proc_net);
615 #endif
619 static void rtl8192_proc_module_remove(void)
621 #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24))
622 remove_proc_entry(RTL819xE_MODULE_NAME, proc_net);
623 #else
624 remove_proc_entry(RTL819xE_MODULE_NAME, init_net.proc_net);
625 #endif
629 static void rtl8192_proc_remove_one(struct net_device *dev)
631 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
633 printk("dev name=======> %s\n",dev->name);
635 if (priv->dir_dev) {
636 // remove_proc_entry("stats-hw", priv->dir_dev);
637 remove_proc_entry("stats-tx", priv->dir_dev);
638 remove_proc_entry("stats-rx", priv->dir_dev);
639 // remove_proc_entry("stats-ieee", priv->dir_dev);
640 remove_proc_entry("stats-ap", priv->dir_dev);
641 remove_proc_entry("registers", priv->dir_dev);
642 // remove_proc_entry("cck-registers",priv->dir_dev);
643 // remove_proc_entry("ofdm-registers",priv->dir_dev);
644 //remove_proc_entry(dev->name, rtl8192_proc);
645 remove_proc_entry("wlan0", rtl8192_proc);
646 priv->dir_dev = NULL;
651 static void rtl8192_proc_init_one(struct net_device *dev)
653 struct proc_dir_entry *e;
654 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
655 priv->dir_dev = create_proc_entry(dev->name,
656 S_IFDIR | S_IRUGO | S_IXUGO,
657 rtl8192_proc);
658 if (!priv->dir_dev) {
659 RT_TRACE(COMP_ERR, "Unable to initialize /proc/net/rtl8192/%s\n",
660 dev->name);
661 return;
663 e = create_proc_read_entry("stats-rx", S_IFREG | S_IRUGO,
664 priv->dir_dev, proc_get_stats_rx, dev);
666 if (!e) {
667 RT_TRACE(COMP_ERR,"Unable to initialize "
668 "/proc/net/rtl8192/%s/stats-rx\n",
669 dev->name);
673 e = create_proc_read_entry("stats-tx", S_IFREG | S_IRUGO,
674 priv->dir_dev, proc_get_stats_tx, dev);
676 if (!e) {
677 RT_TRACE(COMP_ERR, "Unable to initialize "
678 "/proc/net/rtl8192/%s/stats-tx\n",
679 dev->name);
682 e = create_proc_read_entry("stats-ap", S_IFREG | S_IRUGO,
683 priv->dir_dev, proc_get_stats_ap, dev);
685 if (!e) {
686 RT_TRACE(COMP_ERR, "Unable to initialize "
687 "/proc/net/rtl8192/%s/stats-ap\n",
688 dev->name);
691 e = create_proc_read_entry("registers", S_IFREG | S_IRUGO,
692 priv->dir_dev, proc_get_registers, dev);
693 if (!e) {
694 RT_TRACE(COMP_ERR, "Unable to initialize "
695 "/proc/net/rtl8192/%s/registers\n",
696 dev->name);
699 /****************************************************************************
700 -----------------------------MISC STUFF-------------------------
701 *****************************************************************************/
703 short check_nic_enough_desc(struct net_device *dev, int prio)
705 struct r8192_priv *priv = ieee80211_priv(dev);
706 struct rtl8192_tx_ring *ring = &priv->tx_ring[prio];
708 /* for now we reserve two free descriptor as a safety boundary
709 * between the tail and the head
711 if (ring->entries - skb_queue_len(&ring->queue) >= 2) {
712 return 1;
713 } else {
714 return 0;
718 static void tx_timeout(struct net_device *dev)
720 struct r8192_priv *priv = ieee80211_priv(dev);
721 //rtl8192_commit(dev);
723 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
724 schedule_work(&priv->reset_wq);
725 #else
726 schedule_task(&priv->reset_wq);
727 #endif
728 printk("TXTIMEOUT");
732 /****************************************************************************
733 ------------------------------HW STUFF---------------------------
734 *****************************************************************************/
737 static void rtl8192_irq_enable(struct net_device *dev)
739 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
740 priv->irq_enabled = 1;
741 write_nic_dword(dev,INTA_MASK, priv->irq_mask);
745 static void rtl8192_irq_disable(struct net_device *dev)
747 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
749 write_nic_dword(dev,INTA_MASK,0);
750 force_pci_posting(dev);
751 priv->irq_enabled = 0;
755 static void rtl8192_set_mode(struct net_device *dev,int mode)
757 u8 ecmd;
758 ecmd=read_nic_byte(dev, EPROM_CMD);
759 ecmd=ecmd &~ EPROM_CMD_OPERATING_MODE_MASK;
760 ecmd=ecmd | (mode<<EPROM_CMD_OPERATING_MODE_SHIFT);
761 ecmd=ecmd &~ (1<<EPROM_CS_SHIFT);
762 ecmd=ecmd &~ (1<<EPROM_CK_SHIFT);
763 write_nic_byte(dev, EPROM_CMD, ecmd);
767 void rtl8192_update_msr(struct net_device *dev)
769 struct r8192_priv *priv = ieee80211_priv(dev);
770 u8 msr;
772 msr = read_nic_byte(dev, MSR);
773 msr &= ~ MSR_LINK_MASK;
775 /* do not change in link_state != WLAN_LINK_ASSOCIATED.
776 * msr must be updated if the state is ASSOCIATING.
777 * this is intentional and make sense for ad-hoc and
778 * master (see the create BSS/IBSS func)
780 if (priv->ieee80211->state == IEEE80211_LINKED){
782 if (priv->ieee80211->iw_mode == IW_MODE_INFRA)
783 msr |= (MSR_LINK_MANAGED<<MSR_LINK_SHIFT);
784 else if (priv->ieee80211->iw_mode == IW_MODE_ADHOC)
785 msr |= (MSR_LINK_ADHOC<<MSR_LINK_SHIFT);
786 else if (priv->ieee80211->iw_mode == IW_MODE_MASTER)
787 msr |= (MSR_LINK_MASTER<<MSR_LINK_SHIFT);
789 }else
790 msr |= (MSR_LINK_NONE<<MSR_LINK_SHIFT);
792 write_nic_byte(dev, MSR, msr);
795 void rtl8192_set_chan(struct net_device *dev,short ch)
797 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
798 RT_TRACE(COMP_RF, "=====>%s()====ch:%d\n", __FUNCTION__, ch);
799 priv->chan=ch;
800 #if 0
801 if(priv->ieee80211->iw_mode == IW_MODE_ADHOC ||
802 priv->ieee80211->iw_mode == IW_MODE_MASTER){
804 priv->ieee80211->link_state = WLAN_LINK_ASSOCIATED;
805 priv->ieee80211->master_chan = ch;
806 rtl8192_update_beacon_ch(dev);
808 #endif
810 /* this hack should avoid frame TX during channel setting*/
813 // tx = read_nic_dword(dev,TX_CONF);
814 // tx &= ~TX_LOOPBACK_MASK;
816 #ifndef LOOP_TEST
817 //TODO
818 // write_nic_dword(dev,TX_CONF, tx |( TX_LOOPBACK_MAC<<TX_LOOPBACK_SHIFT));
820 //need to implement rf set channel here WB
822 if (priv->rf_set_chan)
823 priv->rf_set_chan(dev,priv->chan);
824 // mdelay(10);
825 // write_nic_dword(dev,TX_CONF,tx | (TX_LOOPBACK_NONE<<TX_LOOPBACK_SHIFT));
826 #endif
829 void rtl8192_rx_enable(struct net_device *dev)
831 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
832 write_nic_dword(dev, RDQDA,priv->rx_ring_dma);
835 /* the TX_DESC_BASE setting is according to the following queue index
836 * BK_QUEUE ===> 0
837 * BE_QUEUE ===> 1
838 * VI_QUEUE ===> 2
839 * VO_QUEUE ===> 3
840 * HCCA_QUEUE ===> 4
841 * TXCMD_QUEUE ===> 5
842 * MGNT_QUEUE ===> 6
843 * HIGH_QUEUE ===> 7
844 * BEACON_QUEUE ===> 8
845 * */
846 static u32 TX_DESC_BASE[] = {BKQDA, BEQDA, VIQDA, VOQDA, HCCAQDA, CQDA, MQDA, HQDA, BQDA};
847 void rtl8192_tx_enable(struct net_device *dev)
849 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
850 u32 i;
851 for (i = 0; i < MAX_TX_QUEUE_COUNT; i++)
852 write_nic_dword(dev, TX_DESC_BASE[i], priv->tx_ring[i].dma);
854 ieee80211_reset_queue(priv->ieee80211);
858 static void rtl8192_free_rx_ring(struct net_device *dev)
860 struct r8192_priv *priv = ieee80211_priv(dev);
861 int i;
863 for (i = 0; i < priv->rxringcount; i++) {
864 struct sk_buff *skb = priv->rx_buf[i];
865 if (!skb)
866 continue;
868 pci_unmap_single(priv->pdev,
869 *((dma_addr_t *)skb->cb),
870 priv->rxbuffersize, PCI_DMA_FROMDEVICE);
871 kfree_skb(skb);
874 pci_free_consistent(priv->pdev, sizeof(*priv->rx_ring) * priv->rxringcount,
875 priv->rx_ring, priv->rx_ring_dma);
876 priv->rx_ring = NULL;
879 static void rtl8192_free_tx_ring(struct net_device *dev, unsigned int prio)
881 struct r8192_priv *priv = ieee80211_priv(dev);
882 struct rtl8192_tx_ring *ring = &priv->tx_ring[prio];
884 while (skb_queue_len(&ring->queue)) {
885 tx_desc_819x_pci *entry = &ring->desc[ring->idx];
886 struct sk_buff *skb = __skb_dequeue(&ring->queue);
888 pci_unmap_single(priv->pdev, le32_to_cpu(entry->TxBuffAddr),
889 skb->len, PCI_DMA_TODEVICE);
890 kfree_skb(skb);
891 ring->idx = (ring->idx + 1) % ring->entries;
894 pci_free_consistent(priv->pdev, sizeof(*ring->desc)*ring->entries,
895 ring->desc, ring->dma);
896 ring->desc = NULL;
900 static void rtl8192_beacon_disable(struct net_device *dev)
902 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
903 u32 reg;
905 reg = read_nic_dword(priv->ieee80211->dev,INTA_MASK);
907 /* disable Beacon realted interrupt signal */
908 reg &= ~(IMR_BcnInt | IMR_BcnInt | IMR_TBDOK | IMR_TBDER);
909 write_nic_dword(priv->ieee80211->dev, INTA_MASK, reg);
912 void rtl8192_rtx_disable(struct net_device *dev)
914 u8 cmd;
915 struct r8192_priv *priv = ieee80211_priv(dev);
916 int i;
918 cmd=read_nic_byte(dev,CMDR);
919 // if(!priv->ieee80211->bSupportRemoteWakeUp) {
920 write_nic_byte(dev, CMDR, cmd &~ \
921 (CR_TE|CR_RE));
922 // }
923 force_pci_posting(dev);
924 mdelay(30);
926 for(i = 0; i < MAX_QUEUE_SIZE; i++) {
927 skb_queue_purge(&priv->ieee80211->skb_waitQ [i]);
929 for(i = 0; i < MAX_QUEUE_SIZE; i++) {
930 skb_queue_purge(&priv->ieee80211->skb_aggQ [i]);
934 skb_queue_purge(&priv->skb_queue);
935 return;
938 static void rtl8192_reset(struct net_device *dev)
940 rtl8192_irq_disable(dev);
941 printk("This is RTL819xP Reset procedure\n");
944 static u16 rtl_rate[] = {10,20,55,110,60,90,120,180,240,360,480,540};
945 inline u16 rtl8192_rate2rate(short rate)
947 if (rate >11) return 0;
948 return rtl_rate[rate];
954 static void rtl8192_data_hard_stop(struct net_device *dev)
956 //FIXME !!
957 #if 0
958 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
959 priv->dma_poll_mask |= (1<<TX_DMA_STOP_LOWPRIORITY_SHIFT);
960 rtl8192_set_mode(dev,EPROM_CMD_CONFIG);
961 write_nic_byte(dev,TX_DMA_POLLING,priv->dma_poll_mask);
962 rtl8192_set_mode(dev,EPROM_CMD_NORMAL);
963 #endif
967 static void rtl8192_data_hard_resume(struct net_device *dev)
969 // FIXME !!
970 #if 0
971 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
972 priv->dma_poll_mask &= ~(1<<TX_DMA_STOP_LOWPRIORITY_SHIFT);
973 rtl8192_set_mode(dev,EPROM_CMD_CONFIG);
974 write_nic_byte(dev,TX_DMA_POLLING,priv->dma_poll_mask);
975 rtl8192_set_mode(dev,EPROM_CMD_NORMAL);
976 #endif
979 /* this function TX data frames when the ieee80211 stack requires this.
980 * It checks also if we need to stop the ieee tx queue, eventually do it
982 static void rtl8192_hard_data_xmit(struct sk_buff *skb, struct net_device *dev, int rate)
984 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
985 int ret;
986 //unsigned long flags;
987 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
988 u8 queue_index = tcb_desc->queue_index;
989 /* shall not be referred by command packet */
990 assert(queue_index != TXCMD_QUEUE);
992 //spin_lock_irqsave(&priv->tx_lock,flags);
994 memcpy((unsigned char *)(skb->cb),&dev,sizeof(dev));
995 #if 0
996 tcb_desc->RATRIndex = 7;
997 tcb_desc->bTxDisableRateFallBack = 1;
998 tcb_desc->bTxUseDriverAssingedRate = 1;
999 tcb_desc->bTxEnableFwCalcDur = 1;
1000 #endif
1001 skb_push(skb, priv->ieee80211->tx_headroom);
1002 ret = rtl8192_tx(dev, skb);
1003 if(ret != 0) {
1004 kfree_skb(skb);
1008 if(queue_index!=MGNT_QUEUE) {
1009 priv->ieee80211->stats.tx_bytes+=(skb->len - priv->ieee80211->tx_headroom);
1010 priv->ieee80211->stats.tx_packets++;
1013 //spin_unlock_irqrestore(&priv->tx_lock,flags);
1015 // return ret;
1016 return;
1019 /* This is a rough attempt to TX a frame
1020 * This is called by the ieee 80211 stack to TX management frames.
1021 * If the ring is full packet are dropped (for data frame the queue
1022 * is stopped before this can happen).
1024 static int rtl8192_hard_start_xmit(struct sk_buff *skb,struct net_device *dev)
1026 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1029 int ret;
1030 //unsigned long flags;
1031 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1032 u8 queue_index = tcb_desc->queue_index;
1035 //spin_lock_irqsave(&priv->tx_lock,flags);
1037 memcpy((unsigned char *)(skb->cb),&dev,sizeof(dev));
1038 if(queue_index == TXCMD_QUEUE) {
1039 // skb_push(skb, USB_HWDESC_HEADER_LEN);
1040 rtl819xE_tx_cmd(dev, skb);
1041 ret = 0;
1042 //spin_unlock_irqrestore(&priv->tx_lock,flags);
1043 return ret;
1044 } else {
1045 // RT_TRACE(COMP_SEND, "To send management packet\n");
1046 tcb_desc->RATRIndex = 7;
1047 tcb_desc->bTxDisableRateFallBack = 1;
1048 tcb_desc->bTxUseDriverAssingedRate = 1;
1049 tcb_desc->bTxEnableFwCalcDur = 1;
1050 skb_push(skb, priv->ieee80211->tx_headroom);
1051 ret = rtl8192_tx(dev, skb);
1052 if(ret != 0) {
1053 kfree_skb(skb);
1057 // priv->ieee80211->stats.tx_bytes+=skb->len;
1058 // priv->ieee80211->stats.tx_packets++;
1060 //spin_unlock_irqrestore(&priv->tx_lock,flags);
1062 return ret;
1067 void rtl8192_try_wake_queue(struct net_device *dev, int pri);
1069 static void rtl8192_tx_isr(struct net_device *dev, int prio)
1071 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1073 struct rtl8192_tx_ring *ring = &priv->tx_ring[prio];
1075 while (skb_queue_len(&ring->queue)) {
1076 tx_desc_819x_pci *entry = &ring->desc[ring->idx];
1077 struct sk_buff *skb;
1079 /* beacon packet will only use the first descriptor defautly,
1080 * and the OWN may not be cleared by the hardware
1081 * */
1082 if(prio != BEACON_QUEUE) {
1083 if(entry->OWN)
1084 return;
1085 ring->idx = (ring->idx + 1) % ring->entries;
1088 skb = __skb_dequeue(&ring->queue);
1089 pci_unmap_single(priv->pdev, le32_to_cpu(entry->TxBuffAddr),
1090 skb->len, PCI_DMA_TODEVICE);
1092 kfree_skb(skb);
1094 if (prio == MGNT_QUEUE){
1095 if (priv->ieee80211->ack_tx_to_ieee){
1096 if (rtl8192_is_tx_queue_empty(dev)){
1097 priv->ieee80211->ack_tx_to_ieee = 0;
1098 ieee80211_ps_tx_ack(priv->ieee80211, 1);
1103 if(prio != BEACON_QUEUE) {
1104 /* try to deal with the pending packets */
1105 tasklet_schedule(&priv->irq_tx_tasklet);
1110 static void rtl8192_stop_beacon(struct net_device *dev)
1112 //rtl8192_beacon_disable(dev);
1115 static void rtl8192_config_rate(struct net_device* dev, u16* rate_config)
1117 struct r8192_priv *priv = ieee80211_priv(dev);
1118 struct ieee80211_network *net;
1119 u8 i=0, basic_rate = 0;
1120 net = & priv->ieee80211->current_network;
1122 for (i=0; i<net->rates_len; i++)
1124 basic_rate = net->rates[i]&0x7f;
1125 switch(basic_rate)
1127 case MGN_1M: *rate_config |= RRSR_1M; break;
1128 case MGN_2M: *rate_config |= RRSR_2M; break;
1129 case MGN_5_5M: *rate_config |= RRSR_5_5M; break;
1130 case MGN_11M: *rate_config |= RRSR_11M; break;
1131 case MGN_6M: *rate_config |= RRSR_6M; break;
1132 case MGN_9M: *rate_config |= RRSR_9M; break;
1133 case MGN_12M: *rate_config |= RRSR_12M; break;
1134 case MGN_18M: *rate_config |= RRSR_18M; break;
1135 case MGN_24M: *rate_config |= RRSR_24M; break;
1136 case MGN_36M: *rate_config |= RRSR_36M; break;
1137 case MGN_48M: *rate_config |= RRSR_48M; break;
1138 case MGN_54M: *rate_config |= RRSR_54M; break;
1141 for (i=0; i<net->rates_ex_len; i++)
1143 basic_rate = net->rates_ex[i]&0x7f;
1144 switch(basic_rate)
1146 case MGN_1M: *rate_config |= RRSR_1M; break;
1147 case MGN_2M: *rate_config |= RRSR_2M; break;
1148 case MGN_5_5M: *rate_config |= RRSR_5_5M; break;
1149 case MGN_11M: *rate_config |= RRSR_11M; break;
1150 case MGN_6M: *rate_config |= RRSR_6M; break;
1151 case MGN_9M: *rate_config |= RRSR_9M; break;
1152 case MGN_12M: *rate_config |= RRSR_12M; break;
1153 case MGN_18M: *rate_config |= RRSR_18M; break;
1154 case MGN_24M: *rate_config |= RRSR_24M; break;
1155 case MGN_36M: *rate_config |= RRSR_36M; break;
1156 case MGN_48M: *rate_config |= RRSR_48M; break;
1157 case MGN_54M: *rate_config |= RRSR_54M; break;
1163 #define SHORT_SLOT_TIME 9
1164 #define NON_SHORT_SLOT_TIME 20
1166 static void rtl8192_update_cap(struct net_device* dev, u16 cap)
1168 u32 tmp = 0;
1169 struct r8192_priv *priv = ieee80211_priv(dev);
1170 struct ieee80211_network *net = &priv->ieee80211->current_network;
1171 priv->short_preamble = cap & WLAN_CAPABILITY_SHORT_PREAMBLE;
1172 tmp = priv->basic_rate;
1173 if (priv->short_preamble)
1174 tmp |= BRSR_AckShortPmb;
1175 write_nic_dword(dev, RRSR, tmp);
1177 if (net->mode & (IEEE_G|IEEE_N_24G))
1179 u8 slot_time = 0;
1180 if ((cap & WLAN_CAPABILITY_SHORT_SLOT)&&(!priv->ieee80211->pHTInfo->bCurrentRT2RTLongSlotTime))
1181 {//short slot time
1182 slot_time = SHORT_SLOT_TIME;
1184 else //long slot time
1185 slot_time = NON_SHORT_SLOT_TIME;
1186 priv->slot_time = slot_time;
1187 write_nic_byte(dev, SLOT_TIME, slot_time);
1192 static void rtl8192_net_update(struct net_device *dev)
1195 struct r8192_priv *priv = ieee80211_priv(dev);
1196 struct ieee80211_network *net;
1197 u16 BcnTimeCfg = 0, BcnCW = 6, BcnIFS = 0xf;
1198 u16 rate_config = 0;
1199 net = &priv->ieee80211->current_network;
1200 //update Basic rate: RR, BRSR
1201 rtl8192_config_rate(dev, &rate_config);
1202 // 2007.01.16, by Emily
1203 // Select RRSR (in Legacy-OFDM and CCK)
1204 // For 8190, we select only 24M, 12M, 6M, 11M, 5.5M, 2M, and 1M from the Basic rate.
1205 // We do not use other rates.
1206 priv->basic_rate = rate_config &= 0x15f;
1207 //BSSID
1208 write_nic_dword(dev,BSSIDR,((u32*)net->bssid)[0]);
1209 write_nic_word(dev,BSSIDR+4,((u16*)net->bssid)[2]);
1210 #if 0
1211 //MSR
1212 rtl8192_update_msr(dev);
1213 #endif
1216 // rtl8192_update_cap(dev, net->capability);
1217 if (priv->ieee80211->iw_mode == IW_MODE_ADHOC)
1219 write_nic_word(dev, ATIMWND, 2);
1220 write_nic_word(dev, BCN_DMATIME, 256);
1221 write_nic_word(dev, BCN_INTERVAL, net->beacon_interval);
1222 // write_nic_word(dev, BcnIntTime, 100);
1223 //BIT15 of BCN_DRV_EARLY_INT will indicate whether software beacon or hw beacon is applied.
1224 write_nic_word(dev, BCN_DRV_EARLY_INT, 10);
1225 write_nic_byte(dev, BCN_ERR_THRESH, 100);
1227 BcnTimeCfg |= (BcnCW<<BCN_TCFG_CW_SHIFT);
1228 // TODO: BcnIFS may required to be changed on ASIC
1229 BcnTimeCfg |= BcnIFS<<BCN_TCFG_IFS;
1231 write_nic_word(dev, BCN_TCFG, BcnTimeCfg);
1237 void rtl819xE_tx_cmd(struct net_device *dev, struct sk_buff *skb)
1239 struct r8192_priv *priv = ieee80211_priv(dev);
1240 struct rtl8192_tx_ring *ring;
1241 tx_desc_819x_pci *entry;
1242 unsigned int idx;
1243 dma_addr_t mapping;
1244 cb_desc *tcb_desc;
1245 unsigned long flags;
1247 ring = &priv->tx_ring[TXCMD_QUEUE];
1248 mapping = pci_map_single(priv->pdev, skb->data, skb->len, PCI_DMA_TODEVICE);
1250 spin_lock_irqsave(&priv->irq_th_lock,flags);
1251 idx = (ring->idx + skb_queue_len(&ring->queue)) % ring->entries;
1252 entry = &ring->desc[idx];
1254 tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1255 memset(entry,0,12);
1256 entry->LINIP = tcb_desc->bLastIniPkt;
1257 entry->FirstSeg = 1;//first segment
1258 entry->LastSeg = 1; //last segment
1259 if(tcb_desc->bCmdOrInit == DESC_PACKET_TYPE_INIT) {
1260 entry->CmdInit = DESC_PACKET_TYPE_INIT;
1261 } else {
1262 entry->CmdInit = DESC_PACKET_TYPE_NORMAL;
1263 entry->Offset = sizeof(TX_FWINFO_8190PCI) + 8;
1264 entry->PktSize = (u16)(tcb_desc->pkt_size + entry->Offset);
1265 entry->QueueSelect = QSLT_CMD;
1266 entry->TxFWInfoSize = 0x08;
1267 entry->RATid = (u8)DESC_PACKET_TYPE_INIT;
1269 entry->TxBufferSize = skb->len;
1270 entry->TxBuffAddr = cpu_to_le32(mapping);
1271 entry->OWN = 1;
1273 #ifdef JOHN_DUMP_TXDESC
1274 { int i;
1275 tx_desc_819x_pci *entry1 = &ring->desc[0];
1276 unsigned int *ptr= (unsigned int *)entry1;
1277 printk("<Tx descriptor>:\n");
1278 for (i = 0; i < 8; i++)
1279 printk("%8x ", ptr[i]);
1280 printk("\n");
1282 #endif
1283 __skb_queue_tail(&ring->queue, skb);
1284 spin_unlock_irqrestore(&priv->irq_th_lock,flags);
1286 write_nic_byte(dev, TPPoll, TPPoll_CQ);
1288 return;
1292 * Mapping Software/Hardware descriptor queue id to "Queue Select Field"
1293 * in TxFwInfo data structure
1294 * 2006.10.30 by Emily
1296 * \param QUEUEID Software Queue
1298 static u8 MapHwQueueToFirmwareQueue(u8 QueueID)
1300 u8 QueueSelect = 0x0; //defualt set to
1302 switch(QueueID) {
1303 case BE_QUEUE:
1304 QueueSelect = QSLT_BE; //or QSelect = pTcb->priority;
1305 break;
1307 case BK_QUEUE:
1308 QueueSelect = QSLT_BK; //or QSelect = pTcb->priority;
1309 break;
1311 case VO_QUEUE:
1312 QueueSelect = QSLT_VO; //or QSelect = pTcb->priority;
1313 break;
1315 case VI_QUEUE:
1316 QueueSelect = QSLT_VI; //or QSelect = pTcb->priority;
1317 break;
1318 case MGNT_QUEUE:
1319 QueueSelect = QSLT_MGNT;
1320 break;
1322 case BEACON_QUEUE:
1323 QueueSelect = QSLT_BEACON;
1324 break;
1326 // TODO: 2006.10.30 mark other queue selection until we verify it is OK
1327 // TODO: Remove Assertions
1328 //#if (RTL819X_FPGA_VER & RTL819X_FPGA_GUANGAN_070502)
1329 case TXCMD_QUEUE:
1330 QueueSelect = QSLT_CMD;
1331 break;
1332 //#endif
1333 case HIGH_QUEUE:
1334 //QueueSelect = QSLT_HIGH;
1335 //break;
1337 default:
1338 RT_TRACE(COMP_ERR, "TransmitTCB(): Impossible Queue Selection: %d \n", QueueID);
1339 break;
1341 return QueueSelect;
1344 static u8 MRateToHwRate8190Pci(u8 rate)
1346 u8 ret = DESC90_RATE1M;
1348 switch(rate) {
1349 case MGN_1M: ret = DESC90_RATE1M; break;
1350 case MGN_2M: ret = DESC90_RATE2M; break;
1351 case MGN_5_5M: ret = DESC90_RATE5_5M; break;
1352 case MGN_11M: ret = DESC90_RATE11M; break;
1353 case MGN_6M: ret = DESC90_RATE6M; break;
1354 case MGN_9M: ret = DESC90_RATE9M; break;
1355 case MGN_12M: ret = DESC90_RATE12M; break;
1356 case MGN_18M: ret = DESC90_RATE18M; break;
1357 case MGN_24M: ret = DESC90_RATE24M; break;
1358 case MGN_36M: ret = DESC90_RATE36M; break;
1359 case MGN_48M: ret = DESC90_RATE48M; break;
1360 case MGN_54M: ret = DESC90_RATE54M; break;
1362 // HT rate since here
1363 case MGN_MCS0: ret = DESC90_RATEMCS0; break;
1364 case MGN_MCS1: ret = DESC90_RATEMCS1; break;
1365 case MGN_MCS2: ret = DESC90_RATEMCS2; break;
1366 case MGN_MCS3: ret = DESC90_RATEMCS3; break;
1367 case MGN_MCS4: ret = DESC90_RATEMCS4; break;
1368 case MGN_MCS5: ret = DESC90_RATEMCS5; break;
1369 case MGN_MCS6: ret = DESC90_RATEMCS6; break;
1370 case MGN_MCS7: ret = DESC90_RATEMCS7; break;
1371 case MGN_MCS8: ret = DESC90_RATEMCS8; break;
1372 case MGN_MCS9: ret = DESC90_RATEMCS9; break;
1373 case MGN_MCS10: ret = DESC90_RATEMCS10; break;
1374 case MGN_MCS11: ret = DESC90_RATEMCS11; break;
1375 case MGN_MCS12: ret = DESC90_RATEMCS12; break;
1376 case MGN_MCS13: ret = DESC90_RATEMCS13; break;
1377 case MGN_MCS14: ret = DESC90_RATEMCS14; break;
1378 case MGN_MCS15: ret = DESC90_RATEMCS15; break;
1379 case (0x80|0x20): ret = DESC90_RATEMCS32; break;
1381 default: break;
1383 return ret;
1387 static u8 QueryIsShort(u8 TxHT, u8 TxRate, cb_desc *tcb_desc)
1389 u8 tmp_Short;
1391 tmp_Short = (TxHT==1)?((tcb_desc->bUseShortGI)?1:0):((tcb_desc->bUseShortPreamble)?1:0);
1393 if(TxHT==1 && TxRate != DESC90_RATEMCS15)
1394 tmp_Short = 0;
1396 return tmp_Short;
1400 * The tx procedure is just as following,
1401 * skb->cb will contain all the following information,
1402 * priority, morefrag, rate, &dev.
1403 * */
1404 short rtl8192_tx(struct net_device *dev, struct sk_buff* skb)
1406 struct r8192_priv *priv = ieee80211_priv(dev);
1407 struct rtl8192_tx_ring *ring;
1408 unsigned long flags;
1409 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1410 tx_desc_819x_pci *pdesc = NULL;
1411 TX_FWINFO_8190PCI *pTxFwInfo = NULL;
1412 dma_addr_t mapping;
1413 bool multi_addr=false,broad_addr=false,uni_addr=false;
1414 u8* pda_addr = NULL;
1415 int idx;
1417 mapping = pci_map_single(priv->pdev, skb->data, skb->len, PCI_DMA_TODEVICE);
1418 /* collect the tx packets statitcs */
1419 pda_addr = ((u8*)skb->data) + sizeof(TX_FWINFO_8190PCI);
1420 if(is_multicast_ether_addr(pda_addr))
1421 multi_addr = true;
1422 else if(is_broadcast_ether_addr(pda_addr))
1423 broad_addr = true;
1424 else
1425 uni_addr = true;
1427 if(uni_addr)
1428 priv->stats.txbytesunicast += (u8)(skb->len) - sizeof(TX_FWINFO_8190PCI);
1429 else if(multi_addr)
1430 priv->stats.txbytesmulticast +=(u8)(skb->len) - sizeof(TX_FWINFO_8190PCI);
1431 else
1432 priv->stats.txbytesbroadcast += (u8)(skb->len) - sizeof(TX_FWINFO_8190PCI);
1434 /* fill tx firmware */
1435 pTxFwInfo = (PTX_FWINFO_8190PCI)skb->data;
1436 memset(pTxFwInfo,0,sizeof(TX_FWINFO_8190PCI));
1437 pTxFwInfo->TxHT = (tcb_desc->data_rate&0x80)?1:0;
1438 pTxFwInfo->TxRate = MRateToHwRate8190Pci((u8)tcb_desc->data_rate);
1439 pTxFwInfo->EnableCPUDur = tcb_desc->bTxEnableFwCalcDur;
1440 pTxFwInfo->Short = QueryIsShort(pTxFwInfo->TxHT, pTxFwInfo->TxRate, tcb_desc);
1442 /* Aggregation related */
1443 if(tcb_desc->bAMPDUEnable) {
1444 pTxFwInfo->AllowAggregation = 1;
1445 pTxFwInfo->RxMF = tcb_desc->ampdu_factor;
1446 pTxFwInfo->RxAMD = tcb_desc->ampdu_density;
1447 } else {
1448 pTxFwInfo->AllowAggregation = 0;
1449 pTxFwInfo->RxMF = 0;
1450 pTxFwInfo->RxAMD = 0;
1454 // Protection mode related
1456 pTxFwInfo->RtsEnable = (tcb_desc->bRTSEnable)?1:0;
1457 pTxFwInfo->CtsEnable = (tcb_desc->bCTSEnable)?1:0;
1458 pTxFwInfo->RtsSTBC = (tcb_desc->bRTSSTBC)?1:0;
1459 pTxFwInfo->RtsHT= (tcb_desc->rts_rate&0x80)?1:0;
1460 pTxFwInfo->RtsRate = MRateToHwRate8190Pci((u8)tcb_desc->rts_rate);
1461 pTxFwInfo->RtsBandwidth = 0;
1462 pTxFwInfo->RtsSubcarrier = tcb_desc->RTSSC;
1463 pTxFwInfo->RtsShort = (pTxFwInfo->RtsHT==0)?(tcb_desc->bRTSUseShortPreamble?1:0):(tcb_desc->bRTSUseShortGI?1:0);
1465 // Set Bandwidth and sub-channel settings.
1467 if(priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20_40)
1469 if(tcb_desc->bPacketBW)
1471 pTxFwInfo->TxBandwidth = 1;
1472 #ifdef RTL8190P
1473 pTxFwInfo->TxSubCarrier = 3;
1474 #else
1475 pTxFwInfo->TxSubCarrier = 0; //By SD3's Jerry suggestion, use duplicated mode, cosa 04012008
1476 #endif
1478 else
1480 pTxFwInfo->TxBandwidth = 0;
1481 pTxFwInfo->TxSubCarrier = priv->nCur40MhzPrimeSC;
1483 } else {
1484 pTxFwInfo->TxBandwidth = 0;
1485 pTxFwInfo->TxSubCarrier = 0;
1488 if (0)
1490 /* 2007/07/25 MH Copy current TX FW info.*/
1491 memcpy((void*)(&Tmp_TxFwInfo), (void*)(pTxFwInfo), sizeof(TX_FWINFO_8190PCI));
1492 printk("&&&&&&&&&&&&&&&&&&&&&&====>print out fwinf\n");
1493 printk("===>enable fwcacl:%d\n", Tmp_TxFwInfo.EnableCPUDur);
1494 printk("===>RTS STBC:%d\n", Tmp_TxFwInfo.RtsSTBC);
1495 printk("===>RTS Subcarrier:%d\n", Tmp_TxFwInfo.RtsSubcarrier);
1496 printk("===>Allow Aggregation:%d\n", Tmp_TxFwInfo.AllowAggregation);
1497 printk("===>TX HT bit:%d\n", Tmp_TxFwInfo.TxHT);
1498 printk("===>Tx rate:%d\n", Tmp_TxFwInfo.TxRate);
1499 printk("===>Received AMPDU Density:%d\n", Tmp_TxFwInfo.RxAMD);
1500 printk("===>Received MPDU Factor:%d\n", Tmp_TxFwInfo.RxMF);
1501 printk("===>TxBandwidth:%d\n", Tmp_TxFwInfo.TxBandwidth);
1502 printk("===>TxSubCarrier:%d\n", Tmp_TxFwInfo.TxSubCarrier);
1504 printk("<=====**********************out of print\n");
1507 spin_lock_irqsave(&priv->irq_th_lock,flags);
1508 ring = &priv->tx_ring[tcb_desc->queue_index];
1509 if (tcb_desc->queue_index != BEACON_QUEUE) {
1510 idx = (ring->idx + skb_queue_len(&ring->queue)) % ring->entries;
1511 } else {
1512 idx = 0;
1515 pdesc = &ring->desc[idx];
1516 if((pdesc->OWN == 1) && (tcb_desc->queue_index != BEACON_QUEUE)) {
1517 RT_TRACE(COMP_ERR,"No more TX desc@%d, ring->idx = %d,idx = %d,%x", \
1518 tcb_desc->queue_index,ring->idx, idx,skb->len);
1519 return skb->len;
1522 /* fill tx descriptor */
1523 memset((u8*)pdesc,0,12);
1524 /*DWORD 0*/
1525 pdesc->LINIP = 0;
1526 pdesc->CmdInit = 1;
1527 pdesc->Offset = sizeof(TX_FWINFO_8190PCI) + 8; //We must add 8!! Emily
1528 pdesc->PktSize = (u16)skb->len-sizeof(TX_FWINFO_8190PCI);
1530 /*DWORD 1*/
1531 pdesc->SecCAMID= 0;
1532 pdesc->RATid = tcb_desc->RATRIndex;
1535 pdesc->NoEnc = 1;
1536 pdesc->SecType = 0x0;
1537 if (tcb_desc->bHwSec) {
1538 static u8 tmp =0;
1539 if (!tmp) {
1540 printk("==>================hw sec\n");
1541 tmp = 1;
1543 switch (priv->ieee80211->pairwise_key_type) {
1544 case KEY_TYPE_WEP40:
1545 case KEY_TYPE_WEP104:
1546 pdesc->SecType = 0x1;
1547 pdesc->NoEnc = 0;
1548 break;
1549 case KEY_TYPE_TKIP:
1550 pdesc->SecType = 0x2;
1551 pdesc->NoEnc = 0;
1552 break;
1553 case KEY_TYPE_CCMP:
1554 pdesc->SecType = 0x3;
1555 pdesc->NoEnc = 0;
1556 break;
1557 case KEY_TYPE_NA:
1558 pdesc->SecType = 0x0;
1559 pdesc->NoEnc = 1;
1560 break;
1565 // Set Packet ID
1567 pdesc->PktId = 0x0;
1569 pdesc->QueueSelect = MapHwQueueToFirmwareQueue(tcb_desc->queue_index);
1570 pdesc->TxFWInfoSize = sizeof(TX_FWINFO_8190PCI);
1572 pdesc->DISFB = tcb_desc->bTxDisableRateFallBack;
1573 pdesc->USERATE = tcb_desc->bTxUseDriverAssingedRate;
1575 pdesc->FirstSeg =1;
1576 pdesc->LastSeg = 1;
1577 pdesc->TxBufferSize = skb->len;
1579 pdesc->TxBuffAddr = cpu_to_le32(mapping);
1580 __skb_queue_tail(&ring->queue, skb);
1581 pdesc->OWN = 1;
1582 spin_unlock_irqrestore(&priv->irq_th_lock,flags);
1583 dev->trans_start = jiffies;
1584 write_nic_word(dev,TPPoll,0x01<<tcb_desc->queue_index);
1585 return 0;
1588 static short rtl8192_alloc_rx_desc_ring(struct net_device *dev)
1590 struct r8192_priv *priv = ieee80211_priv(dev);
1591 rx_desc_819x_pci *entry = NULL;
1592 int i;
1594 priv->rx_ring = pci_alloc_consistent(priv->pdev,
1595 sizeof(*priv->rx_ring) * priv->rxringcount, &priv->rx_ring_dma);
1597 if (!priv->rx_ring || (unsigned long)priv->rx_ring & 0xFF) {
1598 RT_TRACE(COMP_ERR,"Cannot allocate RX ring\n");
1599 return -ENOMEM;
1602 memset(priv->rx_ring, 0, sizeof(*priv->rx_ring) * priv->rxringcount);
1603 priv->rx_idx = 0;
1605 for (i = 0; i < priv->rxringcount; i++) {
1606 struct sk_buff *skb = dev_alloc_skb(priv->rxbuffersize);
1607 dma_addr_t *mapping;
1608 entry = &priv->rx_ring[i];
1609 if (!skb)
1610 return 0;
1611 priv->rx_buf[i] = skb;
1612 mapping = (dma_addr_t *)skb->cb;
1613 *mapping = pci_map_single(priv->pdev, skb->tail,//skb_tail_pointer(skb),
1614 priv->rxbuffersize, PCI_DMA_FROMDEVICE);
1616 entry->BufferAddress = cpu_to_le32(*mapping);
1618 entry->Length = priv->rxbuffersize;
1619 entry->OWN = 1;
1622 entry->EOR = 1;
1623 return 0;
1626 static int rtl8192_alloc_tx_desc_ring(struct net_device *dev,
1627 unsigned int prio, unsigned int entries)
1629 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1630 tx_desc_819x_pci *ring;
1631 dma_addr_t dma;
1632 int i;
1634 ring = pci_alloc_consistent(priv->pdev, sizeof(*ring) * entries, &dma);
1635 if (!ring || (unsigned long)ring & 0xFF) {
1636 RT_TRACE(COMP_ERR, "Cannot allocate TX ring (prio = %d)\n", prio);
1637 return -ENOMEM;
1640 memset(ring, 0, sizeof(*ring)*entries);
1641 priv->tx_ring[prio].desc = ring;
1642 priv->tx_ring[prio].dma = dma;
1643 priv->tx_ring[prio].idx = 0;
1644 priv->tx_ring[prio].entries = entries;
1645 skb_queue_head_init(&priv->tx_ring[prio].queue);
1647 for (i = 0; i < entries; i++)
1648 ring[i].NextDescAddress =
1649 cpu_to_le32((u32)dma + ((i + 1) % entries) * sizeof(*ring));
1651 return 0;
1655 static short rtl8192_pci_initdescring(struct net_device *dev)
1657 u32 ret;
1658 int i;
1659 struct r8192_priv *priv = ieee80211_priv(dev);
1661 ret = rtl8192_alloc_rx_desc_ring(dev);
1662 if (ret) {
1663 return ret;
1667 /* general process for other queue */
1668 for (i = 0; i < MAX_TX_QUEUE_COUNT; i++) {
1669 if ((ret = rtl8192_alloc_tx_desc_ring(dev, i, priv->txringcount)))
1670 goto err_free_rings;
1673 #if 0
1674 /* specific process for hardware beacon process */
1675 if ((ret = rtl8192_alloc_tx_desc_ring(dev, MAX_TX_QUEUE_COUNT - 1, 2)))
1676 goto err_free_rings;
1677 #endif
1679 return 0;
1681 err_free_rings:
1682 rtl8192_free_rx_ring(dev);
1683 for (i = 0; i < MAX_TX_QUEUE_COUNT; i++)
1684 if (priv->tx_ring[i].desc)
1685 rtl8192_free_tx_ring(dev, i);
1686 return 1;
1689 static void rtl8192_pci_resetdescring(struct net_device *dev)
1691 struct r8192_priv *priv = ieee80211_priv(dev);
1692 int i;
1694 /* force the rx_idx to the first one */
1695 if(priv->rx_ring) {
1696 rx_desc_819x_pci *entry = NULL;
1697 for (i = 0; i < priv->rxringcount; i++) {
1698 entry = &priv->rx_ring[i];
1699 entry->OWN = 1;
1701 priv->rx_idx = 0;
1704 /* after reset, release previous pending packet, and force the
1705 * tx idx to the first one */
1706 for (i = 0; i < MAX_TX_QUEUE_COUNT; i++) {
1707 if (priv->tx_ring[i].desc) {
1708 struct rtl8192_tx_ring *ring = &priv->tx_ring[i];
1710 while (skb_queue_len(&ring->queue)) {
1711 tx_desc_819x_pci *entry = &ring->desc[ring->idx];
1712 struct sk_buff *skb = __skb_dequeue(&ring->queue);
1714 pci_unmap_single(priv->pdev, le32_to_cpu(entry->TxBuffAddr),
1715 skb->len, PCI_DMA_TODEVICE);
1716 kfree_skb(skb);
1717 ring->idx = (ring->idx + 1) % ring->entries;
1719 ring->idx = 0;
1724 #if 1
1725 extern void rtl8192_update_ratr_table(struct net_device* dev);
1726 static void rtl8192_link_change(struct net_device *dev)
1728 // int i;
1730 struct r8192_priv *priv = ieee80211_priv(dev);
1731 struct ieee80211_device* ieee = priv->ieee80211;
1732 //write_nic_word(dev, BCN_INTR_ITV, net->beacon_interval);
1733 if (ieee->state == IEEE80211_LINKED)
1735 rtl8192_net_update(dev);
1736 rtl8192_update_ratr_table(dev);
1737 #if 1
1738 //add this as in pure N mode, wep encryption will use software way, but there is no chance to set this as wep will not set group key in wext. WB.2008.07.08
1739 if ((KEY_TYPE_WEP40 == ieee->pairwise_key_type) || (KEY_TYPE_WEP104 == ieee->pairwise_key_type))
1740 EnableHWSecurityConfig8192(dev);
1741 #endif
1743 else
1745 write_nic_byte(dev, 0x173, 0);
1747 /*update timing params*/
1748 //rtl8192_set_chan(dev, priv->chan);
1749 //MSR
1750 rtl8192_update_msr(dev);
1752 // 2007/10/16 MH MAC Will update TSF according to all received beacon, so we have
1753 // // To set CBSSID bit when link with any AP or STA.
1754 if (ieee->iw_mode == IW_MODE_INFRA || ieee->iw_mode == IW_MODE_ADHOC)
1756 u32 reg = 0;
1757 reg = read_nic_dword(dev, RCR);
1758 if (priv->ieee80211->state == IEEE80211_LINKED)
1759 priv->ReceiveConfig = reg |= RCR_CBSSID;
1760 else
1761 priv->ReceiveConfig = reg &= ~RCR_CBSSID;
1762 write_nic_dword(dev, RCR, reg);
1765 #endif
1768 static struct ieee80211_qos_parameters def_qos_parameters = {
1769 {3,3,3,3},/* cw_min */
1770 {7,7,7,7},/* cw_max */
1771 {2,2,2,2},/* aifs */
1772 {0,0,0,0},/* flags */
1773 {0,0,0,0} /* tx_op_limit */
1776 #if LINUX_VERSION_CODE >=KERNEL_VERSION(2,6,20)
1777 static void rtl8192_update_beacon(struct work_struct * work)
1779 struct r8192_priv *priv = container_of(work, struct r8192_priv, update_beacon_wq.work);
1780 struct net_device *dev = priv->ieee80211->dev;
1781 #else
1782 void rtl8192_update_beacon(struct net_device *dev)
1784 struct r8192_priv *priv = ieee80211_priv(dev);
1785 #endif
1786 struct ieee80211_device* ieee = priv->ieee80211;
1787 struct ieee80211_network* net = &ieee->current_network;
1789 if (ieee->pHTInfo->bCurrentHTSupport)
1790 HTUpdateSelfAndPeerSetting(ieee, net);
1791 ieee->pHTInfo->bCurrentRT2RTLongSlotTime = net->bssht.bdRT2RTLongSlotTime;
1792 rtl8192_update_cap(dev, net->capability);
1795 * background support to run QoS activate functionality
1797 static int WDCAPARA_ADD[] = {EDCAPARA_BE,EDCAPARA_BK,EDCAPARA_VI,EDCAPARA_VO};
1798 #if LINUX_VERSION_CODE >=KERNEL_VERSION(2,6,20)
1799 static void rtl8192_qos_activate(struct work_struct * work)
1801 struct r8192_priv *priv = container_of(work, struct r8192_priv, qos_activate);
1802 struct net_device *dev = priv->ieee80211->dev;
1803 #else
1804 void rtl8192_qos_activate(struct net_device *dev)
1806 struct r8192_priv *priv = ieee80211_priv(dev);
1807 #endif
1808 struct ieee80211_qos_parameters *qos_parameters = &priv->ieee80211->current_network.qos_data.parameters;
1809 u8 mode = priv->ieee80211->current_network.mode;
1810 // u32 size = sizeof(struct ieee80211_qos_parameters);
1811 u8 u1bAIFS;
1812 u32 u4bAcParam;
1813 int i;
1814 if (priv == NULL)
1815 return;
1817 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16))
1818 down(&priv->mutex);
1819 #else
1820 mutex_lock(&priv->mutex);
1821 #endif
1822 if(priv->ieee80211->state != IEEE80211_LINKED)
1823 goto success;
1824 RT_TRACE(COMP_QOS,"qos active process with associate response received\n");
1825 /* It better set slot time at first */
1826 /* For we just support b/g mode at present, let the slot time at 9/20 selection */
1827 /* update the ac parameter to related registers */
1828 for(i = 0; i < QOS_QUEUE_NUM; i++) {
1829 //Mode G/A: slotTimeTimer = 9; Mode B: 20
1830 u1bAIFS = qos_parameters->aifs[i] * ((mode&(IEEE_G|IEEE_N_24G)) ?9:20) + aSifsTime;
1831 u4bAcParam = ((((u32)(qos_parameters->tx_op_limit[i]))<< AC_PARAM_TXOP_LIMIT_OFFSET)|
1832 (((u32)(qos_parameters->cw_max[i]))<< AC_PARAM_ECW_MAX_OFFSET)|
1833 (((u32)(qos_parameters->cw_min[i]))<< AC_PARAM_ECW_MIN_OFFSET)|
1834 ((u32)u1bAIFS << AC_PARAM_AIFS_OFFSET));
1835 printk("===>u4bAcParam:%x, ", u4bAcParam);
1836 write_nic_dword(dev, WDCAPARA_ADD[i], u4bAcParam);
1837 //write_nic_dword(dev, WDCAPARA_ADD[i], 0x005e4332);
1840 success:
1841 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16))
1842 up(&priv->mutex);
1843 #else
1844 mutex_unlock(&priv->mutex);
1845 #endif
1848 static int rtl8192_qos_handle_probe_response(struct r8192_priv *priv,
1849 int active_network,
1850 struct ieee80211_network *network)
1852 int ret = 0;
1853 u32 size = sizeof(struct ieee80211_qos_parameters);
1855 if(priv->ieee80211->state !=IEEE80211_LINKED)
1856 return ret;
1858 if ((priv->ieee80211->iw_mode != IW_MODE_INFRA))
1859 return ret;
1861 if (network->flags & NETWORK_HAS_QOS_MASK) {
1862 if (active_network &&
1863 (network->flags & NETWORK_HAS_QOS_PARAMETERS))
1864 network->qos_data.active = network->qos_data.supported;
1866 if ((network->qos_data.active == 1) && (active_network == 1) &&
1867 (network->flags & NETWORK_HAS_QOS_PARAMETERS) &&
1868 (network->qos_data.old_param_count !=
1869 network->qos_data.param_count)) {
1870 network->qos_data.old_param_count =
1871 network->qos_data.param_count;
1872 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
1873 queue_work(priv->priv_wq, &priv->qos_activate);
1874 #else
1875 schedule_task(&priv->qos_activate);
1876 #endif
1877 RT_TRACE (COMP_QOS, "QoS parameters change call "
1878 "qos_activate\n");
1880 } else {
1881 memcpy(&priv->ieee80211->current_network.qos_data.parameters,\
1882 &def_qos_parameters, size);
1884 if ((network->qos_data.active == 1) && (active_network == 1)) {
1885 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
1886 queue_work(priv->priv_wq, &priv->qos_activate);
1887 #else
1888 schedule_task(&priv->qos_activate);
1889 #endif
1890 RT_TRACE(COMP_QOS, "QoS was disabled call qos_activate \n");
1892 network->qos_data.active = 0;
1893 network->qos_data.supported = 0;
1896 return 0;
1899 /* handle manage frame frame beacon and probe response */
1900 static int rtl8192_handle_beacon(struct net_device * dev,
1901 struct ieee80211_beacon * beacon,
1902 struct ieee80211_network * network)
1904 struct r8192_priv *priv = ieee80211_priv(dev);
1906 rtl8192_qos_handle_probe_response(priv,1,network);
1908 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
1909 queue_delayed_work(priv->priv_wq, &priv->update_beacon_wq, 0);
1910 #else
1911 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
1912 schedule_task(&priv->update_beacon_wq);
1913 #else
1914 queue_work(priv->priv_wq, &priv->update_beacon_wq);
1915 #endif
1916 #endif
1917 return 0;
1922 * handling the beaconing responses. if we get different QoS setting
1923 * off the network from the associated setting, adjust the QoS
1924 * setting
1926 static int rtl8192_qos_association_resp(struct r8192_priv *priv,
1927 struct ieee80211_network *network)
1929 int ret = 0;
1930 unsigned long flags;
1931 u32 size = sizeof(struct ieee80211_qos_parameters);
1932 int set_qos_param = 0;
1934 if ((priv == NULL) || (network == NULL))
1935 return ret;
1937 if(priv->ieee80211->state !=IEEE80211_LINKED)
1938 return ret;
1940 if ((priv->ieee80211->iw_mode != IW_MODE_INFRA))
1941 return ret;
1943 spin_lock_irqsave(&priv->ieee80211->lock, flags);
1944 if(network->flags & NETWORK_HAS_QOS_PARAMETERS) {
1945 memcpy(&priv->ieee80211->current_network.qos_data.parameters,\
1946 &network->qos_data.parameters,\
1947 sizeof(struct ieee80211_qos_parameters));
1948 priv->ieee80211->current_network.qos_data.active = 1;
1949 #if 0
1950 if((priv->ieee80211->current_network.qos_data.param_count != \
1951 network->qos_data.param_count))
1952 #endif
1954 set_qos_param = 1;
1955 /* update qos parameter for current network */
1956 priv->ieee80211->current_network.qos_data.old_param_count = \
1957 priv->ieee80211->current_network.qos_data.param_count;
1958 priv->ieee80211->current_network.qos_data.param_count = \
1959 network->qos_data.param_count;
1961 } else {
1962 memcpy(&priv->ieee80211->current_network.qos_data.parameters,\
1963 &def_qos_parameters, size);
1964 priv->ieee80211->current_network.qos_data.active = 0;
1965 priv->ieee80211->current_network.qos_data.supported = 0;
1966 set_qos_param = 1;
1969 spin_unlock_irqrestore(&priv->ieee80211->lock, flags);
1971 RT_TRACE(COMP_QOS, "%s: network->flags = %d,%d\n",__FUNCTION__,network->flags ,priv->ieee80211->current_network.qos_data.active);
1972 if (set_qos_param == 1)
1973 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
1974 queue_work(priv->priv_wq, &priv->qos_activate);
1975 #else
1976 schedule_task(&priv->qos_activate);
1977 #endif
1980 return ret;
1984 static int rtl8192_handle_assoc_response(struct net_device *dev,
1985 struct ieee80211_assoc_response_frame *resp,
1986 struct ieee80211_network *network)
1988 struct r8192_priv *priv = ieee80211_priv(dev);
1989 rtl8192_qos_association_resp(priv, network);
1990 return 0;
1994 //updateRATRTabel for MCS only. Basic rate is not implement.
1995 void rtl8192_update_ratr_table(struct net_device* dev)
1996 // POCTET_STRING posLegacyRate,
1997 // u8* pMcsRate)
1998 // PRT_WLAN_STA pEntry)
2000 struct r8192_priv* priv = ieee80211_priv(dev);
2001 struct ieee80211_device* ieee = priv->ieee80211;
2002 u8* pMcsRate = ieee->dot11HTOperationalRateSet;
2003 //struct ieee80211_network *net = &ieee->current_network;
2004 u32 ratr_value = 0;
2005 u8 rate_index = 0;
2007 rtl8192_config_rate(dev, (u16*)(&ratr_value));
2008 ratr_value |= (*(u16*)(pMcsRate)) << 12;
2009 // switch (net->mode)
2010 switch (ieee->mode)
2012 case IEEE_A:
2013 ratr_value &= 0x00000FF0;
2014 break;
2015 case IEEE_B:
2016 ratr_value &= 0x0000000F;
2017 break;
2018 case IEEE_G:
2019 ratr_value &= 0x00000FF7;
2020 break;
2021 case IEEE_N_24G:
2022 case IEEE_N_5G:
2023 if (ieee->pHTInfo->PeerMimoPs == 0) //MIMO_PS_STATIC
2024 ratr_value &= 0x0007F007;
2025 else{
2026 if (priv->rf_type == RF_1T2R)
2027 ratr_value &= 0x000FF007;
2028 else
2029 ratr_value &= 0x0F81F007;
2031 break;
2032 default:
2033 break;
2035 ratr_value &= 0x0FFFFFFF;
2036 if(ieee->pHTInfo->bCurTxBW40MHz && ieee->pHTInfo->bCurShortGI40MHz){
2037 ratr_value |= 0x80000000;
2038 }else if(!ieee->pHTInfo->bCurTxBW40MHz && ieee->pHTInfo->bCurShortGI20MHz){
2039 ratr_value |= 0x80000000;
2041 write_nic_dword(dev, RATR0+rate_index*4, ratr_value);
2042 write_nic_byte(dev, UFWP, 1);
2045 static u8 ccmp_ie[4] = {0x00,0x50,0xf2,0x04};
2046 static u8 ccmp_rsn_ie[4] = {0x00, 0x0f, 0xac, 0x04};
2047 static bool GetNmodeSupportBySecCfg8190Pci(struct net_device*dev)
2049 #if 1
2050 struct r8192_priv* priv = ieee80211_priv(dev);
2051 struct ieee80211_device* ieee = priv->ieee80211;
2052 int wpa_ie_len= ieee->wpa_ie_len;
2053 struct ieee80211_crypt_data* crypt;
2054 int encrypt;
2056 crypt = ieee->crypt[ieee->tx_keyidx];
2057 encrypt = (ieee->current_network.capability & WLAN_CAPABILITY_PRIVACY) || (ieee->host_encrypt && crypt && crypt->ops && (0 == strcmp(crypt->ops->name,"WEP")));
2059 /* simply judge */
2060 if(encrypt && (wpa_ie_len == 0)) {
2061 /* wep encryption, no N mode setting */
2062 return false;
2063 // } else if((wpa_ie_len != 0)&&(memcmp(&(ieee->wpa_ie[14]),ccmp_ie,4))) {
2064 } else if((wpa_ie_len != 0)) {
2065 /* parse pairwise key type */
2066 //if((pairwisekey = WEP40)||(pairwisekey = WEP104)||(pairwisekey = TKIP))
2067 if (((ieee->wpa_ie[0] == 0xdd) && (!memcmp(&(ieee->wpa_ie[14]),ccmp_ie,4))) || ((ieee->wpa_ie[0] == 0x30) && (!memcmp(&ieee->wpa_ie[10],ccmp_rsn_ie, 4))))
2068 return true;
2069 else
2070 return false;
2071 } else {
2072 //RT_TRACE(COMP_ERR,"In %s The GroupEncAlgorithm is [4]\n",__FUNCTION__ );
2073 return true;
2076 #if 0
2077 //In here we discuss with SD4 David. He think we still can send TKIP in broadcast group key in MCS rate.
2078 //We can't force in G mode if Pairwie key is AES and group key is TKIP
2079 if((pSecInfo->GroupEncAlgorithm == WEP104_Encryption) || (pSecInfo->GroupEncAlgorithm == WEP40_Encryption) ||
2080 (pSecInfo->PairwiseEncAlgorithm == WEP104_Encryption) ||
2081 (pSecInfo->PairwiseEncAlgorithm == WEP40_Encryption) || (pSecInfo->PairwiseEncAlgorithm == TKIP_Encryption))
2083 return false;
2085 else
2086 return true;
2087 #endif
2088 return true;
2089 #endif
2092 static void rtl8192_refresh_supportrate(struct r8192_priv* priv)
2094 struct ieee80211_device* ieee = priv->ieee80211;
2095 //we donot consider set support rate for ABG mode, only HT MCS rate is set here.
2096 if (ieee->mode == WIRELESS_MODE_N_24G || ieee->mode == WIRELESS_MODE_N_5G)
2098 memcpy(ieee->Regdot11HTOperationalRateSet, ieee->RegHTSuppRateSet, 16);
2099 //RT_DEBUG_DATA(COMP_INIT, ieee->RegHTSuppRateSet, 16);
2100 //RT_DEBUG_DATA(COMP_INIT, ieee->Regdot11HTOperationalRateSet, 16);
2102 else
2103 memset(ieee->Regdot11HTOperationalRateSet, 0, 16);
2104 return;
2107 static u8 rtl8192_getSupportedWireleeMode(struct net_device*dev)
2109 struct r8192_priv *priv = ieee80211_priv(dev);
2110 u8 ret = 0;
2111 switch(priv->rf_chip)
2113 case RF_8225:
2114 case RF_8256:
2115 case RF_PSEUDO_11N:
2116 ret = (WIRELESS_MODE_N_24G|WIRELESS_MODE_G|WIRELESS_MODE_B);
2117 break;
2118 case RF_8258:
2119 ret = (WIRELESS_MODE_A|WIRELESS_MODE_N_5G);
2120 break;
2121 default:
2122 ret = WIRELESS_MODE_B;
2123 break;
2125 return ret;
2128 static void rtl8192_SetWirelessMode(struct net_device* dev, u8 wireless_mode)
2130 struct r8192_priv *priv = ieee80211_priv(dev);
2131 u8 bSupportMode = rtl8192_getSupportedWireleeMode(dev);
2133 #if 1
2134 if ((wireless_mode == WIRELESS_MODE_AUTO) || ((wireless_mode&bSupportMode)==0))
2136 if(bSupportMode & WIRELESS_MODE_N_24G)
2138 wireless_mode = WIRELESS_MODE_N_24G;
2140 else if(bSupportMode & WIRELESS_MODE_N_5G)
2142 wireless_mode = WIRELESS_MODE_N_5G;
2144 else if((bSupportMode & WIRELESS_MODE_A))
2146 wireless_mode = WIRELESS_MODE_A;
2148 else if((bSupportMode & WIRELESS_MODE_G))
2150 wireless_mode = WIRELESS_MODE_G;
2152 else if((bSupportMode & WIRELESS_MODE_B))
2154 wireless_mode = WIRELESS_MODE_B;
2156 else{
2157 RT_TRACE(COMP_ERR, "%s(), No valid wireless mode supported, SupportedWirelessMode(%x)!!!\n", __FUNCTION__,bSupportMode);
2158 wireless_mode = WIRELESS_MODE_B;
2161 #ifdef TO_DO_LIST //// TODO: this function doesn't work well at this time, we shoud wait for FPGA
2162 ActUpdateChannelAccessSetting( pAdapter, pHalData->CurrentWirelessMode, &pAdapter->MgntInfo.Info8185.ChannelAccessSetting );
2163 #endif
2164 priv->ieee80211->mode = wireless_mode;
2166 if ((wireless_mode == WIRELESS_MODE_N_24G) || (wireless_mode == WIRELESS_MODE_N_5G))
2167 priv->ieee80211->pHTInfo->bEnableHT = 1;
2168 else
2169 priv->ieee80211->pHTInfo->bEnableHT = 0;
2170 RT_TRACE(COMP_INIT, "Current Wireless Mode is %x\n", wireless_mode);
2171 rtl8192_refresh_supportrate(priv);
2172 #endif
2175 //init priv variables here
2177 static bool GetHalfNmodeSupportByAPs819xPci(struct net_device* dev)
2179 bool Reval;
2180 struct r8192_priv* priv = ieee80211_priv(dev);
2181 struct ieee80211_device* ieee = priv->ieee80211;
2183 if(ieee->bHalfWirelessN24GMode == true)
2184 Reval = true;
2185 else
2186 Reval = false;
2188 return Reval;
2191 short rtl8192_is_tx_queue_empty(struct net_device *dev)
2193 int i=0;
2194 struct r8192_priv *priv = ieee80211_priv(dev);
2195 for (i=0; i<=MGNT_QUEUE; i++)
2197 if ((i== TXCMD_QUEUE) || (i == HCCA_QUEUE) )
2198 continue;
2199 if (skb_queue_len(&(&priv->tx_ring[i])->queue) > 0){
2200 printk("===>tx queue is not empty:%d, %d\n", i, skb_queue_len(&(&priv->tx_ring[i])->queue));
2201 return 0;
2204 return 1;
2206 static void rtl8192_hw_sleep_down(struct net_device *dev)
2208 RT_TRACE(COMP_POWER, "%s()============>come to sleep down\n", __FUNCTION__);
2209 MgntActSet_RF_State(dev, eRfSleep, RF_CHANGE_BY_PS);
2211 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
2212 static void rtl8192_hw_sleep_wq (struct work_struct *work)
2214 // struct r8180_priv *priv = container_of(work, struct r8180_priv, watch_dog_wq);
2215 // struct ieee80211_device * ieee = (struct ieee80211_device*)
2216 // container_of(work, struct ieee80211_device, watch_dog_wq);
2217 struct delayed_work *dwork = container_of(work,struct delayed_work,work);
2218 struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,hw_sleep_wq);
2219 struct net_device *dev = ieee->dev;
2220 #else
2221 void rtl8192_hw_sleep_wq(struct net_device* dev)
2223 #endif
2224 //printk("=========>%s()\n", __FUNCTION__);
2225 rtl8192_hw_sleep_down(dev);
2227 // printk("dev is %d\n",dev);
2228 // printk("&*&(^*(&(&=========>%s()\n", __FUNCTION__);
2229 static void rtl8192_hw_wakeup(struct net_device* dev)
2231 // u32 flags = 0;
2233 // spin_lock_irqsave(&priv->ps_lock,flags);
2234 RT_TRACE(COMP_POWER, "%s()============>come to wake up\n", __FUNCTION__);
2235 MgntActSet_RF_State(dev, eRfOn, RF_CHANGE_BY_PS);
2236 //FIXME: will we send package stored while nic is sleep?
2237 // spin_unlock_irqrestore(&priv->ps_lock,flags);
2239 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
2240 void rtl8192_hw_wakeup_wq (struct work_struct *work)
2242 // struct r8180_priv *priv = container_of(work, struct r8180_priv, watch_dog_wq);
2243 // struct ieee80211_device * ieee = (struct ieee80211_device*)
2244 // container_of(work, struct ieee80211_device, watch_dog_wq);
2245 struct delayed_work *dwork = container_of(work,struct delayed_work,work);
2246 struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,hw_wakeup_wq);
2247 struct net_device *dev = ieee->dev;
2248 #else
2249 void rtl8192_hw_wakeup_wq(struct net_device* dev)
2251 #endif
2252 rtl8192_hw_wakeup(dev);
2256 #define MIN_SLEEP_TIME 50
2257 #define MAX_SLEEP_TIME 10000
2258 static void rtl8192_hw_to_sleep(struct net_device *dev, u32 th, u32 tl)
2261 struct r8192_priv *priv = ieee80211_priv(dev);
2263 u32 rb = jiffies;
2264 unsigned long flags;
2266 spin_lock_irqsave(&priv->ps_lock,flags);
2268 /* Writing HW register with 0 equals to disable
2269 * the timer, that is not really what we want
2271 tl -= MSECS(4+16+7);
2273 //if(tl == 0) tl = 1;
2275 /* FIXME HACK FIXME HACK */
2276 // force_pci_posting(dev);
2277 //mdelay(1);
2279 // rb = read_nic_dword(dev, TSFTR);
2281 /* If the interval in witch we are requested to sleep is too
2282 * short then give up and remain awake
2284 if(((tl>=rb)&& (tl-rb) <= MSECS(MIN_SLEEP_TIME))
2285 ||((rb>tl)&& (rb-tl) < MSECS(MIN_SLEEP_TIME))) {
2286 spin_unlock_irqrestore(&priv->ps_lock,flags);
2287 printk("too short to sleep\n");
2288 return;
2291 // write_nic_dword(dev, TimerInt, tl);
2292 // rb = read_nic_dword(dev, TSFTR);
2294 u32 tmp = (tl>rb)?(tl-rb):(rb-tl);
2295 // if (tl<rb)
2296 queue_delayed_work(priv->ieee80211->wq, &priv->ieee80211->hw_wakeup_wq, tmp); //as tl may be less than rb
2298 /* if we suspect the TimerInt is gone beyond tl
2299 * while setting it, then give up
2301 #if 1
2302 if(((tl > rb) && ((tl-rb) > MSECS(MAX_SLEEP_TIME)))||
2303 ((tl < rb) && ((rb-tl) > MSECS(MAX_SLEEP_TIME)))) {
2304 printk("========>too long to sleep:%x, %x, %lx\n", tl, rb, MSECS(MAX_SLEEP_TIME));
2305 spin_unlock_irqrestore(&priv->ps_lock,flags);
2306 return;
2308 #endif
2309 // if(priv->rf_sleep)
2310 // priv->rf_sleep(dev);
2312 //printk("<=========%s()\n", __FUNCTION__);
2313 queue_delayed_work(priv->ieee80211->wq, (void *)&priv->ieee80211->hw_sleep_wq,0);
2314 spin_unlock_irqrestore(&priv->ps_lock,flags);
2316 static void rtl8192_init_priv_variable(struct net_device* dev)
2318 struct r8192_priv *priv = ieee80211_priv(dev);
2319 u8 i;
2320 priv->being_init_adapter = false;
2321 priv->txbuffsize = 1600;//1024;
2322 priv->txfwbuffersize = 4096;
2323 priv->txringcount = 64;//32;
2324 //priv->txbeaconcount = priv->txringcount;
2325 priv->txbeaconcount = 2;
2326 priv->rxbuffersize = 9100;//2048;//1024;
2327 priv->rxringcount = MAX_RX_COUNT;//64;
2328 priv->irq_enabled=0;
2329 priv->card_8192 = NIC_8192E;
2330 priv->rx_skb_complete = 1;
2331 priv->chan = 1; //set to channel 1
2332 priv->RegWirelessMode = WIRELESS_MODE_AUTO;
2333 priv->RegChannelPlan = 0xf;
2334 priv->nrxAMPDU_size = 0;
2335 priv->nrxAMPDU_aggr_num = 0;
2336 priv->last_rxdesc_tsf_high = 0;
2337 priv->last_rxdesc_tsf_low = 0;
2338 priv->ieee80211->mode = WIRELESS_MODE_AUTO; //SET AUTO
2339 priv->ieee80211->iw_mode = IW_MODE_INFRA;
2340 priv->ieee80211->ieee_up=0;
2341 priv->retry_rts = DEFAULT_RETRY_RTS;
2342 priv->retry_data = DEFAULT_RETRY_DATA;
2343 priv->ieee80211->rts = DEFAULT_RTS_THRESHOLD;
2344 priv->ieee80211->rate = 110; //11 mbps
2345 priv->ieee80211->short_slot = 1;
2346 priv->promisc = (dev->flags & IFF_PROMISC) ? 1:0;
2347 priv->bcck_in_ch14 = false;
2348 priv->bfsync_processing = false;
2349 priv->CCKPresentAttentuation = 0;
2350 priv->rfa_txpowertrackingindex = 0;
2351 priv->rfc_txpowertrackingindex = 0;
2352 priv->CckPwEnl = 6;
2353 priv->ScanDelay = 50;//for Scan TODO
2354 //added by amy for silent reset
2355 priv->ResetProgress = RESET_TYPE_NORESET;
2356 priv->bForcedSilentReset = 0;
2357 priv->bDisableNormalResetCheck = false;
2358 priv->force_reset = false;
2359 //added by amy for power save
2360 priv->RegRfOff = 0;
2361 priv->ieee80211->RfOffReason = 0;
2362 priv->RFChangeInProgress = false;
2363 priv->bHwRfOffAction = 0;
2364 priv->SetRFPowerStateInProgress = false;
2365 priv->ieee80211->PowerSaveControl.bInactivePs = true;
2366 priv->ieee80211->PowerSaveControl.bIPSModeBackup = false;
2367 //just for debug
2368 priv->txpower_checkcnt = 0;
2369 priv->thermal_readback_index =0;
2370 priv->txpower_tracking_callback_cnt = 0;
2371 priv->ccktxpower_adjustcnt_ch14 = 0;
2372 priv->ccktxpower_adjustcnt_not_ch14 = 0;
2374 priv->ieee80211->current_network.beacon_interval = DEFAULT_BEACONINTERVAL;
2375 priv->ieee80211->iw_mode = IW_MODE_INFRA;
2376 priv->ieee80211->softmac_features = IEEE_SOFTMAC_SCAN |
2377 IEEE_SOFTMAC_ASSOCIATE | IEEE_SOFTMAC_PROBERQ |
2378 IEEE_SOFTMAC_PROBERS | IEEE_SOFTMAC_TX_QUEUE;/* |
2379 IEEE_SOFTMAC_BEACONS;*///added by amy 080604 //| //IEEE_SOFTMAC_SINGLE_QUEUE;
2381 priv->ieee80211->active_scan = 1;
2382 priv->ieee80211->modulation = IEEE80211_CCK_MODULATION | IEEE80211_OFDM_MODULATION;
2383 priv->ieee80211->host_encrypt = 1;
2384 priv->ieee80211->host_decrypt = 1;
2385 //priv->ieee80211->start_send_beacons = NULL;//rtl819xusb_beacon_tx;//-by amy 080604
2386 //priv->ieee80211->stop_send_beacons = NULL;//rtl8192_beacon_stop;//-by amy 080604
2387 priv->ieee80211->start_send_beacons = rtl8192_start_beacon;//+by david 081107
2388 priv->ieee80211->stop_send_beacons = rtl8192_stop_beacon;//+by david 081107
2389 priv->ieee80211->softmac_hard_start_xmit = rtl8192_hard_start_xmit;
2390 priv->ieee80211->set_chan = rtl8192_set_chan;
2391 priv->ieee80211->link_change = rtl8192_link_change;
2392 priv->ieee80211->softmac_data_hard_start_xmit = rtl8192_hard_data_xmit;
2393 priv->ieee80211->data_hard_stop = rtl8192_data_hard_stop;
2394 priv->ieee80211->data_hard_resume = rtl8192_data_hard_resume;
2395 priv->ieee80211->init_wmmparam_flag = 0;
2396 priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD;
2397 priv->ieee80211->check_nic_enough_desc = check_nic_enough_desc;
2398 priv->ieee80211->tx_headroom = sizeof(TX_FWINFO_8190PCI);
2399 priv->ieee80211->qos_support = 1;
2400 priv->ieee80211->dot11PowerSaveMode = 0;
2401 //added by WB
2402 // priv->ieee80211->SwChnlByTimerHandler = rtl8192_phy_SwChnl;
2403 priv->ieee80211->SetBWModeHandler = rtl8192_SetBWMode;
2404 priv->ieee80211->handle_assoc_response = rtl8192_handle_assoc_response;
2405 priv->ieee80211->handle_beacon = rtl8192_handle_beacon;
2407 priv->ieee80211->sta_wake_up = rtl8192_hw_wakeup;
2408 // priv->ieee80211->ps_request_tx_ack = rtl8192_rq_tx_ack;
2409 priv->ieee80211->enter_sleep_state = rtl8192_hw_to_sleep;
2410 priv->ieee80211->ps_is_queue_empty = rtl8192_is_tx_queue_empty;
2411 //added by david
2412 priv->ieee80211->GetNmodeSupportBySecCfg = GetNmodeSupportBySecCfg8190Pci;
2413 priv->ieee80211->SetWirelessMode = rtl8192_SetWirelessMode;
2414 priv->ieee80211->GetHalfNmodeSupportByAPsHandler = GetHalfNmodeSupportByAPs819xPci;
2416 //added by amy
2417 priv->ieee80211->InitialGainHandler = InitialGain819xPci;
2419 priv->card_type = USB;
2421 priv->ShortRetryLimit = 0x30;
2422 priv->LongRetryLimit = 0x30;
2424 priv->EarlyRxThreshold = 7;
2425 priv->enable_gpio0 = 0;
2427 priv->TransmitConfig = 0;
2429 priv->ReceiveConfig = RCR_ADD3 |
2430 RCR_AMF | RCR_ADF | //accept management/data
2431 RCR_AICV | //accept control frame for SW AP needs PS-poll, 2005.07.07, by rcnjko.
2432 RCR_AB | RCR_AM | RCR_APM | //accept BC/MC/UC
2433 RCR_AAP | ((u32)7<<RCR_MXDMA_OFFSET) |
2434 ((u32)7 << RCR_FIFO_OFFSET) | RCR_ONLYERLPKT;
2436 priv->irq_mask = (u32)(IMR_ROK | IMR_VODOK | IMR_VIDOK | IMR_BEDOK | IMR_BKDOK |\
2437 IMR_HCCADOK | IMR_MGNTDOK | IMR_COMDOK | IMR_HIGHDOK |\
2438 IMR_BDOK | IMR_RXCMDOK | IMR_TIMEOUT0 | IMR_RDU | IMR_RXFOVW |\
2439 IMR_TXFOVW | IMR_BcnInt | IMR_TBDOK | IMR_TBDER);
2441 priv->AcmControl = 0;
2442 priv->pFirmware = (rt_firmware*)vmalloc(sizeof(rt_firmware));
2443 if (priv->pFirmware)
2444 memset(priv->pFirmware, 0, sizeof(rt_firmware));
2446 /* rx related queue */
2447 skb_queue_head_init(&priv->rx_queue);
2448 skb_queue_head_init(&priv->skb_queue);
2450 /* Tx related queue */
2451 for(i = 0; i < MAX_QUEUE_SIZE; i++) {
2452 skb_queue_head_init(&priv->ieee80211->skb_waitQ [i]);
2454 for(i = 0; i < MAX_QUEUE_SIZE; i++) {
2455 skb_queue_head_init(&priv->ieee80211->skb_aggQ [i]);
2457 priv->rf_set_chan = rtl8192_phy_SwChnl;
2460 //init lock here
2461 static void rtl8192_init_priv_lock(struct r8192_priv* priv)
2463 spin_lock_init(&priv->tx_lock);
2464 spin_lock_init(&priv->irq_lock);//added by thomas
2465 spin_lock_init(&priv->irq_th_lock);
2466 spin_lock_init(&priv->rf_ps_lock);
2467 spin_lock_init(&priv->ps_lock);
2468 //spin_lock_init(&priv->rf_lock);
2469 sema_init(&priv->wx_sem,1);
2470 sema_init(&priv->rf_sem,1);
2471 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16))
2472 sema_init(&priv->mutex, 1);
2473 #else
2474 mutex_init(&priv->mutex);
2475 #endif
2478 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
2479 extern void rtl819x_watchdog_wqcallback(struct work_struct *work);
2480 #else
2481 extern void rtl819x_watchdog_wqcallback(struct net_device *dev);
2482 #endif
2484 void rtl8192_irq_rx_tasklet(struct r8192_priv *priv);
2485 void rtl8192_irq_tx_tasklet(struct r8192_priv *priv);
2486 void rtl8192_prepare_beacon(struct r8192_priv *priv);
2487 //init tasklet and wait_queue here. only 2.6 above kernel is considered
2488 #define DRV_NAME "wlan0"
2489 static void rtl8192_init_priv_task(struct net_device* dev)
2491 struct r8192_priv *priv = ieee80211_priv(dev);
2493 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
2494 #ifdef PF_SYNCTHREAD
2495 priv->priv_wq = create_workqueue(DRV_NAME,0);
2496 #else
2497 priv->priv_wq = create_workqueue(DRV_NAME);
2498 #endif
2499 #endif
2501 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
2502 // INIT_WORK(&priv->reset_wq, (void(*)(void*)) rtl8192_restart);
2503 INIT_WORK(&priv->reset_wq, rtl8192_restart);
2504 // INIT_DELAYED_WORK(&priv->watch_dog_wq, hal_dm_watchdog);
2505 INIT_DELAYED_WORK(&priv->watch_dog_wq, rtl819x_watchdog_wqcallback);
2506 INIT_DELAYED_WORK(&priv->txpower_tracking_wq, dm_txpower_trackingcallback);
2507 INIT_DELAYED_WORK(&priv->rfpath_check_wq, dm_rf_pathcheck_workitemcallback);
2508 INIT_DELAYED_WORK(&priv->update_beacon_wq, rtl8192_update_beacon);
2509 //INIT_WORK(&priv->SwChnlWorkItem, rtl8192_SwChnl_WorkItem);
2510 //INIT_WORK(&priv->SetBWModeWorkItem, rtl8192_SetBWModeWorkItem);
2511 INIT_WORK(&priv->qos_activate, rtl8192_qos_activate);
2512 INIT_DELAYED_WORK(&priv->ieee80211->hw_wakeup_wq,(void*) rtl8192_hw_wakeup_wq);
2513 INIT_DELAYED_WORK(&priv->ieee80211->hw_sleep_wq,(void*) rtl8192_hw_sleep_wq);
2515 #else
2516 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
2517 tq_init(&priv->reset_wq, (void*)rtl8192_restart, dev);
2518 tq_init(&priv->watch_dog_wq, (void*)rtl819x_watchdog_wqcallback, dev);
2519 tq_init(&priv->txpower_tracking_wq, (void*)dm_txpower_trackingcallback, dev);
2520 tq_init(&priv->rfpath_check_wq, (void*)dm_rf_pathcheck_workitemcallback, dev);
2521 tq_init(&priv->update_beacon_wq, (void*)rtl8192_update_beacon, dev);
2522 //tq_init(&priv->SwChnlWorkItem, (void*) rtl8192_SwChnl_WorkItem, dev);
2523 //tq_init(&priv->SetBWModeWorkItem, (void*)rtl8192_SetBWModeWorkItem, dev);
2524 tq_init(&priv->qos_activate, (void *)rtl8192_qos_activate, dev);
2525 tq_init(&priv->ieee80211->hw_wakeup_wq,(void*) rtl8192_hw_wakeup_wq, dev);
2526 tq_init(&priv->ieee80211->hw_sleep_wq,(void*) rtl8192_hw_sleep_wq, dev);
2528 #else
2529 INIT_WORK(&priv->reset_wq,(void(*)(void*)) rtl8192_restart,dev);
2530 // INIT_WORK(&priv->watch_dog_wq, (void(*)(void*)) hal_dm_watchdog,dev);
2531 INIT_WORK(&priv->watch_dog_wq, (void(*)(void*)) rtl819x_watchdog_wqcallback,dev);
2532 INIT_WORK(&priv->txpower_tracking_wq, (void(*)(void*)) dm_txpower_trackingcallback,dev);
2533 INIT_WORK(&priv->rfpath_check_wq, (void(*)(void*)) dm_rf_pathcheck_workitemcallback,dev);
2534 INIT_WORK(&priv->update_beacon_wq, (void(*)(void*))rtl8192_update_beacon,dev);
2535 //INIT_WORK(&priv->SwChnlWorkItem, (void(*)(void*)) rtl8192_SwChnl_WorkItem, dev);
2536 //INIT_WORK(&priv->SetBWModeWorkItem, (void(*)(void*)) rtl8192_SetBWModeWorkItem, dev);
2537 INIT_WORK(&priv->qos_activate, (void(*)(void *))rtl8192_qos_activate, dev);
2538 INIT_WORK(&priv->ieee80211->hw_wakeup_wq,(void*) rtl8192_hw_wakeup_wq, dev);
2539 INIT_WORK(&priv->ieee80211->hw_sleep_wq,(void*) rtl8192_hw_sleep_wq, dev);
2540 #endif
2541 #endif
2543 tasklet_init(&priv->irq_rx_tasklet,
2544 (void(*)(unsigned long))rtl8192_irq_rx_tasklet,
2545 (unsigned long)priv);
2546 tasklet_init(&priv->irq_tx_tasklet,
2547 (void(*)(unsigned long))rtl8192_irq_tx_tasklet,
2548 (unsigned long)priv);
2549 tasklet_init(&priv->irq_prepare_beacon_tasklet,
2550 (void(*)(unsigned long))rtl8192_prepare_beacon,
2551 (unsigned long)priv);
2554 static void rtl8192_get_eeprom_size(struct net_device* dev)
2556 u16 curCR = 0;
2557 struct r8192_priv *priv = ieee80211_priv(dev);
2558 RT_TRACE(COMP_INIT, "===========>%s()\n", __FUNCTION__);
2559 curCR = read_nic_dword(dev, EPROM_CMD);
2560 RT_TRACE(COMP_INIT, "read from Reg Cmd9346CR(%x):%x\n", EPROM_CMD, curCR);
2561 //whether need I consider BIT5?
2562 priv->epromtype = (curCR & EPROM_CMD_9356SEL) ? EPROM_93c56 : EPROM_93c46;
2563 RT_TRACE(COMP_INIT, "<===========%s(), epromtype:%d\n", __FUNCTION__, priv->epromtype);
2566 //used to swap endian. as ntohl & htonl are not neccessary to swap endian, so use this instead.
2567 static inline u16 endian_swap(u16* data)
2569 u16 tmp = *data;
2570 *data = (tmp >> 8) | (tmp << 8);
2571 return *data;
2575 * Note: Adapter->EEPROMAddressSize should be set before this function call.
2576 * EEPROM address size can be got through GetEEPROMSize8185()
2578 static void rtl8192_read_eeprom_info(struct net_device* dev)
2580 struct r8192_priv *priv = ieee80211_priv(dev);
2582 u8 tempval;
2583 #ifdef RTL8192E
2584 u8 ICVer8192, ICVer8256;
2585 #endif
2586 u16 i,usValue, IC_Version;
2587 u16 EEPROMId;
2588 #ifdef RTL8190P
2589 u8 offset;//, tmpAFR;
2590 u8 EepromTxPower[100];
2591 #endif
2592 u8 bMac_Tmp_Addr[6] = {0x00, 0xe0, 0x4c, 0x00, 0x00, 0x01};
2593 RT_TRACE(COMP_INIT, "====> rtl8192_read_eeprom_info\n");
2596 // TODO: I don't know if we need to apply EF function to EEPROM read function
2598 //2 Read EEPROM ID to make sure autoload is success
2599 EEPROMId = eprom_read(dev, 0);
2600 if( EEPROMId != RTL8190_EEPROM_ID )
2602 RT_TRACE(COMP_ERR, "EEPROM ID is invalid:%x, %x\n", EEPROMId, RTL8190_EEPROM_ID);
2603 priv->AutoloadFailFlag=true;
2605 else
2607 priv->AutoloadFailFlag=false;
2611 // Assign Chip Version ID
2613 // Read IC Version && Channel Plan
2614 if(!priv->AutoloadFailFlag)
2616 // VID, PID
2617 priv->eeprom_vid = eprom_read(dev, (EEPROM_VID >> 1));
2618 priv->eeprom_did = eprom_read(dev, (EEPROM_DID >> 1));
2620 usValue = eprom_read(dev, (u16)(EEPROM_Customer_ID>>1)) >> 8 ;
2621 priv->eeprom_CustomerID = (u8)( usValue & 0xff);
2622 usValue = eprom_read(dev, (EEPROM_ICVersion_ChannelPlan>>1));
2623 priv->eeprom_ChannelPlan = usValue&0xff;
2624 IC_Version = ((usValue&0xff00)>>8);
2626 #ifdef RTL8190P
2627 priv->card_8192_version = (VERSION_8190)(IC_Version);
2628 #else
2629 #ifdef RTL8192E
2630 ICVer8192 = (IC_Version&0xf); //bit0~3; 1:A cut, 2:B cut, 3:C cut...
2631 ICVer8256 = ((IC_Version&0xf0)>>4);//bit4~6, bit7 reserved for other RF chip; 1:A cut, 2:B cut, 3:C cut...
2632 RT_TRACE(COMP_INIT, "\nICVer8192 = 0x%x\n", ICVer8192);
2633 RT_TRACE(COMP_INIT, "\nICVer8256 = 0x%x\n", ICVer8256);
2634 if(ICVer8192 == 0x2) //B-cut
2636 if(ICVer8256 == 0x5) //E-cut
2637 priv->card_8192_version= VERSION_8190_BE;
2639 #endif
2640 #endif
2641 switch(priv->card_8192_version)
2643 case VERSION_8190_BD:
2644 case VERSION_8190_BE:
2645 break;
2646 default:
2647 priv->card_8192_version = VERSION_8190_BD;
2648 break;
2650 RT_TRACE(COMP_INIT, "\nIC Version = 0x%x\n", priv->card_8192_version);
2652 else
2654 priv->card_8192_version = VERSION_8190_BD;
2655 priv->eeprom_vid = 0;
2656 priv->eeprom_did = 0;
2657 priv->eeprom_CustomerID = 0;
2658 priv->eeprom_ChannelPlan = 0;
2659 RT_TRACE(COMP_INIT, "\nIC Version = 0x%x\n", 0xff);
2662 RT_TRACE(COMP_INIT, "EEPROM VID = 0x%4x\n", priv->eeprom_vid);
2663 RT_TRACE(COMP_INIT, "EEPROM DID = 0x%4x\n", priv->eeprom_did);
2664 RT_TRACE(COMP_INIT,"EEPROM Customer ID: 0x%2x\n", priv->eeprom_CustomerID);
2666 //2 Read Permanent MAC address
2667 if(!priv->AutoloadFailFlag)
2669 for(i = 0; i < 6; i += 2)
2671 usValue = eprom_read(dev, (u16) ((EEPROM_NODE_ADDRESS_BYTE_0+i)>>1));
2672 *(u16*)(&dev->dev_addr[i]) = usValue;
2674 } else {
2675 // when auto load failed, the last address byte set to be a random one.
2676 // added by david woo.2007/11/7
2677 memcpy(dev->dev_addr, bMac_Tmp_Addr, 6);
2680 RT_TRACE(COMP_INIT, "Permanent Address = %02x-%02x-%02x-%02x-%02x-%02x\n",
2681 dev->dev_addr[0], dev->dev_addr[1],
2682 dev->dev_addr[2], dev->dev_addr[3],
2683 dev->dev_addr[4], dev->dev_addr[5]);
2685 //2 TX Power Check EEPROM Fail or not
2686 if(priv->card_8192_version > VERSION_8190_BD) {
2687 priv->bTXPowerDataReadFromEEPORM = true;
2688 } else {
2689 priv->bTXPowerDataReadFromEEPORM = false;
2692 // 2007/11/15 MH 8190PCI Default=2T4R, 8192PCIE dafault=1T2R
2693 priv->rf_type = RTL819X_DEFAULT_RF_TYPE;
2695 if(priv->card_8192_version > VERSION_8190_BD)
2697 // Read RF-indication and Tx Power gain index diff of legacy to HT OFDM rate.
2698 if(!priv->AutoloadFailFlag)
2700 tempval = (eprom_read(dev, (EEPROM_RFInd_PowerDiff>>1))) & 0xff;
2701 priv->EEPROMLegacyHTTxPowerDiff = tempval & 0xf; // bit[3:0]
2703 if (tempval&0x80) //RF-indication, bit[7]
2704 priv->rf_type = RF_1T2R;
2705 else
2706 priv->rf_type = RF_2T4R;
2708 else
2710 priv->EEPROMLegacyHTTxPowerDiff = EEPROM_Default_LegacyHTTxPowerDiff;
2712 RT_TRACE(COMP_INIT, "EEPROMLegacyHTTxPowerDiff = %d\n",
2713 priv->EEPROMLegacyHTTxPowerDiff);
2715 // Read ThermalMeter from EEPROM
2716 if(!priv->AutoloadFailFlag)
2718 priv->EEPROMThermalMeter = (u8)(((eprom_read(dev, (EEPROM_ThermalMeter>>1))) & 0xff00)>>8);
2720 else
2722 priv->EEPROMThermalMeter = EEPROM_Default_ThermalMeter;
2724 RT_TRACE(COMP_INIT, "ThermalMeter = %d\n", priv->EEPROMThermalMeter);
2725 //vivi, for tx power track
2726 priv->TSSI_13dBm = priv->EEPROMThermalMeter *100;
2728 if(priv->epromtype == EPROM_93c46)
2730 // Read antenna tx power offset of B/C/D to A and CrystalCap from EEPROM
2731 if(!priv->AutoloadFailFlag)
2733 usValue = eprom_read(dev, (EEPROM_TxPwDiff_CrystalCap>>1));
2734 priv->EEPROMAntPwDiff = (usValue&0x0fff);
2735 priv->EEPROMCrystalCap = (u8)((usValue&0xf000)>>12);
2737 else
2739 priv->EEPROMAntPwDiff = EEPROM_Default_AntTxPowerDiff;
2740 priv->EEPROMCrystalCap = EEPROM_Default_TxPwDiff_CrystalCap;
2742 RT_TRACE(COMP_INIT, "EEPROMAntPwDiff = %d\n", priv->EEPROMAntPwDiff);
2743 RT_TRACE(COMP_INIT, "EEPROMCrystalCap = %d\n", priv->EEPROMCrystalCap);
2746 // Get per-channel Tx Power Level
2748 for(i=0; i<14; i+=2)
2750 if(!priv->AutoloadFailFlag)
2752 usValue = eprom_read(dev, (u16) ((EEPROM_TxPwIndex_CCK+i)>>1) );
2754 else
2756 usValue = EEPROM_Default_TxPower;
2758 *((u16*)(&priv->EEPROMTxPowerLevelCCK[i])) = usValue;
2759 RT_TRACE(COMP_INIT,"CCK Tx Power Level, Index %d = 0x%02x\n", i, priv->EEPROMTxPowerLevelCCK[i]);
2760 RT_TRACE(COMP_INIT, "CCK Tx Power Level, Index %d = 0x%02x\n", i+1, priv->EEPROMTxPowerLevelCCK[i+1]);
2762 for(i=0; i<14; i+=2)
2764 if(!priv->AutoloadFailFlag)
2766 usValue = eprom_read(dev, (u16) ((EEPROM_TxPwIndex_OFDM_24G+i)>>1) );
2768 else
2770 usValue = EEPROM_Default_TxPower;
2772 *((u16*)(&priv->EEPROMTxPowerLevelOFDM24G[i])) = usValue;
2773 RT_TRACE(COMP_INIT, "OFDM 2.4G Tx Power Level, Index %d = 0x%02x\n", i, priv->EEPROMTxPowerLevelOFDM24G[i]);
2774 RT_TRACE(COMP_INIT, "OFDM 2.4G Tx Power Level, Index %d = 0x%02x\n", i+1, priv->EEPROMTxPowerLevelOFDM24G[i+1]);
2777 else if(priv->epromtype== EPROM_93c56)
2779 #ifdef RTL8190P
2780 // Read CrystalCap from EEPROM
2781 if(!priv->AutoloadFailFlag)
2783 priv->EEPROMAntPwDiff = EEPROM_Default_AntTxPowerDiff;
2784 priv->EEPROMCrystalCap = (u8)(((eprom_read(dev, (EEPROM_C56_CrystalCap>>1))) & 0xf000)>>12);
2786 else
2788 priv->EEPROMAntPwDiff = EEPROM_Default_AntTxPowerDiff;
2789 priv->EEPROMCrystalCap = EEPROM_Default_TxPwDiff_CrystalCap;
2791 RT_TRACE(COMP_INIT,"EEPROMAntPwDiff = %d\n", priv->EEPROMAntPwDiff);
2792 RT_TRACE(COMP_INIT, "EEPROMCrystalCap = %d\n", priv->EEPROMCrystalCap);
2794 // Get Tx Power Level by Channel
2795 if(!priv->AutoloadFailFlag)
2797 // Read Tx power of Channel 1 ~ 14 from EEPROM.
2798 for(i = 0; i < 12; i+=2)
2800 if (i <6)
2801 offset = EEPROM_C56_RfA_CCK_Chnl1_TxPwIndex + i;
2802 else
2803 offset = EEPROM_C56_RfC_CCK_Chnl1_TxPwIndex + i - 6;
2804 usValue = eprom_read(dev, (offset>>1));
2805 *((u16*)(&EepromTxPower[i])) = usValue;
2808 for(i = 0; i < 12; i++)
2810 if (i <= 2)
2811 priv->EEPROMRfACCKChnl1TxPwLevel[i] = EepromTxPower[i];
2812 else if ((i >=3 )&&(i <= 5))
2813 priv->EEPROMRfAOfdmChnlTxPwLevel[i-3] = EepromTxPower[i];
2814 else if ((i >=6 )&&(i <= 8))
2815 priv->EEPROMRfCCCKChnl1TxPwLevel[i-6] = EepromTxPower[i];
2816 else
2817 priv->EEPROMRfCOfdmChnlTxPwLevel[i-9] = EepromTxPower[i];
2820 else
2822 priv->EEPROMRfACCKChnl1TxPwLevel[0] = EEPROM_Default_TxPowerLevel;
2823 priv->EEPROMRfACCKChnl1TxPwLevel[1] = EEPROM_Default_TxPowerLevel;
2824 priv->EEPROMRfACCKChnl1TxPwLevel[2] = EEPROM_Default_TxPowerLevel;
2826 priv->EEPROMRfAOfdmChnlTxPwLevel[0] = EEPROM_Default_TxPowerLevel;
2827 priv->EEPROMRfAOfdmChnlTxPwLevel[1] = EEPROM_Default_TxPowerLevel;
2828 priv->EEPROMRfAOfdmChnlTxPwLevel[2] = EEPROM_Default_TxPowerLevel;
2830 priv->EEPROMRfCCCKChnl1TxPwLevel[0] = EEPROM_Default_TxPowerLevel;
2831 priv->EEPROMRfCCCKChnl1TxPwLevel[1] = EEPROM_Default_TxPowerLevel;
2832 priv->EEPROMRfCCCKChnl1TxPwLevel[2] = EEPROM_Default_TxPowerLevel;
2834 priv->EEPROMRfCOfdmChnlTxPwLevel[0] = EEPROM_Default_TxPowerLevel;
2835 priv->EEPROMRfCOfdmChnlTxPwLevel[1] = EEPROM_Default_TxPowerLevel;
2836 priv->EEPROMRfCOfdmChnlTxPwLevel[2] = EEPROM_Default_TxPowerLevel;
2838 RT_TRACE(COMP_INIT, "priv->EEPROMRfACCKChnl1TxPwLevel[0] = 0x%x\n", priv->EEPROMRfACCKChnl1TxPwLevel[0]);
2839 RT_TRACE(COMP_INIT, "priv->EEPROMRfACCKChnl1TxPwLevel[1] = 0x%x\n", priv->EEPROMRfACCKChnl1TxPwLevel[1]);
2840 RT_TRACE(COMP_INIT, "priv->EEPROMRfACCKChnl1TxPwLevel[2] = 0x%x\n", priv->EEPROMRfACCKChnl1TxPwLevel[2]);
2841 RT_TRACE(COMP_INIT, "priv->EEPROMRfAOfdmChnlTxPwLevel[0] = 0x%x\n", priv->EEPROMRfAOfdmChnlTxPwLevel[0]);
2842 RT_TRACE(COMP_INIT, "priv->EEPROMRfAOfdmChnlTxPwLevel[1] = 0x%x\n", priv->EEPROMRfAOfdmChnlTxPwLevel[1]);
2843 RT_TRACE(COMP_INIT, "priv->EEPROMRfAOfdmChnlTxPwLevel[2] = 0x%x\n", priv->EEPROMRfAOfdmChnlTxPwLevel[2]);
2844 RT_TRACE(COMP_INIT, "priv->EEPROMRfCCCKChnl1TxPwLevel[0] = 0x%x\n", priv->EEPROMRfCCCKChnl1TxPwLevel[0]);
2845 RT_TRACE(COMP_INIT, "priv->EEPROMRfCCCKChnl1TxPwLevel[1] = 0x%x\n", priv->EEPROMRfCCCKChnl1TxPwLevel[1]);
2846 RT_TRACE(COMP_INIT, "priv->EEPROMRfCCCKChnl1TxPwLevel[2] = 0x%x\n", priv->EEPROMRfCCCKChnl1TxPwLevel[2]);
2847 RT_TRACE(COMP_INIT, "priv->EEPROMRfCOfdmChnlTxPwLevel[0] = 0x%x\n", priv->EEPROMRfCOfdmChnlTxPwLevel[0]);
2848 RT_TRACE(COMP_INIT, "priv->EEPROMRfCOfdmChnlTxPwLevel[1] = 0x%x\n", priv->EEPROMRfCOfdmChnlTxPwLevel[1]);
2849 RT_TRACE(COMP_INIT, "priv->EEPROMRfCOfdmChnlTxPwLevel[2] = 0x%x\n", priv->EEPROMRfCOfdmChnlTxPwLevel[2]);
2850 #endif
2854 // Update HAL variables.
2856 if(priv->epromtype == EPROM_93c46)
2858 for(i=0; i<14; i++)
2860 priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelCCK[i];
2861 priv->TxPowerLevelOFDM24G[i] = priv->EEPROMTxPowerLevelOFDM24G[i];
2863 priv->LegacyHTTxPowerDiff = priv->EEPROMLegacyHTTxPowerDiff;
2864 // Antenna B gain offset to antenna A, bit0~3
2865 priv->AntennaTxPwDiff[0] = (priv->EEPROMAntPwDiff & 0xf);
2866 // Antenna C gain offset to antenna A, bit4~7
2867 priv->AntennaTxPwDiff[1] = ((priv->EEPROMAntPwDiff & 0xf0)>>4);
2868 // Antenna D gain offset to antenna A, bit8~11
2869 priv->AntennaTxPwDiff[2] = ((priv->EEPROMAntPwDiff & 0xf00)>>8);
2870 // CrystalCap, bit12~15
2871 priv->CrystalCap = priv->EEPROMCrystalCap;
2872 // ThermalMeter, bit0~3 for RFIC1, bit4~7 for RFIC2
2873 priv->ThermalMeter[0] = (priv->EEPROMThermalMeter & 0xf);
2874 priv->ThermalMeter[1] = ((priv->EEPROMThermalMeter & 0xf0)>>4);
2876 else if(priv->epromtype == EPROM_93c56)
2878 //char cck_pwr_diff_a=0, cck_pwr_diff_c=0;
2880 //cck_pwr_diff_a = pHalData->EEPROMRfACCKChnl7TxPwLevel - pHalData->EEPROMRfAOfdmChnlTxPwLevel[1];
2881 //cck_pwr_diff_c = pHalData->EEPROMRfCCCKChnl7TxPwLevel - pHalData->EEPROMRfCOfdmChnlTxPwLevel[1];
2882 for(i=0; i<3; i++) // channel 1~3 use the same Tx Power Level.
2884 priv->TxPowerLevelCCK_A[i] = priv->EEPROMRfACCKChnl1TxPwLevel[0];
2885 priv->TxPowerLevelOFDM24G_A[i] = priv->EEPROMRfAOfdmChnlTxPwLevel[0];
2886 priv->TxPowerLevelCCK_C[i] = priv->EEPROMRfCCCKChnl1TxPwLevel[0];
2887 priv->TxPowerLevelOFDM24G_C[i] = priv->EEPROMRfCOfdmChnlTxPwLevel[0];
2889 for(i=3; i<9; i++) // channel 4~9 use the same Tx Power Level
2891 priv->TxPowerLevelCCK_A[i] = priv->EEPROMRfACCKChnl1TxPwLevel[1];
2892 priv->TxPowerLevelOFDM24G_A[i] = priv->EEPROMRfAOfdmChnlTxPwLevel[1];
2893 priv->TxPowerLevelCCK_C[i] = priv->EEPROMRfCCCKChnl1TxPwLevel[1];
2894 priv->TxPowerLevelOFDM24G_C[i] = priv->EEPROMRfCOfdmChnlTxPwLevel[1];
2896 for(i=9; i<14; i++) // channel 10~14 use the same Tx Power Level
2898 priv->TxPowerLevelCCK_A[i] = priv->EEPROMRfACCKChnl1TxPwLevel[2];
2899 priv->TxPowerLevelOFDM24G_A[i] = priv->EEPROMRfAOfdmChnlTxPwLevel[2];
2900 priv->TxPowerLevelCCK_C[i] = priv->EEPROMRfCCCKChnl1TxPwLevel[2];
2901 priv->TxPowerLevelOFDM24G_C[i] = priv->EEPROMRfCOfdmChnlTxPwLevel[2];
2903 for(i=0; i<14; i++)
2904 RT_TRACE(COMP_INIT, "priv->TxPowerLevelCCK_A[%d] = 0x%x\n", i, priv->TxPowerLevelCCK_A[i]);
2905 for(i=0; i<14; i++)
2906 RT_TRACE(COMP_INIT,"priv->TxPowerLevelOFDM24G_A[%d] = 0x%x\n", i, priv->TxPowerLevelOFDM24G_A[i]);
2907 for(i=0; i<14; i++)
2908 RT_TRACE(COMP_INIT, "priv->TxPowerLevelCCK_C[%d] = 0x%x\n", i, priv->TxPowerLevelCCK_C[i]);
2909 for(i=0; i<14; i++)
2910 RT_TRACE(COMP_INIT, "priv->TxPowerLevelOFDM24G_C[%d] = 0x%x\n", i, priv->TxPowerLevelOFDM24G_C[i]);
2911 priv->LegacyHTTxPowerDiff = priv->EEPROMLegacyHTTxPowerDiff;
2912 priv->AntennaTxPwDiff[0] = 0;
2913 priv->AntennaTxPwDiff[1] = 0;
2914 priv->AntennaTxPwDiff[2] = 0;
2915 priv->CrystalCap = priv->EEPROMCrystalCap;
2916 // ThermalMeter, bit0~3 for RFIC1, bit4~7 for RFIC2
2917 priv->ThermalMeter[0] = (priv->EEPROMThermalMeter & 0xf);
2918 priv->ThermalMeter[1] = ((priv->EEPROMThermalMeter & 0xf0)>>4);
2922 if(priv->rf_type == RF_1T2R)
2924 RT_TRACE(COMP_INIT, "\n1T2R config\n");
2926 else if (priv->rf_type == RF_2T4R)
2928 RT_TRACE(COMP_INIT, "\n2T4R config\n");
2931 // 2008/01/16 MH We can only know RF type in the function. So we have to init
2932 // DIG RATR table again.
2933 init_rate_adaptive(dev);
2935 //1 Make a copy for following variables and we can change them if we want
2937 priv->rf_chip= RF_8256;
2939 if(priv->RegChannelPlan == 0xf)
2941 priv->ChannelPlan = priv->eeprom_ChannelPlan;
2943 else
2945 priv->ChannelPlan = priv->RegChannelPlan;
2949 // Used PID and DID to Set CustomerID
2951 if( priv->eeprom_vid == 0x1186 && priv->eeprom_did == 0x3304 )
2953 priv->CustomerID = RT_CID_DLINK;
2956 switch(priv->eeprom_CustomerID)
2958 case EEPROM_CID_DEFAULT:
2959 priv->CustomerID = RT_CID_DEFAULT;
2960 break;
2961 case EEPROM_CID_CAMEO:
2962 priv->CustomerID = RT_CID_819x_CAMEO;
2963 break;
2964 case EEPROM_CID_RUNTOP:
2965 priv->CustomerID = RT_CID_819x_RUNTOP;
2966 break;
2967 case EEPROM_CID_NetCore:
2968 priv->CustomerID = RT_CID_819x_Netcore;
2969 break;
2970 case EEPROM_CID_TOSHIBA: // Merge by Jacken, 2008/01/31
2971 priv->CustomerID = RT_CID_TOSHIBA;
2972 if(priv->eeprom_ChannelPlan&0x80)
2973 priv->ChannelPlan = priv->eeprom_ChannelPlan&0x7f;
2974 else
2975 priv->ChannelPlan = 0x0;
2976 RT_TRACE(COMP_INIT, "Toshiba ChannelPlan = 0x%x\n",
2977 priv->ChannelPlan);
2978 break;
2979 case EEPROM_CID_Nettronix:
2980 priv->ScanDelay = 100; //cosa add for scan
2981 priv->CustomerID = RT_CID_Nettronix;
2982 break;
2983 case EEPROM_CID_Pronet:
2984 priv->CustomerID = RT_CID_PRONET;
2985 break;
2986 case EEPROM_CID_DLINK:
2987 priv->CustomerID = RT_CID_DLINK;
2988 break;
2990 case EEPROM_CID_WHQL:
2991 //Adapter->bInHctTest = TRUE;//do not supported
2993 //priv->bSupportTurboMode = FALSE;
2994 //priv->bAutoTurboBy8186 = FALSE;
2996 //pMgntInfo->PowerSaveControl.bInactivePs = FALSE;
2997 //pMgntInfo->PowerSaveControl.bIPSModeBackup = FALSE;
2998 //pMgntInfo->PowerSaveControl.bLeisurePs = FALSE;
3000 break;
3001 default:
3002 // value from RegCustomerID
3003 break;
3006 //Avoid the channel plan array overflow, by Bruce, 2007-08-27.
3007 if(priv->ChannelPlan > CHANNEL_PLAN_LEN - 1)
3008 priv->ChannelPlan = 0; //FCC
3010 switch(priv->CustomerID)
3012 case RT_CID_DEFAULT:
3013 #ifdef RTL8190P
3014 priv->LedStrategy = HW_LED;
3015 #else
3016 #ifdef RTL8192E
3017 priv->LedStrategy = SW_LED_MODE1;
3018 #endif
3019 #endif
3020 break;
3022 case RT_CID_819x_CAMEO:
3023 priv->LedStrategy = SW_LED_MODE2;
3024 break;
3026 case RT_CID_819x_RUNTOP:
3027 priv->LedStrategy = SW_LED_MODE3;
3028 break;
3030 case RT_CID_819x_Netcore:
3031 priv->LedStrategy = SW_LED_MODE4;
3032 break;
3034 case RT_CID_Nettronix:
3035 priv->LedStrategy = SW_LED_MODE5;
3036 break;
3038 case RT_CID_PRONET:
3039 priv->LedStrategy = SW_LED_MODE6;
3040 break;
3042 case RT_CID_TOSHIBA: //Modify by Jacken 2008/01/31
3043 // Do nothing.
3044 //break;
3046 default:
3047 #ifdef RTL8190P
3048 priv->LedStrategy = HW_LED;
3049 #else
3050 #ifdef RTL8192E
3051 priv->LedStrategy = SW_LED_MODE1;
3052 #endif
3053 #endif
3054 break;
3057 //2008.06.03, for WOL
3058 if( priv->eeprom_vid == 0x1186 && priv->eeprom_did == 0x3304)
3059 priv->ieee80211->bSupportRemoteWakeUp = TRUE;
3060 else
3061 priv->ieee80211->bSupportRemoteWakeUp = FALSE;
3063 RT_TRACE(COMP_INIT, "RegChannelPlan(%d)\n", priv->RegChannelPlan);
3064 RT_TRACE(COMP_INIT, "ChannelPlan = %d \n", priv->ChannelPlan);
3065 RT_TRACE(COMP_INIT, "LedStrategy = %d \n", priv->LedStrategy);
3066 RT_TRACE(COMP_TRACE, "<==== ReadAdapterInfo\n");
3068 return ;
3072 static short rtl8192_get_channel_map(struct net_device * dev)
3074 struct r8192_priv *priv = ieee80211_priv(dev);
3075 #ifdef ENABLE_DOT11D
3076 if(priv->ChannelPlan> COUNTRY_CODE_GLOBAL_DOMAIN){
3077 printk("rtl8180_init:Error channel plan! Set to default.\n");
3078 priv->ChannelPlan= 0;
3080 RT_TRACE(COMP_INIT, "Channel plan is %d\n",priv->ChannelPlan);
3082 rtl819x_set_channel_map(priv->ChannelPlan, priv);
3083 #else
3084 int ch,i;
3085 //Set Default Channel Plan
3086 if(!channels){
3087 DMESG("No channels, aborting");
3088 return -1;
3090 ch=channels;
3091 priv->ChannelPlan= 0;//hikaru
3092 // set channels 1..14 allowed in given locale
3093 for (i=1; i<=14; i++) {
3094 (priv->ieee80211->channel_map)[i] = (u8)(ch & 0x01);
3095 ch >>= 1;
3097 #endif
3098 return 0;
3101 static short rtl8192_init(struct net_device *dev)
3103 struct r8192_priv *priv = ieee80211_priv(dev);
3104 memset(&(priv->stats),0,sizeof(struct Stats));
3105 rtl8192_init_priv_variable(dev);
3106 rtl8192_init_priv_lock(priv);
3107 rtl8192_init_priv_task(dev);
3108 rtl8192_get_eeprom_size(dev);
3109 rtl8192_read_eeprom_info(dev);
3110 rtl8192_get_channel_map(dev);
3111 init_hal_dm(dev);
3112 init_timer(&priv->watch_dog_timer);
3113 priv->watch_dog_timer.data = (unsigned long)dev;
3114 priv->watch_dog_timer.function = watch_dog_timer_callback;
3115 #if defined(IRQF_SHARED)
3116 if(request_irq(dev->irq, (void*)rtl8192_interrupt, IRQF_SHARED, dev->name, dev)){
3117 #else
3118 if(request_irq(dev->irq, (void *)rtl8192_interrupt, SA_SHIRQ, dev->name, dev)){
3119 #endif
3120 printk("Error allocating IRQ %d",dev->irq);
3121 return -1;
3122 }else{
3123 priv->irq=dev->irq;
3124 printk("IRQ %d",dev->irq);
3126 if(rtl8192_pci_initdescring(dev)!=0){
3127 printk("Endopoints initialization failed");
3128 return -1;
3131 //rtl8192_rx_enable(dev);
3132 //rtl8192_adapter_start(dev);
3133 return 0;
3136 /******************************************************************************
3137 *function: This function actually only set RRSR, RATR and BW_OPMODE registers
3138 * not to do all the hw config as its name says
3139 * input: net_device dev
3140 * output: none
3141 * return: none
3142 * notice: This part need to modified according to the rate set we filtered
3143 * ****************************************************************************/
3144 static void rtl8192_hwconfig(struct net_device* dev)
3146 u32 regRATR = 0, regRRSR = 0;
3147 u8 regBwOpMode = 0, regTmp = 0;
3148 struct r8192_priv *priv = ieee80211_priv(dev);
3150 // Set RRSR, RATR, and BW_OPMODE registers
3152 switch(priv->ieee80211->mode)
3154 case WIRELESS_MODE_B:
3155 regBwOpMode = BW_OPMODE_20MHZ;
3156 regRATR = RATE_ALL_CCK;
3157 regRRSR = RATE_ALL_CCK;
3158 break;
3159 case WIRELESS_MODE_A:
3160 regBwOpMode = BW_OPMODE_5G |BW_OPMODE_20MHZ;
3161 regRATR = RATE_ALL_OFDM_AG;
3162 regRRSR = RATE_ALL_OFDM_AG;
3163 break;
3164 case WIRELESS_MODE_G:
3165 regBwOpMode = BW_OPMODE_20MHZ;
3166 regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
3167 regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
3168 break;
3169 case WIRELESS_MODE_AUTO:
3170 case WIRELESS_MODE_N_24G:
3171 // It support CCK rate by default.
3172 // CCK rate will be filtered out only when associated AP does not support it.
3173 regBwOpMode = BW_OPMODE_20MHZ;
3174 regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
3175 regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
3176 break;
3177 case WIRELESS_MODE_N_5G:
3178 regBwOpMode = BW_OPMODE_5G;
3179 regRATR = RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
3180 regRRSR = RATE_ALL_OFDM_AG;
3181 break;
3184 write_nic_byte(dev, BW_OPMODE, regBwOpMode);
3186 u32 ratr_value = 0;
3187 ratr_value = regRATR;
3188 if (priv->rf_type == RF_1T2R)
3190 ratr_value &= ~(RATE_ALL_OFDM_2SS);
3192 write_nic_dword(dev, RATR0, ratr_value);
3193 write_nic_byte(dev, UFWP, 1);
3195 regTmp = read_nic_byte(dev, 0x313);
3196 regRRSR = ((regTmp) << 24) | (regRRSR & 0x00ffffff);
3197 write_nic_dword(dev, RRSR, regRRSR);
3200 // Set Retry Limit here
3202 write_nic_word(dev, RETRY_LIMIT,
3203 priv->ShortRetryLimit << RETRY_LIMIT_SHORT_SHIFT | \
3204 priv->LongRetryLimit << RETRY_LIMIT_LONG_SHIFT);
3205 // Set Contention Window here
3207 // Set Tx AGC
3209 // Set Tx Antenna including Feedback control
3211 // Set Auto Rate fallback control
3217 static RT_STATUS rtl8192_adapter_start(struct net_device *dev)
3219 struct r8192_priv *priv = ieee80211_priv(dev);
3220 // struct ieee80211_device *ieee = priv->ieee80211;
3221 u32 ulRegRead;
3222 RT_STATUS rtStatus = RT_STATUS_SUCCESS;
3223 // static char szMACPHYRegFile[] = RTL819X_PHY_MACPHY_REG;
3224 // static char szMACPHYRegPGFile[] = RTL819X_PHY_MACPHY_REG_PG;
3225 //u8 eRFPath;
3226 u8 tmpvalue;
3227 #ifdef RTL8192E
3228 u8 ICVersion,SwitchingRegulatorOutput;
3229 #endif
3230 bool bfirmwareok = true;
3231 #ifdef RTL8190P
3232 u8 ucRegRead;
3233 #endif
3234 u32 tmpRegA, tmpRegC, TempCCk;
3235 int i =0;
3236 // u32 dwRegRead = 0;
3238 RT_TRACE(COMP_INIT, "====>%s()\n", __FUNCTION__);
3239 priv->being_init_adapter = true;
3240 rtl8192_pci_resetdescring(dev);
3241 // 2007/11/02 MH Before initalizing RF. We can not use FW to do RF-R/W.
3242 priv->Rf_Mode = RF_OP_By_SW_3wire;
3243 #ifdef RTL8192E
3244 //dPLL on
3245 if(priv->ResetProgress == RESET_TYPE_NORESET)
3247 write_nic_byte(dev, ANAPAR, 0x37);
3248 // Accordign to designer's explain, LBUS active will never > 10ms. We delay 10ms
3249 // Joseph increae the time to prevent firmware download fail
3250 mdelay(500);
3252 #endif
3253 //PlatformSleepUs(10000);
3254 // For any kind of InitializeAdapter process, we shall use system now!!
3255 priv->pFirmware->firmware_status = FW_STATUS_0_INIT;
3257 // Set to eRfoff in order not to count receive count.
3258 if(priv->RegRfOff == TRUE)
3259 priv->ieee80211->eRFPowerState = eRfOff;
3262 //3 //Config CPUReset Register
3263 //3//
3264 //3 Firmware Reset Or Not
3265 ulRegRead = read_nic_dword(dev, CPU_GEN);
3266 if(priv->pFirmware->firmware_status == FW_STATUS_0_INIT)
3267 { //called from MPInitialized. do nothing
3268 ulRegRead |= CPU_GEN_SYSTEM_RESET;
3269 }else if(priv->pFirmware->firmware_status == FW_STATUS_5_READY)
3270 ulRegRead |= CPU_GEN_FIRMWARE_RESET; // Called from MPReset
3271 else
3272 RT_TRACE(COMP_ERR, "ERROR in %s(): undefined firmware state(%d)\n", __FUNCTION__, priv->pFirmware->firmware_status);
3274 #ifdef RTL8190P
3275 //2008.06.03, for WOL 90 hw bug
3276 ulRegRead &= (~(CPU_GEN_GPIO_UART));
3277 #endif
3279 write_nic_dword(dev, CPU_GEN, ulRegRead);
3280 //mdelay(100);
3282 #ifdef RTL8192E
3284 //3//
3285 //3 //Fix the issue of E-cut high temperature issue
3286 //3//
3287 // TODO: E cut only
3288 ICVersion = read_nic_byte(dev, IC_VERRSION);
3289 if(ICVersion >= 0x4) //E-cut only
3291 // HW SD suggest that we should not wirte this register too often, so driver
3292 // should readback this register. This register will be modified only when
3293 // power on reset
3294 SwitchingRegulatorOutput = read_nic_byte(dev, SWREGULATOR);
3295 if(SwitchingRegulatorOutput != 0xb8)
3297 write_nic_byte(dev, SWREGULATOR, 0xa8);
3298 mdelay(1);
3299 write_nic_byte(dev, SWREGULATOR, 0xb8);
3302 #endif
3305 //3//
3306 //3// Initialize BB before MAC
3307 //3//
3308 RT_TRACE(COMP_INIT, "BB Config Start!\n");
3309 rtStatus = rtl8192_BBConfig(dev);
3310 if(rtStatus != RT_STATUS_SUCCESS)
3312 RT_TRACE(COMP_ERR, "BB Config failed\n");
3313 return rtStatus;
3315 RT_TRACE(COMP_INIT,"BB Config Finished!\n");
3317 //3//Set Loopback mode or Normal mode
3318 //3//
3319 //2006.12.13 by emily. Note!We should not merge these two CPU_GEN register writings
3320 // because setting of System_Reset bit reset MAC to default transmission mode.
3321 //Loopback mode or not
3322 priv->LoopbackMode = RTL819X_NO_LOOPBACK;
3323 //priv->LoopbackMode = RTL819X_MAC_LOOPBACK;
3324 if(priv->ResetProgress == RESET_TYPE_NORESET)
3326 ulRegRead = read_nic_dword(dev, CPU_GEN);
3327 if(priv->LoopbackMode == RTL819X_NO_LOOPBACK)
3329 ulRegRead = ((ulRegRead & CPU_GEN_NO_LOOPBACK_MSK) | CPU_GEN_NO_LOOPBACK_SET);
3331 else if (priv->LoopbackMode == RTL819X_MAC_LOOPBACK )
3333 ulRegRead |= CPU_CCK_LOOPBACK;
3335 else
3337 RT_TRACE(COMP_ERR,"Serious error: wrong loopback mode setting\n");
3340 //2008.06.03, for WOL
3341 //ulRegRead &= (~(CPU_GEN_GPIO_UART));
3342 write_nic_dword(dev, CPU_GEN, ulRegRead);
3344 // 2006.11.29. After reset cpu, we sholud wait for a second, otherwise, it may fail to write registers. Emily
3345 udelay(500);
3347 //3Set Hardware(Do nothing now)
3348 rtl8192_hwconfig(dev);
3349 //2=======================================================
3350 // Common Setting for all of the FPGA platform. (part 1)
3351 //2=======================================================
3352 // If there is changes, please make sure it applies to all of the FPGA version
3353 //3 Turn on Tx/Rx
3354 write_nic_byte(dev, CMDR, CR_RE|CR_TE);
3356 //2Set Tx dma burst
3357 #ifdef RTL8190P
3358 write_nic_byte(dev, PCIF, ((MXDMA2_NoLimit<<MXDMA2_RX_SHIFT) | \
3359 (MXDMA2_NoLimit<<MXDMA2_TX_SHIFT) | \
3360 (1<<MULRW_SHIFT)));
3361 #else
3362 #ifdef RTL8192E
3363 write_nic_byte(dev, PCIF, ((MXDMA2_NoLimit<<MXDMA2_RX_SHIFT) |\
3364 (MXDMA2_NoLimit<<MXDMA2_TX_SHIFT) ));
3365 #endif
3366 #endif
3367 //set IDR0 here
3368 write_nic_dword(dev, MAC0, ((u32*)dev->dev_addr)[0]);
3369 write_nic_word(dev, MAC4, ((u16*)(dev->dev_addr + 4))[0]);
3370 //set RCR
3371 write_nic_dword(dev, RCR, priv->ReceiveConfig);
3373 //3 Initialize Number of Reserved Pages in Firmware Queue
3374 #ifdef TO_DO_LIST
3375 if(priv->bInHctTest)
3377 PlatformEFIOWrite4Byte(Adapter, RQPN1, NUM_OF_PAGE_IN_FW_QUEUE_BK_DTM << RSVD_FW_QUEUE_PAGE_BK_SHIFT |\
3378 NUM_OF_PAGE_IN_FW_QUEUE_BE_DTM << RSVD_FW_QUEUE_PAGE_BE_SHIFT | \
3379 NUM_OF_PAGE_IN_FW_QUEUE_VI_DTM << RSVD_FW_QUEUE_PAGE_VI_SHIFT | \
3380 NUM_OF_PAGE_IN_FW_QUEUE_VO_DTM <<RSVD_FW_QUEUE_PAGE_VO_SHIFT);
3381 PlatformEFIOWrite4Byte(Adapter, RQPN2, NUM_OF_PAGE_IN_FW_QUEUE_MGNT << RSVD_FW_QUEUE_PAGE_MGNT_SHIFT);
3382 PlatformEFIOWrite4Byte(Adapter, RQPN3, APPLIED_RESERVED_QUEUE_IN_FW| \
3383 NUM_OF_PAGE_IN_FW_QUEUE_BCN<<RSVD_FW_QUEUE_PAGE_BCN_SHIFT|\
3384 NUM_OF_PAGE_IN_FW_QUEUE_PUB_DTM<<RSVD_FW_QUEUE_PAGE_PUB_SHIFT);
3386 else
3387 #endif
3389 write_nic_dword(dev, RQPN1, NUM_OF_PAGE_IN_FW_QUEUE_BK << RSVD_FW_QUEUE_PAGE_BK_SHIFT |\
3390 NUM_OF_PAGE_IN_FW_QUEUE_BE << RSVD_FW_QUEUE_PAGE_BE_SHIFT | \
3391 NUM_OF_PAGE_IN_FW_QUEUE_VI << RSVD_FW_QUEUE_PAGE_VI_SHIFT | \
3392 NUM_OF_PAGE_IN_FW_QUEUE_VO <<RSVD_FW_QUEUE_PAGE_VO_SHIFT);
3393 write_nic_dword(dev, RQPN2, NUM_OF_PAGE_IN_FW_QUEUE_MGNT << RSVD_FW_QUEUE_PAGE_MGNT_SHIFT);
3394 write_nic_dword(dev, RQPN3, APPLIED_RESERVED_QUEUE_IN_FW| \
3395 NUM_OF_PAGE_IN_FW_QUEUE_BCN<<RSVD_FW_QUEUE_PAGE_BCN_SHIFT|\
3396 NUM_OF_PAGE_IN_FW_QUEUE_PUB<<RSVD_FW_QUEUE_PAGE_PUB_SHIFT);
3399 rtl8192_tx_enable(dev);
3400 rtl8192_rx_enable(dev);
3401 //3Set Response Rate Setting Register
3402 // CCK rate is supported by default.
3403 // CCK rate will be filtered out only when associated AP does not support it.
3404 ulRegRead = (0xFFF00000 & read_nic_dword(dev, RRSR)) | RATE_ALL_OFDM_AG | RATE_ALL_CCK;
3405 write_nic_dword(dev, RRSR, ulRegRead);
3406 write_nic_dword(dev, RATR0+4*7, (RATE_ALL_OFDM_AG | RATE_ALL_CCK));
3408 //2Set AckTimeout
3409 // TODO: (it value is only for FPGA version). need to be changed!!2006.12.18, by Emily
3410 write_nic_byte(dev, ACK_TIMEOUT, 0x30);
3412 //rtl8192_actset_wirelessmode(dev,priv->RegWirelessMode);
3413 if(priv->ResetProgress == RESET_TYPE_NORESET)
3414 rtl8192_SetWirelessMode(dev, priv->ieee80211->mode);
3415 //-----------------------------------------------------------------------------
3416 // Set up security related. 070106, by rcnjko:
3417 // 1. Clear all H/W keys.
3418 // 2. Enable H/W encryption/decryption.
3419 //-----------------------------------------------------------------------------
3420 CamResetAllEntry(dev);
3422 u8 SECR_value = 0x0;
3423 SECR_value |= SCR_TxEncEnable;
3424 SECR_value |= SCR_RxDecEnable;
3425 SECR_value |= SCR_NoSKMC;
3426 write_nic_byte(dev, SECR, SECR_value);
3428 //3Beacon related
3429 write_nic_word(dev, ATIMWND, 2);
3430 write_nic_word(dev, BCN_INTERVAL, 100);
3431 for (i=0; i<QOS_QUEUE_NUM; i++)
3432 write_nic_dword(dev, WDCAPARA_ADD[i], 0x005e4332);
3434 // Switching regulator controller: This is set temporarily.
3435 // It's not sure if this can be removed in the future.
3436 // PJ advised to leave it by default.
3438 write_nic_byte(dev, 0xbe, 0xc0);
3440 //2=======================================================
3441 // Set PHY related configuration defined in MAC register bank
3442 //2=======================================================
3443 rtl8192_phy_configmac(dev);
3445 if (priv->card_8192_version > (u8) VERSION_8190_BD) {
3446 rtl8192_phy_getTxPower(dev);
3447 rtl8192_phy_setTxPower(dev, priv->chan);
3450 //if D or C cut
3451 tmpvalue = read_nic_byte(dev, IC_VERRSION);
3452 priv->IC_Cut = tmpvalue;
3453 RT_TRACE(COMP_INIT, "priv->IC_Cut = 0x%x\n", priv->IC_Cut);
3454 if(priv->IC_Cut >= IC_VersionCut_D)
3456 //pHalData->bDcut = TRUE;
3457 if(priv->IC_Cut == IC_VersionCut_D)
3458 RT_TRACE(COMP_INIT, "D-cut\n");
3459 if(priv->IC_Cut == IC_VersionCut_E)
3461 RT_TRACE(COMP_INIT, "E-cut\n");
3462 // HW SD suggest that we should not wirte this register too often, so driver
3463 // should readback this register. This register will be modified only when
3464 // power on reset
3467 else
3469 //pHalData->bDcut = FALSE;
3470 RT_TRACE(COMP_INIT, "Before C-cut\n");
3473 #if 1
3474 //Firmware download
3475 RT_TRACE(COMP_INIT, "Load Firmware!\n");
3476 bfirmwareok = init_firmware(dev);
3477 if(bfirmwareok != true) {
3478 rtStatus = RT_STATUS_FAILURE;
3479 return rtStatus;
3481 RT_TRACE(COMP_INIT, "Load Firmware finished!\n");
3482 #endif
3483 //RF config
3484 if(priv->ResetProgress == RESET_TYPE_NORESET)
3486 RT_TRACE(COMP_INIT, "RF Config Started!\n");
3487 rtStatus = rtl8192_phy_RFConfig(dev);
3488 if(rtStatus != RT_STATUS_SUCCESS)
3490 RT_TRACE(COMP_ERR, "RF Config failed\n");
3491 return rtStatus;
3493 RT_TRACE(COMP_INIT, "RF Config Finished!\n");
3495 rtl8192_phy_updateInitGain(dev);
3497 /*---- Set CCK and OFDM Block "ON"----*/
3498 rtl8192_setBBreg(dev, rFPGA0_RFMOD, bCCKEn, 0x1);
3499 rtl8192_setBBreg(dev, rFPGA0_RFMOD, bOFDMEn, 0x1);
3501 #ifdef RTL8192E
3502 //Enable Led
3503 write_nic_byte(dev, 0x87, 0x0);
3504 #endif
3505 #ifdef RTL8190P
3506 //2008.06.03, for WOL
3507 ucRegRead = read_nic_byte(dev, GPE);
3508 ucRegRead |= BIT0;
3509 write_nic_byte(dev, GPE, ucRegRead);
3511 ucRegRead = read_nic_byte(dev, GPO);
3512 ucRegRead &= ~BIT0;
3513 write_nic_byte(dev, GPO, ucRegRead);
3514 #endif
3516 //2=======================================================
3517 // RF Power Save
3518 //2=======================================================
3519 #ifdef ENABLE_IPS
3522 if(priv->RegRfOff == TRUE)
3523 { // User disable RF via registry.
3524 RT_TRACE((COMP_INIT|COMP_RF|COMP_POWER), "%s(): Turn off RF for RegRfOff ----------\n",__FUNCTION__);
3525 MgntActSet_RF_State(dev, eRfOff, RF_CHANGE_BY_SW);
3526 #if 0//cosa, ask SD3 willis and he doesn't know what is this for
3527 // Those action will be discard in MgntActSet_RF_State because off the same state
3528 for(eRFPath = 0; eRFPath <pHalData->NumTotalRFPath; eRFPath++)
3529 PHY_SetRFReg(Adapter, (RF90_RADIO_PATH_E)eRFPath, 0x4, 0xC00, 0x0);
3530 #endif
3532 else if(priv->ieee80211->RfOffReason > RF_CHANGE_BY_PS)
3533 { // H/W or S/W RF OFF before sleep.
3534 RT_TRACE((COMP_INIT|COMP_RF|COMP_POWER), "%s(): Turn off RF for RfOffReason(%d) ----------\n", __FUNCTION__,priv->ieee80211->RfOffReason);
3535 MgntActSet_RF_State(dev, eRfOff, priv->ieee80211->RfOffReason);
3537 else if(priv->ieee80211->RfOffReason >= RF_CHANGE_BY_IPS)
3538 { // H/W or S/W RF OFF before sleep.
3539 RT_TRACE((COMP_INIT|COMP_RF|COMP_POWER), "%s(): Turn off RF for RfOffReason(%d) ----------\n", __FUNCTION__,priv->ieee80211->RfOffReason);
3540 MgntActSet_RF_State(dev, eRfOff, priv->ieee80211->RfOffReason);
3542 else
3544 RT_TRACE((COMP_INIT|COMP_RF|COMP_POWER), "%s(): RF-ON \n",__FUNCTION__);
3545 priv->ieee80211->eRFPowerState = eRfOn;
3546 priv->ieee80211->RfOffReason = 0;
3547 //DrvIFIndicateCurrentPhyStatus(Adapter);
3548 // LED control
3549 //Adapter->HalFunc.LedControlHandler(Adapter, LED_CTL_POWER_ON);
3552 // If inactive power mode is enabled, disable rf while in disconnected state.
3553 // But we should still tell upper layer we are in rf on state.
3554 // 2007.07.16, by shien chang.
3556 //if(!Adapter->bInHctTest)
3557 //IPSEnter(Adapter);
3561 #endif
3562 if(1){
3563 #ifdef RTL8192E
3564 // We can force firmware to do RF-R/W
3565 if(priv->ieee80211->FwRWRF)
3566 priv->Rf_Mode = RF_OP_By_FW;
3567 else
3568 priv->Rf_Mode = RF_OP_By_SW_3wire;
3569 #else
3570 priv->Rf_Mode = RF_OP_By_SW_3wire;
3571 #endif
3573 #ifdef RTL8190P
3574 if(priv->ResetProgress == RESET_TYPE_NORESET)
3576 dm_initialize_txpower_tracking(dev);
3578 tmpRegA= rtl8192_QueryBBReg(dev,rOFDM0_XATxIQImbalance,bMaskDWord);
3579 tmpRegC= rtl8192_QueryBBReg(dev,rOFDM0_XCTxIQImbalance,bMaskDWord);
3581 if(priv->rf_type == RF_2T4R){
3582 for(i = 0; i<TxBBGainTableLength; i++)
3584 if(tmpRegA == priv->txbbgain_table[i].txbbgain_value)
3586 priv->rfa_txpowertrackingindex= (u8)i;
3587 priv->rfa_txpowertrackingindex_real= (u8)i;
3588 priv->rfa_txpowertracking_default = priv->rfa_txpowertrackingindex;
3589 break;
3593 for(i = 0; i<TxBBGainTableLength; i++)
3595 if(tmpRegC == priv->txbbgain_table[i].txbbgain_value)
3597 priv->rfc_txpowertrackingindex= (u8)i;
3598 priv->rfc_txpowertrackingindex_real= (u8)i;
3599 priv->rfc_txpowertracking_default = priv->rfc_txpowertrackingindex;
3600 break;
3603 TempCCk = rtl8192_QueryBBReg(dev, rCCK0_TxFilter1, bMaskByte2);
3605 for(i=0 ; i<CCKTxBBGainTableLength ; i++)
3607 if(TempCCk == priv->cck_txbbgain_table[i].ccktxbb_valuearray[0])
3609 priv->CCKPresentAttentuation_20Mdefault =(u8) i;
3610 break;
3613 priv->CCKPresentAttentuation_40Mdefault = 0;
3614 priv->CCKPresentAttentuation_difference = 0;
3615 priv->CCKPresentAttentuation = priv->CCKPresentAttentuation_20Mdefault;
3616 RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex_initial = %d\n", priv->rfa_txpowertrackingindex);
3617 RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex_real__initial = %d\n", priv->rfa_txpowertrackingindex_real);
3618 RT_TRACE(COMP_POWER_TRACKING, "priv->rfc_txpowertrackingindex_initial = %d\n", priv->rfc_txpowertrackingindex);
3619 RT_TRACE(COMP_POWER_TRACKING, "priv->rfc_txpowertrackingindex_real_initial = %d\n", priv->rfc_txpowertrackingindex_real);
3620 RT_TRACE(COMP_POWER_TRACKING, "priv->CCKPresentAttentuation_difference_initial = %d\n", priv->CCKPresentAttentuation_difference);
3621 RT_TRACE(COMP_POWER_TRACKING, "priv->CCKPresentAttentuation_initial = %d\n", priv->CCKPresentAttentuation);
3623 #else
3624 #ifdef RTL8192E
3625 if(priv->ResetProgress == RESET_TYPE_NORESET)
3627 dm_initialize_txpower_tracking(dev);
3629 if(priv->IC_Cut >= IC_VersionCut_D)
3631 tmpRegA= rtl8192_QueryBBReg(dev,rOFDM0_XATxIQImbalance,bMaskDWord);
3632 tmpRegC= rtl8192_QueryBBReg(dev,rOFDM0_XCTxIQImbalance,bMaskDWord);
3633 for(i = 0; i<TxBBGainTableLength; i++)
3635 if(tmpRegA == priv->txbbgain_table[i].txbbgain_value)
3637 priv->rfa_txpowertrackingindex= (u8)i;
3638 priv->rfa_txpowertrackingindex_real= (u8)i;
3639 priv->rfa_txpowertracking_default = priv->rfa_txpowertrackingindex;
3640 break;
3644 TempCCk = rtl8192_QueryBBReg(dev, rCCK0_TxFilter1, bMaskByte2);
3646 for(i=0 ; i<CCKTxBBGainTableLength ; i++)
3648 if(TempCCk == priv->cck_txbbgain_table[i].ccktxbb_valuearray[0])
3650 priv->CCKPresentAttentuation_20Mdefault =(u8) i;
3651 break;
3654 priv->CCKPresentAttentuation_40Mdefault = 0;
3655 priv->CCKPresentAttentuation_difference = 0;
3656 priv->CCKPresentAttentuation = priv->CCKPresentAttentuation_20Mdefault;
3657 RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex_initial = %d\n", priv->rfa_txpowertrackingindex);
3658 RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex_real__initial = %d\n", priv->rfa_txpowertrackingindex_real);
3659 RT_TRACE(COMP_POWER_TRACKING, "priv->CCKPresentAttentuation_difference_initial = %d\n", priv->CCKPresentAttentuation_difference);
3660 RT_TRACE(COMP_POWER_TRACKING, "priv->CCKPresentAttentuation_initial = %d\n", priv->CCKPresentAttentuation);
3661 priv->btxpower_tracking = FALSE;//TEMPLY DISABLE
3664 #endif
3665 #endif
3666 rtl8192_irq_enable(dev);
3667 priv->being_init_adapter = false;
3668 return rtStatus;
3672 void rtl8192_prepare_beacon(struct r8192_priv *priv)
3674 struct sk_buff *skb;
3675 //unsigned long flags;
3676 cb_desc *tcb_desc;
3678 skb = ieee80211_get_beacon(priv->ieee80211);
3679 tcb_desc = (cb_desc *)(skb->cb + 8);
3680 //printk("===========> %s\n", __FUNCTION__);
3681 //spin_lock_irqsave(&priv->tx_lock,flags);
3682 /* prepare misc info for the beacon xmit */
3683 tcb_desc->queue_index = BEACON_QUEUE;
3684 /* IBSS does not support HT yet, use 1M defautly */
3685 tcb_desc->data_rate = 2;
3686 tcb_desc->RATRIndex = 7;
3687 tcb_desc->bTxDisableRateFallBack = 1;
3688 tcb_desc->bTxUseDriverAssingedRate = 1;
3690 skb_push(skb, priv->ieee80211->tx_headroom);
3691 if(skb){
3692 rtl8192_tx(priv->ieee80211->dev,skb);
3694 //spin_unlock_irqrestore (&priv->tx_lock, flags);
3698 /* this configures registers for beacon tx and enables it via
3699 * rtl8192_beacon_tx_enable(). rtl8192_beacon_tx_disable() might
3700 * be used to stop beacon transmission
3702 void rtl8192_start_beacon(struct net_device *dev)
3704 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
3705 struct ieee80211_network *net = &priv->ieee80211->current_network;
3706 u16 BcnTimeCfg = 0;
3707 u16 BcnCW = 6;
3708 u16 BcnIFS = 0xf;
3710 DMESG("Enabling beacon TX");
3711 //rtl8192_prepare_beacon(dev);
3712 rtl8192_irq_disable(dev);
3713 //rtl8192_beacon_tx_enable(dev);
3715 /* ATIM window */
3716 write_nic_word(dev, ATIMWND, 2);
3718 /* Beacon interval (in unit of TU) */
3719 write_nic_word(dev, BCN_INTERVAL, net->beacon_interval);
3722 * DrvErlyInt (in unit of TU).
3723 * (Time to send interrupt to notify driver to c
3724 * hange beacon content)
3725 * */
3726 write_nic_word(dev, BCN_DRV_EARLY_INT, 10);
3729 * BcnDMATIM(in unit of us).
3730 * Indicates the time before TBTT to perform beacon queue DMA
3731 * */
3732 write_nic_word(dev, BCN_DMATIME, 256);
3735 * Force beacon frame transmission even after receiving
3736 * beacon frame from other ad hoc STA
3737 * */
3738 write_nic_byte(dev, BCN_ERR_THRESH, 100);
3740 /* Set CW and IFS */
3741 BcnTimeCfg |= BcnCW<<BCN_TCFG_CW_SHIFT;
3742 BcnTimeCfg |= BcnIFS<<BCN_TCFG_IFS;
3743 write_nic_word(dev, BCN_TCFG, BcnTimeCfg);
3746 /* enable the interrupt for ad-hoc process */
3747 rtl8192_irq_enable(dev);
3749 /***************************************************************************
3750 -------------------------------NET STUFF---------------------------
3751 ***************************************************************************/
3755 static bool HalTxCheckStuck8190Pci(struct net_device *dev)
3757 u16 RegTxCounter = read_nic_word(dev, 0x128);
3758 struct r8192_priv *priv = ieee80211_priv(dev);
3759 bool bStuck = FALSE;
3760 RT_TRACE(COMP_RESET,"%s():RegTxCounter is %d,TxCounter is %d\n",__FUNCTION__,RegTxCounter,priv->TxCounter);
3761 if(priv->TxCounter==RegTxCounter)
3762 bStuck = TRUE;
3764 priv->TxCounter = RegTxCounter;
3766 return bStuck;
3770 * <Assumption: RT_TX_SPINLOCK is acquired.>
3771 * First added: 2006.11.19 by emily
3773 static RESET_TYPE
3774 TxCheckStuck(struct net_device *dev)
3776 struct r8192_priv *priv = ieee80211_priv(dev);
3777 u8 QueueID;
3778 ptx_ring head=NULL,tail=NULL,txring = NULL;
3779 u8 ResetThreshold = NIC_SEND_HANG_THRESHOLD_POWERSAVE;
3780 bool bCheckFwTxCnt = false;
3781 //unsigned long flags;
3784 // Decide Stuch threshold according to current power save mode
3786 //printk("++++++++++++>%s()\n",__FUNCTION__);
3787 switch (priv->ieee80211->dot11PowerSaveMode)
3789 // The threshold value may required to be adjusted .
3790 case eActive: // Active/Continuous access.
3791 ResetThreshold = NIC_SEND_HANG_THRESHOLD_NORMAL;
3792 break;
3793 case eMaxPs: // Max power save mode.
3794 ResetThreshold = NIC_SEND_HANG_THRESHOLD_POWERSAVE;
3795 break;
3796 case eFastPs: // Fast power save mode.
3797 ResetThreshold = NIC_SEND_HANG_THRESHOLD_POWERSAVE;
3798 break;
3802 // Check whether specific tcb has been queued for a specific time
3804 for(QueueID = 0; QueueID < MAX_TX_QUEUE; QueueID++)
3808 if(QueueID == TXCMD_QUEUE)
3809 continue;
3811 switch(QueueID) {
3812 case MGNT_QUEUE:
3813 tail=priv->txmapringtail;
3814 head=priv->txmapringhead;
3815 break;
3817 case BK_QUEUE:
3818 tail=priv->txbkpringtail;
3819 head=priv->txbkpringhead;
3820 break;
3822 case BE_QUEUE:
3823 tail=priv->txbepringtail;
3824 head=priv->txbepringhead;
3825 break;
3827 case VI_QUEUE:
3828 tail=priv->txvipringtail;
3829 head=priv->txvipringhead;
3830 break;
3832 case VO_QUEUE:
3833 tail=priv->txvopringtail;
3834 head=priv->txvopringhead;
3835 break;
3837 default:
3838 tail=head=NULL;
3839 break;
3842 if(tail == head)
3843 continue;
3844 else
3846 txring = head;
3847 if(txring == NULL)
3849 RT_TRACE(COMP_ERR,"%s():txring is NULL , BUG!\n",__FUNCTION__);
3850 continue;
3852 txring->nStuckCount++;
3853 bCheckFwTxCnt = TRUE;
3856 #if 1
3857 if(bCheckFwTxCnt)
3859 if(HalTxCheckStuck8190Pci(dev))
3861 RT_TRACE(COMP_RESET, "TxCheckStuck(): Fw indicates no Tx condition! \n");
3862 return RESET_TYPE_SILENT;
3865 #endif
3866 return RESET_TYPE_NORESET;
3870 static bool HalRxCheckStuck8190Pci(struct net_device *dev)
3872 struct r8192_priv *priv = ieee80211_priv(dev);
3873 u16 RegRxCounter = read_nic_word(dev, 0x130);
3874 bool bStuck = FALSE;
3875 static u8 rx_chk_cnt = 0;
3876 RT_TRACE(COMP_RESET,"%s(): RegRxCounter is %d,RxCounter is %d\n",__FUNCTION__,RegRxCounter,priv->RxCounter);
3877 // If rssi is small, we should check rx for long time because of bad rx.
3878 // or maybe it will continuous silent reset every 2 seconds.
3879 rx_chk_cnt++;
3880 if(priv->undecorated_smoothed_pwdb >= (RateAdaptiveTH_High+5))
3882 rx_chk_cnt = 0; //high rssi, check rx stuck right now.
3884 else if(priv->undecorated_smoothed_pwdb < (RateAdaptiveTH_High+5) &&
3885 ((priv->CurrentChannelBW!=HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb>=RateAdaptiveTH_Low_40M) ||
3886 (priv->CurrentChannelBW==HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb>=RateAdaptiveTH_Low_20M)) )
3889 if(rx_chk_cnt < 2)
3891 return bStuck;
3893 else
3895 rx_chk_cnt = 0;
3898 else if(((priv->CurrentChannelBW!=HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb<RateAdaptiveTH_Low_40M) ||
3899 (priv->CurrentChannelBW==HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb<RateAdaptiveTH_Low_20M)) &&
3900 priv->undecorated_smoothed_pwdb >= VeryLowRSSI)
3902 if(rx_chk_cnt < 4)
3904 //DbgPrint("RSSI < %d && RSSI >= %d, no check this time \n", RateAdaptiveTH_Low, VeryLowRSSI);
3905 return bStuck;
3907 else
3909 rx_chk_cnt = 0;
3910 //DbgPrint("RSSI < %d && RSSI >= %d, check this time \n", RateAdaptiveTH_Low, VeryLowRSSI);
3913 else
3915 if(rx_chk_cnt < 8)
3917 //DbgPrint("RSSI <= %d, no check this time \n", VeryLowRSSI);
3918 return bStuck;
3920 else
3922 rx_chk_cnt = 0;
3923 //DbgPrint("RSSI <= %d, check this time \n", VeryLowRSSI);
3926 if(priv->RxCounter==RegRxCounter)
3927 bStuck = TRUE;
3929 priv->RxCounter = RegRxCounter;
3931 return bStuck;
3934 static RESET_TYPE RxCheckStuck(struct net_device *dev)
3937 if(HalRxCheckStuck8190Pci(dev))
3939 RT_TRACE(COMP_RESET, "RxStuck Condition\n");
3940 return RESET_TYPE_SILENT;
3943 return RESET_TYPE_NORESET;
3946 static RESET_TYPE
3947 rtl819x_ifcheck_resetornot(struct net_device *dev)
3949 struct r8192_priv *priv = ieee80211_priv(dev);
3950 RESET_TYPE TxResetType = RESET_TYPE_NORESET;
3951 RESET_TYPE RxResetType = RESET_TYPE_NORESET;
3952 RT_RF_POWER_STATE rfState;
3954 rfState = priv->ieee80211->eRFPowerState;
3956 TxResetType = TxCheckStuck(dev);
3957 #if 1
3958 if( rfState != eRfOff &&
3959 /*ADAPTER_TEST_STATUS_FLAG(Adapter, ADAPTER_STATUS_FW_DOWNLOAD_FAILURE)) &&*/
3960 (priv->ieee80211->iw_mode != IW_MODE_ADHOC))
3962 // If driver is in the status of firmware download failure , driver skips RF initialization and RF is
3963 // in turned off state. Driver should check whether Rx stuck and do silent reset. And
3964 // if driver is in firmware download failure status, driver should initialize RF in the following
3965 // silent reset procedure Emily, 2008.01.21
3967 // Driver should not check RX stuck in IBSS mode because it is required to
3968 // set Check BSSID in order to send beacon, however, if check BSSID is
3969 // set, STA cannot hear any packet a all. Emily, 2008.04.12
3970 RxResetType = RxCheckStuck(dev);
3972 #endif
3974 RT_TRACE(COMP_RESET,"%s(): TxResetType is %d, RxResetType is %d\n",__FUNCTION__,TxResetType,RxResetType);
3975 if(TxResetType==RESET_TYPE_NORMAL || RxResetType==RESET_TYPE_NORMAL)
3976 return RESET_TYPE_NORMAL;
3977 else if(TxResetType==RESET_TYPE_SILENT || RxResetType==RESET_TYPE_SILENT)
3978 return RESET_TYPE_SILENT;
3979 else
3980 return RESET_TYPE_NORESET;
3985 static void CamRestoreAllEntry(struct net_device *dev)
3987 u8 EntryId = 0;
3988 struct r8192_priv *priv = ieee80211_priv(dev);
3989 u8* MacAddr = priv->ieee80211->current_network.bssid;
3991 static u8 CAM_CONST_ADDR[4][6] = {
3992 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
3993 {0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
3994 {0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
3995 {0x00, 0x00, 0x00, 0x00, 0x00, 0x03}};
3996 static u8 CAM_CONST_BROAD[] =
3997 {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
3999 RT_TRACE(COMP_SEC, "CamRestoreAllEntry: \n");
4002 if ((priv->ieee80211->pairwise_key_type == KEY_TYPE_WEP40)||
4003 (priv->ieee80211->pairwise_key_type == KEY_TYPE_WEP104))
4006 for(EntryId=0; EntryId<4; EntryId++)
4009 MacAddr = CAM_CONST_ADDR[EntryId];
4010 setKey(dev,
4011 EntryId ,
4012 EntryId,
4013 priv->ieee80211->pairwise_key_type,
4014 MacAddr,
4016 NULL);
4021 else if(priv->ieee80211->pairwise_key_type == KEY_TYPE_TKIP)
4025 if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
4026 setKey(dev,
4029 priv->ieee80211->pairwise_key_type,
4030 (u8*)dev->dev_addr,
4032 NULL);
4033 else
4034 setKey(dev,
4037 priv->ieee80211->pairwise_key_type,
4038 MacAddr,
4040 NULL);
4043 else if(priv->ieee80211->pairwise_key_type == KEY_TYPE_CCMP)
4047 if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
4048 setKey(dev,
4051 priv->ieee80211->pairwise_key_type,
4052 (u8*)dev->dev_addr,
4054 NULL);
4055 else
4056 setKey(dev,
4059 priv->ieee80211->pairwise_key_type,
4060 MacAddr,
4062 NULL);
4068 if(priv->ieee80211->group_key_type == KEY_TYPE_TKIP)
4070 MacAddr = CAM_CONST_BROAD;
4071 for(EntryId=1 ; EntryId<4 ; EntryId++)
4074 setKey(dev,
4075 EntryId,
4076 EntryId,
4077 priv->ieee80211->group_key_type,
4078 MacAddr,
4080 NULL);
4083 if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
4084 setKey(dev,
4087 priv->ieee80211->group_key_type,
4088 CAM_CONST_ADDR[0],
4090 NULL);
4092 else if(priv->ieee80211->group_key_type == KEY_TYPE_CCMP)
4094 MacAddr = CAM_CONST_BROAD;
4095 for(EntryId=1; EntryId<4 ; EntryId++)
4098 setKey(dev,
4099 EntryId ,
4100 EntryId,
4101 priv->ieee80211->group_key_type,
4102 MacAddr,
4104 NULL);
4108 if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
4109 setKey(dev,
4112 priv->ieee80211->group_key_type,
4113 CAM_CONST_ADDR[0],
4115 NULL);
4119 void rtl8192_cancel_deferred_work(struct r8192_priv* priv);
4120 int _rtl8192_up(struct net_device *dev);
4123 * This function is used to fix Tx/Rx stop bug temporarily.
4124 * This function will do "system reset" to NIC when Tx or Rx is stuck.
4125 * The method checking Tx/Rx stuck of this function is supported by FW,
4126 * which reports Tx and Rx counter to register 0x128 and 0x130.
4127 * */
4128 static void rtl819x_ifsilentreset(struct net_device *dev)
4130 struct r8192_priv *priv = ieee80211_priv(dev);
4131 u8 reset_times = 0;
4132 int reset_status = 0;
4133 struct ieee80211_device *ieee = priv->ieee80211;
4136 // 2007.07.20. If we need to check CCK stop, please uncomment this line.
4137 //bStuck = Adapter->HalFunc.CheckHWStopHandler(Adapter);
4139 if(priv->ResetProgress==RESET_TYPE_NORESET)
4141 RESET_START:
4143 RT_TRACE(COMP_RESET,"=========>Reset progress!! \n");
4145 // Set the variable for reset.
4146 priv->ResetProgress = RESET_TYPE_SILENT;
4147 // rtl8192_close(dev);
4148 #if 1
4149 down(&priv->wx_sem);
4150 if(priv->up == 0)
4152 RT_TRACE(COMP_ERR,"%s():the driver is not up! return\n",__FUNCTION__);
4153 up(&priv->wx_sem);
4154 return ;
4156 priv->up = 0;
4157 RT_TRACE(COMP_RESET,"%s():======>start to down the driver\n",__FUNCTION__);
4158 if(!netif_queue_stopped(dev))
4159 netif_stop_queue(dev);
4161 dm_backup_dynamic_mechanism_state(dev);
4163 rtl8192_irq_disable(dev);
4164 rtl8192_cancel_deferred_work(priv);
4165 deinit_hal_dm(dev);
4166 del_timer_sync(&priv->watch_dog_timer);
4167 ieee->sync_scan_hurryup = 1;
4168 if(ieee->state == IEEE80211_LINKED)
4170 down(&ieee->wx_sem);
4171 printk("ieee->state is IEEE80211_LINKED\n");
4172 ieee80211_stop_send_beacons(priv->ieee80211);
4173 del_timer_sync(&ieee->associate_timer);
4174 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
4175 cancel_delayed_work(&ieee->associate_retry_wq);
4176 #endif
4177 ieee80211_stop_scan(ieee);
4178 netif_carrier_off(dev);
4179 up(&ieee->wx_sem);
4181 else{
4182 printk("ieee->state is NOT LINKED\n");
4183 ieee80211_softmac_stop_protocol(priv->ieee80211);
4185 rtl8192_rtx_disable(dev);
4186 up(&priv->wx_sem);
4187 RT_TRACE(COMP_RESET,"%s():<==========down process is finished\n",__FUNCTION__);
4188 RT_TRACE(COMP_RESET,"%s():===========>start to up the driver\n",__FUNCTION__);
4189 reset_status = _rtl8192_up(dev);
4191 RT_TRACE(COMP_RESET,"%s():<===========up process is finished\n",__FUNCTION__);
4192 if(reset_status == -1)
4194 if(reset_times < 3)
4196 reset_times++;
4197 goto RESET_START;
4199 else
4201 RT_TRACE(COMP_ERR," ERR!!! %s(): Reset Failed!!\n",__FUNCTION__);
4204 #endif
4205 ieee->is_silent_reset = 1;
4206 #if 1
4207 EnableHWSecurityConfig8192(dev);
4208 #if 1
4209 if(ieee->state == IEEE80211_LINKED && ieee->iw_mode == IW_MODE_INFRA)
4211 ieee->set_chan(ieee->dev, ieee->current_network.channel);
4213 #if 1
4214 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
4215 queue_work(ieee->wq, &ieee->associate_complete_wq);
4216 #else
4217 schedule_task(&ieee->associate_complete_wq);
4218 #endif
4219 #endif
4222 else if(ieee->state == IEEE80211_LINKED && ieee->iw_mode == IW_MODE_ADHOC)
4224 ieee->set_chan(ieee->dev, ieee->current_network.channel);
4225 ieee->link_change(ieee->dev);
4227 // notify_wx_assoc_event(ieee);
4229 ieee80211_start_send_beacons(ieee);
4231 if (ieee->data_hard_resume)
4232 ieee->data_hard_resume(ieee->dev);
4233 netif_carrier_on(ieee->dev);
4235 #endif
4237 CamRestoreAllEntry(dev);
4239 // Restore the previous setting for all dynamic mechanism
4240 dm_restore_dynamic_mechanism_state(dev);
4242 priv->ResetProgress = RESET_TYPE_NORESET;
4243 priv->reset_count++;
4245 priv->bForcedSilentReset =false;
4246 priv->bResetInProgress = false;
4248 // For test --> force write UFWP.
4249 write_nic_byte(dev, UFWP, 1);
4250 RT_TRACE(COMP_RESET, "Reset finished!! ====>[%d]\n", priv->reset_count);
4251 #endif
4255 #ifdef ENABLE_IPS
4256 void InactivePsWorkItemCallback(struct net_device *dev)
4258 struct r8192_priv *priv = ieee80211_priv(dev);
4259 PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->ieee80211->PowerSaveControl));
4260 //u8 index = 0;
4262 RT_TRACE(COMP_POWER, "InactivePsWorkItemCallback() ---------> \n");
4264 // This flag "bSwRfProcessing", indicates the status of IPS procedure, should be set if the IPS workitem
4265 // is really scheduled.
4266 // The old code, sets this flag before scheduling the IPS workitem and however, at the same time the
4267 // previous IPS workitem did not end yet, fails to schedule the current workitem. Thus, bSwRfProcessing
4268 // blocks the IPS procedure of switching RF.
4269 // By Bruce, 2007-12-25.
4271 pPSC->bSwRfProcessing = TRUE;
4273 RT_TRACE(COMP_RF, "InactivePsWorkItemCallback(): Set RF to %s.\n", \
4274 pPSC->eInactivePowerState == eRfOff?"OFF":"ON");
4277 MgntActSet_RF_State(dev, pPSC->eInactivePowerState, RF_CHANGE_BY_IPS);
4280 // To solve CAM values miss in RF OFF, rewrite CAM values after RF ON. By Bruce, 2007-09-20.
4282 pPSC->bSwRfProcessing = FALSE;
4283 RT_TRACE(COMP_POWER, "InactivePsWorkItemCallback() <--------- \n");
4287 // Description:
4288 // Enter the inactive power save mode. RF will be off
4289 // 2007.08.17, by shien chang.
4291 void
4292 IPSEnter(struct net_device *dev)
4294 struct r8192_priv *priv = ieee80211_priv(dev);
4295 PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->ieee80211->PowerSaveControl));
4296 RT_RF_POWER_STATE rtState;
4298 if (pPSC->bInactivePs)
4300 rtState = priv->ieee80211->eRFPowerState;
4302 // Added by Bruce, 2007-12-25.
4303 // Do not enter IPS in the following conditions:
4304 // (1) RF is already OFF or Sleep
4305 // (2) bSwRfProcessing (indicates the IPS is still under going)
4306 // (3) Connectted (only disconnected can trigger IPS)
4307 // (4) IBSS (send Beacon)
4308 // (5) AP mode (send Beacon)
4310 if (rtState == eRfOn && !pPSC->bSwRfProcessing
4311 && (priv->ieee80211->state != IEEE80211_LINKED) )
4313 RT_TRACE(COMP_RF,"IPSEnter(): Turn off RF.\n");
4314 pPSC->eInactivePowerState = eRfOff;
4315 // queue_work(priv->priv_wq,&(pPSC->InactivePsWorkItem));
4316 InactivePsWorkItemCallback(dev);
4322 // Description:
4323 // Leave the inactive power save mode, RF will be on.
4324 // 2007.08.17, by shien chang.
4326 void
4327 IPSLeave(struct net_device *dev)
4329 struct r8192_priv *priv = ieee80211_priv(dev);
4330 PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->ieee80211->PowerSaveControl));
4331 RT_RF_POWER_STATE rtState;
4333 if (pPSC->bInactivePs)
4335 rtState = priv->ieee80211->eRFPowerState;
4336 if (rtState != eRfOn && !pPSC->bSwRfProcessing && priv->ieee80211->RfOffReason <= RF_CHANGE_BY_IPS)
4338 RT_TRACE(COMP_POWER, "IPSLeave(): Turn on RF.\n");
4339 pPSC->eInactivePowerState = eRfOn;
4340 // queue_work(priv->priv_wq,&(pPSC->InactivePsWorkItem));
4341 InactivePsWorkItemCallback(dev);
4345 #endif
4347 static void rtl819x_update_rxcounts(
4348 struct r8192_priv *priv,
4349 u32* TotalRxBcnNum,
4350 u32* TotalRxDataNum
4353 u16 SlotIndex;
4354 u8 i;
4356 *TotalRxBcnNum = 0;
4357 *TotalRxDataNum = 0;
4359 SlotIndex = (priv->ieee80211->LinkDetectInfo.SlotIndex++)%(priv->ieee80211->LinkDetectInfo.SlotNum);
4360 priv->ieee80211->LinkDetectInfo.RxBcnNum[SlotIndex] = priv->ieee80211->LinkDetectInfo.NumRecvBcnInPeriod;
4361 priv->ieee80211->LinkDetectInfo.RxDataNum[SlotIndex] = priv->ieee80211->LinkDetectInfo.NumRecvDataInPeriod;
4362 for( i=0; i<priv->ieee80211->LinkDetectInfo.SlotNum; i++ ){
4363 *TotalRxBcnNum += priv->ieee80211->LinkDetectInfo.RxBcnNum[i];
4364 *TotalRxDataNum += priv->ieee80211->LinkDetectInfo.RxDataNum[i];
4369 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
4370 void rtl819x_watchdog_wqcallback(struct work_struct *work)
4372 struct delayed_work *dwork = container_of(work,struct delayed_work,work);
4373 struct r8192_priv *priv = container_of(dwork,struct r8192_priv,watch_dog_wq);
4374 struct net_device *dev = priv->ieee80211->dev;
4375 #else
4376 extern void rtl819x_watchdog_wqcallback(struct net_device *dev)
4378 struct r8192_priv *priv = ieee80211_priv(dev);
4379 #endif
4380 struct ieee80211_device* ieee = priv->ieee80211;
4381 RESET_TYPE ResetType = RESET_TYPE_NORESET;
4382 static u8 check_reset_cnt=0;
4383 unsigned long flags;
4384 bool bBusyTraffic = false;
4385 static u8 last_time = 0;
4386 if(!priv->up)
4387 return;
4388 hal_dm_watchdog(dev);
4389 #ifdef ENABLE_IPS
4390 // printk("watch_dog ENABLE_IPS\n");
4391 if(ieee->actscanning == false){
4392 if((ieee->iw_mode != IW_MODE_ADHOC) && (ieee->state == IEEE80211_NOLINK) && (ieee->beinretry == false) && (ieee->eRFPowerState == eRfOn) && !ieee->is_set_key){
4393 if(ieee->PowerSaveControl.ReturnPoint == IPS_CALLBACK_NONE){
4394 printk("====================>haha:IPSEnter()\n");
4395 IPSEnter(dev);
4396 //ieee80211_stop_scan(priv->ieee80211);
4400 #endif
4401 {//to get busy traffic condition
4402 if(ieee->state == IEEE80211_LINKED)
4404 if( ieee->LinkDetectInfo.NumRxOkInPeriod> 666 ||
4405 ieee->LinkDetectInfo.NumTxOkInPeriod> 666 ) {
4406 bBusyTraffic = true;
4410 ieee->LinkDetectInfo.NumRxOkInPeriod = 0;
4411 ieee->LinkDetectInfo.NumTxOkInPeriod = 0;
4412 ieee->LinkDetectInfo.bBusyTraffic = bBusyTraffic;
4416 //added by amy for AP roaming
4417 if (1)
4419 if(ieee->state == IEEE80211_LINKED && ieee->iw_mode == IW_MODE_INFRA)
4421 u32 TotalRxBcnNum = 0;
4422 u32 TotalRxDataNum = 0;
4424 rtl819x_update_rxcounts(priv, &TotalRxBcnNum, &TotalRxDataNum);
4425 if((TotalRxBcnNum+TotalRxDataNum) == 0)
4427 if( ieee->eRFPowerState == eRfOff)
4428 RT_TRACE(COMP_ERR,"========>%s()\n",__FUNCTION__);
4429 printk("===>%s(): AP is power off,connect another one\n",__FUNCTION__);
4430 // Dot11d_Reset(dev);
4431 ieee->state = IEEE80211_ASSOCIATING;
4432 notify_wx_assoc_event(priv->ieee80211);
4433 RemovePeerTS(priv->ieee80211,priv->ieee80211->current_network.bssid);
4434 ieee->is_roaming = true;
4435 ieee->is_set_key = false;
4436 ieee->link_change(dev);
4437 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
4438 queue_work(ieee->wq, &ieee->associate_procedure_wq);
4439 #else
4440 schedule_task(&ieee->associate_procedure_wq);
4441 #endif
4444 ieee->LinkDetectInfo.NumRecvBcnInPeriod=0;
4445 ieee->LinkDetectInfo.NumRecvDataInPeriod=0;
4448 //check if reset the driver
4449 spin_lock_irqsave(&priv->tx_lock,flags);
4450 if(check_reset_cnt++ >= 3 && !ieee->is_roaming && (last_time != 1))
4452 ResetType = rtl819x_ifcheck_resetornot(dev);
4453 check_reset_cnt = 3;
4454 //DbgPrint("Start to check silent reset\n");
4456 spin_unlock_irqrestore(&priv->tx_lock,flags);
4457 if(!priv->bDisableNormalResetCheck && ResetType == RESET_TYPE_NORMAL)
4459 priv->ResetProgress = RESET_TYPE_NORMAL;
4460 RT_TRACE(COMP_RESET,"%s(): NOMAL RESET\n",__FUNCTION__);
4461 return;
4463 /* disable silent reset temply 2008.9.11*/
4464 #if 1
4465 if( ((priv->force_reset) || (!priv->bDisableNormalResetCheck && ResetType==RESET_TYPE_SILENT))) // This is control by OID set in Pomelo
4467 last_time = 1;
4468 rtl819x_ifsilentreset(dev);
4470 else
4471 last_time = 0;
4472 #endif
4473 priv->force_reset = false;
4474 priv->bForcedSilentReset = false;
4475 priv->bResetInProgress = false;
4476 RT_TRACE(COMP_TRACE, " <==RtUsbCheckForHangWorkItemCallback()\n");
4480 void watch_dog_timer_callback(unsigned long data)
4482 struct r8192_priv *priv = ieee80211_priv((struct net_device *) data);
4483 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
4484 queue_delayed_work(priv->priv_wq,&priv->watch_dog_wq,0);
4485 #else
4486 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
4487 schedule_task(&priv->watch_dog_wq);
4488 #else
4489 queue_work(priv->priv_wq,&priv->watch_dog_wq);
4490 #endif
4491 #endif
4492 mod_timer(&priv->watch_dog_timer, jiffies + MSECS(IEEE80211_WATCH_DOG_TIME));
4495 int _rtl8192_up(struct net_device *dev)
4497 struct r8192_priv *priv = ieee80211_priv(dev);
4498 //int i;
4499 RT_STATUS init_status = RT_STATUS_SUCCESS;
4500 priv->up=1;
4501 priv->ieee80211->ieee_up=1;
4502 RT_TRACE(COMP_INIT, "Bringing up iface");
4504 init_status = rtl8192_adapter_start(dev);
4505 if(init_status != RT_STATUS_SUCCESS)
4507 RT_TRACE(COMP_ERR,"ERR!!! %s(): initialization is failed!\n",__FUNCTION__);
4508 return -1;
4510 RT_TRACE(COMP_INIT, "start adapter finished\n");
4511 #ifdef RTL8192E
4512 if(priv->ieee80211->eRFPowerState!=eRfOn)
4513 MgntActSet_RF_State(dev, eRfOn, priv->ieee80211->RfOffReason);
4514 #endif
4515 if(priv->ieee80211->state != IEEE80211_LINKED)
4516 ieee80211_softmac_start_protocol(priv->ieee80211);
4517 ieee80211_reset_queue(priv->ieee80211);
4518 watch_dog_timer_callback((unsigned long) dev);
4519 if(!netif_queue_stopped(dev))
4520 netif_start_queue(dev);
4521 else
4522 netif_wake_queue(dev);
4524 return 0;
4528 static int rtl8192_open(struct net_device *dev)
4530 struct r8192_priv *priv = ieee80211_priv(dev);
4531 int ret;
4533 down(&priv->wx_sem);
4534 ret = rtl8192_up(dev);
4535 up(&priv->wx_sem);
4536 return ret;
4541 int rtl8192_up(struct net_device *dev)
4543 struct r8192_priv *priv = ieee80211_priv(dev);
4545 if (priv->up == 1) return -1;
4547 return _rtl8192_up(dev);
4551 static int rtl8192_close(struct net_device *dev)
4553 struct r8192_priv *priv = ieee80211_priv(dev);
4554 int ret;
4556 down(&priv->wx_sem);
4558 ret = rtl8192_down(dev);
4560 up(&priv->wx_sem);
4562 return ret;
4566 int rtl8192_down(struct net_device *dev)
4568 struct r8192_priv *priv = ieee80211_priv(dev);
4569 // int i;
4570 #if 0
4571 u8 ucRegRead;
4572 u32 ulRegRead;
4573 #endif
4574 if (priv->up == 0) return -1;
4576 priv->up=0;
4577 priv->ieee80211->ieee_up = 0;
4578 RT_TRACE(COMP_DOWN, "==========>%s()\n", __FUNCTION__);
4579 /* FIXME */
4580 if (!netif_queue_stopped(dev))
4581 netif_stop_queue(dev);
4583 rtl8192_irq_disable(dev);
4584 #if 0
4585 if(!priv->ieee80211->bSupportRemoteWakeUp) {
4586 MgntActSet_RF_State(dev, eRfOff, RF_CHANGE_BY_INIT);
4587 // 2006.11.30. System reset bit
4588 ulRegRead = read_nic_dword(dev, CPU_GEN);
4589 ulRegRead|=CPU_GEN_SYSTEM_RESET;
4590 write_nic_dword(dev, CPU_GEN, ulRegRead);
4591 } else {
4592 //2008.06.03 for WOL
4593 write_nic_dword(dev, WFCRC0, 0xffffffff);
4594 write_nic_dword(dev, WFCRC1, 0xffffffff);
4595 write_nic_dword(dev, WFCRC2, 0xffffffff);
4596 #ifdef RTL8190P
4597 //GPIO 0 = TRUE
4598 ucRegRead = read_nic_byte(dev, GPO);
4599 ucRegRead |= BIT0;
4600 write_nic_byte(dev, GPO, ucRegRead);
4601 #endif
4602 //Write PMR register
4603 write_nic_byte(dev, PMR, 0x5);
4604 //Disable tx, enanble rx
4605 write_nic_byte(dev, MacBlkCtrl, 0xa);
4607 #endif
4608 // flush_scheduled_work();
4609 rtl8192_cancel_deferred_work(priv);
4610 deinit_hal_dm(dev);
4611 del_timer_sync(&priv->watch_dog_timer);
4613 ieee80211_softmac_stop_protocol(priv->ieee80211);
4614 #ifdef ENABLE_IPS
4615 MgntActSet_RF_State(dev, eRfOff, RF_CHANGE_BY_INIT);
4616 #endif
4617 rtl8192_rtx_disable(dev);
4618 memset(&priv->ieee80211->current_network, 0 , offsetof(struct ieee80211_network, list));
4620 RT_TRACE(COMP_DOWN, "<==========%s()\n", __FUNCTION__);
4622 return 0;
4626 void rtl8192_commit(struct net_device *dev)
4628 struct r8192_priv *priv = ieee80211_priv(dev);
4630 if (priv->up == 0) return ;
4633 ieee80211_softmac_stop_protocol(priv->ieee80211);
4635 rtl8192_irq_disable(dev);
4636 rtl8192_rtx_disable(dev);
4637 _rtl8192_up(dev);
4640 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
4641 void rtl8192_restart(struct work_struct *work)
4643 struct r8192_priv *priv = container_of(work, struct r8192_priv, reset_wq);
4644 struct net_device *dev = priv->ieee80211->dev;
4645 #else
4646 void rtl8192_restart(struct net_device *dev)
4649 struct r8192_priv *priv = ieee80211_priv(dev);
4650 #endif
4652 down(&priv->wx_sem);
4654 rtl8192_commit(dev);
4656 up(&priv->wx_sem);
4659 static void r8192_set_multicast(struct net_device *dev)
4661 struct r8192_priv *priv = ieee80211_priv(dev);
4662 short promisc;
4664 //down(&priv->wx_sem);
4666 /* FIXME FIXME */
4668 promisc = (dev->flags & IFF_PROMISC) ? 1:0;
4670 if (promisc != priv->promisc) {
4672 // rtl8192_commit(dev);
4675 priv->promisc = promisc;
4677 //schedule_work(&priv->reset_wq);
4678 //up(&priv->wx_sem);
4682 static int r8192_set_mac_adr(struct net_device *dev, void *mac)
4684 struct r8192_priv *priv = ieee80211_priv(dev);
4685 struct sockaddr *addr = mac;
4687 down(&priv->wx_sem);
4689 memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
4691 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
4692 schedule_work(&priv->reset_wq);
4693 #else
4694 schedule_task(&priv->reset_wq);
4695 #endif
4696 up(&priv->wx_sem);
4698 return 0;
4701 /* based on ipw2200 driver */
4702 static int rtl8192_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
4704 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
4705 struct iwreq *wrq = (struct iwreq *)rq;
4706 int ret=-1;
4707 struct ieee80211_device *ieee = priv->ieee80211;
4708 u32 key[4];
4709 u8 broadcast_addr[6] = {0xff,0xff,0xff,0xff,0xff,0xff};
4710 struct iw_point *p = &wrq->u.data;
4711 struct ieee_param *ipw = NULL;//(struct ieee_param *)wrq->u.data.pointer;
4713 down(&priv->wx_sem);
4716 if (p->length < sizeof(struct ieee_param) || !p->pointer){
4717 ret = -EINVAL;
4718 goto out;
4721 ipw = (struct ieee_param *)kmalloc(p->length, GFP_KERNEL);
4722 if (ipw == NULL){
4723 ret = -ENOMEM;
4724 goto out;
4726 if (copy_from_user(ipw, p->pointer, p->length)) {
4727 kfree(ipw);
4728 ret = -EFAULT;
4729 goto out;
4732 switch (cmd) {
4733 case RTL_IOCTL_WPA_SUPPLICANT:
4734 //parse here for HW security
4735 if (ipw->cmd == IEEE_CMD_SET_ENCRYPTION)
4737 if (ipw->u.crypt.set_tx)
4739 if (strcmp(ipw->u.crypt.alg, "CCMP") == 0)
4740 ieee->pairwise_key_type = KEY_TYPE_CCMP;
4741 else if (strcmp(ipw->u.crypt.alg, "TKIP") == 0)
4742 ieee->pairwise_key_type = KEY_TYPE_TKIP;
4743 else if (strcmp(ipw->u.crypt.alg, "WEP") == 0)
4745 if (ipw->u.crypt.key_len == 13)
4746 ieee->pairwise_key_type = KEY_TYPE_WEP104;
4747 else if (ipw->u.crypt.key_len == 5)
4748 ieee->pairwise_key_type = KEY_TYPE_WEP40;
4750 else
4751 ieee->pairwise_key_type = KEY_TYPE_NA;
4753 if (ieee->pairwise_key_type)
4755 memcpy((u8*)key, ipw->u.crypt.key, 16);
4756 EnableHWSecurityConfig8192(dev);
4757 //we fill both index entry and 4th entry for pairwise key as in IPW interface, adhoc will only get here, so we need index entry for its default key serching!
4758 //added by WB.
4759 setKey(dev, 4, ipw->u.crypt.idx, ieee->pairwise_key_type, (u8*)ieee->ap_mac_addr, 0, key);
4760 if (ieee->auth_mode != 2) //LEAP WEP will never set this.
4761 setKey(dev, ipw->u.crypt.idx, ipw->u.crypt.idx, ieee->pairwise_key_type, (u8*)ieee->ap_mac_addr, 0, key);
4763 if ((ieee->pairwise_key_type == KEY_TYPE_CCMP) && ieee->pHTInfo->bCurrentHTSupport){
4764 write_nic_byte(dev, 0x173, 1); //fix aes bug
4768 else //if (ipw->u.crypt.idx) //group key use idx > 0
4770 memcpy((u8*)key, ipw->u.crypt.key, 16);
4771 if (strcmp(ipw->u.crypt.alg, "CCMP") == 0)
4772 ieee->group_key_type= KEY_TYPE_CCMP;
4773 else if (strcmp(ipw->u.crypt.alg, "TKIP") == 0)
4774 ieee->group_key_type = KEY_TYPE_TKIP;
4775 else if (strcmp(ipw->u.crypt.alg, "WEP") == 0)
4777 if (ipw->u.crypt.key_len == 13)
4778 ieee->group_key_type = KEY_TYPE_WEP104;
4779 else if (ipw->u.crypt.key_len == 5)
4780 ieee->group_key_type = KEY_TYPE_WEP40;
4782 else
4783 ieee->group_key_type = KEY_TYPE_NA;
4785 if (ieee->group_key_type)
4787 setKey( dev,
4788 ipw->u.crypt.idx,
4789 ipw->u.crypt.idx, //KeyIndex
4790 ieee->group_key_type, //KeyType
4791 broadcast_addr, //MacAddr
4792 0, //DefaultKey
4793 key); //KeyContent
4797 #ifdef JOHN_DEBUG
4798 //john's test 0711
4800 int i;
4801 printk("@@ wrq->u pointer = ");
4802 for(i=0;i<wrq->u.data.length;i++){
4803 if(i%10==0) printk("\n");
4804 printk( "%8x|", ((u32*)wrq->u.data.pointer)[i] );
4806 printk("\n");
4808 #endif /*JOHN_DEBUG*/
4809 ret = ieee80211_wpa_supplicant_ioctl(priv->ieee80211, &wrq->u.data);
4810 break;
4812 default:
4813 ret = -EOPNOTSUPP;
4814 break;
4817 kfree(ipw);
4818 out:
4819 up(&priv->wx_sem);
4821 return ret;
4824 static u8 HwRateToMRate90(bool bIsHT, u8 rate)
4826 u8 ret_rate = 0x02;
4828 if(!bIsHT) {
4829 switch(rate) {
4830 case DESC90_RATE1M: ret_rate = MGN_1M; break;
4831 case DESC90_RATE2M: ret_rate = MGN_2M; break;
4832 case DESC90_RATE5_5M: ret_rate = MGN_5_5M; break;
4833 case DESC90_RATE11M: ret_rate = MGN_11M; break;
4834 case DESC90_RATE6M: ret_rate = MGN_6M; break;
4835 case DESC90_RATE9M: ret_rate = MGN_9M; break;
4836 case DESC90_RATE12M: ret_rate = MGN_12M; break;
4837 case DESC90_RATE18M: ret_rate = MGN_18M; break;
4838 case DESC90_RATE24M: ret_rate = MGN_24M; break;
4839 case DESC90_RATE36M: ret_rate = MGN_36M; break;
4840 case DESC90_RATE48M: ret_rate = MGN_48M; break;
4841 case DESC90_RATE54M: ret_rate = MGN_54M; break;
4843 default:
4844 RT_TRACE(COMP_RECV, "HwRateToMRate90(): Non supported Rate [%x], bIsHT = %d!!!\n", rate, bIsHT);
4845 break;
4848 } else {
4849 switch(rate) {
4850 case DESC90_RATEMCS0: ret_rate = MGN_MCS0; break;
4851 case DESC90_RATEMCS1: ret_rate = MGN_MCS1; break;
4852 case DESC90_RATEMCS2: ret_rate = MGN_MCS2; break;
4853 case DESC90_RATEMCS3: ret_rate = MGN_MCS3; break;
4854 case DESC90_RATEMCS4: ret_rate = MGN_MCS4; break;
4855 case DESC90_RATEMCS5: ret_rate = MGN_MCS5; break;
4856 case DESC90_RATEMCS6: ret_rate = MGN_MCS6; break;
4857 case DESC90_RATEMCS7: ret_rate = MGN_MCS7; break;
4858 case DESC90_RATEMCS8: ret_rate = MGN_MCS8; break;
4859 case DESC90_RATEMCS9: ret_rate = MGN_MCS9; break;
4860 case DESC90_RATEMCS10: ret_rate = MGN_MCS10; break;
4861 case DESC90_RATEMCS11: ret_rate = MGN_MCS11; break;
4862 case DESC90_RATEMCS12: ret_rate = MGN_MCS12; break;
4863 case DESC90_RATEMCS13: ret_rate = MGN_MCS13; break;
4864 case DESC90_RATEMCS14: ret_rate = MGN_MCS14; break;
4865 case DESC90_RATEMCS15: ret_rate = MGN_MCS15; break;
4866 case DESC90_RATEMCS32: ret_rate = (0x80|0x20); break;
4868 default:
4869 RT_TRACE(COMP_RECV, "HwRateToMRate90(): Non supported Rate [%x], bIsHT = %d!!!\n",rate, bIsHT);
4870 break;
4874 return ret_rate;
4878 * Function: UpdateRxPktTimeStamp
4879 * Overview: Recored down the TSF time stamp when receiving a packet
4881 * Input:
4882 * PADAPTER Adapter
4883 * PRT_RFD pRfd,
4885 * Output:
4886 * PRT_RFD pRfd
4887 * (pRfd->Status.TimeStampHigh is updated)
4888 * (pRfd->Status.TimeStampLow is updated)
4889 * Return:
4890 * None
4892 static void UpdateRxPktTimeStamp8190 (struct net_device *dev, struct ieee80211_rx_stats *stats)
4894 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
4896 if(stats->bIsAMPDU && !stats->bFirstMPDU) {
4897 stats->mac_time[0] = priv->LastRxDescTSFLow;
4898 stats->mac_time[1] = priv->LastRxDescTSFHigh;
4899 } else {
4900 priv->LastRxDescTSFLow = stats->mac_time[0];
4901 priv->LastRxDescTSFHigh = stats->mac_time[1];
4905 static long rtl819x_translate_todbm(u8 signal_strength_index)// 0-100 index.
4907 long signal_power; // in dBm.
4909 // Translate to dBm (x=0.5y-95).
4910 signal_power = (long)((signal_strength_index + 1) >> 1);
4911 signal_power -= 95;
4913 return signal_power;
4917 // Description:
4918 // Update Rx signal related information in the packet reeived
4919 // to RxStats. User application can query RxStats to realize
4920 // current Rx signal status.
4922 // Assumption:
4923 // In normal operation, user only care about the information of the BSS
4924 // and we shall invoke this function if the packet received is from the BSS.
4926 static void
4927 rtl819x_update_rxsignalstatistics8190pci(
4928 struct r8192_priv * priv,
4929 struct ieee80211_rx_stats * pprevious_stats
4932 int weighting = 0;
4934 //2 <ToDo> Update Rx Statistics (such as signal strength and signal quality).
4936 // Initila state
4937 if(priv->stats.recv_signal_power == 0)
4938 priv->stats.recv_signal_power = pprevious_stats->RecvSignalPower;
4940 // To avoid the past result restricting the statistics sensitivity, weight the current power (5/6) to speed up the
4941 // reaction of smoothed Signal Power.
4942 if(pprevious_stats->RecvSignalPower > priv->stats.recv_signal_power)
4943 weighting = 5;
4944 else if(pprevious_stats->RecvSignalPower < priv->stats.recv_signal_power)
4945 weighting = (-5);
4947 // We need more correct power of received packets and the "SignalStrength" of RxStats have been beautified or translated,
4948 // so we record the correct power in Dbm here. By Bruce, 2008-03-07.
4950 priv->stats.recv_signal_power = (priv->stats.recv_signal_power * 5 + pprevious_stats->RecvSignalPower + weighting) / 6;
4953 static void
4954 rtl8190_process_cck_rxpathsel(
4955 struct r8192_priv * priv,
4956 struct ieee80211_rx_stats * pprevious_stats
4959 #ifdef RTL8190P //Only 90P 2T4R need to check
4960 char last_cck_adc_pwdb[4]={0,0,0,0};
4961 u8 i;
4962 //cosa add for Rx path selection
4963 if(priv->rf_type == RF_2T4R && DM_RxPathSelTable.Enable)
4965 if(pprevious_stats->bIsCCK &&
4966 (pprevious_stats->bPacketToSelf ||pprevious_stats->bPacketBeacon))
4968 /* record the cck adc_pwdb to the sliding window. */
4969 if(priv->stats.cck_adc_pwdb.TotalNum++ >= PHY_RSSI_SLID_WIN_MAX)
4971 priv->stats.cck_adc_pwdb.TotalNum = PHY_RSSI_SLID_WIN_MAX;
4972 for(i=RF90_PATH_A; i<RF90_PATH_MAX; i++)
4974 last_cck_adc_pwdb[i] = priv->stats.cck_adc_pwdb.elements[i][priv->stats.cck_adc_pwdb.index];
4975 priv->stats.cck_adc_pwdb.TotalVal[i] -= last_cck_adc_pwdb[i];
4978 for(i=RF90_PATH_A; i<RF90_PATH_MAX; i++)
4980 priv->stats.cck_adc_pwdb.TotalVal[i] += pprevious_stats->cck_adc_pwdb[i];
4981 priv->stats.cck_adc_pwdb.elements[i][priv->stats.cck_adc_pwdb.index] = pprevious_stats->cck_adc_pwdb[i];
4983 priv->stats.cck_adc_pwdb.index++;
4984 if(priv->stats.cck_adc_pwdb.index >= PHY_RSSI_SLID_WIN_MAX)
4985 priv->stats.cck_adc_pwdb.index = 0;
4987 for(i=RF90_PATH_A; i<RF90_PATH_MAX; i++)
4989 DM_RxPathSelTable.cck_pwdb_sta[i] = priv->stats.cck_adc_pwdb.TotalVal[i]/priv->stats.cck_adc_pwdb.TotalNum;
4992 for(i=RF90_PATH_A; i<RF90_PATH_MAX; i++)
4994 if(pprevious_stats->cck_adc_pwdb[i] > (char)priv->undecorated_smoothed_cck_adc_pwdb[i])
4996 priv->undecorated_smoothed_cck_adc_pwdb[i] =
4997 ( (priv->undecorated_smoothed_cck_adc_pwdb[i]*(Rx_Smooth_Factor-1)) +
4998 (pprevious_stats->cck_adc_pwdb[i])) /(Rx_Smooth_Factor);
4999 priv->undecorated_smoothed_cck_adc_pwdb[i] = priv->undecorated_smoothed_cck_adc_pwdb[i] + 1;
5001 else
5003 priv->undecorated_smoothed_cck_adc_pwdb[i] =
5004 ( (priv->undecorated_smoothed_cck_adc_pwdb[i]*(Rx_Smooth_Factor-1)) +
5005 (pprevious_stats->cck_adc_pwdb[i])) /(Rx_Smooth_Factor);
5010 #endif
5014 /* 2008/01/22 MH We can not delcare RSSI/EVM total value of sliding window to
5015 be a local static. Otherwise, it may increase when we return from S3/S4. The
5016 value will be kept in memory or disk. We must delcare the value in adapter
5017 and it will be reinitialized when return from S3/S4. */
5018 static void rtl8192_process_phyinfo(struct r8192_priv * priv, u8* buffer,struct ieee80211_rx_stats * pprevious_stats, struct ieee80211_rx_stats * pcurrent_stats)
5020 bool bcheck = false;
5021 u8 rfpath;
5022 u32 nspatial_stream, tmp_val;
5023 //u8 i;
5024 static u32 slide_rssi_index=0, slide_rssi_statistics=0;
5025 static u32 slide_evm_index=0, slide_evm_statistics=0;
5026 static u32 last_rssi=0, last_evm=0;
5027 //cosa add for rx path selection
5028 // static long slide_cck_adc_pwdb_index=0, slide_cck_adc_pwdb_statistics=0;
5029 // static char last_cck_adc_pwdb[4]={0,0,0,0};
5030 //cosa add for beacon rssi smoothing
5031 static u32 slide_beacon_adc_pwdb_index=0, slide_beacon_adc_pwdb_statistics=0;
5032 static u32 last_beacon_adc_pwdb=0;
5034 struct ieee80211_hdr_3addr *hdr;
5035 u16 sc ;
5036 unsigned int frag,seq;
5037 hdr = (struct ieee80211_hdr_3addr *)buffer;
5038 sc = le16_to_cpu(hdr->seq_ctl);
5039 frag = WLAN_GET_SEQ_FRAG(sc);
5040 seq = WLAN_GET_SEQ_SEQ(sc);
5041 //cosa add 04292008 to record the sequence number
5042 pcurrent_stats->Seq_Num = seq;
5044 // Check whether we should take the previous packet into accounting
5046 if(!pprevious_stats->bIsAMPDU)
5048 // if previous packet is not aggregated packet
5049 bcheck = true;
5050 }else
5052 //remve for that we don't use AMPDU to calculate PWDB,because the reported PWDB of some AP is fault.
5053 #if 0
5054 // if previous packet is aggregated packet, and current packet
5055 // (1) is not AMPDU
5056 // (2) is the first packet of one AMPDU
5057 // that means the previous packet is the last one aggregated packet
5058 if( !pcurrent_stats->bIsAMPDU || pcurrent_stats->bFirstMPDU)
5059 bcheck = true;
5060 #endif
5063 if(slide_rssi_statistics++ >= PHY_RSSI_SLID_WIN_MAX)
5065 slide_rssi_statistics = PHY_RSSI_SLID_WIN_MAX;
5066 last_rssi = priv->stats.slide_signal_strength[slide_rssi_index];
5067 priv->stats.slide_rssi_total -= last_rssi;
5069 priv->stats.slide_rssi_total += pprevious_stats->SignalStrength;
5071 priv->stats.slide_signal_strength[slide_rssi_index++] = pprevious_stats->SignalStrength;
5072 if(slide_rssi_index >= PHY_RSSI_SLID_WIN_MAX)
5073 slide_rssi_index = 0;
5075 // <1> Showed on UI for user, in dbm
5076 tmp_val = priv->stats.slide_rssi_total/slide_rssi_statistics;
5077 priv->stats.signal_strength = rtl819x_translate_todbm((u8)tmp_val);
5078 pcurrent_stats->rssi = priv->stats.signal_strength;
5080 // If the previous packet does not match the criteria, neglect it
5082 if(!pprevious_stats->bPacketMatchBSSID)
5084 if(!pprevious_stats->bToSelfBA)
5085 return;
5088 if(!bcheck)
5089 return;
5091 rtl8190_process_cck_rxpathsel(priv,pprevious_stats);
5094 // Check RSSI
5096 priv->stats.num_process_phyinfo++;
5097 #if 0
5098 /* record the general signal strength to the sliding window. */
5099 if(slide_rssi_statistics++ >= PHY_RSSI_SLID_WIN_MAX)
5101 slide_rssi_statistics = PHY_RSSI_SLID_WIN_MAX;
5102 last_rssi = priv->stats.slide_signal_strength[slide_rssi_index];
5103 priv->stats.slide_rssi_total -= last_rssi;
5105 priv->stats.slide_rssi_total += pprevious_stats->SignalStrength;
5107 priv->stats.slide_signal_strength[slide_rssi_index++] = pprevious_stats->SignalStrength;
5108 if(slide_rssi_index >= PHY_RSSI_SLID_WIN_MAX)
5109 slide_rssi_index = 0;
5111 // <1> Showed on UI for user, in dbm
5112 tmp_val = priv->stats.slide_rssi_total/slide_rssi_statistics;
5113 priv->stats.signal_strength = rtl819x_translate_todbm((u8)tmp_val);
5115 #endif
5116 // <2> Showed on UI for engineering
5117 // hardware does not provide rssi information for each rf path in CCK
5118 if(!pprevious_stats->bIsCCK && pprevious_stats->bPacketToSelf)
5120 for (rfpath = RF90_PATH_A; rfpath < RF90_PATH_C; rfpath++)
5122 if (!rtl8192_phy_CheckIsLegalRFPath(priv->ieee80211->dev, rfpath))
5123 continue;
5124 RT_TRACE(COMP_DBG,"Jacken -> pPreviousstats->RxMIMOSignalStrength[rfpath] = %d \n" ,pprevious_stats->RxMIMOSignalStrength[rfpath] );
5125 //Fixed by Jacken 2008-03-20
5126 if(priv->stats.rx_rssi_percentage[rfpath] == 0)
5128 priv->stats.rx_rssi_percentage[rfpath] = pprevious_stats->RxMIMOSignalStrength[rfpath];
5129 //DbgPrint("MIMO RSSI initialize \n");
5131 if(pprevious_stats->RxMIMOSignalStrength[rfpath] > priv->stats.rx_rssi_percentage[rfpath])
5133 priv->stats.rx_rssi_percentage[rfpath] =
5134 ( (priv->stats.rx_rssi_percentage[rfpath]*(Rx_Smooth_Factor-1)) +
5135 (pprevious_stats->RxMIMOSignalStrength[rfpath])) /(Rx_Smooth_Factor);
5136 priv->stats.rx_rssi_percentage[rfpath] = priv->stats.rx_rssi_percentage[rfpath] + 1;
5138 else
5140 priv->stats.rx_rssi_percentage[rfpath] =
5141 ( (priv->stats.rx_rssi_percentage[rfpath]*(Rx_Smooth_Factor-1)) +
5142 (pprevious_stats->RxMIMOSignalStrength[rfpath])) /(Rx_Smooth_Factor);
5144 RT_TRACE(COMP_DBG,"Jacken -> priv->RxStats.RxRSSIPercentage[rfPath] = %d \n" ,priv->stats.rx_rssi_percentage[rfpath] );
5150 // Check PWDB.
5152 //cosa add for beacon rssi smoothing by average.
5153 if(pprevious_stats->bPacketBeacon)
5155 /* record the beacon pwdb to the sliding window. */
5156 if(slide_beacon_adc_pwdb_statistics++ >= PHY_Beacon_RSSI_SLID_WIN_MAX)
5158 slide_beacon_adc_pwdb_statistics = PHY_Beacon_RSSI_SLID_WIN_MAX;
5159 last_beacon_adc_pwdb = priv->stats.Slide_Beacon_pwdb[slide_beacon_adc_pwdb_index];
5160 priv->stats.Slide_Beacon_Total -= last_beacon_adc_pwdb;
5161 //DbgPrint("slide_beacon_adc_pwdb_index = %d, last_beacon_adc_pwdb = %d, Adapter->RxStats.Slide_Beacon_Total = %d\n",
5162 // slide_beacon_adc_pwdb_index, last_beacon_adc_pwdb, Adapter->RxStats.Slide_Beacon_Total);
5164 priv->stats.Slide_Beacon_Total += pprevious_stats->RxPWDBAll;
5165 priv->stats.Slide_Beacon_pwdb[slide_beacon_adc_pwdb_index] = pprevious_stats->RxPWDBAll;
5166 //DbgPrint("slide_beacon_adc_pwdb_index = %d, pPreviousRfd->Status.RxPWDBAll = %d\n", slide_beacon_adc_pwdb_index, pPreviousRfd->Status.RxPWDBAll);
5167 slide_beacon_adc_pwdb_index++;
5168 if(slide_beacon_adc_pwdb_index >= PHY_Beacon_RSSI_SLID_WIN_MAX)
5169 slide_beacon_adc_pwdb_index = 0;
5170 pprevious_stats->RxPWDBAll = priv->stats.Slide_Beacon_Total/slide_beacon_adc_pwdb_statistics;
5171 if(pprevious_stats->RxPWDBAll >= 3)
5172 pprevious_stats->RxPWDBAll -= 3;
5175 RT_TRACE(COMP_RXDESC, "Smooth %s PWDB = %d\n",
5176 pprevious_stats->bIsCCK? "CCK": "OFDM",
5177 pprevious_stats->RxPWDBAll);
5179 if(pprevious_stats->bPacketToSelf || pprevious_stats->bPacketBeacon || pprevious_stats->bToSelfBA)
5181 if(priv->undecorated_smoothed_pwdb < 0) // initialize
5183 priv->undecorated_smoothed_pwdb = pprevious_stats->RxPWDBAll;
5184 //DbgPrint("First pwdb initialize \n");
5186 #if 1
5187 if(pprevious_stats->RxPWDBAll > (u32)priv->undecorated_smoothed_pwdb)
5189 priv->undecorated_smoothed_pwdb =
5190 ( ((priv->undecorated_smoothed_pwdb)*(Rx_Smooth_Factor-1)) +
5191 (pprevious_stats->RxPWDBAll)) /(Rx_Smooth_Factor);
5192 priv->undecorated_smoothed_pwdb = priv->undecorated_smoothed_pwdb + 1;
5194 else
5196 priv->undecorated_smoothed_pwdb =
5197 ( ((priv->undecorated_smoothed_pwdb)*(Rx_Smooth_Factor-1)) +
5198 (pprevious_stats->RxPWDBAll)) /(Rx_Smooth_Factor);
5200 #else
5201 //Fixed by Jacken 2008-03-20
5202 if(pPreviousRfd->Status.RxPWDBAll > (u32)pHalData->UndecoratedSmoothedPWDB)
5204 pHalData->UndecoratedSmoothedPWDB =
5205 ( ((pHalData->UndecoratedSmoothedPWDB)* 5) + (pPreviousRfd->Status.RxPWDBAll)) / 6;
5206 pHalData->UndecoratedSmoothedPWDB = pHalData->UndecoratedSmoothedPWDB + 1;
5208 else
5210 pHalData->UndecoratedSmoothedPWDB =
5211 ( ((pHalData->UndecoratedSmoothedPWDB)* 5) + (pPreviousRfd->Status.RxPWDBAll)) / 6;
5213 #endif
5214 rtl819x_update_rxsignalstatistics8190pci(priv,pprevious_stats);
5218 // Check EVM
5220 /* record the general EVM to the sliding window. */
5221 if(pprevious_stats->SignalQuality == 0)
5224 else
5226 if(pprevious_stats->bPacketToSelf || pprevious_stats->bPacketBeacon || pprevious_stats->bToSelfBA){
5227 if(slide_evm_statistics++ >= PHY_RSSI_SLID_WIN_MAX){
5228 slide_evm_statistics = PHY_RSSI_SLID_WIN_MAX;
5229 last_evm = priv->stats.slide_evm[slide_evm_index];
5230 priv->stats.slide_evm_total -= last_evm;
5233 priv->stats.slide_evm_total += pprevious_stats->SignalQuality;
5235 priv->stats.slide_evm[slide_evm_index++] = pprevious_stats->SignalQuality;
5236 if(slide_evm_index >= PHY_RSSI_SLID_WIN_MAX)
5237 slide_evm_index = 0;
5239 // <1> Showed on UI for user, in percentage.
5240 tmp_val = priv->stats.slide_evm_total/slide_evm_statistics;
5241 priv->stats.signal_quality = tmp_val;
5242 //cosa add 10/11/2007, Showed on UI for user in Windows Vista, for Link quality.
5243 priv->stats.last_signal_strength_inpercent = tmp_val;
5246 // <2> Showed on UI for engineering
5247 if(pprevious_stats->bPacketToSelf || pprevious_stats->bPacketBeacon || pprevious_stats->bToSelfBA)
5249 for(nspatial_stream = 0; nspatial_stream<2 ; nspatial_stream++) // 2 spatial stream
5251 if(pprevious_stats->RxMIMOSignalQuality[nspatial_stream] != -1)
5253 if(priv->stats.rx_evm_percentage[nspatial_stream] == 0) // initialize
5255 priv->stats.rx_evm_percentage[nspatial_stream] = pprevious_stats->RxMIMOSignalQuality[nspatial_stream];
5257 priv->stats.rx_evm_percentage[nspatial_stream] =
5258 ( (priv->stats.rx_evm_percentage[nspatial_stream]* (Rx_Smooth_Factor-1)) +
5259 (pprevious_stats->RxMIMOSignalQuality[nspatial_stream]* 1)) / (Rx_Smooth_Factor);
5267 /*-----------------------------------------------------------------------------
5268 * Function: rtl819x_query_rxpwrpercentage()
5270 * Overview:
5272 * Input: char antpower
5274 * Output: NONE
5276 * Return: 0-100 percentage
5278 * Revised History:
5279 * When Who Remark
5280 * 05/26/2008 amy Create Version 0 porting from windows code.
5282 *---------------------------------------------------------------------------*/
5283 static u8 rtl819x_query_rxpwrpercentage(
5284 char antpower
5287 if ((antpower <= -100) || (antpower >= 20))
5289 return 0;
5291 else if (antpower >= 0)
5293 return 100;
5295 else
5297 return (100+antpower);
5300 } /* QueryRxPwrPercentage */
5302 static u8
5303 rtl819x_evm_dbtopercentage(
5304 char value
5307 char ret_val;
5309 ret_val = value;
5311 if(ret_val >= 0)
5312 ret_val = 0;
5313 if(ret_val <= -33)
5314 ret_val = -33;
5315 ret_val = 0 - ret_val;
5316 ret_val*=3;
5317 if(ret_val == 99)
5318 ret_val = 100;
5319 return(ret_val);
5323 // Description:
5324 // We want good-looking for signal strength/quality
5325 // 2007/7/19 01:09, by cosa.
5327 static long rtl819x_signal_scale_mapping(long currsig)
5329 long retsig;
5331 // Step 1. Scale mapping.
5332 if(currsig >= 61 && currsig <= 100)
5334 retsig = 90 + ((currsig - 60) / 4);
5336 else if(currsig >= 41 && currsig <= 60)
5338 retsig = 78 + ((currsig - 40) / 2);
5340 else if(currsig >= 31 && currsig <= 40)
5342 retsig = 66 + (currsig - 30);
5344 else if(currsig >= 21 && currsig <= 30)
5346 retsig = 54 + (currsig - 20);
5348 else if(currsig >= 5 && currsig <= 20)
5350 retsig = 42 + (((currsig - 5) * 2) / 3);
5352 else if(currsig == 4)
5354 retsig = 36;
5356 else if(currsig == 3)
5358 retsig = 27;
5360 else if(currsig == 2)
5362 retsig = 18;
5364 else if(currsig == 1)
5366 retsig = 9;
5368 else
5370 retsig = currsig;
5373 return retsig;
5376 static void rtl8192_query_rxphystatus(
5377 struct r8192_priv * priv,
5378 struct ieee80211_rx_stats * pstats,
5379 prx_desc_819x_pci pdesc,
5380 prx_fwinfo_819x_pci pdrvinfo,
5381 struct ieee80211_rx_stats * precord_stats,
5382 bool bpacket_match_bssid,
5383 bool bpacket_toself,
5384 bool bPacketBeacon,
5385 bool bToSelfBA
5388 //PRT_RFD_STATUS pRtRfdStatus = &(pRfd->Status);
5389 phy_sts_ofdm_819xpci_t* pofdm_buf;
5390 phy_sts_cck_819xpci_t * pcck_buf;
5391 phy_ofdm_rx_status_rxsc_sgien_exintfflag* prxsc;
5392 u8 *prxpkt;
5393 u8 i,max_spatial_stream, tmp_rxsnr, tmp_rxevm, rxsc_sgien_exflg;
5394 char rx_pwr[4], rx_pwr_all=0;
5395 //long rx_avg_pwr = 0;
5396 char rx_snrX, rx_evmX;
5397 u8 evm, pwdb_all;
5398 u32 RSSI, total_rssi=0;//, total_evm=0;
5399 // long signal_strength_index = 0;
5400 u8 is_cck_rate=0;
5401 u8 rf_rx_num = 0;
5403 /* 2007/07/04 MH For OFDM RSSI. For high power or not. */
5404 static u8 check_reg824 = 0;
5405 static u32 reg824_bit9 = 0;
5407 priv->stats.numqry_phystatus++;
5409 is_cck_rate = rx_hal_is_cck_rate(pdrvinfo);
5411 // Record it for next packet processing
5412 memset(precord_stats, 0, sizeof(struct ieee80211_rx_stats));
5413 pstats->bPacketMatchBSSID = precord_stats->bPacketMatchBSSID = bpacket_match_bssid;
5414 pstats->bPacketToSelf = precord_stats->bPacketToSelf = bpacket_toself;
5415 pstats->bIsCCK = precord_stats->bIsCCK = is_cck_rate;//RX_HAL_IS_CCK_RATE(pDrvInfo);
5416 pstats->bPacketBeacon = precord_stats->bPacketBeacon = bPacketBeacon;
5417 pstats->bToSelfBA = precord_stats->bToSelfBA = bToSelfBA;
5418 /*2007.08.30 requested by SD3 Jerry */
5419 if(check_reg824 == 0)
5421 reg824_bit9 = rtl8192_QueryBBReg(priv->ieee80211->dev, rFPGA0_XA_HSSIParameter2, 0x200);
5422 check_reg824 = 1;
5426 prxpkt = (u8*)pdrvinfo;
5428 /* Move pointer to the 16th bytes. Phy status start address. */
5429 prxpkt += sizeof(rx_fwinfo_819x_pci);
5431 /* Initial the cck and ofdm buffer pointer */
5432 pcck_buf = (phy_sts_cck_819xpci_t *)prxpkt;
5433 pofdm_buf = (phy_sts_ofdm_819xpci_t *)prxpkt;
5435 pstats->RxMIMOSignalQuality[0] = -1;
5436 pstats->RxMIMOSignalQuality[1] = -1;
5437 precord_stats->RxMIMOSignalQuality[0] = -1;
5438 precord_stats->RxMIMOSignalQuality[1] = -1;
5440 if(is_cck_rate)
5443 // (1)Hardware does not provide RSSI for CCK
5447 // (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive)
5449 u8 report;//, cck_agc_rpt;
5450 #ifdef RTL8190P
5451 u8 tmp_pwdb;
5452 char cck_adc_pwdb[4];
5453 #endif
5454 priv->stats.numqry_phystatusCCK++;
5456 #ifdef RTL8190P //Only 90P 2T4R need to check
5457 if(priv->rf_type == RF_2T4R && DM_RxPathSelTable.Enable && bpacket_match_bssid)
5459 for(i=RF90_PATH_A; i<RF90_PATH_MAX; i++)
5461 tmp_pwdb = pcck_buf->adc_pwdb_X[i];
5462 cck_adc_pwdb[i] = (char)tmp_pwdb;
5463 cck_adc_pwdb[i] /= 2;
5464 pstats->cck_adc_pwdb[i] = precord_stats->cck_adc_pwdb[i] = cck_adc_pwdb[i];
5465 //DbgPrint("RF-%d tmp_pwdb = 0x%x, cck_adc_pwdb = %d", i, tmp_pwdb, cck_adc_pwdb[i]);
5468 #endif
5470 if(!reg824_bit9)
5472 report = pcck_buf->cck_agc_rpt & 0xc0;
5473 report = report>>6;
5474 switch(report)
5476 //Fixed by Jacken from Bryant 2008-03-20
5477 //Original value is -38 , -26 , -14 , -2
5478 //Fixed value is -35 , -23 , -11 , 6
5479 case 0x3:
5480 rx_pwr_all = -35 - (pcck_buf->cck_agc_rpt & 0x3e);
5481 break;
5482 case 0x2:
5483 rx_pwr_all = -23 - (pcck_buf->cck_agc_rpt & 0x3e);
5484 break;
5485 case 0x1:
5486 rx_pwr_all = -11 - (pcck_buf->cck_agc_rpt & 0x3e);
5487 break;
5488 case 0x0:
5489 rx_pwr_all = 8 - (pcck_buf->cck_agc_rpt & 0x3e);
5490 break;
5493 else
5495 report = pcck_buf->cck_agc_rpt & 0x60;
5496 report = report>>5;
5497 switch(report)
5499 case 0x3:
5500 rx_pwr_all = -35 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1) ;
5501 break;
5502 case 0x2:
5503 rx_pwr_all = -23 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1);
5504 break;
5505 case 0x1:
5506 rx_pwr_all = -11 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1) ;
5507 break;
5508 case 0x0:
5509 rx_pwr_all = -8 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1) ;
5510 break;
5514 pwdb_all = rtl819x_query_rxpwrpercentage(rx_pwr_all);
5515 pstats->RxPWDBAll = precord_stats->RxPWDBAll = pwdb_all;
5516 pstats->RecvSignalPower = rx_pwr_all;
5519 // (3) Get Signal Quality (EVM)
5521 if(bpacket_match_bssid)
5523 u8 sq;
5525 if(pstats->RxPWDBAll > 40)
5527 sq = 100;
5528 }else
5530 sq = pcck_buf->sq_rpt;
5532 if(pcck_buf->sq_rpt > 64)
5533 sq = 0;
5534 else if (pcck_buf->sq_rpt < 20)
5535 sq = 100;
5536 else
5537 sq = ((64-sq) * 100) / 44;
5539 pstats->SignalQuality = precord_stats->SignalQuality = sq;
5540 pstats->RxMIMOSignalQuality[0] = precord_stats->RxMIMOSignalQuality[0] = sq;
5541 pstats->RxMIMOSignalQuality[1] = precord_stats->RxMIMOSignalQuality[1] = -1;
5544 else
5546 priv->stats.numqry_phystatusHT++;
5548 // (1)Get RSSI for HT rate
5550 for(i=RF90_PATH_A; i<RF90_PATH_MAX; i++)
5552 // 2008/01/30 MH we will judge RF RX path now.
5553 if (priv->brfpath_rxenable[i])
5554 rf_rx_num++;
5555 //else
5556 //continue;
5558 //Fixed by Jacken from Bryant 2008-03-20
5559 //Original value is 106
5560 #ifdef RTL8190P //Modify by Jacken 2008/03/31
5561 rx_pwr[i] = ((pofdm_buf->trsw_gain_X[i]&0x3F)*2) - 106;
5562 #else
5563 rx_pwr[i] = ((pofdm_buf->trsw_gain_X[i]&0x3F)*2) - 110;
5564 #endif
5566 //Get Rx snr value in DB
5567 tmp_rxsnr = pofdm_buf->rxsnr_X[i];
5568 rx_snrX = (char)(tmp_rxsnr);
5569 rx_snrX /= 2;
5570 priv->stats.rxSNRdB[i] = (long)rx_snrX;
5572 /* Translate DBM to percentage. */
5573 RSSI = rtl819x_query_rxpwrpercentage(rx_pwr[i]);
5574 if (priv->brfpath_rxenable[i])
5575 total_rssi += RSSI;
5577 /* Record Signal Strength for next packet */
5578 if(bpacket_match_bssid)
5580 pstats->RxMIMOSignalStrength[i] =(u8) RSSI;
5581 precord_stats->RxMIMOSignalStrength[i] =(u8) RSSI;
5587 // (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive)
5589 //Fixed by Jacken from Bryant 2008-03-20
5590 //Original value is 106
5591 rx_pwr_all = (((pofdm_buf->pwdb_all ) >> 1 )& 0x7f) -106;
5592 pwdb_all = rtl819x_query_rxpwrpercentage(rx_pwr_all);
5594 pstats->RxPWDBAll = precord_stats->RxPWDBAll = pwdb_all;
5595 pstats->RxPower = precord_stats->RxPower = rx_pwr_all;
5596 pstats->RecvSignalPower = rx_pwr_all;
5598 // (3)EVM of HT rate
5600 if(pdrvinfo->RxHT && pdrvinfo->RxRate>=DESC90_RATEMCS8 &&
5601 pdrvinfo->RxRate<=DESC90_RATEMCS15)
5602 max_spatial_stream = 2; //both spatial stream make sense
5603 else
5604 max_spatial_stream = 1; //only spatial stream 1 makes sense
5606 for(i=0; i<max_spatial_stream; i++)
5608 tmp_rxevm = pofdm_buf->rxevm_X[i];
5609 rx_evmX = (char)(tmp_rxevm);
5611 // Do not use shift operation like "rx_evmX >>= 1" because the compilor of free build environment
5612 // fill most significant bit to "zero" when doing shifting operation which may change a negative
5613 // value to positive one, then the dbm value (which is supposed to be negative) is not correct anymore.
5614 rx_evmX /= 2; //dbm
5616 evm = rtl819x_evm_dbtopercentage(rx_evmX);
5617 #if 0
5618 EVM = SignalScaleMapping(EVM);//make it good looking, from 0~100
5619 #endif
5620 if(bpacket_match_bssid)
5622 if(i==0) // Fill value in RFD, Get the first spatial stream only
5623 pstats->SignalQuality = precord_stats->SignalQuality = (u8)(evm & 0xff);
5624 pstats->RxMIMOSignalQuality[i] = precord_stats->RxMIMOSignalQuality[i] = (u8)(evm & 0xff);
5629 /* record rx statistics for debug */
5630 rxsc_sgien_exflg = pofdm_buf->rxsc_sgien_exflg;
5631 prxsc = (phy_ofdm_rx_status_rxsc_sgien_exintfflag *)&rxsc_sgien_exflg;
5632 if(pdrvinfo->BW) //40M channel
5633 priv->stats.received_bwtype[1+prxsc->rxsc]++;
5634 else //20M channel
5635 priv->stats.received_bwtype[0]++;
5638 //UI BSS List signal strength(in percentage), make it good looking, from 0~100.
5639 //It is assigned to the BSS List in GetValueFromBeaconOrProbeRsp().
5640 if(is_cck_rate)
5642 pstats->SignalStrength = precord_stats->SignalStrength = (u8)(rtl819x_signal_scale_mapping((long)pwdb_all));//PWDB_ALL;
5645 else
5647 //pRfd->Status.SignalStrength = pRecordRfd->Status.SignalStrength = (u1Byte)(SignalScaleMapping(total_rssi/=RF90_PATH_MAX));//(u1Byte)(total_rssi/=RF90_PATH_MAX);
5648 // We can judge RX path number now.
5649 if (rf_rx_num != 0)
5650 pstats->SignalStrength = precord_stats->SignalStrength = (u8)(rtl819x_signal_scale_mapping((long)(total_rssi/=rf_rx_num)));
5652 } /* QueryRxPhyStatus8190Pci */
5654 static void
5655 rtl8192_record_rxdesc_forlateruse(
5656 struct ieee80211_rx_stats * psrc_stats,
5657 struct ieee80211_rx_stats * ptarget_stats
5660 ptarget_stats->bIsAMPDU = psrc_stats->bIsAMPDU;
5661 ptarget_stats->bFirstMPDU = psrc_stats->bFirstMPDU;
5662 //ptarget_stats->Seq_Num = psrc_stats->Seq_Num;
5667 static void TranslateRxSignalStuff819xpci(struct net_device *dev,
5668 struct sk_buff *skb,
5669 struct ieee80211_rx_stats * pstats,
5670 prx_desc_819x_pci pdesc,
5671 prx_fwinfo_819x_pci pdrvinfo)
5673 // TODO: We must only check packet for current MAC address. Not finish
5674 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
5675 bool bpacket_match_bssid, bpacket_toself;
5676 bool bPacketBeacon=false, bToSelfBA=false;
5677 static struct ieee80211_rx_stats previous_stats;
5678 struct ieee80211_hdr_3addr *hdr;
5679 u16 fc,type;
5681 // Get Signal Quality for only RX data queue (but not command queue)
5683 u8* tmp_buf;
5684 u8 *praddr;
5686 /* Get MAC frame start address. */
5687 tmp_buf = skb->data;
5689 hdr = (struct ieee80211_hdr_3addr *)tmp_buf;
5690 fc = le16_to_cpu(hdr->frame_ctl);
5691 type = WLAN_FC_GET_TYPE(fc);
5692 praddr = hdr->addr1;
5694 /* Check if the received packet is acceptabe. */
5695 bpacket_match_bssid = ((IEEE80211_FTYPE_CTL != type) &&
5696 (eqMacAddr(priv->ieee80211->current_network.bssid, (fc & IEEE80211_FCTL_TODS)? hdr->addr1 : (fc & IEEE80211_FCTL_FROMDS )? hdr->addr2 : hdr->addr3))
5697 && (!pstats->bHwError) && (!pstats->bCRC)&& (!pstats->bICV));
5698 bpacket_toself = bpacket_match_bssid & (eqMacAddr(praddr, priv->ieee80211->dev->dev_addr));
5699 #if 1//cosa
5700 if(WLAN_FC_GET_FRAMETYPE(fc)== IEEE80211_STYPE_BEACON)
5702 bPacketBeacon = true;
5703 //DbgPrint("Beacon 2, MatchBSSID = %d, ToSelf = %d \n", bPacketMatchBSSID, bPacketToSelf);
5705 if(WLAN_FC_GET_FRAMETYPE(fc) == IEEE80211_STYPE_BLOCKACK)
5707 if((eqMacAddr(praddr,dev->dev_addr)))
5708 bToSelfBA = true;
5709 //DbgPrint("BlockAck, MatchBSSID = %d, ToSelf = %d \n", bPacketMatchBSSID, bPacketToSelf);
5712 #endif
5713 if(bpacket_match_bssid)
5715 priv->stats.numpacket_matchbssid++;
5717 if(bpacket_toself){
5718 priv->stats.numpacket_toself++;
5721 // Process PHY information for previous packet (RSSI/PWDB/EVM)
5723 // Because phy information is contained in the last packet of AMPDU only, so driver
5724 // should process phy information of previous packet
5725 rtl8192_process_phyinfo(priv, tmp_buf,&previous_stats, pstats);
5726 rtl8192_query_rxphystatus(priv, pstats, pdesc, pdrvinfo, &previous_stats, bpacket_match_bssid,
5727 bpacket_toself ,bPacketBeacon, bToSelfBA);
5728 rtl8192_record_rxdesc_forlateruse(pstats, &previous_stats);
5733 static void rtl8192_tx_resume(struct net_device *dev)
5735 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
5736 struct ieee80211_device *ieee = priv->ieee80211;
5737 struct sk_buff *skb;
5738 int queue_index;
5740 for(queue_index = BK_QUEUE; queue_index < TXCMD_QUEUE;queue_index++) {
5741 while((!skb_queue_empty(&ieee->skb_waitQ[queue_index]))&&
5742 (priv->ieee80211->check_nic_enough_desc(dev,queue_index) > 0)) {
5743 /* 1. dequeue the packet from the wait queue */
5744 skb = skb_dequeue(&ieee->skb_waitQ[queue_index]);
5745 /* 2. tx the packet directly */
5746 ieee->softmac_data_hard_start_xmit(skb,dev,0/* rate useless now*/);
5747 #if 0
5748 if(queue_index!=MGNT_QUEUE) {
5749 ieee->stats.tx_packets++;
5750 ieee->stats.tx_bytes += skb->len;
5752 #endif
5757 void rtl8192_irq_tx_tasklet(struct r8192_priv *priv)
5759 rtl8192_tx_resume(priv->ieee80211->dev);
5763 * Function: UpdateReceivedRateHistogramStatistics
5764 * Overview: Recored down the received data rate
5766 * Input:
5767 * PADAPTER Adapter
5768 * PRT_RFD pRfd,
5770 * Output:
5771 * PRT_TCB Adapter
5772 * (Adapter->RxStats.ReceivedRateHistogram[] is updated)
5773 * Return:
5774 * None
5776 static void UpdateReceivedRateHistogramStatistics8190(
5777 struct net_device *dev,
5778 struct ieee80211_rx_stats* pstats
5781 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
5782 u32 rcvType=1; //0: Total, 1:OK, 2:CRC, 3:ICV
5783 u32 rateIndex;
5784 u32 preamble_guardinterval; //1: short preamble/GI, 0: long preamble/GI
5786 /* 2007/03/09 MH We will not update rate of packet from rx cmd queue. */
5787 #if 0
5788 if (pRfd->queue_id == CMPK_RX_QUEUE_ID)
5789 return;
5790 #endif
5791 if(pstats->bCRC)
5792 rcvType = 2;
5793 else if(pstats->bICV)
5794 rcvType = 3;
5796 if(pstats->bShortPreamble)
5797 preamble_guardinterval = 1;// short
5798 else
5799 preamble_guardinterval = 0;// long
5801 switch(pstats->rate)
5804 // CCK rate
5806 case MGN_1M: rateIndex = 0; break;
5807 case MGN_2M: rateIndex = 1; break;
5808 case MGN_5_5M: rateIndex = 2; break;
5809 case MGN_11M: rateIndex = 3; break;
5811 // Legacy OFDM rate
5813 case MGN_6M: rateIndex = 4; break;
5814 case MGN_9M: rateIndex = 5; break;
5815 case MGN_12M: rateIndex = 6; break;
5816 case MGN_18M: rateIndex = 7; break;
5817 case MGN_24M: rateIndex = 8; break;
5818 case MGN_36M: rateIndex = 9; break;
5819 case MGN_48M: rateIndex = 10; break;
5820 case MGN_54M: rateIndex = 11; break;
5822 // 11n High throughput rate
5824 case MGN_MCS0: rateIndex = 12; break;
5825 case MGN_MCS1: rateIndex = 13; break;
5826 case MGN_MCS2: rateIndex = 14; break;
5827 case MGN_MCS3: rateIndex = 15; break;
5828 case MGN_MCS4: rateIndex = 16; break;
5829 case MGN_MCS5: rateIndex = 17; break;
5830 case MGN_MCS6: rateIndex = 18; break;
5831 case MGN_MCS7: rateIndex = 19; break;
5832 case MGN_MCS8: rateIndex = 20; break;
5833 case MGN_MCS9: rateIndex = 21; break;
5834 case MGN_MCS10: rateIndex = 22; break;
5835 case MGN_MCS11: rateIndex = 23; break;
5836 case MGN_MCS12: rateIndex = 24; break;
5837 case MGN_MCS13: rateIndex = 25; break;
5838 case MGN_MCS14: rateIndex = 26; break;
5839 case MGN_MCS15: rateIndex = 27; break;
5840 default: rateIndex = 28; break;
5842 priv->stats.received_preamble_GI[preamble_guardinterval][rateIndex]++;
5843 priv->stats.received_rate_histogram[0][rateIndex]++; //total
5844 priv->stats.received_rate_histogram[rcvType][rateIndex]++;
5847 static void rtl8192_rx(struct net_device *dev)
5849 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
5850 struct ieee80211_hdr_1addr *ieee80211_hdr = NULL;
5851 bool unicast_packet = false;
5852 struct ieee80211_rx_stats stats = {
5853 .signal = 0,
5854 .noise = -98,
5855 .rate = 0,
5856 .freq = IEEE80211_24GHZ_BAND,
5858 unsigned int count = priv->rxringcount;
5860 stats.nic_type = NIC_8192E;
5862 while (count--) {
5863 rx_desc_819x_pci *pdesc = &priv->rx_ring[priv->rx_idx];//rx descriptor
5864 struct sk_buff *skb = priv->rx_buf[priv->rx_idx];//rx pkt
5866 if (pdesc->OWN){
5867 /* wait data to be filled by hardware */
5868 return;
5869 } else {
5870 stats.bICV = pdesc->ICV;
5871 stats.bCRC = pdesc->CRC32;
5872 stats.bHwError = pdesc->CRC32 | pdesc->ICV;
5874 stats.Length = pdesc->Length;
5875 if(stats.Length < 24)
5876 stats.bHwError |= 1;
5878 if(stats.bHwError) {
5879 stats.bShift = false;
5881 if(pdesc->CRC32) {
5882 if (pdesc->Length <500)
5883 priv->stats.rxcrcerrmin++;
5884 else if (pdesc->Length >1000)
5885 priv->stats.rxcrcerrmax++;
5886 else
5887 priv->stats.rxcrcerrmid++;
5889 goto done;
5890 } else {
5891 prx_fwinfo_819x_pci pDrvInfo = NULL;
5892 struct sk_buff *new_skb = dev_alloc_skb(priv->rxbuffersize);
5894 if (unlikely(!new_skb)) {
5895 goto done;
5898 stats.RxDrvInfoSize = pdesc->RxDrvInfoSize;
5899 stats.RxBufShift = ((pdesc->Shift)&0x03);
5900 stats.Decrypted = !pdesc->SWDec;
5902 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
5903 pci_dma_sync_single_for_cpu(priv->pdev,
5904 #else
5905 pci_unmap_single(priv->pdev,
5906 #endif
5907 *((dma_addr_t *)skb->cb),
5908 priv->rxbuffersize,
5909 PCI_DMA_FROMDEVICE);
5910 skb_put(skb, pdesc->Length);
5911 pDrvInfo = (rx_fwinfo_819x_pci *)(skb->data + stats.RxBufShift);
5912 skb_reserve(skb, stats.RxDrvInfoSize + stats.RxBufShift);
5914 stats.rate = HwRateToMRate90((bool)pDrvInfo->RxHT, (u8)pDrvInfo->RxRate);
5915 stats.bShortPreamble = pDrvInfo->SPLCP;
5917 /* it is debug only. It should be disabled in released driver.
5918 * 2007.1.11 by Emily
5919 * */
5920 UpdateReceivedRateHistogramStatistics8190(dev, &stats);
5922 stats.bIsAMPDU = (pDrvInfo->PartAggr==1);
5923 stats.bFirstMPDU = (pDrvInfo->PartAggr==1) && (pDrvInfo->FirstAGGR==1);
5925 stats.TimeStampLow = pDrvInfo->TSFL;
5926 stats.TimeStampHigh = read_nic_dword(dev, TSFR+4);
5928 UpdateRxPktTimeStamp8190(dev, &stats);
5931 // Get Total offset of MPDU Frame Body
5933 if((stats.RxBufShift + stats.RxDrvInfoSize) > 0)
5934 stats.bShift = 1;
5936 stats.RxIs40MHzPacket = pDrvInfo->BW;
5938 /* ???? */
5939 TranslateRxSignalStuff819xpci(dev,skb, &stats, pdesc, pDrvInfo);
5941 /* Rx A-MPDU */
5942 if(pDrvInfo->FirstAGGR==1 || pDrvInfo->PartAggr == 1)
5943 RT_TRACE(COMP_RXDESC, "pDrvInfo->FirstAGGR = %d, pDrvInfo->PartAggr = %d\n",
5944 pDrvInfo->FirstAGGR, pDrvInfo->PartAggr);
5945 skb_trim(skb, skb->len - 4/*sCrcLng*/);
5946 /* rx packets statistics */
5947 ieee80211_hdr = (struct ieee80211_hdr_1addr *)skb->data;
5948 unicast_packet = false;
5950 if(is_broadcast_ether_addr(ieee80211_hdr->addr1)) {
5951 //TODO
5952 }else if(is_multicast_ether_addr(ieee80211_hdr->addr1)){
5953 //TODO
5954 }else {
5955 /* unicast packet */
5956 unicast_packet = true;
5959 stats.packetlength = stats.Length-4;
5960 stats.fraglength = stats.packetlength;
5961 stats.fragoffset = 0;
5962 stats.ntotalfrag = 1;
5964 if(!ieee80211_rx(priv->ieee80211, skb, &stats)){
5965 dev_kfree_skb_any(skb);
5966 } else {
5967 priv->stats.rxok++;
5968 if(unicast_packet) {
5969 priv->stats.rxbytesunicast += skb->len;
5973 skb = new_skb;
5974 priv->rx_buf[priv->rx_idx] = skb;
5975 *((dma_addr_t *) skb->cb) = pci_map_single(priv->pdev, skb->tail, priv->rxbuffersize, PCI_DMA_FROMDEVICE);
5976 // *((dma_addr_t *) skb->cb) = pci_map_single(priv->pdev, skb_tail_pointer(skb), priv->rxbuffersize, PCI_DMA_FROMDEVICE);
5980 done:
5981 pdesc->BufferAddress = cpu_to_le32(*((dma_addr_t *)skb->cb));
5982 pdesc->OWN = 1;
5983 pdesc->Length = priv->rxbuffersize;
5984 if (priv->rx_idx == priv->rxringcount-1)
5985 pdesc->EOR = 1;
5986 priv->rx_idx = (priv->rx_idx + 1) % priv->rxringcount;
5991 void rtl8192_irq_rx_tasklet(struct r8192_priv *priv)
5993 rtl8192_rx(priv->ieee80211->dev);
5994 /* unmask RDU */
5995 write_nic_dword(priv->ieee80211->dev, INTA_MASK,read_nic_dword(priv->ieee80211->dev, INTA_MASK) | IMR_RDU);
5998 static const struct net_device_ops rtl8192_netdev_ops = {
5999 .ndo_open = rtl8192_open,
6000 .ndo_stop = rtl8192_close,
6001 /* .ndo_get_stats = rtl8192_stats, */
6002 .ndo_tx_timeout = tx_timeout,
6003 .ndo_do_ioctl = rtl8192_ioctl,
6004 .ndo_set_multicast_list = r8192_set_multicast,
6005 .ndo_set_mac_address = r8192_set_mac_adr,
6006 .ndo_start_xmit = ieee80211_xmit,
6009 /****************************************************************************
6010 ---------------------------- PCI_STUFF---------------------------
6011 *****************************************************************************/
6013 static int __devinit rtl8192_pci_probe(struct pci_dev *pdev,
6014 const struct pci_device_id *id)
6016 unsigned long ioaddr = 0;
6017 struct net_device *dev = NULL;
6018 struct r8192_priv *priv= NULL;
6019 u8 unit = 0;
6021 #ifdef CONFIG_RTL8192_IO_MAP
6022 unsigned long pio_start, pio_len, pio_flags;
6023 #else
6024 unsigned long pmem_start, pmem_len, pmem_flags;
6025 #endif //end #ifdef RTL_IO_MAP
6027 RT_TRACE(COMP_INIT,"Configuring chip resources");
6029 if( pci_enable_device (pdev) ){
6030 RT_TRACE(COMP_ERR,"Failed to enable PCI device");
6031 return -EIO;
6034 pci_set_master(pdev);
6035 //pci_set_wmi(pdev);
6036 pci_set_dma_mask(pdev, 0xffffff00ULL);
6037 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
6038 pci_set_consistent_dma_mask(pdev,0xffffff00ULL);
6039 #endif
6040 dev = alloc_ieee80211(sizeof(struct r8192_priv));
6041 if (!dev)
6042 return -ENOMEM;
6044 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
6045 SET_MODULE_OWNER(dev);
6046 #endif
6048 pci_set_drvdata(pdev, dev);
6049 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
6050 SET_NETDEV_DEV(dev, &pdev->dev);
6051 #endif
6052 priv = ieee80211_priv(dev);
6053 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
6054 priv->ieee80211 = netdev_priv(dev);
6055 #else
6056 priv->ieee80211 = (struct ieee80211_device *)dev->priv;
6057 #endif
6058 priv->pdev=pdev;
6059 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
6060 if((pdev->subsystem_vendor == PCI_VENDOR_ID_DLINK)&&(pdev->subsystem_device == 0x3304)){
6061 priv->ieee80211->bSupportRemoteWakeUp = 1;
6062 } else
6063 #endif
6065 priv->ieee80211->bSupportRemoteWakeUp = 0;
6068 #ifdef CONFIG_RTL8192_IO_MAP
6070 pio_start = (unsigned long)pci_resource_start (pdev, 0);
6071 pio_len = (unsigned long)pci_resource_len (pdev, 0);
6072 pio_flags = (unsigned long)pci_resource_flags (pdev, 0);
6074 if (!(pio_flags & IORESOURCE_IO)) {
6075 RT_TRACE(COMP_ERR,"region #0 not a PIO resource, aborting");
6076 goto fail;
6079 //DMESG("IO space @ 0x%08lx", pio_start );
6080 if( ! request_region( pio_start, pio_len, RTL819xE_MODULE_NAME ) ){
6081 RT_TRACE(COMP_ERR,"request_region failed!");
6082 goto fail;
6085 ioaddr = pio_start;
6086 dev->base_addr = ioaddr; // device I/O address
6088 #else
6090 pmem_start = pci_resource_start(pdev, 1);
6091 pmem_len = pci_resource_len(pdev, 1);
6092 pmem_flags = pci_resource_flags (pdev, 1);
6094 if (!(pmem_flags & IORESOURCE_MEM)) {
6095 RT_TRACE(COMP_ERR,"region #1 not a MMIO resource, aborting");
6096 goto fail;
6099 //DMESG("Memory mapped space @ 0x%08lx ", pmem_start);
6100 if( ! request_mem_region(pmem_start, pmem_len, RTL819xE_MODULE_NAME)) {
6101 RT_TRACE(COMP_ERR,"request_mem_region failed!");
6102 goto fail;
6106 ioaddr = (unsigned long)ioremap_nocache( pmem_start, pmem_len);
6107 if( ioaddr == (unsigned long)NULL ){
6108 RT_TRACE(COMP_ERR,"ioremap failed!");
6109 // release_mem_region( pmem_start, pmem_len );
6110 goto fail1;
6113 dev->mem_start = ioaddr; // shared mem start
6114 dev->mem_end = ioaddr + pci_resource_len(pdev, 0); // shared mem end
6116 #endif //end #ifdef RTL_IO_MAP
6118 /* We disable the RETRY_TIMEOUT register (0x41) to keep
6119 * PCI Tx retries from interfering with C3 CPU state */
6120 pci_write_config_byte(pdev, 0x41, 0x00);
6123 pci_read_config_byte(pdev, 0x05, &unit);
6124 pci_write_config_byte(pdev, 0x05, unit & (~0x04));
6126 dev->irq = pdev->irq;
6127 priv->irq = 0;
6129 dev->netdev_ops = &rtl8192_netdev_ops;
6130 #if 0
6131 dev->open = rtl8192_open;
6132 dev->stop = rtl8192_close;
6133 //dev->hard_start_xmit = rtl8192_8023_hard_start_xmit;
6134 dev->tx_timeout = tx_timeout;
6135 //dev->wireless_handlers = &r8192_wx_handlers_def;
6136 dev->do_ioctl = rtl8192_ioctl;
6137 dev->set_multicast_list = r8192_set_multicast;
6138 dev->set_mac_address = r8192_set_mac_adr;
6139 #endif
6141 //DMESG("Oops: i'm coming\n");
6142 #if WIRELESS_EXT >= 12
6143 #if WIRELESS_EXT < 17
6144 dev->get_wireless_stats = r8192_get_wireless_stats;
6145 #endif
6146 dev->wireless_handlers = (struct iw_handler_def *) &r8192_wx_handlers_def;
6147 #endif
6148 //dev->get_wireless_stats = r8192_get_wireless_stats;
6149 dev->type=ARPHRD_ETHER;
6151 dev->watchdog_timeo = HZ*3; //modified by john, 0805
6153 if (dev_alloc_name(dev, ifname) < 0){
6154 RT_TRACE(COMP_INIT, "Oops: devname already taken! Trying wlan%%d...\n");
6155 ifname = "wlan%d";
6156 dev_alloc_name(dev, ifname);
6159 RT_TRACE(COMP_INIT, "Driver probe completed1\n");
6160 if(rtl8192_init(dev)!=0){
6161 RT_TRACE(COMP_ERR, "Initialization failed");
6162 goto fail;
6165 netif_carrier_off(dev);
6166 netif_stop_queue(dev);
6168 register_netdev(dev);
6169 RT_TRACE(COMP_INIT, "dev name=======> %s\n",dev->name);
6170 rtl8192_proc_init_one(dev);
6173 RT_TRACE(COMP_INIT, "Driver probe completed\n");
6174 //#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
6175 // return dev;
6176 //#else
6177 return 0;
6178 //#endif
6180 fail1:
6182 #ifdef CONFIG_RTL8180_IO_MAP
6184 if( dev->base_addr != 0 ){
6186 release_region(dev->base_addr,
6187 pci_resource_len(pdev, 0) );
6189 #else
6190 if( dev->mem_start != (unsigned long)NULL ){
6191 iounmap( (void *)dev->mem_start );
6192 release_mem_region( pci_resource_start(pdev, 1),
6193 pci_resource_len(pdev, 1) );
6195 #endif //end #ifdef RTL_IO_MAP
6197 fail:
6198 if(dev){
6200 if (priv->irq) {
6201 free_irq(dev->irq, dev);
6202 dev->irq=0;
6204 free_ieee80211(dev);
6207 pci_disable_device(pdev);
6209 DMESG("wlan driver load failed\n");
6210 pci_set_drvdata(pdev, NULL);
6211 return -ENODEV;
6215 /* detach all the work and timer structure declared or inititialized
6216 * in r8192_init function.
6217 * */
6218 void rtl8192_cancel_deferred_work(struct r8192_priv* priv)
6220 /* call cancel_work_sync instead of cancel_delayed_work if and only if Linux_version_code
6221 * is or is newer than 2.6.20 and work structure is defined to be struct work_struct.
6222 * Otherwise call cancel_delayed_work is enough.
6223 * FIXME (2.6.20 shoud 2.6.22, work_struct shoud not cancel)
6224 * */
6225 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
6226 cancel_delayed_work(&priv->watch_dog_wq);
6227 cancel_delayed_work(&priv->update_beacon_wq);
6228 cancel_delayed_work(&priv->ieee80211->hw_wakeup_wq);
6229 cancel_delayed_work(&priv->ieee80211->hw_sleep_wq);
6230 #ifdef RTL8192E
6231 cancel_delayed_work(&priv->gpio_change_rf_wq);
6232 #endif
6233 #endif
6234 #if LINUX_VERSION_CODE >=KERNEL_VERSION(2,6,22)
6235 cancel_work_sync(&priv->reset_wq);
6236 cancel_work_sync(&priv->qos_activate);
6237 //cancel_work_sync(&priv->SetBWModeWorkItem);
6238 //cancel_work_sync(&priv->SwChnlWorkItem);
6239 #else
6240 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
6241 cancel_delayed_work(&priv->reset_wq);
6242 cancel_delayed_work(&priv->qos_activate);
6243 //cancel_delayed_work(&priv->SetBWModeWorkItem);
6244 //cancel_delayed_work(&priv->SwChnlWorkItem);
6245 #endif
6246 #endif
6251 static void __devexit rtl8192_pci_disconnect(struct pci_dev *pdev)
6253 struct net_device *dev = pci_get_drvdata(pdev);
6254 struct r8192_priv *priv ;
6256 if(dev){
6258 unregister_netdev(dev);
6260 priv=ieee80211_priv(dev);
6262 rtl8192_proc_remove_one(dev);
6264 rtl8192_down(dev);
6265 if (priv->pFirmware)
6267 vfree(priv->pFirmware);
6268 priv->pFirmware = NULL;
6270 // priv->rf_close(dev);
6271 // rtl8192_usb_deleteendpoints(dev);
6272 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
6273 destroy_workqueue(priv->priv_wq);
6274 #endif
6275 /* redundant with rtl8192_down */
6276 // rtl8192_irq_disable(dev);
6277 // rtl8192_reset(dev);
6278 // mdelay(10);
6280 u32 i;
6281 /* free tx/rx rings */
6282 rtl8192_free_rx_ring(dev);
6283 for (i = 0; i < MAX_TX_QUEUE_COUNT; i++) {
6284 rtl8192_free_tx_ring(dev, i);
6287 if(priv->irq){
6289 printk("Freeing irq %d\n",dev->irq);
6290 free_irq(dev->irq, dev);
6291 priv->irq=0;
6297 // free_beacon_desc_ring(dev,priv->txbeaconcount);
6299 #ifdef CONFIG_RTL8180_IO_MAP
6301 if( dev->base_addr != 0 ){
6303 release_region(dev->base_addr,
6304 pci_resource_len(pdev, 0) );
6306 #else
6307 if( dev->mem_start != (unsigned long)NULL ){
6308 iounmap( (void *)dev->mem_start );
6309 release_mem_region( pci_resource_start(pdev, 1),
6310 pci_resource_len(pdev, 1) );
6312 #endif /*end #ifdef RTL_IO_MAP*/
6313 free_ieee80211(dev);
6317 pci_disable_device(pdev);
6318 RT_TRACE(COMP_DOWN, "wlan driver removed\n");
6321 extern int ieee80211_init(void);
6322 extern void ieee80211_exit(void);
6324 static int __init rtl8192_pci_module_init(void)
6326 int retval;
6328 retval = ieee80211_init();
6329 if (retval)
6330 return retval;
6332 printk(KERN_INFO "\nLinux kernel driver for RTL8192 based WLAN cards\n");
6333 printk(KERN_INFO "Copyright (c) 2007-2008, Realsil Wlan\n");
6334 RT_TRACE(COMP_INIT, "Initializing module");
6335 RT_TRACE(COMP_INIT, "Wireless extensions version %d", WIRELESS_EXT);
6336 rtl8192_proc_module_init();
6337 #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22))
6338 if(0!=pci_module_init(&rtl8192_pci_driver))
6339 #else
6340 if(0!=pci_register_driver(&rtl8192_pci_driver))
6341 #endif
6343 DMESG("No device found");
6344 /*pci_unregister_driver (&rtl8192_pci_driver);*/
6345 return -ENODEV;
6347 return 0;
6351 static void __exit rtl8192_pci_module_exit(void)
6353 pci_unregister_driver(&rtl8192_pci_driver);
6355 RT_TRACE(COMP_DOWN, "Exiting");
6356 rtl8192_proc_module_remove();
6357 ieee80211_exit();
6360 //warning message WB
6361 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18)
6362 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
6363 void rtl8192_interrupt(int irq, void *netdev, struct pt_regs *regs)
6364 #else
6365 irqreturn_t rtl8192_interrupt(int irq, void *netdev, struct pt_regs *regs)
6366 #endif
6367 #else
6368 irqreturn_t rtl8192_interrupt(int irq, void *netdev)
6369 #endif
6371 struct net_device *dev = (struct net_device *) netdev;
6372 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
6373 unsigned long flags;
6374 u32 inta;
6375 /* We should return IRQ_NONE, but for now let me keep this */
6376 if(priv->irq_enabled == 0){
6377 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
6378 return;
6379 #else
6380 return IRQ_HANDLED;
6381 #endif
6384 spin_lock_irqsave(&priv->irq_th_lock,flags);
6386 //ISR: 4bytes
6388 inta = read_nic_dword(dev, ISR);// & priv->IntrMask;
6389 write_nic_dword(dev,ISR,inta); // reset int situation
6391 priv->stats.shints++;
6392 //DMESG("Enter interrupt, ISR value = 0x%08x", inta);
6393 if(!inta){
6394 spin_unlock_irqrestore(&priv->irq_th_lock,flags);
6395 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
6396 return;
6397 #else
6398 return IRQ_HANDLED;
6399 #endif
6401 most probably we can safely return IRQ_NONE,
6402 but for now is better to avoid problems
6406 if(inta == 0xffff){
6407 /* HW disappared */
6408 spin_unlock_irqrestore(&priv->irq_th_lock,flags);
6409 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
6410 return;
6411 #else
6412 return IRQ_HANDLED;
6413 #endif
6416 priv->stats.ints++;
6417 #ifdef DEBUG_IRQ
6418 DMESG("NIC irq %x",inta);
6419 #endif
6420 //priv->irqpending = inta;
6423 if(!netif_running(dev)) {
6424 spin_unlock_irqrestore(&priv->irq_th_lock,flags);
6425 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
6426 return;
6427 #else
6428 return IRQ_HANDLED;
6429 #endif
6432 if(inta & IMR_TIMEOUT0){
6433 // write_nic_dword(dev, TimerInt, 0);
6434 //DMESG("=================>waking up");
6435 // rtl8180_hw_wakeup(dev);
6438 if(inta & IMR_TBDOK){
6439 RT_TRACE(COMP_INTR, "beacon ok interrupt!\n");
6440 rtl8192_tx_isr(dev, BEACON_QUEUE);
6441 priv->stats.txbeaconokint++;
6444 if(inta & IMR_TBDER){
6445 RT_TRACE(COMP_INTR, "beacon ok interrupt!\n");
6446 rtl8192_tx_isr(dev, BEACON_QUEUE);
6447 priv->stats.txbeaconerr++;
6450 if(inta & IMR_MGNTDOK ) {
6451 RT_TRACE(COMP_INTR, "Manage ok interrupt!\n");
6452 priv->stats.txmanageokint++;
6453 rtl8192_tx_isr(dev,MGNT_QUEUE);
6457 if(inta & IMR_COMDOK)
6459 priv->stats.txcmdpktokint++;
6460 rtl8192_tx_isr(dev,TXCMD_QUEUE);
6463 if(inta & IMR_ROK){
6464 #ifdef DEBUG_RX
6465 DMESG("Frame arrived !");
6466 #endif
6467 priv->stats.rxint++;
6468 tasklet_schedule(&priv->irq_rx_tasklet);
6471 if(inta & IMR_BcnInt) {
6472 RT_TRACE(COMP_INTR, "prepare beacon for interrupt!\n");
6473 tasklet_schedule(&priv->irq_prepare_beacon_tasklet);
6476 if(inta & IMR_RDU){
6477 RT_TRACE(COMP_INTR, "rx descriptor unavailable!\n");
6478 priv->stats.rxrdu++;
6479 /* reset int situation */
6480 write_nic_dword(dev,INTA_MASK,read_nic_dword(dev, INTA_MASK) & ~IMR_RDU);
6481 tasklet_schedule(&priv->irq_rx_tasklet);
6484 if(inta & IMR_RXFOVW){
6485 RT_TRACE(COMP_INTR, "rx overflow !\n");
6486 priv->stats.rxoverflow++;
6487 tasklet_schedule(&priv->irq_rx_tasklet);
6490 if(inta & IMR_TXFOVW) priv->stats.txoverflow++;
6492 if(inta & IMR_BKDOK){
6493 RT_TRACE(COMP_INTR, "BK Tx OK interrupt!\n");
6494 priv->stats.txbkokint++;
6495 priv->ieee80211->LinkDetectInfo.NumTxOkInPeriod++;
6496 rtl8192_tx_isr(dev,BK_QUEUE);
6497 rtl8192_try_wake_queue(dev, BK_QUEUE);
6500 if(inta & IMR_BEDOK){
6501 RT_TRACE(COMP_INTR, "BE TX OK interrupt!\n");
6502 priv->stats.txbeokint++;
6503 priv->ieee80211->LinkDetectInfo.NumTxOkInPeriod++;
6504 rtl8192_tx_isr(dev,BE_QUEUE);
6505 rtl8192_try_wake_queue(dev, BE_QUEUE);
6508 if(inta & IMR_VIDOK){
6509 RT_TRACE(COMP_INTR, "VI TX OK interrupt!\n");
6510 priv->stats.txviokint++;
6511 priv->ieee80211->LinkDetectInfo.NumTxOkInPeriod++;
6512 rtl8192_tx_isr(dev,VI_QUEUE);
6513 rtl8192_try_wake_queue(dev, VI_QUEUE);
6516 if(inta & IMR_VODOK){
6517 priv->stats.txvookint++;
6518 priv->ieee80211->LinkDetectInfo.NumTxOkInPeriod++;
6519 rtl8192_tx_isr(dev,VO_QUEUE);
6520 rtl8192_try_wake_queue(dev, VO_QUEUE);
6523 force_pci_posting(dev);
6524 spin_unlock_irqrestore(&priv->irq_th_lock,flags);
6526 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
6527 return;
6528 #else
6529 return IRQ_HANDLED;
6530 #endif
6533 void rtl8192_try_wake_queue(struct net_device *dev, int pri)
6535 #if 0
6536 unsigned long flags;
6537 short enough_desc;
6538 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
6540 spin_lock_irqsave(&priv->tx_lock,flags);
6541 enough_desc = check_nic_enough_desc(dev,pri);
6542 spin_unlock_irqrestore(&priv->tx_lock,flags);
6544 if(enough_desc)
6545 ieee80211_wake_queue(priv->ieee80211);
6546 #endif
6550 void EnableHWSecurityConfig8192(struct net_device *dev)
6552 u8 SECR_value = 0x0;
6553 // struct ieee80211_device* ieee1 = container_of(&dev, struct ieee80211_device, dev);
6554 //printk("==>ieee1:%p, dev:%p\n", ieee1, dev);
6555 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
6556 struct ieee80211_device* ieee = priv->ieee80211;
6557 //printk("==>ieee:%p, dev:%p\n", ieee, dev);
6558 SECR_value = SCR_TxEncEnable | SCR_RxDecEnable;
6559 #if 1
6560 if (((KEY_TYPE_WEP40 == ieee->pairwise_key_type) || (KEY_TYPE_WEP104 == ieee->pairwise_key_type)) && (priv->ieee80211->auth_mode != 2))
6562 SECR_value |= SCR_RxUseDK;
6563 SECR_value |= SCR_TxUseDK;
6565 else if ((ieee->iw_mode == IW_MODE_ADHOC) && (ieee->pairwise_key_type & (KEY_TYPE_CCMP | KEY_TYPE_TKIP)))
6567 SECR_value |= SCR_RxUseDK;
6568 SECR_value |= SCR_TxUseDK;
6571 #endif
6573 //add HWSec active enable here.
6574 //default using hwsec. when peer AP is in N mode only and pairwise_key_type is none_aes(which HT_IOT_ACT_PURE_N_MODE indicates it), use software security. when peer AP is in b,g,n mode mixed and pairwise_key_type is none_aes, use g mode hw security. WB on 2008.7.4
6575 ieee->hwsec_active = 1;
6577 if ((ieee->pHTInfo->IOTAction&HT_IOT_ACT_PURE_N_MODE) || !hwwep)//!ieee->hwsec_support) //add hwsec_support flag to totol control hw_sec on/off
6579 ieee->hwsec_active = 0;
6580 SECR_value &= ~SCR_RxDecEnable;
6583 RT_TRACE(COMP_SEC,"%s:, hwsec:%d, pairwise_key:%d, SECR_value:%x\n", __FUNCTION__, \
6584 ieee->hwsec_active, ieee->pairwise_key_type, SECR_value);
6586 write_nic_byte(dev, SECR, SECR_value);//SECR_value | SCR_UseDK );
6590 #define TOTAL_CAM_ENTRY 32
6591 //#define CAM_CONTENT_COUNT 8
6592 void setKey( struct net_device *dev,
6593 u8 EntryNo,
6594 u8 KeyIndex,
6595 u16 KeyType,
6596 u8 *MacAddr,
6597 u8 DefaultKey,
6598 u32 *KeyContent )
6600 u32 TargetCommand = 0;
6601 u32 TargetContent = 0;
6602 u16 usConfig = 0;
6603 u8 i;
6604 #ifdef ENABLE_IPS
6605 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
6606 RT_RF_POWER_STATE rtState;
6607 rtState = priv->ieee80211->eRFPowerState;
6608 if(priv->ieee80211->PowerSaveControl.bInactivePs){
6609 if(rtState == eRfOff){
6610 if(priv->ieee80211->RfOffReason > RF_CHANGE_BY_IPS)
6612 RT_TRACE(COMP_ERR, "%s(): RF is OFF.\n",__FUNCTION__);
6613 up(&priv->wx_sem);
6614 return ;
6616 else{
6617 IPSLeave(dev);
6621 priv->ieee80211->is_set_key = true;
6622 #endif
6623 if (EntryNo >= TOTAL_CAM_ENTRY)
6624 RT_TRACE(COMP_ERR, "cam entry exceeds in setKey()\n");
6626 RT_TRACE(COMP_SEC, "====>to setKey(), dev:%p, EntryNo:%d, KeyIndex:%d, KeyType:%d, MacAddr"MAC_FMT"\n", dev,EntryNo, KeyIndex, KeyType, MAC_ARG(MacAddr));
6628 if (DefaultKey)
6629 usConfig |= BIT15 | (KeyType<<2);
6630 else
6631 usConfig |= BIT15 | (KeyType<<2) | KeyIndex;
6632 // usConfig |= BIT15 | (KeyType<<2) | (DefaultKey<<5) | KeyIndex;
6635 for(i=0 ; i<CAM_CONTENT_COUNT; i++){
6636 TargetCommand = i+CAM_CONTENT_COUNT*EntryNo;
6637 TargetCommand |= BIT31|BIT16;
6639 if(i==0){//MAC|Config
6640 TargetContent = (u32)(*(MacAddr+0)) << 16|
6641 (u32)(*(MacAddr+1)) << 24|
6642 (u32)usConfig;
6644 write_nic_dword(dev, WCAMI, TargetContent);
6645 write_nic_dword(dev, RWCAM, TargetCommand);
6646 // printk("setkey cam =%8x\n", read_cam(dev, i+6*EntryNo));
6648 else if(i==1){//MAC
6649 TargetContent = (u32)(*(MacAddr+2)) |
6650 (u32)(*(MacAddr+3)) << 8|
6651 (u32)(*(MacAddr+4)) << 16|
6652 (u32)(*(MacAddr+5)) << 24;
6653 write_nic_dword(dev, WCAMI, TargetContent);
6654 write_nic_dword(dev, RWCAM, TargetCommand);
6656 else { //Key Material
6657 if(KeyContent != NULL)
6659 write_nic_dword(dev, WCAMI, (u32)(*(KeyContent+i-2)) );
6660 write_nic_dword(dev, RWCAM, TargetCommand);
6664 RT_TRACE(COMP_SEC,"=========>after set key, usconfig:%x\n", usConfig);
6666 // This function seems not ready! WB
6667 void CamPrintDbgReg(struct net_device* dev)
6669 unsigned long rvalue;
6670 unsigned char ucValue;
6671 write_nic_dword(dev, DCAM, 0x80000000);
6672 msleep(40);
6673 rvalue = read_nic_dword(dev, DCAM); //delay_ms(40);
6674 RT_TRACE(COMP_SEC, " TX CAM=%8lX ",rvalue);
6675 if((rvalue & 0x40000000) != 0x4000000)
6676 RT_TRACE(COMP_SEC, "-->TX Key Not Found ");
6677 msleep(20);
6678 write_nic_dword(dev, DCAM, 0x00000000); //delay_ms(40);
6679 rvalue = read_nic_dword(dev, DCAM); //delay_ms(40);
6680 RT_TRACE(COMP_SEC, "RX CAM=%8lX ",rvalue);
6681 if((rvalue & 0x40000000) != 0x4000000)
6682 RT_TRACE(COMP_SEC, "-->CAM Key Not Found ");
6683 ucValue = read_nic_byte(dev, SECR);
6684 RT_TRACE(COMP_SEC, "WPA_Config=%x \n",ucValue);
6688 /***************************************************************************
6689 ------------------- module init / exit stubs ----------------
6690 ****************************************************************************/
6691 module_init(rtl8192_pci_module_init);
6692 module_exit(rtl8192_pci_module_exit);