thinkpad-acpi: handle HKEY 0x4010, 0x4011 events
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / drivers / staging / rtl8192u / r8192U_core.c
blobe81b8ab6aa9d160c6a8c30327a751d9d6b82ef48
1 /******************************************************************************
2 * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
3 * Linux device driver for RTL8192U
5 * Based on the r8187 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>
27 #ifndef CONFIG_FORCE_HARD_FLOAT
28 double __floatsidf (int i) { return i; }
29 unsigned int __fixunsdfsi (double d) { return d; }
30 double __adddf3(double a, double b) { return a+b; }
31 double __addsf3(float a, float b) { return a+b; }
32 double __subdf3(double a, double b) { return a-b; }
33 double __extendsfdf2(float a) {return a;}
34 #endif
36 #undef LOOP_TEST
37 #undef DUMP_RX
38 #undef DUMP_TX
39 #undef DEBUG_TX_DESC2
40 #undef RX_DONT_PASS_UL
41 #undef DEBUG_EPROM
42 #undef DEBUG_RX_VERBOSE
43 #undef DUMMY_RX
44 #undef DEBUG_ZERO_RX
45 #undef DEBUG_RX_SKB
46 #undef DEBUG_TX_FRAG
47 #undef DEBUG_RX_FRAG
48 #undef DEBUG_TX_FILLDESC
49 #undef DEBUG_TX
50 #undef DEBUG_IRQ
51 #undef DEBUG_RX
52 #undef DEBUG_RXALLOC
53 #undef DEBUG_REGISTERS
54 #undef DEBUG_RING
55 #undef DEBUG_IRQ_TASKLET
56 #undef DEBUG_TX_ALLOC
57 #undef DEBUG_TX_DESC
59 #define CONFIG_RTL8192_IO_MAP
61 #include <asm/uaccess.h>
62 #include "r8192U_hw.h"
63 #include "r8192U.h"
64 #include "r8190_rtl8256.h" /* RTL8225 Radio frontend */
65 #include "r8180_93cx6.h" /* Card EEPROM */
66 #include "r8192U_wx.h"
67 #include "r819xU_phy.h" //added by WB 4.30.2008
68 #include "r819xU_phyreg.h"
69 #include "r819xU_cmdpkt.h"
70 #include "r8192U_dm.h"
71 //#include "r8192xU_phyreg.h"
72 #include <linux/usb.h>
73 #include <linux/slab.h>
74 // FIXME: check if 2.6.7 is ok
76 #ifdef CONFIG_RTL8192_PM
77 #include "r8192_pm.h"
78 #endif
80 #include "dot11d.h"
81 //set here to open your trace code. //WB
82 u32 rt_global_debug_component = \
83 // COMP_INIT |
84 // COMP_DBG |
85 // COMP_EPROM |
86 // COMP_PHY |
87 // COMP_RF |
88 // COMP_FIRMWARE |
89 // COMP_CH |
90 // COMP_POWER_TRACKING |
91 // COMP_RATE |
92 // COMP_TXAGC |
93 // COMP_TRACE |
94 COMP_DOWN |
95 // COMP_RECV |
96 // COMP_SWBW |
97 COMP_SEC |
98 // COMP_RESET |
99 // COMP_SEND |
100 // COMP_EVENTS |
101 COMP_ERR ; //always open err flags on
103 #define TOTAL_CAM_ENTRY 32
104 #define CAM_CONTENT_COUNT 8
106 static const struct usb_device_id rtl8192_usb_id_tbl[] = {
107 /* Realtek */
108 {USB_DEVICE(0x0bda, 0x8192)},
109 {USB_DEVICE(0x0bda, 0x8709)},
110 /* Corega */
111 {USB_DEVICE(0x07aa, 0x0043)},
112 /* Belkin */
113 {USB_DEVICE(0x050d, 0x805E)},
114 /* Sitecom */
115 {USB_DEVICE(0x0df6, 0x0031)},
116 /* EnGenius */
117 {USB_DEVICE(0x1740, 0x9201)},
118 /* Dlink */
119 {USB_DEVICE(0x2001, 0x3301)},
120 /* Zinwell */
121 {USB_DEVICE(0x5a57, 0x0290)},
122 /* LG */
123 {USB_DEVICE(0x043e, 0x7a01)},
127 MODULE_LICENSE("GPL");
128 MODULE_VERSION("V 1.1");
129 MODULE_DEVICE_TABLE(usb, rtl8192_usb_id_tbl);
130 MODULE_DESCRIPTION("Linux driver for Realtek RTL8192 USB WiFi cards");
132 static char* ifname = "wlan%d";
133 static int hwwep = 1; //default use hw. set 0 to use software security
134 static int channels = 0x3fff;
138 module_param(ifname, charp, S_IRUGO|S_IWUSR );
139 //module_param(hwseqnum,int, S_IRUGO|S_IWUSR);
140 module_param(hwwep,int, S_IRUGO|S_IWUSR);
141 module_param(channels,int, S_IRUGO|S_IWUSR);
143 MODULE_PARM_DESC(ifname," Net interface name, wlan%d=default");
144 //MODULE_PARM_DESC(hwseqnum," Try to use hardware 802.11 header sequence numbers. Zero=default");
145 MODULE_PARM_DESC(hwwep," Try to use hardware security support. ");
146 MODULE_PARM_DESC(channels," Channel bitmask for specific locales. NYI");
148 static int __devinit rtl8192_usb_probe(struct usb_interface *intf,
149 const struct usb_device_id *id);
150 static void __devexit rtl8192_usb_disconnect(struct usb_interface *intf);
153 static struct usb_driver rtl8192_usb_driver = {
154 .name = RTL819xU_MODULE_NAME, /* Driver name */
155 .id_table = rtl8192_usb_id_tbl, /* PCI_ID table */
156 .probe = rtl8192_usb_probe, /* probe fn */
157 .disconnect = rtl8192_usb_disconnect, /* remove fn */
158 #ifdef CONFIG_RTL8192_PM
159 .suspend = rtl8192_suspend, /* PM suspend fn */
160 .resume = rtl8192_resume, /* PM resume fn */
161 #else
162 .suspend = NULL, /* PM suspend fn */
163 .resume = NULL, /* PM resume fn */
164 #endif
168 typedef struct _CHANNEL_LIST
170 u8 Channel[32];
171 u8 Len;
172 }CHANNEL_LIST, *PCHANNEL_LIST;
174 static CHANNEL_LIST ChannelPlan[] = {
175 {{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
176 {{1,2,3,4,5,6,7,8,9,10,11},11}, //IC
177 {{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48,52,56,60,64},21}, //ETSI
178 {{1,2,3,4,5,6,7,8,9,10,11,12,13},13}, //Spain. Change to ETSI.
179 {{1,2,3,4,5,6,7,8,9,10,11,12,13},13}, //France. Change to ETSI.
180 {{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
181 {{1,2,3,4,5,6,7,8,9,10,11,12,13,14,36,40,44,48,52,56,60,64},22},//MKK1
182 {{1,2,3,4,5,6,7,8,9,10,11,12,13},13}, //Israel.
183 {{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
184 {{1,2,3,4,5,6,7,8,9,10,11,12,13,14,36,40,44,48,52,56,60,64}, 22}, //MIC
185 {{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
188 static void rtl819x_set_channel_map(u8 channel_plan, struct r8192_priv* priv)
190 int i, max_chan=-1, min_chan=-1;
191 struct ieee80211_device* ieee = priv->ieee80211;
192 switch (channel_plan)
194 case COUNTRY_CODE_FCC:
195 case COUNTRY_CODE_IC:
196 case COUNTRY_CODE_ETSI:
197 case COUNTRY_CODE_SPAIN:
198 case COUNTRY_CODE_FRANCE:
199 case COUNTRY_CODE_MKK:
200 case COUNTRY_CODE_MKK1:
201 case COUNTRY_CODE_ISRAEL:
202 case COUNTRY_CODE_TELEC:
203 case COUNTRY_CODE_MIC:
205 Dot11d_Init(ieee);
206 ieee->bGlobalDomain = false;
207 //acturally 8225 & 8256 rf chip only support B,G,24N mode
208 if ((priv->rf_chip == RF_8225) || (priv->rf_chip == RF_8256))
210 min_chan = 1;
211 max_chan = 14;
213 else
215 RT_TRACE(COMP_ERR, "unknown rf chip, can't set channel map in function:%s()\n", __FUNCTION__);
217 if (ChannelPlan[channel_plan].Len != 0){
218 // Clear old channel map
219 memset(GET_DOT11D_INFO(ieee)->channel_map, 0, sizeof(GET_DOT11D_INFO(ieee)->channel_map));
220 // Set new channel map
221 for (i=0;i<ChannelPlan[channel_plan].Len;i++)
223 if (ChannelPlan[channel_plan].Channel[i] < min_chan || ChannelPlan[channel_plan].Channel[i] > max_chan)
224 break;
225 GET_DOT11D_INFO(ieee)->channel_map[ChannelPlan[channel_plan].Channel[i]] = 1;
228 break;
230 case COUNTRY_CODE_GLOBAL_DOMAIN:
232 GET_DOT11D_INFO(ieee)->bEnabled = 0;//this flag enabled to follow 11d country IE setting, otherwise, it shall follow global domain settings.
233 Dot11d_Reset(ieee);
234 ieee->bGlobalDomain = true;
235 break;
237 default:
238 break;
240 return;
244 #define rx_hal_is_cck_rate(_pdrvinfo)\
245 (_pdrvinfo->RxRate == DESC90_RATE1M ||\
246 _pdrvinfo->RxRate == DESC90_RATE2M ||\
247 _pdrvinfo->RxRate == DESC90_RATE5_5M ||\
248 _pdrvinfo->RxRate == DESC90_RATE11M) &&\
249 !_pdrvinfo->RxHT\
252 void CamResetAllEntry(struct net_device *dev)
254 u32 ulcommand = 0;
255 //2004/02/11 In static WEP, OID_ADD_KEY or OID_ADD_WEP are set before STA associate to AP.
256 // However, ResetKey is called on OID_802_11_INFRASTRUCTURE_MODE and MlmeAssociateRequest
257 // In this condition, Cam can not be reset because upper layer will not set this static key again.
258 //if(Adapter->EncAlgorithm == WEP_Encryption)
259 // return;
260 //debug
261 //DbgPrint("========================================\n");
262 //DbgPrint(" Call ResetAllEntry \n");
263 //DbgPrint("========================================\n\n");
264 ulcommand |= BIT31|BIT30;
265 write_nic_dword(dev, RWCAM, ulcommand);
270 void write_cam(struct net_device *dev, u8 addr, u32 data)
272 write_nic_dword(dev, WCAMI, data);
273 write_nic_dword(dev, RWCAM, BIT31|BIT16|(addr&0xff) );
276 u32 read_cam(struct net_device *dev, u8 addr)
278 write_nic_dword(dev, RWCAM, 0x80000000|(addr&0xff) );
279 return read_nic_dword(dev, 0xa8);
282 void write_nic_byte_E(struct net_device *dev, int indx, u8 data)
284 int status;
285 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
286 struct usb_device *udev = priv->udev;
288 status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
289 RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
290 indx|0xfe00, 0, &data, 1, HZ / 2);
292 if (status < 0)
294 printk("write_nic_byte_E TimeOut! status:%d\n", status);
298 u8 read_nic_byte_E(struct net_device *dev, int indx)
300 int status;
301 u8 data;
302 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
303 struct usb_device *udev = priv->udev;
305 status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
306 RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
307 indx|0xfe00, 0, &data, 1, HZ / 2);
309 if (status < 0)
311 printk("read_nic_byte_E TimeOut! status:%d\n", status);
314 return data;
316 //as 92U has extend page from 4 to 16, so modify functions below.
317 void write_nic_byte(struct net_device *dev, int indx, u8 data)
319 int status;
321 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
322 struct usb_device *udev = priv->udev;
324 status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
325 RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
326 (indx&0xff)|0xff00, (indx>>8)&0x0f, &data, 1, HZ / 2);
328 if (status < 0)
330 printk("write_nic_byte TimeOut! status:%d\n", status);
337 void write_nic_word(struct net_device *dev, int indx, u16 data)
340 int status;
342 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
343 struct usb_device *udev = priv->udev;
345 status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
346 RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
347 (indx&0xff)|0xff00, (indx>>8)&0x0f, &data, 2, HZ / 2);
349 if (status < 0)
351 printk("write_nic_word TimeOut! status:%d\n", status);
357 void write_nic_dword(struct net_device *dev, int indx, u32 data)
360 int status;
362 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
363 struct usb_device *udev = priv->udev;
365 status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
366 RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
367 (indx&0xff)|0xff00, (indx>>8)&0x0f, &data, 4, HZ / 2);
370 if (status < 0)
372 printk("write_nic_dword TimeOut! status:%d\n", status);
379 u8 read_nic_byte(struct net_device *dev, int indx)
381 u8 data;
382 int status;
383 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
384 struct usb_device *udev = priv->udev;
386 status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
387 RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
388 (indx&0xff)|0xff00, (indx>>8)&0x0f, &data, 1, HZ / 2);
390 if (status < 0)
392 printk("read_nic_byte TimeOut! status:%d\n", status);
395 return data;
400 u16 read_nic_word(struct net_device *dev, int indx)
402 u16 data;
403 int status;
404 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
405 struct usb_device *udev = priv->udev;
407 status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
408 RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
409 (indx&0xff)|0xff00, (indx>>8)&0x0f,
410 &data, 2, HZ / 2);
412 if (status < 0)
413 printk("read_nic_word TimeOut! status:%d\n", status);
415 return data;
418 u16 read_nic_word_E(struct net_device *dev, int indx)
420 u16 data;
421 int status;
422 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
423 struct usb_device *udev = priv->udev;
425 status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
426 RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
427 indx|0xfe00, 0, &data, 2, HZ / 2);
429 if (status < 0)
430 printk("read_nic_word TimeOut! status:%d\n", status);
432 return data;
435 u32 read_nic_dword(struct net_device *dev, int indx)
437 u32 data;
438 int status;
439 /* int result; */
441 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
442 struct usb_device *udev = priv->udev;
444 status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
445 RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
446 (indx&0xff)|0xff00, (indx>>8)&0x0f,
447 &data, 4, HZ / 2);
448 /* if(0 != result) {
449 * printk(KERN_WARNING "read size of data = %d\, date = %d\n",
450 * result, data);
454 if (status < 0)
455 printk("read_nic_dword TimeOut! status:%d\n", status);
457 return data;
460 /* u8 read_phy_cck(struct net_device *dev, u8 adr); */
461 /* u8 read_phy_ofdm(struct net_device *dev, u8 adr); */
462 /* this might still called in what was the PHY rtl8185/rtl8192 common code
463 * plans are to possibility turn it again in one common code...
465 inline void force_pci_posting(struct net_device *dev)
469 static struct net_device_stats *rtl8192_stats(struct net_device *dev);
470 void rtl8192_commit(struct net_device *dev);
471 /* void rtl8192_restart(struct net_device *dev); */
472 void rtl8192_restart(struct work_struct *work);
473 /* void rtl8192_rq_tx_ack(struct work_struct *work); */
474 void watch_dog_timer_callback(unsigned long data);
476 /****************************************************************************
477 * -----------------------------PROCFS STUFF-------------------------
478 *****************************************************************************
481 static struct proc_dir_entry *rtl8192_proc;
483 static int proc_get_stats_ap(char *page, char **start, off_t offset, int count,
484 int *eof, void *data)
486 struct net_device *dev = data;
487 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
488 struct ieee80211_device *ieee = priv->ieee80211;
489 struct ieee80211_network *target;
491 int len = 0;
493 list_for_each_entry(target, &ieee->network_list, list) {
495 len += snprintf(page + len, count - len, "%s ", target->ssid);
497 if (target->wpa_ie_len > 0 || target->rsn_ie_len > 0)
498 len += snprintf(page + len, count - len, "WPA\n");
499 else
500 len += snprintf(page + len, count - len, "non_WPA\n");
503 *eof = 1;
504 return len;
507 static int proc_get_registers(char *page, char **start,
508 off_t offset, int count,
509 int *eof, void *data)
511 struct net_device *dev = data;
512 // struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
514 int len = 0;
515 int i,n;
517 int max=0xff;
519 /* This dump the current register page */
520 len += snprintf(page + len, count - len,
521 "\n####################page 0##################\n ");
523 for(n=0;n<=max;)
525 //printk( "\nD: %2x> ", n);
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,0x000|n));
533 // printk("%2x ",read_nic_byte(dev,n));
535 len += snprintf(page + len, count - len,
536 "\n####################page 1##################\n ");
537 for(n=0;n<=max;)
539 //printk( "\nD: %2x> ", n);
540 len += snprintf(page + len, count - len,
541 "\nD: %2x > ",n);
543 for(i=0;i<16 && n<=max;i++,n++)
544 len += snprintf(page + len, count - len,
545 "%2x ",read_nic_byte(dev,0x100|n));
547 // printk("%2x ",read_nic_byte(dev,n));
549 len += snprintf(page + len, count - len,
550 "\n####################page 3##################\n ");
551 for(n=0;n<=max;)
553 //printk( "\nD: %2x> ", n);
554 len += snprintf(page + len, count - len,
555 "\nD: %2x > ",n);
557 for(i=0;i<16 && n<=max;i++,n++)
558 len += snprintf(page + len, count - len,
559 "%2x ",read_nic_byte(dev,0x300|n));
561 // printk("%2x ",read_nic_byte(dev,n));
565 len += snprintf(page + len, count - len,"\n");
566 *eof = 1;
567 return len;
575 static int proc_get_stats_tx(char *page, char **start,
576 off_t offset, int count,
577 int *eof, void *data)
579 struct net_device *dev = data;
580 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
582 int len = 0;
584 len += snprintf(page + len, count - len,
585 "TX VI priority ok int: %lu\n"
586 "TX VI priority error int: %lu\n"
587 "TX VO priority ok int: %lu\n"
588 "TX VO priority error int: %lu\n"
589 "TX BE priority ok int: %lu\n"
590 "TX BE priority error int: %lu\n"
591 "TX BK priority ok int: %lu\n"
592 "TX BK priority error int: %lu\n"
593 "TX MANAGE priority ok int: %lu\n"
594 "TX MANAGE priority error int: %lu\n"
595 "TX BEACON priority ok int: %lu\n"
596 "TX BEACON priority error int: %lu\n"
597 // "TX high priority ok int: %lu\n"
598 // "TX high priority failed error int: %lu\n"
599 "TX queue resume: %lu\n"
600 "TX queue stopped?: %d\n"
601 "TX fifo overflow: %lu\n"
602 // "TX beacon: %lu\n"
603 "TX VI queue: %d\n"
604 "TX VO queue: %d\n"
605 "TX BE queue: %d\n"
606 "TX BK queue: %d\n"
607 // "TX HW queue: %d\n"
608 "TX VI dropped: %lu\n"
609 "TX VO dropped: %lu\n"
610 "TX BE dropped: %lu\n"
611 "TX BK dropped: %lu\n"
612 "TX total data packets %lu\n",
613 // "TX beacon aborted: %lu\n",
614 priv->stats.txviokint,
615 priv->stats.txvierr,
616 priv->stats.txvookint,
617 priv->stats.txvoerr,
618 priv->stats.txbeokint,
619 priv->stats.txbeerr,
620 priv->stats.txbkokint,
621 priv->stats.txbkerr,
622 priv->stats.txmanageokint,
623 priv->stats.txmanageerr,
624 priv->stats.txbeaconokint,
625 priv->stats.txbeaconerr,
626 // priv->stats.txhpokint,
627 // priv->stats.txhperr,
628 priv->stats.txresumed,
629 netif_queue_stopped(dev),
630 priv->stats.txoverflow,
631 // priv->stats.txbeacon,
632 atomic_read(&(priv->tx_pending[VI_PRIORITY])),
633 atomic_read(&(priv->tx_pending[VO_PRIORITY])),
634 atomic_read(&(priv->tx_pending[BE_PRIORITY])),
635 atomic_read(&(priv->tx_pending[BK_PRIORITY])),
636 // read_nic_byte(dev, TXFIFOCOUNT),
637 priv->stats.txvidrop,
638 priv->stats.txvodrop,
639 priv->stats.txbedrop,
640 priv->stats.txbkdrop,
641 priv->stats.txdatapkt
642 // priv->stats.txbeaconerr
645 *eof = 1;
646 return len;
651 static int proc_get_stats_rx(char *page, char **start,
652 off_t offset, int count,
653 int *eof, void *data)
655 struct net_device *dev = data;
656 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
658 int len = 0;
660 len += snprintf(page + len, count - len,
661 "RX packets: %lu\n"
662 "RX urb status error: %lu\n"
663 "RX invalid urb error: %lu\n",
664 priv->stats.rxoktotal,
665 priv->stats.rxstaterr,
666 priv->stats.rxurberr);
668 *eof = 1;
669 return len;
671 void rtl8192_proc_module_init(void)
673 RT_TRACE(COMP_INIT, "Initializing proc filesystem");
674 rtl8192_proc=create_proc_entry(RTL819xU_MODULE_NAME, S_IFDIR, init_net.proc_net);
678 void rtl8192_proc_module_remove(void)
680 remove_proc_entry(RTL819xU_MODULE_NAME, init_net.proc_net);
684 void rtl8192_proc_remove_one(struct net_device *dev)
686 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
689 if (priv->dir_dev) {
690 // remove_proc_entry("stats-hw", priv->dir_dev);
691 remove_proc_entry("stats-tx", priv->dir_dev);
692 remove_proc_entry("stats-rx", priv->dir_dev);
693 // remove_proc_entry("stats-ieee", priv->dir_dev);
694 remove_proc_entry("stats-ap", priv->dir_dev);
695 remove_proc_entry("registers", priv->dir_dev);
696 // remove_proc_entry("cck-registers",priv->dir_dev);
697 // remove_proc_entry("ofdm-registers",priv->dir_dev);
698 //remove_proc_entry(dev->name, rtl8192_proc);
699 remove_proc_entry("wlan0", rtl8192_proc);
700 priv->dir_dev = NULL;
705 void rtl8192_proc_init_one(struct net_device *dev)
707 struct proc_dir_entry *e;
708 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
709 priv->dir_dev = create_proc_entry(dev->name,
710 S_IFDIR | S_IRUGO | S_IXUGO,
711 rtl8192_proc);
712 if (!priv->dir_dev) {
713 RT_TRACE(COMP_ERR, "Unable to initialize /proc/net/rtl8192/%s\n",
714 dev->name);
715 return;
717 e = create_proc_read_entry("stats-rx", S_IFREG | S_IRUGO,
718 priv->dir_dev, proc_get_stats_rx, dev);
720 if (!e) {
721 RT_TRACE(COMP_ERR,"Unable to initialize "
722 "/proc/net/rtl8192/%s/stats-rx\n",
723 dev->name);
727 e = create_proc_read_entry("stats-tx", S_IFREG | S_IRUGO,
728 priv->dir_dev, proc_get_stats_tx, dev);
730 if (!e) {
731 RT_TRACE(COMP_ERR, "Unable to initialize "
732 "/proc/net/rtl8192/%s/stats-tx\n",
733 dev->name);
736 e = create_proc_read_entry("stats-ap", S_IFREG | S_IRUGO,
737 priv->dir_dev, proc_get_stats_ap, dev);
739 if (!e) {
740 RT_TRACE(COMP_ERR, "Unable to initialize "
741 "/proc/net/rtl8192/%s/stats-ap\n",
742 dev->name);
745 e = create_proc_read_entry("registers", S_IFREG | S_IRUGO,
746 priv->dir_dev, proc_get_registers, dev);
747 if (!e) {
748 RT_TRACE(COMP_ERR, "Unable to initialize "
749 "/proc/net/rtl8192/%s/registers\n",
750 dev->name);
753 /****************************************************************************
754 -----------------------------MISC STUFF-------------------------
755 *****************************************************************************/
757 /* this is only for debugging */
758 void print_buffer(u32 *buffer, int len)
760 int i;
761 u8 *buf =(u8*)buffer;
763 printk("ASCII BUFFER DUMP (len: %x):\n",len);
765 for(i=0;i<len;i++)
766 printk("%c",buf[i]);
768 printk("\nBINARY BUFFER DUMP (len: %x):\n",len);
770 for(i=0;i<len;i++)
771 printk("%x",buf[i]);
773 printk("\n");
776 //short check_nic_enough_desc(struct net_device *dev, priority_t priority)
777 short check_nic_enough_desc(struct net_device *dev,int queue_index)
779 struct r8192_priv *priv = ieee80211_priv(dev);
780 int used = atomic_read(&priv->tx_pending[queue_index]);
782 return (used < MAX_TX_URB);
785 void tx_timeout(struct net_device *dev)
787 struct r8192_priv *priv = ieee80211_priv(dev);
788 //rtl8192_commit(dev);
790 schedule_work(&priv->reset_wq);
791 //DMESG("TXTIMEOUT");
795 /* this is only for debug */
796 void dump_eprom(struct net_device *dev)
798 int i;
799 for(i=0; i<63; i++)
800 RT_TRACE(COMP_EPROM, "EEPROM addr %x : %x", i, eprom_read(dev,i));
803 /* this is only for debug */
804 void rtl8192_dump_reg(struct net_device *dev)
806 int i;
807 int n;
808 int max=0x1ff;
810 RT_TRACE(COMP_PHY, "Dumping NIC register map");
812 for(n=0;n<=max;)
814 printk( "\nD: %2x> ", n);
815 for(i=0;i<16 && n<=max;i++,n++)
816 printk("%2x ",read_nic_byte(dev,n));
818 printk("\n");
821 /****************************************************************************
822 ------------------------------HW STUFF---------------------------
823 *****************************************************************************/
826 void rtl8192_set_mode(struct net_device *dev,int mode)
828 u8 ecmd;
829 ecmd=read_nic_byte(dev, EPROM_CMD);
830 ecmd=ecmd &~ EPROM_CMD_OPERATING_MODE_MASK;
831 ecmd=ecmd | (mode<<EPROM_CMD_OPERATING_MODE_SHIFT);
832 ecmd=ecmd &~ (1<<EPROM_CS_SHIFT);
833 ecmd=ecmd &~ (1<<EPROM_CK_SHIFT);
834 write_nic_byte(dev, EPROM_CMD, ecmd);
838 void rtl8192_update_msr(struct net_device *dev)
840 struct r8192_priv *priv = ieee80211_priv(dev);
841 u8 msr;
843 msr = read_nic_byte(dev, MSR);
844 msr &= ~ MSR_LINK_MASK;
846 /* do not change in link_state != WLAN_LINK_ASSOCIATED.
847 * msr must be updated if the state is ASSOCIATING.
848 * this is intentional and make sense for ad-hoc and
849 * master (see the create BSS/IBSS func)
851 if (priv->ieee80211->state == IEEE80211_LINKED){
853 if (priv->ieee80211->iw_mode == IW_MODE_INFRA)
854 msr |= (MSR_LINK_MANAGED<<MSR_LINK_SHIFT);
855 else if (priv->ieee80211->iw_mode == IW_MODE_ADHOC)
856 msr |= (MSR_LINK_ADHOC<<MSR_LINK_SHIFT);
857 else if (priv->ieee80211->iw_mode == IW_MODE_MASTER)
858 msr |= (MSR_LINK_MASTER<<MSR_LINK_SHIFT);
860 }else
861 msr |= (MSR_LINK_NONE<<MSR_LINK_SHIFT);
863 write_nic_byte(dev, MSR, msr);
866 void rtl8192_set_chan(struct net_device *dev,short ch)
868 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
869 // u32 tx;
870 RT_TRACE(COMP_CH, "=====>%s()====ch:%d\n", __FUNCTION__, ch);
871 priv->chan=ch;
873 /* this hack should avoid frame TX during channel setting*/
876 // tx = read_nic_dword(dev,TX_CONF);
877 // tx &= ~TX_LOOPBACK_MASK;
879 #ifndef LOOP_TEST
880 // write_nic_dword(dev,TX_CONF, tx |( TX_LOOPBACK_MAC<<TX_LOOPBACK_SHIFT));
882 //need to implement rf set channel here WB
884 if (priv->rf_set_chan)
885 priv->rf_set_chan(dev,priv->chan);
886 mdelay(10);
887 // write_nic_dword(dev,TX_CONF,tx | (TX_LOOPBACK_NONE<<TX_LOOPBACK_SHIFT));
888 #endif
891 static void rtl8192_rx_isr(struct urb *urb);
892 //static void rtl8192_rx_isr(struct urb *rx_urb);
894 u32 get_rxpacket_shiftbytes_819xusb(struct ieee80211_rx_stats *pstats)
897 #ifdef USB_RX_AGGREGATION_SUPPORT
898 if (pstats->bisrxaggrsubframe)
899 return (sizeof(rx_desc_819x_usb) + pstats->RxDrvInfoSize
900 + pstats->RxBufShift + 8);
901 else
902 #endif
903 return (sizeof(rx_desc_819x_usb) + pstats->RxDrvInfoSize
904 + pstats->RxBufShift);
907 static int rtl8192_rx_initiate(struct net_device*dev)
909 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
910 struct urb *entry;
911 struct sk_buff *skb;
912 struct rtl8192_rx_info *info;
914 /* nomal packet rx procedure */
915 while (skb_queue_len(&priv->rx_queue) < MAX_RX_URB) {
916 skb = __dev_alloc_skb(RX_URB_SIZE, GFP_KERNEL);
917 if (!skb)
918 break;
919 entry = usb_alloc_urb(0, GFP_KERNEL);
920 if (!entry) {
921 kfree_skb(skb);
922 break;
924 // printk("nomal packet IN request!\n");
925 usb_fill_bulk_urb(entry, priv->udev,
926 usb_rcvbulkpipe(priv->udev, 3), skb_tail_pointer(skb),
927 RX_URB_SIZE, rtl8192_rx_isr, skb);
928 info = (struct rtl8192_rx_info *) skb->cb;
929 info->urb = entry;
930 info->dev = dev;
931 info->out_pipe = 3; //denote rx normal packet queue
932 skb_queue_tail(&priv->rx_queue, skb);
933 usb_submit_urb(entry, GFP_KERNEL);
936 /* command packet rx procedure */
937 while (skb_queue_len(&priv->rx_queue) < MAX_RX_URB + 3) {
938 // printk("command packet IN request!\n");
939 skb = __dev_alloc_skb(RX_URB_SIZE ,GFP_KERNEL);
940 if (!skb)
941 break;
942 entry = usb_alloc_urb(0, GFP_KERNEL);
943 if (!entry) {
944 kfree_skb(skb);
945 break;
947 usb_fill_bulk_urb(entry, priv->udev,
948 usb_rcvbulkpipe(priv->udev, 9), skb_tail_pointer(skb),
949 RX_URB_SIZE, rtl8192_rx_isr, skb);
950 info = (struct rtl8192_rx_info *) skb->cb;
951 info->urb = entry;
952 info->dev = dev;
953 info->out_pipe = 9; //denote rx cmd packet queue
954 skb_queue_tail(&priv->rx_queue, skb);
955 usb_submit_urb(entry, GFP_KERNEL);
958 return 0;
961 void rtl8192_set_rxconf(struct net_device *dev)
963 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
964 u32 rxconf;
966 rxconf=read_nic_dword(dev,RCR);
967 rxconf = rxconf &~ MAC_FILTER_MASK;
968 rxconf = rxconf | RCR_AMF;
969 rxconf = rxconf | RCR_ADF;
970 rxconf = rxconf | RCR_AB;
971 rxconf = rxconf | RCR_AM;
972 //rxconf = rxconf | RCR_ACF;
974 if (dev->flags & IFF_PROMISC) {DMESG ("NIC in promisc mode");}
976 if(priv->ieee80211->iw_mode == IW_MODE_MONITOR || \
977 dev->flags & IFF_PROMISC){
978 rxconf = rxconf | RCR_AAP;
979 } /*else if(priv->ieee80211->iw_mode == IW_MODE_MASTER){
980 rxconf = rxconf | (1<<ACCEPT_ALLMAC_FRAME_SHIFT);
981 rxconf = rxconf | (1<<RX_CHECK_BSSID_SHIFT);
982 }*/else{
983 rxconf = rxconf | RCR_APM;
984 rxconf = rxconf | RCR_CBSSID;
988 if(priv->ieee80211->iw_mode == IW_MODE_MONITOR){
989 rxconf = rxconf | RCR_AICV;
990 rxconf = rxconf | RCR_APWRMGT;
993 if( priv->crcmon == 1 && priv->ieee80211->iw_mode == IW_MODE_MONITOR)
994 rxconf = rxconf | RCR_ACRC32;
997 rxconf = rxconf &~ RX_FIFO_THRESHOLD_MASK;
998 rxconf = rxconf | (RX_FIFO_THRESHOLD_NONE<<RX_FIFO_THRESHOLD_SHIFT);
999 rxconf = rxconf &~ MAX_RX_DMA_MASK;
1000 rxconf = rxconf | ((u32)7<<RCR_MXDMA_OFFSET);
1002 // rxconf = rxconf | (1<<RX_AUTORESETPHY_SHIFT);
1003 rxconf = rxconf | RCR_ONLYERLPKT;
1005 // rxconf = rxconf &~ RCR_CS_MASK;
1006 // rxconf = rxconf | (1<<RCR_CS_SHIFT);
1008 write_nic_dword(dev, RCR, rxconf);
1010 #ifdef DEBUG_RX
1011 DMESG("rxconf: %x %x",rxconf ,read_nic_dword(dev,RCR));
1012 #endif
1014 //wait to be removed
1015 void rtl8192_rx_enable(struct net_device *dev)
1017 //u8 cmd;
1019 //struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1021 rtl8192_rx_initiate(dev);
1023 // rtl8192_set_rxconf(dev);
1027 void rtl8192_tx_enable(struct net_device *dev)
1033 void rtl8192_rtx_disable(struct net_device *dev)
1035 u8 cmd;
1036 struct r8192_priv *priv = ieee80211_priv(dev);
1037 struct sk_buff *skb;
1038 struct rtl8192_rx_info *info;
1040 cmd=read_nic_byte(dev,CMDR);
1041 write_nic_byte(dev, CMDR, cmd &~ \
1042 (CR_TE|CR_RE));
1043 force_pci_posting(dev);
1044 mdelay(10);
1046 while ((skb = __skb_dequeue(&priv->rx_queue))) {
1047 info = (struct rtl8192_rx_info *) skb->cb;
1048 if (!info->urb)
1049 continue;
1051 usb_kill_urb(info->urb);
1052 kfree_skb(skb);
1055 if (skb_queue_len(&priv->skb_queue)) {
1056 printk(KERN_WARNING "skb_queue not empty\n");
1059 skb_queue_purge(&priv->skb_queue);
1060 return;
1064 int alloc_tx_beacon_desc_ring(struct net_device *dev, int count)
1066 return 0;
1069 inline u16 ieeerate2rtlrate(int rate)
1071 switch(rate){
1072 case 10:
1073 return 0;
1074 case 20:
1075 return 1;
1076 case 55:
1077 return 2;
1078 case 110:
1079 return 3;
1080 case 60:
1081 return 4;
1082 case 90:
1083 return 5;
1084 case 120:
1085 return 6;
1086 case 180:
1087 return 7;
1088 case 240:
1089 return 8;
1090 case 360:
1091 return 9;
1092 case 480:
1093 return 10;
1094 case 540:
1095 return 11;
1096 default:
1097 return 3;
1101 static u16 rtl_rate[] = {10,20,55,110,60,90,120,180,240,360,480,540};
1102 inline u16 rtl8192_rate2rate(short rate)
1104 if (rate >11) return 0;
1105 return rtl_rate[rate];
1109 /* The protype of rx_isr has changed since one verion of Linux Kernel */
1110 static void rtl8192_rx_isr(struct urb *urb)
1112 struct sk_buff *skb = (struct sk_buff *) urb->context;
1113 struct rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
1114 struct net_device *dev = info->dev;
1115 struct r8192_priv *priv = ieee80211_priv(dev);
1116 int out_pipe = info->out_pipe;
1117 int err;
1118 if(!priv->up)
1119 return;
1120 if (unlikely(urb->status)) {
1121 info->urb = NULL;
1122 priv->stats.rxstaterr++;
1123 priv->ieee80211->stats.rx_errors++;
1124 usb_free_urb(urb);
1125 // printk("%s():rx status err\n",__FUNCTION__);
1126 return;
1128 skb_unlink(skb, &priv->rx_queue);
1129 skb_put(skb, urb->actual_length);
1131 skb_queue_tail(&priv->skb_queue, skb);
1132 tasklet_schedule(&priv->irq_rx_tasklet);
1134 skb = dev_alloc_skb(RX_URB_SIZE);
1135 if (unlikely(!skb)) {
1136 usb_free_urb(urb);
1137 printk("%s():can,t alloc skb\n",__FUNCTION__);
1138 /* TODO check rx queue length and refill *somewhere* */
1139 return;
1142 usb_fill_bulk_urb(urb, priv->udev,
1143 usb_rcvbulkpipe(priv->udev, out_pipe), skb_tail_pointer(skb),
1144 RX_URB_SIZE, rtl8192_rx_isr, skb);
1146 info = (struct rtl8192_rx_info *) skb->cb;
1147 info->urb = urb;
1148 info->dev = dev;
1149 info->out_pipe = out_pipe;
1151 urb->transfer_buffer = skb_tail_pointer(skb);
1152 urb->context = skb;
1153 skb_queue_tail(&priv->rx_queue, skb);
1154 err = usb_submit_urb(urb, GFP_ATOMIC);
1155 if(err && err != EPERM)
1156 printk("can not submit rxurb, err is %x,URB status is %x\n",err,urb->status);
1160 rtl819xusb_rx_command_packet(
1161 struct net_device *dev,
1162 struct ieee80211_rx_stats *pstats
1165 u32 status;
1167 //RT_TRACE(COMP_RECV, DBG_TRACE, ("---> RxCommandPacketHandle819xUsb()\n"));
1169 status = cmpk_message_handle_rx(dev, pstats);
1170 if (status)
1172 DMESG("rxcommandpackethandle819xusb: It is a command packet\n");
1174 else
1176 //RT_TRACE(COMP_RECV, DBG_TRACE, ("RxCommandPacketHandle819xUsb: It is not a command packet\n"));
1179 //RT_TRACE(COMP_RECV, DBG_TRACE, ("<--- RxCommandPacketHandle819xUsb()\n"));
1180 return status;
1184 void rtl8192_data_hard_stop(struct net_device *dev)
1186 //FIXME !!
1190 void rtl8192_data_hard_resume(struct net_device *dev)
1192 // FIXME !!
1195 /* this function TX data frames when the ieee80211 stack requires this.
1196 * It checks also if we need to stop the ieee tx queue, eventually do it
1198 void rtl8192_hard_data_xmit(struct sk_buff *skb, struct net_device *dev, int rate)
1200 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1201 int ret;
1202 unsigned long flags;
1203 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1204 u8 queue_index = tcb_desc->queue_index;
1206 /* shall not be referred by command packet */
1207 assert(queue_index != TXCMD_QUEUE);
1209 spin_lock_irqsave(&priv->tx_lock,flags);
1211 memcpy((unsigned char *)(skb->cb),&dev,sizeof(dev));
1212 // tcb_desc->RATRIndex = 7;
1213 // tcb_desc->bTxDisableRateFallBack = 1;
1214 // tcb_desc->bTxUseDriverAssingedRate = 1;
1215 tcb_desc->bTxEnableFwCalcDur = 1;
1216 skb_push(skb, priv->ieee80211->tx_headroom);
1217 ret = rtl8192_tx(dev, skb);
1219 //priv->ieee80211->stats.tx_bytes+=(skb->len - priv->ieee80211->tx_headroom);
1220 //priv->ieee80211->stats.tx_packets++;
1222 spin_unlock_irqrestore(&priv->tx_lock,flags);
1224 // return ret;
1225 return;
1228 /* This is a rough attempt to TX a frame
1229 * This is called by the ieee 80211 stack to TX management frames.
1230 * If the ring is full packet are dropped (for data frame the queue
1231 * is stopped before this can happen).
1233 int rtl8192_hard_start_xmit(struct sk_buff *skb,struct net_device *dev)
1235 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1236 int ret;
1237 unsigned long flags;
1238 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1239 u8 queue_index = tcb_desc->queue_index;
1242 spin_lock_irqsave(&priv->tx_lock,flags);
1244 memcpy((unsigned char *)(skb->cb),&dev,sizeof(dev));
1245 if(queue_index == TXCMD_QUEUE) {
1246 skb_push(skb, USB_HWDESC_HEADER_LEN);
1247 rtl819xU_tx_cmd(dev, skb);
1248 ret = 1;
1249 spin_unlock_irqrestore(&priv->tx_lock,flags);
1250 return ret;
1251 } else {
1252 skb_push(skb, priv->ieee80211->tx_headroom);
1253 ret = rtl8192_tx(dev, skb);
1256 spin_unlock_irqrestore(&priv->tx_lock,flags);
1258 return ret;
1262 void rtl8192_try_wake_queue(struct net_device *dev, int pri);
1264 #ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
1265 u16 DrvAggr_PaddingAdd(struct net_device *dev, struct sk_buff *skb)
1267 u16 PaddingNum = 256 - ((skb->len + TX_PACKET_DRVAGGR_SUBFRAME_SHIFT_BYTES) % 256);
1268 return (PaddingNum&0xff);
1271 u8 MRateToHwRate8190Pci(u8 rate);
1272 u8 QueryIsShort(u8 TxHT, u8 TxRate, cb_desc *tcb_desc);
1273 u8 MapHwQueueToFirmwareQueue(u8 QueueID);
1274 struct sk_buff *DrvAggr_Aggregation(struct net_device *dev, struct ieee80211_drv_agg_txb *pSendList)
1276 struct ieee80211_device *ieee = netdev_priv(dev);
1277 struct r8192_priv *priv = ieee80211_priv(dev);
1278 cb_desc *tcb_desc = NULL;
1279 u8 i;
1280 u32 TotalLength;
1281 struct sk_buff *skb;
1282 struct sk_buff *agg_skb;
1283 tx_desc_819x_usb_aggr_subframe *tx_agg_desc = NULL;
1284 tx_fwinfo_819x_usb *tx_fwinfo = NULL;
1287 // Local variable initialization.
1289 /* first skb initialization */
1290 skb = pSendList->tx_agg_frames[0];
1291 TotalLength = skb->len;
1293 /* Get the total aggregation length including the padding space and
1294 * sub frame header.
1296 for(i = 1; i < pSendList->nr_drv_agg_frames; i++) {
1297 TotalLength += DrvAggr_PaddingAdd(dev, skb);
1298 skb = pSendList->tx_agg_frames[i];
1299 TotalLength += (skb->len + TX_PACKET_DRVAGGR_SUBFRAME_SHIFT_BYTES);
1302 /* allocate skb to contain the aggregated packets */
1303 agg_skb = dev_alloc_skb(TotalLength + ieee->tx_headroom);
1304 memset(agg_skb->data, 0, agg_skb->len);
1305 skb_reserve(agg_skb, ieee->tx_headroom);
1307 // RT_DEBUG_DATA(COMP_SEND, skb->cb, sizeof(skb->cb));
1308 /* reserve info for first subframe Tx descriptor to be set in the tx function */
1309 skb = pSendList->tx_agg_frames[0];
1310 tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1311 tcb_desc->drv_agg_enable = 1;
1312 tcb_desc->pkt_size = skb->len;
1313 tcb_desc->DrvAggrNum = pSendList->nr_drv_agg_frames;
1314 printk("DrvAggNum = %d\n", tcb_desc->DrvAggrNum);
1315 // RT_DEBUG_DATA(COMP_SEND, skb->cb, sizeof(skb->cb));
1316 // printk("========>skb->data ======> \n");
1317 // RT_DEBUG_DATA(COMP_SEND, skb->data, skb->len);
1318 memcpy(agg_skb->cb, skb->cb, sizeof(skb->cb));
1319 memcpy(skb_put(agg_skb,skb->len),skb->data,skb->len);
1321 for(i = 1; i < pSendList->nr_drv_agg_frames; i++) {
1322 /* push the next sub frame to be 256 byte aline */
1323 skb_put(agg_skb,DrvAggr_PaddingAdd(dev,skb));
1325 /* Subframe drv Tx descriptor and firmware info setting */
1326 skb = pSendList->tx_agg_frames[i];
1327 tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1328 tx_agg_desc = (tx_desc_819x_usb_aggr_subframe *)agg_skb->tail;
1329 tx_fwinfo = (tx_fwinfo_819x_usb *)(agg_skb->tail + sizeof(tx_desc_819x_usb_aggr_subframe));
1331 memset(tx_fwinfo,0,sizeof(tx_fwinfo_819x_usb));
1332 /* DWORD 0 */
1333 tx_fwinfo->TxHT = (tcb_desc->data_rate&0x80)?1:0;
1334 tx_fwinfo->TxRate = MRateToHwRate8190Pci(tcb_desc->data_rate);
1335 tx_fwinfo->EnableCPUDur = tcb_desc->bTxEnableFwCalcDur;
1336 tx_fwinfo->Short = QueryIsShort(tx_fwinfo->TxHT, tx_fwinfo->TxRate, tcb_desc);
1337 if(tcb_desc->bAMPDUEnable) {//AMPDU enabled
1338 tx_fwinfo->AllowAggregation = 1;
1339 /* DWORD 1 */
1340 tx_fwinfo->RxMF = tcb_desc->ampdu_factor;
1341 tx_fwinfo->RxAMD = tcb_desc->ampdu_density&0x07;//ampdudensity
1342 } else {
1343 tx_fwinfo->AllowAggregation = 0;
1344 /* DWORD 1 */
1345 tx_fwinfo->RxMF = 0;
1346 tx_fwinfo->RxAMD = 0;
1349 /* Protection mode related */
1350 tx_fwinfo->RtsEnable = (tcb_desc->bRTSEnable)?1:0;
1351 tx_fwinfo->CtsEnable = (tcb_desc->bCTSEnable)?1:0;
1352 tx_fwinfo->RtsSTBC = (tcb_desc->bRTSSTBC)?1:0;
1353 tx_fwinfo->RtsHT = (tcb_desc->rts_rate&0x80)?1:0;
1354 tx_fwinfo->RtsRate = MRateToHwRate8190Pci((u8)tcb_desc->rts_rate);
1355 tx_fwinfo->RtsSubcarrier = (tx_fwinfo->RtsHT==0)?(tcb_desc->RTSSC):0;
1356 tx_fwinfo->RtsBandwidth = (tx_fwinfo->RtsHT==1)?((tcb_desc->bRTSBW)?1:0):0;
1357 tx_fwinfo->RtsShort = (tx_fwinfo->RtsHT==0)?(tcb_desc->bRTSUseShortPreamble?1:0):\
1358 (tcb_desc->bRTSUseShortGI?1:0);
1360 /* Set Bandwidth and sub-channel settings. */
1361 if(priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20_40)
1363 if(tcb_desc->bPacketBW) {
1364 tx_fwinfo->TxBandwidth = 1;
1365 tx_fwinfo->TxSubCarrier = 0; //By SD3's Jerry suggestion, use duplicated mode
1366 } else {
1367 tx_fwinfo->TxBandwidth = 0;
1368 tx_fwinfo->TxSubCarrier = priv->nCur40MhzPrimeSC;
1370 } else {
1371 tx_fwinfo->TxBandwidth = 0;
1372 tx_fwinfo->TxSubCarrier = 0;
1375 /* Fill Tx descriptor */
1376 memset(tx_agg_desc, 0, sizeof(tx_desc_819x_usb_aggr_subframe));
1377 /* DWORD 0 */
1378 //tx_agg_desc->LINIP = 0;
1379 //tx_agg_desc->CmdInit = 1;
1380 tx_agg_desc->Offset = sizeof(tx_fwinfo_819x_usb) + 8;
1381 /* already raw data, need not to subtract header length */
1382 tx_agg_desc->PktSize = skb->len & 0xffff;
1384 /*DWORD 1*/
1385 tx_agg_desc->SecCAMID= 0;
1386 tx_agg_desc->RATid = tcb_desc->RATRIndex;
1388 //MPDUOverhead = 0;
1389 tx_agg_desc->NoEnc = 1;
1391 tx_agg_desc->SecType = 0x0;
1393 if (tcb_desc->bHwSec) {
1394 switch (priv->ieee80211->pairwise_key_type)
1396 case KEY_TYPE_WEP40:
1397 case KEY_TYPE_WEP104:
1398 tx_agg_desc->SecType = 0x1;
1399 tx_agg_desc->NoEnc = 0;
1400 break;
1401 case KEY_TYPE_TKIP:
1402 tx_agg_desc->SecType = 0x2;
1403 tx_agg_desc->NoEnc = 0;
1404 break;
1405 case KEY_TYPE_CCMP:
1406 tx_agg_desc->SecType = 0x3;
1407 tx_agg_desc->NoEnc = 0;
1408 break;
1409 case KEY_TYPE_NA:
1410 tx_agg_desc->SecType = 0x0;
1411 tx_agg_desc->NoEnc = 1;
1412 break;
1416 tx_agg_desc->QueueSelect = MapHwQueueToFirmwareQueue(tcb_desc->queue_index);
1417 tx_agg_desc->TxFWInfoSize = sizeof(tx_fwinfo_819x_usb);
1419 tx_agg_desc->DISFB = tcb_desc->bTxDisableRateFallBack;
1420 tx_agg_desc->USERATE = tcb_desc->bTxUseDriverAssingedRate;
1422 tx_agg_desc->OWN = 1;
1424 //DWORD 2
1425 /* According windows driver, it seems that there no need to fill this field */
1426 //tx_agg_desc->TxBufferSize= (u32)(skb->len - USB_HWDESC_HEADER_LEN);
1428 /* to fill next packet */
1429 skb_put(agg_skb,TX_PACKET_DRVAGGR_SUBFRAME_SHIFT_BYTES);
1430 memcpy(skb_put(agg_skb,skb->len),skb->data,skb->len);
1433 for(i = 0; i < pSendList->nr_drv_agg_frames; i++) {
1434 dev_kfree_skb_any(pSendList->tx_agg_frames[i]);
1437 return agg_skb;
1440 /* NOTE:
1441 This function return a list of PTCB which is proper to be aggregate with the input TCB.
1442 If no proper TCB is found to do aggregation, SendList will only contain the input TCB.
1444 u8 DrvAggr_GetAggregatibleList(struct net_device *dev, struct sk_buff *skb,
1445 struct ieee80211_drv_agg_txb *pSendList)
1447 struct ieee80211_device *ieee = netdev_priv(dev);
1448 PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
1449 u16 nMaxAggrNum = pHTInfo->UsbTxAggrNum;
1450 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1451 u8 QueueID = tcb_desc->queue_index;
1453 do {
1454 pSendList->tx_agg_frames[pSendList->nr_drv_agg_frames++] = skb;
1455 if(pSendList->nr_drv_agg_frames >= nMaxAggrNum) {
1456 break;
1459 } while((skb = skb_dequeue(&ieee->skb_drv_aggQ[QueueID])));
1461 RT_TRACE(COMP_AMSDU, "DrvAggr_GetAggregatibleList, nAggrTcbNum = %d \n", pSendList->nr_drv_agg_frames);
1462 return pSendList->nr_drv_agg_frames;
1464 #endif
1466 static void rtl8192_tx_isr(struct urb *tx_urb)
1468 struct sk_buff *skb = (struct sk_buff*)tx_urb->context;
1469 struct net_device *dev = NULL;
1470 struct r8192_priv *priv = NULL;
1471 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1472 u8 queue_index = tcb_desc->queue_index;
1473 // bool bToSend0Byte;
1474 // u16 BufLen = skb->len;
1476 memcpy(&dev,(struct net_device*)(skb->cb),sizeof(struct net_device*));
1477 priv = ieee80211_priv(dev);
1479 if(tcb_desc->queue_index != TXCMD_QUEUE) {
1480 if(tx_urb->status == 0) {
1481 dev->trans_start = jiffies;
1482 // As act as station mode, destion shall be unicast address.
1483 //priv->ieee80211->stats.tx_bytes+=(skb->len - priv->ieee80211->tx_headroom);
1484 //priv->ieee80211->stats.tx_packets++;
1485 priv->stats.txoktotal++;
1486 priv->ieee80211->LinkDetectInfo.NumTxOkInPeriod++;
1487 priv->stats.txbytesunicast += (skb->len - priv->ieee80211->tx_headroom);
1488 } else {
1489 priv->ieee80211->stats.tx_errors++;
1490 //priv->stats.txmanageerr++;
1491 /* TODO */
1495 /* free skb and tx_urb */
1496 if(skb != NULL) {
1497 dev_kfree_skb_any(skb);
1498 usb_free_urb(tx_urb);
1499 atomic_dec(&priv->tx_pending[queue_index]);
1504 // Handle HW Beacon:
1505 // We had transfer our beacon frame to host controller at this moment.
1508 // Caution:
1509 // Handling the wait queue of command packets.
1510 // For Tx command packets, we must not do TCB fragment because it is not handled right now.
1511 // We must cut the packets to match the size of TX_CMD_PKT before we send it.
1514 /* Handle MPDU in wait queue. */
1515 if(queue_index != BEACON_QUEUE) {
1516 /* Don't send data frame during scanning.*/
1517 if((skb_queue_len(&priv->ieee80211->skb_waitQ[queue_index]) != 0)&&\
1518 (!(priv->ieee80211->queue_stop))) {
1519 if(NULL != (skb = skb_dequeue(&(priv->ieee80211->skb_waitQ[queue_index]))))
1520 priv->ieee80211->softmac_hard_start_xmit(skb, dev);
1522 return; //modified by david to avoid further processing AMSDU
1524 #ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
1525 else if ((skb_queue_len(&priv->ieee80211->skb_drv_aggQ[queue_index])!= 0)&&\
1526 (!(priv->ieee80211->queue_stop))) {
1527 // Tx Driver Aggregation process
1528 /* The driver will aggregation the packets according to the following stets
1529 * 1. check whether there's tx irq available, for it's a completion return
1530 * function, it should contain enough tx irq;
1531 * 2. check pakcet type;
1532 * 3. initialize sendlist, check whether the to-be send packet no greater than 1
1533 * 4. aggregation the packets, and fill firmware info and tx desc to it, etc.
1534 * 5. check whehter the packet could be sent, otherwise just insert to wait head
1535 * */
1536 skb = skb_dequeue(&priv->ieee80211->skb_drv_aggQ[queue_index]);
1537 if(!check_nic_enough_desc(dev, queue_index)) {
1538 skb_queue_head(&(priv->ieee80211->skb_drv_aggQ[queue_index]), skb);
1539 return;
1543 /*TODO*/
1545 u8* pHeader = skb->data;
1547 if(IsMgntQosData(pHeader) ||
1548 IsMgntQData_Ack(pHeader) ||
1549 IsMgntQData_Poll(pHeader) ||
1550 IsMgntQData_Poll_Ack(pHeader)
1554 struct ieee80211_drv_agg_txb SendList;
1556 memset(&SendList, 0, sizeof(struct ieee80211_drv_agg_txb));
1557 if(DrvAggr_GetAggregatibleList(dev, skb, &SendList) > 1) {
1558 skb = DrvAggr_Aggregation(dev, &SendList);
1562 priv->ieee80211->softmac_hard_start_xmit(skb, dev);
1565 #endif
1571 void rtl8192_beacon_stop(struct net_device *dev)
1573 u8 msr, msrm, msr2;
1574 struct r8192_priv *priv = ieee80211_priv(dev);
1576 msr = read_nic_byte(dev, MSR);
1577 msrm = msr & MSR_LINK_MASK;
1578 msr2 = msr & ~MSR_LINK_MASK;
1580 if(NIC_8192U == priv->card_8192) {
1581 usb_kill_urb(priv->rx_urb[MAX_RX_URB]);
1583 if ((msrm == (MSR_LINK_ADHOC<<MSR_LINK_SHIFT) ||
1584 (msrm == (MSR_LINK_MASTER<<MSR_LINK_SHIFT)))){
1585 write_nic_byte(dev, MSR, msr2 | MSR_LINK_NONE);
1586 write_nic_byte(dev, MSR, msr);
1590 void rtl8192_config_rate(struct net_device* dev, u16* rate_config)
1592 struct r8192_priv *priv = ieee80211_priv(dev);
1593 struct ieee80211_network *net;
1594 u8 i=0, basic_rate = 0;
1595 net = & priv->ieee80211->current_network;
1597 for (i=0; i<net->rates_len; i++)
1599 basic_rate = net->rates[i]&0x7f;
1600 switch(basic_rate)
1602 case MGN_1M: *rate_config |= RRSR_1M; break;
1603 case MGN_2M: *rate_config |= RRSR_2M; break;
1604 case MGN_5_5M: *rate_config |= RRSR_5_5M; break;
1605 case MGN_11M: *rate_config |= RRSR_11M; break;
1606 case MGN_6M: *rate_config |= RRSR_6M; break;
1607 case MGN_9M: *rate_config |= RRSR_9M; break;
1608 case MGN_12M: *rate_config |= RRSR_12M; break;
1609 case MGN_18M: *rate_config |= RRSR_18M; break;
1610 case MGN_24M: *rate_config |= RRSR_24M; break;
1611 case MGN_36M: *rate_config |= RRSR_36M; break;
1612 case MGN_48M: *rate_config |= RRSR_48M; break;
1613 case MGN_54M: *rate_config |= RRSR_54M; break;
1616 for (i=0; i<net->rates_ex_len; i++)
1618 basic_rate = net->rates_ex[i]&0x7f;
1619 switch(basic_rate)
1621 case MGN_1M: *rate_config |= RRSR_1M; break;
1622 case MGN_2M: *rate_config |= RRSR_2M; break;
1623 case MGN_5_5M: *rate_config |= RRSR_5_5M; break;
1624 case MGN_11M: *rate_config |= RRSR_11M; break;
1625 case MGN_6M: *rate_config |= RRSR_6M; break;
1626 case MGN_9M: *rate_config |= RRSR_9M; break;
1627 case MGN_12M: *rate_config |= RRSR_12M; break;
1628 case MGN_18M: *rate_config |= RRSR_18M; break;
1629 case MGN_24M: *rate_config |= RRSR_24M; break;
1630 case MGN_36M: *rate_config |= RRSR_36M; break;
1631 case MGN_48M: *rate_config |= RRSR_48M; break;
1632 case MGN_54M: *rate_config |= RRSR_54M; break;
1638 #define SHORT_SLOT_TIME 9
1639 #define NON_SHORT_SLOT_TIME 20
1641 void rtl8192_update_cap(struct net_device* dev, u16 cap)
1643 u32 tmp = 0;
1644 struct r8192_priv *priv = ieee80211_priv(dev);
1645 struct ieee80211_network *net = &priv->ieee80211->current_network;
1646 priv->short_preamble = cap & WLAN_CAPABILITY_SHORT_PREAMBLE;
1647 tmp = priv->basic_rate;
1648 if (priv->short_preamble)
1649 tmp |= BRSR_AckShortPmb;
1650 write_nic_dword(dev, RRSR, tmp);
1652 if (net->mode & (IEEE_G|IEEE_N_24G))
1654 u8 slot_time = 0;
1655 if ((cap & WLAN_CAPABILITY_SHORT_SLOT)&&(!priv->ieee80211->pHTInfo->bCurrentRT2RTLongSlotTime))
1656 {//short slot time
1657 slot_time = SHORT_SLOT_TIME;
1659 else //long slot time
1660 slot_time = NON_SHORT_SLOT_TIME;
1661 priv->slot_time = slot_time;
1662 write_nic_byte(dev, SLOT_TIME, slot_time);
1666 void rtl8192_net_update(struct net_device *dev)
1669 struct r8192_priv *priv = ieee80211_priv(dev);
1670 struct ieee80211_network *net;
1671 u16 BcnTimeCfg = 0, BcnCW = 6, BcnIFS = 0xf;
1672 u16 rate_config = 0;
1673 net = & priv->ieee80211->current_network;
1675 rtl8192_config_rate(dev, &rate_config);
1676 priv->basic_rate = rate_config &= 0x15f;
1678 write_nic_dword(dev,BSSIDR,((u32*)net->bssid)[0]);
1679 write_nic_word(dev,BSSIDR+4,((u16*)net->bssid)[2]);
1680 //for(i=0;i<ETH_ALEN;i++)
1681 // write_nic_byte(dev,BSSID+i,net->bssid[i]);
1683 rtl8192_update_msr(dev);
1684 // rtl8192_update_cap(dev, net->capability);
1685 if (priv->ieee80211->iw_mode == IW_MODE_ADHOC)
1687 write_nic_word(dev, ATIMWND, 2);
1688 write_nic_word(dev, BCN_DMATIME, 1023);
1689 write_nic_word(dev, BCN_INTERVAL, net->beacon_interval);
1690 // write_nic_word(dev, BcnIntTime, 100);
1691 write_nic_word(dev, BCN_DRV_EARLY_INT, 1);
1692 write_nic_byte(dev, BCN_ERR_THRESH, 100);
1693 BcnTimeCfg |= (BcnCW<<BCN_TCFG_CW_SHIFT);
1694 // TODO: BcnIFS may required to be changed on ASIC
1695 BcnTimeCfg |= BcnIFS<<BCN_TCFG_IFS;
1697 write_nic_word(dev, BCN_TCFG, BcnTimeCfg);
1704 //temporary hw beacon is not used any more.
1705 //open it when necessary
1706 void rtl819xusb_beacon_tx(struct net_device *dev,u16 tx_rate)
1710 inline u8 rtl8192_IsWirelessBMode(u16 rate)
1712 if( ((rate <= 110) && (rate != 60) && (rate != 90)) || (rate == 220) )
1713 return 1;
1714 else return 0;
1717 u16 N_DBPSOfRate(u16 DataRate);
1719 u16 ComputeTxTime(
1720 u16 FrameLength,
1721 u16 DataRate,
1722 u8 bManagementFrame,
1723 u8 bShortPreamble
1726 u16 FrameTime;
1727 u16 N_DBPS;
1728 u16 Ceiling;
1730 if( rtl8192_IsWirelessBMode(DataRate) )
1732 if( bManagementFrame || !bShortPreamble || DataRate == 10 )
1733 { // long preamble
1734 FrameTime = (u16)(144+48+(FrameLength*8/(DataRate/10)));
1736 else
1737 { // Short preamble
1738 FrameTime = (u16)(72+24+(FrameLength*8/(DataRate/10)));
1740 if( ( FrameLength*8 % (DataRate/10) ) != 0 ) //Get the Ceilling
1741 FrameTime ++;
1742 } else { //802.11g DSSS-OFDM PLCP length field calculation.
1743 N_DBPS = N_DBPSOfRate(DataRate);
1744 Ceiling = (16 + 8*FrameLength + 6) / N_DBPS
1745 + (((16 + 8*FrameLength + 6) % N_DBPS) ? 1 : 0);
1746 FrameTime = (u16)(16 + 4 + 4*Ceiling + 6);
1748 return FrameTime;
1751 u16 N_DBPSOfRate(u16 DataRate)
1753 u16 N_DBPS = 24;
1755 switch(DataRate)
1757 case 60:
1758 N_DBPS = 24;
1759 break;
1761 case 90:
1762 N_DBPS = 36;
1763 break;
1765 case 120:
1766 N_DBPS = 48;
1767 break;
1769 case 180:
1770 N_DBPS = 72;
1771 break;
1773 case 240:
1774 N_DBPS = 96;
1775 break;
1777 case 360:
1778 N_DBPS = 144;
1779 break;
1781 case 480:
1782 N_DBPS = 192;
1783 break;
1785 case 540:
1786 N_DBPS = 216;
1787 break;
1789 default:
1790 break;
1793 return N_DBPS;
1796 void rtl819xU_cmd_isr(struct urb *tx_cmd_urb, struct pt_regs *regs)
1798 usb_free_urb(tx_cmd_urb);
1801 unsigned int txqueue2outpipe(struct r8192_priv* priv,unsigned int tx_queue) {
1803 if(tx_queue >= 9)
1805 RT_TRACE(COMP_ERR,"%s():Unknown queue ID!!!\n",__FUNCTION__);
1806 return 0x04;
1808 return priv->txqueue_to_outpipemap[tx_queue];
1811 short rtl819xU_tx_cmd(struct net_device *dev, struct sk_buff *skb)
1813 struct r8192_priv *priv = ieee80211_priv(dev);
1814 //u8 *tx;
1815 int status;
1816 struct urb *tx_urb;
1817 //int urb_buf_len;
1818 unsigned int idx_pipe;
1819 tx_desc_cmd_819x_usb *pdesc = (tx_desc_cmd_819x_usb *)skb->data;
1820 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1821 u8 queue_index = tcb_desc->queue_index;
1823 //printk("\n %s::queue_index = %d\n",__FUNCTION__, queue_index);
1824 atomic_inc(&priv->tx_pending[queue_index]);
1825 tx_urb = usb_alloc_urb(0,GFP_ATOMIC);
1826 if(!tx_urb){
1827 dev_kfree_skb(skb);
1828 return -ENOMEM;
1831 memset(pdesc, 0, USB_HWDESC_HEADER_LEN);
1832 /* Tx descriptor ought to be set according to the skb->cb */
1833 pdesc->FirstSeg = 1;//bFirstSeg;
1834 pdesc->LastSeg = 1;//bLastSeg;
1835 pdesc->CmdInit = tcb_desc->bCmdOrInit;
1836 pdesc->TxBufferSize = tcb_desc->txbuf_size;
1837 pdesc->OWN = 1;
1838 pdesc->LINIP = tcb_desc->bLastIniPkt;
1840 //----------------------------------------------------------------------------
1841 // Fill up USB_OUT_CONTEXT.
1842 //----------------------------------------------------------------------------
1843 // Get index to out pipe from specified QueueID.
1844 #ifndef USE_ONE_PIPE
1845 idx_pipe = txqueue2outpipe(priv,queue_index);
1846 #else
1847 idx_pipe = 0x04;
1848 #endif
1849 #ifdef JOHN_DUMP_TXDESC
1850 int i;
1851 printk("<Tx descriptor>--rate %x---",rate);
1852 for (i = 0; i < 8; i++)
1853 printk("%8x ", tx[i]);
1854 printk("\n");
1855 #endif
1856 usb_fill_bulk_urb(tx_urb,priv->udev, usb_sndbulkpipe(priv->udev,idx_pipe), \
1857 skb->data, skb->len, rtl8192_tx_isr, skb);
1859 status = usb_submit_urb(tx_urb, GFP_ATOMIC);
1861 if (!status){
1862 return 0;
1863 }else{
1864 DMESGE("Error TX CMD URB, error %d",
1865 status);
1866 return -1;
1871 * Mapping Software/Hardware descriptor queue id to "Queue Select Field"
1872 * in TxFwInfo data structure
1873 * 2006.10.30 by Emily
1875 * \param QUEUEID Software Queue
1877 u8 MapHwQueueToFirmwareQueue(u8 QueueID)
1879 u8 QueueSelect = 0x0; //defualt set to
1881 switch(QueueID) {
1882 case BE_QUEUE:
1883 QueueSelect = QSLT_BE; //or QSelect = pTcb->priority;
1884 break;
1886 case BK_QUEUE:
1887 QueueSelect = QSLT_BK; //or QSelect = pTcb->priority;
1888 break;
1890 case VO_QUEUE:
1891 QueueSelect = QSLT_VO; //or QSelect = pTcb->priority;
1892 break;
1894 case VI_QUEUE:
1895 QueueSelect = QSLT_VI; //or QSelect = pTcb->priority;
1896 break;
1897 case MGNT_QUEUE:
1898 QueueSelect = QSLT_MGNT;
1899 break;
1901 case BEACON_QUEUE:
1902 QueueSelect = QSLT_BEACON;
1903 break;
1905 // TODO: 2006.10.30 mark other queue selection until we verify it is OK
1906 // TODO: Remove Assertions
1907 //#if (RTL819X_FPGA_VER & RTL819X_FPGA_GUANGAN_070502)
1908 case TXCMD_QUEUE:
1909 QueueSelect = QSLT_CMD;
1910 break;
1911 //#endif
1912 case HIGH_QUEUE:
1913 QueueSelect = QSLT_HIGH;
1914 break;
1916 default:
1917 RT_TRACE(COMP_ERR, "TransmitTCB(): Impossible Queue Selection: %d \n", QueueID);
1918 break;
1920 return QueueSelect;
1923 u8 MRateToHwRate8190Pci(u8 rate)
1925 u8 ret = DESC90_RATE1M;
1927 switch(rate) {
1928 case MGN_1M: ret = DESC90_RATE1M; break;
1929 case MGN_2M: ret = DESC90_RATE2M; break;
1930 case MGN_5_5M: ret = DESC90_RATE5_5M; break;
1931 case MGN_11M: ret = DESC90_RATE11M; break;
1932 case MGN_6M: ret = DESC90_RATE6M; break;
1933 case MGN_9M: ret = DESC90_RATE9M; break;
1934 case MGN_12M: ret = DESC90_RATE12M; break;
1935 case MGN_18M: ret = DESC90_RATE18M; break;
1936 case MGN_24M: ret = DESC90_RATE24M; break;
1937 case MGN_36M: ret = DESC90_RATE36M; break;
1938 case MGN_48M: ret = DESC90_RATE48M; break;
1939 case MGN_54M: ret = DESC90_RATE54M; break;
1941 // HT rate since here
1942 case MGN_MCS0: ret = DESC90_RATEMCS0; break;
1943 case MGN_MCS1: ret = DESC90_RATEMCS1; break;
1944 case MGN_MCS2: ret = DESC90_RATEMCS2; break;
1945 case MGN_MCS3: ret = DESC90_RATEMCS3; break;
1946 case MGN_MCS4: ret = DESC90_RATEMCS4; break;
1947 case MGN_MCS5: ret = DESC90_RATEMCS5; break;
1948 case MGN_MCS6: ret = DESC90_RATEMCS6; break;
1949 case MGN_MCS7: ret = DESC90_RATEMCS7; break;
1950 case MGN_MCS8: ret = DESC90_RATEMCS8; break;
1951 case MGN_MCS9: ret = DESC90_RATEMCS9; break;
1952 case MGN_MCS10: ret = DESC90_RATEMCS10; break;
1953 case MGN_MCS11: ret = DESC90_RATEMCS11; break;
1954 case MGN_MCS12: ret = DESC90_RATEMCS12; break;
1955 case MGN_MCS13: ret = DESC90_RATEMCS13; break;
1956 case MGN_MCS14: ret = DESC90_RATEMCS14; break;
1957 case MGN_MCS15: ret = DESC90_RATEMCS15; break;
1958 case (0x80|0x20): ret = DESC90_RATEMCS32; break;
1960 default: break;
1962 return ret;
1966 u8 QueryIsShort(u8 TxHT, u8 TxRate, cb_desc *tcb_desc)
1968 u8 tmp_Short;
1970 tmp_Short = (TxHT==1)?((tcb_desc->bUseShortGI)?1:0):((tcb_desc->bUseShortPreamble)?1:0);
1972 if(TxHT==1 && TxRate != DESC90_RATEMCS15)
1973 tmp_Short = 0;
1975 return tmp_Short;
1978 static void tx_zero_isr(struct urb *tx_urb)
1980 return;
1984 * The tx procedure is just as following,
1985 * skb->cb will contain all the following information,
1986 * priority, morefrag, rate, &dev.
1987 * */
1988 short rtl8192_tx(struct net_device *dev, struct sk_buff* skb)
1990 struct r8192_priv *priv = ieee80211_priv(dev);
1991 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1992 tx_desc_819x_usb *tx_desc = (tx_desc_819x_usb *)skb->data;
1993 tx_fwinfo_819x_usb *tx_fwinfo = (tx_fwinfo_819x_usb *)(skb->data + USB_HWDESC_HEADER_LEN);
1994 struct usb_device *udev = priv->udev;
1995 int pend;
1996 int status;
1997 struct urb *tx_urb = NULL, *tx_urb_zero = NULL;
1998 //int urb_len;
1999 unsigned int idx_pipe;
2000 // RT_DEBUG_DATA(COMP_SEND, tcb_desc, sizeof(cb_desc));
2001 // printk("=============> %s\n", __FUNCTION__);
2002 pend = atomic_read(&priv->tx_pending[tcb_desc->queue_index]);
2003 /* we are locked here so the two atomic_read and inc are executed
2004 * without interleaves
2005 * !!! For debug purpose
2007 if( pend > MAX_TX_URB){
2008 printk("To discard skb packet!\n");
2009 dev_kfree_skb_any(skb);
2010 return -1;
2013 tx_urb = usb_alloc_urb(0,GFP_ATOMIC);
2014 if(!tx_urb){
2015 dev_kfree_skb_any(skb);
2016 return -ENOMEM;
2019 /* Fill Tx firmware info */
2020 memset(tx_fwinfo,0,sizeof(tx_fwinfo_819x_usb));
2021 /* DWORD 0 */
2022 tx_fwinfo->TxHT = (tcb_desc->data_rate&0x80)?1:0;
2023 tx_fwinfo->TxRate = MRateToHwRate8190Pci(tcb_desc->data_rate);
2024 tx_fwinfo->EnableCPUDur = tcb_desc->bTxEnableFwCalcDur;
2025 tx_fwinfo->Short = QueryIsShort(tx_fwinfo->TxHT, tx_fwinfo->TxRate, tcb_desc);
2026 if(tcb_desc->bAMPDUEnable) {//AMPDU enabled
2027 tx_fwinfo->AllowAggregation = 1;
2028 /* DWORD 1 */
2029 tx_fwinfo->RxMF = tcb_desc->ampdu_factor;
2030 tx_fwinfo->RxAMD = tcb_desc->ampdu_density&0x07;//ampdudensity
2031 } else {
2032 tx_fwinfo->AllowAggregation = 0;
2033 /* DWORD 1 */
2034 tx_fwinfo->RxMF = 0;
2035 tx_fwinfo->RxAMD = 0;
2038 /* Protection mode related */
2039 tx_fwinfo->RtsEnable = (tcb_desc->bRTSEnable)?1:0;
2040 tx_fwinfo->CtsEnable = (tcb_desc->bCTSEnable)?1:0;
2041 tx_fwinfo->RtsSTBC = (tcb_desc->bRTSSTBC)?1:0;
2042 tx_fwinfo->RtsHT = (tcb_desc->rts_rate&0x80)?1:0;
2043 tx_fwinfo->RtsRate = MRateToHwRate8190Pci((u8)tcb_desc->rts_rate);
2044 tx_fwinfo->RtsSubcarrier = (tx_fwinfo->RtsHT==0)?(tcb_desc->RTSSC):0;
2045 tx_fwinfo->RtsBandwidth = (tx_fwinfo->RtsHT==1)?((tcb_desc->bRTSBW)?1:0):0;
2046 tx_fwinfo->RtsShort = (tx_fwinfo->RtsHT==0)?(tcb_desc->bRTSUseShortPreamble?1:0):\
2047 (tcb_desc->bRTSUseShortGI?1:0);
2049 /* Set Bandwidth and sub-channel settings. */
2050 if(priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20_40)
2052 if(tcb_desc->bPacketBW) {
2053 tx_fwinfo->TxBandwidth = 1;
2054 tx_fwinfo->TxSubCarrier = 0; //By SD3's Jerry suggestion, use duplicated mode
2055 } else {
2056 tx_fwinfo->TxBandwidth = 0;
2057 tx_fwinfo->TxSubCarrier = priv->nCur40MhzPrimeSC;
2059 } else {
2060 tx_fwinfo->TxBandwidth = 0;
2061 tx_fwinfo->TxSubCarrier = 0;
2064 #ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
2065 if (tcb_desc->drv_agg_enable)
2067 tx_fwinfo->Tx_INFO_RSVD = (tcb_desc->DrvAggrNum & 0x1f) << 1;
2069 #endif
2070 /* Fill Tx descriptor */
2071 memset(tx_desc, 0, sizeof(tx_desc_819x_usb));
2072 /* DWORD 0 */
2073 tx_desc->LINIP = 0;
2074 tx_desc->CmdInit = 1;
2075 tx_desc->Offset = sizeof(tx_fwinfo_819x_usb) + 8;
2077 #ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
2078 if (tcb_desc->drv_agg_enable) {
2079 tx_desc->PktSize = tcb_desc->pkt_size;
2080 } else
2081 #endif
2083 tx_desc->PktSize = (skb->len - TX_PACKET_SHIFT_BYTES) & 0xffff;
2086 /*DWORD 1*/
2087 tx_desc->SecCAMID= 0;
2088 tx_desc->RATid = tcb_desc->RATRIndex;
2090 //MPDUOverhead = 0;
2091 tx_desc->NoEnc = 1;
2093 tx_desc->SecType = 0x0;
2094 if (tcb_desc->bHwSec)
2096 switch (priv->ieee80211->pairwise_key_type)
2098 case KEY_TYPE_WEP40:
2099 case KEY_TYPE_WEP104:
2100 tx_desc->SecType = 0x1;
2101 tx_desc->NoEnc = 0;
2102 break;
2103 case KEY_TYPE_TKIP:
2104 tx_desc->SecType = 0x2;
2105 tx_desc->NoEnc = 0;
2106 break;
2107 case KEY_TYPE_CCMP:
2108 tx_desc->SecType = 0x3;
2109 tx_desc->NoEnc = 0;
2110 break;
2111 case KEY_TYPE_NA:
2112 tx_desc->SecType = 0x0;
2113 tx_desc->NoEnc = 1;
2114 break;
2118 tx_desc->QueueSelect = MapHwQueueToFirmwareQueue(tcb_desc->queue_index);
2119 tx_desc->TxFWInfoSize = sizeof(tx_fwinfo_819x_usb);
2121 tx_desc->DISFB = tcb_desc->bTxDisableRateFallBack;
2122 tx_desc->USERATE = tcb_desc->bTxUseDriverAssingedRate;
2124 /* Fill fields that are required to be initialized in all of the descriptors */
2125 //DWORD 0
2126 tx_desc->FirstSeg = 1;
2127 tx_desc->LastSeg = 1;
2128 tx_desc->OWN = 1;
2130 #ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
2131 if (tcb_desc->drv_agg_enable) {
2132 tx_desc->TxBufferSize = tcb_desc->pkt_size + sizeof(tx_fwinfo_819x_usb);
2133 } else
2134 #endif
2136 //DWORD 2
2137 tx_desc->TxBufferSize = (u32)(skb->len - USB_HWDESC_HEADER_LEN);
2139 /* Get index to out pipe from specified QueueID */
2140 #ifndef USE_ONE_PIPE
2141 idx_pipe = txqueue2outpipe(priv,tcb_desc->queue_index);
2142 #else
2143 idx_pipe = 0x5;
2144 #endif
2146 //RT_DEBUG_DATA(COMP_SEND,tx_fwinfo,sizeof(tx_fwinfo_819x_usb));
2147 //RT_DEBUG_DATA(COMP_SEND,tx_desc,sizeof(tx_desc_819x_usb));
2149 /* To submit bulk urb */
2150 usb_fill_bulk_urb(tx_urb,udev,
2151 usb_sndbulkpipe(udev,idx_pipe), skb->data,
2152 skb->len, rtl8192_tx_isr, skb);
2154 status = usb_submit_urb(tx_urb, GFP_ATOMIC);
2155 if (!status){
2156 //we need to send 0 byte packet whenever 512N bytes/64N(HIGN SPEED/NORMAL SPEED) bytes packet has been transmitted. Otherwise, it will be halt to wait for another packet. WB. 2008.08.27
2157 bool bSend0Byte = false;
2158 u8 zero = 0;
2159 if(udev->speed == USB_SPEED_HIGH)
2161 if (skb->len > 0 && skb->len % 512 == 0)
2162 bSend0Byte = true;
2164 else
2166 if (skb->len > 0 && skb->len % 64 == 0)
2167 bSend0Byte = true;
2169 if (bSend0Byte)
2171 tx_urb_zero = usb_alloc_urb(0,GFP_ATOMIC);
2172 if(!tx_urb_zero){
2173 RT_TRACE(COMP_ERR, "can't alloc urb for zero byte\n");
2174 return -ENOMEM;
2176 usb_fill_bulk_urb(tx_urb_zero,udev,
2177 usb_sndbulkpipe(udev,idx_pipe), &zero,
2178 0, tx_zero_isr, dev);
2179 status = usb_submit_urb(tx_urb_zero, GFP_ATOMIC);
2180 if (status){
2181 RT_TRACE(COMP_ERR, "Error TX URB for zero byte %d, error %d", atomic_read(&priv->tx_pending[tcb_desc->queue_index]), status);
2182 return -1;
2185 dev->trans_start = jiffies;
2186 atomic_inc(&priv->tx_pending[tcb_desc->queue_index]);
2187 return 0;
2188 }else{
2189 RT_TRACE(COMP_ERR, "Error TX URB %d, error %d", atomic_read(&priv->tx_pending[tcb_desc->queue_index]),
2190 status);
2191 return -1;
2195 short rtl8192_usb_initendpoints(struct net_device *dev)
2197 struct r8192_priv *priv = ieee80211_priv(dev);
2199 priv->rx_urb = kmalloc(sizeof(struct urb *) * (MAX_RX_URB+1),
2200 GFP_KERNEL);
2201 if (priv->rx_urb == NULL)
2202 return -ENOMEM;
2204 #ifndef JACKSON_NEW_RX
2205 for(i=0;i<(MAX_RX_URB+1);i++){
2207 priv->rx_urb[i] = usb_alloc_urb(0,GFP_KERNEL);
2209 priv->rx_urb[i]->transfer_buffer = kmalloc(RX_URB_SIZE, GFP_KERNEL);
2211 priv->rx_urb[i]->transfer_buffer_length = RX_URB_SIZE;
2213 #endif
2215 #ifdef THOMAS_BEACON
2217 long align = 0;
2218 void *oldaddr, *newaddr;
2220 priv->rx_urb[16] = usb_alloc_urb(0, GFP_KERNEL);
2221 priv->oldaddr = kmalloc(16, GFP_KERNEL);
2222 oldaddr = priv->oldaddr;
2223 align = ((long)oldaddr) & 3;
2224 if (align) {
2225 newaddr = oldaddr + 4 - align;
2226 priv->rx_urb[16]->transfer_buffer_length = 16 - 4 + align;
2227 } else {
2228 newaddr = oldaddr;
2229 priv->rx_urb[16]->transfer_buffer_length = 16;
2231 priv->rx_urb[16]->transfer_buffer = newaddr;
2233 #endif
2235 memset(priv->rx_urb, 0, sizeof(struct urb*) * MAX_RX_URB);
2236 priv->pp_rxskb = kcalloc(MAX_RX_URB, sizeof(struct sk_buff *),
2237 GFP_KERNEL);
2238 if (priv->pp_rxskb == NULL)
2239 goto destroy;
2241 goto _middle;
2244 destroy:
2245 kfree(priv->pp_rxskb);
2246 kfree(priv->rx_urb);
2248 priv->pp_rxskb = NULL;
2249 priv->rx_urb = NULL;
2251 DMESGE("Endpoint Alloc Failure");
2252 return -ENOMEM;
2255 _middle:
2257 printk("End of initendpoints\n");
2258 return 0;
2261 #ifdef THOMAS_BEACON
2262 void rtl8192_usb_deleteendpoints(struct net_device *dev)
2264 int i;
2265 struct r8192_priv *priv = ieee80211_priv(dev);
2267 if(priv->rx_urb){
2268 for(i=0;i<(MAX_RX_URB+1);i++){
2269 usb_kill_urb(priv->rx_urb[i]);
2270 usb_free_urb(priv->rx_urb[i]);
2272 kfree(priv->rx_urb);
2273 priv->rx_urb = NULL;
2275 kfree(priv->oldaddr);
2276 priv->oldaddr = NULL;
2277 if (priv->pp_rxskb) {
2278 kfree(priv->pp_rxskb);
2279 priv->pp_rxskb = 0;
2282 #else
2283 void rtl8192_usb_deleteendpoints(struct net_device *dev)
2285 int i;
2286 struct r8192_priv *priv = ieee80211_priv(dev);
2288 #ifndef JACKSON_NEW_RX
2290 if(priv->rx_urb){
2291 for(i=0;i<(MAX_RX_URB+1);i++){
2292 usb_kill_urb(priv->rx_urb[i]);
2293 kfree(priv->rx_urb[i]->transfer_buffer);
2294 usb_free_urb(priv->rx_urb[i]);
2296 kfree(priv->rx_urb);
2297 priv->rx_urb = NULL;
2300 #else
2301 kfree(priv->rx_urb);
2302 priv->rx_urb = NULL;
2303 kfree(priv->oldaddr);
2304 priv->oldaddr = NULL;
2305 if (priv->pp_rxskb) {
2306 kfree(priv->pp_rxskb);
2307 priv->pp_rxskb = 0;
2311 #endif
2313 #endif
2315 extern void rtl8192_update_ratr_table(struct net_device* dev);
2316 void rtl8192_link_change(struct net_device *dev)
2318 // int i;
2320 struct r8192_priv *priv = ieee80211_priv(dev);
2321 struct ieee80211_device* ieee = priv->ieee80211;
2322 //write_nic_word(dev, BCN_INTR_ITV, net->beacon_interval);
2323 if (ieee->state == IEEE80211_LINKED)
2325 rtl8192_net_update(dev);
2326 rtl8192_update_ratr_table(dev);
2327 //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
2328 if ((KEY_TYPE_WEP40 == ieee->pairwise_key_type) || (KEY_TYPE_WEP104 == ieee->pairwise_key_type))
2329 EnableHWSecurityConfig8192(dev);
2331 /*update timing params*/
2332 // RT_TRACE(COMP_CH, "========>%s(), chan:%d\n", __FUNCTION__, priv->chan);
2333 // rtl8192_set_chan(dev, priv->chan);
2334 if (ieee->iw_mode == IW_MODE_INFRA || ieee->iw_mode == IW_MODE_ADHOC)
2336 u32 reg = 0;
2337 reg = read_nic_dword(dev, RCR);
2338 if (priv->ieee80211->state == IEEE80211_LINKED)
2339 priv->ReceiveConfig = reg |= RCR_CBSSID;
2340 else
2341 priv->ReceiveConfig = reg &= ~RCR_CBSSID;
2342 write_nic_dword(dev, RCR, reg);
2345 // rtl8192_set_rxconf(dev);
2348 static struct ieee80211_qos_parameters def_qos_parameters = {
2349 {3,3,3,3},/* cw_min */
2350 {7,7,7,7},/* cw_max */
2351 {2,2,2,2},/* aifs */
2352 {0,0,0,0},/* flags */
2353 {0,0,0,0} /* tx_op_limit */
2357 void rtl8192_update_beacon(struct work_struct * work)
2359 struct r8192_priv *priv = container_of(work, struct r8192_priv, update_beacon_wq.work);
2360 struct net_device *dev = priv->ieee80211->dev;
2361 struct ieee80211_device* ieee = priv->ieee80211;
2362 struct ieee80211_network* net = &ieee->current_network;
2364 if (ieee->pHTInfo->bCurrentHTSupport)
2365 HTUpdateSelfAndPeerSetting(ieee, net);
2366 ieee->pHTInfo->bCurrentRT2RTLongSlotTime = net->bssht.bdRT2RTLongSlotTime;
2367 rtl8192_update_cap(dev, net->capability);
2370 * background support to run QoS activate functionality
2372 int WDCAPARA_ADD[] = {EDCAPARA_BE,EDCAPARA_BK,EDCAPARA_VI,EDCAPARA_VO};
2373 void rtl8192_qos_activate(struct work_struct * work)
2375 struct r8192_priv *priv = container_of(work, struct r8192_priv, qos_activate);
2376 struct net_device *dev = priv->ieee80211->dev;
2377 struct ieee80211_qos_parameters *qos_parameters = &priv->ieee80211->current_network.qos_data.parameters;
2378 u8 mode = priv->ieee80211->current_network.mode;
2379 //u32 size = sizeof(struct ieee80211_qos_parameters);
2380 u8 u1bAIFS;
2381 u32 u4bAcParam;
2382 int i;
2384 if (priv == NULL)
2385 return;
2387 mutex_lock(&priv->mutex);
2388 if(priv->ieee80211->state != IEEE80211_LINKED)
2389 goto success;
2390 RT_TRACE(COMP_QOS,"qos active process with associate response received\n");
2391 /* It better set slot time at first */
2392 /* For we just support b/g mode at present, let the slot time at 9/20 selection */
2393 /* update the ac parameter to related registers */
2394 for(i = 0; i < QOS_QUEUE_NUM; i++) {
2395 //Mode G/A: slotTimeTimer = 9; Mode B: 20
2396 u1bAIFS = qos_parameters->aifs[i] * ((mode&(IEEE_G|IEEE_N_24G)) ?9:20) + aSifsTime;
2397 u4bAcParam = ((((u32)(qos_parameters->tx_op_limit[i]))<< AC_PARAM_TXOP_LIMIT_OFFSET)|
2398 (((u32)(qos_parameters->cw_max[i]))<< AC_PARAM_ECW_MAX_OFFSET)|
2399 (((u32)(qos_parameters->cw_min[i]))<< AC_PARAM_ECW_MIN_OFFSET)|
2400 ((u32)u1bAIFS << AC_PARAM_AIFS_OFFSET));
2402 write_nic_dword(dev, WDCAPARA_ADD[i], u4bAcParam);
2403 //write_nic_dword(dev, WDCAPARA_ADD[i], 0x005e4332);
2406 success:
2407 mutex_unlock(&priv->mutex);
2410 static int rtl8192_qos_handle_probe_response(struct r8192_priv *priv,
2411 int active_network,
2412 struct ieee80211_network *network)
2414 int ret = 0;
2415 u32 size = sizeof(struct ieee80211_qos_parameters);
2417 if(priv->ieee80211->state !=IEEE80211_LINKED)
2418 return ret;
2420 if ((priv->ieee80211->iw_mode != IW_MODE_INFRA))
2421 return ret;
2423 if (network->flags & NETWORK_HAS_QOS_MASK) {
2424 if (active_network &&
2425 (network->flags & NETWORK_HAS_QOS_PARAMETERS))
2426 network->qos_data.active = network->qos_data.supported;
2428 if ((network->qos_data.active == 1) && (active_network == 1) &&
2429 (network->flags & NETWORK_HAS_QOS_PARAMETERS) &&
2430 (network->qos_data.old_param_count !=
2431 network->qos_data.param_count)) {
2432 network->qos_data.old_param_count =
2433 network->qos_data.param_count;
2434 queue_work(priv->priv_wq, &priv->qos_activate);
2435 RT_TRACE (COMP_QOS, "QoS parameters change call "
2436 "qos_activate\n");
2438 } else {
2439 memcpy(&priv->ieee80211->current_network.qos_data.parameters,\
2440 &def_qos_parameters, size);
2442 if ((network->qos_data.active == 1) && (active_network == 1)) {
2443 queue_work(priv->priv_wq, &priv->qos_activate);
2444 RT_TRACE(COMP_QOS, "QoS was disabled call qos_activate \n");
2446 network->qos_data.active = 0;
2447 network->qos_data.supported = 0;
2450 return 0;
2453 /* handle manage frame frame beacon and probe response */
2454 static int rtl8192_handle_beacon(struct net_device * dev,
2455 struct ieee80211_beacon * beacon,
2456 struct ieee80211_network * network)
2458 struct r8192_priv *priv = ieee80211_priv(dev);
2460 rtl8192_qos_handle_probe_response(priv,1,network);
2461 queue_delayed_work(priv->priv_wq, &priv->update_beacon_wq, 0);
2462 return 0;
2467 * handling the beaconing responses. if we get different QoS setting
2468 * off the network from the associated setting, adjust the QoS
2469 * setting
2471 static int rtl8192_qos_association_resp(struct r8192_priv *priv,
2472 struct ieee80211_network *network)
2474 int ret = 0;
2475 unsigned long flags;
2476 u32 size = sizeof(struct ieee80211_qos_parameters);
2477 int set_qos_param = 0;
2479 if ((priv == NULL) || (network == NULL))
2480 return ret;
2482 if(priv->ieee80211->state !=IEEE80211_LINKED)
2483 return ret;
2485 if ((priv->ieee80211->iw_mode != IW_MODE_INFRA))
2486 return ret;
2488 spin_lock_irqsave(&priv->ieee80211->lock, flags);
2489 if(network->flags & NETWORK_HAS_QOS_PARAMETERS) {
2490 memcpy(&priv->ieee80211->current_network.qos_data.parameters,\
2491 &network->qos_data.parameters,\
2492 sizeof(struct ieee80211_qos_parameters));
2493 priv->ieee80211->current_network.qos_data.active = 1;
2495 set_qos_param = 1;
2496 /* update qos parameter for current network */
2497 priv->ieee80211->current_network.qos_data.old_param_count = \
2498 priv->ieee80211->current_network.qos_data.param_count;
2499 priv->ieee80211->current_network.qos_data.param_count = \
2500 network->qos_data.param_count;
2502 } else {
2503 memcpy(&priv->ieee80211->current_network.qos_data.parameters,\
2504 &def_qos_parameters, size);
2505 priv->ieee80211->current_network.qos_data.active = 0;
2506 priv->ieee80211->current_network.qos_data.supported = 0;
2507 set_qos_param = 1;
2510 spin_unlock_irqrestore(&priv->ieee80211->lock, flags);
2512 RT_TRACE(COMP_QOS, "%s: network->flags = %d,%d\n",__FUNCTION__,network->flags ,priv->ieee80211->current_network.qos_data.active);
2513 if (set_qos_param == 1)
2514 queue_work(priv->priv_wq, &priv->qos_activate);
2517 return ret;
2521 static int rtl8192_handle_assoc_response(struct net_device *dev,
2522 struct ieee80211_assoc_response_frame *resp,
2523 struct ieee80211_network *network)
2525 struct r8192_priv *priv = ieee80211_priv(dev);
2526 rtl8192_qos_association_resp(priv, network);
2527 return 0;
2531 void rtl8192_update_ratr_table(struct net_device* dev)
2532 // POCTET_STRING posLegacyRate,
2533 // u8* pMcsRate)
2534 // PRT_WLAN_STA pEntry)
2536 struct r8192_priv* priv = ieee80211_priv(dev);
2537 struct ieee80211_device* ieee = priv->ieee80211;
2538 u8* pMcsRate = ieee->dot11HTOperationalRateSet;
2539 //struct ieee80211_network *net = &ieee->current_network;
2540 u32 ratr_value = 0;
2541 u8 rate_index = 0;
2542 rtl8192_config_rate(dev, (u16*)(&ratr_value));
2543 ratr_value |= (*(u16*)(pMcsRate)) << 12;
2544 // switch (net->mode)
2545 switch (ieee->mode)
2547 case IEEE_A:
2548 ratr_value &= 0x00000FF0;
2549 break;
2550 case IEEE_B:
2551 ratr_value &= 0x0000000F;
2552 break;
2553 case IEEE_G:
2554 ratr_value &= 0x00000FF7;
2555 break;
2556 case IEEE_N_24G:
2557 case IEEE_N_5G:
2558 if (ieee->pHTInfo->PeerMimoPs == 0) //MIMO_PS_STATIC
2559 ratr_value &= 0x0007F007;
2560 else{
2561 if (priv->rf_type == RF_1T2R)
2562 ratr_value &= 0x000FF007;
2563 else
2564 ratr_value &= 0x0F81F007;
2566 break;
2567 default:
2568 break;
2570 ratr_value &= 0x0FFFFFFF;
2571 if(ieee->pHTInfo->bCurTxBW40MHz && ieee->pHTInfo->bCurShortGI40MHz){
2572 ratr_value |= 0x80000000;
2573 }else if(!ieee->pHTInfo->bCurTxBW40MHz && ieee->pHTInfo->bCurShortGI20MHz){
2574 ratr_value |= 0x80000000;
2576 write_nic_dword(dev, RATR0+rate_index*4, ratr_value);
2577 write_nic_byte(dev, UFWP, 1);
2580 static u8 ccmp_ie[4] = {0x00,0x50,0xf2,0x04};
2581 static u8 ccmp_rsn_ie[4] = {0x00, 0x0f, 0xac, 0x04};
2582 bool GetNmodeSupportBySecCfg8192(struct net_device*dev)
2584 struct r8192_priv* priv = ieee80211_priv(dev);
2585 struct ieee80211_device* ieee = priv->ieee80211;
2586 struct ieee80211_network * network = &ieee->current_network;
2587 int wpa_ie_len= ieee->wpa_ie_len;
2588 struct ieee80211_crypt_data* crypt;
2589 int encrypt;
2591 crypt = ieee->crypt[ieee->tx_keyidx];
2592 //we use connecting AP's capability instead of only security config on our driver to distinguish whether it should use N mode or G mode
2593 encrypt = (network->capability & WLAN_CAPABILITY_PRIVACY) || (ieee->host_encrypt && crypt && crypt->ops && (0 == strcmp(crypt->ops->name,"WEP")));
2595 /* simply judge */
2596 if(encrypt && (wpa_ie_len == 0)) {
2597 /* wep encryption, no N mode setting */
2598 return false;
2599 // } else if((wpa_ie_len != 0)&&(memcmp(&(ieee->wpa_ie[14]),ccmp_ie,4))) {
2600 } else if((wpa_ie_len != 0)) {
2601 /* parse pairwise key type */
2602 //if((pairwisekey = WEP40)||(pairwisekey = WEP104)||(pairwisekey = TKIP))
2603 if (((ieee->wpa_ie[0] == 0xdd) && (!memcmp(&(ieee->wpa_ie[14]),ccmp_ie,4))) || ((ieee->wpa_ie[0] == 0x30) && (!memcmp(&ieee->wpa_ie[10],ccmp_rsn_ie, 4))))
2604 return true;
2605 else
2606 return false;
2607 } else {
2608 return true;
2611 return true;
2614 bool GetHalfNmodeSupportByAPs819xUsb(struct net_device* dev)
2616 bool Reval;
2617 struct r8192_priv* priv = ieee80211_priv(dev);
2618 struct ieee80211_device* ieee = priv->ieee80211;
2620 if(ieee->bHalfWirelessN24GMode == true)
2621 Reval = true;
2622 else
2623 Reval = false;
2625 return Reval;
2628 void rtl8192_refresh_supportrate(struct r8192_priv* priv)
2630 struct ieee80211_device* ieee = priv->ieee80211;
2631 //we donot consider set support rate for ABG mode, only HT MCS rate is set here.
2632 if (ieee->mode == WIRELESS_MODE_N_24G || ieee->mode == WIRELESS_MODE_N_5G)
2634 memcpy(ieee->Regdot11HTOperationalRateSet, ieee->RegHTSuppRateSet, 16);
2635 //RT_DEBUG_DATA(COMP_INIT, ieee->RegHTSuppRateSet, 16);
2636 //RT_DEBUG_DATA(COMP_INIT, ieee->Regdot11HTOperationalRateSet, 16);
2638 else
2639 memset(ieee->Regdot11HTOperationalRateSet, 0, 16);
2640 return;
2643 u8 rtl8192_getSupportedWireleeMode(struct net_device*dev)
2645 struct r8192_priv *priv = ieee80211_priv(dev);
2646 u8 ret = 0;
2647 switch(priv->rf_chip)
2649 case RF_8225:
2650 case RF_8256:
2651 case RF_PSEUDO_11N:
2652 ret = (WIRELESS_MODE_N_24G|WIRELESS_MODE_G|WIRELESS_MODE_B);
2653 break;
2654 case RF_8258:
2655 ret = (WIRELESS_MODE_A|WIRELESS_MODE_N_5G);
2656 break;
2657 default:
2658 ret = WIRELESS_MODE_B;
2659 break;
2661 return ret;
2663 void rtl8192_SetWirelessMode(struct net_device* dev, u8 wireless_mode)
2665 struct r8192_priv *priv = ieee80211_priv(dev);
2666 u8 bSupportMode = rtl8192_getSupportedWireleeMode(dev);
2668 if ((wireless_mode == WIRELESS_MODE_AUTO) || ((wireless_mode&bSupportMode)==0))
2670 if(bSupportMode & WIRELESS_MODE_N_24G)
2672 wireless_mode = WIRELESS_MODE_N_24G;
2674 else if(bSupportMode & WIRELESS_MODE_N_5G)
2676 wireless_mode = WIRELESS_MODE_N_5G;
2678 else if((bSupportMode & WIRELESS_MODE_A))
2680 wireless_mode = WIRELESS_MODE_A;
2682 else if((bSupportMode & WIRELESS_MODE_G))
2684 wireless_mode = WIRELESS_MODE_G;
2686 else if((bSupportMode & WIRELESS_MODE_B))
2688 wireless_mode = WIRELESS_MODE_B;
2690 else{
2691 RT_TRACE(COMP_ERR, "%s(), No valid wireless mode supported, SupportedWirelessMode(%x)!!!\n", __FUNCTION__,bSupportMode);
2692 wireless_mode = WIRELESS_MODE_B;
2695 #ifdef TO_DO_LIST //// TODO: this function doesn't work well at this time, we should wait for FPGA
2696 ActUpdateChannelAccessSetting( pAdapter, pHalData->CurrentWirelessMode, &pAdapter->MgntInfo.Info8185.ChannelAccessSetting );
2697 #endif
2698 priv->ieee80211->mode = wireless_mode;
2700 if ((wireless_mode == WIRELESS_MODE_N_24G) || (wireless_mode == WIRELESS_MODE_N_5G))
2701 priv->ieee80211->pHTInfo->bEnableHT = 1;
2702 else
2703 priv->ieee80211->pHTInfo->bEnableHT = 0;
2704 RT_TRACE(COMP_INIT, "Current Wireless Mode is %x\n", wireless_mode);
2705 rtl8192_refresh_supportrate(priv);
2708 //init priv variables here. only non_zero value should be initialized here.
2709 static void rtl8192_init_priv_variable(struct net_device* dev)
2711 struct r8192_priv *priv = ieee80211_priv(dev);
2712 u8 i;
2713 priv->card_8192 = NIC_8192U;
2714 priv->chan = 1; //set to channel 1
2715 priv->ieee80211->mode = WIRELESS_MODE_AUTO; //SET AUTO
2716 priv->ieee80211->iw_mode = IW_MODE_INFRA;
2717 priv->ieee80211->ieee_up=0;
2718 priv->retry_rts = DEFAULT_RETRY_RTS;
2719 priv->retry_data = DEFAULT_RETRY_DATA;
2720 priv->ieee80211->rts = DEFAULT_RTS_THRESHOLD;
2721 priv->ieee80211->rate = 110; //11 mbps
2722 priv->ieee80211->short_slot = 1;
2723 priv->promisc = (dev->flags & IFF_PROMISC) ? 1:0;
2724 priv->CckPwEnl = 6;
2725 //for silent reset
2726 priv->IrpPendingCount = 1;
2727 priv->ResetProgress = RESET_TYPE_NORESET;
2728 priv->bForcedSilentReset = 0;
2729 priv->bDisableNormalResetCheck = false;
2730 priv->force_reset = false;
2732 priv->ieee80211->FwRWRF = 0; //we don't use FW read/write RF until stable firmware is available.
2733 priv->ieee80211->current_network.beacon_interval = DEFAULT_BEACONINTERVAL;
2734 priv->ieee80211->iw_mode = IW_MODE_INFRA;
2735 priv->ieee80211->softmac_features = IEEE_SOFTMAC_SCAN |
2736 IEEE_SOFTMAC_ASSOCIATE | IEEE_SOFTMAC_PROBERQ |
2737 IEEE_SOFTMAC_PROBERS | IEEE_SOFTMAC_TX_QUEUE |
2738 IEEE_SOFTMAC_BEACONS;//added by amy 080604 //| //IEEE_SOFTMAC_SINGLE_QUEUE;
2740 priv->ieee80211->active_scan = 1;
2741 priv->ieee80211->modulation = IEEE80211_CCK_MODULATION | IEEE80211_OFDM_MODULATION;
2742 priv->ieee80211->host_encrypt = 1;
2743 priv->ieee80211->host_decrypt = 1;
2744 priv->ieee80211->start_send_beacons = NULL;//rtl819xusb_beacon_tx;//-by amy 080604
2745 priv->ieee80211->stop_send_beacons = NULL;//rtl8192_beacon_stop;//-by amy 080604
2746 priv->ieee80211->softmac_hard_start_xmit = rtl8192_hard_start_xmit;
2747 priv->ieee80211->set_chan = rtl8192_set_chan;
2748 priv->ieee80211->link_change = rtl8192_link_change;
2749 priv->ieee80211->softmac_data_hard_start_xmit = rtl8192_hard_data_xmit;
2750 priv->ieee80211->data_hard_stop = rtl8192_data_hard_stop;
2751 priv->ieee80211->data_hard_resume = rtl8192_data_hard_resume;
2752 priv->ieee80211->init_wmmparam_flag = 0;
2753 priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD;
2754 priv->ieee80211->check_nic_enough_desc = check_nic_enough_desc;
2755 priv->ieee80211->tx_headroom = TX_PACKET_SHIFT_BYTES;
2756 priv->ieee80211->qos_support = 1;
2758 //added by WB
2759 // priv->ieee80211->SwChnlByTimerHandler = rtl8192_phy_SwChnl;
2760 priv->ieee80211->SetBWModeHandler = rtl8192_SetBWMode;
2761 priv->ieee80211->handle_assoc_response = rtl8192_handle_assoc_response;
2762 priv->ieee80211->handle_beacon = rtl8192_handle_beacon;
2763 //added by david
2764 priv->ieee80211->GetNmodeSupportBySecCfg = GetNmodeSupportBySecCfg8192;
2765 priv->ieee80211->GetHalfNmodeSupportByAPsHandler = GetHalfNmodeSupportByAPs819xUsb;
2766 priv->ieee80211->SetWirelessMode = rtl8192_SetWirelessMode;
2767 //added by amy
2768 priv->ieee80211->InitialGainHandler = InitialGain819xUsb;
2769 priv->card_type = USB;
2770 #ifdef TO_DO_LIST
2771 if(Adapter->bInHctTest)
2773 pHalData->ShortRetryLimit = 7;
2774 pHalData->LongRetryLimit = 7;
2776 #endif
2778 priv->ShortRetryLimit = 0x30;
2779 priv->LongRetryLimit = 0x30;
2781 priv->EarlyRxThreshold = 7;
2782 priv->enable_gpio0 = 0;
2783 priv->TransmitConfig =
2784 // TCR_DurProcMode | //for RTL8185B, duration setting by HW
2785 //? TCR_DISReqQsize |
2786 (TCR_MXDMA_2048<<TCR_MXDMA_OFFSET)| // Max DMA Burst Size per Tx DMA Burst, 7: reservied.
2787 (priv->ShortRetryLimit<<TCR_SRL_OFFSET)| // Short retry limit
2788 (priv->LongRetryLimit<<TCR_LRL_OFFSET) | // Long retry limit
2789 (false ? TCR_SAT: 0); // FALSE: HW provies PLCP length and LENGEXT, TURE: SW proiveds them
2790 #ifdef TO_DO_LIST
2791 if(Adapter->bInHctTest)
2792 pHalData->ReceiveConfig = pHalData->CSMethod |
2793 RCR_AMF | RCR_ADF | //RCR_AAP | //accept management/data
2794 //guangan200710
2795 RCR_ACF | //accept control frame for SW AP needs PS-poll, 2005.07.07, by rcnjko.
2796 RCR_AB | RCR_AM | RCR_APM | //accept BC/MC/UC
2797 RCR_AICV | RCR_ACRC32 | //accept ICV/CRC error packet
2798 ((u32)7<<RCR_MXDMA_OFFSET) | // Max DMA Burst Size per Rx DMA Burst, 7: unlimited.
2799 (pHalData->EarlyRxThreshold<<RCR_FIFO_OFFSET) | // Rx FIFO Threshold, 7: No Rx threshold.
2800 (pHalData->EarlyRxThreshold == 7 ? RCR_OnlyErlPkt:0);
2801 else
2803 #endif
2804 priv->ReceiveConfig =
2805 RCR_AMF | RCR_ADF | //accept management/data
2806 RCR_ACF | //accept control frame for SW AP needs PS-poll, 2005.07.07, by rcnjko.
2807 RCR_AB | RCR_AM | RCR_APM | //accept BC/MC/UC
2808 //RCR_AICV | RCR_ACRC32 | //accept ICV/CRC error packet
2809 ((u32)7<<RCR_MXDMA_OFFSET)| // Max DMA Burst Size per Rx DMA Burst, 7: unlimited.
2810 (priv->EarlyRxThreshold<<RX_FIFO_THRESHOLD_SHIFT) | // Rx FIFO Threshold, 7: No Rx threshold.
2811 (priv->EarlyRxThreshold == 7 ? RCR_ONLYERLPKT:0);
2813 priv->AcmControl = 0;
2814 priv->pFirmware = kmalloc(sizeof(rt_firmware), GFP_KERNEL);
2815 if (priv->pFirmware)
2816 memset(priv->pFirmware, 0, sizeof(rt_firmware));
2818 /* rx related queue */
2819 skb_queue_head_init(&priv->rx_queue);
2820 skb_queue_head_init(&priv->skb_queue);
2822 /* Tx related queue */
2823 for(i = 0; i < MAX_QUEUE_SIZE; i++) {
2824 skb_queue_head_init(&priv->ieee80211->skb_waitQ [i]);
2826 for(i = 0; i < MAX_QUEUE_SIZE; i++) {
2827 skb_queue_head_init(&priv->ieee80211->skb_aggQ [i]);
2829 for(i = 0; i < MAX_QUEUE_SIZE; i++) {
2830 skb_queue_head_init(&priv->ieee80211->skb_drv_aggQ [i]);
2832 priv->rf_set_chan = rtl8192_phy_SwChnl;
2835 //init lock here
2836 static void rtl8192_init_priv_lock(struct r8192_priv* priv)
2838 spin_lock_init(&priv->tx_lock);
2839 spin_lock_init(&priv->irq_lock);//added by thomas
2840 //spin_lock_init(&priv->rf_lock);
2841 sema_init(&priv->wx_sem,1);
2842 sema_init(&priv->rf_sem,1);
2843 mutex_init(&priv->mutex);
2846 extern void rtl819x_watchdog_wqcallback(struct work_struct *work);
2848 void rtl8192_irq_rx_tasklet(struct r8192_priv *priv);
2849 //init tasklet and wait_queue here. only 2.6 above kernel is considered
2850 #define DRV_NAME "wlan0"
2851 static void rtl8192_init_priv_task(struct net_device* dev)
2853 struct r8192_priv *priv = ieee80211_priv(dev);
2855 #ifdef PF_SYNCTHREAD
2856 priv->priv_wq = create_workqueue(DRV_NAME,0);
2857 #else
2858 priv->priv_wq = create_workqueue(DRV_NAME);
2859 #endif
2861 INIT_WORK(&priv->reset_wq, rtl8192_restart);
2863 //INIT_DELAYED_WORK(&priv->watch_dog_wq, hal_dm_watchdog);
2864 INIT_DELAYED_WORK(&priv->watch_dog_wq, rtl819x_watchdog_wqcallback);
2865 INIT_DELAYED_WORK(&priv->txpower_tracking_wq, dm_txpower_trackingcallback);
2866 // INIT_DELAYED_WORK(&priv->gpio_change_rf_wq, dm_gpio_change_rf_callback);
2867 INIT_DELAYED_WORK(&priv->rfpath_check_wq, dm_rf_pathcheck_workitemcallback);
2868 INIT_DELAYED_WORK(&priv->update_beacon_wq, rtl8192_update_beacon);
2869 INIT_DELAYED_WORK(&priv->initialgain_operate_wq, InitialGainOperateWorkItemCallBack);
2870 //INIT_WORK(&priv->SwChnlWorkItem, rtl8192_SwChnl_WorkItem);
2871 //INIT_WORK(&priv->SetBWModeWorkItem, rtl8192_SetBWModeWorkItem);
2872 INIT_WORK(&priv->qos_activate, rtl8192_qos_activate);
2874 tasklet_init(&priv->irq_rx_tasklet,
2875 (void(*)(unsigned long))rtl8192_irq_rx_tasklet,
2876 (unsigned long)priv);
2879 static void rtl8192_get_eeprom_size(struct net_device* dev)
2881 u16 curCR = 0;
2882 struct r8192_priv *priv = ieee80211_priv(dev);
2883 RT_TRACE(COMP_EPROM, "===========>%s()\n", __FUNCTION__);
2884 curCR = read_nic_word_E(dev,EPROM_CMD);
2885 RT_TRACE(COMP_EPROM, "read from Reg EPROM_CMD(%x):%x\n", EPROM_CMD, curCR);
2886 //whether need I consider BIT5?
2887 priv->epromtype = (curCR & Cmd9346CR_9356SEL) ? EPROM_93c56 : EPROM_93c46;
2888 RT_TRACE(COMP_EPROM, "<===========%s(), epromtype:%d\n", __FUNCTION__, priv->epromtype);
2891 //used to swap endian. as ntohl & htonl are not necessary to swap endian, so use this instead.
2892 static inline u16 endian_swap(u16* data)
2894 u16 tmp = *data;
2895 *data = (tmp >> 8) | (tmp << 8);
2896 return *data;
2898 static void rtl8192_read_eeprom_info(struct net_device* dev)
2900 u16 wEPROM_ID = 0;
2901 u8 bMac_Tmp_Addr[6] = {0x00, 0xe0, 0x4c, 0x00, 0x00, 0x02};
2902 u8 bLoad_From_EEPOM = false;
2903 struct r8192_priv *priv = ieee80211_priv(dev);
2904 u16 tmpValue = 0;
2905 RT_TRACE(COMP_EPROM, "===========>%s()\n", __FUNCTION__);
2906 wEPROM_ID = eprom_read(dev, 0); //first read EEPROM ID out;
2907 RT_TRACE(COMP_EPROM, "EEPROM ID is 0x%x\n", wEPROM_ID);
2909 if (wEPROM_ID != RTL8190_EEPROM_ID)
2911 RT_TRACE(COMP_ERR, "EEPROM ID is invalid(is 0x%x(should be 0x%x)\n", wEPROM_ID, RTL8190_EEPROM_ID);
2913 else
2914 bLoad_From_EEPOM = true;
2916 if (bLoad_From_EEPOM)
2918 tmpValue = eprom_read(dev, (EEPROM_VID>>1));
2919 priv->eeprom_vid = endian_swap(&tmpValue);
2920 priv->eeprom_pid = eprom_read(dev, (EEPROM_PID>>1));
2921 tmpValue = eprom_read(dev, (EEPROM_ChannelPlan>>1));
2922 priv->eeprom_ChannelPlan =((tmpValue&0xff00)>>8);
2923 priv->btxpowerdata_readfromEEPORM = true;
2924 priv->eeprom_CustomerID = eprom_read(dev, (EEPROM_Customer_ID>>1)) >>8;
2926 else
2928 priv->eeprom_vid = 0;
2929 priv->eeprom_pid = 0;
2930 priv->card_8192_version = VERSION_819xU_B;
2931 priv->eeprom_ChannelPlan = 0;
2932 priv->eeprom_CustomerID = 0;
2934 RT_TRACE(COMP_EPROM, "vid:0x%4x, pid:0x%4x, CustomID:0x%2x, ChanPlan:0x%x\n", priv->eeprom_vid, priv->eeprom_pid, priv->eeprom_CustomerID, priv->eeprom_ChannelPlan);
2935 //set channelplan from eeprom
2936 priv->ChannelPlan = priv->eeprom_ChannelPlan;
2937 if (bLoad_From_EEPOM)
2939 int i;
2940 for (i=0; i<6; i+=2)
2942 u16 tmp = 0;
2943 tmp = eprom_read(dev, (u16)((EEPROM_NODE_ADDRESS_BYTE_0 + i)>>1));
2944 *(u16*)(&dev->dev_addr[i]) = tmp;
2947 else
2949 memcpy(dev->dev_addr, bMac_Tmp_Addr, 6);
2950 //should I set IDR0 here?
2952 RT_TRACE(COMP_EPROM, "MAC addr:%pM\n", dev->dev_addr);
2953 priv->rf_type = RTL819X_DEFAULT_RF_TYPE; //default 1T2R
2954 priv->rf_chip = RF_8256;
2956 if (priv->card_8192_version == (u8)VERSION_819xU_A)
2958 //read Tx power gain offset of legacy OFDM to HT rate
2959 if (bLoad_From_EEPOM)
2960 priv->EEPROMTxPowerDiff = (eprom_read(dev, (EEPROM_TxPowerDiff>>1))&0xff00) >> 8;
2961 else
2962 priv->EEPROMTxPowerDiff = EEPROM_Default_TxPower;
2963 RT_TRACE(COMP_EPROM, "TxPowerDiff:%d\n", priv->EEPROMTxPowerDiff);
2964 //read ThermalMeter from EEPROM
2965 if (bLoad_From_EEPOM)
2966 priv->EEPROMThermalMeter = (u8)(eprom_read(dev, (EEPROM_ThermalMeter>>1))&0x00ff);
2967 else
2968 priv->EEPROMThermalMeter = EEPROM_Default_ThermalMeter;
2969 RT_TRACE(COMP_EPROM, "ThermalMeter:%d\n", priv->EEPROMThermalMeter);
2970 //vivi, for tx power track
2971 priv->TSSI_13dBm = priv->EEPROMThermalMeter *100;
2972 //read antenna tx power offset of B/C/D to A from EEPROM
2973 if (bLoad_From_EEPOM)
2974 priv->EEPROMPwDiff = (eprom_read(dev, (EEPROM_PwDiff>>1))&0x0f00)>>8;
2975 else
2976 priv->EEPROMPwDiff = EEPROM_Default_PwDiff;
2977 RT_TRACE(COMP_EPROM, "TxPwDiff:%d\n", priv->EEPROMPwDiff);
2978 // Read CrystalCap from EEPROM
2979 if (bLoad_From_EEPOM)
2980 priv->EEPROMCrystalCap = (eprom_read(dev, (EEPROM_CrystalCap>>1))&0x0f);
2981 else
2982 priv->EEPROMCrystalCap = EEPROM_Default_CrystalCap;
2983 RT_TRACE(COMP_EPROM, "CrystalCap = %d\n", priv->EEPROMCrystalCap);
2984 //get per-channel Tx power level
2985 if (bLoad_From_EEPOM)
2986 priv->EEPROM_Def_Ver = (eprom_read(dev, (EEPROM_TxPwIndex_Ver>>1))&0xff00)>>8;
2987 else
2988 priv->EEPROM_Def_Ver = 1;
2989 RT_TRACE(COMP_EPROM, "EEPROM_DEF_VER:%d\n", priv->EEPROM_Def_Ver);
2990 if (priv->EEPROM_Def_Ver == 0) //old eeprom definition
2992 int i;
2993 if (bLoad_From_EEPOM)
2994 priv->EEPROMTxPowerLevelCCK = (eprom_read(dev, (EEPROM_TxPwIndex_CCK>>1))&0xff) >> 8;
2995 else
2996 priv->EEPROMTxPowerLevelCCK = 0x10;
2997 RT_TRACE(COMP_EPROM, "CCK Tx Power Levl: 0x%02x\n", priv->EEPROMTxPowerLevelCCK);
2998 for (i=0; i<3; i++)
3000 if (bLoad_From_EEPOM)
3002 tmpValue = eprom_read(dev, (EEPROM_TxPwIndex_OFDM_24G+i)>>1);
3003 if (((EEPROM_TxPwIndex_OFDM_24G+i) % 2) == 0)
3004 tmpValue = tmpValue & 0x00ff;
3005 else
3006 tmpValue = (tmpValue & 0xff00) >> 8;
3008 else
3009 tmpValue = 0x10;
3010 priv->EEPROMTxPowerLevelOFDM24G[i] = (u8) tmpValue;
3011 RT_TRACE(COMP_EPROM, "OFDM 2.4G Tx Power Level, Index %d = 0x%02x\n", i, priv->EEPROMTxPowerLevelCCK);
3013 }//end if EEPROM_DEF_VER == 0
3014 else if (priv->EEPROM_Def_Ver == 1)
3016 if (bLoad_From_EEPOM)
3018 tmpValue = eprom_read(dev, (EEPROM_TxPwIndex_CCK_V1>>1));
3019 tmpValue = (tmpValue & 0xff00) >> 8;
3021 else
3022 tmpValue = 0x10;
3023 priv->EEPROMTxPowerLevelCCK_V1[0] = (u8)tmpValue;
3025 if (bLoad_From_EEPOM)
3026 tmpValue = eprom_read(dev, (EEPROM_TxPwIndex_CCK_V1 + 2)>>1);
3027 else
3028 tmpValue = 0x1010;
3029 *((u16*)(&priv->EEPROMTxPowerLevelCCK_V1[1])) = tmpValue;
3030 if (bLoad_From_EEPOM)
3031 tmpValue = eprom_read(dev, (EEPROM_TxPwIndex_OFDM_24G_V1>>1));
3032 else
3033 tmpValue = 0x1010;
3034 *((u16*)(&priv->EEPROMTxPowerLevelOFDM24G[0])) = tmpValue;
3035 if (bLoad_From_EEPOM)
3036 tmpValue = eprom_read(dev, (EEPROM_TxPwIndex_OFDM_24G_V1+2)>>1);
3037 else
3038 tmpValue = 0x10;
3039 priv->EEPROMTxPowerLevelOFDM24G[2] = (u8)tmpValue;
3040 }//endif EEPROM_Def_Ver == 1
3042 //update HAL variables
3045 int i;
3046 for (i=0; i<14; i++)
3048 if (i<=3)
3049 priv->TxPowerLevelOFDM24G[i] = priv->EEPROMTxPowerLevelOFDM24G[0];
3050 else if (i>=4 && i<=9)
3051 priv->TxPowerLevelOFDM24G[i] = priv->EEPROMTxPowerLevelOFDM24G[1];
3052 else
3053 priv->TxPowerLevelOFDM24G[i] = priv->EEPROMTxPowerLevelOFDM24G[2];
3056 for (i=0; i<14; i++)
3058 if (priv->EEPROM_Def_Ver == 0)
3060 if (i<=3)
3061 priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelOFDM24G[0] + (priv->EEPROMTxPowerLevelCCK - priv->EEPROMTxPowerLevelOFDM24G[1]);
3062 else if (i>=4 && i<=9)
3063 priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelCCK;
3064 else
3065 priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelOFDM24G[2] + (priv->EEPROMTxPowerLevelCCK - priv->EEPROMTxPowerLevelOFDM24G[1]);
3067 else if (priv->EEPROM_Def_Ver == 1)
3069 if (i<=3)
3070 priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelCCK_V1[0];
3071 else if (i>=4 && i<=9)
3072 priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelCCK_V1[1];
3073 else
3074 priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelCCK_V1[2];
3077 }//end update HAL variables
3078 priv->TxPowerDiff = priv->EEPROMPwDiff;
3079 // Antenna B gain offset to antenna A, bit0~3
3080 priv->AntennaTxPwDiff[0] = (priv->EEPROMTxPowerDiff & 0xf);
3081 // Antenna C gain offset to antenna A, bit4~7
3082 priv->AntennaTxPwDiff[1] = ((priv->EEPROMTxPowerDiff & 0xf0)>>4);
3083 // CrystalCap, bit12~15
3084 priv->CrystalCap = priv->EEPROMCrystalCap;
3085 // ThermalMeter, bit0~3 for RFIC1, bit4~7 for RFIC2
3086 // 92U does not enable TX power tracking.
3087 priv->ThermalMeter[0] = priv->EEPROMThermalMeter;
3088 }//end if VersionID == VERSION_819xU_A
3090 //added by vivi, for dlink led, 20080416
3091 switch(priv->eeprom_CustomerID)
3093 case EEPROM_CID_RUNTOP:
3094 priv->CustomerID = RT_CID_819x_RUNTOP;
3095 break;
3097 case EEPROM_CID_DLINK:
3098 priv->CustomerID = RT_CID_DLINK;
3099 break;
3101 default:
3102 priv->CustomerID = RT_CID_DEFAULT;
3103 break;
3107 switch(priv->CustomerID)
3109 case RT_CID_819x_RUNTOP:
3110 priv->LedStrategy = SW_LED_MODE2;
3111 break;
3113 case RT_CID_DLINK:
3114 priv->LedStrategy = SW_LED_MODE4;
3115 break;
3117 default:
3118 priv->LedStrategy = SW_LED_MODE0;
3119 break;
3124 if(priv->rf_type == RF_1T2R)
3126 RT_TRACE(COMP_EPROM, "\n1T2R config\n");
3128 else
3130 RT_TRACE(COMP_EPROM, "\n2T4R config\n");
3133 // 2008/01/16 MH We can only know RF type in the function. So we have to init
3134 // DIG RATR table again.
3135 init_rate_adaptive(dev);
3136 //we need init DIG RATR table here again.
3138 RT_TRACE(COMP_EPROM, "<===========%s()\n", __FUNCTION__);
3139 return;
3142 short rtl8192_get_channel_map(struct net_device * dev)
3144 struct r8192_priv *priv = ieee80211_priv(dev);
3145 if(priv->ChannelPlan > COUNTRY_CODE_GLOBAL_DOMAIN){
3146 printk("rtl8180_init:Error channel plan! Set to default.\n");
3147 priv->ChannelPlan= 0;
3149 RT_TRACE(COMP_INIT, "Channel plan is %d\n",priv->ChannelPlan);
3151 rtl819x_set_channel_map(priv->ChannelPlan, priv);
3152 return 0;
3155 short rtl8192_init(struct net_device *dev)
3158 struct r8192_priv *priv = ieee80211_priv(dev);
3160 memset(&(priv->stats),0,sizeof(struct Stats));
3161 memset(priv->txqueue_to_outpipemap,0,9);
3162 #ifdef PIPE12
3164 int i=0;
3165 u8 queuetopipe[]={3,2,1,0,4,8,7,6,5};
3166 memcpy(priv->txqueue_to_outpipemap,queuetopipe,9);
3167 /* for(i=0;i<9;i++)
3168 printk("%d ",priv->txqueue_to_outpipemap[i]);
3169 printk("\n");*/
3171 #else
3173 u8 queuetopipe[]={3,2,1,0,4,4,0,4,4};
3174 memcpy(priv->txqueue_to_outpipemap,queuetopipe,9);
3175 /* for(i=0;i<9;i++)
3176 printk("%d ",priv->txqueue_to_outpipemap[i]);
3177 printk("\n");*/
3179 #endif
3180 rtl8192_init_priv_variable(dev);
3181 rtl8192_init_priv_lock(priv);
3182 rtl8192_init_priv_task(dev);
3183 rtl8192_get_eeprom_size(dev);
3184 rtl8192_read_eeprom_info(dev);
3185 rtl8192_get_channel_map(dev);
3186 init_hal_dm(dev);
3187 init_timer(&priv->watch_dog_timer);
3188 priv->watch_dog_timer.data = (unsigned long)dev;
3189 priv->watch_dog_timer.function = watch_dog_timer_callback;
3190 if(rtl8192_usb_initendpoints(dev)!=0){
3191 DMESG("Endopoints initialization failed");
3192 return -ENOMEM;
3195 //rtl8192_adapter_start(dev);
3196 #ifdef DEBUG_EPROM
3197 dump_eprom(dev);
3198 #endif
3199 return 0;
3202 /******************************************************************************
3203 *function: This function actually only set RRSR, RATR and BW_OPMODE registers
3204 * not to do all the hw config as its name says
3205 * input: net_device dev
3206 * output: none
3207 * return: none
3208 * notice: This part need to modified according to the rate set we filtered
3209 * ****************************************************************************/
3210 void rtl8192_hwconfig(struct net_device* dev)
3212 u32 regRATR = 0, regRRSR = 0;
3213 u8 regBwOpMode = 0, regTmp = 0;
3214 struct r8192_priv *priv = ieee80211_priv(dev);
3216 // Set RRSR, RATR, and BW_OPMODE registers
3218 switch(priv->ieee80211->mode)
3220 case WIRELESS_MODE_B:
3221 regBwOpMode = BW_OPMODE_20MHZ;
3222 regRATR = RATE_ALL_CCK;
3223 regRRSR = RATE_ALL_CCK;
3224 break;
3225 case WIRELESS_MODE_A:
3226 regBwOpMode = BW_OPMODE_5G |BW_OPMODE_20MHZ;
3227 regRATR = RATE_ALL_OFDM_AG;
3228 regRRSR = RATE_ALL_OFDM_AG;
3229 break;
3230 case WIRELESS_MODE_G:
3231 regBwOpMode = BW_OPMODE_20MHZ;
3232 regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
3233 regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
3234 break;
3235 case WIRELESS_MODE_AUTO:
3236 #ifdef TO_DO_LIST
3237 if (Adapter->bInHctTest)
3239 regBwOpMode = BW_OPMODE_20MHZ;
3240 regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
3241 regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
3243 else
3244 #endif
3246 regBwOpMode = BW_OPMODE_20MHZ;
3247 regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
3248 regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
3250 break;
3251 case WIRELESS_MODE_N_24G:
3252 // It support CCK rate by default.
3253 // CCK rate will be filtered out only when associated AP does not support it.
3254 regBwOpMode = BW_OPMODE_20MHZ;
3255 regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
3256 regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
3257 break;
3258 case WIRELESS_MODE_N_5G:
3259 regBwOpMode = BW_OPMODE_5G;
3260 regRATR = RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
3261 regRRSR = RATE_ALL_OFDM_AG;
3262 break;
3265 write_nic_byte(dev, BW_OPMODE, regBwOpMode);
3267 u32 ratr_value = 0;
3268 ratr_value = regRATR;
3269 if (priv->rf_type == RF_1T2R)
3271 ratr_value &= ~(RATE_ALL_OFDM_2SS);
3273 write_nic_dword(dev, RATR0, ratr_value);
3274 write_nic_byte(dev, UFWP, 1);
3276 regTmp = read_nic_byte(dev, 0x313);
3277 regRRSR = ((regTmp) << 24) | (regRRSR & 0x00ffffff);
3278 write_nic_dword(dev, RRSR, regRRSR);
3281 // Set Retry Limit here
3283 write_nic_word(dev, RETRY_LIMIT,
3284 priv->ShortRetryLimit << RETRY_LIMIT_SHORT_SHIFT | \
3285 priv->LongRetryLimit << RETRY_LIMIT_LONG_SHIFT);
3286 // Set Contention Window here
3288 // Set Tx AGC
3290 // Set Tx Antenna including Feedback control
3292 // Set Auto Rate fallback control
3298 //InitializeAdapter and PhyCfg
3299 bool rtl8192_adapter_start(struct net_device *dev)
3301 struct r8192_priv *priv = ieee80211_priv(dev);
3302 u32 dwRegRead = 0;
3303 bool init_status = true;
3304 RT_TRACE(COMP_INIT, "====>%s()\n", __FUNCTION__);
3305 priv->Rf_Mode = RF_OP_By_SW_3wire;
3306 //for ASIC power on sequence
3307 write_nic_byte_E(dev, 0x5f, 0x80);
3308 mdelay(50);
3309 write_nic_byte_E(dev, 0x5f, 0xf0);
3310 write_nic_byte_E(dev, 0x5d, 0x00);
3311 write_nic_byte_E(dev, 0x5e, 0x80);
3312 write_nic_byte(dev, 0x17, 0x37);
3313 mdelay(10);
3314 //#ifdef TO_DO_LIST
3315 priv->pFirmware->firmware_status = FW_STATUS_0_INIT;
3316 //config CPUReset Register
3317 //Firmware Reset or not?
3318 dwRegRead = read_nic_dword(dev, CPU_GEN);
3319 if (priv->pFirmware->firmware_status == FW_STATUS_0_INIT)
3320 dwRegRead |= CPU_GEN_SYSTEM_RESET; //do nothing here?
3321 else if (priv->pFirmware->firmware_status == FW_STATUS_5_READY)
3322 dwRegRead |= CPU_GEN_FIRMWARE_RESET;
3323 else
3324 RT_TRACE(COMP_ERR, "ERROR in %s(): undefined firmware state(%d)\n", __FUNCTION__, priv->pFirmware->firmware_status);
3326 write_nic_dword(dev, CPU_GEN, dwRegRead);
3327 //mdelay(30);
3328 //config BB.
3329 rtl8192_BBConfig(dev);
3331 //Loopback mode or not
3332 priv->LoopbackMode = RTL819xU_NO_LOOPBACK;
3333 // priv->LoopbackMode = RTL819xU_MAC_LOOPBACK;
3335 dwRegRead = read_nic_dword(dev, CPU_GEN);
3336 if (priv->LoopbackMode == RTL819xU_NO_LOOPBACK)
3337 dwRegRead = ((dwRegRead & CPU_GEN_NO_LOOPBACK_MSK) | CPU_GEN_NO_LOOPBACK_SET);
3338 else if (priv->LoopbackMode == RTL819xU_MAC_LOOPBACK)
3339 dwRegRead |= CPU_CCK_LOOPBACK;
3340 else
3341 RT_TRACE(COMP_ERR, "Serious error in %s(): wrong loopback mode setting(%d)\n", __FUNCTION__, priv->LoopbackMode);
3343 write_nic_dword(dev, CPU_GEN, dwRegRead);
3345 //after reset cpu, we need wait for a seconds to write in register.
3346 udelay(500);
3348 //xiong add for new bitfile:usb suspend reset pin set to 1. //do we need?
3349 write_nic_byte_E(dev, 0x5f, (read_nic_byte_E(dev, 0x5f)|0x20));
3351 //Set Hardware
3352 rtl8192_hwconfig(dev);
3354 //turn on Tx/Rx
3355 write_nic_byte(dev, CMDR, CR_RE|CR_TE);
3357 //set IDR0 here
3358 write_nic_dword(dev, MAC0, ((u32*)dev->dev_addr)[0]);
3359 write_nic_word(dev, MAC4, ((u16*)(dev->dev_addr + 4))[0]);
3361 //set RCR
3362 write_nic_dword(dev, RCR, priv->ReceiveConfig);
3364 //Initialize Number of Reserved Pages in Firmware Queue
3365 write_nic_dword(dev, RQPN1, NUM_OF_PAGE_IN_FW_QUEUE_BK << RSVD_FW_QUEUE_PAGE_BK_SHIFT |\
3366 NUM_OF_PAGE_IN_FW_QUEUE_BE << RSVD_FW_QUEUE_PAGE_BE_SHIFT | \
3367 NUM_OF_PAGE_IN_FW_QUEUE_VI << RSVD_FW_QUEUE_PAGE_VI_SHIFT | \
3368 NUM_OF_PAGE_IN_FW_QUEUE_VO <<RSVD_FW_QUEUE_PAGE_VO_SHIFT);
3369 write_nic_dword(dev, RQPN2, NUM_OF_PAGE_IN_FW_QUEUE_MGNT << RSVD_FW_QUEUE_PAGE_MGNT_SHIFT |\
3370 NUM_OF_PAGE_IN_FW_QUEUE_CMD << RSVD_FW_QUEUE_PAGE_CMD_SHIFT);
3371 write_nic_dword(dev, RQPN3, APPLIED_RESERVED_QUEUE_IN_FW| \
3372 NUM_OF_PAGE_IN_FW_QUEUE_BCN<<RSVD_FW_QUEUE_PAGE_BCN_SHIFT
3373 // | NUM_OF_PAGE_IN_FW_QUEUE_PUB<<RSVD_FW_QUEUE_PAGE_PUB_SHIFT
3375 write_nic_dword(dev, RATR0+4*7, (RATE_ALL_OFDM_AG | RATE_ALL_CCK));
3377 //Set AckTimeout
3378 // TODO: (it value is only for FPGA version). need to be changed!!2006.12.18, by Emily
3379 write_nic_byte(dev, ACK_TIMEOUT, 0x30);
3381 // RT_TRACE(COMP_INIT, "%s():priv->ResetProgress is %d\n", __FUNCTION__,priv->ResetProgress);
3382 if(priv->ResetProgress == RESET_TYPE_NORESET)
3383 rtl8192_SetWirelessMode(dev, priv->ieee80211->mode);
3384 if(priv->ResetProgress == RESET_TYPE_NORESET){
3385 CamResetAllEntry(dev);
3387 u8 SECR_value = 0x0;
3388 SECR_value |= SCR_TxEncEnable;
3389 SECR_value |= SCR_RxDecEnable;
3390 SECR_value |= SCR_NoSKMC;
3391 write_nic_byte(dev, SECR, SECR_value);
3395 //Beacon related
3396 write_nic_word(dev, ATIMWND, 2);
3397 write_nic_word(dev, BCN_INTERVAL, 100);
3400 #define DEFAULT_EDCA 0x005e4332
3401 int i;
3402 for (i=0; i<QOS_QUEUE_NUM; i++)
3403 write_nic_dword(dev, WDCAPARA_ADD[i], DEFAULT_EDCA);
3405 #ifdef USB_RX_AGGREGATION_SUPPORT
3406 //3 For usb rx firmware aggregation control
3407 if(priv->ResetProgress == RESET_TYPE_NORESET)
3409 u32 ulValue;
3410 PRT_HIGH_THROUGHPUT pHTInfo = priv->ieee80211->pHTInfo;
3411 ulValue = (pHTInfo->UsbRxFwAggrEn<<24) | (pHTInfo->UsbRxFwAggrPageNum<<16) |
3412 (pHTInfo->UsbRxFwAggrPacketNum<<8) | (pHTInfo->UsbRxFwAggrTimeout);
3414 * If usb rx firmware aggregation is enabled,
3415 * when anyone of three threshold conditions above is reached,
3416 * firmware will send aggregated packet to driver.
3418 write_nic_dword(dev, 0x1a8, ulValue);
3419 priv->bCurrentRxAggrEnable = true;
3421 #endif
3423 rtl8192_phy_configmac(dev);
3425 if (priv->card_8192_version == (u8) VERSION_819xU_A)
3427 rtl8192_phy_getTxPower(dev);
3428 rtl8192_phy_setTxPower(dev, priv->chan);
3431 //Firmware download
3432 init_status = init_firmware(dev);
3433 if(!init_status)
3435 RT_TRACE(COMP_ERR,"ERR!!! %s(): Firmware download is failed\n", __FUNCTION__);
3436 return init_status;
3438 RT_TRACE(COMP_INIT, "%s():after firmware download\n", __FUNCTION__);
3440 #ifdef TO_DO_LIST
3441 if(Adapter->ResetProgress == RESET_TYPE_NORESET)
3443 if(pMgntInfo->RegRfOff == TRUE)
3444 { // User disable RF via registry.
3445 RT_TRACE((COMP_INIT|COMP_RF), DBG_LOUD, ("InitializeAdapter819xUsb(): Turn off RF for RegRfOff ----------\n"));
3446 MgntActSet_RF_State(Adapter, eRfOff, RF_CHANGE_BY_SW);
3447 // Those action will be discard in MgntActSet_RF_State because off the same state
3448 for(eRFPath = 0; eRFPath <pHalData->NumTotalRFPath; eRFPath++)
3449 PHY_SetRFReg(Adapter, (RF90_RADIO_PATH_E)eRFPath, 0x4, 0xC00, 0x0);
3451 else if(pMgntInfo->RfOffReason > RF_CHANGE_BY_PS)
3452 { // H/W or S/W RF OFF before sleep.
3453 RT_TRACE((COMP_INIT|COMP_RF), DBG_LOUD, ("InitializeAdapter819xUsb(): Turn off RF for RfOffReason(%d) ----------\n", pMgntInfo->RfOffReason));
3454 MgntActSet_RF_State(Adapter, eRfOff, pMgntInfo->RfOffReason);
3456 else
3458 pHalData->eRFPowerState = eRfOn;
3459 pMgntInfo->RfOffReason = 0;
3460 RT_TRACE((COMP_INIT|COMP_RF), DBG_LOUD, ("InitializeAdapter819xUsb(): RF is on ----------\n"));
3463 else
3465 if(pHalData->eRFPowerState == eRfOff)
3467 MgntActSet_RF_State(Adapter, eRfOff, pMgntInfo->RfOffReason);
3468 // Those action will be discard in MgntActSet_RF_State because off the same state
3469 for(eRFPath = 0; eRFPath <pHalData->NumTotalRFPath; eRFPath++)
3470 PHY_SetRFReg(Adapter, (RF90_RADIO_PATH_E)eRFPath, 0x4, 0xC00, 0x0);
3473 #endif
3474 //config RF.
3475 if(priv->ResetProgress == RESET_TYPE_NORESET){
3476 rtl8192_phy_RFConfig(dev);
3477 RT_TRACE(COMP_INIT, "%s():after phy RF config\n", __FUNCTION__);
3481 if(priv->ieee80211->FwRWRF)
3482 // We can force firmware to do RF-R/W
3483 priv->Rf_Mode = RF_OP_By_FW;
3484 else
3485 priv->Rf_Mode = RF_OP_By_SW_3wire;
3488 rtl8192_phy_updateInitGain(dev);
3489 /*--set CCK and OFDM Block "ON"--*/
3490 rtl8192_setBBreg(dev, rFPGA0_RFMOD, bCCKEn, 0x1);
3491 rtl8192_setBBreg(dev, rFPGA0_RFMOD, bOFDMEn, 0x1);
3493 if(priv->ResetProgress == RESET_TYPE_NORESET)
3495 //if D or C cut
3496 u8 tmpvalue = read_nic_byte(dev, 0x301);
3497 if(tmpvalue ==0x03)
3499 priv->bDcut = TRUE;
3500 RT_TRACE(COMP_POWER_TRACKING, "D-cut\n");
3502 else
3504 priv->bDcut = FALSE;
3505 RT_TRACE(COMP_POWER_TRACKING, "C-cut\n");
3507 dm_initialize_txpower_tracking(dev);
3509 if(priv->bDcut == TRUE)
3511 u32 i, TempCCk;
3512 u32 tmpRegA= rtl8192_QueryBBReg(dev,rOFDM0_XATxIQImbalance,bMaskDWord);
3513 // u32 tmpRegC= rtl8192_QueryBBReg(dev,rOFDM0_XCTxIQImbalance,bMaskDWord);
3514 for(i = 0; i<TxBBGainTableLength; i++)
3516 if(tmpRegA == priv->txbbgain_table[i].txbbgain_value)
3518 priv->rfa_txpowertrackingindex= (u8)i;
3519 priv->rfa_txpowertrackingindex_real= (u8)i;
3520 priv->rfa_txpowertracking_default= priv->rfa_txpowertrackingindex;
3521 break;
3525 TempCCk = rtl8192_QueryBBReg(dev, rCCK0_TxFilter1, bMaskByte2);
3527 for(i=0 ; i<CCKTxBBGainTableLength ; i++)
3530 if(TempCCk == priv->cck_txbbgain_table[i].ccktxbb_valuearray[0])
3532 priv->cck_present_attentuation_20Mdefault=(u8) i;
3533 break;
3536 priv->cck_present_attentuation_40Mdefault= 0;
3537 priv->cck_present_attentuation_difference= 0;
3538 priv->cck_present_attentuation = priv->cck_present_attentuation_20Mdefault;
3540 // pMgntInfo->bTXPowerTracking = FALSE;//TEMPLY DISABLE
3543 write_nic_byte(dev, 0x87, 0x0);
3546 return init_status;
3549 /* this configures registers for beacon tx and enables it via
3550 * rtl8192_beacon_tx_enable(). rtl8192_beacon_tx_disable() might
3551 * be used to stop beacon transmission
3553 /***************************************************************************
3554 -------------------------------NET STUFF---------------------------
3555 ***************************************************************************/
3557 static struct net_device_stats *rtl8192_stats(struct net_device *dev)
3559 struct r8192_priv *priv = ieee80211_priv(dev);
3561 return &priv->ieee80211->stats;
3564 bool
3565 HalTxCheckStuck819xUsb(
3566 struct net_device *dev
3569 struct r8192_priv *priv = ieee80211_priv(dev);
3570 u16 RegTxCounter = read_nic_word(dev, 0x128);
3571 bool bStuck = FALSE;
3572 RT_TRACE(COMP_RESET,"%s():RegTxCounter is %d,TxCounter is %d\n",__FUNCTION__,RegTxCounter,priv->TxCounter);
3573 if(priv->TxCounter==RegTxCounter)
3574 bStuck = TRUE;
3576 priv->TxCounter = RegTxCounter;
3578 return bStuck;
3582 * <Assumption: RT_TX_SPINLOCK is acquired.>
3583 * First added: 2006.11.19 by emily
3585 RESET_TYPE
3586 TxCheckStuck(struct net_device *dev)
3588 struct r8192_priv *priv = ieee80211_priv(dev);
3589 u8 QueueID;
3590 // PRT_TCB pTcb;
3591 // u8 ResetThreshold;
3592 bool bCheckFwTxCnt = false;
3593 //unsigned long flags;
3596 // Decide Stuch threshold according to current power save mode
3599 // RT_TRACE(COMP_RESET, " ==> TxCheckStuck()\n");
3600 // PlatformAcquireSpinLock(Adapter, RT_TX_SPINLOCK);
3601 // spin_lock_irqsave(&priv->ieee80211->lock,flags);
3602 for (QueueID = 0; QueueID<=BEACON_QUEUE;QueueID ++)
3604 if(QueueID == TXCMD_QUEUE)
3605 continue;
3606 #ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
3607 if((skb_queue_len(&priv->ieee80211->skb_waitQ[QueueID]) == 0) && (skb_queue_len(&priv->ieee80211->skb_aggQ[QueueID]) == 0) && (skb_queue_len(&priv->ieee80211->skb_drv_aggQ[QueueID]) == 0))
3608 #else
3609 if((skb_queue_len(&priv->ieee80211->skb_waitQ[QueueID]) == 0) && (skb_queue_len(&priv->ieee80211->skb_aggQ[QueueID]) == 0))
3610 #endif
3611 continue;
3613 bCheckFwTxCnt = true;
3615 // PlatformReleaseSpinLock(Adapter, RT_TX_SPINLOCK);
3616 // spin_unlock_irqrestore(&priv->ieee80211->lock,flags);
3617 // RT_TRACE(COMP_RESET,"bCheckFwTxCnt is %d\n",bCheckFwTxCnt);
3618 if(bCheckFwTxCnt)
3620 if(HalTxCheckStuck819xUsb(dev))
3622 RT_TRACE(COMP_RESET, "TxCheckStuck(): Fw indicates no Tx condition! \n");
3623 return RESET_TYPE_SILENT;
3626 return RESET_TYPE_NORESET;
3629 bool
3630 HalRxCheckStuck819xUsb(struct net_device *dev)
3632 u16 RegRxCounter = read_nic_word(dev, 0x130);
3633 struct r8192_priv *priv = ieee80211_priv(dev);
3634 bool bStuck = FALSE;
3635 static u8 rx_chk_cnt = 0;
3636 RT_TRACE(COMP_RESET,"%s(): RegRxCounter is %d,RxCounter is %d\n",__FUNCTION__,RegRxCounter,priv->RxCounter);
3637 // If rssi is small, we should check rx for long time because of bad rx.
3638 // or maybe it will continuous silent reset every 2 seconds.
3639 rx_chk_cnt++;
3640 if(priv->undecorated_smoothed_pwdb >= (RateAdaptiveTH_High+5))
3642 rx_chk_cnt = 0; //high rssi, check rx stuck right now.
3644 else if(priv->undecorated_smoothed_pwdb < (RateAdaptiveTH_High+5) &&
3645 ((priv->CurrentChannelBW!=HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb>=RateAdaptiveTH_Low_40M) ||
3646 (priv->CurrentChannelBW==HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb>=RateAdaptiveTH_Low_20M)) )
3648 if(rx_chk_cnt < 2)
3650 return bStuck;
3652 else
3654 rx_chk_cnt = 0;
3657 else if(((priv->CurrentChannelBW!=HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb<RateAdaptiveTH_Low_40M) ||
3658 (priv->CurrentChannelBW==HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb<RateAdaptiveTH_Low_20M)) &&
3659 priv->undecorated_smoothed_pwdb >= VeryLowRSSI)
3661 if(rx_chk_cnt < 4)
3663 //DbgPrint("RSSI < %d && RSSI >= %d, no check this time \n", RateAdaptiveTH_Low, VeryLowRSSI);
3664 return bStuck;
3666 else
3668 rx_chk_cnt = 0;
3669 //DbgPrint("RSSI < %d && RSSI >= %d, check this time \n", RateAdaptiveTH_Low, VeryLowRSSI);
3672 else
3674 if(rx_chk_cnt < 8)
3676 //DbgPrint("RSSI <= %d, no check this time \n", VeryLowRSSI);
3677 return bStuck;
3679 else
3681 rx_chk_cnt = 0;
3682 //DbgPrint("RSSI <= %d, check this time \n", VeryLowRSSI);
3686 if(priv->RxCounter==RegRxCounter)
3687 bStuck = TRUE;
3689 priv->RxCounter = RegRxCounter;
3691 return bStuck;
3694 RESET_TYPE
3695 RxCheckStuck(struct net_device *dev)
3697 struct r8192_priv *priv = ieee80211_priv(dev);
3698 //int i;
3699 bool bRxCheck = FALSE;
3701 // RT_TRACE(COMP_RESET," ==> RxCheckStuck()\n");
3702 //PlatformAcquireSpinLock(Adapter, RT_RX_SPINLOCK);
3704 if(priv->IrpPendingCount > 1)
3705 bRxCheck = TRUE;
3706 //PlatformReleaseSpinLock(Adapter, RT_RX_SPINLOCK);
3708 // RT_TRACE(COMP_RESET,"bRxCheck is %d \n",bRxCheck);
3709 if(bRxCheck)
3711 if(HalRxCheckStuck819xUsb(dev))
3713 RT_TRACE(COMP_RESET, "RxStuck Condition\n");
3714 return RESET_TYPE_SILENT;
3717 return RESET_TYPE_NORESET;
3722 * This function is called by Checkforhang to check whether we should ask OS to reset driver
3724 * \param pAdapter The adapter context for this miniport
3726 * Note:NIC with USB interface sholud not call this function because we cannot scan descriptor
3727 * to judge whether there is tx stuck.
3728 * Note: This function may be required to be rewrite for Vista OS.
3729 * <<<Assumption: Tx spinlock has been acquired >>>
3731 * 8185 and 8185b does not implement this function. This is added by Emily at 2006.11.24
3733 RESET_TYPE
3734 rtl819x_ifcheck_resetornot(struct net_device *dev)
3736 struct r8192_priv *priv = ieee80211_priv(dev);
3737 RESET_TYPE TxResetType = RESET_TYPE_NORESET;
3738 RESET_TYPE RxResetType = RESET_TYPE_NORESET;
3739 RT_RF_POWER_STATE rfState;
3741 rfState = priv->ieee80211->eRFPowerState;
3743 TxResetType = TxCheckStuck(dev);
3744 if( rfState != eRfOff ||
3745 /*ADAPTER_TEST_STATUS_FLAG(Adapter, ADAPTER_STATUS_FW_DOWNLOAD_FAILURE)) &&*/
3746 (priv->ieee80211->iw_mode != IW_MODE_ADHOC))
3748 // If driver is in the status of firmware download failure , driver skips RF initialization and RF is
3749 // in turned off state. Driver should check whether Rx stuck and do silent reset. And
3750 // if driver is in firmware download failure status, driver should initialize RF in the following
3751 // silent reset procedure Emily, 2008.01.21
3753 // Driver should not check RX stuck in IBSS mode because it is required to
3754 // set Check BSSID in order to send beacon, however, if check BSSID is
3755 // set, STA cannot hear any packet a all. Emily, 2008.04.12
3756 RxResetType = RxCheckStuck(dev);
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 RT_TRACE(COMP_RESET,"%s():silent reset\n",__FUNCTION__);
3762 return RESET_TYPE_SILENT;
3764 else
3765 return RESET_TYPE_NORESET;
3769 void rtl8192_cancel_deferred_work(struct r8192_priv* priv);
3770 int _rtl8192_up(struct net_device *dev);
3771 int rtl8192_close(struct net_device *dev);
3775 void
3776 CamRestoreAllEntry( struct net_device *dev)
3778 u8 EntryId = 0;
3779 struct r8192_priv *priv = ieee80211_priv(dev);
3780 u8* MacAddr = priv->ieee80211->current_network.bssid;
3782 static u8 CAM_CONST_ADDR[4][6] = {
3783 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
3784 {0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
3785 {0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
3786 {0x00, 0x00, 0x00, 0x00, 0x00, 0x03}};
3787 static u8 CAM_CONST_BROAD[] =
3788 {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
3790 RT_TRACE(COMP_SEC, "CamRestoreAllEntry: \n");
3793 if ((priv->ieee80211->pairwise_key_type == KEY_TYPE_WEP40)||
3794 (priv->ieee80211->pairwise_key_type == KEY_TYPE_WEP104))
3797 for(EntryId=0; EntryId<4; EntryId++)
3800 MacAddr = CAM_CONST_ADDR[EntryId];
3801 setKey(dev,
3802 EntryId ,
3803 EntryId,
3804 priv->ieee80211->pairwise_key_type,
3805 MacAddr,
3807 NULL);
3812 else if(priv->ieee80211->pairwise_key_type == KEY_TYPE_TKIP)
3816 if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
3817 setKey(dev,
3820 priv->ieee80211->pairwise_key_type,
3821 (u8*)dev->dev_addr,
3823 NULL);
3824 else
3825 setKey(dev,
3828 priv->ieee80211->pairwise_key_type,
3829 MacAddr,
3831 NULL);
3834 else if(priv->ieee80211->pairwise_key_type == KEY_TYPE_CCMP)
3838 if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
3839 setKey(dev,
3842 priv->ieee80211->pairwise_key_type,
3843 (u8*)dev->dev_addr,
3845 NULL);
3846 else
3847 setKey(dev,
3850 priv->ieee80211->pairwise_key_type,
3851 MacAddr,
3853 NULL);
3859 if(priv->ieee80211->group_key_type == KEY_TYPE_TKIP)
3861 MacAddr = CAM_CONST_BROAD;
3862 for(EntryId=1 ; EntryId<4 ; EntryId++)
3865 setKey(dev,
3866 EntryId,
3867 EntryId,
3868 priv->ieee80211->group_key_type,
3869 MacAddr,
3871 NULL);
3874 if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
3875 setKey(dev,
3878 priv->ieee80211->group_key_type,
3879 CAM_CONST_ADDR[0],
3881 NULL);
3883 else if(priv->ieee80211->group_key_type == KEY_TYPE_CCMP)
3885 MacAddr = CAM_CONST_BROAD;
3886 for(EntryId=1; EntryId<4 ; EntryId++)
3889 setKey(dev,
3890 EntryId ,
3891 EntryId,
3892 priv->ieee80211->group_key_type,
3893 MacAddr,
3895 NULL);
3899 if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
3900 setKey(dev,
3903 priv->ieee80211->group_key_type,
3904 CAM_CONST_ADDR[0],
3906 NULL);
3909 //////////////////////////////////////////////////////////////
3910 // This function is used to fix Tx/Rx stop bug temporarily.
3911 // This function will do "system reset" to NIC when Tx or Rx is stuck.
3912 // The method checking Tx/Rx stuck of this function is supported by FW,
3913 // which reports Tx and Rx counter to register 0x128 and 0x130.
3914 //////////////////////////////////////////////////////////////
3915 void
3916 rtl819x_ifsilentreset(struct net_device *dev)
3918 //OCTET_STRING asocpdu;
3919 struct r8192_priv *priv = ieee80211_priv(dev);
3920 u8 reset_times = 0;
3921 int reset_status = 0;
3922 struct ieee80211_device *ieee = priv->ieee80211;
3925 // 2007.07.20. If we need to check CCK stop, please uncomment this line.
3926 //bStuck = Adapter->HalFunc.CheckHWStopHandler(Adapter);
3928 if(priv->ResetProgress==RESET_TYPE_NORESET)
3930 RESET_START:
3932 RT_TRACE(COMP_RESET,"=========>Reset progress!! \n");
3934 // Set the variable for reset.
3935 priv->ResetProgress = RESET_TYPE_SILENT;
3936 // rtl8192_close(dev);
3937 down(&priv->wx_sem);
3938 if(priv->up == 0)
3940 RT_TRACE(COMP_ERR,"%s():the driver is not up! return\n",__FUNCTION__);
3941 up(&priv->wx_sem);
3942 return ;
3944 priv->up = 0;
3945 RT_TRACE(COMP_RESET,"%s():======>start to down the driver\n",__FUNCTION__);
3946 // if(!netif_queue_stopped(dev))
3947 // netif_stop_queue(dev);
3949 rtl8192_rtx_disable(dev);
3950 rtl8192_cancel_deferred_work(priv);
3951 deinit_hal_dm(dev);
3952 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 netif_carrier_off(dev);
3964 up(&ieee->wx_sem);
3966 else{
3967 printk("ieee->state is NOT LINKED\n");
3968 ieee80211_softmac_stop_protocol(priv->ieee80211); }
3969 up(&priv->wx_sem);
3970 RT_TRACE(COMP_RESET,"%s():<==========down process is finished\n",__FUNCTION__);
3971 //rtl8192_irq_disable(dev);
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 == -EAGAIN)
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 ieee->is_silent_reset = 1;
3989 EnableHWSecurityConfig8192(dev);
3990 if(ieee->state == IEEE80211_LINKED && ieee->iw_mode == IW_MODE_INFRA)
3992 ieee->set_chan(ieee->dev, ieee->current_network.channel);
3994 queue_work(ieee->wq, &ieee->associate_complete_wq);
3997 else if(ieee->state == IEEE80211_LINKED && ieee->iw_mode == IW_MODE_ADHOC)
3999 ieee->set_chan(ieee->dev, ieee->current_network.channel);
4000 ieee->link_change(ieee->dev);
4002 // notify_wx_assoc_event(ieee);
4004 ieee80211_start_send_beacons(ieee);
4006 if (ieee->data_hard_resume)
4007 ieee->data_hard_resume(ieee->dev);
4008 netif_carrier_on(ieee->dev);
4011 CamRestoreAllEntry(dev);
4013 priv->ResetProgress = RESET_TYPE_NORESET;
4014 priv->reset_count++;
4016 priv->bForcedSilentReset =false;
4017 priv->bResetInProgress = false;
4019 // For test --> force write UFWP.
4020 write_nic_byte(dev, UFWP, 1);
4021 RT_TRACE(COMP_RESET, "Reset finished!! ====>[%d]\n", priv->reset_count);
4025 void CAM_read_entry(
4026 struct net_device *dev,
4027 u32 iIndex
4030 u32 target_command=0;
4031 u32 target_content=0;
4032 u8 entry_i=0;
4033 u32 ulStatus;
4034 s32 i=100;
4035 // printk("=======>start read CAM\n");
4036 for(entry_i=0;entry_i<CAM_CONTENT_COUNT;entry_i++)
4038 // polling bit, and No Write enable, and address
4039 target_command= entry_i+CAM_CONTENT_COUNT*iIndex;
4040 target_command= target_command | BIT31;
4042 //Check polling bit is clear
4043 // mdelay(1);
4044 while((i--)>=0)
4046 ulStatus = read_nic_dword(dev, RWCAM);
4047 if(ulStatus & BIT31){
4048 continue;
4050 else{
4051 break;
4054 write_nic_dword(dev, RWCAM, target_command);
4055 RT_TRACE(COMP_SEC,"CAM_read_entry(): WRITE A0: %x \n",target_command);
4056 // printk("CAM_read_entry(): WRITE A0: %lx \n",target_command);
4057 target_content = read_nic_dword(dev, RCAMO);
4058 RT_TRACE(COMP_SEC, "CAM_read_entry(): WRITE A8: %x \n",target_content);
4059 // printk("CAM_read_entry(): WRITE A8: %lx \n",target_content);
4061 printk("\n");
4064 void rtl819x_update_rxcounts(
4065 struct r8192_priv *priv,
4066 u32* TotalRxBcnNum,
4067 u32* TotalRxDataNum
4070 u16 SlotIndex;
4071 u8 i;
4073 *TotalRxBcnNum = 0;
4074 *TotalRxDataNum = 0;
4076 SlotIndex = (priv->ieee80211->LinkDetectInfo.SlotIndex++)%(priv->ieee80211->LinkDetectInfo.SlotNum);
4077 priv->ieee80211->LinkDetectInfo.RxBcnNum[SlotIndex] = priv->ieee80211->LinkDetectInfo.NumRecvBcnInPeriod;
4078 priv->ieee80211->LinkDetectInfo.RxDataNum[SlotIndex] = priv->ieee80211->LinkDetectInfo.NumRecvDataInPeriod;
4079 for( i=0; i<priv->ieee80211->LinkDetectInfo.SlotNum; i++ ){
4080 *TotalRxBcnNum += priv->ieee80211->LinkDetectInfo.RxBcnNum[i];
4081 *TotalRxDataNum += priv->ieee80211->LinkDetectInfo.RxDataNum[i];
4086 extern void rtl819x_watchdog_wqcallback(struct work_struct *work)
4088 struct delayed_work *dwork = container_of(work,struct delayed_work,work);
4089 struct r8192_priv *priv = container_of(dwork,struct r8192_priv,watch_dog_wq);
4090 struct net_device *dev = priv->ieee80211->dev;
4091 struct ieee80211_device* ieee = priv->ieee80211;
4092 RESET_TYPE ResetType = RESET_TYPE_NORESET;
4093 static u8 check_reset_cnt=0;
4094 bool bBusyTraffic = false;
4096 if(!priv->up)
4097 return;
4098 hal_dm_watchdog(dev);
4100 {//to get busy traffic condition
4101 if(ieee->state == IEEE80211_LINKED)
4103 if( ieee->LinkDetectInfo.NumRxOkInPeriod> 666 ||
4104 ieee->LinkDetectInfo.NumTxOkInPeriod> 666 ) {
4105 bBusyTraffic = true;
4107 ieee->LinkDetectInfo.NumRxOkInPeriod = 0;
4108 ieee->LinkDetectInfo.NumTxOkInPeriod = 0;
4109 ieee->LinkDetectInfo.bBusyTraffic = bBusyTraffic;
4112 //added by amy for AP roaming
4114 if(priv->ieee80211->state == IEEE80211_LINKED && priv->ieee80211->iw_mode == IW_MODE_INFRA)
4116 u32 TotalRxBcnNum = 0;
4117 u32 TotalRxDataNum = 0;
4119 rtl819x_update_rxcounts(priv, &TotalRxBcnNum, &TotalRxDataNum);
4120 if((TotalRxBcnNum+TotalRxDataNum) == 0)
4122 #ifdef TODO
4123 if(rfState == eRfOff)
4124 RT_TRACE(COMP_ERR,"========>%s()\n",__FUNCTION__);
4125 #endif
4126 printk("===>%s(): AP is power off,connect another one\n",__FUNCTION__);
4127 // Dot11d_Reset(dev);
4128 priv->ieee80211->state = IEEE80211_ASSOCIATING;
4129 notify_wx_assoc_event(priv->ieee80211);
4130 RemovePeerTS(priv->ieee80211,priv->ieee80211->current_network.bssid);
4131 priv->ieee80211->link_change(dev);
4132 queue_work(priv->ieee80211->wq, &priv->ieee80211->associate_procedure_wq);
4136 priv->ieee80211->LinkDetectInfo.NumRecvBcnInPeriod=0;
4137 priv->ieee80211->LinkDetectInfo.NumRecvDataInPeriod=0;
4139 // CAM_read_entry(dev,4);
4140 //check if reset the driver
4141 if(check_reset_cnt++ >= 3)
4143 ResetType = rtl819x_ifcheck_resetornot(dev);
4144 check_reset_cnt = 3;
4145 //DbgPrint("Start to check silent reset\n");
4147 // RT_TRACE(COMP_RESET,"%s():priv->force_reset is %d,priv->ResetProgress is %d, priv->bForcedSilentReset is %d,priv->bDisableNormalResetCheck is %d,ResetType is %d\n",__FUNCTION__,priv->force_reset,priv->ResetProgress,priv->bForcedSilentReset,priv->bDisableNormalResetCheck,ResetType);
4148 if( (priv->force_reset) || (priv->ResetProgress==RESET_TYPE_NORESET &&
4149 (priv->bForcedSilentReset ||
4150 (!priv->bDisableNormalResetCheck && ResetType==RESET_TYPE_SILENT)))) // This is control by OID set in Pomelo
4152 RT_TRACE(COMP_RESET,"%s():priv->force_reset is %d,priv->ResetProgress is %d, priv->bForcedSilentReset is %d,priv->bDisableNormalResetCheck is %d,ResetType is %d\n",__FUNCTION__,priv->force_reset,priv->ResetProgress,priv->bForcedSilentReset,priv->bDisableNormalResetCheck,ResetType);
4153 rtl819x_ifsilentreset(dev);
4155 priv->force_reset = false;
4156 priv->bForcedSilentReset = false;
4157 priv->bResetInProgress = false;
4158 RT_TRACE(COMP_TRACE, " <==RtUsbCheckForHangWorkItemCallback()\n");
4162 void watch_dog_timer_callback(unsigned long data)
4164 struct r8192_priv *priv = ieee80211_priv((struct net_device *) data);
4165 //printk("===============>watch_dog timer\n");
4166 queue_delayed_work(priv->priv_wq,&priv->watch_dog_wq, 0);
4167 mod_timer(&priv->watch_dog_timer, jiffies + MSECS(IEEE80211_WATCH_DOG_TIME));
4169 int _rtl8192_up(struct net_device *dev)
4171 struct r8192_priv *priv = ieee80211_priv(dev);
4172 //int i;
4173 int init_status = 0;
4174 priv->up=1;
4175 priv->ieee80211->ieee_up=1;
4176 RT_TRACE(COMP_INIT, "Bringing up iface");
4177 init_status = rtl8192_adapter_start(dev);
4178 if(!init_status)
4180 RT_TRACE(COMP_ERR,"ERR!!! %s(): initialization is failed!\n", __FUNCTION__);
4181 priv->up=priv->ieee80211->ieee_up = 0;
4182 return -EAGAIN;
4184 RT_TRACE(COMP_INIT, "start adapter finished\n");
4185 rtl8192_rx_enable(dev);
4186 // rtl8192_tx_enable(dev);
4187 if(priv->ieee80211->state != IEEE80211_LINKED)
4188 ieee80211_softmac_start_protocol(priv->ieee80211);
4189 ieee80211_reset_queue(priv->ieee80211);
4190 watch_dog_timer_callback((unsigned long) dev);
4191 if(!netif_queue_stopped(dev))
4192 netif_start_queue(dev);
4193 else
4194 netif_wake_queue(dev);
4196 return 0;
4200 int rtl8192_open(struct net_device *dev)
4202 struct r8192_priv *priv = ieee80211_priv(dev);
4203 int ret;
4204 down(&priv->wx_sem);
4205 ret = rtl8192_up(dev);
4206 up(&priv->wx_sem);
4207 return ret;
4212 int rtl8192_up(struct net_device *dev)
4214 struct r8192_priv *priv = ieee80211_priv(dev);
4216 if (priv->up == 1) return -1;
4218 return _rtl8192_up(dev);
4222 int rtl8192_close(struct net_device *dev)
4224 struct r8192_priv *priv = ieee80211_priv(dev);
4225 int ret;
4227 down(&priv->wx_sem);
4229 ret = rtl8192_down(dev);
4231 up(&priv->wx_sem);
4233 return ret;
4237 int rtl8192_down(struct net_device *dev)
4239 struct r8192_priv *priv = ieee80211_priv(dev);
4240 int i;
4242 if (priv->up == 0) return -1;
4244 priv->up=0;
4245 priv->ieee80211->ieee_up = 0;
4246 RT_TRACE(COMP_DOWN, "==========>%s()\n", __FUNCTION__);
4247 /* FIXME */
4248 if (!netif_queue_stopped(dev))
4249 netif_stop_queue(dev);
4251 rtl8192_rtx_disable(dev);
4252 //rtl8192_irq_disable(dev);
4254 /* Tx related queue release */
4255 for(i = 0; i < MAX_QUEUE_SIZE; i++) {
4256 skb_queue_purge(&priv->ieee80211->skb_waitQ [i]);
4258 for(i = 0; i < MAX_QUEUE_SIZE; i++) {
4259 skb_queue_purge(&priv->ieee80211->skb_aggQ [i]);
4262 for(i = 0; i < MAX_QUEUE_SIZE; i++) {
4263 skb_queue_purge(&priv->ieee80211->skb_drv_aggQ [i]);
4266 //as cancel_delayed_work will del work->timer, so if work is not definedas struct delayed_work, it will corrupt
4267 // flush_scheduled_work();
4268 rtl8192_cancel_deferred_work(priv);
4269 deinit_hal_dm(dev);
4270 del_timer_sync(&priv->watch_dog_timer);
4273 ieee80211_softmac_stop_protocol(priv->ieee80211);
4274 memset(&priv->ieee80211->current_network, 0 , offsetof(struct ieee80211_network, list));
4275 RT_TRACE(COMP_DOWN, "<==========%s()\n", __FUNCTION__);
4277 return 0;
4281 void rtl8192_commit(struct net_device *dev)
4283 struct r8192_priv *priv = ieee80211_priv(dev);
4284 int reset_status = 0;
4285 //u8 reset_times = 0;
4286 if (priv->up == 0) return ;
4287 priv->up = 0;
4289 rtl8192_cancel_deferred_work(priv);
4290 del_timer_sync(&priv->watch_dog_timer);
4291 //cancel_delayed_work(&priv->SwChnlWorkItem);
4293 ieee80211_softmac_stop_protocol(priv->ieee80211);
4295 //rtl8192_irq_disable(dev);
4296 rtl8192_rtx_disable(dev);
4297 reset_status = _rtl8192_up(dev);
4302 void rtl8192_restart(struct net_device *dev)
4304 struct r8192_priv *priv = ieee80211_priv(dev);
4306 void rtl8192_restart(struct work_struct *work)
4308 struct r8192_priv *priv = container_of(work, struct r8192_priv, reset_wq);
4309 struct net_device *dev = priv->ieee80211->dev;
4311 down(&priv->wx_sem);
4313 rtl8192_commit(dev);
4315 up(&priv->wx_sem);
4318 static void r8192_set_multicast(struct net_device *dev)
4320 struct r8192_priv *priv = ieee80211_priv(dev);
4321 short promisc;
4323 //down(&priv->wx_sem);
4325 /* FIXME FIXME */
4327 promisc = (dev->flags & IFF_PROMISC) ? 1:0;
4329 if (promisc != priv->promisc)
4330 // rtl8192_commit(dev);
4332 priv->promisc = promisc;
4334 //schedule_work(&priv->reset_wq);
4335 //up(&priv->wx_sem);
4339 int r8192_set_mac_adr(struct net_device *dev, void *mac)
4341 struct r8192_priv *priv = ieee80211_priv(dev);
4342 struct sockaddr *addr = mac;
4344 down(&priv->wx_sem);
4346 memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
4348 schedule_work(&priv->reset_wq);
4349 up(&priv->wx_sem);
4351 return 0;
4354 /* based on ipw2200 driver */
4355 int rtl8192_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
4357 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
4358 struct iwreq *wrq = (struct iwreq *)rq;
4359 int ret=-1;
4360 struct ieee80211_device *ieee = priv->ieee80211;
4361 u32 key[4];
4362 u8 broadcast_addr[6] = {0xff,0xff,0xff,0xff,0xff,0xff};
4363 struct iw_point *p = &wrq->u.data;
4364 struct ieee_param *ipw = NULL;//(struct ieee_param *)wrq->u.data.pointer;
4366 down(&priv->wx_sem);
4369 if (p->length < sizeof(struct ieee_param) || !p->pointer){
4370 ret = -EINVAL;
4371 goto out;
4374 ipw = kmalloc(p->length, GFP_KERNEL);
4375 if (ipw == NULL){
4376 ret = -ENOMEM;
4377 goto out;
4379 if (copy_from_user(ipw, p->pointer, p->length)) {
4380 kfree(ipw);
4381 ret = -EFAULT;
4382 goto out;
4385 switch (cmd) {
4386 case RTL_IOCTL_WPA_SUPPLICANT:
4387 //parse here for HW security
4388 if (ipw->cmd == IEEE_CMD_SET_ENCRYPTION)
4390 if (ipw->u.crypt.set_tx)
4392 if (strcmp(ipw->u.crypt.alg, "CCMP") == 0)
4393 ieee->pairwise_key_type = KEY_TYPE_CCMP;
4394 else if (strcmp(ipw->u.crypt.alg, "TKIP") == 0)
4395 ieee->pairwise_key_type = KEY_TYPE_TKIP;
4396 else if (strcmp(ipw->u.crypt.alg, "WEP") == 0)
4398 if (ipw->u.crypt.key_len == 13)
4399 ieee->pairwise_key_type = KEY_TYPE_WEP104;
4400 else if (ipw->u.crypt.key_len == 5)
4401 ieee->pairwise_key_type = KEY_TYPE_WEP40;
4403 else
4404 ieee->pairwise_key_type = KEY_TYPE_NA;
4406 if (ieee->pairwise_key_type)
4408 memcpy((u8*)key, ipw->u.crypt.key, 16);
4409 EnableHWSecurityConfig8192(dev);
4410 //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!
4411 //added by WB.
4412 setKey(dev, 4, ipw->u.crypt.idx, ieee->pairwise_key_type, (u8*)ieee->ap_mac_addr, 0, key);
4413 if (ieee->auth_mode != 2)
4414 setKey(dev, ipw->u.crypt.idx, ipw->u.crypt.idx, ieee->pairwise_key_type, (u8*)ieee->ap_mac_addr, 0, key);
4417 else //if (ipw->u.crypt.idx) //group key use idx > 0
4419 memcpy((u8*)key, ipw->u.crypt.key, 16);
4420 if (strcmp(ipw->u.crypt.alg, "CCMP") == 0)
4421 ieee->group_key_type= KEY_TYPE_CCMP;
4422 else if (strcmp(ipw->u.crypt.alg, "TKIP") == 0)
4423 ieee->group_key_type = KEY_TYPE_TKIP;
4424 else if (strcmp(ipw->u.crypt.alg, "WEP") == 0)
4426 if (ipw->u.crypt.key_len == 13)
4427 ieee->group_key_type = KEY_TYPE_WEP104;
4428 else if (ipw->u.crypt.key_len == 5)
4429 ieee->group_key_type = KEY_TYPE_WEP40;
4431 else
4432 ieee->group_key_type = KEY_TYPE_NA;
4434 if (ieee->group_key_type)
4436 setKey( dev,
4437 ipw->u.crypt.idx,
4438 ipw->u.crypt.idx, //KeyIndex
4439 ieee->group_key_type, //KeyType
4440 broadcast_addr, //MacAddr
4441 0, //DefaultKey
4442 key); //KeyContent
4446 #ifdef JOHN_HWSEC_DEBUG
4447 //john's test 0711
4448 printk("@@ wrq->u pointer = ");
4449 for(i=0;i<wrq->u.data.length;i++){
4450 if(i%10==0) printk("\n");
4451 printk( "%8x|", ((u32*)wrq->u.data.pointer)[i] );
4453 printk("\n");
4454 #endif /*JOHN_HWSEC_DEBUG*/
4455 ret = ieee80211_wpa_supplicant_ioctl(priv->ieee80211, &wrq->u.data);
4456 break;
4458 default:
4459 ret = -EOPNOTSUPP;
4460 break;
4462 kfree(ipw);
4463 ipw = NULL;
4464 out:
4465 up(&priv->wx_sem);
4466 return ret;
4469 u8 HwRateToMRate90(bool bIsHT, u8 rate)
4471 u8 ret_rate = 0xff;
4473 if(!bIsHT) {
4474 switch(rate) {
4475 case DESC90_RATE1M: ret_rate = MGN_1M; break;
4476 case DESC90_RATE2M: ret_rate = MGN_2M; break;
4477 case DESC90_RATE5_5M: ret_rate = MGN_5_5M; break;
4478 case DESC90_RATE11M: ret_rate = MGN_11M; break;
4479 case DESC90_RATE6M: ret_rate = MGN_6M; break;
4480 case DESC90_RATE9M: ret_rate = MGN_9M; break;
4481 case DESC90_RATE12M: ret_rate = MGN_12M; break;
4482 case DESC90_RATE18M: ret_rate = MGN_18M; break;
4483 case DESC90_RATE24M: ret_rate = MGN_24M; break;
4484 case DESC90_RATE36M: ret_rate = MGN_36M; break;
4485 case DESC90_RATE48M: ret_rate = MGN_48M; break;
4486 case DESC90_RATE54M: ret_rate = MGN_54M; break;
4488 default:
4489 ret_rate = 0xff;
4490 RT_TRACE(COMP_RECV, "HwRateToMRate90(): Non supported Rate [%x], bIsHT = %d!!!\n", rate, bIsHT);
4491 break;
4494 } else {
4495 switch(rate) {
4496 case DESC90_RATEMCS0: ret_rate = MGN_MCS0; break;
4497 case DESC90_RATEMCS1: ret_rate = MGN_MCS1; break;
4498 case DESC90_RATEMCS2: ret_rate = MGN_MCS2; break;
4499 case DESC90_RATEMCS3: ret_rate = MGN_MCS3; break;
4500 case DESC90_RATEMCS4: ret_rate = MGN_MCS4; break;
4501 case DESC90_RATEMCS5: ret_rate = MGN_MCS5; break;
4502 case DESC90_RATEMCS6: ret_rate = MGN_MCS6; break;
4503 case DESC90_RATEMCS7: ret_rate = MGN_MCS7; break;
4504 case DESC90_RATEMCS8: ret_rate = MGN_MCS8; break;
4505 case DESC90_RATEMCS9: ret_rate = MGN_MCS9; break;
4506 case DESC90_RATEMCS10: ret_rate = MGN_MCS10; break;
4507 case DESC90_RATEMCS11: ret_rate = MGN_MCS11; break;
4508 case DESC90_RATEMCS12: ret_rate = MGN_MCS12; break;
4509 case DESC90_RATEMCS13: ret_rate = MGN_MCS13; break;
4510 case DESC90_RATEMCS14: ret_rate = MGN_MCS14; break;
4511 case DESC90_RATEMCS15: ret_rate = MGN_MCS15; break;
4512 case DESC90_RATEMCS32: ret_rate = (0x80|0x20); break;
4514 default:
4515 ret_rate = 0xff;
4516 RT_TRACE(COMP_RECV, "HwRateToMRate90(): Non supported Rate [%x], bIsHT = %d!!!\n",rate, bIsHT);
4517 break;
4521 return ret_rate;
4525 * Function: UpdateRxPktTimeStamp
4526 * Overview: Recored down the TSF time stamp when receiving a packet
4528 * Input:
4529 * PADAPTER Adapter
4530 * PRT_RFD pRfd,
4532 * Output:
4533 * PRT_RFD pRfd
4534 * (pRfd->Status.TimeStampHigh is updated)
4535 * (pRfd->Status.TimeStampLow is updated)
4536 * Return:
4537 * None
4539 void UpdateRxPktTimeStamp8190 (struct net_device *dev, struct ieee80211_rx_stats *stats)
4541 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
4543 if(stats->bIsAMPDU && !stats->bFirstMPDU) {
4544 stats->mac_time[0] = priv->LastRxDescTSFLow;
4545 stats->mac_time[1] = priv->LastRxDescTSFHigh;
4546 } else {
4547 priv->LastRxDescTSFLow = stats->mac_time[0];
4548 priv->LastRxDescTSFHigh = stats->mac_time[1];
4552 //by amy 080606
4554 long rtl819x_translate_todbm(u8 signal_strength_index )// 0-100 index.
4556 long signal_power; // in dBm.
4558 // Translate to dBm (x=0.5y-95).
4559 signal_power = (long)((signal_strength_index + 1) >> 1);
4560 signal_power -= 95;
4562 return signal_power;
4566 /* 2008/01/22 MH We can not delcare RSSI/EVM total value of sliding window to
4567 be a local static. Otherwise, it may increase when we return from S3/S4. The
4568 value will be kept in memory or disk. We must delcare the value in adapter
4569 and it will be reinitialized when return from S3/S4. */
4570 void rtl8192_process_phyinfo(struct r8192_priv * priv,u8* buffer, struct ieee80211_rx_stats * pprevious_stats, struct ieee80211_rx_stats * pcurrent_stats)
4572 bool bcheck = false;
4573 u8 rfpath;
4574 u32 nspatial_stream, tmp_val;
4575 //u8 i;
4576 static u32 slide_rssi_index=0, slide_rssi_statistics=0;
4577 static u32 slide_evm_index=0, slide_evm_statistics=0;
4578 static u32 last_rssi=0, last_evm=0;
4580 static u32 slide_beacon_adc_pwdb_index=0, slide_beacon_adc_pwdb_statistics=0;
4581 static u32 last_beacon_adc_pwdb=0;
4583 struct ieee80211_hdr_3addr *hdr;
4584 u16 sc ;
4585 unsigned int frag,seq;
4586 hdr = (struct ieee80211_hdr_3addr *)buffer;
4587 sc = le16_to_cpu(hdr->seq_ctl);
4588 frag = WLAN_GET_SEQ_FRAG(sc);
4589 seq = WLAN_GET_SEQ_SEQ(sc);
4590 //cosa add 04292008 to record the sequence number
4591 pcurrent_stats->Seq_Num = seq;
4593 // Check whether we should take the previous packet into accounting
4595 if(!pprevious_stats->bIsAMPDU)
4597 // if previous packet is not aggregated packet
4598 bcheck = true;
4599 }else
4604 if(slide_rssi_statistics++ >= PHY_RSSI_SLID_WIN_MAX)
4606 slide_rssi_statistics = PHY_RSSI_SLID_WIN_MAX;
4607 last_rssi = priv->stats.slide_signal_strength[slide_rssi_index];
4608 priv->stats.slide_rssi_total -= last_rssi;
4610 priv->stats.slide_rssi_total += pprevious_stats->SignalStrength;
4612 priv->stats.slide_signal_strength[slide_rssi_index++] = pprevious_stats->SignalStrength;
4613 if(slide_rssi_index >= PHY_RSSI_SLID_WIN_MAX)
4614 slide_rssi_index = 0;
4616 // <1> Showed on UI for user, in dbm
4617 tmp_val = priv->stats.slide_rssi_total/slide_rssi_statistics;
4618 priv->stats.signal_strength = rtl819x_translate_todbm((u8)tmp_val);
4619 pcurrent_stats->rssi = priv->stats.signal_strength;
4621 // If the previous packet does not match the criteria, neglect it
4623 if(!pprevious_stats->bPacketMatchBSSID)
4625 if(!pprevious_stats->bToSelfBA)
4626 return;
4629 if(!bcheck)
4630 return;
4633 //rtl8190_process_cck_rxpathsel(priv,pprevious_stats);//only rtl8190 supported
4636 // Check RSSI
4638 priv->stats.num_process_phyinfo++;
4640 /* record the general signal strength to the sliding window. */
4643 // <2> Showed on UI for engineering
4644 // hardware does not provide rssi information for each rf path in CCK
4645 if(!pprevious_stats->bIsCCK && (pprevious_stats->bPacketToSelf || pprevious_stats->bToSelfBA))
4647 for (rfpath = RF90_PATH_A; rfpath < priv->NumTotalRFPath; rfpath++)
4649 if (!rtl8192_phy_CheckIsLegalRFPath(priv->ieee80211->dev, rfpath))
4650 continue;
4652 //Fixed by Jacken 2008-03-20
4653 if(priv->stats.rx_rssi_percentage[rfpath] == 0)
4655 priv->stats.rx_rssi_percentage[rfpath] = pprevious_stats->RxMIMOSignalStrength[rfpath];
4656 //DbgPrint("MIMO RSSI initialize \n");
4658 if(pprevious_stats->RxMIMOSignalStrength[rfpath] > priv->stats.rx_rssi_percentage[rfpath])
4660 priv->stats.rx_rssi_percentage[rfpath] =
4661 ( (priv->stats.rx_rssi_percentage[rfpath]*(Rx_Smooth_Factor-1)) +
4662 (pprevious_stats->RxMIMOSignalStrength[rfpath])) /(Rx_Smooth_Factor);
4663 priv->stats.rx_rssi_percentage[rfpath] = priv->stats.rx_rssi_percentage[rfpath] + 1;
4665 else
4667 priv->stats.rx_rssi_percentage[rfpath] =
4668 ( (priv->stats.rx_rssi_percentage[rfpath]*(Rx_Smooth_Factor-1)) +
4669 (pprevious_stats->RxMIMOSignalStrength[rfpath])) /(Rx_Smooth_Factor);
4671 RT_TRACE(COMP_DBG,"priv->stats.rx_rssi_percentage[rfPath] = %d \n" ,priv->stats.rx_rssi_percentage[rfpath] );
4677 // Check PWDB.
4679 RT_TRACE(COMP_RXDESC, "Smooth %s PWDB = %d\n",
4680 pprevious_stats->bIsCCK? "CCK": "OFDM",
4681 pprevious_stats->RxPWDBAll);
4683 if(pprevious_stats->bPacketBeacon)
4685 /* record the beacon pwdb to the sliding window. */
4686 if(slide_beacon_adc_pwdb_statistics++ >= PHY_Beacon_RSSI_SLID_WIN_MAX)
4688 slide_beacon_adc_pwdb_statistics = PHY_Beacon_RSSI_SLID_WIN_MAX;
4689 last_beacon_adc_pwdb = priv->stats.Slide_Beacon_pwdb[slide_beacon_adc_pwdb_index];
4690 priv->stats.Slide_Beacon_Total -= last_beacon_adc_pwdb;
4691 //DbgPrint("slide_beacon_adc_pwdb_index = %d, last_beacon_adc_pwdb = %d, Adapter->RxStats.Slide_Beacon_Total = %d\n",
4692 // slide_beacon_adc_pwdb_index, last_beacon_adc_pwdb, Adapter->RxStats.Slide_Beacon_Total);
4694 priv->stats.Slide_Beacon_Total += pprevious_stats->RxPWDBAll;
4695 priv->stats.Slide_Beacon_pwdb[slide_beacon_adc_pwdb_index] = pprevious_stats->RxPWDBAll;
4696 //DbgPrint("slide_beacon_adc_pwdb_index = %d, pPreviousRfd->Status.RxPWDBAll = %d\n", slide_beacon_adc_pwdb_index, pPreviousRfd->Status.RxPWDBAll);
4697 slide_beacon_adc_pwdb_index++;
4698 if(slide_beacon_adc_pwdb_index >= PHY_Beacon_RSSI_SLID_WIN_MAX)
4699 slide_beacon_adc_pwdb_index = 0;
4700 pprevious_stats->RxPWDBAll = priv->stats.Slide_Beacon_Total/slide_beacon_adc_pwdb_statistics;
4701 if(pprevious_stats->RxPWDBAll >= 3)
4702 pprevious_stats->RxPWDBAll -= 3;
4705 RT_TRACE(COMP_RXDESC, "Smooth %s PWDB = %d\n",
4706 pprevious_stats->bIsCCK? "CCK": "OFDM",
4707 pprevious_stats->RxPWDBAll);
4710 if(pprevious_stats->bPacketToSelf || pprevious_stats->bPacketBeacon || pprevious_stats->bToSelfBA)
4712 if(priv->undecorated_smoothed_pwdb < 0) // initialize
4714 priv->undecorated_smoothed_pwdb = pprevious_stats->RxPWDBAll;
4715 //DbgPrint("First pwdb initialize \n");
4717 if(pprevious_stats->RxPWDBAll > (u32)priv->undecorated_smoothed_pwdb)
4719 priv->undecorated_smoothed_pwdb =
4720 ( ((priv->undecorated_smoothed_pwdb)*(Rx_Smooth_Factor-1)) +
4721 (pprevious_stats->RxPWDBAll)) /(Rx_Smooth_Factor);
4722 priv->undecorated_smoothed_pwdb = priv->undecorated_smoothed_pwdb + 1;
4724 else
4726 priv->undecorated_smoothed_pwdb =
4727 ( ((priv->undecorated_smoothed_pwdb)*(Rx_Smooth_Factor-1)) +
4728 (pprevious_stats->RxPWDBAll)) /(Rx_Smooth_Factor);
4734 // Check EVM
4736 /* record the general EVM to the sliding window. */
4737 if(pprevious_stats->SignalQuality == 0)
4740 else
4742 if(pprevious_stats->bPacketToSelf || pprevious_stats->bPacketBeacon || pprevious_stats->bToSelfBA){
4743 if(slide_evm_statistics++ >= PHY_RSSI_SLID_WIN_MAX){
4744 slide_evm_statistics = PHY_RSSI_SLID_WIN_MAX;
4745 last_evm = priv->stats.slide_evm[slide_evm_index];
4746 priv->stats.slide_evm_total -= last_evm;
4749 priv->stats.slide_evm_total += pprevious_stats->SignalQuality;
4751 priv->stats.slide_evm[slide_evm_index++] = pprevious_stats->SignalQuality;
4752 if(slide_evm_index >= PHY_RSSI_SLID_WIN_MAX)
4753 slide_evm_index = 0;
4755 // <1> Showed on UI for user, in percentage.
4756 tmp_val = priv->stats.slide_evm_total/slide_evm_statistics;
4757 priv->stats.signal_quality = tmp_val;
4758 //cosa add 10/11/2007, Showed on UI for user in Windows Vista, for Link quality.
4759 priv->stats.last_signal_strength_inpercent = tmp_val;
4762 // <2> Showed on UI for engineering
4763 if(pprevious_stats->bPacketToSelf || pprevious_stats->bPacketBeacon || pprevious_stats->bToSelfBA)
4765 for(nspatial_stream = 0; nspatial_stream<2 ; nspatial_stream++) // 2 spatial stream
4767 if(pprevious_stats->RxMIMOSignalQuality[nspatial_stream] != -1)
4769 if(priv->stats.rx_evm_percentage[nspatial_stream] == 0) // initialize
4771 priv->stats.rx_evm_percentage[nspatial_stream] = pprevious_stats->RxMIMOSignalQuality[nspatial_stream];
4773 priv->stats.rx_evm_percentage[nspatial_stream] =
4774 ( (priv->stats.rx_evm_percentage[nspatial_stream]* (Rx_Smooth_Factor-1)) +
4775 (pprevious_stats->RxMIMOSignalQuality[nspatial_stream]* 1)) / (Rx_Smooth_Factor);
4784 /*-----------------------------------------------------------------------------
4785 * Function: rtl819x_query_rxpwrpercentage()
4787 * Overview:
4789 * Input: char antpower
4791 * Output: NONE
4793 * Return: 0-100 percentage
4795 * Revised History:
4796 * When Who Remark
4797 * 05/26/2008 amy Create Version 0 porting from windows code.
4799 *---------------------------------------------------------------------------*/
4800 static u8 rtl819x_query_rxpwrpercentage(
4801 char antpower
4804 if ((antpower <= -100) || (antpower >= 20))
4806 return 0;
4808 else if (antpower >= 0)
4810 return 100;
4812 else
4814 return (100+antpower);
4817 } /* QueryRxPwrPercentage */
4819 static u8
4820 rtl819x_evm_dbtopercentage(
4821 char value
4824 char ret_val;
4826 ret_val = value;
4828 if(ret_val >= 0)
4829 ret_val = 0;
4830 if(ret_val <= -33)
4831 ret_val = -33;
4832 ret_val = 0 - ret_val;
4833 ret_val*=3;
4834 if(ret_val == 99)
4835 ret_val = 100;
4836 return(ret_val);
4839 // Description:
4840 // We want good-looking for signal strength/quality
4841 // 2007/7/19 01:09, by cosa.
4843 long
4844 rtl819x_signal_scale_mapping(
4845 long currsig
4848 long retsig;
4850 // Step 1. Scale mapping.
4851 if(currsig >= 61 && currsig <= 100)
4853 retsig = 90 + ((currsig - 60) / 4);
4855 else if(currsig >= 41 && currsig <= 60)
4857 retsig = 78 + ((currsig - 40) / 2);
4859 else if(currsig >= 31 && currsig <= 40)
4861 retsig = 66 + (currsig - 30);
4863 else if(currsig >= 21 && currsig <= 30)
4865 retsig = 54 + (currsig - 20);
4867 else if(currsig >= 5 && currsig <= 20)
4869 retsig = 42 + (((currsig - 5) * 2) / 3);
4871 else if(currsig == 4)
4873 retsig = 36;
4875 else if(currsig == 3)
4877 retsig = 27;
4879 else if(currsig == 2)
4881 retsig = 18;
4883 else if(currsig == 1)
4885 retsig = 9;
4887 else
4889 retsig = currsig;
4892 return retsig;
4895 static void rtl8192_query_rxphystatus(
4896 struct r8192_priv * priv,
4897 struct ieee80211_rx_stats * pstats,
4898 rx_drvinfo_819x_usb * pdrvinfo,
4899 struct ieee80211_rx_stats * precord_stats,
4900 bool bpacket_match_bssid,
4901 bool bpacket_toself,
4902 bool bPacketBeacon,
4903 bool bToSelfBA
4906 //PRT_RFD_STATUS pRtRfdStatus = &(pRfd->Status);
4907 phy_sts_ofdm_819xusb_t* pofdm_buf;
4908 phy_sts_cck_819xusb_t * pcck_buf;
4909 phy_ofdm_rx_status_rxsc_sgien_exintfflag* prxsc;
4910 u8 *prxpkt;
4911 u8 i, max_spatial_stream, tmp_rxsnr, tmp_rxevm, rxsc_sgien_exflg;
4912 char rx_pwr[4], rx_pwr_all=0;
4913 //long rx_avg_pwr = 0;
4914 char rx_snrX, rx_evmX;
4915 u8 evm, pwdb_all;
4916 u32 RSSI, total_rssi=0;//, total_evm=0;
4917 // long signal_strength_index = 0;
4918 u8 is_cck_rate=0;
4919 u8 rf_rx_num = 0;
4922 priv->stats.numqry_phystatus++;
4924 is_cck_rate = rx_hal_is_cck_rate(pdrvinfo);
4926 // Record it for next packet processing
4927 memset(precord_stats, 0, sizeof(struct ieee80211_rx_stats));
4928 pstats->bPacketMatchBSSID = precord_stats->bPacketMatchBSSID = bpacket_match_bssid;
4929 pstats->bPacketToSelf = precord_stats->bPacketToSelf = bpacket_toself;
4930 pstats->bIsCCK = precord_stats->bIsCCK = is_cck_rate;//RX_HAL_IS_CCK_RATE(pDrvInfo);
4931 pstats->bPacketBeacon = precord_stats->bPacketBeacon = bPacketBeacon;
4932 pstats->bToSelfBA = precord_stats->bToSelfBA = bToSelfBA;
4934 prxpkt = (u8*)pdrvinfo;
4936 /* Move pointer to the 16th bytes. Phy status start address. */
4937 prxpkt += sizeof(rx_drvinfo_819x_usb);
4939 /* Initial the cck and ofdm buffer pointer */
4940 pcck_buf = (phy_sts_cck_819xusb_t *)prxpkt;
4941 pofdm_buf = (phy_sts_ofdm_819xusb_t *)prxpkt;
4943 pstats->RxMIMOSignalQuality[0] = -1;
4944 pstats->RxMIMOSignalQuality[1] = -1;
4945 precord_stats->RxMIMOSignalQuality[0] = -1;
4946 precord_stats->RxMIMOSignalQuality[1] = -1;
4948 if(is_cck_rate)
4951 // (1)Hardware does not provide RSSI for CCK
4955 // (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive)
4957 u8 report;//, cck_agc_rpt;
4959 priv->stats.numqry_phystatusCCK++;
4961 if(!priv->bCckHighPower)
4963 report = pcck_buf->cck_agc_rpt & 0xc0;
4964 report = report>>6;
4965 switch(report)
4967 //Fixed by Jacken from Bryant 2008-03-20
4968 //Original value is -38 , -26 , -14 , -2
4969 //Fixed value is -35 , -23 , -11 , 6
4970 case 0x3:
4971 rx_pwr_all = -35 - (pcck_buf->cck_agc_rpt & 0x3e);
4972 break;
4973 case 0x2:
4974 rx_pwr_all = -23 - (pcck_buf->cck_agc_rpt & 0x3e);
4975 break;
4976 case 0x1:
4977 rx_pwr_all = -11 - (pcck_buf->cck_agc_rpt & 0x3e);
4978 break;
4979 case 0x0:
4980 rx_pwr_all = 6 - (pcck_buf->cck_agc_rpt & 0x3e);
4981 break;
4984 else
4986 report = pcck_buf->cck_agc_rpt & 0x60;
4987 report = report>>5;
4988 switch(report)
4990 case 0x3:
4991 rx_pwr_all = -35 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1) ;
4992 break;
4993 case 0x2:
4994 rx_pwr_all = -23 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1);
4995 break;
4996 case 0x1:
4997 rx_pwr_all = -11 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1) ;
4998 break;
4999 case 0x0:
5000 rx_pwr_all = 6 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1) ;
5001 break;
5005 pwdb_all = rtl819x_query_rxpwrpercentage(rx_pwr_all);
5006 pstats->RxPWDBAll = precord_stats->RxPWDBAll = pwdb_all;
5007 pstats->RecvSignalPower = pwdb_all;
5010 // (3) Get Signal Quality (EVM)
5012 //if(bpacket_match_bssid)
5014 u8 sq;
5016 if(pstats->RxPWDBAll > 40)
5018 sq = 100;
5019 }else
5021 sq = pcck_buf->sq_rpt;
5023 if(pcck_buf->sq_rpt > 64)
5024 sq = 0;
5025 else if (pcck_buf->sq_rpt < 20)
5026 sq = 100;
5027 else
5028 sq = ((64-sq) * 100) / 44;
5030 pstats->SignalQuality = precord_stats->SignalQuality = sq;
5031 pstats->RxMIMOSignalQuality[0] = precord_stats->RxMIMOSignalQuality[0] = sq;
5032 pstats->RxMIMOSignalQuality[1] = precord_stats->RxMIMOSignalQuality[1] = -1;
5035 else
5037 priv->stats.numqry_phystatusHT++;
5039 // (1)Get RSSI for HT rate
5041 for(i=RF90_PATH_A; i<priv->NumTotalRFPath; i++)
5043 // 2008/01/30 MH we will judge RF RX path now.
5044 if (priv->brfpath_rxenable[i])
5045 rf_rx_num++;
5046 else
5047 continue;
5049 if (!rtl8192_phy_CheckIsLegalRFPath(priv->ieee80211->dev, i))
5050 continue;
5052 //Fixed by Jacken from Bryant 2008-03-20
5053 //Original value is 106
5054 rx_pwr[i] = ((pofdm_buf->trsw_gain_X[i]&0x3F)*2) - 106;
5056 //Get Rx snr value in DB
5057 tmp_rxsnr = pofdm_buf->rxsnr_X[i];
5058 rx_snrX = (char)(tmp_rxsnr);
5059 //rx_snrX >>= 1;
5060 rx_snrX /= 2;
5061 priv->stats.rxSNRdB[i] = (long)rx_snrX;
5063 /* Translate DBM to percentage. */
5064 RSSI = rtl819x_query_rxpwrpercentage(rx_pwr[i]);
5065 total_rssi += RSSI;
5067 /* Record Signal Strength for next packet */
5068 //if(bpacket_match_bssid)
5070 pstats->RxMIMOSignalStrength[i] =(u8) RSSI;
5071 precord_stats->RxMIMOSignalStrength[i] =(u8) RSSI;
5077 // (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive)
5079 //Fixed by Jacken from Bryant 2008-03-20
5080 //Original value is 106
5081 rx_pwr_all = (((pofdm_buf->pwdb_all ) >> 1 )& 0x7f) -106;
5082 pwdb_all = rtl819x_query_rxpwrpercentage(rx_pwr_all);
5084 pstats->RxPWDBAll = precord_stats->RxPWDBAll = pwdb_all;
5085 pstats->RxPower = precord_stats->RxPower = rx_pwr_all;
5088 // (3)EVM of HT rate
5090 if(pdrvinfo->RxHT && pdrvinfo->RxRate>=DESC90_RATEMCS8 &&
5091 pdrvinfo->RxRate<=DESC90_RATEMCS15)
5092 max_spatial_stream = 2; //both spatial stream make sense
5093 else
5094 max_spatial_stream = 1; //only spatial stream 1 makes sense
5096 for(i=0; i<max_spatial_stream; i++)
5098 tmp_rxevm = pofdm_buf->rxevm_X[i];
5099 rx_evmX = (char)(tmp_rxevm);
5101 // Do not use shift operation like "rx_evmX >>= 1" because the compilor of free build environment
5102 // fill most significant bit to "zero" when doing shifting operation which may change a negative
5103 // value to positive one, then the dbm value (which is supposed to be negative) is not correct anymore.
5104 rx_evmX /= 2; //dbm
5106 evm = rtl819x_evm_dbtopercentage(rx_evmX);
5107 //if(bpacket_match_bssid)
5109 if(i==0) // Fill value in RFD, Get the first spatial stream only
5110 pstats->SignalQuality = precord_stats->SignalQuality = (u8)(evm & 0xff);
5111 pstats->RxMIMOSignalQuality[i] = precord_stats->RxMIMOSignalQuality[i] = (u8)(evm & 0xff);
5116 /* record rx statistics for debug */
5117 rxsc_sgien_exflg = pofdm_buf->rxsc_sgien_exflg;
5118 prxsc = (phy_ofdm_rx_status_rxsc_sgien_exintfflag *)&rxsc_sgien_exflg;
5119 if(pdrvinfo->BW) //40M channel
5120 priv->stats.received_bwtype[1+prxsc->rxsc]++;
5121 else //20M channel
5122 priv->stats.received_bwtype[0]++;
5125 //UI BSS List signal strength(in percentage), make it good looking, from 0~100.
5126 //It is assigned to the BSS List in GetValueFromBeaconOrProbeRsp().
5127 if(is_cck_rate)
5129 pstats->SignalStrength = precord_stats->SignalStrength = (u8)(rtl819x_signal_scale_mapping((long)pwdb_all));//PWDB_ALL;
5132 else
5134 //pRfd->Status.SignalStrength = pRecordRfd->Status.SignalStrength = (u8)(SignalScaleMapping(total_rssi/=RF90_PATH_MAX));//(u8)(total_rssi/=RF90_PATH_MAX);
5135 // We can judge RX path number now.
5136 if (rf_rx_num != 0)
5137 pstats->SignalStrength = precord_stats->SignalStrength = (u8)(rtl819x_signal_scale_mapping((long)(total_rssi/=rf_rx_num)));
5139 } /* QueryRxPhyStatus8190Pci */
5141 void
5142 rtl8192_record_rxdesc_forlateruse(
5143 struct ieee80211_rx_stats * psrc_stats,
5144 struct ieee80211_rx_stats * ptarget_stats
5147 ptarget_stats->bIsAMPDU = psrc_stats->bIsAMPDU;
5148 ptarget_stats->bFirstMPDU = psrc_stats->bFirstMPDU;
5149 ptarget_stats->Seq_Num = psrc_stats->Seq_Num;
5153 void TranslateRxSignalStuff819xUsb(struct sk_buff *skb,
5154 struct ieee80211_rx_stats * pstats,
5155 rx_drvinfo_819x_usb *pdrvinfo)
5157 // TODO: We must only check packet for current MAC address. Not finish
5158 rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
5159 struct net_device *dev=info->dev;
5160 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
5161 bool bpacket_match_bssid, bpacket_toself;
5162 bool bPacketBeacon=FALSE, bToSelfBA=FALSE;
5163 static struct ieee80211_rx_stats previous_stats;
5164 struct ieee80211_hdr_3addr *hdr;//by amy
5165 u16 fc,type;
5167 // Get Signal Quality for only RX data queue (but not command queue)
5169 u8* tmp_buf;
5170 //u16 tmp_buf_len = 0;
5171 u8 *praddr;
5173 /* Get MAC frame start address. */
5174 tmp_buf = (u8*)skb->data;// + get_rxpacket_shiftbytes_819xusb(pstats);
5176 hdr = (struct ieee80211_hdr_3addr *)tmp_buf;
5177 fc = le16_to_cpu(hdr->frame_ctl);
5178 type = WLAN_FC_GET_TYPE(fc);
5179 praddr = hdr->addr1;
5181 /* Check if the received packet is acceptabe. */
5182 bpacket_match_bssid = ((IEEE80211_FTYPE_CTL != type) &&
5183 (eqMacAddr(priv->ieee80211->current_network.bssid, (fc & IEEE80211_FCTL_TODS)? hdr->addr1 : (fc & IEEE80211_FCTL_FROMDS )? hdr->addr2 : hdr->addr3))
5184 && (!pstats->bHwError) && (!pstats->bCRC)&& (!pstats->bICV));
5185 bpacket_toself = bpacket_match_bssid & (eqMacAddr(praddr, priv->ieee80211->dev->dev_addr));
5187 if(WLAN_FC_GET_FRAMETYPE(fc)== IEEE80211_STYPE_BEACON)
5189 bPacketBeacon = true;
5190 //DbgPrint("Beacon 2, MatchBSSID = %d, ToSelf = %d \n", bPacketMatchBSSID, bPacketToSelf);
5192 if(WLAN_FC_GET_FRAMETYPE(fc) == IEEE80211_STYPE_BLOCKACK)
5194 if((eqMacAddr(praddr,dev->dev_addr)))
5195 bToSelfBA = true;
5196 //DbgPrint("BlockAck, MatchBSSID = %d, ToSelf = %d \n", bPacketMatchBSSID, bPacketToSelf);
5201 if(bpacket_match_bssid)
5203 priv->stats.numpacket_matchbssid++;
5205 if(bpacket_toself){
5206 priv->stats.numpacket_toself++;
5209 // Process PHY information for previous packet (RSSI/PWDB/EVM)
5211 // Because phy information is contained in the last packet of AMPDU only, so driver
5212 // should process phy information of previous packet
5213 rtl8192_process_phyinfo(priv, tmp_buf, &previous_stats, pstats);
5214 rtl8192_query_rxphystatus(priv, pstats, pdrvinfo, &previous_stats, bpacket_match_bssid,bpacket_toself,bPacketBeacon,bToSelfBA);
5215 rtl8192_record_rxdesc_forlateruse(pstats, &previous_stats);
5220 * Function: UpdateReceivedRateHistogramStatistics
5221 * Overview: Recored down the received data rate
5223 * Input:
5224 * struct net_device *dev
5225 * struct ieee80211_rx_stats *stats
5227 * Output:
5229 * (priv->stats.ReceivedRateHistogram[] is updated)
5230 * Return:
5231 * None
5233 void
5234 UpdateReceivedRateHistogramStatistics8190(
5235 struct net_device *dev,
5236 struct ieee80211_rx_stats *stats
5239 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
5240 u32 rcvType=1; //0: Total, 1:OK, 2:CRC, 3:ICV
5241 u32 rateIndex;
5242 u32 preamble_guardinterval; //1: short preamble/GI, 0: long preamble/GI
5245 if(stats->bCRC)
5246 rcvType = 2;
5247 else if(stats->bICV)
5248 rcvType = 3;
5250 if(stats->bShortPreamble)
5251 preamble_guardinterval = 1;// short
5252 else
5253 preamble_guardinterval = 0;// long
5255 switch(stats->rate)
5258 // CCK rate
5260 case MGN_1M: rateIndex = 0; break;
5261 case MGN_2M: rateIndex = 1; break;
5262 case MGN_5_5M: rateIndex = 2; break;
5263 case MGN_11M: rateIndex = 3; break;
5265 // Legacy OFDM rate
5267 case MGN_6M: rateIndex = 4; break;
5268 case MGN_9M: rateIndex = 5; break;
5269 case MGN_12M: rateIndex = 6; break;
5270 case MGN_18M: rateIndex = 7; break;
5271 case MGN_24M: rateIndex = 8; break;
5272 case MGN_36M: rateIndex = 9; break;
5273 case MGN_48M: rateIndex = 10; break;
5274 case MGN_54M: rateIndex = 11; break;
5276 // 11n High throughput rate
5278 case MGN_MCS0: rateIndex = 12; break;
5279 case MGN_MCS1: rateIndex = 13; break;
5280 case MGN_MCS2: rateIndex = 14; break;
5281 case MGN_MCS3: rateIndex = 15; break;
5282 case MGN_MCS4: rateIndex = 16; break;
5283 case MGN_MCS5: rateIndex = 17; break;
5284 case MGN_MCS6: rateIndex = 18; break;
5285 case MGN_MCS7: rateIndex = 19; break;
5286 case MGN_MCS8: rateIndex = 20; break;
5287 case MGN_MCS9: rateIndex = 21; break;
5288 case MGN_MCS10: rateIndex = 22; break;
5289 case MGN_MCS11: rateIndex = 23; break;
5290 case MGN_MCS12: rateIndex = 24; break;
5291 case MGN_MCS13: rateIndex = 25; break;
5292 case MGN_MCS14: rateIndex = 26; break;
5293 case MGN_MCS15: rateIndex = 27; break;
5294 default: rateIndex = 28; break;
5296 priv->stats.received_preamble_GI[preamble_guardinterval][rateIndex]++;
5297 priv->stats.received_rate_histogram[0][rateIndex]++; //total
5298 priv->stats.received_rate_histogram[rcvType][rateIndex]++;
5302 void query_rxdesc_status(struct sk_buff *skb, struct ieee80211_rx_stats *stats, bool bIsRxAggrSubframe)
5304 rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
5305 struct net_device *dev=info->dev;
5306 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
5307 //rx_desc_819x_usb *desc = (rx_desc_819x_usb *)skb->data;
5308 rx_drvinfo_819x_usb *driver_info = NULL;
5311 //Get Rx Descriptor Information
5313 #ifdef USB_RX_AGGREGATION_SUPPORT
5314 if (bIsRxAggrSubframe)
5316 rx_desc_819x_usb_aggr_subframe *desc = (rx_desc_819x_usb_aggr_subframe *)skb->data;
5317 stats->Length = desc->Length ;
5318 stats->RxDrvInfoSize = desc->RxDrvInfoSize;
5319 stats->RxBufShift = 0; //RxBufShift = 2 in RxDesc, but usb didn't shift bytes in fact.
5320 stats->bICV = desc->ICV;
5321 stats->bCRC = desc->CRC32;
5322 stats->bHwError = stats->bCRC|stats->bICV;
5323 stats->Decrypted = !desc->SWDec;//RTL8190 set this bit to indicate that Hw does not decrypt packet
5324 } else
5325 #endif
5327 rx_desc_819x_usb *desc = (rx_desc_819x_usb *)skb->data;
5329 stats->Length = desc->Length;
5330 stats->RxDrvInfoSize = desc->RxDrvInfoSize;
5331 stats->RxBufShift = 0;//desc->Shift&0x03;
5332 stats->bICV = desc->ICV;
5333 stats->bCRC = desc->CRC32;
5334 stats->bHwError = stats->bCRC|stats->bICV;
5335 //RTL8190 set this bit to indicate that Hw does not decrypt packet
5336 stats->Decrypted = !desc->SWDec;
5339 if((priv->ieee80211->pHTInfo->bCurrentHTSupport == true) && (priv->ieee80211->pairwise_key_type == KEY_TYPE_CCMP))
5341 stats->bHwError = false;
5343 else
5345 stats->bHwError = stats->bCRC|stats->bICV;
5348 if(stats->Length < 24 || stats->Length > MAX_8192U_RX_SIZE)
5349 stats->bHwError |= 1;
5351 //Get Driver Info
5353 // TODO: Need to verify it on FGPA platform
5354 //Driver info are written to the RxBuffer following rx desc
5355 if (stats->RxDrvInfoSize != 0) {
5356 driver_info = (rx_drvinfo_819x_usb *)(skb->data + sizeof(rx_desc_819x_usb) + \
5357 stats->RxBufShift);
5358 /* unit: 0.5M */
5359 /* TODO */
5360 if(!stats->bHwError){
5361 u8 ret_rate;
5362 ret_rate = HwRateToMRate90(driver_info->RxHT, driver_info->RxRate);
5363 if(ret_rate == 0xff)
5365 // Abnormal Case: Receive CRC OK packet with Rx descriptor indicating non supported rate.
5366 // Special Error Handling here, 2008.05.16, by Emily
5368 stats->bHwError = 1;
5369 stats->rate = MGN_1M; //Set 1M rate by default
5370 }else
5372 stats->rate = ret_rate;
5375 else
5376 stats->rate = 0x02;
5378 stats->bShortPreamble = driver_info->SPLCP;
5381 UpdateReceivedRateHistogramStatistics8190(dev, stats);
5383 stats->bIsAMPDU = (driver_info->PartAggr==1);
5384 stats->bFirstMPDU = (driver_info->PartAggr==1) && (driver_info->FirstAGGR==1);
5385 stats->TimeStampLow = driver_info->TSFL;
5386 // xiong mask it, 070514
5387 //pRfd->Status.TimeStampHigh = PlatformEFIORead4Byte(Adapter, TSFR+4);
5388 // stats->TimeStampHigh = read_nic_dword(dev, TSFR+4);
5390 UpdateRxPktTimeStamp8190(dev, stats);
5393 // Rx A-MPDU
5395 if(driver_info->FirstAGGR==1 || driver_info->PartAggr == 1)
5396 RT_TRACE(COMP_RXDESC, "driver_info->FirstAGGR = %d, driver_info->PartAggr = %d\n",
5397 driver_info->FirstAGGR, driver_info->PartAggr);
5401 skb_pull(skb,sizeof(rx_desc_819x_usb));
5403 // Get Total offset of MPDU Frame Body
5405 if((stats->RxBufShift + stats->RxDrvInfoSize) > 0) {
5406 stats->bShift = 1;
5407 skb_pull(skb,stats->RxBufShift + stats->RxDrvInfoSize);
5410 #ifdef USB_RX_AGGREGATION_SUPPORT
5411 /* for the rx aggregated sub frame, the redundant space truelly contained in the packet */
5412 if(bIsRxAggrSubframe) {
5413 skb_pull(skb, 8);
5415 #endif
5416 /* for debug 2008.5.29 */
5418 //added by vivi, for MP, 20080108
5419 stats->RxIs40MHzPacket = driver_info->BW;
5420 if(stats->RxDrvInfoSize != 0)
5421 TranslateRxSignalStuff819xUsb(skb, stats, driver_info);
5425 u32 GetRxPacketShiftBytes819xUsb(struct ieee80211_rx_stats *Status, bool bIsRxAggrSubframe)
5427 #ifdef USB_RX_AGGREGATION_SUPPORT
5428 if (bIsRxAggrSubframe)
5429 return (sizeof(rx_desc_819x_usb) + Status->RxDrvInfoSize
5430 + Status->RxBufShift + 8);
5431 else
5432 #endif
5433 return (sizeof(rx_desc_819x_usb) + Status->RxDrvInfoSize
5434 + Status->RxBufShift);
5437 void rtl8192_rx_nomal(struct sk_buff* skb)
5439 rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
5440 struct net_device *dev=info->dev;
5441 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
5442 struct ieee80211_rx_stats stats = {
5443 .signal = 0,
5444 .noise = -98,
5445 .rate = 0,
5446 // .mac_time = jiffies,
5447 .freq = IEEE80211_24GHZ_BAND,
5449 u32 rx_pkt_len = 0;
5450 struct ieee80211_hdr_1addr *ieee80211_hdr = NULL;
5451 bool unicast_packet = false;
5452 #ifdef USB_RX_AGGREGATION_SUPPORT
5453 struct sk_buff *agg_skb = NULL;
5454 u32 TotalLength = 0;
5455 u32 TempDWord = 0;
5456 u32 PacketLength = 0;
5457 u32 PacketOccupiedLendth = 0;
5458 u8 TempByte = 0;
5459 u32 PacketShiftBytes = 0;
5460 rx_desc_819x_usb_aggr_subframe *RxDescr = NULL;
5461 u8 PaddingBytes = 0;
5462 //add just for testing
5463 u8 testing;
5465 #endif
5467 /* 20 is for ps-poll */
5468 if((skb->len >=(20 + sizeof(rx_desc_819x_usb))) && (skb->len < RX_URB_SIZE)) {
5469 #ifdef USB_RX_AGGREGATION_SUPPORT
5470 TempByte = *(skb->data + sizeof(rx_desc_819x_usb));
5471 #endif
5472 /* first packet should not contain Rx aggregation header */
5473 query_rxdesc_status(skb, &stats, false);
5474 /* TODO */
5475 /* hardware related info */
5476 #ifdef USB_RX_AGGREGATION_SUPPORT
5477 if (TempByte & BIT0) {
5478 agg_skb = skb;
5479 //TotalLength = agg_skb->len - 4; /*sCrcLng*/
5480 TotalLength = stats.Length - 4; /*sCrcLng*/
5481 //RT_TRACE(COMP_RECV, "%s:first aggregated packet!Length=%d\n",__FUNCTION__,TotalLength);
5482 /* though the head pointer has passed this position */
5483 TempDWord = *(u32 *)(agg_skb->data - 4);
5484 PacketLength = (u16)(TempDWord & 0x3FFF); /*sCrcLng*/
5485 skb = dev_alloc_skb(PacketLength);
5486 memcpy(skb_put(skb,PacketLength),agg_skb->data,PacketLength);
5487 PacketShiftBytes = GetRxPacketShiftBytes819xUsb(&stats, false);
5489 #endif
5490 /* Process the MPDU recevied */
5491 skb_trim(skb, skb->len - 4/*sCrcLng*/);
5493 rx_pkt_len = skb->len;
5494 ieee80211_hdr = (struct ieee80211_hdr_1addr *)skb->data;
5495 unicast_packet = false;
5496 if(is_broadcast_ether_addr(ieee80211_hdr->addr1)) {
5497 //TODO
5498 }else if(is_multicast_ether_addr(ieee80211_hdr->addr1)){
5499 //TODO
5500 }else {
5501 /* unicast packet */
5502 unicast_packet = true;
5505 if(!ieee80211_rx(priv->ieee80211,skb, &stats)) {
5506 dev_kfree_skb_any(skb);
5507 } else {
5508 priv->stats.rxoktotal++;
5509 if(unicast_packet) {
5510 priv->stats.rxbytesunicast += rx_pkt_len;
5513 #ifdef USB_RX_AGGREGATION_SUPPORT
5514 testing = 1;
5515 // (PipeIndex == 0) && (TempByte & BIT0) => TotalLength > 0.
5516 if (TotalLength > 0) {
5517 PacketOccupiedLendth = PacketLength + (PacketShiftBytes + 8);
5518 if ((PacketOccupiedLendth & 0xFF) != 0)
5519 PacketOccupiedLendth = (PacketOccupiedLendth & 0xFFFFFF00) + 256;
5520 PacketOccupiedLendth -= 8;
5521 TempDWord = PacketOccupiedLendth - PacketShiftBytes; /*- PacketLength */
5522 if (agg_skb->len > TempDWord)
5523 skb_pull(agg_skb, TempDWord);
5524 else
5525 agg_skb->len = 0;
5527 while (agg_skb->len>=GetRxPacketShiftBytes819xUsb(&stats, true)) {
5528 u8 tmpCRC = 0, tmpICV = 0;
5529 //RT_TRACE(COMP_RECV,"%s:aggred pkt,total_len = %d\n",__FUNCTION__,agg_skb->len);
5530 RxDescr = (rx_desc_819x_usb_aggr_subframe *)(agg_skb->data);
5531 tmpCRC = RxDescr->CRC32;
5532 tmpICV = RxDescr->ICV;
5533 memcpy(agg_skb->data, &agg_skb->data[44], 2);
5534 RxDescr->CRC32 = tmpCRC;
5535 RxDescr->ICV = tmpICV;
5537 memset(&stats, 0, sizeof(struct ieee80211_rx_stats));
5538 stats.signal = 0;
5539 stats.noise = -98;
5540 stats.rate = 0;
5541 stats.freq = IEEE80211_24GHZ_BAND;
5542 query_rxdesc_status(agg_skb, &stats, true);
5543 PacketLength = stats.Length;
5545 if(PacketLength > agg_skb->len) {
5546 break;
5548 /* Process the MPDU recevied */
5549 skb = dev_alloc_skb(PacketLength);
5550 memcpy(skb_put(skb,PacketLength),agg_skb->data, PacketLength);
5551 skb_trim(skb, skb->len - 4/*sCrcLng*/);
5553 rx_pkt_len = skb->len;
5554 ieee80211_hdr = (struct ieee80211_hdr_1addr *)skb->data;
5555 unicast_packet = false;
5556 if(is_broadcast_ether_addr(ieee80211_hdr->addr1)) {
5557 //TODO
5558 }else if(is_multicast_ether_addr(ieee80211_hdr->addr1)){
5559 //TODO
5560 }else {
5561 /* unicast packet */
5562 unicast_packet = true;
5564 if(!ieee80211_rx(priv->ieee80211,skb, &stats)) {
5565 dev_kfree_skb_any(skb);
5566 } else {
5567 priv->stats.rxoktotal++;
5568 if(unicast_packet) {
5569 priv->stats.rxbytesunicast += rx_pkt_len;
5572 /* should trim the packet which has been copied to target skb */
5573 skb_pull(agg_skb, PacketLength);
5574 PacketShiftBytes = GetRxPacketShiftBytes819xUsb(&stats, true);
5575 PacketOccupiedLendth = PacketLength + PacketShiftBytes;
5576 if ((PacketOccupiedLendth & 0xFF) != 0) {
5577 PaddingBytes = 256 - (PacketOccupiedLendth & 0xFF);
5578 if (agg_skb->len > PaddingBytes)
5579 skb_pull(agg_skb, PaddingBytes);
5580 else
5581 agg_skb->len = 0;
5584 dev_kfree_skb(agg_skb);
5586 #endif
5587 } else {
5588 priv->stats.rxurberr++;
5589 printk("actual_length:%d\n", skb->len);
5590 dev_kfree_skb_any(skb);
5595 void
5596 rtl819xusb_process_received_packet(
5597 struct net_device *dev,
5598 struct ieee80211_rx_stats *pstats
5601 // bool bfreerfd=false, bqueued=false;
5602 u8* frame;
5603 u16 frame_len=0;
5604 struct r8192_priv *priv = ieee80211_priv(dev);
5605 // u8 index = 0;
5606 // u8 TID = 0;
5607 //u16 seqnum = 0;
5608 //PRX_TS_RECORD pts = NULL;
5610 // Get shifted bytes of Starting address of 802.11 header. 2006.09.28, by Emily
5611 //porting by amy 080508
5612 pstats->virtual_address += get_rxpacket_shiftbytes_819xusb(pstats);
5613 frame = pstats->virtual_address;
5614 frame_len = pstats->packetlength;
5615 #ifdef TODO // by amy about HCT
5616 if(!Adapter->bInHctTest)
5617 CountRxErrStatistics(Adapter, pRfd);
5618 #endif
5620 #ifdef ENABLE_PS //by amy for adding ps function in future
5621 RT_RF_POWER_STATE rtState;
5622 // When RF is off, we should not count the packet for hw/sw synchronize
5623 // reason, ie. there may be a duration while sw switch is changed and hw
5624 // switch is being changed. 2006.12.04, by shien chang.
5625 Adapter->HalFunc.GetHwRegHandler(Adapter, HW_VAR_RF_STATE, (u8* )(&rtState));
5626 if (rtState == eRfOff)
5628 return;
5630 #endif
5631 priv->stats.rxframgment++;
5634 #ifdef TODO
5635 RmMonitorSignalStrength(Adapter, pRfd);
5636 #endif
5637 /* 2007/01/16 MH Add RX command packet handle here. */
5638 /* 2007/03/01 MH We have to release RFD and return if rx pkt is cmd pkt. */
5639 if (rtl819xusb_rx_command_packet(dev, pstats))
5641 return;
5644 #ifdef SW_CRC_CHECK
5645 SwCrcCheck();
5646 #endif
5651 void query_rx_cmdpkt_desc_status(struct sk_buff *skb, struct ieee80211_rx_stats *stats)
5653 // rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
5654 // struct net_device *dev=info->dev;
5655 // struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
5656 rx_desc_819x_usb *desc = (rx_desc_819x_usb *)skb->data;
5657 // rx_drvinfo_819x_usb *driver_info;
5660 //Get Rx Descriptor Information
5662 stats->virtual_address = (u8*)skb->data;
5663 stats->Length = desc->Length;
5664 stats->RxDrvInfoSize = 0;
5665 stats->RxBufShift = 0;
5666 stats->packetlength = stats->Length-scrclng;
5667 stats->fraglength = stats->packetlength;
5668 stats->fragoffset = 0;
5669 stats->ntotalfrag = 1;
5673 void rtl8192_rx_cmd(struct sk_buff *skb)
5675 struct rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
5676 struct net_device *dev = info->dev;
5677 //int ret;
5678 // struct urb *rx_urb = info->urb;
5679 /* TODO */
5680 struct ieee80211_rx_stats stats = {
5681 .signal = 0,
5682 .noise = -98,
5683 .rate = 0,
5684 // .mac_time = jiffies,
5685 .freq = IEEE80211_24GHZ_BAND,
5688 if((skb->len >=(20 + sizeof(rx_desc_819x_usb))) && (skb->len < RX_URB_SIZE))
5691 query_rx_cmdpkt_desc_status(skb,&stats);
5692 // this is to be done by amy 080508 prfd->queue_id = 1;
5696 // Process the command packet received.
5699 rtl819xusb_process_received_packet(dev,&stats);
5701 dev_kfree_skb_any(skb);
5703 else
5709 void rtl8192_irq_rx_tasklet(struct r8192_priv *priv)
5711 struct sk_buff *skb;
5712 struct rtl8192_rx_info *info;
5714 while (NULL != (skb = skb_dequeue(&priv->skb_queue))) {
5715 info = (struct rtl8192_rx_info *)skb->cb;
5716 switch (info->out_pipe) {
5717 /* Nomal packet pipe */
5718 case 3:
5719 //RT_TRACE(COMP_RECV, "normal in-pipe index(%d)\n",info->out_pipe);
5720 priv->IrpPendingCount--;
5721 rtl8192_rx_nomal(skb);
5722 break;
5724 /* Command packet pipe */
5725 case 9:
5726 RT_TRACE(COMP_RECV, "command in-pipe index(%d)\n",\
5727 info->out_pipe);
5729 rtl8192_rx_cmd(skb);
5730 break;
5732 default: /* should never get here! */
5733 RT_TRACE(COMP_ERR, "Unknown in-pipe index(%d)\n",\
5734 info->out_pipe);
5735 dev_kfree_skb(skb);
5736 break;
5742 static const struct net_device_ops rtl8192_netdev_ops = {
5743 .ndo_open = rtl8192_open,
5744 .ndo_stop = rtl8192_close,
5745 .ndo_get_stats = rtl8192_stats,
5746 .ndo_tx_timeout = tx_timeout,
5747 .ndo_do_ioctl = rtl8192_ioctl,
5748 .ndo_set_multicast_list = r8192_set_multicast,
5749 .ndo_set_mac_address = r8192_set_mac_adr,
5750 .ndo_validate_addr = eth_validate_addr,
5751 .ndo_change_mtu = eth_change_mtu,
5752 .ndo_start_xmit = ieee80211_xmit,
5756 /****************************************************************************
5757 ---------------------------- USB_STUFF---------------------------
5758 *****************************************************************************/
5760 static int __devinit rtl8192_usb_probe(struct usb_interface *intf,
5761 const struct usb_device_id *id)
5763 // unsigned long ioaddr = 0;
5764 struct net_device *dev = NULL;
5765 struct r8192_priv *priv= NULL;
5766 struct usb_device *udev = interface_to_usbdev(intf);
5767 int ret;
5768 RT_TRACE(COMP_INIT, "Oops: i'm coming\n");
5770 dev = alloc_ieee80211(sizeof(struct r8192_priv));
5771 if (dev == NULL)
5772 return -ENOMEM;
5774 usb_set_intfdata(intf, dev);
5775 SET_NETDEV_DEV(dev, &intf->dev);
5776 priv = ieee80211_priv(dev);
5777 priv->ieee80211 = netdev_priv(dev);
5778 priv->udev=udev;
5780 dev->netdev_ops = &rtl8192_netdev_ops;
5782 //DMESG("Oops: i'm coming\n");
5783 #if WIRELESS_EXT >= 12
5784 #if WIRELESS_EXT < 17
5785 dev->get_wireless_stats = r8192_get_wireless_stats;
5786 #endif
5787 dev->wireless_handlers = (struct iw_handler_def *) &r8192_wx_handlers_def;
5788 #endif
5789 dev->type=ARPHRD_ETHER;
5791 dev->watchdog_timeo = HZ*3; //modified by john, 0805
5793 if (dev_alloc_name(dev, ifname) < 0){
5794 RT_TRACE(COMP_INIT, "Oops: devname already taken! Trying wlan%%d...\n");
5795 ifname = "wlan%d";
5796 dev_alloc_name(dev, ifname);
5799 RT_TRACE(COMP_INIT, "Driver probe completed1\n");
5800 if(rtl8192_init(dev)!=0){
5801 RT_TRACE(COMP_ERR, "Initialization failed");
5802 ret = -ENODEV;
5803 goto fail;
5805 netif_carrier_off(dev);
5806 netif_stop_queue(dev);
5808 ret = register_netdev(dev);
5809 if (ret)
5810 goto fail2;
5812 RT_TRACE(COMP_INIT, "dev name=======> %s\n",dev->name);
5813 rtl8192_proc_init_one(dev);
5816 RT_TRACE(COMP_INIT, "Driver probe completed\n");
5817 return 0;
5819 fail2:
5820 rtl8192_down(dev);
5821 kfree(priv->pFirmware);
5822 priv->pFirmware = NULL;
5823 rtl8192_usb_deleteendpoints(dev);
5824 destroy_workqueue(priv->priv_wq);
5825 mdelay(10);
5826 fail:
5827 free_ieee80211(dev);
5829 RT_TRACE(COMP_ERR, "wlan driver load failed\n");
5830 return ret;
5833 //detach all the work and timer structure declared or inititialize in r8192U_init function.
5834 void rtl8192_cancel_deferred_work(struct r8192_priv* priv)
5837 cancel_work_sync(&priv->reset_wq);
5838 cancel_delayed_work(&priv->watch_dog_wq);
5839 cancel_delayed_work(&priv->update_beacon_wq);
5840 cancel_work_sync(&priv->qos_activate);
5841 //cancel_work_sync(&priv->SetBWModeWorkItem);
5842 //cancel_work_sync(&priv->SwChnlWorkItem);
5847 static void __devexit rtl8192_usb_disconnect(struct usb_interface *intf)
5849 struct net_device *dev = usb_get_intfdata(intf);
5851 struct r8192_priv *priv = ieee80211_priv(dev);
5852 if(dev){
5854 unregister_netdev(dev);
5856 RT_TRACE(COMP_DOWN, "=============>wlan driver to be removed\n");
5857 rtl8192_proc_remove_one(dev);
5859 rtl8192_down(dev);
5860 kfree(priv->pFirmware);
5861 priv->pFirmware = NULL;
5862 // priv->rf_close(dev);
5863 // rtl8192_SetRFPowerState(dev, eRfOff);
5864 rtl8192_usb_deleteendpoints(dev);
5865 destroy_workqueue(priv->priv_wq);
5866 //rtl8192_irq_disable(dev);
5867 //rtl8192_reset(dev);
5868 mdelay(10);
5871 free_ieee80211(dev);
5872 RT_TRACE(COMP_DOWN, "wlan driver removed\n");
5875 /* fun with the built-in ieee80211 stack... */
5876 extern int ieee80211_debug_init(void);
5877 extern void ieee80211_debug_exit(void);
5878 extern int ieee80211_crypto_init(void);
5879 extern void ieee80211_crypto_deinit(void);
5880 extern int ieee80211_crypto_tkip_init(void);
5881 extern void ieee80211_crypto_tkip_exit(void);
5882 extern int ieee80211_crypto_ccmp_init(void);
5883 extern void ieee80211_crypto_ccmp_exit(void);
5884 extern int ieee80211_crypto_wep_init(void);
5885 extern void ieee80211_crypto_wep_exit(void);
5887 static int __init rtl8192_usb_module_init(void)
5889 int ret;
5891 #ifdef CONFIG_IEEE80211_DEBUG
5892 ret = ieee80211_debug_init();
5893 if (ret) {
5894 printk(KERN_ERR "ieee80211_debug_init() failed %d\n", ret);
5895 return ret;
5897 #endif
5898 ret = ieee80211_crypto_init();
5899 if (ret) {
5900 printk(KERN_ERR "ieee80211_crypto_init() failed %d\n", ret);
5901 return ret;
5904 ret = ieee80211_crypto_tkip_init();
5905 if (ret) {
5906 printk(KERN_ERR "ieee80211_crypto_tkip_init() failed %d\n",
5907 ret);
5908 return ret;
5911 ret = ieee80211_crypto_ccmp_init();
5912 if (ret) {
5913 printk(KERN_ERR "ieee80211_crypto_ccmp_init() failed %d\n",
5914 ret);
5915 return ret;
5918 ret = ieee80211_crypto_wep_init();
5919 if (ret) {
5920 printk(KERN_ERR "ieee80211_crypto_wep_init() failed %d\n", ret);
5921 return ret;
5924 printk(KERN_INFO "\nLinux kernel driver for RTL8192 based WLAN cards\n");
5925 printk(KERN_INFO "Copyright (c) 2007-2008, Realsil Wlan\n");
5926 RT_TRACE(COMP_INIT, "Initializing module");
5927 RT_TRACE(COMP_INIT, "Wireless extensions version %d", WIRELESS_EXT);
5928 rtl8192_proc_module_init();
5929 return usb_register(&rtl8192_usb_driver);
5933 static void __exit rtl8192_usb_module_exit(void)
5935 usb_deregister(&rtl8192_usb_driver);
5937 RT_TRACE(COMP_DOWN, "Exiting");
5938 // rtl8192_proc_module_remove();
5942 void rtl8192_try_wake_queue(struct net_device *dev, int pri)
5944 unsigned long flags;
5945 short enough_desc;
5946 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
5948 spin_lock_irqsave(&priv->tx_lock,flags);
5949 enough_desc = check_nic_enough_desc(dev,pri);
5950 spin_unlock_irqrestore(&priv->tx_lock,flags);
5952 if(enough_desc)
5953 ieee80211_wake_queue(priv->ieee80211);
5956 void EnableHWSecurityConfig8192(struct net_device *dev)
5958 u8 SECR_value = 0x0;
5959 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
5960 struct ieee80211_device* ieee = priv->ieee80211;
5961 SECR_value = SCR_TxEncEnable | SCR_RxDecEnable;
5962 if (((KEY_TYPE_WEP40 == ieee->pairwise_key_type) || (KEY_TYPE_WEP104 == ieee->pairwise_key_type)) && (priv->ieee80211->auth_mode != 2))
5964 SECR_value |= SCR_RxUseDK;
5965 SECR_value |= SCR_TxUseDK;
5967 else if ((ieee->iw_mode == IW_MODE_ADHOC) && (ieee->pairwise_key_type & (KEY_TYPE_CCMP | KEY_TYPE_TKIP)))
5969 SECR_value |= SCR_RxUseDK;
5970 SECR_value |= SCR_TxUseDK;
5972 //add HWSec active enable here.
5973 //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
5975 ieee->hwsec_active = 1;
5977 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
5979 ieee->hwsec_active = 0;
5980 SECR_value &= ~SCR_RxDecEnable;
5982 RT_TRACE(COMP_SEC,"%s:, hwsec:%d, pairwise_key:%d, SECR_value:%x\n", __FUNCTION__, \
5983 ieee->hwsec_active, ieee->pairwise_key_type, SECR_value);
5985 write_nic_byte(dev, SECR, SECR_value);//SECR_value | SCR_UseDK );
5990 void setKey( struct net_device *dev,
5991 u8 EntryNo,
5992 u8 KeyIndex,
5993 u16 KeyType,
5994 u8 *MacAddr,
5995 u8 DefaultKey,
5996 u32 *KeyContent )
5998 u32 TargetCommand = 0;
5999 u32 TargetContent = 0;
6000 u16 usConfig = 0;
6001 u8 i;
6002 if (EntryNo >= TOTAL_CAM_ENTRY)
6003 RT_TRACE(COMP_ERR, "cam entry exceeds in setKey()\n");
6005 RT_TRACE(COMP_SEC, "====>to setKey(), dev:%p, EntryNo:%d, KeyIndex:%d, KeyType:%d, MacAddr%pM\n", dev,EntryNo, KeyIndex, KeyType, MacAddr);
6007 if (DefaultKey)
6008 usConfig |= BIT15 | (KeyType<<2);
6009 else
6010 usConfig |= BIT15 | (KeyType<<2) | KeyIndex;
6011 // usConfig |= BIT15 | (KeyType<<2) | (DefaultKey<<5) | KeyIndex;
6014 for(i=0 ; i<CAM_CONTENT_COUNT; i++){
6015 TargetCommand = i+CAM_CONTENT_COUNT*EntryNo;
6016 TargetCommand |= BIT31|BIT16;
6018 if(i==0){//MAC|Config
6019 TargetContent = (u32)(*(MacAddr+0)) << 16|
6020 (u32)(*(MacAddr+1)) << 24|
6021 (u32)usConfig;
6023 write_nic_dword(dev, WCAMI, TargetContent);
6024 write_nic_dword(dev, RWCAM, TargetCommand);
6025 // printk("setkey cam =%8x\n", read_cam(dev, i+6*EntryNo));
6027 else if(i==1){//MAC
6028 TargetContent = (u32)(*(MacAddr+2)) |
6029 (u32)(*(MacAddr+3)) << 8|
6030 (u32)(*(MacAddr+4)) << 16|
6031 (u32)(*(MacAddr+5)) << 24;
6032 write_nic_dword(dev, WCAMI, TargetContent);
6033 write_nic_dword(dev, RWCAM, TargetCommand);
6035 else {
6036 //Key Material
6037 if(KeyContent !=NULL){
6038 write_nic_dword(dev, WCAMI, (u32)(*(KeyContent+i-2)) );
6039 write_nic_dword(dev, RWCAM, TargetCommand);
6046 /***************************************************************************
6047 ------------------- module init / exit stubs ----------------
6048 ****************************************************************************/
6049 module_init(rtl8192_usb_module_init);
6050 module_exit(rtl8192_usb_module_exit);