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
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>
27 #ifndef CONFIG_FORCE_HARD_FLOAT
28 double __floatsidf (int i) { return i; }
29 unsigned int __fixunsdfsi (double d) { return d; }
30 double __adddf3(double a, double b) { return a+b; }
31 double __addsf3(float a, float b) { return a+b; }
32 double __subdf3(double a, double b) { return a-b; }
33 double __extendsfdf2(float a) {return a;}
37 #undef RX_DONT_PASS_UL
39 #undef DEBUG_RX_VERBOSE
45 #undef DEBUG_TX_FILLDESC
50 #undef DEBUG_REGISTERS
52 #undef DEBUG_IRQ_TASKLET
56 //#define CONFIG_RTL8192_IO_MAP
57 #include <asm/uaccess.h>
58 #include "r8192E_hw.h"
60 #include "r8190_rtl8256.h" /* RTL8225 Radio frontend */
61 #include "r8180_93cx6.h" /* Card EEPROM */
62 #include "r8192E_wx.h"
63 #include "r819xE_phy.h" //added by WB 4.30.2008
64 #include "r819xE_phyreg.h"
65 #include "r819xE_cmdpkt.h"
66 #include "r8192E_dm.h"
67 //#include "r8192xU_phyreg.h"
68 //#include <linux/usb.h>
69 // FIXME: check if 2.6.7 is ok
79 //set here to open your trace code. //WB
80 u32 rt_global_debug_component = \
98 // COMP_POWER_TRACKING |
100 COMP_ERR ; //always open err flags on
102 #define PCI_DEVICE(vend,dev)\
103 .vendor=(vend),.device=(dev),\
104 .subvendor=PCI_ANY_ID,.subdevice=PCI_ANY_ID
106 static struct pci_device_id rtl8192_pci_id_tbl[] __devinitdata = {
110 { PCI_DEVICE(0x10ec, 0x8190) },
112 { PCI_DEVICE(0x07aa, 0x0045) },
113 { PCI_DEVICE(0x07aa, 0x0046) },
116 { PCI_DEVICE(0x10ec, 0x8192) },
119 { PCI_DEVICE(0x07aa, 0x0044) },
120 { PCI_DEVICE(0x07aa, 0x0047) },
125 static char* ifname = "wlan%d";
127 static int hwseqnum = 0;
128 static int hwwep = 0;
130 static int hwwep = 1; //default use hw. set 0 to use software security
131 static int channels = 0x3fff;
133 MODULE_LICENSE("GPL");
134 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
135 MODULE_VERSION("V 1.1");
137 MODULE_DEVICE_TABLE(pci, rtl8192_pci_id_tbl);
138 //MODULE_AUTHOR("Andrea Merello <andreamrl@tiscali.it>");
139 MODULE_DESCRIPTION("Linux driver for Realtek RTL819x WiFi cards");
142 MODULE_PARM(ifname,"s");
143 MODULE_PARM_DESC(devname," Net interface name, wlan%d=default");
145 MODULE_PARM(hwseqnum,"i");
146 MODULE_PARM_DESC(hwseqnum," Try to use hardware 802.11 header sequence numbers. Zero=default");
148 MODULE_PARM(hwwep,"i");
149 MODULE_PARM_DESC(hwwep," Try to use hardware WEP support. Still broken and not available on all cards");
151 MODULE_PARM(channels,"i");
152 MODULE_PARM_DESC(channels," Channel bitmask for specific locales. NYI");
155 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 9)
156 module_param(ifname, charp, S_IRUGO|S_IWUSR );
157 //module_param(hwseqnum,int, S_IRUGO|S_IWUSR);
158 module_param(hwwep,int, S_IRUGO|S_IWUSR);
159 module_param(channels,int, S_IRUGO|S_IWUSR);
161 MODULE_PARM(ifname, "s");
162 //MODULE_PARM(hwseqnum,"i");
163 MODULE_PARM(hwwep,"i");
164 MODULE_PARM(channels,"i");
167 MODULE_PARM_DESC(ifname," Net interface name, wlan%d=default");
168 //MODULE_PARM_DESC(hwseqnum," Try to use hardware 802.11 header sequence numbers. Zero=default");
169 MODULE_PARM_DESC(hwwep," Try to use hardware WEP support. Still broken and not available on all cards");
170 MODULE_PARM_DESC(channels," Channel bitmask for specific locales. NYI");
172 static int __devinit rtl8192_pci_probe(struct pci_dev *pdev,
173 const struct pci_device_id *id);
174 static void __devexit rtl8192_pci_disconnect(struct pci_dev *pdev);
176 static struct pci_driver rtl8192_pci_driver = {
177 .name = RTL819xE_MODULE_NAME, /* Driver name */
178 .id_table = rtl8192_pci_id_tbl, /* PCI_ID table */
179 .probe = rtl8192_pci_probe, /* probe fn */
180 .remove = __devexit_p(rtl8192_pci_disconnect), /* remove fn */
181 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0)
183 .suspend = rtl8192E_suspend, /* PM suspend fn */
184 .resume = rtl8192E_resume, /* PM resume fn */
186 .suspend = NULL, /* PM suspend fn */
187 .resume = NULL, /* PM resume fn */
194 typedef struct _CHANNEL_LIST
198 }CHANNEL_LIST, *PCHANNEL_LIST;
200 static CHANNEL_LIST ChannelPlan[] = {
201 {{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
202 {{1,2,3,4,5,6,7,8,9,10,11},11}, //IC
203 {{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48,52,56,60,64},21}, //ETSI
204 {{1,2,3,4,5,6,7,8,9,10,11,12,13},13}, //Spain. Change to ETSI.
205 {{1,2,3,4,5,6,7,8,9,10,11,12,13},13}, //France. Change to ETSI.
206 {{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
207 {{1,2,3,4,5,6,7,8,9,10,11,12,13,14,36,40,44,48,52,56,60,64},22},//MKK1
208 {{1,2,3,4,5,6,7,8,9,10,11,12,13},13}, //Israel.
209 {{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
210 {{1,2,3,4,5,6,7,8,9,10,11,12,13,14,36,40,44,48,52,56,60,64}, 22}, //MIC
211 {{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
214 static void rtl819x_set_channel_map(u8 channel_plan, struct r8192_priv* priv)
216 int i, max_chan=-1, min_chan=-1;
217 struct ieee80211_device* ieee = priv->ieee80211;
218 switch (channel_plan)
220 case COUNTRY_CODE_FCC:
221 case COUNTRY_CODE_IC:
222 case COUNTRY_CODE_ETSI:
223 case COUNTRY_CODE_SPAIN:
224 case COUNTRY_CODE_FRANCE:
225 case COUNTRY_CODE_MKK:
226 case COUNTRY_CODE_MKK1:
227 case COUNTRY_CODE_ISRAEL:
228 case COUNTRY_CODE_TELEC:
229 case COUNTRY_CODE_MIC:
232 ieee->bGlobalDomain = false;
233 //acturally 8225 & 8256 rf chip only support B,G,24N mode
234 if ((priv->rf_chip == RF_8225) || (priv->rf_chip == RF_8256))
241 RT_TRACE(COMP_ERR, "unknown rf chip, can't set channel map in function:%s()\n", __FUNCTION__);
243 if (ChannelPlan[channel_plan].Len != 0){
244 // Clear old channel map
245 memset(GET_DOT11D_INFO(ieee)->channel_map, 0, sizeof(GET_DOT11D_INFO(ieee)->channel_map));
246 // Set new channel map
247 for (i=0;i<ChannelPlan[channel_plan].Len;i++)
249 if (ChannelPlan[channel_plan].Channel[i] < min_chan || ChannelPlan[channel_plan].Channel[i] > max_chan)
251 GET_DOT11D_INFO(ieee)->channel_map[ChannelPlan[channel_plan].Channel[i]] = 1;
256 case COUNTRY_CODE_GLOBAL_DOMAIN:
258 GET_DOT11D_INFO(ieee)->bEnabled = 0; //this flag enabled to follow 11d country IE setting, otherwise, it shall follow global domain setting
260 ieee->bGlobalDomain = true;
270 #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 )
271 /* 2007/07/25 MH Defien temp tx fw info. */
272 static TX_FWINFO_T Tmp_TxFwInfo;
275 #define rx_hal_is_cck_rate(_pdrvinfo)\
276 (_pdrvinfo->RxRate == DESC90_RATE1M ||\
277 _pdrvinfo->RxRate == DESC90_RATE2M ||\
278 _pdrvinfo->RxRate == DESC90_RATE5_5M ||\
279 _pdrvinfo->RxRate == DESC90_RATE11M) &&\
283 void CamResetAllEntry(struct net_device *dev)
289 ulcommand |= BIT31|BIT30;
290 write_nic_dword(dev, RWCAM, ulcommand);
292 for(ucIndex=0;ucIndex<TOTAL_CAM_ENTRY;ucIndex++)
293 CAM_mark_invalid(dev, ucIndex);
294 for(ucIndex=0;ucIndex<TOTAL_CAM_ENTRY;ucIndex++)
295 CAM_empty_entry(dev, ucIndex);
300 void write_cam(struct net_device *dev, u8 addr, u32 data)
302 write_nic_dword(dev, WCAMI, data);
303 write_nic_dword(dev, RWCAM, BIT31|BIT16|(addr&0xff) );
305 u32 read_cam(struct net_device *dev, u8 addr)
307 write_nic_dword(dev, RWCAM, 0x80000000|(addr&0xff) );
308 return read_nic_dword(dev, 0xa8);
311 ////////////////////////////////////////////////////////////
312 #ifdef CONFIG_RTL8180_IO_MAP
314 u8 read_nic_byte(struct net_device *dev, int x)
316 return 0xff&inb(dev->base_addr +x);
319 u32 read_nic_dword(struct net_device *dev, int x)
321 return inl(dev->base_addr +x);
324 u16 read_nic_word(struct net_device *dev, int x)
326 return inw(dev->base_addr +x);
329 void write_nic_byte(struct net_device *dev, int x,u8 y)
331 outb(y&0xff,dev->base_addr +x);
334 void write_nic_word(struct net_device *dev, int x,u16 y)
336 outw(y,dev->base_addr +x);
339 void write_nic_dword(struct net_device *dev, int x,u32 y)
341 outl(y,dev->base_addr +x);
344 #else /* RTL_IO_MAP */
346 u8 read_nic_byte(struct net_device *dev, int x)
348 return 0xff&readb((u8*)dev->mem_start +x);
351 u32 read_nic_dword(struct net_device *dev, int x)
353 return readl((u8*)dev->mem_start +x);
356 u16 read_nic_word(struct net_device *dev, int x)
358 return readw((u8*)dev->mem_start +x);
361 void write_nic_byte(struct net_device *dev, int x,u8 y)
363 writeb(y,(u8*)dev->mem_start +x);
367 void write_nic_dword(struct net_device *dev, int x,u32 y)
369 writel(y,(u8*)dev->mem_start +x);
373 void write_nic_word(struct net_device *dev, int x,u16 y)
375 writew(y,(u8*)dev->mem_start +x);
379 #endif /* RTL_IO_MAP */
382 ///////////////////////////////////////////////////////////
384 //u8 read_phy_cck(struct net_device *dev, u8 adr);
385 //u8 read_phy_ofdm(struct net_device *dev, u8 adr);
386 /* this might still called in what was the PHY rtl8185/rtl8192 common code
387 * plans are to possibilty turn it again in one common code...
389 inline void force_pci_posting(struct net_device *dev)
395 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18)
396 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
397 void rtl8192_interrupt(int irq, void *netdev, struct pt_regs *regs);
399 irqreturn_t rtl8192_interrupt(int irq, void *netdev, struct pt_regs *regs);
402 irqreturn_t rtl8192_interrupt(int irq, void *netdev);
404 //static struct net_device_stats *rtl8192_stats(struct net_device *dev);
405 void rtl8192_commit(struct net_device *dev);
406 //void rtl8192_restart(struct net_device *dev);
407 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
408 void rtl8192_restart(struct work_struct *work);
409 //void rtl8192_rq_tx_ack(struct work_struct *work);
411 void rtl8192_restart(struct net_device *dev);
412 // //void rtl8192_rq_tx_ack(struct net_device *dev);
415 void watch_dog_timer_callback(unsigned long data);
417 void IPSEnter(struct net_device *dev);
418 void IPSLeave(struct net_device *dev);
419 void InactivePsWorkItemCallback(struct net_device *dev);
421 /****************************************************************************
422 -----------------------------PROCFS STUFF-------------------------
423 *****************************************************************************/
425 static struct proc_dir_entry *rtl8192_proc = NULL;
429 static int proc_get_stats_ap(char *page, char **start,
430 off_t offset, int count,
431 int *eof, void *data)
433 struct net_device *dev = data;
434 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
435 struct ieee80211_device *ieee = priv->ieee80211;
436 struct ieee80211_network *target;
440 list_for_each_entry(target, &ieee->network_list, list) {
442 len += snprintf(page + len, count - len,
443 "%s ", target->ssid);
445 if(target->wpa_ie_len>0 || target->rsn_ie_len>0){
446 len += snprintf(page + len, count - len,
450 len += snprintf(page + len, count - len,
460 static int proc_get_registers(char *page, char **start,
461 off_t offset, int count,
462 int *eof, void *data)
464 struct net_device *dev = data;
465 // struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
472 /* This dump the current register page */
473 len += snprintf(page + len, count - len,
474 "\n####################page 0##################\n ");
478 //printk( "\nD: %2x> ", n);
479 len += snprintf(page + len, count - len,
482 for(i=0;i<16 && n<=max;i++,n++)
483 len += snprintf(page + len, count - len,
484 "%2x ",read_nic_byte(dev,n));
486 // printk("%2x ",read_nic_byte(dev,n));
488 len += snprintf(page + len, count - len,"\n");
489 len += snprintf(page + len, count - len,
490 "\n####################page 1##################\n ");
493 //printk( "\nD: %2x> ", n);
494 len += snprintf(page + len, count - len,
497 for(i=0;i<16 && n<=max;i++,n++)
498 len += snprintf(page + len, count - len,
499 "%2x ",read_nic_byte(dev,0x100|n));
501 // printk("%2x ",read_nic_byte(dev,n));
504 len += snprintf(page + len, count - len,
505 "\n####################page 3##################\n ");
508 //printk( "\nD: %2x> ", n);
509 len += snprintf(page + len, count - len,
512 for(i=0;i<16 && n<=max;i++,n++)
513 len += snprintf(page + len, count - len,
514 "%2x ",read_nic_byte(dev,0x300|n));
516 // printk("%2x ",read_nic_byte(dev,n));
527 static int proc_get_cck_reg(char *page, char **start,
528 off_t offset, int count,
529 int *eof, void *data)
531 struct net_device *dev = data;
532 // struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
539 /* This dump the current register page */
542 //printk( "\nD: %2x> ", n);
543 len += snprintf(page + len, count - len,
546 for(i=0;i<16 && n<=max;i++,n++)
547 len += snprintf(page + len, count - len,
548 "%2x ",read_phy_cck(dev,n));
550 // printk("%2x ",read_nic_byte(dev,n));
552 len += snprintf(page + len, count - len,"\n");
562 static int proc_get_ofdm_reg(char *page, char **start,
563 off_t offset, int count,
564 int *eof, void *data)
567 struct net_device *dev = data;
568 // struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
576 /* This dump the current register page */
579 //printk( "\nD: %2x> ", n);
580 len += snprintf(page + len, count - len,
583 for(i=0;i<16 && n<=max;i++,n++)
584 len += snprintf(page + len, count - len,
585 "%2x ",read_phy_ofdm(dev,n));
587 // printk("%2x ",read_nic_byte(dev,n));
589 len += snprintf(page + len, count - len,"\n");
600 static int proc_get_stats_hw(char *page, char **start,
601 off_t offset, int count,
602 int *eof, void *data)
604 struct net_device *dev = data;
605 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
609 len += snprintf(page + len, count - len,
620 static int proc_get_stats_tx(char *page, char **start,
621 off_t offset, int count,
622 int *eof, void *data)
624 struct net_device *dev = data;
625 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
629 len += snprintf(page + len, count - len,
630 "TX VI priority ok int: %lu\n"
631 // "TX VI priority error int: %lu\n"
632 "TX VO priority ok int: %lu\n"
633 // "TX VO priority error int: %lu\n"
634 "TX BE priority ok int: %lu\n"
635 // "TX BE priority error int: %lu\n"
636 "TX BK priority ok int: %lu\n"
637 // "TX BK priority error int: %lu\n"
638 "TX MANAGE priority ok int: %lu\n"
639 // "TX MANAGE priority error int: %lu\n"
640 "TX BEACON priority ok int: %lu\n"
641 "TX BEACON priority error int: %lu\n"
642 "TX CMDPKT priority ok int: %lu\n"
643 // "TX high priority ok int: %lu\n"
644 // "TX high priority failed error int: %lu\n"
645 // "TX queue resume: %lu\n"
646 "TX queue stopped?: %d\n"
647 "TX fifo overflow: %lu\n"
648 // "TX beacon: %lu\n"
649 // "TX VI queue: %d\n"
650 // "TX VO queue: %d\n"
651 // "TX BE queue: %d\n"
652 // "TX BK queue: %d\n"
653 // "TX HW queue: %d\n"
654 // "TX VI dropped: %lu\n"
655 // "TX VO dropped: %lu\n"
656 // "TX BE dropped: %lu\n"
657 // "TX BK dropped: %lu\n"
658 "TX total data packets %lu\n"
659 "TX total data bytes :%lu\n",
660 // "TX beacon aborted: %lu\n",
661 priv->stats.txviokint,
662 // priv->stats.txvierr,
663 priv->stats.txvookint,
664 // priv->stats.txvoerr,
665 priv->stats.txbeokint,
666 // priv->stats.txbeerr,
667 priv->stats.txbkokint,
668 // priv->stats.txbkerr,
669 priv->stats.txmanageokint,
670 // priv->stats.txmanageerr,
671 priv->stats.txbeaconokint,
672 priv->stats.txbeaconerr,
673 priv->stats.txcmdpktokint,
674 // priv->stats.txhpokint,
675 // priv->stats.txhperr,
676 // priv->stats.txresumed,
677 netif_queue_stopped(dev),
678 priv->stats.txoverflow,
679 // priv->stats.txbeacon,
680 // atomic_read(&(priv->tx_pending[VI_QUEUE])),
681 // atomic_read(&(priv->tx_pending[VO_QUEUE])),
682 // atomic_read(&(priv->tx_pending[BE_QUEUE])),
683 // atomic_read(&(priv->tx_pending[BK_QUEUE])),
684 // read_nic_byte(dev, TXFIFOCOUNT),
685 // priv->stats.txvidrop,
686 // priv->stats.txvodrop,
687 priv->ieee80211->stats.tx_packets,
688 priv->ieee80211->stats.tx_bytes
691 // priv->stats.txbedrop,
692 // priv->stats.txbkdrop
693 // priv->stats.txdatapkt
694 // priv->stats.txbeaconerr
703 static int proc_get_stats_rx(char *page, char **start,
704 off_t offset, int count,
705 int *eof, void *data)
707 struct net_device *dev = data;
708 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
712 len += snprintf(page + len, count - len,
715 "RX rx overflow error: %lu\n"
716 "RX invalid urb error: %lu\n",
719 priv->stats.rxoverflow,
720 priv->stats.rxurberr);
726 static void rtl8192_proc_module_init(void)
728 RT_TRACE(COMP_INIT, "Initializing proc filesystem");
729 #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24))
730 rtl8192_proc=create_proc_entry(RTL819xE_MODULE_NAME, S_IFDIR, proc_net);
732 rtl8192_proc=create_proc_entry(RTL819xE_MODULE_NAME, S_IFDIR, init_net.proc_net);
737 static void rtl8192_proc_module_remove(void)
739 #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24))
740 remove_proc_entry(RTL819xE_MODULE_NAME, proc_net);
742 remove_proc_entry(RTL819xE_MODULE_NAME, init_net.proc_net);
747 static void rtl8192_proc_remove_one(struct net_device *dev)
749 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
751 printk("dev name=======> %s\n",dev->name);
754 // remove_proc_entry("stats-hw", priv->dir_dev);
755 remove_proc_entry("stats-tx", priv->dir_dev);
756 remove_proc_entry("stats-rx", priv->dir_dev);
757 // remove_proc_entry("stats-ieee", priv->dir_dev);
758 remove_proc_entry("stats-ap", priv->dir_dev);
759 remove_proc_entry("registers", priv->dir_dev);
760 // remove_proc_entry("cck-registers",priv->dir_dev);
761 // remove_proc_entry("ofdm-registers",priv->dir_dev);
762 //remove_proc_entry(dev->name, rtl8192_proc);
763 remove_proc_entry("wlan0", rtl8192_proc);
764 priv->dir_dev = NULL;
769 static void rtl8192_proc_init_one(struct net_device *dev)
771 struct proc_dir_entry *e;
772 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
773 priv->dir_dev = create_proc_entry(dev->name,
774 S_IFDIR | S_IRUGO | S_IXUGO,
776 if (!priv->dir_dev) {
777 RT_TRACE(COMP_ERR, "Unable to initialize /proc/net/rtl8192/%s\n",
782 e = create_proc_read_entry("stats-hw", S_IFREG | S_IRUGO,
783 priv->dir_dev, proc_get_stats_hw, dev);
786 DMESGE("Unable to initialize "
787 "/proc/net/rtl8192/%s/stats-hw\n",
791 e = create_proc_read_entry("stats-rx", S_IFREG | S_IRUGO,
792 priv->dir_dev, proc_get_stats_rx, dev);
795 RT_TRACE(COMP_ERR,"Unable to initialize "
796 "/proc/net/rtl8192/%s/stats-rx\n",
801 e = create_proc_read_entry("stats-tx", S_IFREG | S_IRUGO,
802 priv->dir_dev, proc_get_stats_tx, dev);
805 RT_TRACE(COMP_ERR, "Unable to initialize "
806 "/proc/net/rtl8192/%s/stats-tx\n",
810 e = create_proc_read_entry("stats-ieee", S_IFREG | S_IRUGO,
811 priv->dir_dev, proc_get_stats_ieee, dev);
814 DMESGE("Unable to initialize "
815 "/proc/net/rtl8192/%s/stats-ieee\n",
821 e = create_proc_read_entry("stats-ap", S_IFREG | S_IRUGO,
822 priv->dir_dev, proc_get_stats_ap, dev);
825 RT_TRACE(COMP_ERR, "Unable to initialize "
826 "/proc/net/rtl8192/%s/stats-ap\n",
830 e = create_proc_read_entry("registers", S_IFREG | S_IRUGO,
831 priv->dir_dev, proc_get_registers, dev);
833 RT_TRACE(COMP_ERR, "Unable to initialize "
834 "/proc/net/rtl8192/%s/registers\n",
838 e = create_proc_read_entry("cck-registers", S_IFREG | S_IRUGO,
839 priv->dir_dev, proc_get_cck_reg, dev);
841 RT_TRACE(COMP_ERR, "Unable to initialize "
842 "/proc/net/rtl8192/%s/cck-registers\n",
846 e = create_proc_read_entry("ofdm-registers", S_IFREG | S_IRUGO,
847 priv->dir_dev, proc_get_ofdm_reg, dev);
849 RT_TRACE(COMP_ERR, "Unable to initialize "
850 "/proc/net/rtl8192/%s/ofdm-registers\n",
855 /****************************************************************************
856 -----------------------------MISC STUFF-------------------------
857 *****************************************************************************/
859 short check_nic_enough_desc(struct net_device *dev, int prio)
861 struct r8192_priv *priv = ieee80211_priv(dev);
862 struct rtl8192_tx_ring *ring = &priv->tx_ring[prio];
864 /* for now we reserve two free descriptor as a safety boundary
865 * between the tail and the head
867 if (ring->entries - skb_queue_len(&ring->queue) >= 2) {
874 static void tx_timeout(struct net_device *dev)
876 struct r8192_priv *priv = ieee80211_priv(dev);
877 //rtl8192_commit(dev);
879 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
880 schedule_work(&priv->reset_wq);
882 schedule_task(&priv->reset_wq);
888 /****************************************************************************
889 ------------------------------HW STUFF---------------------------
890 *****************************************************************************/
893 static void rtl8192_irq_enable(struct net_device *dev)
895 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
896 priv->irq_enabled = 1;
897 write_nic_dword(dev,INTA_MASK, priv->irq_mask);
901 static void rtl8192_irq_disable(struct net_device *dev)
903 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
905 write_nic_dword(dev,INTA_MASK,0);
906 force_pci_posting(dev);
907 priv->irq_enabled = 0;
911 static void rtl8192_set_mode(struct net_device *dev,int mode)
914 ecmd=read_nic_byte(dev, EPROM_CMD);
915 ecmd=ecmd &~ EPROM_CMD_OPERATING_MODE_MASK;
916 ecmd=ecmd | (mode<<EPROM_CMD_OPERATING_MODE_SHIFT);
917 ecmd=ecmd &~ (1<<EPROM_CS_SHIFT);
918 ecmd=ecmd &~ (1<<EPROM_CK_SHIFT);
919 write_nic_byte(dev, EPROM_CMD, ecmd);
923 void rtl8192_update_msr(struct net_device *dev)
925 struct r8192_priv *priv = ieee80211_priv(dev);
928 msr = read_nic_byte(dev, MSR);
929 msr &= ~ MSR_LINK_MASK;
931 /* do not change in link_state != WLAN_LINK_ASSOCIATED.
932 * msr must be updated if the state is ASSOCIATING.
933 * this is intentional and make sense for ad-hoc and
934 * master (see the create BSS/IBSS func)
936 if (priv->ieee80211->state == IEEE80211_LINKED){
938 if (priv->ieee80211->iw_mode == IW_MODE_INFRA)
939 msr |= (MSR_LINK_MANAGED<<MSR_LINK_SHIFT);
940 else if (priv->ieee80211->iw_mode == IW_MODE_ADHOC)
941 msr |= (MSR_LINK_ADHOC<<MSR_LINK_SHIFT);
942 else if (priv->ieee80211->iw_mode == IW_MODE_MASTER)
943 msr |= (MSR_LINK_MASTER<<MSR_LINK_SHIFT);
946 msr |= (MSR_LINK_NONE<<MSR_LINK_SHIFT);
948 write_nic_byte(dev, MSR, msr);
951 void rtl8192_set_chan(struct net_device *dev,short ch)
953 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
954 RT_TRACE(COMP_RF, "=====>%s()====ch:%d\n", __FUNCTION__, ch);
957 if(priv->ieee80211->iw_mode == IW_MODE_ADHOC ||
958 priv->ieee80211->iw_mode == IW_MODE_MASTER){
960 priv->ieee80211->link_state = WLAN_LINK_ASSOCIATED;
961 priv->ieee80211->master_chan = ch;
962 rtl8192_update_beacon_ch(dev);
966 /* this hack should avoid frame TX during channel setting*/
969 // tx = read_nic_dword(dev,TX_CONF);
970 // tx &= ~TX_LOOPBACK_MASK;
974 // write_nic_dword(dev,TX_CONF, tx |( TX_LOOPBACK_MAC<<TX_LOOPBACK_SHIFT));
976 //need to implement rf set channel here WB
978 if (priv->rf_set_chan)
979 priv->rf_set_chan(dev,priv->chan);
981 // write_nic_dword(dev,TX_CONF,tx | (TX_LOOPBACK_NONE<<TX_LOOPBACK_SHIFT));
985 void rtl8192_rx_enable(struct net_device *dev)
987 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
988 write_nic_dword(dev, RDQDA,priv->rx_ring_dma);
991 /* the TX_DESC_BASE setting is according to the following queue index
1000 * BEACON_QUEUE ===> 8
1002 static u32 TX_DESC_BASE[] = {BKQDA, BEQDA, VIQDA, VOQDA, HCCAQDA, CQDA, MQDA, HQDA, BQDA};
1003 void rtl8192_tx_enable(struct net_device *dev)
1005 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1007 for (i = 0; i < MAX_TX_QUEUE_COUNT; i++)
1008 write_nic_dword(dev, TX_DESC_BASE[i], priv->tx_ring[i].dma);
1010 ieee80211_reset_queue(priv->ieee80211);
1014 void rtl8192_beacon_tx_enable(struct net_device *dev)
1016 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1019 reg = read_nic_dword(priv->ieee80211->dev,INTA_MASK);
1021 /* enable Beacon realted interrupt signal */
1022 reg |= (IMR_BcnInt | IMR_BcnInt | IMR_TBDOK | IMR_TBDER);
1023 write_nic_byte(dev,reg);
1027 static void rtl8192_free_rx_ring(struct net_device *dev)
1029 struct r8192_priv *priv = ieee80211_priv(dev);
1032 for (i = 0; i < priv->rxringcount; i++) {
1033 struct sk_buff *skb = priv->rx_buf[i];
1037 pci_unmap_single(priv->pdev,
1038 *((dma_addr_t *)skb->cb),
1039 priv->rxbuffersize, PCI_DMA_FROMDEVICE);
1043 pci_free_consistent(priv->pdev, sizeof(*priv->rx_ring) * priv->rxringcount,
1044 priv->rx_ring, priv->rx_ring_dma);
1045 priv->rx_ring = NULL;
1048 static void rtl8192_free_tx_ring(struct net_device *dev, unsigned int prio)
1050 struct r8192_priv *priv = ieee80211_priv(dev);
1051 struct rtl8192_tx_ring *ring = &priv->tx_ring[prio];
1053 while (skb_queue_len(&ring->queue)) {
1054 tx_desc_819x_pci *entry = &ring->desc[ring->idx];
1055 struct sk_buff *skb = __skb_dequeue(&ring->queue);
1057 pci_unmap_single(priv->pdev, le32_to_cpu(entry->TxBuffAddr),
1058 skb->len, PCI_DMA_TODEVICE);
1060 ring->idx = (ring->idx + 1) % ring->entries;
1063 pci_free_consistent(priv->pdev, sizeof(*ring->desc)*ring->entries,
1064 ring->desc, ring->dma);
1069 static void rtl8192_beacon_disable(struct net_device *dev)
1071 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1074 reg = read_nic_dword(priv->ieee80211->dev,INTA_MASK);
1076 /* disable Beacon realted interrupt signal */
1077 reg &= ~(IMR_BcnInt | IMR_BcnInt | IMR_TBDOK | IMR_TBDER);
1078 write_nic_dword(priv->ieee80211->dev, INTA_MASK, reg);
1081 void rtl8192_rtx_disable(struct net_device *dev)
1084 struct r8192_priv *priv = ieee80211_priv(dev);
1087 cmd=read_nic_byte(dev,CMDR);
1088 // if(!priv->ieee80211->bSupportRemoteWakeUp) {
1089 write_nic_byte(dev, CMDR, cmd &~ \
1092 force_pci_posting(dev);
1095 for(i = 0; i < MAX_QUEUE_SIZE; i++) {
1096 skb_queue_purge(&priv->ieee80211->skb_waitQ [i]);
1098 for(i = 0; i < MAX_QUEUE_SIZE; i++) {
1099 skb_queue_purge(&priv->ieee80211->skb_aggQ [i]);
1103 skb_queue_purge(&priv->skb_queue);
1107 static void rtl8192_reset(struct net_device *dev)
1109 rtl8192_irq_disable(dev);
1110 printk("This is RTL819xP Reset procedure\n");
1113 static u16 rtl_rate[] = {10,20,55,110,60,90,120,180,240,360,480,540};
1114 inline u16 rtl8192_rate2rate(short rate)
1116 if (rate >11) return 0;
1117 return rtl_rate[rate];
1123 void rtl8192_tx_queues_stop(struct net_device *dev)
1125 //struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1126 u8 dma_poll_mask = (1<<TX_DMA_STOP_LOWPRIORITY_SHIFT);
1127 dma_poll_mask |= (1<<TX_DMA_STOP_HIPRIORITY_SHIFT);
1128 dma_poll_mask |= (1<<TX_DMA_STOP_NORMPRIORITY_SHIFT);
1129 dma_poll_mask |= (1<<TX_DMA_STOP_BEACON_SHIFT);
1131 rtl8192_set_mode(dev,EPROM_CMD_CONFIG);
1132 write_nic_byte(dev,TX_DMA_POLLING,dma_poll_mask);
1133 rtl8192_set_mode(dev,EPROM_CMD_NORMAL);
1137 static void rtl8192_data_hard_stop(struct net_device *dev)
1141 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1142 priv->dma_poll_mask |= (1<<TX_DMA_STOP_LOWPRIORITY_SHIFT);
1143 rtl8192_set_mode(dev,EPROM_CMD_CONFIG);
1144 write_nic_byte(dev,TX_DMA_POLLING,priv->dma_poll_mask);
1145 rtl8192_set_mode(dev,EPROM_CMD_NORMAL);
1150 static void rtl8192_data_hard_resume(struct net_device *dev)
1154 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1155 priv->dma_poll_mask &= ~(1<<TX_DMA_STOP_LOWPRIORITY_SHIFT);
1156 rtl8192_set_mode(dev,EPROM_CMD_CONFIG);
1157 write_nic_byte(dev,TX_DMA_POLLING,priv->dma_poll_mask);
1158 rtl8192_set_mode(dev,EPROM_CMD_NORMAL);
1162 /* this function TX data frames when the ieee80211 stack requires this.
1163 * It checks also if we need to stop the ieee tx queue, eventually do it
1165 static void rtl8192_hard_data_xmit(struct sk_buff *skb, struct net_device *dev, int rate)
1167 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1169 //unsigned long flags;
1170 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1171 u8 queue_index = tcb_desc->queue_index;
1172 /* shall not be referred by command packet */
1173 assert(queue_index != TXCMD_QUEUE);
1175 //spin_lock_irqsave(&priv->tx_lock,flags);
1177 memcpy((unsigned char *)(skb->cb),&dev,sizeof(dev));
1179 tcb_desc->RATRIndex = 7;
1180 tcb_desc->bTxDisableRateFallBack = 1;
1181 tcb_desc->bTxUseDriverAssingedRate = 1;
1182 tcb_desc->bTxEnableFwCalcDur = 1;
1184 skb_push(skb, priv->ieee80211->tx_headroom);
1185 ret = rtl8192_tx(dev, skb);
1191 if(queue_index!=MGNT_QUEUE) {
1192 priv->ieee80211->stats.tx_bytes+=(skb->len - priv->ieee80211->tx_headroom);
1193 priv->ieee80211->stats.tx_packets++;
1196 //spin_unlock_irqrestore(&priv->tx_lock,flags);
1202 /* This is a rough attempt to TX a frame
1203 * This is called by the ieee 80211 stack to TX management frames.
1204 * If the ring is full packet are dropped (for data frame the queue
1205 * is stopped before this can happen).
1207 static int rtl8192_hard_start_xmit(struct sk_buff *skb,struct net_device *dev)
1209 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1213 //unsigned long flags;
1214 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1215 u8 queue_index = tcb_desc->queue_index;
1218 //spin_lock_irqsave(&priv->tx_lock,flags);
1220 memcpy((unsigned char *)(skb->cb),&dev,sizeof(dev));
1221 if(queue_index == TXCMD_QUEUE) {
1222 // skb_push(skb, USB_HWDESC_HEADER_LEN);
1223 rtl819xE_tx_cmd(dev, skb);
1225 //spin_unlock_irqrestore(&priv->tx_lock,flags);
1228 // RT_TRACE(COMP_SEND, "To send management packet\n");
1229 tcb_desc->RATRIndex = 7;
1230 tcb_desc->bTxDisableRateFallBack = 1;
1231 tcb_desc->bTxUseDriverAssingedRate = 1;
1232 tcb_desc->bTxEnableFwCalcDur = 1;
1233 skb_push(skb, priv->ieee80211->tx_headroom);
1234 ret = rtl8192_tx(dev, skb);
1240 // priv->ieee80211->stats.tx_bytes+=skb->len;
1241 // priv->ieee80211->stats.tx_packets++;
1243 //spin_unlock_irqrestore(&priv->tx_lock,flags);
1250 void rtl8192_try_wake_queue(struct net_device *dev, int pri);
1252 static void rtl8192_tx_isr(struct net_device *dev, int prio)
1254 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1256 struct rtl8192_tx_ring *ring = &priv->tx_ring[prio];
1258 while (skb_queue_len(&ring->queue)) {
1259 tx_desc_819x_pci *entry = &ring->desc[ring->idx];
1260 struct sk_buff *skb;
1262 /* beacon packet will only use the first descriptor defautly,
1263 * and the OWN may not be cleared by the hardware
1265 if(prio != BEACON_QUEUE) {
1268 ring->idx = (ring->idx + 1) % ring->entries;
1271 skb = __skb_dequeue(&ring->queue);
1272 pci_unmap_single(priv->pdev, le32_to_cpu(entry->TxBuffAddr),
1273 skb->len, PCI_DMA_TODEVICE);
1277 if (prio == MGNT_QUEUE){
1278 if (priv->ieee80211->ack_tx_to_ieee){
1279 if (rtl8192_is_tx_queue_empty(dev)){
1280 priv->ieee80211->ack_tx_to_ieee = 0;
1281 ieee80211_ps_tx_ack(priv->ieee80211, 1);
1286 if(prio != BEACON_QUEUE) {
1287 /* try to deal with the pending packets */
1288 tasklet_schedule(&priv->irq_tx_tasklet);
1293 static void rtl8192_stop_beacon(struct net_device *dev)
1295 //rtl8192_beacon_disable(dev);
1298 static void rtl8192_config_rate(struct net_device* dev, u16* rate_config)
1300 struct r8192_priv *priv = ieee80211_priv(dev);
1301 struct ieee80211_network *net;
1302 u8 i=0, basic_rate = 0;
1303 net = & priv->ieee80211->current_network;
1305 for (i=0; i<net->rates_len; i++)
1307 basic_rate = net->rates[i]&0x7f;
1310 case MGN_1M: *rate_config |= RRSR_1M; break;
1311 case MGN_2M: *rate_config |= RRSR_2M; break;
1312 case MGN_5_5M: *rate_config |= RRSR_5_5M; break;
1313 case MGN_11M: *rate_config |= RRSR_11M; break;
1314 case MGN_6M: *rate_config |= RRSR_6M; break;
1315 case MGN_9M: *rate_config |= RRSR_9M; break;
1316 case MGN_12M: *rate_config |= RRSR_12M; break;
1317 case MGN_18M: *rate_config |= RRSR_18M; break;
1318 case MGN_24M: *rate_config |= RRSR_24M; break;
1319 case MGN_36M: *rate_config |= RRSR_36M; break;
1320 case MGN_48M: *rate_config |= RRSR_48M; break;
1321 case MGN_54M: *rate_config |= RRSR_54M; break;
1324 for (i=0; i<net->rates_ex_len; i++)
1326 basic_rate = net->rates_ex[i]&0x7f;
1329 case MGN_1M: *rate_config |= RRSR_1M; break;
1330 case MGN_2M: *rate_config |= RRSR_2M; break;
1331 case MGN_5_5M: *rate_config |= RRSR_5_5M; break;
1332 case MGN_11M: *rate_config |= RRSR_11M; break;
1333 case MGN_6M: *rate_config |= RRSR_6M; break;
1334 case MGN_9M: *rate_config |= RRSR_9M; break;
1335 case MGN_12M: *rate_config |= RRSR_12M; break;
1336 case MGN_18M: *rate_config |= RRSR_18M; break;
1337 case MGN_24M: *rate_config |= RRSR_24M; break;
1338 case MGN_36M: *rate_config |= RRSR_36M; break;
1339 case MGN_48M: *rate_config |= RRSR_48M; break;
1340 case MGN_54M: *rate_config |= RRSR_54M; break;
1346 #define SHORT_SLOT_TIME 9
1347 #define NON_SHORT_SLOT_TIME 20
1349 static void rtl8192_update_cap(struct net_device* dev, u16 cap)
1352 struct r8192_priv *priv = ieee80211_priv(dev);
1353 struct ieee80211_network *net = &priv->ieee80211->current_network;
1354 priv->short_preamble = cap & WLAN_CAPABILITY_SHORT_PREAMBLE;
1355 tmp = priv->basic_rate;
1356 if (priv->short_preamble)
1357 tmp |= BRSR_AckShortPmb;
1358 write_nic_dword(dev, RRSR, tmp);
1360 if (net->mode & (IEEE_G|IEEE_N_24G))
1363 if ((cap & WLAN_CAPABILITY_SHORT_SLOT)&&(!priv->ieee80211->pHTInfo->bCurrentRT2RTLongSlotTime))
1365 slot_time = SHORT_SLOT_TIME;
1367 else //long slot time
1368 slot_time = NON_SHORT_SLOT_TIME;
1369 priv->slot_time = slot_time;
1370 write_nic_byte(dev, SLOT_TIME, slot_time);
1375 static void rtl8192_net_update(struct net_device *dev)
1378 struct r8192_priv *priv = ieee80211_priv(dev);
1379 struct ieee80211_network *net;
1380 u16 BcnTimeCfg = 0, BcnCW = 6, BcnIFS = 0xf;
1381 u16 rate_config = 0;
1382 net = &priv->ieee80211->current_network;
1383 //update Basic rate: RR, BRSR
1384 rtl8192_config_rate(dev, &rate_config);
1385 // 2007.01.16, by Emily
1386 // Select RRSR (in Legacy-OFDM and CCK)
1387 // For 8190, we select only 24M, 12M, 6M, 11M, 5.5M, 2M, and 1M from the Basic rate.
1388 // We do not use other rates.
1389 priv->basic_rate = rate_config &= 0x15f;
1391 write_nic_dword(dev,BSSIDR,((u32*)net->bssid)[0]);
1392 write_nic_word(dev,BSSIDR+4,((u16*)net->bssid)[2]);
1395 rtl8192_update_msr(dev);
1399 // rtl8192_update_cap(dev, net->capability);
1400 if (priv->ieee80211->iw_mode == IW_MODE_ADHOC)
1402 write_nic_word(dev, ATIMWND, 2);
1403 write_nic_word(dev, BCN_DMATIME, 256);
1404 write_nic_word(dev, BCN_INTERVAL, net->beacon_interval);
1405 // write_nic_word(dev, BcnIntTime, 100);
1406 //BIT15 of BCN_DRV_EARLY_INT will indicate whether software beacon or hw beacon is applied.
1407 write_nic_word(dev, BCN_DRV_EARLY_INT, 10);
1408 write_nic_byte(dev, BCN_ERR_THRESH, 100);
1410 BcnTimeCfg |= (BcnCW<<BCN_TCFG_CW_SHIFT);
1411 // TODO: BcnIFS may required to be changed on ASIC
1412 BcnTimeCfg |= BcnIFS<<BCN_TCFG_IFS;
1414 write_nic_word(dev, BCN_TCFG, BcnTimeCfg);
1420 void rtl819xE_tx_cmd(struct net_device *dev, struct sk_buff *skb)
1422 struct r8192_priv *priv = ieee80211_priv(dev);
1423 struct rtl8192_tx_ring *ring;
1424 tx_desc_819x_pci *entry;
1428 unsigned long flags;
1430 ring = &priv->tx_ring[TXCMD_QUEUE];
1431 mapping = pci_map_single(priv->pdev, skb->data, skb->len, PCI_DMA_TODEVICE);
1433 spin_lock_irqsave(&priv->irq_th_lock,flags);
1434 idx = (ring->idx + skb_queue_len(&ring->queue)) % ring->entries;
1435 entry = &ring->desc[idx];
1437 tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1439 entry->LINIP = tcb_desc->bLastIniPkt;
1440 entry->FirstSeg = 1;//first segment
1441 entry->LastSeg = 1; //last segment
1442 if(tcb_desc->bCmdOrInit == DESC_PACKET_TYPE_INIT) {
1443 entry->CmdInit = DESC_PACKET_TYPE_INIT;
1445 entry->CmdInit = DESC_PACKET_TYPE_NORMAL;
1446 entry->Offset = sizeof(TX_FWINFO_8190PCI) + 8;
1447 entry->PktSize = (u16)(tcb_desc->pkt_size + entry->Offset);
1448 entry->QueueSelect = QSLT_CMD;
1449 entry->TxFWInfoSize = 0x08;
1450 entry->RATid = (u8)DESC_PACKET_TYPE_INIT;
1452 entry->TxBufferSize = skb->len;
1453 entry->TxBuffAddr = cpu_to_le32(mapping);
1456 #ifdef JOHN_DUMP_TXDESC
1458 tx_desc_819x_pci *entry1 = &ring->desc[0];
1459 unsigned int *ptr= (unsigned int *)entry1;
1460 printk("<Tx descriptor>:\n");
1461 for (i = 0; i < 8; i++)
1462 printk("%8x ", ptr[i]);
1466 __skb_queue_tail(&ring->queue, skb);
1467 spin_unlock_irqrestore(&priv->irq_th_lock,flags);
1469 write_nic_byte(dev, TPPoll, TPPoll_CQ);
1475 * Mapping Software/Hardware descriptor queue id to "Queue Select Field"
1476 * in TxFwInfo data structure
1477 * 2006.10.30 by Emily
1479 * \param QUEUEID Software Queue
1481 static u8 MapHwQueueToFirmwareQueue(u8 QueueID)
1483 u8 QueueSelect = 0x0; //defualt set to
1487 QueueSelect = QSLT_BE; //or QSelect = pTcb->priority;
1491 QueueSelect = QSLT_BK; //or QSelect = pTcb->priority;
1495 QueueSelect = QSLT_VO; //or QSelect = pTcb->priority;
1499 QueueSelect = QSLT_VI; //or QSelect = pTcb->priority;
1502 QueueSelect = QSLT_MGNT;
1506 QueueSelect = QSLT_BEACON;
1509 // TODO: 2006.10.30 mark other queue selection until we verify it is OK
1510 // TODO: Remove Assertions
1511 //#if (RTL819X_FPGA_VER & RTL819X_FPGA_GUANGAN_070502)
1513 QueueSelect = QSLT_CMD;
1517 //QueueSelect = QSLT_HIGH;
1521 RT_TRACE(COMP_ERR, "TransmitTCB(): Impossible Queue Selection: %d \n", QueueID);
1527 static u8 MRateToHwRate8190Pci(u8 rate)
1529 u8 ret = DESC90_RATE1M;
1532 case MGN_1M: ret = DESC90_RATE1M; break;
1533 case MGN_2M: ret = DESC90_RATE2M; break;
1534 case MGN_5_5M: ret = DESC90_RATE5_5M; break;
1535 case MGN_11M: ret = DESC90_RATE11M; break;
1536 case MGN_6M: ret = DESC90_RATE6M; break;
1537 case MGN_9M: ret = DESC90_RATE9M; break;
1538 case MGN_12M: ret = DESC90_RATE12M; break;
1539 case MGN_18M: ret = DESC90_RATE18M; break;
1540 case MGN_24M: ret = DESC90_RATE24M; break;
1541 case MGN_36M: ret = DESC90_RATE36M; break;
1542 case MGN_48M: ret = DESC90_RATE48M; break;
1543 case MGN_54M: ret = DESC90_RATE54M; break;
1545 // HT rate since here
1546 case MGN_MCS0: ret = DESC90_RATEMCS0; break;
1547 case MGN_MCS1: ret = DESC90_RATEMCS1; break;
1548 case MGN_MCS2: ret = DESC90_RATEMCS2; break;
1549 case MGN_MCS3: ret = DESC90_RATEMCS3; break;
1550 case MGN_MCS4: ret = DESC90_RATEMCS4; break;
1551 case MGN_MCS5: ret = DESC90_RATEMCS5; break;
1552 case MGN_MCS6: ret = DESC90_RATEMCS6; break;
1553 case MGN_MCS7: ret = DESC90_RATEMCS7; break;
1554 case MGN_MCS8: ret = DESC90_RATEMCS8; break;
1555 case MGN_MCS9: ret = DESC90_RATEMCS9; break;
1556 case MGN_MCS10: ret = DESC90_RATEMCS10; break;
1557 case MGN_MCS11: ret = DESC90_RATEMCS11; break;
1558 case MGN_MCS12: ret = DESC90_RATEMCS12; break;
1559 case MGN_MCS13: ret = DESC90_RATEMCS13; break;
1560 case MGN_MCS14: ret = DESC90_RATEMCS14; break;
1561 case MGN_MCS15: ret = DESC90_RATEMCS15; break;
1562 case (0x80|0x20): ret = DESC90_RATEMCS32; break;
1570 static u8 QueryIsShort(u8 TxHT, u8 TxRate, cb_desc *tcb_desc)
1574 tmp_Short = (TxHT==1)?((tcb_desc->bUseShortGI)?1:0):((tcb_desc->bUseShortPreamble)?1:0);
1576 if(TxHT==1 && TxRate != DESC90_RATEMCS15)
1583 * The tx procedure is just as following,
1584 * skb->cb will contain all the following information,
1585 * priority, morefrag, rate, &dev.
1587 short rtl8192_tx(struct net_device *dev, struct sk_buff* skb)
1589 struct r8192_priv *priv = ieee80211_priv(dev);
1590 struct rtl8192_tx_ring *ring;
1591 unsigned long flags;
1592 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1593 tx_desc_819x_pci *pdesc = NULL;
1594 TX_FWINFO_8190PCI *pTxFwInfo = NULL;
1596 bool multi_addr=false,broad_addr=false,uni_addr=false;
1597 u8* pda_addr = NULL;
1600 mapping = pci_map_single(priv->pdev, skb->data, skb->len, PCI_DMA_TODEVICE);
1601 /* collect the tx packets statitcs */
1602 pda_addr = ((u8*)skb->data) + sizeof(TX_FWINFO_8190PCI);
1603 if(is_multicast_ether_addr(pda_addr))
1605 else if(is_broadcast_ether_addr(pda_addr))
1611 priv->stats.txbytesunicast += (u8)(skb->len) - sizeof(TX_FWINFO_8190PCI);
1613 priv->stats.txbytesmulticast +=(u8)(skb->len) - sizeof(TX_FWINFO_8190PCI);
1615 priv->stats.txbytesbroadcast += (u8)(skb->len) - sizeof(TX_FWINFO_8190PCI);
1617 /* fill tx firmware */
1618 pTxFwInfo = (PTX_FWINFO_8190PCI)skb->data;
1619 memset(pTxFwInfo,0,sizeof(TX_FWINFO_8190PCI));
1620 pTxFwInfo->TxHT = (tcb_desc->data_rate&0x80)?1:0;
1621 pTxFwInfo->TxRate = MRateToHwRate8190Pci((u8)tcb_desc->data_rate);
1622 pTxFwInfo->EnableCPUDur = tcb_desc->bTxEnableFwCalcDur;
1623 pTxFwInfo->Short = QueryIsShort(pTxFwInfo->TxHT, pTxFwInfo->TxRate, tcb_desc);
1625 /* Aggregation related */
1626 if(tcb_desc->bAMPDUEnable) {
1627 pTxFwInfo->AllowAggregation = 1;
1628 pTxFwInfo->RxMF = tcb_desc->ampdu_factor;
1629 pTxFwInfo->RxAMD = tcb_desc->ampdu_density;
1631 pTxFwInfo->AllowAggregation = 0;
1632 pTxFwInfo->RxMF = 0;
1633 pTxFwInfo->RxAMD = 0;
1637 // Protection mode related
1639 pTxFwInfo->RtsEnable = (tcb_desc->bRTSEnable)?1:0;
1640 pTxFwInfo->CtsEnable = (tcb_desc->bCTSEnable)?1:0;
1641 pTxFwInfo->RtsSTBC = (tcb_desc->bRTSSTBC)?1:0;
1642 pTxFwInfo->RtsHT= (tcb_desc->rts_rate&0x80)?1:0;
1643 pTxFwInfo->RtsRate = MRateToHwRate8190Pci((u8)tcb_desc->rts_rate);
1644 pTxFwInfo->RtsBandwidth = 0;
1645 pTxFwInfo->RtsSubcarrier = tcb_desc->RTSSC;
1646 pTxFwInfo->RtsShort = (pTxFwInfo->RtsHT==0)?(tcb_desc->bRTSUseShortPreamble?1:0):(tcb_desc->bRTSUseShortGI?1:0);
1648 // Set Bandwidth and sub-channel settings.
1650 if(priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20_40)
1652 if(tcb_desc->bPacketBW)
1654 pTxFwInfo->TxBandwidth = 1;
1656 pTxFwInfo->TxSubCarrier = 3;
1658 pTxFwInfo->TxSubCarrier = 0; //By SD3's Jerry suggestion, use duplicated mode, cosa 04012008
1663 pTxFwInfo->TxBandwidth = 0;
1664 pTxFwInfo->TxSubCarrier = priv->nCur40MhzPrimeSC;
1667 pTxFwInfo->TxBandwidth = 0;
1668 pTxFwInfo->TxSubCarrier = 0;
1673 /* 2007/07/25 MH Copy current TX FW info.*/
1674 memcpy((void*)(&Tmp_TxFwInfo), (void*)(pTxFwInfo), sizeof(TX_FWINFO_8190PCI));
1675 printk("&&&&&&&&&&&&&&&&&&&&&&====>print out fwinf\n");
1676 printk("===>enable fwcacl:%d\n", Tmp_TxFwInfo.EnableCPUDur);
1677 printk("===>RTS STBC:%d\n", Tmp_TxFwInfo.RtsSTBC);
1678 printk("===>RTS Subcarrier:%d\n", Tmp_TxFwInfo.RtsSubcarrier);
1679 printk("===>Allow Aggregation:%d\n", Tmp_TxFwInfo.AllowAggregation);
1680 printk("===>TX HT bit:%d\n", Tmp_TxFwInfo.TxHT);
1681 printk("===>Tx rate:%d\n", Tmp_TxFwInfo.TxRate);
1682 printk("===>Received AMPDU Density:%d\n", Tmp_TxFwInfo.RxAMD);
1683 printk("===>Received MPDU Factor:%d\n", Tmp_TxFwInfo.RxMF);
1684 printk("===>TxBandwidth:%d\n", Tmp_TxFwInfo.TxBandwidth);
1685 printk("===>TxSubCarrier:%d\n", Tmp_TxFwInfo.TxSubCarrier);
1687 printk("<=====**********************out of print\n");
1690 spin_lock_irqsave(&priv->irq_th_lock,flags);
1691 ring = &priv->tx_ring[tcb_desc->queue_index];
1692 if (tcb_desc->queue_index != BEACON_QUEUE) {
1693 idx = (ring->idx + skb_queue_len(&ring->queue)) % ring->entries;
1698 pdesc = &ring->desc[idx];
1699 if((pdesc->OWN == 1) && (tcb_desc->queue_index != BEACON_QUEUE)) {
1700 RT_TRACE(COMP_ERR,"No more TX desc@%d, ring->idx = %d,idx = %d,%x", \
1701 tcb_desc->queue_index,ring->idx, idx,skb->len);
1705 /* fill tx descriptor */
1706 memset((u8*)pdesc,0,12);
1710 pdesc->Offset = sizeof(TX_FWINFO_8190PCI) + 8; //We must add 8!! Emily
1711 pdesc->PktSize = (u16)skb->len-sizeof(TX_FWINFO_8190PCI);
1715 pdesc->RATid = tcb_desc->RATRIndex;
1719 pdesc->SecType = 0x0;
1720 if (tcb_desc->bHwSec) {
1723 printk("==>================hw sec\n");
1726 switch (priv->ieee80211->pairwise_key_type) {
1727 case KEY_TYPE_WEP40:
1728 case KEY_TYPE_WEP104:
1729 pdesc->SecType = 0x1;
1733 pdesc->SecType = 0x2;
1737 pdesc->SecType = 0x3;
1741 pdesc->SecType = 0x0;
1752 pdesc->QueueSelect = MapHwQueueToFirmwareQueue(tcb_desc->queue_index);
1753 pdesc->TxFWInfoSize = sizeof(TX_FWINFO_8190PCI);
1755 pdesc->DISFB = tcb_desc->bTxDisableRateFallBack;
1756 pdesc->USERATE = tcb_desc->bTxUseDriverAssingedRate;
1760 pdesc->TxBufferSize = skb->len;
1762 pdesc->TxBuffAddr = cpu_to_le32(mapping);
1763 __skb_queue_tail(&ring->queue, skb);
1765 spin_unlock_irqrestore(&priv->irq_th_lock,flags);
1766 dev->trans_start = jiffies;
1767 write_nic_word(dev,TPPoll,0x01<<tcb_desc->queue_index);
1771 static short rtl8192_alloc_rx_desc_ring(struct net_device *dev)
1773 struct r8192_priv *priv = ieee80211_priv(dev);
1774 rx_desc_819x_pci *entry = NULL;
1777 priv->rx_ring = pci_alloc_consistent(priv->pdev,
1778 sizeof(*priv->rx_ring) * priv->rxringcount, &priv->rx_ring_dma);
1780 if (!priv->rx_ring || (unsigned long)priv->rx_ring & 0xFF) {
1781 RT_TRACE(COMP_ERR,"Cannot allocate RX ring\n");
1785 memset(priv->rx_ring, 0, sizeof(*priv->rx_ring) * priv->rxringcount);
1788 for (i = 0; i < priv->rxringcount; i++) {
1789 struct sk_buff *skb = dev_alloc_skb(priv->rxbuffersize);
1790 dma_addr_t *mapping;
1791 entry = &priv->rx_ring[i];
1794 priv->rx_buf[i] = skb;
1795 mapping = (dma_addr_t *)skb->cb;
1796 *mapping = pci_map_single(priv->pdev, skb->tail,//skb_tail_pointer(skb),
1797 priv->rxbuffersize, PCI_DMA_FROMDEVICE);
1799 entry->BufferAddress = cpu_to_le32(*mapping);
1801 entry->Length = priv->rxbuffersize;
1809 static int rtl8192_alloc_tx_desc_ring(struct net_device *dev,
1810 unsigned int prio, unsigned int entries)
1812 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1813 tx_desc_819x_pci *ring;
1817 ring = pci_alloc_consistent(priv->pdev, sizeof(*ring) * entries, &dma);
1818 if (!ring || (unsigned long)ring & 0xFF) {
1819 RT_TRACE(COMP_ERR, "Cannot allocate TX ring (prio = %d)\n", prio);
1823 memset(ring, 0, sizeof(*ring)*entries);
1824 priv->tx_ring[prio].desc = ring;
1825 priv->tx_ring[prio].dma = dma;
1826 priv->tx_ring[prio].idx = 0;
1827 priv->tx_ring[prio].entries = entries;
1828 skb_queue_head_init(&priv->tx_ring[prio].queue);
1830 for (i = 0; i < entries; i++)
1831 ring[i].NextDescAddress =
1832 cpu_to_le32((u32)dma + ((i + 1) % entries) * sizeof(*ring));
1838 static short rtl8192_pci_initdescring(struct net_device *dev)
1842 struct r8192_priv *priv = ieee80211_priv(dev);
1844 ret = rtl8192_alloc_rx_desc_ring(dev);
1850 /* general process for other queue */
1851 for (i = 0; i < MAX_TX_QUEUE_COUNT; i++) {
1852 if ((ret = rtl8192_alloc_tx_desc_ring(dev, i, priv->txringcount)))
1853 goto err_free_rings;
1857 /* specific process for hardware beacon process */
1858 if ((ret = rtl8192_alloc_tx_desc_ring(dev, MAX_TX_QUEUE_COUNT - 1, 2)))
1859 goto err_free_rings;
1865 rtl8192_free_rx_ring(dev);
1866 for (i = 0; i < MAX_TX_QUEUE_COUNT; i++)
1867 if (priv->tx_ring[i].desc)
1868 rtl8192_free_tx_ring(dev, i);
1872 static void rtl8192_pci_resetdescring(struct net_device *dev)
1874 struct r8192_priv *priv = ieee80211_priv(dev);
1877 /* force the rx_idx to the first one */
1879 rx_desc_819x_pci *entry = NULL;
1880 for (i = 0; i < priv->rxringcount; i++) {
1881 entry = &priv->rx_ring[i];
1887 /* after reset, release previous pending packet, and force the
1888 * tx idx to the first one */
1889 for (i = 0; i < MAX_TX_QUEUE_COUNT; i++) {
1890 if (priv->tx_ring[i].desc) {
1891 struct rtl8192_tx_ring *ring = &priv->tx_ring[i];
1893 while (skb_queue_len(&ring->queue)) {
1894 tx_desc_819x_pci *entry = &ring->desc[ring->idx];
1895 struct sk_buff *skb = __skb_dequeue(&ring->queue);
1897 pci_unmap_single(priv->pdev, le32_to_cpu(entry->TxBuffAddr),
1898 skb->len, PCI_DMA_TODEVICE);
1900 ring->idx = (ring->idx + 1) % ring->entries;
1908 extern void rtl8192_update_ratr_table(struct net_device* dev);
1909 static void rtl8192_link_change(struct net_device *dev)
1913 struct r8192_priv *priv = ieee80211_priv(dev);
1914 struct ieee80211_device* ieee = priv->ieee80211;
1915 //write_nic_word(dev, BCN_INTR_ITV, net->beacon_interval);
1916 if (ieee->state == IEEE80211_LINKED)
1918 rtl8192_net_update(dev);
1919 rtl8192_update_ratr_table(dev);
1921 //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
1922 if ((KEY_TYPE_WEP40 == ieee->pairwise_key_type) || (KEY_TYPE_WEP104 == ieee->pairwise_key_type))
1923 EnableHWSecurityConfig8192(dev);
1928 write_nic_byte(dev, 0x173, 0);
1930 /*update timing params*/
1931 //rtl8192_set_chan(dev, priv->chan);
1933 rtl8192_update_msr(dev);
1935 // 2007/10/16 MH MAC Will update TSF according to all received beacon, so we have
1936 // // To set CBSSID bit when link with any AP or STA.
1937 if (ieee->iw_mode == IW_MODE_INFRA || ieee->iw_mode == IW_MODE_ADHOC)
1940 reg = read_nic_dword(dev, RCR);
1941 if (priv->ieee80211->state == IEEE80211_LINKED)
1942 priv->ReceiveConfig = reg |= RCR_CBSSID;
1944 priv->ReceiveConfig = reg &= ~RCR_CBSSID;
1945 write_nic_dword(dev, RCR, reg);
1951 static struct ieee80211_qos_parameters def_qos_parameters = {
1952 {3,3,3,3},/* cw_min */
1953 {7,7,7,7},/* cw_max */
1954 {2,2,2,2},/* aifs */
1955 {0,0,0,0},/* flags */
1956 {0,0,0,0} /* tx_op_limit */
1959 #if LINUX_VERSION_CODE >=KERNEL_VERSION(2,6,20)
1960 static void rtl8192_update_beacon(struct work_struct * work)
1962 struct r8192_priv *priv = container_of(work, struct r8192_priv, update_beacon_wq.work);
1963 struct net_device *dev = priv->ieee80211->dev;
1965 void rtl8192_update_beacon(struct net_device *dev)
1967 struct r8192_priv *priv = ieee80211_priv(dev);
1969 struct ieee80211_device* ieee = priv->ieee80211;
1970 struct ieee80211_network* net = &ieee->current_network;
1972 if (ieee->pHTInfo->bCurrentHTSupport)
1973 HTUpdateSelfAndPeerSetting(ieee, net);
1974 ieee->pHTInfo->bCurrentRT2RTLongSlotTime = net->bssht.bdRT2RTLongSlotTime;
1975 rtl8192_update_cap(dev, net->capability);
1978 * background support to run QoS activate functionality
1980 static int WDCAPARA_ADD[] = {EDCAPARA_BE,EDCAPARA_BK,EDCAPARA_VI,EDCAPARA_VO};
1981 #if LINUX_VERSION_CODE >=KERNEL_VERSION(2,6,20)
1982 static void rtl8192_qos_activate(struct work_struct * work)
1984 struct r8192_priv *priv = container_of(work, struct r8192_priv, qos_activate);
1985 struct net_device *dev = priv->ieee80211->dev;
1987 void rtl8192_qos_activate(struct net_device *dev)
1989 struct r8192_priv *priv = ieee80211_priv(dev);
1991 struct ieee80211_qos_parameters *qos_parameters = &priv->ieee80211->current_network.qos_data.parameters;
1992 u8 mode = priv->ieee80211->current_network.mode;
1993 // u32 size = sizeof(struct ieee80211_qos_parameters);
2000 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16))
2003 mutex_lock(&priv->mutex);
2005 if(priv->ieee80211->state != IEEE80211_LINKED)
2007 RT_TRACE(COMP_QOS,"qos active process with associate response received\n");
2008 /* It better set slot time at first */
2009 /* For we just support b/g mode at present, let the slot time at 9/20 selection */
2010 /* update the ac parameter to related registers */
2011 for(i = 0; i < QOS_QUEUE_NUM; i++) {
2012 //Mode G/A: slotTimeTimer = 9; Mode B: 20
2013 u1bAIFS = qos_parameters->aifs[i] * ((mode&(IEEE_G|IEEE_N_24G)) ?9:20) + aSifsTime;
2014 u4bAcParam = ((((u32)(qos_parameters->tx_op_limit[i]))<< AC_PARAM_TXOP_LIMIT_OFFSET)|
2015 (((u32)(qos_parameters->cw_max[i]))<< AC_PARAM_ECW_MAX_OFFSET)|
2016 (((u32)(qos_parameters->cw_min[i]))<< AC_PARAM_ECW_MIN_OFFSET)|
2017 ((u32)u1bAIFS << AC_PARAM_AIFS_OFFSET));
2018 printk("===>u4bAcParam:%x, ", u4bAcParam);
2019 write_nic_dword(dev, WDCAPARA_ADD[i], u4bAcParam);
2020 //write_nic_dword(dev, WDCAPARA_ADD[i], 0x005e4332);
2024 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16))
2027 mutex_unlock(&priv->mutex);
2031 static int rtl8192_qos_handle_probe_response(struct r8192_priv *priv,
2033 struct ieee80211_network *network)
2036 u32 size = sizeof(struct ieee80211_qos_parameters);
2038 if(priv->ieee80211->state !=IEEE80211_LINKED)
2041 if ((priv->ieee80211->iw_mode != IW_MODE_INFRA))
2044 if (network->flags & NETWORK_HAS_QOS_MASK) {
2045 if (active_network &&
2046 (network->flags & NETWORK_HAS_QOS_PARAMETERS))
2047 network->qos_data.active = network->qos_data.supported;
2049 if ((network->qos_data.active == 1) && (active_network == 1) &&
2050 (network->flags & NETWORK_HAS_QOS_PARAMETERS) &&
2051 (network->qos_data.old_param_count !=
2052 network->qos_data.param_count)) {
2053 network->qos_data.old_param_count =
2054 network->qos_data.param_count;
2055 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
2056 queue_work(priv->priv_wq, &priv->qos_activate);
2058 schedule_task(&priv->qos_activate);
2060 RT_TRACE (COMP_QOS, "QoS parameters change call "
2064 memcpy(&priv->ieee80211->current_network.qos_data.parameters,\
2065 &def_qos_parameters, size);
2067 if ((network->qos_data.active == 1) && (active_network == 1)) {
2068 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
2069 queue_work(priv->priv_wq, &priv->qos_activate);
2071 schedule_task(&priv->qos_activate);
2073 RT_TRACE(COMP_QOS, "QoS was disabled call qos_activate \n");
2075 network->qos_data.active = 0;
2076 network->qos_data.supported = 0;
2082 /* handle manage frame frame beacon and probe response */
2083 static int rtl8192_handle_beacon(struct net_device * dev,
2084 struct ieee80211_beacon * beacon,
2085 struct ieee80211_network * network)
2087 struct r8192_priv *priv = ieee80211_priv(dev);
2089 rtl8192_qos_handle_probe_response(priv,1,network);
2091 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
2092 queue_delayed_work(priv->priv_wq, &priv->update_beacon_wq, 0);
2094 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
2095 schedule_task(&priv->update_beacon_wq);
2097 queue_work(priv->priv_wq, &priv->update_beacon_wq);
2105 * handling the beaconing responses. if we get different QoS setting
2106 * off the network from the associated setting, adjust the QoS
2109 static int rtl8192_qos_association_resp(struct r8192_priv *priv,
2110 struct ieee80211_network *network)
2113 unsigned long flags;
2114 u32 size = sizeof(struct ieee80211_qos_parameters);
2115 int set_qos_param = 0;
2117 if ((priv == NULL) || (network == NULL))
2120 if(priv->ieee80211->state !=IEEE80211_LINKED)
2123 if ((priv->ieee80211->iw_mode != IW_MODE_INFRA))
2126 spin_lock_irqsave(&priv->ieee80211->lock, flags);
2127 if(network->flags & NETWORK_HAS_QOS_PARAMETERS) {
2128 memcpy(&priv->ieee80211->current_network.qos_data.parameters,\
2129 &network->qos_data.parameters,\
2130 sizeof(struct ieee80211_qos_parameters));
2131 priv->ieee80211->current_network.qos_data.active = 1;
2133 if((priv->ieee80211->current_network.qos_data.param_count != \
2134 network->qos_data.param_count))
2138 /* update qos parameter for current network */
2139 priv->ieee80211->current_network.qos_data.old_param_count = \
2140 priv->ieee80211->current_network.qos_data.param_count;
2141 priv->ieee80211->current_network.qos_data.param_count = \
2142 network->qos_data.param_count;
2145 memcpy(&priv->ieee80211->current_network.qos_data.parameters,\
2146 &def_qos_parameters, size);
2147 priv->ieee80211->current_network.qos_data.active = 0;
2148 priv->ieee80211->current_network.qos_data.supported = 0;
2152 spin_unlock_irqrestore(&priv->ieee80211->lock, flags);
2154 RT_TRACE(COMP_QOS, "%s: network->flags = %d,%d\n",__FUNCTION__,network->flags ,priv->ieee80211->current_network.qos_data.active);
2155 if (set_qos_param == 1)
2156 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
2157 queue_work(priv->priv_wq, &priv->qos_activate);
2159 schedule_task(&priv->qos_activate);
2167 static int rtl8192_handle_assoc_response(struct net_device *dev,
2168 struct ieee80211_assoc_response_frame *resp,
2169 struct ieee80211_network *network)
2171 struct r8192_priv *priv = ieee80211_priv(dev);
2172 rtl8192_qos_association_resp(priv, network);
2177 //updateRATRTabel for MCS only. Basic rate is not implement.
2178 void rtl8192_update_ratr_table(struct net_device* dev)
2179 // POCTET_STRING posLegacyRate,
2181 // PRT_WLAN_STA pEntry)
2183 struct r8192_priv* priv = ieee80211_priv(dev);
2184 struct ieee80211_device* ieee = priv->ieee80211;
2185 u8* pMcsRate = ieee->dot11HTOperationalRateSet;
2186 //struct ieee80211_network *net = &ieee->current_network;
2190 rtl8192_config_rate(dev, (u16*)(&ratr_value));
2191 ratr_value |= (*(u16*)(pMcsRate)) << 12;
2192 // switch (net->mode)
2196 ratr_value &= 0x00000FF0;
2199 ratr_value &= 0x0000000F;
2202 ratr_value &= 0x00000FF7;
2206 if (ieee->pHTInfo->PeerMimoPs == 0) //MIMO_PS_STATIC
2207 ratr_value &= 0x0007F007;
2209 if (priv->rf_type == RF_1T2R)
2210 ratr_value &= 0x000FF007;
2212 ratr_value &= 0x0F81F007;
2218 ratr_value &= 0x0FFFFFFF;
2219 if(ieee->pHTInfo->bCurTxBW40MHz && ieee->pHTInfo->bCurShortGI40MHz){
2220 ratr_value |= 0x80000000;
2221 }else if(!ieee->pHTInfo->bCurTxBW40MHz && ieee->pHTInfo->bCurShortGI20MHz){
2222 ratr_value |= 0x80000000;
2224 write_nic_dword(dev, RATR0+rate_index*4, ratr_value);
2225 write_nic_byte(dev, UFWP, 1);
2228 static u8 ccmp_ie[4] = {0x00,0x50,0xf2,0x04};
2229 static u8 ccmp_rsn_ie[4] = {0x00, 0x0f, 0xac, 0x04};
2230 static bool GetNmodeSupportBySecCfg8190Pci(struct net_device*dev)
2233 struct r8192_priv* priv = ieee80211_priv(dev);
2234 struct ieee80211_device* ieee = priv->ieee80211;
2235 int wpa_ie_len= ieee->wpa_ie_len;
2236 struct ieee80211_crypt_data* crypt;
2239 crypt = ieee->crypt[ieee->tx_keyidx];
2240 encrypt = (ieee->current_network.capability & WLAN_CAPABILITY_PRIVACY) || (ieee->host_encrypt && crypt && crypt->ops && (0 == strcmp(crypt->ops->name,"WEP")));
2243 if(encrypt && (wpa_ie_len == 0)) {
2244 /* wep encryption, no N mode setting */
2246 // } else if((wpa_ie_len != 0)&&(memcmp(&(ieee->wpa_ie[14]),ccmp_ie,4))) {
2247 } else if((wpa_ie_len != 0)) {
2248 /* parse pairwise key type */
2249 //if((pairwisekey = WEP40)||(pairwisekey = WEP104)||(pairwisekey = TKIP))
2250 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))))
2255 //RT_TRACE(COMP_ERR,"In %s The GroupEncAlgorithm is [4]\n",__FUNCTION__ );
2260 //In here we discuss with SD4 David. He think we still can send TKIP in broadcast group key in MCS rate.
2261 //We can't force in G mode if Pairwie key is AES and group key is TKIP
2262 if((pSecInfo->GroupEncAlgorithm == WEP104_Encryption) || (pSecInfo->GroupEncAlgorithm == WEP40_Encryption) ||
2263 (pSecInfo->PairwiseEncAlgorithm == WEP104_Encryption) ||
2264 (pSecInfo->PairwiseEncAlgorithm == WEP40_Encryption) || (pSecInfo->PairwiseEncAlgorithm == TKIP_Encryption))
2275 static void rtl8192_refresh_supportrate(struct r8192_priv* priv)
2277 struct ieee80211_device* ieee = priv->ieee80211;
2278 //we donot consider set support rate for ABG mode, only HT MCS rate is set here.
2279 if (ieee->mode == WIRELESS_MODE_N_24G || ieee->mode == WIRELESS_MODE_N_5G)
2281 memcpy(ieee->Regdot11HTOperationalRateSet, ieee->RegHTSuppRateSet, 16);
2282 //RT_DEBUG_DATA(COMP_INIT, ieee->RegHTSuppRateSet, 16);
2283 //RT_DEBUG_DATA(COMP_INIT, ieee->Regdot11HTOperationalRateSet, 16);
2286 memset(ieee->Regdot11HTOperationalRateSet, 0, 16);
2290 static u8 rtl8192_getSupportedWireleeMode(struct net_device*dev)
2292 struct r8192_priv *priv = ieee80211_priv(dev);
2294 switch(priv->rf_chip)
2299 ret = (WIRELESS_MODE_N_24G|WIRELESS_MODE_G|WIRELESS_MODE_B);
2302 ret = (WIRELESS_MODE_A|WIRELESS_MODE_N_5G);
2305 ret = WIRELESS_MODE_B;
2311 static void rtl8192_SetWirelessMode(struct net_device* dev, u8 wireless_mode)
2313 struct r8192_priv *priv = ieee80211_priv(dev);
2314 u8 bSupportMode = rtl8192_getSupportedWireleeMode(dev);
2317 if ((wireless_mode == WIRELESS_MODE_AUTO) || ((wireless_mode&bSupportMode)==0))
2319 if(bSupportMode & WIRELESS_MODE_N_24G)
2321 wireless_mode = WIRELESS_MODE_N_24G;
2323 else if(bSupportMode & WIRELESS_MODE_N_5G)
2325 wireless_mode = WIRELESS_MODE_N_5G;
2327 else if((bSupportMode & WIRELESS_MODE_A))
2329 wireless_mode = WIRELESS_MODE_A;
2331 else if((bSupportMode & WIRELESS_MODE_G))
2333 wireless_mode = WIRELESS_MODE_G;
2335 else if((bSupportMode & WIRELESS_MODE_B))
2337 wireless_mode = WIRELESS_MODE_B;
2340 RT_TRACE(COMP_ERR, "%s(), No valid wireless mode supported, SupportedWirelessMode(%x)!!!\n", __FUNCTION__,bSupportMode);
2341 wireless_mode = WIRELESS_MODE_B;
2344 #ifdef TO_DO_LIST //// TODO: this function doesn't work well at this time, we shoud wait for FPGA
2345 ActUpdateChannelAccessSetting( pAdapter, pHalData->CurrentWirelessMode, &pAdapter->MgntInfo.Info8185.ChannelAccessSetting );
2347 priv->ieee80211->mode = wireless_mode;
2349 if ((wireless_mode == WIRELESS_MODE_N_24G) || (wireless_mode == WIRELESS_MODE_N_5G))
2350 priv->ieee80211->pHTInfo->bEnableHT = 1;
2352 priv->ieee80211->pHTInfo->bEnableHT = 0;
2353 RT_TRACE(COMP_INIT, "Current Wireless Mode is %x\n", wireless_mode);
2354 rtl8192_refresh_supportrate(priv);
2358 //init priv variables here
2360 static bool GetHalfNmodeSupportByAPs819xPci(struct net_device* dev)
2363 struct r8192_priv* priv = ieee80211_priv(dev);
2364 struct ieee80211_device* ieee = priv->ieee80211;
2366 if(ieee->bHalfWirelessN24GMode == true)
2374 short rtl8192_is_tx_queue_empty(struct net_device *dev)
2377 struct r8192_priv *priv = ieee80211_priv(dev);
2378 for (i=0; i<=MGNT_QUEUE; i++)
2380 if ((i== TXCMD_QUEUE) || (i == HCCA_QUEUE) )
2382 if (skb_queue_len(&(&priv->tx_ring[i])->queue) > 0){
2383 printk("===>tx queue is not empty:%d, %d\n", i, skb_queue_len(&(&priv->tx_ring[i])->queue));
2390 void rtl8192_rq_tx_ack(struct net_device *dev)
2392 struct r8192_priv *priv = ieee80211_priv(dev);
2393 priv->ieee80211->ack_tx_to_ieee = 1;
2396 static void rtl8192_hw_sleep_down(struct net_device *dev)
2398 RT_TRACE(COMP_POWER, "%s()============>come to sleep down\n", __FUNCTION__);
2399 MgntActSet_RF_State(dev, eRfSleep, RF_CHANGE_BY_PS);
2401 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
2402 static void rtl8192_hw_sleep_wq (struct work_struct *work)
2404 // struct r8180_priv *priv = container_of(work, struct r8180_priv, watch_dog_wq);
2405 // struct ieee80211_device * ieee = (struct ieee80211_device*)
2406 // container_of(work, struct ieee80211_device, watch_dog_wq);
2407 struct delayed_work *dwork = container_of(work,struct delayed_work,work);
2408 struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,hw_sleep_wq);
2409 struct net_device *dev = ieee->dev;
2411 void rtl8192_hw_sleep_wq(struct net_device* dev)
2414 //printk("=========>%s()\n", __FUNCTION__);
2415 rtl8192_hw_sleep_down(dev);
2417 // printk("dev is %d\n",dev);
2418 // printk("&*&(^*(&(&=========>%s()\n", __FUNCTION__);
2419 static void rtl8192_hw_wakeup(struct net_device* dev)
2423 // spin_lock_irqsave(&priv->ps_lock,flags);
2424 RT_TRACE(COMP_POWER, "%s()============>come to wake up\n", __FUNCTION__);
2425 MgntActSet_RF_State(dev, eRfOn, RF_CHANGE_BY_PS);
2426 //FIXME: will we send package stored while nic is sleep?
2427 // spin_unlock_irqrestore(&priv->ps_lock,flags);
2429 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
2430 void rtl8192_hw_wakeup_wq (struct work_struct *work)
2432 // struct r8180_priv *priv = container_of(work, struct r8180_priv, watch_dog_wq);
2433 // struct ieee80211_device * ieee = (struct ieee80211_device*)
2434 // container_of(work, struct ieee80211_device, watch_dog_wq);
2435 struct delayed_work *dwork = container_of(work,struct delayed_work,work);
2436 struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,hw_wakeup_wq);
2437 struct net_device *dev = ieee->dev;
2439 void rtl8192_hw_wakeup_wq(struct net_device* dev)
2442 rtl8192_hw_wakeup(dev);
2446 #define MIN_SLEEP_TIME 50
2447 #define MAX_SLEEP_TIME 10000
2448 static void rtl8192_hw_to_sleep(struct net_device *dev, u32 th, u32 tl)
2451 struct r8192_priv *priv = ieee80211_priv(dev);
2454 unsigned long flags;
2456 spin_lock_irqsave(&priv->ps_lock,flags);
2458 /* Writing HW register with 0 equals to disable
2459 * the timer, that is not really what we want
2461 tl -= MSECS(4+16+7);
2463 //if(tl == 0) tl = 1;
2465 /* FIXME HACK FIXME HACK */
2466 // force_pci_posting(dev);
2469 // rb = read_nic_dword(dev, TSFTR);
2471 /* If the interval in witch we are requested to sleep is too
2472 * short then give up and remain awake
2474 if(((tl>=rb)&& (tl-rb) <= MSECS(MIN_SLEEP_TIME))
2475 ||((rb>tl)&& (rb-tl) < MSECS(MIN_SLEEP_TIME))) {
2476 spin_unlock_irqrestore(&priv->ps_lock,flags);
2477 printk("too short to sleep\n");
2481 // write_nic_dword(dev, TimerInt, tl);
2482 // rb = read_nic_dword(dev, TSFTR);
2484 u32 tmp = (tl>rb)?(tl-rb):(rb-tl);
2486 queue_delayed_work(priv->ieee80211->wq, &priv->ieee80211->hw_wakeup_wq, tmp); //as tl may be less than rb
2488 /* if we suspect the TimerInt is gone beyond tl
2489 * while setting it, then give up
2492 if(((tl > rb) && ((tl-rb) > MSECS(MAX_SLEEP_TIME)))||
2493 ((tl < rb) && ((rb-tl) > MSECS(MAX_SLEEP_TIME)))) {
2494 printk("========>too long to sleep:%x, %x, %lx\n", tl, rb, MSECS(MAX_SLEEP_TIME));
2495 spin_unlock_irqrestore(&priv->ps_lock,flags);
2499 // if(priv->rf_sleep)
2500 // priv->rf_sleep(dev);
2502 //printk("<=========%s()\n", __FUNCTION__);
2503 queue_delayed_work(priv->ieee80211->wq, (void *)&priv->ieee80211->hw_sleep_wq,0);
2504 spin_unlock_irqrestore(&priv->ps_lock,flags);
2506 static void rtl8192_init_priv_variable(struct net_device* dev)
2508 struct r8192_priv *priv = ieee80211_priv(dev);
2510 priv->being_init_adapter = false;
2511 priv->txbuffsize = 1600;//1024;
2512 priv->txfwbuffersize = 4096;
2513 priv->txringcount = 64;//32;
2514 //priv->txbeaconcount = priv->txringcount;
2515 priv->txbeaconcount = 2;
2516 priv->rxbuffersize = 9100;//2048;//1024;
2517 priv->rxringcount = MAX_RX_COUNT;//64;
2518 priv->irq_enabled=0;
2519 priv->card_8192 = NIC_8192E;
2520 priv->rx_skb_complete = 1;
2521 priv->chan = 1; //set to channel 1
2522 priv->RegWirelessMode = WIRELESS_MODE_AUTO;
2523 priv->RegChannelPlan = 0xf;
2524 priv->nrxAMPDU_size = 0;
2525 priv->nrxAMPDU_aggr_num = 0;
2526 priv->last_rxdesc_tsf_high = 0;
2527 priv->last_rxdesc_tsf_low = 0;
2528 priv->ieee80211->mode = WIRELESS_MODE_AUTO; //SET AUTO
2529 priv->ieee80211->iw_mode = IW_MODE_INFRA;
2530 priv->ieee80211->ieee_up=0;
2531 priv->retry_rts = DEFAULT_RETRY_RTS;
2532 priv->retry_data = DEFAULT_RETRY_DATA;
2533 priv->ieee80211->rts = DEFAULT_RTS_THRESHOLD;
2534 priv->ieee80211->rate = 110; //11 mbps
2535 priv->ieee80211->short_slot = 1;
2536 priv->promisc = (dev->flags & IFF_PROMISC) ? 1:0;
2537 priv->bcck_in_ch14 = false;
2538 priv->bfsync_processing = false;
2539 priv->CCKPresentAttentuation = 0;
2540 priv->rfa_txpowertrackingindex = 0;
2541 priv->rfc_txpowertrackingindex = 0;
2543 priv->ScanDelay = 50;//for Scan TODO
2544 //added by amy for silent reset
2545 priv->ResetProgress = RESET_TYPE_NORESET;
2546 priv->bForcedSilentReset = 0;
2547 priv->bDisableNormalResetCheck = false;
2548 priv->force_reset = false;
2549 //added by amy for power save
2551 priv->ieee80211->RfOffReason = 0;
2552 priv->RFChangeInProgress = false;
2553 priv->bHwRfOffAction = 0;
2554 priv->SetRFPowerStateInProgress = false;
2555 priv->ieee80211->PowerSaveControl.bInactivePs = true;
2556 priv->ieee80211->PowerSaveControl.bIPSModeBackup = false;
2558 priv->txpower_checkcnt = 0;
2559 priv->thermal_readback_index =0;
2560 priv->txpower_tracking_callback_cnt = 0;
2561 priv->ccktxpower_adjustcnt_ch14 = 0;
2562 priv->ccktxpower_adjustcnt_not_ch14 = 0;
2564 priv->ieee80211->current_network.beacon_interval = DEFAULT_BEACONINTERVAL;
2565 priv->ieee80211->iw_mode = IW_MODE_INFRA;
2566 priv->ieee80211->softmac_features = IEEE_SOFTMAC_SCAN |
2567 IEEE_SOFTMAC_ASSOCIATE | IEEE_SOFTMAC_PROBERQ |
2568 IEEE_SOFTMAC_PROBERS | IEEE_SOFTMAC_TX_QUEUE;/* |
2569 IEEE_SOFTMAC_BEACONS;*///added by amy 080604 //| //IEEE_SOFTMAC_SINGLE_QUEUE;
2571 priv->ieee80211->active_scan = 1;
2572 priv->ieee80211->modulation = IEEE80211_CCK_MODULATION | IEEE80211_OFDM_MODULATION;
2573 priv->ieee80211->host_encrypt = 1;
2574 priv->ieee80211->host_decrypt = 1;
2575 //priv->ieee80211->start_send_beacons = NULL;//rtl819xusb_beacon_tx;//-by amy 080604
2576 //priv->ieee80211->stop_send_beacons = NULL;//rtl8192_beacon_stop;//-by amy 080604
2577 priv->ieee80211->start_send_beacons = rtl8192_start_beacon;//+by david 081107
2578 priv->ieee80211->stop_send_beacons = rtl8192_stop_beacon;//+by david 081107
2579 priv->ieee80211->softmac_hard_start_xmit = rtl8192_hard_start_xmit;
2580 priv->ieee80211->set_chan = rtl8192_set_chan;
2581 priv->ieee80211->link_change = rtl8192_link_change;
2582 priv->ieee80211->softmac_data_hard_start_xmit = rtl8192_hard_data_xmit;
2583 priv->ieee80211->data_hard_stop = rtl8192_data_hard_stop;
2584 priv->ieee80211->data_hard_resume = rtl8192_data_hard_resume;
2585 priv->ieee80211->init_wmmparam_flag = 0;
2586 priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD;
2587 priv->ieee80211->check_nic_enough_desc = check_nic_enough_desc;
2588 priv->ieee80211->tx_headroom = sizeof(TX_FWINFO_8190PCI);
2589 priv->ieee80211->qos_support = 1;
2590 priv->ieee80211->dot11PowerSaveMode = 0;
2592 // priv->ieee80211->SwChnlByTimerHandler = rtl8192_phy_SwChnl;
2593 priv->ieee80211->SetBWModeHandler = rtl8192_SetBWMode;
2594 priv->ieee80211->handle_assoc_response = rtl8192_handle_assoc_response;
2595 priv->ieee80211->handle_beacon = rtl8192_handle_beacon;
2597 priv->ieee80211->sta_wake_up = rtl8192_hw_wakeup;
2598 // priv->ieee80211->ps_request_tx_ack = rtl8192_rq_tx_ack;
2599 priv->ieee80211->enter_sleep_state = rtl8192_hw_to_sleep;
2600 priv->ieee80211->ps_is_queue_empty = rtl8192_is_tx_queue_empty;
2602 priv->ieee80211->GetNmodeSupportBySecCfg = GetNmodeSupportBySecCfg8190Pci;
2603 priv->ieee80211->SetWirelessMode = rtl8192_SetWirelessMode;
2604 priv->ieee80211->GetHalfNmodeSupportByAPsHandler = GetHalfNmodeSupportByAPs819xPci;
2607 priv->ieee80211->InitialGainHandler = InitialGain819xPci;
2609 priv->card_type = USB;
2611 priv->ShortRetryLimit = 0x30;
2612 priv->LongRetryLimit = 0x30;
2614 priv->EarlyRxThreshold = 7;
2615 priv->enable_gpio0 = 0;
2617 priv->TransmitConfig = 0;
2619 priv->ReceiveConfig = RCR_ADD3 |
2620 RCR_AMF | RCR_ADF | //accept management/data
2621 RCR_AICV | //accept control frame for SW AP needs PS-poll, 2005.07.07, by rcnjko.
2622 RCR_AB | RCR_AM | RCR_APM | //accept BC/MC/UC
2623 RCR_AAP | ((u32)7<<RCR_MXDMA_OFFSET) |
2624 ((u32)7 << RCR_FIFO_OFFSET) | RCR_ONLYERLPKT;
2626 priv->irq_mask = (u32)(IMR_ROK | IMR_VODOK | IMR_VIDOK | IMR_BEDOK | IMR_BKDOK |\
2627 IMR_HCCADOK | IMR_MGNTDOK | IMR_COMDOK | IMR_HIGHDOK |\
2628 IMR_BDOK | IMR_RXCMDOK | IMR_TIMEOUT0 | IMR_RDU | IMR_RXFOVW |\
2629 IMR_TXFOVW | IMR_BcnInt | IMR_TBDOK | IMR_TBDER);
2631 priv->AcmControl = 0;
2632 priv->pFirmware = (rt_firmware*)vmalloc(sizeof(rt_firmware));
2633 if (priv->pFirmware)
2634 memset(priv->pFirmware, 0, sizeof(rt_firmware));
2636 /* rx related queue */
2637 skb_queue_head_init(&priv->rx_queue);
2638 skb_queue_head_init(&priv->skb_queue);
2640 /* Tx related queue */
2641 for(i = 0; i < MAX_QUEUE_SIZE; i++) {
2642 skb_queue_head_init(&priv->ieee80211->skb_waitQ [i]);
2644 for(i = 0; i < MAX_QUEUE_SIZE; i++) {
2645 skb_queue_head_init(&priv->ieee80211->skb_aggQ [i]);
2647 priv->rf_set_chan = rtl8192_phy_SwChnl;
2651 static void rtl8192_init_priv_lock(struct r8192_priv* priv)
2653 spin_lock_init(&priv->tx_lock);
2654 spin_lock_init(&priv->irq_lock);//added by thomas
2655 spin_lock_init(&priv->irq_th_lock);
2656 spin_lock_init(&priv->rf_ps_lock);
2657 spin_lock_init(&priv->ps_lock);
2658 //spin_lock_init(&priv->rf_lock);
2659 sema_init(&priv->wx_sem,1);
2660 sema_init(&priv->rf_sem,1);
2661 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16))
2662 sema_init(&priv->mutex, 1);
2664 mutex_init(&priv->mutex);
2668 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
2669 extern void rtl819x_watchdog_wqcallback(struct work_struct *work);
2671 extern void rtl819x_watchdog_wqcallback(struct net_device *dev);
2674 void rtl8192_irq_rx_tasklet(struct r8192_priv *priv);
2675 void rtl8192_irq_tx_tasklet(struct r8192_priv *priv);
2676 void rtl8192_prepare_beacon(struct r8192_priv *priv);
2677 //init tasklet and wait_queue here. only 2.6 above kernel is considered
2678 #define DRV_NAME "wlan0"
2679 static void rtl8192_init_priv_task(struct net_device* dev)
2681 struct r8192_priv *priv = ieee80211_priv(dev);
2683 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
2684 #ifdef PF_SYNCTHREAD
2685 priv->priv_wq = create_workqueue(DRV_NAME,0);
2687 priv->priv_wq = create_workqueue(DRV_NAME);
2691 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
2692 // INIT_WORK(&priv->reset_wq, (void(*)(void*)) rtl8192_restart);
2693 INIT_WORK(&priv->reset_wq, rtl8192_restart);
2694 // INIT_DELAYED_WORK(&priv->watch_dog_wq, hal_dm_watchdog);
2695 INIT_DELAYED_WORK(&priv->watch_dog_wq, rtl819x_watchdog_wqcallback);
2696 INIT_DELAYED_WORK(&priv->txpower_tracking_wq, dm_txpower_trackingcallback);
2697 INIT_DELAYED_WORK(&priv->rfpath_check_wq, dm_rf_pathcheck_workitemcallback);
2698 INIT_DELAYED_WORK(&priv->update_beacon_wq, rtl8192_update_beacon);
2699 //INIT_WORK(&priv->SwChnlWorkItem, rtl8192_SwChnl_WorkItem);
2700 //INIT_WORK(&priv->SetBWModeWorkItem, rtl8192_SetBWModeWorkItem);
2701 INIT_WORK(&priv->qos_activate, rtl8192_qos_activate);
2702 INIT_DELAYED_WORK(&priv->ieee80211->hw_wakeup_wq,(void*) rtl8192_hw_wakeup_wq);
2703 INIT_DELAYED_WORK(&priv->ieee80211->hw_sleep_wq,(void*) rtl8192_hw_sleep_wq);
2706 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
2707 tq_init(&priv->reset_wq, (void*)rtl8192_restart, dev);
2708 tq_init(&priv->watch_dog_wq, (void*)rtl819x_watchdog_wqcallback, dev);
2709 tq_init(&priv->txpower_tracking_wq, (void*)dm_txpower_trackingcallback, dev);
2710 tq_init(&priv->rfpath_check_wq, (void*)dm_rf_pathcheck_workitemcallback, dev);
2711 tq_init(&priv->update_beacon_wq, (void*)rtl8192_update_beacon, dev);
2712 //tq_init(&priv->SwChnlWorkItem, (void*) rtl8192_SwChnl_WorkItem, dev);
2713 //tq_init(&priv->SetBWModeWorkItem, (void*)rtl8192_SetBWModeWorkItem, dev);
2714 tq_init(&priv->qos_activate, (void *)rtl8192_qos_activate, dev);
2715 tq_init(&priv->ieee80211->hw_wakeup_wq,(void*) rtl8192_hw_wakeup_wq, dev);
2716 tq_init(&priv->ieee80211->hw_sleep_wq,(void*) rtl8192_hw_sleep_wq, dev);
2719 INIT_WORK(&priv->reset_wq,(void(*)(void*)) rtl8192_restart,dev);
2720 // INIT_WORK(&priv->watch_dog_wq, (void(*)(void*)) hal_dm_watchdog,dev);
2721 INIT_WORK(&priv->watch_dog_wq, (void(*)(void*)) rtl819x_watchdog_wqcallback,dev);
2722 INIT_WORK(&priv->txpower_tracking_wq, (void(*)(void*)) dm_txpower_trackingcallback,dev);
2723 INIT_WORK(&priv->rfpath_check_wq, (void(*)(void*)) dm_rf_pathcheck_workitemcallback,dev);
2724 INIT_WORK(&priv->update_beacon_wq, (void(*)(void*))rtl8192_update_beacon,dev);
2725 //INIT_WORK(&priv->SwChnlWorkItem, (void(*)(void*)) rtl8192_SwChnl_WorkItem, dev);
2726 //INIT_WORK(&priv->SetBWModeWorkItem, (void(*)(void*)) rtl8192_SetBWModeWorkItem, dev);
2727 INIT_WORK(&priv->qos_activate, (void(*)(void *))rtl8192_qos_activate, dev);
2728 INIT_WORK(&priv->ieee80211->hw_wakeup_wq,(void*) rtl8192_hw_wakeup_wq, dev);
2729 INIT_WORK(&priv->ieee80211->hw_sleep_wq,(void*) rtl8192_hw_sleep_wq, dev);
2733 tasklet_init(&priv->irq_rx_tasklet,
2734 (void(*)(unsigned long))rtl8192_irq_rx_tasklet,
2735 (unsigned long)priv);
2736 tasklet_init(&priv->irq_tx_tasklet,
2737 (void(*)(unsigned long))rtl8192_irq_tx_tasklet,
2738 (unsigned long)priv);
2739 tasklet_init(&priv->irq_prepare_beacon_tasklet,
2740 (void(*)(unsigned long))rtl8192_prepare_beacon,
2741 (unsigned long)priv);
2744 static void rtl8192_get_eeprom_size(struct net_device* dev)
2747 struct r8192_priv *priv = ieee80211_priv(dev);
2748 RT_TRACE(COMP_INIT, "===========>%s()\n", __FUNCTION__);
2749 curCR = read_nic_dword(dev, EPROM_CMD);
2750 RT_TRACE(COMP_INIT, "read from Reg Cmd9346CR(%x):%x\n", EPROM_CMD, curCR);
2751 //whether need I consider BIT5?
2752 priv->epromtype = (curCR & EPROM_CMD_9356SEL) ? EPROM_93c56 : EPROM_93c46;
2753 RT_TRACE(COMP_INIT, "<===========%s(), epromtype:%d\n", __FUNCTION__, priv->epromtype);
2756 //used to swap endian. as ntohl & htonl are not neccessary to swap endian, so use this instead.
2757 static inline u16 endian_swap(u16* data)
2760 *data = (tmp >> 8) | (tmp << 8);
2765 * Note: Adapter->EEPROMAddressSize should be set before this function call.
2766 * EEPROM address size can be got through GetEEPROMSize8185()
2768 static void rtl8192_read_eeprom_info(struct net_device* dev)
2770 struct r8192_priv *priv = ieee80211_priv(dev);
2774 u8 ICVer8192, ICVer8256;
2776 u16 i,usValue, IC_Version;
2779 u8 offset;//, tmpAFR;
2780 u8 EepromTxPower[100];
2782 u8 bMac_Tmp_Addr[6] = {0x00, 0xe0, 0x4c, 0x00, 0x00, 0x01};
2783 RT_TRACE(COMP_INIT, "====> rtl8192_read_eeprom_info\n");
2786 // TODO: I don't know if we need to apply EF function to EEPROM read function
2788 //2 Read EEPROM ID to make sure autoload is success
2789 EEPROMId = eprom_read(dev, 0);
2790 if( EEPROMId != RTL8190_EEPROM_ID )
2792 RT_TRACE(COMP_ERR, "EEPROM ID is invalid:%x, %x\n", EEPROMId, RTL8190_EEPROM_ID);
2793 priv->AutoloadFailFlag=true;
2797 priv->AutoloadFailFlag=false;
2801 // Assign Chip Version ID
2803 // Read IC Version && Channel Plan
2804 if(!priv->AutoloadFailFlag)
2807 priv->eeprom_vid = eprom_read(dev, (EEPROM_VID >> 1));
2808 priv->eeprom_did = eprom_read(dev, (EEPROM_DID >> 1));
2810 usValue = eprom_read(dev, (u16)(EEPROM_Customer_ID>>1)) >> 8 ;
2811 priv->eeprom_CustomerID = (u8)( usValue & 0xff);
2812 usValue = eprom_read(dev, (EEPROM_ICVersion_ChannelPlan>>1));
2813 priv->eeprom_ChannelPlan = usValue&0xff;
2814 IC_Version = ((usValue&0xff00)>>8);
2817 priv->card_8192_version = (VERSION_8190)(IC_Version);
2820 ICVer8192 = (IC_Version&0xf); //bit0~3; 1:A cut, 2:B cut, 3:C cut...
2821 ICVer8256 = ((IC_Version&0xf0)>>4);//bit4~6, bit7 reserved for other RF chip; 1:A cut, 2:B cut, 3:C cut...
2822 RT_TRACE(COMP_INIT, "\nICVer8192 = 0x%x\n", ICVer8192);
2823 RT_TRACE(COMP_INIT, "\nICVer8256 = 0x%x\n", ICVer8256);
2824 if(ICVer8192 == 0x2) //B-cut
2826 if(ICVer8256 == 0x5) //E-cut
2827 priv->card_8192_version= VERSION_8190_BE;
2831 switch(priv->card_8192_version)
2833 case VERSION_8190_BD:
2834 case VERSION_8190_BE:
2837 priv->card_8192_version = VERSION_8190_BD;
2840 RT_TRACE(COMP_INIT, "\nIC Version = 0x%x\n", priv->card_8192_version);
2844 priv->card_8192_version = VERSION_8190_BD;
2845 priv->eeprom_vid = 0;
2846 priv->eeprom_did = 0;
2847 priv->eeprom_CustomerID = 0;
2848 priv->eeprom_ChannelPlan = 0;
2849 RT_TRACE(COMP_INIT, "\nIC Version = 0x%x\n", 0xff);
2852 RT_TRACE(COMP_INIT, "EEPROM VID = 0x%4x\n", priv->eeprom_vid);
2853 RT_TRACE(COMP_INIT, "EEPROM DID = 0x%4x\n", priv->eeprom_did);
2854 RT_TRACE(COMP_INIT,"EEPROM Customer ID: 0x%2x\n", priv->eeprom_CustomerID);
2856 //2 Read Permanent MAC address
2857 if(!priv->AutoloadFailFlag)
2859 for(i = 0; i < 6; i += 2)
2861 usValue = eprom_read(dev, (u16) ((EEPROM_NODE_ADDRESS_BYTE_0+i)>>1));
2862 *(u16*)(&dev->dev_addr[i]) = usValue;
2865 // when auto load failed, the last address byte set to be a random one.
2866 // added by david woo.2007/11/7
2867 memcpy(dev->dev_addr, bMac_Tmp_Addr, 6);
2869 for(i = 0; i < 6; i++)
2871 Adapter->PermanentAddress[i] = sMacAddr[i];
2872 PlatformEFIOWrite1Byte(Adapter, IDR0+i, sMacAddr[i]);
2877 RT_TRACE(COMP_INIT, "Permanent Address = %02x-%02x-%02x-%02x-%02x-%02x\n",
2878 dev->dev_addr[0], dev->dev_addr[1],
2879 dev->dev_addr[2], dev->dev_addr[3],
2880 dev->dev_addr[4], dev->dev_addr[5]);
2882 //2 TX Power Check EEPROM Fail or not
2883 if(priv->card_8192_version > VERSION_8190_BD) {
2884 priv->bTXPowerDataReadFromEEPORM = true;
2886 priv->bTXPowerDataReadFromEEPORM = false;
2889 // 2007/11/15 MH 8190PCI Default=2T4R, 8192PCIE dafault=1T2R
2890 priv->rf_type = RTL819X_DEFAULT_RF_TYPE;
2892 if(priv->card_8192_version > VERSION_8190_BD)
2894 // Read RF-indication and Tx Power gain index diff of legacy to HT OFDM rate.
2895 if(!priv->AutoloadFailFlag)
2897 tempval = (eprom_read(dev, (EEPROM_RFInd_PowerDiff>>1))) & 0xff;
2898 priv->EEPROMLegacyHTTxPowerDiff = tempval & 0xf; // bit[3:0]
2900 if (tempval&0x80) //RF-indication, bit[7]
2901 priv->rf_type = RF_1T2R;
2903 priv->rf_type = RF_2T4R;
2907 priv->EEPROMLegacyHTTxPowerDiff = EEPROM_Default_LegacyHTTxPowerDiff;
2909 RT_TRACE(COMP_INIT, "EEPROMLegacyHTTxPowerDiff = %d\n",
2910 priv->EEPROMLegacyHTTxPowerDiff);
2912 // Read ThermalMeter from EEPROM
2913 if(!priv->AutoloadFailFlag)
2915 priv->EEPROMThermalMeter = (u8)(((eprom_read(dev, (EEPROM_ThermalMeter>>1))) & 0xff00)>>8);
2919 priv->EEPROMThermalMeter = EEPROM_Default_ThermalMeter;
2921 RT_TRACE(COMP_INIT, "ThermalMeter = %d\n", priv->EEPROMThermalMeter);
2922 //vivi, for tx power track
2923 priv->TSSI_13dBm = priv->EEPROMThermalMeter *100;
2925 if(priv->epromtype == EPROM_93c46)
2927 // Read antenna tx power offset of B/C/D to A and CrystalCap from EEPROM
2928 if(!priv->AutoloadFailFlag)
2930 usValue = eprom_read(dev, (EEPROM_TxPwDiff_CrystalCap>>1));
2931 priv->EEPROMAntPwDiff = (usValue&0x0fff);
2932 priv->EEPROMCrystalCap = (u8)((usValue&0xf000)>>12);
2936 priv->EEPROMAntPwDiff = EEPROM_Default_AntTxPowerDiff;
2937 priv->EEPROMCrystalCap = EEPROM_Default_TxPwDiff_CrystalCap;
2939 RT_TRACE(COMP_INIT, "EEPROMAntPwDiff = %d\n", priv->EEPROMAntPwDiff);
2940 RT_TRACE(COMP_INIT, "EEPROMCrystalCap = %d\n", priv->EEPROMCrystalCap);
2943 // Get per-channel Tx Power Level
2945 for(i=0; i<14; i+=2)
2947 if(!priv->AutoloadFailFlag)
2949 usValue = eprom_read(dev, (u16) ((EEPROM_TxPwIndex_CCK+i)>>1) );
2953 usValue = EEPROM_Default_TxPower;
2955 *((u16*)(&priv->EEPROMTxPowerLevelCCK[i])) = usValue;
2956 RT_TRACE(COMP_INIT,"CCK Tx Power Level, Index %d = 0x%02x\n", i, priv->EEPROMTxPowerLevelCCK[i]);
2957 RT_TRACE(COMP_INIT, "CCK Tx Power Level, Index %d = 0x%02x\n", i+1, priv->EEPROMTxPowerLevelCCK[i+1]);
2959 for(i=0; i<14; i+=2)
2961 if(!priv->AutoloadFailFlag)
2963 usValue = eprom_read(dev, (u16) ((EEPROM_TxPwIndex_OFDM_24G+i)>>1) );
2967 usValue = EEPROM_Default_TxPower;
2969 *((u16*)(&priv->EEPROMTxPowerLevelOFDM24G[i])) = usValue;
2970 RT_TRACE(COMP_INIT, "OFDM 2.4G Tx Power Level, Index %d = 0x%02x\n", i, priv->EEPROMTxPowerLevelOFDM24G[i]);
2971 RT_TRACE(COMP_INIT, "OFDM 2.4G Tx Power Level, Index %d = 0x%02x\n", i+1, priv->EEPROMTxPowerLevelOFDM24G[i+1]);
2974 else if(priv->epromtype== EPROM_93c56)
2977 // Read CrystalCap from EEPROM
2978 if(!priv->AutoloadFailFlag)
2980 priv->EEPROMAntPwDiff = EEPROM_Default_AntTxPowerDiff;
2981 priv->EEPROMCrystalCap = (u8)(((eprom_read(dev, (EEPROM_C56_CrystalCap>>1))) & 0xf000)>>12);
2985 priv->EEPROMAntPwDiff = EEPROM_Default_AntTxPowerDiff;
2986 priv->EEPROMCrystalCap = EEPROM_Default_TxPwDiff_CrystalCap;
2988 RT_TRACE(COMP_INIT,"EEPROMAntPwDiff = %d\n", priv->EEPROMAntPwDiff);
2989 RT_TRACE(COMP_INIT, "EEPROMCrystalCap = %d\n", priv->EEPROMCrystalCap);
2991 // Get Tx Power Level by Channel
2992 if(!priv->AutoloadFailFlag)
2994 // Read Tx power of Channel 1 ~ 14 from EEPROM.
2995 for(i = 0; i < 12; i+=2)
2998 offset = EEPROM_C56_RfA_CCK_Chnl1_TxPwIndex + i;
3000 offset = EEPROM_C56_RfC_CCK_Chnl1_TxPwIndex + i - 6;
3001 usValue = eprom_read(dev, (offset>>1));
3002 *((u16*)(&EepromTxPower[i])) = usValue;
3005 for(i = 0; i < 12; i++)
3008 priv->EEPROMRfACCKChnl1TxPwLevel[i] = EepromTxPower[i];
3009 else if ((i >=3 )&&(i <= 5))
3010 priv->EEPROMRfAOfdmChnlTxPwLevel[i-3] = EepromTxPower[i];
3011 else if ((i >=6 )&&(i <= 8))
3012 priv->EEPROMRfCCCKChnl1TxPwLevel[i-6] = EepromTxPower[i];
3014 priv->EEPROMRfCOfdmChnlTxPwLevel[i-9] = EepromTxPower[i];
3019 priv->EEPROMRfACCKChnl1TxPwLevel[0] = EEPROM_Default_TxPowerLevel;
3020 priv->EEPROMRfACCKChnl1TxPwLevel[1] = EEPROM_Default_TxPowerLevel;
3021 priv->EEPROMRfACCKChnl1TxPwLevel[2] = EEPROM_Default_TxPowerLevel;
3023 priv->EEPROMRfAOfdmChnlTxPwLevel[0] = EEPROM_Default_TxPowerLevel;
3024 priv->EEPROMRfAOfdmChnlTxPwLevel[1] = EEPROM_Default_TxPowerLevel;
3025 priv->EEPROMRfAOfdmChnlTxPwLevel[2] = EEPROM_Default_TxPowerLevel;
3027 priv->EEPROMRfCCCKChnl1TxPwLevel[0] = EEPROM_Default_TxPowerLevel;
3028 priv->EEPROMRfCCCKChnl1TxPwLevel[1] = EEPROM_Default_TxPowerLevel;
3029 priv->EEPROMRfCCCKChnl1TxPwLevel[2] = EEPROM_Default_TxPowerLevel;
3031 priv->EEPROMRfCOfdmChnlTxPwLevel[0] = EEPROM_Default_TxPowerLevel;
3032 priv->EEPROMRfCOfdmChnlTxPwLevel[1] = EEPROM_Default_TxPowerLevel;
3033 priv->EEPROMRfCOfdmChnlTxPwLevel[2] = EEPROM_Default_TxPowerLevel;
3035 RT_TRACE(COMP_INIT, "priv->EEPROMRfACCKChnl1TxPwLevel[0] = 0x%x\n", priv->EEPROMRfACCKChnl1TxPwLevel[0]);
3036 RT_TRACE(COMP_INIT, "priv->EEPROMRfACCKChnl1TxPwLevel[1] = 0x%x\n", priv->EEPROMRfACCKChnl1TxPwLevel[1]);
3037 RT_TRACE(COMP_INIT, "priv->EEPROMRfACCKChnl1TxPwLevel[2] = 0x%x\n", priv->EEPROMRfACCKChnl1TxPwLevel[2]);
3038 RT_TRACE(COMP_INIT, "priv->EEPROMRfAOfdmChnlTxPwLevel[0] = 0x%x\n", priv->EEPROMRfAOfdmChnlTxPwLevel[0]);
3039 RT_TRACE(COMP_INIT, "priv->EEPROMRfAOfdmChnlTxPwLevel[1] = 0x%x\n", priv->EEPROMRfAOfdmChnlTxPwLevel[1]);
3040 RT_TRACE(COMP_INIT, "priv->EEPROMRfAOfdmChnlTxPwLevel[2] = 0x%x\n", priv->EEPROMRfAOfdmChnlTxPwLevel[2]);
3041 RT_TRACE(COMP_INIT, "priv->EEPROMRfCCCKChnl1TxPwLevel[0] = 0x%x\n", priv->EEPROMRfCCCKChnl1TxPwLevel[0]);
3042 RT_TRACE(COMP_INIT, "priv->EEPROMRfCCCKChnl1TxPwLevel[1] = 0x%x\n", priv->EEPROMRfCCCKChnl1TxPwLevel[1]);
3043 RT_TRACE(COMP_INIT, "priv->EEPROMRfCCCKChnl1TxPwLevel[2] = 0x%x\n", priv->EEPROMRfCCCKChnl1TxPwLevel[2]);
3044 RT_TRACE(COMP_INIT, "priv->EEPROMRfCOfdmChnlTxPwLevel[0] = 0x%x\n", priv->EEPROMRfCOfdmChnlTxPwLevel[0]);
3045 RT_TRACE(COMP_INIT, "priv->EEPROMRfCOfdmChnlTxPwLevel[1] = 0x%x\n", priv->EEPROMRfCOfdmChnlTxPwLevel[1]);
3046 RT_TRACE(COMP_INIT, "priv->EEPROMRfCOfdmChnlTxPwLevel[2] = 0x%x\n", priv->EEPROMRfCOfdmChnlTxPwLevel[2]);
3051 // Update HAL variables.
3053 if(priv->epromtype == EPROM_93c46)
3057 priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelCCK[i];
3058 priv->TxPowerLevelOFDM24G[i] = priv->EEPROMTxPowerLevelOFDM24G[i];
3060 priv->LegacyHTTxPowerDiff = priv->EEPROMLegacyHTTxPowerDiff;
3061 // Antenna B gain offset to antenna A, bit0~3
3062 priv->AntennaTxPwDiff[0] = (priv->EEPROMAntPwDiff & 0xf);
3063 // Antenna C gain offset to antenna A, bit4~7
3064 priv->AntennaTxPwDiff[1] = ((priv->EEPROMAntPwDiff & 0xf0)>>4);
3065 // Antenna D gain offset to antenna A, bit8~11
3066 priv->AntennaTxPwDiff[2] = ((priv->EEPROMAntPwDiff & 0xf00)>>8);
3067 // CrystalCap, bit12~15
3068 priv->CrystalCap = priv->EEPROMCrystalCap;
3069 // ThermalMeter, bit0~3 for RFIC1, bit4~7 for RFIC2
3070 priv->ThermalMeter[0] = (priv->EEPROMThermalMeter & 0xf);
3071 priv->ThermalMeter[1] = ((priv->EEPROMThermalMeter & 0xf0)>>4);
3073 else if(priv->epromtype == EPROM_93c56)
3075 //char cck_pwr_diff_a=0, cck_pwr_diff_c=0;
3077 //cck_pwr_diff_a = pHalData->EEPROMRfACCKChnl7TxPwLevel - pHalData->EEPROMRfAOfdmChnlTxPwLevel[1];
3078 //cck_pwr_diff_c = pHalData->EEPROMRfCCCKChnl7TxPwLevel - pHalData->EEPROMRfCOfdmChnlTxPwLevel[1];
3079 for(i=0; i<3; i++) // channel 1~3 use the same Tx Power Level.
3081 priv->TxPowerLevelCCK_A[i] = priv->EEPROMRfACCKChnl1TxPwLevel[0];
3082 priv->TxPowerLevelOFDM24G_A[i] = priv->EEPROMRfAOfdmChnlTxPwLevel[0];
3083 priv->TxPowerLevelCCK_C[i] = priv->EEPROMRfCCCKChnl1TxPwLevel[0];
3084 priv->TxPowerLevelOFDM24G_C[i] = priv->EEPROMRfCOfdmChnlTxPwLevel[0];
3086 for(i=3; i<9; i++) // channel 4~9 use the same Tx Power Level
3088 priv->TxPowerLevelCCK_A[i] = priv->EEPROMRfACCKChnl1TxPwLevel[1];
3089 priv->TxPowerLevelOFDM24G_A[i] = priv->EEPROMRfAOfdmChnlTxPwLevel[1];
3090 priv->TxPowerLevelCCK_C[i] = priv->EEPROMRfCCCKChnl1TxPwLevel[1];
3091 priv->TxPowerLevelOFDM24G_C[i] = priv->EEPROMRfCOfdmChnlTxPwLevel[1];
3093 for(i=9; i<14; i++) // channel 10~14 use the same Tx Power Level
3095 priv->TxPowerLevelCCK_A[i] = priv->EEPROMRfACCKChnl1TxPwLevel[2];
3096 priv->TxPowerLevelOFDM24G_A[i] = priv->EEPROMRfAOfdmChnlTxPwLevel[2];
3097 priv->TxPowerLevelCCK_C[i] = priv->EEPROMRfCCCKChnl1TxPwLevel[2];
3098 priv->TxPowerLevelOFDM24G_C[i] = priv->EEPROMRfCOfdmChnlTxPwLevel[2];
3101 RT_TRACE(COMP_INIT, "priv->TxPowerLevelCCK_A[%d] = 0x%x\n", i, priv->TxPowerLevelCCK_A[i]);
3103 RT_TRACE(COMP_INIT,"priv->TxPowerLevelOFDM24G_A[%d] = 0x%x\n", i, priv->TxPowerLevelOFDM24G_A[i]);
3105 RT_TRACE(COMP_INIT, "priv->TxPowerLevelCCK_C[%d] = 0x%x\n", i, priv->TxPowerLevelCCK_C[i]);
3107 RT_TRACE(COMP_INIT, "priv->TxPowerLevelOFDM24G_C[%d] = 0x%x\n", i, priv->TxPowerLevelOFDM24G_C[i]);
3108 priv->LegacyHTTxPowerDiff = priv->EEPROMLegacyHTTxPowerDiff;
3109 priv->AntennaTxPwDiff[0] = 0;
3110 priv->AntennaTxPwDiff[1] = 0;
3111 priv->AntennaTxPwDiff[2] = 0;
3112 priv->CrystalCap = priv->EEPROMCrystalCap;
3113 // ThermalMeter, bit0~3 for RFIC1, bit4~7 for RFIC2
3114 priv->ThermalMeter[0] = (priv->EEPROMThermalMeter & 0xf);
3115 priv->ThermalMeter[1] = ((priv->EEPROMThermalMeter & 0xf0)>>4);
3119 if(priv->rf_type == RF_1T2R)
3121 RT_TRACE(COMP_INIT, "\n1T2R config\n");
3123 else if (priv->rf_type == RF_2T4R)
3125 RT_TRACE(COMP_INIT, "\n2T4R config\n");
3128 // 2008/01/16 MH We can only know RF type in the function. So we have to init
3129 // DIG RATR table again.
3130 init_rate_adaptive(dev);
3132 //1 Make a copy for following variables and we can change them if we want
3134 priv->rf_chip= RF_8256;
3136 if(priv->RegChannelPlan == 0xf)
3138 priv->ChannelPlan = priv->eeprom_ChannelPlan;
3142 priv->ChannelPlan = priv->RegChannelPlan;
3146 // Used PID and DID to Set CustomerID
3148 if( priv->eeprom_vid == 0x1186 && priv->eeprom_did == 0x3304 )
3150 priv->CustomerID = RT_CID_DLINK;
3153 switch(priv->eeprom_CustomerID)
3155 case EEPROM_CID_DEFAULT:
3156 priv->CustomerID = RT_CID_DEFAULT;
3158 case EEPROM_CID_CAMEO:
3159 priv->CustomerID = RT_CID_819x_CAMEO;
3161 case EEPROM_CID_RUNTOP:
3162 priv->CustomerID = RT_CID_819x_RUNTOP;
3164 case EEPROM_CID_NetCore:
3165 priv->CustomerID = RT_CID_819x_Netcore;
3167 case EEPROM_CID_TOSHIBA: // Merge by Jacken, 2008/01/31
3168 priv->CustomerID = RT_CID_TOSHIBA;
3169 if(priv->eeprom_ChannelPlan&0x80)
3170 priv->ChannelPlan = priv->eeprom_ChannelPlan&0x7f;
3172 priv->ChannelPlan = 0x0;
3173 RT_TRACE(COMP_INIT, "Toshiba ChannelPlan = 0x%x\n",
3176 case EEPROM_CID_Nettronix:
3177 priv->ScanDelay = 100; //cosa add for scan
3178 priv->CustomerID = RT_CID_Nettronix;
3180 case EEPROM_CID_Pronet:
3181 priv->CustomerID = RT_CID_PRONET;
3183 case EEPROM_CID_DLINK:
3184 priv->CustomerID = RT_CID_DLINK;
3187 case EEPROM_CID_WHQL:
3188 //Adapter->bInHctTest = TRUE;//do not supported
3190 //priv->bSupportTurboMode = FALSE;
3191 //priv->bAutoTurboBy8186 = FALSE;
3193 //pMgntInfo->PowerSaveControl.bInactivePs = FALSE;
3194 //pMgntInfo->PowerSaveControl.bIPSModeBackup = FALSE;
3195 //pMgntInfo->PowerSaveControl.bLeisurePs = FALSE;
3199 // value from RegCustomerID
3203 //Avoid the channel plan array overflow, by Bruce, 2007-08-27.
3204 if(priv->ChannelPlan > CHANNEL_PLAN_LEN - 1)
3205 priv->ChannelPlan = 0; //FCC
3207 switch(priv->CustomerID)
3209 case RT_CID_DEFAULT:
3211 priv->LedStrategy = HW_LED;
3214 priv->LedStrategy = SW_LED_MODE1;
3219 case RT_CID_819x_CAMEO:
3220 priv->LedStrategy = SW_LED_MODE2;
3223 case RT_CID_819x_RUNTOP:
3224 priv->LedStrategy = SW_LED_MODE3;
3227 case RT_CID_819x_Netcore:
3228 priv->LedStrategy = SW_LED_MODE4;
3231 case RT_CID_Nettronix:
3232 priv->LedStrategy = SW_LED_MODE5;
3236 priv->LedStrategy = SW_LED_MODE6;
3239 case RT_CID_TOSHIBA: //Modify by Jacken 2008/01/31
3245 priv->LedStrategy = HW_LED;
3248 priv->LedStrategy = SW_LED_MODE1;
3254 //2008.06.03, for WOL
3255 if( priv->eeprom_vid == 0x1186 && priv->eeprom_did == 0x3304)
3256 priv->ieee80211->bSupportRemoteWakeUp = TRUE;
3258 priv->ieee80211->bSupportRemoteWakeUp = FALSE;
3260 RT_TRACE(COMP_INIT, "RegChannelPlan(%d)\n", priv->RegChannelPlan);
3261 RT_TRACE(COMP_INIT, "ChannelPlan = %d \n", priv->ChannelPlan);
3262 RT_TRACE(COMP_INIT, "LedStrategy = %d \n", priv->LedStrategy);
3263 RT_TRACE(COMP_TRACE, "<==== ReadAdapterInfo\n");
3269 static short rtl8192_get_channel_map(struct net_device * dev)
3271 struct r8192_priv *priv = ieee80211_priv(dev);
3272 #ifdef ENABLE_DOT11D
3273 if(priv->ChannelPlan> COUNTRY_CODE_GLOBAL_DOMAIN){
3274 printk("rtl8180_init:Error channel plan! Set to default.\n");
3275 priv->ChannelPlan= 0;
3277 RT_TRACE(COMP_INIT, "Channel plan is %d\n",priv->ChannelPlan);
3279 rtl819x_set_channel_map(priv->ChannelPlan, priv);
3282 //Set Default Channel Plan
3284 DMESG("No channels, aborting");
3288 priv->ChannelPlan= 0;//hikaru
3289 // set channels 1..14 allowed in given locale
3290 for (i=1; i<=14; i++) {
3291 (priv->ieee80211->channel_map)[i] = (u8)(ch & 0x01);
3298 static short rtl8192_init(struct net_device *dev)
3300 struct r8192_priv *priv = ieee80211_priv(dev);
3301 memset(&(priv->stats),0,sizeof(struct Stats));
3302 rtl8192_init_priv_variable(dev);
3303 rtl8192_init_priv_lock(priv);
3304 rtl8192_init_priv_task(dev);
3305 rtl8192_get_eeprom_size(dev);
3306 rtl8192_read_eeprom_info(dev);
3307 rtl8192_get_channel_map(dev);
3309 init_timer(&priv->watch_dog_timer);
3310 priv->watch_dog_timer.data = (unsigned long)dev;
3311 priv->watch_dog_timer.function = watch_dog_timer_callback;
3312 #if defined(IRQF_SHARED)
3313 if(request_irq(dev->irq, (void*)rtl8192_interrupt, IRQF_SHARED, dev->name, dev)){
3315 if(request_irq(dev->irq, (void *)rtl8192_interrupt, SA_SHIRQ, dev->name, dev)){
3317 printk("Error allocating IRQ %d",dev->irq);
3321 printk("IRQ %d",dev->irq);
3323 if(rtl8192_pci_initdescring(dev)!=0){
3324 printk("Endopoints initialization failed");
3328 //rtl8192_rx_enable(dev);
3329 //rtl8192_adapter_start(dev);
3333 /******************************************************************************
3334 *function: This function actually only set RRSR, RATR and BW_OPMODE registers
3335 * not to do all the hw config as its name says
3336 * input: net_device dev
3339 * notice: This part need to modified according to the rate set we filtered
3340 * ****************************************************************************/
3341 static void rtl8192_hwconfig(struct net_device* dev)
3343 u32 regRATR = 0, regRRSR = 0;
3344 u8 regBwOpMode = 0, regTmp = 0;
3345 struct r8192_priv *priv = ieee80211_priv(dev);
3347 // Set RRSR, RATR, and BW_OPMODE registers
3349 switch(priv->ieee80211->mode)
3351 case WIRELESS_MODE_B:
3352 regBwOpMode = BW_OPMODE_20MHZ;
3353 regRATR = RATE_ALL_CCK;
3354 regRRSR = RATE_ALL_CCK;
3356 case WIRELESS_MODE_A:
3357 regBwOpMode = BW_OPMODE_5G |BW_OPMODE_20MHZ;
3358 regRATR = RATE_ALL_OFDM_AG;
3359 regRRSR = RATE_ALL_OFDM_AG;
3361 case WIRELESS_MODE_G:
3362 regBwOpMode = BW_OPMODE_20MHZ;
3363 regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
3364 regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
3366 case WIRELESS_MODE_AUTO:
3367 case WIRELESS_MODE_N_24G:
3368 // It support CCK rate by default.
3369 // CCK rate will be filtered out only when associated AP does not support it.
3370 regBwOpMode = BW_OPMODE_20MHZ;
3371 regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
3372 regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
3374 case WIRELESS_MODE_N_5G:
3375 regBwOpMode = BW_OPMODE_5G;
3376 regRATR = RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
3377 regRRSR = RATE_ALL_OFDM_AG;
3381 write_nic_byte(dev, BW_OPMODE, regBwOpMode);
3384 ratr_value = regRATR;
3385 if (priv->rf_type == RF_1T2R)
3387 ratr_value &= ~(RATE_ALL_OFDM_2SS);
3389 write_nic_dword(dev, RATR0, ratr_value);
3390 write_nic_byte(dev, UFWP, 1);
3392 regTmp = read_nic_byte(dev, 0x313);
3393 regRRSR = ((regTmp) << 24) | (regRRSR & 0x00ffffff);
3394 write_nic_dword(dev, RRSR, regRRSR);
3397 // Set Retry Limit here
3399 write_nic_word(dev, RETRY_LIMIT,
3400 priv->ShortRetryLimit << RETRY_LIMIT_SHORT_SHIFT | \
3401 priv->LongRetryLimit << RETRY_LIMIT_LONG_SHIFT);
3402 // Set Contention Window here
3406 // Set Tx Antenna including Feedback control
3408 // Set Auto Rate fallback control
3414 static RT_STATUS rtl8192_adapter_start(struct net_device *dev)
3416 struct r8192_priv *priv = ieee80211_priv(dev);
3417 // struct ieee80211_device *ieee = priv->ieee80211;
3419 RT_STATUS rtStatus = RT_STATUS_SUCCESS;
3420 // static char szMACPHYRegFile[] = RTL819X_PHY_MACPHY_REG;
3421 // static char szMACPHYRegPGFile[] = RTL819X_PHY_MACPHY_REG_PG;
3425 u8 ICVersion,SwitchingRegulatorOutput;
3427 bool bfirmwareok = true;
3431 u32 tmpRegA, tmpRegC, TempCCk;
3433 // u32 dwRegRead = 0;
3435 RT_TRACE(COMP_INIT, "====>%s()\n", __FUNCTION__);
3436 priv->being_init_adapter = true;
3437 rtl8192_pci_resetdescring(dev);
3438 // 2007/11/02 MH Before initalizing RF. We can not use FW to do RF-R/W.
3439 priv->Rf_Mode = RF_OP_By_SW_3wire;
3442 if(priv->ResetProgress == RESET_TYPE_NORESET)
3444 write_nic_byte(dev, ANAPAR, 0x37);
3445 // Accordign to designer's explain, LBUS active will never > 10ms. We delay 10ms
3446 // Joseph increae the time to prevent firmware download fail
3450 //PlatformSleepUs(10000);
3451 // For any kind of InitializeAdapter process, we shall use system now!!
3452 priv->pFirmware->firmware_status = FW_STATUS_0_INIT;
3454 // Set to eRfoff in order not to count receive count.
3455 if(priv->RegRfOff == TRUE)
3456 priv->ieee80211->eRFPowerState = eRfOff;
3459 //3 //Config CPUReset Register
3461 //3 Firmware Reset Or Not
3462 ulRegRead = read_nic_dword(dev, CPU_GEN);
3463 if(priv->pFirmware->firmware_status == FW_STATUS_0_INIT)
3464 { //called from MPInitialized. do nothing
3465 ulRegRead |= CPU_GEN_SYSTEM_RESET;
3466 }else if(priv->pFirmware->firmware_status == FW_STATUS_5_READY)
3467 ulRegRead |= CPU_GEN_FIRMWARE_RESET; // Called from MPReset
3469 RT_TRACE(COMP_ERR, "ERROR in %s(): undefined firmware state(%d)\n", __FUNCTION__, priv->pFirmware->firmware_status);
3472 //2008.06.03, for WOL 90 hw bug
3473 ulRegRead &= (~(CPU_GEN_GPIO_UART));
3476 write_nic_dword(dev, CPU_GEN, ulRegRead);
3482 //3 //Fix the issue of E-cut high temperature issue
3485 ICVersion = read_nic_byte(dev, IC_VERRSION);
3486 if(ICVersion >= 0x4) //E-cut only
3488 // HW SD suggest that we should not wirte this register too often, so driver
3489 // should readback this register. This register will be modified only when
3491 SwitchingRegulatorOutput = read_nic_byte(dev, SWREGULATOR);
3492 if(SwitchingRegulatorOutput != 0xb8)
3494 write_nic_byte(dev, SWREGULATOR, 0xa8);
3496 write_nic_byte(dev, SWREGULATOR, 0xb8);
3503 //3// Initialize BB before MAC
3505 RT_TRACE(COMP_INIT, "BB Config Start!\n");
3506 rtStatus = rtl8192_BBConfig(dev);
3507 if(rtStatus != RT_STATUS_SUCCESS)
3509 RT_TRACE(COMP_ERR, "BB Config failed\n");
3512 RT_TRACE(COMP_INIT,"BB Config Finished!\n");
3514 //3//Set Loopback mode or Normal mode
3516 //2006.12.13 by emily. Note!We should not merge these two CPU_GEN register writings
3517 // because setting of System_Reset bit reset MAC to default transmission mode.
3518 //Loopback mode or not
3519 priv->LoopbackMode = RTL819X_NO_LOOPBACK;
3520 //priv->LoopbackMode = RTL819X_MAC_LOOPBACK;
3521 if(priv->ResetProgress == RESET_TYPE_NORESET)
3523 ulRegRead = read_nic_dword(dev, CPU_GEN);
3524 if(priv->LoopbackMode == RTL819X_NO_LOOPBACK)
3526 ulRegRead = ((ulRegRead & CPU_GEN_NO_LOOPBACK_MSK) | CPU_GEN_NO_LOOPBACK_SET);
3528 else if (priv->LoopbackMode == RTL819X_MAC_LOOPBACK )
3530 ulRegRead |= CPU_CCK_LOOPBACK;
3534 RT_TRACE(COMP_ERR,"Serious error: wrong loopback mode setting\n");
3537 //2008.06.03, for WOL
3538 //ulRegRead &= (~(CPU_GEN_GPIO_UART));
3539 write_nic_dword(dev, CPU_GEN, ulRegRead);
3541 // 2006.11.29. After reset cpu, we sholud wait for a second, otherwise, it may fail to write registers. Emily
3544 //3Set Hardware(Do nothing now)
3545 rtl8192_hwconfig(dev);
3546 //2=======================================================
3547 // Common Setting for all of the FPGA platform. (part 1)
3548 //2=======================================================
3549 // If there is changes, please make sure it applies to all of the FPGA version
3551 write_nic_byte(dev, CMDR, CR_RE|CR_TE);
3555 write_nic_byte(dev, PCIF, ((MXDMA2_NoLimit<<MXDMA2_RX_SHIFT) | \
3556 (MXDMA2_NoLimit<<MXDMA2_TX_SHIFT) | \
3560 write_nic_byte(dev, PCIF, ((MXDMA2_NoLimit<<MXDMA2_RX_SHIFT) |\
3561 (MXDMA2_NoLimit<<MXDMA2_TX_SHIFT) ));
3565 write_nic_dword(dev, MAC0, ((u32*)dev->dev_addr)[0]);
3566 write_nic_word(dev, MAC4, ((u16*)(dev->dev_addr + 4))[0]);
3568 write_nic_dword(dev, RCR, priv->ReceiveConfig);
3570 //3 Initialize Number of Reserved Pages in Firmware Queue
3572 if(priv->bInHctTest)
3574 PlatformEFIOWrite4Byte(Adapter, RQPN1, NUM_OF_PAGE_IN_FW_QUEUE_BK_DTM << RSVD_FW_QUEUE_PAGE_BK_SHIFT |\
3575 NUM_OF_PAGE_IN_FW_QUEUE_BE_DTM << RSVD_FW_QUEUE_PAGE_BE_SHIFT | \
3576 NUM_OF_PAGE_IN_FW_QUEUE_VI_DTM << RSVD_FW_QUEUE_PAGE_VI_SHIFT | \
3577 NUM_OF_PAGE_IN_FW_QUEUE_VO_DTM <<RSVD_FW_QUEUE_PAGE_VO_SHIFT);
3578 PlatformEFIOWrite4Byte(Adapter, RQPN2, NUM_OF_PAGE_IN_FW_QUEUE_MGNT << RSVD_FW_QUEUE_PAGE_MGNT_SHIFT);
3579 PlatformEFIOWrite4Byte(Adapter, RQPN3, APPLIED_RESERVED_QUEUE_IN_FW| \
3580 NUM_OF_PAGE_IN_FW_QUEUE_BCN<<RSVD_FW_QUEUE_PAGE_BCN_SHIFT|\
3581 NUM_OF_PAGE_IN_FW_QUEUE_PUB_DTM<<RSVD_FW_QUEUE_PAGE_PUB_SHIFT);
3586 write_nic_dword(dev, RQPN1, NUM_OF_PAGE_IN_FW_QUEUE_BK << RSVD_FW_QUEUE_PAGE_BK_SHIFT |\
3587 NUM_OF_PAGE_IN_FW_QUEUE_BE << RSVD_FW_QUEUE_PAGE_BE_SHIFT | \
3588 NUM_OF_PAGE_IN_FW_QUEUE_VI << RSVD_FW_QUEUE_PAGE_VI_SHIFT | \
3589 NUM_OF_PAGE_IN_FW_QUEUE_VO <<RSVD_FW_QUEUE_PAGE_VO_SHIFT);
3590 write_nic_dword(dev, RQPN2, NUM_OF_PAGE_IN_FW_QUEUE_MGNT << RSVD_FW_QUEUE_PAGE_MGNT_SHIFT);
3591 write_nic_dword(dev, RQPN3, APPLIED_RESERVED_QUEUE_IN_FW| \
3592 NUM_OF_PAGE_IN_FW_QUEUE_BCN<<RSVD_FW_QUEUE_PAGE_BCN_SHIFT|\
3593 NUM_OF_PAGE_IN_FW_QUEUE_PUB<<RSVD_FW_QUEUE_PAGE_PUB_SHIFT);
3596 rtl8192_tx_enable(dev);
3597 rtl8192_rx_enable(dev);
3598 //3Set Response Rate Setting Register
3599 // CCK rate is supported by default.
3600 // CCK rate will be filtered out only when associated AP does not support it.
3601 ulRegRead = (0xFFF00000 & read_nic_dword(dev, RRSR)) | RATE_ALL_OFDM_AG | RATE_ALL_CCK;
3602 write_nic_dword(dev, RRSR, ulRegRead);
3603 write_nic_dword(dev, RATR0+4*7, (RATE_ALL_OFDM_AG | RATE_ALL_CCK));
3606 // TODO: (it value is only for FPGA version). need to be changed!!2006.12.18, by Emily
3607 write_nic_byte(dev, ACK_TIMEOUT, 0x30);
3609 //rtl8192_actset_wirelessmode(dev,priv->RegWirelessMode);
3610 if(priv->ResetProgress == RESET_TYPE_NORESET)
3611 rtl8192_SetWirelessMode(dev, priv->ieee80211->mode);
3612 //-----------------------------------------------------------------------------
3613 // Set up security related. 070106, by rcnjko:
3614 // 1. Clear all H/W keys.
3615 // 2. Enable H/W encryption/decryption.
3616 //-----------------------------------------------------------------------------
3617 CamResetAllEntry(dev);
3619 u8 SECR_value = 0x0;
3620 SECR_value |= SCR_TxEncEnable;
3621 SECR_value |= SCR_RxDecEnable;
3622 SECR_value |= SCR_NoSKMC;
3623 write_nic_byte(dev, SECR, SECR_value);
3626 write_nic_word(dev, ATIMWND, 2);
3627 write_nic_word(dev, BCN_INTERVAL, 100);
3628 for (i=0; i<QOS_QUEUE_NUM; i++)
3629 write_nic_dword(dev, WDCAPARA_ADD[i], 0x005e4332);
3631 // Switching regulator controller: This is set temporarily.
3632 // It's not sure if this can be removed in the future.
3633 // PJ advised to leave it by default.
3635 write_nic_byte(dev, 0xbe, 0xc0);
3637 //2=======================================================
3638 // Set PHY related configuration defined in MAC register bank
3639 //2=======================================================
3640 rtl8192_phy_configmac(dev);
3642 if (priv->card_8192_version > (u8) VERSION_8190_BD) {
3643 rtl8192_phy_getTxPower(dev);
3644 rtl8192_phy_setTxPower(dev, priv->chan);
3648 tmpvalue = read_nic_byte(dev, IC_VERRSION);
3649 priv->IC_Cut = tmpvalue;
3650 RT_TRACE(COMP_INIT, "priv->IC_Cut = 0x%x\n", priv->IC_Cut);
3651 if(priv->IC_Cut >= IC_VersionCut_D)
3653 //pHalData->bDcut = TRUE;
3654 if(priv->IC_Cut == IC_VersionCut_D)
3655 RT_TRACE(COMP_INIT, "D-cut\n");
3656 if(priv->IC_Cut == IC_VersionCut_E)
3658 RT_TRACE(COMP_INIT, "E-cut\n");
3659 // HW SD suggest that we should not wirte this register too often, so driver
3660 // should readback this register. This register will be modified only when
3666 //pHalData->bDcut = FALSE;
3667 RT_TRACE(COMP_INIT, "Before C-cut\n");
3672 RT_TRACE(COMP_INIT, "Load Firmware!\n");
3673 bfirmwareok = init_firmware(dev);
3674 if(bfirmwareok != true) {
3675 rtStatus = RT_STATUS_FAILURE;
3678 RT_TRACE(COMP_INIT, "Load Firmware finished!\n");
3681 if(priv->ResetProgress == RESET_TYPE_NORESET)
3683 RT_TRACE(COMP_INIT, "RF Config Started!\n");
3684 rtStatus = rtl8192_phy_RFConfig(dev);
3685 if(rtStatus != RT_STATUS_SUCCESS)
3687 RT_TRACE(COMP_ERR, "RF Config failed\n");
3690 RT_TRACE(COMP_INIT, "RF Config Finished!\n");
3692 rtl8192_phy_updateInitGain(dev);
3694 /*---- Set CCK and OFDM Block "ON"----*/
3695 rtl8192_setBBreg(dev, rFPGA0_RFMOD, bCCKEn, 0x1);
3696 rtl8192_setBBreg(dev, rFPGA0_RFMOD, bOFDMEn, 0x1);
3700 write_nic_byte(dev, 0x87, 0x0);
3703 //2008.06.03, for WOL
3704 ucRegRead = read_nic_byte(dev, GPE);
3706 write_nic_byte(dev, GPE, ucRegRead);
3708 ucRegRead = read_nic_byte(dev, GPO);
3710 write_nic_byte(dev, GPO, ucRegRead);
3713 //2=======================================================
3715 //2=======================================================
3719 if(priv->RegRfOff == TRUE)
3720 { // User disable RF via registry.
3721 RT_TRACE((COMP_INIT|COMP_RF|COMP_POWER), "%s(): Turn off RF for RegRfOff ----------\n",__FUNCTION__);
3722 MgntActSet_RF_State(dev, eRfOff, RF_CHANGE_BY_SW);
3723 #if 0//cosa, ask SD3 willis and he doesn't know what is this for
3724 // Those action will be discard in MgntActSet_RF_State because off the same state
3725 for(eRFPath = 0; eRFPath <pHalData->NumTotalRFPath; eRFPath++)
3726 PHY_SetRFReg(Adapter, (RF90_RADIO_PATH_E)eRFPath, 0x4, 0xC00, 0x0);
3729 else if(priv->ieee80211->RfOffReason > RF_CHANGE_BY_PS)
3730 { // H/W or S/W RF OFF before sleep.
3731 RT_TRACE((COMP_INIT|COMP_RF|COMP_POWER), "%s(): Turn off RF for RfOffReason(%d) ----------\n", __FUNCTION__,priv->ieee80211->RfOffReason);
3732 MgntActSet_RF_State(dev, eRfOff, priv->ieee80211->RfOffReason);
3734 else if(priv->ieee80211->RfOffReason >= RF_CHANGE_BY_IPS)
3735 { // H/W or S/W RF OFF before sleep.
3736 RT_TRACE((COMP_INIT|COMP_RF|COMP_POWER), "%s(): Turn off RF for RfOffReason(%d) ----------\n", __FUNCTION__,priv->ieee80211->RfOffReason);
3737 MgntActSet_RF_State(dev, eRfOff, priv->ieee80211->RfOffReason);
3741 RT_TRACE((COMP_INIT|COMP_RF|COMP_POWER), "%s(): RF-ON \n",__FUNCTION__);
3742 priv->ieee80211->eRFPowerState = eRfOn;
3743 priv->ieee80211->RfOffReason = 0;
3744 //DrvIFIndicateCurrentPhyStatus(Adapter);
3746 //Adapter->HalFunc.LedControlHandler(Adapter, LED_CTL_POWER_ON);
3749 // If inactive power mode is enabled, disable rf while in disconnected state.
3750 // But we should still tell upper layer we are in rf on state.
3751 // 2007.07.16, by shien chang.
3753 //if(!Adapter->bInHctTest)
3754 //IPSEnter(Adapter);
3761 // We can force firmware to do RF-R/W
3762 if(priv->ieee80211->FwRWRF)
3763 priv->Rf_Mode = RF_OP_By_FW;
3765 priv->Rf_Mode = RF_OP_By_SW_3wire;
3767 priv->Rf_Mode = RF_OP_By_SW_3wire;
3771 if(priv->ResetProgress == RESET_TYPE_NORESET)
3773 dm_initialize_txpower_tracking(dev);
3775 tmpRegA= rtl8192_QueryBBReg(dev,rOFDM0_XATxIQImbalance,bMaskDWord);
3776 tmpRegC= rtl8192_QueryBBReg(dev,rOFDM0_XCTxIQImbalance,bMaskDWord);
3778 if(priv->rf_type == RF_2T4R){
3779 for(i = 0; i<TxBBGainTableLength; i++)
3781 if(tmpRegA == priv->txbbgain_table[i].txbbgain_value)
3783 priv->rfa_txpowertrackingindex= (u8)i;
3784 priv->rfa_txpowertrackingindex_real= (u8)i;
3785 priv->rfa_txpowertracking_default = priv->rfa_txpowertrackingindex;
3790 for(i = 0; i<TxBBGainTableLength; i++)
3792 if(tmpRegC == priv->txbbgain_table[i].txbbgain_value)
3794 priv->rfc_txpowertrackingindex= (u8)i;
3795 priv->rfc_txpowertrackingindex_real= (u8)i;
3796 priv->rfc_txpowertracking_default = priv->rfc_txpowertrackingindex;
3800 TempCCk = rtl8192_QueryBBReg(dev, rCCK0_TxFilter1, bMaskByte2);
3802 for(i=0 ; i<CCKTxBBGainTableLength ; i++)
3804 if(TempCCk == priv->cck_txbbgain_table[i].ccktxbb_valuearray[0])
3806 priv->CCKPresentAttentuation_20Mdefault =(u8) i;
3810 priv->CCKPresentAttentuation_40Mdefault = 0;
3811 priv->CCKPresentAttentuation_difference = 0;
3812 priv->CCKPresentAttentuation = priv->CCKPresentAttentuation_20Mdefault;
3813 RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex_initial = %d\n", priv->rfa_txpowertrackingindex);
3814 RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex_real__initial = %d\n", priv->rfa_txpowertrackingindex_real);
3815 RT_TRACE(COMP_POWER_TRACKING, "priv->rfc_txpowertrackingindex_initial = %d\n", priv->rfc_txpowertrackingindex);
3816 RT_TRACE(COMP_POWER_TRACKING, "priv->rfc_txpowertrackingindex_real_initial = %d\n", priv->rfc_txpowertrackingindex_real);
3817 RT_TRACE(COMP_POWER_TRACKING, "priv->CCKPresentAttentuation_difference_initial = %d\n", priv->CCKPresentAttentuation_difference);
3818 RT_TRACE(COMP_POWER_TRACKING, "priv->CCKPresentAttentuation_initial = %d\n", priv->CCKPresentAttentuation);
3822 if(priv->ResetProgress == RESET_TYPE_NORESET)
3824 dm_initialize_txpower_tracking(dev);
3826 if(priv->IC_Cut >= IC_VersionCut_D)
3828 tmpRegA= rtl8192_QueryBBReg(dev,rOFDM0_XATxIQImbalance,bMaskDWord);
3829 tmpRegC= rtl8192_QueryBBReg(dev,rOFDM0_XCTxIQImbalance,bMaskDWord);
3830 for(i = 0; i<TxBBGainTableLength; i++)
3832 if(tmpRegA == priv->txbbgain_table[i].txbbgain_value)
3834 priv->rfa_txpowertrackingindex= (u8)i;
3835 priv->rfa_txpowertrackingindex_real= (u8)i;
3836 priv->rfa_txpowertracking_default = priv->rfa_txpowertrackingindex;
3841 TempCCk = rtl8192_QueryBBReg(dev, rCCK0_TxFilter1, bMaskByte2);
3843 for(i=0 ; i<CCKTxBBGainTableLength ; i++)
3845 if(TempCCk == priv->cck_txbbgain_table[i].ccktxbb_valuearray[0])
3847 priv->CCKPresentAttentuation_20Mdefault =(u8) i;
3851 priv->CCKPresentAttentuation_40Mdefault = 0;
3852 priv->CCKPresentAttentuation_difference = 0;
3853 priv->CCKPresentAttentuation = priv->CCKPresentAttentuation_20Mdefault;
3854 RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex_initial = %d\n", priv->rfa_txpowertrackingindex);
3855 RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex_real__initial = %d\n", priv->rfa_txpowertrackingindex_real);
3856 RT_TRACE(COMP_POWER_TRACKING, "priv->CCKPresentAttentuation_difference_initial = %d\n", priv->CCKPresentAttentuation_difference);
3857 RT_TRACE(COMP_POWER_TRACKING, "priv->CCKPresentAttentuation_initial = %d\n", priv->CCKPresentAttentuation);
3858 priv->btxpower_tracking = FALSE;//TEMPLY DISABLE
3863 rtl8192_irq_enable(dev);
3864 priv->being_init_adapter = false;
3869 void rtl8192_prepare_beacon(struct r8192_priv *priv)
3871 struct sk_buff *skb;
3872 //unsigned long flags;
3875 skb = ieee80211_get_beacon(priv->ieee80211);
3876 tcb_desc = (cb_desc *)(skb->cb + 8);
3877 //printk("===========> %s\n", __FUNCTION__);
3878 //spin_lock_irqsave(&priv->tx_lock,flags);
3879 /* prepare misc info for the beacon xmit */
3880 tcb_desc->queue_index = BEACON_QUEUE;
3881 /* IBSS does not support HT yet, use 1M defautly */
3882 tcb_desc->data_rate = 2;
3883 tcb_desc->RATRIndex = 7;
3884 tcb_desc->bTxDisableRateFallBack = 1;
3885 tcb_desc->bTxUseDriverAssingedRate = 1;
3887 skb_push(skb, priv->ieee80211->tx_headroom);
3889 rtl8192_tx(priv->ieee80211->dev,skb);
3891 //spin_unlock_irqrestore (&priv->tx_lock, flags);
3895 void rtl8192_beacon_tx_enable(struct net_device *dev)
3897 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
3899 rtl8180_set_mode(dev,EPROM_CMD_CONFIG);
3900 #ifdef CONFIG_RTL8185B
3901 priv->dma_poll_stop_mask &= ~(TPPOLLSTOP_BQ);MgntQuery_MgntFrameTxRateMgntQuery_MgntFrameTxRate
3902 write_nic_byte(dev,TPPollStop, priv->dma_poll_mask);
3904 priv->dma_poll_mask &=~(1<<TX_DMA_STOP_BEACON_SHIFT);
3905 write_nic_byte(dev,TX_DMA_POLLING,priv->dma_poll_mask);
3907 rtl8180_set_mode(dev,EPROM_CMD_NORMAL);
3912 /* this configures registers for beacon tx and enables it via
3913 * rtl8192_beacon_tx_enable(). rtl8192_beacon_tx_disable() might
3914 * be used to stop beacon transmission
3916 void rtl8192_start_beacon(struct net_device *dev)
3918 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
3919 struct ieee80211_network *net = &priv->ieee80211->current_network;
3924 DMESG("Enabling beacon TX");
3925 //rtl8192_prepare_beacon(dev);
3926 rtl8192_irq_disable(dev);
3927 //rtl8192_beacon_tx_enable(dev);
3930 write_nic_word(dev, ATIMWND, 2);
3932 /* Beacon interval (in unit of TU) */
3933 write_nic_word(dev, BCN_INTERVAL, net->beacon_interval);
3936 * DrvErlyInt (in unit of TU).
3937 * (Time to send interrupt to notify driver to c
3938 * hange beacon content)
3940 write_nic_word(dev, BCN_DRV_EARLY_INT, 10);
3943 * BcnDMATIM(in unit of us).
3944 * Indicates the time before TBTT to perform beacon queue DMA
3946 write_nic_word(dev, BCN_DMATIME, 256);
3949 * Force beacon frame transmission even after receiving
3950 * beacon frame from other ad hoc STA
3952 write_nic_byte(dev, BCN_ERR_THRESH, 100);
3954 /* Set CW and IFS */
3955 BcnTimeCfg |= BcnCW<<BCN_TCFG_CW_SHIFT;
3956 BcnTimeCfg |= BcnIFS<<BCN_TCFG_IFS;
3957 write_nic_word(dev, BCN_TCFG, BcnTimeCfg);
3960 /* enable the interrupt for ad-hoc process */
3961 rtl8192_irq_enable(dev);
3963 /***************************************************************************
3964 -------------------------------NET STUFF---------------------------
3965 ***************************************************************************/
3967 static struct net_device_stats *rtl8192_stats(struct net_device *dev)
3969 struct r8192_priv *priv = ieee80211_priv(dev);
3971 return &priv->ieee80211->stats;
3977 static bool HalTxCheckStuck8190Pci(struct net_device *dev)
3979 u16 RegTxCounter = read_nic_word(dev, 0x128);
3980 struct r8192_priv *priv = ieee80211_priv(dev);
3981 bool bStuck = FALSE;
3982 RT_TRACE(COMP_RESET,"%s():RegTxCounter is %d,TxCounter is %d\n",__FUNCTION__,RegTxCounter,priv->TxCounter);
3983 if(priv->TxCounter==RegTxCounter)
3986 priv->TxCounter = RegTxCounter;
3992 * <Assumption: RT_TX_SPINLOCK is acquired.>
3993 * First added: 2006.11.19 by emily
3996 TxCheckStuck(struct net_device *dev)
3998 struct r8192_priv *priv = ieee80211_priv(dev);
4000 ptx_ring head=NULL,tail=NULL,txring = NULL;
4001 u8 ResetThreshold = NIC_SEND_HANG_THRESHOLD_POWERSAVE;
4002 bool bCheckFwTxCnt = false;
4003 //unsigned long flags;
4006 // Decide Stuch threshold according to current power save mode
4008 //printk("++++++++++++>%s()\n",__FUNCTION__);
4009 switch (priv->ieee80211->dot11PowerSaveMode)
4011 // The threshold value may required to be adjusted .
4012 case eActive: // Active/Continuous access.
4013 ResetThreshold = NIC_SEND_HANG_THRESHOLD_NORMAL;
4015 case eMaxPs: // Max power save mode.
4016 ResetThreshold = NIC_SEND_HANG_THRESHOLD_POWERSAVE;
4018 case eFastPs: // Fast power save mode.
4019 ResetThreshold = NIC_SEND_HANG_THRESHOLD_POWERSAVE;
4024 // Check whether specific tcb has been queued for a specific time
4026 for(QueueID = 0; QueueID < MAX_TX_QUEUE; QueueID++)
4030 if(QueueID == TXCMD_QUEUE)
4035 tail=priv->txmapringtail;
4036 head=priv->txmapringhead;
4040 tail=priv->txbkpringtail;
4041 head=priv->txbkpringhead;
4045 tail=priv->txbepringtail;
4046 head=priv->txbepringhead;
4050 tail=priv->txvipringtail;
4051 head=priv->txvipringhead;
4055 tail=priv->txvopringtail;
4056 head=priv->txvopringhead;
4071 RT_TRACE(COMP_ERR,"%s():txring is NULL , BUG!\n",__FUNCTION__);
4074 txring->nStuckCount++;
4076 if(txring->nStuckCount > ResetThreshold)
4078 RT_TRACE( COMP_RESET, "<== TxCheckStuck()\n" );
4079 return RESET_TYPE_NORMAL;
4082 bCheckFwTxCnt = TRUE;
4088 if(HalTxCheckStuck8190Pci(dev))
4090 RT_TRACE(COMP_RESET, "TxCheckStuck(): Fw indicates no Tx condition! \n");
4091 return RESET_TYPE_SILENT;
4095 return RESET_TYPE_NORESET;
4099 static bool HalRxCheckStuck8190Pci(struct net_device *dev)
4101 struct r8192_priv *priv = ieee80211_priv(dev);
4102 u16 RegRxCounter = read_nic_word(dev, 0x130);
4103 bool bStuck = FALSE;
4104 static u8 rx_chk_cnt = 0;
4105 RT_TRACE(COMP_RESET,"%s(): RegRxCounter is %d,RxCounter is %d\n",__FUNCTION__,RegRxCounter,priv->RxCounter);
4106 // If rssi is small, we should check rx for long time because of bad rx.
4107 // or maybe it will continuous silent reset every 2 seconds.
4109 if(priv->undecorated_smoothed_pwdb >= (RateAdaptiveTH_High+5))
4111 rx_chk_cnt = 0; //high rssi, check rx stuck right now.
4113 else if(priv->undecorated_smoothed_pwdb < (RateAdaptiveTH_High+5) &&
4114 ((priv->CurrentChannelBW!=HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb>=RateAdaptiveTH_Low_40M) ||
4115 (priv->CurrentChannelBW==HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb>=RateAdaptiveTH_Low_20M)) )
4127 else if(((priv->CurrentChannelBW!=HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb<RateAdaptiveTH_Low_40M) ||
4128 (priv->CurrentChannelBW==HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb<RateAdaptiveTH_Low_20M)) &&
4129 priv->undecorated_smoothed_pwdb >= VeryLowRSSI)
4133 //DbgPrint("RSSI < %d && RSSI >= %d, no check this time \n", RateAdaptiveTH_Low, VeryLowRSSI);
4139 //DbgPrint("RSSI < %d && RSSI >= %d, check this time \n", RateAdaptiveTH_Low, VeryLowRSSI);
4146 //DbgPrint("RSSI <= %d, no check this time \n", VeryLowRSSI);
4152 //DbgPrint("RSSI <= %d, check this time \n", VeryLowRSSI);
4161 if(priv->RxCounter==RegRxCounter)
4164 priv->RxCounter = RegRxCounter;
4169 static RESET_TYPE RxCheckStuck(struct net_device *dev)
4172 if(HalRxCheckStuck8190Pci(dev))
4174 RT_TRACE(COMP_RESET, "RxStuck Condition\n");
4175 return RESET_TYPE_SILENT;
4178 return RESET_TYPE_NORESET;
4182 rtl819x_ifcheck_resetornot(struct net_device *dev)
4184 struct r8192_priv *priv = ieee80211_priv(dev);
4185 RESET_TYPE TxResetType = RESET_TYPE_NORESET;
4186 RESET_TYPE RxResetType = RESET_TYPE_NORESET;
4187 RT_RF_POWER_STATE rfState;
4189 rfState = priv->ieee80211->eRFPowerState;
4191 TxResetType = TxCheckStuck(dev);
4193 if( rfState != eRfOff &&
4194 /*ADAPTER_TEST_STATUS_FLAG(Adapter, ADAPTER_STATUS_FW_DOWNLOAD_FAILURE)) &&*/
4195 (priv->ieee80211->iw_mode != IW_MODE_ADHOC))
4197 // If driver is in the status of firmware download failure , driver skips RF initialization and RF is
4198 // in turned off state. Driver should check whether Rx stuck and do silent reset. And
4199 // if driver is in firmware download failure status, driver should initialize RF in the following
4200 // silent reset procedure Emily, 2008.01.21
4202 // Driver should not check RX stuck in IBSS mode because it is required to
4203 // set Check BSSID in order to send beacon, however, if check BSSID is
4204 // set, STA cannot hear any packet a all. Emily, 2008.04.12
4205 RxResetType = RxCheckStuck(dev);
4209 RT_TRACE(COMP_RESET,"%s(): TxResetType is %d, RxResetType is %d\n",__FUNCTION__,TxResetType,RxResetType);
4210 if(TxResetType==RESET_TYPE_NORMAL || RxResetType==RESET_TYPE_NORMAL)
4211 return RESET_TYPE_NORMAL;
4212 else if(TxResetType==RESET_TYPE_SILENT || RxResetType==RESET_TYPE_SILENT)
4213 return RESET_TYPE_SILENT;
4215 return RESET_TYPE_NORESET;
4220 static void CamRestoreAllEntry(struct net_device *dev)
4223 struct r8192_priv *priv = ieee80211_priv(dev);
4224 u8* MacAddr = priv->ieee80211->current_network.bssid;
4226 static u8 CAM_CONST_ADDR[4][6] = {
4227 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
4228 {0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
4229 {0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
4230 {0x00, 0x00, 0x00, 0x00, 0x00, 0x03}};
4231 static u8 CAM_CONST_BROAD[] =
4232 {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
4234 RT_TRACE(COMP_SEC, "CamRestoreAllEntry: \n");
4237 if ((priv->ieee80211->pairwise_key_type == KEY_TYPE_WEP40)||
4238 (priv->ieee80211->pairwise_key_type == KEY_TYPE_WEP104))
4241 for(EntryId=0; EntryId<4; EntryId++)
4244 MacAddr = CAM_CONST_ADDR[EntryId];
4248 priv->ieee80211->pairwise_key_type,
4256 else if(priv->ieee80211->pairwise_key_type == KEY_TYPE_TKIP)
4260 if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
4264 priv->ieee80211->pairwise_key_type,
4272 priv->ieee80211->pairwise_key_type,
4278 else if(priv->ieee80211->pairwise_key_type == KEY_TYPE_CCMP)
4282 if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
4286 priv->ieee80211->pairwise_key_type,
4294 priv->ieee80211->pairwise_key_type,
4303 if(priv->ieee80211->group_key_type == KEY_TYPE_TKIP)
4305 MacAddr = CAM_CONST_BROAD;
4306 for(EntryId=1 ; EntryId<4 ; EntryId++)
4312 priv->ieee80211->group_key_type,
4318 if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
4322 priv->ieee80211->group_key_type,
4327 else if(priv->ieee80211->group_key_type == KEY_TYPE_CCMP)
4329 MacAddr = CAM_CONST_BROAD;
4330 for(EntryId=1; EntryId<4 ; EntryId++)
4336 priv->ieee80211->group_key_type,
4343 if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
4347 priv->ieee80211->group_key_type,
4354 void rtl8192_cancel_deferred_work(struct r8192_priv* priv);
4355 int _rtl8192_up(struct net_device *dev);
4358 * This function is used to fix Tx/Rx stop bug temporarily.
4359 * This function will do "system reset" to NIC when Tx or Rx is stuck.
4360 * The method checking Tx/Rx stuck of this function is supported by FW,
4361 * which reports Tx and Rx counter to register 0x128 and 0x130.
4363 static void rtl819x_ifsilentreset(struct net_device *dev)
4365 struct r8192_priv *priv = ieee80211_priv(dev);
4367 int reset_status = 0;
4368 struct ieee80211_device *ieee = priv->ieee80211;
4371 // 2007.07.20. If we need to check CCK stop, please uncomment this line.
4372 //bStuck = Adapter->HalFunc.CheckHWStopHandler(Adapter);
4374 if(priv->ResetProgress==RESET_TYPE_NORESET)
4378 RT_TRACE(COMP_RESET,"=========>Reset progress!! \n");
4380 // Set the variable for reset.
4381 priv->ResetProgress = RESET_TYPE_SILENT;
4382 // rtl8192_close(dev);
4384 down(&priv->wx_sem);
4387 RT_TRACE(COMP_ERR,"%s():the driver is not up! return\n",__FUNCTION__);
4392 RT_TRACE(COMP_RESET,"%s():======>start to down the driver\n",__FUNCTION__);
4393 if(!netif_queue_stopped(dev))
4394 netif_stop_queue(dev);
4396 dm_backup_dynamic_mechanism_state(dev);
4398 rtl8192_irq_disable(dev);
4399 rtl8192_cancel_deferred_work(priv);
4401 del_timer_sync(&priv->watch_dog_timer);
4402 ieee->sync_scan_hurryup = 1;
4403 if(ieee->state == IEEE80211_LINKED)
4405 down(&ieee->wx_sem);
4406 printk("ieee->state is IEEE80211_LINKED\n");
4407 ieee80211_stop_send_beacons(priv->ieee80211);
4408 del_timer_sync(&ieee->associate_timer);
4409 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
4410 cancel_delayed_work(&ieee->associate_retry_wq);
4412 ieee80211_stop_scan(ieee);
4413 netif_carrier_off(dev);
4417 printk("ieee->state is NOT LINKED\n");
4418 ieee80211_softmac_stop_protocol(priv->ieee80211);
4420 rtl8192_rtx_disable(dev);
4422 RT_TRACE(COMP_RESET,"%s():<==========down process is finished\n",__FUNCTION__);
4423 RT_TRACE(COMP_RESET,"%s():===========>start to up the driver\n",__FUNCTION__);
4424 reset_status = _rtl8192_up(dev);
4426 RT_TRACE(COMP_RESET,"%s():<===========up process is finished\n",__FUNCTION__);
4427 if(reset_status == -1)
4436 RT_TRACE(COMP_ERR," ERR!!! %s(): Reset Failed!!\n",__FUNCTION__);
4440 ieee->is_silent_reset = 1;
4442 EnableHWSecurityConfig8192(dev);
4444 if(ieee->state == IEEE80211_LINKED && ieee->iw_mode == IW_MODE_INFRA)
4446 ieee->set_chan(ieee->dev, ieee->current_network.channel);
4449 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
4450 queue_work(ieee->wq, &ieee->associate_complete_wq);
4452 schedule_task(&ieee->associate_complete_wq);
4457 else if(ieee->state == IEEE80211_LINKED && ieee->iw_mode == IW_MODE_ADHOC)
4459 ieee->set_chan(ieee->dev, ieee->current_network.channel);
4460 ieee->link_change(ieee->dev);
4462 // notify_wx_assoc_event(ieee);
4464 ieee80211_start_send_beacons(ieee);
4466 if (ieee->data_hard_resume)
4467 ieee->data_hard_resume(ieee->dev);
4468 netif_carrier_on(ieee->dev);
4472 CamRestoreAllEntry(dev);
4474 // Restore the previous setting for all dynamic mechanism
4475 dm_restore_dynamic_mechanism_state(dev);
4477 priv->ResetProgress = RESET_TYPE_NORESET;
4478 priv->reset_count++;
4480 priv->bForcedSilentReset =false;
4481 priv->bResetInProgress = false;
4483 // For test --> force write UFWP.
4484 write_nic_byte(dev, UFWP, 1);
4485 RT_TRACE(COMP_RESET, "Reset finished!! ====>[%d]\n", priv->reset_count);
4491 void InactivePsWorkItemCallback(struct net_device *dev)
4493 struct r8192_priv *priv = ieee80211_priv(dev);
4494 PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->ieee80211->PowerSaveControl));
4497 RT_TRACE(COMP_POWER, "InactivePsWorkItemCallback() ---------> \n");
4499 // This flag "bSwRfProcessing", indicates the status of IPS procedure, should be set if the IPS workitem
4500 // is really scheduled.
4501 // The old code, sets this flag before scheduling the IPS workitem and however, at the same time the
4502 // previous IPS workitem did not end yet, fails to schedule the current workitem. Thus, bSwRfProcessing
4503 // blocks the IPS procedure of switching RF.
4504 // By Bruce, 2007-12-25.
4506 pPSC->bSwRfProcessing = TRUE;
4508 RT_TRACE(COMP_RF, "InactivePsWorkItemCallback(): Set RF to %s.\n", \
4509 pPSC->eInactivePowerState == eRfOff?"OFF":"ON");
4512 MgntActSet_RF_State(dev, pPSC->eInactivePowerState, RF_CHANGE_BY_IPS);
4515 // To solve CAM values miss in RF OFF, rewrite CAM values after RF ON. By Bruce, 2007-09-20.
4518 if(pPSC->eInactivePowerState == eRfOn)
4519 CamRestoreAllEntry(dev);
4521 pPSC->bSwRfProcessing = FALSE;
4522 RT_TRACE(COMP_POWER, "InactivePsWorkItemCallback() <--------- \n");
4527 // Enter the inactive power save mode. RF will be off
4528 // 2007.08.17, by shien chang.
4531 IPSEnter(struct net_device *dev)
4533 struct r8192_priv *priv = ieee80211_priv(dev);
4534 PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->ieee80211->PowerSaveControl));
4535 RT_RF_POWER_STATE rtState;
4537 if (pPSC->bInactivePs)
4539 rtState = priv->ieee80211->eRFPowerState;
4541 // Added by Bruce, 2007-12-25.
4542 // Do not enter IPS in the following conditions:
4543 // (1) RF is already OFF or Sleep
4544 // (2) bSwRfProcessing (indicates the IPS is still under going)
4545 // (3) Connectted (only disconnected can trigger IPS)
4546 // (4) IBSS (send Beacon)
4547 // (5) AP mode (send Beacon)
4549 if (rtState == eRfOn && !pPSC->bSwRfProcessing
4550 && (priv->ieee80211->state != IEEE80211_LINKED) )
4552 RT_TRACE(COMP_RF,"IPSEnter(): Turn off RF.\n");
4553 pPSC->eInactivePowerState = eRfOff;
4554 // queue_work(priv->priv_wq,&(pPSC->InactivePsWorkItem));
4555 InactivePsWorkItemCallback(dev);
4562 // Leave the inactive power save mode, RF will be on.
4563 // 2007.08.17, by shien chang.
4566 IPSLeave(struct net_device *dev)
4568 struct r8192_priv *priv = ieee80211_priv(dev);
4569 PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->ieee80211->PowerSaveControl));
4570 RT_RF_POWER_STATE rtState;
4572 if (pPSC->bInactivePs)
4574 rtState = priv->ieee80211->eRFPowerState;
4575 if (rtState != eRfOn && !pPSC->bSwRfProcessing && priv->ieee80211->RfOffReason <= RF_CHANGE_BY_IPS)
4577 RT_TRACE(COMP_POWER, "IPSLeave(): Turn on RF.\n");
4578 pPSC->eInactivePowerState = eRfOn;
4579 // queue_work(priv->priv_wq,&(pPSC->InactivePsWorkItem));
4580 InactivePsWorkItemCallback(dev);
4586 static void rtl819x_update_rxcounts(
4587 struct r8192_priv *priv,
4596 *TotalRxDataNum = 0;
4598 SlotIndex = (priv->ieee80211->LinkDetectInfo.SlotIndex++)%(priv->ieee80211->LinkDetectInfo.SlotNum);
4599 priv->ieee80211->LinkDetectInfo.RxBcnNum[SlotIndex] = priv->ieee80211->LinkDetectInfo.NumRecvBcnInPeriod;
4600 priv->ieee80211->LinkDetectInfo.RxDataNum[SlotIndex] = priv->ieee80211->LinkDetectInfo.NumRecvDataInPeriod;
4601 for( i=0; i<priv->ieee80211->LinkDetectInfo.SlotNum; i++ ){
4602 *TotalRxBcnNum += priv->ieee80211->LinkDetectInfo.RxBcnNum[i];
4603 *TotalRxDataNum += priv->ieee80211->LinkDetectInfo.RxDataNum[i];
4608 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
4609 void rtl819x_watchdog_wqcallback(struct work_struct *work)
4611 struct delayed_work *dwork = container_of(work,struct delayed_work,work);
4612 struct r8192_priv *priv = container_of(dwork,struct r8192_priv,watch_dog_wq);
4613 struct net_device *dev = priv->ieee80211->dev;
4615 extern void rtl819x_watchdog_wqcallback(struct net_device *dev)
4617 struct r8192_priv *priv = ieee80211_priv(dev);
4619 struct ieee80211_device* ieee = priv->ieee80211;
4620 RESET_TYPE ResetType = RESET_TYPE_NORESET;
4621 static u8 check_reset_cnt=0;
4622 unsigned long flags;
4623 bool bBusyTraffic = false;
4624 static u8 last_time = 0;
4627 hal_dm_watchdog(dev);
4629 // printk("watch_dog ENABLE_IPS\n");
4630 if(ieee->actscanning == false){
4631 if((ieee->iw_mode != IW_MODE_ADHOC) && (ieee->state == IEEE80211_NOLINK) && (ieee->beinretry == false) && (ieee->eRFPowerState == eRfOn) && !ieee->is_set_key){
4632 if(ieee->PowerSaveControl.ReturnPoint == IPS_CALLBACK_NONE){
4633 printk("====================>haha:IPSEnter()\n");
4635 //ieee80211_stop_scan(priv->ieee80211);
4640 {//to get busy traffic condition
4641 if(ieee->state == IEEE80211_LINKED)
4643 if( ieee->LinkDetectInfo.NumRxOkInPeriod> 666 ||
4644 ieee->LinkDetectInfo.NumTxOkInPeriod> 666 ) {
4645 bBusyTraffic = true;
4649 ieee->LinkDetectInfo.NumRxOkInPeriod = 0;
4650 ieee->LinkDetectInfo.NumTxOkInPeriod = 0;
4651 ieee->LinkDetectInfo.bBusyTraffic = bBusyTraffic;
4655 //added by amy for AP roaming
4658 if(ieee->state == IEEE80211_LINKED && ieee->iw_mode == IW_MODE_INFRA)
4660 u32 TotalRxBcnNum = 0;
4661 u32 TotalRxDataNum = 0;
4663 rtl819x_update_rxcounts(priv, &TotalRxBcnNum, &TotalRxDataNum);
4664 if((TotalRxBcnNum+TotalRxDataNum) == 0)
4666 if( ieee->eRFPowerState == eRfOff)
4667 RT_TRACE(COMP_ERR,"========>%s()\n",__FUNCTION__);
4668 printk("===>%s(): AP is power off,connect another one\n",__FUNCTION__);
4669 // Dot11d_Reset(dev);
4670 ieee->state = IEEE80211_ASSOCIATING;
4671 notify_wx_assoc_event(priv->ieee80211);
4672 RemovePeerTS(priv->ieee80211,priv->ieee80211->current_network.bssid);
4673 ieee->is_roaming = true;
4674 ieee->is_set_key = false;
4675 ieee->link_change(dev);
4676 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
4677 queue_work(ieee->wq, &ieee->associate_procedure_wq);
4679 schedule_task(&ieee->associate_procedure_wq);
4683 ieee->LinkDetectInfo.NumRecvBcnInPeriod=0;
4684 ieee->LinkDetectInfo.NumRecvDataInPeriod=0;
4687 //check if reset the driver
4688 spin_lock_irqsave(&priv->tx_lock,flags);
4689 if(check_reset_cnt++ >= 3 && !ieee->is_roaming && (last_time != 1))
4691 ResetType = rtl819x_ifcheck_resetornot(dev);
4692 check_reset_cnt = 3;
4693 //DbgPrint("Start to check silent reset\n");
4695 spin_unlock_irqrestore(&priv->tx_lock,flags);
4696 if(!priv->bDisableNormalResetCheck && ResetType == RESET_TYPE_NORMAL)
4698 priv->ResetProgress = RESET_TYPE_NORMAL;
4699 RT_TRACE(COMP_RESET,"%s(): NOMAL RESET\n",__FUNCTION__);
4702 /* disable silent reset temply 2008.9.11*/
4704 if( ((priv->force_reset) || (!priv->bDisableNormalResetCheck && ResetType==RESET_TYPE_SILENT))) // This is control by OID set in Pomelo
4707 rtl819x_ifsilentreset(dev);
4712 priv->force_reset = false;
4713 priv->bForcedSilentReset = false;
4714 priv->bResetInProgress = false;
4715 RT_TRACE(COMP_TRACE, " <==RtUsbCheckForHangWorkItemCallback()\n");
4719 void watch_dog_timer_callback(unsigned long data)
4721 struct r8192_priv *priv = ieee80211_priv((struct net_device *) data);
4722 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
4723 queue_delayed_work(priv->priv_wq,&priv->watch_dog_wq,0);
4725 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
4726 schedule_task(&priv->watch_dog_wq);
4728 queue_work(priv->priv_wq,&priv->watch_dog_wq);
4731 mod_timer(&priv->watch_dog_timer, jiffies + MSECS(IEEE80211_WATCH_DOG_TIME));
4734 int _rtl8192_up(struct net_device *dev)
4736 struct r8192_priv *priv = ieee80211_priv(dev);
4738 RT_STATUS init_status = RT_STATUS_SUCCESS;
4740 priv->ieee80211->ieee_up=1;
4741 RT_TRACE(COMP_INIT, "Bringing up iface");
4743 init_status = rtl8192_adapter_start(dev);
4744 if(init_status != RT_STATUS_SUCCESS)
4746 RT_TRACE(COMP_ERR,"ERR!!! %s(): initialization is failed!\n",__FUNCTION__);
4749 RT_TRACE(COMP_INIT, "start adapter finished\n");
4751 if(priv->ieee80211->eRFPowerState!=eRfOn)
4752 MgntActSet_RF_State(dev, eRfOn, priv->ieee80211->RfOffReason);
4754 if(priv->ieee80211->state != IEEE80211_LINKED)
4755 ieee80211_softmac_start_protocol(priv->ieee80211);
4756 ieee80211_reset_queue(priv->ieee80211);
4757 watch_dog_timer_callback((unsigned long) dev);
4758 if(!netif_queue_stopped(dev))
4759 netif_start_queue(dev);
4761 netif_wake_queue(dev);
4767 static int rtl8192_open(struct net_device *dev)
4769 struct r8192_priv *priv = ieee80211_priv(dev);
4772 down(&priv->wx_sem);
4773 ret = rtl8192_up(dev);
4780 int rtl8192_up(struct net_device *dev)
4782 struct r8192_priv *priv = ieee80211_priv(dev);
4784 if (priv->up == 1) return -1;
4786 return _rtl8192_up(dev);
4790 static int rtl8192_close(struct net_device *dev)
4792 struct r8192_priv *priv = ieee80211_priv(dev);
4795 down(&priv->wx_sem);
4797 ret = rtl8192_down(dev);
4805 int rtl8192_down(struct net_device *dev)
4807 struct r8192_priv *priv = ieee80211_priv(dev);
4813 if (priv->up == 0) return -1;
4816 priv->ieee80211->ieee_up = 0;
4817 RT_TRACE(COMP_DOWN, "==========>%s()\n", __FUNCTION__);
4819 if (!netif_queue_stopped(dev))
4820 netif_stop_queue(dev);
4822 rtl8192_irq_disable(dev);
4824 if(!priv->ieee80211->bSupportRemoteWakeUp) {
4825 MgntActSet_RF_State(dev, eRfOff, RF_CHANGE_BY_INIT);
4826 // 2006.11.30. System reset bit
4827 ulRegRead = read_nic_dword(dev, CPU_GEN);
4828 ulRegRead|=CPU_GEN_SYSTEM_RESET;
4829 write_nic_dword(dev, CPU_GEN, ulRegRead);
4831 //2008.06.03 for WOL
4832 write_nic_dword(dev, WFCRC0, 0xffffffff);
4833 write_nic_dword(dev, WFCRC1, 0xffffffff);
4834 write_nic_dword(dev, WFCRC2, 0xffffffff);
4837 ucRegRead = read_nic_byte(dev, GPO);
4839 write_nic_byte(dev, GPO, ucRegRead);
4841 //Write PMR register
4842 write_nic_byte(dev, PMR, 0x5);
4843 //Disable tx, enanble rx
4844 write_nic_byte(dev, MacBlkCtrl, 0xa);
4847 // flush_scheduled_work();
4848 rtl8192_cancel_deferred_work(priv);
4850 del_timer_sync(&priv->watch_dog_timer);
4852 ieee80211_softmac_stop_protocol(priv->ieee80211);
4854 MgntActSet_RF_State(dev, eRfOff, RF_CHANGE_BY_INIT);
4856 rtl8192_rtx_disable(dev);
4857 memset(&priv->ieee80211->current_network, 0 , offsetof(struct ieee80211_network, list));
4859 RT_TRACE(COMP_DOWN, "<==========%s()\n", __FUNCTION__);
4865 void rtl8192_commit(struct net_device *dev)
4867 struct r8192_priv *priv = ieee80211_priv(dev);
4869 if (priv->up == 0) return ;
4872 ieee80211_softmac_stop_protocol(priv->ieee80211);
4874 rtl8192_irq_disable(dev);
4875 rtl8192_rtx_disable(dev);
4880 void rtl8192_restart(struct net_device *dev)
4882 struct r8192_priv *priv = ieee80211_priv(dev);
4884 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
4885 void rtl8192_restart(struct work_struct *work)
4887 struct r8192_priv *priv = container_of(work, struct r8192_priv, reset_wq);
4888 struct net_device *dev = priv->ieee80211->dev;
4890 void rtl8192_restart(struct net_device *dev)
4893 struct r8192_priv *priv = ieee80211_priv(dev);
4896 down(&priv->wx_sem);
4898 rtl8192_commit(dev);
4903 static void r8192_set_multicast(struct net_device *dev)
4905 struct r8192_priv *priv = ieee80211_priv(dev);
4908 //down(&priv->wx_sem);
4912 promisc = (dev->flags & IFF_PROMISC) ? 1:0;
4914 if (promisc != priv->promisc) {
4916 // rtl8192_commit(dev);
4919 priv->promisc = promisc;
4921 //schedule_work(&priv->reset_wq);
4922 //up(&priv->wx_sem);
4926 static int r8192_set_mac_adr(struct net_device *dev, void *mac)
4928 struct r8192_priv *priv = ieee80211_priv(dev);
4929 struct sockaddr *addr = mac;
4931 down(&priv->wx_sem);
4933 memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
4935 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
4936 schedule_work(&priv->reset_wq);
4938 schedule_task(&priv->reset_wq);
4945 /* based on ipw2200 driver */
4946 static int rtl8192_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
4948 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
4949 struct iwreq *wrq = (struct iwreq *)rq;
4951 struct ieee80211_device *ieee = priv->ieee80211;
4953 u8 broadcast_addr[6] = {0xff,0xff,0xff,0xff,0xff,0xff};
4954 struct iw_point *p = &wrq->u.data;
4955 struct ieee_param *ipw = NULL;//(struct ieee_param *)wrq->u.data.pointer;
4957 down(&priv->wx_sem);
4960 if (p->length < sizeof(struct ieee_param) || !p->pointer){
4965 ipw = (struct ieee_param *)kmalloc(p->length, GFP_KERNEL);
4970 if (copy_from_user(ipw, p->pointer, p->length)) {
4977 case RTL_IOCTL_WPA_SUPPLICANT:
4978 //parse here for HW security
4979 if (ipw->cmd == IEEE_CMD_SET_ENCRYPTION)
4981 if (ipw->u.crypt.set_tx)
4983 if (strcmp(ipw->u.crypt.alg, "CCMP") == 0)
4984 ieee->pairwise_key_type = KEY_TYPE_CCMP;
4985 else if (strcmp(ipw->u.crypt.alg, "TKIP") == 0)
4986 ieee->pairwise_key_type = KEY_TYPE_TKIP;
4987 else if (strcmp(ipw->u.crypt.alg, "WEP") == 0)
4989 if (ipw->u.crypt.key_len == 13)
4990 ieee->pairwise_key_type = KEY_TYPE_WEP104;
4991 else if (ipw->u.crypt.key_len == 5)
4992 ieee->pairwise_key_type = KEY_TYPE_WEP40;
4995 ieee->pairwise_key_type = KEY_TYPE_NA;
4997 if (ieee->pairwise_key_type)
4999 memcpy((u8*)key, ipw->u.crypt.key, 16);
5000 EnableHWSecurityConfig8192(dev);
5001 //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!
5003 setKey(dev, 4, ipw->u.crypt.idx, ieee->pairwise_key_type, (u8*)ieee->ap_mac_addr, 0, key);
5004 if (ieee->auth_mode != 2) //LEAP WEP will never set this.
5005 setKey(dev, ipw->u.crypt.idx, ipw->u.crypt.idx, ieee->pairwise_key_type, (u8*)ieee->ap_mac_addr, 0, key);
5007 if ((ieee->pairwise_key_type == KEY_TYPE_CCMP) && ieee->pHTInfo->bCurrentHTSupport){
5008 write_nic_byte(dev, 0x173, 1); //fix aes bug
5012 else //if (ipw->u.crypt.idx) //group key use idx > 0
5014 memcpy((u8*)key, ipw->u.crypt.key, 16);
5015 if (strcmp(ipw->u.crypt.alg, "CCMP") == 0)
5016 ieee->group_key_type= KEY_TYPE_CCMP;
5017 else if (strcmp(ipw->u.crypt.alg, "TKIP") == 0)
5018 ieee->group_key_type = KEY_TYPE_TKIP;
5019 else if (strcmp(ipw->u.crypt.alg, "WEP") == 0)
5021 if (ipw->u.crypt.key_len == 13)
5022 ieee->group_key_type = KEY_TYPE_WEP104;
5023 else if (ipw->u.crypt.key_len == 5)
5024 ieee->group_key_type = KEY_TYPE_WEP40;
5027 ieee->group_key_type = KEY_TYPE_NA;
5029 if (ieee->group_key_type)
5033 ipw->u.crypt.idx, //KeyIndex
5034 ieee->group_key_type, //KeyType
5035 broadcast_addr, //MacAddr
5045 printk("@@ wrq->u pointer = ");
5046 for(i=0;i<wrq->u.data.length;i++){
5047 if(i%10==0) printk("\n");
5048 printk( "%8x|", ((u32*)wrq->u.data.pointer)[i] );
5052 #endif /*JOHN_DEBUG*/
5053 ret = ieee80211_wpa_supplicant_ioctl(priv->ieee80211, &wrq->u.data);
5068 static u8 HwRateToMRate90(bool bIsHT, u8 rate)
5074 case DESC90_RATE1M: ret_rate = MGN_1M; break;
5075 case DESC90_RATE2M: ret_rate = MGN_2M; break;
5076 case DESC90_RATE5_5M: ret_rate = MGN_5_5M; break;
5077 case DESC90_RATE11M: ret_rate = MGN_11M; break;
5078 case DESC90_RATE6M: ret_rate = MGN_6M; break;
5079 case DESC90_RATE9M: ret_rate = MGN_9M; break;
5080 case DESC90_RATE12M: ret_rate = MGN_12M; break;
5081 case DESC90_RATE18M: ret_rate = MGN_18M; break;
5082 case DESC90_RATE24M: ret_rate = MGN_24M; break;
5083 case DESC90_RATE36M: ret_rate = MGN_36M; break;
5084 case DESC90_RATE48M: ret_rate = MGN_48M; break;
5085 case DESC90_RATE54M: ret_rate = MGN_54M; break;
5088 RT_TRACE(COMP_RECV, "HwRateToMRate90(): Non supported Rate [%x], bIsHT = %d!!!\n", rate, bIsHT);
5094 case DESC90_RATEMCS0: ret_rate = MGN_MCS0; break;
5095 case DESC90_RATEMCS1: ret_rate = MGN_MCS1; break;
5096 case DESC90_RATEMCS2: ret_rate = MGN_MCS2; break;
5097 case DESC90_RATEMCS3: ret_rate = MGN_MCS3; break;
5098 case DESC90_RATEMCS4: ret_rate = MGN_MCS4; break;
5099 case DESC90_RATEMCS5: ret_rate = MGN_MCS5; break;
5100 case DESC90_RATEMCS6: ret_rate = MGN_MCS6; break;
5101 case DESC90_RATEMCS7: ret_rate = MGN_MCS7; break;
5102 case DESC90_RATEMCS8: ret_rate = MGN_MCS8; break;
5103 case DESC90_RATEMCS9: ret_rate = MGN_MCS9; break;
5104 case DESC90_RATEMCS10: ret_rate = MGN_MCS10; break;
5105 case DESC90_RATEMCS11: ret_rate = MGN_MCS11; break;
5106 case DESC90_RATEMCS12: ret_rate = MGN_MCS12; break;
5107 case DESC90_RATEMCS13: ret_rate = MGN_MCS13; break;
5108 case DESC90_RATEMCS14: ret_rate = MGN_MCS14; break;
5109 case DESC90_RATEMCS15: ret_rate = MGN_MCS15; break;
5110 case DESC90_RATEMCS32: ret_rate = (0x80|0x20); break;
5113 RT_TRACE(COMP_RECV, "HwRateToMRate90(): Non supported Rate [%x], bIsHT = %d!!!\n",rate, bIsHT);
5122 * Function: UpdateRxPktTimeStamp
5123 * Overview: Recored down the TSF time stamp when receiving a packet
5131 * (pRfd->Status.TimeStampHigh is updated)
5132 * (pRfd->Status.TimeStampLow is updated)
5136 static void UpdateRxPktTimeStamp8190 (struct net_device *dev, struct ieee80211_rx_stats *stats)
5138 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
5140 if(stats->bIsAMPDU && !stats->bFirstMPDU) {
5141 stats->mac_time[0] = priv->LastRxDescTSFLow;
5142 stats->mac_time[1] = priv->LastRxDescTSFHigh;
5144 priv->LastRxDescTSFLow = stats->mac_time[0];
5145 priv->LastRxDescTSFHigh = stats->mac_time[1];
5149 static long rtl819x_translate_todbm(u8 signal_strength_index)// 0-100 index.
5151 long signal_power; // in dBm.
5153 // Translate to dBm (x=0.5y-95).
5154 signal_power = (long)((signal_strength_index + 1) >> 1);
5157 return signal_power;
5162 // Update Rx signal related information in the packet reeived
5163 // to RxStats. User application can query RxStats to realize
5164 // current Rx signal status.
5167 // In normal operation, user only care about the information of the BSS
5168 // and we shall invoke this function if the packet received is from the BSS.
5171 rtl819x_update_rxsignalstatistics8190pci(
5172 struct r8192_priv * priv,
5173 struct ieee80211_rx_stats * pprevious_stats
5178 //2 <ToDo> Update Rx Statistics (such as signal strength and signal quality).
5181 if(priv->stats.recv_signal_power == 0)
5182 priv->stats.recv_signal_power = pprevious_stats->RecvSignalPower;
5184 // To avoid the past result restricting the statistics sensitivity, weight the current power (5/6) to speed up the
5185 // reaction of smoothed Signal Power.
5186 if(pprevious_stats->RecvSignalPower > priv->stats.recv_signal_power)
5188 else if(pprevious_stats->RecvSignalPower < priv->stats.recv_signal_power)
5191 // We need more correct power of received packets and the "SignalStrength" of RxStats have been beautified or translated,
5192 // so we record the correct power in Dbm here. By Bruce, 2008-03-07.
5194 priv->stats.recv_signal_power = (priv->stats.recv_signal_power * 5 + pprevious_stats->RecvSignalPower + weighting) / 6;
5198 rtl8190_process_cck_rxpathsel(
5199 struct r8192_priv * priv,
5200 struct ieee80211_rx_stats * pprevious_stats
5203 #ifdef RTL8190P //Only 90P 2T4R need to check
5204 char last_cck_adc_pwdb[4]={0,0,0,0};
5206 //cosa add for Rx path selection
5207 if(priv->rf_type == RF_2T4R && DM_RxPathSelTable.Enable)
5209 if(pprevious_stats->bIsCCK &&
5210 (pprevious_stats->bPacketToSelf ||pprevious_stats->bPacketBeacon))
5212 /* record the cck adc_pwdb to the sliding window. */
5213 if(priv->stats.cck_adc_pwdb.TotalNum++ >= PHY_RSSI_SLID_WIN_MAX)
5215 priv->stats.cck_adc_pwdb.TotalNum = PHY_RSSI_SLID_WIN_MAX;
5216 for(i=RF90_PATH_A; i<RF90_PATH_MAX; i++)
5218 last_cck_adc_pwdb[i] = priv->stats.cck_adc_pwdb.elements[i][priv->stats.cck_adc_pwdb.index];
5219 priv->stats.cck_adc_pwdb.TotalVal[i] -= last_cck_adc_pwdb[i];
5222 for(i=RF90_PATH_A; i<RF90_PATH_MAX; i++)
5224 priv->stats.cck_adc_pwdb.TotalVal[i] += pprevious_stats->cck_adc_pwdb[i];
5225 priv->stats.cck_adc_pwdb.elements[i][priv->stats.cck_adc_pwdb.index] = pprevious_stats->cck_adc_pwdb[i];
5227 priv->stats.cck_adc_pwdb.index++;
5228 if(priv->stats.cck_adc_pwdb.index >= PHY_RSSI_SLID_WIN_MAX)
5229 priv->stats.cck_adc_pwdb.index = 0;
5231 for(i=RF90_PATH_A; i<RF90_PATH_MAX; i++)
5233 DM_RxPathSelTable.cck_pwdb_sta[i] = priv->stats.cck_adc_pwdb.TotalVal[i]/priv->stats.cck_adc_pwdb.TotalNum;
5236 for(i=RF90_PATH_A; i<RF90_PATH_MAX; i++)
5238 if(pprevious_stats->cck_adc_pwdb[i] > (char)priv->undecorated_smoothed_cck_adc_pwdb[i])
5240 priv->undecorated_smoothed_cck_adc_pwdb[i] =
5241 ( (priv->undecorated_smoothed_cck_adc_pwdb[i]*(Rx_Smooth_Factor-1)) +
5242 (pprevious_stats->cck_adc_pwdb[i])) /(Rx_Smooth_Factor);
5243 priv->undecorated_smoothed_cck_adc_pwdb[i] = priv->undecorated_smoothed_cck_adc_pwdb[i] + 1;
5247 priv->undecorated_smoothed_cck_adc_pwdb[i] =
5248 ( (priv->undecorated_smoothed_cck_adc_pwdb[i]*(Rx_Smooth_Factor-1)) +
5249 (pprevious_stats->cck_adc_pwdb[i])) /(Rx_Smooth_Factor);
5258 /* 2008/01/22 MH We can not delcare RSSI/EVM total value of sliding window to
5259 be a local static. Otherwise, it may increase when we return from S3/S4. The
5260 value will be kept in memory or disk. We must delcare the value in adapter
5261 and it will be reinitialized when return from S3/S4. */
5262 static void rtl8192_process_phyinfo(struct r8192_priv * priv, u8* buffer,struct ieee80211_rx_stats * pprevious_stats, struct ieee80211_rx_stats * pcurrent_stats)
5264 bool bcheck = false;
5266 u32 nspatial_stream, tmp_val;
5268 static u32 slide_rssi_index=0, slide_rssi_statistics=0;
5269 static u32 slide_evm_index=0, slide_evm_statistics=0;
5270 static u32 last_rssi=0, last_evm=0;
5271 //cosa add for rx path selection
5272 // static long slide_cck_adc_pwdb_index=0, slide_cck_adc_pwdb_statistics=0;
5273 // static char last_cck_adc_pwdb[4]={0,0,0,0};
5274 //cosa add for beacon rssi smoothing
5275 static u32 slide_beacon_adc_pwdb_index=0, slide_beacon_adc_pwdb_statistics=0;
5276 static u32 last_beacon_adc_pwdb=0;
5278 struct ieee80211_hdr_3addr *hdr;
5280 unsigned int frag,seq;
5281 hdr = (struct ieee80211_hdr_3addr *)buffer;
5282 sc = le16_to_cpu(hdr->seq_ctl);
5283 frag = WLAN_GET_SEQ_FRAG(sc);
5284 seq = WLAN_GET_SEQ_SEQ(sc);
5285 //cosa add 04292008 to record the sequence number
5286 pcurrent_stats->Seq_Num = seq;
5288 // Check whether we should take the previous packet into accounting
5290 if(!pprevious_stats->bIsAMPDU)
5292 // if previous packet is not aggregated packet
5296 //remve for that we don't use AMPDU to calculate PWDB,because the reported PWDB of some AP is fault.
5298 // if previous packet is aggregated packet, and current packet
5300 // (2) is the first packet of one AMPDU
5301 // that means the previous packet is the last one aggregated packet
5302 if( !pcurrent_stats->bIsAMPDU || pcurrent_stats->bFirstMPDU)
5307 if(slide_rssi_statistics++ >= PHY_RSSI_SLID_WIN_MAX)
5309 slide_rssi_statistics = PHY_RSSI_SLID_WIN_MAX;
5310 last_rssi = priv->stats.slide_signal_strength[slide_rssi_index];
5311 priv->stats.slide_rssi_total -= last_rssi;
5313 priv->stats.slide_rssi_total += pprevious_stats->SignalStrength;
5315 priv->stats.slide_signal_strength[slide_rssi_index++] = pprevious_stats->SignalStrength;
5316 if(slide_rssi_index >= PHY_RSSI_SLID_WIN_MAX)
5317 slide_rssi_index = 0;
5319 // <1> Showed on UI for user, in dbm
5320 tmp_val = priv->stats.slide_rssi_total/slide_rssi_statistics;
5321 priv->stats.signal_strength = rtl819x_translate_todbm((u8)tmp_val);
5322 pcurrent_stats->rssi = priv->stats.signal_strength;
5324 // If the previous packet does not match the criteria, neglect it
5326 if(!pprevious_stats->bPacketMatchBSSID)
5328 if(!pprevious_stats->bToSelfBA)
5335 rtl8190_process_cck_rxpathsel(priv,pprevious_stats);
5340 priv->stats.num_process_phyinfo++;
5342 /* record the general signal strength to the sliding window. */
5343 if(slide_rssi_statistics++ >= PHY_RSSI_SLID_WIN_MAX)
5345 slide_rssi_statistics = PHY_RSSI_SLID_WIN_MAX;
5346 last_rssi = priv->stats.slide_signal_strength[slide_rssi_index];
5347 priv->stats.slide_rssi_total -= last_rssi;
5349 priv->stats.slide_rssi_total += pprevious_stats->SignalStrength;
5351 priv->stats.slide_signal_strength[slide_rssi_index++] = pprevious_stats->SignalStrength;
5352 if(slide_rssi_index >= PHY_RSSI_SLID_WIN_MAX)
5353 slide_rssi_index = 0;
5355 // <1> Showed on UI for user, in dbm
5356 tmp_val = priv->stats.slide_rssi_total/slide_rssi_statistics;
5357 priv->stats.signal_strength = rtl819x_translate_todbm((u8)tmp_val);
5360 // <2> Showed on UI for engineering
5361 // hardware does not provide rssi information for each rf path in CCK
5362 if(!pprevious_stats->bIsCCK && pprevious_stats->bPacketToSelf)
5364 for (rfpath = RF90_PATH_A; rfpath < RF90_PATH_C; rfpath++)
5366 if (!rtl8192_phy_CheckIsLegalRFPath(priv->ieee80211->dev, rfpath))
5368 RT_TRACE(COMP_DBG,"Jacken -> pPreviousstats->RxMIMOSignalStrength[rfpath] = %d \n" ,pprevious_stats->RxMIMOSignalStrength[rfpath] );
5369 //Fixed by Jacken 2008-03-20
5370 if(priv->stats.rx_rssi_percentage[rfpath] == 0)
5372 priv->stats.rx_rssi_percentage[rfpath] = pprevious_stats->RxMIMOSignalStrength[rfpath];
5373 //DbgPrint("MIMO RSSI initialize \n");
5375 if(pprevious_stats->RxMIMOSignalStrength[rfpath] > priv->stats.rx_rssi_percentage[rfpath])
5377 priv->stats.rx_rssi_percentage[rfpath] =
5378 ( (priv->stats.rx_rssi_percentage[rfpath]*(Rx_Smooth_Factor-1)) +
5379 (pprevious_stats->RxMIMOSignalStrength[rfpath])) /(Rx_Smooth_Factor);
5380 priv->stats.rx_rssi_percentage[rfpath] = priv->stats.rx_rssi_percentage[rfpath] + 1;
5384 priv->stats.rx_rssi_percentage[rfpath] =
5385 ( (priv->stats.rx_rssi_percentage[rfpath]*(Rx_Smooth_Factor-1)) +
5386 (pprevious_stats->RxMIMOSignalStrength[rfpath])) /(Rx_Smooth_Factor);
5388 RT_TRACE(COMP_DBG,"Jacken -> priv->RxStats.RxRSSIPercentage[rfPath] = %d \n" ,priv->stats.rx_rssi_percentage[rfpath] );
5396 //cosa add for beacon rssi smoothing by average.
5397 if(pprevious_stats->bPacketBeacon)
5399 /* record the beacon pwdb to the sliding window. */
5400 if(slide_beacon_adc_pwdb_statistics++ >= PHY_Beacon_RSSI_SLID_WIN_MAX)
5402 slide_beacon_adc_pwdb_statistics = PHY_Beacon_RSSI_SLID_WIN_MAX;
5403 last_beacon_adc_pwdb = priv->stats.Slide_Beacon_pwdb[slide_beacon_adc_pwdb_index];
5404 priv->stats.Slide_Beacon_Total -= last_beacon_adc_pwdb;
5405 //DbgPrint("slide_beacon_adc_pwdb_index = %d, last_beacon_adc_pwdb = %d, Adapter->RxStats.Slide_Beacon_Total = %d\n",
5406 // slide_beacon_adc_pwdb_index, last_beacon_adc_pwdb, Adapter->RxStats.Slide_Beacon_Total);
5408 priv->stats.Slide_Beacon_Total += pprevious_stats->RxPWDBAll;
5409 priv->stats.Slide_Beacon_pwdb[slide_beacon_adc_pwdb_index] = pprevious_stats->RxPWDBAll;
5410 //DbgPrint("slide_beacon_adc_pwdb_index = %d, pPreviousRfd->Status.RxPWDBAll = %d\n", slide_beacon_adc_pwdb_index, pPreviousRfd->Status.RxPWDBAll);
5411 slide_beacon_adc_pwdb_index++;
5412 if(slide_beacon_adc_pwdb_index >= PHY_Beacon_RSSI_SLID_WIN_MAX)
5413 slide_beacon_adc_pwdb_index = 0;
5414 pprevious_stats->RxPWDBAll = priv->stats.Slide_Beacon_Total/slide_beacon_adc_pwdb_statistics;
5415 if(pprevious_stats->RxPWDBAll >= 3)
5416 pprevious_stats->RxPWDBAll -= 3;
5419 RT_TRACE(COMP_RXDESC, "Smooth %s PWDB = %d\n",
5420 pprevious_stats->bIsCCK? "CCK": "OFDM",
5421 pprevious_stats->RxPWDBAll);
5423 if(pprevious_stats->bPacketToSelf || pprevious_stats->bPacketBeacon || pprevious_stats->bToSelfBA)
5425 if(priv->undecorated_smoothed_pwdb < 0) // initialize
5427 priv->undecorated_smoothed_pwdb = pprevious_stats->RxPWDBAll;
5428 //DbgPrint("First pwdb initialize \n");
5431 if(pprevious_stats->RxPWDBAll > (u32)priv->undecorated_smoothed_pwdb)
5433 priv->undecorated_smoothed_pwdb =
5434 ( ((priv->undecorated_smoothed_pwdb)*(Rx_Smooth_Factor-1)) +
5435 (pprevious_stats->RxPWDBAll)) /(Rx_Smooth_Factor);
5436 priv->undecorated_smoothed_pwdb = priv->undecorated_smoothed_pwdb + 1;
5440 priv->undecorated_smoothed_pwdb =
5441 ( ((priv->undecorated_smoothed_pwdb)*(Rx_Smooth_Factor-1)) +
5442 (pprevious_stats->RxPWDBAll)) /(Rx_Smooth_Factor);
5445 //Fixed by Jacken 2008-03-20
5446 if(pPreviousRfd->Status.RxPWDBAll > (u32)pHalData->UndecoratedSmoothedPWDB)
5448 pHalData->UndecoratedSmoothedPWDB =
5449 ( ((pHalData->UndecoratedSmoothedPWDB)* 5) + (pPreviousRfd->Status.RxPWDBAll)) / 6;
5450 pHalData->UndecoratedSmoothedPWDB = pHalData->UndecoratedSmoothedPWDB + 1;
5454 pHalData->UndecoratedSmoothedPWDB =
5455 ( ((pHalData->UndecoratedSmoothedPWDB)* 5) + (pPreviousRfd->Status.RxPWDBAll)) / 6;
5458 rtl819x_update_rxsignalstatistics8190pci(priv,pprevious_stats);
5464 /* record the general EVM to the sliding window. */
5465 if(pprevious_stats->SignalQuality == 0)
5470 if(pprevious_stats->bPacketToSelf || pprevious_stats->bPacketBeacon || pprevious_stats->bToSelfBA){
5471 if(slide_evm_statistics++ >= PHY_RSSI_SLID_WIN_MAX){
5472 slide_evm_statistics = PHY_RSSI_SLID_WIN_MAX;
5473 last_evm = priv->stats.slide_evm[slide_evm_index];
5474 priv->stats.slide_evm_total -= last_evm;
5477 priv->stats.slide_evm_total += pprevious_stats->SignalQuality;
5479 priv->stats.slide_evm[slide_evm_index++] = pprevious_stats->SignalQuality;
5480 if(slide_evm_index >= PHY_RSSI_SLID_WIN_MAX)
5481 slide_evm_index = 0;
5483 // <1> Showed on UI for user, in percentage.
5484 tmp_val = priv->stats.slide_evm_total/slide_evm_statistics;
5485 priv->stats.signal_quality = tmp_val;
5486 //cosa add 10/11/2007, Showed on UI for user in Windows Vista, for Link quality.
5487 priv->stats.last_signal_strength_inpercent = tmp_val;
5490 // <2> Showed on UI for engineering
5491 if(pprevious_stats->bPacketToSelf || pprevious_stats->bPacketBeacon || pprevious_stats->bToSelfBA)
5493 for(nspatial_stream = 0; nspatial_stream<2 ; nspatial_stream++) // 2 spatial stream
5495 if(pprevious_stats->RxMIMOSignalQuality[nspatial_stream] != -1)
5497 if(priv->stats.rx_evm_percentage[nspatial_stream] == 0) // initialize
5499 priv->stats.rx_evm_percentage[nspatial_stream] = pprevious_stats->RxMIMOSignalQuality[nspatial_stream];
5501 priv->stats.rx_evm_percentage[nspatial_stream] =
5502 ( (priv->stats.rx_evm_percentage[nspatial_stream]* (Rx_Smooth_Factor-1)) +
5503 (pprevious_stats->RxMIMOSignalQuality[nspatial_stream]* 1)) / (Rx_Smooth_Factor);
5511 /*-----------------------------------------------------------------------------
5512 * Function: rtl819x_query_rxpwrpercentage()
5516 * Input: char antpower
5520 * Return: 0-100 percentage
5524 * 05/26/2008 amy Create Version 0 porting from windows code.
5526 *---------------------------------------------------------------------------*/
5527 static u8 rtl819x_query_rxpwrpercentage(
5531 if ((antpower <= -100) || (antpower >= 20))
5535 else if (antpower >= 0)
5541 return (100+antpower);
5544 } /* QueryRxPwrPercentage */
5547 rtl819x_evm_dbtopercentage(
5559 ret_val = 0 - ret_val;
5568 // We want good-looking for signal strength/quality
5569 // 2007/7/19 01:09, by cosa.
5571 static long rtl819x_signal_scale_mapping(long currsig)
5575 // Step 1. Scale mapping.
5576 if(currsig >= 61 && currsig <= 100)
5578 retsig = 90 + ((currsig - 60) / 4);
5580 else if(currsig >= 41 && currsig <= 60)
5582 retsig = 78 + ((currsig - 40) / 2);
5584 else if(currsig >= 31 && currsig <= 40)
5586 retsig = 66 + (currsig - 30);
5588 else if(currsig >= 21 && currsig <= 30)
5590 retsig = 54 + (currsig - 20);
5592 else if(currsig >= 5 && currsig <= 20)
5594 retsig = 42 + (((currsig - 5) * 2) / 3);
5596 else if(currsig == 4)
5600 else if(currsig == 3)
5604 else if(currsig == 2)
5608 else if(currsig == 1)
5620 static void rtl8192_query_rxphystatus(
5621 struct r8192_priv * priv,
5622 struct ieee80211_rx_stats * pstats,
5623 prx_desc_819x_pci pdesc,
5624 prx_fwinfo_819x_pci pdrvinfo,
5625 struct ieee80211_rx_stats * precord_stats,
5626 bool bpacket_match_bssid,
5627 bool bpacket_toself,
5632 //PRT_RFD_STATUS pRtRfdStatus = &(pRfd->Status);
5633 phy_sts_ofdm_819xpci_t* pofdm_buf;
5634 phy_sts_cck_819xpci_t * pcck_buf;
5635 phy_ofdm_rx_status_rxsc_sgien_exintfflag* prxsc;
5637 u8 i,max_spatial_stream, tmp_rxsnr, tmp_rxevm, rxsc_sgien_exflg;
5638 char rx_pwr[4], rx_pwr_all=0;
5639 //long rx_avg_pwr = 0;
5640 char rx_snrX, rx_evmX;
5642 u32 RSSI, total_rssi=0;//, total_evm=0;
5643 // long signal_strength_index = 0;
5647 /* 2007/07/04 MH For OFDM RSSI. For high power or not. */
5648 static u8 check_reg824 = 0;
5649 static u32 reg824_bit9 = 0;
5651 priv->stats.numqry_phystatus++;
5653 is_cck_rate = rx_hal_is_cck_rate(pdrvinfo);
5655 // Record it for next packet processing
5656 memset(precord_stats, 0, sizeof(struct ieee80211_rx_stats));
5657 pstats->bPacketMatchBSSID = precord_stats->bPacketMatchBSSID = bpacket_match_bssid;
5658 pstats->bPacketToSelf = precord_stats->bPacketToSelf = bpacket_toself;
5659 pstats->bIsCCK = precord_stats->bIsCCK = is_cck_rate;//RX_HAL_IS_CCK_RATE(pDrvInfo);
5660 pstats->bPacketBeacon = precord_stats->bPacketBeacon = bPacketBeacon;
5661 pstats->bToSelfBA = precord_stats->bToSelfBA = bToSelfBA;
5662 /*2007.08.30 requested by SD3 Jerry */
5663 if(check_reg824 == 0)
5665 reg824_bit9 = rtl8192_QueryBBReg(priv->ieee80211->dev, rFPGA0_XA_HSSIParameter2, 0x200);
5670 prxpkt = (u8*)pdrvinfo;
5672 /* Move pointer to the 16th bytes. Phy status start address. */
5673 prxpkt += sizeof(rx_fwinfo_819x_pci);
5675 /* Initial the cck and ofdm buffer pointer */
5676 pcck_buf = (phy_sts_cck_819xpci_t *)prxpkt;
5677 pofdm_buf = (phy_sts_ofdm_819xpci_t *)prxpkt;
5679 pstats->RxMIMOSignalQuality[0] = -1;
5680 pstats->RxMIMOSignalQuality[1] = -1;
5681 precord_stats->RxMIMOSignalQuality[0] = -1;
5682 precord_stats->RxMIMOSignalQuality[1] = -1;
5687 // (1)Hardware does not provide RSSI for CCK
5691 // (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive)
5693 u8 report;//, cck_agc_rpt;
5696 char cck_adc_pwdb[4];
5698 priv->stats.numqry_phystatusCCK++;
5700 #ifdef RTL8190P //Only 90P 2T4R need to check
5701 if(priv->rf_type == RF_2T4R && DM_RxPathSelTable.Enable && bpacket_match_bssid)
5703 for(i=RF90_PATH_A; i<RF90_PATH_MAX; i++)
5705 tmp_pwdb = pcck_buf->adc_pwdb_X[i];
5706 cck_adc_pwdb[i] = (char)tmp_pwdb;
5707 cck_adc_pwdb[i] /= 2;
5708 pstats->cck_adc_pwdb[i] = precord_stats->cck_adc_pwdb[i] = cck_adc_pwdb[i];
5709 //DbgPrint("RF-%d tmp_pwdb = 0x%x, cck_adc_pwdb = %d", i, tmp_pwdb, cck_adc_pwdb[i]);
5716 report = pcck_buf->cck_agc_rpt & 0xc0;
5720 //Fixed by Jacken from Bryant 2008-03-20
5721 //Original value is -38 , -26 , -14 , -2
5722 //Fixed value is -35 , -23 , -11 , 6
5724 rx_pwr_all = -35 - (pcck_buf->cck_agc_rpt & 0x3e);
5727 rx_pwr_all = -23 - (pcck_buf->cck_agc_rpt & 0x3e);
5730 rx_pwr_all = -11 - (pcck_buf->cck_agc_rpt & 0x3e);
5733 rx_pwr_all = 8 - (pcck_buf->cck_agc_rpt & 0x3e);
5739 report = pcck_buf->cck_agc_rpt & 0x60;
5744 rx_pwr_all = -35 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1) ;
5747 rx_pwr_all = -23 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1);
5750 rx_pwr_all = -11 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1) ;
5753 rx_pwr_all = -8 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1) ;
5758 pwdb_all = rtl819x_query_rxpwrpercentage(rx_pwr_all);
5759 pstats->RxPWDBAll = precord_stats->RxPWDBAll = pwdb_all;
5760 pstats->RecvSignalPower = rx_pwr_all;
5763 // (3) Get Signal Quality (EVM)
5765 if(bpacket_match_bssid)
5769 if(pstats->RxPWDBAll > 40)
5774 sq = pcck_buf->sq_rpt;
5776 if(pcck_buf->sq_rpt > 64)
5778 else if (pcck_buf->sq_rpt < 20)
5781 sq = ((64-sq) * 100) / 44;
5783 pstats->SignalQuality = precord_stats->SignalQuality = sq;
5784 pstats->RxMIMOSignalQuality[0] = precord_stats->RxMIMOSignalQuality[0] = sq;
5785 pstats->RxMIMOSignalQuality[1] = precord_stats->RxMIMOSignalQuality[1] = -1;
5790 priv->stats.numqry_phystatusHT++;
5792 // (1)Get RSSI for HT rate
5794 for(i=RF90_PATH_A; i<RF90_PATH_MAX; i++)
5796 // 2008/01/30 MH we will judge RF RX path now.
5797 if (priv->brfpath_rxenable[i])
5802 //Fixed by Jacken from Bryant 2008-03-20
5803 //Original value is 106
5804 #ifdef RTL8190P //Modify by Jacken 2008/03/31
5805 rx_pwr[i] = ((pofdm_buf->trsw_gain_X[i]&0x3F)*2) - 106;
5807 rx_pwr[i] = ((pofdm_buf->trsw_gain_X[i]&0x3F)*2) - 110;
5810 //Get Rx snr value in DB
5811 tmp_rxsnr = pofdm_buf->rxsnr_X[i];
5812 rx_snrX = (char)(tmp_rxsnr);
5814 priv->stats.rxSNRdB[i] = (long)rx_snrX;
5816 /* Translate DBM to percentage. */
5817 RSSI = rtl819x_query_rxpwrpercentage(rx_pwr[i]);
5818 if (priv->brfpath_rxenable[i])
5821 /* Record Signal Strength for next packet */
5822 if(bpacket_match_bssid)
5824 pstats->RxMIMOSignalStrength[i] =(u8) RSSI;
5825 precord_stats->RxMIMOSignalStrength[i] =(u8) RSSI;
5831 // (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive)
5833 //Fixed by Jacken from Bryant 2008-03-20
5834 //Original value is 106
5835 rx_pwr_all = (((pofdm_buf->pwdb_all ) >> 1 )& 0x7f) -106;
5836 pwdb_all = rtl819x_query_rxpwrpercentage(rx_pwr_all);
5838 pstats->RxPWDBAll = precord_stats->RxPWDBAll = pwdb_all;
5839 pstats->RxPower = precord_stats->RxPower = rx_pwr_all;
5840 pstats->RecvSignalPower = rx_pwr_all;
5842 // (3)EVM of HT rate
5844 if(pdrvinfo->RxHT && pdrvinfo->RxRate>=DESC90_RATEMCS8 &&
5845 pdrvinfo->RxRate<=DESC90_RATEMCS15)
5846 max_spatial_stream = 2; //both spatial stream make sense
5848 max_spatial_stream = 1; //only spatial stream 1 makes sense
5850 for(i=0; i<max_spatial_stream; i++)
5852 tmp_rxevm = pofdm_buf->rxevm_X[i];
5853 rx_evmX = (char)(tmp_rxevm);
5855 // Do not use shift operation like "rx_evmX >>= 1" because the compilor of free build environment
5856 // fill most significant bit to "zero" when doing shifting operation which may change a negative
5857 // value to positive one, then the dbm value (which is supposed to be negative) is not correct anymore.
5860 evm = rtl819x_evm_dbtopercentage(rx_evmX);
5862 EVM = SignalScaleMapping(EVM);//make it good looking, from 0~100
5864 if(bpacket_match_bssid)
5866 if(i==0) // Fill value in RFD, Get the first spatial stream only
5867 pstats->SignalQuality = precord_stats->SignalQuality = (u8)(evm & 0xff);
5868 pstats->RxMIMOSignalQuality[i] = precord_stats->RxMIMOSignalQuality[i] = (u8)(evm & 0xff);
5873 /* record rx statistics for debug */
5874 rxsc_sgien_exflg = pofdm_buf->rxsc_sgien_exflg;
5875 prxsc = (phy_ofdm_rx_status_rxsc_sgien_exintfflag *)&rxsc_sgien_exflg;
5876 if(pdrvinfo->BW) //40M channel
5877 priv->stats.received_bwtype[1+prxsc->rxsc]++;
5879 priv->stats.received_bwtype[0]++;
5882 //UI BSS List signal strength(in percentage), make it good looking, from 0~100.
5883 //It is assigned to the BSS List in GetValueFromBeaconOrProbeRsp().
5886 pstats->SignalStrength = precord_stats->SignalStrength = (u8)(rtl819x_signal_scale_mapping((long)pwdb_all));//PWDB_ALL;
5891 //pRfd->Status.SignalStrength = pRecordRfd->Status.SignalStrength = (u1Byte)(SignalScaleMapping(total_rssi/=RF90_PATH_MAX));//(u1Byte)(total_rssi/=RF90_PATH_MAX);
5892 // We can judge RX path number now.
5894 pstats->SignalStrength = precord_stats->SignalStrength = (u8)(rtl819x_signal_scale_mapping((long)(total_rssi/=rf_rx_num)));
5896 } /* QueryRxPhyStatus8190Pci */
5899 rtl8192_record_rxdesc_forlateruse(
5900 struct ieee80211_rx_stats * psrc_stats,
5901 struct ieee80211_rx_stats * ptarget_stats
5904 ptarget_stats->bIsAMPDU = psrc_stats->bIsAMPDU;
5905 ptarget_stats->bFirstMPDU = psrc_stats->bFirstMPDU;
5906 //ptarget_stats->Seq_Num = psrc_stats->Seq_Num;
5911 static void TranslateRxSignalStuff819xpci(struct net_device *dev,
5912 struct sk_buff *skb,
5913 struct ieee80211_rx_stats * pstats,
5914 prx_desc_819x_pci pdesc,
5915 prx_fwinfo_819x_pci pdrvinfo)
5917 // TODO: We must only check packet for current MAC address. Not finish
5918 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
5919 bool bpacket_match_bssid, bpacket_toself;
5920 bool bPacketBeacon=false, bToSelfBA=false;
5921 static struct ieee80211_rx_stats previous_stats;
5922 struct ieee80211_hdr_3addr *hdr;
5925 // Get Signal Quality for only RX data queue (but not command queue)
5930 /* Get MAC frame start address. */
5931 tmp_buf = skb->data;
5933 hdr = (struct ieee80211_hdr_3addr *)tmp_buf;
5934 fc = le16_to_cpu(hdr->frame_ctl);
5935 type = WLAN_FC_GET_TYPE(fc);
5936 praddr = hdr->addr1;
5938 /* Check if the received packet is acceptabe. */
5939 bpacket_match_bssid = ((IEEE80211_FTYPE_CTL != type) &&
5940 (eqMacAddr(priv->ieee80211->current_network.bssid, (fc & IEEE80211_FCTL_TODS)? hdr->addr1 : (fc & IEEE80211_FCTL_FROMDS )? hdr->addr2 : hdr->addr3))
5941 && (!pstats->bHwError) && (!pstats->bCRC)&& (!pstats->bICV));
5942 bpacket_toself = bpacket_match_bssid & (eqMacAddr(praddr, priv->ieee80211->dev->dev_addr));
5944 if(WLAN_FC_GET_FRAMETYPE(fc)== IEEE80211_STYPE_BEACON)
5946 bPacketBeacon = true;
5947 //DbgPrint("Beacon 2, MatchBSSID = %d, ToSelf = %d \n", bPacketMatchBSSID, bPacketToSelf);
5949 if(WLAN_FC_GET_FRAMETYPE(fc) == IEEE80211_STYPE_BLOCKACK)
5951 if((eqMacAddr(praddr,dev->dev_addr)))
5953 //DbgPrint("BlockAck, MatchBSSID = %d, ToSelf = %d \n", bPacketMatchBSSID, bPacketToSelf);
5957 if(bpacket_match_bssid)
5959 priv->stats.numpacket_matchbssid++;
5962 priv->stats.numpacket_toself++;
5965 // Process PHY information for previous packet (RSSI/PWDB/EVM)
5967 // Because phy information is contained in the last packet of AMPDU only, so driver
5968 // should process phy information of previous packet
5969 rtl8192_process_phyinfo(priv, tmp_buf,&previous_stats, pstats);
5970 rtl8192_query_rxphystatus(priv, pstats, pdesc, pdrvinfo, &previous_stats, bpacket_match_bssid,
5971 bpacket_toself ,bPacketBeacon, bToSelfBA);
5972 rtl8192_record_rxdesc_forlateruse(pstats, &previous_stats);
5977 static void rtl8192_tx_resume(struct net_device *dev)
5979 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
5980 struct ieee80211_device *ieee = priv->ieee80211;
5981 struct sk_buff *skb;
5984 for(queue_index = BK_QUEUE; queue_index < TXCMD_QUEUE;queue_index++) {
5985 while((!skb_queue_empty(&ieee->skb_waitQ[queue_index]))&&
5986 (priv->ieee80211->check_nic_enough_desc(dev,queue_index) > 0)) {
5987 /* 1. dequeue the packet from the wait queue */
5988 skb = skb_dequeue(&ieee->skb_waitQ[queue_index]);
5989 /* 2. tx the packet directly */
5990 ieee->softmac_data_hard_start_xmit(skb,dev,0/* rate useless now*/);
5992 if(queue_index!=MGNT_QUEUE) {
5993 ieee->stats.tx_packets++;
5994 ieee->stats.tx_bytes += skb->len;
6001 void rtl8192_irq_tx_tasklet(struct r8192_priv *priv)
6003 rtl8192_tx_resume(priv->ieee80211->dev);
6007 * Function: UpdateReceivedRateHistogramStatistics
6008 * Overview: Recored down the received data rate
6016 * (Adapter->RxStats.ReceivedRateHistogram[] is updated)
6020 static void UpdateReceivedRateHistogramStatistics8190(
6021 struct net_device *dev,
6022 struct ieee80211_rx_stats* pstats
6025 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
6026 u32 rcvType=1; //0: Total, 1:OK, 2:CRC, 3:ICV
6028 u32 preamble_guardinterval; //1: short preamble/GI, 0: long preamble/GI
6030 /* 2007/03/09 MH We will not update rate of packet from rx cmd queue. */
6032 if (pRfd->queue_id == CMPK_RX_QUEUE_ID)
6037 else if(pstats->bICV)
6040 if(pstats->bShortPreamble)
6041 preamble_guardinterval = 1;// short
6043 preamble_guardinterval = 0;// long
6045 switch(pstats->rate)
6050 case MGN_1M: rateIndex = 0; break;
6051 case MGN_2M: rateIndex = 1; break;
6052 case MGN_5_5M: rateIndex = 2; break;
6053 case MGN_11M: rateIndex = 3; break;
6057 case MGN_6M: rateIndex = 4; break;
6058 case MGN_9M: rateIndex = 5; break;
6059 case MGN_12M: rateIndex = 6; break;
6060 case MGN_18M: rateIndex = 7; break;
6061 case MGN_24M: rateIndex = 8; break;
6062 case MGN_36M: rateIndex = 9; break;
6063 case MGN_48M: rateIndex = 10; break;
6064 case MGN_54M: rateIndex = 11; break;
6066 // 11n High throughput rate
6068 case MGN_MCS0: rateIndex = 12; break;
6069 case MGN_MCS1: rateIndex = 13; break;
6070 case MGN_MCS2: rateIndex = 14; break;
6071 case MGN_MCS3: rateIndex = 15; break;
6072 case MGN_MCS4: rateIndex = 16; break;
6073 case MGN_MCS5: rateIndex = 17; break;
6074 case MGN_MCS6: rateIndex = 18; break;
6075 case MGN_MCS7: rateIndex = 19; break;
6076 case MGN_MCS8: rateIndex = 20; break;
6077 case MGN_MCS9: rateIndex = 21; break;
6078 case MGN_MCS10: rateIndex = 22; break;
6079 case MGN_MCS11: rateIndex = 23; break;
6080 case MGN_MCS12: rateIndex = 24; break;
6081 case MGN_MCS13: rateIndex = 25; break;
6082 case MGN_MCS14: rateIndex = 26; break;
6083 case MGN_MCS15: rateIndex = 27; break;
6084 default: rateIndex = 28; break;
6086 priv->stats.received_preamble_GI[preamble_guardinterval][rateIndex]++;
6087 priv->stats.received_rate_histogram[0][rateIndex]++; //total
6088 priv->stats.received_rate_histogram[rcvType][rateIndex]++;
6091 static void rtl8192_rx(struct net_device *dev)
6093 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
6094 struct ieee80211_hdr_1addr *ieee80211_hdr = NULL;
6095 bool unicast_packet = false;
6096 struct ieee80211_rx_stats stats = {
6100 .freq = IEEE80211_24GHZ_BAND,
6102 unsigned int count = priv->rxringcount;
6104 stats.nic_type = NIC_8192E;
6107 rx_desc_819x_pci *pdesc = &priv->rx_ring[priv->rx_idx];//rx descriptor
6108 struct sk_buff *skb = priv->rx_buf[priv->rx_idx];//rx pkt
6111 /* wait data to be filled by hardware */
6114 stats.bICV = pdesc->ICV;
6115 stats.bCRC = pdesc->CRC32;
6116 stats.bHwError = pdesc->CRC32 | pdesc->ICV;
6118 stats.Length = pdesc->Length;
6119 if(stats.Length < 24)
6120 stats.bHwError |= 1;
6122 if(stats.bHwError) {
6123 stats.bShift = false;
6126 if (pdesc->Length <500)
6127 priv->stats.rxcrcerrmin++;
6128 else if (pdesc->Length >1000)
6129 priv->stats.rxcrcerrmax++;
6131 priv->stats.rxcrcerrmid++;
6135 prx_fwinfo_819x_pci pDrvInfo = NULL;
6136 struct sk_buff *new_skb = dev_alloc_skb(priv->rxbuffersize);
6138 if (unlikely(!new_skb)) {
6142 stats.RxDrvInfoSize = pdesc->RxDrvInfoSize;
6143 stats.RxBufShift = ((pdesc->Shift)&0x03);
6144 stats.Decrypted = !pdesc->SWDec;
6146 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
6147 pci_dma_sync_single_for_cpu(priv->pdev,
6149 pci_unmap_single(priv->pdev,
6151 *((dma_addr_t *)skb->cb),
6153 PCI_DMA_FROMDEVICE);
6154 skb_put(skb, pdesc->Length);
6155 pDrvInfo = (rx_fwinfo_819x_pci *)(skb->data + stats.RxBufShift);
6156 skb_reserve(skb, stats.RxDrvInfoSize + stats.RxBufShift);
6158 stats.rate = HwRateToMRate90((bool)pDrvInfo->RxHT, (u8)pDrvInfo->RxRate);
6159 stats.bShortPreamble = pDrvInfo->SPLCP;
6161 /* it is debug only. It should be disabled in released driver.
6162 * 2007.1.11 by Emily
6164 UpdateReceivedRateHistogramStatistics8190(dev, &stats);
6166 stats.bIsAMPDU = (pDrvInfo->PartAggr==1);
6167 stats.bFirstMPDU = (pDrvInfo->PartAggr==1) && (pDrvInfo->FirstAGGR==1);
6169 stats.TimeStampLow = pDrvInfo->TSFL;
6170 stats.TimeStampHigh = read_nic_dword(dev, TSFR+4);
6172 UpdateRxPktTimeStamp8190(dev, &stats);
6175 // Get Total offset of MPDU Frame Body
6177 if((stats.RxBufShift + stats.RxDrvInfoSize) > 0)
6180 stats.RxIs40MHzPacket = pDrvInfo->BW;
6183 TranslateRxSignalStuff819xpci(dev,skb, &stats, pdesc, pDrvInfo);
6186 if(pDrvInfo->FirstAGGR==1 || pDrvInfo->PartAggr == 1)
6187 RT_TRACE(COMP_RXDESC, "pDrvInfo->FirstAGGR = %d, pDrvInfo->PartAggr = %d\n",
6188 pDrvInfo->FirstAGGR, pDrvInfo->PartAggr);
6189 skb_trim(skb, skb->len - 4/*sCrcLng*/);
6190 /* rx packets statistics */
6191 ieee80211_hdr = (struct ieee80211_hdr_1addr *)skb->data;
6192 unicast_packet = false;
6194 if(is_broadcast_ether_addr(ieee80211_hdr->addr1)) {
6196 }else if(is_multicast_ether_addr(ieee80211_hdr->addr1)){
6199 /* unicast packet */
6200 unicast_packet = true;
6203 stats.packetlength = stats.Length-4;
6204 stats.fraglength = stats.packetlength;
6205 stats.fragoffset = 0;
6206 stats.ntotalfrag = 1;
6208 if(!ieee80211_rx(priv->ieee80211, skb, &stats)){
6209 dev_kfree_skb_any(skb);
6212 if(unicast_packet) {
6213 priv->stats.rxbytesunicast += skb->len;
6218 priv->rx_buf[priv->rx_idx] = skb;
6219 *((dma_addr_t *) skb->cb) = pci_map_single(priv->pdev, skb->tail, priv->rxbuffersize, PCI_DMA_FROMDEVICE);
6220 // *((dma_addr_t *) skb->cb) = pci_map_single(priv->pdev, skb_tail_pointer(skb), priv->rxbuffersize, PCI_DMA_FROMDEVICE);
6225 pdesc->BufferAddress = cpu_to_le32(*((dma_addr_t *)skb->cb));
6227 pdesc->Length = priv->rxbuffersize;
6228 if (priv->rx_idx == priv->rxringcount-1)
6230 priv->rx_idx = (priv->rx_idx + 1) % priv->rxringcount;
6235 void rtl8192_irq_rx_tasklet(struct r8192_priv *priv)
6237 rtl8192_rx(priv->ieee80211->dev);
6239 write_nic_dword(priv->ieee80211->dev, INTA_MASK,read_nic_dword(priv->ieee80211->dev, INTA_MASK) | IMR_RDU);
6242 static const struct net_device_ops rtl8192_netdev_ops = {
6243 .ndo_open = rtl8192_open,
6244 .ndo_stop = rtl8192_close,
6245 /* .ndo_get_stats = rtl8192_stats, */
6246 .ndo_tx_timeout = tx_timeout,
6247 .ndo_do_ioctl = rtl8192_ioctl,
6248 .ndo_set_multicast_list = r8192_set_multicast,
6249 .ndo_set_mac_address = r8192_set_mac_adr,
6250 .ndo_start_xmit = ieee80211_xmit,
6253 /****************************************************************************
6254 ---------------------------- PCI_STUFF---------------------------
6255 *****************************************************************************/
6257 static int __devinit rtl8192_pci_probe(struct pci_dev *pdev,
6258 const struct pci_device_id *id)
6260 unsigned long ioaddr = 0;
6261 struct net_device *dev = NULL;
6262 struct r8192_priv *priv= NULL;
6265 #ifdef CONFIG_RTL8192_IO_MAP
6266 unsigned long pio_start, pio_len, pio_flags;
6268 unsigned long pmem_start, pmem_len, pmem_flags;
6269 #endif //end #ifdef RTL_IO_MAP
6271 RT_TRACE(COMP_INIT,"Configuring chip resources");
6273 if( pci_enable_device (pdev) ){
6274 RT_TRACE(COMP_ERR,"Failed to enable PCI device");
6278 pci_set_master(pdev);
6279 //pci_set_wmi(pdev);
6280 pci_set_dma_mask(pdev, 0xffffff00ULL);
6281 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
6282 pci_set_consistent_dma_mask(pdev,0xffffff00ULL);
6284 dev = alloc_ieee80211(sizeof(struct r8192_priv));
6288 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
6289 SET_MODULE_OWNER(dev);
6292 pci_set_drvdata(pdev, dev);
6293 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
6294 SET_NETDEV_DEV(dev, &pdev->dev);
6296 priv = ieee80211_priv(dev);
6297 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
6298 priv->ieee80211 = netdev_priv(dev);
6300 priv->ieee80211 = (struct ieee80211_device *)dev->priv;
6303 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
6304 if((pdev->subsystem_vendor == PCI_VENDOR_ID_DLINK)&&(pdev->subsystem_device == 0x3304)){
6305 priv->ieee80211->bSupportRemoteWakeUp = 1;
6309 priv->ieee80211->bSupportRemoteWakeUp = 0;
6312 #ifdef CONFIG_RTL8192_IO_MAP
6314 pio_start = (unsigned long)pci_resource_start (pdev, 0);
6315 pio_len = (unsigned long)pci_resource_len (pdev, 0);
6316 pio_flags = (unsigned long)pci_resource_flags (pdev, 0);
6318 if (!(pio_flags & IORESOURCE_IO)) {
6319 RT_TRACE(COMP_ERR,"region #0 not a PIO resource, aborting");
6323 //DMESG("IO space @ 0x%08lx", pio_start );
6324 if( ! request_region( pio_start, pio_len, RTL819xE_MODULE_NAME ) ){
6325 RT_TRACE(COMP_ERR,"request_region failed!");
6330 dev->base_addr = ioaddr; // device I/O address
6334 pmem_start = pci_resource_start(pdev, 1);
6335 pmem_len = pci_resource_len(pdev, 1);
6336 pmem_flags = pci_resource_flags (pdev, 1);
6338 if (!(pmem_flags & IORESOURCE_MEM)) {
6339 RT_TRACE(COMP_ERR,"region #1 not a MMIO resource, aborting");
6343 //DMESG("Memory mapped space @ 0x%08lx ", pmem_start);
6344 if( ! request_mem_region(pmem_start, pmem_len, RTL819xE_MODULE_NAME)) {
6345 RT_TRACE(COMP_ERR,"request_mem_region failed!");
6350 ioaddr = (unsigned long)ioremap_nocache( pmem_start, pmem_len);
6351 if( ioaddr == (unsigned long)NULL ){
6352 RT_TRACE(COMP_ERR,"ioremap failed!");
6353 // release_mem_region( pmem_start, pmem_len );
6357 dev->mem_start = ioaddr; // shared mem start
6358 dev->mem_end = ioaddr + pci_resource_len(pdev, 0); // shared mem end
6360 #endif //end #ifdef RTL_IO_MAP
6362 /* We disable the RETRY_TIMEOUT register (0x41) to keep
6363 * PCI Tx retries from interfering with C3 CPU state */
6364 pci_write_config_byte(pdev, 0x41, 0x00);
6367 pci_read_config_byte(pdev, 0x05, &unit);
6368 pci_write_config_byte(pdev, 0x05, unit & (~0x04));
6370 dev->irq = pdev->irq;
6373 dev->netdev_ops = &rtl8192_netdev_ops;
6375 dev->open = rtl8192_open;
6376 dev->stop = rtl8192_close;
6377 //dev->hard_start_xmit = rtl8192_8023_hard_start_xmit;
6378 dev->tx_timeout = tx_timeout;
6379 //dev->wireless_handlers = &r8192_wx_handlers_def;
6380 dev->do_ioctl = rtl8192_ioctl;
6381 dev->set_multicast_list = r8192_set_multicast;
6382 dev->set_mac_address = r8192_set_mac_adr;
6385 //DMESG("Oops: i'm coming\n");
6386 #if WIRELESS_EXT >= 12
6387 #if WIRELESS_EXT < 17
6388 dev->get_wireless_stats = r8192_get_wireless_stats;
6390 dev->wireless_handlers = (struct iw_handler_def *) &r8192_wx_handlers_def;
6392 //dev->get_wireless_stats = r8192_get_wireless_stats;
6393 dev->type=ARPHRD_ETHER;
6395 dev->watchdog_timeo = HZ*3; //modified by john, 0805
6397 if (dev_alloc_name(dev, ifname) < 0){
6398 RT_TRACE(COMP_INIT, "Oops: devname already taken! Trying wlan%%d...\n");
6400 dev_alloc_name(dev, ifname);
6403 RT_TRACE(COMP_INIT, "Driver probe completed1\n");
6404 if(rtl8192_init(dev)!=0){
6405 RT_TRACE(COMP_ERR, "Initialization failed");
6409 netif_carrier_off(dev);
6410 netif_stop_queue(dev);
6412 register_netdev(dev);
6413 RT_TRACE(COMP_INIT, "dev name=======> %s\n",dev->name);
6414 rtl8192_proc_init_one(dev);
6417 RT_TRACE(COMP_INIT, "Driver probe completed\n");
6418 //#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
6426 #ifdef CONFIG_RTL8180_IO_MAP
6428 if( dev->base_addr != 0 ){
6430 release_region(dev->base_addr,
6431 pci_resource_len(pdev, 0) );
6434 if( dev->mem_start != (unsigned long)NULL ){
6435 iounmap( (void *)dev->mem_start );
6436 release_mem_region( pci_resource_start(pdev, 1),
6437 pci_resource_len(pdev, 1) );
6439 #endif //end #ifdef RTL_IO_MAP
6445 free_irq(dev->irq, dev);
6448 free_ieee80211(dev);
6451 pci_disable_device(pdev);
6453 DMESG("wlan driver load failed\n");
6454 pci_set_drvdata(pdev, NULL);
6459 /* detach all the work and timer structure declared or inititialized
6460 * in r8192_init function.
6462 void rtl8192_cancel_deferred_work(struct r8192_priv* priv)
6464 /* call cancel_work_sync instead of cancel_delayed_work if and only if Linux_version_code
6465 * is or is newer than 2.6.20 and work structure is defined to be struct work_struct.
6466 * Otherwise call cancel_delayed_work is enough.
6467 * FIXME (2.6.20 shoud 2.6.22, work_struct shoud not cancel)
6469 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
6470 cancel_delayed_work(&priv->watch_dog_wq);
6471 cancel_delayed_work(&priv->update_beacon_wq);
6472 cancel_delayed_work(&priv->ieee80211->hw_wakeup_wq);
6473 cancel_delayed_work(&priv->ieee80211->hw_sleep_wq);
6475 cancel_delayed_work(&priv->gpio_change_rf_wq);
6478 #if LINUX_VERSION_CODE >=KERNEL_VERSION(2,6,22)
6479 cancel_work_sync(&priv->reset_wq);
6480 cancel_work_sync(&priv->qos_activate);
6481 //cancel_work_sync(&priv->SetBWModeWorkItem);
6482 //cancel_work_sync(&priv->SwChnlWorkItem);
6484 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
6485 cancel_delayed_work(&priv->reset_wq);
6486 cancel_delayed_work(&priv->qos_activate);
6487 //cancel_delayed_work(&priv->SetBWModeWorkItem);
6488 //cancel_delayed_work(&priv->SwChnlWorkItem);
6495 static void __devexit rtl8192_pci_disconnect(struct pci_dev *pdev)
6497 struct net_device *dev = pci_get_drvdata(pdev);
6498 struct r8192_priv *priv ;
6502 unregister_netdev(dev);
6504 priv=ieee80211_priv(dev);
6506 rtl8192_proc_remove_one(dev);
6509 if (priv->pFirmware)
6511 vfree(priv->pFirmware);
6512 priv->pFirmware = NULL;
6514 // priv->rf_close(dev);
6515 // rtl8192_usb_deleteendpoints(dev);
6516 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
6517 destroy_workqueue(priv->priv_wq);
6519 /* redundant with rtl8192_down */
6520 // rtl8192_irq_disable(dev);
6521 // rtl8192_reset(dev);
6525 /* free tx/rx rings */
6526 rtl8192_free_rx_ring(dev);
6527 for (i = 0; i < MAX_TX_QUEUE_COUNT; i++) {
6528 rtl8192_free_tx_ring(dev, i);
6533 printk("Freeing irq %d\n",dev->irq);
6534 free_irq(dev->irq, dev);
6541 // free_beacon_desc_ring(dev,priv->txbeaconcount);
6543 #ifdef CONFIG_RTL8180_IO_MAP
6545 if( dev->base_addr != 0 ){
6547 release_region(dev->base_addr,
6548 pci_resource_len(pdev, 0) );
6551 if( dev->mem_start != (unsigned long)NULL ){
6552 iounmap( (void *)dev->mem_start );
6553 release_mem_region( pci_resource_start(pdev, 1),
6554 pci_resource_len(pdev, 1) );
6556 #endif /*end #ifdef RTL_IO_MAP*/
6557 free_ieee80211(dev);
6561 pci_disable_device(pdev);
6562 RT_TRACE(COMP_DOWN, "wlan driver removed\n");
6565 extern int ieee80211_init(void);
6566 extern void ieee80211_exit(void);
6568 static int __init rtl8192_pci_module_init(void)
6572 retval = ieee80211_init();
6576 printk(KERN_INFO "\nLinux kernel driver for RTL8192 based WLAN cards\n");
6577 printk(KERN_INFO "Copyright (c) 2007-2008, Realsil Wlan\n");
6578 RT_TRACE(COMP_INIT, "Initializing module");
6579 RT_TRACE(COMP_INIT, "Wireless extensions version %d", WIRELESS_EXT);
6580 rtl8192_proc_module_init();
6581 #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22))
6582 if(0!=pci_module_init(&rtl8192_pci_driver))
6584 if(0!=pci_register_driver(&rtl8192_pci_driver))
6587 DMESG("No device found");
6588 /*pci_unregister_driver (&rtl8192_pci_driver);*/
6595 static void __exit rtl8192_pci_module_exit(void)
6597 pci_unregister_driver(&rtl8192_pci_driver);
6599 RT_TRACE(COMP_DOWN, "Exiting");
6600 rtl8192_proc_module_remove();
6604 //warning message WB
6605 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18)
6606 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
6607 void rtl8192_interrupt(int irq, void *netdev, struct pt_regs *regs)
6609 irqreturn_t rtl8192_interrupt(int irq, void *netdev, struct pt_regs *regs)
6612 irqreturn_t rtl8192_interrupt(int irq, void *netdev)
6615 struct net_device *dev = (struct net_device *) netdev;
6616 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
6617 unsigned long flags;
6619 /* We should return IRQ_NONE, but for now let me keep this */
6620 if(priv->irq_enabled == 0){
6621 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
6628 spin_lock_irqsave(&priv->irq_th_lock,flags);
6632 inta = read_nic_dword(dev, ISR);// & priv->IntrMask;
6633 write_nic_dword(dev,ISR,inta); // reset int situation
6635 priv->stats.shints++;
6636 //DMESG("Enter interrupt, ISR value = 0x%08x", inta);
6638 spin_unlock_irqrestore(&priv->irq_th_lock,flags);
6639 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
6645 most probably we can safely return IRQ_NONE,
6646 but for now is better to avoid problems
6652 spin_unlock_irqrestore(&priv->irq_th_lock,flags);
6653 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
6662 DMESG("NIC irq %x",inta);
6664 //priv->irqpending = inta;
6667 if(!netif_running(dev)) {
6668 spin_unlock_irqrestore(&priv->irq_th_lock,flags);
6669 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
6676 if(inta & IMR_TIMEOUT0){
6677 // write_nic_dword(dev, TimerInt, 0);
6678 //DMESG("=================>waking up");
6679 // rtl8180_hw_wakeup(dev);
6682 if(inta & IMR_TBDOK){
6683 RT_TRACE(COMP_INTR, "beacon ok interrupt!\n");
6684 rtl8192_tx_isr(dev, BEACON_QUEUE);
6685 priv->stats.txbeaconokint++;
6688 if(inta & IMR_TBDER){
6689 RT_TRACE(COMP_INTR, "beacon ok interrupt!\n");
6690 rtl8192_tx_isr(dev, BEACON_QUEUE);
6691 priv->stats.txbeaconerr++;
6694 if(inta & IMR_MGNTDOK ) {
6695 RT_TRACE(COMP_INTR, "Manage ok interrupt!\n");
6696 priv->stats.txmanageokint++;
6697 rtl8192_tx_isr(dev,MGNT_QUEUE);
6701 if(inta & IMR_COMDOK)
6703 priv->stats.txcmdpktokint++;
6704 rtl8192_tx_isr(dev,TXCMD_QUEUE);
6709 DMESG("Frame arrived !");
6711 priv->stats.rxint++;
6712 tasklet_schedule(&priv->irq_rx_tasklet);
6715 if(inta & IMR_BcnInt) {
6716 RT_TRACE(COMP_INTR, "prepare beacon for interrupt!\n");
6717 tasklet_schedule(&priv->irq_prepare_beacon_tasklet);
6721 RT_TRACE(COMP_INTR, "rx descriptor unavailable!\n");
6722 priv->stats.rxrdu++;
6723 /* reset int situation */
6724 write_nic_dword(dev,INTA_MASK,read_nic_dword(dev, INTA_MASK) & ~IMR_RDU);
6725 tasklet_schedule(&priv->irq_rx_tasklet);
6728 if(inta & IMR_RXFOVW){
6729 RT_TRACE(COMP_INTR, "rx overflow !\n");
6730 priv->stats.rxoverflow++;
6731 tasklet_schedule(&priv->irq_rx_tasklet);
6734 if(inta & IMR_TXFOVW) priv->stats.txoverflow++;
6736 if(inta & IMR_BKDOK){
6737 RT_TRACE(COMP_INTR, "BK Tx OK interrupt!\n");
6738 priv->stats.txbkokint++;
6739 priv->ieee80211->LinkDetectInfo.NumTxOkInPeriod++;
6740 rtl8192_tx_isr(dev,BK_QUEUE);
6741 rtl8192_try_wake_queue(dev, BK_QUEUE);
6744 if(inta & IMR_BEDOK){
6745 RT_TRACE(COMP_INTR, "BE TX OK interrupt!\n");
6746 priv->stats.txbeokint++;
6747 priv->ieee80211->LinkDetectInfo.NumTxOkInPeriod++;
6748 rtl8192_tx_isr(dev,BE_QUEUE);
6749 rtl8192_try_wake_queue(dev, BE_QUEUE);
6752 if(inta & IMR_VIDOK){
6753 RT_TRACE(COMP_INTR, "VI TX OK interrupt!\n");
6754 priv->stats.txviokint++;
6755 priv->ieee80211->LinkDetectInfo.NumTxOkInPeriod++;
6756 rtl8192_tx_isr(dev,VI_QUEUE);
6757 rtl8192_try_wake_queue(dev, VI_QUEUE);
6760 if(inta & IMR_VODOK){
6761 priv->stats.txvookint++;
6762 priv->ieee80211->LinkDetectInfo.NumTxOkInPeriod++;
6763 rtl8192_tx_isr(dev,VO_QUEUE);
6764 rtl8192_try_wake_queue(dev, VO_QUEUE);
6767 force_pci_posting(dev);
6768 spin_unlock_irqrestore(&priv->irq_th_lock,flags);
6770 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
6777 void rtl8192_try_wake_queue(struct net_device *dev, int pri)
6780 unsigned long flags;
6782 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
6784 spin_lock_irqsave(&priv->tx_lock,flags);
6785 enough_desc = check_nic_enough_desc(dev,pri);
6786 spin_unlock_irqrestore(&priv->tx_lock,flags);
6789 ieee80211_wake_queue(priv->ieee80211);
6794 void EnableHWSecurityConfig8192(struct net_device *dev)
6796 u8 SECR_value = 0x0;
6797 // struct ieee80211_device* ieee1 = container_of(&dev, struct ieee80211_device, dev);
6798 //printk("==>ieee1:%p, dev:%p\n", ieee1, dev);
6799 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
6800 struct ieee80211_device* ieee = priv->ieee80211;
6801 //printk("==>ieee:%p, dev:%p\n", ieee, dev);
6802 SECR_value = SCR_TxEncEnable | SCR_RxDecEnable;
6804 if (((KEY_TYPE_WEP40 == ieee->pairwise_key_type) || (KEY_TYPE_WEP104 == ieee->pairwise_key_type)) && (priv->ieee80211->auth_mode != 2))
6806 SECR_value |= SCR_RxUseDK;
6807 SECR_value |= SCR_TxUseDK;
6809 else if ((ieee->iw_mode == IW_MODE_ADHOC) && (ieee->pairwise_key_type & (KEY_TYPE_CCMP | KEY_TYPE_TKIP)))
6811 SECR_value |= SCR_RxUseDK;
6812 SECR_value |= SCR_TxUseDK;
6817 //add HWSec active enable here.
6818 //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
6819 ieee->hwsec_active = 1;
6821 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
6823 ieee->hwsec_active = 0;
6824 SECR_value &= ~SCR_RxDecEnable;
6827 RT_TRACE(COMP_SEC,"%s:, hwsec:%d, pairwise_key:%d, SECR_value:%x\n", __FUNCTION__, \
6828 ieee->hwsec_active, ieee->pairwise_key_type, SECR_value);
6830 write_nic_byte(dev, SECR, SECR_value);//SECR_value | SCR_UseDK );
6834 #define TOTAL_CAM_ENTRY 32
6835 //#define CAM_CONTENT_COUNT 8
6836 void setKey( struct net_device *dev,
6844 u32 TargetCommand = 0;
6845 u32 TargetContent = 0;
6849 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
6850 RT_RF_POWER_STATE rtState;
6851 rtState = priv->ieee80211->eRFPowerState;
6852 if(priv->ieee80211->PowerSaveControl.bInactivePs){
6853 if(rtState == eRfOff){
6854 if(priv->ieee80211->RfOffReason > RF_CHANGE_BY_IPS)
6856 RT_TRACE(COMP_ERR, "%s(): RF is OFF.\n",__FUNCTION__);
6865 priv->ieee80211->is_set_key = true;
6867 if (EntryNo >= TOTAL_CAM_ENTRY)
6868 RT_TRACE(COMP_ERR, "cam entry exceeds in setKey()\n");
6870 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));
6873 usConfig |= BIT15 | (KeyType<<2);
6875 usConfig |= BIT15 | (KeyType<<2) | KeyIndex;
6876 // usConfig |= BIT15 | (KeyType<<2) | (DefaultKey<<5) | KeyIndex;
6879 for(i=0 ; i<CAM_CONTENT_COUNT; i++){
6880 TargetCommand = i+CAM_CONTENT_COUNT*EntryNo;
6881 TargetCommand |= BIT31|BIT16;
6883 if(i==0){//MAC|Config
6884 TargetContent = (u32)(*(MacAddr+0)) << 16|
6885 (u32)(*(MacAddr+1)) << 24|
6888 write_nic_dword(dev, WCAMI, TargetContent);
6889 write_nic_dword(dev, RWCAM, TargetCommand);
6890 // printk("setkey cam =%8x\n", read_cam(dev, i+6*EntryNo));
6893 TargetContent = (u32)(*(MacAddr+2)) |
6894 (u32)(*(MacAddr+3)) << 8|
6895 (u32)(*(MacAddr+4)) << 16|
6896 (u32)(*(MacAddr+5)) << 24;
6897 write_nic_dword(dev, WCAMI, TargetContent);
6898 write_nic_dword(dev, RWCAM, TargetCommand);
6900 else { //Key Material
6901 if(KeyContent != NULL)
6903 write_nic_dword(dev, WCAMI, (u32)(*(KeyContent+i-2)) );
6904 write_nic_dword(dev, RWCAM, TargetCommand);
6908 RT_TRACE(COMP_SEC,"=========>after set key, usconfig:%x\n", usConfig);
6910 // This function seems not ready! WB
6911 void CamPrintDbgReg(struct net_device* dev)
6913 unsigned long rvalue;
6914 unsigned char ucValue;
6915 write_nic_dword(dev, DCAM, 0x80000000);
6917 rvalue = read_nic_dword(dev, DCAM); //delay_ms(40);
6918 RT_TRACE(COMP_SEC, " TX CAM=%8lX ",rvalue);
6919 if((rvalue & 0x40000000) != 0x4000000)
6920 RT_TRACE(COMP_SEC, "-->TX Key Not Found ");
6922 write_nic_dword(dev, DCAM, 0x00000000); //delay_ms(40);
6923 rvalue = read_nic_dword(dev, DCAM); //delay_ms(40);
6924 RT_TRACE(COMP_SEC, "RX CAM=%8lX ",rvalue);
6925 if((rvalue & 0x40000000) != 0x4000000)
6926 RT_TRACE(COMP_SEC, "-->CAM Key Not Found ");
6927 ucValue = read_nic_byte(dev, SECR);
6928 RT_TRACE(COMP_SEC, "WPA_Config=%x \n",ucValue);
6932 /***************************************************************************
6933 ------------------- module init / exit stubs ----------------
6934 ****************************************************************************/
6935 module_init(rtl8192_pci_module_init);
6936 module_exit(rtl8192_pci_module_exit);