Staging: rtl8192u: remove dead code
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / drivers / staging / rtl8192u / r8192U_core.c
blobadade13e1e19fc98fa3c85a0ba53ebc355868f15
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 // FIXME: check if 2.6.7 is ok
75 #ifdef CONFIG_RTL8192_PM
76 #include "r8192_pm.h"
77 #endif
79 #ifdef ENABLE_DOT11D
80 #include "dot11d.h"
81 #endif
82 //set here to open your trace code. //WB
83 u32 rt_global_debug_component = \
84 // COMP_INIT |
85 // COMP_DBG |
86 // COMP_EPROM |
87 // COMP_PHY |
88 // COMP_RF |
89 // COMP_FIRMWARE |
90 // COMP_CH |
91 // COMP_POWER_TRACKING |
92 // COMP_RATE |
93 // COMP_TXAGC |
94 // COMP_TRACE |
95 COMP_DOWN |
96 // COMP_RECV |
97 // COMP_SWBW |
98 COMP_SEC |
99 // COMP_RESET |
100 // COMP_SEND |
101 // COMP_EVENTS |
102 COMP_ERR ; //always open err flags on
104 #define TOTAL_CAM_ENTRY 32
105 #define CAM_CONTENT_COUNT 8
107 static struct usb_device_id rtl8192_usb_id_tbl[] = {
108 /* Realtek */
109 {USB_DEVICE(0x0bda, 0x8192)},
110 {USB_DEVICE(0x0bda, 0x8709)},
111 /* Corega */
112 {USB_DEVICE(0x07aa, 0x0043)},
113 /* Belkin */
114 {USB_DEVICE(0x050d, 0x805E)},
115 /* Sitecom */
116 {USB_DEVICE(0x0df6, 0x0031)},
117 /* EnGenius */
118 {USB_DEVICE(0x1740, 0x9201)},
119 /* Dlink */
120 {USB_DEVICE(0x2001, 0x3301)},
121 /* Zinwell */
122 {USB_DEVICE(0x5a57, 0x0290)},
126 MODULE_LICENSE("GPL");
127 MODULE_VERSION("V 1.1");
128 MODULE_DEVICE_TABLE(usb, rtl8192_usb_id_tbl);
129 MODULE_DESCRIPTION("Linux driver for Realtek RTL8192 USB WiFi cards");
131 static char* ifname = "wlan%d";
132 static int hwwep = 1; //default use hw. set 0 to use software security
133 static int channels = 0x3fff;
137 module_param(ifname, charp, S_IRUGO|S_IWUSR );
138 //module_param(hwseqnum,int, S_IRUGO|S_IWUSR);
139 module_param(hwwep,int, S_IRUGO|S_IWUSR);
140 module_param(channels,int, S_IRUGO|S_IWUSR);
142 MODULE_PARM_DESC(ifname," Net interface name, wlan%d=default");
143 //MODULE_PARM_DESC(hwseqnum," Try to use hardware 802.11 header sequence numbers. Zero=default");
144 MODULE_PARM_DESC(hwwep," Try to use hardware security support. ");
145 MODULE_PARM_DESC(channels," Channel bitmask for specific locales. NYI");
147 static int __devinit rtl8192_usb_probe(struct usb_interface *intf,
148 const struct usb_device_id *id);
149 static void __devexit rtl8192_usb_disconnect(struct usb_interface *intf);
152 static struct usb_driver rtl8192_usb_driver = {
153 .name = RTL819xU_MODULE_NAME, /* Driver name */
154 .id_table = rtl8192_usb_id_tbl, /* PCI_ID table */
155 .probe = rtl8192_usb_probe, /* probe fn */
156 .disconnect = rtl8192_usb_disconnect, /* remove fn */
157 #ifdef CONFIG_RTL8192_PM
158 .suspend = rtl8192_suspend, /* PM suspend fn */
159 .resume = rtl8192_resume, /* PM resume fn */
160 #else
161 .suspend = NULL, /* PM suspend fn */
162 .resume = NULL, /* PM resume fn */
163 #endif
166 #ifdef ENABLE_DOT11D
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;
242 #endif
244 #define eqMacAddr(a,b) ( ((a)[0]==(b)[0] && (a)[1]==(b)[1] && (a)[2]==(b)[2] && (a)[3]==(b)[3] && (a)[4]==(b)[4] && (a)[5]==(b)[5]) ? 1:0 )
246 #define rx_hal_is_cck_rate(_pdrvinfo)\
247 (_pdrvinfo->RxRate == DESC90_RATE1M ||\
248 _pdrvinfo->RxRate == DESC90_RATE2M ||\
249 _pdrvinfo->RxRate == DESC90_RATE5_5M ||\
250 _pdrvinfo->RxRate == DESC90_RATE11M) &&\
251 !_pdrvinfo->RxHT\
254 void CamResetAllEntry(struct net_device *dev)
256 u32 ulcommand = 0;
257 //2004/02/11 In static WEP, OID_ADD_KEY or OID_ADD_WEP are set before STA associate to AP.
258 // However, ResetKey is called on OID_802_11_INFRASTRUCTURE_MODE and MlmeAssociateRequest
259 // In this condition, Cam can not be reset because upper layer will not set this static key again.
260 //if(Adapter->EncAlgorithm == WEP_Encryption)
261 // return;
262 //debug
263 //DbgPrint("========================================\n");
264 //DbgPrint(" Call ResetAllEntry \n");
265 //DbgPrint("========================================\n\n");
266 ulcommand |= BIT31|BIT30;
267 write_nic_dword(dev, RWCAM, ulcommand);
272 void write_cam(struct net_device *dev, u8 addr, u32 data)
274 write_nic_dword(dev, WCAMI, data);
275 write_nic_dword(dev, RWCAM, BIT31|BIT16|(addr&0xff) );
278 u32 read_cam(struct net_device *dev, u8 addr)
280 write_nic_dword(dev, RWCAM, 0x80000000|(addr&0xff) );
281 return read_nic_dword(dev, 0xa8);
284 void write_nic_byte_E(struct net_device *dev, int indx, u8 data)
286 int status;
287 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
288 struct usb_device *udev = priv->udev;
290 status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
291 RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
292 indx|0xfe00, 0, &data, 1, HZ / 2);
294 if (status < 0)
296 printk("write_nic_byte_E TimeOut! status:%d\n", status);
300 u8 read_nic_byte_E(struct net_device *dev, int indx)
302 int status;
303 u8 data;
304 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
305 struct usb_device *udev = priv->udev;
307 status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
308 RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
309 indx|0xfe00, 0, &data, 1, HZ / 2);
311 if (status < 0)
313 printk("read_nic_byte_E TimeOut! status:%d\n", status);
316 return data;
318 //as 92U has extend page from 4 to 16, so modify functions below.
319 void write_nic_byte(struct net_device *dev, int indx, u8 data)
321 int status;
323 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
324 struct usb_device *udev = priv->udev;
326 status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
327 RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
328 (indx&0xff)|0xff00, (indx>>8)&0x0f, &data, 1, HZ / 2);
330 if (status < 0)
332 printk("write_nic_byte TimeOut! status:%d\n", status);
339 void write_nic_word(struct net_device *dev, int indx, u16 data)
342 int status;
344 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
345 struct usb_device *udev = priv->udev;
347 status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
348 RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
349 (indx&0xff)|0xff00, (indx>>8)&0x0f, &data, 2, HZ / 2);
351 if (status < 0)
353 printk("write_nic_word TimeOut! status:%d\n", status);
359 void write_nic_dword(struct net_device *dev, int indx, u32 data)
362 int status;
364 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
365 struct usb_device *udev = priv->udev;
367 status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
368 RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
369 (indx&0xff)|0xff00, (indx>>8)&0x0f, &data, 4, HZ / 2);
372 if (status < 0)
374 printk("write_nic_dword TimeOut! status:%d\n", status);
381 u8 read_nic_byte(struct net_device *dev, int indx)
383 u8 data;
384 int status;
385 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
386 struct usb_device *udev = priv->udev;
388 status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
389 RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
390 (indx&0xff)|0xff00, (indx>>8)&0x0f, &data, 1, HZ / 2);
392 if (status < 0)
394 printk("read_nic_byte TimeOut! status:%d\n", status);
397 return data;
402 u16 read_nic_word(struct net_device *dev, int indx)
404 u16 data;
405 int status;
406 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
407 struct usb_device *udev = priv->udev;
409 status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
410 RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
411 (indx&0xff)|0xff00, (indx>>8)&0x0f, &data, 2, HZ / 2);
413 if (status < 0)
415 printk("read_nic_word TimeOut! status:%d\n", status);
419 return data;
422 u16 read_nic_word_E(struct net_device *dev, int indx)
424 u16 data;
425 int status;
426 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
427 struct usb_device *udev = priv->udev;
429 status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
430 RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
431 indx|0xfe00, 0, &data, 2, HZ / 2);
433 if (status < 0)
435 printk("read_nic_word TimeOut! status:%d\n", status);
439 return data;
442 u32 read_nic_dword(struct net_device *dev, int indx)
444 u32 data;
445 int status;
446 // int result;
448 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
449 struct usb_device *udev = priv->udev;
451 status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
452 RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
453 (indx&0xff)|0xff00, (indx>>8)&0x0f, &data, 4, HZ / 2);
454 // if(0 != result) {
455 // printk(KERN_WARNING "read size of data = %d\, date = %d\n", result, data);
456 // }
458 if (status < 0)
460 printk("read_nic_dword TimeOut! status:%d\n", status);
465 return data;
469 //u8 read_phy_cck(struct net_device *dev, u8 adr);
470 //u8 read_phy_ofdm(struct net_device *dev, u8 adr);
471 /* this might still called in what was the PHY rtl8185/rtl8192 common code
472 * plans are to possibilty turn it again in one common code...
474 inline void force_pci_posting(struct net_device *dev)
479 static struct net_device_stats *rtl8192_stats(struct net_device *dev);
480 void rtl8192_commit(struct net_device *dev);
481 //void rtl8192_restart(struct net_device *dev);
482 void rtl8192_restart(struct work_struct *work);
483 //void rtl8192_rq_tx_ack(struct work_struct *work);
485 void watch_dog_timer_callback(unsigned long data);
487 /****************************************************************************
488 -----------------------------PROCFS STUFF-------------------------
489 *****************************************************************************/
491 static struct proc_dir_entry *rtl8192_proc = NULL;
495 static int proc_get_stats_ap(char *page, char **start,
496 off_t offset, int count,
497 int *eof, void *data)
499 struct net_device *dev = data;
500 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
501 struct ieee80211_device *ieee = priv->ieee80211;
502 struct ieee80211_network *target;
504 int len = 0;
506 list_for_each_entry(target, &ieee->network_list, list) {
508 len += snprintf(page + len, count - len,
509 "%s ", target->ssid);
511 if(target->wpa_ie_len>0 || target->rsn_ie_len>0){
512 len += snprintf(page + len, count - len,
513 "WPA\n");
515 else{
516 len += snprintf(page + len, count - len,
517 "non_WPA\n");
522 *eof = 1;
523 return len;
526 static int proc_get_registers(char *page, char **start,
527 off_t offset, int count,
528 int *eof, void *data)
530 struct net_device *dev = data;
531 // struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
533 int len = 0;
534 int i,n;
536 int max=0xff;
538 /* This dump the current register page */
539 len += snprintf(page + len, count - len,
540 "\n####################page 0##################\n ");
542 for(n=0;n<=max;)
544 //printk( "\nD: %2x> ", n);
545 len += snprintf(page + len, count - len,
546 "\nD: %2x > ",n);
548 for(i=0;i<16 && n<=max;i++,n++)
549 len += snprintf(page + len, count - len,
550 "%2x ",read_nic_byte(dev,0x000|n));
552 // printk("%2x ",read_nic_byte(dev,n));
554 len += snprintf(page + len, count - len,
555 "\n####################page 1##################\n ");
556 for(n=0;n<=max;)
558 //printk( "\nD: %2x> ", n);
559 len += snprintf(page + len, count - len,
560 "\nD: %2x > ",n);
562 for(i=0;i<16 && n<=max;i++,n++)
563 len += snprintf(page + len, count - len,
564 "%2x ",read_nic_byte(dev,0x100|n));
566 // printk("%2x ",read_nic_byte(dev,n));
568 len += snprintf(page + len, count - len,
569 "\n####################page 3##################\n ");
570 for(n=0;n<=max;)
572 //printk( "\nD: %2x> ", n);
573 len += snprintf(page + len, count - len,
574 "\nD: %2x > ",n);
576 for(i=0;i<16 && n<=max;i++,n++)
577 len += snprintf(page + len, count - len,
578 "%2x ",read_nic_byte(dev,0x300|n));
580 // printk("%2x ",read_nic_byte(dev,n));
584 len += snprintf(page + len, count - len,"\n");
585 *eof = 1;
586 return len;
594 static int proc_get_stats_tx(char *page, char **start,
595 off_t offset, int count,
596 int *eof, void *data)
598 struct net_device *dev = data;
599 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
601 int len = 0;
603 len += snprintf(page + len, count - len,
604 "TX VI priority ok int: %lu\n"
605 "TX VI priority error int: %lu\n"
606 "TX VO priority ok int: %lu\n"
607 "TX VO priority error int: %lu\n"
608 "TX BE priority ok int: %lu\n"
609 "TX BE priority error int: %lu\n"
610 "TX BK priority ok int: %lu\n"
611 "TX BK priority error int: %lu\n"
612 "TX MANAGE priority ok int: %lu\n"
613 "TX MANAGE priority error int: %lu\n"
614 "TX BEACON priority ok int: %lu\n"
615 "TX BEACON priority error int: %lu\n"
616 // "TX high priority ok int: %lu\n"
617 // "TX high priority failed error int: %lu\n"
618 "TX queue resume: %lu\n"
619 "TX queue stopped?: %d\n"
620 "TX fifo overflow: %lu\n"
621 // "TX beacon: %lu\n"
622 "TX VI queue: %d\n"
623 "TX VO queue: %d\n"
624 "TX BE queue: %d\n"
625 "TX BK queue: %d\n"
626 // "TX HW queue: %d\n"
627 "TX VI dropped: %lu\n"
628 "TX VO dropped: %lu\n"
629 "TX BE dropped: %lu\n"
630 "TX BK dropped: %lu\n"
631 "TX total data packets %lu\n",
632 // "TX beacon aborted: %lu\n",
633 priv->stats.txviokint,
634 priv->stats.txvierr,
635 priv->stats.txvookint,
636 priv->stats.txvoerr,
637 priv->stats.txbeokint,
638 priv->stats.txbeerr,
639 priv->stats.txbkokint,
640 priv->stats.txbkerr,
641 priv->stats.txmanageokint,
642 priv->stats.txmanageerr,
643 priv->stats.txbeaconokint,
644 priv->stats.txbeaconerr,
645 // priv->stats.txhpokint,
646 // priv->stats.txhperr,
647 priv->stats.txresumed,
648 netif_queue_stopped(dev),
649 priv->stats.txoverflow,
650 // priv->stats.txbeacon,
651 atomic_read(&(priv->tx_pending[VI_PRIORITY])),
652 atomic_read(&(priv->tx_pending[VO_PRIORITY])),
653 atomic_read(&(priv->tx_pending[BE_PRIORITY])),
654 atomic_read(&(priv->tx_pending[BK_PRIORITY])),
655 // read_nic_byte(dev, TXFIFOCOUNT),
656 priv->stats.txvidrop,
657 priv->stats.txvodrop,
658 priv->stats.txbedrop,
659 priv->stats.txbkdrop,
660 priv->stats.txdatapkt
661 // priv->stats.txbeaconerr
664 *eof = 1;
665 return len;
670 static int proc_get_stats_rx(char *page, char **start,
671 off_t offset, int count,
672 int *eof, void *data)
674 struct net_device *dev = data;
675 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
677 int len = 0;
679 len += snprintf(page + len, count - len,
680 "RX packets: %lu\n"
681 "RX urb status error: %lu\n"
682 "RX invalid urb error: %lu\n",
683 priv->stats.rxoktotal,
684 priv->stats.rxstaterr,
685 priv->stats.rxurberr);
687 *eof = 1;
688 return len;
690 void rtl8192_proc_module_init(void)
692 RT_TRACE(COMP_INIT, "Initializing proc filesystem");
693 rtl8192_proc=create_proc_entry(RTL819xU_MODULE_NAME, S_IFDIR, init_net.proc_net);
697 void rtl8192_proc_module_remove(void)
699 remove_proc_entry(RTL819xU_MODULE_NAME, init_net.proc_net);
703 void rtl8192_proc_remove_one(struct net_device *dev)
705 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
708 if (priv->dir_dev) {
709 // remove_proc_entry("stats-hw", priv->dir_dev);
710 remove_proc_entry("stats-tx", priv->dir_dev);
711 remove_proc_entry("stats-rx", priv->dir_dev);
712 // remove_proc_entry("stats-ieee", priv->dir_dev);
713 remove_proc_entry("stats-ap", priv->dir_dev);
714 remove_proc_entry("registers", priv->dir_dev);
715 // remove_proc_entry("cck-registers",priv->dir_dev);
716 // remove_proc_entry("ofdm-registers",priv->dir_dev);
717 //remove_proc_entry(dev->name, rtl8192_proc);
718 remove_proc_entry("wlan0", rtl8192_proc);
719 priv->dir_dev = NULL;
724 void rtl8192_proc_init_one(struct net_device *dev)
726 struct proc_dir_entry *e;
727 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
728 priv->dir_dev = create_proc_entry(dev->name,
729 S_IFDIR | S_IRUGO | S_IXUGO,
730 rtl8192_proc);
731 if (!priv->dir_dev) {
732 RT_TRACE(COMP_ERR, "Unable to initialize /proc/net/rtl8192/%s\n",
733 dev->name);
734 return;
736 e = create_proc_read_entry("stats-rx", S_IFREG | S_IRUGO,
737 priv->dir_dev, proc_get_stats_rx, dev);
739 if (!e) {
740 RT_TRACE(COMP_ERR,"Unable to initialize "
741 "/proc/net/rtl8192/%s/stats-rx\n",
742 dev->name);
746 e = create_proc_read_entry("stats-tx", S_IFREG | S_IRUGO,
747 priv->dir_dev, proc_get_stats_tx, dev);
749 if (!e) {
750 RT_TRACE(COMP_ERR, "Unable to initialize "
751 "/proc/net/rtl8192/%s/stats-tx\n",
752 dev->name);
755 e = create_proc_read_entry("stats-ap", S_IFREG | S_IRUGO,
756 priv->dir_dev, proc_get_stats_ap, dev);
758 if (!e) {
759 RT_TRACE(COMP_ERR, "Unable to initialize "
760 "/proc/net/rtl8192/%s/stats-ap\n",
761 dev->name);
764 e = create_proc_read_entry("registers", S_IFREG | S_IRUGO,
765 priv->dir_dev, proc_get_registers, dev);
766 if (!e) {
767 RT_TRACE(COMP_ERR, "Unable to initialize "
768 "/proc/net/rtl8192/%s/registers\n",
769 dev->name);
772 /****************************************************************************
773 -----------------------------MISC STUFF-------------------------
774 *****************************************************************************/
776 /* this is only for debugging */
777 void print_buffer(u32 *buffer, int len)
779 int i;
780 u8 *buf =(u8*)buffer;
782 printk("ASCII BUFFER DUMP (len: %x):\n",len);
784 for(i=0;i<len;i++)
785 printk("%c",buf[i]);
787 printk("\nBINARY BUFFER DUMP (len: %x):\n",len);
789 for(i=0;i<len;i++)
790 printk("%x",buf[i]);
792 printk("\n");
795 //short check_nic_enough_desc(struct net_device *dev, priority_t priority)
796 short check_nic_enough_desc(struct net_device *dev,int queue_index)
798 struct r8192_priv *priv = ieee80211_priv(dev);
799 int used = atomic_read(&priv->tx_pending[queue_index]);
801 return (used < MAX_TX_URB);
804 void tx_timeout(struct net_device *dev)
806 struct r8192_priv *priv = ieee80211_priv(dev);
807 //rtl8192_commit(dev);
809 schedule_work(&priv->reset_wq);
810 //DMESG("TXTIMEOUT");
814 /* this is only for debug */
815 void dump_eprom(struct net_device *dev)
817 int i;
818 for(i=0; i<63; i++)
819 RT_TRACE(COMP_EPROM, "EEPROM addr %x : %x", i, eprom_read(dev,i));
822 /* this is only for debug */
823 void rtl8192_dump_reg(struct net_device *dev)
825 int i;
826 int n;
827 int max=0x1ff;
829 RT_TRACE(COMP_PHY, "Dumping NIC register map");
831 for(n=0;n<=max;)
833 printk( "\nD: %2x> ", n);
834 for(i=0;i<16 && n<=max;i++,n++)
835 printk("%2x ",read_nic_byte(dev,n));
837 printk("\n");
840 /****************************************************************************
841 ------------------------------HW STUFF---------------------------
842 *****************************************************************************/
845 void rtl8192_set_mode(struct net_device *dev,int mode)
847 u8 ecmd;
848 ecmd=read_nic_byte(dev, EPROM_CMD);
849 ecmd=ecmd &~ EPROM_CMD_OPERATING_MODE_MASK;
850 ecmd=ecmd | (mode<<EPROM_CMD_OPERATING_MODE_SHIFT);
851 ecmd=ecmd &~ (1<<EPROM_CS_SHIFT);
852 ecmd=ecmd &~ (1<<EPROM_CK_SHIFT);
853 write_nic_byte(dev, EPROM_CMD, ecmd);
857 void rtl8192_update_msr(struct net_device *dev)
859 struct r8192_priv *priv = ieee80211_priv(dev);
860 u8 msr;
862 msr = read_nic_byte(dev, MSR);
863 msr &= ~ MSR_LINK_MASK;
865 /* do not change in link_state != WLAN_LINK_ASSOCIATED.
866 * msr must be updated if the state is ASSOCIATING.
867 * this is intentional and make sense for ad-hoc and
868 * master (see the create BSS/IBSS func)
870 if (priv->ieee80211->state == IEEE80211_LINKED){
872 if (priv->ieee80211->iw_mode == IW_MODE_INFRA)
873 msr |= (MSR_LINK_MANAGED<<MSR_LINK_SHIFT);
874 else if (priv->ieee80211->iw_mode == IW_MODE_ADHOC)
875 msr |= (MSR_LINK_ADHOC<<MSR_LINK_SHIFT);
876 else if (priv->ieee80211->iw_mode == IW_MODE_MASTER)
877 msr |= (MSR_LINK_MASTER<<MSR_LINK_SHIFT);
879 }else
880 msr |= (MSR_LINK_NONE<<MSR_LINK_SHIFT);
882 write_nic_byte(dev, MSR, msr);
885 void rtl8192_set_chan(struct net_device *dev,short ch)
887 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
888 // u32 tx;
889 RT_TRACE(COMP_CH, "=====>%s()====ch:%d\n", __FUNCTION__, ch);
890 priv->chan=ch;
892 /* this hack should avoid frame TX during channel setting*/
895 // tx = read_nic_dword(dev,TX_CONF);
896 // tx &= ~TX_LOOPBACK_MASK;
898 #ifndef LOOP_TEST
899 // write_nic_dword(dev,TX_CONF, tx |( TX_LOOPBACK_MAC<<TX_LOOPBACK_SHIFT));
901 //need to implement rf set channel here WB
903 if (priv->rf_set_chan)
904 priv->rf_set_chan(dev,priv->chan);
905 mdelay(10);
906 // write_nic_dword(dev,TX_CONF,tx | (TX_LOOPBACK_NONE<<TX_LOOPBACK_SHIFT));
907 #endif
910 static void rtl8192_rx_isr(struct urb *urb);
911 //static void rtl8192_rx_isr(struct urb *rx_urb);
913 u32 get_rxpacket_shiftbytes_819xusb(struct ieee80211_rx_stats *pstats)
916 #ifdef USB_RX_AGGREGATION_SUPPORT
917 if (pstats->bisrxaggrsubframe)
918 return (sizeof(rx_desc_819x_usb) + pstats->RxDrvInfoSize
919 + pstats->RxBufShift + 8);
920 else
921 #endif
922 return (sizeof(rx_desc_819x_usb) + pstats->RxDrvInfoSize
923 + pstats->RxBufShift);
926 static int rtl8192_rx_initiate(struct net_device*dev)
928 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
929 struct urb *entry;
930 struct sk_buff *skb;
931 struct rtl8192_rx_info *info;
933 /* nomal packet rx procedure */
934 while (skb_queue_len(&priv->rx_queue) < MAX_RX_URB) {
935 skb = __dev_alloc_skb(RX_URB_SIZE, GFP_KERNEL);
936 if (!skb)
937 break;
938 entry = usb_alloc_urb(0, GFP_KERNEL);
939 if (!entry) {
940 kfree_skb(skb);
941 break;
943 // printk("nomal packet IN request!\n");
944 usb_fill_bulk_urb(entry, priv->udev,
945 usb_rcvbulkpipe(priv->udev, 3), skb_tail_pointer(skb),
946 RX_URB_SIZE, rtl8192_rx_isr, skb);
947 info = (struct rtl8192_rx_info *) skb->cb;
948 info->urb = entry;
949 info->dev = dev;
950 info->out_pipe = 3; //denote rx normal packet queue
951 skb_queue_tail(&priv->rx_queue, skb);
952 usb_submit_urb(entry, GFP_KERNEL);
955 /* command packet rx procedure */
956 while (skb_queue_len(&priv->rx_queue) < MAX_RX_URB + 3) {
957 // printk("command packet IN request!\n");
958 skb = __dev_alloc_skb(RX_URB_SIZE ,GFP_KERNEL);
959 if (!skb)
960 break;
961 entry = usb_alloc_urb(0, GFP_KERNEL);
962 if (!entry) {
963 kfree_skb(skb);
964 break;
966 usb_fill_bulk_urb(entry, priv->udev,
967 usb_rcvbulkpipe(priv->udev, 9), skb_tail_pointer(skb),
968 RX_URB_SIZE, rtl8192_rx_isr, skb);
969 info = (struct rtl8192_rx_info *) skb->cb;
970 info->urb = entry;
971 info->dev = dev;
972 info->out_pipe = 9; //denote rx cmd packet queue
973 skb_queue_tail(&priv->rx_queue, skb);
974 usb_submit_urb(entry, GFP_KERNEL);
977 return 0;
980 void rtl8192_set_rxconf(struct net_device *dev)
982 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
983 u32 rxconf;
985 rxconf=read_nic_dword(dev,RCR);
986 rxconf = rxconf &~ MAC_FILTER_MASK;
987 rxconf = rxconf | RCR_AMF;
988 rxconf = rxconf | RCR_ADF;
989 rxconf = rxconf | RCR_AB;
990 rxconf = rxconf | RCR_AM;
991 //rxconf = rxconf | RCR_ACF;
993 if (dev->flags & IFF_PROMISC) {DMESG ("NIC in promisc mode");}
995 if(priv->ieee80211->iw_mode == IW_MODE_MONITOR || \
996 dev->flags & IFF_PROMISC){
997 rxconf = rxconf | RCR_AAP;
998 } /*else if(priv->ieee80211->iw_mode == IW_MODE_MASTER){
999 rxconf = rxconf | (1<<ACCEPT_ALLMAC_FRAME_SHIFT);
1000 rxconf = rxconf | (1<<RX_CHECK_BSSID_SHIFT);
1001 }*/else{
1002 rxconf = rxconf | RCR_APM;
1003 rxconf = rxconf | RCR_CBSSID;
1007 if(priv->ieee80211->iw_mode == IW_MODE_MONITOR){
1008 rxconf = rxconf | RCR_AICV;
1009 rxconf = rxconf | RCR_APWRMGT;
1012 if( priv->crcmon == 1 && priv->ieee80211->iw_mode == IW_MODE_MONITOR)
1013 rxconf = rxconf | RCR_ACRC32;
1016 rxconf = rxconf &~ RX_FIFO_THRESHOLD_MASK;
1017 rxconf = rxconf | (RX_FIFO_THRESHOLD_NONE<<RX_FIFO_THRESHOLD_SHIFT);
1018 rxconf = rxconf &~ MAX_RX_DMA_MASK;
1019 rxconf = rxconf | ((u32)7<<RCR_MXDMA_OFFSET);
1021 // rxconf = rxconf | (1<<RX_AUTORESETPHY_SHIFT);
1022 rxconf = rxconf | RCR_ONLYERLPKT;
1024 // rxconf = rxconf &~ RCR_CS_MASK;
1025 // rxconf = rxconf | (1<<RCR_CS_SHIFT);
1027 write_nic_dword(dev, RCR, rxconf);
1029 #ifdef DEBUG_RX
1030 DMESG("rxconf: %x %x",rxconf ,read_nic_dword(dev,RCR));
1031 #endif
1033 //wait to be removed
1034 void rtl8192_rx_enable(struct net_device *dev)
1036 //u8 cmd;
1038 //struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1040 rtl8192_rx_initiate(dev);
1042 // rtl8192_set_rxconf(dev);
1046 void rtl8192_tx_enable(struct net_device *dev)
1052 void rtl8192_rtx_disable(struct net_device *dev)
1054 u8 cmd;
1055 struct r8192_priv *priv = ieee80211_priv(dev);
1056 struct sk_buff *skb;
1057 struct rtl8192_rx_info *info;
1059 cmd=read_nic_byte(dev,CMDR);
1060 write_nic_byte(dev, CMDR, cmd &~ \
1061 (CR_TE|CR_RE));
1062 force_pci_posting(dev);
1063 mdelay(10);
1065 while ((skb = __skb_dequeue(&priv->rx_queue))) {
1066 info = (struct rtl8192_rx_info *) skb->cb;
1067 if (!info->urb)
1068 continue;
1070 usb_kill_urb(info->urb);
1071 kfree_skb(skb);
1074 if (skb_queue_len(&priv->skb_queue)) {
1075 printk(KERN_WARNING "skb_queue not empty\n");
1078 skb_queue_purge(&priv->skb_queue);
1079 return;
1083 int alloc_tx_beacon_desc_ring(struct net_device *dev, int count)
1085 return 0;
1088 inline u16 ieeerate2rtlrate(int rate)
1090 switch(rate){
1091 case 10:
1092 return 0;
1093 case 20:
1094 return 1;
1095 case 55:
1096 return 2;
1097 case 110:
1098 return 3;
1099 case 60:
1100 return 4;
1101 case 90:
1102 return 5;
1103 case 120:
1104 return 6;
1105 case 180:
1106 return 7;
1107 case 240:
1108 return 8;
1109 case 360:
1110 return 9;
1111 case 480:
1112 return 10;
1113 case 540:
1114 return 11;
1115 default:
1116 return 3;
1120 static u16 rtl_rate[] = {10,20,55,110,60,90,120,180,240,360,480,540};
1121 inline u16 rtl8192_rate2rate(short rate)
1123 if (rate >11) return 0;
1124 return rtl_rate[rate];
1128 /* The protype of rx_isr has changed since one verion of Linux Kernel */
1129 static void rtl8192_rx_isr(struct urb *urb)
1131 struct sk_buff *skb = (struct sk_buff *) urb->context;
1132 struct rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
1133 struct net_device *dev = info->dev;
1134 struct r8192_priv *priv = ieee80211_priv(dev);
1135 int out_pipe = info->out_pipe;
1136 int err;
1137 if(!priv->up)
1138 return;
1139 if (unlikely(urb->status)) {
1140 info->urb = NULL;
1141 priv->stats.rxstaterr++;
1142 priv->ieee80211->stats.rx_errors++;
1143 usb_free_urb(urb);
1144 // printk("%s():rx status err\n",__FUNCTION__);
1145 return;
1147 skb_unlink(skb, &priv->rx_queue);
1148 skb_put(skb, urb->actual_length);
1150 skb_queue_tail(&priv->skb_queue, skb);
1151 tasklet_schedule(&priv->irq_rx_tasklet);
1153 skb = dev_alloc_skb(RX_URB_SIZE);
1154 if (unlikely(!skb)) {
1155 usb_free_urb(urb);
1156 printk("%s():can,t alloc skb\n",__FUNCTION__);
1157 /* TODO check rx queue length and refill *somewhere* */
1158 return;
1161 usb_fill_bulk_urb(urb, priv->udev,
1162 usb_rcvbulkpipe(priv->udev, out_pipe), skb_tail_pointer(skb),
1163 RX_URB_SIZE, rtl8192_rx_isr, skb);
1165 info = (struct rtl8192_rx_info *) skb->cb;
1166 info->urb = urb;
1167 info->dev = dev;
1168 info->out_pipe = out_pipe;
1170 urb->transfer_buffer = skb_tail_pointer(skb);
1171 urb->context = skb;
1172 skb_queue_tail(&priv->rx_queue, skb);
1173 err = usb_submit_urb(urb, GFP_ATOMIC);
1174 if(err && err != EPERM)
1175 printk("can not submit rxurb, err is %x,URB status is %x\n",err,urb->status);
1179 rtl819xusb_rx_command_packet(
1180 struct net_device *dev,
1181 struct ieee80211_rx_stats *pstats
1184 u32 status;
1186 //RT_TRACE(COMP_RECV, DBG_TRACE, ("---> RxCommandPacketHandle819xUsb()\n"));
1188 status = cmpk_message_handle_rx(dev, pstats);
1189 if (status)
1191 DMESG("rxcommandpackethandle819xusb: It is a command packet\n");
1193 else
1195 //RT_TRACE(COMP_RECV, DBG_TRACE, ("RxCommandPacketHandle819xUsb: It is not a command packet\n"));
1198 //RT_TRACE(COMP_RECV, DBG_TRACE, ("<--- RxCommandPacketHandle819xUsb()\n"));
1199 return status;
1203 void rtl8192_data_hard_stop(struct net_device *dev)
1205 //FIXME !!
1209 void rtl8192_data_hard_resume(struct net_device *dev)
1211 // FIXME !!
1214 /* this function TX data frames when the ieee80211 stack requires this.
1215 * It checks also if we need to stop the ieee tx queue, eventually do it
1217 void rtl8192_hard_data_xmit(struct sk_buff *skb, struct net_device *dev, int rate)
1219 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1220 int ret;
1221 unsigned long flags;
1222 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1223 u8 queue_index = tcb_desc->queue_index;
1225 /* shall not be referred by command packet */
1226 assert(queue_index != TXCMD_QUEUE);
1228 spin_lock_irqsave(&priv->tx_lock,flags);
1230 memcpy((unsigned char *)(skb->cb),&dev,sizeof(dev));
1231 // tcb_desc->RATRIndex = 7;
1232 // tcb_desc->bTxDisableRateFallBack = 1;
1233 // tcb_desc->bTxUseDriverAssingedRate = 1;
1234 tcb_desc->bTxEnableFwCalcDur = 1;
1235 skb_push(skb, priv->ieee80211->tx_headroom);
1236 ret = rtl8192_tx(dev, skb);
1238 //priv->ieee80211->stats.tx_bytes+=(skb->len - priv->ieee80211->tx_headroom);
1239 //priv->ieee80211->stats.tx_packets++;
1241 spin_unlock_irqrestore(&priv->tx_lock,flags);
1243 // return ret;
1244 return;
1247 /* This is a rough attempt to TX a frame
1248 * This is called by the ieee 80211 stack to TX management frames.
1249 * If the ring is full packet are dropped (for data frame the queue
1250 * is stopped before this can happen).
1252 int rtl8192_hard_start_xmit(struct sk_buff *skb,struct net_device *dev)
1254 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1255 int ret;
1256 unsigned long flags;
1257 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1258 u8 queue_index = tcb_desc->queue_index;
1261 spin_lock_irqsave(&priv->tx_lock,flags);
1263 memcpy((unsigned char *)(skb->cb),&dev,sizeof(dev));
1264 if(queue_index == TXCMD_QUEUE) {
1265 skb_push(skb, USB_HWDESC_HEADER_LEN);
1266 rtl819xU_tx_cmd(dev, skb);
1267 ret = 1;
1268 spin_unlock_irqrestore(&priv->tx_lock,flags);
1269 return ret;
1270 } else {
1271 skb_push(skb, priv->ieee80211->tx_headroom);
1272 ret = rtl8192_tx(dev, skb);
1275 spin_unlock_irqrestore(&priv->tx_lock,flags);
1277 return ret;
1281 void rtl8192_try_wake_queue(struct net_device *dev, int pri);
1283 #ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
1284 u16 DrvAggr_PaddingAdd(struct net_device *dev, struct sk_buff *skb)
1286 u16 PaddingNum = 256 - ((skb->len + TX_PACKET_DRVAGGR_SUBFRAME_SHIFT_BYTES) % 256);
1287 return (PaddingNum&0xff);
1290 u8 MRateToHwRate8190Pci(u8 rate);
1291 u8 QueryIsShort(u8 TxHT, u8 TxRate, cb_desc *tcb_desc);
1292 u8 MapHwQueueToFirmwareQueue(u8 QueueID);
1293 struct sk_buff *DrvAggr_Aggregation(struct net_device *dev, struct ieee80211_drv_agg_txb *pSendList)
1295 struct ieee80211_device *ieee = netdev_priv(dev);
1296 struct r8192_priv *priv = ieee80211_priv(dev);
1297 cb_desc *tcb_desc = NULL;
1298 u8 i;
1299 u32 TotalLength;
1300 struct sk_buff *skb;
1301 struct sk_buff *agg_skb;
1302 tx_desc_819x_usb_aggr_subframe *tx_agg_desc = NULL;
1303 tx_fwinfo_819x_usb *tx_fwinfo = NULL;
1306 // Local variable initialization.
1308 /* first skb initialization */
1309 skb = pSendList->tx_agg_frames[0];
1310 TotalLength = skb->len;
1312 /* Get the total aggregation length including the padding space and
1313 * sub frame header.
1315 for(i = 1; i < pSendList->nr_drv_agg_frames; i++) {
1316 TotalLength += DrvAggr_PaddingAdd(dev, skb);
1317 skb = pSendList->tx_agg_frames[i];
1318 TotalLength += (skb->len + TX_PACKET_DRVAGGR_SUBFRAME_SHIFT_BYTES);
1321 /* allocate skb to contain the aggregated packets */
1322 agg_skb = dev_alloc_skb(TotalLength + ieee->tx_headroom);
1323 memset(agg_skb->data, 0, agg_skb->len);
1324 skb_reserve(agg_skb, ieee->tx_headroom);
1326 // RT_DEBUG_DATA(COMP_SEND, skb->cb, sizeof(skb->cb));
1327 /* reserve info for first subframe Tx descriptor to be set in the tx function */
1328 skb = pSendList->tx_agg_frames[0];
1329 tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1330 tcb_desc->drv_agg_enable = 1;
1331 tcb_desc->pkt_size = skb->len;
1332 tcb_desc->DrvAggrNum = pSendList->nr_drv_agg_frames;
1333 printk("DrvAggNum = %d\n", tcb_desc->DrvAggrNum);
1334 // RT_DEBUG_DATA(COMP_SEND, skb->cb, sizeof(skb->cb));
1335 // printk("========>skb->data ======> \n");
1336 // RT_DEBUG_DATA(COMP_SEND, skb->data, skb->len);
1337 memcpy(agg_skb->cb, skb->cb, sizeof(skb->cb));
1338 memcpy(skb_put(agg_skb,skb->len),skb->data,skb->len);
1340 for(i = 1; i < pSendList->nr_drv_agg_frames; i++) {
1341 /* push the next sub frame to be 256 byte aline */
1342 skb_put(agg_skb,DrvAggr_PaddingAdd(dev,skb));
1344 /* Subframe drv Tx descriptor and firmware info setting */
1345 skb = pSendList->tx_agg_frames[i];
1346 tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1347 tx_agg_desc = (tx_desc_819x_usb_aggr_subframe *)agg_skb->tail;
1348 tx_fwinfo = (tx_fwinfo_819x_usb *)(agg_skb->tail + sizeof(tx_desc_819x_usb_aggr_subframe));
1350 memset(tx_fwinfo,0,sizeof(tx_fwinfo_819x_usb));
1351 /* DWORD 0 */
1352 tx_fwinfo->TxHT = (tcb_desc->data_rate&0x80)?1:0;
1353 tx_fwinfo->TxRate = MRateToHwRate8190Pci(tcb_desc->data_rate);
1354 tx_fwinfo->EnableCPUDur = tcb_desc->bTxEnableFwCalcDur;
1355 tx_fwinfo->Short = QueryIsShort(tx_fwinfo->TxHT, tx_fwinfo->TxRate, tcb_desc);
1356 if(tcb_desc->bAMPDUEnable) {//AMPDU enabled
1357 tx_fwinfo->AllowAggregation = 1;
1358 /* DWORD 1 */
1359 tx_fwinfo->RxMF = tcb_desc->ampdu_factor;
1360 tx_fwinfo->RxAMD = tcb_desc->ampdu_density&0x07;//ampdudensity
1361 } else {
1362 tx_fwinfo->AllowAggregation = 0;
1363 /* DWORD 1 */
1364 tx_fwinfo->RxMF = 0;
1365 tx_fwinfo->RxAMD = 0;
1368 /* Protection mode related */
1369 tx_fwinfo->RtsEnable = (tcb_desc->bRTSEnable)?1:0;
1370 tx_fwinfo->CtsEnable = (tcb_desc->bCTSEnable)?1:0;
1371 tx_fwinfo->RtsSTBC = (tcb_desc->bRTSSTBC)?1:0;
1372 tx_fwinfo->RtsHT = (tcb_desc->rts_rate&0x80)?1:0;
1373 tx_fwinfo->RtsRate = MRateToHwRate8190Pci((u8)tcb_desc->rts_rate);
1374 tx_fwinfo->RtsSubcarrier = (tx_fwinfo->RtsHT==0)?(tcb_desc->RTSSC):0;
1375 tx_fwinfo->RtsBandwidth = (tx_fwinfo->RtsHT==1)?((tcb_desc->bRTSBW)?1:0):0;
1376 tx_fwinfo->RtsShort = (tx_fwinfo->RtsHT==0)?(tcb_desc->bRTSUseShortPreamble?1:0):\
1377 (tcb_desc->bRTSUseShortGI?1:0);
1379 /* Set Bandwidth and sub-channel settings. */
1380 if(priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20_40)
1382 if(tcb_desc->bPacketBW) {
1383 tx_fwinfo->TxBandwidth = 1;
1384 tx_fwinfo->TxSubCarrier = 0; //By SD3's Jerry suggestion, use duplicated mode
1385 } else {
1386 tx_fwinfo->TxBandwidth = 0;
1387 tx_fwinfo->TxSubCarrier = priv->nCur40MhzPrimeSC;
1389 } else {
1390 tx_fwinfo->TxBandwidth = 0;
1391 tx_fwinfo->TxSubCarrier = 0;
1394 /* Fill Tx descriptor */
1395 memset(tx_agg_desc, 0, sizeof(tx_desc_819x_usb_aggr_subframe));
1396 /* DWORD 0 */
1397 //tx_agg_desc->LINIP = 0;
1398 //tx_agg_desc->CmdInit = 1;
1399 tx_agg_desc->Offset = sizeof(tx_fwinfo_819x_usb) + 8;
1400 /* already raw data, need not to substract header length */
1401 tx_agg_desc->PktSize = skb->len & 0xffff;
1403 /*DWORD 1*/
1404 tx_agg_desc->SecCAMID= 0;
1405 tx_agg_desc->RATid = tcb_desc->RATRIndex;
1407 //MPDUOverhead = 0;
1408 tx_agg_desc->NoEnc = 1;
1410 tx_agg_desc->SecType = 0x0;
1412 if (tcb_desc->bHwSec) {
1413 switch (priv->ieee80211->pairwise_key_type)
1415 case KEY_TYPE_WEP40:
1416 case KEY_TYPE_WEP104:
1417 tx_agg_desc->SecType = 0x1;
1418 tx_agg_desc->NoEnc = 0;
1419 break;
1420 case KEY_TYPE_TKIP:
1421 tx_agg_desc->SecType = 0x2;
1422 tx_agg_desc->NoEnc = 0;
1423 break;
1424 case KEY_TYPE_CCMP:
1425 tx_agg_desc->SecType = 0x3;
1426 tx_agg_desc->NoEnc = 0;
1427 break;
1428 case KEY_TYPE_NA:
1429 tx_agg_desc->SecType = 0x0;
1430 tx_agg_desc->NoEnc = 1;
1431 break;
1435 tx_agg_desc->QueueSelect = MapHwQueueToFirmwareQueue(tcb_desc->queue_index);
1436 tx_agg_desc->TxFWInfoSize = sizeof(tx_fwinfo_819x_usb);
1438 tx_agg_desc->DISFB = tcb_desc->bTxDisableRateFallBack;
1439 tx_agg_desc->USERATE = tcb_desc->bTxUseDriverAssingedRate;
1441 tx_agg_desc->OWN = 1;
1443 //DWORD 2
1444 /* According windows driver, it seems that there no need to fill this field */
1445 //tx_agg_desc->TxBufferSize= (u32)(skb->len - USB_HWDESC_HEADER_LEN);
1447 /* to fill next packet */
1448 skb_put(agg_skb,TX_PACKET_DRVAGGR_SUBFRAME_SHIFT_BYTES);
1449 memcpy(skb_put(agg_skb,skb->len),skb->data,skb->len);
1452 for(i = 0; i < pSendList->nr_drv_agg_frames; i++) {
1453 dev_kfree_skb_any(pSendList->tx_agg_frames[i]);
1456 return agg_skb;
1459 /* NOTE:
1460 This function return a list of PTCB which is proper to be aggregate with the input TCB.
1461 If no proper TCB is found to do aggregation, SendList will only contain the input TCB.
1463 u8 DrvAggr_GetAggregatibleList(struct net_device *dev, struct sk_buff *skb,
1464 struct ieee80211_drv_agg_txb *pSendList)
1466 struct ieee80211_device *ieee = netdev_priv(dev);
1467 PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
1468 u16 nMaxAggrNum = pHTInfo->UsbTxAggrNum;
1469 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1470 u8 QueueID = tcb_desc->queue_index;
1472 do {
1473 pSendList->tx_agg_frames[pSendList->nr_drv_agg_frames++] = skb;
1474 if(pSendList->nr_drv_agg_frames >= nMaxAggrNum) {
1475 break;
1478 } while((skb = skb_dequeue(&ieee->skb_drv_aggQ[QueueID])));
1480 RT_TRACE(COMP_AMSDU, "DrvAggr_GetAggregatibleList, nAggrTcbNum = %d \n", pSendList->nr_drv_agg_frames);
1481 return pSendList->nr_drv_agg_frames;
1483 #endif
1485 static void rtl8192_tx_isr(struct urb *tx_urb)
1487 struct sk_buff *skb = (struct sk_buff*)tx_urb->context;
1488 struct net_device *dev = NULL;
1489 struct r8192_priv *priv = NULL;
1490 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1491 u8 queue_index = tcb_desc->queue_index;
1492 // bool bToSend0Byte;
1493 // u16 BufLen = skb->len;
1495 memcpy(&dev,(struct net_device*)(skb->cb),sizeof(struct net_device*));
1496 priv = ieee80211_priv(dev);
1498 if(tcb_desc->queue_index != TXCMD_QUEUE) {
1499 if(tx_urb->status == 0) {
1500 dev->trans_start = jiffies;
1501 // As act as station mode, destion shall be unicast address.
1502 //priv->ieee80211->stats.tx_bytes+=(skb->len - priv->ieee80211->tx_headroom);
1503 //priv->ieee80211->stats.tx_packets++;
1504 priv->stats.txoktotal++;
1505 priv->ieee80211->LinkDetectInfo.NumTxOkInPeriod++;
1506 priv->stats.txbytesunicast += (skb->len - priv->ieee80211->tx_headroom);
1507 } else {
1508 priv->ieee80211->stats.tx_errors++;
1509 //priv->stats.txmanageerr++;
1510 /* TODO */
1514 /* free skb and tx_urb */
1515 if(skb != NULL) {
1516 dev_kfree_skb_any(skb);
1517 usb_free_urb(tx_urb);
1518 atomic_dec(&priv->tx_pending[queue_index]);
1523 // Handle HW Beacon:
1524 // We had transfer our beacon frame to host controler at this moment.
1527 // Caution:
1528 // Handling the wait queue of command packets.
1529 // For Tx command packets, we must not do TCB fragment because it is not handled right now.
1530 // We must cut the packets to match the size of TX_CMD_PKT before we send it.
1533 /* Handle MPDU in wait queue. */
1534 if(queue_index != BEACON_QUEUE) {
1535 /* Don't send data frame during scanning.*/
1536 if((skb_queue_len(&priv->ieee80211->skb_waitQ[queue_index]) != 0)&&\
1537 (!(priv->ieee80211->queue_stop))) {
1538 if(NULL != (skb = skb_dequeue(&(priv->ieee80211->skb_waitQ[queue_index]))))
1539 priv->ieee80211->softmac_hard_start_xmit(skb, dev);
1541 return; //modified by david to avoid further processing AMSDU
1543 #ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
1544 else if ((skb_queue_len(&priv->ieee80211->skb_drv_aggQ[queue_index])!= 0)&&\
1545 (!(priv->ieee80211->queue_stop))) {
1546 // Tx Driver Aggregation process
1547 /* The driver will aggregation the packets according to the following stets
1548 * 1. check whether there's tx irq available, for it's a completion return
1549 * function, it should contain enough tx irq;
1550 * 2. check pakcet type;
1551 * 3. intialize sendlist, check whether the to-be send packet no greater than 1
1552 * 4. aggregation the packets, and fill firmware info and tx desc to it, etc.
1553 * 5. check whehter the packet could be sent, otherwise just insert to wait head
1554 * */
1555 skb = skb_dequeue(&priv->ieee80211->skb_drv_aggQ[queue_index]);
1556 if(!check_nic_enough_desc(dev, queue_index)) {
1557 skb_queue_head(&(priv->ieee80211->skb_drv_aggQ[queue_index]), skb);
1558 return;
1562 /*TODO*/
1564 u8* pHeader = skb->data;
1566 if(IsMgntQosData(pHeader) ||
1567 IsMgntQData_Ack(pHeader) ||
1568 IsMgntQData_Poll(pHeader) ||
1569 IsMgntQData_Poll_Ack(pHeader)
1573 struct ieee80211_drv_agg_txb SendList;
1575 memset(&SendList, 0, sizeof(struct ieee80211_drv_agg_txb));
1576 if(DrvAggr_GetAggregatibleList(dev, skb, &SendList) > 1) {
1577 skb = DrvAggr_Aggregation(dev, &SendList);
1581 priv->ieee80211->softmac_hard_start_xmit(skb, dev);
1584 #endif
1590 void rtl8192_beacon_stop(struct net_device *dev)
1592 u8 msr, msrm, msr2;
1593 struct r8192_priv *priv = ieee80211_priv(dev);
1595 msr = read_nic_byte(dev, MSR);
1596 msrm = msr & MSR_LINK_MASK;
1597 msr2 = msr & ~MSR_LINK_MASK;
1599 if(NIC_8192U == priv->card_8192) {
1600 usb_kill_urb(priv->rx_urb[MAX_RX_URB]);
1602 if ((msrm == (MSR_LINK_ADHOC<<MSR_LINK_SHIFT) ||
1603 (msrm == (MSR_LINK_MASTER<<MSR_LINK_SHIFT)))){
1604 write_nic_byte(dev, MSR, msr2 | MSR_LINK_NONE);
1605 write_nic_byte(dev, MSR, msr);
1609 void rtl8192_config_rate(struct net_device* dev, u16* rate_config)
1611 struct r8192_priv *priv = ieee80211_priv(dev);
1612 struct ieee80211_network *net;
1613 u8 i=0, basic_rate = 0;
1614 net = & priv->ieee80211->current_network;
1616 for (i=0; i<net->rates_len; i++)
1618 basic_rate = net->rates[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;
1635 for (i=0; i<net->rates_ex_len; i++)
1637 basic_rate = net->rates_ex[i]&0x7f;
1638 switch(basic_rate)
1640 case MGN_1M: *rate_config |= RRSR_1M; break;
1641 case MGN_2M: *rate_config |= RRSR_2M; break;
1642 case MGN_5_5M: *rate_config |= RRSR_5_5M; break;
1643 case MGN_11M: *rate_config |= RRSR_11M; break;
1644 case MGN_6M: *rate_config |= RRSR_6M; break;
1645 case MGN_9M: *rate_config |= RRSR_9M; break;
1646 case MGN_12M: *rate_config |= RRSR_12M; break;
1647 case MGN_18M: *rate_config |= RRSR_18M; break;
1648 case MGN_24M: *rate_config |= RRSR_24M; break;
1649 case MGN_36M: *rate_config |= RRSR_36M; break;
1650 case MGN_48M: *rate_config |= RRSR_48M; break;
1651 case MGN_54M: *rate_config |= RRSR_54M; break;
1657 #define SHORT_SLOT_TIME 9
1658 #define NON_SHORT_SLOT_TIME 20
1660 void rtl8192_update_cap(struct net_device* dev, u16 cap)
1662 u32 tmp = 0;
1663 struct r8192_priv *priv = ieee80211_priv(dev);
1664 struct ieee80211_network *net = &priv->ieee80211->current_network;
1665 priv->short_preamble = cap & WLAN_CAPABILITY_SHORT_PREAMBLE;
1666 tmp = priv->basic_rate;
1667 if (priv->short_preamble)
1668 tmp |= BRSR_AckShortPmb;
1669 write_nic_dword(dev, RRSR, tmp);
1671 if (net->mode & (IEEE_G|IEEE_N_24G))
1673 u8 slot_time = 0;
1674 if ((cap & WLAN_CAPABILITY_SHORT_SLOT)&&(!priv->ieee80211->pHTInfo->bCurrentRT2RTLongSlotTime))
1675 {//short slot time
1676 slot_time = SHORT_SLOT_TIME;
1678 else //long slot time
1679 slot_time = NON_SHORT_SLOT_TIME;
1680 priv->slot_time = slot_time;
1681 write_nic_byte(dev, SLOT_TIME, slot_time);
1685 void rtl8192_net_update(struct net_device *dev)
1688 struct r8192_priv *priv = ieee80211_priv(dev);
1689 struct ieee80211_network *net;
1690 u16 BcnTimeCfg = 0, BcnCW = 6, BcnIFS = 0xf;
1691 u16 rate_config = 0;
1692 net = & priv->ieee80211->current_network;
1694 rtl8192_config_rate(dev, &rate_config);
1695 priv->basic_rate = rate_config &= 0x15f;
1697 write_nic_dword(dev,BSSIDR,((u32*)net->bssid)[0]);
1698 write_nic_word(dev,BSSIDR+4,((u16*)net->bssid)[2]);
1699 //for(i=0;i<ETH_ALEN;i++)
1700 // write_nic_byte(dev,BSSID+i,net->bssid[i]);
1702 rtl8192_update_msr(dev);
1703 // rtl8192_update_cap(dev, net->capability);
1704 if (priv->ieee80211->iw_mode == IW_MODE_ADHOC)
1706 write_nic_word(dev, ATIMWND, 2);
1707 write_nic_word(dev, BCN_DMATIME, 1023);
1708 write_nic_word(dev, BCN_INTERVAL, net->beacon_interval);
1709 // write_nic_word(dev, BcnIntTime, 100);
1710 write_nic_word(dev, BCN_DRV_EARLY_INT, 1);
1711 write_nic_byte(dev, BCN_ERR_THRESH, 100);
1712 BcnTimeCfg |= (BcnCW<<BCN_TCFG_CW_SHIFT);
1713 // TODO: BcnIFS may required to be changed on ASIC
1714 BcnTimeCfg |= BcnIFS<<BCN_TCFG_IFS;
1716 write_nic_word(dev, BCN_TCFG, BcnTimeCfg);
1723 //temporary hw beacon is not used any more.
1724 //open it when necessary
1725 void rtl819xusb_beacon_tx(struct net_device *dev,u16 tx_rate)
1729 inline u8 rtl8192_IsWirelessBMode(u16 rate)
1731 if( ((rate <= 110) && (rate != 60) && (rate != 90)) || (rate == 220) )
1732 return 1;
1733 else return 0;
1736 u16 N_DBPSOfRate(u16 DataRate);
1738 u16 ComputeTxTime(
1739 u16 FrameLength,
1740 u16 DataRate,
1741 u8 bManagementFrame,
1742 u8 bShortPreamble
1745 u16 FrameTime;
1746 u16 N_DBPS;
1747 u16 Ceiling;
1749 if( rtl8192_IsWirelessBMode(DataRate) )
1751 if( bManagementFrame || !bShortPreamble || DataRate == 10 )
1752 { // long preamble
1753 FrameTime = (u16)(144+48+(FrameLength*8/(DataRate/10)));
1755 else
1756 { // Short preamble
1757 FrameTime = (u16)(72+24+(FrameLength*8/(DataRate/10)));
1759 if( ( FrameLength*8 % (DataRate/10) ) != 0 ) //Get the Ceilling
1760 FrameTime ++;
1761 } else { //802.11g DSSS-OFDM PLCP length field calculation.
1762 N_DBPS = N_DBPSOfRate(DataRate);
1763 Ceiling = (16 + 8*FrameLength + 6) / N_DBPS
1764 + (((16 + 8*FrameLength + 6) % N_DBPS) ? 1 : 0);
1765 FrameTime = (u16)(16 + 4 + 4*Ceiling + 6);
1767 return FrameTime;
1770 u16 N_DBPSOfRate(u16 DataRate)
1772 u16 N_DBPS = 24;
1774 switch(DataRate)
1776 case 60:
1777 N_DBPS = 24;
1778 break;
1780 case 90:
1781 N_DBPS = 36;
1782 break;
1784 case 120:
1785 N_DBPS = 48;
1786 break;
1788 case 180:
1789 N_DBPS = 72;
1790 break;
1792 case 240:
1793 N_DBPS = 96;
1794 break;
1796 case 360:
1797 N_DBPS = 144;
1798 break;
1800 case 480:
1801 N_DBPS = 192;
1802 break;
1804 case 540:
1805 N_DBPS = 216;
1806 break;
1808 default:
1809 break;
1812 return N_DBPS;
1815 void rtl819xU_cmd_isr(struct urb *tx_cmd_urb, struct pt_regs *regs)
1817 usb_free_urb(tx_cmd_urb);
1820 unsigned int txqueue2outpipe(struct r8192_priv* priv,unsigned int tx_queue) {
1822 if(tx_queue >= 9)
1824 RT_TRACE(COMP_ERR,"%s():Unknown queue ID!!!\n",__FUNCTION__);
1825 return 0x04;
1827 return priv->txqueue_to_outpipemap[tx_queue];
1830 short rtl819xU_tx_cmd(struct net_device *dev, struct sk_buff *skb)
1832 struct r8192_priv *priv = ieee80211_priv(dev);
1833 //u8 *tx;
1834 int status;
1835 struct urb *tx_urb;
1836 //int urb_buf_len;
1837 unsigned int idx_pipe;
1838 tx_desc_cmd_819x_usb *pdesc = (tx_desc_cmd_819x_usb *)skb->data;
1839 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1840 u8 queue_index = tcb_desc->queue_index;
1842 //printk("\n %s::queue_index = %d\n",__FUNCTION__, queue_index);
1843 atomic_inc(&priv->tx_pending[queue_index]);
1844 tx_urb = usb_alloc_urb(0,GFP_ATOMIC);
1845 if(!tx_urb){
1846 dev_kfree_skb(skb);
1847 return -ENOMEM;
1850 memset(pdesc, 0, USB_HWDESC_HEADER_LEN);
1851 /* Tx descriptor ought to be set according to the skb->cb */
1852 pdesc->FirstSeg = 1;//bFirstSeg;
1853 pdesc->LastSeg = 1;//bLastSeg;
1854 pdesc->CmdInit = tcb_desc->bCmdOrInit;
1855 pdesc->TxBufferSize = tcb_desc->txbuf_size;
1856 pdesc->OWN = 1;
1857 pdesc->LINIP = tcb_desc->bLastIniPkt;
1859 //----------------------------------------------------------------------------
1860 // Fill up USB_OUT_CONTEXT.
1861 //----------------------------------------------------------------------------
1862 // Get index to out pipe from specified QueueID.
1863 #ifndef USE_ONE_PIPE
1864 idx_pipe = txqueue2outpipe(priv,queue_index);
1865 #else
1866 idx_pipe = 0x04;
1867 #endif
1868 #ifdef JOHN_DUMP_TXDESC
1869 int i;
1870 printk("<Tx descriptor>--rate %x---",rate);
1871 for (i = 0; i < 8; i++)
1872 printk("%8x ", tx[i]);
1873 printk("\n");
1874 #endif
1875 usb_fill_bulk_urb(tx_urb,priv->udev, usb_sndbulkpipe(priv->udev,idx_pipe), \
1876 skb->data, skb->len, rtl8192_tx_isr, skb);
1878 status = usb_submit_urb(tx_urb, GFP_ATOMIC);
1880 if (!status){
1881 return 0;
1882 }else{
1883 DMESGE("Error TX CMD URB, error %d",
1884 status);
1885 return -1;
1890 * Mapping Software/Hardware descriptor queue id to "Queue Select Field"
1891 * in TxFwInfo data structure
1892 * 2006.10.30 by Emily
1894 * \param QUEUEID Software Queue
1896 u8 MapHwQueueToFirmwareQueue(u8 QueueID)
1898 u8 QueueSelect = 0x0; //defualt set to
1900 switch(QueueID) {
1901 case BE_QUEUE:
1902 QueueSelect = QSLT_BE; //or QSelect = pTcb->priority;
1903 break;
1905 case BK_QUEUE:
1906 QueueSelect = QSLT_BK; //or QSelect = pTcb->priority;
1907 break;
1909 case VO_QUEUE:
1910 QueueSelect = QSLT_VO; //or QSelect = pTcb->priority;
1911 break;
1913 case VI_QUEUE:
1914 QueueSelect = QSLT_VI; //or QSelect = pTcb->priority;
1915 break;
1916 case MGNT_QUEUE:
1917 QueueSelect = QSLT_MGNT;
1918 break;
1920 case BEACON_QUEUE:
1921 QueueSelect = QSLT_BEACON;
1922 break;
1924 // TODO: 2006.10.30 mark other queue selection until we verify it is OK
1925 // TODO: Remove Assertions
1926 //#if (RTL819X_FPGA_VER & RTL819X_FPGA_GUANGAN_070502)
1927 case TXCMD_QUEUE:
1928 QueueSelect = QSLT_CMD;
1929 break;
1930 //#endif
1931 case HIGH_QUEUE:
1932 QueueSelect = QSLT_HIGH;
1933 break;
1935 default:
1936 RT_TRACE(COMP_ERR, "TransmitTCB(): Impossible Queue Selection: %d \n", QueueID);
1937 break;
1939 return QueueSelect;
1942 u8 MRateToHwRate8190Pci(u8 rate)
1944 u8 ret = DESC90_RATE1M;
1946 switch(rate) {
1947 case MGN_1M: ret = DESC90_RATE1M; break;
1948 case MGN_2M: ret = DESC90_RATE2M; break;
1949 case MGN_5_5M: ret = DESC90_RATE5_5M; break;
1950 case MGN_11M: ret = DESC90_RATE11M; break;
1951 case MGN_6M: ret = DESC90_RATE6M; break;
1952 case MGN_9M: ret = DESC90_RATE9M; break;
1953 case MGN_12M: ret = DESC90_RATE12M; break;
1954 case MGN_18M: ret = DESC90_RATE18M; break;
1955 case MGN_24M: ret = DESC90_RATE24M; break;
1956 case MGN_36M: ret = DESC90_RATE36M; break;
1957 case MGN_48M: ret = DESC90_RATE48M; break;
1958 case MGN_54M: ret = DESC90_RATE54M; break;
1960 // HT rate since here
1961 case MGN_MCS0: ret = DESC90_RATEMCS0; break;
1962 case MGN_MCS1: ret = DESC90_RATEMCS1; break;
1963 case MGN_MCS2: ret = DESC90_RATEMCS2; break;
1964 case MGN_MCS3: ret = DESC90_RATEMCS3; break;
1965 case MGN_MCS4: ret = DESC90_RATEMCS4; break;
1966 case MGN_MCS5: ret = DESC90_RATEMCS5; break;
1967 case MGN_MCS6: ret = DESC90_RATEMCS6; break;
1968 case MGN_MCS7: ret = DESC90_RATEMCS7; break;
1969 case MGN_MCS8: ret = DESC90_RATEMCS8; break;
1970 case MGN_MCS9: ret = DESC90_RATEMCS9; break;
1971 case MGN_MCS10: ret = DESC90_RATEMCS10; break;
1972 case MGN_MCS11: ret = DESC90_RATEMCS11; break;
1973 case MGN_MCS12: ret = DESC90_RATEMCS12; break;
1974 case MGN_MCS13: ret = DESC90_RATEMCS13; break;
1975 case MGN_MCS14: ret = DESC90_RATEMCS14; break;
1976 case MGN_MCS15: ret = DESC90_RATEMCS15; break;
1977 case (0x80|0x20): ret = DESC90_RATEMCS32; break;
1979 default: break;
1981 return ret;
1985 u8 QueryIsShort(u8 TxHT, u8 TxRate, cb_desc *tcb_desc)
1987 u8 tmp_Short;
1989 tmp_Short = (TxHT==1)?((tcb_desc->bUseShortGI)?1:0):((tcb_desc->bUseShortPreamble)?1:0);
1991 if(TxHT==1 && TxRate != DESC90_RATEMCS15)
1992 tmp_Short = 0;
1994 return tmp_Short;
1997 static void tx_zero_isr(struct urb *tx_urb)
1999 return;
2003 * The tx procedure is just as following,
2004 * skb->cb will contain all the following information,
2005 * priority, morefrag, rate, &dev.
2006 * */
2007 short rtl8192_tx(struct net_device *dev, struct sk_buff* skb)
2009 struct r8192_priv *priv = ieee80211_priv(dev);
2010 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
2011 tx_desc_819x_usb *tx_desc = (tx_desc_819x_usb *)skb->data;
2012 tx_fwinfo_819x_usb *tx_fwinfo = (tx_fwinfo_819x_usb *)(skb->data + USB_HWDESC_HEADER_LEN);
2013 struct usb_device *udev = priv->udev;
2014 int pend;
2015 int status;
2016 struct urb *tx_urb = NULL, *tx_urb_zero = NULL;
2017 //int urb_len;
2018 unsigned int idx_pipe;
2019 // RT_DEBUG_DATA(COMP_SEND, tcb_desc, sizeof(cb_desc));
2020 // printk("=============> %s\n", __FUNCTION__);
2021 pend = atomic_read(&priv->tx_pending[tcb_desc->queue_index]);
2022 /* we are locked here so the two atomic_read and inc are executed
2023 * without interleaves
2024 * !!! For debug purpose
2026 if( pend > MAX_TX_URB){
2027 printk("To discard skb packet!\n");
2028 dev_kfree_skb_any(skb);
2029 return -1;
2032 tx_urb = usb_alloc_urb(0,GFP_ATOMIC);
2033 if(!tx_urb){
2034 dev_kfree_skb_any(skb);
2035 return -ENOMEM;
2038 /* Fill Tx firmware info */
2039 memset(tx_fwinfo,0,sizeof(tx_fwinfo_819x_usb));
2040 /* DWORD 0 */
2041 tx_fwinfo->TxHT = (tcb_desc->data_rate&0x80)?1:0;
2042 tx_fwinfo->TxRate = MRateToHwRate8190Pci(tcb_desc->data_rate);
2043 tx_fwinfo->EnableCPUDur = tcb_desc->bTxEnableFwCalcDur;
2044 tx_fwinfo->Short = QueryIsShort(tx_fwinfo->TxHT, tx_fwinfo->TxRate, tcb_desc);
2045 if(tcb_desc->bAMPDUEnable) {//AMPDU enabled
2046 tx_fwinfo->AllowAggregation = 1;
2047 /* DWORD 1 */
2048 tx_fwinfo->RxMF = tcb_desc->ampdu_factor;
2049 tx_fwinfo->RxAMD = tcb_desc->ampdu_density&0x07;//ampdudensity
2050 } else {
2051 tx_fwinfo->AllowAggregation = 0;
2052 /* DWORD 1 */
2053 tx_fwinfo->RxMF = 0;
2054 tx_fwinfo->RxAMD = 0;
2057 /* Protection mode related */
2058 tx_fwinfo->RtsEnable = (tcb_desc->bRTSEnable)?1:0;
2059 tx_fwinfo->CtsEnable = (tcb_desc->bCTSEnable)?1:0;
2060 tx_fwinfo->RtsSTBC = (tcb_desc->bRTSSTBC)?1:0;
2061 tx_fwinfo->RtsHT = (tcb_desc->rts_rate&0x80)?1:0;
2062 tx_fwinfo->RtsRate = MRateToHwRate8190Pci((u8)tcb_desc->rts_rate);
2063 tx_fwinfo->RtsSubcarrier = (tx_fwinfo->RtsHT==0)?(tcb_desc->RTSSC):0;
2064 tx_fwinfo->RtsBandwidth = (tx_fwinfo->RtsHT==1)?((tcb_desc->bRTSBW)?1:0):0;
2065 tx_fwinfo->RtsShort = (tx_fwinfo->RtsHT==0)?(tcb_desc->bRTSUseShortPreamble?1:0):\
2066 (tcb_desc->bRTSUseShortGI?1:0);
2068 /* Set Bandwidth and sub-channel settings. */
2069 if(priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20_40)
2071 if(tcb_desc->bPacketBW) {
2072 tx_fwinfo->TxBandwidth = 1;
2073 tx_fwinfo->TxSubCarrier = 0; //By SD3's Jerry suggestion, use duplicated mode
2074 } else {
2075 tx_fwinfo->TxBandwidth = 0;
2076 tx_fwinfo->TxSubCarrier = priv->nCur40MhzPrimeSC;
2078 } else {
2079 tx_fwinfo->TxBandwidth = 0;
2080 tx_fwinfo->TxSubCarrier = 0;
2083 #ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
2084 if (tcb_desc->drv_agg_enable)
2086 tx_fwinfo->Tx_INFO_RSVD = (tcb_desc->DrvAggrNum & 0x1f) << 1;
2088 #endif
2089 /* Fill Tx descriptor */
2090 memset(tx_desc, 0, sizeof(tx_desc_819x_usb));
2091 /* DWORD 0 */
2092 tx_desc->LINIP = 0;
2093 tx_desc->CmdInit = 1;
2094 tx_desc->Offset = sizeof(tx_fwinfo_819x_usb) + 8;
2096 #ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
2097 if (tcb_desc->drv_agg_enable) {
2098 tx_desc->PktSize = tcb_desc->pkt_size;
2099 } else
2100 #endif
2102 tx_desc->PktSize = (skb->len - TX_PACKET_SHIFT_BYTES) & 0xffff;
2105 /*DWORD 1*/
2106 tx_desc->SecCAMID= 0;
2107 tx_desc->RATid = tcb_desc->RATRIndex;
2109 //MPDUOverhead = 0;
2110 tx_desc->NoEnc = 1;
2112 tx_desc->SecType = 0x0;
2113 if (tcb_desc->bHwSec)
2115 switch (priv->ieee80211->pairwise_key_type)
2117 case KEY_TYPE_WEP40:
2118 case KEY_TYPE_WEP104:
2119 tx_desc->SecType = 0x1;
2120 tx_desc->NoEnc = 0;
2121 break;
2122 case KEY_TYPE_TKIP:
2123 tx_desc->SecType = 0x2;
2124 tx_desc->NoEnc = 0;
2125 break;
2126 case KEY_TYPE_CCMP:
2127 tx_desc->SecType = 0x3;
2128 tx_desc->NoEnc = 0;
2129 break;
2130 case KEY_TYPE_NA:
2131 tx_desc->SecType = 0x0;
2132 tx_desc->NoEnc = 1;
2133 break;
2137 tx_desc->QueueSelect = MapHwQueueToFirmwareQueue(tcb_desc->queue_index);
2138 tx_desc->TxFWInfoSize = sizeof(tx_fwinfo_819x_usb);
2140 tx_desc->DISFB = tcb_desc->bTxDisableRateFallBack;
2141 tx_desc->USERATE = tcb_desc->bTxUseDriverAssingedRate;
2143 /* Fill fields that are required to be initialized in all of the descriptors */
2144 //DWORD 0
2145 tx_desc->FirstSeg = 1;
2146 tx_desc->LastSeg = 1;
2147 tx_desc->OWN = 1;
2149 #ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
2150 if (tcb_desc->drv_agg_enable) {
2151 tx_desc->TxBufferSize = tcb_desc->pkt_size + sizeof(tx_fwinfo_819x_usb);
2152 } else
2153 #endif
2155 //DWORD 2
2156 tx_desc->TxBufferSize = (u32)(skb->len - USB_HWDESC_HEADER_LEN);
2158 /* Get index to out pipe from specified QueueID */
2159 #ifndef USE_ONE_PIPE
2160 idx_pipe = txqueue2outpipe(priv,tcb_desc->queue_index);
2161 #else
2162 idx_pipe = 0x5;
2163 #endif
2165 //RT_DEBUG_DATA(COMP_SEND,tx_fwinfo,sizeof(tx_fwinfo_819x_usb));
2166 //RT_DEBUG_DATA(COMP_SEND,tx_desc,sizeof(tx_desc_819x_usb));
2168 /* To submit bulk urb */
2169 usb_fill_bulk_urb(tx_urb,udev,
2170 usb_sndbulkpipe(udev,idx_pipe), skb->data,
2171 skb->len, rtl8192_tx_isr, skb);
2173 status = usb_submit_urb(tx_urb, GFP_ATOMIC);
2174 if (!status){
2175 //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
2176 bool bSend0Byte = false;
2177 u8 zero = 0;
2178 if(udev->speed == USB_SPEED_HIGH)
2180 if (skb->len > 0 && skb->len % 512 == 0)
2181 bSend0Byte = true;
2183 else
2185 if (skb->len > 0 && skb->len % 64 == 0)
2186 bSend0Byte = true;
2188 if (bSend0Byte)
2190 tx_urb_zero = usb_alloc_urb(0,GFP_ATOMIC);
2191 if(!tx_urb_zero){
2192 RT_TRACE(COMP_ERR, "can't alloc urb for zero byte\n");
2193 return -ENOMEM;
2195 usb_fill_bulk_urb(tx_urb_zero,udev,
2196 usb_sndbulkpipe(udev,idx_pipe), &zero,
2197 0, tx_zero_isr, dev);
2198 status = usb_submit_urb(tx_urb_zero, GFP_ATOMIC);
2199 if (status){
2200 RT_TRACE(COMP_ERR, "Error TX URB for zero byte %d, error %d", atomic_read(&priv->tx_pending[tcb_desc->queue_index]), status);
2201 return -1;
2204 dev->trans_start = jiffies;
2205 atomic_inc(&priv->tx_pending[tcb_desc->queue_index]);
2206 return 0;
2207 }else{
2208 RT_TRACE(COMP_ERR, "Error TX URB %d, error %d", atomic_read(&priv->tx_pending[tcb_desc->queue_index]),
2209 status);
2210 return -1;
2214 short rtl8192_usb_initendpoints(struct net_device *dev)
2216 struct r8192_priv *priv = ieee80211_priv(dev);
2218 priv->rx_urb = (struct urb**) kmalloc (sizeof(struct urb*) * (MAX_RX_URB+1), GFP_KERNEL);
2220 #ifndef JACKSON_NEW_RX
2221 for(i=0;i<(MAX_RX_URB+1);i++){
2223 priv->rx_urb[i] = usb_alloc_urb(0,GFP_KERNEL);
2225 priv->rx_urb[i]->transfer_buffer = kmalloc(RX_URB_SIZE, GFP_KERNEL);
2227 priv->rx_urb[i]->transfer_buffer_length = RX_URB_SIZE;
2229 #endif
2231 #ifdef THOMAS_BEACON
2233 long align = 0;
2234 void *oldaddr, *newaddr;
2236 priv->rx_urb[16] = usb_alloc_urb(0, GFP_KERNEL);
2237 priv->oldaddr = kmalloc(16, GFP_KERNEL);
2238 oldaddr = priv->oldaddr;
2239 align = ((long)oldaddr) & 3;
2240 if (align) {
2241 newaddr = oldaddr + 4 - align;
2242 priv->rx_urb[16]->transfer_buffer_length = 16 - 4 + align;
2243 } else {
2244 newaddr = oldaddr;
2245 priv->rx_urb[16]->transfer_buffer_length = 16;
2247 priv->rx_urb[16]->transfer_buffer = newaddr;
2249 #endif
2251 memset(priv->rx_urb, 0, sizeof(struct urb*) * MAX_RX_URB);
2252 priv->pp_rxskb = (struct sk_buff **)kmalloc(sizeof(struct sk_buff *) * MAX_RX_URB, GFP_KERNEL);
2253 if (priv->pp_rxskb == NULL)
2254 goto destroy;
2256 memset(priv->pp_rxskb, 0, sizeof(struct sk_buff*) * MAX_RX_URB);
2258 goto _middle;
2261 destroy:
2262 if (priv->pp_rxskb) {
2263 kfree(priv->pp_rxskb);
2265 if (priv->rx_urb) {
2266 kfree(priv->rx_urb);
2269 priv->pp_rxskb = NULL;
2270 priv->rx_urb = NULL;
2272 DMESGE("Endpoint Alloc Failure");
2273 return -ENOMEM;
2276 _middle:
2278 printk("End of initendpoints\n");
2279 return 0;
2282 #ifdef THOMAS_BEACON
2283 void rtl8192_usb_deleteendpoints(struct net_device *dev)
2285 int i;
2286 struct r8192_priv *priv = ieee80211_priv(dev);
2288 if(priv->rx_urb){
2289 for(i=0;i<(MAX_RX_URB+1);i++){
2290 usb_kill_urb(priv->rx_urb[i]);
2291 usb_free_urb(priv->rx_urb[i]);
2293 kfree(priv->rx_urb);
2294 priv->rx_urb = NULL;
2296 if(priv->oldaddr){
2297 kfree(priv->oldaddr);
2298 priv->oldaddr = NULL;
2300 if (priv->pp_rxskb) {
2301 kfree(priv->pp_rxskb);
2302 priv->pp_rxskb = 0;
2305 #else
2306 void rtl8192_usb_deleteendpoints(struct net_device *dev)
2308 int i;
2309 struct r8192_priv *priv = ieee80211_priv(dev);
2311 #ifndef JACKSON_NEW_RX
2313 if(priv->rx_urb){
2314 for(i=0;i<(MAX_RX_URB+1);i++){
2315 usb_kill_urb(priv->rx_urb[i]);
2316 kfree(priv->rx_urb[i]->transfer_buffer);
2317 usb_free_urb(priv->rx_urb[i]);
2319 kfree(priv->rx_urb);
2320 priv->rx_urb = NULL;
2323 #else
2324 if(priv->rx_urb){
2325 kfree(priv->rx_urb);
2326 priv->rx_urb = NULL;
2328 if(priv->oldaddr){
2329 kfree(priv->oldaddr);
2330 priv->oldaddr = NULL;
2332 if (priv->pp_rxskb) {
2333 kfree(priv->pp_rxskb);
2334 priv->pp_rxskb = 0;
2338 #endif
2340 #endif
2342 extern void rtl8192_update_ratr_table(struct net_device* dev);
2343 void rtl8192_link_change(struct net_device *dev)
2345 // int i;
2347 struct r8192_priv *priv = ieee80211_priv(dev);
2348 struct ieee80211_device* ieee = priv->ieee80211;
2349 //write_nic_word(dev, BCN_INTR_ITV, net->beacon_interval);
2350 if (ieee->state == IEEE80211_LINKED)
2352 rtl8192_net_update(dev);
2353 rtl8192_update_ratr_table(dev);
2354 //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
2355 if ((KEY_TYPE_WEP40 == ieee->pairwise_key_type) || (KEY_TYPE_WEP104 == ieee->pairwise_key_type))
2356 EnableHWSecurityConfig8192(dev);
2358 /*update timing params*/
2359 // RT_TRACE(COMP_CH, "========>%s(), chan:%d\n", __FUNCTION__, priv->chan);
2360 // rtl8192_set_chan(dev, priv->chan);
2361 if (ieee->iw_mode == IW_MODE_INFRA || ieee->iw_mode == IW_MODE_ADHOC)
2363 u32 reg = 0;
2364 reg = read_nic_dword(dev, RCR);
2365 if (priv->ieee80211->state == IEEE80211_LINKED)
2366 priv->ReceiveConfig = reg |= RCR_CBSSID;
2367 else
2368 priv->ReceiveConfig = reg &= ~RCR_CBSSID;
2369 write_nic_dword(dev, RCR, reg);
2372 // rtl8192_set_rxconf(dev);
2375 static struct ieee80211_qos_parameters def_qos_parameters = {
2376 {3,3,3,3},/* cw_min */
2377 {7,7,7,7},/* cw_max */
2378 {2,2,2,2},/* aifs */
2379 {0,0,0,0},/* flags */
2380 {0,0,0,0} /* tx_op_limit */
2384 void rtl8192_update_beacon(struct work_struct * work)
2386 struct r8192_priv *priv = container_of(work, struct r8192_priv, update_beacon_wq.work);
2387 struct net_device *dev = priv->ieee80211->dev;
2388 struct ieee80211_device* ieee = priv->ieee80211;
2389 struct ieee80211_network* net = &ieee->current_network;
2391 if (ieee->pHTInfo->bCurrentHTSupport)
2392 HTUpdateSelfAndPeerSetting(ieee, net);
2393 ieee->pHTInfo->bCurrentRT2RTLongSlotTime = net->bssht.bdRT2RTLongSlotTime;
2394 rtl8192_update_cap(dev, net->capability);
2397 * background support to run QoS activate functionality
2399 int WDCAPARA_ADD[] = {EDCAPARA_BE,EDCAPARA_BK,EDCAPARA_VI,EDCAPARA_VO};
2400 void rtl8192_qos_activate(struct work_struct * work)
2402 struct r8192_priv *priv = container_of(work, struct r8192_priv, qos_activate);
2403 struct net_device *dev = priv->ieee80211->dev;
2404 struct ieee80211_qos_parameters *qos_parameters = &priv->ieee80211->current_network.qos_data.parameters;
2405 u8 mode = priv->ieee80211->current_network.mode;
2406 //u32 size = sizeof(struct ieee80211_qos_parameters);
2407 u8 u1bAIFS;
2408 u32 u4bAcParam;
2409 int i;
2411 if (priv == NULL)
2412 return;
2414 mutex_lock(&priv->mutex);
2415 if(priv->ieee80211->state != IEEE80211_LINKED)
2416 goto success;
2417 RT_TRACE(COMP_QOS,"qos active process with associate response received\n");
2418 /* It better set slot time at first */
2419 /* For we just support b/g mode at present, let the slot time at 9/20 selection */
2420 /* update the ac parameter to related registers */
2421 for(i = 0; i < QOS_QUEUE_NUM; i++) {
2422 //Mode G/A: slotTimeTimer = 9; Mode B: 20
2423 u1bAIFS = qos_parameters->aifs[i] * ((mode&(IEEE_G|IEEE_N_24G)) ?9:20) + aSifsTime;
2424 u4bAcParam = ((((u32)(qos_parameters->tx_op_limit[i]))<< AC_PARAM_TXOP_LIMIT_OFFSET)|
2425 (((u32)(qos_parameters->cw_max[i]))<< AC_PARAM_ECW_MAX_OFFSET)|
2426 (((u32)(qos_parameters->cw_min[i]))<< AC_PARAM_ECW_MIN_OFFSET)|
2427 ((u32)u1bAIFS << AC_PARAM_AIFS_OFFSET));
2429 write_nic_dword(dev, WDCAPARA_ADD[i], u4bAcParam);
2430 //write_nic_dword(dev, WDCAPARA_ADD[i], 0x005e4332);
2433 success:
2434 mutex_unlock(&priv->mutex);
2437 static int rtl8192_qos_handle_probe_response(struct r8192_priv *priv,
2438 int active_network,
2439 struct ieee80211_network *network)
2441 int ret = 0;
2442 u32 size = sizeof(struct ieee80211_qos_parameters);
2444 if(priv->ieee80211->state !=IEEE80211_LINKED)
2445 return ret;
2447 if ((priv->ieee80211->iw_mode != IW_MODE_INFRA))
2448 return ret;
2450 if (network->flags & NETWORK_HAS_QOS_MASK) {
2451 if (active_network &&
2452 (network->flags & NETWORK_HAS_QOS_PARAMETERS))
2453 network->qos_data.active = network->qos_data.supported;
2455 if ((network->qos_data.active == 1) && (active_network == 1) &&
2456 (network->flags & NETWORK_HAS_QOS_PARAMETERS) &&
2457 (network->qos_data.old_param_count !=
2458 network->qos_data.param_count)) {
2459 network->qos_data.old_param_count =
2460 network->qos_data.param_count;
2461 queue_work(priv->priv_wq, &priv->qos_activate);
2462 RT_TRACE (COMP_QOS, "QoS parameters change call "
2463 "qos_activate\n");
2465 } else {
2466 memcpy(&priv->ieee80211->current_network.qos_data.parameters,\
2467 &def_qos_parameters, size);
2469 if ((network->qos_data.active == 1) && (active_network == 1)) {
2470 queue_work(priv->priv_wq, &priv->qos_activate);
2471 RT_TRACE(COMP_QOS, "QoS was disabled call qos_activate \n");
2473 network->qos_data.active = 0;
2474 network->qos_data.supported = 0;
2477 return 0;
2480 /* handle manage frame frame beacon and probe response */
2481 static int rtl8192_handle_beacon(struct net_device * dev,
2482 struct ieee80211_beacon * beacon,
2483 struct ieee80211_network * network)
2485 struct r8192_priv *priv = ieee80211_priv(dev);
2487 rtl8192_qos_handle_probe_response(priv,1,network);
2488 queue_delayed_work(priv->priv_wq, &priv->update_beacon_wq, 0);
2489 return 0;
2494 * handling the beaconing responses. if we get different QoS setting
2495 * off the network from the associated setting, adjust the QoS
2496 * setting
2498 static int rtl8192_qos_association_resp(struct r8192_priv *priv,
2499 struct ieee80211_network *network)
2501 int ret = 0;
2502 unsigned long flags;
2503 u32 size = sizeof(struct ieee80211_qos_parameters);
2504 int set_qos_param = 0;
2506 if ((priv == NULL) || (network == NULL))
2507 return ret;
2509 if(priv->ieee80211->state !=IEEE80211_LINKED)
2510 return ret;
2512 if ((priv->ieee80211->iw_mode != IW_MODE_INFRA))
2513 return ret;
2515 spin_lock_irqsave(&priv->ieee80211->lock, flags);
2516 if(network->flags & NETWORK_HAS_QOS_PARAMETERS) {
2517 memcpy(&priv->ieee80211->current_network.qos_data.parameters,\
2518 &network->qos_data.parameters,\
2519 sizeof(struct ieee80211_qos_parameters));
2520 priv->ieee80211->current_network.qos_data.active = 1;
2522 set_qos_param = 1;
2523 /* update qos parameter for current network */
2524 priv->ieee80211->current_network.qos_data.old_param_count = \
2525 priv->ieee80211->current_network.qos_data.param_count;
2526 priv->ieee80211->current_network.qos_data.param_count = \
2527 network->qos_data.param_count;
2529 } else {
2530 memcpy(&priv->ieee80211->current_network.qos_data.parameters,\
2531 &def_qos_parameters, size);
2532 priv->ieee80211->current_network.qos_data.active = 0;
2533 priv->ieee80211->current_network.qos_data.supported = 0;
2534 set_qos_param = 1;
2537 spin_unlock_irqrestore(&priv->ieee80211->lock, flags);
2539 RT_TRACE(COMP_QOS, "%s: network->flags = %d,%d\n",__FUNCTION__,network->flags ,priv->ieee80211->current_network.qos_data.active);
2540 if (set_qos_param == 1)
2541 queue_work(priv->priv_wq, &priv->qos_activate);
2544 return ret;
2548 static int rtl8192_handle_assoc_response(struct net_device *dev,
2549 struct ieee80211_assoc_response_frame *resp,
2550 struct ieee80211_network *network)
2552 struct r8192_priv *priv = ieee80211_priv(dev);
2553 rtl8192_qos_association_resp(priv, network);
2554 return 0;
2558 void rtl8192_update_ratr_table(struct net_device* dev)
2559 // POCTET_STRING posLegacyRate,
2560 // u8* pMcsRate)
2561 // PRT_WLAN_STA pEntry)
2563 struct r8192_priv* priv = ieee80211_priv(dev);
2564 struct ieee80211_device* ieee = priv->ieee80211;
2565 u8* pMcsRate = ieee->dot11HTOperationalRateSet;
2566 //struct ieee80211_network *net = &ieee->current_network;
2567 u32 ratr_value = 0;
2568 u8 rate_index = 0;
2569 rtl8192_config_rate(dev, (u16*)(&ratr_value));
2570 ratr_value |= (*(u16*)(pMcsRate)) << 12;
2571 // switch (net->mode)
2572 switch (ieee->mode)
2574 case IEEE_A:
2575 ratr_value &= 0x00000FF0;
2576 break;
2577 case IEEE_B:
2578 ratr_value &= 0x0000000F;
2579 break;
2580 case IEEE_G:
2581 ratr_value &= 0x00000FF7;
2582 break;
2583 case IEEE_N_24G:
2584 case IEEE_N_5G:
2585 if (ieee->pHTInfo->PeerMimoPs == 0) //MIMO_PS_STATIC
2586 ratr_value &= 0x0007F007;
2587 else{
2588 if (priv->rf_type == RF_1T2R)
2589 ratr_value &= 0x000FF007;
2590 else
2591 ratr_value &= 0x0F81F007;
2593 break;
2594 default:
2595 break;
2597 ratr_value &= 0x0FFFFFFF;
2598 if(ieee->pHTInfo->bCurTxBW40MHz && ieee->pHTInfo->bCurShortGI40MHz){
2599 ratr_value |= 0x80000000;
2600 }else if(!ieee->pHTInfo->bCurTxBW40MHz && ieee->pHTInfo->bCurShortGI20MHz){
2601 ratr_value |= 0x80000000;
2603 write_nic_dword(dev, RATR0+rate_index*4, ratr_value);
2604 write_nic_byte(dev, UFWP, 1);
2607 static u8 ccmp_ie[4] = {0x00,0x50,0xf2,0x04};
2608 static u8 ccmp_rsn_ie[4] = {0x00, 0x0f, 0xac, 0x04};
2609 bool GetNmodeSupportBySecCfg8192(struct net_device*dev)
2611 struct r8192_priv* priv = ieee80211_priv(dev);
2612 struct ieee80211_device* ieee = priv->ieee80211;
2613 struct ieee80211_network * network = &ieee->current_network;
2614 int wpa_ie_len= ieee->wpa_ie_len;
2615 struct ieee80211_crypt_data* crypt;
2616 int encrypt;
2618 crypt = ieee->crypt[ieee->tx_keyidx];
2619 //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
2620 encrypt = (network->capability & WLAN_CAPABILITY_PRIVACY) || (ieee->host_encrypt && crypt && crypt->ops && (0 == strcmp(crypt->ops->name,"WEP")));
2622 /* simply judge */
2623 if(encrypt && (wpa_ie_len == 0)) {
2624 /* wep encryption, no N mode setting */
2625 return false;
2626 // } else if((wpa_ie_len != 0)&&(memcmp(&(ieee->wpa_ie[14]),ccmp_ie,4))) {
2627 } else if((wpa_ie_len != 0)) {
2628 /* parse pairwise key type */
2629 //if((pairwisekey = WEP40)||(pairwisekey = WEP104)||(pairwisekey = TKIP))
2630 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))))
2631 return true;
2632 else
2633 return false;
2634 } else {
2635 return true;
2638 return true;
2641 bool GetHalfNmodeSupportByAPs819xUsb(struct net_device* dev)
2643 bool Reval;
2644 struct r8192_priv* priv = ieee80211_priv(dev);
2645 struct ieee80211_device* ieee = priv->ieee80211;
2647 if(ieee->bHalfWirelessN24GMode == true)
2648 Reval = true;
2649 else
2650 Reval = false;
2652 return Reval;
2655 void rtl8192_refresh_supportrate(struct r8192_priv* priv)
2657 struct ieee80211_device* ieee = priv->ieee80211;
2658 //we donot consider set support rate for ABG mode, only HT MCS rate is set here.
2659 if (ieee->mode == WIRELESS_MODE_N_24G || ieee->mode == WIRELESS_MODE_N_5G)
2661 memcpy(ieee->Regdot11HTOperationalRateSet, ieee->RegHTSuppRateSet, 16);
2662 //RT_DEBUG_DATA(COMP_INIT, ieee->RegHTSuppRateSet, 16);
2663 //RT_DEBUG_DATA(COMP_INIT, ieee->Regdot11HTOperationalRateSet, 16);
2665 else
2666 memset(ieee->Regdot11HTOperationalRateSet, 0, 16);
2667 return;
2670 u8 rtl8192_getSupportedWireleeMode(struct net_device*dev)
2672 struct r8192_priv *priv = ieee80211_priv(dev);
2673 u8 ret = 0;
2674 switch(priv->rf_chip)
2676 case RF_8225:
2677 case RF_8256:
2678 case RF_PSEUDO_11N:
2679 ret = (WIRELESS_MODE_N_24G|WIRELESS_MODE_G|WIRELESS_MODE_B);
2680 break;
2681 case RF_8258:
2682 ret = (WIRELESS_MODE_A|WIRELESS_MODE_N_5G);
2683 break;
2684 default:
2685 ret = WIRELESS_MODE_B;
2686 break;
2688 return ret;
2690 void rtl8192_SetWirelessMode(struct net_device* dev, u8 wireless_mode)
2692 struct r8192_priv *priv = ieee80211_priv(dev);
2693 u8 bSupportMode = rtl8192_getSupportedWireleeMode(dev);
2695 if ((wireless_mode == WIRELESS_MODE_AUTO) || ((wireless_mode&bSupportMode)==0))
2697 if(bSupportMode & WIRELESS_MODE_N_24G)
2699 wireless_mode = WIRELESS_MODE_N_24G;
2701 else if(bSupportMode & WIRELESS_MODE_N_5G)
2703 wireless_mode = WIRELESS_MODE_N_5G;
2705 else if((bSupportMode & WIRELESS_MODE_A))
2707 wireless_mode = WIRELESS_MODE_A;
2709 else if((bSupportMode & WIRELESS_MODE_G))
2711 wireless_mode = WIRELESS_MODE_G;
2713 else if((bSupportMode & WIRELESS_MODE_B))
2715 wireless_mode = WIRELESS_MODE_B;
2717 else{
2718 RT_TRACE(COMP_ERR, "%s(), No valid wireless mode supported, SupportedWirelessMode(%x)!!!\n", __FUNCTION__,bSupportMode);
2719 wireless_mode = WIRELESS_MODE_B;
2722 #ifdef TO_DO_LIST //// TODO: this function doesn't work well at this time, we shoud wait for FPGA
2723 ActUpdateChannelAccessSetting( pAdapter, pHalData->CurrentWirelessMode, &pAdapter->MgntInfo.Info8185.ChannelAccessSetting );
2724 #endif
2725 priv->ieee80211->mode = wireless_mode;
2727 if ((wireless_mode == WIRELESS_MODE_N_24G) || (wireless_mode == WIRELESS_MODE_N_5G))
2728 priv->ieee80211->pHTInfo->bEnableHT = 1;
2729 else
2730 priv->ieee80211->pHTInfo->bEnableHT = 0;
2731 RT_TRACE(COMP_INIT, "Current Wireless Mode is %x\n", wireless_mode);
2732 rtl8192_refresh_supportrate(priv);
2735 //init priv variables here. only non_zero value should be initialized here.
2736 static void rtl8192_init_priv_variable(struct net_device* dev)
2738 struct r8192_priv *priv = ieee80211_priv(dev);
2739 u8 i;
2740 priv->card_8192 = NIC_8192U;
2741 priv->chan = 1; //set to channel 1
2742 priv->ieee80211->mode = WIRELESS_MODE_AUTO; //SET AUTO
2743 priv->ieee80211->iw_mode = IW_MODE_INFRA;
2744 priv->ieee80211->ieee_up=0;
2745 priv->retry_rts = DEFAULT_RETRY_RTS;
2746 priv->retry_data = DEFAULT_RETRY_DATA;
2747 priv->ieee80211->rts = DEFAULT_RTS_THRESHOLD;
2748 priv->ieee80211->rate = 110; //11 mbps
2749 priv->ieee80211->short_slot = 1;
2750 priv->promisc = (dev->flags & IFF_PROMISC) ? 1:0;
2751 priv->CckPwEnl = 6;
2752 //for silent reset
2753 priv->IrpPendingCount = 1;
2754 priv->ResetProgress = RESET_TYPE_NORESET;
2755 priv->bForcedSilentReset = 0;
2756 priv->bDisableNormalResetCheck = false;
2757 priv->force_reset = false;
2759 priv->ieee80211->FwRWRF = 0; //we don't use FW read/write RF until stable firmware is available.
2760 priv->ieee80211->current_network.beacon_interval = DEFAULT_BEACONINTERVAL;
2761 priv->ieee80211->iw_mode = IW_MODE_INFRA;
2762 priv->ieee80211->softmac_features = IEEE_SOFTMAC_SCAN |
2763 IEEE_SOFTMAC_ASSOCIATE | IEEE_SOFTMAC_PROBERQ |
2764 IEEE_SOFTMAC_PROBERS | IEEE_SOFTMAC_TX_QUEUE |
2765 IEEE_SOFTMAC_BEACONS;//added by amy 080604 //| //IEEE_SOFTMAC_SINGLE_QUEUE;
2767 priv->ieee80211->active_scan = 1;
2768 priv->ieee80211->modulation = IEEE80211_CCK_MODULATION | IEEE80211_OFDM_MODULATION;
2769 priv->ieee80211->host_encrypt = 1;
2770 priv->ieee80211->host_decrypt = 1;
2771 priv->ieee80211->start_send_beacons = NULL;//rtl819xusb_beacon_tx;//-by amy 080604
2772 priv->ieee80211->stop_send_beacons = NULL;//rtl8192_beacon_stop;//-by amy 080604
2773 priv->ieee80211->softmac_hard_start_xmit = rtl8192_hard_start_xmit;
2774 priv->ieee80211->set_chan = rtl8192_set_chan;
2775 priv->ieee80211->link_change = rtl8192_link_change;
2776 priv->ieee80211->softmac_data_hard_start_xmit = rtl8192_hard_data_xmit;
2777 priv->ieee80211->data_hard_stop = rtl8192_data_hard_stop;
2778 priv->ieee80211->data_hard_resume = rtl8192_data_hard_resume;
2779 priv->ieee80211->init_wmmparam_flag = 0;
2780 priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD;
2781 priv->ieee80211->check_nic_enough_desc = check_nic_enough_desc;
2782 priv->ieee80211->tx_headroom = TX_PACKET_SHIFT_BYTES;
2783 priv->ieee80211->qos_support = 1;
2785 //added by WB
2786 // priv->ieee80211->SwChnlByTimerHandler = rtl8192_phy_SwChnl;
2787 priv->ieee80211->SetBWModeHandler = rtl8192_SetBWMode;
2788 priv->ieee80211->handle_assoc_response = rtl8192_handle_assoc_response;
2789 priv->ieee80211->handle_beacon = rtl8192_handle_beacon;
2790 //added by david
2791 priv->ieee80211->GetNmodeSupportBySecCfg = GetNmodeSupportBySecCfg8192;
2792 priv->ieee80211->GetHalfNmodeSupportByAPsHandler = GetHalfNmodeSupportByAPs819xUsb;
2793 priv->ieee80211->SetWirelessMode = rtl8192_SetWirelessMode;
2794 //added by amy
2795 priv->ieee80211->InitialGainHandler = InitialGain819xUsb;
2796 priv->card_type = USB;
2797 #ifdef TO_DO_LIST
2798 if(Adapter->bInHctTest)
2800 pHalData->ShortRetryLimit = 7;
2801 pHalData->LongRetryLimit = 7;
2803 #endif
2805 priv->ShortRetryLimit = 0x30;
2806 priv->LongRetryLimit = 0x30;
2808 priv->EarlyRxThreshold = 7;
2809 priv->enable_gpio0 = 0;
2810 priv->TransmitConfig =
2811 // TCR_DurProcMode | //for RTL8185B, duration setting by HW
2812 //? TCR_DISReqQsize |
2813 (TCR_MXDMA_2048<<TCR_MXDMA_OFFSET)| // Max DMA Burst Size per Tx DMA Burst, 7: reservied.
2814 (priv->ShortRetryLimit<<TCR_SRL_OFFSET)| // Short retry limit
2815 (priv->LongRetryLimit<<TCR_LRL_OFFSET) | // Long retry limit
2816 (false ? TCR_SAT: 0); // FALSE: HW provies PLCP length and LENGEXT, TURE: SW proiveds them
2817 #ifdef TO_DO_LIST
2818 if(Adapter->bInHctTest)
2819 pHalData->ReceiveConfig = pHalData->CSMethod |
2820 RCR_AMF | RCR_ADF | //RCR_AAP | //accept management/data
2821 //guangan200710
2822 RCR_ACF | //accept control frame for SW AP needs PS-poll, 2005.07.07, by rcnjko.
2823 RCR_AB | RCR_AM | RCR_APM | //accept BC/MC/UC
2824 RCR_AICV | RCR_ACRC32 | //accept ICV/CRC error packet
2825 ((u32)7<<RCR_MXDMA_OFFSET) | // Max DMA Burst Size per Rx DMA Burst, 7: unlimited.
2826 (pHalData->EarlyRxThreshold<<RCR_FIFO_OFFSET) | // Rx FIFO Threshold, 7: No Rx threshold.
2827 (pHalData->EarlyRxThreshold == 7 ? RCR_OnlyErlPkt:0);
2828 else
2830 #endif
2831 priv->ReceiveConfig =
2832 RCR_AMF | RCR_ADF | //accept management/data
2833 RCR_ACF | //accept control frame for SW AP needs PS-poll, 2005.07.07, by rcnjko.
2834 RCR_AB | RCR_AM | RCR_APM | //accept BC/MC/UC
2835 //RCR_AICV | RCR_ACRC32 | //accept ICV/CRC error packet
2836 ((u32)7<<RCR_MXDMA_OFFSET)| // Max DMA Burst Size per Rx DMA Burst, 7: unlimited.
2837 (priv->EarlyRxThreshold<<RX_FIFO_THRESHOLD_SHIFT) | // Rx FIFO Threshold, 7: No Rx threshold.
2838 (priv->EarlyRxThreshold == 7 ? RCR_ONLYERLPKT:0);
2840 priv->AcmControl = 0;
2841 priv->pFirmware = (rt_firmware*)kmalloc(sizeof(rt_firmware), GFP_KERNEL);
2842 if (priv->pFirmware)
2843 memset(priv->pFirmware, 0, sizeof(rt_firmware));
2845 /* rx related queue */
2846 skb_queue_head_init(&priv->rx_queue);
2847 skb_queue_head_init(&priv->skb_queue);
2849 /* Tx related queue */
2850 for(i = 0; i < MAX_QUEUE_SIZE; i++) {
2851 skb_queue_head_init(&priv->ieee80211->skb_waitQ [i]);
2853 for(i = 0; i < MAX_QUEUE_SIZE; i++) {
2854 skb_queue_head_init(&priv->ieee80211->skb_aggQ [i]);
2856 for(i = 0; i < MAX_QUEUE_SIZE; i++) {
2857 skb_queue_head_init(&priv->ieee80211->skb_drv_aggQ [i]);
2859 priv->rf_set_chan = rtl8192_phy_SwChnl;
2862 //init lock here
2863 static void rtl8192_init_priv_lock(struct r8192_priv* priv)
2865 spin_lock_init(&priv->tx_lock);
2866 spin_lock_init(&priv->irq_lock);//added by thomas
2867 //spin_lock_init(&priv->rf_lock);
2868 sema_init(&priv->wx_sem,1);
2869 sema_init(&priv->rf_sem,1);
2870 mutex_init(&priv->mutex);
2873 extern void rtl819x_watchdog_wqcallback(struct work_struct *work);
2875 void rtl8192_irq_rx_tasklet(struct r8192_priv *priv);
2876 //init tasklet and wait_queue here. only 2.6 above kernel is considered
2877 #define DRV_NAME "wlan0"
2878 static void rtl8192_init_priv_task(struct net_device* dev)
2880 struct r8192_priv *priv = ieee80211_priv(dev);
2882 #ifdef PF_SYNCTHREAD
2883 priv->priv_wq = create_workqueue(DRV_NAME,0);
2884 #else
2885 priv->priv_wq = create_workqueue(DRV_NAME);
2886 #endif
2888 INIT_WORK(&priv->reset_wq, rtl8192_restart);
2890 //INIT_DELAYED_WORK(&priv->watch_dog_wq, hal_dm_watchdog);
2891 INIT_DELAYED_WORK(&priv->watch_dog_wq, rtl819x_watchdog_wqcallback);
2892 INIT_DELAYED_WORK(&priv->txpower_tracking_wq, dm_txpower_trackingcallback);
2893 // INIT_DELAYED_WORK(&priv->gpio_change_rf_wq, dm_gpio_change_rf_callback);
2894 INIT_DELAYED_WORK(&priv->rfpath_check_wq, dm_rf_pathcheck_workitemcallback);
2895 INIT_DELAYED_WORK(&priv->update_beacon_wq, rtl8192_update_beacon);
2896 INIT_DELAYED_WORK(&priv->initialgain_operate_wq, InitialGainOperateWorkItemCallBack);
2897 //INIT_WORK(&priv->SwChnlWorkItem, rtl8192_SwChnl_WorkItem);
2898 //INIT_WORK(&priv->SetBWModeWorkItem, rtl8192_SetBWModeWorkItem);
2899 INIT_WORK(&priv->qos_activate, rtl8192_qos_activate);
2901 tasklet_init(&priv->irq_rx_tasklet,
2902 (void(*)(unsigned long))rtl8192_irq_rx_tasklet,
2903 (unsigned long)priv);
2906 static void rtl8192_get_eeprom_size(struct net_device* dev)
2908 u16 curCR = 0;
2909 struct r8192_priv *priv = ieee80211_priv(dev);
2910 RT_TRACE(COMP_EPROM, "===========>%s()\n", __FUNCTION__);
2911 curCR = read_nic_word_E(dev,EPROM_CMD);
2912 RT_TRACE(COMP_EPROM, "read from Reg EPROM_CMD(%x):%x\n", EPROM_CMD, curCR);
2913 //whether need I consider BIT5?
2914 priv->epromtype = (curCR & Cmd9346CR_9356SEL) ? EPROM_93c56 : EPROM_93c46;
2915 RT_TRACE(COMP_EPROM, "<===========%s(), epromtype:%d\n", __FUNCTION__, priv->epromtype);
2918 //used to swap endian. as ntohl & htonl are not neccessary to swap endian, so use this instead.
2919 static inline u16 endian_swap(u16* data)
2921 u16 tmp = *data;
2922 *data = (tmp >> 8) | (tmp << 8);
2923 return *data;
2925 static void rtl8192_read_eeprom_info(struct net_device* dev)
2927 u16 wEPROM_ID = 0;
2928 u8 bMac_Tmp_Addr[6] = {0x00, 0xe0, 0x4c, 0x00, 0x00, 0x02};
2929 u8 bLoad_From_EEPOM = false;
2930 struct r8192_priv *priv = ieee80211_priv(dev);
2931 u16 tmpValue = 0;
2932 RT_TRACE(COMP_EPROM, "===========>%s()\n", __FUNCTION__);
2933 wEPROM_ID = eprom_read(dev, 0); //first read EEPROM ID out;
2934 RT_TRACE(COMP_EPROM, "EEPROM ID is 0x%x\n", wEPROM_ID);
2936 if (wEPROM_ID != RTL8190_EEPROM_ID)
2938 RT_TRACE(COMP_ERR, "EEPROM ID is invalid(is 0x%x(should be 0x%x)\n", wEPROM_ID, RTL8190_EEPROM_ID);
2940 else
2941 bLoad_From_EEPOM = true;
2943 if (bLoad_From_EEPOM)
2945 tmpValue = eprom_read(dev, (EEPROM_VID>>1));
2946 priv->eeprom_vid = endian_swap(&tmpValue);
2947 priv->eeprom_pid = eprom_read(dev, (EEPROM_PID>>1));
2948 tmpValue = eprom_read(dev, (EEPROM_ChannelPlan>>1));
2949 priv->eeprom_ChannelPlan =((tmpValue&0xff00)>>8);
2950 priv->btxpowerdata_readfromEEPORM = true;
2951 priv->eeprom_CustomerID = eprom_read(dev, (EEPROM_Customer_ID>>1)) >>8;
2953 else
2955 priv->eeprom_vid = 0;
2956 priv->eeprom_pid = 0;
2957 priv->card_8192_version = VERSION_819xU_B;
2958 priv->eeprom_ChannelPlan = 0;
2959 priv->eeprom_CustomerID = 0;
2961 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);
2962 //set channelplan from eeprom
2963 priv->ChannelPlan = priv->eeprom_ChannelPlan;
2964 if (bLoad_From_EEPOM)
2966 int i;
2967 for (i=0; i<6; i+=2)
2969 u16 tmp = 0;
2970 tmp = eprom_read(dev, (u16)((EEPROM_NODE_ADDRESS_BYTE_0 + i)>>1));
2971 *(u16*)(&dev->dev_addr[i]) = tmp;
2974 else
2976 memcpy(dev->dev_addr, bMac_Tmp_Addr, 6);
2977 //should I set IDR0 here?
2979 RT_TRACE(COMP_EPROM, "MAC addr:"MAC_FMT"\n", MAC_ARG(dev->dev_addr));
2980 priv->rf_type = RTL819X_DEFAULT_RF_TYPE; //default 1T2R
2981 priv->rf_chip = RF_8256;
2983 if (priv->card_8192_version == (u8)VERSION_819xU_A)
2985 //read Tx power gain offset of legacy OFDM to HT rate
2986 if (bLoad_From_EEPOM)
2987 priv->EEPROMTxPowerDiff = (eprom_read(dev, (EEPROM_TxPowerDiff>>1))&0xff00) >> 8;
2988 else
2989 priv->EEPROMTxPowerDiff = EEPROM_Default_TxPower;
2990 RT_TRACE(COMP_EPROM, "TxPowerDiff:%d\n", priv->EEPROMTxPowerDiff);
2991 //read ThermalMeter from EEPROM
2992 if (bLoad_From_EEPOM)
2993 priv->EEPROMThermalMeter = (u8)(eprom_read(dev, (EEPROM_ThermalMeter>>1))&0x00ff);
2994 else
2995 priv->EEPROMThermalMeter = EEPROM_Default_ThermalMeter;
2996 RT_TRACE(COMP_EPROM, "ThermalMeter:%d\n", priv->EEPROMThermalMeter);
2997 //vivi, for tx power track
2998 priv->TSSI_13dBm = priv->EEPROMThermalMeter *100;
2999 //read antenna tx power offset of B/C/D to A from EEPROM
3000 if (bLoad_From_EEPOM)
3001 priv->EEPROMPwDiff = (eprom_read(dev, (EEPROM_PwDiff>>1))&0x0f00)>>8;
3002 else
3003 priv->EEPROMPwDiff = EEPROM_Default_PwDiff;
3004 RT_TRACE(COMP_EPROM, "TxPwDiff:%d\n", priv->EEPROMPwDiff);
3005 // Read CrystalCap from EEPROM
3006 if (bLoad_From_EEPOM)
3007 priv->EEPROMCrystalCap = (eprom_read(dev, (EEPROM_CrystalCap>>1))&0x0f);
3008 else
3009 priv->EEPROMCrystalCap = EEPROM_Default_CrystalCap;
3010 RT_TRACE(COMP_EPROM, "CrystalCap = %d\n", priv->EEPROMCrystalCap);
3011 //get per-channel Tx power level
3012 if (bLoad_From_EEPOM)
3013 priv->EEPROM_Def_Ver = (eprom_read(dev, (EEPROM_TxPwIndex_Ver>>1))&0xff00)>>8;
3014 else
3015 priv->EEPROM_Def_Ver = 1;
3016 RT_TRACE(COMP_EPROM, "EEPROM_DEF_VER:%d\n", priv->EEPROM_Def_Ver);
3017 if (priv->EEPROM_Def_Ver == 0) //old eeprom definition
3019 int i;
3020 if (bLoad_From_EEPOM)
3021 priv->EEPROMTxPowerLevelCCK = (eprom_read(dev, (EEPROM_TxPwIndex_CCK>>1))&0xff) >> 8;
3022 else
3023 priv->EEPROMTxPowerLevelCCK = 0x10;
3024 RT_TRACE(COMP_EPROM, "CCK Tx Power Levl: 0x%02x\n", priv->EEPROMTxPowerLevelCCK);
3025 for (i=0; i<3; i++)
3027 if (bLoad_From_EEPOM)
3029 tmpValue = eprom_read(dev, (EEPROM_TxPwIndex_OFDM_24G+i)>>1);
3030 if (((EEPROM_TxPwIndex_OFDM_24G+i) % 2) == 0)
3031 tmpValue = tmpValue & 0x00ff;
3032 else
3033 tmpValue = (tmpValue & 0xff00) >> 8;
3035 else
3036 tmpValue = 0x10;
3037 priv->EEPROMTxPowerLevelOFDM24G[i] = (u8) tmpValue;
3038 RT_TRACE(COMP_EPROM, "OFDM 2.4G Tx Power Level, Index %d = 0x%02x\n", i, priv->EEPROMTxPowerLevelCCK);
3040 }//end if EEPROM_DEF_VER == 0
3041 else if (priv->EEPROM_Def_Ver == 1)
3043 if (bLoad_From_EEPOM)
3045 tmpValue = eprom_read(dev, (EEPROM_TxPwIndex_CCK_V1>>1));
3046 tmpValue = (tmpValue & 0xff00) >> 8;
3048 else
3049 tmpValue = 0x10;
3050 priv->EEPROMTxPowerLevelCCK_V1[0] = (u8)tmpValue;
3052 if (bLoad_From_EEPOM)
3053 tmpValue = eprom_read(dev, (EEPROM_TxPwIndex_CCK_V1 + 2)>>1);
3054 else
3055 tmpValue = 0x1010;
3056 *((u16*)(&priv->EEPROMTxPowerLevelCCK_V1[1])) = tmpValue;
3057 if (bLoad_From_EEPOM)
3058 tmpValue = eprom_read(dev, (EEPROM_TxPwIndex_OFDM_24G_V1>>1));
3059 else
3060 tmpValue = 0x1010;
3061 *((u16*)(&priv->EEPROMTxPowerLevelOFDM24G[0])) = tmpValue;
3062 if (bLoad_From_EEPOM)
3063 tmpValue = eprom_read(dev, (EEPROM_TxPwIndex_OFDM_24G_V1+2)>>1);
3064 else
3065 tmpValue = 0x10;
3066 priv->EEPROMTxPowerLevelOFDM24G[2] = (u8)tmpValue;
3067 }//endif EEPROM_Def_Ver == 1
3069 //update HAL variables
3072 int i;
3073 for (i=0; i<14; i++)
3075 if (i<=3)
3076 priv->TxPowerLevelOFDM24G[i] = priv->EEPROMTxPowerLevelOFDM24G[0];
3077 else if (i>=4 && i<=9)
3078 priv->TxPowerLevelOFDM24G[i] = priv->EEPROMTxPowerLevelOFDM24G[1];
3079 else
3080 priv->TxPowerLevelOFDM24G[i] = priv->EEPROMTxPowerLevelOFDM24G[2];
3083 for (i=0; i<14; i++)
3085 if (priv->EEPROM_Def_Ver == 0)
3087 if (i<=3)
3088 priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelOFDM24G[0] + (priv->EEPROMTxPowerLevelCCK - priv->EEPROMTxPowerLevelOFDM24G[1]);
3089 else if (i>=4 && i<=9)
3090 priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelCCK;
3091 else
3092 priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelOFDM24G[2] + (priv->EEPROMTxPowerLevelCCK - priv->EEPROMTxPowerLevelOFDM24G[1]);
3094 else if (priv->EEPROM_Def_Ver == 1)
3096 if (i<=3)
3097 priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelCCK_V1[0];
3098 else if (i>=4 && i<=9)
3099 priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelCCK_V1[1];
3100 else
3101 priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelCCK_V1[2];
3104 }//end update HAL variables
3105 priv->TxPowerDiff = priv->EEPROMPwDiff;
3106 // Antenna B gain offset to antenna A, bit0~3
3107 priv->AntennaTxPwDiff[0] = (priv->EEPROMTxPowerDiff & 0xf);
3108 // Antenna C gain offset to antenna A, bit4~7
3109 priv->AntennaTxPwDiff[1] = ((priv->EEPROMTxPowerDiff & 0xf0)>>4);
3110 // CrystalCap, bit12~15
3111 priv->CrystalCap = priv->EEPROMCrystalCap;
3112 // ThermalMeter, bit0~3 for RFIC1, bit4~7 for RFIC2
3113 // 92U does not enable TX power tracking.
3114 priv->ThermalMeter[0] = priv->EEPROMThermalMeter;
3115 }//end if VersionID == VERSION_819xU_A
3117 //added by vivi, for dlink led, 20080416
3118 switch(priv->eeprom_CustomerID)
3120 case EEPROM_CID_RUNTOP:
3121 priv->CustomerID = RT_CID_819x_RUNTOP;
3122 break;
3124 case EEPROM_CID_DLINK:
3125 priv->CustomerID = RT_CID_DLINK;
3126 break;
3128 default:
3129 priv->CustomerID = RT_CID_DEFAULT;
3130 break;
3134 switch(priv->CustomerID)
3136 case RT_CID_819x_RUNTOP:
3137 priv->LedStrategy = SW_LED_MODE2;
3138 break;
3140 case RT_CID_DLINK:
3141 priv->LedStrategy = SW_LED_MODE4;
3142 break;
3144 default:
3145 priv->LedStrategy = SW_LED_MODE0;
3146 break;
3151 if(priv->rf_type == RF_1T2R)
3153 RT_TRACE(COMP_EPROM, "\n1T2R config\n");
3155 else
3157 RT_TRACE(COMP_EPROM, "\n2T4R config\n");
3160 // 2008/01/16 MH We can only know RF type in the function. So we have to init
3161 // DIG RATR table again.
3162 init_rate_adaptive(dev);
3163 //we need init DIG RATR table here again.
3165 RT_TRACE(COMP_EPROM, "<===========%s()\n", __FUNCTION__);
3166 return;
3169 short rtl8192_get_channel_map(struct net_device * dev)
3171 struct r8192_priv *priv = ieee80211_priv(dev);
3172 #ifdef ENABLE_DOT11D
3173 if(priv->ChannelPlan > COUNTRY_CODE_GLOBAL_DOMAIN){
3174 printk("rtl8180_init:Error channel plan! Set to default.\n");
3175 priv->ChannelPlan= 0;
3177 RT_TRACE(COMP_INIT, "Channel plan is %d\n",priv->ChannelPlan);
3179 rtl819x_set_channel_map(priv->ChannelPlan, priv);
3180 #else
3181 int ch,i;
3182 //Set Default Channel Plan
3183 if(!channels){
3184 DMESG("No channels, aborting");
3185 return -1;
3187 ch=channels;
3188 priv->ChannelPlan= 0;//hikaru
3189 // set channels 1..14 allowed in given locale
3190 for (i=1; i<=14; i++) {
3191 (priv->ieee80211->channel_map)[i] = (u8)(ch & 0x01);
3192 ch >>= 1;
3194 #endif
3195 return 0;
3198 short rtl8192_init(struct net_device *dev)
3201 struct r8192_priv *priv = ieee80211_priv(dev);
3203 memset(&(priv->stats),0,sizeof(struct Stats));
3204 memset(priv->txqueue_to_outpipemap,0,9);
3205 #ifdef PIPE12
3207 int i=0;
3208 u8 queuetopipe[]={3,2,1,0,4,8,7,6,5};
3209 memcpy(priv->txqueue_to_outpipemap,queuetopipe,9);
3210 /* for(i=0;i<9;i++)
3211 printk("%d ",priv->txqueue_to_outpipemap[i]);
3212 printk("\n");*/
3214 #else
3216 u8 queuetopipe[]={3,2,1,0,4,4,0,4,4};
3217 memcpy(priv->txqueue_to_outpipemap,queuetopipe,9);
3218 /* for(i=0;i<9;i++)
3219 printk("%d ",priv->txqueue_to_outpipemap[i]);
3220 printk("\n");*/
3222 #endif
3223 rtl8192_init_priv_variable(dev);
3224 rtl8192_init_priv_lock(priv);
3225 rtl8192_init_priv_task(dev);
3226 rtl8192_get_eeprom_size(dev);
3227 rtl8192_read_eeprom_info(dev);
3228 rtl8192_get_channel_map(dev);
3229 init_hal_dm(dev);
3230 init_timer(&priv->watch_dog_timer);
3231 priv->watch_dog_timer.data = (unsigned long)dev;
3232 priv->watch_dog_timer.function = watch_dog_timer_callback;
3233 if(rtl8192_usb_initendpoints(dev)!=0){
3234 DMESG("Endopoints initialization failed");
3235 return -ENOMEM;
3238 //rtl8192_adapter_start(dev);
3239 #ifdef DEBUG_EPROM
3240 dump_eprom(dev);
3241 #endif
3242 return 0;
3245 /******************************************************************************
3246 *function: This function actually only set RRSR, RATR and BW_OPMODE registers
3247 * not to do all the hw config as its name says
3248 * input: net_device dev
3249 * output: none
3250 * return: none
3251 * notice: This part need to modified according to the rate set we filtered
3252 * ****************************************************************************/
3253 void rtl8192_hwconfig(struct net_device* dev)
3255 u32 regRATR = 0, regRRSR = 0;
3256 u8 regBwOpMode = 0, regTmp = 0;
3257 struct r8192_priv *priv = ieee80211_priv(dev);
3259 // Set RRSR, RATR, and BW_OPMODE registers
3261 switch(priv->ieee80211->mode)
3263 case WIRELESS_MODE_B:
3264 regBwOpMode = BW_OPMODE_20MHZ;
3265 regRATR = RATE_ALL_CCK;
3266 regRRSR = RATE_ALL_CCK;
3267 break;
3268 case WIRELESS_MODE_A:
3269 regBwOpMode = BW_OPMODE_5G |BW_OPMODE_20MHZ;
3270 regRATR = RATE_ALL_OFDM_AG;
3271 regRRSR = RATE_ALL_OFDM_AG;
3272 break;
3273 case WIRELESS_MODE_G:
3274 regBwOpMode = BW_OPMODE_20MHZ;
3275 regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
3276 regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
3277 break;
3278 case WIRELESS_MODE_AUTO:
3279 #ifdef TO_DO_LIST
3280 if (Adapter->bInHctTest)
3282 regBwOpMode = BW_OPMODE_20MHZ;
3283 regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
3284 regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
3286 else
3287 #endif
3289 regBwOpMode = BW_OPMODE_20MHZ;
3290 regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
3291 regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
3293 break;
3294 case WIRELESS_MODE_N_24G:
3295 // It support CCK rate by default.
3296 // CCK rate will be filtered out only when associated AP does not support it.
3297 regBwOpMode = BW_OPMODE_20MHZ;
3298 regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
3299 regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
3300 break;
3301 case WIRELESS_MODE_N_5G:
3302 regBwOpMode = BW_OPMODE_5G;
3303 regRATR = RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
3304 regRRSR = RATE_ALL_OFDM_AG;
3305 break;
3308 write_nic_byte(dev, BW_OPMODE, regBwOpMode);
3310 u32 ratr_value = 0;
3311 ratr_value = regRATR;
3312 if (priv->rf_type == RF_1T2R)
3314 ratr_value &= ~(RATE_ALL_OFDM_2SS);
3316 write_nic_dword(dev, RATR0, ratr_value);
3317 write_nic_byte(dev, UFWP, 1);
3319 regTmp = read_nic_byte(dev, 0x313);
3320 regRRSR = ((regTmp) << 24) | (regRRSR & 0x00ffffff);
3321 write_nic_dword(dev, RRSR, regRRSR);
3324 // Set Retry Limit here
3326 write_nic_word(dev, RETRY_LIMIT,
3327 priv->ShortRetryLimit << RETRY_LIMIT_SHORT_SHIFT | \
3328 priv->LongRetryLimit << RETRY_LIMIT_LONG_SHIFT);
3329 // Set Contention Window here
3331 // Set Tx AGC
3333 // Set Tx Antenna including Feedback control
3335 // Set Auto Rate fallback control
3341 //InitializeAdapter and PhyCfg
3342 bool rtl8192_adapter_start(struct net_device *dev)
3344 struct r8192_priv *priv = ieee80211_priv(dev);
3345 u32 dwRegRead = 0;
3346 bool init_status = true;
3347 RT_TRACE(COMP_INIT, "====>%s()\n", __FUNCTION__);
3348 priv->Rf_Mode = RF_OP_By_SW_3wire;
3349 //for ASIC power on sequence
3350 write_nic_byte_E(dev, 0x5f, 0x80);
3351 mdelay(50);
3352 write_nic_byte_E(dev, 0x5f, 0xf0);
3353 write_nic_byte_E(dev, 0x5d, 0x00);
3354 write_nic_byte_E(dev, 0x5e, 0x80);
3355 write_nic_byte(dev, 0x17, 0x37);
3356 mdelay(10);
3357 //#ifdef TO_DO_LIST
3358 priv->pFirmware->firmware_status = FW_STATUS_0_INIT;
3359 //config CPUReset Register
3360 //Firmware Reset or not?
3361 dwRegRead = read_nic_dword(dev, CPU_GEN);
3362 if (priv->pFirmware->firmware_status == FW_STATUS_0_INIT)
3363 dwRegRead |= CPU_GEN_SYSTEM_RESET; //do nothing here?
3364 else if (priv->pFirmware->firmware_status == FW_STATUS_5_READY)
3365 dwRegRead |= CPU_GEN_FIRMWARE_RESET;
3366 else
3367 RT_TRACE(COMP_ERR, "ERROR in %s(): undefined firmware state(%d)\n", __FUNCTION__, priv->pFirmware->firmware_status);
3369 write_nic_dword(dev, CPU_GEN, dwRegRead);
3370 //mdelay(30);
3371 //config BB.
3372 rtl8192_BBConfig(dev);
3374 //Loopback mode or not
3375 priv->LoopbackMode = RTL819xU_NO_LOOPBACK;
3376 // priv->LoopbackMode = RTL819xU_MAC_LOOPBACK;
3378 dwRegRead = read_nic_dword(dev, CPU_GEN);
3379 if (priv->LoopbackMode == RTL819xU_NO_LOOPBACK)
3380 dwRegRead = ((dwRegRead & CPU_GEN_NO_LOOPBACK_MSK) | CPU_GEN_NO_LOOPBACK_SET);
3381 else if (priv->LoopbackMode == RTL819xU_MAC_LOOPBACK)
3382 dwRegRead |= CPU_CCK_LOOPBACK;
3383 else
3384 RT_TRACE(COMP_ERR, "Serious error in %s(): wrong loopback mode setting(%d)\n", __FUNCTION__, priv->LoopbackMode);
3386 write_nic_dword(dev, CPU_GEN, dwRegRead);
3388 //after reset cpu, we need wait for a seconds to write in register.
3389 udelay(500);
3391 //xiong add for new bitfile:usb suspend reset pin set to 1. //do we need?
3392 write_nic_byte_E(dev, 0x5f, (read_nic_byte_E(dev, 0x5f)|0x20));
3394 //Set Hardware
3395 rtl8192_hwconfig(dev);
3397 //turn on Tx/Rx
3398 write_nic_byte(dev, CMDR, CR_RE|CR_TE);
3400 //set IDR0 here
3401 write_nic_dword(dev, MAC0, ((u32*)dev->dev_addr)[0]);
3402 write_nic_word(dev, MAC4, ((u16*)(dev->dev_addr + 4))[0]);
3404 //set RCR
3405 write_nic_dword(dev, RCR, priv->ReceiveConfig);
3407 //Initialize Number of Reserved Pages in Firmware Queue
3408 write_nic_dword(dev, RQPN1, NUM_OF_PAGE_IN_FW_QUEUE_BK << RSVD_FW_QUEUE_PAGE_BK_SHIFT |\
3409 NUM_OF_PAGE_IN_FW_QUEUE_BE << RSVD_FW_QUEUE_PAGE_BE_SHIFT | \
3410 NUM_OF_PAGE_IN_FW_QUEUE_VI << RSVD_FW_QUEUE_PAGE_VI_SHIFT | \
3411 NUM_OF_PAGE_IN_FW_QUEUE_VO <<RSVD_FW_QUEUE_PAGE_VO_SHIFT);
3412 write_nic_dword(dev, RQPN2, NUM_OF_PAGE_IN_FW_QUEUE_MGNT << RSVD_FW_QUEUE_PAGE_MGNT_SHIFT |\
3413 NUM_OF_PAGE_IN_FW_QUEUE_CMD << RSVD_FW_QUEUE_PAGE_CMD_SHIFT);
3414 write_nic_dword(dev, RQPN3, APPLIED_RESERVED_QUEUE_IN_FW| \
3415 NUM_OF_PAGE_IN_FW_QUEUE_BCN<<RSVD_FW_QUEUE_PAGE_BCN_SHIFT
3416 // | NUM_OF_PAGE_IN_FW_QUEUE_PUB<<RSVD_FW_QUEUE_PAGE_PUB_SHIFT
3418 write_nic_dword(dev, RATR0+4*7, (RATE_ALL_OFDM_AG | RATE_ALL_CCK));
3420 //Set AckTimeout
3421 // TODO: (it value is only for FPGA version). need to be changed!!2006.12.18, by Emily
3422 write_nic_byte(dev, ACK_TIMEOUT, 0x30);
3424 // RT_TRACE(COMP_INIT, "%s():priv->ResetProgress is %d\n", __FUNCTION__,priv->ResetProgress);
3425 if(priv->ResetProgress == RESET_TYPE_NORESET)
3426 rtl8192_SetWirelessMode(dev, priv->ieee80211->mode);
3427 if(priv->ResetProgress == RESET_TYPE_NORESET){
3428 CamResetAllEntry(dev);
3430 u8 SECR_value = 0x0;
3431 SECR_value |= SCR_TxEncEnable;
3432 SECR_value |= SCR_RxDecEnable;
3433 SECR_value |= SCR_NoSKMC;
3434 write_nic_byte(dev, SECR, SECR_value);
3438 //Beacon related
3439 write_nic_word(dev, ATIMWND, 2);
3440 write_nic_word(dev, BCN_INTERVAL, 100);
3443 #define DEFAULT_EDCA 0x005e4332
3444 int i;
3445 for (i=0; i<QOS_QUEUE_NUM; i++)
3446 write_nic_dword(dev, WDCAPARA_ADD[i], DEFAULT_EDCA);
3448 #ifdef USB_RX_AGGREGATION_SUPPORT
3449 //3 For usb rx firmware aggregation control
3450 if(priv->ResetProgress == RESET_TYPE_NORESET)
3452 u32 ulValue;
3453 PRT_HIGH_THROUGHPUT pHTInfo = priv->ieee80211->pHTInfo;
3454 ulValue = (pHTInfo->UsbRxFwAggrEn<<24) | (pHTInfo->UsbRxFwAggrPageNum<<16) |
3455 (pHTInfo->UsbRxFwAggrPacketNum<<8) | (pHTInfo->UsbRxFwAggrTimeout);
3457 * If usb rx firmware aggregation is enabled,
3458 * when anyone of three threshold conditions above is reached,
3459 * firmware will send aggregated packet to driver.
3461 write_nic_dword(dev, 0x1a8, ulValue);
3462 priv->bCurrentRxAggrEnable = true;
3464 #endif
3466 rtl8192_phy_configmac(dev);
3468 if (priv->card_8192_version == (u8) VERSION_819xU_A)
3470 rtl8192_phy_getTxPower(dev);
3471 rtl8192_phy_setTxPower(dev, priv->chan);
3474 //Firmware download
3475 init_status = init_firmware(dev);
3476 if(!init_status)
3478 RT_TRACE(COMP_ERR,"ERR!!! %s(): Firmware download is failed\n", __FUNCTION__);
3479 return init_status;
3481 RT_TRACE(COMP_INIT, "%s():after firmware download\n", __FUNCTION__);
3483 #ifdef TO_DO_LIST
3484 if(Adapter->ResetProgress == RESET_TYPE_NORESET)
3486 if(pMgntInfo->RegRfOff == TRUE)
3487 { // User disable RF via registry.
3488 RT_TRACE((COMP_INIT|COMP_RF), DBG_LOUD, ("InitializeAdapter819xUsb(): Turn off RF for RegRfOff ----------\n"));
3489 MgntActSet_RF_State(Adapter, eRfOff, RF_CHANGE_BY_SW);
3490 // Those action will be discard in MgntActSet_RF_State because off the same state
3491 for(eRFPath = 0; eRFPath <pHalData->NumTotalRFPath; eRFPath++)
3492 PHY_SetRFReg(Adapter, (RF90_RADIO_PATH_E)eRFPath, 0x4, 0xC00, 0x0);
3494 else if(pMgntInfo->RfOffReason > RF_CHANGE_BY_PS)
3495 { // H/W or S/W RF OFF before sleep.
3496 RT_TRACE((COMP_INIT|COMP_RF), DBG_LOUD, ("InitializeAdapter819xUsb(): Turn off RF for RfOffReason(%d) ----------\n", pMgntInfo->RfOffReason));
3497 MgntActSet_RF_State(Adapter, eRfOff, pMgntInfo->RfOffReason);
3499 else
3501 pHalData->eRFPowerState = eRfOn;
3502 pMgntInfo->RfOffReason = 0;
3503 RT_TRACE((COMP_INIT|COMP_RF), DBG_LOUD, ("InitializeAdapter819xUsb(): RF is on ----------\n"));
3506 else
3508 if(pHalData->eRFPowerState == eRfOff)
3510 MgntActSet_RF_State(Adapter, eRfOff, pMgntInfo->RfOffReason);
3511 // Those action will be discard in MgntActSet_RF_State because off the same state
3512 for(eRFPath = 0; eRFPath <pHalData->NumTotalRFPath; eRFPath++)
3513 PHY_SetRFReg(Adapter, (RF90_RADIO_PATH_E)eRFPath, 0x4, 0xC00, 0x0);
3516 #endif
3517 //config RF.
3518 if(priv->ResetProgress == RESET_TYPE_NORESET){
3519 rtl8192_phy_RFConfig(dev);
3520 RT_TRACE(COMP_INIT, "%s():after phy RF config\n", __FUNCTION__);
3524 if(priv->ieee80211->FwRWRF)
3525 // We can force firmware to do RF-R/W
3526 priv->Rf_Mode = RF_OP_By_FW;
3527 else
3528 priv->Rf_Mode = RF_OP_By_SW_3wire;
3531 rtl8192_phy_updateInitGain(dev);
3532 /*--set CCK and OFDM Block "ON"--*/
3533 rtl8192_setBBreg(dev, rFPGA0_RFMOD, bCCKEn, 0x1);
3534 rtl8192_setBBreg(dev, rFPGA0_RFMOD, bOFDMEn, 0x1);
3536 if(priv->ResetProgress == RESET_TYPE_NORESET)
3538 //if D or C cut
3539 u8 tmpvalue = read_nic_byte(dev, 0x301);
3540 if(tmpvalue ==0x03)
3542 priv->bDcut = TRUE;
3543 RT_TRACE(COMP_POWER_TRACKING, "D-cut\n");
3545 else
3547 priv->bDcut = FALSE;
3548 RT_TRACE(COMP_POWER_TRACKING, "C-cut\n");
3550 dm_initialize_txpower_tracking(dev);
3552 if(priv->bDcut == TRUE)
3554 u32 i, TempCCk;
3555 u32 tmpRegA= rtl8192_QueryBBReg(dev,rOFDM0_XATxIQImbalance,bMaskDWord);
3556 // u32 tmpRegC= rtl8192_QueryBBReg(dev,rOFDM0_XCTxIQImbalance,bMaskDWord);
3557 for(i = 0; i<TxBBGainTableLength; i++)
3559 if(tmpRegA == priv->txbbgain_table[i].txbbgain_value)
3561 priv->rfa_txpowertrackingindex= (u8)i;
3562 priv->rfa_txpowertrackingindex_real= (u8)i;
3563 priv->rfa_txpowertracking_default= priv->rfa_txpowertrackingindex;
3564 break;
3568 TempCCk = rtl8192_QueryBBReg(dev, rCCK0_TxFilter1, bMaskByte2);
3570 for(i=0 ; i<CCKTxBBGainTableLength ; i++)
3573 if(TempCCk == priv->cck_txbbgain_table[i].ccktxbb_valuearray[0])
3575 priv->cck_present_attentuation_20Mdefault=(u8) i;
3576 break;
3579 priv->cck_present_attentuation_40Mdefault= 0;
3580 priv->cck_present_attentuation_difference= 0;
3581 priv->cck_present_attentuation = priv->cck_present_attentuation_20Mdefault;
3583 // pMgntInfo->bTXPowerTracking = FALSE;//TEMPLY DISABLE
3586 write_nic_byte(dev, 0x87, 0x0);
3589 return init_status;
3592 /* this configures registers for beacon tx and enables it via
3593 * rtl8192_beacon_tx_enable(). rtl8192_beacon_tx_disable() might
3594 * be used to stop beacon transmission
3596 /***************************************************************************
3597 -------------------------------NET STUFF---------------------------
3598 ***************************************************************************/
3600 static struct net_device_stats *rtl8192_stats(struct net_device *dev)
3602 struct r8192_priv *priv = ieee80211_priv(dev);
3604 return &priv->ieee80211->stats;
3607 bool
3608 HalTxCheckStuck819xUsb(
3609 struct net_device *dev
3612 struct r8192_priv *priv = ieee80211_priv(dev);
3613 u16 RegTxCounter = read_nic_word(dev, 0x128);
3614 bool bStuck = FALSE;
3615 RT_TRACE(COMP_RESET,"%s():RegTxCounter is %d,TxCounter is %d\n",__FUNCTION__,RegTxCounter,priv->TxCounter);
3616 if(priv->TxCounter==RegTxCounter)
3617 bStuck = TRUE;
3619 priv->TxCounter = RegTxCounter;
3621 return bStuck;
3625 * <Assumption: RT_TX_SPINLOCK is acquired.>
3626 * First added: 2006.11.19 by emily
3628 RESET_TYPE
3629 TxCheckStuck(struct net_device *dev)
3631 struct r8192_priv *priv = ieee80211_priv(dev);
3632 u8 QueueID;
3633 // PRT_TCB pTcb;
3634 // u8 ResetThreshold;
3635 bool bCheckFwTxCnt = false;
3636 //unsigned long flags;
3639 // Decide Stuch threshold according to current power save mode
3642 // RT_TRACE(COMP_RESET, " ==> TxCheckStuck()\n");
3643 // PlatformAcquireSpinLock(Adapter, RT_TX_SPINLOCK);
3644 // spin_lock_irqsave(&priv->ieee80211->lock,flags);
3645 for (QueueID = 0; QueueID<=BEACON_QUEUE;QueueID ++)
3647 if(QueueID == TXCMD_QUEUE)
3648 continue;
3649 #ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
3650 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))
3651 #else
3652 if((skb_queue_len(&priv->ieee80211->skb_waitQ[QueueID]) == 0) && (skb_queue_len(&priv->ieee80211->skb_aggQ[QueueID]) == 0))
3653 #endif
3654 continue;
3656 bCheckFwTxCnt = true;
3658 // PlatformReleaseSpinLock(Adapter, RT_TX_SPINLOCK);
3659 // spin_unlock_irqrestore(&priv->ieee80211->lock,flags);
3660 // RT_TRACE(COMP_RESET,"bCheckFwTxCnt is %d\n",bCheckFwTxCnt);
3661 if(bCheckFwTxCnt)
3663 if(HalTxCheckStuck819xUsb(dev))
3665 RT_TRACE(COMP_RESET, "TxCheckStuck(): Fw indicates no Tx condition! \n");
3666 return RESET_TYPE_SILENT;
3669 return RESET_TYPE_NORESET;
3672 bool
3673 HalRxCheckStuck819xUsb(struct net_device *dev)
3675 u16 RegRxCounter = read_nic_word(dev, 0x130);
3676 struct r8192_priv *priv = ieee80211_priv(dev);
3677 bool bStuck = FALSE;
3678 static u8 rx_chk_cnt = 0;
3679 RT_TRACE(COMP_RESET,"%s(): RegRxCounter is %d,RxCounter is %d\n",__FUNCTION__,RegRxCounter,priv->RxCounter);
3680 // If rssi is small, we should check rx for long time because of bad rx.
3681 // or maybe it will continuous silent reset every 2 seconds.
3682 rx_chk_cnt++;
3683 if(priv->undecorated_smoothed_pwdb >= (RateAdaptiveTH_High+5))
3685 rx_chk_cnt = 0; //high rssi, check rx stuck right now.
3687 else if(priv->undecorated_smoothed_pwdb < (RateAdaptiveTH_High+5) &&
3688 ((priv->CurrentChannelBW!=HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb>=RateAdaptiveTH_Low_40M) ||
3689 (priv->CurrentChannelBW==HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb>=RateAdaptiveTH_Low_20M)) )
3691 if(rx_chk_cnt < 2)
3693 return bStuck;
3695 else
3697 rx_chk_cnt = 0;
3700 else if(((priv->CurrentChannelBW!=HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb<RateAdaptiveTH_Low_40M) ||
3701 (priv->CurrentChannelBW==HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb<RateAdaptiveTH_Low_20M)) &&
3702 priv->undecorated_smoothed_pwdb >= VeryLowRSSI)
3704 if(rx_chk_cnt < 4)
3706 //DbgPrint("RSSI < %d && RSSI >= %d, no check this time \n", RateAdaptiveTH_Low, VeryLowRSSI);
3707 return bStuck;
3709 else
3711 rx_chk_cnt = 0;
3712 //DbgPrint("RSSI < %d && RSSI >= %d, check this time \n", RateAdaptiveTH_Low, VeryLowRSSI);
3715 else
3717 if(rx_chk_cnt < 8)
3719 //DbgPrint("RSSI <= %d, no check this time \n", VeryLowRSSI);
3720 return bStuck;
3722 else
3724 rx_chk_cnt = 0;
3725 //DbgPrint("RSSI <= %d, check this time \n", VeryLowRSSI);
3729 if(priv->RxCounter==RegRxCounter)
3730 bStuck = TRUE;
3732 priv->RxCounter = RegRxCounter;
3734 return bStuck;
3737 RESET_TYPE
3738 RxCheckStuck(struct net_device *dev)
3740 struct r8192_priv *priv = ieee80211_priv(dev);
3741 //int i;
3742 bool bRxCheck = FALSE;
3744 // RT_TRACE(COMP_RESET," ==> RxCheckStuck()\n");
3745 //PlatformAcquireSpinLock(Adapter, RT_RX_SPINLOCK);
3747 if(priv->IrpPendingCount > 1)
3748 bRxCheck = TRUE;
3749 //PlatformReleaseSpinLock(Adapter, RT_RX_SPINLOCK);
3751 // RT_TRACE(COMP_RESET,"bRxCheck is %d \n",bRxCheck);
3752 if(bRxCheck)
3754 if(HalRxCheckStuck819xUsb(dev))
3756 RT_TRACE(COMP_RESET, "RxStuck Condition\n");
3757 return RESET_TYPE_SILENT;
3760 return RESET_TYPE_NORESET;
3765 * This function is called by Checkforhang to check whether we should ask OS to reset driver
3767 * \param pAdapter The adapter context for this miniport
3769 * Note:NIC with USB interface sholud not call this function because we cannot scan descriptor
3770 * to judge whether there is tx stuck.
3771 * Note: This function may be required to be rewrite for Vista OS.
3772 * <<<Assumption: Tx spinlock has been acquired >>>
3774 * 8185 and 8185b does not implement this function. This is added by Emily at 2006.11.24
3776 RESET_TYPE
3777 rtl819x_ifcheck_resetornot(struct net_device *dev)
3779 struct r8192_priv *priv = ieee80211_priv(dev);
3780 RESET_TYPE TxResetType = RESET_TYPE_NORESET;
3781 RESET_TYPE RxResetType = RESET_TYPE_NORESET;
3782 RT_RF_POWER_STATE rfState;
3784 rfState = priv->ieee80211->eRFPowerState;
3786 TxResetType = TxCheckStuck(dev);
3787 if( rfState != eRfOff ||
3788 /*ADAPTER_TEST_STATUS_FLAG(Adapter, ADAPTER_STATUS_FW_DOWNLOAD_FAILURE)) &&*/
3789 (priv->ieee80211->iw_mode != IW_MODE_ADHOC))
3791 // If driver is in the status of firmware download failure , driver skips RF initialization and RF is
3792 // in turned off state. Driver should check whether Rx stuck and do silent reset. And
3793 // if driver is in firmware download failure status, driver should initialize RF in the following
3794 // silent reset procedure Emily, 2008.01.21
3796 // Driver should not check RX stuck in IBSS mode because it is required to
3797 // set Check BSSID in order to send beacon, however, if check BSSID is
3798 // set, STA cannot hear any packet a all. Emily, 2008.04.12
3799 RxResetType = RxCheckStuck(dev);
3801 if(TxResetType==RESET_TYPE_NORMAL || RxResetType==RESET_TYPE_NORMAL)
3802 return RESET_TYPE_NORMAL;
3803 else if(TxResetType==RESET_TYPE_SILENT || RxResetType==RESET_TYPE_SILENT){
3804 RT_TRACE(COMP_RESET,"%s():silent reset\n",__FUNCTION__);
3805 return RESET_TYPE_SILENT;
3807 else
3808 return RESET_TYPE_NORESET;
3812 void rtl8192_cancel_deferred_work(struct r8192_priv* priv);
3813 int _rtl8192_up(struct net_device *dev);
3814 int rtl8192_close(struct net_device *dev);
3818 void
3819 CamRestoreAllEntry( struct net_device *dev)
3821 u8 EntryId = 0;
3822 struct r8192_priv *priv = ieee80211_priv(dev);
3823 u8* MacAddr = priv->ieee80211->current_network.bssid;
3825 static u8 CAM_CONST_ADDR[4][6] = {
3826 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
3827 {0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
3828 {0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
3829 {0x00, 0x00, 0x00, 0x00, 0x00, 0x03}};
3830 static u8 CAM_CONST_BROAD[] =
3831 {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
3833 RT_TRACE(COMP_SEC, "CamRestoreAllEntry: \n");
3836 if ((priv->ieee80211->pairwise_key_type == KEY_TYPE_WEP40)||
3837 (priv->ieee80211->pairwise_key_type == KEY_TYPE_WEP104))
3840 for(EntryId=0; EntryId<4; EntryId++)
3843 MacAddr = CAM_CONST_ADDR[EntryId];
3844 setKey(dev,
3845 EntryId ,
3846 EntryId,
3847 priv->ieee80211->pairwise_key_type,
3848 MacAddr,
3850 NULL);
3855 else if(priv->ieee80211->pairwise_key_type == KEY_TYPE_TKIP)
3859 if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
3860 setKey(dev,
3863 priv->ieee80211->pairwise_key_type,
3864 (u8*)dev->dev_addr,
3866 NULL);
3867 else
3868 setKey(dev,
3871 priv->ieee80211->pairwise_key_type,
3872 MacAddr,
3874 NULL);
3877 else if(priv->ieee80211->pairwise_key_type == KEY_TYPE_CCMP)
3881 if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
3882 setKey(dev,
3885 priv->ieee80211->pairwise_key_type,
3886 (u8*)dev->dev_addr,
3888 NULL);
3889 else
3890 setKey(dev,
3893 priv->ieee80211->pairwise_key_type,
3894 MacAddr,
3896 NULL);
3902 if(priv->ieee80211->group_key_type == KEY_TYPE_TKIP)
3904 MacAddr = CAM_CONST_BROAD;
3905 for(EntryId=1 ; EntryId<4 ; EntryId++)
3908 setKey(dev,
3909 EntryId,
3910 EntryId,
3911 priv->ieee80211->group_key_type,
3912 MacAddr,
3914 NULL);
3917 if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
3918 setKey(dev,
3921 priv->ieee80211->group_key_type,
3922 CAM_CONST_ADDR[0],
3924 NULL);
3926 else if(priv->ieee80211->group_key_type == KEY_TYPE_CCMP)
3928 MacAddr = CAM_CONST_BROAD;
3929 for(EntryId=1; EntryId<4 ; EntryId++)
3932 setKey(dev,
3933 EntryId ,
3934 EntryId,
3935 priv->ieee80211->group_key_type,
3936 MacAddr,
3938 NULL);
3942 if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
3943 setKey(dev,
3946 priv->ieee80211->group_key_type,
3947 CAM_CONST_ADDR[0],
3949 NULL);
3952 //////////////////////////////////////////////////////////////
3953 // This function is used to fix Tx/Rx stop bug temporarily.
3954 // This function will do "system reset" to NIC when Tx or Rx is stuck.
3955 // The method checking Tx/Rx stuck of this function is supported by FW,
3956 // which reports Tx and Rx counter to register 0x128 and 0x130.
3957 //////////////////////////////////////////////////////////////
3958 void
3959 rtl819x_ifsilentreset(struct net_device *dev)
3961 //OCTET_STRING asocpdu;
3962 struct r8192_priv *priv = ieee80211_priv(dev);
3963 u8 reset_times = 0;
3964 int reset_status = 0;
3965 struct ieee80211_device *ieee = priv->ieee80211;
3968 // 2007.07.20. If we need to check CCK stop, please uncomment this line.
3969 //bStuck = Adapter->HalFunc.CheckHWStopHandler(Adapter);
3971 if(priv->ResetProgress==RESET_TYPE_NORESET)
3973 RESET_START:
3975 RT_TRACE(COMP_RESET,"=========>Reset progress!! \n");
3977 // Set the variable for reset.
3978 priv->ResetProgress = RESET_TYPE_SILENT;
3979 // rtl8192_close(dev);
3980 down(&priv->wx_sem);
3981 if(priv->up == 0)
3983 RT_TRACE(COMP_ERR,"%s():the driver is not up! return\n",__FUNCTION__);
3984 up(&priv->wx_sem);
3985 return ;
3987 priv->up = 0;
3988 RT_TRACE(COMP_RESET,"%s():======>start to down the driver\n",__FUNCTION__);
3989 // if(!netif_queue_stopped(dev))
3990 // netif_stop_queue(dev);
3992 rtl8192_rtx_disable(dev);
3993 rtl8192_cancel_deferred_work(priv);
3994 deinit_hal_dm(dev);
3995 del_timer_sync(&priv->watch_dog_timer);
3997 ieee->sync_scan_hurryup = 1;
3998 if(ieee->state == IEEE80211_LINKED)
4000 down(&ieee->wx_sem);
4001 printk("ieee->state is IEEE80211_LINKED\n");
4002 ieee80211_stop_send_beacons(priv->ieee80211);
4003 del_timer_sync(&ieee->associate_timer);
4004 cancel_delayed_work(&ieee->associate_retry_wq);
4005 ieee80211_stop_scan(ieee);
4006 netif_carrier_off(dev);
4007 up(&ieee->wx_sem);
4009 else{
4010 printk("ieee->state is NOT LINKED\n");
4011 ieee80211_softmac_stop_protocol(priv->ieee80211); }
4012 up(&priv->wx_sem);
4013 RT_TRACE(COMP_RESET,"%s():<==========down process is finished\n",__FUNCTION__);
4014 //rtl8192_irq_disable(dev);
4015 RT_TRACE(COMP_RESET,"%s():===========>start to up the driver\n",__FUNCTION__);
4016 reset_status = _rtl8192_up(dev);
4018 RT_TRACE(COMP_RESET,"%s():<===========up process is finished\n",__FUNCTION__);
4019 if(reset_status == -EAGAIN)
4021 if(reset_times < 3)
4023 reset_times++;
4024 goto RESET_START;
4026 else
4028 RT_TRACE(COMP_ERR," ERR!!! %s(): Reset Failed!!\n", __FUNCTION__);
4031 ieee->is_silent_reset = 1;
4032 EnableHWSecurityConfig8192(dev);
4033 if(ieee->state == IEEE80211_LINKED && ieee->iw_mode == IW_MODE_INFRA)
4035 ieee->set_chan(ieee->dev, ieee->current_network.channel);
4037 queue_work(ieee->wq, &ieee->associate_complete_wq);
4040 else if(ieee->state == IEEE80211_LINKED && ieee->iw_mode == IW_MODE_ADHOC)
4042 ieee->set_chan(ieee->dev, ieee->current_network.channel);
4043 ieee->link_change(ieee->dev);
4045 // notify_wx_assoc_event(ieee);
4047 ieee80211_start_send_beacons(ieee);
4049 if (ieee->data_hard_resume)
4050 ieee->data_hard_resume(ieee->dev);
4051 netif_carrier_on(ieee->dev);
4054 CamRestoreAllEntry(dev);
4056 priv->ResetProgress = RESET_TYPE_NORESET;
4057 priv->reset_count++;
4059 priv->bForcedSilentReset =false;
4060 priv->bResetInProgress = false;
4062 // For test --> force write UFWP.
4063 write_nic_byte(dev, UFWP, 1);
4064 RT_TRACE(COMP_RESET, "Reset finished!! ====>[%d]\n", priv->reset_count);
4068 void CAM_read_entry(
4069 struct net_device *dev,
4070 u32 iIndex
4073 u32 target_command=0;
4074 u32 target_content=0;
4075 u8 entry_i=0;
4076 u32 ulStatus;
4077 s32 i=100;
4078 // printk("=======>start read CAM\n");
4079 for(entry_i=0;entry_i<CAM_CONTENT_COUNT;entry_i++)
4081 // polling bit, and No Write enable, and address
4082 target_command= entry_i+CAM_CONTENT_COUNT*iIndex;
4083 target_command= target_command | BIT31;
4085 //Check polling bit is clear
4086 // mdelay(1);
4087 while((i--)>=0)
4089 ulStatus = read_nic_dword(dev, RWCAM);
4090 if(ulStatus & BIT31){
4091 continue;
4093 else{
4094 break;
4097 write_nic_dword(dev, RWCAM, target_command);
4098 RT_TRACE(COMP_SEC,"CAM_read_entry(): WRITE A0: %x \n",target_command);
4099 // printk("CAM_read_entry(): WRITE A0: %lx \n",target_command);
4100 target_content = read_nic_dword(dev, RCAMO);
4101 RT_TRACE(COMP_SEC, "CAM_read_entry(): WRITE A8: %x \n",target_content);
4102 // printk("CAM_read_entry(): WRITE A8: %lx \n",target_content);
4104 printk("\n");
4107 void rtl819x_update_rxcounts(
4108 struct r8192_priv *priv,
4109 u32* TotalRxBcnNum,
4110 u32* TotalRxDataNum
4113 u16 SlotIndex;
4114 u8 i;
4116 *TotalRxBcnNum = 0;
4117 *TotalRxDataNum = 0;
4119 SlotIndex = (priv->ieee80211->LinkDetectInfo.SlotIndex++)%(priv->ieee80211->LinkDetectInfo.SlotNum);
4120 priv->ieee80211->LinkDetectInfo.RxBcnNum[SlotIndex] = priv->ieee80211->LinkDetectInfo.NumRecvBcnInPeriod;
4121 priv->ieee80211->LinkDetectInfo.RxDataNum[SlotIndex] = priv->ieee80211->LinkDetectInfo.NumRecvDataInPeriod;
4122 for( i=0; i<priv->ieee80211->LinkDetectInfo.SlotNum; i++ ){
4123 *TotalRxBcnNum += priv->ieee80211->LinkDetectInfo.RxBcnNum[i];
4124 *TotalRxDataNum += priv->ieee80211->LinkDetectInfo.RxDataNum[i];
4129 extern void rtl819x_watchdog_wqcallback(struct work_struct *work)
4131 struct delayed_work *dwork = container_of(work,struct delayed_work,work);
4132 struct r8192_priv *priv = container_of(dwork,struct r8192_priv,watch_dog_wq);
4133 struct net_device *dev = priv->ieee80211->dev;
4134 struct ieee80211_device* ieee = priv->ieee80211;
4135 RESET_TYPE ResetType = RESET_TYPE_NORESET;
4136 static u8 check_reset_cnt=0;
4137 bool bBusyTraffic = false;
4139 if(!priv->up)
4140 return;
4141 hal_dm_watchdog(dev);
4143 {//to get busy traffic condition
4144 if(ieee->state == IEEE80211_LINKED)
4146 if( ieee->LinkDetectInfo.NumRxOkInPeriod> 666 ||
4147 ieee->LinkDetectInfo.NumTxOkInPeriod> 666 ) {
4148 bBusyTraffic = true;
4150 ieee->LinkDetectInfo.NumRxOkInPeriod = 0;
4151 ieee->LinkDetectInfo.NumTxOkInPeriod = 0;
4152 ieee->LinkDetectInfo.bBusyTraffic = bBusyTraffic;
4155 //added by amy for AP roaming
4157 if(priv->ieee80211->state == IEEE80211_LINKED && priv->ieee80211->iw_mode == IW_MODE_INFRA)
4159 u32 TotalRxBcnNum = 0;
4160 u32 TotalRxDataNum = 0;
4162 rtl819x_update_rxcounts(priv, &TotalRxBcnNum, &TotalRxDataNum);
4163 if((TotalRxBcnNum+TotalRxDataNum) == 0)
4165 #ifdef TODO
4166 if(rfState == eRfOff)
4167 RT_TRACE(COMP_ERR,"========>%s()\n",__FUNCTION__);
4168 #endif
4169 printk("===>%s(): AP is power off,connect another one\n",__FUNCTION__);
4170 // Dot11d_Reset(dev);
4171 priv->ieee80211->state = IEEE80211_ASSOCIATING;
4172 notify_wx_assoc_event(priv->ieee80211);
4173 RemovePeerTS(priv->ieee80211,priv->ieee80211->current_network.bssid);
4174 priv->ieee80211->link_change(dev);
4175 queue_work(priv->ieee80211->wq, &priv->ieee80211->associate_procedure_wq);
4179 priv->ieee80211->LinkDetectInfo.NumRecvBcnInPeriod=0;
4180 priv->ieee80211->LinkDetectInfo.NumRecvDataInPeriod=0;
4182 // CAM_read_entry(dev,4);
4183 //check if reset the driver
4184 if(check_reset_cnt++ >= 3)
4186 ResetType = rtl819x_ifcheck_resetornot(dev);
4187 check_reset_cnt = 3;
4188 //DbgPrint("Start to check silent reset\n");
4190 // 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);
4191 if( (priv->force_reset) || (priv->ResetProgress==RESET_TYPE_NORESET &&
4192 (priv->bForcedSilentReset ||
4193 (!priv->bDisableNormalResetCheck && ResetType==RESET_TYPE_SILENT)))) // This is control by OID set in Pomelo
4195 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);
4196 rtl819x_ifsilentreset(dev);
4198 priv->force_reset = false;
4199 priv->bForcedSilentReset = false;
4200 priv->bResetInProgress = false;
4201 RT_TRACE(COMP_TRACE, " <==RtUsbCheckForHangWorkItemCallback()\n");
4205 void watch_dog_timer_callback(unsigned long data)
4207 struct r8192_priv *priv = ieee80211_priv((struct net_device *) data);
4208 //printk("===============>watch_dog timer\n");
4209 queue_delayed_work(priv->priv_wq,&priv->watch_dog_wq, 0);
4210 mod_timer(&priv->watch_dog_timer, jiffies + MSECS(IEEE80211_WATCH_DOG_TIME));
4212 int _rtl8192_up(struct net_device *dev)
4214 struct r8192_priv *priv = ieee80211_priv(dev);
4215 //int i;
4216 int init_status = 0;
4217 priv->up=1;
4218 priv->ieee80211->ieee_up=1;
4219 RT_TRACE(COMP_INIT, "Bringing up iface");
4220 init_status = rtl8192_adapter_start(dev);
4221 if(!init_status)
4223 RT_TRACE(COMP_ERR,"ERR!!! %s(): initialization is failed!\n", __FUNCTION__);
4224 priv->up=priv->ieee80211->ieee_up = 0;
4225 return -EAGAIN;
4227 RT_TRACE(COMP_INIT, "start adapter finished\n");
4228 rtl8192_rx_enable(dev);
4229 // rtl8192_tx_enable(dev);
4230 if(priv->ieee80211->state != IEEE80211_LINKED)
4231 ieee80211_softmac_start_protocol(priv->ieee80211);
4232 ieee80211_reset_queue(priv->ieee80211);
4233 watch_dog_timer_callback((unsigned long) dev);
4234 if(!netif_queue_stopped(dev))
4235 netif_start_queue(dev);
4236 else
4237 netif_wake_queue(dev);
4239 return 0;
4243 int rtl8192_open(struct net_device *dev)
4245 struct r8192_priv *priv = ieee80211_priv(dev);
4246 int ret;
4247 down(&priv->wx_sem);
4248 ret = rtl8192_up(dev);
4249 up(&priv->wx_sem);
4250 return ret;
4255 int rtl8192_up(struct net_device *dev)
4257 struct r8192_priv *priv = ieee80211_priv(dev);
4259 if (priv->up == 1) return -1;
4261 return _rtl8192_up(dev);
4265 int rtl8192_close(struct net_device *dev)
4267 struct r8192_priv *priv = ieee80211_priv(dev);
4268 int ret;
4270 down(&priv->wx_sem);
4272 ret = rtl8192_down(dev);
4274 up(&priv->wx_sem);
4276 return ret;
4280 int rtl8192_down(struct net_device *dev)
4282 struct r8192_priv *priv = ieee80211_priv(dev);
4283 int i;
4285 if (priv->up == 0) return -1;
4287 priv->up=0;
4288 priv->ieee80211->ieee_up = 0;
4289 RT_TRACE(COMP_DOWN, "==========>%s()\n", __FUNCTION__);
4290 /* FIXME */
4291 if (!netif_queue_stopped(dev))
4292 netif_stop_queue(dev);
4294 rtl8192_rtx_disable(dev);
4295 //rtl8192_irq_disable(dev);
4297 /* Tx related queue release */
4298 for(i = 0; i < MAX_QUEUE_SIZE; i++) {
4299 skb_queue_purge(&priv->ieee80211->skb_waitQ [i]);
4301 for(i = 0; i < MAX_QUEUE_SIZE; i++) {
4302 skb_queue_purge(&priv->ieee80211->skb_aggQ [i]);
4305 for(i = 0; i < MAX_QUEUE_SIZE; i++) {
4306 skb_queue_purge(&priv->ieee80211->skb_drv_aggQ [i]);
4309 //as cancel_delayed_work will del work->timer, so if work is not definedas struct delayed_work, it will corrupt
4310 // flush_scheduled_work();
4311 rtl8192_cancel_deferred_work(priv);
4312 deinit_hal_dm(dev);
4313 del_timer_sync(&priv->watch_dog_timer);
4316 ieee80211_softmac_stop_protocol(priv->ieee80211);
4317 memset(&priv->ieee80211->current_network, 0 , offsetof(struct ieee80211_network, list));
4318 RT_TRACE(COMP_DOWN, "<==========%s()\n", __FUNCTION__);
4320 return 0;
4324 void rtl8192_commit(struct net_device *dev)
4326 struct r8192_priv *priv = ieee80211_priv(dev);
4327 int reset_status = 0;
4328 //u8 reset_times = 0;
4329 if (priv->up == 0) return ;
4330 priv->up = 0;
4332 rtl8192_cancel_deferred_work(priv);
4333 del_timer_sync(&priv->watch_dog_timer);
4334 //cancel_delayed_work(&priv->SwChnlWorkItem);
4336 ieee80211_softmac_stop_protocol(priv->ieee80211);
4338 //rtl8192_irq_disable(dev);
4339 rtl8192_rtx_disable(dev);
4340 reset_status = _rtl8192_up(dev);
4345 void rtl8192_restart(struct net_device *dev)
4347 struct r8192_priv *priv = ieee80211_priv(dev);
4349 void rtl8192_restart(struct work_struct *work)
4351 struct r8192_priv *priv = container_of(work, struct r8192_priv, reset_wq);
4352 struct net_device *dev = priv->ieee80211->dev;
4354 down(&priv->wx_sem);
4356 rtl8192_commit(dev);
4358 up(&priv->wx_sem);
4361 static void r8192_set_multicast(struct net_device *dev)
4363 struct r8192_priv *priv = ieee80211_priv(dev);
4364 short promisc;
4366 //down(&priv->wx_sem);
4368 /* FIXME FIXME */
4370 promisc = (dev->flags & IFF_PROMISC) ? 1:0;
4372 if (promisc != priv->promisc)
4373 // rtl8192_commit(dev);
4375 priv->promisc = promisc;
4377 //schedule_work(&priv->reset_wq);
4378 //up(&priv->wx_sem);
4382 int r8192_set_mac_adr(struct net_device *dev, void *mac)
4384 struct r8192_priv *priv = ieee80211_priv(dev);
4385 struct sockaddr *addr = mac;
4387 down(&priv->wx_sem);
4389 memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
4391 schedule_work(&priv->reset_wq);
4392 up(&priv->wx_sem);
4394 return 0;
4397 /* based on ipw2200 driver */
4398 int rtl8192_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
4400 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
4401 struct iwreq *wrq = (struct iwreq *)rq;
4402 int ret=-1;
4403 struct ieee80211_device *ieee = priv->ieee80211;
4404 u32 key[4];
4405 u8 broadcast_addr[6] = {0xff,0xff,0xff,0xff,0xff,0xff};
4406 struct iw_point *p = &wrq->u.data;
4407 struct ieee_param *ipw = NULL;//(struct ieee_param *)wrq->u.data.pointer;
4409 down(&priv->wx_sem);
4412 if (p->length < sizeof(struct ieee_param) || !p->pointer){
4413 ret = -EINVAL;
4414 goto out;
4417 ipw = (struct ieee_param *)kmalloc(p->length, GFP_KERNEL);
4418 if (ipw == NULL){
4419 ret = -ENOMEM;
4420 goto out;
4422 if (copy_from_user(ipw, p->pointer, p->length)) {
4423 kfree(ipw);
4424 ret = -EFAULT;
4425 goto out;
4428 switch (cmd) {
4429 case RTL_IOCTL_WPA_SUPPLICANT:
4430 //parse here for HW security
4431 if (ipw->cmd == IEEE_CMD_SET_ENCRYPTION)
4433 if (ipw->u.crypt.set_tx)
4435 if (strcmp(ipw->u.crypt.alg, "CCMP") == 0)
4436 ieee->pairwise_key_type = KEY_TYPE_CCMP;
4437 else if (strcmp(ipw->u.crypt.alg, "TKIP") == 0)
4438 ieee->pairwise_key_type = KEY_TYPE_TKIP;
4439 else if (strcmp(ipw->u.crypt.alg, "WEP") == 0)
4441 if (ipw->u.crypt.key_len == 13)
4442 ieee->pairwise_key_type = KEY_TYPE_WEP104;
4443 else if (ipw->u.crypt.key_len == 5)
4444 ieee->pairwise_key_type = KEY_TYPE_WEP40;
4446 else
4447 ieee->pairwise_key_type = KEY_TYPE_NA;
4449 if (ieee->pairwise_key_type)
4451 memcpy((u8*)key, ipw->u.crypt.key, 16);
4452 EnableHWSecurityConfig8192(dev);
4453 //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!
4454 //added by WB.
4455 setKey(dev, 4, ipw->u.crypt.idx, ieee->pairwise_key_type, (u8*)ieee->ap_mac_addr, 0, key);
4456 if (ieee->auth_mode != 2)
4457 setKey(dev, ipw->u.crypt.idx, ipw->u.crypt.idx, ieee->pairwise_key_type, (u8*)ieee->ap_mac_addr, 0, key);
4460 else //if (ipw->u.crypt.idx) //group key use idx > 0
4462 memcpy((u8*)key, ipw->u.crypt.key, 16);
4463 if (strcmp(ipw->u.crypt.alg, "CCMP") == 0)
4464 ieee->group_key_type= KEY_TYPE_CCMP;
4465 else if (strcmp(ipw->u.crypt.alg, "TKIP") == 0)
4466 ieee->group_key_type = KEY_TYPE_TKIP;
4467 else if (strcmp(ipw->u.crypt.alg, "WEP") == 0)
4469 if (ipw->u.crypt.key_len == 13)
4470 ieee->group_key_type = KEY_TYPE_WEP104;
4471 else if (ipw->u.crypt.key_len == 5)
4472 ieee->group_key_type = KEY_TYPE_WEP40;
4474 else
4475 ieee->group_key_type = KEY_TYPE_NA;
4477 if (ieee->group_key_type)
4479 setKey( dev,
4480 ipw->u.crypt.idx,
4481 ipw->u.crypt.idx, //KeyIndex
4482 ieee->group_key_type, //KeyType
4483 broadcast_addr, //MacAddr
4484 0, //DefaultKey
4485 key); //KeyContent
4489 #ifdef JOHN_HWSEC_DEBUG
4490 //john's test 0711
4491 printk("@@ wrq->u pointer = ");
4492 for(i=0;i<wrq->u.data.length;i++){
4493 if(i%10==0) printk("\n");
4494 printk( "%8x|", ((u32*)wrq->u.data.pointer)[i] );
4496 printk("\n");
4497 #endif /*JOHN_HWSEC_DEBUG*/
4498 ret = ieee80211_wpa_supplicant_ioctl(priv->ieee80211, &wrq->u.data);
4499 break;
4501 default:
4502 ret = -EOPNOTSUPP;
4503 break;
4505 kfree(ipw);
4506 ipw = NULL;
4507 out:
4508 up(&priv->wx_sem);
4509 return ret;
4512 u8 HwRateToMRate90(bool bIsHT, u8 rate)
4514 u8 ret_rate = 0xff;
4516 if(!bIsHT) {
4517 switch(rate) {
4518 case DESC90_RATE1M: ret_rate = MGN_1M; break;
4519 case DESC90_RATE2M: ret_rate = MGN_2M; break;
4520 case DESC90_RATE5_5M: ret_rate = MGN_5_5M; break;
4521 case DESC90_RATE11M: ret_rate = MGN_11M; break;
4522 case DESC90_RATE6M: ret_rate = MGN_6M; break;
4523 case DESC90_RATE9M: ret_rate = MGN_9M; break;
4524 case DESC90_RATE12M: ret_rate = MGN_12M; break;
4525 case DESC90_RATE18M: ret_rate = MGN_18M; break;
4526 case DESC90_RATE24M: ret_rate = MGN_24M; break;
4527 case DESC90_RATE36M: ret_rate = MGN_36M; break;
4528 case DESC90_RATE48M: ret_rate = MGN_48M; break;
4529 case DESC90_RATE54M: ret_rate = MGN_54M; break;
4531 default:
4532 ret_rate = 0xff;
4533 RT_TRACE(COMP_RECV, "HwRateToMRate90(): Non supported Rate [%x], bIsHT = %d!!!\n", rate, bIsHT);
4534 break;
4537 } else {
4538 switch(rate) {
4539 case DESC90_RATEMCS0: ret_rate = MGN_MCS0; break;
4540 case DESC90_RATEMCS1: ret_rate = MGN_MCS1; break;
4541 case DESC90_RATEMCS2: ret_rate = MGN_MCS2; break;
4542 case DESC90_RATEMCS3: ret_rate = MGN_MCS3; break;
4543 case DESC90_RATEMCS4: ret_rate = MGN_MCS4; break;
4544 case DESC90_RATEMCS5: ret_rate = MGN_MCS5; break;
4545 case DESC90_RATEMCS6: ret_rate = MGN_MCS6; break;
4546 case DESC90_RATEMCS7: ret_rate = MGN_MCS7; break;
4547 case DESC90_RATEMCS8: ret_rate = MGN_MCS8; break;
4548 case DESC90_RATEMCS9: ret_rate = MGN_MCS9; break;
4549 case DESC90_RATEMCS10: ret_rate = MGN_MCS10; break;
4550 case DESC90_RATEMCS11: ret_rate = MGN_MCS11; break;
4551 case DESC90_RATEMCS12: ret_rate = MGN_MCS12; break;
4552 case DESC90_RATEMCS13: ret_rate = MGN_MCS13; break;
4553 case DESC90_RATEMCS14: ret_rate = MGN_MCS14; break;
4554 case DESC90_RATEMCS15: ret_rate = MGN_MCS15; break;
4555 case DESC90_RATEMCS32: ret_rate = (0x80|0x20); break;
4557 default:
4558 ret_rate = 0xff;
4559 RT_TRACE(COMP_RECV, "HwRateToMRate90(): Non supported Rate [%x], bIsHT = %d!!!\n",rate, bIsHT);
4560 break;
4564 return ret_rate;
4568 * Function: UpdateRxPktTimeStamp
4569 * Overview: Recored down the TSF time stamp when receiving a packet
4571 * Input:
4572 * PADAPTER Adapter
4573 * PRT_RFD pRfd,
4575 * Output:
4576 * PRT_RFD pRfd
4577 * (pRfd->Status.TimeStampHigh is updated)
4578 * (pRfd->Status.TimeStampLow is updated)
4579 * Return:
4580 * None
4582 void UpdateRxPktTimeStamp8190 (struct net_device *dev, struct ieee80211_rx_stats *stats)
4584 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
4586 if(stats->bIsAMPDU && !stats->bFirstMPDU) {
4587 stats->mac_time[0] = priv->LastRxDescTSFLow;
4588 stats->mac_time[1] = priv->LastRxDescTSFHigh;
4589 } else {
4590 priv->LastRxDescTSFLow = stats->mac_time[0];
4591 priv->LastRxDescTSFHigh = stats->mac_time[1];
4595 //by amy 080606
4597 long rtl819x_translate_todbm(u8 signal_strength_index )// 0-100 index.
4599 long signal_power; // in dBm.
4601 // Translate to dBm (x=0.5y-95).
4602 signal_power = (long)((signal_strength_index + 1) >> 1);
4603 signal_power -= 95;
4605 return signal_power;
4609 /* 2008/01/22 MH We can not delcare RSSI/EVM total value of sliding window to
4610 be a local static. Otherwise, it may increase when we return from S3/S4. The
4611 value will be kept in memory or disk. We must delcare the value in adapter
4612 and it will be reinitialized when return from S3/S4. */
4613 void rtl8192_process_phyinfo(struct r8192_priv * priv,u8* buffer, struct ieee80211_rx_stats * pprevious_stats, struct ieee80211_rx_stats * pcurrent_stats)
4615 bool bcheck = false;
4616 u8 rfpath;
4617 u32 nspatial_stream, tmp_val;
4618 //u8 i;
4619 static u32 slide_rssi_index=0, slide_rssi_statistics=0;
4620 static u32 slide_evm_index=0, slide_evm_statistics=0;
4621 static u32 last_rssi=0, last_evm=0;
4623 static u32 slide_beacon_adc_pwdb_index=0, slide_beacon_adc_pwdb_statistics=0;
4624 static u32 last_beacon_adc_pwdb=0;
4626 struct ieee80211_hdr_3addr *hdr;
4627 u16 sc ;
4628 unsigned int frag,seq;
4629 hdr = (struct ieee80211_hdr_3addr *)buffer;
4630 sc = le16_to_cpu(hdr->seq_ctl);
4631 frag = WLAN_GET_SEQ_FRAG(sc);
4632 seq = WLAN_GET_SEQ_SEQ(sc);
4633 //cosa add 04292008 to record the sequence number
4634 pcurrent_stats->Seq_Num = seq;
4636 // Check whether we should take the previous packet into accounting
4638 if(!pprevious_stats->bIsAMPDU)
4640 // if previous packet is not aggregated packet
4641 bcheck = true;
4642 }else
4647 if(slide_rssi_statistics++ >= PHY_RSSI_SLID_WIN_MAX)
4649 slide_rssi_statistics = PHY_RSSI_SLID_WIN_MAX;
4650 last_rssi = priv->stats.slide_signal_strength[slide_rssi_index];
4651 priv->stats.slide_rssi_total -= last_rssi;
4653 priv->stats.slide_rssi_total += pprevious_stats->SignalStrength;
4655 priv->stats.slide_signal_strength[slide_rssi_index++] = pprevious_stats->SignalStrength;
4656 if(slide_rssi_index >= PHY_RSSI_SLID_WIN_MAX)
4657 slide_rssi_index = 0;
4659 // <1> Showed on UI for user, in dbm
4660 tmp_val = priv->stats.slide_rssi_total/slide_rssi_statistics;
4661 priv->stats.signal_strength = rtl819x_translate_todbm((u8)tmp_val);
4662 pcurrent_stats->rssi = priv->stats.signal_strength;
4664 // If the previous packet does not match the criteria, neglect it
4666 if(!pprevious_stats->bPacketMatchBSSID)
4668 if(!pprevious_stats->bToSelfBA)
4669 return;
4672 if(!bcheck)
4673 return;
4676 //rtl8190_process_cck_rxpathsel(priv,pprevious_stats);//only rtl8190 supported
4679 // Check RSSI
4681 priv->stats.num_process_phyinfo++;
4683 /* record the general signal strength to the sliding window. */
4686 // <2> Showed on UI for engineering
4687 // hardware does not provide rssi information for each rf path in CCK
4688 if(!pprevious_stats->bIsCCK && (pprevious_stats->bPacketToSelf || pprevious_stats->bToSelfBA))
4690 for (rfpath = RF90_PATH_A; rfpath < priv->NumTotalRFPath; rfpath++)
4692 if (!rtl8192_phy_CheckIsLegalRFPath(priv->ieee80211->dev, rfpath))
4693 continue;
4695 //Fixed by Jacken 2008-03-20
4696 if(priv->stats.rx_rssi_percentage[rfpath] == 0)
4698 priv->stats.rx_rssi_percentage[rfpath] = pprevious_stats->RxMIMOSignalStrength[rfpath];
4699 //DbgPrint("MIMO RSSI initialize \n");
4701 if(pprevious_stats->RxMIMOSignalStrength[rfpath] > priv->stats.rx_rssi_percentage[rfpath])
4703 priv->stats.rx_rssi_percentage[rfpath] =
4704 ( (priv->stats.rx_rssi_percentage[rfpath]*(Rx_Smooth_Factor-1)) +
4705 (pprevious_stats->RxMIMOSignalStrength[rfpath])) /(Rx_Smooth_Factor);
4706 priv->stats.rx_rssi_percentage[rfpath] = priv->stats.rx_rssi_percentage[rfpath] + 1;
4708 else
4710 priv->stats.rx_rssi_percentage[rfpath] =
4711 ( (priv->stats.rx_rssi_percentage[rfpath]*(Rx_Smooth_Factor-1)) +
4712 (pprevious_stats->RxMIMOSignalStrength[rfpath])) /(Rx_Smooth_Factor);
4714 RT_TRACE(COMP_DBG,"priv->stats.rx_rssi_percentage[rfPath] = %d \n" ,priv->stats.rx_rssi_percentage[rfpath] );
4720 // Check PWDB.
4722 RT_TRACE(COMP_RXDESC, "Smooth %s PWDB = %d\n",
4723 pprevious_stats->bIsCCK? "CCK": "OFDM",
4724 pprevious_stats->RxPWDBAll);
4726 if(pprevious_stats->bPacketBeacon)
4728 /* record the beacon pwdb to the sliding window. */
4729 if(slide_beacon_adc_pwdb_statistics++ >= PHY_Beacon_RSSI_SLID_WIN_MAX)
4731 slide_beacon_adc_pwdb_statistics = PHY_Beacon_RSSI_SLID_WIN_MAX;
4732 last_beacon_adc_pwdb = priv->stats.Slide_Beacon_pwdb[slide_beacon_adc_pwdb_index];
4733 priv->stats.Slide_Beacon_Total -= last_beacon_adc_pwdb;
4734 //DbgPrint("slide_beacon_adc_pwdb_index = %d, last_beacon_adc_pwdb = %d, Adapter->RxStats.Slide_Beacon_Total = %d\n",
4735 // slide_beacon_adc_pwdb_index, last_beacon_adc_pwdb, Adapter->RxStats.Slide_Beacon_Total);
4737 priv->stats.Slide_Beacon_Total += pprevious_stats->RxPWDBAll;
4738 priv->stats.Slide_Beacon_pwdb[slide_beacon_adc_pwdb_index] = pprevious_stats->RxPWDBAll;
4739 //DbgPrint("slide_beacon_adc_pwdb_index = %d, pPreviousRfd->Status.RxPWDBAll = %d\n", slide_beacon_adc_pwdb_index, pPreviousRfd->Status.RxPWDBAll);
4740 slide_beacon_adc_pwdb_index++;
4741 if(slide_beacon_adc_pwdb_index >= PHY_Beacon_RSSI_SLID_WIN_MAX)
4742 slide_beacon_adc_pwdb_index = 0;
4743 pprevious_stats->RxPWDBAll = priv->stats.Slide_Beacon_Total/slide_beacon_adc_pwdb_statistics;
4744 if(pprevious_stats->RxPWDBAll >= 3)
4745 pprevious_stats->RxPWDBAll -= 3;
4748 RT_TRACE(COMP_RXDESC, "Smooth %s PWDB = %d\n",
4749 pprevious_stats->bIsCCK? "CCK": "OFDM",
4750 pprevious_stats->RxPWDBAll);
4753 if(pprevious_stats->bPacketToSelf || pprevious_stats->bPacketBeacon || pprevious_stats->bToSelfBA)
4755 if(priv->undecorated_smoothed_pwdb < 0) // initialize
4757 priv->undecorated_smoothed_pwdb = pprevious_stats->RxPWDBAll;
4758 //DbgPrint("First pwdb initialize \n");
4760 if(pprevious_stats->RxPWDBAll > (u32)priv->undecorated_smoothed_pwdb)
4762 priv->undecorated_smoothed_pwdb =
4763 ( ((priv->undecorated_smoothed_pwdb)*(Rx_Smooth_Factor-1)) +
4764 (pprevious_stats->RxPWDBAll)) /(Rx_Smooth_Factor);
4765 priv->undecorated_smoothed_pwdb = priv->undecorated_smoothed_pwdb + 1;
4767 else
4769 priv->undecorated_smoothed_pwdb =
4770 ( ((priv->undecorated_smoothed_pwdb)*(Rx_Smooth_Factor-1)) +
4771 (pprevious_stats->RxPWDBAll)) /(Rx_Smooth_Factor);
4777 // Check EVM
4779 /* record the general EVM to the sliding window. */
4780 if(pprevious_stats->SignalQuality == 0)
4783 else
4785 if(pprevious_stats->bPacketToSelf || pprevious_stats->bPacketBeacon || pprevious_stats->bToSelfBA){
4786 if(slide_evm_statistics++ >= PHY_RSSI_SLID_WIN_MAX){
4787 slide_evm_statistics = PHY_RSSI_SLID_WIN_MAX;
4788 last_evm = priv->stats.slide_evm[slide_evm_index];
4789 priv->stats.slide_evm_total -= last_evm;
4792 priv->stats.slide_evm_total += pprevious_stats->SignalQuality;
4794 priv->stats.slide_evm[slide_evm_index++] = pprevious_stats->SignalQuality;
4795 if(slide_evm_index >= PHY_RSSI_SLID_WIN_MAX)
4796 slide_evm_index = 0;
4798 // <1> Showed on UI for user, in percentage.
4799 tmp_val = priv->stats.slide_evm_total/slide_evm_statistics;
4800 priv->stats.signal_quality = tmp_val;
4801 //cosa add 10/11/2007, Showed on UI for user in Windows Vista, for Link quality.
4802 priv->stats.last_signal_strength_inpercent = tmp_val;
4805 // <2> Showed on UI for engineering
4806 if(pprevious_stats->bPacketToSelf || pprevious_stats->bPacketBeacon || pprevious_stats->bToSelfBA)
4808 for(nspatial_stream = 0; nspatial_stream<2 ; nspatial_stream++) // 2 spatial stream
4810 if(pprevious_stats->RxMIMOSignalQuality[nspatial_stream] != -1)
4812 if(priv->stats.rx_evm_percentage[nspatial_stream] == 0) // initialize
4814 priv->stats.rx_evm_percentage[nspatial_stream] = pprevious_stats->RxMIMOSignalQuality[nspatial_stream];
4816 priv->stats.rx_evm_percentage[nspatial_stream] =
4817 ( (priv->stats.rx_evm_percentage[nspatial_stream]* (Rx_Smooth_Factor-1)) +
4818 (pprevious_stats->RxMIMOSignalQuality[nspatial_stream]* 1)) / (Rx_Smooth_Factor);
4827 /*-----------------------------------------------------------------------------
4828 * Function: rtl819x_query_rxpwrpercentage()
4830 * Overview:
4832 * Input: char antpower
4834 * Output: NONE
4836 * Return: 0-100 percentage
4838 * Revised History:
4839 * When Who Remark
4840 * 05/26/2008 amy Create Version 0 porting from windows code.
4842 *---------------------------------------------------------------------------*/
4843 static u8 rtl819x_query_rxpwrpercentage(
4844 char antpower
4847 if ((antpower <= -100) || (antpower >= 20))
4849 return 0;
4851 else if (antpower >= 0)
4853 return 100;
4855 else
4857 return (100+antpower);
4860 } /* QueryRxPwrPercentage */
4862 static u8
4863 rtl819x_evm_dbtopercentage(
4864 char value
4867 char ret_val;
4869 ret_val = value;
4871 if(ret_val >= 0)
4872 ret_val = 0;
4873 if(ret_val <= -33)
4874 ret_val = -33;
4875 ret_val = 0 - ret_val;
4876 ret_val*=3;
4877 if(ret_val == 99)
4878 ret_val = 100;
4879 return(ret_val);
4882 // Description:
4883 // We want good-looking for signal strength/quality
4884 // 2007/7/19 01:09, by cosa.
4886 long
4887 rtl819x_signal_scale_mapping(
4888 long currsig
4891 long retsig;
4893 // Step 1. Scale mapping.
4894 if(currsig >= 61 && currsig <= 100)
4896 retsig = 90 + ((currsig - 60) / 4);
4898 else if(currsig >= 41 && currsig <= 60)
4900 retsig = 78 + ((currsig - 40) / 2);
4902 else if(currsig >= 31 && currsig <= 40)
4904 retsig = 66 + (currsig - 30);
4906 else if(currsig >= 21 && currsig <= 30)
4908 retsig = 54 + (currsig - 20);
4910 else if(currsig >= 5 && currsig <= 20)
4912 retsig = 42 + (((currsig - 5) * 2) / 3);
4914 else if(currsig == 4)
4916 retsig = 36;
4918 else if(currsig == 3)
4920 retsig = 27;
4922 else if(currsig == 2)
4924 retsig = 18;
4926 else if(currsig == 1)
4928 retsig = 9;
4930 else
4932 retsig = currsig;
4935 return retsig;
4938 static void rtl8192_query_rxphystatus(
4939 struct r8192_priv * priv,
4940 struct ieee80211_rx_stats * pstats,
4941 rx_drvinfo_819x_usb * pdrvinfo,
4942 struct ieee80211_rx_stats * precord_stats,
4943 bool bpacket_match_bssid,
4944 bool bpacket_toself,
4945 bool bPacketBeacon,
4946 bool bToSelfBA
4949 //PRT_RFD_STATUS pRtRfdStatus = &(pRfd->Status);
4950 phy_sts_ofdm_819xusb_t* pofdm_buf;
4951 phy_sts_cck_819xusb_t * pcck_buf;
4952 phy_ofdm_rx_status_rxsc_sgien_exintfflag* prxsc;
4953 u8 *prxpkt;
4954 u8 i, max_spatial_stream, tmp_rxsnr, tmp_rxevm, rxsc_sgien_exflg;
4955 char rx_pwr[4], rx_pwr_all=0;
4956 //long rx_avg_pwr = 0;
4957 char rx_snrX, rx_evmX;
4958 u8 evm, pwdb_all;
4959 u32 RSSI, total_rssi=0;//, total_evm=0;
4960 // long signal_strength_index = 0;
4961 u8 is_cck_rate=0;
4962 u8 rf_rx_num = 0;
4965 priv->stats.numqry_phystatus++;
4967 is_cck_rate = rx_hal_is_cck_rate(pdrvinfo);
4969 // Record it for next packet processing
4970 memset(precord_stats, 0, sizeof(struct ieee80211_rx_stats));
4971 pstats->bPacketMatchBSSID = precord_stats->bPacketMatchBSSID = bpacket_match_bssid;
4972 pstats->bPacketToSelf = precord_stats->bPacketToSelf = bpacket_toself;
4973 pstats->bIsCCK = precord_stats->bIsCCK = is_cck_rate;//RX_HAL_IS_CCK_RATE(pDrvInfo);
4974 pstats->bPacketBeacon = precord_stats->bPacketBeacon = bPacketBeacon;
4975 pstats->bToSelfBA = precord_stats->bToSelfBA = bToSelfBA;
4977 prxpkt = (u8*)pdrvinfo;
4979 /* Move pointer to the 16th bytes. Phy status start address. */
4980 prxpkt += sizeof(rx_drvinfo_819x_usb);
4982 /* Initial the cck and ofdm buffer pointer */
4983 pcck_buf = (phy_sts_cck_819xusb_t *)prxpkt;
4984 pofdm_buf = (phy_sts_ofdm_819xusb_t *)prxpkt;
4986 pstats->RxMIMOSignalQuality[0] = -1;
4987 pstats->RxMIMOSignalQuality[1] = -1;
4988 precord_stats->RxMIMOSignalQuality[0] = -1;
4989 precord_stats->RxMIMOSignalQuality[1] = -1;
4991 if(is_cck_rate)
4994 // (1)Hardware does not provide RSSI for CCK
4998 // (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive)
5000 u8 report;//, cck_agc_rpt;
5002 priv->stats.numqry_phystatusCCK++;
5004 if(!priv->bCckHighPower)
5006 report = pcck_buf->cck_agc_rpt & 0xc0;
5007 report = report>>6;
5008 switch(report)
5010 //Fixed by Jacken from Bryant 2008-03-20
5011 //Original value is -38 , -26 , -14 , -2
5012 //Fixed value is -35 , -23 , -11 , 6
5013 case 0x3:
5014 rx_pwr_all = -35 - (pcck_buf->cck_agc_rpt & 0x3e);
5015 break;
5016 case 0x2:
5017 rx_pwr_all = -23 - (pcck_buf->cck_agc_rpt & 0x3e);
5018 break;
5019 case 0x1:
5020 rx_pwr_all = -11 - (pcck_buf->cck_agc_rpt & 0x3e);
5021 break;
5022 case 0x0:
5023 rx_pwr_all = 6 - (pcck_buf->cck_agc_rpt & 0x3e);
5024 break;
5027 else
5029 report = pcck_buf->cck_agc_rpt & 0x60;
5030 report = report>>5;
5031 switch(report)
5033 case 0x3:
5034 rx_pwr_all = -35 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1) ;
5035 break;
5036 case 0x2:
5037 rx_pwr_all = -23 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1);
5038 break;
5039 case 0x1:
5040 rx_pwr_all = -11 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1) ;
5041 break;
5042 case 0x0:
5043 rx_pwr_all = 6 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1) ;
5044 break;
5048 pwdb_all = rtl819x_query_rxpwrpercentage(rx_pwr_all);
5049 pstats->RxPWDBAll = precord_stats->RxPWDBAll = pwdb_all;
5050 pstats->RecvSignalPower = pwdb_all;
5053 // (3) Get Signal Quality (EVM)
5055 //if(bpacket_match_bssid)
5057 u8 sq;
5059 if(pstats->RxPWDBAll > 40)
5061 sq = 100;
5062 }else
5064 sq = pcck_buf->sq_rpt;
5066 if(pcck_buf->sq_rpt > 64)
5067 sq = 0;
5068 else if (pcck_buf->sq_rpt < 20)
5069 sq = 100;
5070 else
5071 sq = ((64-sq) * 100) / 44;
5073 pstats->SignalQuality = precord_stats->SignalQuality = sq;
5074 pstats->RxMIMOSignalQuality[0] = precord_stats->RxMIMOSignalQuality[0] = sq;
5075 pstats->RxMIMOSignalQuality[1] = precord_stats->RxMIMOSignalQuality[1] = -1;
5078 else
5080 priv->stats.numqry_phystatusHT++;
5082 // (1)Get RSSI for HT rate
5084 for(i=RF90_PATH_A; i<priv->NumTotalRFPath; i++)
5086 // 2008/01/30 MH we will judge RF RX path now.
5087 if (priv->brfpath_rxenable[i])
5088 rf_rx_num++;
5089 else
5090 continue;
5092 if (!rtl8192_phy_CheckIsLegalRFPath(priv->ieee80211->dev, i))
5093 continue;
5095 //Fixed by Jacken from Bryant 2008-03-20
5096 //Original value is 106
5097 rx_pwr[i] = ((pofdm_buf->trsw_gain_X[i]&0x3F)*2) - 106;
5099 //Get Rx snr value in DB
5100 tmp_rxsnr = pofdm_buf->rxsnr_X[i];
5101 rx_snrX = (char)(tmp_rxsnr);
5102 //rx_snrX >>= 1;;
5103 rx_snrX /= 2;
5104 priv->stats.rxSNRdB[i] = (long)rx_snrX;
5106 /* Translate DBM to percentage. */
5107 RSSI = rtl819x_query_rxpwrpercentage(rx_pwr[i]);
5108 total_rssi += RSSI;
5110 /* Record Signal Strength for next packet */
5111 //if(bpacket_match_bssid)
5113 pstats->RxMIMOSignalStrength[i] =(u8) RSSI;
5114 precord_stats->RxMIMOSignalStrength[i] =(u8) RSSI;
5120 // (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive)
5122 //Fixed by Jacken from Bryant 2008-03-20
5123 //Original value is 106
5124 rx_pwr_all = (((pofdm_buf->pwdb_all ) >> 1 )& 0x7f) -106;
5125 pwdb_all = rtl819x_query_rxpwrpercentage(rx_pwr_all);
5127 pstats->RxPWDBAll = precord_stats->RxPWDBAll = pwdb_all;
5128 pstats->RxPower = precord_stats->RxPower = rx_pwr_all;
5131 // (3)EVM of HT rate
5133 if(pdrvinfo->RxHT && pdrvinfo->RxRate>=DESC90_RATEMCS8 &&
5134 pdrvinfo->RxRate<=DESC90_RATEMCS15)
5135 max_spatial_stream = 2; //both spatial stream make sense
5136 else
5137 max_spatial_stream = 1; //only spatial stream 1 makes sense
5139 for(i=0; i<max_spatial_stream; i++)
5141 tmp_rxevm = pofdm_buf->rxevm_X[i];
5142 rx_evmX = (char)(tmp_rxevm);
5144 // Do not use shift operation like "rx_evmX >>= 1" because the compilor of free build environment
5145 // fill most significant bit to "zero" when doing shifting operation which may change a negative
5146 // value to positive one, then the dbm value (which is supposed to be negative) is not correct anymore.
5147 rx_evmX /= 2; //dbm
5149 evm = rtl819x_evm_dbtopercentage(rx_evmX);
5150 //if(bpacket_match_bssid)
5152 if(i==0) // Fill value in RFD, Get the first spatial stream only
5153 pstats->SignalQuality = precord_stats->SignalQuality = (u8)(evm & 0xff);
5154 pstats->RxMIMOSignalQuality[i] = precord_stats->RxMIMOSignalQuality[i] = (u8)(evm & 0xff);
5159 /* record rx statistics for debug */
5160 rxsc_sgien_exflg = pofdm_buf->rxsc_sgien_exflg;
5161 prxsc = (phy_ofdm_rx_status_rxsc_sgien_exintfflag *)&rxsc_sgien_exflg;
5162 if(pdrvinfo->BW) //40M channel
5163 priv->stats.received_bwtype[1+prxsc->rxsc]++;
5164 else //20M channel
5165 priv->stats.received_bwtype[0]++;
5168 //UI BSS List signal strength(in percentage), make it good looking, from 0~100.
5169 //It is assigned to the BSS List in GetValueFromBeaconOrProbeRsp().
5170 if(is_cck_rate)
5172 pstats->SignalStrength = precord_stats->SignalStrength = (u8)(rtl819x_signal_scale_mapping((long)pwdb_all));//PWDB_ALL;
5175 else
5177 //pRfd->Status.SignalStrength = pRecordRfd->Status.SignalStrength = (u8)(SignalScaleMapping(total_rssi/=RF90_PATH_MAX));//(u8)(total_rssi/=RF90_PATH_MAX);
5178 // We can judge RX path number now.
5179 if (rf_rx_num != 0)
5180 pstats->SignalStrength = precord_stats->SignalStrength = (u8)(rtl819x_signal_scale_mapping((long)(total_rssi/=rf_rx_num)));
5182 } /* QueryRxPhyStatus8190Pci */
5184 void
5185 rtl8192_record_rxdesc_forlateruse(
5186 struct ieee80211_rx_stats * psrc_stats,
5187 struct ieee80211_rx_stats * ptarget_stats
5190 ptarget_stats->bIsAMPDU = psrc_stats->bIsAMPDU;
5191 ptarget_stats->bFirstMPDU = psrc_stats->bFirstMPDU;
5192 ptarget_stats->Seq_Num = psrc_stats->Seq_Num;
5196 void TranslateRxSignalStuff819xUsb(struct sk_buff *skb,
5197 struct ieee80211_rx_stats * pstats,
5198 rx_drvinfo_819x_usb *pdrvinfo)
5200 // TODO: We must only check packet for current MAC address. Not finish
5201 rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
5202 struct net_device *dev=info->dev;
5203 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
5204 bool bpacket_match_bssid, bpacket_toself;
5205 bool bPacketBeacon=FALSE, bToSelfBA=FALSE;
5206 static struct ieee80211_rx_stats previous_stats;
5207 struct ieee80211_hdr_3addr *hdr;//by amy
5208 u16 fc,type;
5210 // Get Signal Quality for only RX data queue (but not command queue)
5212 u8* tmp_buf;
5213 //u16 tmp_buf_len = 0;
5214 u8 *praddr;
5216 /* Get MAC frame start address. */
5217 tmp_buf = (u8*)skb->data;// + get_rxpacket_shiftbytes_819xusb(pstats);
5219 hdr = (struct ieee80211_hdr_3addr *)tmp_buf;
5220 fc = le16_to_cpu(hdr->frame_ctl);
5221 type = WLAN_FC_GET_TYPE(fc);
5222 praddr = hdr->addr1;
5224 /* Check if the received packet is acceptabe. */
5225 bpacket_match_bssid = ((IEEE80211_FTYPE_CTL != type) &&
5226 (eqMacAddr(priv->ieee80211->current_network.bssid, (fc & IEEE80211_FCTL_TODS)? hdr->addr1 : (fc & IEEE80211_FCTL_FROMDS )? hdr->addr2 : hdr->addr3))
5227 && (!pstats->bHwError) && (!pstats->bCRC)&& (!pstats->bICV));
5228 bpacket_toself = bpacket_match_bssid & (eqMacAddr(praddr, priv->ieee80211->dev->dev_addr));
5230 if(WLAN_FC_GET_FRAMETYPE(fc)== IEEE80211_STYPE_BEACON)
5232 bPacketBeacon = true;
5233 //DbgPrint("Beacon 2, MatchBSSID = %d, ToSelf = %d \n", bPacketMatchBSSID, bPacketToSelf);
5235 if(WLAN_FC_GET_FRAMETYPE(fc) == IEEE80211_STYPE_BLOCKACK)
5237 if((eqMacAddr(praddr,dev->dev_addr)))
5238 bToSelfBA = true;
5239 //DbgPrint("BlockAck, MatchBSSID = %d, ToSelf = %d \n", bPacketMatchBSSID, bPacketToSelf);
5244 if(bpacket_match_bssid)
5246 priv->stats.numpacket_matchbssid++;
5248 if(bpacket_toself){
5249 priv->stats.numpacket_toself++;
5252 // Process PHY information for previous packet (RSSI/PWDB/EVM)
5254 // Because phy information is contained in the last packet of AMPDU only, so driver
5255 // should process phy information of previous packet
5256 rtl8192_process_phyinfo(priv, tmp_buf, &previous_stats, pstats);
5257 rtl8192_query_rxphystatus(priv, pstats, pdrvinfo, &previous_stats, bpacket_match_bssid,bpacket_toself,bPacketBeacon,bToSelfBA);
5258 rtl8192_record_rxdesc_forlateruse(pstats, &previous_stats);
5263 * Function: UpdateReceivedRateHistogramStatistics
5264 * Overview: Recored down the received data rate
5266 * Input:
5267 * struct net_device *dev
5268 * struct ieee80211_rx_stats *stats
5270 * Output:
5272 * (priv->stats.ReceivedRateHistogram[] is updated)
5273 * Return:
5274 * None
5276 void
5277 UpdateReceivedRateHistogramStatistics8190(
5278 struct net_device *dev,
5279 struct ieee80211_rx_stats *stats
5282 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
5283 u32 rcvType=1; //0: Total, 1:OK, 2:CRC, 3:ICV
5284 u32 rateIndex;
5285 u32 preamble_guardinterval; //1: short preamble/GI, 0: long preamble/GI
5288 if(stats->bCRC)
5289 rcvType = 2;
5290 else if(stats->bICV)
5291 rcvType = 3;
5293 if(stats->bShortPreamble)
5294 preamble_guardinterval = 1;// short
5295 else
5296 preamble_guardinterval = 0;// long
5298 switch(stats->rate)
5301 // CCK rate
5303 case MGN_1M: rateIndex = 0; break;
5304 case MGN_2M: rateIndex = 1; break;
5305 case MGN_5_5M: rateIndex = 2; break;
5306 case MGN_11M: rateIndex = 3; break;
5308 // Legacy OFDM rate
5310 case MGN_6M: rateIndex = 4; break;
5311 case MGN_9M: rateIndex = 5; break;
5312 case MGN_12M: rateIndex = 6; break;
5313 case MGN_18M: rateIndex = 7; break;
5314 case MGN_24M: rateIndex = 8; break;
5315 case MGN_36M: rateIndex = 9; break;
5316 case MGN_48M: rateIndex = 10; break;
5317 case MGN_54M: rateIndex = 11; break;
5319 // 11n High throughput rate
5321 case MGN_MCS0: rateIndex = 12; break;
5322 case MGN_MCS1: rateIndex = 13; break;
5323 case MGN_MCS2: rateIndex = 14; break;
5324 case MGN_MCS3: rateIndex = 15; break;
5325 case MGN_MCS4: rateIndex = 16; break;
5326 case MGN_MCS5: rateIndex = 17; break;
5327 case MGN_MCS6: rateIndex = 18; break;
5328 case MGN_MCS7: rateIndex = 19; break;
5329 case MGN_MCS8: rateIndex = 20; break;
5330 case MGN_MCS9: rateIndex = 21; break;
5331 case MGN_MCS10: rateIndex = 22; break;
5332 case MGN_MCS11: rateIndex = 23; break;
5333 case MGN_MCS12: rateIndex = 24; break;
5334 case MGN_MCS13: rateIndex = 25; break;
5335 case MGN_MCS14: rateIndex = 26; break;
5336 case MGN_MCS15: rateIndex = 27; break;
5337 default: rateIndex = 28; break;
5339 priv->stats.received_preamble_GI[preamble_guardinterval][rateIndex]++;
5340 priv->stats.received_rate_histogram[0][rateIndex]++; //total
5341 priv->stats.received_rate_histogram[rcvType][rateIndex]++;
5345 void query_rxdesc_status(struct sk_buff *skb, struct ieee80211_rx_stats *stats, bool bIsRxAggrSubframe)
5347 rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
5348 struct net_device *dev=info->dev;
5349 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
5350 //rx_desc_819x_usb *desc = (rx_desc_819x_usb *)skb->data;
5351 rx_drvinfo_819x_usb *driver_info = NULL;
5354 //Get Rx Descriptor Information
5356 #ifdef USB_RX_AGGREGATION_SUPPORT
5357 if (bIsRxAggrSubframe)
5359 rx_desc_819x_usb_aggr_subframe *desc = (rx_desc_819x_usb_aggr_subframe *)skb->data;
5360 stats->Length = desc->Length ;
5361 stats->RxDrvInfoSize = desc->RxDrvInfoSize;
5362 stats->RxBufShift = 0; //RxBufShift = 2 in RxDesc, but usb didn't shift bytes in fact.
5363 stats->bICV = desc->ICV;
5364 stats->bCRC = desc->CRC32;
5365 stats->bHwError = stats->bCRC|stats->bICV;
5366 stats->Decrypted = !desc->SWDec;//RTL8190 set this bit to indicate that Hw does not decrypt packet
5367 } else
5368 #endif
5370 rx_desc_819x_usb *desc = (rx_desc_819x_usb *)skb->data;
5372 stats->Length = desc->Length;
5373 stats->RxDrvInfoSize = desc->RxDrvInfoSize;
5374 stats->RxBufShift = 0;//desc->Shift&0x03;
5375 stats->bICV = desc->ICV;
5376 stats->bCRC = desc->CRC32;
5377 stats->bHwError = stats->bCRC|stats->bICV;
5378 //RTL8190 set this bit to indicate that Hw does not decrypt packet
5379 stats->Decrypted = !desc->SWDec;
5382 if((priv->ieee80211->pHTInfo->bCurrentHTSupport == true) && (priv->ieee80211->pairwise_key_type == KEY_TYPE_CCMP))
5384 stats->bHwError = false;
5386 else
5388 stats->bHwError = stats->bCRC|stats->bICV;
5391 if(stats->Length < 24 || stats->Length > MAX_8192U_RX_SIZE)
5392 stats->bHwError |= 1;
5394 //Get Driver Info
5396 // TODO: Need to verify it on FGPA platform
5397 //Driver info are written to the RxBuffer following rx desc
5398 if (stats->RxDrvInfoSize != 0) {
5399 driver_info = (rx_drvinfo_819x_usb *)(skb->data + sizeof(rx_desc_819x_usb) + \
5400 stats->RxBufShift);
5401 /* unit: 0.5M */
5402 /* TODO */
5403 if(!stats->bHwError){
5404 u8 ret_rate;
5405 ret_rate = HwRateToMRate90(driver_info->RxHT, driver_info->RxRate);
5406 if(ret_rate == 0xff)
5408 // Abnormal Case: Receive CRC OK packet with Rx descriptor indicating non supported rate.
5409 // Special Error Handling here, 2008.05.16, by Emily
5411 stats->bHwError = 1;
5412 stats->rate = MGN_1M; //Set 1M rate by default
5413 }else
5415 stats->rate = ret_rate;
5418 else
5419 stats->rate = 0x02;
5421 stats->bShortPreamble = driver_info->SPLCP;
5424 UpdateReceivedRateHistogramStatistics8190(dev, stats);
5426 stats->bIsAMPDU = (driver_info->PartAggr==1);
5427 stats->bFirstMPDU = (driver_info->PartAggr==1) && (driver_info->FirstAGGR==1);
5428 stats->TimeStampLow = driver_info->TSFL;
5429 // xiong mask it, 070514
5430 //pRfd->Status.TimeStampHigh = PlatformEFIORead4Byte(Adapter, TSFR+4);
5431 // stats->TimeStampHigh = read_nic_dword(dev, TSFR+4);
5433 UpdateRxPktTimeStamp8190(dev, stats);
5436 // Rx A-MPDU
5438 if(driver_info->FirstAGGR==1 || driver_info->PartAggr == 1)
5439 RT_TRACE(COMP_RXDESC, "driver_info->FirstAGGR = %d, driver_info->PartAggr = %d\n",
5440 driver_info->FirstAGGR, driver_info->PartAggr);
5444 skb_pull(skb,sizeof(rx_desc_819x_usb));
5446 // Get Total offset of MPDU Frame Body
5448 if((stats->RxBufShift + stats->RxDrvInfoSize) > 0) {
5449 stats->bShift = 1;
5450 skb_pull(skb,stats->RxBufShift + stats->RxDrvInfoSize);
5453 #ifdef USB_RX_AGGREGATION_SUPPORT
5454 /* for the rx aggregated sub frame, the redundant space truelly contained in the packet */
5455 if(bIsRxAggrSubframe) {
5456 skb_pull(skb, 8);
5458 #endif
5459 /* for debug 2008.5.29 */
5461 //added by vivi, for MP, 20080108
5462 stats->RxIs40MHzPacket = driver_info->BW;
5463 if(stats->RxDrvInfoSize != 0)
5464 TranslateRxSignalStuff819xUsb(skb, stats, driver_info);
5468 u32 GetRxPacketShiftBytes819xUsb(struct ieee80211_rx_stats *Status, bool bIsRxAggrSubframe)
5470 #ifdef USB_RX_AGGREGATION_SUPPORT
5471 if (bIsRxAggrSubframe)
5472 return (sizeof(rx_desc_819x_usb) + Status->RxDrvInfoSize
5473 + Status->RxBufShift + 8);
5474 else
5475 #endif
5476 return (sizeof(rx_desc_819x_usb) + Status->RxDrvInfoSize
5477 + Status->RxBufShift);
5480 void rtl8192_rx_nomal(struct sk_buff* skb)
5482 rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
5483 struct net_device *dev=info->dev;
5484 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
5485 struct ieee80211_rx_stats stats = {
5486 .signal = 0,
5487 .noise = -98,
5488 .rate = 0,
5489 // .mac_time = jiffies,
5490 .freq = IEEE80211_24GHZ_BAND,
5492 u32 rx_pkt_len = 0;
5493 struct ieee80211_hdr_1addr *ieee80211_hdr = NULL;
5494 bool unicast_packet = false;
5495 #ifdef USB_RX_AGGREGATION_SUPPORT
5496 struct sk_buff *agg_skb = NULL;
5497 u32 TotalLength = 0;
5498 u32 TempDWord = 0;
5499 u32 PacketLength = 0;
5500 u32 PacketOccupiedLendth = 0;
5501 u8 TempByte = 0;
5502 u32 PacketShiftBytes = 0;
5503 rx_desc_819x_usb_aggr_subframe *RxDescr = NULL;
5504 u8 PaddingBytes = 0;
5505 //add just for testing
5506 u8 testing;
5508 #endif
5510 /* 20 is for ps-poll */
5511 if((skb->len >=(20 + sizeof(rx_desc_819x_usb))) && (skb->len < RX_URB_SIZE)) {
5512 #ifdef USB_RX_AGGREGATION_SUPPORT
5513 TempByte = *(skb->data + sizeof(rx_desc_819x_usb));
5514 #endif
5515 /* first packet should not contain Rx aggregation header */
5516 query_rxdesc_status(skb, &stats, false);
5517 /* TODO */
5518 /* hardware related info */
5519 #ifdef USB_RX_AGGREGATION_SUPPORT
5520 if (TempByte & BIT0) {
5521 agg_skb = skb;
5522 //TotalLength = agg_skb->len - 4; /*sCrcLng*/
5523 TotalLength = stats.Length - 4; /*sCrcLng*/
5524 //RT_TRACE(COMP_RECV, "%s:first aggregated packet!Length=%d\n",__FUNCTION__,TotalLength);
5525 /* though the head pointer has passed this position */
5526 TempDWord = *(u32 *)(agg_skb->data - 4);
5527 PacketLength = (u16)(TempDWord & 0x3FFF); /*sCrcLng*/
5528 skb = dev_alloc_skb(PacketLength);
5529 memcpy(skb_put(skb,PacketLength),agg_skb->data,PacketLength);
5530 PacketShiftBytes = GetRxPacketShiftBytes819xUsb(&stats, false);
5532 #endif
5533 /* Process the MPDU recevied */
5534 skb_trim(skb, skb->len - 4/*sCrcLng*/);
5536 rx_pkt_len = skb->len;
5537 ieee80211_hdr = (struct ieee80211_hdr_1addr *)skb->data;
5538 unicast_packet = false;
5539 if(is_broadcast_ether_addr(ieee80211_hdr->addr1)) {
5540 //TODO
5541 }else if(is_multicast_ether_addr(ieee80211_hdr->addr1)){
5542 //TODO
5543 }else {
5544 /* unicast packet */
5545 unicast_packet = true;
5548 if(!ieee80211_rx(priv->ieee80211,skb, &stats)) {
5549 dev_kfree_skb_any(skb);
5550 } else {
5551 priv->stats.rxoktotal++;
5552 if(unicast_packet) {
5553 priv->stats.rxbytesunicast += rx_pkt_len;
5556 #ifdef USB_RX_AGGREGATION_SUPPORT
5557 testing = 1;
5558 // (PipeIndex == 0) && (TempByte & BIT0) => TotalLength > 0.
5559 if (TotalLength > 0) {
5560 PacketOccupiedLendth = PacketLength + (PacketShiftBytes + 8);
5561 if ((PacketOccupiedLendth & 0xFF) != 0)
5562 PacketOccupiedLendth = (PacketOccupiedLendth & 0xFFFFFF00) + 256;
5563 PacketOccupiedLendth -= 8;
5564 TempDWord = PacketOccupiedLendth - PacketShiftBytes; /*- PacketLength */
5565 if (agg_skb->len > TempDWord)
5566 skb_pull(agg_skb, TempDWord);
5567 else
5568 agg_skb->len = 0;
5570 while (agg_skb->len>=GetRxPacketShiftBytes819xUsb(&stats, true)) {
5571 u8 tmpCRC = 0, tmpICV = 0;
5572 //RT_TRACE(COMP_RECV,"%s:aggred pkt,total_len = %d\n",__FUNCTION__,agg_skb->len);
5573 RxDescr = (rx_desc_819x_usb_aggr_subframe *)(agg_skb->data);
5574 tmpCRC = RxDescr->CRC32;
5575 tmpICV = RxDescr->ICV;
5576 memcpy(agg_skb->data, &agg_skb->data[44], 2);
5577 RxDescr->CRC32 = tmpCRC;
5578 RxDescr->ICV = tmpICV;
5580 memset(&stats, 0, sizeof(struct ieee80211_rx_stats));
5581 stats.signal = 0;
5582 stats.noise = -98;
5583 stats.rate = 0;
5584 stats.freq = IEEE80211_24GHZ_BAND;
5585 query_rxdesc_status(agg_skb, &stats, true);
5586 PacketLength = stats.Length;
5588 if(PacketLength > agg_skb->len) {
5589 break;
5591 /* Process the MPDU recevied */
5592 skb = dev_alloc_skb(PacketLength);
5593 memcpy(skb_put(skb,PacketLength),agg_skb->data, PacketLength);
5594 skb_trim(skb, skb->len - 4/*sCrcLng*/);
5596 rx_pkt_len = skb->len;
5597 ieee80211_hdr = (struct ieee80211_hdr_1addr *)skb->data;
5598 unicast_packet = false;
5599 if(is_broadcast_ether_addr(ieee80211_hdr->addr1)) {
5600 //TODO
5601 }else if(is_multicast_ether_addr(ieee80211_hdr->addr1)){
5602 //TODO
5603 }else {
5604 /* unicast packet */
5605 unicast_packet = true;
5607 if(!ieee80211_rx(priv->ieee80211,skb, &stats)) {
5608 dev_kfree_skb_any(skb);
5609 } else {
5610 priv->stats.rxoktotal++;
5611 if(unicast_packet) {
5612 priv->stats.rxbytesunicast += rx_pkt_len;
5615 /* should trim the packet which has been copied to target skb */
5616 skb_pull(agg_skb, PacketLength);
5617 PacketShiftBytes = GetRxPacketShiftBytes819xUsb(&stats, true);
5618 PacketOccupiedLendth = PacketLength + PacketShiftBytes;
5619 if ((PacketOccupiedLendth & 0xFF) != 0) {
5620 PaddingBytes = 256 - (PacketOccupiedLendth & 0xFF);
5621 if (agg_skb->len > PaddingBytes)
5622 skb_pull(agg_skb, PaddingBytes);
5623 else
5624 agg_skb->len = 0;
5627 dev_kfree_skb(agg_skb);
5629 #endif
5630 } else {
5631 priv->stats.rxurberr++;
5632 printk("actual_length:%d\n", skb->len);
5633 dev_kfree_skb_any(skb);
5638 void
5639 rtl819xusb_process_received_packet(
5640 struct net_device *dev,
5641 struct ieee80211_rx_stats *pstats
5644 // bool bfreerfd=false, bqueued=false;
5645 u8* frame;
5646 u16 frame_len=0;
5647 struct r8192_priv *priv = ieee80211_priv(dev);
5648 // u8 index = 0;
5649 // u8 TID = 0;
5650 //u16 seqnum = 0;
5651 //PRX_TS_RECORD pts = NULL;
5653 // Get shifted bytes of Starting address of 802.11 header. 2006.09.28, by Emily
5654 //porting by amy 080508
5655 pstats->virtual_address += get_rxpacket_shiftbytes_819xusb(pstats);
5656 frame = pstats->virtual_address;
5657 frame_len = pstats->packetlength;
5658 #ifdef TODO // by amy about HCT
5659 if(!Adapter->bInHctTest)
5660 CountRxErrStatistics(Adapter, pRfd);
5661 #endif
5663 #ifdef ENABLE_PS //by amy for adding ps function in future
5664 RT_RF_POWER_STATE rtState;
5665 // When RF is off, we should not count the packet for hw/sw synchronize
5666 // reason, ie. there may be a duration while sw switch is changed and hw
5667 // switch is being changed. 2006.12.04, by shien chang.
5668 Adapter->HalFunc.GetHwRegHandler(Adapter, HW_VAR_RF_STATE, (u8* )(&rtState));
5669 if (rtState == eRfOff)
5671 return;
5673 #endif
5674 priv->stats.rxframgment++;
5677 #ifdef TODO
5678 RmMonitorSignalStrength(Adapter, pRfd);
5679 #endif
5680 /* 2007/01/16 MH Add RX command packet handle here. */
5681 /* 2007/03/01 MH We have to release RFD and return if rx pkt is cmd pkt. */
5682 if (rtl819xusb_rx_command_packet(dev, pstats))
5684 return;
5687 #ifdef SW_CRC_CHECK
5688 SwCrcCheck();
5689 #endif
5694 void query_rx_cmdpkt_desc_status(struct sk_buff *skb, struct ieee80211_rx_stats *stats)
5696 // rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
5697 // struct net_device *dev=info->dev;
5698 // struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
5699 rx_desc_819x_usb *desc = (rx_desc_819x_usb *)skb->data;
5700 // rx_drvinfo_819x_usb *driver_info;
5703 //Get Rx Descriptor Information
5705 stats->virtual_address = (u8*)skb->data;
5706 stats->Length = desc->Length;
5707 stats->RxDrvInfoSize = 0;
5708 stats->RxBufShift = 0;
5709 stats->packetlength = stats->Length-scrclng;
5710 stats->fraglength = stats->packetlength;
5711 stats->fragoffset = 0;
5712 stats->ntotalfrag = 1;
5716 void rtl8192_rx_cmd(struct sk_buff *skb)
5718 struct rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
5719 struct net_device *dev = info->dev;
5720 //int ret;
5721 // struct urb *rx_urb = info->urb;
5722 /* TODO */
5723 struct ieee80211_rx_stats stats = {
5724 .signal = 0,
5725 .noise = -98,
5726 .rate = 0,
5727 // .mac_time = jiffies,
5728 .freq = IEEE80211_24GHZ_BAND,
5731 if((skb->len >=(20 + sizeof(rx_desc_819x_usb))) && (skb->len < RX_URB_SIZE))
5734 query_rx_cmdpkt_desc_status(skb,&stats);
5735 // this is to be done by amy 080508 prfd->queue_id = 1;
5739 // Process the command packet received.
5742 rtl819xusb_process_received_packet(dev,&stats);
5744 dev_kfree_skb_any(skb);
5746 else
5752 void rtl8192_irq_rx_tasklet(struct r8192_priv *priv)
5754 struct sk_buff *skb;
5755 struct rtl8192_rx_info *info;
5757 while (NULL != (skb = skb_dequeue(&priv->skb_queue))) {
5758 info = (struct rtl8192_rx_info *)skb->cb;
5759 switch (info->out_pipe) {
5760 /* Nomal packet pipe */
5761 case 3:
5762 //RT_TRACE(COMP_RECV, "normal in-pipe index(%d)\n",info->out_pipe);
5763 priv->IrpPendingCount--;
5764 rtl8192_rx_nomal(skb);
5765 break;
5767 /* Command packet pipe */
5768 case 9:
5769 RT_TRACE(COMP_RECV, "command in-pipe index(%d)\n",\
5770 info->out_pipe);
5772 rtl8192_rx_cmd(skb);
5773 break;
5775 default: /* should never get here! */
5776 RT_TRACE(COMP_ERR, "Unknown in-pipe index(%d)\n",\
5777 info->out_pipe);
5778 dev_kfree_skb(skb);
5779 break;
5785 static const struct net_device_ops rtl8192_netdev_ops = {
5786 .ndo_open = rtl8192_open,
5787 .ndo_stop = rtl8192_close,
5788 .ndo_get_stats = rtl8192_stats,
5789 .ndo_tx_timeout = tx_timeout,
5790 .ndo_do_ioctl = rtl8192_ioctl,
5791 .ndo_set_multicast_list = r8192_set_multicast,
5792 .ndo_set_mac_address = r8192_set_mac_adr,
5793 .ndo_validate_addr = eth_validate_addr,
5794 .ndo_change_mtu = eth_change_mtu,
5795 .ndo_start_xmit = ieee80211_xmit,
5799 /****************************************************************************
5800 ---------------------------- USB_STUFF---------------------------
5801 *****************************************************************************/
5803 static int __devinit rtl8192_usb_probe(struct usb_interface *intf,
5804 const struct usb_device_id *id)
5806 // unsigned long ioaddr = 0;
5807 struct net_device *dev = NULL;
5808 struct r8192_priv *priv= NULL;
5809 struct usb_device *udev = interface_to_usbdev(intf);
5810 RT_TRACE(COMP_INIT, "Oops: i'm coming\n");
5812 dev = alloc_ieee80211(sizeof(struct r8192_priv));
5815 usb_set_intfdata(intf, dev);
5816 SET_NETDEV_DEV(dev, &intf->dev);
5817 priv = ieee80211_priv(dev);
5818 priv->ieee80211 = netdev_priv(dev);
5819 priv->udev=udev;
5821 dev->netdev_ops = &rtl8192_netdev_ops;
5823 //DMESG("Oops: i'm coming\n");
5824 #if WIRELESS_EXT >= 12
5825 #if WIRELESS_EXT < 17
5826 dev->get_wireless_stats = r8192_get_wireless_stats;
5827 #endif
5828 dev->wireless_handlers = (struct iw_handler_def *) &r8192_wx_handlers_def;
5829 #endif
5830 dev->type=ARPHRD_ETHER;
5832 dev->watchdog_timeo = HZ*3; //modified by john, 0805
5834 if (dev_alloc_name(dev, ifname) < 0){
5835 RT_TRACE(COMP_INIT, "Oops: devname already taken! Trying wlan%%d...\n");
5836 ifname = "wlan%d";
5837 dev_alloc_name(dev, ifname);
5840 RT_TRACE(COMP_INIT, "Driver probe completed1\n");
5841 if(rtl8192_init(dev)!=0){
5842 RT_TRACE(COMP_ERR, "Initialization failed");
5843 goto fail;
5845 netif_carrier_off(dev);
5846 netif_stop_queue(dev);
5848 register_netdev(dev);
5849 RT_TRACE(COMP_INIT, "dev name=======> %s\n",dev->name);
5850 rtl8192_proc_init_one(dev);
5853 RT_TRACE(COMP_INIT, "Driver probe completed\n");
5854 return 0;
5857 fail:
5858 free_ieee80211(dev);
5860 RT_TRACE(COMP_ERR, "wlan driver load failed\n");
5861 return -ENODEV;
5865 //detach all the work and timer structure declared or inititialize in r8192U_init function.
5866 void rtl8192_cancel_deferred_work(struct r8192_priv* priv)
5869 cancel_work_sync(&priv->reset_wq);
5870 cancel_delayed_work(&priv->watch_dog_wq);
5871 cancel_delayed_work(&priv->update_beacon_wq);
5872 cancel_work_sync(&priv->qos_activate);
5873 //cancel_work_sync(&priv->SetBWModeWorkItem);
5874 //cancel_work_sync(&priv->SwChnlWorkItem);
5879 static void __devexit rtl8192_usb_disconnect(struct usb_interface *intf)
5881 struct net_device *dev = usb_get_intfdata(intf);
5883 struct r8192_priv *priv = ieee80211_priv(dev);
5884 if(dev){
5886 unregister_netdev(dev);
5888 RT_TRACE(COMP_DOWN, "=============>wlan driver to be removed\n");
5889 rtl8192_proc_remove_one(dev);
5891 rtl8192_down(dev);
5892 if (priv->pFirmware)
5894 kfree(priv->pFirmware);
5895 priv->pFirmware = NULL;
5897 // priv->rf_close(dev);
5898 // rtl8192_SetRFPowerState(dev, eRfOff);
5899 rtl8192_usb_deleteendpoints(dev);
5900 destroy_workqueue(priv->priv_wq);
5901 //rtl8192_irq_disable(dev);
5902 //rtl8192_reset(dev);
5903 mdelay(10);
5906 free_ieee80211(dev);
5907 RT_TRACE(COMP_DOWN, "wlan driver removed\n");
5910 /* fun with the built-in ieee80211 stack... */
5911 extern int ieee80211_debug_init(void);
5912 extern void ieee80211_debug_exit(void);
5913 extern int ieee80211_crypto_init(void);
5914 extern void ieee80211_crypto_deinit(void);
5915 extern int ieee80211_crypto_tkip_init(void);
5916 extern void ieee80211_crypto_tkip_exit(void);
5917 extern int ieee80211_crypto_ccmp_init(void);
5918 extern void ieee80211_crypto_ccmp_exit(void);
5919 extern int ieee80211_crypto_wep_init(void);
5920 extern void ieee80211_crypto_wep_exit(void);
5922 static int __init rtl8192_usb_module_init(void)
5924 int ret;
5926 #ifdef CONFIG_IEEE80211_DEBUG
5927 ret = ieee80211_debug_init();
5928 if (ret) {
5929 printk(KERN_ERR "ieee80211_debug_init() failed %d\n", ret);
5930 return ret;
5932 #endif
5933 ret = ieee80211_crypto_init();
5934 if (ret) {
5935 printk(KERN_ERR "ieee80211_crypto_init() failed %d\n", ret);
5936 return ret;
5939 ret = ieee80211_crypto_tkip_init();
5940 if (ret) {
5941 printk(KERN_ERR "ieee80211_crypto_tkip_init() failed %d\n",
5942 ret);
5943 return ret;
5946 ret = ieee80211_crypto_ccmp_init();
5947 if (ret) {
5948 printk(KERN_ERR "ieee80211_crypto_ccmp_init() failed %d\n",
5949 ret);
5950 return ret;
5953 ret = ieee80211_crypto_wep_init();
5954 if (ret) {
5955 printk(KERN_ERR "ieee80211_crypto_wep_init() failed %d\n", ret);
5956 return ret;
5959 printk(KERN_INFO "\nLinux kernel driver for RTL8192 based WLAN cards\n");
5960 printk(KERN_INFO "Copyright (c) 2007-2008, Realsil Wlan\n");
5961 RT_TRACE(COMP_INIT, "Initializing module");
5962 RT_TRACE(COMP_INIT, "Wireless extensions version %d", WIRELESS_EXT);
5963 rtl8192_proc_module_init();
5964 return usb_register(&rtl8192_usb_driver);
5968 static void __exit rtl8192_usb_module_exit(void)
5970 usb_deregister(&rtl8192_usb_driver);
5972 RT_TRACE(COMP_DOWN, "Exiting");
5973 // rtl8192_proc_module_remove();
5977 void rtl8192_try_wake_queue(struct net_device *dev, int pri)
5979 unsigned long flags;
5980 short enough_desc;
5981 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
5983 spin_lock_irqsave(&priv->tx_lock,flags);
5984 enough_desc = check_nic_enough_desc(dev,pri);
5985 spin_unlock_irqrestore(&priv->tx_lock,flags);
5987 if(enough_desc)
5988 ieee80211_wake_queue(priv->ieee80211);
5991 void EnableHWSecurityConfig8192(struct net_device *dev)
5993 u8 SECR_value = 0x0;
5994 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
5995 struct ieee80211_device* ieee = priv->ieee80211;
5996 SECR_value = SCR_TxEncEnable | SCR_RxDecEnable;
5997 if (((KEY_TYPE_WEP40 == ieee->pairwise_key_type) || (KEY_TYPE_WEP104 == ieee->pairwise_key_type)) && (priv->ieee80211->auth_mode != 2))
5999 SECR_value |= SCR_RxUseDK;
6000 SECR_value |= SCR_TxUseDK;
6002 else if ((ieee->iw_mode == IW_MODE_ADHOC) && (ieee->pairwise_key_type & (KEY_TYPE_CCMP | KEY_TYPE_TKIP)))
6004 SECR_value |= SCR_RxUseDK;
6005 SECR_value |= SCR_TxUseDK;
6007 //add HWSec active enable here.
6008 //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
6010 ieee->hwsec_active = 1;
6012 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
6014 ieee->hwsec_active = 0;
6015 SECR_value &= ~SCR_RxDecEnable;
6017 RT_TRACE(COMP_SEC,"%s:, hwsec:%d, pairwise_key:%d, SECR_value:%x\n", __FUNCTION__, \
6018 ieee->hwsec_active, ieee->pairwise_key_type, SECR_value);
6020 write_nic_byte(dev, SECR, SECR_value);//SECR_value | SCR_UseDK );
6025 void setKey( struct net_device *dev,
6026 u8 EntryNo,
6027 u8 KeyIndex,
6028 u16 KeyType,
6029 u8 *MacAddr,
6030 u8 DefaultKey,
6031 u32 *KeyContent )
6033 u32 TargetCommand = 0;
6034 u32 TargetContent = 0;
6035 u16 usConfig = 0;
6036 u8 i;
6037 if (EntryNo >= TOTAL_CAM_ENTRY)
6038 RT_TRACE(COMP_ERR, "cam entry exceeds in setKey()\n");
6040 RT_TRACE(COMP_SEC, "====>to setKey(), dev:%p, EntryNo:%d, KeyIndex:%d, KeyType:%d, MacAddr"MAC_FMT"\n", dev,EntryNo, KeyIndex, KeyType, MAC_ARG(MacAddr));
6042 if (DefaultKey)
6043 usConfig |= BIT15 | (KeyType<<2);
6044 else
6045 usConfig |= BIT15 | (KeyType<<2) | KeyIndex;
6046 // usConfig |= BIT15 | (KeyType<<2) | (DefaultKey<<5) | KeyIndex;
6049 for(i=0 ; i<CAM_CONTENT_COUNT; i++){
6050 TargetCommand = i+CAM_CONTENT_COUNT*EntryNo;
6051 TargetCommand |= BIT31|BIT16;
6053 if(i==0){//MAC|Config
6054 TargetContent = (u32)(*(MacAddr+0)) << 16|
6055 (u32)(*(MacAddr+1)) << 24|
6056 (u32)usConfig;
6058 write_nic_dword(dev, WCAMI, TargetContent);
6059 write_nic_dword(dev, RWCAM, TargetCommand);
6060 // printk("setkey cam =%8x\n", read_cam(dev, i+6*EntryNo));
6062 else if(i==1){//MAC
6063 TargetContent = (u32)(*(MacAddr+2)) |
6064 (u32)(*(MacAddr+3)) << 8|
6065 (u32)(*(MacAddr+4)) << 16|
6066 (u32)(*(MacAddr+5)) << 24;
6067 write_nic_dword(dev, WCAMI, TargetContent);
6068 write_nic_dword(dev, RWCAM, TargetCommand);
6070 else {
6071 //Key Material
6072 if(KeyContent !=NULL){
6073 write_nic_dword(dev, WCAMI, (u32)(*(KeyContent+i-2)) );
6074 write_nic_dword(dev, RWCAM, TargetCommand);
6081 /***************************************************************************
6082 ------------------- module init / exit stubs ----------------
6083 ****************************************************************************/
6084 module_init(rtl8192_usb_module_init);
6085 module_exit(rtl8192_usb_module_exit);