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 /* this is only for debugging */
860 static void print_buffer(u32 *buffer, int len)
863 u8 *buf =(u8*)buffer;
865 printk("ASCII BUFFER DUMP (len: %x):\n",len);
870 printk("\nBINARY BUFFER DUMP (len: %x):\n",len);
878 short check_nic_enough_desc(struct net_device *dev, int prio)
880 struct r8192_priv *priv = ieee80211_priv(dev);
881 struct rtl8192_tx_ring *ring = &priv->tx_ring[prio];
883 /* for now we reserve two free descriptor as a safety boundary
884 * between the tail and the head
886 if (ring->entries - skb_queue_len(&ring->queue) >= 2) {
893 static void tx_timeout(struct net_device *dev)
895 struct r8192_priv *priv = ieee80211_priv(dev);
896 //rtl8192_commit(dev);
898 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
899 schedule_work(&priv->reset_wq);
901 schedule_task(&priv->reset_wq);
907 /* this is only for debug */
908 static void dump_eprom(struct net_device *dev)
911 for(i=0; i<0xff; i++)
912 RT_TRACE(COMP_INIT, "EEPROM addr %x : %x", i, eprom_read(dev,i));
915 /* this is only for debug */
916 static void rtl8192_dump_reg(struct net_device *dev)
922 RT_TRACE(COMP_INIT, "Dumping NIC register map");
926 printk( "\nD: %2x> ", n);
927 for(i=0;i<16 && n<=max;i++,n++)
928 printk("%2x ",read_nic_byte(dev,n));
933 /****************************************************************************
934 ------------------------------HW STUFF---------------------------
935 *****************************************************************************/
938 static void rtl8192_irq_enable(struct net_device *dev)
940 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
941 priv->irq_enabled = 1;
942 write_nic_dword(dev,INTA_MASK, priv->irq_mask);
946 static void rtl8192_irq_disable(struct net_device *dev)
948 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
950 write_nic_dword(dev,INTA_MASK,0);
951 force_pci_posting(dev);
952 priv->irq_enabled = 0;
956 static void rtl8192_set_mode(struct net_device *dev,int mode)
959 ecmd=read_nic_byte(dev, EPROM_CMD);
960 ecmd=ecmd &~ EPROM_CMD_OPERATING_MODE_MASK;
961 ecmd=ecmd | (mode<<EPROM_CMD_OPERATING_MODE_SHIFT);
962 ecmd=ecmd &~ (1<<EPROM_CS_SHIFT);
963 ecmd=ecmd &~ (1<<EPROM_CK_SHIFT);
964 write_nic_byte(dev, EPROM_CMD, ecmd);
968 void rtl8192_update_msr(struct net_device *dev)
970 struct r8192_priv *priv = ieee80211_priv(dev);
973 msr = read_nic_byte(dev, MSR);
974 msr &= ~ MSR_LINK_MASK;
976 /* do not change in link_state != WLAN_LINK_ASSOCIATED.
977 * msr must be updated if the state is ASSOCIATING.
978 * this is intentional and make sense for ad-hoc and
979 * master (see the create BSS/IBSS func)
981 if (priv->ieee80211->state == IEEE80211_LINKED){
983 if (priv->ieee80211->iw_mode == IW_MODE_INFRA)
984 msr |= (MSR_LINK_MANAGED<<MSR_LINK_SHIFT);
985 else if (priv->ieee80211->iw_mode == IW_MODE_ADHOC)
986 msr |= (MSR_LINK_ADHOC<<MSR_LINK_SHIFT);
987 else if (priv->ieee80211->iw_mode == IW_MODE_MASTER)
988 msr |= (MSR_LINK_MASTER<<MSR_LINK_SHIFT);
991 msr |= (MSR_LINK_NONE<<MSR_LINK_SHIFT);
993 write_nic_byte(dev, MSR, msr);
996 void rtl8192_set_chan(struct net_device *dev,short ch)
998 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
999 RT_TRACE(COMP_RF, "=====>%s()====ch:%d\n", __FUNCTION__, ch);
1002 if(priv->ieee80211->iw_mode == IW_MODE_ADHOC ||
1003 priv->ieee80211->iw_mode == IW_MODE_MASTER){
1005 priv->ieee80211->link_state = WLAN_LINK_ASSOCIATED;
1006 priv->ieee80211->master_chan = ch;
1007 rtl8192_update_beacon_ch(dev);
1011 /* this hack should avoid frame TX during channel setting*/
1014 // tx = read_nic_dword(dev,TX_CONF);
1015 // tx &= ~TX_LOOPBACK_MASK;
1019 // write_nic_dword(dev,TX_CONF, tx |( TX_LOOPBACK_MAC<<TX_LOOPBACK_SHIFT));
1021 //need to implement rf set channel here WB
1023 if (priv->rf_set_chan)
1024 priv->rf_set_chan(dev,priv->chan);
1026 // write_nic_dword(dev,TX_CONF,tx | (TX_LOOPBACK_NONE<<TX_LOOPBACK_SHIFT));
1030 void rtl8192_rx_enable(struct net_device *dev)
1032 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1033 write_nic_dword(dev, RDQDA,priv->rx_ring_dma);
1036 /* the TX_DESC_BASE setting is according to the following queue index
1042 * TXCMD_QUEUE ===> 5
1045 * BEACON_QUEUE ===> 8
1047 static u32 TX_DESC_BASE[] = {BKQDA, BEQDA, VIQDA, VOQDA, HCCAQDA, CQDA, MQDA, HQDA, BQDA};
1048 void rtl8192_tx_enable(struct net_device *dev)
1050 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1052 for (i = 0; i < MAX_TX_QUEUE_COUNT; i++)
1053 write_nic_dword(dev, TX_DESC_BASE[i], priv->tx_ring[i].dma);
1055 ieee80211_reset_queue(priv->ieee80211);
1059 void rtl8192_beacon_tx_enable(struct net_device *dev)
1061 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1064 reg = read_nic_dword(priv->ieee80211->dev,INTA_MASK);
1066 /* enable Beacon realted interrupt signal */
1067 reg |= (IMR_BcnInt | IMR_BcnInt | IMR_TBDOK | IMR_TBDER);
1068 write_nic_byte(dev,reg);
1072 static void rtl8192_free_rx_ring(struct net_device *dev)
1074 struct r8192_priv *priv = ieee80211_priv(dev);
1077 for (i = 0; i < priv->rxringcount; i++) {
1078 struct sk_buff *skb = priv->rx_buf[i];
1082 pci_unmap_single(priv->pdev,
1083 *((dma_addr_t *)skb->cb),
1084 priv->rxbuffersize, PCI_DMA_FROMDEVICE);
1088 pci_free_consistent(priv->pdev, sizeof(*priv->rx_ring) * priv->rxringcount,
1089 priv->rx_ring, priv->rx_ring_dma);
1090 priv->rx_ring = NULL;
1093 static void rtl8192_free_tx_ring(struct net_device *dev, unsigned int prio)
1095 struct r8192_priv *priv = ieee80211_priv(dev);
1096 struct rtl8192_tx_ring *ring = &priv->tx_ring[prio];
1098 while (skb_queue_len(&ring->queue)) {
1099 tx_desc_819x_pci *entry = &ring->desc[ring->idx];
1100 struct sk_buff *skb = __skb_dequeue(&ring->queue);
1102 pci_unmap_single(priv->pdev, le32_to_cpu(entry->TxBuffAddr),
1103 skb->len, PCI_DMA_TODEVICE);
1105 ring->idx = (ring->idx + 1) % ring->entries;
1108 pci_free_consistent(priv->pdev, sizeof(*ring->desc)*ring->entries,
1109 ring->desc, ring->dma);
1114 static void rtl8192_beacon_disable(struct net_device *dev)
1116 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1119 reg = read_nic_dword(priv->ieee80211->dev,INTA_MASK);
1121 /* disable Beacon realted interrupt signal */
1122 reg &= ~(IMR_BcnInt | IMR_BcnInt | IMR_TBDOK | IMR_TBDER);
1123 write_nic_dword(priv->ieee80211->dev, INTA_MASK, reg);
1126 void rtl8192_rtx_disable(struct net_device *dev)
1129 struct r8192_priv *priv = ieee80211_priv(dev);
1132 cmd=read_nic_byte(dev,CMDR);
1133 // if(!priv->ieee80211->bSupportRemoteWakeUp) {
1134 write_nic_byte(dev, CMDR, cmd &~ \
1137 force_pci_posting(dev);
1140 for(i = 0; i < MAX_QUEUE_SIZE; i++) {
1141 skb_queue_purge(&priv->ieee80211->skb_waitQ [i]);
1143 for(i = 0; i < MAX_QUEUE_SIZE; i++) {
1144 skb_queue_purge(&priv->ieee80211->skb_aggQ [i]);
1148 skb_queue_purge(&priv->skb_queue);
1152 static void rtl8192_reset(struct net_device *dev)
1154 rtl8192_irq_disable(dev);
1155 printk("This is RTL819xP Reset procedure\n");
1158 static u16 rtl_rate[] = {10,20,55,110,60,90,120,180,240,360,480,540};
1159 inline u16 rtl8192_rate2rate(short rate)
1161 if (rate >11) return 0;
1162 return rtl_rate[rate];
1167 static u32 rtl819xusb_rx_command_packet(struct net_device *dev, struct ieee80211_rx_stats *pstats)
1171 //RT_TRACE(COMP_RECV, DBG_TRACE, ("---> RxCommandPacketHandle819xUsb()\n"));
1173 RT_TRACE(COMP_EVENTS, "---->rtl819xusb_rx_command_packet()\n");
1174 status = cmpk_message_handle_rx(dev, pstats);
1177 DMESG("rxcommandpackethandle819xusb: It is a command packet\n");
1181 //RT_TRACE(COMP_RECV, DBG_TRACE, ("RxCommandPacketHandle819xUsb: It is not a command packet\n"));
1184 //RT_TRACE(COMP_RECV, DBG_TRACE, ("<--- RxCommandPacketHandle819xUsb()\n"));
1189 void rtl8192_tx_queues_stop(struct net_device *dev)
1191 //struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1192 u8 dma_poll_mask = (1<<TX_DMA_STOP_LOWPRIORITY_SHIFT);
1193 dma_poll_mask |= (1<<TX_DMA_STOP_HIPRIORITY_SHIFT);
1194 dma_poll_mask |= (1<<TX_DMA_STOP_NORMPRIORITY_SHIFT);
1195 dma_poll_mask |= (1<<TX_DMA_STOP_BEACON_SHIFT);
1197 rtl8192_set_mode(dev,EPROM_CMD_CONFIG);
1198 write_nic_byte(dev,TX_DMA_POLLING,dma_poll_mask);
1199 rtl8192_set_mode(dev,EPROM_CMD_NORMAL);
1203 static void rtl8192_data_hard_stop(struct net_device *dev)
1207 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1208 priv->dma_poll_mask |= (1<<TX_DMA_STOP_LOWPRIORITY_SHIFT);
1209 rtl8192_set_mode(dev,EPROM_CMD_CONFIG);
1210 write_nic_byte(dev,TX_DMA_POLLING,priv->dma_poll_mask);
1211 rtl8192_set_mode(dev,EPROM_CMD_NORMAL);
1216 static void rtl8192_data_hard_resume(struct net_device *dev)
1220 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1221 priv->dma_poll_mask &= ~(1<<TX_DMA_STOP_LOWPRIORITY_SHIFT);
1222 rtl8192_set_mode(dev,EPROM_CMD_CONFIG);
1223 write_nic_byte(dev,TX_DMA_POLLING,priv->dma_poll_mask);
1224 rtl8192_set_mode(dev,EPROM_CMD_NORMAL);
1228 /* this function TX data frames when the ieee80211 stack requires this.
1229 * It checks also if we need to stop the ieee tx queue, eventually do it
1231 static void rtl8192_hard_data_xmit(struct sk_buff *skb, struct net_device *dev, int rate)
1233 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1235 //unsigned long flags;
1236 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1237 u8 queue_index = tcb_desc->queue_index;
1238 /* shall not be referred by command packet */
1239 assert(queue_index != TXCMD_QUEUE);
1241 //spin_lock_irqsave(&priv->tx_lock,flags);
1243 memcpy((unsigned char *)(skb->cb),&dev,sizeof(dev));
1245 tcb_desc->RATRIndex = 7;
1246 tcb_desc->bTxDisableRateFallBack = 1;
1247 tcb_desc->bTxUseDriverAssingedRate = 1;
1248 tcb_desc->bTxEnableFwCalcDur = 1;
1250 skb_push(skb, priv->ieee80211->tx_headroom);
1251 ret = rtl8192_tx(dev, skb);
1257 if(queue_index!=MGNT_QUEUE) {
1258 priv->ieee80211->stats.tx_bytes+=(skb->len - priv->ieee80211->tx_headroom);
1259 priv->ieee80211->stats.tx_packets++;
1262 //spin_unlock_irqrestore(&priv->tx_lock,flags);
1268 /* This is a rough attempt to TX a frame
1269 * This is called by the ieee 80211 stack to TX management frames.
1270 * If the ring is full packet are dropped (for data frame the queue
1271 * is stopped before this can happen).
1273 static int rtl8192_hard_start_xmit(struct sk_buff *skb,struct net_device *dev)
1275 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1279 //unsigned long flags;
1280 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1281 u8 queue_index = tcb_desc->queue_index;
1284 //spin_lock_irqsave(&priv->tx_lock,flags);
1286 memcpy((unsigned char *)(skb->cb),&dev,sizeof(dev));
1287 if(queue_index == TXCMD_QUEUE) {
1288 // skb_push(skb, USB_HWDESC_HEADER_LEN);
1289 rtl819xE_tx_cmd(dev, skb);
1291 //spin_unlock_irqrestore(&priv->tx_lock,flags);
1294 // RT_TRACE(COMP_SEND, "To send management packet\n");
1295 tcb_desc->RATRIndex = 7;
1296 tcb_desc->bTxDisableRateFallBack = 1;
1297 tcb_desc->bTxUseDriverAssingedRate = 1;
1298 tcb_desc->bTxEnableFwCalcDur = 1;
1299 skb_push(skb, priv->ieee80211->tx_headroom);
1300 ret = rtl8192_tx(dev, skb);
1306 // priv->ieee80211->stats.tx_bytes+=skb->len;
1307 // priv->ieee80211->stats.tx_packets++;
1309 //spin_unlock_irqrestore(&priv->tx_lock,flags);
1316 void rtl8192_try_wake_queue(struct net_device *dev, int pri);
1318 static void rtl8192_tx_isr(struct net_device *dev, int prio)
1320 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1322 struct rtl8192_tx_ring *ring = &priv->tx_ring[prio];
1324 while (skb_queue_len(&ring->queue)) {
1325 tx_desc_819x_pci *entry = &ring->desc[ring->idx];
1326 struct sk_buff *skb;
1328 /* beacon packet will only use the first descriptor defautly,
1329 * and the OWN may not be cleared by the hardware
1331 if(prio != BEACON_QUEUE) {
1334 ring->idx = (ring->idx + 1) % ring->entries;
1337 skb = __skb_dequeue(&ring->queue);
1338 pci_unmap_single(priv->pdev, le32_to_cpu(entry->TxBuffAddr),
1339 skb->len, PCI_DMA_TODEVICE);
1343 if (prio == MGNT_QUEUE){
1344 if (priv->ieee80211->ack_tx_to_ieee){
1345 if (rtl8192_is_tx_queue_empty(dev)){
1346 priv->ieee80211->ack_tx_to_ieee = 0;
1347 ieee80211_ps_tx_ack(priv->ieee80211, 1);
1352 if(prio != BEACON_QUEUE) {
1353 /* try to deal with the pending packets */
1354 tasklet_schedule(&priv->irq_tx_tasklet);
1359 static void rtl8192_stop_beacon(struct net_device *dev)
1361 //rtl8192_beacon_disable(dev);
1364 static void rtl8192_config_rate(struct net_device* dev, u16* rate_config)
1366 struct r8192_priv *priv = ieee80211_priv(dev);
1367 struct ieee80211_network *net;
1368 u8 i=0, basic_rate = 0;
1369 net = & priv->ieee80211->current_network;
1371 for (i=0; i<net->rates_len; i++)
1373 basic_rate = net->rates[i]&0x7f;
1376 case MGN_1M: *rate_config |= RRSR_1M; break;
1377 case MGN_2M: *rate_config |= RRSR_2M; break;
1378 case MGN_5_5M: *rate_config |= RRSR_5_5M; break;
1379 case MGN_11M: *rate_config |= RRSR_11M; break;
1380 case MGN_6M: *rate_config |= RRSR_6M; break;
1381 case MGN_9M: *rate_config |= RRSR_9M; break;
1382 case MGN_12M: *rate_config |= RRSR_12M; break;
1383 case MGN_18M: *rate_config |= RRSR_18M; break;
1384 case MGN_24M: *rate_config |= RRSR_24M; break;
1385 case MGN_36M: *rate_config |= RRSR_36M; break;
1386 case MGN_48M: *rate_config |= RRSR_48M; break;
1387 case MGN_54M: *rate_config |= RRSR_54M; break;
1390 for (i=0; i<net->rates_ex_len; i++)
1392 basic_rate = net->rates_ex[i]&0x7f;
1395 case MGN_1M: *rate_config |= RRSR_1M; break;
1396 case MGN_2M: *rate_config |= RRSR_2M; break;
1397 case MGN_5_5M: *rate_config |= RRSR_5_5M; break;
1398 case MGN_11M: *rate_config |= RRSR_11M; break;
1399 case MGN_6M: *rate_config |= RRSR_6M; break;
1400 case MGN_9M: *rate_config |= RRSR_9M; break;
1401 case MGN_12M: *rate_config |= RRSR_12M; break;
1402 case MGN_18M: *rate_config |= RRSR_18M; break;
1403 case MGN_24M: *rate_config |= RRSR_24M; break;
1404 case MGN_36M: *rate_config |= RRSR_36M; break;
1405 case MGN_48M: *rate_config |= RRSR_48M; break;
1406 case MGN_54M: *rate_config |= RRSR_54M; break;
1412 #define SHORT_SLOT_TIME 9
1413 #define NON_SHORT_SLOT_TIME 20
1415 static void rtl8192_update_cap(struct net_device* dev, u16 cap)
1418 struct r8192_priv *priv = ieee80211_priv(dev);
1419 struct ieee80211_network *net = &priv->ieee80211->current_network;
1420 priv->short_preamble = cap & WLAN_CAPABILITY_SHORT_PREAMBLE;
1421 tmp = priv->basic_rate;
1422 if (priv->short_preamble)
1423 tmp |= BRSR_AckShortPmb;
1424 write_nic_dword(dev, RRSR, tmp);
1426 if (net->mode & (IEEE_G|IEEE_N_24G))
1429 if ((cap & WLAN_CAPABILITY_SHORT_SLOT)&&(!priv->ieee80211->pHTInfo->bCurrentRT2RTLongSlotTime))
1431 slot_time = SHORT_SLOT_TIME;
1433 else //long slot time
1434 slot_time = NON_SHORT_SLOT_TIME;
1435 priv->slot_time = slot_time;
1436 write_nic_byte(dev, SLOT_TIME, slot_time);
1441 static void rtl8192_net_update(struct net_device *dev)
1444 struct r8192_priv *priv = ieee80211_priv(dev);
1445 struct ieee80211_network *net;
1446 u16 BcnTimeCfg = 0, BcnCW = 6, BcnIFS = 0xf;
1447 u16 rate_config = 0;
1448 net = &priv->ieee80211->current_network;
1449 //update Basic rate: RR, BRSR
1450 rtl8192_config_rate(dev, &rate_config);
1451 // 2007.01.16, by Emily
1452 // Select RRSR (in Legacy-OFDM and CCK)
1453 // For 8190, we select only 24M, 12M, 6M, 11M, 5.5M, 2M, and 1M from the Basic rate.
1454 // We do not use other rates.
1455 priv->basic_rate = rate_config &= 0x15f;
1457 write_nic_dword(dev,BSSIDR,((u32*)net->bssid)[0]);
1458 write_nic_word(dev,BSSIDR+4,((u16*)net->bssid)[2]);
1461 rtl8192_update_msr(dev);
1465 // rtl8192_update_cap(dev, net->capability);
1466 if (priv->ieee80211->iw_mode == IW_MODE_ADHOC)
1468 write_nic_word(dev, ATIMWND, 2);
1469 write_nic_word(dev, BCN_DMATIME, 256);
1470 write_nic_word(dev, BCN_INTERVAL, net->beacon_interval);
1471 // write_nic_word(dev, BcnIntTime, 100);
1472 //BIT15 of BCN_DRV_EARLY_INT will indicate whether software beacon or hw beacon is applied.
1473 write_nic_word(dev, BCN_DRV_EARLY_INT, 10);
1474 write_nic_byte(dev, BCN_ERR_THRESH, 100);
1476 BcnTimeCfg |= (BcnCW<<BCN_TCFG_CW_SHIFT);
1477 // TODO: BcnIFS may required to be changed on ASIC
1478 BcnTimeCfg |= BcnIFS<<BCN_TCFG_IFS;
1480 write_nic_word(dev, BCN_TCFG, BcnTimeCfg);
1486 inline u8 rtl8192_IsWirelessBMode(u16 rate)
1488 if( ((rate <= 110) && (rate != 60) && (rate != 90)) || (rate == 220) )
1493 u16 N_DBPSOfRate(u16 DataRate);
1495 static u16 ComputeTxTime(
1498 u8 bManagementFrame,
1506 if( rtl8192_IsWirelessBMode(DataRate) )
1508 if( bManagementFrame || !bShortPreamble || DataRate == 10 )
1510 FrameTime = (u16)(144+48+(FrameLength*8/(DataRate/10)));
1514 FrameTime = (u16)(72+24+(FrameLength*8/(DataRate/10)));
1516 if( ( FrameLength*8 % (DataRate/10) ) != 0 ) //Get the Ceilling
1518 } else { //802.11g DSSS-OFDM PLCP length field calculation.
1519 N_DBPS = N_DBPSOfRate(DataRate);
1520 Ceiling = (16 + 8*FrameLength + 6) / N_DBPS
1521 + (((16 + 8*FrameLength + 6) % N_DBPS) ? 1 : 0);
1522 FrameTime = (u16)(16 + 4 + 4*Ceiling + 6);
1527 u16 N_DBPSOfRate(u16 DataRate)
1572 static unsigned int txqueue2outpipe(unsigned int tx_queue)
1574 unsigned int outpipe = 0x04;
1593 case HCCA_QUEUE://EP8
1597 case BEACON_QUEUE://EPA
1601 case HIGH_QUEUE://EPB
1605 case MGNT_QUEUE://EPC
1609 case TXCMD_QUEUE://EPD
1614 printk("Unknow queue index!\n");
1621 void rtl819xE_tx_cmd(struct net_device *dev, struct sk_buff *skb)
1623 struct r8192_priv *priv = ieee80211_priv(dev);
1624 struct rtl8192_tx_ring *ring;
1625 tx_desc_819x_pci *entry;
1629 unsigned long flags;
1631 ring = &priv->tx_ring[TXCMD_QUEUE];
1632 mapping = pci_map_single(priv->pdev, skb->data, skb->len, PCI_DMA_TODEVICE);
1634 spin_lock_irqsave(&priv->irq_th_lock,flags);
1635 idx = (ring->idx + skb_queue_len(&ring->queue)) % ring->entries;
1636 entry = &ring->desc[idx];
1638 tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1640 entry->LINIP = tcb_desc->bLastIniPkt;
1641 entry->FirstSeg = 1;//first segment
1642 entry->LastSeg = 1; //last segment
1643 if(tcb_desc->bCmdOrInit == DESC_PACKET_TYPE_INIT) {
1644 entry->CmdInit = DESC_PACKET_TYPE_INIT;
1646 entry->CmdInit = DESC_PACKET_TYPE_NORMAL;
1647 entry->Offset = sizeof(TX_FWINFO_8190PCI) + 8;
1648 entry->PktSize = (u16)(tcb_desc->pkt_size + entry->Offset);
1649 entry->QueueSelect = QSLT_CMD;
1650 entry->TxFWInfoSize = 0x08;
1651 entry->RATid = (u8)DESC_PACKET_TYPE_INIT;
1653 entry->TxBufferSize = skb->len;
1654 entry->TxBuffAddr = cpu_to_le32(mapping);
1657 #ifdef JOHN_DUMP_TXDESC
1659 tx_desc_819x_pci *entry1 = &ring->desc[0];
1660 unsigned int *ptr= (unsigned int *)entry1;
1661 printk("<Tx descriptor>:\n");
1662 for (i = 0; i < 8; i++)
1663 printk("%8x ", ptr[i]);
1667 __skb_queue_tail(&ring->queue, skb);
1668 spin_unlock_irqrestore(&priv->irq_th_lock,flags);
1670 write_nic_byte(dev, TPPoll, TPPoll_CQ);
1676 * Mapping Software/Hardware descriptor queue id to "Queue Select Field"
1677 * in TxFwInfo data structure
1678 * 2006.10.30 by Emily
1680 * \param QUEUEID Software Queue
1682 static u8 MapHwQueueToFirmwareQueue(u8 QueueID)
1684 u8 QueueSelect = 0x0; //defualt set to
1688 QueueSelect = QSLT_BE; //or QSelect = pTcb->priority;
1692 QueueSelect = QSLT_BK; //or QSelect = pTcb->priority;
1696 QueueSelect = QSLT_VO; //or QSelect = pTcb->priority;
1700 QueueSelect = QSLT_VI; //or QSelect = pTcb->priority;
1703 QueueSelect = QSLT_MGNT;
1707 QueueSelect = QSLT_BEACON;
1710 // TODO: 2006.10.30 mark other queue selection until we verify it is OK
1711 // TODO: Remove Assertions
1712 //#if (RTL819X_FPGA_VER & RTL819X_FPGA_GUANGAN_070502)
1714 QueueSelect = QSLT_CMD;
1718 //QueueSelect = QSLT_HIGH;
1722 RT_TRACE(COMP_ERR, "TransmitTCB(): Impossible Queue Selection: %d \n", QueueID);
1728 static u8 MRateToHwRate8190Pci(u8 rate)
1730 u8 ret = DESC90_RATE1M;
1733 case MGN_1M: ret = DESC90_RATE1M; break;
1734 case MGN_2M: ret = DESC90_RATE2M; break;
1735 case MGN_5_5M: ret = DESC90_RATE5_5M; break;
1736 case MGN_11M: ret = DESC90_RATE11M; break;
1737 case MGN_6M: ret = DESC90_RATE6M; break;
1738 case MGN_9M: ret = DESC90_RATE9M; break;
1739 case MGN_12M: ret = DESC90_RATE12M; break;
1740 case MGN_18M: ret = DESC90_RATE18M; break;
1741 case MGN_24M: ret = DESC90_RATE24M; break;
1742 case MGN_36M: ret = DESC90_RATE36M; break;
1743 case MGN_48M: ret = DESC90_RATE48M; break;
1744 case MGN_54M: ret = DESC90_RATE54M; break;
1746 // HT rate since here
1747 case MGN_MCS0: ret = DESC90_RATEMCS0; break;
1748 case MGN_MCS1: ret = DESC90_RATEMCS1; break;
1749 case MGN_MCS2: ret = DESC90_RATEMCS2; break;
1750 case MGN_MCS3: ret = DESC90_RATEMCS3; break;
1751 case MGN_MCS4: ret = DESC90_RATEMCS4; break;
1752 case MGN_MCS5: ret = DESC90_RATEMCS5; break;
1753 case MGN_MCS6: ret = DESC90_RATEMCS6; break;
1754 case MGN_MCS7: ret = DESC90_RATEMCS7; break;
1755 case MGN_MCS8: ret = DESC90_RATEMCS8; break;
1756 case MGN_MCS9: ret = DESC90_RATEMCS9; break;
1757 case MGN_MCS10: ret = DESC90_RATEMCS10; break;
1758 case MGN_MCS11: ret = DESC90_RATEMCS11; break;
1759 case MGN_MCS12: ret = DESC90_RATEMCS12; break;
1760 case MGN_MCS13: ret = DESC90_RATEMCS13; break;
1761 case MGN_MCS14: ret = DESC90_RATEMCS14; break;
1762 case MGN_MCS15: ret = DESC90_RATEMCS15; break;
1763 case (0x80|0x20): ret = DESC90_RATEMCS32; break;
1771 static u8 QueryIsShort(u8 TxHT, u8 TxRate, cb_desc *tcb_desc)
1775 tmp_Short = (TxHT==1)?((tcb_desc->bUseShortGI)?1:0):((tcb_desc->bUseShortPreamble)?1:0);
1777 if(TxHT==1 && TxRate != DESC90_RATEMCS15)
1784 * The tx procedure is just as following,
1785 * skb->cb will contain all the following information,
1786 * priority, morefrag, rate, &dev.
1788 short rtl8192_tx(struct net_device *dev, struct sk_buff* skb)
1790 struct r8192_priv *priv = ieee80211_priv(dev);
1791 struct rtl8192_tx_ring *ring;
1792 unsigned long flags;
1793 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1794 tx_desc_819x_pci *pdesc = NULL;
1795 TX_FWINFO_8190PCI *pTxFwInfo = NULL;
1797 bool multi_addr=false,broad_addr=false,uni_addr=false;
1798 u8* pda_addr = NULL;
1801 mapping = pci_map_single(priv->pdev, skb->data, skb->len, PCI_DMA_TODEVICE);
1802 /* collect the tx packets statitcs */
1803 pda_addr = ((u8*)skb->data) + sizeof(TX_FWINFO_8190PCI);
1804 if(is_multicast_ether_addr(pda_addr))
1806 else if(is_broadcast_ether_addr(pda_addr))
1812 priv->stats.txbytesunicast += (u8)(skb->len) - sizeof(TX_FWINFO_8190PCI);
1814 priv->stats.txbytesmulticast +=(u8)(skb->len) - sizeof(TX_FWINFO_8190PCI);
1816 priv->stats.txbytesbroadcast += (u8)(skb->len) - sizeof(TX_FWINFO_8190PCI);
1818 /* fill tx firmware */
1819 pTxFwInfo = (PTX_FWINFO_8190PCI)skb->data;
1820 memset(pTxFwInfo,0,sizeof(TX_FWINFO_8190PCI));
1821 pTxFwInfo->TxHT = (tcb_desc->data_rate&0x80)?1:0;
1822 pTxFwInfo->TxRate = MRateToHwRate8190Pci((u8)tcb_desc->data_rate);
1823 pTxFwInfo->EnableCPUDur = tcb_desc->bTxEnableFwCalcDur;
1824 pTxFwInfo->Short = QueryIsShort(pTxFwInfo->TxHT, pTxFwInfo->TxRate, tcb_desc);
1826 /* Aggregation related */
1827 if(tcb_desc->bAMPDUEnable) {
1828 pTxFwInfo->AllowAggregation = 1;
1829 pTxFwInfo->RxMF = tcb_desc->ampdu_factor;
1830 pTxFwInfo->RxAMD = tcb_desc->ampdu_density;
1832 pTxFwInfo->AllowAggregation = 0;
1833 pTxFwInfo->RxMF = 0;
1834 pTxFwInfo->RxAMD = 0;
1838 // Protection mode related
1840 pTxFwInfo->RtsEnable = (tcb_desc->bRTSEnable)?1:0;
1841 pTxFwInfo->CtsEnable = (tcb_desc->bCTSEnable)?1:0;
1842 pTxFwInfo->RtsSTBC = (tcb_desc->bRTSSTBC)?1:0;
1843 pTxFwInfo->RtsHT= (tcb_desc->rts_rate&0x80)?1:0;
1844 pTxFwInfo->RtsRate = MRateToHwRate8190Pci((u8)tcb_desc->rts_rate);
1845 pTxFwInfo->RtsBandwidth = 0;
1846 pTxFwInfo->RtsSubcarrier = tcb_desc->RTSSC;
1847 pTxFwInfo->RtsShort = (pTxFwInfo->RtsHT==0)?(tcb_desc->bRTSUseShortPreamble?1:0):(tcb_desc->bRTSUseShortGI?1:0);
1849 // Set Bandwidth and sub-channel settings.
1851 if(priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20_40)
1853 if(tcb_desc->bPacketBW)
1855 pTxFwInfo->TxBandwidth = 1;
1857 pTxFwInfo->TxSubCarrier = 3;
1859 pTxFwInfo->TxSubCarrier = 0; //By SD3's Jerry suggestion, use duplicated mode, cosa 04012008
1864 pTxFwInfo->TxBandwidth = 0;
1865 pTxFwInfo->TxSubCarrier = priv->nCur40MhzPrimeSC;
1868 pTxFwInfo->TxBandwidth = 0;
1869 pTxFwInfo->TxSubCarrier = 0;
1874 /* 2007/07/25 MH Copy current TX FW info.*/
1875 memcpy((void*)(&Tmp_TxFwInfo), (void*)(pTxFwInfo), sizeof(TX_FWINFO_8190PCI));
1876 printk("&&&&&&&&&&&&&&&&&&&&&&====>print out fwinf\n");
1877 printk("===>enable fwcacl:%d\n", Tmp_TxFwInfo.EnableCPUDur);
1878 printk("===>RTS STBC:%d\n", Tmp_TxFwInfo.RtsSTBC);
1879 printk("===>RTS Subcarrier:%d\n", Tmp_TxFwInfo.RtsSubcarrier);
1880 printk("===>Allow Aggregation:%d\n", Tmp_TxFwInfo.AllowAggregation);
1881 printk("===>TX HT bit:%d\n", Tmp_TxFwInfo.TxHT);
1882 printk("===>Tx rate:%d\n", Tmp_TxFwInfo.TxRate);
1883 printk("===>Received AMPDU Density:%d\n", Tmp_TxFwInfo.RxAMD);
1884 printk("===>Received MPDU Factor:%d\n", Tmp_TxFwInfo.RxMF);
1885 printk("===>TxBandwidth:%d\n", Tmp_TxFwInfo.TxBandwidth);
1886 printk("===>TxSubCarrier:%d\n", Tmp_TxFwInfo.TxSubCarrier);
1888 printk("<=====**********************out of print\n");
1891 spin_lock_irqsave(&priv->irq_th_lock,flags);
1892 ring = &priv->tx_ring[tcb_desc->queue_index];
1893 if (tcb_desc->queue_index != BEACON_QUEUE) {
1894 idx = (ring->idx + skb_queue_len(&ring->queue)) % ring->entries;
1899 pdesc = &ring->desc[idx];
1900 if((pdesc->OWN == 1) && (tcb_desc->queue_index != BEACON_QUEUE)) {
1901 RT_TRACE(COMP_ERR,"No more TX desc@%d, ring->idx = %d,idx = %d,%x", \
1902 tcb_desc->queue_index,ring->idx, idx,skb->len);
1906 /* fill tx descriptor */
1907 memset((u8*)pdesc,0,12);
1911 pdesc->Offset = sizeof(TX_FWINFO_8190PCI) + 8; //We must add 8!! Emily
1912 pdesc->PktSize = (u16)skb->len-sizeof(TX_FWINFO_8190PCI);
1916 pdesc->RATid = tcb_desc->RATRIndex;
1920 pdesc->SecType = 0x0;
1921 if (tcb_desc->bHwSec) {
1924 printk("==>================hw sec\n");
1927 switch (priv->ieee80211->pairwise_key_type) {
1928 case KEY_TYPE_WEP40:
1929 case KEY_TYPE_WEP104:
1930 pdesc->SecType = 0x1;
1934 pdesc->SecType = 0x2;
1938 pdesc->SecType = 0x3;
1942 pdesc->SecType = 0x0;
1953 pdesc->QueueSelect = MapHwQueueToFirmwareQueue(tcb_desc->queue_index);
1954 pdesc->TxFWInfoSize = sizeof(TX_FWINFO_8190PCI);
1956 pdesc->DISFB = tcb_desc->bTxDisableRateFallBack;
1957 pdesc->USERATE = tcb_desc->bTxUseDriverAssingedRate;
1961 pdesc->TxBufferSize = skb->len;
1963 pdesc->TxBuffAddr = cpu_to_le32(mapping);
1964 __skb_queue_tail(&ring->queue, skb);
1966 spin_unlock_irqrestore(&priv->irq_th_lock,flags);
1967 dev->trans_start = jiffies;
1968 write_nic_word(dev,TPPoll,0x01<<tcb_desc->queue_index);
1972 static short rtl8192_alloc_rx_desc_ring(struct net_device *dev)
1974 struct r8192_priv *priv = ieee80211_priv(dev);
1975 rx_desc_819x_pci *entry = NULL;
1978 priv->rx_ring = pci_alloc_consistent(priv->pdev,
1979 sizeof(*priv->rx_ring) * priv->rxringcount, &priv->rx_ring_dma);
1981 if (!priv->rx_ring || (unsigned long)priv->rx_ring & 0xFF) {
1982 RT_TRACE(COMP_ERR,"Cannot allocate RX ring\n");
1986 memset(priv->rx_ring, 0, sizeof(*priv->rx_ring) * priv->rxringcount);
1989 for (i = 0; i < priv->rxringcount; i++) {
1990 struct sk_buff *skb = dev_alloc_skb(priv->rxbuffersize);
1991 dma_addr_t *mapping;
1992 entry = &priv->rx_ring[i];
1995 priv->rx_buf[i] = skb;
1996 mapping = (dma_addr_t *)skb->cb;
1997 *mapping = pci_map_single(priv->pdev, skb->tail,//skb_tail_pointer(skb),
1998 priv->rxbuffersize, PCI_DMA_FROMDEVICE);
2000 entry->BufferAddress = cpu_to_le32(*mapping);
2002 entry->Length = priv->rxbuffersize;
2010 static int rtl8192_alloc_tx_desc_ring(struct net_device *dev,
2011 unsigned int prio, unsigned int entries)
2013 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
2014 tx_desc_819x_pci *ring;
2018 ring = pci_alloc_consistent(priv->pdev, sizeof(*ring) * entries, &dma);
2019 if (!ring || (unsigned long)ring & 0xFF) {
2020 RT_TRACE(COMP_ERR, "Cannot allocate TX ring (prio = %d)\n", prio);
2024 memset(ring, 0, sizeof(*ring)*entries);
2025 priv->tx_ring[prio].desc = ring;
2026 priv->tx_ring[prio].dma = dma;
2027 priv->tx_ring[prio].idx = 0;
2028 priv->tx_ring[prio].entries = entries;
2029 skb_queue_head_init(&priv->tx_ring[prio].queue);
2031 for (i = 0; i < entries; i++)
2032 ring[i].NextDescAddress =
2033 cpu_to_le32((u32)dma + ((i + 1) % entries) * sizeof(*ring));
2039 static short rtl8192_pci_initdescring(struct net_device *dev)
2043 struct r8192_priv *priv = ieee80211_priv(dev);
2045 ret = rtl8192_alloc_rx_desc_ring(dev);
2051 /* general process for other queue */
2052 for (i = 0; i < MAX_TX_QUEUE_COUNT; i++) {
2053 if ((ret = rtl8192_alloc_tx_desc_ring(dev, i, priv->txringcount)))
2054 goto err_free_rings;
2058 /* specific process for hardware beacon process */
2059 if ((ret = rtl8192_alloc_tx_desc_ring(dev, MAX_TX_QUEUE_COUNT - 1, 2)))
2060 goto err_free_rings;
2066 rtl8192_free_rx_ring(dev);
2067 for (i = 0; i < MAX_TX_QUEUE_COUNT; i++)
2068 if (priv->tx_ring[i].desc)
2069 rtl8192_free_tx_ring(dev, i);
2073 static void rtl8192_pci_resetdescring(struct net_device *dev)
2075 struct r8192_priv *priv = ieee80211_priv(dev);
2078 /* force the rx_idx to the first one */
2080 rx_desc_819x_pci *entry = NULL;
2081 for (i = 0; i < priv->rxringcount; i++) {
2082 entry = &priv->rx_ring[i];
2088 /* after reset, release previous pending packet, and force the
2089 * tx idx to the first one */
2090 for (i = 0; i < MAX_TX_QUEUE_COUNT; i++) {
2091 if (priv->tx_ring[i].desc) {
2092 struct rtl8192_tx_ring *ring = &priv->tx_ring[i];
2094 while (skb_queue_len(&ring->queue)) {
2095 tx_desc_819x_pci *entry = &ring->desc[ring->idx];
2096 struct sk_buff *skb = __skb_dequeue(&ring->queue);
2098 pci_unmap_single(priv->pdev, le32_to_cpu(entry->TxBuffAddr),
2099 skb->len, PCI_DMA_TODEVICE);
2101 ring->idx = (ring->idx + 1) % ring->entries;
2109 extern void rtl8192_update_ratr_table(struct net_device* dev);
2110 static void rtl8192_link_change(struct net_device *dev)
2114 struct r8192_priv *priv = ieee80211_priv(dev);
2115 struct ieee80211_device* ieee = priv->ieee80211;
2116 //write_nic_word(dev, BCN_INTR_ITV, net->beacon_interval);
2117 if (ieee->state == IEEE80211_LINKED)
2119 rtl8192_net_update(dev);
2120 rtl8192_update_ratr_table(dev);
2122 //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
2123 if ((KEY_TYPE_WEP40 == ieee->pairwise_key_type) || (KEY_TYPE_WEP104 == ieee->pairwise_key_type))
2124 EnableHWSecurityConfig8192(dev);
2129 write_nic_byte(dev, 0x173, 0);
2131 /*update timing params*/
2132 //rtl8192_set_chan(dev, priv->chan);
2134 rtl8192_update_msr(dev);
2136 // 2007/10/16 MH MAC Will update TSF according to all received beacon, so we have
2137 // // To set CBSSID bit when link with any AP or STA.
2138 if (ieee->iw_mode == IW_MODE_INFRA || ieee->iw_mode == IW_MODE_ADHOC)
2141 reg = read_nic_dword(dev, RCR);
2142 if (priv->ieee80211->state == IEEE80211_LINKED)
2143 priv->ReceiveConfig = reg |= RCR_CBSSID;
2145 priv->ReceiveConfig = reg &= ~RCR_CBSSID;
2146 write_nic_dword(dev, RCR, reg);
2152 static struct ieee80211_qos_parameters def_qos_parameters = {
2153 {3,3,3,3},/* cw_min */
2154 {7,7,7,7},/* cw_max */
2155 {2,2,2,2},/* aifs */
2156 {0,0,0,0},/* flags */
2157 {0,0,0,0} /* tx_op_limit */
2160 #if LINUX_VERSION_CODE >=KERNEL_VERSION(2,6,20)
2161 static void rtl8192_update_beacon(struct work_struct * work)
2163 struct r8192_priv *priv = container_of(work, struct r8192_priv, update_beacon_wq.work);
2164 struct net_device *dev = priv->ieee80211->dev;
2166 void rtl8192_update_beacon(struct net_device *dev)
2168 struct r8192_priv *priv = ieee80211_priv(dev);
2170 struct ieee80211_device* ieee = priv->ieee80211;
2171 struct ieee80211_network* net = &ieee->current_network;
2173 if (ieee->pHTInfo->bCurrentHTSupport)
2174 HTUpdateSelfAndPeerSetting(ieee, net);
2175 ieee->pHTInfo->bCurrentRT2RTLongSlotTime = net->bssht.bdRT2RTLongSlotTime;
2176 rtl8192_update_cap(dev, net->capability);
2179 * background support to run QoS activate functionality
2181 static int WDCAPARA_ADD[] = {EDCAPARA_BE,EDCAPARA_BK,EDCAPARA_VI,EDCAPARA_VO};
2182 #if LINUX_VERSION_CODE >=KERNEL_VERSION(2,6,20)
2183 static void rtl8192_qos_activate(struct work_struct * work)
2185 struct r8192_priv *priv = container_of(work, struct r8192_priv, qos_activate);
2186 struct net_device *dev = priv->ieee80211->dev;
2188 void rtl8192_qos_activate(struct net_device *dev)
2190 struct r8192_priv *priv = ieee80211_priv(dev);
2192 struct ieee80211_qos_parameters *qos_parameters = &priv->ieee80211->current_network.qos_data.parameters;
2193 u8 mode = priv->ieee80211->current_network.mode;
2194 // u32 size = sizeof(struct ieee80211_qos_parameters);
2201 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16))
2204 mutex_lock(&priv->mutex);
2206 if(priv->ieee80211->state != IEEE80211_LINKED)
2208 RT_TRACE(COMP_QOS,"qos active process with associate response received\n");
2209 /* It better set slot time at first */
2210 /* For we just support b/g mode at present, let the slot time at 9/20 selection */
2211 /* update the ac parameter to related registers */
2212 for(i = 0; i < QOS_QUEUE_NUM; i++) {
2213 //Mode G/A: slotTimeTimer = 9; Mode B: 20
2214 u1bAIFS = qos_parameters->aifs[i] * ((mode&(IEEE_G|IEEE_N_24G)) ?9:20) + aSifsTime;
2215 u4bAcParam = ((((u32)(qos_parameters->tx_op_limit[i]))<< AC_PARAM_TXOP_LIMIT_OFFSET)|
2216 (((u32)(qos_parameters->cw_max[i]))<< AC_PARAM_ECW_MAX_OFFSET)|
2217 (((u32)(qos_parameters->cw_min[i]))<< AC_PARAM_ECW_MIN_OFFSET)|
2218 ((u32)u1bAIFS << AC_PARAM_AIFS_OFFSET));
2219 printk("===>u4bAcParam:%x, ", u4bAcParam);
2220 write_nic_dword(dev, WDCAPARA_ADD[i], u4bAcParam);
2221 //write_nic_dword(dev, WDCAPARA_ADD[i], 0x005e4332);
2225 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16))
2228 mutex_unlock(&priv->mutex);
2232 static int rtl8192_qos_handle_probe_response(struct r8192_priv *priv,
2234 struct ieee80211_network *network)
2237 u32 size = sizeof(struct ieee80211_qos_parameters);
2239 if(priv->ieee80211->state !=IEEE80211_LINKED)
2242 if ((priv->ieee80211->iw_mode != IW_MODE_INFRA))
2245 if (network->flags & NETWORK_HAS_QOS_MASK) {
2246 if (active_network &&
2247 (network->flags & NETWORK_HAS_QOS_PARAMETERS))
2248 network->qos_data.active = network->qos_data.supported;
2250 if ((network->qos_data.active == 1) && (active_network == 1) &&
2251 (network->flags & NETWORK_HAS_QOS_PARAMETERS) &&
2252 (network->qos_data.old_param_count !=
2253 network->qos_data.param_count)) {
2254 network->qos_data.old_param_count =
2255 network->qos_data.param_count;
2256 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
2257 queue_work(priv->priv_wq, &priv->qos_activate);
2259 schedule_task(&priv->qos_activate);
2261 RT_TRACE (COMP_QOS, "QoS parameters change call "
2265 memcpy(&priv->ieee80211->current_network.qos_data.parameters,\
2266 &def_qos_parameters, size);
2268 if ((network->qos_data.active == 1) && (active_network == 1)) {
2269 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
2270 queue_work(priv->priv_wq, &priv->qos_activate);
2272 schedule_task(&priv->qos_activate);
2274 RT_TRACE(COMP_QOS, "QoS was disabled call qos_activate \n");
2276 network->qos_data.active = 0;
2277 network->qos_data.supported = 0;
2283 /* handle manage frame frame beacon and probe response */
2284 static int rtl8192_handle_beacon(struct net_device * dev,
2285 struct ieee80211_beacon * beacon,
2286 struct ieee80211_network * network)
2288 struct r8192_priv *priv = ieee80211_priv(dev);
2290 rtl8192_qos_handle_probe_response(priv,1,network);
2292 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
2293 queue_delayed_work(priv->priv_wq, &priv->update_beacon_wq, 0);
2295 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
2296 schedule_task(&priv->update_beacon_wq);
2298 queue_work(priv->priv_wq, &priv->update_beacon_wq);
2306 * handling the beaconing responses. if we get different QoS setting
2307 * off the network from the associated setting, adjust the QoS
2310 static int rtl8192_qos_association_resp(struct r8192_priv *priv,
2311 struct ieee80211_network *network)
2314 unsigned long flags;
2315 u32 size = sizeof(struct ieee80211_qos_parameters);
2316 int set_qos_param = 0;
2318 if ((priv == NULL) || (network == NULL))
2321 if(priv->ieee80211->state !=IEEE80211_LINKED)
2324 if ((priv->ieee80211->iw_mode != IW_MODE_INFRA))
2327 spin_lock_irqsave(&priv->ieee80211->lock, flags);
2328 if(network->flags & NETWORK_HAS_QOS_PARAMETERS) {
2329 memcpy(&priv->ieee80211->current_network.qos_data.parameters,\
2330 &network->qos_data.parameters,\
2331 sizeof(struct ieee80211_qos_parameters));
2332 priv->ieee80211->current_network.qos_data.active = 1;
2334 if((priv->ieee80211->current_network.qos_data.param_count != \
2335 network->qos_data.param_count))
2339 /* update qos parameter for current network */
2340 priv->ieee80211->current_network.qos_data.old_param_count = \
2341 priv->ieee80211->current_network.qos_data.param_count;
2342 priv->ieee80211->current_network.qos_data.param_count = \
2343 network->qos_data.param_count;
2346 memcpy(&priv->ieee80211->current_network.qos_data.parameters,\
2347 &def_qos_parameters, size);
2348 priv->ieee80211->current_network.qos_data.active = 0;
2349 priv->ieee80211->current_network.qos_data.supported = 0;
2353 spin_unlock_irqrestore(&priv->ieee80211->lock, flags);
2355 RT_TRACE(COMP_QOS, "%s: network->flags = %d,%d\n",__FUNCTION__,network->flags ,priv->ieee80211->current_network.qos_data.active);
2356 if (set_qos_param == 1)
2357 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
2358 queue_work(priv->priv_wq, &priv->qos_activate);
2360 schedule_task(&priv->qos_activate);
2368 static int rtl8192_handle_assoc_response(struct net_device *dev,
2369 struct ieee80211_assoc_response_frame *resp,
2370 struct ieee80211_network *network)
2372 struct r8192_priv *priv = ieee80211_priv(dev);
2373 rtl8192_qos_association_resp(priv, network);
2378 //updateRATRTabel for MCS only. Basic rate is not implement.
2379 void rtl8192_update_ratr_table(struct net_device* dev)
2380 // POCTET_STRING posLegacyRate,
2382 // PRT_WLAN_STA pEntry)
2384 struct r8192_priv* priv = ieee80211_priv(dev);
2385 struct ieee80211_device* ieee = priv->ieee80211;
2386 u8* pMcsRate = ieee->dot11HTOperationalRateSet;
2387 //struct ieee80211_network *net = &ieee->current_network;
2391 rtl8192_config_rate(dev, (u16*)(&ratr_value));
2392 ratr_value |= (*(u16*)(pMcsRate)) << 12;
2393 // switch (net->mode)
2397 ratr_value &= 0x00000FF0;
2400 ratr_value &= 0x0000000F;
2403 ratr_value &= 0x00000FF7;
2407 if (ieee->pHTInfo->PeerMimoPs == 0) //MIMO_PS_STATIC
2408 ratr_value &= 0x0007F007;
2410 if (priv->rf_type == RF_1T2R)
2411 ratr_value &= 0x000FF007;
2413 ratr_value &= 0x0F81F007;
2419 ratr_value &= 0x0FFFFFFF;
2420 if(ieee->pHTInfo->bCurTxBW40MHz && ieee->pHTInfo->bCurShortGI40MHz){
2421 ratr_value |= 0x80000000;
2422 }else if(!ieee->pHTInfo->bCurTxBW40MHz && ieee->pHTInfo->bCurShortGI20MHz){
2423 ratr_value |= 0x80000000;
2425 write_nic_dword(dev, RATR0+rate_index*4, ratr_value);
2426 write_nic_byte(dev, UFWP, 1);
2429 static u8 ccmp_ie[4] = {0x00,0x50,0xf2,0x04};
2430 static u8 ccmp_rsn_ie[4] = {0x00, 0x0f, 0xac, 0x04};
2431 static bool GetNmodeSupportBySecCfg8190Pci(struct net_device*dev)
2434 struct r8192_priv* priv = ieee80211_priv(dev);
2435 struct ieee80211_device* ieee = priv->ieee80211;
2436 int wpa_ie_len= ieee->wpa_ie_len;
2437 struct ieee80211_crypt_data* crypt;
2440 crypt = ieee->crypt[ieee->tx_keyidx];
2441 encrypt = (ieee->current_network.capability & WLAN_CAPABILITY_PRIVACY) || (ieee->host_encrypt && crypt && crypt->ops && (0 == strcmp(crypt->ops->name,"WEP")));
2444 if(encrypt && (wpa_ie_len == 0)) {
2445 /* wep encryption, no N mode setting */
2447 // } else if((wpa_ie_len != 0)&&(memcmp(&(ieee->wpa_ie[14]),ccmp_ie,4))) {
2448 } else if((wpa_ie_len != 0)) {
2449 /* parse pairwise key type */
2450 //if((pairwisekey = WEP40)||(pairwisekey = WEP104)||(pairwisekey = TKIP))
2451 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))))
2456 //RT_TRACE(COMP_ERR,"In %s The GroupEncAlgorithm is [4]\n",__FUNCTION__ );
2461 //In here we discuss with SD4 David. He think we still can send TKIP in broadcast group key in MCS rate.
2462 //We can't force in G mode if Pairwie key is AES and group key is TKIP
2463 if((pSecInfo->GroupEncAlgorithm == WEP104_Encryption) || (pSecInfo->GroupEncAlgorithm == WEP40_Encryption) ||
2464 (pSecInfo->PairwiseEncAlgorithm == WEP104_Encryption) ||
2465 (pSecInfo->PairwiseEncAlgorithm == WEP40_Encryption) || (pSecInfo->PairwiseEncAlgorithm == TKIP_Encryption))
2476 static void rtl8192_refresh_supportrate(struct r8192_priv* priv)
2478 struct ieee80211_device* ieee = priv->ieee80211;
2479 //we donot consider set support rate for ABG mode, only HT MCS rate is set here.
2480 if (ieee->mode == WIRELESS_MODE_N_24G || ieee->mode == WIRELESS_MODE_N_5G)
2482 memcpy(ieee->Regdot11HTOperationalRateSet, ieee->RegHTSuppRateSet, 16);
2483 //RT_DEBUG_DATA(COMP_INIT, ieee->RegHTSuppRateSet, 16);
2484 //RT_DEBUG_DATA(COMP_INIT, ieee->Regdot11HTOperationalRateSet, 16);
2487 memset(ieee->Regdot11HTOperationalRateSet, 0, 16);
2491 static u8 rtl8192_getSupportedWireleeMode(struct net_device*dev)
2493 struct r8192_priv *priv = ieee80211_priv(dev);
2495 switch(priv->rf_chip)
2500 ret = (WIRELESS_MODE_N_24G|WIRELESS_MODE_G|WIRELESS_MODE_B);
2503 ret = (WIRELESS_MODE_A|WIRELESS_MODE_N_5G);
2506 ret = WIRELESS_MODE_B;
2512 static void rtl8192_SetWirelessMode(struct net_device* dev, u8 wireless_mode)
2514 struct r8192_priv *priv = ieee80211_priv(dev);
2515 u8 bSupportMode = rtl8192_getSupportedWireleeMode(dev);
2518 if ((wireless_mode == WIRELESS_MODE_AUTO) || ((wireless_mode&bSupportMode)==0))
2520 if(bSupportMode & WIRELESS_MODE_N_24G)
2522 wireless_mode = WIRELESS_MODE_N_24G;
2524 else if(bSupportMode & WIRELESS_MODE_N_5G)
2526 wireless_mode = WIRELESS_MODE_N_5G;
2528 else if((bSupportMode & WIRELESS_MODE_A))
2530 wireless_mode = WIRELESS_MODE_A;
2532 else if((bSupportMode & WIRELESS_MODE_G))
2534 wireless_mode = WIRELESS_MODE_G;
2536 else if((bSupportMode & WIRELESS_MODE_B))
2538 wireless_mode = WIRELESS_MODE_B;
2541 RT_TRACE(COMP_ERR, "%s(), No valid wireless mode supported, SupportedWirelessMode(%x)!!!\n", __FUNCTION__,bSupportMode);
2542 wireless_mode = WIRELESS_MODE_B;
2545 #ifdef TO_DO_LIST //// TODO: this function doesn't work well at this time, we shoud wait for FPGA
2546 ActUpdateChannelAccessSetting( pAdapter, pHalData->CurrentWirelessMode, &pAdapter->MgntInfo.Info8185.ChannelAccessSetting );
2548 priv->ieee80211->mode = wireless_mode;
2550 if ((wireless_mode == WIRELESS_MODE_N_24G) || (wireless_mode == WIRELESS_MODE_N_5G))
2551 priv->ieee80211->pHTInfo->bEnableHT = 1;
2553 priv->ieee80211->pHTInfo->bEnableHT = 0;
2554 RT_TRACE(COMP_INIT, "Current Wireless Mode is %x\n", wireless_mode);
2555 rtl8192_refresh_supportrate(priv);
2559 //init priv variables here
2561 static bool GetHalfNmodeSupportByAPs819xPci(struct net_device* dev)
2564 struct r8192_priv* priv = ieee80211_priv(dev);
2565 struct ieee80211_device* ieee = priv->ieee80211;
2567 if(ieee->bHalfWirelessN24GMode == true)
2575 short rtl8192_is_tx_queue_empty(struct net_device *dev)
2578 struct r8192_priv *priv = ieee80211_priv(dev);
2579 for (i=0; i<=MGNT_QUEUE; i++)
2581 if ((i== TXCMD_QUEUE) || (i == HCCA_QUEUE) )
2583 if (skb_queue_len(&(&priv->tx_ring[i])->queue) > 0){
2584 printk("===>tx queue is not empty:%d, %d\n", i, skb_queue_len(&(&priv->tx_ring[i])->queue));
2591 void rtl8192_rq_tx_ack(struct net_device *dev)
2593 struct r8192_priv *priv = ieee80211_priv(dev);
2594 priv->ieee80211->ack_tx_to_ieee = 1;
2597 static void rtl8192_hw_sleep_down(struct net_device *dev)
2599 RT_TRACE(COMP_POWER, "%s()============>come to sleep down\n", __FUNCTION__);
2600 MgntActSet_RF_State(dev, eRfSleep, RF_CHANGE_BY_PS);
2602 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
2603 static void rtl8192_hw_sleep_wq (struct work_struct *work)
2605 // struct r8180_priv *priv = container_of(work, struct r8180_priv, watch_dog_wq);
2606 // struct ieee80211_device * ieee = (struct ieee80211_device*)
2607 // container_of(work, struct ieee80211_device, watch_dog_wq);
2608 struct delayed_work *dwork = container_of(work,struct delayed_work,work);
2609 struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,hw_sleep_wq);
2610 struct net_device *dev = ieee->dev;
2612 void rtl8192_hw_sleep_wq(struct net_device* dev)
2615 //printk("=========>%s()\n", __FUNCTION__);
2616 rtl8192_hw_sleep_down(dev);
2618 // printk("dev is %d\n",dev);
2619 // printk("&*&(^*(&(&=========>%s()\n", __FUNCTION__);
2620 static void rtl8192_hw_wakeup(struct net_device* dev)
2624 // spin_lock_irqsave(&priv->ps_lock,flags);
2625 RT_TRACE(COMP_POWER, "%s()============>come to wake up\n", __FUNCTION__);
2626 MgntActSet_RF_State(dev, eRfOn, RF_CHANGE_BY_PS);
2627 //FIXME: will we send package stored while nic is sleep?
2628 // spin_unlock_irqrestore(&priv->ps_lock,flags);
2630 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
2631 void rtl8192_hw_wakeup_wq (struct work_struct *work)
2633 // struct r8180_priv *priv = container_of(work, struct r8180_priv, watch_dog_wq);
2634 // struct ieee80211_device * ieee = (struct ieee80211_device*)
2635 // container_of(work, struct ieee80211_device, watch_dog_wq);
2636 struct delayed_work *dwork = container_of(work,struct delayed_work,work);
2637 struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,hw_wakeup_wq);
2638 struct net_device *dev = ieee->dev;
2640 void rtl8192_hw_wakeup_wq(struct net_device* dev)
2643 rtl8192_hw_wakeup(dev);
2647 #define MIN_SLEEP_TIME 50
2648 #define MAX_SLEEP_TIME 10000
2649 static void rtl8192_hw_to_sleep(struct net_device *dev, u32 th, u32 tl)
2652 struct r8192_priv *priv = ieee80211_priv(dev);
2655 unsigned long flags;
2657 spin_lock_irqsave(&priv->ps_lock,flags);
2659 /* Writing HW register with 0 equals to disable
2660 * the timer, that is not really what we want
2662 tl -= MSECS(4+16+7);
2664 //if(tl == 0) tl = 1;
2666 /* FIXME HACK FIXME HACK */
2667 // force_pci_posting(dev);
2670 // rb = read_nic_dword(dev, TSFTR);
2672 /* If the interval in witch we are requested to sleep is too
2673 * short then give up and remain awake
2675 if(((tl>=rb)&& (tl-rb) <= MSECS(MIN_SLEEP_TIME))
2676 ||((rb>tl)&& (rb-tl) < MSECS(MIN_SLEEP_TIME))) {
2677 spin_unlock_irqrestore(&priv->ps_lock,flags);
2678 printk("too short to sleep\n");
2682 // write_nic_dword(dev, TimerInt, tl);
2683 // rb = read_nic_dword(dev, TSFTR);
2685 u32 tmp = (tl>rb)?(tl-rb):(rb-tl);
2687 queue_delayed_work(priv->ieee80211->wq, &priv->ieee80211->hw_wakeup_wq, tmp); //as tl may be less than rb
2689 /* if we suspect the TimerInt is gone beyond tl
2690 * while setting it, then give up
2693 if(((tl > rb) && ((tl-rb) > MSECS(MAX_SLEEP_TIME)))||
2694 ((tl < rb) && ((rb-tl) > MSECS(MAX_SLEEP_TIME)))) {
2695 printk("========>too long to sleep:%x, %x, %lx\n", tl, rb, MSECS(MAX_SLEEP_TIME));
2696 spin_unlock_irqrestore(&priv->ps_lock,flags);
2700 // if(priv->rf_sleep)
2701 // priv->rf_sleep(dev);
2703 //printk("<=========%s()\n", __FUNCTION__);
2704 queue_delayed_work(priv->ieee80211->wq, (void *)&priv->ieee80211->hw_sleep_wq,0);
2705 spin_unlock_irqrestore(&priv->ps_lock,flags);
2707 static void rtl8192_init_priv_variable(struct net_device* dev)
2709 struct r8192_priv *priv = ieee80211_priv(dev);
2711 priv->being_init_adapter = false;
2712 priv->txbuffsize = 1600;//1024;
2713 priv->txfwbuffersize = 4096;
2714 priv->txringcount = 64;//32;
2715 //priv->txbeaconcount = priv->txringcount;
2716 priv->txbeaconcount = 2;
2717 priv->rxbuffersize = 9100;//2048;//1024;
2718 priv->rxringcount = MAX_RX_COUNT;//64;
2719 priv->irq_enabled=0;
2720 priv->card_8192 = NIC_8192E;
2721 priv->rx_skb_complete = 1;
2722 priv->chan = 1; //set to channel 1
2723 priv->RegWirelessMode = WIRELESS_MODE_AUTO;
2724 priv->RegChannelPlan = 0xf;
2725 priv->nrxAMPDU_size = 0;
2726 priv->nrxAMPDU_aggr_num = 0;
2727 priv->last_rxdesc_tsf_high = 0;
2728 priv->last_rxdesc_tsf_low = 0;
2729 priv->ieee80211->mode = WIRELESS_MODE_AUTO; //SET AUTO
2730 priv->ieee80211->iw_mode = IW_MODE_INFRA;
2731 priv->ieee80211->ieee_up=0;
2732 priv->retry_rts = DEFAULT_RETRY_RTS;
2733 priv->retry_data = DEFAULT_RETRY_DATA;
2734 priv->ieee80211->rts = DEFAULT_RTS_THRESHOLD;
2735 priv->ieee80211->rate = 110; //11 mbps
2736 priv->ieee80211->short_slot = 1;
2737 priv->promisc = (dev->flags & IFF_PROMISC) ? 1:0;
2738 priv->bcck_in_ch14 = false;
2739 priv->bfsync_processing = false;
2740 priv->CCKPresentAttentuation = 0;
2741 priv->rfa_txpowertrackingindex = 0;
2742 priv->rfc_txpowertrackingindex = 0;
2744 priv->ScanDelay = 50;//for Scan TODO
2745 //added by amy for silent reset
2746 priv->ResetProgress = RESET_TYPE_NORESET;
2747 priv->bForcedSilentReset = 0;
2748 priv->bDisableNormalResetCheck = false;
2749 priv->force_reset = false;
2750 //added by amy for power save
2752 priv->ieee80211->RfOffReason = 0;
2753 priv->RFChangeInProgress = false;
2754 priv->bHwRfOffAction = 0;
2755 priv->SetRFPowerStateInProgress = false;
2756 priv->ieee80211->PowerSaveControl.bInactivePs = true;
2757 priv->ieee80211->PowerSaveControl.bIPSModeBackup = false;
2759 priv->txpower_checkcnt = 0;
2760 priv->thermal_readback_index =0;
2761 priv->txpower_tracking_callback_cnt = 0;
2762 priv->ccktxpower_adjustcnt_ch14 = 0;
2763 priv->ccktxpower_adjustcnt_not_ch14 = 0;
2765 priv->ieee80211->current_network.beacon_interval = DEFAULT_BEACONINTERVAL;
2766 priv->ieee80211->iw_mode = IW_MODE_INFRA;
2767 priv->ieee80211->softmac_features = IEEE_SOFTMAC_SCAN |
2768 IEEE_SOFTMAC_ASSOCIATE | IEEE_SOFTMAC_PROBERQ |
2769 IEEE_SOFTMAC_PROBERS | IEEE_SOFTMAC_TX_QUEUE;/* |
2770 IEEE_SOFTMAC_BEACONS;*///added by amy 080604 //| //IEEE_SOFTMAC_SINGLE_QUEUE;
2772 priv->ieee80211->active_scan = 1;
2773 priv->ieee80211->modulation = IEEE80211_CCK_MODULATION | IEEE80211_OFDM_MODULATION;
2774 priv->ieee80211->host_encrypt = 1;
2775 priv->ieee80211->host_decrypt = 1;
2776 //priv->ieee80211->start_send_beacons = NULL;//rtl819xusb_beacon_tx;//-by amy 080604
2777 //priv->ieee80211->stop_send_beacons = NULL;//rtl8192_beacon_stop;//-by amy 080604
2778 priv->ieee80211->start_send_beacons = rtl8192_start_beacon;//+by david 081107
2779 priv->ieee80211->stop_send_beacons = rtl8192_stop_beacon;//+by david 081107
2780 priv->ieee80211->softmac_hard_start_xmit = rtl8192_hard_start_xmit;
2781 priv->ieee80211->set_chan = rtl8192_set_chan;
2782 priv->ieee80211->link_change = rtl8192_link_change;
2783 priv->ieee80211->softmac_data_hard_start_xmit = rtl8192_hard_data_xmit;
2784 priv->ieee80211->data_hard_stop = rtl8192_data_hard_stop;
2785 priv->ieee80211->data_hard_resume = rtl8192_data_hard_resume;
2786 priv->ieee80211->init_wmmparam_flag = 0;
2787 priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD;
2788 priv->ieee80211->check_nic_enough_desc = check_nic_enough_desc;
2789 priv->ieee80211->tx_headroom = sizeof(TX_FWINFO_8190PCI);
2790 priv->ieee80211->qos_support = 1;
2791 priv->ieee80211->dot11PowerSaveMode = 0;
2793 // priv->ieee80211->SwChnlByTimerHandler = rtl8192_phy_SwChnl;
2794 priv->ieee80211->SetBWModeHandler = rtl8192_SetBWMode;
2795 priv->ieee80211->handle_assoc_response = rtl8192_handle_assoc_response;
2796 priv->ieee80211->handle_beacon = rtl8192_handle_beacon;
2798 priv->ieee80211->sta_wake_up = rtl8192_hw_wakeup;
2799 // priv->ieee80211->ps_request_tx_ack = rtl8192_rq_tx_ack;
2800 priv->ieee80211->enter_sleep_state = rtl8192_hw_to_sleep;
2801 priv->ieee80211->ps_is_queue_empty = rtl8192_is_tx_queue_empty;
2803 priv->ieee80211->GetNmodeSupportBySecCfg = GetNmodeSupportBySecCfg8190Pci;
2804 priv->ieee80211->SetWirelessMode = rtl8192_SetWirelessMode;
2805 priv->ieee80211->GetHalfNmodeSupportByAPsHandler = GetHalfNmodeSupportByAPs819xPci;
2808 priv->ieee80211->InitialGainHandler = InitialGain819xPci;
2810 priv->card_type = USB;
2812 priv->ShortRetryLimit = 0x30;
2813 priv->LongRetryLimit = 0x30;
2815 priv->EarlyRxThreshold = 7;
2816 priv->enable_gpio0 = 0;
2818 priv->TransmitConfig = 0;
2820 priv->ReceiveConfig = RCR_ADD3 |
2821 RCR_AMF | RCR_ADF | //accept management/data
2822 RCR_AICV | //accept control frame for SW AP needs PS-poll, 2005.07.07, by rcnjko.
2823 RCR_AB | RCR_AM | RCR_APM | //accept BC/MC/UC
2824 RCR_AAP | ((u32)7<<RCR_MXDMA_OFFSET) |
2825 ((u32)7 << RCR_FIFO_OFFSET) | RCR_ONLYERLPKT;
2827 priv->irq_mask = (u32)(IMR_ROK | IMR_VODOK | IMR_VIDOK | IMR_BEDOK | IMR_BKDOK |\
2828 IMR_HCCADOK | IMR_MGNTDOK | IMR_COMDOK | IMR_HIGHDOK |\
2829 IMR_BDOK | IMR_RXCMDOK | IMR_TIMEOUT0 | IMR_RDU | IMR_RXFOVW |\
2830 IMR_TXFOVW | IMR_BcnInt | IMR_TBDOK | IMR_TBDER);
2832 priv->AcmControl = 0;
2833 priv->pFirmware = (rt_firmware*)vmalloc(sizeof(rt_firmware));
2834 if (priv->pFirmware)
2835 memset(priv->pFirmware, 0, sizeof(rt_firmware));
2837 /* rx related queue */
2838 skb_queue_head_init(&priv->rx_queue);
2839 skb_queue_head_init(&priv->skb_queue);
2841 /* Tx related queue */
2842 for(i = 0; i < MAX_QUEUE_SIZE; i++) {
2843 skb_queue_head_init(&priv->ieee80211->skb_waitQ [i]);
2845 for(i = 0; i < MAX_QUEUE_SIZE; i++) {
2846 skb_queue_head_init(&priv->ieee80211->skb_aggQ [i]);
2848 priv->rf_set_chan = rtl8192_phy_SwChnl;
2852 static void rtl8192_init_priv_lock(struct r8192_priv* priv)
2854 spin_lock_init(&priv->tx_lock);
2855 spin_lock_init(&priv->irq_lock);//added by thomas
2856 spin_lock_init(&priv->irq_th_lock);
2857 spin_lock_init(&priv->rf_ps_lock);
2858 spin_lock_init(&priv->ps_lock);
2859 //spin_lock_init(&priv->rf_lock);
2860 sema_init(&priv->wx_sem,1);
2861 sema_init(&priv->rf_sem,1);
2862 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16))
2863 sema_init(&priv->mutex, 1);
2865 mutex_init(&priv->mutex);
2869 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
2870 extern void rtl819x_watchdog_wqcallback(struct work_struct *work);
2872 extern void rtl819x_watchdog_wqcallback(struct net_device *dev);
2875 void rtl8192_irq_rx_tasklet(struct r8192_priv *priv);
2876 void rtl8192_irq_tx_tasklet(struct r8192_priv *priv);
2877 void rtl8192_prepare_beacon(struct r8192_priv *priv);
2878 //init tasklet and wait_queue here. only 2.6 above kernel is considered
2879 #define DRV_NAME "wlan0"
2880 static void rtl8192_init_priv_task(struct net_device* dev)
2882 struct r8192_priv *priv = ieee80211_priv(dev);
2884 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
2885 #ifdef PF_SYNCTHREAD
2886 priv->priv_wq = create_workqueue(DRV_NAME,0);
2888 priv->priv_wq = create_workqueue(DRV_NAME);
2892 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
2893 // INIT_WORK(&priv->reset_wq, (void(*)(void*)) rtl8192_restart);
2894 INIT_WORK(&priv->reset_wq, rtl8192_restart);
2895 // INIT_DELAYED_WORK(&priv->watch_dog_wq, hal_dm_watchdog);
2896 INIT_DELAYED_WORK(&priv->watch_dog_wq, rtl819x_watchdog_wqcallback);
2897 INIT_DELAYED_WORK(&priv->txpower_tracking_wq, dm_txpower_trackingcallback);
2898 INIT_DELAYED_WORK(&priv->rfpath_check_wq, dm_rf_pathcheck_workitemcallback);
2899 INIT_DELAYED_WORK(&priv->update_beacon_wq, rtl8192_update_beacon);
2900 //INIT_WORK(&priv->SwChnlWorkItem, rtl8192_SwChnl_WorkItem);
2901 //INIT_WORK(&priv->SetBWModeWorkItem, rtl8192_SetBWModeWorkItem);
2902 INIT_WORK(&priv->qos_activate, rtl8192_qos_activate);
2903 INIT_DELAYED_WORK(&priv->ieee80211->hw_wakeup_wq,(void*) rtl8192_hw_wakeup_wq);
2904 INIT_DELAYED_WORK(&priv->ieee80211->hw_sleep_wq,(void*) rtl8192_hw_sleep_wq);
2907 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
2908 tq_init(&priv->reset_wq, (void*)rtl8192_restart, dev);
2909 tq_init(&priv->watch_dog_wq, (void*)rtl819x_watchdog_wqcallback, dev);
2910 tq_init(&priv->txpower_tracking_wq, (void*)dm_txpower_trackingcallback, dev);
2911 tq_init(&priv->rfpath_check_wq, (void*)dm_rf_pathcheck_workitemcallback, dev);
2912 tq_init(&priv->update_beacon_wq, (void*)rtl8192_update_beacon, dev);
2913 //tq_init(&priv->SwChnlWorkItem, (void*) rtl8192_SwChnl_WorkItem, dev);
2914 //tq_init(&priv->SetBWModeWorkItem, (void*)rtl8192_SetBWModeWorkItem, dev);
2915 tq_init(&priv->qos_activate, (void *)rtl8192_qos_activate, dev);
2916 tq_init(&priv->ieee80211->hw_wakeup_wq,(void*) rtl8192_hw_wakeup_wq, dev);
2917 tq_init(&priv->ieee80211->hw_sleep_wq,(void*) rtl8192_hw_sleep_wq, dev);
2920 INIT_WORK(&priv->reset_wq,(void(*)(void*)) rtl8192_restart,dev);
2921 // INIT_WORK(&priv->watch_dog_wq, (void(*)(void*)) hal_dm_watchdog,dev);
2922 INIT_WORK(&priv->watch_dog_wq, (void(*)(void*)) rtl819x_watchdog_wqcallback,dev);
2923 INIT_WORK(&priv->txpower_tracking_wq, (void(*)(void*)) dm_txpower_trackingcallback,dev);
2924 INIT_WORK(&priv->rfpath_check_wq, (void(*)(void*)) dm_rf_pathcheck_workitemcallback,dev);
2925 INIT_WORK(&priv->update_beacon_wq, (void(*)(void*))rtl8192_update_beacon,dev);
2926 //INIT_WORK(&priv->SwChnlWorkItem, (void(*)(void*)) rtl8192_SwChnl_WorkItem, dev);
2927 //INIT_WORK(&priv->SetBWModeWorkItem, (void(*)(void*)) rtl8192_SetBWModeWorkItem, dev);
2928 INIT_WORK(&priv->qos_activate, (void(*)(void *))rtl8192_qos_activate, dev);
2929 INIT_WORK(&priv->ieee80211->hw_wakeup_wq,(void*) rtl8192_hw_wakeup_wq, dev);
2930 INIT_WORK(&priv->ieee80211->hw_sleep_wq,(void*) rtl8192_hw_sleep_wq, dev);
2934 tasklet_init(&priv->irq_rx_tasklet,
2935 (void(*)(unsigned long))rtl8192_irq_rx_tasklet,
2936 (unsigned long)priv);
2937 tasklet_init(&priv->irq_tx_tasklet,
2938 (void(*)(unsigned long))rtl8192_irq_tx_tasklet,
2939 (unsigned long)priv);
2940 tasklet_init(&priv->irq_prepare_beacon_tasklet,
2941 (void(*)(unsigned long))rtl8192_prepare_beacon,
2942 (unsigned long)priv);
2945 static void rtl8192_get_eeprom_size(struct net_device* dev)
2948 struct r8192_priv *priv = ieee80211_priv(dev);
2949 RT_TRACE(COMP_INIT, "===========>%s()\n", __FUNCTION__);
2950 curCR = read_nic_dword(dev, EPROM_CMD);
2951 RT_TRACE(COMP_INIT, "read from Reg Cmd9346CR(%x):%x\n", EPROM_CMD, curCR);
2952 //whether need I consider BIT5?
2953 priv->epromtype = (curCR & EPROM_CMD_9356SEL) ? EPROM_93c56 : EPROM_93c46;
2954 RT_TRACE(COMP_INIT, "<===========%s(), epromtype:%d\n", __FUNCTION__, priv->epromtype);
2957 //used to swap endian. as ntohl & htonl are not neccessary to swap endian, so use this instead.
2958 static inline u16 endian_swap(u16* data)
2961 *data = (tmp >> 8) | (tmp << 8);
2966 * Note: Adapter->EEPROMAddressSize should be set before this function call.
2967 * EEPROM address size can be got through GetEEPROMSize8185()
2969 static void rtl8192_read_eeprom_info(struct net_device* dev)
2971 struct r8192_priv *priv = ieee80211_priv(dev);
2975 u8 ICVer8192, ICVer8256;
2977 u16 i,usValue, IC_Version;
2980 u8 offset;//, tmpAFR;
2981 u8 EepromTxPower[100];
2983 u8 bMac_Tmp_Addr[6] = {0x00, 0xe0, 0x4c, 0x00, 0x00, 0x01};
2984 RT_TRACE(COMP_INIT, "====> rtl8192_read_eeprom_info\n");
2987 // TODO: I don't know if we need to apply EF function to EEPROM read function
2989 //2 Read EEPROM ID to make sure autoload is success
2990 EEPROMId = eprom_read(dev, 0);
2991 if( EEPROMId != RTL8190_EEPROM_ID )
2993 RT_TRACE(COMP_ERR, "EEPROM ID is invalid:%x, %x\n", EEPROMId, RTL8190_EEPROM_ID);
2994 priv->AutoloadFailFlag=true;
2998 priv->AutoloadFailFlag=false;
3002 // Assign Chip Version ID
3004 // Read IC Version && Channel Plan
3005 if(!priv->AutoloadFailFlag)
3008 priv->eeprom_vid = eprom_read(dev, (EEPROM_VID >> 1));
3009 priv->eeprom_did = eprom_read(dev, (EEPROM_DID >> 1));
3011 usValue = eprom_read(dev, (u16)(EEPROM_Customer_ID>>1)) >> 8 ;
3012 priv->eeprom_CustomerID = (u8)( usValue & 0xff);
3013 usValue = eprom_read(dev, (EEPROM_ICVersion_ChannelPlan>>1));
3014 priv->eeprom_ChannelPlan = usValue&0xff;
3015 IC_Version = ((usValue&0xff00)>>8);
3018 priv->card_8192_version = (VERSION_8190)(IC_Version);
3021 ICVer8192 = (IC_Version&0xf); //bit0~3; 1:A cut, 2:B cut, 3:C cut...
3022 ICVer8256 = ((IC_Version&0xf0)>>4);//bit4~6, bit7 reserved for other RF chip; 1:A cut, 2:B cut, 3:C cut...
3023 RT_TRACE(COMP_INIT, "\nICVer8192 = 0x%x\n", ICVer8192);
3024 RT_TRACE(COMP_INIT, "\nICVer8256 = 0x%x\n", ICVer8256);
3025 if(ICVer8192 == 0x2) //B-cut
3027 if(ICVer8256 == 0x5) //E-cut
3028 priv->card_8192_version= VERSION_8190_BE;
3032 switch(priv->card_8192_version)
3034 case VERSION_8190_BD:
3035 case VERSION_8190_BE:
3038 priv->card_8192_version = VERSION_8190_BD;
3041 RT_TRACE(COMP_INIT, "\nIC Version = 0x%x\n", priv->card_8192_version);
3045 priv->card_8192_version = VERSION_8190_BD;
3046 priv->eeprom_vid = 0;
3047 priv->eeprom_did = 0;
3048 priv->eeprom_CustomerID = 0;
3049 priv->eeprom_ChannelPlan = 0;
3050 RT_TRACE(COMP_INIT, "\nIC Version = 0x%x\n", 0xff);
3053 RT_TRACE(COMP_INIT, "EEPROM VID = 0x%4x\n", priv->eeprom_vid);
3054 RT_TRACE(COMP_INIT, "EEPROM DID = 0x%4x\n", priv->eeprom_did);
3055 RT_TRACE(COMP_INIT,"EEPROM Customer ID: 0x%2x\n", priv->eeprom_CustomerID);
3057 //2 Read Permanent MAC address
3058 if(!priv->AutoloadFailFlag)
3060 for(i = 0; i < 6; i += 2)
3062 usValue = eprom_read(dev, (u16) ((EEPROM_NODE_ADDRESS_BYTE_0+i)>>1));
3063 *(u16*)(&dev->dev_addr[i]) = usValue;
3066 // when auto load failed, the last address byte set to be a random one.
3067 // added by david woo.2007/11/7
3068 memcpy(dev->dev_addr, bMac_Tmp_Addr, 6);
3070 for(i = 0; i < 6; i++)
3072 Adapter->PermanentAddress[i] = sMacAddr[i];
3073 PlatformEFIOWrite1Byte(Adapter, IDR0+i, sMacAddr[i]);
3078 RT_TRACE(COMP_INIT, "Permanent Address = %02x-%02x-%02x-%02x-%02x-%02x\n",
3079 dev->dev_addr[0], dev->dev_addr[1],
3080 dev->dev_addr[2], dev->dev_addr[3],
3081 dev->dev_addr[4], dev->dev_addr[5]);
3083 //2 TX Power Check EEPROM Fail or not
3084 if(priv->card_8192_version > VERSION_8190_BD) {
3085 priv->bTXPowerDataReadFromEEPORM = true;
3087 priv->bTXPowerDataReadFromEEPORM = false;
3090 // 2007/11/15 MH 8190PCI Default=2T4R, 8192PCIE dafault=1T2R
3091 priv->rf_type = RTL819X_DEFAULT_RF_TYPE;
3093 if(priv->card_8192_version > VERSION_8190_BD)
3095 // Read RF-indication and Tx Power gain index diff of legacy to HT OFDM rate.
3096 if(!priv->AutoloadFailFlag)
3098 tempval = (eprom_read(dev, (EEPROM_RFInd_PowerDiff>>1))) & 0xff;
3099 priv->EEPROMLegacyHTTxPowerDiff = tempval & 0xf; // bit[3:0]
3101 if (tempval&0x80) //RF-indication, bit[7]
3102 priv->rf_type = RF_1T2R;
3104 priv->rf_type = RF_2T4R;
3108 priv->EEPROMLegacyHTTxPowerDiff = EEPROM_Default_LegacyHTTxPowerDiff;
3110 RT_TRACE(COMP_INIT, "EEPROMLegacyHTTxPowerDiff = %d\n",
3111 priv->EEPROMLegacyHTTxPowerDiff);
3113 // Read ThermalMeter from EEPROM
3114 if(!priv->AutoloadFailFlag)
3116 priv->EEPROMThermalMeter = (u8)(((eprom_read(dev, (EEPROM_ThermalMeter>>1))) & 0xff00)>>8);
3120 priv->EEPROMThermalMeter = EEPROM_Default_ThermalMeter;
3122 RT_TRACE(COMP_INIT, "ThermalMeter = %d\n", priv->EEPROMThermalMeter);
3123 //vivi, for tx power track
3124 priv->TSSI_13dBm = priv->EEPROMThermalMeter *100;
3126 if(priv->epromtype == EPROM_93c46)
3128 // Read antenna tx power offset of B/C/D to A and CrystalCap from EEPROM
3129 if(!priv->AutoloadFailFlag)
3131 usValue = eprom_read(dev, (EEPROM_TxPwDiff_CrystalCap>>1));
3132 priv->EEPROMAntPwDiff = (usValue&0x0fff);
3133 priv->EEPROMCrystalCap = (u8)((usValue&0xf000)>>12);
3137 priv->EEPROMAntPwDiff = EEPROM_Default_AntTxPowerDiff;
3138 priv->EEPROMCrystalCap = EEPROM_Default_TxPwDiff_CrystalCap;
3140 RT_TRACE(COMP_INIT, "EEPROMAntPwDiff = %d\n", priv->EEPROMAntPwDiff);
3141 RT_TRACE(COMP_INIT, "EEPROMCrystalCap = %d\n", priv->EEPROMCrystalCap);
3144 // Get per-channel Tx Power Level
3146 for(i=0; i<14; i+=2)
3148 if(!priv->AutoloadFailFlag)
3150 usValue = eprom_read(dev, (u16) ((EEPROM_TxPwIndex_CCK+i)>>1) );
3154 usValue = EEPROM_Default_TxPower;
3156 *((u16*)(&priv->EEPROMTxPowerLevelCCK[i])) = usValue;
3157 RT_TRACE(COMP_INIT,"CCK Tx Power Level, Index %d = 0x%02x\n", i, priv->EEPROMTxPowerLevelCCK[i]);
3158 RT_TRACE(COMP_INIT, "CCK Tx Power Level, Index %d = 0x%02x\n", i+1, priv->EEPROMTxPowerLevelCCK[i+1]);
3160 for(i=0; i<14; i+=2)
3162 if(!priv->AutoloadFailFlag)
3164 usValue = eprom_read(dev, (u16) ((EEPROM_TxPwIndex_OFDM_24G+i)>>1) );
3168 usValue = EEPROM_Default_TxPower;
3170 *((u16*)(&priv->EEPROMTxPowerLevelOFDM24G[i])) = usValue;
3171 RT_TRACE(COMP_INIT, "OFDM 2.4G Tx Power Level, Index %d = 0x%02x\n", i, priv->EEPROMTxPowerLevelOFDM24G[i]);
3172 RT_TRACE(COMP_INIT, "OFDM 2.4G Tx Power Level, Index %d = 0x%02x\n", i+1, priv->EEPROMTxPowerLevelOFDM24G[i+1]);
3175 else if(priv->epromtype== EPROM_93c56)
3178 // Read CrystalCap from EEPROM
3179 if(!priv->AutoloadFailFlag)
3181 priv->EEPROMAntPwDiff = EEPROM_Default_AntTxPowerDiff;
3182 priv->EEPROMCrystalCap = (u8)(((eprom_read(dev, (EEPROM_C56_CrystalCap>>1))) & 0xf000)>>12);
3186 priv->EEPROMAntPwDiff = EEPROM_Default_AntTxPowerDiff;
3187 priv->EEPROMCrystalCap = EEPROM_Default_TxPwDiff_CrystalCap;
3189 RT_TRACE(COMP_INIT,"EEPROMAntPwDiff = %d\n", priv->EEPROMAntPwDiff);
3190 RT_TRACE(COMP_INIT, "EEPROMCrystalCap = %d\n", priv->EEPROMCrystalCap);
3192 // Get Tx Power Level by Channel
3193 if(!priv->AutoloadFailFlag)
3195 // Read Tx power of Channel 1 ~ 14 from EEPROM.
3196 for(i = 0; i < 12; i+=2)
3199 offset = EEPROM_C56_RfA_CCK_Chnl1_TxPwIndex + i;
3201 offset = EEPROM_C56_RfC_CCK_Chnl1_TxPwIndex + i - 6;
3202 usValue = eprom_read(dev, (offset>>1));
3203 *((u16*)(&EepromTxPower[i])) = usValue;
3206 for(i = 0; i < 12; i++)
3209 priv->EEPROMRfACCKChnl1TxPwLevel[i] = EepromTxPower[i];
3210 else if ((i >=3 )&&(i <= 5))
3211 priv->EEPROMRfAOfdmChnlTxPwLevel[i-3] = EepromTxPower[i];
3212 else if ((i >=6 )&&(i <= 8))
3213 priv->EEPROMRfCCCKChnl1TxPwLevel[i-6] = EepromTxPower[i];
3215 priv->EEPROMRfCOfdmChnlTxPwLevel[i-9] = EepromTxPower[i];
3220 priv->EEPROMRfACCKChnl1TxPwLevel[0] = EEPROM_Default_TxPowerLevel;
3221 priv->EEPROMRfACCKChnl1TxPwLevel[1] = EEPROM_Default_TxPowerLevel;
3222 priv->EEPROMRfACCKChnl1TxPwLevel[2] = EEPROM_Default_TxPowerLevel;
3224 priv->EEPROMRfAOfdmChnlTxPwLevel[0] = EEPROM_Default_TxPowerLevel;
3225 priv->EEPROMRfAOfdmChnlTxPwLevel[1] = EEPROM_Default_TxPowerLevel;
3226 priv->EEPROMRfAOfdmChnlTxPwLevel[2] = EEPROM_Default_TxPowerLevel;
3228 priv->EEPROMRfCCCKChnl1TxPwLevel[0] = EEPROM_Default_TxPowerLevel;
3229 priv->EEPROMRfCCCKChnl1TxPwLevel[1] = EEPROM_Default_TxPowerLevel;
3230 priv->EEPROMRfCCCKChnl1TxPwLevel[2] = EEPROM_Default_TxPowerLevel;
3232 priv->EEPROMRfCOfdmChnlTxPwLevel[0] = EEPROM_Default_TxPowerLevel;
3233 priv->EEPROMRfCOfdmChnlTxPwLevel[1] = EEPROM_Default_TxPowerLevel;
3234 priv->EEPROMRfCOfdmChnlTxPwLevel[2] = EEPROM_Default_TxPowerLevel;
3236 RT_TRACE(COMP_INIT, "priv->EEPROMRfACCKChnl1TxPwLevel[0] = 0x%x\n", priv->EEPROMRfACCKChnl1TxPwLevel[0]);
3237 RT_TRACE(COMP_INIT, "priv->EEPROMRfACCKChnl1TxPwLevel[1] = 0x%x\n", priv->EEPROMRfACCKChnl1TxPwLevel[1]);
3238 RT_TRACE(COMP_INIT, "priv->EEPROMRfACCKChnl1TxPwLevel[2] = 0x%x\n", priv->EEPROMRfACCKChnl1TxPwLevel[2]);
3239 RT_TRACE(COMP_INIT, "priv->EEPROMRfAOfdmChnlTxPwLevel[0] = 0x%x\n", priv->EEPROMRfAOfdmChnlTxPwLevel[0]);
3240 RT_TRACE(COMP_INIT, "priv->EEPROMRfAOfdmChnlTxPwLevel[1] = 0x%x\n", priv->EEPROMRfAOfdmChnlTxPwLevel[1]);
3241 RT_TRACE(COMP_INIT, "priv->EEPROMRfAOfdmChnlTxPwLevel[2] = 0x%x\n", priv->EEPROMRfAOfdmChnlTxPwLevel[2]);
3242 RT_TRACE(COMP_INIT, "priv->EEPROMRfCCCKChnl1TxPwLevel[0] = 0x%x\n", priv->EEPROMRfCCCKChnl1TxPwLevel[0]);
3243 RT_TRACE(COMP_INIT, "priv->EEPROMRfCCCKChnl1TxPwLevel[1] = 0x%x\n", priv->EEPROMRfCCCKChnl1TxPwLevel[1]);
3244 RT_TRACE(COMP_INIT, "priv->EEPROMRfCCCKChnl1TxPwLevel[2] = 0x%x\n", priv->EEPROMRfCCCKChnl1TxPwLevel[2]);
3245 RT_TRACE(COMP_INIT, "priv->EEPROMRfCOfdmChnlTxPwLevel[0] = 0x%x\n", priv->EEPROMRfCOfdmChnlTxPwLevel[0]);
3246 RT_TRACE(COMP_INIT, "priv->EEPROMRfCOfdmChnlTxPwLevel[1] = 0x%x\n", priv->EEPROMRfCOfdmChnlTxPwLevel[1]);
3247 RT_TRACE(COMP_INIT, "priv->EEPROMRfCOfdmChnlTxPwLevel[2] = 0x%x\n", priv->EEPROMRfCOfdmChnlTxPwLevel[2]);
3252 // Update HAL variables.
3254 if(priv->epromtype == EPROM_93c46)
3258 priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelCCK[i];
3259 priv->TxPowerLevelOFDM24G[i] = priv->EEPROMTxPowerLevelOFDM24G[i];
3261 priv->LegacyHTTxPowerDiff = priv->EEPROMLegacyHTTxPowerDiff;
3262 // Antenna B gain offset to antenna A, bit0~3
3263 priv->AntennaTxPwDiff[0] = (priv->EEPROMAntPwDiff & 0xf);
3264 // Antenna C gain offset to antenna A, bit4~7
3265 priv->AntennaTxPwDiff[1] = ((priv->EEPROMAntPwDiff & 0xf0)>>4);
3266 // Antenna D gain offset to antenna A, bit8~11
3267 priv->AntennaTxPwDiff[2] = ((priv->EEPROMAntPwDiff & 0xf00)>>8);
3268 // CrystalCap, bit12~15
3269 priv->CrystalCap = priv->EEPROMCrystalCap;
3270 // ThermalMeter, bit0~3 for RFIC1, bit4~7 for RFIC2
3271 priv->ThermalMeter[0] = (priv->EEPROMThermalMeter & 0xf);
3272 priv->ThermalMeter[1] = ((priv->EEPROMThermalMeter & 0xf0)>>4);
3274 else if(priv->epromtype == EPROM_93c56)
3276 //char cck_pwr_diff_a=0, cck_pwr_diff_c=0;
3278 //cck_pwr_diff_a = pHalData->EEPROMRfACCKChnl7TxPwLevel - pHalData->EEPROMRfAOfdmChnlTxPwLevel[1];
3279 //cck_pwr_diff_c = pHalData->EEPROMRfCCCKChnl7TxPwLevel - pHalData->EEPROMRfCOfdmChnlTxPwLevel[1];
3280 for(i=0; i<3; i++) // channel 1~3 use the same Tx Power Level.
3282 priv->TxPowerLevelCCK_A[i] = priv->EEPROMRfACCKChnl1TxPwLevel[0];
3283 priv->TxPowerLevelOFDM24G_A[i] = priv->EEPROMRfAOfdmChnlTxPwLevel[0];
3284 priv->TxPowerLevelCCK_C[i] = priv->EEPROMRfCCCKChnl1TxPwLevel[0];
3285 priv->TxPowerLevelOFDM24G_C[i] = priv->EEPROMRfCOfdmChnlTxPwLevel[0];
3287 for(i=3; i<9; i++) // channel 4~9 use the same Tx Power Level
3289 priv->TxPowerLevelCCK_A[i] = priv->EEPROMRfACCKChnl1TxPwLevel[1];
3290 priv->TxPowerLevelOFDM24G_A[i] = priv->EEPROMRfAOfdmChnlTxPwLevel[1];
3291 priv->TxPowerLevelCCK_C[i] = priv->EEPROMRfCCCKChnl1TxPwLevel[1];
3292 priv->TxPowerLevelOFDM24G_C[i] = priv->EEPROMRfCOfdmChnlTxPwLevel[1];
3294 for(i=9; i<14; i++) // channel 10~14 use the same Tx Power Level
3296 priv->TxPowerLevelCCK_A[i] = priv->EEPROMRfACCKChnl1TxPwLevel[2];
3297 priv->TxPowerLevelOFDM24G_A[i] = priv->EEPROMRfAOfdmChnlTxPwLevel[2];
3298 priv->TxPowerLevelCCK_C[i] = priv->EEPROMRfCCCKChnl1TxPwLevel[2];
3299 priv->TxPowerLevelOFDM24G_C[i] = priv->EEPROMRfCOfdmChnlTxPwLevel[2];
3302 RT_TRACE(COMP_INIT, "priv->TxPowerLevelCCK_A[%d] = 0x%x\n", i, priv->TxPowerLevelCCK_A[i]);
3304 RT_TRACE(COMP_INIT,"priv->TxPowerLevelOFDM24G_A[%d] = 0x%x\n", i, priv->TxPowerLevelOFDM24G_A[i]);
3306 RT_TRACE(COMP_INIT, "priv->TxPowerLevelCCK_C[%d] = 0x%x\n", i, priv->TxPowerLevelCCK_C[i]);
3308 RT_TRACE(COMP_INIT, "priv->TxPowerLevelOFDM24G_C[%d] = 0x%x\n", i, priv->TxPowerLevelOFDM24G_C[i]);
3309 priv->LegacyHTTxPowerDiff = priv->EEPROMLegacyHTTxPowerDiff;
3310 priv->AntennaTxPwDiff[0] = 0;
3311 priv->AntennaTxPwDiff[1] = 0;
3312 priv->AntennaTxPwDiff[2] = 0;
3313 priv->CrystalCap = priv->EEPROMCrystalCap;
3314 // ThermalMeter, bit0~3 for RFIC1, bit4~7 for RFIC2
3315 priv->ThermalMeter[0] = (priv->EEPROMThermalMeter & 0xf);
3316 priv->ThermalMeter[1] = ((priv->EEPROMThermalMeter & 0xf0)>>4);
3320 if(priv->rf_type == RF_1T2R)
3322 RT_TRACE(COMP_INIT, "\n1T2R config\n");
3324 else if (priv->rf_type == RF_2T4R)
3326 RT_TRACE(COMP_INIT, "\n2T4R config\n");
3329 // 2008/01/16 MH We can only know RF type in the function. So we have to init
3330 // DIG RATR table again.
3331 init_rate_adaptive(dev);
3333 //1 Make a copy for following variables and we can change them if we want
3335 priv->rf_chip= RF_8256;
3337 if(priv->RegChannelPlan == 0xf)
3339 priv->ChannelPlan = priv->eeprom_ChannelPlan;
3343 priv->ChannelPlan = priv->RegChannelPlan;
3347 // Used PID and DID to Set CustomerID
3349 if( priv->eeprom_vid == 0x1186 && priv->eeprom_did == 0x3304 )
3351 priv->CustomerID = RT_CID_DLINK;
3354 switch(priv->eeprom_CustomerID)
3356 case EEPROM_CID_DEFAULT:
3357 priv->CustomerID = RT_CID_DEFAULT;
3359 case EEPROM_CID_CAMEO:
3360 priv->CustomerID = RT_CID_819x_CAMEO;
3362 case EEPROM_CID_RUNTOP:
3363 priv->CustomerID = RT_CID_819x_RUNTOP;
3365 case EEPROM_CID_NetCore:
3366 priv->CustomerID = RT_CID_819x_Netcore;
3368 case EEPROM_CID_TOSHIBA: // Merge by Jacken, 2008/01/31
3369 priv->CustomerID = RT_CID_TOSHIBA;
3370 if(priv->eeprom_ChannelPlan&0x80)
3371 priv->ChannelPlan = priv->eeprom_ChannelPlan&0x7f;
3373 priv->ChannelPlan = 0x0;
3374 RT_TRACE(COMP_INIT, "Toshiba ChannelPlan = 0x%x\n",
3377 case EEPROM_CID_Nettronix:
3378 priv->ScanDelay = 100; //cosa add for scan
3379 priv->CustomerID = RT_CID_Nettronix;
3381 case EEPROM_CID_Pronet:
3382 priv->CustomerID = RT_CID_PRONET;
3384 case EEPROM_CID_DLINK:
3385 priv->CustomerID = RT_CID_DLINK;
3388 case EEPROM_CID_WHQL:
3389 //Adapter->bInHctTest = TRUE;//do not supported
3391 //priv->bSupportTurboMode = FALSE;
3392 //priv->bAutoTurboBy8186 = FALSE;
3394 //pMgntInfo->PowerSaveControl.bInactivePs = FALSE;
3395 //pMgntInfo->PowerSaveControl.bIPSModeBackup = FALSE;
3396 //pMgntInfo->PowerSaveControl.bLeisurePs = FALSE;
3400 // value from RegCustomerID
3404 //Avoid the channel plan array overflow, by Bruce, 2007-08-27.
3405 if(priv->ChannelPlan > CHANNEL_PLAN_LEN - 1)
3406 priv->ChannelPlan = 0; //FCC
3408 switch(priv->CustomerID)
3410 case RT_CID_DEFAULT:
3412 priv->LedStrategy = HW_LED;
3415 priv->LedStrategy = SW_LED_MODE1;
3420 case RT_CID_819x_CAMEO:
3421 priv->LedStrategy = SW_LED_MODE2;
3424 case RT_CID_819x_RUNTOP:
3425 priv->LedStrategy = SW_LED_MODE3;
3428 case RT_CID_819x_Netcore:
3429 priv->LedStrategy = SW_LED_MODE4;
3432 case RT_CID_Nettronix:
3433 priv->LedStrategy = SW_LED_MODE5;
3437 priv->LedStrategy = SW_LED_MODE6;
3440 case RT_CID_TOSHIBA: //Modify by Jacken 2008/01/31
3446 priv->LedStrategy = HW_LED;
3449 priv->LedStrategy = SW_LED_MODE1;
3455 //2008.06.03, for WOL
3456 if( priv->eeprom_vid == 0x1186 && priv->eeprom_did == 0x3304)
3457 priv->ieee80211->bSupportRemoteWakeUp = TRUE;
3459 priv->ieee80211->bSupportRemoteWakeUp = FALSE;
3461 RT_TRACE(COMP_INIT, "RegChannelPlan(%d)\n", priv->RegChannelPlan);
3462 RT_TRACE(COMP_INIT, "ChannelPlan = %d \n", priv->ChannelPlan);
3463 RT_TRACE(COMP_INIT, "LedStrategy = %d \n", priv->LedStrategy);
3464 RT_TRACE(COMP_TRACE, "<==== ReadAdapterInfo\n");
3470 static short rtl8192_get_channel_map(struct net_device * dev)
3472 struct r8192_priv *priv = ieee80211_priv(dev);
3473 #ifdef ENABLE_DOT11D
3474 if(priv->ChannelPlan> COUNTRY_CODE_GLOBAL_DOMAIN){
3475 printk("rtl8180_init:Error channel plan! Set to default.\n");
3476 priv->ChannelPlan= 0;
3478 RT_TRACE(COMP_INIT, "Channel plan is %d\n",priv->ChannelPlan);
3480 rtl819x_set_channel_map(priv->ChannelPlan, priv);
3483 //Set Default Channel Plan
3485 DMESG("No channels, aborting");
3489 priv->ChannelPlan= 0;//hikaru
3490 // set channels 1..14 allowed in given locale
3491 for (i=1; i<=14; i++) {
3492 (priv->ieee80211->channel_map)[i] = (u8)(ch & 0x01);
3499 static short rtl8192_init(struct net_device *dev)
3501 struct r8192_priv *priv = ieee80211_priv(dev);
3502 memset(&(priv->stats),0,sizeof(struct Stats));
3503 rtl8192_init_priv_variable(dev);
3504 rtl8192_init_priv_lock(priv);
3505 rtl8192_init_priv_task(dev);
3506 rtl8192_get_eeprom_size(dev);
3507 rtl8192_read_eeprom_info(dev);
3508 rtl8192_get_channel_map(dev);
3510 init_timer(&priv->watch_dog_timer);
3511 priv->watch_dog_timer.data = (unsigned long)dev;
3512 priv->watch_dog_timer.function = watch_dog_timer_callback;
3513 #if defined(IRQF_SHARED)
3514 if(request_irq(dev->irq, (void*)rtl8192_interrupt, IRQF_SHARED, dev->name, dev)){
3516 if(request_irq(dev->irq, (void *)rtl8192_interrupt, SA_SHIRQ, dev->name, dev)){
3518 printk("Error allocating IRQ %d",dev->irq);
3522 printk("IRQ %d",dev->irq);
3524 if(rtl8192_pci_initdescring(dev)!=0){
3525 printk("Endopoints initialization failed");
3529 //rtl8192_rx_enable(dev);
3530 //rtl8192_adapter_start(dev);
3531 //#ifdef DEBUG_EPROM
3534 //rtl8192_dump_reg(dev);
3538 /******************************************************************************
3539 *function: This function actually only set RRSR, RATR and BW_OPMODE registers
3540 * not to do all the hw config as its name says
3541 * input: net_device dev
3544 * notice: This part need to modified according to the rate set we filtered
3545 * ****************************************************************************/
3546 static void rtl8192_hwconfig(struct net_device* dev)
3548 u32 regRATR = 0, regRRSR = 0;
3549 u8 regBwOpMode = 0, regTmp = 0;
3550 struct r8192_priv *priv = ieee80211_priv(dev);
3552 // Set RRSR, RATR, and BW_OPMODE registers
3554 switch(priv->ieee80211->mode)
3556 case WIRELESS_MODE_B:
3557 regBwOpMode = BW_OPMODE_20MHZ;
3558 regRATR = RATE_ALL_CCK;
3559 regRRSR = RATE_ALL_CCK;
3561 case WIRELESS_MODE_A:
3562 regBwOpMode = BW_OPMODE_5G |BW_OPMODE_20MHZ;
3563 regRATR = RATE_ALL_OFDM_AG;
3564 regRRSR = RATE_ALL_OFDM_AG;
3566 case WIRELESS_MODE_G:
3567 regBwOpMode = BW_OPMODE_20MHZ;
3568 regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
3569 regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
3571 case WIRELESS_MODE_AUTO:
3572 case WIRELESS_MODE_N_24G:
3573 // It support CCK rate by default.
3574 // CCK rate will be filtered out only when associated AP does not support it.
3575 regBwOpMode = BW_OPMODE_20MHZ;
3576 regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
3577 regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
3579 case WIRELESS_MODE_N_5G:
3580 regBwOpMode = BW_OPMODE_5G;
3581 regRATR = RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
3582 regRRSR = RATE_ALL_OFDM_AG;
3586 write_nic_byte(dev, BW_OPMODE, regBwOpMode);
3589 ratr_value = regRATR;
3590 if (priv->rf_type == RF_1T2R)
3592 ratr_value &= ~(RATE_ALL_OFDM_2SS);
3594 write_nic_dword(dev, RATR0, ratr_value);
3595 write_nic_byte(dev, UFWP, 1);
3597 regTmp = read_nic_byte(dev, 0x313);
3598 regRRSR = ((regTmp) << 24) | (regRRSR & 0x00ffffff);
3599 write_nic_dword(dev, RRSR, regRRSR);
3602 // Set Retry Limit here
3604 write_nic_word(dev, RETRY_LIMIT,
3605 priv->ShortRetryLimit << RETRY_LIMIT_SHORT_SHIFT | \
3606 priv->LongRetryLimit << RETRY_LIMIT_LONG_SHIFT);
3607 // Set Contention Window here
3611 // Set Tx Antenna including Feedback control
3613 // Set Auto Rate fallback control
3619 static RT_STATUS rtl8192_adapter_start(struct net_device *dev)
3621 struct r8192_priv *priv = ieee80211_priv(dev);
3622 // struct ieee80211_device *ieee = priv->ieee80211;
3624 RT_STATUS rtStatus = RT_STATUS_SUCCESS;
3625 // static char szMACPHYRegFile[] = RTL819X_PHY_MACPHY_REG;
3626 // static char szMACPHYRegPGFile[] = RTL819X_PHY_MACPHY_REG_PG;
3630 u8 ICVersion,SwitchingRegulatorOutput;
3632 bool bfirmwareok = true;
3636 u32 tmpRegA, tmpRegC, TempCCk;
3638 // u32 dwRegRead = 0;
3640 RT_TRACE(COMP_INIT, "====>%s()\n", __FUNCTION__);
3641 priv->being_init_adapter = true;
3642 rtl8192_pci_resetdescring(dev);
3643 // 2007/11/02 MH Before initalizing RF. We can not use FW to do RF-R/W.
3644 priv->Rf_Mode = RF_OP_By_SW_3wire;
3647 if(priv->ResetProgress == RESET_TYPE_NORESET)
3649 write_nic_byte(dev, ANAPAR, 0x37);
3650 // Accordign to designer's explain, LBUS active will never > 10ms. We delay 10ms
3651 // Joseph increae the time to prevent firmware download fail
3655 //PlatformSleepUs(10000);
3656 // For any kind of InitializeAdapter process, we shall use system now!!
3657 priv->pFirmware->firmware_status = FW_STATUS_0_INIT;
3659 // Set to eRfoff in order not to count receive count.
3660 if(priv->RegRfOff == TRUE)
3661 priv->ieee80211->eRFPowerState = eRfOff;
3664 //3 //Config CPUReset Register
3666 //3 Firmware Reset Or Not
3667 ulRegRead = read_nic_dword(dev, CPU_GEN);
3668 if(priv->pFirmware->firmware_status == FW_STATUS_0_INIT)
3669 { //called from MPInitialized. do nothing
3670 ulRegRead |= CPU_GEN_SYSTEM_RESET;
3671 }else if(priv->pFirmware->firmware_status == FW_STATUS_5_READY)
3672 ulRegRead |= CPU_GEN_FIRMWARE_RESET; // Called from MPReset
3674 RT_TRACE(COMP_ERR, "ERROR in %s(): undefined firmware state(%d)\n", __FUNCTION__, priv->pFirmware->firmware_status);
3677 //2008.06.03, for WOL 90 hw bug
3678 ulRegRead &= (~(CPU_GEN_GPIO_UART));
3681 write_nic_dword(dev, CPU_GEN, ulRegRead);
3687 //3 //Fix the issue of E-cut high temperature issue
3690 ICVersion = read_nic_byte(dev, IC_VERRSION);
3691 if(ICVersion >= 0x4) //E-cut only
3693 // HW SD suggest that we should not wirte this register too often, so driver
3694 // should readback this register. This register will be modified only when
3696 SwitchingRegulatorOutput = read_nic_byte(dev, SWREGULATOR);
3697 if(SwitchingRegulatorOutput != 0xb8)
3699 write_nic_byte(dev, SWREGULATOR, 0xa8);
3701 write_nic_byte(dev, SWREGULATOR, 0xb8);
3708 //3// Initialize BB before MAC
3710 //rtl8192_dump_reg(dev);
3711 RT_TRACE(COMP_INIT, "BB Config Start!\n");
3712 rtStatus = rtl8192_BBConfig(dev);
3713 if(rtStatus != RT_STATUS_SUCCESS)
3715 RT_TRACE(COMP_ERR, "BB Config failed\n");
3718 RT_TRACE(COMP_INIT,"BB Config Finished!\n");
3720 //rtl8192_dump_reg(dev);
3722 //3//Set Loopback mode or Normal mode
3724 //2006.12.13 by emily. Note!We should not merge these two CPU_GEN register writings
3725 // because setting of System_Reset bit reset MAC to default transmission mode.
3726 //Loopback mode or not
3727 priv->LoopbackMode = RTL819X_NO_LOOPBACK;
3728 //priv->LoopbackMode = RTL819X_MAC_LOOPBACK;
3729 if(priv->ResetProgress == RESET_TYPE_NORESET)
3731 ulRegRead = read_nic_dword(dev, CPU_GEN);
3732 if(priv->LoopbackMode == RTL819X_NO_LOOPBACK)
3734 ulRegRead = ((ulRegRead & CPU_GEN_NO_LOOPBACK_MSK) | CPU_GEN_NO_LOOPBACK_SET);
3736 else if (priv->LoopbackMode == RTL819X_MAC_LOOPBACK )
3738 ulRegRead |= CPU_CCK_LOOPBACK;
3742 RT_TRACE(COMP_ERR,"Serious error: wrong loopback mode setting\n");
3745 //2008.06.03, for WOL
3746 //ulRegRead &= (~(CPU_GEN_GPIO_UART));
3747 write_nic_dword(dev, CPU_GEN, ulRegRead);
3749 // 2006.11.29. After reset cpu, we sholud wait for a second, otherwise, it may fail to write registers. Emily
3752 //3Set Hardware(Do nothing now)
3753 rtl8192_hwconfig(dev);
3754 //2=======================================================
3755 // Common Setting for all of the FPGA platform. (part 1)
3756 //2=======================================================
3757 // If there is changes, please make sure it applies to all of the FPGA version
3759 write_nic_byte(dev, CMDR, CR_RE|CR_TE);
3763 write_nic_byte(dev, PCIF, ((MXDMA2_NoLimit<<MXDMA2_RX_SHIFT) | \
3764 (MXDMA2_NoLimit<<MXDMA2_TX_SHIFT) | \
3768 write_nic_byte(dev, PCIF, ((MXDMA2_NoLimit<<MXDMA2_RX_SHIFT) |\
3769 (MXDMA2_NoLimit<<MXDMA2_TX_SHIFT) ));
3773 write_nic_dword(dev, MAC0, ((u32*)dev->dev_addr)[0]);
3774 write_nic_word(dev, MAC4, ((u16*)(dev->dev_addr + 4))[0]);
3776 write_nic_dword(dev, RCR, priv->ReceiveConfig);
3778 //3 Initialize Number of Reserved Pages in Firmware Queue
3780 if(priv->bInHctTest)
3782 PlatformEFIOWrite4Byte(Adapter, RQPN1, NUM_OF_PAGE_IN_FW_QUEUE_BK_DTM << RSVD_FW_QUEUE_PAGE_BK_SHIFT |\
3783 NUM_OF_PAGE_IN_FW_QUEUE_BE_DTM << RSVD_FW_QUEUE_PAGE_BE_SHIFT | \
3784 NUM_OF_PAGE_IN_FW_QUEUE_VI_DTM << RSVD_FW_QUEUE_PAGE_VI_SHIFT | \
3785 NUM_OF_PAGE_IN_FW_QUEUE_VO_DTM <<RSVD_FW_QUEUE_PAGE_VO_SHIFT);
3786 PlatformEFIOWrite4Byte(Adapter, RQPN2, NUM_OF_PAGE_IN_FW_QUEUE_MGNT << RSVD_FW_QUEUE_PAGE_MGNT_SHIFT);
3787 PlatformEFIOWrite4Byte(Adapter, RQPN3, APPLIED_RESERVED_QUEUE_IN_FW| \
3788 NUM_OF_PAGE_IN_FW_QUEUE_BCN<<RSVD_FW_QUEUE_PAGE_BCN_SHIFT|\
3789 NUM_OF_PAGE_IN_FW_QUEUE_PUB_DTM<<RSVD_FW_QUEUE_PAGE_PUB_SHIFT);
3794 write_nic_dword(dev, RQPN1, NUM_OF_PAGE_IN_FW_QUEUE_BK << RSVD_FW_QUEUE_PAGE_BK_SHIFT |\
3795 NUM_OF_PAGE_IN_FW_QUEUE_BE << RSVD_FW_QUEUE_PAGE_BE_SHIFT | \
3796 NUM_OF_PAGE_IN_FW_QUEUE_VI << RSVD_FW_QUEUE_PAGE_VI_SHIFT | \
3797 NUM_OF_PAGE_IN_FW_QUEUE_VO <<RSVD_FW_QUEUE_PAGE_VO_SHIFT);
3798 write_nic_dword(dev, RQPN2, NUM_OF_PAGE_IN_FW_QUEUE_MGNT << RSVD_FW_QUEUE_PAGE_MGNT_SHIFT);
3799 write_nic_dword(dev, RQPN3, APPLIED_RESERVED_QUEUE_IN_FW| \
3800 NUM_OF_PAGE_IN_FW_QUEUE_BCN<<RSVD_FW_QUEUE_PAGE_BCN_SHIFT|\
3801 NUM_OF_PAGE_IN_FW_QUEUE_PUB<<RSVD_FW_QUEUE_PAGE_PUB_SHIFT);
3804 rtl8192_tx_enable(dev);
3805 rtl8192_rx_enable(dev);
3806 //3Set Response Rate Setting Register
3807 // CCK rate is supported by default.
3808 // CCK rate will be filtered out only when associated AP does not support it.
3809 ulRegRead = (0xFFF00000 & read_nic_dword(dev, RRSR)) | RATE_ALL_OFDM_AG | RATE_ALL_CCK;
3810 write_nic_dword(dev, RRSR, ulRegRead);
3811 write_nic_dword(dev, RATR0+4*7, (RATE_ALL_OFDM_AG | RATE_ALL_CCK));
3814 // TODO: (it value is only for FPGA version). need to be changed!!2006.12.18, by Emily
3815 write_nic_byte(dev, ACK_TIMEOUT, 0x30);
3817 //rtl8192_actset_wirelessmode(dev,priv->RegWirelessMode);
3818 if(priv->ResetProgress == RESET_TYPE_NORESET)
3819 rtl8192_SetWirelessMode(dev, priv->ieee80211->mode);
3820 //-----------------------------------------------------------------------------
3821 // Set up security related. 070106, by rcnjko:
3822 // 1. Clear all H/W keys.
3823 // 2. Enable H/W encryption/decryption.
3824 //-----------------------------------------------------------------------------
3825 CamResetAllEntry(dev);
3827 u8 SECR_value = 0x0;
3828 SECR_value |= SCR_TxEncEnable;
3829 SECR_value |= SCR_RxDecEnable;
3830 SECR_value |= SCR_NoSKMC;
3831 write_nic_byte(dev, SECR, SECR_value);
3834 write_nic_word(dev, ATIMWND, 2);
3835 write_nic_word(dev, BCN_INTERVAL, 100);
3836 for (i=0; i<QOS_QUEUE_NUM; i++)
3837 write_nic_dword(dev, WDCAPARA_ADD[i], 0x005e4332);
3839 // Switching regulator controller: This is set temporarily.
3840 // It's not sure if this can be removed in the future.
3841 // PJ advised to leave it by default.
3843 write_nic_byte(dev, 0xbe, 0xc0);
3845 //2=======================================================
3846 // Set PHY related configuration defined in MAC register bank
3847 //2=======================================================
3848 rtl8192_phy_configmac(dev);
3850 if (priv->card_8192_version > (u8) VERSION_8190_BD) {
3851 rtl8192_phy_getTxPower(dev);
3852 rtl8192_phy_setTxPower(dev, priv->chan);
3856 tmpvalue = read_nic_byte(dev, IC_VERRSION);
3857 priv->IC_Cut = tmpvalue;
3858 RT_TRACE(COMP_INIT, "priv->IC_Cut = 0x%x\n", priv->IC_Cut);
3859 if(priv->IC_Cut >= IC_VersionCut_D)
3861 //pHalData->bDcut = TRUE;
3862 if(priv->IC_Cut == IC_VersionCut_D)
3863 RT_TRACE(COMP_INIT, "D-cut\n");
3864 if(priv->IC_Cut == IC_VersionCut_E)
3866 RT_TRACE(COMP_INIT, "E-cut\n");
3867 // HW SD suggest that we should not wirte this register too often, so driver
3868 // should readback this register. This register will be modified only when
3874 //pHalData->bDcut = FALSE;
3875 RT_TRACE(COMP_INIT, "Before C-cut\n");
3880 RT_TRACE(COMP_INIT, "Load Firmware!\n");
3881 bfirmwareok = init_firmware(dev);
3882 if(bfirmwareok != true) {
3883 rtStatus = RT_STATUS_FAILURE;
3886 RT_TRACE(COMP_INIT, "Load Firmware finished!\n");
3889 if(priv->ResetProgress == RESET_TYPE_NORESET)
3891 RT_TRACE(COMP_INIT, "RF Config Started!\n");
3892 rtStatus = rtl8192_phy_RFConfig(dev);
3893 if(rtStatus != RT_STATUS_SUCCESS)
3895 RT_TRACE(COMP_ERR, "RF Config failed\n");
3898 RT_TRACE(COMP_INIT, "RF Config Finished!\n");
3900 rtl8192_phy_updateInitGain(dev);
3902 /*---- Set CCK and OFDM Block "ON"----*/
3903 rtl8192_setBBreg(dev, rFPGA0_RFMOD, bCCKEn, 0x1);
3904 rtl8192_setBBreg(dev, rFPGA0_RFMOD, bOFDMEn, 0x1);
3908 write_nic_byte(dev, 0x87, 0x0);
3911 //2008.06.03, for WOL
3912 ucRegRead = read_nic_byte(dev, GPE);
3914 write_nic_byte(dev, GPE, ucRegRead);
3916 ucRegRead = read_nic_byte(dev, GPO);
3918 write_nic_byte(dev, GPO, ucRegRead);
3921 //2=======================================================
3923 //2=======================================================
3927 if(priv->RegRfOff == TRUE)
3928 { // User disable RF via registry.
3929 RT_TRACE((COMP_INIT|COMP_RF|COMP_POWER), "%s(): Turn off RF for RegRfOff ----------\n",__FUNCTION__);
3930 MgntActSet_RF_State(dev, eRfOff, RF_CHANGE_BY_SW);
3931 #if 0//cosa, ask SD3 willis and he doesn't know what is this for
3932 // Those action will be discard in MgntActSet_RF_State because off the same state
3933 for(eRFPath = 0; eRFPath <pHalData->NumTotalRFPath; eRFPath++)
3934 PHY_SetRFReg(Adapter, (RF90_RADIO_PATH_E)eRFPath, 0x4, 0xC00, 0x0);
3937 else if(priv->ieee80211->RfOffReason > RF_CHANGE_BY_PS)
3938 { // H/W or S/W RF OFF before sleep.
3939 RT_TRACE((COMP_INIT|COMP_RF|COMP_POWER), "%s(): Turn off RF for RfOffReason(%d) ----------\n", __FUNCTION__,priv->ieee80211->RfOffReason);
3940 MgntActSet_RF_State(dev, eRfOff, priv->ieee80211->RfOffReason);
3942 else if(priv->ieee80211->RfOffReason >= RF_CHANGE_BY_IPS)
3943 { // H/W or S/W RF OFF before sleep.
3944 RT_TRACE((COMP_INIT|COMP_RF|COMP_POWER), "%s(): Turn off RF for RfOffReason(%d) ----------\n", __FUNCTION__,priv->ieee80211->RfOffReason);
3945 MgntActSet_RF_State(dev, eRfOff, priv->ieee80211->RfOffReason);
3949 RT_TRACE((COMP_INIT|COMP_RF|COMP_POWER), "%s(): RF-ON \n",__FUNCTION__);
3950 priv->ieee80211->eRFPowerState = eRfOn;
3951 priv->ieee80211->RfOffReason = 0;
3952 //DrvIFIndicateCurrentPhyStatus(Adapter);
3954 //Adapter->HalFunc.LedControlHandler(Adapter, LED_CTL_POWER_ON);
3957 // If inactive power mode is enabled, disable rf while in disconnected state.
3958 // But we should still tell upper layer we are in rf on state.
3959 // 2007.07.16, by shien chang.
3961 //if(!Adapter->bInHctTest)
3962 //IPSEnter(Adapter);
3969 // We can force firmware to do RF-R/W
3970 if(priv->ieee80211->FwRWRF)
3971 priv->Rf_Mode = RF_OP_By_FW;
3973 priv->Rf_Mode = RF_OP_By_SW_3wire;
3975 priv->Rf_Mode = RF_OP_By_SW_3wire;
3979 if(priv->ResetProgress == RESET_TYPE_NORESET)
3981 dm_initialize_txpower_tracking(dev);
3983 tmpRegA= rtl8192_QueryBBReg(dev,rOFDM0_XATxIQImbalance,bMaskDWord);
3984 tmpRegC= rtl8192_QueryBBReg(dev,rOFDM0_XCTxIQImbalance,bMaskDWord);
3986 if(priv->rf_type == RF_2T4R){
3987 for(i = 0; i<TxBBGainTableLength; i++)
3989 if(tmpRegA == priv->txbbgain_table[i].txbbgain_value)
3991 priv->rfa_txpowertrackingindex= (u8)i;
3992 priv->rfa_txpowertrackingindex_real= (u8)i;
3993 priv->rfa_txpowertracking_default = priv->rfa_txpowertrackingindex;
3998 for(i = 0; i<TxBBGainTableLength; i++)
4000 if(tmpRegC == priv->txbbgain_table[i].txbbgain_value)
4002 priv->rfc_txpowertrackingindex= (u8)i;
4003 priv->rfc_txpowertrackingindex_real= (u8)i;
4004 priv->rfc_txpowertracking_default = priv->rfc_txpowertrackingindex;
4008 TempCCk = rtl8192_QueryBBReg(dev, rCCK0_TxFilter1, bMaskByte2);
4010 for(i=0 ; i<CCKTxBBGainTableLength ; i++)
4012 if(TempCCk == priv->cck_txbbgain_table[i].ccktxbb_valuearray[0])
4014 priv->CCKPresentAttentuation_20Mdefault =(u8) i;
4018 priv->CCKPresentAttentuation_40Mdefault = 0;
4019 priv->CCKPresentAttentuation_difference = 0;
4020 priv->CCKPresentAttentuation = priv->CCKPresentAttentuation_20Mdefault;
4021 RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex_initial = %d\n", priv->rfa_txpowertrackingindex);
4022 RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex_real__initial = %d\n", priv->rfa_txpowertrackingindex_real);
4023 RT_TRACE(COMP_POWER_TRACKING, "priv->rfc_txpowertrackingindex_initial = %d\n", priv->rfc_txpowertrackingindex);
4024 RT_TRACE(COMP_POWER_TRACKING, "priv->rfc_txpowertrackingindex_real_initial = %d\n", priv->rfc_txpowertrackingindex_real);
4025 RT_TRACE(COMP_POWER_TRACKING, "priv->CCKPresentAttentuation_difference_initial = %d\n", priv->CCKPresentAttentuation_difference);
4026 RT_TRACE(COMP_POWER_TRACKING, "priv->CCKPresentAttentuation_initial = %d\n", priv->CCKPresentAttentuation);
4030 if(priv->ResetProgress == RESET_TYPE_NORESET)
4032 dm_initialize_txpower_tracking(dev);
4034 if(priv->IC_Cut >= IC_VersionCut_D)
4036 tmpRegA= rtl8192_QueryBBReg(dev,rOFDM0_XATxIQImbalance,bMaskDWord);
4037 tmpRegC= rtl8192_QueryBBReg(dev,rOFDM0_XCTxIQImbalance,bMaskDWord);
4038 for(i = 0; i<TxBBGainTableLength; i++)
4040 if(tmpRegA == priv->txbbgain_table[i].txbbgain_value)
4042 priv->rfa_txpowertrackingindex= (u8)i;
4043 priv->rfa_txpowertrackingindex_real= (u8)i;
4044 priv->rfa_txpowertracking_default = priv->rfa_txpowertrackingindex;
4049 TempCCk = rtl8192_QueryBBReg(dev, rCCK0_TxFilter1, bMaskByte2);
4051 for(i=0 ; i<CCKTxBBGainTableLength ; i++)
4053 if(TempCCk == priv->cck_txbbgain_table[i].ccktxbb_valuearray[0])
4055 priv->CCKPresentAttentuation_20Mdefault =(u8) i;
4059 priv->CCKPresentAttentuation_40Mdefault = 0;
4060 priv->CCKPresentAttentuation_difference = 0;
4061 priv->CCKPresentAttentuation = priv->CCKPresentAttentuation_20Mdefault;
4062 RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex_initial = %d\n", priv->rfa_txpowertrackingindex);
4063 RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex_real__initial = %d\n", priv->rfa_txpowertrackingindex_real);
4064 RT_TRACE(COMP_POWER_TRACKING, "priv->CCKPresentAttentuation_difference_initial = %d\n", priv->CCKPresentAttentuation_difference);
4065 RT_TRACE(COMP_POWER_TRACKING, "priv->CCKPresentAttentuation_initial = %d\n", priv->CCKPresentAttentuation);
4066 priv->btxpower_tracking = FALSE;//TEMPLY DISABLE
4071 rtl8192_irq_enable(dev);
4072 priv->being_init_adapter = false;
4077 void rtl8192_prepare_beacon(struct r8192_priv *priv)
4079 struct sk_buff *skb;
4080 //unsigned long flags;
4083 skb = ieee80211_get_beacon(priv->ieee80211);
4084 tcb_desc = (cb_desc *)(skb->cb + 8);
4085 //printk("===========> %s\n", __FUNCTION__);
4086 //spin_lock_irqsave(&priv->tx_lock,flags);
4087 /* prepare misc info for the beacon xmit */
4088 tcb_desc->queue_index = BEACON_QUEUE;
4089 /* IBSS does not support HT yet, use 1M defautly */
4090 tcb_desc->data_rate = 2;
4091 tcb_desc->RATRIndex = 7;
4092 tcb_desc->bTxDisableRateFallBack = 1;
4093 tcb_desc->bTxUseDriverAssingedRate = 1;
4095 skb_push(skb, priv->ieee80211->tx_headroom);
4097 rtl8192_tx(priv->ieee80211->dev,skb);
4099 //spin_unlock_irqrestore (&priv->tx_lock, flags);
4103 void rtl8192_beacon_tx_enable(struct net_device *dev)
4105 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
4107 rtl8180_set_mode(dev,EPROM_CMD_CONFIG);
4108 #ifdef CONFIG_RTL8185B
4109 priv->dma_poll_stop_mask &= ~(TPPOLLSTOP_BQ);MgntQuery_MgntFrameTxRateMgntQuery_MgntFrameTxRate
4110 write_nic_byte(dev,TPPollStop, priv->dma_poll_mask);
4112 priv->dma_poll_mask &=~(1<<TX_DMA_STOP_BEACON_SHIFT);
4113 write_nic_byte(dev,TX_DMA_POLLING,priv->dma_poll_mask);
4115 rtl8180_set_mode(dev,EPROM_CMD_NORMAL);
4120 /* this configures registers for beacon tx and enables it via
4121 * rtl8192_beacon_tx_enable(). rtl8192_beacon_tx_disable() might
4122 * be used to stop beacon transmission
4124 void rtl8192_start_beacon(struct net_device *dev)
4126 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
4127 struct ieee80211_network *net = &priv->ieee80211->current_network;
4132 DMESG("Enabling beacon TX");
4133 //rtl8192_prepare_beacon(dev);
4134 rtl8192_irq_disable(dev);
4135 //rtl8192_beacon_tx_enable(dev);
4138 write_nic_word(dev, ATIMWND, 2);
4140 /* Beacon interval (in unit of TU) */
4141 write_nic_word(dev, BCN_INTERVAL, net->beacon_interval);
4144 * DrvErlyInt (in unit of TU).
4145 * (Time to send interrupt to notify driver to c
4146 * hange beacon content)
4148 write_nic_word(dev, BCN_DRV_EARLY_INT, 10);
4151 * BcnDMATIM(in unit of us).
4152 * Indicates the time before TBTT to perform beacon queue DMA
4154 write_nic_word(dev, BCN_DMATIME, 256);
4157 * Force beacon frame transmission even after receiving
4158 * beacon frame from other ad hoc STA
4160 write_nic_byte(dev, BCN_ERR_THRESH, 100);
4162 /* Set CW and IFS */
4163 BcnTimeCfg |= BcnCW<<BCN_TCFG_CW_SHIFT;
4164 BcnTimeCfg |= BcnIFS<<BCN_TCFG_IFS;
4165 write_nic_word(dev, BCN_TCFG, BcnTimeCfg);
4168 /* enable the interrupt for ad-hoc process */
4169 rtl8192_irq_enable(dev);
4171 /***************************************************************************
4172 -------------------------------NET STUFF---------------------------
4173 ***************************************************************************/
4175 static struct net_device_stats *rtl8192_stats(struct net_device *dev)
4177 struct r8192_priv *priv = ieee80211_priv(dev);
4179 return &priv->ieee80211->stats;
4185 static bool HalTxCheckStuck8190Pci(struct net_device *dev)
4187 u16 RegTxCounter = read_nic_word(dev, 0x128);
4188 struct r8192_priv *priv = ieee80211_priv(dev);
4189 bool bStuck = FALSE;
4190 RT_TRACE(COMP_RESET,"%s():RegTxCounter is %d,TxCounter is %d\n",__FUNCTION__,RegTxCounter,priv->TxCounter);
4191 if(priv->TxCounter==RegTxCounter)
4194 priv->TxCounter = RegTxCounter;
4200 * <Assumption: RT_TX_SPINLOCK is acquired.>
4201 * First added: 2006.11.19 by emily
4204 TxCheckStuck(struct net_device *dev)
4206 struct r8192_priv *priv = ieee80211_priv(dev);
4208 ptx_ring head=NULL,tail=NULL,txring = NULL;
4209 u8 ResetThreshold = NIC_SEND_HANG_THRESHOLD_POWERSAVE;
4210 bool bCheckFwTxCnt = false;
4211 //unsigned long flags;
4214 // Decide Stuch threshold according to current power save mode
4216 //printk("++++++++++++>%s()\n",__FUNCTION__);
4217 switch (priv->ieee80211->dot11PowerSaveMode)
4219 // The threshold value may required to be adjusted .
4220 case eActive: // Active/Continuous access.
4221 ResetThreshold = NIC_SEND_HANG_THRESHOLD_NORMAL;
4223 case eMaxPs: // Max power save mode.
4224 ResetThreshold = NIC_SEND_HANG_THRESHOLD_POWERSAVE;
4226 case eFastPs: // Fast power save mode.
4227 ResetThreshold = NIC_SEND_HANG_THRESHOLD_POWERSAVE;
4232 // Check whether specific tcb has been queued for a specific time
4234 for(QueueID = 0; QueueID < MAX_TX_QUEUE; QueueID++)
4238 if(QueueID == TXCMD_QUEUE)
4243 tail=priv->txmapringtail;
4244 head=priv->txmapringhead;
4248 tail=priv->txbkpringtail;
4249 head=priv->txbkpringhead;
4253 tail=priv->txbepringtail;
4254 head=priv->txbepringhead;
4258 tail=priv->txvipringtail;
4259 head=priv->txvipringhead;
4263 tail=priv->txvopringtail;
4264 head=priv->txvopringhead;
4279 RT_TRACE(COMP_ERR,"%s():txring is NULL , BUG!\n",__FUNCTION__);
4282 txring->nStuckCount++;
4284 if(txring->nStuckCount > ResetThreshold)
4286 RT_TRACE( COMP_RESET, "<== TxCheckStuck()\n" );
4287 return RESET_TYPE_NORMAL;
4290 bCheckFwTxCnt = TRUE;
4296 if(HalTxCheckStuck8190Pci(dev))
4298 RT_TRACE(COMP_RESET, "TxCheckStuck(): Fw indicates no Tx condition! \n");
4299 return RESET_TYPE_SILENT;
4303 return RESET_TYPE_NORESET;
4307 static bool HalRxCheckStuck8190Pci(struct net_device *dev)
4309 struct r8192_priv *priv = ieee80211_priv(dev);
4310 u16 RegRxCounter = read_nic_word(dev, 0x130);
4311 bool bStuck = FALSE;
4312 static u8 rx_chk_cnt = 0;
4313 RT_TRACE(COMP_RESET,"%s(): RegRxCounter is %d,RxCounter is %d\n",__FUNCTION__,RegRxCounter,priv->RxCounter);
4314 // If rssi is small, we should check rx for long time because of bad rx.
4315 // or maybe it will continuous silent reset every 2 seconds.
4317 if(priv->undecorated_smoothed_pwdb >= (RateAdaptiveTH_High+5))
4319 rx_chk_cnt = 0; //high rssi, check rx stuck right now.
4321 else if(priv->undecorated_smoothed_pwdb < (RateAdaptiveTH_High+5) &&
4322 ((priv->CurrentChannelBW!=HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb>=RateAdaptiveTH_Low_40M) ||
4323 (priv->CurrentChannelBW==HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb>=RateAdaptiveTH_Low_20M)) )
4335 else if(((priv->CurrentChannelBW!=HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb<RateAdaptiveTH_Low_40M) ||
4336 (priv->CurrentChannelBW==HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb<RateAdaptiveTH_Low_20M)) &&
4337 priv->undecorated_smoothed_pwdb >= VeryLowRSSI)
4341 //DbgPrint("RSSI < %d && RSSI >= %d, no check this time \n", RateAdaptiveTH_Low, VeryLowRSSI);
4347 //DbgPrint("RSSI < %d && RSSI >= %d, check this time \n", RateAdaptiveTH_Low, VeryLowRSSI);
4354 //DbgPrint("RSSI <= %d, no check this time \n", VeryLowRSSI);
4360 //DbgPrint("RSSI <= %d, check this time \n", VeryLowRSSI);
4369 if(priv->RxCounter==RegRxCounter)
4372 priv->RxCounter = RegRxCounter;
4377 static RESET_TYPE RxCheckStuck(struct net_device *dev)
4380 if(HalRxCheckStuck8190Pci(dev))
4382 RT_TRACE(COMP_RESET, "RxStuck Condition\n");
4383 return RESET_TYPE_SILENT;
4386 return RESET_TYPE_NORESET;
4390 rtl819x_ifcheck_resetornot(struct net_device *dev)
4392 struct r8192_priv *priv = ieee80211_priv(dev);
4393 RESET_TYPE TxResetType = RESET_TYPE_NORESET;
4394 RESET_TYPE RxResetType = RESET_TYPE_NORESET;
4395 RT_RF_POWER_STATE rfState;
4397 rfState = priv->ieee80211->eRFPowerState;
4399 TxResetType = TxCheckStuck(dev);
4401 if( rfState != eRfOff &&
4402 /*ADAPTER_TEST_STATUS_FLAG(Adapter, ADAPTER_STATUS_FW_DOWNLOAD_FAILURE)) &&*/
4403 (priv->ieee80211->iw_mode != IW_MODE_ADHOC))
4405 // If driver is in the status of firmware download failure , driver skips RF initialization and RF is
4406 // in turned off state. Driver should check whether Rx stuck and do silent reset. And
4407 // if driver is in firmware download failure status, driver should initialize RF in the following
4408 // silent reset procedure Emily, 2008.01.21
4410 // Driver should not check RX stuck in IBSS mode because it is required to
4411 // set Check BSSID in order to send beacon, however, if check BSSID is
4412 // set, STA cannot hear any packet a all. Emily, 2008.04.12
4413 RxResetType = RxCheckStuck(dev);
4417 RT_TRACE(COMP_RESET,"%s(): TxResetType is %d, RxResetType is %d\n",__FUNCTION__,TxResetType,RxResetType);
4418 if(TxResetType==RESET_TYPE_NORMAL || RxResetType==RESET_TYPE_NORMAL)
4419 return RESET_TYPE_NORMAL;
4420 else if(TxResetType==RESET_TYPE_SILENT || RxResetType==RESET_TYPE_SILENT)
4421 return RESET_TYPE_SILENT;
4423 return RESET_TYPE_NORESET;
4428 static void CamRestoreAllEntry(struct net_device *dev)
4431 struct r8192_priv *priv = ieee80211_priv(dev);
4432 u8* MacAddr = priv->ieee80211->current_network.bssid;
4434 static u8 CAM_CONST_ADDR[4][6] = {
4435 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
4436 {0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
4437 {0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
4438 {0x00, 0x00, 0x00, 0x00, 0x00, 0x03}};
4439 static u8 CAM_CONST_BROAD[] =
4440 {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
4442 RT_TRACE(COMP_SEC, "CamRestoreAllEntry: \n");
4445 if ((priv->ieee80211->pairwise_key_type == KEY_TYPE_WEP40)||
4446 (priv->ieee80211->pairwise_key_type == KEY_TYPE_WEP104))
4449 for(EntryId=0; EntryId<4; EntryId++)
4452 MacAddr = CAM_CONST_ADDR[EntryId];
4456 priv->ieee80211->pairwise_key_type,
4464 else if(priv->ieee80211->pairwise_key_type == KEY_TYPE_TKIP)
4468 if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
4472 priv->ieee80211->pairwise_key_type,
4480 priv->ieee80211->pairwise_key_type,
4486 else if(priv->ieee80211->pairwise_key_type == KEY_TYPE_CCMP)
4490 if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
4494 priv->ieee80211->pairwise_key_type,
4502 priv->ieee80211->pairwise_key_type,
4511 if(priv->ieee80211->group_key_type == KEY_TYPE_TKIP)
4513 MacAddr = CAM_CONST_BROAD;
4514 for(EntryId=1 ; EntryId<4 ; EntryId++)
4520 priv->ieee80211->group_key_type,
4526 if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
4530 priv->ieee80211->group_key_type,
4535 else if(priv->ieee80211->group_key_type == KEY_TYPE_CCMP)
4537 MacAddr = CAM_CONST_BROAD;
4538 for(EntryId=1; EntryId<4 ; EntryId++)
4544 priv->ieee80211->group_key_type,
4551 if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
4555 priv->ieee80211->group_key_type,
4562 void rtl8192_cancel_deferred_work(struct r8192_priv* priv);
4563 int _rtl8192_up(struct net_device *dev);
4566 * This function is used to fix Tx/Rx stop bug temporarily.
4567 * This function will do "system reset" to NIC when Tx or Rx is stuck.
4568 * The method checking Tx/Rx stuck of this function is supported by FW,
4569 * which reports Tx and Rx counter to register 0x128 and 0x130.
4571 static void rtl819x_ifsilentreset(struct net_device *dev)
4573 struct r8192_priv *priv = ieee80211_priv(dev);
4575 int reset_status = 0;
4576 struct ieee80211_device *ieee = priv->ieee80211;
4579 // 2007.07.20. If we need to check CCK stop, please uncomment this line.
4580 //bStuck = Adapter->HalFunc.CheckHWStopHandler(Adapter);
4582 if(priv->ResetProgress==RESET_TYPE_NORESET)
4586 RT_TRACE(COMP_RESET,"=========>Reset progress!! \n");
4588 // Set the variable for reset.
4589 priv->ResetProgress = RESET_TYPE_SILENT;
4590 // rtl8192_close(dev);
4592 down(&priv->wx_sem);
4595 RT_TRACE(COMP_ERR,"%s():the driver is not up! return\n",__FUNCTION__);
4600 RT_TRACE(COMP_RESET,"%s():======>start to down the driver\n",__FUNCTION__);
4601 if(!netif_queue_stopped(dev))
4602 netif_stop_queue(dev);
4604 dm_backup_dynamic_mechanism_state(dev);
4606 rtl8192_irq_disable(dev);
4607 rtl8192_cancel_deferred_work(priv);
4609 del_timer_sync(&priv->watch_dog_timer);
4610 ieee->sync_scan_hurryup = 1;
4611 if(ieee->state == IEEE80211_LINKED)
4613 down(&ieee->wx_sem);
4614 printk("ieee->state is IEEE80211_LINKED\n");
4615 ieee80211_stop_send_beacons(priv->ieee80211);
4616 del_timer_sync(&ieee->associate_timer);
4617 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
4618 cancel_delayed_work(&ieee->associate_retry_wq);
4620 ieee80211_stop_scan(ieee);
4621 netif_carrier_off(dev);
4625 printk("ieee->state is NOT LINKED\n");
4626 ieee80211_softmac_stop_protocol(priv->ieee80211);
4628 rtl8192_rtx_disable(dev);
4630 RT_TRACE(COMP_RESET,"%s():<==========down process is finished\n",__FUNCTION__);
4631 RT_TRACE(COMP_RESET,"%s():===========>start to up the driver\n",__FUNCTION__);
4632 reset_status = _rtl8192_up(dev);
4634 RT_TRACE(COMP_RESET,"%s():<===========up process is finished\n",__FUNCTION__);
4635 if(reset_status == -1)
4644 RT_TRACE(COMP_ERR," ERR!!! %s(): Reset Failed!!\n",__FUNCTION__);
4648 ieee->is_silent_reset = 1;
4650 EnableHWSecurityConfig8192(dev);
4652 if(ieee->state == IEEE80211_LINKED && ieee->iw_mode == IW_MODE_INFRA)
4654 ieee->set_chan(ieee->dev, ieee->current_network.channel);
4657 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
4658 queue_work(ieee->wq, &ieee->associate_complete_wq);
4660 schedule_task(&ieee->associate_complete_wq);
4665 else if(ieee->state == IEEE80211_LINKED && ieee->iw_mode == IW_MODE_ADHOC)
4667 ieee->set_chan(ieee->dev, ieee->current_network.channel);
4668 ieee->link_change(ieee->dev);
4670 // notify_wx_assoc_event(ieee);
4672 ieee80211_start_send_beacons(ieee);
4674 if (ieee->data_hard_resume)
4675 ieee->data_hard_resume(ieee->dev);
4676 netif_carrier_on(ieee->dev);
4680 CamRestoreAllEntry(dev);
4682 // Restore the previous setting for all dynamic mechanism
4683 dm_restore_dynamic_mechanism_state(dev);
4685 priv->ResetProgress = RESET_TYPE_NORESET;
4686 priv->reset_count++;
4688 priv->bForcedSilentReset =false;
4689 priv->bResetInProgress = false;
4691 // For test --> force write UFWP.
4692 write_nic_byte(dev, UFWP, 1);
4693 RT_TRACE(COMP_RESET, "Reset finished!! ====>[%d]\n", priv->reset_count);
4699 void InactivePsWorkItemCallback(struct net_device *dev)
4701 struct r8192_priv *priv = ieee80211_priv(dev);
4702 PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->ieee80211->PowerSaveControl));
4705 RT_TRACE(COMP_POWER, "InactivePsWorkItemCallback() ---------> \n");
4707 // This flag "bSwRfProcessing", indicates the status of IPS procedure, should be set if the IPS workitem
4708 // is really scheduled.
4709 // The old code, sets this flag before scheduling the IPS workitem and however, at the same time the
4710 // previous IPS workitem did not end yet, fails to schedule the current workitem. Thus, bSwRfProcessing
4711 // blocks the IPS procedure of switching RF.
4712 // By Bruce, 2007-12-25.
4714 pPSC->bSwRfProcessing = TRUE;
4716 RT_TRACE(COMP_RF, "InactivePsWorkItemCallback(): Set RF to %s.\n", \
4717 pPSC->eInactivePowerState == eRfOff?"OFF":"ON");
4720 MgntActSet_RF_State(dev, pPSC->eInactivePowerState, RF_CHANGE_BY_IPS);
4723 // To solve CAM values miss in RF OFF, rewrite CAM values after RF ON. By Bruce, 2007-09-20.
4726 if(pPSC->eInactivePowerState == eRfOn)
4727 CamRestoreAllEntry(dev);
4729 pPSC->bSwRfProcessing = FALSE;
4730 RT_TRACE(COMP_POWER, "InactivePsWorkItemCallback() <--------- \n");
4735 // Enter the inactive power save mode. RF will be off
4736 // 2007.08.17, by shien chang.
4739 IPSEnter(struct net_device *dev)
4741 struct r8192_priv *priv = ieee80211_priv(dev);
4742 PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->ieee80211->PowerSaveControl));
4743 RT_RF_POWER_STATE rtState;
4745 if (pPSC->bInactivePs)
4747 rtState = priv->ieee80211->eRFPowerState;
4749 // Added by Bruce, 2007-12-25.
4750 // Do not enter IPS in the following conditions:
4751 // (1) RF is already OFF or Sleep
4752 // (2) bSwRfProcessing (indicates the IPS is still under going)
4753 // (3) Connectted (only disconnected can trigger IPS)
4754 // (4) IBSS (send Beacon)
4755 // (5) AP mode (send Beacon)
4757 if (rtState == eRfOn && !pPSC->bSwRfProcessing
4758 && (priv->ieee80211->state != IEEE80211_LINKED) )
4760 RT_TRACE(COMP_RF,"IPSEnter(): Turn off RF.\n");
4761 pPSC->eInactivePowerState = eRfOff;
4762 // queue_work(priv->priv_wq,&(pPSC->InactivePsWorkItem));
4763 InactivePsWorkItemCallback(dev);
4770 // Leave the inactive power save mode, RF will be on.
4771 // 2007.08.17, by shien chang.
4774 IPSLeave(struct net_device *dev)
4776 struct r8192_priv *priv = ieee80211_priv(dev);
4777 PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->ieee80211->PowerSaveControl));
4778 RT_RF_POWER_STATE rtState;
4780 if (pPSC->bInactivePs)
4782 rtState = priv->ieee80211->eRFPowerState;
4783 if (rtState != eRfOn && !pPSC->bSwRfProcessing && priv->ieee80211->RfOffReason <= RF_CHANGE_BY_IPS)
4785 RT_TRACE(COMP_POWER, "IPSLeave(): Turn on RF.\n");
4786 pPSC->eInactivePowerState = eRfOn;
4787 // queue_work(priv->priv_wq,&(pPSC->InactivePsWorkItem));
4788 InactivePsWorkItemCallback(dev);
4793 static void CAM_read_entry(
4794 struct net_device *dev,
4798 u32 target_command=0;
4799 u32 target_content=0;
4803 // printk("=======>start read CAM\n");
4804 for(entry_i=0;entry_i<CAM_CONTENT_COUNT;entry_i++)
4806 // polling bit, and No Write enable, and address
4807 target_command= entry_i+CAM_CONTENT_COUNT*iIndex;
4808 target_command= target_command | BIT31;
4810 //Check polling bit is clear
4815 ulStatus = read_nic_dword(dev, RWCAM);
4816 if(ulStatus & BIT31){
4824 write_nic_dword(dev, RWCAM, target_command);
4825 RT_TRACE(COMP_SEC,"CAM_read_entry(): WRITE A0: %x \n",target_command);
4826 // printk("CAM_read_entry(): WRITE A0: %lx \n",target_command);
4827 target_content = read_nic_dword(dev, RCAMO);
4828 RT_TRACE(COMP_SEC, "CAM_read_entry(): WRITE A8: %x \n",target_content);
4829 // printk("CAM_read_entry(): WRITE A8: %lx \n",target_content);
4834 static void rtl819x_update_rxcounts(
4835 struct r8192_priv *priv,
4844 *TotalRxDataNum = 0;
4846 SlotIndex = (priv->ieee80211->LinkDetectInfo.SlotIndex++)%(priv->ieee80211->LinkDetectInfo.SlotNum);
4847 priv->ieee80211->LinkDetectInfo.RxBcnNum[SlotIndex] = priv->ieee80211->LinkDetectInfo.NumRecvBcnInPeriod;
4848 priv->ieee80211->LinkDetectInfo.RxDataNum[SlotIndex] = priv->ieee80211->LinkDetectInfo.NumRecvDataInPeriod;
4849 for( i=0; i<priv->ieee80211->LinkDetectInfo.SlotNum; i++ ){
4850 *TotalRxBcnNum += priv->ieee80211->LinkDetectInfo.RxBcnNum[i];
4851 *TotalRxDataNum += priv->ieee80211->LinkDetectInfo.RxDataNum[i];
4856 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
4857 void rtl819x_watchdog_wqcallback(struct work_struct *work)
4859 struct delayed_work *dwork = container_of(work,struct delayed_work,work);
4860 struct r8192_priv *priv = container_of(dwork,struct r8192_priv,watch_dog_wq);
4861 struct net_device *dev = priv->ieee80211->dev;
4863 extern void rtl819x_watchdog_wqcallback(struct net_device *dev)
4865 struct r8192_priv *priv = ieee80211_priv(dev);
4867 struct ieee80211_device* ieee = priv->ieee80211;
4868 RESET_TYPE ResetType = RESET_TYPE_NORESET;
4869 static u8 check_reset_cnt=0;
4870 unsigned long flags;
4871 bool bBusyTraffic = false;
4872 static u8 last_time = 0;
4875 hal_dm_watchdog(dev);
4877 // printk("watch_dog ENABLE_IPS\n");
4878 if(ieee->actscanning == false){
4879 if((ieee->iw_mode != IW_MODE_ADHOC) && (ieee->state == IEEE80211_NOLINK) && (ieee->beinretry == false) && (ieee->eRFPowerState == eRfOn) && !ieee->is_set_key){
4880 if(ieee->PowerSaveControl.ReturnPoint == IPS_CALLBACK_NONE){
4881 printk("====================>haha:IPSEnter()\n");
4883 //ieee80211_stop_scan(priv->ieee80211);
4888 {//to get busy traffic condition
4889 if(ieee->state == IEEE80211_LINKED)
4891 if( ieee->LinkDetectInfo.NumRxOkInPeriod> 666 ||
4892 ieee->LinkDetectInfo.NumTxOkInPeriod> 666 ) {
4893 bBusyTraffic = true;
4897 ieee->LinkDetectInfo.NumRxOkInPeriod = 0;
4898 ieee->LinkDetectInfo.NumTxOkInPeriod = 0;
4899 ieee->LinkDetectInfo.bBusyTraffic = bBusyTraffic;
4903 //added by amy for AP roaming
4906 if(ieee->state == IEEE80211_LINKED && ieee->iw_mode == IW_MODE_INFRA)
4908 u32 TotalRxBcnNum = 0;
4909 u32 TotalRxDataNum = 0;
4911 rtl819x_update_rxcounts(priv, &TotalRxBcnNum, &TotalRxDataNum);
4912 if((TotalRxBcnNum+TotalRxDataNum) == 0)
4914 if( ieee->eRFPowerState == eRfOff)
4915 RT_TRACE(COMP_ERR,"========>%s()\n",__FUNCTION__);
4916 printk("===>%s(): AP is power off,connect another one\n",__FUNCTION__);
4917 // Dot11d_Reset(dev);
4918 ieee->state = IEEE80211_ASSOCIATING;
4919 notify_wx_assoc_event(priv->ieee80211);
4920 RemovePeerTS(priv->ieee80211,priv->ieee80211->current_network.bssid);
4921 ieee->is_roaming = true;
4922 ieee->is_set_key = false;
4923 ieee->link_change(dev);
4924 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
4925 queue_work(ieee->wq, &ieee->associate_procedure_wq);
4927 schedule_task(&ieee->associate_procedure_wq);
4931 ieee->LinkDetectInfo.NumRecvBcnInPeriod=0;
4932 ieee->LinkDetectInfo.NumRecvDataInPeriod=0;
4935 // CAM_read_entry(dev,0);
4936 //check if reset the driver
4937 spin_lock_irqsave(&priv->tx_lock,flags);
4938 if(check_reset_cnt++ >= 3 && !ieee->is_roaming && (last_time != 1))
4940 ResetType = rtl819x_ifcheck_resetornot(dev);
4941 check_reset_cnt = 3;
4942 //DbgPrint("Start to check silent reset\n");
4944 spin_unlock_irqrestore(&priv->tx_lock,flags);
4945 if(!priv->bDisableNormalResetCheck && ResetType == RESET_TYPE_NORMAL)
4947 priv->ResetProgress = RESET_TYPE_NORMAL;
4948 RT_TRACE(COMP_RESET,"%s(): NOMAL RESET\n",__FUNCTION__);
4951 /* disable silent reset temply 2008.9.11*/
4953 if( ((priv->force_reset) || (!priv->bDisableNormalResetCheck && ResetType==RESET_TYPE_SILENT))) // This is control by OID set in Pomelo
4956 rtl819x_ifsilentreset(dev);
4961 priv->force_reset = false;
4962 priv->bForcedSilentReset = false;
4963 priv->bResetInProgress = false;
4964 RT_TRACE(COMP_TRACE, " <==RtUsbCheckForHangWorkItemCallback()\n");
4968 void watch_dog_timer_callback(unsigned long data)
4970 struct r8192_priv *priv = ieee80211_priv((struct net_device *) data);
4971 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
4972 queue_delayed_work(priv->priv_wq,&priv->watch_dog_wq,0);
4974 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
4975 schedule_task(&priv->watch_dog_wq);
4977 queue_work(priv->priv_wq,&priv->watch_dog_wq);
4980 mod_timer(&priv->watch_dog_timer, jiffies + MSECS(IEEE80211_WATCH_DOG_TIME));
4983 int _rtl8192_up(struct net_device *dev)
4985 struct r8192_priv *priv = ieee80211_priv(dev);
4987 RT_STATUS init_status = RT_STATUS_SUCCESS;
4989 priv->ieee80211->ieee_up=1;
4990 RT_TRACE(COMP_INIT, "Bringing up iface");
4992 init_status = rtl8192_adapter_start(dev);
4993 if(init_status != RT_STATUS_SUCCESS)
4995 RT_TRACE(COMP_ERR,"ERR!!! %s(): initialization is failed!\n",__FUNCTION__);
4998 RT_TRACE(COMP_INIT, "start adapter finished\n");
5000 if(priv->ieee80211->eRFPowerState!=eRfOn)
5001 MgntActSet_RF_State(dev, eRfOn, priv->ieee80211->RfOffReason);
5003 if(priv->ieee80211->state != IEEE80211_LINKED)
5004 ieee80211_softmac_start_protocol(priv->ieee80211);
5005 ieee80211_reset_queue(priv->ieee80211);
5006 watch_dog_timer_callback((unsigned long) dev);
5007 if(!netif_queue_stopped(dev))
5008 netif_start_queue(dev);
5010 netif_wake_queue(dev);
5016 static int rtl8192_open(struct net_device *dev)
5018 struct r8192_priv *priv = ieee80211_priv(dev);
5021 down(&priv->wx_sem);
5022 ret = rtl8192_up(dev);
5029 int rtl8192_up(struct net_device *dev)
5031 struct r8192_priv *priv = ieee80211_priv(dev);
5033 if (priv->up == 1) return -1;
5035 return _rtl8192_up(dev);
5039 static int rtl8192_close(struct net_device *dev)
5041 struct r8192_priv *priv = ieee80211_priv(dev);
5044 down(&priv->wx_sem);
5046 ret = rtl8192_down(dev);
5054 int rtl8192_down(struct net_device *dev)
5056 struct r8192_priv *priv = ieee80211_priv(dev);
5062 if (priv->up == 0) return -1;
5065 priv->ieee80211->ieee_up = 0;
5066 RT_TRACE(COMP_DOWN, "==========>%s()\n", __FUNCTION__);
5068 if (!netif_queue_stopped(dev))
5069 netif_stop_queue(dev);
5071 rtl8192_irq_disable(dev);
5073 if(!priv->ieee80211->bSupportRemoteWakeUp) {
5074 MgntActSet_RF_State(dev, eRfOff, RF_CHANGE_BY_INIT);
5075 // 2006.11.30. System reset bit
5076 ulRegRead = read_nic_dword(dev, CPU_GEN);
5077 ulRegRead|=CPU_GEN_SYSTEM_RESET;
5078 write_nic_dword(dev, CPU_GEN, ulRegRead);
5080 //2008.06.03 for WOL
5081 write_nic_dword(dev, WFCRC0, 0xffffffff);
5082 write_nic_dword(dev, WFCRC1, 0xffffffff);
5083 write_nic_dword(dev, WFCRC2, 0xffffffff);
5086 ucRegRead = read_nic_byte(dev, GPO);
5088 write_nic_byte(dev, GPO, ucRegRead);
5090 //Write PMR register
5091 write_nic_byte(dev, PMR, 0x5);
5092 //Disable tx, enanble rx
5093 write_nic_byte(dev, MacBlkCtrl, 0xa);
5096 // flush_scheduled_work();
5097 rtl8192_cancel_deferred_work(priv);
5099 del_timer_sync(&priv->watch_dog_timer);
5101 ieee80211_softmac_stop_protocol(priv->ieee80211);
5103 MgntActSet_RF_State(dev, eRfOff, RF_CHANGE_BY_INIT);
5105 rtl8192_rtx_disable(dev);
5106 memset(&priv->ieee80211->current_network, 0 , offsetof(struct ieee80211_network, list));
5108 RT_TRACE(COMP_DOWN, "<==========%s()\n", __FUNCTION__);
5114 void rtl8192_commit(struct net_device *dev)
5116 struct r8192_priv *priv = ieee80211_priv(dev);
5118 if (priv->up == 0) return ;
5121 ieee80211_softmac_stop_protocol(priv->ieee80211);
5123 rtl8192_irq_disable(dev);
5124 rtl8192_rtx_disable(dev);
5129 void rtl8192_restart(struct net_device *dev)
5131 struct r8192_priv *priv = ieee80211_priv(dev);
5133 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
5134 void rtl8192_restart(struct work_struct *work)
5136 struct r8192_priv *priv = container_of(work, struct r8192_priv, reset_wq);
5137 struct net_device *dev = priv->ieee80211->dev;
5139 void rtl8192_restart(struct net_device *dev)
5142 struct r8192_priv *priv = ieee80211_priv(dev);
5145 down(&priv->wx_sem);
5147 rtl8192_commit(dev);
5152 static void r8192_set_multicast(struct net_device *dev)
5154 struct r8192_priv *priv = ieee80211_priv(dev);
5157 //down(&priv->wx_sem);
5161 promisc = (dev->flags & IFF_PROMISC) ? 1:0;
5163 if (promisc != priv->promisc) {
5165 // rtl8192_commit(dev);
5168 priv->promisc = promisc;
5170 //schedule_work(&priv->reset_wq);
5171 //up(&priv->wx_sem);
5175 static int r8192_set_mac_adr(struct net_device *dev, void *mac)
5177 struct r8192_priv *priv = ieee80211_priv(dev);
5178 struct sockaddr *addr = mac;
5180 down(&priv->wx_sem);
5182 memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
5184 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
5185 schedule_work(&priv->reset_wq);
5187 schedule_task(&priv->reset_wq);
5194 /* based on ipw2200 driver */
5195 static int rtl8192_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
5197 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
5198 struct iwreq *wrq = (struct iwreq *)rq;
5200 struct ieee80211_device *ieee = priv->ieee80211;
5202 u8 broadcast_addr[6] = {0xff,0xff,0xff,0xff,0xff,0xff};
5203 struct iw_point *p = &wrq->u.data;
5204 struct ieee_param *ipw = NULL;//(struct ieee_param *)wrq->u.data.pointer;
5206 down(&priv->wx_sem);
5209 if (p->length < sizeof(struct ieee_param) || !p->pointer){
5214 ipw = (struct ieee_param *)kmalloc(p->length, GFP_KERNEL);
5219 if (copy_from_user(ipw, p->pointer, p->length)) {
5226 case RTL_IOCTL_WPA_SUPPLICANT:
5227 //parse here for HW security
5228 if (ipw->cmd == IEEE_CMD_SET_ENCRYPTION)
5230 if (ipw->u.crypt.set_tx)
5232 if (strcmp(ipw->u.crypt.alg, "CCMP") == 0)
5233 ieee->pairwise_key_type = KEY_TYPE_CCMP;
5234 else if (strcmp(ipw->u.crypt.alg, "TKIP") == 0)
5235 ieee->pairwise_key_type = KEY_TYPE_TKIP;
5236 else if (strcmp(ipw->u.crypt.alg, "WEP") == 0)
5238 if (ipw->u.crypt.key_len == 13)
5239 ieee->pairwise_key_type = KEY_TYPE_WEP104;
5240 else if (ipw->u.crypt.key_len == 5)
5241 ieee->pairwise_key_type = KEY_TYPE_WEP40;
5244 ieee->pairwise_key_type = KEY_TYPE_NA;
5246 if (ieee->pairwise_key_type)
5248 memcpy((u8*)key, ipw->u.crypt.key, 16);
5249 EnableHWSecurityConfig8192(dev);
5250 //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!
5252 setKey(dev, 4, ipw->u.crypt.idx, ieee->pairwise_key_type, (u8*)ieee->ap_mac_addr, 0, key);
5253 if (ieee->auth_mode != 2) //LEAP WEP will never set this.
5254 setKey(dev, ipw->u.crypt.idx, ipw->u.crypt.idx, ieee->pairwise_key_type, (u8*)ieee->ap_mac_addr, 0, key);
5256 if ((ieee->pairwise_key_type == KEY_TYPE_CCMP) && ieee->pHTInfo->bCurrentHTSupport){
5257 write_nic_byte(dev, 0x173, 1); //fix aes bug
5261 else //if (ipw->u.crypt.idx) //group key use idx > 0
5263 memcpy((u8*)key, ipw->u.crypt.key, 16);
5264 if (strcmp(ipw->u.crypt.alg, "CCMP") == 0)
5265 ieee->group_key_type= KEY_TYPE_CCMP;
5266 else if (strcmp(ipw->u.crypt.alg, "TKIP") == 0)
5267 ieee->group_key_type = KEY_TYPE_TKIP;
5268 else if (strcmp(ipw->u.crypt.alg, "WEP") == 0)
5270 if (ipw->u.crypt.key_len == 13)
5271 ieee->group_key_type = KEY_TYPE_WEP104;
5272 else if (ipw->u.crypt.key_len == 5)
5273 ieee->group_key_type = KEY_TYPE_WEP40;
5276 ieee->group_key_type = KEY_TYPE_NA;
5278 if (ieee->group_key_type)
5282 ipw->u.crypt.idx, //KeyIndex
5283 ieee->group_key_type, //KeyType
5284 broadcast_addr, //MacAddr
5294 printk("@@ wrq->u pointer = ");
5295 for(i=0;i<wrq->u.data.length;i++){
5296 if(i%10==0) printk("\n");
5297 printk( "%8x|", ((u32*)wrq->u.data.pointer)[i] );
5301 #endif /*JOHN_DEBUG*/
5302 ret = ieee80211_wpa_supplicant_ioctl(priv->ieee80211, &wrq->u.data);
5317 static u8 HwRateToMRate90(bool bIsHT, u8 rate)
5323 case DESC90_RATE1M: ret_rate = MGN_1M; break;
5324 case DESC90_RATE2M: ret_rate = MGN_2M; break;
5325 case DESC90_RATE5_5M: ret_rate = MGN_5_5M; break;
5326 case DESC90_RATE11M: ret_rate = MGN_11M; break;
5327 case DESC90_RATE6M: ret_rate = MGN_6M; break;
5328 case DESC90_RATE9M: ret_rate = MGN_9M; break;
5329 case DESC90_RATE12M: ret_rate = MGN_12M; break;
5330 case DESC90_RATE18M: ret_rate = MGN_18M; break;
5331 case DESC90_RATE24M: ret_rate = MGN_24M; break;
5332 case DESC90_RATE36M: ret_rate = MGN_36M; break;
5333 case DESC90_RATE48M: ret_rate = MGN_48M; break;
5334 case DESC90_RATE54M: ret_rate = MGN_54M; break;
5337 RT_TRACE(COMP_RECV, "HwRateToMRate90(): Non supported Rate [%x], bIsHT = %d!!!\n", rate, bIsHT);
5343 case DESC90_RATEMCS0: ret_rate = MGN_MCS0; break;
5344 case DESC90_RATEMCS1: ret_rate = MGN_MCS1; break;
5345 case DESC90_RATEMCS2: ret_rate = MGN_MCS2; break;
5346 case DESC90_RATEMCS3: ret_rate = MGN_MCS3; break;
5347 case DESC90_RATEMCS4: ret_rate = MGN_MCS4; break;
5348 case DESC90_RATEMCS5: ret_rate = MGN_MCS5; break;
5349 case DESC90_RATEMCS6: ret_rate = MGN_MCS6; break;
5350 case DESC90_RATEMCS7: ret_rate = MGN_MCS7; break;
5351 case DESC90_RATEMCS8: ret_rate = MGN_MCS8; break;
5352 case DESC90_RATEMCS9: ret_rate = MGN_MCS9; break;
5353 case DESC90_RATEMCS10: ret_rate = MGN_MCS10; break;
5354 case DESC90_RATEMCS11: ret_rate = MGN_MCS11; break;
5355 case DESC90_RATEMCS12: ret_rate = MGN_MCS12; break;
5356 case DESC90_RATEMCS13: ret_rate = MGN_MCS13; break;
5357 case DESC90_RATEMCS14: ret_rate = MGN_MCS14; break;
5358 case DESC90_RATEMCS15: ret_rate = MGN_MCS15; break;
5359 case DESC90_RATEMCS32: ret_rate = (0x80|0x20); break;
5362 RT_TRACE(COMP_RECV, "HwRateToMRate90(): Non supported Rate [%x], bIsHT = %d!!!\n",rate, bIsHT);
5371 * Function: UpdateRxPktTimeStamp
5372 * Overview: Recored down the TSF time stamp when receiving a packet
5380 * (pRfd->Status.TimeStampHigh is updated)
5381 * (pRfd->Status.TimeStampLow is updated)
5385 static void UpdateRxPktTimeStamp8190 (struct net_device *dev, struct ieee80211_rx_stats *stats)
5387 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
5389 if(stats->bIsAMPDU && !stats->bFirstMPDU) {
5390 stats->mac_time[0] = priv->LastRxDescTSFLow;
5391 stats->mac_time[1] = priv->LastRxDescTSFHigh;
5393 priv->LastRxDescTSFLow = stats->mac_time[0];
5394 priv->LastRxDescTSFHigh = stats->mac_time[1];
5398 static long rtl819x_translate_todbm(u8 signal_strength_index)// 0-100 index.
5400 long signal_power; // in dBm.
5402 // Translate to dBm (x=0.5y-95).
5403 signal_power = (long)((signal_strength_index + 1) >> 1);
5406 return signal_power;
5411 // Update Rx signal related information in the packet reeived
5412 // to RxStats. User application can query RxStats to realize
5413 // current Rx signal status.
5416 // In normal operation, user only care about the information of the BSS
5417 // and we shall invoke this function if the packet received is from the BSS.
5420 rtl819x_update_rxsignalstatistics8190pci(
5421 struct r8192_priv * priv,
5422 struct ieee80211_rx_stats * pprevious_stats
5427 //2 <ToDo> Update Rx Statistics (such as signal strength and signal quality).
5430 if(priv->stats.recv_signal_power == 0)
5431 priv->stats.recv_signal_power = pprevious_stats->RecvSignalPower;
5433 // To avoid the past result restricting the statistics sensitivity, weight the current power (5/6) to speed up the
5434 // reaction of smoothed Signal Power.
5435 if(pprevious_stats->RecvSignalPower > priv->stats.recv_signal_power)
5437 else if(pprevious_stats->RecvSignalPower < priv->stats.recv_signal_power)
5440 // We need more correct power of received packets and the "SignalStrength" of RxStats have been beautified or translated,
5441 // so we record the correct power in Dbm here. By Bruce, 2008-03-07.
5443 priv->stats.recv_signal_power = (priv->stats.recv_signal_power * 5 + pprevious_stats->RecvSignalPower + weighting) / 6;
5447 rtl8190_process_cck_rxpathsel(
5448 struct r8192_priv * priv,
5449 struct ieee80211_rx_stats * pprevious_stats
5452 #ifdef RTL8190P //Only 90P 2T4R need to check
5453 char last_cck_adc_pwdb[4]={0,0,0,0};
5455 //cosa add for Rx path selection
5456 if(priv->rf_type == RF_2T4R && DM_RxPathSelTable.Enable)
5458 if(pprevious_stats->bIsCCK &&
5459 (pprevious_stats->bPacketToSelf ||pprevious_stats->bPacketBeacon))
5461 /* record the cck adc_pwdb to the sliding window. */
5462 if(priv->stats.cck_adc_pwdb.TotalNum++ >= PHY_RSSI_SLID_WIN_MAX)
5464 priv->stats.cck_adc_pwdb.TotalNum = PHY_RSSI_SLID_WIN_MAX;
5465 for(i=RF90_PATH_A; i<RF90_PATH_MAX; i++)
5467 last_cck_adc_pwdb[i] = priv->stats.cck_adc_pwdb.elements[i][priv->stats.cck_adc_pwdb.index];
5468 priv->stats.cck_adc_pwdb.TotalVal[i] -= last_cck_adc_pwdb[i];
5471 for(i=RF90_PATH_A; i<RF90_PATH_MAX; i++)
5473 priv->stats.cck_adc_pwdb.TotalVal[i] += pprevious_stats->cck_adc_pwdb[i];
5474 priv->stats.cck_adc_pwdb.elements[i][priv->stats.cck_adc_pwdb.index] = pprevious_stats->cck_adc_pwdb[i];
5476 priv->stats.cck_adc_pwdb.index++;
5477 if(priv->stats.cck_adc_pwdb.index >= PHY_RSSI_SLID_WIN_MAX)
5478 priv->stats.cck_adc_pwdb.index = 0;
5480 for(i=RF90_PATH_A; i<RF90_PATH_MAX; i++)
5482 DM_RxPathSelTable.cck_pwdb_sta[i] = priv->stats.cck_adc_pwdb.TotalVal[i]/priv->stats.cck_adc_pwdb.TotalNum;
5485 for(i=RF90_PATH_A; i<RF90_PATH_MAX; i++)
5487 if(pprevious_stats->cck_adc_pwdb[i] > (char)priv->undecorated_smoothed_cck_adc_pwdb[i])
5489 priv->undecorated_smoothed_cck_adc_pwdb[i] =
5490 ( (priv->undecorated_smoothed_cck_adc_pwdb[i]*(Rx_Smooth_Factor-1)) +
5491 (pprevious_stats->cck_adc_pwdb[i])) /(Rx_Smooth_Factor);
5492 priv->undecorated_smoothed_cck_adc_pwdb[i] = priv->undecorated_smoothed_cck_adc_pwdb[i] + 1;
5496 priv->undecorated_smoothed_cck_adc_pwdb[i] =
5497 ( (priv->undecorated_smoothed_cck_adc_pwdb[i]*(Rx_Smooth_Factor-1)) +
5498 (pprevious_stats->cck_adc_pwdb[i])) /(Rx_Smooth_Factor);
5507 /* 2008/01/22 MH We can not delcare RSSI/EVM total value of sliding window to
5508 be a local static. Otherwise, it may increase when we return from S3/S4. The
5509 value will be kept in memory or disk. We must delcare the value in adapter
5510 and it will be reinitialized when return from S3/S4. */
5511 static void rtl8192_process_phyinfo(struct r8192_priv * priv, u8* buffer,struct ieee80211_rx_stats * pprevious_stats, struct ieee80211_rx_stats * pcurrent_stats)
5513 bool bcheck = false;
5515 u32 nspatial_stream, tmp_val;
5517 static u32 slide_rssi_index=0, slide_rssi_statistics=0;
5518 static u32 slide_evm_index=0, slide_evm_statistics=0;
5519 static u32 last_rssi=0, last_evm=0;
5520 //cosa add for rx path selection
5521 // static long slide_cck_adc_pwdb_index=0, slide_cck_adc_pwdb_statistics=0;
5522 // static char last_cck_adc_pwdb[4]={0,0,0,0};
5523 //cosa add for beacon rssi smoothing
5524 static u32 slide_beacon_adc_pwdb_index=0, slide_beacon_adc_pwdb_statistics=0;
5525 static u32 last_beacon_adc_pwdb=0;
5527 struct ieee80211_hdr_3addr *hdr;
5529 unsigned int frag,seq;
5530 hdr = (struct ieee80211_hdr_3addr *)buffer;
5531 sc = le16_to_cpu(hdr->seq_ctl);
5532 frag = WLAN_GET_SEQ_FRAG(sc);
5533 seq = WLAN_GET_SEQ_SEQ(sc);
5534 //cosa add 04292008 to record the sequence number
5535 pcurrent_stats->Seq_Num = seq;
5537 // Check whether we should take the previous packet into accounting
5539 if(!pprevious_stats->bIsAMPDU)
5541 // if previous packet is not aggregated packet
5545 //remve for that we don't use AMPDU to calculate PWDB,because the reported PWDB of some AP is fault.
5547 // if previous packet is aggregated packet, and current packet
5549 // (2) is the first packet of one AMPDU
5550 // that means the previous packet is the last one aggregated packet
5551 if( !pcurrent_stats->bIsAMPDU || pcurrent_stats->bFirstMPDU)
5556 if(slide_rssi_statistics++ >= PHY_RSSI_SLID_WIN_MAX)
5558 slide_rssi_statistics = PHY_RSSI_SLID_WIN_MAX;
5559 last_rssi = priv->stats.slide_signal_strength[slide_rssi_index];
5560 priv->stats.slide_rssi_total -= last_rssi;
5562 priv->stats.slide_rssi_total += pprevious_stats->SignalStrength;
5564 priv->stats.slide_signal_strength[slide_rssi_index++] = pprevious_stats->SignalStrength;
5565 if(slide_rssi_index >= PHY_RSSI_SLID_WIN_MAX)
5566 slide_rssi_index = 0;
5568 // <1> Showed on UI for user, in dbm
5569 tmp_val = priv->stats.slide_rssi_total/slide_rssi_statistics;
5570 priv->stats.signal_strength = rtl819x_translate_todbm((u8)tmp_val);
5571 pcurrent_stats->rssi = priv->stats.signal_strength;
5573 // If the previous packet does not match the criteria, neglect it
5575 if(!pprevious_stats->bPacketMatchBSSID)
5577 if(!pprevious_stats->bToSelfBA)
5584 rtl8190_process_cck_rxpathsel(priv,pprevious_stats);
5589 priv->stats.num_process_phyinfo++;
5591 /* record the general signal strength to the sliding window. */
5592 if(slide_rssi_statistics++ >= PHY_RSSI_SLID_WIN_MAX)
5594 slide_rssi_statistics = PHY_RSSI_SLID_WIN_MAX;
5595 last_rssi = priv->stats.slide_signal_strength[slide_rssi_index];
5596 priv->stats.slide_rssi_total -= last_rssi;
5598 priv->stats.slide_rssi_total += pprevious_stats->SignalStrength;
5600 priv->stats.slide_signal_strength[slide_rssi_index++] = pprevious_stats->SignalStrength;
5601 if(slide_rssi_index >= PHY_RSSI_SLID_WIN_MAX)
5602 slide_rssi_index = 0;
5604 // <1> Showed on UI for user, in dbm
5605 tmp_val = priv->stats.slide_rssi_total/slide_rssi_statistics;
5606 priv->stats.signal_strength = rtl819x_translate_todbm((u8)tmp_val);
5609 // <2> Showed on UI for engineering
5610 // hardware does not provide rssi information for each rf path in CCK
5611 if(!pprevious_stats->bIsCCK && pprevious_stats->bPacketToSelf)
5613 for (rfpath = RF90_PATH_A; rfpath < RF90_PATH_C; rfpath++)
5615 if (!rtl8192_phy_CheckIsLegalRFPath(priv->ieee80211->dev, rfpath))
5617 RT_TRACE(COMP_DBG,"Jacken -> pPreviousstats->RxMIMOSignalStrength[rfpath] = %d \n" ,pprevious_stats->RxMIMOSignalStrength[rfpath] );
5618 //Fixed by Jacken 2008-03-20
5619 if(priv->stats.rx_rssi_percentage[rfpath] == 0)
5621 priv->stats.rx_rssi_percentage[rfpath] = pprevious_stats->RxMIMOSignalStrength[rfpath];
5622 //DbgPrint("MIMO RSSI initialize \n");
5624 if(pprevious_stats->RxMIMOSignalStrength[rfpath] > priv->stats.rx_rssi_percentage[rfpath])
5626 priv->stats.rx_rssi_percentage[rfpath] =
5627 ( (priv->stats.rx_rssi_percentage[rfpath]*(Rx_Smooth_Factor-1)) +
5628 (pprevious_stats->RxMIMOSignalStrength[rfpath])) /(Rx_Smooth_Factor);
5629 priv->stats.rx_rssi_percentage[rfpath] = priv->stats.rx_rssi_percentage[rfpath] + 1;
5633 priv->stats.rx_rssi_percentage[rfpath] =
5634 ( (priv->stats.rx_rssi_percentage[rfpath]*(Rx_Smooth_Factor-1)) +
5635 (pprevious_stats->RxMIMOSignalStrength[rfpath])) /(Rx_Smooth_Factor);
5637 RT_TRACE(COMP_DBG,"Jacken -> priv->RxStats.RxRSSIPercentage[rfPath] = %d \n" ,priv->stats.rx_rssi_percentage[rfpath] );
5645 //cosa add for beacon rssi smoothing by average.
5646 if(pprevious_stats->bPacketBeacon)
5648 /* record the beacon pwdb to the sliding window. */
5649 if(slide_beacon_adc_pwdb_statistics++ >= PHY_Beacon_RSSI_SLID_WIN_MAX)
5651 slide_beacon_adc_pwdb_statistics = PHY_Beacon_RSSI_SLID_WIN_MAX;
5652 last_beacon_adc_pwdb = priv->stats.Slide_Beacon_pwdb[slide_beacon_adc_pwdb_index];
5653 priv->stats.Slide_Beacon_Total -= last_beacon_adc_pwdb;
5654 //DbgPrint("slide_beacon_adc_pwdb_index = %d, last_beacon_adc_pwdb = %d, Adapter->RxStats.Slide_Beacon_Total = %d\n",
5655 // slide_beacon_adc_pwdb_index, last_beacon_adc_pwdb, Adapter->RxStats.Slide_Beacon_Total);
5657 priv->stats.Slide_Beacon_Total += pprevious_stats->RxPWDBAll;
5658 priv->stats.Slide_Beacon_pwdb[slide_beacon_adc_pwdb_index] = pprevious_stats->RxPWDBAll;
5659 //DbgPrint("slide_beacon_adc_pwdb_index = %d, pPreviousRfd->Status.RxPWDBAll = %d\n", slide_beacon_adc_pwdb_index, pPreviousRfd->Status.RxPWDBAll);
5660 slide_beacon_adc_pwdb_index++;
5661 if(slide_beacon_adc_pwdb_index >= PHY_Beacon_RSSI_SLID_WIN_MAX)
5662 slide_beacon_adc_pwdb_index = 0;
5663 pprevious_stats->RxPWDBAll = priv->stats.Slide_Beacon_Total/slide_beacon_adc_pwdb_statistics;
5664 if(pprevious_stats->RxPWDBAll >= 3)
5665 pprevious_stats->RxPWDBAll -= 3;
5668 RT_TRACE(COMP_RXDESC, "Smooth %s PWDB = %d\n",
5669 pprevious_stats->bIsCCK? "CCK": "OFDM",
5670 pprevious_stats->RxPWDBAll);
5672 if(pprevious_stats->bPacketToSelf || pprevious_stats->bPacketBeacon || pprevious_stats->bToSelfBA)
5674 if(priv->undecorated_smoothed_pwdb < 0) // initialize
5676 priv->undecorated_smoothed_pwdb = pprevious_stats->RxPWDBAll;
5677 //DbgPrint("First pwdb initialize \n");
5680 if(pprevious_stats->RxPWDBAll > (u32)priv->undecorated_smoothed_pwdb)
5682 priv->undecorated_smoothed_pwdb =
5683 ( ((priv->undecorated_smoothed_pwdb)*(Rx_Smooth_Factor-1)) +
5684 (pprevious_stats->RxPWDBAll)) /(Rx_Smooth_Factor);
5685 priv->undecorated_smoothed_pwdb = priv->undecorated_smoothed_pwdb + 1;
5689 priv->undecorated_smoothed_pwdb =
5690 ( ((priv->undecorated_smoothed_pwdb)*(Rx_Smooth_Factor-1)) +
5691 (pprevious_stats->RxPWDBAll)) /(Rx_Smooth_Factor);
5694 //Fixed by Jacken 2008-03-20
5695 if(pPreviousRfd->Status.RxPWDBAll > (u32)pHalData->UndecoratedSmoothedPWDB)
5697 pHalData->UndecoratedSmoothedPWDB =
5698 ( ((pHalData->UndecoratedSmoothedPWDB)* 5) + (pPreviousRfd->Status.RxPWDBAll)) / 6;
5699 pHalData->UndecoratedSmoothedPWDB = pHalData->UndecoratedSmoothedPWDB + 1;
5703 pHalData->UndecoratedSmoothedPWDB =
5704 ( ((pHalData->UndecoratedSmoothedPWDB)* 5) + (pPreviousRfd->Status.RxPWDBAll)) / 6;
5707 rtl819x_update_rxsignalstatistics8190pci(priv,pprevious_stats);
5713 /* record the general EVM to the sliding window. */
5714 if(pprevious_stats->SignalQuality == 0)
5719 if(pprevious_stats->bPacketToSelf || pprevious_stats->bPacketBeacon || pprevious_stats->bToSelfBA){
5720 if(slide_evm_statistics++ >= PHY_RSSI_SLID_WIN_MAX){
5721 slide_evm_statistics = PHY_RSSI_SLID_WIN_MAX;
5722 last_evm = priv->stats.slide_evm[slide_evm_index];
5723 priv->stats.slide_evm_total -= last_evm;
5726 priv->stats.slide_evm_total += pprevious_stats->SignalQuality;
5728 priv->stats.slide_evm[slide_evm_index++] = pprevious_stats->SignalQuality;
5729 if(slide_evm_index >= PHY_RSSI_SLID_WIN_MAX)
5730 slide_evm_index = 0;
5732 // <1> Showed on UI for user, in percentage.
5733 tmp_val = priv->stats.slide_evm_total/slide_evm_statistics;
5734 priv->stats.signal_quality = tmp_val;
5735 //cosa add 10/11/2007, Showed on UI for user in Windows Vista, for Link quality.
5736 priv->stats.last_signal_strength_inpercent = tmp_val;
5739 // <2> Showed on UI for engineering
5740 if(pprevious_stats->bPacketToSelf || pprevious_stats->bPacketBeacon || pprevious_stats->bToSelfBA)
5742 for(nspatial_stream = 0; nspatial_stream<2 ; nspatial_stream++) // 2 spatial stream
5744 if(pprevious_stats->RxMIMOSignalQuality[nspatial_stream] != -1)
5746 if(priv->stats.rx_evm_percentage[nspatial_stream] == 0) // initialize
5748 priv->stats.rx_evm_percentage[nspatial_stream] = pprevious_stats->RxMIMOSignalQuality[nspatial_stream];
5750 priv->stats.rx_evm_percentage[nspatial_stream] =
5751 ( (priv->stats.rx_evm_percentage[nspatial_stream]* (Rx_Smooth_Factor-1)) +
5752 (pprevious_stats->RxMIMOSignalQuality[nspatial_stream]* 1)) / (Rx_Smooth_Factor);
5760 /*-----------------------------------------------------------------------------
5761 * Function: rtl819x_query_rxpwrpercentage()
5765 * Input: char antpower
5769 * Return: 0-100 percentage
5773 * 05/26/2008 amy Create Version 0 porting from windows code.
5775 *---------------------------------------------------------------------------*/
5776 static u8 rtl819x_query_rxpwrpercentage(
5780 if ((antpower <= -100) || (antpower >= 20))
5784 else if (antpower >= 0)
5790 return (100+antpower);
5793 } /* QueryRxPwrPercentage */
5796 rtl819x_evm_dbtopercentage(
5808 ret_val = 0 - ret_val;
5817 // We want good-looking for signal strength/quality
5818 // 2007/7/19 01:09, by cosa.
5820 static long rtl819x_signal_scale_mapping(long currsig)
5824 // Step 1. Scale mapping.
5825 if(currsig >= 61 && currsig <= 100)
5827 retsig = 90 + ((currsig - 60) / 4);
5829 else if(currsig >= 41 && currsig <= 60)
5831 retsig = 78 + ((currsig - 40) / 2);
5833 else if(currsig >= 31 && currsig <= 40)
5835 retsig = 66 + (currsig - 30);
5837 else if(currsig >= 21 && currsig <= 30)
5839 retsig = 54 + (currsig - 20);
5841 else if(currsig >= 5 && currsig <= 20)
5843 retsig = 42 + (((currsig - 5) * 2) / 3);
5845 else if(currsig == 4)
5849 else if(currsig == 3)
5853 else if(currsig == 2)
5857 else if(currsig == 1)
5869 static void rtl8192_query_rxphystatus(
5870 struct r8192_priv * priv,
5871 struct ieee80211_rx_stats * pstats,
5872 prx_desc_819x_pci pdesc,
5873 prx_fwinfo_819x_pci pdrvinfo,
5874 struct ieee80211_rx_stats * precord_stats,
5875 bool bpacket_match_bssid,
5876 bool bpacket_toself,
5881 //PRT_RFD_STATUS pRtRfdStatus = &(pRfd->Status);
5882 phy_sts_ofdm_819xpci_t* pofdm_buf;
5883 phy_sts_cck_819xpci_t * pcck_buf;
5884 phy_ofdm_rx_status_rxsc_sgien_exintfflag* prxsc;
5886 u8 i,max_spatial_stream, tmp_rxsnr, tmp_rxevm, rxsc_sgien_exflg;
5887 char rx_pwr[4], rx_pwr_all=0;
5888 //long rx_avg_pwr = 0;
5889 char rx_snrX, rx_evmX;
5891 u32 RSSI, total_rssi=0;//, total_evm=0;
5892 // long signal_strength_index = 0;
5896 /* 2007/07/04 MH For OFDM RSSI. For high power or not. */
5897 static u8 check_reg824 = 0;
5898 static u32 reg824_bit9 = 0;
5900 priv->stats.numqry_phystatus++;
5902 is_cck_rate = rx_hal_is_cck_rate(pdrvinfo);
5904 // Record it for next packet processing
5905 memset(precord_stats, 0, sizeof(struct ieee80211_rx_stats));
5906 pstats->bPacketMatchBSSID = precord_stats->bPacketMatchBSSID = bpacket_match_bssid;
5907 pstats->bPacketToSelf = precord_stats->bPacketToSelf = bpacket_toself;
5908 pstats->bIsCCK = precord_stats->bIsCCK = is_cck_rate;//RX_HAL_IS_CCK_RATE(pDrvInfo);
5909 pstats->bPacketBeacon = precord_stats->bPacketBeacon = bPacketBeacon;
5910 pstats->bToSelfBA = precord_stats->bToSelfBA = bToSelfBA;
5911 /*2007.08.30 requested by SD3 Jerry */
5912 if(check_reg824 == 0)
5914 reg824_bit9 = rtl8192_QueryBBReg(priv->ieee80211->dev, rFPGA0_XA_HSSIParameter2, 0x200);
5919 prxpkt = (u8*)pdrvinfo;
5921 /* Move pointer to the 16th bytes. Phy status start address. */
5922 prxpkt += sizeof(rx_fwinfo_819x_pci);
5924 /* Initial the cck and ofdm buffer pointer */
5925 pcck_buf = (phy_sts_cck_819xpci_t *)prxpkt;
5926 pofdm_buf = (phy_sts_ofdm_819xpci_t *)prxpkt;
5928 pstats->RxMIMOSignalQuality[0] = -1;
5929 pstats->RxMIMOSignalQuality[1] = -1;
5930 precord_stats->RxMIMOSignalQuality[0] = -1;
5931 precord_stats->RxMIMOSignalQuality[1] = -1;
5936 // (1)Hardware does not provide RSSI for CCK
5940 // (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive)
5942 u8 report;//, cck_agc_rpt;
5945 char cck_adc_pwdb[4];
5947 priv->stats.numqry_phystatusCCK++;
5949 #ifdef RTL8190P //Only 90P 2T4R need to check
5950 if(priv->rf_type == RF_2T4R && DM_RxPathSelTable.Enable && bpacket_match_bssid)
5952 for(i=RF90_PATH_A; i<RF90_PATH_MAX; i++)
5954 tmp_pwdb = pcck_buf->adc_pwdb_X[i];
5955 cck_adc_pwdb[i] = (char)tmp_pwdb;
5956 cck_adc_pwdb[i] /= 2;
5957 pstats->cck_adc_pwdb[i] = precord_stats->cck_adc_pwdb[i] = cck_adc_pwdb[i];
5958 //DbgPrint("RF-%d tmp_pwdb = 0x%x, cck_adc_pwdb = %d", i, tmp_pwdb, cck_adc_pwdb[i]);
5965 report = pcck_buf->cck_agc_rpt & 0xc0;
5969 //Fixed by Jacken from Bryant 2008-03-20
5970 //Original value is -38 , -26 , -14 , -2
5971 //Fixed value is -35 , -23 , -11 , 6
5973 rx_pwr_all = -35 - (pcck_buf->cck_agc_rpt & 0x3e);
5976 rx_pwr_all = -23 - (pcck_buf->cck_agc_rpt & 0x3e);
5979 rx_pwr_all = -11 - (pcck_buf->cck_agc_rpt & 0x3e);
5982 rx_pwr_all = 8 - (pcck_buf->cck_agc_rpt & 0x3e);
5988 report = pcck_buf->cck_agc_rpt & 0x60;
5993 rx_pwr_all = -35 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1) ;
5996 rx_pwr_all = -23 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1);
5999 rx_pwr_all = -11 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1) ;
6002 rx_pwr_all = -8 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1) ;
6007 pwdb_all = rtl819x_query_rxpwrpercentage(rx_pwr_all);
6008 pstats->RxPWDBAll = precord_stats->RxPWDBAll = pwdb_all;
6009 pstats->RecvSignalPower = rx_pwr_all;
6012 // (3) Get Signal Quality (EVM)
6014 if(bpacket_match_bssid)
6018 if(pstats->RxPWDBAll > 40)
6023 sq = pcck_buf->sq_rpt;
6025 if(pcck_buf->sq_rpt > 64)
6027 else if (pcck_buf->sq_rpt < 20)
6030 sq = ((64-sq) * 100) / 44;
6032 pstats->SignalQuality = precord_stats->SignalQuality = sq;
6033 pstats->RxMIMOSignalQuality[0] = precord_stats->RxMIMOSignalQuality[0] = sq;
6034 pstats->RxMIMOSignalQuality[1] = precord_stats->RxMIMOSignalQuality[1] = -1;
6039 priv->stats.numqry_phystatusHT++;
6041 // (1)Get RSSI for HT rate
6043 for(i=RF90_PATH_A; i<RF90_PATH_MAX; i++)
6045 // 2008/01/30 MH we will judge RF RX path now.
6046 if (priv->brfpath_rxenable[i])
6051 //Fixed by Jacken from Bryant 2008-03-20
6052 //Original value is 106
6053 #ifdef RTL8190P //Modify by Jacken 2008/03/31
6054 rx_pwr[i] = ((pofdm_buf->trsw_gain_X[i]&0x3F)*2) - 106;
6056 rx_pwr[i] = ((pofdm_buf->trsw_gain_X[i]&0x3F)*2) - 110;
6059 //Get Rx snr value in DB
6060 tmp_rxsnr = pofdm_buf->rxsnr_X[i];
6061 rx_snrX = (char)(tmp_rxsnr);
6063 priv->stats.rxSNRdB[i] = (long)rx_snrX;
6065 /* Translate DBM to percentage. */
6066 RSSI = rtl819x_query_rxpwrpercentage(rx_pwr[i]);
6067 if (priv->brfpath_rxenable[i])
6070 /* Record Signal Strength for next packet */
6071 if(bpacket_match_bssid)
6073 pstats->RxMIMOSignalStrength[i] =(u8) RSSI;
6074 precord_stats->RxMIMOSignalStrength[i] =(u8) RSSI;
6080 // (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive)
6082 //Fixed by Jacken from Bryant 2008-03-20
6083 //Original value is 106
6084 rx_pwr_all = (((pofdm_buf->pwdb_all ) >> 1 )& 0x7f) -106;
6085 pwdb_all = rtl819x_query_rxpwrpercentage(rx_pwr_all);
6087 pstats->RxPWDBAll = precord_stats->RxPWDBAll = pwdb_all;
6088 pstats->RxPower = precord_stats->RxPower = rx_pwr_all;
6089 pstats->RecvSignalPower = rx_pwr_all;
6091 // (3)EVM of HT rate
6093 if(pdrvinfo->RxHT && pdrvinfo->RxRate>=DESC90_RATEMCS8 &&
6094 pdrvinfo->RxRate<=DESC90_RATEMCS15)
6095 max_spatial_stream = 2; //both spatial stream make sense
6097 max_spatial_stream = 1; //only spatial stream 1 makes sense
6099 for(i=0; i<max_spatial_stream; i++)
6101 tmp_rxevm = pofdm_buf->rxevm_X[i];
6102 rx_evmX = (char)(tmp_rxevm);
6104 // Do not use shift operation like "rx_evmX >>= 1" because the compilor of free build environment
6105 // fill most significant bit to "zero" when doing shifting operation which may change a negative
6106 // value to positive one, then the dbm value (which is supposed to be negative) is not correct anymore.
6109 evm = rtl819x_evm_dbtopercentage(rx_evmX);
6111 EVM = SignalScaleMapping(EVM);//make it good looking, from 0~100
6113 if(bpacket_match_bssid)
6115 if(i==0) // Fill value in RFD, Get the first spatial stream only
6116 pstats->SignalQuality = precord_stats->SignalQuality = (u8)(evm & 0xff);
6117 pstats->RxMIMOSignalQuality[i] = precord_stats->RxMIMOSignalQuality[i] = (u8)(evm & 0xff);
6122 /* record rx statistics for debug */
6123 rxsc_sgien_exflg = pofdm_buf->rxsc_sgien_exflg;
6124 prxsc = (phy_ofdm_rx_status_rxsc_sgien_exintfflag *)&rxsc_sgien_exflg;
6125 if(pdrvinfo->BW) //40M channel
6126 priv->stats.received_bwtype[1+prxsc->rxsc]++;
6128 priv->stats.received_bwtype[0]++;
6131 //UI BSS List signal strength(in percentage), make it good looking, from 0~100.
6132 //It is assigned to the BSS List in GetValueFromBeaconOrProbeRsp().
6135 pstats->SignalStrength = precord_stats->SignalStrength = (u8)(rtl819x_signal_scale_mapping((long)pwdb_all));//PWDB_ALL;
6140 //pRfd->Status.SignalStrength = pRecordRfd->Status.SignalStrength = (u1Byte)(SignalScaleMapping(total_rssi/=RF90_PATH_MAX));//(u1Byte)(total_rssi/=RF90_PATH_MAX);
6141 // We can judge RX path number now.
6143 pstats->SignalStrength = precord_stats->SignalStrength = (u8)(rtl819x_signal_scale_mapping((long)(total_rssi/=rf_rx_num)));
6145 } /* QueryRxPhyStatus8190Pci */
6148 rtl8192_record_rxdesc_forlateruse(
6149 struct ieee80211_rx_stats * psrc_stats,
6150 struct ieee80211_rx_stats * ptarget_stats
6153 ptarget_stats->bIsAMPDU = psrc_stats->bIsAMPDU;
6154 ptarget_stats->bFirstMPDU = psrc_stats->bFirstMPDU;
6155 //ptarget_stats->Seq_Num = psrc_stats->Seq_Num;
6160 static void TranslateRxSignalStuff819xpci(struct net_device *dev,
6161 struct sk_buff *skb,
6162 struct ieee80211_rx_stats * pstats,
6163 prx_desc_819x_pci pdesc,
6164 prx_fwinfo_819x_pci pdrvinfo)
6166 // TODO: We must only check packet for current MAC address. Not finish
6167 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
6168 bool bpacket_match_bssid, bpacket_toself;
6169 bool bPacketBeacon=false, bToSelfBA=false;
6170 static struct ieee80211_rx_stats previous_stats;
6171 struct ieee80211_hdr_3addr *hdr;
6174 // Get Signal Quality for only RX data queue (but not command queue)
6179 /* Get MAC frame start address. */
6180 tmp_buf = skb->data;
6182 hdr = (struct ieee80211_hdr_3addr *)tmp_buf;
6183 fc = le16_to_cpu(hdr->frame_ctl);
6184 type = WLAN_FC_GET_TYPE(fc);
6185 praddr = hdr->addr1;
6187 /* Check if the received packet is acceptabe. */
6188 bpacket_match_bssid = ((IEEE80211_FTYPE_CTL != type) &&
6189 (eqMacAddr(priv->ieee80211->current_network.bssid, (fc & IEEE80211_FCTL_TODS)? hdr->addr1 : (fc & IEEE80211_FCTL_FROMDS )? hdr->addr2 : hdr->addr3))
6190 && (!pstats->bHwError) && (!pstats->bCRC)&& (!pstats->bICV));
6191 bpacket_toself = bpacket_match_bssid & (eqMacAddr(praddr, priv->ieee80211->dev->dev_addr));
6193 if(WLAN_FC_GET_FRAMETYPE(fc)== IEEE80211_STYPE_BEACON)
6195 bPacketBeacon = true;
6196 //DbgPrint("Beacon 2, MatchBSSID = %d, ToSelf = %d \n", bPacketMatchBSSID, bPacketToSelf);
6198 if(WLAN_FC_GET_FRAMETYPE(fc) == IEEE80211_STYPE_BLOCKACK)
6200 if((eqMacAddr(praddr,dev->dev_addr)))
6202 //DbgPrint("BlockAck, MatchBSSID = %d, ToSelf = %d \n", bPacketMatchBSSID, bPacketToSelf);
6206 if(bpacket_match_bssid)
6208 priv->stats.numpacket_matchbssid++;
6211 priv->stats.numpacket_toself++;
6214 // Process PHY information for previous packet (RSSI/PWDB/EVM)
6216 // Because phy information is contained in the last packet of AMPDU only, so driver
6217 // should process phy information of previous packet
6218 rtl8192_process_phyinfo(priv, tmp_buf,&previous_stats, pstats);
6219 rtl8192_query_rxphystatus(priv, pstats, pdesc, pdrvinfo, &previous_stats, bpacket_match_bssid,
6220 bpacket_toself ,bPacketBeacon, bToSelfBA);
6221 rtl8192_record_rxdesc_forlateruse(pstats, &previous_stats);
6226 static void rtl8192_tx_resume(struct net_device *dev)
6228 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
6229 struct ieee80211_device *ieee = priv->ieee80211;
6230 struct sk_buff *skb;
6233 for(queue_index = BK_QUEUE; queue_index < TXCMD_QUEUE;queue_index++) {
6234 while((!skb_queue_empty(&ieee->skb_waitQ[queue_index]))&&
6235 (priv->ieee80211->check_nic_enough_desc(dev,queue_index) > 0)) {
6236 /* 1. dequeue the packet from the wait queue */
6237 skb = skb_dequeue(&ieee->skb_waitQ[queue_index]);
6238 /* 2. tx the packet directly */
6239 ieee->softmac_data_hard_start_xmit(skb,dev,0/* rate useless now*/);
6241 if(queue_index!=MGNT_QUEUE) {
6242 ieee->stats.tx_packets++;
6243 ieee->stats.tx_bytes += skb->len;
6250 void rtl8192_irq_tx_tasklet(struct r8192_priv *priv)
6252 rtl8192_tx_resume(priv->ieee80211->dev);
6256 * Function: UpdateReceivedRateHistogramStatistics
6257 * Overview: Recored down the received data rate
6265 * (Adapter->RxStats.ReceivedRateHistogram[] is updated)
6269 static void UpdateReceivedRateHistogramStatistics8190(
6270 struct net_device *dev,
6271 struct ieee80211_rx_stats* pstats
6274 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
6275 u32 rcvType=1; //0: Total, 1:OK, 2:CRC, 3:ICV
6277 u32 preamble_guardinterval; //1: short preamble/GI, 0: long preamble/GI
6279 /* 2007/03/09 MH We will not update rate of packet from rx cmd queue. */
6281 if (pRfd->queue_id == CMPK_RX_QUEUE_ID)
6286 else if(pstats->bICV)
6289 if(pstats->bShortPreamble)
6290 preamble_guardinterval = 1;// short
6292 preamble_guardinterval = 0;// long
6294 switch(pstats->rate)
6299 case MGN_1M: rateIndex = 0; break;
6300 case MGN_2M: rateIndex = 1; break;
6301 case MGN_5_5M: rateIndex = 2; break;
6302 case MGN_11M: rateIndex = 3; break;
6306 case MGN_6M: rateIndex = 4; break;
6307 case MGN_9M: rateIndex = 5; break;
6308 case MGN_12M: rateIndex = 6; break;
6309 case MGN_18M: rateIndex = 7; break;
6310 case MGN_24M: rateIndex = 8; break;
6311 case MGN_36M: rateIndex = 9; break;
6312 case MGN_48M: rateIndex = 10; break;
6313 case MGN_54M: rateIndex = 11; break;
6315 // 11n High throughput rate
6317 case MGN_MCS0: rateIndex = 12; break;
6318 case MGN_MCS1: rateIndex = 13; break;
6319 case MGN_MCS2: rateIndex = 14; break;
6320 case MGN_MCS3: rateIndex = 15; break;
6321 case MGN_MCS4: rateIndex = 16; break;
6322 case MGN_MCS5: rateIndex = 17; break;
6323 case MGN_MCS6: rateIndex = 18; break;
6324 case MGN_MCS7: rateIndex = 19; break;
6325 case MGN_MCS8: rateIndex = 20; break;
6326 case MGN_MCS9: rateIndex = 21; break;
6327 case MGN_MCS10: rateIndex = 22; break;
6328 case MGN_MCS11: rateIndex = 23; break;
6329 case MGN_MCS12: rateIndex = 24; break;
6330 case MGN_MCS13: rateIndex = 25; break;
6331 case MGN_MCS14: rateIndex = 26; break;
6332 case MGN_MCS15: rateIndex = 27; break;
6333 default: rateIndex = 28; break;
6335 priv->stats.received_preamble_GI[preamble_guardinterval][rateIndex]++;
6336 priv->stats.received_rate_histogram[0][rateIndex]++; //total
6337 priv->stats.received_rate_histogram[rcvType][rateIndex]++;
6340 static void rtl8192_rx(struct net_device *dev)
6342 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
6343 struct ieee80211_hdr_1addr *ieee80211_hdr = NULL;
6344 bool unicast_packet = false;
6345 struct ieee80211_rx_stats stats = {
6349 .freq = IEEE80211_24GHZ_BAND,
6351 unsigned int count = priv->rxringcount;
6353 stats.nic_type = NIC_8192E;
6356 rx_desc_819x_pci *pdesc = &priv->rx_ring[priv->rx_idx];//rx descriptor
6357 struct sk_buff *skb = priv->rx_buf[priv->rx_idx];//rx pkt
6360 /* wait data to be filled by hardware */
6363 stats.bICV = pdesc->ICV;
6364 stats.bCRC = pdesc->CRC32;
6365 stats.bHwError = pdesc->CRC32 | pdesc->ICV;
6367 stats.Length = pdesc->Length;
6368 if(stats.Length < 24)
6369 stats.bHwError |= 1;
6371 if(stats.bHwError) {
6372 stats.bShift = false;
6375 if (pdesc->Length <500)
6376 priv->stats.rxcrcerrmin++;
6377 else if (pdesc->Length >1000)
6378 priv->stats.rxcrcerrmax++;
6380 priv->stats.rxcrcerrmid++;
6384 prx_fwinfo_819x_pci pDrvInfo = NULL;
6385 struct sk_buff *new_skb = dev_alloc_skb(priv->rxbuffersize);
6387 if (unlikely(!new_skb)) {
6391 stats.RxDrvInfoSize = pdesc->RxDrvInfoSize;
6392 stats.RxBufShift = ((pdesc->Shift)&0x03);
6393 stats.Decrypted = !pdesc->SWDec;
6395 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
6396 pci_dma_sync_single_for_cpu(priv->pdev,
6398 pci_unmap_single(priv->pdev,
6400 *((dma_addr_t *)skb->cb),
6402 PCI_DMA_FROMDEVICE);
6403 skb_put(skb, pdesc->Length);
6404 pDrvInfo = (rx_fwinfo_819x_pci *)(skb->data + stats.RxBufShift);
6405 skb_reserve(skb, stats.RxDrvInfoSize + stats.RxBufShift);
6407 stats.rate = HwRateToMRate90((bool)pDrvInfo->RxHT, (u8)pDrvInfo->RxRate);
6408 stats.bShortPreamble = pDrvInfo->SPLCP;
6410 /* it is debug only. It should be disabled in released driver.
6411 * 2007.1.11 by Emily
6413 UpdateReceivedRateHistogramStatistics8190(dev, &stats);
6415 stats.bIsAMPDU = (pDrvInfo->PartAggr==1);
6416 stats.bFirstMPDU = (pDrvInfo->PartAggr==1) && (pDrvInfo->FirstAGGR==1);
6418 stats.TimeStampLow = pDrvInfo->TSFL;
6419 stats.TimeStampHigh = read_nic_dword(dev, TSFR+4);
6421 UpdateRxPktTimeStamp8190(dev, &stats);
6424 // Get Total offset of MPDU Frame Body
6426 if((stats.RxBufShift + stats.RxDrvInfoSize) > 0)
6429 stats.RxIs40MHzPacket = pDrvInfo->BW;
6432 TranslateRxSignalStuff819xpci(dev,skb, &stats, pdesc, pDrvInfo);
6435 if(pDrvInfo->FirstAGGR==1 || pDrvInfo->PartAggr == 1)
6436 RT_TRACE(COMP_RXDESC, "pDrvInfo->FirstAGGR = %d, pDrvInfo->PartAggr = %d\n",
6437 pDrvInfo->FirstAGGR, pDrvInfo->PartAggr);
6438 skb_trim(skb, skb->len - 4/*sCrcLng*/);
6439 /* rx packets statistics */
6440 ieee80211_hdr = (struct ieee80211_hdr_1addr *)skb->data;
6441 unicast_packet = false;
6443 if(is_broadcast_ether_addr(ieee80211_hdr->addr1)) {
6445 }else if(is_multicast_ether_addr(ieee80211_hdr->addr1)){
6448 /* unicast packet */
6449 unicast_packet = true;
6452 stats.packetlength = stats.Length-4;
6453 stats.fraglength = stats.packetlength;
6454 stats.fragoffset = 0;
6455 stats.ntotalfrag = 1;
6457 if(!ieee80211_rx(priv->ieee80211, skb, &stats)){
6458 dev_kfree_skb_any(skb);
6461 if(unicast_packet) {
6462 priv->stats.rxbytesunicast += skb->len;
6467 priv->rx_buf[priv->rx_idx] = skb;
6468 *((dma_addr_t *) skb->cb) = pci_map_single(priv->pdev, skb->tail, priv->rxbuffersize, PCI_DMA_FROMDEVICE);
6469 // *((dma_addr_t *) skb->cb) = pci_map_single(priv->pdev, skb_tail_pointer(skb), priv->rxbuffersize, PCI_DMA_FROMDEVICE);
6474 pdesc->BufferAddress = cpu_to_le32(*((dma_addr_t *)skb->cb));
6476 pdesc->Length = priv->rxbuffersize;
6477 if (priv->rx_idx == priv->rxringcount-1)
6479 priv->rx_idx = (priv->rx_idx + 1) % priv->rxringcount;
6484 void rtl8192_irq_rx_tasklet(struct r8192_priv *priv)
6486 rtl8192_rx(priv->ieee80211->dev);
6488 write_nic_dword(priv->ieee80211->dev, INTA_MASK,read_nic_dword(priv->ieee80211->dev, INTA_MASK) | IMR_RDU);
6491 static const struct net_device_ops rtl8192_netdev_ops = {
6492 .ndo_open = rtl8192_open,
6493 .ndo_stop = rtl8192_close,
6494 /* .ndo_get_stats = rtl8192_stats, */
6495 .ndo_tx_timeout = tx_timeout,
6496 .ndo_do_ioctl = rtl8192_ioctl,
6497 .ndo_set_multicast_list = r8192_set_multicast,
6498 .ndo_set_mac_address = r8192_set_mac_adr,
6499 .ndo_start_xmit = ieee80211_xmit,
6502 /****************************************************************************
6503 ---------------------------- PCI_STUFF---------------------------
6504 *****************************************************************************/
6506 static int __devinit rtl8192_pci_probe(struct pci_dev *pdev,
6507 const struct pci_device_id *id)
6509 unsigned long ioaddr = 0;
6510 struct net_device *dev = NULL;
6511 struct r8192_priv *priv= NULL;
6514 #ifdef CONFIG_RTL8192_IO_MAP
6515 unsigned long pio_start, pio_len, pio_flags;
6517 unsigned long pmem_start, pmem_len, pmem_flags;
6518 #endif //end #ifdef RTL_IO_MAP
6520 RT_TRACE(COMP_INIT,"Configuring chip resources");
6522 if( pci_enable_device (pdev) ){
6523 RT_TRACE(COMP_ERR,"Failed to enable PCI device");
6527 pci_set_master(pdev);
6528 //pci_set_wmi(pdev);
6529 pci_set_dma_mask(pdev, 0xffffff00ULL);
6530 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
6531 pci_set_consistent_dma_mask(pdev,0xffffff00ULL);
6533 dev = alloc_ieee80211(sizeof(struct r8192_priv));
6537 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
6538 SET_MODULE_OWNER(dev);
6541 pci_set_drvdata(pdev, dev);
6542 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
6543 SET_NETDEV_DEV(dev, &pdev->dev);
6545 priv = ieee80211_priv(dev);
6546 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
6547 priv->ieee80211 = netdev_priv(dev);
6549 priv->ieee80211 = (struct ieee80211_device *)dev->priv;
6552 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
6553 if((pdev->subsystem_vendor == PCI_VENDOR_ID_DLINK)&&(pdev->subsystem_device == 0x3304)){
6554 priv->ieee80211->bSupportRemoteWakeUp = 1;
6558 priv->ieee80211->bSupportRemoteWakeUp = 0;
6561 #ifdef CONFIG_RTL8192_IO_MAP
6563 pio_start = (unsigned long)pci_resource_start (pdev, 0);
6564 pio_len = (unsigned long)pci_resource_len (pdev, 0);
6565 pio_flags = (unsigned long)pci_resource_flags (pdev, 0);
6567 if (!(pio_flags & IORESOURCE_IO)) {
6568 RT_TRACE(COMP_ERR,"region #0 not a PIO resource, aborting");
6572 //DMESG("IO space @ 0x%08lx", pio_start );
6573 if( ! request_region( pio_start, pio_len, RTL819xE_MODULE_NAME ) ){
6574 RT_TRACE(COMP_ERR,"request_region failed!");
6579 dev->base_addr = ioaddr; // device I/O address
6583 pmem_start = pci_resource_start(pdev, 1);
6584 pmem_len = pci_resource_len(pdev, 1);
6585 pmem_flags = pci_resource_flags (pdev, 1);
6587 if (!(pmem_flags & IORESOURCE_MEM)) {
6588 RT_TRACE(COMP_ERR,"region #1 not a MMIO resource, aborting");
6592 //DMESG("Memory mapped space @ 0x%08lx ", pmem_start);
6593 if( ! request_mem_region(pmem_start, pmem_len, RTL819xE_MODULE_NAME)) {
6594 RT_TRACE(COMP_ERR,"request_mem_region failed!");
6599 ioaddr = (unsigned long)ioremap_nocache( pmem_start, pmem_len);
6600 if( ioaddr == (unsigned long)NULL ){
6601 RT_TRACE(COMP_ERR,"ioremap failed!");
6602 // release_mem_region( pmem_start, pmem_len );
6606 dev->mem_start = ioaddr; // shared mem start
6607 dev->mem_end = ioaddr + pci_resource_len(pdev, 0); // shared mem end
6609 #endif //end #ifdef RTL_IO_MAP
6611 /* We disable the RETRY_TIMEOUT register (0x41) to keep
6612 * PCI Tx retries from interfering with C3 CPU state */
6613 pci_write_config_byte(pdev, 0x41, 0x00);
6616 pci_read_config_byte(pdev, 0x05, &unit);
6617 pci_write_config_byte(pdev, 0x05, unit & (~0x04));
6619 dev->irq = pdev->irq;
6622 dev->netdev_ops = &rtl8192_netdev_ops;
6624 dev->open = rtl8192_open;
6625 dev->stop = rtl8192_close;
6626 //dev->hard_start_xmit = rtl8192_8023_hard_start_xmit;
6627 dev->tx_timeout = tx_timeout;
6628 //dev->wireless_handlers = &r8192_wx_handlers_def;
6629 dev->do_ioctl = rtl8192_ioctl;
6630 dev->set_multicast_list = r8192_set_multicast;
6631 dev->set_mac_address = r8192_set_mac_adr;
6634 //DMESG("Oops: i'm coming\n");
6635 #if WIRELESS_EXT >= 12
6636 #if WIRELESS_EXT < 17
6637 dev->get_wireless_stats = r8192_get_wireless_stats;
6639 dev->wireless_handlers = (struct iw_handler_def *) &r8192_wx_handlers_def;
6641 //dev->get_wireless_stats = r8192_get_wireless_stats;
6642 dev->type=ARPHRD_ETHER;
6644 dev->watchdog_timeo = HZ*3; //modified by john, 0805
6646 if (dev_alloc_name(dev, ifname) < 0){
6647 RT_TRACE(COMP_INIT, "Oops: devname already taken! Trying wlan%%d...\n");
6649 dev_alloc_name(dev, ifname);
6652 RT_TRACE(COMP_INIT, "Driver probe completed1\n");
6653 if(rtl8192_init(dev)!=0){
6654 RT_TRACE(COMP_ERR, "Initialization failed");
6658 netif_carrier_off(dev);
6659 netif_stop_queue(dev);
6661 register_netdev(dev);
6662 RT_TRACE(COMP_INIT, "dev name=======> %s\n",dev->name);
6663 rtl8192_proc_init_one(dev);
6666 RT_TRACE(COMP_INIT, "Driver probe completed\n");
6667 //#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
6675 #ifdef CONFIG_RTL8180_IO_MAP
6677 if( dev->base_addr != 0 ){
6679 release_region(dev->base_addr,
6680 pci_resource_len(pdev, 0) );
6683 if( dev->mem_start != (unsigned long)NULL ){
6684 iounmap( (void *)dev->mem_start );
6685 release_mem_region( pci_resource_start(pdev, 1),
6686 pci_resource_len(pdev, 1) );
6688 #endif //end #ifdef RTL_IO_MAP
6694 free_irq(dev->irq, dev);
6697 free_ieee80211(dev);
6700 pci_disable_device(pdev);
6702 DMESG("wlan driver load failed\n");
6703 pci_set_drvdata(pdev, NULL);
6708 /* detach all the work and timer structure declared or inititialized
6709 * in r8192_init function.
6711 void rtl8192_cancel_deferred_work(struct r8192_priv* priv)
6713 /* call cancel_work_sync instead of cancel_delayed_work if and only if Linux_version_code
6714 * is or is newer than 2.6.20 and work structure is defined to be struct work_struct.
6715 * Otherwise call cancel_delayed_work is enough.
6716 * FIXME (2.6.20 shoud 2.6.22, work_struct shoud not cancel)
6718 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
6719 cancel_delayed_work(&priv->watch_dog_wq);
6720 cancel_delayed_work(&priv->update_beacon_wq);
6721 cancel_delayed_work(&priv->ieee80211->hw_wakeup_wq);
6722 cancel_delayed_work(&priv->ieee80211->hw_sleep_wq);
6724 cancel_delayed_work(&priv->gpio_change_rf_wq);
6727 #if LINUX_VERSION_CODE >=KERNEL_VERSION(2,6,22)
6728 cancel_work_sync(&priv->reset_wq);
6729 cancel_work_sync(&priv->qos_activate);
6730 //cancel_work_sync(&priv->SetBWModeWorkItem);
6731 //cancel_work_sync(&priv->SwChnlWorkItem);
6733 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
6734 cancel_delayed_work(&priv->reset_wq);
6735 cancel_delayed_work(&priv->qos_activate);
6736 //cancel_delayed_work(&priv->SetBWModeWorkItem);
6737 //cancel_delayed_work(&priv->SwChnlWorkItem);
6744 static void __devexit rtl8192_pci_disconnect(struct pci_dev *pdev)
6746 struct net_device *dev = pci_get_drvdata(pdev);
6747 struct r8192_priv *priv ;
6751 unregister_netdev(dev);
6753 priv=ieee80211_priv(dev);
6755 rtl8192_proc_remove_one(dev);
6758 if (priv->pFirmware)
6760 vfree(priv->pFirmware);
6761 priv->pFirmware = NULL;
6763 // priv->rf_close(dev);
6764 // rtl8192_usb_deleteendpoints(dev);
6765 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
6766 destroy_workqueue(priv->priv_wq);
6768 /* redundant with rtl8192_down */
6769 // rtl8192_irq_disable(dev);
6770 // rtl8192_reset(dev);
6774 /* free tx/rx rings */
6775 rtl8192_free_rx_ring(dev);
6776 for (i = 0; i < MAX_TX_QUEUE_COUNT; i++) {
6777 rtl8192_free_tx_ring(dev, i);
6782 printk("Freeing irq %d\n",dev->irq);
6783 free_irq(dev->irq, dev);
6790 // free_beacon_desc_ring(dev,priv->txbeaconcount);
6792 #ifdef CONFIG_RTL8180_IO_MAP
6794 if( dev->base_addr != 0 ){
6796 release_region(dev->base_addr,
6797 pci_resource_len(pdev, 0) );
6800 if( dev->mem_start != (unsigned long)NULL ){
6801 iounmap( (void *)dev->mem_start );
6802 release_mem_region( pci_resource_start(pdev, 1),
6803 pci_resource_len(pdev, 1) );
6805 #endif /*end #ifdef RTL_IO_MAP*/
6806 free_ieee80211(dev);
6810 pci_disable_device(pdev);
6811 RT_TRACE(COMP_DOWN, "wlan driver removed\n");
6814 extern int ieee80211_init(void);
6815 extern void ieee80211_exit(void);
6817 static int __init rtl8192_pci_module_init(void)
6821 retval = ieee80211_init();
6825 printk(KERN_INFO "\nLinux kernel driver for RTL8192 based WLAN cards\n");
6826 printk(KERN_INFO "Copyright (c) 2007-2008, Realsil Wlan\n");
6827 RT_TRACE(COMP_INIT, "Initializing module");
6828 RT_TRACE(COMP_INIT, "Wireless extensions version %d", WIRELESS_EXT);
6829 rtl8192_proc_module_init();
6830 #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22))
6831 if(0!=pci_module_init(&rtl8192_pci_driver))
6833 if(0!=pci_register_driver(&rtl8192_pci_driver))
6836 DMESG("No device found");
6837 /*pci_unregister_driver (&rtl8192_pci_driver);*/
6844 static void __exit rtl8192_pci_module_exit(void)
6846 pci_unregister_driver(&rtl8192_pci_driver);
6848 RT_TRACE(COMP_DOWN, "Exiting");
6849 rtl8192_proc_module_remove();
6853 //warning message WB
6854 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18)
6855 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
6856 void rtl8192_interrupt(int irq, void *netdev, struct pt_regs *regs)
6858 irqreturn_t rtl8192_interrupt(int irq, void *netdev, struct pt_regs *regs)
6861 irqreturn_t rtl8192_interrupt(int irq, void *netdev)
6864 struct net_device *dev = (struct net_device *) netdev;
6865 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
6866 unsigned long flags;
6868 /* We should return IRQ_NONE, but for now let me keep this */
6869 if(priv->irq_enabled == 0){
6870 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
6877 spin_lock_irqsave(&priv->irq_th_lock,flags);
6881 inta = read_nic_dword(dev, ISR);// & priv->IntrMask;
6882 write_nic_dword(dev,ISR,inta); // reset int situation
6884 priv->stats.shints++;
6885 //DMESG("Enter interrupt, ISR value = 0x%08x", inta);
6887 spin_unlock_irqrestore(&priv->irq_th_lock,flags);
6888 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
6894 most probably we can safely return IRQ_NONE,
6895 but for now is better to avoid problems
6901 spin_unlock_irqrestore(&priv->irq_th_lock,flags);
6902 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
6911 DMESG("NIC irq %x",inta);
6913 //priv->irqpending = inta;
6916 if(!netif_running(dev)) {
6917 spin_unlock_irqrestore(&priv->irq_th_lock,flags);
6918 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
6925 if(inta & IMR_TIMEOUT0){
6926 // write_nic_dword(dev, TimerInt, 0);
6927 //DMESG("=================>waking up");
6928 // rtl8180_hw_wakeup(dev);
6931 if(inta & IMR_TBDOK){
6932 RT_TRACE(COMP_INTR, "beacon ok interrupt!\n");
6933 rtl8192_tx_isr(dev, BEACON_QUEUE);
6934 priv->stats.txbeaconokint++;
6937 if(inta & IMR_TBDER){
6938 RT_TRACE(COMP_INTR, "beacon ok interrupt!\n");
6939 rtl8192_tx_isr(dev, BEACON_QUEUE);
6940 priv->stats.txbeaconerr++;
6943 if(inta & IMR_MGNTDOK ) {
6944 RT_TRACE(COMP_INTR, "Manage ok interrupt!\n");
6945 priv->stats.txmanageokint++;
6946 rtl8192_tx_isr(dev,MGNT_QUEUE);
6950 if(inta & IMR_COMDOK)
6952 priv->stats.txcmdpktokint++;
6953 rtl8192_tx_isr(dev,TXCMD_QUEUE);
6958 DMESG("Frame arrived !");
6960 priv->stats.rxint++;
6961 tasklet_schedule(&priv->irq_rx_tasklet);
6964 if(inta & IMR_BcnInt) {
6965 RT_TRACE(COMP_INTR, "prepare beacon for interrupt!\n");
6966 tasklet_schedule(&priv->irq_prepare_beacon_tasklet);
6970 RT_TRACE(COMP_INTR, "rx descriptor unavailable!\n");
6971 priv->stats.rxrdu++;
6972 /* reset int situation */
6973 write_nic_dword(dev,INTA_MASK,read_nic_dword(dev, INTA_MASK) & ~IMR_RDU);
6974 tasklet_schedule(&priv->irq_rx_tasklet);
6977 if(inta & IMR_RXFOVW){
6978 RT_TRACE(COMP_INTR, "rx overflow !\n");
6979 priv->stats.rxoverflow++;
6980 tasklet_schedule(&priv->irq_rx_tasklet);
6983 if(inta & IMR_TXFOVW) priv->stats.txoverflow++;
6985 if(inta & IMR_BKDOK){
6986 RT_TRACE(COMP_INTR, "BK Tx OK interrupt!\n");
6987 priv->stats.txbkokint++;
6988 priv->ieee80211->LinkDetectInfo.NumTxOkInPeriod++;
6989 rtl8192_tx_isr(dev,BK_QUEUE);
6990 rtl8192_try_wake_queue(dev, BK_QUEUE);
6993 if(inta & IMR_BEDOK){
6994 RT_TRACE(COMP_INTR, "BE TX OK interrupt!\n");
6995 priv->stats.txbeokint++;
6996 priv->ieee80211->LinkDetectInfo.NumTxOkInPeriod++;
6997 rtl8192_tx_isr(dev,BE_QUEUE);
6998 rtl8192_try_wake_queue(dev, BE_QUEUE);
7001 if(inta & IMR_VIDOK){
7002 RT_TRACE(COMP_INTR, "VI TX OK interrupt!\n");
7003 priv->stats.txviokint++;
7004 priv->ieee80211->LinkDetectInfo.NumTxOkInPeriod++;
7005 rtl8192_tx_isr(dev,VI_QUEUE);
7006 rtl8192_try_wake_queue(dev, VI_QUEUE);
7009 if(inta & IMR_VODOK){
7010 priv->stats.txvookint++;
7011 priv->ieee80211->LinkDetectInfo.NumTxOkInPeriod++;
7012 rtl8192_tx_isr(dev,VO_QUEUE);
7013 rtl8192_try_wake_queue(dev, VO_QUEUE);
7016 force_pci_posting(dev);
7017 spin_unlock_irqrestore(&priv->irq_th_lock,flags);
7019 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
7026 void rtl8192_try_wake_queue(struct net_device *dev, int pri)
7029 unsigned long flags;
7031 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
7033 spin_lock_irqsave(&priv->tx_lock,flags);
7034 enough_desc = check_nic_enough_desc(dev,pri);
7035 spin_unlock_irqrestore(&priv->tx_lock,flags);
7038 ieee80211_wake_queue(priv->ieee80211);
7043 void EnableHWSecurityConfig8192(struct net_device *dev)
7045 u8 SECR_value = 0x0;
7046 // struct ieee80211_device* ieee1 = container_of(&dev, struct ieee80211_device, dev);
7047 //printk("==>ieee1:%p, dev:%p\n", ieee1, dev);
7048 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
7049 struct ieee80211_device* ieee = priv->ieee80211;
7050 //printk("==>ieee:%p, dev:%p\n", ieee, dev);
7051 SECR_value = SCR_TxEncEnable | SCR_RxDecEnable;
7053 if (((KEY_TYPE_WEP40 == ieee->pairwise_key_type) || (KEY_TYPE_WEP104 == ieee->pairwise_key_type)) && (priv->ieee80211->auth_mode != 2))
7055 SECR_value |= SCR_RxUseDK;
7056 SECR_value |= SCR_TxUseDK;
7058 else if ((ieee->iw_mode == IW_MODE_ADHOC) && (ieee->pairwise_key_type & (KEY_TYPE_CCMP | KEY_TYPE_TKIP)))
7060 SECR_value |= SCR_RxUseDK;
7061 SECR_value |= SCR_TxUseDK;
7066 //add HWSec active enable here.
7067 //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
7068 ieee->hwsec_active = 1;
7070 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
7072 ieee->hwsec_active = 0;
7073 SECR_value &= ~SCR_RxDecEnable;
7076 RT_TRACE(COMP_SEC,"%s:, hwsec:%d, pairwise_key:%d, SECR_value:%x\n", __FUNCTION__, \
7077 ieee->hwsec_active, ieee->pairwise_key_type, SECR_value);
7079 write_nic_byte(dev, SECR, SECR_value);//SECR_value | SCR_UseDK );
7083 #define TOTAL_CAM_ENTRY 32
7084 //#define CAM_CONTENT_COUNT 8
7085 void setKey( struct net_device *dev,
7093 u32 TargetCommand = 0;
7094 u32 TargetContent = 0;
7098 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
7099 RT_RF_POWER_STATE rtState;
7100 rtState = priv->ieee80211->eRFPowerState;
7101 if(priv->ieee80211->PowerSaveControl.bInactivePs){
7102 if(rtState == eRfOff){
7103 if(priv->ieee80211->RfOffReason > RF_CHANGE_BY_IPS)
7105 RT_TRACE(COMP_ERR, "%s(): RF is OFF.\n",__FUNCTION__);
7114 priv->ieee80211->is_set_key = true;
7116 if (EntryNo >= TOTAL_CAM_ENTRY)
7117 RT_TRACE(COMP_ERR, "cam entry exceeds in setKey()\n");
7119 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));
7122 usConfig |= BIT15 | (KeyType<<2);
7124 usConfig |= BIT15 | (KeyType<<2) | KeyIndex;
7125 // usConfig |= BIT15 | (KeyType<<2) | (DefaultKey<<5) | KeyIndex;
7128 for(i=0 ; i<CAM_CONTENT_COUNT; i++){
7129 TargetCommand = i+CAM_CONTENT_COUNT*EntryNo;
7130 TargetCommand |= BIT31|BIT16;
7132 if(i==0){//MAC|Config
7133 TargetContent = (u32)(*(MacAddr+0)) << 16|
7134 (u32)(*(MacAddr+1)) << 24|
7137 write_nic_dword(dev, WCAMI, TargetContent);
7138 write_nic_dword(dev, RWCAM, TargetCommand);
7139 // printk("setkey cam =%8x\n", read_cam(dev, i+6*EntryNo));
7142 TargetContent = (u32)(*(MacAddr+2)) |
7143 (u32)(*(MacAddr+3)) << 8|
7144 (u32)(*(MacAddr+4)) << 16|
7145 (u32)(*(MacAddr+5)) << 24;
7146 write_nic_dword(dev, WCAMI, TargetContent);
7147 write_nic_dword(dev, RWCAM, TargetCommand);
7149 else { //Key Material
7150 if(KeyContent != NULL)
7152 write_nic_dword(dev, WCAMI, (u32)(*(KeyContent+i-2)) );
7153 write_nic_dword(dev, RWCAM, TargetCommand);
7157 RT_TRACE(COMP_SEC,"=========>after set key, usconfig:%x\n", usConfig);
7158 // CAM_read_entry(dev, 0);
7160 // This function seems not ready! WB
7161 void CamPrintDbgReg(struct net_device* dev)
7163 unsigned long rvalue;
7164 unsigned char ucValue;
7165 write_nic_dword(dev, DCAM, 0x80000000);
7167 rvalue = read_nic_dword(dev, DCAM); //delay_ms(40);
7168 RT_TRACE(COMP_SEC, " TX CAM=%8lX ",rvalue);
7169 if((rvalue & 0x40000000) != 0x4000000)
7170 RT_TRACE(COMP_SEC, "-->TX Key Not Found ");
7172 write_nic_dword(dev, DCAM, 0x00000000); //delay_ms(40);
7173 rvalue = read_nic_dword(dev, DCAM); //delay_ms(40);
7174 RT_TRACE(COMP_SEC, "RX CAM=%8lX ",rvalue);
7175 if((rvalue & 0x40000000) != 0x4000000)
7176 RT_TRACE(COMP_SEC, "-->CAM Key Not Found ");
7177 ucValue = read_nic_byte(dev, SECR);
7178 RT_TRACE(COMP_SEC, "WPA_Config=%x \n",ucValue);
7182 /***************************************************************************
7183 ------------------- module init / exit stubs ----------------
7184 ****************************************************************************/
7185 module_init(rtl8192_pci_module_init);
7186 module_exit(rtl8192_pci_module_exit);