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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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];
1168 rtl819xusb_rx_command_packet(
1169 struct net_device *dev,
1170 struct ieee80211_rx_stats *pstats
1175 //RT_TRACE(COMP_RECV, DBG_TRACE, ("---> RxCommandPacketHandle819xUsb()\n"));
1177 RT_TRACE(COMP_EVENTS, "---->rtl819xusb_rx_command_packet()\n");
1178 status = cmpk_message_handle_rx(dev, pstats);
1181 DMESG("rxcommandpackethandle819xusb: It is a command packet\n");
1185 //RT_TRACE(COMP_RECV, DBG_TRACE, ("RxCommandPacketHandle819xUsb: It is not a command packet\n"));
1188 //RT_TRACE(COMP_RECV, DBG_TRACE, ("<--- RxCommandPacketHandle819xUsb()\n"));
1193 void rtl8192_tx_queues_stop(struct net_device *dev)
1195 //struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1196 u8 dma_poll_mask = (1<<TX_DMA_STOP_LOWPRIORITY_SHIFT);
1197 dma_poll_mask |= (1<<TX_DMA_STOP_HIPRIORITY_SHIFT);
1198 dma_poll_mask |= (1<<TX_DMA_STOP_NORMPRIORITY_SHIFT);
1199 dma_poll_mask |= (1<<TX_DMA_STOP_BEACON_SHIFT);
1201 rtl8192_set_mode(dev,EPROM_CMD_CONFIG);
1202 write_nic_byte(dev,TX_DMA_POLLING,dma_poll_mask);
1203 rtl8192_set_mode(dev,EPROM_CMD_NORMAL);
1207 void rtl8192_data_hard_stop(struct net_device *dev)
1211 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1212 priv->dma_poll_mask |= (1<<TX_DMA_STOP_LOWPRIORITY_SHIFT);
1213 rtl8192_set_mode(dev,EPROM_CMD_CONFIG);
1214 write_nic_byte(dev,TX_DMA_POLLING,priv->dma_poll_mask);
1215 rtl8192_set_mode(dev,EPROM_CMD_NORMAL);
1220 void rtl8192_data_hard_resume(struct net_device *dev)
1224 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1225 priv->dma_poll_mask &= ~(1<<TX_DMA_STOP_LOWPRIORITY_SHIFT);
1226 rtl8192_set_mode(dev,EPROM_CMD_CONFIG);
1227 write_nic_byte(dev,TX_DMA_POLLING,priv->dma_poll_mask);
1228 rtl8192_set_mode(dev,EPROM_CMD_NORMAL);
1232 /* this function TX data frames when the ieee80211 stack requires this.
1233 * It checks also if we need to stop the ieee tx queue, eventually do it
1235 void rtl8192_hard_data_xmit(struct sk_buff *skb, struct net_device *dev, int rate)
1237 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1239 //unsigned long flags;
1240 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1241 u8 queue_index = tcb_desc->queue_index;
1242 /* shall not be referred by command packet */
1243 assert(queue_index != TXCMD_QUEUE);
1245 //spin_lock_irqsave(&priv->tx_lock,flags);
1247 memcpy((unsigned char *)(skb->cb),&dev,sizeof(dev));
1249 tcb_desc->RATRIndex = 7;
1250 tcb_desc->bTxDisableRateFallBack = 1;
1251 tcb_desc->bTxUseDriverAssingedRate = 1;
1252 tcb_desc->bTxEnableFwCalcDur = 1;
1254 skb_push(skb, priv->ieee80211->tx_headroom);
1255 ret = rtl8192_tx(dev, skb);
1261 if(queue_index!=MGNT_QUEUE) {
1262 priv->ieee80211->stats.tx_bytes+=(skb->len - priv->ieee80211->tx_headroom);
1263 priv->ieee80211->stats.tx_packets++;
1266 //spin_unlock_irqrestore(&priv->tx_lock,flags);
1272 /* This is a rough attempt to TX a frame
1273 * This is called by the ieee 80211 stack to TX management frames.
1274 * If the ring is full packet are dropped (for data frame the queue
1275 * is stopped before this can happen).
1277 int rtl8192_hard_start_xmit(struct sk_buff *skb,struct net_device *dev)
1279 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1283 //unsigned long flags;
1284 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1285 u8 queue_index = tcb_desc->queue_index;
1288 //spin_lock_irqsave(&priv->tx_lock,flags);
1290 memcpy((unsigned char *)(skb->cb),&dev,sizeof(dev));
1291 if(queue_index == TXCMD_QUEUE) {
1292 // skb_push(skb, USB_HWDESC_HEADER_LEN);
1293 rtl819xE_tx_cmd(dev, skb);
1295 //spin_unlock_irqrestore(&priv->tx_lock,flags);
1298 // RT_TRACE(COMP_SEND, "To send management packet\n");
1299 tcb_desc->RATRIndex = 7;
1300 tcb_desc->bTxDisableRateFallBack = 1;
1301 tcb_desc->bTxUseDriverAssingedRate = 1;
1302 tcb_desc->bTxEnableFwCalcDur = 1;
1303 skb_push(skb, priv->ieee80211->tx_headroom);
1304 ret = rtl8192_tx(dev, skb);
1310 // priv->ieee80211->stats.tx_bytes+=skb->len;
1311 // priv->ieee80211->stats.tx_packets++;
1313 //spin_unlock_irqrestore(&priv->tx_lock,flags);
1320 void rtl8192_try_wake_queue(struct net_device *dev, int pri);
1322 void rtl8192_tx_isr(struct net_device *dev, int prio)
1324 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1326 struct rtl8192_tx_ring *ring = &priv->tx_ring[prio];
1328 while (skb_queue_len(&ring->queue)) {
1329 tx_desc_819x_pci *entry = &ring->desc[ring->idx];
1330 struct sk_buff *skb;
1332 /* beacon packet will only use the first descriptor defautly,
1333 * and the OWN may not be cleared by the hardware
1335 if(prio != BEACON_QUEUE) {
1338 ring->idx = (ring->idx + 1) % ring->entries;
1341 skb = __skb_dequeue(&ring->queue);
1342 pci_unmap_single(priv->pdev, le32_to_cpu(entry->TxBuffAddr),
1343 skb->len, PCI_DMA_TODEVICE);
1347 if (prio == MGNT_QUEUE){
1348 if (priv->ieee80211->ack_tx_to_ieee){
1349 if (rtl8192_is_tx_queue_empty(dev)){
1350 priv->ieee80211->ack_tx_to_ieee = 0;
1351 ieee80211_ps_tx_ack(priv->ieee80211, 1);
1356 if(prio != BEACON_QUEUE) {
1357 /* try to deal with the pending packets */
1358 tasklet_schedule(&priv->irq_tx_tasklet);
1363 void rtl8192_stop_beacon(struct net_device *dev)
1365 //rtl8192_beacon_disable(dev);
1368 void rtl8192_config_rate(struct net_device* dev, u16* rate_config)
1370 struct r8192_priv *priv = ieee80211_priv(dev);
1371 struct ieee80211_network *net;
1372 u8 i=0, basic_rate = 0;
1373 net = & priv->ieee80211->current_network;
1375 for (i=0; i<net->rates_len; i++)
1377 basic_rate = net->rates[i]&0x7f;
1380 case MGN_1M: *rate_config |= RRSR_1M; break;
1381 case MGN_2M: *rate_config |= RRSR_2M; break;
1382 case MGN_5_5M: *rate_config |= RRSR_5_5M; break;
1383 case MGN_11M: *rate_config |= RRSR_11M; break;
1384 case MGN_6M: *rate_config |= RRSR_6M; break;
1385 case MGN_9M: *rate_config |= RRSR_9M; break;
1386 case MGN_12M: *rate_config |= RRSR_12M; break;
1387 case MGN_18M: *rate_config |= RRSR_18M; break;
1388 case MGN_24M: *rate_config |= RRSR_24M; break;
1389 case MGN_36M: *rate_config |= RRSR_36M; break;
1390 case MGN_48M: *rate_config |= RRSR_48M; break;
1391 case MGN_54M: *rate_config |= RRSR_54M; break;
1394 for (i=0; i<net->rates_ex_len; i++)
1396 basic_rate = net->rates_ex[i]&0x7f;
1399 case MGN_1M: *rate_config |= RRSR_1M; break;
1400 case MGN_2M: *rate_config |= RRSR_2M; break;
1401 case MGN_5_5M: *rate_config |= RRSR_5_5M; break;
1402 case MGN_11M: *rate_config |= RRSR_11M; break;
1403 case MGN_6M: *rate_config |= RRSR_6M; break;
1404 case MGN_9M: *rate_config |= RRSR_9M; break;
1405 case MGN_12M: *rate_config |= RRSR_12M; break;
1406 case MGN_18M: *rate_config |= RRSR_18M; break;
1407 case MGN_24M: *rate_config |= RRSR_24M; break;
1408 case MGN_36M: *rate_config |= RRSR_36M; break;
1409 case MGN_48M: *rate_config |= RRSR_48M; break;
1410 case MGN_54M: *rate_config |= RRSR_54M; break;
1416 #define SHORT_SLOT_TIME 9
1417 #define NON_SHORT_SLOT_TIME 20
1419 void rtl8192_update_cap(struct net_device* dev, u16 cap)
1422 struct r8192_priv *priv = ieee80211_priv(dev);
1423 struct ieee80211_network *net = &priv->ieee80211->current_network;
1424 priv->short_preamble = cap & WLAN_CAPABILITY_SHORT_PREAMBLE;
1425 tmp = priv->basic_rate;
1426 if (priv->short_preamble)
1427 tmp |= BRSR_AckShortPmb;
1428 write_nic_dword(dev, RRSR, tmp);
1430 if (net->mode & (IEEE_G|IEEE_N_24G))
1433 if ((cap & WLAN_CAPABILITY_SHORT_SLOT)&&(!priv->ieee80211->pHTInfo->bCurrentRT2RTLongSlotTime))
1435 slot_time = SHORT_SLOT_TIME;
1437 else //long slot time
1438 slot_time = NON_SHORT_SLOT_TIME;
1439 priv->slot_time = slot_time;
1440 write_nic_byte(dev, SLOT_TIME, slot_time);
1444 void rtl8192_net_update(struct net_device *dev)
1447 struct r8192_priv *priv = ieee80211_priv(dev);
1448 struct ieee80211_network *net;
1449 u16 BcnTimeCfg = 0, BcnCW = 6, BcnIFS = 0xf;
1450 u16 rate_config = 0;
1451 net = &priv->ieee80211->current_network;
1452 //update Basic rate: RR, BRSR
1453 rtl8192_config_rate(dev, &rate_config);
1454 // 2007.01.16, by Emily
1455 // Select RRSR (in Legacy-OFDM and CCK)
1456 // For 8190, we select only 24M, 12M, 6M, 11M, 5.5M, 2M, and 1M from the Basic rate.
1457 // We do not use other rates.
1458 priv->basic_rate = rate_config &= 0x15f;
1460 write_nic_dword(dev,BSSIDR,((u32*)net->bssid)[0]);
1461 write_nic_word(dev,BSSIDR+4,((u16*)net->bssid)[2]);
1464 rtl8192_update_msr(dev);
1468 // rtl8192_update_cap(dev, net->capability);
1469 if (priv->ieee80211->iw_mode == IW_MODE_ADHOC)
1471 write_nic_word(dev, ATIMWND, 2);
1472 write_nic_word(dev, BCN_DMATIME, 256);
1473 write_nic_word(dev, BCN_INTERVAL, net->beacon_interval);
1474 // write_nic_word(dev, BcnIntTime, 100);
1475 //BIT15 of BCN_DRV_EARLY_INT will indicate whether software beacon or hw beacon is applied.
1476 write_nic_word(dev, BCN_DRV_EARLY_INT, 10);
1477 write_nic_byte(dev, BCN_ERR_THRESH, 100);
1479 BcnTimeCfg |= (BcnCW<<BCN_TCFG_CW_SHIFT);
1480 // TODO: BcnIFS may required to be changed on ASIC
1481 BcnTimeCfg |= BcnIFS<<BCN_TCFG_IFS;
1483 write_nic_word(dev, BCN_TCFG, BcnTimeCfg);
1489 inline u8 rtl8192_IsWirelessBMode(u16 rate)
1491 if( ((rate <= 110) && (rate != 60) && (rate != 90)) || (rate == 220) )
1496 u16 N_DBPSOfRate(u16 DataRate);
1501 u8 bManagementFrame,
1509 if( rtl8192_IsWirelessBMode(DataRate) )
1511 if( bManagementFrame || !bShortPreamble || DataRate == 10 )
1513 FrameTime = (u16)(144+48+(FrameLength*8/(DataRate/10)));
1517 FrameTime = (u16)(72+24+(FrameLength*8/(DataRate/10)));
1519 if( ( FrameLength*8 % (DataRate/10) ) != 0 ) //Get the Ceilling
1521 } else { //802.11g DSSS-OFDM PLCP length field calculation.
1522 N_DBPS = N_DBPSOfRate(DataRate);
1523 Ceiling = (16 + 8*FrameLength + 6) / N_DBPS
1524 + (((16 + 8*FrameLength + 6) % N_DBPS) ? 1 : 0);
1525 FrameTime = (u16)(16 + 4 + 4*Ceiling + 6);
1530 u16 N_DBPSOfRate(u16 DataRate)
1575 unsigned int txqueue2outpipe(unsigned int tx_queue) {
1576 unsigned int outpipe = 0x04;
1595 case HCCA_QUEUE://EP8
1599 case BEACON_QUEUE://EPA
1603 case HIGH_QUEUE://EPB
1607 case MGNT_QUEUE://EPC
1611 case TXCMD_QUEUE://EPD
1616 printk("Unknow queue index!\n");
1623 void rtl819xE_tx_cmd(struct net_device *dev, struct sk_buff *skb)
1625 struct r8192_priv *priv = ieee80211_priv(dev);
1626 struct rtl8192_tx_ring *ring;
1627 tx_desc_819x_pci *entry;
1631 unsigned long flags;
1633 ring = &priv->tx_ring[TXCMD_QUEUE];
1634 mapping = pci_map_single(priv->pdev, skb->data, skb->len, PCI_DMA_TODEVICE);
1636 spin_lock_irqsave(&priv->irq_th_lock,flags);
1637 idx = (ring->idx + skb_queue_len(&ring->queue)) % ring->entries;
1638 entry = &ring->desc[idx];
1640 tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1642 entry->LINIP = tcb_desc->bLastIniPkt;
1643 entry->FirstSeg = 1;//first segment
1644 entry->LastSeg = 1; //last segment
1645 if(tcb_desc->bCmdOrInit == DESC_PACKET_TYPE_INIT) {
1646 entry->CmdInit = DESC_PACKET_TYPE_INIT;
1648 entry->CmdInit = DESC_PACKET_TYPE_NORMAL;
1649 entry->Offset = sizeof(TX_FWINFO_8190PCI) + 8;
1650 entry->PktSize = (u16)(tcb_desc->pkt_size + entry->Offset);
1651 entry->QueueSelect = QSLT_CMD;
1652 entry->TxFWInfoSize = 0x08;
1653 entry->RATid = (u8)DESC_PACKET_TYPE_INIT;
1655 entry->TxBufferSize = skb->len;
1656 entry->TxBuffAddr = cpu_to_le32(mapping);
1659 #ifdef JOHN_DUMP_TXDESC
1661 tx_desc_819x_pci *entry1 = &ring->desc[0];
1662 unsigned int *ptr= (unsigned int *)entry1;
1663 printk("<Tx descriptor>:\n");
1664 for (i = 0; i < 8; i++)
1665 printk("%8x ", ptr[i]);
1669 __skb_queue_tail(&ring->queue, skb);
1670 spin_unlock_irqrestore(&priv->irq_th_lock,flags);
1672 write_nic_byte(dev, TPPoll, TPPoll_CQ);
1678 * Mapping Software/Hardware descriptor queue id to "Queue Select Field"
1679 * in TxFwInfo data structure
1680 * 2006.10.30 by Emily
1682 * \param QUEUEID Software Queue
1684 u8 MapHwQueueToFirmwareQueue(u8 QueueID)
1686 u8 QueueSelect = 0x0; //defualt set to
1690 QueueSelect = QSLT_BE; //or QSelect = pTcb->priority;
1694 QueueSelect = QSLT_BK; //or QSelect = pTcb->priority;
1698 QueueSelect = QSLT_VO; //or QSelect = pTcb->priority;
1702 QueueSelect = QSLT_VI; //or QSelect = pTcb->priority;
1705 QueueSelect = QSLT_MGNT;
1709 QueueSelect = QSLT_BEACON;
1712 // TODO: 2006.10.30 mark other queue selection until we verify it is OK
1713 // TODO: Remove Assertions
1714 //#if (RTL819X_FPGA_VER & RTL819X_FPGA_GUANGAN_070502)
1716 QueueSelect = QSLT_CMD;
1720 //QueueSelect = QSLT_HIGH;
1724 RT_TRACE(COMP_ERR, "TransmitTCB(): Impossible Queue Selection: %d \n", QueueID);
1730 u8 MRateToHwRate8190Pci(u8 rate)
1732 u8 ret = DESC90_RATE1M;
1735 case MGN_1M: ret = DESC90_RATE1M; break;
1736 case MGN_2M: ret = DESC90_RATE2M; break;
1737 case MGN_5_5M: ret = DESC90_RATE5_5M; break;
1738 case MGN_11M: ret = DESC90_RATE11M; break;
1739 case MGN_6M: ret = DESC90_RATE6M; break;
1740 case MGN_9M: ret = DESC90_RATE9M; break;
1741 case MGN_12M: ret = DESC90_RATE12M; break;
1742 case MGN_18M: ret = DESC90_RATE18M; break;
1743 case MGN_24M: ret = DESC90_RATE24M; break;
1744 case MGN_36M: ret = DESC90_RATE36M; break;
1745 case MGN_48M: ret = DESC90_RATE48M; break;
1746 case MGN_54M: ret = DESC90_RATE54M; break;
1748 // HT rate since here
1749 case MGN_MCS0: ret = DESC90_RATEMCS0; break;
1750 case MGN_MCS1: ret = DESC90_RATEMCS1; break;
1751 case MGN_MCS2: ret = DESC90_RATEMCS2; break;
1752 case MGN_MCS3: ret = DESC90_RATEMCS3; break;
1753 case MGN_MCS4: ret = DESC90_RATEMCS4; break;
1754 case MGN_MCS5: ret = DESC90_RATEMCS5; break;
1755 case MGN_MCS6: ret = DESC90_RATEMCS6; break;
1756 case MGN_MCS7: ret = DESC90_RATEMCS7; break;
1757 case MGN_MCS8: ret = DESC90_RATEMCS8; break;
1758 case MGN_MCS9: ret = DESC90_RATEMCS9; break;
1759 case MGN_MCS10: ret = DESC90_RATEMCS10; break;
1760 case MGN_MCS11: ret = DESC90_RATEMCS11; break;
1761 case MGN_MCS12: ret = DESC90_RATEMCS12; break;
1762 case MGN_MCS13: ret = DESC90_RATEMCS13; break;
1763 case MGN_MCS14: ret = DESC90_RATEMCS14; break;
1764 case MGN_MCS15: ret = DESC90_RATEMCS15; break;
1765 case (0x80|0x20): ret = DESC90_RATEMCS32; break;
1773 u8 QueryIsShort(u8 TxHT, u8 TxRate, cb_desc *tcb_desc)
1777 tmp_Short = (TxHT==1)?((tcb_desc->bUseShortGI)?1:0):((tcb_desc->bUseShortPreamble)?1:0);
1779 if(TxHT==1 && TxRate != DESC90_RATEMCS15)
1786 * The tx procedure is just as following,
1787 * skb->cb will contain all the following information,
1788 * priority, morefrag, rate, &dev.
1790 short rtl8192_tx(struct net_device *dev, struct sk_buff* skb)
1792 struct r8192_priv *priv = ieee80211_priv(dev);
1793 struct rtl8192_tx_ring *ring;
1794 unsigned long flags;
1795 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1796 tx_desc_819x_pci *pdesc = NULL;
1797 TX_FWINFO_8190PCI *pTxFwInfo = NULL;
1799 bool multi_addr=false,broad_addr=false,uni_addr=false;
1800 u8* pda_addr = NULL;
1803 mapping = pci_map_single(priv->pdev, skb->data, skb->len, PCI_DMA_TODEVICE);
1804 /* collect the tx packets statitcs */
1805 pda_addr = ((u8*)skb->data) + sizeof(TX_FWINFO_8190PCI);
1806 if(is_multicast_ether_addr(pda_addr))
1808 else if(is_broadcast_ether_addr(pda_addr))
1814 priv->stats.txbytesunicast += (u8)(skb->len) - sizeof(TX_FWINFO_8190PCI);
1816 priv->stats.txbytesmulticast +=(u8)(skb->len) - sizeof(TX_FWINFO_8190PCI);
1818 priv->stats.txbytesbroadcast += (u8)(skb->len) - sizeof(TX_FWINFO_8190PCI);
1820 /* fill tx firmware */
1821 pTxFwInfo = (PTX_FWINFO_8190PCI)skb->data;
1822 memset(pTxFwInfo,0,sizeof(TX_FWINFO_8190PCI));
1823 pTxFwInfo->TxHT = (tcb_desc->data_rate&0x80)?1:0;
1824 pTxFwInfo->TxRate = MRateToHwRate8190Pci((u8)tcb_desc->data_rate);
1825 pTxFwInfo->EnableCPUDur = tcb_desc->bTxEnableFwCalcDur;
1826 pTxFwInfo->Short = QueryIsShort(pTxFwInfo->TxHT, pTxFwInfo->TxRate, tcb_desc);
1828 /* Aggregation related */
1829 if(tcb_desc->bAMPDUEnable) {
1830 pTxFwInfo->AllowAggregation = 1;
1831 pTxFwInfo->RxMF = tcb_desc->ampdu_factor;
1832 pTxFwInfo->RxAMD = tcb_desc->ampdu_density;
1834 pTxFwInfo->AllowAggregation = 0;
1835 pTxFwInfo->RxMF = 0;
1836 pTxFwInfo->RxAMD = 0;
1840 // Protection mode related
1842 pTxFwInfo->RtsEnable = (tcb_desc->bRTSEnable)?1:0;
1843 pTxFwInfo->CtsEnable = (tcb_desc->bCTSEnable)?1:0;
1844 pTxFwInfo->RtsSTBC = (tcb_desc->bRTSSTBC)?1:0;
1845 pTxFwInfo->RtsHT= (tcb_desc->rts_rate&0x80)?1:0;
1846 pTxFwInfo->RtsRate = MRateToHwRate8190Pci((u8)tcb_desc->rts_rate);
1847 pTxFwInfo->RtsBandwidth = 0;
1848 pTxFwInfo->RtsSubcarrier = tcb_desc->RTSSC;
1849 pTxFwInfo->RtsShort = (pTxFwInfo->RtsHT==0)?(tcb_desc->bRTSUseShortPreamble?1:0):(tcb_desc->bRTSUseShortGI?1:0);
1851 // Set Bandwidth and sub-channel settings.
1853 if(priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20_40)
1855 if(tcb_desc->bPacketBW)
1857 pTxFwInfo->TxBandwidth = 1;
1859 pTxFwInfo->TxSubCarrier = 3;
1861 pTxFwInfo->TxSubCarrier = 0; //By SD3's Jerry suggestion, use duplicated mode, cosa 04012008
1866 pTxFwInfo->TxBandwidth = 0;
1867 pTxFwInfo->TxSubCarrier = priv->nCur40MhzPrimeSC;
1870 pTxFwInfo->TxBandwidth = 0;
1871 pTxFwInfo->TxSubCarrier = 0;
1876 /* 2007/07/25 MH Copy current TX FW info.*/
1877 memcpy((void*)(&Tmp_TxFwInfo), (void*)(pTxFwInfo), sizeof(TX_FWINFO_8190PCI));
1878 printk("&&&&&&&&&&&&&&&&&&&&&&====>print out fwinf\n");
1879 printk("===>enable fwcacl:%d\n", Tmp_TxFwInfo.EnableCPUDur);
1880 printk("===>RTS STBC:%d\n", Tmp_TxFwInfo.RtsSTBC);
1881 printk("===>RTS Subcarrier:%d\n", Tmp_TxFwInfo.RtsSubcarrier);
1882 printk("===>Allow Aggregation:%d\n", Tmp_TxFwInfo.AllowAggregation);
1883 printk("===>TX HT bit:%d\n", Tmp_TxFwInfo.TxHT);
1884 printk("===>Tx rate:%d\n", Tmp_TxFwInfo.TxRate);
1885 printk("===>Received AMPDU Density:%d\n", Tmp_TxFwInfo.RxAMD);
1886 printk("===>Received MPDU Factor:%d\n", Tmp_TxFwInfo.RxMF);
1887 printk("===>TxBandwidth:%d\n", Tmp_TxFwInfo.TxBandwidth);
1888 printk("===>TxSubCarrier:%d\n", Tmp_TxFwInfo.TxSubCarrier);
1890 printk("<=====**********************out of print\n");
1893 spin_lock_irqsave(&priv->irq_th_lock,flags);
1894 ring = &priv->tx_ring[tcb_desc->queue_index];
1895 if (tcb_desc->queue_index != BEACON_QUEUE) {
1896 idx = (ring->idx + skb_queue_len(&ring->queue)) % ring->entries;
1901 pdesc = &ring->desc[idx];
1902 if((pdesc->OWN == 1) && (tcb_desc->queue_index != BEACON_QUEUE)) {
1903 RT_TRACE(COMP_ERR,"No more TX desc@%d, ring->idx = %d,idx = %d,%x", \
1904 tcb_desc->queue_index,ring->idx, idx,skb->len);
1908 /* fill tx descriptor */
1909 memset((u8*)pdesc,0,12);
1913 pdesc->Offset = sizeof(TX_FWINFO_8190PCI) + 8; //We must add 8!! Emily
1914 pdesc->PktSize = (u16)skb->len-sizeof(TX_FWINFO_8190PCI);
1918 pdesc->RATid = tcb_desc->RATRIndex;
1922 pdesc->SecType = 0x0;
1923 if (tcb_desc->bHwSec) {
1926 printk("==>================hw sec\n");
1929 switch (priv->ieee80211->pairwise_key_type) {
1930 case KEY_TYPE_WEP40:
1931 case KEY_TYPE_WEP104:
1932 pdesc->SecType = 0x1;
1936 pdesc->SecType = 0x2;
1940 pdesc->SecType = 0x3;
1944 pdesc->SecType = 0x0;
1955 pdesc->QueueSelect = MapHwQueueToFirmwareQueue(tcb_desc->queue_index);
1956 pdesc->TxFWInfoSize = sizeof(TX_FWINFO_8190PCI);
1958 pdesc->DISFB = tcb_desc->bTxDisableRateFallBack;
1959 pdesc->USERATE = tcb_desc->bTxUseDriverAssingedRate;
1963 pdesc->TxBufferSize = skb->len;
1965 pdesc->TxBuffAddr = cpu_to_le32(mapping);
1966 __skb_queue_tail(&ring->queue, skb);
1968 spin_unlock_irqrestore(&priv->irq_th_lock,flags);
1969 dev->trans_start = jiffies;
1970 write_nic_word(dev,TPPoll,0x01<<tcb_desc->queue_index);
1974 short rtl8192_alloc_rx_desc_ring(struct net_device *dev)
1976 struct r8192_priv *priv = ieee80211_priv(dev);
1977 rx_desc_819x_pci *entry = NULL;
1980 priv->rx_ring = pci_alloc_consistent(priv->pdev,
1981 sizeof(*priv->rx_ring) * priv->rxringcount, &priv->rx_ring_dma);
1983 if (!priv->rx_ring || (unsigned long)priv->rx_ring & 0xFF) {
1984 RT_TRACE(COMP_ERR,"Cannot allocate RX ring\n");
1988 memset(priv->rx_ring, 0, sizeof(*priv->rx_ring) * priv->rxringcount);
1991 for (i = 0; i < priv->rxringcount; i++) {
1992 struct sk_buff *skb = dev_alloc_skb(priv->rxbuffersize);
1993 dma_addr_t *mapping;
1994 entry = &priv->rx_ring[i];
1997 priv->rx_buf[i] = skb;
1998 mapping = (dma_addr_t *)skb->cb;
1999 *mapping = pci_map_single(priv->pdev, skb->tail,//skb_tail_pointer(skb),
2000 priv->rxbuffersize, PCI_DMA_FROMDEVICE);
2002 entry->BufferAddress = cpu_to_le32(*mapping);
2004 entry->Length = priv->rxbuffersize;
2012 static int rtl8192_alloc_tx_desc_ring(struct net_device *dev,
2013 unsigned int prio, unsigned int entries)
2015 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
2016 tx_desc_819x_pci *ring;
2020 ring = pci_alloc_consistent(priv->pdev, sizeof(*ring) * entries, &dma);
2021 if (!ring || (unsigned long)ring & 0xFF) {
2022 RT_TRACE(COMP_ERR, "Cannot allocate TX ring (prio = %d)\n", prio);
2026 memset(ring, 0, sizeof(*ring)*entries);
2027 priv->tx_ring[prio].desc = ring;
2028 priv->tx_ring[prio].dma = dma;
2029 priv->tx_ring[prio].idx = 0;
2030 priv->tx_ring[prio].entries = entries;
2031 skb_queue_head_init(&priv->tx_ring[prio].queue);
2033 for (i = 0; i < entries; i++)
2034 ring[i].NextDescAddress =
2035 cpu_to_le32((u32)dma + ((i + 1) % entries) * sizeof(*ring));
2041 short rtl8192_pci_initdescring(struct net_device *dev)
2045 struct r8192_priv *priv = ieee80211_priv(dev);
2047 ret = rtl8192_alloc_rx_desc_ring(dev);
2053 /* general process for other queue */
2054 for (i = 0; i < MAX_TX_QUEUE_COUNT; i++) {
2055 if ((ret = rtl8192_alloc_tx_desc_ring(dev, i, priv->txringcount)))
2056 goto err_free_rings;
2060 /* specific process for hardware beacon process */
2061 if ((ret = rtl8192_alloc_tx_desc_ring(dev, MAX_TX_QUEUE_COUNT - 1, 2)))
2062 goto err_free_rings;
2068 rtl8192_free_rx_ring(dev);
2069 for (i = 0; i < MAX_TX_QUEUE_COUNT; i++)
2070 if (priv->tx_ring[i].desc)
2071 rtl8192_free_tx_ring(dev, i);
2075 void rtl8192_pci_resetdescring(struct net_device *dev)
2077 struct r8192_priv *priv = ieee80211_priv(dev);
2080 /* force the rx_idx to the first one */
2082 rx_desc_819x_pci *entry = NULL;
2083 for (i = 0; i < priv->rxringcount; i++) {
2084 entry = &priv->rx_ring[i];
2090 /* after reset, release previous pending packet, and force the
2091 * tx idx to the first one */
2092 for (i = 0; i < MAX_TX_QUEUE_COUNT; i++) {
2093 if (priv->tx_ring[i].desc) {
2094 struct rtl8192_tx_ring *ring = &priv->tx_ring[i];
2096 while (skb_queue_len(&ring->queue)) {
2097 tx_desc_819x_pci *entry = &ring->desc[ring->idx];
2098 struct sk_buff *skb = __skb_dequeue(&ring->queue);
2100 pci_unmap_single(priv->pdev, le32_to_cpu(entry->TxBuffAddr),
2101 skb->len, PCI_DMA_TODEVICE);
2103 ring->idx = (ring->idx + 1) % ring->entries;
2111 extern void rtl8192_update_ratr_table(struct net_device* dev);
2112 void rtl8192_link_change(struct net_device *dev)
2116 struct r8192_priv *priv = ieee80211_priv(dev);
2117 struct ieee80211_device* ieee = priv->ieee80211;
2118 //write_nic_word(dev, BCN_INTR_ITV, net->beacon_interval);
2119 if (ieee->state == IEEE80211_LINKED)
2121 rtl8192_net_update(dev);
2122 rtl8192_update_ratr_table(dev);
2124 //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
2125 if ((KEY_TYPE_WEP40 == ieee->pairwise_key_type) || (KEY_TYPE_WEP104 == ieee->pairwise_key_type))
2126 EnableHWSecurityConfig8192(dev);
2131 write_nic_byte(dev, 0x173, 0);
2133 /*update timing params*/
2134 //rtl8192_set_chan(dev, priv->chan);
2136 rtl8192_update_msr(dev);
2138 // 2007/10/16 MH MAC Will update TSF according to all received beacon, so we have
2139 // // To set CBSSID bit when link with any AP or STA.
2140 if (ieee->iw_mode == IW_MODE_INFRA || ieee->iw_mode == IW_MODE_ADHOC)
2143 reg = read_nic_dword(dev, RCR);
2144 if (priv->ieee80211->state == IEEE80211_LINKED)
2145 priv->ReceiveConfig = reg |= RCR_CBSSID;
2147 priv->ReceiveConfig = reg &= ~RCR_CBSSID;
2148 write_nic_dword(dev, RCR, reg);
2154 static struct ieee80211_qos_parameters def_qos_parameters = {
2155 {3,3,3,3},/* cw_min */
2156 {7,7,7,7},/* cw_max */
2157 {2,2,2,2},/* aifs */
2158 {0,0,0,0},/* flags */
2159 {0,0,0,0} /* tx_op_limit */
2162 #if LINUX_VERSION_CODE >=KERNEL_VERSION(2,6,20)
2163 void rtl8192_update_beacon(struct work_struct * work)
2165 struct r8192_priv *priv = container_of(work, struct r8192_priv, update_beacon_wq.work);
2166 struct net_device *dev = priv->ieee80211->dev;
2168 void rtl8192_update_beacon(struct net_device *dev)
2170 struct r8192_priv *priv = ieee80211_priv(dev);
2172 struct ieee80211_device* ieee = priv->ieee80211;
2173 struct ieee80211_network* net = &ieee->current_network;
2175 if (ieee->pHTInfo->bCurrentHTSupport)
2176 HTUpdateSelfAndPeerSetting(ieee, net);
2177 ieee->pHTInfo->bCurrentRT2RTLongSlotTime = net->bssht.bdRT2RTLongSlotTime;
2178 rtl8192_update_cap(dev, net->capability);
2181 * background support to run QoS activate functionality
2183 int WDCAPARA_ADD[] = {EDCAPARA_BE,EDCAPARA_BK,EDCAPARA_VI,EDCAPARA_VO};
2184 #if LINUX_VERSION_CODE >=KERNEL_VERSION(2,6,20)
2185 void rtl8192_qos_activate(struct work_struct * work)
2187 struct r8192_priv *priv = container_of(work, struct r8192_priv, qos_activate);
2188 struct net_device *dev = priv->ieee80211->dev;
2190 void rtl8192_qos_activate(struct net_device *dev)
2192 struct r8192_priv *priv = ieee80211_priv(dev);
2194 struct ieee80211_qos_parameters *qos_parameters = &priv->ieee80211->current_network.qos_data.parameters;
2195 u8 mode = priv->ieee80211->current_network.mode;
2196 // u32 size = sizeof(struct ieee80211_qos_parameters);
2203 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16))
2206 mutex_lock(&priv->mutex);
2208 if(priv->ieee80211->state != IEEE80211_LINKED)
2210 RT_TRACE(COMP_QOS,"qos active process with associate response received\n");
2211 /* It better set slot time at first */
2212 /* For we just support b/g mode at present, let the slot time at 9/20 selection */
2213 /* update the ac parameter to related registers */
2214 for(i = 0; i < QOS_QUEUE_NUM; i++) {
2215 //Mode G/A: slotTimeTimer = 9; Mode B: 20
2216 u1bAIFS = qos_parameters->aifs[i] * ((mode&(IEEE_G|IEEE_N_24G)) ?9:20) + aSifsTime;
2217 u4bAcParam = ((((u32)(qos_parameters->tx_op_limit[i]))<< AC_PARAM_TXOP_LIMIT_OFFSET)|
2218 (((u32)(qos_parameters->cw_max[i]))<< AC_PARAM_ECW_MAX_OFFSET)|
2219 (((u32)(qos_parameters->cw_min[i]))<< AC_PARAM_ECW_MIN_OFFSET)|
2220 ((u32)u1bAIFS << AC_PARAM_AIFS_OFFSET));
2221 printk("===>u4bAcParam:%x, ", u4bAcParam);
2222 write_nic_dword(dev, WDCAPARA_ADD[i], u4bAcParam);
2223 //write_nic_dword(dev, WDCAPARA_ADD[i], 0x005e4332);
2227 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16))
2230 mutex_unlock(&priv->mutex);
2234 static int rtl8192_qos_handle_probe_response(struct r8192_priv *priv,
2236 struct ieee80211_network *network)
2239 u32 size = sizeof(struct ieee80211_qos_parameters);
2241 if(priv->ieee80211->state !=IEEE80211_LINKED)
2244 if ((priv->ieee80211->iw_mode != IW_MODE_INFRA))
2247 if (network->flags & NETWORK_HAS_QOS_MASK) {
2248 if (active_network &&
2249 (network->flags & NETWORK_HAS_QOS_PARAMETERS))
2250 network->qos_data.active = network->qos_data.supported;
2252 if ((network->qos_data.active == 1) && (active_network == 1) &&
2253 (network->flags & NETWORK_HAS_QOS_PARAMETERS) &&
2254 (network->qos_data.old_param_count !=
2255 network->qos_data.param_count)) {
2256 network->qos_data.old_param_count =
2257 network->qos_data.param_count;
2258 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
2259 queue_work(priv->priv_wq, &priv->qos_activate);
2261 schedule_task(&priv->qos_activate);
2263 RT_TRACE (COMP_QOS, "QoS parameters change call "
2267 memcpy(&priv->ieee80211->current_network.qos_data.parameters,\
2268 &def_qos_parameters, size);
2270 if ((network->qos_data.active == 1) && (active_network == 1)) {
2271 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
2272 queue_work(priv->priv_wq, &priv->qos_activate);
2274 schedule_task(&priv->qos_activate);
2276 RT_TRACE(COMP_QOS, "QoS was disabled call qos_activate \n");
2278 network->qos_data.active = 0;
2279 network->qos_data.supported = 0;
2285 /* handle manage frame frame beacon and probe response */
2286 static int rtl8192_handle_beacon(struct net_device * dev,
2287 struct ieee80211_beacon * beacon,
2288 struct ieee80211_network * network)
2290 struct r8192_priv *priv = ieee80211_priv(dev);
2292 rtl8192_qos_handle_probe_response(priv,1,network);
2294 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
2295 queue_delayed_work(priv->priv_wq, &priv->update_beacon_wq, 0);
2297 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
2298 schedule_task(&priv->update_beacon_wq);
2300 queue_work(priv->priv_wq, &priv->update_beacon_wq);
2308 * handling the beaconing responses. if we get different QoS setting
2309 * off the network from the associated setting, adjust the QoS
2312 static int rtl8192_qos_association_resp(struct r8192_priv *priv,
2313 struct ieee80211_network *network)
2316 unsigned long flags;
2317 u32 size = sizeof(struct ieee80211_qos_parameters);
2318 int set_qos_param = 0;
2320 if ((priv == NULL) || (network == NULL))
2323 if(priv->ieee80211->state !=IEEE80211_LINKED)
2326 if ((priv->ieee80211->iw_mode != IW_MODE_INFRA))
2329 spin_lock_irqsave(&priv->ieee80211->lock, flags);
2330 if(network->flags & NETWORK_HAS_QOS_PARAMETERS) {
2331 memcpy(&priv->ieee80211->current_network.qos_data.parameters,\
2332 &network->qos_data.parameters,\
2333 sizeof(struct ieee80211_qos_parameters));
2334 priv->ieee80211->current_network.qos_data.active = 1;
2336 if((priv->ieee80211->current_network.qos_data.param_count != \
2337 network->qos_data.param_count))
2341 /* update qos parameter for current network */
2342 priv->ieee80211->current_network.qos_data.old_param_count = \
2343 priv->ieee80211->current_network.qos_data.param_count;
2344 priv->ieee80211->current_network.qos_data.param_count = \
2345 network->qos_data.param_count;
2348 memcpy(&priv->ieee80211->current_network.qos_data.parameters,\
2349 &def_qos_parameters, size);
2350 priv->ieee80211->current_network.qos_data.active = 0;
2351 priv->ieee80211->current_network.qos_data.supported = 0;
2355 spin_unlock_irqrestore(&priv->ieee80211->lock, flags);
2357 RT_TRACE(COMP_QOS, "%s: network->flags = %d,%d\n",__FUNCTION__,network->flags ,priv->ieee80211->current_network.qos_data.active);
2358 if (set_qos_param == 1)
2359 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
2360 queue_work(priv->priv_wq, &priv->qos_activate);
2362 schedule_task(&priv->qos_activate);
2370 static int rtl8192_handle_assoc_response(struct net_device *dev,
2371 struct ieee80211_assoc_response_frame *resp,
2372 struct ieee80211_network *network)
2374 struct r8192_priv *priv = ieee80211_priv(dev);
2375 rtl8192_qos_association_resp(priv, network);
2380 //updateRATRTabel for MCS only. Basic rate is not implement.
2381 void rtl8192_update_ratr_table(struct net_device* dev)
2382 // POCTET_STRING posLegacyRate,
2384 // PRT_WLAN_STA pEntry)
2386 struct r8192_priv* priv = ieee80211_priv(dev);
2387 struct ieee80211_device* ieee = priv->ieee80211;
2388 u8* pMcsRate = ieee->dot11HTOperationalRateSet;
2389 //struct ieee80211_network *net = &ieee->current_network;
2393 rtl8192_config_rate(dev, (u16*)(&ratr_value));
2394 ratr_value |= (*(u16*)(pMcsRate)) << 12;
2395 // switch (net->mode)
2399 ratr_value &= 0x00000FF0;
2402 ratr_value &= 0x0000000F;
2405 ratr_value &= 0x00000FF7;
2409 if (ieee->pHTInfo->PeerMimoPs == 0) //MIMO_PS_STATIC
2410 ratr_value &= 0x0007F007;
2412 if (priv->rf_type == RF_1T2R)
2413 ratr_value &= 0x000FF007;
2415 ratr_value &= 0x0F81F007;
2421 ratr_value &= 0x0FFFFFFF;
2422 if(ieee->pHTInfo->bCurTxBW40MHz && ieee->pHTInfo->bCurShortGI40MHz){
2423 ratr_value |= 0x80000000;
2424 }else if(!ieee->pHTInfo->bCurTxBW40MHz && ieee->pHTInfo->bCurShortGI20MHz){
2425 ratr_value |= 0x80000000;
2427 write_nic_dword(dev, RATR0+rate_index*4, ratr_value);
2428 write_nic_byte(dev, UFWP, 1);
2431 static u8 ccmp_ie[4] = {0x00,0x50,0xf2,0x04};
2432 static u8 ccmp_rsn_ie[4] = {0x00, 0x0f, 0xac, 0x04};
2433 bool GetNmodeSupportBySecCfg8190Pci(struct net_device*dev)
2436 struct r8192_priv* priv = ieee80211_priv(dev);
2437 struct ieee80211_device* ieee = priv->ieee80211;
2438 int wpa_ie_len= ieee->wpa_ie_len;
2439 struct ieee80211_crypt_data* crypt;
2442 crypt = ieee->crypt[ieee->tx_keyidx];
2443 encrypt = (ieee->current_network.capability & WLAN_CAPABILITY_PRIVACY) || (ieee->host_encrypt && crypt && crypt->ops && (0 == strcmp(crypt->ops->name,"WEP")));
2446 if(encrypt && (wpa_ie_len == 0)) {
2447 /* wep encryption, no N mode setting */
2449 // } else if((wpa_ie_len != 0)&&(memcmp(&(ieee->wpa_ie[14]),ccmp_ie,4))) {
2450 } else if((wpa_ie_len != 0)) {
2451 /* parse pairwise key type */
2452 //if((pairwisekey = WEP40)||(pairwisekey = WEP104)||(pairwisekey = TKIP))
2453 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))))
2458 //RT_TRACE(COMP_ERR,"In %s The GroupEncAlgorithm is [4]\n",__FUNCTION__ );
2463 //In here we discuss with SD4 David. He think we still can send TKIP in broadcast group key in MCS rate.
2464 //We can't force in G mode if Pairwie key is AES and group key is TKIP
2465 if((pSecInfo->GroupEncAlgorithm == WEP104_Encryption) || (pSecInfo->GroupEncAlgorithm == WEP40_Encryption) ||
2466 (pSecInfo->PairwiseEncAlgorithm == WEP104_Encryption) ||
2467 (pSecInfo->PairwiseEncAlgorithm == WEP40_Encryption) || (pSecInfo->PairwiseEncAlgorithm == TKIP_Encryption))
2478 void rtl8192_refresh_supportrate(struct r8192_priv* priv)
2480 struct ieee80211_device* ieee = priv->ieee80211;
2481 //we donot consider set support rate for ABG mode, only HT MCS rate is set here.
2482 if (ieee->mode == WIRELESS_MODE_N_24G || ieee->mode == WIRELESS_MODE_N_5G)
2484 memcpy(ieee->Regdot11HTOperationalRateSet, ieee->RegHTSuppRateSet, 16);
2485 //RT_DEBUG_DATA(COMP_INIT, ieee->RegHTSuppRateSet, 16);
2486 //RT_DEBUG_DATA(COMP_INIT, ieee->Regdot11HTOperationalRateSet, 16);
2489 memset(ieee->Regdot11HTOperationalRateSet, 0, 16);
2493 u8 rtl8192_getSupportedWireleeMode(struct net_device*dev)
2495 struct r8192_priv *priv = ieee80211_priv(dev);
2497 switch(priv->rf_chip)
2502 ret = (WIRELESS_MODE_N_24G|WIRELESS_MODE_G|WIRELESS_MODE_B);
2505 ret = (WIRELESS_MODE_A|WIRELESS_MODE_N_5G);
2508 ret = WIRELESS_MODE_B;
2513 void rtl8192_SetWirelessMode(struct net_device* dev, u8 wireless_mode)
2515 struct r8192_priv *priv = ieee80211_priv(dev);
2516 u8 bSupportMode = rtl8192_getSupportedWireleeMode(dev);
2519 if ((wireless_mode == WIRELESS_MODE_AUTO) || ((wireless_mode&bSupportMode)==0))
2521 if(bSupportMode & WIRELESS_MODE_N_24G)
2523 wireless_mode = WIRELESS_MODE_N_24G;
2525 else if(bSupportMode & WIRELESS_MODE_N_5G)
2527 wireless_mode = WIRELESS_MODE_N_5G;
2529 else if((bSupportMode & WIRELESS_MODE_A))
2531 wireless_mode = WIRELESS_MODE_A;
2533 else if((bSupportMode & WIRELESS_MODE_G))
2535 wireless_mode = WIRELESS_MODE_G;
2537 else if((bSupportMode & WIRELESS_MODE_B))
2539 wireless_mode = WIRELESS_MODE_B;
2542 RT_TRACE(COMP_ERR, "%s(), No valid wireless mode supported, SupportedWirelessMode(%x)!!!\n", __FUNCTION__,bSupportMode);
2543 wireless_mode = WIRELESS_MODE_B;
2546 #ifdef TO_DO_LIST //// TODO: this function doesn't work well at this time, we shoud wait for FPGA
2547 ActUpdateChannelAccessSetting( pAdapter, pHalData->CurrentWirelessMode, &pAdapter->MgntInfo.Info8185.ChannelAccessSetting );
2549 priv->ieee80211->mode = wireless_mode;
2551 if ((wireless_mode == WIRELESS_MODE_N_24G) || (wireless_mode == WIRELESS_MODE_N_5G))
2552 priv->ieee80211->pHTInfo->bEnableHT = 1;
2554 priv->ieee80211->pHTInfo->bEnableHT = 0;
2555 RT_TRACE(COMP_INIT, "Current Wireless Mode is %x\n", wireless_mode);
2556 rtl8192_refresh_supportrate(priv);
2560 //init priv variables here
2562 bool GetHalfNmodeSupportByAPs819xPci(struct net_device* dev)
2565 struct r8192_priv* priv = ieee80211_priv(dev);
2566 struct ieee80211_device* ieee = priv->ieee80211;
2568 if(ieee->bHalfWirelessN24GMode == true)
2576 short rtl8192_is_tx_queue_empty(struct net_device *dev)
2579 struct r8192_priv *priv = ieee80211_priv(dev);
2580 for (i=0; i<=MGNT_QUEUE; i++)
2582 if ((i== TXCMD_QUEUE) || (i == HCCA_QUEUE) )
2584 if (skb_queue_len(&(&priv->tx_ring[i])->queue) > 0){
2585 printk("===>tx queue is not empty:%d, %d\n", i, skb_queue_len(&(&priv->tx_ring[i])->queue));
2592 void rtl8192_rq_tx_ack(struct net_device *dev)
2594 struct r8192_priv *priv = ieee80211_priv(dev);
2595 priv->ieee80211->ack_tx_to_ieee = 1;
2598 void rtl8192_hw_sleep_down(struct net_device *dev)
2600 RT_TRACE(COMP_POWER, "%s()============>come to sleep down\n", __FUNCTION__);
2601 MgntActSet_RF_State(dev, eRfSleep, RF_CHANGE_BY_PS);
2603 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
2604 void rtl8192_hw_sleep_wq (struct work_struct *work)
2606 // struct r8180_priv *priv = container_of(work, struct r8180_priv, watch_dog_wq);
2607 // struct ieee80211_device * ieee = (struct ieee80211_device*)
2608 // container_of(work, struct ieee80211_device, watch_dog_wq);
2609 struct delayed_work *dwork = container_of(work,struct delayed_work,work);
2610 struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,hw_sleep_wq);
2611 struct net_device *dev = ieee->dev;
2613 void rtl8192_hw_sleep_wq(struct net_device* dev)
2616 //printk("=========>%s()\n", __FUNCTION__);
2617 rtl8192_hw_sleep_down(dev);
2619 // printk("dev is %d\n",dev);
2620 // printk("&*&(^*(&(&=========>%s()\n", __FUNCTION__);
2621 void rtl8192_hw_wakeup(struct net_device* dev)
2625 // spin_lock_irqsave(&priv->ps_lock,flags);
2626 RT_TRACE(COMP_POWER, "%s()============>come to wake up\n", __FUNCTION__);
2627 MgntActSet_RF_State(dev, eRfOn, RF_CHANGE_BY_PS);
2628 //FIXME: will we send package stored while nic is sleep?
2629 // spin_unlock_irqrestore(&priv->ps_lock,flags);
2631 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
2632 void rtl8192_hw_wakeup_wq (struct work_struct *work)
2634 // struct r8180_priv *priv = container_of(work, struct r8180_priv, watch_dog_wq);
2635 // struct ieee80211_device * ieee = (struct ieee80211_device*)
2636 // container_of(work, struct ieee80211_device, watch_dog_wq);
2637 struct delayed_work *dwork = container_of(work,struct delayed_work,work);
2638 struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,hw_wakeup_wq);
2639 struct net_device *dev = ieee->dev;
2641 void rtl8192_hw_wakeup_wq(struct net_device* dev)
2644 rtl8192_hw_wakeup(dev);
2648 #define MIN_SLEEP_TIME 50
2649 #define MAX_SLEEP_TIME 10000
2650 void rtl8192_hw_to_sleep(struct net_device *dev, u32 th, u32 tl)
2653 struct r8192_priv *priv = ieee80211_priv(dev);
2656 unsigned long flags;
2658 spin_lock_irqsave(&priv->ps_lock,flags);
2660 /* Writing HW register with 0 equals to disable
2661 * the timer, that is not really what we want
2663 tl -= MSECS(4+16+7);
2665 //if(tl == 0) tl = 1;
2667 /* FIXME HACK FIXME HACK */
2668 // force_pci_posting(dev);
2671 // rb = read_nic_dword(dev, TSFTR);
2673 /* If the interval in witch we are requested to sleep is too
2674 * short then give up and remain awake
2676 if(((tl>=rb)&& (tl-rb) <= MSECS(MIN_SLEEP_TIME))
2677 ||((rb>tl)&& (rb-tl) < MSECS(MIN_SLEEP_TIME))) {
2678 spin_unlock_irqrestore(&priv->ps_lock,flags);
2679 printk("too short to sleep\n");
2683 // write_nic_dword(dev, TimerInt, tl);
2684 // rb = read_nic_dword(dev, TSFTR);
2686 u32 tmp = (tl>rb)?(tl-rb):(rb-tl);
2688 queue_delayed_work(priv->ieee80211->wq, &priv->ieee80211->hw_wakeup_wq, tmp); //as tl may be less than rb
2690 /* if we suspect the TimerInt is gone beyond tl
2691 * while setting it, then give up
2694 if(((tl > rb) && ((tl-rb) > MSECS(MAX_SLEEP_TIME)))||
2695 ((tl < rb) && ((rb-tl) > MSECS(MAX_SLEEP_TIME)))) {
2696 printk("========>too long to sleep:%x, %x, %lx\n", tl, rb, MSECS(MAX_SLEEP_TIME));
2697 spin_unlock_irqrestore(&priv->ps_lock,flags);
2701 // if(priv->rf_sleep)
2702 // priv->rf_sleep(dev);
2704 //printk("<=========%s()\n", __FUNCTION__);
2705 queue_delayed_work(priv->ieee80211->wq, (void *)&priv->ieee80211->hw_sleep_wq,0);
2706 spin_unlock_irqrestore(&priv->ps_lock,flags);
2708 static void rtl8192_init_priv_variable(struct net_device* dev)
2710 struct r8192_priv *priv = ieee80211_priv(dev);
2712 priv->being_init_adapter = false;
2713 priv->txbuffsize = 1600;//1024;
2714 priv->txfwbuffersize = 4096;
2715 priv->txringcount = 64;//32;
2716 //priv->txbeaconcount = priv->txringcount;
2717 priv->txbeaconcount = 2;
2718 priv->rxbuffersize = 9100;//2048;//1024;
2719 priv->rxringcount = MAX_RX_COUNT;//64;
2720 priv->irq_enabled=0;
2721 priv->card_8192 = NIC_8192E;
2722 priv->rx_skb_complete = 1;
2723 priv->chan = 1; //set to channel 1
2724 priv->RegWirelessMode = WIRELESS_MODE_AUTO;
2725 priv->RegChannelPlan = 0xf;
2726 priv->nrxAMPDU_size = 0;
2727 priv->nrxAMPDU_aggr_num = 0;
2728 priv->last_rxdesc_tsf_high = 0;
2729 priv->last_rxdesc_tsf_low = 0;
2730 priv->ieee80211->mode = WIRELESS_MODE_AUTO; //SET AUTO
2731 priv->ieee80211->iw_mode = IW_MODE_INFRA;
2732 priv->ieee80211->ieee_up=0;
2733 priv->retry_rts = DEFAULT_RETRY_RTS;
2734 priv->retry_data = DEFAULT_RETRY_DATA;
2735 priv->ieee80211->rts = DEFAULT_RTS_THRESHOLD;
2736 priv->ieee80211->rate = 110; //11 mbps
2737 priv->ieee80211->short_slot = 1;
2738 priv->promisc = (dev->flags & IFF_PROMISC) ? 1:0;
2739 priv->bcck_in_ch14 = false;
2740 priv->bfsync_processing = false;
2741 priv->CCKPresentAttentuation = 0;
2742 priv->rfa_txpowertrackingindex = 0;
2743 priv->rfc_txpowertrackingindex = 0;
2745 priv->ScanDelay = 50;//for Scan TODO
2746 //added by amy for silent reset
2747 priv->ResetProgress = RESET_TYPE_NORESET;
2748 priv->bForcedSilentReset = 0;
2749 priv->bDisableNormalResetCheck = false;
2750 priv->force_reset = false;
2751 //added by amy for power save
2753 priv->ieee80211->RfOffReason = 0;
2754 priv->RFChangeInProgress = false;
2755 priv->bHwRfOffAction = 0;
2756 priv->SetRFPowerStateInProgress = false;
2757 priv->ieee80211->PowerSaveControl.bInactivePs = true;
2758 priv->ieee80211->PowerSaveControl.bIPSModeBackup = false;
2760 priv->txpower_checkcnt = 0;
2761 priv->thermal_readback_index =0;
2762 priv->txpower_tracking_callback_cnt = 0;
2763 priv->ccktxpower_adjustcnt_ch14 = 0;
2764 priv->ccktxpower_adjustcnt_not_ch14 = 0;
2766 priv->ieee80211->current_network.beacon_interval = DEFAULT_BEACONINTERVAL;
2767 priv->ieee80211->iw_mode = IW_MODE_INFRA;
2768 priv->ieee80211->softmac_features = IEEE_SOFTMAC_SCAN |
2769 IEEE_SOFTMAC_ASSOCIATE | IEEE_SOFTMAC_PROBERQ |
2770 IEEE_SOFTMAC_PROBERS | IEEE_SOFTMAC_TX_QUEUE;/* |
2771 IEEE_SOFTMAC_BEACONS;*///added by amy 080604 //| //IEEE_SOFTMAC_SINGLE_QUEUE;
2773 priv->ieee80211->active_scan = 1;
2774 priv->ieee80211->modulation = IEEE80211_CCK_MODULATION | IEEE80211_OFDM_MODULATION;
2775 priv->ieee80211->host_encrypt = 1;
2776 priv->ieee80211->host_decrypt = 1;
2777 //priv->ieee80211->start_send_beacons = NULL;//rtl819xusb_beacon_tx;//-by amy 080604
2778 //priv->ieee80211->stop_send_beacons = NULL;//rtl8192_beacon_stop;//-by amy 080604
2779 priv->ieee80211->start_send_beacons = rtl8192_start_beacon;//+by david 081107
2780 priv->ieee80211->stop_send_beacons = rtl8192_stop_beacon;//+by david 081107
2781 priv->ieee80211->softmac_hard_start_xmit = rtl8192_hard_start_xmit;
2782 priv->ieee80211->set_chan = rtl8192_set_chan;
2783 priv->ieee80211->link_change = rtl8192_link_change;
2784 priv->ieee80211->softmac_data_hard_start_xmit = rtl8192_hard_data_xmit;
2785 priv->ieee80211->data_hard_stop = rtl8192_data_hard_stop;
2786 priv->ieee80211->data_hard_resume = rtl8192_data_hard_resume;
2787 priv->ieee80211->init_wmmparam_flag = 0;
2788 priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD;
2789 priv->ieee80211->check_nic_enough_desc = check_nic_enough_desc;
2790 priv->ieee80211->tx_headroom = sizeof(TX_FWINFO_8190PCI);
2791 priv->ieee80211->qos_support = 1;
2792 priv->ieee80211->dot11PowerSaveMode = 0;
2794 // priv->ieee80211->SwChnlByTimerHandler = rtl8192_phy_SwChnl;
2795 priv->ieee80211->SetBWModeHandler = rtl8192_SetBWMode;
2796 priv->ieee80211->handle_assoc_response = rtl8192_handle_assoc_response;
2797 priv->ieee80211->handle_beacon = rtl8192_handle_beacon;
2799 priv->ieee80211->sta_wake_up = rtl8192_hw_wakeup;
2800 // priv->ieee80211->ps_request_tx_ack = rtl8192_rq_tx_ack;
2801 priv->ieee80211->enter_sleep_state = rtl8192_hw_to_sleep;
2802 priv->ieee80211->ps_is_queue_empty = rtl8192_is_tx_queue_empty;
2804 priv->ieee80211->GetNmodeSupportBySecCfg = GetNmodeSupportBySecCfg8190Pci;
2805 priv->ieee80211->SetWirelessMode = rtl8192_SetWirelessMode;
2806 priv->ieee80211->GetHalfNmodeSupportByAPsHandler = GetHalfNmodeSupportByAPs819xPci;
2809 priv->ieee80211->InitialGainHandler = InitialGain819xPci;
2811 priv->card_type = USB;
2813 priv->ShortRetryLimit = 0x30;
2814 priv->LongRetryLimit = 0x30;
2816 priv->EarlyRxThreshold = 7;
2817 priv->enable_gpio0 = 0;
2819 priv->TransmitConfig = 0;
2821 priv->ReceiveConfig = RCR_ADD3 |
2822 RCR_AMF | RCR_ADF | //accept management/data
2823 RCR_AICV | //accept control frame for SW AP needs PS-poll, 2005.07.07, by rcnjko.
2824 RCR_AB | RCR_AM | RCR_APM | //accept BC/MC/UC
2825 RCR_AAP | ((u32)7<<RCR_MXDMA_OFFSET) |
2826 ((u32)7 << RCR_FIFO_OFFSET) | RCR_ONLYERLPKT;
2828 priv->irq_mask = (u32)(IMR_ROK | IMR_VODOK | IMR_VIDOK | IMR_BEDOK | IMR_BKDOK |\
2829 IMR_HCCADOK | IMR_MGNTDOK | IMR_COMDOK | IMR_HIGHDOK |\
2830 IMR_BDOK | IMR_RXCMDOK | IMR_TIMEOUT0 | IMR_RDU | IMR_RXFOVW |\
2831 IMR_TXFOVW | IMR_BcnInt | IMR_TBDOK | IMR_TBDER);
2833 priv->AcmControl = 0;
2834 priv->pFirmware = (rt_firmware*)vmalloc(sizeof(rt_firmware));
2835 if (priv->pFirmware)
2836 memset(priv->pFirmware, 0, sizeof(rt_firmware));
2838 /* rx related queue */
2839 skb_queue_head_init(&priv->rx_queue);
2840 skb_queue_head_init(&priv->skb_queue);
2842 /* Tx related queue */
2843 for(i = 0; i < MAX_QUEUE_SIZE; i++) {
2844 skb_queue_head_init(&priv->ieee80211->skb_waitQ [i]);
2846 for(i = 0; i < MAX_QUEUE_SIZE; i++) {
2847 skb_queue_head_init(&priv->ieee80211->skb_aggQ [i]);
2849 priv->rf_set_chan = rtl8192_phy_SwChnl;
2853 static void rtl8192_init_priv_lock(struct r8192_priv* priv)
2855 spin_lock_init(&priv->tx_lock);
2856 spin_lock_init(&priv->irq_lock);//added by thomas
2857 spin_lock_init(&priv->irq_th_lock);
2858 spin_lock_init(&priv->rf_ps_lock);
2859 spin_lock_init(&priv->ps_lock);
2860 //spin_lock_init(&priv->rf_lock);
2861 sema_init(&priv->wx_sem,1);
2862 sema_init(&priv->rf_sem,1);
2863 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16))
2864 sema_init(&priv->mutex, 1);
2866 mutex_init(&priv->mutex);
2870 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
2871 extern void rtl819x_watchdog_wqcallback(struct work_struct *work);
2873 extern void rtl819x_watchdog_wqcallback(struct net_device *dev);
2876 void rtl8192_irq_rx_tasklet(struct r8192_priv *priv);
2877 void rtl8192_irq_tx_tasklet(struct r8192_priv *priv);
2878 void rtl8192_prepare_beacon(struct r8192_priv *priv);
2879 //init tasklet and wait_queue here. only 2.6 above kernel is considered
2880 #define DRV_NAME "wlan0"
2881 static void rtl8192_init_priv_task(struct net_device* dev)
2883 struct r8192_priv *priv = ieee80211_priv(dev);
2885 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
2886 #ifdef PF_SYNCTHREAD
2887 priv->priv_wq = create_workqueue(DRV_NAME,0);
2889 priv->priv_wq = create_workqueue(DRV_NAME);
2893 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
2894 // INIT_WORK(&priv->reset_wq, (void(*)(void*)) rtl8192_restart);
2895 INIT_WORK(&priv->reset_wq, rtl8192_restart);
2896 // INIT_DELAYED_WORK(&priv->watch_dog_wq, hal_dm_watchdog);
2897 INIT_DELAYED_WORK(&priv->watch_dog_wq, rtl819x_watchdog_wqcallback);
2898 INIT_DELAYED_WORK(&priv->txpower_tracking_wq, dm_txpower_trackingcallback);
2899 INIT_DELAYED_WORK(&priv->rfpath_check_wq, dm_rf_pathcheck_workitemcallback);
2900 INIT_DELAYED_WORK(&priv->update_beacon_wq, rtl8192_update_beacon);
2901 //INIT_WORK(&priv->SwChnlWorkItem, rtl8192_SwChnl_WorkItem);
2902 //INIT_WORK(&priv->SetBWModeWorkItem, rtl8192_SetBWModeWorkItem);
2903 INIT_WORK(&priv->qos_activate, rtl8192_qos_activate);
2904 INIT_DELAYED_WORK(&priv->ieee80211->hw_wakeup_wq,(void*) rtl8192_hw_wakeup_wq);
2905 INIT_DELAYED_WORK(&priv->ieee80211->hw_sleep_wq,(void*) rtl8192_hw_sleep_wq);
2908 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
2909 tq_init(&priv->reset_wq, (void*)rtl8192_restart, dev);
2910 tq_init(&priv->watch_dog_wq, (void*)rtl819x_watchdog_wqcallback, dev);
2911 tq_init(&priv->txpower_tracking_wq, (void*)dm_txpower_trackingcallback, dev);
2912 tq_init(&priv->rfpath_check_wq, (void*)dm_rf_pathcheck_workitemcallback, dev);
2913 tq_init(&priv->update_beacon_wq, (void*)rtl8192_update_beacon, dev);
2914 //tq_init(&priv->SwChnlWorkItem, (void*) rtl8192_SwChnl_WorkItem, dev);
2915 //tq_init(&priv->SetBWModeWorkItem, (void*)rtl8192_SetBWModeWorkItem, dev);
2916 tq_init(&priv->qos_activate, (void *)rtl8192_qos_activate, dev);
2917 tq_init(&priv->ieee80211->hw_wakeup_wq,(void*) rtl8192_hw_wakeup_wq, dev);
2918 tq_init(&priv->ieee80211->hw_sleep_wq,(void*) rtl8192_hw_sleep_wq, dev);
2921 INIT_WORK(&priv->reset_wq,(void(*)(void*)) rtl8192_restart,dev);
2922 // INIT_WORK(&priv->watch_dog_wq, (void(*)(void*)) hal_dm_watchdog,dev);
2923 INIT_WORK(&priv->watch_dog_wq, (void(*)(void*)) rtl819x_watchdog_wqcallback,dev);
2924 INIT_WORK(&priv->txpower_tracking_wq, (void(*)(void*)) dm_txpower_trackingcallback,dev);
2925 INIT_WORK(&priv->rfpath_check_wq, (void(*)(void*)) dm_rf_pathcheck_workitemcallback,dev);
2926 INIT_WORK(&priv->update_beacon_wq, (void(*)(void*))rtl8192_update_beacon,dev);
2927 //INIT_WORK(&priv->SwChnlWorkItem, (void(*)(void*)) rtl8192_SwChnl_WorkItem, dev);
2928 //INIT_WORK(&priv->SetBWModeWorkItem, (void(*)(void*)) rtl8192_SetBWModeWorkItem, dev);
2929 INIT_WORK(&priv->qos_activate, (void(*)(void *))rtl8192_qos_activate, dev);
2930 INIT_WORK(&priv->ieee80211->hw_wakeup_wq,(void*) rtl8192_hw_wakeup_wq, dev);
2931 INIT_WORK(&priv->ieee80211->hw_sleep_wq,(void*) rtl8192_hw_sleep_wq, dev);
2935 tasklet_init(&priv->irq_rx_tasklet,
2936 (void(*)(unsigned long))rtl8192_irq_rx_tasklet,
2937 (unsigned long)priv);
2938 tasklet_init(&priv->irq_tx_tasklet,
2939 (void(*)(unsigned long))rtl8192_irq_tx_tasklet,
2940 (unsigned long)priv);
2941 tasklet_init(&priv->irq_prepare_beacon_tasklet,
2942 (void(*)(unsigned long))rtl8192_prepare_beacon,
2943 (unsigned long)priv);
2946 static void rtl8192_get_eeprom_size(struct net_device* dev)
2949 struct r8192_priv *priv = ieee80211_priv(dev);
2950 RT_TRACE(COMP_INIT, "===========>%s()\n", __FUNCTION__);
2951 curCR = read_nic_dword(dev, EPROM_CMD);
2952 RT_TRACE(COMP_INIT, "read from Reg Cmd9346CR(%x):%x\n", EPROM_CMD, curCR);
2953 //whether need I consider BIT5?
2954 priv->epromtype = (curCR & EPROM_CMD_9356SEL) ? EPROM_93c56 : EPROM_93c46;
2955 RT_TRACE(COMP_INIT, "<===========%s(), epromtype:%d\n", __FUNCTION__, priv->epromtype);
2958 //used to swap endian. as ntohl & htonl are not neccessary to swap endian, so use this instead.
2959 static inline u16 endian_swap(u16* data)
2962 *data = (tmp >> 8) | (tmp << 8);
2967 * Note: Adapter->EEPROMAddressSize should be set before this function call.
2968 * EEPROM address size can be got through GetEEPROMSize8185()
2970 static void rtl8192_read_eeprom_info(struct net_device* dev)
2972 struct r8192_priv *priv = ieee80211_priv(dev);
2976 u8 ICVer8192, ICVer8256;
2978 u16 i,usValue, IC_Version;
2981 u8 offset;//, tmpAFR;
2982 u8 EepromTxPower[100];
2984 u8 bMac_Tmp_Addr[6] = {0x00, 0xe0, 0x4c, 0x00, 0x00, 0x01};
2985 RT_TRACE(COMP_INIT, "====> rtl8192_read_eeprom_info\n");
2988 // TODO: I don't know if we need to apply EF function to EEPROM read function
2990 //2 Read EEPROM ID to make sure autoload is success
2991 EEPROMId = eprom_read(dev, 0);
2992 if( EEPROMId != RTL8190_EEPROM_ID )
2994 RT_TRACE(COMP_ERR, "EEPROM ID is invalid:%x, %x\n", EEPROMId, RTL8190_EEPROM_ID);
2995 priv->AutoloadFailFlag=true;
2999 priv->AutoloadFailFlag=false;
3003 // Assign Chip Version ID
3005 // Read IC Version && Channel Plan
3006 if(!priv->AutoloadFailFlag)
3009 priv->eeprom_vid = eprom_read(dev, (EEPROM_VID >> 1));
3010 priv->eeprom_did = eprom_read(dev, (EEPROM_DID >> 1));
3012 usValue = eprom_read(dev, (u16)(EEPROM_Customer_ID>>1)) >> 8 ;
3013 priv->eeprom_CustomerID = (u8)( usValue & 0xff);
3014 usValue = eprom_read(dev, (EEPROM_ICVersion_ChannelPlan>>1));
3015 priv->eeprom_ChannelPlan = usValue&0xff;
3016 IC_Version = ((usValue&0xff00)>>8);
3019 priv->card_8192_version = (VERSION_8190)(IC_Version);
3022 ICVer8192 = (IC_Version&0xf); //bit0~3; 1:A cut, 2:B cut, 3:C cut...
3023 ICVer8256 = ((IC_Version&0xf0)>>4);//bit4~6, bit7 reserved for other RF chip; 1:A cut, 2:B cut, 3:C cut...
3024 RT_TRACE(COMP_INIT, "\nICVer8192 = 0x%x\n", ICVer8192);
3025 RT_TRACE(COMP_INIT, "\nICVer8256 = 0x%x\n", ICVer8256);
3026 if(ICVer8192 == 0x2) //B-cut
3028 if(ICVer8256 == 0x5) //E-cut
3029 priv->card_8192_version= VERSION_8190_BE;
3033 switch(priv->card_8192_version)
3035 case VERSION_8190_BD:
3036 case VERSION_8190_BE:
3039 priv->card_8192_version = VERSION_8190_BD;
3042 RT_TRACE(COMP_INIT, "\nIC Version = 0x%x\n", priv->card_8192_version);
3046 priv->card_8192_version = VERSION_8190_BD;
3047 priv->eeprom_vid = 0;
3048 priv->eeprom_did = 0;
3049 priv->eeprom_CustomerID = 0;
3050 priv->eeprom_ChannelPlan = 0;
3051 RT_TRACE(COMP_INIT, "\nIC Version = 0x%x\n", 0xff);
3054 RT_TRACE(COMP_INIT, "EEPROM VID = 0x%4x\n", priv->eeprom_vid);
3055 RT_TRACE(COMP_INIT, "EEPROM DID = 0x%4x\n", priv->eeprom_did);
3056 RT_TRACE(COMP_INIT,"EEPROM Customer ID: 0x%2x\n", priv->eeprom_CustomerID);
3058 //2 Read Permanent MAC address
3059 if(!priv->AutoloadFailFlag)
3061 for(i = 0; i < 6; i += 2)
3063 usValue = eprom_read(dev, (u16) ((EEPROM_NODE_ADDRESS_BYTE_0+i)>>1));
3064 *(u16*)(&dev->dev_addr[i]) = usValue;
3067 // when auto load failed, the last address byte set to be a random one.
3068 // added by david woo.2007/11/7
3069 memcpy(dev->dev_addr, bMac_Tmp_Addr, 6);
3071 for(i = 0; i < 6; i++)
3073 Adapter->PermanentAddress[i] = sMacAddr[i];
3074 PlatformEFIOWrite1Byte(Adapter, IDR0+i, sMacAddr[i]);
3079 RT_TRACE(COMP_INIT, "Permanent Address = %02x-%02x-%02x-%02x-%02x-%02x\n",
3080 dev->dev_addr[0], dev->dev_addr[1],
3081 dev->dev_addr[2], dev->dev_addr[3],
3082 dev->dev_addr[4], dev->dev_addr[5]);
3084 //2 TX Power Check EEPROM Fail or not
3085 if(priv->card_8192_version > VERSION_8190_BD) {
3086 priv->bTXPowerDataReadFromEEPORM = true;
3088 priv->bTXPowerDataReadFromEEPORM = false;
3091 // 2007/11/15 MH 8190PCI Default=2T4R, 8192PCIE dafault=1T2R
3092 priv->rf_type = RTL819X_DEFAULT_RF_TYPE;
3094 if(priv->card_8192_version > VERSION_8190_BD)
3096 // Read RF-indication and Tx Power gain index diff of legacy to HT OFDM rate.
3097 if(!priv->AutoloadFailFlag)
3099 tempval = (eprom_read(dev, (EEPROM_RFInd_PowerDiff>>1))) & 0xff;
3100 priv->EEPROMLegacyHTTxPowerDiff = tempval & 0xf; // bit[3:0]
3102 if (tempval&0x80) //RF-indication, bit[7]
3103 priv->rf_type = RF_1T2R;
3105 priv->rf_type = RF_2T4R;
3109 priv->EEPROMLegacyHTTxPowerDiff = EEPROM_Default_LegacyHTTxPowerDiff;
3111 RT_TRACE(COMP_INIT, "EEPROMLegacyHTTxPowerDiff = %d\n",
3112 priv->EEPROMLegacyHTTxPowerDiff);
3114 // Read ThermalMeter from EEPROM
3115 if(!priv->AutoloadFailFlag)
3117 priv->EEPROMThermalMeter = (u8)(((eprom_read(dev, (EEPROM_ThermalMeter>>1))) & 0xff00)>>8);
3121 priv->EEPROMThermalMeter = EEPROM_Default_ThermalMeter;
3123 RT_TRACE(COMP_INIT, "ThermalMeter = %d\n", priv->EEPROMThermalMeter);
3124 //vivi, for tx power track
3125 priv->TSSI_13dBm = priv->EEPROMThermalMeter *100;
3127 if(priv->epromtype == EPROM_93c46)
3129 // Read antenna tx power offset of B/C/D to A and CrystalCap from EEPROM
3130 if(!priv->AutoloadFailFlag)
3132 usValue = eprom_read(dev, (EEPROM_TxPwDiff_CrystalCap>>1));
3133 priv->EEPROMAntPwDiff = (usValue&0x0fff);
3134 priv->EEPROMCrystalCap = (u8)((usValue&0xf000)>>12);
3138 priv->EEPROMAntPwDiff = EEPROM_Default_AntTxPowerDiff;
3139 priv->EEPROMCrystalCap = EEPROM_Default_TxPwDiff_CrystalCap;
3141 RT_TRACE(COMP_INIT, "EEPROMAntPwDiff = %d\n", priv->EEPROMAntPwDiff);
3142 RT_TRACE(COMP_INIT, "EEPROMCrystalCap = %d\n", priv->EEPROMCrystalCap);
3145 // Get per-channel Tx Power Level
3147 for(i=0; i<14; i+=2)
3149 if(!priv->AutoloadFailFlag)
3151 usValue = eprom_read(dev, (u16) ((EEPROM_TxPwIndex_CCK+i)>>1) );
3155 usValue = EEPROM_Default_TxPower;
3157 *((u16*)(&priv->EEPROMTxPowerLevelCCK[i])) = usValue;
3158 RT_TRACE(COMP_INIT,"CCK Tx Power Level, Index %d = 0x%02x\n", i, priv->EEPROMTxPowerLevelCCK[i]);
3159 RT_TRACE(COMP_INIT, "CCK Tx Power Level, Index %d = 0x%02x\n", i+1, priv->EEPROMTxPowerLevelCCK[i+1]);
3161 for(i=0; i<14; i+=2)
3163 if(!priv->AutoloadFailFlag)
3165 usValue = eprom_read(dev, (u16) ((EEPROM_TxPwIndex_OFDM_24G+i)>>1) );
3169 usValue = EEPROM_Default_TxPower;
3171 *((u16*)(&priv->EEPROMTxPowerLevelOFDM24G[i])) = usValue;
3172 RT_TRACE(COMP_INIT, "OFDM 2.4G Tx Power Level, Index %d = 0x%02x\n", i, priv->EEPROMTxPowerLevelOFDM24G[i]);
3173 RT_TRACE(COMP_INIT, "OFDM 2.4G Tx Power Level, Index %d = 0x%02x\n", i+1, priv->EEPROMTxPowerLevelOFDM24G[i+1]);
3176 else if(priv->epromtype== EPROM_93c56)
3179 // Read CrystalCap from EEPROM
3180 if(!priv->AutoloadFailFlag)
3182 priv->EEPROMAntPwDiff = EEPROM_Default_AntTxPowerDiff;
3183 priv->EEPROMCrystalCap = (u8)(((eprom_read(dev, (EEPROM_C56_CrystalCap>>1))) & 0xf000)>>12);
3187 priv->EEPROMAntPwDiff = EEPROM_Default_AntTxPowerDiff;
3188 priv->EEPROMCrystalCap = EEPROM_Default_TxPwDiff_CrystalCap;
3190 RT_TRACE(COMP_INIT,"EEPROMAntPwDiff = %d\n", priv->EEPROMAntPwDiff);
3191 RT_TRACE(COMP_INIT, "EEPROMCrystalCap = %d\n", priv->EEPROMCrystalCap);
3193 // Get Tx Power Level by Channel
3194 if(!priv->AutoloadFailFlag)
3196 // Read Tx power of Channel 1 ~ 14 from EEPROM.
3197 for(i = 0; i < 12; i+=2)
3200 offset = EEPROM_C56_RfA_CCK_Chnl1_TxPwIndex + i;
3202 offset = EEPROM_C56_RfC_CCK_Chnl1_TxPwIndex + i - 6;
3203 usValue = eprom_read(dev, (offset>>1));
3204 *((u16*)(&EepromTxPower[i])) = usValue;
3207 for(i = 0; i < 12; i++)
3210 priv->EEPROMRfACCKChnl1TxPwLevel[i] = EepromTxPower[i];
3211 else if ((i >=3 )&&(i <= 5))
3212 priv->EEPROMRfAOfdmChnlTxPwLevel[i-3] = EepromTxPower[i];
3213 else if ((i >=6 )&&(i <= 8))
3214 priv->EEPROMRfCCCKChnl1TxPwLevel[i-6] = EepromTxPower[i];
3216 priv->EEPROMRfCOfdmChnlTxPwLevel[i-9] = EepromTxPower[i];
3221 priv->EEPROMRfACCKChnl1TxPwLevel[0] = EEPROM_Default_TxPowerLevel;
3222 priv->EEPROMRfACCKChnl1TxPwLevel[1] = EEPROM_Default_TxPowerLevel;
3223 priv->EEPROMRfACCKChnl1TxPwLevel[2] = EEPROM_Default_TxPowerLevel;
3225 priv->EEPROMRfAOfdmChnlTxPwLevel[0] = EEPROM_Default_TxPowerLevel;
3226 priv->EEPROMRfAOfdmChnlTxPwLevel[1] = EEPROM_Default_TxPowerLevel;
3227 priv->EEPROMRfAOfdmChnlTxPwLevel[2] = EEPROM_Default_TxPowerLevel;
3229 priv->EEPROMRfCCCKChnl1TxPwLevel[0] = EEPROM_Default_TxPowerLevel;
3230 priv->EEPROMRfCCCKChnl1TxPwLevel[1] = EEPROM_Default_TxPowerLevel;
3231 priv->EEPROMRfCCCKChnl1TxPwLevel[2] = EEPROM_Default_TxPowerLevel;
3233 priv->EEPROMRfCOfdmChnlTxPwLevel[0] = EEPROM_Default_TxPowerLevel;
3234 priv->EEPROMRfCOfdmChnlTxPwLevel[1] = EEPROM_Default_TxPowerLevel;
3235 priv->EEPROMRfCOfdmChnlTxPwLevel[2] = EEPROM_Default_TxPowerLevel;
3237 RT_TRACE(COMP_INIT, "priv->EEPROMRfACCKChnl1TxPwLevel[0] = 0x%x\n", priv->EEPROMRfACCKChnl1TxPwLevel[0]);
3238 RT_TRACE(COMP_INIT, "priv->EEPROMRfACCKChnl1TxPwLevel[1] = 0x%x\n", priv->EEPROMRfACCKChnl1TxPwLevel[1]);
3239 RT_TRACE(COMP_INIT, "priv->EEPROMRfACCKChnl1TxPwLevel[2] = 0x%x\n", priv->EEPROMRfACCKChnl1TxPwLevel[2]);
3240 RT_TRACE(COMP_INIT, "priv->EEPROMRfAOfdmChnlTxPwLevel[0] = 0x%x\n", priv->EEPROMRfAOfdmChnlTxPwLevel[0]);
3241 RT_TRACE(COMP_INIT, "priv->EEPROMRfAOfdmChnlTxPwLevel[1] = 0x%x\n", priv->EEPROMRfAOfdmChnlTxPwLevel[1]);
3242 RT_TRACE(COMP_INIT, "priv->EEPROMRfAOfdmChnlTxPwLevel[2] = 0x%x\n", priv->EEPROMRfAOfdmChnlTxPwLevel[2]);
3243 RT_TRACE(COMP_INIT, "priv->EEPROMRfCCCKChnl1TxPwLevel[0] = 0x%x\n", priv->EEPROMRfCCCKChnl1TxPwLevel[0]);
3244 RT_TRACE(COMP_INIT, "priv->EEPROMRfCCCKChnl1TxPwLevel[1] = 0x%x\n", priv->EEPROMRfCCCKChnl1TxPwLevel[1]);
3245 RT_TRACE(COMP_INIT, "priv->EEPROMRfCCCKChnl1TxPwLevel[2] = 0x%x\n", priv->EEPROMRfCCCKChnl1TxPwLevel[2]);
3246 RT_TRACE(COMP_INIT, "priv->EEPROMRfCOfdmChnlTxPwLevel[0] = 0x%x\n", priv->EEPROMRfCOfdmChnlTxPwLevel[0]);
3247 RT_TRACE(COMP_INIT, "priv->EEPROMRfCOfdmChnlTxPwLevel[1] = 0x%x\n", priv->EEPROMRfCOfdmChnlTxPwLevel[1]);
3248 RT_TRACE(COMP_INIT, "priv->EEPROMRfCOfdmChnlTxPwLevel[2] = 0x%x\n", priv->EEPROMRfCOfdmChnlTxPwLevel[2]);
3253 // Update HAL variables.
3255 if(priv->epromtype == EPROM_93c46)
3259 priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelCCK[i];
3260 priv->TxPowerLevelOFDM24G[i] = priv->EEPROMTxPowerLevelOFDM24G[i];
3262 priv->LegacyHTTxPowerDiff = priv->EEPROMLegacyHTTxPowerDiff;
3263 // Antenna B gain offset to antenna A, bit0~3
3264 priv->AntennaTxPwDiff[0] = (priv->EEPROMAntPwDiff & 0xf);
3265 // Antenna C gain offset to antenna A, bit4~7
3266 priv->AntennaTxPwDiff[1] = ((priv->EEPROMAntPwDiff & 0xf0)>>4);
3267 // Antenna D gain offset to antenna A, bit8~11
3268 priv->AntennaTxPwDiff[2] = ((priv->EEPROMAntPwDiff & 0xf00)>>8);
3269 // CrystalCap, bit12~15
3270 priv->CrystalCap = priv->EEPROMCrystalCap;
3271 // ThermalMeter, bit0~3 for RFIC1, bit4~7 for RFIC2
3272 priv->ThermalMeter[0] = (priv->EEPROMThermalMeter & 0xf);
3273 priv->ThermalMeter[1] = ((priv->EEPROMThermalMeter & 0xf0)>>4);
3275 else if(priv->epromtype == EPROM_93c56)
3277 //char cck_pwr_diff_a=0, cck_pwr_diff_c=0;
3279 //cck_pwr_diff_a = pHalData->EEPROMRfACCKChnl7TxPwLevel - pHalData->EEPROMRfAOfdmChnlTxPwLevel[1];
3280 //cck_pwr_diff_c = pHalData->EEPROMRfCCCKChnl7TxPwLevel - pHalData->EEPROMRfCOfdmChnlTxPwLevel[1];
3281 for(i=0; i<3; i++) // channel 1~3 use the same Tx Power Level.
3283 priv->TxPowerLevelCCK_A[i] = priv->EEPROMRfACCKChnl1TxPwLevel[0];
3284 priv->TxPowerLevelOFDM24G_A[i] = priv->EEPROMRfAOfdmChnlTxPwLevel[0];
3285 priv->TxPowerLevelCCK_C[i] = priv->EEPROMRfCCCKChnl1TxPwLevel[0];
3286 priv->TxPowerLevelOFDM24G_C[i] = priv->EEPROMRfCOfdmChnlTxPwLevel[0];
3288 for(i=3; i<9; i++) // channel 4~9 use the same Tx Power Level
3290 priv->TxPowerLevelCCK_A[i] = priv->EEPROMRfACCKChnl1TxPwLevel[1];
3291 priv->TxPowerLevelOFDM24G_A[i] = priv->EEPROMRfAOfdmChnlTxPwLevel[1];
3292 priv->TxPowerLevelCCK_C[i] = priv->EEPROMRfCCCKChnl1TxPwLevel[1];
3293 priv->TxPowerLevelOFDM24G_C[i] = priv->EEPROMRfCOfdmChnlTxPwLevel[1];
3295 for(i=9; i<14; i++) // channel 10~14 use the same Tx Power Level
3297 priv->TxPowerLevelCCK_A[i] = priv->EEPROMRfACCKChnl1TxPwLevel[2];
3298 priv->TxPowerLevelOFDM24G_A[i] = priv->EEPROMRfAOfdmChnlTxPwLevel[2];
3299 priv->TxPowerLevelCCK_C[i] = priv->EEPROMRfCCCKChnl1TxPwLevel[2];
3300 priv->TxPowerLevelOFDM24G_C[i] = priv->EEPROMRfCOfdmChnlTxPwLevel[2];
3303 RT_TRACE(COMP_INIT, "priv->TxPowerLevelCCK_A[%d] = 0x%x\n", i, priv->TxPowerLevelCCK_A[i]);
3305 RT_TRACE(COMP_INIT,"priv->TxPowerLevelOFDM24G_A[%d] = 0x%x\n", i, priv->TxPowerLevelOFDM24G_A[i]);
3307 RT_TRACE(COMP_INIT, "priv->TxPowerLevelCCK_C[%d] = 0x%x\n", i, priv->TxPowerLevelCCK_C[i]);
3309 RT_TRACE(COMP_INIT, "priv->TxPowerLevelOFDM24G_C[%d] = 0x%x\n", i, priv->TxPowerLevelOFDM24G_C[i]);
3310 priv->LegacyHTTxPowerDiff = priv->EEPROMLegacyHTTxPowerDiff;
3311 priv->AntennaTxPwDiff[0] = 0;
3312 priv->AntennaTxPwDiff[1] = 0;
3313 priv->AntennaTxPwDiff[2] = 0;
3314 priv->CrystalCap = priv->EEPROMCrystalCap;
3315 // ThermalMeter, bit0~3 for RFIC1, bit4~7 for RFIC2
3316 priv->ThermalMeter[0] = (priv->EEPROMThermalMeter & 0xf);
3317 priv->ThermalMeter[1] = ((priv->EEPROMThermalMeter & 0xf0)>>4);
3321 if(priv->rf_type == RF_1T2R)
3323 RT_TRACE(COMP_INIT, "\n1T2R config\n");
3325 else if (priv->rf_type == RF_2T4R)
3327 RT_TRACE(COMP_INIT, "\n2T4R config\n");
3330 // 2008/01/16 MH We can only know RF type in the function. So we have to init
3331 // DIG RATR table again.
3332 init_rate_adaptive(dev);
3334 //1 Make a copy for following variables and we can change them if we want
3336 priv->rf_chip= RF_8256;
3338 if(priv->RegChannelPlan == 0xf)
3340 priv->ChannelPlan = priv->eeprom_ChannelPlan;
3344 priv->ChannelPlan = priv->RegChannelPlan;
3348 // Used PID and DID to Set CustomerID
3350 if( priv->eeprom_vid == 0x1186 && priv->eeprom_did == 0x3304 )
3352 priv->CustomerID = RT_CID_DLINK;
3355 switch(priv->eeprom_CustomerID)
3357 case EEPROM_CID_DEFAULT:
3358 priv->CustomerID = RT_CID_DEFAULT;
3360 case EEPROM_CID_CAMEO:
3361 priv->CustomerID = RT_CID_819x_CAMEO;
3363 case EEPROM_CID_RUNTOP:
3364 priv->CustomerID = RT_CID_819x_RUNTOP;
3366 case EEPROM_CID_NetCore:
3367 priv->CustomerID = RT_CID_819x_Netcore;
3369 case EEPROM_CID_TOSHIBA: // Merge by Jacken, 2008/01/31
3370 priv->CustomerID = RT_CID_TOSHIBA;
3371 if(priv->eeprom_ChannelPlan&0x80)
3372 priv->ChannelPlan = priv->eeprom_ChannelPlan&0x7f;
3374 priv->ChannelPlan = 0x0;
3375 RT_TRACE(COMP_INIT, "Toshiba ChannelPlan = 0x%x\n",
3378 case EEPROM_CID_Nettronix:
3379 priv->ScanDelay = 100; //cosa add for scan
3380 priv->CustomerID = RT_CID_Nettronix;
3382 case EEPROM_CID_Pronet:
3383 priv->CustomerID = RT_CID_PRONET;
3385 case EEPROM_CID_DLINK:
3386 priv->CustomerID = RT_CID_DLINK;
3389 case EEPROM_CID_WHQL:
3390 //Adapter->bInHctTest = TRUE;//do not supported
3392 //priv->bSupportTurboMode = FALSE;
3393 //priv->bAutoTurboBy8186 = FALSE;
3395 //pMgntInfo->PowerSaveControl.bInactivePs = FALSE;
3396 //pMgntInfo->PowerSaveControl.bIPSModeBackup = FALSE;
3397 //pMgntInfo->PowerSaveControl.bLeisurePs = FALSE;
3401 // value from RegCustomerID
3405 //Avoid the channel plan array overflow, by Bruce, 2007-08-27.
3406 if(priv->ChannelPlan > CHANNEL_PLAN_LEN - 1)
3407 priv->ChannelPlan = 0; //FCC
3409 switch(priv->CustomerID)
3411 case RT_CID_DEFAULT:
3413 priv->LedStrategy = HW_LED;
3416 priv->LedStrategy = SW_LED_MODE1;
3421 case RT_CID_819x_CAMEO:
3422 priv->LedStrategy = SW_LED_MODE2;
3425 case RT_CID_819x_RUNTOP:
3426 priv->LedStrategy = SW_LED_MODE3;
3429 case RT_CID_819x_Netcore:
3430 priv->LedStrategy = SW_LED_MODE4;
3433 case RT_CID_Nettronix:
3434 priv->LedStrategy = SW_LED_MODE5;
3438 priv->LedStrategy = SW_LED_MODE6;
3441 case RT_CID_TOSHIBA: //Modify by Jacken 2008/01/31
3447 priv->LedStrategy = HW_LED;
3450 priv->LedStrategy = SW_LED_MODE1;
3456 //2008.06.03, for WOL
3457 if( priv->eeprom_vid == 0x1186 && priv->eeprom_did == 0x3304)
3458 priv->ieee80211->bSupportRemoteWakeUp = TRUE;
3460 priv->ieee80211->bSupportRemoteWakeUp = FALSE;
3462 RT_TRACE(COMP_INIT, "RegChannelPlan(%d)\n", priv->RegChannelPlan);
3463 RT_TRACE(COMP_INIT, "ChannelPlan = %d \n", priv->ChannelPlan);
3464 RT_TRACE(COMP_INIT, "LedStrategy = %d \n", priv->LedStrategy);
3465 RT_TRACE(COMP_TRACE, "<==== ReadAdapterInfo\n");
3471 short rtl8192_get_channel_map(struct net_device * dev)
3473 struct r8192_priv *priv = ieee80211_priv(dev);
3474 #ifdef ENABLE_DOT11D
3475 if(priv->ChannelPlan> COUNTRY_CODE_GLOBAL_DOMAIN){
3476 printk("rtl8180_init:Error channel plan! Set to default.\n");
3477 priv->ChannelPlan= 0;
3479 RT_TRACE(COMP_INIT, "Channel plan is %d\n",priv->ChannelPlan);
3481 rtl819x_set_channel_map(priv->ChannelPlan, priv);
3484 //Set Default Channel Plan
3486 DMESG("No channels, aborting");
3490 priv->ChannelPlan= 0;//hikaru
3491 // set channels 1..14 allowed in given locale
3492 for (i=1; i<=14; i++) {
3493 (priv->ieee80211->channel_map)[i] = (u8)(ch & 0x01);
3499 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 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 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);
3838 for (i=0; i<QOS_QUEUE_NUM; i++)
3839 write_nic_dword(dev, WDCAPARA_ADD[i], 0x005e4332);
3842 // Switching regulator controller: This is set temporarily.
3843 // It's not sure if this can be removed in the future.
3844 // PJ advised to leave it by default.
3846 write_nic_byte(dev, 0xbe, 0xc0);
3848 //2=======================================================
3849 // Set PHY related configuration defined in MAC register bank
3850 //2=======================================================
3851 rtl8192_phy_configmac(dev);
3853 if (priv->card_8192_version > (u8) VERSION_8190_BD) {
3854 rtl8192_phy_getTxPower(dev);
3855 rtl8192_phy_setTxPower(dev, priv->chan);
3859 tmpvalue = read_nic_byte(dev, IC_VERRSION);
3860 priv->IC_Cut = tmpvalue;
3861 RT_TRACE(COMP_INIT, "priv->IC_Cut = 0x%x\n", priv->IC_Cut);
3862 if(priv->IC_Cut >= IC_VersionCut_D)
3864 //pHalData->bDcut = TRUE;
3865 if(priv->IC_Cut == IC_VersionCut_D)
3866 RT_TRACE(COMP_INIT, "D-cut\n");
3867 if(priv->IC_Cut == IC_VersionCut_E)
3869 RT_TRACE(COMP_INIT, "E-cut\n");
3870 // HW SD suggest that we should not wirte this register too often, so driver
3871 // should readback this register. This register will be modified only when
3877 //pHalData->bDcut = FALSE;
3878 RT_TRACE(COMP_INIT, "Before C-cut\n");
3883 RT_TRACE(COMP_INIT, "Load Firmware!\n");
3884 bfirmwareok = init_firmware(dev);
3885 if(bfirmwareok != true) {
3886 rtStatus = RT_STATUS_FAILURE;
3889 RT_TRACE(COMP_INIT, "Load Firmware finished!\n");
3892 if(priv->ResetProgress == RESET_TYPE_NORESET)
3894 RT_TRACE(COMP_INIT, "RF Config Started!\n");
3895 rtStatus = rtl8192_phy_RFConfig(dev);
3896 if(rtStatus != RT_STATUS_SUCCESS)
3898 RT_TRACE(COMP_ERR, "RF Config failed\n");
3901 RT_TRACE(COMP_INIT, "RF Config Finished!\n");
3903 rtl8192_phy_updateInitGain(dev);
3905 /*---- Set CCK and OFDM Block "ON"----*/
3906 rtl8192_setBBreg(dev, rFPGA0_RFMOD, bCCKEn, 0x1);
3907 rtl8192_setBBreg(dev, rFPGA0_RFMOD, bOFDMEn, 0x1);
3911 write_nic_byte(dev, 0x87, 0x0);
3914 //2008.06.03, for WOL
3915 ucRegRead = read_nic_byte(dev, GPE);
3917 write_nic_byte(dev, GPE, ucRegRead);
3919 ucRegRead = read_nic_byte(dev, GPO);
3921 write_nic_byte(dev, GPO, ucRegRead);
3924 //2=======================================================
3926 //2=======================================================
3930 if(priv->RegRfOff == TRUE)
3931 { // User disable RF via registry.
3932 RT_TRACE((COMP_INIT|COMP_RF|COMP_POWER), "%s(): Turn off RF for RegRfOff ----------\n",__FUNCTION__);
3933 MgntActSet_RF_State(dev, eRfOff, RF_CHANGE_BY_SW);
3934 #if 0//cosa, ask SD3 willis and he doesn't know what is this for
3935 // Those action will be discard in MgntActSet_RF_State because off the same state
3936 for(eRFPath = 0; eRFPath <pHalData->NumTotalRFPath; eRFPath++)
3937 PHY_SetRFReg(Adapter, (RF90_RADIO_PATH_E)eRFPath, 0x4, 0xC00, 0x0);
3940 else if(priv->ieee80211->RfOffReason > RF_CHANGE_BY_PS)
3941 { // H/W or S/W RF OFF before sleep.
3942 RT_TRACE((COMP_INIT|COMP_RF|COMP_POWER), "%s(): Turn off RF for RfOffReason(%d) ----------\n", __FUNCTION__,priv->ieee80211->RfOffReason);
3943 MgntActSet_RF_State(dev, eRfOff, priv->ieee80211->RfOffReason);
3945 else if(priv->ieee80211->RfOffReason >= RF_CHANGE_BY_IPS)
3946 { // H/W or S/W RF OFF before sleep.
3947 RT_TRACE((COMP_INIT|COMP_RF|COMP_POWER), "%s(): Turn off RF for RfOffReason(%d) ----------\n", __FUNCTION__,priv->ieee80211->RfOffReason);
3948 MgntActSet_RF_State(dev, eRfOff, priv->ieee80211->RfOffReason);
3952 RT_TRACE((COMP_INIT|COMP_RF|COMP_POWER), "%s(): RF-ON \n",__FUNCTION__);
3953 priv->ieee80211->eRFPowerState = eRfOn;
3954 priv->ieee80211->RfOffReason = 0;
3955 //DrvIFIndicateCurrentPhyStatus(Adapter);
3957 //Adapter->HalFunc.LedControlHandler(Adapter, LED_CTL_POWER_ON);
3960 // If inactive power mode is enabled, disable rf while in disconnected state.
3961 // But we should still tell upper layer we are in rf on state.
3962 // 2007.07.16, by shien chang.
3964 //if(!Adapter->bInHctTest)
3965 //IPSEnter(Adapter);
3972 // We can force firmware to do RF-R/W
3973 if(priv->ieee80211->FwRWRF)
3974 priv->Rf_Mode = RF_OP_By_FW;
3976 priv->Rf_Mode = RF_OP_By_SW_3wire;
3978 priv->Rf_Mode = RF_OP_By_SW_3wire;
3982 if(priv->ResetProgress == RESET_TYPE_NORESET)
3984 dm_initialize_txpower_tracking(dev);
3986 tmpRegA= rtl8192_QueryBBReg(dev,rOFDM0_XATxIQImbalance,bMaskDWord);
3987 tmpRegC= rtl8192_QueryBBReg(dev,rOFDM0_XCTxIQImbalance,bMaskDWord);
3989 if(priv->rf_type == RF_2T4R){
3990 for(i = 0; i<TxBBGainTableLength; i++)
3992 if(tmpRegA == priv->txbbgain_table[i].txbbgain_value)
3994 priv->rfa_txpowertrackingindex= (u8)i;
3995 priv->rfa_txpowertrackingindex_real= (u8)i;
3996 priv->rfa_txpowertracking_default = priv->rfa_txpowertrackingindex;
4001 for(i = 0; i<TxBBGainTableLength; i++)
4003 if(tmpRegC == priv->txbbgain_table[i].txbbgain_value)
4005 priv->rfc_txpowertrackingindex= (u8)i;
4006 priv->rfc_txpowertrackingindex_real= (u8)i;
4007 priv->rfc_txpowertracking_default = priv->rfc_txpowertrackingindex;
4011 TempCCk = rtl8192_QueryBBReg(dev, rCCK0_TxFilter1, bMaskByte2);
4013 for(i=0 ; i<CCKTxBBGainTableLength ; i++)
4015 if(TempCCk == priv->cck_txbbgain_table[i].ccktxbb_valuearray[0])
4017 priv->CCKPresentAttentuation_20Mdefault =(u8) i;
4021 priv->CCKPresentAttentuation_40Mdefault = 0;
4022 priv->CCKPresentAttentuation_difference = 0;
4023 priv->CCKPresentAttentuation = priv->CCKPresentAttentuation_20Mdefault;
4024 RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex_initial = %d\n", priv->rfa_txpowertrackingindex);
4025 RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex_real__initial = %d\n", priv->rfa_txpowertrackingindex_real);
4026 RT_TRACE(COMP_POWER_TRACKING, "priv->rfc_txpowertrackingindex_initial = %d\n", priv->rfc_txpowertrackingindex);
4027 RT_TRACE(COMP_POWER_TRACKING, "priv->rfc_txpowertrackingindex_real_initial = %d\n", priv->rfc_txpowertrackingindex_real);
4028 RT_TRACE(COMP_POWER_TRACKING, "priv->CCKPresentAttentuation_difference_initial = %d\n", priv->CCKPresentAttentuation_difference);
4029 RT_TRACE(COMP_POWER_TRACKING, "priv->CCKPresentAttentuation_initial = %d\n", priv->CCKPresentAttentuation);
4033 if(priv->ResetProgress == RESET_TYPE_NORESET)
4035 dm_initialize_txpower_tracking(dev);
4037 if(priv->IC_Cut >= IC_VersionCut_D)
4039 tmpRegA= rtl8192_QueryBBReg(dev,rOFDM0_XATxIQImbalance,bMaskDWord);
4040 tmpRegC= rtl8192_QueryBBReg(dev,rOFDM0_XCTxIQImbalance,bMaskDWord);
4041 for(i = 0; i<TxBBGainTableLength; i++)
4043 if(tmpRegA == priv->txbbgain_table[i].txbbgain_value)
4045 priv->rfa_txpowertrackingindex= (u8)i;
4046 priv->rfa_txpowertrackingindex_real= (u8)i;
4047 priv->rfa_txpowertracking_default = priv->rfa_txpowertrackingindex;
4052 TempCCk = rtl8192_QueryBBReg(dev, rCCK0_TxFilter1, bMaskByte2);
4054 for(i=0 ; i<CCKTxBBGainTableLength ; i++)
4056 if(TempCCk == priv->cck_txbbgain_table[i].ccktxbb_valuearray[0])
4058 priv->CCKPresentAttentuation_20Mdefault =(u8) i;
4062 priv->CCKPresentAttentuation_40Mdefault = 0;
4063 priv->CCKPresentAttentuation_difference = 0;
4064 priv->CCKPresentAttentuation = priv->CCKPresentAttentuation_20Mdefault;
4065 RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex_initial = %d\n", priv->rfa_txpowertrackingindex);
4066 RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex_real__initial = %d\n", priv->rfa_txpowertrackingindex_real);
4067 RT_TRACE(COMP_POWER_TRACKING, "priv->CCKPresentAttentuation_difference_initial = %d\n", priv->CCKPresentAttentuation_difference);
4068 RT_TRACE(COMP_POWER_TRACKING, "priv->CCKPresentAttentuation_initial = %d\n", priv->CCKPresentAttentuation);
4069 priv->btxpower_tracking = FALSE;//TEMPLY DISABLE
4074 rtl8192_irq_enable(dev);
4075 priv->being_init_adapter = false;
4080 void rtl8192_prepare_beacon(struct r8192_priv *priv)
4082 struct sk_buff *skb;
4083 //unsigned long flags;
4086 skb = ieee80211_get_beacon(priv->ieee80211);
4087 tcb_desc = (cb_desc *)(skb->cb + 8);
4088 //printk("===========> %s\n", __FUNCTION__);
4089 //spin_lock_irqsave(&priv->tx_lock,flags);
4090 /* prepare misc info for the beacon xmit */
4091 tcb_desc->queue_index = BEACON_QUEUE;
4092 /* IBSS does not support HT yet, use 1M defautly */
4093 tcb_desc->data_rate = 2;
4094 tcb_desc->RATRIndex = 7;
4095 tcb_desc->bTxDisableRateFallBack = 1;
4096 tcb_desc->bTxUseDriverAssingedRate = 1;
4098 skb_push(skb, priv->ieee80211->tx_headroom);
4100 rtl8192_tx(priv->ieee80211->dev,skb);
4102 //spin_unlock_irqrestore (&priv->tx_lock, flags);
4106 void rtl8192_beacon_tx_enable(struct net_device *dev)
4108 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
4110 rtl8180_set_mode(dev,EPROM_CMD_CONFIG);
4111 #ifdef CONFIG_RTL8185B
4112 priv->dma_poll_stop_mask &= ~(TPPOLLSTOP_BQ);MgntQuery_MgntFrameTxRateMgntQuery_MgntFrameTxRate
4113 write_nic_byte(dev,TPPollStop, priv->dma_poll_mask);
4115 priv->dma_poll_mask &=~(1<<TX_DMA_STOP_BEACON_SHIFT);
4116 write_nic_byte(dev,TX_DMA_POLLING,priv->dma_poll_mask);
4118 rtl8180_set_mode(dev,EPROM_CMD_NORMAL);
4123 /* this configures registers for beacon tx and enables it via
4124 * rtl8192_beacon_tx_enable(). rtl8192_beacon_tx_disable() might
4125 * be used to stop beacon transmission
4127 void rtl8192_start_beacon(struct net_device *dev)
4129 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
4130 struct ieee80211_network *net = &priv->ieee80211->current_network;
4135 DMESG("Enabling beacon TX");
4136 //rtl8192_prepare_beacon(dev);
4137 rtl8192_irq_disable(dev);
4138 //rtl8192_beacon_tx_enable(dev);
4141 write_nic_word(dev, ATIMWND, 2);
4143 /* Beacon interval (in unit of TU) */
4144 write_nic_word(dev, BCN_INTERVAL, net->beacon_interval);
4147 * DrvErlyInt (in unit of TU).
4148 * (Time to send interrupt to notify driver to c
4149 * hange beacon content)
4151 write_nic_word(dev, BCN_DRV_EARLY_INT, 10);
4154 * BcnDMATIM(in unit of us).
4155 * Indicates the time before TBTT to perform beacon queue DMA
4157 write_nic_word(dev, BCN_DMATIME, 256);
4160 * Force beacon frame transmission even after receiving
4161 * beacon frame from other ad hoc STA
4163 write_nic_byte(dev, BCN_ERR_THRESH, 100);
4165 /* Set CW and IFS */
4166 BcnTimeCfg |= BcnCW<<BCN_TCFG_CW_SHIFT;
4167 BcnTimeCfg |= BcnIFS<<BCN_TCFG_IFS;
4168 write_nic_word(dev, BCN_TCFG, BcnTimeCfg);
4171 /* enable the interrupt for ad-hoc process */
4172 rtl8192_irq_enable(dev);
4174 /***************************************************************************
4175 -------------------------------NET STUFF---------------------------
4176 ***************************************************************************/
4178 static struct net_device_stats *rtl8192_stats(struct net_device *dev)
4180 struct r8192_priv *priv = ieee80211_priv(dev);
4182 return &priv->ieee80211->stats;
4188 bool HalTxCheckStuck8190Pci(struct net_device *dev)
4190 u16 RegTxCounter = read_nic_word(dev, 0x128);
4191 struct r8192_priv *priv = ieee80211_priv(dev);
4192 bool bStuck = FALSE;
4193 RT_TRACE(COMP_RESET,"%s():RegTxCounter is %d,TxCounter is %d\n",__FUNCTION__,RegTxCounter,priv->TxCounter);
4194 if(priv->TxCounter==RegTxCounter)
4197 priv->TxCounter = RegTxCounter;
4203 * <Assumption: RT_TX_SPINLOCK is acquired.>
4204 * First added: 2006.11.19 by emily
4207 TxCheckStuck(struct net_device *dev)
4209 struct r8192_priv *priv = ieee80211_priv(dev);
4211 ptx_ring head=NULL,tail=NULL,txring = NULL;
4212 u8 ResetThreshold = NIC_SEND_HANG_THRESHOLD_POWERSAVE;
4213 bool bCheckFwTxCnt = false;
4214 //unsigned long flags;
4217 // Decide Stuch threshold according to current power save mode
4219 //printk("++++++++++++>%s()\n",__FUNCTION__);
4220 switch (priv->ieee80211->dot11PowerSaveMode)
4222 // The threshold value may required to be adjusted .
4223 case eActive: // Active/Continuous access.
4224 ResetThreshold = NIC_SEND_HANG_THRESHOLD_NORMAL;
4226 case eMaxPs: // Max power save mode.
4227 ResetThreshold = NIC_SEND_HANG_THRESHOLD_POWERSAVE;
4229 case eFastPs: // Fast power save mode.
4230 ResetThreshold = NIC_SEND_HANG_THRESHOLD_POWERSAVE;
4235 // Check whether specific tcb has been queued for a specific time
4237 for(QueueID = 0; QueueID < MAX_TX_QUEUE; QueueID++)
4241 if(QueueID == TXCMD_QUEUE)
4246 tail=priv->txmapringtail;
4247 head=priv->txmapringhead;
4251 tail=priv->txbkpringtail;
4252 head=priv->txbkpringhead;
4256 tail=priv->txbepringtail;
4257 head=priv->txbepringhead;
4261 tail=priv->txvipringtail;
4262 head=priv->txvipringhead;
4266 tail=priv->txvopringtail;
4267 head=priv->txvopringhead;
4282 RT_TRACE(COMP_ERR,"%s():txring is NULL , BUG!\n",__FUNCTION__);
4285 txring->nStuckCount++;
4287 if(txring->nStuckCount > ResetThreshold)
4289 RT_TRACE( COMP_RESET, "<== TxCheckStuck()\n" );
4290 return RESET_TYPE_NORMAL;
4293 bCheckFwTxCnt = TRUE;
4299 if(HalTxCheckStuck8190Pci(dev))
4301 RT_TRACE(COMP_RESET, "TxCheckStuck(): Fw indicates no Tx condition! \n");
4302 return RESET_TYPE_SILENT;
4306 return RESET_TYPE_NORESET;
4310 bool HalRxCheckStuck8190Pci(struct net_device *dev)
4312 struct r8192_priv *priv = ieee80211_priv(dev);
4313 u16 RegRxCounter = read_nic_word(dev, 0x130);
4314 bool bStuck = FALSE;
4315 static u8 rx_chk_cnt = 0;
4316 RT_TRACE(COMP_RESET,"%s(): RegRxCounter is %d,RxCounter is %d\n",__FUNCTION__,RegRxCounter,priv->RxCounter);
4317 // If rssi is small, we should check rx for long time because of bad rx.
4318 // or maybe it will continuous silent reset every 2 seconds.
4320 if(priv->undecorated_smoothed_pwdb >= (RateAdaptiveTH_High+5))
4322 rx_chk_cnt = 0; //high rssi, check rx stuck right now.
4324 else if(priv->undecorated_smoothed_pwdb < (RateAdaptiveTH_High+5) &&
4325 ((priv->CurrentChannelBW!=HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb>=RateAdaptiveTH_Low_40M) ||
4326 (priv->CurrentChannelBW==HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb>=RateAdaptiveTH_Low_20M)) )
4338 else if(((priv->CurrentChannelBW!=HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb<RateAdaptiveTH_Low_40M) ||
4339 (priv->CurrentChannelBW==HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb<RateAdaptiveTH_Low_20M)) &&
4340 priv->undecorated_smoothed_pwdb >= VeryLowRSSI)
4344 //DbgPrint("RSSI < %d && RSSI >= %d, no check this time \n", RateAdaptiveTH_Low, VeryLowRSSI);
4350 //DbgPrint("RSSI < %d && RSSI >= %d, check this time \n", RateAdaptiveTH_Low, VeryLowRSSI);
4357 //DbgPrint("RSSI <= %d, no check this time \n", VeryLowRSSI);
4363 //DbgPrint("RSSI <= %d, check this time \n", VeryLowRSSI);
4372 if(priv->RxCounter==RegRxCounter)
4375 priv->RxCounter = RegRxCounter;
4380 RESET_TYPE RxCheckStuck(struct net_device *dev)
4383 if(HalRxCheckStuck8190Pci(dev))
4385 RT_TRACE(COMP_RESET, "RxStuck Condition\n");
4386 return RESET_TYPE_SILENT;
4389 return RESET_TYPE_NORESET;
4393 rtl819x_ifcheck_resetornot(struct net_device *dev)
4395 struct r8192_priv *priv = ieee80211_priv(dev);
4396 RESET_TYPE TxResetType = RESET_TYPE_NORESET;
4397 RESET_TYPE RxResetType = RESET_TYPE_NORESET;
4398 RT_RF_POWER_STATE rfState;
4400 rfState = priv->ieee80211->eRFPowerState;
4402 TxResetType = TxCheckStuck(dev);
4404 if( rfState != eRfOff &&
4405 /*ADAPTER_TEST_STATUS_FLAG(Adapter, ADAPTER_STATUS_FW_DOWNLOAD_FAILURE)) &&*/
4406 (priv->ieee80211->iw_mode != IW_MODE_ADHOC))
4408 // If driver is in the status of firmware download failure , driver skips RF initialization and RF is
4409 // in turned off state. Driver should check whether Rx stuck and do silent reset. And
4410 // if driver is in firmware download failure status, driver should initialize RF in the following
4411 // silent reset procedure Emily, 2008.01.21
4413 // Driver should not check RX stuck in IBSS mode because it is required to
4414 // set Check BSSID in order to send beacon, however, if check BSSID is
4415 // set, STA cannot hear any packet a all. Emily, 2008.04.12
4416 RxResetType = RxCheckStuck(dev);
4420 RT_TRACE(COMP_RESET,"%s(): TxResetType is %d, RxResetType is %d\n",__FUNCTION__,TxResetType,RxResetType);
4421 if(TxResetType==RESET_TYPE_NORMAL || RxResetType==RESET_TYPE_NORMAL)
4422 return RESET_TYPE_NORMAL;
4423 else if(TxResetType==RESET_TYPE_SILENT || RxResetType==RESET_TYPE_SILENT)
4424 return RESET_TYPE_SILENT;
4426 return RESET_TYPE_NORESET;
4431 void CamRestoreAllEntry( struct net_device *dev)
4434 struct r8192_priv *priv = ieee80211_priv(dev);
4435 u8* MacAddr = priv->ieee80211->current_network.bssid;
4437 static u8 CAM_CONST_ADDR[4][6] = {
4438 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
4439 {0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
4440 {0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
4441 {0x00, 0x00, 0x00, 0x00, 0x00, 0x03}};
4442 static u8 CAM_CONST_BROAD[] =
4443 {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
4445 RT_TRACE(COMP_SEC, "CamRestoreAllEntry: \n");
4448 if ((priv->ieee80211->pairwise_key_type == KEY_TYPE_WEP40)||
4449 (priv->ieee80211->pairwise_key_type == KEY_TYPE_WEP104))
4452 for(EntryId=0; EntryId<4; EntryId++)
4455 MacAddr = CAM_CONST_ADDR[EntryId];
4459 priv->ieee80211->pairwise_key_type,
4467 else if(priv->ieee80211->pairwise_key_type == KEY_TYPE_TKIP)
4471 if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
4475 priv->ieee80211->pairwise_key_type,
4483 priv->ieee80211->pairwise_key_type,
4489 else if(priv->ieee80211->pairwise_key_type == KEY_TYPE_CCMP)
4493 if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
4497 priv->ieee80211->pairwise_key_type,
4505 priv->ieee80211->pairwise_key_type,
4514 if(priv->ieee80211->group_key_type == KEY_TYPE_TKIP)
4516 MacAddr = CAM_CONST_BROAD;
4517 for(EntryId=1 ; EntryId<4 ; EntryId++)
4523 priv->ieee80211->group_key_type,
4529 if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
4533 priv->ieee80211->group_key_type,
4538 else if(priv->ieee80211->group_key_type == KEY_TYPE_CCMP)
4540 MacAddr = CAM_CONST_BROAD;
4541 for(EntryId=1; EntryId<4 ; EntryId++)
4547 priv->ieee80211->group_key_type,
4554 if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
4558 priv->ieee80211->group_key_type,
4565 void rtl8192_cancel_deferred_work(struct r8192_priv* priv);
4566 int _rtl8192_up(struct net_device *dev);
4569 * This function is used to fix Tx/Rx stop bug temporarily.
4570 * This function will do "system reset" to NIC when Tx or Rx is stuck.
4571 * The method checking Tx/Rx stuck of this function is supported by FW,
4572 * which reports Tx and Rx counter to register 0x128 and 0x130.
4574 void rtl819x_ifsilentreset(struct net_device *dev)
4576 struct r8192_priv *priv = ieee80211_priv(dev);
4578 int reset_status = 0;
4579 struct ieee80211_device *ieee = priv->ieee80211;
4582 // 2007.07.20. If we need to check CCK stop, please uncomment this line.
4583 //bStuck = Adapter->HalFunc.CheckHWStopHandler(Adapter);
4585 if(priv->ResetProgress==RESET_TYPE_NORESET)
4589 RT_TRACE(COMP_RESET,"=========>Reset progress!! \n");
4591 // Set the variable for reset.
4592 priv->ResetProgress = RESET_TYPE_SILENT;
4593 // rtl8192_close(dev);
4595 down(&priv->wx_sem);
4598 RT_TRACE(COMP_ERR,"%s():the driver is not up! return\n",__FUNCTION__);
4603 RT_TRACE(COMP_RESET,"%s():======>start to down the driver\n",__FUNCTION__);
4604 if(!netif_queue_stopped(dev))
4605 netif_stop_queue(dev);
4607 dm_backup_dynamic_mechanism_state(dev);
4609 rtl8192_irq_disable(dev);
4610 rtl8192_cancel_deferred_work(priv);
4612 del_timer_sync(&priv->watch_dog_timer);
4613 ieee->sync_scan_hurryup = 1;
4614 if(ieee->state == IEEE80211_LINKED)
4616 down(&ieee->wx_sem);
4617 printk("ieee->state is IEEE80211_LINKED\n");
4618 ieee80211_stop_send_beacons(priv->ieee80211);
4619 del_timer_sync(&ieee->associate_timer);
4620 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
4621 cancel_delayed_work(&ieee->associate_retry_wq);
4623 ieee80211_stop_scan(ieee);
4624 netif_carrier_off(dev);
4628 printk("ieee->state is NOT LINKED\n");
4629 ieee80211_softmac_stop_protocol(priv->ieee80211);
4631 rtl8192_rtx_disable(dev);
4633 RT_TRACE(COMP_RESET,"%s():<==========down process is finished\n",__FUNCTION__);
4634 RT_TRACE(COMP_RESET,"%s():===========>start to up the driver\n",__FUNCTION__);
4635 reset_status = _rtl8192_up(dev);
4637 RT_TRACE(COMP_RESET,"%s():<===========up process is finished\n",__FUNCTION__);
4638 if(reset_status == -1)
4647 RT_TRACE(COMP_ERR," ERR!!! %s(): Reset Failed!!\n",__FUNCTION__);
4651 ieee->is_silent_reset = 1;
4653 EnableHWSecurityConfig8192(dev);
4655 if(ieee->state == IEEE80211_LINKED && ieee->iw_mode == IW_MODE_INFRA)
4657 ieee->set_chan(ieee->dev, ieee->current_network.channel);
4660 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
4661 queue_work(ieee->wq, &ieee->associate_complete_wq);
4663 schedule_task(&ieee->associate_complete_wq);
4668 else if(ieee->state == IEEE80211_LINKED && ieee->iw_mode == IW_MODE_ADHOC)
4670 ieee->set_chan(ieee->dev, ieee->current_network.channel);
4671 ieee->link_change(ieee->dev);
4673 // notify_wx_assoc_event(ieee);
4675 ieee80211_start_send_beacons(ieee);
4677 if (ieee->data_hard_resume)
4678 ieee->data_hard_resume(ieee->dev);
4679 netif_carrier_on(ieee->dev);
4683 CamRestoreAllEntry(dev);
4685 // Restore the previous setting for all dynamic mechanism
4686 dm_restore_dynamic_mechanism_state(dev);
4688 priv->ResetProgress = RESET_TYPE_NORESET;
4689 priv->reset_count++;
4691 priv->bForcedSilentReset =false;
4692 priv->bResetInProgress = false;
4694 // For test --> force write UFWP.
4695 write_nic_byte(dev, UFWP, 1);
4696 RT_TRACE(COMP_RESET, "Reset finished!! ====>[%d]\n", priv->reset_count);
4702 void InactivePsWorkItemCallback(struct net_device *dev)
4704 struct r8192_priv *priv = ieee80211_priv(dev);
4705 PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->ieee80211->PowerSaveControl));
4708 RT_TRACE(COMP_POWER, "InactivePsWorkItemCallback() ---------> \n");
4710 // This flag "bSwRfProcessing", indicates the status of IPS procedure, should be set if the IPS workitem
4711 // is really scheduled.
4712 // The old code, sets this flag before scheduling the IPS workitem and however, at the same time the
4713 // previous IPS workitem did not end yet, fails to schedule the current workitem. Thus, bSwRfProcessing
4714 // blocks the IPS procedure of switching RF.
4715 // By Bruce, 2007-12-25.
4717 pPSC->bSwRfProcessing = TRUE;
4719 RT_TRACE(COMP_RF, "InactivePsWorkItemCallback(): Set RF to %s.\n", \
4720 pPSC->eInactivePowerState == eRfOff?"OFF":"ON");
4723 MgntActSet_RF_State(dev, pPSC->eInactivePowerState, RF_CHANGE_BY_IPS);
4726 // To solve CAM values miss in RF OFF, rewrite CAM values after RF ON. By Bruce, 2007-09-20.
4729 if(pPSC->eInactivePowerState == eRfOn)
4730 CamRestoreAllEntry(dev);
4732 pPSC->bSwRfProcessing = FALSE;
4733 RT_TRACE(COMP_POWER, "InactivePsWorkItemCallback() <--------- \n");
4738 // Enter the inactive power save mode. RF will be off
4739 // 2007.08.17, by shien chang.
4742 IPSEnter(struct net_device *dev)
4744 struct r8192_priv *priv = ieee80211_priv(dev);
4745 PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->ieee80211->PowerSaveControl));
4746 RT_RF_POWER_STATE rtState;
4748 if (pPSC->bInactivePs)
4750 rtState = priv->ieee80211->eRFPowerState;
4752 // Added by Bruce, 2007-12-25.
4753 // Do not enter IPS in the following conditions:
4754 // (1) RF is already OFF or Sleep
4755 // (2) bSwRfProcessing (indicates the IPS is still under going)
4756 // (3) Connectted (only disconnected can trigger IPS)
4757 // (4) IBSS (send Beacon)
4758 // (5) AP mode (send Beacon)
4760 if (rtState == eRfOn && !pPSC->bSwRfProcessing
4761 && (priv->ieee80211->state != IEEE80211_LINKED) )
4763 RT_TRACE(COMP_RF,"IPSEnter(): Turn off RF.\n");
4764 pPSC->eInactivePowerState = eRfOff;
4765 // queue_work(priv->priv_wq,&(pPSC->InactivePsWorkItem));
4766 InactivePsWorkItemCallback(dev);
4773 // Leave the inactive power save mode, RF will be on.
4774 // 2007.08.17, by shien chang.
4777 IPSLeave(struct net_device *dev)
4779 struct r8192_priv *priv = ieee80211_priv(dev);
4780 PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->ieee80211->PowerSaveControl));
4781 RT_RF_POWER_STATE rtState;
4783 if (pPSC->bInactivePs)
4785 rtState = priv->ieee80211->eRFPowerState;
4786 if (rtState != eRfOn && !pPSC->bSwRfProcessing && priv->ieee80211->RfOffReason <= RF_CHANGE_BY_IPS)
4788 RT_TRACE(COMP_POWER, "IPSLeave(): Turn on RF.\n");
4789 pPSC->eInactivePowerState = eRfOn;
4790 // queue_work(priv->priv_wq,&(pPSC->InactivePsWorkItem));
4791 InactivePsWorkItemCallback(dev);
4796 void CAM_read_entry(
4797 struct net_device *dev,
4801 u32 target_command=0;
4802 u32 target_content=0;
4806 // printk("=======>start read CAM\n");
4807 for(entry_i=0;entry_i<CAM_CONTENT_COUNT;entry_i++)
4809 // polling bit, and No Write enable, and address
4810 target_command= entry_i+CAM_CONTENT_COUNT*iIndex;
4811 target_command= target_command | BIT31;
4813 //Check polling bit is clear
4818 ulStatus = read_nic_dword(dev, RWCAM);
4819 if(ulStatus & BIT31){
4827 write_nic_dword(dev, RWCAM, target_command);
4828 RT_TRACE(COMP_SEC,"CAM_read_entry(): WRITE A0: %x \n",target_command);
4829 // printk("CAM_read_entry(): WRITE A0: %lx \n",target_command);
4830 target_content = read_nic_dword(dev, RCAMO);
4831 RT_TRACE(COMP_SEC, "CAM_read_entry(): WRITE A8: %x \n",target_content);
4832 // printk("CAM_read_entry(): WRITE A8: %lx \n",target_content);
4837 void rtl819x_update_rxcounts(
4838 struct r8192_priv *priv,
4847 *TotalRxDataNum = 0;
4849 SlotIndex = (priv->ieee80211->LinkDetectInfo.SlotIndex++)%(priv->ieee80211->LinkDetectInfo.SlotNum);
4850 priv->ieee80211->LinkDetectInfo.RxBcnNum[SlotIndex] = priv->ieee80211->LinkDetectInfo.NumRecvBcnInPeriod;
4851 priv->ieee80211->LinkDetectInfo.RxDataNum[SlotIndex] = priv->ieee80211->LinkDetectInfo.NumRecvDataInPeriod;
4852 for( i=0; i<priv->ieee80211->LinkDetectInfo.SlotNum; i++ ){
4853 *TotalRxBcnNum += priv->ieee80211->LinkDetectInfo.RxBcnNum[i];
4854 *TotalRxDataNum += priv->ieee80211->LinkDetectInfo.RxDataNum[i];
4859 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
4860 extern void rtl819x_watchdog_wqcallback(struct work_struct *work)
4862 struct delayed_work *dwork = container_of(work,struct delayed_work,work);
4863 struct r8192_priv *priv = container_of(dwork,struct r8192_priv,watch_dog_wq);
4864 struct net_device *dev = priv->ieee80211->dev;
4866 extern void rtl819x_watchdog_wqcallback(struct net_device *dev)
4868 struct r8192_priv *priv = ieee80211_priv(dev);
4870 struct ieee80211_device* ieee = priv->ieee80211;
4871 RESET_TYPE ResetType = RESET_TYPE_NORESET;
4872 static u8 check_reset_cnt=0;
4873 unsigned long flags;
4874 bool bBusyTraffic = false;
4875 static u8 last_time = 0;
4878 hal_dm_watchdog(dev);
4880 // printk("watch_dog ENABLE_IPS\n");
4881 if(ieee->actscanning == false){
4882 if((ieee->iw_mode != IW_MODE_ADHOC) && (ieee->state == IEEE80211_NOLINK) && (ieee->beinretry == false) && (ieee->eRFPowerState == eRfOn) && !ieee->is_set_key){
4883 if(ieee->PowerSaveControl.ReturnPoint == IPS_CALLBACK_NONE){
4884 printk("====================>haha:IPSEnter()\n");
4886 //ieee80211_stop_scan(priv->ieee80211);
4891 {//to get busy traffic condition
4892 if(ieee->state == IEEE80211_LINKED)
4894 if( ieee->LinkDetectInfo.NumRxOkInPeriod> 666 ||
4895 ieee->LinkDetectInfo.NumTxOkInPeriod> 666 ) {
4896 bBusyTraffic = true;
4900 ieee->LinkDetectInfo.NumRxOkInPeriod = 0;
4901 ieee->LinkDetectInfo.NumTxOkInPeriod = 0;
4902 ieee->LinkDetectInfo.bBusyTraffic = bBusyTraffic;
4906 //added by amy for AP roaming
4909 if(ieee->state == IEEE80211_LINKED && ieee->iw_mode == IW_MODE_INFRA)
4911 u32 TotalRxBcnNum = 0;
4912 u32 TotalRxDataNum = 0;
4914 rtl819x_update_rxcounts(priv, &TotalRxBcnNum, &TotalRxDataNum);
4915 if((TotalRxBcnNum+TotalRxDataNum) == 0)
4917 if( ieee->eRFPowerState == eRfOff)
4918 RT_TRACE(COMP_ERR,"========>%s()\n",__FUNCTION__);
4919 printk("===>%s(): AP is power off,connect another one\n",__FUNCTION__);
4920 // Dot11d_Reset(dev);
4921 ieee->state = IEEE80211_ASSOCIATING;
4922 notify_wx_assoc_event(priv->ieee80211);
4923 RemovePeerTS(priv->ieee80211,priv->ieee80211->current_network.bssid);
4924 ieee->is_roaming = true;
4925 ieee->is_set_key = false;
4926 ieee->link_change(dev);
4927 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
4928 queue_work(ieee->wq, &ieee->associate_procedure_wq);
4930 schedule_task(&ieee->associate_procedure_wq);
4934 ieee->LinkDetectInfo.NumRecvBcnInPeriod=0;
4935 ieee->LinkDetectInfo.NumRecvDataInPeriod=0;
4938 // CAM_read_entry(dev,0);
4939 //check if reset the driver
4940 spin_lock_irqsave(&priv->tx_lock,flags);
4941 if(check_reset_cnt++ >= 3 && !ieee->is_roaming && (last_time != 1))
4943 ResetType = rtl819x_ifcheck_resetornot(dev);
4944 check_reset_cnt = 3;
4945 //DbgPrint("Start to check silent reset\n");
4947 spin_unlock_irqrestore(&priv->tx_lock,flags);
4948 if(!priv->bDisableNormalResetCheck && ResetType == RESET_TYPE_NORMAL)
4950 priv->ResetProgress = RESET_TYPE_NORMAL;
4951 RT_TRACE(COMP_RESET,"%s(): NOMAL RESET\n",__FUNCTION__);
4954 /* disable silent reset temply 2008.9.11*/
4956 if( ((priv->force_reset) || (!priv->bDisableNormalResetCheck && ResetType==RESET_TYPE_SILENT))) // This is control by OID set in Pomelo
4959 rtl819x_ifsilentreset(dev);
4964 priv->force_reset = false;
4965 priv->bForcedSilentReset = false;
4966 priv->bResetInProgress = false;
4967 RT_TRACE(COMP_TRACE, " <==RtUsbCheckForHangWorkItemCallback()\n");
4971 void watch_dog_timer_callback(unsigned long data)
4973 struct r8192_priv *priv = ieee80211_priv((struct net_device *) data);
4974 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
4975 queue_delayed_work(priv->priv_wq,&priv->watch_dog_wq,0);
4977 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
4978 schedule_task(&priv->watch_dog_wq);
4980 queue_work(priv->priv_wq,&priv->watch_dog_wq);
4983 mod_timer(&priv->watch_dog_timer, jiffies + MSECS(IEEE80211_WATCH_DOG_TIME));
4986 int _rtl8192_up(struct net_device *dev)
4988 struct r8192_priv *priv = ieee80211_priv(dev);
4990 RT_STATUS init_status = RT_STATUS_SUCCESS;
4992 priv->ieee80211->ieee_up=1;
4993 RT_TRACE(COMP_INIT, "Bringing up iface");
4995 init_status = rtl8192_adapter_start(dev);
4996 if(init_status != RT_STATUS_SUCCESS)
4998 RT_TRACE(COMP_ERR,"ERR!!! %s(): initialization is failed!\n",__FUNCTION__);
5001 RT_TRACE(COMP_INIT, "start adapter finished\n");
5003 if(priv->ieee80211->eRFPowerState!=eRfOn)
5004 MgntActSet_RF_State(dev, eRfOn, priv->ieee80211->RfOffReason);
5006 if(priv->ieee80211->state != IEEE80211_LINKED)
5007 ieee80211_softmac_start_protocol(priv->ieee80211);
5008 ieee80211_reset_queue(priv->ieee80211);
5009 watch_dog_timer_callback((unsigned long) dev);
5010 if(!netif_queue_stopped(dev))
5011 netif_start_queue(dev);
5013 netif_wake_queue(dev);
5019 int rtl8192_open(struct net_device *dev)
5021 struct r8192_priv *priv = ieee80211_priv(dev);
5024 down(&priv->wx_sem);
5025 ret = rtl8192_up(dev);
5032 int rtl8192_up(struct net_device *dev)
5034 struct r8192_priv *priv = ieee80211_priv(dev);
5036 if (priv->up == 1) return -1;
5038 return _rtl8192_up(dev);
5042 int rtl8192_close(struct net_device *dev)
5044 struct r8192_priv *priv = ieee80211_priv(dev);
5047 down(&priv->wx_sem);
5049 ret = rtl8192_down(dev);
5057 int rtl8192_down(struct net_device *dev)
5059 struct r8192_priv *priv = ieee80211_priv(dev);
5065 if (priv->up == 0) return -1;
5068 priv->ieee80211->ieee_up = 0;
5069 RT_TRACE(COMP_DOWN, "==========>%s()\n", __FUNCTION__);
5071 if (!netif_queue_stopped(dev))
5072 netif_stop_queue(dev);
5074 rtl8192_irq_disable(dev);
5076 if(!priv->ieee80211->bSupportRemoteWakeUp) {
5077 MgntActSet_RF_State(dev, eRfOff, RF_CHANGE_BY_INIT);
5078 // 2006.11.30. System reset bit
5079 ulRegRead = read_nic_dword(dev, CPU_GEN);
5080 ulRegRead|=CPU_GEN_SYSTEM_RESET;
5081 write_nic_dword(dev, CPU_GEN, ulRegRead);
5083 //2008.06.03 for WOL
5084 write_nic_dword(dev, WFCRC0, 0xffffffff);
5085 write_nic_dword(dev, WFCRC1, 0xffffffff);
5086 write_nic_dword(dev, WFCRC2, 0xffffffff);
5089 ucRegRead = read_nic_byte(dev, GPO);
5091 write_nic_byte(dev, GPO, ucRegRead);
5093 //Write PMR register
5094 write_nic_byte(dev, PMR, 0x5);
5095 //Disable tx, enanble rx
5096 write_nic_byte(dev, MacBlkCtrl, 0xa);
5099 // flush_scheduled_work();
5100 rtl8192_cancel_deferred_work(priv);
5102 del_timer_sync(&priv->watch_dog_timer);
5104 ieee80211_softmac_stop_protocol(priv->ieee80211);
5106 MgntActSet_RF_State(dev, eRfOff, RF_CHANGE_BY_INIT);
5108 rtl8192_rtx_disable(dev);
5109 memset(&priv->ieee80211->current_network, 0 , offsetof(struct ieee80211_network, list));
5111 RT_TRACE(COMP_DOWN, "<==========%s()\n", __FUNCTION__);
5117 void rtl8192_commit(struct net_device *dev)
5119 struct r8192_priv *priv = ieee80211_priv(dev);
5121 if (priv->up == 0) return ;
5124 ieee80211_softmac_stop_protocol(priv->ieee80211);
5126 rtl8192_irq_disable(dev);
5127 rtl8192_rtx_disable(dev);
5132 void rtl8192_restart(struct net_device *dev)
5134 struct r8192_priv *priv = ieee80211_priv(dev);
5136 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
5137 void rtl8192_restart(struct work_struct *work)
5139 struct r8192_priv *priv = container_of(work, struct r8192_priv, reset_wq);
5140 struct net_device *dev = priv->ieee80211->dev;
5142 void rtl8192_restart(struct net_device *dev)
5145 struct r8192_priv *priv = ieee80211_priv(dev);
5148 down(&priv->wx_sem);
5150 rtl8192_commit(dev);
5155 static void r8192_set_multicast(struct net_device *dev)
5157 struct r8192_priv *priv = ieee80211_priv(dev);
5160 //down(&priv->wx_sem);
5164 promisc = (dev->flags & IFF_PROMISC) ? 1:0;
5166 if (promisc != priv->promisc) {
5168 // rtl8192_commit(dev);
5171 priv->promisc = promisc;
5173 //schedule_work(&priv->reset_wq);
5174 //up(&priv->wx_sem);
5178 int r8192_set_mac_adr(struct net_device *dev, void *mac)
5180 struct r8192_priv *priv = ieee80211_priv(dev);
5181 struct sockaddr *addr = mac;
5183 down(&priv->wx_sem);
5185 memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
5187 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
5188 schedule_work(&priv->reset_wq);
5190 schedule_task(&priv->reset_wq);
5197 /* based on ipw2200 driver */
5198 int rtl8192_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
5200 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
5201 struct iwreq *wrq = (struct iwreq *)rq;
5203 struct ieee80211_device *ieee = priv->ieee80211;
5205 u8 broadcast_addr[6] = {0xff,0xff,0xff,0xff,0xff,0xff};
5206 struct iw_point *p = &wrq->u.data;
5207 struct ieee_param *ipw = NULL;//(struct ieee_param *)wrq->u.data.pointer;
5209 down(&priv->wx_sem);
5212 if (p->length < sizeof(struct ieee_param) || !p->pointer){
5217 ipw = (struct ieee_param *)kmalloc(p->length, GFP_KERNEL);
5222 if (copy_from_user(ipw, p->pointer, p->length)) {
5229 case RTL_IOCTL_WPA_SUPPLICANT:
5230 //parse here for HW security
5231 if (ipw->cmd == IEEE_CMD_SET_ENCRYPTION)
5233 if (ipw->u.crypt.set_tx)
5235 if (strcmp(ipw->u.crypt.alg, "CCMP") == 0)
5236 ieee->pairwise_key_type = KEY_TYPE_CCMP;
5237 else if (strcmp(ipw->u.crypt.alg, "TKIP") == 0)
5238 ieee->pairwise_key_type = KEY_TYPE_TKIP;
5239 else if (strcmp(ipw->u.crypt.alg, "WEP") == 0)
5241 if (ipw->u.crypt.key_len == 13)
5242 ieee->pairwise_key_type = KEY_TYPE_WEP104;
5243 else if (ipw->u.crypt.key_len == 5)
5244 ieee->pairwise_key_type = KEY_TYPE_WEP40;
5247 ieee->pairwise_key_type = KEY_TYPE_NA;
5249 if (ieee->pairwise_key_type)
5251 memcpy((u8*)key, ipw->u.crypt.key, 16);
5252 EnableHWSecurityConfig8192(dev);
5253 //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!
5255 setKey(dev, 4, ipw->u.crypt.idx, ieee->pairwise_key_type, (u8*)ieee->ap_mac_addr, 0, key);
5256 if (ieee->auth_mode != 2) //LEAP WEP will never set this.
5257 setKey(dev, ipw->u.crypt.idx, ipw->u.crypt.idx, ieee->pairwise_key_type, (u8*)ieee->ap_mac_addr, 0, key);
5259 if ((ieee->pairwise_key_type == KEY_TYPE_CCMP) && ieee->pHTInfo->bCurrentHTSupport){
5260 write_nic_byte(dev, 0x173, 1); //fix aes bug
5264 else //if (ipw->u.crypt.idx) //group key use idx > 0
5266 memcpy((u8*)key, ipw->u.crypt.key, 16);
5267 if (strcmp(ipw->u.crypt.alg, "CCMP") == 0)
5268 ieee->group_key_type= KEY_TYPE_CCMP;
5269 else if (strcmp(ipw->u.crypt.alg, "TKIP") == 0)
5270 ieee->group_key_type = KEY_TYPE_TKIP;
5271 else if (strcmp(ipw->u.crypt.alg, "WEP") == 0)
5273 if (ipw->u.crypt.key_len == 13)
5274 ieee->group_key_type = KEY_TYPE_WEP104;
5275 else if (ipw->u.crypt.key_len == 5)
5276 ieee->group_key_type = KEY_TYPE_WEP40;
5279 ieee->group_key_type = KEY_TYPE_NA;
5281 if (ieee->group_key_type)
5285 ipw->u.crypt.idx, //KeyIndex
5286 ieee->group_key_type, //KeyType
5287 broadcast_addr, //MacAddr
5297 printk("@@ wrq->u pointer = ");
5298 for(i=0;i<wrq->u.data.length;i++){
5299 if(i%10==0) printk("\n");
5300 printk( "%8x|", ((u32*)wrq->u.data.pointer)[i] );
5304 #endif /*JOHN_DEBUG*/
5305 ret = ieee80211_wpa_supplicant_ioctl(priv->ieee80211, &wrq->u.data);
5320 u8 HwRateToMRate90(bool bIsHT, u8 rate)
5326 case DESC90_RATE1M: ret_rate = MGN_1M; break;
5327 case DESC90_RATE2M: ret_rate = MGN_2M; break;
5328 case DESC90_RATE5_5M: ret_rate = MGN_5_5M; break;
5329 case DESC90_RATE11M: ret_rate = MGN_11M; break;
5330 case DESC90_RATE6M: ret_rate = MGN_6M; break;
5331 case DESC90_RATE9M: ret_rate = MGN_9M; break;
5332 case DESC90_RATE12M: ret_rate = MGN_12M; break;
5333 case DESC90_RATE18M: ret_rate = MGN_18M; break;
5334 case DESC90_RATE24M: ret_rate = MGN_24M; break;
5335 case DESC90_RATE36M: ret_rate = MGN_36M; break;
5336 case DESC90_RATE48M: ret_rate = MGN_48M; break;
5337 case DESC90_RATE54M: ret_rate = MGN_54M; break;
5340 RT_TRACE(COMP_RECV, "HwRateToMRate90(): Non supported Rate [%x], bIsHT = %d!!!\n", rate, bIsHT);
5346 case DESC90_RATEMCS0: ret_rate = MGN_MCS0; break;
5347 case DESC90_RATEMCS1: ret_rate = MGN_MCS1; break;
5348 case DESC90_RATEMCS2: ret_rate = MGN_MCS2; break;
5349 case DESC90_RATEMCS3: ret_rate = MGN_MCS3; break;
5350 case DESC90_RATEMCS4: ret_rate = MGN_MCS4; break;
5351 case DESC90_RATEMCS5: ret_rate = MGN_MCS5; break;
5352 case DESC90_RATEMCS6: ret_rate = MGN_MCS6; break;
5353 case DESC90_RATEMCS7: ret_rate = MGN_MCS7; break;
5354 case DESC90_RATEMCS8: ret_rate = MGN_MCS8; break;
5355 case DESC90_RATEMCS9: ret_rate = MGN_MCS9; break;
5356 case DESC90_RATEMCS10: ret_rate = MGN_MCS10; break;
5357 case DESC90_RATEMCS11: ret_rate = MGN_MCS11; break;
5358 case DESC90_RATEMCS12: ret_rate = MGN_MCS12; break;
5359 case DESC90_RATEMCS13: ret_rate = MGN_MCS13; break;
5360 case DESC90_RATEMCS14: ret_rate = MGN_MCS14; break;
5361 case DESC90_RATEMCS15: ret_rate = MGN_MCS15; break;
5362 case DESC90_RATEMCS32: ret_rate = (0x80|0x20); break;
5365 RT_TRACE(COMP_RECV, "HwRateToMRate90(): Non supported Rate [%x], bIsHT = %d!!!\n",rate, bIsHT);
5374 * Function: UpdateRxPktTimeStamp
5375 * Overview: Recored down the TSF time stamp when receiving a packet
5383 * (pRfd->Status.TimeStampHigh is updated)
5384 * (pRfd->Status.TimeStampLow is updated)
5388 void UpdateRxPktTimeStamp8190 (struct net_device *dev, struct ieee80211_rx_stats *stats)
5390 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
5392 if(stats->bIsAMPDU && !stats->bFirstMPDU) {
5393 stats->mac_time[0] = priv->LastRxDescTSFLow;
5394 stats->mac_time[1] = priv->LastRxDescTSFHigh;
5396 priv->LastRxDescTSFLow = stats->mac_time[0];
5397 priv->LastRxDescTSFHigh = stats->mac_time[1];
5401 long rtl819x_translate_todbm(u8 signal_strength_index )// 0-100 index.
5403 long signal_power; // in dBm.
5405 // Translate to dBm (x=0.5y-95).
5406 signal_power = (long)((signal_strength_index + 1) >> 1);
5409 return signal_power;
5414 // Update Rx signal related information in the packet reeived
5415 // to RxStats. User application can query RxStats to realize
5416 // current Rx signal status.
5419 // In normal operation, user only care about the information of the BSS
5420 // and we shall invoke this function if the packet received is from the BSS.
5423 rtl819x_update_rxsignalstatistics8190pci(
5424 struct r8192_priv * priv,
5425 struct ieee80211_rx_stats * pprevious_stats
5430 //2 <ToDo> Update Rx Statistics (such as signal strength and signal quality).
5433 if(priv->stats.recv_signal_power == 0)
5434 priv->stats.recv_signal_power = pprevious_stats->RecvSignalPower;
5436 // To avoid the past result restricting the statistics sensitivity, weight the current power (5/6) to speed up the
5437 // reaction of smoothed Signal Power.
5438 if(pprevious_stats->RecvSignalPower > priv->stats.recv_signal_power)
5440 else if(pprevious_stats->RecvSignalPower < priv->stats.recv_signal_power)
5443 // We need more correct power of received packets and the "SignalStrength" of RxStats have been beautified or translated,
5444 // so we record the correct power in Dbm here. By Bruce, 2008-03-07.
5446 priv->stats.recv_signal_power = (priv->stats.recv_signal_power * 5 + pprevious_stats->RecvSignalPower + weighting) / 6;
5450 rtl8190_process_cck_rxpathsel(
5451 struct r8192_priv * priv,
5452 struct ieee80211_rx_stats * pprevious_stats
5455 #ifdef RTL8190P //Only 90P 2T4R need to check
5456 char last_cck_adc_pwdb[4]={0,0,0,0};
5458 //cosa add for Rx path selection
5459 if(priv->rf_type == RF_2T4R && DM_RxPathSelTable.Enable)
5461 if(pprevious_stats->bIsCCK &&
5462 (pprevious_stats->bPacketToSelf ||pprevious_stats->bPacketBeacon))
5464 /* record the cck adc_pwdb to the sliding window. */
5465 if(priv->stats.cck_adc_pwdb.TotalNum++ >= PHY_RSSI_SLID_WIN_MAX)
5467 priv->stats.cck_adc_pwdb.TotalNum = PHY_RSSI_SLID_WIN_MAX;
5468 for(i=RF90_PATH_A; i<RF90_PATH_MAX; i++)
5470 last_cck_adc_pwdb[i] = priv->stats.cck_adc_pwdb.elements[i][priv->stats.cck_adc_pwdb.index];
5471 priv->stats.cck_adc_pwdb.TotalVal[i] -= last_cck_adc_pwdb[i];
5474 for(i=RF90_PATH_A; i<RF90_PATH_MAX; i++)
5476 priv->stats.cck_adc_pwdb.TotalVal[i] += pprevious_stats->cck_adc_pwdb[i];
5477 priv->stats.cck_adc_pwdb.elements[i][priv->stats.cck_adc_pwdb.index] = pprevious_stats->cck_adc_pwdb[i];
5479 priv->stats.cck_adc_pwdb.index++;
5480 if(priv->stats.cck_adc_pwdb.index >= PHY_RSSI_SLID_WIN_MAX)
5481 priv->stats.cck_adc_pwdb.index = 0;
5483 for(i=RF90_PATH_A; i<RF90_PATH_MAX; i++)
5485 DM_RxPathSelTable.cck_pwdb_sta[i] = priv->stats.cck_adc_pwdb.TotalVal[i]/priv->stats.cck_adc_pwdb.TotalNum;
5488 for(i=RF90_PATH_A; i<RF90_PATH_MAX; i++)
5490 if(pprevious_stats->cck_adc_pwdb[i] > (char)priv->undecorated_smoothed_cck_adc_pwdb[i])
5492 priv->undecorated_smoothed_cck_adc_pwdb[i] =
5493 ( (priv->undecorated_smoothed_cck_adc_pwdb[i]*(Rx_Smooth_Factor-1)) +
5494 (pprevious_stats->cck_adc_pwdb[i])) /(Rx_Smooth_Factor);
5495 priv->undecorated_smoothed_cck_adc_pwdb[i] = priv->undecorated_smoothed_cck_adc_pwdb[i] + 1;
5499 priv->undecorated_smoothed_cck_adc_pwdb[i] =
5500 ( (priv->undecorated_smoothed_cck_adc_pwdb[i]*(Rx_Smooth_Factor-1)) +
5501 (pprevious_stats->cck_adc_pwdb[i])) /(Rx_Smooth_Factor);
5510 /* 2008/01/22 MH We can not delcare RSSI/EVM total value of sliding window to
5511 be a local static. Otherwise, it may increase when we return from S3/S4. The
5512 value will be kept in memory or disk. We must delcare the value in adapter
5513 and it will be reinitialized when return from S3/S4. */
5514 void rtl8192_process_phyinfo(struct r8192_priv * priv, u8* buffer,struct ieee80211_rx_stats * pprevious_stats, struct ieee80211_rx_stats * pcurrent_stats)
5516 bool bcheck = false;
5518 u32 nspatial_stream, tmp_val;
5520 static u32 slide_rssi_index=0, slide_rssi_statistics=0;
5521 static u32 slide_evm_index=0, slide_evm_statistics=0;
5522 static u32 last_rssi=0, last_evm=0;
5523 //cosa add for rx path selection
5524 // static long slide_cck_adc_pwdb_index=0, slide_cck_adc_pwdb_statistics=0;
5525 // static char last_cck_adc_pwdb[4]={0,0,0,0};
5526 //cosa add for beacon rssi smoothing
5527 static u32 slide_beacon_adc_pwdb_index=0, slide_beacon_adc_pwdb_statistics=0;
5528 static u32 last_beacon_adc_pwdb=0;
5530 struct ieee80211_hdr_3addr *hdr;
5532 unsigned int frag,seq;
5533 hdr = (struct ieee80211_hdr_3addr *)buffer;
5534 sc = le16_to_cpu(hdr->seq_ctl);
5535 frag = WLAN_GET_SEQ_FRAG(sc);
5536 seq = WLAN_GET_SEQ_SEQ(sc);
5537 //cosa add 04292008 to record the sequence number
5538 pcurrent_stats->Seq_Num = seq;
5540 // Check whether we should take the previous packet into accounting
5542 if(!pprevious_stats->bIsAMPDU)
5544 // if previous packet is not aggregated packet
5548 //remve for that we don't use AMPDU to calculate PWDB,because the reported PWDB of some AP is fault.
5550 // if previous packet is aggregated packet, and current packet
5552 // (2) is the first packet of one AMPDU
5553 // that means the previous packet is the last one aggregated packet
5554 if( !pcurrent_stats->bIsAMPDU || pcurrent_stats->bFirstMPDU)
5559 if(slide_rssi_statistics++ >= PHY_RSSI_SLID_WIN_MAX)
5561 slide_rssi_statistics = PHY_RSSI_SLID_WIN_MAX;
5562 last_rssi = priv->stats.slide_signal_strength[slide_rssi_index];
5563 priv->stats.slide_rssi_total -= last_rssi;
5565 priv->stats.slide_rssi_total += pprevious_stats->SignalStrength;
5567 priv->stats.slide_signal_strength[slide_rssi_index++] = pprevious_stats->SignalStrength;
5568 if(slide_rssi_index >= PHY_RSSI_SLID_WIN_MAX)
5569 slide_rssi_index = 0;
5571 // <1> Showed on UI for user, in dbm
5572 tmp_val = priv->stats.slide_rssi_total/slide_rssi_statistics;
5573 priv->stats.signal_strength = rtl819x_translate_todbm((u8)tmp_val);
5574 pcurrent_stats->rssi = priv->stats.signal_strength;
5576 // If the previous packet does not match the criteria, neglect it
5578 if(!pprevious_stats->bPacketMatchBSSID)
5580 if(!pprevious_stats->bToSelfBA)
5587 rtl8190_process_cck_rxpathsel(priv,pprevious_stats);
5592 priv->stats.num_process_phyinfo++;
5594 /* record the general signal strength to the sliding window. */
5595 if(slide_rssi_statistics++ >= PHY_RSSI_SLID_WIN_MAX)
5597 slide_rssi_statistics = PHY_RSSI_SLID_WIN_MAX;
5598 last_rssi = priv->stats.slide_signal_strength[slide_rssi_index];
5599 priv->stats.slide_rssi_total -= last_rssi;
5601 priv->stats.slide_rssi_total += pprevious_stats->SignalStrength;
5603 priv->stats.slide_signal_strength[slide_rssi_index++] = pprevious_stats->SignalStrength;
5604 if(slide_rssi_index >= PHY_RSSI_SLID_WIN_MAX)
5605 slide_rssi_index = 0;
5607 // <1> Showed on UI for user, in dbm
5608 tmp_val = priv->stats.slide_rssi_total/slide_rssi_statistics;
5609 priv->stats.signal_strength = rtl819x_translate_todbm((u8)tmp_val);
5612 // <2> Showed on UI for engineering
5613 // hardware does not provide rssi information for each rf path in CCK
5614 if(!pprevious_stats->bIsCCK && pprevious_stats->bPacketToSelf)
5616 for (rfpath = RF90_PATH_A; rfpath < RF90_PATH_C; rfpath++)
5618 if (!rtl8192_phy_CheckIsLegalRFPath(priv->ieee80211->dev, rfpath))
5620 RT_TRACE(COMP_DBG,"Jacken -> pPreviousstats->RxMIMOSignalStrength[rfpath] = %d \n" ,pprevious_stats->RxMIMOSignalStrength[rfpath] );
5621 //Fixed by Jacken 2008-03-20
5622 if(priv->stats.rx_rssi_percentage[rfpath] == 0)
5624 priv->stats.rx_rssi_percentage[rfpath] = pprevious_stats->RxMIMOSignalStrength[rfpath];
5625 //DbgPrint("MIMO RSSI initialize \n");
5627 if(pprevious_stats->RxMIMOSignalStrength[rfpath] > priv->stats.rx_rssi_percentage[rfpath])
5629 priv->stats.rx_rssi_percentage[rfpath] =
5630 ( (priv->stats.rx_rssi_percentage[rfpath]*(Rx_Smooth_Factor-1)) +
5631 (pprevious_stats->RxMIMOSignalStrength[rfpath])) /(Rx_Smooth_Factor);
5632 priv->stats.rx_rssi_percentage[rfpath] = priv->stats.rx_rssi_percentage[rfpath] + 1;
5636 priv->stats.rx_rssi_percentage[rfpath] =
5637 ( (priv->stats.rx_rssi_percentage[rfpath]*(Rx_Smooth_Factor-1)) +
5638 (pprevious_stats->RxMIMOSignalStrength[rfpath])) /(Rx_Smooth_Factor);
5640 RT_TRACE(COMP_DBG,"Jacken -> priv->RxStats.RxRSSIPercentage[rfPath] = %d \n" ,priv->stats.rx_rssi_percentage[rfpath] );
5648 //cosa add for beacon rssi smoothing by average.
5649 if(pprevious_stats->bPacketBeacon)
5651 /* record the beacon pwdb to the sliding window. */
5652 if(slide_beacon_adc_pwdb_statistics++ >= PHY_Beacon_RSSI_SLID_WIN_MAX)
5654 slide_beacon_adc_pwdb_statistics = PHY_Beacon_RSSI_SLID_WIN_MAX;
5655 last_beacon_adc_pwdb = priv->stats.Slide_Beacon_pwdb[slide_beacon_adc_pwdb_index];
5656 priv->stats.Slide_Beacon_Total -= last_beacon_adc_pwdb;
5657 //DbgPrint("slide_beacon_adc_pwdb_index = %d, last_beacon_adc_pwdb = %d, Adapter->RxStats.Slide_Beacon_Total = %d\n",
5658 // slide_beacon_adc_pwdb_index, last_beacon_adc_pwdb, Adapter->RxStats.Slide_Beacon_Total);
5660 priv->stats.Slide_Beacon_Total += pprevious_stats->RxPWDBAll;
5661 priv->stats.Slide_Beacon_pwdb[slide_beacon_adc_pwdb_index] = pprevious_stats->RxPWDBAll;
5662 //DbgPrint("slide_beacon_adc_pwdb_index = %d, pPreviousRfd->Status.RxPWDBAll = %d\n", slide_beacon_adc_pwdb_index, pPreviousRfd->Status.RxPWDBAll);
5663 slide_beacon_adc_pwdb_index++;
5664 if(slide_beacon_adc_pwdb_index >= PHY_Beacon_RSSI_SLID_WIN_MAX)
5665 slide_beacon_adc_pwdb_index = 0;
5666 pprevious_stats->RxPWDBAll = priv->stats.Slide_Beacon_Total/slide_beacon_adc_pwdb_statistics;
5667 if(pprevious_stats->RxPWDBAll >= 3)
5668 pprevious_stats->RxPWDBAll -= 3;
5671 RT_TRACE(COMP_RXDESC, "Smooth %s PWDB = %d\n",
5672 pprevious_stats->bIsCCK? "CCK": "OFDM",
5673 pprevious_stats->RxPWDBAll);
5675 if(pprevious_stats->bPacketToSelf || pprevious_stats->bPacketBeacon || pprevious_stats->bToSelfBA)
5677 if(priv->undecorated_smoothed_pwdb < 0) // initialize
5679 priv->undecorated_smoothed_pwdb = pprevious_stats->RxPWDBAll;
5680 //DbgPrint("First pwdb initialize \n");
5683 if(pprevious_stats->RxPWDBAll > (u32)priv->undecorated_smoothed_pwdb)
5685 priv->undecorated_smoothed_pwdb =
5686 ( ((priv->undecorated_smoothed_pwdb)*(Rx_Smooth_Factor-1)) +
5687 (pprevious_stats->RxPWDBAll)) /(Rx_Smooth_Factor);
5688 priv->undecorated_smoothed_pwdb = priv->undecorated_smoothed_pwdb + 1;
5692 priv->undecorated_smoothed_pwdb =
5693 ( ((priv->undecorated_smoothed_pwdb)*(Rx_Smooth_Factor-1)) +
5694 (pprevious_stats->RxPWDBAll)) /(Rx_Smooth_Factor);
5697 //Fixed by Jacken 2008-03-20
5698 if(pPreviousRfd->Status.RxPWDBAll > (u32)pHalData->UndecoratedSmoothedPWDB)
5700 pHalData->UndecoratedSmoothedPWDB =
5701 ( ((pHalData->UndecoratedSmoothedPWDB)* 5) + (pPreviousRfd->Status.RxPWDBAll)) / 6;
5702 pHalData->UndecoratedSmoothedPWDB = pHalData->UndecoratedSmoothedPWDB + 1;
5706 pHalData->UndecoratedSmoothedPWDB =
5707 ( ((pHalData->UndecoratedSmoothedPWDB)* 5) + (pPreviousRfd->Status.RxPWDBAll)) / 6;
5710 rtl819x_update_rxsignalstatistics8190pci(priv,pprevious_stats);
5716 /* record the general EVM to the sliding window. */
5717 if(pprevious_stats->SignalQuality == 0)
5722 if(pprevious_stats->bPacketToSelf || pprevious_stats->bPacketBeacon || pprevious_stats->bToSelfBA){
5723 if(slide_evm_statistics++ >= PHY_RSSI_SLID_WIN_MAX){
5724 slide_evm_statistics = PHY_RSSI_SLID_WIN_MAX;
5725 last_evm = priv->stats.slide_evm[slide_evm_index];
5726 priv->stats.slide_evm_total -= last_evm;
5729 priv->stats.slide_evm_total += pprevious_stats->SignalQuality;
5731 priv->stats.slide_evm[slide_evm_index++] = pprevious_stats->SignalQuality;
5732 if(slide_evm_index >= PHY_RSSI_SLID_WIN_MAX)
5733 slide_evm_index = 0;
5735 // <1> Showed on UI for user, in percentage.
5736 tmp_val = priv->stats.slide_evm_total/slide_evm_statistics;
5737 priv->stats.signal_quality = tmp_val;
5738 //cosa add 10/11/2007, Showed on UI for user in Windows Vista, for Link quality.
5739 priv->stats.last_signal_strength_inpercent = tmp_val;
5742 // <2> Showed on UI for engineering
5743 if(pprevious_stats->bPacketToSelf || pprevious_stats->bPacketBeacon || pprevious_stats->bToSelfBA)
5745 for(nspatial_stream = 0; nspatial_stream<2 ; nspatial_stream++) // 2 spatial stream
5747 if(pprevious_stats->RxMIMOSignalQuality[nspatial_stream] != -1)
5749 if(priv->stats.rx_evm_percentage[nspatial_stream] == 0) // initialize
5751 priv->stats.rx_evm_percentage[nspatial_stream] = pprevious_stats->RxMIMOSignalQuality[nspatial_stream];
5753 priv->stats.rx_evm_percentage[nspatial_stream] =
5754 ( (priv->stats.rx_evm_percentage[nspatial_stream]* (Rx_Smooth_Factor-1)) +
5755 (pprevious_stats->RxMIMOSignalQuality[nspatial_stream]* 1)) / (Rx_Smooth_Factor);
5763 /*-----------------------------------------------------------------------------
5764 * Function: rtl819x_query_rxpwrpercentage()
5768 * Input: char antpower
5772 * Return: 0-100 percentage
5776 * 05/26/2008 amy Create Version 0 porting from windows code.
5778 *---------------------------------------------------------------------------*/
5779 static u8 rtl819x_query_rxpwrpercentage(
5783 if ((antpower <= -100) || (antpower >= 20))
5787 else if (antpower >= 0)
5793 return (100+antpower);
5796 } /* QueryRxPwrPercentage */
5799 rtl819x_evm_dbtopercentage(
5811 ret_val = 0 - ret_val;
5820 // We want good-looking for signal strength/quality
5821 // 2007/7/19 01:09, by cosa.
5824 rtl819x_signal_scale_mapping(
5830 // Step 1. Scale mapping.
5831 if(currsig >= 61 && currsig <= 100)
5833 retsig = 90 + ((currsig - 60) / 4);
5835 else if(currsig >= 41 && currsig <= 60)
5837 retsig = 78 + ((currsig - 40) / 2);
5839 else if(currsig >= 31 && currsig <= 40)
5841 retsig = 66 + (currsig - 30);
5843 else if(currsig >= 21 && currsig <= 30)
5845 retsig = 54 + (currsig - 20);
5847 else if(currsig >= 5 && currsig <= 20)
5849 retsig = 42 + (((currsig - 5) * 2) / 3);
5851 else if(currsig == 4)
5855 else if(currsig == 3)
5859 else if(currsig == 2)
5863 else if(currsig == 1)
5875 static void rtl8192_query_rxphystatus(
5876 struct r8192_priv * priv,
5877 struct ieee80211_rx_stats * pstats,
5878 prx_desc_819x_pci pdesc,
5879 prx_fwinfo_819x_pci pdrvinfo,
5880 struct ieee80211_rx_stats * precord_stats,
5881 bool bpacket_match_bssid,
5882 bool bpacket_toself,
5887 //PRT_RFD_STATUS pRtRfdStatus = &(pRfd->Status);
5888 phy_sts_ofdm_819xpci_t* pofdm_buf;
5889 phy_sts_cck_819xpci_t * pcck_buf;
5890 phy_ofdm_rx_status_rxsc_sgien_exintfflag* prxsc;
5892 u8 i,max_spatial_stream, tmp_rxsnr, tmp_rxevm, rxsc_sgien_exflg;
5893 char rx_pwr[4], rx_pwr_all=0;
5894 //long rx_avg_pwr = 0;
5895 char rx_snrX, rx_evmX;
5897 u32 RSSI, total_rssi=0;//, total_evm=0;
5898 // long signal_strength_index = 0;
5902 /* 2007/07/04 MH For OFDM RSSI. For high power or not. */
5903 static u8 check_reg824 = 0;
5904 static u32 reg824_bit9 = 0;
5906 priv->stats.numqry_phystatus++;
5908 is_cck_rate = rx_hal_is_cck_rate(pdrvinfo);
5910 // Record it for next packet processing
5911 memset(precord_stats, 0, sizeof(struct ieee80211_rx_stats));
5912 pstats->bPacketMatchBSSID = precord_stats->bPacketMatchBSSID = bpacket_match_bssid;
5913 pstats->bPacketToSelf = precord_stats->bPacketToSelf = bpacket_toself;
5914 pstats->bIsCCK = precord_stats->bIsCCK = is_cck_rate;//RX_HAL_IS_CCK_RATE(pDrvInfo);
5915 pstats->bPacketBeacon = precord_stats->bPacketBeacon = bPacketBeacon;
5916 pstats->bToSelfBA = precord_stats->bToSelfBA = bToSelfBA;
5917 /*2007.08.30 requested by SD3 Jerry */
5918 if(check_reg824 == 0)
5920 reg824_bit9 = rtl8192_QueryBBReg(priv->ieee80211->dev, rFPGA0_XA_HSSIParameter2, 0x200);
5925 prxpkt = (u8*)pdrvinfo;
5927 /* Move pointer to the 16th bytes. Phy status start address. */
5928 prxpkt += sizeof(rx_fwinfo_819x_pci);
5930 /* Initial the cck and ofdm buffer pointer */
5931 pcck_buf = (phy_sts_cck_819xpci_t *)prxpkt;
5932 pofdm_buf = (phy_sts_ofdm_819xpci_t *)prxpkt;
5934 pstats->RxMIMOSignalQuality[0] = -1;
5935 pstats->RxMIMOSignalQuality[1] = -1;
5936 precord_stats->RxMIMOSignalQuality[0] = -1;
5937 precord_stats->RxMIMOSignalQuality[1] = -1;
5942 // (1)Hardware does not provide RSSI for CCK
5946 // (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive)
5948 u8 report;//, cck_agc_rpt;
5951 char cck_adc_pwdb[4];
5953 priv->stats.numqry_phystatusCCK++;
5955 #ifdef RTL8190P //Only 90P 2T4R need to check
5956 if(priv->rf_type == RF_2T4R && DM_RxPathSelTable.Enable && bpacket_match_bssid)
5958 for(i=RF90_PATH_A; i<RF90_PATH_MAX; i++)
5960 tmp_pwdb = pcck_buf->adc_pwdb_X[i];
5961 cck_adc_pwdb[i] = (char)tmp_pwdb;
5962 cck_adc_pwdb[i] /= 2;
5963 pstats->cck_adc_pwdb[i] = precord_stats->cck_adc_pwdb[i] = cck_adc_pwdb[i];
5964 //DbgPrint("RF-%d tmp_pwdb = 0x%x, cck_adc_pwdb = %d", i, tmp_pwdb, cck_adc_pwdb[i]);
5971 report = pcck_buf->cck_agc_rpt & 0xc0;
5975 //Fixed by Jacken from Bryant 2008-03-20
5976 //Original value is -38 , -26 , -14 , -2
5977 //Fixed value is -35 , -23 , -11 , 6
5979 rx_pwr_all = -35 - (pcck_buf->cck_agc_rpt & 0x3e);
5982 rx_pwr_all = -23 - (pcck_buf->cck_agc_rpt & 0x3e);
5985 rx_pwr_all = -11 - (pcck_buf->cck_agc_rpt & 0x3e);
5988 rx_pwr_all = 8 - (pcck_buf->cck_agc_rpt & 0x3e);
5994 report = pcck_buf->cck_agc_rpt & 0x60;
5999 rx_pwr_all = -35 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1) ;
6002 rx_pwr_all = -23 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1);
6005 rx_pwr_all = -11 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1) ;
6008 rx_pwr_all = -8 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1) ;
6013 pwdb_all = rtl819x_query_rxpwrpercentage(rx_pwr_all);
6014 pstats->RxPWDBAll = precord_stats->RxPWDBAll = pwdb_all;
6015 pstats->RecvSignalPower = rx_pwr_all;
6018 // (3) Get Signal Quality (EVM)
6020 if(bpacket_match_bssid)
6024 if(pstats->RxPWDBAll > 40)
6029 sq = pcck_buf->sq_rpt;
6031 if(pcck_buf->sq_rpt > 64)
6033 else if (pcck_buf->sq_rpt < 20)
6036 sq = ((64-sq) * 100) / 44;
6038 pstats->SignalQuality = precord_stats->SignalQuality = sq;
6039 pstats->RxMIMOSignalQuality[0] = precord_stats->RxMIMOSignalQuality[0] = sq;
6040 pstats->RxMIMOSignalQuality[1] = precord_stats->RxMIMOSignalQuality[1] = -1;
6045 priv->stats.numqry_phystatusHT++;
6047 // (1)Get RSSI for HT rate
6049 for(i=RF90_PATH_A; i<RF90_PATH_MAX; i++)
6051 // 2008/01/30 MH we will judge RF RX path now.
6052 if (priv->brfpath_rxenable[i])
6057 //Fixed by Jacken from Bryant 2008-03-20
6058 //Original value is 106
6059 #ifdef RTL8190P //Modify by Jacken 2008/03/31
6060 rx_pwr[i] = ((pofdm_buf->trsw_gain_X[i]&0x3F)*2) - 106;
6062 rx_pwr[i] = ((pofdm_buf->trsw_gain_X[i]&0x3F)*2) - 110;
6065 //Get Rx snr value in DB
6066 tmp_rxsnr = pofdm_buf->rxsnr_X[i];
6067 rx_snrX = (char)(tmp_rxsnr);
6069 priv->stats.rxSNRdB[i] = (long)rx_snrX;
6071 /* Translate DBM to percentage. */
6072 RSSI = rtl819x_query_rxpwrpercentage(rx_pwr[i]);
6073 if (priv->brfpath_rxenable[i])
6076 /* Record Signal Strength for next packet */
6077 if(bpacket_match_bssid)
6079 pstats->RxMIMOSignalStrength[i] =(u8) RSSI;
6080 precord_stats->RxMIMOSignalStrength[i] =(u8) RSSI;
6086 // (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive)
6088 //Fixed by Jacken from Bryant 2008-03-20
6089 //Original value is 106
6090 rx_pwr_all = (((pofdm_buf->pwdb_all ) >> 1 )& 0x7f) -106;
6091 pwdb_all = rtl819x_query_rxpwrpercentage(rx_pwr_all);
6093 pstats->RxPWDBAll = precord_stats->RxPWDBAll = pwdb_all;
6094 pstats->RxPower = precord_stats->RxPower = rx_pwr_all;
6095 pstats->RecvSignalPower = rx_pwr_all;
6097 // (3)EVM of HT rate
6099 if(pdrvinfo->RxHT && pdrvinfo->RxRate>=DESC90_RATEMCS8 &&
6100 pdrvinfo->RxRate<=DESC90_RATEMCS15)
6101 max_spatial_stream = 2; //both spatial stream make sense
6103 max_spatial_stream = 1; //only spatial stream 1 makes sense
6105 for(i=0; i<max_spatial_stream; i++)
6107 tmp_rxevm = pofdm_buf->rxevm_X[i];
6108 rx_evmX = (char)(tmp_rxevm);
6110 // Do not use shift operation like "rx_evmX >>= 1" because the compilor of free build environment
6111 // fill most significant bit to "zero" when doing shifting operation which may change a negative
6112 // value to positive one, then the dbm value (which is supposed to be negative) is not correct anymore.
6115 evm = rtl819x_evm_dbtopercentage(rx_evmX);
6117 EVM = SignalScaleMapping(EVM);//make it good looking, from 0~100
6119 if(bpacket_match_bssid)
6121 if(i==0) // Fill value in RFD, Get the first spatial stream only
6122 pstats->SignalQuality = precord_stats->SignalQuality = (u8)(evm & 0xff);
6123 pstats->RxMIMOSignalQuality[i] = precord_stats->RxMIMOSignalQuality[i] = (u8)(evm & 0xff);
6128 /* record rx statistics for debug */
6129 rxsc_sgien_exflg = pofdm_buf->rxsc_sgien_exflg;
6130 prxsc = (phy_ofdm_rx_status_rxsc_sgien_exintfflag *)&rxsc_sgien_exflg;
6131 if(pdrvinfo->BW) //40M channel
6132 priv->stats.received_bwtype[1+prxsc->rxsc]++;
6134 priv->stats.received_bwtype[0]++;
6137 //UI BSS List signal strength(in percentage), make it good looking, from 0~100.
6138 //It is assigned to the BSS List in GetValueFromBeaconOrProbeRsp().
6141 pstats->SignalStrength = precord_stats->SignalStrength = (u8)(rtl819x_signal_scale_mapping((long)pwdb_all));//PWDB_ALL;
6146 //pRfd->Status.SignalStrength = pRecordRfd->Status.SignalStrength = (u1Byte)(SignalScaleMapping(total_rssi/=RF90_PATH_MAX));//(u1Byte)(total_rssi/=RF90_PATH_MAX);
6147 // We can judge RX path number now.
6149 pstats->SignalStrength = precord_stats->SignalStrength = (u8)(rtl819x_signal_scale_mapping((long)(total_rssi/=rf_rx_num)));
6151 } /* QueryRxPhyStatus8190Pci */
6154 rtl8192_record_rxdesc_forlateruse(
6155 struct ieee80211_rx_stats * psrc_stats,
6156 struct ieee80211_rx_stats * ptarget_stats
6159 ptarget_stats->bIsAMPDU = psrc_stats->bIsAMPDU;
6160 ptarget_stats->bFirstMPDU = psrc_stats->bFirstMPDU;
6161 //ptarget_stats->Seq_Num = psrc_stats->Seq_Num;
6166 void TranslateRxSignalStuff819xpci(struct net_device *dev,
6167 struct sk_buff *skb,
6168 struct ieee80211_rx_stats * pstats,
6169 prx_desc_819x_pci pdesc,
6170 prx_fwinfo_819x_pci pdrvinfo)
6172 // TODO: We must only check packet for current MAC address. Not finish
6173 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
6174 bool bpacket_match_bssid, bpacket_toself;
6175 bool bPacketBeacon=false, bToSelfBA=false;
6176 static struct ieee80211_rx_stats previous_stats;
6177 struct ieee80211_hdr_3addr *hdr;
6180 // Get Signal Quality for only RX data queue (but not command queue)
6185 /* Get MAC frame start address. */
6186 tmp_buf = skb->data;
6188 hdr = (struct ieee80211_hdr_3addr *)tmp_buf;
6189 fc = le16_to_cpu(hdr->frame_ctl);
6190 type = WLAN_FC_GET_TYPE(fc);
6191 praddr = hdr->addr1;
6193 /* Check if the received packet is acceptabe. */
6194 bpacket_match_bssid = ((IEEE80211_FTYPE_CTL != type) &&
6195 (eqMacAddr(priv->ieee80211->current_network.bssid, (fc & IEEE80211_FCTL_TODS)? hdr->addr1 : (fc & IEEE80211_FCTL_FROMDS )? hdr->addr2 : hdr->addr3))
6196 && (!pstats->bHwError) && (!pstats->bCRC)&& (!pstats->bICV));
6197 bpacket_toself = bpacket_match_bssid & (eqMacAddr(praddr, priv->ieee80211->dev->dev_addr));
6199 if(WLAN_FC_GET_FRAMETYPE(fc)== IEEE80211_STYPE_BEACON)
6201 bPacketBeacon = true;
6202 //DbgPrint("Beacon 2, MatchBSSID = %d, ToSelf = %d \n", bPacketMatchBSSID, bPacketToSelf);
6204 if(WLAN_FC_GET_FRAMETYPE(fc) == IEEE80211_STYPE_BLOCKACK)
6206 if((eqMacAddr(praddr,dev->dev_addr)))
6208 //DbgPrint("BlockAck, MatchBSSID = %d, ToSelf = %d \n", bPacketMatchBSSID, bPacketToSelf);
6212 if(bpacket_match_bssid)
6214 priv->stats.numpacket_matchbssid++;
6217 priv->stats.numpacket_toself++;
6220 // Process PHY information for previous packet (RSSI/PWDB/EVM)
6222 // Because phy information is contained in the last packet of AMPDU only, so driver
6223 // should process phy information of previous packet
6224 rtl8192_process_phyinfo(priv, tmp_buf,&previous_stats, pstats);
6225 rtl8192_query_rxphystatus(priv, pstats, pdesc, pdrvinfo, &previous_stats, bpacket_match_bssid,
6226 bpacket_toself ,bPacketBeacon, bToSelfBA);
6227 rtl8192_record_rxdesc_forlateruse(pstats, &previous_stats);
6232 void rtl8192_tx_resume(struct net_device *dev)
6234 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
6235 struct ieee80211_device *ieee = priv->ieee80211;
6236 struct sk_buff *skb;
6239 for(queue_index = BK_QUEUE; queue_index < TXCMD_QUEUE;queue_index++) {
6240 while((!skb_queue_empty(&ieee->skb_waitQ[queue_index]))&&
6241 (priv->ieee80211->check_nic_enough_desc(dev,queue_index) > 0)) {
6242 /* 1. dequeue the packet from the wait queue */
6243 skb = skb_dequeue(&ieee->skb_waitQ[queue_index]);
6244 /* 2. tx the packet directly */
6245 ieee->softmac_data_hard_start_xmit(skb,dev,0/* rate useless now*/);
6247 if(queue_index!=MGNT_QUEUE) {
6248 ieee->stats.tx_packets++;
6249 ieee->stats.tx_bytes += skb->len;
6256 void rtl8192_irq_tx_tasklet(struct r8192_priv *priv)
6258 rtl8192_tx_resume(priv->ieee80211->dev);
6262 * Function: UpdateReceivedRateHistogramStatistics
6263 * Overview: Recored down the received data rate
6271 * (Adapter->RxStats.ReceivedRateHistogram[] is updated)
6275 void UpdateReceivedRateHistogramStatistics8190(
6276 struct net_device *dev,
6277 struct ieee80211_rx_stats* pstats
6280 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
6281 u32 rcvType=1; //0: Total, 1:OK, 2:CRC, 3:ICV
6283 u32 preamble_guardinterval; //1: short preamble/GI, 0: long preamble/GI
6285 /* 2007/03/09 MH We will not update rate of packet from rx cmd queue. */
6287 if (pRfd->queue_id == CMPK_RX_QUEUE_ID)
6292 else if(pstats->bICV)
6295 if(pstats->bShortPreamble)
6296 preamble_guardinterval = 1;// short
6298 preamble_guardinterval = 0;// long
6300 switch(pstats->rate)
6305 case MGN_1M: rateIndex = 0; break;
6306 case MGN_2M: rateIndex = 1; break;
6307 case MGN_5_5M: rateIndex = 2; break;
6308 case MGN_11M: rateIndex = 3; break;
6312 case MGN_6M: rateIndex = 4; break;
6313 case MGN_9M: rateIndex = 5; break;
6314 case MGN_12M: rateIndex = 6; break;
6315 case MGN_18M: rateIndex = 7; break;
6316 case MGN_24M: rateIndex = 8; break;
6317 case MGN_36M: rateIndex = 9; break;
6318 case MGN_48M: rateIndex = 10; break;
6319 case MGN_54M: rateIndex = 11; break;
6321 // 11n High throughput rate
6323 case MGN_MCS0: rateIndex = 12; break;
6324 case MGN_MCS1: rateIndex = 13; break;
6325 case MGN_MCS2: rateIndex = 14; break;
6326 case MGN_MCS3: rateIndex = 15; break;
6327 case MGN_MCS4: rateIndex = 16; break;
6328 case MGN_MCS5: rateIndex = 17; break;
6329 case MGN_MCS6: rateIndex = 18; break;
6330 case MGN_MCS7: rateIndex = 19; break;
6331 case MGN_MCS8: rateIndex = 20; break;
6332 case MGN_MCS9: rateIndex = 21; break;
6333 case MGN_MCS10: rateIndex = 22; break;
6334 case MGN_MCS11: rateIndex = 23; break;
6335 case MGN_MCS12: rateIndex = 24; break;
6336 case MGN_MCS13: rateIndex = 25; break;
6337 case MGN_MCS14: rateIndex = 26; break;
6338 case MGN_MCS15: rateIndex = 27; break;
6339 default: rateIndex = 28; break;
6341 priv->stats.received_preamble_GI[preamble_guardinterval][rateIndex]++;
6342 priv->stats.received_rate_histogram[0][rateIndex]++; //total
6343 priv->stats.received_rate_histogram[rcvType][rateIndex]++;
6346 void rtl8192_rx(struct net_device *dev)
6348 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
6349 struct ieee80211_hdr_1addr *ieee80211_hdr = NULL;
6350 bool unicast_packet = false;
6351 struct ieee80211_rx_stats stats = {
6355 .freq = IEEE80211_24GHZ_BAND,
6357 unsigned int count = priv->rxringcount;
6359 stats.nic_type = NIC_8192E;
6362 rx_desc_819x_pci *pdesc = &priv->rx_ring[priv->rx_idx];//rx descriptor
6363 struct sk_buff *skb = priv->rx_buf[priv->rx_idx];//rx pkt
6366 /* wait data to be filled by hardware */
6369 stats.bICV = pdesc->ICV;
6370 stats.bCRC = pdesc->CRC32;
6371 stats.bHwError = pdesc->CRC32 | pdesc->ICV;
6373 stats.Length = pdesc->Length;
6374 if(stats.Length < 24)
6375 stats.bHwError |= 1;
6377 if(stats.bHwError) {
6378 stats.bShift = false;
6381 if (pdesc->Length <500)
6382 priv->stats.rxcrcerrmin++;
6383 else if (pdesc->Length >1000)
6384 priv->stats.rxcrcerrmax++;
6386 priv->stats.rxcrcerrmid++;
6390 prx_fwinfo_819x_pci pDrvInfo = NULL;
6391 struct sk_buff *new_skb = dev_alloc_skb(priv->rxbuffersize);
6393 if (unlikely(!new_skb)) {
6397 stats.RxDrvInfoSize = pdesc->RxDrvInfoSize;
6398 stats.RxBufShift = ((pdesc->Shift)&0x03);
6399 stats.Decrypted = !pdesc->SWDec;
6401 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
6402 pci_dma_sync_single_for_cpu(priv->pdev,
6404 pci_unmap_single(priv->pdev,
6406 *((dma_addr_t *)skb->cb),
6408 PCI_DMA_FROMDEVICE);
6409 skb_put(skb, pdesc->Length);
6410 pDrvInfo = (rx_fwinfo_819x_pci *)(skb->data + stats.RxBufShift);
6411 skb_reserve(skb, stats.RxDrvInfoSize + stats.RxBufShift);
6413 stats.rate = HwRateToMRate90((bool)pDrvInfo->RxHT, (u8)pDrvInfo->RxRate);
6414 stats.bShortPreamble = pDrvInfo->SPLCP;
6416 /* it is debug only. It should be disabled in released driver.
6417 * 2007.1.11 by Emily
6419 UpdateReceivedRateHistogramStatistics8190(dev, &stats);
6421 stats.bIsAMPDU = (pDrvInfo->PartAggr==1);
6422 stats.bFirstMPDU = (pDrvInfo->PartAggr==1) && (pDrvInfo->FirstAGGR==1);
6424 stats.TimeStampLow = pDrvInfo->TSFL;
6425 stats.TimeStampHigh = read_nic_dword(dev, TSFR+4);
6427 UpdateRxPktTimeStamp8190(dev, &stats);
6430 // Get Total offset of MPDU Frame Body
6432 if((stats.RxBufShift + stats.RxDrvInfoSize) > 0)
6435 stats.RxIs40MHzPacket = pDrvInfo->BW;
6438 TranslateRxSignalStuff819xpci(dev,skb, &stats, pdesc, pDrvInfo);
6441 if(pDrvInfo->FirstAGGR==1 || pDrvInfo->PartAggr == 1)
6442 RT_TRACE(COMP_RXDESC, "pDrvInfo->FirstAGGR = %d, pDrvInfo->PartAggr = %d\n",
6443 pDrvInfo->FirstAGGR, pDrvInfo->PartAggr);
6444 skb_trim(skb, skb->len - 4/*sCrcLng*/);
6445 /* rx packets statistics */
6446 ieee80211_hdr = (struct ieee80211_hdr_1addr *)skb->data;
6447 unicast_packet = false;
6449 if(is_broadcast_ether_addr(ieee80211_hdr->addr1)) {
6451 }else if(is_multicast_ether_addr(ieee80211_hdr->addr1)){
6454 /* unicast packet */
6455 unicast_packet = true;
6458 stats.packetlength = stats.Length-4;
6459 stats.fraglength = stats.packetlength;
6460 stats.fragoffset = 0;
6461 stats.ntotalfrag = 1;
6463 if(!ieee80211_rx(priv->ieee80211, skb, &stats)){
6464 dev_kfree_skb_any(skb);
6467 if(unicast_packet) {
6468 priv->stats.rxbytesunicast += skb->len;
6473 priv->rx_buf[priv->rx_idx] = skb;
6474 *((dma_addr_t *) skb->cb) = pci_map_single(priv->pdev, skb->tail, priv->rxbuffersize, PCI_DMA_FROMDEVICE);
6475 // *((dma_addr_t *) skb->cb) = pci_map_single(priv->pdev, skb_tail_pointer(skb), priv->rxbuffersize, PCI_DMA_FROMDEVICE);
6480 pdesc->BufferAddress = cpu_to_le32(*((dma_addr_t *)skb->cb));
6482 pdesc->Length = priv->rxbuffersize;
6483 if (priv->rx_idx == priv->rxringcount-1)
6485 priv->rx_idx = (priv->rx_idx + 1) % priv->rxringcount;
6490 void rtl8192_irq_rx_tasklet(struct r8192_priv *priv)
6492 rtl8192_rx(priv->ieee80211->dev);
6494 write_nic_dword(priv->ieee80211->dev, INTA_MASK,read_nic_dword(priv->ieee80211->dev, INTA_MASK) | IMR_RDU);
6497 static const struct net_device_ops rtl8192_netdev_ops = {
6498 .ndo_open = rtl8192_open,
6499 .ndo_stop = rtl8192_close,
6500 /* .ndo_get_stats = rtl8192_stats, */
6501 .ndo_tx_timeout = tx_timeout,
6502 .ndo_do_ioctl = rtl8192_ioctl,
6503 .ndo_set_multicast_list = r8192_set_multicast,
6504 .ndo_set_mac_address = r8192_set_mac_adr,
6505 .ndo_start_xmit = ieee80211_xmit,
6508 /****************************************************************************
6509 ---------------------------- PCI_STUFF---------------------------
6510 *****************************************************************************/
6512 static int __devinit rtl8192_pci_probe(struct pci_dev *pdev,
6513 const struct pci_device_id *id)
6515 unsigned long ioaddr = 0;
6516 struct net_device *dev = NULL;
6517 struct r8192_priv *priv= NULL;
6520 #ifdef CONFIG_RTL8192_IO_MAP
6521 unsigned long pio_start, pio_len, pio_flags;
6523 unsigned long pmem_start, pmem_len, pmem_flags;
6524 #endif //end #ifdef RTL_IO_MAP
6526 RT_TRACE(COMP_INIT,"Configuring chip resources");
6528 if( pci_enable_device (pdev) ){
6529 RT_TRACE(COMP_ERR,"Failed to enable PCI device");
6533 pci_set_master(pdev);
6534 //pci_set_wmi(pdev);
6535 pci_set_dma_mask(pdev, 0xffffff00ULL);
6536 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
6537 pci_set_consistent_dma_mask(pdev,0xffffff00ULL);
6539 dev = alloc_ieee80211(sizeof(struct r8192_priv));
6543 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
6544 SET_MODULE_OWNER(dev);
6547 pci_set_drvdata(pdev, dev);
6548 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
6549 SET_NETDEV_DEV(dev, &pdev->dev);
6551 priv = ieee80211_priv(dev);
6552 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
6553 priv->ieee80211 = netdev_priv(dev);
6555 priv->ieee80211 = (struct ieee80211_device *)dev->priv;
6558 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
6559 if((pdev->subsystem_vendor == PCI_VENDOR_ID_DLINK)&&(pdev->subsystem_device == 0x3304)){
6560 priv->ieee80211->bSupportRemoteWakeUp = 1;
6564 priv->ieee80211->bSupportRemoteWakeUp = 0;
6567 #ifdef CONFIG_RTL8192_IO_MAP
6569 pio_start = (unsigned long)pci_resource_start (pdev, 0);
6570 pio_len = (unsigned long)pci_resource_len (pdev, 0);
6571 pio_flags = (unsigned long)pci_resource_flags (pdev, 0);
6573 if (!(pio_flags & IORESOURCE_IO)) {
6574 RT_TRACE(COMP_ERR,"region #0 not a PIO resource, aborting");
6578 //DMESG("IO space @ 0x%08lx", pio_start );
6579 if( ! request_region( pio_start, pio_len, RTL819xE_MODULE_NAME ) ){
6580 RT_TRACE(COMP_ERR,"request_region failed!");
6585 dev->base_addr = ioaddr; // device I/O address
6589 pmem_start = pci_resource_start(pdev, 1);
6590 pmem_len = pci_resource_len(pdev, 1);
6591 pmem_flags = pci_resource_flags (pdev, 1);
6593 if (!(pmem_flags & IORESOURCE_MEM)) {
6594 RT_TRACE(COMP_ERR,"region #1 not a MMIO resource, aborting");
6598 //DMESG("Memory mapped space @ 0x%08lx ", pmem_start);
6599 if( ! request_mem_region(pmem_start, pmem_len, RTL819xE_MODULE_NAME)) {
6600 RT_TRACE(COMP_ERR,"request_mem_region failed!");
6605 ioaddr = (unsigned long)ioremap_nocache( pmem_start, pmem_len);
6606 if( ioaddr == (unsigned long)NULL ){
6607 RT_TRACE(COMP_ERR,"ioremap failed!");
6608 // release_mem_region( pmem_start, pmem_len );
6612 dev->mem_start = ioaddr; // shared mem start
6613 dev->mem_end = ioaddr + pci_resource_len(pdev, 0); // shared mem end
6615 #endif //end #ifdef RTL_IO_MAP
6617 /* We disable the RETRY_TIMEOUT register (0x41) to keep
6618 * PCI Tx retries from interfering with C3 CPU state */
6619 pci_write_config_byte(pdev, 0x41, 0x00);
6622 pci_read_config_byte(pdev, 0x05, &unit);
6623 pci_write_config_byte(pdev, 0x05, unit & (~0x04));
6625 dev->irq = pdev->irq;
6628 dev->netdev_ops = &rtl8192_netdev_ops;
6630 dev->open = rtl8192_open;
6631 dev->stop = rtl8192_close;
6632 //dev->hard_start_xmit = rtl8192_8023_hard_start_xmit;
6633 dev->tx_timeout = tx_timeout;
6634 //dev->wireless_handlers = &r8192_wx_handlers_def;
6635 dev->do_ioctl = rtl8192_ioctl;
6636 dev->set_multicast_list = r8192_set_multicast;
6637 dev->set_mac_address = r8192_set_mac_adr;
6640 //DMESG("Oops: i'm coming\n");
6641 #if WIRELESS_EXT >= 12
6642 #if WIRELESS_EXT < 17
6643 dev->get_wireless_stats = r8192_get_wireless_stats;
6645 dev->wireless_handlers = (struct iw_handler_def *) &r8192_wx_handlers_def;
6647 //dev->get_wireless_stats = r8192_get_wireless_stats;
6648 dev->type=ARPHRD_ETHER;
6650 dev->watchdog_timeo = HZ*3; //modified by john, 0805
6652 if (dev_alloc_name(dev, ifname) < 0){
6653 RT_TRACE(COMP_INIT, "Oops: devname already taken! Trying wlan%%d...\n");
6655 dev_alloc_name(dev, ifname);
6658 RT_TRACE(COMP_INIT, "Driver probe completed1\n");
6659 if(rtl8192_init(dev)!=0){
6660 RT_TRACE(COMP_ERR, "Initialization failed");
6664 netif_carrier_off(dev);
6665 netif_stop_queue(dev);
6667 register_netdev(dev);
6668 RT_TRACE(COMP_INIT, "dev name=======> %s\n",dev->name);
6669 rtl8192_proc_init_one(dev);
6672 RT_TRACE(COMP_INIT, "Driver probe completed\n");
6673 //#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
6681 #ifdef CONFIG_RTL8180_IO_MAP
6683 if( dev->base_addr != 0 ){
6685 release_region(dev->base_addr,
6686 pci_resource_len(pdev, 0) );
6689 if( dev->mem_start != (unsigned long)NULL ){
6690 iounmap( (void *)dev->mem_start );
6691 release_mem_region( pci_resource_start(pdev, 1),
6692 pci_resource_len(pdev, 1) );
6694 #endif //end #ifdef RTL_IO_MAP
6700 free_irq(dev->irq, dev);
6703 free_ieee80211(dev);
6706 pci_disable_device(pdev);
6708 DMESG("wlan driver load failed\n");
6709 pci_set_drvdata(pdev, NULL);
6714 /* detach all the work and timer structure declared or inititialized
6715 * in r8192_init function.
6717 void rtl8192_cancel_deferred_work(struct r8192_priv* priv)
6719 /* call cancel_work_sync instead of cancel_delayed_work if and only if Linux_version_code
6720 * is or is newer than 2.6.20 and work structure is defined to be struct work_struct.
6721 * Otherwise call cancel_delayed_work is enough.
6722 * FIXME (2.6.20 shoud 2.6.22, work_struct shoud not cancel)
6724 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
6725 cancel_delayed_work(&priv->watch_dog_wq);
6726 cancel_delayed_work(&priv->update_beacon_wq);
6727 cancel_delayed_work(&priv->ieee80211->hw_wakeup_wq);
6728 cancel_delayed_work(&priv->ieee80211->hw_sleep_wq);
6730 cancel_delayed_work(&priv->gpio_change_rf_wq);
6733 #if LINUX_VERSION_CODE >=KERNEL_VERSION(2,6,22)
6734 cancel_work_sync(&priv->reset_wq);
6735 cancel_work_sync(&priv->qos_activate);
6736 //cancel_work_sync(&priv->SetBWModeWorkItem);
6737 //cancel_work_sync(&priv->SwChnlWorkItem);
6739 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
6740 cancel_delayed_work(&priv->reset_wq);
6741 cancel_delayed_work(&priv->qos_activate);
6742 //cancel_delayed_work(&priv->SetBWModeWorkItem);
6743 //cancel_delayed_work(&priv->SwChnlWorkItem);
6750 static void __devexit rtl8192_pci_disconnect(struct pci_dev *pdev)
6752 struct net_device *dev = pci_get_drvdata(pdev);
6753 struct r8192_priv *priv ;
6757 unregister_netdev(dev);
6759 priv=ieee80211_priv(dev);
6761 rtl8192_proc_remove_one(dev);
6764 if (priv->pFirmware)
6766 vfree(priv->pFirmware);
6767 priv->pFirmware = NULL;
6769 // priv->rf_close(dev);
6770 // rtl8192_usb_deleteendpoints(dev);
6771 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
6772 destroy_workqueue(priv->priv_wq);
6774 /* redundant with rtl8192_down */
6775 // rtl8192_irq_disable(dev);
6776 // rtl8192_reset(dev);
6780 /* free tx/rx rings */
6781 rtl8192_free_rx_ring(dev);
6782 for (i = 0; i < MAX_TX_QUEUE_COUNT; i++) {
6783 rtl8192_free_tx_ring(dev, i);
6788 printk("Freeing irq %d\n",dev->irq);
6789 free_irq(dev->irq, dev);
6796 // free_beacon_desc_ring(dev,priv->txbeaconcount);
6798 #ifdef CONFIG_RTL8180_IO_MAP
6800 if( dev->base_addr != 0 ){
6802 release_region(dev->base_addr,
6803 pci_resource_len(pdev, 0) );
6806 if( dev->mem_start != (unsigned long)NULL ){
6807 iounmap( (void *)dev->mem_start );
6808 release_mem_region( pci_resource_start(pdev, 1),
6809 pci_resource_len(pdev, 1) );
6811 #endif /*end #ifdef RTL_IO_MAP*/
6812 free_ieee80211(dev);
6816 pci_disable_device(pdev);
6817 RT_TRACE(COMP_DOWN, "wlan driver removed\n");
6820 extern int ieee80211_init(void);
6821 extern void ieee80211_exit(void);
6823 static int __init rtl8192_pci_module_init(void)
6827 retval = ieee80211_init();
6831 printk(KERN_INFO "\nLinux kernel driver for RTL8192 based WLAN cards\n");
6832 printk(KERN_INFO "Copyright (c) 2007-2008, Realsil Wlan\n");
6833 RT_TRACE(COMP_INIT, "Initializing module");
6834 RT_TRACE(COMP_INIT, "Wireless extensions version %d", WIRELESS_EXT);
6835 rtl8192_proc_module_init();
6836 #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22))
6837 if(0!=pci_module_init(&rtl8192_pci_driver))
6839 if(0!=pci_register_driver(&rtl8192_pci_driver))
6842 DMESG("No device found");
6843 /*pci_unregister_driver (&rtl8192_pci_driver);*/
6850 static void __exit rtl8192_pci_module_exit(void)
6852 pci_unregister_driver(&rtl8192_pci_driver);
6854 RT_TRACE(COMP_DOWN, "Exiting");
6855 rtl8192_proc_module_remove();
6859 //warning message WB
6860 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18)
6861 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
6862 void rtl8192_interrupt(int irq, void *netdev, struct pt_regs *regs)
6864 irqreturn_t rtl8192_interrupt(int irq, void *netdev, struct pt_regs *regs)
6867 irqreturn_t rtl8192_interrupt(int irq, void *netdev)
6870 struct net_device *dev = (struct net_device *) netdev;
6871 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
6872 unsigned long flags;
6874 /* We should return IRQ_NONE, but for now let me keep this */
6875 if(priv->irq_enabled == 0){
6876 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
6883 spin_lock_irqsave(&priv->irq_th_lock,flags);
6887 inta = read_nic_dword(dev, ISR);// & priv->IntrMask;
6888 write_nic_dword(dev,ISR,inta); // reset int situation
6890 priv->stats.shints++;
6891 //DMESG("Enter interrupt, ISR value = 0x%08x", inta);
6893 spin_unlock_irqrestore(&priv->irq_th_lock,flags);
6894 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
6900 most probably we can safely return IRQ_NONE,
6901 but for now is better to avoid problems
6907 spin_unlock_irqrestore(&priv->irq_th_lock,flags);
6908 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
6917 DMESG("NIC irq %x",inta);
6919 //priv->irqpending = inta;
6922 if(!netif_running(dev)) {
6923 spin_unlock_irqrestore(&priv->irq_th_lock,flags);
6924 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
6931 if(inta & IMR_TIMEOUT0){
6932 // write_nic_dword(dev, TimerInt, 0);
6933 //DMESG("=================>waking up");
6934 // rtl8180_hw_wakeup(dev);
6937 if(inta & IMR_TBDOK){
6938 RT_TRACE(COMP_INTR, "beacon ok interrupt!\n");
6939 rtl8192_tx_isr(dev, BEACON_QUEUE);
6940 priv->stats.txbeaconokint++;
6943 if(inta & IMR_TBDER){
6944 RT_TRACE(COMP_INTR, "beacon ok interrupt!\n");
6945 rtl8192_tx_isr(dev, BEACON_QUEUE);
6946 priv->stats.txbeaconerr++;
6949 if(inta & IMR_MGNTDOK ) {
6950 RT_TRACE(COMP_INTR, "Manage ok interrupt!\n");
6951 priv->stats.txmanageokint++;
6952 rtl8192_tx_isr(dev,MGNT_QUEUE);
6956 if(inta & IMR_COMDOK)
6958 priv->stats.txcmdpktokint++;
6959 rtl8192_tx_isr(dev,TXCMD_QUEUE);
6964 DMESG("Frame arrived !");
6966 priv->stats.rxint++;
6967 tasklet_schedule(&priv->irq_rx_tasklet);
6970 if(inta & IMR_BcnInt) {
6971 RT_TRACE(COMP_INTR, "prepare beacon for interrupt!\n");
6972 tasklet_schedule(&priv->irq_prepare_beacon_tasklet);
6976 RT_TRACE(COMP_INTR, "rx descriptor unavailable!\n");
6977 priv->stats.rxrdu++;
6978 /* reset int situation */
6979 write_nic_dword(dev,INTA_MASK,read_nic_dword(dev, INTA_MASK) & ~IMR_RDU);
6980 tasklet_schedule(&priv->irq_rx_tasklet);
6983 if(inta & IMR_RXFOVW){
6984 RT_TRACE(COMP_INTR, "rx overflow !\n");
6985 priv->stats.rxoverflow++;
6986 tasklet_schedule(&priv->irq_rx_tasklet);
6989 if(inta & IMR_TXFOVW) priv->stats.txoverflow++;
6991 if(inta & IMR_BKDOK){
6992 RT_TRACE(COMP_INTR, "BK Tx OK interrupt!\n");
6993 priv->stats.txbkokint++;
6994 priv->ieee80211->LinkDetectInfo.NumTxOkInPeriod++;
6995 rtl8192_tx_isr(dev,BK_QUEUE);
6996 rtl8192_try_wake_queue(dev, BK_QUEUE);
6999 if(inta & IMR_BEDOK){
7000 RT_TRACE(COMP_INTR, "BE TX OK interrupt!\n");
7001 priv->stats.txbeokint++;
7002 priv->ieee80211->LinkDetectInfo.NumTxOkInPeriod++;
7003 rtl8192_tx_isr(dev,BE_QUEUE);
7004 rtl8192_try_wake_queue(dev, BE_QUEUE);
7007 if(inta & IMR_VIDOK){
7008 RT_TRACE(COMP_INTR, "VI TX OK interrupt!\n");
7009 priv->stats.txviokint++;
7010 priv->ieee80211->LinkDetectInfo.NumTxOkInPeriod++;
7011 rtl8192_tx_isr(dev,VI_QUEUE);
7012 rtl8192_try_wake_queue(dev, VI_QUEUE);
7015 if(inta & IMR_VODOK){
7016 priv->stats.txvookint++;
7017 priv->ieee80211->LinkDetectInfo.NumTxOkInPeriod++;
7018 rtl8192_tx_isr(dev,VO_QUEUE);
7019 rtl8192_try_wake_queue(dev, VO_QUEUE);
7022 force_pci_posting(dev);
7023 spin_unlock_irqrestore(&priv->irq_th_lock,flags);
7025 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
7032 void rtl8192_try_wake_queue(struct net_device *dev, int pri)
7035 unsigned long flags;
7037 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
7039 spin_lock_irqsave(&priv->tx_lock,flags);
7040 enough_desc = check_nic_enough_desc(dev,pri);
7041 spin_unlock_irqrestore(&priv->tx_lock,flags);
7044 ieee80211_wake_queue(priv->ieee80211);
7049 void EnableHWSecurityConfig8192(struct net_device *dev)
7051 u8 SECR_value = 0x0;
7052 // struct ieee80211_device* ieee1 = container_of(&dev, struct ieee80211_device, dev);
7053 //printk("==>ieee1:%p, dev:%p\n", ieee1, dev);
7054 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
7055 struct ieee80211_device* ieee = priv->ieee80211;
7056 //printk("==>ieee:%p, dev:%p\n", ieee, dev);
7057 SECR_value = SCR_TxEncEnable | SCR_RxDecEnable;
7059 if (((KEY_TYPE_WEP40 == ieee->pairwise_key_type) || (KEY_TYPE_WEP104 == ieee->pairwise_key_type)) && (priv->ieee80211->auth_mode != 2))
7061 SECR_value |= SCR_RxUseDK;
7062 SECR_value |= SCR_TxUseDK;
7064 else if ((ieee->iw_mode == IW_MODE_ADHOC) && (ieee->pairwise_key_type & (KEY_TYPE_CCMP | KEY_TYPE_TKIP)))
7066 SECR_value |= SCR_RxUseDK;
7067 SECR_value |= SCR_TxUseDK;
7072 //add HWSec active enable here.
7073 //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
7074 ieee->hwsec_active = 1;
7076 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
7078 ieee->hwsec_active = 0;
7079 SECR_value &= ~SCR_RxDecEnable;
7082 RT_TRACE(COMP_SEC,"%s:, hwsec:%d, pairwise_key:%d, SECR_value:%x\n", __FUNCTION__, \
7083 ieee->hwsec_active, ieee->pairwise_key_type, SECR_value);
7085 write_nic_byte(dev, SECR, SECR_value);//SECR_value | SCR_UseDK );
7089 #define TOTAL_CAM_ENTRY 32
7090 //#define CAM_CONTENT_COUNT 8
7091 void setKey( struct net_device *dev,
7099 u32 TargetCommand = 0;
7100 u32 TargetContent = 0;
7104 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
7105 RT_RF_POWER_STATE rtState;
7106 rtState = priv->ieee80211->eRFPowerState;
7107 if(priv->ieee80211->PowerSaveControl.bInactivePs){
7108 if(rtState == eRfOff){
7109 if(priv->ieee80211->RfOffReason > RF_CHANGE_BY_IPS)
7111 RT_TRACE(COMP_ERR, "%s(): RF is OFF.\n",__FUNCTION__);
7120 priv->ieee80211->is_set_key = true;
7122 if (EntryNo >= TOTAL_CAM_ENTRY)
7123 RT_TRACE(COMP_ERR, "cam entry exceeds in setKey()\n");
7125 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));
7128 usConfig |= BIT15 | (KeyType<<2);
7130 usConfig |= BIT15 | (KeyType<<2) | KeyIndex;
7131 // usConfig |= BIT15 | (KeyType<<2) | (DefaultKey<<5) | KeyIndex;
7134 for(i=0 ; i<CAM_CONTENT_COUNT; i++){
7135 TargetCommand = i+CAM_CONTENT_COUNT*EntryNo;
7136 TargetCommand |= BIT31|BIT16;
7138 if(i==0){//MAC|Config
7139 TargetContent = (u32)(*(MacAddr+0)) << 16|
7140 (u32)(*(MacAddr+1)) << 24|
7143 write_nic_dword(dev, WCAMI, TargetContent);
7144 write_nic_dword(dev, RWCAM, TargetCommand);
7145 // printk("setkey cam =%8x\n", read_cam(dev, i+6*EntryNo));
7148 TargetContent = (u32)(*(MacAddr+2)) |
7149 (u32)(*(MacAddr+3)) << 8|
7150 (u32)(*(MacAddr+4)) << 16|
7151 (u32)(*(MacAddr+5)) << 24;
7152 write_nic_dword(dev, WCAMI, TargetContent);
7153 write_nic_dword(dev, RWCAM, TargetCommand);
7155 else { //Key Material
7156 if(KeyContent != NULL)
7158 write_nic_dword(dev, WCAMI, (u32)(*(KeyContent+i-2)) );
7159 write_nic_dword(dev, RWCAM, TargetCommand);
7163 RT_TRACE(COMP_SEC,"=========>after set key, usconfig:%x\n", usConfig);
7164 // CAM_read_entry(dev, 0);
7166 // This function seems not ready! WB
7167 void CamPrintDbgReg(struct net_device* dev)
7169 unsigned long rvalue;
7170 unsigned char ucValue;
7171 write_nic_dword(dev, DCAM, 0x80000000);
7173 rvalue = read_nic_dword(dev, DCAM); //delay_ms(40);
7174 RT_TRACE(COMP_SEC, " TX CAM=%8lX ",rvalue);
7175 if((rvalue & 0x40000000) != 0x4000000)
7176 RT_TRACE(COMP_SEC, "-->TX Key Not Found ");
7178 write_nic_dword(dev, DCAM, 0x00000000); //delay_ms(40);
7179 rvalue = read_nic_dword(dev, DCAM); //delay_ms(40);
7180 RT_TRACE(COMP_SEC, "RX CAM=%8lX ",rvalue);
7181 if((rvalue & 0x40000000) != 0x4000000)
7182 RT_TRACE(COMP_SEC, "-->CAM Key Not Found ");
7183 ucValue = read_nic_byte(dev, SECR);
7184 RT_TRACE(COMP_SEC, "WPA_Config=%x \n",ucValue);
7188 /***************************************************************************
7189 ------------------- module init / exit stubs ----------------
7190 ****************************************************************************/
7191 module_init(rtl8192_pci_module_init);
7192 module_exit(rtl8192_pci_module_exit);