Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next
[linux-2.6.git] / drivers / staging / rtl8192u / r8192U_core.c
blob14c14c24ac500bc39c79d02424eb7cd706287269
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)
30 return i;
33 unsigned int __fixunsdfsi(double d)
35 return d;
38 double __adddf3(double a, double b)
40 return a+b;
43 double __addsf3(float a, float b)
45 return a+b;
48 double __subdf3(double a, double b)
50 return a-b;
53 double __extendsfdf2(float a)
55 return a;
57 #endif
59 #undef LOOP_TEST
60 #undef DUMP_RX
61 #undef DUMP_TX
62 #undef DEBUG_TX_DESC2
63 #undef RX_DONT_PASS_UL
64 #undef DEBUG_EPROM
65 #undef DEBUG_RX_VERBOSE
66 #undef DUMMY_RX
67 #undef DEBUG_ZERO_RX
68 #undef DEBUG_RX_SKB
69 #undef DEBUG_TX_FRAG
70 #undef DEBUG_RX_FRAG
71 #undef DEBUG_TX_FILLDESC
72 #undef DEBUG_TX
73 #undef DEBUG_IRQ
74 #undef DEBUG_RX
75 #undef DEBUG_RXALLOC
76 #undef DEBUG_REGISTERS
77 #undef DEBUG_RING
78 #undef DEBUG_IRQ_TASKLET
79 #undef DEBUG_TX_ALLOC
80 #undef DEBUG_TX_DESC
82 #define CONFIG_RTL8192_IO_MAP
84 #include <asm/uaccess.h>
85 #include "r8192U_hw.h"
86 #include "r8192U.h"
87 #include "r8190_rtl8256.h" /* RTL8225 Radio frontend */
88 #include "r8180_93cx6.h" /* Card EEPROM */
89 #include "r8192U_wx.h"
90 #include "r819xU_phy.h" //added by WB 4.30.2008
91 #include "r819xU_phyreg.h"
92 #include "r819xU_cmdpkt.h"
93 #include "r8192U_dm.h"
94 #include <linux/usb.h>
95 #include <linux/slab.h>
96 #include <linux/proc_fs.h>
97 #include <linux/seq_file.h>
98 // FIXME: check if 2.6.7 is ok
100 #ifdef CONFIG_RTL8192_PM
101 #include "r8192_pm.h"
102 #endif
104 #include "dot11d.h"
105 //set here to open your trace code. //WB
106 u32 rt_global_debug_component = COMP_DOWN |
107 COMP_SEC |
108 COMP_ERR; //always open err flags on
110 #define TOTAL_CAM_ENTRY 32
111 #define CAM_CONTENT_COUNT 8
113 static const struct usb_device_id rtl8192_usb_id_tbl[] = {
114 /* Realtek */
115 {USB_DEVICE(0x0bda, 0x8709)},
116 /* Corega */
117 {USB_DEVICE(0x07aa, 0x0043)},
118 /* Belkin */
119 {USB_DEVICE(0x050d, 0x805E)},
120 /* Sitecom */
121 {USB_DEVICE(0x0df6, 0x0031)},
122 /* EnGenius */
123 {USB_DEVICE(0x1740, 0x9201)},
124 /* Dlink */
125 {USB_DEVICE(0x2001, 0x3301)},
126 /* Zinwell */
127 {USB_DEVICE(0x5a57, 0x0290)},
128 /* LG */
129 {USB_DEVICE(0x043e, 0x7a01)},
133 MODULE_LICENSE("GPL");
134 MODULE_VERSION("V 1.1");
135 MODULE_DEVICE_TABLE(usb, rtl8192_usb_id_tbl);
136 MODULE_DESCRIPTION("Linux driver for Realtek RTL8192 USB WiFi cards");
138 static char *ifname = "wlan%d";
139 static int hwwep = 1; //default use hw. set 0 to use software security
140 static int channels = 0x3fff;
144 module_param(ifname, charp, S_IRUGO|S_IWUSR);
145 module_param(hwwep, int, S_IRUGO|S_IWUSR);
146 module_param(channels, int, S_IRUGO|S_IWUSR);
148 MODULE_PARM_DESC(ifname, " Net interface name, wlan%d=default");
149 MODULE_PARM_DESC(hwwep, " Try to use hardware security support. ");
150 MODULE_PARM_DESC(channels, " Channel bitmask for specific locales. NYI");
152 static int rtl8192_usb_probe(struct usb_interface *intf,
153 const struct usb_device_id *id);
154 static void rtl8192_usb_disconnect(struct usb_interface *intf);
157 static struct usb_driver rtl8192_usb_driver = {
158 .name = RTL819xU_MODULE_NAME, /* Driver name */
159 .id_table = rtl8192_usb_id_tbl, /* PCI_ID table */
160 .probe = rtl8192_usb_probe, /* probe fn */
161 .disconnect = rtl8192_usb_disconnect, /* remove fn */
162 #ifdef CONFIG_RTL8192_PM
163 .suspend = rtl8192_suspend, /* PM suspend fn */
164 .resume = rtl8192_resume, /* PM resume fn */
165 #else
166 .suspend = NULL, /* PM suspend fn */
167 .resume = NULL, /* PM resume fn */
168 #endif
172 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) {
196 case COUNTRY_CODE_FCC:
197 case COUNTRY_CODE_IC:
198 case COUNTRY_CODE_ETSI:
199 case COUNTRY_CODE_SPAIN:
200 case COUNTRY_CODE_FRANCE:
201 case COUNTRY_CODE_MKK:
202 case COUNTRY_CODE_MKK1:
203 case COUNTRY_CODE_ISRAEL:
204 case COUNTRY_CODE_TELEC:
205 case COUNTRY_CODE_MIC:
206 Dot11d_Init(ieee);
207 ieee->bGlobalDomain = false;
208 //actually 8225 & 8256 rf chips only support B,G,24N mode
209 if ((priv->rf_chip == RF_8225) || (priv->rf_chip == RF_8256)) {
210 min_chan = 1;
211 max_chan = 14;
212 } else {
213 RT_TRACE(COMP_ERR, "unknown rf chip, can't set channel map in function:%s()\n", __func__);
215 if (ChannelPlan[channel_plan].Len != 0) {
216 // Clear old channel map
217 memset(GET_DOT11D_INFO(ieee)->channel_map, 0, sizeof(GET_DOT11D_INFO(ieee)->channel_map));
218 // Set new channel map
219 for (i = 0; i < ChannelPlan[channel_plan].Len; i++) {
220 if (ChannelPlan[channel_plan].Channel[i] < min_chan || ChannelPlan[channel_plan].Channel[i] > max_chan)
221 break;
222 GET_DOT11D_INFO(ieee)->channel_map[ChannelPlan[channel_plan].Channel[i]] = 1;
225 break;
227 case COUNTRY_CODE_GLOBAL_DOMAIN:
228 GET_DOT11D_INFO(ieee)->bEnabled = 0;//this flag enabled to follow 11d country IE setting, otherwise, it shall follow global domain settings.
229 Dot11d_Reset(ieee);
230 ieee->bGlobalDomain = true;
231 break;
233 default:
234 break;
241 void CamResetAllEntry(struct net_device *dev)
243 u32 ulcommand = 0;
244 //2004/02/11 In static WEP, OID_ADD_KEY or OID_ADD_WEP are set before STA associate to AP.
245 // However, ResetKey is called on OID_802_11_INFRASTRUCTURE_MODE and MlmeAssociateRequest
246 // In this condition, Cam can not be reset because upper layer will not set this static key again.
247 ulcommand |= BIT31|BIT30;
248 write_nic_dword(dev, RWCAM, ulcommand);
253 void write_cam(struct net_device *dev, u8 addr, u32 data)
255 write_nic_dword(dev, WCAMI, data);
256 write_nic_dword(dev, RWCAM, BIT31|BIT16|(addr&0xff));
259 u32 read_cam(struct net_device *dev, u8 addr)
261 u32 data;
263 write_nic_dword(dev, RWCAM, 0x80000000|(addr&0xff));
264 read_nic_dword(dev, 0xa8, &data);
265 return data;
268 void write_nic_byte_E(struct net_device *dev, int indx, u8 data)
270 int status;
271 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
272 struct usb_device *udev = priv->udev;
274 status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
275 RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
276 indx|0xfe00, 0, &data, 1, HZ / 2);
278 if (status < 0)
279 netdev_err(dev, "write_nic_byte_E TimeOut! status: %d\n", status);
282 int read_nic_byte_E(struct net_device *dev, int indx, u8 *data)
284 int status;
285 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
286 struct usb_device *udev = priv->udev;
288 status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
289 RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
290 indx|0xfe00, 0, data, 1, HZ / 2);
292 if (status < 0) {
293 netdev_err(dev, "%s failure status: %d\n", __func__, status);
294 return status;
297 return 0;
299 //as 92U has extend page from 4 to 16, so modify functions below.
300 void write_nic_byte(struct net_device *dev, int indx, u8 data)
302 int status;
304 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
305 struct usb_device *udev = priv->udev;
307 status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
308 RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
309 (indx&0xff)|0xff00, (indx>>8)&0x0f, &data, 1, HZ / 2);
311 if (status < 0)
312 netdev_err(dev, "write_nic_byte TimeOut! status: %d\n", status);
318 void write_nic_word(struct net_device *dev, int indx, u16 data)
321 int status;
323 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
324 struct usb_device *udev = priv->udev;
326 status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
327 RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
328 (indx&0xff)|0xff00, (indx>>8)&0x0f, &data, 2, HZ / 2);
330 if (status < 0)
331 netdev_err(dev, "write_nic_word TimeOut! status: %d\n", status);
336 void write_nic_dword(struct net_device *dev, int indx, u32 data)
339 int status;
341 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
342 struct usb_device *udev = priv->udev;
344 status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
345 RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
346 (indx&0xff)|0xff00, (indx>>8)&0x0f, &data, 4, HZ / 2);
349 if (status < 0)
350 netdev_err(dev, "write_nic_dword TimeOut! status: %d\n", status);
356 int read_nic_byte(struct net_device *dev, int indx, u8 *data)
358 int status;
359 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
360 struct usb_device *udev = priv->udev;
362 status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
363 RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
364 (indx&0xff)|0xff00, (indx>>8)&0x0f, data, 1, HZ / 2);
366 if (status < 0) {
367 netdev_err(dev, "%s failure status: %d\n", __func__, status);
368 return status;
371 return 0;
376 int read_nic_word(struct net_device *dev, int indx, u16 *data)
378 int status;
379 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
380 struct usb_device *udev = priv->udev;
382 status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
383 RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
384 (indx&0xff)|0xff00, (indx>>8)&0x0f,
385 data, 2, HZ / 2);
387 if (status < 0) {
388 netdev_err(dev, "%s failure status: %d\n", __func__, status);
389 return status;
392 return 0;
395 int read_nic_word_E(struct net_device *dev, int indx, u16 *data)
397 int status;
398 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
399 struct usb_device *udev = priv->udev;
401 status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
402 RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
403 indx|0xfe00, 0, data, 2, HZ / 2);
405 if (status < 0) {
406 netdev_err(dev, "%s failure status: %d\n", __func__, status);
407 return status;
410 return 0;
413 int read_nic_dword(struct net_device *dev, int indx, u32 *data)
415 int status;
417 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
418 struct usb_device *udev = priv->udev;
420 status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
421 RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
422 (indx&0xff)|0xff00, (indx>>8)&0x0f,
423 data, 4, HZ / 2);
425 if (status < 0) {
426 netdev_err(dev, "%s failure status: %d\n", __func__, status);
427 return status;
430 return 0;
433 /* u8 read_phy_cck(struct net_device *dev, u8 adr); */
434 /* u8 read_phy_ofdm(struct net_device *dev, u8 adr); */
435 /* this might still called in what was the PHY rtl8185/rtl8192 common code
436 * plans are to possibility turn it again in one common code...
438 inline void force_pci_posting(struct net_device *dev)
442 static struct net_device_stats *rtl8192_stats(struct net_device *dev);
443 void rtl8192_commit(struct net_device *dev);
444 void rtl8192_restart(struct work_struct *work);
445 void watch_dog_timer_callback(unsigned long data);
447 /****************************************************************************
448 * -----------------------------PROCFS STUFF-------------------------
449 *****************************************************************************
452 static struct proc_dir_entry *rtl8192_proc;
454 static int proc_get_stats_ap(struct seq_file *m, void *v)
456 struct net_device *dev = m->private;
457 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
458 struct ieee80211_device *ieee = priv->ieee80211;
459 struct ieee80211_network *target;
461 list_for_each_entry(target, &ieee->network_list, list) {
462 const char *wpa = "non_WPA";
463 if (target->wpa_ie_len > 0 || target->rsn_ie_len > 0)
464 wpa = "WPA";
466 seq_printf(m, "%s %s\n", target->ssid, wpa);
469 return 0;
472 static int proc_get_registers(struct seq_file *m, void *v)
474 struct net_device *dev = m->private;
475 int i, n, max = 0xff;
476 u8 byte_rd;
478 seq_puts(m, "\n####################page 0##################\n ");
480 for (n = 0; n <= max;) {
481 seq_printf(m, "\nD: %2x > ", n);
483 for (i = 0; i < 16 && n <= max; i++, n++) {
484 read_nic_byte(dev, 0x000|n, &byte_rd);
485 seq_printf(m, "%2x ", byte_rd);
489 seq_puts(m, "\n####################page 1##################\n ");
490 for (n = 0; n <= max;) {
491 seq_printf(m, "\nD: %2x > ", n);
493 for (i = 0; i < 16 && n <= max; i++, n++) {
494 read_nic_byte(dev, 0x100|n, &byte_rd);
495 seq_printf(m, "%2x ", byte_rd);
499 seq_puts(m, "\n####################page 3##################\n ");
500 for (n = 0; n <= max;) {
501 seq_printf(m, "\nD: %2x > ", n);
503 for (i = 0; i < 16 && n <= max; i++, n++) {
504 read_nic_byte(dev, 0x300|n, &byte_rd);
505 seq_printf(m, "%2x ", byte_rd);
509 seq_putc(m, '\n');
510 return 0;
513 static int proc_get_stats_tx(struct seq_file *m, void *v)
515 struct net_device *dev = m->private;
516 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
518 seq_printf(m,
519 "TX VI priority ok int: %lu\n"
520 "TX VI priority error int: %lu\n"
521 "TX VO priority ok int: %lu\n"
522 "TX VO priority error int: %lu\n"
523 "TX BE priority ok int: %lu\n"
524 "TX BE priority error int: %lu\n"
525 "TX BK priority ok int: %lu\n"
526 "TX BK priority error int: %lu\n"
527 "TX MANAGE priority ok int: %lu\n"
528 "TX MANAGE priority error int: %lu\n"
529 "TX BEACON priority ok int: %lu\n"
530 "TX BEACON priority error int: %lu\n"
531 "TX queue resume: %lu\n"
532 "TX queue stopped?: %d\n"
533 "TX fifo overflow: %lu\n"
534 "TX VI queue: %d\n"
535 "TX VO queue: %d\n"
536 "TX BE queue: %d\n"
537 "TX BK queue: %d\n"
538 "TX VI dropped: %lu\n"
539 "TX VO dropped: %lu\n"
540 "TX BE dropped: %lu\n"
541 "TX BK dropped: %lu\n"
542 "TX total data packets %lu\n",
543 priv->stats.txviokint,
544 priv->stats.txvierr,
545 priv->stats.txvookint,
546 priv->stats.txvoerr,
547 priv->stats.txbeokint,
548 priv->stats.txbeerr,
549 priv->stats.txbkokint,
550 priv->stats.txbkerr,
551 priv->stats.txmanageokint,
552 priv->stats.txmanageerr,
553 priv->stats.txbeaconokint,
554 priv->stats.txbeaconerr,
555 priv->stats.txresumed,
556 netif_queue_stopped(dev),
557 priv->stats.txoverflow,
558 atomic_read(&(priv->tx_pending[VI_PRIORITY])),
559 atomic_read(&(priv->tx_pending[VO_PRIORITY])),
560 atomic_read(&(priv->tx_pending[BE_PRIORITY])),
561 atomic_read(&(priv->tx_pending[BK_PRIORITY])),
562 priv->stats.txvidrop,
563 priv->stats.txvodrop,
564 priv->stats.txbedrop,
565 priv->stats.txbkdrop,
566 priv->stats.txdatapkt
569 return 0;
572 static int proc_get_stats_rx(struct seq_file *m, void *v)
574 struct net_device *dev = m->private;
575 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
577 seq_printf(m,
578 "RX packets: %lu\n"
579 "RX urb status error: %lu\n"
580 "RX invalid urb error: %lu\n",
581 priv->stats.rxoktotal,
582 priv->stats.rxstaterr,
583 priv->stats.rxurberr);
585 return 0;
588 void rtl8192_proc_module_init(void)
590 RT_TRACE(COMP_INIT, "Initializing proc filesystem");
591 rtl8192_proc = proc_mkdir(RTL819xU_MODULE_NAME, init_net.proc_net);
595 void rtl8192_proc_module_remove(void)
597 remove_proc_entry(RTL819xU_MODULE_NAME, init_net.proc_net);
601 * seq_file wrappers for procfile show routines.
603 static int rtl8192_proc_open(struct inode *inode, struct file *file)
605 struct net_device *dev = proc_get_parent_data(inode);
606 int (*show)(struct seq_file *, void *) = PDE_DATA(inode);
608 return single_open(file, show, dev);
611 static const struct file_operations rtl8192_proc_fops = {
612 .open = rtl8192_proc_open,
613 .read = seq_read,
614 .llseek = seq_lseek,
615 .release = single_release,
619 * Table of proc files we need to create.
621 struct rtl8192_proc_file {
622 char name[12];
623 int (*show)(struct seq_file *, void *);
626 static const struct rtl8192_proc_file rtl8192_proc_files[] = {
627 { "stats-rx", &proc_get_stats_rx },
628 { "stats-tx", &proc_get_stats_tx },
629 { "stats-ap", &proc_get_stats_ap },
630 { "registers", &proc_get_registers },
631 { "" }
634 void rtl8192_proc_init_one(struct net_device *dev)
636 const struct rtl8192_proc_file *f;
637 struct proc_dir_entry *dir;
639 if (rtl8192_proc) {
640 dir = proc_mkdir_data(dev->name, 0, rtl8192_proc, dev);
641 if (!dir) {
642 RT_TRACE(COMP_ERR, "Unable to initialize /proc/net/rtl8192/%s\n",
643 dev->name);
644 return;
647 for (f = rtl8192_proc_files; f->name[0]; f++) {
648 if (!proc_create_data(f->name, S_IFREG | S_IRUGO, dir,
649 &rtl8192_proc_fops, f->show)) {
650 RT_TRACE(COMP_ERR, "Unable to initialize "
651 "/proc/net/rtl8192/%s/%s\n",
652 dev->name, f->name);
653 return;
659 void rtl8192_proc_remove_one(struct net_device *dev)
661 remove_proc_subtree(dev->name, rtl8192_proc);
664 /****************************************************************************
665 -----------------------------MISC STUFF-------------------------
666 *****************************************************************************/
668 short check_nic_enough_desc(struct net_device *dev, int queue_index)
670 struct r8192_priv *priv = ieee80211_priv(dev);
671 int used = atomic_read(&priv->tx_pending[queue_index]);
673 return (used < MAX_TX_URB);
676 void tx_timeout(struct net_device *dev)
678 struct r8192_priv *priv = ieee80211_priv(dev);
680 schedule_work(&priv->reset_wq);
684 /* this is only for debug */
685 void dump_eprom(struct net_device *dev)
687 int i;
688 for (i = 0; i < 63; i++)
689 RT_TRACE(COMP_EPROM, "EEPROM addr %x : %x", i, eprom_read(dev, i));
693 /****************************************************************************
694 ------------------------------HW STUFF---------------------------
695 *****************************************************************************/
698 void rtl8192_set_mode(struct net_device *dev, int mode)
700 u8 ecmd;
701 read_nic_byte(dev, EPROM_CMD, &ecmd);
702 ecmd = ecmd & ~EPROM_CMD_OPERATING_MODE_MASK;
703 ecmd = ecmd | (mode<<EPROM_CMD_OPERATING_MODE_SHIFT);
704 ecmd = ecmd & ~EPROM_CS_BIT;
705 ecmd = ecmd & ~EPROM_CK_BIT;
706 write_nic_byte(dev, EPROM_CMD, ecmd);
710 void rtl8192_update_msr(struct net_device *dev)
712 struct r8192_priv *priv = ieee80211_priv(dev);
713 u8 msr;
715 read_nic_byte(dev, MSR, &msr);
716 msr &= ~MSR_LINK_MASK;
718 /* do not change in link_state != WLAN_LINK_ASSOCIATED.
719 * msr must be updated if the state is ASSOCIATING.
720 * this is intentional and make sense for ad-hoc and
721 * master (see the create BSS/IBSS func)
723 if (priv->ieee80211->state == IEEE80211_LINKED) {
725 if (priv->ieee80211->iw_mode == IW_MODE_INFRA)
726 msr |= (MSR_LINK_MANAGED<<MSR_LINK_SHIFT);
727 else if (priv->ieee80211->iw_mode == IW_MODE_ADHOC)
728 msr |= (MSR_LINK_ADHOC<<MSR_LINK_SHIFT);
729 else if (priv->ieee80211->iw_mode == IW_MODE_MASTER)
730 msr |= (MSR_LINK_MASTER<<MSR_LINK_SHIFT);
732 } else {
733 msr |= (MSR_LINK_NONE<<MSR_LINK_SHIFT);
736 write_nic_byte(dev, MSR, msr);
739 void rtl8192_set_chan(struct net_device *dev, short ch)
741 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
742 RT_TRACE(COMP_CH, "=====>%s()====ch:%d\n", __func__, ch);
743 priv->chan = ch;
745 /* this hack should avoid frame TX during channel setting*/
747 #ifndef LOOP_TEST
748 //need to implement rf set channel here WB
750 if (priv->rf_set_chan)
751 priv->rf_set_chan(dev, priv->chan);
752 mdelay(10);
753 #endif
756 static void rtl8192_rx_isr(struct urb *urb);
758 u32 get_rxpacket_shiftbytes_819xusb(struct ieee80211_rx_stats *pstats)
761 #ifdef USB_RX_AGGREGATION_SUPPORT
762 if (pstats->bisrxaggrsubframe)
763 return (sizeof(rx_desc_819x_usb) + pstats->RxDrvInfoSize
764 + pstats->RxBufShift + 8);
765 else
766 #endif
767 return (sizeof(rx_desc_819x_usb) + pstats->RxDrvInfoSize
768 + pstats->RxBufShift);
771 static int rtl8192_rx_initiate(struct net_device *dev)
773 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
774 struct urb *entry;
775 struct sk_buff *skb;
776 struct rtl8192_rx_info *info;
778 /* nomal packet rx procedure */
779 while (skb_queue_len(&priv->rx_queue) < MAX_RX_URB) {
780 skb = __dev_alloc_skb(RX_URB_SIZE, GFP_KERNEL);
781 if (!skb)
782 break;
783 entry = usb_alloc_urb(0, GFP_KERNEL);
784 if (!entry) {
785 kfree_skb(skb);
786 break;
788 usb_fill_bulk_urb(entry, priv->udev,
789 usb_rcvbulkpipe(priv->udev, 3), skb_tail_pointer(skb),
790 RX_URB_SIZE, rtl8192_rx_isr, skb);
791 info = (struct rtl8192_rx_info *) skb->cb;
792 info->urb = entry;
793 info->dev = dev;
794 info->out_pipe = 3; //denote rx normal packet queue
795 skb_queue_tail(&priv->rx_queue, skb);
796 usb_submit_urb(entry, GFP_KERNEL);
799 /* command packet rx procedure */
800 while (skb_queue_len(&priv->rx_queue) < MAX_RX_URB + 3) {
801 skb = __dev_alloc_skb(RX_URB_SIZE, GFP_KERNEL);
802 if (!skb)
803 break;
804 entry = usb_alloc_urb(0, GFP_KERNEL);
805 if (!entry) {
806 kfree_skb(skb);
807 break;
809 usb_fill_bulk_urb(entry, priv->udev,
810 usb_rcvbulkpipe(priv->udev, 9), skb_tail_pointer(skb),
811 RX_URB_SIZE, rtl8192_rx_isr, skb);
812 info = (struct rtl8192_rx_info *) skb->cb;
813 info->urb = entry;
814 info->dev = dev;
815 info->out_pipe = 9; //denote rx cmd packet queue
816 skb_queue_tail(&priv->rx_queue, skb);
817 usb_submit_urb(entry, GFP_KERNEL);
820 return 0;
823 void rtl8192_set_rxconf(struct net_device *dev)
825 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
826 u32 rxconf;
828 read_nic_dword(dev, RCR, &rxconf);
829 rxconf = rxconf & ~MAC_FILTER_MASK;
830 rxconf = rxconf | RCR_AMF;
831 rxconf = rxconf | RCR_ADF;
832 rxconf = rxconf | RCR_AB;
833 rxconf = rxconf | RCR_AM;
835 if (dev->flags & IFF_PROMISC)
836 DMESG("NIC in promisc mode");
838 if (priv->ieee80211->iw_mode == IW_MODE_MONITOR ||
839 dev->flags & IFF_PROMISC) {
840 rxconf = rxconf | RCR_AAP;
841 } else {
842 rxconf = rxconf | RCR_APM;
843 rxconf = rxconf | RCR_CBSSID;
847 if (priv->ieee80211->iw_mode == IW_MODE_MONITOR) {
848 rxconf = rxconf | RCR_AICV;
849 rxconf = rxconf | RCR_APWRMGT;
852 if (priv->crcmon == 1 && priv->ieee80211->iw_mode == IW_MODE_MONITOR)
853 rxconf = rxconf | RCR_ACRC32;
856 rxconf = rxconf & ~RX_FIFO_THRESHOLD_MASK;
857 rxconf = rxconf | (RX_FIFO_THRESHOLD_NONE<<RX_FIFO_THRESHOLD_SHIFT);
858 rxconf = rxconf & ~MAX_RX_DMA_MASK;
859 rxconf = rxconf | ((u32)7<<RCR_MXDMA_OFFSET);
861 rxconf = rxconf | RCR_ONLYERLPKT;
863 write_nic_dword(dev, RCR, rxconf);
865 //wait to be removed
866 void rtl8192_rx_enable(struct net_device *dev)
868 rtl8192_rx_initiate(dev);
872 void rtl8192_tx_enable(struct net_device *dev)
878 void rtl8192_rtx_disable(struct net_device *dev)
880 u8 cmd;
881 struct r8192_priv *priv = ieee80211_priv(dev);
882 struct sk_buff *skb;
883 struct rtl8192_rx_info *info;
885 read_nic_byte(dev, CMDR, &cmd);
886 write_nic_byte(dev, CMDR, cmd & ~(CR_TE|CR_RE));
887 force_pci_posting(dev);
888 mdelay(10);
890 while ((skb = __skb_dequeue(&priv->rx_queue))) {
891 info = (struct rtl8192_rx_info *) skb->cb;
892 if (!info->urb)
893 continue;
895 usb_kill_urb(info->urb);
896 kfree_skb(skb);
899 if (skb_queue_len(&priv->skb_queue))
900 netdev_warn(dev, "skb_queue not empty\n");
902 skb_queue_purge(&priv->skb_queue);
903 return;
907 int alloc_tx_beacon_desc_ring(struct net_device *dev, int count)
909 return 0;
912 inline u16 ieeerate2rtlrate(int rate)
914 switch (rate) {
915 case 10:
916 return 0;
917 case 20:
918 return 1;
919 case 55:
920 return 2;
921 case 110:
922 return 3;
923 case 60:
924 return 4;
925 case 90:
926 return 5;
927 case 120:
928 return 6;
929 case 180:
930 return 7;
931 case 240:
932 return 8;
933 case 360:
934 return 9;
935 case 480:
936 return 10;
937 case 540:
938 return 11;
939 default:
940 return 3;
944 static u16 rtl_rate[] = {10, 20, 55, 110, 60, 90, 120, 180, 240, 360, 480, 540};
945 inline u16 rtl8192_rate2rate(short rate)
947 if (rate > 11) return 0;
948 return rtl_rate[rate];
952 /* The prototype of rx_isr has changed since one version of Linux Kernel */
953 static void rtl8192_rx_isr(struct urb *urb)
955 struct sk_buff *skb = (struct sk_buff *) urb->context;
956 struct rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
957 struct net_device *dev = info->dev;
958 struct r8192_priv *priv = ieee80211_priv(dev);
959 int out_pipe = info->out_pipe;
960 int err;
961 if (!priv->up)
962 return;
963 if (unlikely(urb->status)) {
964 info->urb = NULL;
965 priv->stats.rxstaterr++;
966 priv->ieee80211->stats.rx_errors++;
967 usb_free_urb(urb);
968 return;
970 skb_unlink(skb, &priv->rx_queue);
971 skb_put(skb, urb->actual_length);
973 skb_queue_tail(&priv->skb_queue, skb);
974 tasklet_schedule(&priv->irq_rx_tasklet);
976 skb = dev_alloc_skb(RX_URB_SIZE);
977 if (unlikely(!skb)) {
978 usb_free_urb(urb);
979 netdev_err(dev, "%s(): can't alloc skb\n", __func__);
980 /* TODO check rx queue length and refill *somewhere* */
981 return;
984 usb_fill_bulk_urb(urb, priv->udev,
985 usb_rcvbulkpipe(priv->udev, out_pipe), skb_tail_pointer(skb),
986 RX_URB_SIZE, rtl8192_rx_isr, skb);
988 info = (struct rtl8192_rx_info *) skb->cb;
989 info->urb = urb;
990 info->dev = dev;
991 info->out_pipe = out_pipe;
993 urb->transfer_buffer = skb_tail_pointer(skb);
994 urb->context = skb;
995 skb_queue_tail(&priv->rx_queue, skb);
996 err = usb_submit_urb(urb, GFP_ATOMIC);
997 if (err && err != EPERM)
998 netdev_err(dev, "can not submit rxurb, err is %x, URB status is %x\n", err, urb->status);
1001 u32 rtl819xusb_rx_command_packet(struct net_device *dev,
1002 struct ieee80211_rx_stats *pstats)
1004 u32 status;
1006 status = cmpk_message_handle_rx(dev, pstats);
1007 if (status)
1008 DMESG("rxcommandpackethandle819xusb: It is a command packet\n");
1010 return status;
1014 void rtl8192_data_hard_stop(struct net_device *dev)
1016 //FIXME !!
1020 void rtl8192_data_hard_resume(struct net_device *dev)
1022 // FIXME !!
1025 /* this function TX data frames when the ieee80211 stack requires this.
1026 * It checks also if we need to stop the ieee tx queue, eventually do it
1028 void rtl8192_hard_data_xmit(struct sk_buff *skb, struct net_device *dev, int rate)
1030 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1031 int ret;
1032 unsigned long flags;
1033 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1034 u8 queue_index = tcb_desc->queue_index;
1036 /* shall not be referred by command packet */
1037 RTL8192U_ASSERT(queue_index != TXCMD_QUEUE);
1039 spin_lock_irqsave(&priv->tx_lock, flags);
1041 memcpy((unsigned char *)(skb->cb), &dev, sizeof(dev));
1042 tcb_desc->bTxEnableFwCalcDur = 1;
1043 skb_push(skb, priv->ieee80211->tx_headroom);
1044 ret = rtl8192_tx(dev, skb);
1046 spin_unlock_irqrestore(&priv->tx_lock, flags);
1048 return;
1051 /* This is a rough attempt to TX a frame
1052 * This is called by the ieee 80211 stack to TX management frames.
1053 * If the ring is full packet are dropped (for data frame the queue
1054 * is stopped before this can happen).
1056 int rtl8192_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
1058 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1059 int ret;
1060 unsigned long flags;
1061 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1062 u8 queue_index = tcb_desc->queue_index;
1065 spin_lock_irqsave(&priv->tx_lock, flags);
1067 memcpy((unsigned char *)(skb->cb), &dev, sizeof(dev));
1068 if (queue_index == TXCMD_QUEUE) {
1069 skb_push(skb, USB_HWDESC_HEADER_LEN);
1070 rtl819xU_tx_cmd(dev, skb);
1071 ret = 1;
1072 spin_unlock_irqrestore(&priv->tx_lock, flags);
1073 return ret;
1074 } else {
1075 skb_push(skb, priv->ieee80211->tx_headroom);
1076 ret = rtl8192_tx(dev, skb);
1079 spin_unlock_irqrestore(&priv->tx_lock, flags);
1081 return ret;
1085 void rtl8192_try_wake_queue(struct net_device *dev, int pri);
1087 #ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
1088 u16 DrvAggr_PaddingAdd(struct net_device *dev, struct sk_buff *skb)
1090 u16 PaddingNum = 256 - ((skb->len + TX_PACKET_DRVAGGR_SUBFRAME_SHIFT_BYTES) % 256);
1091 return PaddingNum & 0xff;
1094 u8 MRateToHwRate8190Pci(u8 rate);
1095 u8 QueryIsShort(u8 TxHT, u8 TxRate, cb_desc *tcb_desc);
1096 u8 MapHwQueueToFirmwareQueue(u8 QueueID);
1097 struct sk_buff *DrvAggr_Aggregation(struct net_device *dev, struct ieee80211_drv_agg_txb *pSendList)
1099 struct ieee80211_device *ieee = netdev_priv(dev);
1100 struct r8192_priv *priv = ieee80211_priv(dev);
1101 cb_desc *tcb_desc = NULL;
1102 u8 i;
1103 u32 TotalLength;
1104 struct sk_buff *skb;
1105 struct sk_buff *agg_skb;
1106 tx_desc_819x_usb_aggr_subframe *tx_agg_desc = NULL;
1107 tx_fwinfo_819x_usb *tx_fwinfo = NULL;
1110 // Local variable initialization.
1112 /* first skb initialization */
1113 skb = pSendList->tx_agg_frames[0];
1114 TotalLength = skb->len;
1116 /* Get the total aggregation length including the padding space and
1117 * sub frame header.
1119 for (i = 1; i < pSendList->nr_drv_agg_frames; i++) {
1120 TotalLength += DrvAggr_PaddingAdd(dev, skb);
1121 skb = pSendList->tx_agg_frames[i];
1122 TotalLength += (skb->len + TX_PACKET_DRVAGGR_SUBFRAME_SHIFT_BYTES);
1125 /* allocate skb to contain the aggregated packets */
1126 agg_skb = dev_alloc_skb(TotalLength + ieee->tx_headroom);
1127 memset(agg_skb->data, 0, agg_skb->len);
1128 skb_reserve(agg_skb, ieee->tx_headroom);
1130 /* reserve info for first subframe Tx descriptor to be set in the tx function */
1131 skb = pSendList->tx_agg_frames[0];
1132 tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1133 tcb_desc->drv_agg_enable = 1;
1134 tcb_desc->pkt_size = skb->len;
1135 tcb_desc->DrvAggrNum = pSendList->nr_drv_agg_frames;
1136 netdev_dbg(dev, "DrvAggNum = %d\n", tcb_desc->DrvAggrNum);
1137 memcpy(agg_skb->cb, skb->cb, sizeof(skb->cb));
1138 memcpy(skb_put(agg_skb, skb->len), skb->data, skb->len);
1140 for (i = 1; i < pSendList->nr_drv_agg_frames; i++) {
1141 /* push the next sub frame to be 256 byte aline */
1142 skb_put(agg_skb, DrvAggr_PaddingAdd(dev, skb));
1144 /* Subframe drv Tx descriptor and firmware info setting */
1145 skb = pSendList->tx_agg_frames[i];
1146 tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1147 tx_agg_desc = (tx_desc_819x_usb_aggr_subframe *)skb_tail_pointer(agg_skb);
1148 tx_fwinfo = (tx_fwinfo_819x_usb *)(skb_tail_pointer(agg_skb) + sizeof(tx_desc_819x_usb_aggr_subframe));
1150 memset(tx_fwinfo, 0, sizeof(tx_fwinfo_819x_usb));
1151 /* DWORD 0 */
1152 tx_fwinfo->TxHT = (tcb_desc->data_rate&0x80) ? 1 : 0;
1153 tx_fwinfo->TxRate = MRateToHwRate8190Pci(tcb_desc->data_rate);
1154 tx_fwinfo->EnableCPUDur = tcb_desc->bTxEnableFwCalcDur;
1155 tx_fwinfo->Short = QueryIsShort(tx_fwinfo->TxHT, tx_fwinfo->TxRate, tcb_desc);
1156 if (tcb_desc->bAMPDUEnable) {//AMPDU enabled
1157 tx_fwinfo->AllowAggregation = 1;
1158 /* DWORD 1 */
1159 tx_fwinfo->RxMF = tcb_desc->ampdu_factor;
1160 tx_fwinfo->RxAMD = tcb_desc->ampdu_density&0x07;//ampdudensity
1161 } else {
1162 tx_fwinfo->AllowAggregation = 0;
1163 /* DWORD 1 */
1164 tx_fwinfo->RxMF = 0;
1165 tx_fwinfo->RxAMD = 0;
1168 /* Protection mode related */
1169 tx_fwinfo->RtsEnable = (tcb_desc->bRTSEnable) ? 1 : 0;
1170 tx_fwinfo->CtsEnable = (tcb_desc->bCTSEnable) ? 1 : 0;
1171 tx_fwinfo->RtsSTBC = (tcb_desc->bRTSSTBC) ? 1 : 0;
1172 tx_fwinfo->RtsHT = (tcb_desc->rts_rate&0x80) ? 1 : 0;
1173 tx_fwinfo->RtsRate = MRateToHwRate8190Pci((u8)tcb_desc->rts_rate);
1174 tx_fwinfo->RtsSubcarrier = (tx_fwinfo->RtsHT == 0) ? (tcb_desc->RTSSC) : 0;
1175 tx_fwinfo->RtsBandwidth = (tx_fwinfo->RtsHT == 1) ? ((tcb_desc->bRTSBW) ? 1 : 0) : 0;
1176 tx_fwinfo->RtsShort = (tx_fwinfo->RtsHT == 0) ? (tcb_desc->bRTSUseShortPreamble ? 1 : 0) :
1177 (tcb_desc->bRTSUseShortGI ? 1 : 0);
1179 /* Set Bandwidth and sub-channel settings. */
1180 if (priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20_40) {
1181 if (tcb_desc->bPacketBW) {
1182 tx_fwinfo->TxBandwidth = 1;
1183 tx_fwinfo->TxSubCarrier = 0; //By SD3's Jerry suggestion, use duplicated mode
1184 } else {
1185 tx_fwinfo->TxBandwidth = 0;
1186 tx_fwinfo->TxSubCarrier = priv->nCur40MhzPrimeSC;
1188 } else {
1189 tx_fwinfo->TxBandwidth = 0;
1190 tx_fwinfo->TxSubCarrier = 0;
1193 /* Fill Tx descriptor */
1194 memset(tx_agg_desc, 0, sizeof(tx_desc_819x_usb_aggr_subframe));
1195 /* DWORD 0 */
1196 tx_agg_desc->Offset = sizeof(tx_fwinfo_819x_usb) + 8;
1197 /* already raw data, need not to subtract header length */
1198 tx_agg_desc->PktSize = skb->len & 0xffff;
1200 /*DWORD 1*/
1201 tx_agg_desc->SecCAMID = 0;
1202 tx_agg_desc->RATid = tcb_desc->RATRIndex;
1203 tx_agg_desc->NoEnc = 1;
1204 tx_agg_desc->SecType = 0x0;
1206 if (tcb_desc->bHwSec) {
1207 switch (priv->ieee80211->pairwise_key_type) {
1208 case KEY_TYPE_WEP40:
1209 case KEY_TYPE_WEP104:
1210 tx_agg_desc->SecType = 0x1;
1211 tx_agg_desc->NoEnc = 0;
1212 break;
1213 case KEY_TYPE_TKIP:
1214 tx_agg_desc->SecType = 0x2;
1215 tx_agg_desc->NoEnc = 0;
1216 break;
1217 case KEY_TYPE_CCMP:
1218 tx_agg_desc->SecType = 0x3;
1219 tx_agg_desc->NoEnc = 0;
1220 break;
1221 case KEY_TYPE_NA:
1222 tx_agg_desc->SecType = 0x0;
1223 tx_agg_desc->NoEnc = 1;
1224 break;
1228 tx_agg_desc->QueueSelect = MapHwQueueToFirmwareQueue(tcb_desc->queue_index);
1229 tx_agg_desc->TxFWInfoSize = sizeof(tx_fwinfo_819x_usb);
1231 tx_agg_desc->DISFB = tcb_desc->bTxDisableRateFallBack;
1232 tx_agg_desc->USERATE = tcb_desc->bTxUseDriverAssingedRate;
1234 tx_agg_desc->OWN = 1;
1236 //DWORD 2
1237 /* According windows driver, it seems that there no need to fill this field */
1239 /* to fill next packet */
1240 skb_put(agg_skb, TX_PACKET_DRVAGGR_SUBFRAME_SHIFT_BYTES);
1241 memcpy(skb_put(agg_skb, skb->len), skb->data, skb->len);
1244 for (i = 0; i < pSendList->nr_drv_agg_frames; i++)
1245 dev_kfree_skb_any(pSendList->tx_agg_frames[i]);
1247 return agg_skb;
1250 /* NOTE:
1251 This function return a list of PTCB which is proper to be aggregate with the input TCB.
1252 If no proper TCB is found to do aggregation, SendList will only contain the input TCB.
1254 u8 DrvAggr_GetAggregatibleList(struct net_device *dev, struct sk_buff *skb,
1255 struct ieee80211_drv_agg_txb *pSendList)
1257 struct ieee80211_device *ieee = netdev_priv(dev);
1258 PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
1259 u16 nMaxAggrNum = pHTInfo->UsbTxAggrNum;
1260 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1261 u8 QueueID = tcb_desc->queue_index;
1263 do {
1264 pSendList->tx_agg_frames[pSendList->nr_drv_agg_frames++] = skb;
1265 if (pSendList->nr_drv_agg_frames >= nMaxAggrNum)
1266 break;
1268 } while ((skb = skb_dequeue(&ieee->skb_drv_aggQ[QueueID])));
1270 RT_TRACE(COMP_AMSDU, "DrvAggr_GetAggregatibleList, nAggrTcbNum = %d \n", pSendList->nr_drv_agg_frames);
1271 return pSendList->nr_drv_agg_frames;
1273 #endif
1275 static void rtl8192_tx_isr(struct urb *tx_urb)
1277 struct sk_buff *skb = (struct sk_buff *)tx_urb->context;
1278 struct net_device *dev = NULL;
1279 struct r8192_priv *priv = NULL;
1280 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1281 u8 queue_index = tcb_desc->queue_index;
1283 memcpy(&dev, (struct net_device *)(skb->cb), sizeof(struct net_device *));
1284 priv = ieee80211_priv(dev);
1286 if (tcb_desc->queue_index != TXCMD_QUEUE) {
1287 if (tx_urb->status == 0) {
1288 dev->trans_start = jiffies;
1289 priv->stats.txoktotal++;
1290 priv->ieee80211->LinkDetectInfo.NumTxOkInPeriod++;
1291 priv->stats.txbytesunicast += (skb->len - priv->ieee80211->tx_headroom);
1292 } else {
1293 priv->ieee80211->stats.tx_errors++;
1294 /* TODO */
1298 /* free skb and tx_urb */
1299 if (skb != NULL) {
1300 dev_kfree_skb_any(skb);
1301 usb_free_urb(tx_urb);
1302 atomic_dec(&priv->tx_pending[queue_index]);
1306 // Handle HW Beacon:
1307 // We had transfer our beacon frame to host controller at this moment.
1310 // Caution:
1311 // Handling the wait queue of command packets.
1312 // For Tx command packets, we must not do TCB fragment because it is not handled right now.
1313 // We must cut the packets to match the size of TX_CMD_PKT before we send it.
1316 /* Handle MPDU in wait queue. */
1317 if (queue_index != BEACON_QUEUE) {
1318 /* Don't send data frame during scanning.*/
1319 if ((skb_queue_len(&priv->ieee80211->skb_waitQ[queue_index]) != 0) &&
1320 (!(priv->ieee80211->queue_stop))) {
1321 if (NULL != (skb = skb_dequeue(&(priv->ieee80211->skb_waitQ[queue_index]))))
1322 priv->ieee80211->softmac_hard_start_xmit(skb, dev);
1324 return; //modified by david to avoid further processing AMSDU
1326 #ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
1327 else if ((skb_queue_len(&priv->ieee80211->skb_drv_aggQ[queue_index]) != 0) &&
1328 (!(priv->ieee80211->queue_stop))) {
1329 // Tx Driver Aggregation process
1330 /* The driver will aggregation the packets according to the following stats
1331 * 1. check whether there's tx irq available, for it's a completion return
1332 * function, it should contain enough tx irq;
1333 * 2. check packet type;
1334 * 3. initialize sendlist, check whether the to-be send packet no greater than 1
1335 * 4. aggregates the packets, and fill firmware info and tx desc into it, etc.
1336 * 5. check whether the packet could be sent, otherwise just insert into wait head
1337 * */
1338 skb = skb_dequeue(&priv->ieee80211->skb_drv_aggQ[queue_index]);
1339 if (!check_nic_enough_desc(dev, queue_index)) {
1340 skb_queue_head(&(priv->ieee80211->skb_drv_aggQ[queue_index]), skb);
1341 return;
1344 /*TODO*/
1346 struct ieee80211_drv_agg_txb SendList;
1348 memset(&SendList, 0, sizeof(struct ieee80211_drv_agg_txb));
1349 if (DrvAggr_GetAggregatibleList(dev, skb, &SendList) > 1) {
1350 skb = DrvAggr_Aggregation(dev, &SendList);
1354 priv->ieee80211->softmac_hard_start_xmit(skb, dev);
1356 #endif
1361 void rtl8192_beacon_stop(struct net_device *dev)
1363 u8 msr, msrm, msr2;
1364 struct r8192_priv *priv = ieee80211_priv(dev);
1366 read_nic_byte(dev, MSR, &msr);
1367 msrm = msr & MSR_LINK_MASK;
1368 msr2 = msr & ~MSR_LINK_MASK;
1370 if (NIC_8192U == priv->card_8192)
1371 usb_kill_urb(priv->rx_urb[MAX_RX_URB]);
1372 if ((msrm == (MSR_LINK_ADHOC<<MSR_LINK_SHIFT) ||
1373 (msrm == (MSR_LINK_MASTER<<MSR_LINK_SHIFT)))) {
1374 write_nic_byte(dev, MSR, msr2 | MSR_LINK_NONE);
1375 write_nic_byte(dev, MSR, msr);
1379 void rtl8192_config_rate(struct net_device *dev, u16 *rate_config)
1381 struct r8192_priv *priv = ieee80211_priv(dev);
1382 struct ieee80211_network *net;
1383 u8 i = 0, basic_rate = 0;
1384 net = &priv->ieee80211->current_network;
1386 for (i = 0; i < net->rates_len; i++) {
1387 basic_rate = net->rates[i]&0x7f;
1388 switch (basic_rate) {
1389 case MGN_1M: *rate_config |= RRSR_1M; break;
1390 case MGN_2M: *rate_config |= RRSR_2M; break;
1391 case MGN_5_5M: *rate_config |= RRSR_5_5M; break;
1392 case MGN_11M: *rate_config |= RRSR_11M; break;
1393 case MGN_6M: *rate_config |= RRSR_6M; break;
1394 case MGN_9M: *rate_config |= RRSR_9M; break;
1395 case MGN_12M: *rate_config |= RRSR_12M; break;
1396 case MGN_18M: *rate_config |= RRSR_18M; break;
1397 case MGN_24M: *rate_config |= RRSR_24M; break;
1398 case MGN_36M: *rate_config |= RRSR_36M; break;
1399 case MGN_48M: *rate_config |= RRSR_48M; break;
1400 case MGN_54M: *rate_config |= RRSR_54M; break;
1403 for (i = 0; i < net->rates_ex_len; i++) {
1404 basic_rate = net->rates_ex[i]&0x7f;
1405 switch (basic_rate) {
1406 case MGN_1M: *rate_config |= RRSR_1M; break;
1407 case MGN_2M: *rate_config |= RRSR_2M; break;
1408 case MGN_5_5M: *rate_config |= RRSR_5_5M; break;
1409 case MGN_11M: *rate_config |= RRSR_11M; break;
1410 case MGN_6M: *rate_config |= RRSR_6M; break;
1411 case MGN_9M: *rate_config |= RRSR_9M; break;
1412 case MGN_12M: *rate_config |= RRSR_12M; break;
1413 case MGN_18M: *rate_config |= RRSR_18M; break;
1414 case MGN_24M: *rate_config |= RRSR_24M; break;
1415 case MGN_36M: *rate_config |= RRSR_36M; break;
1416 case MGN_48M: *rate_config |= RRSR_48M; break;
1417 case MGN_54M: *rate_config |= RRSR_54M; break;
1423 #define SHORT_SLOT_TIME 9
1424 #define NON_SHORT_SLOT_TIME 20
1426 void rtl8192_update_cap(struct net_device *dev, u16 cap)
1428 u32 tmp = 0;
1429 struct r8192_priv *priv = ieee80211_priv(dev);
1430 struct ieee80211_network *net = &priv->ieee80211->current_network;
1431 priv->short_preamble = cap & WLAN_CAPABILITY_SHORT_PREAMBLE;
1432 tmp = priv->basic_rate;
1433 if (priv->short_preamble)
1434 tmp |= BRSR_AckShortPmb;
1435 write_nic_dword(dev, RRSR, tmp);
1437 if (net->mode & (IEEE_G|IEEE_N_24G)) {
1438 u8 slot_time = 0;
1439 if ((cap & WLAN_CAPABILITY_SHORT_SLOT) && (!priv->ieee80211->pHTInfo->bCurrentRT2RTLongSlotTime)) //short slot time
1440 slot_time = SHORT_SLOT_TIME;
1441 else //long slot time
1442 slot_time = NON_SHORT_SLOT_TIME;
1443 priv->slot_time = slot_time;
1444 write_nic_byte(dev, SLOT_TIME, slot_time);
1448 void rtl8192_net_update(struct net_device *dev)
1451 struct r8192_priv *priv = ieee80211_priv(dev);
1452 struct ieee80211_network *net;
1453 u16 BcnTimeCfg = 0, BcnCW = 6, BcnIFS = 0xf;
1454 u16 rate_config = 0;
1455 net = &priv->ieee80211->current_network;
1457 rtl8192_config_rate(dev, &rate_config);
1458 priv->basic_rate = rate_config &= 0x15f;
1460 write_nic_dword(dev, BSSIDR, ((u32 *)net->bssid)[0]);
1461 write_nic_word(dev, BSSIDR+4, ((u16 *)net->bssid)[2]);
1463 rtl8192_update_msr(dev);
1464 if (priv->ieee80211->iw_mode == IW_MODE_ADHOC) {
1465 write_nic_word(dev, ATIMWND, 2);
1466 write_nic_word(dev, BCN_DMATIME, 1023);
1467 write_nic_word(dev, BCN_INTERVAL, net->beacon_interval);
1468 write_nic_word(dev, BCN_DRV_EARLY_INT, 1);
1469 write_nic_byte(dev, BCN_ERR_THRESH, 100);
1470 BcnTimeCfg |= (BcnCW<<BCN_TCFG_CW_SHIFT);
1471 // TODO: BcnIFS may required to be changed on ASIC
1472 BcnTimeCfg |= BcnIFS<<BCN_TCFG_IFS;
1474 write_nic_word(dev, BCN_TCFG, BcnTimeCfg);
1481 //temporary hw beacon is not used any more.
1482 //open it when necessary
1483 void rtl819xusb_beacon_tx(struct net_device *dev, u16 tx_rate)
1487 inline u8 rtl8192_IsWirelessBMode(u16 rate)
1489 if (((rate <= 110) && (rate != 60) && (rate != 90)) || (rate == 220))
1490 return 1;
1491 else return 0;
1494 u16 N_DBPSOfRate(u16 DataRate);
1496 u16 ComputeTxTime(u16 FrameLength, u16 DataRate, u8 bManagementFrame,
1497 u8 bShortPreamble)
1499 u16 FrameTime;
1500 u16 N_DBPS;
1501 u16 Ceiling;
1503 if (rtl8192_IsWirelessBMode(DataRate)) {
1504 if (bManagementFrame || !bShortPreamble || DataRate == 10) // long preamble
1505 FrameTime = (u16)(144+48+(FrameLength*8/(DataRate/10)));
1506 else // Short preamble
1507 FrameTime = (u16)(72+24+(FrameLength*8/(DataRate/10)));
1508 if ((FrameLength*8 % (DataRate/10)) != 0) //Get the Ceilling
1509 FrameTime++;
1510 } else { //802.11g DSSS-OFDM PLCP length field calculation.
1511 N_DBPS = N_DBPSOfRate(DataRate);
1512 Ceiling = (16 + 8*FrameLength + 6) / N_DBPS
1513 + (((16 + 8*FrameLength + 6) % N_DBPS) ? 1 : 0);
1514 FrameTime = (u16)(16 + 4 + 4*Ceiling + 6);
1516 return FrameTime;
1519 u16 N_DBPSOfRate(u16 DataRate)
1521 u16 N_DBPS = 24;
1523 switch (DataRate) {
1524 case 60:
1525 N_DBPS = 24;
1526 break;
1528 case 90:
1529 N_DBPS = 36;
1530 break;
1532 case 120:
1533 N_DBPS = 48;
1534 break;
1536 case 180:
1537 N_DBPS = 72;
1538 break;
1540 case 240:
1541 N_DBPS = 96;
1542 break;
1544 case 360:
1545 N_DBPS = 144;
1546 break;
1548 case 480:
1549 N_DBPS = 192;
1550 break;
1552 case 540:
1553 N_DBPS = 216;
1554 break;
1556 default:
1557 break;
1560 return N_DBPS;
1563 void rtl819xU_cmd_isr(struct urb *tx_cmd_urb, struct pt_regs *regs)
1565 usb_free_urb(tx_cmd_urb);
1568 unsigned int txqueue2outpipe(struct r8192_priv *priv, unsigned int tx_queue)
1570 if (tx_queue >= 9) {
1571 RT_TRACE(COMP_ERR, "%s():Unknown queue ID!!!\n", __func__);
1572 return 0x04;
1574 return priv->txqueue_to_outpipemap[tx_queue];
1577 short rtl819xU_tx_cmd(struct net_device *dev, struct sk_buff *skb)
1579 struct r8192_priv *priv = ieee80211_priv(dev);
1580 int status;
1581 struct urb *tx_urb;
1582 unsigned int idx_pipe;
1583 tx_desc_cmd_819x_usb *pdesc = (tx_desc_cmd_819x_usb *)skb->data;
1584 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1585 u8 queue_index = tcb_desc->queue_index;
1587 atomic_inc(&priv->tx_pending[queue_index]);
1588 tx_urb = usb_alloc_urb(0, GFP_ATOMIC);
1589 if (!tx_urb) {
1590 dev_kfree_skb(skb);
1591 return -ENOMEM;
1594 memset(pdesc, 0, USB_HWDESC_HEADER_LEN);
1595 /* Tx descriptor ought to be set according to the skb->cb */
1596 pdesc->FirstSeg = 1;//bFirstSeg;
1597 pdesc->LastSeg = 1;//bLastSeg;
1598 pdesc->CmdInit = tcb_desc->bCmdOrInit;
1599 pdesc->TxBufferSize = tcb_desc->txbuf_size;
1600 pdesc->OWN = 1;
1601 pdesc->LINIP = tcb_desc->bLastIniPkt;
1603 //----------------------------------------------------------------------------
1604 // Fill up USB_OUT_CONTEXT.
1605 //----------------------------------------------------------------------------
1606 // Get index to out pipe from specified QueueID.
1607 #ifndef USE_ONE_PIPE
1608 idx_pipe = txqueue2outpipe(priv, queue_index);
1609 #else
1610 idx_pipe = 0x04;
1611 #endif
1612 #ifdef JOHN_DUMP_TXDESC
1613 int i;
1614 printk("<Tx descriptor>--rate %x---", rate);
1615 for (i = 0; i < 8; i++)
1616 printk("%8x ", tx[i]);
1617 printk("\n");
1618 #endif
1619 usb_fill_bulk_urb(tx_urb, priv->udev, usb_sndbulkpipe(priv->udev, idx_pipe),
1620 skb->data, skb->len, rtl8192_tx_isr, skb);
1622 status = usb_submit_urb(tx_urb, GFP_ATOMIC);
1624 if (!status) {
1625 return 0;
1626 } else {
1627 DMESGE("Error TX CMD URB, error %d", status);
1628 return -1;
1633 * Mapping Software/Hardware descriptor queue id to "Queue Select Field"
1634 * in TxFwInfo data structure
1635 * 2006.10.30 by Emily
1637 * \param QUEUEID Software Queue
1639 u8 MapHwQueueToFirmwareQueue(u8 QueueID)
1641 u8 QueueSelect = 0x0; //defualt set to
1643 switch (QueueID) {
1644 case BE_QUEUE:
1645 QueueSelect = QSLT_BE;
1646 break;
1648 case BK_QUEUE:
1649 QueueSelect = QSLT_BK;
1650 break;
1652 case VO_QUEUE:
1653 QueueSelect = QSLT_VO;
1654 break;
1656 case VI_QUEUE:
1657 QueueSelect = QSLT_VI;
1658 break;
1659 case MGNT_QUEUE:
1660 QueueSelect = QSLT_MGNT;
1661 break;
1663 case BEACON_QUEUE:
1664 QueueSelect = QSLT_BEACON;
1665 break;
1667 // TODO: 2006.10.30 mark other queue selection until we verify it is OK
1668 // TODO: Remove Assertions
1669 case TXCMD_QUEUE:
1670 QueueSelect = QSLT_CMD;
1671 break;
1672 case HIGH_QUEUE:
1673 QueueSelect = QSLT_HIGH;
1674 break;
1676 default:
1677 RT_TRACE(COMP_ERR, "TransmitTCB(): Impossible Queue Selection: %d \n", QueueID);
1678 break;
1680 return QueueSelect;
1683 u8 MRateToHwRate8190Pci(u8 rate)
1685 u8 ret = DESC90_RATE1M;
1687 switch (rate) {
1688 case MGN_1M: ret = DESC90_RATE1M; break;
1689 case MGN_2M: ret = DESC90_RATE2M; break;
1690 case MGN_5_5M: ret = DESC90_RATE5_5M; break;
1691 case MGN_11M: ret = DESC90_RATE11M; break;
1692 case MGN_6M: ret = DESC90_RATE6M; break;
1693 case MGN_9M: ret = DESC90_RATE9M; break;
1694 case MGN_12M: ret = DESC90_RATE12M; break;
1695 case MGN_18M: ret = DESC90_RATE18M; break;
1696 case MGN_24M: ret = DESC90_RATE24M; break;
1697 case MGN_36M: ret = DESC90_RATE36M; break;
1698 case MGN_48M: ret = DESC90_RATE48M; break;
1699 case MGN_54M: ret = DESC90_RATE54M; break;
1701 // HT rate since here
1702 case MGN_MCS0: ret = DESC90_RATEMCS0; break;
1703 case MGN_MCS1: ret = DESC90_RATEMCS1; break;
1704 case MGN_MCS2: ret = DESC90_RATEMCS2; break;
1705 case MGN_MCS3: ret = DESC90_RATEMCS3; break;
1706 case MGN_MCS4: ret = DESC90_RATEMCS4; break;
1707 case MGN_MCS5: ret = DESC90_RATEMCS5; break;
1708 case MGN_MCS6: ret = DESC90_RATEMCS6; break;
1709 case MGN_MCS7: ret = DESC90_RATEMCS7; break;
1710 case MGN_MCS8: ret = DESC90_RATEMCS8; break;
1711 case MGN_MCS9: ret = DESC90_RATEMCS9; break;
1712 case MGN_MCS10: ret = DESC90_RATEMCS10; break;
1713 case MGN_MCS11: ret = DESC90_RATEMCS11; break;
1714 case MGN_MCS12: ret = DESC90_RATEMCS12; break;
1715 case MGN_MCS13: ret = DESC90_RATEMCS13; break;
1716 case MGN_MCS14: ret = DESC90_RATEMCS14; break;
1717 case MGN_MCS15: ret = DESC90_RATEMCS15; break;
1718 case (0x80|0x20): ret = DESC90_RATEMCS32; break;
1720 default: break;
1722 return ret;
1726 u8 QueryIsShort(u8 TxHT, u8 TxRate, cb_desc *tcb_desc)
1728 u8 tmp_Short;
1730 tmp_Short = (TxHT == 1) ? ((tcb_desc->bUseShortGI) ? 1 : 0) : ((tcb_desc->bUseShortPreamble) ? 1 : 0);
1732 if (TxHT == 1 && TxRate != DESC90_RATEMCS15)
1733 tmp_Short = 0;
1735 return tmp_Short;
1738 static void tx_zero_isr(struct urb *tx_urb)
1740 return;
1744 * The tx procedure is just as following,
1745 * skb->cb will contain all the following information,
1746 * priority, morefrag, rate, &dev.
1747 * */
1748 short rtl8192_tx(struct net_device *dev, struct sk_buff *skb)
1750 struct r8192_priv *priv = ieee80211_priv(dev);
1751 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1752 tx_desc_819x_usb *tx_desc = (tx_desc_819x_usb *)skb->data;
1753 tx_fwinfo_819x_usb *tx_fwinfo = (tx_fwinfo_819x_usb *)(skb->data + USB_HWDESC_HEADER_LEN);
1754 struct usb_device *udev = priv->udev;
1755 int pend;
1756 int status;
1757 struct urb *tx_urb = NULL, *tx_urb_zero = NULL;
1758 unsigned int idx_pipe;
1759 pend = atomic_read(&priv->tx_pending[tcb_desc->queue_index]);
1760 /* we are locked here so the two atomic_read and inc are executed
1761 * without interleaves
1762 * !!! For debug purpose
1764 if (pend > MAX_TX_URB) {
1765 netdev_dbg(dev, "To discard skb packet!\n");
1766 dev_kfree_skb_any(skb);
1767 return -1;
1770 tx_urb = usb_alloc_urb(0, GFP_ATOMIC);
1771 if (!tx_urb) {
1772 dev_kfree_skb_any(skb);
1773 return -ENOMEM;
1776 /* Fill Tx firmware info */
1777 memset(tx_fwinfo, 0, sizeof(tx_fwinfo_819x_usb));
1778 /* DWORD 0 */
1779 tx_fwinfo->TxHT = (tcb_desc->data_rate&0x80) ? 1 : 0;
1780 tx_fwinfo->TxRate = MRateToHwRate8190Pci(tcb_desc->data_rate);
1781 tx_fwinfo->EnableCPUDur = tcb_desc->bTxEnableFwCalcDur;
1782 tx_fwinfo->Short = QueryIsShort(tx_fwinfo->TxHT, tx_fwinfo->TxRate, tcb_desc);
1783 if (tcb_desc->bAMPDUEnable) {//AMPDU enabled
1784 tx_fwinfo->AllowAggregation = 1;
1785 /* DWORD 1 */
1786 tx_fwinfo->RxMF = tcb_desc->ampdu_factor;
1787 tx_fwinfo->RxAMD = tcb_desc->ampdu_density&0x07;//ampdudensity
1788 } else {
1789 tx_fwinfo->AllowAggregation = 0;
1790 /* DWORD 1 */
1791 tx_fwinfo->RxMF = 0;
1792 tx_fwinfo->RxAMD = 0;
1795 /* Protection mode related */
1796 tx_fwinfo->RtsEnable = (tcb_desc->bRTSEnable) ? 1 : 0;
1797 tx_fwinfo->CtsEnable = (tcb_desc->bCTSEnable) ? 1 : 0;
1798 tx_fwinfo->RtsSTBC = (tcb_desc->bRTSSTBC) ? 1 : 0;
1799 tx_fwinfo->RtsHT = (tcb_desc->rts_rate&0x80) ? 1 : 0;
1800 tx_fwinfo->RtsRate = MRateToHwRate8190Pci((u8)tcb_desc->rts_rate);
1801 tx_fwinfo->RtsSubcarrier = (tx_fwinfo->RtsHT == 0) ? (tcb_desc->RTSSC) : 0;
1802 tx_fwinfo->RtsBandwidth = (tx_fwinfo->RtsHT == 1) ? ((tcb_desc->bRTSBW) ? 1 : 0) : 0;
1803 tx_fwinfo->RtsShort = (tx_fwinfo->RtsHT == 0) ? (tcb_desc->bRTSUseShortPreamble ? 1 : 0) :
1804 (tcb_desc->bRTSUseShortGI ? 1 : 0);
1806 /* Set Bandwidth and sub-channel settings. */
1807 if (priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20_40) {
1808 if (tcb_desc->bPacketBW) {
1809 tx_fwinfo->TxBandwidth = 1;
1810 tx_fwinfo->TxSubCarrier = 0; //By SD3's Jerry suggestion, use duplicated mode
1811 } else {
1812 tx_fwinfo->TxBandwidth = 0;
1813 tx_fwinfo->TxSubCarrier = priv->nCur40MhzPrimeSC;
1815 } else {
1816 tx_fwinfo->TxBandwidth = 0;
1817 tx_fwinfo->TxSubCarrier = 0;
1820 #ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
1821 if (tcb_desc->drv_agg_enable)
1822 tx_fwinfo->Tx_INFO_RSVD = (tcb_desc->DrvAggrNum & 0x1f) << 1;
1823 #endif
1824 /* Fill Tx descriptor */
1825 memset(tx_desc, 0, sizeof(tx_desc_819x_usb));
1826 /* DWORD 0 */
1827 tx_desc->LINIP = 0;
1828 tx_desc->CmdInit = 1;
1829 tx_desc->Offset = sizeof(tx_fwinfo_819x_usb) + 8;
1831 #ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
1832 if (tcb_desc->drv_agg_enable)
1833 tx_desc->PktSize = tcb_desc->pkt_size;
1834 else
1835 #endif
1837 tx_desc->PktSize = (skb->len - TX_PACKET_SHIFT_BYTES) & 0xffff;
1840 /*DWORD 1*/
1841 tx_desc->SecCAMID = 0;
1842 tx_desc->RATid = tcb_desc->RATRIndex;
1843 tx_desc->NoEnc = 1;
1844 tx_desc->SecType = 0x0;
1845 if (tcb_desc->bHwSec) {
1846 switch (priv->ieee80211->pairwise_key_type) {
1847 case KEY_TYPE_WEP40:
1848 case KEY_TYPE_WEP104:
1849 tx_desc->SecType = 0x1;
1850 tx_desc->NoEnc = 0;
1851 break;
1852 case KEY_TYPE_TKIP:
1853 tx_desc->SecType = 0x2;
1854 tx_desc->NoEnc = 0;
1855 break;
1856 case KEY_TYPE_CCMP:
1857 tx_desc->SecType = 0x3;
1858 tx_desc->NoEnc = 0;
1859 break;
1860 case KEY_TYPE_NA:
1861 tx_desc->SecType = 0x0;
1862 tx_desc->NoEnc = 1;
1863 break;
1867 tx_desc->QueueSelect = MapHwQueueToFirmwareQueue(tcb_desc->queue_index);
1868 tx_desc->TxFWInfoSize = sizeof(tx_fwinfo_819x_usb);
1870 tx_desc->DISFB = tcb_desc->bTxDisableRateFallBack;
1871 tx_desc->USERATE = tcb_desc->bTxUseDriverAssingedRate;
1873 /* Fill fields that are required to be initialized in all of the descriptors */
1874 //DWORD 0
1875 tx_desc->FirstSeg = 1;
1876 tx_desc->LastSeg = 1;
1877 tx_desc->OWN = 1;
1879 #ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
1880 if (tcb_desc->drv_agg_enable) {
1881 tx_desc->TxBufferSize = tcb_desc->pkt_size + sizeof(tx_fwinfo_819x_usb);
1882 } else
1883 #endif
1885 //DWORD 2
1886 tx_desc->TxBufferSize = (u32)(skb->len - USB_HWDESC_HEADER_LEN);
1888 /* Get index to out pipe from specified QueueID */
1889 #ifndef USE_ONE_PIPE
1890 idx_pipe = txqueue2outpipe(priv, tcb_desc->queue_index);
1891 #else
1892 idx_pipe = 0x5;
1893 #endif
1895 /* To submit bulk urb */
1896 usb_fill_bulk_urb(tx_urb, udev,
1897 usb_sndbulkpipe(udev, idx_pipe), skb->data,
1898 skb->len, rtl8192_tx_isr, skb);
1900 status = usb_submit_urb(tx_urb, GFP_ATOMIC);
1901 if (!status) {
1902 //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
1903 bool bSend0Byte = false;
1904 u8 zero = 0;
1905 if (udev->speed == USB_SPEED_HIGH) {
1906 if (skb->len > 0 && skb->len % 512 == 0)
1907 bSend0Byte = true;
1908 } else {
1909 if (skb->len > 0 && skb->len % 64 == 0)
1910 bSend0Byte = true;
1912 if (bSend0Byte) {
1913 tx_urb_zero = usb_alloc_urb(0, GFP_ATOMIC);
1914 if (!tx_urb_zero) {
1915 RT_TRACE(COMP_ERR, "can't alloc urb for zero byte\n");
1916 return -ENOMEM;
1918 usb_fill_bulk_urb(tx_urb_zero, udev,
1919 usb_sndbulkpipe(udev, idx_pipe), &zero,
1920 0, tx_zero_isr, dev);
1921 status = usb_submit_urb(tx_urb_zero, GFP_ATOMIC);
1922 if (status) {
1923 RT_TRACE(COMP_ERR, "Error TX URB for zero byte %d, error %d", atomic_read(&priv->tx_pending[tcb_desc->queue_index]), status);
1924 return -1;
1927 dev->trans_start = jiffies;
1928 atomic_inc(&priv->tx_pending[tcb_desc->queue_index]);
1929 return 0;
1930 } else {
1931 RT_TRACE(COMP_ERR, "Error TX URB %d, error %d", atomic_read(&priv->tx_pending[tcb_desc->queue_index]),
1932 status);
1933 return -1;
1937 short rtl8192_usb_initendpoints(struct net_device *dev)
1939 struct r8192_priv *priv = ieee80211_priv(dev);
1941 priv->rx_urb = kmalloc(sizeof(struct urb *) * (MAX_RX_URB+1),
1942 GFP_KERNEL);
1943 if (priv->rx_urb == NULL)
1944 return -ENOMEM;
1946 #ifndef JACKSON_NEW_RX
1947 for (i = 0; i < (MAX_RX_URB+1); i++) {
1949 priv->rx_urb[i] = usb_alloc_urb(0, GFP_KERNEL);
1951 priv->rx_urb[i]->transfer_buffer = kmalloc(RX_URB_SIZE, GFP_KERNEL);
1953 priv->rx_urb[i]->transfer_buffer_length = RX_URB_SIZE;
1955 #endif
1957 #ifdef THOMAS_BEACON
1959 long align = 0;
1960 void *oldaddr, *newaddr;
1962 priv->rx_urb[16] = usb_alloc_urb(0, GFP_KERNEL);
1963 priv->oldaddr = kmalloc(16, GFP_KERNEL);
1964 oldaddr = priv->oldaddr;
1965 align = ((long)oldaddr) & 3;
1966 if (align) {
1967 newaddr = oldaddr + 4 - align;
1968 priv->rx_urb[16]->transfer_buffer_length = 16 - 4 + align;
1969 } else {
1970 newaddr = oldaddr;
1971 priv->rx_urb[16]->transfer_buffer_length = 16;
1973 priv->rx_urb[16]->transfer_buffer = newaddr;
1975 #endif
1977 memset(priv->rx_urb, 0, sizeof(struct urb *) * MAX_RX_URB);
1978 priv->pp_rxskb = kcalloc(MAX_RX_URB, sizeof(struct sk_buff *),
1979 GFP_KERNEL);
1980 if (!priv->pp_rxskb) {
1981 kfree(priv->rx_urb);
1983 priv->pp_rxskb = NULL;
1984 priv->rx_urb = NULL;
1986 DMESGE("Endpoint Alloc Failure");
1987 return -ENOMEM;
1990 netdev_dbg(dev, "End of initendpoints\n");
1991 return 0;
1994 #ifdef THOMAS_BEACON
1995 void rtl8192_usb_deleteendpoints(struct net_device *dev)
1997 int i;
1998 struct r8192_priv *priv = ieee80211_priv(dev);
2000 if (priv->rx_urb) {
2001 for (i = 0; i < (MAX_RX_URB+1); i++) {
2002 usb_kill_urb(priv->rx_urb[i]);
2003 usb_free_urb(priv->rx_urb[i]);
2005 kfree(priv->rx_urb);
2006 priv->rx_urb = NULL;
2008 kfree(priv->oldaddr);
2009 priv->oldaddr = NULL;
2010 if (priv->pp_rxskb) {
2011 kfree(priv->pp_rxskb);
2012 priv->pp_rxskb = 0;
2015 #else
2016 void rtl8192_usb_deleteendpoints(struct net_device *dev)
2018 int i;
2019 struct r8192_priv *priv = ieee80211_priv(dev);
2021 #ifndef JACKSON_NEW_RX
2023 if (priv->rx_urb) {
2024 for (i = 0; i < (MAX_RX_URB+1); i++) {
2025 usb_kill_urb(priv->rx_urb[i]);
2026 kfree(priv->rx_urb[i]->transfer_buffer);
2027 usb_free_urb(priv->rx_urb[i]);
2029 kfree(priv->rx_urb);
2030 priv->rx_urb = NULL;
2033 #else
2034 kfree(priv->rx_urb);
2035 priv->rx_urb = NULL;
2036 kfree(priv->oldaddr);
2037 priv->oldaddr = NULL;
2038 if (priv->pp_rxskb) {
2039 kfree(priv->pp_rxskb);
2040 priv->pp_rxskb = 0;
2044 #endif
2046 #endif
2048 extern void rtl8192_update_ratr_table(struct net_device *dev);
2049 void rtl8192_link_change(struct net_device *dev)
2051 struct r8192_priv *priv = ieee80211_priv(dev);
2052 struct ieee80211_device *ieee = priv->ieee80211;
2053 if (ieee->state == IEEE80211_LINKED) {
2054 rtl8192_net_update(dev);
2055 rtl8192_update_ratr_table(dev);
2056 //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
2057 if ((KEY_TYPE_WEP40 == ieee->pairwise_key_type) || (KEY_TYPE_WEP104 == ieee->pairwise_key_type))
2058 EnableHWSecurityConfig8192(dev);
2060 /*update timing params*/
2061 if (ieee->iw_mode == IW_MODE_INFRA || ieee->iw_mode == IW_MODE_ADHOC) {
2062 u32 reg = 0;
2063 read_nic_dword(dev, RCR, &reg);
2064 if (priv->ieee80211->state == IEEE80211_LINKED)
2065 priv->ReceiveConfig = reg |= RCR_CBSSID;
2066 else
2067 priv->ReceiveConfig = reg &= ~RCR_CBSSID;
2068 write_nic_dword(dev, RCR, reg);
2072 static struct ieee80211_qos_parameters def_qos_parameters = {
2073 {3, 3, 3, 3},/* cw_min */
2074 {7, 7, 7, 7},/* cw_max */
2075 {2, 2, 2, 2},/* aifs */
2076 {0, 0, 0, 0},/* flags */
2077 {0, 0, 0, 0} /* tx_op_limit */
2081 void rtl8192_update_beacon(struct work_struct *work)
2083 struct r8192_priv *priv = container_of(work, struct r8192_priv, update_beacon_wq.work);
2084 struct net_device *dev = priv->ieee80211->dev;
2085 struct ieee80211_device *ieee = priv->ieee80211;
2086 struct ieee80211_network *net = &ieee->current_network;
2088 if (ieee->pHTInfo->bCurrentHTSupport)
2089 HTUpdateSelfAndPeerSetting(ieee, net);
2090 ieee->pHTInfo->bCurrentRT2RTLongSlotTime = net->bssht.bdRT2RTLongSlotTime;
2091 rtl8192_update_cap(dev, net->capability);
2094 * background support to run QoS activate functionality
2096 int WDCAPARA_ADD[] = {EDCAPARA_BE, EDCAPARA_BK, EDCAPARA_VI, EDCAPARA_VO};
2097 void rtl8192_qos_activate(struct work_struct *work)
2099 struct r8192_priv *priv = container_of(work, struct r8192_priv, qos_activate);
2100 struct net_device *dev = priv->ieee80211->dev;
2101 struct ieee80211_qos_parameters *qos_parameters = &priv->ieee80211->current_network.qos_data.parameters;
2102 u8 mode = priv->ieee80211->current_network.mode;
2103 u8 u1bAIFS;
2104 u32 u4bAcParam;
2105 int i;
2107 if (priv == NULL)
2108 return;
2110 mutex_lock(&priv->mutex);
2111 if (priv->ieee80211->state != IEEE80211_LINKED)
2112 goto success;
2113 RT_TRACE(COMP_QOS, "qos active process with associate response received\n");
2114 /* It better set slot time at first */
2115 /* For we just support b/g mode at present, let the slot time at 9/20 selection */
2116 /* update the ac parameter to related registers */
2117 for (i = 0; i < QOS_QUEUE_NUM; i++) {
2118 //Mode G/A: slotTimeTimer = 9; Mode B: 20
2119 u1bAIFS = qos_parameters->aifs[i] * ((mode&(IEEE_G|IEEE_N_24G)) ? 9 : 20) + aSifsTime;
2120 u4bAcParam = ((((u32)(qos_parameters->tx_op_limit[i]))<< AC_PARAM_TXOP_LIMIT_OFFSET)|
2121 (((u32)(qos_parameters->cw_max[i]))<< AC_PARAM_ECW_MAX_OFFSET)|
2122 (((u32)(qos_parameters->cw_min[i]))<< AC_PARAM_ECW_MIN_OFFSET)|
2123 ((u32)u1bAIFS << AC_PARAM_AIFS_OFFSET));
2125 write_nic_dword(dev, WDCAPARA_ADD[i], u4bAcParam);
2128 success:
2129 mutex_unlock(&priv->mutex);
2132 static int rtl8192_qos_handle_probe_response(struct r8192_priv *priv,
2133 int active_network,
2134 struct ieee80211_network *network)
2136 int ret = 0;
2137 u32 size = sizeof(struct ieee80211_qos_parameters);
2139 if (priv->ieee80211->state != IEEE80211_LINKED)
2140 return ret;
2142 if ((priv->ieee80211->iw_mode != IW_MODE_INFRA))
2143 return ret;
2145 if (network->flags & NETWORK_HAS_QOS_MASK) {
2146 if (active_network &&
2147 (network->flags & NETWORK_HAS_QOS_PARAMETERS))
2148 network->qos_data.active = network->qos_data.supported;
2150 if ((network->qos_data.active == 1) && (active_network == 1) &&
2151 (network->flags & NETWORK_HAS_QOS_PARAMETERS) &&
2152 (network->qos_data.old_param_count !=
2153 network->qos_data.param_count)) {
2154 network->qos_data.old_param_count =
2155 network->qos_data.param_count;
2156 queue_work(priv->priv_wq, &priv->qos_activate);
2157 RT_TRACE(COMP_QOS, "QoS parameters change call "
2158 "qos_activate\n");
2160 } else {
2161 memcpy(&priv->ieee80211->current_network.qos_data.parameters,
2162 &def_qos_parameters, size);
2164 if ((network->qos_data.active == 1) && (active_network == 1)) {
2165 queue_work(priv->priv_wq, &priv->qos_activate);
2166 RT_TRACE(COMP_QOS, "QoS was disabled call qos_activate \n");
2168 network->qos_data.active = 0;
2169 network->qos_data.supported = 0;
2172 return 0;
2175 /* handle and manage frame from beacon and probe response */
2176 static int rtl8192_handle_beacon(struct net_device *dev,
2177 struct ieee80211_beacon *beacon,
2178 struct ieee80211_network *network)
2180 struct r8192_priv *priv = ieee80211_priv(dev);
2182 rtl8192_qos_handle_probe_response(priv, 1, network);
2183 queue_delayed_work(priv->priv_wq, &priv->update_beacon_wq, 0);
2184 return 0;
2189 * handling the beaconing responses. if we get different QoS setting
2190 * off the network from the associated setting, adjust the QoS
2191 * setting
2193 static int rtl8192_qos_association_resp(struct r8192_priv *priv,
2194 struct ieee80211_network *network)
2196 int ret = 0;
2197 unsigned long flags;
2198 u32 size = sizeof(struct ieee80211_qos_parameters);
2199 int set_qos_param = 0;
2201 if ((priv == NULL) || (network == NULL))
2202 return ret;
2204 if (priv->ieee80211->state != IEEE80211_LINKED)
2205 return ret;
2207 if ((priv->ieee80211->iw_mode != IW_MODE_INFRA))
2208 return ret;
2210 spin_lock_irqsave(&priv->ieee80211->lock, flags);
2211 if (network->flags & NETWORK_HAS_QOS_PARAMETERS) {
2212 memcpy(&priv->ieee80211->current_network.qos_data.parameters,
2213 &network->qos_data.parameters,
2214 sizeof(struct ieee80211_qos_parameters));
2215 priv->ieee80211->current_network.qos_data.active = 1;
2216 set_qos_param = 1;
2217 /* update qos parameter for current network */
2218 priv->ieee80211->current_network.qos_data.old_param_count =
2219 priv->ieee80211->current_network.qos_data.param_count;
2220 priv->ieee80211->current_network.qos_data.param_count =
2221 network->qos_data.param_count;
2222 } else {
2223 memcpy(&priv->ieee80211->current_network.qos_data.parameters,
2224 &def_qos_parameters, size);
2225 priv->ieee80211->current_network.qos_data.active = 0;
2226 priv->ieee80211->current_network.qos_data.supported = 0;
2227 set_qos_param = 1;
2230 spin_unlock_irqrestore(&priv->ieee80211->lock, flags);
2232 RT_TRACE(COMP_QOS, "%s: network->flags = %d,%d\n", __func__, network->flags, priv->ieee80211->current_network.qos_data.active);
2233 if (set_qos_param == 1)
2234 queue_work(priv->priv_wq, &priv->qos_activate);
2237 return ret;
2241 static int rtl8192_handle_assoc_response(struct net_device *dev,
2242 struct ieee80211_assoc_response_frame *resp,
2243 struct ieee80211_network *network)
2245 struct r8192_priv *priv = ieee80211_priv(dev);
2246 rtl8192_qos_association_resp(priv, network);
2247 return 0;
2251 void rtl8192_update_ratr_table(struct net_device *dev)
2253 struct r8192_priv *priv = ieee80211_priv(dev);
2254 struct ieee80211_device *ieee = priv->ieee80211;
2255 u8 *pMcsRate = ieee->dot11HTOperationalRateSet;
2256 u32 ratr_value = 0;
2257 u8 rate_index = 0;
2258 rtl8192_config_rate(dev, (u16 *)(&ratr_value));
2259 ratr_value |= (*(u16 *)(pMcsRate)) << 12;
2260 switch (ieee->mode) {
2261 case IEEE_A:
2262 ratr_value &= 0x00000FF0;
2263 break;
2264 case IEEE_B:
2265 ratr_value &= 0x0000000F;
2266 break;
2267 case IEEE_G:
2268 ratr_value &= 0x00000FF7;
2269 break;
2270 case IEEE_N_24G:
2271 case IEEE_N_5G:
2272 if (ieee->pHTInfo->PeerMimoPs == 0) {//MIMO_PS_STATIC
2273 ratr_value &= 0x0007F007;
2274 } else {
2275 if (priv->rf_type == RF_1T2R)
2276 ratr_value &= 0x000FF007;
2277 else
2278 ratr_value &= 0x0F81F007;
2280 break;
2281 default:
2282 break;
2284 ratr_value &= 0x0FFFFFFF;
2285 if (ieee->pHTInfo->bCurTxBW40MHz && ieee->pHTInfo->bCurShortGI40MHz)
2286 ratr_value |= 0x80000000;
2287 else if (!ieee->pHTInfo->bCurTxBW40MHz && ieee->pHTInfo->bCurShortGI20MHz)
2288 ratr_value |= 0x80000000;
2289 write_nic_dword(dev, RATR0+rate_index*4, ratr_value);
2290 write_nic_byte(dev, UFWP, 1);
2293 static u8 ccmp_ie[4] = {0x00, 0x50, 0xf2, 0x04};
2294 static u8 ccmp_rsn_ie[4] = {0x00, 0x0f, 0xac, 0x04};
2295 bool GetNmodeSupportBySecCfg8192(struct net_device *dev)
2297 struct r8192_priv *priv = ieee80211_priv(dev);
2298 struct ieee80211_device *ieee = priv->ieee80211;
2299 struct ieee80211_network *network = &ieee->current_network;
2300 int wpa_ie_len = ieee->wpa_ie_len;
2301 struct ieee80211_crypt_data *crypt;
2302 int encrypt;
2304 crypt = ieee->crypt[ieee->tx_keyidx];
2305 //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
2306 encrypt = (network->capability & WLAN_CAPABILITY_PRIVACY) || (ieee->host_encrypt && crypt && crypt->ops && (0 == strcmp(crypt->ops->name, "WEP")));
2308 /* simply judge */
2309 if (encrypt && (wpa_ie_len == 0)) {
2310 /* wep encryption, no N mode setting */
2311 return false;
2312 } else if ((wpa_ie_len != 0)) {
2313 /* parse pairwise key type */
2314 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))))
2315 return true;
2316 else
2317 return false;
2318 } else {
2319 return true;
2322 return true;
2325 bool GetHalfNmodeSupportByAPs819xUsb(struct net_device *dev)
2327 bool Reval;
2328 struct r8192_priv *priv = ieee80211_priv(dev);
2329 struct ieee80211_device *ieee = priv->ieee80211;
2331 if (ieee->bHalfWirelessN24GMode == true)
2332 Reval = true;
2333 else
2334 Reval = false;
2336 return Reval;
2339 void rtl8192_refresh_supportrate(struct r8192_priv *priv)
2341 struct ieee80211_device *ieee = priv->ieee80211;
2342 //we do not consider set support rate for ABG mode, only HT MCS rate is set here.
2343 if (ieee->mode == WIRELESS_MODE_N_24G || ieee->mode == WIRELESS_MODE_N_5G)
2344 memcpy(ieee->Regdot11HTOperationalRateSet, ieee->RegHTSuppRateSet, 16);
2345 else
2346 memset(ieee->Regdot11HTOperationalRateSet, 0, 16);
2347 return;
2350 u8 rtl8192_getSupportedWireleeMode(struct net_device *dev)
2352 struct r8192_priv *priv = ieee80211_priv(dev);
2353 u8 ret = 0;
2354 switch (priv->rf_chip) {
2355 case RF_8225:
2356 case RF_8256:
2357 case RF_PSEUDO_11N:
2358 ret = (WIRELESS_MODE_N_24G|WIRELESS_MODE_G|WIRELESS_MODE_B);
2359 break;
2360 case RF_8258:
2361 ret = (WIRELESS_MODE_A|WIRELESS_MODE_N_5G);
2362 break;
2363 default:
2364 ret = WIRELESS_MODE_B;
2365 break;
2367 return ret;
2369 void rtl8192_SetWirelessMode(struct net_device *dev, u8 wireless_mode)
2371 struct r8192_priv *priv = ieee80211_priv(dev);
2372 u8 bSupportMode = rtl8192_getSupportedWireleeMode(dev);
2374 if ((wireless_mode == WIRELESS_MODE_AUTO) || ((wireless_mode&bSupportMode) == 0)) {
2375 if (bSupportMode & WIRELESS_MODE_N_24G) {
2376 wireless_mode = WIRELESS_MODE_N_24G;
2377 } else if (bSupportMode & WIRELESS_MODE_N_5G) {
2378 wireless_mode = WIRELESS_MODE_N_5G;
2379 } else if ((bSupportMode & WIRELESS_MODE_A)) {
2380 wireless_mode = WIRELESS_MODE_A;
2381 } else if ((bSupportMode & WIRELESS_MODE_G)) {
2382 wireless_mode = WIRELESS_MODE_G;
2383 } else if ((bSupportMode & WIRELESS_MODE_B)) {
2384 wireless_mode = WIRELESS_MODE_B;
2385 } else {
2386 RT_TRACE(COMP_ERR, "%s(), No valid wireless mode supported, SupportedWirelessMode(%x)!!!\n", __func__, bSupportMode);
2387 wireless_mode = WIRELESS_MODE_B;
2390 #ifdef TO_DO_LIST //// TODO: this function doesn't work well at this time, we should wait for FPGA
2391 ActUpdateChannelAccessSetting(pAdapter, pHalData->CurrentWirelessMode, &pAdapter->MgntInfo.Info8185.ChannelAccessSetting);
2392 #endif
2393 priv->ieee80211->mode = wireless_mode;
2395 if ((wireless_mode == WIRELESS_MODE_N_24G) || (wireless_mode == WIRELESS_MODE_N_5G))
2396 priv->ieee80211->pHTInfo->bEnableHT = 1;
2397 else
2398 priv->ieee80211->pHTInfo->bEnableHT = 0;
2399 RT_TRACE(COMP_INIT, "Current Wireless Mode is %x\n", wireless_mode);
2400 rtl8192_refresh_supportrate(priv);
2403 //init priv variables here. only non_zero value should be initialized here.
2404 static void rtl8192_init_priv_variable(struct net_device *dev)
2406 struct r8192_priv *priv = ieee80211_priv(dev);
2407 u8 i;
2408 priv->card_8192 = NIC_8192U;
2409 priv->chan = 1; //set to channel 1
2410 priv->ieee80211->mode = WIRELESS_MODE_AUTO; //SET AUTO
2411 priv->ieee80211->iw_mode = IW_MODE_INFRA;
2412 priv->ieee80211->ieee_up = 0;
2413 priv->retry_rts = DEFAULT_RETRY_RTS;
2414 priv->retry_data = DEFAULT_RETRY_DATA;
2415 priv->ieee80211->rts = DEFAULT_RTS_THRESHOLD;
2416 priv->ieee80211->rate = 110; //11 mbps
2417 priv->ieee80211->short_slot = 1;
2418 priv->promisc = (dev->flags & IFF_PROMISC) ? 1 : 0;
2419 priv->CckPwEnl = 6;
2420 //for silent reset
2421 priv->IrpPendingCount = 1;
2422 priv->ResetProgress = RESET_TYPE_NORESET;
2423 priv->bForcedSilentReset = 0;
2424 priv->bDisableNormalResetCheck = false;
2425 priv->force_reset = false;
2427 priv->ieee80211->FwRWRF = 0; //we don't use FW read/write RF until stable firmware is available.
2428 priv->ieee80211->current_network.beacon_interval = DEFAULT_BEACONINTERVAL;
2429 priv->ieee80211->iw_mode = IW_MODE_INFRA;
2430 priv->ieee80211->softmac_features = IEEE_SOFTMAC_SCAN |
2431 IEEE_SOFTMAC_ASSOCIATE | IEEE_SOFTMAC_PROBERQ |
2432 IEEE_SOFTMAC_PROBERS | IEEE_SOFTMAC_TX_QUEUE |
2433 IEEE_SOFTMAC_BEACONS;//added by amy 080604
2435 priv->ieee80211->active_scan = 1;
2436 priv->ieee80211->modulation = IEEE80211_CCK_MODULATION | IEEE80211_OFDM_MODULATION;
2437 priv->ieee80211->host_encrypt = 1;
2438 priv->ieee80211->host_decrypt = 1;
2439 priv->ieee80211->start_send_beacons = NULL; //-by amy 080604
2440 priv->ieee80211->stop_send_beacons = NULL; //-by amy 080604
2441 priv->ieee80211->softmac_hard_start_xmit = rtl8192_hard_start_xmit;
2442 priv->ieee80211->set_chan = rtl8192_set_chan;
2443 priv->ieee80211->link_change = rtl8192_link_change;
2444 priv->ieee80211->softmac_data_hard_start_xmit = rtl8192_hard_data_xmit;
2445 priv->ieee80211->data_hard_stop = rtl8192_data_hard_stop;
2446 priv->ieee80211->data_hard_resume = rtl8192_data_hard_resume;
2447 priv->ieee80211->init_wmmparam_flag = 0;
2448 priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD;
2449 priv->ieee80211->check_nic_enough_desc = check_nic_enough_desc;
2450 priv->ieee80211->tx_headroom = TX_PACKET_SHIFT_BYTES;
2451 priv->ieee80211->qos_support = 1;
2453 //added by WB
2454 priv->ieee80211->SetBWModeHandler = rtl8192_SetBWMode;
2455 priv->ieee80211->handle_assoc_response = rtl8192_handle_assoc_response;
2456 priv->ieee80211->handle_beacon = rtl8192_handle_beacon;
2457 //added by david
2458 priv->ieee80211->GetNmodeSupportBySecCfg = GetNmodeSupportBySecCfg8192;
2459 priv->ieee80211->GetHalfNmodeSupportByAPsHandler = GetHalfNmodeSupportByAPs819xUsb;
2460 priv->ieee80211->SetWirelessMode = rtl8192_SetWirelessMode;
2461 //added by amy
2462 priv->ieee80211->InitialGainHandler = InitialGain819xUsb;
2463 priv->card_type = USB;
2464 #ifdef TO_DO_LIST
2465 if (Adapter->bInHctTest) {
2466 pHalData->ShortRetryLimit = 7;
2467 pHalData->LongRetryLimit = 7;
2469 #endif
2470 priv->ShortRetryLimit = 0x30;
2471 priv->LongRetryLimit = 0x30;
2472 priv->EarlyRxThreshold = 7;
2473 priv->enable_gpio0 = 0;
2474 priv->TransmitConfig =
2475 (TCR_MXDMA_2048<<TCR_MXDMA_OFFSET)| // Max DMA Burst Size per Tx DMA Burst, 7: reserved.
2476 (priv->ShortRetryLimit<<TCR_SRL_OFFSET)| // Short retry limit
2477 (priv->LongRetryLimit<<TCR_LRL_OFFSET) | // Long retry limit
2478 (false ? TCR_SAT : 0); // FALSE: HW provides PLCP length and LENGEXT, TRUE: SW provides them
2479 #ifdef TO_DO_LIST
2480 if (Adapter->bInHctTest)
2481 pHalData->ReceiveConfig = pHalData->CSMethod |
2482 RCR_AMF | RCR_ADF | //accept management/data
2483 //guangan200710
2484 RCR_ACF | //accept control frame for SW AP needs PS-poll, 2005.07.07, by rcnjko.
2485 RCR_AB | RCR_AM | RCR_APM | //accept BC/MC/UC
2486 RCR_AICV | RCR_ACRC32 | //accept ICV/CRC error packet
2487 ((u32)7<<RCR_MXDMA_OFFSET) | // Max DMA Burst Size per Rx DMA Burst, 7: unlimited.
2488 (pHalData->EarlyRxThreshold<<RCR_FIFO_OFFSET) | // Rx FIFO Threshold, 7: No Rx threshold.
2489 (pHalData->EarlyRxThreshold == 7 ? RCR_OnlyErlPkt : 0);
2490 else
2492 #endif
2493 priv->ReceiveConfig =
2494 RCR_AMF | RCR_ADF | //accept management/data
2495 RCR_ACF | //accept control frame for SW AP needs PS-poll, 2005.07.07, by rcnjko.
2496 RCR_AB | RCR_AM | RCR_APM | //accept BC/MC/UC
2497 ((u32)7<<RCR_MXDMA_OFFSET)| // Max DMA Burst Size per Rx DMA Burst, 7: unlimited.
2498 (priv->EarlyRxThreshold<<RX_FIFO_THRESHOLD_SHIFT) | // Rx FIFO Threshold, 7: No Rx threshold.
2499 (priv->EarlyRxThreshold == 7 ? RCR_ONLYERLPKT : 0);
2501 priv->AcmControl = 0;
2502 priv->pFirmware = kzalloc(sizeof(rt_firmware), GFP_KERNEL);
2504 /* rx related queue */
2505 skb_queue_head_init(&priv->rx_queue);
2506 skb_queue_head_init(&priv->skb_queue);
2508 /* Tx related queue */
2509 for (i = 0; i < MAX_QUEUE_SIZE; i++)
2510 skb_queue_head_init(&priv->ieee80211->skb_waitQ[i]);
2511 for (i = 0; i < MAX_QUEUE_SIZE; i++)
2512 skb_queue_head_init(&priv->ieee80211->skb_aggQ[i]);
2513 for (i = 0; i < MAX_QUEUE_SIZE; i++)
2514 skb_queue_head_init(&priv->ieee80211->skb_drv_aggQ[i]);
2515 priv->rf_set_chan = rtl8192_phy_SwChnl;
2518 //init lock here
2519 static void rtl8192_init_priv_lock(struct r8192_priv *priv)
2521 spin_lock_init(&priv->tx_lock);
2522 spin_lock_init(&priv->irq_lock);//added by thomas
2523 sema_init(&priv->wx_sem, 1);
2524 sema_init(&priv->rf_sem, 1);
2525 mutex_init(&priv->mutex);
2528 extern void rtl819x_watchdog_wqcallback(struct work_struct *work);
2530 void rtl8192_irq_rx_tasklet(struct r8192_priv *priv);
2531 //init tasklet and wait_queue here. only 2.6 above kernel is considered
2532 #define DRV_NAME "wlan0"
2533 static void rtl8192_init_priv_task(struct net_device *dev)
2535 struct r8192_priv *priv = ieee80211_priv(dev);
2537 priv->priv_wq = create_workqueue(DRV_NAME);
2539 INIT_WORK(&priv->reset_wq, rtl8192_restart);
2541 INIT_DELAYED_WORK(&priv->watch_dog_wq, rtl819x_watchdog_wqcallback);
2542 INIT_DELAYED_WORK(&priv->txpower_tracking_wq, dm_txpower_trackingcallback);
2543 INIT_DELAYED_WORK(&priv->rfpath_check_wq, dm_rf_pathcheck_workitemcallback);
2544 INIT_DELAYED_WORK(&priv->update_beacon_wq, rtl8192_update_beacon);
2545 INIT_DELAYED_WORK(&priv->initialgain_operate_wq, InitialGainOperateWorkItemCallBack);
2546 INIT_WORK(&priv->qos_activate, rtl8192_qos_activate);
2548 tasklet_init(&priv->irq_rx_tasklet,
2549 (void(*)(unsigned long))rtl8192_irq_rx_tasklet,
2550 (unsigned long)priv);
2553 static void rtl8192_get_eeprom_size(struct net_device *dev)
2555 u16 curCR = 0;
2556 struct r8192_priv *priv = ieee80211_priv(dev);
2557 RT_TRACE(COMP_EPROM, "===========>%s()\n", __func__);
2558 read_nic_word_E(dev, EPROM_CMD, &curCR);
2559 RT_TRACE(COMP_EPROM, "read from Reg EPROM_CMD(%x):%x\n", EPROM_CMD, curCR);
2560 //whether need I consider BIT5?
2561 priv->epromtype = (curCR & Cmd9346CR_9356SEL) ? EPROM_93c56 : EPROM_93c46;
2562 RT_TRACE(COMP_EPROM, "<===========%s(), epromtype:%d\n", __func__, priv->epromtype);
2565 //used to swap endian. as ntohl & htonl are not necessary to swap endian, so use this instead.
2566 static inline u16 endian_swap(u16 *data)
2568 u16 tmp = *data;
2569 *data = (tmp >> 8) | (tmp << 8);
2570 return *data;
2572 static void rtl8192_read_eeprom_info(struct net_device *dev)
2574 u16 wEPROM_ID = 0;
2575 u8 bMac_Tmp_Addr[6] = {0x00, 0xe0, 0x4c, 0x00, 0x00, 0x02};
2576 u8 bLoad_From_EEPOM = false;
2577 struct r8192_priv *priv = ieee80211_priv(dev);
2578 u16 tmpValue = 0;
2579 int i;
2580 RT_TRACE(COMP_EPROM, "===========>%s()\n", __func__);
2581 wEPROM_ID = eprom_read(dev, 0); //first read EEPROM ID out;
2582 RT_TRACE(COMP_EPROM, "EEPROM ID is 0x%x\n", wEPROM_ID);
2584 if (wEPROM_ID != RTL8190_EEPROM_ID) {
2585 RT_TRACE(COMP_ERR, "EEPROM ID is invalid(is 0x%x(should be 0x%x)\n", wEPROM_ID, RTL8190_EEPROM_ID);
2586 } else {
2587 bLoad_From_EEPOM = true;
2590 if (bLoad_From_EEPOM) {
2591 tmpValue = eprom_read(dev, (EEPROM_VID>>1));
2592 priv->eeprom_vid = endian_swap(&tmpValue);
2593 priv->eeprom_pid = eprom_read(dev, (EEPROM_PID>>1));
2594 tmpValue = eprom_read(dev, (EEPROM_ChannelPlan>>1));
2595 priv->eeprom_ChannelPlan = ((tmpValue&0xff00)>>8);
2596 priv->btxpowerdata_readfromEEPORM = true;
2597 priv->eeprom_CustomerID = eprom_read(dev, (EEPROM_Customer_ID>>1)) >>8;
2598 } else {
2599 priv->eeprom_vid = 0;
2600 priv->eeprom_pid = 0;
2601 priv->card_8192_version = VERSION_819xU_B;
2602 priv->eeprom_ChannelPlan = 0;
2603 priv->eeprom_CustomerID = 0;
2605 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);
2606 //set channelplan from eeprom
2607 priv->ChannelPlan = priv->eeprom_ChannelPlan;
2608 if (bLoad_From_EEPOM) {
2609 int i;
2610 for (i = 0; i < 6; i += 2) {
2611 u16 tmp = 0;
2612 tmp = eprom_read(dev, (u16)((EEPROM_NODE_ADDRESS_BYTE_0 + i)>>1));
2613 *(u16 *)(&dev->dev_addr[i]) = tmp;
2615 } else {
2616 memcpy(dev->dev_addr, bMac_Tmp_Addr, 6);
2617 //should I set IDR0 here?
2619 RT_TRACE(COMP_EPROM, "MAC addr:%pM\n", dev->dev_addr);
2620 priv->rf_type = RTL819X_DEFAULT_RF_TYPE; //default 1T2R
2621 priv->rf_chip = RF_8256;
2623 if (priv->card_8192_version == (u8)VERSION_819xU_A) {
2624 //read Tx power gain offset of legacy OFDM to HT rate
2625 if (bLoad_From_EEPOM)
2626 priv->EEPROMTxPowerDiff = (eprom_read(dev, (EEPROM_TxPowerDiff>>1))&0xff00) >> 8;
2627 else
2628 priv->EEPROMTxPowerDiff = EEPROM_Default_TxPower;
2629 RT_TRACE(COMP_EPROM, "TxPowerDiff:%d\n", priv->EEPROMTxPowerDiff);
2630 //read ThermalMeter from EEPROM
2631 if (bLoad_From_EEPOM)
2632 priv->EEPROMThermalMeter = (u8)(eprom_read(dev, (EEPROM_ThermalMeter>>1))&0x00ff);
2633 else
2634 priv->EEPROMThermalMeter = EEPROM_Default_ThermalMeter;
2635 RT_TRACE(COMP_EPROM, "ThermalMeter:%d\n", priv->EEPROMThermalMeter);
2636 //vivi, for tx power track
2637 priv->TSSI_13dBm = priv->EEPROMThermalMeter *100;
2638 //read antenna tx power offset of B/C/D to A from EEPROM
2639 if (bLoad_From_EEPOM)
2640 priv->EEPROMPwDiff = (eprom_read(dev, (EEPROM_PwDiff>>1))&0x0f00)>>8;
2641 else
2642 priv->EEPROMPwDiff = EEPROM_Default_PwDiff;
2643 RT_TRACE(COMP_EPROM, "TxPwDiff:%d\n", priv->EEPROMPwDiff);
2644 // Read CrystalCap from EEPROM
2645 if (bLoad_From_EEPOM)
2646 priv->EEPROMCrystalCap = (eprom_read(dev, (EEPROM_CrystalCap>>1))&0x0f);
2647 else
2648 priv->EEPROMCrystalCap = EEPROM_Default_CrystalCap;
2649 RT_TRACE(COMP_EPROM, "CrystalCap = %d\n", priv->EEPROMCrystalCap);
2650 //get per-channel Tx power level
2651 if (bLoad_From_EEPOM)
2652 priv->EEPROM_Def_Ver = (eprom_read(dev, (EEPROM_TxPwIndex_Ver>>1))&0xff00)>>8;
2653 else
2654 priv->EEPROM_Def_Ver = 1;
2655 RT_TRACE(COMP_EPROM, "EEPROM_DEF_VER:%d\n", priv->EEPROM_Def_Ver);
2656 if (priv->EEPROM_Def_Ver == 0) { //old eeprom definition
2657 int i;
2658 if (bLoad_From_EEPOM)
2659 priv->EEPROMTxPowerLevelCCK = (eprom_read(dev, (EEPROM_TxPwIndex_CCK>>1))&0xff) >> 8;
2660 else
2661 priv->EEPROMTxPowerLevelCCK = 0x10;
2662 RT_TRACE(COMP_EPROM, "CCK Tx Power Levl: 0x%02x\n", priv->EEPROMTxPowerLevelCCK);
2663 for (i = 0; i < 3; i++) {
2664 if (bLoad_From_EEPOM) {
2665 tmpValue = eprom_read(dev, (EEPROM_TxPwIndex_OFDM_24G+i)>>1);
2666 if (((EEPROM_TxPwIndex_OFDM_24G+i) % 2) == 0)
2667 tmpValue = tmpValue & 0x00ff;
2668 else
2669 tmpValue = (tmpValue & 0xff00) >> 8;
2670 } else {
2671 tmpValue = 0x10;
2673 priv->EEPROMTxPowerLevelOFDM24G[i] = (u8) tmpValue;
2674 RT_TRACE(COMP_EPROM, "OFDM 2.4G Tx Power Level, Index %d = 0x%02x\n", i, priv->EEPROMTxPowerLevelCCK);
2676 } else if (priv->EEPROM_Def_Ver == 1) {
2677 if (bLoad_From_EEPOM) {
2678 tmpValue = eprom_read(dev, (EEPROM_TxPwIndex_CCK_V1>>1));
2679 tmpValue = (tmpValue & 0xff00) >> 8;
2680 } else {
2681 tmpValue = 0x10;
2683 priv->EEPROMTxPowerLevelCCK_V1[0] = (u8)tmpValue;
2685 if (bLoad_From_EEPOM)
2686 tmpValue = eprom_read(dev, (EEPROM_TxPwIndex_CCK_V1 + 2)>>1);
2687 else
2688 tmpValue = 0x1010;
2689 *((u16 *)(&priv->EEPROMTxPowerLevelCCK_V1[1])) = tmpValue;
2690 if (bLoad_From_EEPOM)
2691 tmpValue = eprom_read(dev, (EEPROM_TxPwIndex_OFDM_24G_V1>>1));
2692 else
2693 tmpValue = 0x1010;
2694 *((u16 *)(&priv->EEPROMTxPowerLevelOFDM24G[0])) = tmpValue;
2695 if (bLoad_From_EEPOM)
2696 tmpValue = eprom_read(dev, (EEPROM_TxPwIndex_OFDM_24G_V1+2)>>1);
2697 else
2698 tmpValue = 0x10;
2699 priv->EEPROMTxPowerLevelOFDM24G[2] = (u8)tmpValue;
2700 }//endif EEPROM_Def_Ver == 1
2702 //update HAL variables
2704 for (i = 0; i < 14; i++) {
2705 if (i <= 3)
2706 priv->TxPowerLevelOFDM24G[i] = priv->EEPROMTxPowerLevelOFDM24G[0];
2707 else if (i >= 4 && i <= 9)
2708 priv->TxPowerLevelOFDM24G[i] = priv->EEPROMTxPowerLevelOFDM24G[1];
2709 else
2710 priv->TxPowerLevelOFDM24G[i] = priv->EEPROMTxPowerLevelOFDM24G[2];
2713 for (i = 0; i < 14; i++) {
2714 if (priv->EEPROM_Def_Ver == 0) {
2715 if (i <= 3)
2716 priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelOFDM24G[0] + (priv->EEPROMTxPowerLevelCCK - priv->EEPROMTxPowerLevelOFDM24G[1]);
2717 else if (i >= 4 && i <= 9)
2718 priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelCCK;
2719 else
2720 priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelOFDM24G[2] + (priv->EEPROMTxPowerLevelCCK - priv->EEPROMTxPowerLevelOFDM24G[1]);
2721 } else if (priv->EEPROM_Def_Ver == 1) {
2722 if (i <= 3)
2723 priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelCCK_V1[0];
2724 else if (i >= 4 && i <= 9)
2725 priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelCCK_V1[1];
2726 else
2727 priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelCCK_V1[2];
2730 priv->TxPowerDiff = priv->EEPROMPwDiff;
2731 // Antenna B gain offset to antenna A, bit0~3
2732 priv->AntennaTxPwDiff[0] = (priv->EEPROMTxPowerDiff & 0xf);
2733 // Antenna C gain offset to antenna A, bit4~7
2734 priv->AntennaTxPwDiff[1] = ((priv->EEPROMTxPowerDiff & 0xf0)>>4);
2735 // CrystalCap, bit12~15
2736 priv->CrystalCap = priv->EEPROMCrystalCap;
2737 // ThermalMeter, bit0~3 for RFIC1, bit4~7 for RFIC2
2738 // 92U does not enable TX power tracking.
2739 priv->ThermalMeter[0] = priv->EEPROMThermalMeter;
2740 }//end if VersionID == VERSION_819xU_A
2742 //added by vivi, for dlink led, 20080416
2743 switch (priv->eeprom_CustomerID) {
2744 case EEPROM_CID_RUNTOP:
2745 priv->CustomerID = RT_CID_819x_RUNTOP;
2746 break;
2748 case EEPROM_CID_DLINK:
2749 priv->CustomerID = RT_CID_DLINK;
2750 break;
2752 default:
2753 priv->CustomerID = RT_CID_DEFAULT;
2754 break;
2758 switch (priv->CustomerID) {
2759 case RT_CID_819x_RUNTOP:
2760 priv->LedStrategy = SW_LED_MODE2;
2761 break;
2763 case RT_CID_DLINK:
2764 priv->LedStrategy = SW_LED_MODE4;
2765 break;
2767 default:
2768 priv->LedStrategy = SW_LED_MODE0;
2769 break;
2774 if (priv->rf_type == RF_1T2R) {
2775 RT_TRACE(COMP_EPROM, "\n1T2R config\n");
2776 } else {
2777 RT_TRACE(COMP_EPROM, "\n2T4R config\n");
2780 // 2008/01/16 MH We can only know RF type in the function. So we have to init
2781 // DIG RATR table again.
2782 init_rate_adaptive(dev);
2783 //we need init DIG RATR table here again.
2785 RT_TRACE(COMP_EPROM, "<===========%s()\n", __func__);
2786 return;
2789 short rtl8192_get_channel_map(struct net_device *dev)
2791 struct r8192_priv *priv = ieee80211_priv(dev);
2792 if (priv->ChannelPlan > COUNTRY_CODE_GLOBAL_DOMAIN) {
2793 netdev_err(dev, "rtl8180_init: Error channel plan! Set to default.\n");
2794 priv->ChannelPlan = 0;
2796 RT_TRACE(COMP_INIT, "Channel plan is %d\n", priv->ChannelPlan);
2798 rtl819x_set_channel_map(priv->ChannelPlan, priv);
2799 return 0;
2802 short rtl8192_init(struct net_device *dev)
2805 struct r8192_priv *priv = ieee80211_priv(dev);
2807 memset(&(priv->stats), 0, sizeof(struct Stats));
2808 memset(priv->txqueue_to_outpipemap, 0, 9);
2809 #ifdef PIPE12
2811 int i = 0;
2812 u8 queuetopipe[] = {3, 2, 1, 0, 4, 8, 7, 6, 5};
2813 memcpy(priv->txqueue_to_outpipemap, queuetopipe, 9);
2815 #else
2817 u8 queuetopipe[] = {3, 2, 1, 0, 4, 4, 0, 4, 4};
2818 memcpy(priv->txqueue_to_outpipemap, queuetopipe, 9);
2820 #endif
2821 rtl8192_init_priv_variable(dev);
2822 rtl8192_init_priv_lock(priv);
2823 rtl8192_init_priv_task(dev);
2824 rtl8192_get_eeprom_size(dev);
2825 rtl8192_read_eeprom_info(dev);
2826 rtl8192_get_channel_map(dev);
2827 init_hal_dm(dev);
2828 init_timer(&priv->watch_dog_timer);
2829 priv->watch_dog_timer.data = (unsigned long)dev;
2830 priv->watch_dog_timer.function = watch_dog_timer_callback;
2831 if (rtl8192_usb_initendpoints(dev) != 0) {
2832 DMESG("Endopoints initialization failed");
2833 return -ENOMEM;
2836 #ifdef DEBUG_EPROM
2837 dump_eprom(dev);
2838 #endif
2839 return 0;
2842 /******************************************************************************
2843 *function: This function actually only set RRSR, RATR and BW_OPMODE registers
2844 * not to do all the hw config as its name says
2845 * input: net_device dev
2846 * output: none
2847 * return: none
2848 * notice: This part need to modified according to the rate set we filtered
2849 * ****************************************************************************/
2850 void rtl8192_hwconfig(struct net_device *dev)
2852 u32 regRATR = 0, regRRSR = 0;
2853 u8 regBwOpMode = 0, regTmp = 0;
2854 struct r8192_priv *priv = ieee80211_priv(dev);
2855 u32 ratr_value = 0;
2857 // Set RRSR, RATR, and BW_OPMODE registers
2859 switch (priv->ieee80211->mode) {
2860 case WIRELESS_MODE_B:
2861 regBwOpMode = BW_OPMODE_20MHZ;
2862 regRATR = RATE_ALL_CCK;
2863 regRRSR = RATE_ALL_CCK;
2864 break;
2865 case WIRELESS_MODE_A:
2866 regBwOpMode = BW_OPMODE_5G |BW_OPMODE_20MHZ;
2867 regRATR = RATE_ALL_OFDM_AG;
2868 regRRSR = RATE_ALL_OFDM_AG;
2869 break;
2870 case WIRELESS_MODE_G:
2871 regBwOpMode = BW_OPMODE_20MHZ;
2872 regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
2873 regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
2874 break;
2875 case WIRELESS_MODE_AUTO:
2876 #ifdef TO_DO_LIST
2877 if (Adapter->bInHctTest) {
2878 regBwOpMode = BW_OPMODE_20MHZ;
2879 regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
2880 regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
2882 else
2883 #endif
2885 regBwOpMode = BW_OPMODE_20MHZ;
2886 regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
2887 regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
2889 break;
2890 case WIRELESS_MODE_N_24G:
2891 // It support CCK rate by default.
2892 // CCK rate will be filtered out only when associated AP does not support it.
2893 regBwOpMode = BW_OPMODE_20MHZ;
2894 regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
2895 regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
2896 break;
2897 case WIRELESS_MODE_N_5G:
2898 regBwOpMode = BW_OPMODE_5G;
2899 regRATR = RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
2900 regRRSR = RATE_ALL_OFDM_AG;
2901 break;
2904 write_nic_byte(dev, BW_OPMODE, regBwOpMode);
2905 ratr_value = regRATR;
2906 if (priv->rf_type == RF_1T2R)
2907 ratr_value &= ~(RATE_ALL_OFDM_2SS);
2908 write_nic_dword(dev, RATR0, ratr_value);
2909 write_nic_byte(dev, UFWP, 1);
2910 read_nic_byte(dev, 0x313, &regTmp);
2911 regRRSR = ((regTmp) << 24) | (regRRSR & 0x00ffffff);
2912 write_nic_dword(dev, RRSR, regRRSR);
2915 // Set Retry Limit here
2917 write_nic_word(dev, RETRY_LIMIT,
2918 priv->ShortRetryLimit << RETRY_LIMIT_SHORT_SHIFT |
2919 priv->LongRetryLimit << RETRY_LIMIT_LONG_SHIFT);
2920 // Set Contention Window here
2922 // Set Tx AGC
2924 // Set Tx Antenna including Feedback control
2926 // Set Auto Rate fallback control
2932 //InitializeAdapter and PhyCfg
2933 bool rtl8192_adapter_start(struct net_device *dev)
2935 struct r8192_priv *priv = ieee80211_priv(dev);
2936 u32 dwRegRead = 0;
2937 bool init_status = true;
2938 u8 SECR_value = 0x0;
2939 u8 tmp;
2940 RT_TRACE(COMP_INIT, "====>%s()\n", __func__);
2941 priv->Rf_Mode = RF_OP_By_SW_3wire;
2942 //for ASIC power on sequence
2943 write_nic_byte_E(dev, 0x5f, 0x80);
2944 mdelay(50);
2945 write_nic_byte_E(dev, 0x5f, 0xf0);
2946 write_nic_byte_E(dev, 0x5d, 0x00);
2947 write_nic_byte_E(dev, 0x5e, 0x80);
2948 write_nic_byte(dev, 0x17, 0x37);
2949 mdelay(10);
2950 priv->pFirmware->firmware_status = FW_STATUS_0_INIT;
2951 //config CPUReset Register
2952 //Firmware Reset or not?
2953 read_nic_dword(dev, CPU_GEN, &dwRegRead);
2954 if (priv->pFirmware->firmware_status == FW_STATUS_0_INIT)
2955 dwRegRead |= CPU_GEN_SYSTEM_RESET; //do nothing here?
2956 else if (priv->pFirmware->firmware_status == FW_STATUS_5_READY)
2957 dwRegRead |= CPU_GEN_FIRMWARE_RESET;
2958 else
2959 RT_TRACE(COMP_ERR, "ERROR in %s(): undefined firmware state(%d)\n", __func__, priv->pFirmware->firmware_status);
2961 write_nic_dword(dev, CPU_GEN, dwRegRead);
2962 //config BB.
2963 rtl8192_BBConfig(dev);
2965 //Loopback mode or not
2966 priv->LoopbackMode = RTL819xU_NO_LOOPBACK;
2968 read_nic_dword(dev, CPU_GEN, &dwRegRead);
2969 if (priv->LoopbackMode == RTL819xU_NO_LOOPBACK)
2970 dwRegRead = ((dwRegRead & CPU_GEN_NO_LOOPBACK_MSK) | CPU_GEN_NO_LOOPBACK_SET);
2971 else if (priv->LoopbackMode == RTL819xU_MAC_LOOPBACK)
2972 dwRegRead |= CPU_CCK_LOOPBACK;
2973 else
2974 RT_TRACE(COMP_ERR, "Serious error in %s(): wrong loopback mode setting(%d)\n", __func__, priv->LoopbackMode);
2976 write_nic_dword(dev, CPU_GEN, dwRegRead);
2978 //after reset cpu, we need wait for a seconds to write in register.
2979 udelay(500);
2981 //xiong add for new bitfile:usb suspend reset pin set to 1. //do we need?
2982 read_nic_byte_E(dev, 0x5f, &tmp);
2983 write_nic_byte_E(dev, 0x5f, tmp|0x20);
2985 //Set Hardware
2986 rtl8192_hwconfig(dev);
2988 //turn on Tx/Rx
2989 write_nic_byte(dev, CMDR, CR_RE|CR_TE);
2991 //set IDR0 here
2992 write_nic_dword(dev, MAC0, ((u32 *)dev->dev_addr)[0]);
2993 write_nic_word(dev, MAC4, ((u16 *)(dev->dev_addr + 4))[0]);
2995 //set RCR
2996 write_nic_dword(dev, RCR, priv->ReceiveConfig);
2998 //Initialize Number of Reserved Pages in Firmware Queue
2999 write_nic_dword(dev, RQPN1, NUM_OF_PAGE_IN_FW_QUEUE_BK << RSVD_FW_QUEUE_PAGE_BK_SHIFT |
3000 NUM_OF_PAGE_IN_FW_QUEUE_BE << RSVD_FW_QUEUE_PAGE_BE_SHIFT |
3001 NUM_OF_PAGE_IN_FW_QUEUE_VI << RSVD_FW_QUEUE_PAGE_VI_SHIFT |
3002 NUM_OF_PAGE_IN_FW_QUEUE_VO <<RSVD_FW_QUEUE_PAGE_VO_SHIFT);
3003 write_nic_dword(dev, RQPN2, NUM_OF_PAGE_IN_FW_QUEUE_MGNT << RSVD_FW_QUEUE_PAGE_MGNT_SHIFT |
3004 NUM_OF_PAGE_IN_FW_QUEUE_CMD << RSVD_FW_QUEUE_PAGE_CMD_SHIFT);
3005 write_nic_dword(dev, RQPN3, APPLIED_RESERVED_QUEUE_IN_FW|
3006 NUM_OF_PAGE_IN_FW_QUEUE_BCN<<RSVD_FW_QUEUE_PAGE_BCN_SHIFT);
3007 write_nic_dword(dev, RATR0+4*7, (RATE_ALL_OFDM_AG | RATE_ALL_CCK));
3009 //Set AckTimeout
3010 // TODO: (it value is only for FPGA version). need to be changed!!2006.12.18, by Emily
3011 write_nic_byte(dev, ACK_TIMEOUT, 0x30);
3013 if (priv->ResetProgress == RESET_TYPE_NORESET)
3014 rtl8192_SetWirelessMode(dev, priv->ieee80211->mode);
3015 if (priv->ResetProgress == RESET_TYPE_NORESET) {
3016 CamResetAllEntry(dev);
3017 SECR_value |= SCR_TxEncEnable;
3018 SECR_value |= SCR_RxDecEnable;
3019 SECR_value |= SCR_NoSKMC;
3020 write_nic_byte(dev, SECR, SECR_value);
3023 //Beacon related
3024 write_nic_word(dev, ATIMWND, 2);
3025 write_nic_word(dev, BCN_INTERVAL, 100);
3027 #define DEFAULT_EDCA 0x005e4332
3029 int i;
3030 for (i = 0; i < QOS_QUEUE_NUM; i++)
3031 write_nic_dword(dev, WDCAPARA_ADD[i], DEFAULT_EDCA);
3033 #ifdef USB_RX_AGGREGATION_SUPPORT
3034 //3 For usb rx firmware aggregation control
3035 if (priv->ResetProgress == RESET_TYPE_NORESET) {
3036 u32 ulValue;
3037 PRT_HIGH_THROUGHPUT pHTInfo = priv->ieee80211->pHTInfo;
3038 ulValue = (pHTInfo->UsbRxFwAggrEn<<24) | (pHTInfo->UsbRxFwAggrPageNum<<16) |
3039 (pHTInfo->UsbRxFwAggrPacketNum<<8) | (pHTInfo->UsbRxFwAggrTimeout);
3041 * If usb rx firmware aggregation is enabled,
3042 * when anyone of three threshold conditions above is reached,
3043 * firmware will send aggregated packet to driver.
3045 write_nic_dword(dev, 0x1a8, ulValue);
3046 priv->bCurrentRxAggrEnable = true;
3048 #endif
3050 rtl8192_phy_configmac(dev);
3052 if (priv->card_8192_version == (u8) VERSION_819xU_A) {
3053 rtl8192_phy_getTxPower(dev);
3054 rtl8192_phy_setTxPower(dev, priv->chan);
3057 //Firmware download
3058 init_status = init_firmware(dev);
3059 if (!init_status) {
3060 RT_TRACE(COMP_ERR, "ERR!!! %s(): Firmware download is failed\n", __func__);
3061 return init_status;
3063 RT_TRACE(COMP_INIT, "%s():after firmware download\n", __func__);
3065 #ifdef TO_DO_LIST
3066 if (Adapter->ResetProgress == RESET_TYPE_NORESET) {
3067 if (pMgntInfo->RegRfOff == TRUE) { // User disable RF via registry.
3068 RT_TRACE((COMP_INIT|COMP_RF), DBG_LOUD, ("InitializeAdapter819xUsb(): Turn off RF for RegRfOff ----------\n"));
3069 MgntActSet_RF_State(Adapter, eRfOff, RF_CHANGE_BY_SW);
3070 // Those actions will be discard in MgntActSet_RF_State because of the same state
3071 for (eRFPath = 0; eRFPath < pHalData->NumTotalRFPath; eRFPath++)
3072 PHY_SetRFReg(Adapter, (RF90_RADIO_PATH_E)eRFPath, 0x4, 0xC00, 0x0);
3073 } else if (pMgntInfo->RfOffReason > RF_CHANGE_BY_PS) { // H/W or S/W RF OFF before sleep.
3074 RT_TRACE((COMP_INIT|COMP_RF), DBG_LOUD, ("InitializeAdapter819xUsb(): Turn off RF for RfOffReason(%d) ----------\n", pMgntInfo->RfOffReason));
3075 MgntActSet_RF_State(Adapter, eRfOff, pMgntInfo->RfOffReason);
3076 } else {
3077 pHalData->eRFPowerState = eRfOn;
3078 pMgntInfo->RfOffReason = 0;
3079 RT_TRACE((COMP_INIT|COMP_RF), DBG_LOUD, ("InitializeAdapter819xUsb(): RF is on ----------\n"));
3081 } else {
3082 if (pHalData->eRFPowerState == eRfOff) {
3083 MgntActSet_RF_State(Adapter, eRfOff, pMgntInfo->RfOffReason);
3084 // Those actions will be discard in MgntActSet_RF_State because of the same state
3085 for (eRFPath = 0; eRFPath < pHalData->NumTotalRFPath; eRFPath++)
3086 PHY_SetRFReg(Adapter, (RF90_RADIO_PATH_E)eRFPath, 0x4, 0xC00, 0x0);
3089 #endif
3090 //config RF.
3091 if (priv->ResetProgress == RESET_TYPE_NORESET) {
3092 rtl8192_phy_RFConfig(dev);
3093 RT_TRACE(COMP_INIT, "%s():after phy RF config\n", __func__);
3097 if (priv->ieee80211->FwRWRF)
3098 // We can force firmware to do RF-R/W
3099 priv->Rf_Mode = RF_OP_By_FW;
3100 else
3101 priv->Rf_Mode = RF_OP_By_SW_3wire;
3104 rtl8192_phy_updateInitGain(dev);
3105 /*--set CCK and OFDM Block "ON"--*/
3106 rtl8192_setBBreg(dev, rFPGA0_RFMOD, bCCKEn, 0x1);
3107 rtl8192_setBBreg(dev, rFPGA0_RFMOD, bOFDMEn, 0x1);
3109 if (priv->ResetProgress == RESET_TYPE_NORESET) {
3110 //if D or C cut
3111 u8 tmpvalue;
3112 read_nic_byte(dev, 0x301, &tmpvalue);
3113 if (tmpvalue == 0x03) {
3114 priv->bDcut = TRUE;
3115 RT_TRACE(COMP_POWER_TRACKING, "D-cut\n");
3116 } else {
3117 priv->bDcut = FALSE;
3118 RT_TRACE(COMP_POWER_TRACKING, "C-cut\n");
3120 dm_initialize_txpower_tracking(dev);
3122 if (priv->bDcut == TRUE) {
3123 u32 i, TempCCk;
3124 u32 tmpRegA = rtl8192_QueryBBReg(dev, rOFDM0_XATxIQImbalance, bMaskDWord);
3125 for (i = 0; i < TxBBGainTableLength; i++) {
3126 if (tmpRegA == priv->txbbgain_table[i].txbbgain_value) {
3127 priv->rfa_txpowertrackingindex = (u8)i;
3128 priv->rfa_txpowertrackingindex_real = (u8)i;
3129 priv->rfa_txpowertracking_default = priv->rfa_txpowertrackingindex;
3130 break;
3134 TempCCk = rtl8192_QueryBBReg(dev, rCCK0_TxFilter1, bMaskByte2);
3136 for (i = 0; i < CCKTxBBGainTableLength; i++) {
3138 if (TempCCk == priv->cck_txbbgain_table[i].ccktxbb_valuearray[0]) {
3139 priv->cck_present_attentuation_20Mdefault = (u8) i;
3140 break;
3143 priv->cck_present_attentuation_40Mdefault = 0;
3144 priv->cck_present_attentuation_difference = 0;
3145 priv->cck_present_attentuation = priv->cck_present_attentuation_20Mdefault;
3149 write_nic_byte(dev, 0x87, 0x0);
3152 return init_status;
3155 /* this configures registers for beacon tx and enables it via
3156 * rtl8192_beacon_tx_enable(). rtl8192_beacon_tx_disable() might
3157 * be used to stop beacon transmission
3159 /***************************************************************************
3160 -------------------------------NET STUFF---------------------------
3161 ***************************************************************************/
3163 static struct net_device_stats *rtl8192_stats(struct net_device *dev)
3165 struct r8192_priv *priv = ieee80211_priv(dev);
3167 return &priv->ieee80211->stats;
3170 bool HalTxCheckStuck819xUsb(struct net_device *dev)
3172 struct r8192_priv *priv = ieee80211_priv(dev);
3173 u16 RegTxCounter;
3174 bool bStuck = FALSE;
3175 read_nic_word(dev, 0x128, &RegTxCounter);
3176 RT_TRACE(COMP_RESET, "%s():RegTxCounter is %d,TxCounter is %d\n", __func__, RegTxCounter, priv->TxCounter);
3177 if (priv->TxCounter == RegTxCounter)
3178 bStuck = TRUE;
3180 priv->TxCounter = RegTxCounter;
3182 return bStuck;
3186 * <Assumption: RT_TX_SPINLOCK is acquired.>
3187 * First added: 2006.11.19 by emily
3189 RESET_TYPE TxCheckStuck(struct net_device *dev)
3191 struct r8192_priv *priv = ieee80211_priv(dev);
3192 u8 QueueID;
3193 bool bCheckFwTxCnt = false;
3196 // Decide such threshold according to current power save mode
3199 for (QueueID = 0; QueueID <= BEACON_QUEUE; QueueID++) {
3200 if (QueueID == TXCMD_QUEUE)
3201 continue;
3202 #ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
3203 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))
3204 #else
3205 if ((skb_queue_len(&priv->ieee80211->skb_waitQ[QueueID]) == 0) && (skb_queue_len(&priv->ieee80211->skb_aggQ[QueueID]) == 0))
3206 #endif
3207 continue;
3209 bCheckFwTxCnt = true;
3211 if (bCheckFwTxCnt) {
3212 if (HalTxCheckStuck819xUsb(dev)) {
3213 RT_TRACE(COMP_RESET, "TxCheckStuck(): Fw indicates no Tx condition! \n");
3214 return RESET_TYPE_SILENT;
3217 return RESET_TYPE_NORESET;
3220 bool HalRxCheckStuck819xUsb(struct net_device *dev)
3222 u16 RegRxCounter;
3223 struct r8192_priv *priv = ieee80211_priv(dev);
3224 bool bStuck = FALSE;
3225 static u8 rx_chk_cnt;
3226 read_nic_word(dev, 0x130, &RegRxCounter);
3227 RT_TRACE(COMP_RESET, "%s(): RegRxCounter is %d,RxCounter is %d\n", __func__, RegRxCounter, priv->RxCounter);
3228 // If rssi is small, we should check rx for long time because of bad rx.
3229 // or maybe it will continuous silent reset every 2 seconds.
3230 rx_chk_cnt++;
3231 if (priv->undecorated_smoothed_pwdb >= (RateAdaptiveTH_High+5)) {
3232 rx_chk_cnt = 0; //high rssi, check rx stuck right now.
3233 } else if (priv->undecorated_smoothed_pwdb < (RateAdaptiveTH_High+5) &&
3234 ((priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20 && priv->undecorated_smoothed_pwdb >= RateAdaptiveTH_Low_40M) ||
3235 (priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20 && priv->undecorated_smoothed_pwdb >= RateAdaptiveTH_Low_20M))) {
3236 if (rx_chk_cnt < 2)
3237 return bStuck;
3238 else
3239 rx_chk_cnt = 0;
3240 } else if (((priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20 && priv->undecorated_smoothed_pwdb < RateAdaptiveTH_Low_40M) ||
3241 (priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20 && priv->undecorated_smoothed_pwdb < RateAdaptiveTH_Low_20M)) &&
3242 priv->undecorated_smoothed_pwdb >= VeryLowRSSI) {
3243 if (rx_chk_cnt < 4)
3244 return bStuck;
3245 else
3246 rx_chk_cnt = 0;
3247 } else {
3248 if (rx_chk_cnt < 8)
3249 return bStuck;
3250 else
3251 rx_chk_cnt = 0;
3254 if (priv->RxCounter == RegRxCounter)
3255 bStuck = TRUE;
3257 priv->RxCounter = RegRxCounter;
3259 return bStuck;
3262 RESET_TYPE RxCheckStuck(struct net_device *dev)
3264 struct r8192_priv *priv = ieee80211_priv(dev);
3265 bool bRxCheck = FALSE;
3267 if (priv->IrpPendingCount > 1)
3268 bRxCheck = TRUE;
3270 if (bRxCheck) {
3271 if (HalRxCheckStuck819xUsb(dev)) {
3272 RT_TRACE(COMP_RESET, "RxStuck Condition\n");
3273 return RESET_TYPE_SILENT;
3276 return RESET_TYPE_NORESET;
3281 * This function is called by Checkforhang to check whether we should ask OS to reset driver
3283 * \param pAdapter The adapter context for this miniport
3285 * Note:NIC with USB interface sholud not call this function because we cannot scan descriptor
3286 * to judge whether there is tx stuck.
3287 * Note: This function may be required to be rewrite for Vista OS.
3288 * <<<Assumption: Tx spinlock has been acquired >>>
3290 * 8185 and 8185b does not implement this function. This is added by Emily at 2006.11.24
3292 RESET_TYPE rtl819x_ifcheck_resetornot(struct net_device *dev)
3294 struct r8192_priv *priv = ieee80211_priv(dev);
3295 RESET_TYPE TxResetType = RESET_TYPE_NORESET;
3296 RESET_TYPE RxResetType = RESET_TYPE_NORESET;
3297 RT_RF_POWER_STATE rfState;
3299 rfState = priv->ieee80211->eRFPowerState;
3301 TxResetType = TxCheckStuck(dev);
3302 if (rfState != eRfOff ||
3303 (priv->ieee80211->iw_mode != IW_MODE_ADHOC)) {
3304 // If driver is in the status of firmware download failure , driver skips RF initialization and RF is
3305 // in turned off state. Driver should check whether Rx stuck and do silent reset. And
3306 // if driver is in firmware download failure status, driver should initialize RF in the following
3307 // silent reset procedure Emily, 2008.01.21
3309 // Driver should not check RX stuck in IBSS mode because it is required to
3310 // set Check BSSID in order to send beacon, however, if check BSSID is
3311 // set, STA cannot hear any packet at all. Emily, 2008.04.12
3312 RxResetType = RxCheckStuck(dev);
3314 if (TxResetType == RESET_TYPE_NORMAL || RxResetType == RESET_TYPE_NORMAL) {
3315 return RESET_TYPE_NORMAL;
3316 } else if (TxResetType == RESET_TYPE_SILENT || RxResetType == RESET_TYPE_SILENT) {
3317 RT_TRACE(COMP_RESET, "%s():silent reset\n", __func__);
3318 return RESET_TYPE_SILENT;
3319 } else {
3320 return RESET_TYPE_NORESET;
3325 void rtl8192_cancel_deferred_work(struct r8192_priv *priv);
3326 int _rtl8192_up(struct net_device *dev);
3327 int rtl8192_close(struct net_device *dev);
3331 void CamRestoreAllEntry(struct net_device *dev)
3333 u8 EntryId = 0;
3334 struct r8192_priv *priv = ieee80211_priv(dev);
3335 u8 *MacAddr = priv->ieee80211->current_network.bssid;
3337 static u8 CAM_CONST_ADDR[4][6] = {
3338 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
3339 {0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
3340 {0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
3341 {0x00, 0x00, 0x00, 0x00, 0x00, 0x03} };
3342 static u8 CAM_CONST_BROAD[] = {
3343 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
3345 RT_TRACE(COMP_SEC, "CamRestoreAllEntry: \n");
3348 if ((priv->ieee80211->pairwise_key_type == KEY_TYPE_WEP40) ||
3349 (priv->ieee80211->pairwise_key_type == KEY_TYPE_WEP104)) {
3351 for (EntryId = 0; EntryId < 4; EntryId++) {
3352 MacAddr = CAM_CONST_ADDR[EntryId];
3353 setKey(dev, EntryId, EntryId,
3354 priv->ieee80211->pairwise_key_type,
3355 MacAddr, 0, NULL);
3358 } else if (priv->ieee80211->pairwise_key_type == KEY_TYPE_TKIP) {
3360 if (priv->ieee80211->iw_mode == IW_MODE_ADHOC)
3361 setKey(dev, 4, 0, priv->ieee80211->pairwise_key_type,
3362 (u8 *)dev->dev_addr, 0, NULL);
3363 else
3364 setKey(dev, 4, 0, priv->ieee80211->pairwise_key_type,
3365 MacAddr, 0, NULL);
3366 } else if (priv->ieee80211->pairwise_key_type == KEY_TYPE_CCMP) {
3368 if (priv->ieee80211->iw_mode == IW_MODE_ADHOC)
3369 setKey(dev, 4, 0, priv->ieee80211->pairwise_key_type,
3370 (u8 *)dev->dev_addr, 0, NULL);
3371 else
3372 setKey(dev, 4, 0, priv->ieee80211->pairwise_key_type,
3373 MacAddr, 0, NULL);
3378 if (priv->ieee80211->group_key_type == KEY_TYPE_TKIP) {
3379 MacAddr = CAM_CONST_BROAD;
3380 for (EntryId = 1; EntryId < 4; EntryId++) {
3381 setKey(dev, EntryId, EntryId,
3382 priv->ieee80211->group_key_type,
3383 MacAddr, 0, NULL);
3385 if (priv->ieee80211->iw_mode == IW_MODE_ADHOC)
3386 setKey(dev, 0, 0, priv->ieee80211->group_key_type,
3387 CAM_CONST_ADDR[0], 0, NULL);
3388 } else if (priv->ieee80211->group_key_type == KEY_TYPE_CCMP) {
3389 MacAddr = CAM_CONST_BROAD;
3390 for (EntryId = 1; EntryId < 4; EntryId++) {
3391 setKey(dev, EntryId, EntryId,
3392 priv->ieee80211->group_key_type,
3393 MacAddr, 0, NULL);
3396 if (priv->ieee80211->iw_mode == IW_MODE_ADHOC)
3397 setKey(dev, 0, 0, priv->ieee80211->group_key_type,
3398 CAM_CONST_ADDR[0], 0, NULL);
3401 //////////////////////////////////////////////////////////////
3402 // This function is used to fix Tx/Rx stop bug temporarily.
3403 // This function will do "system reset" to NIC when Tx or Rx is stuck.
3404 // The method checking Tx/Rx stuck of this function is supported by FW,
3405 // which reports Tx and Rx counter to register 0x128 and 0x130.
3406 //////////////////////////////////////////////////////////////
3407 void rtl819x_ifsilentreset(struct net_device *dev)
3409 struct r8192_priv *priv = ieee80211_priv(dev);
3410 u8 reset_times = 0;
3411 int reset_status = 0;
3412 struct ieee80211_device *ieee = priv->ieee80211;
3415 // 2007.07.20. If we need to check CCK stop, please uncomment this line.
3416 //bStuck = Adapter->HalFunc.CheckHWStopHandler(Adapter);
3418 if (priv->ResetProgress == RESET_TYPE_NORESET) {
3419 RESET_START:
3421 RT_TRACE(COMP_RESET, "=========>Reset progress!! \n");
3423 // Set the variable for reset.
3424 priv->ResetProgress = RESET_TYPE_SILENT;
3425 down(&priv->wx_sem);
3426 if (priv->up == 0) {
3427 RT_TRACE(COMP_ERR, "%s():the driver is not up! return\n", __func__);
3428 up(&priv->wx_sem);
3429 return;
3431 priv->up = 0;
3432 RT_TRACE(COMP_RESET, "%s():======>start to down the driver\n", __func__);
3434 rtl8192_rtx_disable(dev);
3435 rtl8192_cancel_deferred_work(priv);
3436 deinit_hal_dm(dev);
3437 del_timer_sync(&priv->watch_dog_timer);
3439 ieee->sync_scan_hurryup = 1;
3440 if (ieee->state == IEEE80211_LINKED) {
3441 down(&ieee->wx_sem);
3442 netdev_dbg(dev, "ieee->state is IEEE80211_LINKED\n");
3443 ieee80211_stop_send_beacons(priv->ieee80211);
3444 del_timer_sync(&ieee->associate_timer);
3445 cancel_delayed_work(&ieee->associate_retry_wq);
3446 ieee80211_stop_scan(ieee);
3447 netif_carrier_off(dev);
3448 up(&ieee->wx_sem);
3449 } else {
3450 netdev_dbg(dev, "ieee->state is NOT LINKED\n");
3451 ieee80211_softmac_stop_protocol(priv->ieee80211);
3453 up(&priv->wx_sem);
3454 RT_TRACE(COMP_RESET, "%s():<==========down process is finished\n", __func__);
3455 RT_TRACE(COMP_RESET, "%s():===========>start up the driver\n", __func__);
3456 reset_status = _rtl8192_up(dev);
3458 RT_TRACE(COMP_RESET, "%s():<===========up process is finished\n", __func__);
3459 if (reset_status == -EAGAIN) {
3460 if (reset_times < 3) {
3461 reset_times++;
3462 goto RESET_START;
3463 } else {
3464 RT_TRACE(COMP_ERR, " ERR!!! %s(): Reset Failed!!\n", __func__);
3467 ieee->is_silent_reset = 1;
3468 EnableHWSecurityConfig8192(dev);
3469 if (ieee->state == IEEE80211_LINKED && ieee->iw_mode == IW_MODE_INFRA) {
3470 ieee->set_chan(ieee->dev, ieee->current_network.channel);
3472 queue_work(ieee->wq, &ieee->associate_complete_wq);
3474 } else if (ieee->state == IEEE80211_LINKED && ieee->iw_mode == IW_MODE_ADHOC) {
3475 ieee->set_chan(ieee->dev, ieee->current_network.channel);
3476 ieee->link_change(ieee->dev);
3478 ieee80211_start_send_beacons(ieee);
3480 if (ieee->data_hard_resume)
3481 ieee->data_hard_resume(ieee->dev);
3482 netif_carrier_on(ieee->dev);
3485 CamRestoreAllEntry(dev);
3487 priv->ResetProgress = RESET_TYPE_NORESET;
3488 priv->reset_count++;
3490 priv->bForcedSilentReset = false;
3491 priv->bResetInProgress = false;
3493 // For test --> force write UFWP.
3494 write_nic_byte(dev, UFWP, 1);
3495 RT_TRACE(COMP_RESET, "Reset finished!! ====>[%d]\n", priv->reset_count);
3499 void CAM_read_entry(struct net_device *dev, u32 iIndex)
3501 u32 target_command = 0;
3502 u32 target_content = 0;
3503 u8 entry_i = 0;
3504 u32 ulStatus;
3505 s32 i = 100;
3506 for (entry_i = 0; entry_i < CAM_CONTENT_COUNT; entry_i++) {
3507 // polling bit, and No Write enable, and address
3508 target_command = entry_i+CAM_CONTENT_COUNT*iIndex;
3509 target_command = target_command | BIT31;
3511 //Check polling bit is clear
3512 while ((i--) >= 0) {
3513 read_nic_dword(dev, RWCAM, &ulStatus);
3514 if (ulStatus & BIT31)
3515 continue;
3516 else
3517 break;
3519 write_nic_dword(dev, RWCAM, target_command);
3520 RT_TRACE(COMP_SEC, "CAM_read_entry(): WRITE A0: %x \n", target_command);
3521 read_nic_dword(dev, RCAMO, &target_content);
3522 RT_TRACE(COMP_SEC, "CAM_read_entry(): WRITE A8: %x \n", target_content);
3524 printk("\n");
3527 void rtl819x_update_rxcounts(struct r8192_priv *priv, u32 *TotalRxBcnNum,
3528 u32 *TotalRxDataNum)
3530 u16 SlotIndex;
3531 u8 i;
3533 *TotalRxBcnNum = 0;
3534 *TotalRxDataNum = 0;
3536 SlotIndex = (priv->ieee80211->LinkDetectInfo.SlotIndex++)%(priv->ieee80211->LinkDetectInfo.SlotNum);
3537 priv->ieee80211->LinkDetectInfo.RxBcnNum[SlotIndex] = priv->ieee80211->LinkDetectInfo.NumRecvBcnInPeriod;
3538 priv->ieee80211->LinkDetectInfo.RxDataNum[SlotIndex] = priv->ieee80211->LinkDetectInfo.NumRecvDataInPeriod;
3539 for (i = 0; i < priv->ieee80211->LinkDetectInfo.SlotNum; i++) {
3540 *TotalRxBcnNum += priv->ieee80211->LinkDetectInfo.RxBcnNum[i];
3541 *TotalRxDataNum += priv->ieee80211->LinkDetectInfo.RxDataNum[i];
3546 extern void rtl819x_watchdog_wqcallback(struct work_struct *work)
3548 struct delayed_work *dwork = container_of(work, struct delayed_work, work);
3549 struct r8192_priv *priv = container_of(dwork, struct r8192_priv, watch_dog_wq);
3550 struct net_device *dev = priv->ieee80211->dev;
3551 struct ieee80211_device *ieee = priv->ieee80211;
3552 RESET_TYPE ResetType = RESET_TYPE_NORESET;
3553 static u8 check_reset_cnt;
3554 bool bBusyTraffic = false;
3555 u32 TotalRxBcnNum = 0;
3556 u32 TotalRxDataNum = 0;
3558 if (!priv->up)
3559 return;
3560 hal_dm_watchdog(dev);
3562 //to get busy traffic condition
3563 if (ieee->state == IEEE80211_LINKED) {
3564 if (ieee->LinkDetectInfo.NumRxOkInPeriod > 666 ||
3565 ieee->LinkDetectInfo.NumTxOkInPeriod > 666 ) {
3566 bBusyTraffic = true;
3568 ieee->LinkDetectInfo.NumRxOkInPeriod = 0;
3569 ieee->LinkDetectInfo.NumTxOkInPeriod = 0;
3570 ieee->LinkDetectInfo.bBusyTraffic = bBusyTraffic;
3572 //added by amy for AP roaming
3573 if (priv->ieee80211->state == IEEE80211_LINKED && priv->ieee80211->iw_mode == IW_MODE_INFRA) {
3575 rtl819x_update_rxcounts(priv, &TotalRxBcnNum, &TotalRxDataNum);
3576 if ((TotalRxBcnNum+TotalRxDataNum) == 0) {
3577 #ifdef TODO
3578 if (rfState == eRfOff)
3579 RT_TRACE(COMP_ERR, "========>%s()\n", __func__);
3580 #endif
3581 netdev_dbg(dev, "===>%s(): AP is power off, connect another one\n", __func__);
3582 priv->ieee80211->state = IEEE80211_ASSOCIATING;
3583 notify_wx_assoc_event(priv->ieee80211);
3584 RemovePeerTS(priv->ieee80211, priv->ieee80211->current_network.bssid);
3585 priv->ieee80211->link_change(dev);
3586 queue_work(priv->ieee80211->wq, &priv->ieee80211->associate_procedure_wq);
3590 priv->ieee80211->LinkDetectInfo.NumRecvBcnInPeriod = 0;
3591 priv->ieee80211->LinkDetectInfo.NumRecvDataInPeriod = 0;
3592 //check if reset the driver
3593 if (check_reset_cnt++ >= 3) {
3594 ResetType = rtl819x_ifcheck_resetornot(dev);
3595 check_reset_cnt = 3;
3597 if ((priv->force_reset) || (priv->ResetProgress == RESET_TYPE_NORESET &&
3598 (priv->bForcedSilentReset ||
3599 (!priv->bDisableNormalResetCheck && ResetType == RESET_TYPE_SILENT)))) { // This is control by OID set in Pomelo
3600 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", __func__, priv->force_reset, priv->ResetProgress, priv->bForcedSilentReset, priv->bDisableNormalResetCheck, ResetType);
3601 rtl819x_ifsilentreset(dev);
3603 priv->force_reset = false;
3604 priv->bForcedSilentReset = false;
3605 priv->bResetInProgress = false;
3606 RT_TRACE(COMP_TRACE, " <==RtUsbCheckForHangWorkItemCallback()\n");
3610 void watch_dog_timer_callback(unsigned long data)
3612 struct r8192_priv *priv = ieee80211_priv((struct net_device *) data);
3613 queue_delayed_work(priv->priv_wq, &priv->watch_dog_wq, 0);
3614 mod_timer(&priv->watch_dog_timer, jiffies + MSECS(IEEE80211_WATCH_DOG_TIME));
3616 int _rtl8192_up(struct net_device *dev)
3618 struct r8192_priv *priv = ieee80211_priv(dev);
3619 int init_status = 0;
3620 priv->up = 1;
3621 priv->ieee80211->ieee_up = 1;
3622 RT_TRACE(COMP_INIT, "Bringing up iface");
3623 init_status = rtl8192_adapter_start(dev);
3624 if (!init_status) {
3625 RT_TRACE(COMP_ERR, "ERR!!! %s(): initialization failed!\n", __func__);
3626 priv->up = priv->ieee80211->ieee_up = 0;
3627 return -EAGAIN;
3629 RT_TRACE(COMP_INIT, "start adapter finished\n");
3630 rtl8192_rx_enable(dev);
3631 if (priv->ieee80211->state != IEEE80211_LINKED)
3632 ieee80211_softmac_start_protocol(priv->ieee80211);
3633 ieee80211_reset_queue(priv->ieee80211);
3634 watch_dog_timer_callback((unsigned long) dev);
3635 if (!netif_queue_stopped(dev))
3636 netif_start_queue(dev);
3637 else
3638 netif_wake_queue(dev);
3640 return 0;
3644 int rtl8192_open(struct net_device *dev)
3646 struct r8192_priv *priv = ieee80211_priv(dev);
3647 int ret;
3648 down(&priv->wx_sem);
3649 ret = rtl8192_up(dev);
3650 up(&priv->wx_sem);
3651 return ret;
3656 int rtl8192_up(struct net_device *dev)
3658 struct r8192_priv *priv = ieee80211_priv(dev);
3660 if (priv->up == 1) return -1;
3662 return _rtl8192_up(dev);
3666 int rtl8192_close(struct net_device *dev)
3668 struct r8192_priv *priv = ieee80211_priv(dev);
3669 int ret;
3671 down(&priv->wx_sem);
3673 ret = rtl8192_down(dev);
3675 up(&priv->wx_sem);
3677 return ret;
3681 int rtl8192_down(struct net_device *dev)
3683 struct r8192_priv *priv = ieee80211_priv(dev);
3684 int i;
3686 if (priv->up == 0) return -1;
3688 priv->up = 0;
3689 priv->ieee80211->ieee_up = 0;
3690 RT_TRACE(COMP_DOWN, "==========>%s()\n", __func__);
3691 /* FIXME */
3692 if (!netif_queue_stopped(dev))
3693 netif_stop_queue(dev);
3695 rtl8192_rtx_disable(dev);
3697 /* Tx related queue release */
3698 for (i = 0; i < MAX_QUEUE_SIZE; i++)
3699 skb_queue_purge(&priv->ieee80211->skb_waitQ[i]);
3700 for (i = 0; i < MAX_QUEUE_SIZE; i++)
3701 skb_queue_purge(&priv->ieee80211->skb_aggQ[i]);
3703 for (i = 0; i < MAX_QUEUE_SIZE; i++)
3704 skb_queue_purge(&priv->ieee80211->skb_drv_aggQ[i]);
3706 //as cancel_delayed_work will del work->timer, so if work is not defined as struct delayed_work, it will corrupt
3707 rtl8192_cancel_deferred_work(priv);
3708 deinit_hal_dm(dev);
3709 del_timer_sync(&priv->watch_dog_timer);
3712 ieee80211_softmac_stop_protocol(priv->ieee80211);
3713 memset(&priv->ieee80211->current_network, 0, offsetof(struct ieee80211_network, list));
3714 RT_TRACE(COMP_DOWN, "<==========%s()\n", __func__);
3716 return 0;
3720 void rtl8192_commit(struct net_device *dev)
3722 struct r8192_priv *priv = ieee80211_priv(dev);
3723 int reset_status = 0;
3724 if (priv->up == 0) return;
3725 priv->up = 0;
3727 rtl8192_cancel_deferred_work(priv);
3728 del_timer_sync(&priv->watch_dog_timer);
3730 ieee80211_softmac_stop_protocol(priv->ieee80211);
3732 rtl8192_rtx_disable(dev);
3733 reset_status = _rtl8192_up(dev);
3737 void rtl8192_restart(struct work_struct *work)
3739 struct r8192_priv *priv = container_of(work, struct r8192_priv, reset_wq);
3740 struct net_device *dev = priv->ieee80211->dev;
3742 down(&priv->wx_sem);
3744 rtl8192_commit(dev);
3746 up(&priv->wx_sem);
3749 static void r8192_set_multicast(struct net_device *dev)
3751 struct r8192_priv *priv = ieee80211_priv(dev);
3752 short promisc;
3754 /* FIXME FIXME */
3756 promisc = (dev->flags & IFF_PROMISC) ? 1 : 0;
3758 if (promisc != priv->promisc)
3760 priv->promisc = promisc;
3764 int r8192_set_mac_adr(struct net_device *dev, void *mac)
3766 struct r8192_priv *priv = ieee80211_priv(dev);
3767 struct sockaddr *addr = mac;
3769 down(&priv->wx_sem);
3771 memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
3773 schedule_work(&priv->reset_wq);
3774 up(&priv->wx_sem);
3776 return 0;
3779 /* based on ipw2200 driver */
3780 int rtl8192_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
3782 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
3783 struct iwreq *wrq = (struct iwreq *)rq;
3784 int ret = -1;
3785 struct ieee80211_device *ieee = priv->ieee80211;
3786 u32 key[4];
3787 u8 broadcast_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
3788 struct iw_point *p = &wrq->u.data;
3789 struct ieee_param *ipw = NULL;
3791 down(&priv->wx_sem);
3794 if (p->length < sizeof(struct ieee_param) || !p->pointer) {
3795 ret = -EINVAL;
3796 goto out;
3799 ipw = kmalloc(p->length, GFP_KERNEL);
3800 if (ipw == NULL) {
3801 ret = -ENOMEM;
3802 goto out;
3804 if (copy_from_user(ipw, p->pointer, p->length)) {
3805 kfree(ipw);
3806 ret = -EFAULT;
3807 goto out;
3810 switch (cmd) {
3811 case RTL_IOCTL_WPA_SUPPLICANT:
3812 //parse here for HW security
3813 if (ipw->cmd == IEEE_CMD_SET_ENCRYPTION) {
3814 if (ipw->u.crypt.set_tx) {
3815 if (strcmp(ipw->u.crypt.alg, "CCMP") == 0) {
3816 ieee->pairwise_key_type = KEY_TYPE_CCMP;
3817 } else if (strcmp(ipw->u.crypt.alg, "TKIP") == 0) {
3818 ieee->pairwise_key_type = KEY_TYPE_TKIP;
3819 } else if (strcmp(ipw->u.crypt.alg, "WEP") == 0) {
3820 if (ipw->u.crypt.key_len == 13)
3821 ieee->pairwise_key_type = KEY_TYPE_WEP104;
3822 else if (ipw->u.crypt.key_len == 5)
3823 ieee->pairwise_key_type = KEY_TYPE_WEP40;
3824 } else {
3825 ieee->pairwise_key_type = KEY_TYPE_NA;
3828 if (ieee->pairwise_key_type) {
3829 memcpy((u8 *)key, ipw->u.crypt.key, 16);
3830 EnableHWSecurityConfig8192(dev);
3831 //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!
3832 //added by WB.
3833 setKey(dev, 4, ipw->u.crypt.idx, ieee->pairwise_key_type, (u8 *)ieee->ap_mac_addr, 0, key);
3834 if (ieee->auth_mode != 2)
3835 setKey(dev, ipw->u.crypt.idx, ipw->u.crypt.idx, ieee->pairwise_key_type, (u8 *)ieee->ap_mac_addr, 0, key);
3837 } else {
3838 memcpy((u8 *)key, ipw->u.crypt.key, 16);
3839 if (strcmp(ipw->u.crypt.alg, "CCMP") == 0) {
3840 ieee->group_key_type = KEY_TYPE_CCMP;
3841 } else if (strcmp(ipw->u.crypt.alg, "TKIP") == 0) {
3842 ieee->group_key_type = KEY_TYPE_TKIP;
3843 } else if (strcmp(ipw->u.crypt.alg, "WEP") == 0) {
3844 if (ipw->u.crypt.key_len == 13)
3845 ieee->group_key_type = KEY_TYPE_WEP104;
3846 else if (ipw->u.crypt.key_len == 5)
3847 ieee->group_key_type = KEY_TYPE_WEP40;
3848 } else {
3849 ieee->group_key_type = KEY_TYPE_NA;
3852 if (ieee->group_key_type) {
3853 setKey(dev, ipw->u.crypt.idx,
3854 ipw->u.crypt.idx, //KeyIndex
3855 ieee->group_key_type, //KeyType
3856 broadcast_addr, //MacAddr
3857 0, //DefaultKey
3858 key); //KeyContent
3862 #ifdef JOHN_HWSEC_DEBUG
3863 //john's test 0711
3864 printk("@@ wrq->u pointer = ");
3865 for (i = 0; i < wrq->u.data.length; i++) {
3866 if (i%10 == 0) printk("\n");
3867 printk("%8x|", ((u32 *)wrq->u.data.pointer)[i]);
3869 printk("\n");
3870 #endif /*JOHN_HWSEC_DEBUG*/
3871 ret = ieee80211_wpa_supplicant_ioctl(priv->ieee80211, &wrq->u.data);
3872 break;
3874 default:
3875 ret = -EOPNOTSUPP;
3876 break;
3878 kfree(ipw);
3879 ipw = NULL;
3880 out:
3881 up(&priv->wx_sem);
3882 return ret;
3885 u8 HwRateToMRate90(bool bIsHT, u8 rate)
3887 u8 ret_rate = 0xff;
3889 if (!bIsHT) {
3890 switch (rate) {
3891 case DESC90_RATE1M: ret_rate = MGN_1M; break;
3892 case DESC90_RATE2M: ret_rate = MGN_2M; break;
3893 case DESC90_RATE5_5M: ret_rate = MGN_5_5M; break;
3894 case DESC90_RATE11M: ret_rate = MGN_11M; break;
3895 case DESC90_RATE6M: ret_rate = MGN_6M; break;
3896 case DESC90_RATE9M: ret_rate = MGN_9M; break;
3897 case DESC90_RATE12M: ret_rate = MGN_12M; break;
3898 case DESC90_RATE18M: ret_rate = MGN_18M; break;
3899 case DESC90_RATE24M: ret_rate = MGN_24M; break;
3900 case DESC90_RATE36M: ret_rate = MGN_36M; break;
3901 case DESC90_RATE48M: ret_rate = MGN_48M; break;
3902 case DESC90_RATE54M: ret_rate = MGN_54M; break;
3904 default:
3905 ret_rate = 0xff;
3906 RT_TRACE(COMP_RECV, "HwRateToMRate90(): Non supported Rate [%x], bIsHT = %d!!!\n", rate, bIsHT);
3907 break;
3910 } else {
3911 switch (rate) {
3912 case DESC90_RATEMCS0: ret_rate = MGN_MCS0; break;
3913 case DESC90_RATEMCS1: ret_rate = MGN_MCS1; break;
3914 case DESC90_RATEMCS2: ret_rate = MGN_MCS2; break;
3915 case DESC90_RATEMCS3: ret_rate = MGN_MCS3; break;
3916 case DESC90_RATEMCS4: ret_rate = MGN_MCS4; break;
3917 case DESC90_RATEMCS5: ret_rate = MGN_MCS5; break;
3918 case DESC90_RATEMCS6: ret_rate = MGN_MCS6; break;
3919 case DESC90_RATEMCS7: ret_rate = MGN_MCS7; break;
3920 case DESC90_RATEMCS8: ret_rate = MGN_MCS8; break;
3921 case DESC90_RATEMCS9: ret_rate = MGN_MCS9; break;
3922 case DESC90_RATEMCS10: ret_rate = MGN_MCS10; break;
3923 case DESC90_RATEMCS11: ret_rate = MGN_MCS11; break;
3924 case DESC90_RATEMCS12: ret_rate = MGN_MCS12; break;
3925 case DESC90_RATEMCS13: ret_rate = MGN_MCS13; break;
3926 case DESC90_RATEMCS14: ret_rate = MGN_MCS14; break;
3927 case DESC90_RATEMCS15: ret_rate = MGN_MCS15; break;
3928 case DESC90_RATEMCS32: ret_rate = (0x80|0x20); break;
3930 default:
3931 ret_rate = 0xff;
3932 RT_TRACE(COMP_RECV, "HwRateToMRate90(): Non supported Rate [%x], bIsHT = %d!!!\n", rate, bIsHT);
3933 break;
3937 return ret_rate;
3941 * Function: UpdateRxPktTimeStamp
3942 * Overview: Record the TSF time stamp when receiving a packet
3944 * Input:
3945 * PADAPTER Adapter
3946 * PRT_RFD pRfd,
3948 * Output:
3949 * PRT_RFD pRfd
3950 * (pRfd->Status.TimeStampHigh is updated)
3951 * (pRfd->Status.TimeStampLow is updated)
3952 * Return:
3953 * None
3955 void UpdateRxPktTimeStamp8190(struct net_device *dev, struct ieee80211_rx_stats *stats)
3957 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
3959 if (stats->bIsAMPDU && !stats->bFirstMPDU) {
3960 stats->mac_time[0] = priv->LastRxDescTSFLow;
3961 stats->mac_time[1] = priv->LastRxDescTSFHigh;
3962 } else {
3963 priv->LastRxDescTSFLow = stats->mac_time[0];
3964 priv->LastRxDescTSFHigh = stats->mac_time[1];
3968 //by amy 080606
3970 long rtl819x_translate_todbm(u8 signal_strength_index)// 0-100 index.
3972 long signal_power; // in dBm.
3974 // Translate to dBm (x=0.5y-95).
3975 signal_power = (long)((signal_strength_index + 1) >> 1);
3976 signal_power -= 95;
3978 return signal_power;
3982 /* 2008/01/22 MH We can not declare RSSI/EVM total value of sliding window to
3983 be a local static. Otherwise, it may increase when we return from S3/S4. The
3984 value will be kept in memory or disk. Declare the value in the adaptor
3985 and it will be reinitialized when returned from S3/S4. */
3986 void rtl8192_process_phyinfo(struct r8192_priv *priv, u8 *buffer, struct ieee80211_rx_stats *pprevious_stats, struct ieee80211_rx_stats *pcurrent_stats)
3988 bool bcheck = false;
3989 u8 rfpath;
3990 u32 nspatial_stream, tmp_val;
3991 static u32 slide_rssi_index, slide_rssi_statistics;
3992 static u32 slide_evm_index, slide_evm_statistics;
3993 static u32 last_rssi, last_evm;
3995 static u32 slide_beacon_adc_pwdb_index, slide_beacon_adc_pwdb_statistics;
3996 static u32 last_beacon_adc_pwdb;
3998 struct ieee80211_hdr_3addr *hdr;
3999 u16 sc;
4000 unsigned int frag, seq;
4001 hdr = (struct ieee80211_hdr_3addr *)buffer;
4002 sc = le16_to_cpu(hdr->seq_ctl);
4003 frag = WLAN_GET_SEQ_FRAG(sc);
4004 seq = WLAN_GET_SEQ_SEQ(sc);
4005 //cosa add 04292008 to record the sequence number
4006 pcurrent_stats->Seq_Num = seq;
4008 // Check whether we should take the previous packet into accounting
4010 if (!pprevious_stats->bIsAMPDU) {
4011 // if previous packet is not aggregated packet
4012 bcheck = true;
4015 if (slide_rssi_statistics++ >= PHY_RSSI_SLID_WIN_MAX) {
4016 slide_rssi_statistics = PHY_RSSI_SLID_WIN_MAX;
4017 last_rssi = priv->stats.slide_signal_strength[slide_rssi_index];
4018 priv->stats.slide_rssi_total -= last_rssi;
4020 priv->stats.slide_rssi_total += pprevious_stats->SignalStrength;
4022 priv->stats.slide_signal_strength[slide_rssi_index++] = pprevious_stats->SignalStrength;
4023 if (slide_rssi_index >= PHY_RSSI_SLID_WIN_MAX)
4024 slide_rssi_index = 0;
4026 // <1> Showed on UI for user, in dbm
4027 tmp_val = priv->stats.slide_rssi_total/slide_rssi_statistics;
4028 priv->stats.signal_strength = rtl819x_translate_todbm((u8)tmp_val);
4029 pcurrent_stats->rssi = priv->stats.signal_strength;
4031 // If the previous packet does not match the criteria, neglect it
4033 if (!pprevious_stats->bPacketMatchBSSID) {
4034 if (!pprevious_stats->bToSelfBA)
4035 return;
4038 if (!bcheck)
4039 return;
4042 //rtl8190_process_cck_rxpathsel(priv,pprevious_stats);//only rtl8190 supported
4045 // Check RSSI
4047 priv->stats.num_process_phyinfo++;
4049 /* record the general signal strength to the sliding window. */
4052 // <2> Showed on UI for engineering
4053 // hardware does not provide rssi information for each rf path in CCK
4054 if (!pprevious_stats->bIsCCK && (pprevious_stats->bPacketToSelf || pprevious_stats->bToSelfBA)) {
4055 for (rfpath = RF90_PATH_A; rfpath < priv->NumTotalRFPath; rfpath++) {
4056 if (!rtl8192_phy_CheckIsLegalRFPath(priv->ieee80211->dev, rfpath))
4057 continue;
4059 //Fixed by Jacken 2008-03-20
4060 if (priv->stats.rx_rssi_percentage[rfpath] == 0)
4061 priv->stats.rx_rssi_percentage[rfpath] = pprevious_stats->RxMIMOSignalStrength[rfpath];
4062 if (pprevious_stats->RxMIMOSignalStrength[rfpath] > priv->stats.rx_rssi_percentage[rfpath]) {
4063 priv->stats.rx_rssi_percentage[rfpath] =
4064 ((priv->stats.rx_rssi_percentage[rfpath]*(Rx_Smooth_Factor-1)) +
4065 (pprevious_stats->RxMIMOSignalStrength[rfpath])) /(Rx_Smooth_Factor);
4066 priv->stats.rx_rssi_percentage[rfpath] = priv->stats.rx_rssi_percentage[rfpath] + 1;
4067 } else {
4068 priv->stats.rx_rssi_percentage[rfpath] =
4069 ((priv->stats.rx_rssi_percentage[rfpath]*(Rx_Smooth_Factor-1)) +
4070 (pprevious_stats->RxMIMOSignalStrength[rfpath])) /(Rx_Smooth_Factor);
4072 RT_TRACE(COMP_DBG, "priv->stats.rx_rssi_percentage[rfPath] = %d \n", priv->stats.rx_rssi_percentage[rfpath]);
4078 // Check PWDB.
4080 RT_TRACE(COMP_RXDESC, "Smooth %s PWDB = %d\n",
4081 pprevious_stats->bIsCCK ? "CCK" : "OFDM",
4082 pprevious_stats->RxPWDBAll);
4084 if (pprevious_stats->bPacketBeacon) {
4085 /* record the beacon pwdb to the sliding window. */
4086 if (slide_beacon_adc_pwdb_statistics++ >= PHY_Beacon_RSSI_SLID_WIN_MAX) {
4087 slide_beacon_adc_pwdb_statistics = PHY_Beacon_RSSI_SLID_WIN_MAX;
4088 last_beacon_adc_pwdb = priv->stats.Slide_Beacon_pwdb[slide_beacon_adc_pwdb_index];
4089 priv->stats.Slide_Beacon_Total -= last_beacon_adc_pwdb;
4091 priv->stats.Slide_Beacon_Total += pprevious_stats->RxPWDBAll;
4092 priv->stats.Slide_Beacon_pwdb[slide_beacon_adc_pwdb_index] = pprevious_stats->RxPWDBAll;
4093 slide_beacon_adc_pwdb_index++;
4094 if (slide_beacon_adc_pwdb_index >= PHY_Beacon_RSSI_SLID_WIN_MAX)
4095 slide_beacon_adc_pwdb_index = 0;
4096 pprevious_stats->RxPWDBAll = priv->stats.Slide_Beacon_Total/slide_beacon_adc_pwdb_statistics;
4097 if (pprevious_stats->RxPWDBAll >= 3)
4098 pprevious_stats->RxPWDBAll -= 3;
4101 RT_TRACE(COMP_RXDESC, "Smooth %s PWDB = %d\n",
4102 pprevious_stats->bIsCCK ? "CCK" : "OFDM",
4103 pprevious_stats->RxPWDBAll);
4106 if (pprevious_stats->bPacketToSelf || pprevious_stats->bPacketBeacon || pprevious_stats->bToSelfBA) {
4107 if (priv->undecorated_smoothed_pwdb < 0) // initialize
4108 priv->undecorated_smoothed_pwdb = pprevious_stats->RxPWDBAll;
4109 if (pprevious_stats->RxPWDBAll > (u32)priv->undecorated_smoothed_pwdb) {
4110 priv->undecorated_smoothed_pwdb =
4111 (((priv->undecorated_smoothed_pwdb)*(Rx_Smooth_Factor-1)) +
4112 (pprevious_stats->RxPWDBAll)) /(Rx_Smooth_Factor);
4113 priv->undecorated_smoothed_pwdb = priv->undecorated_smoothed_pwdb + 1;
4114 } else {
4115 priv->undecorated_smoothed_pwdb =
4116 (((priv->undecorated_smoothed_pwdb)*(Rx_Smooth_Factor-1)) +
4117 (pprevious_stats->RxPWDBAll)) /(Rx_Smooth_Factor);
4123 // Check EVM
4125 /* record the general EVM to the sliding window. */
4126 if (pprevious_stats->SignalQuality) {
4127 if (pprevious_stats->bPacketToSelf || pprevious_stats->bPacketBeacon || pprevious_stats->bToSelfBA) {
4128 if (slide_evm_statistics++ >= PHY_RSSI_SLID_WIN_MAX) {
4129 slide_evm_statistics = PHY_RSSI_SLID_WIN_MAX;
4130 last_evm = priv->stats.slide_evm[slide_evm_index];
4131 priv->stats.slide_evm_total -= last_evm;
4134 priv->stats.slide_evm_total += pprevious_stats->SignalQuality;
4136 priv->stats.slide_evm[slide_evm_index++] = pprevious_stats->SignalQuality;
4137 if (slide_evm_index >= PHY_RSSI_SLID_WIN_MAX)
4138 slide_evm_index = 0;
4140 // <1> Showed on UI for user, in percentage.
4141 tmp_val = priv->stats.slide_evm_total/slide_evm_statistics;
4142 priv->stats.signal_quality = tmp_val;
4143 //cosa add 10/11/2007, Showed on UI for user in Windows Vista, for Link quality.
4144 priv->stats.last_signal_strength_inpercent = tmp_val;
4147 // <2> Showed on UI for engineering
4148 if (pprevious_stats->bPacketToSelf || pprevious_stats->bPacketBeacon || pprevious_stats->bToSelfBA) {
4149 for (nspatial_stream = 0; nspatial_stream < 2; nspatial_stream++) { // 2 spatial stream
4150 if (pprevious_stats->RxMIMOSignalQuality[nspatial_stream] != -1) {
4151 if (priv->stats.rx_evm_percentage[nspatial_stream] == 0) // initialize
4152 priv->stats.rx_evm_percentage[nspatial_stream] = pprevious_stats->RxMIMOSignalQuality[nspatial_stream];
4153 priv->stats.rx_evm_percentage[nspatial_stream] =
4154 ((priv->stats.rx_evm_percentage[nspatial_stream]* (Rx_Smooth_Factor-1)) +
4155 (pprevious_stats->RxMIMOSignalQuality[nspatial_stream]* 1)) / (Rx_Smooth_Factor);
4164 /*-----------------------------------------------------------------------------
4165 * Function: rtl819x_query_rxpwrpercentage()
4167 * Overview:
4169 * Input: char antpower
4171 * Output: NONE
4173 * Return: 0-100 percentage
4175 * Revised History:
4176 * When Who Remark
4177 * 05/26/2008 amy Create Version 0 porting from windows code.
4179 *---------------------------------------------------------------------------*/
4180 static u8 rtl819x_query_rxpwrpercentage(char antpower)
4182 if ((antpower <= -100) || (antpower >= 20))
4183 return 0;
4184 else if (antpower >= 0)
4185 return 100;
4186 else
4187 return 100 + antpower;
4189 } /* QueryRxPwrPercentage */
4191 static u8 rtl819x_evm_dbtopercentage(char value)
4193 char ret_val;
4195 ret_val = value;
4197 if (ret_val >= 0)
4198 ret_val = 0;
4199 if (ret_val <= -33)
4200 ret_val = -33;
4201 ret_val = 0 - ret_val;
4202 ret_val *= 3;
4203 if (ret_val == 99)
4204 ret_val = 100;
4205 return ret_val;
4208 // Description:
4209 // We want good-looking for signal strength/quality
4210 // 2007/7/19 01:09, by cosa.
4212 long rtl819x_signal_scale_mapping(long currsig)
4214 long retsig;
4216 // Step 1. Scale mapping.
4217 if (currsig >= 61 && currsig <= 100)
4218 retsig = 90 + ((currsig - 60) / 4);
4219 else if (currsig >= 41 && currsig <= 60)
4220 retsig = 78 + ((currsig - 40) / 2);
4221 else if (currsig >= 31 && currsig <= 40)
4222 retsig = 66 + (currsig - 30);
4223 else if (currsig >= 21 && currsig <= 30)
4224 retsig = 54 + (currsig - 20);
4225 else if (currsig >= 5 && currsig <= 20)
4226 retsig = 42 + (((currsig - 5) * 2) / 3);
4227 else if (currsig == 4)
4228 retsig = 36;
4229 else if (currsig == 3)
4230 retsig = 27;
4231 else if (currsig == 2)
4232 retsig = 18;
4233 else if (currsig == 1)
4234 retsig = 9;
4235 else
4236 retsig = currsig;
4238 return retsig;
4241 static inline bool rx_hal_is_cck_rate(struct rx_drvinfo_819x_usb *pdrvinfo)
4243 if (pdrvinfo->RxHT)
4244 return false;
4246 switch (pdrvinfo->RxRate) {
4247 case DESC90_RATE1M:
4248 case DESC90_RATE2M:
4249 case DESC90_RATE5_5M:
4250 case DESC90_RATE11M:
4251 return true;
4252 default:
4253 return false;
4257 static void rtl8192_query_rxphystatus(struct r8192_priv *priv,
4258 struct ieee80211_rx_stats *pstats,
4259 rx_drvinfo_819x_usb *pdrvinfo,
4260 struct ieee80211_rx_stats *precord_stats,
4261 bool bpacket_match_bssid,
4262 bool bpacket_toself,
4263 bool bPacketBeacon,
4264 bool bToSelfBA)
4266 phy_sts_ofdm_819xusb_t *pofdm_buf;
4267 phy_sts_cck_819xusb_t *pcck_buf;
4268 phy_ofdm_rx_status_rxsc_sgien_exintfflag *prxsc;
4269 u8 *prxpkt;
4270 u8 i, max_spatial_stream, tmp_rxsnr, tmp_rxevm, rxsc_sgien_exflg;
4271 char rx_pwr[4], rx_pwr_all = 0;
4272 char rx_snrX, rx_evmX;
4273 u8 evm, pwdb_all;
4274 u32 RSSI, total_rssi = 0;
4275 u8 is_cck_rate = 0;
4276 u8 rf_rx_num = 0;
4277 u8 sq;
4280 priv->stats.numqry_phystatus++;
4282 is_cck_rate = rx_hal_is_cck_rate(pdrvinfo);
4284 // Record it for next packet processing
4285 memset(precord_stats, 0, sizeof(struct ieee80211_rx_stats));
4286 pstats->bPacketMatchBSSID = precord_stats->bPacketMatchBSSID = bpacket_match_bssid;
4287 pstats->bPacketToSelf = precord_stats->bPacketToSelf = bpacket_toself;
4288 pstats->bIsCCK = precord_stats->bIsCCK = is_cck_rate;
4289 pstats->bPacketBeacon = precord_stats->bPacketBeacon = bPacketBeacon;
4290 pstats->bToSelfBA = precord_stats->bToSelfBA = bToSelfBA;
4292 prxpkt = (u8 *)pdrvinfo;
4294 /* Move pointer to the 16th bytes. Phy status start address. */
4295 prxpkt += sizeof(rx_drvinfo_819x_usb);
4297 /* Initial the cck and ofdm buffer pointer */
4298 pcck_buf = (phy_sts_cck_819xusb_t *)prxpkt;
4299 pofdm_buf = (phy_sts_ofdm_819xusb_t *)prxpkt;
4301 pstats->RxMIMOSignalQuality[0] = -1;
4302 pstats->RxMIMOSignalQuality[1] = -1;
4303 precord_stats->RxMIMOSignalQuality[0] = -1;
4304 precord_stats->RxMIMOSignalQuality[1] = -1;
4306 if (is_cck_rate) {
4308 // (1)Hardware does not provide RSSI for CCK
4312 // (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive)
4314 u8 report;
4316 priv->stats.numqry_phystatusCCK++;
4318 if (!priv->bCckHighPower) {
4319 report = pcck_buf->cck_agc_rpt & 0xc0;
4320 report = report>>6;
4321 switch (report) {
4322 //Fixed by Jacken from Bryant 2008-03-20
4323 //Original value is -38 , -26 , -14 , -2
4324 //Fixed value is -35 , -23 , -11 , 6
4325 case 0x3:
4326 rx_pwr_all = -35 - (pcck_buf->cck_agc_rpt & 0x3e);
4327 break;
4328 case 0x2:
4329 rx_pwr_all = -23 - (pcck_buf->cck_agc_rpt & 0x3e);
4330 break;
4331 case 0x1:
4332 rx_pwr_all = -11 - (pcck_buf->cck_agc_rpt & 0x3e);
4333 break;
4334 case 0x0:
4335 rx_pwr_all = 6 - (pcck_buf->cck_agc_rpt & 0x3e);
4336 break;
4338 } else {
4339 report = pcck_buf->cck_agc_rpt & 0x60;
4340 report = report>>5;
4341 switch (report) {
4342 case 0x3:
4343 rx_pwr_all = -35 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1);
4344 break;
4345 case 0x2:
4346 rx_pwr_all = -23 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1);
4347 break;
4348 case 0x1:
4349 rx_pwr_all = -11 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1);
4350 break;
4351 case 0x0:
4352 rx_pwr_all = 6 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1);
4353 break;
4357 pwdb_all = rtl819x_query_rxpwrpercentage(rx_pwr_all);
4358 pstats->RxPWDBAll = precord_stats->RxPWDBAll = pwdb_all;
4359 pstats->RecvSignalPower = pwdb_all;
4362 // (3) Get Signal Quality (EVM)
4365 if (pstats->RxPWDBAll > 40) {
4366 sq = 100;
4367 } else {
4368 sq = pcck_buf->sq_rpt;
4370 if (pcck_buf->sq_rpt > 64)
4371 sq = 0;
4372 else if (pcck_buf->sq_rpt < 20)
4373 sq = 100;
4374 else
4375 sq = ((64-sq) * 100) / 44;
4377 pstats->SignalQuality = precord_stats->SignalQuality = sq;
4378 pstats->RxMIMOSignalQuality[0] = precord_stats->RxMIMOSignalQuality[0] = sq;
4379 pstats->RxMIMOSignalQuality[1] = precord_stats->RxMIMOSignalQuality[1] = -1;
4381 } else {
4382 priv->stats.numqry_phystatusHT++;
4384 // (1)Get RSSI for HT rate
4386 for (i = RF90_PATH_A; i < priv->NumTotalRFPath; i++) {
4387 // 2008/01/30 MH we will judge RF RX path now.
4388 if (priv->brfpath_rxenable[i])
4389 rf_rx_num++;
4390 else
4391 continue;
4393 if (!rtl8192_phy_CheckIsLegalRFPath(priv->ieee80211->dev, i))
4394 continue;
4396 //Fixed by Jacken from Bryant 2008-03-20
4397 //Original value is 106
4398 rx_pwr[i] = ((pofdm_buf->trsw_gain_X[i]&0x3F)*2) - 106;
4400 //Get Rx snr value in DB
4401 tmp_rxsnr = pofdm_buf->rxsnr_X[i];
4402 rx_snrX = (char)(tmp_rxsnr);
4403 rx_snrX /= 2;
4404 priv->stats.rxSNRdB[i] = (long)rx_snrX;
4406 /* Translate DBM to percentage. */
4407 RSSI = rtl819x_query_rxpwrpercentage(rx_pwr[i]);
4408 total_rssi += RSSI;
4410 /* Record Signal Strength for next packet */
4411 pstats->RxMIMOSignalStrength[i] = (u8) RSSI;
4412 precord_stats->RxMIMOSignalStrength[i] = (u8) RSSI;
4417 // (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive)
4419 //Fixed by Jacken from Bryant 2008-03-20
4420 //Original value is 106
4421 rx_pwr_all = (((pofdm_buf->pwdb_all) >> 1)& 0x7f) -106;
4422 pwdb_all = rtl819x_query_rxpwrpercentage(rx_pwr_all);
4424 pstats->RxPWDBAll = precord_stats->RxPWDBAll = pwdb_all;
4425 pstats->RxPower = precord_stats->RxPower = rx_pwr_all;
4428 // (3)EVM of HT rate
4430 if (pdrvinfo->RxHT && pdrvinfo->RxRate >= DESC90_RATEMCS8 &&
4431 pdrvinfo->RxRate <= DESC90_RATEMCS15)
4432 max_spatial_stream = 2; //both spatial stream make sense
4433 else
4434 max_spatial_stream = 1; //only spatial stream 1 makes sense
4436 for (i = 0; i < max_spatial_stream; i++) {
4437 tmp_rxevm = pofdm_buf->rxevm_X[i];
4438 rx_evmX = (char)(tmp_rxevm);
4440 // Do not use shift operation like "rx_evmX >>= 1" because the compiler of free build environment
4441 // will set the most significant bit to "zero" when doing shifting operation which may change a negative
4442 // value to positive one, then the dbm value (which is supposed to be negative) is not correct anymore.
4443 rx_evmX /= 2; //dbm
4445 evm = rtl819x_evm_dbtopercentage(rx_evmX);
4446 if (i == 0) // Fill value in RFD, Get the first spatial stream only
4447 pstats->SignalQuality = precord_stats->SignalQuality = (u8)(evm & 0xff);
4448 pstats->RxMIMOSignalQuality[i] = precord_stats->RxMIMOSignalQuality[i] = (u8)(evm & 0xff);
4452 /* record rx statistics for debug */
4453 rxsc_sgien_exflg = pofdm_buf->rxsc_sgien_exflg;
4454 prxsc = (phy_ofdm_rx_status_rxsc_sgien_exintfflag *)&rxsc_sgien_exflg;
4455 if (pdrvinfo->BW) //40M channel
4456 priv->stats.received_bwtype[1+prxsc->rxsc]++;
4457 else //20M channel
4458 priv->stats.received_bwtype[0]++;
4461 //UI BSS List signal strength(in percentage), make it good looking, from 0~100.
4462 //It is assigned to the BSS List in GetValueFromBeaconOrProbeRsp().
4463 if (is_cck_rate) {
4464 pstats->SignalStrength = precord_stats->SignalStrength = (u8)(rtl819x_signal_scale_mapping((long)pwdb_all));
4465 } else {
4466 // We can judge RX path number now.
4467 if (rf_rx_num != 0)
4468 pstats->SignalStrength = precord_stats->SignalStrength = (u8)(rtl819x_signal_scale_mapping((long)(total_rssi /= rf_rx_num)));
4470 } /* QueryRxPhyStatus8190Pci */
4472 void rtl8192_record_rxdesc_forlateruse(struct ieee80211_rx_stats *psrc_stats,
4473 struct ieee80211_rx_stats *ptarget_stats)
4475 ptarget_stats->bIsAMPDU = psrc_stats->bIsAMPDU;
4476 ptarget_stats->bFirstMPDU = psrc_stats->bFirstMPDU;
4477 ptarget_stats->Seq_Num = psrc_stats->Seq_Num;
4481 void TranslateRxSignalStuff819xUsb(struct sk_buff *skb,
4482 struct ieee80211_rx_stats *pstats,
4483 rx_drvinfo_819x_usb *pdrvinfo)
4485 // TODO: We must only check packet for current MAC address. Not finish
4486 rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
4487 struct net_device *dev = info->dev;
4488 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
4489 bool bpacket_match_bssid, bpacket_toself;
4490 bool bPacketBeacon = FALSE, bToSelfBA = FALSE;
4491 static struct ieee80211_rx_stats previous_stats;
4492 struct ieee80211_hdr_3addr *hdr;//by amy
4493 u16 fc, type;
4495 // Get Signal Quality for only RX data queue (but not command queue)
4497 u8 *tmp_buf;
4498 u8 *praddr;
4500 /* Get MAC frame start address. */
4501 tmp_buf = (u8 *)skb->data;
4503 hdr = (struct ieee80211_hdr_3addr *)tmp_buf;
4504 fc = le16_to_cpu(hdr->frame_ctl);
4505 type = WLAN_FC_GET_TYPE(fc);
4506 praddr = hdr->addr1;
4508 /* Check if the received packet is acceptable. */
4509 bpacket_match_bssid = ((IEEE80211_FTYPE_CTL != type) &&
4510 (eqMacAddr(priv->ieee80211->current_network.bssid, (fc & IEEE80211_FCTL_TODS) ? hdr->addr1 : (fc & IEEE80211_FCTL_FROMDS) ? hdr->addr2 : hdr->addr3))
4511 && (!pstats->bHwError) && (!pstats->bCRC) && (!pstats->bICV));
4512 bpacket_toself = bpacket_match_bssid & (eqMacAddr(praddr, priv->ieee80211->dev->dev_addr));
4514 if (WLAN_FC_GET_FRAMETYPE(fc) == IEEE80211_STYPE_BEACON)
4515 bPacketBeacon = true;
4516 if (WLAN_FC_GET_FRAMETYPE(fc) == IEEE80211_STYPE_BLOCKACK) {
4517 if ((eqMacAddr(praddr, dev->dev_addr)))
4518 bToSelfBA = true;
4523 if (bpacket_match_bssid)
4524 priv->stats.numpacket_matchbssid++;
4525 if (bpacket_toself)
4526 priv->stats.numpacket_toself++;
4528 // Process PHY information for previous packet (RSSI/PWDB/EVM)
4530 // Because phy information is contained in the last packet of AMPDU only, so driver
4531 // should process phy information of previous packet
4532 rtl8192_process_phyinfo(priv, tmp_buf, &previous_stats, pstats);
4533 rtl8192_query_rxphystatus(priv, pstats, pdrvinfo, &previous_stats, bpacket_match_bssid, bpacket_toself, bPacketBeacon, bToSelfBA);
4534 rtl8192_record_rxdesc_forlateruse(pstats, &previous_stats);
4539 * Function: UpdateReceivedRateHistogramStatistics
4540 * Overview: Record the received data rate
4542 * Input:
4543 * struct net_device *dev
4544 * struct ieee80211_rx_stats *stats
4546 * Output:
4548 * (priv->stats.ReceivedRateHistogram[] is updated)
4549 * Return:
4550 * None
4552 void UpdateReceivedRateHistogramStatistics8190(struct net_device *dev,
4553 struct ieee80211_rx_stats *stats)
4555 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
4556 u32 rcvType = 1; //0: Total, 1:OK, 2:CRC, 3:ICV
4557 u32 rateIndex;
4558 u32 preamble_guardinterval; //1: short preamble/GI, 0: long preamble/GI
4561 if (stats->bCRC)
4562 rcvType = 2;
4563 else if (stats->bICV)
4564 rcvType = 3;
4566 if (stats->bShortPreamble)
4567 preamble_guardinterval = 1;// short
4568 else
4569 preamble_guardinterval = 0;// long
4571 switch (stats->rate) {
4573 // CCK rate
4575 case MGN_1M: rateIndex = 0; break;
4576 case MGN_2M: rateIndex = 1; break;
4577 case MGN_5_5M: rateIndex = 2; break;
4578 case MGN_11M: rateIndex = 3; break;
4580 // Legacy OFDM rate
4582 case MGN_6M: rateIndex = 4; break;
4583 case MGN_9M: rateIndex = 5; break;
4584 case MGN_12M: rateIndex = 6; break;
4585 case MGN_18M: rateIndex = 7; break;
4586 case MGN_24M: rateIndex = 8; break;
4587 case MGN_36M: rateIndex = 9; break;
4588 case MGN_48M: rateIndex = 10; break;
4589 case MGN_54M: rateIndex = 11; break;
4591 // 11n High throughput rate
4593 case MGN_MCS0: rateIndex = 12; break;
4594 case MGN_MCS1: rateIndex = 13; break;
4595 case MGN_MCS2: rateIndex = 14; break;
4596 case MGN_MCS3: rateIndex = 15; break;
4597 case MGN_MCS4: rateIndex = 16; break;
4598 case MGN_MCS5: rateIndex = 17; break;
4599 case MGN_MCS6: rateIndex = 18; break;
4600 case MGN_MCS7: rateIndex = 19; break;
4601 case MGN_MCS8: rateIndex = 20; break;
4602 case MGN_MCS9: rateIndex = 21; break;
4603 case MGN_MCS10: rateIndex = 22; break;
4604 case MGN_MCS11: rateIndex = 23; break;
4605 case MGN_MCS12: rateIndex = 24; break;
4606 case MGN_MCS13: rateIndex = 25; break;
4607 case MGN_MCS14: rateIndex = 26; break;
4608 case MGN_MCS15: rateIndex = 27; break;
4609 default: rateIndex = 28; break;
4611 priv->stats.received_preamble_GI[preamble_guardinterval][rateIndex]++;
4612 priv->stats.received_rate_histogram[0][rateIndex]++; //total
4613 priv->stats.received_rate_histogram[rcvType][rateIndex]++;
4617 void query_rxdesc_status(struct sk_buff *skb, struct ieee80211_rx_stats *stats, bool bIsRxAggrSubframe)
4619 rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
4620 struct net_device *dev = info->dev;
4621 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
4622 rx_drvinfo_819x_usb *driver_info = NULL;
4625 //Get Rx Descriptor Information
4627 #ifdef USB_RX_AGGREGATION_SUPPORT
4628 if (bIsRxAggrSubframe) {
4629 rx_desc_819x_usb_aggr_subframe *desc = (rx_desc_819x_usb_aggr_subframe *)skb->data;
4630 stats->Length = desc->Length;
4631 stats->RxDrvInfoSize = desc->RxDrvInfoSize;
4632 stats->RxBufShift = 0; //RxBufShift = 2 in RxDesc, but usb didn't shift bytes in fact.
4633 stats->bICV = desc->ICV;
4634 stats->bCRC = desc->CRC32;
4635 stats->bHwError = stats->bCRC|stats->bICV;
4636 stats->Decrypted = !desc->SWDec;//RTL8190 set this bit to indicate that Hw does not decrypt packet
4637 } else
4638 #endif
4640 rx_desc_819x_usb *desc = (rx_desc_819x_usb *)skb->data;
4642 stats->Length = desc->Length;
4643 stats->RxDrvInfoSize = desc->RxDrvInfoSize;
4644 stats->RxBufShift = 0;
4645 stats->bICV = desc->ICV;
4646 stats->bCRC = desc->CRC32;
4647 stats->bHwError = stats->bCRC|stats->bICV;
4648 //RTL8190 set this bit to indicate that Hw does not decrypt packet
4649 stats->Decrypted = !desc->SWDec;
4652 if ((priv->ieee80211->pHTInfo->bCurrentHTSupport == true) && (priv->ieee80211->pairwise_key_type == KEY_TYPE_CCMP))
4653 stats->bHwError = false;
4654 else
4655 stats->bHwError = stats->bCRC|stats->bICV;
4657 if (stats->Length < 24 || stats->Length > MAX_8192U_RX_SIZE)
4658 stats->bHwError |= 1;
4660 //Get Driver Info
4662 // TODO: Need to verify it on FGPA platform
4663 //Driver info are written to the RxBuffer following rx desc
4664 if (stats->RxDrvInfoSize != 0) {
4665 driver_info = (rx_drvinfo_819x_usb *)(skb->data + sizeof(rx_desc_819x_usb) +
4666 stats->RxBufShift);
4667 /* unit: 0.5M */
4668 /* TODO */
4669 if (!stats->bHwError) {
4670 u8 ret_rate;
4671 ret_rate = HwRateToMRate90(driver_info->RxHT, driver_info->RxRate);
4672 if (ret_rate == 0xff) {
4673 // Abnormal Case: Receive CRC OK packet with Rx descriptor indicating non supported rate.
4674 // Special Error Handling here, 2008.05.16, by Emily
4676 stats->bHwError = 1;
4677 stats->rate = MGN_1M; //Set 1M rate by default
4678 } else {
4679 stats->rate = ret_rate;
4681 } else {
4682 stats->rate = 0x02;
4685 stats->bShortPreamble = driver_info->SPLCP;
4688 UpdateReceivedRateHistogramStatistics8190(dev, stats);
4690 stats->bIsAMPDU = (driver_info->PartAggr == 1);
4691 stats->bFirstMPDU = (driver_info->PartAggr == 1) && (driver_info->FirstAGGR == 1);
4692 stats->TimeStampLow = driver_info->TSFL;
4693 // xiong mask it, 070514
4695 UpdateRxPktTimeStamp8190(dev, stats);
4698 // Rx A-MPDU
4700 if (driver_info->FirstAGGR == 1 || driver_info->PartAggr == 1)
4701 RT_TRACE(COMP_RXDESC, "driver_info->FirstAGGR = %d, driver_info->PartAggr = %d\n",
4702 driver_info->FirstAGGR, driver_info->PartAggr);
4706 skb_pull(skb, sizeof(rx_desc_819x_usb));
4708 // Get Total offset of MPDU Frame Body
4710 if ((stats->RxBufShift + stats->RxDrvInfoSize) > 0) {
4711 stats->bShift = 1;
4712 skb_pull(skb, stats->RxBufShift + stats->RxDrvInfoSize);
4715 #ifdef USB_RX_AGGREGATION_SUPPORT
4716 /* for the rx aggregated sub frame, the redundant space truly contained in the packet */
4717 if (bIsRxAggrSubframe)
4718 skb_pull(skb, 8);
4719 #endif
4720 /* for debug 2008.5.29 */
4722 //added by vivi, for MP, 20080108
4723 stats->RxIs40MHzPacket = driver_info->BW;
4724 if (stats->RxDrvInfoSize != 0)
4725 TranslateRxSignalStuff819xUsb(skb, stats, driver_info);
4729 u32 GetRxPacketShiftBytes819xUsb(struct ieee80211_rx_stats *Status, bool bIsRxAggrSubframe)
4731 #ifdef USB_RX_AGGREGATION_SUPPORT
4732 if (bIsRxAggrSubframe)
4733 return (sizeof(rx_desc_819x_usb) + Status->RxDrvInfoSize
4734 + Status->RxBufShift + 8);
4735 else
4736 #endif
4737 return (sizeof(rx_desc_819x_usb) + Status->RxDrvInfoSize
4738 + Status->RxBufShift);
4741 void rtl8192_rx_nomal(struct sk_buff *skb)
4743 rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
4744 struct net_device *dev = info->dev;
4745 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
4746 struct ieee80211_rx_stats stats = {
4747 .signal = 0,
4748 .noise = -98,
4749 .rate = 0,
4750 .freq = IEEE80211_24GHZ_BAND,
4752 u32 rx_pkt_len = 0;
4753 struct ieee80211_hdr_1addr *ieee80211_hdr = NULL;
4754 bool unicast_packet = false;
4755 #ifdef USB_RX_AGGREGATION_SUPPORT
4756 struct sk_buff *agg_skb = NULL;
4757 u32 TotalLength = 0;
4758 u32 TempDWord = 0;
4759 u32 PacketLength = 0;
4760 u32 PacketOccupiedLendth = 0;
4761 u8 TempByte = 0;
4762 u32 PacketShiftBytes = 0;
4763 rx_desc_819x_usb_aggr_subframe *RxDescr = NULL;
4764 u8 PaddingBytes = 0;
4765 //add just for testing
4766 u8 testing;
4768 #endif
4770 /* 20 is for ps-poll */
4771 if ((skb->len >= (20 + sizeof(rx_desc_819x_usb))) && (skb->len < RX_URB_SIZE)) {
4772 #ifdef USB_RX_AGGREGATION_SUPPORT
4773 TempByte = *(skb->data + sizeof(rx_desc_819x_usb));
4774 #endif
4775 /* first packet should not contain Rx aggregation header */
4776 query_rxdesc_status(skb, &stats, false);
4777 /* TODO */
4778 /* hardware related info */
4779 #ifdef USB_RX_AGGREGATION_SUPPORT
4780 if (TempByte & BIT0) {
4781 agg_skb = skb;
4782 TotalLength = stats.Length - 4; /*sCrcLng*/
4783 /* though the head pointer has passed this position */
4784 TempDWord = *(u32 *)(agg_skb->data - 4);
4785 PacketLength = (u16)(TempDWord & 0x3FFF); /*sCrcLng*/
4786 skb = dev_alloc_skb(PacketLength);
4787 memcpy(skb_put(skb, PacketLength), agg_skb->data, PacketLength);
4788 PacketShiftBytes = GetRxPacketShiftBytes819xUsb(&stats, false);
4790 #endif
4791 /* Process the MPDU received */
4792 skb_trim(skb, skb->len - 4/*sCrcLng*/);
4794 rx_pkt_len = skb->len;
4795 ieee80211_hdr = (struct ieee80211_hdr_1addr *)skb->data;
4796 unicast_packet = false;
4797 if (is_broadcast_ether_addr(ieee80211_hdr->addr1)) {
4798 //TODO
4799 } else if (is_multicast_ether_addr(ieee80211_hdr->addr1)) {
4800 //TODO
4801 } else {
4802 /* unicast packet */
4803 unicast_packet = true;
4806 if (!ieee80211_rx(priv->ieee80211, skb, &stats)) {
4807 dev_kfree_skb_any(skb);
4808 } else {
4809 priv->stats.rxoktotal++;
4810 if (unicast_packet)
4811 priv->stats.rxbytesunicast += rx_pkt_len;
4813 #ifdef USB_RX_AGGREGATION_SUPPORT
4814 testing = 1;
4815 if (TotalLength > 0) {
4816 PacketOccupiedLendth = PacketLength + (PacketShiftBytes + 8);
4817 if ((PacketOccupiedLendth & 0xFF) != 0)
4818 PacketOccupiedLendth = (PacketOccupiedLendth & 0xFFFFFF00) + 256;
4819 PacketOccupiedLendth -= 8;
4820 TempDWord = PacketOccupiedLendth - PacketShiftBytes; /*- PacketLength */
4821 if (agg_skb->len > TempDWord)
4822 skb_pull(agg_skb, TempDWord);
4823 else
4824 agg_skb->len = 0;
4826 while (agg_skb->len >= GetRxPacketShiftBytes819xUsb(&stats, true)) {
4827 u8 tmpCRC = 0, tmpICV = 0;
4828 RxDescr = (rx_desc_819x_usb_aggr_subframe *)(agg_skb->data);
4829 tmpCRC = RxDescr->CRC32;
4830 tmpICV = RxDescr->ICV;
4831 memcpy(agg_skb->data, &agg_skb->data[44], 2);
4832 RxDescr->CRC32 = tmpCRC;
4833 RxDescr->ICV = tmpICV;
4835 memset(&stats, 0, sizeof(struct ieee80211_rx_stats));
4836 stats.signal = 0;
4837 stats.noise = -98;
4838 stats.rate = 0;
4839 stats.freq = IEEE80211_24GHZ_BAND;
4840 query_rxdesc_status(agg_skb, &stats, true);
4841 PacketLength = stats.Length;
4843 if (PacketLength > agg_skb->len)
4844 break;
4845 /* Process the MPDU received */
4846 skb = dev_alloc_skb(PacketLength);
4847 memcpy(skb_put(skb, PacketLength), agg_skb->data, PacketLength);
4848 skb_trim(skb, skb->len - 4/*sCrcLng*/);
4850 rx_pkt_len = skb->len;
4851 ieee80211_hdr = (struct ieee80211_hdr_1addr *)skb->data;
4852 unicast_packet = false;
4853 if (is_broadcast_ether_addr(ieee80211_hdr->addr1)) {
4854 //TODO
4855 } else if (is_multicast_ether_addr(ieee80211_hdr->addr1)) {
4856 //TODO
4857 } else {
4858 /* unicast packet */
4859 unicast_packet = true;
4861 if (!ieee80211_rx(priv->ieee80211, skb, &stats)) {
4862 dev_kfree_skb_any(skb);
4863 } else {
4864 priv->stats.rxoktotal++;
4865 if (unicast_packet)
4866 priv->stats.rxbytesunicast += rx_pkt_len;
4868 /* should trim the packet which has been copied to target skb */
4869 skb_pull(agg_skb, PacketLength);
4870 PacketShiftBytes = GetRxPacketShiftBytes819xUsb(&stats, true);
4871 PacketOccupiedLendth = PacketLength + PacketShiftBytes;
4872 if ((PacketOccupiedLendth & 0xFF) != 0) {
4873 PaddingBytes = 256 - (PacketOccupiedLendth & 0xFF);
4874 if (agg_skb->len > PaddingBytes)
4875 skb_pull(agg_skb, PaddingBytes);
4876 else
4877 agg_skb->len = 0;
4880 dev_kfree_skb(agg_skb);
4882 #endif
4883 } else {
4884 priv->stats.rxurberr++;
4885 netdev_dbg(dev, "actual_length: %d\n", skb->len);
4886 dev_kfree_skb_any(skb);
4891 void rtl819xusb_process_received_packet(struct net_device *dev,
4892 struct ieee80211_rx_stats *pstats)
4894 u8 *frame;
4895 u16 frame_len = 0;
4896 struct r8192_priv *priv = ieee80211_priv(dev);
4898 // Get shifted bytes of Starting address of 802.11 header. 2006.09.28, by Emily
4899 //porting by amy 080508
4900 pstats->virtual_address += get_rxpacket_shiftbytes_819xusb(pstats);
4901 frame = pstats->virtual_address;
4902 frame_len = pstats->packetlength;
4903 #ifdef TODO // by amy about HCT
4904 if (!Adapter->bInHctTest)
4905 CountRxErrStatistics(Adapter, pRfd);
4906 #endif
4907 #ifdef ENABLE_PS //by amy for adding ps function in future
4908 RT_RF_POWER_STATE rtState;
4909 // When RF is off, we should not count the packet for hw/sw synchronize
4910 // reason, ie. there may be a duration while sw switch is changed and hw
4911 // switch is being changed. 2006.12.04, by shien chang.
4912 Adapter->HalFunc.GetHwRegHandler(Adapter, HW_VAR_RF_STATE, (u8 *)(&rtState));
4913 if (rtState == eRfOff)
4914 return;
4915 #endif
4916 priv->stats.rxframgment++;
4918 #ifdef TODO
4919 RmMonitorSignalStrength(Adapter, pRfd);
4920 #endif
4921 /* 2007/01/16 MH Add RX command packet handle here. */
4922 /* 2007/03/01 MH We have to release RFD and return if rx pkt is cmd pkt. */
4923 if (rtl819xusb_rx_command_packet(dev, pstats))
4924 return;
4926 #ifdef SW_CRC_CHECK
4927 SwCrcCheck();
4928 #endif
4933 void query_rx_cmdpkt_desc_status(struct sk_buff *skb, struct ieee80211_rx_stats *stats)
4935 rx_desc_819x_usb *desc = (rx_desc_819x_usb *)skb->data;
4938 //Get Rx Descriptor Information
4940 stats->virtual_address = (u8 *)skb->data;
4941 stats->Length = desc->Length;
4942 stats->RxDrvInfoSize = 0;
4943 stats->RxBufShift = 0;
4944 stats->packetlength = stats->Length-scrclng;
4945 stats->fraglength = stats->packetlength;
4946 stats->fragoffset = 0;
4947 stats->ntotalfrag = 1;
4951 void rtl8192_rx_cmd(struct sk_buff *skb)
4953 struct rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
4954 struct net_device *dev = info->dev;
4955 /* TODO */
4956 struct ieee80211_rx_stats stats = {
4957 .signal = 0,
4958 .noise = -98,
4959 .rate = 0,
4960 .freq = IEEE80211_24GHZ_BAND,
4963 if ((skb->len >= (20 + sizeof(rx_desc_819x_usb))) && (skb->len < RX_URB_SIZE)) {
4965 query_rx_cmdpkt_desc_status(skb, &stats);
4966 // this is to be done by amy 080508 prfd->queue_id = 1;
4970 // Process the command packet received.
4973 rtl819xusb_process_received_packet(dev, &stats);
4975 dev_kfree_skb_any(skb);
4979 void rtl8192_irq_rx_tasklet(struct r8192_priv *priv)
4981 struct sk_buff *skb;
4982 struct rtl8192_rx_info *info;
4984 while (NULL != (skb = skb_dequeue(&priv->skb_queue))) {
4985 info = (struct rtl8192_rx_info *)skb->cb;
4986 switch (info->out_pipe) {
4987 /* Nomal packet pipe */
4988 case 3:
4989 priv->IrpPendingCount--;
4990 rtl8192_rx_nomal(skb);
4991 break;
4993 /* Command packet pipe */
4994 case 9:
4995 RT_TRACE(COMP_RECV, "command in-pipe index(%d)\n",
4996 info->out_pipe);
4998 rtl8192_rx_cmd(skb);
4999 break;
5001 default: /* should never get here! */
5002 RT_TRACE(COMP_ERR, "Unknown in-pipe index(%d)\n",
5003 info->out_pipe);
5004 dev_kfree_skb(skb);
5005 break;
5011 static const struct net_device_ops rtl8192_netdev_ops = {
5012 .ndo_open = rtl8192_open,
5013 .ndo_stop = rtl8192_close,
5014 .ndo_get_stats = rtl8192_stats,
5015 .ndo_tx_timeout = tx_timeout,
5016 .ndo_do_ioctl = rtl8192_ioctl,
5017 .ndo_set_rx_mode = r8192_set_multicast,
5018 .ndo_set_mac_address = r8192_set_mac_adr,
5019 .ndo_validate_addr = eth_validate_addr,
5020 .ndo_change_mtu = eth_change_mtu,
5021 .ndo_start_xmit = ieee80211_xmit,
5025 /****************************************************************************
5026 ---------------------------- USB_STUFF---------------------------
5027 *****************************************************************************/
5029 static int rtl8192_usb_probe(struct usb_interface *intf,
5030 const struct usb_device_id *id)
5032 struct net_device *dev = NULL;
5033 struct r8192_priv *priv = NULL;
5034 struct usb_device *udev = interface_to_usbdev(intf);
5035 int ret;
5036 RT_TRACE(COMP_INIT, "Oops: i'm coming\n");
5038 dev = alloc_ieee80211(sizeof(struct r8192_priv));
5039 if (dev == NULL)
5040 return -ENOMEM;
5042 usb_set_intfdata(intf, dev);
5043 SET_NETDEV_DEV(dev, &intf->dev);
5044 priv = ieee80211_priv(dev);
5045 priv->ieee80211 = netdev_priv(dev);
5046 priv->udev = udev;
5048 dev->netdev_ops = &rtl8192_netdev_ops;
5050 #if WIRELESS_EXT >= 12
5051 #if WIRELESS_EXT < 17
5052 dev->get_wireless_stats = r8192_get_wireless_stats;
5053 #endif
5054 dev->wireless_handlers = (struct iw_handler_def *) &r8192_wx_handlers_def;
5055 #endif
5056 dev->type = ARPHRD_ETHER;
5058 dev->watchdog_timeo = HZ*3; //modified by john, 0805
5060 if (dev_alloc_name(dev, ifname) < 0) {
5061 RT_TRACE(COMP_INIT, "Oops: devname already taken! Trying wlan%%d...\n");
5062 ifname = "wlan%d";
5063 dev_alloc_name(dev, ifname);
5066 RT_TRACE(COMP_INIT, "Driver probe completed1\n");
5067 if (rtl8192_init(dev) != 0) {
5068 RT_TRACE(COMP_ERR, "Initialization failed");
5069 ret = -ENODEV;
5070 goto fail;
5072 netif_carrier_off(dev);
5073 netif_stop_queue(dev);
5075 ret = register_netdev(dev);
5076 if (ret)
5077 goto fail2;
5079 RT_TRACE(COMP_INIT, "dev name=======> %s\n", dev->name);
5080 rtl8192_proc_init_one(dev);
5083 RT_TRACE(COMP_INIT, "Driver probe completed\n");
5084 return 0;
5086 fail2:
5087 rtl8192_down(dev);
5088 kfree(priv->pFirmware);
5089 priv->pFirmware = NULL;
5090 rtl8192_usb_deleteendpoints(dev);
5091 destroy_workqueue(priv->priv_wq);
5092 mdelay(10);
5093 fail:
5094 free_ieee80211(dev);
5096 RT_TRACE(COMP_ERR, "wlan driver load failed\n");
5097 return ret;
5100 //detach all the work and timer structure declared or inititialize in r8192U_init function.
5101 void rtl8192_cancel_deferred_work(struct r8192_priv *priv)
5104 cancel_work_sync(&priv->reset_wq);
5105 cancel_delayed_work(&priv->watch_dog_wq);
5106 cancel_delayed_work(&priv->update_beacon_wq);
5107 cancel_work_sync(&priv->qos_activate);
5111 static void rtl8192_usb_disconnect(struct usb_interface *intf)
5113 struct net_device *dev = usb_get_intfdata(intf);
5115 struct r8192_priv *priv = ieee80211_priv(dev);
5116 if (dev) {
5118 unregister_netdev(dev);
5120 RT_TRACE(COMP_DOWN, "=============>wlan driver to be removed\n");
5121 rtl8192_proc_remove_one(dev);
5123 rtl8192_down(dev);
5124 kfree(priv->pFirmware);
5125 priv->pFirmware = NULL;
5126 rtl8192_usb_deleteendpoints(dev);
5127 destroy_workqueue(priv->priv_wq);
5128 mdelay(10);
5131 free_ieee80211(dev);
5132 RT_TRACE(COMP_DOWN, "wlan driver removed\n");
5135 /* fun with the built-in ieee80211 stack... */
5136 extern int ieee80211_debug_init(void);
5137 extern void ieee80211_debug_exit(void);
5138 extern int ieee80211_crypto_init(void);
5139 extern void ieee80211_crypto_deinit(void);
5140 extern int ieee80211_crypto_tkip_init(void);
5141 extern void ieee80211_crypto_tkip_exit(void);
5142 extern int ieee80211_crypto_ccmp_init(void);
5143 extern void ieee80211_crypto_ccmp_exit(void);
5144 extern int ieee80211_crypto_wep_init(void);
5145 extern void ieee80211_crypto_wep_exit(void);
5147 static int __init rtl8192_usb_module_init(void)
5149 int ret;
5151 #ifdef CONFIG_IEEE80211_DEBUG
5152 ret = ieee80211_debug_init();
5153 if (ret) {
5154 pr_err("ieee80211_debug_init() failed %d\n", ret);
5155 return ret;
5157 #endif
5158 ret = ieee80211_crypto_init();
5159 if (ret) {
5160 pr_err("ieee80211_crypto_init() failed %d\n", ret);
5161 return ret;
5164 ret = ieee80211_crypto_tkip_init();
5165 if (ret) {
5166 pr_err("ieee80211_crypto_tkip_init() failed %d\n", ret);
5167 return ret;
5170 ret = ieee80211_crypto_ccmp_init();
5171 if (ret) {
5172 pr_err("ieee80211_crypto_ccmp_init() failed %d\n", ret);
5173 return ret;
5176 ret = ieee80211_crypto_wep_init();
5177 if (ret) {
5178 pr_err("ieee80211_crypto_wep_init() failed %d\n", ret);
5179 return ret;
5182 pr_info("\nLinux kernel driver for RTL8192 based WLAN cards\n");
5183 pr_info("Copyright (c) 2007-2008, Realsil Wlan\n");
5184 RT_TRACE(COMP_INIT, "Initializing module");
5185 RT_TRACE(COMP_INIT, "Wireless extensions version %d", WIRELESS_EXT);
5186 rtl8192_proc_module_init();
5187 return usb_register(&rtl8192_usb_driver);
5191 static void __exit rtl8192_usb_module_exit(void)
5193 usb_deregister(&rtl8192_usb_driver);
5195 RT_TRACE(COMP_DOWN, "Exiting");
5199 void rtl8192_try_wake_queue(struct net_device *dev, int pri)
5201 unsigned long flags;
5202 short enough_desc;
5203 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
5205 spin_lock_irqsave(&priv->tx_lock, flags);
5206 enough_desc = check_nic_enough_desc(dev, pri);
5207 spin_unlock_irqrestore(&priv->tx_lock, flags);
5209 if (enough_desc)
5210 ieee80211_wake_queue(priv->ieee80211);
5213 void EnableHWSecurityConfig8192(struct net_device *dev)
5215 u8 SECR_value = 0x0;
5216 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
5217 struct ieee80211_device *ieee = priv->ieee80211;
5218 SECR_value = SCR_TxEncEnable | SCR_RxDecEnable;
5219 if (((KEY_TYPE_WEP40 == ieee->pairwise_key_type) || (KEY_TYPE_WEP104 == ieee->pairwise_key_type)) && (priv->ieee80211->auth_mode != 2)) {
5220 SECR_value |= SCR_RxUseDK;
5221 SECR_value |= SCR_TxUseDK;
5222 } else if ((ieee->iw_mode == IW_MODE_ADHOC) && (ieee->pairwise_key_type & (KEY_TYPE_CCMP | KEY_TYPE_TKIP))) {
5223 SECR_value |= SCR_RxUseDK;
5224 SECR_value |= SCR_TxUseDK;
5226 //add HWSec active enable here.
5227 //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
5229 ieee->hwsec_active = 1;
5231 if ((ieee->pHTInfo->IOTAction&HT_IOT_ACT_PURE_N_MODE) || !hwwep) { //add hwsec_support flag to totol control hw_sec on/off
5232 ieee->hwsec_active = 0;
5233 SECR_value &= ~SCR_RxDecEnable;
5235 RT_TRACE(COMP_SEC, "%s:, hwsec:%d, pairwise_key:%d, SECR_value:%x\n", __func__,
5236 ieee->hwsec_active, ieee->pairwise_key_type, SECR_value);
5237 write_nic_byte(dev, SECR, SECR_value);
5241 void setKey(struct net_device *dev, u8 EntryNo, u8 KeyIndex, u16 KeyType,
5242 u8 *MacAddr, u8 DefaultKey, u32 *KeyContent)
5244 u32 TargetCommand = 0;
5245 u32 TargetContent = 0;
5246 u16 usConfig = 0;
5247 u8 i;
5248 if (EntryNo >= TOTAL_CAM_ENTRY)
5249 RT_TRACE(COMP_ERR, "cam entry exceeds in setKey()\n");
5251 RT_TRACE(COMP_SEC, "====>to setKey(), dev:%p, EntryNo:%d, KeyIndex:%d, KeyType:%d, MacAddr%pM\n", dev, EntryNo, KeyIndex, KeyType, MacAddr);
5253 if (DefaultKey)
5254 usConfig |= BIT15 | (KeyType<<2);
5255 else
5256 usConfig |= BIT15 | (KeyType<<2) | KeyIndex;
5259 for (i = 0; i < CAM_CONTENT_COUNT; i++) {
5260 TargetCommand = i+CAM_CONTENT_COUNT*EntryNo;
5261 TargetCommand |= BIT31|BIT16;
5263 if (i == 0) { //MAC|Config
5264 TargetContent = (u32)(*(MacAddr+0)) << 16|
5265 (u32)(*(MacAddr+1)) << 24|
5266 (u32)usConfig;
5268 write_nic_dword(dev, WCAMI, TargetContent);
5269 write_nic_dword(dev, RWCAM, TargetCommand);
5270 } else if (i == 1) { //MAC
5271 TargetContent = (u32)(*(MacAddr+2)) |
5272 (u32)(*(MacAddr+3)) << 8|
5273 (u32)(*(MacAddr+4)) << 16|
5274 (u32)(*(MacAddr+5)) << 24;
5275 write_nic_dword(dev, WCAMI, TargetContent);
5276 write_nic_dword(dev, RWCAM, TargetCommand);
5277 } else {
5278 //Key Material
5279 if (KeyContent != NULL) {
5280 write_nic_dword(dev, WCAMI, (u32)(*(KeyContent+i-2)));
5281 write_nic_dword(dev, RWCAM, TargetCommand);
5288 /***************************************************************************
5289 ------------------- module init / exit stubs ----------------
5290 ****************************************************************************/
5291 module_init(rtl8192_usb_module_init);
5292 module_exit(rtl8192_usb_module_exit);