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 <linux/vmalloc.h>
50 #include <linux/slab.h>
51 #include <asm/uaccess.h>
52 #include "r8192E_hw.h"
54 #include "r8190_rtl8256.h" /* RTL8225 Radio frontend */
55 #include "r8180_93cx6.h" /* Card EEPROM */
56 #include "r8192E_wx.h"
57 #include "r819xE_phy.h" //added by WB 4.30.2008
58 #include "r819xE_phyreg.h"
59 #include "r819xE_cmdpkt.h"
60 #include "r8192E_dm.h"
67 #include "ieee80211/dot11d.h"
70 //set here to open your trace code. //WB
71 u32 rt_global_debug_component =
89 // COMP_POWER_TRACKING |
91 COMP_ERR ; //always open err flags on
93 static const struct pci_device_id rtl8192_pci_id_tbl[] __devinitdata = {
97 { PCI_DEVICE(0x10ec, 0x8190) },
99 { PCI_DEVICE(0x07aa, 0x0045) },
100 { PCI_DEVICE(0x07aa, 0x0046) },
103 { PCI_DEVICE(0x10ec, 0x8192) },
106 { PCI_DEVICE(0x07aa, 0x0044) },
107 { PCI_DEVICE(0x07aa, 0x0047) },
112 static char ifname[IFNAMSIZ] = "wlan%d";
113 static int hwwep = 1; //default use hw. set 0 to use software security
114 static int channels = 0x3fff;
116 MODULE_LICENSE("GPL");
117 MODULE_VERSION("V 1.1");
118 MODULE_DEVICE_TABLE(pci, rtl8192_pci_id_tbl);
119 //MODULE_AUTHOR("Andrea Merello <andreamrl@tiscali.it>");
120 MODULE_DESCRIPTION("Linux driver for Realtek RTL819x WiFi cards");
123 module_param_string(ifname, ifname, sizeof(ifname), S_IRUGO|S_IWUSR);
124 module_param(hwwep,int, S_IRUGO|S_IWUSR);
125 module_param(channels,int, S_IRUGO|S_IWUSR);
127 MODULE_PARM_DESC(ifname," Net interface name, wlan%d=default");
128 MODULE_PARM_DESC(hwwep," Try to use hardware WEP support. Still broken and not available on all cards");
129 MODULE_PARM_DESC(channels," Channel bitmask for specific locales. NYI");
131 static int __devinit rtl8192_pci_probe(struct pci_dev *pdev,
132 const struct pci_device_id *id);
133 static void __devexit rtl8192_pci_disconnect(struct pci_dev *pdev);
135 static struct pci_driver rtl8192_pci_driver = {
136 .name = RTL819xE_MODULE_NAME, /* Driver name */
137 .id_table = rtl8192_pci_id_tbl, /* PCI_ID table */
138 .probe = rtl8192_pci_probe, /* probe fn */
139 .remove = __devexit_p(rtl8192_pci_disconnect), /* remove fn */
141 .suspend = rtl8192E_suspend, /* PM suspend fn */
142 .resume = rtl8192E_resume, /* PM resume fn */
144 .suspend = NULL, /* PM suspend fn */
145 .resume = NULL, /* PM resume fn */
149 static void rtl8192_start_beacon(struct net_device *dev);
150 static void rtl8192_stop_beacon(struct net_device *dev);
151 static void rtl819x_watchdog_wqcallback(struct work_struct *work);
152 static void rtl8192_irq_rx_tasklet(struct r8192_priv *priv);
153 static void rtl8192_irq_tx_tasklet(struct r8192_priv *priv);
154 static void rtl8192_prepare_beacon(struct r8192_priv *priv);
155 static irqreturn_t rtl8192_interrupt(int irq, void *netdev);
156 static void rtl8192_try_wake_queue(struct net_device *dev, int pri);
157 static void rtl819xE_tx_cmd(struct net_device *dev, struct sk_buff *skb);
158 static void rtl8192_update_ratr_table(struct net_device* dev);
159 static void rtl8192_restart(struct work_struct *work);
160 static void watch_dog_timer_callback(unsigned long data);
161 static int _rtl8192_up(struct net_device *dev);
162 static void rtl8192_cancel_deferred_work(struct r8192_priv* priv);
166 typedef struct _CHANNEL_LIST
170 }CHANNEL_LIST, *PCHANNEL_LIST;
172 static const CHANNEL_LIST ChannelPlan[] = {
173 {{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
174 {{1,2,3,4,5,6,7,8,9,10,11},11}, //IC
175 {{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48,52,56,60,64},21}, //ETSI
176 {{1,2,3,4,5,6,7,8,9,10,11,12,13},13}, //Spain. Change to ETSI.
177 {{1,2,3,4,5,6,7,8,9,10,11,12,13},13}, //France. Change to ETSI.
178 {{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
179 {{1,2,3,4,5,6,7,8,9,10,11,12,13,14,36,40,44,48,52,56,60,64},22},//MKK1
180 {{1,2,3,4,5,6,7,8,9,10,11,12,13},13}, //Israel.
181 {{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
182 {{1,2,3,4,5,6,7,8,9,10,11,12,13,14,36,40,44,48,52,56,60,64}, 22}, //MIC
183 {{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
186 static void rtl819x_set_channel_map(u8 channel_plan, struct r8192_priv* priv)
188 int i, max_chan=-1, min_chan=-1;
189 struct ieee80211_device* ieee = priv->ieee80211;
190 switch (channel_plan)
192 case COUNTRY_CODE_FCC:
193 case COUNTRY_CODE_IC:
194 case COUNTRY_CODE_ETSI:
195 case COUNTRY_CODE_SPAIN:
196 case COUNTRY_CODE_FRANCE:
197 case COUNTRY_CODE_MKK:
198 case COUNTRY_CODE_MKK1:
199 case COUNTRY_CODE_ISRAEL:
200 case COUNTRY_CODE_TELEC:
201 case COUNTRY_CODE_MIC:
204 ieee->bGlobalDomain = false;
205 //acturally 8225 & 8256 rf chip only support B,G,24N mode
206 if ((priv->rf_chip == RF_8225) || (priv->rf_chip == RF_8256))
213 RT_TRACE(COMP_ERR, "unknown rf chip, can't set channel map in function:%s()\n", __FUNCTION__);
215 if (ChannelPlan[channel_plan].Len != 0){
216 // Clear old channel map
217 memset(GET_DOT11D_INFO(ieee)->channel_map, 0, sizeof(GET_DOT11D_INFO(ieee)->channel_map));
218 // Set new channel map
219 for (i=0;i<ChannelPlan[channel_plan].Len;i++)
221 if (ChannelPlan[channel_plan].Channel[i] < min_chan || ChannelPlan[channel_plan].Channel[i] > max_chan)
223 GET_DOT11D_INFO(ieee)->channel_map[ChannelPlan[channel_plan].Channel[i]] = 1;
228 case COUNTRY_CODE_GLOBAL_DOMAIN:
230 GET_DOT11D_INFO(ieee)->bEnabled = 0; //this flag enabled to follow 11d country IE setting, otherwise, it shall follow global domain setting
232 ieee->bGlobalDomain = true;
242 #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 )
243 /* 2007/07/25 MH Defien temp tx fw info. */
244 static TX_FWINFO_T Tmp_TxFwInfo;
247 #define rx_hal_is_cck_rate(_pdrvinfo)\
248 (_pdrvinfo->RxRate == DESC90_RATE1M ||\
249 _pdrvinfo->RxRate == DESC90_RATE2M ||\
250 _pdrvinfo->RxRate == DESC90_RATE5_5M ||\
251 _pdrvinfo->RxRate == DESC90_RATE11M) &&\
255 void CamResetAllEntry(struct net_device *dev)
261 ulcommand |= BIT31|BIT30;
262 write_nic_dword(dev, RWCAM, ulcommand);
264 for(ucIndex=0;ucIndex<TOTAL_CAM_ENTRY;ucIndex++)
265 CAM_mark_invalid(dev, ucIndex);
266 for(ucIndex=0;ucIndex<TOTAL_CAM_ENTRY;ucIndex++)
267 CAM_empty_entry(dev, ucIndex);
272 void write_cam(struct net_device *dev, u8 addr, u32 data)
274 write_nic_dword(dev, WCAMI, data);
275 write_nic_dword(dev, RWCAM, BIT31|BIT16|(addr&0xff) );
277 u32 read_cam(struct net_device *dev, u8 addr)
279 write_nic_dword(dev, RWCAM, 0x80000000|(addr&0xff) );
280 return read_nic_dword(dev, 0xa8);
283 #ifdef CONFIG_RTL8180_IO_MAP
285 u8 read_nic_byte(struct net_device *dev, int x)
287 return 0xff&inb(dev->base_addr +x);
290 u32 read_nic_dword(struct net_device *dev, int x)
292 return inl(dev->base_addr +x);
295 u16 read_nic_word(struct net_device *dev, int x)
297 return inw(dev->base_addr +x);
300 void write_nic_byte(struct net_device *dev, int x,u8 y)
302 outb(y&0xff,dev->base_addr +x);
305 void write_nic_word(struct net_device *dev, int x,u16 y)
307 outw(y,dev->base_addr +x);
310 void write_nic_dword(struct net_device *dev, int x,u32 y)
312 outl(y,dev->base_addr +x);
315 #else /* RTL_IO_MAP */
317 u8 read_nic_byte(struct net_device *dev, int x)
319 return 0xff&readb((u8*)dev->mem_start +x);
322 u32 read_nic_dword(struct net_device *dev, int x)
324 return readl((u8*)dev->mem_start +x);
327 u16 read_nic_word(struct net_device *dev, int x)
329 return readw((u8*)dev->mem_start +x);
332 void write_nic_byte(struct net_device *dev, int x,u8 y)
334 writeb(y,(u8*)dev->mem_start +x);
338 void write_nic_dword(struct net_device *dev, int x,u32 y)
340 writel(y,(u8*)dev->mem_start +x);
344 void write_nic_word(struct net_device *dev, int x,u16 y)
346 writew(y,(u8*)dev->mem_start +x);
350 #endif /* RTL_IO_MAP */
352 u8 rtl8192e_ap_sec_type(struct ieee80211_device *ieee)
354 //struct r8192_priv* priv = ieee80211_priv(dev);
355 //struct ieee80211_device *ieee = priv->ieee80211;
357 static const u8 ccmp_ie[4] = {0x00,0x50,0xf2,0x04};
358 static const u8 ccmp_rsn_ie[4] = {0x00, 0x0f, 0xac, 0x04};
359 int wpa_ie_len= ieee->wpa_ie_len;
360 struct ieee80211_crypt_data* crypt;
363 crypt = ieee->crypt[ieee->tx_keyidx];
365 encrypt = (ieee->current_network.capability & WLAN_CAPABILITY_PRIVACY) ||
366 (ieee->host_encrypt && crypt && crypt->ops &&
367 (0 == strcmp(crypt->ops->name,"WEP")));
370 if(encrypt && (wpa_ie_len == 0)) {
371 // wep encryption, no N mode setting */
373 } else if((wpa_ie_len != 0)) {
374 // parse pairwise key type */
375 if (((ieee->wpa_ie[0] == 0xdd) && (!memcmp(&(ieee->wpa_ie[14]),ccmp_ie,4))) ||
376 ((ieee->wpa_ie[0] == 0x30) && (!memcmp(&ieee->wpa_ie[10],ccmp_rsn_ie, 4))))
386 rtl8192e_SetHwReg(struct net_device *dev,u8 variable,u8* val)
388 struct r8192_priv* priv = ieee80211_priv(dev);
394 write_nic_dword(dev, BSSIDR, ((u32*)(val))[0]);
395 write_nic_word(dev, BSSIDR+2, ((u16*)(val+2))[0]);
398 case HW_VAR_MEDIA_STATUS:
400 RT_OP_MODE OpMode = *((RT_OP_MODE *)(val));
401 //LED_CTL_MODE LedAction = LED_CTL_NO_LINK;
402 u8 btMsr = read_nic_byte(dev, MSR);
408 case RT_OP_MODE_INFRASTRUCTURE:
410 //LedAction = LED_CTL_LINK;
413 case RT_OP_MODE_IBSS:
415 // led link set separate
420 //LedAction = LED_CTL_LINK;
428 write_nic_byte(dev, MSR, btMsr);
430 //priv->ieee80211->LedControlHandler(dev, LedAction);
434 case HW_VAR_CECHK_BSSID:
438 Type = ((u8*)(val))[0];
439 //priv->ieee80211->GetHwRegHandler(dev, HW_VAR_RCR, (u8*)(&RegRCR));
440 RegRCR = read_nic_dword(dev,RCR);
441 priv->ReceiveConfig = RegRCR;
444 RegRCR |= (RCR_CBSSID);
445 else if (Type == false)
446 RegRCR &= (~RCR_CBSSID);
448 //priv->ieee80211->SetHwRegHandler( dev, HW_VAR_RCR, (u8*)(&RegRCR) );
449 write_nic_dword(dev, RCR,RegRCR);
450 priv->ReceiveConfig = RegRCR;
455 case HW_VAR_SLOT_TIME:
457 //PSTA_QOS pStaQos = Adapter->MgntInfo.pStaQos;
460 priv->slot_time = val[0];
461 write_nic_byte(dev, SLOT_TIME, val[0]);
466 case HW_VAR_ACK_PREAMBLE:
469 priv->short_preamble = (bool)(*(u8*)val );
470 regTmp = priv->basic_rate;
471 if (priv->short_preamble)
472 regTmp |= BRSR_AckShortPmb;
473 write_nic_dword(dev, RRSR, regTmp);
478 write_nic_dword(dev, CPU_GEN, ((u32*)(val))[0]);
487 static struct proc_dir_entry *rtl8192_proc = NULL;
489 static int proc_get_stats_ap(char *page, char **start,
490 off_t offset, int count,
491 int *eof, void *data)
493 struct net_device *dev = data;
494 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
495 struct ieee80211_device *ieee = priv->ieee80211;
496 struct ieee80211_network *target;
500 list_for_each_entry(target, &ieee->network_list, list) {
502 len += snprintf(page + len, count - len,
503 "%s ", target->ssid);
505 if(target->wpa_ie_len>0 || target->rsn_ie_len>0){
506 len += snprintf(page + len, count - len,
510 len += snprintf(page + len, count - len,
520 static int proc_get_registers(char *page, char **start,
521 off_t offset, int count,
522 int *eof, void *data)
524 struct net_device *dev = data;
525 // struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
532 /* This dump the current register page */
533 len += snprintf(page + len, count - len,
534 "\n####################page 0##################\n ");
538 //printk( "\nD: %2x> ", n);
539 len += snprintf(page + len, count - len,
542 for(i=0;i<16 && n<=max;i++,n++)
543 len += snprintf(page + len, count - len,
544 "%2x ",read_nic_byte(dev,n));
546 // printk("%2x ",read_nic_byte(dev,n));
548 len += snprintf(page + len, count - len,"\n");
549 len += snprintf(page + len, count - len,
550 "\n####################page 1##################\n ");
553 //printk( "\nD: %2x> ", n);
554 len += snprintf(page + len, count - len,
557 for(i=0;i<16 && n<=max;i++,n++)
558 len += snprintf(page + len, count - len,
559 "%2x ",read_nic_byte(dev,0x100|n));
561 // printk("%2x ",read_nic_byte(dev,n));
564 len += snprintf(page + len, count - len,
565 "\n####################page 3##################\n ");
568 //printk( "\nD: %2x> ", n);
569 len += snprintf(page + len, count - len,
572 for(i=0;i<16 && n<=max;i++,n++)
573 len += snprintf(page + len, count - len,
574 "%2x ",read_nic_byte(dev,0x300|n));
576 // printk("%2x ",read_nic_byte(dev,n));
587 static int proc_get_stats_tx(char *page, char **start,
588 off_t offset, int count,
589 int *eof, void *data)
591 struct net_device *dev = data;
592 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
596 len += snprintf(page + len, count - len,
597 "TX VI priority ok int: %lu\n"
598 // "TX VI priority error int: %lu\n"
599 "TX VO priority ok int: %lu\n"
600 // "TX VO priority error int: %lu\n"
601 "TX BE priority ok int: %lu\n"
602 // "TX BE priority error int: %lu\n"
603 "TX BK priority ok int: %lu\n"
604 // "TX BK priority error int: %lu\n"
605 "TX MANAGE priority ok int: %lu\n"
606 // "TX MANAGE priority error int: %lu\n"
607 "TX BEACON priority ok int: %lu\n"
608 "TX BEACON priority error int: %lu\n"
609 "TX CMDPKT priority ok int: %lu\n"
610 // "TX high priority ok int: %lu\n"
611 // "TX high priority failed error int: %lu\n"
612 // "TX queue resume: %lu\n"
613 "TX queue stopped?: %d\n"
614 "TX fifo overflow: %lu\n"
615 // "TX beacon: %lu\n"
616 // "TX VI queue: %d\n"
617 // "TX VO queue: %d\n"
618 // "TX BE queue: %d\n"
619 // "TX BK queue: %d\n"
620 // "TX HW queue: %d\n"
621 // "TX VI dropped: %lu\n"
622 // "TX VO dropped: %lu\n"
623 // "TX BE dropped: %lu\n"
624 // "TX BK dropped: %lu\n"
625 "TX total data packets %lu\n"
626 "TX total data bytes :%lu\n",
627 // "TX beacon aborted: %lu\n",
628 priv->stats.txviokint,
629 // priv->stats.txvierr,
630 priv->stats.txvookint,
631 // priv->stats.txvoerr,
632 priv->stats.txbeokint,
633 // priv->stats.txbeerr,
634 priv->stats.txbkokint,
635 // priv->stats.txbkerr,
636 priv->stats.txmanageokint,
637 // priv->stats.txmanageerr,
638 priv->stats.txbeaconokint,
639 priv->stats.txbeaconerr,
640 priv->stats.txcmdpktokint,
641 // priv->stats.txhpokint,
642 // priv->stats.txhperr,
643 // priv->stats.txresumed,
644 netif_queue_stopped(dev),
645 priv->stats.txoverflow,
646 // priv->stats.txbeacon,
647 // atomic_read(&(priv->tx_pending[VI_QUEUE])),
648 // atomic_read(&(priv->tx_pending[VO_QUEUE])),
649 // atomic_read(&(priv->tx_pending[BE_QUEUE])),
650 // atomic_read(&(priv->tx_pending[BK_QUEUE])),
651 // read_nic_byte(dev, TXFIFOCOUNT),
652 // priv->stats.txvidrop,
653 // priv->stats.txvodrop,
654 priv->ieee80211->stats.tx_packets,
655 priv->ieee80211->stats.tx_bytes
658 // priv->stats.txbedrop,
659 // priv->stats.txbkdrop
660 // priv->stats.txdatapkt
661 // priv->stats.txbeaconerr
670 static int proc_get_stats_rx(char *page, char **start,
671 off_t offset, int count,
672 int *eof, void *data)
674 struct net_device *dev = data;
675 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
679 len += snprintf(page + len, count - len,
682 "RX rx overflow error: %lu\n"
683 "RX invalid urb error: %lu\n",
686 priv->stats.rxoverflow,
687 priv->stats.rxurberr);
693 static void rtl8192_proc_module_init(void)
695 RT_TRACE(COMP_INIT, "Initializing proc filesystem");
696 rtl8192_proc=create_proc_entry(RTL819xE_MODULE_NAME, S_IFDIR, init_net.proc_net);
700 static void rtl8192_proc_module_remove(void)
702 remove_proc_entry(RTL819xE_MODULE_NAME, init_net.proc_net);
706 static void rtl8192_proc_remove_one(struct net_device *dev)
708 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
710 printk("dev name=======> %s\n",dev->name);
713 // remove_proc_entry("stats-hw", priv->dir_dev);
714 remove_proc_entry("stats-tx", priv->dir_dev);
715 remove_proc_entry("stats-rx", priv->dir_dev);
716 // remove_proc_entry("stats-ieee", priv->dir_dev);
717 remove_proc_entry("stats-ap", priv->dir_dev);
718 remove_proc_entry("registers", priv->dir_dev);
719 // remove_proc_entry("cck-registers",priv->dir_dev);
720 // remove_proc_entry("ofdm-registers",priv->dir_dev);
721 //remove_proc_entry(dev->name, rtl8192_proc);
722 remove_proc_entry("wlan0", rtl8192_proc);
723 priv->dir_dev = NULL;
728 static void rtl8192_proc_init_one(struct net_device *dev)
730 struct proc_dir_entry *e;
731 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
732 priv->dir_dev = create_proc_entry(dev->name,
733 S_IFDIR | S_IRUGO | S_IXUGO,
735 if (!priv->dir_dev) {
736 RT_TRACE(COMP_ERR, "Unable to initialize /proc/net/rtl8192/%s\n",
740 e = create_proc_read_entry("stats-rx", S_IFREG | S_IRUGO,
741 priv->dir_dev, proc_get_stats_rx, dev);
744 RT_TRACE(COMP_ERR,"Unable to initialize "
745 "/proc/net/rtl8192/%s/stats-rx\n",
750 e = create_proc_read_entry("stats-tx", S_IFREG | S_IRUGO,
751 priv->dir_dev, proc_get_stats_tx, dev);
754 RT_TRACE(COMP_ERR, "Unable to initialize "
755 "/proc/net/rtl8192/%s/stats-tx\n",
759 e = create_proc_read_entry("stats-ap", S_IFREG | S_IRUGO,
760 priv->dir_dev, proc_get_stats_ap, dev);
763 RT_TRACE(COMP_ERR, "Unable to initialize "
764 "/proc/net/rtl8192/%s/stats-ap\n",
768 e = create_proc_read_entry("registers", S_IFREG | S_IRUGO,
769 priv->dir_dev, proc_get_registers, dev);
771 RT_TRACE(COMP_ERR, "Unable to initialize "
772 "/proc/net/rtl8192/%s/registers\n",
777 short check_nic_enough_desc(struct net_device *dev, int prio)
779 struct r8192_priv *priv = ieee80211_priv(dev);
780 struct rtl8192_tx_ring *ring = &priv->tx_ring[prio];
782 /* for now we reserve two free descriptor as a safety boundary
783 * between the tail and the head
785 return (ring->entries - skb_queue_len(&ring->queue) >= 2);
788 static void tx_timeout(struct net_device *dev)
790 struct r8192_priv *priv = ieee80211_priv(dev);
791 //rtl8192_commit(dev);
793 schedule_work(&priv->reset_wq);
797 static void rtl8192_irq_enable(struct net_device *dev)
799 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
800 priv->irq_enabled = 1;
801 write_nic_dword(dev,INTA_MASK, priv->irq_mask);
804 void rtl8192_irq_disable(struct net_device *dev)
806 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
808 write_nic_dword(dev,INTA_MASK,0);
809 priv->irq_enabled = 0;
814 static void rtl8192_set_mode(struct net_device *dev,int mode)
817 ecmd=read_nic_byte(dev, EPROM_CMD);
818 ecmd=ecmd &~ EPROM_CMD_OPERATING_MODE_MASK;
819 ecmd=ecmd | (mode<<EPROM_CMD_OPERATING_MODE_SHIFT);
820 ecmd=ecmd &~ (1<<EPROM_CS_SHIFT);
821 ecmd=ecmd &~ (1<<EPROM_CK_SHIFT);
822 write_nic_byte(dev, EPROM_CMD, ecmd);
826 void rtl8192_update_msr(struct net_device *dev)
828 struct r8192_priv *priv = ieee80211_priv(dev);
831 msr = read_nic_byte(dev, MSR);
832 msr &= ~ MSR_LINK_MASK;
834 /* do not change in link_state != WLAN_LINK_ASSOCIATED.
835 * msr must be updated if the state is ASSOCIATING.
836 * this is intentional and make sense for ad-hoc and
837 * master (see the create BSS/IBSS func)
839 if (priv->ieee80211->state == IEEE80211_LINKED){
841 if (priv->ieee80211->iw_mode == IW_MODE_INFRA)
842 msr |= (MSR_LINK_MANAGED<<MSR_LINK_SHIFT);
843 else if (priv->ieee80211->iw_mode == IW_MODE_ADHOC)
844 msr |= (MSR_LINK_ADHOC<<MSR_LINK_SHIFT);
845 else if (priv->ieee80211->iw_mode == IW_MODE_MASTER)
846 msr |= (MSR_LINK_MASTER<<MSR_LINK_SHIFT);
849 msr |= (MSR_LINK_NONE<<MSR_LINK_SHIFT);
851 write_nic_byte(dev, MSR, msr);
854 void rtl8192_set_chan(struct net_device *dev,short ch)
856 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
857 RT_TRACE(COMP_RF, "=====>%s()====ch:%d\n", __FUNCTION__, ch);
860 if(priv->ieee80211->iw_mode == IW_MODE_ADHOC ||
861 priv->ieee80211->iw_mode == IW_MODE_MASTER){
863 priv->ieee80211->link_state = WLAN_LINK_ASSOCIATED;
864 priv->ieee80211->master_chan = ch;
865 rtl8192_update_beacon_ch(dev);
869 /* this hack should avoid frame TX during channel setting*/
872 // tx = read_nic_dword(dev,TX_CONF);
873 // tx &= ~TX_LOOPBACK_MASK;
877 // write_nic_dword(dev,TX_CONF, tx |( TX_LOOPBACK_MAC<<TX_LOOPBACK_SHIFT));
879 //need to implement rf set channel here WB
881 if (priv->rf_set_chan)
882 priv->rf_set_chan(dev,priv->chan);
884 // write_nic_dword(dev,TX_CONF,tx | (TX_LOOPBACK_NONE<<TX_LOOPBACK_SHIFT));
888 void rtl8192_rx_enable(struct net_device *dev)
890 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
891 write_nic_dword(dev, RDQDA,priv->rx_ring_dma);
894 /* the TX_DESC_BASE setting is according to the following queue index
903 * BEACON_QUEUE ===> 8
905 static const u32 TX_DESC_BASE[] = {BKQDA, BEQDA, VIQDA, VOQDA, HCCAQDA, CQDA, MQDA, HQDA, BQDA};
906 void rtl8192_tx_enable(struct net_device *dev)
908 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
910 for (i = 0; i < MAX_TX_QUEUE_COUNT; i++)
911 write_nic_dword(dev, TX_DESC_BASE[i], priv->tx_ring[i].dma);
913 ieee80211_reset_queue(priv->ieee80211);
917 static void rtl8192_free_rx_ring(struct net_device *dev)
919 struct r8192_priv *priv = ieee80211_priv(dev);
922 for (i = 0; i < priv->rxringcount; i++) {
923 struct sk_buff *skb = priv->rx_buf[i];
927 pci_unmap_single(priv->pdev,
928 *((dma_addr_t *)skb->cb),
929 priv->rxbuffersize, PCI_DMA_FROMDEVICE);
933 pci_free_consistent(priv->pdev, sizeof(*priv->rx_ring) * priv->rxringcount,
934 priv->rx_ring, priv->rx_ring_dma);
935 priv->rx_ring = NULL;
938 static void rtl8192_free_tx_ring(struct net_device *dev, unsigned int prio)
940 struct r8192_priv *priv = ieee80211_priv(dev);
941 struct rtl8192_tx_ring *ring = &priv->tx_ring[prio];
943 while (skb_queue_len(&ring->queue)) {
944 tx_desc_819x_pci *entry = &ring->desc[ring->idx];
945 struct sk_buff *skb = __skb_dequeue(&ring->queue);
947 pci_unmap_single(priv->pdev, le32_to_cpu(entry->TxBuffAddr),
948 skb->len, PCI_DMA_TODEVICE);
950 ring->idx = (ring->idx + 1) % ring->entries;
953 pci_free_consistent(priv->pdev, sizeof(*ring->desc)*ring->entries,
954 ring->desc, ring->dma);
958 void PHY_SetRtl8192eRfOff(struct net_device* dev)
960 //disable RF-Chip A/B
961 rtl8192_setBBreg(dev, rFPGA0_XA_RFInterfaceOE, BIT4, 0x0);
962 //analog to digital off, for power save
963 rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0x300, 0x0);
964 //digital to analog off, for power save
965 rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x18, 0x0);
967 rtl8192_setBBreg(dev, rOFDM0_TRxPathEnable, 0xf, 0x0);
969 rtl8192_setBBreg(dev, rOFDM1_TRxPathEnable, 0xf, 0x0);
970 //analog to digital part2 off, for power save
971 rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x60, 0x0);
972 rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x4, 0x0);
973 // Analog parameter!!Change bias and Lbus control.
974 write_nic_byte(dev, ANAPAR_FOR_8192PciE, 0x07);
978 void rtl8192_halt_adapter(struct net_device *dev, bool reset)
981 struct r8192_priv *priv = ieee80211_priv(dev);
987 OpMode = RT_OP_MODE_NO_LINK;
988 priv->ieee80211->SetHwRegHandler(dev, HW_VAR_MEDIA_STATUS, &OpMode);
991 if(!priv->ieee80211->bSupportRemoteWakeUp)
993 u1bTmp = 0x0; // disable tx/rx. In 8185 we write 0x10 (Reset bit), but here we make reference to WMAC and wirte 0x0. 2006.11.21 Emily
994 //priv->ieee80211->SetHwRegHandler(dev, HW_VAR_COMMAND, &u1bTmp ); // Using HW_VAR_COMMAND instead of writing CMDR directly. Rewrited by Annie, 2006-04-07.
995 write_nic_byte(dev, CMDR, u1bTmp);
998 cmd=read_nic_byte(dev,CMDR);
999 write_nic_byte(dev, CMDR, cmd &~ (CR_TE|CR_RE));
1006 //PlatformStallExecution(150000);
1010 priv->bHwRfOffAction = 2;
1014 // Call MgntActSet_RF_State instead to prevent RF config race condition.
1015 // By Bruce, 2008-01-17.
1017 if(!priv->ieee80211->bSupportRemoteWakeUp)
1019 //MgntActSet_RF_State(Adapter, eRfOff, RF_CHANGE_BY_INIT);
1020 //MgntActSet_RF_State(Adapter, eRfOff, Adapter->MgntInfo.RfOffReason);
1021 //if(Adapter->HardwareType == HARDWARE_TYPE_RTL8190P)
1023 PHY_SetRtl8192eRfOff(dev);
1025 // 2006.11.30. System reset bit
1026 //priv->ieee80211->GetHwRegHandler(dev, HW_VAR_CPU_RST, (u32*)(&ulRegRead) );
1027 ulRegRead = read_nic_dword(dev,CPU_GEN);
1028 ulRegRead|=CPU_GEN_SYSTEM_RESET;
1029 //priv->ieee80211->SetHwRegHandler(dev, HW_VAR_CPU_RST, &ulRegRead);
1030 write_nic_dword(dev,CPU_GEN, ulRegRead);
1034 //2008.06.03 for WOL
1035 write_nic_dword(dev, WFCRC0, 0xffffffff);
1036 write_nic_dword(dev, WFCRC1, 0xffffffff);
1037 write_nic_dword(dev, WFCRC2, 0xffffffff);
1039 //Write PMR register
1040 write_nic_byte(dev, PMR, 0x5);
1041 //Disable tx, enanble rx
1042 write_nic_byte(dev, MacBlkCtrl, 0xa);
1046 for(i = 0; i < MAX_QUEUE_SIZE; i++) {
1047 skb_queue_purge(&priv->ieee80211->skb_waitQ [i]);
1049 for(i = 0; i < MAX_QUEUE_SIZE; i++) {
1050 skb_queue_purge(&priv->ieee80211->skb_aggQ [i]);
1053 skb_queue_purge(&priv->skb_queue);
1056 static const u16 rtl_rate[] = {10,20,55,110,60,90,120,180,240,360,480,540};
1057 inline u16 rtl8192_rate2rate(short rate)
1059 if (rate >11) return 0;
1060 return rtl_rate[rate];
1063 static void rtl8192_data_hard_stop(struct net_device *dev)
1067 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1068 priv->dma_poll_mask |= (1<<TX_DMA_STOP_LOWPRIORITY_SHIFT);
1069 rtl8192_set_mode(dev,EPROM_CMD_CONFIG);
1070 write_nic_byte(dev,TX_DMA_POLLING,priv->dma_poll_mask);
1071 rtl8192_set_mode(dev,EPROM_CMD_NORMAL);
1076 static void rtl8192_data_hard_resume(struct net_device *dev)
1080 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1081 priv->dma_poll_mask &= ~(1<<TX_DMA_STOP_LOWPRIORITY_SHIFT);
1082 rtl8192_set_mode(dev,EPROM_CMD_CONFIG);
1083 write_nic_byte(dev,TX_DMA_POLLING,priv->dma_poll_mask);
1084 rtl8192_set_mode(dev,EPROM_CMD_NORMAL);
1089 * this function TX data frames when the ieee80211 stack requires this.
1090 * It checks also if we need to stop the ieee tx queue, eventually do it
1092 static void rtl8192_hard_data_xmit(struct sk_buff *skb, struct net_device *dev, int rate)
1094 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1096 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1097 u8 queue_index = tcb_desc->queue_index;
1099 /* shall not be referred by command packet */
1100 assert(queue_index != TXCMD_QUEUE);
1102 if (priv->bHwRadioOff || (!priv->up))
1108 memcpy(skb->cb, &dev, sizeof(dev));
1110 skb_push(skb, priv->ieee80211->tx_headroom);
1111 ret = rtl8192_tx(dev, skb);
1116 if (queue_index != MGNT_QUEUE) {
1117 priv->ieee80211->stats.tx_bytes += (skb->len - priv->ieee80211->tx_headroom);
1118 priv->ieee80211->stats.tx_packets++;
1123 * This is a rough attempt to TX a frame
1124 * This is called by the ieee 80211 stack to TX management frames.
1125 * If the ring is full packet are dropped (for data frame the queue
1126 * is stopped before this can happen).
1128 static int rtl8192_hard_start_xmit(struct sk_buff *skb,struct net_device *dev)
1130 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1134 //unsigned long flags;
1135 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1136 u8 queue_index = tcb_desc->queue_index;
1138 if(queue_index != TXCMD_QUEUE){
1139 if (priv->bHwRadioOff ||(!priv->up))
1146 //spin_lock_irqsave(&priv->tx_lock,flags);
1148 memcpy((unsigned char *)(skb->cb),&dev,sizeof(dev));
1149 if(queue_index == TXCMD_QUEUE) {
1150 // skb_push(skb, USB_HWDESC_HEADER_LEN);
1151 rtl819xE_tx_cmd(dev, skb);
1153 //spin_unlock_irqrestore(&priv->tx_lock,flags);
1156 // RT_TRACE(COMP_SEND, "To send management packet\n");
1157 tcb_desc->RATRIndex = 7;
1158 tcb_desc->bTxDisableRateFallBack = 1;
1159 tcb_desc->bTxUseDriverAssingedRate = 1;
1160 tcb_desc->bTxEnableFwCalcDur = 1;
1161 skb_push(skb, priv->ieee80211->tx_headroom);
1162 ret = rtl8192_tx(dev, skb);
1168 // priv->ieee80211->stats.tx_bytes+=skb->len;
1169 // priv->ieee80211->stats.tx_packets++;
1171 //spin_unlock_irqrestore(&priv->tx_lock,flags);
1178 static void rtl8192_tx_isr(struct net_device *dev, int prio)
1180 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1182 struct rtl8192_tx_ring *ring = &priv->tx_ring[prio];
1184 while (skb_queue_len(&ring->queue)) {
1185 tx_desc_819x_pci *entry = &ring->desc[ring->idx];
1186 struct sk_buff *skb;
1188 /* beacon packet will only use the first descriptor defaultly,
1189 * and the OWN may not be cleared by the hardware
1191 if(prio != BEACON_QUEUE) {
1194 ring->idx = (ring->idx + 1) % ring->entries;
1197 skb = __skb_dequeue(&ring->queue);
1198 pci_unmap_single(priv->pdev, le32_to_cpu(entry->TxBuffAddr),
1199 skb->len, PCI_DMA_TODEVICE);
1203 if (prio == MGNT_QUEUE){
1204 if (priv->ieee80211->ack_tx_to_ieee){
1205 if (rtl8192_is_tx_queue_empty(dev)){
1206 priv->ieee80211->ack_tx_to_ieee = 0;
1207 ieee80211_ps_tx_ack(priv->ieee80211, 1);
1212 if(prio != BEACON_QUEUE) {
1213 /* try to deal with the pending packets */
1214 tasklet_schedule(&priv->irq_tx_tasklet);
1219 static void rtl8192_stop_beacon(struct net_device *dev)
1223 static void rtl8192_config_rate(struct net_device* dev, u16* rate_config)
1225 struct r8192_priv *priv = ieee80211_priv(dev);
1226 struct ieee80211_network *net;
1227 u8 i=0, basic_rate = 0;
1228 net = & priv->ieee80211->current_network;
1230 for (i=0; i<net->rates_len; i++)
1232 basic_rate = net->rates[i]&0x7f;
1235 case MGN_1M: *rate_config |= RRSR_1M; break;
1236 case MGN_2M: *rate_config |= RRSR_2M; break;
1237 case MGN_5_5M: *rate_config |= RRSR_5_5M; break;
1238 case MGN_11M: *rate_config |= RRSR_11M; break;
1239 case MGN_6M: *rate_config |= RRSR_6M; break;
1240 case MGN_9M: *rate_config |= RRSR_9M; break;
1241 case MGN_12M: *rate_config |= RRSR_12M; break;
1242 case MGN_18M: *rate_config |= RRSR_18M; break;
1243 case MGN_24M: *rate_config |= RRSR_24M; break;
1244 case MGN_36M: *rate_config |= RRSR_36M; break;
1245 case MGN_48M: *rate_config |= RRSR_48M; break;
1246 case MGN_54M: *rate_config |= RRSR_54M; break;
1249 for (i=0; i<net->rates_ex_len; i++)
1251 basic_rate = net->rates_ex[i]&0x7f;
1254 case MGN_1M: *rate_config |= RRSR_1M; break;
1255 case MGN_2M: *rate_config |= RRSR_2M; break;
1256 case MGN_5_5M: *rate_config |= RRSR_5_5M; break;
1257 case MGN_11M: *rate_config |= RRSR_11M; break;
1258 case MGN_6M: *rate_config |= RRSR_6M; break;
1259 case MGN_9M: *rate_config |= RRSR_9M; break;
1260 case MGN_12M: *rate_config |= RRSR_12M; break;
1261 case MGN_18M: *rate_config |= RRSR_18M; break;
1262 case MGN_24M: *rate_config |= RRSR_24M; break;
1263 case MGN_36M: *rate_config |= RRSR_36M; break;
1264 case MGN_48M: *rate_config |= RRSR_48M; break;
1265 case MGN_54M: *rate_config |= RRSR_54M; break;
1271 #define SHORT_SLOT_TIME 9
1272 #define NON_SHORT_SLOT_TIME 20
1274 static void rtl8192_update_cap(struct net_device* dev, u16 cap)
1277 struct r8192_priv *priv = ieee80211_priv(dev);
1278 struct ieee80211_network *net = &priv->ieee80211->current_network;
1279 priv->short_preamble = cap & WLAN_CAPABILITY_SHORT_PREAMBLE;
1280 tmp = priv->basic_rate;
1281 if (priv->short_preamble)
1282 tmp |= BRSR_AckShortPmb;
1283 write_nic_dword(dev, RRSR, tmp);
1285 if (net->mode & (IEEE_G|IEEE_N_24G))
1288 if ((cap & WLAN_CAPABILITY_SHORT_SLOT)&&(!priv->ieee80211->pHTInfo->bCurrentRT2RTLongSlotTime))
1290 slot_time = SHORT_SLOT_TIME;
1292 else //long slot time
1293 slot_time = NON_SHORT_SLOT_TIME;
1294 priv->slot_time = slot_time;
1295 write_nic_byte(dev, SLOT_TIME, slot_time);
1300 static void rtl8192_net_update(struct net_device *dev)
1303 struct r8192_priv *priv = ieee80211_priv(dev);
1304 struct ieee80211_network *net;
1305 u16 BcnTimeCfg = 0, BcnCW = 6, BcnIFS = 0xf;
1306 u16 rate_config = 0;
1307 net = &priv->ieee80211->current_network;
1308 //update Basic rate: RR, BRSR
1309 rtl8192_config_rate(dev, &rate_config);
1310 // 2007.01.16, by Emily
1311 // Select RRSR (in Legacy-OFDM and CCK)
1312 // For 8190, we select only 24M, 12M, 6M, 11M, 5.5M, 2M, and 1M from the Basic rate.
1313 // We do not use other rates.
1314 priv->basic_rate = rate_config &= 0x15f;
1316 write_nic_dword(dev,BSSIDR,((u32*)net->bssid)[0]);
1317 write_nic_word(dev,BSSIDR+4,((u16*)net->bssid)[2]);
1320 rtl8192_update_msr(dev);
1324 // rtl8192_update_cap(dev, net->capability);
1325 if (priv->ieee80211->iw_mode == IW_MODE_ADHOC)
1327 write_nic_word(dev, ATIMWND, 2);
1328 write_nic_word(dev, BCN_DMATIME, 256);
1329 write_nic_word(dev, BCN_INTERVAL, net->beacon_interval);
1330 // write_nic_word(dev, BcnIntTime, 100);
1331 //BIT15 of BCN_DRV_EARLY_INT will indicate whether software beacon or hw beacon is applied.
1332 write_nic_word(dev, BCN_DRV_EARLY_INT, 10);
1333 write_nic_byte(dev, BCN_ERR_THRESH, 100);
1335 BcnTimeCfg |= (BcnCW<<BCN_TCFG_CW_SHIFT);
1336 // TODO: BcnIFS may required to be changed on ASIC
1337 BcnTimeCfg |= BcnIFS<<BCN_TCFG_IFS;
1339 write_nic_word(dev, BCN_TCFG, BcnTimeCfg);
1345 void rtl819xE_tx_cmd(struct net_device *dev, struct sk_buff *skb)
1347 struct r8192_priv *priv = ieee80211_priv(dev);
1348 struct rtl8192_tx_ring *ring;
1349 tx_desc_819x_pci *entry;
1353 unsigned long flags;
1355 ring = &priv->tx_ring[TXCMD_QUEUE];
1356 mapping = pci_map_single(priv->pdev, skb->data, skb->len, PCI_DMA_TODEVICE);
1358 spin_lock_irqsave(&priv->irq_th_lock,flags);
1359 idx = (ring->idx + skb_queue_len(&ring->queue)) % ring->entries;
1360 entry = &ring->desc[idx];
1362 tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1364 entry->LINIP = tcb_desc->bLastIniPkt;
1365 entry->FirstSeg = 1;//first segment
1366 entry->LastSeg = 1; //last segment
1367 if(tcb_desc->bCmdOrInit == DESC_PACKET_TYPE_INIT) {
1368 entry->CmdInit = DESC_PACKET_TYPE_INIT;
1370 entry->CmdInit = DESC_PACKET_TYPE_NORMAL;
1371 entry->Offset = sizeof(TX_FWINFO_8190PCI) + 8;
1372 entry->PktSize = (u16)(tcb_desc->pkt_size + entry->Offset);
1373 entry->QueueSelect = QSLT_CMD;
1374 entry->TxFWInfoSize = 0x08;
1375 entry->RATid = (u8)DESC_PACKET_TYPE_INIT;
1377 entry->TxBufferSize = skb->len;
1378 entry->TxBuffAddr = cpu_to_le32(mapping);
1381 #ifdef JOHN_DUMP_TXDESC
1383 tx_desc_819x_pci *entry1 = &ring->desc[0];
1384 unsigned int *ptr= (unsigned int *)entry1;
1385 printk("<Tx descriptor>:\n");
1386 for (i = 0; i < 8; i++)
1387 printk("%8x ", ptr[i]);
1391 __skb_queue_tail(&ring->queue, skb);
1392 spin_unlock_irqrestore(&priv->irq_th_lock,flags);
1394 write_nic_byte(dev, TPPoll, TPPoll_CQ);
1400 * Mapping Software/Hardware descriptor queue id to "Queue Select Field"
1401 * in TxFwInfo data structure
1403 static u8 MapHwQueueToFirmwareQueue(u8 QueueID)
1405 u8 QueueSelect = 0x0; //defualt set to
1409 QueueSelect = QSLT_BE; //or QSelect = pTcb->priority;
1413 QueueSelect = QSLT_BK; //or QSelect = pTcb->priority;
1417 QueueSelect = QSLT_VO; //or QSelect = pTcb->priority;
1421 QueueSelect = QSLT_VI; //or QSelect = pTcb->priority;
1424 QueueSelect = QSLT_MGNT;
1428 QueueSelect = QSLT_BEACON;
1431 // TODO: 2006.10.30 mark other queue selection until we verify it is OK
1432 // TODO: Remove Assertions
1433 //#if (RTL819X_FPGA_VER & RTL819X_FPGA_GUANGAN_070502)
1435 QueueSelect = QSLT_CMD;
1439 //QueueSelect = QSLT_HIGH;
1443 RT_TRACE(COMP_ERR, "TransmitTCB(): Impossible Queue Selection: %d \n", QueueID);
1449 static u8 MRateToHwRate8190Pci(u8 rate)
1451 u8 ret = DESC90_RATE1M;
1454 case MGN_1M: ret = DESC90_RATE1M; break;
1455 case MGN_2M: ret = DESC90_RATE2M; break;
1456 case MGN_5_5M: ret = DESC90_RATE5_5M; break;
1457 case MGN_11M: ret = DESC90_RATE11M; break;
1458 case MGN_6M: ret = DESC90_RATE6M; break;
1459 case MGN_9M: ret = DESC90_RATE9M; break;
1460 case MGN_12M: ret = DESC90_RATE12M; break;
1461 case MGN_18M: ret = DESC90_RATE18M; break;
1462 case MGN_24M: ret = DESC90_RATE24M; break;
1463 case MGN_36M: ret = DESC90_RATE36M; break;
1464 case MGN_48M: ret = DESC90_RATE48M; break;
1465 case MGN_54M: ret = DESC90_RATE54M; break;
1467 // HT rate since here
1468 case MGN_MCS0: ret = DESC90_RATEMCS0; break;
1469 case MGN_MCS1: ret = DESC90_RATEMCS1; break;
1470 case MGN_MCS2: ret = DESC90_RATEMCS2; break;
1471 case MGN_MCS3: ret = DESC90_RATEMCS3; break;
1472 case MGN_MCS4: ret = DESC90_RATEMCS4; break;
1473 case MGN_MCS5: ret = DESC90_RATEMCS5; break;
1474 case MGN_MCS6: ret = DESC90_RATEMCS6; break;
1475 case MGN_MCS7: ret = DESC90_RATEMCS7; break;
1476 case MGN_MCS8: ret = DESC90_RATEMCS8; break;
1477 case MGN_MCS9: ret = DESC90_RATEMCS9; break;
1478 case MGN_MCS10: ret = DESC90_RATEMCS10; break;
1479 case MGN_MCS11: ret = DESC90_RATEMCS11; break;
1480 case MGN_MCS12: ret = DESC90_RATEMCS12; break;
1481 case MGN_MCS13: ret = DESC90_RATEMCS13; break;
1482 case MGN_MCS14: ret = DESC90_RATEMCS14; break;
1483 case MGN_MCS15: ret = DESC90_RATEMCS15; break;
1484 case (0x80|0x20): ret = DESC90_RATEMCS32; break;
1492 static u8 QueryIsShort(u8 TxHT, u8 TxRate, cb_desc *tcb_desc)
1496 tmp_Short = (TxHT==1)?((tcb_desc->bUseShortGI)?1:0):((tcb_desc->bUseShortPreamble)?1:0);
1498 if(TxHT==1 && TxRate != DESC90_RATEMCS15)
1505 * The tx procedure is just as following,
1506 * skb->cb will contain all the following information,
1507 * priority, morefrag, rate, &dev.
1509 short rtl8192_tx(struct net_device *dev, struct sk_buff* skb)
1511 struct r8192_priv *priv = ieee80211_priv(dev);
1512 struct rtl8192_tx_ring *ring;
1513 unsigned long flags;
1514 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1515 tx_desc_819x_pci *pdesc = NULL;
1516 TX_FWINFO_8190PCI *pTxFwInfo = NULL;
1518 bool multi_addr=false,broad_addr=false,uni_addr=false;
1519 u8* pda_addr = NULL;
1522 if(priv->bdisable_nic){
1523 RT_TRACE(COMP_ERR,"%s: ERR!! Nic is disabled! Can't tx packet len=%d qidx=%d!!!\n", __FUNCTION__, skb->len, tcb_desc->queue_index);
1528 priv->ieee80211->bAwakePktSent = true;
1531 mapping = pci_map_single(priv->pdev, skb->data, skb->len, PCI_DMA_TODEVICE);
1532 /* collect the tx packets statitcs */
1533 pda_addr = ((u8*)skb->data) + sizeof(TX_FWINFO_8190PCI);
1534 if(is_multicast_ether_addr(pda_addr))
1536 else if(is_broadcast_ether_addr(pda_addr))
1542 priv->stats.txbytesunicast += (u8)(skb->len) - sizeof(TX_FWINFO_8190PCI);
1544 priv->stats.txbytesmulticast +=(u8)(skb->len) - sizeof(TX_FWINFO_8190PCI);
1546 priv->stats.txbytesbroadcast += (u8)(skb->len) - sizeof(TX_FWINFO_8190PCI);
1548 /* fill tx firmware */
1549 pTxFwInfo = (PTX_FWINFO_8190PCI)skb->data;
1550 memset(pTxFwInfo,0,sizeof(TX_FWINFO_8190PCI));
1551 pTxFwInfo->TxHT = (tcb_desc->data_rate&0x80)?1:0;
1552 pTxFwInfo->TxRate = MRateToHwRate8190Pci((u8)tcb_desc->data_rate);
1553 pTxFwInfo->EnableCPUDur = tcb_desc->bTxEnableFwCalcDur;
1554 pTxFwInfo->Short = QueryIsShort(pTxFwInfo->TxHT, pTxFwInfo->TxRate, tcb_desc);
1556 /* Aggregation related */
1557 if(tcb_desc->bAMPDUEnable) {
1558 pTxFwInfo->AllowAggregation = 1;
1559 pTxFwInfo->RxMF = tcb_desc->ampdu_factor;
1560 pTxFwInfo->RxAMD = tcb_desc->ampdu_density;
1562 pTxFwInfo->AllowAggregation = 0;
1563 pTxFwInfo->RxMF = 0;
1564 pTxFwInfo->RxAMD = 0;
1568 // Protection mode related
1570 pTxFwInfo->RtsEnable = (tcb_desc->bRTSEnable)?1:0;
1571 pTxFwInfo->CtsEnable = (tcb_desc->bCTSEnable)?1:0;
1572 pTxFwInfo->RtsSTBC = (tcb_desc->bRTSSTBC)?1:0;
1573 pTxFwInfo->RtsHT= (tcb_desc->rts_rate&0x80)?1:0;
1574 pTxFwInfo->RtsRate = MRateToHwRate8190Pci((u8)tcb_desc->rts_rate);
1575 pTxFwInfo->RtsBandwidth = 0;
1576 pTxFwInfo->RtsSubcarrier = tcb_desc->RTSSC;
1577 pTxFwInfo->RtsShort = (pTxFwInfo->RtsHT==0)?(tcb_desc->bRTSUseShortPreamble?1:0):(tcb_desc->bRTSUseShortGI?1:0);
1579 // Set Bandwidth and sub-channel settings.
1581 if(priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20_40)
1583 if(tcb_desc->bPacketBW)
1585 pTxFwInfo->TxBandwidth = 1;
1587 pTxFwInfo->TxSubCarrier = 3;
1589 pTxFwInfo->TxSubCarrier = 0; //By SD3's Jerry suggestion, use duplicated mode, cosa 04012008
1594 pTxFwInfo->TxBandwidth = 0;
1595 pTxFwInfo->TxSubCarrier = priv->nCur40MhzPrimeSC;
1598 pTxFwInfo->TxBandwidth = 0;
1599 pTxFwInfo->TxSubCarrier = 0;
1604 /* 2007/07/25 MH Copy current TX FW info.*/
1605 memcpy((void*)(&Tmp_TxFwInfo), (void*)(pTxFwInfo), sizeof(TX_FWINFO_8190PCI));
1606 printk("&&&&&&&&&&&&&&&&&&&&&&====>print out fwinf\n");
1607 printk("===>enable fwcacl:%d\n", Tmp_TxFwInfo.EnableCPUDur);
1608 printk("===>RTS STBC:%d\n", Tmp_TxFwInfo.RtsSTBC);
1609 printk("===>RTS Subcarrier:%d\n", Tmp_TxFwInfo.RtsSubcarrier);
1610 printk("===>Allow Aggregation:%d\n", Tmp_TxFwInfo.AllowAggregation);
1611 printk("===>TX HT bit:%d\n", Tmp_TxFwInfo.TxHT);
1612 printk("===>Tx rate:%d\n", Tmp_TxFwInfo.TxRate);
1613 printk("===>Received AMPDU Density:%d\n", Tmp_TxFwInfo.RxAMD);
1614 printk("===>Received MPDU Factor:%d\n", Tmp_TxFwInfo.RxMF);
1615 printk("===>TxBandwidth:%d\n", Tmp_TxFwInfo.TxBandwidth);
1616 printk("===>TxSubCarrier:%d\n", Tmp_TxFwInfo.TxSubCarrier);
1618 printk("<=====**********************out of print\n");
1621 spin_lock_irqsave(&priv->irq_th_lock,flags);
1622 ring = &priv->tx_ring[tcb_desc->queue_index];
1623 if (tcb_desc->queue_index != BEACON_QUEUE) {
1624 idx = (ring->idx + skb_queue_len(&ring->queue)) % ring->entries;
1629 pdesc = &ring->desc[idx];
1630 if((pdesc->OWN == 1) && (tcb_desc->queue_index != BEACON_QUEUE)) {
1631 RT_TRACE(COMP_ERR,"No more TX desc@%d, ring->idx = %d,idx = %d,%x",
1632 tcb_desc->queue_index,ring->idx, idx,skb->len);
1633 spin_unlock_irqrestore(&priv->irq_th_lock,flags);
1637 /* fill tx descriptor */
1638 memset((u8*)pdesc,0,12);
1642 pdesc->Offset = sizeof(TX_FWINFO_8190PCI) + 8; //We must add 8!! Emily
1643 pdesc->PktSize = (u16)skb->len-sizeof(TX_FWINFO_8190PCI);
1647 pdesc->RATid = tcb_desc->RATRIndex;
1651 pdesc->SecType = 0x0;
1652 if (tcb_desc->bHwSec) {
1653 switch (priv->ieee80211->pairwise_key_type) {
1654 case KEY_TYPE_WEP40:
1655 case KEY_TYPE_WEP104:
1656 pdesc->SecType = 0x1;
1660 pdesc->SecType = 0x2;
1664 pdesc->SecType = 0x3;
1668 pdesc->SecType = 0x0;
1679 pdesc->QueueSelect = MapHwQueueToFirmwareQueue(tcb_desc->queue_index);
1680 pdesc->TxFWInfoSize = sizeof(TX_FWINFO_8190PCI);
1682 pdesc->DISFB = tcb_desc->bTxDisableRateFallBack;
1683 pdesc->USERATE = tcb_desc->bTxUseDriverAssingedRate;
1687 pdesc->TxBufferSize = skb->len;
1689 pdesc->TxBuffAddr = cpu_to_le32(mapping);
1690 __skb_queue_tail(&ring->queue, skb);
1692 spin_unlock_irqrestore(&priv->irq_th_lock,flags);
1693 dev->trans_start = jiffies;
1694 write_nic_word(dev,TPPoll,0x01<<tcb_desc->queue_index);
1698 static short rtl8192_alloc_rx_desc_ring(struct net_device *dev)
1700 struct r8192_priv *priv = ieee80211_priv(dev);
1701 rx_desc_819x_pci *entry = NULL;
1704 priv->rx_ring = pci_alloc_consistent(priv->pdev,
1705 sizeof(*priv->rx_ring) * priv->rxringcount, &priv->rx_ring_dma);
1707 if (!priv->rx_ring || (unsigned long)priv->rx_ring & 0xFF) {
1708 RT_TRACE(COMP_ERR,"Cannot allocate RX ring\n");
1712 memset(priv->rx_ring, 0, sizeof(*priv->rx_ring) * priv->rxringcount);
1715 for (i = 0; i < priv->rxringcount; i++) {
1716 struct sk_buff *skb = dev_alloc_skb(priv->rxbuffersize);
1717 dma_addr_t *mapping;
1718 entry = &priv->rx_ring[i];
1721 priv->rx_buf[i] = skb;
1722 mapping = (dma_addr_t *)skb->cb;
1723 *mapping = pci_map_single(priv->pdev, skb_tail_pointer(skb),
1724 priv->rxbuffersize, PCI_DMA_FROMDEVICE);
1726 entry->BufferAddress = cpu_to_le32(*mapping);
1728 entry->Length = priv->rxbuffersize;
1736 static int rtl8192_alloc_tx_desc_ring(struct net_device *dev,
1737 unsigned int prio, unsigned int entries)
1739 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1740 tx_desc_819x_pci *ring;
1744 ring = pci_alloc_consistent(priv->pdev, sizeof(*ring) * entries, &dma);
1745 if (!ring || (unsigned long)ring & 0xFF) {
1746 RT_TRACE(COMP_ERR, "Cannot allocate TX ring (prio = %d)\n", prio);
1750 memset(ring, 0, sizeof(*ring)*entries);
1751 priv->tx_ring[prio].desc = ring;
1752 priv->tx_ring[prio].dma = dma;
1753 priv->tx_ring[prio].idx = 0;
1754 priv->tx_ring[prio].entries = entries;
1755 skb_queue_head_init(&priv->tx_ring[prio].queue);
1757 for (i = 0; i < entries; i++)
1758 ring[i].NextDescAddress =
1759 cpu_to_le32((u32)dma + ((i + 1) % entries) * sizeof(*ring));
1765 static short rtl8192_pci_initdescring(struct net_device *dev)
1769 struct r8192_priv *priv = ieee80211_priv(dev);
1771 ret = rtl8192_alloc_rx_desc_ring(dev);
1777 /* general process for other queue */
1778 for (i = 0; i < MAX_TX_QUEUE_COUNT; i++) {
1779 ret = rtl8192_alloc_tx_desc_ring(dev, i, priv->txringcount);
1781 goto err_free_rings;
1785 /* specific process for hardware beacon process */
1786 ret = rtl8192_alloc_tx_desc_ring(dev, MAX_TX_QUEUE_COUNT - 1, 2);
1788 goto err_free_rings;
1794 rtl8192_free_rx_ring(dev);
1795 for (i = 0; i < MAX_TX_QUEUE_COUNT; i++)
1796 if (priv->tx_ring[i].desc)
1797 rtl8192_free_tx_ring(dev, i);
1801 static void rtl8192_pci_resetdescring(struct net_device *dev)
1803 struct r8192_priv *priv = ieee80211_priv(dev);
1806 /* force the rx_idx to the first one */
1808 rx_desc_819x_pci *entry = NULL;
1809 for (i = 0; i < priv->rxringcount; i++) {
1810 entry = &priv->rx_ring[i];
1816 /* after reset, release previous pending packet, and force the
1817 * tx idx to the first one */
1818 for (i = 0; i < MAX_TX_QUEUE_COUNT; i++) {
1819 if (priv->tx_ring[i].desc) {
1820 struct rtl8192_tx_ring *ring = &priv->tx_ring[i];
1822 while (skb_queue_len(&ring->queue)) {
1823 tx_desc_819x_pci *entry = &ring->desc[ring->idx];
1824 struct sk_buff *skb = __skb_dequeue(&ring->queue);
1826 pci_unmap_single(priv->pdev, le32_to_cpu(entry->TxBuffAddr),
1827 skb->len, PCI_DMA_TODEVICE);
1829 ring->idx = (ring->idx + 1) % ring->entries;
1836 static void rtl8192_link_change(struct net_device *dev)
1838 struct r8192_priv *priv = ieee80211_priv(dev);
1839 struct ieee80211_device* ieee = priv->ieee80211;
1840 //write_nic_word(dev, BCN_INTR_ITV, net->beacon_interval);
1841 if (ieee->state == IEEE80211_LINKED)
1843 rtl8192_net_update(dev);
1844 rtl8192_update_ratr_table(dev);
1846 //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
1847 if ((KEY_TYPE_WEP40 == ieee->pairwise_key_type) || (KEY_TYPE_WEP104 == ieee->pairwise_key_type))
1848 EnableHWSecurityConfig8192(dev);
1853 write_nic_byte(dev, 0x173, 0);
1855 /*update timing params*/
1856 //rtl8192_set_chan(dev, priv->chan);
1858 rtl8192_update_msr(dev);
1860 // 2007/10/16 MH MAC Will update TSF according to all received beacon, so we have
1861 // // To set CBSSID bit when link with any AP or STA.
1862 if (ieee->iw_mode == IW_MODE_INFRA || ieee->iw_mode == IW_MODE_ADHOC)
1865 reg = read_nic_dword(dev, RCR);
1866 if (priv->ieee80211->state == IEEE80211_LINKED)
1867 priv->ReceiveConfig = reg |= RCR_CBSSID;
1869 priv->ReceiveConfig = reg &= ~RCR_CBSSID;
1870 write_nic_dword(dev, RCR, reg);
1875 static const struct ieee80211_qos_parameters def_qos_parameters = {
1876 {3,3,3,3},/* cw_min */
1877 {7,7,7,7},/* cw_max */
1878 {2,2,2,2},/* aifs */
1879 {0,0,0,0},/* flags */
1880 {0,0,0,0} /* tx_op_limit */
1883 static void rtl8192_update_beacon(struct work_struct * work)
1885 struct r8192_priv *priv = container_of(work, struct r8192_priv, update_beacon_wq.work);
1886 struct net_device *dev = priv->ieee80211->dev;
1887 struct ieee80211_device* ieee = priv->ieee80211;
1888 struct ieee80211_network* net = &ieee->current_network;
1890 if (ieee->pHTInfo->bCurrentHTSupport)
1891 HTUpdateSelfAndPeerSetting(ieee, net);
1892 ieee->pHTInfo->bCurrentRT2RTLongSlotTime = net->bssht.bdRT2RTLongSlotTime;
1893 rtl8192_update_cap(dev, net->capability);
1897 * background support to run QoS activate functionality
1899 static const int WDCAPARA_ADD[] = {EDCAPARA_BE,EDCAPARA_BK,EDCAPARA_VI,EDCAPARA_VO};
1900 static void rtl8192_qos_activate(struct work_struct * work)
1902 struct r8192_priv *priv = container_of(work, struct r8192_priv, qos_activate);
1903 struct net_device *dev = priv->ieee80211->dev;
1904 struct ieee80211_qos_parameters *qos_parameters = &priv->ieee80211->current_network.qos_data.parameters;
1905 u8 mode = priv->ieee80211->current_network.mode;
1910 mutex_lock(&priv->mutex);
1911 if(priv->ieee80211->state != IEEE80211_LINKED)
1913 RT_TRACE(COMP_QOS,"qos active process with associate response received\n");
1914 /* It better set slot time at first */
1915 /* For we just support b/g mode at present, let the slot time at 9/20 selection */
1916 /* update the ac parameter to related registers */
1917 for(i = 0; i < QOS_QUEUE_NUM; i++) {
1918 //Mode G/A: slotTimeTimer = 9; Mode B: 20
1919 u1bAIFS = qos_parameters->aifs[i] * ((mode&(IEEE_G|IEEE_N_24G)) ?9:20) + aSifsTime;
1920 u4bAcParam = ((((u32)(qos_parameters->tx_op_limit[i]))<< AC_PARAM_TXOP_LIMIT_OFFSET)|
1921 (((u32)(qos_parameters->cw_max[i]))<< AC_PARAM_ECW_MAX_OFFSET)|
1922 (((u32)(qos_parameters->cw_min[i]))<< AC_PARAM_ECW_MIN_OFFSET)|
1923 ((u32)u1bAIFS << AC_PARAM_AIFS_OFFSET));
1924 //printk("===>u4bAcParam:%x, ", u4bAcParam);
1925 write_nic_dword(dev, WDCAPARA_ADD[i], u4bAcParam);
1926 //write_nic_dword(dev, WDCAPARA_ADD[i], 0x005e4332);
1930 mutex_unlock(&priv->mutex);
1933 static int rtl8192_qos_handle_probe_response(struct r8192_priv *priv,
1935 struct ieee80211_network *network)
1938 u32 size = sizeof(struct ieee80211_qos_parameters);
1940 if(priv->ieee80211->state !=IEEE80211_LINKED)
1943 if ((priv->ieee80211->iw_mode != IW_MODE_INFRA))
1946 if (network->flags & NETWORK_HAS_QOS_MASK) {
1947 if (active_network &&
1948 (network->flags & NETWORK_HAS_QOS_PARAMETERS))
1949 network->qos_data.active = network->qos_data.supported;
1951 if ((network->qos_data.active == 1) && (active_network == 1) &&
1952 (network->flags & NETWORK_HAS_QOS_PARAMETERS) &&
1953 (network->qos_data.old_param_count !=
1954 network->qos_data.param_count)) {
1955 network->qos_data.old_param_count =
1956 network->qos_data.param_count;
1957 queue_work(priv->priv_wq, &priv->qos_activate);
1958 RT_TRACE (COMP_QOS, "QoS parameters change call "
1962 memcpy(&priv->ieee80211->current_network.qos_data.parameters,
1963 &def_qos_parameters, size);
1965 if ((network->qos_data.active == 1) && (active_network == 1)) {
1966 queue_work(priv->priv_wq, &priv->qos_activate);
1967 RT_TRACE(COMP_QOS, "QoS was disabled call qos_activate \n");
1969 network->qos_data.active = 0;
1970 network->qos_data.supported = 0;
1976 /* handle manage frame frame beacon and probe response */
1977 static int rtl8192_handle_beacon(struct net_device * dev,
1978 struct ieee80211_beacon * beacon,
1979 struct ieee80211_network * network)
1981 struct r8192_priv *priv = ieee80211_priv(dev);
1983 rtl8192_qos_handle_probe_response(priv,1,network);
1985 queue_delayed_work(priv->priv_wq, &priv->update_beacon_wq, 0);
1991 * handling the beaconing responses. if we get different QoS setting
1992 * off the network from the associated setting, adjust the QoS setting
1994 static int rtl8192_qos_association_resp(struct r8192_priv *priv,
1995 struct ieee80211_network *network)
1998 unsigned long flags;
1999 u32 size = sizeof(struct ieee80211_qos_parameters);
2000 int set_qos_param = 0;
2002 if ((priv == NULL) || (network == NULL))
2005 if(priv->ieee80211->state !=IEEE80211_LINKED)
2008 if ((priv->ieee80211->iw_mode != IW_MODE_INFRA))
2011 spin_lock_irqsave(&priv->ieee80211->lock, flags);
2012 if(network->flags & NETWORK_HAS_QOS_PARAMETERS) {
2013 memcpy(&priv->ieee80211->current_network.qos_data.parameters,
2014 &network->qos_data.parameters,
2015 sizeof(struct ieee80211_qos_parameters));
2016 priv->ieee80211->current_network.qos_data.active = 1;
2018 if((priv->ieee80211->current_network.qos_data.param_count !=
2019 network->qos_data.param_count))
2023 /* update qos parameter for current network */
2024 priv->ieee80211->current_network.qos_data.old_param_count =
2025 priv->ieee80211->current_network.qos_data.param_count;
2026 priv->ieee80211->current_network.qos_data.param_count =
2027 network->qos_data.param_count;
2030 memcpy(&priv->ieee80211->current_network.qos_data.parameters,
2031 &def_qos_parameters, size);
2032 priv->ieee80211->current_network.qos_data.active = 0;
2033 priv->ieee80211->current_network.qos_data.supported = 0;
2037 spin_unlock_irqrestore(&priv->ieee80211->lock, flags);
2039 RT_TRACE(COMP_QOS, "%s: network->flags = %d,%d\n",__FUNCTION__,network->flags ,priv->ieee80211->current_network.qos_data.active);
2040 if (set_qos_param == 1)
2041 queue_work(priv->priv_wq, &priv->qos_activate);
2047 static int rtl8192_handle_assoc_response(struct net_device *dev,
2048 struct ieee80211_assoc_response_frame *resp,
2049 struct ieee80211_network *network)
2051 struct r8192_priv *priv = ieee80211_priv(dev);
2052 rtl8192_qos_association_resp(priv, network);
2057 /* updateRATRTabel for MCS only. Basic rate is not implemented. */
2058 static void rtl8192_update_ratr_table(struct net_device* dev)
2060 struct r8192_priv* priv = ieee80211_priv(dev);
2061 struct ieee80211_device* ieee = priv->ieee80211;
2062 u8* pMcsRate = ieee->dot11HTOperationalRateSet;
2066 rtl8192_config_rate(dev, (u16*)(&ratr_value));
2067 ratr_value |= (*(u16*)(pMcsRate)) << 12;
2072 ratr_value &= 0x00000FF0;
2075 ratr_value &= 0x0000000F;
2078 ratr_value &= 0x00000FF7;
2082 if (ieee->pHTInfo->PeerMimoPs == 0) //MIMO_PS_STATIC
2083 ratr_value &= 0x0007F007;
2085 if (priv->rf_type == RF_1T2R)
2086 ratr_value &= 0x000FF007;
2088 ratr_value &= 0x0F81F007;
2094 ratr_value &= 0x0FFFFFFF;
2095 if(ieee->pHTInfo->bCurTxBW40MHz && ieee->pHTInfo->bCurShortGI40MHz){
2096 ratr_value |= 0x80000000;
2097 }else if(!ieee->pHTInfo->bCurTxBW40MHz && ieee->pHTInfo->bCurShortGI20MHz){
2098 ratr_value |= 0x80000000;
2100 write_nic_dword(dev, RATR0+rate_index*4, ratr_value);
2101 write_nic_byte(dev, UFWP, 1);
2104 static bool GetNmodeSupportBySecCfg8190Pci(struct net_device*dev)
2108 struct r8192_priv *priv = ieee80211_priv(dev);
2109 struct ieee80211_device *ieee = priv->ieee80211;
2110 return !(ieee->rtllib_ap_sec_type &&
2111 (ieee->rtllib_ap_sec_type(ieee)&(SEC_ALG_WEP|SEC_ALG_TKIP)));
2113 struct r8192_priv* priv = ieee80211_priv(dev);
2114 struct ieee80211_device* ieee = priv->ieee80211;
2115 int wpa_ie_len= ieee->wpa_ie_len;
2116 struct ieee80211_crypt_data* crypt;
2119 crypt = ieee->crypt[ieee->tx_keyidx];
2120 encrypt = (ieee->current_network.capability & WLAN_CAPABILITY_PRIVACY) || (ieee->host_encrypt && crypt && crypt->ops && (0 == strcmp(crypt->ops->name,"WEP")));
2123 if(encrypt && (wpa_ie_len == 0)) {
2124 /* wep encryption, no N mode setting */
2126 // } else if((wpa_ie_len != 0)&&(memcmp(&(ieee->wpa_ie[14]),ccmp_ie,4))) {
2127 } else if((wpa_ie_len != 0)) {
2128 /* parse pairwise key type */
2129 //if((pairwisekey = WEP40)||(pairwisekey = WEP104)||(pairwisekey = TKIP))
2130 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))))
2135 //RT_TRACE(COMP_ERR,"In %s The GroupEncAlgorithm is [4]\n",__FUNCTION__ );
2143 static void rtl8192_refresh_supportrate(struct r8192_priv* priv)
2145 struct ieee80211_device* ieee = priv->ieee80211;
2146 //we donot consider set support rate for ABG mode, only HT MCS rate is set here.
2147 if (ieee->mode == WIRELESS_MODE_N_24G || ieee->mode == WIRELESS_MODE_N_5G)
2149 memcpy(ieee->Regdot11HTOperationalRateSet, ieee->RegHTSuppRateSet, 16);
2150 //RT_DEBUG_DATA(COMP_INIT, ieee->RegHTSuppRateSet, 16);
2151 //RT_DEBUG_DATA(COMP_INIT, ieee->Regdot11HTOperationalRateSet, 16);
2154 memset(ieee->Regdot11HTOperationalRateSet, 0, 16);
2157 static u8 rtl8192_getSupportedWireleeMode(struct net_device*dev)
2159 struct r8192_priv *priv = ieee80211_priv(dev);
2161 switch(priv->rf_chip)
2166 ret = (WIRELESS_MODE_N_24G|WIRELESS_MODE_G|WIRELESS_MODE_B);
2169 ret = (WIRELESS_MODE_A|WIRELESS_MODE_N_5G);
2172 ret = WIRELESS_MODE_B;
2178 static void rtl8192_SetWirelessMode(struct net_device* dev, u8 wireless_mode)
2180 struct r8192_priv *priv = ieee80211_priv(dev);
2181 u8 bSupportMode = rtl8192_getSupportedWireleeMode(dev);
2184 if ((wireless_mode == WIRELESS_MODE_AUTO) || ((wireless_mode&bSupportMode)==0))
2186 if(bSupportMode & WIRELESS_MODE_N_24G)
2188 wireless_mode = WIRELESS_MODE_N_24G;
2190 else if(bSupportMode & WIRELESS_MODE_N_5G)
2192 wireless_mode = WIRELESS_MODE_N_5G;
2194 else if((bSupportMode & WIRELESS_MODE_A))
2196 wireless_mode = WIRELESS_MODE_A;
2198 else if((bSupportMode & WIRELESS_MODE_G))
2200 wireless_mode = WIRELESS_MODE_G;
2202 else if((bSupportMode & WIRELESS_MODE_B))
2204 wireless_mode = WIRELESS_MODE_B;
2207 RT_TRACE(COMP_ERR, "%s(), No valid wireless mode supported, SupportedWirelessMode(%x)!!!\n", __FUNCTION__,bSupportMode);
2208 wireless_mode = WIRELESS_MODE_B;
2211 #ifdef TO_DO_LIST //// TODO: this function doesn't work well at this time, we should wait for FPGA
2212 ActUpdateChannelAccessSetting( pAdapter, pHalData->CurrentWirelessMode, &pAdapter->MgntInfo.Info8185.ChannelAccessSetting );
2214 priv->ieee80211->mode = wireless_mode;
2216 if ((wireless_mode == WIRELESS_MODE_N_24G) || (wireless_mode == WIRELESS_MODE_N_5G))
2217 priv->ieee80211->pHTInfo->bEnableHT = 1;
2219 priv->ieee80211->pHTInfo->bEnableHT = 0;
2220 RT_TRACE(COMP_INIT, "Current Wireless Mode is %x\n", wireless_mode);
2221 rtl8192_refresh_supportrate(priv);
2226 static bool GetHalfNmodeSupportByAPs819xPci(struct net_device* dev)
2228 struct r8192_priv* priv = ieee80211_priv(dev);
2229 struct ieee80211_device* ieee = priv->ieee80211;
2231 return ieee->bHalfWirelessN24GMode;
2234 short rtl8192_is_tx_queue_empty(struct net_device *dev)
2237 struct r8192_priv *priv = ieee80211_priv(dev);
2238 for (i=0; i<=MGNT_QUEUE; i++)
2240 if ((i== TXCMD_QUEUE) || (i == HCCA_QUEUE) )
2242 if (skb_queue_len(&(&priv->tx_ring[i])->queue) > 0){
2243 printk("===>tx queue is not empty:%d, %d\n", i, skb_queue_len(&(&priv->tx_ring[i])->queue));
2250 static void rtl8192_hw_sleep_down(struct net_device *dev)
2252 struct r8192_priv *priv = ieee80211_priv(dev);
2253 unsigned long flags = 0;
2255 spin_lock_irqsave(&priv->rf_ps_lock,flags);
2256 if (priv->RFChangeInProgress) {
2257 spin_unlock_irqrestore(&priv->rf_ps_lock,flags);
2258 RT_TRACE(COMP_RF, "rtl8192_hw_sleep_down(): RF Change in progress! \n");
2259 printk("rtl8192_hw_sleep_down(): RF Change in progress!\n");
2262 spin_unlock_irqrestore(&priv->rf_ps_lock,flags);
2264 MgntActSet_RF_State(dev, eRfSleep, RF_CHANGE_BY_PS);
2267 static void rtl8192_hw_sleep_wq (struct work_struct *work)
2269 struct delayed_work *dwork = container_of(work,struct delayed_work,work);
2270 struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,hw_sleep_wq);
2271 struct net_device *dev = ieee->dev;
2273 rtl8192_hw_sleep_down(dev);
2276 static void rtl8192_hw_wakeup(struct net_device* dev)
2278 struct r8192_priv *priv = ieee80211_priv(dev);
2279 unsigned long flags = 0;
2281 spin_lock_irqsave(&priv->rf_ps_lock,flags);
2282 if (priv->RFChangeInProgress) {
2283 spin_unlock_irqrestore(&priv->rf_ps_lock,flags);
2284 RT_TRACE(COMP_RF, "rtl8192_hw_wakeup(): RF Change in progress! \n");
2285 printk("rtl8192_hw_wakeup(): RF Change in progress! schedule wake up task again\n");
2286 queue_delayed_work(priv->ieee80211->wq,&priv->ieee80211->hw_wakeup_wq,MSECS(10));//PowerSave is not supported if kernel version is below 2.6.20
2289 spin_unlock_irqrestore(&priv->rf_ps_lock,flags);
2291 MgntActSet_RF_State(dev, eRfOn, RF_CHANGE_BY_PS);
2294 void rtl8192_hw_wakeup_wq (struct work_struct *work)
2296 struct delayed_work *dwork = container_of(work,struct delayed_work,work);
2297 struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,hw_wakeup_wq);
2298 struct net_device *dev = ieee->dev;
2299 rtl8192_hw_wakeup(dev);
2303 #define MIN_SLEEP_TIME 50
2304 #define MAX_SLEEP_TIME 10000
2305 static void rtl8192_hw_to_sleep(struct net_device *dev, u32 th, u32 tl)
2307 struct r8192_priv *priv = ieee80211_priv(dev);
2310 unsigned long flags;
2312 spin_lock_irqsave(&priv->ps_lock,flags);
2314 // Writing HW register with 0 equals to disable
2315 // the timer, that is not really what we want
2317 tl -= MSECS(8+16+7);
2319 // If the interval in witch we are requested to sleep is too
2320 // short then give up and remain awake
2321 // when we sleep after send null frame, the timer will be too short to sleep.
2323 if(((tl>=rb)&& (tl-rb) <= MSECS(MIN_SLEEP_TIME))
2324 ||((rb>tl)&& (rb-tl) < MSECS(MIN_SLEEP_TIME))) {
2325 spin_unlock_irqrestore(&priv->ps_lock,flags);
2326 printk("too short to sleep::%x, %x, %lx\n",tl, rb, MSECS(MIN_SLEEP_TIME));
2330 if(((tl > rb) && ((tl-rb) > MSECS(MAX_SLEEP_TIME)))||
2331 ((tl < rb) && (tl>MSECS(69)) && ((rb-tl) > MSECS(MAX_SLEEP_TIME)))||
2332 ((tl<rb)&&(tl<MSECS(69))&&((tl+0xffffffff-rb)>MSECS(MAX_SLEEP_TIME)))) {
2333 printk("========>too long to sleep:%x, %x, %lx\n", tl, rb, MSECS(MAX_SLEEP_TIME));
2334 spin_unlock_irqrestore(&priv->ps_lock,flags);
2338 u32 tmp = (tl>rb)?(tl-rb):(rb-tl);
2339 queue_delayed_work(priv->ieee80211->wq,
2340 &priv->ieee80211->hw_wakeup_wq,tmp);
2341 //PowerSave not supported when kernel version less 2.6.20
2343 queue_delayed_work(priv->ieee80211->wq,
2344 (void *)&priv->ieee80211->hw_sleep_wq,0);
2345 spin_unlock_irqrestore(&priv->ps_lock,flags);
2349 static void rtl8192_init_priv_variable(struct net_device* dev)
2351 struct r8192_priv *priv = ieee80211_priv(dev);
2353 PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->ieee80211->PowerSaveControl));
2355 // Default Halt the NIC if RF is OFF.
2356 pPSC->RegRfPsLevel |= RT_RF_OFF_LEVL_HALT_NIC;
2357 pPSC->RegRfPsLevel |= RT_RF_OFF_LEVL_CLK_REQ;
2358 pPSC->RegRfPsLevel |= RT_RF_OFF_LEVL_ASPM;
2359 pPSC->RegRfPsLevel |= RT_RF_LPS_LEVEL_ASPM;
2360 pPSC->bLeisurePs = true;
2361 pPSC->RegMaxLPSAwakeIntvl = 5;
2362 priv->bHwRadioOff = false;
2364 priv->being_init_adapter = false;
2365 priv->txbuffsize = 1600;//1024;
2366 priv->txfwbuffersize = 4096;
2367 priv->txringcount = 64;//32;
2368 //priv->txbeaconcount = priv->txringcount;
2369 priv->txbeaconcount = 2;
2370 priv->rxbuffersize = 9100;//2048;//1024;
2371 priv->rxringcount = MAX_RX_COUNT;//64;
2372 priv->irq_enabled=0;
2373 priv->card_8192 = NIC_8192E;
2374 priv->rx_skb_complete = 1;
2375 priv->chan = 1; //set to channel 1
2376 priv->RegWirelessMode = WIRELESS_MODE_AUTO;
2377 priv->RegChannelPlan = 0xf;
2378 priv->nrxAMPDU_size = 0;
2379 priv->nrxAMPDU_aggr_num = 0;
2380 priv->last_rxdesc_tsf_high = 0;
2381 priv->last_rxdesc_tsf_low = 0;
2382 priv->ieee80211->mode = WIRELESS_MODE_AUTO; //SET AUTO
2383 priv->ieee80211->iw_mode = IW_MODE_INFRA;
2384 priv->ieee80211->ieee_up=0;
2385 priv->retry_rts = DEFAULT_RETRY_RTS;
2386 priv->retry_data = DEFAULT_RETRY_DATA;
2387 priv->ieee80211->rts = DEFAULT_RTS_THRESHOLD;
2388 priv->ieee80211->rate = 110; //11 mbps
2389 priv->ieee80211->short_slot = 1;
2390 priv->promisc = (dev->flags & IFF_PROMISC) ? 1:0;
2391 priv->bcck_in_ch14 = false;
2392 priv->bfsync_processing = false;
2393 priv->CCKPresentAttentuation = 0;
2394 priv->rfa_txpowertrackingindex = 0;
2395 priv->rfc_txpowertrackingindex = 0;
2397 priv->ScanDelay = 50;//for Scan TODO
2398 //added by amy for silent reset
2399 priv->ResetProgress = RESET_TYPE_NORESET;
2400 priv->bForcedSilentReset = 0;
2401 priv->bDisableNormalResetCheck = false;
2402 priv->force_reset = false;
2403 //added by amy for power save
2405 priv->ieee80211->RfOffReason = 0;
2406 priv->RFChangeInProgress = false;
2407 priv->bHwRfOffAction = 0;
2408 priv->SetRFPowerStateInProgress = false;
2409 priv->ieee80211->PowerSaveControl.bInactivePs = true;
2410 priv->ieee80211->PowerSaveControl.bIPSModeBackup = false;
2412 priv->txpower_checkcnt = 0;
2413 priv->thermal_readback_index =0;
2414 priv->txpower_tracking_callback_cnt = 0;
2415 priv->ccktxpower_adjustcnt_ch14 = 0;
2416 priv->ccktxpower_adjustcnt_not_ch14 = 0;
2418 priv->ieee80211->current_network.beacon_interval = DEFAULT_BEACONINTERVAL;
2419 priv->ieee80211->iw_mode = IW_MODE_INFRA;
2420 priv->ieee80211->softmac_features = IEEE_SOFTMAC_SCAN |
2421 IEEE_SOFTMAC_ASSOCIATE | IEEE_SOFTMAC_PROBERQ |
2422 IEEE_SOFTMAC_PROBERS | IEEE_SOFTMAC_TX_QUEUE;/* |
2423 IEEE_SOFTMAC_BEACONS;*///added by amy 080604 //| //IEEE_SOFTMAC_SINGLE_QUEUE;
2425 priv->ieee80211->active_scan = 1;
2426 priv->ieee80211->modulation = IEEE80211_CCK_MODULATION | IEEE80211_OFDM_MODULATION;
2427 priv->ieee80211->host_encrypt = 1;
2428 priv->ieee80211->host_decrypt = 1;
2429 //priv->ieee80211->start_send_beacons = NULL;//rtl819xusb_beacon_tx;//-by amy 080604
2430 //priv->ieee80211->stop_send_beacons = NULL;//rtl8192_beacon_stop;//-by amy 080604
2431 priv->ieee80211->start_send_beacons = rtl8192_start_beacon;//+by david 081107
2432 priv->ieee80211->stop_send_beacons = rtl8192_stop_beacon;//+by david 081107
2433 priv->ieee80211->softmac_hard_start_xmit = rtl8192_hard_start_xmit;
2434 priv->ieee80211->set_chan = rtl8192_set_chan;
2435 priv->ieee80211->link_change = rtl8192_link_change;
2436 priv->ieee80211->softmac_data_hard_start_xmit = rtl8192_hard_data_xmit;
2437 priv->ieee80211->data_hard_stop = rtl8192_data_hard_stop;
2438 priv->ieee80211->data_hard_resume = rtl8192_data_hard_resume;
2439 priv->ieee80211->init_wmmparam_flag = 0;
2440 priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD;
2441 priv->ieee80211->check_nic_enough_desc = check_nic_enough_desc;
2442 priv->ieee80211->tx_headroom = sizeof(TX_FWINFO_8190PCI);
2443 priv->ieee80211->qos_support = 1;
2444 priv->ieee80211->dot11PowerSaveMode = 0;
2446 // priv->ieee80211->SwChnlByTimerHandler = rtl8192_phy_SwChnl;
2447 priv->ieee80211->SetBWModeHandler = rtl8192_SetBWMode;
2448 priv->ieee80211->handle_assoc_response = rtl8192_handle_assoc_response;
2449 priv->ieee80211->handle_beacon = rtl8192_handle_beacon;
2451 priv->ieee80211->sta_wake_up = rtl8192_hw_wakeup;
2452 // priv->ieee80211->ps_request_tx_ack = rtl8192_rq_tx_ack;
2453 priv->ieee80211->enter_sleep_state = rtl8192_hw_to_sleep;
2454 priv->ieee80211->ps_is_queue_empty = rtl8192_is_tx_queue_empty;
2456 priv->ieee80211->GetNmodeSupportBySecCfg = GetNmodeSupportBySecCfg8190Pci;
2457 priv->ieee80211->SetWirelessMode = rtl8192_SetWirelessMode;
2458 priv->ieee80211->GetHalfNmodeSupportByAPsHandler = GetHalfNmodeSupportByAPs819xPci;
2461 priv->ieee80211->InitialGainHandler = InitialGain819xPci;
2464 priv->ieee80211->ieee80211_ips_leave_wq = ieee80211_ips_leave_wq;
2465 priv->ieee80211->ieee80211_ips_leave = ieee80211_ips_leave;
2468 priv->ieee80211->LeisurePSLeave = LeisurePSLeave;
2471 priv->ieee80211->SetHwRegHandler = rtl8192e_SetHwReg;
2472 priv->ieee80211->rtllib_ap_sec_type = rtl8192e_ap_sec_type;
2474 priv->card_type = USB;
2476 priv->ShortRetryLimit = 0x30;
2477 priv->LongRetryLimit = 0x30;
2479 priv->EarlyRxThreshold = 7;
2480 priv->enable_gpio0 = 0;
2482 priv->TransmitConfig = 0;
2484 priv->ReceiveConfig = RCR_ADD3 |
2485 RCR_AMF | RCR_ADF | //accept management/data
2486 RCR_AICV | //accept control frame for SW AP needs PS-poll, 2005.07.07, by rcnjko.
2487 RCR_AB | RCR_AM | RCR_APM | //accept BC/MC/UC
2488 RCR_AAP | ((u32)7<<RCR_MXDMA_OFFSET) |
2489 ((u32)7 << RCR_FIFO_OFFSET) | RCR_ONLYERLPKT;
2491 priv->irq_mask = (u32)(IMR_ROK | IMR_VODOK | IMR_VIDOK | IMR_BEDOK | IMR_BKDOK |
2492 IMR_HCCADOK | IMR_MGNTDOK | IMR_COMDOK | IMR_HIGHDOK |
2493 IMR_BDOK | IMR_RXCMDOK | IMR_TIMEOUT0 | IMR_RDU | IMR_RXFOVW |
2494 IMR_TXFOVW | IMR_BcnInt | IMR_TBDOK | IMR_TBDER);
2496 priv->AcmControl = 0;
2497 priv->pFirmware = (rt_firmware*)vmalloc(sizeof(rt_firmware));
2498 if (priv->pFirmware)
2499 memset(priv->pFirmware, 0, sizeof(rt_firmware));
2501 /* rx related queue */
2502 skb_queue_head_init(&priv->rx_queue);
2503 skb_queue_head_init(&priv->skb_queue);
2505 /* Tx related queue */
2506 for(i = 0; i < MAX_QUEUE_SIZE; i++) {
2507 skb_queue_head_init(&priv->ieee80211->skb_waitQ [i]);
2509 for(i = 0; i < MAX_QUEUE_SIZE; i++) {
2510 skb_queue_head_init(&priv->ieee80211->skb_aggQ [i]);
2512 priv->rf_set_chan = rtl8192_phy_SwChnl;
2515 static void rtl8192_init_priv_lock(struct r8192_priv* priv)
2517 spin_lock_init(&priv->tx_lock);
2518 spin_lock_init(&priv->irq_lock);//added by thomas
2519 spin_lock_init(&priv->irq_th_lock);
2520 spin_lock_init(&priv->rf_ps_lock);
2521 spin_lock_init(&priv->ps_lock);
2522 //spin_lock_init(&priv->rf_lock);
2523 sema_init(&priv->wx_sem,1);
2524 sema_init(&priv->rf_sem,1);
2525 mutex_init(&priv->mutex);
2528 /* init tasklet and wait_queue here */
2529 #define DRV_NAME "wlan0"
2530 static void rtl8192_init_priv_task(struct net_device* dev)
2532 struct r8192_priv *priv = ieee80211_priv(dev);
2534 #ifdef PF_SYNCTHREAD
2535 priv->priv_wq = create_workqueue(DRV_NAME,0);
2537 priv->priv_wq = create_workqueue(DRV_NAME);
2541 INIT_WORK(&priv->ieee80211->ips_leave_wq, (void*)IPSLeave_wq);
2544 // INIT_WORK(&priv->reset_wq, (void(*)(void*)) rtl8192_restart);
2545 INIT_WORK(&priv->reset_wq, rtl8192_restart);
2546 // INIT_DELAYED_WORK(&priv->watch_dog_wq, hal_dm_watchdog);
2547 INIT_DELAYED_WORK(&priv->watch_dog_wq, rtl819x_watchdog_wqcallback);
2548 INIT_DELAYED_WORK(&priv->txpower_tracking_wq, dm_txpower_trackingcallback);
2549 INIT_DELAYED_WORK(&priv->rfpath_check_wq, dm_rf_pathcheck_workitemcallback);
2550 INIT_DELAYED_WORK(&priv->update_beacon_wq, rtl8192_update_beacon);
2551 //INIT_WORK(&priv->SwChnlWorkItem, rtl8192_SwChnl_WorkItem);
2552 //INIT_WORK(&priv->SetBWModeWorkItem, rtl8192_SetBWModeWorkItem);
2553 INIT_WORK(&priv->qos_activate, rtl8192_qos_activate);
2554 INIT_DELAYED_WORK(&priv->ieee80211->hw_wakeup_wq,(void*) rtl8192_hw_wakeup_wq);
2555 INIT_DELAYED_WORK(&priv->ieee80211->hw_sleep_wq,(void*) rtl8192_hw_sleep_wq);
2557 tasklet_init(&priv->irq_rx_tasklet,
2558 (void(*)(unsigned long))rtl8192_irq_rx_tasklet,
2559 (unsigned long)priv);
2560 tasklet_init(&priv->irq_tx_tasklet,
2561 (void(*)(unsigned long))rtl8192_irq_tx_tasklet,
2562 (unsigned long)priv);
2563 tasklet_init(&priv->irq_prepare_beacon_tasklet,
2564 (void(*)(unsigned long))rtl8192_prepare_beacon,
2565 (unsigned long)priv);
2568 static void rtl8192_get_eeprom_size(struct net_device* dev)
2571 struct r8192_priv *priv = ieee80211_priv(dev);
2572 RT_TRACE(COMP_INIT, "===========>%s()\n", __FUNCTION__);
2573 curCR = read_nic_dword(dev, EPROM_CMD);
2574 RT_TRACE(COMP_INIT, "read from Reg Cmd9346CR(%x):%x\n", EPROM_CMD, curCR);
2575 //whether need I consider BIT5?
2576 priv->epromtype = (curCR & EPROM_CMD_9356SEL) ? EPROM_93c56 : EPROM_93c46;
2577 RT_TRACE(COMP_INIT, "<===========%s(), epromtype:%d\n", __FUNCTION__, priv->epromtype);
2581 * used to swap endian. as ntohl & htonl are not
2582 * neccessary to swap endian, so use this instead.
2584 static inline u16 endian_swap(u16* data)
2587 *data = (tmp >> 8) | (tmp << 8);
2592 * Adapter->EEPROMAddressSize should be set before this function call.
2593 * EEPROM address size can be got through GetEEPROMSize8185()
2595 static void rtl8192_read_eeprom_info(struct net_device* dev)
2597 struct r8192_priv *priv = ieee80211_priv(dev);
2601 u8 ICVer8192, ICVer8256;
2603 u16 i,usValue, IC_Version;
2607 u8 EepromTxPower[100];
2609 u8 bMac_Tmp_Addr[6] = {0x00, 0xe0, 0x4c, 0x00, 0x00, 0x01};
2610 RT_TRACE(COMP_INIT, "====> rtl8192_read_eeprom_info\n");
2613 // TODO: I don't know if we need to apply EF function to EEPROM read function
2615 //2 Read EEPROM ID to make sure autoload is success
2616 EEPROMId = eprom_read(dev, 0);
2617 if( EEPROMId != RTL8190_EEPROM_ID )
2619 RT_TRACE(COMP_ERR, "EEPROM ID is invalid:%x, %x\n", EEPROMId, RTL8190_EEPROM_ID);
2620 priv->AutoloadFailFlag=true;
2624 priv->AutoloadFailFlag=false;
2628 // Assign Chip Version ID
2630 // Read IC Version && Channel Plan
2631 if(!priv->AutoloadFailFlag)
2634 priv->eeprom_vid = eprom_read(dev, (EEPROM_VID >> 1));
2635 priv->eeprom_did = eprom_read(dev, (EEPROM_DID >> 1));
2637 usValue = eprom_read(dev, (u16)(EEPROM_Customer_ID>>1)) >> 8 ;
2638 priv->eeprom_CustomerID = (u8)( usValue & 0xff);
2639 usValue = eprom_read(dev, (EEPROM_ICVersion_ChannelPlan>>1));
2640 priv->eeprom_ChannelPlan = usValue&0xff;
2641 IC_Version = ((usValue&0xff00)>>8);
2644 priv->card_8192_version = (VERSION_8190)(IC_Version);
2647 ICVer8192 = (IC_Version&0xf); //bit0~3; 1:A cut, 2:B cut, 3:C cut...
2648 ICVer8256 = ((IC_Version&0xf0)>>4);//bit4~6, bit7 reserved for other RF chip; 1:A cut, 2:B cut, 3:C cut...
2649 RT_TRACE(COMP_INIT, "\nICVer8192 = 0x%x\n", ICVer8192);
2650 RT_TRACE(COMP_INIT, "\nICVer8256 = 0x%x\n", ICVer8256);
2651 if(ICVer8192 == 0x2) //B-cut
2653 if(ICVer8256 == 0x5) //E-cut
2654 priv->card_8192_version= VERSION_8190_BE;
2658 switch(priv->card_8192_version)
2660 case VERSION_8190_BD:
2661 case VERSION_8190_BE:
2664 priv->card_8192_version = VERSION_8190_BD;
2667 RT_TRACE(COMP_INIT, "\nIC Version = 0x%x\n", priv->card_8192_version);
2671 priv->card_8192_version = VERSION_8190_BD;
2672 priv->eeprom_vid = 0;
2673 priv->eeprom_did = 0;
2674 priv->eeprom_CustomerID = 0;
2675 priv->eeprom_ChannelPlan = 0;
2676 RT_TRACE(COMP_INIT, "\nIC Version = 0x%x\n", 0xff);
2679 RT_TRACE(COMP_INIT, "EEPROM VID = 0x%4x\n", priv->eeprom_vid);
2680 RT_TRACE(COMP_INIT, "EEPROM DID = 0x%4x\n", priv->eeprom_did);
2681 RT_TRACE(COMP_INIT,"EEPROM Customer ID: 0x%2x\n", priv->eeprom_CustomerID);
2683 //2 Read Permanent MAC address
2684 if(!priv->AutoloadFailFlag)
2686 for(i = 0; i < 6; i += 2)
2688 usValue = eprom_read(dev, (u16) ((EEPROM_NODE_ADDRESS_BYTE_0+i)>>1));
2689 *(u16*)(&dev->dev_addr[i]) = usValue;
2692 // when auto load failed, the last address byte set to be a random one.
2693 // added by david woo.2007/11/7
2694 memcpy(dev->dev_addr, bMac_Tmp_Addr, 6);
2697 RT_TRACE(COMP_INIT, "Permanent Address = %pM\n", dev->dev_addr);
2699 //2 TX Power Check EEPROM Fail or not
2700 if(priv->card_8192_version > VERSION_8190_BD) {
2701 priv->bTXPowerDataReadFromEEPORM = true;
2703 priv->bTXPowerDataReadFromEEPORM = false;
2706 // 2007/11/15 MH 8190PCI Default=2T4R, 8192PCIE default=1T2R
2707 priv->rf_type = RTL819X_DEFAULT_RF_TYPE;
2709 if(priv->card_8192_version > VERSION_8190_BD)
2711 // Read RF-indication and Tx Power gain index diff of legacy to HT OFDM rate.
2712 if(!priv->AutoloadFailFlag)
2714 tempval = (eprom_read(dev, (EEPROM_RFInd_PowerDiff>>1))) & 0xff;
2715 priv->EEPROMLegacyHTTxPowerDiff = tempval & 0xf; // bit[3:0]
2717 if (tempval&0x80) //RF-indication, bit[7]
2718 priv->rf_type = RF_1T2R;
2720 priv->rf_type = RF_2T4R;
2724 priv->EEPROMLegacyHTTxPowerDiff = EEPROM_Default_LegacyHTTxPowerDiff;
2726 RT_TRACE(COMP_INIT, "EEPROMLegacyHTTxPowerDiff = %d\n",
2727 priv->EEPROMLegacyHTTxPowerDiff);
2729 // Read ThermalMeter from EEPROM
2730 if(!priv->AutoloadFailFlag)
2732 priv->EEPROMThermalMeter = (u8)(((eprom_read(dev, (EEPROM_ThermalMeter>>1))) & 0xff00)>>8);
2736 priv->EEPROMThermalMeter = EEPROM_Default_ThermalMeter;
2738 RT_TRACE(COMP_INIT, "ThermalMeter = %d\n", priv->EEPROMThermalMeter);
2739 //vivi, for tx power track
2740 priv->TSSI_13dBm = priv->EEPROMThermalMeter *100;
2742 if(priv->epromtype == EPROM_93c46)
2744 // Read antenna tx power offset of B/C/D to A and CrystalCap from EEPROM
2745 if(!priv->AutoloadFailFlag)
2747 usValue = eprom_read(dev, (EEPROM_TxPwDiff_CrystalCap>>1));
2748 priv->EEPROMAntPwDiff = (usValue&0x0fff);
2749 priv->EEPROMCrystalCap = (u8)((usValue&0xf000)>>12);
2753 priv->EEPROMAntPwDiff = EEPROM_Default_AntTxPowerDiff;
2754 priv->EEPROMCrystalCap = EEPROM_Default_TxPwDiff_CrystalCap;
2756 RT_TRACE(COMP_INIT, "EEPROMAntPwDiff = %d\n", priv->EEPROMAntPwDiff);
2757 RT_TRACE(COMP_INIT, "EEPROMCrystalCap = %d\n", priv->EEPROMCrystalCap);
2760 // Get per-channel Tx Power Level
2762 for(i=0; i<14; i+=2)
2764 if(!priv->AutoloadFailFlag)
2766 usValue = eprom_read(dev, (u16) ((EEPROM_TxPwIndex_CCK+i)>>1) );
2770 usValue = EEPROM_Default_TxPower;
2772 *((u16*)(&priv->EEPROMTxPowerLevelCCK[i])) = usValue;
2773 RT_TRACE(COMP_INIT,"CCK Tx Power Level, Index %d = 0x%02x\n", i, priv->EEPROMTxPowerLevelCCK[i]);
2774 RT_TRACE(COMP_INIT, "CCK Tx Power Level, Index %d = 0x%02x\n", i+1, priv->EEPROMTxPowerLevelCCK[i+1]);
2776 for(i=0; i<14; i+=2)
2778 if(!priv->AutoloadFailFlag)
2780 usValue = eprom_read(dev, (u16) ((EEPROM_TxPwIndex_OFDM_24G+i)>>1) );
2784 usValue = EEPROM_Default_TxPower;
2786 *((u16*)(&priv->EEPROMTxPowerLevelOFDM24G[i])) = usValue;
2787 RT_TRACE(COMP_INIT, "OFDM 2.4G Tx Power Level, Index %d = 0x%02x\n", i, priv->EEPROMTxPowerLevelOFDM24G[i]);
2788 RT_TRACE(COMP_INIT, "OFDM 2.4G Tx Power Level, Index %d = 0x%02x\n", i+1, priv->EEPROMTxPowerLevelOFDM24G[i+1]);
2791 else if(priv->epromtype== EPROM_93c56)
2794 // Read CrystalCap from EEPROM
2795 if(!priv->AutoloadFailFlag)
2797 priv->EEPROMAntPwDiff = EEPROM_Default_AntTxPowerDiff;
2798 priv->EEPROMCrystalCap = (u8)(((eprom_read(dev, (EEPROM_C56_CrystalCap>>1))) & 0xf000)>>12);
2802 priv->EEPROMAntPwDiff = EEPROM_Default_AntTxPowerDiff;
2803 priv->EEPROMCrystalCap = EEPROM_Default_TxPwDiff_CrystalCap;
2805 RT_TRACE(COMP_INIT,"EEPROMAntPwDiff = %d\n", priv->EEPROMAntPwDiff);
2806 RT_TRACE(COMP_INIT, "EEPROMCrystalCap = %d\n", priv->EEPROMCrystalCap);
2808 // Get Tx Power Level by Channel
2809 if(!priv->AutoloadFailFlag)
2811 // Read Tx power of Channel 1 ~ 14 from EEPROM.
2812 for(i = 0; i < 12; i+=2)
2815 offset = EEPROM_C56_RfA_CCK_Chnl1_TxPwIndex + i;
2817 offset = EEPROM_C56_RfC_CCK_Chnl1_TxPwIndex + i - 6;
2818 usValue = eprom_read(dev, (offset>>1));
2819 *((u16*)(&EepromTxPower[i])) = usValue;
2822 for(i = 0; i < 12; i++)
2825 priv->EEPROMRfACCKChnl1TxPwLevel[i] = EepromTxPower[i];
2826 else if ((i >=3 )&&(i <= 5))
2827 priv->EEPROMRfAOfdmChnlTxPwLevel[i-3] = EepromTxPower[i];
2828 else if ((i >=6 )&&(i <= 8))
2829 priv->EEPROMRfCCCKChnl1TxPwLevel[i-6] = EepromTxPower[i];
2831 priv->EEPROMRfCOfdmChnlTxPwLevel[i-9] = EepromTxPower[i];
2836 priv->EEPROMRfACCKChnl1TxPwLevel[0] = EEPROM_Default_TxPowerLevel;
2837 priv->EEPROMRfACCKChnl1TxPwLevel[1] = EEPROM_Default_TxPowerLevel;
2838 priv->EEPROMRfACCKChnl1TxPwLevel[2] = EEPROM_Default_TxPowerLevel;
2840 priv->EEPROMRfAOfdmChnlTxPwLevel[0] = EEPROM_Default_TxPowerLevel;
2841 priv->EEPROMRfAOfdmChnlTxPwLevel[1] = EEPROM_Default_TxPowerLevel;
2842 priv->EEPROMRfAOfdmChnlTxPwLevel[2] = EEPROM_Default_TxPowerLevel;
2844 priv->EEPROMRfCCCKChnl1TxPwLevel[0] = EEPROM_Default_TxPowerLevel;
2845 priv->EEPROMRfCCCKChnl1TxPwLevel[1] = EEPROM_Default_TxPowerLevel;
2846 priv->EEPROMRfCCCKChnl1TxPwLevel[2] = EEPROM_Default_TxPowerLevel;
2848 priv->EEPROMRfCOfdmChnlTxPwLevel[0] = EEPROM_Default_TxPowerLevel;
2849 priv->EEPROMRfCOfdmChnlTxPwLevel[1] = EEPROM_Default_TxPowerLevel;
2850 priv->EEPROMRfCOfdmChnlTxPwLevel[2] = EEPROM_Default_TxPowerLevel;
2852 RT_TRACE(COMP_INIT, "priv->EEPROMRfACCKChnl1TxPwLevel[0] = 0x%x\n", priv->EEPROMRfACCKChnl1TxPwLevel[0]);
2853 RT_TRACE(COMP_INIT, "priv->EEPROMRfACCKChnl1TxPwLevel[1] = 0x%x\n", priv->EEPROMRfACCKChnl1TxPwLevel[1]);
2854 RT_TRACE(COMP_INIT, "priv->EEPROMRfACCKChnl1TxPwLevel[2] = 0x%x\n", priv->EEPROMRfACCKChnl1TxPwLevel[2]);
2855 RT_TRACE(COMP_INIT, "priv->EEPROMRfAOfdmChnlTxPwLevel[0] = 0x%x\n", priv->EEPROMRfAOfdmChnlTxPwLevel[0]);
2856 RT_TRACE(COMP_INIT, "priv->EEPROMRfAOfdmChnlTxPwLevel[1] = 0x%x\n", priv->EEPROMRfAOfdmChnlTxPwLevel[1]);
2857 RT_TRACE(COMP_INIT, "priv->EEPROMRfAOfdmChnlTxPwLevel[2] = 0x%x\n", priv->EEPROMRfAOfdmChnlTxPwLevel[2]);
2858 RT_TRACE(COMP_INIT, "priv->EEPROMRfCCCKChnl1TxPwLevel[0] = 0x%x\n", priv->EEPROMRfCCCKChnl1TxPwLevel[0]);
2859 RT_TRACE(COMP_INIT, "priv->EEPROMRfCCCKChnl1TxPwLevel[1] = 0x%x\n", priv->EEPROMRfCCCKChnl1TxPwLevel[1]);
2860 RT_TRACE(COMP_INIT, "priv->EEPROMRfCCCKChnl1TxPwLevel[2] = 0x%x\n", priv->EEPROMRfCCCKChnl1TxPwLevel[2]);
2861 RT_TRACE(COMP_INIT, "priv->EEPROMRfCOfdmChnlTxPwLevel[0] = 0x%x\n", priv->EEPROMRfCOfdmChnlTxPwLevel[0]);
2862 RT_TRACE(COMP_INIT, "priv->EEPROMRfCOfdmChnlTxPwLevel[1] = 0x%x\n", priv->EEPROMRfCOfdmChnlTxPwLevel[1]);
2863 RT_TRACE(COMP_INIT, "priv->EEPROMRfCOfdmChnlTxPwLevel[2] = 0x%x\n", priv->EEPROMRfCOfdmChnlTxPwLevel[2]);
2868 // Update HAL variables.
2870 if(priv->epromtype == EPROM_93c46)
2874 priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelCCK[i];
2875 priv->TxPowerLevelOFDM24G[i] = priv->EEPROMTxPowerLevelOFDM24G[i];
2877 priv->LegacyHTTxPowerDiff = priv->EEPROMLegacyHTTxPowerDiff;
2878 // Antenna B gain offset to antenna A, bit0~3
2879 priv->AntennaTxPwDiff[0] = (priv->EEPROMAntPwDiff & 0xf);
2880 // Antenna C gain offset to antenna A, bit4~7
2881 priv->AntennaTxPwDiff[1] = ((priv->EEPROMAntPwDiff & 0xf0)>>4);
2882 // Antenna D gain offset to antenna A, bit8~11
2883 priv->AntennaTxPwDiff[2] = ((priv->EEPROMAntPwDiff & 0xf00)>>8);
2884 // CrystalCap, bit12~15
2885 priv->CrystalCap = priv->EEPROMCrystalCap;
2886 // ThermalMeter, bit0~3 for RFIC1, bit4~7 for RFIC2
2887 priv->ThermalMeter[0] = (priv->EEPROMThermalMeter & 0xf);
2888 priv->ThermalMeter[1] = ((priv->EEPROMThermalMeter & 0xf0)>>4);
2890 else if(priv->epromtype == EPROM_93c56)
2892 //char cck_pwr_diff_a=0, cck_pwr_diff_c=0;
2894 //cck_pwr_diff_a = pHalData->EEPROMRfACCKChnl7TxPwLevel - pHalData->EEPROMRfAOfdmChnlTxPwLevel[1];
2895 //cck_pwr_diff_c = pHalData->EEPROMRfCCCKChnl7TxPwLevel - pHalData->EEPROMRfCOfdmChnlTxPwLevel[1];
2896 for(i=0; i<3; i++) // channel 1~3 use the same Tx Power Level.
2898 priv->TxPowerLevelCCK_A[i] = priv->EEPROMRfACCKChnl1TxPwLevel[0];
2899 priv->TxPowerLevelOFDM24G_A[i] = priv->EEPROMRfAOfdmChnlTxPwLevel[0];
2900 priv->TxPowerLevelCCK_C[i] = priv->EEPROMRfCCCKChnl1TxPwLevel[0];
2901 priv->TxPowerLevelOFDM24G_C[i] = priv->EEPROMRfCOfdmChnlTxPwLevel[0];
2903 for(i=3; i<9; i++) // channel 4~9 use the same Tx Power Level
2905 priv->TxPowerLevelCCK_A[i] = priv->EEPROMRfACCKChnl1TxPwLevel[1];
2906 priv->TxPowerLevelOFDM24G_A[i] = priv->EEPROMRfAOfdmChnlTxPwLevel[1];
2907 priv->TxPowerLevelCCK_C[i] = priv->EEPROMRfCCCKChnl1TxPwLevel[1];
2908 priv->TxPowerLevelOFDM24G_C[i] = priv->EEPROMRfCOfdmChnlTxPwLevel[1];
2910 for(i=9; i<14; i++) // channel 10~14 use the same Tx Power Level
2912 priv->TxPowerLevelCCK_A[i] = priv->EEPROMRfACCKChnl1TxPwLevel[2];
2913 priv->TxPowerLevelOFDM24G_A[i] = priv->EEPROMRfAOfdmChnlTxPwLevel[2];
2914 priv->TxPowerLevelCCK_C[i] = priv->EEPROMRfCCCKChnl1TxPwLevel[2];
2915 priv->TxPowerLevelOFDM24G_C[i] = priv->EEPROMRfCOfdmChnlTxPwLevel[2];
2918 RT_TRACE(COMP_INIT, "priv->TxPowerLevelCCK_A[%d] = 0x%x\n", i, priv->TxPowerLevelCCK_A[i]);
2920 RT_TRACE(COMP_INIT,"priv->TxPowerLevelOFDM24G_A[%d] = 0x%x\n", i, priv->TxPowerLevelOFDM24G_A[i]);
2922 RT_TRACE(COMP_INIT, "priv->TxPowerLevelCCK_C[%d] = 0x%x\n", i, priv->TxPowerLevelCCK_C[i]);
2924 RT_TRACE(COMP_INIT, "priv->TxPowerLevelOFDM24G_C[%d] = 0x%x\n", i, priv->TxPowerLevelOFDM24G_C[i]);
2925 priv->LegacyHTTxPowerDiff = priv->EEPROMLegacyHTTxPowerDiff;
2926 priv->AntennaTxPwDiff[0] = 0;
2927 priv->AntennaTxPwDiff[1] = 0;
2928 priv->AntennaTxPwDiff[2] = 0;
2929 priv->CrystalCap = priv->EEPROMCrystalCap;
2930 // ThermalMeter, bit0~3 for RFIC1, bit4~7 for RFIC2
2931 priv->ThermalMeter[0] = (priv->EEPROMThermalMeter & 0xf);
2932 priv->ThermalMeter[1] = ((priv->EEPROMThermalMeter & 0xf0)>>4);
2936 if(priv->rf_type == RF_1T2R)
2938 RT_TRACE(COMP_INIT, "\n1T2R config\n");
2940 else if (priv->rf_type == RF_2T4R)
2942 RT_TRACE(COMP_INIT, "\n2T4R config\n");
2945 // 2008/01/16 MH We can only know RF type in the function. So we have to init
2946 // DIG RATR table again.
2947 init_rate_adaptive(dev);
2949 //1 Make a copy for following variables and we can change them if we want
2951 priv->rf_chip= RF_8256;
2953 if(priv->RegChannelPlan == 0xf)
2955 priv->ChannelPlan = priv->eeprom_ChannelPlan;
2959 priv->ChannelPlan = priv->RegChannelPlan;
2963 // Used PID and DID to Set CustomerID
2965 if( priv->eeprom_vid == 0x1186 && priv->eeprom_did == 0x3304 )
2967 priv->CustomerID = RT_CID_DLINK;
2970 switch(priv->eeprom_CustomerID)
2972 case EEPROM_CID_DEFAULT:
2973 priv->CustomerID = RT_CID_DEFAULT;
2975 case EEPROM_CID_CAMEO:
2976 priv->CustomerID = RT_CID_819x_CAMEO;
2978 case EEPROM_CID_RUNTOP:
2979 priv->CustomerID = RT_CID_819x_RUNTOP;
2981 case EEPROM_CID_NetCore:
2982 priv->CustomerID = RT_CID_819x_Netcore;
2984 case EEPROM_CID_TOSHIBA: // Merge by Jacken, 2008/01/31
2985 priv->CustomerID = RT_CID_TOSHIBA;
2986 if(priv->eeprom_ChannelPlan&0x80)
2987 priv->ChannelPlan = priv->eeprom_ChannelPlan&0x7f;
2989 priv->ChannelPlan = 0x0;
2990 RT_TRACE(COMP_INIT, "Toshiba ChannelPlan = 0x%x\n",
2993 case EEPROM_CID_Nettronix:
2994 priv->ScanDelay = 100; //cosa add for scan
2995 priv->CustomerID = RT_CID_Nettronix;
2997 case EEPROM_CID_Pronet:
2998 priv->CustomerID = RT_CID_PRONET;
3000 case EEPROM_CID_DLINK:
3001 priv->CustomerID = RT_CID_DLINK;
3004 case EEPROM_CID_WHQL:
3005 //Adapter->bInHctTest = TRUE;//do not supported
3007 //priv->bSupportTurboMode = FALSE;
3008 //priv->bAutoTurboBy8186 = FALSE;
3010 //pMgntInfo->PowerSaveControl.bInactivePs = FALSE;
3011 //pMgntInfo->PowerSaveControl.bIPSModeBackup = FALSE;
3012 //pMgntInfo->PowerSaveControl.bLeisurePs = FALSE;
3016 // value from RegCustomerID
3020 //Avoid the channel plan array overflow, by Bruce, 2007-08-27.
3021 if(priv->ChannelPlan > CHANNEL_PLAN_LEN - 1)
3022 priv->ChannelPlan = 0; //FCC
3024 switch(priv->CustomerID)
3026 case RT_CID_DEFAULT:
3028 priv->LedStrategy = HW_LED;
3031 priv->LedStrategy = SW_LED_MODE1;
3036 case RT_CID_819x_CAMEO:
3037 priv->LedStrategy = SW_LED_MODE2;
3040 case RT_CID_819x_RUNTOP:
3041 priv->LedStrategy = SW_LED_MODE3;
3044 case RT_CID_819x_Netcore:
3045 priv->LedStrategy = SW_LED_MODE4;
3048 case RT_CID_Nettronix:
3049 priv->LedStrategy = SW_LED_MODE5;
3053 priv->LedStrategy = SW_LED_MODE6;
3056 case RT_CID_TOSHIBA: //Modify by Jacken 2008/01/31
3062 priv->LedStrategy = HW_LED;
3065 priv->LedStrategy = SW_LED_MODE1;
3072 if( priv->eeprom_vid == 0x1186 && priv->eeprom_did == 0x3304)
3073 priv->ieee80211->bSupportRemoteWakeUp = true;
3075 priv->ieee80211->bSupportRemoteWakeUp = false;
3078 RT_TRACE(COMP_INIT, "RegChannelPlan(%d)\n", priv->RegChannelPlan);
3079 RT_TRACE(COMP_INIT, "ChannelPlan = %d \n", priv->ChannelPlan);
3080 RT_TRACE(COMP_INIT, "LedStrategy = %d \n", priv->LedStrategy);
3081 RT_TRACE(COMP_TRACE, "<==== ReadAdapterInfo\n");
3087 static short rtl8192_get_channel_map(struct net_device * dev)
3089 struct r8192_priv *priv = ieee80211_priv(dev);
3090 #ifdef ENABLE_DOT11D
3091 if(priv->ChannelPlan> COUNTRY_CODE_GLOBAL_DOMAIN){
3092 printk("rtl8180_init:Error channel plan! Set to default.\n");
3093 priv->ChannelPlan= 0;
3095 RT_TRACE(COMP_INIT, "Channel plan is %d\n",priv->ChannelPlan);
3097 rtl819x_set_channel_map(priv->ChannelPlan, priv);
3100 //Set Default Channel Plan
3102 DMESG("No channels, aborting");
3106 priv->ChannelPlan= 0;//hikaru
3107 // set channels 1..14 allowed in given locale
3108 for (i=1; i<=14; i++) {
3109 (priv->ieee80211->channel_map)[i] = (u8)(ch & 0x01);
3116 static short rtl8192_init(struct net_device *dev)
3118 struct r8192_priv *priv = ieee80211_priv(dev);
3119 memset(&(priv->stats),0,sizeof(struct Stats));
3120 rtl8192_init_priv_variable(dev);
3121 rtl8192_init_priv_lock(priv);
3122 rtl8192_init_priv_task(dev);
3123 rtl8192_get_eeprom_size(dev);
3124 rtl8192_read_eeprom_info(dev);
3125 rtl8192_get_channel_map(dev);
3127 init_timer(&priv->watch_dog_timer);
3128 priv->watch_dog_timer.data = (unsigned long)dev;
3129 priv->watch_dog_timer.function = watch_dog_timer_callback;
3130 #if defined(IRQF_SHARED)
3131 if(request_irq(dev->irq, (void*)rtl8192_interrupt, IRQF_SHARED, dev->name, dev)){
3133 if(request_irq(dev->irq, (void *)rtl8192_interrupt, SA_SHIRQ, dev->name, dev)){
3135 printk("Error allocating IRQ %d",dev->irq);
3139 printk("IRQ %d",dev->irq);
3141 if(rtl8192_pci_initdescring(dev)!=0){
3142 printk("Endopoints initialization failed");
3146 //rtl8192_rx_enable(dev);
3147 //rtl8192_adapter_start(dev);
3152 * Actually only set RRSR, RATR and BW_OPMODE registers
3153 * not to do all the hw config as its name says
3154 * This part need to modified according to the rate set we filtered
3156 static void rtl8192_hwconfig(struct net_device* dev)
3158 u32 regRATR = 0, regRRSR = 0;
3159 u8 regBwOpMode = 0, regTmp = 0;
3160 struct r8192_priv *priv = ieee80211_priv(dev);
3162 // Set RRSR, RATR, and BW_OPMODE registers
3164 switch(priv->ieee80211->mode)
3166 case WIRELESS_MODE_B:
3167 regBwOpMode = BW_OPMODE_20MHZ;
3168 regRATR = RATE_ALL_CCK;
3169 regRRSR = RATE_ALL_CCK;
3171 case WIRELESS_MODE_A:
3172 regBwOpMode = BW_OPMODE_5G |BW_OPMODE_20MHZ;
3173 regRATR = RATE_ALL_OFDM_AG;
3174 regRRSR = RATE_ALL_OFDM_AG;
3176 case WIRELESS_MODE_G:
3177 regBwOpMode = BW_OPMODE_20MHZ;
3178 regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
3179 regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
3181 case WIRELESS_MODE_AUTO:
3182 case WIRELESS_MODE_N_24G:
3183 // It support CCK rate by default.
3184 // CCK rate will be filtered out only when associated AP does not support it.
3185 regBwOpMode = BW_OPMODE_20MHZ;
3186 regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
3187 regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
3189 case WIRELESS_MODE_N_5G:
3190 regBwOpMode = BW_OPMODE_5G;
3191 regRATR = RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
3192 regRRSR = RATE_ALL_OFDM_AG;
3196 write_nic_byte(dev, BW_OPMODE, regBwOpMode);
3199 ratr_value = regRATR;
3200 if (priv->rf_type == RF_1T2R)
3202 ratr_value &= ~(RATE_ALL_OFDM_2SS);
3204 write_nic_dword(dev, RATR0, ratr_value);
3205 write_nic_byte(dev, UFWP, 1);
3207 regTmp = read_nic_byte(dev, 0x313);
3208 regRRSR = ((regTmp) << 24) | (regRRSR & 0x00ffffff);
3209 write_nic_dword(dev, RRSR, regRRSR);
3212 // Set Retry Limit here
3214 write_nic_word(dev, RETRY_LIMIT,
3215 priv->ShortRetryLimit << RETRY_LIMIT_SHORT_SHIFT |
3216 priv->LongRetryLimit << RETRY_LIMIT_LONG_SHIFT);
3217 // Set Contention Window here
3221 // Set Tx Antenna including Feedback control
3223 // Set Auto Rate fallback control
3229 static RT_STATUS rtl8192_adapter_start(struct net_device *dev)
3231 struct r8192_priv *priv = ieee80211_priv(dev);
3232 // struct ieee80211_device *ieee = priv->ieee80211;
3234 RT_STATUS rtStatus = RT_STATUS_SUCCESS;
3238 u8 ICVersion,SwitchingRegulatorOutput;
3240 bool bfirmwareok = true;
3244 u32 tmpRegA, tmpRegC, TempCCk;
3247 RT_TRACE(COMP_INIT, "====>%s()\n", __FUNCTION__);
3248 priv->being_init_adapter = true;
3249 rtl8192_pci_resetdescring(dev);
3250 // 2007/11/02 MH Before initalizing RF. We can not use FW to do RF-R/W.
3251 priv->Rf_Mode = RF_OP_By_SW_3wire;
3254 if(priv->ResetProgress == RESET_TYPE_NORESET)
3256 write_nic_byte(dev, ANAPAR, 0x37);
3257 // Accordign to designer's explain, LBUS active will never > 10ms. We delay 10ms
3258 // Joseph increae the time to prevent firmware download fail
3262 //PlatformSleepUs(10000);
3263 // For any kind of InitializeAdapter process, we shall use system now!!
3264 priv->pFirmware->firmware_status = FW_STATUS_0_INIT;
3266 // Set to eRfoff in order not to count receive count.
3267 if(priv->RegRfOff == TRUE)
3268 priv->ieee80211->eRFPowerState = eRfOff;
3271 //3 //Config CPUReset Register
3273 //3 Firmware Reset Or Not
3274 ulRegRead = read_nic_dword(dev, CPU_GEN);
3275 if(priv->pFirmware->firmware_status == FW_STATUS_0_INIT)
3276 { //called from MPInitialized. do nothing
3277 ulRegRead |= CPU_GEN_SYSTEM_RESET;
3278 }else if(priv->pFirmware->firmware_status == FW_STATUS_5_READY)
3279 ulRegRead |= CPU_GEN_FIRMWARE_RESET; // Called from MPReset
3281 RT_TRACE(COMP_ERR, "ERROR in %s(): undefined firmware state(%d)\n", __FUNCTION__, priv->pFirmware->firmware_status);
3284 //2008.06.03, for WOL 90 hw bug
3285 ulRegRead &= (~(CPU_GEN_GPIO_UART));
3288 write_nic_dword(dev, CPU_GEN, ulRegRead);
3294 //3 //Fix the issue of E-cut high temperature issue
3297 ICVersion = read_nic_byte(dev, IC_VERRSION);
3298 if(ICVersion >= 0x4) //E-cut only
3300 // HW SD suggest that we should not wirte this register too often, so driver
3301 // should readback this register. This register will be modified only when
3303 SwitchingRegulatorOutput = read_nic_byte(dev, SWREGULATOR);
3304 if(SwitchingRegulatorOutput != 0xb8)
3306 write_nic_byte(dev, SWREGULATOR, 0xa8);
3308 write_nic_byte(dev, SWREGULATOR, 0xb8);
3315 //3// Initialize BB before MAC
3317 RT_TRACE(COMP_INIT, "BB Config Start!\n");
3318 rtStatus = rtl8192_BBConfig(dev);
3319 if(rtStatus != RT_STATUS_SUCCESS)
3321 RT_TRACE(COMP_ERR, "BB Config failed\n");
3324 RT_TRACE(COMP_INIT,"BB Config Finished!\n");
3326 //3//Set Loopback mode or Normal mode
3328 //2006.12.13 by emily. Note!We should not merge these two CPU_GEN register writings
3329 // because setting of System_Reset bit reset MAC to default transmission mode.
3330 //Loopback mode or not
3331 priv->LoopbackMode = RTL819X_NO_LOOPBACK;
3332 //priv->LoopbackMode = RTL819X_MAC_LOOPBACK;
3333 if(priv->ResetProgress == RESET_TYPE_NORESET)
3335 ulRegRead = read_nic_dword(dev, CPU_GEN);
3336 if(priv->LoopbackMode == RTL819X_NO_LOOPBACK)
3338 ulRegRead = ((ulRegRead & CPU_GEN_NO_LOOPBACK_MSK) | CPU_GEN_NO_LOOPBACK_SET);
3340 else if (priv->LoopbackMode == RTL819X_MAC_LOOPBACK )
3342 ulRegRead |= CPU_CCK_LOOPBACK;
3346 RT_TRACE(COMP_ERR,"Serious error: wrong loopback mode setting\n");
3349 //2008.06.03, for WOL
3350 //ulRegRead &= (~(CPU_GEN_GPIO_UART));
3351 write_nic_dword(dev, CPU_GEN, ulRegRead);
3353 // 2006.11.29. After reset cpu, we sholud wait for a second, otherwise, it may fail to write registers. Emily
3356 //3Set Hardware(Do nothing now)
3357 rtl8192_hwconfig(dev);
3358 //2=======================================================
3359 // Common Setting for all of the FPGA platform. (part 1)
3360 //2=======================================================
3361 // If there is changes, please make sure it applies to all of the FPGA version
3363 write_nic_byte(dev, CMDR, CR_RE|CR_TE);
3367 write_nic_byte(dev, PCIF, ((MXDMA2_NoLimit<<MXDMA2_RX_SHIFT) |
3368 (MXDMA2_NoLimit<<MXDMA2_TX_SHIFT) |
3372 write_nic_byte(dev, PCIF, ((MXDMA2_NoLimit<<MXDMA2_RX_SHIFT) |
3373 (MXDMA2_NoLimit<<MXDMA2_TX_SHIFT) ));
3377 write_nic_dword(dev, MAC0, ((u32*)dev->dev_addr)[0]);
3378 write_nic_word(dev, MAC4, ((u16*)(dev->dev_addr + 4))[0]);
3380 write_nic_dword(dev, RCR, priv->ReceiveConfig);
3382 //3 Initialize Number of Reserved Pages in Firmware Queue
3384 if(priv->bInHctTest)
3386 PlatformEFIOWrite4Byte(Adapter, RQPN1, NUM_OF_PAGE_IN_FW_QUEUE_BK_DTM << RSVD_FW_QUEUE_PAGE_BK_SHIFT |
3387 NUM_OF_PAGE_IN_FW_QUEUE_BE_DTM << RSVD_FW_QUEUE_PAGE_BE_SHIFT |
3388 NUM_OF_PAGE_IN_FW_QUEUE_VI_DTM << RSVD_FW_QUEUE_PAGE_VI_SHIFT |
3389 NUM_OF_PAGE_IN_FW_QUEUE_VO_DTM <<RSVD_FW_QUEUE_PAGE_VO_SHIFT);
3390 PlatformEFIOWrite4Byte(Adapter, RQPN2, NUM_OF_PAGE_IN_FW_QUEUE_MGNT << RSVD_FW_QUEUE_PAGE_MGNT_SHIFT);
3391 PlatformEFIOWrite4Byte(Adapter, RQPN3, APPLIED_RESERVED_QUEUE_IN_FW|
3392 NUM_OF_PAGE_IN_FW_QUEUE_BCN<<RSVD_FW_QUEUE_PAGE_BCN_SHIFT|
3393 NUM_OF_PAGE_IN_FW_QUEUE_PUB_DTM<<RSVD_FW_QUEUE_PAGE_PUB_SHIFT);
3398 write_nic_dword(dev, RQPN1, NUM_OF_PAGE_IN_FW_QUEUE_BK << RSVD_FW_QUEUE_PAGE_BK_SHIFT |
3399 NUM_OF_PAGE_IN_FW_QUEUE_BE << RSVD_FW_QUEUE_PAGE_BE_SHIFT |
3400 NUM_OF_PAGE_IN_FW_QUEUE_VI << RSVD_FW_QUEUE_PAGE_VI_SHIFT |
3401 NUM_OF_PAGE_IN_FW_QUEUE_VO <<RSVD_FW_QUEUE_PAGE_VO_SHIFT);
3402 write_nic_dword(dev, RQPN2, NUM_OF_PAGE_IN_FW_QUEUE_MGNT << RSVD_FW_QUEUE_PAGE_MGNT_SHIFT);
3403 write_nic_dword(dev, RQPN3, APPLIED_RESERVED_QUEUE_IN_FW|
3404 NUM_OF_PAGE_IN_FW_QUEUE_BCN<<RSVD_FW_QUEUE_PAGE_BCN_SHIFT|
3405 NUM_OF_PAGE_IN_FW_QUEUE_PUB<<RSVD_FW_QUEUE_PAGE_PUB_SHIFT);
3408 rtl8192_tx_enable(dev);
3409 rtl8192_rx_enable(dev);
3410 //3Set Response Rate Setting Register
3411 // CCK rate is supported by default.
3412 // CCK rate will be filtered out only when associated AP does not support it.
3413 ulRegRead = (0xFFF00000 & read_nic_dword(dev, RRSR)) | RATE_ALL_OFDM_AG | RATE_ALL_CCK;
3414 write_nic_dword(dev, RRSR, ulRegRead);
3415 write_nic_dword(dev, RATR0+4*7, (RATE_ALL_OFDM_AG | RATE_ALL_CCK));
3418 // TODO: (it value is only for FPGA version). need to be changed!!2006.12.18, by Emily
3419 write_nic_byte(dev, ACK_TIMEOUT, 0x30);
3421 //rtl8192_actset_wirelessmode(dev,priv->RegWirelessMode);
3422 if(priv->ResetProgress == RESET_TYPE_NORESET)
3423 rtl8192_SetWirelessMode(dev, priv->ieee80211->mode);
3424 //-----------------------------------------------------------------------------
3425 // Set up security related. 070106, by rcnjko:
3426 // 1. Clear all H/W keys.
3427 // 2. Enable H/W encryption/decryption.
3428 //-----------------------------------------------------------------------------
3429 CamResetAllEntry(dev);
3431 u8 SECR_value = 0x0;
3432 SECR_value |= SCR_TxEncEnable;
3433 SECR_value |= SCR_RxDecEnable;
3434 SECR_value |= SCR_NoSKMC;
3435 write_nic_byte(dev, SECR, SECR_value);
3438 write_nic_word(dev, ATIMWND, 2);
3439 write_nic_word(dev, BCN_INTERVAL, 100);
3440 for (i=0; i<QOS_QUEUE_NUM; i++)
3441 write_nic_dword(dev, WDCAPARA_ADD[i], 0x005e4332);
3443 // Switching regulator controller: This is set temporarily.
3444 // It's not sure if this can be removed in the future.
3445 // PJ advised to leave it by default.
3447 write_nic_byte(dev, 0xbe, 0xc0);
3449 //2=======================================================
3450 // Set PHY related configuration defined in MAC register bank
3451 //2=======================================================
3452 rtl8192_phy_configmac(dev);
3454 if (priv->card_8192_version > (u8) VERSION_8190_BD) {
3455 rtl8192_phy_getTxPower(dev);
3456 rtl8192_phy_setTxPower(dev, priv->chan);
3460 tmpvalue = read_nic_byte(dev, IC_VERRSION);
3461 priv->IC_Cut = tmpvalue;
3462 RT_TRACE(COMP_INIT, "priv->IC_Cut = 0x%x\n", priv->IC_Cut);
3463 if(priv->IC_Cut >= IC_VersionCut_D)
3465 //pHalData->bDcut = TRUE;
3466 if(priv->IC_Cut == IC_VersionCut_D)
3467 RT_TRACE(COMP_INIT, "D-cut\n");
3468 if(priv->IC_Cut == IC_VersionCut_E)
3470 RT_TRACE(COMP_INIT, "E-cut\n");
3471 // HW SD suggest that we should not wirte this register too often, so driver
3472 // should readback this register. This register will be modified only when
3478 //pHalData->bDcut = FALSE;
3479 RT_TRACE(COMP_INIT, "Before C-cut\n");
3484 RT_TRACE(COMP_INIT, "Load Firmware!\n");
3485 bfirmwareok = init_firmware(dev);
3486 if(bfirmwareok != true) {
3487 rtStatus = RT_STATUS_FAILURE;
3490 RT_TRACE(COMP_INIT, "Load Firmware finished!\n");
3493 if(priv->ResetProgress == RESET_TYPE_NORESET)
3495 RT_TRACE(COMP_INIT, "RF Config Started!\n");
3496 rtStatus = rtl8192_phy_RFConfig(dev);
3497 if(rtStatus != RT_STATUS_SUCCESS)
3499 RT_TRACE(COMP_ERR, "RF Config failed\n");
3502 RT_TRACE(COMP_INIT, "RF Config Finished!\n");
3504 rtl8192_phy_updateInitGain(dev);
3506 /*---- Set CCK and OFDM Block "ON"----*/
3507 rtl8192_setBBreg(dev, rFPGA0_RFMOD, bCCKEn, 0x1);
3508 rtl8192_setBBreg(dev, rFPGA0_RFMOD, bOFDMEn, 0x1);
3512 write_nic_byte(dev, 0x87, 0x0);
3515 //2008.06.03, for WOL
3516 ucRegRead = read_nic_byte(dev, GPE);
3518 write_nic_byte(dev, GPE, ucRegRead);
3520 ucRegRead = read_nic_byte(dev, GPO);
3522 write_nic_byte(dev, GPO, ucRegRead);
3525 //2=======================================================
3527 //2=======================================================
3531 if(priv->RegRfOff == TRUE)
3532 { // User disable RF via registry.
3533 RT_TRACE((COMP_INIT|COMP_RF|COMP_POWER), "%s(): Turn off RF for RegRfOff ----------\n",__FUNCTION__);
3534 MgntActSet_RF_State(dev, eRfOff, RF_CHANGE_BY_SW);
3535 #if 0//cosa, ask SD3 willis and he doesn't know what is this for
3536 // Those action will be discard in MgntActSet_RF_State because off the same state
3537 for(eRFPath = 0; eRFPath <pHalData->NumTotalRFPath; eRFPath++)
3538 PHY_SetRFReg(Adapter, (RF90_RADIO_PATH_E)eRFPath, 0x4, 0xC00, 0x0);
3541 else if(priv->ieee80211->RfOffReason > RF_CHANGE_BY_PS)
3542 { // H/W or S/W RF OFF before sleep.
3543 RT_TRACE((COMP_INIT|COMP_RF|COMP_POWER), "%s(): Turn off RF for RfOffReason(%d) ----------\n", __FUNCTION__,priv->ieee80211->RfOffReason);
3544 MgntActSet_RF_State(dev, eRfOff, priv->ieee80211->RfOffReason);
3546 else if(priv->ieee80211->RfOffReason >= RF_CHANGE_BY_IPS)
3547 { // H/W or S/W RF OFF before sleep.
3548 RT_TRACE((COMP_INIT|COMP_RF|COMP_POWER), "%s(): Turn off RF for RfOffReason(%d) ----------\n", __FUNCTION__,priv->ieee80211->RfOffReason);
3549 MgntActSet_RF_State(dev, eRfOff, priv->ieee80211->RfOffReason);
3553 RT_TRACE((COMP_INIT|COMP_RF|COMP_POWER), "%s(): RF-ON \n",__FUNCTION__);
3554 priv->ieee80211->eRFPowerState = eRfOn;
3555 priv->ieee80211->RfOffReason = 0;
3556 //DrvIFIndicateCurrentPhyStatus(Adapter);
3558 //Adapter->HalFunc.LedControlHandler(Adapter, LED_CTL_POWER_ON);
3561 // If inactive power mode is enabled, disable rf while in disconnected state.
3562 // But we should still tell upper layer we are in rf on state.
3563 // 2007.07.16, by shien chang.
3565 //if(!Adapter->bInHctTest)
3566 //IPSEnter(Adapter);
3573 // We can force firmware to do RF-R/W
3574 if(priv->ieee80211->FwRWRF)
3575 priv->Rf_Mode = RF_OP_By_FW;
3577 priv->Rf_Mode = RF_OP_By_SW_3wire;
3579 priv->Rf_Mode = RF_OP_By_SW_3wire;
3583 if(priv->ResetProgress == RESET_TYPE_NORESET)
3585 dm_initialize_txpower_tracking(dev);
3587 tmpRegA= rtl8192_QueryBBReg(dev,rOFDM0_XATxIQImbalance,bMaskDWord);
3588 tmpRegC= rtl8192_QueryBBReg(dev,rOFDM0_XCTxIQImbalance,bMaskDWord);
3590 if(priv->rf_type == RF_2T4R){
3591 for(i = 0; i<TxBBGainTableLength; i++)
3593 if(tmpRegA == priv->txbbgain_table[i].txbbgain_value)
3595 priv->rfa_txpowertrackingindex= (u8)i;
3596 priv->rfa_txpowertrackingindex_real= (u8)i;
3597 priv->rfa_txpowertracking_default = priv->rfa_txpowertrackingindex;
3602 for(i = 0; i<TxBBGainTableLength; i++)
3604 if(tmpRegC == priv->txbbgain_table[i].txbbgain_value)
3606 priv->rfc_txpowertrackingindex= (u8)i;
3607 priv->rfc_txpowertrackingindex_real= (u8)i;
3608 priv->rfc_txpowertracking_default = priv->rfc_txpowertrackingindex;
3612 TempCCk = rtl8192_QueryBBReg(dev, rCCK0_TxFilter1, bMaskByte2);
3614 for(i=0 ; i<CCKTxBBGainTableLength ; i++)
3616 if(TempCCk == priv->cck_txbbgain_table[i].ccktxbb_valuearray[0])
3618 priv->CCKPresentAttentuation_20Mdefault =(u8) i;
3622 priv->CCKPresentAttentuation_40Mdefault = 0;
3623 priv->CCKPresentAttentuation_difference = 0;
3624 priv->CCKPresentAttentuation = priv->CCKPresentAttentuation_20Mdefault;
3625 RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex_initial = %d\n", priv->rfa_txpowertrackingindex);
3626 RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex_real__initial = %d\n", priv->rfa_txpowertrackingindex_real);
3627 RT_TRACE(COMP_POWER_TRACKING, "priv->rfc_txpowertrackingindex_initial = %d\n", priv->rfc_txpowertrackingindex);
3628 RT_TRACE(COMP_POWER_TRACKING, "priv->rfc_txpowertrackingindex_real_initial = %d\n", priv->rfc_txpowertrackingindex_real);
3629 RT_TRACE(COMP_POWER_TRACKING, "priv->CCKPresentAttentuation_difference_initial = %d\n", priv->CCKPresentAttentuation_difference);
3630 RT_TRACE(COMP_POWER_TRACKING, "priv->CCKPresentAttentuation_initial = %d\n", priv->CCKPresentAttentuation);
3634 if(priv->ResetProgress == RESET_TYPE_NORESET)
3636 dm_initialize_txpower_tracking(dev);
3638 if(priv->IC_Cut >= IC_VersionCut_D)
3640 tmpRegA= rtl8192_QueryBBReg(dev,rOFDM0_XATxIQImbalance,bMaskDWord);
3641 tmpRegC= rtl8192_QueryBBReg(dev,rOFDM0_XCTxIQImbalance,bMaskDWord);
3642 for(i = 0; i<TxBBGainTableLength; i++)
3644 if(tmpRegA == priv->txbbgain_table[i].txbbgain_value)
3646 priv->rfa_txpowertrackingindex= (u8)i;
3647 priv->rfa_txpowertrackingindex_real= (u8)i;
3648 priv->rfa_txpowertracking_default = priv->rfa_txpowertrackingindex;
3653 TempCCk = rtl8192_QueryBBReg(dev, rCCK0_TxFilter1, bMaskByte2);
3655 for(i=0 ; i<CCKTxBBGainTableLength ; i++)
3657 if(TempCCk == priv->cck_txbbgain_table[i].ccktxbb_valuearray[0])
3659 priv->CCKPresentAttentuation_20Mdefault =(u8) i;
3663 priv->CCKPresentAttentuation_40Mdefault = 0;
3664 priv->CCKPresentAttentuation_difference = 0;
3665 priv->CCKPresentAttentuation = priv->CCKPresentAttentuation_20Mdefault;
3666 RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex_initial = %d\n", priv->rfa_txpowertrackingindex);
3667 RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex_real__initial = %d\n", priv->rfa_txpowertrackingindex_real);
3668 RT_TRACE(COMP_POWER_TRACKING, "priv->CCKPresentAttentuation_difference_initial = %d\n", priv->CCKPresentAttentuation_difference);
3669 RT_TRACE(COMP_POWER_TRACKING, "priv->CCKPresentAttentuation_initial = %d\n", priv->CCKPresentAttentuation);
3670 priv->btxpower_tracking = FALSE;//TEMPLY DISABLE
3675 rtl8192_irq_enable(dev);
3676 priv->being_init_adapter = false;
3681 static void rtl8192_prepare_beacon(struct r8192_priv *priv)
3683 struct sk_buff *skb;
3684 //unsigned long flags;
3687 skb = ieee80211_get_beacon(priv->ieee80211);
3688 tcb_desc = (cb_desc *)(skb->cb + 8);
3689 //spin_lock_irqsave(&priv->tx_lock,flags);
3690 /* prepare misc info for the beacon xmit */
3691 tcb_desc->queue_index = BEACON_QUEUE;
3692 /* IBSS does not support HT yet, use 1M defaultly */
3693 tcb_desc->data_rate = 2;
3694 tcb_desc->RATRIndex = 7;
3695 tcb_desc->bTxDisableRateFallBack = 1;
3696 tcb_desc->bTxUseDriverAssingedRate = 1;
3698 skb_push(skb, priv->ieee80211->tx_headroom);
3700 rtl8192_tx(priv->ieee80211->dev,skb);
3702 //spin_unlock_irqrestore (&priv->tx_lock, flags);
3707 * configure registers for beacon tx and enables it via
3708 * rtl8192_beacon_tx_enable(). rtl8192_beacon_tx_disable() might
3709 * be used to stop beacon transmission
3711 static void rtl8192_start_beacon(struct net_device *dev)
3713 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
3714 struct ieee80211_network *net = &priv->ieee80211->current_network;
3719 DMESG("Enabling beacon TX");
3720 //rtl8192_prepare_beacon(dev);
3721 rtl8192_irq_disable(dev);
3722 //rtl8192_beacon_tx_enable(dev);
3725 write_nic_word(dev, ATIMWND, 2);
3727 /* Beacon interval (in unit of TU) */
3728 write_nic_word(dev, BCN_INTERVAL, net->beacon_interval);
3731 * DrvErlyInt (in unit of TU).
3732 * (Time to send interrupt to notify driver to c
3733 * hange beacon content)
3735 write_nic_word(dev, BCN_DRV_EARLY_INT, 10);
3738 * BcnDMATIM(in unit of us).
3739 * Indicates the time before TBTT to perform beacon queue DMA
3741 write_nic_word(dev, BCN_DMATIME, 256);
3744 * Force beacon frame transmission even after receiving
3745 * beacon frame from other ad hoc STA
3747 write_nic_byte(dev, BCN_ERR_THRESH, 100);
3749 /* Set CW and IFS */
3750 BcnTimeCfg |= BcnCW<<BCN_TCFG_CW_SHIFT;
3751 BcnTimeCfg |= BcnIFS<<BCN_TCFG_IFS;
3752 write_nic_word(dev, BCN_TCFG, BcnTimeCfg);
3755 /* enable the interrupt for ad-hoc process */
3756 rtl8192_irq_enable(dev);
3759 static bool HalTxCheckStuck8190Pci(struct net_device *dev)
3761 u16 RegTxCounter = read_nic_word(dev, 0x128);
3762 struct r8192_priv *priv = ieee80211_priv(dev);
3763 bool bStuck = FALSE;
3764 RT_TRACE(COMP_RESET,"%s():RegTxCounter is %d,TxCounter is %d\n",__FUNCTION__,RegTxCounter,priv->TxCounter);
3765 if(priv->TxCounter==RegTxCounter)
3768 priv->TxCounter = RegTxCounter;
3774 * Assumption: RT_TX_SPINLOCK is acquired.
3777 TxCheckStuck(struct net_device *dev)
3779 struct r8192_priv *priv = ieee80211_priv(dev);
3781 ptx_ring head=NULL,tail=NULL,txring = NULL;
3782 u8 ResetThreshold = NIC_SEND_HANG_THRESHOLD_POWERSAVE;
3783 bool bCheckFwTxCnt = false;
3786 // Decide Stuch threshold according to current power save mode
3788 switch (priv->ieee80211->dot11PowerSaveMode)
3790 // The threshold value may required to be adjusted .
3791 case eActive: // Active/Continuous access.
3792 ResetThreshold = NIC_SEND_HANG_THRESHOLD_NORMAL;
3794 case eMaxPs: // Max power save mode.
3795 ResetThreshold = NIC_SEND_HANG_THRESHOLD_POWERSAVE;
3797 case eFastPs: // Fast power save mode.
3798 ResetThreshold = NIC_SEND_HANG_THRESHOLD_POWERSAVE;
3803 // Check whether specific tcb has been queued for a specific time
3805 for(QueueID = 0; QueueID < MAX_TX_QUEUE; QueueID++)
3809 if(QueueID == TXCMD_QUEUE)
3814 tail=priv->txmapringtail;
3815 head=priv->txmapringhead;
3819 tail=priv->txbkpringtail;
3820 head=priv->txbkpringhead;
3824 tail=priv->txbepringtail;
3825 head=priv->txbepringhead;
3829 tail=priv->txvipringtail;
3830 head=priv->txvipringhead;
3834 tail=priv->txvopringtail;
3835 head=priv->txvopringhead;
3850 RT_TRACE(COMP_ERR,"%s():txring is NULL , BUG!\n",__FUNCTION__);
3853 txring->nStuckCount++;
3854 bCheckFwTxCnt = TRUE;
3860 if(HalTxCheckStuck8190Pci(dev))
3862 RT_TRACE(COMP_RESET, "TxCheckStuck(): Fw indicates no Tx condition! \n");
3863 return RESET_TYPE_SILENT;
3867 return RESET_TYPE_NORESET;
3871 static bool HalRxCheckStuck8190Pci(struct net_device *dev)
3873 struct r8192_priv *priv = ieee80211_priv(dev);
3874 u16 RegRxCounter = read_nic_word(dev, 0x130);
3875 bool bStuck = FALSE;
3876 static u8 rx_chk_cnt = 0;
3877 RT_TRACE(COMP_RESET,"%s(): RegRxCounter is %d,RxCounter is %d\n",__FUNCTION__,RegRxCounter,priv->RxCounter);
3878 // If rssi is small, we should check rx for long time because of bad rx.
3879 // or maybe it will continuous silent reset every 2 seconds.
3881 if(priv->undecorated_smoothed_pwdb >= (RateAdaptiveTH_High+5))
3883 rx_chk_cnt = 0; //high rssi, check rx stuck right now.
3885 else if(priv->undecorated_smoothed_pwdb < (RateAdaptiveTH_High+5) &&
3886 ((priv->CurrentChannelBW!=HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb>=RateAdaptiveTH_Low_40M) ||
3887 (priv->CurrentChannelBW==HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb>=RateAdaptiveTH_Low_20M)) )
3899 else if(((priv->CurrentChannelBW!=HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb<RateAdaptiveTH_Low_40M) ||
3900 (priv->CurrentChannelBW==HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb<RateAdaptiveTH_Low_20M)) &&
3901 priv->undecorated_smoothed_pwdb >= VeryLowRSSI)
3905 //DbgPrint("RSSI < %d && RSSI >= %d, no check this time \n", RateAdaptiveTH_Low, VeryLowRSSI);
3911 //DbgPrint("RSSI < %d && RSSI >= %d, check this time \n", RateAdaptiveTH_Low, VeryLowRSSI);
3918 //DbgPrint("RSSI <= %d, no check this time \n", VeryLowRSSI);
3924 //DbgPrint("RSSI <= %d, check this time \n", VeryLowRSSI);
3927 if(priv->RxCounter==RegRxCounter)
3930 priv->RxCounter = RegRxCounter;
3935 static RESET_TYPE RxCheckStuck(struct net_device *dev)
3938 if(HalRxCheckStuck8190Pci(dev))
3940 RT_TRACE(COMP_RESET, "RxStuck Condition\n");
3941 return RESET_TYPE_SILENT;
3944 return RESET_TYPE_NORESET;
3948 rtl819x_ifcheck_resetornot(struct net_device *dev)
3950 struct r8192_priv *priv = ieee80211_priv(dev);
3951 RESET_TYPE TxResetType = RESET_TYPE_NORESET;
3952 RESET_TYPE RxResetType = RESET_TYPE_NORESET;
3953 RT_RF_POWER_STATE rfState;
3955 rfState = priv->ieee80211->eRFPowerState;
3957 TxResetType = TxCheckStuck(dev);
3959 if( rfState != eRfOff &&
3960 /*ADAPTER_TEST_STATUS_FLAG(Adapter, ADAPTER_STATUS_FW_DOWNLOAD_FAILURE)) &&*/
3961 (priv->ieee80211->iw_mode != IW_MODE_ADHOC))
3963 // If driver is in the status of firmware download failure , driver skips RF initialization and RF is
3964 // in turned off state. Driver should check whether Rx stuck and do silent reset. And
3965 // if driver is in firmware download failure status, driver should initialize RF in the following
3966 // silent reset procedure Emily, 2008.01.21
3968 // Driver should not check RX stuck in IBSS mode because it is required to
3969 // set Check BSSID in order to send beacon, however, if check BSSID is
3970 // set, STA cannot hear any packet a all. Emily, 2008.04.12
3971 RxResetType = RxCheckStuck(dev);
3975 RT_TRACE(COMP_RESET,"%s(): TxResetType is %d, RxResetType is %d\n",__FUNCTION__,TxResetType,RxResetType);
3976 if(TxResetType==RESET_TYPE_NORMAL || RxResetType==RESET_TYPE_NORMAL)
3977 return RESET_TYPE_NORMAL;
3978 else if(TxResetType==RESET_TYPE_SILENT || RxResetType==RESET_TYPE_SILENT)
3979 return RESET_TYPE_SILENT;
3981 return RESET_TYPE_NORESET;
3986 static void CamRestoreAllEntry(struct net_device *dev)
3989 struct r8192_priv *priv = ieee80211_priv(dev);
3990 const u8* MacAddr = priv->ieee80211->current_network.bssid;
3992 static const u8 CAM_CONST_ADDR[4][6] = {
3993 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
3994 {0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
3995 {0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
3996 {0x00, 0x00, 0x00, 0x00, 0x00, 0x03}};
3997 static const u8 CAM_CONST_BROAD[] =
3998 {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
4000 RT_TRACE(COMP_SEC, "CamRestoreAllEntry: \n");
4003 if ((priv->ieee80211->pairwise_key_type == KEY_TYPE_WEP40)||
4004 (priv->ieee80211->pairwise_key_type == KEY_TYPE_WEP104))
4007 for(EntryId=0; EntryId<4; EntryId++)
4010 MacAddr = CAM_CONST_ADDR[EntryId];
4014 priv->ieee80211->pairwise_key_type,
4022 else if(priv->ieee80211->pairwise_key_type == KEY_TYPE_TKIP)
4026 if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
4030 priv->ieee80211->pairwise_key_type,
4038 priv->ieee80211->pairwise_key_type,
4044 else if(priv->ieee80211->pairwise_key_type == KEY_TYPE_CCMP)
4048 if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
4052 priv->ieee80211->pairwise_key_type,
4060 priv->ieee80211->pairwise_key_type,
4069 if(priv->ieee80211->group_key_type == KEY_TYPE_TKIP)
4071 MacAddr = CAM_CONST_BROAD;
4072 for(EntryId=1 ; EntryId<4 ; EntryId++)
4078 priv->ieee80211->group_key_type,
4084 if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
4088 priv->ieee80211->group_key_type,
4093 else if(priv->ieee80211->group_key_type == KEY_TYPE_CCMP)
4095 MacAddr = CAM_CONST_BROAD;
4096 for(EntryId=1; EntryId<4 ; EntryId++)
4102 priv->ieee80211->group_key_type,
4109 if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
4113 priv->ieee80211->group_key_type,
4121 * This function is used to fix Tx/Rx stop bug temporarily.
4122 * This function will do "system reset" to NIC when Tx or Rx is stuck.
4123 * The method checking Tx/Rx stuck of this function is supported by FW,
4124 * which reports Tx and Rx counter to register 0x128 and 0x130.
4126 static void rtl819x_ifsilentreset(struct net_device *dev)
4128 struct r8192_priv *priv = ieee80211_priv(dev);
4130 int reset_status = 0;
4131 struct ieee80211_device *ieee = priv->ieee80211;
4136 // 2007.07.20. If we need to check CCK stop, please uncomment this line.
4137 //bStuck = Adapter->HalFunc.CheckHWStopHandler(Adapter);
4139 if(priv->ResetProgress==RESET_TYPE_NORESET)
4143 //LZM for PS-Poll AID issue. 090429
4144 if(priv->ieee80211->state == IEEE80211_LINKED)
4145 LeisurePSLeave(dev);
4148 RT_TRACE(COMP_RESET,"=========>Reset progress!! \n");
4150 // Set the variable for reset.
4151 priv->ResetProgress = RESET_TYPE_SILENT;
4152 // rtl8192_close(dev);
4154 down(&priv->wx_sem);
4157 RT_TRACE(COMP_ERR,"%s():the driver is not up! return\n",__FUNCTION__);
4162 RT_TRACE(COMP_RESET,"%s():======>start to down the driver\n",__FUNCTION__);
4163 if(!netif_queue_stopped(dev))
4164 netif_stop_queue(dev);
4166 dm_backup_dynamic_mechanism_state(dev);
4168 rtl8192_irq_disable(dev);
4169 rtl8192_cancel_deferred_work(priv);
4171 del_timer_sync(&priv->watch_dog_timer);
4172 ieee->sync_scan_hurryup = 1;
4173 if(ieee->state == IEEE80211_LINKED)
4175 down(&ieee->wx_sem);
4176 printk("ieee->state is IEEE80211_LINKED\n");
4177 ieee80211_stop_send_beacons(priv->ieee80211);
4178 del_timer_sync(&ieee->associate_timer);
4179 cancel_delayed_work(&ieee->associate_retry_wq);
4180 ieee80211_stop_scan(ieee);
4184 printk("ieee->state is NOT LINKED\n");
4185 ieee80211_softmac_stop_protocol(priv->ieee80211,true);
4187 rtl8192_halt_adapter(dev, true);
4189 RT_TRACE(COMP_RESET,"%s():<==========down process is finished\n",__FUNCTION__);
4190 RT_TRACE(COMP_RESET,"%s():===========>start to up the driver\n",__FUNCTION__);
4191 reset_status = _rtl8192_up(dev);
4193 RT_TRACE(COMP_RESET,"%s():<===========up process is finished\n",__FUNCTION__);
4194 if(reset_status == -1)
4203 RT_TRACE(COMP_ERR," ERR!!! %s(): Reset Failed!!\n",__FUNCTION__);
4207 ieee->is_silent_reset = 1;
4209 EnableHWSecurityConfig8192(dev);
4211 if(ieee->state == IEEE80211_LINKED && ieee->iw_mode == IW_MODE_INFRA)
4213 ieee->set_chan(ieee->dev, ieee->current_network.channel);
4216 queue_work(ieee->wq, &ieee->associate_complete_wq);
4220 else if(ieee->state == IEEE80211_LINKED && ieee->iw_mode == IW_MODE_ADHOC)
4222 ieee->set_chan(ieee->dev, ieee->current_network.channel);
4223 ieee->link_change(ieee->dev);
4225 // notify_wx_assoc_event(ieee);
4227 ieee80211_start_send_beacons(ieee);
4229 if (ieee->data_hard_resume)
4230 ieee->data_hard_resume(ieee->dev);
4231 netif_carrier_on(ieee->dev);
4235 CamRestoreAllEntry(dev);
4237 // Restore the previous setting for all dynamic mechanism
4238 dm_restore_dynamic_mechanism_state(dev);
4240 priv->ResetProgress = RESET_TYPE_NORESET;
4241 priv->reset_count++;
4243 priv->bForcedSilentReset =false;
4244 priv->bResetInProgress = false;
4246 // For test --> force write UFWP.
4247 write_nic_byte(dev, UFWP, 1);
4248 RT_TRACE(COMP_RESET, "Reset finished!! ====>[%d]\n", priv->reset_count);
4254 void InactivePsWorkItemCallback(struct net_device *dev)
4256 struct r8192_priv *priv = ieee80211_priv(dev);
4257 PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->ieee80211->PowerSaveControl));
4259 RT_TRACE(COMP_POWER, "InactivePsWorkItemCallback() ---------> \n");
4261 // This flag "bSwRfProcessing", indicates the status of IPS procedure, should be set if the IPS workitem
4262 // is really scheduled.
4263 // The old code, sets this flag before scheduling the IPS workitem and however, at the same time the
4264 // previous IPS workitem did not end yet, fails to schedule the current workitem. Thus, bSwRfProcessing
4265 // blocks the IPS procedure of switching RF.
4266 // By Bruce, 2007-12-25.
4268 pPSC->bSwRfProcessing = TRUE;
4270 RT_TRACE(COMP_RF, "InactivePsWorkItemCallback(): Set RF to %s.\n",
4271 pPSC->eInactivePowerState == eRfOff?"OFF":"ON");
4274 MgntActSet_RF_State(dev, pPSC->eInactivePowerState, RF_CHANGE_BY_IPS);
4277 // To solve CAM values miss in RF OFF, rewrite CAM values after RF ON. By Bruce, 2007-09-20.
4279 pPSC->bSwRfProcessing = FALSE;
4280 RT_TRACE(COMP_POWER, "InactivePsWorkItemCallback() <--------- \n");
4284 /* Change current and default preamble mode. */
4285 bool MgntActSet_802_11_PowerSaveMode(struct net_device *dev, u8 rtPsMode)
4287 struct r8192_priv *priv = ieee80211_priv(dev);
4289 // Currently, we do not change power save mode on IBSS mode.
4290 if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
4296 // <RJ_NOTE> If we make HW to fill up the PwrMgt bit for us,
4297 // some AP will not response to our mgnt frames with PwrMgt bit set,
4298 // e.g. cannot associate the AP.
4299 // So I commented out it. 2005.02.16, by rcnjko.
4301 // // Change device's power save mode.
4302 // Adapter->HalFunc.SetPSModeHandler( Adapter, rtPsMode );
4304 // Update power save mode configured.
4305 //RT_TRACE(COMP_LPS,"%s(): set ieee->ps = %x\n",__FUNCTION__,rtPsMode);
4306 if(!priv->ps_force) {
4307 priv->ieee80211->ps = rtPsMode;
4310 // Awake immediately
4311 if(priv->ieee80211->sta_sleep != 0 && rtPsMode == IEEE80211_PS_DISABLED)
4313 unsigned long flags;
4315 //PlatformSetTimer(Adapter, &(pMgntInfo->AwakeTimer), 0);
4316 // Notify the AP we awke.
4317 rtl8192_hw_wakeup(dev);
4318 priv->ieee80211->sta_sleep = 0;
4320 spin_lock_irqsave(&(priv->ieee80211->mgmt_tx_lock), flags);
4321 printk("LPS leave: notify AP we are awaked ++++++++++ SendNullFunctionData\n");
4322 ieee80211_sta_ps_send_null_frame(priv->ieee80211, 0);
4323 spin_unlock_irqrestore(&(priv->ieee80211->mgmt_tx_lock), flags);
4329 /* Enter the leisure power save mode. */
4330 void LeisurePSEnter(struct net_device *dev)
4332 struct r8192_priv *priv = ieee80211_priv(dev);
4333 PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->ieee80211->PowerSaveControl));
4335 //RT_TRACE(COMP_PS, "LeisurePSEnter()...\n");
4336 //RT_TRACE(COMP_PS, "pPSC->bLeisurePs = %d, ieee->ps = %d,pPSC->LpsIdleCount is %d,RT_CHECK_FOR_HANG_PERIOD is %d\n",
4337 // pPSC->bLeisurePs, priv->ieee80211->ps,pPSC->LpsIdleCount,RT_CHECK_FOR_HANG_PERIOD);
4339 if(!((priv->ieee80211->iw_mode == IW_MODE_INFRA) &&
4340 (priv->ieee80211->state == IEEE80211_LINKED)) ||
4341 (priv->ieee80211->iw_mode == IW_MODE_ADHOC) ||
4342 (priv->ieee80211->iw_mode == IW_MODE_MASTER))
4345 if (pPSC->bLeisurePs)
4347 // Idle for a while if we connect to AP a while ago.
4348 if(pPSC->LpsIdleCount >= RT_CHECK_FOR_HANG_PERIOD) // 4 Sec
4351 if(priv->ieee80211->ps == IEEE80211_PS_DISABLED)
4354 //RT_TRACE(COMP_LPS, "LeisurePSEnter(): Enter 802.11 power save mode...\n");
4355 MgntActSet_802_11_PowerSaveMode(dev, IEEE80211_PS_MBCAST|IEEE80211_PS_UNICAST);
4360 pPSC->LpsIdleCount++;
4365 /* Leave leisure power save mode. */
4366 void LeisurePSLeave(struct net_device *dev)
4368 struct r8192_priv *priv = ieee80211_priv(dev);
4369 PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->ieee80211->PowerSaveControl));
4371 if (pPSC->bLeisurePs)
4373 if(priv->ieee80211->ps != IEEE80211_PS_DISABLED)
4375 // move to lps_wakecomplete()
4376 //RT_TRACE(COMP_LPS, "LeisurePSLeave(): Busy Traffic , Leave 802.11 power save..\n");
4377 MgntActSet_802_11_PowerSaveMode(dev, IEEE80211_PS_DISABLED);
4385 /* Enter the inactive power save mode. RF will be off */
4387 IPSEnter(struct net_device *dev)
4389 struct r8192_priv *priv = ieee80211_priv(dev);
4390 PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->ieee80211->PowerSaveControl));
4391 RT_RF_POWER_STATE rtState;
4393 if (pPSC->bInactivePs)
4395 rtState = priv->ieee80211->eRFPowerState;
4397 // Added by Bruce, 2007-12-25.
4398 // Do not enter IPS in the following conditions:
4399 // (1) RF is already OFF or Sleep
4400 // (2) bSwRfProcessing (indicates the IPS is still under going)
4401 // (3) Connectted (only disconnected can trigger IPS)
4402 // (4) IBSS (send Beacon)
4403 // (5) AP mode (send Beacon)
4405 if (rtState == eRfOn && !pPSC->bSwRfProcessing
4406 && (priv->ieee80211->state != IEEE80211_LINKED) )
4408 RT_TRACE(COMP_RF,"IPSEnter(): Turn off RF.\n");
4409 //printk("IPSEnter(): Turn off RF.\n");
4410 pPSC->eInactivePowerState = eRfOff;
4411 // queue_work(priv->priv_wq,&(pPSC->InactivePsWorkItem));
4412 InactivePsWorkItemCallback(dev);
4419 // Leave the inactive power save mode, RF will be on.
4420 // 2007.08.17, by shien chang.
4423 IPSLeave(struct net_device *dev)
4425 struct r8192_priv *priv = ieee80211_priv(dev);
4426 PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->ieee80211->PowerSaveControl));
4427 RT_RF_POWER_STATE rtState;
4429 if (pPSC->bInactivePs)
4431 rtState = priv->ieee80211->eRFPowerState;
4432 if (rtState != eRfOn && !pPSC->bSwRfProcessing && priv->ieee80211->RfOffReason <= RF_CHANGE_BY_IPS)
4434 RT_TRACE(COMP_POWER, "IPSLeave(): Turn on RF.\n");
4435 //printk("IPSLeave(): Turn on RF.\n");
4436 pPSC->eInactivePowerState = eRfOn;
4437 // queue_work(priv->priv_wq,&(pPSC->InactivePsWorkItem));
4438 InactivePsWorkItemCallback(dev);
4443 void IPSLeave_wq(void *data)
4445 struct ieee80211_device *ieee = container_of(data,struct ieee80211_device,ips_leave_wq);
4446 struct net_device *dev = ieee->dev;
4448 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
4449 down(&priv->ieee80211->ips_sem);
4451 up(&priv->ieee80211->ips_sem);
4454 void ieee80211_ips_leave_wq(struct net_device *dev)
4456 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
4457 RT_RF_POWER_STATE rtState;
4458 rtState = priv->ieee80211->eRFPowerState;
4460 if(priv->ieee80211->PowerSaveControl.bInactivePs){
4461 if(rtState == eRfOff){
4462 if(priv->ieee80211->RfOffReason > RF_CHANGE_BY_IPS)
4464 RT_TRACE(COMP_ERR, "%s(): RF is OFF.\n",__FUNCTION__);
4468 printk("=========>%s(): IPSLeave\n",__FUNCTION__);
4469 queue_work(priv->ieee80211->wq,&priv->ieee80211->ips_leave_wq);
4474 //added by amy 090331 end
4475 void ieee80211_ips_leave(struct net_device *dev)
4477 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
4478 down(&priv->ieee80211->ips_sem);
4480 up(&priv->ieee80211->ips_sem);
4484 static void rtl819x_update_rxcounts(
4485 struct r8192_priv *priv,
4494 *TotalRxDataNum = 0;
4496 SlotIndex = (priv->ieee80211->LinkDetectInfo.SlotIndex++)%(priv->ieee80211->LinkDetectInfo.SlotNum);
4497 priv->ieee80211->LinkDetectInfo.RxBcnNum[SlotIndex] = priv->ieee80211->LinkDetectInfo.NumRecvBcnInPeriod;
4498 priv->ieee80211->LinkDetectInfo.RxDataNum[SlotIndex] = priv->ieee80211->LinkDetectInfo.NumRecvDataInPeriod;
4499 for( i=0; i<priv->ieee80211->LinkDetectInfo.SlotNum; i++ ){
4500 *TotalRxBcnNum += priv->ieee80211->LinkDetectInfo.RxBcnNum[i];
4501 *TotalRxDataNum += priv->ieee80211->LinkDetectInfo.RxDataNum[i];
4506 static void rtl819x_watchdog_wqcallback(struct work_struct *work)
4508 struct delayed_work *dwork = container_of(work,struct delayed_work,work);
4509 struct r8192_priv *priv = container_of(dwork,struct r8192_priv,watch_dog_wq);
4510 struct net_device *dev = priv->ieee80211->dev;
4511 struct ieee80211_device* ieee = priv->ieee80211;
4512 RESET_TYPE ResetType = RESET_TYPE_NORESET;
4513 static u8 check_reset_cnt=0;
4514 unsigned long flags;
4515 bool bBusyTraffic = false;
4516 static u8 last_time = 0;
4517 bool bEnterPS = false;
4519 if ((!priv->up) || priv->bHwRadioOff)
4524 hal_dm_watchdog(dev);
4526 // printk("watch_dog ENABLE_IPS\n");
4527 if(ieee->actscanning == false){
4528 //printk("%d,%d,%d,%d\n", ieee->eRFPowerState, ieee->is_set_key, ieee->proto_stoppping, ieee->wx_set_enc);
4529 if((ieee->iw_mode == IW_MODE_INFRA) && (ieee->state == IEEE80211_NOLINK) &&
4530 (ieee->eRFPowerState == eRfOn)&&!ieee->is_set_key &&
4531 (!ieee->proto_stoppping) && !ieee->wx_set_enc){
4532 if(ieee->PowerSaveControl.ReturnPoint == IPS_CALLBACK_NONE){
4533 //printk("====================>haha:IPSEnter()\n");
4535 //ieee80211_stop_scan(priv->ieee80211);
4540 {//to get busy traffic condition
4541 if(ieee->state == IEEE80211_LINKED)
4543 if( ieee->LinkDetectInfo.NumRxOkInPeriod> 100 ||
4544 ieee->LinkDetectInfo.NumTxOkInPeriod> 100 ) {
4545 bBusyTraffic = true;
4549 //added by amy for Leisure PS
4550 if( ((ieee->LinkDetectInfo.NumRxUnicastOkInPeriod + ieee->LinkDetectInfo.NumTxOkInPeriod) > 8 ) ||
4551 (ieee->LinkDetectInfo.NumRxUnicastOkInPeriod > 2) )
4553 //printk("ieee->LinkDetectInfo.NumRxUnicastOkInPeriod is %d,ieee->LinkDetectInfo.NumTxOkInPeriod is %d\n",
4554 // ieee->LinkDetectInfo.NumRxUnicastOkInPeriod,ieee->LinkDetectInfo.NumTxOkInPeriod);
4562 //printk("***bEnterPS = %d\n", bEnterPS);
4563 // LeisurePS only work in infra mode.
4566 LeisurePSEnter(dev);
4570 LeisurePSLeave(dev);
4578 //RT_TRACE(COMP_LPS,"====>no link LPS leave\n");
4579 LeisurePSLeave(dev);
4583 ieee->LinkDetectInfo.NumRxOkInPeriod = 0;
4584 ieee->LinkDetectInfo.NumTxOkInPeriod = 0;
4585 ieee->LinkDetectInfo.NumRxUnicastOkInPeriod = 0;
4586 ieee->LinkDetectInfo.bBusyTraffic = bBusyTraffic;
4590 //added by amy for AP roaming
4593 if(ieee->state == IEEE80211_LINKED && ieee->iw_mode == IW_MODE_INFRA)
4595 u32 TotalRxBcnNum = 0;
4596 u32 TotalRxDataNum = 0;
4598 rtl819x_update_rxcounts(priv, &TotalRxBcnNum, &TotalRxDataNum);
4599 if((TotalRxBcnNum+TotalRxDataNum) == 0)
4601 if( ieee->eRFPowerState == eRfOff)
4602 RT_TRACE(COMP_ERR,"========>%s()\n",__FUNCTION__);
4603 printk("===>%s(): AP is power off,connect another one\n",__FUNCTION__);
4604 // Dot11d_Reset(dev);
4605 ieee->state = IEEE80211_ASSOCIATING;
4606 notify_wx_assoc_event(priv->ieee80211);
4607 RemovePeerTS(priv->ieee80211,priv->ieee80211->current_network.bssid);
4608 ieee->is_roaming = true;
4609 ieee->is_set_key = false;
4610 ieee->link_change(dev);
4611 queue_work(ieee->wq, &ieee->associate_procedure_wq);
4614 ieee->LinkDetectInfo.NumRecvBcnInPeriod=0;
4615 ieee->LinkDetectInfo.NumRecvDataInPeriod=0;
4618 //check if reset the driver
4619 spin_lock_irqsave(&priv->tx_lock,flags);
4620 if(check_reset_cnt++ >= 3 && !ieee->is_roaming && (last_time != 1))
4622 ResetType = rtl819x_ifcheck_resetornot(dev);
4623 check_reset_cnt = 3;
4624 //DbgPrint("Start to check silent reset\n");
4626 spin_unlock_irqrestore(&priv->tx_lock,flags);
4627 if(!priv->bDisableNormalResetCheck && ResetType == RESET_TYPE_NORMAL)
4629 priv->ResetProgress = RESET_TYPE_NORMAL;
4630 RT_TRACE(COMP_RESET,"%s(): NOMAL RESET\n",__FUNCTION__);
4633 /* disable silent reset temply 2008.9.11*/
4635 if( ((priv->force_reset) || (!priv->bDisableNormalResetCheck && ResetType==RESET_TYPE_SILENT))) // This is control by OID set in Pomelo
4638 rtl819x_ifsilentreset(dev);
4643 priv->force_reset = false;
4644 priv->bForcedSilentReset = false;
4645 priv->bResetInProgress = false;
4646 RT_TRACE(COMP_TRACE, " <==RtUsbCheckForHangWorkItemCallback()\n");
4650 void watch_dog_timer_callback(unsigned long data)
4652 struct r8192_priv *priv = ieee80211_priv((struct net_device *) data);
4653 queue_delayed_work(priv->priv_wq,&priv->watch_dog_wq,0);
4654 mod_timer(&priv->watch_dog_timer, jiffies + MSECS(IEEE80211_WATCH_DOG_TIME));
4658 static int _rtl8192_up(struct net_device *dev)
4660 struct r8192_priv *priv = ieee80211_priv(dev);
4662 RT_STATUS init_status = RT_STATUS_SUCCESS;
4664 priv->ieee80211->ieee_up=1;
4665 priv->bdisable_nic = false; //YJ,add,091111
4666 RT_TRACE(COMP_INIT, "Bringing up iface");
4668 init_status = rtl8192_adapter_start(dev);
4669 if(init_status != RT_STATUS_SUCCESS)
4671 RT_TRACE(COMP_ERR,"ERR!!! %s(): initialization is failed!\n",__FUNCTION__);
4674 RT_TRACE(COMP_INIT, "start adapter finished\n");
4676 if(priv->ieee80211->eRFPowerState!=eRfOn)
4677 MgntActSet_RF_State(dev, eRfOn, priv->ieee80211->RfOffReason);
4679 if(priv->ieee80211->state != IEEE80211_LINKED)
4680 ieee80211_softmac_start_protocol(priv->ieee80211);
4681 ieee80211_reset_queue(priv->ieee80211);
4682 watch_dog_timer_callback((unsigned long) dev);
4683 if(!netif_queue_stopped(dev))
4684 netif_start_queue(dev);
4686 netif_wake_queue(dev);
4692 static int rtl8192_open(struct net_device *dev)
4694 struct r8192_priv *priv = ieee80211_priv(dev);
4697 down(&priv->wx_sem);
4698 ret = rtl8192_up(dev);
4705 int rtl8192_up(struct net_device *dev)
4707 struct r8192_priv *priv = ieee80211_priv(dev);
4709 if (priv->up == 1) return -1;
4711 return _rtl8192_up(dev);
4715 static int rtl8192_close(struct net_device *dev)
4717 struct r8192_priv *priv = ieee80211_priv(dev);
4720 down(&priv->wx_sem);
4722 ret = rtl8192_down(dev);
4730 int rtl8192_down(struct net_device *dev)
4732 struct r8192_priv *priv = ieee80211_priv(dev);
4734 if (priv->up == 0) return -1;
4737 //LZM for PS-Poll AID issue. 090429
4738 if(priv->ieee80211->state == IEEE80211_LINKED)
4739 LeisurePSLeave(dev);
4743 priv->ieee80211->ieee_up = 0;
4744 RT_TRACE(COMP_DOWN, "==========>%s()\n", __FUNCTION__);
4746 if (!netif_queue_stopped(dev))
4747 netif_stop_queue(dev);
4749 rtl8192_irq_disable(dev);
4750 rtl8192_cancel_deferred_work(priv);
4752 del_timer_sync(&priv->watch_dog_timer);
4754 ieee80211_softmac_stop_protocol(priv->ieee80211,true);
4756 rtl8192_halt_adapter(dev,false);
4757 memset(&priv->ieee80211->current_network, 0 , offsetof(struct ieee80211_network, list));
4759 RT_TRACE(COMP_DOWN, "<==========%s()\n", __FUNCTION__);
4765 void rtl8192_commit(struct net_device *dev)
4767 struct r8192_priv *priv = ieee80211_priv(dev);
4769 if (priv->up == 0) return ;
4772 ieee80211_softmac_stop_protocol(priv->ieee80211,true);
4774 rtl8192_irq_disable(dev);
4775 rtl8192_halt_adapter(dev,true);
4779 static void rtl8192_restart(struct work_struct *work)
4781 struct r8192_priv *priv = container_of(work, struct r8192_priv, reset_wq);
4782 struct net_device *dev = priv->ieee80211->dev;
4784 down(&priv->wx_sem);
4786 rtl8192_commit(dev);
4791 static void r8192_set_multicast(struct net_device *dev)
4793 struct r8192_priv *priv = ieee80211_priv(dev);
4796 //down(&priv->wx_sem);
4800 promisc = (dev->flags & IFF_PROMISC) ? 1:0;
4802 if (promisc != priv->promisc) {
4804 // rtl8192_commit(dev);
4807 priv->promisc = promisc;
4809 //schedule_work(&priv->reset_wq);
4810 //up(&priv->wx_sem);
4814 static int r8192_set_mac_adr(struct net_device *dev, void *mac)
4816 struct r8192_priv *priv = ieee80211_priv(dev);
4817 struct sockaddr *addr = mac;
4819 down(&priv->wx_sem);
4821 memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
4823 schedule_work(&priv->reset_wq);
4829 /* based on ipw2200 driver */
4830 static int rtl8192_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
4832 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
4833 struct iwreq *wrq = (struct iwreq *)rq;
4835 struct ieee80211_device *ieee = priv->ieee80211;
4837 u8 broadcast_addr[6] = {0xff,0xff,0xff,0xff,0xff,0xff};
4838 struct iw_point *p = &wrq->u.data;
4839 struct ieee_param *ipw = NULL;//(struct ieee_param *)wrq->u.data.pointer;
4841 down(&priv->wx_sem);
4844 if (p->length < sizeof(struct ieee_param) || !p->pointer){
4849 ipw = kmalloc(p->length, GFP_KERNEL);
4854 if (copy_from_user(ipw, p->pointer, p->length)) {
4861 case RTL_IOCTL_WPA_SUPPLICANT:
4862 //parse here for HW security
4863 if (ipw->cmd == IEEE_CMD_SET_ENCRYPTION)
4865 if (ipw->u.crypt.set_tx)
4867 if (strcmp(ipw->u.crypt.alg, "CCMP") == 0)
4868 ieee->pairwise_key_type = KEY_TYPE_CCMP;
4869 else if (strcmp(ipw->u.crypt.alg, "TKIP") == 0)
4870 ieee->pairwise_key_type = KEY_TYPE_TKIP;
4871 else if (strcmp(ipw->u.crypt.alg, "WEP") == 0)
4873 if (ipw->u.crypt.key_len == 13)
4874 ieee->pairwise_key_type = KEY_TYPE_WEP104;
4875 else if (ipw->u.crypt.key_len == 5)
4876 ieee->pairwise_key_type = KEY_TYPE_WEP40;
4879 ieee->pairwise_key_type = KEY_TYPE_NA;
4881 if (ieee->pairwise_key_type)
4883 memcpy((u8*)key, ipw->u.crypt.key, 16);
4884 EnableHWSecurityConfig8192(dev);
4885 //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!
4887 setKey(dev, 4, ipw->u.crypt.idx, ieee->pairwise_key_type, (u8*)ieee->ap_mac_addr, 0, key);
4888 if (ieee->auth_mode != 2) //LEAP WEP will never set this.
4889 setKey(dev, ipw->u.crypt.idx, ipw->u.crypt.idx, ieee->pairwise_key_type, (u8*)ieee->ap_mac_addr, 0, key);
4891 if ((ieee->pairwise_key_type == KEY_TYPE_CCMP) && ieee->pHTInfo->bCurrentHTSupport){
4892 write_nic_byte(dev, 0x173, 1); //fix aes bug
4896 else //if (ipw->u.crypt.idx) //group key use idx > 0
4898 memcpy((u8*)key, ipw->u.crypt.key, 16);
4899 if (strcmp(ipw->u.crypt.alg, "CCMP") == 0)
4900 ieee->group_key_type= KEY_TYPE_CCMP;
4901 else if (strcmp(ipw->u.crypt.alg, "TKIP") == 0)
4902 ieee->group_key_type = KEY_TYPE_TKIP;
4903 else if (strcmp(ipw->u.crypt.alg, "WEP") == 0)
4905 if (ipw->u.crypt.key_len == 13)
4906 ieee->group_key_type = KEY_TYPE_WEP104;
4907 else if (ipw->u.crypt.key_len == 5)
4908 ieee->group_key_type = KEY_TYPE_WEP40;
4911 ieee->group_key_type = KEY_TYPE_NA;
4913 if (ieee->group_key_type)
4917 ipw->u.crypt.idx, //KeyIndex
4918 ieee->group_key_type, //KeyType
4919 broadcast_addr, //MacAddr
4929 printk("@@ wrq->u pointer = ");
4930 for(i=0;i<wrq->u.data.length;i++){
4931 if(i%10==0) printk("\n");
4932 printk( "%8x|", ((u32*)wrq->u.data.pointer)[i] );
4936 #endif /*JOHN_DEBUG*/
4937 ret = ieee80211_wpa_supplicant_ioctl(priv->ieee80211, &wrq->u.data);
4952 static u8 HwRateToMRate90(bool bIsHT, u8 rate)
4958 case DESC90_RATE1M: ret_rate = MGN_1M; break;
4959 case DESC90_RATE2M: ret_rate = MGN_2M; break;
4960 case DESC90_RATE5_5M: ret_rate = MGN_5_5M; break;
4961 case DESC90_RATE11M: ret_rate = MGN_11M; break;
4962 case DESC90_RATE6M: ret_rate = MGN_6M; break;
4963 case DESC90_RATE9M: ret_rate = MGN_9M; break;
4964 case DESC90_RATE12M: ret_rate = MGN_12M; break;
4965 case DESC90_RATE18M: ret_rate = MGN_18M; break;
4966 case DESC90_RATE24M: ret_rate = MGN_24M; break;
4967 case DESC90_RATE36M: ret_rate = MGN_36M; break;
4968 case DESC90_RATE48M: ret_rate = MGN_48M; break;
4969 case DESC90_RATE54M: ret_rate = MGN_54M; break;
4972 RT_TRACE(COMP_RECV, "HwRateToMRate90(): Non supported Rate [%x], bIsHT = %d!!!\n", rate, bIsHT);
4978 case DESC90_RATEMCS0: ret_rate = MGN_MCS0; break;
4979 case DESC90_RATEMCS1: ret_rate = MGN_MCS1; break;
4980 case DESC90_RATEMCS2: ret_rate = MGN_MCS2; break;
4981 case DESC90_RATEMCS3: ret_rate = MGN_MCS3; break;
4982 case DESC90_RATEMCS4: ret_rate = MGN_MCS4; break;
4983 case DESC90_RATEMCS5: ret_rate = MGN_MCS5; break;
4984 case DESC90_RATEMCS6: ret_rate = MGN_MCS6; break;
4985 case DESC90_RATEMCS7: ret_rate = MGN_MCS7; break;
4986 case DESC90_RATEMCS8: ret_rate = MGN_MCS8; break;
4987 case DESC90_RATEMCS9: ret_rate = MGN_MCS9; break;
4988 case DESC90_RATEMCS10: ret_rate = MGN_MCS10; break;
4989 case DESC90_RATEMCS11: ret_rate = MGN_MCS11; break;
4990 case DESC90_RATEMCS12: ret_rate = MGN_MCS12; break;
4991 case DESC90_RATEMCS13: ret_rate = MGN_MCS13; break;
4992 case DESC90_RATEMCS14: ret_rate = MGN_MCS14; break;
4993 case DESC90_RATEMCS15: ret_rate = MGN_MCS15; break;
4994 case DESC90_RATEMCS32: ret_rate = (0x80|0x20); break;
4997 RT_TRACE(COMP_RECV, "HwRateToMRate90(): Non supported Rate [%x], bIsHT = %d!!!\n",rate, bIsHT);
5005 /* Record the TSF time stamp when receiving a packet */
5006 static void UpdateRxPktTimeStamp8190 (struct net_device *dev, struct ieee80211_rx_stats *stats)
5008 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
5010 if(stats->bIsAMPDU && !stats->bFirstMPDU) {
5011 stats->mac_time[0] = priv->LastRxDescTSFLow;
5012 stats->mac_time[1] = priv->LastRxDescTSFHigh;
5014 priv->LastRxDescTSFLow = stats->mac_time[0];
5015 priv->LastRxDescTSFHigh = stats->mac_time[1];
5019 static long rtl819x_translate_todbm(u8 signal_strength_index)// 0-100 index.
5021 long signal_power; // in dBm.
5023 // Translate to dBm (x=0.5y-95).
5024 signal_power = (long)((signal_strength_index + 1) >> 1);
5027 return signal_power;
5031 * Update Rx signal related information in the packet reeived
5032 * to RxStats. User application can query RxStats to realize
5033 * current Rx signal status.
5035 * In normal operation, user only care about the information of the BSS
5036 * and we shall invoke this function if the packet received is from the BSS.
5039 rtl819x_update_rxsignalstatistics8190pci(
5040 struct r8192_priv * priv,
5041 struct ieee80211_rx_stats * pprevious_stats
5046 //2 <ToDo> Update Rx Statistics (such as signal strength and signal quality).
5049 if(priv->stats.recv_signal_power == 0)
5050 priv->stats.recv_signal_power = pprevious_stats->RecvSignalPower;
5052 // To avoid the past result restricting the statistics sensitivity, weight the current power (5/6) to speed up the
5053 // reaction of smoothed Signal Power.
5054 if(pprevious_stats->RecvSignalPower > priv->stats.recv_signal_power)
5056 else if(pprevious_stats->RecvSignalPower < priv->stats.recv_signal_power)
5059 // We need more correct power of received packets and the "SignalStrength" of RxStats have been beautified or translated,
5060 // so we record the correct power in Dbm here. By Bruce, 2008-03-07.
5062 priv->stats.recv_signal_power = (priv->stats.recv_signal_power * 5 + pprevious_stats->RecvSignalPower + weighting) / 6;
5066 rtl8190_process_cck_rxpathsel(
5067 struct r8192_priv * priv,
5068 struct ieee80211_rx_stats * pprevious_stats
5071 #ifdef RTL8190P //Only 90P 2T4R need to check
5072 char last_cck_adc_pwdb[4]={0,0,0,0};
5074 //cosa add for Rx path selection
5075 if(priv->rf_type == RF_2T4R && DM_RxPathSelTable.Enable)
5077 if(pprevious_stats->bIsCCK &&
5078 (pprevious_stats->bPacketToSelf ||pprevious_stats->bPacketBeacon))
5080 /* record the cck adc_pwdb to the sliding window. */
5081 if(priv->stats.cck_adc_pwdb.TotalNum++ >= PHY_RSSI_SLID_WIN_MAX)
5083 priv->stats.cck_adc_pwdb.TotalNum = PHY_RSSI_SLID_WIN_MAX;
5084 for(i=RF90_PATH_A; i<RF90_PATH_MAX; i++)
5086 last_cck_adc_pwdb[i] = priv->stats.cck_adc_pwdb.elements[i][priv->stats.cck_adc_pwdb.index];
5087 priv->stats.cck_adc_pwdb.TotalVal[i] -= last_cck_adc_pwdb[i];
5090 for(i=RF90_PATH_A; i<RF90_PATH_MAX; i++)
5092 priv->stats.cck_adc_pwdb.TotalVal[i] += pprevious_stats->cck_adc_pwdb[i];
5093 priv->stats.cck_adc_pwdb.elements[i][priv->stats.cck_adc_pwdb.index] = pprevious_stats->cck_adc_pwdb[i];
5095 priv->stats.cck_adc_pwdb.index++;
5096 if(priv->stats.cck_adc_pwdb.index >= PHY_RSSI_SLID_WIN_MAX)
5097 priv->stats.cck_adc_pwdb.index = 0;
5099 for(i=RF90_PATH_A; i<RF90_PATH_MAX; i++)
5101 DM_RxPathSelTable.cck_pwdb_sta[i] = priv->stats.cck_adc_pwdb.TotalVal[i]/priv->stats.cck_adc_pwdb.TotalNum;
5104 for(i=RF90_PATH_A; i<RF90_PATH_MAX; i++)
5106 if(pprevious_stats->cck_adc_pwdb[i] > (char)priv->undecorated_smoothed_cck_adc_pwdb[i])
5108 priv->undecorated_smoothed_cck_adc_pwdb[i] =
5109 ( (priv->undecorated_smoothed_cck_adc_pwdb[i]*(Rx_Smooth_Factor-1)) +
5110 (pprevious_stats->cck_adc_pwdb[i])) /(Rx_Smooth_Factor);
5111 priv->undecorated_smoothed_cck_adc_pwdb[i] = priv->undecorated_smoothed_cck_adc_pwdb[i] + 1;
5115 priv->undecorated_smoothed_cck_adc_pwdb[i] =
5116 ( (priv->undecorated_smoothed_cck_adc_pwdb[i]*(Rx_Smooth_Factor-1)) +
5117 (pprevious_stats->cck_adc_pwdb[i])) /(Rx_Smooth_Factor);
5126 /* 2008/01/22 MH We can not delcare RSSI/EVM total value of sliding window to
5127 be a local static. Otherwise, it may increase when we return from S3/S4. The
5128 value will be kept in memory or disk. We must delcare the value in adapter
5129 and it will be reinitialized when return from S3/S4. */
5130 static void rtl8192_process_phyinfo(struct r8192_priv * priv, u8* buffer,struct ieee80211_rx_stats * pprevious_stats, struct ieee80211_rx_stats * pcurrent_stats)
5132 bool bcheck = false;
5134 u32 nspatial_stream, tmp_val;
5136 static u32 slide_rssi_index=0, slide_rssi_statistics=0;
5137 static u32 slide_evm_index=0, slide_evm_statistics=0;
5138 static u32 last_rssi=0, last_evm=0;
5139 //cosa add for rx path selection
5140 // static long slide_cck_adc_pwdb_index=0, slide_cck_adc_pwdb_statistics=0;
5141 // static char last_cck_adc_pwdb[4]={0,0,0,0};
5142 //cosa add for beacon rssi smoothing
5143 static u32 slide_beacon_adc_pwdb_index=0, slide_beacon_adc_pwdb_statistics=0;
5144 static u32 last_beacon_adc_pwdb=0;
5146 struct ieee80211_hdr_3addr *hdr;
5148 unsigned int frag,seq;
5149 hdr = (struct ieee80211_hdr_3addr *)buffer;
5150 sc = le16_to_cpu(hdr->seq_ctl);
5151 frag = WLAN_GET_SEQ_FRAG(sc);
5152 seq = WLAN_GET_SEQ_SEQ(sc);
5153 //cosa add 04292008 to record the sequence number
5154 pcurrent_stats->Seq_Num = seq;
5156 // Check whether we should take the previous packet into accounting
5158 if(!pprevious_stats->bIsAMPDU)
5160 // if previous packet is not aggregated packet
5164 //remve for that we don't use AMPDU to calculate PWDB,because the reported PWDB of some AP is fault.
5166 // if previous packet is aggregated packet, and current packet
5168 // (2) is the first packet of one AMPDU
5169 // that means the previous packet is the last one aggregated packet
5170 if( !pcurrent_stats->bIsAMPDU || pcurrent_stats->bFirstMPDU)
5175 if(slide_rssi_statistics++ >= PHY_RSSI_SLID_WIN_MAX)
5177 slide_rssi_statistics = PHY_RSSI_SLID_WIN_MAX;
5178 last_rssi = priv->stats.slide_signal_strength[slide_rssi_index];
5179 priv->stats.slide_rssi_total -= last_rssi;
5181 priv->stats.slide_rssi_total += pprevious_stats->SignalStrength;
5183 priv->stats.slide_signal_strength[slide_rssi_index++] = pprevious_stats->SignalStrength;
5184 if(slide_rssi_index >= PHY_RSSI_SLID_WIN_MAX)
5185 slide_rssi_index = 0;
5187 // <1> Showed on UI for user, in dbm
5188 tmp_val = priv->stats.slide_rssi_total/slide_rssi_statistics;
5189 priv->stats.signal_strength = rtl819x_translate_todbm((u8)tmp_val);
5190 pcurrent_stats->rssi = priv->stats.signal_strength;
5192 // If the previous packet does not match the criteria, neglect it
5194 if(!pprevious_stats->bPacketMatchBSSID)
5196 if(!pprevious_stats->bToSelfBA)
5203 rtl8190_process_cck_rxpathsel(priv,pprevious_stats);
5208 priv->stats.num_process_phyinfo++;
5210 /* record the general signal strength to the sliding window. */
5211 if(slide_rssi_statistics++ >= PHY_RSSI_SLID_WIN_MAX)
5213 slide_rssi_statistics = PHY_RSSI_SLID_WIN_MAX;
5214 last_rssi = priv->stats.slide_signal_strength[slide_rssi_index];
5215 priv->stats.slide_rssi_total -= last_rssi;
5217 priv->stats.slide_rssi_total += pprevious_stats->SignalStrength;
5219 priv->stats.slide_signal_strength[slide_rssi_index++] = pprevious_stats->SignalStrength;
5220 if(slide_rssi_index >= PHY_RSSI_SLID_WIN_MAX)
5221 slide_rssi_index = 0;
5223 // <1> Showed on UI for user, in dbm
5224 tmp_val = priv->stats.slide_rssi_total/slide_rssi_statistics;
5225 priv->stats.signal_strength = rtl819x_translate_todbm((u8)tmp_val);
5228 // <2> Showed on UI for engineering
5229 // hardware does not provide rssi information for each rf path in CCK
5230 if(!pprevious_stats->bIsCCK && pprevious_stats->bPacketToSelf)
5232 for (rfpath = RF90_PATH_A; rfpath < RF90_PATH_C; rfpath++)
5234 if (!rtl8192_phy_CheckIsLegalRFPath(priv->ieee80211->dev, rfpath))
5236 RT_TRACE(COMP_DBG,"Jacken -> pPreviousstats->RxMIMOSignalStrength[rfpath] = %d \n" ,pprevious_stats->RxMIMOSignalStrength[rfpath] );
5237 //Fixed by Jacken 2008-03-20
5238 if(priv->stats.rx_rssi_percentage[rfpath] == 0)
5240 priv->stats.rx_rssi_percentage[rfpath] = pprevious_stats->RxMIMOSignalStrength[rfpath];
5241 //DbgPrint("MIMO RSSI initialize \n");
5243 if(pprevious_stats->RxMIMOSignalStrength[rfpath] > priv->stats.rx_rssi_percentage[rfpath])
5245 priv->stats.rx_rssi_percentage[rfpath] =
5246 ( (priv->stats.rx_rssi_percentage[rfpath]*(Rx_Smooth_Factor-1)) +
5247 (pprevious_stats->RxMIMOSignalStrength[rfpath])) /(Rx_Smooth_Factor);
5248 priv->stats.rx_rssi_percentage[rfpath] = priv->stats.rx_rssi_percentage[rfpath] + 1;
5252 priv->stats.rx_rssi_percentage[rfpath] =
5253 ( (priv->stats.rx_rssi_percentage[rfpath]*(Rx_Smooth_Factor-1)) +
5254 (pprevious_stats->RxMIMOSignalStrength[rfpath])) /(Rx_Smooth_Factor);
5256 RT_TRACE(COMP_DBG,"Jacken -> priv->RxStats.RxRSSIPercentage[rfPath] = %d \n" ,priv->stats.rx_rssi_percentage[rfpath] );
5264 //cosa add for beacon rssi smoothing by average.
5265 if(pprevious_stats->bPacketBeacon)
5267 /* record the beacon pwdb to the sliding window. */
5268 if(slide_beacon_adc_pwdb_statistics++ >= PHY_Beacon_RSSI_SLID_WIN_MAX)
5270 slide_beacon_adc_pwdb_statistics = PHY_Beacon_RSSI_SLID_WIN_MAX;
5271 last_beacon_adc_pwdb = priv->stats.Slide_Beacon_pwdb[slide_beacon_adc_pwdb_index];
5272 priv->stats.Slide_Beacon_Total -= last_beacon_adc_pwdb;
5273 //DbgPrint("slide_beacon_adc_pwdb_index = %d, last_beacon_adc_pwdb = %d, Adapter->RxStats.Slide_Beacon_Total = %d\n",
5274 // slide_beacon_adc_pwdb_index, last_beacon_adc_pwdb, Adapter->RxStats.Slide_Beacon_Total);
5276 priv->stats.Slide_Beacon_Total += pprevious_stats->RxPWDBAll;
5277 priv->stats.Slide_Beacon_pwdb[slide_beacon_adc_pwdb_index] = pprevious_stats->RxPWDBAll;
5278 //DbgPrint("slide_beacon_adc_pwdb_index = %d, pPreviousRfd->Status.RxPWDBAll = %d\n", slide_beacon_adc_pwdb_index, pPreviousRfd->Status.RxPWDBAll);
5279 slide_beacon_adc_pwdb_index++;
5280 if(slide_beacon_adc_pwdb_index >= PHY_Beacon_RSSI_SLID_WIN_MAX)
5281 slide_beacon_adc_pwdb_index = 0;
5282 pprevious_stats->RxPWDBAll = priv->stats.Slide_Beacon_Total/slide_beacon_adc_pwdb_statistics;
5283 if(pprevious_stats->RxPWDBAll >= 3)
5284 pprevious_stats->RxPWDBAll -= 3;
5287 RT_TRACE(COMP_RXDESC, "Smooth %s PWDB = %d\n",
5288 pprevious_stats->bIsCCK? "CCK": "OFDM",
5289 pprevious_stats->RxPWDBAll);
5291 if(pprevious_stats->bPacketToSelf || pprevious_stats->bPacketBeacon || pprevious_stats->bToSelfBA)
5293 if(priv->undecorated_smoothed_pwdb < 0) // initialize
5295 priv->undecorated_smoothed_pwdb = pprevious_stats->RxPWDBAll;
5296 //DbgPrint("First pwdb initialize \n");
5299 if(pprevious_stats->RxPWDBAll > (u32)priv->undecorated_smoothed_pwdb)
5301 priv->undecorated_smoothed_pwdb =
5302 ( ((priv->undecorated_smoothed_pwdb)*(Rx_Smooth_Factor-1)) +
5303 (pprevious_stats->RxPWDBAll)) /(Rx_Smooth_Factor);
5304 priv->undecorated_smoothed_pwdb = priv->undecorated_smoothed_pwdb + 1;
5308 priv->undecorated_smoothed_pwdb =
5309 ( ((priv->undecorated_smoothed_pwdb)*(Rx_Smooth_Factor-1)) +
5310 (pprevious_stats->RxPWDBAll)) /(Rx_Smooth_Factor);
5313 //Fixed by Jacken 2008-03-20
5314 if(pPreviousRfd->Status.RxPWDBAll > (u32)pHalData->UndecoratedSmoothedPWDB)
5316 pHalData->UndecoratedSmoothedPWDB =
5317 ( ((pHalData->UndecoratedSmoothedPWDB)* 5) + (pPreviousRfd->Status.RxPWDBAll)) / 6;
5318 pHalData->UndecoratedSmoothedPWDB = pHalData->UndecoratedSmoothedPWDB + 1;
5322 pHalData->UndecoratedSmoothedPWDB =
5323 ( ((pHalData->UndecoratedSmoothedPWDB)* 5) + (pPreviousRfd->Status.RxPWDBAll)) / 6;
5326 rtl819x_update_rxsignalstatistics8190pci(priv,pprevious_stats);
5332 /* record the general EVM to the sliding window. */
5333 if(pprevious_stats->SignalQuality == 0)
5338 if(pprevious_stats->bPacketToSelf || pprevious_stats->bPacketBeacon || pprevious_stats->bToSelfBA){
5339 if(slide_evm_statistics++ >= PHY_RSSI_SLID_WIN_MAX){
5340 slide_evm_statistics = PHY_RSSI_SLID_WIN_MAX;
5341 last_evm = priv->stats.slide_evm[slide_evm_index];
5342 priv->stats.slide_evm_total -= last_evm;
5345 priv->stats.slide_evm_total += pprevious_stats->SignalQuality;
5347 priv->stats.slide_evm[slide_evm_index++] = pprevious_stats->SignalQuality;
5348 if(slide_evm_index >= PHY_RSSI_SLID_WIN_MAX)
5349 slide_evm_index = 0;
5351 // <1> Showed on UI for user, in percentage.
5352 tmp_val = priv->stats.slide_evm_total/slide_evm_statistics;
5353 priv->stats.signal_quality = tmp_val;
5354 //cosa add 10/11/2007, Showed on UI for user in Windows Vista, for Link quality.
5355 priv->stats.last_signal_strength_inpercent = tmp_val;
5358 // <2> Showed on UI for engineering
5359 if(pprevious_stats->bPacketToSelf || pprevious_stats->bPacketBeacon || pprevious_stats->bToSelfBA)
5361 for(nspatial_stream = 0; nspatial_stream<2 ; nspatial_stream++) // 2 spatial stream
5363 if(pprevious_stats->RxMIMOSignalQuality[nspatial_stream] != -1)
5365 if(priv->stats.rx_evm_percentage[nspatial_stream] == 0) // initialize
5367 priv->stats.rx_evm_percentage[nspatial_stream] = pprevious_stats->RxMIMOSignalQuality[nspatial_stream];
5369 priv->stats.rx_evm_percentage[nspatial_stream] =
5370 ( (priv->stats.rx_evm_percentage[nspatial_stream]* (Rx_Smooth_Factor-1)) +
5371 (pprevious_stats->RxMIMOSignalQuality[nspatial_stream]* 1)) / (Rx_Smooth_Factor);
5379 static u8 rtl819x_query_rxpwrpercentage(
5383 if ((antpower <= -100) || (antpower >= 20))
5387 else if (antpower >= 0)
5393 return (100+antpower);
5399 rtl819x_evm_dbtopercentage(
5411 ret_val = 0 - ret_val;
5418 /* We want good-looking for signal strength/quality */
5419 static long rtl819x_signal_scale_mapping(long currsig)
5423 // Step 1. Scale mapping.
5424 if(currsig >= 61 && currsig <= 100)
5426 retsig = 90 + ((currsig - 60) / 4);
5428 else if(currsig >= 41 && currsig <= 60)
5430 retsig = 78 + ((currsig - 40) / 2);
5432 else if(currsig >= 31 && currsig <= 40)
5434 retsig = 66 + (currsig - 30);
5436 else if(currsig >= 21 && currsig <= 30)
5438 retsig = 54 + (currsig - 20);
5440 else if(currsig >= 5 && currsig <= 20)
5442 retsig = 42 + (((currsig - 5) * 2) / 3);
5444 else if(currsig == 4)
5448 else if(currsig == 3)
5452 else if(currsig == 2)
5456 else if(currsig == 1)
5468 static void rtl8192_query_rxphystatus(
5469 struct r8192_priv * priv,
5470 struct ieee80211_rx_stats * pstats,
5471 prx_desc_819x_pci pdesc,
5472 prx_fwinfo_819x_pci pdrvinfo,
5473 struct ieee80211_rx_stats * precord_stats,
5474 bool bpacket_match_bssid,
5475 bool bpacket_toself,
5480 //PRT_RFD_STATUS pRtRfdStatus = &(pRfd->Status);
5481 phy_sts_ofdm_819xpci_t* pofdm_buf;
5482 phy_sts_cck_819xpci_t * pcck_buf;
5483 phy_ofdm_rx_status_rxsc_sgien_exintfflag* prxsc;
5485 u8 i,max_spatial_stream, tmp_rxsnr, tmp_rxevm, rxsc_sgien_exflg;
5486 char rx_pwr[4], rx_pwr_all=0;
5487 //long rx_avg_pwr = 0;
5488 char rx_snrX, rx_evmX;
5490 u32 RSSI, total_rssi=0;//, total_evm=0;
5491 // long signal_strength_index = 0;
5495 /* 2007/07/04 MH For OFDM RSSI. For high power or not. */
5496 static u8 check_reg824 = 0;
5497 static u32 reg824_bit9 = 0;
5499 priv->stats.numqry_phystatus++;
5501 is_cck_rate = rx_hal_is_cck_rate(pdrvinfo);
5503 // Record it for next packet processing
5504 memset(precord_stats, 0, sizeof(struct ieee80211_rx_stats));
5505 pstats->bPacketMatchBSSID = precord_stats->bPacketMatchBSSID = bpacket_match_bssid;
5506 pstats->bPacketToSelf = precord_stats->bPacketToSelf = bpacket_toself;
5507 pstats->bIsCCK = precord_stats->bIsCCK = is_cck_rate;//RX_HAL_IS_CCK_RATE(pDrvInfo);
5508 pstats->bPacketBeacon = precord_stats->bPacketBeacon = bPacketBeacon;
5509 pstats->bToSelfBA = precord_stats->bToSelfBA = bToSelfBA;
5510 /*2007.08.30 requested by SD3 Jerry */
5511 if(check_reg824 == 0)
5513 reg824_bit9 = rtl8192_QueryBBReg(priv->ieee80211->dev, rFPGA0_XA_HSSIParameter2, 0x200);
5518 prxpkt = (u8*)pdrvinfo;
5520 /* Move pointer to the 16th bytes. Phy status start address. */
5521 prxpkt += sizeof(rx_fwinfo_819x_pci);
5523 /* Initial the cck and ofdm buffer pointer */
5524 pcck_buf = (phy_sts_cck_819xpci_t *)prxpkt;
5525 pofdm_buf = (phy_sts_ofdm_819xpci_t *)prxpkt;
5527 pstats->RxMIMOSignalQuality[0] = -1;
5528 pstats->RxMIMOSignalQuality[1] = -1;
5529 precord_stats->RxMIMOSignalQuality[0] = -1;
5530 precord_stats->RxMIMOSignalQuality[1] = -1;
5535 // (1)Hardware does not provide RSSI for CCK
5539 // (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive)
5541 u8 report;//, cck_agc_rpt;
5544 char cck_adc_pwdb[4];
5546 priv->stats.numqry_phystatusCCK++;
5548 #ifdef RTL8190P //Only 90P 2T4R need to check
5549 if(priv->rf_type == RF_2T4R && DM_RxPathSelTable.Enable && bpacket_match_bssid)
5551 for(i=RF90_PATH_A; i<RF90_PATH_MAX; i++)
5553 tmp_pwdb = pcck_buf->adc_pwdb_X[i];
5554 cck_adc_pwdb[i] = (char)tmp_pwdb;
5555 cck_adc_pwdb[i] /= 2;
5556 pstats->cck_adc_pwdb[i] = precord_stats->cck_adc_pwdb[i] = cck_adc_pwdb[i];
5557 //DbgPrint("RF-%d tmp_pwdb = 0x%x, cck_adc_pwdb = %d", i, tmp_pwdb, cck_adc_pwdb[i]);
5564 report = pcck_buf->cck_agc_rpt & 0xc0;
5568 //Fixed by Jacken from Bryant 2008-03-20
5569 //Original value is -38 , -26 , -14 , -2
5570 //Fixed value is -35 , -23 , -11 , 6
5572 rx_pwr_all = -35 - (pcck_buf->cck_agc_rpt & 0x3e);
5575 rx_pwr_all = -23 - (pcck_buf->cck_agc_rpt & 0x3e);
5578 rx_pwr_all = -11 - (pcck_buf->cck_agc_rpt & 0x3e);
5581 rx_pwr_all = 8 - (pcck_buf->cck_agc_rpt & 0x3e);
5587 report = pcck_buf->cck_agc_rpt & 0x60;
5592 rx_pwr_all = -35 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1) ;
5595 rx_pwr_all = -23 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1);
5598 rx_pwr_all = -11 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1) ;
5601 rx_pwr_all = -8 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1) ;
5606 pwdb_all = rtl819x_query_rxpwrpercentage(rx_pwr_all);
5607 pstats->RxPWDBAll = precord_stats->RxPWDBAll = pwdb_all;
5608 pstats->RecvSignalPower = rx_pwr_all;
5611 // (3) Get Signal Quality (EVM)
5613 if(bpacket_match_bssid)
5617 if(pstats->RxPWDBAll > 40)
5622 sq = pcck_buf->sq_rpt;
5624 if(pcck_buf->sq_rpt > 64)
5626 else if (pcck_buf->sq_rpt < 20)
5629 sq = ((64-sq) * 100) / 44;
5631 pstats->SignalQuality = precord_stats->SignalQuality = sq;
5632 pstats->RxMIMOSignalQuality[0] = precord_stats->RxMIMOSignalQuality[0] = sq;
5633 pstats->RxMIMOSignalQuality[1] = precord_stats->RxMIMOSignalQuality[1] = -1;
5638 priv->stats.numqry_phystatusHT++;
5640 // (1)Get RSSI for HT rate
5642 for(i=RF90_PATH_A; i<RF90_PATH_MAX; i++)
5644 // 2008/01/30 MH we will judge RF RX path now.
5645 if (priv->brfpath_rxenable[i])
5650 //Fixed by Jacken from Bryant 2008-03-20
5651 //Original value is 106
5652 #ifdef RTL8190P //Modify by Jacken 2008/03/31
5653 rx_pwr[i] = ((pofdm_buf->trsw_gain_X[i]&0x3F)*2) - 106;
5655 rx_pwr[i] = ((pofdm_buf->trsw_gain_X[i]&0x3F)*2) - 110;
5658 //Get Rx snr value in DB
5659 tmp_rxsnr = pofdm_buf->rxsnr_X[i];
5660 rx_snrX = (char)(tmp_rxsnr);
5662 priv->stats.rxSNRdB[i] = (long)rx_snrX;
5664 /* Translate DBM to percentage. */
5665 RSSI = rtl819x_query_rxpwrpercentage(rx_pwr[i]);
5666 if (priv->brfpath_rxenable[i])
5669 /* Record Signal Strength for next packet */
5670 if(bpacket_match_bssid)
5672 pstats->RxMIMOSignalStrength[i] =(u8) RSSI;
5673 precord_stats->RxMIMOSignalStrength[i] =(u8) RSSI;
5679 // (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive)
5681 //Fixed by Jacken from Bryant 2008-03-20
5682 //Original value is 106
5683 rx_pwr_all = (((pofdm_buf->pwdb_all ) >> 1 )& 0x7f) -106;
5684 pwdb_all = rtl819x_query_rxpwrpercentage(rx_pwr_all);
5686 pstats->RxPWDBAll = precord_stats->RxPWDBAll = pwdb_all;
5687 pstats->RxPower = precord_stats->RxPower = rx_pwr_all;
5688 pstats->RecvSignalPower = rx_pwr_all;
5690 // (3)EVM of HT rate
5692 if(pdrvinfo->RxHT && pdrvinfo->RxRate>=DESC90_RATEMCS8 &&
5693 pdrvinfo->RxRate<=DESC90_RATEMCS15)
5694 max_spatial_stream = 2; //both spatial stream make sense
5696 max_spatial_stream = 1; //only spatial stream 1 makes sense
5698 for(i=0; i<max_spatial_stream; i++)
5700 tmp_rxevm = pofdm_buf->rxevm_X[i];
5701 rx_evmX = (char)(tmp_rxevm);
5703 // Do not use shift operation like "rx_evmX >>= 1" because the compilor of free build environment
5704 // fill most significant bit to "zero" when doing shifting operation which may change a negative
5705 // value to positive one, then the dbm value (which is supposed to be negative) is not correct anymore.
5708 evm = rtl819x_evm_dbtopercentage(rx_evmX);
5710 EVM = SignalScaleMapping(EVM);//make it good looking, from 0~100
5712 if(bpacket_match_bssid)
5714 if(i==0) // Fill value in RFD, Get the first spatial stream only
5715 pstats->SignalQuality = precord_stats->SignalQuality = (u8)(evm & 0xff);
5716 pstats->RxMIMOSignalQuality[i] = precord_stats->RxMIMOSignalQuality[i] = (u8)(evm & 0xff);
5721 /* record rx statistics for debug */
5722 rxsc_sgien_exflg = pofdm_buf->rxsc_sgien_exflg;
5723 prxsc = (phy_ofdm_rx_status_rxsc_sgien_exintfflag *)&rxsc_sgien_exflg;
5724 if(pdrvinfo->BW) //40M channel
5725 priv->stats.received_bwtype[1+prxsc->rxsc]++;
5727 priv->stats.received_bwtype[0]++;
5730 //UI BSS List signal strength(in percentage), make it good looking, from 0~100.
5731 //It is assigned to the BSS List in GetValueFromBeaconOrProbeRsp().
5734 pstats->SignalStrength = precord_stats->SignalStrength = (u8)(rtl819x_signal_scale_mapping((long)pwdb_all));//PWDB_ALL;
5739 //pRfd->Status.SignalStrength = pRecordRfd->Status.SignalStrength = (u1Byte)(SignalScaleMapping(total_rssi/=RF90_PATH_MAX));//(u1Byte)(total_rssi/=RF90_PATH_MAX);
5740 // We can judge RX path number now.
5742 pstats->SignalStrength = precord_stats->SignalStrength = (u8)(rtl819x_signal_scale_mapping((long)(total_rssi/=rf_rx_num)));
5747 rtl8192_record_rxdesc_forlateruse(
5748 struct ieee80211_rx_stats * psrc_stats,
5749 struct ieee80211_rx_stats * ptarget_stats
5752 ptarget_stats->bIsAMPDU = psrc_stats->bIsAMPDU;
5753 ptarget_stats->bFirstMPDU = psrc_stats->bFirstMPDU;
5754 //ptarget_stats->Seq_Num = psrc_stats->Seq_Num;
5759 static void TranslateRxSignalStuff819xpci(struct net_device *dev,
5760 struct sk_buff *skb,
5761 struct ieee80211_rx_stats * pstats,
5762 prx_desc_819x_pci pdesc,
5763 prx_fwinfo_819x_pci pdrvinfo)
5765 // TODO: We must only check packet for current MAC address. Not finish
5766 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
5767 bool bpacket_match_bssid, bpacket_toself;
5768 bool bPacketBeacon=false, bToSelfBA=false;
5769 static struct ieee80211_rx_stats previous_stats;
5770 struct ieee80211_hdr_3addr *hdr;
5773 // Get Signal Quality for only RX data queue (but not command queue)
5778 /* Get MAC frame start address. */
5779 tmp_buf = skb->data;
5781 hdr = (struct ieee80211_hdr_3addr *)tmp_buf;
5782 fc = le16_to_cpu(hdr->frame_ctl);
5783 type = WLAN_FC_GET_TYPE(fc);
5784 praddr = hdr->addr1;
5786 /* Check if the received packet is acceptabe. */
5787 bpacket_match_bssid = ((IEEE80211_FTYPE_CTL != type) &&
5788 (eqMacAddr(priv->ieee80211->current_network.bssid, (fc & IEEE80211_FCTL_TODS)? hdr->addr1 : (fc & IEEE80211_FCTL_FROMDS )? hdr->addr2 : hdr->addr3))
5789 && (!pstats->bHwError) && (!pstats->bCRC)&& (!pstats->bICV));
5790 bpacket_toself = bpacket_match_bssid & (eqMacAddr(praddr, priv->ieee80211->dev->dev_addr));
5792 if(WLAN_FC_GET_FRAMETYPE(fc)== IEEE80211_STYPE_BEACON)
5794 bPacketBeacon = true;
5795 //DbgPrint("Beacon 2, MatchBSSID = %d, ToSelf = %d \n", bPacketMatchBSSID, bPacketToSelf);
5797 if(WLAN_FC_GET_FRAMETYPE(fc) == IEEE80211_STYPE_BLOCKACK)
5799 if((eqMacAddr(praddr,dev->dev_addr)))
5801 //DbgPrint("BlockAck, MatchBSSID = %d, ToSelf = %d \n", bPacketMatchBSSID, bPacketToSelf);
5805 if(bpacket_match_bssid)
5807 priv->stats.numpacket_matchbssid++;
5810 priv->stats.numpacket_toself++;
5813 // Process PHY information for previous packet (RSSI/PWDB/EVM)
5815 // Because phy information is contained in the last packet of AMPDU only, so driver
5816 // should process phy information of previous packet
5817 rtl8192_process_phyinfo(priv, tmp_buf,&previous_stats, pstats);
5818 rtl8192_query_rxphystatus(priv, pstats, pdesc, pdrvinfo, &previous_stats, bpacket_match_bssid,
5819 bpacket_toself ,bPacketBeacon, bToSelfBA);
5820 rtl8192_record_rxdesc_forlateruse(pstats, &previous_stats);
5825 static void rtl8192_tx_resume(struct net_device *dev)
5827 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
5828 struct ieee80211_device *ieee = priv->ieee80211;
5829 struct sk_buff *skb;
5832 for(queue_index = BK_QUEUE; queue_index < TXCMD_QUEUE;queue_index++) {
5833 while((!skb_queue_empty(&ieee->skb_waitQ[queue_index]))&&
5834 (priv->ieee80211->check_nic_enough_desc(dev,queue_index) > 0)) {
5835 /* 1. dequeue the packet from the wait queue */
5836 skb = skb_dequeue(&ieee->skb_waitQ[queue_index]);
5837 /* 2. tx the packet directly */
5838 ieee->softmac_data_hard_start_xmit(skb,dev,0/* rate useless now*/);
5840 if(queue_index!=MGNT_QUEUE) {
5841 ieee->stats.tx_packets++;
5842 ieee->stats.tx_bytes += skb->len;
5849 static void rtl8192_irq_tx_tasklet(struct r8192_priv *priv)
5851 rtl8192_tx_resume(priv->ieee80211->dev);
5854 /* Record the received data rate */
5855 static void UpdateReceivedRateHistogramStatistics8190(
5856 struct net_device *dev,
5857 struct ieee80211_rx_stats* pstats
5860 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
5861 u32 rcvType=1; //0: Total, 1:OK, 2:CRC, 3:ICV
5863 u32 preamble_guardinterval; //1: short preamble/GI, 0: long preamble/GI
5867 else if(pstats->bICV)
5870 if(pstats->bShortPreamble)
5871 preamble_guardinterval = 1;// short
5873 preamble_guardinterval = 0;// long
5875 switch(pstats->rate)
5880 case MGN_1M: rateIndex = 0; break;
5881 case MGN_2M: rateIndex = 1; break;
5882 case MGN_5_5M: rateIndex = 2; break;
5883 case MGN_11M: rateIndex = 3; break;
5887 case MGN_6M: rateIndex = 4; break;
5888 case MGN_9M: rateIndex = 5; break;
5889 case MGN_12M: rateIndex = 6; break;
5890 case MGN_18M: rateIndex = 7; break;
5891 case MGN_24M: rateIndex = 8; break;
5892 case MGN_36M: rateIndex = 9; break;
5893 case MGN_48M: rateIndex = 10; break;
5894 case MGN_54M: rateIndex = 11; break;
5896 // 11n High throughput rate
5898 case MGN_MCS0: rateIndex = 12; break;
5899 case MGN_MCS1: rateIndex = 13; break;
5900 case MGN_MCS2: rateIndex = 14; break;
5901 case MGN_MCS3: rateIndex = 15; break;
5902 case MGN_MCS4: rateIndex = 16; break;
5903 case MGN_MCS5: rateIndex = 17; break;
5904 case MGN_MCS6: rateIndex = 18; break;
5905 case MGN_MCS7: rateIndex = 19; break;
5906 case MGN_MCS8: rateIndex = 20; break;
5907 case MGN_MCS9: rateIndex = 21; break;
5908 case MGN_MCS10: rateIndex = 22; break;
5909 case MGN_MCS11: rateIndex = 23; break;
5910 case MGN_MCS12: rateIndex = 24; break;
5911 case MGN_MCS13: rateIndex = 25; break;
5912 case MGN_MCS14: rateIndex = 26; break;
5913 case MGN_MCS15: rateIndex = 27; break;
5914 default: rateIndex = 28; break;
5916 priv->stats.received_preamble_GI[preamble_guardinterval][rateIndex]++;
5917 priv->stats.received_rate_histogram[0][rateIndex]++; //total
5918 priv->stats.received_rate_histogram[rcvType][rateIndex]++;
5921 static void rtl8192_rx(struct net_device *dev)
5923 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
5924 struct ieee80211_hdr_1addr *ieee80211_hdr = NULL;
5925 bool unicast_packet = false;
5926 struct ieee80211_rx_stats stats = {
5930 .freq = IEEE80211_24GHZ_BAND,
5932 unsigned int count = priv->rxringcount;
5934 stats.nic_type = NIC_8192E;
5937 rx_desc_819x_pci *pdesc = &priv->rx_ring[priv->rx_idx];//rx descriptor
5938 struct sk_buff *skb = priv->rx_buf[priv->rx_idx];//rx pkt
5941 /* wait data to be filled by hardware */
5944 stats.bICV = pdesc->ICV;
5945 stats.bCRC = pdesc->CRC32;
5946 stats.bHwError = pdesc->CRC32 | pdesc->ICV;
5948 stats.Length = pdesc->Length;
5949 if(stats.Length < 24)
5950 stats.bHwError |= 1;
5952 if(stats.bHwError) {
5953 stats.bShift = false;
5956 if (pdesc->Length <500)
5957 priv->stats.rxcrcerrmin++;
5958 else if (pdesc->Length >1000)
5959 priv->stats.rxcrcerrmax++;
5961 priv->stats.rxcrcerrmid++;
5965 prx_fwinfo_819x_pci pDrvInfo = NULL;
5966 struct sk_buff *new_skb = dev_alloc_skb(priv->rxbuffersize);
5968 if (unlikely(!new_skb)) {
5972 stats.RxDrvInfoSize = pdesc->RxDrvInfoSize;
5973 stats.RxBufShift = ((pdesc->Shift)&0x03);
5974 stats.Decrypted = !pdesc->SWDec;
5976 pci_dma_sync_single_for_cpu(priv->pdev,
5977 *((dma_addr_t *)skb->cb),
5979 PCI_DMA_FROMDEVICE);
5980 skb_put(skb, pdesc->Length);
5981 pDrvInfo = (rx_fwinfo_819x_pci *)(skb->data + stats.RxBufShift);
5982 skb_reserve(skb, stats.RxDrvInfoSize + stats.RxBufShift);
5984 stats.rate = HwRateToMRate90((bool)pDrvInfo->RxHT, (u8)pDrvInfo->RxRate);
5985 stats.bShortPreamble = pDrvInfo->SPLCP;
5987 /* it is debug only. It should be disabled in released driver.
5988 * 2007.1.11 by Emily
5990 UpdateReceivedRateHistogramStatistics8190(dev, &stats);
5992 stats.bIsAMPDU = (pDrvInfo->PartAggr==1);
5993 stats.bFirstMPDU = (pDrvInfo->PartAggr==1) && (pDrvInfo->FirstAGGR==1);
5995 stats.TimeStampLow = pDrvInfo->TSFL;
5996 stats.TimeStampHigh = read_nic_dword(dev, TSFR+4);
5998 UpdateRxPktTimeStamp8190(dev, &stats);
6001 // Get Total offset of MPDU Frame Body
6003 if((stats.RxBufShift + stats.RxDrvInfoSize) > 0)
6006 stats.RxIs40MHzPacket = pDrvInfo->BW;
6009 TranslateRxSignalStuff819xpci(dev,skb, &stats, pdesc, pDrvInfo);
6012 if(pDrvInfo->FirstAGGR==1 || pDrvInfo->PartAggr == 1)
6013 RT_TRACE(COMP_RXDESC, "pDrvInfo->FirstAGGR = %d, pDrvInfo->PartAggr = %d\n",
6014 pDrvInfo->FirstAGGR, pDrvInfo->PartAggr);
6015 skb_trim(skb, skb->len - 4/*sCrcLng*/);
6016 /* rx packets statistics */
6017 ieee80211_hdr = (struct ieee80211_hdr_1addr *)skb->data;
6018 unicast_packet = false;
6020 if(is_broadcast_ether_addr(ieee80211_hdr->addr1)) {
6022 }else if(is_multicast_ether_addr(ieee80211_hdr->addr1)){
6025 /* unicast packet */
6026 unicast_packet = true;
6029 stats.packetlength = stats.Length-4;
6030 stats.fraglength = stats.packetlength;
6031 stats.fragoffset = 0;
6032 stats.ntotalfrag = 1;
6034 if(!ieee80211_rtl_rx(priv->ieee80211, skb, &stats)){
6035 dev_kfree_skb_any(skb);
6038 if(unicast_packet) {
6039 priv->stats.rxbytesunicast += skb->len;
6044 priv->rx_buf[priv->rx_idx] = skb;
6045 *((dma_addr_t *) skb->cb) = pci_map_single(priv->pdev, skb_tail_pointer(skb), priv->rxbuffersize, PCI_DMA_FROMDEVICE);
6050 pdesc->BufferAddress = cpu_to_le32(*((dma_addr_t *)skb->cb));
6052 pdesc->Length = priv->rxbuffersize;
6053 if (priv->rx_idx == priv->rxringcount-1)
6055 priv->rx_idx = (priv->rx_idx + 1) % priv->rxringcount;
6060 static void rtl8192_irq_rx_tasklet(struct r8192_priv *priv)
6062 rtl8192_rx(priv->ieee80211->dev);
6064 write_nic_dword(priv->ieee80211->dev, INTA_MASK,read_nic_dword(priv->ieee80211->dev, INTA_MASK) | IMR_RDU);
6067 static const struct net_device_ops rtl8192_netdev_ops = {
6068 .ndo_open = rtl8192_open,
6069 .ndo_stop = rtl8192_close,
6070 .ndo_tx_timeout = tx_timeout,
6071 .ndo_do_ioctl = rtl8192_ioctl,
6072 .ndo_set_multicast_list = r8192_set_multicast,
6073 .ndo_set_mac_address = r8192_set_mac_adr,
6074 .ndo_start_xmit = ieee80211_rtl_xmit,
6077 static int __devinit rtl8192_pci_probe(struct pci_dev *pdev,
6078 const struct pci_device_id *id)
6080 unsigned long ioaddr = 0;
6081 struct net_device *dev = NULL;
6082 struct r8192_priv *priv= NULL;
6086 #ifdef CONFIG_RTL8192_IO_MAP
6087 unsigned long pio_start, pio_len, pio_flags;
6089 unsigned long pmem_start, pmem_len, pmem_flags;
6090 #endif //end #ifdef RTL_IO_MAP
6092 RT_TRACE(COMP_INIT,"Configuring chip resources");
6094 if( pci_enable_device (pdev) ){
6095 RT_TRACE(COMP_ERR,"Failed to enable PCI device");
6099 pci_set_master(pdev);
6100 //pci_set_wmi(pdev);
6101 pci_set_dma_mask(pdev, 0xffffff00ULL);
6102 pci_set_consistent_dma_mask(pdev,0xffffff00ULL);
6103 dev = alloc_ieee80211(sizeof(struct r8192_priv));
6109 pci_set_drvdata(pdev, dev);
6110 SET_NETDEV_DEV(dev, &pdev->dev);
6111 priv = ieee80211_priv(dev);
6112 priv->ieee80211 = netdev_priv(dev);
6114 if((pdev->subsystem_vendor == PCI_VENDOR_ID_DLINK)&&(pdev->subsystem_device == 0x3304)){
6115 priv->ieee80211->bSupportRemoteWakeUp = 1;
6118 priv->ieee80211->bSupportRemoteWakeUp = 0;
6121 #ifdef CONFIG_RTL8192_IO_MAP
6123 pio_start = (unsigned long)pci_resource_start (pdev, 0);
6124 pio_len = (unsigned long)pci_resource_len (pdev, 0);
6125 pio_flags = (unsigned long)pci_resource_flags (pdev, 0);
6127 if (!(pio_flags & IORESOURCE_IO)) {
6128 RT_TRACE(COMP_ERR,"region #0 not a PIO resource, aborting");
6132 //DMESG("IO space @ 0x%08lx", pio_start );
6133 if( ! request_region( pio_start, pio_len, RTL819xE_MODULE_NAME ) ){
6134 RT_TRACE(COMP_ERR,"request_region failed!");
6139 dev->base_addr = ioaddr; // device I/O address
6143 pmem_start = pci_resource_start(pdev, 1);
6144 pmem_len = pci_resource_len(pdev, 1);
6145 pmem_flags = pci_resource_flags (pdev, 1);
6147 if (!(pmem_flags & IORESOURCE_MEM)) {
6148 RT_TRACE(COMP_ERR,"region #1 not a MMIO resource, aborting");
6152 //DMESG("Memory mapped space @ 0x%08lx ", pmem_start);
6153 if( ! request_mem_region(pmem_start, pmem_len, RTL819xE_MODULE_NAME)) {
6154 RT_TRACE(COMP_ERR,"request_mem_region failed!");
6159 ioaddr = (unsigned long)ioremap_nocache( pmem_start, pmem_len);
6160 if( ioaddr == (unsigned long)NULL ){
6161 RT_TRACE(COMP_ERR,"ioremap failed!");
6162 // release_mem_region( pmem_start, pmem_len );
6166 dev->mem_start = ioaddr; // shared mem start
6167 dev->mem_end = ioaddr + pci_resource_len(pdev, 0); // shared mem end
6169 #endif //end #ifdef RTL_IO_MAP
6171 /* We disable the RETRY_TIMEOUT register (0x41) to keep
6172 * PCI Tx retries from interfering with C3 CPU state */
6173 pci_write_config_byte(pdev, 0x41, 0x00);
6176 pci_read_config_byte(pdev, 0x05, &unit);
6177 pci_write_config_byte(pdev, 0x05, unit & (~0x04));
6179 dev->irq = pdev->irq;
6182 dev->netdev_ops = &rtl8192_netdev_ops;
6184 dev->open = rtl8192_open;
6185 dev->stop = rtl8192_close;
6186 //dev->hard_start_xmit = rtl8192_8023_hard_start_xmit;
6187 dev->tx_timeout = tx_timeout;
6188 //dev->wireless_handlers = &r8192_wx_handlers_def;
6189 dev->do_ioctl = rtl8192_ioctl;
6190 dev->set_multicast_list = r8192_set_multicast;
6191 dev->set_mac_address = r8192_set_mac_adr;
6194 //DMESG("Oops: i'm coming\n");
6195 #if WIRELESS_EXT >= 12
6196 #if WIRELESS_EXT < 17
6197 dev->get_wireless_stats = r8192_get_wireless_stats;
6199 dev->wireless_handlers = (struct iw_handler_def *) &r8192_wx_handlers_def;
6201 //dev->get_wireless_stats = r8192_get_wireless_stats;
6202 dev->type=ARPHRD_ETHER;
6204 dev->watchdog_timeo = HZ*3; //modified by john, 0805
6206 if (dev_alloc_name(dev, ifname) < 0){
6207 RT_TRACE(COMP_INIT, "Oops: devname already taken! Trying wlan%%d...\n");
6208 strcpy(ifname, "wlan%d");
6209 dev_alloc_name(dev, ifname);
6212 RT_TRACE(COMP_INIT, "Driver probe completed1\n");
6213 if(rtl8192_init(dev)!=0){
6214 RT_TRACE(COMP_ERR, "Initialization failed");
6218 netif_carrier_off(dev);
6219 netif_stop_queue(dev);
6221 register_netdev(dev);
6222 RT_TRACE(COMP_INIT, "dev name=======> %s\n",dev->name);
6223 rtl8192_proc_init_one(dev);
6226 RT_TRACE(COMP_INIT, "Driver probe completed\n");
6231 #ifdef CONFIG_RTL8180_IO_MAP
6233 if( dev->base_addr != 0 ){
6235 release_region(dev->base_addr,
6236 pci_resource_len(pdev, 0) );
6239 if( dev->mem_start != (unsigned long)NULL ){
6240 iounmap( (void *)dev->mem_start );
6241 release_mem_region( pci_resource_start(pdev, 1),
6242 pci_resource_len(pdev, 1) );
6244 #endif //end #ifdef RTL_IO_MAP
6250 free_irq(dev->irq, dev);
6253 free_ieee80211(dev);
6257 pci_disable_device(pdev);
6259 DMESG("wlan driver load failed\n");
6260 pci_set_drvdata(pdev, NULL);
6265 /* detach all the work and timer structure declared or inititialized
6266 * in r8192_init function.
6268 static void rtl8192_cancel_deferred_work(struct r8192_priv* priv)
6270 /* call cancel_work_sync instead of cancel_delayed_work if and only if Linux_version_code
6271 * is or is newer than 2.6.20 and work structure is defined to be struct work_struct.
6272 * Otherwise call cancel_delayed_work is enough.
6273 * FIXME (2.6.20 should 2.6.22, work_struct should not cancel)
6275 cancel_delayed_work(&priv->watch_dog_wq);
6276 cancel_delayed_work(&priv->update_beacon_wq);
6277 cancel_delayed_work(&priv->ieee80211->hw_wakeup_wq);
6278 cancel_delayed_work(&priv->ieee80211->hw_sleep_wq);
6280 cancel_delayed_work(&priv->gpio_change_rf_wq);
6282 cancel_work_sync(&priv->reset_wq);
6283 cancel_work_sync(&priv->qos_activate);
6284 //cancel_work_sync(&priv->SetBWModeWorkItem);
6285 //cancel_work_sync(&priv->SwChnlWorkItem);
6290 static void __devexit rtl8192_pci_disconnect(struct pci_dev *pdev)
6292 struct net_device *dev = pci_get_drvdata(pdev);
6293 struct r8192_priv *priv ;
6297 unregister_netdev(dev);
6299 priv=ieee80211_priv(dev);
6301 rtl8192_proc_remove_one(dev);
6304 if (priv->pFirmware)
6306 vfree(priv->pFirmware);
6307 priv->pFirmware = NULL;
6309 // priv->rf_close(dev);
6310 // rtl8192_usb_deleteendpoints(dev);
6311 destroy_workqueue(priv->priv_wq);
6312 /* redundant with rtl8192_down */
6313 // rtl8192_irq_disable(dev);
6314 // rtl8192_reset(dev);
6318 /* free tx/rx rings */
6319 rtl8192_free_rx_ring(dev);
6320 for (i = 0; i < MAX_TX_QUEUE_COUNT; i++) {
6321 rtl8192_free_tx_ring(dev, i);
6326 printk("Freeing irq %d\n",dev->irq);
6327 free_irq(dev->irq, dev);
6334 // free_beacon_desc_ring(dev,priv->txbeaconcount);
6336 #ifdef CONFIG_RTL8180_IO_MAP
6338 if( dev->base_addr != 0 ){
6340 release_region(dev->base_addr,
6341 pci_resource_len(pdev, 0) );
6344 if( dev->mem_start != (unsigned long)NULL ){
6345 iounmap( (void *)dev->mem_start );
6346 release_mem_region( pci_resource_start(pdev, 1),
6347 pci_resource_len(pdev, 1) );
6349 #endif /*end #ifdef RTL_IO_MAP*/
6350 free_ieee80211(dev);
6354 pci_disable_device(pdev);
6355 RT_TRACE(COMP_DOWN, "wlan driver removed\n");
6358 extern int ieee80211_rtl_init(void);
6359 extern void ieee80211_rtl_exit(void);
6361 static int __init rtl8192_pci_module_init(void)
6365 retval = ieee80211_rtl_init();
6369 printk(KERN_INFO "\nLinux kernel driver for RTL8192 based WLAN cards\n");
6370 printk(KERN_INFO "Copyright (c) 2007-2008, Realsil Wlan\n");
6371 RT_TRACE(COMP_INIT, "Initializing module");
6372 RT_TRACE(COMP_INIT, "Wireless extensions version %d", WIRELESS_EXT);
6373 rtl8192_proc_module_init();
6374 if(0!=pci_register_driver(&rtl8192_pci_driver))
6376 DMESG("No device found");
6377 /*pci_unregister_driver (&rtl8192_pci_driver);*/
6384 static void __exit rtl8192_pci_module_exit(void)
6386 pci_unregister_driver(&rtl8192_pci_driver);
6388 RT_TRACE(COMP_DOWN, "Exiting");
6389 rtl8192_proc_module_remove();
6390 ieee80211_rtl_exit();
6393 //warning message WB
6394 static irqreturn_t rtl8192_interrupt(int irq, void *netdev)
6396 struct net_device *dev = (struct net_device *) netdev;
6397 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
6398 unsigned long flags;
6400 /* We should return IRQ_NONE, but for now let me keep this */
6401 if(priv->irq_enabled == 0){
6405 spin_lock_irqsave(&priv->irq_th_lock,flags);
6409 inta = read_nic_dword(dev, ISR);// & priv->IntrMask;
6410 write_nic_dword(dev,ISR,inta); // reset int situation
6412 priv->stats.shints++;
6413 //DMESG("Enter interrupt, ISR value = 0x%08x", inta);
6415 spin_unlock_irqrestore(&priv->irq_th_lock,flags);
6418 most probably we can safely return IRQ_NONE,
6419 but for now is better to avoid problems
6425 spin_unlock_irqrestore(&priv->irq_th_lock,flags);
6431 DMESG("NIC irq %x",inta);
6433 //priv->irqpending = inta;
6436 if(!netif_running(dev)) {
6437 spin_unlock_irqrestore(&priv->irq_th_lock,flags);
6441 if(inta & IMR_TIMEOUT0){
6442 // write_nic_dword(dev, TimerInt, 0);
6443 //DMESG("=================>waking up");
6444 // rtl8180_hw_wakeup(dev);
6447 if(inta & IMR_TBDOK){
6448 RT_TRACE(COMP_INTR, "beacon ok interrupt!\n");
6449 rtl8192_tx_isr(dev, BEACON_QUEUE);
6450 priv->stats.txbeaconokint++;
6453 if(inta & IMR_TBDER){
6454 RT_TRACE(COMP_INTR, "beacon ok interrupt!\n");
6455 rtl8192_tx_isr(dev, BEACON_QUEUE);
6456 priv->stats.txbeaconerr++;
6459 if(inta & IMR_MGNTDOK ) {
6460 RT_TRACE(COMP_INTR, "Manage ok interrupt!\n");
6461 priv->stats.txmanageokint++;
6462 rtl8192_tx_isr(dev,MGNT_QUEUE);
6466 if(inta & IMR_COMDOK)
6468 priv->stats.txcmdpktokint++;
6469 rtl8192_tx_isr(dev,TXCMD_QUEUE);
6474 DMESG("Frame arrived !");
6476 priv->stats.rxint++;
6477 tasklet_schedule(&priv->irq_rx_tasklet);
6480 if(inta & IMR_BcnInt) {
6481 RT_TRACE(COMP_INTR, "prepare beacon for interrupt!\n");
6482 tasklet_schedule(&priv->irq_prepare_beacon_tasklet);
6486 RT_TRACE(COMP_INTR, "rx descriptor unavailable!\n");
6487 priv->stats.rxrdu++;
6488 /* reset int situation */
6489 write_nic_dword(dev,INTA_MASK,read_nic_dword(dev, INTA_MASK) & ~IMR_RDU);
6490 tasklet_schedule(&priv->irq_rx_tasklet);
6493 if(inta & IMR_RXFOVW){
6494 RT_TRACE(COMP_INTR, "rx overflow !\n");
6495 priv->stats.rxoverflow++;
6496 tasklet_schedule(&priv->irq_rx_tasklet);
6499 if(inta & IMR_TXFOVW) priv->stats.txoverflow++;
6501 if(inta & IMR_BKDOK){
6502 RT_TRACE(COMP_INTR, "BK Tx OK interrupt!\n");
6503 priv->stats.txbkokint++;
6504 priv->ieee80211->LinkDetectInfo.NumTxOkInPeriod++;
6505 rtl8192_tx_isr(dev,BK_QUEUE);
6506 rtl8192_try_wake_queue(dev, BK_QUEUE);
6509 if(inta & IMR_BEDOK){
6510 RT_TRACE(COMP_INTR, "BE TX OK interrupt!\n");
6511 priv->stats.txbeokint++;
6512 priv->ieee80211->LinkDetectInfo.NumTxOkInPeriod++;
6513 rtl8192_tx_isr(dev,BE_QUEUE);
6514 rtl8192_try_wake_queue(dev, BE_QUEUE);
6517 if(inta & IMR_VIDOK){
6518 RT_TRACE(COMP_INTR, "VI TX OK interrupt!\n");
6519 priv->stats.txviokint++;
6520 priv->ieee80211->LinkDetectInfo.NumTxOkInPeriod++;
6521 rtl8192_tx_isr(dev,VI_QUEUE);
6522 rtl8192_try_wake_queue(dev, VI_QUEUE);
6525 if(inta & IMR_VODOK){
6526 priv->stats.txvookint++;
6527 priv->ieee80211->LinkDetectInfo.NumTxOkInPeriod++;
6528 rtl8192_tx_isr(dev,VO_QUEUE);
6529 rtl8192_try_wake_queue(dev, VO_QUEUE);
6532 spin_unlock_irqrestore(&priv->irq_th_lock,flags);
6537 static void rtl8192_try_wake_queue(struct net_device *dev, int pri)
6542 void EnableHWSecurityConfig8192(struct net_device *dev)
6544 u8 SECR_value = 0x0;
6545 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
6546 struct ieee80211_device* ieee = priv->ieee80211;
6548 SECR_value = SCR_TxEncEnable | SCR_RxDecEnable;
6550 if (((KEY_TYPE_WEP40 == ieee->pairwise_key_type) || (KEY_TYPE_WEP104 == ieee->pairwise_key_type)) && (priv->ieee80211->auth_mode != 2))
6552 SECR_value |= SCR_RxUseDK;
6553 SECR_value |= SCR_TxUseDK;
6555 else if ((ieee->iw_mode == IW_MODE_ADHOC) && (ieee->pairwise_key_type & (KEY_TYPE_CCMP | KEY_TYPE_TKIP)))
6557 SECR_value |= SCR_RxUseDK;
6558 SECR_value |= SCR_TxUseDK;
6563 //add HWSec active enable here.
6564 //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
6565 ieee->hwsec_active = 1;
6567 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
6569 ieee->hwsec_active = 0;
6570 SECR_value &= ~SCR_RxDecEnable;
6573 RT_TRACE(COMP_SEC,"%s:, hwsec:%d, pairwise_key:%d, SECR_value:%x\n", __FUNCTION__,
6574 ieee->hwsec_active, ieee->pairwise_key_type, SECR_value);
6576 write_nic_byte(dev, SECR, SECR_value);//SECR_value | SCR_UseDK );
6580 #define TOTAL_CAM_ENTRY 32
6581 //#define CAM_CONTENT_COUNT 8
6582 void setKey( struct net_device *dev,
6590 u32 TargetCommand = 0;
6591 u32 TargetContent = 0;
6595 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
6596 RT_RF_POWER_STATE rtState;
6597 rtState = priv->ieee80211->eRFPowerState;
6598 if(priv->ieee80211->PowerSaveControl.bInactivePs){
6599 if(rtState == eRfOff){
6600 if(priv->ieee80211->RfOffReason > RF_CHANGE_BY_IPS)
6602 RT_TRACE(COMP_ERR, "%s(): RF is OFF.\n",__FUNCTION__);
6603 //up(&priv->wx_sem);
6607 down(&priv->ieee80211->ips_sem);
6609 up(&priv->ieee80211->ips_sem);
6613 priv->ieee80211->is_set_key = true;
6615 if (EntryNo >= TOTAL_CAM_ENTRY)
6616 RT_TRACE(COMP_ERR, "cam entry exceeds in setKey()\n");
6618 RT_TRACE(COMP_SEC, "====>to setKey(), dev:%p, EntryNo:%d, KeyIndex:%d, KeyType:%d, MacAddr%pM\n", dev,EntryNo, KeyIndex, KeyType, MacAddr);
6621 usConfig |= BIT15 | (KeyType<<2);
6623 usConfig |= BIT15 | (KeyType<<2) | KeyIndex;
6624 // usConfig |= BIT15 | (KeyType<<2) | (DefaultKey<<5) | KeyIndex;
6627 for(i=0 ; i<CAM_CONTENT_COUNT; i++){
6628 TargetCommand = i+CAM_CONTENT_COUNT*EntryNo;
6629 TargetCommand |= BIT31|BIT16;
6631 if(i==0){//MAC|Config
6632 TargetContent = (u32)(*(MacAddr+0)) << 16|
6633 (u32)(*(MacAddr+1)) << 24|
6636 write_nic_dword(dev, WCAMI, TargetContent);
6637 write_nic_dword(dev, RWCAM, TargetCommand);
6638 // printk("setkey cam =%8x\n", read_cam(dev, i+6*EntryNo));
6641 TargetContent = (u32)(*(MacAddr+2)) |
6642 (u32)(*(MacAddr+3)) << 8|
6643 (u32)(*(MacAddr+4)) << 16|
6644 (u32)(*(MacAddr+5)) << 24;
6645 write_nic_dword(dev, WCAMI, TargetContent);
6646 write_nic_dword(dev, RWCAM, TargetCommand);
6648 else { //Key Material
6649 if(KeyContent != NULL)
6651 write_nic_dword(dev, WCAMI, (u32)(*(KeyContent+i-2)) );
6652 write_nic_dword(dev, RWCAM, TargetCommand);
6656 RT_TRACE(COMP_SEC,"=========>after set key, usconfig:%x\n", usConfig);
6659 bool NicIFEnableNIC(struct net_device* dev)
6661 RT_STATUS init_status = RT_STATUS_SUCCESS;
6662 struct r8192_priv* priv = ieee80211_priv(dev);
6663 PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->ieee80211->PowerSaveControl));
6667 RT_TRACE(COMP_ERR, "ERR!!! %s(): Driver is already down!\n",__FUNCTION__);
6668 priv->bdisable_nic = false; //YJ,add,091111
6671 // <1> Reset memory: descriptor, buffer,..
6672 //NicIFResetMemory(Adapter);
6674 // <2> Enable Adapter
6675 //priv->bfirst_init = true;
6676 init_status = rtl8192_adapter_start(dev);
6677 if (init_status != RT_STATUS_SUCCESS) {
6678 RT_TRACE(COMP_ERR,"ERR!!! %s(): initialization is failed!\n",__FUNCTION__);
6679 priv->bdisable_nic = false; //YJ,add,091111
6682 //printk("start adapter finished\n");
6683 RT_CLEAR_PS_LEVEL(pPSC, RT_RF_OFF_LEVL_HALT_NIC);
6684 //priv->bfirst_init = false;
6686 // <3> Enable Interrupt
6687 rtl8192_irq_enable(dev);
6688 priv->bdisable_nic = false;
6690 return (init_status == RT_STATUS_SUCCESS);
6693 bool NicIFDisableNIC(struct net_device* dev)
6696 struct r8192_priv* priv = ieee80211_priv(dev);
6698 // <1> Disable Interrupt
6700 priv->bdisable_nic = true; //YJ,move,091109
6701 tmp_state = priv->ieee80211->state;
6703 ieee80211_softmac_stop_protocol(priv->ieee80211, false);
6705 priv->ieee80211->state = tmp_state;
6706 rtl8192_cancel_deferred_work(priv);
6707 rtl8192_irq_disable(dev);
6708 // <2> Stop all timer
6710 // <3> Disable Adapter
6711 rtl8192_halt_adapter(dev, false);
6712 // priv->bdisable_nic = true;
6717 module_init(rtl8192_pci_module_init);
6718 module_exit(rtl8192_pci_module_exit);