drivers/staging: Remove unnecessary semicolons
[linux-2.6.git] / drivers / staging / rtl8192u / r8192U_core.c
blobcbfe1341d85657eaa08f21ed7e711d7c72d70b4f
1 /******************************************************************************
2 * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
3 * Linux device driver for RTL8192U
5 * Based on the r8187 driver, which is:
6 * Copyright 2004-2005 Andrea Merello <andreamrl@tiscali.it>, et al.
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of version 2 of the GNU General Public License as
9 * published by the Free Software Foundation.
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
16 * You should have received a copy of the GNU General Public License along with
17 * this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
20 * The full GNU General Public License is included in this distribution in the
21 * file called LICENSE.
23 * Contact Information:
24 * Jerry chuang <wlanfae@realtek.com>
27 #ifndef CONFIG_FORCE_HARD_FLOAT
28 double __floatsidf (int i) { return i; }
29 unsigned int __fixunsdfsi (double d) { return d; }
30 double __adddf3(double a, double b) { return a+b; }
31 double __addsf3(float a, float b) { return a+b; }
32 double __subdf3(double a, double b) { return a-b; }
33 double __extendsfdf2(float a) {return a;}
34 #endif
36 #undef LOOP_TEST
37 #undef DUMP_RX
38 #undef DUMP_TX
39 #undef DEBUG_TX_DESC2
40 #undef RX_DONT_PASS_UL
41 #undef DEBUG_EPROM
42 #undef DEBUG_RX_VERBOSE
43 #undef DUMMY_RX
44 #undef DEBUG_ZERO_RX
45 #undef DEBUG_RX_SKB
46 #undef DEBUG_TX_FRAG
47 #undef DEBUG_RX_FRAG
48 #undef DEBUG_TX_FILLDESC
49 #undef DEBUG_TX
50 #undef DEBUG_IRQ
51 #undef DEBUG_RX
52 #undef DEBUG_RXALLOC
53 #undef DEBUG_REGISTERS
54 #undef DEBUG_RING
55 #undef DEBUG_IRQ_TASKLET
56 #undef DEBUG_TX_ALLOC
57 #undef DEBUG_TX_DESC
59 #define CONFIG_RTL8192_IO_MAP
61 #include <asm/uaccess.h>
62 #include "r8192U_hw.h"
63 #include "r8192U.h"
64 #include "r8190_rtl8256.h" /* RTL8225 Radio frontend */
65 #include "r8180_93cx6.h" /* Card EEPROM */
66 #include "r8192U_wx.h"
67 #include "r819xU_phy.h" //added by WB 4.30.2008
68 #include "r819xU_phyreg.h"
69 #include "r819xU_cmdpkt.h"
70 #include "r8192U_dm.h"
71 //#include "r8192xU_phyreg.h"
72 #include <linux/usb.h>
73 #include <linux/slab.h>
74 // FIXME: check if 2.6.7 is ok
76 #ifdef CONFIG_RTL8192_PM
77 #include "r8192_pm.h"
78 #endif
80 #ifdef ENABLE_DOT11D
81 #include "dot11d.h"
82 #endif
83 //set here to open your trace code. //WB
84 u32 rt_global_debug_component = \
85 // COMP_INIT |
86 // COMP_DBG |
87 // COMP_EPROM |
88 // COMP_PHY |
89 // COMP_RF |
90 // COMP_FIRMWARE |
91 // COMP_CH |
92 // COMP_POWER_TRACKING |
93 // COMP_RATE |
94 // COMP_TXAGC |
95 // COMP_TRACE |
96 COMP_DOWN |
97 // COMP_RECV |
98 // COMP_SWBW |
99 COMP_SEC |
100 // COMP_RESET |
101 // COMP_SEND |
102 // COMP_EVENTS |
103 COMP_ERR ; //always open err flags on
105 #define TOTAL_CAM_ENTRY 32
106 #define CAM_CONTENT_COUNT 8
108 static const struct usb_device_id rtl8192_usb_id_tbl[] = {
109 /* Realtek */
110 {USB_DEVICE(0x0bda, 0x8192)},
111 {USB_DEVICE(0x0bda, 0x8709)},
112 /* Corega */
113 {USB_DEVICE(0x07aa, 0x0043)},
114 /* Belkin */
115 {USB_DEVICE(0x050d, 0x805E)},
116 /* Sitecom */
117 {USB_DEVICE(0x0df6, 0x0031)},
118 /* EnGenius */
119 {USB_DEVICE(0x1740, 0x9201)},
120 /* Dlink */
121 {USB_DEVICE(0x2001, 0x3301)},
122 /* Zinwell */
123 {USB_DEVICE(0x5a57, 0x0290)},
124 /* LG */
125 {USB_DEVICE(0x043e, 0x7a01)},
129 MODULE_LICENSE("GPL");
130 MODULE_VERSION("V 1.1");
131 MODULE_DEVICE_TABLE(usb, rtl8192_usb_id_tbl);
132 MODULE_DESCRIPTION("Linux driver for Realtek RTL8192 USB WiFi cards");
134 static char* ifname = "wlan%d";
135 static int hwwep = 1; //default use hw. set 0 to use software security
136 static int channels = 0x3fff;
140 module_param(ifname, charp, S_IRUGO|S_IWUSR );
141 //module_param(hwseqnum,int, S_IRUGO|S_IWUSR);
142 module_param(hwwep,int, S_IRUGO|S_IWUSR);
143 module_param(channels,int, S_IRUGO|S_IWUSR);
145 MODULE_PARM_DESC(ifname," Net interface name, wlan%d=default");
146 //MODULE_PARM_DESC(hwseqnum," Try to use hardware 802.11 header sequence numbers. Zero=default");
147 MODULE_PARM_DESC(hwwep," Try to use hardware security support. ");
148 MODULE_PARM_DESC(channels," Channel bitmask for specific locales. NYI");
150 static int __devinit rtl8192_usb_probe(struct usb_interface *intf,
151 const struct usb_device_id *id);
152 static void __devexit rtl8192_usb_disconnect(struct usb_interface *intf);
155 static struct usb_driver rtl8192_usb_driver = {
156 .name = RTL819xU_MODULE_NAME, /* Driver name */
157 .id_table = rtl8192_usb_id_tbl, /* PCI_ID table */
158 .probe = rtl8192_usb_probe, /* probe fn */
159 .disconnect = rtl8192_usb_disconnect, /* remove fn */
160 #ifdef CONFIG_RTL8192_PM
161 .suspend = rtl8192_suspend, /* PM suspend fn */
162 .resume = rtl8192_resume, /* PM resume fn */
163 #else
164 .suspend = NULL, /* PM suspend fn */
165 .resume = NULL, /* PM resume fn */
166 #endif
169 #ifdef ENABLE_DOT11D
171 typedef struct _CHANNEL_LIST
173 u8 Channel[32];
174 u8 Len;
175 }CHANNEL_LIST, *PCHANNEL_LIST;
177 static CHANNEL_LIST ChannelPlan[] = {
178 {{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
179 {{1,2,3,4,5,6,7,8,9,10,11},11}, //IC
180 {{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48,52,56,60,64},21}, //ETSI
181 {{1,2,3,4,5,6,7,8,9,10,11,12,13},13}, //Spain. Change to ETSI.
182 {{1,2,3,4,5,6,7,8,9,10,11,12,13},13}, //France. Change to ETSI.
183 {{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
184 {{1,2,3,4,5,6,7,8,9,10,11,12,13,14,36,40,44,48,52,56,60,64},22},//MKK1
185 {{1,2,3,4,5,6,7,8,9,10,11,12,13},13}, //Israel.
186 {{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
187 {{1,2,3,4,5,6,7,8,9,10,11,12,13,14,36,40,44,48,52,56,60,64}, 22}, //MIC
188 {{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
191 static void rtl819x_set_channel_map(u8 channel_plan, struct r8192_priv* priv)
193 int i, max_chan=-1, min_chan=-1;
194 struct ieee80211_device* ieee = priv->ieee80211;
195 switch (channel_plan)
197 case COUNTRY_CODE_FCC:
198 case COUNTRY_CODE_IC:
199 case COUNTRY_CODE_ETSI:
200 case COUNTRY_CODE_SPAIN:
201 case COUNTRY_CODE_FRANCE:
202 case COUNTRY_CODE_MKK:
203 case COUNTRY_CODE_MKK1:
204 case COUNTRY_CODE_ISRAEL:
205 case COUNTRY_CODE_TELEC:
206 case COUNTRY_CODE_MIC:
208 Dot11d_Init(ieee);
209 ieee->bGlobalDomain = false;
210 //acturally 8225 & 8256 rf chip only support B,G,24N mode
211 if ((priv->rf_chip == RF_8225) || (priv->rf_chip == RF_8256))
213 min_chan = 1;
214 max_chan = 14;
216 else
218 RT_TRACE(COMP_ERR, "unknown rf chip, can't set channel map in function:%s()\n", __FUNCTION__);
220 if (ChannelPlan[channel_plan].Len != 0){
221 // Clear old channel map
222 memset(GET_DOT11D_INFO(ieee)->channel_map, 0, sizeof(GET_DOT11D_INFO(ieee)->channel_map));
223 // Set new channel map
224 for (i=0;i<ChannelPlan[channel_plan].Len;i++)
226 if (ChannelPlan[channel_plan].Channel[i] < min_chan || ChannelPlan[channel_plan].Channel[i] > max_chan)
227 break;
228 GET_DOT11D_INFO(ieee)->channel_map[ChannelPlan[channel_plan].Channel[i]] = 1;
231 break;
233 case COUNTRY_CODE_GLOBAL_DOMAIN:
235 GET_DOT11D_INFO(ieee)->bEnabled = 0;//this flag enabled to follow 11d country IE setting, otherwise, it shall follow global domain settings.
236 Dot11d_Reset(ieee);
237 ieee->bGlobalDomain = true;
238 break;
240 default:
241 break;
243 return;
245 #endif
247 #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 )
249 #define rx_hal_is_cck_rate(_pdrvinfo)\
250 (_pdrvinfo->RxRate == DESC90_RATE1M ||\
251 _pdrvinfo->RxRate == DESC90_RATE2M ||\
252 _pdrvinfo->RxRate == DESC90_RATE5_5M ||\
253 _pdrvinfo->RxRate == DESC90_RATE11M) &&\
254 !_pdrvinfo->RxHT\
257 void CamResetAllEntry(struct net_device *dev)
259 u32 ulcommand = 0;
260 //2004/02/11 In static WEP, OID_ADD_KEY or OID_ADD_WEP are set before STA associate to AP.
261 // However, ResetKey is called on OID_802_11_INFRASTRUCTURE_MODE and MlmeAssociateRequest
262 // In this condition, Cam can not be reset because upper layer will not set this static key again.
263 //if(Adapter->EncAlgorithm == WEP_Encryption)
264 // return;
265 //debug
266 //DbgPrint("========================================\n");
267 //DbgPrint(" Call ResetAllEntry \n");
268 //DbgPrint("========================================\n\n");
269 ulcommand |= BIT31|BIT30;
270 write_nic_dword(dev, RWCAM, ulcommand);
275 void write_cam(struct net_device *dev, u8 addr, u32 data)
277 write_nic_dword(dev, WCAMI, data);
278 write_nic_dword(dev, RWCAM, BIT31|BIT16|(addr&0xff) );
281 u32 read_cam(struct net_device *dev, u8 addr)
283 write_nic_dword(dev, RWCAM, 0x80000000|(addr&0xff) );
284 return read_nic_dword(dev, 0xa8);
287 void write_nic_byte_E(struct net_device *dev, int indx, u8 data)
289 int status;
290 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
291 struct usb_device *udev = priv->udev;
293 status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
294 RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
295 indx|0xfe00, 0, &data, 1, HZ / 2);
297 if (status < 0)
299 printk("write_nic_byte_E TimeOut! status:%d\n", status);
303 u8 read_nic_byte_E(struct net_device *dev, int indx)
305 int status;
306 u8 data;
307 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
308 struct usb_device *udev = priv->udev;
310 status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
311 RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
312 indx|0xfe00, 0, &data, 1, HZ / 2);
314 if (status < 0)
316 printk("read_nic_byte_E TimeOut! status:%d\n", status);
319 return data;
321 //as 92U has extend page from 4 to 16, so modify functions below.
322 void write_nic_byte(struct net_device *dev, int indx, u8 data)
324 int status;
326 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
327 struct usb_device *udev = priv->udev;
329 status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
330 RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
331 (indx&0xff)|0xff00, (indx>>8)&0x0f, &data, 1, HZ / 2);
333 if (status < 0)
335 printk("write_nic_byte TimeOut! status:%d\n", status);
342 void write_nic_word(struct net_device *dev, int indx, u16 data)
345 int status;
347 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
348 struct usb_device *udev = priv->udev;
350 status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
351 RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
352 (indx&0xff)|0xff00, (indx>>8)&0x0f, &data, 2, HZ / 2);
354 if (status < 0)
356 printk("write_nic_word TimeOut! status:%d\n", status);
362 void write_nic_dword(struct net_device *dev, int indx, u32 data)
365 int status;
367 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
368 struct usb_device *udev = priv->udev;
370 status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
371 RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
372 (indx&0xff)|0xff00, (indx>>8)&0x0f, &data, 4, HZ / 2);
375 if (status < 0)
377 printk("write_nic_dword TimeOut! status:%d\n", status);
384 u8 read_nic_byte(struct net_device *dev, int indx)
386 u8 data;
387 int status;
388 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
389 struct usb_device *udev = priv->udev;
391 status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
392 RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
393 (indx&0xff)|0xff00, (indx>>8)&0x0f, &data, 1, HZ / 2);
395 if (status < 0)
397 printk("read_nic_byte TimeOut! status:%d\n", status);
400 return data;
405 u16 read_nic_word(struct net_device *dev, int indx)
407 u16 data;
408 int status;
409 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
410 struct usb_device *udev = priv->udev;
412 status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
413 RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
414 (indx&0xff)|0xff00, (indx>>8)&0x0f,
415 &data, 2, HZ / 2);
417 if (status < 0)
418 printk("read_nic_word TimeOut! status:%d\n", status);
420 return data;
423 u16 read_nic_word_E(struct net_device *dev, int indx)
425 u16 data;
426 int status;
427 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
428 struct usb_device *udev = priv->udev;
430 status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
431 RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
432 indx|0xfe00, 0, &data, 2, HZ / 2);
434 if (status < 0)
435 printk("read_nic_word TimeOut! status:%d\n", status);
437 return data;
440 u32 read_nic_dword(struct net_device *dev, int indx)
442 u32 data;
443 int status;
444 /* int result; */
446 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
447 struct usb_device *udev = priv->udev;
449 status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
450 RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
451 (indx&0xff)|0xff00, (indx>>8)&0x0f,
452 &data, 4, HZ / 2);
453 /* if(0 != result) {
454 * printk(KERN_WARNING "read size of data = %d\, date = %d\n",
455 * result, data);
459 if (status < 0)
460 printk("read_nic_dword TimeOut! status:%d\n", status);
462 return data;
465 /* u8 read_phy_cck(struct net_device *dev, u8 adr); */
466 /* u8 read_phy_ofdm(struct net_device *dev, u8 adr); */
467 /* this might still called in what was the PHY rtl8185/rtl8192 common code
468 * plans are to possibilty turn it again in one common code...
470 inline void force_pci_posting(struct net_device *dev)
474 static struct net_device_stats *rtl8192_stats(struct net_device *dev);
475 void rtl8192_commit(struct net_device *dev);
476 /* void rtl8192_restart(struct net_device *dev); */
477 void rtl8192_restart(struct work_struct *work);
478 /* void rtl8192_rq_tx_ack(struct work_struct *work); */
479 void watch_dog_timer_callback(unsigned long data);
481 /****************************************************************************
482 * -----------------------------PROCFS STUFF-------------------------
483 *****************************************************************************
486 static struct proc_dir_entry *rtl8192_proc;
488 static int proc_get_stats_ap(char *page, char **start, off_t offset, int count,
489 int *eof, void *data)
491 struct net_device *dev = data;
492 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
493 struct ieee80211_device *ieee = priv->ieee80211;
494 struct ieee80211_network *target;
496 int len = 0;
498 list_for_each_entry(target, &ieee->network_list, list) {
500 len += snprintf(page + len, count - len, "%s ", target->ssid);
502 if (target->wpa_ie_len > 0 || target->rsn_ie_len > 0)
503 len += snprintf(page + len, count - len, "WPA\n");
504 else
505 len += snprintf(page + len, count - len, "non_WPA\n");
508 *eof = 1;
509 return len;
512 static int proc_get_registers(char *page, char **start,
513 off_t offset, int count,
514 int *eof, void *data)
516 struct net_device *dev = data;
517 // struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
519 int len = 0;
520 int i,n;
522 int max=0xff;
524 /* This dump the current register page */
525 len += snprintf(page + len, count - len,
526 "\n####################page 0##################\n ");
528 for(n=0;n<=max;)
530 //printk( "\nD: %2x> ", n);
531 len += snprintf(page + len, count - len,
532 "\nD: %2x > ",n);
534 for(i=0;i<16 && n<=max;i++,n++)
535 len += snprintf(page + len, count - len,
536 "%2x ",read_nic_byte(dev,0x000|n));
538 // printk("%2x ",read_nic_byte(dev,n));
540 len += snprintf(page + len, count - len,
541 "\n####################page 1##################\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,0x100|n));
552 // printk("%2x ",read_nic_byte(dev,n));
554 len += snprintf(page + len, count - len,
555 "\n####################page 3##################\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,0x300|n));
566 // printk("%2x ",read_nic_byte(dev,n));
570 len += snprintf(page + len, count - len,"\n");
571 *eof = 1;
572 return len;
580 static int proc_get_stats_tx(char *page, char **start,
581 off_t offset, int count,
582 int *eof, void *data)
584 struct net_device *dev = data;
585 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
587 int len = 0;
589 len += snprintf(page + len, count - len,
590 "TX VI priority ok int: %lu\n"
591 "TX VI priority error int: %lu\n"
592 "TX VO priority ok int: %lu\n"
593 "TX VO priority error int: %lu\n"
594 "TX BE priority ok int: %lu\n"
595 "TX BE priority error int: %lu\n"
596 "TX BK priority ok int: %lu\n"
597 "TX BK priority error int: %lu\n"
598 "TX MANAGE priority ok int: %lu\n"
599 "TX MANAGE priority error int: %lu\n"
600 "TX BEACON priority ok int: %lu\n"
601 "TX BEACON priority error int: %lu\n"
602 // "TX high priority ok int: %lu\n"
603 // "TX high priority failed error int: %lu\n"
604 "TX queue resume: %lu\n"
605 "TX queue stopped?: %d\n"
606 "TX fifo overflow: %lu\n"
607 // "TX beacon: %lu\n"
608 "TX VI queue: %d\n"
609 "TX VO queue: %d\n"
610 "TX BE queue: %d\n"
611 "TX BK queue: %d\n"
612 // "TX HW queue: %d\n"
613 "TX VI dropped: %lu\n"
614 "TX VO dropped: %lu\n"
615 "TX BE dropped: %lu\n"
616 "TX BK dropped: %lu\n"
617 "TX total data packets %lu\n",
618 // "TX beacon aborted: %lu\n",
619 priv->stats.txviokint,
620 priv->stats.txvierr,
621 priv->stats.txvookint,
622 priv->stats.txvoerr,
623 priv->stats.txbeokint,
624 priv->stats.txbeerr,
625 priv->stats.txbkokint,
626 priv->stats.txbkerr,
627 priv->stats.txmanageokint,
628 priv->stats.txmanageerr,
629 priv->stats.txbeaconokint,
630 priv->stats.txbeaconerr,
631 // priv->stats.txhpokint,
632 // priv->stats.txhperr,
633 priv->stats.txresumed,
634 netif_queue_stopped(dev),
635 priv->stats.txoverflow,
636 // priv->stats.txbeacon,
637 atomic_read(&(priv->tx_pending[VI_PRIORITY])),
638 atomic_read(&(priv->tx_pending[VO_PRIORITY])),
639 atomic_read(&(priv->tx_pending[BE_PRIORITY])),
640 atomic_read(&(priv->tx_pending[BK_PRIORITY])),
641 // read_nic_byte(dev, TXFIFOCOUNT),
642 priv->stats.txvidrop,
643 priv->stats.txvodrop,
644 priv->stats.txbedrop,
645 priv->stats.txbkdrop,
646 priv->stats.txdatapkt
647 // priv->stats.txbeaconerr
650 *eof = 1;
651 return len;
656 static int proc_get_stats_rx(char *page, char **start,
657 off_t offset, int count,
658 int *eof, void *data)
660 struct net_device *dev = data;
661 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
663 int len = 0;
665 len += snprintf(page + len, count - len,
666 "RX packets: %lu\n"
667 "RX urb status error: %lu\n"
668 "RX invalid urb error: %lu\n",
669 priv->stats.rxoktotal,
670 priv->stats.rxstaterr,
671 priv->stats.rxurberr);
673 *eof = 1;
674 return len;
676 void rtl8192_proc_module_init(void)
678 RT_TRACE(COMP_INIT, "Initializing proc filesystem");
679 rtl8192_proc=create_proc_entry(RTL819xU_MODULE_NAME, S_IFDIR, init_net.proc_net);
683 void rtl8192_proc_module_remove(void)
685 remove_proc_entry(RTL819xU_MODULE_NAME, init_net.proc_net);
689 void rtl8192_proc_remove_one(struct net_device *dev)
691 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
694 if (priv->dir_dev) {
695 // remove_proc_entry("stats-hw", priv->dir_dev);
696 remove_proc_entry("stats-tx", priv->dir_dev);
697 remove_proc_entry("stats-rx", priv->dir_dev);
698 // remove_proc_entry("stats-ieee", priv->dir_dev);
699 remove_proc_entry("stats-ap", priv->dir_dev);
700 remove_proc_entry("registers", priv->dir_dev);
701 // remove_proc_entry("cck-registers",priv->dir_dev);
702 // remove_proc_entry("ofdm-registers",priv->dir_dev);
703 //remove_proc_entry(dev->name, rtl8192_proc);
704 remove_proc_entry("wlan0", rtl8192_proc);
705 priv->dir_dev = NULL;
710 void rtl8192_proc_init_one(struct net_device *dev)
712 struct proc_dir_entry *e;
713 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
714 priv->dir_dev = create_proc_entry(dev->name,
715 S_IFDIR | S_IRUGO | S_IXUGO,
716 rtl8192_proc);
717 if (!priv->dir_dev) {
718 RT_TRACE(COMP_ERR, "Unable to initialize /proc/net/rtl8192/%s\n",
719 dev->name);
720 return;
722 e = create_proc_read_entry("stats-rx", S_IFREG | S_IRUGO,
723 priv->dir_dev, proc_get_stats_rx, dev);
725 if (!e) {
726 RT_TRACE(COMP_ERR,"Unable to initialize "
727 "/proc/net/rtl8192/%s/stats-rx\n",
728 dev->name);
732 e = create_proc_read_entry("stats-tx", S_IFREG | S_IRUGO,
733 priv->dir_dev, proc_get_stats_tx, dev);
735 if (!e) {
736 RT_TRACE(COMP_ERR, "Unable to initialize "
737 "/proc/net/rtl8192/%s/stats-tx\n",
738 dev->name);
741 e = create_proc_read_entry("stats-ap", S_IFREG | S_IRUGO,
742 priv->dir_dev, proc_get_stats_ap, dev);
744 if (!e) {
745 RT_TRACE(COMP_ERR, "Unable to initialize "
746 "/proc/net/rtl8192/%s/stats-ap\n",
747 dev->name);
750 e = create_proc_read_entry("registers", S_IFREG | S_IRUGO,
751 priv->dir_dev, proc_get_registers, dev);
752 if (!e) {
753 RT_TRACE(COMP_ERR, "Unable to initialize "
754 "/proc/net/rtl8192/%s/registers\n",
755 dev->name);
758 /****************************************************************************
759 -----------------------------MISC STUFF-------------------------
760 *****************************************************************************/
762 /* this is only for debugging */
763 void print_buffer(u32 *buffer, int len)
765 int i;
766 u8 *buf =(u8*)buffer;
768 printk("ASCII BUFFER DUMP (len: %x):\n",len);
770 for(i=0;i<len;i++)
771 printk("%c",buf[i]);
773 printk("\nBINARY BUFFER DUMP (len: %x):\n",len);
775 for(i=0;i<len;i++)
776 printk("%x",buf[i]);
778 printk("\n");
781 //short check_nic_enough_desc(struct net_device *dev, priority_t priority)
782 short check_nic_enough_desc(struct net_device *dev,int queue_index)
784 struct r8192_priv *priv = ieee80211_priv(dev);
785 int used = atomic_read(&priv->tx_pending[queue_index]);
787 return (used < MAX_TX_URB);
790 void tx_timeout(struct net_device *dev)
792 struct r8192_priv *priv = ieee80211_priv(dev);
793 //rtl8192_commit(dev);
795 schedule_work(&priv->reset_wq);
796 //DMESG("TXTIMEOUT");
800 /* this is only for debug */
801 void dump_eprom(struct net_device *dev)
803 int i;
804 for(i=0; i<63; i++)
805 RT_TRACE(COMP_EPROM, "EEPROM addr %x : %x", i, eprom_read(dev,i));
808 /* this is only for debug */
809 void rtl8192_dump_reg(struct net_device *dev)
811 int i;
812 int n;
813 int max=0x1ff;
815 RT_TRACE(COMP_PHY, "Dumping NIC register map");
817 for(n=0;n<=max;)
819 printk( "\nD: %2x> ", n);
820 for(i=0;i<16 && n<=max;i++,n++)
821 printk("%2x ",read_nic_byte(dev,n));
823 printk("\n");
826 /****************************************************************************
827 ------------------------------HW STUFF---------------------------
828 *****************************************************************************/
831 void rtl8192_set_mode(struct net_device *dev,int mode)
833 u8 ecmd;
834 ecmd=read_nic_byte(dev, EPROM_CMD);
835 ecmd=ecmd &~ EPROM_CMD_OPERATING_MODE_MASK;
836 ecmd=ecmd | (mode<<EPROM_CMD_OPERATING_MODE_SHIFT);
837 ecmd=ecmd &~ (1<<EPROM_CS_SHIFT);
838 ecmd=ecmd &~ (1<<EPROM_CK_SHIFT);
839 write_nic_byte(dev, EPROM_CMD, ecmd);
843 void rtl8192_update_msr(struct net_device *dev)
845 struct r8192_priv *priv = ieee80211_priv(dev);
846 u8 msr;
848 msr = read_nic_byte(dev, MSR);
849 msr &= ~ MSR_LINK_MASK;
851 /* do not change in link_state != WLAN_LINK_ASSOCIATED.
852 * msr must be updated if the state is ASSOCIATING.
853 * this is intentional and make sense for ad-hoc and
854 * master (see the create BSS/IBSS func)
856 if (priv->ieee80211->state == IEEE80211_LINKED){
858 if (priv->ieee80211->iw_mode == IW_MODE_INFRA)
859 msr |= (MSR_LINK_MANAGED<<MSR_LINK_SHIFT);
860 else if (priv->ieee80211->iw_mode == IW_MODE_ADHOC)
861 msr |= (MSR_LINK_ADHOC<<MSR_LINK_SHIFT);
862 else if (priv->ieee80211->iw_mode == IW_MODE_MASTER)
863 msr |= (MSR_LINK_MASTER<<MSR_LINK_SHIFT);
865 }else
866 msr |= (MSR_LINK_NONE<<MSR_LINK_SHIFT);
868 write_nic_byte(dev, MSR, msr);
871 void rtl8192_set_chan(struct net_device *dev,short ch)
873 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
874 // u32 tx;
875 RT_TRACE(COMP_CH, "=====>%s()====ch:%d\n", __FUNCTION__, ch);
876 priv->chan=ch;
878 /* this hack should avoid frame TX during channel setting*/
881 // tx = read_nic_dword(dev,TX_CONF);
882 // tx &= ~TX_LOOPBACK_MASK;
884 #ifndef LOOP_TEST
885 // write_nic_dword(dev,TX_CONF, tx |( TX_LOOPBACK_MAC<<TX_LOOPBACK_SHIFT));
887 //need to implement rf set channel here WB
889 if (priv->rf_set_chan)
890 priv->rf_set_chan(dev,priv->chan);
891 mdelay(10);
892 // write_nic_dword(dev,TX_CONF,tx | (TX_LOOPBACK_NONE<<TX_LOOPBACK_SHIFT));
893 #endif
896 static void rtl8192_rx_isr(struct urb *urb);
897 //static void rtl8192_rx_isr(struct urb *rx_urb);
899 u32 get_rxpacket_shiftbytes_819xusb(struct ieee80211_rx_stats *pstats)
902 #ifdef USB_RX_AGGREGATION_SUPPORT
903 if (pstats->bisrxaggrsubframe)
904 return (sizeof(rx_desc_819x_usb) + pstats->RxDrvInfoSize
905 + pstats->RxBufShift + 8);
906 else
907 #endif
908 return (sizeof(rx_desc_819x_usb) + pstats->RxDrvInfoSize
909 + pstats->RxBufShift);
912 static int rtl8192_rx_initiate(struct net_device*dev)
914 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
915 struct urb *entry;
916 struct sk_buff *skb;
917 struct rtl8192_rx_info *info;
919 /* nomal packet rx procedure */
920 while (skb_queue_len(&priv->rx_queue) < MAX_RX_URB) {
921 skb = __dev_alloc_skb(RX_URB_SIZE, GFP_KERNEL);
922 if (!skb)
923 break;
924 entry = usb_alloc_urb(0, GFP_KERNEL);
925 if (!entry) {
926 kfree_skb(skb);
927 break;
929 // printk("nomal packet IN request!\n");
930 usb_fill_bulk_urb(entry, priv->udev,
931 usb_rcvbulkpipe(priv->udev, 3), skb_tail_pointer(skb),
932 RX_URB_SIZE, rtl8192_rx_isr, skb);
933 info = (struct rtl8192_rx_info *) skb->cb;
934 info->urb = entry;
935 info->dev = dev;
936 info->out_pipe = 3; //denote rx normal packet queue
937 skb_queue_tail(&priv->rx_queue, skb);
938 usb_submit_urb(entry, GFP_KERNEL);
941 /* command packet rx procedure */
942 while (skb_queue_len(&priv->rx_queue) < MAX_RX_URB + 3) {
943 // printk("command packet IN request!\n");
944 skb = __dev_alloc_skb(RX_URB_SIZE ,GFP_KERNEL);
945 if (!skb)
946 break;
947 entry = usb_alloc_urb(0, GFP_KERNEL);
948 if (!entry) {
949 kfree_skb(skb);
950 break;
952 usb_fill_bulk_urb(entry, priv->udev,
953 usb_rcvbulkpipe(priv->udev, 9), skb_tail_pointer(skb),
954 RX_URB_SIZE, rtl8192_rx_isr, skb);
955 info = (struct rtl8192_rx_info *) skb->cb;
956 info->urb = entry;
957 info->dev = dev;
958 info->out_pipe = 9; //denote rx cmd packet queue
959 skb_queue_tail(&priv->rx_queue, skb);
960 usb_submit_urb(entry, GFP_KERNEL);
963 return 0;
966 void rtl8192_set_rxconf(struct net_device *dev)
968 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
969 u32 rxconf;
971 rxconf=read_nic_dword(dev,RCR);
972 rxconf = rxconf &~ MAC_FILTER_MASK;
973 rxconf = rxconf | RCR_AMF;
974 rxconf = rxconf | RCR_ADF;
975 rxconf = rxconf | RCR_AB;
976 rxconf = rxconf | RCR_AM;
977 //rxconf = rxconf | RCR_ACF;
979 if (dev->flags & IFF_PROMISC) {DMESG ("NIC in promisc mode");}
981 if(priv->ieee80211->iw_mode == IW_MODE_MONITOR || \
982 dev->flags & IFF_PROMISC){
983 rxconf = rxconf | RCR_AAP;
984 } /*else if(priv->ieee80211->iw_mode == IW_MODE_MASTER){
985 rxconf = rxconf | (1<<ACCEPT_ALLMAC_FRAME_SHIFT);
986 rxconf = rxconf | (1<<RX_CHECK_BSSID_SHIFT);
987 }*/else{
988 rxconf = rxconf | RCR_APM;
989 rxconf = rxconf | RCR_CBSSID;
993 if(priv->ieee80211->iw_mode == IW_MODE_MONITOR){
994 rxconf = rxconf | RCR_AICV;
995 rxconf = rxconf | RCR_APWRMGT;
998 if( priv->crcmon == 1 && priv->ieee80211->iw_mode == IW_MODE_MONITOR)
999 rxconf = rxconf | RCR_ACRC32;
1002 rxconf = rxconf &~ RX_FIFO_THRESHOLD_MASK;
1003 rxconf = rxconf | (RX_FIFO_THRESHOLD_NONE<<RX_FIFO_THRESHOLD_SHIFT);
1004 rxconf = rxconf &~ MAX_RX_DMA_MASK;
1005 rxconf = rxconf | ((u32)7<<RCR_MXDMA_OFFSET);
1007 // rxconf = rxconf | (1<<RX_AUTORESETPHY_SHIFT);
1008 rxconf = rxconf | RCR_ONLYERLPKT;
1010 // rxconf = rxconf &~ RCR_CS_MASK;
1011 // rxconf = rxconf | (1<<RCR_CS_SHIFT);
1013 write_nic_dword(dev, RCR, rxconf);
1015 #ifdef DEBUG_RX
1016 DMESG("rxconf: %x %x",rxconf ,read_nic_dword(dev,RCR));
1017 #endif
1019 //wait to be removed
1020 void rtl8192_rx_enable(struct net_device *dev)
1022 //u8 cmd;
1024 //struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1026 rtl8192_rx_initiate(dev);
1028 // rtl8192_set_rxconf(dev);
1032 void rtl8192_tx_enable(struct net_device *dev)
1038 void rtl8192_rtx_disable(struct net_device *dev)
1040 u8 cmd;
1041 struct r8192_priv *priv = ieee80211_priv(dev);
1042 struct sk_buff *skb;
1043 struct rtl8192_rx_info *info;
1045 cmd=read_nic_byte(dev,CMDR);
1046 write_nic_byte(dev, CMDR, cmd &~ \
1047 (CR_TE|CR_RE));
1048 force_pci_posting(dev);
1049 mdelay(10);
1051 while ((skb = __skb_dequeue(&priv->rx_queue))) {
1052 info = (struct rtl8192_rx_info *) skb->cb;
1053 if (!info->urb)
1054 continue;
1056 usb_kill_urb(info->urb);
1057 kfree_skb(skb);
1060 if (skb_queue_len(&priv->skb_queue)) {
1061 printk(KERN_WARNING "skb_queue not empty\n");
1064 skb_queue_purge(&priv->skb_queue);
1065 return;
1069 int alloc_tx_beacon_desc_ring(struct net_device *dev, int count)
1071 return 0;
1074 inline u16 ieeerate2rtlrate(int rate)
1076 switch(rate){
1077 case 10:
1078 return 0;
1079 case 20:
1080 return 1;
1081 case 55:
1082 return 2;
1083 case 110:
1084 return 3;
1085 case 60:
1086 return 4;
1087 case 90:
1088 return 5;
1089 case 120:
1090 return 6;
1091 case 180:
1092 return 7;
1093 case 240:
1094 return 8;
1095 case 360:
1096 return 9;
1097 case 480:
1098 return 10;
1099 case 540:
1100 return 11;
1101 default:
1102 return 3;
1106 static u16 rtl_rate[] = {10,20,55,110,60,90,120,180,240,360,480,540};
1107 inline u16 rtl8192_rate2rate(short rate)
1109 if (rate >11) return 0;
1110 return rtl_rate[rate];
1114 /* The protype of rx_isr has changed since one verion of Linux Kernel */
1115 static void rtl8192_rx_isr(struct urb *urb)
1117 struct sk_buff *skb = (struct sk_buff *) urb->context;
1118 struct rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
1119 struct net_device *dev = info->dev;
1120 struct r8192_priv *priv = ieee80211_priv(dev);
1121 int out_pipe = info->out_pipe;
1122 int err;
1123 if(!priv->up)
1124 return;
1125 if (unlikely(urb->status)) {
1126 info->urb = NULL;
1127 priv->stats.rxstaterr++;
1128 priv->ieee80211->stats.rx_errors++;
1129 usb_free_urb(urb);
1130 // printk("%s():rx status err\n",__FUNCTION__);
1131 return;
1133 skb_unlink(skb, &priv->rx_queue);
1134 skb_put(skb, urb->actual_length);
1136 skb_queue_tail(&priv->skb_queue, skb);
1137 tasklet_schedule(&priv->irq_rx_tasklet);
1139 skb = dev_alloc_skb(RX_URB_SIZE);
1140 if (unlikely(!skb)) {
1141 usb_free_urb(urb);
1142 printk("%s():can,t alloc skb\n",__FUNCTION__);
1143 /* TODO check rx queue length and refill *somewhere* */
1144 return;
1147 usb_fill_bulk_urb(urb, priv->udev,
1148 usb_rcvbulkpipe(priv->udev, out_pipe), skb_tail_pointer(skb),
1149 RX_URB_SIZE, rtl8192_rx_isr, skb);
1151 info = (struct rtl8192_rx_info *) skb->cb;
1152 info->urb = urb;
1153 info->dev = dev;
1154 info->out_pipe = out_pipe;
1156 urb->transfer_buffer = skb_tail_pointer(skb);
1157 urb->context = skb;
1158 skb_queue_tail(&priv->rx_queue, skb);
1159 err = usb_submit_urb(urb, GFP_ATOMIC);
1160 if(err && err != EPERM)
1161 printk("can not submit rxurb, err is %x,URB status is %x\n",err,urb->status);
1165 rtl819xusb_rx_command_packet(
1166 struct net_device *dev,
1167 struct ieee80211_rx_stats *pstats
1170 u32 status;
1172 //RT_TRACE(COMP_RECV, DBG_TRACE, ("---> RxCommandPacketHandle819xUsb()\n"));
1174 status = cmpk_message_handle_rx(dev, pstats);
1175 if (status)
1177 DMESG("rxcommandpackethandle819xusb: It is a command packet\n");
1179 else
1181 //RT_TRACE(COMP_RECV, DBG_TRACE, ("RxCommandPacketHandle819xUsb: It is not a command packet\n"));
1184 //RT_TRACE(COMP_RECV, DBG_TRACE, ("<--- RxCommandPacketHandle819xUsb()\n"));
1185 return status;
1189 void rtl8192_data_hard_stop(struct net_device *dev)
1191 //FIXME !!
1195 void rtl8192_data_hard_resume(struct net_device *dev)
1197 // FIXME !!
1200 /* this function TX data frames when the ieee80211 stack requires this.
1201 * It checks also if we need to stop the ieee tx queue, eventually do it
1203 void rtl8192_hard_data_xmit(struct sk_buff *skb, struct net_device *dev, int rate)
1205 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1206 int ret;
1207 unsigned long flags;
1208 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1209 u8 queue_index = tcb_desc->queue_index;
1211 /* shall not be referred by command packet */
1212 assert(queue_index != TXCMD_QUEUE);
1214 spin_lock_irqsave(&priv->tx_lock,flags);
1216 memcpy((unsigned char *)(skb->cb),&dev,sizeof(dev));
1217 // tcb_desc->RATRIndex = 7;
1218 // tcb_desc->bTxDisableRateFallBack = 1;
1219 // tcb_desc->bTxUseDriverAssingedRate = 1;
1220 tcb_desc->bTxEnableFwCalcDur = 1;
1221 skb_push(skb, priv->ieee80211->tx_headroom);
1222 ret = rtl8192_tx(dev, skb);
1224 //priv->ieee80211->stats.tx_bytes+=(skb->len - priv->ieee80211->tx_headroom);
1225 //priv->ieee80211->stats.tx_packets++;
1227 spin_unlock_irqrestore(&priv->tx_lock,flags);
1229 // return ret;
1230 return;
1233 /* This is a rough attempt to TX a frame
1234 * This is called by the ieee 80211 stack to TX management frames.
1235 * If the ring is full packet are dropped (for data frame the queue
1236 * is stopped before this can happen).
1238 int rtl8192_hard_start_xmit(struct sk_buff *skb,struct net_device *dev)
1240 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1241 int ret;
1242 unsigned long flags;
1243 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1244 u8 queue_index = tcb_desc->queue_index;
1247 spin_lock_irqsave(&priv->tx_lock,flags);
1249 memcpy((unsigned char *)(skb->cb),&dev,sizeof(dev));
1250 if(queue_index == TXCMD_QUEUE) {
1251 skb_push(skb, USB_HWDESC_HEADER_LEN);
1252 rtl819xU_tx_cmd(dev, skb);
1253 ret = 1;
1254 spin_unlock_irqrestore(&priv->tx_lock,flags);
1255 return ret;
1256 } else {
1257 skb_push(skb, priv->ieee80211->tx_headroom);
1258 ret = rtl8192_tx(dev, skb);
1261 spin_unlock_irqrestore(&priv->tx_lock,flags);
1263 return ret;
1267 void rtl8192_try_wake_queue(struct net_device *dev, int pri);
1269 #ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
1270 u16 DrvAggr_PaddingAdd(struct net_device *dev, struct sk_buff *skb)
1272 u16 PaddingNum = 256 - ((skb->len + TX_PACKET_DRVAGGR_SUBFRAME_SHIFT_BYTES) % 256);
1273 return (PaddingNum&0xff);
1276 u8 MRateToHwRate8190Pci(u8 rate);
1277 u8 QueryIsShort(u8 TxHT, u8 TxRate, cb_desc *tcb_desc);
1278 u8 MapHwQueueToFirmwareQueue(u8 QueueID);
1279 struct sk_buff *DrvAggr_Aggregation(struct net_device *dev, struct ieee80211_drv_agg_txb *pSendList)
1281 struct ieee80211_device *ieee = netdev_priv(dev);
1282 struct r8192_priv *priv = ieee80211_priv(dev);
1283 cb_desc *tcb_desc = NULL;
1284 u8 i;
1285 u32 TotalLength;
1286 struct sk_buff *skb;
1287 struct sk_buff *agg_skb;
1288 tx_desc_819x_usb_aggr_subframe *tx_agg_desc = NULL;
1289 tx_fwinfo_819x_usb *tx_fwinfo = NULL;
1292 // Local variable initialization.
1294 /* first skb initialization */
1295 skb = pSendList->tx_agg_frames[0];
1296 TotalLength = skb->len;
1298 /* Get the total aggregation length including the padding space and
1299 * sub frame header.
1301 for(i = 1; i < pSendList->nr_drv_agg_frames; i++) {
1302 TotalLength += DrvAggr_PaddingAdd(dev, skb);
1303 skb = pSendList->tx_agg_frames[i];
1304 TotalLength += (skb->len + TX_PACKET_DRVAGGR_SUBFRAME_SHIFT_BYTES);
1307 /* allocate skb to contain the aggregated packets */
1308 agg_skb = dev_alloc_skb(TotalLength + ieee->tx_headroom);
1309 memset(agg_skb->data, 0, agg_skb->len);
1310 skb_reserve(agg_skb, ieee->tx_headroom);
1312 // RT_DEBUG_DATA(COMP_SEND, skb->cb, sizeof(skb->cb));
1313 /* reserve info for first subframe Tx descriptor to be set in the tx function */
1314 skb = pSendList->tx_agg_frames[0];
1315 tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1316 tcb_desc->drv_agg_enable = 1;
1317 tcb_desc->pkt_size = skb->len;
1318 tcb_desc->DrvAggrNum = pSendList->nr_drv_agg_frames;
1319 printk("DrvAggNum = %d\n", tcb_desc->DrvAggrNum);
1320 // RT_DEBUG_DATA(COMP_SEND, skb->cb, sizeof(skb->cb));
1321 // printk("========>skb->data ======> \n");
1322 // RT_DEBUG_DATA(COMP_SEND, skb->data, skb->len);
1323 memcpy(agg_skb->cb, skb->cb, sizeof(skb->cb));
1324 memcpy(skb_put(agg_skb,skb->len),skb->data,skb->len);
1326 for(i = 1; i < pSendList->nr_drv_agg_frames; i++) {
1327 /* push the next sub frame to be 256 byte aline */
1328 skb_put(agg_skb,DrvAggr_PaddingAdd(dev,skb));
1330 /* Subframe drv Tx descriptor and firmware info setting */
1331 skb = pSendList->tx_agg_frames[i];
1332 tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1333 tx_agg_desc = (tx_desc_819x_usb_aggr_subframe *)agg_skb->tail;
1334 tx_fwinfo = (tx_fwinfo_819x_usb *)(agg_skb->tail + sizeof(tx_desc_819x_usb_aggr_subframe));
1336 memset(tx_fwinfo,0,sizeof(tx_fwinfo_819x_usb));
1337 /* DWORD 0 */
1338 tx_fwinfo->TxHT = (tcb_desc->data_rate&0x80)?1:0;
1339 tx_fwinfo->TxRate = MRateToHwRate8190Pci(tcb_desc->data_rate);
1340 tx_fwinfo->EnableCPUDur = tcb_desc->bTxEnableFwCalcDur;
1341 tx_fwinfo->Short = QueryIsShort(tx_fwinfo->TxHT, tx_fwinfo->TxRate, tcb_desc);
1342 if(tcb_desc->bAMPDUEnable) {//AMPDU enabled
1343 tx_fwinfo->AllowAggregation = 1;
1344 /* DWORD 1 */
1345 tx_fwinfo->RxMF = tcb_desc->ampdu_factor;
1346 tx_fwinfo->RxAMD = tcb_desc->ampdu_density&0x07;//ampdudensity
1347 } else {
1348 tx_fwinfo->AllowAggregation = 0;
1349 /* DWORD 1 */
1350 tx_fwinfo->RxMF = 0;
1351 tx_fwinfo->RxAMD = 0;
1354 /* Protection mode related */
1355 tx_fwinfo->RtsEnable = (tcb_desc->bRTSEnable)?1:0;
1356 tx_fwinfo->CtsEnable = (tcb_desc->bCTSEnable)?1:0;
1357 tx_fwinfo->RtsSTBC = (tcb_desc->bRTSSTBC)?1:0;
1358 tx_fwinfo->RtsHT = (tcb_desc->rts_rate&0x80)?1:0;
1359 tx_fwinfo->RtsRate = MRateToHwRate8190Pci((u8)tcb_desc->rts_rate);
1360 tx_fwinfo->RtsSubcarrier = (tx_fwinfo->RtsHT==0)?(tcb_desc->RTSSC):0;
1361 tx_fwinfo->RtsBandwidth = (tx_fwinfo->RtsHT==1)?((tcb_desc->bRTSBW)?1:0):0;
1362 tx_fwinfo->RtsShort = (tx_fwinfo->RtsHT==0)?(tcb_desc->bRTSUseShortPreamble?1:0):\
1363 (tcb_desc->bRTSUseShortGI?1:0);
1365 /* Set Bandwidth and sub-channel settings. */
1366 if(priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20_40)
1368 if(tcb_desc->bPacketBW) {
1369 tx_fwinfo->TxBandwidth = 1;
1370 tx_fwinfo->TxSubCarrier = 0; //By SD3's Jerry suggestion, use duplicated mode
1371 } else {
1372 tx_fwinfo->TxBandwidth = 0;
1373 tx_fwinfo->TxSubCarrier = priv->nCur40MhzPrimeSC;
1375 } else {
1376 tx_fwinfo->TxBandwidth = 0;
1377 tx_fwinfo->TxSubCarrier = 0;
1380 /* Fill Tx descriptor */
1381 memset(tx_agg_desc, 0, sizeof(tx_desc_819x_usb_aggr_subframe));
1382 /* DWORD 0 */
1383 //tx_agg_desc->LINIP = 0;
1384 //tx_agg_desc->CmdInit = 1;
1385 tx_agg_desc->Offset = sizeof(tx_fwinfo_819x_usb) + 8;
1386 /* already raw data, need not to substract header length */
1387 tx_agg_desc->PktSize = skb->len & 0xffff;
1389 /*DWORD 1*/
1390 tx_agg_desc->SecCAMID= 0;
1391 tx_agg_desc->RATid = tcb_desc->RATRIndex;
1393 //MPDUOverhead = 0;
1394 tx_agg_desc->NoEnc = 1;
1396 tx_agg_desc->SecType = 0x0;
1398 if (tcb_desc->bHwSec) {
1399 switch (priv->ieee80211->pairwise_key_type)
1401 case KEY_TYPE_WEP40:
1402 case KEY_TYPE_WEP104:
1403 tx_agg_desc->SecType = 0x1;
1404 tx_agg_desc->NoEnc = 0;
1405 break;
1406 case KEY_TYPE_TKIP:
1407 tx_agg_desc->SecType = 0x2;
1408 tx_agg_desc->NoEnc = 0;
1409 break;
1410 case KEY_TYPE_CCMP:
1411 tx_agg_desc->SecType = 0x3;
1412 tx_agg_desc->NoEnc = 0;
1413 break;
1414 case KEY_TYPE_NA:
1415 tx_agg_desc->SecType = 0x0;
1416 tx_agg_desc->NoEnc = 1;
1417 break;
1421 tx_agg_desc->QueueSelect = MapHwQueueToFirmwareQueue(tcb_desc->queue_index);
1422 tx_agg_desc->TxFWInfoSize = sizeof(tx_fwinfo_819x_usb);
1424 tx_agg_desc->DISFB = tcb_desc->bTxDisableRateFallBack;
1425 tx_agg_desc->USERATE = tcb_desc->bTxUseDriverAssingedRate;
1427 tx_agg_desc->OWN = 1;
1429 //DWORD 2
1430 /* According windows driver, it seems that there no need to fill this field */
1431 //tx_agg_desc->TxBufferSize= (u32)(skb->len - USB_HWDESC_HEADER_LEN);
1433 /* to fill next packet */
1434 skb_put(agg_skb,TX_PACKET_DRVAGGR_SUBFRAME_SHIFT_BYTES);
1435 memcpy(skb_put(agg_skb,skb->len),skb->data,skb->len);
1438 for(i = 0; i < pSendList->nr_drv_agg_frames; i++) {
1439 dev_kfree_skb_any(pSendList->tx_agg_frames[i]);
1442 return agg_skb;
1445 /* NOTE:
1446 This function return a list of PTCB which is proper to be aggregate with the input TCB.
1447 If no proper TCB is found to do aggregation, SendList will only contain the input TCB.
1449 u8 DrvAggr_GetAggregatibleList(struct net_device *dev, struct sk_buff *skb,
1450 struct ieee80211_drv_agg_txb *pSendList)
1452 struct ieee80211_device *ieee = netdev_priv(dev);
1453 PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
1454 u16 nMaxAggrNum = pHTInfo->UsbTxAggrNum;
1455 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1456 u8 QueueID = tcb_desc->queue_index;
1458 do {
1459 pSendList->tx_agg_frames[pSendList->nr_drv_agg_frames++] = skb;
1460 if(pSendList->nr_drv_agg_frames >= nMaxAggrNum) {
1461 break;
1464 } while((skb = skb_dequeue(&ieee->skb_drv_aggQ[QueueID])));
1466 RT_TRACE(COMP_AMSDU, "DrvAggr_GetAggregatibleList, nAggrTcbNum = %d \n", pSendList->nr_drv_agg_frames);
1467 return pSendList->nr_drv_agg_frames;
1469 #endif
1471 static void rtl8192_tx_isr(struct urb *tx_urb)
1473 struct sk_buff *skb = (struct sk_buff*)tx_urb->context;
1474 struct net_device *dev = NULL;
1475 struct r8192_priv *priv = NULL;
1476 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1477 u8 queue_index = tcb_desc->queue_index;
1478 // bool bToSend0Byte;
1479 // u16 BufLen = skb->len;
1481 memcpy(&dev,(struct net_device*)(skb->cb),sizeof(struct net_device*));
1482 priv = ieee80211_priv(dev);
1484 if(tcb_desc->queue_index != TXCMD_QUEUE) {
1485 if(tx_urb->status == 0) {
1486 dev->trans_start = jiffies;
1487 // As act as station mode, destion shall be unicast address.
1488 //priv->ieee80211->stats.tx_bytes+=(skb->len - priv->ieee80211->tx_headroom);
1489 //priv->ieee80211->stats.tx_packets++;
1490 priv->stats.txoktotal++;
1491 priv->ieee80211->LinkDetectInfo.NumTxOkInPeriod++;
1492 priv->stats.txbytesunicast += (skb->len - priv->ieee80211->tx_headroom);
1493 } else {
1494 priv->ieee80211->stats.tx_errors++;
1495 //priv->stats.txmanageerr++;
1496 /* TODO */
1500 /* free skb and tx_urb */
1501 if(skb != NULL) {
1502 dev_kfree_skb_any(skb);
1503 usb_free_urb(tx_urb);
1504 atomic_dec(&priv->tx_pending[queue_index]);
1509 // Handle HW Beacon:
1510 // We had transfer our beacon frame to host controller at this moment.
1513 // Caution:
1514 // Handling the wait queue of command packets.
1515 // For Tx command packets, we must not do TCB fragment because it is not handled right now.
1516 // We must cut the packets to match the size of TX_CMD_PKT before we send it.
1519 /* Handle MPDU in wait queue. */
1520 if(queue_index != BEACON_QUEUE) {
1521 /* Don't send data frame during scanning.*/
1522 if((skb_queue_len(&priv->ieee80211->skb_waitQ[queue_index]) != 0)&&\
1523 (!(priv->ieee80211->queue_stop))) {
1524 if(NULL != (skb = skb_dequeue(&(priv->ieee80211->skb_waitQ[queue_index]))))
1525 priv->ieee80211->softmac_hard_start_xmit(skb, dev);
1527 return; //modified by david to avoid further processing AMSDU
1529 #ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
1530 else if ((skb_queue_len(&priv->ieee80211->skb_drv_aggQ[queue_index])!= 0)&&\
1531 (!(priv->ieee80211->queue_stop))) {
1532 // Tx Driver Aggregation process
1533 /* The driver will aggregation the packets according to the following stets
1534 * 1. check whether there's tx irq available, for it's a completion return
1535 * function, it should contain enough tx irq;
1536 * 2. check pakcet type;
1537 * 3. initialize sendlist, check whether the to-be send packet no greater than 1
1538 * 4. aggregation the packets, and fill firmware info and tx desc to it, etc.
1539 * 5. check whehter the packet could be sent, otherwise just insert to wait head
1540 * */
1541 skb = skb_dequeue(&priv->ieee80211->skb_drv_aggQ[queue_index]);
1542 if(!check_nic_enough_desc(dev, queue_index)) {
1543 skb_queue_head(&(priv->ieee80211->skb_drv_aggQ[queue_index]), skb);
1544 return;
1548 /*TODO*/
1550 u8* pHeader = skb->data;
1552 if(IsMgntQosData(pHeader) ||
1553 IsMgntQData_Ack(pHeader) ||
1554 IsMgntQData_Poll(pHeader) ||
1555 IsMgntQData_Poll_Ack(pHeader)
1559 struct ieee80211_drv_agg_txb SendList;
1561 memset(&SendList, 0, sizeof(struct ieee80211_drv_agg_txb));
1562 if(DrvAggr_GetAggregatibleList(dev, skb, &SendList) > 1) {
1563 skb = DrvAggr_Aggregation(dev, &SendList);
1567 priv->ieee80211->softmac_hard_start_xmit(skb, dev);
1570 #endif
1576 void rtl8192_beacon_stop(struct net_device *dev)
1578 u8 msr, msrm, msr2;
1579 struct r8192_priv *priv = ieee80211_priv(dev);
1581 msr = read_nic_byte(dev, MSR);
1582 msrm = msr & MSR_LINK_MASK;
1583 msr2 = msr & ~MSR_LINK_MASK;
1585 if(NIC_8192U == priv->card_8192) {
1586 usb_kill_urb(priv->rx_urb[MAX_RX_URB]);
1588 if ((msrm == (MSR_LINK_ADHOC<<MSR_LINK_SHIFT) ||
1589 (msrm == (MSR_LINK_MASTER<<MSR_LINK_SHIFT)))){
1590 write_nic_byte(dev, MSR, msr2 | MSR_LINK_NONE);
1591 write_nic_byte(dev, MSR, msr);
1595 void rtl8192_config_rate(struct net_device* dev, u16* rate_config)
1597 struct r8192_priv *priv = ieee80211_priv(dev);
1598 struct ieee80211_network *net;
1599 u8 i=0, basic_rate = 0;
1600 net = & priv->ieee80211->current_network;
1602 for (i=0; i<net->rates_len; i++)
1604 basic_rate = net->rates[i]&0x7f;
1605 switch(basic_rate)
1607 case MGN_1M: *rate_config |= RRSR_1M; break;
1608 case MGN_2M: *rate_config |= RRSR_2M; break;
1609 case MGN_5_5M: *rate_config |= RRSR_5_5M; break;
1610 case MGN_11M: *rate_config |= RRSR_11M; break;
1611 case MGN_6M: *rate_config |= RRSR_6M; break;
1612 case MGN_9M: *rate_config |= RRSR_9M; break;
1613 case MGN_12M: *rate_config |= RRSR_12M; break;
1614 case MGN_18M: *rate_config |= RRSR_18M; break;
1615 case MGN_24M: *rate_config |= RRSR_24M; break;
1616 case MGN_36M: *rate_config |= RRSR_36M; break;
1617 case MGN_48M: *rate_config |= RRSR_48M; break;
1618 case MGN_54M: *rate_config |= RRSR_54M; break;
1621 for (i=0; i<net->rates_ex_len; i++)
1623 basic_rate = net->rates_ex[i]&0x7f;
1624 switch(basic_rate)
1626 case MGN_1M: *rate_config |= RRSR_1M; break;
1627 case MGN_2M: *rate_config |= RRSR_2M; break;
1628 case MGN_5_5M: *rate_config |= RRSR_5_5M; break;
1629 case MGN_11M: *rate_config |= RRSR_11M; break;
1630 case MGN_6M: *rate_config |= RRSR_6M; break;
1631 case MGN_9M: *rate_config |= RRSR_9M; break;
1632 case MGN_12M: *rate_config |= RRSR_12M; break;
1633 case MGN_18M: *rate_config |= RRSR_18M; break;
1634 case MGN_24M: *rate_config |= RRSR_24M; break;
1635 case MGN_36M: *rate_config |= RRSR_36M; break;
1636 case MGN_48M: *rate_config |= RRSR_48M; break;
1637 case MGN_54M: *rate_config |= RRSR_54M; break;
1643 #define SHORT_SLOT_TIME 9
1644 #define NON_SHORT_SLOT_TIME 20
1646 void rtl8192_update_cap(struct net_device* dev, u16 cap)
1648 u32 tmp = 0;
1649 struct r8192_priv *priv = ieee80211_priv(dev);
1650 struct ieee80211_network *net = &priv->ieee80211->current_network;
1651 priv->short_preamble = cap & WLAN_CAPABILITY_SHORT_PREAMBLE;
1652 tmp = priv->basic_rate;
1653 if (priv->short_preamble)
1654 tmp |= BRSR_AckShortPmb;
1655 write_nic_dword(dev, RRSR, tmp);
1657 if (net->mode & (IEEE_G|IEEE_N_24G))
1659 u8 slot_time = 0;
1660 if ((cap & WLAN_CAPABILITY_SHORT_SLOT)&&(!priv->ieee80211->pHTInfo->bCurrentRT2RTLongSlotTime))
1661 {//short slot time
1662 slot_time = SHORT_SLOT_TIME;
1664 else //long slot time
1665 slot_time = NON_SHORT_SLOT_TIME;
1666 priv->slot_time = slot_time;
1667 write_nic_byte(dev, SLOT_TIME, slot_time);
1671 void rtl8192_net_update(struct net_device *dev)
1674 struct r8192_priv *priv = ieee80211_priv(dev);
1675 struct ieee80211_network *net;
1676 u16 BcnTimeCfg = 0, BcnCW = 6, BcnIFS = 0xf;
1677 u16 rate_config = 0;
1678 net = & priv->ieee80211->current_network;
1680 rtl8192_config_rate(dev, &rate_config);
1681 priv->basic_rate = rate_config &= 0x15f;
1683 write_nic_dword(dev,BSSIDR,((u32*)net->bssid)[0]);
1684 write_nic_word(dev,BSSIDR+4,((u16*)net->bssid)[2]);
1685 //for(i=0;i<ETH_ALEN;i++)
1686 // write_nic_byte(dev,BSSID+i,net->bssid[i]);
1688 rtl8192_update_msr(dev);
1689 // rtl8192_update_cap(dev, net->capability);
1690 if (priv->ieee80211->iw_mode == IW_MODE_ADHOC)
1692 write_nic_word(dev, ATIMWND, 2);
1693 write_nic_word(dev, BCN_DMATIME, 1023);
1694 write_nic_word(dev, BCN_INTERVAL, net->beacon_interval);
1695 // write_nic_word(dev, BcnIntTime, 100);
1696 write_nic_word(dev, BCN_DRV_EARLY_INT, 1);
1697 write_nic_byte(dev, BCN_ERR_THRESH, 100);
1698 BcnTimeCfg |= (BcnCW<<BCN_TCFG_CW_SHIFT);
1699 // TODO: BcnIFS may required to be changed on ASIC
1700 BcnTimeCfg |= BcnIFS<<BCN_TCFG_IFS;
1702 write_nic_word(dev, BCN_TCFG, BcnTimeCfg);
1709 //temporary hw beacon is not used any more.
1710 //open it when necessary
1711 void rtl819xusb_beacon_tx(struct net_device *dev,u16 tx_rate)
1715 inline u8 rtl8192_IsWirelessBMode(u16 rate)
1717 if( ((rate <= 110) && (rate != 60) && (rate != 90)) || (rate == 220) )
1718 return 1;
1719 else return 0;
1722 u16 N_DBPSOfRate(u16 DataRate);
1724 u16 ComputeTxTime(
1725 u16 FrameLength,
1726 u16 DataRate,
1727 u8 bManagementFrame,
1728 u8 bShortPreamble
1731 u16 FrameTime;
1732 u16 N_DBPS;
1733 u16 Ceiling;
1735 if( rtl8192_IsWirelessBMode(DataRate) )
1737 if( bManagementFrame || !bShortPreamble || DataRate == 10 )
1738 { // long preamble
1739 FrameTime = (u16)(144+48+(FrameLength*8/(DataRate/10)));
1741 else
1742 { // Short preamble
1743 FrameTime = (u16)(72+24+(FrameLength*8/(DataRate/10)));
1745 if( ( FrameLength*8 % (DataRate/10) ) != 0 ) //Get the Ceilling
1746 FrameTime ++;
1747 } else { //802.11g DSSS-OFDM PLCP length field calculation.
1748 N_DBPS = N_DBPSOfRate(DataRate);
1749 Ceiling = (16 + 8*FrameLength + 6) / N_DBPS
1750 + (((16 + 8*FrameLength + 6) % N_DBPS) ? 1 : 0);
1751 FrameTime = (u16)(16 + 4 + 4*Ceiling + 6);
1753 return FrameTime;
1756 u16 N_DBPSOfRate(u16 DataRate)
1758 u16 N_DBPS = 24;
1760 switch(DataRate)
1762 case 60:
1763 N_DBPS = 24;
1764 break;
1766 case 90:
1767 N_DBPS = 36;
1768 break;
1770 case 120:
1771 N_DBPS = 48;
1772 break;
1774 case 180:
1775 N_DBPS = 72;
1776 break;
1778 case 240:
1779 N_DBPS = 96;
1780 break;
1782 case 360:
1783 N_DBPS = 144;
1784 break;
1786 case 480:
1787 N_DBPS = 192;
1788 break;
1790 case 540:
1791 N_DBPS = 216;
1792 break;
1794 default:
1795 break;
1798 return N_DBPS;
1801 void rtl819xU_cmd_isr(struct urb *tx_cmd_urb, struct pt_regs *regs)
1803 usb_free_urb(tx_cmd_urb);
1806 unsigned int txqueue2outpipe(struct r8192_priv* priv,unsigned int tx_queue) {
1808 if(tx_queue >= 9)
1810 RT_TRACE(COMP_ERR,"%s():Unknown queue ID!!!\n",__FUNCTION__);
1811 return 0x04;
1813 return priv->txqueue_to_outpipemap[tx_queue];
1816 short rtl819xU_tx_cmd(struct net_device *dev, struct sk_buff *skb)
1818 struct r8192_priv *priv = ieee80211_priv(dev);
1819 //u8 *tx;
1820 int status;
1821 struct urb *tx_urb;
1822 //int urb_buf_len;
1823 unsigned int idx_pipe;
1824 tx_desc_cmd_819x_usb *pdesc = (tx_desc_cmd_819x_usb *)skb->data;
1825 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1826 u8 queue_index = tcb_desc->queue_index;
1828 //printk("\n %s::queue_index = %d\n",__FUNCTION__, queue_index);
1829 atomic_inc(&priv->tx_pending[queue_index]);
1830 tx_urb = usb_alloc_urb(0,GFP_ATOMIC);
1831 if(!tx_urb){
1832 dev_kfree_skb(skb);
1833 return -ENOMEM;
1836 memset(pdesc, 0, USB_HWDESC_HEADER_LEN);
1837 /* Tx descriptor ought to be set according to the skb->cb */
1838 pdesc->FirstSeg = 1;//bFirstSeg;
1839 pdesc->LastSeg = 1;//bLastSeg;
1840 pdesc->CmdInit = tcb_desc->bCmdOrInit;
1841 pdesc->TxBufferSize = tcb_desc->txbuf_size;
1842 pdesc->OWN = 1;
1843 pdesc->LINIP = tcb_desc->bLastIniPkt;
1845 //----------------------------------------------------------------------------
1846 // Fill up USB_OUT_CONTEXT.
1847 //----------------------------------------------------------------------------
1848 // Get index to out pipe from specified QueueID.
1849 #ifndef USE_ONE_PIPE
1850 idx_pipe = txqueue2outpipe(priv,queue_index);
1851 #else
1852 idx_pipe = 0x04;
1853 #endif
1854 #ifdef JOHN_DUMP_TXDESC
1855 int i;
1856 printk("<Tx descriptor>--rate %x---",rate);
1857 for (i = 0; i < 8; i++)
1858 printk("%8x ", tx[i]);
1859 printk("\n");
1860 #endif
1861 usb_fill_bulk_urb(tx_urb,priv->udev, usb_sndbulkpipe(priv->udev,idx_pipe), \
1862 skb->data, skb->len, rtl8192_tx_isr, skb);
1864 status = usb_submit_urb(tx_urb, GFP_ATOMIC);
1866 if (!status){
1867 return 0;
1868 }else{
1869 DMESGE("Error TX CMD URB, error %d",
1870 status);
1871 return -1;
1876 * Mapping Software/Hardware descriptor queue id to "Queue Select Field"
1877 * in TxFwInfo data structure
1878 * 2006.10.30 by Emily
1880 * \param QUEUEID Software Queue
1882 u8 MapHwQueueToFirmwareQueue(u8 QueueID)
1884 u8 QueueSelect = 0x0; //defualt set to
1886 switch(QueueID) {
1887 case BE_QUEUE:
1888 QueueSelect = QSLT_BE; //or QSelect = pTcb->priority;
1889 break;
1891 case BK_QUEUE:
1892 QueueSelect = QSLT_BK; //or QSelect = pTcb->priority;
1893 break;
1895 case VO_QUEUE:
1896 QueueSelect = QSLT_VO; //or QSelect = pTcb->priority;
1897 break;
1899 case VI_QUEUE:
1900 QueueSelect = QSLT_VI; //or QSelect = pTcb->priority;
1901 break;
1902 case MGNT_QUEUE:
1903 QueueSelect = QSLT_MGNT;
1904 break;
1906 case BEACON_QUEUE:
1907 QueueSelect = QSLT_BEACON;
1908 break;
1910 // TODO: 2006.10.30 mark other queue selection until we verify it is OK
1911 // TODO: Remove Assertions
1912 //#if (RTL819X_FPGA_VER & RTL819X_FPGA_GUANGAN_070502)
1913 case TXCMD_QUEUE:
1914 QueueSelect = QSLT_CMD;
1915 break;
1916 //#endif
1917 case HIGH_QUEUE:
1918 QueueSelect = QSLT_HIGH;
1919 break;
1921 default:
1922 RT_TRACE(COMP_ERR, "TransmitTCB(): Impossible Queue Selection: %d \n", QueueID);
1923 break;
1925 return QueueSelect;
1928 u8 MRateToHwRate8190Pci(u8 rate)
1930 u8 ret = DESC90_RATE1M;
1932 switch(rate) {
1933 case MGN_1M: ret = DESC90_RATE1M; break;
1934 case MGN_2M: ret = DESC90_RATE2M; break;
1935 case MGN_5_5M: ret = DESC90_RATE5_5M; break;
1936 case MGN_11M: ret = DESC90_RATE11M; break;
1937 case MGN_6M: ret = DESC90_RATE6M; break;
1938 case MGN_9M: ret = DESC90_RATE9M; break;
1939 case MGN_12M: ret = DESC90_RATE12M; break;
1940 case MGN_18M: ret = DESC90_RATE18M; break;
1941 case MGN_24M: ret = DESC90_RATE24M; break;
1942 case MGN_36M: ret = DESC90_RATE36M; break;
1943 case MGN_48M: ret = DESC90_RATE48M; break;
1944 case MGN_54M: ret = DESC90_RATE54M; break;
1946 // HT rate since here
1947 case MGN_MCS0: ret = DESC90_RATEMCS0; break;
1948 case MGN_MCS1: ret = DESC90_RATEMCS1; break;
1949 case MGN_MCS2: ret = DESC90_RATEMCS2; break;
1950 case MGN_MCS3: ret = DESC90_RATEMCS3; break;
1951 case MGN_MCS4: ret = DESC90_RATEMCS4; break;
1952 case MGN_MCS5: ret = DESC90_RATEMCS5; break;
1953 case MGN_MCS6: ret = DESC90_RATEMCS6; break;
1954 case MGN_MCS7: ret = DESC90_RATEMCS7; break;
1955 case MGN_MCS8: ret = DESC90_RATEMCS8; break;
1956 case MGN_MCS9: ret = DESC90_RATEMCS9; break;
1957 case MGN_MCS10: ret = DESC90_RATEMCS10; break;
1958 case MGN_MCS11: ret = DESC90_RATEMCS11; break;
1959 case MGN_MCS12: ret = DESC90_RATEMCS12; break;
1960 case MGN_MCS13: ret = DESC90_RATEMCS13; break;
1961 case MGN_MCS14: ret = DESC90_RATEMCS14; break;
1962 case MGN_MCS15: ret = DESC90_RATEMCS15; break;
1963 case (0x80|0x20): ret = DESC90_RATEMCS32; break;
1965 default: break;
1967 return ret;
1971 u8 QueryIsShort(u8 TxHT, u8 TxRate, cb_desc *tcb_desc)
1973 u8 tmp_Short;
1975 tmp_Short = (TxHT==1)?((tcb_desc->bUseShortGI)?1:0):((tcb_desc->bUseShortPreamble)?1:0);
1977 if(TxHT==1 && TxRate != DESC90_RATEMCS15)
1978 tmp_Short = 0;
1980 return tmp_Short;
1983 static void tx_zero_isr(struct urb *tx_urb)
1985 return;
1989 * The tx procedure is just as following,
1990 * skb->cb will contain all the following information,
1991 * priority, morefrag, rate, &dev.
1992 * */
1993 short rtl8192_tx(struct net_device *dev, struct sk_buff* skb)
1995 struct r8192_priv *priv = ieee80211_priv(dev);
1996 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1997 tx_desc_819x_usb *tx_desc = (tx_desc_819x_usb *)skb->data;
1998 tx_fwinfo_819x_usb *tx_fwinfo = (tx_fwinfo_819x_usb *)(skb->data + USB_HWDESC_HEADER_LEN);
1999 struct usb_device *udev = priv->udev;
2000 int pend;
2001 int status;
2002 struct urb *tx_urb = NULL, *tx_urb_zero = NULL;
2003 //int urb_len;
2004 unsigned int idx_pipe;
2005 // RT_DEBUG_DATA(COMP_SEND, tcb_desc, sizeof(cb_desc));
2006 // printk("=============> %s\n", __FUNCTION__);
2007 pend = atomic_read(&priv->tx_pending[tcb_desc->queue_index]);
2008 /* we are locked here so the two atomic_read and inc are executed
2009 * without interleaves
2010 * !!! For debug purpose
2012 if( pend > MAX_TX_URB){
2013 printk("To discard skb packet!\n");
2014 dev_kfree_skb_any(skb);
2015 return -1;
2018 tx_urb = usb_alloc_urb(0,GFP_ATOMIC);
2019 if(!tx_urb){
2020 dev_kfree_skb_any(skb);
2021 return -ENOMEM;
2024 /* Fill Tx firmware info */
2025 memset(tx_fwinfo,0,sizeof(tx_fwinfo_819x_usb));
2026 /* DWORD 0 */
2027 tx_fwinfo->TxHT = (tcb_desc->data_rate&0x80)?1:0;
2028 tx_fwinfo->TxRate = MRateToHwRate8190Pci(tcb_desc->data_rate);
2029 tx_fwinfo->EnableCPUDur = tcb_desc->bTxEnableFwCalcDur;
2030 tx_fwinfo->Short = QueryIsShort(tx_fwinfo->TxHT, tx_fwinfo->TxRate, tcb_desc);
2031 if(tcb_desc->bAMPDUEnable) {//AMPDU enabled
2032 tx_fwinfo->AllowAggregation = 1;
2033 /* DWORD 1 */
2034 tx_fwinfo->RxMF = tcb_desc->ampdu_factor;
2035 tx_fwinfo->RxAMD = tcb_desc->ampdu_density&0x07;//ampdudensity
2036 } else {
2037 tx_fwinfo->AllowAggregation = 0;
2038 /* DWORD 1 */
2039 tx_fwinfo->RxMF = 0;
2040 tx_fwinfo->RxAMD = 0;
2043 /* Protection mode related */
2044 tx_fwinfo->RtsEnable = (tcb_desc->bRTSEnable)?1:0;
2045 tx_fwinfo->CtsEnable = (tcb_desc->bCTSEnable)?1:0;
2046 tx_fwinfo->RtsSTBC = (tcb_desc->bRTSSTBC)?1:0;
2047 tx_fwinfo->RtsHT = (tcb_desc->rts_rate&0x80)?1:0;
2048 tx_fwinfo->RtsRate = MRateToHwRate8190Pci((u8)tcb_desc->rts_rate);
2049 tx_fwinfo->RtsSubcarrier = (tx_fwinfo->RtsHT==0)?(tcb_desc->RTSSC):0;
2050 tx_fwinfo->RtsBandwidth = (tx_fwinfo->RtsHT==1)?((tcb_desc->bRTSBW)?1:0):0;
2051 tx_fwinfo->RtsShort = (tx_fwinfo->RtsHT==0)?(tcb_desc->bRTSUseShortPreamble?1:0):\
2052 (tcb_desc->bRTSUseShortGI?1:0);
2054 /* Set Bandwidth and sub-channel settings. */
2055 if(priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20_40)
2057 if(tcb_desc->bPacketBW) {
2058 tx_fwinfo->TxBandwidth = 1;
2059 tx_fwinfo->TxSubCarrier = 0; //By SD3's Jerry suggestion, use duplicated mode
2060 } else {
2061 tx_fwinfo->TxBandwidth = 0;
2062 tx_fwinfo->TxSubCarrier = priv->nCur40MhzPrimeSC;
2064 } else {
2065 tx_fwinfo->TxBandwidth = 0;
2066 tx_fwinfo->TxSubCarrier = 0;
2069 #ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
2070 if (tcb_desc->drv_agg_enable)
2072 tx_fwinfo->Tx_INFO_RSVD = (tcb_desc->DrvAggrNum & 0x1f) << 1;
2074 #endif
2075 /* Fill Tx descriptor */
2076 memset(tx_desc, 0, sizeof(tx_desc_819x_usb));
2077 /* DWORD 0 */
2078 tx_desc->LINIP = 0;
2079 tx_desc->CmdInit = 1;
2080 tx_desc->Offset = sizeof(tx_fwinfo_819x_usb) + 8;
2082 #ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
2083 if (tcb_desc->drv_agg_enable) {
2084 tx_desc->PktSize = tcb_desc->pkt_size;
2085 } else
2086 #endif
2088 tx_desc->PktSize = (skb->len - TX_PACKET_SHIFT_BYTES) & 0xffff;
2091 /*DWORD 1*/
2092 tx_desc->SecCAMID= 0;
2093 tx_desc->RATid = tcb_desc->RATRIndex;
2095 //MPDUOverhead = 0;
2096 tx_desc->NoEnc = 1;
2098 tx_desc->SecType = 0x0;
2099 if (tcb_desc->bHwSec)
2101 switch (priv->ieee80211->pairwise_key_type)
2103 case KEY_TYPE_WEP40:
2104 case KEY_TYPE_WEP104:
2105 tx_desc->SecType = 0x1;
2106 tx_desc->NoEnc = 0;
2107 break;
2108 case KEY_TYPE_TKIP:
2109 tx_desc->SecType = 0x2;
2110 tx_desc->NoEnc = 0;
2111 break;
2112 case KEY_TYPE_CCMP:
2113 tx_desc->SecType = 0x3;
2114 tx_desc->NoEnc = 0;
2115 break;
2116 case KEY_TYPE_NA:
2117 tx_desc->SecType = 0x0;
2118 tx_desc->NoEnc = 1;
2119 break;
2123 tx_desc->QueueSelect = MapHwQueueToFirmwareQueue(tcb_desc->queue_index);
2124 tx_desc->TxFWInfoSize = sizeof(tx_fwinfo_819x_usb);
2126 tx_desc->DISFB = tcb_desc->bTxDisableRateFallBack;
2127 tx_desc->USERATE = tcb_desc->bTxUseDriverAssingedRate;
2129 /* Fill fields that are required to be initialized in all of the descriptors */
2130 //DWORD 0
2131 tx_desc->FirstSeg = 1;
2132 tx_desc->LastSeg = 1;
2133 tx_desc->OWN = 1;
2135 #ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
2136 if (tcb_desc->drv_agg_enable) {
2137 tx_desc->TxBufferSize = tcb_desc->pkt_size + sizeof(tx_fwinfo_819x_usb);
2138 } else
2139 #endif
2141 //DWORD 2
2142 tx_desc->TxBufferSize = (u32)(skb->len - USB_HWDESC_HEADER_LEN);
2144 /* Get index to out pipe from specified QueueID */
2145 #ifndef USE_ONE_PIPE
2146 idx_pipe = txqueue2outpipe(priv,tcb_desc->queue_index);
2147 #else
2148 idx_pipe = 0x5;
2149 #endif
2151 //RT_DEBUG_DATA(COMP_SEND,tx_fwinfo,sizeof(tx_fwinfo_819x_usb));
2152 //RT_DEBUG_DATA(COMP_SEND,tx_desc,sizeof(tx_desc_819x_usb));
2154 /* To submit bulk urb */
2155 usb_fill_bulk_urb(tx_urb,udev,
2156 usb_sndbulkpipe(udev,idx_pipe), skb->data,
2157 skb->len, rtl8192_tx_isr, skb);
2159 status = usb_submit_urb(tx_urb, GFP_ATOMIC);
2160 if (!status){
2161 //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
2162 bool bSend0Byte = false;
2163 u8 zero = 0;
2164 if(udev->speed == USB_SPEED_HIGH)
2166 if (skb->len > 0 && skb->len % 512 == 0)
2167 bSend0Byte = true;
2169 else
2171 if (skb->len > 0 && skb->len % 64 == 0)
2172 bSend0Byte = true;
2174 if (bSend0Byte)
2176 tx_urb_zero = usb_alloc_urb(0,GFP_ATOMIC);
2177 if(!tx_urb_zero){
2178 RT_TRACE(COMP_ERR, "can't alloc urb for zero byte\n");
2179 return -ENOMEM;
2181 usb_fill_bulk_urb(tx_urb_zero,udev,
2182 usb_sndbulkpipe(udev,idx_pipe), &zero,
2183 0, tx_zero_isr, dev);
2184 status = usb_submit_urb(tx_urb_zero, GFP_ATOMIC);
2185 if (status){
2186 RT_TRACE(COMP_ERR, "Error TX URB for zero byte %d, error %d", atomic_read(&priv->tx_pending[tcb_desc->queue_index]), status);
2187 return -1;
2190 dev->trans_start = jiffies;
2191 atomic_inc(&priv->tx_pending[tcb_desc->queue_index]);
2192 return 0;
2193 }else{
2194 RT_TRACE(COMP_ERR, "Error TX URB %d, error %d", atomic_read(&priv->tx_pending[tcb_desc->queue_index]),
2195 status);
2196 return -1;
2200 short rtl8192_usb_initendpoints(struct net_device *dev)
2202 struct r8192_priv *priv = ieee80211_priv(dev);
2204 priv->rx_urb = kmalloc(sizeof(struct urb *) * (MAX_RX_URB+1),
2205 GFP_KERNEL);
2207 #ifndef JACKSON_NEW_RX
2208 for(i=0;i<(MAX_RX_URB+1);i++){
2210 priv->rx_urb[i] = usb_alloc_urb(0,GFP_KERNEL);
2212 priv->rx_urb[i]->transfer_buffer = kmalloc(RX_URB_SIZE, GFP_KERNEL);
2214 priv->rx_urb[i]->transfer_buffer_length = RX_URB_SIZE;
2216 #endif
2218 #ifdef THOMAS_BEACON
2220 long align = 0;
2221 void *oldaddr, *newaddr;
2223 priv->rx_urb[16] = usb_alloc_urb(0, GFP_KERNEL);
2224 priv->oldaddr = kmalloc(16, GFP_KERNEL);
2225 oldaddr = priv->oldaddr;
2226 align = ((long)oldaddr) & 3;
2227 if (align) {
2228 newaddr = oldaddr + 4 - align;
2229 priv->rx_urb[16]->transfer_buffer_length = 16 - 4 + align;
2230 } else {
2231 newaddr = oldaddr;
2232 priv->rx_urb[16]->transfer_buffer_length = 16;
2234 priv->rx_urb[16]->transfer_buffer = newaddr;
2236 #endif
2238 memset(priv->rx_urb, 0, sizeof(struct urb*) * MAX_RX_URB);
2239 priv->pp_rxskb = kcalloc(MAX_RX_URB, sizeof(struct sk_buff *),
2240 GFP_KERNEL);
2241 if (priv->pp_rxskb == NULL)
2242 goto destroy;
2244 goto _middle;
2247 destroy:
2248 if (priv->pp_rxskb) {
2249 kfree(priv->pp_rxskb);
2251 if (priv->rx_urb) {
2252 kfree(priv->rx_urb);
2255 priv->pp_rxskb = NULL;
2256 priv->rx_urb = NULL;
2258 DMESGE("Endpoint Alloc Failure");
2259 return -ENOMEM;
2262 _middle:
2264 printk("End of initendpoints\n");
2265 return 0;
2268 #ifdef THOMAS_BEACON
2269 void rtl8192_usb_deleteendpoints(struct net_device *dev)
2271 int i;
2272 struct r8192_priv *priv = ieee80211_priv(dev);
2274 if(priv->rx_urb){
2275 for(i=0;i<(MAX_RX_URB+1);i++){
2276 usb_kill_urb(priv->rx_urb[i]);
2277 usb_free_urb(priv->rx_urb[i]);
2279 kfree(priv->rx_urb);
2280 priv->rx_urb = NULL;
2282 if(priv->oldaddr){
2283 kfree(priv->oldaddr);
2284 priv->oldaddr = NULL;
2286 if (priv->pp_rxskb) {
2287 kfree(priv->pp_rxskb);
2288 priv->pp_rxskb = 0;
2291 #else
2292 void rtl8192_usb_deleteendpoints(struct net_device *dev)
2294 int i;
2295 struct r8192_priv *priv = ieee80211_priv(dev);
2297 #ifndef JACKSON_NEW_RX
2299 if(priv->rx_urb){
2300 for(i=0;i<(MAX_RX_URB+1);i++){
2301 usb_kill_urb(priv->rx_urb[i]);
2302 kfree(priv->rx_urb[i]->transfer_buffer);
2303 usb_free_urb(priv->rx_urb[i]);
2305 kfree(priv->rx_urb);
2306 priv->rx_urb = NULL;
2309 #else
2310 if(priv->rx_urb){
2311 kfree(priv->rx_urb);
2312 priv->rx_urb = NULL;
2314 if(priv->oldaddr){
2315 kfree(priv->oldaddr);
2316 priv->oldaddr = NULL;
2318 if (priv->pp_rxskb) {
2319 kfree(priv->pp_rxskb);
2320 priv->pp_rxskb = 0;
2324 #endif
2326 #endif
2328 extern void rtl8192_update_ratr_table(struct net_device* dev);
2329 void rtl8192_link_change(struct net_device *dev)
2331 // int i;
2333 struct r8192_priv *priv = ieee80211_priv(dev);
2334 struct ieee80211_device* ieee = priv->ieee80211;
2335 //write_nic_word(dev, BCN_INTR_ITV, net->beacon_interval);
2336 if (ieee->state == IEEE80211_LINKED)
2338 rtl8192_net_update(dev);
2339 rtl8192_update_ratr_table(dev);
2340 //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
2341 if ((KEY_TYPE_WEP40 == ieee->pairwise_key_type) || (KEY_TYPE_WEP104 == ieee->pairwise_key_type))
2342 EnableHWSecurityConfig8192(dev);
2344 /*update timing params*/
2345 // RT_TRACE(COMP_CH, "========>%s(), chan:%d\n", __FUNCTION__, priv->chan);
2346 // rtl8192_set_chan(dev, priv->chan);
2347 if (ieee->iw_mode == IW_MODE_INFRA || ieee->iw_mode == IW_MODE_ADHOC)
2349 u32 reg = 0;
2350 reg = read_nic_dword(dev, RCR);
2351 if (priv->ieee80211->state == IEEE80211_LINKED)
2352 priv->ReceiveConfig = reg |= RCR_CBSSID;
2353 else
2354 priv->ReceiveConfig = reg &= ~RCR_CBSSID;
2355 write_nic_dword(dev, RCR, reg);
2358 // rtl8192_set_rxconf(dev);
2361 static struct ieee80211_qos_parameters def_qos_parameters = {
2362 {3,3,3,3},/* cw_min */
2363 {7,7,7,7},/* cw_max */
2364 {2,2,2,2},/* aifs */
2365 {0,0,0,0},/* flags */
2366 {0,0,0,0} /* tx_op_limit */
2370 void rtl8192_update_beacon(struct work_struct * work)
2372 struct r8192_priv *priv = container_of(work, struct r8192_priv, update_beacon_wq.work);
2373 struct net_device *dev = priv->ieee80211->dev;
2374 struct ieee80211_device* ieee = priv->ieee80211;
2375 struct ieee80211_network* net = &ieee->current_network;
2377 if (ieee->pHTInfo->bCurrentHTSupport)
2378 HTUpdateSelfAndPeerSetting(ieee, net);
2379 ieee->pHTInfo->bCurrentRT2RTLongSlotTime = net->bssht.bdRT2RTLongSlotTime;
2380 rtl8192_update_cap(dev, net->capability);
2383 * background support to run QoS activate functionality
2385 int WDCAPARA_ADD[] = {EDCAPARA_BE,EDCAPARA_BK,EDCAPARA_VI,EDCAPARA_VO};
2386 void rtl8192_qos_activate(struct work_struct * work)
2388 struct r8192_priv *priv = container_of(work, struct r8192_priv, qos_activate);
2389 struct net_device *dev = priv->ieee80211->dev;
2390 struct ieee80211_qos_parameters *qos_parameters = &priv->ieee80211->current_network.qos_data.parameters;
2391 u8 mode = priv->ieee80211->current_network.mode;
2392 //u32 size = sizeof(struct ieee80211_qos_parameters);
2393 u8 u1bAIFS;
2394 u32 u4bAcParam;
2395 int i;
2397 if (priv == NULL)
2398 return;
2400 mutex_lock(&priv->mutex);
2401 if(priv->ieee80211->state != IEEE80211_LINKED)
2402 goto success;
2403 RT_TRACE(COMP_QOS,"qos active process with associate response received\n");
2404 /* It better set slot time at first */
2405 /* For we just support b/g mode at present, let the slot time at 9/20 selection */
2406 /* update the ac parameter to related registers */
2407 for(i = 0; i < QOS_QUEUE_NUM; i++) {
2408 //Mode G/A: slotTimeTimer = 9; Mode B: 20
2409 u1bAIFS = qos_parameters->aifs[i] * ((mode&(IEEE_G|IEEE_N_24G)) ?9:20) + aSifsTime;
2410 u4bAcParam = ((((u32)(qos_parameters->tx_op_limit[i]))<< AC_PARAM_TXOP_LIMIT_OFFSET)|
2411 (((u32)(qos_parameters->cw_max[i]))<< AC_PARAM_ECW_MAX_OFFSET)|
2412 (((u32)(qos_parameters->cw_min[i]))<< AC_PARAM_ECW_MIN_OFFSET)|
2413 ((u32)u1bAIFS << AC_PARAM_AIFS_OFFSET));
2415 write_nic_dword(dev, WDCAPARA_ADD[i], u4bAcParam);
2416 //write_nic_dword(dev, WDCAPARA_ADD[i], 0x005e4332);
2419 success:
2420 mutex_unlock(&priv->mutex);
2423 static int rtl8192_qos_handle_probe_response(struct r8192_priv *priv,
2424 int active_network,
2425 struct ieee80211_network *network)
2427 int ret = 0;
2428 u32 size = sizeof(struct ieee80211_qos_parameters);
2430 if(priv->ieee80211->state !=IEEE80211_LINKED)
2431 return ret;
2433 if ((priv->ieee80211->iw_mode != IW_MODE_INFRA))
2434 return ret;
2436 if (network->flags & NETWORK_HAS_QOS_MASK) {
2437 if (active_network &&
2438 (network->flags & NETWORK_HAS_QOS_PARAMETERS))
2439 network->qos_data.active = network->qos_data.supported;
2441 if ((network->qos_data.active == 1) && (active_network == 1) &&
2442 (network->flags & NETWORK_HAS_QOS_PARAMETERS) &&
2443 (network->qos_data.old_param_count !=
2444 network->qos_data.param_count)) {
2445 network->qos_data.old_param_count =
2446 network->qos_data.param_count;
2447 queue_work(priv->priv_wq, &priv->qos_activate);
2448 RT_TRACE (COMP_QOS, "QoS parameters change call "
2449 "qos_activate\n");
2451 } else {
2452 memcpy(&priv->ieee80211->current_network.qos_data.parameters,\
2453 &def_qos_parameters, size);
2455 if ((network->qos_data.active == 1) && (active_network == 1)) {
2456 queue_work(priv->priv_wq, &priv->qos_activate);
2457 RT_TRACE(COMP_QOS, "QoS was disabled call qos_activate \n");
2459 network->qos_data.active = 0;
2460 network->qos_data.supported = 0;
2463 return 0;
2466 /* handle manage frame frame beacon and probe response */
2467 static int rtl8192_handle_beacon(struct net_device * dev,
2468 struct ieee80211_beacon * beacon,
2469 struct ieee80211_network * network)
2471 struct r8192_priv *priv = ieee80211_priv(dev);
2473 rtl8192_qos_handle_probe_response(priv,1,network);
2474 queue_delayed_work(priv->priv_wq, &priv->update_beacon_wq, 0);
2475 return 0;
2480 * handling the beaconing responses. if we get different QoS setting
2481 * off the network from the associated setting, adjust the QoS
2482 * setting
2484 static int rtl8192_qos_association_resp(struct r8192_priv *priv,
2485 struct ieee80211_network *network)
2487 int ret = 0;
2488 unsigned long flags;
2489 u32 size = sizeof(struct ieee80211_qos_parameters);
2490 int set_qos_param = 0;
2492 if ((priv == NULL) || (network == NULL))
2493 return ret;
2495 if(priv->ieee80211->state !=IEEE80211_LINKED)
2496 return ret;
2498 if ((priv->ieee80211->iw_mode != IW_MODE_INFRA))
2499 return ret;
2501 spin_lock_irqsave(&priv->ieee80211->lock, flags);
2502 if(network->flags & NETWORK_HAS_QOS_PARAMETERS) {
2503 memcpy(&priv->ieee80211->current_network.qos_data.parameters,\
2504 &network->qos_data.parameters,\
2505 sizeof(struct ieee80211_qos_parameters));
2506 priv->ieee80211->current_network.qos_data.active = 1;
2508 set_qos_param = 1;
2509 /* update qos parameter for current network */
2510 priv->ieee80211->current_network.qos_data.old_param_count = \
2511 priv->ieee80211->current_network.qos_data.param_count;
2512 priv->ieee80211->current_network.qos_data.param_count = \
2513 network->qos_data.param_count;
2515 } else {
2516 memcpy(&priv->ieee80211->current_network.qos_data.parameters,\
2517 &def_qos_parameters, size);
2518 priv->ieee80211->current_network.qos_data.active = 0;
2519 priv->ieee80211->current_network.qos_data.supported = 0;
2520 set_qos_param = 1;
2523 spin_unlock_irqrestore(&priv->ieee80211->lock, flags);
2525 RT_TRACE(COMP_QOS, "%s: network->flags = %d,%d\n",__FUNCTION__,network->flags ,priv->ieee80211->current_network.qos_data.active);
2526 if (set_qos_param == 1)
2527 queue_work(priv->priv_wq, &priv->qos_activate);
2530 return ret;
2534 static int rtl8192_handle_assoc_response(struct net_device *dev,
2535 struct ieee80211_assoc_response_frame *resp,
2536 struct ieee80211_network *network)
2538 struct r8192_priv *priv = ieee80211_priv(dev);
2539 rtl8192_qos_association_resp(priv, network);
2540 return 0;
2544 void rtl8192_update_ratr_table(struct net_device* dev)
2545 // POCTET_STRING posLegacyRate,
2546 // u8* pMcsRate)
2547 // PRT_WLAN_STA pEntry)
2549 struct r8192_priv* priv = ieee80211_priv(dev);
2550 struct ieee80211_device* ieee = priv->ieee80211;
2551 u8* pMcsRate = ieee->dot11HTOperationalRateSet;
2552 //struct ieee80211_network *net = &ieee->current_network;
2553 u32 ratr_value = 0;
2554 u8 rate_index = 0;
2555 rtl8192_config_rate(dev, (u16*)(&ratr_value));
2556 ratr_value |= (*(u16*)(pMcsRate)) << 12;
2557 // switch (net->mode)
2558 switch (ieee->mode)
2560 case IEEE_A:
2561 ratr_value &= 0x00000FF0;
2562 break;
2563 case IEEE_B:
2564 ratr_value &= 0x0000000F;
2565 break;
2566 case IEEE_G:
2567 ratr_value &= 0x00000FF7;
2568 break;
2569 case IEEE_N_24G:
2570 case IEEE_N_5G:
2571 if (ieee->pHTInfo->PeerMimoPs == 0) //MIMO_PS_STATIC
2572 ratr_value &= 0x0007F007;
2573 else{
2574 if (priv->rf_type == RF_1T2R)
2575 ratr_value &= 0x000FF007;
2576 else
2577 ratr_value &= 0x0F81F007;
2579 break;
2580 default:
2581 break;
2583 ratr_value &= 0x0FFFFFFF;
2584 if(ieee->pHTInfo->bCurTxBW40MHz && ieee->pHTInfo->bCurShortGI40MHz){
2585 ratr_value |= 0x80000000;
2586 }else if(!ieee->pHTInfo->bCurTxBW40MHz && ieee->pHTInfo->bCurShortGI20MHz){
2587 ratr_value |= 0x80000000;
2589 write_nic_dword(dev, RATR0+rate_index*4, ratr_value);
2590 write_nic_byte(dev, UFWP, 1);
2593 static u8 ccmp_ie[4] = {0x00,0x50,0xf2,0x04};
2594 static u8 ccmp_rsn_ie[4] = {0x00, 0x0f, 0xac, 0x04};
2595 bool GetNmodeSupportBySecCfg8192(struct net_device*dev)
2597 struct r8192_priv* priv = ieee80211_priv(dev);
2598 struct ieee80211_device* ieee = priv->ieee80211;
2599 struct ieee80211_network * network = &ieee->current_network;
2600 int wpa_ie_len= ieee->wpa_ie_len;
2601 struct ieee80211_crypt_data* crypt;
2602 int encrypt;
2604 crypt = ieee->crypt[ieee->tx_keyidx];
2605 //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
2606 encrypt = (network->capability & WLAN_CAPABILITY_PRIVACY) || (ieee->host_encrypt && crypt && crypt->ops && (0 == strcmp(crypt->ops->name,"WEP")));
2608 /* simply judge */
2609 if(encrypt && (wpa_ie_len == 0)) {
2610 /* wep encryption, no N mode setting */
2611 return false;
2612 // } else if((wpa_ie_len != 0)&&(memcmp(&(ieee->wpa_ie[14]),ccmp_ie,4))) {
2613 } else if((wpa_ie_len != 0)) {
2614 /* parse pairwise key type */
2615 //if((pairwisekey = WEP40)||(pairwisekey = WEP104)||(pairwisekey = TKIP))
2616 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))))
2617 return true;
2618 else
2619 return false;
2620 } else {
2621 return true;
2624 return true;
2627 bool GetHalfNmodeSupportByAPs819xUsb(struct net_device* dev)
2629 bool Reval;
2630 struct r8192_priv* priv = ieee80211_priv(dev);
2631 struct ieee80211_device* ieee = priv->ieee80211;
2633 if(ieee->bHalfWirelessN24GMode == true)
2634 Reval = true;
2635 else
2636 Reval = false;
2638 return Reval;
2641 void rtl8192_refresh_supportrate(struct r8192_priv* priv)
2643 struct ieee80211_device* ieee = priv->ieee80211;
2644 //we donot consider set support rate for ABG mode, only HT MCS rate is set here.
2645 if (ieee->mode == WIRELESS_MODE_N_24G || ieee->mode == WIRELESS_MODE_N_5G)
2647 memcpy(ieee->Regdot11HTOperationalRateSet, ieee->RegHTSuppRateSet, 16);
2648 //RT_DEBUG_DATA(COMP_INIT, ieee->RegHTSuppRateSet, 16);
2649 //RT_DEBUG_DATA(COMP_INIT, ieee->Regdot11HTOperationalRateSet, 16);
2651 else
2652 memset(ieee->Regdot11HTOperationalRateSet, 0, 16);
2653 return;
2656 u8 rtl8192_getSupportedWireleeMode(struct net_device*dev)
2658 struct r8192_priv *priv = ieee80211_priv(dev);
2659 u8 ret = 0;
2660 switch(priv->rf_chip)
2662 case RF_8225:
2663 case RF_8256:
2664 case RF_PSEUDO_11N:
2665 ret = (WIRELESS_MODE_N_24G|WIRELESS_MODE_G|WIRELESS_MODE_B);
2666 break;
2667 case RF_8258:
2668 ret = (WIRELESS_MODE_A|WIRELESS_MODE_N_5G);
2669 break;
2670 default:
2671 ret = WIRELESS_MODE_B;
2672 break;
2674 return ret;
2676 void rtl8192_SetWirelessMode(struct net_device* dev, u8 wireless_mode)
2678 struct r8192_priv *priv = ieee80211_priv(dev);
2679 u8 bSupportMode = rtl8192_getSupportedWireleeMode(dev);
2681 if ((wireless_mode == WIRELESS_MODE_AUTO) || ((wireless_mode&bSupportMode)==0))
2683 if(bSupportMode & WIRELESS_MODE_N_24G)
2685 wireless_mode = WIRELESS_MODE_N_24G;
2687 else if(bSupportMode & WIRELESS_MODE_N_5G)
2689 wireless_mode = WIRELESS_MODE_N_5G;
2691 else if((bSupportMode & WIRELESS_MODE_A))
2693 wireless_mode = WIRELESS_MODE_A;
2695 else if((bSupportMode & WIRELESS_MODE_G))
2697 wireless_mode = WIRELESS_MODE_G;
2699 else if((bSupportMode & WIRELESS_MODE_B))
2701 wireless_mode = WIRELESS_MODE_B;
2703 else{
2704 RT_TRACE(COMP_ERR, "%s(), No valid wireless mode supported, SupportedWirelessMode(%x)!!!\n", __FUNCTION__,bSupportMode);
2705 wireless_mode = WIRELESS_MODE_B;
2708 #ifdef TO_DO_LIST //// TODO: this function doesn't work well at this time, we should wait for FPGA
2709 ActUpdateChannelAccessSetting( pAdapter, pHalData->CurrentWirelessMode, &pAdapter->MgntInfo.Info8185.ChannelAccessSetting );
2710 #endif
2711 priv->ieee80211->mode = wireless_mode;
2713 if ((wireless_mode == WIRELESS_MODE_N_24G) || (wireless_mode == WIRELESS_MODE_N_5G))
2714 priv->ieee80211->pHTInfo->bEnableHT = 1;
2715 else
2716 priv->ieee80211->pHTInfo->bEnableHT = 0;
2717 RT_TRACE(COMP_INIT, "Current Wireless Mode is %x\n", wireless_mode);
2718 rtl8192_refresh_supportrate(priv);
2721 //init priv variables here. only non_zero value should be initialized here.
2722 static void rtl8192_init_priv_variable(struct net_device* dev)
2724 struct r8192_priv *priv = ieee80211_priv(dev);
2725 u8 i;
2726 priv->card_8192 = NIC_8192U;
2727 priv->chan = 1; //set to channel 1
2728 priv->ieee80211->mode = WIRELESS_MODE_AUTO; //SET AUTO
2729 priv->ieee80211->iw_mode = IW_MODE_INFRA;
2730 priv->ieee80211->ieee_up=0;
2731 priv->retry_rts = DEFAULT_RETRY_RTS;
2732 priv->retry_data = DEFAULT_RETRY_DATA;
2733 priv->ieee80211->rts = DEFAULT_RTS_THRESHOLD;
2734 priv->ieee80211->rate = 110; //11 mbps
2735 priv->ieee80211->short_slot = 1;
2736 priv->promisc = (dev->flags & IFF_PROMISC) ? 1:0;
2737 priv->CckPwEnl = 6;
2738 //for silent reset
2739 priv->IrpPendingCount = 1;
2740 priv->ResetProgress = RESET_TYPE_NORESET;
2741 priv->bForcedSilentReset = 0;
2742 priv->bDisableNormalResetCheck = false;
2743 priv->force_reset = false;
2745 priv->ieee80211->FwRWRF = 0; //we don't use FW read/write RF until stable firmware is available.
2746 priv->ieee80211->current_network.beacon_interval = DEFAULT_BEACONINTERVAL;
2747 priv->ieee80211->iw_mode = IW_MODE_INFRA;
2748 priv->ieee80211->softmac_features = IEEE_SOFTMAC_SCAN |
2749 IEEE_SOFTMAC_ASSOCIATE | IEEE_SOFTMAC_PROBERQ |
2750 IEEE_SOFTMAC_PROBERS | IEEE_SOFTMAC_TX_QUEUE |
2751 IEEE_SOFTMAC_BEACONS;//added by amy 080604 //| //IEEE_SOFTMAC_SINGLE_QUEUE;
2753 priv->ieee80211->active_scan = 1;
2754 priv->ieee80211->modulation = IEEE80211_CCK_MODULATION | IEEE80211_OFDM_MODULATION;
2755 priv->ieee80211->host_encrypt = 1;
2756 priv->ieee80211->host_decrypt = 1;
2757 priv->ieee80211->start_send_beacons = NULL;//rtl819xusb_beacon_tx;//-by amy 080604
2758 priv->ieee80211->stop_send_beacons = NULL;//rtl8192_beacon_stop;//-by amy 080604
2759 priv->ieee80211->softmac_hard_start_xmit = rtl8192_hard_start_xmit;
2760 priv->ieee80211->set_chan = rtl8192_set_chan;
2761 priv->ieee80211->link_change = rtl8192_link_change;
2762 priv->ieee80211->softmac_data_hard_start_xmit = rtl8192_hard_data_xmit;
2763 priv->ieee80211->data_hard_stop = rtl8192_data_hard_stop;
2764 priv->ieee80211->data_hard_resume = rtl8192_data_hard_resume;
2765 priv->ieee80211->init_wmmparam_flag = 0;
2766 priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD;
2767 priv->ieee80211->check_nic_enough_desc = check_nic_enough_desc;
2768 priv->ieee80211->tx_headroom = TX_PACKET_SHIFT_BYTES;
2769 priv->ieee80211->qos_support = 1;
2771 //added by WB
2772 // priv->ieee80211->SwChnlByTimerHandler = rtl8192_phy_SwChnl;
2773 priv->ieee80211->SetBWModeHandler = rtl8192_SetBWMode;
2774 priv->ieee80211->handle_assoc_response = rtl8192_handle_assoc_response;
2775 priv->ieee80211->handle_beacon = rtl8192_handle_beacon;
2776 //added by david
2777 priv->ieee80211->GetNmodeSupportBySecCfg = GetNmodeSupportBySecCfg8192;
2778 priv->ieee80211->GetHalfNmodeSupportByAPsHandler = GetHalfNmodeSupportByAPs819xUsb;
2779 priv->ieee80211->SetWirelessMode = rtl8192_SetWirelessMode;
2780 //added by amy
2781 priv->ieee80211->InitialGainHandler = InitialGain819xUsb;
2782 priv->card_type = USB;
2783 #ifdef TO_DO_LIST
2784 if(Adapter->bInHctTest)
2786 pHalData->ShortRetryLimit = 7;
2787 pHalData->LongRetryLimit = 7;
2789 #endif
2791 priv->ShortRetryLimit = 0x30;
2792 priv->LongRetryLimit = 0x30;
2794 priv->EarlyRxThreshold = 7;
2795 priv->enable_gpio0 = 0;
2796 priv->TransmitConfig =
2797 // TCR_DurProcMode | //for RTL8185B, duration setting by HW
2798 //? TCR_DISReqQsize |
2799 (TCR_MXDMA_2048<<TCR_MXDMA_OFFSET)| // Max DMA Burst Size per Tx DMA Burst, 7: reservied.
2800 (priv->ShortRetryLimit<<TCR_SRL_OFFSET)| // Short retry limit
2801 (priv->LongRetryLimit<<TCR_LRL_OFFSET) | // Long retry limit
2802 (false ? TCR_SAT: 0); // FALSE: HW provies PLCP length and LENGEXT, TURE: SW proiveds them
2803 #ifdef TO_DO_LIST
2804 if(Adapter->bInHctTest)
2805 pHalData->ReceiveConfig = pHalData->CSMethod |
2806 RCR_AMF | RCR_ADF | //RCR_AAP | //accept management/data
2807 //guangan200710
2808 RCR_ACF | //accept control frame for SW AP needs PS-poll, 2005.07.07, by rcnjko.
2809 RCR_AB | RCR_AM | RCR_APM | //accept BC/MC/UC
2810 RCR_AICV | RCR_ACRC32 | //accept ICV/CRC error packet
2811 ((u32)7<<RCR_MXDMA_OFFSET) | // Max DMA Burst Size per Rx DMA Burst, 7: unlimited.
2812 (pHalData->EarlyRxThreshold<<RCR_FIFO_OFFSET) | // Rx FIFO Threshold, 7: No Rx threshold.
2813 (pHalData->EarlyRxThreshold == 7 ? RCR_OnlyErlPkt:0);
2814 else
2816 #endif
2817 priv->ReceiveConfig =
2818 RCR_AMF | RCR_ADF | //accept management/data
2819 RCR_ACF | //accept control frame for SW AP needs PS-poll, 2005.07.07, by rcnjko.
2820 RCR_AB | RCR_AM | RCR_APM | //accept BC/MC/UC
2821 //RCR_AICV | RCR_ACRC32 | //accept ICV/CRC error packet
2822 ((u32)7<<RCR_MXDMA_OFFSET)| // Max DMA Burst Size per Rx DMA Burst, 7: unlimited.
2823 (priv->EarlyRxThreshold<<RX_FIFO_THRESHOLD_SHIFT) | // Rx FIFO Threshold, 7: No Rx threshold.
2824 (priv->EarlyRxThreshold == 7 ? RCR_ONLYERLPKT:0);
2826 priv->AcmControl = 0;
2827 priv->pFirmware = kmalloc(sizeof(rt_firmware), GFP_KERNEL);
2828 if (priv->pFirmware)
2829 memset(priv->pFirmware, 0, sizeof(rt_firmware));
2831 /* rx related queue */
2832 skb_queue_head_init(&priv->rx_queue);
2833 skb_queue_head_init(&priv->skb_queue);
2835 /* Tx related queue */
2836 for(i = 0; i < MAX_QUEUE_SIZE; i++) {
2837 skb_queue_head_init(&priv->ieee80211->skb_waitQ [i]);
2839 for(i = 0; i < MAX_QUEUE_SIZE; i++) {
2840 skb_queue_head_init(&priv->ieee80211->skb_aggQ [i]);
2842 for(i = 0; i < MAX_QUEUE_SIZE; i++) {
2843 skb_queue_head_init(&priv->ieee80211->skb_drv_aggQ [i]);
2845 priv->rf_set_chan = rtl8192_phy_SwChnl;
2848 //init lock here
2849 static void rtl8192_init_priv_lock(struct r8192_priv* priv)
2851 spin_lock_init(&priv->tx_lock);
2852 spin_lock_init(&priv->irq_lock);//added by thomas
2853 //spin_lock_init(&priv->rf_lock);
2854 sema_init(&priv->wx_sem,1);
2855 sema_init(&priv->rf_sem,1);
2856 mutex_init(&priv->mutex);
2859 extern void rtl819x_watchdog_wqcallback(struct work_struct *work);
2861 void rtl8192_irq_rx_tasklet(struct r8192_priv *priv);
2862 //init tasklet and wait_queue here. only 2.6 above kernel is considered
2863 #define DRV_NAME "wlan0"
2864 static void rtl8192_init_priv_task(struct net_device* dev)
2866 struct r8192_priv *priv = ieee80211_priv(dev);
2868 #ifdef PF_SYNCTHREAD
2869 priv->priv_wq = create_workqueue(DRV_NAME,0);
2870 #else
2871 priv->priv_wq = create_workqueue(DRV_NAME);
2872 #endif
2874 INIT_WORK(&priv->reset_wq, rtl8192_restart);
2876 //INIT_DELAYED_WORK(&priv->watch_dog_wq, hal_dm_watchdog);
2877 INIT_DELAYED_WORK(&priv->watch_dog_wq, rtl819x_watchdog_wqcallback);
2878 INIT_DELAYED_WORK(&priv->txpower_tracking_wq, dm_txpower_trackingcallback);
2879 // INIT_DELAYED_WORK(&priv->gpio_change_rf_wq, dm_gpio_change_rf_callback);
2880 INIT_DELAYED_WORK(&priv->rfpath_check_wq, dm_rf_pathcheck_workitemcallback);
2881 INIT_DELAYED_WORK(&priv->update_beacon_wq, rtl8192_update_beacon);
2882 INIT_DELAYED_WORK(&priv->initialgain_operate_wq, InitialGainOperateWorkItemCallBack);
2883 //INIT_WORK(&priv->SwChnlWorkItem, rtl8192_SwChnl_WorkItem);
2884 //INIT_WORK(&priv->SetBWModeWorkItem, rtl8192_SetBWModeWorkItem);
2885 INIT_WORK(&priv->qos_activate, rtl8192_qos_activate);
2887 tasklet_init(&priv->irq_rx_tasklet,
2888 (void(*)(unsigned long))rtl8192_irq_rx_tasklet,
2889 (unsigned long)priv);
2892 static void rtl8192_get_eeprom_size(struct net_device* dev)
2894 u16 curCR = 0;
2895 struct r8192_priv *priv = ieee80211_priv(dev);
2896 RT_TRACE(COMP_EPROM, "===========>%s()\n", __FUNCTION__);
2897 curCR = read_nic_word_E(dev,EPROM_CMD);
2898 RT_TRACE(COMP_EPROM, "read from Reg EPROM_CMD(%x):%x\n", EPROM_CMD, curCR);
2899 //whether need I consider BIT5?
2900 priv->epromtype = (curCR & Cmd9346CR_9356SEL) ? EPROM_93c56 : EPROM_93c46;
2901 RT_TRACE(COMP_EPROM, "<===========%s(), epromtype:%d\n", __FUNCTION__, priv->epromtype);
2904 //used to swap endian. as ntohl & htonl are not neccessary to swap endian, so use this instead.
2905 static inline u16 endian_swap(u16* data)
2907 u16 tmp = *data;
2908 *data = (tmp >> 8) | (tmp << 8);
2909 return *data;
2911 static void rtl8192_read_eeprom_info(struct net_device* dev)
2913 u16 wEPROM_ID = 0;
2914 u8 bMac_Tmp_Addr[6] = {0x00, 0xe0, 0x4c, 0x00, 0x00, 0x02};
2915 u8 bLoad_From_EEPOM = false;
2916 struct r8192_priv *priv = ieee80211_priv(dev);
2917 u16 tmpValue = 0;
2918 RT_TRACE(COMP_EPROM, "===========>%s()\n", __FUNCTION__);
2919 wEPROM_ID = eprom_read(dev, 0); //first read EEPROM ID out;
2920 RT_TRACE(COMP_EPROM, "EEPROM ID is 0x%x\n", wEPROM_ID);
2922 if (wEPROM_ID != RTL8190_EEPROM_ID)
2924 RT_TRACE(COMP_ERR, "EEPROM ID is invalid(is 0x%x(should be 0x%x)\n", wEPROM_ID, RTL8190_EEPROM_ID);
2926 else
2927 bLoad_From_EEPOM = true;
2929 if (bLoad_From_EEPOM)
2931 tmpValue = eprom_read(dev, (EEPROM_VID>>1));
2932 priv->eeprom_vid = endian_swap(&tmpValue);
2933 priv->eeprom_pid = eprom_read(dev, (EEPROM_PID>>1));
2934 tmpValue = eprom_read(dev, (EEPROM_ChannelPlan>>1));
2935 priv->eeprom_ChannelPlan =((tmpValue&0xff00)>>8);
2936 priv->btxpowerdata_readfromEEPORM = true;
2937 priv->eeprom_CustomerID = eprom_read(dev, (EEPROM_Customer_ID>>1)) >>8;
2939 else
2941 priv->eeprom_vid = 0;
2942 priv->eeprom_pid = 0;
2943 priv->card_8192_version = VERSION_819xU_B;
2944 priv->eeprom_ChannelPlan = 0;
2945 priv->eeprom_CustomerID = 0;
2947 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);
2948 //set channelplan from eeprom
2949 priv->ChannelPlan = priv->eeprom_ChannelPlan;
2950 if (bLoad_From_EEPOM)
2952 int i;
2953 for (i=0; i<6; i+=2)
2955 u16 tmp = 0;
2956 tmp = eprom_read(dev, (u16)((EEPROM_NODE_ADDRESS_BYTE_0 + i)>>1));
2957 *(u16*)(&dev->dev_addr[i]) = tmp;
2960 else
2962 memcpy(dev->dev_addr, bMac_Tmp_Addr, 6);
2963 //should I set IDR0 here?
2965 RT_TRACE(COMP_EPROM, "MAC addr:%pM\n", dev->dev_addr);
2966 priv->rf_type = RTL819X_DEFAULT_RF_TYPE; //default 1T2R
2967 priv->rf_chip = RF_8256;
2969 if (priv->card_8192_version == (u8)VERSION_819xU_A)
2971 //read Tx power gain offset of legacy OFDM to HT rate
2972 if (bLoad_From_EEPOM)
2973 priv->EEPROMTxPowerDiff = (eprom_read(dev, (EEPROM_TxPowerDiff>>1))&0xff00) >> 8;
2974 else
2975 priv->EEPROMTxPowerDiff = EEPROM_Default_TxPower;
2976 RT_TRACE(COMP_EPROM, "TxPowerDiff:%d\n", priv->EEPROMTxPowerDiff);
2977 //read ThermalMeter from EEPROM
2978 if (bLoad_From_EEPOM)
2979 priv->EEPROMThermalMeter = (u8)(eprom_read(dev, (EEPROM_ThermalMeter>>1))&0x00ff);
2980 else
2981 priv->EEPROMThermalMeter = EEPROM_Default_ThermalMeter;
2982 RT_TRACE(COMP_EPROM, "ThermalMeter:%d\n", priv->EEPROMThermalMeter);
2983 //vivi, for tx power track
2984 priv->TSSI_13dBm = priv->EEPROMThermalMeter *100;
2985 //read antenna tx power offset of B/C/D to A from EEPROM
2986 if (bLoad_From_EEPOM)
2987 priv->EEPROMPwDiff = (eprom_read(dev, (EEPROM_PwDiff>>1))&0x0f00)>>8;
2988 else
2989 priv->EEPROMPwDiff = EEPROM_Default_PwDiff;
2990 RT_TRACE(COMP_EPROM, "TxPwDiff:%d\n", priv->EEPROMPwDiff);
2991 // Read CrystalCap from EEPROM
2992 if (bLoad_From_EEPOM)
2993 priv->EEPROMCrystalCap = (eprom_read(dev, (EEPROM_CrystalCap>>1))&0x0f);
2994 else
2995 priv->EEPROMCrystalCap = EEPROM_Default_CrystalCap;
2996 RT_TRACE(COMP_EPROM, "CrystalCap = %d\n", priv->EEPROMCrystalCap);
2997 //get per-channel Tx power level
2998 if (bLoad_From_EEPOM)
2999 priv->EEPROM_Def_Ver = (eprom_read(dev, (EEPROM_TxPwIndex_Ver>>1))&0xff00)>>8;
3000 else
3001 priv->EEPROM_Def_Ver = 1;
3002 RT_TRACE(COMP_EPROM, "EEPROM_DEF_VER:%d\n", priv->EEPROM_Def_Ver);
3003 if (priv->EEPROM_Def_Ver == 0) //old eeprom definition
3005 int i;
3006 if (bLoad_From_EEPOM)
3007 priv->EEPROMTxPowerLevelCCK = (eprom_read(dev, (EEPROM_TxPwIndex_CCK>>1))&0xff) >> 8;
3008 else
3009 priv->EEPROMTxPowerLevelCCK = 0x10;
3010 RT_TRACE(COMP_EPROM, "CCK Tx Power Levl: 0x%02x\n", priv->EEPROMTxPowerLevelCCK);
3011 for (i=0; i<3; i++)
3013 if (bLoad_From_EEPOM)
3015 tmpValue = eprom_read(dev, (EEPROM_TxPwIndex_OFDM_24G+i)>>1);
3016 if (((EEPROM_TxPwIndex_OFDM_24G+i) % 2) == 0)
3017 tmpValue = tmpValue & 0x00ff;
3018 else
3019 tmpValue = (tmpValue & 0xff00) >> 8;
3021 else
3022 tmpValue = 0x10;
3023 priv->EEPROMTxPowerLevelOFDM24G[i] = (u8) tmpValue;
3024 RT_TRACE(COMP_EPROM, "OFDM 2.4G Tx Power Level, Index %d = 0x%02x\n", i, priv->EEPROMTxPowerLevelCCK);
3026 }//end if EEPROM_DEF_VER == 0
3027 else if (priv->EEPROM_Def_Ver == 1)
3029 if (bLoad_From_EEPOM)
3031 tmpValue = eprom_read(dev, (EEPROM_TxPwIndex_CCK_V1>>1));
3032 tmpValue = (tmpValue & 0xff00) >> 8;
3034 else
3035 tmpValue = 0x10;
3036 priv->EEPROMTxPowerLevelCCK_V1[0] = (u8)tmpValue;
3038 if (bLoad_From_EEPOM)
3039 tmpValue = eprom_read(dev, (EEPROM_TxPwIndex_CCK_V1 + 2)>>1);
3040 else
3041 tmpValue = 0x1010;
3042 *((u16*)(&priv->EEPROMTxPowerLevelCCK_V1[1])) = tmpValue;
3043 if (bLoad_From_EEPOM)
3044 tmpValue = eprom_read(dev, (EEPROM_TxPwIndex_OFDM_24G_V1>>1));
3045 else
3046 tmpValue = 0x1010;
3047 *((u16*)(&priv->EEPROMTxPowerLevelOFDM24G[0])) = tmpValue;
3048 if (bLoad_From_EEPOM)
3049 tmpValue = eprom_read(dev, (EEPROM_TxPwIndex_OFDM_24G_V1+2)>>1);
3050 else
3051 tmpValue = 0x10;
3052 priv->EEPROMTxPowerLevelOFDM24G[2] = (u8)tmpValue;
3053 }//endif EEPROM_Def_Ver == 1
3055 //update HAL variables
3058 int i;
3059 for (i=0; i<14; i++)
3061 if (i<=3)
3062 priv->TxPowerLevelOFDM24G[i] = priv->EEPROMTxPowerLevelOFDM24G[0];
3063 else if (i>=4 && i<=9)
3064 priv->TxPowerLevelOFDM24G[i] = priv->EEPROMTxPowerLevelOFDM24G[1];
3065 else
3066 priv->TxPowerLevelOFDM24G[i] = priv->EEPROMTxPowerLevelOFDM24G[2];
3069 for (i=0; i<14; i++)
3071 if (priv->EEPROM_Def_Ver == 0)
3073 if (i<=3)
3074 priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelOFDM24G[0] + (priv->EEPROMTxPowerLevelCCK - priv->EEPROMTxPowerLevelOFDM24G[1]);
3075 else if (i>=4 && i<=9)
3076 priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelCCK;
3077 else
3078 priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelOFDM24G[2] + (priv->EEPROMTxPowerLevelCCK - priv->EEPROMTxPowerLevelOFDM24G[1]);
3080 else if (priv->EEPROM_Def_Ver == 1)
3082 if (i<=3)
3083 priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelCCK_V1[0];
3084 else if (i>=4 && i<=9)
3085 priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelCCK_V1[1];
3086 else
3087 priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelCCK_V1[2];
3090 }//end update HAL variables
3091 priv->TxPowerDiff = priv->EEPROMPwDiff;
3092 // Antenna B gain offset to antenna A, bit0~3
3093 priv->AntennaTxPwDiff[0] = (priv->EEPROMTxPowerDiff & 0xf);
3094 // Antenna C gain offset to antenna A, bit4~7
3095 priv->AntennaTxPwDiff[1] = ((priv->EEPROMTxPowerDiff & 0xf0)>>4);
3096 // CrystalCap, bit12~15
3097 priv->CrystalCap = priv->EEPROMCrystalCap;
3098 // ThermalMeter, bit0~3 for RFIC1, bit4~7 for RFIC2
3099 // 92U does not enable TX power tracking.
3100 priv->ThermalMeter[0] = priv->EEPROMThermalMeter;
3101 }//end if VersionID == VERSION_819xU_A
3103 //added by vivi, for dlink led, 20080416
3104 switch(priv->eeprom_CustomerID)
3106 case EEPROM_CID_RUNTOP:
3107 priv->CustomerID = RT_CID_819x_RUNTOP;
3108 break;
3110 case EEPROM_CID_DLINK:
3111 priv->CustomerID = RT_CID_DLINK;
3112 break;
3114 default:
3115 priv->CustomerID = RT_CID_DEFAULT;
3116 break;
3120 switch(priv->CustomerID)
3122 case RT_CID_819x_RUNTOP:
3123 priv->LedStrategy = SW_LED_MODE2;
3124 break;
3126 case RT_CID_DLINK:
3127 priv->LedStrategy = SW_LED_MODE4;
3128 break;
3130 default:
3131 priv->LedStrategy = SW_LED_MODE0;
3132 break;
3137 if(priv->rf_type == RF_1T2R)
3139 RT_TRACE(COMP_EPROM, "\n1T2R config\n");
3141 else
3143 RT_TRACE(COMP_EPROM, "\n2T4R config\n");
3146 // 2008/01/16 MH We can only know RF type in the function. So we have to init
3147 // DIG RATR table again.
3148 init_rate_adaptive(dev);
3149 //we need init DIG RATR table here again.
3151 RT_TRACE(COMP_EPROM, "<===========%s()\n", __FUNCTION__);
3152 return;
3155 short rtl8192_get_channel_map(struct net_device * dev)
3157 struct r8192_priv *priv = ieee80211_priv(dev);
3158 #ifdef ENABLE_DOT11D
3159 if(priv->ChannelPlan > COUNTRY_CODE_GLOBAL_DOMAIN){
3160 printk("rtl8180_init:Error channel plan! Set to default.\n");
3161 priv->ChannelPlan= 0;
3163 RT_TRACE(COMP_INIT, "Channel plan is %d\n",priv->ChannelPlan);
3165 rtl819x_set_channel_map(priv->ChannelPlan, priv);
3166 #else
3167 int ch,i;
3168 //Set Default Channel Plan
3169 if(!channels){
3170 DMESG("No channels, aborting");
3171 return -1;
3173 ch=channels;
3174 priv->ChannelPlan= 0;//hikaru
3175 // set channels 1..14 allowed in given locale
3176 for (i=1; i<=14; i++) {
3177 (priv->ieee80211->channel_map)[i] = (u8)(ch & 0x01);
3178 ch >>= 1;
3180 #endif
3181 return 0;
3184 short rtl8192_init(struct net_device *dev)
3187 struct r8192_priv *priv = ieee80211_priv(dev);
3189 memset(&(priv->stats),0,sizeof(struct Stats));
3190 memset(priv->txqueue_to_outpipemap,0,9);
3191 #ifdef PIPE12
3193 int i=0;
3194 u8 queuetopipe[]={3,2,1,0,4,8,7,6,5};
3195 memcpy(priv->txqueue_to_outpipemap,queuetopipe,9);
3196 /* for(i=0;i<9;i++)
3197 printk("%d ",priv->txqueue_to_outpipemap[i]);
3198 printk("\n");*/
3200 #else
3202 u8 queuetopipe[]={3,2,1,0,4,4,0,4,4};
3203 memcpy(priv->txqueue_to_outpipemap,queuetopipe,9);
3204 /* for(i=0;i<9;i++)
3205 printk("%d ",priv->txqueue_to_outpipemap[i]);
3206 printk("\n");*/
3208 #endif
3209 rtl8192_init_priv_variable(dev);
3210 rtl8192_init_priv_lock(priv);
3211 rtl8192_init_priv_task(dev);
3212 rtl8192_get_eeprom_size(dev);
3213 rtl8192_read_eeprom_info(dev);
3214 rtl8192_get_channel_map(dev);
3215 init_hal_dm(dev);
3216 init_timer(&priv->watch_dog_timer);
3217 priv->watch_dog_timer.data = (unsigned long)dev;
3218 priv->watch_dog_timer.function = watch_dog_timer_callback;
3219 if(rtl8192_usb_initendpoints(dev)!=0){
3220 DMESG("Endopoints initialization failed");
3221 return -ENOMEM;
3224 //rtl8192_adapter_start(dev);
3225 #ifdef DEBUG_EPROM
3226 dump_eprom(dev);
3227 #endif
3228 return 0;
3231 /******************************************************************************
3232 *function: This function actually only set RRSR, RATR and BW_OPMODE registers
3233 * not to do all the hw config as its name says
3234 * input: net_device dev
3235 * output: none
3236 * return: none
3237 * notice: This part need to modified according to the rate set we filtered
3238 * ****************************************************************************/
3239 void rtl8192_hwconfig(struct net_device* dev)
3241 u32 regRATR = 0, regRRSR = 0;
3242 u8 regBwOpMode = 0, regTmp = 0;
3243 struct r8192_priv *priv = ieee80211_priv(dev);
3245 // Set RRSR, RATR, and BW_OPMODE registers
3247 switch(priv->ieee80211->mode)
3249 case WIRELESS_MODE_B:
3250 regBwOpMode = BW_OPMODE_20MHZ;
3251 regRATR = RATE_ALL_CCK;
3252 regRRSR = RATE_ALL_CCK;
3253 break;
3254 case WIRELESS_MODE_A:
3255 regBwOpMode = BW_OPMODE_5G |BW_OPMODE_20MHZ;
3256 regRATR = RATE_ALL_OFDM_AG;
3257 regRRSR = RATE_ALL_OFDM_AG;
3258 break;
3259 case WIRELESS_MODE_G:
3260 regBwOpMode = BW_OPMODE_20MHZ;
3261 regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
3262 regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
3263 break;
3264 case WIRELESS_MODE_AUTO:
3265 #ifdef TO_DO_LIST
3266 if (Adapter->bInHctTest)
3268 regBwOpMode = BW_OPMODE_20MHZ;
3269 regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
3270 regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
3272 else
3273 #endif
3275 regBwOpMode = BW_OPMODE_20MHZ;
3276 regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
3277 regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
3279 break;
3280 case WIRELESS_MODE_N_24G:
3281 // It support CCK rate by default.
3282 // CCK rate will be filtered out only when associated AP does not support it.
3283 regBwOpMode = BW_OPMODE_20MHZ;
3284 regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
3285 regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
3286 break;
3287 case WIRELESS_MODE_N_5G:
3288 regBwOpMode = BW_OPMODE_5G;
3289 regRATR = RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
3290 regRRSR = RATE_ALL_OFDM_AG;
3291 break;
3294 write_nic_byte(dev, BW_OPMODE, regBwOpMode);
3296 u32 ratr_value = 0;
3297 ratr_value = regRATR;
3298 if (priv->rf_type == RF_1T2R)
3300 ratr_value &= ~(RATE_ALL_OFDM_2SS);
3302 write_nic_dword(dev, RATR0, ratr_value);
3303 write_nic_byte(dev, UFWP, 1);
3305 regTmp = read_nic_byte(dev, 0x313);
3306 regRRSR = ((regTmp) << 24) | (regRRSR & 0x00ffffff);
3307 write_nic_dword(dev, RRSR, regRRSR);
3310 // Set Retry Limit here
3312 write_nic_word(dev, RETRY_LIMIT,
3313 priv->ShortRetryLimit << RETRY_LIMIT_SHORT_SHIFT | \
3314 priv->LongRetryLimit << RETRY_LIMIT_LONG_SHIFT);
3315 // Set Contention Window here
3317 // Set Tx AGC
3319 // Set Tx Antenna including Feedback control
3321 // Set Auto Rate fallback control
3327 //InitializeAdapter and PhyCfg
3328 bool rtl8192_adapter_start(struct net_device *dev)
3330 struct r8192_priv *priv = ieee80211_priv(dev);
3331 u32 dwRegRead = 0;
3332 bool init_status = true;
3333 RT_TRACE(COMP_INIT, "====>%s()\n", __FUNCTION__);
3334 priv->Rf_Mode = RF_OP_By_SW_3wire;
3335 //for ASIC power on sequence
3336 write_nic_byte_E(dev, 0x5f, 0x80);
3337 mdelay(50);
3338 write_nic_byte_E(dev, 0x5f, 0xf0);
3339 write_nic_byte_E(dev, 0x5d, 0x00);
3340 write_nic_byte_E(dev, 0x5e, 0x80);
3341 write_nic_byte(dev, 0x17, 0x37);
3342 mdelay(10);
3343 //#ifdef TO_DO_LIST
3344 priv->pFirmware->firmware_status = FW_STATUS_0_INIT;
3345 //config CPUReset Register
3346 //Firmware Reset or not?
3347 dwRegRead = read_nic_dword(dev, CPU_GEN);
3348 if (priv->pFirmware->firmware_status == FW_STATUS_0_INIT)
3349 dwRegRead |= CPU_GEN_SYSTEM_RESET; //do nothing here?
3350 else if (priv->pFirmware->firmware_status == FW_STATUS_5_READY)
3351 dwRegRead |= CPU_GEN_FIRMWARE_RESET;
3352 else
3353 RT_TRACE(COMP_ERR, "ERROR in %s(): undefined firmware state(%d)\n", __FUNCTION__, priv->pFirmware->firmware_status);
3355 write_nic_dword(dev, CPU_GEN, dwRegRead);
3356 //mdelay(30);
3357 //config BB.
3358 rtl8192_BBConfig(dev);
3360 //Loopback mode or not
3361 priv->LoopbackMode = RTL819xU_NO_LOOPBACK;
3362 // priv->LoopbackMode = RTL819xU_MAC_LOOPBACK;
3364 dwRegRead = read_nic_dword(dev, CPU_GEN);
3365 if (priv->LoopbackMode == RTL819xU_NO_LOOPBACK)
3366 dwRegRead = ((dwRegRead & CPU_GEN_NO_LOOPBACK_MSK) | CPU_GEN_NO_LOOPBACK_SET);
3367 else if (priv->LoopbackMode == RTL819xU_MAC_LOOPBACK)
3368 dwRegRead |= CPU_CCK_LOOPBACK;
3369 else
3370 RT_TRACE(COMP_ERR, "Serious error in %s(): wrong loopback mode setting(%d)\n", __FUNCTION__, priv->LoopbackMode);
3372 write_nic_dword(dev, CPU_GEN, dwRegRead);
3374 //after reset cpu, we need wait for a seconds to write in register.
3375 udelay(500);
3377 //xiong add for new bitfile:usb suspend reset pin set to 1. //do we need?
3378 write_nic_byte_E(dev, 0x5f, (read_nic_byte_E(dev, 0x5f)|0x20));
3380 //Set Hardware
3381 rtl8192_hwconfig(dev);
3383 //turn on Tx/Rx
3384 write_nic_byte(dev, CMDR, CR_RE|CR_TE);
3386 //set IDR0 here
3387 write_nic_dword(dev, MAC0, ((u32*)dev->dev_addr)[0]);
3388 write_nic_word(dev, MAC4, ((u16*)(dev->dev_addr + 4))[0]);
3390 //set RCR
3391 write_nic_dword(dev, RCR, priv->ReceiveConfig);
3393 //Initialize Number of Reserved Pages in Firmware Queue
3394 write_nic_dword(dev, RQPN1, NUM_OF_PAGE_IN_FW_QUEUE_BK << RSVD_FW_QUEUE_PAGE_BK_SHIFT |\
3395 NUM_OF_PAGE_IN_FW_QUEUE_BE << RSVD_FW_QUEUE_PAGE_BE_SHIFT | \
3396 NUM_OF_PAGE_IN_FW_QUEUE_VI << RSVD_FW_QUEUE_PAGE_VI_SHIFT | \
3397 NUM_OF_PAGE_IN_FW_QUEUE_VO <<RSVD_FW_QUEUE_PAGE_VO_SHIFT);
3398 write_nic_dword(dev, RQPN2, NUM_OF_PAGE_IN_FW_QUEUE_MGNT << RSVD_FW_QUEUE_PAGE_MGNT_SHIFT |\
3399 NUM_OF_PAGE_IN_FW_QUEUE_CMD << RSVD_FW_QUEUE_PAGE_CMD_SHIFT);
3400 write_nic_dword(dev, RQPN3, APPLIED_RESERVED_QUEUE_IN_FW| \
3401 NUM_OF_PAGE_IN_FW_QUEUE_BCN<<RSVD_FW_QUEUE_PAGE_BCN_SHIFT
3402 // | NUM_OF_PAGE_IN_FW_QUEUE_PUB<<RSVD_FW_QUEUE_PAGE_PUB_SHIFT
3404 write_nic_dword(dev, RATR0+4*7, (RATE_ALL_OFDM_AG | RATE_ALL_CCK));
3406 //Set AckTimeout
3407 // TODO: (it value is only for FPGA version). need to be changed!!2006.12.18, by Emily
3408 write_nic_byte(dev, ACK_TIMEOUT, 0x30);
3410 // RT_TRACE(COMP_INIT, "%s():priv->ResetProgress is %d\n", __FUNCTION__,priv->ResetProgress);
3411 if(priv->ResetProgress == RESET_TYPE_NORESET)
3412 rtl8192_SetWirelessMode(dev, priv->ieee80211->mode);
3413 if(priv->ResetProgress == RESET_TYPE_NORESET){
3414 CamResetAllEntry(dev);
3416 u8 SECR_value = 0x0;
3417 SECR_value |= SCR_TxEncEnable;
3418 SECR_value |= SCR_RxDecEnable;
3419 SECR_value |= SCR_NoSKMC;
3420 write_nic_byte(dev, SECR, SECR_value);
3424 //Beacon related
3425 write_nic_word(dev, ATIMWND, 2);
3426 write_nic_word(dev, BCN_INTERVAL, 100);
3429 #define DEFAULT_EDCA 0x005e4332
3430 int i;
3431 for (i=0; i<QOS_QUEUE_NUM; i++)
3432 write_nic_dword(dev, WDCAPARA_ADD[i], DEFAULT_EDCA);
3434 #ifdef USB_RX_AGGREGATION_SUPPORT
3435 //3 For usb rx firmware aggregation control
3436 if(priv->ResetProgress == RESET_TYPE_NORESET)
3438 u32 ulValue;
3439 PRT_HIGH_THROUGHPUT pHTInfo = priv->ieee80211->pHTInfo;
3440 ulValue = (pHTInfo->UsbRxFwAggrEn<<24) | (pHTInfo->UsbRxFwAggrPageNum<<16) |
3441 (pHTInfo->UsbRxFwAggrPacketNum<<8) | (pHTInfo->UsbRxFwAggrTimeout);
3443 * If usb rx firmware aggregation is enabled,
3444 * when anyone of three threshold conditions above is reached,
3445 * firmware will send aggregated packet to driver.
3447 write_nic_dword(dev, 0x1a8, ulValue);
3448 priv->bCurrentRxAggrEnable = true;
3450 #endif
3452 rtl8192_phy_configmac(dev);
3454 if (priv->card_8192_version == (u8) VERSION_819xU_A)
3456 rtl8192_phy_getTxPower(dev);
3457 rtl8192_phy_setTxPower(dev, priv->chan);
3460 //Firmware download
3461 init_status = init_firmware(dev);
3462 if(!init_status)
3464 RT_TRACE(COMP_ERR,"ERR!!! %s(): Firmware download is failed\n", __FUNCTION__);
3465 return init_status;
3467 RT_TRACE(COMP_INIT, "%s():after firmware download\n", __FUNCTION__);
3469 #ifdef TO_DO_LIST
3470 if(Adapter->ResetProgress == RESET_TYPE_NORESET)
3472 if(pMgntInfo->RegRfOff == TRUE)
3473 { // User disable RF via registry.
3474 RT_TRACE((COMP_INIT|COMP_RF), DBG_LOUD, ("InitializeAdapter819xUsb(): Turn off RF for RegRfOff ----------\n"));
3475 MgntActSet_RF_State(Adapter, eRfOff, RF_CHANGE_BY_SW);
3476 // Those action will be discard in MgntActSet_RF_State because off the same state
3477 for(eRFPath = 0; eRFPath <pHalData->NumTotalRFPath; eRFPath++)
3478 PHY_SetRFReg(Adapter, (RF90_RADIO_PATH_E)eRFPath, 0x4, 0xC00, 0x0);
3480 else if(pMgntInfo->RfOffReason > RF_CHANGE_BY_PS)
3481 { // H/W or S/W RF OFF before sleep.
3482 RT_TRACE((COMP_INIT|COMP_RF), DBG_LOUD, ("InitializeAdapter819xUsb(): Turn off RF for RfOffReason(%d) ----------\n", pMgntInfo->RfOffReason));
3483 MgntActSet_RF_State(Adapter, eRfOff, pMgntInfo->RfOffReason);
3485 else
3487 pHalData->eRFPowerState = eRfOn;
3488 pMgntInfo->RfOffReason = 0;
3489 RT_TRACE((COMP_INIT|COMP_RF), DBG_LOUD, ("InitializeAdapter819xUsb(): RF is on ----------\n"));
3492 else
3494 if(pHalData->eRFPowerState == eRfOff)
3496 MgntActSet_RF_State(Adapter, eRfOff, pMgntInfo->RfOffReason);
3497 // Those action will be discard in MgntActSet_RF_State because off the same state
3498 for(eRFPath = 0; eRFPath <pHalData->NumTotalRFPath; eRFPath++)
3499 PHY_SetRFReg(Adapter, (RF90_RADIO_PATH_E)eRFPath, 0x4, 0xC00, 0x0);
3502 #endif
3503 //config RF.
3504 if(priv->ResetProgress == RESET_TYPE_NORESET){
3505 rtl8192_phy_RFConfig(dev);
3506 RT_TRACE(COMP_INIT, "%s():after phy RF config\n", __FUNCTION__);
3510 if(priv->ieee80211->FwRWRF)
3511 // We can force firmware to do RF-R/W
3512 priv->Rf_Mode = RF_OP_By_FW;
3513 else
3514 priv->Rf_Mode = RF_OP_By_SW_3wire;
3517 rtl8192_phy_updateInitGain(dev);
3518 /*--set CCK and OFDM Block "ON"--*/
3519 rtl8192_setBBreg(dev, rFPGA0_RFMOD, bCCKEn, 0x1);
3520 rtl8192_setBBreg(dev, rFPGA0_RFMOD, bOFDMEn, 0x1);
3522 if(priv->ResetProgress == RESET_TYPE_NORESET)
3524 //if D or C cut
3525 u8 tmpvalue = read_nic_byte(dev, 0x301);
3526 if(tmpvalue ==0x03)
3528 priv->bDcut = TRUE;
3529 RT_TRACE(COMP_POWER_TRACKING, "D-cut\n");
3531 else
3533 priv->bDcut = FALSE;
3534 RT_TRACE(COMP_POWER_TRACKING, "C-cut\n");
3536 dm_initialize_txpower_tracking(dev);
3538 if(priv->bDcut == TRUE)
3540 u32 i, TempCCk;
3541 u32 tmpRegA= rtl8192_QueryBBReg(dev,rOFDM0_XATxIQImbalance,bMaskDWord);
3542 // u32 tmpRegC= rtl8192_QueryBBReg(dev,rOFDM0_XCTxIQImbalance,bMaskDWord);
3543 for(i = 0; i<TxBBGainTableLength; i++)
3545 if(tmpRegA == priv->txbbgain_table[i].txbbgain_value)
3547 priv->rfa_txpowertrackingindex= (u8)i;
3548 priv->rfa_txpowertrackingindex_real= (u8)i;
3549 priv->rfa_txpowertracking_default= priv->rfa_txpowertrackingindex;
3550 break;
3554 TempCCk = rtl8192_QueryBBReg(dev, rCCK0_TxFilter1, bMaskByte2);
3556 for(i=0 ; i<CCKTxBBGainTableLength ; i++)
3559 if(TempCCk == priv->cck_txbbgain_table[i].ccktxbb_valuearray[0])
3561 priv->cck_present_attentuation_20Mdefault=(u8) i;
3562 break;
3565 priv->cck_present_attentuation_40Mdefault= 0;
3566 priv->cck_present_attentuation_difference= 0;
3567 priv->cck_present_attentuation = priv->cck_present_attentuation_20Mdefault;
3569 // pMgntInfo->bTXPowerTracking = FALSE;//TEMPLY DISABLE
3572 write_nic_byte(dev, 0x87, 0x0);
3575 return init_status;
3578 /* this configures registers for beacon tx and enables it via
3579 * rtl8192_beacon_tx_enable(). rtl8192_beacon_tx_disable() might
3580 * be used to stop beacon transmission
3582 /***************************************************************************
3583 -------------------------------NET STUFF---------------------------
3584 ***************************************************************************/
3586 static struct net_device_stats *rtl8192_stats(struct net_device *dev)
3588 struct r8192_priv *priv = ieee80211_priv(dev);
3590 return &priv->ieee80211->stats;
3593 bool
3594 HalTxCheckStuck819xUsb(
3595 struct net_device *dev
3598 struct r8192_priv *priv = ieee80211_priv(dev);
3599 u16 RegTxCounter = read_nic_word(dev, 0x128);
3600 bool bStuck = FALSE;
3601 RT_TRACE(COMP_RESET,"%s():RegTxCounter is %d,TxCounter is %d\n",__FUNCTION__,RegTxCounter,priv->TxCounter);
3602 if(priv->TxCounter==RegTxCounter)
3603 bStuck = TRUE;
3605 priv->TxCounter = RegTxCounter;
3607 return bStuck;
3611 * <Assumption: RT_TX_SPINLOCK is acquired.>
3612 * First added: 2006.11.19 by emily
3614 RESET_TYPE
3615 TxCheckStuck(struct net_device *dev)
3617 struct r8192_priv *priv = ieee80211_priv(dev);
3618 u8 QueueID;
3619 // PRT_TCB pTcb;
3620 // u8 ResetThreshold;
3621 bool bCheckFwTxCnt = false;
3622 //unsigned long flags;
3625 // Decide Stuch threshold according to current power save mode
3628 // RT_TRACE(COMP_RESET, " ==> TxCheckStuck()\n");
3629 // PlatformAcquireSpinLock(Adapter, RT_TX_SPINLOCK);
3630 // spin_lock_irqsave(&priv->ieee80211->lock,flags);
3631 for (QueueID = 0; QueueID<=BEACON_QUEUE;QueueID ++)
3633 if(QueueID == TXCMD_QUEUE)
3634 continue;
3635 #ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
3636 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))
3637 #else
3638 if((skb_queue_len(&priv->ieee80211->skb_waitQ[QueueID]) == 0) && (skb_queue_len(&priv->ieee80211->skb_aggQ[QueueID]) == 0))
3639 #endif
3640 continue;
3642 bCheckFwTxCnt = true;
3644 // PlatformReleaseSpinLock(Adapter, RT_TX_SPINLOCK);
3645 // spin_unlock_irqrestore(&priv->ieee80211->lock,flags);
3646 // RT_TRACE(COMP_RESET,"bCheckFwTxCnt is %d\n",bCheckFwTxCnt);
3647 if(bCheckFwTxCnt)
3649 if(HalTxCheckStuck819xUsb(dev))
3651 RT_TRACE(COMP_RESET, "TxCheckStuck(): Fw indicates no Tx condition! \n");
3652 return RESET_TYPE_SILENT;
3655 return RESET_TYPE_NORESET;
3658 bool
3659 HalRxCheckStuck819xUsb(struct net_device *dev)
3661 u16 RegRxCounter = read_nic_word(dev, 0x130);
3662 struct r8192_priv *priv = ieee80211_priv(dev);
3663 bool bStuck = FALSE;
3664 static u8 rx_chk_cnt = 0;
3665 RT_TRACE(COMP_RESET,"%s(): RegRxCounter is %d,RxCounter is %d\n",__FUNCTION__,RegRxCounter,priv->RxCounter);
3666 // If rssi is small, we should check rx for long time because of bad rx.
3667 // or maybe it will continuous silent reset every 2 seconds.
3668 rx_chk_cnt++;
3669 if(priv->undecorated_smoothed_pwdb >= (RateAdaptiveTH_High+5))
3671 rx_chk_cnt = 0; //high rssi, check rx stuck right now.
3673 else if(priv->undecorated_smoothed_pwdb < (RateAdaptiveTH_High+5) &&
3674 ((priv->CurrentChannelBW!=HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb>=RateAdaptiveTH_Low_40M) ||
3675 (priv->CurrentChannelBW==HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb>=RateAdaptiveTH_Low_20M)) )
3677 if(rx_chk_cnt < 2)
3679 return bStuck;
3681 else
3683 rx_chk_cnt = 0;
3686 else if(((priv->CurrentChannelBW!=HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb<RateAdaptiveTH_Low_40M) ||
3687 (priv->CurrentChannelBW==HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb<RateAdaptiveTH_Low_20M)) &&
3688 priv->undecorated_smoothed_pwdb >= VeryLowRSSI)
3690 if(rx_chk_cnt < 4)
3692 //DbgPrint("RSSI < %d && RSSI >= %d, no check this time \n", RateAdaptiveTH_Low, VeryLowRSSI);
3693 return bStuck;
3695 else
3697 rx_chk_cnt = 0;
3698 //DbgPrint("RSSI < %d && RSSI >= %d, check this time \n", RateAdaptiveTH_Low, VeryLowRSSI);
3701 else
3703 if(rx_chk_cnt < 8)
3705 //DbgPrint("RSSI <= %d, no check this time \n", VeryLowRSSI);
3706 return bStuck;
3708 else
3710 rx_chk_cnt = 0;
3711 //DbgPrint("RSSI <= %d, check this time \n", VeryLowRSSI);
3715 if(priv->RxCounter==RegRxCounter)
3716 bStuck = TRUE;
3718 priv->RxCounter = RegRxCounter;
3720 return bStuck;
3723 RESET_TYPE
3724 RxCheckStuck(struct net_device *dev)
3726 struct r8192_priv *priv = ieee80211_priv(dev);
3727 //int i;
3728 bool bRxCheck = FALSE;
3730 // RT_TRACE(COMP_RESET," ==> RxCheckStuck()\n");
3731 //PlatformAcquireSpinLock(Adapter, RT_RX_SPINLOCK);
3733 if(priv->IrpPendingCount > 1)
3734 bRxCheck = TRUE;
3735 //PlatformReleaseSpinLock(Adapter, RT_RX_SPINLOCK);
3737 // RT_TRACE(COMP_RESET,"bRxCheck is %d \n",bRxCheck);
3738 if(bRxCheck)
3740 if(HalRxCheckStuck819xUsb(dev))
3742 RT_TRACE(COMP_RESET, "RxStuck Condition\n");
3743 return RESET_TYPE_SILENT;
3746 return RESET_TYPE_NORESET;
3751 * This function is called by Checkforhang to check whether we should ask OS to reset driver
3753 * \param pAdapter The adapter context for this miniport
3755 * Note:NIC with USB interface sholud not call this function because we cannot scan descriptor
3756 * to judge whether there is tx stuck.
3757 * Note: This function may be required to be rewrite for Vista OS.
3758 * <<<Assumption: Tx spinlock has been acquired >>>
3760 * 8185 and 8185b does not implement this function. This is added by Emily at 2006.11.24
3762 RESET_TYPE
3763 rtl819x_ifcheck_resetornot(struct net_device *dev)
3765 struct r8192_priv *priv = ieee80211_priv(dev);
3766 RESET_TYPE TxResetType = RESET_TYPE_NORESET;
3767 RESET_TYPE RxResetType = RESET_TYPE_NORESET;
3768 RT_RF_POWER_STATE rfState;
3770 rfState = priv->ieee80211->eRFPowerState;
3772 TxResetType = TxCheckStuck(dev);
3773 if( rfState != eRfOff ||
3774 /*ADAPTER_TEST_STATUS_FLAG(Adapter, ADAPTER_STATUS_FW_DOWNLOAD_FAILURE)) &&*/
3775 (priv->ieee80211->iw_mode != IW_MODE_ADHOC))
3777 // If driver is in the status of firmware download failure , driver skips RF initialization and RF is
3778 // in turned off state. Driver should check whether Rx stuck and do silent reset. And
3779 // if driver is in firmware download failure status, driver should initialize RF in the following
3780 // silent reset procedure Emily, 2008.01.21
3782 // Driver should not check RX stuck in IBSS mode because it is required to
3783 // set Check BSSID in order to send beacon, however, if check BSSID is
3784 // set, STA cannot hear any packet a all. Emily, 2008.04.12
3785 RxResetType = RxCheckStuck(dev);
3787 if(TxResetType==RESET_TYPE_NORMAL || RxResetType==RESET_TYPE_NORMAL)
3788 return RESET_TYPE_NORMAL;
3789 else if(TxResetType==RESET_TYPE_SILENT || RxResetType==RESET_TYPE_SILENT){
3790 RT_TRACE(COMP_RESET,"%s():silent reset\n",__FUNCTION__);
3791 return RESET_TYPE_SILENT;
3793 else
3794 return RESET_TYPE_NORESET;
3798 void rtl8192_cancel_deferred_work(struct r8192_priv* priv);
3799 int _rtl8192_up(struct net_device *dev);
3800 int rtl8192_close(struct net_device *dev);
3804 void
3805 CamRestoreAllEntry( struct net_device *dev)
3807 u8 EntryId = 0;
3808 struct r8192_priv *priv = ieee80211_priv(dev);
3809 u8* MacAddr = priv->ieee80211->current_network.bssid;
3811 static u8 CAM_CONST_ADDR[4][6] = {
3812 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
3813 {0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
3814 {0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
3815 {0x00, 0x00, 0x00, 0x00, 0x00, 0x03}};
3816 static u8 CAM_CONST_BROAD[] =
3817 {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
3819 RT_TRACE(COMP_SEC, "CamRestoreAllEntry: \n");
3822 if ((priv->ieee80211->pairwise_key_type == KEY_TYPE_WEP40)||
3823 (priv->ieee80211->pairwise_key_type == KEY_TYPE_WEP104))
3826 for(EntryId=0; EntryId<4; EntryId++)
3829 MacAddr = CAM_CONST_ADDR[EntryId];
3830 setKey(dev,
3831 EntryId ,
3832 EntryId,
3833 priv->ieee80211->pairwise_key_type,
3834 MacAddr,
3836 NULL);
3841 else if(priv->ieee80211->pairwise_key_type == KEY_TYPE_TKIP)
3845 if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
3846 setKey(dev,
3849 priv->ieee80211->pairwise_key_type,
3850 (u8*)dev->dev_addr,
3852 NULL);
3853 else
3854 setKey(dev,
3857 priv->ieee80211->pairwise_key_type,
3858 MacAddr,
3860 NULL);
3863 else if(priv->ieee80211->pairwise_key_type == KEY_TYPE_CCMP)
3867 if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
3868 setKey(dev,
3871 priv->ieee80211->pairwise_key_type,
3872 (u8*)dev->dev_addr,
3874 NULL);
3875 else
3876 setKey(dev,
3879 priv->ieee80211->pairwise_key_type,
3880 MacAddr,
3882 NULL);
3888 if(priv->ieee80211->group_key_type == KEY_TYPE_TKIP)
3890 MacAddr = CAM_CONST_BROAD;
3891 for(EntryId=1 ; EntryId<4 ; EntryId++)
3894 setKey(dev,
3895 EntryId,
3896 EntryId,
3897 priv->ieee80211->group_key_type,
3898 MacAddr,
3900 NULL);
3903 if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
3904 setKey(dev,
3907 priv->ieee80211->group_key_type,
3908 CAM_CONST_ADDR[0],
3910 NULL);
3912 else if(priv->ieee80211->group_key_type == KEY_TYPE_CCMP)
3914 MacAddr = CAM_CONST_BROAD;
3915 for(EntryId=1; EntryId<4 ; EntryId++)
3918 setKey(dev,
3919 EntryId ,
3920 EntryId,
3921 priv->ieee80211->group_key_type,
3922 MacAddr,
3924 NULL);
3928 if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
3929 setKey(dev,
3932 priv->ieee80211->group_key_type,
3933 CAM_CONST_ADDR[0],
3935 NULL);
3938 //////////////////////////////////////////////////////////////
3939 // This function is used to fix Tx/Rx stop bug temporarily.
3940 // This function will do "system reset" to NIC when Tx or Rx is stuck.
3941 // The method checking Tx/Rx stuck of this function is supported by FW,
3942 // which reports Tx and Rx counter to register 0x128 and 0x130.
3943 //////////////////////////////////////////////////////////////
3944 void
3945 rtl819x_ifsilentreset(struct net_device *dev)
3947 //OCTET_STRING asocpdu;
3948 struct r8192_priv *priv = ieee80211_priv(dev);
3949 u8 reset_times = 0;
3950 int reset_status = 0;
3951 struct ieee80211_device *ieee = priv->ieee80211;
3954 // 2007.07.20. If we need to check CCK stop, please uncomment this line.
3955 //bStuck = Adapter->HalFunc.CheckHWStopHandler(Adapter);
3957 if(priv->ResetProgress==RESET_TYPE_NORESET)
3959 RESET_START:
3961 RT_TRACE(COMP_RESET,"=========>Reset progress!! \n");
3963 // Set the variable for reset.
3964 priv->ResetProgress = RESET_TYPE_SILENT;
3965 // rtl8192_close(dev);
3966 down(&priv->wx_sem);
3967 if(priv->up == 0)
3969 RT_TRACE(COMP_ERR,"%s():the driver is not up! return\n",__FUNCTION__);
3970 up(&priv->wx_sem);
3971 return ;
3973 priv->up = 0;
3974 RT_TRACE(COMP_RESET,"%s():======>start to down the driver\n",__FUNCTION__);
3975 // if(!netif_queue_stopped(dev))
3976 // netif_stop_queue(dev);
3978 rtl8192_rtx_disable(dev);
3979 rtl8192_cancel_deferred_work(priv);
3980 deinit_hal_dm(dev);
3981 del_timer_sync(&priv->watch_dog_timer);
3983 ieee->sync_scan_hurryup = 1;
3984 if(ieee->state == IEEE80211_LINKED)
3986 down(&ieee->wx_sem);
3987 printk("ieee->state is IEEE80211_LINKED\n");
3988 ieee80211_stop_send_beacons(priv->ieee80211);
3989 del_timer_sync(&ieee->associate_timer);
3990 cancel_delayed_work(&ieee->associate_retry_wq);
3991 ieee80211_stop_scan(ieee);
3992 netif_carrier_off(dev);
3993 up(&ieee->wx_sem);
3995 else{
3996 printk("ieee->state is NOT LINKED\n");
3997 ieee80211_softmac_stop_protocol(priv->ieee80211); }
3998 up(&priv->wx_sem);
3999 RT_TRACE(COMP_RESET,"%s():<==========down process is finished\n",__FUNCTION__);
4000 //rtl8192_irq_disable(dev);
4001 RT_TRACE(COMP_RESET,"%s():===========>start to up the driver\n",__FUNCTION__);
4002 reset_status = _rtl8192_up(dev);
4004 RT_TRACE(COMP_RESET,"%s():<===========up process is finished\n",__FUNCTION__);
4005 if(reset_status == -EAGAIN)
4007 if(reset_times < 3)
4009 reset_times++;
4010 goto RESET_START;
4012 else
4014 RT_TRACE(COMP_ERR," ERR!!! %s(): Reset Failed!!\n", __FUNCTION__);
4017 ieee->is_silent_reset = 1;
4018 EnableHWSecurityConfig8192(dev);
4019 if(ieee->state == IEEE80211_LINKED && ieee->iw_mode == IW_MODE_INFRA)
4021 ieee->set_chan(ieee->dev, ieee->current_network.channel);
4023 queue_work(ieee->wq, &ieee->associate_complete_wq);
4026 else if(ieee->state == IEEE80211_LINKED && ieee->iw_mode == IW_MODE_ADHOC)
4028 ieee->set_chan(ieee->dev, ieee->current_network.channel);
4029 ieee->link_change(ieee->dev);
4031 // notify_wx_assoc_event(ieee);
4033 ieee80211_start_send_beacons(ieee);
4035 if (ieee->data_hard_resume)
4036 ieee->data_hard_resume(ieee->dev);
4037 netif_carrier_on(ieee->dev);
4040 CamRestoreAllEntry(dev);
4042 priv->ResetProgress = RESET_TYPE_NORESET;
4043 priv->reset_count++;
4045 priv->bForcedSilentReset =false;
4046 priv->bResetInProgress = false;
4048 // For test --> force write UFWP.
4049 write_nic_byte(dev, UFWP, 1);
4050 RT_TRACE(COMP_RESET, "Reset finished!! ====>[%d]\n", priv->reset_count);
4054 void CAM_read_entry(
4055 struct net_device *dev,
4056 u32 iIndex
4059 u32 target_command=0;
4060 u32 target_content=0;
4061 u8 entry_i=0;
4062 u32 ulStatus;
4063 s32 i=100;
4064 // printk("=======>start read CAM\n");
4065 for(entry_i=0;entry_i<CAM_CONTENT_COUNT;entry_i++)
4067 // polling bit, and No Write enable, and address
4068 target_command= entry_i+CAM_CONTENT_COUNT*iIndex;
4069 target_command= target_command | BIT31;
4071 //Check polling bit is clear
4072 // mdelay(1);
4073 while((i--)>=0)
4075 ulStatus = read_nic_dword(dev, RWCAM);
4076 if(ulStatus & BIT31){
4077 continue;
4079 else{
4080 break;
4083 write_nic_dword(dev, RWCAM, target_command);
4084 RT_TRACE(COMP_SEC,"CAM_read_entry(): WRITE A0: %x \n",target_command);
4085 // printk("CAM_read_entry(): WRITE A0: %lx \n",target_command);
4086 target_content = read_nic_dword(dev, RCAMO);
4087 RT_TRACE(COMP_SEC, "CAM_read_entry(): WRITE A8: %x \n",target_content);
4088 // printk("CAM_read_entry(): WRITE A8: %lx \n",target_content);
4090 printk("\n");
4093 void rtl819x_update_rxcounts(
4094 struct r8192_priv *priv,
4095 u32* TotalRxBcnNum,
4096 u32* TotalRxDataNum
4099 u16 SlotIndex;
4100 u8 i;
4102 *TotalRxBcnNum = 0;
4103 *TotalRxDataNum = 0;
4105 SlotIndex = (priv->ieee80211->LinkDetectInfo.SlotIndex++)%(priv->ieee80211->LinkDetectInfo.SlotNum);
4106 priv->ieee80211->LinkDetectInfo.RxBcnNum[SlotIndex] = priv->ieee80211->LinkDetectInfo.NumRecvBcnInPeriod;
4107 priv->ieee80211->LinkDetectInfo.RxDataNum[SlotIndex] = priv->ieee80211->LinkDetectInfo.NumRecvDataInPeriod;
4108 for( i=0; i<priv->ieee80211->LinkDetectInfo.SlotNum; i++ ){
4109 *TotalRxBcnNum += priv->ieee80211->LinkDetectInfo.RxBcnNum[i];
4110 *TotalRxDataNum += priv->ieee80211->LinkDetectInfo.RxDataNum[i];
4115 extern void rtl819x_watchdog_wqcallback(struct work_struct *work)
4117 struct delayed_work *dwork = container_of(work,struct delayed_work,work);
4118 struct r8192_priv *priv = container_of(dwork,struct r8192_priv,watch_dog_wq);
4119 struct net_device *dev = priv->ieee80211->dev;
4120 struct ieee80211_device* ieee = priv->ieee80211;
4121 RESET_TYPE ResetType = RESET_TYPE_NORESET;
4122 static u8 check_reset_cnt=0;
4123 bool bBusyTraffic = false;
4125 if(!priv->up)
4126 return;
4127 hal_dm_watchdog(dev);
4129 {//to get busy traffic condition
4130 if(ieee->state == IEEE80211_LINKED)
4132 if( ieee->LinkDetectInfo.NumRxOkInPeriod> 666 ||
4133 ieee->LinkDetectInfo.NumTxOkInPeriod> 666 ) {
4134 bBusyTraffic = true;
4136 ieee->LinkDetectInfo.NumRxOkInPeriod = 0;
4137 ieee->LinkDetectInfo.NumTxOkInPeriod = 0;
4138 ieee->LinkDetectInfo.bBusyTraffic = bBusyTraffic;
4141 //added by amy for AP roaming
4143 if(priv->ieee80211->state == IEEE80211_LINKED && priv->ieee80211->iw_mode == IW_MODE_INFRA)
4145 u32 TotalRxBcnNum = 0;
4146 u32 TotalRxDataNum = 0;
4148 rtl819x_update_rxcounts(priv, &TotalRxBcnNum, &TotalRxDataNum);
4149 if((TotalRxBcnNum+TotalRxDataNum) == 0)
4151 #ifdef TODO
4152 if(rfState == eRfOff)
4153 RT_TRACE(COMP_ERR,"========>%s()\n",__FUNCTION__);
4154 #endif
4155 printk("===>%s(): AP is power off,connect another one\n",__FUNCTION__);
4156 // Dot11d_Reset(dev);
4157 priv->ieee80211->state = IEEE80211_ASSOCIATING;
4158 notify_wx_assoc_event(priv->ieee80211);
4159 RemovePeerTS(priv->ieee80211,priv->ieee80211->current_network.bssid);
4160 priv->ieee80211->link_change(dev);
4161 queue_work(priv->ieee80211->wq, &priv->ieee80211->associate_procedure_wq);
4165 priv->ieee80211->LinkDetectInfo.NumRecvBcnInPeriod=0;
4166 priv->ieee80211->LinkDetectInfo.NumRecvDataInPeriod=0;
4168 // CAM_read_entry(dev,4);
4169 //check if reset the driver
4170 if(check_reset_cnt++ >= 3)
4172 ResetType = rtl819x_ifcheck_resetornot(dev);
4173 check_reset_cnt = 3;
4174 //DbgPrint("Start to check silent reset\n");
4176 // 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);
4177 if( (priv->force_reset) || (priv->ResetProgress==RESET_TYPE_NORESET &&
4178 (priv->bForcedSilentReset ||
4179 (!priv->bDisableNormalResetCheck && ResetType==RESET_TYPE_SILENT)))) // This is control by OID set in Pomelo
4181 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);
4182 rtl819x_ifsilentreset(dev);
4184 priv->force_reset = false;
4185 priv->bForcedSilentReset = false;
4186 priv->bResetInProgress = false;
4187 RT_TRACE(COMP_TRACE, " <==RtUsbCheckForHangWorkItemCallback()\n");
4191 void watch_dog_timer_callback(unsigned long data)
4193 struct r8192_priv *priv = ieee80211_priv((struct net_device *) data);
4194 //printk("===============>watch_dog timer\n");
4195 queue_delayed_work(priv->priv_wq,&priv->watch_dog_wq, 0);
4196 mod_timer(&priv->watch_dog_timer, jiffies + MSECS(IEEE80211_WATCH_DOG_TIME));
4198 int _rtl8192_up(struct net_device *dev)
4200 struct r8192_priv *priv = ieee80211_priv(dev);
4201 //int i;
4202 int init_status = 0;
4203 priv->up=1;
4204 priv->ieee80211->ieee_up=1;
4205 RT_TRACE(COMP_INIT, "Bringing up iface");
4206 init_status = rtl8192_adapter_start(dev);
4207 if(!init_status)
4209 RT_TRACE(COMP_ERR,"ERR!!! %s(): initialization is failed!\n", __FUNCTION__);
4210 priv->up=priv->ieee80211->ieee_up = 0;
4211 return -EAGAIN;
4213 RT_TRACE(COMP_INIT, "start adapter finished\n");
4214 rtl8192_rx_enable(dev);
4215 // rtl8192_tx_enable(dev);
4216 if(priv->ieee80211->state != IEEE80211_LINKED)
4217 ieee80211_softmac_start_protocol(priv->ieee80211);
4218 ieee80211_reset_queue(priv->ieee80211);
4219 watch_dog_timer_callback((unsigned long) dev);
4220 if(!netif_queue_stopped(dev))
4221 netif_start_queue(dev);
4222 else
4223 netif_wake_queue(dev);
4225 return 0;
4229 int rtl8192_open(struct net_device *dev)
4231 struct r8192_priv *priv = ieee80211_priv(dev);
4232 int ret;
4233 down(&priv->wx_sem);
4234 ret = rtl8192_up(dev);
4235 up(&priv->wx_sem);
4236 return ret;
4241 int rtl8192_up(struct net_device *dev)
4243 struct r8192_priv *priv = ieee80211_priv(dev);
4245 if (priv->up == 1) return -1;
4247 return _rtl8192_up(dev);
4251 int rtl8192_close(struct net_device *dev)
4253 struct r8192_priv *priv = ieee80211_priv(dev);
4254 int ret;
4256 down(&priv->wx_sem);
4258 ret = rtl8192_down(dev);
4260 up(&priv->wx_sem);
4262 return ret;
4266 int rtl8192_down(struct net_device *dev)
4268 struct r8192_priv *priv = ieee80211_priv(dev);
4269 int i;
4271 if (priv->up == 0) return -1;
4273 priv->up=0;
4274 priv->ieee80211->ieee_up = 0;
4275 RT_TRACE(COMP_DOWN, "==========>%s()\n", __FUNCTION__);
4276 /* FIXME */
4277 if (!netif_queue_stopped(dev))
4278 netif_stop_queue(dev);
4280 rtl8192_rtx_disable(dev);
4281 //rtl8192_irq_disable(dev);
4283 /* Tx related queue release */
4284 for(i = 0; i < MAX_QUEUE_SIZE; i++) {
4285 skb_queue_purge(&priv->ieee80211->skb_waitQ [i]);
4287 for(i = 0; i < MAX_QUEUE_SIZE; i++) {
4288 skb_queue_purge(&priv->ieee80211->skb_aggQ [i]);
4291 for(i = 0; i < MAX_QUEUE_SIZE; i++) {
4292 skb_queue_purge(&priv->ieee80211->skb_drv_aggQ [i]);
4295 //as cancel_delayed_work will del work->timer, so if work is not definedas struct delayed_work, it will corrupt
4296 // flush_scheduled_work();
4297 rtl8192_cancel_deferred_work(priv);
4298 deinit_hal_dm(dev);
4299 del_timer_sync(&priv->watch_dog_timer);
4302 ieee80211_softmac_stop_protocol(priv->ieee80211);
4303 memset(&priv->ieee80211->current_network, 0 , offsetof(struct ieee80211_network, list));
4304 RT_TRACE(COMP_DOWN, "<==========%s()\n", __FUNCTION__);
4306 return 0;
4310 void rtl8192_commit(struct net_device *dev)
4312 struct r8192_priv *priv = ieee80211_priv(dev);
4313 int reset_status = 0;
4314 //u8 reset_times = 0;
4315 if (priv->up == 0) return ;
4316 priv->up = 0;
4318 rtl8192_cancel_deferred_work(priv);
4319 del_timer_sync(&priv->watch_dog_timer);
4320 //cancel_delayed_work(&priv->SwChnlWorkItem);
4322 ieee80211_softmac_stop_protocol(priv->ieee80211);
4324 //rtl8192_irq_disable(dev);
4325 rtl8192_rtx_disable(dev);
4326 reset_status = _rtl8192_up(dev);
4331 void rtl8192_restart(struct net_device *dev)
4333 struct r8192_priv *priv = ieee80211_priv(dev);
4335 void rtl8192_restart(struct work_struct *work)
4337 struct r8192_priv *priv = container_of(work, struct r8192_priv, reset_wq);
4338 struct net_device *dev = priv->ieee80211->dev;
4340 down(&priv->wx_sem);
4342 rtl8192_commit(dev);
4344 up(&priv->wx_sem);
4347 static void r8192_set_multicast(struct net_device *dev)
4349 struct r8192_priv *priv = ieee80211_priv(dev);
4350 short promisc;
4352 //down(&priv->wx_sem);
4354 /* FIXME FIXME */
4356 promisc = (dev->flags & IFF_PROMISC) ? 1:0;
4358 if (promisc != priv->promisc)
4359 // rtl8192_commit(dev);
4361 priv->promisc = promisc;
4363 //schedule_work(&priv->reset_wq);
4364 //up(&priv->wx_sem);
4368 int r8192_set_mac_adr(struct net_device *dev, void *mac)
4370 struct r8192_priv *priv = ieee80211_priv(dev);
4371 struct sockaddr *addr = mac;
4373 down(&priv->wx_sem);
4375 memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
4377 schedule_work(&priv->reset_wq);
4378 up(&priv->wx_sem);
4380 return 0;
4383 /* based on ipw2200 driver */
4384 int rtl8192_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
4386 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
4387 struct iwreq *wrq = (struct iwreq *)rq;
4388 int ret=-1;
4389 struct ieee80211_device *ieee = priv->ieee80211;
4390 u32 key[4];
4391 u8 broadcast_addr[6] = {0xff,0xff,0xff,0xff,0xff,0xff};
4392 struct iw_point *p = &wrq->u.data;
4393 struct ieee_param *ipw = NULL;//(struct ieee_param *)wrq->u.data.pointer;
4395 down(&priv->wx_sem);
4398 if (p->length < sizeof(struct ieee_param) || !p->pointer){
4399 ret = -EINVAL;
4400 goto out;
4403 ipw = kmalloc(p->length, GFP_KERNEL);
4404 if (ipw == NULL){
4405 ret = -ENOMEM;
4406 goto out;
4408 if (copy_from_user(ipw, p->pointer, p->length)) {
4409 kfree(ipw);
4410 ret = -EFAULT;
4411 goto out;
4414 switch (cmd) {
4415 case RTL_IOCTL_WPA_SUPPLICANT:
4416 //parse here for HW security
4417 if (ipw->cmd == IEEE_CMD_SET_ENCRYPTION)
4419 if (ipw->u.crypt.set_tx)
4421 if (strcmp(ipw->u.crypt.alg, "CCMP") == 0)
4422 ieee->pairwise_key_type = KEY_TYPE_CCMP;
4423 else if (strcmp(ipw->u.crypt.alg, "TKIP") == 0)
4424 ieee->pairwise_key_type = KEY_TYPE_TKIP;
4425 else if (strcmp(ipw->u.crypt.alg, "WEP") == 0)
4427 if (ipw->u.crypt.key_len == 13)
4428 ieee->pairwise_key_type = KEY_TYPE_WEP104;
4429 else if (ipw->u.crypt.key_len == 5)
4430 ieee->pairwise_key_type = KEY_TYPE_WEP40;
4432 else
4433 ieee->pairwise_key_type = KEY_TYPE_NA;
4435 if (ieee->pairwise_key_type)
4437 memcpy((u8*)key, ipw->u.crypt.key, 16);
4438 EnableHWSecurityConfig8192(dev);
4439 //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!
4440 //added by WB.
4441 setKey(dev, 4, ipw->u.crypt.idx, ieee->pairwise_key_type, (u8*)ieee->ap_mac_addr, 0, key);
4442 if (ieee->auth_mode != 2)
4443 setKey(dev, ipw->u.crypt.idx, ipw->u.crypt.idx, ieee->pairwise_key_type, (u8*)ieee->ap_mac_addr, 0, key);
4446 else //if (ipw->u.crypt.idx) //group key use idx > 0
4448 memcpy((u8*)key, ipw->u.crypt.key, 16);
4449 if (strcmp(ipw->u.crypt.alg, "CCMP") == 0)
4450 ieee->group_key_type= KEY_TYPE_CCMP;
4451 else if (strcmp(ipw->u.crypt.alg, "TKIP") == 0)
4452 ieee->group_key_type = KEY_TYPE_TKIP;
4453 else if (strcmp(ipw->u.crypt.alg, "WEP") == 0)
4455 if (ipw->u.crypt.key_len == 13)
4456 ieee->group_key_type = KEY_TYPE_WEP104;
4457 else if (ipw->u.crypt.key_len == 5)
4458 ieee->group_key_type = KEY_TYPE_WEP40;
4460 else
4461 ieee->group_key_type = KEY_TYPE_NA;
4463 if (ieee->group_key_type)
4465 setKey( dev,
4466 ipw->u.crypt.idx,
4467 ipw->u.crypt.idx, //KeyIndex
4468 ieee->group_key_type, //KeyType
4469 broadcast_addr, //MacAddr
4470 0, //DefaultKey
4471 key); //KeyContent
4475 #ifdef JOHN_HWSEC_DEBUG
4476 //john's test 0711
4477 printk("@@ wrq->u pointer = ");
4478 for(i=0;i<wrq->u.data.length;i++){
4479 if(i%10==0) printk("\n");
4480 printk( "%8x|", ((u32*)wrq->u.data.pointer)[i] );
4482 printk("\n");
4483 #endif /*JOHN_HWSEC_DEBUG*/
4484 ret = ieee80211_wpa_supplicant_ioctl(priv->ieee80211, &wrq->u.data);
4485 break;
4487 default:
4488 ret = -EOPNOTSUPP;
4489 break;
4491 kfree(ipw);
4492 ipw = NULL;
4493 out:
4494 up(&priv->wx_sem);
4495 return ret;
4498 u8 HwRateToMRate90(bool bIsHT, u8 rate)
4500 u8 ret_rate = 0xff;
4502 if(!bIsHT) {
4503 switch(rate) {
4504 case DESC90_RATE1M: ret_rate = MGN_1M; break;
4505 case DESC90_RATE2M: ret_rate = MGN_2M; break;
4506 case DESC90_RATE5_5M: ret_rate = MGN_5_5M; break;
4507 case DESC90_RATE11M: ret_rate = MGN_11M; break;
4508 case DESC90_RATE6M: ret_rate = MGN_6M; break;
4509 case DESC90_RATE9M: ret_rate = MGN_9M; break;
4510 case DESC90_RATE12M: ret_rate = MGN_12M; break;
4511 case DESC90_RATE18M: ret_rate = MGN_18M; break;
4512 case DESC90_RATE24M: ret_rate = MGN_24M; break;
4513 case DESC90_RATE36M: ret_rate = MGN_36M; break;
4514 case DESC90_RATE48M: ret_rate = MGN_48M; break;
4515 case DESC90_RATE54M: ret_rate = MGN_54M; break;
4517 default:
4518 ret_rate = 0xff;
4519 RT_TRACE(COMP_RECV, "HwRateToMRate90(): Non supported Rate [%x], bIsHT = %d!!!\n", rate, bIsHT);
4520 break;
4523 } else {
4524 switch(rate) {
4525 case DESC90_RATEMCS0: ret_rate = MGN_MCS0; break;
4526 case DESC90_RATEMCS1: ret_rate = MGN_MCS1; break;
4527 case DESC90_RATEMCS2: ret_rate = MGN_MCS2; break;
4528 case DESC90_RATEMCS3: ret_rate = MGN_MCS3; break;
4529 case DESC90_RATEMCS4: ret_rate = MGN_MCS4; break;
4530 case DESC90_RATEMCS5: ret_rate = MGN_MCS5; break;
4531 case DESC90_RATEMCS6: ret_rate = MGN_MCS6; break;
4532 case DESC90_RATEMCS7: ret_rate = MGN_MCS7; break;
4533 case DESC90_RATEMCS8: ret_rate = MGN_MCS8; break;
4534 case DESC90_RATEMCS9: ret_rate = MGN_MCS9; break;
4535 case DESC90_RATEMCS10: ret_rate = MGN_MCS10; break;
4536 case DESC90_RATEMCS11: ret_rate = MGN_MCS11; break;
4537 case DESC90_RATEMCS12: ret_rate = MGN_MCS12; break;
4538 case DESC90_RATEMCS13: ret_rate = MGN_MCS13; break;
4539 case DESC90_RATEMCS14: ret_rate = MGN_MCS14; break;
4540 case DESC90_RATEMCS15: ret_rate = MGN_MCS15; break;
4541 case DESC90_RATEMCS32: ret_rate = (0x80|0x20); break;
4543 default:
4544 ret_rate = 0xff;
4545 RT_TRACE(COMP_RECV, "HwRateToMRate90(): Non supported Rate [%x], bIsHT = %d!!!\n",rate, bIsHT);
4546 break;
4550 return ret_rate;
4554 * Function: UpdateRxPktTimeStamp
4555 * Overview: Recored down the TSF time stamp when receiving a packet
4557 * Input:
4558 * PADAPTER Adapter
4559 * PRT_RFD pRfd,
4561 * Output:
4562 * PRT_RFD pRfd
4563 * (pRfd->Status.TimeStampHigh is updated)
4564 * (pRfd->Status.TimeStampLow is updated)
4565 * Return:
4566 * None
4568 void UpdateRxPktTimeStamp8190 (struct net_device *dev, struct ieee80211_rx_stats *stats)
4570 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
4572 if(stats->bIsAMPDU && !stats->bFirstMPDU) {
4573 stats->mac_time[0] = priv->LastRxDescTSFLow;
4574 stats->mac_time[1] = priv->LastRxDescTSFHigh;
4575 } else {
4576 priv->LastRxDescTSFLow = stats->mac_time[0];
4577 priv->LastRxDescTSFHigh = stats->mac_time[1];
4581 //by amy 080606
4583 long rtl819x_translate_todbm(u8 signal_strength_index )// 0-100 index.
4585 long signal_power; // in dBm.
4587 // Translate to dBm (x=0.5y-95).
4588 signal_power = (long)((signal_strength_index + 1) >> 1);
4589 signal_power -= 95;
4591 return signal_power;
4595 /* 2008/01/22 MH We can not delcare RSSI/EVM total value of sliding window to
4596 be a local static. Otherwise, it may increase when we return from S3/S4. The
4597 value will be kept in memory or disk. We must delcare the value in adapter
4598 and it will be reinitialized when return from S3/S4. */
4599 void rtl8192_process_phyinfo(struct r8192_priv * priv,u8* buffer, struct ieee80211_rx_stats * pprevious_stats, struct ieee80211_rx_stats * pcurrent_stats)
4601 bool bcheck = false;
4602 u8 rfpath;
4603 u32 nspatial_stream, tmp_val;
4604 //u8 i;
4605 static u32 slide_rssi_index=0, slide_rssi_statistics=0;
4606 static u32 slide_evm_index=0, slide_evm_statistics=0;
4607 static u32 last_rssi=0, last_evm=0;
4609 static u32 slide_beacon_adc_pwdb_index=0, slide_beacon_adc_pwdb_statistics=0;
4610 static u32 last_beacon_adc_pwdb=0;
4612 struct ieee80211_hdr_3addr *hdr;
4613 u16 sc ;
4614 unsigned int frag,seq;
4615 hdr = (struct ieee80211_hdr_3addr *)buffer;
4616 sc = le16_to_cpu(hdr->seq_ctl);
4617 frag = WLAN_GET_SEQ_FRAG(sc);
4618 seq = WLAN_GET_SEQ_SEQ(sc);
4619 //cosa add 04292008 to record the sequence number
4620 pcurrent_stats->Seq_Num = seq;
4622 // Check whether we should take the previous packet into accounting
4624 if(!pprevious_stats->bIsAMPDU)
4626 // if previous packet is not aggregated packet
4627 bcheck = true;
4628 }else
4633 if(slide_rssi_statistics++ >= PHY_RSSI_SLID_WIN_MAX)
4635 slide_rssi_statistics = PHY_RSSI_SLID_WIN_MAX;
4636 last_rssi = priv->stats.slide_signal_strength[slide_rssi_index];
4637 priv->stats.slide_rssi_total -= last_rssi;
4639 priv->stats.slide_rssi_total += pprevious_stats->SignalStrength;
4641 priv->stats.slide_signal_strength[slide_rssi_index++] = pprevious_stats->SignalStrength;
4642 if(slide_rssi_index >= PHY_RSSI_SLID_WIN_MAX)
4643 slide_rssi_index = 0;
4645 // <1> Showed on UI for user, in dbm
4646 tmp_val = priv->stats.slide_rssi_total/slide_rssi_statistics;
4647 priv->stats.signal_strength = rtl819x_translate_todbm((u8)tmp_val);
4648 pcurrent_stats->rssi = priv->stats.signal_strength;
4650 // If the previous packet does not match the criteria, neglect it
4652 if(!pprevious_stats->bPacketMatchBSSID)
4654 if(!pprevious_stats->bToSelfBA)
4655 return;
4658 if(!bcheck)
4659 return;
4662 //rtl8190_process_cck_rxpathsel(priv,pprevious_stats);//only rtl8190 supported
4665 // Check RSSI
4667 priv->stats.num_process_phyinfo++;
4669 /* record the general signal strength to the sliding window. */
4672 // <2> Showed on UI for engineering
4673 // hardware does not provide rssi information for each rf path in CCK
4674 if(!pprevious_stats->bIsCCK && (pprevious_stats->bPacketToSelf || pprevious_stats->bToSelfBA))
4676 for (rfpath = RF90_PATH_A; rfpath < priv->NumTotalRFPath; rfpath++)
4678 if (!rtl8192_phy_CheckIsLegalRFPath(priv->ieee80211->dev, rfpath))
4679 continue;
4681 //Fixed by Jacken 2008-03-20
4682 if(priv->stats.rx_rssi_percentage[rfpath] == 0)
4684 priv->stats.rx_rssi_percentage[rfpath] = pprevious_stats->RxMIMOSignalStrength[rfpath];
4685 //DbgPrint("MIMO RSSI initialize \n");
4687 if(pprevious_stats->RxMIMOSignalStrength[rfpath] > priv->stats.rx_rssi_percentage[rfpath])
4689 priv->stats.rx_rssi_percentage[rfpath] =
4690 ( (priv->stats.rx_rssi_percentage[rfpath]*(Rx_Smooth_Factor-1)) +
4691 (pprevious_stats->RxMIMOSignalStrength[rfpath])) /(Rx_Smooth_Factor);
4692 priv->stats.rx_rssi_percentage[rfpath] = priv->stats.rx_rssi_percentage[rfpath] + 1;
4694 else
4696 priv->stats.rx_rssi_percentage[rfpath] =
4697 ( (priv->stats.rx_rssi_percentage[rfpath]*(Rx_Smooth_Factor-1)) +
4698 (pprevious_stats->RxMIMOSignalStrength[rfpath])) /(Rx_Smooth_Factor);
4700 RT_TRACE(COMP_DBG,"priv->stats.rx_rssi_percentage[rfPath] = %d \n" ,priv->stats.rx_rssi_percentage[rfpath] );
4706 // Check PWDB.
4708 RT_TRACE(COMP_RXDESC, "Smooth %s PWDB = %d\n",
4709 pprevious_stats->bIsCCK? "CCK": "OFDM",
4710 pprevious_stats->RxPWDBAll);
4712 if(pprevious_stats->bPacketBeacon)
4714 /* record the beacon pwdb to the sliding window. */
4715 if(slide_beacon_adc_pwdb_statistics++ >= PHY_Beacon_RSSI_SLID_WIN_MAX)
4717 slide_beacon_adc_pwdb_statistics = PHY_Beacon_RSSI_SLID_WIN_MAX;
4718 last_beacon_adc_pwdb = priv->stats.Slide_Beacon_pwdb[slide_beacon_adc_pwdb_index];
4719 priv->stats.Slide_Beacon_Total -= last_beacon_adc_pwdb;
4720 //DbgPrint("slide_beacon_adc_pwdb_index = %d, last_beacon_adc_pwdb = %d, Adapter->RxStats.Slide_Beacon_Total = %d\n",
4721 // slide_beacon_adc_pwdb_index, last_beacon_adc_pwdb, Adapter->RxStats.Slide_Beacon_Total);
4723 priv->stats.Slide_Beacon_Total += pprevious_stats->RxPWDBAll;
4724 priv->stats.Slide_Beacon_pwdb[slide_beacon_adc_pwdb_index] = pprevious_stats->RxPWDBAll;
4725 //DbgPrint("slide_beacon_adc_pwdb_index = %d, pPreviousRfd->Status.RxPWDBAll = %d\n", slide_beacon_adc_pwdb_index, pPreviousRfd->Status.RxPWDBAll);
4726 slide_beacon_adc_pwdb_index++;
4727 if(slide_beacon_adc_pwdb_index >= PHY_Beacon_RSSI_SLID_WIN_MAX)
4728 slide_beacon_adc_pwdb_index = 0;
4729 pprevious_stats->RxPWDBAll = priv->stats.Slide_Beacon_Total/slide_beacon_adc_pwdb_statistics;
4730 if(pprevious_stats->RxPWDBAll >= 3)
4731 pprevious_stats->RxPWDBAll -= 3;
4734 RT_TRACE(COMP_RXDESC, "Smooth %s PWDB = %d\n",
4735 pprevious_stats->bIsCCK? "CCK": "OFDM",
4736 pprevious_stats->RxPWDBAll);
4739 if(pprevious_stats->bPacketToSelf || pprevious_stats->bPacketBeacon || pprevious_stats->bToSelfBA)
4741 if(priv->undecorated_smoothed_pwdb < 0) // initialize
4743 priv->undecorated_smoothed_pwdb = pprevious_stats->RxPWDBAll;
4744 //DbgPrint("First pwdb initialize \n");
4746 if(pprevious_stats->RxPWDBAll > (u32)priv->undecorated_smoothed_pwdb)
4748 priv->undecorated_smoothed_pwdb =
4749 ( ((priv->undecorated_smoothed_pwdb)*(Rx_Smooth_Factor-1)) +
4750 (pprevious_stats->RxPWDBAll)) /(Rx_Smooth_Factor);
4751 priv->undecorated_smoothed_pwdb = priv->undecorated_smoothed_pwdb + 1;
4753 else
4755 priv->undecorated_smoothed_pwdb =
4756 ( ((priv->undecorated_smoothed_pwdb)*(Rx_Smooth_Factor-1)) +
4757 (pprevious_stats->RxPWDBAll)) /(Rx_Smooth_Factor);
4763 // Check EVM
4765 /* record the general EVM to the sliding window. */
4766 if(pprevious_stats->SignalQuality == 0)
4769 else
4771 if(pprevious_stats->bPacketToSelf || pprevious_stats->bPacketBeacon || pprevious_stats->bToSelfBA){
4772 if(slide_evm_statistics++ >= PHY_RSSI_SLID_WIN_MAX){
4773 slide_evm_statistics = PHY_RSSI_SLID_WIN_MAX;
4774 last_evm = priv->stats.slide_evm[slide_evm_index];
4775 priv->stats.slide_evm_total -= last_evm;
4778 priv->stats.slide_evm_total += pprevious_stats->SignalQuality;
4780 priv->stats.slide_evm[slide_evm_index++] = pprevious_stats->SignalQuality;
4781 if(slide_evm_index >= PHY_RSSI_SLID_WIN_MAX)
4782 slide_evm_index = 0;
4784 // <1> Showed on UI for user, in percentage.
4785 tmp_val = priv->stats.slide_evm_total/slide_evm_statistics;
4786 priv->stats.signal_quality = tmp_val;
4787 //cosa add 10/11/2007, Showed on UI for user in Windows Vista, for Link quality.
4788 priv->stats.last_signal_strength_inpercent = tmp_val;
4791 // <2> Showed on UI for engineering
4792 if(pprevious_stats->bPacketToSelf || pprevious_stats->bPacketBeacon || pprevious_stats->bToSelfBA)
4794 for(nspatial_stream = 0; nspatial_stream<2 ; nspatial_stream++) // 2 spatial stream
4796 if(pprevious_stats->RxMIMOSignalQuality[nspatial_stream] != -1)
4798 if(priv->stats.rx_evm_percentage[nspatial_stream] == 0) // initialize
4800 priv->stats.rx_evm_percentage[nspatial_stream] = pprevious_stats->RxMIMOSignalQuality[nspatial_stream];
4802 priv->stats.rx_evm_percentage[nspatial_stream] =
4803 ( (priv->stats.rx_evm_percentage[nspatial_stream]* (Rx_Smooth_Factor-1)) +
4804 (pprevious_stats->RxMIMOSignalQuality[nspatial_stream]* 1)) / (Rx_Smooth_Factor);
4813 /*-----------------------------------------------------------------------------
4814 * Function: rtl819x_query_rxpwrpercentage()
4816 * Overview:
4818 * Input: char antpower
4820 * Output: NONE
4822 * Return: 0-100 percentage
4824 * Revised History:
4825 * When Who Remark
4826 * 05/26/2008 amy Create Version 0 porting from windows code.
4828 *---------------------------------------------------------------------------*/
4829 static u8 rtl819x_query_rxpwrpercentage(
4830 char antpower
4833 if ((antpower <= -100) || (antpower >= 20))
4835 return 0;
4837 else if (antpower >= 0)
4839 return 100;
4841 else
4843 return (100+antpower);
4846 } /* QueryRxPwrPercentage */
4848 static u8
4849 rtl819x_evm_dbtopercentage(
4850 char value
4853 char ret_val;
4855 ret_val = value;
4857 if(ret_val >= 0)
4858 ret_val = 0;
4859 if(ret_val <= -33)
4860 ret_val = -33;
4861 ret_val = 0 - ret_val;
4862 ret_val*=3;
4863 if(ret_val == 99)
4864 ret_val = 100;
4865 return(ret_val);
4868 // Description:
4869 // We want good-looking for signal strength/quality
4870 // 2007/7/19 01:09, by cosa.
4872 long
4873 rtl819x_signal_scale_mapping(
4874 long currsig
4877 long retsig;
4879 // Step 1. Scale mapping.
4880 if(currsig >= 61 && currsig <= 100)
4882 retsig = 90 + ((currsig - 60) / 4);
4884 else if(currsig >= 41 && currsig <= 60)
4886 retsig = 78 + ((currsig - 40) / 2);
4888 else if(currsig >= 31 && currsig <= 40)
4890 retsig = 66 + (currsig - 30);
4892 else if(currsig >= 21 && currsig <= 30)
4894 retsig = 54 + (currsig - 20);
4896 else if(currsig >= 5 && currsig <= 20)
4898 retsig = 42 + (((currsig - 5) * 2) / 3);
4900 else if(currsig == 4)
4902 retsig = 36;
4904 else if(currsig == 3)
4906 retsig = 27;
4908 else if(currsig == 2)
4910 retsig = 18;
4912 else if(currsig == 1)
4914 retsig = 9;
4916 else
4918 retsig = currsig;
4921 return retsig;
4924 static void rtl8192_query_rxphystatus(
4925 struct r8192_priv * priv,
4926 struct ieee80211_rx_stats * pstats,
4927 rx_drvinfo_819x_usb * pdrvinfo,
4928 struct ieee80211_rx_stats * precord_stats,
4929 bool bpacket_match_bssid,
4930 bool bpacket_toself,
4931 bool bPacketBeacon,
4932 bool bToSelfBA
4935 //PRT_RFD_STATUS pRtRfdStatus = &(pRfd->Status);
4936 phy_sts_ofdm_819xusb_t* pofdm_buf;
4937 phy_sts_cck_819xusb_t * pcck_buf;
4938 phy_ofdm_rx_status_rxsc_sgien_exintfflag* prxsc;
4939 u8 *prxpkt;
4940 u8 i, max_spatial_stream, tmp_rxsnr, tmp_rxevm, rxsc_sgien_exflg;
4941 char rx_pwr[4], rx_pwr_all=0;
4942 //long rx_avg_pwr = 0;
4943 char rx_snrX, rx_evmX;
4944 u8 evm, pwdb_all;
4945 u32 RSSI, total_rssi=0;//, total_evm=0;
4946 // long signal_strength_index = 0;
4947 u8 is_cck_rate=0;
4948 u8 rf_rx_num = 0;
4951 priv->stats.numqry_phystatus++;
4953 is_cck_rate = rx_hal_is_cck_rate(pdrvinfo);
4955 // Record it for next packet processing
4956 memset(precord_stats, 0, sizeof(struct ieee80211_rx_stats));
4957 pstats->bPacketMatchBSSID = precord_stats->bPacketMatchBSSID = bpacket_match_bssid;
4958 pstats->bPacketToSelf = precord_stats->bPacketToSelf = bpacket_toself;
4959 pstats->bIsCCK = precord_stats->bIsCCK = is_cck_rate;//RX_HAL_IS_CCK_RATE(pDrvInfo);
4960 pstats->bPacketBeacon = precord_stats->bPacketBeacon = bPacketBeacon;
4961 pstats->bToSelfBA = precord_stats->bToSelfBA = bToSelfBA;
4963 prxpkt = (u8*)pdrvinfo;
4965 /* Move pointer to the 16th bytes. Phy status start address. */
4966 prxpkt += sizeof(rx_drvinfo_819x_usb);
4968 /* Initial the cck and ofdm buffer pointer */
4969 pcck_buf = (phy_sts_cck_819xusb_t *)prxpkt;
4970 pofdm_buf = (phy_sts_ofdm_819xusb_t *)prxpkt;
4972 pstats->RxMIMOSignalQuality[0] = -1;
4973 pstats->RxMIMOSignalQuality[1] = -1;
4974 precord_stats->RxMIMOSignalQuality[0] = -1;
4975 precord_stats->RxMIMOSignalQuality[1] = -1;
4977 if(is_cck_rate)
4980 // (1)Hardware does not provide RSSI for CCK
4984 // (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive)
4986 u8 report;//, cck_agc_rpt;
4988 priv->stats.numqry_phystatusCCK++;
4990 if(!priv->bCckHighPower)
4992 report = pcck_buf->cck_agc_rpt & 0xc0;
4993 report = report>>6;
4994 switch(report)
4996 //Fixed by Jacken from Bryant 2008-03-20
4997 //Original value is -38 , -26 , -14 , -2
4998 //Fixed value is -35 , -23 , -11 , 6
4999 case 0x3:
5000 rx_pwr_all = -35 - (pcck_buf->cck_agc_rpt & 0x3e);
5001 break;
5002 case 0x2:
5003 rx_pwr_all = -23 - (pcck_buf->cck_agc_rpt & 0x3e);
5004 break;
5005 case 0x1:
5006 rx_pwr_all = -11 - (pcck_buf->cck_agc_rpt & 0x3e);
5007 break;
5008 case 0x0:
5009 rx_pwr_all = 6 - (pcck_buf->cck_agc_rpt & 0x3e);
5010 break;
5013 else
5015 report = pcck_buf->cck_agc_rpt & 0x60;
5016 report = report>>5;
5017 switch(report)
5019 case 0x3:
5020 rx_pwr_all = -35 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1) ;
5021 break;
5022 case 0x2:
5023 rx_pwr_all = -23 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1);
5024 break;
5025 case 0x1:
5026 rx_pwr_all = -11 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1) ;
5027 break;
5028 case 0x0:
5029 rx_pwr_all = 6 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1) ;
5030 break;
5034 pwdb_all = rtl819x_query_rxpwrpercentage(rx_pwr_all);
5035 pstats->RxPWDBAll = precord_stats->RxPWDBAll = pwdb_all;
5036 pstats->RecvSignalPower = pwdb_all;
5039 // (3) Get Signal Quality (EVM)
5041 //if(bpacket_match_bssid)
5043 u8 sq;
5045 if(pstats->RxPWDBAll > 40)
5047 sq = 100;
5048 }else
5050 sq = pcck_buf->sq_rpt;
5052 if(pcck_buf->sq_rpt > 64)
5053 sq = 0;
5054 else if (pcck_buf->sq_rpt < 20)
5055 sq = 100;
5056 else
5057 sq = ((64-sq) * 100) / 44;
5059 pstats->SignalQuality = precord_stats->SignalQuality = sq;
5060 pstats->RxMIMOSignalQuality[0] = precord_stats->RxMIMOSignalQuality[0] = sq;
5061 pstats->RxMIMOSignalQuality[1] = precord_stats->RxMIMOSignalQuality[1] = -1;
5064 else
5066 priv->stats.numqry_phystatusHT++;
5068 // (1)Get RSSI for HT rate
5070 for(i=RF90_PATH_A; i<priv->NumTotalRFPath; i++)
5072 // 2008/01/30 MH we will judge RF RX path now.
5073 if (priv->brfpath_rxenable[i])
5074 rf_rx_num++;
5075 else
5076 continue;
5078 if (!rtl8192_phy_CheckIsLegalRFPath(priv->ieee80211->dev, i))
5079 continue;
5081 //Fixed by Jacken from Bryant 2008-03-20
5082 //Original value is 106
5083 rx_pwr[i] = ((pofdm_buf->trsw_gain_X[i]&0x3F)*2) - 106;
5085 //Get Rx snr value in DB
5086 tmp_rxsnr = pofdm_buf->rxsnr_X[i];
5087 rx_snrX = (char)(tmp_rxsnr);
5088 //rx_snrX >>= 1;
5089 rx_snrX /= 2;
5090 priv->stats.rxSNRdB[i] = (long)rx_snrX;
5092 /* Translate DBM to percentage. */
5093 RSSI = rtl819x_query_rxpwrpercentage(rx_pwr[i]);
5094 total_rssi += RSSI;
5096 /* Record Signal Strength for next packet */
5097 //if(bpacket_match_bssid)
5099 pstats->RxMIMOSignalStrength[i] =(u8) RSSI;
5100 precord_stats->RxMIMOSignalStrength[i] =(u8) RSSI;
5106 // (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive)
5108 //Fixed by Jacken from Bryant 2008-03-20
5109 //Original value is 106
5110 rx_pwr_all = (((pofdm_buf->pwdb_all ) >> 1 )& 0x7f) -106;
5111 pwdb_all = rtl819x_query_rxpwrpercentage(rx_pwr_all);
5113 pstats->RxPWDBAll = precord_stats->RxPWDBAll = pwdb_all;
5114 pstats->RxPower = precord_stats->RxPower = rx_pwr_all;
5117 // (3)EVM of HT rate
5119 if(pdrvinfo->RxHT && pdrvinfo->RxRate>=DESC90_RATEMCS8 &&
5120 pdrvinfo->RxRate<=DESC90_RATEMCS15)
5121 max_spatial_stream = 2; //both spatial stream make sense
5122 else
5123 max_spatial_stream = 1; //only spatial stream 1 makes sense
5125 for(i=0; i<max_spatial_stream; i++)
5127 tmp_rxevm = pofdm_buf->rxevm_X[i];
5128 rx_evmX = (char)(tmp_rxevm);
5130 // Do not use shift operation like "rx_evmX >>= 1" because the compilor of free build environment
5131 // fill most significant bit to "zero" when doing shifting operation which may change a negative
5132 // value to positive one, then the dbm value (which is supposed to be negative) is not correct anymore.
5133 rx_evmX /= 2; //dbm
5135 evm = rtl819x_evm_dbtopercentage(rx_evmX);
5136 //if(bpacket_match_bssid)
5138 if(i==0) // Fill value in RFD, Get the first spatial stream only
5139 pstats->SignalQuality = precord_stats->SignalQuality = (u8)(evm & 0xff);
5140 pstats->RxMIMOSignalQuality[i] = precord_stats->RxMIMOSignalQuality[i] = (u8)(evm & 0xff);
5145 /* record rx statistics for debug */
5146 rxsc_sgien_exflg = pofdm_buf->rxsc_sgien_exflg;
5147 prxsc = (phy_ofdm_rx_status_rxsc_sgien_exintfflag *)&rxsc_sgien_exflg;
5148 if(pdrvinfo->BW) //40M channel
5149 priv->stats.received_bwtype[1+prxsc->rxsc]++;
5150 else //20M channel
5151 priv->stats.received_bwtype[0]++;
5154 //UI BSS List signal strength(in percentage), make it good looking, from 0~100.
5155 //It is assigned to the BSS List in GetValueFromBeaconOrProbeRsp().
5156 if(is_cck_rate)
5158 pstats->SignalStrength = precord_stats->SignalStrength = (u8)(rtl819x_signal_scale_mapping((long)pwdb_all));//PWDB_ALL;
5161 else
5163 //pRfd->Status.SignalStrength = pRecordRfd->Status.SignalStrength = (u8)(SignalScaleMapping(total_rssi/=RF90_PATH_MAX));//(u8)(total_rssi/=RF90_PATH_MAX);
5164 // We can judge RX path number now.
5165 if (rf_rx_num != 0)
5166 pstats->SignalStrength = precord_stats->SignalStrength = (u8)(rtl819x_signal_scale_mapping((long)(total_rssi/=rf_rx_num)));
5168 } /* QueryRxPhyStatus8190Pci */
5170 void
5171 rtl8192_record_rxdesc_forlateruse(
5172 struct ieee80211_rx_stats * psrc_stats,
5173 struct ieee80211_rx_stats * ptarget_stats
5176 ptarget_stats->bIsAMPDU = psrc_stats->bIsAMPDU;
5177 ptarget_stats->bFirstMPDU = psrc_stats->bFirstMPDU;
5178 ptarget_stats->Seq_Num = psrc_stats->Seq_Num;
5182 void TranslateRxSignalStuff819xUsb(struct sk_buff *skb,
5183 struct ieee80211_rx_stats * pstats,
5184 rx_drvinfo_819x_usb *pdrvinfo)
5186 // TODO: We must only check packet for current MAC address. Not finish
5187 rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
5188 struct net_device *dev=info->dev;
5189 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
5190 bool bpacket_match_bssid, bpacket_toself;
5191 bool bPacketBeacon=FALSE, bToSelfBA=FALSE;
5192 static struct ieee80211_rx_stats previous_stats;
5193 struct ieee80211_hdr_3addr *hdr;//by amy
5194 u16 fc,type;
5196 // Get Signal Quality for only RX data queue (but not command queue)
5198 u8* tmp_buf;
5199 //u16 tmp_buf_len = 0;
5200 u8 *praddr;
5202 /* Get MAC frame start address. */
5203 tmp_buf = (u8*)skb->data;// + get_rxpacket_shiftbytes_819xusb(pstats);
5205 hdr = (struct ieee80211_hdr_3addr *)tmp_buf;
5206 fc = le16_to_cpu(hdr->frame_ctl);
5207 type = WLAN_FC_GET_TYPE(fc);
5208 praddr = hdr->addr1;
5210 /* Check if the received packet is acceptabe. */
5211 bpacket_match_bssid = ((IEEE80211_FTYPE_CTL != type) &&
5212 (eqMacAddr(priv->ieee80211->current_network.bssid, (fc & IEEE80211_FCTL_TODS)? hdr->addr1 : (fc & IEEE80211_FCTL_FROMDS )? hdr->addr2 : hdr->addr3))
5213 && (!pstats->bHwError) && (!pstats->bCRC)&& (!pstats->bICV));
5214 bpacket_toself = bpacket_match_bssid & (eqMacAddr(praddr, priv->ieee80211->dev->dev_addr));
5216 if(WLAN_FC_GET_FRAMETYPE(fc)== IEEE80211_STYPE_BEACON)
5218 bPacketBeacon = true;
5219 //DbgPrint("Beacon 2, MatchBSSID = %d, ToSelf = %d \n", bPacketMatchBSSID, bPacketToSelf);
5221 if(WLAN_FC_GET_FRAMETYPE(fc) == IEEE80211_STYPE_BLOCKACK)
5223 if((eqMacAddr(praddr,dev->dev_addr)))
5224 bToSelfBA = true;
5225 //DbgPrint("BlockAck, MatchBSSID = %d, ToSelf = %d \n", bPacketMatchBSSID, bPacketToSelf);
5230 if(bpacket_match_bssid)
5232 priv->stats.numpacket_matchbssid++;
5234 if(bpacket_toself){
5235 priv->stats.numpacket_toself++;
5238 // Process PHY information for previous packet (RSSI/PWDB/EVM)
5240 // Because phy information is contained in the last packet of AMPDU only, so driver
5241 // should process phy information of previous packet
5242 rtl8192_process_phyinfo(priv, tmp_buf, &previous_stats, pstats);
5243 rtl8192_query_rxphystatus(priv, pstats, pdrvinfo, &previous_stats, bpacket_match_bssid,bpacket_toself,bPacketBeacon,bToSelfBA);
5244 rtl8192_record_rxdesc_forlateruse(pstats, &previous_stats);
5249 * Function: UpdateReceivedRateHistogramStatistics
5250 * Overview: Recored down the received data rate
5252 * Input:
5253 * struct net_device *dev
5254 * struct ieee80211_rx_stats *stats
5256 * Output:
5258 * (priv->stats.ReceivedRateHistogram[] is updated)
5259 * Return:
5260 * None
5262 void
5263 UpdateReceivedRateHistogramStatistics8190(
5264 struct net_device *dev,
5265 struct ieee80211_rx_stats *stats
5268 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
5269 u32 rcvType=1; //0: Total, 1:OK, 2:CRC, 3:ICV
5270 u32 rateIndex;
5271 u32 preamble_guardinterval; //1: short preamble/GI, 0: long preamble/GI
5274 if(stats->bCRC)
5275 rcvType = 2;
5276 else if(stats->bICV)
5277 rcvType = 3;
5279 if(stats->bShortPreamble)
5280 preamble_guardinterval = 1;// short
5281 else
5282 preamble_guardinterval = 0;// long
5284 switch(stats->rate)
5287 // CCK rate
5289 case MGN_1M: rateIndex = 0; break;
5290 case MGN_2M: rateIndex = 1; break;
5291 case MGN_5_5M: rateIndex = 2; break;
5292 case MGN_11M: rateIndex = 3; break;
5294 // Legacy OFDM rate
5296 case MGN_6M: rateIndex = 4; break;
5297 case MGN_9M: rateIndex = 5; break;
5298 case MGN_12M: rateIndex = 6; break;
5299 case MGN_18M: rateIndex = 7; break;
5300 case MGN_24M: rateIndex = 8; break;
5301 case MGN_36M: rateIndex = 9; break;
5302 case MGN_48M: rateIndex = 10; break;
5303 case MGN_54M: rateIndex = 11; break;
5305 // 11n High throughput rate
5307 case MGN_MCS0: rateIndex = 12; break;
5308 case MGN_MCS1: rateIndex = 13; break;
5309 case MGN_MCS2: rateIndex = 14; break;
5310 case MGN_MCS3: rateIndex = 15; break;
5311 case MGN_MCS4: rateIndex = 16; break;
5312 case MGN_MCS5: rateIndex = 17; break;
5313 case MGN_MCS6: rateIndex = 18; break;
5314 case MGN_MCS7: rateIndex = 19; break;
5315 case MGN_MCS8: rateIndex = 20; break;
5316 case MGN_MCS9: rateIndex = 21; break;
5317 case MGN_MCS10: rateIndex = 22; break;
5318 case MGN_MCS11: rateIndex = 23; break;
5319 case MGN_MCS12: rateIndex = 24; break;
5320 case MGN_MCS13: rateIndex = 25; break;
5321 case MGN_MCS14: rateIndex = 26; break;
5322 case MGN_MCS15: rateIndex = 27; break;
5323 default: rateIndex = 28; break;
5325 priv->stats.received_preamble_GI[preamble_guardinterval][rateIndex]++;
5326 priv->stats.received_rate_histogram[0][rateIndex]++; //total
5327 priv->stats.received_rate_histogram[rcvType][rateIndex]++;
5331 void query_rxdesc_status(struct sk_buff *skb, struct ieee80211_rx_stats *stats, bool bIsRxAggrSubframe)
5333 rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
5334 struct net_device *dev=info->dev;
5335 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
5336 //rx_desc_819x_usb *desc = (rx_desc_819x_usb *)skb->data;
5337 rx_drvinfo_819x_usb *driver_info = NULL;
5340 //Get Rx Descriptor Information
5342 #ifdef USB_RX_AGGREGATION_SUPPORT
5343 if (bIsRxAggrSubframe)
5345 rx_desc_819x_usb_aggr_subframe *desc = (rx_desc_819x_usb_aggr_subframe *)skb->data;
5346 stats->Length = desc->Length ;
5347 stats->RxDrvInfoSize = desc->RxDrvInfoSize;
5348 stats->RxBufShift = 0; //RxBufShift = 2 in RxDesc, but usb didn't shift bytes in fact.
5349 stats->bICV = desc->ICV;
5350 stats->bCRC = desc->CRC32;
5351 stats->bHwError = stats->bCRC|stats->bICV;
5352 stats->Decrypted = !desc->SWDec;//RTL8190 set this bit to indicate that Hw does not decrypt packet
5353 } else
5354 #endif
5356 rx_desc_819x_usb *desc = (rx_desc_819x_usb *)skb->data;
5358 stats->Length = desc->Length;
5359 stats->RxDrvInfoSize = desc->RxDrvInfoSize;
5360 stats->RxBufShift = 0;//desc->Shift&0x03;
5361 stats->bICV = desc->ICV;
5362 stats->bCRC = desc->CRC32;
5363 stats->bHwError = stats->bCRC|stats->bICV;
5364 //RTL8190 set this bit to indicate that Hw does not decrypt packet
5365 stats->Decrypted = !desc->SWDec;
5368 if((priv->ieee80211->pHTInfo->bCurrentHTSupport == true) && (priv->ieee80211->pairwise_key_type == KEY_TYPE_CCMP))
5370 stats->bHwError = false;
5372 else
5374 stats->bHwError = stats->bCRC|stats->bICV;
5377 if(stats->Length < 24 || stats->Length > MAX_8192U_RX_SIZE)
5378 stats->bHwError |= 1;
5380 //Get Driver Info
5382 // TODO: Need to verify it on FGPA platform
5383 //Driver info are written to the RxBuffer following rx desc
5384 if (stats->RxDrvInfoSize != 0) {
5385 driver_info = (rx_drvinfo_819x_usb *)(skb->data + sizeof(rx_desc_819x_usb) + \
5386 stats->RxBufShift);
5387 /* unit: 0.5M */
5388 /* TODO */
5389 if(!stats->bHwError){
5390 u8 ret_rate;
5391 ret_rate = HwRateToMRate90(driver_info->RxHT, driver_info->RxRate);
5392 if(ret_rate == 0xff)
5394 // Abnormal Case: Receive CRC OK packet with Rx descriptor indicating non supported rate.
5395 // Special Error Handling here, 2008.05.16, by Emily
5397 stats->bHwError = 1;
5398 stats->rate = MGN_1M; //Set 1M rate by default
5399 }else
5401 stats->rate = ret_rate;
5404 else
5405 stats->rate = 0x02;
5407 stats->bShortPreamble = driver_info->SPLCP;
5410 UpdateReceivedRateHistogramStatistics8190(dev, stats);
5412 stats->bIsAMPDU = (driver_info->PartAggr==1);
5413 stats->bFirstMPDU = (driver_info->PartAggr==1) && (driver_info->FirstAGGR==1);
5414 stats->TimeStampLow = driver_info->TSFL;
5415 // xiong mask it, 070514
5416 //pRfd->Status.TimeStampHigh = PlatformEFIORead4Byte(Adapter, TSFR+4);
5417 // stats->TimeStampHigh = read_nic_dword(dev, TSFR+4);
5419 UpdateRxPktTimeStamp8190(dev, stats);
5422 // Rx A-MPDU
5424 if(driver_info->FirstAGGR==1 || driver_info->PartAggr == 1)
5425 RT_TRACE(COMP_RXDESC, "driver_info->FirstAGGR = %d, driver_info->PartAggr = %d\n",
5426 driver_info->FirstAGGR, driver_info->PartAggr);
5430 skb_pull(skb,sizeof(rx_desc_819x_usb));
5432 // Get Total offset of MPDU Frame Body
5434 if((stats->RxBufShift + stats->RxDrvInfoSize) > 0) {
5435 stats->bShift = 1;
5436 skb_pull(skb,stats->RxBufShift + stats->RxDrvInfoSize);
5439 #ifdef USB_RX_AGGREGATION_SUPPORT
5440 /* for the rx aggregated sub frame, the redundant space truelly contained in the packet */
5441 if(bIsRxAggrSubframe) {
5442 skb_pull(skb, 8);
5444 #endif
5445 /* for debug 2008.5.29 */
5447 //added by vivi, for MP, 20080108
5448 stats->RxIs40MHzPacket = driver_info->BW;
5449 if(stats->RxDrvInfoSize != 0)
5450 TranslateRxSignalStuff819xUsb(skb, stats, driver_info);
5454 u32 GetRxPacketShiftBytes819xUsb(struct ieee80211_rx_stats *Status, bool bIsRxAggrSubframe)
5456 #ifdef USB_RX_AGGREGATION_SUPPORT
5457 if (bIsRxAggrSubframe)
5458 return (sizeof(rx_desc_819x_usb) + Status->RxDrvInfoSize
5459 + Status->RxBufShift + 8);
5460 else
5461 #endif
5462 return (sizeof(rx_desc_819x_usb) + Status->RxDrvInfoSize
5463 + Status->RxBufShift);
5466 void rtl8192_rx_nomal(struct sk_buff* skb)
5468 rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
5469 struct net_device *dev=info->dev;
5470 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
5471 struct ieee80211_rx_stats stats = {
5472 .signal = 0,
5473 .noise = -98,
5474 .rate = 0,
5475 // .mac_time = jiffies,
5476 .freq = IEEE80211_24GHZ_BAND,
5478 u32 rx_pkt_len = 0;
5479 struct ieee80211_hdr_1addr *ieee80211_hdr = NULL;
5480 bool unicast_packet = false;
5481 #ifdef USB_RX_AGGREGATION_SUPPORT
5482 struct sk_buff *agg_skb = NULL;
5483 u32 TotalLength = 0;
5484 u32 TempDWord = 0;
5485 u32 PacketLength = 0;
5486 u32 PacketOccupiedLendth = 0;
5487 u8 TempByte = 0;
5488 u32 PacketShiftBytes = 0;
5489 rx_desc_819x_usb_aggr_subframe *RxDescr = NULL;
5490 u8 PaddingBytes = 0;
5491 //add just for testing
5492 u8 testing;
5494 #endif
5496 /* 20 is for ps-poll */
5497 if((skb->len >=(20 + sizeof(rx_desc_819x_usb))) && (skb->len < RX_URB_SIZE)) {
5498 #ifdef USB_RX_AGGREGATION_SUPPORT
5499 TempByte = *(skb->data + sizeof(rx_desc_819x_usb));
5500 #endif
5501 /* first packet should not contain Rx aggregation header */
5502 query_rxdesc_status(skb, &stats, false);
5503 /* TODO */
5504 /* hardware related info */
5505 #ifdef USB_RX_AGGREGATION_SUPPORT
5506 if (TempByte & BIT0) {
5507 agg_skb = skb;
5508 //TotalLength = agg_skb->len - 4; /*sCrcLng*/
5509 TotalLength = stats.Length - 4; /*sCrcLng*/
5510 //RT_TRACE(COMP_RECV, "%s:first aggregated packet!Length=%d\n",__FUNCTION__,TotalLength);
5511 /* though the head pointer has passed this position */
5512 TempDWord = *(u32 *)(agg_skb->data - 4);
5513 PacketLength = (u16)(TempDWord & 0x3FFF); /*sCrcLng*/
5514 skb = dev_alloc_skb(PacketLength);
5515 memcpy(skb_put(skb,PacketLength),agg_skb->data,PacketLength);
5516 PacketShiftBytes = GetRxPacketShiftBytes819xUsb(&stats, false);
5518 #endif
5519 /* Process the MPDU recevied */
5520 skb_trim(skb, skb->len - 4/*sCrcLng*/);
5522 rx_pkt_len = skb->len;
5523 ieee80211_hdr = (struct ieee80211_hdr_1addr *)skb->data;
5524 unicast_packet = false;
5525 if(is_broadcast_ether_addr(ieee80211_hdr->addr1)) {
5526 //TODO
5527 }else if(is_multicast_ether_addr(ieee80211_hdr->addr1)){
5528 //TODO
5529 }else {
5530 /* unicast packet */
5531 unicast_packet = true;
5534 if(!ieee80211_rx(priv->ieee80211,skb, &stats)) {
5535 dev_kfree_skb_any(skb);
5536 } else {
5537 priv->stats.rxoktotal++;
5538 if(unicast_packet) {
5539 priv->stats.rxbytesunicast += rx_pkt_len;
5542 #ifdef USB_RX_AGGREGATION_SUPPORT
5543 testing = 1;
5544 // (PipeIndex == 0) && (TempByte & BIT0) => TotalLength > 0.
5545 if (TotalLength > 0) {
5546 PacketOccupiedLendth = PacketLength + (PacketShiftBytes + 8);
5547 if ((PacketOccupiedLendth & 0xFF) != 0)
5548 PacketOccupiedLendth = (PacketOccupiedLendth & 0xFFFFFF00) + 256;
5549 PacketOccupiedLendth -= 8;
5550 TempDWord = PacketOccupiedLendth - PacketShiftBytes; /*- PacketLength */
5551 if (agg_skb->len > TempDWord)
5552 skb_pull(agg_skb, TempDWord);
5553 else
5554 agg_skb->len = 0;
5556 while (agg_skb->len>=GetRxPacketShiftBytes819xUsb(&stats, true)) {
5557 u8 tmpCRC = 0, tmpICV = 0;
5558 //RT_TRACE(COMP_RECV,"%s:aggred pkt,total_len = %d\n",__FUNCTION__,agg_skb->len);
5559 RxDescr = (rx_desc_819x_usb_aggr_subframe *)(agg_skb->data);
5560 tmpCRC = RxDescr->CRC32;
5561 tmpICV = RxDescr->ICV;
5562 memcpy(agg_skb->data, &agg_skb->data[44], 2);
5563 RxDescr->CRC32 = tmpCRC;
5564 RxDescr->ICV = tmpICV;
5566 memset(&stats, 0, sizeof(struct ieee80211_rx_stats));
5567 stats.signal = 0;
5568 stats.noise = -98;
5569 stats.rate = 0;
5570 stats.freq = IEEE80211_24GHZ_BAND;
5571 query_rxdesc_status(agg_skb, &stats, true);
5572 PacketLength = stats.Length;
5574 if(PacketLength > agg_skb->len) {
5575 break;
5577 /* Process the MPDU recevied */
5578 skb = dev_alloc_skb(PacketLength);
5579 memcpy(skb_put(skb,PacketLength),agg_skb->data, PacketLength);
5580 skb_trim(skb, skb->len - 4/*sCrcLng*/);
5582 rx_pkt_len = skb->len;
5583 ieee80211_hdr = (struct ieee80211_hdr_1addr *)skb->data;
5584 unicast_packet = false;
5585 if(is_broadcast_ether_addr(ieee80211_hdr->addr1)) {
5586 //TODO
5587 }else if(is_multicast_ether_addr(ieee80211_hdr->addr1)){
5588 //TODO
5589 }else {
5590 /* unicast packet */
5591 unicast_packet = true;
5593 if(!ieee80211_rx(priv->ieee80211,skb, &stats)) {
5594 dev_kfree_skb_any(skb);
5595 } else {
5596 priv->stats.rxoktotal++;
5597 if(unicast_packet) {
5598 priv->stats.rxbytesunicast += rx_pkt_len;
5601 /* should trim the packet which has been copied to target skb */
5602 skb_pull(agg_skb, PacketLength);
5603 PacketShiftBytes = GetRxPacketShiftBytes819xUsb(&stats, true);
5604 PacketOccupiedLendth = PacketLength + PacketShiftBytes;
5605 if ((PacketOccupiedLendth & 0xFF) != 0) {
5606 PaddingBytes = 256 - (PacketOccupiedLendth & 0xFF);
5607 if (agg_skb->len > PaddingBytes)
5608 skb_pull(agg_skb, PaddingBytes);
5609 else
5610 agg_skb->len = 0;
5613 dev_kfree_skb(agg_skb);
5615 #endif
5616 } else {
5617 priv->stats.rxurberr++;
5618 printk("actual_length:%d\n", skb->len);
5619 dev_kfree_skb_any(skb);
5624 void
5625 rtl819xusb_process_received_packet(
5626 struct net_device *dev,
5627 struct ieee80211_rx_stats *pstats
5630 // bool bfreerfd=false, bqueued=false;
5631 u8* frame;
5632 u16 frame_len=0;
5633 struct r8192_priv *priv = ieee80211_priv(dev);
5634 // u8 index = 0;
5635 // u8 TID = 0;
5636 //u16 seqnum = 0;
5637 //PRX_TS_RECORD pts = NULL;
5639 // Get shifted bytes of Starting address of 802.11 header. 2006.09.28, by Emily
5640 //porting by amy 080508
5641 pstats->virtual_address += get_rxpacket_shiftbytes_819xusb(pstats);
5642 frame = pstats->virtual_address;
5643 frame_len = pstats->packetlength;
5644 #ifdef TODO // by amy about HCT
5645 if(!Adapter->bInHctTest)
5646 CountRxErrStatistics(Adapter, pRfd);
5647 #endif
5649 #ifdef ENABLE_PS //by amy for adding ps function in future
5650 RT_RF_POWER_STATE rtState;
5651 // When RF is off, we should not count the packet for hw/sw synchronize
5652 // reason, ie. there may be a duration while sw switch is changed and hw
5653 // switch is being changed. 2006.12.04, by shien chang.
5654 Adapter->HalFunc.GetHwRegHandler(Adapter, HW_VAR_RF_STATE, (u8* )(&rtState));
5655 if (rtState == eRfOff)
5657 return;
5659 #endif
5660 priv->stats.rxframgment++;
5663 #ifdef TODO
5664 RmMonitorSignalStrength(Adapter, pRfd);
5665 #endif
5666 /* 2007/01/16 MH Add RX command packet handle here. */
5667 /* 2007/03/01 MH We have to release RFD and return if rx pkt is cmd pkt. */
5668 if (rtl819xusb_rx_command_packet(dev, pstats))
5670 return;
5673 #ifdef SW_CRC_CHECK
5674 SwCrcCheck();
5675 #endif
5680 void query_rx_cmdpkt_desc_status(struct sk_buff *skb, struct ieee80211_rx_stats *stats)
5682 // rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
5683 // struct net_device *dev=info->dev;
5684 // struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
5685 rx_desc_819x_usb *desc = (rx_desc_819x_usb *)skb->data;
5686 // rx_drvinfo_819x_usb *driver_info;
5689 //Get Rx Descriptor Information
5691 stats->virtual_address = (u8*)skb->data;
5692 stats->Length = desc->Length;
5693 stats->RxDrvInfoSize = 0;
5694 stats->RxBufShift = 0;
5695 stats->packetlength = stats->Length-scrclng;
5696 stats->fraglength = stats->packetlength;
5697 stats->fragoffset = 0;
5698 stats->ntotalfrag = 1;
5702 void rtl8192_rx_cmd(struct sk_buff *skb)
5704 struct rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
5705 struct net_device *dev = info->dev;
5706 //int ret;
5707 // struct urb *rx_urb = info->urb;
5708 /* TODO */
5709 struct ieee80211_rx_stats stats = {
5710 .signal = 0,
5711 .noise = -98,
5712 .rate = 0,
5713 // .mac_time = jiffies,
5714 .freq = IEEE80211_24GHZ_BAND,
5717 if((skb->len >=(20 + sizeof(rx_desc_819x_usb))) && (skb->len < RX_URB_SIZE))
5720 query_rx_cmdpkt_desc_status(skb,&stats);
5721 // this is to be done by amy 080508 prfd->queue_id = 1;
5725 // Process the command packet received.
5728 rtl819xusb_process_received_packet(dev,&stats);
5730 dev_kfree_skb_any(skb);
5732 else
5738 void rtl8192_irq_rx_tasklet(struct r8192_priv *priv)
5740 struct sk_buff *skb;
5741 struct rtl8192_rx_info *info;
5743 while (NULL != (skb = skb_dequeue(&priv->skb_queue))) {
5744 info = (struct rtl8192_rx_info *)skb->cb;
5745 switch (info->out_pipe) {
5746 /* Nomal packet pipe */
5747 case 3:
5748 //RT_TRACE(COMP_RECV, "normal in-pipe index(%d)\n",info->out_pipe);
5749 priv->IrpPendingCount--;
5750 rtl8192_rx_nomal(skb);
5751 break;
5753 /* Command packet pipe */
5754 case 9:
5755 RT_TRACE(COMP_RECV, "command in-pipe index(%d)\n",\
5756 info->out_pipe);
5758 rtl8192_rx_cmd(skb);
5759 break;
5761 default: /* should never get here! */
5762 RT_TRACE(COMP_ERR, "Unknown in-pipe index(%d)\n",\
5763 info->out_pipe);
5764 dev_kfree_skb(skb);
5765 break;
5771 static const struct net_device_ops rtl8192_netdev_ops = {
5772 .ndo_open = rtl8192_open,
5773 .ndo_stop = rtl8192_close,
5774 .ndo_get_stats = rtl8192_stats,
5775 .ndo_tx_timeout = tx_timeout,
5776 .ndo_do_ioctl = rtl8192_ioctl,
5777 .ndo_set_multicast_list = r8192_set_multicast,
5778 .ndo_set_mac_address = r8192_set_mac_adr,
5779 .ndo_validate_addr = eth_validate_addr,
5780 .ndo_change_mtu = eth_change_mtu,
5781 .ndo_start_xmit = ieee80211_xmit,
5785 /****************************************************************************
5786 ---------------------------- USB_STUFF---------------------------
5787 *****************************************************************************/
5789 static int __devinit rtl8192_usb_probe(struct usb_interface *intf,
5790 const struct usb_device_id *id)
5792 // unsigned long ioaddr = 0;
5793 struct net_device *dev = NULL;
5794 struct r8192_priv *priv= NULL;
5795 struct usb_device *udev = interface_to_usbdev(intf);
5796 int ret;
5797 RT_TRACE(COMP_INIT, "Oops: i'm coming\n");
5799 dev = alloc_ieee80211(sizeof(struct r8192_priv));
5800 if (dev == NULL)
5801 return -ENOMEM;
5803 usb_set_intfdata(intf, dev);
5804 SET_NETDEV_DEV(dev, &intf->dev);
5805 priv = ieee80211_priv(dev);
5806 priv->ieee80211 = netdev_priv(dev);
5807 priv->udev=udev;
5809 dev->netdev_ops = &rtl8192_netdev_ops;
5811 //DMESG("Oops: i'm coming\n");
5812 #if WIRELESS_EXT >= 12
5813 #if WIRELESS_EXT < 17
5814 dev->get_wireless_stats = r8192_get_wireless_stats;
5815 #endif
5816 dev->wireless_handlers = (struct iw_handler_def *) &r8192_wx_handlers_def;
5817 #endif
5818 dev->type=ARPHRD_ETHER;
5820 dev->watchdog_timeo = HZ*3; //modified by john, 0805
5822 if (dev_alloc_name(dev, ifname) < 0){
5823 RT_TRACE(COMP_INIT, "Oops: devname already taken! Trying wlan%%d...\n");
5824 ifname = "wlan%d";
5825 dev_alloc_name(dev, ifname);
5828 RT_TRACE(COMP_INIT, "Driver probe completed1\n");
5829 if(rtl8192_init(dev)!=0){
5830 RT_TRACE(COMP_ERR, "Initialization failed");
5831 ret = -ENODEV;
5832 goto fail;
5834 netif_carrier_off(dev);
5835 netif_stop_queue(dev);
5837 ret = register_netdev(dev);
5838 if (ret)
5839 goto fail2;
5841 RT_TRACE(COMP_INIT, "dev name=======> %s\n",dev->name);
5842 rtl8192_proc_init_one(dev);
5845 RT_TRACE(COMP_INIT, "Driver probe completed\n");
5846 return 0;
5848 fail2:
5849 rtl8192_down(dev);
5850 if (priv->pFirmware) {
5851 kfree(priv->pFirmware);
5852 priv->pFirmware = NULL;
5854 rtl8192_usb_deleteendpoints(dev);
5855 destroy_workqueue(priv->priv_wq);
5856 mdelay(10);
5857 fail:
5858 free_ieee80211(dev);
5860 RT_TRACE(COMP_ERR, "wlan driver load failed\n");
5861 return ret;
5864 //detach all the work and timer structure declared or inititialize in r8192U_init function.
5865 void rtl8192_cancel_deferred_work(struct r8192_priv* priv)
5868 cancel_work_sync(&priv->reset_wq);
5869 cancel_delayed_work(&priv->watch_dog_wq);
5870 cancel_delayed_work(&priv->update_beacon_wq);
5871 cancel_work_sync(&priv->qos_activate);
5872 //cancel_work_sync(&priv->SetBWModeWorkItem);
5873 //cancel_work_sync(&priv->SwChnlWorkItem);
5878 static void __devexit rtl8192_usb_disconnect(struct usb_interface *intf)
5880 struct net_device *dev = usb_get_intfdata(intf);
5882 struct r8192_priv *priv = ieee80211_priv(dev);
5883 if(dev){
5885 unregister_netdev(dev);
5887 RT_TRACE(COMP_DOWN, "=============>wlan driver to be removed\n");
5888 rtl8192_proc_remove_one(dev);
5890 rtl8192_down(dev);
5891 if (priv->pFirmware)
5893 kfree(priv->pFirmware);
5894 priv->pFirmware = NULL;
5896 // priv->rf_close(dev);
5897 // rtl8192_SetRFPowerState(dev, eRfOff);
5898 rtl8192_usb_deleteendpoints(dev);
5899 destroy_workqueue(priv->priv_wq);
5900 //rtl8192_irq_disable(dev);
5901 //rtl8192_reset(dev);
5902 mdelay(10);
5905 free_ieee80211(dev);
5906 RT_TRACE(COMP_DOWN, "wlan driver removed\n");
5909 /* fun with the built-in ieee80211 stack... */
5910 extern int ieee80211_debug_init(void);
5911 extern void ieee80211_debug_exit(void);
5912 extern int ieee80211_crypto_init(void);
5913 extern void ieee80211_crypto_deinit(void);
5914 extern int ieee80211_crypto_tkip_init(void);
5915 extern void ieee80211_crypto_tkip_exit(void);
5916 extern int ieee80211_crypto_ccmp_init(void);
5917 extern void ieee80211_crypto_ccmp_exit(void);
5918 extern int ieee80211_crypto_wep_init(void);
5919 extern void ieee80211_crypto_wep_exit(void);
5921 static int __init rtl8192_usb_module_init(void)
5923 int ret;
5925 #ifdef CONFIG_IEEE80211_DEBUG
5926 ret = ieee80211_debug_init();
5927 if (ret) {
5928 printk(KERN_ERR "ieee80211_debug_init() failed %d\n", ret);
5929 return ret;
5931 #endif
5932 ret = ieee80211_crypto_init();
5933 if (ret) {
5934 printk(KERN_ERR "ieee80211_crypto_init() failed %d\n", ret);
5935 return ret;
5938 ret = ieee80211_crypto_tkip_init();
5939 if (ret) {
5940 printk(KERN_ERR "ieee80211_crypto_tkip_init() failed %d\n",
5941 ret);
5942 return ret;
5945 ret = ieee80211_crypto_ccmp_init();
5946 if (ret) {
5947 printk(KERN_ERR "ieee80211_crypto_ccmp_init() failed %d\n",
5948 ret);
5949 return ret;
5952 ret = ieee80211_crypto_wep_init();
5953 if (ret) {
5954 printk(KERN_ERR "ieee80211_crypto_wep_init() failed %d\n", ret);
5955 return ret;
5958 printk(KERN_INFO "\nLinux kernel driver for RTL8192 based WLAN cards\n");
5959 printk(KERN_INFO "Copyright (c) 2007-2008, Realsil Wlan\n");
5960 RT_TRACE(COMP_INIT, "Initializing module");
5961 RT_TRACE(COMP_INIT, "Wireless extensions version %d", WIRELESS_EXT);
5962 rtl8192_proc_module_init();
5963 return usb_register(&rtl8192_usb_driver);
5967 static void __exit rtl8192_usb_module_exit(void)
5969 usb_deregister(&rtl8192_usb_driver);
5971 RT_TRACE(COMP_DOWN, "Exiting");
5972 // rtl8192_proc_module_remove();
5976 void rtl8192_try_wake_queue(struct net_device *dev, int pri)
5978 unsigned long flags;
5979 short enough_desc;
5980 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
5982 spin_lock_irqsave(&priv->tx_lock,flags);
5983 enough_desc = check_nic_enough_desc(dev,pri);
5984 spin_unlock_irqrestore(&priv->tx_lock,flags);
5986 if(enough_desc)
5987 ieee80211_wake_queue(priv->ieee80211);
5990 void EnableHWSecurityConfig8192(struct net_device *dev)
5992 u8 SECR_value = 0x0;
5993 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
5994 struct ieee80211_device* ieee = priv->ieee80211;
5995 SECR_value = SCR_TxEncEnable | SCR_RxDecEnable;
5996 if (((KEY_TYPE_WEP40 == ieee->pairwise_key_type) || (KEY_TYPE_WEP104 == ieee->pairwise_key_type)) && (priv->ieee80211->auth_mode != 2))
5998 SECR_value |= SCR_RxUseDK;
5999 SECR_value |= SCR_TxUseDK;
6001 else if ((ieee->iw_mode == IW_MODE_ADHOC) && (ieee->pairwise_key_type & (KEY_TYPE_CCMP | KEY_TYPE_TKIP)))
6003 SECR_value |= SCR_RxUseDK;
6004 SECR_value |= SCR_TxUseDK;
6006 //add HWSec active enable here.
6007 //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
6009 ieee->hwsec_active = 1;
6011 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
6013 ieee->hwsec_active = 0;
6014 SECR_value &= ~SCR_RxDecEnable;
6016 RT_TRACE(COMP_SEC,"%s:, hwsec:%d, pairwise_key:%d, SECR_value:%x\n", __FUNCTION__, \
6017 ieee->hwsec_active, ieee->pairwise_key_type, SECR_value);
6019 write_nic_byte(dev, SECR, SECR_value);//SECR_value | SCR_UseDK );
6024 void setKey( struct net_device *dev,
6025 u8 EntryNo,
6026 u8 KeyIndex,
6027 u16 KeyType,
6028 u8 *MacAddr,
6029 u8 DefaultKey,
6030 u32 *KeyContent )
6032 u32 TargetCommand = 0;
6033 u32 TargetContent = 0;
6034 u16 usConfig = 0;
6035 u8 i;
6036 if (EntryNo >= TOTAL_CAM_ENTRY)
6037 RT_TRACE(COMP_ERR, "cam entry exceeds in setKey()\n");
6039 RT_TRACE(COMP_SEC, "====>to setKey(), dev:%p, EntryNo:%d, KeyIndex:%d, KeyType:%d, MacAddr%pM\n", dev,EntryNo, KeyIndex, KeyType, MacAddr);
6041 if (DefaultKey)
6042 usConfig |= BIT15 | (KeyType<<2);
6043 else
6044 usConfig |= BIT15 | (KeyType<<2) | KeyIndex;
6045 // usConfig |= BIT15 | (KeyType<<2) | (DefaultKey<<5) | KeyIndex;
6048 for(i=0 ; i<CAM_CONTENT_COUNT; i++){
6049 TargetCommand = i+CAM_CONTENT_COUNT*EntryNo;
6050 TargetCommand |= BIT31|BIT16;
6052 if(i==0){//MAC|Config
6053 TargetContent = (u32)(*(MacAddr+0)) << 16|
6054 (u32)(*(MacAddr+1)) << 24|
6055 (u32)usConfig;
6057 write_nic_dword(dev, WCAMI, TargetContent);
6058 write_nic_dword(dev, RWCAM, TargetCommand);
6059 // printk("setkey cam =%8x\n", read_cam(dev, i+6*EntryNo));
6061 else if(i==1){//MAC
6062 TargetContent = (u32)(*(MacAddr+2)) |
6063 (u32)(*(MacAddr+3)) << 8|
6064 (u32)(*(MacAddr+4)) << 16|
6065 (u32)(*(MacAddr+5)) << 24;
6066 write_nic_dword(dev, WCAMI, TargetContent);
6067 write_nic_dword(dev, RWCAM, TargetCommand);
6069 else {
6070 //Key Material
6071 if(KeyContent !=NULL){
6072 write_nic_dword(dev, WCAMI, (u32)(*(KeyContent+i-2)) );
6073 write_nic_dword(dev, RWCAM, TargetCommand);
6080 /***************************************************************************
6081 ------------------- module init / exit stubs ----------------
6082 ****************************************************************************/
6083 module_init(rtl8192_usb_module_init);
6084 module_exit(rtl8192_usb_module_exit);