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>
29 #undef RX_DONT_PASS_UL
31 #undef DEBUG_RX_VERBOSE
37 #undef DEBUG_TX_FILLDESC
42 #undef DEBUG_REGISTERS
44 #undef DEBUG_IRQ_TASKLET
48 //#define CONFIG_RTL8192_IO_MAP
49 #include <asm/uaccess.h>
50 #include "r8192E_hw.h"
52 #include "r8190_rtl8256.h" /* RTL8225 Radio frontend */
53 #include "r8180_93cx6.h" /* Card EEPROM */
54 #include "r8192E_wx.h"
55 #include "r819xE_phy.h" //added by WB 4.30.2008
56 #include "r819xE_phyreg.h"
57 #include "r819xE_cmdpkt.h"
58 #include "r8192E_dm.h"
59 //#include "r8192xU_phyreg.h"
60 //#include <linux/usb.h>
61 // FIXME: check if 2.6.7 is ok
71 //set here to open your trace code. //WB
72 u32 rt_global_debug_component = \
90 // COMP_POWER_TRACKING |
92 COMP_ERR ; //always open err flags on
94 #define PCI_DEVICE(vend,dev)\
95 .vendor=(vend),.device=(dev),\
96 .subvendor=PCI_ANY_ID,.subdevice=PCI_ANY_ID
98 static struct pci_device_id rtl8192_pci_id_tbl[] __devinitdata = {
102 { PCI_DEVICE(0x10ec, 0x8190) },
104 { PCI_DEVICE(0x07aa, 0x0045) },
105 { PCI_DEVICE(0x07aa, 0x0046) },
108 { PCI_DEVICE(0x10ec, 0x8192) },
111 { PCI_DEVICE(0x07aa, 0x0044) },
112 { PCI_DEVICE(0x07aa, 0x0047) },
117 static char* ifname = "wlan%d";
119 static int hwseqnum = 0;
120 static int hwwep = 0;
122 static int hwwep = 1; //default use hw. set 0 to use software security
123 static int channels = 0x3fff;
125 MODULE_LICENSE("GPL");
126 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
127 MODULE_VERSION("V 1.1");
129 MODULE_DEVICE_TABLE(pci, rtl8192_pci_id_tbl);
130 //MODULE_AUTHOR("Andrea Merello <andreamrl@tiscali.it>");
131 MODULE_DESCRIPTION("Linux driver for Realtek RTL819x WiFi cards");
134 MODULE_PARM(ifname,"s");
135 MODULE_PARM_DESC(devname," Net interface name, wlan%d=default");
137 MODULE_PARM(hwseqnum,"i");
138 MODULE_PARM_DESC(hwseqnum," Try to use hardware 802.11 header sequence numbers. Zero=default");
140 MODULE_PARM(hwwep,"i");
141 MODULE_PARM_DESC(hwwep," Try to use hardware WEP support. Still broken and not available on all cards");
143 MODULE_PARM(channels,"i");
144 MODULE_PARM_DESC(channels," Channel bitmask for specific locales. NYI");
147 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 9)
148 module_param(ifname, charp, S_IRUGO|S_IWUSR );
149 //module_param(hwseqnum,int, S_IRUGO|S_IWUSR);
150 module_param(hwwep,int, S_IRUGO|S_IWUSR);
151 module_param(channels,int, S_IRUGO|S_IWUSR);
153 MODULE_PARM(ifname, "s");
154 //MODULE_PARM(hwseqnum,"i");
155 MODULE_PARM(hwwep,"i");
156 MODULE_PARM(channels,"i");
159 MODULE_PARM_DESC(ifname," Net interface name, wlan%d=default");
160 //MODULE_PARM_DESC(hwseqnum," Try to use hardware 802.11 header sequence numbers. Zero=default");
161 MODULE_PARM_DESC(hwwep," Try to use hardware WEP support. Still broken and not available on all cards");
162 MODULE_PARM_DESC(channels," Channel bitmask for specific locales. NYI");
164 static int __devinit rtl8192_pci_probe(struct pci_dev *pdev,
165 const struct pci_device_id *id);
166 static void __devexit rtl8192_pci_disconnect(struct pci_dev *pdev);
168 static struct pci_driver rtl8192_pci_driver = {
169 .name = RTL819xE_MODULE_NAME, /* Driver name */
170 .id_table = rtl8192_pci_id_tbl, /* PCI_ID table */
171 .probe = rtl8192_pci_probe, /* probe fn */
172 .remove = __devexit_p(rtl8192_pci_disconnect), /* remove fn */
173 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0)
175 .suspend = rtl8192E_suspend, /* PM suspend fn */
176 .resume = rtl8192E_resume, /* PM resume fn */
178 .suspend = NULL, /* PM suspend fn */
179 .resume = NULL, /* PM resume fn */
186 typedef struct _CHANNEL_LIST
190 }CHANNEL_LIST, *PCHANNEL_LIST;
192 static CHANNEL_LIST ChannelPlan[] = {
193 {{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
194 {{1,2,3,4,5,6,7,8,9,10,11},11}, //IC
195 {{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48,52,56,60,64},21}, //ETSI
196 {{1,2,3,4,5,6,7,8,9,10,11,12,13},13}, //Spain. Change to ETSI.
197 {{1,2,3,4,5,6,7,8,9,10,11,12,13},13}, //France. Change to ETSI.
198 {{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
199 {{1,2,3,4,5,6,7,8,9,10,11,12,13,14,36,40,44,48,52,56,60,64},22},//MKK1
200 {{1,2,3,4,5,6,7,8,9,10,11,12,13},13}, //Israel.
201 {{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
202 {{1,2,3,4,5,6,7,8,9,10,11,12,13,14,36,40,44,48,52,56,60,64}, 22}, //MIC
203 {{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
206 static void rtl819x_set_channel_map(u8 channel_plan, struct r8192_priv* priv)
208 int i, max_chan=-1, min_chan=-1;
209 struct ieee80211_device* ieee = priv->ieee80211;
210 switch (channel_plan)
212 case COUNTRY_CODE_FCC:
213 case COUNTRY_CODE_IC:
214 case COUNTRY_CODE_ETSI:
215 case COUNTRY_CODE_SPAIN:
216 case COUNTRY_CODE_FRANCE:
217 case COUNTRY_CODE_MKK:
218 case COUNTRY_CODE_MKK1:
219 case COUNTRY_CODE_ISRAEL:
220 case COUNTRY_CODE_TELEC:
221 case COUNTRY_CODE_MIC:
224 ieee->bGlobalDomain = false;
225 //acturally 8225 & 8256 rf chip only support B,G,24N mode
226 if ((priv->rf_chip == RF_8225) || (priv->rf_chip == RF_8256))
233 RT_TRACE(COMP_ERR, "unknown rf chip, can't set channel map in function:%s()\n", __FUNCTION__);
235 if (ChannelPlan[channel_plan].Len != 0){
236 // Clear old channel map
237 memset(GET_DOT11D_INFO(ieee)->channel_map, 0, sizeof(GET_DOT11D_INFO(ieee)->channel_map));
238 // Set new channel map
239 for (i=0;i<ChannelPlan[channel_plan].Len;i++)
241 if (ChannelPlan[channel_plan].Channel[i] < min_chan || ChannelPlan[channel_plan].Channel[i] > max_chan)
243 GET_DOT11D_INFO(ieee)->channel_map[ChannelPlan[channel_plan].Channel[i]] = 1;
248 case COUNTRY_CODE_GLOBAL_DOMAIN:
250 GET_DOT11D_INFO(ieee)->bEnabled = 0; //this flag enabled to follow 11d country IE setting, otherwise, it shall follow global domain setting
252 ieee->bGlobalDomain = true;
262 #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 )
263 /* 2007/07/25 MH Defien temp tx fw info. */
264 static TX_FWINFO_T Tmp_TxFwInfo;
267 #define rx_hal_is_cck_rate(_pdrvinfo)\
268 (_pdrvinfo->RxRate == DESC90_RATE1M ||\
269 _pdrvinfo->RxRate == DESC90_RATE2M ||\
270 _pdrvinfo->RxRate == DESC90_RATE5_5M ||\
271 _pdrvinfo->RxRate == DESC90_RATE11M) &&\
275 void CamResetAllEntry(struct net_device *dev)
281 ulcommand |= BIT31|BIT30;
282 write_nic_dword(dev, RWCAM, ulcommand);
284 for(ucIndex=0;ucIndex<TOTAL_CAM_ENTRY;ucIndex++)
285 CAM_mark_invalid(dev, ucIndex);
286 for(ucIndex=0;ucIndex<TOTAL_CAM_ENTRY;ucIndex++)
287 CAM_empty_entry(dev, ucIndex);
292 void write_cam(struct net_device *dev, u8 addr, u32 data)
294 write_nic_dword(dev, WCAMI, data);
295 write_nic_dword(dev, RWCAM, BIT31|BIT16|(addr&0xff) );
297 u32 read_cam(struct net_device *dev, u8 addr)
299 write_nic_dword(dev, RWCAM, 0x80000000|(addr&0xff) );
300 return read_nic_dword(dev, 0xa8);
303 ////////////////////////////////////////////////////////////
304 #ifdef CONFIG_RTL8180_IO_MAP
306 u8 read_nic_byte(struct net_device *dev, int x)
308 return 0xff&inb(dev->base_addr +x);
311 u32 read_nic_dword(struct net_device *dev, int x)
313 return inl(dev->base_addr +x);
316 u16 read_nic_word(struct net_device *dev, int x)
318 return inw(dev->base_addr +x);
321 void write_nic_byte(struct net_device *dev, int x,u8 y)
323 outb(y&0xff,dev->base_addr +x);
326 void write_nic_word(struct net_device *dev, int x,u16 y)
328 outw(y,dev->base_addr +x);
331 void write_nic_dword(struct net_device *dev, int x,u32 y)
333 outl(y,dev->base_addr +x);
336 #else /* RTL_IO_MAP */
338 u8 read_nic_byte(struct net_device *dev, int x)
340 return 0xff&readb((u8*)dev->mem_start +x);
343 u32 read_nic_dword(struct net_device *dev, int x)
345 return readl((u8*)dev->mem_start +x);
348 u16 read_nic_word(struct net_device *dev, int x)
350 return readw((u8*)dev->mem_start +x);
353 void write_nic_byte(struct net_device *dev, int x,u8 y)
355 writeb(y,(u8*)dev->mem_start +x);
359 void write_nic_dword(struct net_device *dev, int x,u32 y)
361 writel(y,(u8*)dev->mem_start +x);
365 void write_nic_word(struct net_device *dev, int x,u16 y)
367 writew(y,(u8*)dev->mem_start +x);
371 #endif /* RTL_IO_MAP */
374 ///////////////////////////////////////////////////////////
376 //u8 read_phy_cck(struct net_device *dev, u8 adr);
377 //u8 read_phy_ofdm(struct net_device *dev, u8 adr);
378 /* this might still called in what was the PHY rtl8185/rtl8192 common code
379 * plans are to possibilty turn it again in one common code...
381 inline void force_pci_posting(struct net_device *dev)
387 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18)
388 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
389 void rtl8192_interrupt(int irq, void *netdev, struct pt_regs *regs);
391 irqreturn_t rtl8192_interrupt(int irq, void *netdev, struct pt_regs *regs);
394 irqreturn_t rtl8192_interrupt(int irq, void *netdev);
396 //static struct net_device_stats *rtl8192_stats(struct net_device *dev);
397 void rtl8192_commit(struct net_device *dev);
398 //void rtl8192_restart(struct net_device *dev);
399 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
400 void rtl8192_restart(struct work_struct *work);
401 //void rtl8192_rq_tx_ack(struct work_struct *work);
403 void rtl8192_restart(struct net_device *dev);
404 // //void rtl8192_rq_tx_ack(struct net_device *dev);
407 void watch_dog_timer_callback(unsigned long data);
409 void IPSEnter(struct net_device *dev);
410 void IPSLeave(struct net_device *dev);
411 void InactivePsWorkItemCallback(struct net_device *dev);
413 /****************************************************************************
414 -----------------------------PROCFS STUFF-------------------------
415 *****************************************************************************/
417 static struct proc_dir_entry *rtl8192_proc = NULL;
421 static int proc_get_stats_ap(char *page, char **start,
422 off_t offset, int count,
423 int *eof, void *data)
425 struct net_device *dev = data;
426 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
427 struct ieee80211_device *ieee = priv->ieee80211;
428 struct ieee80211_network *target;
432 list_for_each_entry(target, &ieee->network_list, list) {
434 len += snprintf(page + len, count - len,
435 "%s ", target->ssid);
437 if(target->wpa_ie_len>0 || target->rsn_ie_len>0){
438 len += snprintf(page + len, count - len,
442 len += snprintf(page + len, count - len,
452 static int proc_get_registers(char *page, char **start,
453 off_t offset, int count,
454 int *eof, void *data)
456 struct net_device *dev = data;
457 // struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
464 /* This dump the current register page */
465 len += snprintf(page + len, count - len,
466 "\n####################page 0##################\n ");
470 //printk( "\nD: %2x> ", n);
471 len += snprintf(page + len, count - len,
474 for(i=0;i<16 && n<=max;i++,n++)
475 len += snprintf(page + len, count - len,
476 "%2x ",read_nic_byte(dev,n));
478 // printk("%2x ",read_nic_byte(dev,n));
480 len += snprintf(page + len, count - len,"\n");
481 len += snprintf(page + len, count - len,
482 "\n####################page 1##################\n ");
485 //printk( "\nD: %2x> ", n);
486 len += snprintf(page + len, count - len,
489 for(i=0;i<16 && n<=max;i++,n++)
490 len += snprintf(page + len, count - len,
491 "%2x ",read_nic_byte(dev,0x100|n));
493 // printk("%2x ",read_nic_byte(dev,n));
496 len += snprintf(page + len, count - len,
497 "\n####################page 3##################\n ");
500 //printk( "\nD: %2x> ", n);
501 len += snprintf(page + len, count - len,
504 for(i=0;i<16 && n<=max;i++,n++)
505 len += snprintf(page + len, count - len,
506 "%2x ",read_nic_byte(dev,0x300|n));
508 // printk("%2x ",read_nic_byte(dev,n));
519 static int proc_get_cck_reg(char *page, char **start,
520 off_t offset, int count,
521 int *eof, void *data)
523 struct net_device *dev = data;
524 // struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
531 /* This dump the current register page */
534 //printk( "\nD: %2x> ", n);
535 len += snprintf(page + len, count - len,
538 for(i=0;i<16 && n<=max;i++,n++)
539 len += snprintf(page + len, count - len,
540 "%2x ",read_phy_cck(dev,n));
542 // printk("%2x ",read_nic_byte(dev,n));
544 len += snprintf(page + len, count - len,"\n");
554 static int proc_get_ofdm_reg(char *page, char **start,
555 off_t offset, int count,
556 int *eof, void *data)
559 struct net_device *dev = data;
560 // struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
568 /* This dump the current register page */
571 //printk( "\nD: %2x> ", n);
572 len += snprintf(page + len, count - len,
575 for(i=0;i<16 && n<=max;i++,n++)
576 len += snprintf(page + len, count - len,
577 "%2x ",read_phy_ofdm(dev,n));
579 // printk("%2x ",read_nic_byte(dev,n));
581 len += snprintf(page + len, count - len,"\n");
592 static int proc_get_stats_hw(char *page, char **start,
593 off_t offset, int count,
594 int *eof, void *data)
596 struct net_device *dev = data;
597 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
601 len += snprintf(page + len, count - len,
612 static int proc_get_stats_tx(char *page, char **start,
613 off_t offset, int count,
614 int *eof, void *data)
616 struct net_device *dev = data;
617 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
621 len += snprintf(page + len, count - len,
622 "TX VI priority ok int: %lu\n"
623 // "TX VI priority error int: %lu\n"
624 "TX VO priority ok int: %lu\n"
625 // "TX VO priority error int: %lu\n"
626 "TX BE priority ok int: %lu\n"
627 // "TX BE priority error int: %lu\n"
628 "TX BK priority ok int: %lu\n"
629 // "TX BK priority error int: %lu\n"
630 "TX MANAGE priority ok int: %lu\n"
631 // "TX MANAGE priority error int: %lu\n"
632 "TX BEACON priority ok int: %lu\n"
633 "TX BEACON priority error int: %lu\n"
634 "TX CMDPKT priority ok int: %lu\n"
635 // "TX high priority ok int: %lu\n"
636 // "TX high priority failed error int: %lu\n"
637 // "TX queue resume: %lu\n"
638 "TX queue stopped?: %d\n"
639 "TX fifo overflow: %lu\n"
640 // "TX beacon: %lu\n"
641 // "TX VI queue: %d\n"
642 // "TX VO queue: %d\n"
643 // "TX BE queue: %d\n"
644 // "TX BK queue: %d\n"
645 // "TX HW queue: %d\n"
646 // "TX VI dropped: %lu\n"
647 // "TX VO dropped: %lu\n"
648 // "TX BE dropped: %lu\n"
649 // "TX BK dropped: %lu\n"
650 "TX total data packets %lu\n"
651 "TX total data bytes :%lu\n",
652 // "TX beacon aborted: %lu\n",
653 priv->stats.txviokint,
654 // priv->stats.txvierr,
655 priv->stats.txvookint,
656 // priv->stats.txvoerr,
657 priv->stats.txbeokint,
658 // priv->stats.txbeerr,
659 priv->stats.txbkokint,
660 // priv->stats.txbkerr,
661 priv->stats.txmanageokint,
662 // priv->stats.txmanageerr,
663 priv->stats.txbeaconokint,
664 priv->stats.txbeaconerr,
665 priv->stats.txcmdpktokint,
666 // priv->stats.txhpokint,
667 // priv->stats.txhperr,
668 // priv->stats.txresumed,
669 netif_queue_stopped(dev),
670 priv->stats.txoverflow,
671 // priv->stats.txbeacon,
672 // atomic_read(&(priv->tx_pending[VI_QUEUE])),
673 // atomic_read(&(priv->tx_pending[VO_QUEUE])),
674 // atomic_read(&(priv->tx_pending[BE_QUEUE])),
675 // atomic_read(&(priv->tx_pending[BK_QUEUE])),
676 // read_nic_byte(dev, TXFIFOCOUNT),
677 // priv->stats.txvidrop,
678 // priv->stats.txvodrop,
679 priv->ieee80211->stats.tx_packets,
680 priv->ieee80211->stats.tx_bytes
683 // priv->stats.txbedrop,
684 // priv->stats.txbkdrop
685 // priv->stats.txdatapkt
686 // priv->stats.txbeaconerr
695 static int proc_get_stats_rx(char *page, char **start,
696 off_t offset, int count,
697 int *eof, void *data)
699 struct net_device *dev = data;
700 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
704 len += snprintf(page + len, count - len,
707 "RX rx overflow error: %lu\n"
708 "RX invalid urb error: %lu\n",
711 priv->stats.rxoverflow,
712 priv->stats.rxurberr);
718 static void rtl8192_proc_module_init(void)
720 RT_TRACE(COMP_INIT, "Initializing proc filesystem");
721 #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24))
722 rtl8192_proc=create_proc_entry(RTL819xE_MODULE_NAME, S_IFDIR, proc_net);
724 rtl8192_proc=create_proc_entry(RTL819xE_MODULE_NAME, S_IFDIR, init_net.proc_net);
729 static void rtl8192_proc_module_remove(void)
731 #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24))
732 remove_proc_entry(RTL819xE_MODULE_NAME, proc_net);
734 remove_proc_entry(RTL819xE_MODULE_NAME, init_net.proc_net);
739 static void rtl8192_proc_remove_one(struct net_device *dev)
741 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
743 printk("dev name=======> %s\n",dev->name);
746 // remove_proc_entry("stats-hw", priv->dir_dev);
747 remove_proc_entry("stats-tx", priv->dir_dev);
748 remove_proc_entry("stats-rx", priv->dir_dev);
749 // remove_proc_entry("stats-ieee", priv->dir_dev);
750 remove_proc_entry("stats-ap", priv->dir_dev);
751 remove_proc_entry("registers", priv->dir_dev);
752 // remove_proc_entry("cck-registers",priv->dir_dev);
753 // remove_proc_entry("ofdm-registers",priv->dir_dev);
754 //remove_proc_entry(dev->name, rtl8192_proc);
755 remove_proc_entry("wlan0", rtl8192_proc);
756 priv->dir_dev = NULL;
761 static void rtl8192_proc_init_one(struct net_device *dev)
763 struct proc_dir_entry *e;
764 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
765 priv->dir_dev = create_proc_entry(dev->name,
766 S_IFDIR | S_IRUGO | S_IXUGO,
768 if (!priv->dir_dev) {
769 RT_TRACE(COMP_ERR, "Unable to initialize /proc/net/rtl8192/%s\n",
774 e = create_proc_read_entry("stats-hw", S_IFREG | S_IRUGO,
775 priv->dir_dev, proc_get_stats_hw, dev);
778 DMESGE("Unable to initialize "
779 "/proc/net/rtl8192/%s/stats-hw\n",
783 e = create_proc_read_entry("stats-rx", S_IFREG | S_IRUGO,
784 priv->dir_dev, proc_get_stats_rx, dev);
787 RT_TRACE(COMP_ERR,"Unable to initialize "
788 "/proc/net/rtl8192/%s/stats-rx\n",
793 e = create_proc_read_entry("stats-tx", S_IFREG | S_IRUGO,
794 priv->dir_dev, proc_get_stats_tx, dev);
797 RT_TRACE(COMP_ERR, "Unable to initialize "
798 "/proc/net/rtl8192/%s/stats-tx\n",
802 e = create_proc_read_entry("stats-ieee", S_IFREG | S_IRUGO,
803 priv->dir_dev, proc_get_stats_ieee, dev);
806 DMESGE("Unable to initialize "
807 "/proc/net/rtl8192/%s/stats-ieee\n",
813 e = create_proc_read_entry("stats-ap", S_IFREG | S_IRUGO,
814 priv->dir_dev, proc_get_stats_ap, dev);
817 RT_TRACE(COMP_ERR, "Unable to initialize "
818 "/proc/net/rtl8192/%s/stats-ap\n",
822 e = create_proc_read_entry("registers", S_IFREG | S_IRUGO,
823 priv->dir_dev, proc_get_registers, dev);
825 RT_TRACE(COMP_ERR, "Unable to initialize "
826 "/proc/net/rtl8192/%s/registers\n",
830 e = create_proc_read_entry("cck-registers", S_IFREG | S_IRUGO,
831 priv->dir_dev, proc_get_cck_reg, dev);
833 RT_TRACE(COMP_ERR, "Unable to initialize "
834 "/proc/net/rtl8192/%s/cck-registers\n",
838 e = create_proc_read_entry("ofdm-registers", S_IFREG | S_IRUGO,
839 priv->dir_dev, proc_get_ofdm_reg, dev);
841 RT_TRACE(COMP_ERR, "Unable to initialize "
842 "/proc/net/rtl8192/%s/ofdm-registers\n",
847 /****************************************************************************
848 -----------------------------MISC STUFF-------------------------
849 *****************************************************************************/
851 short check_nic_enough_desc(struct net_device *dev, int prio)
853 struct r8192_priv *priv = ieee80211_priv(dev);
854 struct rtl8192_tx_ring *ring = &priv->tx_ring[prio];
856 /* for now we reserve two free descriptor as a safety boundary
857 * between the tail and the head
859 if (ring->entries - skb_queue_len(&ring->queue) >= 2) {
866 static void tx_timeout(struct net_device *dev)
868 struct r8192_priv *priv = ieee80211_priv(dev);
869 //rtl8192_commit(dev);
871 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
872 schedule_work(&priv->reset_wq);
874 schedule_task(&priv->reset_wq);
880 /****************************************************************************
881 ------------------------------HW STUFF---------------------------
882 *****************************************************************************/
885 static void rtl8192_irq_enable(struct net_device *dev)
887 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
888 priv->irq_enabled = 1;
889 write_nic_dword(dev,INTA_MASK, priv->irq_mask);
893 static void rtl8192_irq_disable(struct net_device *dev)
895 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
897 write_nic_dword(dev,INTA_MASK,0);
898 force_pci_posting(dev);
899 priv->irq_enabled = 0;
903 static void rtl8192_set_mode(struct net_device *dev,int mode)
906 ecmd=read_nic_byte(dev, EPROM_CMD);
907 ecmd=ecmd &~ EPROM_CMD_OPERATING_MODE_MASK;
908 ecmd=ecmd | (mode<<EPROM_CMD_OPERATING_MODE_SHIFT);
909 ecmd=ecmd &~ (1<<EPROM_CS_SHIFT);
910 ecmd=ecmd &~ (1<<EPROM_CK_SHIFT);
911 write_nic_byte(dev, EPROM_CMD, ecmd);
915 void rtl8192_update_msr(struct net_device *dev)
917 struct r8192_priv *priv = ieee80211_priv(dev);
920 msr = read_nic_byte(dev, MSR);
921 msr &= ~ MSR_LINK_MASK;
923 /* do not change in link_state != WLAN_LINK_ASSOCIATED.
924 * msr must be updated if the state is ASSOCIATING.
925 * this is intentional and make sense for ad-hoc and
926 * master (see the create BSS/IBSS func)
928 if (priv->ieee80211->state == IEEE80211_LINKED){
930 if (priv->ieee80211->iw_mode == IW_MODE_INFRA)
931 msr |= (MSR_LINK_MANAGED<<MSR_LINK_SHIFT);
932 else if (priv->ieee80211->iw_mode == IW_MODE_ADHOC)
933 msr |= (MSR_LINK_ADHOC<<MSR_LINK_SHIFT);
934 else if (priv->ieee80211->iw_mode == IW_MODE_MASTER)
935 msr |= (MSR_LINK_MASTER<<MSR_LINK_SHIFT);
938 msr |= (MSR_LINK_NONE<<MSR_LINK_SHIFT);
940 write_nic_byte(dev, MSR, msr);
943 void rtl8192_set_chan(struct net_device *dev,short ch)
945 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
946 RT_TRACE(COMP_RF, "=====>%s()====ch:%d\n", __FUNCTION__, ch);
949 if(priv->ieee80211->iw_mode == IW_MODE_ADHOC ||
950 priv->ieee80211->iw_mode == IW_MODE_MASTER){
952 priv->ieee80211->link_state = WLAN_LINK_ASSOCIATED;
953 priv->ieee80211->master_chan = ch;
954 rtl8192_update_beacon_ch(dev);
958 /* this hack should avoid frame TX during channel setting*/
961 // tx = read_nic_dword(dev,TX_CONF);
962 // tx &= ~TX_LOOPBACK_MASK;
966 // write_nic_dword(dev,TX_CONF, tx |( TX_LOOPBACK_MAC<<TX_LOOPBACK_SHIFT));
968 //need to implement rf set channel here WB
970 if (priv->rf_set_chan)
971 priv->rf_set_chan(dev,priv->chan);
973 // write_nic_dword(dev,TX_CONF,tx | (TX_LOOPBACK_NONE<<TX_LOOPBACK_SHIFT));
977 void rtl8192_rx_enable(struct net_device *dev)
979 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
980 write_nic_dword(dev, RDQDA,priv->rx_ring_dma);
983 /* the TX_DESC_BASE setting is according to the following queue index
992 * BEACON_QUEUE ===> 8
994 static u32 TX_DESC_BASE[] = {BKQDA, BEQDA, VIQDA, VOQDA, HCCAQDA, CQDA, MQDA, HQDA, BQDA};
995 void rtl8192_tx_enable(struct net_device *dev)
997 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
999 for (i = 0; i < MAX_TX_QUEUE_COUNT; i++)
1000 write_nic_dword(dev, TX_DESC_BASE[i], priv->tx_ring[i].dma);
1002 ieee80211_reset_queue(priv->ieee80211);
1006 void rtl8192_beacon_tx_enable(struct net_device *dev)
1008 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1011 reg = read_nic_dword(priv->ieee80211->dev,INTA_MASK);
1013 /* enable Beacon realted interrupt signal */
1014 reg |= (IMR_BcnInt | IMR_BcnInt | IMR_TBDOK | IMR_TBDER);
1015 write_nic_byte(dev,reg);
1019 static void rtl8192_free_rx_ring(struct net_device *dev)
1021 struct r8192_priv *priv = ieee80211_priv(dev);
1024 for (i = 0; i < priv->rxringcount; i++) {
1025 struct sk_buff *skb = priv->rx_buf[i];
1029 pci_unmap_single(priv->pdev,
1030 *((dma_addr_t *)skb->cb),
1031 priv->rxbuffersize, PCI_DMA_FROMDEVICE);
1035 pci_free_consistent(priv->pdev, sizeof(*priv->rx_ring) * priv->rxringcount,
1036 priv->rx_ring, priv->rx_ring_dma);
1037 priv->rx_ring = NULL;
1040 static void rtl8192_free_tx_ring(struct net_device *dev, unsigned int prio)
1042 struct r8192_priv *priv = ieee80211_priv(dev);
1043 struct rtl8192_tx_ring *ring = &priv->tx_ring[prio];
1045 while (skb_queue_len(&ring->queue)) {
1046 tx_desc_819x_pci *entry = &ring->desc[ring->idx];
1047 struct sk_buff *skb = __skb_dequeue(&ring->queue);
1049 pci_unmap_single(priv->pdev, le32_to_cpu(entry->TxBuffAddr),
1050 skb->len, PCI_DMA_TODEVICE);
1052 ring->idx = (ring->idx + 1) % ring->entries;
1055 pci_free_consistent(priv->pdev, sizeof(*ring->desc)*ring->entries,
1056 ring->desc, ring->dma);
1061 static void rtl8192_beacon_disable(struct net_device *dev)
1063 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1066 reg = read_nic_dword(priv->ieee80211->dev,INTA_MASK);
1068 /* disable Beacon realted interrupt signal */
1069 reg &= ~(IMR_BcnInt | IMR_BcnInt | IMR_TBDOK | IMR_TBDER);
1070 write_nic_dword(priv->ieee80211->dev, INTA_MASK, reg);
1073 void rtl8192_rtx_disable(struct net_device *dev)
1076 struct r8192_priv *priv = ieee80211_priv(dev);
1079 cmd=read_nic_byte(dev,CMDR);
1080 // if(!priv->ieee80211->bSupportRemoteWakeUp) {
1081 write_nic_byte(dev, CMDR, cmd &~ \
1084 force_pci_posting(dev);
1087 for(i = 0; i < MAX_QUEUE_SIZE; i++) {
1088 skb_queue_purge(&priv->ieee80211->skb_waitQ [i]);
1090 for(i = 0; i < MAX_QUEUE_SIZE; i++) {
1091 skb_queue_purge(&priv->ieee80211->skb_aggQ [i]);
1095 skb_queue_purge(&priv->skb_queue);
1099 static void rtl8192_reset(struct net_device *dev)
1101 rtl8192_irq_disable(dev);
1102 printk("This is RTL819xP Reset procedure\n");
1105 static u16 rtl_rate[] = {10,20,55,110,60,90,120,180,240,360,480,540};
1106 inline u16 rtl8192_rate2rate(short rate)
1108 if (rate >11) return 0;
1109 return rtl_rate[rate];
1115 void rtl8192_tx_queues_stop(struct net_device *dev)
1117 //struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1118 u8 dma_poll_mask = (1<<TX_DMA_STOP_LOWPRIORITY_SHIFT);
1119 dma_poll_mask |= (1<<TX_DMA_STOP_HIPRIORITY_SHIFT);
1120 dma_poll_mask |= (1<<TX_DMA_STOP_NORMPRIORITY_SHIFT);
1121 dma_poll_mask |= (1<<TX_DMA_STOP_BEACON_SHIFT);
1123 rtl8192_set_mode(dev,EPROM_CMD_CONFIG);
1124 write_nic_byte(dev,TX_DMA_POLLING,dma_poll_mask);
1125 rtl8192_set_mode(dev,EPROM_CMD_NORMAL);
1129 static void rtl8192_data_hard_stop(struct net_device *dev)
1133 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1134 priv->dma_poll_mask |= (1<<TX_DMA_STOP_LOWPRIORITY_SHIFT);
1135 rtl8192_set_mode(dev,EPROM_CMD_CONFIG);
1136 write_nic_byte(dev,TX_DMA_POLLING,priv->dma_poll_mask);
1137 rtl8192_set_mode(dev,EPROM_CMD_NORMAL);
1142 static void rtl8192_data_hard_resume(struct net_device *dev)
1146 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1147 priv->dma_poll_mask &= ~(1<<TX_DMA_STOP_LOWPRIORITY_SHIFT);
1148 rtl8192_set_mode(dev,EPROM_CMD_CONFIG);
1149 write_nic_byte(dev,TX_DMA_POLLING,priv->dma_poll_mask);
1150 rtl8192_set_mode(dev,EPROM_CMD_NORMAL);
1154 /* this function TX data frames when the ieee80211 stack requires this.
1155 * It checks also if we need to stop the ieee tx queue, eventually do it
1157 static void rtl8192_hard_data_xmit(struct sk_buff *skb, struct net_device *dev, int rate)
1159 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1161 //unsigned long flags;
1162 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1163 u8 queue_index = tcb_desc->queue_index;
1164 /* shall not be referred by command packet */
1165 assert(queue_index != TXCMD_QUEUE);
1167 //spin_lock_irqsave(&priv->tx_lock,flags);
1169 memcpy((unsigned char *)(skb->cb),&dev,sizeof(dev));
1171 tcb_desc->RATRIndex = 7;
1172 tcb_desc->bTxDisableRateFallBack = 1;
1173 tcb_desc->bTxUseDriverAssingedRate = 1;
1174 tcb_desc->bTxEnableFwCalcDur = 1;
1176 skb_push(skb, priv->ieee80211->tx_headroom);
1177 ret = rtl8192_tx(dev, skb);
1183 if(queue_index!=MGNT_QUEUE) {
1184 priv->ieee80211->stats.tx_bytes+=(skb->len - priv->ieee80211->tx_headroom);
1185 priv->ieee80211->stats.tx_packets++;
1188 //spin_unlock_irqrestore(&priv->tx_lock,flags);
1194 /* This is a rough attempt to TX a frame
1195 * This is called by the ieee 80211 stack to TX management frames.
1196 * If the ring is full packet are dropped (for data frame the queue
1197 * is stopped before this can happen).
1199 static int rtl8192_hard_start_xmit(struct sk_buff *skb,struct net_device *dev)
1201 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1205 //unsigned long flags;
1206 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1207 u8 queue_index = tcb_desc->queue_index;
1210 //spin_lock_irqsave(&priv->tx_lock,flags);
1212 memcpy((unsigned char *)(skb->cb),&dev,sizeof(dev));
1213 if(queue_index == TXCMD_QUEUE) {
1214 // skb_push(skb, USB_HWDESC_HEADER_LEN);
1215 rtl819xE_tx_cmd(dev, skb);
1217 //spin_unlock_irqrestore(&priv->tx_lock,flags);
1220 // RT_TRACE(COMP_SEND, "To send management packet\n");
1221 tcb_desc->RATRIndex = 7;
1222 tcb_desc->bTxDisableRateFallBack = 1;
1223 tcb_desc->bTxUseDriverAssingedRate = 1;
1224 tcb_desc->bTxEnableFwCalcDur = 1;
1225 skb_push(skb, priv->ieee80211->tx_headroom);
1226 ret = rtl8192_tx(dev, skb);
1232 // priv->ieee80211->stats.tx_bytes+=skb->len;
1233 // priv->ieee80211->stats.tx_packets++;
1235 //spin_unlock_irqrestore(&priv->tx_lock,flags);
1242 void rtl8192_try_wake_queue(struct net_device *dev, int pri);
1244 static void rtl8192_tx_isr(struct net_device *dev, int prio)
1246 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1248 struct rtl8192_tx_ring *ring = &priv->tx_ring[prio];
1250 while (skb_queue_len(&ring->queue)) {
1251 tx_desc_819x_pci *entry = &ring->desc[ring->idx];
1252 struct sk_buff *skb;
1254 /* beacon packet will only use the first descriptor defautly,
1255 * and the OWN may not be cleared by the hardware
1257 if(prio != BEACON_QUEUE) {
1260 ring->idx = (ring->idx + 1) % ring->entries;
1263 skb = __skb_dequeue(&ring->queue);
1264 pci_unmap_single(priv->pdev, le32_to_cpu(entry->TxBuffAddr),
1265 skb->len, PCI_DMA_TODEVICE);
1269 if (prio == MGNT_QUEUE){
1270 if (priv->ieee80211->ack_tx_to_ieee){
1271 if (rtl8192_is_tx_queue_empty(dev)){
1272 priv->ieee80211->ack_tx_to_ieee = 0;
1273 ieee80211_ps_tx_ack(priv->ieee80211, 1);
1278 if(prio != BEACON_QUEUE) {
1279 /* try to deal with the pending packets */
1280 tasklet_schedule(&priv->irq_tx_tasklet);
1285 static void rtl8192_stop_beacon(struct net_device *dev)
1287 //rtl8192_beacon_disable(dev);
1290 static void rtl8192_config_rate(struct net_device* dev, u16* rate_config)
1292 struct r8192_priv *priv = ieee80211_priv(dev);
1293 struct ieee80211_network *net;
1294 u8 i=0, basic_rate = 0;
1295 net = & priv->ieee80211->current_network;
1297 for (i=0; i<net->rates_len; i++)
1299 basic_rate = net->rates[i]&0x7f;
1302 case MGN_1M: *rate_config |= RRSR_1M; break;
1303 case MGN_2M: *rate_config |= RRSR_2M; break;
1304 case MGN_5_5M: *rate_config |= RRSR_5_5M; break;
1305 case MGN_11M: *rate_config |= RRSR_11M; break;
1306 case MGN_6M: *rate_config |= RRSR_6M; break;
1307 case MGN_9M: *rate_config |= RRSR_9M; break;
1308 case MGN_12M: *rate_config |= RRSR_12M; break;
1309 case MGN_18M: *rate_config |= RRSR_18M; break;
1310 case MGN_24M: *rate_config |= RRSR_24M; break;
1311 case MGN_36M: *rate_config |= RRSR_36M; break;
1312 case MGN_48M: *rate_config |= RRSR_48M; break;
1313 case MGN_54M: *rate_config |= RRSR_54M; break;
1316 for (i=0; i<net->rates_ex_len; i++)
1318 basic_rate = net->rates_ex[i]&0x7f;
1321 case MGN_1M: *rate_config |= RRSR_1M; break;
1322 case MGN_2M: *rate_config |= RRSR_2M; break;
1323 case MGN_5_5M: *rate_config |= RRSR_5_5M; break;
1324 case MGN_11M: *rate_config |= RRSR_11M; break;
1325 case MGN_6M: *rate_config |= RRSR_6M; break;
1326 case MGN_9M: *rate_config |= RRSR_9M; break;
1327 case MGN_12M: *rate_config |= RRSR_12M; break;
1328 case MGN_18M: *rate_config |= RRSR_18M; break;
1329 case MGN_24M: *rate_config |= RRSR_24M; break;
1330 case MGN_36M: *rate_config |= RRSR_36M; break;
1331 case MGN_48M: *rate_config |= RRSR_48M; break;
1332 case MGN_54M: *rate_config |= RRSR_54M; break;
1338 #define SHORT_SLOT_TIME 9
1339 #define NON_SHORT_SLOT_TIME 20
1341 static void rtl8192_update_cap(struct net_device* dev, u16 cap)
1344 struct r8192_priv *priv = ieee80211_priv(dev);
1345 struct ieee80211_network *net = &priv->ieee80211->current_network;
1346 priv->short_preamble = cap & WLAN_CAPABILITY_SHORT_PREAMBLE;
1347 tmp = priv->basic_rate;
1348 if (priv->short_preamble)
1349 tmp |= BRSR_AckShortPmb;
1350 write_nic_dword(dev, RRSR, tmp);
1352 if (net->mode & (IEEE_G|IEEE_N_24G))
1355 if ((cap & WLAN_CAPABILITY_SHORT_SLOT)&&(!priv->ieee80211->pHTInfo->bCurrentRT2RTLongSlotTime))
1357 slot_time = SHORT_SLOT_TIME;
1359 else //long slot time
1360 slot_time = NON_SHORT_SLOT_TIME;
1361 priv->slot_time = slot_time;
1362 write_nic_byte(dev, SLOT_TIME, slot_time);
1367 static void rtl8192_net_update(struct net_device *dev)
1370 struct r8192_priv *priv = ieee80211_priv(dev);
1371 struct ieee80211_network *net;
1372 u16 BcnTimeCfg = 0, BcnCW = 6, BcnIFS = 0xf;
1373 u16 rate_config = 0;
1374 net = &priv->ieee80211->current_network;
1375 //update Basic rate: RR, BRSR
1376 rtl8192_config_rate(dev, &rate_config);
1377 // 2007.01.16, by Emily
1378 // Select RRSR (in Legacy-OFDM and CCK)
1379 // For 8190, we select only 24M, 12M, 6M, 11M, 5.5M, 2M, and 1M from the Basic rate.
1380 // We do not use other rates.
1381 priv->basic_rate = rate_config &= 0x15f;
1383 write_nic_dword(dev,BSSIDR,((u32*)net->bssid)[0]);
1384 write_nic_word(dev,BSSIDR+4,((u16*)net->bssid)[2]);
1387 rtl8192_update_msr(dev);
1391 // rtl8192_update_cap(dev, net->capability);
1392 if (priv->ieee80211->iw_mode == IW_MODE_ADHOC)
1394 write_nic_word(dev, ATIMWND, 2);
1395 write_nic_word(dev, BCN_DMATIME, 256);
1396 write_nic_word(dev, BCN_INTERVAL, net->beacon_interval);
1397 // write_nic_word(dev, BcnIntTime, 100);
1398 //BIT15 of BCN_DRV_EARLY_INT will indicate whether software beacon or hw beacon is applied.
1399 write_nic_word(dev, BCN_DRV_EARLY_INT, 10);
1400 write_nic_byte(dev, BCN_ERR_THRESH, 100);
1402 BcnTimeCfg |= (BcnCW<<BCN_TCFG_CW_SHIFT);
1403 // TODO: BcnIFS may required to be changed on ASIC
1404 BcnTimeCfg |= BcnIFS<<BCN_TCFG_IFS;
1406 write_nic_word(dev, BCN_TCFG, BcnTimeCfg);
1412 void rtl819xE_tx_cmd(struct net_device *dev, struct sk_buff *skb)
1414 struct r8192_priv *priv = ieee80211_priv(dev);
1415 struct rtl8192_tx_ring *ring;
1416 tx_desc_819x_pci *entry;
1420 unsigned long flags;
1422 ring = &priv->tx_ring[TXCMD_QUEUE];
1423 mapping = pci_map_single(priv->pdev, skb->data, skb->len, PCI_DMA_TODEVICE);
1425 spin_lock_irqsave(&priv->irq_th_lock,flags);
1426 idx = (ring->idx + skb_queue_len(&ring->queue)) % ring->entries;
1427 entry = &ring->desc[idx];
1429 tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1431 entry->LINIP = tcb_desc->bLastIniPkt;
1432 entry->FirstSeg = 1;//first segment
1433 entry->LastSeg = 1; //last segment
1434 if(tcb_desc->bCmdOrInit == DESC_PACKET_TYPE_INIT) {
1435 entry->CmdInit = DESC_PACKET_TYPE_INIT;
1437 entry->CmdInit = DESC_PACKET_TYPE_NORMAL;
1438 entry->Offset = sizeof(TX_FWINFO_8190PCI) + 8;
1439 entry->PktSize = (u16)(tcb_desc->pkt_size + entry->Offset);
1440 entry->QueueSelect = QSLT_CMD;
1441 entry->TxFWInfoSize = 0x08;
1442 entry->RATid = (u8)DESC_PACKET_TYPE_INIT;
1444 entry->TxBufferSize = skb->len;
1445 entry->TxBuffAddr = cpu_to_le32(mapping);
1448 #ifdef JOHN_DUMP_TXDESC
1450 tx_desc_819x_pci *entry1 = &ring->desc[0];
1451 unsigned int *ptr= (unsigned int *)entry1;
1452 printk("<Tx descriptor>:\n");
1453 for (i = 0; i < 8; i++)
1454 printk("%8x ", ptr[i]);
1458 __skb_queue_tail(&ring->queue, skb);
1459 spin_unlock_irqrestore(&priv->irq_th_lock,flags);
1461 write_nic_byte(dev, TPPoll, TPPoll_CQ);
1467 * Mapping Software/Hardware descriptor queue id to "Queue Select Field"
1468 * in TxFwInfo data structure
1469 * 2006.10.30 by Emily
1471 * \param QUEUEID Software Queue
1473 static u8 MapHwQueueToFirmwareQueue(u8 QueueID)
1475 u8 QueueSelect = 0x0; //defualt set to
1479 QueueSelect = QSLT_BE; //or QSelect = pTcb->priority;
1483 QueueSelect = QSLT_BK; //or QSelect = pTcb->priority;
1487 QueueSelect = QSLT_VO; //or QSelect = pTcb->priority;
1491 QueueSelect = QSLT_VI; //or QSelect = pTcb->priority;
1494 QueueSelect = QSLT_MGNT;
1498 QueueSelect = QSLT_BEACON;
1501 // TODO: 2006.10.30 mark other queue selection until we verify it is OK
1502 // TODO: Remove Assertions
1503 //#if (RTL819X_FPGA_VER & RTL819X_FPGA_GUANGAN_070502)
1505 QueueSelect = QSLT_CMD;
1509 //QueueSelect = QSLT_HIGH;
1513 RT_TRACE(COMP_ERR, "TransmitTCB(): Impossible Queue Selection: %d \n", QueueID);
1519 static u8 MRateToHwRate8190Pci(u8 rate)
1521 u8 ret = DESC90_RATE1M;
1524 case MGN_1M: ret = DESC90_RATE1M; break;
1525 case MGN_2M: ret = DESC90_RATE2M; break;
1526 case MGN_5_5M: ret = DESC90_RATE5_5M; break;
1527 case MGN_11M: ret = DESC90_RATE11M; break;
1528 case MGN_6M: ret = DESC90_RATE6M; break;
1529 case MGN_9M: ret = DESC90_RATE9M; break;
1530 case MGN_12M: ret = DESC90_RATE12M; break;
1531 case MGN_18M: ret = DESC90_RATE18M; break;
1532 case MGN_24M: ret = DESC90_RATE24M; break;
1533 case MGN_36M: ret = DESC90_RATE36M; break;
1534 case MGN_48M: ret = DESC90_RATE48M; break;
1535 case MGN_54M: ret = DESC90_RATE54M; break;
1537 // HT rate since here
1538 case MGN_MCS0: ret = DESC90_RATEMCS0; break;
1539 case MGN_MCS1: ret = DESC90_RATEMCS1; break;
1540 case MGN_MCS2: ret = DESC90_RATEMCS2; break;
1541 case MGN_MCS3: ret = DESC90_RATEMCS3; break;
1542 case MGN_MCS4: ret = DESC90_RATEMCS4; break;
1543 case MGN_MCS5: ret = DESC90_RATEMCS5; break;
1544 case MGN_MCS6: ret = DESC90_RATEMCS6; break;
1545 case MGN_MCS7: ret = DESC90_RATEMCS7; break;
1546 case MGN_MCS8: ret = DESC90_RATEMCS8; break;
1547 case MGN_MCS9: ret = DESC90_RATEMCS9; break;
1548 case MGN_MCS10: ret = DESC90_RATEMCS10; break;
1549 case MGN_MCS11: ret = DESC90_RATEMCS11; break;
1550 case MGN_MCS12: ret = DESC90_RATEMCS12; break;
1551 case MGN_MCS13: ret = DESC90_RATEMCS13; break;
1552 case MGN_MCS14: ret = DESC90_RATEMCS14; break;
1553 case MGN_MCS15: ret = DESC90_RATEMCS15; break;
1554 case (0x80|0x20): ret = DESC90_RATEMCS32; break;
1562 static u8 QueryIsShort(u8 TxHT, u8 TxRate, cb_desc *tcb_desc)
1566 tmp_Short = (TxHT==1)?((tcb_desc->bUseShortGI)?1:0):((tcb_desc->bUseShortPreamble)?1:0);
1568 if(TxHT==1 && TxRate != DESC90_RATEMCS15)
1575 * The tx procedure is just as following,
1576 * skb->cb will contain all the following information,
1577 * priority, morefrag, rate, &dev.
1579 short rtl8192_tx(struct net_device *dev, struct sk_buff* skb)
1581 struct r8192_priv *priv = ieee80211_priv(dev);
1582 struct rtl8192_tx_ring *ring;
1583 unsigned long flags;
1584 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1585 tx_desc_819x_pci *pdesc = NULL;
1586 TX_FWINFO_8190PCI *pTxFwInfo = NULL;
1588 bool multi_addr=false,broad_addr=false,uni_addr=false;
1589 u8* pda_addr = NULL;
1592 mapping = pci_map_single(priv->pdev, skb->data, skb->len, PCI_DMA_TODEVICE);
1593 /* collect the tx packets statitcs */
1594 pda_addr = ((u8*)skb->data) + sizeof(TX_FWINFO_8190PCI);
1595 if(is_multicast_ether_addr(pda_addr))
1597 else if(is_broadcast_ether_addr(pda_addr))
1603 priv->stats.txbytesunicast += (u8)(skb->len) - sizeof(TX_FWINFO_8190PCI);
1605 priv->stats.txbytesmulticast +=(u8)(skb->len) - sizeof(TX_FWINFO_8190PCI);
1607 priv->stats.txbytesbroadcast += (u8)(skb->len) - sizeof(TX_FWINFO_8190PCI);
1609 /* fill tx firmware */
1610 pTxFwInfo = (PTX_FWINFO_8190PCI)skb->data;
1611 memset(pTxFwInfo,0,sizeof(TX_FWINFO_8190PCI));
1612 pTxFwInfo->TxHT = (tcb_desc->data_rate&0x80)?1:0;
1613 pTxFwInfo->TxRate = MRateToHwRate8190Pci((u8)tcb_desc->data_rate);
1614 pTxFwInfo->EnableCPUDur = tcb_desc->bTxEnableFwCalcDur;
1615 pTxFwInfo->Short = QueryIsShort(pTxFwInfo->TxHT, pTxFwInfo->TxRate, tcb_desc);
1617 /* Aggregation related */
1618 if(tcb_desc->bAMPDUEnable) {
1619 pTxFwInfo->AllowAggregation = 1;
1620 pTxFwInfo->RxMF = tcb_desc->ampdu_factor;
1621 pTxFwInfo->RxAMD = tcb_desc->ampdu_density;
1623 pTxFwInfo->AllowAggregation = 0;
1624 pTxFwInfo->RxMF = 0;
1625 pTxFwInfo->RxAMD = 0;
1629 // Protection mode related
1631 pTxFwInfo->RtsEnable = (tcb_desc->bRTSEnable)?1:0;
1632 pTxFwInfo->CtsEnable = (tcb_desc->bCTSEnable)?1:0;
1633 pTxFwInfo->RtsSTBC = (tcb_desc->bRTSSTBC)?1:0;
1634 pTxFwInfo->RtsHT= (tcb_desc->rts_rate&0x80)?1:0;
1635 pTxFwInfo->RtsRate = MRateToHwRate8190Pci((u8)tcb_desc->rts_rate);
1636 pTxFwInfo->RtsBandwidth = 0;
1637 pTxFwInfo->RtsSubcarrier = tcb_desc->RTSSC;
1638 pTxFwInfo->RtsShort = (pTxFwInfo->RtsHT==0)?(tcb_desc->bRTSUseShortPreamble?1:0):(tcb_desc->bRTSUseShortGI?1:0);
1640 // Set Bandwidth and sub-channel settings.
1642 if(priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20_40)
1644 if(tcb_desc->bPacketBW)
1646 pTxFwInfo->TxBandwidth = 1;
1648 pTxFwInfo->TxSubCarrier = 3;
1650 pTxFwInfo->TxSubCarrier = 0; //By SD3's Jerry suggestion, use duplicated mode, cosa 04012008
1655 pTxFwInfo->TxBandwidth = 0;
1656 pTxFwInfo->TxSubCarrier = priv->nCur40MhzPrimeSC;
1659 pTxFwInfo->TxBandwidth = 0;
1660 pTxFwInfo->TxSubCarrier = 0;
1665 /* 2007/07/25 MH Copy current TX FW info.*/
1666 memcpy((void*)(&Tmp_TxFwInfo), (void*)(pTxFwInfo), sizeof(TX_FWINFO_8190PCI));
1667 printk("&&&&&&&&&&&&&&&&&&&&&&====>print out fwinf\n");
1668 printk("===>enable fwcacl:%d\n", Tmp_TxFwInfo.EnableCPUDur);
1669 printk("===>RTS STBC:%d\n", Tmp_TxFwInfo.RtsSTBC);
1670 printk("===>RTS Subcarrier:%d\n", Tmp_TxFwInfo.RtsSubcarrier);
1671 printk("===>Allow Aggregation:%d\n", Tmp_TxFwInfo.AllowAggregation);
1672 printk("===>TX HT bit:%d\n", Tmp_TxFwInfo.TxHT);
1673 printk("===>Tx rate:%d\n", Tmp_TxFwInfo.TxRate);
1674 printk("===>Received AMPDU Density:%d\n", Tmp_TxFwInfo.RxAMD);
1675 printk("===>Received MPDU Factor:%d\n", Tmp_TxFwInfo.RxMF);
1676 printk("===>TxBandwidth:%d\n", Tmp_TxFwInfo.TxBandwidth);
1677 printk("===>TxSubCarrier:%d\n", Tmp_TxFwInfo.TxSubCarrier);
1679 printk("<=====**********************out of print\n");
1682 spin_lock_irqsave(&priv->irq_th_lock,flags);
1683 ring = &priv->tx_ring[tcb_desc->queue_index];
1684 if (tcb_desc->queue_index != BEACON_QUEUE) {
1685 idx = (ring->idx + skb_queue_len(&ring->queue)) % ring->entries;
1690 pdesc = &ring->desc[idx];
1691 if((pdesc->OWN == 1) && (tcb_desc->queue_index != BEACON_QUEUE)) {
1692 RT_TRACE(COMP_ERR,"No more TX desc@%d, ring->idx = %d,idx = %d,%x", \
1693 tcb_desc->queue_index,ring->idx, idx,skb->len);
1697 /* fill tx descriptor */
1698 memset((u8*)pdesc,0,12);
1702 pdesc->Offset = sizeof(TX_FWINFO_8190PCI) + 8; //We must add 8!! Emily
1703 pdesc->PktSize = (u16)skb->len-sizeof(TX_FWINFO_8190PCI);
1707 pdesc->RATid = tcb_desc->RATRIndex;
1711 pdesc->SecType = 0x0;
1712 if (tcb_desc->bHwSec) {
1715 printk("==>================hw sec\n");
1718 switch (priv->ieee80211->pairwise_key_type) {
1719 case KEY_TYPE_WEP40:
1720 case KEY_TYPE_WEP104:
1721 pdesc->SecType = 0x1;
1725 pdesc->SecType = 0x2;
1729 pdesc->SecType = 0x3;
1733 pdesc->SecType = 0x0;
1744 pdesc->QueueSelect = MapHwQueueToFirmwareQueue(tcb_desc->queue_index);
1745 pdesc->TxFWInfoSize = sizeof(TX_FWINFO_8190PCI);
1747 pdesc->DISFB = tcb_desc->bTxDisableRateFallBack;
1748 pdesc->USERATE = tcb_desc->bTxUseDriverAssingedRate;
1752 pdesc->TxBufferSize = skb->len;
1754 pdesc->TxBuffAddr = cpu_to_le32(mapping);
1755 __skb_queue_tail(&ring->queue, skb);
1757 spin_unlock_irqrestore(&priv->irq_th_lock,flags);
1758 dev->trans_start = jiffies;
1759 write_nic_word(dev,TPPoll,0x01<<tcb_desc->queue_index);
1763 static short rtl8192_alloc_rx_desc_ring(struct net_device *dev)
1765 struct r8192_priv *priv = ieee80211_priv(dev);
1766 rx_desc_819x_pci *entry = NULL;
1769 priv->rx_ring = pci_alloc_consistent(priv->pdev,
1770 sizeof(*priv->rx_ring) * priv->rxringcount, &priv->rx_ring_dma);
1772 if (!priv->rx_ring || (unsigned long)priv->rx_ring & 0xFF) {
1773 RT_TRACE(COMP_ERR,"Cannot allocate RX ring\n");
1777 memset(priv->rx_ring, 0, sizeof(*priv->rx_ring) * priv->rxringcount);
1780 for (i = 0; i < priv->rxringcount; i++) {
1781 struct sk_buff *skb = dev_alloc_skb(priv->rxbuffersize);
1782 dma_addr_t *mapping;
1783 entry = &priv->rx_ring[i];
1786 priv->rx_buf[i] = skb;
1787 mapping = (dma_addr_t *)skb->cb;
1788 *mapping = pci_map_single(priv->pdev, skb->tail,//skb_tail_pointer(skb),
1789 priv->rxbuffersize, PCI_DMA_FROMDEVICE);
1791 entry->BufferAddress = cpu_to_le32(*mapping);
1793 entry->Length = priv->rxbuffersize;
1801 static int rtl8192_alloc_tx_desc_ring(struct net_device *dev,
1802 unsigned int prio, unsigned int entries)
1804 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1805 tx_desc_819x_pci *ring;
1809 ring = pci_alloc_consistent(priv->pdev, sizeof(*ring) * entries, &dma);
1810 if (!ring || (unsigned long)ring & 0xFF) {
1811 RT_TRACE(COMP_ERR, "Cannot allocate TX ring (prio = %d)\n", prio);
1815 memset(ring, 0, sizeof(*ring)*entries);
1816 priv->tx_ring[prio].desc = ring;
1817 priv->tx_ring[prio].dma = dma;
1818 priv->tx_ring[prio].idx = 0;
1819 priv->tx_ring[prio].entries = entries;
1820 skb_queue_head_init(&priv->tx_ring[prio].queue);
1822 for (i = 0; i < entries; i++)
1823 ring[i].NextDescAddress =
1824 cpu_to_le32((u32)dma + ((i + 1) % entries) * sizeof(*ring));
1830 static short rtl8192_pci_initdescring(struct net_device *dev)
1834 struct r8192_priv *priv = ieee80211_priv(dev);
1836 ret = rtl8192_alloc_rx_desc_ring(dev);
1842 /* general process for other queue */
1843 for (i = 0; i < MAX_TX_QUEUE_COUNT; i++) {
1844 if ((ret = rtl8192_alloc_tx_desc_ring(dev, i, priv->txringcount)))
1845 goto err_free_rings;
1849 /* specific process for hardware beacon process */
1850 if ((ret = rtl8192_alloc_tx_desc_ring(dev, MAX_TX_QUEUE_COUNT - 1, 2)))
1851 goto err_free_rings;
1857 rtl8192_free_rx_ring(dev);
1858 for (i = 0; i < MAX_TX_QUEUE_COUNT; i++)
1859 if (priv->tx_ring[i].desc)
1860 rtl8192_free_tx_ring(dev, i);
1864 static void rtl8192_pci_resetdescring(struct net_device *dev)
1866 struct r8192_priv *priv = ieee80211_priv(dev);
1869 /* force the rx_idx to the first one */
1871 rx_desc_819x_pci *entry = NULL;
1872 for (i = 0; i < priv->rxringcount; i++) {
1873 entry = &priv->rx_ring[i];
1879 /* after reset, release previous pending packet, and force the
1880 * tx idx to the first one */
1881 for (i = 0; i < MAX_TX_QUEUE_COUNT; i++) {
1882 if (priv->tx_ring[i].desc) {
1883 struct rtl8192_tx_ring *ring = &priv->tx_ring[i];
1885 while (skb_queue_len(&ring->queue)) {
1886 tx_desc_819x_pci *entry = &ring->desc[ring->idx];
1887 struct sk_buff *skb = __skb_dequeue(&ring->queue);
1889 pci_unmap_single(priv->pdev, le32_to_cpu(entry->TxBuffAddr),
1890 skb->len, PCI_DMA_TODEVICE);
1892 ring->idx = (ring->idx + 1) % ring->entries;
1900 extern void rtl8192_update_ratr_table(struct net_device* dev);
1901 static void rtl8192_link_change(struct net_device *dev)
1905 struct r8192_priv *priv = ieee80211_priv(dev);
1906 struct ieee80211_device* ieee = priv->ieee80211;
1907 //write_nic_word(dev, BCN_INTR_ITV, net->beacon_interval);
1908 if (ieee->state == IEEE80211_LINKED)
1910 rtl8192_net_update(dev);
1911 rtl8192_update_ratr_table(dev);
1913 //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
1914 if ((KEY_TYPE_WEP40 == ieee->pairwise_key_type) || (KEY_TYPE_WEP104 == ieee->pairwise_key_type))
1915 EnableHWSecurityConfig8192(dev);
1920 write_nic_byte(dev, 0x173, 0);
1922 /*update timing params*/
1923 //rtl8192_set_chan(dev, priv->chan);
1925 rtl8192_update_msr(dev);
1927 // 2007/10/16 MH MAC Will update TSF according to all received beacon, so we have
1928 // // To set CBSSID bit when link with any AP or STA.
1929 if (ieee->iw_mode == IW_MODE_INFRA || ieee->iw_mode == IW_MODE_ADHOC)
1932 reg = read_nic_dword(dev, RCR);
1933 if (priv->ieee80211->state == IEEE80211_LINKED)
1934 priv->ReceiveConfig = reg |= RCR_CBSSID;
1936 priv->ReceiveConfig = reg &= ~RCR_CBSSID;
1937 write_nic_dword(dev, RCR, reg);
1943 static struct ieee80211_qos_parameters def_qos_parameters = {
1944 {3,3,3,3},/* cw_min */
1945 {7,7,7,7},/* cw_max */
1946 {2,2,2,2},/* aifs */
1947 {0,0,0,0},/* flags */
1948 {0,0,0,0} /* tx_op_limit */
1951 #if LINUX_VERSION_CODE >=KERNEL_VERSION(2,6,20)
1952 static void rtl8192_update_beacon(struct work_struct * work)
1954 struct r8192_priv *priv = container_of(work, struct r8192_priv, update_beacon_wq.work);
1955 struct net_device *dev = priv->ieee80211->dev;
1957 void rtl8192_update_beacon(struct net_device *dev)
1959 struct r8192_priv *priv = ieee80211_priv(dev);
1961 struct ieee80211_device* ieee = priv->ieee80211;
1962 struct ieee80211_network* net = &ieee->current_network;
1964 if (ieee->pHTInfo->bCurrentHTSupport)
1965 HTUpdateSelfAndPeerSetting(ieee, net);
1966 ieee->pHTInfo->bCurrentRT2RTLongSlotTime = net->bssht.bdRT2RTLongSlotTime;
1967 rtl8192_update_cap(dev, net->capability);
1970 * background support to run QoS activate functionality
1972 static int WDCAPARA_ADD[] = {EDCAPARA_BE,EDCAPARA_BK,EDCAPARA_VI,EDCAPARA_VO};
1973 #if LINUX_VERSION_CODE >=KERNEL_VERSION(2,6,20)
1974 static void rtl8192_qos_activate(struct work_struct * work)
1976 struct r8192_priv *priv = container_of(work, struct r8192_priv, qos_activate);
1977 struct net_device *dev = priv->ieee80211->dev;
1979 void rtl8192_qos_activate(struct net_device *dev)
1981 struct r8192_priv *priv = ieee80211_priv(dev);
1983 struct ieee80211_qos_parameters *qos_parameters = &priv->ieee80211->current_network.qos_data.parameters;
1984 u8 mode = priv->ieee80211->current_network.mode;
1985 // u32 size = sizeof(struct ieee80211_qos_parameters);
1992 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16))
1995 mutex_lock(&priv->mutex);
1997 if(priv->ieee80211->state != IEEE80211_LINKED)
1999 RT_TRACE(COMP_QOS,"qos active process with associate response received\n");
2000 /* It better set slot time at first */
2001 /* For we just support b/g mode at present, let the slot time at 9/20 selection */
2002 /* update the ac parameter to related registers */
2003 for(i = 0; i < QOS_QUEUE_NUM; i++) {
2004 //Mode G/A: slotTimeTimer = 9; Mode B: 20
2005 u1bAIFS = qos_parameters->aifs[i] * ((mode&(IEEE_G|IEEE_N_24G)) ?9:20) + aSifsTime;
2006 u4bAcParam = ((((u32)(qos_parameters->tx_op_limit[i]))<< AC_PARAM_TXOP_LIMIT_OFFSET)|
2007 (((u32)(qos_parameters->cw_max[i]))<< AC_PARAM_ECW_MAX_OFFSET)|
2008 (((u32)(qos_parameters->cw_min[i]))<< AC_PARAM_ECW_MIN_OFFSET)|
2009 ((u32)u1bAIFS << AC_PARAM_AIFS_OFFSET));
2010 printk("===>u4bAcParam:%x, ", u4bAcParam);
2011 write_nic_dword(dev, WDCAPARA_ADD[i], u4bAcParam);
2012 //write_nic_dword(dev, WDCAPARA_ADD[i], 0x005e4332);
2016 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16))
2019 mutex_unlock(&priv->mutex);
2023 static int rtl8192_qos_handle_probe_response(struct r8192_priv *priv,
2025 struct ieee80211_network *network)
2028 u32 size = sizeof(struct ieee80211_qos_parameters);
2030 if(priv->ieee80211->state !=IEEE80211_LINKED)
2033 if ((priv->ieee80211->iw_mode != IW_MODE_INFRA))
2036 if (network->flags & NETWORK_HAS_QOS_MASK) {
2037 if (active_network &&
2038 (network->flags & NETWORK_HAS_QOS_PARAMETERS))
2039 network->qos_data.active = network->qos_data.supported;
2041 if ((network->qos_data.active == 1) && (active_network == 1) &&
2042 (network->flags & NETWORK_HAS_QOS_PARAMETERS) &&
2043 (network->qos_data.old_param_count !=
2044 network->qos_data.param_count)) {
2045 network->qos_data.old_param_count =
2046 network->qos_data.param_count;
2047 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
2048 queue_work(priv->priv_wq, &priv->qos_activate);
2050 schedule_task(&priv->qos_activate);
2052 RT_TRACE (COMP_QOS, "QoS parameters change call "
2056 memcpy(&priv->ieee80211->current_network.qos_data.parameters,\
2057 &def_qos_parameters, size);
2059 if ((network->qos_data.active == 1) && (active_network == 1)) {
2060 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
2061 queue_work(priv->priv_wq, &priv->qos_activate);
2063 schedule_task(&priv->qos_activate);
2065 RT_TRACE(COMP_QOS, "QoS was disabled call qos_activate \n");
2067 network->qos_data.active = 0;
2068 network->qos_data.supported = 0;
2074 /* handle manage frame frame beacon and probe response */
2075 static int rtl8192_handle_beacon(struct net_device * dev,
2076 struct ieee80211_beacon * beacon,
2077 struct ieee80211_network * network)
2079 struct r8192_priv *priv = ieee80211_priv(dev);
2081 rtl8192_qos_handle_probe_response(priv,1,network);
2083 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
2084 queue_delayed_work(priv->priv_wq, &priv->update_beacon_wq, 0);
2086 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
2087 schedule_task(&priv->update_beacon_wq);
2089 queue_work(priv->priv_wq, &priv->update_beacon_wq);
2097 * handling the beaconing responses. if we get different QoS setting
2098 * off the network from the associated setting, adjust the QoS
2101 static int rtl8192_qos_association_resp(struct r8192_priv *priv,
2102 struct ieee80211_network *network)
2105 unsigned long flags;
2106 u32 size = sizeof(struct ieee80211_qos_parameters);
2107 int set_qos_param = 0;
2109 if ((priv == NULL) || (network == NULL))
2112 if(priv->ieee80211->state !=IEEE80211_LINKED)
2115 if ((priv->ieee80211->iw_mode != IW_MODE_INFRA))
2118 spin_lock_irqsave(&priv->ieee80211->lock, flags);
2119 if(network->flags & NETWORK_HAS_QOS_PARAMETERS) {
2120 memcpy(&priv->ieee80211->current_network.qos_data.parameters,\
2121 &network->qos_data.parameters,\
2122 sizeof(struct ieee80211_qos_parameters));
2123 priv->ieee80211->current_network.qos_data.active = 1;
2125 if((priv->ieee80211->current_network.qos_data.param_count != \
2126 network->qos_data.param_count))
2130 /* update qos parameter for current network */
2131 priv->ieee80211->current_network.qos_data.old_param_count = \
2132 priv->ieee80211->current_network.qos_data.param_count;
2133 priv->ieee80211->current_network.qos_data.param_count = \
2134 network->qos_data.param_count;
2137 memcpy(&priv->ieee80211->current_network.qos_data.parameters,\
2138 &def_qos_parameters, size);
2139 priv->ieee80211->current_network.qos_data.active = 0;
2140 priv->ieee80211->current_network.qos_data.supported = 0;
2144 spin_unlock_irqrestore(&priv->ieee80211->lock, flags);
2146 RT_TRACE(COMP_QOS, "%s: network->flags = %d,%d\n",__FUNCTION__,network->flags ,priv->ieee80211->current_network.qos_data.active);
2147 if (set_qos_param == 1)
2148 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
2149 queue_work(priv->priv_wq, &priv->qos_activate);
2151 schedule_task(&priv->qos_activate);
2159 static int rtl8192_handle_assoc_response(struct net_device *dev,
2160 struct ieee80211_assoc_response_frame *resp,
2161 struct ieee80211_network *network)
2163 struct r8192_priv *priv = ieee80211_priv(dev);
2164 rtl8192_qos_association_resp(priv, network);
2169 //updateRATRTabel for MCS only. Basic rate is not implement.
2170 void rtl8192_update_ratr_table(struct net_device* dev)
2171 // POCTET_STRING posLegacyRate,
2173 // PRT_WLAN_STA pEntry)
2175 struct r8192_priv* priv = ieee80211_priv(dev);
2176 struct ieee80211_device* ieee = priv->ieee80211;
2177 u8* pMcsRate = ieee->dot11HTOperationalRateSet;
2178 //struct ieee80211_network *net = &ieee->current_network;
2182 rtl8192_config_rate(dev, (u16*)(&ratr_value));
2183 ratr_value |= (*(u16*)(pMcsRate)) << 12;
2184 // switch (net->mode)
2188 ratr_value &= 0x00000FF0;
2191 ratr_value &= 0x0000000F;
2194 ratr_value &= 0x00000FF7;
2198 if (ieee->pHTInfo->PeerMimoPs == 0) //MIMO_PS_STATIC
2199 ratr_value &= 0x0007F007;
2201 if (priv->rf_type == RF_1T2R)
2202 ratr_value &= 0x000FF007;
2204 ratr_value &= 0x0F81F007;
2210 ratr_value &= 0x0FFFFFFF;
2211 if(ieee->pHTInfo->bCurTxBW40MHz && ieee->pHTInfo->bCurShortGI40MHz){
2212 ratr_value |= 0x80000000;
2213 }else if(!ieee->pHTInfo->bCurTxBW40MHz && ieee->pHTInfo->bCurShortGI20MHz){
2214 ratr_value |= 0x80000000;
2216 write_nic_dword(dev, RATR0+rate_index*4, ratr_value);
2217 write_nic_byte(dev, UFWP, 1);
2220 static u8 ccmp_ie[4] = {0x00,0x50,0xf2,0x04};
2221 static u8 ccmp_rsn_ie[4] = {0x00, 0x0f, 0xac, 0x04};
2222 static bool GetNmodeSupportBySecCfg8190Pci(struct net_device*dev)
2225 struct r8192_priv* priv = ieee80211_priv(dev);
2226 struct ieee80211_device* ieee = priv->ieee80211;
2227 int wpa_ie_len= ieee->wpa_ie_len;
2228 struct ieee80211_crypt_data* crypt;
2231 crypt = ieee->crypt[ieee->tx_keyidx];
2232 encrypt = (ieee->current_network.capability & WLAN_CAPABILITY_PRIVACY) || (ieee->host_encrypt && crypt && crypt->ops && (0 == strcmp(crypt->ops->name,"WEP")));
2235 if(encrypt && (wpa_ie_len == 0)) {
2236 /* wep encryption, no N mode setting */
2238 // } else if((wpa_ie_len != 0)&&(memcmp(&(ieee->wpa_ie[14]),ccmp_ie,4))) {
2239 } else if((wpa_ie_len != 0)) {
2240 /* parse pairwise key type */
2241 //if((pairwisekey = WEP40)||(pairwisekey = WEP104)||(pairwisekey = TKIP))
2242 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))))
2247 //RT_TRACE(COMP_ERR,"In %s The GroupEncAlgorithm is [4]\n",__FUNCTION__ );
2252 //In here we discuss with SD4 David. He think we still can send TKIP in broadcast group key in MCS rate.
2253 //We can't force in G mode if Pairwie key is AES and group key is TKIP
2254 if((pSecInfo->GroupEncAlgorithm == WEP104_Encryption) || (pSecInfo->GroupEncAlgorithm == WEP40_Encryption) ||
2255 (pSecInfo->PairwiseEncAlgorithm == WEP104_Encryption) ||
2256 (pSecInfo->PairwiseEncAlgorithm == WEP40_Encryption) || (pSecInfo->PairwiseEncAlgorithm == TKIP_Encryption))
2267 static void rtl8192_refresh_supportrate(struct r8192_priv* priv)
2269 struct ieee80211_device* ieee = priv->ieee80211;
2270 //we donot consider set support rate for ABG mode, only HT MCS rate is set here.
2271 if (ieee->mode == WIRELESS_MODE_N_24G || ieee->mode == WIRELESS_MODE_N_5G)
2273 memcpy(ieee->Regdot11HTOperationalRateSet, ieee->RegHTSuppRateSet, 16);
2274 //RT_DEBUG_DATA(COMP_INIT, ieee->RegHTSuppRateSet, 16);
2275 //RT_DEBUG_DATA(COMP_INIT, ieee->Regdot11HTOperationalRateSet, 16);
2278 memset(ieee->Regdot11HTOperationalRateSet, 0, 16);
2282 static u8 rtl8192_getSupportedWireleeMode(struct net_device*dev)
2284 struct r8192_priv *priv = ieee80211_priv(dev);
2286 switch(priv->rf_chip)
2291 ret = (WIRELESS_MODE_N_24G|WIRELESS_MODE_G|WIRELESS_MODE_B);
2294 ret = (WIRELESS_MODE_A|WIRELESS_MODE_N_5G);
2297 ret = WIRELESS_MODE_B;
2303 static void rtl8192_SetWirelessMode(struct net_device* dev, u8 wireless_mode)
2305 struct r8192_priv *priv = ieee80211_priv(dev);
2306 u8 bSupportMode = rtl8192_getSupportedWireleeMode(dev);
2309 if ((wireless_mode == WIRELESS_MODE_AUTO) || ((wireless_mode&bSupportMode)==0))
2311 if(bSupportMode & WIRELESS_MODE_N_24G)
2313 wireless_mode = WIRELESS_MODE_N_24G;
2315 else if(bSupportMode & WIRELESS_MODE_N_5G)
2317 wireless_mode = WIRELESS_MODE_N_5G;
2319 else if((bSupportMode & WIRELESS_MODE_A))
2321 wireless_mode = WIRELESS_MODE_A;
2323 else if((bSupportMode & WIRELESS_MODE_G))
2325 wireless_mode = WIRELESS_MODE_G;
2327 else if((bSupportMode & WIRELESS_MODE_B))
2329 wireless_mode = WIRELESS_MODE_B;
2332 RT_TRACE(COMP_ERR, "%s(), No valid wireless mode supported, SupportedWirelessMode(%x)!!!\n", __FUNCTION__,bSupportMode);
2333 wireless_mode = WIRELESS_MODE_B;
2336 #ifdef TO_DO_LIST //// TODO: this function doesn't work well at this time, we shoud wait for FPGA
2337 ActUpdateChannelAccessSetting( pAdapter, pHalData->CurrentWirelessMode, &pAdapter->MgntInfo.Info8185.ChannelAccessSetting );
2339 priv->ieee80211->mode = wireless_mode;
2341 if ((wireless_mode == WIRELESS_MODE_N_24G) || (wireless_mode == WIRELESS_MODE_N_5G))
2342 priv->ieee80211->pHTInfo->bEnableHT = 1;
2344 priv->ieee80211->pHTInfo->bEnableHT = 0;
2345 RT_TRACE(COMP_INIT, "Current Wireless Mode is %x\n", wireless_mode);
2346 rtl8192_refresh_supportrate(priv);
2350 //init priv variables here
2352 static bool GetHalfNmodeSupportByAPs819xPci(struct net_device* dev)
2355 struct r8192_priv* priv = ieee80211_priv(dev);
2356 struct ieee80211_device* ieee = priv->ieee80211;
2358 if(ieee->bHalfWirelessN24GMode == true)
2366 short rtl8192_is_tx_queue_empty(struct net_device *dev)
2369 struct r8192_priv *priv = ieee80211_priv(dev);
2370 for (i=0; i<=MGNT_QUEUE; i++)
2372 if ((i== TXCMD_QUEUE) || (i == HCCA_QUEUE) )
2374 if (skb_queue_len(&(&priv->tx_ring[i])->queue) > 0){
2375 printk("===>tx queue is not empty:%d, %d\n", i, skb_queue_len(&(&priv->tx_ring[i])->queue));
2382 void rtl8192_rq_tx_ack(struct net_device *dev)
2384 struct r8192_priv *priv = ieee80211_priv(dev);
2385 priv->ieee80211->ack_tx_to_ieee = 1;
2388 static void rtl8192_hw_sleep_down(struct net_device *dev)
2390 RT_TRACE(COMP_POWER, "%s()============>come to sleep down\n", __FUNCTION__);
2391 MgntActSet_RF_State(dev, eRfSleep, RF_CHANGE_BY_PS);
2393 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
2394 static void rtl8192_hw_sleep_wq (struct work_struct *work)
2396 // struct r8180_priv *priv = container_of(work, struct r8180_priv, watch_dog_wq);
2397 // struct ieee80211_device * ieee = (struct ieee80211_device*)
2398 // container_of(work, struct ieee80211_device, watch_dog_wq);
2399 struct delayed_work *dwork = container_of(work,struct delayed_work,work);
2400 struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,hw_sleep_wq);
2401 struct net_device *dev = ieee->dev;
2403 void rtl8192_hw_sleep_wq(struct net_device* dev)
2406 //printk("=========>%s()\n", __FUNCTION__);
2407 rtl8192_hw_sleep_down(dev);
2409 // printk("dev is %d\n",dev);
2410 // printk("&*&(^*(&(&=========>%s()\n", __FUNCTION__);
2411 static void rtl8192_hw_wakeup(struct net_device* dev)
2415 // spin_lock_irqsave(&priv->ps_lock,flags);
2416 RT_TRACE(COMP_POWER, "%s()============>come to wake up\n", __FUNCTION__);
2417 MgntActSet_RF_State(dev, eRfOn, RF_CHANGE_BY_PS);
2418 //FIXME: will we send package stored while nic is sleep?
2419 // spin_unlock_irqrestore(&priv->ps_lock,flags);
2421 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
2422 void rtl8192_hw_wakeup_wq (struct work_struct *work)
2424 // struct r8180_priv *priv = container_of(work, struct r8180_priv, watch_dog_wq);
2425 // struct ieee80211_device * ieee = (struct ieee80211_device*)
2426 // container_of(work, struct ieee80211_device, watch_dog_wq);
2427 struct delayed_work *dwork = container_of(work,struct delayed_work,work);
2428 struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,hw_wakeup_wq);
2429 struct net_device *dev = ieee->dev;
2431 void rtl8192_hw_wakeup_wq(struct net_device* dev)
2434 rtl8192_hw_wakeup(dev);
2438 #define MIN_SLEEP_TIME 50
2439 #define MAX_SLEEP_TIME 10000
2440 static void rtl8192_hw_to_sleep(struct net_device *dev, u32 th, u32 tl)
2443 struct r8192_priv *priv = ieee80211_priv(dev);
2446 unsigned long flags;
2448 spin_lock_irqsave(&priv->ps_lock,flags);
2450 /* Writing HW register with 0 equals to disable
2451 * the timer, that is not really what we want
2453 tl -= MSECS(4+16+7);
2455 //if(tl == 0) tl = 1;
2457 /* FIXME HACK FIXME HACK */
2458 // force_pci_posting(dev);
2461 // rb = read_nic_dword(dev, TSFTR);
2463 /* If the interval in witch we are requested to sleep is too
2464 * short then give up and remain awake
2466 if(((tl>=rb)&& (tl-rb) <= MSECS(MIN_SLEEP_TIME))
2467 ||((rb>tl)&& (rb-tl) < MSECS(MIN_SLEEP_TIME))) {
2468 spin_unlock_irqrestore(&priv->ps_lock,flags);
2469 printk("too short to sleep\n");
2473 // write_nic_dword(dev, TimerInt, tl);
2474 // rb = read_nic_dword(dev, TSFTR);
2476 u32 tmp = (tl>rb)?(tl-rb):(rb-tl);
2478 queue_delayed_work(priv->ieee80211->wq, &priv->ieee80211->hw_wakeup_wq, tmp); //as tl may be less than rb
2480 /* if we suspect the TimerInt is gone beyond tl
2481 * while setting it, then give up
2484 if(((tl > rb) && ((tl-rb) > MSECS(MAX_SLEEP_TIME)))||
2485 ((tl < rb) && ((rb-tl) > MSECS(MAX_SLEEP_TIME)))) {
2486 printk("========>too long to sleep:%x, %x, %lx\n", tl, rb, MSECS(MAX_SLEEP_TIME));
2487 spin_unlock_irqrestore(&priv->ps_lock,flags);
2491 // if(priv->rf_sleep)
2492 // priv->rf_sleep(dev);
2494 //printk("<=========%s()\n", __FUNCTION__);
2495 queue_delayed_work(priv->ieee80211->wq, (void *)&priv->ieee80211->hw_sleep_wq,0);
2496 spin_unlock_irqrestore(&priv->ps_lock,flags);
2498 static void rtl8192_init_priv_variable(struct net_device* dev)
2500 struct r8192_priv *priv = ieee80211_priv(dev);
2502 priv->being_init_adapter = false;
2503 priv->txbuffsize = 1600;//1024;
2504 priv->txfwbuffersize = 4096;
2505 priv->txringcount = 64;//32;
2506 //priv->txbeaconcount = priv->txringcount;
2507 priv->txbeaconcount = 2;
2508 priv->rxbuffersize = 9100;//2048;//1024;
2509 priv->rxringcount = MAX_RX_COUNT;//64;
2510 priv->irq_enabled=0;
2511 priv->card_8192 = NIC_8192E;
2512 priv->rx_skb_complete = 1;
2513 priv->chan = 1; //set to channel 1
2514 priv->RegWirelessMode = WIRELESS_MODE_AUTO;
2515 priv->RegChannelPlan = 0xf;
2516 priv->nrxAMPDU_size = 0;
2517 priv->nrxAMPDU_aggr_num = 0;
2518 priv->last_rxdesc_tsf_high = 0;
2519 priv->last_rxdesc_tsf_low = 0;
2520 priv->ieee80211->mode = WIRELESS_MODE_AUTO; //SET AUTO
2521 priv->ieee80211->iw_mode = IW_MODE_INFRA;
2522 priv->ieee80211->ieee_up=0;
2523 priv->retry_rts = DEFAULT_RETRY_RTS;
2524 priv->retry_data = DEFAULT_RETRY_DATA;
2525 priv->ieee80211->rts = DEFAULT_RTS_THRESHOLD;
2526 priv->ieee80211->rate = 110; //11 mbps
2527 priv->ieee80211->short_slot = 1;
2528 priv->promisc = (dev->flags & IFF_PROMISC) ? 1:0;
2529 priv->bcck_in_ch14 = false;
2530 priv->bfsync_processing = false;
2531 priv->CCKPresentAttentuation = 0;
2532 priv->rfa_txpowertrackingindex = 0;
2533 priv->rfc_txpowertrackingindex = 0;
2535 priv->ScanDelay = 50;//for Scan TODO
2536 //added by amy for silent reset
2537 priv->ResetProgress = RESET_TYPE_NORESET;
2538 priv->bForcedSilentReset = 0;
2539 priv->bDisableNormalResetCheck = false;
2540 priv->force_reset = false;
2541 //added by amy for power save
2543 priv->ieee80211->RfOffReason = 0;
2544 priv->RFChangeInProgress = false;
2545 priv->bHwRfOffAction = 0;
2546 priv->SetRFPowerStateInProgress = false;
2547 priv->ieee80211->PowerSaveControl.bInactivePs = true;
2548 priv->ieee80211->PowerSaveControl.bIPSModeBackup = false;
2550 priv->txpower_checkcnt = 0;
2551 priv->thermal_readback_index =0;
2552 priv->txpower_tracking_callback_cnt = 0;
2553 priv->ccktxpower_adjustcnt_ch14 = 0;
2554 priv->ccktxpower_adjustcnt_not_ch14 = 0;
2556 priv->ieee80211->current_network.beacon_interval = DEFAULT_BEACONINTERVAL;
2557 priv->ieee80211->iw_mode = IW_MODE_INFRA;
2558 priv->ieee80211->softmac_features = IEEE_SOFTMAC_SCAN |
2559 IEEE_SOFTMAC_ASSOCIATE | IEEE_SOFTMAC_PROBERQ |
2560 IEEE_SOFTMAC_PROBERS | IEEE_SOFTMAC_TX_QUEUE;/* |
2561 IEEE_SOFTMAC_BEACONS;*///added by amy 080604 //| //IEEE_SOFTMAC_SINGLE_QUEUE;
2563 priv->ieee80211->active_scan = 1;
2564 priv->ieee80211->modulation = IEEE80211_CCK_MODULATION | IEEE80211_OFDM_MODULATION;
2565 priv->ieee80211->host_encrypt = 1;
2566 priv->ieee80211->host_decrypt = 1;
2567 //priv->ieee80211->start_send_beacons = NULL;//rtl819xusb_beacon_tx;//-by amy 080604
2568 //priv->ieee80211->stop_send_beacons = NULL;//rtl8192_beacon_stop;//-by amy 080604
2569 priv->ieee80211->start_send_beacons = rtl8192_start_beacon;//+by david 081107
2570 priv->ieee80211->stop_send_beacons = rtl8192_stop_beacon;//+by david 081107
2571 priv->ieee80211->softmac_hard_start_xmit = rtl8192_hard_start_xmit;
2572 priv->ieee80211->set_chan = rtl8192_set_chan;
2573 priv->ieee80211->link_change = rtl8192_link_change;
2574 priv->ieee80211->softmac_data_hard_start_xmit = rtl8192_hard_data_xmit;
2575 priv->ieee80211->data_hard_stop = rtl8192_data_hard_stop;
2576 priv->ieee80211->data_hard_resume = rtl8192_data_hard_resume;
2577 priv->ieee80211->init_wmmparam_flag = 0;
2578 priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD;
2579 priv->ieee80211->check_nic_enough_desc = check_nic_enough_desc;
2580 priv->ieee80211->tx_headroom = sizeof(TX_FWINFO_8190PCI);
2581 priv->ieee80211->qos_support = 1;
2582 priv->ieee80211->dot11PowerSaveMode = 0;
2584 // priv->ieee80211->SwChnlByTimerHandler = rtl8192_phy_SwChnl;
2585 priv->ieee80211->SetBWModeHandler = rtl8192_SetBWMode;
2586 priv->ieee80211->handle_assoc_response = rtl8192_handle_assoc_response;
2587 priv->ieee80211->handle_beacon = rtl8192_handle_beacon;
2589 priv->ieee80211->sta_wake_up = rtl8192_hw_wakeup;
2590 // priv->ieee80211->ps_request_tx_ack = rtl8192_rq_tx_ack;
2591 priv->ieee80211->enter_sleep_state = rtl8192_hw_to_sleep;
2592 priv->ieee80211->ps_is_queue_empty = rtl8192_is_tx_queue_empty;
2594 priv->ieee80211->GetNmodeSupportBySecCfg = GetNmodeSupportBySecCfg8190Pci;
2595 priv->ieee80211->SetWirelessMode = rtl8192_SetWirelessMode;
2596 priv->ieee80211->GetHalfNmodeSupportByAPsHandler = GetHalfNmodeSupportByAPs819xPci;
2599 priv->ieee80211->InitialGainHandler = InitialGain819xPci;
2601 priv->card_type = USB;
2603 priv->ShortRetryLimit = 0x30;
2604 priv->LongRetryLimit = 0x30;
2606 priv->EarlyRxThreshold = 7;
2607 priv->enable_gpio0 = 0;
2609 priv->TransmitConfig = 0;
2611 priv->ReceiveConfig = RCR_ADD3 |
2612 RCR_AMF | RCR_ADF | //accept management/data
2613 RCR_AICV | //accept control frame for SW AP needs PS-poll, 2005.07.07, by rcnjko.
2614 RCR_AB | RCR_AM | RCR_APM | //accept BC/MC/UC
2615 RCR_AAP | ((u32)7<<RCR_MXDMA_OFFSET) |
2616 ((u32)7 << RCR_FIFO_OFFSET) | RCR_ONLYERLPKT;
2618 priv->irq_mask = (u32)(IMR_ROK | IMR_VODOK | IMR_VIDOK | IMR_BEDOK | IMR_BKDOK |\
2619 IMR_HCCADOK | IMR_MGNTDOK | IMR_COMDOK | IMR_HIGHDOK |\
2620 IMR_BDOK | IMR_RXCMDOK | IMR_TIMEOUT0 | IMR_RDU | IMR_RXFOVW |\
2621 IMR_TXFOVW | IMR_BcnInt | IMR_TBDOK | IMR_TBDER);
2623 priv->AcmControl = 0;
2624 priv->pFirmware = (rt_firmware*)vmalloc(sizeof(rt_firmware));
2625 if (priv->pFirmware)
2626 memset(priv->pFirmware, 0, sizeof(rt_firmware));
2628 /* rx related queue */
2629 skb_queue_head_init(&priv->rx_queue);
2630 skb_queue_head_init(&priv->skb_queue);
2632 /* Tx related queue */
2633 for(i = 0; i < MAX_QUEUE_SIZE; i++) {
2634 skb_queue_head_init(&priv->ieee80211->skb_waitQ [i]);
2636 for(i = 0; i < MAX_QUEUE_SIZE; i++) {
2637 skb_queue_head_init(&priv->ieee80211->skb_aggQ [i]);
2639 priv->rf_set_chan = rtl8192_phy_SwChnl;
2643 static void rtl8192_init_priv_lock(struct r8192_priv* priv)
2645 spin_lock_init(&priv->tx_lock);
2646 spin_lock_init(&priv->irq_lock);//added by thomas
2647 spin_lock_init(&priv->irq_th_lock);
2648 spin_lock_init(&priv->rf_ps_lock);
2649 spin_lock_init(&priv->ps_lock);
2650 //spin_lock_init(&priv->rf_lock);
2651 sema_init(&priv->wx_sem,1);
2652 sema_init(&priv->rf_sem,1);
2653 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16))
2654 sema_init(&priv->mutex, 1);
2656 mutex_init(&priv->mutex);
2660 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
2661 extern void rtl819x_watchdog_wqcallback(struct work_struct *work);
2663 extern void rtl819x_watchdog_wqcallback(struct net_device *dev);
2666 void rtl8192_irq_rx_tasklet(struct r8192_priv *priv);
2667 void rtl8192_irq_tx_tasklet(struct r8192_priv *priv);
2668 void rtl8192_prepare_beacon(struct r8192_priv *priv);
2669 //init tasklet and wait_queue here. only 2.6 above kernel is considered
2670 #define DRV_NAME "wlan0"
2671 static void rtl8192_init_priv_task(struct net_device* dev)
2673 struct r8192_priv *priv = ieee80211_priv(dev);
2675 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
2676 #ifdef PF_SYNCTHREAD
2677 priv->priv_wq = create_workqueue(DRV_NAME,0);
2679 priv->priv_wq = create_workqueue(DRV_NAME);
2683 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
2684 // INIT_WORK(&priv->reset_wq, (void(*)(void*)) rtl8192_restart);
2685 INIT_WORK(&priv->reset_wq, rtl8192_restart);
2686 // INIT_DELAYED_WORK(&priv->watch_dog_wq, hal_dm_watchdog);
2687 INIT_DELAYED_WORK(&priv->watch_dog_wq, rtl819x_watchdog_wqcallback);
2688 INIT_DELAYED_WORK(&priv->txpower_tracking_wq, dm_txpower_trackingcallback);
2689 INIT_DELAYED_WORK(&priv->rfpath_check_wq, dm_rf_pathcheck_workitemcallback);
2690 INIT_DELAYED_WORK(&priv->update_beacon_wq, rtl8192_update_beacon);
2691 //INIT_WORK(&priv->SwChnlWorkItem, rtl8192_SwChnl_WorkItem);
2692 //INIT_WORK(&priv->SetBWModeWorkItem, rtl8192_SetBWModeWorkItem);
2693 INIT_WORK(&priv->qos_activate, rtl8192_qos_activate);
2694 INIT_DELAYED_WORK(&priv->ieee80211->hw_wakeup_wq,(void*) rtl8192_hw_wakeup_wq);
2695 INIT_DELAYED_WORK(&priv->ieee80211->hw_sleep_wq,(void*) rtl8192_hw_sleep_wq);
2698 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
2699 tq_init(&priv->reset_wq, (void*)rtl8192_restart, dev);
2700 tq_init(&priv->watch_dog_wq, (void*)rtl819x_watchdog_wqcallback, dev);
2701 tq_init(&priv->txpower_tracking_wq, (void*)dm_txpower_trackingcallback, dev);
2702 tq_init(&priv->rfpath_check_wq, (void*)dm_rf_pathcheck_workitemcallback, dev);
2703 tq_init(&priv->update_beacon_wq, (void*)rtl8192_update_beacon, dev);
2704 //tq_init(&priv->SwChnlWorkItem, (void*) rtl8192_SwChnl_WorkItem, dev);
2705 //tq_init(&priv->SetBWModeWorkItem, (void*)rtl8192_SetBWModeWorkItem, dev);
2706 tq_init(&priv->qos_activate, (void *)rtl8192_qos_activate, dev);
2707 tq_init(&priv->ieee80211->hw_wakeup_wq,(void*) rtl8192_hw_wakeup_wq, dev);
2708 tq_init(&priv->ieee80211->hw_sleep_wq,(void*) rtl8192_hw_sleep_wq, dev);
2711 INIT_WORK(&priv->reset_wq,(void(*)(void*)) rtl8192_restart,dev);
2712 // INIT_WORK(&priv->watch_dog_wq, (void(*)(void*)) hal_dm_watchdog,dev);
2713 INIT_WORK(&priv->watch_dog_wq, (void(*)(void*)) rtl819x_watchdog_wqcallback,dev);
2714 INIT_WORK(&priv->txpower_tracking_wq, (void(*)(void*)) dm_txpower_trackingcallback,dev);
2715 INIT_WORK(&priv->rfpath_check_wq, (void(*)(void*)) dm_rf_pathcheck_workitemcallback,dev);
2716 INIT_WORK(&priv->update_beacon_wq, (void(*)(void*))rtl8192_update_beacon,dev);
2717 //INIT_WORK(&priv->SwChnlWorkItem, (void(*)(void*)) rtl8192_SwChnl_WorkItem, dev);
2718 //INIT_WORK(&priv->SetBWModeWorkItem, (void(*)(void*)) rtl8192_SetBWModeWorkItem, dev);
2719 INIT_WORK(&priv->qos_activate, (void(*)(void *))rtl8192_qos_activate, dev);
2720 INIT_WORK(&priv->ieee80211->hw_wakeup_wq,(void*) rtl8192_hw_wakeup_wq, dev);
2721 INIT_WORK(&priv->ieee80211->hw_sleep_wq,(void*) rtl8192_hw_sleep_wq, dev);
2725 tasklet_init(&priv->irq_rx_tasklet,
2726 (void(*)(unsigned long))rtl8192_irq_rx_tasklet,
2727 (unsigned long)priv);
2728 tasklet_init(&priv->irq_tx_tasklet,
2729 (void(*)(unsigned long))rtl8192_irq_tx_tasklet,
2730 (unsigned long)priv);
2731 tasklet_init(&priv->irq_prepare_beacon_tasklet,
2732 (void(*)(unsigned long))rtl8192_prepare_beacon,
2733 (unsigned long)priv);
2736 static void rtl8192_get_eeprom_size(struct net_device* dev)
2739 struct r8192_priv *priv = ieee80211_priv(dev);
2740 RT_TRACE(COMP_INIT, "===========>%s()\n", __FUNCTION__);
2741 curCR = read_nic_dword(dev, EPROM_CMD);
2742 RT_TRACE(COMP_INIT, "read from Reg Cmd9346CR(%x):%x\n", EPROM_CMD, curCR);
2743 //whether need I consider BIT5?
2744 priv->epromtype = (curCR & EPROM_CMD_9356SEL) ? EPROM_93c56 : EPROM_93c46;
2745 RT_TRACE(COMP_INIT, "<===========%s(), epromtype:%d\n", __FUNCTION__, priv->epromtype);
2748 //used to swap endian. as ntohl & htonl are not neccessary to swap endian, so use this instead.
2749 static inline u16 endian_swap(u16* data)
2752 *data = (tmp >> 8) | (tmp << 8);
2757 * Note: Adapter->EEPROMAddressSize should be set before this function call.
2758 * EEPROM address size can be got through GetEEPROMSize8185()
2760 static void rtl8192_read_eeprom_info(struct net_device* dev)
2762 struct r8192_priv *priv = ieee80211_priv(dev);
2766 u8 ICVer8192, ICVer8256;
2768 u16 i,usValue, IC_Version;
2771 u8 offset;//, tmpAFR;
2772 u8 EepromTxPower[100];
2774 u8 bMac_Tmp_Addr[6] = {0x00, 0xe0, 0x4c, 0x00, 0x00, 0x01};
2775 RT_TRACE(COMP_INIT, "====> rtl8192_read_eeprom_info\n");
2778 // TODO: I don't know if we need to apply EF function to EEPROM read function
2780 //2 Read EEPROM ID to make sure autoload is success
2781 EEPROMId = eprom_read(dev, 0);
2782 if( EEPROMId != RTL8190_EEPROM_ID )
2784 RT_TRACE(COMP_ERR, "EEPROM ID is invalid:%x, %x\n", EEPROMId, RTL8190_EEPROM_ID);
2785 priv->AutoloadFailFlag=true;
2789 priv->AutoloadFailFlag=false;
2793 // Assign Chip Version ID
2795 // Read IC Version && Channel Plan
2796 if(!priv->AutoloadFailFlag)
2799 priv->eeprom_vid = eprom_read(dev, (EEPROM_VID >> 1));
2800 priv->eeprom_did = eprom_read(dev, (EEPROM_DID >> 1));
2802 usValue = eprom_read(dev, (u16)(EEPROM_Customer_ID>>1)) >> 8 ;
2803 priv->eeprom_CustomerID = (u8)( usValue & 0xff);
2804 usValue = eprom_read(dev, (EEPROM_ICVersion_ChannelPlan>>1));
2805 priv->eeprom_ChannelPlan = usValue&0xff;
2806 IC_Version = ((usValue&0xff00)>>8);
2809 priv->card_8192_version = (VERSION_8190)(IC_Version);
2812 ICVer8192 = (IC_Version&0xf); //bit0~3; 1:A cut, 2:B cut, 3:C cut...
2813 ICVer8256 = ((IC_Version&0xf0)>>4);//bit4~6, bit7 reserved for other RF chip; 1:A cut, 2:B cut, 3:C cut...
2814 RT_TRACE(COMP_INIT, "\nICVer8192 = 0x%x\n", ICVer8192);
2815 RT_TRACE(COMP_INIT, "\nICVer8256 = 0x%x\n", ICVer8256);
2816 if(ICVer8192 == 0x2) //B-cut
2818 if(ICVer8256 == 0x5) //E-cut
2819 priv->card_8192_version= VERSION_8190_BE;
2823 switch(priv->card_8192_version)
2825 case VERSION_8190_BD:
2826 case VERSION_8190_BE:
2829 priv->card_8192_version = VERSION_8190_BD;
2832 RT_TRACE(COMP_INIT, "\nIC Version = 0x%x\n", priv->card_8192_version);
2836 priv->card_8192_version = VERSION_8190_BD;
2837 priv->eeprom_vid = 0;
2838 priv->eeprom_did = 0;
2839 priv->eeprom_CustomerID = 0;
2840 priv->eeprom_ChannelPlan = 0;
2841 RT_TRACE(COMP_INIT, "\nIC Version = 0x%x\n", 0xff);
2844 RT_TRACE(COMP_INIT, "EEPROM VID = 0x%4x\n", priv->eeprom_vid);
2845 RT_TRACE(COMP_INIT, "EEPROM DID = 0x%4x\n", priv->eeprom_did);
2846 RT_TRACE(COMP_INIT,"EEPROM Customer ID: 0x%2x\n", priv->eeprom_CustomerID);
2848 //2 Read Permanent MAC address
2849 if(!priv->AutoloadFailFlag)
2851 for(i = 0; i < 6; i += 2)
2853 usValue = eprom_read(dev, (u16) ((EEPROM_NODE_ADDRESS_BYTE_0+i)>>1));
2854 *(u16*)(&dev->dev_addr[i]) = usValue;
2857 // when auto load failed, the last address byte set to be a random one.
2858 // added by david woo.2007/11/7
2859 memcpy(dev->dev_addr, bMac_Tmp_Addr, 6);
2861 for(i = 0; i < 6; i++)
2863 Adapter->PermanentAddress[i] = sMacAddr[i];
2864 PlatformEFIOWrite1Byte(Adapter, IDR0+i, sMacAddr[i]);
2869 RT_TRACE(COMP_INIT, "Permanent Address = %02x-%02x-%02x-%02x-%02x-%02x\n",
2870 dev->dev_addr[0], dev->dev_addr[1],
2871 dev->dev_addr[2], dev->dev_addr[3],
2872 dev->dev_addr[4], dev->dev_addr[5]);
2874 //2 TX Power Check EEPROM Fail or not
2875 if(priv->card_8192_version > VERSION_8190_BD) {
2876 priv->bTXPowerDataReadFromEEPORM = true;
2878 priv->bTXPowerDataReadFromEEPORM = false;
2881 // 2007/11/15 MH 8190PCI Default=2T4R, 8192PCIE dafault=1T2R
2882 priv->rf_type = RTL819X_DEFAULT_RF_TYPE;
2884 if(priv->card_8192_version > VERSION_8190_BD)
2886 // Read RF-indication and Tx Power gain index diff of legacy to HT OFDM rate.
2887 if(!priv->AutoloadFailFlag)
2889 tempval = (eprom_read(dev, (EEPROM_RFInd_PowerDiff>>1))) & 0xff;
2890 priv->EEPROMLegacyHTTxPowerDiff = tempval & 0xf; // bit[3:0]
2892 if (tempval&0x80) //RF-indication, bit[7]
2893 priv->rf_type = RF_1T2R;
2895 priv->rf_type = RF_2T4R;
2899 priv->EEPROMLegacyHTTxPowerDiff = EEPROM_Default_LegacyHTTxPowerDiff;
2901 RT_TRACE(COMP_INIT, "EEPROMLegacyHTTxPowerDiff = %d\n",
2902 priv->EEPROMLegacyHTTxPowerDiff);
2904 // Read ThermalMeter from EEPROM
2905 if(!priv->AutoloadFailFlag)
2907 priv->EEPROMThermalMeter = (u8)(((eprom_read(dev, (EEPROM_ThermalMeter>>1))) & 0xff00)>>8);
2911 priv->EEPROMThermalMeter = EEPROM_Default_ThermalMeter;
2913 RT_TRACE(COMP_INIT, "ThermalMeter = %d\n", priv->EEPROMThermalMeter);
2914 //vivi, for tx power track
2915 priv->TSSI_13dBm = priv->EEPROMThermalMeter *100;
2917 if(priv->epromtype == EPROM_93c46)
2919 // Read antenna tx power offset of B/C/D to A and CrystalCap from EEPROM
2920 if(!priv->AutoloadFailFlag)
2922 usValue = eprom_read(dev, (EEPROM_TxPwDiff_CrystalCap>>1));
2923 priv->EEPROMAntPwDiff = (usValue&0x0fff);
2924 priv->EEPROMCrystalCap = (u8)((usValue&0xf000)>>12);
2928 priv->EEPROMAntPwDiff = EEPROM_Default_AntTxPowerDiff;
2929 priv->EEPROMCrystalCap = EEPROM_Default_TxPwDiff_CrystalCap;
2931 RT_TRACE(COMP_INIT, "EEPROMAntPwDiff = %d\n", priv->EEPROMAntPwDiff);
2932 RT_TRACE(COMP_INIT, "EEPROMCrystalCap = %d\n", priv->EEPROMCrystalCap);
2935 // Get per-channel Tx Power Level
2937 for(i=0; i<14; i+=2)
2939 if(!priv->AutoloadFailFlag)
2941 usValue = eprom_read(dev, (u16) ((EEPROM_TxPwIndex_CCK+i)>>1) );
2945 usValue = EEPROM_Default_TxPower;
2947 *((u16*)(&priv->EEPROMTxPowerLevelCCK[i])) = usValue;
2948 RT_TRACE(COMP_INIT,"CCK Tx Power Level, Index %d = 0x%02x\n", i, priv->EEPROMTxPowerLevelCCK[i]);
2949 RT_TRACE(COMP_INIT, "CCK Tx Power Level, Index %d = 0x%02x\n", i+1, priv->EEPROMTxPowerLevelCCK[i+1]);
2951 for(i=0; i<14; i+=2)
2953 if(!priv->AutoloadFailFlag)
2955 usValue = eprom_read(dev, (u16) ((EEPROM_TxPwIndex_OFDM_24G+i)>>1) );
2959 usValue = EEPROM_Default_TxPower;
2961 *((u16*)(&priv->EEPROMTxPowerLevelOFDM24G[i])) = usValue;
2962 RT_TRACE(COMP_INIT, "OFDM 2.4G Tx Power Level, Index %d = 0x%02x\n", i, priv->EEPROMTxPowerLevelOFDM24G[i]);
2963 RT_TRACE(COMP_INIT, "OFDM 2.4G Tx Power Level, Index %d = 0x%02x\n", i+1, priv->EEPROMTxPowerLevelOFDM24G[i+1]);
2966 else if(priv->epromtype== EPROM_93c56)
2969 // Read CrystalCap from EEPROM
2970 if(!priv->AutoloadFailFlag)
2972 priv->EEPROMAntPwDiff = EEPROM_Default_AntTxPowerDiff;
2973 priv->EEPROMCrystalCap = (u8)(((eprom_read(dev, (EEPROM_C56_CrystalCap>>1))) & 0xf000)>>12);
2977 priv->EEPROMAntPwDiff = EEPROM_Default_AntTxPowerDiff;
2978 priv->EEPROMCrystalCap = EEPROM_Default_TxPwDiff_CrystalCap;
2980 RT_TRACE(COMP_INIT,"EEPROMAntPwDiff = %d\n", priv->EEPROMAntPwDiff);
2981 RT_TRACE(COMP_INIT, "EEPROMCrystalCap = %d\n", priv->EEPROMCrystalCap);
2983 // Get Tx Power Level by Channel
2984 if(!priv->AutoloadFailFlag)
2986 // Read Tx power of Channel 1 ~ 14 from EEPROM.
2987 for(i = 0; i < 12; i+=2)
2990 offset = EEPROM_C56_RfA_CCK_Chnl1_TxPwIndex + i;
2992 offset = EEPROM_C56_RfC_CCK_Chnl1_TxPwIndex + i - 6;
2993 usValue = eprom_read(dev, (offset>>1));
2994 *((u16*)(&EepromTxPower[i])) = usValue;
2997 for(i = 0; i < 12; i++)
3000 priv->EEPROMRfACCKChnl1TxPwLevel[i] = EepromTxPower[i];
3001 else if ((i >=3 )&&(i <= 5))
3002 priv->EEPROMRfAOfdmChnlTxPwLevel[i-3] = EepromTxPower[i];
3003 else if ((i >=6 )&&(i <= 8))
3004 priv->EEPROMRfCCCKChnl1TxPwLevel[i-6] = EepromTxPower[i];
3006 priv->EEPROMRfCOfdmChnlTxPwLevel[i-9] = EepromTxPower[i];
3011 priv->EEPROMRfACCKChnl1TxPwLevel[0] = EEPROM_Default_TxPowerLevel;
3012 priv->EEPROMRfACCKChnl1TxPwLevel[1] = EEPROM_Default_TxPowerLevel;
3013 priv->EEPROMRfACCKChnl1TxPwLevel[2] = EEPROM_Default_TxPowerLevel;
3015 priv->EEPROMRfAOfdmChnlTxPwLevel[0] = EEPROM_Default_TxPowerLevel;
3016 priv->EEPROMRfAOfdmChnlTxPwLevel[1] = EEPROM_Default_TxPowerLevel;
3017 priv->EEPROMRfAOfdmChnlTxPwLevel[2] = EEPROM_Default_TxPowerLevel;
3019 priv->EEPROMRfCCCKChnl1TxPwLevel[0] = EEPROM_Default_TxPowerLevel;
3020 priv->EEPROMRfCCCKChnl1TxPwLevel[1] = EEPROM_Default_TxPowerLevel;
3021 priv->EEPROMRfCCCKChnl1TxPwLevel[2] = EEPROM_Default_TxPowerLevel;
3023 priv->EEPROMRfCOfdmChnlTxPwLevel[0] = EEPROM_Default_TxPowerLevel;
3024 priv->EEPROMRfCOfdmChnlTxPwLevel[1] = EEPROM_Default_TxPowerLevel;
3025 priv->EEPROMRfCOfdmChnlTxPwLevel[2] = EEPROM_Default_TxPowerLevel;
3027 RT_TRACE(COMP_INIT, "priv->EEPROMRfACCKChnl1TxPwLevel[0] = 0x%x\n", priv->EEPROMRfACCKChnl1TxPwLevel[0]);
3028 RT_TRACE(COMP_INIT, "priv->EEPROMRfACCKChnl1TxPwLevel[1] = 0x%x\n", priv->EEPROMRfACCKChnl1TxPwLevel[1]);
3029 RT_TRACE(COMP_INIT, "priv->EEPROMRfACCKChnl1TxPwLevel[2] = 0x%x\n", priv->EEPROMRfACCKChnl1TxPwLevel[2]);
3030 RT_TRACE(COMP_INIT, "priv->EEPROMRfAOfdmChnlTxPwLevel[0] = 0x%x\n", priv->EEPROMRfAOfdmChnlTxPwLevel[0]);
3031 RT_TRACE(COMP_INIT, "priv->EEPROMRfAOfdmChnlTxPwLevel[1] = 0x%x\n", priv->EEPROMRfAOfdmChnlTxPwLevel[1]);
3032 RT_TRACE(COMP_INIT, "priv->EEPROMRfAOfdmChnlTxPwLevel[2] = 0x%x\n", priv->EEPROMRfAOfdmChnlTxPwLevel[2]);
3033 RT_TRACE(COMP_INIT, "priv->EEPROMRfCCCKChnl1TxPwLevel[0] = 0x%x\n", priv->EEPROMRfCCCKChnl1TxPwLevel[0]);
3034 RT_TRACE(COMP_INIT, "priv->EEPROMRfCCCKChnl1TxPwLevel[1] = 0x%x\n", priv->EEPROMRfCCCKChnl1TxPwLevel[1]);
3035 RT_TRACE(COMP_INIT, "priv->EEPROMRfCCCKChnl1TxPwLevel[2] = 0x%x\n", priv->EEPROMRfCCCKChnl1TxPwLevel[2]);
3036 RT_TRACE(COMP_INIT, "priv->EEPROMRfCOfdmChnlTxPwLevel[0] = 0x%x\n", priv->EEPROMRfCOfdmChnlTxPwLevel[0]);
3037 RT_TRACE(COMP_INIT, "priv->EEPROMRfCOfdmChnlTxPwLevel[1] = 0x%x\n", priv->EEPROMRfCOfdmChnlTxPwLevel[1]);
3038 RT_TRACE(COMP_INIT, "priv->EEPROMRfCOfdmChnlTxPwLevel[2] = 0x%x\n", priv->EEPROMRfCOfdmChnlTxPwLevel[2]);
3043 // Update HAL variables.
3045 if(priv->epromtype == EPROM_93c46)
3049 priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelCCK[i];
3050 priv->TxPowerLevelOFDM24G[i] = priv->EEPROMTxPowerLevelOFDM24G[i];
3052 priv->LegacyHTTxPowerDiff = priv->EEPROMLegacyHTTxPowerDiff;
3053 // Antenna B gain offset to antenna A, bit0~3
3054 priv->AntennaTxPwDiff[0] = (priv->EEPROMAntPwDiff & 0xf);
3055 // Antenna C gain offset to antenna A, bit4~7
3056 priv->AntennaTxPwDiff[1] = ((priv->EEPROMAntPwDiff & 0xf0)>>4);
3057 // Antenna D gain offset to antenna A, bit8~11
3058 priv->AntennaTxPwDiff[2] = ((priv->EEPROMAntPwDiff & 0xf00)>>8);
3059 // CrystalCap, bit12~15
3060 priv->CrystalCap = priv->EEPROMCrystalCap;
3061 // ThermalMeter, bit0~3 for RFIC1, bit4~7 for RFIC2
3062 priv->ThermalMeter[0] = (priv->EEPROMThermalMeter & 0xf);
3063 priv->ThermalMeter[1] = ((priv->EEPROMThermalMeter & 0xf0)>>4);
3065 else if(priv->epromtype == EPROM_93c56)
3067 //char cck_pwr_diff_a=0, cck_pwr_diff_c=0;
3069 //cck_pwr_diff_a = pHalData->EEPROMRfACCKChnl7TxPwLevel - pHalData->EEPROMRfAOfdmChnlTxPwLevel[1];
3070 //cck_pwr_diff_c = pHalData->EEPROMRfCCCKChnl7TxPwLevel - pHalData->EEPROMRfCOfdmChnlTxPwLevel[1];
3071 for(i=0; i<3; i++) // channel 1~3 use the same Tx Power Level.
3073 priv->TxPowerLevelCCK_A[i] = priv->EEPROMRfACCKChnl1TxPwLevel[0];
3074 priv->TxPowerLevelOFDM24G_A[i] = priv->EEPROMRfAOfdmChnlTxPwLevel[0];
3075 priv->TxPowerLevelCCK_C[i] = priv->EEPROMRfCCCKChnl1TxPwLevel[0];
3076 priv->TxPowerLevelOFDM24G_C[i] = priv->EEPROMRfCOfdmChnlTxPwLevel[0];
3078 for(i=3; i<9; i++) // channel 4~9 use the same Tx Power Level
3080 priv->TxPowerLevelCCK_A[i] = priv->EEPROMRfACCKChnl1TxPwLevel[1];
3081 priv->TxPowerLevelOFDM24G_A[i] = priv->EEPROMRfAOfdmChnlTxPwLevel[1];
3082 priv->TxPowerLevelCCK_C[i] = priv->EEPROMRfCCCKChnl1TxPwLevel[1];
3083 priv->TxPowerLevelOFDM24G_C[i] = priv->EEPROMRfCOfdmChnlTxPwLevel[1];
3085 for(i=9; i<14; i++) // channel 10~14 use the same Tx Power Level
3087 priv->TxPowerLevelCCK_A[i] = priv->EEPROMRfACCKChnl1TxPwLevel[2];
3088 priv->TxPowerLevelOFDM24G_A[i] = priv->EEPROMRfAOfdmChnlTxPwLevel[2];
3089 priv->TxPowerLevelCCK_C[i] = priv->EEPROMRfCCCKChnl1TxPwLevel[2];
3090 priv->TxPowerLevelOFDM24G_C[i] = priv->EEPROMRfCOfdmChnlTxPwLevel[2];
3093 RT_TRACE(COMP_INIT, "priv->TxPowerLevelCCK_A[%d] = 0x%x\n", i, priv->TxPowerLevelCCK_A[i]);
3095 RT_TRACE(COMP_INIT,"priv->TxPowerLevelOFDM24G_A[%d] = 0x%x\n", i, priv->TxPowerLevelOFDM24G_A[i]);
3097 RT_TRACE(COMP_INIT, "priv->TxPowerLevelCCK_C[%d] = 0x%x\n", i, priv->TxPowerLevelCCK_C[i]);
3099 RT_TRACE(COMP_INIT, "priv->TxPowerLevelOFDM24G_C[%d] = 0x%x\n", i, priv->TxPowerLevelOFDM24G_C[i]);
3100 priv->LegacyHTTxPowerDiff = priv->EEPROMLegacyHTTxPowerDiff;
3101 priv->AntennaTxPwDiff[0] = 0;
3102 priv->AntennaTxPwDiff[1] = 0;
3103 priv->AntennaTxPwDiff[2] = 0;
3104 priv->CrystalCap = priv->EEPROMCrystalCap;
3105 // ThermalMeter, bit0~3 for RFIC1, bit4~7 for RFIC2
3106 priv->ThermalMeter[0] = (priv->EEPROMThermalMeter & 0xf);
3107 priv->ThermalMeter[1] = ((priv->EEPROMThermalMeter & 0xf0)>>4);
3111 if(priv->rf_type == RF_1T2R)
3113 RT_TRACE(COMP_INIT, "\n1T2R config\n");
3115 else if (priv->rf_type == RF_2T4R)
3117 RT_TRACE(COMP_INIT, "\n2T4R config\n");
3120 // 2008/01/16 MH We can only know RF type in the function. So we have to init
3121 // DIG RATR table again.
3122 init_rate_adaptive(dev);
3124 //1 Make a copy for following variables and we can change them if we want
3126 priv->rf_chip= RF_8256;
3128 if(priv->RegChannelPlan == 0xf)
3130 priv->ChannelPlan = priv->eeprom_ChannelPlan;
3134 priv->ChannelPlan = priv->RegChannelPlan;
3138 // Used PID and DID to Set CustomerID
3140 if( priv->eeprom_vid == 0x1186 && priv->eeprom_did == 0x3304 )
3142 priv->CustomerID = RT_CID_DLINK;
3145 switch(priv->eeprom_CustomerID)
3147 case EEPROM_CID_DEFAULT:
3148 priv->CustomerID = RT_CID_DEFAULT;
3150 case EEPROM_CID_CAMEO:
3151 priv->CustomerID = RT_CID_819x_CAMEO;
3153 case EEPROM_CID_RUNTOP:
3154 priv->CustomerID = RT_CID_819x_RUNTOP;
3156 case EEPROM_CID_NetCore:
3157 priv->CustomerID = RT_CID_819x_Netcore;
3159 case EEPROM_CID_TOSHIBA: // Merge by Jacken, 2008/01/31
3160 priv->CustomerID = RT_CID_TOSHIBA;
3161 if(priv->eeprom_ChannelPlan&0x80)
3162 priv->ChannelPlan = priv->eeprom_ChannelPlan&0x7f;
3164 priv->ChannelPlan = 0x0;
3165 RT_TRACE(COMP_INIT, "Toshiba ChannelPlan = 0x%x\n",
3168 case EEPROM_CID_Nettronix:
3169 priv->ScanDelay = 100; //cosa add for scan
3170 priv->CustomerID = RT_CID_Nettronix;
3172 case EEPROM_CID_Pronet:
3173 priv->CustomerID = RT_CID_PRONET;
3175 case EEPROM_CID_DLINK:
3176 priv->CustomerID = RT_CID_DLINK;
3179 case EEPROM_CID_WHQL:
3180 //Adapter->bInHctTest = TRUE;//do not supported
3182 //priv->bSupportTurboMode = FALSE;
3183 //priv->bAutoTurboBy8186 = FALSE;
3185 //pMgntInfo->PowerSaveControl.bInactivePs = FALSE;
3186 //pMgntInfo->PowerSaveControl.bIPSModeBackup = FALSE;
3187 //pMgntInfo->PowerSaveControl.bLeisurePs = FALSE;
3191 // value from RegCustomerID
3195 //Avoid the channel plan array overflow, by Bruce, 2007-08-27.
3196 if(priv->ChannelPlan > CHANNEL_PLAN_LEN - 1)
3197 priv->ChannelPlan = 0; //FCC
3199 switch(priv->CustomerID)
3201 case RT_CID_DEFAULT:
3203 priv->LedStrategy = HW_LED;
3206 priv->LedStrategy = SW_LED_MODE1;
3211 case RT_CID_819x_CAMEO:
3212 priv->LedStrategy = SW_LED_MODE2;
3215 case RT_CID_819x_RUNTOP:
3216 priv->LedStrategy = SW_LED_MODE3;
3219 case RT_CID_819x_Netcore:
3220 priv->LedStrategy = SW_LED_MODE4;
3223 case RT_CID_Nettronix:
3224 priv->LedStrategy = SW_LED_MODE5;
3228 priv->LedStrategy = SW_LED_MODE6;
3231 case RT_CID_TOSHIBA: //Modify by Jacken 2008/01/31
3237 priv->LedStrategy = HW_LED;
3240 priv->LedStrategy = SW_LED_MODE1;
3246 //2008.06.03, for WOL
3247 if( priv->eeprom_vid == 0x1186 && priv->eeprom_did == 0x3304)
3248 priv->ieee80211->bSupportRemoteWakeUp = TRUE;
3250 priv->ieee80211->bSupportRemoteWakeUp = FALSE;
3252 RT_TRACE(COMP_INIT, "RegChannelPlan(%d)\n", priv->RegChannelPlan);
3253 RT_TRACE(COMP_INIT, "ChannelPlan = %d \n", priv->ChannelPlan);
3254 RT_TRACE(COMP_INIT, "LedStrategy = %d \n", priv->LedStrategy);
3255 RT_TRACE(COMP_TRACE, "<==== ReadAdapterInfo\n");
3261 static short rtl8192_get_channel_map(struct net_device * dev)
3263 struct r8192_priv *priv = ieee80211_priv(dev);
3264 #ifdef ENABLE_DOT11D
3265 if(priv->ChannelPlan> COUNTRY_CODE_GLOBAL_DOMAIN){
3266 printk("rtl8180_init:Error channel plan! Set to default.\n");
3267 priv->ChannelPlan= 0;
3269 RT_TRACE(COMP_INIT, "Channel plan is %d\n",priv->ChannelPlan);
3271 rtl819x_set_channel_map(priv->ChannelPlan, priv);
3274 //Set Default Channel Plan
3276 DMESG("No channels, aborting");
3280 priv->ChannelPlan= 0;//hikaru
3281 // set channels 1..14 allowed in given locale
3282 for (i=1; i<=14; i++) {
3283 (priv->ieee80211->channel_map)[i] = (u8)(ch & 0x01);
3290 static short rtl8192_init(struct net_device *dev)
3292 struct r8192_priv *priv = ieee80211_priv(dev);
3293 memset(&(priv->stats),0,sizeof(struct Stats));
3294 rtl8192_init_priv_variable(dev);
3295 rtl8192_init_priv_lock(priv);
3296 rtl8192_init_priv_task(dev);
3297 rtl8192_get_eeprom_size(dev);
3298 rtl8192_read_eeprom_info(dev);
3299 rtl8192_get_channel_map(dev);
3301 init_timer(&priv->watch_dog_timer);
3302 priv->watch_dog_timer.data = (unsigned long)dev;
3303 priv->watch_dog_timer.function = watch_dog_timer_callback;
3304 #if defined(IRQF_SHARED)
3305 if(request_irq(dev->irq, (void*)rtl8192_interrupt, IRQF_SHARED, dev->name, dev)){
3307 if(request_irq(dev->irq, (void *)rtl8192_interrupt, SA_SHIRQ, dev->name, dev)){
3309 printk("Error allocating IRQ %d",dev->irq);
3313 printk("IRQ %d",dev->irq);
3315 if(rtl8192_pci_initdescring(dev)!=0){
3316 printk("Endopoints initialization failed");
3320 //rtl8192_rx_enable(dev);
3321 //rtl8192_adapter_start(dev);
3325 /******************************************************************************
3326 *function: This function actually only set RRSR, RATR and BW_OPMODE registers
3327 * not to do all the hw config as its name says
3328 * input: net_device dev
3331 * notice: This part need to modified according to the rate set we filtered
3332 * ****************************************************************************/
3333 static void rtl8192_hwconfig(struct net_device* dev)
3335 u32 regRATR = 0, regRRSR = 0;
3336 u8 regBwOpMode = 0, regTmp = 0;
3337 struct r8192_priv *priv = ieee80211_priv(dev);
3339 // Set RRSR, RATR, and BW_OPMODE registers
3341 switch(priv->ieee80211->mode)
3343 case WIRELESS_MODE_B:
3344 regBwOpMode = BW_OPMODE_20MHZ;
3345 regRATR = RATE_ALL_CCK;
3346 regRRSR = RATE_ALL_CCK;
3348 case WIRELESS_MODE_A:
3349 regBwOpMode = BW_OPMODE_5G |BW_OPMODE_20MHZ;
3350 regRATR = RATE_ALL_OFDM_AG;
3351 regRRSR = RATE_ALL_OFDM_AG;
3353 case WIRELESS_MODE_G:
3354 regBwOpMode = BW_OPMODE_20MHZ;
3355 regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
3356 regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
3358 case WIRELESS_MODE_AUTO:
3359 case WIRELESS_MODE_N_24G:
3360 // It support CCK rate by default.
3361 // CCK rate will be filtered out only when associated AP does not support it.
3362 regBwOpMode = BW_OPMODE_20MHZ;
3363 regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
3364 regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
3366 case WIRELESS_MODE_N_5G:
3367 regBwOpMode = BW_OPMODE_5G;
3368 regRATR = RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
3369 regRRSR = RATE_ALL_OFDM_AG;
3373 write_nic_byte(dev, BW_OPMODE, regBwOpMode);
3376 ratr_value = regRATR;
3377 if (priv->rf_type == RF_1T2R)
3379 ratr_value &= ~(RATE_ALL_OFDM_2SS);
3381 write_nic_dword(dev, RATR0, ratr_value);
3382 write_nic_byte(dev, UFWP, 1);
3384 regTmp = read_nic_byte(dev, 0x313);
3385 regRRSR = ((regTmp) << 24) | (regRRSR & 0x00ffffff);
3386 write_nic_dword(dev, RRSR, regRRSR);
3389 // Set Retry Limit here
3391 write_nic_word(dev, RETRY_LIMIT,
3392 priv->ShortRetryLimit << RETRY_LIMIT_SHORT_SHIFT | \
3393 priv->LongRetryLimit << RETRY_LIMIT_LONG_SHIFT);
3394 // Set Contention Window here
3398 // Set Tx Antenna including Feedback control
3400 // Set Auto Rate fallback control
3406 static RT_STATUS rtl8192_adapter_start(struct net_device *dev)
3408 struct r8192_priv *priv = ieee80211_priv(dev);
3409 // struct ieee80211_device *ieee = priv->ieee80211;
3411 RT_STATUS rtStatus = RT_STATUS_SUCCESS;
3412 // static char szMACPHYRegFile[] = RTL819X_PHY_MACPHY_REG;
3413 // static char szMACPHYRegPGFile[] = RTL819X_PHY_MACPHY_REG_PG;
3417 u8 ICVersion,SwitchingRegulatorOutput;
3419 bool bfirmwareok = true;
3423 u32 tmpRegA, tmpRegC, TempCCk;
3425 // u32 dwRegRead = 0;
3427 RT_TRACE(COMP_INIT, "====>%s()\n", __FUNCTION__);
3428 priv->being_init_adapter = true;
3429 rtl8192_pci_resetdescring(dev);
3430 // 2007/11/02 MH Before initalizing RF. We can not use FW to do RF-R/W.
3431 priv->Rf_Mode = RF_OP_By_SW_3wire;
3434 if(priv->ResetProgress == RESET_TYPE_NORESET)
3436 write_nic_byte(dev, ANAPAR, 0x37);
3437 // Accordign to designer's explain, LBUS active will never > 10ms. We delay 10ms
3438 // Joseph increae the time to prevent firmware download fail
3442 //PlatformSleepUs(10000);
3443 // For any kind of InitializeAdapter process, we shall use system now!!
3444 priv->pFirmware->firmware_status = FW_STATUS_0_INIT;
3446 // Set to eRfoff in order not to count receive count.
3447 if(priv->RegRfOff == TRUE)
3448 priv->ieee80211->eRFPowerState = eRfOff;
3451 //3 //Config CPUReset Register
3453 //3 Firmware Reset Or Not
3454 ulRegRead = read_nic_dword(dev, CPU_GEN);
3455 if(priv->pFirmware->firmware_status == FW_STATUS_0_INIT)
3456 { //called from MPInitialized. do nothing
3457 ulRegRead |= CPU_GEN_SYSTEM_RESET;
3458 }else if(priv->pFirmware->firmware_status == FW_STATUS_5_READY)
3459 ulRegRead |= CPU_GEN_FIRMWARE_RESET; // Called from MPReset
3461 RT_TRACE(COMP_ERR, "ERROR in %s(): undefined firmware state(%d)\n", __FUNCTION__, priv->pFirmware->firmware_status);
3464 //2008.06.03, for WOL 90 hw bug
3465 ulRegRead &= (~(CPU_GEN_GPIO_UART));
3468 write_nic_dword(dev, CPU_GEN, ulRegRead);
3474 //3 //Fix the issue of E-cut high temperature issue
3477 ICVersion = read_nic_byte(dev, IC_VERRSION);
3478 if(ICVersion >= 0x4) //E-cut only
3480 // HW SD suggest that we should not wirte this register too often, so driver
3481 // should readback this register. This register will be modified only when
3483 SwitchingRegulatorOutput = read_nic_byte(dev, SWREGULATOR);
3484 if(SwitchingRegulatorOutput != 0xb8)
3486 write_nic_byte(dev, SWREGULATOR, 0xa8);
3488 write_nic_byte(dev, SWREGULATOR, 0xb8);
3495 //3// Initialize BB before MAC
3497 RT_TRACE(COMP_INIT, "BB Config Start!\n");
3498 rtStatus = rtl8192_BBConfig(dev);
3499 if(rtStatus != RT_STATUS_SUCCESS)
3501 RT_TRACE(COMP_ERR, "BB Config failed\n");
3504 RT_TRACE(COMP_INIT,"BB Config Finished!\n");
3506 //3//Set Loopback mode or Normal mode
3508 //2006.12.13 by emily. Note!We should not merge these two CPU_GEN register writings
3509 // because setting of System_Reset bit reset MAC to default transmission mode.
3510 //Loopback mode or not
3511 priv->LoopbackMode = RTL819X_NO_LOOPBACK;
3512 //priv->LoopbackMode = RTL819X_MAC_LOOPBACK;
3513 if(priv->ResetProgress == RESET_TYPE_NORESET)
3515 ulRegRead = read_nic_dword(dev, CPU_GEN);
3516 if(priv->LoopbackMode == RTL819X_NO_LOOPBACK)
3518 ulRegRead = ((ulRegRead & CPU_GEN_NO_LOOPBACK_MSK) | CPU_GEN_NO_LOOPBACK_SET);
3520 else if (priv->LoopbackMode == RTL819X_MAC_LOOPBACK )
3522 ulRegRead |= CPU_CCK_LOOPBACK;
3526 RT_TRACE(COMP_ERR,"Serious error: wrong loopback mode setting\n");
3529 //2008.06.03, for WOL
3530 //ulRegRead &= (~(CPU_GEN_GPIO_UART));
3531 write_nic_dword(dev, CPU_GEN, ulRegRead);
3533 // 2006.11.29. After reset cpu, we sholud wait for a second, otherwise, it may fail to write registers. Emily
3536 //3Set Hardware(Do nothing now)
3537 rtl8192_hwconfig(dev);
3538 //2=======================================================
3539 // Common Setting for all of the FPGA platform. (part 1)
3540 //2=======================================================
3541 // If there is changes, please make sure it applies to all of the FPGA version
3543 write_nic_byte(dev, CMDR, CR_RE|CR_TE);
3547 write_nic_byte(dev, PCIF, ((MXDMA2_NoLimit<<MXDMA2_RX_SHIFT) | \
3548 (MXDMA2_NoLimit<<MXDMA2_TX_SHIFT) | \
3552 write_nic_byte(dev, PCIF, ((MXDMA2_NoLimit<<MXDMA2_RX_SHIFT) |\
3553 (MXDMA2_NoLimit<<MXDMA2_TX_SHIFT) ));
3557 write_nic_dword(dev, MAC0, ((u32*)dev->dev_addr)[0]);
3558 write_nic_word(dev, MAC4, ((u16*)(dev->dev_addr + 4))[0]);
3560 write_nic_dword(dev, RCR, priv->ReceiveConfig);
3562 //3 Initialize Number of Reserved Pages in Firmware Queue
3564 if(priv->bInHctTest)
3566 PlatformEFIOWrite4Byte(Adapter, RQPN1, NUM_OF_PAGE_IN_FW_QUEUE_BK_DTM << RSVD_FW_QUEUE_PAGE_BK_SHIFT |\
3567 NUM_OF_PAGE_IN_FW_QUEUE_BE_DTM << RSVD_FW_QUEUE_PAGE_BE_SHIFT | \
3568 NUM_OF_PAGE_IN_FW_QUEUE_VI_DTM << RSVD_FW_QUEUE_PAGE_VI_SHIFT | \
3569 NUM_OF_PAGE_IN_FW_QUEUE_VO_DTM <<RSVD_FW_QUEUE_PAGE_VO_SHIFT);
3570 PlatformEFIOWrite4Byte(Adapter, RQPN2, NUM_OF_PAGE_IN_FW_QUEUE_MGNT << RSVD_FW_QUEUE_PAGE_MGNT_SHIFT);
3571 PlatformEFIOWrite4Byte(Adapter, RQPN3, APPLIED_RESERVED_QUEUE_IN_FW| \
3572 NUM_OF_PAGE_IN_FW_QUEUE_BCN<<RSVD_FW_QUEUE_PAGE_BCN_SHIFT|\
3573 NUM_OF_PAGE_IN_FW_QUEUE_PUB_DTM<<RSVD_FW_QUEUE_PAGE_PUB_SHIFT);
3578 write_nic_dword(dev, RQPN1, NUM_OF_PAGE_IN_FW_QUEUE_BK << RSVD_FW_QUEUE_PAGE_BK_SHIFT |\
3579 NUM_OF_PAGE_IN_FW_QUEUE_BE << RSVD_FW_QUEUE_PAGE_BE_SHIFT | \
3580 NUM_OF_PAGE_IN_FW_QUEUE_VI << RSVD_FW_QUEUE_PAGE_VI_SHIFT | \
3581 NUM_OF_PAGE_IN_FW_QUEUE_VO <<RSVD_FW_QUEUE_PAGE_VO_SHIFT);
3582 write_nic_dword(dev, RQPN2, NUM_OF_PAGE_IN_FW_QUEUE_MGNT << RSVD_FW_QUEUE_PAGE_MGNT_SHIFT);
3583 write_nic_dword(dev, RQPN3, APPLIED_RESERVED_QUEUE_IN_FW| \
3584 NUM_OF_PAGE_IN_FW_QUEUE_BCN<<RSVD_FW_QUEUE_PAGE_BCN_SHIFT|\
3585 NUM_OF_PAGE_IN_FW_QUEUE_PUB<<RSVD_FW_QUEUE_PAGE_PUB_SHIFT);
3588 rtl8192_tx_enable(dev);
3589 rtl8192_rx_enable(dev);
3590 //3Set Response Rate Setting Register
3591 // CCK rate is supported by default.
3592 // CCK rate will be filtered out only when associated AP does not support it.
3593 ulRegRead = (0xFFF00000 & read_nic_dword(dev, RRSR)) | RATE_ALL_OFDM_AG | RATE_ALL_CCK;
3594 write_nic_dword(dev, RRSR, ulRegRead);
3595 write_nic_dword(dev, RATR0+4*7, (RATE_ALL_OFDM_AG | RATE_ALL_CCK));
3598 // TODO: (it value is only for FPGA version). need to be changed!!2006.12.18, by Emily
3599 write_nic_byte(dev, ACK_TIMEOUT, 0x30);
3601 //rtl8192_actset_wirelessmode(dev,priv->RegWirelessMode);
3602 if(priv->ResetProgress == RESET_TYPE_NORESET)
3603 rtl8192_SetWirelessMode(dev, priv->ieee80211->mode);
3604 //-----------------------------------------------------------------------------
3605 // Set up security related. 070106, by rcnjko:
3606 // 1. Clear all H/W keys.
3607 // 2. Enable H/W encryption/decryption.
3608 //-----------------------------------------------------------------------------
3609 CamResetAllEntry(dev);
3611 u8 SECR_value = 0x0;
3612 SECR_value |= SCR_TxEncEnable;
3613 SECR_value |= SCR_RxDecEnable;
3614 SECR_value |= SCR_NoSKMC;
3615 write_nic_byte(dev, SECR, SECR_value);
3618 write_nic_word(dev, ATIMWND, 2);
3619 write_nic_word(dev, BCN_INTERVAL, 100);
3620 for (i=0; i<QOS_QUEUE_NUM; i++)
3621 write_nic_dword(dev, WDCAPARA_ADD[i], 0x005e4332);
3623 // Switching regulator controller: This is set temporarily.
3624 // It's not sure if this can be removed in the future.
3625 // PJ advised to leave it by default.
3627 write_nic_byte(dev, 0xbe, 0xc0);
3629 //2=======================================================
3630 // Set PHY related configuration defined in MAC register bank
3631 //2=======================================================
3632 rtl8192_phy_configmac(dev);
3634 if (priv->card_8192_version > (u8) VERSION_8190_BD) {
3635 rtl8192_phy_getTxPower(dev);
3636 rtl8192_phy_setTxPower(dev, priv->chan);
3640 tmpvalue = read_nic_byte(dev, IC_VERRSION);
3641 priv->IC_Cut = tmpvalue;
3642 RT_TRACE(COMP_INIT, "priv->IC_Cut = 0x%x\n", priv->IC_Cut);
3643 if(priv->IC_Cut >= IC_VersionCut_D)
3645 //pHalData->bDcut = TRUE;
3646 if(priv->IC_Cut == IC_VersionCut_D)
3647 RT_TRACE(COMP_INIT, "D-cut\n");
3648 if(priv->IC_Cut == IC_VersionCut_E)
3650 RT_TRACE(COMP_INIT, "E-cut\n");
3651 // HW SD suggest that we should not wirte this register too often, so driver
3652 // should readback this register. This register will be modified only when
3658 //pHalData->bDcut = FALSE;
3659 RT_TRACE(COMP_INIT, "Before C-cut\n");
3664 RT_TRACE(COMP_INIT, "Load Firmware!\n");
3665 bfirmwareok = init_firmware(dev);
3666 if(bfirmwareok != true) {
3667 rtStatus = RT_STATUS_FAILURE;
3670 RT_TRACE(COMP_INIT, "Load Firmware finished!\n");
3673 if(priv->ResetProgress == RESET_TYPE_NORESET)
3675 RT_TRACE(COMP_INIT, "RF Config Started!\n");
3676 rtStatus = rtl8192_phy_RFConfig(dev);
3677 if(rtStatus != RT_STATUS_SUCCESS)
3679 RT_TRACE(COMP_ERR, "RF Config failed\n");
3682 RT_TRACE(COMP_INIT, "RF Config Finished!\n");
3684 rtl8192_phy_updateInitGain(dev);
3686 /*---- Set CCK and OFDM Block "ON"----*/
3687 rtl8192_setBBreg(dev, rFPGA0_RFMOD, bCCKEn, 0x1);
3688 rtl8192_setBBreg(dev, rFPGA0_RFMOD, bOFDMEn, 0x1);
3692 write_nic_byte(dev, 0x87, 0x0);
3695 //2008.06.03, for WOL
3696 ucRegRead = read_nic_byte(dev, GPE);
3698 write_nic_byte(dev, GPE, ucRegRead);
3700 ucRegRead = read_nic_byte(dev, GPO);
3702 write_nic_byte(dev, GPO, ucRegRead);
3705 //2=======================================================
3707 //2=======================================================
3711 if(priv->RegRfOff == TRUE)
3712 { // User disable RF via registry.
3713 RT_TRACE((COMP_INIT|COMP_RF|COMP_POWER), "%s(): Turn off RF for RegRfOff ----------\n",__FUNCTION__);
3714 MgntActSet_RF_State(dev, eRfOff, RF_CHANGE_BY_SW);
3715 #if 0//cosa, ask SD3 willis and he doesn't know what is this for
3716 // Those action will be discard in MgntActSet_RF_State because off the same state
3717 for(eRFPath = 0; eRFPath <pHalData->NumTotalRFPath; eRFPath++)
3718 PHY_SetRFReg(Adapter, (RF90_RADIO_PATH_E)eRFPath, 0x4, 0xC00, 0x0);
3721 else if(priv->ieee80211->RfOffReason > RF_CHANGE_BY_PS)
3722 { // H/W or S/W RF OFF before sleep.
3723 RT_TRACE((COMP_INIT|COMP_RF|COMP_POWER), "%s(): Turn off RF for RfOffReason(%d) ----------\n", __FUNCTION__,priv->ieee80211->RfOffReason);
3724 MgntActSet_RF_State(dev, eRfOff, priv->ieee80211->RfOffReason);
3726 else if(priv->ieee80211->RfOffReason >= RF_CHANGE_BY_IPS)
3727 { // H/W or S/W RF OFF before sleep.
3728 RT_TRACE((COMP_INIT|COMP_RF|COMP_POWER), "%s(): Turn off RF for RfOffReason(%d) ----------\n", __FUNCTION__,priv->ieee80211->RfOffReason);
3729 MgntActSet_RF_State(dev, eRfOff, priv->ieee80211->RfOffReason);
3733 RT_TRACE((COMP_INIT|COMP_RF|COMP_POWER), "%s(): RF-ON \n",__FUNCTION__);
3734 priv->ieee80211->eRFPowerState = eRfOn;
3735 priv->ieee80211->RfOffReason = 0;
3736 //DrvIFIndicateCurrentPhyStatus(Adapter);
3738 //Adapter->HalFunc.LedControlHandler(Adapter, LED_CTL_POWER_ON);
3741 // If inactive power mode is enabled, disable rf while in disconnected state.
3742 // But we should still tell upper layer we are in rf on state.
3743 // 2007.07.16, by shien chang.
3745 //if(!Adapter->bInHctTest)
3746 //IPSEnter(Adapter);
3753 // We can force firmware to do RF-R/W
3754 if(priv->ieee80211->FwRWRF)
3755 priv->Rf_Mode = RF_OP_By_FW;
3757 priv->Rf_Mode = RF_OP_By_SW_3wire;
3759 priv->Rf_Mode = RF_OP_By_SW_3wire;
3763 if(priv->ResetProgress == RESET_TYPE_NORESET)
3765 dm_initialize_txpower_tracking(dev);
3767 tmpRegA= rtl8192_QueryBBReg(dev,rOFDM0_XATxIQImbalance,bMaskDWord);
3768 tmpRegC= rtl8192_QueryBBReg(dev,rOFDM0_XCTxIQImbalance,bMaskDWord);
3770 if(priv->rf_type == RF_2T4R){
3771 for(i = 0; i<TxBBGainTableLength; i++)
3773 if(tmpRegA == priv->txbbgain_table[i].txbbgain_value)
3775 priv->rfa_txpowertrackingindex= (u8)i;
3776 priv->rfa_txpowertrackingindex_real= (u8)i;
3777 priv->rfa_txpowertracking_default = priv->rfa_txpowertrackingindex;
3782 for(i = 0; i<TxBBGainTableLength; i++)
3784 if(tmpRegC == priv->txbbgain_table[i].txbbgain_value)
3786 priv->rfc_txpowertrackingindex= (u8)i;
3787 priv->rfc_txpowertrackingindex_real= (u8)i;
3788 priv->rfc_txpowertracking_default = priv->rfc_txpowertrackingindex;
3792 TempCCk = rtl8192_QueryBBReg(dev, rCCK0_TxFilter1, bMaskByte2);
3794 for(i=0 ; i<CCKTxBBGainTableLength ; i++)
3796 if(TempCCk == priv->cck_txbbgain_table[i].ccktxbb_valuearray[0])
3798 priv->CCKPresentAttentuation_20Mdefault =(u8) i;
3802 priv->CCKPresentAttentuation_40Mdefault = 0;
3803 priv->CCKPresentAttentuation_difference = 0;
3804 priv->CCKPresentAttentuation = priv->CCKPresentAttentuation_20Mdefault;
3805 RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex_initial = %d\n", priv->rfa_txpowertrackingindex);
3806 RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex_real__initial = %d\n", priv->rfa_txpowertrackingindex_real);
3807 RT_TRACE(COMP_POWER_TRACKING, "priv->rfc_txpowertrackingindex_initial = %d\n", priv->rfc_txpowertrackingindex);
3808 RT_TRACE(COMP_POWER_TRACKING, "priv->rfc_txpowertrackingindex_real_initial = %d\n", priv->rfc_txpowertrackingindex_real);
3809 RT_TRACE(COMP_POWER_TRACKING, "priv->CCKPresentAttentuation_difference_initial = %d\n", priv->CCKPresentAttentuation_difference);
3810 RT_TRACE(COMP_POWER_TRACKING, "priv->CCKPresentAttentuation_initial = %d\n", priv->CCKPresentAttentuation);
3814 if(priv->ResetProgress == RESET_TYPE_NORESET)
3816 dm_initialize_txpower_tracking(dev);
3818 if(priv->IC_Cut >= IC_VersionCut_D)
3820 tmpRegA= rtl8192_QueryBBReg(dev,rOFDM0_XATxIQImbalance,bMaskDWord);
3821 tmpRegC= rtl8192_QueryBBReg(dev,rOFDM0_XCTxIQImbalance,bMaskDWord);
3822 for(i = 0; i<TxBBGainTableLength; i++)
3824 if(tmpRegA == priv->txbbgain_table[i].txbbgain_value)
3826 priv->rfa_txpowertrackingindex= (u8)i;
3827 priv->rfa_txpowertrackingindex_real= (u8)i;
3828 priv->rfa_txpowertracking_default = priv->rfa_txpowertrackingindex;
3833 TempCCk = rtl8192_QueryBBReg(dev, rCCK0_TxFilter1, bMaskByte2);
3835 for(i=0 ; i<CCKTxBBGainTableLength ; i++)
3837 if(TempCCk == priv->cck_txbbgain_table[i].ccktxbb_valuearray[0])
3839 priv->CCKPresentAttentuation_20Mdefault =(u8) i;
3843 priv->CCKPresentAttentuation_40Mdefault = 0;
3844 priv->CCKPresentAttentuation_difference = 0;
3845 priv->CCKPresentAttentuation = priv->CCKPresentAttentuation_20Mdefault;
3846 RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex_initial = %d\n", priv->rfa_txpowertrackingindex);
3847 RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex_real__initial = %d\n", priv->rfa_txpowertrackingindex_real);
3848 RT_TRACE(COMP_POWER_TRACKING, "priv->CCKPresentAttentuation_difference_initial = %d\n", priv->CCKPresentAttentuation_difference);
3849 RT_TRACE(COMP_POWER_TRACKING, "priv->CCKPresentAttentuation_initial = %d\n", priv->CCKPresentAttentuation);
3850 priv->btxpower_tracking = FALSE;//TEMPLY DISABLE
3855 rtl8192_irq_enable(dev);
3856 priv->being_init_adapter = false;
3861 void rtl8192_prepare_beacon(struct r8192_priv *priv)
3863 struct sk_buff *skb;
3864 //unsigned long flags;
3867 skb = ieee80211_get_beacon(priv->ieee80211);
3868 tcb_desc = (cb_desc *)(skb->cb + 8);
3869 //printk("===========> %s\n", __FUNCTION__);
3870 //spin_lock_irqsave(&priv->tx_lock,flags);
3871 /* prepare misc info for the beacon xmit */
3872 tcb_desc->queue_index = BEACON_QUEUE;
3873 /* IBSS does not support HT yet, use 1M defautly */
3874 tcb_desc->data_rate = 2;
3875 tcb_desc->RATRIndex = 7;
3876 tcb_desc->bTxDisableRateFallBack = 1;
3877 tcb_desc->bTxUseDriverAssingedRate = 1;
3879 skb_push(skb, priv->ieee80211->tx_headroom);
3881 rtl8192_tx(priv->ieee80211->dev,skb);
3883 //spin_unlock_irqrestore (&priv->tx_lock, flags);
3887 void rtl8192_beacon_tx_enable(struct net_device *dev)
3889 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
3891 rtl8180_set_mode(dev,EPROM_CMD_CONFIG);
3892 #ifdef CONFIG_RTL8185B
3893 priv->dma_poll_stop_mask &= ~(TPPOLLSTOP_BQ);MgntQuery_MgntFrameTxRateMgntQuery_MgntFrameTxRate
3894 write_nic_byte(dev,TPPollStop, priv->dma_poll_mask);
3896 priv->dma_poll_mask &=~(1<<TX_DMA_STOP_BEACON_SHIFT);
3897 write_nic_byte(dev,TX_DMA_POLLING,priv->dma_poll_mask);
3899 rtl8180_set_mode(dev,EPROM_CMD_NORMAL);
3904 /* this configures registers for beacon tx and enables it via
3905 * rtl8192_beacon_tx_enable(). rtl8192_beacon_tx_disable() might
3906 * be used to stop beacon transmission
3908 void rtl8192_start_beacon(struct net_device *dev)
3910 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
3911 struct ieee80211_network *net = &priv->ieee80211->current_network;
3916 DMESG("Enabling beacon TX");
3917 //rtl8192_prepare_beacon(dev);
3918 rtl8192_irq_disable(dev);
3919 //rtl8192_beacon_tx_enable(dev);
3922 write_nic_word(dev, ATIMWND, 2);
3924 /* Beacon interval (in unit of TU) */
3925 write_nic_word(dev, BCN_INTERVAL, net->beacon_interval);
3928 * DrvErlyInt (in unit of TU).
3929 * (Time to send interrupt to notify driver to c
3930 * hange beacon content)
3932 write_nic_word(dev, BCN_DRV_EARLY_INT, 10);
3935 * BcnDMATIM(in unit of us).
3936 * Indicates the time before TBTT to perform beacon queue DMA
3938 write_nic_word(dev, BCN_DMATIME, 256);
3941 * Force beacon frame transmission even after receiving
3942 * beacon frame from other ad hoc STA
3944 write_nic_byte(dev, BCN_ERR_THRESH, 100);
3946 /* Set CW and IFS */
3947 BcnTimeCfg |= BcnCW<<BCN_TCFG_CW_SHIFT;
3948 BcnTimeCfg |= BcnIFS<<BCN_TCFG_IFS;
3949 write_nic_word(dev, BCN_TCFG, BcnTimeCfg);
3952 /* enable the interrupt for ad-hoc process */
3953 rtl8192_irq_enable(dev);
3955 /***************************************************************************
3956 -------------------------------NET STUFF---------------------------
3957 ***************************************************************************/
3959 static struct net_device_stats *rtl8192_stats(struct net_device *dev)
3961 struct r8192_priv *priv = ieee80211_priv(dev);
3963 return &priv->ieee80211->stats;
3969 static bool HalTxCheckStuck8190Pci(struct net_device *dev)
3971 u16 RegTxCounter = read_nic_word(dev, 0x128);
3972 struct r8192_priv *priv = ieee80211_priv(dev);
3973 bool bStuck = FALSE;
3974 RT_TRACE(COMP_RESET,"%s():RegTxCounter is %d,TxCounter is %d\n",__FUNCTION__,RegTxCounter,priv->TxCounter);
3975 if(priv->TxCounter==RegTxCounter)
3978 priv->TxCounter = RegTxCounter;
3984 * <Assumption: RT_TX_SPINLOCK is acquired.>
3985 * First added: 2006.11.19 by emily
3988 TxCheckStuck(struct net_device *dev)
3990 struct r8192_priv *priv = ieee80211_priv(dev);
3992 ptx_ring head=NULL,tail=NULL,txring = NULL;
3993 u8 ResetThreshold = NIC_SEND_HANG_THRESHOLD_POWERSAVE;
3994 bool bCheckFwTxCnt = false;
3995 //unsigned long flags;
3998 // Decide Stuch threshold according to current power save mode
4000 //printk("++++++++++++>%s()\n",__FUNCTION__);
4001 switch (priv->ieee80211->dot11PowerSaveMode)
4003 // The threshold value may required to be adjusted .
4004 case eActive: // Active/Continuous access.
4005 ResetThreshold = NIC_SEND_HANG_THRESHOLD_NORMAL;
4007 case eMaxPs: // Max power save mode.
4008 ResetThreshold = NIC_SEND_HANG_THRESHOLD_POWERSAVE;
4010 case eFastPs: // Fast power save mode.
4011 ResetThreshold = NIC_SEND_HANG_THRESHOLD_POWERSAVE;
4016 // Check whether specific tcb has been queued for a specific time
4018 for(QueueID = 0; QueueID < MAX_TX_QUEUE; QueueID++)
4022 if(QueueID == TXCMD_QUEUE)
4027 tail=priv->txmapringtail;
4028 head=priv->txmapringhead;
4032 tail=priv->txbkpringtail;
4033 head=priv->txbkpringhead;
4037 tail=priv->txbepringtail;
4038 head=priv->txbepringhead;
4042 tail=priv->txvipringtail;
4043 head=priv->txvipringhead;
4047 tail=priv->txvopringtail;
4048 head=priv->txvopringhead;
4063 RT_TRACE(COMP_ERR,"%s():txring is NULL , BUG!\n",__FUNCTION__);
4066 txring->nStuckCount++;
4068 if(txring->nStuckCount > ResetThreshold)
4070 RT_TRACE( COMP_RESET, "<== TxCheckStuck()\n" );
4071 return RESET_TYPE_NORMAL;
4074 bCheckFwTxCnt = TRUE;
4080 if(HalTxCheckStuck8190Pci(dev))
4082 RT_TRACE(COMP_RESET, "TxCheckStuck(): Fw indicates no Tx condition! \n");
4083 return RESET_TYPE_SILENT;
4087 return RESET_TYPE_NORESET;
4091 static bool HalRxCheckStuck8190Pci(struct net_device *dev)
4093 struct r8192_priv *priv = ieee80211_priv(dev);
4094 u16 RegRxCounter = read_nic_word(dev, 0x130);
4095 bool bStuck = FALSE;
4096 static u8 rx_chk_cnt = 0;
4097 RT_TRACE(COMP_RESET,"%s(): RegRxCounter is %d,RxCounter is %d\n",__FUNCTION__,RegRxCounter,priv->RxCounter);
4098 // If rssi is small, we should check rx for long time because of bad rx.
4099 // or maybe it will continuous silent reset every 2 seconds.
4101 if(priv->undecorated_smoothed_pwdb >= (RateAdaptiveTH_High+5))
4103 rx_chk_cnt = 0; //high rssi, check rx stuck right now.
4105 else if(priv->undecorated_smoothed_pwdb < (RateAdaptiveTH_High+5) &&
4106 ((priv->CurrentChannelBW!=HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb>=RateAdaptiveTH_Low_40M) ||
4107 (priv->CurrentChannelBW==HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb>=RateAdaptiveTH_Low_20M)) )
4119 else if(((priv->CurrentChannelBW!=HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb<RateAdaptiveTH_Low_40M) ||
4120 (priv->CurrentChannelBW==HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb<RateAdaptiveTH_Low_20M)) &&
4121 priv->undecorated_smoothed_pwdb >= VeryLowRSSI)
4125 //DbgPrint("RSSI < %d && RSSI >= %d, no check this time \n", RateAdaptiveTH_Low, VeryLowRSSI);
4131 //DbgPrint("RSSI < %d && RSSI >= %d, check this time \n", RateAdaptiveTH_Low, VeryLowRSSI);
4138 //DbgPrint("RSSI <= %d, no check this time \n", VeryLowRSSI);
4144 //DbgPrint("RSSI <= %d, check this time \n", VeryLowRSSI);
4153 if(priv->RxCounter==RegRxCounter)
4156 priv->RxCounter = RegRxCounter;
4161 static RESET_TYPE RxCheckStuck(struct net_device *dev)
4164 if(HalRxCheckStuck8190Pci(dev))
4166 RT_TRACE(COMP_RESET, "RxStuck Condition\n");
4167 return RESET_TYPE_SILENT;
4170 return RESET_TYPE_NORESET;
4174 rtl819x_ifcheck_resetornot(struct net_device *dev)
4176 struct r8192_priv *priv = ieee80211_priv(dev);
4177 RESET_TYPE TxResetType = RESET_TYPE_NORESET;
4178 RESET_TYPE RxResetType = RESET_TYPE_NORESET;
4179 RT_RF_POWER_STATE rfState;
4181 rfState = priv->ieee80211->eRFPowerState;
4183 TxResetType = TxCheckStuck(dev);
4185 if( rfState != eRfOff &&
4186 /*ADAPTER_TEST_STATUS_FLAG(Adapter, ADAPTER_STATUS_FW_DOWNLOAD_FAILURE)) &&*/
4187 (priv->ieee80211->iw_mode != IW_MODE_ADHOC))
4189 // If driver is in the status of firmware download failure , driver skips RF initialization and RF is
4190 // in turned off state. Driver should check whether Rx stuck and do silent reset. And
4191 // if driver is in firmware download failure status, driver should initialize RF in the following
4192 // silent reset procedure Emily, 2008.01.21
4194 // Driver should not check RX stuck in IBSS mode because it is required to
4195 // set Check BSSID in order to send beacon, however, if check BSSID is
4196 // set, STA cannot hear any packet a all. Emily, 2008.04.12
4197 RxResetType = RxCheckStuck(dev);
4201 RT_TRACE(COMP_RESET,"%s(): TxResetType is %d, RxResetType is %d\n",__FUNCTION__,TxResetType,RxResetType);
4202 if(TxResetType==RESET_TYPE_NORMAL || RxResetType==RESET_TYPE_NORMAL)
4203 return RESET_TYPE_NORMAL;
4204 else if(TxResetType==RESET_TYPE_SILENT || RxResetType==RESET_TYPE_SILENT)
4205 return RESET_TYPE_SILENT;
4207 return RESET_TYPE_NORESET;
4212 static void CamRestoreAllEntry(struct net_device *dev)
4215 struct r8192_priv *priv = ieee80211_priv(dev);
4216 u8* MacAddr = priv->ieee80211->current_network.bssid;
4218 static u8 CAM_CONST_ADDR[4][6] = {
4219 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
4220 {0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
4221 {0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
4222 {0x00, 0x00, 0x00, 0x00, 0x00, 0x03}};
4223 static u8 CAM_CONST_BROAD[] =
4224 {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
4226 RT_TRACE(COMP_SEC, "CamRestoreAllEntry: \n");
4229 if ((priv->ieee80211->pairwise_key_type == KEY_TYPE_WEP40)||
4230 (priv->ieee80211->pairwise_key_type == KEY_TYPE_WEP104))
4233 for(EntryId=0; EntryId<4; EntryId++)
4236 MacAddr = CAM_CONST_ADDR[EntryId];
4240 priv->ieee80211->pairwise_key_type,
4248 else if(priv->ieee80211->pairwise_key_type == KEY_TYPE_TKIP)
4252 if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
4256 priv->ieee80211->pairwise_key_type,
4264 priv->ieee80211->pairwise_key_type,
4270 else if(priv->ieee80211->pairwise_key_type == KEY_TYPE_CCMP)
4274 if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
4278 priv->ieee80211->pairwise_key_type,
4286 priv->ieee80211->pairwise_key_type,
4295 if(priv->ieee80211->group_key_type == KEY_TYPE_TKIP)
4297 MacAddr = CAM_CONST_BROAD;
4298 for(EntryId=1 ; EntryId<4 ; EntryId++)
4304 priv->ieee80211->group_key_type,
4310 if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
4314 priv->ieee80211->group_key_type,
4319 else if(priv->ieee80211->group_key_type == KEY_TYPE_CCMP)
4321 MacAddr = CAM_CONST_BROAD;
4322 for(EntryId=1; EntryId<4 ; EntryId++)
4328 priv->ieee80211->group_key_type,
4335 if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
4339 priv->ieee80211->group_key_type,
4346 void rtl8192_cancel_deferred_work(struct r8192_priv* priv);
4347 int _rtl8192_up(struct net_device *dev);
4350 * This function is used to fix Tx/Rx stop bug temporarily.
4351 * This function will do "system reset" to NIC when Tx or Rx is stuck.
4352 * The method checking Tx/Rx stuck of this function is supported by FW,
4353 * which reports Tx and Rx counter to register 0x128 and 0x130.
4355 static void rtl819x_ifsilentreset(struct net_device *dev)
4357 struct r8192_priv *priv = ieee80211_priv(dev);
4359 int reset_status = 0;
4360 struct ieee80211_device *ieee = priv->ieee80211;
4363 // 2007.07.20. If we need to check CCK stop, please uncomment this line.
4364 //bStuck = Adapter->HalFunc.CheckHWStopHandler(Adapter);
4366 if(priv->ResetProgress==RESET_TYPE_NORESET)
4370 RT_TRACE(COMP_RESET,"=========>Reset progress!! \n");
4372 // Set the variable for reset.
4373 priv->ResetProgress = RESET_TYPE_SILENT;
4374 // rtl8192_close(dev);
4376 down(&priv->wx_sem);
4379 RT_TRACE(COMP_ERR,"%s():the driver is not up! return\n",__FUNCTION__);
4384 RT_TRACE(COMP_RESET,"%s():======>start to down the driver\n",__FUNCTION__);
4385 if(!netif_queue_stopped(dev))
4386 netif_stop_queue(dev);
4388 dm_backup_dynamic_mechanism_state(dev);
4390 rtl8192_irq_disable(dev);
4391 rtl8192_cancel_deferred_work(priv);
4393 del_timer_sync(&priv->watch_dog_timer);
4394 ieee->sync_scan_hurryup = 1;
4395 if(ieee->state == IEEE80211_LINKED)
4397 down(&ieee->wx_sem);
4398 printk("ieee->state is IEEE80211_LINKED\n");
4399 ieee80211_stop_send_beacons(priv->ieee80211);
4400 del_timer_sync(&ieee->associate_timer);
4401 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
4402 cancel_delayed_work(&ieee->associate_retry_wq);
4404 ieee80211_stop_scan(ieee);
4405 netif_carrier_off(dev);
4409 printk("ieee->state is NOT LINKED\n");
4410 ieee80211_softmac_stop_protocol(priv->ieee80211);
4412 rtl8192_rtx_disable(dev);
4414 RT_TRACE(COMP_RESET,"%s():<==========down process is finished\n",__FUNCTION__);
4415 RT_TRACE(COMP_RESET,"%s():===========>start to up the driver\n",__FUNCTION__);
4416 reset_status = _rtl8192_up(dev);
4418 RT_TRACE(COMP_RESET,"%s():<===========up process is finished\n",__FUNCTION__);
4419 if(reset_status == -1)
4428 RT_TRACE(COMP_ERR," ERR!!! %s(): Reset Failed!!\n",__FUNCTION__);
4432 ieee->is_silent_reset = 1;
4434 EnableHWSecurityConfig8192(dev);
4436 if(ieee->state == IEEE80211_LINKED && ieee->iw_mode == IW_MODE_INFRA)
4438 ieee->set_chan(ieee->dev, ieee->current_network.channel);
4441 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
4442 queue_work(ieee->wq, &ieee->associate_complete_wq);
4444 schedule_task(&ieee->associate_complete_wq);
4449 else if(ieee->state == IEEE80211_LINKED && ieee->iw_mode == IW_MODE_ADHOC)
4451 ieee->set_chan(ieee->dev, ieee->current_network.channel);
4452 ieee->link_change(ieee->dev);
4454 // notify_wx_assoc_event(ieee);
4456 ieee80211_start_send_beacons(ieee);
4458 if (ieee->data_hard_resume)
4459 ieee->data_hard_resume(ieee->dev);
4460 netif_carrier_on(ieee->dev);
4464 CamRestoreAllEntry(dev);
4466 // Restore the previous setting for all dynamic mechanism
4467 dm_restore_dynamic_mechanism_state(dev);
4469 priv->ResetProgress = RESET_TYPE_NORESET;
4470 priv->reset_count++;
4472 priv->bForcedSilentReset =false;
4473 priv->bResetInProgress = false;
4475 // For test --> force write UFWP.
4476 write_nic_byte(dev, UFWP, 1);
4477 RT_TRACE(COMP_RESET, "Reset finished!! ====>[%d]\n", priv->reset_count);
4483 void InactivePsWorkItemCallback(struct net_device *dev)
4485 struct r8192_priv *priv = ieee80211_priv(dev);
4486 PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->ieee80211->PowerSaveControl));
4489 RT_TRACE(COMP_POWER, "InactivePsWorkItemCallback() ---------> \n");
4491 // This flag "bSwRfProcessing", indicates the status of IPS procedure, should be set if the IPS workitem
4492 // is really scheduled.
4493 // The old code, sets this flag before scheduling the IPS workitem and however, at the same time the
4494 // previous IPS workitem did not end yet, fails to schedule the current workitem. Thus, bSwRfProcessing
4495 // blocks the IPS procedure of switching RF.
4496 // By Bruce, 2007-12-25.
4498 pPSC->bSwRfProcessing = TRUE;
4500 RT_TRACE(COMP_RF, "InactivePsWorkItemCallback(): Set RF to %s.\n", \
4501 pPSC->eInactivePowerState == eRfOff?"OFF":"ON");
4504 MgntActSet_RF_State(dev, pPSC->eInactivePowerState, RF_CHANGE_BY_IPS);
4507 // To solve CAM values miss in RF OFF, rewrite CAM values after RF ON. By Bruce, 2007-09-20.
4510 if(pPSC->eInactivePowerState == eRfOn)
4511 CamRestoreAllEntry(dev);
4513 pPSC->bSwRfProcessing = FALSE;
4514 RT_TRACE(COMP_POWER, "InactivePsWorkItemCallback() <--------- \n");
4519 // Enter the inactive power save mode. RF will be off
4520 // 2007.08.17, by shien chang.
4523 IPSEnter(struct net_device *dev)
4525 struct r8192_priv *priv = ieee80211_priv(dev);
4526 PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->ieee80211->PowerSaveControl));
4527 RT_RF_POWER_STATE rtState;
4529 if (pPSC->bInactivePs)
4531 rtState = priv->ieee80211->eRFPowerState;
4533 // Added by Bruce, 2007-12-25.
4534 // Do not enter IPS in the following conditions:
4535 // (1) RF is already OFF or Sleep
4536 // (2) bSwRfProcessing (indicates the IPS is still under going)
4537 // (3) Connectted (only disconnected can trigger IPS)
4538 // (4) IBSS (send Beacon)
4539 // (5) AP mode (send Beacon)
4541 if (rtState == eRfOn && !pPSC->bSwRfProcessing
4542 && (priv->ieee80211->state != IEEE80211_LINKED) )
4544 RT_TRACE(COMP_RF,"IPSEnter(): Turn off RF.\n");
4545 pPSC->eInactivePowerState = eRfOff;
4546 // queue_work(priv->priv_wq,&(pPSC->InactivePsWorkItem));
4547 InactivePsWorkItemCallback(dev);
4554 // Leave the inactive power save mode, RF will be on.
4555 // 2007.08.17, by shien chang.
4558 IPSLeave(struct net_device *dev)
4560 struct r8192_priv *priv = ieee80211_priv(dev);
4561 PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->ieee80211->PowerSaveControl));
4562 RT_RF_POWER_STATE rtState;
4564 if (pPSC->bInactivePs)
4566 rtState = priv->ieee80211->eRFPowerState;
4567 if (rtState != eRfOn && !pPSC->bSwRfProcessing && priv->ieee80211->RfOffReason <= RF_CHANGE_BY_IPS)
4569 RT_TRACE(COMP_POWER, "IPSLeave(): Turn on RF.\n");
4570 pPSC->eInactivePowerState = eRfOn;
4571 // queue_work(priv->priv_wq,&(pPSC->InactivePsWorkItem));
4572 InactivePsWorkItemCallback(dev);
4578 static void rtl819x_update_rxcounts(
4579 struct r8192_priv *priv,
4588 *TotalRxDataNum = 0;
4590 SlotIndex = (priv->ieee80211->LinkDetectInfo.SlotIndex++)%(priv->ieee80211->LinkDetectInfo.SlotNum);
4591 priv->ieee80211->LinkDetectInfo.RxBcnNum[SlotIndex] = priv->ieee80211->LinkDetectInfo.NumRecvBcnInPeriod;
4592 priv->ieee80211->LinkDetectInfo.RxDataNum[SlotIndex] = priv->ieee80211->LinkDetectInfo.NumRecvDataInPeriod;
4593 for( i=0; i<priv->ieee80211->LinkDetectInfo.SlotNum; i++ ){
4594 *TotalRxBcnNum += priv->ieee80211->LinkDetectInfo.RxBcnNum[i];
4595 *TotalRxDataNum += priv->ieee80211->LinkDetectInfo.RxDataNum[i];
4600 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
4601 void rtl819x_watchdog_wqcallback(struct work_struct *work)
4603 struct delayed_work *dwork = container_of(work,struct delayed_work,work);
4604 struct r8192_priv *priv = container_of(dwork,struct r8192_priv,watch_dog_wq);
4605 struct net_device *dev = priv->ieee80211->dev;
4607 extern void rtl819x_watchdog_wqcallback(struct net_device *dev)
4609 struct r8192_priv *priv = ieee80211_priv(dev);
4611 struct ieee80211_device* ieee = priv->ieee80211;
4612 RESET_TYPE ResetType = RESET_TYPE_NORESET;
4613 static u8 check_reset_cnt=0;
4614 unsigned long flags;
4615 bool bBusyTraffic = false;
4616 static u8 last_time = 0;
4619 hal_dm_watchdog(dev);
4621 // printk("watch_dog ENABLE_IPS\n");
4622 if(ieee->actscanning == false){
4623 if((ieee->iw_mode != IW_MODE_ADHOC) && (ieee->state == IEEE80211_NOLINK) && (ieee->beinretry == false) && (ieee->eRFPowerState == eRfOn) && !ieee->is_set_key){
4624 if(ieee->PowerSaveControl.ReturnPoint == IPS_CALLBACK_NONE){
4625 printk("====================>haha:IPSEnter()\n");
4627 //ieee80211_stop_scan(priv->ieee80211);
4632 {//to get busy traffic condition
4633 if(ieee->state == IEEE80211_LINKED)
4635 if( ieee->LinkDetectInfo.NumRxOkInPeriod> 666 ||
4636 ieee->LinkDetectInfo.NumTxOkInPeriod> 666 ) {
4637 bBusyTraffic = true;
4641 ieee->LinkDetectInfo.NumRxOkInPeriod = 0;
4642 ieee->LinkDetectInfo.NumTxOkInPeriod = 0;
4643 ieee->LinkDetectInfo.bBusyTraffic = bBusyTraffic;
4647 //added by amy for AP roaming
4650 if(ieee->state == IEEE80211_LINKED && ieee->iw_mode == IW_MODE_INFRA)
4652 u32 TotalRxBcnNum = 0;
4653 u32 TotalRxDataNum = 0;
4655 rtl819x_update_rxcounts(priv, &TotalRxBcnNum, &TotalRxDataNum);
4656 if((TotalRxBcnNum+TotalRxDataNum) == 0)
4658 if( ieee->eRFPowerState == eRfOff)
4659 RT_TRACE(COMP_ERR,"========>%s()\n",__FUNCTION__);
4660 printk("===>%s(): AP is power off,connect another one\n",__FUNCTION__);
4661 // Dot11d_Reset(dev);
4662 ieee->state = IEEE80211_ASSOCIATING;
4663 notify_wx_assoc_event(priv->ieee80211);
4664 RemovePeerTS(priv->ieee80211,priv->ieee80211->current_network.bssid);
4665 ieee->is_roaming = true;
4666 ieee->is_set_key = false;
4667 ieee->link_change(dev);
4668 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
4669 queue_work(ieee->wq, &ieee->associate_procedure_wq);
4671 schedule_task(&ieee->associate_procedure_wq);
4675 ieee->LinkDetectInfo.NumRecvBcnInPeriod=0;
4676 ieee->LinkDetectInfo.NumRecvDataInPeriod=0;
4679 //check if reset the driver
4680 spin_lock_irqsave(&priv->tx_lock,flags);
4681 if(check_reset_cnt++ >= 3 && !ieee->is_roaming && (last_time != 1))
4683 ResetType = rtl819x_ifcheck_resetornot(dev);
4684 check_reset_cnt = 3;
4685 //DbgPrint("Start to check silent reset\n");
4687 spin_unlock_irqrestore(&priv->tx_lock,flags);
4688 if(!priv->bDisableNormalResetCheck && ResetType == RESET_TYPE_NORMAL)
4690 priv->ResetProgress = RESET_TYPE_NORMAL;
4691 RT_TRACE(COMP_RESET,"%s(): NOMAL RESET\n",__FUNCTION__);
4694 /* disable silent reset temply 2008.9.11*/
4696 if( ((priv->force_reset) || (!priv->bDisableNormalResetCheck && ResetType==RESET_TYPE_SILENT))) // This is control by OID set in Pomelo
4699 rtl819x_ifsilentreset(dev);
4704 priv->force_reset = false;
4705 priv->bForcedSilentReset = false;
4706 priv->bResetInProgress = false;
4707 RT_TRACE(COMP_TRACE, " <==RtUsbCheckForHangWorkItemCallback()\n");
4711 void watch_dog_timer_callback(unsigned long data)
4713 struct r8192_priv *priv = ieee80211_priv((struct net_device *) data);
4714 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
4715 queue_delayed_work(priv->priv_wq,&priv->watch_dog_wq,0);
4717 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
4718 schedule_task(&priv->watch_dog_wq);
4720 queue_work(priv->priv_wq,&priv->watch_dog_wq);
4723 mod_timer(&priv->watch_dog_timer, jiffies + MSECS(IEEE80211_WATCH_DOG_TIME));
4726 int _rtl8192_up(struct net_device *dev)
4728 struct r8192_priv *priv = ieee80211_priv(dev);
4730 RT_STATUS init_status = RT_STATUS_SUCCESS;
4732 priv->ieee80211->ieee_up=1;
4733 RT_TRACE(COMP_INIT, "Bringing up iface");
4735 init_status = rtl8192_adapter_start(dev);
4736 if(init_status != RT_STATUS_SUCCESS)
4738 RT_TRACE(COMP_ERR,"ERR!!! %s(): initialization is failed!\n",__FUNCTION__);
4741 RT_TRACE(COMP_INIT, "start adapter finished\n");
4743 if(priv->ieee80211->eRFPowerState!=eRfOn)
4744 MgntActSet_RF_State(dev, eRfOn, priv->ieee80211->RfOffReason);
4746 if(priv->ieee80211->state != IEEE80211_LINKED)
4747 ieee80211_softmac_start_protocol(priv->ieee80211);
4748 ieee80211_reset_queue(priv->ieee80211);
4749 watch_dog_timer_callback((unsigned long) dev);
4750 if(!netif_queue_stopped(dev))
4751 netif_start_queue(dev);
4753 netif_wake_queue(dev);
4759 static int rtl8192_open(struct net_device *dev)
4761 struct r8192_priv *priv = ieee80211_priv(dev);
4764 down(&priv->wx_sem);
4765 ret = rtl8192_up(dev);
4772 int rtl8192_up(struct net_device *dev)
4774 struct r8192_priv *priv = ieee80211_priv(dev);
4776 if (priv->up == 1) return -1;
4778 return _rtl8192_up(dev);
4782 static int rtl8192_close(struct net_device *dev)
4784 struct r8192_priv *priv = ieee80211_priv(dev);
4787 down(&priv->wx_sem);
4789 ret = rtl8192_down(dev);
4797 int rtl8192_down(struct net_device *dev)
4799 struct r8192_priv *priv = ieee80211_priv(dev);
4805 if (priv->up == 0) return -1;
4808 priv->ieee80211->ieee_up = 0;
4809 RT_TRACE(COMP_DOWN, "==========>%s()\n", __FUNCTION__);
4811 if (!netif_queue_stopped(dev))
4812 netif_stop_queue(dev);
4814 rtl8192_irq_disable(dev);
4816 if(!priv->ieee80211->bSupportRemoteWakeUp) {
4817 MgntActSet_RF_State(dev, eRfOff, RF_CHANGE_BY_INIT);
4818 // 2006.11.30. System reset bit
4819 ulRegRead = read_nic_dword(dev, CPU_GEN);
4820 ulRegRead|=CPU_GEN_SYSTEM_RESET;
4821 write_nic_dword(dev, CPU_GEN, ulRegRead);
4823 //2008.06.03 for WOL
4824 write_nic_dword(dev, WFCRC0, 0xffffffff);
4825 write_nic_dword(dev, WFCRC1, 0xffffffff);
4826 write_nic_dword(dev, WFCRC2, 0xffffffff);
4829 ucRegRead = read_nic_byte(dev, GPO);
4831 write_nic_byte(dev, GPO, ucRegRead);
4833 //Write PMR register
4834 write_nic_byte(dev, PMR, 0x5);
4835 //Disable tx, enanble rx
4836 write_nic_byte(dev, MacBlkCtrl, 0xa);
4839 // flush_scheduled_work();
4840 rtl8192_cancel_deferred_work(priv);
4842 del_timer_sync(&priv->watch_dog_timer);
4844 ieee80211_softmac_stop_protocol(priv->ieee80211);
4846 MgntActSet_RF_State(dev, eRfOff, RF_CHANGE_BY_INIT);
4848 rtl8192_rtx_disable(dev);
4849 memset(&priv->ieee80211->current_network, 0 , offsetof(struct ieee80211_network, list));
4851 RT_TRACE(COMP_DOWN, "<==========%s()\n", __FUNCTION__);
4857 void rtl8192_commit(struct net_device *dev)
4859 struct r8192_priv *priv = ieee80211_priv(dev);
4861 if (priv->up == 0) return ;
4864 ieee80211_softmac_stop_protocol(priv->ieee80211);
4866 rtl8192_irq_disable(dev);
4867 rtl8192_rtx_disable(dev);
4872 void rtl8192_restart(struct net_device *dev)
4874 struct r8192_priv *priv = ieee80211_priv(dev);
4876 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
4877 void rtl8192_restart(struct work_struct *work)
4879 struct r8192_priv *priv = container_of(work, struct r8192_priv, reset_wq);
4880 struct net_device *dev = priv->ieee80211->dev;
4882 void rtl8192_restart(struct net_device *dev)
4885 struct r8192_priv *priv = ieee80211_priv(dev);
4888 down(&priv->wx_sem);
4890 rtl8192_commit(dev);
4895 static void r8192_set_multicast(struct net_device *dev)
4897 struct r8192_priv *priv = ieee80211_priv(dev);
4900 //down(&priv->wx_sem);
4904 promisc = (dev->flags & IFF_PROMISC) ? 1:0;
4906 if (promisc != priv->promisc) {
4908 // rtl8192_commit(dev);
4911 priv->promisc = promisc;
4913 //schedule_work(&priv->reset_wq);
4914 //up(&priv->wx_sem);
4918 static int r8192_set_mac_adr(struct net_device *dev, void *mac)
4920 struct r8192_priv *priv = ieee80211_priv(dev);
4921 struct sockaddr *addr = mac;
4923 down(&priv->wx_sem);
4925 memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
4927 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
4928 schedule_work(&priv->reset_wq);
4930 schedule_task(&priv->reset_wq);
4937 /* based on ipw2200 driver */
4938 static int rtl8192_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
4940 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
4941 struct iwreq *wrq = (struct iwreq *)rq;
4943 struct ieee80211_device *ieee = priv->ieee80211;
4945 u8 broadcast_addr[6] = {0xff,0xff,0xff,0xff,0xff,0xff};
4946 struct iw_point *p = &wrq->u.data;
4947 struct ieee_param *ipw = NULL;//(struct ieee_param *)wrq->u.data.pointer;
4949 down(&priv->wx_sem);
4952 if (p->length < sizeof(struct ieee_param) || !p->pointer){
4957 ipw = (struct ieee_param *)kmalloc(p->length, GFP_KERNEL);
4962 if (copy_from_user(ipw, p->pointer, p->length)) {
4969 case RTL_IOCTL_WPA_SUPPLICANT:
4970 //parse here for HW security
4971 if (ipw->cmd == IEEE_CMD_SET_ENCRYPTION)
4973 if (ipw->u.crypt.set_tx)
4975 if (strcmp(ipw->u.crypt.alg, "CCMP") == 0)
4976 ieee->pairwise_key_type = KEY_TYPE_CCMP;
4977 else if (strcmp(ipw->u.crypt.alg, "TKIP") == 0)
4978 ieee->pairwise_key_type = KEY_TYPE_TKIP;
4979 else if (strcmp(ipw->u.crypt.alg, "WEP") == 0)
4981 if (ipw->u.crypt.key_len == 13)
4982 ieee->pairwise_key_type = KEY_TYPE_WEP104;
4983 else if (ipw->u.crypt.key_len == 5)
4984 ieee->pairwise_key_type = KEY_TYPE_WEP40;
4987 ieee->pairwise_key_type = KEY_TYPE_NA;
4989 if (ieee->pairwise_key_type)
4991 memcpy((u8*)key, ipw->u.crypt.key, 16);
4992 EnableHWSecurityConfig8192(dev);
4993 //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!
4995 setKey(dev, 4, ipw->u.crypt.idx, ieee->pairwise_key_type, (u8*)ieee->ap_mac_addr, 0, key);
4996 if (ieee->auth_mode != 2) //LEAP WEP will never set this.
4997 setKey(dev, ipw->u.crypt.idx, ipw->u.crypt.idx, ieee->pairwise_key_type, (u8*)ieee->ap_mac_addr, 0, key);
4999 if ((ieee->pairwise_key_type == KEY_TYPE_CCMP) && ieee->pHTInfo->bCurrentHTSupport){
5000 write_nic_byte(dev, 0x173, 1); //fix aes bug
5004 else //if (ipw->u.crypt.idx) //group key use idx > 0
5006 memcpy((u8*)key, ipw->u.crypt.key, 16);
5007 if (strcmp(ipw->u.crypt.alg, "CCMP") == 0)
5008 ieee->group_key_type= KEY_TYPE_CCMP;
5009 else if (strcmp(ipw->u.crypt.alg, "TKIP") == 0)
5010 ieee->group_key_type = KEY_TYPE_TKIP;
5011 else if (strcmp(ipw->u.crypt.alg, "WEP") == 0)
5013 if (ipw->u.crypt.key_len == 13)
5014 ieee->group_key_type = KEY_TYPE_WEP104;
5015 else if (ipw->u.crypt.key_len == 5)
5016 ieee->group_key_type = KEY_TYPE_WEP40;
5019 ieee->group_key_type = KEY_TYPE_NA;
5021 if (ieee->group_key_type)
5025 ipw->u.crypt.idx, //KeyIndex
5026 ieee->group_key_type, //KeyType
5027 broadcast_addr, //MacAddr
5037 printk("@@ wrq->u pointer = ");
5038 for(i=0;i<wrq->u.data.length;i++){
5039 if(i%10==0) printk("\n");
5040 printk( "%8x|", ((u32*)wrq->u.data.pointer)[i] );
5044 #endif /*JOHN_DEBUG*/
5045 ret = ieee80211_wpa_supplicant_ioctl(priv->ieee80211, &wrq->u.data);
5060 static u8 HwRateToMRate90(bool bIsHT, u8 rate)
5066 case DESC90_RATE1M: ret_rate = MGN_1M; break;
5067 case DESC90_RATE2M: ret_rate = MGN_2M; break;
5068 case DESC90_RATE5_5M: ret_rate = MGN_5_5M; break;
5069 case DESC90_RATE11M: ret_rate = MGN_11M; break;
5070 case DESC90_RATE6M: ret_rate = MGN_6M; break;
5071 case DESC90_RATE9M: ret_rate = MGN_9M; break;
5072 case DESC90_RATE12M: ret_rate = MGN_12M; break;
5073 case DESC90_RATE18M: ret_rate = MGN_18M; break;
5074 case DESC90_RATE24M: ret_rate = MGN_24M; break;
5075 case DESC90_RATE36M: ret_rate = MGN_36M; break;
5076 case DESC90_RATE48M: ret_rate = MGN_48M; break;
5077 case DESC90_RATE54M: ret_rate = MGN_54M; break;
5080 RT_TRACE(COMP_RECV, "HwRateToMRate90(): Non supported Rate [%x], bIsHT = %d!!!\n", rate, bIsHT);
5086 case DESC90_RATEMCS0: ret_rate = MGN_MCS0; break;
5087 case DESC90_RATEMCS1: ret_rate = MGN_MCS1; break;
5088 case DESC90_RATEMCS2: ret_rate = MGN_MCS2; break;
5089 case DESC90_RATEMCS3: ret_rate = MGN_MCS3; break;
5090 case DESC90_RATEMCS4: ret_rate = MGN_MCS4; break;
5091 case DESC90_RATEMCS5: ret_rate = MGN_MCS5; break;
5092 case DESC90_RATEMCS6: ret_rate = MGN_MCS6; break;
5093 case DESC90_RATEMCS7: ret_rate = MGN_MCS7; break;
5094 case DESC90_RATEMCS8: ret_rate = MGN_MCS8; break;
5095 case DESC90_RATEMCS9: ret_rate = MGN_MCS9; break;
5096 case DESC90_RATEMCS10: ret_rate = MGN_MCS10; break;
5097 case DESC90_RATEMCS11: ret_rate = MGN_MCS11; break;
5098 case DESC90_RATEMCS12: ret_rate = MGN_MCS12; break;
5099 case DESC90_RATEMCS13: ret_rate = MGN_MCS13; break;
5100 case DESC90_RATEMCS14: ret_rate = MGN_MCS14; break;
5101 case DESC90_RATEMCS15: ret_rate = MGN_MCS15; break;
5102 case DESC90_RATEMCS32: ret_rate = (0x80|0x20); break;
5105 RT_TRACE(COMP_RECV, "HwRateToMRate90(): Non supported Rate [%x], bIsHT = %d!!!\n",rate, bIsHT);
5114 * Function: UpdateRxPktTimeStamp
5115 * Overview: Recored down the TSF time stamp when receiving a packet
5123 * (pRfd->Status.TimeStampHigh is updated)
5124 * (pRfd->Status.TimeStampLow is updated)
5128 static void UpdateRxPktTimeStamp8190 (struct net_device *dev, struct ieee80211_rx_stats *stats)
5130 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
5132 if(stats->bIsAMPDU && !stats->bFirstMPDU) {
5133 stats->mac_time[0] = priv->LastRxDescTSFLow;
5134 stats->mac_time[1] = priv->LastRxDescTSFHigh;
5136 priv->LastRxDescTSFLow = stats->mac_time[0];
5137 priv->LastRxDescTSFHigh = stats->mac_time[1];
5141 static long rtl819x_translate_todbm(u8 signal_strength_index)// 0-100 index.
5143 long signal_power; // in dBm.
5145 // Translate to dBm (x=0.5y-95).
5146 signal_power = (long)((signal_strength_index + 1) >> 1);
5149 return signal_power;
5154 // Update Rx signal related information in the packet reeived
5155 // to RxStats. User application can query RxStats to realize
5156 // current Rx signal status.
5159 // In normal operation, user only care about the information of the BSS
5160 // and we shall invoke this function if the packet received is from the BSS.
5163 rtl819x_update_rxsignalstatistics8190pci(
5164 struct r8192_priv * priv,
5165 struct ieee80211_rx_stats * pprevious_stats
5170 //2 <ToDo> Update Rx Statistics (such as signal strength and signal quality).
5173 if(priv->stats.recv_signal_power == 0)
5174 priv->stats.recv_signal_power = pprevious_stats->RecvSignalPower;
5176 // To avoid the past result restricting the statistics sensitivity, weight the current power (5/6) to speed up the
5177 // reaction of smoothed Signal Power.
5178 if(pprevious_stats->RecvSignalPower > priv->stats.recv_signal_power)
5180 else if(pprevious_stats->RecvSignalPower < priv->stats.recv_signal_power)
5183 // We need more correct power of received packets and the "SignalStrength" of RxStats have been beautified or translated,
5184 // so we record the correct power in Dbm here. By Bruce, 2008-03-07.
5186 priv->stats.recv_signal_power = (priv->stats.recv_signal_power * 5 + pprevious_stats->RecvSignalPower + weighting) / 6;
5190 rtl8190_process_cck_rxpathsel(
5191 struct r8192_priv * priv,
5192 struct ieee80211_rx_stats * pprevious_stats
5195 #ifdef RTL8190P //Only 90P 2T4R need to check
5196 char last_cck_adc_pwdb[4]={0,0,0,0};
5198 //cosa add for Rx path selection
5199 if(priv->rf_type == RF_2T4R && DM_RxPathSelTable.Enable)
5201 if(pprevious_stats->bIsCCK &&
5202 (pprevious_stats->bPacketToSelf ||pprevious_stats->bPacketBeacon))
5204 /* record the cck adc_pwdb to the sliding window. */
5205 if(priv->stats.cck_adc_pwdb.TotalNum++ >= PHY_RSSI_SLID_WIN_MAX)
5207 priv->stats.cck_adc_pwdb.TotalNum = PHY_RSSI_SLID_WIN_MAX;
5208 for(i=RF90_PATH_A; i<RF90_PATH_MAX; i++)
5210 last_cck_adc_pwdb[i] = priv->stats.cck_adc_pwdb.elements[i][priv->stats.cck_adc_pwdb.index];
5211 priv->stats.cck_adc_pwdb.TotalVal[i] -= last_cck_adc_pwdb[i];
5214 for(i=RF90_PATH_A; i<RF90_PATH_MAX; i++)
5216 priv->stats.cck_adc_pwdb.TotalVal[i] += pprevious_stats->cck_adc_pwdb[i];
5217 priv->stats.cck_adc_pwdb.elements[i][priv->stats.cck_adc_pwdb.index] = pprevious_stats->cck_adc_pwdb[i];
5219 priv->stats.cck_adc_pwdb.index++;
5220 if(priv->stats.cck_adc_pwdb.index >= PHY_RSSI_SLID_WIN_MAX)
5221 priv->stats.cck_adc_pwdb.index = 0;
5223 for(i=RF90_PATH_A; i<RF90_PATH_MAX; i++)
5225 DM_RxPathSelTable.cck_pwdb_sta[i] = priv->stats.cck_adc_pwdb.TotalVal[i]/priv->stats.cck_adc_pwdb.TotalNum;
5228 for(i=RF90_PATH_A; i<RF90_PATH_MAX; i++)
5230 if(pprevious_stats->cck_adc_pwdb[i] > (char)priv->undecorated_smoothed_cck_adc_pwdb[i])
5232 priv->undecorated_smoothed_cck_adc_pwdb[i] =
5233 ( (priv->undecorated_smoothed_cck_adc_pwdb[i]*(Rx_Smooth_Factor-1)) +
5234 (pprevious_stats->cck_adc_pwdb[i])) /(Rx_Smooth_Factor);
5235 priv->undecorated_smoothed_cck_adc_pwdb[i] = priv->undecorated_smoothed_cck_adc_pwdb[i] + 1;
5239 priv->undecorated_smoothed_cck_adc_pwdb[i] =
5240 ( (priv->undecorated_smoothed_cck_adc_pwdb[i]*(Rx_Smooth_Factor-1)) +
5241 (pprevious_stats->cck_adc_pwdb[i])) /(Rx_Smooth_Factor);
5250 /* 2008/01/22 MH We can not delcare RSSI/EVM total value of sliding window to
5251 be a local static. Otherwise, it may increase when we return from S3/S4. The
5252 value will be kept in memory or disk. We must delcare the value in adapter
5253 and it will be reinitialized when return from S3/S4. */
5254 static void rtl8192_process_phyinfo(struct r8192_priv * priv, u8* buffer,struct ieee80211_rx_stats * pprevious_stats, struct ieee80211_rx_stats * pcurrent_stats)
5256 bool bcheck = false;
5258 u32 nspatial_stream, tmp_val;
5260 static u32 slide_rssi_index=0, slide_rssi_statistics=0;
5261 static u32 slide_evm_index=0, slide_evm_statistics=0;
5262 static u32 last_rssi=0, last_evm=0;
5263 //cosa add for rx path selection
5264 // static long slide_cck_adc_pwdb_index=0, slide_cck_adc_pwdb_statistics=0;
5265 // static char last_cck_adc_pwdb[4]={0,0,0,0};
5266 //cosa add for beacon rssi smoothing
5267 static u32 slide_beacon_adc_pwdb_index=0, slide_beacon_adc_pwdb_statistics=0;
5268 static u32 last_beacon_adc_pwdb=0;
5270 struct ieee80211_hdr_3addr *hdr;
5272 unsigned int frag,seq;
5273 hdr = (struct ieee80211_hdr_3addr *)buffer;
5274 sc = le16_to_cpu(hdr->seq_ctl);
5275 frag = WLAN_GET_SEQ_FRAG(sc);
5276 seq = WLAN_GET_SEQ_SEQ(sc);
5277 //cosa add 04292008 to record the sequence number
5278 pcurrent_stats->Seq_Num = seq;
5280 // Check whether we should take the previous packet into accounting
5282 if(!pprevious_stats->bIsAMPDU)
5284 // if previous packet is not aggregated packet
5288 //remve for that we don't use AMPDU to calculate PWDB,because the reported PWDB of some AP is fault.
5290 // if previous packet is aggregated packet, and current packet
5292 // (2) is the first packet of one AMPDU
5293 // that means the previous packet is the last one aggregated packet
5294 if( !pcurrent_stats->bIsAMPDU || pcurrent_stats->bFirstMPDU)
5299 if(slide_rssi_statistics++ >= PHY_RSSI_SLID_WIN_MAX)
5301 slide_rssi_statistics = PHY_RSSI_SLID_WIN_MAX;
5302 last_rssi = priv->stats.slide_signal_strength[slide_rssi_index];
5303 priv->stats.slide_rssi_total -= last_rssi;
5305 priv->stats.slide_rssi_total += pprevious_stats->SignalStrength;
5307 priv->stats.slide_signal_strength[slide_rssi_index++] = pprevious_stats->SignalStrength;
5308 if(slide_rssi_index >= PHY_RSSI_SLID_WIN_MAX)
5309 slide_rssi_index = 0;
5311 // <1> Showed on UI for user, in dbm
5312 tmp_val = priv->stats.slide_rssi_total/slide_rssi_statistics;
5313 priv->stats.signal_strength = rtl819x_translate_todbm((u8)tmp_val);
5314 pcurrent_stats->rssi = priv->stats.signal_strength;
5316 // If the previous packet does not match the criteria, neglect it
5318 if(!pprevious_stats->bPacketMatchBSSID)
5320 if(!pprevious_stats->bToSelfBA)
5327 rtl8190_process_cck_rxpathsel(priv,pprevious_stats);
5332 priv->stats.num_process_phyinfo++;
5334 /* record the general signal strength to the sliding window. */
5335 if(slide_rssi_statistics++ >= PHY_RSSI_SLID_WIN_MAX)
5337 slide_rssi_statistics = PHY_RSSI_SLID_WIN_MAX;
5338 last_rssi = priv->stats.slide_signal_strength[slide_rssi_index];
5339 priv->stats.slide_rssi_total -= last_rssi;
5341 priv->stats.slide_rssi_total += pprevious_stats->SignalStrength;
5343 priv->stats.slide_signal_strength[slide_rssi_index++] = pprevious_stats->SignalStrength;
5344 if(slide_rssi_index >= PHY_RSSI_SLID_WIN_MAX)
5345 slide_rssi_index = 0;
5347 // <1> Showed on UI for user, in dbm
5348 tmp_val = priv->stats.slide_rssi_total/slide_rssi_statistics;
5349 priv->stats.signal_strength = rtl819x_translate_todbm((u8)tmp_val);
5352 // <2> Showed on UI for engineering
5353 // hardware does not provide rssi information for each rf path in CCK
5354 if(!pprevious_stats->bIsCCK && pprevious_stats->bPacketToSelf)
5356 for (rfpath = RF90_PATH_A; rfpath < RF90_PATH_C; rfpath++)
5358 if (!rtl8192_phy_CheckIsLegalRFPath(priv->ieee80211->dev, rfpath))
5360 RT_TRACE(COMP_DBG,"Jacken -> pPreviousstats->RxMIMOSignalStrength[rfpath] = %d \n" ,pprevious_stats->RxMIMOSignalStrength[rfpath] );
5361 //Fixed by Jacken 2008-03-20
5362 if(priv->stats.rx_rssi_percentage[rfpath] == 0)
5364 priv->stats.rx_rssi_percentage[rfpath] = pprevious_stats->RxMIMOSignalStrength[rfpath];
5365 //DbgPrint("MIMO RSSI initialize \n");
5367 if(pprevious_stats->RxMIMOSignalStrength[rfpath] > priv->stats.rx_rssi_percentage[rfpath])
5369 priv->stats.rx_rssi_percentage[rfpath] =
5370 ( (priv->stats.rx_rssi_percentage[rfpath]*(Rx_Smooth_Factor-1)) +
5371 (pprevious_stats->RxMIMOSignalStrength[rfpath])) /(Rx_Smooth_Factor);
5372 priv->stats.rx_rssi_percentage[rfpath] = priv->stats.rx_rssi_percentage[rfpath] + 1;
5376 priv->stats.rx_rssi_percentage[rfpath] =
5377 ( (priv->stats.rx_rssi_percentage[rfpath]*(Rx_Smooth_Factor-1)) +
5378 (pprevious_stats->RxMIMOSignalStrength[rfpath])) /(Rx_Smooth_Factor);
5380 RT_TRACE(COMP_DBG,"Jacken -> priv->RxStats.RxRSSIPercentage[rfPath] = %d \n" ,priv->stats.rx_rssi_percentage[rfpath] );
5388 //cosa add for beacon rssi smoothing by average.
5389 if(pprevious_stats->bPacketBeacon)
5391 /* record the beacon pwdb to the sliding window. */
5392 if(slide_beacon_adc_pwdb_statistics++ >= PHY_Beacon_RSSI_SLID_WIN_MAX)
5394 slide_beacon_adc_pwdb_statistics = PHY_Beacon_RSSI_SLID_WIN_MAX;
5395 last_beacon_adc_pwdb = priv->stats.Slide_Beacon_pwdb[slide_beacon_adc_pwdb_index];
5396 priv->stats.Slide_Beacon_Total -= last_beacon_adc_pwdb;
5397 //DbgPrint("slide_beacon_adc_pwdb_index = %d, last_beacon_adc_pwdb = %d, Adapter->RxStats.Slide_Beacon_Total = %d\n",
5398 // slide_beacon_adc_pwdb_index, last_beacon_adc_pwdb, Adapter->RxStats.Slide_Beacon_Total);
5400 priv->stats.Slide_Beacon_Total += pprevious_stats->RxPWDBAll;
5401 priv->stats.Slide_Beacon_pwdb[slide_beacon_adc_pwdb_index] = pprevious_stats->RxPWDBAll;
5402 //DbgPrint("slide_beacon_adc_pwdb_index = %d, pPreviousRfd->Status.RxPWDBAll = %d\n", slide_beacon_adc_pwdb_index, pPreviousRfd->Status.RxPWDBAll);
5403 slide_beacon_adc_pwdb_index++;
5404 if(slide_beacon_adc_pwdb_index >= PHY_Beacon_RSSI_SLID_WIN_MAX)
5405 slide_beacon_adc_pwdb_index = 0;
5406 pprevious_stats->RxPWDBAll = priv->stats.Slide_Beacon_Total/slide_beacon_adc_pwdb_statistics;
5407 if(pprevious_stats->RxPWDBAll >= 3)
5408 pprevious_stats->RxPWDBAll -= 3;
5411 RT_TRACE(COMP_RXDESC, "Smooth %s PWDB = %d\n",
5412 pprevious_stats->bIsCCK? "CCK": "OFDM",
5413 pprevious_stats->RxPWDBAll);
5415 if(pprevious_stats->bPacketToSelf || pprevious_stats->bPacketBeacon || pprevious_stats->bToSelfBA)
5417 if(priv->undecorated_smoothed_pwdb < 0) // initialize
5419 priv->undecorated_smoothed_pwdb = pprevious_stats->RxPWDBAll;
5420 //DbgPrint("First pwdb initialize \n");
5423 if(pprevious_stats->RxPWDBAll > (u32)priv->undecorated_smoothed_pwdb)
5425 priv->undecorated_smoothed_pwdb =
5426 ( ((priv->undecorated_smoothed_pwdb)*(Rx_Smooth_Factor-1)) +
5427 (pprevious_stats->RxPWDBAll)) /(Rx_Smooth_Factor);
5428 priv->undecorated_smoothed_pwdb = priv->undecorated_smoothed_pwdb + 1;
5432 priv->undecorated_smoothed_pwdb =
5433 ( ((priv->undecorated_smoothed_pwdb)*(Rx_Smooth_Factor-1)) +
5434 (pprevious_stats->RxPWDBAll)) /(Rx_Smooth_Factor);
5437 //Fixed by Jacken 2008-03-20
5438 if(pPreviousRfd->Status.RxPWDBAll > (u32)pHalData->UndecoratedSmoothedPWDB)
5440 pHalData->UndecoratedSmoothedPWDB =
5441 ( ((pHalData->UndecoratedSmoothedPWDB)* 5) + (pPreviousRfd->Status.RxPWDBAll)) / 6;
5442 pHalData->UndecoratedSmoothedPWDB = pHalData->UndecoratedSmoothedPWDB + 1;
5446 pHalData->UndecoratedSmoothedPWDB =
5447 ( ((pHalData->UndecoratedSmoothedPWDB)* 5) + (pPreviousRfd->Status.RxPWDBAll)) / 6;
5450 rtl819x_update_rxsignalstatistics8190pci(priv,pprevious_stats);
5456 /* record the general EVM to the sliding window. */
5457 if(pprevious_stats->SignalQuality == 0)
5462 if(pprevious_stats->bPacketToSelf || pprevious_stats->bPacketBeacon || pprevious_stats->bToSelfBA){
5463 if(slide_evm_statistics++ >= PHY_RSSI_SLID_WIN_MAX){
5464 slide_evm_statistics = PHY_RSSI_SLID_WIN_MAX;
5465 last_evm = priv->stats.slide_evm[slide_evm_index];
5466 priv->stats.slide_evm_total -= last_evm;
5469 priv->stats.slide_evm_total += pprevious_stats->SignalQuality;
5471 priv->stats.slide_evm[slide_evm_index++] = pprevious_stats->SignalQuality;
5472 if(slide_evm_index >= PHY_RSSI_SLID_WIN_MAX)
5473 slide_evm_index = 0;
5475 // <1> Showed on UI for user, in percentage.
5476 tmp_val = priv->stats.slide_evm_total/slide_evm_statistics;
5477 priv->stats.signal_quality = tmp_val;
5478 //cosa add 10/11/2007, Showed on UI for user in Windows Vista, for Link quality.
5479 priv->stats.last_signal_strength_inpercent = tmp_val;
5482 // <2> Showed on UI for engineering
5483 if(pprevious_stats->bPacketToSelf || pprevious_stats->bPacketBeacon || pprevious_stats->bToSelfBA)
5485 for(nspatial_stream = 0; nspatial_stream<2 ; nspatial_stream++) // 2 spatial stream
5487 if(pprevious_stats->RxMIMOSignalQuality[nspatial_stream] != -1)
5489 if(priv->stats.rx_evm_percentage[nspatial_stream] == 0) // initialize
5491 priv->stats.rx_evm_percentage[nspatial_stream] = pprevious_stats->RxMIMOSignalQuality[nspatial_stream];
5493 priv->stats.rx_evm_percentage[nspatial_stream] =
5494 ( (priv->stats.rx_evm_percentage[nspatial_stream]* (Rx_Smooth_Factor-1)) +
5495 (pprevious_stats->RxMIMOSignalQuality[nspatial_stream]* 1)) / (Rx_Smooth_Factor);
5503 /*-----------------------------------------------------------------------------
5504 * Function: rtl819x_query_rxpwrpercentage()
5508 * Input: char antpower
5512 * Return: 0-100 percentage
5516 * 05/26/2008 amy Create Version 0 porting from windows code.
5518 *---------------------------------------------------------------------------*/
5519 static u8 rtl819x_query_rxpwrpercentage(
5523 if ((antpower <= -100) || (antpower >= 20))
5527 else if (antpower >= 0)
5533 return (100+antpower);
5536 } /* QueryRxPwrPercentage */
5539 rtl819x_evm_dbtopercentage(
5551 ret_val = 0 - ret_val;
5560 // We want good-looking for signal strength/quality
5561 // 2007/7/19 01:09, by cosa.
5563 static long rtl819x_signal_scale_mapping(long currsig)
5567 // Step 1. Scale mapping.
5568 if(currsig >= 61 && currsig <= 100)
5570 retsig = 90 + ((currsig - 60) / 4);
5572 else if(currsig >= 41 && currsig <= 60)
5574 retsig = 78 + ((currsig - 40) / 2);
5576 else if(currsig >= 31 && currsig <= 40)
5578 retsig = 66 + (currsig - 30);
5580 else if(currsig >= 21 && currsig <= 30)
5582 retsig = 54 + (currsig - 20);
5584 else if(currsig >= 5 && currsig <= 20)
5586 retsig = 42 + (((currsig - 5) * 2) / 3);
5588 else if(currsig == 4)
5592 else if(currsig == 3)
5596 else if(currsig == 2)
5600 else if(currsig == 1)
5612 static void rtl8192_query_rxphystatus(
5613 struct r8192_priv * priv,
5614 struct ieee80211_rx_stats * pstats,
5615 prx_desc_819x_pci pdesc,
5616 prx_fwinfo_819x_pci pdrvinfo,
5617 struct ieee80211_rx_stats * precord_stats,
5618 bool bpacket_match_bssid,
5619 bool bpacket_toself,
5624 //PRT_RFD_STATUS pRtRfdStatus = &(pRfd->Status);
5625 phy_sts_ofdm_819xpci_t* pofdm_buf;
5626 phy_sts_cck_819xpci_t * pcck_buf;
5627 phy_ofdm_rx_status_rxsc_sgien_exintfflag* prxsc;
5629 u8 i,max_spatial_stream, tmp_rxsnr, tmp_rxevm, rxsc_sgien_exflg;
5630 char rx_pwr[4], rx_pwr_all=0;
5631 //long rx_avg_pwr = 0;
5632 char rx_snrX, rx_evmX;
5634 u32 RSSI, total_rssi=0;//, total_evm=0;
5635 // long signal_strength_index = 0;
5639 /* 2007/07/04 MH For OFDM RSSI. For high power or not. */
5640 static u8 check_reg824 = 0;
5641 static u32 reg824_bit9 = 0;
5643 priv->stats.numqry_phystatus++;
5645 is_cck_rate = rx_hal_is_cck_rate(pdrvinfo);
5647 // Record it for next packet processing
5648 memset(precord_stats, 0, sizeof(struct ieee80211_rx_stats));
5649 pstats->bPacketMatchBSSID = precord_stats->bPacketMatchBSSID = bpacket_match_bssid;
5650 pstats->bPacketToSelf = precord_stats->bPacketToSelf = bpacket_toself;
5651 pstats->bIsCCK = precord_stats->bIsCCK = is_cck_rate;//RX_HAL_IS_CCK_RATE(pDrvInfo);
5652 pstats->bPacketBeacon = precord_stats->bPacketBeacon = bPacketBeacon;
5653 pstats->bToSelfBA = precord_stats->bToSelfBA = bToSelfBA;
5654 /*2007.08.30 requested by SD3 Jerry */
5655 if(check_reg824 == 0)
5657 reg824_bit9 = rtl8192_QueryBBReg(priv->ieee80211->dev, rFPGA0_XA_HSSIParameter2, 0x200);
5662 prxpkt = (u8*)pdrvinfo;
5664 /* Move pointer to the 16th bytes. Phy status start address. */
5665 prxpkt += sizeof(rx_fwinfo_819x_pci);
5667 /* Initial the cck and ofdm buffer pointer */
5668 pcck_buf = (phy_sts_cck_819xpci_t *)prxpkt;
5669 pofdm_buf = (phy_sts_ofdm_819xpci_t *)prxpkt;
5671 pstats->RxMIMOSignalQuality[0] = -1;
5672 pstats->RxMIMOSignalQuality[1] = -1;
5673 precord_stats->RxMIMOSignalQuality[0] = -1;
5674 precord_stats->RxMIMOSignalQuality[1] = -1;
5679 // (1)Hardware does not provide RSSI for CCK
5683 // (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive)
5685 u8 report;//, cck_agc_rpt;
5688 char cck_adc_pwdb[4];
5690 priv->stats.numqry_phystatusCCK++;
5692 #ifdef RTL8190P //Only 90P 2T4R need to check
5693 if(priv->rf_type == RF_2T4R && DM_RxPathSelTable.Enable && bpacket_match_bssid)
5695 for(i=RF90_PATH_A; i<RF90_PATH_MAX; i++)
5697 tmp_pwdb = pcck_buf->adc_pwdb_X[i];
5698 cck_adc_pwdb[i] = (char)tmp_pwdb;
5699 cck_adc_pwdb[i] /= 2;
5700 pstats->cck_adc_pwdb[i] = precord_stats->cck_adc_pwdb[i] = cck_adc_pwdb[i];
5701 //DbgPrint("RF-%d tmp_pwdb = 0x%x, cck_adc_pwdb = %d", i, tmp_pwdb, cck_adc_pwdb[i]);
5708 report = pcck_buf->cck_agc_rpt & 0xc0;
5712 //Fixed by Jacken from Bryant 2008-03-20
5713 //Original value is -38 , -26 , -14 , -2
5714 //Fixed value is -35 , -23 , -11 , 6
5716 rx_pwr_all = -35 - (pcck_buf->cck_agc_rpt & 0x3e);
5719 rx_pwr_all = -23 - (pcck_buf->cck_agc_rpt & 0x3e);
5722 rx_pwr_all = -11 - (pcck_buf->cck_agc_rpt & 0x3e);
5725 rx_pwr_all = 8 - (pcck_buf->cck_agc_rpt & 0x3e);
5731 report = pcck_buf->cck_agc_rpt & 0x60;
5736 rx_pwr_all = -35 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1) ;
5739 rx_pwr_all = -23 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1);
5742 rx_pwr_all = -11 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1) ;
5745 rx_pwr_all = -8 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1) ;
5750 pwdb_all = rtl819x_query_rxpwrpercentage(rx_pwr_all);
5751 pstats->RxPWDBAll = precord_stats->RxPWDBAll = pwdb_all;
5752 pstats->RecvSignalPower = rx_pwr_all;
5755 // (3) Get Signal Quality (EVM)
5757 if(bpacket_match_bssid)
5761 if(pstats->RxPWDBAll > 40)
5766 sq = pcck_buf->sq_rpt;
5768 if(pcck_buf->sq_rpt > 64)
5770 else if (pcck_buf->sq_rpt < 20)
5773 sq = ((64-sq) * 100) / 44;
5775 pstats->SignalQuality = precord_stats->SignalQuality = sq;
5776 pstats->RxMIMOSignalQuality[0] = precord_stats->RxMIMOSignalQuality[0] = sq;
5777 pstats->RxMIMOSignalQuality[1] = precord_stats->RxMIMOSignalQuality[1] = -1;
5782 priv->stats.numqry_phystatusHT++;
5784 // (1)Get RSSI for HT rate
5786 for(i=RF90_PATH_A; i<RF90_PATH_MAX; i++)
5788 // 2008/01/30 MH we will judge RF RX path now.
5789 if (priv->brfpath_rxenable[i])
5794 //Fixed by Jacken from Bryant 2008-03-20
5795 //Original value is 106
5796 #ifdef RTL8190P //Modify by Jacken 2008/03/31
5797 rx_pwr[i] = ((pofdm_buf->trsw_gain_X[i]&0x3F)*2) - 106;
5799 rx_pwr[i] = ((pofdm_buf->trsw_gain_X[i]&0x3F)*2) - 110;
5802 //Get Rx snr value in DB
5803 tmp_rxsnr = pofdm_buf->rxsnr_X[i];
5804 rx_snrX = (char)(tmp_rxsnr);
5806 priv->stats.rxSNRdB[i] = (long)rx_snrX;
5808 /* Translate DBM to percentage. */
5809 RSSI = rtl819x_query_rxpwrpercentage(rx_pwr[i]);
5810 if (priv->brfpath_rxenable[i])
5813 /* Record Signal Strength for next packet */
5814 if(bpacket_match_bssid)
5816 pstats->RxMIMOSignalStrength[i] =(u8) RSSI;
5817 precord_stats->RxMIMOSignalStrength[i] =(u8) RSSI;
5823 // (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive)
5825 //Fixed by Jacken from Bryant 2008-03-20
5826 //Original value is 106
5827 rx_pwr_all = (((pofdm_buf->pwdb_all ) >> 1 )& 0x7f) -106;
5828 pwdb_all = rtl819x_query_rxpwrpercentage(rx_pwr_all);
5830 pstats->RxPWDBAll = precord_stats->RxPWDBAll = pwdb_all;
5831 pstats->RxPower = precord_stats->RxPower = rx_pwr_all;
5832 pstats->RecvSignalPower = rx_pwr_all;
5834 // (3)EVM of HT rate
5836 if(pdrvinfo->RxHT && pdrvinfo->RxRate>=DESC90_RATEMCS8 &&
5837 pdrvinfo->RxRate<=DESC90_RATEMCS15)
5838 max_spatial_stream = 2; //both spatial stream make sense
5840 max_spatial_stream = 1; //only spatial stream 1 makes sense
5842 for(i=0; i<max_spatial_stream; i++)
5844 tmp_rxevm = pofdm_buf->rxevm_X[i];
5845 rx_evmX = (char)(tmp_rxevm);
5847 // Do not use shift operation like "rx_evmX >>= 1" because the compilor of free build environment
5848 // fill most significant bit to "zero" when doing shifting operation which may change a negative
5849 // value to positive one, then the dbm value (which is supposed to be negative) is not correct anymore.
5852 evm = rtl819x_evm_dbtopercentage(rx_evmX);
5854 EVM = SignalScaleMapping(EVM);//make it good looking, from 0~100
5856 if(bpacket_match_bssid)
5858 if(i==0) // Fill value in RFD, Get the first spatial stream only
5859 pstats->SignalQuality = precord_stats->SignalQuality = (u8)(evm & 0xff);
5860 pstats->RxMIMOSignalQuality[i] = precord_stats->RxMIMOSignalQuality[i] = (u8)(evm & 0xff);
5865 /* record rx statistics for debug */
5866 rxsc_sgien_exflg = pofdm_buf->rxsc_sgien_exflg;
5867 prxsc = (phy_ofdm_rx_status_rxsc_sgien_exintfflag *)&rxsc_sgien_exflg;
5868 if(pdrvinfo->BW) //40M channel
5869 priv->stats.received_bwtype[1+prxsc->rxsc]++;
5871 priv->stats.received_bwtype[0]++;
5874 //UI BSS List signal strength(in percentage), make it good looking, from 0~100.
5875 //It is assigned to the BSS List in GetValueFromBeaconOrProbeRsp().
5878 pstats->SignalStrength = precord_stats->SignalStrength = (u8)(rtl819x_signal_scale_mapping((long)pwdb_all));//PWDB_ALL;
5883 //pRfd->Status.SignalStrength = pRecordRfd->Status.SignalStrength = (u1Byte)(SignalScaleMapping(total_rssi/=RF90_PATH_MAX));//(u1Byte)(total_rssi/=RF90_PATH_MAX);
5884 // We can judge RX path number now.
5886 pstats->SignalStrength = precord_stats->SignalStrength = (u8)(rtl819x_signal_scale_mapping((long)(total_rssi/=rf_rx_num)));
5888 } /* QueryRxPhyStatus8190Pci */
5891 rtl8192_record_rxdesc_forlateruse(
5892 struct ieee80211_rx_stats * psrc_stats,
5893 struct ieee80211_rx_stats * ptarget_stats
5896 ptarget_stats->bIsAMPDU = psrc_stats->bIsAMPDU;
5897 ptarget_stats->bFirstMPDU = psrc_stats->bFirstMPDU;
5898 //ptarget_stats->Seq_Num = psrc_stats->Seq_Num;
5903 static void TranslateRxSignalStuff819xpci(struct net_device *dev,
5904 struct sk_buff *skb,
5905 struct ieee80211_rx_stats * pstats,
5906 prx_desc_819x_pci pdesc,
5907 prx_fwinfo_819x_pci pdrvinfo)
5909 // TODO: We must only check packet for current MAC address. Not finish
5910 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
5911 bool bpacket_match_bssid, bpacket_toself;
5912 bool bPacketBeacon=false, bToSelfBA=false;
5913 static struct ieee80211_rx_stats previous_stats;
5914 struct ieee80211_hdr_3addr *hdr;
5917 // Get Signal Quality for only RX data queue (but not command queue)
5922 /* Get MAC frame start address. */
5923 tmp_buf = skb->data;
5925 hdr = (struct ieee80211_hdr_3addr *)tmp_buf;
5926 fc = le16_to_cpu(hdr->frame_ctl);
5927 type = WLAN_FC_GET_TYPE(fc);
5928 praddr = hdr->addr1;
5930 /* Check if the received packet is acceptabe. */
5931 bpacket_match_bssid = ((IEEE80211_FTYPE_CTL != type) &&
5932 (eqMacAddr(priv->ieee80211->current_network.bssid, (fc & IEEE80211_FCTL_TODS)? hdr->addr1 : (fc & IEEE80211_FCTL_FROMDS )? hdr->addr2 : hdr->addr3))
5933 && (!pstats->bHwError) && (!pstats->bCRC)&& (!pstats->bICV));
5934 bpacket_toself = bpacket_match_bssid & (eqMacAddr(praddr, priv->ieee80211->dev->dev_addr));
5936 if(WLAN_FC_GET_FRAMETYPE(fc)== IEEE80211_STYPE_BEACON)
5938 bPacketBeacon = true;
5939 //DbgPrint("Beacon 2, MatchBSSID = %d, ToSelf = %d \n", bPacketMatchBSSID, bPacketToSelf);
5941 if(WLAN_FC_GET_FRAMETYPE(fc) == IEEE80211_STYPE_BLOCKACK)
5943 if((eqMacAddr(praddr,dev->dev_addr)))
5945 //DbgPrint("BlockAck, MatchBSSID = %d, ToSelf = %d \n", bPacketMatchBSSID, bPacketToSelf);
5949 if(bpacket_match_bssid)
5951 priv->stats.numpacket_matchbssid++;
5954 priv->stats.numpacket_toself++;
5957 // Process PHY information for previous packet (RSSI/PWDB/EVM)
5959 // Because phy information is contained in the last packet of AMPDU only, so driver
5960 // should process phy information of previous packet
5961 rtl8192_process_phyinfo(priv, tmp_buf,&previous_stats, pstats);
5962 rtl8192_query_rxphystatus(priv, pstats, pdesc, pdrvinfo, &previous_stats, bpacket_match_bssid,
5963 bpacket_toself ,bPacketBeacon, bToSelfBA);
5964 rtl8192_record_rxdesc_forlateruse(pstats, &previous_stats);
5969 static void rtl8192_tx_resume(struct net_device *dev)
5971 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
5972 struct ieee80211_device *ieee = priv->ieee80211;
5973 struct sk_buff *skb;
5976 for(queue_index = BK_QUEUE; queue_index < TXCMD_QUEUE;queue_index++) {
5977 while((!skb_queue_empty(&ieee->skb_waitQ[queue_index]))&&
5978 (priv->ieee80211->check_nic_enough_desc(dev,queue_index) > 0)) {
5979 /* 1. dequeue the packet from the wait queue */
5980 skb = skb_dequeue(&ieee->skb_waitQ[queue_index]);
5981 /* 2. tx the packet directly */
5982 ieee->softmac_data_hard_start_xmit(skb,dev,0/* rate useless now*/);
5984 if(queue_index!=MGNT_QUEUE) {
5985 ieee->stats.tx_packets++;
5986 ieee->stats.tx_bytes += skb->len;
5993 void rtl8192_irq_tx_tasklet(struct r8192_priv *priv)
5995 rtl8192_tx_resume(priv->ieee80211->dev);
5999 * Function: UpdateReceivedRateHistogramStatistics
6000 * Overview: Recored down the received data rate
6008 * (Adapter->RxStats.ReceivedRateHistogram[] is updated)
6012 static void UpdateReceivedRateHistogramStatistics8190(
6013 struct net_device *dev,
6014 struct ieee80211_rx_stats* pstats
6017 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
6018 u32 rcvType=1; //0: Total, 1:OK, 2:CRC, 3:ICV
6020 u32 preamble_guardinterval; //1: short preamble/GI, 0: long preamble/GI
6022 /* 2007/03/09 MH We will not update rate of packet from rx cmd queue. */
6024 if (pRfd->queue_id == CMPK_RX_QUEUE_ID)
6029 else if(pstats->bICV)
6032 if(pstats->bShortPreamble)
6033 preamble_guardinterval = 1;// short
6035 preamble_guardinterval = 0;// long
6037 switch(pstats->rate)
6042 case MGN_1M: rateIndex = 0; break;
6043 case MGN_2M: rateIndex = 1; break;
6044 case MGN_5_5M: rateIndex = 2; break;
6045 case MGN_11M: rateIndex = 3; break;
6049 case MGN_6M: rateIndex = 4; break;
6050 case MGN_9M: rateIndex = 5; break;
6051 case MGN_12M: rateIndex = 6; break;
6052 case MGN_18M: rateIndex = 7; break;
6053 case MGN_24M: rateIndex = 8; break;
6054 case MGN_36M: rateIndex = 9; break;
6055 case MGN_48M: rateIndex = 10; break;
6056 case MGN_54M: rateIndex = 11; break;
6058 // 11n High throughput rate
6060 case MGN_MCS0: rateIndex = 12; break;
6061 case MGN_MCS1: rateIndex = 13; break;
6062 case MGN_MCS2: rateIndex = 14; break;
6063 case MGN_MCS3: rateIndex = 15; break;
6064 case MGN_MCS4: rateIndex = 16; break;
6065 case MGN_MCS5: rateIndex = 17; break;
6066 case MGN_MCS6: rateIndex = 18; break;
6067 case MGN_MCS7: rateIndex = 19; break;
6068 case MGN_MCS8: rateIndex = 20; break;
6069 case MGN_MCS9: rateIndex = 21; break;
6070 case MGN_MCS10: rateIndex = 22; break;
6071 case MGN_MCS11: rateIndex = 23; break;
6072 case MGN_MCS12: rateIndex = 24; break;
6073 case MGN_MCS13: rateIndex = 25; break;
6074 case MGN_MCS14: rateIndex = 26; break;
6075 case MGN_MCS15: rateIndex = 27; break;
6076 default: rateIndex = 28; break;
6078 priv->stats.received_preamble_GI[preamble_guardinterval][rateIndex]++;
6079 priv->stats.received_rate_histogram[0][rateIndex]++; //total
6080 priv->stats.received_rate_histogram[rcvType][rateIndex]++;
6083 static void rtl8192_rx(struct net_device *dev)
6085 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
6086 struct ieee80211_hdr_1addr *ieee80211_hdr = NULL;
6087 bool unicast_packet = false;
6088 struct ieee80211_rx_stats stats = {
6092 .freq = IEEE80211_24GHZ_BAND,
6094 unsigned int count = priv->rxringcount;
6096 stats.nic_type = NIC_8192E;
6099 rx_desc_819x_pci *pdesc = &priv->rx_ring[priv->rx_idx];//rx descriptor
6100 struct sk_buff *skb = priv->rx_buf[priv->rx_idx];//rx pkt
6103 /* wait data to be filled by hardware */
6106 stats.bICV = pdesc->ICV;
6107 stats.bCRC = pdesc->CRC32;
6108 stats.bHwError = pdesc->CRC32 | pdesc->ICV;
6110 stats.Length = pdesc->Length;
6111 if(stats.Length < 24)
6112 stats.bHwError |= 1;
6114 if(stats.bHwError) {
6115 stats.bShift = false;
6118 if (pdesc->Length <500)
6119 priv->stats.rxcrcerrmin++;
6120 else if (pdesc->Length >1000)
6121 priv->stats.rxcrcerrmax++;
6123 priv->stats.rxcrcerrmid++;
6127 prx_fwinfo_819x_pci pDrvInfo = NULL;
6128 struct sk_buff *new_skb = dev_alloc_skb(priv->rxbuffersize);
6130 if (unlikely(!new_skb)) {
6134 stats.RxDrvInfoSize = pdesc->RxDrvInfoSize;
6135 stats.RxBufShift = ((pdesc->Shift)&0x03);
6136 stats.Decrypted = !pdesc->SWDec;
6138 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
6139 pci_dma_sync_single_for_cpu(priv->pdev,
6141 pci_unmap_single(priv->pdev,
6143 *((dma_addr_t *)skb->cb),
6145 PCI_DMA_FROMDEVICE);
6146 skb_put(skb, pdesc->Length);
6147 pDrvInfo = (rx_fwinfo_819x_pci *)(skb->data + stats.RxBufShift);
6148 skb_reserve(skb, stats.RxDrvInfoSize + stats.RxBufShift);
6150 stats.rate = HwRateToMRate90((bool)pDrvInfo->RxHT, (u8)pDrvInfo->RxRate);
6151 stats.bShortPreamble = pDrvInfo->SPLCP;
6153 /* it is debug only. It should be disabled in released driver.
6154 * 2007.1.11 by Emily
6156 UpdateReceivedRateHistogramStatistics8190(dev, &stats);
6158 stats.bIsAMPDU = (pDrvInfo->PartAggr==1);
6159 stats.bFirstMPDU = (pDrvInfo->PartAggr==1) && (pDrvInfo->FirstAGGR==1);
6161 stats.TimeStampLow = pDrvInfo->TSFL;
6162 stats.TimeStampHigh = read_nic_dword(dev, TSFR+4);
6164 UpdateRxPktTimeStamp8190(dev, &stats);
6167 // Get Total offset of MPDU Frame Body
6169 if((stats.RxBufShift + stats.RxDrvInfoSize) > 0)
6172 stats.RxIs40MHzPacket = pDrvInfo->BW;
6175 TranslateRxSignalStuff819xpci(dev,skb, &stats, pdesc, pDrvInfo);
6178 if(pDrvInfo->FirstAGGR==1 || pDrvInfo->PartAggr == 1)
6179 RT_TRACE(COMP_RXDESC, "pDrvInfo->FirstAGGR = %d, pDrvInfo->PartAggr = %d\n",
6180 pDrvInfo->FirstAGGR, pDrvInfo->PartAggr);
6181 skb_trim(skb, skb->len - 4/*sCrcLng*/);
6182 /* rx packets statistics */
6183 ieee80211_hdr = (struct ieee80211_hdr_1addr *)skb->data;
6184 unicast_packet = false;
6186 if(is_broadcast_ether_addr(ieee80211_hdr->addr1)) {
6188 }else if(is_multicast_ether_addr(ieee80211_hdr->addr1)){
6191 /* unicast packet */
6192 unicast_packet = true;
6195 stats.packetlength = stats.Length-4;
6196 stats.fraglength = stats.packetlength;
6197 stats.fragoffset = 0;
6198 stats.ntotalfrag = 1;
6200 if(!ieee80211_rx(priv->ieee80211, skb, &stats)){
6201 dev_kfree_skb_any(skb);
6204 if(unicast_packet) {
6205 priv->stats.rxbytesunicast += skb->len;
6210 priv->rx_buf[priv->rx_idx] = skb;
6211 *((dma_addr_t *) skb->cb) = pci_map_single(priv->pdev, skb->tail, priv->rxbuffersize, PCI_DMA_FROMDEVICE);
6212 // *((dma_addr_t *) skb->cb) = pci_map_single(priv->pdev, skb_tail_pointer(skb), priv->rxbuffersize, PCI_DMA_FROMDEVICE);
6217 pdesc->BufferAddress = cpu_to_le32(*((dma_addr_t *)skb->cb));
6219 pdesc->Length = priv->rxbuffersize;
6220 if (priv->rx_idx == priv->rxringcount-1)
6222 priv->rx_idx = (priv->rx_idx + 1) % priv->rxringcount;
6227 void rtl8192_irq_rx_tasklet(struct r8192_priv *priv)
6229 rtl8192_rx(priv->ieee80211->dev);
6231 write_nic_dword(priv->ieee80211->dev, INTA_MASK,read_nic_dword(priv->ieee80211->dev, INTA_MASK) | IMR_RDU);
6234 static const struct net_device_ops rtl8192_netdev_ops = {
6235 .ndo_open = rtl8192_open,
6236 .ndo_stop = rtl8192_close,
6237 /* .ndo_get_stats = rtl8192_stats, */
6238 .ndo_tx_timeout = tx_timeout,
6239 .ndo_do_ioctl = rtl8192_ioctl,
6240 .ndo_set_multicast_list = r8192_set_multicast,
6241 .ndo_set_mac_address = r8192_set_mac_adr,
6242 .ndo_start_xmit = ieee80211_xmit,
6245 /****************************************************************************
6246 ---------------------------- PCI_STUFF---------------------------
6247 *****************************************************************************/
6249 static int __devinit rtl8192_pci_probe(struct pci_dev *pdev,
6250 const struct pci_device_id *id)
6252 unsigned long ioaddr = 0;
6253 struct net_device *dev = NULL;
6254 struct r8192_priv *priv= NULL;
6257 #ifdef CONFIG_RTL8192_IO_MAP
6258 unsigned long pio_start, pio_len, pio_flags;
6260 unsigned long pmem_start, pmem_len, pmem_flags;
6261 #endif //end #ifdef RTL_IO_MAP
6263 RT_TRACE(COMP_INIT,"Configuring chip resources");
6265 if( pci_enable_device (pdev) ){
6266 RT_TRACE(COMP_ERR,"Failed to enable PCI device");
6270 pci_set_master(pdev);
6271 //pci_set_wmi(pdev);
6272 pci_set_dma_mask(pdev, 0xffffff00ULL);
6273 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
6274 pci_set_consistent_dma_mask(pdev,0xffffff00ULL);
6276 dev = alloc_ieee80211(sizeof(struct r8192_priv));
6280 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
6281 SET_MODULE_OWNER(dev);
6284 pci_set_drvdata(pdev, dev);
6285 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
6286 SET_NETDEV_DEV(dev, &pdev->dev);
6288 priv = ieee80211_priv(dev);
6289 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
6290 priv->ieee80211 = netdev_priv(dev);
6292 priv->ieee80211 = (struct ieee80211_device *)dev->priv;
6295 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
6296 if((pdev->subsystem_vendor == PCI_VENDOR_ID_DLINK)&&(pdev->subsystem_device == 0x3304)){
6297 priv->ieee80211->bSupportRemoteWakeUp = 1;
6301 priv->ieee80211->bSupportRemoteWakeUp = 0;
6304 #ifdef CONFIG_RTL8192_IO_MAP
6306 pio_start = (unsigned long)pci_resource_start (pdev, 0);
6307 pio_len = (unsigned long)pci_resource_len (pdev, 0);
6308 pio_flags = (unsigned long)pci_resource_flags (pdev, 0);
6310 if (!(pio_flags & IORESOURCE_IO)) {
6311 RT_TRACE(COMP_ERR,"region #0 not a PIO resource, aborting");
6315 //DMESG("IO space @ 0x%08lx", pio_start );
6316 if( ! request_region( pio_start, pio_len, RTL819xE_MODULE_NAME ) ){
6317 RT_TRACE(COMP_ERR,"request_region failed!");
6322 dev->base_addr = ioaddr; // device I/O address
6326 pmem_start = pci_resource_start(pdev, 1);
6327 pmem_len = pci_resource_len(pdev, 1);
6328 pmem_flags = pci_resource_flags (pdev, 1);
6330 if (!(pmem_flags & IORESOURCE_MEM)) {
6331 RT_TRACE(COMP_ERR,"region #1 not a MMIO resource, aborting");
6335 //DMESG("Memory mapped space @ 0x%08lx ", pmem_start);
6336 if( ! request_mem_region(pmem_start, pmem_len, RTL819xE_MODULE_NAME)) {
6337 RT_TRACE(COMP_ERR,"request_mem_region failed!");
6342 ioaddr = (unsigned long)ioremap_nocache( pmem_start, pmem_len);
6343 if( ioaddr == (unsigned long)NULL ){
6344 RT_TRACE(COMP_ERR,"ioremap failed!");
6345 // release_mem_region( pmem_start, pmem_len );
6349 dev->mem_start = ioaddr; // shared mem start
6350 dev->mem_end = ioaddr + pci_resource_len(pdev, 0); // shared mem end
6352 #endif //end #ifdef RTL_IO_MAP
6354 /* We disable the RETRY_TIMEOUT register (0x41) to keep
6355 * PCI Tx retries from interfering with C3 CPU state */
6356 pci_write_config_byte(pdev, 0x41, 0x00);
6359 pci_read_config_byte(pdev, 0x05, &unit);
6360 pci_write_config_byte(pdev, 0x05, unit & (~0x04));
6362 dev->irq = pdev->irq;
6365 dev->netdev_ops = &rtl8192_netdev_ops;
6367 dev->open = rtl8192_open;
6368 dev->stop = rtl8192_close;
6369 //dev->hard_start_xmit = rtl8192_8023_hard_start_xmit;
6370 dev->tx_timeout = tx_timeout;
6371 //dev->wireless_handlers = &r8192_wx_handlers_def;
6372 dev->do_ioctl = rtl8192_ioctl;
6373 dev->set_multicast_list = r8192_set_multicast;
6374 dev->set_mac_address = r8192_set_mac_adr;
6377 //DMESG("Oops: i'm coming\n");
6378 #if WIRELESS_EXT >= 12
6379 #if WIRELESS_EXT < 17
6380 dev->get_wireless_stats = r8192_get_wireless_stats;
6382 dev->wireless_handlers = (struct iw_handler_def *) &r8192_wx_handlers_def;
6384 //dev->get_wireless_stats = r8192_get_wireless_stats;
6385 dev->type=ARPHRD_ETHER;
6387 dev->watchdog_timeo = HZ*3; //modified by john, 0805
6389 if (dev_alloc_name(dev, ifname) < 0){
6390 RT_TRACE(COMP_INIT, "Oops: devname already taken! Trying wlan%%d...\n");
6392 dev_alloc_name(dev, ifname);
6395 RT_TRACE(COMP_INIT, "Driver probe completed1\n");
6396 if(rtl8192_init(dev)!=0){
6397 RT_TRACE(COMP_ERR, "Initialization failed");
6401 netif_carrier_off(dev);
6402 netif_stop_queue(dev);
6404 register_netdev(dev);
6405 RT_TRACE(COMP_INIT, "dev name=======> %s\n",dev->name);
6406 rtl8192_proc_init_one(dev);
6409 RT_TRACE(COMP_INIT, "Driver probe completed\n");
6410 //#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
6418 #ifdef CONFIG_RTL8180_IO_MAP
6420 if( dev->base_addr != 0 ){
6422 release_region(dev->base_addr,
6423 pci_resource_len(pdev, 0) );
6426 if( dev->mem_start != (unsigned long)NULL ){
6427 iounmap( (void *)dev->mem_start );
6428 release_mem_region( pci_resource_start(pdev, 1),
6429 pci_resource_len(pdev, 1) );
6431 #endif //end #ifdef RTL_IO_MAP
6437 free_irq(dev->irq, dev);
6440 free_ieee80211(dev);
6443 pci_disable_device(pdev);
6445 DMESG("wlan driver load failed\n");
6446 pci_set_drvdata(pdev, NULL);
6451 /* detach all the work and timer structure declared or inititialized
6452 * in r8192_init function.
6454 void rtl8192_cancel_deferred_work(struct r8192_priv* priv)
6456 /* call cancel_work_sync instead of cancel_delayed_work if and only if Linux_version_code
6457 * is or is newer than 2.6.20 and work structure is defined to be struct work_struct.
6458 * Otherwise call cancel_delayed_work is enough.
6459 * FIXME (2.6.20 shoud 2.6.22, work_struct shoud not cancel)
6461 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
6462 cancel_delayed_work(&priv->watch_dog_wq);
6463 cancel_delayed_work(&priv->update_beacon_wq);
6464 cancel_delayed_work(&priv->ieee80211->hw_wakeup_wq);
6465 cancel_delayed_work(&priv->ieee80211->hw_sleep_wq);
6467 cancel_delayed_work(&priv->gpio_change_rf_wq);
6470 #if LINUX_VERSION_CODE >=KERNEL_VERSION(2,6,22)
6471 cancel_work_sync(&priv->reset_wq);
6472 cancel_work_sync(&priv->qos_activate);
6473 //cancel_work_sync(&priv->SetBWModeWorkItem);
6474 //cancel_work_sync(&priv->SwChnlWorkItem);
6476 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
6477 cancel_delayed_work(&priv->reset_wq);
6478 cancel_delayed_work(&priv->qos_activate);
6479 //cancel_delayed_work(&priv->SetBWModeWorkItem);
6480 //cancel_delayed_work(&priv->SwChnlWorkItem);
6487 static void __devexit rtl8192_pci_disconnect(struct pci_dev *pdev)
6489 struct net_device *dev = pci_get_drvdata(pdev);
6490 struct r8192_priv *priv ;
6494 unregister_netdev(dev);
6496 priv=ieee80211_priv(dev);
6498 rtl8192_proc_remove_one(dev);
6501 if (priv->pFirmware)
6503 vfree(priv->pFirmware);
6504 priv->pFirmware = NULL;
6506 // priv->rf_close(dev);
6507 // rtl8192_usb_deleteendpoints(dev);
6508 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
6509 destroy_workqueue(priv->priv_wq);
6511 /* redundant with rtl8192_down */
6512 // rtl8192_irq_disable(dev);
6513 // rtl8192_reset(dev);
6517 /* free tx/rx rings */
6518 rtl8192_free_rx_ring(dev);
6519 for (i = 0; i < MAX_TX_QUEUE_COUNT; i++) {
6520 rtl8192_free_tx_ring(dev, i);
6525 printk("Freeing irq %d\n",dev->irq);
6526 free_irq(dev->irq, dev);
6533 // free_beacon_desc_ring(dev,priv->txbeaconcount);
6535 #ifdef CONFIG_RTL8180_IO_MAP
6537 if( dev->base_addr != 0 ){
6539 release_region(dev->base_addr,
6540 pci_resource_len(pdev, 0) );
6543 if( dev->mem_start != (unsigned long)NULL ){
6544 iounmap( (void *)dev->mem_start );
6545 release_mem_region( pci_resource_start(pdev, 1),
6546 pci_resource_len(pdev, 1) );
6548 #endif /*end #ifdef RTL_IO_MAP*/
6549 free_ieee80211(dev);
6553 pci_disable_device(pdev);
6554 RT_TRACE(COMP_DOWN, "wlan driver removed\n");
6557 extern int ieee80211_init(void);
6558 extern void ieee80211_exit(void);
6560 static int __init rtl8192_pci_module_init(void)
6564 retval = ieee80211_init();
6568 printk(KERN_INFO "\nLinux kernel driver for RTL8192 based WLAN cards\n");
6569 printk(KERN_INFO "Copyright (c) 2007-2008, Realsil Wlan\n");
6570 RT_TRACE(COMP_INIT, "Initializing module");
6571 RT_TRACE(COMP_INIT, "Wireless extensions version %d", WIRELESS_EXT);
6572 rtl8192_proc_module_init();
6573 #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22))
6574 if(0!=pci_module_init(&rtl8192_pci_driver))
6576 if(0!=pci_register_driver(&rtl8192_pci_driver))
6579 DMESG("No device found");
6580 /*pci_unregister_driver (&rtl8192_pci_driver);*/
6587 static void __exit rtl8192_pci_module_exit(void)
6589 pci_unregister_driver(&rtl8192_pci_driver);
6591 RT_TRACE(COMP_DOWN, "Exiting");
6592 rtl8192_proc_module_remove();
6596 //warning message WB
6597 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18)
6598 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
6599 void rtl8192_interrupt(int irq, void *netdev, struct pt_regs *regs)
6601 irqreturn_t rtl8192_interrupt(int irq, void *netdev, struct pt_regs *regs)
6604 irqreturn_t rtl8192_interrupt(int irq, void *netdev)
6607 struct net_device *dev = (struct net_device *) netdev;
6608 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
6609 unsigned long flags;
6611 /* We should return IRQ_NONE, but for now let me keep this */
6612 if(priv->irq_enabled == 0){
6613 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
6620 spin_lock_irqsave(&priv->irq_th_lock,flags);
6624 inta = read_nic_dword(dev, ISR);// & priv->IntrMask;
6625 write_nic_dword(dev,ISR,inta); // reset int situation
6627 priv->stats.shints++;
6628 //DMESG("Enter interrupt, ISR value = 0x%08x", inta);
6630 spin_unlock_irqrestore(&priv->irq_th_lock,flags);
6631 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
6637 most probably we can safely return IRQ_NONE,
6638 but for now is better to avoid problems
6644 spin_unlock_irqrestore(&priv->irq_th_lock,flags);
6645 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
6654 DMESG("NIC irq %x",inta);
6656 //priv->irqpending = inta;
6659 if(!netif_running(dev)) {
6660 spin_unlock_irqrestore(&priv->irq_th_lock,flags);
6661 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
6668 if(inta & IMR_TIMEOUT0){
6669 // write_nic_dword(dev, TimerInt, 0);
6670 //DMESG("=================>waking up");
6671 // rtl8180_hw_wakeup(dev);
6674 if(inta & IMR_TBDOK){
6675 RT_TRACE(COMP_INTR, "beacon ok interrupt!\n");
6676 rtl8192_tx_isr(dev, BEACON_QUEUE);
6677 priv->stats.txbeaconokint++;
6680 if(inta & IMR_TBDER){
6681 RT_TRACE(COMP_INTR, "beacon ok interrupt!\n");
6682 rtl8192_tx_isr(dev, BEACON_QUEUE);
6683 priv->stats.txbeaconerr++;
6686 if(inta & IMR_MGNTDOK ) {
6687 RT_TRACE(COMP_INTR, "Manage ok interrupt!\n");
6688 priv->stats.txmanageokint++;
6689 rtl8192_tx_isr(dev,MGNT_QUEUE);
6693 if(inta & IMR_COMDOK)
6695 priv->stats.txcmdpktokint++;
6696 rtl8192_tx_isr(dev,TXCMD_QUEUE);
6701 DMESG("Frame arrived !");
6703 priv->stats.rxint++;
6704 tasklet_schedule(&priv->irq_rx_tasklet);
6707 if(inta & IMR_BcnInt) {
6708 RT_TRACE(COMP_INTR, "prepare beacon for interrupt!\n");
6709 tasklet_schedule(&priv->irq_prepare_beacon_tasklet);
6713 RT_TRACE(COMP_INTR, "rx descriptor unavailable!\n");
6714 priv->stats.rxrdu++;
6715 /* reset int situation */
6716 write_nic_dword(dev,INTA_MASK,read_nic_dword(dev, INTA_MASK) & ~IMR_RDU);
6717 tasklet_schedule(&priv->irq_rx_tasklet);
6720 if(inta & IMR_RXFOVW){
6721 RT_TRACE(COMP_INTR, "rx overflow !\n");
6722 priv->stats.rxoverflow++;
6723 tasklet_schedule(&priv->irq_rx_tasklet);
6726 if(inta & IMR_TXFOVW) priv->stats.txoverflow++;
6728 if(inta & IMR_BKDOK){
6729 RT_TRACE(COMP_INTR, "BK Tx OK interrupt!\n");
6730 priv->stats.txbkokint++;
6731 priv->ieee80211->LinkDetectInfo.NumTxOkInPeriod++;
6732 rtl8192_tx_isr(dev,BK_QUEUE);
6733 rtl8192_try_wake_queue(dev, BK_QUEUE);
6736 if(inta & IMR_BEDOK){
6737 RT_TRACE(COMP_INTR, "BE TX OK interrupt!\n");
6738 priv->stats.txbeokint++;
6739 priv->ieee80211->LinkDetectInfo.NumTxOkInPeriod++;
6740 rtl8192_tx_isr(dev,BE_QUEUE);
6741 rtl8192_try_wake_queue(dev, BE_QUEUE);
6744 if(inta & IMR_VIDOK){
6745 RT_TRACE(COMP_INTR, "VI TX OK interrupt!\n");
6746 priv->stats.txviokint++;
6747 priv->ieee80211->LinkDetectInfo.NumTxOkInPeriod++;
6748 rtl8192_tx_isr(dev,VI_QUEUE);
6749 rtl8192_try_wake_queue(dev, VI_QUEUE);
6752 if(inta & IMR_VODOK){
6753 priv->stats.txvookint++;
6754 priv->ieee80211->LinkDetectInfo.NumTxOkInPeriod++;
6755 rtl8192_tx_isr(dev,VO_QUEUE);
6756 rtl8192_try_wake_queue(dev, VO_QUEUE);
6759 force_pci_posting(dev);
6760 spin_unlock_irqrestore(&priv->irq_th_lock,flags);
6762 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
6769 void rtl8192_try_wake_queue(struct net_device *dev, int pri)
6772 unsigned long flags;
6774 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
6776 spin_lock_irqsave(&priv->tx_lock,flags);
6777 enough_desc = check_nic_enough_desc(dev,pri);
6778 spin_unlock_irqrestore(&priv->tx_lock,flags);
6781 ieee80211_wake_queue(priv->ieee80211);
6786 void EnableHWSecurityConfig8192(struct net_device *dev)
6788 u8 SECR_value = 0x0;
6789 // struct ieee80211_device* ieee1 = container_of(&dev, struct ieee80211_device, dev);
6790 //printk("==>ieee1:%p, dev:%p\n", ieee1, dev);
6791 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
6792 struct ieee80211_device* ieee = priv->ieee80211;
6793 //printk("==>ieee:%p, dev:%p\n", ieee, dev);
6794 SECR_value = SCR_TxEncEnable | SCR_RxDecEnable;
6796 if (((KEY_TYPE_WEP40 == ieee->pairwise_key_type) || (KEY_TYPE_WEP104 == ieee->pairwise_key_type)) && (priv->ieee80211->auth_mode != 2))
6798 SECR_value |= SCR_RxUseDK;
6799 SECR_value |= SCR_TxUseDK;
6801 else if ((ieee->iw_mode == IW_MODE_ADHOC) && (ieee->pairwise_key_type & (KEY_TYPE_CCMP | KEY_TYPE_TKIP)))
6803 SECR_value |= SCR_RxUseDK;
6804 SECR_value |= SCR_TxUseDK;
6809 //add HWSec active enable here.
6810 //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
6811 ieee->hwsec_active = 1;
6813 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
6815 ieee->hwsec_active = 0;
6816 SECR_value &= ~SCR_RxDecEnable;
6819 RT_TRACE(COMP_SEC,"%s:, hwsec:%d, pairwise_key:%d, SECR_value:%x\n", __FUNCTION__, \
6820 ieee->hwsec_active, ieee->pairwise_key_type, SECR_value);
6822 write_nic_byte(dev, SECR, SECR_value);//SECR_value | SCR_UseDK );
6826 #define TOTAL_CAM_ENTRY 32
6827 //#define CAM_CONTENT_COUNT 8
6828 void setKey( struct net_device *dev,
6836 u32 TargetCommand = 0;
6837 u32 TargetContent = 0;
6841 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
6842 RT_RF_POWER_STATE rtState;
6843 rtState = priv->ieee80211->eRFPowerState;
6844 if(priv->ieee80211->PowerSaveControl.bInactivePs){
6845 if(rtState == eRfOff){
6846 if(priv->ieee80211->RfOffReason > RF_CHANGE_BY_IPS)
6848 RT_TRACE(COMP_ERR, "%s(): RF is OFF.\n",__FUNCTION__);
6857 priv->ieee80211->is_set_key = true;
6859 if (EntryNo >= TOTAL_CAM_ENTRY)
6860 RT_TRACE(COMP_ERR, "cam entry exceeds in setKey()\n");
6862 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));
6865 usConfig |= BIT15 | (KeyType<<2);
6867 usConfig |= BIT15 | (KeyType<<2) | KeyIndex;
6868 // usConfig |= BIT15 | (KeyType<<2) | (DefaultKey<<5) | KeyIndex;
6871 for(i=0 ; i<CAM_CONTENT_COUNT; i++){
6872 TargetCommand = i+CAM_CONTENT_COUNT*EntryNo;
6873 TargetCommand |= BIT31|BIT16;
6875 if(i==0){//MAC|Config
6876 TargetContent = (u32)(*(MacAddr+0)) << 16|
6877 (u32)(*(MacAddr+1)) << 24|
6880 write_nic_dword(dev, WCAMI, TargetContent);
6881 write_nic_dword(dev, RWCAM, TargetCommand);
6882 // printk("setkey cam =%8x\n", read_cam(dev, i+6*EntryNo));
6885 TargetContent = (u32)(*(MacAddr+2)) |
6886 (u32)(*(MacAddr+3)) << 8|
6887 (u32)(*(MacAddr+4)) << 16|
6888 (u32)(*(MacAddr+5)) << 24;
6889 write_nic_dword(dev, WCAMI, TargetContent);
6890 write_nic_dword(dev, RWCAM, TargetCommand);
6892 else { //Key Material
6893 if(KeyContent != NULL)
6895 write_nic_dword(dev, WCAMI, (u32)(*(KeyContent+i-2)) );
6896 write_nic_dword(dev, RWCAM, TargetCommand);
6900 RT_TRACE(COMP_SEC,"=========>after set key, usconfig:%x\n", usConfig);
6902 // This function seems not ready! WB
6903 void CamPrintDbgReg(struct net_device* dev)
6905 unsigned long rvalue;
6906 unsigned char ucValue;
6907 write_nic_dword(dev, DCAM, 0x80000000);
6909 rvalue = read_nic_dword(dev, DCAM); //delay_ms(40);
6910 RT_TRACE(COMP_SEC, " TX CAM=%8lX ",rvalue);
6911 if((rvalue & 0x40000000) != 0x4000000)
6912 RT_TRACE(COMP_SEC, "-->TX Key Not Found ");
6914 write_nic_dword(dev, DCAM, 0x00000000); //delay_ms(40);
6915 rvalue = read_nic_dword(dev, DCAM); //delay_ms(40);
6916 RT_TRACE(COMP_SEC, "RX CAM=%8lX ",rvalue);
6917 if((rvalue & 0x40000000) != 0x4000000)
6918 RT_TRACE(COMP_SEC, "-->CAM Key Not Found ");
6919 ucValue = read_nic_byte(dev, SECR);
6920 RT_TRACE(COMP_SEC, "WPA_Config=%x \n",ucValue);
6924 /***************************************************************************
6925 ------------------- module init / exit stubs ----------------
6926 ****************************************************************************/
6927 module_init(rtl8192_pci_module_init);
6928 module_exit(rtl8192_pci_module_exit);