Staging: rtl8192e: Fix typo in enum name
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / drivers / staging / rtl8192e / r8192E_core.c
blob044e226fe9ab1715028ce378be06dc0a263205ad
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
14 * more details.
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
29 #undef DEBUG_EPROM
30 #undef DEBUG_RX_VERBOSE
31 #undef DUMMY_RX
32 #undef DEBUG_ZERO_RX
33 #undef DEBUG_RX_SKB
34 #undef DEBUG_TX_FRAG
35 #undef DEBUG_RX_FRAG
36 #undef DEBUG_TX_FILLDESC
37 #undef DEBUG_TX
38 #undef DEBUG_IRQ
39 #undef DEBUG_RX
40 #undef DEBUG_RXALLOC
41 #undef DEBUG_REGISTERS
42 #undef DEBUG_RING
43 #undef DEBUG_IRQ_TASKLET
44 #undef DEBUG_TX_ALLOC
45 #undef DEBUG_TX_DESC
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"
52 #include "r8192E.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"
61 #ifdef CONFIG_PM
62 #include "r8192_pm.h"
63 #endif
65 #ifdef ENABLE_DOT11D
66 #include "ieee80211/dot11d.h"
67 #endif
69 //set here to open your trace code. //WB
70 u32 rt_global_debug_component =
71 // COMP_INIT |
72 // COMP_EPROM |
73 // COMP_PHY |
74 // COMP_RF |
75 // COMP_FIRMWARE |
76 // COMP_TRACE |
77 // COMP_DOWN |
78 // COMP_SWBW |
79 // COMP_SEC |
80 // COMP_QOS |
81 // COMP_RATE |
82 // COMP_RECV |
83 // COMP_SEND |
84 // COMP_POWER |
85 // COMP_EVENTS |
86 // COMP_RESET |
87 // COMP_CMDPKT |
88 // COMP_POWER_TRACKING |
89 // COMP_INTR |
90 COMP_ERR ; //always open err flags on
92 static DEFINE_PCI_DEVICE_TABLE(rtl8192_pci_id_tbl) = {
93 #ifdef RTL8190P
94 /* Realtek */
95 /* Dlink */
96 { PCI_DEVICE(0x10ec, 0x8190) },
97 /* Corega */
98 { PCI_DEVICE(0x07aa, 0x0045) },
99 { PCI_DEVICE(0x07aa, 0x0046) },
100 #else
101 /* Realtek */
102 { PCI_DEVICE(0x10ec, 0x8192) },
104 /* Corega */
105 { PCI_DEVICE(0x07aa, 0x0044) },
106 { PCI_DEVICE(0x07aa, 0x0047) },
107 #endif
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 */
139 #ifdef CONFIG_PM
140 .suspend = rtl8192E_suspend, /* PM suspend fn */
141 .resume = rtl8192E_resume, /* PM resume fn */
142 #else
143 .suspend = NULL, /* PM suspend fn */
144 .resume = NULL, /* PM resume fn */
145 #endif
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 rtl819xE_tx_cmd(struct net_device *dev, struct sk_buff *skb);
156 static void rtl8192_update_ratr_table(struct net_device* dev);
157 static void rtl8192_restart(struct work_struct *work);
158 static void watch_dog_timer_callback(unsigned long data);
159 static int _rtl8192_up(struct net_device *dev);
160 static void rtl8192_cancel_deferred_work(struct r8192_priv* priv);
162 #ifdef ENABLE_DOT11D
164 typedef struct _CHANNEL_LIST
166 u8 Channel[32];
167 u8 Len;
168 }CHANNEL_LIST, *PCHANNEL_LIST;
170 static const CHANNEL_LIST ChannelPlan[] = {
171 {{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
172 {{1,2,3,4,5,6,7,8,9,10,11},11}, //IC
173 {{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48,52,56,60,64},21}, //ETSI
174 {{1,2,3,4,5,6,7,8,9,10,11,12,13},13}, //Spain. Change to ETSI.
175 {{1,2,3,4,5,6,7,8,9,10,11,12,13},13}, //France. Change to ETSI.
176 {{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
177 {{1,2,3,4,5,6,7,8,9,10,11,12,13,14,36,40,44,48,52,56,60,64},22},//MKK1
178 {{1,2,3,4,5,6,7,8,9,10,11,12,13},13}, //Israel.
179 {{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
180 {{1,2,3,4,5,6,7,8,9,10,11,12,13,14,36,40,44,48,52,56,60,64}, 22}, //MIC
181 {{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
184 static void rtl819x_set_channel_map(u8 channel_plan, struct r8192_priv* priv)
186 int i, max_chan=-1, min_chan=-1;
187 struct ieee80211_device* ieee = priv->ieee80211;
188 switch (channel_plan)
190 case COUNTRY_CODE_FCC:
191 case COUNTRY_CODE_IC:
192 case COUNTRY_CODE_ETSI:
193 case COUNTRY_CODE_SPAIN:
194 case COUNTRY_CODE_FRANCE:
195 case COUNTRY_CODE_MKK:
196 case COUNTRY_CODE_MKK1:
197 case COUNTRY_CODE_ISRAEL:
198 case COUNTRY_CODE_TELEC:
199 case COUNTRY_CODE_MIC:
201 Dot11d_Init(ieee);
202 ieee->bGlobalDomain = false;
203 //acturally 8225 & 8256 rf chip only support B,G,24N mode
204 if ((priv->rf_chip == RF_8225) || (priv->rf_chip == RF_8256))
206 min_chan = 1;
207 max_chan = 14;
209 else
211 RT_TRACE(COMP_ERR, "unknown rf chip, can't set channel map in function:%s()\n", __FUNCTION__);
213 if (ChannelPlan[channel_plan].Len != 0){
214 // Clear old channel map
215 memset(GET_DOT11D_INFO(ieee)->channel_map, 0, sizeof(GET_DOT11D_INFO(ieee)->channel_map));
216 // Set new channel map
217 for (i=0;i<ChannelPlan[channel_plan].Len;i++)
219 if (ChannelPlan[channel_plan].Channel[i] < min_chan || ChannelPlan[channel_plan].Channel[i] > max_chan)
220 break;
221 GET_DOT11D_INFO(ieee)->channel_map[ChannelPlan[channel_plan].Channel[i]] = 1;
224 break;
226 case COUNTRY_CODE_GLOBAL_DOMAIN:
228 GET_DOT11D_INFO(ieee)->bEnabled = 0; //this flag enabled to follow 11d country IE setting, otherwise, it shall follow global domain setting
229 Dot11d_Reset(ieee);
230 ieee->bGlobalDomain = true;
231 break;
233 default:
234 break;
237 #endif
239 static inline bool rx_hal_is_cck_rate(prx_fwinfo_819x_pci pdrvinfo)
241 return (pdrvinfo->RxRate == DESC90_RATE1M ||
242 pdrvinfo->RxRate == DESC90_RATE2M ||
243 pdrvinfo->RxRate == DESC90_RATE5_5M ||
244 pdrvinfo->RxRate == DESC90_RATE11M) &&
245 !pdrvinfo->RxHT;
248 void CamResetAllEntry(struct net_device *dev)
250 write_nic_dword(dev, RWCAM, BIT31|BIT30);
254 void write_cam(struct net_device *dev, u8 addr, u32 data)
256 write_nic_dword(dev, WCAMI, data);
257 write_nic_dword(dev, RWCAM, BIT31|BIT16|(addr&0xff) );
259 u32 read_cam(struct net_device *dev, u8 addr)
261 write_nic_dword(dev, RWCAM, 0x80000000|(addr&0xff) );
262 return read_nic_dword(dev, 0xa8);
265 #ifdef CONFIG_RTL8180_IO_MAP
267 u8 read_nic_byte(struct net_device *dev, int x)
269 return 0xff&inb(dev->base_addr +x);
272 u32 read_nic_dword(struct net_device *dev, int x)
274 return inl(dev->base_addr +x);
277 u16 read_nic_word(struct net_device *dev, int x)
279 return inw(dev->base_addr +x);
282 void write_nic_byte(struct net_device *dev, int x,u8 y)
284 outb(y&0xff,dev->base_addr +x);
287 void write_nic_word(struct net_device *dev, int x,u16 y)
289 outw(y,dev->base_addr +x);
292 void write_nic_dword(struct net_device *dev, int x,u32 y)
294 outl(y,dev->base_addr +x);
297 #else /* RTL_IO_MAP */
299 u8 read_nic_byte(struct net_device *dev, int x)
301 return 0xff&readb((u8*)dev->mem_start +x);
304 u32 read_nic_dword(struct net_device *dev, int x)
306 return readl((u8*)dev->mem_start +x);
309 u16 read_nic_word(struct net_device *dev, int x)
311 return readw((u8*)dev->mem_start +x);
314 void write_nic_byte(struct net_device *dev, int x,u8 y)
316 writeb(y,(u8*)dev->mem_start +x);
317 udelay(20);
320 void write_nic_dword(struct net_device *dev, int x,u32 y)
322 writel(y,(u8*)dev->mem_start +x);
323 udelay(20);
326 void write_nic_word(struct net_device *dev, int x,u16 y)
328 writew(y,(u8*)dev->mem_start +x);
329 udelay(20);
332 #endif /* RTL_IO_MAP */
334 u8 rtl8192e_ap_sec_type(struct ieee80211_device *ieee)
336 static const u8 ccmp_ie[4] = {0x00,0x50,0xf2,0x04};
337 static const u8 ccmp_rsn_ie[4] = {0x00, 0x0f, 0xac, 0x04};
338 int wpa_ie_len= ieee->wpa_ie_len;
339 struct ieee80211_crypt_data* crypt;
340 int encrypt;
342 crypt = ieee->crypt[ieee->tx_keyidx];
344 encrypt = (ieee->current_network.capability & WLAN_CAPABILITY_PRIVACY) ||
345 (ieee->host_encrypt && crypt && crypt->ops &&
346 (0 == strcmp(crypt->ops->name,"WEP")));
348 /* simply judge */
349 if(encrypt && (wpa_ie_len == 0)) {
350 // wep encryption, no N mode setting */
351 return SEC_ALG_WEP;
352 } else if((wpa_ie_len != 0)) {
353 // parse pairwise key type */
354 if (((ieee->wpa_ie[0] == 0xdd) && (!memcmp(&(ieee->wpa_ie[14]),ccmp_ie,4))) ||
355 ((ieee->wpa_ie[0] == 0x30) && (!memcmp(&ieee->wpa_ie[10],ccmp_rsn_ie, 4))))
356 return SEC_ALG_CCMP;
357 else
358 return SEC_ALG_TKIP;
359 } else {
360 return SEC_ALG_NONE;
364 void
365 rtl8192e_SetHwReg(struct net_device *dev,u8 variable,u8* val)
367 struct r8192_priv* priv = ieee80211_priv(dev);
369 switch(variable)
372 case HW_VAR_BSSID:
373 write_nic_dword(dev, BSSIDR, ((u32*)(val))[0]);
374 write_nic_word(dev, BSSIDR+2, ((u16*)(val+2))[0]);
375 break;
377 case HW_VAR_MEDIA_STATUS:
379 RT_OP_MODE OpMode = *((RT_OP_MODE *)(val));
380 u8 btMsr = read_nic_byte(dev, MSR);
382 btMsr &= 0xfc;
384 switch(OpMode)
386 case RT_OP_MODE_INFRASTRUCTURE:
387 btMsr |= MSR_INFRA;
388 break;
390 case RT_OP_MODE_IBSS:
391 btMsr |= MSR_ADHOC;
392 break;
394 case RT_OP_MODE_AP:
395 btMsr |= MSR_AP;
396 break;
398 default:
399 btMsr |= MSR_NOLINK;
400 break;
403 write_nic_byte(dev, MSR, btMsr);
405 break;
407 case HW_VAR_CHECK_BSSID:
409 u32 RegRCR, Type;
411 Type = ((u8*)(val))[0];
412 RegRCR = read_nic_dword(dev,RCR);
413 priv->ReceiveConfig = RegRCR;
415 if (Type == true)
416 RegRCR |= (RCR_CBSSID);
417 else if (Type == false)
418 RegRCR &= (~RCR_CBSSID);
420 write_nic_dword(dev, RCR,RegRCR);
421 priv->ReceiveConfig = RegRCR;
424 break;
426 case HW_VAR_SLOT_TIME:
428 priv->slot_time = val[0];
429 write_nic_byte(dev, SLOT_TIME, val[0]);
432 break;
434 case HW_VAR_ACK_PREAMBLE:
436 u32 regTmp = 0;
437 priv->short_preamble = (bool)(*(u8*)val );
438 regTmp = priv->basic_rate;
439 if (priv->short_preamble)
440 regTmp |= BRSR_AckShortPmb;
441 write_nic_dword(dev, RRSR, regTmp);
443 break;
445 case HW_VAR_CPU_RST:
446 write_nic_dword(dev, CPU_GEN, ((u32*)(val))[0]);
447 break;
449 default:
450 break;
455 static struct proc_dir_entry *rtl8192_proc = NULL;
457 static int proc_get_stats_ap(char *page, char **start,
458 off_t offset, int count,
459 int *eof, void *data)
461 struct net_device *dev = data;
462 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
463 struct ieee80211_device *ieee = priv->ieee80211;
464 struct ieee80211_network *target;
465 int len = 0;
467 list_for_each_entry(target, &ieee->network_list, list) {
469 len += snprintf(page + len, count - len,
470 "%s ", target->ssid);
472 if(target->wpa_ie_len>0 || target->rsn_ie_len>0){
473 len += snprintf(page + len, count - len,
474 "WPA\n");
476 else{
477 len += snprintf(page + len, count - len,
478 "non_WPA\n");
483 *eof = 1;
484 return len;
487 static int proc_get_registers(char *page, char **start,
488 off_t offset, int count,
489 int *eof, void *data)
491 struct net_device *dev = data;
492 int len = 0;
493 int i,n;
494 int max=0xff;
496 /* This dump the current register page */
497 len += snprintf(page + len, count - len,
498 "\n####################page 0##################\n ");
500 for(n=0;n<=max;)
502 len += snprintf(page + len, count - len,
503 "\nD: %2x > ",n);
505 for(i=0;i<16 && n<=max;i++,n++)
506 len += snprintf(page + len, count - len,
507 "%2x ",read_nic_byte(dev,n));
509 len += snprintf(page + len, count - len,"\n");
510 len += snprintf(page + len, count - len,
511 "\n####################page 1##################\n ");
512 for(n=0;n<=max;)
514 len += snprintf(page + len, count - len,
515 "\nD: %2x > ",n);
517 for(i=0;i<16 && n<=max;i++,n++)
518 len += snprintf(page + len, count - len,
519 "%2x ",read_nic_byte(dev,0x100|n));
522 len += snprintf(page + len, count - len,
523 "\n####################page 3##################\n ");
524 for(n=0;n<=max;)
526 len += snprintf(page + len, count - len,
527 "\nD: %2x > ",n);
529 for(i=0;i<16 && n<=max;i++,n++)
530 len += snprintf(page + len, count - len,
531 "%2x ",read_nic_byte(dev,0x300|n));
534 *eof = 1;
535 return len;
539 static int proc_get_stats_tx(char *page, char **start,
540 off_t offset, int count,
541 int *eof, void *data)
543 struct net_device *dev = data;
544 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
546 int len = 0;
548 len += snprintf(page + len, count - len,
549 "TX VI priority ok int: %lu\n"
550 // "TX VI priority error int: %lu\n"
551 "TX VO priority ok int: %lu\n"
552 // "TX VO priority error int: %lu\n"
553 "TX BE priority ok int: %lu\n"
554 // "TX BE priority error int: %lu\n"
555 "TX BK priority ok int: %lu\n"
556 // "TX BK priority error int: %lu\n"
557 "TX MANAGE priority ok int: %lu\n"
558 // "TX MANAGE priority error int: %lu\n"
559 "TX BEACON priority ok int: %lu\n"
560 "TX BEACON priority error int: %lu\n"
561 "TX CMDPKT priority ok int: %lu\n"
562 // "TX high priority ok int: %lu\n"
563 // "TX high priority failed error int: %lu\n"
564 // "TX queue resume: %lu\n"
565 "TX queue stopped?: %d\n"
566 "TX fifo overflow: %lu\n"
567 // "TX beacon: %lu\n"
568 // "TX VI queue: %d\n"
569 // "TX VO queue: %d\n"
570 // "TX BE queue: %d\n"
571 // "TX BK queue: %d\n"
572 // "TX HW queue: %d\n"
573 // "TX VI dropped: %lu\n"
574 // "TX VO dropped: %lu\n"
575 // "TX BE dropped: %lu\n"
576 // "TX BK dropped: %lu\n"
577 "TX total data packets %lu\n"
578 "TX total data bytes :%lu\n",
579 // "TX beacon aborted: %lu\n",
580 priv->stats.txviokint,
581 // priv->stats.txvierr,
582 priv->stats.txvookint,
583 // priv->stats.txvoerr,
584 priv->stats.txbeokint,
585 // priv->stats.txbeerr,
586 priv->stats.txbkokint,
587 // priv->stats.txbkerr,
588 priv->stats.txmanageokint,
589 // priv->stats.txmanageerr,
590 priv->stats.txbeaconokint,
591 priv->stats.txbeaconerr,
592 priv->stats.txcmdpktokint,
593 // priv->stats.txhpokint,
594 // priv->stats.txhperr,
595 // priv->stats.txresumed,
596 netif_queue_stopped(dev),
597 priv->stats.txoverflow,
598 // priv->stats.txbeacon,
599 // atomic_read(&(priv->tx_pending[VI_QUEUE])),
600 // atomic_read(&(priv->tx_pending[VO_QUEUE])),
601 // atomic_read(&(priv->tx_pending[BE_QUEUE])),
602 // atomic_read(&(priv->tx_pending[BK_QUEUE])),
603 // read_nic_byte(dev, TXFIFOCOUNT),
604 // priv->stats.txvidrop,
605 // priv->stats.txvodrop,
606 priv->ieee80211->stats.tx_packets,
607 priv->ieee80211->stats.tx_bytes
610 // priv->stats.txbedrop,
611 // priv->stats.txbkdrop
612 // priv->stats.txdatapkt
613 // priv->stats.txbeaconerr
616 *eof = 1;
617 return len;
622 static int proc_get_stats_rx(char *page, char **start,
623 off_t offset, int count,
624 int *eof, void *data)
626 struct net_device *dev = data;
627 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
629 int len = 0;
631 len += snprintf(page + len, count - len,
632 "RX packets: %lu\n"
633 "RX desc err: %lu\n"
634 "RX rx overflow error: %lu\n"
635 "RX invalid urb error: %lu\n",
636 priv->stats.rxint,
637 priv->stats.rxrdu,
638 priv->stats.rxoverflow,
639 priv->stats.rxurberr);
641 *eof = 1;
642 return len;
645 static void rtl8192_proc_module_init(void)
647 RT_TRACE(COMP_INIT, "Initializing proc filesystem");
648 rtl8192_proc=create_proc_entry(RTL819xE_MODULE_NAME, S_IFDIR, init_net.proc_net);
652 static void rtl8192_proc_module_remove(void)
654 remove_proc_entry(RTL819xE_MODULE_NAME, init_net.proc_net);
658 static void rtl8192_proc_remove_one(struct net_device *dev)
660 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
662 printk("dev name=======> %s\n",dev->name);
664 if (priv->dir_dev) {
665 // remove_proc_entry("stats-hw", priv->dir_dev);
666 remove_proc_entry("stats-tx", priv->dir_dev);
667 remove_proc_entry("stats-rx", priv->dir_dev);
668 // remove_proc_entry("stats-ieee", priv->dir_dev);
669 remove_proc_entry("stats-ap", priv->dir_dev);
670 remove_proc_entry("registers", priv->dir_dev);
671 // remove_proc_entry("cck-registers",priv->dir_dev);
672 // remove_proc_entry("ofdm-registers",priv->dir_dev);
673 //remove_proc_entry(dev->name, rtl8192_proc);
674 remove_proc_entry("wlan0", rtl8192_proc);
675 priv->dir_dev = NULL;
680 static void rtl8192_proc_init_one(struct net_device *dev)
682 struct proc_dir_entry *e;
683 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
684 priv->dir_dev = create_proc_entry(dev->name,
685 S_IFDIR | S_IRUGO | S_IXUGO,
686 rtl8192_proc);
687 if (!priv->dir_dev) {
688 RT_TRACE(COMP_ERR, "Unable to initialize /proc/net/rtl8192/%s\n",
689 dev->name);
690 return;
692 e = create_proc_read_entry("stats-rx", S_IFREG | S_IRUGO,
693 priv->dir_dev, proc_get_stats_rx, dev);
695 if (!e) {
696 RT_TRACE(COMP_ERR,"Unable to initialize "
697 "/proc/net/rtl8192/%s/stats-rx\n",
698 dev->name);
702 e = create_proc_read_entry("stats-tx", S_IFREG | S_IRUGO,
703 priv->dir_dev, proc_get_stats_tx, dev);
705 if (!e) {
706 RT_TRACE(COMP_ERR, "Unable to initialize "
707 "/proc/net/rtl8192/%s/stats-tx\n",
708 dev->name);
711 e = create_proc_read_entry("stats-ap", S_IFREG | S_IRUGO,
712 priv->dir_dev, proc_get_stats_ap, dev);
714 if (!e) {
715 RT_TRACE(COMP_ERR, "Unable to initialize "
716 "/proc/net/rtl8192/%s/stats-ap\n",
717 dev->name);
720 e = create_proc_read_entry("registers", S_IFREG | S_IRUGO,
721 priv->dir_dev, proc_get_registers, dev);
722 if (!e) {
723 RT_TRACE(COMP_ERR, "Unable to initialize "
724 "/proc/net/rtl8192/%s/registers\n",
725 dev->name);
729 short check_nic_enough_desc(struct net_device *dev, int prio)
731 struct r8192_priv *priv = ieee80211_priv(dev);
732 struct rtl8192_tx_ring *ring = &priv->tx_ring[prio];
734 /* for now we reserve two free descriptor as a safety boundary
735 * between the tail and the head
737 return (ring->entries - skb_queue_len(&ring->queue) >= 2);
740 static void tx_timeout(struct net_device *dev)
742 struct r8192_priv *priv = ieee80211_priv(dev);
744 schedule_work(&priv->reset_wq);
745 printk("TXTIMEOUT");
748 static void rtl8192_irq_enable(struct net_device *dev)
750 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
751 priv->irq_enabled = 1;
752 write_nic_dword(dev,INTA_MASK, priv->irq_mask);
755 void rtl8192_irq_disable(struct net_device *dev)
757 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
759 write_nic_dword(dev,INTA_MASK,0);
760 priv->irq_enabled = 0;
763 void rtl8192_update_msr(struct net_device *dev)
765 struct r8192_priv *priv = ieee80211_priv(dev);
766 u8 msr;
768 msr = read_nic_byte(dev, MSR);
769 msr &= ~ MSR_LINK_MASK;
771 /* do not change in link_state != WLAN_LINK_ASSOCIATED.
772 * msr must be updated if the state is ASSOCIATING.
773 * this is intentional and make sense for ad-hoc and
774 * master (see the create BSS/IBSS func)
776 if (priv->ieee80211->state == IEEE80211_LINKED){
778 if (priv->ieee80211->iw_mode == IW_MODE_INFRA)
779 msr |= (MSR_LINK_MANAGED<<MSR_LINK_SHIFT);
780 else if (priv->ieee80211->iw_mode == IW_MODE_ADHOC)
781 msr |= (MSR_LINK_ADHOC<<MSR_LINK_SHIFT);
782 else if (priv->ieee80211->iw_mode == IW_MODE_MASTER)
783 msr |= (MSR_LINK_MASTER<<MSR_LINK_SHIFT);
785 }else
786 msr |= (MSR_LINK_NONE<<MSR_LINK_SHIFT);
788 write_nic_byte(dev, MSR, msr);
791 void rtl8192_set_chan(struct net_device *dev,short ch)
793 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
795 priv->chan = ch;
797 /* need to implement rf set channel here WB */
799 if (priv->rf_set_chan)
800 priv->rf_set_chan(dev, priv->chan);
803 void rtl8192_rx_enable(struct net_device *dev)
805 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
807 write_nic_dword(dev, RDQDA,priv->rx_ring_dma);
810 /* the TX_DESC_BASE setting is according to the following queue index
811 * BK_QUEUE ===> 0
812 * BE_QUEUE ===> 1
813 * VI_QUEUE ===> 2
814 * VO_QUEUE ===> 3
815 * HCCA_QUEUE ===> 4
816 * TXCMD_QUEUE ===> 5
817 * MGNT_QUEUE ===> 6
818 * HIGH_QUEUE ===> 7
819 * BEACON_QUEUE ===> 8
820 * */
821 static const u32 TX_DESC_BASE[] = {BKQDA, BEQDA, VIQDA, VOQDA, HCCAQDA, CQDA, MQDA, HQDA, BQDA};
822 void rtl8192_tx_enable(struct net_device *dev)
824 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
825 u32 i;
827 for (i = 0; i < MAX_TX_QUEUE_COUNT; i++)
828 write_nic_dword(dev, TX_DESC_BASE[i], priv->tx_ring[i].dma);
830 ieee80211_reset_queue(priv->ieee80211);
834 static void rtl8192_free_rx_ring(struct net_device *dev)
836 struct r8192_priv *priv = ieee80211_priv(dev);
837 int i;
839 for (i = 0; i < priv->rxringcount; i++) {
840 struct sk_buff *skb = priv->rx_buf[i];
841 if (!skb)
842 continue;
844 pci_unmap_single(priv->pdev,
845 *((dma_addr_t *)skb->cb),
846 priv->rxbuffersize, PCI_DMA_FROMDEVICE);
847 kfree_skb(skb);
850 pci_free_consistent(priv->pdev, sizeof(*priv->rx_ring) * priv->rxringcount,
851 priv->rx_ring, priv->rx_ring_dma);
852 priv->rx_ring = NULL;
855 static void rtl8192_free_tx_ring(struct net_device *dev, unsigned int prio)
857 struct r8192_priv *priv = ieee80211_priv(dev);
858 struct rtl8192_tx_ring *ring = &priv->tx_ring[prio];
860 while (skb_queue_len(&ring->queue)) {
861 tx_desc_819x_pci *entry = &ring->desc[ring->idx];
862 struct sk_buff *skb = __skb_dequeue(&ring->queue);
864 pci_unmap_single(priv->pdev, le32_to_cpu(entry->TxBuffAddr),
865 skb->len, PCI_DMA_TODEVICE);
866 kfree_skb(skb);
867 ring->idx = (ring->idx + 1) % ring->entries;
870 pci_free_consistent(priv->pdev, sizeof(*ring->desc)*ring->entries,
871 ring->desc, ring->dma);
872 ring->desc = NULL;
875 void PHY_SetRtl8192eRfOff(struct net_device* dev)
877 //disable RF-Chip A/B
878 rtl8192_setBBreg(dev, rFPGA0_XA_RFInterfaceOE, BIT4, 0x0);
879 //analog to digital off, for power save
880 rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0x300, 0x0);
881 //digital to analog off, for power save
882 rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x18, 0x0);
883 //rx antenna off
884 rtl8192_setBBreg(dev, rOFDM0_TRxPathEnable, 0xf, 0x0);
885 //rx antenna off
886 rtl8192_setBBreg(dev, rOFDM1_TRxPathEnable, 0xf, 0x0);
887 //analog to digital part2 off, for power save
888 rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x60, 0x0);
889 rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x4, 0x0);
890 // Analog parameter!!Change bias and Lbus control.
891 write_nic_byte(dev, ANAPAR_FOR_8192PciE, 0x07);
895 void rtl8192_halt_adapter(struct net_device *dev, bool reset)
897 struct r8192_priv *priv = ieee80211_priv(dev);
898 int i;
899 u8 OpMode;
900 u32 ulRegRead;
902 OpMode = RT_OP_MODE_NO_LINK;
903 priv->ieee80211->SetHwRegHandler(dev, HW_VAR_MEDIA_STATUS, &OpMode);
905 if (!priv->ieee80211->bSupportRemoteWakeUp) {
907 * disable tx/rx. In 8185 we write 0x10 (Reset bit),
908 * but here we make reference to WMAC and wirte 0x0
910 write_nic_byte(dev, CMDR, 0);
913 mdelay(20);
915 if (!reset) {
916 mdelay(150);
918 #ifdef RTL8192E
919 priv->bHwRfOffAction = 2;
920 #endif
923 * Call MgntActSet_RF_State instead to
924 * prevent RF config race condition.
926 if (!priv->ieee80211->bSupportRemoteWakeUp) {
927 PHY_SetRtl8192eRfOff(dev);
928 ulRegRead = read_nic_dword(dev,CPU_GEN);
929 ulRegRead |= CPU_GEN_SYSTEM_RESET;
930 write_nic_dword(dev,CPU_GEN, ulRegRead);
931 } else {
932 /* for WOL */
933 write_nic_dword(dev, WFCRC0, 0xffffffff);
934 write_nic_dword(dev, WFCRC1, 0xffffffff);
935 write_nic_dword(dev, WFCRC2, 0xffffffff);
937 /* Write PMR register */
938 write_nic_byte(dev, PMR, 0x5);
939 /* Disable tx, enanble rx */
940 write_nic_byte(dev, MacBlkCtrl, 0xa);
944 for(i = 0; i < MAX_QUEUE_SIZE; i++) {
945 skb_queue_purge(&priv->ieee80211->skb_waitQ [i]);
947 for(i = 0; i < MAX_QUEUE_SIZE; i++) {
948 skb_queue_purge(&priv->ieee80211->skb_aggQ [i]);
951 skb_queue_purge(&priv->skb_queue);
954 static const u16 rtl_rate[] = {10,20,55,110,60,90,120,180,240,360,480,540};
955 inline u16 rtl8192_rate2rate(short rate)
957 if (rate >11) return 0;
958 return rtl_rate[rate];
961 static void rtl8192_data_hard_stop(struct net_device *dev)
965 static void rtl8192_data_hard_resume(struct net_device *dev)
970 * this function TX data frames when the ieee80211 stack requires this.
971 * It checks also if we need to stop the ieee tx queue, eventually do it
973 static void rtl8192_hard_data_xmit(struct sk_buff *skb, struct net_device *dev, int rate)
975 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
976 int ret;
977 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
978 u8 queue_index = tcb_desc->queue_index;
980 /* shall not be referred by command packet */
981 BUG_ON(queue_index == TXCMD_QUEUE);
983 if (priv->bHwRadioOff || (!priv->up))
985 kfree_skb(skb);
986 return;
989 memcpy(skb->cb, &dev, sizeof(dev));
991 skb_push(skb, priv->ieee80211->tx_headroom);
992 ret = rtl8192_tx(dev, skb);
993 if (ret != 0) {
994 kfree_skb(skb);
997 if (queue_index != MGNT_QUEUE) {
998 priv->ieee80211->stats.tx_bytes += (skb->len - priv->ieee80211->tx_headroom);
999 priv->ieee80211->stats.tx_packets++;
1004 * This is a rough attempt to TX a frame
1005 * This is called by the ieee 80211 stack to TX management frames.
1006 * If the ring is full packet are dropped (for data frame the queue
1007 * is stopped before this can happen).
1009 static int rtl8192_hard_start_xmit(struct sk_buff *skb,struct net_device *dev)
1011 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1012 int ret;
1013 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1014 u8 queue_index = tcb_desc->queue_index;
1016 if (queue_index != TXCMD_QUEUE) {
1017 if (priv->bHwRadioOff || (!priv->up))
1019 kfree_skb(skb);
1020 return 0;
1024 memcpy(skb->cb, &dev, sizeof(dev));
1025 if (queue_index == TXCMD_QUEUE) {
1026 rtl819xE_tx_cmd(dev, skb);
1027 ret = 0;
1028 return ret;
1029 } else {
1030 tcb_desc->RATRIndex = 7;
1031 tcb_desc->bTxDisableRateFallBack = 1;
1032 tcb_desc->bTxUseDriverAssingedRate = 1;
1033 tcb_desc->bTxEnableFwCalcDur = 1;
1034 skb_push(skb, priv->ieee80211->tx_headroom);
1035 ret = rtl8192_tx(dev, skb);
1036 if (ret != 0) {
1037 kfree_skb(skb);
1041 return ret;
1045 static void rtl8192_tx_isr(struct net_device *dev, int prio)
1047 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1048 struct rtl8192_tx_ring *ring = &priv->tx_ring[prio];
1050 while (skb_queue_len(&ring->queue)) {
1051 tx_desc_819x_pci *entry = &ring->desc[ring->idx];
1052 struct sk_buff *skb;
1055 * beacon packet will only use the first descriptor defaultly,
1056 * and the OWN may not be cleared by the hardware
1058 if (prio != BEACON_QUEUE) {
1059 if (entry->OWN)
1060 return;
1061 ring->idx = (ring->idx + 1) % ring->entries;
1064 skb = __skb_dequeue(&ring->queue);
1065 pci_unmap_single(priv->pdev, le32_to_cpu(entry->TxBuffAddr),
1066 skb->len, PCI_DMA_TODEVICE);
1068 kfree_skb(skb);
1070 if (prio == MGNT_QUEUE) {
1071 if (priv->ieee80211->ack_tx_to_ieee) {
1072 if (rtl8192_is_tx_queue_empty(dev)) {
1073 priv->ieee80211->ack_tx_to_ieee = 0;
1074 ieee80211_ps_tx_ack(priv->ieee80211, 1);
1079 if (prio != BEACON_QUEUE) {
1080 /* try to deal with the pending packets */
1081 tasklet_schedule(&priv->irq_tx_tasklet);
1085 static void rtl8192_stop_beacon(struct net_device *dev)
1089 static void rtl8192_config_rate(struct net_device* dev, u16* rate_config)
1091 struct r8192_priv *priv = ieee80211_priv(dev);
1092 struct ieee80211_network *net;
1093 u8 i=0, basic_rate = 0;
1094 net = & priv->ieee80211->current_network;
1096 for (i=0; i<net->rates_len; i++)
1098 basic_rate = net->rates[i]&0x7f;
1099 switch(basic_rate)
1101 case MGN_1M: *rate_config |= RRSR_1M; break;
1102 case MGN_2M: *rate_config |= RRSR_2M; break;
1103 case MGN_5_5M: *rate_config |= RRSR_5_5M; break;
1104 case MGN_11M: *rate_config |= RRSR_11M; break;
1105 case MGN_6M: *rate_config |= RRSR_6M; break;
1106 case MGN_9M: *rate_config |= RRSR_9M; break;
1107 case MGN_12M: *rate_config |= RRSR_12M; break;
1108 case MGN_18M: *rate_config |= RRSR_18M; break;
1109 case MGN_24M: *rate_config |= RRSR_24M; break;
1110 case MGN_36M: *rate_config |= RRSR_36M; break;
1111 case MGN_48M: *rate_config |= RRSR_48M; break;
1112 case MGN_54M: *rate_config |= RRSR_54M; break;
1115 for (i=0; i<net->rates_ex_len; i++)
1117 basic_rate = net->rates_ex[i]&0x7f;
1118 switch(basic_rate)
1120 case MGN_1M: *rate_config |= RRSR_1M; break;
1121 case MGN_2M: *rate_config |= RRSR_2M; break;
1122 case MGN_5_5M: *rate_config |= RRSR_5_5M; break;
1123 case MGN_11M: *rate_config |= RRSR_11M; break;
1124 case MGN_6M: *rate_config |= RRSR_6M; break;
1125 case MGN_9M: *rate_config |= RRSR_9M; break;
1126 case MGN_12M: *rate_config |= RRSR_12M; break;
1127 case MGN_18M: *rate_config |= RRSR_18M; break;
1128 case MGN_24M: *rate_config |= RRSR_24M; break;
1129 case MGN_36M: *rate_config |= RRSR_36M; break;
1130 case MGN_48M: *rate_config |= RRSR_48M; break;
1131 case MGN_54M: *rate_config |= RRSR_54M; break;
1137 #define SHORT_SLOT_TIME 9
1138 #define NON_SHORT_SLOT_TIME 20
1140 static void rtl8192_update_cap(struct net_device* dev, u16 cap)
1142 u32 tmp = 0;
1143 struct r8192_priv *priv = ieee80211_priv(dev);
1144 struct ieee80211_network *net = &priv->ieee80211->current_network;
1145 priv->short_preamble = cap & WLAN_CAPABILITY_SHORT_PREAMBLE;
1146 tmp = priv->basic_rate;
1147 if (priv->short_preamble)
1148 tmp |= BRSR_AckShortPmb;
1149 write_nic_dword(dev, RRSR, tmp);
1151 if (net->mode & (IEEE_G|IEEE_N_24G))
1153 u8 slot_time = 0;
1154 if ((cap & WLAN_CAPABILITY_SHORT_SLOT)&&(!priv->ieee80211->pHTInfo->bCurrentRT2RTLongSlotTime))
1155 {//short slot time
1156 slot_time = SHORT_SLOT_TIME;
1158 else //long slot time
1159 slot_time = NON_SHORT_SLOT_TIME;
1160 priv->slot_time = slot_time;
1161 write_nic_byte(dev, SLOT_TIME, slot_time);
1166 static void rtl8192_net_update(struct net_device *dev)
1168 struct r8192_priv *priv = ieee80211_priv(dev);
1169 struct ieee80211_network *net;
1170 u16 BcnTimeCfg = 0, BcnCW = 6, BcnIFS = 0xf;
1171 u16 rate_config = 0;
1172 net = &priv->ieee80211->current_network;
1174 /* update Basic rate: RR, BRSR */
1175 rtl8192_config_rate(dev, &rate_config);
1178 * Select RRSR (in Legacy-OFDM and CCK)
1179 * For 8190, we select only 24M, 12M, 6M, 11M, 5.5M,
1180 * 2M, and 1M from the Basic rate.
1181 * We do not use other rates.
1183 priv->basic_rate = rate_config &= 0x15f;
1185 /* BSSID */
1186 write_nic_dword(dev, BSSIDR, ((u32 *)net->bssid)[0]);
1187 write_nic_word(dev, BSSIDR+4, ((u16 *)net->bssid)[2]);
1189 if (priv->ieee80211->iw_mode == IW_MODE_ADHOC)
1191 write_nic_word(dev, ATIMWND, 2);
1192 write_nic_word(dev, BCN_DMATIME, 256);
1193 write_nic_word(dev, BCN_INTERVAL, net->beacon_interval);
1195 * BIT15 of BCN_DRV_EARLY_INT will indicate
1196 * whether software beacon or hw beacon is applied.
1198 write_nic_word(dev, BCN_DRV_EARLY_INT, 10);
1199 write_nic_byte(dev, BCN_ERR_THRESH, 100);
1201 BcnTimeCfg |= (BcnCW<<BCN_TCFG_CW_SHIFT);
1202 /* TODO: BcnIFS may required to be changed on ASIC */
1203 BcnTimeCfg |= BcnIFS<<BCN_TCFG_IFS;
1204 write_nic_word(dev, BCN_TCFG, BcnTimeCfg);
1208 void rtl819xE_tx_cmd(struct net_device *dev, struct sk_buff *skb)
1210 struct r8192_priv *priv = ieee80211_priv(dev);
1211 struct rtl8192_tx_ring *ring;
1212 tx_desc_819x_pci *entry;
1213 unsigned int idx;
1214 dma_addr_t mapping;
1215 cb_desc *tcb_desc;
1216 unsigned long flags;
1218 ring = &priv->tx_ring[TXCMD_QUEUE];
1219 mapping = pci_map_single(priv->pdev, skb->data, skb->len, PCI_DMA_TODEVICE);
1221 spin_lock_irqsave(&priv->irq_th_lock,flags);
1222 idx = (ring->idx + skb_queue_len(&ring->queue)) % ring->entries;
1223 entry = &ring->desc[idx];
1225 tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1226 memset(entry,0,12);
1227 entry->LINIP = tcb_desc->bLastIniPkt;
1228 entry->FirstSeg = 1;//first segment
1229 entry->LastSeg = 1; //last segment
1230 if(tcb_desc->bCmdOrInit == DESC_PACKET_TYPE_INIT) {
1231 entry->CmdInit = DESC_PACKET_TYPE_INIT;
1232 } else {
1233 entry->CmdInit = DESC_PACKET_TYPE_NORMAL;
1234 entry->Offset = sizeof(TX_FWINFO_8190PCI) + 8;
1235 entry->PktSize = (u16)(tcb_desc->pkt_size + entry->Offset);
1236 entry->QueueSelect = QSLT_CMD;
1237 entry->TxFWInfoSize = 0x08;
1238 entry->RATid = (u8)DESC_PACKET_TYPE_INIT;
1240 entry->TxBufferSize = skb->len;
1241 entry->TxBuffAddr = cpu_to_le32(mapping);
1242 entry->OWN = 1;
1244 #ifdef JOHN_DUMP_TXDESC
1245 { int i;
1246 tx_desc_819x_pci *entry1 = &ring->desc[0];
1247 unsigned int *ptr= (unsigned int *)entry1;
1248 printk("<Tx descriptor>:\n");
1249 for (i = 0; i < 8; i++)
1250 printk("%8x ", ptr[i]);
1251 printk("\n");
1253 #endif
1254 __skb_queue_tail(&ring->queue, skb);
1255 spin_unlock_irqrestore(&priv->irq_th_lock,flags);
1257 write_nic_byte(dev, TPPoll, TPPoll_CQ);
1259 return;
1263 * Mapping Software/Hardware descriptor queue id to "Queue Select Field"
1264 * in TxFwInfo data structure
1266 static u8 MapHwQueueToFirmwareQueue(u8 QueueID)
1268 u8 QueueSelect = 0;
1270 switch (QueueID) {
1271 case BE_QUEUE:
1272 QueueSelect = QSLT_BE;
1273 break;
1275 case BK_QUEUE:
1276 QueueSelect = QSLT_BK;
1277 break;
1279 case VO_QUEUE:
1280 QueueSelect = QSLT_VO;
1281 break;
1283 case VI_QUEUE:
1284 QueueSelect = QSLT_VI;
1285 break;
1287 case MGNT_QUEUE:
1288 QueueSelect = QSLT_MGNT;
1289 break;
1291 case BEACON_QUEUE:
1292 QueueSelect = QSLT_BEACON;
1293 break;
1295 case TXCMD_QUEUE:
1296 QueueSelect = QSLT_CMD;
1297 break;
1299 case HIGH_QUEUE:
1300 default:
1301 RT_TRACE(COMP_ERR, "Impossible Queue Selection: %d\n", QueueID);
1302 break;
1304 return QueueSelect;
1307 static u8 MRateToHwRate8190Pci(u8 rate)
1309 u8 ret = DESC90_RATE1M;
1311 switch(rate) {
1312 case MGN_1M: ret = DESC90_RATE1M; break;
1313 case MGN_2M: ret = DESC90_RATE2M; break;
1314 case MGN_5_5M: ret = DESC90_RATE5_5M; break;
1315 case MGN_11M: ret = DESC90_RATE11M; break;
1316 case MGN_6M: ret = DESC90_RATE6M; break;
1317 case MGN_9M: ret = DESC90_RATE9M; break;
1318 case MGN_12M: ret = DESC90_RATE12M; break;
1319 case MGN_18M: ret = DESC90_RATE18M; break;
1320 case MGN_24M: ret = DESC90_RATE24M; break;
1321 case MGN_36M: ret = DESC90_RATE36M; break;
1322 case MGN_48M: ret = DESC90_RATE48M; break;
1323 case MGN_54M: ret = DESC90_RATE54M; break;
1325 // HT rate since here
1326 case MGN_MCS0: ret = DESC90_RATEMCS0; break;
1327 case MGN_MCS1: ret = DESC90_RATEMCS1; break;
1328 case MGN_MCS2: ret = DESC90_RATEMCS2; break;
1329 case MGN_MCS3: ret = DESC90_RATEMCS3; break;
1330 case MGN_MCS4: ret = DESC90_RATEMCS4; break;
1331 case MGN_MCS5: ret = DESC90_RATEMCS5; break;
1332 case MGN_MCS6: ret = DESC90_RATEMCS6; break;
1333 case MGN_MCS7: ret = DESC90_RATEMCS7; break;
1334 case MGN_MCS8: ret = DESC90_RATEMCS8; break;
1335 case MGN_MCS9: ret = DESC90_RATEMCS9; break;
1336 case MGN_MCS10: ret = DESC90_RATEMCS10; break;
1337 case MGN_MCS11: ret = DESC90_RATEMCS11; break;
1338 case MGN_MCS12: ret = DESC90_RATEMCS12; break;
1339 case MGN_MCS13: ret = DESC90_RATEMCS13; break;
1340 case MGN_MCS14: ret = DESC90_RATEMCS14; break;
1341 case MGN_MCS15: ret = DESC90_RATEMCS15; break;
1342 case (0x80|0x20): ret = DESC90_RATEMCS32; break;
1344 default: break;
1346 return ret;
1350 static u8 QueryIsShort(u8 TxHT, u8 TxRate, cb_desc *tcb_desc)
1352 u8 tmp_Short;
1354 tmp_Short = (TxHT==1)?((tcb_desc->bUseShortGI)?1:0):((tcb_desc->bUseShortPreamble)?1:0);
1356 if(TxHT==1 && TxRate != DESC90_RATEMCS15)
1357 tmp_Short = 0;
1359 return tmp_Short;
1363 * The tx procedure is just as following,
1364 * skb->cb will contain all the following information,
1365 * priority, morefrag, rate, &dev.
1367 short rtl8192_tx(struct net_device *dev, struct sk_buff* skb)
1369 struct r8192_priv *priv = ieee80211_priv(dev);
1370 struct rtl8192_tx_ring *ring;
1371 unsigned long flags;
1372 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1373 tx_desc_819x_pci *pdesc = NULL;
1374 TX_FWINFO_8190PCI *pTxFwInfo = NULL;
1375 dma_addr_t mapping;
1376 bool multi_addr = false, broad_addr = false, uni_addr = false;
1377 u8 *pda_addr = NULL;
1378 int idx;
1380 if (priv->bdisable_nic) {
1381 RT_TRACE(COMP_ERR, "Nic is disabled! Can't tx packet len=%d qidx=%d!!!\n",
1382 skb->len, tcb_desc->queue_index);
1383 return skb->len;
1386 #ifdef ENABLE_LPS
1387 priv->ieee80211->bAwakePktSent = true;
1388 #endif
1390 mapping = pci_map_single(priv->pdev, skb->data, skb->len, PCI_DMA_TODEVICE);
1392 /* collect the tx packets statitcs */
1393 pda_addr = ((u8 *)skb->data) + sizeof(TX_FWINFO_8190PCI);
1394 if (is_multicast_ether_addr(pda_addr))
1395 multi_addr = true;
1396 else if (is_broadcast_ether_addr(pda_addr))
1397 broad_addr = true;
1398 else
1399 uni_addr = true;
1401 if (uni_addr)
1402 priv->stats.txbytesunicast += (u8)(skb->len) - sizeof(TX_FWINFO_8190PCI);
1403 else if (multi_addr)
1404 priv->stats.txbytesmulticast += (u8)(skb->len) - sizeof(TX_FWINFO_8190PCI);
1405 else
1406 priv->stats.txbytesbroadcast += (u8)(skb->len) - sizeof(TX_FWINFO_8190PCI);
1408 /* fill tx firmware */
1409 pTxFwInfo = (PTX_FWINFO_8190PCI)skb->data;
1410 memset(pTxFwInfo, 0, sizeof(TX_FWINFO_8190PCI));
1411 pTxFwInfo->TxHT = (tcb_desc->data_rate&0x80) ? 1 : 0;
1412 pTxFwInfo->TxRate = MRateToHwRate8190Pci((u8)tcb_desc->data_rate);
1413 pTxFwInfo->EnableCPUDur = tcb_desc->bTxEnableFwCalcDur;
1414 pTxFwInfo->Short = QueryIsShort(pTxFwInfo->TxHT, pTxFwInfo->TxRate, tcb_desc);
1416 /* Aggregation related */
1417 if (tcb_desc->bAMPDUEnable) {
1418 pTxFwInfo->AllowAggregation = 1;
1419 pTxFwInfo->RxMF = tcb_desc->ampdu_factor;
1420 pTxFwInfo->RxAMD = tcb_desc->ampdu_density;
1421 } else {
1422 pTxFwInfo->AllowAggregation = 0;
1423 pTxFwInfo->RxMF = 0;
1424 pTxFwInfo->RxAMD = 0;
1427 /* Protection mode related */
1428 pTxFwInfo->RtsEnable = (tcb_desc->bRTSEnable) ? 1 : 0;
1429 pTxFwInfo->CtsEnable = (tcb_desc->bCTSEnable) ? 1 : 0;
1430 pTxFwInfo->RtsSTBC = (tcb_desc->bRTSSTBC) ? 1 : 0;
1431 pTxFwInfo->RtsHT = (tcb_desc->rts_rate&0x80) ? 1 : 0;
1432 pTxFwInfo->RtsRate = MRateToHwRate8190Pci((u8)tcb_desc->rts_rate);
1433 pTxFwInfo->RtsBandwidth = 0;
1434 pTxFwInfo->RtsSubcarrier = tcb_desc->RTSSC;
1435 pTxFwInfo->RtsShort = (pTxFwInfo->RtsHT == 0) ? (tcb_desc->bRTSUseShortPreamble ? 1 : 0) : (tcb_desc->bRTSUseShortGI? 1 : 0);
1437 /* Set Bandwidth and sub-channel settings. */
1438 if (priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20_40) {
1439 if (tcb_desc->bPacketBW) {
1440 pTxFwInfo->TxBandwidth = 1;
1441 #ifdef RTL8190P
1442 pTxFwInfo->TxSubCarrier = 3;
1443 #else
1444 /* use duplicated mode */
1445 pTxFwInfo->TxSubCarrier = 0;
1446 #endif
1447 } else {
1448 pTxFwInfo->TxBandwidth = 0;
1449 pTxFwInfo->TxSubCarrier = priv->nCur40MhzPrimeSC;
1451 } else {
1452 pTxFwInfo->TxBandwidth = 0;
1453 pTxFwInfo->TxSubCarrier = 0;
1456 spin_lock_irqsave(&priv->irq_th_lock, flags);
1457 ring = &priv->tx_ring[tcb_desc->queue_index];
1458 if (tcb_desc->queue_index != BEACON_QUEUE)
1459 idx = (ring->idx + skb_queue_len(&ring->queue)) % ring->entries;
1460 else
1461 idx = 0;
1463 pdesc = &ring->desc[idx];
1464 if ((pdesc->OWN == 1) && (tcb_desc->queue_index != BEACON_QUEUE)) {
1465 RT_TRACE(COMP_ERR, "No more TX desc@%d, ring->idx = %d,idx = %d,%x",
1466 tcb_desc->queue_index, ring->idx, idx, skb->len);
1467 spin_unlock_irqrestore(&priv->irq_th_lock, flags);
1468 return skb->len;
1471 /* fill tx descriptor */
1472 memset(pdesc, 0, 12);
1474 /*DWORD 0*/
1475 pdesc->LINIP = 0;
1476 pdesc->CmdInit = 1;
1477 pdesc->Offset = sizeof(TX_FWINFO_8190PCI) + 8; /* We must add 8!! */
1478 pdesc->PktSize = (u16)skb->len-sizeof(TX_FWINFO_8190PCI);
1480 /*DWORD 1*/
1481 pdesc->SecCAMID = 0;
1482 pdesc->RATid = tcb_desc->RATRIndex;
1484 pdesc->NoEnc = 1;
1485 pdesc->SecType = 0x0;
1486 if (tcb_desc->bHwSec) {
1487 switch (priv->ieee80211->pairwise_key_type) {
1488 case KEY_TYPE_WEP40:
1489 case KEY_TYPE_WEP104:
1490 pdesc->SecType = 0x1;
1491 pdesc->NoEnc = 0;
1492 break;
1493 case KEY_TYPE_TKIP:
1494 pdesc->SecType = 0x2;
1495 pdesc->NoEnc = 0;
1496 break;
1497 case KEY_TYPE_CCMP:
1498 pdesc->SecType = 0x3;
1499 pdesc->NoEnc = 0;
1500 break;
1501 case KEY_TYPE_NA:
1502 pdesc->SecType = 0x0;
1503 pdesc->NoEnc = 1;
1504 break;
1508 /* Set Packet ID */
1509 pdesc->PktId = 0x0;
1511 pdesc->QueueSelect = MapHwQueueToFirmwareQueue(tcb_desc->queue_index);
1512 pdesc->TxFWInfoSize = sizeof(TX_FWINFO_8190PCI);
1514 pdesc->DISFB = tcb_desc->bTxDisableRateFallBack;
1515 pdesc->USERATE = tcb_desc->bTxUseDriverAssingedRate;
1517 pdesc->FirstSeg = 1;
1518 pdesc->LastSeg = 1;
1519 pdesc->TxBufferSize = skb->len;
1521 pdesc->TxBuffAddr = cpu_to_le32(mapping);
1522 __skb_queue_tail(&ring->queue, skb);
1523 pdesc->OWN = 1;
1524 spin_unlock_irqrestore(&priv->irq_th_lock, flags);
1525 dev->trans_start = jiffies;
1526 write_nic_word(dev, TPPoll, 0x01<<tcb_desc->queue_index);
1527 return 0;
1530 static short rtl8192_alloc_rx_desc_ring(struct net_device *dev)
1532 struct r8192_priv *priv = ieee80211_priv(dev);
1533 rx_desc_819x_pci *entry = NULL;
1534 int i;
1536 priv->rx_ring = pci_alloc_consistent(priv->pdev,
1537 sizeof(*priv->rx_ring) * priv->rxringcount, &priv->rx_ring_dma);
1539 if (!priv->rx_ring || (unsigned long)priv->rx_ring & 0xFF) {
1540 RT_TRACE(COMP_ERR,"Cannot allocate RX ring\n");
1541 return -ENOMEM;
1544 memset(priv->rx_ring, 0, sizeof(*priv->rx_ring) * priv->rxringcount);
1545 priv->rx_idx = 0;
1547 for (i = 0; i < priv->rxringcount; i++) {
1548 struct sk_buff *skb = dev_alloc_skb(priv->rxbuffersize);
1549 dma_addr_t *mapping;
1550 entry = &priv->rx_ring[i];
1551 if (!skb)
1552 return 0;
1553 priv->rx_buf[i] = skb;
1554 mapping = (dma_addr_t *)skb->cb;
1555 *mapping = pci_map_single(priv->pdev, skb_tail_pointer(skb),
1556 priv->rxbuffersize, PCI_DMA_FROMDEVICE);
1558 entry->BufferAddress = cpu_to_le32(*mapping);
1560 entry->Length = priv->rxbuffersize;
1561 entry->OWN = 1;
1564 entry->EOR = 1;
1565 return 0;
1568 static int rtl8192_alloc_tx_desc_ring(struct net_device *dev,
1569 unsigned int prio, unsigned int entries)
1571 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1572 tx_desc_819x_pci *ring;
1573 dma_addr_t dma;
1574 int i;
1576 ring = pci_alloc_consistent(priv->pdev, sizeof(*ring) * entries, &dma);
1577 if (!ring || (unsigned long)ring & 0xFF) {
1578 RT_TRACE(COMP_ERR, "Cannot allocate TX ring (prio = %d)\n", prio);
1579 return -ENOMEM;
1582 memset(ring, 0, sizeof(*ring)*entries);
1583 priv->tx_ring[prio].desc = ring;
1584 priv->tx_ring[prio].dma = dma;
1585 priv->tx_ring[prio].idx = 0;
1586 priv->tx_ring[prio].entries = entries;
1587 skb_queue_head_init(&priv->tx_ring[prio].queue);
1589 for (i = 0; i < entries; i++)
1590 ring[i].NextDescAddress =
1591 cpu_to_le32((u32)dma + ((i + 1) % entries) * sizeof(*ring));
1593 return 0;
1596 static short rtl8192_pci_initdescring(struct net_device *dev)
1598 u32 ret;
1599 int i;
1600 struct r8192_priv *priv = ieee80211_priv(dev);
1602 ret = rtl8192_alloc_rx_desc_ring(dev);
1603 if (ret)
1604 return ret;
1606 /* general process for other queue */
1607 for (i = 0; i < MAX_TX_QUEUE_COUNT; i++) {
1608 ret = rtl8192_alloc_tx_desc_ring(dev, i, priv->txringcount);
1609 if (ret)
1610 goto err_free_rings;
1613 return 0;
1615 err_free_rings:
1616 rtl8192_free_rx_ring(dev);
1617 for (i = 0; i < MAX_TX_QUEUE_COUNT; i++)
1618 if (priv->tx_ring[i].desc)
1619 rtl8192_free_tx_ring(dev, i);
1620 return 1;
1623 static void rtl8192_pci_resetdescring(struct net_device *dev)
1625 struct r8192_priv *priv = ieee80211_priv(dev);
1626 int i;
1628 /* force the rx_idx to the first one */
1629 if(priv->rx_ring) {
1630 rx_desc_819x_pci *entry = NULL;
1631 for (i = 0; i < priv->rxringcount; i++) {
1632 entry = &priv->rx_ring[i];
1633 entry->OWN = 1;
1635 priv->rx_idx = 0;
1638 /* after reset, release previous pending packet, and force the
1639 * tx idx to the first one */
1640 for (i = 0; i < MAX_TX_QUEUE_COUNT; i++) {
1641 if (priv->tx_ring[i].desc) {
1642 struct rtl8192_tx_ring *ring = &priv->tx_ring[i];
1644 while (skb_queue_len(&ring->queue)) {
1645 tx_desc_819x_pci *entry = &ring->desc[ring->idx];
1646 struct sk_buff *skb = __skb_dequeue(&ring->queue);
1648 pci_unmap_single(priv->pdev, le32_to_cpu(entry->TxBuffAddr),
1649 skb->len, PCI_DMA_TODEVICE);
1650 kfree_skb(skb);
1651 ring->idx = (ring->idx + 1) % ring->entries;
1653 ring->idx = 0;
1658 static void rtl8192_link_change(struct net_device *dev)
1660 struct r8192_priv *priv = ieee80211_priv(dev);
1661 struct ieee80211_device* ieee = priv->ieee80211;
1662 //write_nic_word(dev, BCN_INTR_ITV, net->beacon_interval);
1663 if (ieee->state == IEEE80211_LINKED)
1665 rtl8192_net_update(dev);
1666 rtl8192_update_ratr_table(dev);
1667 #if 1
1668 //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
1669 if ((KEY_TYPE_WEP40 == ieee->pairwise_key_type) || (KEY_TYPE_WEP104 == ieee->pairwise_key_type))
1670 EnableHWSecurityConfig8192(dev);
1671 #endif
1673 else
1675 write_nic_byte(dev, 0x173, 0);
1677 /*update timing params*/
1678 //rtl8192_set_chan(dev, priv->chan);
1679 //MSR
1680 rtl8192_update_msr(dev);
1682 // 2007/10/16 MH MAC Will update TSF according to all received beacon, so we have
1683 // // To set CBSSID bit when link with any AP or STA.
1684 if (ieee->iw_mode == IW_MODE_INFRA || ieee->iw_mode == IW_MODE_ADHOC)
1686 u32 reg = 0;
1687 reg = read_nic_dword(dev, RCR);
1688 if (priv->ieee80211->state == IEEE80211_LINKED)
1689 priv->ReceiveConfig = reg |= RCR_CBSSID;
1690 else
1691 priv->ReceiveConfig = reg &= ~RCR_CBSSID;
1692 write_nic_dword(dev, RCR, reg);
1697 static const struct ieee80211_qos_parameters def_qos_parameters = {
1698 {3,3,3,3},/* cw_min */
1699 {7,7,7,7},/* cw_max */
1700 {2,2,2,2},/* aifs */
1701 {0,0,0,0},/* flags */
1702 {0,0,0,0} /* tx_op_limit */
1705 static void rtl8192_update_beacon(struct work_struct * work)
1707 struct r8192_priv *priv = container_of(work, struct r8192_priv, update_beacon_wq.work);
1708 struct net_device *dev = priv->ieee80211->dev;
1709 struct ieee80211_device* ieee = priv->ieee80211;
1710 struct ieee80211_network* net = &ieee->current_network;
1712 if (ieee->pHTInfo->bCurrentHTSupport)
1713 HTUpdateSelfAndPeerSetting(ieee, net);
1714 ieee->pHTInfo->bCurrentRT2RTLongSlotTime = net->bssht.bdRT2RTLongSlotTime;
1715 rtl8192_update_cap(dev, net->capability);
1719 * background support to run QoS activate functionality
1721 static const int WDCAPARA_ADD[] = {EDCAPARA_BE,EDCAPARA_BK,EDCAPARA_VI,EDCAPARA_VO};
1722 static void rtl8192_qos_activate(struct work_struct * work)
1724 struct r8192_priv *priv = container_of(work, struct r8192_priv, qos_activate);
1725 struct net_device *dev = priv->ieee80211->dev;
1726 struct ieee80211_qos_parameters *qos_parameters = &priv->ieee80211->current_network.qos_data.parameters;
1727 u8 mode = priv->ieee80211->current_network.mode;
1728 u8 u1bAIFS;
1729 u32 u4bAcParam;
1730 int i;
1732 mutex_lock(&priv->mutex);
1733 if(priv->ieee80211->state != IEEE80211_LINKED)
1734 goto success;
1735 RT_TRACE(COMP_QOS,"qos active process with associate response received\n");
1736 /* It better set slot time at first */
1737 /* For we just support b/g mode at present, let the slot time at 9/20 selection */
1738 /* update the ac parameter to related registers */
1739 for(i = 0; i < QOS_QUEUE_NUM; i++) {
1740 //Mode G/A: slotTimeTimer = 9; Mode B: 20
1741 u1bAIFS = qos_parameters->aifs[i] * ((mode&(IEEE_G|IEEE_N_24G)) ?9:20) + aSifsTime;
1742 u4bAcParam = ((((u32)(qos_parameters->tx_op_limit[i]))<< AC_PARAM_TXOP_LIMIT_OFFSET)|
1743 (((u32)(qos_parameters->cw_max[i]))<< AC_PARAM_ECW_MAX_OFFSET)|
1744 (((u32)(qos_parameters->cw_min[i]))<< AC_PARAM_ECW_MIN_OFFSET)|
1745 ((u32)u1bAIFS << AC_PARAM_AIFS_OFFSET));
1746 //printk("===>u4bAcParam:%x, ", u4bAcParam);
1747 write_nic_dword(dev, WDCAPARA_ADD[i], u4bAcParam);
1748 //write_nic_dword(dev, WDCAPARA_ADD[i], 0x005e4332);
1751 success:
1752 mutex_unlock(&priv->mutex);
1755 static int rtl8192_qos_handle_probe_response(struct r8192_priv *priv,
1756 int active_network,
1757 struct ieee80211_network *network)
1759 int ret = 0;
1760 u32 size = sizeof(struct ieee80211_qos_parameters);
1762 if(priv->ieee80211->state !=IEEE80211_LINKED)
1763 return ret;
1765 if ((priv->ieee80211->iw_mode != IW_MODE_INFRA))
1766 return ret;
1768 if (network->flags & NETWORK_HAS_QOS_MASK) {
1769 if (active_network &&
1770 (network->flags & NETWORK_HAS_QOS_PARAMETERS))
1771 network->qos_data.active = network->qos_data.supported;
1773 if ((network->qos_data.active == 1) && (active_network == 1) &&
1774 (network->flags & NETWORK_HAS_QOS_PARAMETERS) &&
1775 (network->qos_data.old_param_count !=
1776 network->qos_data.param_count)) {
1777 network->qos_data.old_param_count =
1778 network->qos_data.param_count;
1779 queue_work(priv->priv_wq, &priv->qos_activate);
1780 RT_TRACE (COMP_QOS, "QoS parameters change call "
1781 "qos_activate\n");
1783 } else {
1784 memcpy(&priv->ieee80211->current_network.qos_data.parameters,
1785 &def_qos_parameters, size);
1787 if ((network->qos_data.active == 1) && (active_network == 1)) {
1788 queue_work(priv->priv_wq, &priv->qos_activate);
1789 RT_TRACE(COMP_QOS, "QoS was disabled call qos_activate \n");
1791 network->qos_data.active = 0;
1792 network->qos_data.supported = 0;
1795 return 0;
1798 /* handle manage frame frame beacon and probe response */
1799 static int rtl8192_handle_beacon(struct net_device * dev,
1800 struct ieee80211_beacon * beacon,
1801 struct ieee80211_network * network)
1803 struct r8192_priv *priv = ieee80211_priv(dev);
1805 rtl8192_qos_handle_probe_response(priv,1,network);
1807 queue_delayed_work(priv->priv_wq, &priv->update_beacon_wq, 0);
1808 return 0;
1813 * handling the beaconing responses. if we get different QoS setting
1814 * off the network from the associated setting, adjust the QoS setting
1816 static int rtl8192_qos_association_resp(struct r8192_priv *priv,
1817 struct ieee80211_network *network)
1819 int ret = 0;
1820 unsigned long flags;
1821 u32 size = sizeof(struct ieee80211_qos_parameters);
1822 int set_qos_param = 0;
1824 if ((priv == NULL) || (network == NULL))
1825 return ret;
1827 if (priv->ieee80211->state != IEEE80211_LINKED)
1828 return ret;
1830 if ((priv->ieee80211->iw_mode != IW_MODE_INFRA))
1831 return ret;
1833 spin_lock_irqsave(&priv->ieee80211->lock, flags);
1834 if (network->flags & NETWORK_HAS_QOS_PARAMETERS) {
1835 memcpy(&priv->ieee80211->current_network.qos_data.parameters,
1836 &network->qos_data.parameters,
1837 sizeof(struct ieee80211_qos_parameters));
1838 priv->ieee80211->current_network.qos_data.active = 1;
1839 set_qos_param = 1;
1840 /* update qos parameter for current network */
1841 priv->ieee80211->current_network.qos_data.old_param_count =
1842 priv->ieee80211->current_network.qos_data.param_count;
1843 priv->ieee80211->current_network.qos_data.param_count =
1844 network->qos_data.param_count;
1846 } else {
1847 memcpy(&priv->ieee80211->current_network.qos_data.parameters,
1848 &def_qos_parameters, size);
1849 priv->ieee80211->current_network.qos_data.active = 0;
1850 priv->ieee80211->current_network.qos_data.supported = 0;
1851 set_qos_param = 1;
1854 spin_unlock_irqrestore(&priv->ieee80211->lock, flags);
1856 RT_TRACE(COMP_QOS, "%s: network->flags = %d,%d\n", __FUNCTION__,
1857 network->flags, priv->ieee80211->current_network.qos_data.active);
1858 if (set_qos_param == 1)
1859 queue_work(priv->priv_wq, &priv->qos_activate);
1861 return ret;
1865 static int rtl8192_handle_assoc_response(struct net_device *dev,
1866 struct ieee80211_assoc_response_frame *resp,
1867 struct ieee80211_network *network)
1869 struct r8192_priv *priv = ieee80211_priv(dev);
1870 rtl8192_qos_association_resp(priv, network);
1871 return 0;
1875 /* updateRATRTabel for MCS only. Basic rate is not implemented. */
1876 static void rtl8192_update_ratr_table(struct net_device* dev)
1878 struct r8192_priv* priv = ieee80211_priv(dev);
1879 struct ieee80211_device* ieee = priv->ieee80211;
1880 u8* pMcsRate = ieee->dot11HTOperationalRateSet;
1881 u32 ratr_value = 0;
1882 u8 rate_index = 0;
1884 rtl8192_config_rate(dev, (u16*)(&ratr_value));
1885 ratr_value |= (*(u16*)(pMcsRate)) << 12;
1887 switch (ieee->mode)
1889 case IEEE_A:
1890 ratr_value &= 0x00000FF0;
1891 break;
1892 case IEEE_B:
1893 ratr_value &= 0x0000000F;
1894 break;
1895 case IEEE_G:
1896 ratr_value &= 0x00000FF7;
1897 break;
1898 case IEEE_N_24G:
1899 case IEEE_N_5G:
1900 if (ieee->pHTInfo->PeerMimoPs == 0) //MIMO_PS_STATIC
1901 ratr_value &= 0x0007F007;
1902 else{
1903 if (priv->rf_type == RF_1T2R)
1904 ratr_value &= 0x000FF007;
1905 else
1906 ratr_value &= 0x0F81F007;
1908 break;
1909 default:
1910 break;
1912 ratr_value &= 0x0FFFFFFF;
1913 if(ieee->pHTInfo->bCurTxBW40MHz && ieee->pHTInfo->bCurShortGI40MHz){
1914 ratr_value |= 0x80000000;
1915 }else if(!ieee->pHTInfo->bCurTxBW40MHz && ieee->pHTInfo->bCurShortGI20MHz){
1916 ratr_value |= 0x80000000;
1918 write_nic_dword(dev, RATR0+rate_index*4, ratr_value);
1919 write_nic_byte(dev, UFWP, 1);
1922 static bool GetNmodeSupportBySecCfg8190Pci(struct net_device*dev)
1924 struct r8192_priv *priv = ieee80211_priv(dev);
1925 struct ieee80211_device *ieee = priv->ieee80211;
1927 return !(ieee->rtllib_ap_sec_type &&
1928 (ieee->rtllib_ap_sec_type(ieee)&(SEC_ALG_WEP|SEC_ALG_TKIP)));
1931 static void rtl8192_refresh_supportrate(struct r8192_priv* priv)
1933 struct ieee80211_device* ieee = priv->ieee80211;
1934 //we donot consider set support rate for ABG mode, only HT MCS rate is set here.
1935 if (ieee->mode == WIRELESS_MODE_N_24G || ieee->mode == WIRELESS_MODE_N_5G)
1937 memcpy(ieee->Regdot11HTOperationalRateSet, ieee->RegHTSuppRateSet, 16);
1938 //RT_DEBUG_DATA(COMP_INIT, ieee->RegHTSuppRateSet, 16);
1939 //RT_DEBUG_DATA(COMP_INIT, ieee->Regdot11HTOperationalRateSet, 16);
1941 else
1942 memset(ieee->Regdot11HTOperationalRateSet, 0, 16);
1945 static u8 rtl8192_getSupportedWireleeMode(struct net_device*dev)
1947 struct r8192_priv *priv = ieee80211_priv(dev);
1948 u8 ret = 0;
1949 switch(priv->rf_chip)
1951 case RF_8225:
1952 case RF_8256:
1953 case RF_PSEUDO_11N:
1954 ret = (WIRELESS_MODE_N_24G|WIRELESS_MODE_G|WIRELESS_MODE_B);
1955 break;
1956 case RF_8258:
1957 ret = (WIRELESS_MODE_A|WIRELESS_MODE_N_5G);
1958 break;
1959 default:
1960 ret = WIRELESS_MODE_B;
1961 break;
1963 return ret;
1966 static void rtl8192_SetWirelessMode(struct net_device* dev, u8 wireless_mode)
1968 struct r8192_priv *priv = ieee80211_priv(dev);
1969 u8 bSupportMode = rtl8192_getSupportedWireleeMode(dev);
1971 #if 1
1972 if ((wireless_mode == WIRELESS_MODE_AUTO) || ((wireless_mode&bSupportMode)==0))
1974 if(bSupportMode & WIRELESS_MODE_N_24G)
1976 wireless_mode = WIRELESS_MODE_N_24G;
1978 else if(bSupportMode & WIRELESS_MODE_N_5G)
1980 wireless_mode = WIRELESS_MODE_N_5G;
1982 else if((bSupportMode & WIRELESS_MODE_A))
1984 wireless_mode = WIRELESS_MODE_A;
1986 else if((bSupportMode & WIRELESS_MODE_G))
1988 wireless_mode = WIRELESS_MODE_G;
1990 else if((bSupportMode & WIRELESS_MODE_B))
1992 wireless_mode = WIRELESS_MODE_B;
1994 else{
1995 RT_TRACE(COMP_ERR, "%s(), No valid wireless mode supported, SupportedWirelessMode(%x)!!!\n", __FUNCTION__,bSupportMode);
1996 wireless_mode = WIRELESS_MODE_B;
1999 #ifdef TO_DO_LIST //// TODO: this function doesn't work well at this time, we should wait for FPGA
2000 ActUpdateChannelAccessSetting( pAdapter, pHalData->CurrentWirelessMode, &pAdapter->MgntInfo.Info8185.ChannelAccessSetting );
2001 #endif
2002 priv->ieee80211->mode = wireless_mode;
2004 if ((wireless_mode == WIRELESS_MODE_N_24G) || (wireless_mode == WIRELESS_MODE_N_5G))
2005 priv->ieee80211->pHTInfo->bEnableHT = 1;
2006 else
2007 priv->ieee80211->pHTInfo->bEnableHT = 0;
2008 RT_TRACE(COMP_INIT, "Current Wireless Mode is %x\n", wireless_mode);
2009 rtl8192_refresh_supportrate(priv);
2010 #endif
2014 static bool GetHalfNmodeSupportByAPs819xPci(struct net_device* dev)
2016 struct r8192_priv* priv = ieee80211_priv(dev);
2017 struct ieee80211_device* ieee = priv->ieee80211;
2019 return ieee->bHalfWirelessN24GMode;
2022 short rtl8192_is_tx_queue_empty(struct net_device *dev)
2024 int i=0;
2025 struct r8192_priv *priv = ieee80211_priv(dev);
2026 for (i=0; i<=MGNT_QUEUE; i++)
2028 if ((i== TXCMD_QUEUE) || (i == HCCA_QUEUE) )
2029 continue;
2030 if (skb_queue_len(&(&priv->tx_ring[i])->queue) > 0){
2031 printk("===>tx queue is not empty:%d, %d\n", i, skb_queue_len(&(&priv->tx_ring[i])->queue));
2032 return 0;
2035 return 1;
2038 static void rtl8192_hw_sleep_down(struct net_device *dev)
2040 struct r8192_priv *priv = ieee80211_priv(dev);
2041 unsigned long flags = 0;
2043 spin_lock_irqsave(&priv->rf_ps_lock,flags);
2044 if (priv->RFChangeInProgress) {
2045 spin_unlock_irqrestore(&priv->rf_ps_lock,flags);
2046 RT_TRACE(COMP_RF, "rtl8192_hw_sleep_down(): RF Change in progress! \n");
2047 printk("rtl8192_hw_sleep_down(): RF Change in progress!\n");
2048 return;
2050 spin_unlock_irqrestore(&priv->rf_ps_lock,flags);
2052 MgntActSet_RF_State(dev, eRfSleep, RF_CHANGE_BY_PS);
2055 static void rtl8192_hw_sleep_wq (struct work_struct *work)
2057 struct delayed_work *dwork = container_of(work,struct delayed_work,work);
2058 struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,hw_sleep_wq);
2059 struct net_device *dev = ieee->dev;
2061 rtl8192_hw_sleep_down(dev);
2064 static void rtl8192_hw_wakeup(struct net_device* dev)
2066 struct r8192_priv *priv = ieee80211_priv(dev);
2067 unsigned long flags = 0;
2069 spin_lock_irqsave(&priv->rf_ps_lock,flags);
2070 if (priv->RFChangeInProgress) {
2071 spin_unlock_irqrestore(&priv->rf_ps_lock,flags);
2072 RT_TRACE(COMP_RF, "rtl8192_hw_wakeup(): RF Change in progress! \n");
2073 printk("rtl8192_hw_wakeup(): RF Change in progress! schedule wake up task again\n");
2074 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
2075 return;
2077 spin_unlock_irqrestore(&priv->rf_ps_lock,flags);
2079 MgntActSet_RF_State(dev, eRfOn, RF_CHANGE_BY_PS);
2082 void rtl8192_hw_wakeup_wq (struct work_struct *work)
2084 struct delayed_work *dwork = container_of(work,struct delayed_work,work);
2085 struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,hw_wakeup_wq);
2086 struct net_device *dev = ieee->dev;
2087 rtl8192_hw_wakeup(dev);
2091 #define MIN_SLEEP_TIME 50
2092 #define MAX_SLEEP_TIME 10000
2093 static void rtl8192_hw_to_sleep(struct net_device *dev, u32 th, u32 tl)
2095 struct r8192_priv *priv = ieee80211_priv(dev);
2097 u32 rb = jiffies;
2098 unsigned long flags;
2100 spin_lock_irqsave(&priv->ps_lock,flags);
2102 // Writing HW register with 0 equals to disable
2103 // the timer, that is not really what we want
2105 tl -= MSECS(8+16+7);
2107 // If the interval in witch we are requested to sleep is too
2108 // short then give up and remain awake
2109 // when we sleep after send null frame, the timer will be too short to sleep.
2111 if(((tl>=rb)&& (tl-rb) <= MSECS(MIN_SLEEP_TIME))
2112 ||((rb>tl)&& (rb-tl) < MSECS(MIN_SLEEP_TIME))) {
2113 spin_unlock_irqrestore(&priv->ps_lock,flags);
2114 printk("too short to sleep::%x, %x, %lx\n",tl, rb, MSECS(MIN_SLEEP_TIME));
2115 return;
2118 if(((tl > rb) && ((tl-rb) > MSECS(MAX_SLEEP_TIME)))||
2119 ((tl < rb) && (tl>MSECS(69)) && ((rb-tl) > MSECS(MAX_SLEEP_TIME)))||
2120 ((tl<rb)&&(tl<MSECS(69))&&((tl+0xffffffff-rb)>MSECS(MAX_SLEEP_TIME)))) {
2121 printk("========>too long to sleep:%x, %x, %lx\n", tl, rb, MSECS(MAX_SLEEP_TIME));
2122 spin_unlock_irqrestore(&priv->ps_lock,flags);
2123 return;
2126 u32 tmp = (tl>rb)?(tl-rb):(rb-tl);
2127 queue_delayed_work(priv->ieee80211->wq,
2128 &priv->ieee80211->hw_wakeup_wq,tmp);
2129 //PowerSave not supported when kernel version less 2.6.20
2131 queue_delayed_work(priv->ieee80211->wq,
2132 (void *)&priv->ieee80211->hw_sleep_wq,0);
2133 spin_unlock_irqrestore(&priv->ps_lock,flags);
2137 static void rtl8192_init_priv_variable(struct net_device* dev)
2139 struct r8192_priv *priv = ieee80211_priv(dev);
2140 u8 i;
2141 PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->ieee80211->PowerSaveControl));
2143 // Default Halt the NIC if RF is OFF.
2144 pPSC->RegRfPsLevel |= RT_RF_OFF_LEVL_HALT_NIC;
2145 pPSC->RegRfPsLevel |= RT_RF_OFF_LEVL_CLK_REQ;
2146 pPSC->RegRfPsLevel |= RT_RF_OFF_LEVL_ASPM;
2147 pPSC->RegRfPsLevel |= RT_RF_LPS_LEVEL_ASPM;
2148 pPSC->bLeisurePs = true;
2149 pPSC->RegMaxLPSAwakeIntvl = 5;
2150 priv->bHwRadioOff = false;
2152 priv->being_init_adapter = false;
2153 priv->txbuffsize = 1600;//1024;
2154 priv->txfwbuffersize = 4096;
2155 priv->txringcount = 64;//32;
2156 //priv->txbeaconcount = priv->txringcount;
2157 priv->txbeaconcount = 2;
2158 priv->rxbuffersize = 9100;//2048;//1024;
2159 priv->rxringcount = MAX_RX_COUNT;//64;
2160 priv->irq_enabled=0;
2161 priv->card_8192 = NIC_8192E;
2162 priv->rx_skb_complete = 1;
2163 priv->chan = 1; //set to channel 1
2164 priv->RegWirelessMode = WIRELESS_MODE_AUTO;
2165 priv->RegChannelPlan = 0xf;
2166 priv->nrxAMPDU_size = 0;
2167 priv->nrxAMPDU_aggr_num = 0;
2168 priv->last_rxdesc_tsf_high = 0;
2169 priv->last_rxdesc_tsf_low = 0;
2170 priv->ieee80211->mode = WIRELESS_MODE_AUTO; //SET AUTO
2171 priv->ieee80211->iw_mode = IW_MODE_INFRA;
2172 priv->ieee80211->ieee_up=0;
2173 priv->retry_rts = DEFAULT_RETRY_RTS;
2174 priv->retry_data = DEFAULT_RETRY_DATA;
2175 priv->ieee80211->rts = DEFAULT_RTS_THRESHOLD;
2176 priv->ieee80211->rate = 110; //11 mbps
2177 priv->ieee80211->short_slot = 1;
2178 priv->promisc = (dev->flags & IFF_PROMISC) ? 1:0;
2179 priv->bcck_in_ch14 = false;
2180 priv->bfsync_processing = false;
2181 priv->CCKPresentAttentuation = 0;
2182 priv->rfa_txpowertrackingindex = 0;
2183 priv->rfc_txpowertrackingindex = 0;
2184 priv->CckPwEnl = 6;
2185 priv->ScanDelay = 50;//for Scan TODO
2186 //added by amy for silent reset
2187 priv->ResetProgress = RESET_TYPE_NORESET;
2188 priv->bForcedSilentReset = 0;
2189 priv->bDisableNormalResetCheck = false;
2190 priv->force_reset = false;
2191 //added by amy for power save
2192 priv->RegRfOff = 0;
2193 priv->ieee80211->RfOffReason = 0;
2194 priv->RFChangeInProgress = false;
2195 priv->bHwRfOffAction = 0;
2196 priv->SetRFPowerStateInProgress = false;
2197 priv->ieee80211->PowerSaveControl.bInactivePs = true;
2198 priv->ieee80211->PowerSaveControl.bIPSModeBackup = false;
2199 //just for debug
2200 priv->txpower_checkcnt = 0;
2201 priv->thermal_readback_index =0;
2202 priv->txpower_tracking_callback_cnt = 0;
2203 priv->ccktxpower_adjustcnt_ch14 = 0;
2204 priv->ccktxpower_adjustcnt_not_ch14 = 0;
2206 priv->ieee80211->current_network.beacon_interval = DEFAULT_BEACONINTERVAL;
2207 priv->ieee80211->iw_mode = IW_MODE_INFRA;
2208 priv->ieee80211->softmac_features = IEEE_SOFTMAC_SCAN |
2209 IEEE_SOFTMAC_ASSOCIATE | IEEE_SOFTMAC_PROBERQ |
2210 IEEE_SOFTMAC_PROBERS | IEEE_SOFTMAC_TX_QUEUE;/* |
2211 IEEE_SOFTMAC_BEACONS;*///added by amy 080604 //| //IEEE_SOFTMAC_SINGLE_QUEUE;
2213 priv->ieee80211->active_scan = 1;
2214 priv->ieee80211->modulation = IEEE80211_CCK_MODULATION | IEEE80211_OFDM_MODULATION;
2215 priv->ieee80211->host_encrypt = 1;
2216 priv->ieee80211->host_decrypt = 1;
2217 //priv->ieee80211->start_send_beacons = NULL;//rtl819xusb_beacon_tx;//-by amy 080604
2218 //priv->ieee80211->stop_send_beacons = NULL;//rtl8192_beacon_stop;//-by amy 080604
2219 priv->ieee80211->start_send_beacons = rtl8192_start_beacon;//+by david 081107
2220 priv->ieee80211->stop_send_beacons = rtl8192_stop_beacon;//+by david 081107
2221 priv->ieee80211->softmac_hard_start_xmit = rtl8192_hard_start_xmit;
2222 priv->ieee80211->set_chan = rtl8192_set_chan;
2223 priv->ieee80211->link_change = rtl8192_link_change;
2224 priv->ieee80211->softmac_data_hard_start_xmit = rtl8192_hard_data_xmit;
2225 priv->ieee80211->data_hard_stop = rtl8192_data_hard_stop;
2226 priv->ieee80211->data_hard_resume = rtl8192_data_hard_resume;
2227 priv->ieee80211->init_wmmparam_flag = 0;
2228 priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD;
2229 priv->ieee80211->check_nic_enough_desc = check_nic_enough_desc;
2230 priv->ieee80211->tx_headroom = sizeof(TX_FWINFO_8190PCI);
2231 priv->ieee80211->qos_support = 1;
2232 priv->ieee80211->dot11PowerSaveMode = 0;
2233 //added by WB
2234 // priv->ieee80211->SwChnlByTimerHandler = rtl8192_phy_SwChnl;
2235 priv->ieee80211->SetBWModeHandler = rtl8192_SetBWMode;
2236 priv->ieee80211->handle_assoc_response = rtl8192_handle_assoc_response;
2237 priv->ieee80211->handle_beacon = rtl8192_handle_beacon;
2239 priv->ieee80211->sta_wake_up = rtl8192_hw_wakeup;
2240 // priv->ieee80211->ps_request_tx_ack = rtl8192_rq_tx_ack;
2241 priv->ieee80211->enter_sleep_state = rtl8192_hw_to_sleep;
2242 priv->ieee80211->ps_is_queue_empty = rtl8192_is_tx_queue_empty;
2243 //added by david
2244 priv->ieee80211->GetNmodeSupportBySecCfg = GetNmodeSupportBySecCfg8190Pci;
2245 priv->ieee80211->SetWirelessMode = rtl8192_SetWirelessMode;
2246 priv->ieee80211->GetHalfNmodeSupportByAPsHandler = GetHalfNmodeSupportByAPs819xPci;
2248 //added by amy
2249 priv->ieee80211->InitialGainHandler = InitialGain819xPci;
2251 #ifdef ENABLE_IPS
2252 priv->ieee80211->ieee80211_ips_leave_wq = ieee80211_ips_leave_wq;
2253 priv->ieee80211->ieee80211_ips_leave = ieee80211_ips_leave;
2254 #endif
2255 #ifdef ENABLE_LPS
2256 priv->ieee80211->LeisurePSLeave = LeisurePSLeave;
2257 #endif
2259 priv->ieee80211->SetHwRegHandler = rtl8192e_SetHwReg;
2260 priv->ieee80211->rtllib_ap_sec_type = rtl8192e_ap_sec_type;
2262 priv->card_type = USB;
2264 priv->ShortRetryLimit = 0x30;
2265 priv->LongRetryLimit = 0x30;
2267 priv->EarlyRxThreshold = 7;
2268 priv->enable_gpio0 = 0;
2270 priv->TransmitConfig = 0;
2272 priv->ReceiveConfig = RCR_ADD3 |
2273 RCR_AMF | RCR_ADF | //accept management/data
2274 RCR_AICV | //accept control frame for SW AP needs PS-poll, 2005.07.07, by rcnjko.
2275 RCR_AB | RCR_AM | RCR_APM | //accept BC/MC/UC
2276 RCR_AAP | ((u32)7<<RCR_MXDMA_OFFSET) |
2277 ((u32)7 << RCR_FIFO_OFFSET) | RCR_ONLYERLPKT;
2279 priv->irq_mask = (u32)(IMR_ROK | IMR_VODOK | IMR_VIDOK | IMR_BEDOK | IMR_BKDOK |
2280 IMR_HCCADOK | IMR_MGNTDOK | IMR_COMDOK | IMR_HIGHDOK |
2281 IMR_BDOK | IMR_RXCMDOK | IMR_TIMEOUT0 | IMR_RDU | IMR_RXFOVW |
2282 IMR_TXFOVW | IMR_BcnInt | IMR_TBDOK | IMR_TBDER);
2284 priv->AcmControl = 0;
2285 priv->pFirmware = vzalloc(sizeof(rt_firmware));
2287 /* rx related queue */
2288 skb_queue_head_init(&priv->rx_queue);
2289 skb_queue_head_init(&priv->skb_queue);
2291 /* Tx related queue */
2292 for(i = 0; i < MAX_QUEUE_SIZE; i++) {
2293 skb_queue_head_init(&priv->ieee80211->skb_waitQ [i]);
2295 for(i = 0; i < MAX_QUEUE_SIZE; i++) {
2296 skb_queue_head_init(&priv->ieee80211->skb_aggQ [i]);
2298 priv->rf_set_chan = rtl8192_phy_SwChnl;
2301 static void rtl8192_init_priv_lock(struct r8192_priv* priv)
2303 spin_lock_init(&priv->tx_lock);
2304 spin_lock_init(&priv->irq_lock);//added by thomas
2305 spin_lock_init(&priv->irq_th_lock);
2306 spin_lock_init(&priv->rf_ps_lock);
2307 spin_lock_init(&priv->ps_lock);
2308 //spin_lock_init(&priv->rf_lock);
2309 sema_init(&priv->wx_sem,1);
2310 sema_init(&priv->rf_sem,1);
2311 mutex_init(&priv->mutex);
2314 /* init tasklet and wait_queue here */
2315 #define DRV_NAME "wlan0"
2316 static void rtl8192_init_priv_task(struct net_device* dev)
2318 struct r8192_priv *priv = ieee80211_priv(dev);
2320 #ifdef PF_SYNCTHREAD
2321 priv->priv_wq = create_workqueue(DRV_NAME,0);
2322 #else
2323 priv->priv_wq = create_workqueue(DRV_NAME);
2324 #endif
2326 #ifdef ENABLE_IPS
2327 INIT_WORK(&priv->ieee80211->ips_leave_wq, (void*)IPSLeave_wq);
2328 #endif
2330 // INIT_WORK(&priv->reset_wq, (void(*)(void*)) rtl8192_restart);
2331 INIT_WORK(&priv->reset_wq, rtl8192_restart);
2332 // INIT_DELAYED_WORK(&priv->watch_dog_wq, hal_dm_watchdog);
2333 INIT_DELAYED_WORK(&priv->watch_dog_wq, rtl819x_watchdog_wqcallback);
2334 INIT_DELAYED_WORK(&priv->txpower_tracking_wq, dm_txpower_trackingcallback);
2335 INIT_DELAYED_WORK(&priv->rfpath_check_wq, dm_rf_pathcheck_workitemcallback);
2336 INIT_DELAYED_WORK(&priv->update_beacon_wq, rtl8192_update_beacon);
2337 //INIT_WORK(&priv->SwChnlWorkItem, rtl8192_SwChnl_WorkItem);
2338 //INIT_WORK(&priv->SetBWModeWorkItem, rtl8192_SetBWModeWorkItem);
2339 INIT_WORK(&priv->qos_activate, rtl8192_qos_activate);
2340 INIT_DELAYED_WORK(&priv->ieee80211->hw_wakeup_wq,(void*) rtl8192_hw_wakeup_wq);
2341 INIT_DELAYED_WORK(&priv->ieee80211->hw_sleep_wq,(void*) rtl8192_hw_sleep_wq);
2343 tasklet_init(&priv->irq_rx_tasklet,
2344 (void(*)(unsigned long))rtl8192_irq_rx_tasklet,
2345 (unsigned long)priv);
2346 tasklet_init(&priv->irq_tx_tasklet,
2347 (void(*)(unsigned long))rtl8192_irq_tx_tasklet,
2348 (unsigned long)priv);
2349 tasklet_init(&priv->irq_prepare_beacon_tasklet,
2350 (void(*)(unsigned long))rtl8192_prepare_beacon,
2351 (unsigned long)priv);
2354 static void rtl8192_get_eeprom_size(struct net_device* dev)
2356 u16 curCR = 0;
2357 struct r8192_priv *priv = ieee80211_priv(dev);
2358 RT_TRACE(COMP_INIT, "===========>%s()\n", __FUNCTION__);
2359 curCR = read_nic_dword(dev, EPROM_CMD);
2360 RT_TRACE(COMP_INIT, "read from Reg Cmd9346CR(%x):%x\n", EPROM_CMD, curCR);
2361 //whether need I consider BIT5?
2362 priv->epromtype = (curCR & EPROM_CMD_9356SEL) ? EPROM_93c56 : EPROM_93c46;
2363 RT_TRACE(COMP_INIT, "<===========%s(), epromtype:%d\n", __FUNCTION__, priv->epromtype);
2367 * used to swap endian. as ntohl & htonl are not
2368 * neccessary to swap endian, so use this instead.
2370 static inline u16 endian_swap(u16* data)
2372 u16 tmp = *data;
2373 *data = (tmp >> 8) | (tmp << 8);
2374 return *data;
2378 * Adapter->EEPROMAddressSize should be set before this function call.
2379 * EEPROM address size can be got through GetEEPROMSize8185()
2381 static void rtl8192_read_eeprom_info(struct net_device* dev)
2383 struct r8192_priv *priv = ieee80211_priv(dev);
2385 u8 tempval;
2386 #ifdef RTL8192E
2387 u8 ICVer8192, ICVer8256;
2388 #endif
2389 u16 i,usValue, IC_Version;
2390 u16 EEPROMId;
2391 #ifdef RTL8190P
2392 u8 offset;
2393 u8 EepromTxPower[100];
2394 #endif
2395 u8 bMac_Tmp_Addr[6] = {0x00, 0xe0, 0x4c, 0x00, 0x00, 0x01};
2396 RT_TRACE(COMP_INIT, "====> rtl8192_read_eeprom_info\n");
2399 // TODO: I don't know if we need to apply EF function to EEPROM read function
2401 //2 Read EEPROM ID to make sure autoload is success
2402 EEPROMId = eprom_read(dev, 0);
2403 if( EEPROMId != RTL8190_EEPROM_ID )
2405 RT_TRACE(COMP_ERR, "EEPROM ID is invalid:%x, %x\n", EEPROMId, RTL8190_EEPROM_ID);
2406 priv->AutoloadFailFlag=true;
2408 else
2410 priv->AutoloadFailFlag=false;
2414 // Assign Chip Version ID
2416 // Read IC Version && Channel Plan
2417 if(!priv->AutoloadFailFlag)
2419 // VID, PID
2420 priv->eeprom_vid = eprom_read(dev, (EEPROM_VID >> 1));
2421 priv->eeprom_did = eprom_read(dev, (EEPROM_DID >> 1));
2423 usValue = eprom_read(dev, (u16)(EEPROM_Customer_ID>>1)) >> 8 ;
2424 priv->eeprom_CustomerID = (u8)( usValue & 0xff);
2425 usValue = eprom_read(dev, (EEPROM_ICVersion_ChannelPlan>>1));
2426 priv->eeprom_ChannelPlan = usValue&0xff;
2427 IC_Version = ((usValue&0xff00)>>8);
2429 #ifdef RTL8190P
2430 priv->card_8192_version = (VERSION_8190)(IC_Version);
2431 #else
2432 #ifdef RTL8192E
2433 ICVer8192 = (IC_Version&0xf); //bit0~3; 1:A cut, 2:B cut, 3:C cut...
2434 ICVer8256 = ((IC_Version&0xf0)>>4);//bit4~6, bit7 reserved for other RF chip; 1:A cut, 2:B cut, 3:C cut...
2435 RT_TRACE(COMP_INIT, "\nICVer8192 = 0x%x\n", ICVer8192);
2436 RT_TRACE(COMP_INIT, "\nICVer8256 = 0x%x\n", ICVer8256);
2437 if(ICVer8192 == 0x2) //B-cut
2439 if(ICVer8256 == 0x5) //E-cut
2440 priv->card_8192_version= VERSION_8190_BE;
2442 #endif
2443 #endif
2444 switch(priv->card_8192_version)
2446 case VERSION_8190_BD:
2447 case VERSION_8190_BE:
2448 break;
2449 default:
2450 priv->card_8192_version = VERSION_8190_BD;
2451 break;
2453 RT_TRACE(COMP_INIT, "\nIC Version = 0x%x\n", priv->card_8192_version);
2455 else
2457 priv->card_8192_version = VERSION_8190_BD;
2458 priv->eeprom_vid = 0;
2459 priv->eeprom_did = 0;
2460 priv->eeprom_CustomerID = 0;
2461 priv->eeprom_ChannelPlan = 0;
2462 RT_TRACE(COMP_INIT, "\nIC Version = 0x%x\n", 0xff);
2465 RT_TRACE(COMP_INIT, "EEPROM VID = 0x%4x\n", priv->eeprom_vid);
2466 RT_TRACE(COMP_INIT, "EEPROM DID = 0x%4x\n", priv->eeprom_did);
2467 RT_TRACE(COMP_INIT,"EEPROM Customer ID: 0x%2x\n", priv->eeprom_CustomerID);
2469 //2 Read Permanent MAC address
2470 if(!priv->AutoloadFailFlag)
2472 for(i = 0; i < 6; i += 2)
2474 usValue = eprom_read(dev, (u16) ((EEPROM_NODE_ADDRESS_BYTE_0+i)>>1));
2475 *(u16*)(&dev->dev_addr[i]) = usValue;
2477 } else {
2478 // when auto load failed, the last address byte set to be a random one.
2479 // added by david woo.2007/11/7
2480 memcpy(dev->dev_addr, bMac_Tmp_Addr, 6);
2483 RT_TRACE(COMP_INIT, "Permanent Address = %pM\n", dev->dev_addr);
2485 //2 TX Power Check EEPROM Fail or not
2486 if(priv->card_8192_version > VERSION_8190_BD) {
2487 priv->bTXPowerDataReadFromEEPORM = true;
2488 } else {
2489 priv->bTXPowerDataReadFromEEPORM = false;
2492 // 2007/11/15 MH 8190PCI Default=2T4R, 8192PCIE default=1T2R
2493 priv->rf_type = RTL819X_DEFAULT_RF_TYPE;
2495 if(priv->card_8192_version > VERSION_8190_BD)
2497 // Read RF-indication and Tx Power gain index diff of legacy to HT OFDM rate.
2498 if(!priv->AutoloadFailFlag)
2500 tempval = (eprom_read(dev, (EEPROM_RFInd_PowerDiff>>1))) & 0xff;
2501 priv->EEPROMLegacyHTTxPowerDiff = tempval & 0xf; // bit[3:0]
2503 if (tempval&0x80) //RF-indication, bit[7]
2504 priv->rf_type = RF_1T2R;
2505 else
2506 priv->rf_type = RF_2T4R;
2508 else
2510 priv->EEPROMLegacyHTTxPowerDiff = EEPROM_Default_LegacyHTTxPowerDiff;
2512 RT_TRACE(COMP_INIT, "EEPROMLegacyHTTxPowerDiff = %d\n",
2513 priv->EEPROMLegacyHTTxPowerDiff);
2515 // Read ThermalMeter from EEPROM
2516 if(!priv->AutoloadFailFlag)
2518 priv->EEPROMThermalMeter = (u8)(((eprom_read(dev, (EEPROM_ThermalMeter>>1))) & 0xff00)>>8);
2520 else
2522 priv->EEPROMThermalMeter = EEPROM_Default_ThermalMeter;
2524 RT_TRACE(COMP_INIT, "ThermalMeter = %d\n", priv->EEPROMThermalMeter);
2525 //vivi, for tx power track
2526 priv->TSSI_13dBm = priv->EEPROMThermalMeter *100;
2528 if(priv->epromtype == EPROM_93c46)
2530 // Read antenna tx power offset of B/C/D to A and CrystalCap from EEPROM
2531 if(!priv->AutoloadFailFlag)
2533 usValue = eprom_read(dev, (EEPROM_TxPwDiff_CrystalCap>>1));
2534 priv->EEPROMAntPwDiff = (usValue&0x0fff);
2535 priv->EEPROMCrystalCap = (u8)((usValue&0xf000)>>12);
2537 else
2539 priv->EEPROMAntPwDiff = EEPROM_Default_AntTxPowerDiff;
2540 priv->EEPROMCrystalCap = EEPROM_Default_TxPwDiff_CrystalCap;
2542 RT_TRACE(COMP_INIT, "EEPROMAntPwDiff = %d\n", priv->EEPROMAntPwDiff);
2543 RT_TRACE(COMP_INIT, "EEPROMCrystalCap = %d\n", priv->EEPROMCrystalCap);
2546 // Get per-channel Tx Power Level
2548 for(i=0; i<14; i+=2)
2550 if(!priv->AutoloadFailFlag)
2552 usValue = eprom_read(dev, (u16) ((EEPROM_TxPwIndex_CCK+i)>>1) );
2554 else
2556 usValue = EEPROM_Default_TxPower;
2558 *((u16*)(&priv->EEPROMTxPowerLevelCCK[i])) = usValue;
2559 RT_TRACE(COMP_INIT,"CCK Tx Power Level, Index %d = 0x%02x\n", i, priv->EEPROMTxPowerLevelCCK[i]);
2560 RT_TRACE(COMP_INIT, "CCK Tx Power Level, Index %d = 0x%02x\n", i+1, priv->EEPROMTxPowerLevelCCK[i+1]);
2562 for(i=0; i<14; i+=2)
2564 if(!priv->AutoloadFailFlag)
2566 usValue = eprom_read(dev, (u16) ((EEPROM_TxPwIndex_OFDM_24G+i)>>1) );
2568 else
2570 usValue = EEPROM_Default_TxPower;
2572 *((u16*)(&priv->EEPROMTxPowerLevelOFDM24G[i])) = usValue;
2573 RT_TRACE(COMP_INIT, "OFDM 2.4G Tx Power Level, Index %d = 0x%02x\n", i, priv->EEPROMTxPowerLevelOFDM24G[i]);
2574 RT_TRACE(COMP_INIT, "OFDM 2.4G Tx Power Level, Index %d = 0x%02x\n", i+1, priv->EEPROMTxPowerLevelOFDM24G[i+1]);
2577 else if(priv->epromtype== EPROM_93c56)
2579 #ifdef RTL8190P
2580 // Read CrystalCap from EEPROM
2581 if(!priv->AutoloadFailFlag)
2583 priv->EEPROMAntPwDiff = EEPROM_Default_AntTxPowerDiff;
2584 priv->EEPROMCrystalCap = (u8)(((eprom_read(dev, (EEPROM_C56_CrystalCap>>1))) & 0xf000)>>12);
2586 else
2588 priv->EEPROMAntPwDiff = EEPROM_Default_AntTxPowerDiff;
2589 priv->EEPROMCrystalCap = EEPROM_Default_TxPwDiff_CrystalCap;
2591 RT_TRACE(COMP_INIT,"EEPROMAntPwDiff = %d\n", priv->EEPROMAntPwDiff);
2592 RT_TRACE(COMP_INIT, "EEPROMCrystalCap = %d\n", priv->EEPROMCrystalCap);
2594 // Get Tx Power Level by Channel
2595 if(!priv->AutoloadFailFlag)
2597 // Read Tx power of Channel 1 ~ 14 from EEPROM.
2598 for(i = 0; i < 12; i+=2)
2600 if (i <6)
2601 offset = EEPROM_C56_RfA_CCK_Chnl1_TxPwIndex + i;
2602 else
2603 offset = EEPROM_C56_RfC_CCK_Chnl1_TxPwIndex + i - 6;
2604 usValue = eprom_read(dev, (offset>>1));
2605 *((u16*)(&EepromTxPower[i])) = usValue;
2608 for(i = 0; i < 12; i++)
2610 if (i <= 2)
2611 priv->EEPROMRfACCKChnl1TxPwLevel[i] = EepromTxPower[i];
2612 else if ((i >=3 )&&(i <= 5))
2613 priv->EEPROMRfAOfdmChnlTxPwLevel[i-3] = EepromTxPower[i];
2614 else if ((i >=6 )&&(i <= 8))
2615 priv->EEPROMRfCCCKChnl1TxPwLevel[i-6] = EepromTxPower[i];
2616 else
2617 priv->EEPROMRfCOfdmChnlTxPwLevel[i-9] = EepromTxPower[i];
2620 else
2622 priv->EEPROMRfACCKChnl1TxPwLevel[0] = EEPROM_Default_TxPowerLevel;
2623 priv->EEPROMRfACCKChnl1TxPwLevel[1] = EEPROM_Default_TxPowerLevel;
2624 priv->EEPROMRfACCKChnl1TxPwLevel[2] = EEPROM_Default_TxPowerLevel;
2626 priv->EEPROMRfAOfdmChnlTxPwLevel[0] = EEPROM_Default_TxPowerLevel;
2627 priv->EEPROMRfAOfdmChnlTxPwLevel[1] = EEPROM_Default_TxPowerLevel;
2628 priv->EEPROMRfAOfdmChnlTxPwLevel[2] = EEPROM_Default_TxPowerLevel;
2630 priv->EEPROMRfCCCKChnl1TxPwLevel[0] = EEPROM_Default_TxPowerLevel;
2631 priv->EEPROMRfCCCKChnl1TxPwLevel[1] = EEPROM_Default_TxPowerLevel;
2632 priv->EEPROMRfCCCKChnl1TxPwLevel[2] = EEPROM_Default_TxPowerLevel;
2634 priv->EEPROMRfCOfdmChnlTxPwLevel[0] = EEPROM_Default_TxPowerLevel;
2635 priv->EEPROMRfCOfdmChnlTxPwLevel[1] = EEPROM_Default_TxPowerLevel;
2636 priv->EEPROMRfCOfdmChnlTxPwLevel[2] = EEPROM_Default_TxPowerLevel;
2638 RT_TRACE(COMP_INIT, "priv->EEPROMRfACCKChnl1TxPwLevel[0] = 0x%x\n", priv->EEPROMRfACCKChnl1TxPwLevel[0]);
2639 RT_TRACE(COMP_INIT, "priv->EEPROMRfACCKChnl1TxPwLevel[1] = 0x%x\n", priv->EEPROMRfACCKChnl1TxPwLevel[1]);
2640 RT_TRACE(COMP_INIT, "priv->EEPROMRfACCKChnl1TxPwLevel[2] = 0x%x\n", priv->EEPROMRfACCKChnl1TxPwLevel[2]);
2641 RT_TRACE(COMP_INIT, "priv->EEPROMRfAOfdmChnlTxPwLevel[0] = 0x%x\n", priv->EEPROMRfAOfdmChnlTxPwLevel[0]);
2642 RT_TRACE(COMP_INIT, "priv->EEPROMRfAOfdmChnlTxPwLevel[1] = 0x%x\n", priv->EEPROMRfAOfdmChnlTxPwLevel[1]);
2643 RT_TRACE(COMP_INIT, "priv->EEPROMRfAOfdmChnlTxPwLevel[2] = 0x%x\n", priv->EEPROMRfAOfdmChnlTxPwLevel[2]);
2644 RT_TRACE(COMP_INIT, "priv->EEPROMRfCCCKChnl1TxPwLevel[0] = 0x%x\n", priv->EEPROMRfCCCKChnl1TxPwLevel[0]);
2645 RT_TRACE(COMP_INIT, "priv->EEPROMRfCCCKChnl1TxPwLevel[1] = 0x%x\n", priv->EEPROMRfCCCKChnl1TxPwLevel[1]);
2646 RT_TRACE(COMP_INIT, "priv->EEPROMRfCCCKChnl1TxPwLevel[2] = 0x%x\n", priv->EEPROMRfCCCKChnl1TxPwLevel[2]);
2647 RT_TRACE(COMP_INIT, "priv->EEPROMRfCOfdmChnlTxPwLevel[0] = 0x%x\n", priv->EEPROMRfCOfdmChnlTxPwLevel[0]);
2648 RT_TRACE(COMP_INIT, "priv->EEPROMRfCOfdmChnlTxPwLevel[1] = 0x%x\n", priv->EEPROMRfCOfdmChnlTxPwLevel[1]);
2649 RT_TRACE(COMP_INIT, "priv->EEPROMRfCOfdmChnlTxPwLevel[2] = 0x%x\n", priv->EEPROMRfCOfdmChnlTxPwLevel[2]);
2650 #endif
2654 // Update HAL variables.
2656 if(priv->epromtype == EPROM_93c46)
2658 for(i=0; i<14; i++)
2660 priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelCCK[i];
2661 priv->TxPowerLevelOFDM24G[i] = priv->EEPROMTxPowerLevelOFDM24G[i];
2663 priv->LegacyHTTxPowerDiff = priv->EEPROMLegacyHTTxPowerDiff;
2664 // Antenna B gain offset to antenna A, bit0~3
2665 priv->AntennaTxPwDiff[0] = (priv->EEPROMAntPwDiff & 0xf);
2666 // Antenna C gain offset to antenna A, bit4~7
2667 priv->AntennaTxPwDiff[1] = ((priv->EEPROMAntPwDiff & 0xf0)>>4);
2668 // Antenna D gain offset to antenna A, bit8~11
2669 priv->AntennaTxPwDiff[2] = ((priv->EEPROMAntPwDiff & 0xf00)>>8);
2670 // CrystalCap, bit12~15
2671 priv->CrystalCap = priv->EEPROMCrystalCap;
2672 // ThermalMeter, bit0~3 for RFIC1, bit4~7 for RFIC2
2673 priv->ThermalMeter[0] = (priv->EEPROMThermalMeter & 0xf);
2674 priv->ThermalMeter[1] = ((priv->EEPROMThermalMeter & 0xf0)>>4);
2676 else if(priv->epromtype == EPROM_93c56)
2678 //char cck_pwr_diff_a=0, cck_pwr_diff_c=0;
2680 //cck_pwr_diff_a = pHalData->EEPROMRfACCKChnl7TxPwLevel - pHalData->EEPROMRfAOfdmChnlTxPwLevel[1];
2681 //cck_pwr_diff_c = pHalData->EEPROMRfCCCKChnl7TxPwLevel - pHalData->EEPROMRfCOfdmChnlTxPwLevel[1];
2682 for(i=0; i<3; i++) // channel 1~3 use the same Tx Power Level.
2684 priv->TxPowerLevelCCK_A[i] = priv->EEPROMRfACCKChnl1TxPwLevel[0];
2685 priv->TxPowerLevelOFDM24G_A[i] = priv->EEPROMRfAOfdmChnlTxPwLevel[0];
2686 priv->TxPowerLevelCCK_C[i] = priv->EEPROMRfCCCKChnl1TxPwLevel[0];
2687 priv->TxPowerLevelOFDM24G_C[i] = priv->EEPROMRfCOfdmChnlTxPwLevel[0];
2689 for(i=3; i<9; i++) // channel 4~9 use the same Tx Power Level
2691 priv->TxPowerLevelCCK_A[i] = priv->EEPROMRfACCKChnl1TxPwLevel[1];
2692 priv->TxPowerLevelOFDM24G_A[i] = priv->EEPROMRfAOfdmChnlTxPwLevel[1];
2693 priv->TxPowerLevelCCK_C[i] = priv->EEPROMRfCCCKChnl1TxPwLevel[1];
2694 priv->TxPowerLevelOFDM24G_C[i] = priv->EEPROMRfCOfdmChnlTxPwLevel[1];
2696 for(i=9; i<14; i++) // channel 10~14 use the same Tx Power Level
2698 priv->TxPowerLevelCCK_A[i] = priv->EEPROMRfACCKChnl1TxPwLevel[2];
2699 priv->TxPowerLevelOFDM24G_A[i] = priv->EEPROMRfAOfdmChnlTxPwLevel[2];
2700 priv->TxPowerLevelCCK_C[i] = priv->EEPROMRfCCCKChnl1TxPwLevel[2];
2701 priv->TxPowerLevelOFDM24G_C[i] = priv->EEPROMRfCOfdmChnlTxPwLevel[2];
2703 for(i=0; i<14; i++)
2704 RT_TRACE(COMP_INIT, "priv->TxPowerLevelCCK_A[%d] = 0x%x\n", i, priv->TxPowerLevelCCK_A[i]);
2705 for(i=0; i<14; i++)
2706 RT_TRACE(COMP_INIT,"priv->TxPowerLevelOFDM24G_A[%d] = 0x%x\n", i, priv->TxPowerLevelOFDM24G_A[i]);
2707 for(i=0; i<14; i++)
2708 RT_TRACE(COMP_INIT, "priv->TxPowerLevelCCK_C[%d] = 0x%x\n", i, priv->TxPowerLevelCCK_C[i]);
2709 for(i=0; i<14; i++)
2710 RT_TRACE(COMP_INIT, "priv->TxPowerLevelOFDM24G_C[%d] = 0x%x\n", i, priv->TxPowerLevelOFDM24G_C[i]);
2711 priv->LegacyHTTxPowerDiff = priv->EEPROMLegacyHTTxPowerDiff;
2712 priv->AntennaTxPwDiff[0] = 0;
2713 priv->AntennaTxPwDiff[1] = 0;
2714 priv->AntennaTxPwDiff[2] = 0;
2715 priv->CrystalCap = priv->EEPROMCrystalCap;
2716 // ThermalMeter, bit0~3 for RFIC1, bit4~7 for RFIC2
2717 priv->ThermalMeter[0] = (priv->EEPROMThermalMeter & 0xf);
2718 priv->ThermalMeter[1] = ((priv->EEPROMThermalMeter & 0xf0)>>4);
2722 if(priv->rf_type == RF_1T2R)
2724 RT_TRACE(COMP_INIT, "\n1T2R config\n");
2726 else if (priv->rf_type == RF_2T4R)
2728 RT_TRACE(COMP_INIT, "\n2T4R config\n");
2731 // 2008/01/16 MH We can only know RF type in the function. So we have to init
2732 // DIG RATR table again.
2733 init_rate_adaptive(dev);
2735 //1 Make a copy for following variables and we can change them if we want
2737 priv->rf_chip= RF_8256;
2739 if(priv->RegChannelPlan == 0xf)
2741 priv->ChannelPlan = priv->eeprom_ChannelPlan;
2743 else
2745 priv->ChannelPlan = priv->RegChannelPlan;
2749 // Used PID and DID to Set CustomerID
2751 if( priv->eeprom_vid == 0x1186 && priv->eeprom_did == 0x3304 )
2753 priv->CustomerID = RT_CID_DLINK;
2756 switch(priv->eeprom_CustomerID)
2758 case EEPROM_CID_DEFAULT:
2759 priv->CustomerID = RT_CID_DEFAULT;
2760 break;
2761 case EEPROM_CID_CAMEO:
2762 priv->CustomerID = RT_CID_819x_CAMEO;
2763 break;
2764 case EEPROM_CID_RUNTOP:
2765 priv->CustomerID = RT_CID_819x_RUNTOP;
2766 break;
2767 case EEPROM_CID_NetCore:
2768 priv->CustomerID = RT_CID_819x_Netcore;
2769 break;
2770 case EEPROM_CID_TOSHIBA: // Merge by Jacken, 2008/01/31
2771 priv->CustomerID = RT_CID_TOSHIBA;
2772 if(priv->eeprom_ChannelPlan&0x80)
2773 priv->ChannelPlan = priv->eeprom_ChannelPlan&0x7f;
2774 else
2775 priv->ChannelPlan = 0x0;
2776 RT_TRACE(COMP_INIT, "Toshiba ChannelPlan = 0x%x\n",
2777 priv->ChannelPlan);
2778 break;
2779 case EEPROM_CID_Nettronix:
2780 priv->ScanDelay = 100; //cosa add for scan
2781 priv->CustomerID = RT_CID_Nettronix;
2782 break;
2783 case EEPROM_CID_Pronet:
2784 priv->CustomerID = RT_CID_PRONET;
2785 break;
2786 case EEPROM_CID_DLINK:
2787 priv->CustomerID = RT_CID_DLINK;
2788 break;
2790 case EEPROM_CID_WHQL:
2791 //Adapter->bInHctTest = TRUE;//do not supported
2793 //priv->bSupportTurboMode = FALSE;
2794 //priv->bAutoTurboBy8186 = FALSE;
2796 //pMgntInfo->PowerSaveControl.bInactivePs = FALSE;
2797 //pMgntInfo->PowerSaveControl.bIPSModeBackup = FALSE;
2798 //pMgntInfo->PowerSaveControl.bLeisurePs = FALSE;
2800 break;
2801 default:
2802 // value from RegCustomerID
2803 break;
2806 //Avoid the channel plan array overflow, by Bruce, 2007-08-27.
2807 if(priv->ChannelPlan > CHANNEL_PLAN_LEN - 1)
2808 priv->ChannelPlan = 0; //FCC
2810 switch(priv->CustomerID)
2812 case RT_CID_DEFAULT:
2813 #ifdef RTL8190P
2814 priv->LedStrategy = HW_LED;
2815 #else
2816 #ifdef RTL8192E
2817 priv->LedStrategy = SW_LED_MODE1;
2818 #endif
2819 #endif
2820 break;
2822 case RT_CID_819x_CAMEO:
2823 priv->LedStrategy = SW_LED_MODE2;
2824 break;
2826 case RT_CID_819x_RUNTOP:
2827 priv->LedStrategy = SW_LED_MODE3;
2828 break;
2830 case RT_CID_819x_Netcore:
2831 priv->LedStrategy = SW_LED_MODE4;
2832 break;
2834 case RT_CID_Nettronix:
2835 priv->LedStrategy = SW_LED_MODE5;
2836 break;
2838 case RT_CID_PRONET:
2839 priv->LedStrategy = SW_LED_MODE6;
2840 break;
2842 case RT_CID_TOSHIBA: //Modify by Jacken 2008/01/31
2843 // Do nothing.
2844 //break;
2846 default:
2847 #ifdef RTL8190P
2848 priv->LedStrategy = HW_LED;
2849 #else
2850 #ifdef RTL8192E
2851 priv->LedStrategy = SW_LED_MODE1;
2852 #endif
2853 #endif
2854 break;
2858 if( priv->eeprom_vid == 0x1186 && priv->eeprom_did == 0x3304)
2859 priv->ieee80211->bSupportRemoteWakeUp = true;
2860 else
2861 priv->ieee80211->bSupportRemoteWakeUp = false;
2864 RT_TRACE(COMP_INIT, "RegChannelPlan(%d)\n", priv->RegChannelPlan);
2865 RT_TRACE(COMP_INIT, "ChannelPlan = %d \n", priv->ChannelPlan);
2866 RT_TRACE(COMP_INIT, "LedStrategy = %d \n", priv->LedStrategy);
2867 RT_TRACE(COMP_TRACE, "<==== ReadAdapterInfo\n");
2869 return ;
2873 static short rtl8192_get_channel_map(struct net_device * dev)
2875 struct r8192_priv *priv = ieee80211_priv(dev);
2876 #ifdef ENABLE_DOT11D
2877 if(priv->ChannelPlan> COUNTRY_CODE_GLOBAL_DOMAIN){
2878 printk("rtl8180_init:Error channel plan! Set to default.\n");
2879 priv->ChannelPlan= 0;
2881 RT_TRACE(COMP_INIT, "Channel plan is %d\n",priv->ChannelPlan);
2883 rtl819x_set_channel_map(priv->ChannelPlan, priv);
2884 #else
2885 int ch,i;
2886 //Set Default Channel Plan
2887 if(!channels){
2888 DMESG("No channels, aborting");
2889 return -1;
2891 ch=channels;
2892 priv->ChannelPlan= 0;//hikaru
2893 // set channels 1..14 allowed in given locale
2894 for (i=1; i<=14; i++) {
2895 (priv->ieee80211->channel_map)[i] = (u8)(ch & 0x01);
2896 ch >>= 1;
2898 #endif
2899 return 0;
2902 static short rtl8192_init(struct net_device *dev)
2904 struct r8192_priv *priv = ieee80211_priv(dev);
2905 memset(&(priv->stats),0,sizeof(struct Stats));
2906 rtl8192_init_priv_variable(dev);
2907 rtl8192_init_priv_lock(priv);
2908 rtl8192_init_priv_task(dev);
2909 rtl8192_get_eeprom_size(dev);
2910 rtl8192_read_eeprom_info(dev);
2911 rtl8192_get_channel_map(dev);
2912 init_hal_dm(dev);
2913 init_timer(&priv->watch_dog_timer);
2914 priv->watch_dog_timer.data = (unsigned long)dev;
2915 priv->watch_dog_timer.function = watch_dog_timer_callback;
2916 if (request_irq(dev->irq, rtl8192_interrupt, IRQF_SHARED, dev->name, dev)) {
2917 printk("Error allocating IRQ %d",dev->irq);
2918 return -1;
2919 }else{
2920 priv->irq=dev->irq;
2921 printk("IRQ %d",dev->irq);
2923 if(rtl8192_pci_initdescring(dev)!=0){
2924 printk("Endopoints initialization failed");
2925 return -1;
2928 //rtl8192_rx_enable(dev);
2929 //rtl8192_adapter_start(dev);
2930 return 0;
2934 * Actually only set RRSR, RATR and BW_OPMODE registers
2935 * not to do all the hw config as its name says
2936 * This part need to modified according to the rate set we filtered
2938 static void rtl8192_hwconfig(struct net_device* dev)
2940 u32 regRATR = 0, regRRSR = 0;
2941 u8 regBwOpMode = 0, regTmp = 0;
2942 struct r8192_priv *priv = ieee80211_priv(dev);
2944 // Set RRSR, RATR, and BW_OPMODE registers
2946 switch(priv->ieee80211->mode)
2948 case WIRELESS_MODE_B:
2949 regBwOpMode = BW_OPMODE_20MHZ;
2950 regRATR = RATE_ALL_CCK;
2951 regRRSR = RATE_ALL_CCK;
2952 break;
2953 case WIRELESS_MODE_A:
2954 regBwOpMode = BW_OPMODE_5G |BW_OPMODE_20MHZ;
2955 regRATR = RATE_ALL_OFDM_AG;
2956 regRRSR = RATE_ALL_OFDM_AG;
2957 break;
2958 case WIRELESS_MODE_G:
2959 regBwOpMode = BW_OPMODE_20MHZ;
2960 regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
2961 regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
2962 break;
2963 case WIRELESS_MODE_AUTO:
2964 case WIRELESS_MODE_N_24G:
2965 // It support CCK rate by default.
2966 // CCK rate will be filtered out only when associated AP does not support it.
2967 regBwOpMode = BW_OPMODE_20MHZ;
2968 regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
2969 regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
2970 break;
2971 case WIRELESS_MODE_N_5G:
2972 regBwOpMode = BW_OPMODE_5G;
2973 regRATR = RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
2974 regRRSR = RATE_ALL_OFDM_AG;
2975 break;
2978 write_nic_byte(dev, BW_OPMODE, regBwOpMode);
2980 u32 ratr_value = 0;
2981 ratr_value = regRATR;
2982 if (priv->rf_type == RF_1T2R)
2984 ratr_value &= ~(RATE_ALL_OFDM_2SS);
2986 write_nic_dword(dev, RATR0, ratr_value);
2987 write_nic_byte(dev, UFWP, 1);
2989 regTmp = read_nic_byte(dev, 0x313);
2990 regRRSR = ((regTmp) << 24) | (regRRSR & 0x00ffffff);
2991 write_nic_dword(dev, RRSR, regRRSR);
2994 // Set Retry Limit here
2996 write_nic_word(dev, RETRY_LIMIT,
2997 priv->ShortRetryLimit << RETRY_LIMIT_SHORT_SHIFT |
2998 priv->LongRetryLimit << RETRY_LIMIT_LONG_SHIFT);
2999 // Set Contention Window here
3001 // Set Tx AGC
3003 // Set Tx Antenna including Feedback control
3005 // Set Auto Rate fallback control
3011 static RT_STATUS rtl8192_adapter_start(struct net_device *dev)
3013 struct r8192_priv *priv = ieee80211_priv(dev);
3014 // struct ieee80211_device *ieee = priv->ieee80211;
3015 u32 ulRegRead;
3016 RT_STATUS rtStatus = RT_STATUS_SUCCESS;
3017 //u8 eRFPath;
3018 u8 tmpvalue;
3019 #ifdef RTL8192E
3020 u8 ICVersion,SwitchingRegulatorOutput;
3021 #endif
3022 bool bfirmwareok = true;
3023 #ifdef RTL8190P
3024 u8 ucRegRead;
3025 #endif
3026 u32 tmpRegA, tmpRegC, TempCCk;
3027 int i =0;
3029 RT_TRACE(COMP_INIT, "====>%s()\n", __FUNCTION__);
3030 priv->being_init_adapter = true;
3031 rtl8192_pci_resetdescring(dev);
3032 // 2007/11/02 MH Before initalizing RF. We can not use FW to do RF-R/W.
3033 priv->Rf_Mode = RF_OP_By_SW_3wire;
3034 #ifdef RTL8192E
3035 //dPLL on
3036 if(priv->ResetProgress == RESET_TYPE_NORESET)
3038 write_nic_byte(dev, ANAPAR, 0x37);
3039 // Accordign to designer's explain, LBUS active will never > 10ms. We delay 10ms
3040 // Joseph increae the time to prevent firmware download fail
3041 mdelay(500);
3043 #endif
3044 //PlatformSleepUs(10000);
3045 // For any kind of InitializeAdapter process, we shall use system now!!
3046 priv->pFirmware->firmware_status = FW_STATUS_0_INIT;
3048 // Set to eRfoff in order not to count receive count.
3049 if(priv->RegRfOff == TRUE)
3050 priv->ieee80211->eRFPowerState = eRfOff;
3053 //3 //Config CPUReset Register
3054 //3//
3055 //3 Firmware Reset Or Not
3056 ulRegRead = read_nic_dword(dev, CPU_GEN);
3057 if(priv->pFirmware->firmware_status == FW_STATUS_0_INIT)
3058 { //called from MPInitialized. do nothing
3059 ulRegRead |= CPU_GEN_SYSTEM_RESET;
3060 }else if(priv->pFirmware->firmware_status == FW_STATUS_5_READY)
3061 ulRegRead |= CPU_GEN_FIRMWARE_RESET; // Called from MPReset
3062 else
3063 RT_TRACE(COMP_ERR, "ERROR in %s(): undefined firmware state(%d)\n", __FUNCTION__, priv->pFirmware->firmware_status);
3065 #ifdef RTL8190P
3066 //2008.06.03, for WOL 90 hw bug
3067 ulRegRead &= (~(CPU_GEN_GPIO_UART));
3068 #endif
3070 write_nic_dword(dev, CPU_GEN, ulRegRead);
3071 //mdelay(100);
3073 #ifdef RTL8192E
3075 //3//
3076 //3 //Fix the issue of E-cut high temperature issue
3077 //3//
3078 // TODO: E cut only
3079 ICVersion = read_nic_byte(dev, IC_VERRSION);
3080 if(ICVersion >= 0x4) //E-cut only
3082 // HW SD suggest that we should not wirte this register too often, so driver
3083 // should readback this register. This register will be modified only when
3084 // power on reset
3085 SwitchingRegulatorOutput = read_nic_byte(dev, SWREGULATOR);
3086 if(SwitchingRegulatorOutput != 0xb8)
3088 write_nic_byte(dev, SWREGULATOR, 0xa8);
3089 mdelay(1);
3090 write_nic_byte(dev, SWREGULATOR, 0xb8);
3093 #endif
3096 //3//
3097 //3// Initialize BB before MAC
3098 //3//
3099 RT_TRACE(COMP_INIT, "BB Config Start!\n");
3100 rtStatus = rtl8192_BBConfig(dev);
3101 if(rtStatus != RT_STATUS_SUCCESS)
3103 RT_TRACE(COMP_ERR, "BB Config failed\n");
3104 return rtStatus;
3106 RT_TRACE(COMP_INIT,"BB Config Finished!\n");
3108 //3//Set Loopback mode or Normal mode
3109 //3//
3110 //2006.12.13 by emily. Note!We should not merge these two CPU_GEN register writings
3111 // because setting of System_Reset bit reset MAC to default transmission mode.
3112 //Loopback mode or not
3113 priv->LoopbackMode = RTL819X_NO_LOOPBACK;
3114 //priv->LoopbackMode = RTL819X_MAC_LOOPBACK;
3115 if(priv->ResetProgress == RESET_TYPE_NORESET)
3117 ulRegRead = read_nic_dword(dev, CPU_GEN);
3118 if(priv->LoopbackMode == RTL819X_NO_LOOPBACK)
3120 ulRegRead = ((ulRegRead & CPU_GEN_NO_LOOPBACK_MSK) | CPU_GEN_NO_LOOPBACK_SET);
3122 else if (priv->LoopbackMode == RTL819X_MAC_LOOPBACK )
3124 ulRegRead |= CPU_CCK_LOOPBACK;
3126 else
3128 RT_TRACE(COMP_ERR,"Serious error: wrong loopback mode setting\n");
3131 //2008.06.03, for WOL
3132 //ulRegRead &= (~(CPU_GEN_GPIO_UART));
3133 write_nic_dword(dev, CPU_GEN, ulRegRead);
3135 // 2006.11.29. After reset cpu, we sholud wait for a second, otherwise, it may fail to write registers. Emily
3136 udelay(500);
3138 //3Set Hardware(Do nothing now)
3139 rtl8192_hwconfig(dev);
3140 //2=======================================================
3141 // Common Setting for all of the FPGA platform. (part 1)
3142 //2=======================================================
3143 // If there is changes, please make sure it applies to all of the FPGA version
3144 //3 Turn on Tx/Rx
3145 write_nic_byte(dev, CMDR, CR_RE|CR_TE);
3147 //2Set Tx dma burst
3148 #ifdef RTL8190P
3149 write_nic_byte(dev, PCIF, ((MXDMA2_NoLimit<<MXDMA2_RX_SHIFT) |
3150 (MXDMA2_NoLimit<<MXDMA2_TX_SHIFT) |
3151 (1<<MULRW_SHIFT)));
3152 #else
3153 #ifdef RTL8192E
3154 write_nic_byte(dev, PCIF, ((MXDMA2_NoLimit<<MXDMA2_RX_SHIFT) |
3155 (MXDMA2_NoLimit<<MXDMA2_TX_SHIFT) ));
3156 #endif
3157 #endif
3158 //set IDR0 here
3159 write_nic_dword(dev, MAC0, ((u32*)dev->dev_addr)[0]);
3160 write_nic_word(dev, MAC4, ((u16*)(dev->dev_addr + 4))[0]);
3161 //set RCR
3162 write_nic_dword(dev, RCR, priv->ReceiveConfig);
3164 //3 Initialize Number of Reserved Pages in Firmware Queue
3165 #ifdef TO_DO_LIST
3166 if(priv->bInHctTest)
3168 PlatformEFIOWrite4Byte(Adapter, RQPN1, NUM_OF_PAGE_IN_FW_QUEUE_BK_DTM << RSVD_FW_QUEUE_PAGE_BK_SHIFT |
3169 NUM_OF_PAGE_IN_FW_QUEUE_BE_DTM << RSVD_FW_QUEUE_PAGE_BE_SHIFT |
3170 NUM_OF_PAGE_IN_FW_QUEUE_VI_DTM << RSVD_FW_QUEUE_PAGE_VI_SHIFT |
3171 NUM_OF_PAGE_IN_FW_QUEUE_VO_DTM <<RSVD_FW_QUEUE_PAGE_VO_SHIFT);
3172 PlatformEFIOWrite4Byte(Adapter, RQPN2, NUM_OF_PAGE_IN_FW_QUEUE_MGNT << RSVD_FW_QUEUE_PAGE_MGNT_SHIFT);
3173 PlatformEFIOWrite4Byte(Adapter, RQPN3, APPLIED_RESERVED_QUEUE_IN_FW|
3174 NUM_OF_PAGE_IN_FW_QUEUE_BCN<<RSVD_FW_QUEUE_PAGE_BCN_SHIFT|
3175 NUM_OF_PAGE_IN_FW_QUEUE_PUB_DTM<<RSVD_FW_QUEUE_PAGE_PUB_SHIFT);
3177 else
3178 #endif
3180 write_nic_dword(dev, RQPN1, NUM_OF_PAGE_IN_FW_QUEUE_BK << RSVD_FW_QUEUE_PAGE_BK_SHIFT |
3181 NUM_OF_PAGE_IN_FW_QUEUE_BE << RSVD_FW_QUEUE_PAGE_BE_SHIFT |
3182 NUM_OF_PAGE_IN_FW_QUEUE_VI << RSVD_FW_QUEUE_PAGE_VI_SHIFT |
3183 NUM_OF_PAGE_IN_FW_QUEUE_VO <<RSVD_FW_QUEUE_PAGE_VO_SHIFT);
3184 write_nic_dword(dev, RQPN2, NUM_OF_PAGE_IN_FW_QUEUE_MGNT << RSVD_FW_QUEUE_PAGE_MGNT_SHIFT);
3185 write_nic_dword(dev, RQPN3, APPLIED_RESERVED_QUEUE_IN_FW|
3186 NUM_OF_PAGE_IN_FW_QUEUE_BCN<<RSVD_FW_QUEUE_PAGE_BCN_SHIFT|
3187 NUM_OF_PAGE_IN_FW_QUEUE_PUB<<RSVD_FW_QUEUE_PAGE_PUB_SHIFT);
3190 rtl8192_tx_enable(dev);
3191 rtl8192_rx_enable(dev);
3192 //3Set Response Rate Setting Register
3193 // CCK rate is supported by default.
3194 // CCK rate will be filtered out only when associated AP does not support it.
3195 ulRegRead = (0xFFF00000 & read_nic_dword(dev, RRSR)) | RATE_ALL_OFDM_AG | RATE_ALL_CCK;
3196 write_nic_dword(dev, RRSR, ulRegRead);
3197 write_nic_dword(dev, RATR0+4*7, (RATE_ALL_OFDM_AG | RATE_ALL_CCK));
3199 //2Set AckTimeout
3200 // TODO: (it value is only for FPGA version). need to be changed!!2006.12.18, by Emily
3201 write_nic_byte(dev, ACK_TIMEOUT, 0x30);
3203 //rtl8192_actset_wirelessmode(dev,priv->RegWirelessMode);
3204 if(priv->ResetProgress == RESET_TYPE_NORESET)
3205 rtl8192_SetWirelessMode(dev, priv->ieee80211->mode);
3206 //-----------------------------------------------------------------------------
3207 // Set up security related. 070106, by rcnjko:
3208 // 1. Clear all H/W keys.
3209 // 2. Enable H/W encryption/decryption.
3210 //-----------------------------------------------------------------------------
3211 CamResetAllEntry(dev);
3213 u8 SECR_value = 0x0;
3214 SECR_value |= SCR_TxEncEnable;
3215 SECR_value |= SCR_RxDecEnable;
3216 SECR_value |= SCR_NoSKMC;
3217 write_nic_byte(dev, SECR, SECR_value);
3219 //3Beacon related
3220 write_nic_word(dev, ATIMWND, 2);
3221 write_nic_word(dev, BCN_INTERVAL, 100);
3222 for (i=0; i<QOS_QUEUE_NUM; i++)
3223 write_nic_dword(dev, WDCAPARA_ADD[i], 0x005e4332);
3225 // Switching regulator controller: This is set temporarily.
3226 // It's not sure if this can be removed in the future.
3227 // PJ advised to leave it by default.
3229 write_nic_byte(dev, 0xbe, 0xc0);
3231 //2=======================================================
3232 // Set PHY related configuration defined in MAC register bank
3233 //2=======================================================
3234 rtl8192_phy_configmac(dev);
3236 if (priv->card_8192_version > (u8) VERSION_8190_BD) {
3237 rtl8192_phy_getTxPower(dev);
3238 rtl8192_phy_setTxPower(dev, priv->chan);
3241 //if D or C cut
3242 tmpvalue = read_nic_byte(dev, IC_VERRSION);
3243 priv->IC_Cut = tmpvalue;
3244 RT_TRACE(COMP_INIT, "priv->IC_Cut = 0x%x\n", priv->IC_Cut);
3245 if(priv->IC_Cut >= IC_VersionCut_D)
3247 //pHalData->bDcut = TRUE;
3248 if(priv->IC_Cut == IC_VersionCut_D)
3249 RT_TRACE(COMP_INIT, "D-cut\n");
3250 if(priv->IC_Cut == IC_VersionCut_E)
3252 RT_TRACE(COMP_INIT, "E-cut\n");
3253 // HW SD suggest that we should not wirte this register too often, so driver
3254 // should readback this register. This register will be modified only when
3255 // power on reset
3258 else
3260 //pHalData->bDcut = FALSE;
3261 RT_TRACE(COMP_INIT, "Before C-cut\n");
3264 #if 1
3265 //Firmware download
3266 RT_TRACE(COMP_INIT, "Load Firmware!\n");
3267 bfirmwareok = init_firmware(dev);
3268 if(bfirmwareok != true) {
3269 rtStatus = RT_STATUS_FAILURE;
3270 return rtStatus;
3272 RT_TRACE(COMP_INIT, "Load Firmware finished!\n");
3273 #endif
3274 //RF config
3275 if(priv->ResetProgress == RESET_TYPE_NORESET)
3277 RT_TRACE(COMP_INIT, "RF Config Started!\n");
3278 rtStatus = rtl8192_phy_RFConfig(dev);
3279 if(rtStatus != RT_STATUS_SUCCESS)
3281 RT_TRACE(COMP_ERR, "RF Config failed\n");
3282 return rtStatus;
3284 RT_TRACE(COMP_INIT, "RF Config Finished!\n");
3286 rtl8192_phy_updateInitGain(dev);
3288 /*---- Set CCK and OFDM Block "ON"----*/
3289 rtl8192_setBBreg(dev, rFPGA0_RFMOD, bCCKEn, 0x1);
3290 rtl8192_setBBreg(dev, rFPGA0_RFMOD, bOFDMEn, 0x1);
3292 #ifdef RTL8192E
3293 //Enable Led
3294 write_nic_byte(dev, 0x87, 0x0);
3295 #endif
3296 #ifdef RTL8190P
3297 //2008.06.03, for WOL
3298 ucRegRead = read_nic_byte(dev, GPE);
3299 ucRegRead |= BIT0;
3300 write_nic_byte(dev, GPE, ucRegRead);
3302 ucRegRead = read_nic_byte(dev, GPO);
3303 ucRegRead &= ~BIT0;
3304 write_nic_byte(dev, GPO, ucRegRead);
3305 #endif
3307 //2=======================================================
3308 // RF Power Save
3309 //2=======================================================
3310 #ifdef ENABLE_IPS
3313 if(priv->RegRfOff == TRUE)
3314 { // User disable RF via registry.
3315 RT_TRACE((COMP_INIT|COMP_RF|COMP_POWER), "%s(): Turn off RF for RegRfOff ----------\n",__FUNCTION__);
3316 MgntActSet_RF_State(dev, eRfOff, RF_CHANGE_BY_SW);
3317 #if 0//cosa, ask SD3 willis and he doesn't know what is this for
3318 // Those action will be discard in MgntActSet_RF_State because off the same state
3319 for(eRFPath = 0; eRFPath <pHalData->NumTotalRFPath; eRFPath++)
3320 PHY_SetRFReg(Adapter, (RF90_RADIO_PATH_E)eRFPath, 0x4, 0xC00, 0x0);
3321 #endif
3323 else if(priv->ieee80211->RfOffReason > RF_CHANGE_BY_PS)
3324 { // H/W or S/W RF OFF before sleep.
3325 RT_TRACE((COMP_INIT|COMP_RF|COMP_POWER), "%s(): Turn off RF for RfOffReason(%d) ----------\n", __FUNCTION__,priv->ieee80211->RfOffReason);
3326 MgntActSet_RF_State(dev, eRfOff, priv->ieee80211->RfOffReason);
3328 else if(priv->ieee80211->RfOffReason >= RF_CHANGE_BY_IPS)
3329 { // H/W or S/W RF OFF before sleep.
3330 RT_TRACE((COMP_INIT|COMP_RF|COMP_POWER), "%s(): Turn off RF for RfOffReason(%d) ----------\n", __FUNCTION__,priv->ieee80211->RfOffReason);
3331 MgntActSet_RF_State(dev, eRfOff, priv->ieee80211->RfOffReason);
3333 else
3335 RT_TRACE((COMP_INIT|COMP_RF|COMP_POWER), "%s(): RF-ON \n",__FUNCTION__);
3336 priv->ieee80211->eRFPowerState = eRfOn;
3337 priv->ieee80211->RfOffReason = 0;
3338 //DrvIFIndicateCurrentPhyStatus(Adapter);
3339 // LED control
3340 //Adapter->HalFunc.LedControlHandler(Adapter, LED_CTL_POWER_ON);
3343 // If inactive power mode is enabled, disable rf while in disconnected state.
3344 // But we should still tell upper layer we are in rf on state.
3345 // 2007.07.16, by shien chang.
3347 //if(!Adapter->bInHctTest)
3348 //IPSEnter(Adapter);
3352 #endif
3353 if(1){
3354 #ifdef RTL8192E
3355 // We can force firmware to do RF-R/W
3356 if(priv->ieee80211->FwRWRF)
3357 priv->Rf_Mode = RF_OP_By_FW;
3358 else
3359 priv->Rf_Mode = RF_OP_By_SW_3wire;
3360 #else
3361 priv->Rf_Mode = RF_OP_By_SW_3wire;
3362 #endif
3364 #ifdef RTL8190P
3365 if(priv->ResetProgress == RESET_TYPE_NORESET)
3367 dm_initialize_txpower_tracking(dev);
3369 tmpRegA= rtl8192_QueryBBReg(dev,rOFDM0_XATxIQImbalance,bMaskDWord);
3370 tmpRegC= rtl8192_QueryBBReg(dev,rOFDM0_XCTxIQImbalance,bMaskDWord);
3372 if(priv->rf_type == RF_2T4R){
3373 for(i = 0; i<TxBBGainTableLength; i++)
3375 if(tmpRegA == priv->txbbgain_table[i].txbbgain_value)
3377 priv->rfa_txpowertrackingindex= (u8)i;
3378 priv->rfa_txpowertrackingindex_real= (u8)i;
3379 priv->rfa_txpowertracking_default = priv->rfa_txpowertrackingindex;
3380 break;
3384 for(i = 0; i<TxBBGainTableLength; i++)
3386 if(tmpRegC == priv->txbbgain_table[i].txbbgain_value)
3388 priv->rfc_txpowertrackingindex= (u8)i;
3389 priv->rfc_txpowertrackingindex_real= (u8)i;
3390 priv->rfc_txpowertracking_default = priv->rfc_txpowertrackingindex;
3391 break;
3394 TempCCk = rtl8192_QueryBBReg(dev, rCCK0_TxFilter1, bMaskByte2);
3396 for(i=0 ; i<CCKTxBBGainTableLength ; i++)
3398 if(TempCCk == priv->cck_txbbgain_table[i].ccktxbb_valuearray[0])
3400 priv->CCKPresentAttentuation_20Mdefault =(u8) i;
3401 break;
3404 priv->CCKPresentAttentuation_40Mdefault = 0;
3405 priv->CCKPresentAttentuation_difference = 0;
3406 priv->CCKPresentAttentuation = priv->CCKPresentAttentuation_20Mdefault;
3407 RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex_initial = %d\n", priv->rfa_txpowertrackingindex);
3408 RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex_real__initial = %d\n", priv->rfa_txpowertrackingindex_real);
3409 RT_TRACE(COMP_POWER_TRACKING, "priv->rfc_txpowertrackingindex_initial = %d\n", priv->rfc_txpowertrackingindex);
3410 RT_TRACE(COMP_POWER_TRACKING, "priv->rfc_txpowertrackingindex_real_initial = %d\n", priv->rfc_txpowertrackingindex_real);
3411 RT_TRACE(COMP_POWER_TRACKING, "priv->CCKPresentAttentuation_difference_initial = %d\n", priv->CCKPresentAttentuation_difference);
3412 RT_TRACE(COMP_POWER_TRACKING, "priv->CCKPresentAttentuation_initial = %d\n", priv->CCKPresentAttentuation);
3414 #else
3415 #ifdef RTL8192E
3416 if(priv->ResetProgress == RESET_TYPE_NORESET)
3418 dm_initialize_txpower_tracking(dev);
3420 if(priv->IC_Cut >= IC_VersionCut_D)
3422 tmpRegA= rtl8192_QueryBBReg(dev,rOFDM0_XATxIQImbalance,bMaskDWord);
3423 tmpRegC= rtl8192_QueryBBReg(dev,rOFDM0_XCTxIQImbalance,bMaskDWord);
3424 for(i = 0; i<TxBBGainTableLength; i++)
3426 if(tmpRegA == priv->txbbgain_table[i].txbbgain_value)
3428 priv->rfa_txpowertrackingindex= (u8)i;
3429 priv->rfa_txpowertrackingindex_real= (u8)i;
3430 priv->rfa_txpowertracking_default = priv->rfa_txpowertrackingindex;
3431 break;
3435 TempCCk = rtl8192_QueryBBReg(dev, rCCK0_TxFilter1, bMaskByte2);
3437 for(i=0 ; i<CCKTxBBGainTableLength ; i++)
3439 if(TempCCk == priv->cck_txbbgain_table[i].ccktxbb_valuearray[0])
3441 priv->CCKPresentAttentuation_20Mdefault =(u8) i;
3442 break;
3445 priv->CCKPresentAttentuation_40Mdefault = 0;
3446 priv->CCKPresentAttentuation_difference = 0;
3447 priv->CCKPresentAttentuation = priv->CCKPresentAttentuation_20Mdefault;
3448 RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex_initial = %d\n", priv->rfa_txpowertrackingindex);
3449 RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex_real__initial = %d\n", priv->rfa_txpowertrackingindex_real);
3450 RT_TRACE(COMP_POWER_TRACKING, "priv->CCKPresentAttentuation_difference_initial = %d\n", priv->CCKPresentAttentuation_difference);
3451 RT_TRACE(COMP_POWER_TRACKING, "priv->CCKPresentAttentuation_initial = %d\n", priv->CCKPresentAttentuation);
3452 priv->btxpower_tracking = FALSE;//TEMPLY DISABLE
3455 #endif
3456 #endif
3457 rtl8192_irq_enable(dev);
3458 priv->being_init_adapter = false;
3459 return rtStatus;
3463 static void rtl8192_prepare_beacon(struct r8192_priv *priv)
3465 struct sk_buff *skb;
3466 //unsigned long flags;
3467 cb_desc *tcb_desc;
3469 skb = ieee80211_get_beacon(priv->ieee80211);
3470 tcb_desc = (cb_desc *)(skb->cb + 8);
3471 //spin_lock_irqsave(&priv->tx_lock,flags);
3472 /* prepare misc info for the beacon xmit */
3473 tcb_desc->queue_index = BEACON_QUEUE;
3474 /* IBSS does not support HT yet, use 1M defaultly */
3475 tcb_desc->data_rate = 2;
3476 tcb_desc->RATRIndex = 7;
3477 tcb_desc->bTxDisableRateFallBack = 1;
3478 tcb_desc->bTxUseDriverAssingedRate = 1;
3480 skb_push(skb, priv->ieee80211->tx_headroom);
3481 if(skb){
3482 rtl8192_tx(priv->ieee80211->dev,skb);
3484 //spin_unlock_irqrestore (&priv->tx_lock, flags);
3489 * configure registers for beacon tx and enables it via
3490 * rtl8192_beacon_tx_enable(). rtl8192_beacon_tx_disable() might
3491 * be used to stop beacon transmission
3493 static void rtl8192_start_beacon(struct net_device *dev)
3495 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
3496 struct ieee80211_network *net = &priv->ieee80211->current_network;
3497 u16 BcnTimeCfg = 0;
3498 u16 BcnCW = 6;
3499 u16 BcnIFS = 0xf;
3501 DMESG("Enabling beacon TX");
3502 //rtl8192_prepare_beacon(dev);
3503 rtl8192_irq_disable(dev);
3504 //rtl8192_beacon_tx_enable(dev);
3506 /* ATIM window */
3507 write_nic_word(dev, ATIMWND, 2);
3509 /* Beacon interval (in unit of TU) */
3510 write_nic_word(dev, BCN_INTERVAL, net->beacon_interval);
3513 * DrvErlyInt (in unit of TU).
3514 * (Time to send interrupt to notify driver to c
3515 * hange beacon content)
3516 * */
3517 write_nic_word(dev, BCN_DRV_EARLY_INT, 10);
3520 * BcnDMATIM(in unit of us).
3521 * Indicates the time before TBTT to perform beacon queue DMA
3522 * */
3523 write_nic_word(dev, BCN_DMATIME, 256);
3526 * Force beacon frame transmission even after receiving
3527 * beacon frame from other ad hoc STA
3528 * */
3529 write_nic_byte(dev, BCN_ERR_THRESH, 100);
3531 /* Set CW and IFS */
3532 BcnTimeCfg |= BcnCW<<BCN_TCFG_CW_SHIFT;
3533 BcnTimeCfg |= BcnIFS<<BCN_TCFG_IFS;
3534 write_nic_word(dev, BCN_TCFG, BcnTimeCfg);
3537 /* enable the interrupt for ad-hoc process */
3538 rtl8192_irq_enable(dev);
3541 static bool HalTxCheckStuck8190Pci(struct net_device *dev)
3543 u16 RegTxCounter = read_nic_word(dev, 0x128);
3544 struct r8192_priv *priv = ieee80211_priv(dev);
3545 bool bStuck = FALSE;
3546 RT_TRACE(COMP_RESET,"%s():RegTxCounter is %d,TxCounter is %d\n",__FUNCTION__,RegTxCounter,priv->TxCounter);
3547 if(priv->TxCounter==RegTxCounter)
3548 bStuck = TRUE;
3550 priv->TxCounter = RegTxCounter;
3552 return bStuck;
3556 * Assumption: RT_TX_SPINLOCK is acquired.
3558 static RESET_TYPE
3559 TxCheckStuck(struct net_device *dev)
3561 struct r8192_priv *priv = ieee80211_priv(dev);
3562 u8 QueueID;
3563 ptx_ring head=NULL,tail=NULL,txring = NULL;
3564 u8 ResetThreshold = NIC_SEND_HANG_THRESHOLD_POWERSAVE;
3565 bool bCheckFwTxCnt = false;
3568 // Decide Stuch threshold according to current power save mode
3570 switch (priv->ieee80211->dot11PowerSaveMode)
3572 // The threshold value may required to be adjusted .
3573 case eActive: // Active/Continuous access.
3574 ResetThreshold = NIC_SEND_HANG_THRESHOLD_NORMAL;
3575 break;
3576 case eMaxPs: // Max power save mode.
3577 ResetThreshold = NIC_SEND_HANG_THRESHOLD_POWERSAVE;
3578 break;
3579 case eFastPs: // Fast power save mode.
3580 ResetThreshold = NIC_SEND_HANG_THRESHOLD_POWERSAVE;
3581 break;
3585 // Check whether specific tcb has been queued for a specific time
3587 for(QueueID = 0; QueueID < MAX_TX_QUEUE; QueueID++)
3591 if(QueueID == TXCMD_QUEUE)
3592 continue;
3594 switch(QueueID) {
3595 case MGNT_QUEUE:
3596 tail=priv->txmapringtail;
3597 head=priv->txmapringhead;
3598 break;
3600 case BK_QUEUE:
3601 tail=priv->txbkpringtail;
3602 head=priv->txbkpringhead;
3603 break;
3605 case BE_QUEUE:
3606 tail=priv->txbepringtail;
3607 head=priv->txbepringhead;
3608 break;
3610 case VI_QUEUE:
3611 tail=priv->txvipringtail;
3612 head=priv->txvipringhead;
3613 break;
3615 case VO_QUEUE:
3616 tail=priv->txvopringtail;
3617 head=priv->txvopringhead;
3618 break;
3620 default:
3621 tail=head=NULL;
3622 break;
3625 if(tail == head)
3626 continue;
3627 else
3629 txring = head;
3630 if(txring == NULL)
3632 RT_TRACE(COMP_ERR,"%s():txring is NULL , BUG!\n",__FUNCTION__);
3633 continue;
3635 txring->nStuckCount++;
3636 bCheckFwTxCnt = TRUE;
3639 #if 1
3640 if(bCheckFwTxCnt)
3642 if(HalTxCheckStuck8190Pci(dev))
3644 RT_TRACE(COMP_RESET, "TxCheckStuck(): Fw indicates no Tx condition! \n");
3645 return RESET_TYPE_SILENT;
3648 #endif
3649 return RESET_TYPE_NORESET;
3653 static bool HalRxCheckStuck8190Pci(struct net_device *dev)
3655 struct r8192_priv *priv = ieee80211_priv(dev);
3656 u16 RegRxCounter = read_nic_word(dev, 0x130);
3657 bool bStuck = FALSE;
3658 static u8 rx_chk_cnt = 0;
3659 RT_TRACE(COMP_RESET,"%s(): RegRxCounter is %d,RxCounter is %d\n",__FUNCTION__,RegRxCounter,priv->RxCounter);
3660 // If rssi is small, we should check rx for long time because of bad rx.
3661 // or maybe it will continuous silent reset every 2 seconds.
3662 rx_chk_cnt++;
3663 if(priv->undecorated_smoothed_pwdb >= (RateAdaptiveTH_High+5))
3665 rx_chk_cnt = 0; //high rssi, check rx stuck right now.
3667 else if(priv->undecorated_smoothed_pwdb < (RateAdaptiveTH_High+5) &&
3668 ((priv->CurrentChannelBW!=HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb>=RateAdaptiveTH_Low_40M) ||
3669 (priv->CurrentChannelBW==HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb>=RateAdaptiveTH_Low_20M)) )
3672 if(rx_chk_cnt < 2)
3674 return bStuck;
3676 else
3678 rx_chk_cnt = 0;
3681 else if(((priv->CurrentChannelBW!=HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb<RateAdaptiveTH_Low_40M) ||
3682 (priv->CurrentChannelBW==HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb<RateAdaptiveTH_Low_20M)) &&
3683 priv->undecorated_smoothed_pwdb >= VeryLowRSSI)
3685 if(rx_chk_cnt < 4)
3687 //DbgPrint("RSSI < %d && RSSI >= %d, no check this time \n", RateAdaptiveTH_Low, VeryLowRSSI);
3688 return bStuck;
3690 else
3692 rx_chk_cnt = 0;
3693 //DbgPrint("RSSI < %d && RSSI >= %d, check this time \n", RateAdaptiveTH_Low, VeryLowRSSI);
3696 else
3698 if(rx_chk_cnt < 8)
3700 //DbgPrint("RSSI <= %d, no check this time \n", VeryLowRSSI);
3701 return bStuck;
3703 else
3705 rx_chk_cnt = 0;
3706 //DbgPrint("RSSI <= %d, check this time \n", VeryLowRSSI);
3709 if(priv->RxCounter==RegRxCounter)
3710 bStuck = TRUE;
3712 priv->RxCounter = RegRxCounter;
3714 return bStuck;
3717 static RESET_TYPE RxCheckStuck(struct net_device *dev)
3720 if(HalRxCheckStuck8190Pci(dev))
3722 RT_TRACE(COMP_RESET, "RxStuck Condition\n");
3723 return RESET_TYPE_SILENT;
3726 return RESET_TYPE_NORESET;
3729 static RESET_TYPE
3730 rtl819x_ifcheck_resetornot(struct net_device *dev)
3732 struct r8192_priv *priv = ieee80211_priv(dev);
3733 RESET_TYPE TxResetType = RESET_TYPE_NORESET;
3734 RESET_TYPE RxResetType = RESET_TYPE_NORESET;
3735 RT_RF_POWER_STATE rfState;
3737 rfState = priv->ieee80211->eRFPowerState;
3739 TxResetType = TxCheckStuck(dev);
3740 #if 1
3741 if( rfState != eRfOff &&
3742 /*ADAPTER_TEST_STATUS_FLAG(Adapter, ADAPTER_STATUS_FW_DOWNLOAD_FAILURE)) &&*/
3743 (priv->ieee80211->iw_mode != IW_MODE_ADHOC))
3745 // If driver is in the status of firmware download failure , driver skips RF initialization and RF is
3746 // in turned off state. Driver should check whether Rx stuck and do silent reset. And
3747 // if driver is in firmware download failure status, driver should initialize RF in the following
3748 // silent reset procedure Emily, 2008.01.21
3750 // Driver should not check RX stuck in IBSS mode because it is required to
3751 // set Check BSSID in order to send beacon, however, if check BSSID is
3752 // set, STA cannot hear any packet a all. Emily, 2008.04.12
3753 RxResetType = RxCheckStuck(dev);
3755 #endif
3757 RT_TRACE(COMP_RESET,"%s(): TxResetType is %d, RxResetType is %d\n",__FUNCTION__,TxResetType,RxResetType);
3758 if(TxResetType==RESET_TYPE_NORMAL || RxResetType==RESET_TYPE_NORMAL)
3759 return RESET_TYPE_NORMAL;
3760 else if(TxResetType==RESET_TYPE_SILENT || RxResetType==RESET_TYPE_SILENT)
3761 return RESET_TYPE_SILENT;
3762 else
3763 return RESET_TYPE_NORESET;
3768 static void CamRestoreAllEntry(struct net_device *dev)
3770 u8 EntryId = 0;
3771 struct r8192_priv *priv = ieee80211_priv(dev);
3772 const u8* MacAddr = priv->ieee80211->current_network.bssid;
3774 static const u8 CAM_CONST_ADDR[4][6] = {
3775 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
3776 {0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
3777 {0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
3778 {0x00, 0x00, 0x00, 0x00, 0x00, 0x03}};
3779 static const u8 CAM_CONST_BROAD[] =
3780 {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
3782 RT_TRACE(COMP_SEC, "CamRestoreAllEntry: \n");
3785 if ((priv->ieee80211->pairwise_key_type == KEY_TYPE_WEP40)||
3786 (priv->ieee80211->pairwise_key_type == KEY_TYPE_WEP104))
3789 for(EntryId=0; EntryId<4; EntryId++)
3792 MacAddr = CAM_CONST_ADDR[EntryId];
3793 setKey(dev,
3794 EntryId ,
3795 EntryId,
3796 priv->ieee80211->pairwise_key_type,
3797 MacAddr,
3799 NULL);
3804 else if(priv->ieee80211->pairwise_key_type == KEY_TYPE_TKIP)
3808 if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
3809 setKey(dev,
3812 priv->ieee80211->pairwise_key_type,
3813 (u8*)dev->dev_addr,
3815 NULL);
3816 else
3817 setKey(dev,
3820 priv->ieee80211->pairwise_key_type,
3821 MacAddr,
3823 NULL);
3826 else if(priv->ieee80211->pairwise_key_type == KEY_TYPE_CCMP)
3830 if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
3831 setKey(dev,
3834 priv->ieee80211->pairwise_key_type,
3835 (u8*)dev->dev_addr,
3837 NULL);
3838 else
3839 setKey(dev,
3842 priv->ieee80211->pairwise_key_type,
3843 MacAddr,
3845 NULL);
3851 if(priv->ieee80211->group_key_type == KEY_TYPE_TKIP)
3853 MacAddr = CAM_CONST_BROAD;
3854 for(EntryId=1 ; EntryId<4 ; EntryId++)
3857 setKey(dev,
3858 EntryId,
3859 EntryId,
3860 priv->ieee80211->group_key_type,
3861 MacAddr,
3863 NULL);
3866 if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
3867 setKey(dev,
3870 priv->ieee80211->group_key_type,
3871 CAM_CONST_ADDR[0],
3873 NULL);
3875 else if(priv->ieee80211->group_key_type == KEY_TYPE_CCMP)
3877 MacAddr = CAM_CONST_BROAD;
3878 for(EntryId=1; EntryId<4 ; EntryId++)
3881 setKey(dev,
3882 EntryId ,
3883 EntryId,
3884 priv->ieee80211->group_key_type,
3885 MacAddr,
3887 NULL);
3891 if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
3892 setKey(dev,
3895 priv->ieee80211->group_key_type,
3896 CAM_CONST_ADDR[0],
3898 NULL);
3903 * This function is used to fix Tx/Rx stop bug temporarily.
3904 * This function will do "system reset" to NIC when Tx or Rx is stuck.
3905 * The method checking Tx/Rx stuck of this function is supported by FW,
3906 * which reports Tx and Rx counter to register 0x128 and 0x130.
3908 static void rtl819x_ifsilentreset(struct net_device *dev)
3910 struct r8192_priv *priv = ieee80211_priv(dev);
3911 u8 reset_times = 0;
3912 int reset_status = 0;
3913 struct ieee80211_device *ieee = priv->ieee80211;
3916 return;
3918 // 2007.07.20. If we need to check CCK stop, please uncomment this line.
3919 //bStuck = Adapter->HalFunc.CheckHWStopHandler(Adapter);
3921 if(priv->ResetProgress==RESET_TYPE_NORESET)
3923 RESET_START:
3924 #ifdef ENABLE_LPS
3925 //LZM for PS-Poll AID issue. 090429
3926 if(priv->ieee80211->state == IEEE80211_LINKED)
3927 LeisurePSLeave(dev);
3928 #endif
3930 RT_TRACE(COMP_RESET,"=========>Reset progress!! \n");
3932 // Set the variable for reset.
3933 priv->ResetProgress = RESET_TYPE_SILENT;
3934 // rtl8192_close(dev);
3935 #if 1
3936 down(&priv->wx_sem);
3937 if(priv->up == 0)
3939 RT_TRACE(COMP_ERR,"%s():the driver is not up! return\n",__FUNCTION__);
3940 up(&priv->wx_sem);
3941 return ;
3943 priv->up = 0;
3944 RT_TRACE(COMP_RESET,"%s():======>start to down the driver\n",__FUNCTION__);
3945 if(!netif_queue_stopped(dev))
3946 netif_stop_queue(dev);
3948 dm_backup_dynamic_mechanism_state(dev);
3950 rtl8192_irq_disable(dev);
3951 rtl8192_cancel_deferred_work(priv);
3952 deinit_hal_dm(dev);
3953 del_timer_sync(&priv->watch_dog_timer);
3954 ieee->sync_scan_hurryup = 1;
3955 if(ieee->state == IEEE80211_LINKED)
3957 down(&ieee->wx_sem);
3958 printk("ieee->state is IEEE80211_LINKED\n");
3959 ieee80211_stop_send_beacons(priv->ieee80211);
3960 del_timer_sync(&ieee->associate_timer);
3961 cancel_delayed_work(&ieee->associate_retry_wq);
3962 ieee80211_stop_scan(ieee);
3963 up(&ieee->wx_sem);
3965 else{
3966 printk("ieee->state is NOT LINKED\n");
3967 ieee80211_softmac_stop_protocol(priv->ieee80211,true);
3969 rtl8192_halt_adapter(dev, true);
3970 up(&priv->wx_sem);
3971 RT_TRACE(COMP_RESET,"%s():<==========down process is finished\n",__FUNCTION__);
3972 RT_TRACE(COMP_RESET,"%s():===========>start to up the driver\n",__FUNCTION__);
3973 reset_status = _rtl8192_up(dev);
3975 RT_TRACE(COMP_RESET,"%s():<===========up process is finished\n",__FUNCTION__);
3976 if(reset_status == -1)
3978 if(reset_times < 3)
3980 reset_times++;
3981 goto RESET_START;
3983 else
3985 RT_TRACE(COMP_ERR," ERR!!! %s(): Reset Failed!!\n",__FUNCTION__);
3988 #endif
3989 ieee->is_silent_reset = 1;
3990 #if 1
3991 EnableHWSecurityConfig8192(dev);
3992 #if 1
3993 if(ieee->state == IEEE80211_LINKED && ieee->iw_mode == IW_MODE_INFRA)
3995 ieee->set_chan(ieee->dev, ieee->current_network.channel);
3997 #if 1
3998 queue_work(ieee->wq, &ieee->associate_complete_wq);
3999 #endif
4002 else if(ieee->state == IEEE80211_LINKED && ieee->iw_mode == IW_MODE_ADHOC)
4004 ieee->set_chan(ieee->dev, ieee->current_network.channel);
4005 ieee->link_change(ieee->dev);
4007 // notify_wx_assoc_event(ieee);
4009 ieee80211_start_send_beacons(ieee);
4011 if (ieee->data_hard_resume)
4012 ieee->data_hard_resume(ieee->dev);
4013 netif_carrier_on(ieee->dev);
4015 #endif
4017 CamRestoreAllEntry(dev);
4019 // Restore the previous setting for all dynamic mechanism
4020 dm_restore_dynamic_mechanism_state(dev);
4022 priv->ResetProgress = RESET_TYPE_NORESET;
4023 priv->reset_count++;
4025 priv->bForcedSilentReset =false;
4026 priv->bResetInProgress = false;
4028 // For test --> force write UFWP.
4029 write_nic_byte(dev, UFWP, 1);
4030 RT_TRACE(COMP_RESET, "Reset finished!! ====>[%d]\n", priv->reset_count);
4031 #endif
4035 #ifdef ENABLE_IPS
4036 void InactivePsWorkItemCallback(struct net_device *dev)
4038 struct r8192_priv *priv = ieee80211_priv(dev);
4039 PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->ieee80211->PowerSaveControl));
4041 RT_TRACE(COMP_POWER, "InactivePsWorkItemCallback() ---------> \n");
4043 // This flag "bSwRfProcessing", indicates the status of IPS procedure, should be set if the IPS workitem
4044 // is really scheduled.
4045 // The old code, sets this flag before scheduling the IPS workitem and however, at the same time the
4046 // previous IPS workitem did not end yet, fails to schedule the current workitem. Thus, bSwRfProcessing
4047 // blocks the IPS procedure of switching RF.
4048 // By Bruce, 2007-12-25.
4050 pPSC->bSwRfProcessing = TRUE;
4052 RT_TRACE(COMP_RF, "InactivePsWorkItemCallback(): Set RF to %s.\n",
4053 pPSC->eInactivePowerState == eRfOff?"OFF":"ON");
4056 MgntActSet_RF_State(dev, pPSC->eInactivePowerState, RF_CHANGE_BY_IPS);
4059 // To solve CAM values miss in RF OFF, rewrite CAM values after RF ON. By Bruce, 2007-09-20.
4061 pPSC->bSwRfProcessing = FALSE;
4062 RT_TRACE(COMP_POWER, "InactivePsWorkItemCallback() <--------- \n");
4065 #ifdef ENABLE_LPS
4066 /* Change current and default preamble mode. */
4067 bool MgntActSet_802_11_PowerSaveMode(struct net_device *dev, u8 rtPsMode)
4069 struct r8192_priv *priv = ieee80211_priv(dev);
4071 // Currently, we do not change power save mode on IBSS mode.
4072 if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
4074 return false;
4078 // <RJ_NOTE> If we make HW to fill up the PwrMgt bit for us,
4079 // some AP will not response to our mgnt frames with PwrMgt bit set,
4080 // e.g. cannot associate the AP.
4081 // So I commented out it. 2005.02.16, by rcnjko.
4083 // // Change device's power save mode.
4084 // Adapter->HalFunc.SetPSModeHandler( Adapter, rtPsMode );
4086 // Update power save mode configured.
4087 //RT_TRACE(COMP_LPS,"%s(): set ieee->ps = %x\n",__FUNCTION__,rtPsMode);
4088 if(!priv->ps_force) {
4089 priv->ieee80211->ps = rtPsMode;
4092 // Awake immediately
4093 if(priv->ieee80211->sta_sleep != 0 && rtPsMode == IEEE80211_PS_DISABLED)
4095 unsigned long flags;
4097 //PlatformSetTimer(Adapter, &(pMgntInfo->AwakeTimer), 0);
4098 // Notify the AP we awke.
4099 rtl8192_hw_wakeup(dev);
4100 priv->ieee80211->sta_sleep = 0;
4102 spin_lock_irqsave(&(priv->ieee80211->mgmt_tx_lock), flags);
4103 printk("LPS leave: notify AP we are awaked ++++++++++ SendNullFunctionData\n");
4104 ieee80211_sta_ps_send_null_frame(priv->ieee80211, 0);
4105 spin_unlock_irqrestore(&(priv->ieee80211->mgmt_tx_lock), flags);
4108 return true;
4111 /* Enter the leisure power save mode. */
4112 void LeisurePSEnter(struct net_device *dev)
4114 struct r8192_priv *priv = ieee80211_priv(dev);
4115 PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->ieee80211->PowerSaveControl));
4117 //RT_TRACE(COMP_PS, "LeisurePSEnter()...\n");
4118 //RT_TRACE(COMP_PS, "pPSC->bLeisurePs = %d, ieee->ps = %d,pPSC->LpsIdleCount is %d,RT_CHECK_FOR_HANG_PERIOD is %d\n",
4119 // pPSC->bLeisurePs, priv->ieee80211->ps,pPSC->LpsIdleCount,RT_CHECK_FOR_HANG_PERIOD);
4121 if(!((priv->ieee80211->iw_mode == IW_MODE_INFRA) &&
4122 (priv->ieee80211->state == IEEE80211_LINKED)) ||
4123 (priv->ieee80211->iw_mode == IW_MODE_ADHOC) ||
4124 (priv->ieee80211->iw_mode == IW_MODE_MASTER))
4125 return;
4127 if (pPSC->bLeisurePs)
4129 // Idle for a while if we connect to AP a while ago.
4130 if(pPSC->LpsIdleCount >= RT_CHECK_FOR_HANG_PERIOD) // 4 Sec
4133 if(priv->ieee80211->ps == IEEE80211_PS_DISABLED)
4136 //RT_TRACE(COMP_LPS, "LeisurePSEnter(): Enter 802.11 power save mode...\n");
4137 MgntActSet_802_11_PowerSaveMode(dev, IEEE80211_PS_MBCAST|IEEE80211_PS_UNICAST);
4141 else
4142 pPSC->LpsIdleCount++;
4147 /* Leave leisure power save mode. */
4148 void LeisurePSLeave(struct net_device *dev)
4150 struct r8192_priv *priv = ieee80211_priv(dev);
4151 PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->ieee80211->PowerSaveControl));
4153 if (pPSC->bLeisurePs)
4155 if(priv->ieee80211->ps != IEEE80211_PS_DISABLED)
4157 // move to lps_wakecomplete()
4158 //RT_TRACE(COMP_LPS, "LeisurePSLeave(): Busy Traffic , Leave 802.11 power save..\n");
4159 MgntActSet_802_11_PowerSaveMode(dev, IEEE80211_PS_DISABLED);
4164 #endif
4167 /* Enter the inactive power save mode. RF will be off */
4168 void
4169 IPSEnter(struct net_device *dev)
4171 struct r8192_priv *priv = ieee80211_priv(dev);
4172 PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->ieee80211->PowerSaveControl));
4173 RT_RF_POWER_STATE rtState;
4175 if (pPSC->bInactivePs)
4177 rtState = priv->ieee80211->eRFPowerState;
4179 // Added by Bruce, 2007-12-25.
4180 // Do not enter IPS in the following conditions:
4181 // (1) RF is already OFF or Sleep
4182 // (2) bSwRfProcessing (indicates the IPS is still under going)
4183 // (3) Connectted (only disconnected can trigger IPS)
4184 // (4) IBSS (send Beacon)
4185 // (5) AP mode (send Beacon)
4187 if (rtState == eRfOn && !pPSC->bSwRfProcessing
4188 && (priv->ieee80211->state != IEEE80211_LINKED) )
4190 RT_TRACE(COMP_RF,"IPSEnter(): Turn off RF.\n");
4191 //printk("IPSEnter(): Turn off RF.\n");
4192 pPSC->eInactivePowerState = eRfOff;
4193 // queue_work(priv->priv_wq,&(pPSC->InactivePsWorkItem));
4194 InactivePsWorkItemCallback(dev);
4200 // Description:
4201 // Leave the inactive power save mode, RF will be on.
4202 // 2007.08.17, by shien chang.
4204 void
4205 IPSLeave(struct net_device *dev)
4207 struct r8192_priv *priv = ieee80211_priv(dev);
4208 PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->ieee80211->PowerSaveControl));
4209 RT_RF_POWER_STATE rtState;
4211 if (pPSC->bInactivePs)
4213 rtState = priv->ieee80211->eRFPowerState;
4214 if (rtState != eRfOn && !pPSC->bSwRfProcessing && priv->ieee80211->RfOffReason <= RF_CHANGE_BY_IPS)
4216 RT_TRACE(COMP_POWER, "IPSLeave(): Turn on RF.\n");
4217 //printk("IPSLeave(): Turn on RF.\n");
4218 pPSC->eInactivePowerState = eRfOn;
4219 // queue_work(priv->priv_wq,&(pPSC->InactivePsWorkItem));
4220 InactivePsWorkItemCallback(dev);
4225 void IPSLeave_wq(void *data)
4227 struct ieee80211_device *ieee = container_of(data,struct ieee80211_device,ips_leave_wq);
4228 struct net_device *dev = ieee->dev;
4230 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
4231 down(&priv->ieee80211->ips_sem);
4232 IPSLeave(dev);
4233 up(&priv->ieee80211->ips_sem);
4236 void ieee80211_ips_leave_wq(struct net_device *dev)
4238 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
4239 RT_RF_POWER_STATE rtState;
4240 rtState = priv->ieee80211->eRFPowerState;
4242 if(priv->ieee80211->PowerSaveControl.bInactivePs){
4243 if(rtState == eRfOff){
4244 if(priv->ieee80211->RfOffReason > RF_CHANGE_BY_IPS)
4246 RT_TRACE(COMP_ERR, "%s(): RF is OFF.\n",__FUNCTION__);
4247 return;
4249 else{
4250 printk("=========>%s(): IPSLeave\n",__FUNCTION__);
4251 queue_work(priv->ieee80211->wq,&priv->ieee80211->ips_leave_wq);
4256 //added by amy 090331 end
4257 void ieee80211_ips_leave(struct net_device *dev)
4259 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
4260 down(&priv->ieee80211->ips_sem);
4261 IPSLeave(dev);
4262 up(&priv->ieee80211->ips_sem);
4264 #endif
4266 static void rtl819x_update_rxcounts(
4267 struct r8192_priv *priv,
4268 u32* TotalRxBcnNum,
4269 u32* TotalRxDataNum
4272 u16 SlotIndex;
4273 u8 i;
4275 *TotalRxBcnNum = 0;
4276 *TotalRxDataNum = 0;
4278 SlotIndex = (priv->ieee80211->LinkDetectInfo.SlotIndex++)%(priv->ieee80211->LinkDetectInfo.SlotNum);
4279 priv->ieee80211->LinkDetectInfo.RxBcnNum[SlotIndex] = priv->ieee80211->LinkDetectInfo.NumRecvBcnInPeriod;
4280 priv->ieee80211->LinkDetectInfo.RxDataNum[SlotIndex] = priv->ieee80211->LinkDetectInfo.NumRecvDataInPeriod;
4281 for( i=0; i<priv->ieee80211->LinkDetectInfo.SlotNum; i++ ){
4282 *TotalRxBcnNum += priv->ieee80211->LinkDetectInfo.RxBcnNum[i];
4283 *TotalRxDataNum += priv->ieee80211->LinkDetectInfo.RxDataNum[i];
4288 static void rtl819x_watchdog_wqcallback(struct work_struct *work)
4290 struct delayed_work *dwork = container_of(work,struct delayed_work,work);
4291 struct r8192_priv *priv = container_of(dwork,struct r8192_priv,watch_dog_wq);
4292 struct net_device *dev = priv->ieee80211->dev;
4293 struct ieee80211_device* ieee = priv->ieee80211;
4294 RESET_TYPE ResetType = RESET_TYPE_NORESET;
4295 static u8 check_reset_cnt=0;
4296 unsigned long flags;
4297 bool bBusyTraffic = false;
4298 static u8 last_time = 0;
4299 bool bEnterPS = false;
4301 if ((!priv->up) || priv->bHwRadioOff)
4302 return;
4304 if(!priv->up)
4305 return;
4306 hal_dm_watchdog(dev);
4307 #ifdef ENABLE_IPS
4308 // printk("watch_dog ENABLE_IPS\n");
4309 if(ieee->actscanning == false){
4310 //printk("%d,%d,%d,%d\n", ieee->eRFPowerState, ieee->is_set_key, ieee->proto_stoppping, ieee->wx_set_enc);
4311 if((ieee->iw_mode == IW_MODE_INFRA) && (ieee->state == IEEE80211_NOLINK) &&
4312 (ieee->eRFPowerState == eRfOn)&&!ieee->is_set_key &&
4313 (!ieee->proto_stoppping) && !ieee->wx_set_enc){
4314 if(ieee->PowerSaveControl.ReturnPoint == IPS_CALLBACK_NONE){
4315 //printk("====================>haha:IPSEnter()\n");
4316 IPSEnter(dev);
4317 //ieee80211_stop_scan(priv->ieee80211);
4321 #endif
4322 {//to get busy traffic condition
4323 if(ieee->state == IEEE80211_LINKED)
4325 if( ieee->LinkDetectInfo.NumRxOkInPeriod> 100 ||
4326 ieee->LinkDetectInfo.NumTxOkInPeriod> 100 ) {
4327 bBusyTraffic = true;
4330 #ifdef ENABLE_LPS
4331 //added by amy for Leisure PS
4332 if( ((ieee->LinkDetectInfo.NumRxUnicastOkInPeriod + ieee->LinkDetectInfo.NumTxOkInPeriod) > 8 ) ||
4333 (ieee->LinkDetectInfo.NumRxUnicastOkInPeriod > 2) )
4335 //printk("ieee->LinkDetectInfo.NumRxUnicastOkInPeriod is %d,ieee->LinkDetectInfo.NumTxOkInPeriod is %d\n",
4336 // ieee->LinkDetectInfo.NumRxUnicastOkInPeriod,ieee->LinkDetectInfo.NumTxOkInPeriod);
4337 bEnterPS= false;
4339 else
4341 bEnterPS= true;
4344 //printk("***bEnterPS = %d\n", bEnterPS);
4345 // LeisurePS only work in infra mode.
4346 if(bEnterPS)
4348 LeisurePSEnter(dev);
4350 else
4352 LeisurePSLeave(dev);
4354 #endif
4357 else
4359 #ifdef ENABLE_LPS
4360 //RT_TRACE(COMP_LPS,"====>no link LPS leave\n");
4361 LeisurePSLeave(dev);
4362 #endif
4365 ieee->LinkDetectInfo.NumRxOkInPeriod = 0;
4366 ieee->LinkDetectInfo.NumTxOkInPeriod = 0;
4367 ieee->LinkDetectInfo.NumRxUnicastOkInPeriod = 0;
4368 ieee->LinkDetectInfo.bBusyTraffic = bBusyTraffic;
4372 //added by amy for AP roaming
4373 if (1)
4375 if(ieee->state == IEEE80211_LINKED && ieee->iw_mode == IW_MODE_INFRA)
4377 u32 TotalRxBcnNum = 0;
4378 u32 TotalRxDataNum = 0;
4380 rtl819x_update_rxcounts(priv, &TotalRxBcnNum, &TotalRxDataNum);
4381 if((TotalRxBcnNum+TotalRxDataNum) == 0)
4383 if( ieee->eRFPowerState == eRfOff)
4384 RT_TRACE(COMP_ERR,"========>%s()\n",__FUNCTION__);
4385 printk("===>%s(): AP is power off,connect another one\n",__FUNCTION__);
4386 // Dot11d_Reset(dev);
4387 ieee->state = IEEE80211_ASSOCIATING;
4388 notify_wx_assoc_event(priv->ieee80211);
4389 RemovePeerTS(priv->ieee80211,priv->ieee80211->current_network.bssid);
4390 ieee->is_roaming = true;
4391 ieee->is_set_key = false;
4392 ieee->link_change(dev);
4393 queue_work(ieee->wq, &ieee->associate_procedure_wq);
4396 ieee->LinkDetectInfo.NumRecvBcnInPeriod=0;
4397 ieee->LinkDetectInfo.NumRecvDataInPeriod=0;
4400 //check if reset the driver
4401 spin_lock_irqsave(&priv->tx_lock,flags);
4402 if(check_reset_cnt++ >= 3 && !ieee->is_roaming && (last_time != 1))
4404 ResetType = rtl819x_ifcheck_resetornot(dev);
4405 check_reset_cnt = 3;
4406 //DbgPrint("Start to check silent reset\n");
4408 spin_unlock_irqrestore(&priv->tx_lock,flags);
4409 if(!priv->bDisableNormalResetCheck && ResetType == RESET_TYPE_NORMAL)
4411 priv->ResetProgress = RESET_TYPE_NORMAL;
4412 RT_TRACE(COMP_RESET,"%s(): NOMAL RESET\n",__FUNCTION__);
4413 return;
4415 /* disable silent reset temply 2008.9.11*/
4416 #if 1
4417 if( ((priv->force_reset) || (!priv->bDisableNormalResetCheck && ResetType==RESET_TYPE_SILENT))) // This is control by OID set in Pomelo
4419 last_time = 1;
4420 rtl819x_ifsilentreset(dev);
4422 else
4423 last_time = 0;
4424 #endif
4425 priv->force_reset = false;
4426 priv->bForcedSilentReset = false;
4427 priv->bResetInProgress = false;
4428 RT_TRACE(COMP_TRACE, " <==RtUsbCheckForHangWorkItemCallback()\n");
4432 void watch_dog_timer_callback(unsigned long data)
4434 struct r8192_priv *priv = ieee80211_priv((struct net_device *) data);
4435 queue_delayed_work(priv->priv_wq,&priv->watch_dog_wq,0);
4436 mod_timer(&priv->watch_dog_timer, jiffies + MSECS(IEEE80211_WATCH_DOG_TIME));
4440 static int _rtl8192_up(struct net_device *dev)
4442 struct r8192_priv *priv = ieee80211_priv(dev);
4443 //int i;
4444 RT_STATUS init_status = RT_STATUS_SUCCESS;
4445 priv->up=1;
4446 priv->ieee80211->ieee_up=1;
4447 priv->bdisable_nic = false; //YJ,add,091111
4448 RT_TRACE(COMP_INIT, "Bringing up iface");
4450 init_status = rtl8192_adapter_start(dev);
4451 if(init_status != RT_STATUS_SUCCESS)
4453 RT_TRACE(COMP_ERR,"ERR!!! %s(): initialization is failed!\n",__FUNCTION__);
4454 return -1;
4456 RT_TRACE(COMP_INIT, "start adapter finished\n");
4457 #ifdef RTL8192E
4458 if(priv->ieee80211->eRFPowerState!=eRfOn)
4459 MgntActSet_RF_State(dev, eRfOn, priv->ieee80211->RfOffReason);
4460 #endif
4461 if(priv->ieee80211->state != IEEE80211_LINKED)
4462 ieee80211_softmac_start_protocol(priv->ieee80211);
4463 ieee80211_reset_queue(priv->ieee80211);
4464 watch_dog_timer_callback((unsigned long) dev);
4465 if(!netif_queue_stopped(dev))
4466 netif_start_queue(dev);
4467 else
4468 netif_wake_queue(dev);
4470 return 0;
4474 static int rtl8192_open(struct net_device *dev)
4476 struct r8192_priv *priv = ieee80211_priv(dev);
4477 int ret;
4479 down(&priv->wx_sem);
4480 ret = rtl8192_up(dev);
4481 up(&priv->wx_sem);
4482 return ret;
4487 int rtl8192_up(struct net_device *dev)
4489 struct r8192_priv *priv = ieee80211_priv(dev);
4491 if (priv->up == 1) return -1;
4493 return _rtl8192_up(dev);
4497 static int rtl8192_close(struct net_device *dev)
4499 struct r8192_priv *priv = ieee80211_priv(dev);
4500 int ret;
4502 down(&priv->wx_sem);
4504 ret = rtl8192_down(dev);
4506 up(&priv->wx_sem);
4508 return ret;
4512 int rtl8192_down(struct net_device *dev)
4514 struct r8192_priv *priv = ieee80211_priv(dev);
4516 if (priv->up == 0) return -1;
4518 #ifdef ENABLE_LPS
4519 //LZM for PS-Poll AID issue. 090429
4520 if(priv->ieee80211->state == IEEE80211_LINKED)
4521 LeisurePSLeave(dev);
4522 #endif
4524 priv->up=0;
4525 priv->ieee80211->ieee_up = 0;
4526 RT_TRACE(COMP_DOWN, "==========>%s()\n", __FUNCTION__);
4527 /* FIXME */
4528 if (!netif_queue_stopped(dev))
4529 netif_stop_queue(dev);
4531 rtl8192_irq_disable(dev);
4532 rtl8192_cancel_deferred_work(priv);
4533 deinit_hal_dm(dev);
4534 del_timer_sync(&priv->watch_dog_timer);
4536 ieee80211_softmac_stop_protocol(priv->ieee80211,true);
4538 rtl8192_halt_adapter(dev,false);
4539 memset(&priv->ieee80211->current_network, 0 , offsetof(struct ieee80211_network, list));
4541 RT_TRACE(COMP_DOWN, "<==========%s()\n", __FUNCTION__);
4543 return 0;
4547 void rtl8192_commit(struct net_device *dev)
4549 struct r8192_priv *priv = ieee80211_priv(dev);
4551 if (priv->up == 0) return ;
4554 ieee80211_softmac_stop_protocol(priv->ieee80211,true);
4556 rtl8192_irq_disable(dev);
4557 rtl8192_halt_adapter(dev,true);
4558 _rtl8192_up(dev);
4561 static void rtl8192_restart(struct work_struct *work)
4563 struct r8192_priv *priv = container_of(work, struct r8192_priv, reset_wq);
4564 struct net_device *dev = priv->ieee80211->dev;
4566 down(&priv->wx_sem);
4568 rtl8192_commit(dev);
4570 up(&priv->wx_sem);
4573 static void r8192_set_multicast(struct net_device *dev)
4575 struct r8192_priv *priv = ieee80211_priv(dev);
4576 short promisc;
4578 //down(&priv->wx_sem);
4580 /* FIXME FIXME */
4582 promisc = (dev->flags & IFF_PROMISC) ? 1:0;
4584 if (promisc != priv->promisc) {
4586 // rtl8192_commit(dev);
4589 priv->promisc = promisc;
4591 //schedule_work(&priv->reset_wq);
4592 //up(&priv->wx_sem);
4596 static int r8192_set_mac_adr(struct net_device *dev, void *mac)
4598 struct r8192_priv *priv = ieee80211_priv(dev);
4599 struct sockaddr *addr = mac;
4601 down(&priv->wx_sem);
4603 memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
4605 schedule_work(&priv->reset_wq);
4606 up(&priv->wx_sem);
4608 return 0;
4611 /* based on ipw2200 driver */
4612 static int rtl8192_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
4614 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
4615 struct iwreq *wrq = (struct iwreq *)rq;
4616 int ret=-1;
4617 struct ieee80211_device *ieee = priv->ieee80211;
4618 u32 key[4];
4619 u8 broadcast_addr[6] = {0xff,0xff,0xff,0xff,0xff,0xff};
4620 struct iw_point *p = &wrq->u.data;
4621 struct ieee_param *ipw = NULL;//(struct ieee_param *)wrq->u.data.pointer;
4623 down(&priv->wx_sem);
4626 if (p->length < sizeof(struct ieee_param) || !p->pointer){
4627 ret = -EINVAL;
4628 goto out;
4631 ipw = kmalloc(p->length, GFP_KERNEL);
4632 if (ipw == NULL){
4633 ret = -ENOMEM;
4634 goto out;
4636 if (copy_from_user(ipw, p->pointer, p->length)) {
4637 kfree(ipw);
4638 ret = -EFAULT;
4639 goto out;
4642 switch (cmd) {
4643 case RTL_IOCTL_WPA_SUPPLICANT:
4644 //parse here for HW security
4645 if (ipw->cmd == IEEE_CMD_SET_ENCRYPTION)
4647 if (ipw->u.crypt.set_tx)
4649 if (strcmp(ipw->u.crypt.alg, "CCMP") == 0)
4650 ieee->pairwise_key_type = KEY_TYPE_CCMP;
4651 else if (strcmp(ipw->u.crypt.alg, "TKIP") == 0)
4652 ieee->pairwise_key_type = KEY_TYPE_TKIP;
4653 else if (strcmp(ipw->u.crypt.alg, "WEP") == 0)
4655 if (ipw->u.crypt.key_len == 13)
4656 ieee->pairwise_key_type = KEY_TYPE_WEP104;
4657 else if (ipw->u.crypt.key_len == 5)
4658 ieee->pairwise_key_type = KEY_TYPE_WEP40;
4660 else
4661 ieee->pairwise_key_type = KEY_TYPE_NA;
4663 if (ieee->pairwise_key_type)
4665 memcpy((u8*)key, ipw->u.crypt.key, 16);
4666 EnableHWSecurityConfig8192(dev);
4667 //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!
4668 //added by WB.
4669 setKey(dev, 4, ipw->u.crypt.idx, ieee->pairwise_key_type, (u8*)ieee->ap_mac_addr, 0, key);
4670 if (ieee->auth_mode != 2) //LEAP WEP will never set this.
4671 setKey(dev, ipw->u.crypt.idx, ipw->u.crypt.idx, ieee->pairwise_key_type, (u8*)ieee->ap_mac_addr, 0, key);
4673 if ((ieee->pairwise_key_type == KEY_TYPE_CCMP) && ieee->pHTInfo->bCurrentHTSupport){
4674 write_nic_byte(dev, 0x173, 1); //fix aes bug
4678 else //if (ipw->u.crypt.idx) //group key use idx > 0
4680 memcpy((u8*)key, ipw->u.crypt.key, 16);
4681 if (strcmp(ipw->u.crypt.alg, "CCMP") == 0)
4682 ieee->group_key_type= KEY_TYPE_CCMP;
4683 else if (strcmp(ipw->u.crypt.alg, "TKIP") == 0)
4684 ieee->group_key_type = KEY_TYPE_TKIP;
4685 else if (strcmp(ipw->u.crypt.alg, "WEP") == 0)
4687 if (ipw->u.crypt.key_len == 13)
4688 ieee->group_key_type = KEY_TYPE_WEP104;
4689 else if (ipw->u.crypt.key_len == 5)
4690 ieee->group_key_type = KEY_TYPE_WEP40;
4692 else
4693 ieee->group_key_type = KEY_TYPE_NA;
4695 if (ieee->group_key_type)
4697 setKey( dev,
4698 ipw->u.crypt.idx,
4699 ipw->u.crypt.idx, //KeyIndex
4700 ieee->group_key_type, //KeyType
4701 broadcast_addr, //MacAddr
4702 0, //DefaultKey
4703 key); //KeyContent
4707 ret = ieee80211_wpa_supplicant_ioctl(priv->ieee80211, &wrq->u.data);
4708 break;
4710 default:
4711 ret = -EOPNOTSUPP;
4712 break;
4715 kfree(ipw);
4716 out:
4717 up(&priv->wx_sem);
4719 return ret;
4722 static u8 HwRateToMRate90(bool bIsHT, u8 rate)
4724 u8 ret_rate = 0x02;
4726 if(!bIsHT) {
4727 switch(rate) {
4728 case DESC90_RATE1M: ret_rate = MGN_1M; break;
4729 case DESC90_RATE2M: ret_rate = MGN_2M; break;
4730 case DESC90_RATE5_5M: ret_rate = MGN_5_5M; break;
4731 case DESC90_RATE11M: ret_rate = MGN_11M; break;
4732 case DESC90_RATE6M: ret_rate = MGN_6M; break;
4733 case DESC90_RATE9M: ret_rate = MGN_9M; break;
4734 case DESC90_RATE12M: ret_rate = MGN_12M; break;
4735 case DESC90_RATE18M: ret_rate = MGN_18M; break;
4736 case DESC90_RATE24M: ret_rate = MGN_24M; break;
4737 case DESC90_RATE36M: ret_rate = MGN_36M; break;
4738 case DESC90_RATE48M: ret_rate = MGN_48M; break;
4739 case DESC90_RATE54M: ret_rate = MGN_54M; break;
4741 default:
4742 RT_TRACE(COMP_RECV, "HwRateToMRate90(): Non supported Rate [%x], bIsHT = %d!!!\n", rate, bIsHT);
4743 break;
4746 } else {
4747 switch(rate) {
4748 case DESC90_RATEMCS0: ret_rate = MGN_MCS0; break;
4749 case DESC90_RATEMCS1: ret_rate = MGN_MCS1; break;
4750 case DESC90_RATEMCS2: ret_rate = MGN_MCS2; break;
4751 case DESC90_RATEMCS3: ret_rate = MGN_MCS3; break;
4752 case DESC90_RATEMCS4: ret_rate = MGN_MCS4; break;
4753 case DESC90_RATEMCS5: ret_rate = MGN_MCS5; break;
4754 case DESC90_RATEMCS6: ret_rate = MGN_MCS6; break;
4755 case DESC90_RATEMCS7: ret_rate = MGN_MCS7; break;
4756 case DESC90_RATEMCS8: ret_rate = MGN_MCS8; break;
4757 case DESC90_RATEMCS9: ret_rate = MGN_MCS9; break;
4758 case DESC90_RATEMCS10: ret_rate = MGN_MCS10; break;
4759 case DESC90_RATEMCS11: ret_rate = MGN_MCS11; break;
4760 case DESC90_RATEMCS12: ret_rate = MGN_MCS12; break;
4761 case DESC90_RATEMCS13: ret_rate = MGN_MCS13; break;
4762 case DESC90_RATEMCS14: ret_rate = MGN_MCS14; break;
4763 case DESC90_RATEMCS15: ret_rate = MGN_MCS15; break;
4764 case DESC90_RATEMCS32: ret_rate = (0x80|0x20); break;
4766 default:
4767 RT_TRACE(COMP_RECV, "HwRateToMRate90(): Non supported Rate [%x], bIsHT = %d!!!\n",rate, bIsHT);
4768 break;
4772 return ret_rate;
4775 /* Record the TSF time stamp when receiving a packet */
4776 static void UpdateRxPktTimeStamp8190 (struct net_device *dev, struct ieee80211_rx_stats *stats)
4778 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
4780 if(stats->bIsAMPDU && !stats->bFirstMPDU) {
4781 stats->mac_time[0] = priv->LastRxDescTSFLow;
4782 stats->mac_time[1] = priv->LastRxDescTSFHigh;
4783 } else {
4784 priv->LastRxDescTSFLow = stats->mac_time[0];
4785 priv->LastRxDescTSFHigh = stats->mac_time[1];
4789 static long rtl819x_translate_todbm(u8 signal_strength_index)// 0-100 index.
4791 long signal_power; // in dBm.
4793 // Translate to dBm (x=0.5y-95).
4794 signal_power = (long)((signal_strength_index + 1) >> 1);
4795 signal_power -= 95;
4797 return signal_power;
4801 * Update Rx signal related information in the packet reeived
4802 * to RxStats. User application can query RxStats to realize
4803 * current Rx signal status.
4805 * In normal operation, user only care about the information of the BSS
4806 * and we shall invoke this function if the packet received is from the BSS.
4808 static void
4809 rtl819x_update_rxsignalstatistics8190pci(
4810 struct r8192_priv * priv,
4811 struct ieee80211_rx_stats * pprevious_stats
4814 int weighting = 0;
4816 //2 <ToDo> Update Rx Statistics (such as signal strength and signal quality).
4818 // Initila state
4819 if(priv->stats.recv_signal_power == 0)
4820 priv->stats.recv_signal_power = pprevious_stats->RecvSignalPower;
4822 // To avoid the past result restricting the statistics sensitivity, weight the current power (5/6) to speed up the
4823 // reaction of smoothed Signal Power.
4824 if(pprevious_stats->RecvSignalPower > priv->stats.recv_signal_power)
4825 weighting = 5;
4826 else if(pprevious_stats->RecvSignalPower < priv->stats.recv_signal_power)
4827 weighting = (-5);
4829 // We need more correct power of received packets and the "SignalStrength" of RxStats have been beautified or translated,
4830 // so we record the correct power in Dbm here. By Bruce, 2008-03-07.
4832 priv->stats.recv_signal_power = (priv->stats.recv_signal_power * 5 + pprevious_stats->RecvSignalPower + weighting) / 6;
4835 static void
4836 rtl8190_process_cck_rxpathsel(
4837 struct r8192_priv * priv,
4838 struct ieee80211_rx_stats * pprevious_stats
4841 #ifdef RTL8190P //Only 90P 2T4R need to check
4842 char last_cck_adc_pwdb[4]={0,0,0,0};
4843 u8 i;
4844 //cosa add for Rx path selection
4845 if(priv->rf_type == RF_2T4R && DM_RxPathSelTable.Enable)
4847 if(pprevious_stats->bIsCCK &&
4848 (pprevious_stats->bPacketToSelf ||pprevious_stats->bPacketBeacon))
4850 /* record the cck adc_pwdb to the sliding window. */
4851 if(priv->stats.cck_adc_pwdb.TotalNum++ >= PHY_RSSI_SLID_WIN_MAX)
4853 priv->stats.cck_adc_pwdb.TotalNum = PHY_RSSI_SLID_WIN_MAX;
4854 for(i=RF90_PATH_A; i<RF90_PATH_MAX; i++)
4856 last_cck_adc_pwdb[i] = priv->stats.cck_adc_pwdb.elements[i][priv->stats.cck_adc_pwdb.index];
4857 priv->stats.cck_adc_pwdb.TotalVal[i] -= last_cck_adc_pwdb[i];
4860 for(i=RF90_PATH_A; i<RF90_PATH_MAX; i++)
4862 priv->stats.cck_adc_pwdb.TotalVal[i] += pprevious_stats->cck_adc_pwdb[i];
4863 priv->stats.cck_adc_pwdb.elements[i][priv->stats.cck_adc_pwdb.index] = pprevious_stats->cck_adc_pwdb[i];
4865 priv->stats.cck_adc_pwdb.index++;
4866 if(priv->stats.cck_adc_pwdb.index >= PHY_RSSI_SLID_WIN_MAX)
4867 priv->stats.cck_adc_pwdb.index = 0;
4869 for(i=RF90_PATH_A; i<RF90_PATH_MAX; i++)
4871 DM_RxPathSelTable.cck_pwdb_sta[i] = priv->stats.cck_adc_pwdb.TotalVal[i]/priv->stats.cck_adc_pwdb.TotalNum;
4874 for(i=RF90_PATH_A; i<RF90_PATH_MAX; i++)
4876 if(pprevious_stats->cck_adc_pwdb[i] > (char)priv->undecorated_smoothed_cck_adc_pwdb[i])
4878 priv->undecorated_smoothed_cck_adc_pwdb[i] =
4879 ( (priv->undecorated_smoothed_cck_adc_pwdb[i]*(Rx_Smooth_Factor-1)) +
4880 (pprevious_stats->cck_adc_pwdb[i])) /(Rx_Smooth_Factor);
4881 priv->undecorated_smoothed_cck_adc_pwdb[i] = priv->undecorated_smoothed_cck_adc_pwdb[i] + 1;
4883 else
4885 priv->undecorated_smoothed_cck_adc_pwdb[i] =
4886 ( (priv->undecorated_smoothed_cck_adc_pwdb[i]*(Rx_Smooth_Factor-1)) +
4887 (pprevious_stats->cck_adc_pwdb[i])) /(Rx_Smooth_Factor);
4892 #endif
4896 /* 2008/01/22 MH We can not delcare RSSI/EVM total value of sliding window to
4897 be a local static. Otherwise, it may increase when we return from S3/S4. The
4898 value will be kept in memory or disk. We must delcare the value in adapter
4899 and it will be reinitialized when return from S3/S4. */
4900 static void rtl8192_process_phyinfo(struct r8192_priv * priv, u8* buffer,struct ieee80211_rx_stats * pprevious_stats, struct ieee80211_rx_stats * pcurrent_stats)
4902 bool bcheck = false;
4903 u8 rfpath;
4904 u32 nspatial_stream, tmp_val;
4905 //u8 i;
4906 static u32 slide_rssi_index=0, slide_rssi_statistics=0;
4907 static u32 slide_evm_index=0, slide_evm_statistics=0;
4908 static u32 last_rssi=0, last_evm=0;
4909 //cosa add for rx path selection
4910 // static long slide_cck_adc_pwdb_index=0, slide_cck_adc_pwdb_statistics=0;
4911 // static char last_cck_adc_pwdb[4]={0,0,0,0};
4912 //cosa add for beacon rssi smoothing
4913 static u32 slide_beacon_adc_pwdb_index=0, slide_beacon_adc_pwdb_statistics=0;
4914 static u32 last_beacon_adc_pwdb=0;
4916 struct ieee80211_hdr_3addr *hdr;
4917 u16 sc ;
4918 unsigned int frag,seq;
4919 hdr = (struct ieee80211_hdr_3addr *)buffer;
4920 sc = le16_to_cpu(hdr->seq_ctl);
4921 frag = WLAN_GET_SEQ_FRAG(sc);
4922 seq = WLAN_GET_SEQ_SEQ(sc);
4923 //cosa add 04292008 to record the sequence number
4924 pcurrent_stats->Seq_Num = seq;
4926 // Check whether we should take the previous packet into accounting
4928 if(!pprevious_stats->bIsAMPDU)
4930 // if previous packet is not aggregated packet
4931 bcheck = true;
4932 }else
4934 //remve for that we don't use AMPDU to calculate PWDB,because the reported PWDB of some AP is fault.
4935 #if 0
4936 // if previous packet is aggregated packet, and current packet
4937 // (1) is not AMPDU
4938 // (2) is the first packet of one AMPDU
4939 // that means the previous packet is the last one aggregated packet
4940 if( !pcurrent_stats->bIsAMPDU || pcurrent_stats->bFirstMPDU)
4941 bcheck = true;
4942 #endif
4945 if(slide_rssi_statistics++ >= PHY_RSSI_SLID_WIN_MAX)
4947 slide_rssi_statistics = PHY_RSSI_SLID_WIN_MAX;
4948 last_rssi = priv->stats.slide_signal_strength[slide_rssi_index];
4949 priv->stats.slide_rssi_total -= last_rssi;
4951 priv->stats.slide_rssi_total += pprevious_stats->SignalStrength;
4953 priv->stats.slide_signal_strength[slide_rssi_index++] = pprevious_stats->SignalStrength;
4954 if(slide_rssi_index >= PHY_RSSI_SLID_WIN_MAX)
4955 slide_rssi_index = 0;
4957 // <1> Showed on UI for user, in dbm
4958 tmp_val = priv->stats.slide_rssi_total/slide_rssi_statistics;
4959 priv->stats.signal_strength = rtl819x_translate_todbm((u8)tmp_val);
4960 pcurrent_stats->rssi = priv->stats.signal_strength;
4962 // If the previous packet does not match the criteria, neglect it
4964 if(!pprevious_stats->bPacketMatchBSSID)
4966 if(!pprevious_stats->bToSelfBA)
4967 return;
4970 if(!bcheck)
4971 return;
4973 rtl8190_process_cck_rxpathsel(priv,pprevious_stats);
4976 // Check RSSI
4978 priv->stats.num_process_phyinfo++;
4979 #if 0
4980 /* record the general signal strength to the sliding window. */
4981 if(slide_rssi_statistics++ >= PHY_RSSI_SLID_WIN_MAX)
4983 slide_rssi_statistics = PHY_RSSI_SLID_WIN_MAX;
4984 last_rssi = priv->stats.slide_signal_strength[slide_rssi_index];
4985 priv->stats.slide_rssi_total -= last_rssi;
4987 priv->stats.slide_rssi_total += pprevious_stats->SignalStrength;
4989 priv->stats.slide_signal_strength[slide_rssi_index++] = pprevious_stats->SignalStrength;
4990 if(slide_rssi_index >= PHY_RSSI_SLID_WIN_MAX)
4991 slide_rssi_index = 0;
4993 // <1> Showed on UI for user, in dbm
4994 tmp_val = priv->stats.slide_rssi_total/slide_rssi_statistics;
4995 priv->stats.signal_strength = rtl819x_translate_todbm((u8)tmp_val);
4997 #endif
4998 // <2> Showed on UI for engineering
4999 // hardware does not provide rssi information for each rf path in CCK
5000 if(!pprevious_stats->bIsCCK && pprevious_stats->bPacketToSelf)
5002 for (rfpath = RF90_PATH_A; rfpath < RF90_PATH_C; rfpath++)
5004 if (!rtl8192_phy_CheckIsLegalRFPath(priv->ieee80211->dev, rfpath))
5005 continue;
5006 RT_TRACE(COMP_DBG,"Jacken -> pPreviousstats->RxMIMOSignalStrength[rfpath] = %d \n" ,pprevious_stats->RxMIMOSignalStrength[rfpath] );
5007 //Fixed by Jacken 2008-03-20
5008 if(priv->stats.rx_rssi_percentage[rfpath] == 0)
5010 priv->stats.rx_rssi_percentage[rfpath] = pprevious_stats->RxMIMOSignalStrength[rfpath];
5011 //DbgPrint("MIMO RSSI initialize \n");
5013 if(pprevious_stats->RxMIMOSignalStrength[rfpath] > priv->stats.rx_rssi_percentage[rfpath])
5015 priv->stats.rx_rssi_percentage[rfpath] =
5016 ( (priv->stats.rx_rssi_percentage[rfpath]*(Rx_Smooth_Factor-1)) +
5017 (pprevious_stats->RxMIMOSignalStrength[rfpath])) /(Rx_Smooth_Factor);
5018 priv->stats.rx_rssi_percentage[rfpath] = priv->stats.rx_rssi_percentage[rfpath] + 1;
5020 else
5022 priv->stats.rx_rssi_percentage[rfpath] =
5023 ( (priv->stats.rx_rssi_percentage[rfpath]*(Rx_Smooth_Factor-1)) +
5024 (pprevious_stats->RxMIMOSignalStrength[rfpath])) /(Rx_Smooth_Factor);
5026 RT_TRACE(COMP_DBG,"Jacken -> priv->RxStats.RxRSSIPercentage[rfPath] = %d \n" ,priv->stats.rx_rssi_percentage[rfpath] );
5032 // Check PWDB.
5034 //cosa add for beacon rssi smoothing by average.
5035 if(pprevious_stats->bPacketBeacon)
5037 /* record the beacon pwdb to the sliding window. */
5038 if(slide_beacon_adc_pwdb_statistics++ >= PHY_Beacon_RSSI_SLID_WIN_MAX)
5040 slide_beacon_adc_pwdb_statistics = PHY_Beacon_RSSI_SLID_WIN_MAX;
5041 last_beacon_adc_pwdb = priv->stats.Slide_Beacon_pwdb[slide_beacon_adc_pwdb_index];
5042 priv->stats.Slide_Beacon_Total -= last_beacon_adc_pwdb;
5043 //DbgPrint("slide_beacon_adc_pwdb_index = %d, last_beacon_adc_pwdb = %d, Adapter->RxStats.Slide_Beacon_Total = %d\n",
5044 // slide_beacon_adc_pwdb_index, last_beacon_adc_pwdb, Adapter->RxStats.Slide_Beacon_Total);
5046 priv->stats.Slide_Beacon_Total += pprevious_stats->RxPWDBAll;
5047 priv->stats.Slide_Beacon_pwdb[slide_beacon_adc_pwdb_index] = pprevious_stats->RxPWDBAll;
5048 //DbgPrint("slide_beacon_adc_pwdb_index = %d, pPreviousRfd->Status.RxPWDBAll = %d\n", slide_beacon_adc_pwdb_index, pPreviousRfd->Status.RxPWDBAll);
5049 slide_beacon_adc_pwdb_index++;
5050 if(slide_beacon_adc_pwdb_index >= PHY_Beacon_RSSI_SLID_WIN_MAX)
5051 slide_beacon_adc_pwdb_index = 0;
5052 pprevious_stats->RxPWDBAll = priv->stats.Slide_Beacon_Total/slide_beacon_adc_pwdb_statistics;
5053 if(pprevious_stats->RxPWDBAll >= 3)
5054 pprevious_stats->RxPWDBAll -= 3;
5057 RT_TRACE(COMP_RXDESC, "Smooth %s PWDB = %d\n",
5058 pprevious_stats->bIsCCK? "CCK": "OFDM",
5059 pprevious_stats->RxPWDBAll);
5061 if(pprevious_stats->bPacketToSelf || pprevious_stats->bPacketBeacon || pprevious_stats->bToSelfBA)
5063 if(priv->undecorated_smoothed_pwdb < 0) // initialize
5065 priv->undecorated_smoothed_pwdb = pprevious_stats->RxPWDBAll;
5066 //DbgPrint("First pwdb initialize \n");
5068 #if 1
5069 if(pprevious_stats->RxPWDBAll > (u32)priv->undecorated_smoothed_pwdb)
5071 priv->undecorated_smoothed_pwdb =
5072 ( ((priv->undecorated_smoothed_pwdb)*(Rx_Smooth_Factor-1)) +
5073 (pprevious_stats->RxPWDBAll)) /(Rx_Smooth_Factor);
5074 priv->undecorated_smoothed_pwdb = priv->undecorated_smoothed_pwdb + 1;
5076 else
5078 priv->undecorated_smoothed_pwdb =
5079 ( ((priv->undecorated_smoothed_pwdb)*(Rx_Smooth_Factor-1)) +
5080 (pprevious_stats->RxPWDBAll)) /(Rx_Smooth_Factor);
5082 #else
5083 //Fixed by Jacken 2008-03-20
5084 if(pPreviousRfd->Status.RxPWDBAll > (u32)pHalData->UndecoratedSmoothedPWDB)
5086 pHalData->UndecoratedSmoothedPWDB =
5087 ( ((pHalData->UndecoratedSmoothedPWDB)* 5) + (pPreviousRfd->Status.RxPWDBAll)) / 6;
5088 pHalData->UndecoratedSmoothedPWDB = pHalData->UndecoratedSmoothedPWDB + 1;
5090 else
5092 pHalData->UndecoratedSmoothedPWDB =
5093 ( ((pHalData->UndecoratedSmoothedPWDB)* 5) + (pPreviousRfd->Status.RxPWDBAll)) / 6;
5095 #endif
5096 rtl819x_update_rxsignalstatistics8190pci(priv,pprevious_stats);
5100 // Check EVM
5102 /* record the general EVM to the sliding window. */
5103 if(pprevious_stats->SignalQuality == 0)
5106 else
5108 if(pprevious_stats->bPacketToSelf || pprevious_stats->bPacketBeacon || pprevious_stats->bToSelfBA){
5109 if(slide_evm_statistics++ >= PHY_RSSI_SLID_WIN_MAX){
5110 slide_evm_statistics = PHY_RSSI_SLID_WIN_MAX;
5111 last_evm = priv->stats.slide_evm[slide_evm_index];
5112 priv->stats.slide_evm_total -= last_evm;
5115 priv->stats.slide_evm_total += pprevious_stats->SignalQuality;
5117 priv->stats.slide_evm[slide_evm_index++] = pprevious_stats->SignalQuality;
5118 if(slide_evm_index >= PHY_RSSI_SLID_WIN_MAX)
5119 slide_evm_index = 0;
5121 // <1> Showed on UI for user, in percentage.
5122 tmp_val = priv->stats.slide_evm_total/slide_evm_statistics;
5123 priv->stats.signal_quality = tmp_val;
5124 //cosa add 10/11/2007, Showed on UI for user in Windows Vista, for Link quality.
5125 priv->stats.last_signal_strength_inpercent = tmp_val;
5128 // <2> Showed on UI for engineering
5129 if(pprevious_stats->bPacketToSelf || pprevious_stats->bPacketBeacon || pprevious_stats->bToSelfBA)
5131 for(nspatial_stream = 0; nspatial_stream<2 ; nspatial_stream++) // 2 spatial stream
5133 if(pprevious_stats->RxMIMOSignalQuality[nspatial_stream] != -1)
5135 if(priv->stats.rx_evm_percentage[nspatial_stream] == 0) // initialize
5137 priv->stats.rx_evm_percentage[nspatial_stream] = pprevious_stats->RxMIMOSignalQuality[nspatial_stream];
5139 priv->stats.rx_evm_percentage[nspatial_stream] =
5140 ( (priv->stats.rx_evm_percentage[nspatial_stream]* (Rx_Smooth_Factor-1)) +
5141 (pprevious_stats->RxMIMOSignalQuality[nspatial_stream]* 1)) / (Rx_Smooth_Factor);
5149 static u8 rtl819x_query_rxpwrpercentage(
5150 char antpower
5153 if ((antpower <= -100) || (antpower >= 20))
5155 return 0;
5157 else if (antpower >= 0)
5159 return 100;
5161 else
5163 return (100+antpower);
5168 static u8
5169 rtl819x_evm_dbtopercentage(
5170 char value
5173 char ret_val;
5175 ret_val = value;
5177 if(ret_val >= 0)
5178 ret_val = 0;
5179 if(ret_val <= -33)
5180 ret_val = -33;
5181 ret_val = 0 - ret_val;
5182 ret_val*=3;
5183 if(ret_val == 99)
5184 ret_val = 100;
5185 return ret_val;
5188 /* We want good-looking for signal strength/quality */
5189 static long rtl819x_signal_scale_mapping(long currsig)
5191 long retsig;
5193 // Step 1. Scale mapping.
5194 if(currsig >= 61 && currsig <= 100)
5196 retsig = 90 + ((currsig - 60) / 4);
5198 else if(currsig >= 41 && currsig <= 60)
5200 retsig = 78 + ((currsig - 40) / 2);
5202 else if(currsig >= 31 && currsig <= 40)
5204 retsig = 66 + (currsig - 30);
5206 else if(currsig >= 21 && currsig <= 30)
5208 retsig = 54 + (currsig - 20);
5210 else if(currsig >= 5 && currsig <= 20)
5212 retsig = 42 + (((currsig - 5) * 2) / 3);
5214 else if(currsig == 4)
5216 retsig = 36;
5218 else if(currsig == 3)
5220 retsig = 27;
5222 else if(currsig == 2)
5224 retsig = 18;
5226 else if(currsig == 1)
5228 retsig = 9;
5230 else
5232 retsig = currsig;
5235 return retsig;
5238 static void rtl8192_query_rxphystatus(
5239 struct r8192_priv * priv,
5240 struct ieee80211_rx_stats * pstats,
5241 prx_desc_819x_pci pdesc,
5242 prx_fwinfo_819x_pci pdrvinfo,
5243 struct ieee80211_rx_stats * precord_stats,
5244 bool bpacket_match_bssid,
5245 bool bpacket_toself,
5246 bool bPacketBeacon,
5247 bool bToSelfBA
5250 //PRT_RFD_STATUS pRtRfdStatus = &(pRfd->Status);
5251 phy_sts_ofdm_819xpci_t* pofdm_buf;
5252 phy_sts_cck_819xpci_t * pcck_buf;
5253 phy_ofdm_rx_status_rxsc_sgien_exintfflag* prxsc;
5254 u8 *prxpkt;
5255 u8 i,max_spatial_stream, tmp_rxsnr, tmp_rxevm, rxsc_sgien_exflg;
5256 char rx_pwr[4], rx_pwr_all=0;
5257 //long rx_avg_pwr = 0;
5258 char rx_snrX, rx_evmX;
5259 u8 evm, pwdb_all;
5260 u32 RSSI, total_rssi=0;//, total_evm=0;
5261 // long signal_strength_index = 0;
5262 u8 is_cck_rate=0;
5263 u8 rf_rx_num = 0;
5265 /* 2007/07/04 MH For OFDM RSSI. For high power or not. */
5266 static u8 check_reg824 = 0;
5267 static u32 reg824_bit9 = 0;
5269 priv->stats.numqry_phystatus++;
5271 is_cck_rate = rx_hal_is_cck_rate(pdrvinfo);
5273 // Record it for next packet processing
5274 memset(precord_stats, 0, sizeof(struct ieee80211_rx_stats));
5275 pstats->bPacketMatchBSSID = precord_stats->bPacketMatchBSSID = bpacket_match_bssid;
5276 pstats->bPacketToSelf = precord_stats->bPacketToSelf = bpacket_toself;
5277 pstats->bIsCCK = precord_stats->bIsCCK = is_cck_rate;//RX_HAL_IS_CCK_RATE(pDrvInfo);
5278 pstats->bPacketBeacon = precord_stats->bPacketBeacon = bPacketBeacon;
5279 pstats->bToSelfBA = precord_stats->bToSelfBA = bToSelfBA;
5280 /*2007.08.30 requested by SD3 Jerry */
5281 if(check_reg824 == 0)
5283 reg824_bit9 = rtl8192_QueryBBReg(priv->ieee80211->dev, rFPGA0_XA_HSSIParameter2, 0x200);
5284 check_reg824 = 1;
5288 prxpkt = (u8*)pdrvinfo;
5290 /* Move pointer to the 16th bytes. Phy status start address. */
5291 prxpkt += sizeof(rx_fwinfo_819x_pci);
5293 /* Initial the cck and ofdm buffer pointer */
5294 pcck_buf = (phy_sts_cck_819xpci_t *)prxpkt;
5295 pofdm_buf = (phy_sts_ofdm_819xpci_t *)prxpkt;
5297 pstats->RxMIMOSignalQuality[0] = -1;
5298 pstats->RxMIMOSignalQuality[1] = -1;
5299 precord_stats->RxMIMOSignalQuality[0] = -1;
5300 precord_stats->RxMIMOSignalQuality[1] = -1;
5302 if(is_cck_rate)
5305 // (1)Hardware does not provide RSSI for CCK
5309 // (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive)
5311 u8 report;//, cck_agc_rpt;
5312 #ifdef RTL8190P
5313 u8 tmp_pwdb;
5314 char cck_adc_pwdb[4];
5315 #endif
5316 priv->stats.numqry_phystatusCCK++;
5318 #ifdef RTL8190P //Only 90P 2T4R need to check
5319 if(priv->rf_type == RF_2T4R && DM_RxPathSelTable.Enable && bpacket_match_bssid)
5321 for(i=RF90_PATH_A; i<RF90_PATH_MAX; i++)
5323 tmp_pwdb = pcck_buf->adc_pwdb_X[i];
5324 cck_adc_pwdb[i] = (char)tmp_pwdb;
5325 cck_adc_pwdb[i] /= 2;
5326 pstats->cck_adc_pwdb[i] = precord_stats->cck_adc_pwdb[i] = cck_adc_pwdb[i];
5327 //DbgPrint("RF-%d tmp_pwdb = 0x%x, cck_adc_pwdb = %d", i, tmp_pwdb, cck_adc_pwdb[i]);
5330 #endif
5332 if(!reg824_bit9)
5334 report = pcck_buf->cck_agc_rpt & 0xc0;
5335 report = report>>6;
5336 switch(report)
5338 //Fixed by Jacken from Bryant 2008-03-20
5339 //Original value is -38 , -26 , -14 , -2
5340 //Fixed value is -35 , -23 , -11 , 6
5341 case 0x3:
5342 rx_pwr_all = -35 - (pcck_buf->cck_agc_rpt & 0x3e);
5343 break;
5344 case 0x2:
5345 rx_pwr_all = -23 - (pcck_buf->cck_agc_rpt & 0x3e);
5346 break;
5347 case 0x1:
5348 rx_pwr_all = -11 - (pcck_buf->cck_agc_rpt & 0x3e);
5349 break;
5350 case 0x0:
5351 rx_pwr_all = 8 - (pcck_buf->cck_agc_rpt & 0x3e);
5352 break;
5355 else
5357 report = pcck_buf->cck_agc_rpt & 0x60;
5358 report = report>>5;
5359 switch(report)
5361 case 0x3:
5362 rx_pwr_all = -35 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1) ;
5363 break;
5364 case 0x2:
5365 rx_pwr_all = -23 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1);
5366 break;
5367 case 0x1:
5368 rx_pwr_all = -11 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1) ;
5369 break;
5370 case 0x0:
5371 rx_pwr_all = -8 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1) ;
5372 break;
5376 pwdb_all = rtl819x_query_rxpwrpercentage(rx_pwr_all);
5377 pstats->RxPWDBAll = precord_stats->RxPWDBAll = pwdb_all;
5378 pstats->RecvSignalPower = rx_pwr_all;
5381 // (3) Get Signal Quality (EVM)
5383 if(bpacket_match_bssid)
5385 u8 sq;
5387 if(pstats->RxPWDBAll > 40)
5389 sq = 100;
5390 }else
5392 sq = pcck_buf->sq_rpt;
5394 if(pcck_buf->sq_rpt > 64)
5395 sq = 0;
5396 else if (pcck_buf->sq_rpt < 20)
5397 sq = 100;
5398 else
5399 sq = ((64-sq) * 100) / 44;
5401 pstats->SignalQuality = precord_stats->SignalQuality = sq;
5402 pstats->RxMIMOSignalQuality[0] = precord_stats->RxMIMOSignalQuality[0] = sq;
5403 pstats->RxMIMOSignalQuality[1] = precord_stats->RxMIMOSignalQuality[1] = -1;
5406 else
5408 priv->stats.numqry_phystatusHT++;
5410 // (1)Get RSSI for HT rate
5412 for(i=RF90_PATH_A; i<RF90_PATH_MAX; i++)
5414 // 2008/01/30 MH we will judge RF RX path now.
5415 if (priv->brfpath_rxenable[i])
5416 rf_rx_num++;
5417 //else
5418 //continue;
5420 //Fixed by Jacken from Bryant 2008-03-20
5421 //Original value is 106
5422 #ifdef RTL8190P //Modify by Jacken 2008/03/31
5423 rx_pwr[i] = ((pofdm_buf->trsw_gain_X[i]&0x3F)*2) - 106;
5424 #else
5425 rx_pwr[i] = ((pofdm_buf->trsw_gain_X[i]&0x3F)*2) - 110;
5426 #endif
5428 //Get Rx snr value in DB
5429 tmp_rxsnr = pofdm_buf->rxsnr_X[i];
5430 rx_snrX = (char)(tmp_rxsnr);
5431 rx_snrX /= 2;
5432 priv->stats.rxSNRdB[i] = (long)rx_snrX;
5434 /* Translate DBM to percentage. */
5435 RSSI = rtl819x_query_rxpwrpercentage(rx_pwr[i]);
5436 if (priv->brfpath_rxenable[i])
5437 total_rssi += RSSI;
5439 /* Record Signal Strength for next packet */
5440 if(bpacket_match_bssid)
5442 pstats->RxMIMOSignalStrength[i] =(u8) RSSI;
5443 precord_stats->RxMIMOSignalStrength[i] =(u8) RSSI;
5449 // (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive)
5451 //Fixed by Jacken from Bryant 2008-03-20
5452 //Original value is 106
5453 rx_pwr_all = (((pofdm_buf->pwdb_all ) >> 1 )& 0x7f) -106;
5454 pwdb_all = rtl819x_query_rxpwrpercentage(rx_pwr_all);
5456 pstats->RxPWDBAll = precord_stats->RxPWDBAll = pwdb_all;
5457 pstats->RxPower = precord_stats->RxPower = rx_pwr_all;
5458 pstats->RecvSignalPower = rx_pwr_all;
5460 // (3)EVM of HT rate
5462 if(pdrvinfo->RxHT && pdrvinfo->RxRate>=DESC90_RATEMCS8 &&
5463 pdrvinfo->RxRate<=DESC90_RATEMCS15)
5464 max_spatial_stream = 2; //both spatial stream make sense
5465 else
5466 max_spatial_stream = 1; //only spatial stream 1 makes sense
5468 for(i=0; i<max_spatial_stream; i++)
5470 tmp_rxevm = pofdm_buf->rxevm_X[i];
5471 rx_evmX = (char)(tmp_rxevm);
5473 // Do not use shift operation like "rx_evmX >>= 1" because the compilor of free build environment
5474 // fill most significant bit to "zero" when doing shifting operation which may change a negative
5475 // value to positive one, then the dbm value (which is supposed to be negative) is not correct anymore.
5476 rx_evmX /= 2; //dbm
5478 evm = rtl819x_evm_dbtopercentage(rx_evmX);
5479 #if 0
5480 EVM = SignalScaleMapping(EVM);//make it good looking, from 0~100
5481 #endif
5482 if(bpacket_match_bssid)
5484 if(i==0) // Fill value in RFD, Get the first spatial stream only
5485 pstats->SignalQuality = precord_stats->SignalQuality = (u8)(evm & 0xff);
5486 pstats->RxMIMOSignalQuality[i] = precord_stats->RxMIMOSignalQuality[i] = (u8)(evm & 0xff);
5491 /* record rx statistics for debug */
5492 rxsc_sgien_exflg = pofdm_buf->rxsc_sgien_exflg;
5493 prxsc = (phy_ofdm_rx_status_rxsc_sgien_exintfflag *)&rxsc_sgien_exflg;
5494 if(pdrvinfo->BW) //40M channel
5495 priv->stats.received_bwtype[1+prxsc->rxsc]++;
5496 else //20M channel
5497 priv->stats.received_bwtype[0]++;
5500 //UI BSS List signal strength(in percentage), make it good looking, from 0~100.
5501 //It is assigned to the BSS List in GetValueFromBeaconOrProbeRsp().
5502 if(is_cck_rate)
5504 pstats->SignalStrength = precord_stats->SignalStrength = (u8)(rtl819x_signal_scale_mapping((long)pwdb_all));//PWDB_ALL;
5507 else
5509 //pRfd->Status.SignalStrength = pRecordRfd->Status.SignalStrength = (u1Byte)(SignalScaleMapping(total_rssi/=RF90_PATH_MAX));//(u1Byte)(total_rssi/=RF90_PATH_MAX);
5510 // We can judge RX path number now.
5511 if (rf_rx_num != 0)
5512 pstats->SignalStrength = precord_stats->SignalStrength = (u8)(rtl819x_signal_scale_mapping((long)(total_rssi/=rf_rx_num)));
5516 static void
5517 rtl8192_record_rxdesc_forlateruse(
5518 struct ieee80211_rx_stats * psrc_stats,
5519 struct ieee80211_rx_stats * ptarget_stats
5522 ptarget_stats->bIsAMPDU = psrc_stats->bIsAMPDU;
5523 ptarget_stats->bFirstMPDU = psrc_stats->bFirstMPDU;
5524 //ptarget_stats->Seq_Num = psrc_stats->Seq_Num;
5529 static void TranslateRxSignalStuff819xpci(struct net_device *dev,
5530 struct sk_buff *skb,
5531 struct ieee80211_rx_stats * pstats,
5532 prx_desc_819x_pci pdesc,
5533 prx_fwinfo_819x_pci pdrvinfo)
5535 // TODO: We must only check packet for current MAC address. Not finish
5536 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
5537 bool bpacket_match_bssid, bpacket_toself;
5538 bool bPacketBeacon=false, bToSelfBA=false;
5539 static struct ieee80211_rx_stats previous_stats;
5540 struct ieee80211_hdr_3addr *hdr;
5541 u16 fc,type;
5543 // Get Signal Quality for only RX data queue (but not command queue)
5545 u8* tmp_buf;
5546 u8 *praddr;
5548 /* Get MAC frame start address. */
5549 tmp_buf = skb->data;
5551 hdr = (struct ieee80211_hdr_3addr *)tmp_buf;
5552 fc = le16_to_cpu(hdr->frame_ctl);
5553 type = WLAN_FC_GET_TYPE(fc);
5554 praddr = hdr->addr1;
5556 /* Check if the received packet is acceptabe. */
5557 bpacket_match_bssid = ((IEEE80211_FTYPE_CTL != type) &&
5558 (!compare_ether_addr(priv->ieee80211->current_network.bssid, (fc & IEEE80211_FCTL_TODS)? hdr->addr1 : (fc & IEEE80211_FCTL_FROMDS )? hdr->addr2 : hdr->addr3))
5559 && (!pstats->bHwError) && (!pstats->bCRC)&& (!pstats->bICV));
5560 bpacket_toself = bpacket_match_bssid & (!compare_ether_addr(praddr, priv->ieee80211->dev->dev_addr));
5561 #if 1//cosa
5562 if(WLAN_FC_GET_FRAMETYPE(fc)== IEEE80211_STYPE_BEACON)
5564 bPacketBeacon = true;
5565 //DbgPrint("Beacon 2, MatchBSSID = %d, ToSelf = %d \n", bPacketMatchBSSID, bPacketToSelf);
5567 if(WLAN_FC_GET_FRAMETYPE(fc) == IEEE80211_STYPE_BLOCKACK)
5569 if((!compare_ether_addr(praddr,dev->dev_addr)))
5570 bToSelfBA = true;
5571 //DbgPrint("BlockAck, MatchBSSID = %d, ToSelf = %d \n", bPacketMatchBSSID, bPacketToSelf);
5574 #endif
5575 if(bpacket_match_bssid)
5577 priv->stats.numpacket_matchbssid++;
5579 if(bpacket_toself){
5580 priv->stats.numpacket_toself++;
5583 // Process PHY information for previous packet (RSSI/PWDB/EVM)
5585 // Because phy information is contained in the last packet of AMPDU only, so driver
5586 // should process phy information of previous packet
5587 rtl8192_process_phyinfo(priv, tmp_buf,&previous_stats, pstats);
5588 rtl8192_query_rxphystatus(priv, pstats, pdesc, pdrvinfo, &previous_stats, bpacket_match_bssid,
5589 bpacket_toself ,bPacketBeacon, bToSelfBA);
5590 rtl8192_record_rxdesc_forlateruse(pstats, &previous_stats);
5595 static void rtl8192_tx_resume(struct net_device *dev)
5597 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
5598 struct ieee80211_device *ieee = priv->ieee80211;
5599 struct sk_buff *skb;
5600 int queue_index;
5602 for(queue_index = BK_QUEUE; queue_index < TXCMD_QUEUE;queue_index++) {
5603 while((!skb_queue_empty(&ieee->skb_waitQ[queue_index]))&&
5604 (priv->ieee80211->check_nic_enough_desc(dev,queue_index) > 0)) {
5605 /* 1. dequeue the packet from the wait queue */
5606 skb = skb_dequeue(&ieee->skb_waitQ[queue_index]);
5607 /* 2. tx the packet directly */
5608 ieee->softmac_data_hard_start_xmit(skb,dev,0/* rate useless now*/);
5609 #if 0
5610 if(queue_index!=MGNT_QUEUE) {
5611 ieee->stats.tx_packets++;
5612 ieee->stats.tx_bytes += skb->len;
5614 #endif
5619 static void rtl8192_irq_tx_tasklet(struct r8192_priv *priv)
5621 rtl8192_tx_resume(priv->ieee80211->dev);
5624 /* Record the received data rate */
5625 static void UpdateReceivedRateHistogramStatistics8190(
5626 struct net_device *dev,
5627 struct ieee80211_rx_stats* pstats
5630 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
5631 u32 rcvType=1; //0: Total, 1:OK, 2:CRC, 3:ICV
5632 u32 rateIndex;
5633 u32 preamble_guardinterval; //1: short preamble/GI, 0: long preamble/GI
5635 if(pstats->bCRC)
5636 rcvType = 2;
5637 else if(pstats->bICV)
5638 rcvType = 3;
5640 if(pstats->bShortPreamble)
5641 preamble_guardinterval = 1;// short
5642 else
5643 preamble_guardinterval = 0;// long
5645 switch(pstats->rate)
5648 // CCK rate
5650 case MGN_1M: rateIndex = 0; break;
5651 case MGN_2M: rateIndex = 1; break;
5652 case MGN_5_5M: rateIndex = 2; break;
5653 case MGN_11M: rateIndex = 3; break;
5655 // Legacy OFDM rate
5657 case MGN_6M: rateIndex = 4; break;
5658 case MGN_9M: rateIndex = 5; break;
5659 case MGN_12M: rateIndex = 6; break;
5660 case MGN_18M: rateIndex = 7; break;
5661 case MGN_24M: rateIndex = 8; break;
5662 case MGN_36M: rateIndex = 9; break;
5663 case MGN_48M: rateIndex = 10; break;
5664 case MGN_54M: rateIndex = 11; break;
5666 // 11n High throughput rate
5668 case MGN_MCS0: rateIndex = 12; break;
5669 case MGN_MCS1: rateIndex = 13; break;
5670 case MGN_MCS2: rateIndex = 14; break;
5671 case MGN_MCS3: rateIndex = 15; break;
5672 case MGN_MCS4: rateIndex = 16; break;
5673 case MGN_MCS5: rateIndex = 17; break;
5674 case MGN_MCS6: rateIndex = 18; break;
5675 case MGN_MCS7: rateIndex = 19; break;
5676 case MGN_MCS8: rateIndex = 20; break;
5677 case MGN_MCS9: rateIndex = 21; break;
5678 case MGN_MCS10: rateIndex = 22; break;
5679 case MGN_MCS11: rateIndex = 23; break;
5680 case MGN_MCS12: rateIndex = 24; break;
5681 case MGN_MCS13: rateIndex = 25; break;
5682 case MGN_MCS14: rateIndex = 26; break;
5683 case MGN_MCS15: rateIndex = 27; break;
5684 default: rateIndex = 28; break;
5686 priv->stats.received_preamble_GI[preamble_guardinterval][rateIndex]++;
5687 priv->stats.received_rate_histogram[0][rateIndex]++; //total
5688 priv->stats.received_rate_histogram[rcvType][rateIndex]++;
5691 static void rtl8192_rx(struct net_device *dev)
5693 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
5694 struct ieee80211_hdr_1addr *ieee80211_hdr = NULL;
5695 bool unicast_packet = false;
5696 struct ieee80211_rx_stats stats = {
5697 .signal = 0,
5698 .noise = -98,
5699 .rate = 0,
5700 .freq = IEEE80211_24GHZ_BAND,
5702 unsigned int count = priv->rxringcount;
5704 stats.nic_type = NIC_8192E;
5706 while (count--) {
5707 rx_desc_819x_pci *pdesc = &priv->rx_ring[priv->rx_idx];//rx descriptor
5708 struct sk_buff *skb = priv->rx_buf[priv->rx_idx];//rx pkt
5710 if (pdesc->OWN){
5711 /* wait data to be filled by hardware */
5712 return;
5713 } else {
5714 stats.bICV = pdesc->ICV;
5715 stats.bCRC = pdesc->CRC32;
5716 stats.bHwError = pdesc->CRC32 | pdesc->ICV;
5718 stats.Length = pdesc->Length;
5719 if(stats.Length < 24)
5720 stats.bHwError |= 1;
5722 if(stats.bHwError) {
5723 stats.bShift = false;
5725 if(pdesc->CRC32) {
5726 if (pdesc->Length <500)
5727 priv->stats.rxcrcerrmin++;
5728 else if (pdesc->Length >1000)
5729 priv->stats.rxcrcerrmax++;
5730 else
5731 priv->stats.rxcrcerrmid++;
5733 goto done;
5734 } else {
5735 prx_fwinfo_819x_pci pDrvInfo = NULL;
5736 struct sk_buff *new_skb = dev_alloc_skb(priv->rxbuffersize);
5738 if (unlikely(!new_skb)) {
5739 goto done;
5742 stats.RxDrvInfoSize = pdesc->RxDrvInfoSize;
5743 stats.RxBufShift = ((pdesc->Shift)&0x03);
5744 stats.Decrypted = !pdesc->SWDec;
5746 pci_dma_sync_single_for_cpu(priv->pdev,
5747 *((dma_addr_t *)skb->cb),
5748 priv->rxbuffersize,
5749 PCI_DMA_FROMDEVICE);
5750 skb_put(skb, pdesc->Length);
5751 pDrvInfo = (rx_fwinfo_819x_pci *)(skb->data + stats.RxBufShift);
5752 skb_reserve(skb, stats.RxDrvInfoSize + stats.RxBufShift);
5754 stats.rate = HwRateToMRate90((bool)pDrvInfo->RxHT, (u8)pDrvInfo->RxRate);
5755 stats.bShortPreamble = pDrvInfo->SPLCP;
5757 /* it is debug only. It should be disabled in released driver.
5758 * 2007.1.11 by Emily
5759 * */
5760 UpdateReceivedRateHistogramStatistics8190(dev, &stats);
5762 stats.bIsAMPDU = (pDrvInfo->PartAggr==1);
5763 stats.bFirstMPDU = (pDrvInfo->PartAggr==1) && (pDrvInfo->FirstAGGR==1);
5765 stats.TimeStampLow = pDrvInfo->TSFL;
5766 stats.TimeStampHigh = read_nic_dword(dev, TSFR+4);
5768 UpdateRxPktTimeStamp8190(dev, &stats);
5771 // Get Total offset of MPDU Frame Body
5773 if((stats.RxBufShift + stats.RxDrvInfoSize) > 0)
5774 stats.bShift = 1;
5776 stats.RxIs40MHzPacket = pDrvInfo->BW;
5778 /* ???? */
5779 TranslateRxSignalStuff819xpci(dev,skb, &stats, pdesc, pDrvInfo);
5781 /* Rx A-MPDU */
5782 if(pDrvInfo->FirstAGGR==1 || pDrvInfo->PartAggr == 1)
5783 RT_TRACE(COMP_RXDESC, "pDrvInfo->FirstAGGR = %d, pDrvInfo->PartAggr = %d\n",
5784 pDrvInfo->FirstAGGR, pDrvInfo->PartAggr);
5785 skb_trim(skb, skb->len - 4/*sCrcLng*/);
5786 /* rx packets statistics */
5787 ieee80211_hdr = (struct ieee80211_hdr_1addr *)skb->data;
5788 unicast_packet = false;
5790 if(is_broadcast_ether_addr(ieee80211_hdr->addr1)) {
5791 //TODO
5792 }else if(is_multicast_ether_addr(ieee80211_hdr->addr1)){
5793 //TODO
5794 }else {
5795 /* unicast packet */
5796 unicast_packet = true;
5799 stats.packetlength = stats.Length-4;
5800 stats.fraglength = stats.packetlength;
5801 stats.fragoffset = 0;
5802 stats.ntotalfrag = 1;
5804 if(!ieee80211_rtl_rx(priv->ieee80211, skb, &stats)){
5805 dev_kfree_skb_any(skb);
5806 } else {
5807 priv->stats.rxok++;
5808 if(unicast_packet) {
5809 priv->stats.rxbytesunicast += skb->len;
5813 pci_unmap_single(priv->pdev, *((dma_addr_t *) skb->cb),
5814 priv->rxbuffersize, PCI_DMA_FROMDEVICE);
5816 skb = new_skb;
5817 priv->rx_buf[priv->rx_idx] = skb;
5818 *((dma_addr_t *) skb->cb) = pci_map_single(priv->pdev, skb_tail_pointer(skb), priv->rxbuffersize, PCI_DMA_FROMDEVICE);
5822 done:
5823 pdesc->BufferAddress = cpu_to_le32(*((dma_addr_t *)skb->cb));
5824 pdesc->OWN = 1;
5825 pdesc->Length = priv->rxbuffersize;
5826 if (priv->rx_idx == priv->rxringcount-1)
5827 pdesc->EOR = 1;
5828 priv->rx_idx = (priv->rx_idx + 1) % priv->rxringcount;
5833 static void rtl8192_irq_rx_tasklet(struct r8192_priv *priv)
5835 rtl8192_rx(priv->ieee80211->dev);
5836 /* unmask RDU */
5837 write_nic_dword(priv->ieee80211->dev, INTA_MASK,read_nic_dword(priv->ieee80211->dev, INTA_MASK) | IMR_RDU);
5840 static const struct net_device_ops rtl8192_netdev_ops = {
5841 .ndo_open = rtl8192_open,
5842 .ndo_stop = rtl8192_close,
5843 .ndo_tx_timeout = tx_timeout,
5844 .ndo_do_ioctl = rtl8192_ioctl,
5845 .ndo_set_multicast_list = r8192_set_multicast,
5846 .ndo_set_mac_address = r8192_set_mac_adr,
5847 .ndo_start_xmit = ieee80211_rtl_xmit,
5850 static int __devinit rtl8192_pci_probe(struct pci_dev *pdev,
5851 const struct pci_device_id *id)
5853 unsigned long ioaddr = 0;
5854 struct net_device *dev = NULL;
5855 struct r8192_priv *priv= NULL;
5856 u8 unit = 0;
5857 int ret = -ENODEV;
5859 #ifdef CONFIG_RTL8192_IO_MAP
5860 unsigned long pio_start, pio_len, pio_flags;
5861 #else
5862 unsigned long pmem_start, pmem_len, pmem_flags;
5863 #endif //end #ifdef RTL_IO_MAP
5865 RT_TRACE(COMP_INIT,"Configuring chip resources");
5867 if( pci_enable_device (pdev) ){
5868 RT_TRACE(COMP_ERR,"Failed to enable PCI device");
5869 return -EIO;
5872 pci_set_master(pdev);
5873 //pci_set_wmi(pdev);
5874 pci_set_dma_mask(pdev, 0xffffff00ULL);
5875 pci_set_consistent_dma_mask(pdev,0xffffff00ULL);
5876 dev = alloc_ieee80211(sizeof(struct r8192_priv));
5877 if (!dev) {
5878 ret = -ENOMEM;
5879 goto fail_free;
5882 pci_set_drvdata(pdev, dev);
5883 SET_NETDEV_DEV(dev, &pdev->dev);
5884 priv = ieee80211_priv(dev);
5885 priv->ieee80211 = netdev_priv(dev);
5886 priv->pdev=pdev;
5887 if((pdev->subsystem_vendor == PCI_VENDOR_ID_DLINK)&&(pdev->subsystem_device == 0x3304)){
5888 priv->ieee80211->bSupportRemoteWakeUp = 1;
5889 } else
5891 priv->ieee80211->bSupportRemoteWakeUp = 0;
5894 #ifdef CONFIG_RTL8192_IO_MAP
5896 pio_start = (unsigned long)pci_resource_start (pdev, 0);
5897 pio_len = (unsigned long)pci_resource_len (pdev, 0);
5898 pio_flags = (unsigned long)pci_resource_flags (pdev, 0);
5900 if (!(pio_flags & IORESOURCE_IO)) {
5901 RT_TRACE(COMP_ERR,"region #0 not a PIO resource, aborting");
5902 goto fail;
5905 //DMESG("IO space @ 0x%08lx", pio_start );
5906 if( ! request_region( pio_start, pio_len, RTL819xE_MODULE_NAME ) ){
5907 RT_TRACE(COMP_ERR,"request_region failed!");
5908 goto fail;
5911 ioaddr = pio_start;
5912 dev->base_addr = ioaddr; // device I/O address
5914 #else
5916 pmem_start = pci_resource_start(pdev, 1);
5917 pmem_len = pci_resource_len(pdev, 1);
5918 pmem_flags = pci_resource_flags (pdev, 1);
5920 if (!(pmem_flags & IORESOURCE_MEM)) {
5921 RT_TRACE(COMP_ERR,"region #1 not a MMIO resource, aborting");
5922 goto fail;
5925 //DMESG("Memory mapped space @ 0x%08lx ", pmem_start);
5926 if( ! request_mem_region(pmem_start, pmem_len, RTL819xE_MODULE_NAME)) {
5927 RT_TRACE(COMP_ERR,"request_mem_region failed!");
5928 goto fail;
5932 ioaddr = (unsigned long)ioremap_nocache( pmem_start, pmem_len);
5933 if( ioaddr == (unsigned long)NULL ){
5934 RT_TRACE(COMP_ERR,"ioremap failed!");
5935 // release_mem_region( pmem_start, pmem_len );
5936 goto fail1;
5939 dev->mem_start = ioaddr; // shared mem start
5940 dev->mem_end = ioaddr + pci_resource_len(pdev, 0); // shared mem end
5942 #endif //end #ifdef RTL_IO_MAP
5944 /* We disable the RETRY_TIMEOUT register (0x41) to keep
5945 * PCI Tx retries from interfering with C3 CPU state */
5946 pci_write_config_byte(pdev, 0x41, 0x00);
5949 pci_read_config_byte(pdev, 0x05, &unit);
5950 pci_write_config_byte(pdev, 0x05, unit & (~0x04));
5952 dev->irq = pdev->irq;
5953 priv->irq = 0;
5955 dev->netdev_ops = &rtl8192_netdev_ops;
5956 #if 0
5957 dev->open = rtl8192_open;
5958 dev->stop = rtl8192_close;
5959 //dev->hard_start_xmit = rtl8192_8023_hard_start_xmit;
5960 dev->tx_timeout = tx_timeout;
5961 //dev->wireless_handlers = &r8192_wx_handlers_def;
5962 dev->do_ioctl = rtl8192_ioctl;
5963 dev->set_multicast_list = r8192_set_multicast;
5964 dev->set_mac_address = r8192_set_mac_adr;
5965 #endif
5967 //DMESG("Oops: i'm coming\n");
5968 #if WIRELESS_EXT >= 12
5969 #if WIRELESS_EXT < 17
5970 dev->get_wireless_stats = r8192_get_wireless_stats;
5971 #endif
5972 dev->wireless_handlers = (struct iw_handler_def *) &r8192_wx_handlers_def;
5973 #endif
5974 //dev->get_wireless_stats = r8192_get_wireless_stats;
5975 dev->type=ARPHRD_ETHER;
5977 dev->watchdog_timeo = HZ*3; //modified by john, 0805
5979 if (dev_alloc_name(dev, ifname) < 0){
5980 RT_TRACE(COMP_INIT, "Oops: devname already taken! Trying wlan%%d...\n");
5981 strcpy(ifname, "wlan%d");
5982 dev_alloc_name(dev, ifname);
5985 RT_TRACE(COMP_INIT, "Driver probe completed1\n");
5986 if(rtl8192_init(dev)!=0){
5987 RT_TRACE(COMP_ERR, "Initialization failed");
5988 goto fail;
5991 netif_carrier_off(dev);
5992 netif_stop_queue(dev);
5994 register_netdev(dev);
5995 RT_TRACE(COMP_INIT, "dev name=======> %s\n",dev->name);
5996 rtl8192_proc_init_one(dev);
5999 RT_TRACE(COMP_INIT, "Driver probe completed\n");
6000 return 0;
6002 fail1:
6004 #ifdef CONFIG_RTL8180_IO_MAP
6006 if( dev->base_addr != 0 ){
6008 release_region(dev->base_addr,
6009 pci_resource_len(pdev, 0) );
6011 #else
6012 if( dev->mem_start != (unsigned long)NULL ){
6013 iounmap( (void *)dev->mem_start );
6014 release_mem_region( pci_resource_start(pdev, 1),
6015 pci_resource_len(pdev, 1) );
6017 #endif //end #ifdef RTL_IO_MAP
6019 fail:
6020 if(dev){
6022 if (priv->irq) {
6023 free_irq(dev->irq, dev);
6024 dev->irq=0;
6026 free_ieee80211(dev);
6029 fail_free:
6030 pci_disable_device(pdev);
6032 DMESG("wlan driver load failed\n");
6033 pci_set_drvdata(pdev, NULL);
6034 return ret;
6038 /* detach all the work and timer structure declared or inititialized
6039 * in r8192_init function.
6040 * */
6041 static void rtl8192_cancel_deferred_work(struct r8192_priv* priv)
6043 /* call cancel_work_sync instead of cancel_delayed_work if and only if Linux_version_code
6044 * is or is newer than 2.6.20 and work structure is defined to be struct work_struct.
6045 * Otherwise call cancel_delayed_work is enough.
6046 * FIXME (2.6.20 should 2.6.22, work_struct should not cancel)
6047 * */
6048 cancel_delayed_work(&priv->watch_dog_wq);
6049 cancel_delayed_work(&priv->update_beacon_wq);
6050 cancel_delayed_work(&priv->ieee80211->hw_wakeup_wq);
6051 cancel_delayed_work(&priv->ieee80211->hw_sleep_wq);
6052 #ifdef RTL8192E
6053 cancel_delayed_work(&priv->gpio_change_rf_wq);
6054 #endif
6055 cancel_work_sync(&priv->reset_wq);
6056 cancel_work_sync(&priv->qos_activate);
6057 //cancel_work_sync(&priv->SetBWModeWorkItem);
6058 //cancel_work_sync(&priv->SwChnlWorkItem);
6063 static void __devexit rtl8192_pci_disconnect(struct pci_dev *pdev)
6065 struct net_device *dev = pci_get_drvdata(pdev);
6066 struct r8192_priv *priv ;
6068 if(dev){
6070 unregister_netdev(dev);
6072 priv=ieee80211_priv(dev);
6074 rtl8192_proc_remove_one(dev);
6076 rtl8192_down(dev);
6077 if (priv->pFirmware)
6079 vfree(priv->pFirmware);
6080 priv->pFirmware = NULL;
6082 // priv->rf_close(dev);
6083 // rtl8192_usb_deleteendpoints(dev);
6084 destroy_workqueue(priv->priv_wq);
6085 /* redundant with rtl8192_down */
6086 // rtl8192_irq_disable(dev);
6087 // rtl8192_reset(dev);
6088 // mdelay(10);
6090 u32 i;
6091 /* free tx/rx rings */
6092 rtl8192_free_rx_ring(dev);
6093 for (i = 0; i < MAX_TX_QUEUE_COUNT; i++) {
6094 rtl8192_free_tx_ring(dev, i);
6097 if(priv->irq){
6099 printk("Freeing irq %d\n",dev->irq);
6100 free_irq(dev->irq, dev);
6101 priv->irq=0;
6107 // free_beacon_desc_ring(dev,priv->txbeaconcount);
6109 #ifdef CONFIG_RTL8180_IO_MAP
6111 if( dev->base_addr != 0 ){
6113 release_region(dev->base_addr,
6114 pci_resource_len(pdev, 0) );
6116 #else
6117 if( dev->mem_start != (unsigned long)NULL ){
6118 iounmap( (void *)dev->mem_start );
6119 release_mem_region( pci_resource_start(pdev, 1),
6120 pci_resource_len(pdev, 1) );
6122 #endif /*end #ifdef RTL_IO_MAP*/
6123 free_ieee80211(dev);
6127 pci_disable_device(pdev);
6128 RT_TRACE(COMP_DOWN, "wlan driver removed\n");
6131 extern int ieee80211_rtl_init(void);
6132 extern void ieee80211_rtl_exit(void);
6134 static int __init rtl8192_pci_module_init(void)
6136 int retval;
6138 retval = ieee80211_rtl_init();
6139 if (retval)
6140 return retval;
6142 printk(KERN_INFO "\nLinux kernel driver for RTL8192 based WLAN cards\n");
6143 printk(KERN_INFO "Copyright (c) 2007-2008, Realsil Wlan\n");
6144 RT_TRACE(COMP_INIT, "Initializing module");
6145 RT_TRACE(COMP_INIT, "Wireless extensions version %d", WIRELESS_EXT);
6146 rtl8192_proc_module_init();
6147 if(0!=pci_register_driver(&rtl8192_pci_driver))
6149 DMESG("No device found");
6150 /*pci_unregister_driver (&rtl8192_pci_driver);*/
6151 return -ENODEV;
6153 return 0;
6157 static void __exit rtl8192_pci_module_exit(void)
6159 pci_unregister_driver(&rtl8192_pci_driver);
6161 RT_TRACE(COMP_DOWN, "Exiting");
6162 rtl8192_proc_module_remove();
6163 ieee80211_rtl_exit();
6166 static irqreturn_t rtl8192_interrupt(int irq, void *netdev)
6168 struct net_device *dev = (struct net_device *) netdev;
6169 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
6170 unsigned long flags;
6171 u32 inta;
6172 irqreturn_t ret = IRQ_HANDLED;
6174 spin_lock_irqsave(&priv->irq_th_lock, flags);
6176 /* We should return IRQ_NONE, but for now let me keep this */
6177 if (priv->irq_enabled == 0)
6178 goto out_unlock;
6180 /* ISR: 4bytes */
6182 inta = read_nic_dword(dev, ISR); /* & priv->IntrMask; */
6183 write_nic_dword(dev, ISR, inta); /* reset int situation */
6185 priv->stats.shints++;
6186 if (!inta) {
6188 * most probably we can safely return IRQ_NONE,
6189 * but for now is better to avoid problems
6191 goto out_unlock;
6194 if (inta == 0xffff) {
6195 /* HW disappared */
6196 goto out_unlock;
6199 priv->stats.ints++;
6200 #ifdef DEBUG_IRQ
6201 DMESG("NIC irq %x",inta);
6202 #endif
6204 if (!netif_running(dev))
6205 goto out_unlock;
6207 if (inta & IMR_TBDOK) {
6208 RT_TRACE(COMP_INTR, "beacon ok interrupt!\n");
6209 rtl8192_tx_isr(dev, BEACON_QUEUE);
6210 priv->stats.txbeaconokint++;
6213 if (inta & IMR_TBDER) {
6214 RT_TRACE(COMP_INTR, "beacon ok interrupt!\n");
6215 rtl8192_tx_isr(dev, BEACON_QUEUE);
6216 priv->stats.txbeaconerr++;
6219 if (inta & IMR_MGNTDOK ) {
6220 RT_TRACE(COMP_INTR, "Manage ok interrupt!\n");
6221 priv->stats.txmanageokint++;
6222 rtl8192_tx_isr(dev,MGNT_QUEUE);
6225 if (inta & IMR_COMDOK)
6227 priv->stats.txcmdpktokint++;
6228 rtl8192_tx_isr(dev, TXCMD_QUEUE);
6231 if (inta & IMR_ROK) {
6232 #ifdef DEBUG_RX
6233 DMESG("Frame arrived !");
6234 #endif
6235 priv->stats.rxint++;
6236 tasklet_schedule(&priv->irq_rx_tasklet);
6239 if (inta & IMR_BcnInt) {
6240 RT_TRACE(COMP_INTR, "prepare beacon for interrupt!\n");
6241 tasklet_schedule(&priv->irq_prepare_beacon_tasklet);
6244 if (inta & IMR_RDU) {
6245 RT_TRACE(COMP_INTR, "rx descriptor unavailable!\n");
6246 priv->stats.rxrdu++;
6247 /* reset int situation */
6248 write_nic_dword(dev, INTA_MASK, read_nic_dword(dev, INTA_MASK) & ~IMR_RDU);
6249 tasklet_schedule(&priv->irq_rx_tasklet);
6252 if (inta & IMR_RXFOVW) {
6253 RT_TRACE(COMP_INTR, "rx overflow !\n");
6254 priv->stats.rxoverflow++;
6255 tasklet_schedule(&priv->irq_rx_tasklet);
6258 if (inta & IMR_TXFOVW)
6259 priv->stats.txoverflow++;
6261 if (inta & IMR_BKDOK) {
6262 RT_TRACE(COMP_INTR, "BK Tx OK interrupt!\n");
6263 priv->stats.txbkokint++;
6264 priv->ieee80211->LinkDetectInfo.NumTxOkInPeriod++;
6265 rtl8192_tx_isr(dev, BK_QUEUE);
6268 if (inta & IMR_BEDOK) {
6269 RT_TRACE(COMP_INTR, "BE TX OK interrupt!\n");
6270 priv->stats.txbeokint++;
6271 priv->ieee80211->LinkDetectInfo.NumTxOkInPeriod++;
6272 rtl8192_tx_isr(dev, BE_QUEUE);
6275 if (inta & IMR_VIDOK) {
6276 RT_TRACE(COMP_INTR, "VI TX OK interrupt!\n");
6277 priv->stats.txviokint++;
6278 priv->ieee80211->LinkDetectInfo.NumTxOkInPeriod++;
6279 rtl8192_tx_isr(dev, VI_QUEUE);
6282 if (inta & IMR_VODOK) {
6283 priv->stats.txvookint++;
6284 priv->ieee80211->LinkDetectInfo.NumTxOkInPeriod++;
6285 rtl8192_tx_isr(dev, VO_QUEUE);
6288 out_unlock:
6289 spin_unlock_irqrestore(&priv->irq_th_lock, flags);
6291 return ret;
6294 void EnableHWSecurityConfig8192(struct net_device *dev)
6296 u8 SECR_value = 0x0;
6297 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
6298 struct ieee80211_device* ieee = priv->ieee80211;
6300 SECR_value = SCR_TxEncEnable | SCR_RxDecEnable;
6301 #if 1
6302 if (((KEY_TYPE_WEP40 == ieee->pairwise_key_type) || (KEY_TYPE_WEP104 == ieee->pairwise_key_type)) && (priv->ieee80211->auth_mode != 2))
6304 SECR_value |= SCR_RxUseDK;
6305 SECR_value |= SCR_TxUseDK;
6307 else if ((ieee->iw_mode == IW_MODE_ADHOC) && (ieee->pairwise_key_type & (KEY_TYPE_CCMP | KEY_TYPE_TKIP)))
6309 SECR_value |= SCR_RxUseDK;
6310 SECR_value |= SCR_TxUseDK;
6313 #endif
6315 //add HWSec active enable here.
6316 //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
6317 ieee->hwsec_active = 1;
6319 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
6321 ieee->hwsec_active = 0;
6322 SECR_value &= ~SCR_RxDecEnable;
6325 RT_TRACE(COMP_SEC,"%s:, hwsec:%d, pairwise_key:%d, SECR_value:%x\n", __FUNCTION__,
6326 ieee->hwsec_active, ieee->pairwise_key_type, SECR_value);
6328 write_nic_byte(dev, SECR, SECR_value);//SECR_value | SCR_UseDK );
6332 #define TOTAL_CAM_ENTRY 32
6333 //#define CAM_CONTENT_COUNT 8
6334 void setKey( struct net_device *dev,
6335 u8 EntryNo,
6336 u8 KeyIndex,
6337 u16 KeyType,
6338 const u8 *MacAddr,
6339 u8 DefaultKey,
6340 u32 *KeyContent )
6342 u32 TargetCommand = 0;
6343 u32 TargetContent = 0;
6344 u16 usConfig = 0;
6345 u8 i;
6346 #ifdef ENABLE_IPS
6347 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
6348 RT_RF_POWER_STATE rtState;
6349 rtState = priv->ieee80211->eRFPowerState;
6350 if(priv->ieee80211->PowerSaveControl.bInactivePs){
6351 if(rtState == eRfOff){
6352 if(priv->ieee80211->RfOffReason > RF_CHANGE_BY_IPS)
6354 RT_TRACE(COMP_ERR, "%s(): RF is OFF.\n",__FUNCTION__);
6355 //up(&priv->wx_sem);
6356 return ;
6358 else{
6359 down(&priv->ieee80211->ips_sem);
6360 IPSLeave(dev);
6361 up(&priv->ieee80211->ips_sem);
6365 priv->ieee80211->is_set_key = true;
6366 #endif
6367 if (EntryNo >= TOTAL_CAM_ENTRY)
6368 RT_TRACE(COMP_ERR, "cam entry exceeds in setKey()\n");
6370 RT_TRACE(COMP_SEC, "====>to setKey(), dev:%p, EntryNo:%d, KeyIndex:%d, KeyType:%d, MacAddr%pM\n", dev,EntryNo, KeyIndex, KeyType, MacAddr);
6372 if (DefaultKey)
6373 usConfig |= BIT15 | (KeyType<<2);
6374 else
6375 usConfig |= BIT15 | (KeyType<<2) | KeyIndex;
6376 // usConfig |= BIT15 | (KeyType<<2) | (DefaultKey<<5) | KeyIndex;
6379 for(i=0 ; i<CAM_CONTENT_COUNT; i++){
6380 TargetCommand = i+CAM_CONTENT_COUNT*EntryNo;
6381 TargetCommand |= BIT31|BIT16;
6383 if(i==0){//MAC|Config
6384 TargetContent = (u32)(*(MacAddr+0)) << 16|
6385 (u32)(*(MacAddr+1)) << 24|
6386 (u32)usConfig;
6388 write_nic_dword(dev, WCAMI, TargetContent);
6389 write_nic_dword(dev, RWCAM, TargetCommand);
6390 // printk("setkey cam =%8x\n", read_cam(dev, i+6*EntryNo));
6392 else if(i==1){//MAC
6393 TargetContent = (u32)(*(MacAddr+2)) |
6394 (u32)(*(MacAddr+3)) << 8|
6395 (u32)(*(MacAddr+4)) << 16|
6396 (u32)(*(MacAddr+5)) << 24;
6397 write_nic_dword(dev, WCAMI, TargetContent);
6398 write_nic_dword(dev, RWCAM, TargetCommand);
6400 else { //Key Material
6401 if(KeyContent != NULL)
6403 write_nic_dword(dev, WCAMI, (u32)(*(KeyContent+i-2)) );
6404 write_nic_dword(dev, RWCAM, TargetCommand);
6408 RT_TRACE(COMP_SEC,"=========>after set key, usconfig:%x\n", usConfig);
6411 bool NicIFEnableNIC(struct net_device* dev)
6413 RT_STATUS init_status = RT_STATUS_SUCCESS;
6414 struct r8192_priv* priv = ieee80211_priv(dev);
6415 PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->ieee80211->PowerSaveControl));
6417 //YJ,add,091109
6418 if (priv->up == 0){
6419 RT_TRACE(COMP_ERR, "ERR!!! %s(): Driver is already down!\n",__FUNCTION__);
6420 priv->bdisable_nic = false; //YJ,add,091111
6421 return false;
6423 // <1> Reset memory: descriptor, buffer,..
6424 //NicIFResetMemory(Adapter);
6426 // <2> Enable Adapter
6427 //priv->bfirst_init = true;
6428 init_status = rtl8192_adapter_start(dev);
6429 if (init_status != RT_STATUS_SUCCESS) {
6430 RT_TRACE(COMP_ERR,"ERR!!! %s(): initialization is failed!\n",__FUNCTION__);
6431 priv->bdisable_nic = false; //YJ,add,091111
6432 return -1;
6434 //printk("start adapter finished\n");
6435 RT_CLEAR_PS_LEVEL(pPSC, RT_RF_OFF_LEVL_HALT_NIC);
6436 //priv->bfirst_init = false;
6438 // <3> Enable Interrupt
6439 rtl8192_irq_enable(dev);
6440 priv->bdisable_nic = false;
6442 return (init_status == RT_STATUS_SUCCESS);
6445 bool NicIFDisableNIC(struct net_device* dev)
6447 bool status = true;
6448 struct r8192_priv* priv = ieee80211_priv(dev);
6449 u8 tmp_state = 0;
6450 // <1> Disable Interrupt
6452 priv->bdisable_nic = true; //YJ,move,091109
6453 tmp_state = priv->ieee80211->state;
6455 ieee80211_softmac_stop_protocol(priv->ieee80211, false);
6457 priv->ieee80211->state = tmp_state;
6458 rtl8192_cancel_deferred_work(priv);
6459 rtl8192_irq_disable(dev);
6460 // <2> Stop all timer
6462 // <3> Disable Adapter
6463 rtl8192_halt_adapter(dev, false);
6464 // priv->bdisable_nic = true;
6466 return status;
6469 module_init(rtl8192_pci_module_init);
6470 module_exit(rtl8192_pci_module_exit);