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>
28 #undef RX_DONT_PASS_UL
30 #undef DEBUG_RX_VERBOSE
36 #undef DEBUG_TX_FILLDESC
41 #undef DEBUG_REGISTERS
43 #undef DEBUG_IRQ_TASKLET
47 //#define CONFIG_RTL8192_IO_MAP
48 #include <linux/vmalloc.h>
49 #include <linux/slab.h>
50 #include <asm/uaccess.h>
51 #include "r8192E_hw.h"
53 #include "r8190_rtl8256.h" /* RTL8225 Radio frontend */
54 #include "r8180_93cx6.h" /* Card EEPROM */
55 #include "r8192E_wx.h"
56 #include "r819xE_phy.h" //added by WB 4.30.2008
57 #include "r819xE_phyreg.h"
58 #include "r819xE_cmdpkt.h"
59 #include "r8192E_dm.h"
66 #include "ieee80211/dot11d.h"
69 //set here to open your trace code. //WB
70 u32 rt_global_debug_component =
88 // COMP_POWER_TRACKING |
90 COMP_ERR ; //always open err flags on
92 static const struct pci_device_id rtl8192_pci_id_tbl[] __devinitdata = {
96 { PCI_DEVICE(0x10ec, 0x8190) },
98 { PCI_DEVICE(0x07aa, 0x0045) },
99 { PCI_DEVICE(0x07aa, 0x0046) },
102 { PCI_DEVICE(0x10ec, 0x8192) },
105 { PCI_DEVICE(0x07aa, 0x0044) },
106 { PCI_DEVICE(0x07aa, 0x0047) },
111 static char ifname[IFNAMSIZ] = "wlan%d";
112 static int hwwep = 1; //default use hw. set 0 to use software security
113 static int channels = 0x3fff;
115 MODULE_LICENSE("GPL");
116 MODULE_VERSION("V 1.1");
117 MODULE_DEVICE_TABLE(pci, rtl8192_pci_id_tbl);
118 //MODULE_AUTHOR("Andrea Merello <andreamrl@tiscali.it>");
119 MODULE_DESCRIPTION("Linux driver for Realtek RTL819x WiFi cards");
122 module_param_string(ifname, ifname, sizeof(ifname), S_IRUGO|S_IWUSR);
123 module_param(hwwep,int, S_IRUGO|S_IWUSR);
124 module_param(channels,int, S_IRUGO|S_IWUSR);
126 MODULE_PARM_DESC(ifname," Net interface name, wlan%d=default");
127 MODULE_PARM_DESC(hwwep," Try to use hardware WEP support. Still broken and not available on all cards");
128 MODULE_PARM_DESC(channels," Channel bitmask for specific locales. NYI");
130 static int __devinit rtl8192_pci_probe(struct pci_dev *pdev,
131 const struct pci_device_id *id);
132 static void __devexit rtl8192_pci_disconnect(struct pci_dev *pdev);
134 static struct pci_driver rtl8192_pci_driver = {
135 .name = RTL819xE_MODULE_NAME, /* Driver name */
136 .id_table = rtl8192_pci_id_tbl, /* PCI_ID table */
137 .probe = rtl8192_pci_probe, /* probe fn */
138 .remove = __devexit_p(rtl8192_pci_disconnect), /* remove fn */
140 .suspend = rtl8192E_suspend, /* PM suspend fn */
141 .resume = rtl8192E_resume, /* PM resume fn */
143 .suspend = NULL, /* PM suspend fn */
144 .resume = NULL, /* PM resume fn */
148 static void rtl8192_start_beacon(struct net_device *dev);
149 static void rtl8192_stop_beacon(struct net_device *dev);
150 static void rtl819x_watchdog_wqcallback(struct work_struct *work);
151 static void rtl8192_irq_rx_tasklet(struct r8192_priv *priv);
152 static void rtl8192_irq_tx_tasklet(struct r8192_priv *priv);
153 static void rtl8192_prepare_beacon(struct r8192_priv *priv);
154 static irqreturn_t rtl8192_interrupt(int irq, void *netdev);
155 static void rtl8192_try_wake_queue(struct net_device *dev, int pri);
156 static void rtl819xE_tx_cmd(struct net_device *dev, struct sk_buff *skb);
157 static void rtl8192_update_ratr_table(struct net_device* dev);
158 static void rtl8192_restart(struct work_struct *work);
159 static void watch_dog_timer_callback(unsigned long data);
160 static int _rtl8192_up(struct net_device *dev);
161 static void rtl8192_cancel_deferred_work(struct r8192_priv* priv);
165 typedef struct _CHANNEL_LIST
169 }CHANNEL_LIST, *PCHANNEL_LIST;
171 static const CHANNEL_LIST ChannelPlan[] = {
172 {{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
173 {{1,2,3,4,5,6,7,8,9,10,11},11}, //IC
174 {{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48,52,56,60,64},21}, //ETSI
175 {{1,2,3,4,5,6,7,8,9,10,11,12,13},13}, //Spain. Change to ETSI.
176 {{1,2,3,4,5,6,7,8,9,10,11,12,13},13}, //France. Change to ETSI.
177 {{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
178 {{1,2,3,4,5,6,7,8,9,10,11,12,13,14,36,40,44,48,52,56,60,64},22},//MKK1
179 {{1,2,3,4,5,6,7,8,9,10,11,12,13},13}, //Israel.
180 {{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
181 {{1,2,3,4,5,6,7,8,9,10,11,12,13,14,36,40,44,48,52,56,60,64}, 22}, //MIC
182 {{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
185 static void rtl819x_set_channel_map(u8 channel_plan, struct r8192_priv* priv)
187 int i, max_chan=-1, min_chan=-1;
188 struct ieee80211_device* ieee = priv->ieee80211;
189 switch (channel_plan)
191 case COUNTRY_CODE_FCC:
192 case COUNTRY_CODE_IC:
193 case COUNTRY_CODE_ETSI:
194 case COUNTRY_CODE_SPAIN:
195 case COUNTRY_CODE_FRANCE:
196 case COUNTRY_CODE_MKK:
197 case COUNTRY_CODE_MKK1:
198 case COUNTRY_CODE_ISRAEL:
199 case COUNTRY_CODE_TELEC:
200 case COUNTRY_CODE_MIC:
203 ieee->bGlobalDomain = false;
204 //acturally 8225 & 8256 rf chip only support B,G,24N mode
205 if ((priv->rf_chip == RF_8225) || (priv->rf_chip == RF_8256))
212 RT_TRACE(COMP_ERR, "unknown rf chip, can't set channel map in function:%s()\n", __FUNCTION__);
214 if (ChannelPlan[channel_plan].Len != 0){
215 // Clear old channel map
216 memset(GET_DOT11D_INFO(ieee)->channel_map, 0, sizeof(GET_DOT11D_INFO(ieee)->channel_map));
217 // Set new channel map
218 for (i=0;i<ChannelPlan[channel_plan].Len;i++)
220 if (ChannelPlan[channel_plan].Channel[i] < min_chan || ChannelPlan[channel_plan].Channel[i] > max_chan)
222 GET_DOT11D_INFO(ieee)->channel_map[ChannelPlan[channel_plan].Channel[i]] = 1;
227 case COUNTRY_CODE_GLOBAL_DOMAIN:
229 GET_DOT11D_INFO(ieee)->bEnabled = 0; //this flag enabled to follow 11d country IE setting, otherwise, it shall follow global domain setting
231 ieee->bGlobalDomain = true;
241 #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 )
242 /* 2007/07/25 MH Defien temp tx fw info. */
243 static TX_FWINFO_T Tmp_TxFwInfo;
246 #define rx_hal_is_cck_rate(_pdrvinfo)\
247 (_pdrvinfo->RxRate == DESC90_RATE1M ||\
248 _pdrvinfo->RxRate == DESC90_RATE2M ||\
249 _pdrvinfo->RxRate == DESC90_RATE5_5M ||\
250 _pdrvinfo->RxRate == DESC90_RATE11M) &&\
254 void CamResetAllEntry(struct net_device *dev)
256 write_nic_dword(dev, RWCAM, BIT31|BIT30);
260 void write_cam(struct net_device *dev, u8 addr, u32 data)
262 write_nic_dword(dev, WCAMI, data);
263 write_nic_dword(dev, RWCAM, BIT31|BIT16|(addr&0xff) );
265 u32 read_cam(struct net_device *dev, u8 addr)
267 write_nic_dword(dev, RWCAM, 0x80000000|(addr&0xff) );
268 return read_nic_dword(dev, 0xa8);
271 #ifdef CONFIG_RTL8180_IO_MAP
273 u8 read_nic_byte(struct net_device *dev, int x)
275 return 0xff&inb(dev->base_addr +x);
278 u32 read_nic_dword(struct net_device *dev, int x)
280 return inl(dev->base_addr +x);
283 u16 read_nic_word(struct net_device *dev, int x)
285 return inw(dev->base_addr +x);
288 void write_nic_byte(struct net_device *dev, int x,u8 y)
290 outb(y&0xff,dev->base_addr +x);
293 void write_nic_word(struct net_device *dev, int x,u16 y)
295 outw(y,dev->base_addr +x);
298 void write_nic_dword(struct net_device *dev, int x,u32 y)
300 outl(y,dev->base_addr +x);
303 #else /* RTL_IO_MAP */
305 u8 read_nic_byte(struct net_device *dev, int x)
307 return 0xff&readb((u8*)dev->mem_start +x);
310 u32 read_nic_dword(struct net_device *dev, int x)
312 return readl((u8*)dev->mem_start +x);
315 u16 read_nic_word(struct net_device *dev, int x)
317 return readw((u8*)dev->mem_start +x);
320 void write_nic_byte(struct net_device *dev, int x,u8 y)
322 writeb(y,(u8*)dev->mem_start +x);
326 void write_nic_dword(struct net_device *dev, int x,u32 y)
328 writel(y,(u8*)dev->mem_start +x);
332 void write_nic_word(struct net_device *dev, int x,u16 y)
334 writew(y,(u8*)dev->mem_start +x);
338 #endif /* RTL_IO_MAP */
340 u8 rtl8192e_ap_sec_type(struct ieee80211_device *ieee)
342 static const u8 ccmp_ie[4] = {0x00,0x50,0xf2,0x04};
343 static const u8 ccmp_rsn_ie[4] = {0x00, 0x0f, 0xac, 0x04};
344 int wpa_ie_len= ieee->wpa_ie_len;
345 struct ieee80211_crypt_data* crypt;
348 crypt = ieee->crypt[ieee->tx_keyidx];
350 encrypt = (ieee->current_network.capability & WLAN_CAPABILITY_PRIVACY) ||
351 (ieee->host_encrypt && crypt && crypt->ops &&
352 (0 == strcmp(crypt->ops->name,"WEP")));
355 if(encrypt && (wpa_ie_len == 0)) {
356 // wep encryption, no N mode setting */
358 } else if((wpa_ie_len != 0)) {
359 // parse pairwise key type */
360 if (((ieee->wpa_ie[0] == 0xdd) && (!memcmp(&(ieee->wpa_ie[14]),ccmp_ie,4))) ||
361 ((ieee->wpa_ie[0] == 0x30) && (!memcmp(&ieee->wpa_ie[10],ccmp_rsn_ie, 4))))
371 rtl8192e_SetHwReg(struct net_device *dev,u8 variable,u8* val)
373 struct r8192_priv* priv = ieee80211_priv(dev);
379 write_nic_dword(dev, BSSIDR, ((u32*)(val))[0]);
380 write_nic_word(dev, BSSIDR+2, ((u16*)(val+2))[0]);
383 case HW_VAR_MEDIA_STATUS:
385 RT_OP_MODE OpMode = *((RT_OP_MODE *)(val));
386 u8 btMsr = read_nic_byte(dev, MSR);
392 case RT_OP_MODE_INFRASTRUCTURE:
396 case RT_OP_MODE_IBSS:
409 write_nic_byte(dev, MSR, btMsr);
413 case HW_VAR_CECHK_BSSID:
417 Type = ((u8*)(val))[0];
418 RegRCR = read_nic_dword(dev,RCR);
419 priv->ReceiveConfig = RegRCR;
422 RegRCR |= (RCR_CBSSID);
423 else if (Type == false)
424 RegRCR &= (~RCR_CBSSID);
426 write_nic_dword(dev, RCR,RegRCR);
427 priv->ReceiveConfig = RegRCR;
432 case HW_VAR_SLOT_TIME:
434 priv->slot_time = val[0];
435 write_nic_byte(dev, SLOT_TIME, val[0]);
440 case HW_VAR_ACK_PREAMBLE:
443 priv->short_preamble = (bool)(*(u8*)val );
444 regTmp = priv->basic_rate;
445 if (priv->short_preamble)
446 regTmp |= BRSR_AckShortPmb;
447 write_nic_dword(dev, RRSR, regTmp);
452 write_nic_dword(dev, CPU_GEN, ((u32*)(val))[0]);
461 static struct proc_dir_entry *rtl8192_proc = NULL;
463 static int proc_get_stats_ap(char *page, char **start,
464 off_t offset, int count,
465 int *eof, void *data)
467 struct net_device *dev = data;
468 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
469 struct ieee80211_device *ieee = priv->ieee80211;
470 struct ieee80211_network *target;
473 list_for_each_entry(target, &ieee->network_list, list) {
475 len += snprintf(page + len, count - len,
476 "%s ", target->ssid);
478 if(target->wpa_ie_len>0 || target->rsn_ie_len>0){
479 len += snprintf(page + len, count - len,
483 len += snprintf(page + len, count - len,
493 static int proc_get_registers(char *page, char **start,
494 off_t offset, int count,
495 int *eof, void *data)
497 struct net_device *dev = data;
502 /* This dump the current register page */
503 len += snprintf(page + len, count - len,
504 "\n####################page 0##################\n ");
508 len += snprintf(page + len, count - len,
511 for(i=0;i<16 && n<=max;i++,n++)
512 len += snprintf(page + len, count - len,
513 "%2x ",read_nic_byte(dev,n));
515 len += snprintf(page + len, count - len,"\n");
516 len += snprintf(page + len, count - len,
517 "\n####################page 1##################\n ");
520 len += snprintf(page + len, count - len,
523 for(i=0;i<16 && n<=max;i++,n++)
524 len += snprintf(page + len, count - len,
525 "%2x ",read_nic_byte(dev,0x100|n));
528 len += snprintf(page + len, count - len,
529 "\n####################page 3##################\n ");
532 len += snprintf(page + len, count - len,
535 for(i=0;i<16 && n<=max;i++,n++)
536 len += snprintf(page + len, count - len,
537 "%2x ",read_nic_byte(dev,0x300|n));
545 static int proc_get_stats_tx(char *page, char **start,
546 off_t offset, int count,
547 int *eof, void *data)
549 struct net_device *dev = data;
550 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
554 len += snprintf(page + len, count - len,
555 "TX VI priority ok int: %lu\n"
556 // "TX VI priority error int: %lu\n"
557 "TX VO priority ok int: %lu\n"
558 // "TX VO priority error int: %lu\n"
559 "TX BE priority ok int: %lu\n"
560 // "TX BE priority error int: %lu\n"
561 "TX BK priority ok int: %lu\n"
562 // "TX BK priority error int: %lu\n"
563 "TX MANAGE priority ok int: %lu\n"
564 // "TX MANAGE priority error int: %lu\n"
565 "TX BEACON priority ok int: %lu\n"
566 "TX BEACON priority error int: %lu\n"
567 "TX CMDPKT priority ok int: %lu\n"
568 // "TX high priority ok int: %lu\n"
569 // "TX high priority failed error int: %lu\n"
570 // "TX queue resume: %lu\n"
571 "TX queue stopped?: %d\n"
572 "TX fifo overflow: %lu\n"
573 // "TX beacon: %lu\n"
574 // "TX VI queue: %d\n"
575 // "TX VO queue: %d\n"
576 // "TX BE queue: %d\n"
577 // "TX BK queue: %d\n"
578 // "TX HW queue: %d\n"
579 // "TX VI dropped: %lu\n"
580 // "TX VO dropped: %lu\n"
581 // "TX BE dropped: %lu\n"
582 // "TX BK dropped: %lu\n"
583 "TX total data packets %lu\n"
584 "TX total data bytes :%lu\n",
585 // "TX beacon aborted: %lu\n",
586 priv->stats.txviokint,
587 // priv->stats.txvierr,
588 priv->stats.txvookint,
589 // priv->stats.txvoerr,
590 priv->stats.txbeokint,
591 // priv->stats.txbeerr,
592 priv->stats.txbkokint,
593 // priv->stats.txbkerr,
594 priv->stats.txmanageokint,
595 // priv->stats.txmanageerr,
596 priv->stats.txbeaconokint,
597 priv->stats.txbeaconerr,
598 priv->stats.txcmdpktokint,
599 // priv->stats.txhpokint,
600 // priv->stats.txhperr,
601 // priv->stats.txresumed,
602 netif_queue_stopped(dev),
603 priv->stats.txoverflow,
604 // priv->stats.txbeacon,
605 // atomic_read(&(priv->tx_pending[VI_QUEUE])),
606 // atomic_read(&(priv->tx_pending[VO_QUEUE])),
607 // atomic_read(&(priv->tx_pending[BE_QUEUE])),
608 // atomic_read(&(priv->tx_pending[BK_QUEUE])),
609 // read_nic_byte(dev, TXFIFOCOUNT),
610 // priv->stats.txvidrop,
611 // priv->stats.txvodrop,
612 priv->ieee80211->stats.tx_packets,
613 priv->ieee80211->stats.tx_bytes
616 // priv->stats.txbedrop,
617 // priv->stats.txbkdrop
618 // priv->stats.txdatapkt
619 // priv->stats.txbeaconerr
628 static int proc_get_stats_rx(char *page, char **start,
629 off_t offset, int count,
630 int *eof, void *data)
632 struct net_device *dev = data;
633 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
637 len += snprintf(page + len, count - len,
640 "RX rx overflow error: %lu\n"
641 "RX invalid urb error: %lu\n",
644 priv->stats.rxoverflow,
645 priv->stats.rxurberr);
651 static void rtl8192_proc_module_init(void)
653 RT_TRACE(COMP_INIT, "Initializing proc filesystem");
654 rtl8192_proc=create_proc_entry(RTL819xE_MODULE_NAME, S_IFDIR, init_net.proc_net);
658 static void rtl8192_proc_module_remove(void)
660 remove_proc_entry(RTL819xE_MODULE_NAME, init_net.proc_net);
664 static void rtl8192_proc_remove_one(struct net_device *dev)
666 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
668 printk("dev name=======> %s\n",dev->name);
671 // remove_proc_entry("stats-hw", priv->dir_dev);
672 remove_proc_entry("stats-tx", priv->dir_dev);
673 remove_proc_entry("stats-rx", priv->dir_dev);
674 // remove_proc_entry("stats-ieee", priv->dir_dev);
675 remove_proc_entry("stats-ap", priv->dir_dev);
676 remove_proc_entry("registers", priv->dir_dev);
677 // remove_proc_entry("cck-registers",priv->dir_dev);
678 // remove_proc_entry("ofdm-registers",priv->dir_dev);
679 //remove_proc_entry(dev->name, rtl8192_proc);
680 remove_proc_entry("wlan0", rtl8192_proc);
681 priv->dir_dev = NULL;
686 static void rtl8192_proc_init_one(struct net_device *dev)
688 struct proc_dir_entry *e;
689 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
690 priv->dir_dev = create_proc_entry(dev->name,
691 S_IFDIR | S_IRUGO | S_IXUGO,
693 if (!priv->dir_dev) {
694 RT_TRACE(COMP_ERR, "Unable to initialize /proc/net/rtl8192/%s\n",
698 e = create_proc_read_entry("stats-rx", S_IFREG | S_IRUGO,
699 priv->dir_dev, proc_get_stats_rx, dev);
702 RT_TRACE(COMP_ERR,"Unable to initialize "
703 "/proc/net/rtl8192/%s/stats-rx\n",
708 e = create_proc_read_entry("stats-tx", S_IFREG | S_IRUGO,
709 priv->dir_dev, proc_get_stats_tx, dev);
712 RT_TRACE(COMP_ERR, "Unable to initialize "
713 "/proc/net/rtl8192/%s/stats-tx\n",
717 e = create_proc_read_entry("stats-ap", S_IFREG | S_IRUGO,
718 priv->dir_dev, proc_get_stats_ap, dev);
721 RT_TRACE(COMP_ERR, "Unable to initialize "
722 "/proc/net/rtl8192/%s/stats-ap\n",
726 e = create_proc_read_entry("registers", S_IFREG | S_IRUGO,
727 priv->dir_dev, proc_get_registers, dev);
729 RT_TRACE(COMP_ERR, "Unable to initialize "
730 "/proc/net/rtl8192/%s/registers\n",
735 short check_nic_enough_desc(struct net_device *dev, int prio)
737 struct r8192_priv *priv = ieee80211_priv(dev);
738 struct rtl8192_tx_ring *ring = &priv->tx_ring[prio];
740 /* for now we reserve two free descriptor as a safety boundary
741 * between the tail and the head
743 return (ring->entries - skb_queue_len(&ring->queue) >= 2);
746 static void tx_timeout(struct net_device *dev)
748 struct r8192_priv *priv = ieee80211_priv(dev);
750 schedule_work(&priv->reset_wq);
754 static void rtl8192_irq_enable(struct net_device *dev)
756 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
757 priv->irq_enabled = 1;
758 write_nic_dword(dev,INTA_MASK, priv->irq_mask);
761 void rtl8192_irq_disable(struct net_device *dev)
763 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
765 write_nic_dword(dev,INTA_MASK,0);
766 priv->irq_enabled = 0;
769 void rtl8192_update_msr(struct net_device *dev)
771 struct r8192_priv *priv = ieee80211_priv(dev);
774 msr = read_nic_byte(dev, MSR);
775 msr &= ~ MSR_LINK_MASK;
777 /* do not change in link_state != WLAN_LINK_ASSOCIATED.
778 * msr must be updated if the state is ASSOCIATING.
779 * this is intentional and make sense for ad-hoc and
780 * master (see the create BSS/IBSS func)
782 if (priv->ieee80211->state == IEEE80211_LINKED){
784 if (priv->ieee80211->iw_mode == IW_MODE_INFRA)
785 msr |= (MSR_LINK_MANAGED<<MSR_LINK_SHIFT);
786 else if (priv->ieee80211->iw_mode == IW_MODE_ADHOC)
787 msr |= (MSR_LINK_ADHOC<<MSR_LINK_SHIFT);
788 else if (priv->ieee80211->iw_mode == IW_MODE_MASTER)
789 msr |= (MSR_LINK_MASTER<<MSR_LINK_SHIFT);
792 msr |= (MSR_LINK_NONE<<MSR_LINK_SHIFT);
794 write_nic_byte(dev, MSR, msr);
797 void rtl8192_set_chan(struct net_device *dev,short ch)
799 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
803 /* need to implement rf set channel here WB */
805 if (priv->rf_set_chan)
806 priv->rf_set_chan(dev, priv->chan);
809 void rtl8192_rx_enable(struct net_device *dev)
811 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
813 write_nic_dword(dev, RDQDA,priv->rx_ring_dma);
816 /* the TX_DESC_BASE setting is according to the following queue index
825 * BEACON_QUEUE ===> 8
827 static const u32 TX_DESC_BASE[] = {BKQDA, BEQDA, VIQDA, VOQDA, HCCAQDA, CQDA, MQDA, HQDA, BQDA};
828 void rtl8192_tx_enable(struct net_device *dev)
830 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
833 for (i = 0; i < MAX_TX_QUEUE_COUNT; i++)
834 write_nic_dword(dev, TX_DESC_BASE[i], priv->tx_ring[i].dma);
836 ieee80211_reset_queue(priv->ieee80211);
840 static void rtl8192_free_rx_ring(struct net_device *dev)
842 struct r8192_priv *priv = ieee80211_priv(dev);
845 for (i = 0; i < priv->rxringcount; i++) {
846 struct sk_buff *skb = priv->rx_buf[i];
850 pci_unmap_single(priv->pdev,
851 *((dma_addr_t *)skb->cb),
852 priv->rxbuffersize, PCI_DMA_FROMDEVICE);
856 pci_free_consistent(priv->pdev, sizeof(*priv->rx_ring) * priv->rxringcount,
857 priv->rx_ring, priv->rx_ring_dma);
858 priv->rx_ring = NULL;
861 static void rtl8192_free_tx_ring(struct net_device *dev, unsigned int prio)
863 struct r8192_priv *priv = ieee80211_priv(dev);
864 struct rtl8192_tx_ring *ring = &priv->tx_ring[prio];
866 while (skb_queue_len(&ring->queue)) {
867 tx_desc_819x_pci *entry = &ring->desc[ring->idx];
868 struct sk_buff *skb = __skb_dequeue(&ring->queue);
870 pci_unmap_single(priv->pdev, le32_to_cpu(entry->TxBuffAddr),
871 skb->len, PCI_DMA_TODEVICE);
873 ring->idx = (ring->idx + 1) % ring->entries;
876 pci_free_consistent(priv->pdev, sizeof(*ring->desc)*ring->entries,
877 ring->desc, ring->dma);
881 void PHY_SetRtl8192eRfOff(struct net_device* dev)
883 //disable RF-Chip A/B
884 rtl8192_setBBreg(dev, rFPGA0_XA_RFInterfaceOE, BIT4, 0x0);
885 //analog to digital off, for power save
886 rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0x300, 0x0);
887 //digital to analog off, for power save
888 rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x18, 0x0);
890 rtl8192_setBBreg(dev, rOFDM0_TRxPathEnable, 0xf, 0x0);
892 rtl8192_setBBreg(dev, rOFDM1_TRxPathEnable, 0xf, 0x0);
893 //analog to digital part2 off, for power save
894 rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x60, 0x0);
895 rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x4, 0x0);
896 // Analog parameter!!Change bias and Lbus control.
897 write_nic_byte(dev, ANAPAR_FOR_8192PciE, 0x07);
901 void rtl8192_halt_adapter(struct net_device *dev, bool reset)
903 struct r8192_priv *priv = ieee80211_priv(dev);
909 OpMode = RT_OP_MODE_NO_LINK;
910 priv->ieee80211->SetHwRegHandler(dev, HW_VAR_MEDIA_STATUS, &OpMode);
912 if(!priv->ieee80211->bSupportRemoteWakeUp)
914 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
915 //priv->ieee80211->SetHwRegHandler(dev, HW_VAR_COMMAND, &u1bTmp ); // Using HW_VAR_COMMAND instead of writing CMDR directly. Rewrited by Annie, 2006-04-07.
916 write_nic_byte(dev, CMDR, u1bTmp);
923 //PlatformStallExecution(150000);
927 priv->bHwRfOffAction = 2;
931 // Call MgntActSet_RF_State instead to prevent RF config race condition.
932 // By Bruce, 2008-01-17.
934 if(!priv->ieee80211->bSupportRemoteWakeUp)
936 //MgntActSet_RF_State(Adapter, eRfOff, RF_CHANGE_BY_INIT);
937 //MgntActSet_RF_State(Adapter, eRfOff, Adapter->MgntInfo.RfOffReason);
938 //if(Adapter->HardwareType == HARDWARE_TYPE_RTL8190P)
940 PHY_SetRtl8192eRfOff(dev);
942 // 2006.11.30. System reset bit
943 //priv->ieee80211->GetHwRegHandler(dev, HW_VAR_CPU_RST, (u32*)(&ulRegRead) );
944 ulRegRead = read_nic_dword(dev,CPU_GEN);
945 ulRegRead|=CPU_GEN_SYSTEM_RESET;
946 //priv->ieee80211->SetHwRegHandler(dev, HW_VAR_CPU_RST, &ulRegRead);
947 write_nic_dword(dev,CPU_GEN, ulRegRead);
952 write_nic_dword(dev, WFCRC0, 0xffffffff);
953 write_nic_dword(dev, WFCRC1, 0xffffffff);
954 write_nic_dword(dev, WFCRC2, 0xffffffff);
957 write_nic_byte(dev, PMR, 0x5);
958 //Disable tx, enanble rx
959 write_nic_byte(dev, MacBlkCtrl, 0xa);
963 for(i = 0; i < MAX_QUEUE_SIZE; i++) {
964 skb_queue_purge(&priv->ieee80211->skb_waitQ [i]);
966 for(i = 0; i < MAX_QUEUE_SIZE; i++) {
967 skb_queue_purge(&priv->ieee80211->skb_aggQ [i]);
970 skb_queue_purge(&priv->skb_queue);
973 static const u16 rtl_rate[] = {10,20,55,110,60,90,120,180,240,360,480,540};
974 inline u16 rtl8192_rate2rate(short rate)
976 if (rate >11) return 0;
977 return rtl_rate[rate];
980 static void rtl8192_data_hard_stop(struct net_device *dev)
984 static void rtl8192_data_hard_resume(struct net_device *dev)
989 * this function TX data frames when the ieee80211 stack requires this.
990 * It checks also if we need to stop the ieee tx queue, eventually do it
992 static void rtl8192_hard_data_xmit(struct sk_buff *skb, struct net_device *dev, int rate)
994 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
996 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
997 u8 queue_index = tcb_desc->queue_index;
999 /* shall not be referred by command packet */
1000 assert(queue_index != TXCMD_QUEUE);
1002 if (priv->bHwRadioOff || (!priv->up))
1008 memcpy(skb->cb, &dev, sizeof(dev));
1010 skb_push(skb, priv->ieee80211->tx_headroom);
1011 ret = rtl8192_tx(dev, skb);
1016 if (queue_index != MGNT_QUEUE) {
1017 priv->ieee80211->stats.tx_bytes += (skb->len - priv->ieee80211->tx_headroom);
1018 priv->ieee80211->stats.tx_packets++;
1023 * This is a rough attempt to TX a frame
1024 * This is called by the ieee 80211 stack to TX management frames.
1025 * If the ring is full packet are dropped (for data frame the queue
1026 * is stopped before this can happen).
1028 static int rtl8192_hard_start_xmit(struct sk_buff *skb,struct net_device *dev)
1030 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1034 //unsigned long flags;
1035 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1036 u8 queue_index = tcb_desc->queue_index;
1038 if(queue_index != TXCMD_QUEUE){
1039 if (priv->bHwRadioOff ||(!priv->up))
1046 //spin_lock_irqsave(&priv->tx_lock,flags);
1048 memcpy((unsigned char *)(skb->cb),&dev,sizeof(dev));
1049 if(queue_index == TXCMD_QUEUE) {
1050 // skb_push(skb, USB_HWDESC_HEADER_LEN);
1051 rtl819xE_tx_cmd(dev, skb);
1053 //spin_unlock_irqrestore(&priv->tx_lock,flags);
1056 // RT_TRACE(COMP_SEND, "To send management packet\n");
1057 tcb_desc->RATRIndex = 7;
1058 tcb_desc->bTxDisableRateFallBack = 1;
1059 tcb_desc->bTxUseDriverAssingedRate = 1;
1060 tcb_desc->bTxEnableFwCalcDur = 1;
1061 skb_push(skb, priv->ieee80211->tx_headroom);
1062 ret = rtl8192_tx(dev, skb);
1068 // priv->ieee80211->stats.tx_bytes+=skb->len;
1069 // priv->ieee80211->stats.tx_packets++;
1071 //spin_unlock_irqrestore(&priv->tx_lock,flags);
1078 static void rtl8192_tx_isr(struct net_device *dev, int prio)
1080 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1082 struct rtl8192_tx_ring *ring = &priv->tx_ring[prio];
1084 while (skb_queue_len(&ring->queue)) {
1085 tx_desc_819x_pci *entry = &ring->desc[ring->idx];
1086 struct sk_buff *skb;
1088 /* beacon packet will only use the first descriptor defaultly,
1089 * and the OWN may not be cleared by the hardware
1091 if(prio != BEACON_QUEUE) {
1094 ring->idx = (ring->idx + 1) % ring->entries;
1097 skb = __skb_dequeue(&ring->queue);
1098 pci_unmap_single(priv->pdev, le32_to_cpu(entry->TxBuffAddr),
1099 skb->len, PCI_DMA_TODEVICE);
1103 if (prio == MGNT_QUEUE){
1104 if (priv->ieee80211->ack_tx_to_ieee){
1105 if (rtl8192_is_tx_queue_empty(dev)){
1106 priv->ieee80211->ack_tx_to_ieee = 0;
1107 ieee80211_ps_tx_ack(priv->ieee80211, 1);
1112 if(prio != BEACON_QUEUE) {
1113 /* try to deal with the pending packets */
1114 tasklet_schedule(&priv->irq_tx_tasklet);
1119 static void rtl8192_stop_beacon(struct net_device *dev)
1123 static void rtl8192_config_rate(struct net_device* dev, u16* rate_config)
1125 struct r8192_priv *priv = ieee80211_priv(dev);
1126 struct ieee80211_network *net;
1127 u8 i=0, basic_rate = 0;
1128 net = & priv->ieee80211->current_network;
1130 for (i=0; i<net->rates_len; i++)
1132 basic_rate = net->rates[i]&0x7f;
1135 case MGN_1M: *rate_config |= RRSR_1M; break;
1136 case MGN_2M: *rate_config |= RRSR_2M; break;
1137 case MGN_5_5M: *rate_config |= RRSR_5_5M; break;
1138 case MGN_11M: *rate_config |= RRSR_11M; break;
1139 case MGN_6M: *rate_config |= RRSR_6M; break;
1140 case MGN_9M: *rate_config |= RRSR_9M; break;
1141 case MGN_12M: *rate_config |= RRSR_12M; break;
1142 case MGN_18M: *rate_config |= RRSR_18M; break;
1143 case MGN_24M: *rate_config |= RRSR_24M; break;
1144 case MGN_36M: *rate_config |= RRSR_36M; break;
1145 case MGN_48M: *rate_config |= RRSR_48M; break;
1146 case MGN_54M: *rate_config |= RRSR_54M; break;
1149 for (i=0; i<net->rates_ex_len; i++)
1151 basic_rate = net->rates_ex[i]&0x7f;
1154 case MGN_1M: *rate_config |= RRSR_1M; break;
1155 case MGN_2M: *rate_config |= RRSR_2M; break;
1156 case MGN_5_5M: *rate_config |= RRSR_5_5M; break;
1157 case MGN_11M: *rate_config |= RRSR_11M; break;
1158 case MGN_6M: *rate_config |= RRSR_6M; break;
1159 case MGN_9M: *rate_config |= RRSR_9M; break;
1160 case MGN_12M: *rate_config |= RRSR_12M; break;
1161 case MGN_18M: *rate_config |= RRSR_18M; break;
1162 case MGN_24M: *rate_config |= RRSR_24M; break;
1163 case MGN_36M: *rate_config |= RRSR_36M; break;
1164 case MGN_48M: *rate_config |= RRSR_48M; break;
1165 case MGN_54M: *rate_config |= RRSR_54M; break;
1171 #define SHORT_SLOT_TIME 9
1172 #define NON_SHORT_SLOT_TIME 20
1174 static void rtl8192_update_cap(struct net_device* dev, u16 cap)
1177 struct r8192_priv *priv = ieee80211_priv(dev);
1178 struct ieee80211_network *net = &priv->ieee80211->current_network;
1179 priv->short_preamble = cap & WLAN_CAPABILITY_SHORT_PREAMBLE;
1180 tmp = priv->basic_rate;
1181 if (priv->short_preamble)
1182 tmp |= BRSR_AckShortPmb;
1183 write_nic_dword(dev, RRSR, tmp);
1185 if (net->mode & (IEEE_G|IEEE_N_24G))
1188 if ((cap & WLAN_CAPABILITY_SHORT_SLOT)&&(!priv->ieee80211->pHTInfo->bCurrentRT2RTLongSlotTime))
1190 slot_time = SHORT_SLOT_TIME;
1192 else //long slot time
1193 slot_time = NON_SHORT_SLOT_TIME;
1194 priv->slot_time = slot_time;
1195 write_nic_byte(dev, SLOT_TIME, slot_time);
1200 static void rtl8192_net_update(struct net_device *dev)
1203 struct r8192_priv *priv = ieee80211_priv(dev);
1204 struct ieee80211_network *net;
1205 u16 BcnTimeCfg = 0, BcnCW = 6, BcnIFS = 0xf;
1206 u16 rate_config = 0;
1207 net = &priv->ieee80211->current_network;
1208 //update Basic rate: RR, BRSR
1209 rtl8192_config_rate(dev, &rate_config);
1210 // 2007.01.16, by Emily
1211 // Select RRSR (in Legacy-OFDM and CCK)
1212 // For 8190, we select only 24M, 12M, 6M, 11M, 5.5M, 2M, and 1M from the Basic rate.
1213 // We do not use other rates.
1214 priv->basic_rate = rate_config &= 0x15f;
1216 write_nic_dword(dev,BSSIDR,((u32*)net->bssid)[0]);
1217 write_nic_word(dev,BSSIDR+4,((u16*)net->bssid)[2]);
1220 rtl8192_update_msr(dev);
1224 // rtl8192_update_cap(dev, net->capability);
1225 if (priv->ieee80211->iw_mode == IW_MODE_ADHOC)
1227 write_nic_word(dev, ATIMWND, 2);
1228 write_nic_word(dev, BCN_DMATIME, 256);
1229 write_nic_word(dev, BCN_INTERVAL, net->beacon_interval);
1230 // write_nic_word(dev, BcnIntTime, 100);
1231 //BIT15 of BCN_DRV_EARLY_INT will indicate whether software beacon or hw beacon is applied.
1232 write_nic_word(dev, BCN_DRV_EARLY_INT, 10);
1233 write_nic_byte(dev, BCN_ERR_THRESH, 100);
1235 BcnTimeCfg |= (BcnCW<<BCN_TCFG_CW_SHIFT);
1236 // TODO: BcnIFS may required to be changed on ASIC
1237 BcnTimeCfg |= BcnIFS<<BCN_TCFG_IFS;
1239 write_nic_word(dev, BCN_TCFG, BcnTimeCfg);
1245 void rtl819xE_tx_cmd(struct net_device *dev, struct sk_buff *skb)
1247 struct r8192_priv *priv = ieee80211_priv(dev);
1248 struct rtl8192_tx_ring *ring;
1249 tx_desc_819x_pci *entry;
1253 unsigned long flags;
1255 ring = &priv->tx_ring[TXCMD_QUEUE];
1256 mapping = pci_map_single(priv->pdev, skb->data, skb->len, PCI_DMA_TODEVICE);
1258 spin_lock_irqsave(&priv->irq_th_lock,flags);
1259 idx = (ring->idx + skb_queue_len(&ring->queue)) % ring->entries;
1260 entry = &ring->desc[idx];
1262 tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1264 entry->LINIP = tcb_desc->bLastIniPkt;
1265 entry->FirstSeg = 1;//first segment
1266 entry->LastSeg = 1; //last segment
1267 if(tcb_desc->bCmdOrInit == DESC_PACKET_TYPE_INIT) {
1268 entry->CmdInit = DESC_PACKET_TYPE_INIT;
1270 entry->CmdInit = DESC_PACKET_TYPE_NORMAL;
1271 entry->Offset = sizeof(TX_FWINFO_8190PCI) + 8;
1272 entry->PktSize = (u16)(tcb_desc->pkt_size + entry->Offset);
1273 entry->QueueSelect = QSLT_CMD;
1274 entry->TxFWInfoSize = 0x08;
1275 entry->RATid = (u8)DESC_PACKET_TYPE_INIT;
1277 entry->TxBufferSize = skb->len;
1278 entry->TxBuffAddr = cpu_to_le32(mapping);
1281 #ifdef JOHN_DUMP_TXDESC
1283 tx_desc_819x_pci *entry1 = &ring->desc[0];
1284 unsigned int *ptr= (unsigned int *)entry1;
1285 printk("<Tx descriptor>:\n");
1286 for (i = 0; i < 8; i++)
1287 printk("%8x ", ptr[i]);
1291 __skb_queue_tail(&ring->queue, skb);
1292 spin_unlock_irqrestore(&priv->irq_th_lock,flags);
1294 write_nic_byte(dev, TPPoll, TPPoll_CQ);
1300 * Mapping Software/Hardware descriptor queue id to "Queue Select Field"
1301 * in TxFwInfo data structure
1303 static u8 MapHwQueueToFirmwareQueue(u8 QueueID)
1305 u8 QueueSelect = 0x0; //defualt set to
1309 QueueSelect = QSLT_BE; //or QSelect = pTcb->priority;
1313 QueueSelect = QSLT_BK; //or QSelect = pTcb->priority;
1317 QueueSelect = QSLT_VO; //or QSelect = pTcb->priority;
1321 QueueSelect = QSLT_VI; //or QSelect = pTcb->priority;
1324 QueueSelect = QSLT_MGNT;
1328 QueueSelect = QSLT_BEACON;
1331 // TODO: 2006.10.30 mark other queue selection until we verify it is OK
1332 // TODO: Remove Assertions
1333 //#if (RTL819X_FPGA_VER & RTL819X_FPGA_GUANGAN_070502)
1335 QueueSelect = QSLT_CMD;
1339 //QueueSelect = QSLT_HIGH;
1343 RT_TRACE(COMP_ERR, "TransmitTCB(): Impossible Queue Selection: %d \n", QueueID);
1349 static u8 MRateToHwRate8190Pci(u8 rate)
1351 u8 ret = DESC90_RATE1M;
1354 case MGN_1M: ret = DESC90_RATE1M; break;
1355 case MGN_2M: ret = DESC90_RATE2M; break;
1356 case MGN_5_5M: ret = DESC90_RATE5_5M; break;
1357 case MGN_11M: ret = DESC90_RATE11M; break;
1358 case MGN_6M: ret = DESC90_RATE6M; break;
1359 case MGN_9M: ret = DESC90_RATE9M; break;
1360 case MGN_12M: ret = DESC90_RATE12M; break;
1361 case MGN_18M: ret = DESC90_RATE18M; break;
1362 case MGN_24M: ret = DESC90_RATE24M; break;
1363 case MGN_36M: ret = DESC90_RATE36M; break;
1364 case MGN_48M: ret = DESC90_RATE48M; break;
1365 case MGN_54M: ret = DESC90_RATE54M; break;
1367 // HT rate since here
1368 case MGN_MCS0: ret = DESC90_RATEMCS0; break;
1369 case MGN_MCS1: ret = DESC90_RATEMCS1; break;
1370 case MGN_MCS2: ret = DESC90_RATEMCS2; break;
1371 case MGN_MCS3: ret = DESC90_RATEMCS3; break;
1372 case MGN_MCS4: ret = DESC90_RATEMCS4; break;
1373 case MGN_MCS5: ret = DESC90_RATEMCS5; break;
1374 case MGN_MCS6: ret = DESC90_RATEMCS6; break;
1375 case MGN_MCS7: ret = DESC90_RATEMCS7; break;
1376 case MGN_MCS8: ret = DESC90_RATEMCS8; break;
1377 case MGN_MCS9: ret = DESC90_RATEMCS9; break;
1378 case MGN_MCS10: ret = DESC90_RATEMCS10; break;
1379 case MGN_MCS11: ret = DESC90_RATEMCS11; break;
1380 case MGN_MCS12: ret = DESC90_RATEMCS12; break;
1381 case MGN_MCS13: ret = DESC90_RATEMCS13; break;
1382 case MGN_MCS14: ret = DESC90_RATEMCS14; break;
1383 case MGN_MCS15: ret = DESC90_RATEMCS15; break;
1384 case (0x80|0x20): ret = DESC90_RATEMCS32; break;
1392 static u8 QueryIsShort(u8 TxHT, u8 TxRate, cb_desc *tcb_desc)
1396 tmp_Short = (TxHT==1)?((tcb_desc->bUseShortGI)?1:0):((tcb_desc->bUseShortPreamble)?1:0);
1398 if(TxHT==1 && TxRate != DESC90_RATEMCS15)
1405 * The tx procedure is just as following,
1406 * skb->cb will contain all the following information,
1407 * priority, morefrag, rate, &dev.
1409 short rtl8192_tx(struct net_device *dev, struct sk_buff* skb)
1411 struct r8192_priv *priv = ieee80211_priv(dev);
1412 struct rtl8192_tx_ring *ring;
1413 unsigned long flags;
1414 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1415 tx_desc_819x_pci *pdesc = NULL;
1416 TX_FWINFO_8190PCI *pTxFwInfo = NULL;
1418 bool multi_addr=false,broad_addr=false,uni_addr=false;
1419 u8* pda_addr = NULL;
1422 if(priv->bdisable_nic){
1423 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);
1428 priv->ieee80211->bAwakePktSent = true;
1431 mapping = pci_map_single(priv->pdev, skb->data, skb->len, PCI_DMA_TODEVICE);
1432 /* collect the tx packets statitcs */
1433 pda_addr = ((u8*)skb->data) + sizeof(TX_FWINFO_8190PCI);
1434 if(is_multicast_ether_addr(pda_addr))
1436 else if(is_broadcast_ether_addr(pda_addr))
1442 priv->stats.txbytesunicast += (u8)(skb->len) - sizeof(TX_FWINFO_8190PCI);
1444 priv->stats.txbytesmulticast +=(u8)(skb->len) - sizeof(TX_FWINFO_8190PCI);
1446 priv->stats.txbytesbroadcast += (u8)(skb->len) - sizeof(TX_FWINFO_8190PCI);
1448 /* fill tx firmware */
1449 pTxFwInfo = (PTX_FWINFO_8190PCI)skb->data;
1450 memset(pTxFwInfo,0,sizeof(TX_FWINFO_8190PCI));
1451 pTxFwInfo->TxHT = (tcb_desc->data_rate&0x80)?1:0;
1452 pTxFwInfo->TxRate = MRateToHwRate8190Pci((u8)tcb_desc->data_rate);
1453 pTxFwInfo->EnableCPUDur = tcb_desc->bTxEnableFwCalcDur;
1454 pTxFwInfo->Short = QueryIsShort(pTxFwInfo->TxHT, pTxFwInfo->TxRate, tcb_desc);
1456 /* Aggregation related */
1457 if(tcb_desc->bAMPDUEnable) {
1458 pTxFwInfo->AllowAggregation = 1;
1459 pTxFwInfo->RxMF = tcb_desc->ampdu_factor;
1460 pTxFwInfo->RxAMD = tcb_desc->ampdu_density;
1462 pTxFwInfo->AllowAggregation = 0;
1463 pTxFwInfo->RxMF = 0;
1464 pTxFwInfo->RxAMD = 0;
1468 // Protection mode related
1470 pTxFwInfo->RtsEnable = (tcb_desc->bRTSEnable)?1:0;
1471 pTxFwInfo->CtsEnable = (tcb_desc->bCTSEnable)?1:0;
1472 pTxFwInfo->RtsSTBC = (tcb_desc->bRTSSTBC)?1:0;
1473 pTxFwInfo->RtsHT= (tcb_desc->rts_rate&0x80)?1:0;
1474 pTxFwInfo->RtsRate = MRateToHwRate8190Pci((u8)tcb_desc->rts_rate);
1475 pTxFwInfo->RtsBandwidth = 0;
1476 pTxFwInfo->RtsSubcarrier = tcb_desc->RTSSC;
1477 pTxFwInfo->RtsShort = (pTxFwInfo->RtsHT==0)?(tcb_desc->bRTSUseShortPreamble?1:0):(tcb_desc->bRTSUseShortGI?1:0);
1479 // Set Bandwidth and sub-channel settings.
1481 if(priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20_40)
1483 if(tcb_desc->bPacketBW)
1485 pTxFwInfo->TxBandwidth = 1;
1487 pTxFwInfo->TxSubCarrier = 3;
1489 pTxFwInfo->TxSubCarrier = 0; //By SD3's Jerry suggestion, use duplicated mode, cosa 04012008
1494 pTxFwInfo->TxBandwidth = 0;
1495 pTxFwInfo->TxSubCarrier = priv->nCur40MhzPrimeSC;
1498 pTxFwInfo->TxBandwidth = 0;
1499 pTxFwInfo->TxSubCarrier = 0;
1504 /* 2007/07/25 MH Copy current TX FW info.*/
1505 memcpy((void*)(&Tmp_TxFwInfo), (void*)(pTxFwInfo), sizeof(TX_FWINFO_8190PCI));
1506 printk("&&&&&&&&&&&&&&&&&&&&&&====>print out fwinf\n");
1507 printk("===>enable fwcacl:%d\n", Tmp_TxFwInfo.EnableCPUDur);
1508 printk("===>RTS STBC:%d\n", Tmp_TxFwInfo.RtsSTBC);
1509 printk("===>RTS Subcarrier:%d\n", Tmp_TxFwInfo.RtsSubcarrier);
1510 printk("===>Allow Aggregation:%d\n", Tmp_TxFwInfo.AllowAggregation);
1511 printk("===>TX HT bit:%d\n", Tmp_TxFwInfo.TxHT);
1512 printk("===>Tx rate:%d\n", Tmp_TxFwInfo.TxRate);
1513 printk("===>Received AMPDU Density:%d\n", Tmp_TxFwInfo.RxAMD);
1514 printk("===>Received MPDU Factor:%d\n", Tmp_TxFwInfo.RxMF);
1515 printk("===>TxBandwidth:%d\n", Tmp_TxFwInfo.TxBandwidth);
1516 printk("===>TxSubCarrier:%d\n", Tmp_TxFwInfo.TxSubCarrier);
1518 printk("<=====**********************out of print\n");
1521 spin_lock_irqsave(&priv->irq_th_lock,flags);
1522 ring = &priv->tx_ring[tcb_desc->queue_index];
1523 if (tcb_desc->queue_index != BEACON_QUEUE) {
1524 idx = (ring->idx + skb_queue_len(&ring->queue)) % ring->entries;
1529 pdesc = &ring->desc[idx];
1530 if((pdesc->OWN == 1) && (tcb_desc->queue_index != BEACON_QUEUE)) {
1531 RT_TRACE(COMP_ERR,"No more TX desc@%d, ring->idx = %d,idx = %d,%x",
1532 tcb_desc->queue_index,ring->idx, idx,skb->len);
1533 spin_unlock_irqrestore(&priv->irq_th_lock,flags);
1537 /* fill tx descriptor */
1538 memset((u8*)pdesc,0,12);
1542 pdesc->Offset = sizeof(TX_FWINFO_8190PCI) + 8; //We must add 8!! Emily
1543 pdesc->PktSize = (u16)skb->len-sizeof(TX_FWINFO_8190PCI);
1547 pdesc->RATid = tcb_desc->RATRIndex;
1551 pdesc->SecType = 0x0;
1552 if (tcb_desc->bHwSec) {
1553 switch (priv->ieee80211->pairwise_key_type) {
1554 case KEY_TYPE_WEP40:
1555 case KEY_TYPE_WEP104:
1556 pdesc->SecType = 0x1;
1560 pdesc->SecType = 0x2;
1564 pdesc->SecType = 0x3;
1568 pdesc->SecType = 0x0;
1579 pdesc->QueueSelect = MapHwQueueToFirmwareQueue(tcb_desc->queue_index);
1580 pdesc->TxFWInfoSize = sizeof(TX_FWINFO_8190PCI);
1582 pdesc->DISFB = tcb_desc->bTxDisableRateFallBack;
1583 pdesc->USERATE = tcb_desc->bTxUseDriverAssingedRate;
1587 pdesc->TxBufferSize = skb->len;
1589 pdesc->TxBuffAddr = cpu_to_le32(mapping);
1590 __skb_queue_tail(&ring->queue, skb);
1592 spin_unlock_irqrestore(&priv->irq_th_lock,flags);
1593 dev->trans_start = jiffies;
1594 write_nic_word(dev,TPPoll,0x01<<tcb_desc->queue_index);
1598 static short rtl8192_alloc_rx_desc_ring(struct net_device *dev)
1600 struct r8192_priv *priv = ieee80211_priv(dev);
1601 rx_desc_819x_pci *entry = NULL;
1604 priv->rx_ring = pci_alloc_consistent(priv->pdev,
1605 sizeof(*priv->rx_ring) * priv->rxringcount, &priv->rx_ring_dma);
1607 if (!priv->rx_ring || (unsigned long)priv->rx_ring & 0xFF) {
1608 RT_TRACE(COMP_ERR,"Cannot allocate RX ring\n");
1612 memset(priv->rx_ring, 0, sizeof(*priv->rx_ring) * priv->rxringcount);
1615 for (i = 0; i < priv->rxringcount; i++) {
1616 struct sk_buff *skb = dev_alloc_skb(priv->rxbuffersize);
1617 dma_addr_t *mapping;
1618 entry = &priv->rx_ring[i];
1621 priv->rx_buf[i] = skb;
1622 mapping = (dma_addr_t *)skb->cb;
1623 *mapping = pci_map_single(priv->pdev, skb_tail_pointer(skb),
1624 priv->rxbuffersize, PCI_DMA_FROMDEVICE);
1626 entry->BufferAddress = cpu_to_le32(*mapping);
1628 entry->Length = priv->rxbuffersize;
1636 static int rtl8192_alloc_tx_desc_ring(struct net_device *dev,
1637 unsigned int prio, unsigned int entries)
1639 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1640 tx_desc_819x_pci *ring;
1644 ring = pci_alloc_consistent(priv->pdev, sizeof(*ring) * entries, &dma);
1645 if (!ring || (unsigned long)ring & 0xFF) {
1646 RT_TRACE(COMP_ERR, "Cannot allocate TX ring (prio = %d)\n", prio);
1650 memset(ring, 0, sizeof(*ring)*entries);
1651 priv->tx_ring[prio].desc = ring;
1652 priv->tx_ring[prio].dma = dma;
1653 priv->tx_ring[prio].idx = 0;
1654 priv->tx_ring[prio].entries = entries;
1655 skb_queue_head_init(&priv->tx_ring[prio].queue);
1657 for (i = 0; i < entries; i++)
1658 ring[i].NextDescAddress =
1659 cpu_to_le32((u32)dma + ((i + 1) % entries) * sizeof(*ring));
1665 static short rtl8192_pci_initdescring(struct net_device *dev)
1669 struct r8192_priv *priv = ieee80211_priv(dev);
1671 ret = rtl8192_alloc_rx_desc_ring(dev);
1677 /* general process for other queue */
1678 for (i = 0; i < MAX_TX_QUEUE_COUNT; i++) {
1679 ret = rtl8192_alloc_tx_desc_ring(dev, i, priv->txringcount);
1681 goto err_free_rings;
1685 /* specific process for hardware beacon process */
1686 ret = rtl8192_alloc_tx_desc_ring(dev, MAX_TX_QUEUE_COUNT - 1, 2);
1688 goto err_free_rings;
1694 rtl8192_free_rx_ring(dev);
1695 for (i = 0; i < MAX_TX_QUEUE_COUNT; i++)
1696 if (priv->tx_ring[i].desc)
1697 rtl8192_free_tx_ring(dev, i);
1701 static void rtl8192_pci_resetdescring(struct net_device *dev)
1703 struct r8192_priv *priv = ieee80211_priv(dev);
1706 /* force the rx_idx to the first one */
1708 rx_desc_819x_pci *entry = NULL;
1709 for (i = 0; i < priv->rxringcount; i++) {
1710 entry = &priv->rx_ring[i];
1716 /* after reset, release previous pending packet, and force the
1717 * tx idx to the first one */
1718 for (i = 0; i < MAX_TX_QUEUE_COUNT; i++) {
1719 if (priv->tx_ring[i].desc) {
1720 struct rtl8192_tx_ring *ring = &priv->tx_ring[i];
1722 while (skb_queue_len(&ring->queue)) {
1723 tx_desc_819x_pci *entry = &ring->desc[ring->idx];
1724 struct sk_buff *skb = __skb_dequeue(&ring->queue);
1726 pci_unmap_single(priv->pdev, le32_to_cpu(entry->TxBuffAddr),
1727 skb->len, PCI_DMA_TODEVICE);
1729 ring->idx = (ring->idx + 1) % ring->entries;
1736 static void rtl8192_link_change(struct net_device *dev)
1738 struct r8192_priv *priv = ieee80211_priv(dev);
1739 struct ieee80211_device* ieee = priv->ieee80211;
1740 //write_nic_word(dev, BCN_INTR_ITV, net->beacon_interval);
1741 if (ieee->state == IEEE80211_LINKED)
1743 rtl8192_net_update(dev);
1744 rtl8192_update_ratr_table(dev);
1746 //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
1747 if ((KEY_TYPE_WEP40 == ieee->pairwise_key_type) || (KEY_TYPE_WEP104 == ieee->pairwise_key_type))
1748 EnableHWSecurityConfig8192(dev);
1753 write_nic_byte(dev, 0x173, 0);
1755 /*update timing params*/
1756 //rtl8192_set_chan(dev, priv->chan);
1758 rtl8192_update_msr(dev);
1760 // 2007/10/16 MH MAC Will update TSF according to all received beacon, so we have
1761 // // To set CBSSID bit when link with any AP or STA.
1762 if (ieee->iw_mode == IW_MODE_INFRA || ieee->iw_mode == IW_MODE_ADHOC)
1765 reg = read_nic_dword(dev, RCR);
1766 if (priv->ieee80211->state == IEEE80211_LINKED)
1767 priv->ReceiveConfig = reg |= RCR_CBSSID;
1769 priv->ReceiveConfig = reg &= ~RCR_CBSSID;
1770 write_nic_dword(dev, RCR, reg);
1775 static const struct ieee80211_qos_parameters def_qos_parameters = {
1776 {3,3,3,3},/* cw_min */
1777 {7,7,7,7},/* cw_max */
1778 {2,2,2,2},/* aifs */
1779 {0,0,0,0},/* flags */
1780 {0,0,0,0} /* tx_op_limit */
1783 static void rtl8192_update_beacon(struct work_struct * work)
1785 struct r8192_priv *priv = container_of(work, struct r8192_priv, update_beacon_wq.work);
1786 struct net_device *dev = priv->ieee80211->dev;
1787 struct ieee80211_device* ieee = priv->ieee80211;
1788 struct ieee80211_network* net = &ieee->current_network;
1790 if (ieee->pHTInfo->bCurrentHTSupport)
1791 HTUpdateSelfAndPeerSetting(ieee, net);
1792 ieee->pHTInfo->bCurrentRT2RTLongSlotTime = net->bssht.bdRT2RTLongSlotTime;
1793 rtl8192_update_cap(dev, net->capability);
1797 * background support to run QoS activate functionality
1799 static const int WDCAPARA_ADD[] = {EDCAPARA_BE,EDCAPARA_BK,EDCAPARA_VI,EDCAPARA_VO};
1800 static void rtl8192_qos_activate(struct work_struct * work)
1802 struct r8192_priv *priv = container_of(work, struct r8192_priv, qos_activate);
1803 struct net_device *dev = priv->ieee80211->dev;
1804 struct ieee80211_qos_parameters *qos_parameters = &priv->ieee80211->current_network.qos_data.parameters;
1805 u8 mode = priv->ieee80211->current_network.mode;
1810 mutex_lock(&priv->mutex);
1811 if(priv->ieee80211->state != IEEE80211_LINKED)
1813 RT_TRACE(COMP_QOS,"qos active process with associate response received\n");
1814 /* It better set slot time at first */
1815 /* For we just support b/g mode at present, let the slot time at 9/20 selection */
1816 /* update the ac parameter to related registers */
1817 for(i = 0; i < QOS_QUEUE_NUM; i++) {
1818 //Mode G/A: slotTimeTimer = 9; Mode B: 20
1819 u1bAIFS = qos_parameters->aifs[i] * ((mode&(IEEE_G|IEEE_N_24G)) ?9:20) + aSifsTime;
1820 u4bAcParam = ((((u32)(qos_parameters->tx_op_limit[i]))<< AC_PARAM_TXOP_LIMIT_OFFSET)|
1821 (((u32)(qos_parameters->cw_max[i]))<< AC_PARAM_ECW_MAX_OFFSET)|
1822 (((u32)(qos_parameters->cw_min[i]))<< AC_PARAM_ECW_MIN_OFFSET)|
1823 ((u32)u1bAIFS << AC_PARAM_AIFS_OFFSET));
1824 //printk("===>u4bAcParam:%x, ", u4bAcParam);
1825 write_nic_dword(dev, WDCAPARA_ADD[i], u4bAcParam);
1826 //write_nic_dword(dev, WDCAPARA_ADD[i], 0x005e4332);
1830 mutex_unlock(&priv->mutex);
1833 static int rtl8192_qos_handle_probe_response(struct r8192_priv *priv,
1835 struct ieee80211_network *network)
1838 u32 size = sizeof(struct ieee80211_qos_parameters);
1840 if(priv->ieee80211->state !=IEEE80211_LINKED)
1843 if ((priv->ieee80211->iw_mode != IW_MODE_INFRA))
1846 if (network->flags & NETWORK_HAS_QOS_MASK) {
1847 if (active_network &&
1848 (network->flags & NETWORK_HAS_QOS_PARAMETERS))
1849 network->qos_data.active = network->qos_data.supported;
1851 if ((network->qos_data.active == 1) && (active_network == 1) &&
1852 (network->flags & NETWORK_HAS_QOS_PARAMETERS) &&
1853 (network->qos_data.old_param_count !=
1854 network->qos_data.param_count)) {
1855 network->qos_data.old_param_count =
1856 network->qos_data.param_count;
1857 queue_work(priv->priv_wq, &priv->qos_activate);
1858 RT_TRACE (COMP_QOS, "QoS parameters change call "
1862 memcpy(&priv->ieee80211->current_network.qos_data.parameters,
1863 &def_qos_parameters, size);
1865 if ((network->qos_data.active == 1) && (active_network == 1)) {
1866 queue_work(priv->priv_wq, &priv->qos_activate);
1867 RT_TRACE(COMP_QOS, "QoS was disabled call qos_activate \n");
1869 network->qos_data.active = 0;
1870 network->qos_data.supported = 0;
1876 /* handle manage frame frame beacon and probe response */
1877 static int rtl8192_handle_beacon(struct net_device * dev,
1878 struct ieee80211_beacon * beacon,
1879 struct ieee80211_network * network)
1881 struct r8192_priv *priv = ieee80211_priv(dev);
1883 rtl8192_qos_handle_probe_response(priv,1,network);
1885 queue_delayed_work(priv->priv_wq, &priv->update_beacon_wq, 0);
1891 * handling the beaconing responses. if we get different QoS setting
1892 * off the network from the associated setting, adjust the QoS setting
1894 static int rtl8192_qos_association_resp(struct r8192_priv *priv,
1895 struct ieee80211_network *network)
1898 unsigned long flags;
1899 u32 size = sizeof(struct ieee80211_qos_parameters);
1900 int set_qos_param = 0;
1902 if ((priv == NULL) || (network == NULL))
1905 if(priv->ieee80211->state !=IEEE80211_LINKED)
1908 if ((priv->ieee80211->iw_mode != IW_MODE_INFRA))
1911 spin_lock_irqsave(&priv->ieee80211->lock, flags);
1912 if(network->flags & NETWORK_HAS_QOS_PARAMETERS) {
1913 memcpy(&priv->ieee80211->current_network.qos_data.parameters,
1914 &network->qos_data.parameters,
1915 sizeof(struct ieee80211_qos_parameters));
1916 priv->ieee80211->current_network.qos_data.active = 1;
1918 if((priv->ieee80211->current_network.qos_data.param_count !=
1919 network->qos_data.param_count))
1923 /* update qos parameter for current network */
1924 priv->ieee80211->current_network.qos_data.old_param_count =
1925 priv->ieee80211->current_network.qos_data.param_count;
1926 priv->ieee80211->current_network.qos_data.param_count =
1927 network->qos_data.param_count;
1930 memcpy(&priv->ieee80211->current_network.qos_data.parameters,
1931 &def_qos_parameters, size);
1932 priv->ieee80211->current_network.qos_data.active = 0;
1933 priv->ieee80211->current_network.qos_data.supported = 0;
1937 spin_unlock_irqrestore(&priv->ieee80211->lock, flags);
1939 RT_TRACE(COMP_QOS, "%s: network->flags = %d,%d\n",__FUNCTION__,network->flags ,priv->ieee80211->current_network.qos_data.active);
1940 if (set_qos_param == 1)
1941 queue_work(priv->priv_wq, &priv->qos_activate);
1947 static int rtl8192_handle_assoc_response(struct net_device *dev,
1948 struct ieee80211_assoc_response_frame *resp,
1949 struct ieee80211_network *network)
1951 struct r8192_priv *priv = ieee80211_priv(dev);
1952 rtl8192_qos_association_resp(priv, network);
1957 /* updateRATRTabel for MCS only. Basic rate is not implemented. */
1958 static void rtl8192_update_ratr_table(struct net_device* dev)
1960 struct r8192_priv* priv = ieee80211_priv(dev);
1961 struct ieee80211_device* ieee = priv->ieee80211;
1962 u8* pMcsRate = ieee->dot11HTOperationalRateSet;
1966 rtl8192_config_rate(dev, (u16*)(&ratr_value));
1967 ratr_value |= (*(u16*)(pMcsRate)) << 12;
1972 ratr_value &= 0x00000FF0;
1975 ratr_value &= 0x0000000F;
1978 ratr_value &= 0x00000FF7;
1982 if (ieee->pHTInfo->PeerMimoPs == 0) //MIMO_PS_STATIC
1983 ratr_value &= 0x0007F007;
1985 if (priv->rf_type == RF_1T2R)
1986 ratr_value &= 0x000FF007;
1988 ratr_value &= 0x0F81F007;
1994 ratr_value &= 0x0FFFFFFF;
1995 if(ieee->pHTInfo->bCurTxBW40MHz && ieee->pHTInfo->bCurShortGI40MHz){
1996 ratr_value |= 0x80000000;
1997 }else if(!ieee->pHTInfo->bCurTxBW40MHz && ieee->pHTInfo->bCurShortGI20MHz){
1998 ratr_value |= 0x80000000;
2000 write_nic_dword(dev, RATR0+rate_index*4, ratr_value);
2001 write_nic_byte(dev, UFWP, 1);
2004 static bool GetNmodeSupportBySecCfg8190Pci(struct net_device*dev)
2008 struct r8192_priv *priv = ieee80211_priv(dev);
2009 struct ieee80211_device *ieee = priv->ieee80211;
2010 return !(ieee->rtllib_ap_sec_type &&
2011 (ieee->rtllib_ap_sec_type(ieee)&(SEC_ALG_WEP|SEC_ALG_TKIP)));
2013 struct r8192_priv* priv = ieee80211_priv(dev);
2014 struct ieee80211_device* ieee = priv->ieee80211;
2015 int wpa_ie_len= ieee->wpa_ie_len;
2016 struct ieee80211_crypt_data* crypt;
2019 crypt = ieee->crypt[ieee->tx_keyidx];
2020 encrypt = (ieee->current_network.capability & WLAN_CAPABILITY_PRIVACY) || (ieee->host_encrypt && crypt && crypt->ops && (0 == strcmp(crypt->ops->name,"WEP")));
2023 if(encrypt && (wpa_ie_len == 0)) {
2024 /* wep encryption, no N mode setting */
2026 // } else if((wpa_ie_len != 0)&&(memcmp(&(ieee->wpa_ie[14]),ccmp_ie,4))) {
2027 } else if((wpa_ie_len != 0)) {
2028 /* parse pairwise key type */
2029 //if((pairwisekey = WEP40)||(pairwisekey = WEP104)||(pairwisekey = TKIP))
2030 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))))
2035 //RT_TRACE(COMP_ERR,"In %s The GroupEncAlgorithm is [4]\n",__FUNCTION__ );
2043 static void rtl8192_refresh_supportrate(struct r8192_priv* priv)
2045 struct ieee80211_device* ieee = priv->ieee80211;
2046 //we donot consider set support rate for ABG mode, only HT MCS rate is set here.
2047 if (ieee->mode == WIRELESS_MODE_N_24G || ieee->mode == WIRELESS_MODE_N_5G)
2049 memcpy(ieee->Regdot11HTOperationalRateSet, ieee->RegHTSuppRateSet, 16);
2050 //RT_DEBUG_DATA(COMP_INIT, ieee->RegHTSuppRateSet, 16);
2051 //RT_DEBUG_DATA(COMP_INIT, ieee->Regdot11HTOperationalRateSet, 16);
2054 memset(ieee->Regdot11HTOperationalRateSet, 0, 16);
2057 static u8 rtl8192_getSupportedWireleeMode(struct net_device*dev)
2059 struct r8192_priv *priv = ieee80211_priv(dev);
2061 switch(priv->rf_chip)
2066 ret = (WIRELESS_MODE_N_24G|WIRELESS_MODE_G|WIRELESS_MODE_B);
2069 ret = (WIRELESS_MODE_A|WIRELESS_MODE_N_5G);
2072 ret = WIRELESS_MODE_B;
2078 static void rtl8192_SetWirelessMode(struct net_device* dev, u8 wireless_mode)
2080 struct r8192_priv *priv = ieee80211_priv(dev);
2081 u8 bSupportMode = rtl8192_getSupportedWireleeMode(dev);
2084 if ((wireless_mode == WIRELESS_MODE_AUTO) || ((wireless_mode&bSupportMode)==0))
2086 if(bSupportMode & WIRELESS_MODE_N_24G)
2088 wireless_mode = WIRELESS_MODE_N_24G;
2090 else if(bSupportMode & WIRELESS_MODE_N_5G)
2092 wireless_mode = WIRELESS_MODE_N_5G;
2094 else if((bSupportMode & WIRELESS_MODE_A))
2096 wireless_mode = WIRELESS_MODE_A;
2098 else if((bSupportMode & WIRELESS_MODE_G))
2100 wireless_mode = WIRELESS_MODE_G;
2102 else if((bSupportMode & WIRELESS_MODE_B))
2104 wireless_mode = WIRELESS_MODE_B;
2107 RT_TRACE(COMP_ERR, "%s(), No valid wireless mode supported, SupportedWirelessMode(%x)!!!\n", __FUNCTION__,bSupportMode);
2108 wireless_mode = WIRELESS_MODE_B;
2111 #ifdef TO_DO_LIST //// TODO: this function doesn't work well at this time, we should wait for FPGA
2112 ActUpdateChannelAccessSetting( pAdapter, pHalData->CurrentWirelessMode, &pAdapter->MgntInfo.Info8185.ChannelAccessSetting );
2114 priv->ieee80211->mode = wireless_mode;
2116 if ((wireless_mode == WIRELESS_MODE_N_24G) || (wireless_mode == WIRELESS_MODE_N_5G))
2117 priv->ieee80211->pHTInfo->bEnableHT = 1;
2119 priv->ieee80211->pHTInfo->bEnableHT = 0;
2120 RT_TRACE(COMP_INIT, "Current Wireless Mode is %x\n", wireless_mode);
2121 rtl8192_refresh_supportrate(priv);
2126 static bool GetHalfNmodeSupportByAPs819xPci(struct net_device* dev)
2128 struct r8192_priv* priv = ieee80211_priv(dev);
2129 struct ieee80211_device* ieee = priv->ieee80211;
2131 return ieee->bHalfWirelessN24GMode;
2134 short rtl8192_is_tx_queue_empty(struct net_device *dev)
2137 struct r8192_priv *priv = ieee80211_priv(dev);
2138 for (i=0; i<=MGNT_QUEUE; i++)
2140 if ((i== TXCMD_QUEUE) || (i == HCCA_QUEUE) )
2142 if (skb_queue_len(&(&priv->tx_ring[i])->queue) > 0){
2143 printk("===>tx queue is not empty:%d, %d\n", i, skb_queue_len(&(&priv->tx_ring[i])->queue));
2150 static void rtl8192_hw_sleep_down(struct net_device *dev)
2152 struct r8192_priv *priv = ieee80211_priv(dev);
2153 unsigned long flags = 0;
2155 spin_lock_irqsave(&priv->rf_ps_lock,flags);
2156 if (priv->RFChangeInProgress) {
2157 spin_unlock_irqrestore(&priv->rf_ps_lock,flags);
2158 RT_TRACE(COMP_RF, "rtl8192_hw_sleep_down(): RF Change in progress! \n");
2159 printk("rtl8192_hw_sleep_down(): RF Change in progress!\n");
2162 spin_unlock_irqrestore(&priv->rf_ps_lock,flags);
2164 MgntActSet_RF_State(dev, eRfSleep, RF_CHANGE_BY_PS);
2167 static void rtl8192_hw_sleep_wq (struct work_struct *work)
2169 struct delayed_work *dwork = container_of(work,struct delayed_work,work);
2170 struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,hw_sleep_wq);
2171 struct net_device *dev = ieee->dev;
2173 rtl8192_hw_sleep_down(dev);
2176 static void rtl8192_hw_wakeup(struct net_device* dev)
2178 struct r8192_priv *priv = ieee80211_priv(dev);
2179 unsigned long flags = 0;
2181 spin_lock_irqsave(&priv->rf_ps_lock,flags);
2182 if (priv->RFChangeInProgress) {
2183 spin_unlock_irqrestore(&priv->rf_ps_lock,flags);
2184 RT_TRACE(COMP_RF, "rtl8192_hw_wakeup(): RF Change in progress! \n");
2185 printk("rtl8192_hw_wakeup(): RF Change in progress! schedule wake up task again\n");
2186 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
2189 spin_unlock_irqrestore(&priv->rf_ps_lock,flags);
2191 MgntActSet_RF_State(dev, eRfOn, RF_CHANGE_BY_PS);
2194 void rtl8192_hw_wakeup_wq (struct work_struct *work)
2196 struct delayed_work *dwork = container_of(work,struct delayed_work,work);
2197 struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,hw_wakeup_wq);
2198 struct net_device *dev = ieee->dev;
2199 rtl8192_hw_wakeup(dev);
2203 #define MIN_SLEEP_TIME 50
2204 #define MAX_SLEEP_TIME 10000
2205 static void rtl8192_hw_to_sleep(struct net_device *dev, u32 th, u32 tl)
2207 struct r8192_priv *priv = ieee80211_priv(dev);
2210 unsigned long flags;
2212 spin_lock_irqsave(&priv->ps_lock,flags);
2214 // Writing HW register with 0 equals to disable
2215 // the timer, that is not really what we want
2217 tl -= MSECS(8+16+7);
2219 // If the interval in witch we are requested to sleep is too
2220 // short then give up and remain awake
2221 // when we sleep after send null frame, the timer will be too short to sleep.
2223 if(((tl>=rb)&& (tl-rb) <= MSECS(MIN_SLEEP_TIME))
2224 ||((rb>tl)&& (rb-tl) < MSECS(MIN_SLEEP_TIME))) {
2225 spin_unlock_irqrestore(&priv->ps_lock,flags);
2226 printk("too short to sleep::%x, %x, %lx\n",tl, rb, MSECS(MIN_SLEEP_TIME));
2230 if(((tl > rb) && ((tl-rb) > MSECS(MAX_SLEEP_TIME)))||
2231 ((tl < rb) && (tl>MSECS(69)) && ((rb-tl) > MSECS(MAX_SLEEP_TIME)))||
2232 ((tl<rb)&&(tl<MSECS(69))&&((tl+0xffffffff-rb)>MSECS(MAX_SLEEP_TIME)))) {
2233 printk("========>too long to sleep:%x, %x, %lx\n", tl, rb, MSECS(MAX_SLEEP_TIME));
2234 spin_unlock_irqrestore(&priv->ps_lock,flags);
2238 u32 tmp = (tl>rb)?(tl-rb):(rb-tl);
2239 queue_delayed_work(priv->ieee80211->wq,
2240 &priv->ieee80211->hw_wakeup_wq,tmp);
2241 //PowerSave not supported when kernel version less 2.6.20
2243 queue_delayed_work(priv->ieee80211->wq,
2244 (void *)&priv->ieee80211->hw_sleep_wq,0);
2245 spin_unlock_irqrestore(&priv->ps_lock,flags);
2249 static void rtl8192_init_priv_variable(struct net_device* dev)
2251 struct r8192_priv *priv = ieee80211_priv(dev);
2253 PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->ieee80211->PowerSaveControl));
2255 // Default Halt the NIC if RF is OFF.
2256 pPSC->RegRfPsLevel |= RT_RF_OFF_LEVL_HALT_NIC;
2257 pPSC->RegRfPsLevel |= RT_RF_OFF_LEVL_CLK_REQ;
2258 pPSC->RegRfPsLevel |= RT_RF_OFF_LEVL_ASPM;
2259 pPSC->RegRfPsLevel |= RT_RF_LPS_LEVEL_ASPM;
2260 pPSC->bLeisurePs = true;
2261 pPSC->RegMaxLPSAwakeIntvl = 5;
2262 priv->bHwRadioOff = false;
2264 priv->being_init_adapter = false;
2265 priv->txbuffsize = 1600;//1024;
2266 priv->txfwbuffersize = 4096;
2267 priv->txringcount = 64;//32;
2268 //priv->txbeaconcount = priv->txringcount;
2269 priv->txbeaconcount = 2;
2270 priv->rxbuffersize = 9100;//2048;//1024;
2271 priv->rxringcount = MAX_RX_COUNT;//64;
2272 priv->irq_enabled=0;
2273 priv->card_8192 = NIC_8192E;
2274 priv->rx_skb_complete = 1;
2275 priv->chan = 1; //set to channel 1
2276 priv->RegWirelessMode = WIRELESS_MODE_AUTO;
2277 priv->RegChannelPlan = 0xf;
2278 priv->nrxAMPDU_size = 0;
2279 priv->nrxAMPDU_aggr_num = 0;
2280 priv->last_rxdesc_tsf_high = 0;
2281 priv->last_rxdesc_tsf_low = 0;
2282 priv->ieee80211->mode = WIRELESS_MODE_AUTO; //SET AUTO
2283 priv->ieee80211->iw_mode = IW_MODE_INFRA;
2284 priv->ieee80211->ieee_up=0;
2285 priv->retry_rts = DEFAULT_RETRY_RTS;
2286 priv->retry_data = DEFAULT_RETRY_DATA;
2287 priv->ieee80211->rts = DEFAULT_RTS_THRESHOLD;
2288 priv->ieee80211->rate = 110; //11 mbps
2289 priv->ieee80211->short_slot = 1;
2290 priv->promisc = (dev->flags & IFF_PROMISC) ? 1:0;
2291 priv->bcck_in_ch14 = false;
2292 priv->bfsync_processing = false;
2293 priv->CCKPresentAttentuation = 0;
2294 priv->rfa_txpowertrackingindex = 0;
2295 priv->rfc_txpowertrackingindex = 0;
2297 priv->ScanDelay = 50;//for Scan TODO
2298 //added by amy for silent reset
2299 priv->ResetProgress = RESET_TYPE_NORESET;
2300 priv->bForcedSilentReset = 0;
2301 priv->bDisableNormalResetCheck = false;
2302 priv->force_reset = false;
2303 //added by amy for power save
2305 priv->ieee80211->RfOffReason = 0;
2306 priv->RFChangeInProgress = false;
2307 priv->bHwRfOffAction = 0;
2308 priv->SetRFPowerStateInProgress = false;
2309 priv->ieee80211->PowerSaveControl.bInactivePs = true;
2310 priv->ieee80211->PowerSaveControl.bIPSModeBackup = false;
2312 priv->txpower_checkcnt = 0;
2313 priv->thermal_readback_index =0;
2314 priv->txpower_tracking_callback_cnt = 0;
2315 priv->ccktxpower_adjustcnt_ch14 = 0;
2316 priv->ccktxpower_adjustcnt_not_ch14 = 0;
2318 priv->ieee80211->current_network.beacon_interval = DEFAULT_BEACONINTERVAL;
2319 priv->ieee80211->iw_mode = IW_MODE_INFRA;
2320 priv->ieee80211->softmac_features = IEEE_SOFTMAC_SCAN |
2321 IEEE_SOFTMAC_ASSOCIATE | IEEE_SOFTMAC_PROBERQ |
2322 IEEE_SOFTMAC_PROBERS | IEEE_SOFTMAC_TX_QUEUE;/* |
2323 IEEE_SOFTMAC_BEACONS;*///added by amy 080604 //| //IEEE_SOFTMAC_SINGLE_QUEUE;
2325 priv->ieee80211->active_scan = 1;
2326 priv->ieee80211->modulation = IEEE80211_CCK_MODULATION | IEEE80211_OFDM_MODULATION;
2327 priv->ieee80211->host_encrypt = 1;
2328 priv->ieee80211->host_decrypt = 1;
2329 //priv->ieee80211->start_send_beacons = NULL;//rtl819xusb_beacon_tx;//-by amy 080604
2330 //priv->ieee80211->stop_send_beacons = NULL;//rtl8192_beacon_stop;//-by amy 080604
2331 priv->ieee80211->start_send_beacons = rtl8192_start_beacon;//+by david 081107
2332 priv->ieee80211->stop_send_beacons = rtl8192_stop_beacon;//+by david 081107
2333 priv->ieee80211->softmac_hard_start_xmit = rtl8192_hard_start_xmit;
2334 priv->ieee80211->set_chan = rtl8192_set_chan;
2335 priv->ieee80211->link_change = rtl8192_link_change;
2336 priv->ieee80211->softmac_data_hard_start_xmit = rtl8192_hard_data_xmit;
2337 priv->ieee80211->data_hard_stop = rtl8192_data_hard_stop;
2338 priv->ieee80211->data_hard_resume = rtl8192_data_hard_resume;
2339 priv->ieee80211->init_wmmparam_flag = 0;
2340 priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD;
2341 priv->ieee80211->check_nic_enough_desc = check_nic_enough_desc;
2342 priv->ieee80211->tx_headroom = sizeof(TX_FWINFO_8190PCI);
2343 priv->ieee80211->qos_support = 1;
2344 priv->ieee80211->dot11PowerSaveMode = 0;
2346 // priv->ieee80211->SwChnlByTimerHandler = rtl8192_phy_SwChnl;
2347 priv->ieee80211->SetBWModeHandler = rtl8192_SetBWMode;
2348 priv->ieee80211->handle_assoc_response = rtl8192_handle_assoc_response;
2349 priv->ieee80211->handle_beacon = rtl8192_handle_beacon;
2351 priv->ieee80211->sta_wake_up = rtl8192_hw_wakeup;
2352 // priv->ieee80211->ps_request_tx_ack = rtl8192_rq_tx_ack;
2353 priv->ieee80211->enter_sleep_state = rtl8192_hw_to_sleep;
2354 priv->ieee80211->ps_is_queue_empty = rtl8192_is_tx_queue_empty;
2356 priv->ieee80211->GetNmodeSupportBySecCfg = GetNmodeSupportBySecCfg8190Pci;
2357 priv->ieee80211->SetWirelessMode = rtl8192_SetWirelessMode;
2358 priv->ieee80211->GetHalfNmodeSupportByAPsHandler = GetHalfNmodeSupportByAPs819xPci;
2361 priv->ieee80211->InitialGainHandler = InitialGain819xPci;
2364 priv->ieee80211->ieee80211_ips_leave_wq = ieee80211_ips_leave_wq;
2365 priv->ieee80211->ieee80211_ips_leave = ieee80211_ips_leave;
2368 priv->ieee80211->LeisurePSLeave = LeisurePSLeave;
2371 priv->ieee80211->SetHwRegHandler = rtl8192e_SetHwReg;
2372 priv->ieee80211->rtllib_ap_sec_type = rtl8192e_ap_sec_type;
2374 priv->card_type = USB;
2376 priv->ShortRetryLimit = 0x30;
2377 priv->LongRetryLimit = 0x30;
2379 priv->EarlyRxThreshold = 7;
2380 priv->enable_gpio0 = 0;
2382 priv->TransmitConfig = 0;
2384 priv->ReceiveConfig = RCR_ADD3 |
2385 RCR_AMF | RCR_ADF | //accept management/data
2386 RCR_AICV | //accept control frame for SW AP needs PS-poll, 2005.07.07, by rcnjko.
2387 RCR_AB | RCR_AM | RCR_APM | //accept BC/MC/UC
2388 RCR_AAP | ((u32)7<<RCR_MXDMA_OFFSET) |
2389 ((u32)7 << RCR_FIFO_OFFSET) | RCR_ONLYERLPKT;
2391 priv->irq_mask = (u32)(IMR_ROK | IMR_VODOK | IMR_VIDOK | IMR_BEDOK | IMR_BKDOK |
2392 IMR_HCCADOK | IMR_MGNTDOK | IMR_COMDOK | IMR_HIGHDOK |
2393 IMR_BDOK | IMR_RXCMDOK | IMR_TIMEOUT0 | IMR_RDU | IMR_RXFOVW |
2394 IMR_TXFOVW | IMR_BcnInt | IMR_TBDOK | IMR_TBDER);
2396 priv->AcmControl = 0;
2397 priv->pFirmware = (rt_firmware*)vmalloc(sizeof(rt_firmware));
2398 if (priv->pFirmware)
2399 memset(priv->pFirmware, 0, sizeof(rt_firmware));
2401 /* rx related queue */
2402 skb_queue_head_init(&priv->rx_queue);
2403 skb_queue_head_init(&priv->skb_queue);
2405 /* Tx related queue */
2406 for(i = 0; i < MAX_QUEUE_SIZE; i++) {
2407 skb_queue_head_init(&priv->ieee80211->skb_waitQ [i]);
2409 for(i = 0; i < MAX_QUEUE_SIZE; i++) {
2410 skb_queue_head_init(&priv->ieee80211->skb_aggQ [i]);
2412 priv->rf_set_chan = rtl8192_phy_SwChnl;
2415 static void rtl8192_init_priv_lock(struct r8192_priv* priv)
2417 spin_lock_init(&priv->tx_lock);
2418 spin_lock_init(&priv->irq_lock);//added by thomas
2419 spin_lock_init(&priv->irq_th_lock);
2420 spin_lock_init(&priv->rf_ps_lock);
2421 spin_lock_init(&priv->ps_lock);
2422 //spin_lock_init(&priv->rf_lock);
2423 sema_init(&priv->wx_sem,1);
2424 sema_init(&priv->rf_sem,1);
2425 mutex_init(&priv->mutex);
2428 /* init tasklet and wait_queue here */
2429 #define DRV_NAME "wlan0"
2430 static void rtl8192_init_priv_task(struct net_device* dev)
2432 struct r8192_priv *priv = ieee80211_priv(dev);
2434 #ifdef PF_SYNCTHREAD
2435 priv->priv_wq = create_workqueue(DRV_NAME,0);
2437 priv->priv_wq = create_workqueue(DRV_NAME);
2441 INIT_WORK(&priv->ieee80211->ips_leave_wq, (void*)IPSLeave_wq);
2444 // INIT_WORK(&priv->reset_wq, (void(*)(void*)) rtl8192_restart);
2445 INIT_WORK(&priv->reset_wq, rtl8192_restart);
2446 // INIT_DELAYED_WORK(&priv->watch_dog_wq, hal_dm_watchdog);
2447 INIT_DELAYED_WORK(&priv->watch_dog_wq, rtl819x_watchdog_wqcallback);
2448 INIT_DELAYED_WORK(&priv->txpower_tracking_wq, dm_txpower_trackingcallback);
2449 INIT_DELAYED_WORK(&priv->rfpath_check_wq, dm_rf_pathcheck_workitemcallback);
2450 INIT_DELAYED_WORK(&priv->update_beacon_wq, rtl8192_update_beacon);
2451 //INIT_WORK(&priv->SwChnlWorkItem, rtl8192_SwChnl_WorkItem);
2452 //INIT_WORK(&priv->SetBWModeWorkItem, rtl8192_SetBWModeWorkItem);
2453 INIT_WORK(&priv->qos_activate, rtl8192_qos_activate);
2454 INIT_DELAYED_WORK(&priv->ieee80211->hw_wakeup_wq,(void*) rtl8192_hw_wakeup_wq);
2455 INIT_DELAYED_WORK(&priv->ieee80211->hw_sleep_wq,(void*) rtl8192_hw_sleep_wq);
2457 tasklet_init(&priv->irq_rx_tasklet,
2458 (void(*)(unsigned long))rtl8192_irq_rx_tasklet,
2459 (unsigned long)priv);
2460 tasklet_init(&priv->irq_tx_tasklet,
2461 (void(*)(unsigned long))rtl8192_irq_tx_tasklet,
2462 (unsigned long)priv);
2463 tasklet_init(&priv->irq_prepare_beacon_tasklet,
2464 (void(*)(unsigned long))rtl8192_prepare_beacon,
2465 (unsigned long)priv);
2468 static void rtl8192_get_eeprom_size(struct net_device* dev)
2471 struct r8192_priv *priv = ieee80211_priv(dev);
2472 RT_TRACE(COMP_INIT, "===========>%s()\n", __FUNCTION__);
2473 curCR = read_nic_dword(dev, EPROM_CMD);
2474 RT_TRACE(COMP_INIT, "read from Reg Cmd9346CR(%x):%x\n", EPROM_CMD, curCR);
2475 //whether need I consider BIT5?
2476 priv->epromtype = (curCR & EPROM_CMD_9356SEL) ? EPROM_93c56 : EPROM_93c46;
2477 RT_TRACE(COMP_INIT, "<===========%s(), epromtype:%d\n", __FUNCTION__, priv->epromtype);
2481 * used to swap endian. as ntohl & htonl are not
2482 * neccessary to swap endian, so use this instead.
2484 static inline u16 endian_swap(u16* data)
2487 *data = (tmp >> 8) | (tmp << 8);
2492 * Adapter->EEPROMAddressSize should be set before this function call.
2493 * EEPROM address size can be got through GetEEPROMSize8185()
2495 static void rtl8192_read_eeprom_info(struct net_device* dev)
2497 struct r8192_priv *priv = ieee80211_priv(dev);
2501 u8 ICVer8192, ICVer8256;
2503 u16 i,usValue, IC_Version;
2507 u8 EepromTxPower[100];
2509 u8 bMac_Tmp_Addr[6] = {0x00, 0xe0, 0x4c, 0x00, 0x00, 0x01};
2510 RT_TRACE(COMP_INIT, "====> rtl8192_read_eeprom_info\n");
2513 // TODO: I don't know if we need to apply EF function to EEPROM read function
2515 //2 Read EEPROM ID to make sure autoload is success
2516 EEPROMId = eprom_read(dev, 0);
2517 if( EEPROMId != RTL8190_EEPROM_ID )
2519 RT_TRACE(COMP_ERR, "EEPROM ID is invalid:%x, %x\n", EEPROMId, RTL8190_EEPROM_ID);
2520 priv->AutoloadFailFlag=true;
2524 priv->AutoloadFailFlag=false;
2528 // Assign Chip Version ID
2530 // Read IC Version && Channel Plan
2531 if(!priv->AutoloadFailFlag)
2534 priv->eeprom_vid = eprom_read(dev, (EEPROM_VID >> 1));
2535 priv->eeprom_did = eprom_read(dev, (EEPROM_DID >> 1));
2537 usValue = eprom_read(dev, (u16)(EEPROM_Customer_ID>>1)) >> 8 ;
2538 priv->eeprom_CustomerID = (u8)( usValue & 0xff);
2539 usValue = eprom_read(dev, (EEPROM_ICVersion_ChannelPlan>>1));
2540 priv->eeprom_ChannelPlan = usValue&0xff;
2541 IC_Version = ((usValue&0xff00)>>8);
2544 priv->card_8192_version = (VERSION_8190)(IC_Version);
2547 ICVer8192 = (IC_Version&0xf); //bit0~3; 1:A cut, 2:B cut, 3:C cut...
2548 ICVer8256 = ((IC_Version&0xf0)>>4);//bit4~6, bit7 reserved for other RF chip; 1:A cut, 2:B cut, 3:C cut...
2549 RT_TRACE(COMP_INIT, "\nICVer8192 = 0x%x\n", ICVer8192);
2550 RT_TRACE(COMP_INIT, "\nICVer8256 = 0x%x\n", ICVer8256);
2551 if(ICVer8192 == 0x2) //B-cut
2553 if(ICVer8256 == 0x5) //E-cut
2554 priv->card_8192_version= VERSION_8190_BE;
2558 switch(priv->card_8192_version)
2560 case VERSION_8190_BD:
2561 case VERSION_8190_BE:
2564 priv->card_8192_version = VERSION_8190_BD;
2567 RT_TRACE(COMP_INIT, "\nIC Version = 0x%x\n", priv->card_8192_version);
2571 priv->card_8192_version = VERSION_8190_BD;
2572 priv->eeprom_vid = 0;
2573 priv->eeprom_did = 0;
2574 priv->eeprom_CustomerID = 0;
2575 priv->eeprom_ChannelPlan = 0;
2576 RT_TRACE(COMP_INIT, "\nIC Version = 0x%x\n", 0xff);
2579 RT_TRACE(COMP_INIT, "EEPROM VID = 0x%4x\n", priv->eeprom_vid);
2580 RT_TRACE(COMP_INIT, "EEPROM DID = 0x%4x\n", priv->eeprom_did);
2581 RT_TRACE(COMP_INIT,"EEPROM Customer ID: 0x%2x\n", priv->eeprom_CustomerID);
2583 //2 Read Permanent MAC address
2584 if(!priv->AutoloadFailFlag)
2586 for(i = 0; i < 6; i += 2)
2588 usValue = eprom_read(dev, (u16) ((EEPROM_NODE_ADDRESS_BYTE_0+i)>>1));
2589 *(u16*)(&dev->dev_addr[i]) = usValue;
2592 // when auto load failed, the last address byte set to be a random one.
2593 // added by david woo.2007/11/7
2594 memcpy(dev->dev_addr, bMac_Tmp_Addr, 6);
2597 RT_TRACE(COMP_INIT, "Permanent Address = %pM\n", dev->dev_addr);
2599 //2 TX Power Check EEPROM Fail or not
2600 if(priv->card_8192_version > VERSION_8190_BD) {
2601 priv->bTXPowerDataReadFromEEPORM = true;
2603 priv->bTXPowerDataReadFromEEPORM = false;
2606 // 2007/11/15 MH 8190PCI Default=2T4R, 8192PCIE default=1T2R
2607 priv->rf_type = RTL819X_DEFAULT_RF_TYPE;
2609 if(priv->card_8192_version > VERSION_8190_BD)
2611 // Read RF-indication and Tx Power gain index diff of legacy to HT OFDM rate.
2612 if(!priv->AutoloadFailFlag)
2614 tempval = (eprom_read(dev, (EEPROM_RFInd_PowerDiff>>1))) & 0xff;
2615 priv->EEPROMLegacyHTTxPowerDiff = tempval & 0xf; // bit[3:0]
2617 if (tempval&0x80) //RF-indication, bit[7]
2618 priv->rf_type = RF_1T2R;
2620 priv->rf_type = RF_2T4R;
2624 priv->EEPROMLegacyHTTxPowerDiff = EEPROM_Default_LegacyHTTxPowerDiff;
2626 RT_TRACE(COMP_INIT, "EEPROMLegacyHTTxPowerDiff = %d\n",
2627 priv->EEPROMLegacyHTTxPowerDiff);
2629 // Read ThermalMeter from EEPROM
2630 if(!priv->AutoloadFailFlag)
2632 priv->EEPROMThermalMeter = (u8)(((eprom_read(dev, (EEPROM_ThermalMeter>>1))) & 0xff00)>>8);
2636 priv->EEPROMThermalMeter = EEPROM_Default_ThermalMeter;
2638 RT_TRACE(COMP_INIT, "ThermalMeter = %d\n", priv->EEPROMThermalMeter);
2639 //vivi, for tx power track
2640 priv->TSSI_13dBm = priv->EEPROMThermalMeter *100;
2642 if(priv->epromtype == EPROM_93c46)
2644 // Read antenna tx power offset of B/C/D to A and CrystalCap from EEPROM
2645 if(!priv->AutoloadFailFlag)
2647 usValue = eprom_read(dev, (EEPROM_TxPwDiff_CrystalCap>>1));
2648 priv->EEPROMAntPwDiff = (usValue&0x0fff);
2649 priv->EEPROMCrystalCap = (u8)((usValue&0xf000)>>12);
2653 priv->EEPROMAntPwDiff = EEPROM_Default_AntTxPowerDiff;
2654 priv->EEPROMCrystalCap = EEPROM_Default_TxPwDiff_CrystalCap;
2656 RT_TRACE(COMP_INIT, "EEPROMAntPwDiff = %d\n", priv->EEPROMAntPwDiff);
2657 RT_TRACE(COMP_INIT, "EEPROMCrystalCap = %d\n", priv->EEPROMCrystalCap);
2660 // Get per-channel Tx Power Level
2662 for(i=0; i<14; i+=2)
2664 if(!priv->AutoloadFailFlag)
2666 usValue = eprom_read(dev, (u16) ((EEPROM_TxPwIndex_CCK+i)>>1) );
2670 usValue = EEPROM_Default_TxPower;
2672 *((u16*)(&priv->EEPROMTxPowerLevelCCK[i])) = usValue;
2673 RT_TRACE(COMP_INIT,"CCK Tx Power Level, Index %d = 0x%02x\n", i, priv->EEPROMTxPowerLevelCCK[i]);
2674 RT_TRACE(COMP_INIT, "CCK Tx Power Level, Index %d = 0x%02x\n", i+1, priv->EEPROMTxPowerLevelCCK[i+1]);
2676 for(i=0; i<14; i+=2)
2678 if(!priv->AutoloadFailFlag)
2680 usValue = eprom_read(dev, (u16) ((EEPROM_TxPwIndex_OFDM_24G+i)>>1) );
2684 usValue = EEPROM_Default_TxPower;
2686 *((u16*)(&priv->EEPROMTxPowerLevelOFDM24G[i])) = usValue;
2687 RT_TRACE(COMP_INIT, "OFDM 2.4G Tx Power Level, Index %d = 0x%02x\n", i, priv->EEPROMTxPowerLevelOFDM24G[i]);
2688 RT_TRACE(COMP_INIT, "OFDM 2.4G Tx Power Level, Index %d = 0x%02x\n", i+1, priv->EEPROMTxPowerLevelOFDM24G[i+1]);
2691 else if(priv->epromtype== EPROM_93c56)
2694 // Read CrystalCap from EEPROM
2695 if(!priv->AutoloadFailFlag)
2697 priv->EEPROMAntPwDiff = EEPROM_Default_AntTxPowerDiff;
2698 priv->EEPROMCrystalCap = (u8)(((eprom_read(dev, (EEPROM_C56_CrystalCap>>1))) & 0xf000)>>12);
2702 priv->EEPROMAntPwDiff = EEPROM_Default_AntTxPowerDiff;
2703 priv->EEPROMCrystalCap = EEPROM_Default_TxPwDiff_CrystalCap;
2705 RT_TRACE(COMP_INIT,"EEPROMAntPwDiff = %d\n", priv->EEPROMAntPwDiff);
2706 RT_TRACE(COMP_INIT, "EEPROMCrystalCap = %d\n", priv->EEPROMCrystalCap);
2708 // Get Tx Power Level by Channel
2709 if(!priv->AutoloadFailFlag)
2711 // Read Tx power of Channel 1 ~ 14 from EEPROM.
2712 for(i = 0; i < 12; i+=2)
2715 offset = EEPROM_C56_RfA_CCK_Chnl1_TxPwIndex + i;
2717 offset = EEPROM_C56_RfC_CCK_Chnl1_TxPwIndex + i - 6;
2718 usValue = eprom_read(dev, (offset>>1));
2719 *((u16*)(&EepromTxPower[i])) = usValue;
2722 for(i = 0; i < 12; i++)
2725 priv->EEPROMRfACCKChnl1TxPwLevel[i] = EepromTxPower[i];
2726 else if ((i >=3 )&&(i <= 5))
2727 priv->EEPROMRfAOfdmChnlTxPwLevel[i-3] = EepromTxPower[i];
2728 else if ((i >=6 )&&(i <= 8))
2729 priv->EEPROMRfCCCKChnl1TxPwLevel[i-6] = EepromTxPower[i];
2731 priv->EEPROMRfCOfdmChnlTxPwLevel[i-9] = EepromTxPower[i];
2736 priv->EEPROMRfACCKChnl1TxPwLevel[0] = EEPROM_Default_TxPowerLevel;
2737 priv->EEPROMRfACCKChnl1TxPwLevel[1] = EEPROM_Default_TxPowerLevel;
2738 priv->EEPROMRfACCKChnl1TxPwLevel[2] = EEPROM_Default_TxPowerLevel;
2740 priv->EEPROMRfAOfdmChnlTxPwLevel[0] = EEPROM_Default_TxPowerLevel;
2741 priv->EEPROMRfAOfdmChnlTxPwLevel[1] = EEPROM_Default_TxPowerLevel;
2742 priv->EEPROMRfAOfdmChnlTxPwLevel[2] = EEPROM_Default_TxPowerLevel;
2744 priv->EEPROMRfCCCKChnl1TxPwLevel[0] = EEPROM_Default_TxPowerLevel;
2745 priv->EEPROMRfCCCKChnl1TxPwLevel[1] = EEPROM_Default_TxPowerLevel;
2746 priv->EEPROMRfCCCKChnl1TxPwLevel[2] = EEPROM_Default_TxPowerLevel;
2748 priv->EEPROMRfCOfdmChnlTxPwLevel[0] = EEPROM_Default_TxPowerLevel;
2749 priv->EEPROMRfCOfdmChnlTxPwLevel[1] = EEPROM_Default_TxPowerLevel;
2750 priv->EEPROMRfCOfdmChnlTxPwLevel[2] = EEPROM_Default_TxPowerLevel;
2752 RT_TRACE(COMP_INIT, "priv->EEPROMRfACCKChnl1TxPwLevel[0] = 0x%x\n", priv->EEPROMRfACCKChnl1TxPwLevel[0]);
2753 RT_TRACE(COMP_INIT, "priv->EEPROMRfACCKChnl1TxPwLevel[1] = 0x%x\n", priv->EEPROMRfACCKChnl1TxPwLevel[1]);
2754 RT_TRACE(COMP_INIT, "priv->EEPROMRfACCKChnl1TxPwLevel[2] = 0x%x\n", priv->EEPROMRfACCKChnl1TxPwLevel[2]);
2755 RT_TRACE(COMP_INIT, "priv->EEPROMRfAOfdmChnlTxPwLevel[0] = 0x%x\n", priv->EEPROMRfAOfdmChnlTxPwLevel[0]);
2756 RT_TRACE(COMP_INIT, "priv->EEPROMRfAOfdmChnlTxPwLevel[1] = 0x%x\n", priv->EEPROMRfAOfdmChnlTxPwLevel[1]);
2757 RT_TRACE(COMP_INIT, "priv->EEPROMRfAOfdmChnlTxPwLevel[2] = 0x%x\n", priv->EEPROMRfAOfdmChnlTxPwLevel[2]);
2758 RT_TRACE(COMP_INIT, "priv->EEPROMRfCCCKChnl1TxPwLevel[0] = 0x%x\n", priv->EEPROMRfCCCKChnl1TxPwLevel[0]);
2759 RT_TRACE(COMP_INIT, "priv->EEPROMRfCCCKChnl1TxPwLevel[1] = 0x%x\n", priv->EEPROMRfCCCKChnl1TxPwLevel[1]);
2760 RT_TRACE(COMP_INIT, "priv->EEPROMRfCCCKChnl1TxPwLevel[2] = 0x%x\n", priv->EEPROMRfCCCKChnl1TxPwLevel[2]);
2761 RT_TRACE(COMP_INIT, "priv->EEPROMRfCOfdmChnlTxPwLevel[0] = 0x%x\n", priv->EEPROMRfCOfdmChnlTxPwLevel[0]);
2762 RT_TRACE(COMP_INIT, "priv->EEPROMRfCOfdmChnlTxPwLevel[1] = 0x%x\n", priv->EEPROMRfCOfdmChnlTxPwLevel[1]);
2763 RT_TRACE(COMP_INIT, "priv->EEPROMRfCOfdmChnlTxPwLevel[2] = 0x%x\n", priv->EEPROMRfCOfdmChnlTxPwLevel[2]);
2768 // Update HAL variables.
2770 if(priv->epromtype == EPROM_93c46)
2774 priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelCCK[i];
2775 priv->TxPowerLevelOFDM24G[i] = priv->EEPROMTxPowerLevelOFDM24G[i];
2777 priv->LegacyHTTxPowerDiff = priv->EEPROMLegacyHTTxPowerDiff;
2778 // Antenna B gain offset to antenna A, bit0~3
2779 priv->AntennaTxPwDiff[0] = (priv->EEPROMAntPwDiff & 0xf);
2780 // Antenna C gain offset to antenna A, bit4~7
2781 priv->AntennaTxPwDiff[1] = ((priv->EEPROMAntPwDiff & 0xf0)>>4);
2782 // Antenna D gain offset to antenna A, bit8~11
2783 priv->AntennaTxPwDiff[2] = ((priv->EEPROMAntPwDiff & 0xf00)>>8);
2784 // CrystalCap, bit12~15
2785 priv->CrystalCap = priv->EEPROMCrystalCap;
2786 // ThermalMeter, bit0~3 for RFIC1, bit4~7 for RFIC2
2787 priv->ThermalMeter[0] = (priv->EEPROMThermalMeter & 0xf);
2788 priv->ThermalMeter[1] = ((priv->EEPROMThermalMeter & 0xf0)>>4);
2790 else if(priv->epromtype == EPROM_93c56)
2792 //char cck_pwr_diff_a=0, cck_pwr_diff_c=0;
2794 //cck_pwr_diff_a = pHalData->EEPROMRfACCKChnl7TxPwLevel - pHalData->EEPROMRfAOfdmChnlTxPwLevel[1];
2795 //cck_pwr_diff_c = pHalData->EEPROMRfCCCKChnl7TxPwLevel - pHalData->EEPROMRfCOfdmChnlTxPwLevel[1];
2796 for(i=0; i<3; i++) // channel 1~3 use the same Tx Power Level.
2798 priv->TxPowerLevelCCK_A[i] = priv->EEPROMRfACCKChnl1TxPwLevel[0];
2799 priv->TxPowerLevelOFDM24G_A[i] = priv->EEPROMRfAOfdmChnlTxPwLevel[0];
2800 priv->TxPowerLevelCCK_C[i] = priv->EEPROMRfCCCKChnl1TxPwLevel[0];
2801 priv->TxPowerLevelOFDM24G_C[i] = priv->EEPROMRfCOfdmChnlTxPwLevel[0];
2803 for(i=3; i<9; i++) // channel 4~9 use the same Tx Power Level
2805 priv->TxPowerLevelCCK_A[i] = priv->EEPROMRfACCKChnl1TxPwLevel[1];
2806 priv->TxPowerLevelOFDM24G_A[i] = priv->EEPROMRfAOfdmChnlTxPwLevel[1];
2807 priv->TxPowerLevelCCK_C[i] = priv->EEPROMRfCCCKChnl1TxPwLevel[1];
2808 priv->TxPowerLevelOFDM24G_C[i] = priv->EEPROMRfCOfdmChnlTxPwLevel[1];
2810 for(i=9; i<14; i++) // channel 10~14 use the same Tx Power Level
2812 priv->TxPowerLevelCCK_A[i] = priv->EEPROMRfACCKChnl1TxPwLevel[2];
2813 priv->TxPowerLevelOFDM24G_A[i] = priv->EEPROMRfAOfdmChnlTxPwLevel[2];
2814 priv->TxPowerLevelCCK_C[i] = priv->EEPROMRfCCCKChnl1TxPwLevel[2];
2815 priv->TxPowerLevelOFDM24G_C[i] = priv->EEPROMRfCOfdmChnlTxPwLevel[2];
2818 RT_TRACE(COMP_INIT, "priv->TxPowerLevelCCK_A[%d] = 0x%x\n", i, priv->TxPowerLevelCCK_A[i]);
2820 RT_TRACE(COMP_INIT,"priv->TxPowerLevelOFDM24G_A[%d] = 0x%x\n", i, priv->TxPowerLevelOFDM24G_A[i]);
2822 RT_TRACE(COMP_INIT, "priv->TxPowerLevelCCK_C[%d] = 0x%x\n", i, priv->TxPowerLevelCCK_C[i]);
2824 RT_TRACE(COMP_INIT, "priv->TxPowerLevelOFDM24G_C[%d] = 0x%x\n", i, priv->TxPowerLevelOFDM24G_C[i]);
2825 priv->LegacyHTTxPowerDiff = priv->EEPROMLegacyHTTxPowerDiff;
2826 priv->AntennaTxPwDiff[0] = 0;
2827 priv->AntennaTxPwDiff[1] = 0;
2828 priv->AntennaTxPwDiff[2] = 0;
2829 priv->CrystalCap = priv->EEPROMCrystalCap;
2830 // ThermalMeter, bit0~3 for RFIC1, bit4~7 for RFIC2
2831 priv->ThermalMeter[0] = (priv->EEPROMThermalMeter & 0xf);
2832 priv->ThermalMeter[1] = ((priv->EEPROMThermalMeter & 0xf0)>>4);
2836 if(priv->rf_type == RF_1T2R)
2838 RT_TRACE(COMP_INIT, "\n1T2R config\n");
2840 else if (priv->rf_type == RF_2T4R)
2842 RT_TRACE(COMP_INIT, "\n2T4R config\n");
2845 // 2008/01/16 MH We can only know RF type in the function. So we have to init
2846 // DIG RATR table again.
2847 init_rate_adaptive(dev);
2849 //1 Make a copy for following variables and we can change them if we want
2851 priv->rf_chip= RF_8256;
2853 if(priv->RegChannelPlan == 0xf)
2855 priv->ChannelPlan = priv->eeprom_ChannelPlan;
2859 priv->ChannelPlan = priv->RegChannelPlan;
2863 // Used PID and DID to Set CustomerID
2865 if( priv->eeprom_vid == 0x1186 && priv->eeprom_did == 0x3304 )
2867 priv->CustomerID = RT_CID_DLINK;
2870 switch(priv->eeprom_CustomerID)
2872 case EEPROM_CID_DEFAULT:
2873 priv->CustomerID = RT_CID_DEFAULT;
2875 case EEPROM_CID_CAMEO:
2876 priv->CustomerID = RT_CID_819x_CAMEO;
2878 case EEPROM_CID_RUNTOP:
2879 priv->CustomerID = RT_CID_819x_RUNTOP;
2881 case EEPROM_CID_NetCore:
2882 priv->CustomerID = RT_CID_819x_Netcore;
2884 case EEPROM_CID_TOSHIBA: // Merge by Jacken, 2008/01/31
2885 priv->CustomerID = RT_CID_TOSHIBA;
2886 if(priv->eeprom_ChannelPlan&0x80)
2887 priv->ChannelPlan = priv->eeprom_ChannelPlan&0x7f;
2889 priv->ChannelPlan = 0x0;
2890 RT_TRACE(COMP_INIT, "Toshiba ChannelPlan = 0x%x\n",
2893 case EEPROM_CID_Nettronix:
2894 priv->ScanDelay = 100; //cosa add for scan
2895 priv->CustomerID = RT_CID_Nettronix;
2897 case EEPROM_CID_Pronet:
2898 priv->CustomerID = RT_CID_PRONET;
2900 case EEPROM_CID_DLINK:
2901 priv->CustomerID = RT_CID_DLINK;
2904 case EEPROM_CID_WHQL:
2905 //Adapter->bInHctTest = TRUE;//do not supported
2907 //priv->bSupportTurboMode = FALSE;
2908 //priv->bAutoTurboBy8186 = FALSE;
2910 //pMgntInfo->PowerSaveControl.bInactivePs = FALSE;
2911 //pMgntInfo->PowerSaveControl.bIPSModeBackup = FALSE;
2912 //pMgntInfo->PowerSaveControl.bLeisurePs = FALSE;
2916 // value from RegCustomerID
2920 //Avoid the channel plan array overflow, by Bruce, 2007-08-27.
2921 if(priv->ChannelPlan > CHANNEL_PLAN_LEN - 1)
2922 priv->ChannelPlan = 0; //FCC
2924 switch(priv->CustomerID)
2926 case RT_CID_DEFAULT:
2928 priv->LedStrategy = HW_LED;
2931 priv->LedStrategy = SW_LED_MODE1;
2936 case RT_CID_819x_CAMEO:
2937 priv->LedStrategy = SW_LED_MODE2;
2940 case RT_CID_819x_RUNTOP:
2941 priv->LedStrategy = SW_LED_MODE3;
2944 case RT_CID_819x_Netcore:
2945 priv->LedStrategy = SW_LED_MODE4;
2948 case RT_CID_Nettronix:
2949 priv->LedStrategy = SW_LED_MODE5;
2953 priv->LedStrategy = SW_LED_MODE6;
2956 case RT_CID_TOSHIBA: //Modify by Jacken 2008/01/31
2962 priv->LedStrategy = HW_LED;
2965 priv->LedStrategy = SW_LED_MODE1;
2972 if( priv->eeprom_vid == 0x1186 && priv->eeprom_did == 0x3304)
2973 priv->ieee80211->bSupportRemoteWakeUp = true;
2975 priv->ieee80211->bSupportRemoteWakeUp = false;
2978 RT_TRACE(COMP_INIT, "RegChannelPlan(%d)\n", priv->RegChannelPlan);
2979 RT_TRACE(COMP_INIT, "ChannelPlan = %d \n", priv->ChannelPlan);
2980 RT_TRACE(COMP_INIT, "LedStrategy = %d \n", priv->LedStrategy);
2981 RT_TRACE(COMP_TRACE, "<==== ReadAdapterInfo\n");
2987 static short rtl8192_get_channel_map(struct net_device * dev)
2989 struct r8192_priv *priv = ieee80211_priv(dev);
2990 #ifdef ENABLE_DOT11D
2991 if(priv->ChannelPlan> COUNTRY_CODE_GLOBAL_DOMAIN){
2992 printk("rtl8180_init:Error channel plan! Set to default.\n");
2993 priv->ChannelPlan= 0;
2995 RT_TRACE(COMP_INIT, "Channel plan is %d\n",priv->ChannelPlan);
2997 rtl819x_set_channel_map(priv->ChannelPlan, priv);
3000 //Set Default Channel Plan
3002 DMESG("No channels, aborting");
3006 priv->ChannelPlan= 0;//hikaru
3007 // set channels 1..14 allowed in given locale
3008 for (i=1; i<=14; i++) {
3009 (priv->ieee80211->channel_map)[i] = (u8)(ch & 0x01);
3016 static short rtl8192_init(struct net_device *dev)
3018 struct r8192_priv *priv = ieee80211_priv(dev);
3019 memset(&(priv->stats),0,sizeof(struct Stats));
3020 rtl8192_init_priv_variable(dev);
3021 rtl8192_init_priv_lock(priv);
3022 rtl8192_init_priv_task(dev);
3023 rtl8192_get_eeprom_size(dev);
3024 rtl8192_read_eeprom_info(dev);
3025 rtl8192_get_channel_map(dev);
3027 init_timer(&priv->watch_dog_timer);
3028 priv->watch_dog_timer.data = (unsigned long)dev;
3029 priv->watch_dog_timer.function = watch_dog_timer_callback;
3030 #if defined(IRQF_SHARED)
3031 if(request_irq(dev->irq, (void*)rtl8192_interrupt, IRQF_SHARED, dev->name, dev)){
3033 if(request_irq(dev->irq, (void *)rtl8192_interrupt, SA_SHIRQ, dev->name, dev)){
3035 printk("Error allocating IRQ %d",dev->irq);
3039 printk("IRQ %d",dev->irq);
3041 if(rtl8192_pci_initdescring(dev)!=0){
3042 printk("Endopoints initialization failed");
3046 //rtl8192_rx_enable(dev);
3047 //rtl8192_adapter_start(dev);
3052 * Actually only set RRSR, RATR and BW_OPMODE registers
3053 * not to do all the hw config as its name says
3054 * This part need to modified according to the rate set we filtered
3056 static void rtl8192_hwconfig(struct net_device* dev)
3058 u32 regRATR = 0, regRRSR = 0;
3059 u8 regBwOpMode = 0, regTmp = 0;
3060 struct r8192_priv *priv = ieee80211_priv(dev);
3062 // Set RRSR, RATR, and BW_OPMODE registers
3064 switch(priv->ieee80211->mode)
3066 case WIRELESS_MODE_B:
3067 regBwOpMode = BW_OPMODE_20MHZ;
3068 regRATR = RATE_ALL_CCK;
3069 regRRSR = RATE_ALL_CCK;
3071 case WIRELESS_MODE_A:
3072 regBwOpMode = BW_OPMODE_5G |BW_OPMODE_20MHZ;
3073 regRATR = RATE_ALL_OFDM_AG;
3074 regRRSR = RATE_ALL_OFDM_AG;
3076 case WIRELESS_MODE_G:
3077 regBwOpMode = BW_OPMODE_20MHZ;
3078 regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
3079 regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
3081 case WIRELESS_MODE_AUTO:
3082 case WIRELESS_MODE_N_24G:
3083 // It support CCK rate by default.
3084 // CCK rate will be filtered out only when associated AP does not support it.
3085 regBwOpMode = BW_OPMODE_20MHZ;
3086 regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
3087 regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
3089 case WIRELESS_MODE_N_5G:
3090 regBwOpMode = BW_OPMODE_5G;
3091 regRATR = RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
3092 regRRSR = RATE_ALL_OFDM_AG;
3096 write_nic_byte(dev, BW_OPMODE, regBwOpMode);
3099 ratr_value = regRATR;
3100 if (priv->rf_type == RF_1T2R)
3102 ratr_value &= ~(RATE_ALL_OFDM_2SS);
3104 write_nic_dword(dev, RATR0, ratr_value);
3105 write_nic_byte(dev, UFWP, 1);
3107 regTmp = read_nic_byte(dev, 0x313);
3108 regRRSR = ((regTmp) << 24) | (regRRSR & 0x00ffffff);
3109 write_nic_dword(dev, RRSR, regRRSR);
3112 // Set Retry Limit here
3114 write_nic_word(dev, RETRY_LIMIT,
3115 priv->ShortRetryLimit << RETRY_LIMIT_SHORT_SHIFT |
3116 priv->LongRetryLimit << RETRY_LIMIT_LONG_SHIFT);
3117 // Set Contention Window here
3121 // Set Tx Antenna including Feedback control
3123 // Set Auto Rate fallback control
3129 static RT_STATUS rtl8192_adapter_start(struct net_device *dev)
3131 struct r8192_priv *priv = ieee80211_priv(dev);
3132 // struct ieee80211_device *ieee = priv->ieee80211;
3134 RT_STATUS rtStatus = RT_STATUS_SUCCESS;
3138 u8 ICVersion,SwitchingRegulatorOutput;
3140 bool bfirmwareok = true;
3144 u32 tmpRegA, tmpRegC, TempCCk;
3147 RT_TRACE(COMP_INIT, "====>%s()\n", __FUNCTION__);
3148 priv->being_init_adapter = true;
3149 rtl8192_pci_resetdescring(dev);
3150 // 2007/11/02 MH Before initalizing RF. We can not use FW to do RF-R/W.
3151 priv->Rf_Mode = RF_OP_By_SW_3wire;
3154 if(priv->ResetProgress == RESET_TYPE_NORESET)
3156 write_nic_byte(dev, ANAPAR, 0x37);
3157 // Accordign to designer's explain, LBUS active will never > 10ms. We delay 10ms
3158 // Joseph increae the time to prevent firmware download fail
3162 //PlatformSleepUs(10000);
3163 // For any kind of InitializeAdapter process, we shall use system now!!
3164 priv->pFirmware->firmware_status = FW_STATUS_0_INIT;
3166 // Set to eRfoff in order not to count receive count.
3167 if(priv->RegRfOff == TRUE)
3168 priv->ieee80211->eRFPowerState = eRfOff;
3171 //3 //Config CPUReset Register
3173 //3 Firmware Reset Or Not
3174 ulRegRead = read_nic_dword(dev, CPU_GEN);
3175 if(priv->pFirmware->firmware_status == FW_STATUS_0_INIT)
3176 { //called from MPInitialized. do nothing
3177 ulRegRead |= CPU_GEN_SYSTEM_RESET;
3178 }else if(priv->pFirmware->firmware_status == FW_STATUS_5_READY)
3179 ulRegRead |= CPU_GEN_FIRMWARE_RESET; // Called from MPReset
3181 RT_TRACE(COMP_ERR, "ERROR in %s(): undefined firmware state(%d)\n", __FUNCTION__, priv->pFirmware->firmware_status);
3184 //2008.06.03, for WOL 90 hw bug
3185 ulRegRead &= (~(CPU_GEN_GPIO_UART));
3188 write_nic_dword(dev, CPU_GEN, ulRegRead);
3194 //3 //Fix the issue of E-cut high temperature issue
3197 ICVersion = read_nic_byte(dev, IC_VERRSION);
3198 if(ICVersion >= 0x4) //E-cut only
3200 // HW SD suggest that we should not wirte this register too often, so driver
3201 // should readback this register. This register will be modified only when
3203 SwitchingRegulatorOutput = read_nic_byte(dev, SWREGULATOR);
3204 if(SwitchingRegulatorOutput != 0xb8)
3206 write_nic_byte(dev, SWREGULATOR, 0xa8);
3208 write_nic_byte(dev, SWREGULATOR, 0xb8);
3215 //3// Initialize BB before MAC
3217 RT_TRACE(COMP_INIT, "BB Config Start!\n");
3218 rtStatus = rtl8192_BBConfig(dev);
3219 if(rtStatus != RT_STATUS_SUCCESS)
3221 RT_TRACE(COMP_ERR, "BB Config failed\n");
3224 RT_TRACE(COMP_INIT,"BB Config Finished!\n");
3226 //3//Set Loopback mode or Normal mode
3228 //2006.12.13 by emily. Note!We should not merge these two CPU_GEN register writings
3229 // because setting of System_Reset bit reset MAC to default transmission mode.
3230 //Loopback mode or not
3231 priv->LoopbackMode = RTL819X_NO_LOOPBACK;
3232 //priv->LoopbackMode = RTL819X_MAC_LOOPBACK;
3233 if(priv->ResetProgress == RESET_TYPE_NORESET)
3235 ulRegRead = read_nic_dword(dev, CPU_GEN);
3236 if(priv->LoopbackMode == RTL819X_NO_LOOPBACK)
3238 ulRegRead = ((ulRegRead & CPU_GEN_NO_LOOPBACK_MSK) | CPU_GEN_NO_LOOPBACK_SET);
3240 else if (priv->LoopbackMode == RTL819X_MAC_LOOPBACK )
3242 ulRegRead |= CPU_CCK_LOOPBACK;
3246 RT_TRACE(COMP_ERR,"Serious error: wrong loopback mode setting\n");
3249 //2008.06.03, for WOL
3250 //ulRegRead &= (~(CPU_GEN_GPIO_UART));
3251 write_nic_dword(dev, CPU_GEN, ulRegRead);
3253 // 2006.11.29. After reset cpu, we sholud wait for a second, otherwise, it may fail to write registers. Emily
3256 //3Set Hardware(Do nothing now)
3257 rtl8192_hwconfig(dev);
3258 //2=======================================================
3259 // Common Setting for all of the FPGA platform. (part 1)
3260 //2=======================================================
3261 // If there is changes, please make sure it applies to all of the FPGA version
3263 write_nic_byte(dev, CMDR, CR_RE|CR_TE);
3267 write_nic_byte(dev, PCIF, ((MXDMA2_NoLimit<<MXDMA2_RX_SHIFT) |
3268 (MXDMA2_NoLimit<<MXDMA2_TX_SHIFT) |
3272 write_nic_byte(dev, PCIF, ((MXDMA2_NoLimit<<MXDMA2_RX_SHIFT) |
3273 (MXDMA2_NoLimit<<MXDMA2_TX_SHIFT) ));
3277 write_nic_dword(dev, MAC0, ((u32*)dev->dev_addr)[0]);
3278 write_nic_word(dev, MAC4, ((u16*)(dev->dev_addr + 4))[0]);
3280 write_nic_dword(dev, RCR, priv->ReceiveConfig);
3282 //3 Initialize Number of Reserved Pages in Firmware Queue
3284 if(priv->bInHctTest)
3286 PlatformEFIOWrite4Byte(Adapter, RQPN1, NUM_OF_PAGE_IN_FW_QUEUE_BK_DTM << RSVD_FW_QUEUE_PAGE_BK_SHIFT |
3287 NUM_OF_PAGE_IN_FW_QUEUE_BE_DTM << RSVD_FW_QUEUE_PAGE_BE_SHIFT |
3288 NUM_OF_PAGE_IN_FW_QUEUE_VI_DTM << RSVD_FW_QUEUE_PAGE_VI_SHIFT |
3289 NUM_OF_PAGE_IN_FW_QUEUE_VO_DTM <<RSVD_FW_QUEUE_PAGE_VO_SHIFT);
3290 PlatformEFIOWrite4Byte(Adapter, RQPN2, NUM_OF_PAGE_IN_FW_QUEUE_MGNT << RSVD_FW_QUEUE_PAGE_MGNT_SHIFT);
3291 PlatformEFIOWrite4Byte(Adapter, RQPN3, APPLIED_RESERVED_QUEUE_IN_FW|
3292 NUM_OF_PAGE_IN_FW_QUEUE_BCN<<RSVD_FW_QUEUE_PAGE_BCN_SHIFT|
3293 NUM_OF_PAGE_IN_FW_QUEUE_PUB_DTM<<RSVD_FW_QUEUE_PAGE_PUB_SHIFT);
3298 write_nic_dword(dev, RQPN1, NUM_OF_PAGE_IN_FW_QUEUE_BK << RSVD_FW_QUEUE_PAGE_BK_SHIFT |
3299 NUM_OF_PAGE_IN_FW_QUEUE_BE << RSVD_FW_QUEUE_PAGE_BE_SHIFT |
3300 NUM_OF_PAGE_IN_FW_QUEUE_VI << RSVD_FW_QUEUE_PAGE_VI_SHIFT |
3301 NUM_OF_PAGE_IN_FW_QUEUE_VO <<RSVD_FW_QUEUE_PAGE_VO_SHIFT);
3302 write_nic_dword(dev, RQPN2, NUM_OF_PAGE_IN_FW_QUEUE_MGNT << RSVD_FW_QUEUE_PAGE_MGNT_SHIFT);
3303 write_nic_dword(dev, RQPN3, APPLIED_RESERVED_QUEUE_IN_FW|
3304 NUM_OF_PAGE_IN_FW_QUEUE_BCN<<RSVD_FW_QUEUE_PAGE_BCN_SHIFT|
3305 NUM_OF_PAGE_IN_FW_QUEUE_PUB<<RSVD_FW_QUEUE_PAGE_PUB_SHIFT);
3308 rtl8192_tx_enable(dev);
3309 rtl8192_rx_enable(dev);
3310 //3Set Response Rate Setting Register
3311 // CCK rate is supported by default.
3312 // CCK rate will be filtered out only when associated AP does not support it.
3313 ulRegRead = (0xFFF00000 & read_nic_dword(dev, RRSR)) | RATE_ALL_OFDM_AG | RATE_ALL_CCK;
3314 write_nic_dword(dev, RRSR, ulRegRead);
3315 write_nic_dword(dev, RATR0+4*7, (RATE_ALL_OFDM_AG | RATE_ALL_CCK));
3318 // TODO: (it value is only for FPGA version). need to be changed!!2006.12.18, by Emily
3319 write_nic_byte(dev, ACK_TIMEOUT, 0x30);
3321 //rtl8192_actset_wirelessmode(dev,priv->RegWirelessMode);
3322 if(priv->ResetProgress == RESET_TYPE_NORESET)
3323 rtl8192_SetWirelessMode(dev, priv->ieee80211->mode);
3324 //-----------------------------------------------------------------------------
3325 // Set up security related. 070106, by rcnjko:
3326 // 1. Clear all H/W keys.
3327 // 2. Enable H/W encryption/decryption.
3328 //-----------------------------------------------------------------------------
3329 CamResetAllEntry(dev);
3331 u8 SECR_value = 0x0;
3332 SECR_value |= SCR_TxEncEnable;
3333 SECR_value |= SCR_RxDecEnable;
3334 SECR_value |= SCR_NoSKMC;
3335 write_nic_byte(dev, SECR, SECR_value);
3338 write_nic_word(dev, ATIMWND, 2);
3339 write_nic_word(dev, BCN_INTERVAL, 100);
3340 for (i=0; i<QOS_QUEUE_NUM; i++)
3341 write_nic_dword(dev, WDCAPARA_ADD[i], 0x005e4332);
3343 // Switching regulator controller: This is set temporarily.
3344 // It's not sure if this can be removed in the future.
3345 // PJ advised to leave it by default.
3347 write_nic_byte(dev, 0xbe, 0xc0);
3349 //2=======================================================
3350 // Set PHY related configuration defined in MAC register bank
3351 //2=======================================================
3352 rtl8192_phy_configmac(dev);
3354 if (priv->card_8192_version > (u8) VERSION_8190_BD) {
3355 rtl8192_phy_getTxPower(dev);
3356 rtl8192_phy_setTxPower(dev, priv->chan);
3360 tmpvalue = read_nic_byte(dev, IC_VERRSION);
3361 priv->IC_Cut = tmpvalue;
3362 RT_TRACE(COMP_INIT, "priv->IC_Cut = 0x%x\n", priv->IC_Cut);
3363 if(priv->IC_Cut >= IC_VersionCut_D)
3365 //pHalData->bDcut = TRUE;
3366 if(priv->IC_Cut == IC_VersionCut_D)
3367 RT_TRACE(COMP_INIT, "D-cut\n");
3368 if(priv->IC_Cut == IC_VersionCut_E)
3370 RT_TRACE(COMP_INIT, "E-cut\n");
3371 // HW SD suggest that we should not wirte this register too often, so driver
3372 // should readback this register. This register will be modified only when
3378 //pHalData->bDcut = FALSE;
3379 RT_TRACE(COMP_INIT, "Before C-cut\n");
3384 RT_TRACE(COMP_INIT, "Load Firmware!\n");
3385 bfirmwareok = init_firmware(dev);
3386 if(bfirmwareok != true) {
3387 rtStatus = RT_STATUS_FAILURE;
3390 RT_TRACE(COMP_INIT, "Load Firmware finished!\n");
3393 if(priv->ResetProgress == RESET_TYPE_NORESET)
3395 RT_TRACE(COMP_INIT, "RF Config Started!\n");
3396 rtStatus = rtl8192_phy_RFConfig(dev);
3397 if(rtStatus != RT_STATUS_SUCCESS)
3399 RT_TRACE(COMP_ERR, "RF Config failed\n");
3402 RT_TRACE(COMP_INIT, "RF Config Finished!\n");
3404 rtl8192_phy_updateInitGain(dev);
3406 /*---- Set CCK and OFDM Block "ON"----*/
3407 rtl8192_setBBreg(dev, rFPGA0_RFMOD, bCCKEn, 0x1);
3408 rtl8192_setBBreg(dev, rFPGA0_RFMOD, bOFDMEn, 0x1);
3412 write_nic_byte(dev, 0x87, 0x0);
3415 //2008.06.03, for WOL
3416 ucRegRead = read_nic_byte(dev, GPE);
3418 write_nic_byte(dev, GPE, ucRegRead);
3420 ucRegRead = read_nic_byte(dev, GPO);
3422 write_nic_byte(dev, GPO, ucRegRead);
3425 //2=======================================================
3427 //2=======================================================
3431 if(priv->RegRfOff == TRUE)
3432 { // User disable RF via registry.
3433 RT_TRACE((COMP_INIT|COMP_RF|COMP_POWER), "%s(): Turn off RF for RegRfOff ----------\n",__FUNCTION__);
3434 MgntActSet_RF_State(dev, eRfOff, RF_CHANGE_BY_SW);
3435 #if 0//cosa, ask SD3 willis and he doesn't know what is this for
3436 // Those action will be discard in MgntActSet_RF_State because off the same state
3437 for(eRFPath = 0; eRFPath <pHalData->NumTotalRFPath; eRFPath++)
3438 PHY_SetRFReg(Adapter, (RF90_RADIO_PATH_E)eRFPath, 0x4, 0xC00, 0x0);
3441 else if(priv->ieee80211->RfOffReason > RF_CHANGE_BY_PS)
3442 { // H/W or S/W RF OFF before sleep.
3443 RT_TRACE((COMP_INIT|COMP_RF|COMP_POWER), "%s(): Turn off RF for RfOffReason(%d) ----------\n", __FUNCTION__,priv->ieee80211->RfOffReason);
3444 MgntActSet_RF_State(dev, eRfOff, priv->ieee80211->RfOffReason);
3446 else if(priv->ieee80211->RfOffReason >= RF_CHANGE_BY_IPS)
3447 { // H/W or S/W RF OFF before sleep.
3448 RT_TRACE((COMP_INIT|COMP_RF|COMP_POWER), "%s(): Turn off RF for RfOffReason(%d) ----------\n", __FUNCTION__,priv->ieee80211->RfOffReason);
3449 MgntActSet_RF_State(dev, eRfOff, priv->ieee80211->RfOffReason);
3453 RT_TRACE((COMP_INIT|COMP_RF|COMP_POWER), "%s(): RF-ON \n",__FUNCTION__);
3454 priv->ieee80211->eRFPowerState = eRfOn;
3455 priv->ieee80211->RfOffReason = 0;
3456 //DrvIFIndicateCurrentPhyStatus(Adapter);
3458 //Adapter->HalFunc.LedControlHandler(Adapter, LED_CTL_POWER_ON);
3461 // If inactive power mode is enabled, disable rf while in disconnected state.
3462 // But we should still tell upper layer we are in rf on state.
3463 // 2007.07.16, by shien chang.
3465 //if(!Adapter->bInHctTest)
3466 //IPSEnter(Adapter);
3473 // We can force firmware to do RF-R/W
3474 if(priv->ieee80211->FwRWRF)
3475 priv->Rf_Mode = RF_OP_By_FW;
3477 priv->Rf_Mode = RF_OP_By_SW_3wire;
3479 priv->Rf_Mode = RF_OP_By_SW_3wire;
3483 if(priv->ResetProgress == RESET_TYPE_NORESET)
3485 dm_initialize_txpower_tracking(dev);
3487 tmpRegA= rtl8192_QueryBBReg(dev,rOFDM0_XATxIQImbalance,bMaskDWord);
3488 tmpRegC= rtl8192_QueryBBReg(dev,rOFDM0_XCTxIQImbalance,bMaskDWord);
3490 if(priv->rf_type == RF_2T4R){
3491 for(i = 0; i<TxBBGainTableLength; i++)
3493 if(tmpRegA == priv->txbbgain_table[i].txbbgain_value)
3495 priv->rfa_txpowertrackingindex= (u8)i;
3496 priv->rfa_txpowertrackingindex_real= (u8)i;
3497 priv->rfa_txpowertracking_default = priv->rfa_txpowertrackingindex;
3502 for(i = 0; i<TxBBGainTableLength; i++)
3504 if(tmpRegC == priv->txbbgain_table[i].txbbgain_value)
3506 priv->rfc_txpowertrackingindex= (u8)i;
3507 priv->rfc_txpowertrackingindex_real= (u8)i;
3508 priv->rfc_txpowertracking_default = priv->rfc_txpowertrackingindex;
3512 TempCCk = rtl8192_QueryBBReg(dev, rCCK0_TxFilter1, bMaskByte2);
3514 for(i=0 ; i<CCKTxBBGainTableLength ; i++)
3516 if(TempCCk == priv->cck_txbbgain_table[i].ccktxbb_valuearray[0])
3518 priv->CCKPresentAttentuation_20Mdefault =(u8) i;
3522 priv->CCKPresentAttentuation_40Mdefault = 0;
3523 priv->CCKPresentAttentuation_difference = 0;
3524 priv->CCKPresentAttentuation = priv->CCKPresentAttentuation_20Mdefault;
3525 RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex_initial = %d\n", priv->rfa_txpowertrackingindex);
3526 RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex_real__initial = %d\n", priv->rfa_txpowertrackingindex_real);
3527 RT_TRACE(COMP_POWER_TRACKING, "priv->rfc_txpowertrackingindex_initial = %d\n", priv->rfc_txpowertrackingindex);
3528 RT_TRACE(COMP_POWER_TRACKING, "priv->rfc_txpowertrackingindex_real_initial = %d\n", priv->rfc_txpowertrackingindex_real);
3529 RT_TRACE(COMP_POWER_TRACKING, "priv->CCKPresentAttentuation_difference_initial = %d\n", priv->CCKPresentAttentuation_difference);
3530 RT_TRACE(COMP_POWER_TRACKING, "priv->CCKPresentAttentuation_initial = %d\n", priv->CCKPresentAttentuation);
3534 if(priv->ResetProgress == RESET_TYPE_NORESET)
3536 dm_initialize_txpower_tracking(dev);
3538 if(priv->IC_Cut >= IC_VersionCut_D)
3540 tmpRegA= rtl8192_QueryBBReg(dev,rOFDM0_XATxIQImbalance,bMaskDWord);
3541 tmpRegC= rtl8192_QueryBBReg(dev,rOFDM0_XCTxIQImbalance,bMaskDWord);
3542 for(i = 0; i<TxBBGainTableLength; i++)
3544 if(tmpRegA == priv->txbbgain_table[i].txbbgain_value)
3546 priv->rfa_txpowertrackingindex= (u8)i;
3547 priv->rfa_txpowertrackingindex_real= (u8)i;
3548 priv->rfa_txpowertracking_default = priv->rfa_txpowertrackingindex;
3553 TempCCk = rtl8192_QueryBBReg(dev, rCCK0_TxFilter1, bMaskByte2);
3555 for(i=0 ; i<CCKTxBBGainTableLength ; i++)
3557 if(TempCCk == priv->cck_txbbgain_table[i].ccktxbb_valuearray[0])
3559 priv->CCKPresentAttentuation_20Mdefault =(u8) i;
3563 priv->CCKPresentAttentuation_40Mdefault = 0;
3564 priv->CCKPresentAttentuation_difference = 0;
3565 priv->CCKPresentAttentuation = priv->CCKPresentAttentuation_20Mdefault;
3566 RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex_initial = %d\n", priv->rfa_txpowertrackingindex);
3567 RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex_real__initial = %d\n", priv->rfa_txpowertrackingindex_real);
3568 RT_TRACE(COMP_POWER_TRACKING, "priv->CCKPresentAttentuation_difference_initial = %d\n", priv->CCKPresentAttentuation_difference);
3569 RT_TRACE(COMP_POWER_TRACKING, "priv->CCKPresentAttentuation_initial = %d\n", priv->CCKPresentAttentuation);
3570 priv->btxpower_tracking = FALSE;//TEMPLY DISABLE
3575 rtl8192_irq_enable(dev);
3576 priv->being_init_adapter = false;
3581 static void rtl8192_prepare_beacon(struct r8192_priv *priv)
3583 struct sk_buff *skb;
3584 //unsigned long flags;
3587 skb = ieee80211_get_beacon(priv->ieee80211);
3588 tcb_desc = (cb_desc *)(skb->cb + 8);
3589 //spin_lock_irqsave(&priv->tx_lock,flags);
3590 /* prepare misc info for the beacon xmit */
3591 tcb_desc->queue_index = BEACON_QUEUE;
3592 /* IBSS does not support HT yet, use 1M defaultly */
3593 tcb_desc->data_rate = 2;
3594 tcb_desc->RATRIndex = 7;
3595 tcb_desc->bTxDisableRateFallBack = 1;
3596 tcb_desc->bTxUseDriverAssingedRate = 1;
3598 skb_push(skb, priv->ieee80211->tx_headroom);
3600 rtl8192_tx(priv->ieee80211->dev,skb);
3602 //spin_unlock_irqrestore (&priv->tx_lock, flags);
3607 * configure registers for beacon tx and enables it via
3608 * rtl8192_beacon_tx_enable(). rtl8192_beacon_tx_disable() might
3609 * be used to stop beacon transmission
3611 static void rtl8192_start_beacon(struct net_device *dev)
3613 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
3614 struct ieee80211_network *net = &priv->ieee80211->current_network;
3619 DMESG("Enabling beacon TX");
3620 //rtl8192_prepare_beacon(dev);
3621 rtl8192_irq_disable(dev);
3622 //rtl8192_beacon_tx_enable(dev);
3625 write_nic_word(dev, ATIMWND, 2);
3627 /* Beacon interval (in unit of TU) */
3628 write_nic_word(dev, BCN_INTERVAL, net->beacon_interval);
3631 * DrvErlyInt (in unit of TU).
3632 * (Time to send interrupt to notify driver to c
3633 * hange beacon content)
3635 write_nic_word(dev, BCN_DRV_EARLY_INT, 10);
3638 * BcnDMATIM(in unit of us).
3639 * Indicates the time before TBTT to perform beacon queue DMA
3641 write_nic_word(dev, BCN_DMATIME, 256);
3644 * Force beacon frame transmission even after receiving
3645 * beacon frame from other ad hoc STA
3647 write_nic_byte(dev, BCN_ERR_THRESH, 100);
3649 /* Set CW and IFS */
3650 BcnTimeCfg |= BcnCW<<BCN_TCFG_CW_SHIFT;
3651 BcnTimeCfg |= BcnIFS<<BCN_TCFG_IFS;
3652 write_nic_word(dev, BCN_TCFG, BcnTimeCfg);
3655 /* enable the interrupt for ad-hoc process */
3656 rtl8192_irq_enable(dev);
3659 static bool HalTxCheckStuck8190Pci(struct net_device *dev)
3661 u16 RegTxCounter = read_nic_word(dev, 0x128);
3662 struct r8192_priv *priv = ieee80211_priv(dev);
3663 bool bStuck = FALSE;
3664 RT_TRACE(COMP_RESET,"%s():RegTxCounter is %d,TxCounter is %d\n",__FUNCTION__,RegTxCounter,priv->TxCounter);
3665 if(priv->TxCounter==RegTxCounter)
3668 priv->TxCounter = RegTxCounter;
3674 * Assumption: RT_TX_SPINLOCK is acquired.
3677 TxCheckStuck(struct net_device *dev)
3679 struct r8192_priv *priv = ieee80211_priv(dev);
3681 ptx_ring head=NULL,tail=NULL,txring = NULL;
3682 u8 ResetThreshold = NIC_SEND_HANG_THRESHOLD_POWERSAVE;
3683 bool bCheckFwTxCnt = false;
3686 // Decide Stuch threshold according to current power save mode
3688 switch (priv->ieee80211->dot11PowerSaveMode)
3690 // The threshold value may required to be adjusted .
3691 case eActive: // Active/Continuous access.
3692 ResetThreshold = NIC_SEND_HANG_THRESHOLD_NORMAL;
3694 case eMaxPs: // Max power save mode.
3695 ResetThreshold = NIC_SEND_HANG_THRESHOLD_POWERSAVE;
3697 case eFastPs: // Fast power save mode.
3698 ResetThreshold = NIC_SEND_HANG_THRESHOLD_POWERSAVE;
3703 // Check whether specific tcb has been queued for a specific time
3705 for(QueueID = 0; QueueID < MAX_TX_QUEUE; QueueID++)
3709 if(QueueID == TXCMD_QUEUE)
3714 tail=priv->txmapringtail;
3715 head=priv->txmapringhead;
3719 tail=priv->txbkpringtail;
3720 head=priv->txbkpringhead;
3724 tail=priv->txbepringtail;
3725 head=priv->txbepringhead;
3729 tail=priv->txvipringtail;
3730 head=priv->txvipringhead;
3734 tail=priv->txvopringtail;
3735 head=priv->txvopringhead;
3750 RT_TRACE(COMP_ERR,"%s():txring is NULL , BUG!\n",__FUNCTION__);
3753 txring->nStuckCount++;
3754 bCheckFwTxCnt = TRUE;
3760 if(HalTxCheckStuck8190Pci(dev))
3762 RT_TRACE(COMP_RESET, "TxCheckStuck(): Fw indicates no Tx condition! \n");
3763 return RESET_TYPE_SILENT;
3767 return RESET_TYPE_NORESET;
3771 static bool HalRxCheckStuck8190Pci(struct net_device *dev)
3773 struct r8192_priv *priv = ieee80211_priv(dev);
3774 u16 RegRxCounter = read_nic_word(dev, 0x130);
3775 bool bStuck = FALSE;
3776 static u8 rx_chk_cnt = 0;
3777 RT_TRACE(COMP_RESET,"%s(): RegRxCounter is %d,RxCounter is %d\n",__FUNCTION__,RegRxCounter,priv->RxCounter);
3778 // If rssi is small, we should check rx for long time because of bad rx.
3779 // or maybe it will continuous silent reset every 2 seconds.
3781 if(priv->undecorated_smoothed_pwdb >= (RateAdaptiveTH_High+5))
3783 rx_chk_cnt = 0; //high rssi, check rx stuck right now.
3785 else if(priv->undecorated_smoothed_pwdb < (RateAdaptiveTH_High+5) &&
3786 ((priv->CurrentChannelBW!=HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb>=RateAdaptiveTH_Low_40M) ||
3787 (priv->CurrentChannelBW==HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb>=RateAdaptiveTH_Low_20M)) )
3799 else if(((priv->CurrentChannelBW!=HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb<RateAdaptiveTH_Low_40M) ||
3800 (priv->CurrentChannelBW==HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb<RateAdaptiveTH_Low_20M)) &&
3801 priv->undecorated_smoothed_pwdb >= VeryLowRSSI)
3805 //DbgPrint("RSSI < %d && RSSI >= %d, no check this time \n", RateAdaptiveTH_Low, VeryLowRSSI);
3811 //DbgPrint("RSSI < %d && RSSI >= %d, check this time \n", RateAdaptiveTH_Low, VeryLowRSSI);
3818 //DbgPrint("RSSI <= %d, no check this time \n", VeryLowRSSI);
3824 //DbgPrint("RSSI <= %d, check this time \n", VeryLowRSSI);
3827 if(priv->RxCounter==RegRxCounter)
3830 priv->RxCounter = RegRxCounter;
3835 static RESET_TYPE RxCheckStuck(struct net_device *dev)
3838 if(HalRxCheckStuck8190Pci(dev))
3840 RT_TRACE(COMP_RESET, "RxStuck Condition\n");
3841 return RESET_TYPE_SILENT;
3844 return RESET_TYPE_NORESET;
3848 rtl819x_ifcheck_resetornot(struct net_device *dev)
3850 struct r8192_priv *priv = ieee80211_priv(dev);
3851 RESET_TYPE TxResetType = RESET_TYPE_NORESET;
3852 RESET_TYPE RxResetType = RESET_TYPE_NORESET;
3853 RT_RF_POWER_STATE rfState;
3855 rfState = priv->ieee80211->eRFPowerState;
3857 TxResetType = TxCheckStuck(dev);
3859 if( rfState != eRfOff &&
3860 /*ADAPTER_TEST_STATUS_FLAG(Adapter, ADAPTER_STATUS_FW_DOWNLOAD_FAILURE)) &&*/
3861 (priv->ieee80211->iw_mode != IW_MODE_ADHOC))
3863 // If driver is in the status of firmware download failure , driver skips RF initialization and RF is
3864 // in turned off state. Driver should check whether Rx stuck and do silent reset. And
3865 // if driver is in firmware download failure status, driver should initialize RF in the following
3866 // silent reset procedure Emily, 2008.01.21
3868 // Driver should not check RX stuck in IBSS mode because it is required to
3869 // set Check BSSID in order to send beacon, however, if check BSSID is
3870 // set, STA cannot hear any packet a all. Emily, 2008.04.12
3871 RxResetType = RxCheckStuck(dev);
3875 RT_TRACE(COMP_RESET,"%s(): TxResetType is %d, RxResetType is %d\n",__FUNCTION__,TxResetType,RxResetType);
3876 if(TxResetType==RESET_TYPE_NORMAL || RxResetType==RESET_TYPE_NORMAL)
3877 return RESET_TYPE_NORMAL;
3878 else if(TxResetType==RESET_TYPE_SILENT || RxResetType==RESET_TYPE_SILENT)
3879 return RESET_TYPE_SILENT;
3881 return RESET_TYPE_NORESET;
3886 static void CamRestoreAllEntry(struct net_device *dev)
3889 struct r8192_priv *priv = ieee80211_priv(dev);
3890 const u8* MacAddr = priv->ieee80211->current_network.bssid;
3892 static const u8 CAM_CONST_ADDR[4][6] = {
3893 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
3894 {0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
3895 {0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
3896 {0x00, 0x00, 0x00, 0x00, 0x00, 0x03}};
3897 static const u8 CAM_CONST_BROAD[] =
3898 {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
3900 RT_TRACE(COMP_SEC, "CamRestoreAllEntry: \n");
3903 if ((priv->ieee80211->pairwise_key_type == KEY_TYPE_WEP40)||
3904 (priv->ieee80211->pairwise_key_type == KEY_TYPE_WEP104))
3907 for(EntryId=0; EntryId<4; EntryId++)
3910 MacAddr = CAM_CONST_ADDR[EntryId];
3914 priv->ieee80211->pairwise_key_type,
3922 else if(priv->ieee80211->pairwise_key_type == KEY_TYPE_TKIP)
3926 if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
3930 priv->ieee80211->pairwise_key_type,
3938 priv->ieee80211->pairwise_key_type,
3944 else if(priv->ieee80211->pairwise_key_type == KEY_TYPE_CCMP)
3948 if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
3952 priv->ieee80211->pairwise_key_type,
3960 priv->ieee80211->pairwise_key_type,
3969 if(priv->ieee80211->group_key_type == KEY_TYPE_TKIP)
3971 MacAddr = CAM_CONST_BROAD;
3972 for(EntryId=1 ; EntryId<4 ; EntryId++)
3978 priv->ieee80211->group_key_type,
3984 if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
3988 priv->ieee80211->group_key_type,
3993 else if(priv->ieee80211->group_key_type == KEY_TYPE_CCMP)
3995 MacAddr = CAM_CONST_BROAD;
3996 for(EntryId=1; EntryId<4 ; EntryId++)
4002 priv->ieee80211->group_key_type,
4009 if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
4013 priv->ieee80211->group_key_type,
4021 * This function is used to fix Tx/Rx stop bug temporarily.
4022 * This function will do "system reset" to NIC when Tx or Rx is stuck.
4023 * The method checking Tx/Rx stuck of this function is supported by FW,
4024 * which reports Tx and Rx counter to register 0x128 and 0x130.
4026 static void rtl819x_ifsilentreset(struct net_device *dev)
4028 struct r8192_priv *priv = ieee80211_priv(dev);
4030 int reset_status = 0;
4031 struct ieee80211_device *ieee = priv->ieee80211;
4036 // 2007.07.20. If we need to check CCK stop, please uncomment this line.
4037 //bStuck = Adapter->HalFunc.CheckHWStopHandler(Adapter);
4039 if(priv->ResetProgress==RESET_TYPE_NORESET)
4043 //LZM for PS-Poll AID issue. 090429
4044 if(priv->ieee80211->state == IEEE80211_LINKED)
4045 LeisurePSLeave(dev);
4048 RT_TRACE(COMP_RESET,"=========>Reset progress!! \n");
4050 // Set the variable for reset.
4051 priv->ResetProgress = RESET_TYPE_SILENT;
4052 // rtl8192_close(dev);
4054 down(&priv->wx_sem);
4057 RT_TRACE(COMP_ERR,"%s():the driver is not up! return\n",__FUNCTION__);
4062 RT_TRACE(COMP_RESET,"%s():======>start to down the driver\n",__FUNCTION__);
4063 if(!netif_queue_stopped(dev))
4064 netif_stop_queue(dev);
4066 dm_backup_dynamic_mechanism_state(dev);
4068 rtl8192_irq_disable(dev);
4069 rtl8192_cancel_deferred_work(priv);
4071 del_timer_sync(&priv->watch_dog_timer);
4072 ieee->sync_scan_hurryup = 1;
4073 if(ieee->state == IEEE80211_LINKED)
4075 down(&ieee->wx_sem);
4076 printk("ieee->state is IEEE80211_LINKED\n");
4077 ieee80211_stop_send_beacons(priv->ieee80211);
4078 del_timer_sync(&ieee->associate_timer);
4079 cancel_delayed_work(&ieee->associate_retry_wq);
4080 ieee80211_stop_scan(ieee);
4084 printk("ieee->state is NOT LINKED\n");
4085 ieee80211_softmac_stop_protocol(priv->ieee80211,true);
4087 rtl8192_halt_adapter(dev, true);
4089 RT_TRACE(COMP_RESET,"%s():<==========down process is finished\n",__FUNCTION__);
4090 RT_TRACE(COMP_RESET,"%s():===========>start to up the driver\n",__FUNCTION__);
4091 reset_status = _rtl8192_up(dev);
4093 RT_TRACE(COMP_RESET,"%s():<===========up process is finished\n",__FUNCTION__);
4094 if(reset_status == -1)
4103 RT_TRACE(COMP_ERR," ERR!!! %s(): Reset Failed!!\n",__FUNCTION__);
4107 ieee->is_silent_reset = 1;
4109 EnableHWSecurityConfig8192(dev);
4111 if(ieee->state == IEEE80211_LINKED && ieee->iw_mode == IW_MODE_INFRA)
4113 ieee->set_chan(ieee->dev, ieee->current_network.channel);
4116 queue_work(ieee->wq, &ieee->associate_complete_wq);
4120 else if(ieee->state == IEEE80211_LINKED && ieee->iw_mode == IW_MODE_ADHOC)
4122 ieee->set_chan(ieee->dev, ieee->current_network.channel);
4123 ieee->link_change(ieee->dev);
4125 // notify_wx_assoc_event(ieee);
4127 ieee80211_start_send_beacons(ieee);
4129 if (ieee->data_hard_resume)
4130 ieee->data_hard_resume(ieee->dev);
4131 netif_carrier_on(ieee->dev);
4135 CamRestoreAllEntry(dev);
4137 // Restore the previous setting for all dynamic mechanism
4138 dm_restore_dynamic_mechanism_state(dev);
4140 priv->ResetProgress = RESET_TYPE_NORESET;
4141 priv->reset_count++;
4143 priv->bForcedSilentReset =false;
4144 priv->bResetInProgress = false;
4146 // For test --> force write UFWP.
4147 write_nic_byte(dev, UFWP, 1);
4148 RT_TRACE(COMP_RESET, "Reset finished!! ====>[%d]\n", priv->reset_count);
4154 void InactivePsWorkItemCallback(struct net_device *dev)
4156 struct r8192_priv *priv = ieee80211_priv(dev);
4157 PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->ieee80211->PowerSaveControl));
4159 RT_TRACE(COMP_POWER, "InactivePsWorkItemCallback() ---------> \n");
4161 // This flag "bSwRfProcessing", indicates the status of IPS procedure, should be set if the IPS workitem
4162 // is really scheduled.
4163 // The old code, sets this flag before scheduling the IPS workitem and however, at the same time the
4164 // previous IPS workitem did not end yet, fails to schedule the current workitem. Thus, bSwRfProcessing
4165 // blocks the IPS procedure of switching RF.
4166 // By Bruce, 2007-12-25.
4168 pPSC->bSwRfProcessing = TRUE;
4170 RT_TRACE(COMP_RF, "InactivePsWorkItemCallback(): Set RF to %s.\n",
4171 pPSC->eInactivePowerState == eRfOff?"OFF":"ON");
4174 MgntActSet_RF_State(dev, pPSC->eInactivePowerState, RF_CHANGE_BY_IPS);
4177 // To solve CAM values miss in RF OFF, rewrite CAM values after RF ON. By Bruce, 2007-09-20.
4179 pPSC->bSwRfProcessing = FALSE;
4180 RT_TRACE(COMP_POWER, "InactivePsWorkItemCallback() <--------- \n");
4184 /* Change current and default preamble mode. */
4185 bool MgntActSet_802_11_PowerSaveMode(struct net_device *dev, u8 rtPsMode)
4187 struct r8192_priv *priv = ieee80211_priv(dev);
4189 // Currently, we do not change power save mode on IBSS mode.
4190 if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
4196 // <RJ_NOTE> If we make HW to fill up the PwrMgt bit for us,
4197 // some AP will not response to our mgnt frames with PwrMgt bit set,
4198 // e.g. cannot associate the AP.
4199 // So I commented out it. 2005.02.16, by rcnjko.
4201 // // Change device's power save mode.
4202 // Adapter->HalFunc.SetPSModeHandler( Adapter, rtPsMode );
4204 // Update power save mode configured.
4205 //RT_TRACE(COMP_LPS,"%s(): set ieee->ps = %x\n",__FUNCTION__,rtPsMode);
4206 if(!priv->ps_force) {
4207 priv->ieee80211->ps = rtPsMode;
4210 // Awake immediately
4211 if(priv->ieee80211->sta_sleep != 0 && rtPsMode == IEEE80211_PS_DISABLED)
4213 unsigned long flags;
4215 //PlatformSetTimer(Adapter, &(pMgntInfo->AwakeTimer), 0);
4216 // Notify the AP we awke.
4217 rtl8192_hw_wakeup(dev);
4218 priv->ieee80211->sta_sleep = 0;
4220 spin_lock_irqsave(&(priv->ieee80211->mgmt_tx_lock), flags);
4221 printk("LPS leave: notify AP we are awaked ++++++++++ SendNullFunctionData\n");
4222 ieee80211_sta_ps_send_null_frame(priv->ieee80211, 0);
4223 spin_unlock_irqrestore(&(priv->ieee80211->mgmt_tx_lock), flags);
4229 /* Enter the leisure power save mode. */
4230 void LeisurePSEnter(struct net_device *dev)
4232 struct r8192_priv *priv = ieee80211_priv(dev);
4233 PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->ieee80211->PowerSaveControl));
4235 //RT_TRACE(COMP_PS, "LeisurePSEnter()...\n");
4236 //RT_TRACE(COMP_PS, "pPSC->bLeisurePs = %d, ieee->ps = %d,pPSC->LpsIdleCount is %d,RT_CHECK_FOR_HANG_PERIOD is %d\n",
4237 // pPSC->bLeisurePs, priv->ieee80211->ps,pPSC->LpsIdleCount,RT_CHECK_FOR_HANG_PERIOD);
4239 if(!((priv->ieee80211->iw_mode == IW_MODE_INFRA) &&
4240 (priv->ieee80211->state == IEEE80211_LINKED)) ||
4241 (priv->ieee80211->iw_mode == IW_MODE_ADHOC) ||
4242 (priv->ieee80211->iw_mode == IW_MODE_MASTER))
4245 if (pPSC->bLeisurePs)
4247 // Idle for a while if we connect to AP a while ago.
4248 if(pPSC->LpsIdleCount >= RT_CHECK_FOR_HANG_PERIOD) // 4 Sec
4251 if(priv->ieee80211->ps == IEEE80211_PS_DISABLED)
4254 //RT_TRACE(COMP_LPS, "LeisurePSEnter(): Enter 802.11 power save mode...\n");
4255 MgntActSet_802_11_PowerSaveMode(dev, IEEE80211_PS_MBCAST|IEEE80211_PS_UNICAST);
4260 pPSC->LpsIdleCount++;
4265 /* Leave leisure power save mode. */
4266 void LeisurePSLeave(struct net_device *dev)
4268 struct r8192_priv *priv = ieee80211_priv(dev);
4269 PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->ieee80211->PowerSaveControl));
4271 if (pPSC->bLeisurePs)
4273 if(priv->ieee80211->ps != IEEE80211_PS_DISABLED)
4275 // move to lps_wakecomplete()
4276 //RT_TRACE(COMP_LPS, "LeisurePSLeave(): Busy Traffic , Leave 802.11 power save..\n");
4277 MgntActSet_802_11_PowerSaveMode(dev, IEEE80211_PS_DISABLED);
4285 /* Enter the inactive power save mode. RF will be off */
4287 IPSEnter(struct net_device *dev)
4289 struct r8192_priv *priv = ieee80211_priv(dev);
4290 PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->ieee80211->PowerSaveControl));
4291 RT_RF_POWER_STATE rtState;
4293 if (pPSC->bInactivePs)
4295 rtState = priv->ieee80211->eRFPowerState;
4297 // Added by Bruce, 2007-12-25.
4298 // Do not enter IPS in the following conditions:
4299 // (1) RF is already OFF or Sleep
4300 // (2) bSwRfProcessing (indicates the IPS is still under going)
4301 // (3) Connectted (only disconnected can trigger IPS)
4302 // (4) IBSS (send Beacon)
4303 // (5) AP mode (send Beacon)
4305 if (rtState == eRfOn && !pPSC->bSwRfProcessing
4306 && (priv->ieee80211->state != IEEE80211_LINKED) )
4308 RT_TRACE(COMP_RF,"IPSEnter(): Turn off RF.\n");
4309 //printk("IPSEnter(): Turn off RF.\n");
4310 pPSC->eInactivePowerState = eRfOff;
4311 // queue_work(priv->priv_wq,&(pPSC->InactivePsWorkItem));
4312 InactivePsWorkItemCallback(dev);
4319 // Leave the inactive power save mode, RF will be on.
4320 // 2007.08.17, by shien chang.
4323 IPSLeave(struct net_device *dev)
4325 struct r8192_priv *priv = ieee80211_priv(dev);
4326 PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->ieee80211->PowerSaveControl));
4327 RT_RF_POWER_STATE rtState;
4329 if (pPSC->bInactivePs)
4331 rtState = priv->ieee80211->eRFPowerState;
4332 if (rtState != eRfOn && !pPSC->bSwRfProcessing && priv->ieee80211->RfOffReason <= RF_CHANGE_BY_IPS)
4334 RT_TRACE(COMP_POWER, "IPSLeave(): Turn on RF.\n");
4335 //printk("IPSLeave(): Turn on RF.\n");
4336 pPSC->eInactivePowerState = eRfOn;
4337 // queue_work(priv->priv_wq,&(pPSC->InactivePsWorkItem));
4338 InactivePsWorkItemCallback(dev);
4343 void IPSLeave_wq(void *data)
4345 struct ieee80211_device *ieee = container_of(data,struct ieee80211_device,ips_leave_wq);
4346 struct net_device *dev = ieee->dev;
4348 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
4349 down(&priv->ieee80211->ips_sem);
4351 up(&priv->ieee80211->ips_sem);
4354 void ieee80211_ips_leave_wq(struct net_device *dev)
4356 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
4357 RT_RF_POWER_STATE rtState;
4358 rtState = priv->ieee80211->eRFPowerState;
4360 if(priv->ieee80211->PowerSaveControl.bInactivePs){
4361 if(rtState == eRfOff){
4362 if(priv->ieee80211->RfOffReason > RF_CHANGE_BY_IPS)
4364 RT_TRACE(COMP_ERR, "%s(): RF is OFF.\n",__FUNCTION__);
4368 printk("=========>%s(): IPSLeave\n",__FUNCTION__);
4369 queue_work(priv->ieee80211->wq,&priv->ieee80211->ips_leave_wq);
4374 //added by amy 090331 end
4375 void ieee80211_ips_leave(struct net_device *dev)
4377 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
4378 down(&priv->ieee80211->ips_sem);
4380 up(&priv->ieee80211->ips_sem);
4384 static void rtl819x_update_rxcounts(
4385 struct r8192_priv *priv,
4394 *TotalRxDataNum = 0;
4396 SlotIndex = (priv->ieee80211->LinkDetectInfo.SlotIndex++)%(priv->ieee80211->LinkDetectInfo.SlotNum);
4397 priv->ieee80211->LinkDetectInfo.RxBcnNum[SlotIndex] = priv->ieee80211->LinkDetectInfo.NumRecvBcnInPeriod;
4398 priv->ieee80211->LinkDetectInfo.RxDataNum[SlotIndex] = priv->ieee80211->LinkDetectInfo.NumRecvDataInPeriod;
4399 for( i=0; i<priv->ieee80211->LinkDetectInfo.SlotNum; i++ ){
4400 *TotalRxBcnNum += priv->ieee80211->LinkDetectInfo.RxBcnNum[i];
4401 *TotalRxDataNum += priv->ieee80211->LinkDetectInfo.RxDataNum[i];
4406 static void rtl819x_watchdog_wqcallback(struct work_struct *work)
4408 struct delayed_work *dwork = container_of(work,struct delayed_work,work);
4409 struct r8192_priv *priv = container_of(dwork,struct r8192_priv,watch_dog_wq);
4410 struct net_device *dev = priv->ieee80211->dev;
4411 struct ieee80211_device* ieee = priv->ieee80211;
4412 RESET_TYPE ResetType = RESET_TYPE_NORESET;
4413 static u8 check_reset_cnt=0;
4414 unsigned long flags;
4415 bool bBusyTraffic = false;
4416 static u8 last_time = 0;
4417 bool bEnterPS = false;
4419 if ((!priv->up) || priv->bHwRadioOff)
4424 hal_dm_watchdog(dev);
4426 // printk("watch_dog ENABLE_IPS\n");
4427 if(ieee->actscanning == false){
4428 //printk("%d,%d,%d,%d\n", ieee->eRFPowerState, ieee->is_set_key, ieee->proto_stoppping, ieee->wx_set_enc);
4429 if((ieee->iw_mode == IW_MODE_INFRA) && (ieee->state == IEEE80211_NOLINK) &&
4430 (ieee->eRFPowerState == eRfOn)&&!ieee->is_set_key &&
4431 (!ieee->proto_stoppping) && !ieee->wx_set_enc){
4432 if(ieee->PowerSaveControl.ReturnPoint == IPS_CALLBACK_NONE){
4433 //printk("====================>haha:IPSEnter()\n");
4435 //ieee80211_stop_scan(priv->ieee80211);
4440 {//to get busy traffic condition
4441 if(ieee->state == IEEE80211_LINKED)
4443 if( ieee->LinkDetectInfo.NumRxOkInPeriod> 100 ||
4444 ieee->LinkDetectInfo.NumTxOkInPeriod> 100 ) {
4445 bBusyTraffic = true;
4449 //added by amy for Leisure PS
4450 if( ((ieee->LinkDetectInfo.NumRxUnicastOkInPeriod + ieee->LinkDetectInfo.NumTxOkInPeriod) > 8 ) ||
4451 (ieee->LinkDetectInfo.NumRxUnicastOkInPeriod > 2) )
4453 //printk("ieee->LinkDetectInfo.NumRxUnicastOkInPeriod is %d,ieee->LinkDetectInfo.NumTxOkInPeriod is %d\n",
4454 // ieee->LinkDetectInfo.NumRxUnicastOkInPeriod,ieee->LinkDetectInfo.NumTxOkInPeriod);
4462 //printk("***bEnterPS = %d\n", bEnterPS);
4463 // LeisurePS only work in infra mode.
4466 LeisurePSEnter(dev);
4470 LeisurePSLeave(dev);
4478 //RT_TRACE(COMP_LPS,"====>no link LPS leave\n");
4479 LeisurePSLeave(dev);
4483 ieee->LinkDetectInfo.NumRxOkInPeriod = 0;
4484 ieee->LinkDetectInfo.NumTxOkInPeriod = 0;
4485 ieee->LinkDetectInfo.NumRxUnicastOkInPeriod = 0;
4486 ieee->LinkDetectInfo.bBusyTraffic = bBusyTraffic;
4490 //added by amy for AP roaming
4493 if(ieee->state == IEEE80211_LINKED && ieee->iw_mode == IW_MODE_INFRA)
4495 u32 TotalRxBcnNum = 0;
4496 u32 TotalRxDataNum = 0;
4498 rtl819x_update_rxcounts(priv, &TotalRxBcnNum, &TotalRxDataNum);
4499 if((TotalRxBcnNum+TotalRxDataNum) == 0)
4501 if( ieee->eRFPowerState == eRfOff)
4502 RT_TRACE(COMP_ERR,"========>%s()\n",__FUNCTION__);
4503 printk("===>%s(): AP is power off,connect another one\n",__FUNCTION__);
4504 // Dot11d_Reset(dev);
4505 ieee->state = IEEE80211_ASSOCIATING;
4506 notify_wx_assoc_event(priv->ieee80211);
4507 RemovePeerTS(priv->ieee80211,priv->ieee80211->current_network.bssid);
4508 ieee->is_roaming = true;
4509 ieee->is_set_key = false;
4510 ieee->link_change(dev);
4511 queue_work(ieee->wq, &ieee->associate_procedure_wq);
4514 ieee->LinkDetectInfo.NumRecvBcnInPeriod=0;
4515 ieee->LinkDetectInfo.NumRecvDataInPeriod=0;
4518 //check if reset the driver
4519 spin_lock_irqsave(&priv->tx_lock,flags);
4520 if(check_reset_cnt++ >= 3 && !ieee->is_roaming && (last_time != 1))
4522 ResetType = rtl819x_ifcheck_resetornot(dev);
4523 check_reset_cnt = 3;
4524 //DbgPrint("Start to check silent reset\n");
4526 spin_unlock_irqrestore(&priv->tx_lock,flags);
4527 if(!priv->bDisableNormalResetCheck && ResetType == RESET_TYPE_NORMAL)
4529 priv->ResetProgress = RESET_TYPE_NORMAL;
4530 RT_TRACE(COMP_RESET,"%s(): NOMAL RESET\n",__FUNCTION__);
4533 /* disable silent reset temply 2008.9.11*/
4535 if( ((priv->force_reset) || (!priv->bDisableNormalResetCheck && ResetType==RESET_TYPE_SILENT))) // This is control by OID set in Pomelo
4538 rtl819x_ifsilentreset(dev);
4543 priv->force_reset = false;
4544 priv->bForcedSilentReset = false;
4545 priv->bResetInProgress = false;
4546 RT_TRACE(COMP_TRACE, " <==RtUsbCheckForHangWorkItemCallback()\n");
4550 void watch_dog_timer_callback(unsigned long data)
4552 struct r8192_priv *priv = ieee80211_priv((struct net_device *) data);
4553 queue_delayed_work(priv->priv_wq,&priv->watch_dog_wq,0);
4554 mod_timer(&priv->watch_dog_timer, jiffies + MSECS(IEEE80211_WATCH_DOG_TIME));
4558 static int _rtl8192_up(struct net_device *dev)
4560 struct r8192_priv *priv = ieee80211_priv(dev);
4562 RT_STATUS init_status = RT_STATUS_SUCCESS;
4564 priv->ieee80211->ieee_up=1;
4565 priv->bdisable_nic = false; //YJ,add,091111
4566 RT_TRACE(COMP_INIT, "Bringing up iface");
4568 init_status = rtl8192_adapter_start(dev);
4569 if(init_status != RT_STATUS_SUCCESS)
4571 RT_TRACE(COMP_ERR,"ERR!!! %s(): initialization is failed!\n",__FUNCTION__);
4574 RT_TRACE(COMP_INIT, "start adapter finished\n");
4576 if(priv->ieee80211->eRFPowerState!=eRfOn)
4577 MgntActSet_RF_State(dev, eRfOn, priv->ieee80211->RfOffReason);
4579 if(priv->ieee80211->state != IEEE80211_LINKED)
4580 ieee80211_softmac_start_protocol(priv->ieee80211);
4581 ieee80211_reset_queue(priv->ieee80211);
4582 watch_dog_timer_callback((unsigned long) dev);
4583 if(!netif_queue_stopped(dev))
4584 netif_start_queue(dev);
4586 netif_wake_queue(dev);
4592 static int rtl8192_open(struct net_device *dev)
4594 struct r8192_priv *priv = ieee80211_priv(dev);
4597 down(&priv->wx_sem);
4598 ret = rtl8192_up(dev);
4605 int rtl8192_up(struct net_device *dev)
4607 struct r8192_priv *priv = ieee80211_priv(dev);
4609 if (priv->up == 1) return -1;
4611 return _rtl8192_up(dev);
4615 static int rtl8192_close(struct net_device *dev)
4617 struct r8192_priv *priv = ieee80211_priv(dev);
4620 down(&priv->wx_sem);
4622 ret = rtl8192_down(dev);
4630 int rtl8192_down(struct net_device *dev)
4632 struct r8192_priv *priv = ieee80211_priv(dev);
4634 if (priv->up == 0) return -1;
4637 //LZM for PS-Poll AID issue. 090429
4638 if(priv->ieee80211->state == IEEE80211_LINKED)
4639 LeisurePSLeave(dev);
4643 priv->ieee80211->ieee_up = 0;
4644 RT_TRACE(COMP_DOWN, "==========>%s()\n", __FUNCTION__);
4646 if (!netif_queue_stopped(dev))
4647 netif_stop_queue(dev);
4649 rtl8192_irq_disable(dev);
4650 rtl8192_cancel_deferred_work(priv);
4652 del_timer_sync(&priv->watch_dog_timer);
4654 ieee80211_softmac_stop_protocol(priv->ieee80211,true);
4656 rtl8192_halt_adapter(dev,false);
4657 memset(&priv->ieee80211->current_network, 0 , offsetof(struct ieee80211_network, list));
4659 RT_TRACE(COMP_DOWN, "<==========%s()\n", __FUNCTION__);
4665 void rtl8192_commit(struct net_device *dev)
4667 struct r8192_priv *priv = ieee80211_priv(dev);
4669 if (priv->up == 0) return ;
4672 ieee80211_softmac_stop_protocol(priv->ieee80211,true);
4674 rtl8192_irq_disable(dev);
4675 rtl8192_halt_adapter(dev,true);
4679 static void rtl8192_restart(struct work_struct *work)
4681 struct r8192_priv *priv = container_of(work, struct r8192_priv, reset_wq);
4682 struct net_device *dev = priv->ieee80211->dev;
4684 down(&priv->wx_sem);
4686 rtl8192_commit(dev);
4691 static void r8192_set_multicast(struct net_device *dev)
4693 struct r8192_priv *priv = ieee80211_priv(dev);
4696 //down(&priv->wx_sem);
4700 promisc = (dev->flags & IFF_PROMISC) ? 1:0;
4702 if (promisc != priv->promisc) {
4704 // rtl8192_commit(dev);
4707 priv->promisc = promisc;
4709 //schedule_work(&priv->reset_wq);
4710 //up(&priv->wx_sem);
4714 static int r8192_set_mac_adr(struct net_device *dev, void *mac)
4716 struct r8192_priv *priv = ieee80211_priv(dev);
4717 struct sockaddr *addr = mac;
4719 down(&priv->wx_sem);
4721 memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
4723 schedule_work(&priv->reset_wq);
4729 /* based on ipw2200 driver */
4730 static int rtl8192_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
4732 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
4733 struct iwreq *wrq = (struct iwreq *)rq;
4735 struct ieee80211_device *ieee = priv->ieee80211;
4737 u8 broadcast_addr[6] = {0xff,0xff,0xff,0xff,0xff,0xff};
4738 struct iw_point *p = &wrq->u.data;
4739 struct ieee_param *ipw = NULL;//(struct ieee_param *)wrq->u.data.pointer;
4741 down(&priv->wx_sem);
4744 if (p->length < sizeof(struct ieee_param) || !p->pointer){
4749 ipw = kmalloc(p->length, GFP_KERNEL);
4754 if (copy_from_user(ipw, p->pointer, p->length)) {
4761 case RTL_IOCTL_WPA_SUPPLICANT:
4762 //parse here for HW security
4763 if (ipw->cmd == IEEE_CMD_SET_ENCRYPTION)
4765 if (ipw->u.crypt.set_tx)
4767 if (strcmp(ipw->u.crypt.alg, "CCMP") == 0)
4768 ieee->pairwise_key_type = KEY_TYPE_CCMP;
4769 else if (strcmp(ipw->u.crypt.alg, "TKIP") == 0)
4770 ieee->pairwise_key_type = KEY_TYPE_TKIP;
4771 else if (strcmp(ipw->u.crypt.alg, "WEP") == 0)
4773 if (ipw->u.crypt.key_len == 13)
4774 ieee->pairwise_key_type = KEY_TYPE_WEP104;
4775 else if (ipw->u.crypt.key_len == 5)
4776 ieee->pairwise_key_type = KEY_TYPE_WEP40;
4779 ieee->pairwise_key_type = KEY_TYPE_NA;
4781 if (ieee->pairwise_key_type)
4783 memcpy((u8*)key, ipw->u.crypt.key, 16);
4784 EnableHWSecurityConfig8192(dev);
4785 //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!
4787 setKey(dev, 4, ipw->u.crypt.idx, ieee->pairwise_key_type, (u8*)ieee->ap_mac_addr, 0, key);
4788 if (ieee->auth_mode != 2) //LEAP WEP will never set this.
4789 setKey(dev, ipw->u.crypt.idx, ipw->u.crypt.idx, ieee->pairwise_key_type, (u8*)ieee->ap_mac_addr, 0, key);
4791 if ((ieee->pairwise_key_type == KEY_TYPE_CCMP) && ieee->pHTInfo->bCurrentHTSupport){
4792 write_nic_byte(dev, 0x173, 1); //fix aes bug
4796 else //if (ipw->u.crypt.idx) //group key use idx > 0
4798 memcpy((u8*)key, ipw->u.crypt.key, 16);
4799 if (strcmp(ipw->u.crypt.alg, "CCMP") == 0)
4800 ieee->group_key_type= KEY_TYPE_CCMP;
4801 else if (strcmp(ipw->u.crypt.alg, "TKIP") == 0)
4802 ieee->group_key_type = KEY_TYPE_TKIP;
4803 else if (strcmp(ipw->u.crypt.alg, "WEP") == 0)
4805 if (ipw->u.crypt.key_len == 13)
4806 ieee->group_key_type = KEY_TYPE_WEP104;
4807 else if (ipw->u.crypt.key_len == 5)
4808 ieee->group_key_type = KEY_TYPE_WEP40;
4811 ieee->group_key_type = KEY_TYPE_NA;
4813 if (ieee->group_key_type)
4817 ipw->u.crypt.idx, //KeyIndex
4818 ieee->group_key_type, //KeyType
4819 broadcast_addr, //MacAddr
4829 printk("@@ wrq->u pointer = ");
4830 for(i=0;i<wrq->u.data.length;i++){
4831 if(i%10==0) printk("\n");
4832 printk( "%8x|", ((u32*)wrq->u.data.pointer)[i] );
4836 #endif /*JOHN_DEBUG*/
4837 ret = ieee80211_wpa_supplicant_ioctl(priv->ieee80211, &wrq->u.data);
4852 static u8 HwRateToMRate90(bool bIsHT, u8 rate)
4858 case DESC90_RATE1M: ret_rate = MGN_1M; break;
4859 case DESC90_RATE2M: ret_rate = MGN_2M; break;
4860 case DESC90_RATE5_5M: ret_rate = MGN_5_5M; break;
4861 case DESC90_RATE11M: ret_rate = MGN_11M; break;
4862 case DESC90_RATE6M: ret_rate = MGN_6M; break;
4863 case DESC90_RATE9M: ret_rate = MGN_9M; break;
4864 case DESC90_RATE12M: ret_rate = MGN_12M; break;
4865 case DESC90_RATE18M: ret_rate = MGN_18M; break;
4866 case DESC90_RATE24M: ret_rate = MGN_24M; break;
4867 case DESC90_RATE36M: ret_rate = MGN_36M; break;
4868 case DESC90_RATE48M: ret_rate = MGN_48M; break;
4869 case DESC90_RATE54M: ret_rate = MGN_54M; break;
4872 RT_TRACE(COMP_RECV, "HwRateToMRate90(): Non supported Rate [%x], bIsHT = %d!!!\n", rate, bIsHT);
4878 case DESC90_RATEMCS0: ret_rate = MGN_MCS0; break;
4879 case DESC90_RATEMCS1: ret_rate = MGN_MCS1; break;
4880 case DESC90_RATEMCS2: ret_rate = MGN_MCS2; break;
4881 case DESC90_RATEMCS3: ret_rate = MGN_MCS3; break;
4882 case DESC90_RATEMCS4: ret_rate = MGN_MCS4; break;
4883 case DESC90_RATEMCS5: ret_rate = MGN_MCS5; break;
4884 case DESC90_RATEMCS6: ret_rate = MGN_MCS6; break;
4885 case DESC90_RATEMCS7: ret_rate = MGN_MCS7; break;
4886 case DESC90_RATEMCS8: ret_rate = MGN_MCS8; break;
4887 case DESC90_RATEMCS9: ret_rate = MGN_MCS9; break;
4888 case DESC90_RATEMCS10: ret_rate = MGN_MCS10; break;
4889 case DESC90_RATEMCS11: ret_rate = MGN_MCS11; break;
4890 case DESC90_RATEMCS12: ret_rate = MGN_MCS12; break;
4891 case DESC90_RATEMCS13: ret_rate = MGN_MCS13; break;
4892 case DESC90_RATEMCS14: ret_rate = MGN_MCS14; break;
4893 case DESC90_RATEMCS15: ret_rate = MGN_MCS15; break;
4894 case DESC90_RATEMCS32: ret_rate = (0x80|0x20); break;
4897 RT_TRACE(COMP_RECV, "HwRateToMRate90(): Non supported Rate [%x], bIsHT = %d!!!\n",rate, bIsHT);
4905 /* Record the TSF time stamp when receiving a packet */
4906 static void UpdateRxPktTimeStamp8190 (struct net_device *dev, struct ieee80211_rx_stats *stats)
4908 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
4910 if(stats->bIsAMPDU && !stats->bFirstMPDU) {
4911 stats->mac_time[0] = priv->LastRxDescTSFLow;
4912 stats->mac_time[1] = priv->LastRxDescTSFHigh;
4914 priv->LastRxDescTSFLow = stats->mac_time[0];
4915 priv->LastRxDescTSFHigh = stats->mac_time[1];
4919 static long rtl819x_translate_todbm(u8 signal_strength_index)// 0-100 index.
4921 long signal_power; // in dBm.
4923 // Translate to dBm (x=0.5y-95).
4924 signal_power = (long)((signal_strength_index + 1) >> 1);
4927 return signal_power;
4931 * Update Rx signal related information in the packet reeived
4932 * to RxStats. User application can query RxStats to realize
4933 * current Rx signal status.
4935 * In normal operation, user only care about the information of the BSS
4936 * and we shall invoke this function if the packet received is from the BSS.
4939 rtl819x_update_rxsignalstatistics8190pci(
4940 struct r8192_priv * priv,
4941 struct ieee80211_rx_stats * pprevious_stats
4946 //2 <ToDo> Update Rx Statistics (such as signal strength and signal quality).
4949 if(priv->stats.recv_signal_power == 0)
4950 priv->stats.recv_signal_power = pprevious_stats->RecvSignalPower;
4952 // To avoid the past result restricting the statistics sensitivity, weight the current power (5/6) to speed up the
4953 // reaction of smoothed Signal Power.
4954 if(pprevious_stats->RecvSignalPower > priv->stats.recv_signal_power)
4956 else if(pprevious_stats->RecvSignalPower < priv->stats.recv_signal_power)
4959 // We need more correct power of received packets and the "SignalStrength" of RxStats have been beautified or translated,
4960 // so we record the correct power in Dbm here. By Bruce, 2008-03-07.
4962 priv->stats.recv_signal_power = (priv->stats.recv_signal_power * 5 + pprevious_stats->RecvSignalPower + weighting) / 6;
4966 rtl8190_process_cck_rxpathsel(
4967 struct r8192_priv * priv,
4968 struct ieee80211_rx_stats * pprevious_stats
4971 #ifdef RTL8190P //Only 90P 2T4R need to check
4972 char last_cck_adc_pwdb[4]={0,0,0,0};
4974 //cosa add for Rx path selection
4975 if(priv->rf_type == RF_2T4R && DM_RxPathSelTable.Enable)
4977 if(pprevious_stats->bIsCCK &&
4978 (pprevious_stats->bPacketToSelf ||pprevious_stats->bPacketBeacon))
4980 /* record the cck adc_pwdb to the sliding window. */
4981 if(priv->stats.cck_adc_pwdb.TotalNum++ >= PHY_RSSI_SLID_WIN_MAX)
4983 priv->stats.cck_adc_pwdb.TotalNum = PHY_RSSI_SLID_WIN_MAX;
4984 for(i=RF90_PATH_A; i<RF90_PATH_MAX; i++)
4986 last_cck_adc_pwdb[i] = priv->stats.cck_adc_pwdb.elements[i][priv->stats.cck_adc_pwdb.index];
4987 priv->stats.cck_adc_pwdb.TotalVal[i] -= last_cck_adc_pwdb[i];
4990 for(i=RF90_PATH_A; i<RF90_PATH_MAX; i++)
4992 priv->stats.cck_adc_pwdb.TotalVal[i] += pprevious_stats->cck_adc_pwdb[i];
4993 priv->stats.cck_adc_pwdb.elements[i][priv->stats.cck_adc_pwdb.index] = pprevious_stats->cck_adc_pwdb[i];
4995 priv->stats.cck_adc_pwdb.index++;
4996 if(priv->stats.cck_adc_pwdb.index >= PHY_RSSI_SLID_WIN_MAX)
4997 priv->stats.cck_adc_pwdb.index = 0;
4999 for(i=RF90_PATH_A; i<RF90_PATH_MAX; i++)
5001 DM_RxPathSelTable.cck_pwdb_sta[i] = priv->stats.cck_adc_pwdb.TotalVal[i]/priv->stats.cck_adc_pwdb.TotalNum;
5004 for(i=RF90_PATH_A; i<RF90_PATH_MAX; i++)
5006 if(pprevious_stats->cck_adc_pwdb[i] > (char)priv->undecorated_smoothed_cck_adc_pwdb[i])
5008 priv->undecorated_smoothed_cck_adc_pwdb[i] =
5009 ( (priv->undecorated_smoothed_cck_adc_pwdb[i]*(Rx_Smooth_Factor-1)) +
5010 (pprevious_stats->cck_adc_pwdb[i])) /(Rx_Smooth_Factor);
5011 priv->undecorated_smoothed_cck_adc_pwdb[i] = priv->undecorated_smoothed_cck_adc_pwdb[i] + 1;
5015 priv->undecorated_smoothed_cck_adc_pwdb[i] =
5016 ( (priv->undecorated_smoothed_cck_adc_pwdb[i]*(Rx_Smooth_Factor-1)) +
5017 (pprevious_stats->cck_adc_pwdb[i])) /(Rx_Smooth_Factor);
5026 /* 2008/01/22 MH We can not delcare RSSI/EVM total value of sliding window to
5027 be a local static. Otherwise, it may increase when we return from S3/S4. The
5028 value will be kept in memory or disk. We must delcare the value in adapter
5029 and it will be reinitialized when return from S3/S4. */
5030 static void rtl8192_process_phyinfo(struct r8192_priv * priv, u8* buffer,struct ieee80211_rx_stats * pprevious_stats, struct ieee80211_rx_stats * pcurrent_stats)
5032 bool bcheck = false;
5034 u32 nspatial_stream, tmp_val;
5036 static u32 slide_rssi_index=0, slide_rssi_statistics=0;
5037 static u32 slide_evm_index=0, slide_evm_statistics=0;
5038 static u32 last_rssi=0, last_evm=0;
5039 //cosa add for rx path selection
5040 // static long slide_cck_adc_pwdb_index=0, slide_cck_adc_pwdb_statistics=0;
5041 // static char last_cck_adc_pwdb[4]={0,0,0,0};
5042 //cosa add for beacon rssi smoothing
5043 static u32 slide_beacon_adc_pwdb_index=0, slide_beacon_adc_pwdb_statistics=0;
5044 static u32 last_beacon_adc_pwdb=0;
5046 struct ieee80211_hdr_3addr *hdr;
5048 unsigned int frag,seq;
5049 hdr = (struct ieee80211_hdr_3addr *)buffer;
5050 sc = le16_to_cpu(hdr->seq_ctl);
5051 frag = WLAN_GET_SEQ_FRAG(sc);
5052 seq = WLAN_GET_SEQ_SEQ(sc);
5053 //cosa add 04292008 to record the sequence number
5054 pcurrent_stats->Seq_Num = seq;
5056 // Check whether we should take the previous packet into accounting
5058 if(!pprevious_stats->bIsAMPDU)
5060 // if previous packet is not aggregated packet
5064 //remve for that we don't use AMPDU to calculate PWDB,because the reported PWDB of some AP is fault.
5066 // if previous packet is aggregated packet, and current packet
5068 // (2) is the first packet of one AMPDU
5069 // that means the previous packet is the last one aggregated packet
5070 if( !pcurrent_stats->bIsAMPDU || pcurrent_stats->bFirstMPDU)
5075 if(slide_rssi_statistics++ >= PHY_RSSI_SLID_WIN_MAX)
5077 slide_rssi_statistics = PHY_RSSI_SLID_WIN_MAX;
5078 last_rssi = priv->stats.slide_signal_strength[slide_rssi_index];
5079 priv->stats.slide_rssi_total -= last_rssi;
5081 priv->stats.slide_rssi_total += pprevious_stats->SignalStrength;
5083 priv->stats.slide_signal_strength[slide_rssi_index++] = pprevious_stats->SignalStrength;
5084 if(slide_rssi_index >= PHY_RSSI_SLID_WIN_MAX)
5085 slide_rssi_index = 0;
5087 // <1> Showed on UI for user, in dbm
5088 tmp_val = priv->stats.slide_rssi_total/slide_rssi_statistics;
5089 priv->stats.signal_strength = rtl819x_translate_todbm((u8)tmp_val);
5090 pcurrent_stats->rssi = priv->stats.signal_strength;
5092 // If the previous packet does not match the criteria, neglect it
5094 if(!pprevious_stats->bPacketMatchBSSID)
5096 if(!pprevious_stats->bToSelfBA)
5103 rtl8190_process_cck_rxpathsel(priv,pprevious_stats);
5108 priv->stats.num_process_phyinfo++;
5110 /* record the general signal strength to the sliding window. */
5111 if(slide_rssi_statistics++ >= PHY_RSSI_SLID_WIN_MAX)
5113 slide_rssi_statistics = PHY_RSSI_SLID_WIN_MAX;
5114 last_rssi = priv->stats.slide_signal_strength[slide_rssi_index];
5115 priv->stats.slide_rssi_total -= last_rssi;
5117 priv->stats.slide_rssi_total += pprevious_stats->SignalStrength;
5119 priv->stats.slide_signal_strength[slide_rssi_index++] = pprevious_stats->SignalStrength;
5120 if(slide_rssi_index >= PHY_RSSI_SLID_WIN_MAX)
5121 slide_rssi_index = 0;
5123 // <1> Showed on UI for user, in dbm
5124 tmp_val = priv->stats.slide_rssi_total/slide_rssi_statistics;
5125 priv->stats.signal_strength = rtl819x_translate_todbm((u8)tmp_val);
5128 // <2> Showed on UI for engineering
5129 // hardware does not provide rssi information for each rf path in CCK
5130 if(!pprevious_stats->bIsCCK && pprevious_stats->bPacketToSelf)
5132 for (rfpath = RF90_PATH_A; rfpath < RF90_PATH_C; rfpath++)
5134 if (!rtl8192_phy_CheckIsLegalRFPath(priv->ieee80211->dev, rfpath))
5136 RT_TRACE(COMP_DBG,"Jacken -> pPreviousstats->RxMIMOSignalStrength[rfpath] = %d \n" ,pprevious_stats->RxMIMOSignalStrength[rfpath] );
5137 //Fixed by Jacken 2008-03-20
5138 if(priv->stats.rx_rssi_percentage[rfpath] == 0)
5140 priv->stats.rx_rssi_percentage[rfpath] = pprevious_stats->RxMIMOSignalStrength[rfpath];
5141 //DbgPrint("MIMO RSSI initialize \n");
5143 if(pprevious_stats->RxMIMOSignalStrength[rfpath] > priv->stats.rx_rssi_percentage[rfpath])
5145 priv->stats.rx_rssi_percentage[rfpath] =
5146 ( (priv->stats.rx_rssi_percentage[rfpath]*(Rx_Smooth_Factor-1)) +
5147 (pprevious_stats->RxMIMOSignalStrength[rfpath])) /(Rx_Smooth_Factor);
5148 priv->stats.rx_rssi_percentage[rfpath] = priv->stats.rx_rssi_percentage[rfpath] + 1;
5152 priv->stats.rx_rssi_percentage[rfpath] =
5153 ( (priv->stats.rx_rssi_percentage[rfpath]*(Rx_Smooth_Factor-1)) +
5154 (pprevious_stats->RxMIMOSignalStrength[rfpath])) /(Rx_Smooth_Factor);
5156 RT_TRACE(COMP_DBG,"Jacken -> priv->RxStats.RxRSSIPercentage[rfPath] = %d \n" ,priv->stats.rx_rssi_percentage[rfpath] );
5164 //cosa add for beacon rssi smoothing by average.
5165 if(pprevious_stats->bPacketBeacon)
5167 /* record the beacon pwdb to the sliding window. */
5168 if(slide_beacon_adc_pwdb_statistics++ >= PHY_Beacon_RSSI_SLID_WIN_MAX)
5170 slide_beacon_adc_pwdb_statistics = PHY_Beacon_RSSI_SLID_WIN_MAX;
5171 last_beacon_adc_pwdb = priv->stats.Slide_Beacon_pwdb[slide_beacon_adc_pwdb_index];
5172 priv->stats.Slide_Beacon_Total -= last_beacon_adc_pwdb;
5173 //DbgPrint("slide_beacon_adc_pwdb_index = %d, last_beacon_adc_pwdb = %d, Adapter->RxStats.Slide_Beacon_Total = %d\n",
5174 // slide_beacon_adc_pwdb_index, last_beacon_adc_pwdb, Adapter->RxStats.Slide_Beacon_Total);
5176 priv->stats.Slide_Beacon_Total += pprevious_stats->RxPWDBAll;
5177 priv->stats.Slide_Beacon_pwdb[slide_beacon_adc_pwdb_index] = pprevious_stats->RxPWDBAll;
5178 //DbgPrint("slide_beacon_adc_pwdb_index = %d, pPreviousRfd->Status.RxPWDBAll = %d\n", slide_beacon_adc_pwdb_index, pPreviousRfd->Status.RxPWDBAll);
5179 slide_beacon_adc_pwdb_index++;
5180 if(slide_beacon_adc_pwdb_index >= PHY_Beacon_RSSI_SLID_WIN_MAX)
5181 slide_beacon_adc_pwdb_index = 0;
5182 pprevious_stats->RxPWDBAll = priv->stats.Slide_Beacon_Total/slide_beacon_adc_pwdb_statistics;
5183 if(pprevious_stats->RxPWDBAll >= 3)
5184 pprevious_stats->RxPWDBAll -= 3;
5187 RT_TRACE(COMP_RXDESC, "Smooth %s PWDB = %d\n",
5188 pprevious_stats->bIsCCK? "CCK": "OFDM",
5189 pprevious_stats->RxPWDBAll);
5191 if(pprevious_stats->bPacketToSelf || pprevious_stats->bPacketBeacon || pprevious_stats->bToSelfBA)
5193 if(priv->undecorated_smoothed_pwdb < 0) // initialize
5195 priv->undecorated_smoothed_pwdb = pprevious_stats->RxPWDBAll;
5196 //DbgPrint("First pwdb initialize \n");
5199 if(pprevious_stats->RxPWDBAll > (u32)priv->undecorated_smoothed_pwdb)
5201 priv->undecorated_smoothed_pwdb =
5202 ( ((priv->undecorated_smoothed_pwdb)*(Rx_Smooth_Factor-1)) +
5203 (pprevious_stats->RxPWDBAll)) /(Rx_Smooth_Factor);
5204 priv->undecorated_smoothed_pwdb = priv->undecorated_smoothed_pwdb + 1;
5208 priv->undecorated_smoothed_pwdb =
5209 ( ((priv->undecorated_smoothed_pwdb)*(Rx_Smooth_Factor-1)) +
5210 (pprevious_stats->RxPWDBAll)) /(Rx_Smooth_Factor);
5213 //Fixed by Jacken 2008-03-20
5214 if(pPreviousRfd->Status.RxPWDBAll > (u32)pHalData->UndecoratedSmoothedPWDB)
5216 pHalData->UndecoratedSmoothedPWDB =
5217 ( ((pHalData->UndecoratedSmoothedPWDB)* 5) + (pPreviousRfd->Status.RxPWDBAll)) / 6;
5218 pHalData->UndecoratedSmoothedPWDB = pHalData->UndecoratedSmoothedPWDB + 1;
5222 pHalData->UndecoratedSmoothedPWDB =
5223 ( ((pHalData->UndecoratedSmoothedPWDB)* 5) + (pPreviousRfd->Status.RxPWDBAll)) / 6;
5226 rtl819x_update_rxsignalstatistics8190pci(priv,pprevious_stats);
5232 /* record the general EVM to the sliding window. */
5233 if(pprevious_stats->SignalQuality == 0)
5238 if(pprevious_stats->bPacketToSelf || pprevious_stats->bPacketBeacon || pprevious_stats->bToSelfBA){
5239 if(slide_evm_statistics++ >= PHY_RSSI_SLID_WIN_MAX){
5240 slide_evm_statistics = PHY_RSSI_SLID_WIN_MAX;
5241 last_evm = priv->stats.slide_evm[slide_evm_index];
5242 priv->stats.slide_evm_total -= last_evm;
5245 priv->stats.slide_evm_total += pprevious_stats->SignalQuality;
5247 priv->stats.slide_evm[slide_evm_index++] = pprevious_stats->SignalQuality;
5248 if(slide_evm_index >= PHY_RSSI_SLID_WIN_MAX)
5249 slide_evm_index = 0;
5251 // <1> Showed on UI for user, in percentage.
5252 tmp_val = priv->stats.slide_evm_total/slide_evm_statistics;
5253 priv->stats.signal_quality = tmp_val;
5254 //cosa add 10/11/2007, Showed on UI for user in Windows Vista, for Link quality.
5255 priv->stats.last_signal_strength_inpercent = tmp_val;
5258 // <2> Showed on UI for engineering
5259 if(pprevious_stats->bPacketToSelf || pprevious_stats->bPacketBeacon || pprevious_stats->bToSelfBA)
5261 for(nspatial_stream = 0; nspatial_stream<2 ; nspatial_stream++) // 2 spatial stream
5263 if(pprevious_stats->RxMIMOSignalQuality[nspatial_stream] != -1)
5265 if(priv->stats.rx_evm_percentage[nspatial_stream] == 0) // initialize
5267 priv->stats.rx_evm_percentage[nspatial_stream] = pprevious_stats->RxMIMOSignalQuality[nspatial_stream];
5269 priv->stats.rx_evm_percentage[nspatial_stream] =
5270 ( (priv->stats.rx_evm_percentage[nspatial_stream]* (Rx_Smooth_Factor-1)) +
5271 (pprevious_stats->RxMIMOSignalQuality[nspatial_stream]* 1)) / (Rx_Smooth_Factor);
5279 static u8 rtl819x_query_rxpwrpercentage(
5283 if ((antpower <= -100) || (antpower >= 20))
5287 else if (antpower >= 0)
5293 return (100+antpower);
5299 rtl819x_evm_dbtopercentage(
5311 ret_val = 0 - ret_val;
5318 /* We want good-looking for signal strength/quality */
5319 static long rtl819x_signal_scale_mapping(long currsig)
5323 // Step 1. Scale mapping.
5324 if(currsig >= 61 && currsig <= 100)
5326 retsig = 90 + ((currsig - 60) / 4);
5328 else if(currsig >= 41 && currsig <= 60)
5330 retsig = 78 + ((currsig - 40) / 2);
5332 else if(currsig >= 31 && currsig <= 40)
5334 retsig = 66 + (currsig - 30);
5336 else if(currsig >= 21 && currsig <= 30)
5338 retsig = 54 + (currsig - 20);
5340 else if(currsig >= 5 && currsig <= 20)
5342 retsig = 42 + (((currsig - 5) * 2) / 3);
5344 else if(currsig == 4)
5348 else if(currsig == 3)
5352 else if(currsig == 2)
5356 else if(currsig == 1)
5368 static void rtl8192_query_rxphystatus(
5369 struct r8192_priv * priv,
5370 struct ieee80211_rx_stats * pstats,
5371 prx_desc_819x_pci pdesc,
5372 prx_fwinfo_819x_pci pdrvinfo,
5373 struct ieee80211_rx_stats * precord_stats,
5374 bool bpacket_match_bssid,
5375 bool bpacket_toself,
5380 //PRT_RFD_STATUS pRtRfdStatus = &(pRfd->Status);
5381 phy_sts_ofdm_819xpci_t* pofdm_buf;
5382 phy_sts_cck_819xpci_t * pcck_buf;
5383 phy_ofdm_rx_status_rxsc_sgien_exintfflag* prxsc;
5385 u8 i,max_spatial_stream, tmp_rxsnr, tmp_rxevm, rxsc_sgien_exflg;
5386 char rx_pwr[4], rx_pwr_all=0;
5387 //long rx_avg_pwr = 0;
5388 char rx_snrX, rx_evmX;
5390 u32 RSSI, total_rssi=0;//, total_evm=0;
5391 // long signal_strength_index = 0;
5395 /* 2007/07/04 MH For OFDM RSSI. For high power or not. */
5396 static u8 check_reg824 = 0;
5397 static u32 reg824_bit9 = 0;
5399 priv->stats.numqry_phystatus++;
5401 is_cck_rate = rx_hal_is_cck_rate(pdrvinfo);
5403 // Record it for next packet processing
5404 memset(precord_stats, 0, sizeof(struct ieee80211_rx_stats));
5405 pstats->bPacketMatchBSSID = precord_stats->bPacketMatchBSSID = bpacket_match_bssid;
5406 pstats->bPacketToSelf = precord_stats->bPacketToSelf = bpacket_toself;
5407 pstats->bIsCCK = precord_stats->bIsCCK = is_cck_rate;//RX_HAL_IS_CCK_RATE(pDrvInfo);
5408 pstats->bPacketBeacon = precord_stats->bPacketBeacon = bPacketBeacon;
5409 pstats->bToSelfBA = precord_stats->bToSelfBA = bToSelfBA;
5410 /*2007.08.30 requested by SD3 Jerry */
5411 if(check_reg824 == 0)
5413 reg824_bit9 = rtl8192_QueryBBReg(priv->ieee80211->dev, rFPGA0_XA_HSSIParameter2, 0x200);
5418 prxpkt = (u8*)pdrvinfo;
5420 /* Move pointer to the 16th bytes. Phy status start address. */
5421 prxpkt += sizeof(rx_fwinfo_819x_pci);
5423 /* Initial the cck and ofdm buffer pointer */
5424 pcck_buf = (phy_sts_cck_819xpci_t *)prxpkt;
5425 pofdm_buf = (phy_sts_ofdm_819xpci_t *)prxpkt;
5427 pstats->RxMIMOSignalQuality[0] = -1;
5428 pstats->RxMIMOSignalQuality[1] = -1;
5429 precord_stats->RxMIMOSignalQuality[0] = -1;
5430 precord_stats->RxMIMOSignalQuality[1] = -1;
5435 // (1)Hardware does not provide RSSI for CCK
5439 // (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive)
5441 u8 report;//, cck_agc_rpt;
5444 char cck_adc_pwdb[4];
5446 priv->stats.numqry_phystatusCCK++;
5448 #ifdef RTL8190P //Only 90P 2T4R need to check
5449 if(priv->rf_type == RF_2T4R && DM_RxPathSelTable.Enable && bpacket_match_bssid)
5451 for(i=RF90_PATH_A; i<RF90_PATH_MAX; i++)
5453 tmp_pwdb = pcck_buf->adc_pwdb_X[i];
5454 cck_adc_pwdb[i] = (char)tmp_pwdb;
5455 cck_adc_pwdb[i] /= 2;
5456 pstats->cck_adc_pwdb[i] = precord_stats->cck_adc_pwdb[i] = cck_adc_pwdb[i];
5457 //DbgPrint("RF-%d tmp_pwdb = 0x%x, cck_adc_pwdb = %d", i, tmp_pwdb, cck_adc_pwdb[i]);
5464 report = pcck_buf->cck_agc_rpt & 0xc0;
5468 //Fixed by Jacken from Bryant 2008-03-20
5469 //Original value is -38 , -26 , -14 , -2
5470 //Fixed value is -35 , -23 , -11 , 6
5472 rx_pwr_all = -35 - (pcck_buf->cck_agc_rpt & 0x3e);
5475 rx_pwr_all = -23 - (pcck_buf->cck_agc_rpt & 0x3e);
5478 rx_pwr_all = -11 - (pcck_buf->cck_agc_rpt & 0x3e);
5481 rx_pwr_all = 8 - (pcck_buf->cck_agc_rpt & 0x3e);
5487 report = pcck_buf->cck_agc_rpt & 0x60;
5492 rx_pwr_all = -35 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1) ;
5495 rx_pwr_all = -23 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1);
5498 rx_pwr_all = -11 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1) ;
5501 rx_pwr_all = -8 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1) ;
5506 pwdb_all = rtl819x_query_rxpwrpercentage(rx_pwr_all);
5507 pstats->RxPWDBAll = precord_stats->RxPWDBAll = pwdb_all;
5508 pstats->RecvSignalPower = rx_pwr_all;
5511 // (3) Get Signal Quality (EVM)
5513 if(bpacket_match_bssid)
5517 if(pstats->RxPWDBAll > 40)
5522 sq = pcck_buf->sq_rpt;
5524 if(pcck_buf->sq_rpt > 64)
5526 else if (pcck_buf->sq_rpt < 20)
5529 sq = ((64-sq) * 100) / 44;
5531 pstats->SignalQuality = precord_stats->SignalQuality = sq;
5532 pstats->RxMIMOSignalQuality[0] = precord_stats->RxMIMOSignalQuality[0] = sq;
5533 pstats->RxMIMOSignalQuality[1] = precord_stats->RxMIMOSignalQuality[1] = -1;
5538 priv->stats.numqry_phystatusHT++;
5540 // (1)Get RSSI for HT rate
5542 for(i=RF90_PATH_A; i<RF90_PATH_MAX; i++)
5544 // 2008/01/30 MH we will judge RF RX path now.
5545 if (priv->brfpath_rxenable[i])
5550 //Fixed by Jacken from Bryant 2008-03-20
5551 //Original value is 106
5552 #ifdef RTL8190P //Modify by Jacken 2008/03/31
5553 rx_pwr[i] = ((pofdm_buf->trsw_gain_X[i]&0x3F)*2) - 106;
5555 rx_pwr[i] = ((pofdm_buf->trsw_gain_X[i]&0x3F)*2) - 110;
5558 //Get Rx snr value in DB
5559 tmp_rxsnr = pofdm_buf->rxsnr_X[i];
5560 rx_snrX = (char)(tmp_rxsnr);
5562 priv->stats.rxSNRdB[i] = (long)rx_snrX;
5564 /* Translate DBM to percentage. */
5565 RSSI = rtl819x_query_rxpwrpercentage(rx_pwr[i]);
5566 if (priv->brfpath_rxenable[i])
5569 /* Record Signal Strength for next packet */
5570 if(bpacket_match_bssid)
5572 pstats->RxMIMOSignalStrength[i] =(u8) RSSI;
5573 precord_stats->RxMIMOSignalStrength[i] =(u8) RSSI;
5579 // (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive)
5581 //Fixed by Jacken from Bryant 2008-03-20
5582 //Original value is 106
5583 rx_pwr_all = (((pofdm_buf->pwdb_all ) >> 1 )& 0x7f) -106;
5584 pwdb_all = rtl819x_query_rxpwrpercentage(rx_pwr_all);
5586 pstats->RxPWDBAll = precord_stats->RxPWDBAll = pwdb_all;
5587 pstats->RxPower = precord_stats->RxPower = rx_pwr_all;
5588 pstats->RecvSignalPower = rx_pwr_all;
5590 // (3)EVM of HT rate
5592 if(pdrvinfo->RxHT && pdrvinfo->RxRate>=DESC90_RATEMCS8 &&
5593 pdrvinfo->RxRate<=DESC90_RATEMCS15)
5594 max_spatial_stream = 2; //both spatial stream make sense
5596 max_spatial_stream = 1; //only spatial stream 1 makes sense
5598 for(i=0; i<max_spatial_stream; i++)
5600 tmp_rxevm = pofdm_buf->rxevm_X[i];
5601 rx_evmX = (char)(tmp_rxevm);
5603 // Do not use shift operation like "rx_evmX >>= 1" because the compilor of free build environment
5604 // fill most significant bit to "zero" when doing shifting operation which may change a negative
5605 // value to positive one, then the dbm value (which is supposed to be negative) is not correct anymore.
5608 evm = rtl819x_evm_dbtopercentage(rx_evmX);
5610 EVM = SignalScaleMapping(EVM);//make it good looking, from 0~100
5612 if(bpacket_match_bssid)
5614 if(i==0) // Fill value in RFD, Get the first spatial stream only
5615 pstats->SignalQuality = precord_stats->SignalQuality = (u8)(evm & 0xff);
5616 pstats->RxMIMOSignalQuality[i] = precord_stats->RxMIMOSignalQuality[i] = (u8)(evm & 0xff);
5621 /* record rx statistics for debug */
5622 rxsc_sgien_exflg = pofdm_buf->rxsc_sgien_exflg;
5623 prxsc = (phy_ofdm_rx_status_rxsc_sgien_exintfflag *)&rxsc_sgien_exflg;
5624 if(pdrvinfo->BW) //40M channel
5625 priv->stats.received_bwtype[1+prxsc->rxsc]++;
5627 priv->stats.received_bwtype[0]++;
5630 //UI BSS List signal strength(in percentage), make it good looking, from 0~100.
5631 //It is assigned to the BSS List in GetValueFromBeaconOrProbeRsp().
5634 pstats->SignalStrength = precord_stats->SignalStrength = (u8)(rtl819x_signal_scale_mapping((long)pwdb_all));//PWDB_ALL;
5639 //pRfd->Status.SignalStrength = pRecordRfd->Status.SignalStrength = (u1Byte)(SignalScaleMapping(total_rssi/=RF90_PATH_MAX));//(u1Byte)(total_rssi/=RF90_PATH_MAX);
5640 // We can judge RX path number now.
5642 pstats->SignalStrength = precord_stats->SignalStrength = (u8)(rtl819x_signal_scale_mapping((long)(total_rssi/=rf_rx_num)));
5647 rtl8192_record_rxdesc_forlateruse(
5648 struct ieee80211_rx_stats * psrc_stats,
5649 struct ieee80211_rx_stats * ptarget_stats
5652 ptarget_stats->bIsAMPDU = psrc_stats->bIsAMPDU;
5653 ptarget_stats->bFirstMPDU = psrc_stats->bFirstMPDU;
5654 //ptarget_stats->Seq_Num = psrc_stats->Seq_Num;
5659 static void TranslateRxSignalStuff819xpci(struct net_device *dev,
5660 struct sk_buff *skb,
5661 struct ieee80211_rx_stats * pstats,
5662 prx_desc_819x_pci pdesc,
5663 prx_fwinfo_819x_pci pdrvinfo)
5665 // TODO: We must only check packet for current MAC address. Not finish
5666 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
5667 bool bpacket_match_bssid, bpacket_toself;
5668 bool bPacketBeacon=false, bToSelfBA=false;
5669 static struct ieee80211_rx_stats previous_stats;
5670 struct ieee80211_hdr_3addr *hdr;
5673 // Get Signal Quality for only RX data queue (but not command queue)
5678 /* Get MAC frame start address. */
5679 tmp_buf = skb->data;
5681 hdr = (struct ieee80211_hdr_3addr *)tmp_buf;
5682 fc = le16_to_cpu(hdr->frame_ctl);
5683 type = WLAN_FC_GET_TYPE(fc);
5684 praddr = hdr->addr1;
5686 /* Check if the received packet is acceptabe. */
5687 bpacket_match_bssid = ((IEEE80211_FTYPE_CTL != type) &&
5688 (eqMacAddr(priv->ieee80211->current_network.bssid, (fc & IEEE80211_FCTL_TODS)? hdr->addr1 : (fc & IEEE80211_FCTL_FROMDS )? hdr->addr2 : hdr->addr3))
5689 && (!pstats->bHwError) && (!pstats->bCRC)&& (!pstats->bICV));
5690 bpacket_toself = bpacket_match_bssid & (eqMacAddr(praddr, priv->ieee80211->dev->dev_addr));
5692 if(WLAN_FC_GET_FRAMETYPE(fc)== IEEE80211_STYPE_BEACON)
5694 bPacketBeacon = true;
5695 //DbgPrint("Beacon 2, MatchBSSID = %d, ToSelf = %d \n", bPacketMatchBSSID, bPacketToSelf);
5697 if(WLAN_FC_GET_FRAMETYPE(fc) == IEEE80211_STYPE_BLOCKACK)
5699 if((eqMacAddr(praddr,dev->dev_addr)))
5701 //DbgPrint("BlockAck, MatchBSSID = %d, ToSelf = %d \n", bPacketMatchBSSID, bPacketToSelf);
5705 if(bpacket_match_bssid)
5707 priv->stats.numpacket_matchbssid++;
5710 priv->stats.numpacket_toself++;
5713 // Process PHY information for previous packet (RSSI/PWDB/EVM)
5715 // Because phy information is contained in the last packet of AMPDU only, so driver
5716 // should process phy information of previous packet
5717 rtl8192_process_phyinfo(priv, tmp_buf,&previous_stats, pstats);
5718 rtl8192_query_rxphystatus(priv, pstats, pdesc, pdrvinfo, &previous_stats, bpacket_match_bssid,
5719 bpacket_toself ,bPacketBeacon, bToSelfBA);
5720 rtl8192_record_rxdesc_forlateruse(pstats, &previous_stats);
5725 static void rtl8192_tx_resume(struct net_device *dev)
5727 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
5728 struct ieee80211_device *ieee = priv->ieee80211;
5729 struct sk_buff *skb;
5732 for(queue_index = BK_QUEUE; queue_index < TXCMD_QUEUE;queue_index++) {
5733 while((!skb_queue_empty(&ieee->skb_waitQ[queue_index]))&&
5734 (priv->ieee80211->check_nic_enough_desc(dev,queue_index) > 0)) {
5735 /* 1. dequeue the packet from the wait queue */
5736 skb = skb_dequeue(&ieee->skb_waitQ[queue_index]);
5737 /* 2. tx the packet directly */
5738 ieee->softmac_data_hard_start_xmit(skb,dev,0/* rate useless now*/);
5740 if(queue_index!=MGNT_QUEUE) {
5741 ieee->stats.tx_packets++;
5742 ieee->stats.tx_bytes += skb->len;
5749 static void rtl8192_irq_tx_tasklet(struct r8192_priv *priv)
5751 rtl8192_tx_resume(priv->ieee80211->dev);
5754 /* Record the received data rate */
5755 static void UpdateReceivedRateHistogramStatistics8190(
5756 struct net_device *dev,
5757 struct ieee80211_rx_stats* pstats
5760 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
5761 u32 rcvType=1; //0: Total, 1:OK, 2:CRC, 3:ICV
5763 u32 preamble_guardinterval; //1: short preamble/GI, 0: long preamble/GI
5767 else if(pstats->bICV)
5770 if(pstats->bShortPreamble)
5771 preamble_guardinterval = 1;// short
5773 preamble_guardinterval = 0;// long
5775 switch(pstats->rate)
5780 case MGN_1M: rateIndex = 0; break;
5781 case MGN_2M: rateIndex = 1; break;
5782 case MGN_5_5M: rateIndex = 2; break;
5783 case MGN_11M: rateIndex = 3; break;
5787 case MGN_6M: rateIndex = 4; break;
5788 case MGN_9M: rateIndex = 5; break;
5789 case MGN_12M: rateIndex = 6; break;
5790 case MGN_18M: rateIndex = 7; break;
5791 case MGN_24M: rateIndex = 8; break;
5792 case MGN_36M: rateIndex = 9; break;
5793 case MGN_48M: rateIndex = 10; break;
5794 case MGN_54M: rateIndex = 11; break;
5796 // 11n High throughput rate
5798 case MGN_MCS0: rateIndex = 12; break;
5799 case MGN_MCS1: rateIndex = 13; break;
5800 case MGN_MCS2: rateIndex = 14; break;
5801 case MGN_MCS3: rateIndex = 15; break;
5802 case MGN_MCS4: rateIndex = 16; break;
5803 case MGN_MCS5: rateIndex = 17; break;
5804 case MGN_MCS6: rateIndex = 18; break;
5805 case MGN_MCS7: rateIndex = 19; break;
5806 case MGN_MCS8: rateIndex = 20; break;
5807 case MGN_MCS9: rateIndex = 21; break;
5808 case MGN_MCS10: rateIndex = 22; break;
5809 case MGN_MCS11: rateIndex = 23; break;
5810 case MGN_MCS12: rateIndex = 24; break;
5811 case MGN_MCS13: rateIndex = 25; break;
5812 case MGN_MCS14: rateIndex = 26; break;
5813 case MGN_MCS15: rateIndex = 27; break;
5814 default: rateIndex = 28; break;
5816 priv->stats.received_preamble_GI[preamble_guardinterval][rateIndex]++;
5817 priv->stats.received_rate_histogram[0][rateIndex]++; //total
5818 priv->stats.received_rate_histogram[rcvType][rateIndex]++;
5821 static void rtl8192_rx(struct net_device *dev)
5823 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
5824 struct ieee80211_hdr_1addr *ieee80211_hdr = NULL;
5825 bool unicast_packet = false;
5826 struct ieee80211_rx_stats stats = {
5830 .freq = IEEE80211_24GHZ_BAND,
5832 unsigned int count = priv->rxringcount;
5834 stats.nic_type = NIC_8192E;
5837 rx_desc_819x_pci *pdesc = &priv->rx_ring[priv->rx_idx];//rx descriptor
5838 struct sk_buff *skb = priv->rx_buf[priv->rx_idx];//rx pkt
5841 /* wait data to be filled by hardware */
5844 stats.bICV = pdesc->ICV;
5845 stats.bCRC = pdesc->CRC32;
5846 stats.bHwError = pdesc->CRC32 | pdesc->ICV;
5848 stats.Length = pdesc->Length;
5849 if(stats.Length < 24)
5850 stats.bHwError |= 1;
5852 if(stats.bHwError) {
5853 stats.bShift = false;
5856 if (pdesc->Length <500)
5857 priv->stats.rxcrcerrmin++;
5858 else if (pdesc->Length >1000)
5859 priv->stats.rxcrcerrmax++;
5861 priv->stats.rxcrcerrmid++;
5865 prx_fwinfo_819x_pci pDrvInfo = NULL;
5866 struct sk_buff *new_skb = dev_alloc_skb(priv->rxbuffersize);
5868 if (unlikely(!new_skb)) {
5872 stats.RxDrvInfoSize = pdesc->RxDrvInfoSize;
5873 stats.RxBufShift = ((pdesc->Shift)&0x03);
5874 stats.Decrypted = !pdesc->SWDec;
5876 pci_dma_sync_single_for_cpu(priv->pdev,
5877 *((dma_addr_t *)skb->cb),
5879 PCI_DMA_FROMDEVICE);
5880 skb_put(skb, pdesc->Length);
5881 pDrvInfo = (rx_fwinfo_819x_pci *)(skb->data + stats.RxBufShift);
5882 skb_reserve(skb, stats.RxDrvInfoSize + stats.RxBufShift);
5884 stats.rate = HwRateToMRate90((bool)pDrvInfo->RxHT, (u8)pDrvInfo->RxRate);
5885 stats.bShortPreamble = pDrvInfo->SPLCP;
5887 /* it is debug only. It should be disabled in released driver.
5888 * 2007.1.11 by Emily
5890 UpdateReceivedRateHistogramStatistics8190(dev, &stats);
5892 stats.bIsAMPDU = (pDrvInfo->PartAggr==1);
5893 stats.bFirstMPDU = (pDrvInfo->PartAggr==1) && (pDrvInfo->FirstAGGR==1);
5895 stats.TimeStampLow = pDrvInfo->TSFL;
5896 stats.TimeStampHigh = read_nic_dword(dev, TSFR+4);
5898 UpdateRxPktTimeStamp8190(dev, &stats);
5901 // Get Total offset of MPDU Frame Body
5903 if((stats.RxBufShift + stats.RxDrvInfoSize) > 0)
5906 stats.RxIs40MHzPacket = pDrvInfo->BW;
5909 TranslateRxSignalStuff819xpci(dev,skb, &stats, pdesc, pDrvInfo);
5912 if(pDrvInfo->FirstAGGR==1 || pDrvInfo->PartAggr == 1)
5913 RT_TRACE(COMP_RXDESC, "pDrvInfo->FirstAGGR = %d, pDrvInfo->PartAggr = %d\n",
5914 pDrvInfo->FirstAGGR, pDrvInfo->PartAggr);
5915 skb_trim(skb, skb->len - 4/*sCrcLng*/);
5916 /* rx packets statistics */
5917 ieee80211_hdr = (struct ieee80211_hdr_1addr *)skb->data;
5918 unicast_packet = false;
5920 if(is_broadcast_ether_addr(ieee80211_hdr->addr1)) {
5922 }else if(is_multicast_ether_addr(ieee80211_hdr->addr1)){
5925 /* unicast packet */
5926 unicast_packet = true;
5929 stats.packetlength = stats.Length-4;
5930 stats.fraglength = stats.packetlength;
5931 stats.fragoffset = 0;
5932 stats.ntotalfrag = 1;
5934 if(!ieee80211_rtl_rx(priv->ieee80211, skb, &stats)){
5935 dev_kfree_skb_any(skb);
5938 if(unicast_packet) {
5939 priv->stats.rxbytesunicast += skb->len;
5944 priv->rx_buf[priv->rx_idx] = skb;
5945 *((dma_addr_t *) skb->cb) = pci_map_single(priv->pdev, skb_tail_pointer(skb), priv->rxbuffersize, PCI_DMA_FROMDEVICE);
5950 pdesc->BufferAddress = cpu_to_le32(*((dma_addr_t *)skb->cb));
5952 pdesc->Length = priv->rxbuffersize;
5953 if (priv->rx_idx == priv->rxringcount-1)
5955 priv->rx_idx = (priv->rx_idx + 1) % priv->rxringcount;
5960 static void rtl8192_irq_rx_tasklet(struct r8192_priv *priv)
5962 rtl8192_rx(priv->ieee80211->dev);
5964 write_nic_dword(priv->ieee80211->dev, INTA_MASK,read_nic_dword(priv->ieee80211->dev, INTA_MASK) | IMR_RDU);
5967 static const struct net_device_ops rtl8192_netdev_ops = {
5968 .ndo_open = rtl8192_open,
5969 .ndo_stop = rtl8192_close,
5970 .ndo_tx_timeout = tx_timeout,
5971 .ndo_do_ioctl = rtl8192_ioctl,
5972 .ndo_set_multicast_list = r8192_set_multicast,
5973 .ndo_set_mac_address = r8192_set_mac_adr,
5974 .ndo_start_xmit = ieee80211_rtl_xmit,
5977 static int __devinit rtl8192_pci_probe(struct pci_dev *pdev,
5978 const struct pci_device_id *id)
5980 unsigned long ioaddr = 0;
5981 struct net_device *dev = NULL;
5982 struct r8192_priv *priv= NULL;
5986 #ifdef CONFIG_RTL8192_IO_MAP
5987 unsigned long pio_start, pio_len, pio_flags;
5989 unsigned long pmem_start, pmem_len, pmem_flags;
5990 #endif //end #ifdef RTL_IO_MAP
5992 RT_TRACE(COMP_INIT,"Configuring chip resources");
5994 if( pci_enable_device (pdev) ){
5995 RT_TRACE(COMP_ERR,"Failed to enable PCI device");
5999 pci_set_master(pdev);
6000 //pci_set_wmi(pdev);
6001 pci_set_dma_mask(pdev, 0xffffff00ULL);
6002 pci_set_consistent_dma_mask(pdev,0xffffff00ULL);
6003 dev = alloc_ieee80211(sizeof(struct r8192_priv));
6009 pci_set_drvdata(pdev, dev);
6010 SET_NETDEV_DEV(dev, &pdev->dev);
6011 priv = ieee80211_priv(dev);
6012 priv->ieee80211 = netdev_priv(dev);
6014 if((pdev->subsystem_vendor == PCI_VENDOR_ID_DLINK)&&(pdev->subsystem_device == 0x3304)){
6015 priv->ieee80211->bSupportRemoteWakeUp = 1;
6018 priv->ieee80211->bSupportRemoteWakeUp = 0;
6021 #ifdef CONFIG_RTL8192_IO_MAP
6023 pio_start = (unsigned long)pci_resource_start (pdev, 0);
6024 pio_len = (unsigned long)pci_resource_len (pdev, 0);
6025 pio_flags = (unsigned long)pci_resource_flags (pdev, 0);
6027 if (!(pio_flags & IORESOURCE_IO)) {
6028 RT_TRACE(COMP_ERR,"region #0 not a PIO resource, aborting");
6032 //DMESG("IO space @ 0x%08lx", pio_start );
6033 if( ! request_region( pio_start, pio_len, RTL819xE_MODULE_NAME ) ){
6034 RT_TRACE(COMP_ERR,"request_region failed!");
6039 dev->base_addr = ioaddr; // device I/O address
6043 pmem_start = pci_resource_start(pdev, 1);
6044 pmem_len = pci_resource_len(pdev, 1);
6045 pmem_flags = pci_resource_flags (pdev, 1);
6047 if (!(pmem_flags & IORESOURCE_MEM)) {
6048 RT_TRACE(COMP_ERR,"region #1 not a MMIO resource, aborting");
6052 //DMESG("Memory mapped space @ 0x%08lx ", pmem_start);
6053 if( ! request_mem_region(pmem_start, pmem_len, RTL819xE_MODULE_NAME)) {
6054 RT_TRACE(COMP_ERR,"request_mem_region failed!");
6059 ioaddr = (unsigned long)ioremap_nocache( pmem_start, pmem_len);
6060 if( ioaddr == (unsigned long)NULL ){
6061 RT_TRACE(COMP_ERR,"ioremap failed!");
6062 // release_mem_region( pmem_start, pmem_len );
6066 dev->mem_start = ioaddr; // shared mem start
6067 dev->mem_end = ioaddr + pci_resource_len(pdev, 0); // shared mem end
6069 #endif //end #ifdef RTL_IO_MAP
6071 /* We disable the RETRY_TIMEOUT register (0x41) to keep
6072 * PCI Tx retries from interfering with C3 CPU state */
6073 pci_write_config_byte(pdev, 0x41, 0x00);
6076 pci_read_config_byte(pdev, 0x05, &unit);
6077 pci_write_config_byte(pdev, 0x05, unit & (~0x04));
6079 dev->irq = pdev->irq;
6082 dev->netdev_ops = &rtl8192_netdev_ops;
6084 dev->open = rtl8192_open;
6085 dev->stop = rtl8192_close;
6086 //dev->hard_start_xmit = rtl8192_8023_hard_start_xmit;
6087 dev->tx_timeout = tx_timeout;
6088 //dev->wireless_handlers = &r8192_wx_handlers_def;
6089 dev->do_ioctl = rtl8192_ioctl;
6090 dev->set_multicast_list = r8192_set_multicast;
6091 dev->set_mac_address = r8192_set_mac_adr;
6094 //DMESG("Oops: i'm coming\n");
6095 #if WIRELESS_EXT >= 12
6096 #if WIRELESS_EXT < 17
6097 dev->get_wireless_stats = r8192_get_wireless_stats;
6099 dev->wireless_handlers = (struct iw_handler_def *) &r8192_wx_handlers_def;
6101 //dev->get_wireless_stats = r8192_get_wireless_stats;
6102 dev->type=ARPHRD_ETHER;
6104 dev->watchdog_timeo = HZ*3; //modified by john, 0805
6106 if (dev_alloc_name(dev, ifname) < 0){
6107 RT_TRACE(COMP_INIT, "Oops: devname already taken! Trying wlan%%d...\n");
6108 strcpy(ifname, "wlan%d");
6109 dev_alloc_name(dev, ifname);
6112 RT_TRACE(COMP_INIT, "Driver probe completed1\n");
6113 if(rtl8192_init(dev)!=0){
6114 RT_TRACE(COMP_ERR, "Initialization failed");
6118 netif_carrier_off(dev);
6119 netif_stop_queue(dev);
6121 register_netdev(dev);
6122 RT_TRACE(COMP_INIT, "dev name=======> %s\n",dev->name);
6123 rtl8192_proc_init_one(dev);
6126 RT_TRACE(COMP_INIT, "Driver probe completed\n");
6131 #ifdef CONFIG_RTL8180_IO_MAP
6133 if( dev->base_addr != 0 ){
6135 release_region(dev->base_addr,
6136 pci_resource_len(pdev, 0) );
6139 if( dev->mem_start != (unsigned long)NULL ){
6140 iounmap( (void *)dev->mem_start );
6141 release_mem_region( pci_resource_start(pdev, 1),
6142 pci_resource_len(pdev, 1) );
6144 #endif //end #ifdef RTL_IO_MAP
6150 free_irq(dev->irq, dev);
6153 free_ieee80211(dev);
6157 pci_disable_device(pdev);
6159 DMESG("wlan driver load failed\n");
6160 pci_set_drvdata(pdev, NULL);
6165 /* detach all the work and timer structure declared or inititialized
6166 * in r8192_init function.
6168 static void rtl8192_cancel_deferred_work(struct r8192_priv* priv)
6170 /* call cancel_work_sync instead of cancel_delayed_work if and only if Linux_version_code
6171 * is or is newer than 2.6.20 and work structure is defined to be struct work_struct.
6172 * Otherwise call cancel_delayed_work is enough.
6173 * FIXME (2.6.20 should 2.6.22, work_struct should not cancel)
6175 cancel_delayed_work(&priv->watch_dog_wq);
6176 cancel_delayed_work(&priv->update_beacon_wq);
6177 cancel_delayed_work(&priv->ieee80211->hw_wakeup_wq);
6178 cancel_delayed_work(&priv->ieee80211->hw_sleep_wq);
6180 cancel_delayed_work(&priv->gpio_change_rf_wq);
6182 cancel_work_sync(&priv->reset_wq);
6183 cancel_work_sync(&priv->qos_activate);
6184 //cancel_work_sync(&priv->SetBWModeWorkItem);
6185 //cancel_work_sync(&priv->SwChnlWorkItem);
6190 static void __devexit rtl8192_pci_disconnect(struct pci_dev *pdev)
6192 struct net_device *dev = pci_get_drvdata(pdev);
6193 struct r8192_priv *priv ;
6197 unregister_netdev(dev);
6199 priv=ieee80211_priv(dev);
6201 rtl8192_proc_remove_one(dev);
6204 if (priv->pFirmware)
6206 vfree(priv->pFirmware);
6207 priv->pFirmware = NULL;
6209 // priv->rf_close(dev);
6210 // rtl8192_usb_deleteendpoints(dev);
6211 destroy_workqueue(priv->priv_wq);
6212 /* redundant with rtl8192_down */
6213 // rtl8192_irq_disable(dev);
6214 // rtl8192_reset(dev);
6218 /* free tx/rx rings */
6219 rtl8192_free_rx_ring(dev);
6220 for (i = 0; i < MAX_TX_QUEUE_COUNT; i++) {
6221 rtl8192_free_tx_ring(dev, i);
6226 printk("Freeing irq %d\n",dev->irq);
6227 free_irq(dev->irq, dev);
6234 // free_beacon_desc_ring(dev,priv->txbeaconcount);
6236 #ifdef CONFIG_RTL8180_IO_MAP
6238 if( dev->base_addr != 0 ){
6240 release_region(dev->base_addr,
6241 pci_resource_len(pdev, 0) );
6244 if( dev->mem_start != (unsigned long)NULL ){
6245 iounmap( (void *)dev->mem_start );
6246 release_mem_region( pci_resource_start(pdev, 1),
6247 pci_resource_len(pdev, 1) );
6249 #endif /*end #ifdef RTL_IO_MAP*/
6250 free_ieee80211(dev);
6254 pci_disable_device(pdev);
6255 RT_TRACE(COMP_DOWN, "wlan driver removed\n");
6258 extern int ieee80211_rtl_init(void);
6259 extern void ieee80211_rtl_exit(void);
6261 static int __init rtl8192_pci_module_init(void)
6265 retval = ieee80211_rtl_init();
6269 printk(KERN_INFO "\nLinux kernel driver for RTL8192 based WLAN cards\n");
6270 printk(KERN_INFO "Copyright (c) 2007-2008, Realsil Wlan\n");
6271 RT_TRACE(COMP_INIT, "Initializing module");
6272 RT_TRACE(COMP_INIT, "Wireless extensions version %d", WIRELESS_EXT);
6273 rtl8192_proc_module_init();
6274 if(0!=pci_register_driver(&rtl8192_pci_driver))
6276 DMESG("No device found");
6277 /*pci_unregister_driver (&rtl8192_pci_driver);*/
6284 static void __exit rtl8192_pci_module_exit(void)
6286 pci_unregister_driver(&rtl8192_pci_driver);
6288 RT_TRACE(COMP_DOWN, "Exiting");
6289 rtl8192_proc_module_remove();
6290 ieee80211_rtl_exit();
6293 //warning message WB
6294 static irqreturn_t rtl8192_interrupt(int irq, void *netdev)
6296 struct net_device *dev = (struct net_device *) netdev;
6297 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
6298 unsigned long flags;
6300 /* We should return IRQ_NONE, but for now let me keep this */
6301 if(priv->irq_enabled == 0){
6305 spin_lock_irqsave(&priv->irq_th_lock,flags);
6309 inta = read_nic_dword(dev, ISR);// & priv->IntrMask;
6310 write_nic_dword(dev,ISR,inta); // reset int situation
6312 priv->stats.shints++;
6313 //DMESG("Enter interrupt, ISR value = 0x%08x", inta);
6315 spin_unlock_irqrestore(&priv->irq_th_lock,flags);
6318 most probably we can safely return IRQ_NONE,
6319 but for now is better to avoid problems
6325 spin_unlock_irqrestore(&priv->irq_th_lock,flags);
6331 DMESG("NIC irq %x",inta);
6333 //priv->irqpending = inta;
6336 if(!netif_running(dev)) {
6337 spin_unlock_irqrestore(&priv->irq_th_lock,flags);
6341 if(inta & IMR_TIMEOUT0){
6342 // write_nic_dword(dev, TimerInt, 0);
6343 //DMESG("=================>waking up");
6344 // rtl8180_hw_wakeup(dev);
6347 if(inta & IMR_TBDOK){
6348 RT_TRACE(COMP_INTR, "beacon ok interrupt!\n");
6349 rtl8192_tx_isr(dev, BEACON_QUEUE);
6350 priv->stats.txbeaconokint++;
6353 if(inta & IMR_TBDER){
6354 RT_TRACE(COMP_INTR, "beacon ok interrupt!\n");
6355 rtl8192_tx_isr(dev, BEACON_QUEUE);
6356 priv->stats.txbeaconerr++;
6359 if(inta & IMR_MGNTDOK ) {
6360 RT_TRACE(COMP_INTR, "Manage ok interrupt!\n");
6361 priv->stats.txmanageokint++;
6362 rtl8192_tx_isr(dev,MGNT_QUEUE);
6366 if(inta & IMR_COMDOK)
6368 priv->stats.txcmdpktokint++;
6369 rtl8192_tx_isr(dev,TXCMD_QUEUE);
6374 DMESG("Frame arrived !");
6376 priv->stats.rxint++;
6377 tasklet_schedule(&priv->irq_rx_tasklet);
6380 if(inta & IMR_BcnInt) {
6381 RT_TRACE(COMP_INTR, "prepare beacon for interrupt!\n");
6382 tasklet_schedule(&priv->irq_prepare_beacon_tasklet);
6386 RT_TRACE(COMP_INTR, "rx descriptor unavailable!\n");
6387 priv->stats.rxrdu++;
6388 /* reset int situation */
6389 write_nic_dword(dev,INTA_MASK,read_nic_dword(dev, INTA_MASK) & ~IMR_RDU);
6390 tasklet_schedule(&priv->irq_rx_tasklet);
6393 if(inta & IMR_RXFOVW){
6394 RT_TRACE(COMP_INTR, "rx overflow !\n");
6395 priv->stats.rxoverflow++;
6396 tasklet_schedule(&priv->irq_rx_tasklet);
6399 if(inta & IMR_TXFOVW) priv->stats.txoverflow++;
6401 if(inta & IMR_BKDOK){
6402 RT_TRACE(COMP_INTR, "BK Tx OK interrupt!\n");
6403 priv->stats.txbkokint++;
6404 priv->ieee80211->LinkDetectInfo.NumTxOkInPeriod++;
6405 rtl8192_tx_isr(dev,BK_QUEUE);
6406 rtl8192_try_wake_queue(dev, BK_QUEUE);
6409 if(inta & IMR_BEDOK){
6410 RT_TRACE(COMP_INTR, "BE TX OK interrupt!\n");
6411 priv->stats.txbeokint++;
6412 priv->ieee80211->LinkDetectInfo.NumTxOkInPeriod++;
6413 rtl8192_tx_isr(dev,BE_QUEUE);
6414 rtl8192_try_wake_queue(dev, BE_QUEUE);
6417 if(inta & IMR_VIDOK){
6418 RT_TRACE(COMP_INTR, "VI TX OK interrupt!\n");
6419 priv->stats.txviokint++;
6420 priv->ieee80211->LinkDetectInfo.NumTxOkInPeriod++;
6421 rtl8192_tx_isr(dev,VI_QUEUE);
6422 rtl8192_try_wake_queue(dev, VI_QUEUE);
6425 if(inta & IMR_VODOK){
6426 priv->stats.txvookint++;
6427 priv->ieee80211->LinkDetectInfo.NumTxOkInPeriod++;
6428 rtl8192_tx_isr(dev,VO_QUEUE);
6429 rtl8192_try_wake_queue(dev, VO_QUEUE);
6432 spin_unlock_irqrestore(&priv->irq_th_lock,flags);
6437 static void rtl8192_try_wake_queue(struct net_device *dev, int pri)
6442 void EnableHWSecurityConfig8192(struct net_device *dev)
6444 u8 SECR_value = 0x0;
6445 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
6446 struct ieee80211_device* ieee = priv->ieee80211;
6448 SECR_value = SCR_TxEncEnable | SCR_RxDecEnable;
6450 if (((KEY_TYPE_WEP40 == ieee->pairwise_key_type) || (KEY_TYPE_WEP104 == ieee->pairwise_key_type)) && (priv->ieee80211->auth_mode != 2))
6452 SECR_value |= SCR_RxUseDK;
6453 SECR_value |= SCR_TxUseDK;
6455 else if ((ieee->iw_mode == IW_MODE_ADHOC) && (ieee->pairwise_key_type & (KEY_TYPE_CCMP | KEY_TYPE_TKIP)))
6457 SECR_value |= SCR_RxUseDK;
6458 SECR_value |= SCR_TxUseDK;
6463 //add HWSec active enable here.
6464 //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
6465 ieee->hwsec_active = 1;
6467 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
6469 ieee->hwsec_active = 0;
6470 SECR_value &= ~SCR_RxDecEnable;
6473 RT_TRACE(COMP_SEC,"%s:, hwsec:%d, pairwise_key:%d, SECR_value:%x\n", __FUNCTION__,
6474 ieee->hwsec_active, ieee->pairwise_key_type, SECR_value);
6476 write_nic_byte(dev, SECR, SECR_value);//SECR_value | SCR_UseDK );
6480 #define TOTAL_CAM_ENTRY 32
6481 //#define CAM_CONTENT_COUNT 8
6482 void setKey( struct net_device *dev,
6490 u32 TargetCommand = 0;
6491 u32 TargetContent = 0;
6495 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
6496 RT_RF_POWER_STATE rtState;
6497 rtState = priv->ieee80211->eRFPowerState;
6498 if(priv->ieee80211->PowerSaveControl.bInactivePs){
6499 if(rtState == eRfOff){
6500 if(priv->ieee80211->RfOffReason > RF_CHANGE_BY_IPS)
6502 RT_TRACE(COMP_ERR, "%s(): RF is OFF.\n",__FUNCTION__);
6503 //up(&priv->wx_sem);
6507 down(&priv->ieee80211->ips_sem);
6509 up(&priv->ieee80211->ips_sem);
6513 priv->ieee80211->is_set_key = true;
6515 if (EntryNo >= TOTAL_CAM_ENTRY)
6516 RT_TRACE(COMP_ERR, "cam entry exceeds in setKey()\n");
6518 RT_TRACE(COMP_SEC, "====>to setKey(), dev:%p, EntryNo:%d, KeyIndex:%d, KeyType:%d, MacAddr%pM\n", dev,EntryNo, KeyIndex, KeyType, MacAddr);
6521 usConfig |= BIT15 | (KeyType<<2);
6523 usConfig |= BIT15 | (KeyType<<2) | KeyIndex;
6524 // usConfig |= BIT15 | (KeyType<<2) | (DefaultKey<<5) | KeyIndex;
6527 for(i=0 ; i<CAM_CONTENT_COUNT; i++){
6528 TargetCommand = i+CAM_CONTENT_COUNT*EntryNo;
6529 TargetCommand |= BIT31|BIT16;
6531 if(i==0){//MAC|Config
6532 TargetContent = (u32)(*(MacAddr+0)) << 16|
6533 (u32)(*(MacAddr+1)) << 24|
6536 write_nic_dword(dev, WCAMI, TargetContent);
6537 write_nic_dword(dev, RWCAM, TargetCommand);
6538 // printk("setkey cam =%8x\n", read_cam(dev, i+6*EntryNo));
6541 TargetContent = (u32)(*(MacAddr+2)) |
6542 (u32)(*(MacAddr+3)) << 8|
6543 (u32)(*(MacAddr+4)) << 16|
6544 (u32)(*(MacAddr+5)) << 24;
6545 write_nic_dword(dev, WCAMI, TargetContent);
6546 write_nic_dword(dev, RWCAM, TargetCommand);
6548 else { //Key Material
6549 if(KeyContent != NULL)
6551 write_nic_dword(dev, WCAMI, (u32)(*(KeyContent+i-2)) );
6552 write_nic_dword(dev, RWCAM, TargetCommand);
6556 RT_TRACE(COMP_SEC,"=========>after set key, usconfig:%x\n", usConfig);
6559 bool NicIFEnableNIC(struct net_device* dev)
6561 RT_STATUS init_status = RT_STATUS_SUCCESS;
6562 struct r8192_priv* priv = ieee80211_priv(dev);
6563 PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->ieee80211->PowerSaveControl));
6567 RT_TRACE(COMP_ERR, "ERR!!! %s(): Driver is already down!\n",__FUNCTION__);
6568 priv->bdisable_nic = false; //YJ,add,091111
6571 // <1> Reset memory: descriptor, buffer,..
6572 //NicIFResetMemory(Adapter);
6574 // <2> Enable Adapter
6575 //priv->bfirst_init = true;
6576 init_status = rtl8192_adapter_start(dev);
6577 if (init_status != RT_STATUS_SUCCESS) {
6578 RT_TRACE(COMP_ERR,"ERR!!! %s(): initialization is failed!\n",__FUNCTION__);
6579 priv->bdisable_nic = false; //YJ,add,091111
6582 //printk("start adapter finished\n");
6583 RT_CLEAR_PS_LEVEL(pPSC, RT_RF_OFF_LEVL_HALT_NIC);
6584 //priv->bfirst_init = false;
6586 // <3> Enable Interrupt
6587 rtl8192_irq_enable(dev);
6588 priv->bdisable_nic = false;
6590 return (init_status == RT_STATUS_SUCCESS);
6593 bool NicIFDisableNIC(struct net_device* dev)
6596 struct r8192_priv* priv = ieee80211_priv(dev);
6598 // <1> Disable Interrupt
6600 priv->bdisable_nic = true; //YJ,move,091109
6601 tmp_state = priv->ieee80211->state;
6603 ieee80211_softmac_stop_protocol(priv->ieee80211, false);
6605 priv->ieee80211->state = tmp_state;
6606 rtl8192_cancel_deferred_work(priv);
6607 rtl8192_irq_disable(dev);
6608 // <2> Stop all timer
6610 // <3> Disable Adapter
6611 rtl8192_halt_adapter(dev, false);
6612 // priv->bdisable_nic = true;
6617 module_init(rtl8192_pci_module_init);
6618 module_exit(rtl8192_pci_module_exit);