Staging: rtl8192u: fix sparse warnings for static functions
[linux-2.6/btrfs-unstable.git] / drivers / staging / rtl8192u / r8192U_core.c
blob63a4cdf1dc048c601a8adeed251a7eca1b8ac801
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 <andrea.merello@gmail.com>, 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 static 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 static 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 static 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 static 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 static 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 static 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 usb_fill_bulk_urb(tx_urb, priv->udev, usb_sndbulkpipe(priv->udev, idx_pipe),
1613 skb->data, skb->len, rtl8192_tx_isr, skb);
1615 status = usb_submit_urb(tx_urb, GFP_ATOMIC);
1617 if (!status) {
1618 return 0;
1619 } else {
1620 DMESGE("Error TX CMD URB, error %d", status);
1621 return -1;
1626 * Mapping Software/Hardware descriptor queue id to "Queue Select Field"
1627 * in TxFwInfo data structure
1628 * 2006.10.30 by Emily
1630 * \param QUEUEID Software Queue
1632 static u8 MapHwQueueToFirmwareQueue(u8 QueueID)
1634 u8 QueueSelect = 0x0; //defualt set to
1636 switch (QueueID) {
1637 case BE_QUEUE:
1638 QueueSelect = QSLT_BE;
1639 break;
1641 case BK_QUEUE:
1642 QueueSelect = QSLT_BK;
1643 break;
1645 case VO_QUEUE:
1646 QueueSelect = QSLT_VO;
1647 break;
1649 case VI_QUEUE:
1650 QueueSelect = QSLT_VI;
1651 break;
1652 case MGNT_QUEUE:
1653 QueueSelect = QSLT_MGNT;
1654 break;
1656 case BEACON_QUEUE:
1657 QueueSelect = QSLT_BEACON;
1658 break;
1660 // TODO: 2006.10.30 mark other queue selection until we verify it is OK
1661 // TODO: Remove Assertions
1662 case TXCMD_QUEUE:
1663 QueueSelect = QSLT_CMD;
1664 break;
1665 case HIGH_QUEUE:
1666 QueueSelect = QSLT_HIGH;
1667 break;
1669 default:
1670 RT_TRACE(COMP_ERR, "TransmitTCB(): Impossible Queue Selection: %d \n", QueueID);
1671 break;
1673 return QueueSelect;
1676 u8 MRateToHwRate8190Pci(u8 rate)
1678 u8 ret = DESC90_RATE1M;
1680 switch (rate) {
1681 case MGN_1M: ret = DESC90_RATE1M; break;
1682 case MGN_2M: ret = DESC90_RATE2M; break;
1683 case MGN_5_5M: ret = DESC90_RATE5_5M; break;
1684 case MGN_11M: ret = DESC90_RATE11M; break;
1685 case MGN_6M: ret = DESC90_RATE6M; break;
1686 case MGN_9M: ret = DESC90_RATE9M; break;
1687 case MGN_12M: ret = DESC90_RATE12M; break;
1688 case MGN_18M: ret = DESC90_RATE18M; break;
1689 case MGN_24M: ret = DESC90_RATE24M; break;
1690 case MGN_36M: ret = DESC90_RATE36M; break;
1691 case MGN_48M: ret = DESC90_RATE48M; break;
1692 case MGN_54M: ret = DESC90_RATE54M; break;
1694 // HT rate since here
1695 case MGN_MCS0: ret = DESC90_RATEMCS0; break;
1696 case MGN_MCS1: ret = DESC90_RATEMCS1; break;
1697 case MGN_MCS2: ret = DESC90_RATEMCS2; break;
1698 case MGN_MCS3: ret = DESC90_RATEMCS3; break;
1699 case MGN_MCS4: ret = DESC90_RATEMCS4; break;
1700 case MGN_MCS5: ret = DESC90_RATEMCS5; break;
1701 case MGN_MCS6: ret = DESC90_RATEMCS6; break;
1702 case MGN_MCS7: ret = DESC90_RATEMCS7; break;
1703 case MGN_MCS8: ret = DESC90_RATEMCS8; break;
1704 case MGN_MCS9: ret = DESC90_RATEMCS9; break;
1705 case MGN_MCS10: ret = DESC90_RATEMCS10; break;
1706 case MGN_MCS11: ret = DESC90_RATEMCS11; break;
1707 case MGN_MCS12: ret = DESC90_RATEMCS12; break;
1708 case MGN_MCS13: ret = DESC90_RATEMCS13; break;
1709 case MGN_MCS14: ret = DESC90_RATEMCS14; break;
1710 case MGN_MCS15: ret = DESC90_RATEMCS15; break;
1711 case (0x80|0x20): ret = DESC90_RATEMCS32; break;
1713 default: break;
1715 return ret;
1719 static u8 QueryIsShort(u8 TxHT, u8 TxRate, cb_desc *tcb_desc)
1721 u8 tmp_Short;
1723 tmp_Short = (TxHT == 1) ? ((tcb_desc->bUseShortGI) ? 1 : 0) : ((tcb_desc->bUseShortPreamble) ? 1 : 0);
1725 if (TxHT == 1 && TxRate != DESC90_RATEMCS15)
1726 tmp_Short = 0;
1728 return tmp_Short;
1731 static void tx_zero_isr(struct urb *tx_urb)
1733 return;
1737 * The tx procedure is just as following,
1738 * skb->cb will contain all the following information,
1739 * priority, morefrag, rate, &dev.
1740 * */
1741 short rtl8192_tx(struct net_device *dev, struct sk_buff *skb)
1743 struct r8192_priv *priv = ieee80211_priv(dev);
1744 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1745 tx_desc_819x_usb *tx_desc = (tx_desc_819x_usb *)skb->data;
1746 tx_fwinfo_819x_usb *tx_fwinfo = (tx_fwinfo_819x_usb *)(skb->data + USB_HWDESC_HEADER_LEN);
1747 struct usb_device *udev = priv->udev;
1748 int pend;
1749 int status;
1750 struct urb *tx_urb = NULL, *tx_urb_zero = NULL;
1751 unsigned int idx_pipe;
1752 pend = atomic_read(&priv->tx_pending[tcb_desc->queue_index]);
1753 /* we are locked here so the two atomic_read and inc are executed
1754 * without interleaves
1755 * !!! For debug purpose
1757 if (pend > MAX_TX_URB) {
1758 netdev_dbg(dev, "To discard skb packet!\n");
1759 dev_kfree_skb_any(skb);
1760 return -1;
1763 tx_urb = usb_alloc_urb(0, GFP_ATOMIC);
1764 if (!tx_urb) {
1765 dev_kfree_skb_any(skb);
1766 return -ENOMEM;
1769 /* Fill Tx firmware info */
1770 memset(tx_fwinfo, 0, sizeof(tx_fwinfo_819x_usb));
1771 /* DWORD 0 */
1772 tx_fwinfo->TxHT = (tcb_desc->data_rate&0x80) ? 1 : 0;
1773 tx_fwinfo->TxRate = MRateToHwRate8190Pci(tcb_desc->data_rate);
1774 tx_fwinfo->EnableCPUDur = tcb_desc->bTxEnableFwCalcDur;
1775 tx_fwinfo->Short = QueryIsShort(tx_fwinfo->TxHT, tx_fwinfo->TxRate, tcb_desc);
1776 if (tcb_desc->bAMPDUEnable) {//AMPDU enabled
1777 tx_fwinfo->AllowAggregation = 1;
1778 /* DWORD 1 */
1779 tx_fwinfo->RxMF = tcb_desc->ampdu_factor;
1780 tx_fwinfo->RxAMD = tcb_desc->ampdu_density&0x07;//ampdudensity
1781 } else {
1782 tx_fwinfo->AllowAggregation = 0;
1783 /* DWORD 1 */
1784 tx_fwinfo->RxMF = 0;
1785 tx_fwinfo->RxAMD = 0;
1788 /* Protection mode related */
1789 tx_fwinfo->RtsEnable = (tcb_desc->bRTSEnable) ? 1 : 0;
1790 tx_fwinfo->CtsEnable = (tcb_desc->bCTSEnable) ? 1 : 0;
1791 tx_fwinfo->RtsSTBC = (tcb_desc->bRTSSTBC) ? 1 : 0;
1792 tx_fwinfo->RtsHT = (tcb_desc->rts_rate&0x80) ? 1 : 0;
1793 tx_fwinfo->RtsRate = MRateToHwRate8190Pci((u8)tcb_desc->rts_rate);
1794 tx_fwinfo->RtsSubcarrier = (tx_fwinfo->RtsHT == 0) ? (tcb_desc->RTSSC) : 0;
1795 tx_fwinfo->RtsBandwidth = (tx_fwinfo->RtsHT == 1) ? ((tcb_desc->bRTSBW) ? 1 : 0) : 0;
1796 tx_fwinfo->RtsShort = (tx_fwinfo->RtsHT == 0) ? (tcb_desc->bRTSUseShortPreamble ? 1 : 0) :
1797 (tcb_desc->bRTSUseShortGI ? 1 : 0);
1799 /* Set Bandwidth and sub-channel settings. */
1800 if (priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20_40) {
1801 if (tcb_desc->bPacketBW) {
1802 tx_fwinfo->TxBandwidth = 1;
1803 tx_fwinfo->TxSubCarrier = 0; //By SD3's Jerry suggestion, use duplicated mode
1804 } else {
1805 tx_fwinfo->TxBandwidth = 0;
1806 tx_fwinfo->TxSubCarrier = priv->nCur40MhzPrimeSC;
1808 } else {
1809 tx_fwinfo->TxBandwidth = 0;
1810 tx_fwinfo->TxSubCarrier = 0;
1813 #ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
1814 if (tcb_desc->drv_agg_enable)
1815 tx_fwinfo->Tx_INFO_RSVD = (tcb_desc->DrvAggrNum & 0x1f) << 1;
1816 #endif
1817 /* Fill Tx descriptor */
1818 memset(tx_desc, 0, sizeof(tx_desc_819x_usb));
1819 /* DWORD 0 */
1820 tx_desc->LINIP = 0;
1821 tx_desc->CmdInit = 1;
1822 tx_desc->Offset = sizeof(tx_fwinfo_819x_usb) + 8;
1824 #ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
1825 if (tcb_desc->drv_agg_enable)
1826 tx_desc->PktSize = tcb_desc->pkt_size;
1827 else
1828 #endif
1830 tx_desc->PktSize = (skb->len - TX_PACKET_SHIFT_BYTES) & 0xffff;
1833 /*DWORD 1*/
1834 tx_desc->SecCAMID = 0;
1835 tx_desc->RATid = tcb_desc->RATRIndex;
1836 tx_desc->NoEnc = 1;
1837 tx_desc->SecType = 0x0;
1838 if (tcb_desc->bHwSec) {
1839 switch (priv->ieee80211->pairwise_key_type) {
1840 case KEY_TYPE_WEP40:
1841 case KEY_TYPE_WEP104:
1842 tx_desc->SecType = 0x1;
1843 tx_desc->NoEnc = 0;
1844 break;
1845 case KEY_TYPE_TKIP:
1846 tx_desc->SecType = 0x2;
1847 tx_desc->NoEnc = 0;
1848 break;
1849 case KEY_TYPE_CCMP:
1850 tx_desc->SecType = 0x3;
1851 tx_desc->NoEnc = 0;
1852 break;
1853 case KEY_TYPE_NA:
1854 tx_desc->SecType = 0x0;
1855 tx_desc->NoEnc = 1;
1856 break;
1860 tx_desc->QueueSelect = MapHwQueueToFirmwareQueue(tcb_desc->queue_index);
1861 tx_desc->TxFWInfoSize = sizeof(tx_fwinfo_819x_usb);
1863 tx_desc->DISFB = tcb_desc->bTxDisableRateFallBack;
1864 tx_desc->USERATE = tcb_desc->bTxUseDriverAssingedRate;
1866 /* Fill fields that are required to be initialized in all of the descriptors */
1867 //DWORD 0
1868 tx_desc->FirstSeg = 1;
1869 tx_desc->LastSeg = 1;
1870 tx_desc->OWN = 1;
1872 #ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
1873 if (tcb_desc->drv_agg_enable) {
1874 tx_desc->TxBufferSize = tcb_desc->pkt_size + sizeof(tx_fwinfo_819x_usb);
1875 } else
1876 #endif
1878 //DWORD 2
1879 tx_desc->TxBufferSize = (u32)(skb->len - USB_HWDESC_HEADER_LEN);
1881 /* Get index to out pipe from specified QueueID */
1882 #ifndef USE_ONE_PIPE
1883 idx_pipe = txqueue2outpipe(priv, tcb_desc->queue_index);
1884 #else
1885 idx_pipe = 0x5;
1886 #endif
1888 /* To submit bulk urb */
1889 usb_fill_bulk_urb(tx_urb, udev,
1890 usb_sndbulkpipe(udev, idx_pipe), skb->data,
1891 skb->len, rtl8192_tx_isr, skb);
1893 status = usb_submit_urb(tx_urb, GFP_ATOMIC);
1894 if (!status) {
1895 //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
1896 bool bSend0Byte = false;
1897 u8 zero = 0;
1898 if (udev->speed == USB_SPEED_HIGH) {
1899 if (skb->len > 0 && skb->len % 512 == 0)
1900 bSend0Byte = true;
1901 } else {
1902 if (skb->len > 0 && skb->len % 64 == 0)
1903 bSend0Byte = true;
1905 if (bSend0Byte) {
1906 tx_urb_zero = usb_alloc_urb(0, GFP_ATOMIC);
1907 if (!tx_urb_zero) {
1908 RT_TRACE(COMP_ERR, "can't alloc urb for zero byte\n");
1909 return -ENOMEM;
1911 usb_fill_bulk_urb(tx_urb_zero, udev,
1912 usb_sndbulkpipe(udev, idx_pipe), &zero,
1913 0, tx_zero_isr, dev);
1914 status = usb_submit_urb(tx_urb_zero, GFP_ATOMIC);
1915 if (status) {
1916 RT_TRACE(COMP_ERR, "Error TX URB for zero byte %d, error %d", atomic_read(&priv->tx_pending[tcb_desc->queue_index]), status);
1917 return -1;
1920 dev->trans_start = jiffies;
1921 atomic_inc(&priv->tx_pending[tcb_desc->queue_index]);
1922 return 0;
1923 } else {
1924 RT_TRACE(COMP_ERR, "Error TX URB %d, error %d", atomic_read(&priv->tx_pending[tcb_desc->queue_index]),
1925 status);
1926 return -1;
1930 static short rtl8192_usb_initendpoints(struct net_device *dev)
1932 struct r8192_priv *priv = ieee80211_priv(dev);
1934 priv->rx_urb = kmalloc(sizeof(struct urb *) * (MAX_RX_URB+1),
1935 GFP_KERNEL);
1936 if (priv->rx_urb == NULL)
1937 return -ENOMEM;
1939 #ifndef JACKSON_NEW_RX
1940 for (i = 0; i < (MAX_RX_URB+1); i++) {
1942 priv->rx_urb[i] = usb_alloc_urb(0, GFP_KERNEL);
1944 priv->rx_urb[i]->transfer_buffer = kmalloc(RX_URB_SIZE, GFP_KERNEL);
1946 priv->rx_urb[i]->transfer_buffer_length = RX_URB_SIZE;
1948 #endif
1950 #ifdef THOMAS_BEACON
1952 long align = 0;
1953 void *oldaddr, *newaddr;
1955 priv->rx_urb[16] = usb_alloc_urb(0, GFP_KERNEL);
1956 priv->oldaddr = kmalloc(16, GFP_KERNEL);
1957 oldaddr = priv->oldaddr;
1958 align = ((long)oldaddr) & 3;
1959 if (align) {
1960 newaddr = oldaddr + 4 - align;
1961 priv->rx_urb[16]->transfer_buffer_length = 16 - 4 + align;
1962 } else {
1963 newaddr = oldaddr;
1964 priv->rx_urb[16]->transfer_buffer_length = 16;
1966 priv->rx_urb[16]->transfer_buffer = newaddr;
1968 #endif
1970 memset(priv->rx_urb, 0, sizeof(struct urb *) * MAX_RX_URB);
1971 priv->pp_rxskb = kcalloc(MAX_RX_URB, sizeof(struct sk_buff *),
1972 GFP_KERNEL);
1973 if (!priv->pp_rxskb) {
1974 kfree(priv->rx_urb);
1976 priv->pp_rxskb = NULL;
1977 priv->rx_urb = NULL;
1979 DMESGE("Endpoint Alloc Failure");
1980 return -ENOMEM;
1983 netdev_dbg(dev, "End of initendpoints\n");
1984 return 0;
1987 #ifdef THOMAS_BEACON
1988 static void rtl8192_usb_deleteendpoints(struct net_device *dev)
1990 int i;
1991 struct r8192_priv *priv = ieee80211_priv(dev);
1993 if (priv->rx_urb) {
1994 for (i = 0; i < (MAX_RX_URB+1); i++) {
1995 usb_kill_urb(priv->rx_urb[i]);
1996 usb_free_urb(priv->rx_urb[i]);
1998 kfree(priv->rx_urb);
1999 priv->rx_urb = NULL;
2001 kfree(priv->oldaddr);
2002 priv->oldaddr = NULL;
2003 if (priv->pp_rxskb) {
2004 kfree(priv->pp_rxskb);
2005 priv->pp_rxskb = NULL;
2008 #else
2009 void rtl8192_usb_deleteendpoints(struct net_device *dev)
2011 int i;
2012 struct r8192_priv *priv = ieee80211_priv(dev);
2014 #ifndef JACKSON_NEW_RX
2016 if (priv->rx_urb) {
2017 for (i = 0; i < (MAX_RX_URB+1); i++) {
2018 usb_kill_urb(priv->rx_urb[i]);
2019 kfree(priv->rx_urb[i]->transfer_buffer);
2020 usb_free_urb(priv->rx_urb[i]);
2022 kfree(priv->rx_urb);
2023 priv->rx_urb = NULL;
2026 #else
2027 kfree(priv->rx_urb);
2028 priv->rx_urb = NULL;
2029 kfree(priv->oldaddr);
2030 priv->oldaddr = NULL;
2031 if (priv->pp_rxskb) {
2032 kfree(priv->pp_rxskb);
2033 priv->pp_rxskb = 0;
2037 #endif
2039 #endif
2041 extern void rtl8192_update_ratr_table(struct net_device *dev);
2042 void rtl8192_link_change(struct net_device *dev)
2044 struct r8192_priv *priv = ieee80211_priv(dev);
2045 struct ieee80211_device *ieee = priv->ieee80211;
2046 if (ieee->state == IEEE80211_LINKED) {
2047 rtl8192_net_update(dev);
2048 rtl8192_update_ratr_table(dev);
2049 //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
2050 if ((KEY_TYPE_WEP40 == ieee->pairwise_key_type) || (KEY_TYPE_WEP104 == ieee->pairwise_key_type))
2051 EnableHWSecurityConfig8192(dev);
2053 /*update timing params*/
2054 if (ieee->iw_mode == IW_MODE_INFRA || ieee->iw_mode == IW_MODE_ADHOC) {
2055 u32 reg = 0;
2056 read_nic_dword(dev, RCR, &reg);
2057 if (priv->ieee80211->state == IEEE80211_LINKED)
2058 priv->ReceiveConfig = reg |= RCR_CBSSID;
2059 else
2060 priv->ReceiveConfig = reg &= ~RCR_CBSSID;
2061 write_nic_dword(dev, RCR, reg);
2065 static struct ieee80211_qos_parameters def_qos_parameters = {
2066 {3, 3, 3, 3},/* cw_min */
2067 {7, 7, 7, 7},/* cw_max */
2068 {2, 2, 2, 2},/* aifs */
2069 {0, 0, 0, 0},/* flags */
2070 {0, 0, 0, 0} /* tx_op_limit */
2074 void rtl8192_update_beacon(struct work_struct *work)
2076 struct r8192_priv *priv = container_of(work, struct r8192_priv, update_beacon_wq.work);
2077 struct net_device *dev = priv->ieee80211->dev;
2078 struct ieee80211_device *ieee = priv->ieee80211;
2079 struct ieee80211_network *net = &ieee->current_network;
2081 if (ieee->pHTInfo->bCurrentHTSupport)
2082 HTUpdateSelfAndPeerSetting(ieee, net);
2083 ieee->pHTInfo->bCurrentRT2RTLongSlotTime = net->bssht.bdRT2RTLongSlotTime;
2084 rtl8192_update_cap(dev, net->capability);
2087 * background support to run QoS activate functionality
2089 int WDCAPARA_ADD[] = {EDCAPARA_BE, EDCAPARA_BK, EDCAPARA_VI, EDCAPARA_VO};
2090 void rtl8192_qos_activate(struct work_struct *work)
2092 struct r8192_priv *priv = container_of(work, struct r8192_priv, qos_activate);
2093 struct net_device *dev = priv->ieee80211->dev;
2094 struct ieee80211_qos_parameters *qos_parameters = &priv->ieee80211->current_network.qos_data.parameters;
2095 u8 mode = priv->ieee80211->current_network.mode;
2096 u8 u1bAIFS;
2097 u32 u4bAcParam;
2098 int i;
2100 if (priv == NULL)
2101 return;
2103 mutex_lock(&priv->mutex);
2104 if (priv->ieee80211->state != IEEE80211_LINKED)
2105 goto success;
2106 RT_TRACE(COMP_QOS, "qos active process with associate response received\n");
2107 /* It better set slot time at first */
2108 /* For we just support b/g mode at present, let the slot time at 9/20 selection */
2109 /* update the ac parameter to related registers */
2110 for (i = 0; i < QOS_QUEUE_NUM; i++) {
2111 //Mode G/A: slotTimeTimer = 9; Mode B: 20
2112 u1bAIFS = qos_parameters->aifs[i] * ((mode&(IEEE_G|IEEE_N_24G)) ? 9 : 20) + aSifsTime;
2113 u4bAcParam = ((((u32)(qos_parameters->tx_op_limit[i]))<< AC_PARAM_TXOP_LIMIT_OFFSET)|
2114 (((u32)(qos_parameters->cw_max[i]))<< AC_PARAM_ECW_MAX_OFFSET)|
2115 (((u32)(qos_parameters->cw_min[i]))<< AC_PARAM_ECW_MIN_OFFSET)|
2116 ((u32)u1bAIFS << AC_PARAM_AIFS_OFFSET));
2118 write_nic_dword(dev, WDCAPARA_ADD[i], u4bAcParam);
2121 success:
2122 mutex_unlock(&priv->mutex);
2125 static int rtl8192_qos_handle_probe_response(struct r8192_priv *priv,
2126 int active_network,
2127 struct ieee80211_network *network)
2129 int ret = 0;
2130 u32 size = sizeof(struct ieee80211_qos_parameters);
2132 if (priv->ieee80211->state != IEEE80211_LINKED)
2133 return ret;
2135 if ((priv->ieee80211->iw_mode != IW_MODE_INFRA))
2136 return ret;
2138 if (network->flags & NETWORK_HAS_QOS_MASK) {
2139 if (active_network &&
2140 (network->flags & NETWORK_HAS_QOS_PARAMETERS))
2141 network->qos_data.active = network->qos_data.supported;
2143 if ((network->qos_data.active == 1) && (active_network == 1) &&
2144 (network->flags & NETWORK_HAS_QOS_PARAMETERS) &&
2145 (network->qos_data.old_param_count !=
2146 network->qos_data.param_count)) {
2147 network->qos_data.old_param_count =
2148 network->qos_data.param_count;
2149 queue_work(priv->priv_wq, &priv->qos_activate);
2150 RT_TRACE(COMP_QOS, "QoS parameters change call "
2151 "qos_activate\n");
2153 } else {
2154 memcpy(&priv->ieee80211->current_network.qos_data.parameters,
2155 &def_qos_parameters, size);
2157 if ((network->qos_data.active == 1) && (active_network == 1)) {
2158 queue_work(priv->priv_wq, &priv->qos_activate);
2159 RT_TRACE(COMP_QOS, "QoS was disabled call qos_activate \n");
2161 network->qos_data.active = 0;
2162 network->qos_data.supported = 0;
2165 return 0;
2168 /* handle and manage frame from beacon and probe response */
2169 static int rtl8192_handle_beacon(struct net_device *dev,
2170 struct ieee80211_beacon *beacon,
2171 struct ieee80211_network *network)
2173 struct r8192_priv *priv = ieee80211_priv(dev);
2175 rtl8192_qos_handle_probe_response(priv, 1, network);
2176 queue_delayed_work(priv->priv_wq, &priv->update_beacon_wq, 0);
2177 return 0;
2182 * handling the beaconing responses. if we get different QoS setting
2183 * off the network from the associated setting, adjust the QoS
2184 * setting
2186 static int rtl8192_qos_association_resp(struct r8192_priv *priv,
2187 struct ieee80211_network *network)
2189 int ret = 0;
2190 unsigned long flags;
2191 u32 size = sizeof(struct ieee80211_qos_parameters);
2192 int set_qos_param = 0;
2194 if ((priv == NULL) || (network == NULL))
2195 return ret;
2197 if (priv->ieee80211->state != IEEE80211_LINKED)
2198 return ret;
2200 if ((priv->ieee80211->iw_mode != IW_MODE_INFRA))
2201 return ret;
2203 spin_lock_irqsave(&priv->ieee80211->lock, flags);
2204 if (network->flags & NETWORK_HAS_QOS_PARAMETERS) {
2205 memcpy(&priv->ieee80211->current_network.qos_data.parameters,
2206 &network->qos_data.parameters,
2207 sizeof(struct ieee80211_qos_parameters));
2208 priv->ieee80211->current_network.qos_data.active = 1;
2209 set_qos_param = 1;
2210 /* update qos parameter for current network */
2211 priv->ieee80211->current_network.qos_data.old_param_count =
2212 priv->ieee80211->current_network.qos_data.param_count;
2213 priv->ieee80211->current_network.qos_data.param_count =
2214 network->qos_data.param_count;
2215 } else {
2216 memcpy(&priv->ieee80211->current_network.qos_data.parameters,
2217 &def_qos_parameters, size);
2218 priv->ieee80211->current_network.qos_data.active = 0;
2219 priv->ieee80211->current_network.qos_data.supported = 0;
2220 set_qos_param = 1;
2223 spin_unlock_irqrestore(&priv->ieee80211->lock, flags);
2225 RT_TRACE(COMP_QOS, "%s: network->flags = %d,%d\n", __func__, network->flags, priv->ieee80211->current_network.qos_data.active);
2226 if (set_qos_param == 1)
2227 queue_work(priv->priv_wq, &priv->qos_activate);
2230 return ret;
2234 static int rtl8192_handle_assoc_response(struct net_device *dev,
2235 struct ieee80211_assoc_response_frame *resp,
2236 struct ieee80211_network *network)
2238 struct r8192_priv *priv = ieee80211_priv(dev);
2239 rtl8192_qos_association_resp(priv, network);
2240 return 0;
2244 void rtl8192_update_ratr_table(struct net_device *dev)
2246 struct r8192_priv *priv = ieee80211_priv(dev);
2247 struct ieee80211_device *ieee = priv->ieee80211;
2248 u8 *pMcsRate = ieee->dot11HTOperationalRateSet;
2249 u32 ratr_value = 0;
2250 u8 rate_index = 0;
2251 rtl8192_config_rate(dev, (u16 *)(&ratr_value));
2252 ratr_value |= (*(u16 *)(pMcsRate)) << 12;
2253 switch (ieee->mode) {
2254 case IEEE_A:
2255 ratr_value &= 0x00000FF0;
2256 break;
2257 case IEEE_B:
2258 ratr_value &= 0x0000000F;
2259 break;
2260 case IEEE_G:
2261 ratr_value &= 0x00000FF7;
2262 break;
2263 case IEEE_N_24G:
2264 case IEEE_N_5G:
2265 if (ieee->pHTInfo->PeerMimoPs == 0) {//MIMO_PS_STATIC
2266 ratr_value &= 0x0007F007;
2267 } else {
2268 if (priv->rf_type == RF_1T2R)
2269 ratr_value &= 0x000FF007;
2270 else
2271 ratr_value &= 0x0F81F007;
2273 break;
2274 default:
2275 break;
2277 ratr_value &= 0x0FFFFFFF;
2278 if (ieee->pHTInfo->bCurTxBW40MHz && ieee->pHTInfo->bCurShortGI40MHz)
2279 ratr_value |= 0x80000000;
2280 else if (!ieee->pHTInfo->bCurTxBW40MHz && ieee->pHTInfo->bCurShortGI20MHz)
2281 ratr_value |= 0x80000000;
2282 write_nic_dword(dev, RATR0+rate_index*4, ratr_value);
2283 write_nic_byte(dev, UFWP, 1);
2286 static u8 ccmp_ie[4] = {0x00, 0x50, 0xf2, 0x04};
2287 static u8 ccmp_rsn_ie[4] = {0x00, 0x0f, 0xac, 0x04};
2288 static bool GetNmodeSupportBySecCfg8192(struct net_device *dev)
2290 struct r8192_priv *priv = ieee80211_priv(dev);
2291 struct ieee80211_device *ieee = priv->ieee80211;
2292 struct ieee80211_network *network = &ieee->current_network;
2293 int wpa_ie_len = ieee->wpa_ie_len;
2294 struct ieee80211_crypt_data *crypt;
2295 int encrypt;
2297 crypt = ieee->crypt[ieee->tx_keyidx];
2298 //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
2299 encrypt = (network->capability & WLAN_CAPABILITY_PRIVACY) || (ieee->host_encrypt && crypt && crypt->ops && (0 == strcmp(crypt->ops->name, "WEP")));
2301 /* simply judge */
2302 if (encrypt && (wpa_ie_len == 0)) {
2303 /* wep encryption, no N mode setting */
2304 return false;
2305 } else if ((wpa_ie_len != 0)) {
2306 /* parse pairwise key type */
2307 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))))
2308 return true;
2309 else
2310 return false;
2311 } else {
2312 return true;
2315 return true;
2318 bool GetHalfNmodeSupportByAPs819xUsb(struct net_device *dev)
2320 bool Reval;
2321 struct r8192_priv *priv = ieee80211_priv(dev);
2322 struct ieee80211_device *ieee = priv->ieee80211;
2324 if (ieee->bHalfWirelessN24GMode == true)
2325 Reval = true;
2326 else
2327 Reval = false;
2329 return Reval;
2332 void rtl8192_refresh_supportrate(struct r8192_priv *priv)
2334 struct ieee80211_device *ieee = priv->ieee80211;
2335 //we do not consider set support rate for ABG mode, only HT MCS rate is set here.
2336 if (ieee->mode == WIRELESS_MODE_N_24G || ieee->mode == WIRELESS_MODE_N_5G)
2337 memcpy(ieee->Regdot11HTOperationalRateSet, ieee->RegHTSuppRateSet, 16);
2338 else
2339 memset(ieee->Regdot11HTOperationalRateSet, 0, 16);
2340 return;
2343 u8 rtl8192_getSupportedWireleeMode(struct net_device *dev)
2345 struct r8192_priv *priv = ieee80211_priv(dev);
2346 u8 ret = 0;
2347 switch (priv->rf_chip) {
2348 case RF_8225:
2349 case RF_8256:
2350 case RF_PSEUDO_11N:
2351 ret = (WIRELESS_MODE_N_24G|WIRELESS_MODE_G|WIRELESS_MODE_B);
2352 break;
2353 case RF_8258:
2354 ret = (WIRELESS_MODE_A|WIRELESS_MODE_N_5G);
2355 break;
2356 default:
2357 ret = WIRELESS_MODE_B;
2358 break;
2360 return ret;
2362 void rtl8192_SetWirelessMode(struct net_device *dev, u8 wireless_mode)
2364 struct r8192_priv *priv = ieee80211_priv(dev);
2365 u8 bSupportMode = rtl8192_getSupportedWireleeMode(dev);
2367 if ((wireless_mode == WIRELESS_MODE_AUTO) || ((wireless_mode&bSupportMode) == 0)) {
2368 if (bSupportMode & WIRELESS_MODE_N_24G) {
2369 wireless_mode = WIRELESS_MODE_N_24G;
2370 } else if (bSupportMode & WIRELESS_MODE_N_5G) {
2371 wireless_mode = WIRELESS_MODE_N_5G;
2372 } else if ((bSupportMode & WIRELESS_MODE_A)) {
2373 wireless_mode = WIRELESS_MODE_A;
2374 } else if ((bSupportMode & WIRELESS_MODE_G)) {
2375 wireless_mode = WIRELESS_MODE_G;
2376 } else if ((bSupportMode & WIRELESS_MODE_B)) {
2377 wireless_mode = WIRELESS_MODE_B;
2378 } else {
2379 RT_TRACE(COMP_ERR, "%s(), No valid wireless mode supported, SupportedWirelessMode(%x)!!!\n", __func__, bSupportMode);
2380 wireless_mode = WIRELESS_MODE_B;
2383 #ifdef TO_DO_LIST //// TODO: this function doesn't work well at this time, we should wait for FPGA
2384 ActUpdateChannelAccessSetting(pAdapter, pHalData->CurrentWirelessMode, &pAdapter->MgntInfo.Info8185.ChannelAccessSetting);
2385 #endif
2386 priv->ieee80211->mode = wireless_mode;
2388 if ((wireless_mode == WIRELESS_MODE_N_24G) || (wireless_mode == WIRELESS_MODE_N_5G))
2389 priv->ieee80211->pHTInfo->bEnableHT = 1;
2390 else
2391 priv->ieee80211->pHTInfo->bEnableHT = 0;
2392 RT_TRACE(COMP_INIT, "Current Wireless Mode is %x\n", wireless_mode);
2393 rtl8192_refresh_supportrate(priv);
2396 //init priv variables here. only non_zero value should be initialized here.
2397 static void rtl8192_init_priv_variable(struct net_device *dev)
2399 struct r8192_priv *priv = ieee80211_priv(dev);
2400 u8 i;
2401 priv->card_8192 = NIC_8192U;
2402 priv->chan = 1; //set to channel 1
2403 priv->ieee80211->mode = WIRELESS_MODE_AUTO; //SET AUTO
2404 priv->ieee80211->iw_mode = IW_MODE_INFRA;
2405 priv->ieee80211->ieee_up = 0;
2406 priv->retry_rts = DEFAULT_RETRY_RTS;
2407 priv->retry_data = DEFAULT_RETRY_DATA;
2408 priv->ieee80211->rts = DEFAULT_RTS_THRESHOLD;
2409 priv->ieee80211->rate = 110; //11 mbps
2410 priv->ieee80211->short_slot = 1;
2411 priv->promisc = (dev->flags & IFF_PROMISC) ? 1 : 0;
2412 priv->CckPwEnl = 6;
2413 //for silent reset
2414 priv->IrpPendingCount = 1;
2415 priv->ResetProgress = RESET_TYPE_NORESET;
2416 priv->bForcedSilentReset = 0;
2417 priv->bDisableNormalResetCheck = false;
2418 priv->force_reset = false;
2420 priv->ieee80211->FwRWRF = 0; //we don't use FW read/write RF until stable firmware is available.
2421 priv->ieee80211->current_network.beacon_interval = DEFAULT_BEACONINTERVAL;
2422 priv->ieee80211->iw_mode = IW_MODE_INFRA;
2423 priv->ieee80211->softmac_features = IEEE_SOFTMAC_SCAN |
2424 IEEE_SOFTMAC_ASSOCIATE | IEEE_SOFTMAC_PROBERQ |
2425 IEEE_SOFTMAC_PROBERS | IEEE_SOFTMAC_TX_QUEUE |
2426 IEEE_SOFTMAC_BEACONS;//added by amy 080604
2428 priv->ieee80211->active_scan = 1;
2429 priv->ieee80211->modulation = IEEE80211_CCK_MODULATION | IEEE80211_OFDM_MODULATION;
2430 priv->ieee80211->host_encrypt = 1;
2431 priv->ieee80211->host_decrypt = 1;
2432 priv->ieee80211->start_send_beacons = NULL; //-by amy 080604
2433 priv->ieee80211->stop_send_beacons = NULL; //-by amy 080604
2434 priv->ieee80211->softmac_hard_start_xmit = rtl8192_hard_start_xmit;
2435 priv->ieee80211->set_chan = rtl8192_set_chan;
2436 priv->ieee80211->link_change = rtl8192_link_change;
2437 priv->ieee80211->softmac_data_hard_start_xmit = rtl8192_hard_data_xmit;
2438 priv->ieee80211->data_hard_stop = rtl8192_data_hard_stop;
2439 priv->ieee80211->data_hard_resume = rtl8192_data_hard_resume;
2440 priv->ieee80211->init_wmmparam_flag = 0;
2441 priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD;
2442 priv->ieee80211->check_nic_enough_desc = check_nic_enough_desc;
2443 priv->ieee80211->tx_headroom = TX_PACKET_SHIFT_BYTES;
2444 priv->ieee80211->qos_support = 1;
2446 //added by WB
2447 priv->ieee80211->SetBWModeHandler = rtl8192_SetBWMode;
2448 priv->ieee80211->handle_assoc_response = rtl8192_handle_assoc_response;
2449 priv->ieee80211->handle_beacon = rtl8192_handle_beacon;
2450 //added by david
2451 priv->ieee80211->GetNmodeSupportBySecCfg = GetNmodeSupportBySecCfg8192;
2452 priv->ieee80211->GetHalfNmodeSupportByAPsHandler = GetHalfNmodeSupportByAPs819xUsb;
2453 priv->ieee80211->SetWirelessMode = rtl8192_SetWirelessMode;
2454 //added by amy
2455 priv->ieee80211->InitialGainHandler = InitialGain819xUsb;
2456 priv->card_type = USB;
2457 #ifdef TO_DO_LIST
2458 if (Adapter->bInHctTest) {
2459 pHalData->ShortRetryLimit = 7;
2460 pHalData->LongRetryLimit = 7;
2462 #endif
2463 priv->ShortRetryLimit = 0x30;
2464 priv->LongRetryLimit = 0x30;
2465 priv->EarlyRxThreshold = 7;
2466 priv->enable_gpio0 = 0;
2467 priv->TransmitConfig =
2468 (TCR_MXDMA_2048<<TCR_MXDMA_OFFSET)| // Max DMA Burst Size per Tx DMA Burst, 7: reserved.
2469 (priv->ShortRetryLimit<<TCR_SRL_OFFSET)| // Short retry limit
2470 (priv->LongRetryLimit<<TCR_LRL_OFFSET) | // Long retry limit
2471 (false ? TCR_SAT : 0); // FALSE: HW provides PLCP length and LENGEXT, TRUE: SW provides them
2472 #ifdef TO_DO_LIST
2473 if (Adapter->bInHctTest)
2474 pHalData->ReceiveConfig = pHalData->CSMethod |
2475 RCR_AMF | RCR_ADF | //accept management/data
2476 //guangan200710
2477 RCR_ACF | //accept control frame for SW AP needs PS-poll, 2005.07.07, by rcnjko.
2478 RCR_AB | RCR_AM | RCR_APM | //accept BC/MC/UC
2479 RCR_AICV | RCR_ACRC32 | //accept ICV/CRC error packet
2480 ((u32)7<<RCR_MXDMA_OFFSET) | // Max DMA Burst Size per Rx DMA Burst, 7: unlimited.
2481 (pHalData->EarlyRxThreshold<<RCR_FIFO_OFFSET) | // Rx FIFO Threshold, 7: No Rx threshold.
2482 (pHalData->EarlyRxThreshold == 7 ? RCR_OnlyErlPkt : 0);
2483 else
2485 #endif
2486 priv->ReceiveConfig =
2487 RCR_AMF | RCR_ADF | //accept management/data
2488 RCR_ACF | //accept control frame for SW AP needs PS-poll, 2005.07.07, by rcnjko.
2489 RCR_AB | RCR_AM | RCR_APM | //accept BC/MC/UC
2490 ((u32)7<<RCR_MXDMA_OFFSET)| // Max DMA Burst Size per Rx DMA Burst, 7: unlimited.
2491 (priv->EarlyRxThreshold<<RX_FIFO_THRESHOLD_SHIFT) | // Rx FIFO Threshold, 7: No Rx threshold.
2492 (priv->EarlyRxThreshold == 7 ? RCR_ONLYERLPKT : 0);
2494 priv->AcmControl = 0;
2495 priv->pFirmware = kzalloc(sizeof(rt_firmware), GFP_KERNEL);
2497 /* rx related queue */
2498 skb_queue_head_init(&priv->rx_queue);
2499 skb_queue_head_init(&priv->skb_queue);
2501 /* Tx related queue */
2502 for (i = 0; i < MAX_QUEUE_SIZE; i++)
2503 skb_queue_head_init(&priv->ieee80211->skb_waitQ[i]);
2504 for (i = 0; i < MAX_QUEUE_SIZE; i++)
2505 skb_queue_head_init(&priv->ieee80211->skb_aggQ[i]);
2506 for (i = 0; i < MAX_QUEUE_SIZE; i++)
2507 skb_queue_head_init(&priv->ieee80211->skb_drv_aggQ[i]);
2508 priv->rf_set_chan = rtl8192_phy_SwChnl;
2511 //init lock here
2512 static void rtl8192_init_priv_lock(struct r8192_priv *priv)
2514 spin_lock_init(&priv->tx_lock);
2515 spin_lock_init(&priv->irq_lock);//added by thomas
2516 sema_init(&priv->wx_sem, 1);
2517 sema_init(&priv->rf_sem, 1);
2518 mutex_init(&priv->mutex);
2521 extern void rtl819x_watchdog_wqcallback(struct work_struct *work);
2523 void rtl8192_irq_rx_tasklet(struct r8192_priv *priv);
2524 //init tasklet and wait_queue here. only 2.6 above kernel is considered
2525 #define DRV_NAME "wlan0"
2526 static void rtl8192_init_priv_task(struct net_device *dev)
2528 struct r8192_priv *priv = ieee80211_priv(dev);
2530 priv->priv_wq = create_workqueue(DRV_NAME);
2532 INIT_WORK(&priv->reset_wq, rtl8192_restart);
2534 INIT_DELAYED_WORK(&priv->watch_dog_wq, rtl819x_watchdog_wqcallback);
2535 INIT_DELAYED_WORK(&priv->txpower_tracking_wq, dm_txpower_trackingcallback);
2536 INIT_DELAYED_WORK(&priv->rfpath_check_wq, dm_rf_pathcheck_workitemcallback);
2537 INIT_DELAYED_WORK(&priv->update_beacon_wq, rtl8192_update_beacon);
2538 INIT_DELAYED_WORK(&priv->initialgain_operate_wq, InitialGainOperateWorkItemCallBack);
2539 INIT_WORK(&priv->qos_activate, rtl8192_qos_activate);
2541 tasklet_init(&priv->irq_rx_tasklet,
2542 (void(*)(unsigned long))rtl8192_irq_rx_tasklet,
2543 (unsigned long)priv);
2546 static void rtl8192_get_eeprom_size(struct net_device *dev)
2548 u16 curCR = 0;
2549 struct r8192_priv *priv = ieee80211_priv(dev);
2550 RT_TRACE(COMP_EPROM, "===========>%s()\n", __func__);
2551 read_nic_word_E(dev, EPROM_CMD, &curCR);
2552 RT_TRACE(COMP_EPROM, "read from Reg EPROM_CMD(%x):%x\n", EPROM_CMD, curCR);
2553 //whether need I consider BIT5?
2554 priv->epromtype = (curCR & Cmd9346CR_9356SEL) ? EPROM_93c56 : EPROM_93c46;
2555 RT_TRACE(COMP_EPROM, "<===========%s(), epromtype:%d\n", __func__, priv->epromtype);
2558 //used to swap endian. as ntohl & htonl are not necessary to swap endian, so use this instead.
2559 static inline u16 endian_swap(u16 *data)
2561 u16 tmp = *data;
2562 *data = (tmp >> 8) | (tmp << 8);
2563 return *data;
2565 static void rtl8192_read_eeprom_info(struct net_device *dev)
2567 u16 wEPROM_ID = 0;
2568 u8 bMac_Tmp_Addr[6] = {0x00, 0xe0, 0x4c, 0x00, 0x00, 0x02};
2569 u8 bLoad_From_EEPOM = false;
2570 struct r8192_priv *priv = ieee80211_priv(dev);
2571 u16 tmpValue = 0;
2572 int i;
2573 RT_TRACE(COMP_EPROM, "===========>%s()\n", __func__);
2574 wEPROM_ID = eprom_read(dev, 0); //first read EEPROM ID out;
2575 RT_TRACE(COMP_EPROM, "EEPROM ID is 0x%x\n", wEPROM_ID);
2577 if (wEPROM_ID != RTL8190_EEPROM_ID) {
2578 RT_TRACE(COMP_ERR, "EEPROM ID is invalid(is 0x%x(should be 0x%x)\n", wEPROM_ID, RTL8190_EEPROM_ID);
2579 } else {
2580 bLoad_From_EEPOM = true;
2583 if (bLoad_From_EEPOM) {
2584 tmpValue = eprom_read(dev, (EEPROM_VID>>1));
2585 priv->eeprom_vid = endian_swap(&tmpValue);
2586 priv->eeprom_pid = eprom_read(dev, (EEPROM_PID>>1));
2587 tmpValue = eprom_read(dev, (EEPROM_ChannelPlan>>1));
2588 priv->eeprom_ChannelPlan = ((tmpValue&0xff00)>>8);
2589 priv->btxpowerdata_readfromEEPORM = true;
2590 priv->eeprom_CustomerID = eprom_read(dev, (EEPROM_Customer_ID>>1)) >>8;
2591 } else {
2592 priv->eeprom_vid = 0;
2593 priv->eeprom_pid = 0;
2594 priv->card_8192_version = VERSION_819xU_B;
2595 priv->eeprom_ChannelPlan = 0;
2596 priv->eeprom_CustomerID = 0;
2598 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);
2599 //set channelplan from eeprom
2600 priv->ChannelPlan = priv->eeprom_ChannelPlan;
2601 if (bLoad_From_EEPOM) {
2602 int i;
2603 for (i = 0; i < 6; i += 2) {
2604 u16 tmp = 0;
2605 tmp = eprom_read(dev, (u16)((EEPROM_NODE_ADDRESS_BYTE_0 + i)>>1));
2606 *(u16 *)(&dev->dev_addr[i]) = tmp;
2608 } else {
2609 memcpy(dev->dev_addr, bMac_Tmp_Addr, 6);
2610 //should I set IDR0 here?
2612 RT_TRACE(COMP_EPROM, "MAC addr:%pM\n", dev->dev_addr);
2613 priv->rf_type = RTL819X_DEFAULT_RF_TYPE; //default 1T2R
2614 priv->rf_chip = RF_8256;
2616 if (priv->card_8192_version == (u8)VERSION_819xU_A) {
2617 //read Tx power gain offset of legacy OFDM to HT rate
2618 if (bLoad_From_EEPOM)
2619 priv->EEPROMTxPowerDiff = (eprom_read(dev, (EEPROM_TxPowerDiff>>1))&0xff00) >> 8;
2620 else
2621 priv->EEPROMTxPowerDiff = EEPROM_Default_TxPower;
2622 RT_TRACE(COMP_EPROM, "TxPowerDiff:%d\n", priv->EEPROMTxPowerDiff);
2623 //read ThermalMeter from EEPROM
2624 if (bLoad_From_EEPOM)
2625 priv->EEPROMThermalMeter = (u8)(eprom_read(dev, (EEPROM_ThermalMeter>>1))&0x00ff);
2626 else
2627 priv->EEPROMThermalMeter = EEPROM_Default_ThermalMeter;
2628 RT_TRACE(COMP_EPROM, "ThermalMeter:%d\n", priv->EEPROMThermalMeter);
2629 //vivi, for tx power track
2630 priv->TSSI_13dBm = priv->EEPROMThermalMeter *100;
2631 //read antenna tx power offset of B/C/D to A from EEPROM
2632 if (bLoad_From_EEPOM)
2633 priv->EEPROMPwDiff = (eprom_read(dev, (EEPROM_PwDiff>>1))&0x0f00)>>8;
2634 else
2635 priv->EEPROMPwDiff = EEPROM_Default_PwDiff;
2636 RT_TRACE(COMP_EPROM, "TxPwDiff:%d\n", priv->EEPROMPwDiff);
2637 // Read CrystalCap from EEPROM
2638 if (bLoad_From_EEPOM)
2639 priv->EEPROMCrystalCap = (eprom_read(dev, (EEPROM_CrystalCap>>1))&0x0f);
2640 else
2641 priv->EEPROMCrystalCap = EEPROM_Default_CrystalCap;
2642 RT_TRACE(COMP_EPROM, "CrystalCap = %d\n", priv->EEPROMCrystalCap);
2643 //get per-channel Tx power level
2644 if (bLoad_From_EEPOM)
2645 priv->EEPROM_Def_Ver = (eprom_read(dev, (EEPROM_TxPwIndex_Ver>>1))&0xff00)>>8;
2646 else
2647 priv->EEPROM_Def_Ver = 1;
2648 RT_TRACE(COMP_EPROM, "EEPROM_DEF_VER:%d\n", priv->EEPROM_Def_Ver);
2649 if (priv->EEPROM_Def_Ver == 0) { //old eeprom definition
2650 int i;
2651 if (bLoad_From_EEPOM)
2652 priv->EEPROMTxPowerLevelCCK = (eprom_read(dev, (EEPROM_TxPwIndex_CCK>>1))&0xff) >> 8;
2653 else
2654 priv->EEPROMTxPowerLevelCCK = 0x10;
2655 RT_TRACE(COMP_EPROM, "CCK Tx Power Levl: 0x%02x\n", priv->EEPROMTxPowerLevelCCK);
2656 for (i = 0; i < 3; i++) {
2657 if (bLoad_From_EEPOM) {
2658 tmpValue = eprom_read(dev, (EEPROM_TxPwIndex_OFDM_24G+i)>>1);
2659 if (((EEPROM_TxPwIndex_OFDM_24G+i) % 2) == 0)
2660 tmpValue = tmpValue & 0x00ff;
2661 else
2662 tmpValue = (tmpValue & 0xff00) >> 8;
2663 } else {
2664 tmpValue = 0x10;
2666 priv->EEPROMTxPowerLevelOFDM24G[i] = (u8) tmpValue;
2667 RT_TRACE(COMP_EPROM, "OFDM 2.4G Tx Power Level, Index %d = 0x%02x\n", i, priv->EEPROMTxPowerLevelCCK);
2669 } else if (priv->EEPROM_Def_Ver == 1) {
2670 if (bLoad_From_EEPOM) {
2671 tmpValue = eprom_read(dev, (EEPROM_TxPwIndex_CCK_V1>>1));
2672 tmpValue = (tmpValue & 0xff00) >> 8;
2673 } else {
2674 tmpValue = 0x10;
2676 priv->EEPROMTxPowerLevelCCK_V1[0] = (u8)tmpValue;
2678 if (bLoad_From_EEPOM)
2679 tmpValue = eprom_read(dev, (EEPROM_TxPwIndex_CCK_V1 + 2)>>1);
2680 else
2681 tmpValue = 0x1010;
2682 *((u16 *)(&priv->EEPROMTxPowerLevelCCK_V1[1])) = tmpValue;
2683 if (bLoad_From_EEPOM)
2684 tmpValue = eprom_read(dev, (EEPROM_TxPwIndex_OFDM_24G_V1>>1));
2685 else
2686 tmpValue = 0x1010;
2687 *((u16 *)(&priv->EEPROMTxPowerLevelOFDM24G[0])) = tmpValue;
2688 if (bLoad_From_EEPOM)
2689 tmpValue = eprom_read(dev, (EEPROM_TxPwIndex_OFDM_24G_V1+2)>>1);
2690 else
2691 tmpValue = 0x10;
2692 priv->EEPROMTxPowerLevelOFDM24G[2] = (u8)tmpValue;
2693 }//endif EEPROM_Def_Ver == 1
2695 //update HAL variables
2697 for (i = 0; i < 14; i++) {
2698 if (i <= 3)
2699 priv->TxPowerLevelOFDM24G[i] = priv->EEPROMTxPowerLevelOFDM24G[0];
2700 else if (i >= 4 && i <= 9)
2701 priv->TxPowerLevelOFDM24G[i] = priv->EEPROMTxPowerLevelOFDM24G[1];
2702 else
2703 priv->TxPowerLevelOFDM24G[i] = priv->EEPROMTxPowerLevelOFDM24G[2];
2706 for (i = 0; i < 14; i++) {
2707 if (priv->EEPROM_Def_Ver == 0) {
2708 if (i <= 3)
2709 priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelOFDM24G[0] + (priv->EEPROMTxPowerLevelCCK - priv->EEPROMTxPowerLevelOFDM24G[1]);
2710 else if (i >= 4 && i <= 9)
2711 priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelCCK;
2712 else
2713 priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelOFDM24G[2] + (priv->EEPROMTxPowerLevelCCK - priv->EEPROMTxPowerLevelOFDM24G[1]);
2714 } else if (priv->EEPROM_Def_Ver == 1) {
2715 if (i <= 3)
2716 priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelCCK_V1[0];
2717 else if (i >= 4 && i <= 9)
2718 priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelCCK_V1[1];
2719 else
2720 priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelCCK_V1[2];
2723 priv->TxPowerDiff = priv->EEPROMPwDiff;
2724 // Antenna B gain offset to antenna A, bit0~3
2725 priv->AntennaTxPwDiff[0] = (priv->EEPROMTxPowerDiff & 0xf);
2726 // Antenna C gain offset to antenna A, bit4~7
2727 priv->AntennaTxPwDiff[1] = ((priv->EEPROMTxPowerDiff & 0xf0)>>4);
2728 // CrystalCap, bit12~15
2729 priv->CrystalCap = priv->EEPROMCrystalCap;
2730 // ThermalMeter, bit0~3 for RFIC1, bit4~7 for RFIC2
2731 // 92U does not enable TX power tracking.
2732 priv->ThermalMeter[0] = priv->EEPROMThermalMeter;
2733 }//end if VersionID == VERSION_819xU_A
2735 //added by vivi, for dlink led, 20080416
2736 switch (priv->eeprom_CustomerID) {
2737 case EEPROM_CID_RUNTOP:
2738 priv->CustomerID = RT_CID_819x_RUNTOP;
2739 break;
2741 case EEPROM_CID_DLINK:
2742 priv->CustomerID = RT_CID_DLINK;
2743 break;
2745 default:
2746 priv->CustomerID = RT_CID_DEFAULT;
2747 break;
2751 switch (priv->CustomerID) {
2752 case RT_CID_819x_RUNTOP:
2753 priv->LedStrategy = SW_LED_MODE2;
2754 break;
2756 case RT_CID_DLINK:
2757 priv->LedStrategy = SW_LED_MODE4;
2758 break;
2760 default:
2761 priv->LedStrategy = SW_LED_MODE0;
2762 break;
2767 if (priv->rf_type == RF_1T2R) {
2768 RT_TRACE(COMP_EPROM, "\n1T2R config\n");
2769 } else {
2770 RT_TRACE(COMP_EPROM, "\n2T4R config\n");
2773 // 2008/01/16 MH We can only know RF type in the function. So we have to init
2774 // DIG RATR table again.
2775 init_rate_adaptive(dev);
2776 //we need init DIG RATR table here again.
2778 RT_TRACE(COMP_EPROM, "<===========%s()\n", __func__);
2779 return;
2782 short rtl8192_get_channel_map(struct net_device *dev)
2784 struct r8192_priv *priv = ieee80211_priv(dev);
2785 if (priv->ChannelPlan > COUNTRY_CODE_GLOBAL_DOMAIN) {
2786 netdev_err(dev, "rtl8180_init: Error channel plan! Set to default.\n");
2787 priv->ChannelPlan = 0;
2789 RT_TRACE(COMP_INIT, "Channel plan is %d\n", priv->ChannelPlan);
2791 rtl819x_set_channel_map(priv->ChannelPlan, priv);
2792 return 0;
2795 short rtl8192_init(struct net_device *dev)
2798 struct r8192_priv *priv = ieee80211_priv(dev);
2800 memset(&(priv->stats), 0, sizeof(struct Stats));
2801 memset(priv->txqueue_to_outpipemap, 0, 9);
2802 #ifdef PIPE12
2804 int i = 0;
2805 u8 queuetopipe[] = {3, 2, 1, 0, 4, 8, 7, 6, 5};
2806 memcpy(priv->txqueue_to_outpipemap, queuetopipe, 9);
2808 #else
2810 u8 queuetopipe[] = {3, 2, 1, 0, 4, 4, 0, 4, 4};
2811 memcpy(priv->txqueue_to_outpipemap, queuetopipe, 9);
2813 #endif
2814 rtl8192_init_priv_variable(dev);
2815 rtl8192_init_priv_lock(priv);
2816 rtl8192_init_priv_task(dev);
2817 rtl8192_get_eeprom_size(dev);
2818 rtl8192_read_eeprom_info(dev);
2819 rtl8192_get_channel_map(dev);
2820 init_hal_dm(dev);
2821 init_timer(&priv->watch_dog_timer);
2822 priv->watch_dog_timer.data = (unsigned long)dev;
2823 priv->watch_dog_timer.function = watch_dog_timer_callback;
2824 if (rtl8192_usb_initendpoints(dev) != 0) {
2825 DMESG("Endopoints initialization failed");
2826 return -ENOMEM;
2829 #ifdef DEBUG_EPROM
2830 dump_eprom(dev);
2831 #endif
2832 return 0;
2835 /******************************************************************************
2836 *function: This function actually only set RRSR, RATR and BW_OPMODE registers
2837 * not to do all the hw config as its name says
2838 * input: net_device dev
2839 * output: none
2840 * return: none
2841 * notice: This part need to modified according to the rate set we filtered
2842 * ****************************************************************************/
2843 void rtl8192_hwconfig(struct net_device *dev)
2845 u32 regRATR = 0, regRRSR = 0;
2846 u8 regBwOpMode = 0, regTmp = 0;
2847 struct r8192_priv *priv = ieee80211_priv(dev);
2848 u32 ratr_value = 0;
2850 // Set RRSR, RATR, and BW_OPMODE registers
2852 switch (priv->ieee80211->mode) {
2853 case WIRELESS_MODE_B:
2854 regBwOpMode = BW_OPMODE_20MHZ;
2855 regRATR = RATE_ALL_CCK;
2856 regRRSR = RATE_ALL_CCK;
2857 break;
2858 case WIRELESS_MODE_A:
2859 regBwOpMode = BW_OPMODE_5G |BW_OPMODE_20MHZ;
2860 regRATR = RATE_ALL_OFDM_AG;
2861 regRRSR = RATE_ALL_OFDM_AG;
2862 break;
2863 case WIRELESS_MODE_G:
2864 regBwOpMode = BW_OPMODE_20MHZ;
2865 regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
2866 regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
2867 break;
2868 case WIRELESS_MODE_AUTO:
2869 #ifdef TO_DO_LIST
2870 if (Adapter->bInHctTest) {
2871 regBwOpMode = BW_OPMODE_20MHZ;
2872 regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
2873 regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
2875 else
2876 #endif
2878 regBwOpMode = BW_OPMODE_20MHZ;
2879 regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
2880 regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
2882 break;
2883 case WIRELESS_MODE_N_24G:
2884 // It support CCK rate by default.
2885 // CCK rate will be filtered out only when associated AP does not support it.
2886 regBwOpMode = BW_OPMODE_20MHZ;
2887 regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
2888 regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
2889 break;
2890 case WIRELESS_MODE_N_5G:
2891 regBwOpMode = BW_OPMODE_5G;
2892 regRATR = RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
2893 regRRSR = RATE_ALL_OFDM_AG;
2894 break;
2897 write_nic_byte(dev, BW_OPMODE, regBwOpMode);
2898 ratr_value = regRATR;
2899 if (priv->rf_type == RF_1T2R)
2900 ratr_value &= ~(RATE_ALL_OFDM_2SS);
2901 write_nic_dword(dev, RATR0, ratr_value);
2902 write_nic_byte(dev, UFWP, 1);
2903 read_nic_byte(dev, 0x313, &regTmp);
2904 regRRSR = ((regTmp) << 24) | (regRRSR & 0x00ffffff);
2905 write_nic_dword(dev, RRSR, regRRSR);
2908 // Set Retry Limit here
2910 write_nic_word(dev, RETRY_LIMIT,
2911 priv->ShortRetryLimit << RETRY_LIMIT_SHORT_SHIFT |
2912 priv->LongRetryLimit << RETRY_LIMIT_LONG_SHIFT);
2913 // Set Contention Window here
2915 // Set Tx AGC
2917 // Set Tx Antenna including Feedback control
2919 // Set Auto Rate fallback control
2925 //InitializeAdapter and PhyCfg
2926 bool rtl8192_adapter_start(struct net_device *dev)
2928 struct r8192_priv *priv = ieee80211_priv(dev);
2929 u32 dwRegRead = 0;
2930 bool init_status = true;
2931 u8 SECR_value = 0x0;
2932 u8 tmp;
2933 RT_TRACE(COMP_INIT, "====>%s()\n", __func__);
2934 priv->Rf_Mode = RF_OP_By_SW_3wire;
2935 //for ASIC power on sequence
2936 write_nic_byte_E(dev, 0x5f, 0x80);
2937 mdelay(50);
2938 write_nic_byte_E(dev, 0x5f, 0xf0);
2939 write_nic_byte_E(dev, 0x5d, 0x00);
2940 write_nic_byte_E(dev, 0x5e, 0x80);
2941 write_nic_byte(dev, 0x17, 0x37);
2942 mdelay(10);
2943 priv->pFirmware->firmware_status = FW_STATUS_0_INIT;
2944 //config CPUReset Register
2945 //Firmware Reset or not?
2946 read_nic_dword(dev, CPU_GEN, &dwRegRead);
2947 if (priv->pFirmware->firmware_status == FW_STATUS_0_INIT)
2948 dwRegRead |= CPU_GEN_SYSTEM_RESET; //do nothing here?
2949 else if (priv->pFirmware->firmware_status == FW_STATUS_5_READY)
2950 dwRegRead |= CPU_GEN_FIRMWARE_RESET;
2951 else
2952 RT_TRACE(COMP_ERR, "ERROR in %s(): undefined firmware state(%d)\n", __func__, priv->pFirmware->firmware_status);
2954 write_nic_dword(dev, CPU_GEN, dwRegRead);
2955 //config BB.
2956 rtl8192_BBConfig(dev);
2958 //Loopback mode or not
2959 priv->LoopbackMode = RTL819xU_NO_LOOPBACK;
2961 read_nic_dword(dev, CPU_GEN, &dwRegRead);
2962 if (priv->LoopbackMode == RTL819xU_NO_LOOPBACK)
2963 dwRegRead = ((dwRegRead & CPU_GEN_NO_LOOPBACK_MSK) | CPU_GEN_NO_LOOPBACK_SET);
2964 else if (priv->LoopbackMode == RTL819xU_MAC_LOOPBACK)
2965 dwRegRead |= CPU_CCK_LOOPBACK;
2966 else
2967 RT_TRACE(COMP_ERR, "Serious error in %s(): wrong loopback mode setting(%d)\n", __func__, priv->LoopbackMode);
2969 write_nic_dword(dev, CPU_GEN, dwRegRead);
2971 //after reset cpu, we need wait for a seconds to write in register.
2972 udelay(500);
2974 //xiong add for new bitfile:usb suspend reset pin set to 1. //do we need?
2975 read_nic_byte_E(dev, 0x5f, &tmp);
2976 write_nic_byte_E(dev, 0x5f, tmp|0x20);
2978 //Set Hardware
2979 rtl8192_hwconfig(dev);
2981 //turn on Tx/Rx
2982 write_nic_byte(dev, CMDR, CR_RE|CR_TE);
2984 //set IDR0 here
2985 write_nic_dword(dev, MAC0, ((u32 *)dev->dev_addr)[0]);
2986 write_nic_word(dev, MAC4, ((u16 *)(dev->dev_addr + 4))[0]);
2988 //set RCR
2989 write_nic_dword(dev, RCR, priv->ReceiveConfig);
2991 //Initialize Number of Reserved Pages in Firmware Queue
2992 write_nic_dword(dev, RQPN1, NUM_OF_PAGE_IN_FW_QUEUE_BK << RSVD_FW_QUEUE_PAGE_BK_SHIFT |
2993 NUM_OF_PAGE_IN_FW_QUEUE_BE << RSVD_FW_QUEUE_PAGE_BE_SHIFT |
2994 NUM_OF_PAGE_IN_FW_QUEUE_VI << RSVD_FW_QUEUE_PAGE_VI_SHIFT |
2995 NUM_OF_PAGE_IN_FW_QUEUE_VO <<RSVD_FW_QUEUE_PAGE_VO_SHIFT);
2996 write_nic_dword(dev, RQPN2, NUM_OF_PAGE_IN_FW_QUEUE_MGNT << RSVD_FW_QUEUE_PAGE_MGNT_SHIFT |
2997 NUM_OF_PAGE_IN_FW_QUEUE_CMD << RSVD_FW_QUEUE_PAGE_CMD_SHIFT);
2998 write_nic_dword(dev, RQPN3, APPLIED_RESERVED_QUEUE_IN_FW|
2999 NUM_OF_PAGE_IN_FW_QUEUE_BCN<<RSVD_FW_QUEUE_PAGE_BCN_SHIFT);
3000 write_nic_dword(dev, RATR0+4*7, (RATE_ALL_OFDM_AG | RATE_ALL_CCK));
3002 //Set AckTimeout
3003 // TODO: (it value is only for FPGA version). need to be changed!!2006.12.18, by Emily
3004 write_nic_byte(dev, ACK_TIMEOUT, 0x30);
3006 if (priv->ResetProgress == RESET_TYPE_NORESET)
3007 rtl8192_SetWirelessMode(dev, priv->ieee80211->mode);
3008 if (priv->ResetProgress == RESET_TYPE_NORESET) {
3009 CamResetAllEntry(dev);
3010 SECR_value |= SCR_TxEncEnable;
3011 SECR_value |= SCR_RxDecEnable;
3012 SECR_value |= SCR_NoSKMC;
3013 write_nic_byte(dev, SECR, SECR_value);
3016 //Beacon related
3017 write_nic_word(dev, ATIMWND, 2);
3018 write_nic_word(dev, BCN_INTERVAL, 100);
3020 #define DEFAULT_EDCA 0x005e4332
3022 int i;
3023 for (i = 0; i < QOS_QUEUE_NUM; i++)
3024 write_nic_dword(dev, WDCAPARA_ADD[i], DEFAULT_EDCA);
3026 #ifdef USB_RX_AGGREGATION_SUPPORT
3027 //3 For usb rx firmware aggregation control
3028 if (priv->ResetProgress == RESET_TYPE_NORESET) {
3029 u32 ulValue;
3030 PRT_HIGH_THROUGHPUT pHTInfo = priv->ieee80211->pHTInfo;
3031 ulValue = (pHTInfo->UsbRxFwAggrEn<<24) | (pHTInfo->UsbRxFwAggrPageNum<<16) |
3032 (pHTInfo->UsbRxFwAggrPacketNum<<8) | (pHTInfo->UsbRxFwAggrTimeout);
3034 * If usb rx firmware aggregation is enabled,
3035 * when anyone of three threshold conditions above is reached,
3036 * firmware will send aggregated packet to driver.
3038 write_nic_dword(dev, 0x1a8, ulValue);
3039 priv->bCurrentRxAggrEnable = true;
3041 #endif
3043 rtl8192_phy_configmac(dev);
3045 if (priv->card_8192_version == (u8) VERSION_819xU_A) {
3046 rtl8192_phy_getTxPower(dev);
3047 rtl8192_phy_setTxPower(dev, priv->chan);
3050 //Firmware download
3051 init_status = init_firmware(dev);
3052 if (!init_status) {
3053 RT_TRACE(COMP_ERR, "ERR!!! %s(): Firmware download is failed\n", __func__);
3054 return init_status;
3056 RT_TRACE(COMP_INIT, "%s():after firmware download\n", __func__);
3058 #ifdef TO_DO_LIST
3059 if (Adapter->ResetProgress == RESET_TYPE_NORESET) {
3060 if (pMgntInfo->RegRfOff == TRUE) { // User disable RF via registry.
3061 RT_TRACE((COMP_INIT|COMP_RF), DBG_LOUD, ("InitializeAdapter819xUsb(): Turn off RF for RegRfOff ----------\n"));
3062 MgntActSet_RF_State(Adapter, eRfOff, RF_CHANGE_BY_SW);
3063 // Those actions will be discard in MgntActSet_RF_State because of the same state
3064 for (eRFPath = 0; eRFPath < pHalData->NumTotalRFPath; eRFPath++)
3065 PHY_SetRFReg(Adapter, (RF90_RADIO_PATH_E)eRFPath, 0x4, 0xC00, 0x0);
3066 } else if (pMgntInfo->RfOffReason > RF_CHANGE_BY_PS) { // H/W or S/W RF OFF before sleep.
3067 RT_TRACE((COMP_INIT|COMP_RF), DBG_LOUD, ("InitializeAdapter819xUsb(): Turn off RF for RfOffReason(%d) ----------\n", pMgntInfo->RfOffReason));
3068 MgntActSet_RF_State(Adapter, eRfOff, pMgntInfo->RfOffReason);
3069 } else {
3070 pHalData->eRFPowerState = eRfOn;
3071 pMgntInfo->RfOffReason = 0;
3072 RT_TRACE((COMP_INIT|COMP_RF), DBG_LOUD, ("InitializeAdapter819xUsb(): RF is on ----------\n"));
3074 } else {
3075 if (pHalData->eRFPowerState == eRfOff) {
3076 MgntActSet_RF_State(Adapter, eRfOff, pMgntInfo->RfOffReason);
3077 // Those actions will be discard in MgntActSet_RF_State because of the same state
3078 for (eRFPath = 0; eRFPath < pHalData->NumTotalRFPath; eRFPath++)
3079 PHY_SetRFReg(Adapter, (RF90_RADIO_PATH_E)eRFPath, 0x4, 0xC00, 0x0);
3082 #endif
3083 //config RF.
3084 if (priv->ResetProgress == RESET_TYPE_NORESET) {
3085 rtl8192_phy_RFConfig(dev);
3086 RT_TRACE(COMP_INIT, "%s():after phy RF config\n", __func__);
3090 if (priv->ieee80211->FwRWRF)
3091 // We can force firmware to do RF-R/W
3092 priv->Rf_Mode = RF_OP_By_FW;
3093 else
3094 priv->Rf_Mode = RF_OP_By_SW_3wire;
3097 rtl8192_phy_updateInitGain(dev);
3098 /*--set CCK and OFDM Block "ON"--*/
3099 rtl8192_setBBreg(dev, rFPGA0_RFMOD, bCCKEn, 0x1);
3100 rtl8192_setBBreg(dev, rFPGA0_RFMOD, bOFDMEn, 0x1);
3102 if (priv->ResetProgress == RESET_TYPE_NORESET) {
3103 //if D or C cut
3104 u8 tmpvalue;
3105 read_nic_byte(dev, 0x301, &tmpvalue);
3106 if (tmpvalue == 0x03) {
3107 priv->bDcut = TRUE;
3108 RT_TRACE(COMP_POWER_TRACKING, "D-cut\n");
3109 } else {
3110 priv->bDcut = FALSE;
3111 RT_TRACE(COMP_POWER_TRACKING, "C-cut\n");
3113 dm_initialize_txpower_tracking(dev);
3115 if (priv->bDcut == TRUE) {
3116 u32 i, TempCCk;
3117 u32 tmpRegA = rtl8192_QueryBBReg(dev, rOFDM0_XATxIQImbalance, bMaskDWord);
3118 for (i = 0; i < TxBBGainTableLength; i++) {
3119 if (tmpRegA == priv->txbbgain_table[i].txbbgain_value) {
3120 priv->rfa_txpowertrackingindex = (u8)i;
3121 priv->rfa_txpowertrackingindex_real = (u8)i;
3122 priv->rfa_txpowertracking_default = priv->rfa_txpowertrackingindex;
3123 break;
3127 TempCCk = rtl8192_QueryBBReg(dev, rCCK0_TxFilter1, bMaskByte2);
3129 for (i = 0; i < CCKTxBBGainTableLength; i++) {
3131 if (TempCCk == priv->cck_txbbgain_table[i].ccktxbb_valuearray[0]) {
3132 priv->cck_present_attentuation_20Mdefault = (u8) i;
3133 break;
3136 priv->cck_present_attentuation_40Mdefault = 0;
3137 priv->cck_present_attentuation_difference = 0;
3138 priv->cck_present_attentuation = priv->cck_present_attentuation_20Mdefault;
3142 write_nic_byte(dev, 0x87, 0x0);
3145 return init_status;
3148 /* this configures registers for beacon tx and enables it via
3149 * rtl8192_beacon_tx_enable(). rtl8192_beacon_tx_disable() might
3150 * be used to stop beacon transmission
3152 /***************************************************************************
3153 -------------------------------NET STUFF---------------------------
3154 ***************************************************************************/
3156 static struct net_device_stats *rtl8192_stats(struct net_device *dev)
3158 struct r8192_priv *priv = ieee80211_priv(dev);
3160 return &priv->ieee80211->stats;
3163 static bool HalTxCheckStuck819xUsb(struct net_device *dev)
3165 struct r8192_priv *priv = ieee80211_priv(dev);
3166 u16 RegTxCounter;
3167 bool bStuck = FALSE;
3168 read_nic_word(dev, 0x128, &RegTxCounter);
3169 RT_TRACE(COMP_RESET, "%s():RegTxCounter is %d,TxCounter is %d\n", __func__, RegTxCounter, priv->TxCounter);
3170 if (priv->TxCounter == RegTxCounter)
3171 bStuck = TRUE;
3173 priv->TxCounter = RegTxCounter;
3175 return bStuck;
3179 * <Assumption: RT_TX_SPINLOCK is acquired.>
3180 * First added: 2006.11.19 by emily
3182 RESET_TYPE TxCheckStuck(struct net_device *dev)
3184 struct r8192_priv *priv = ieee80211_priv(dev);
3185 u8 QueueID;
3186 bool bCheckFwTxCnt = false;
3189 // Decide such threshold according to current power save mode
3192 for (QueueID = 0; QueueID <= BEACON_QUEUE; QueueID++) {
3193 if (QueueID == TXCMD_QUEUE)
3194 continue;
3195 #ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
3196 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))
3197 #else
3198 if ((skb_queue_len(&priv->ieee80211->skb_waitQ[QueueID]) == 0) && (skb_queue_len(&priv->ieee80211->skb_aggQ[QueueID]) == 0))
3199 #endif
3200 continue;
3202 bCheckFwTxCnt = true;
3204 if (bCheckFwTxCnt) {
3205 if (HalTxCheckStuck819xUsb(dev)) {
3206 RT_TRACE(COMP_RESET, "TxCheckStuck(): Fw indicates no Tx condition! \n");
3207 return RESET_TYPE_SILENT;
3210 return RESET_TYPE_NORESET;
3213 static bool HalRxCheckStuck819xUsb(struct net_device *dev)
3215 u16 RegRxCounter;
3216 struct r8192_priv *priv = ieee80211_priv(dev);
3217 bool bStuck = FALSE;
3218 static u8 rx_chk_cnt;
3219 read_nic_word(dev, 0x130, &RegRxCounter);
3220 RT_TRACE(COMP_RESET, "%s(): RegRxCounter is %d,RxCounter is %d\n", __func__, RegRxCounter, priv->RxCounter);
3221 // If rssi is small, we should check rx for long time because of bad rx.
3222 // or maybe it will continuous silent reset every 2 seconds.
3223 rx_chk_cnt++;
3224 if (priv->undecorated_smoothed_pwdb >= (RateAdaptiveTH_High+5)) {
3225 rx_chk_cnt = 0; //high rssi, check rx stuck right now.
3226 } else if (priv->undecorated_smoothed_pwdb < (RateAdaptiveTH_High+5) &&
3227 ((priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20 && priv->undecorated_smoothed_pwdb >= RateAdaptiveTH_Low_40M) ||
3228 (priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20 && priv->undecorated_smoothed_pwdb >= RateAdaptiveTH_Low_20M))) {
3229 if (rx_chk_cnt < 2)
3230 return bStuck;
3231 else
3232 rx_chk_cnt = 0;
3233 } else if (((priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20 && priv->undecorated_smoothed_pwdb < RateAdaptiveTH_Low_40M) ||
3234 (priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20 && priv->undecorated_smoothed_pwdb < RateAdaptiveTH_Low_20M)) &&
3235 priv->undecorated_smoothed_pwdb >= VeryLowRSSI) {
3236 if (rx_chk_cnt < 4)
3237 return bStuck;
3238 else
3239 rx_chk_cnt = 0;
3240 } else {
3241 if (rx_chk_cnt < 8)
3242 return bStuck;
3243 else
3244 rx_chk_cnt = 0;
3247 if (priv->RxCounter == RegRxCounter)
3248 bStuck = TRUE;
3250 priv->RxCounter = RegRxCounter;
3252 return bStuck;
3255 static RESET_TYPE RxCheckStuck(struct net_device *dev)
3257 struct r8192_priv *priv = ieee80211_priv(dev);
3258 bool bRxCheck = FALSE;
3260 if (priv->IrpPendingCount > 1)
3261 bRxCheck = TRUE;
3263 if (bRxCheck) {
3264 if (HalRxCheckStuck819xUsb(dev)) {
3265 RT_TRACE(COMP_RESET, "RxStuck Condition\n");
3266 return RESET_TYPE_SILENT;
3269 return RESET_TYPE_NORESET;
3274 * This function is called by Checkforhang to check whether we should ask OS to reset driver
3276 * \param pAdapter The adapter context for this miniport
3278 * Note:NIC with USB interface sholud not call this function because we cannot scan descriptor
3279 * to judge whether there is tx stuck.
3280 * Note: This function may be required to be rewrite for Vista OS.
3281 * <<<Assumption: Tx spinlock has been acquired >>>
3283 * 8185 and 8185b does not implement this function. This is added by Emily at 2006.11.24
3285 RESET_TYPE rtl819x_ifcheck_resetornot(struct net_device *dev)
3287 struct r8192_priv *priv = ieee80211_priv(dev);
3288 RESET_TYPE TxResetType = RESET_TYPE_NORESET;
3289 RESET_TYPE RxResetType = RESET_TYPE_NORESET;
3290 RT_RF_POWER_STATE rfState;
3292 rfState = priv->ieee80211->eRFPowerState;
3294 TxResetType = TxCheckStuck(dev);
3295 if (rfState != eRfOff ||
3296 (priv->ieee80211->iw_mode != IW_MODE_ADHOC)) {
3297 // If driver is in the status of firmware download failure , driver skips RF initialization and RF is
3298 // in turned off state. Driver should check whether Rx stuck and do silent reset. And
3299 // if driver is in firmware download failure status, driver should initialize RF in the following
3300 // silent reset procedure Emily, 2008.01.21
3302 // Driver should not check RX stuck in IBSS mode because it is required to
3303 // set Check BSSID in order to send beacon, however, if check BSSID is
3304 // set, STA cannot hear any packet at all. Emily, 2008.04.12
3305 RxResetType = RxCheckStuck(dev);
3307 if (TxResetType == RESET_TYPE_NORMAL || RxResetType == RESET_TYPE_NORMAL) {
3308 return RESET_TYPE_NORMAL;
3309 } else if (TxResetType == RESET_TYPE_SILENT || RxResetType == RESET_TYPE_SILENT) {
3310 RT_TRACE(COMP_RESET, "%s():silent reset\n", __func__);
3311 return RESET_TYPE_SILENT;
3312 } else {
3313 return RESET_TYPE_NORESET;
3318 void rtl8192_cancel_deferred_work(struct r8192_priv *priv);
3319 int _rtl8192_up(struct net_device *dev);
3320 int rtl8192_close(struct net_device *dev);
3324 void CamRestoreAllEntry(struct net_device *dev)
3326 u8 EntryId = 0;
3327 struct r8192_priv *priv = ieee80211_priv(dev);
3328 u8 *MacAddr = priv->ieee80211->current_network.bssid;
3330 static u8 CAM_CONST_ADDR[4][6] = {
3331 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
3332 {0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
3333 {0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
3334 {0x00, 0x00, 0x00, 0x00, 0x00, 0x03} };
3335 static u8 CAM_CONST_BROAD[] = {
3336 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
3338 RT_TRACE(COMP_SEC, "CamRestoreAllEntry: \n");
3341 if ((priv->ieee80211->pairwise_key_type == KEY_TYPE_WEP40) ||
3342 (priv->ieee80211->pairwise_key_type == KEY_TYPE_WEP104)) {
3344 for (EntryId = 0; EntryId < 4; EntryId++) {
3345 MacAddr = CAM_CONST_ADDR[EntryId];
3346 setKey(dev, EntryId, EntryId,
3347 priv->ieee80211->pairwise_key_type,
3348 MacAddr, 0, NULL);
3351 } else if (priv->ieee80211->pairwise_key_type == KEY_TYPE_TKIP) {
3353 if (priv->ieee80211->iw_mode == IW_MODE_ADHOC)
3354 setKey(dev, 4, 0, priv->ieee80211->pairwise_key_type,
3355 (u8 *)dev->dev_addr, 0, NULL);
3356 else
3357 setKey(dev, 4, 0, priv->ieee80211->pairwise_key_type,
3358 MacAddr, 0, NULL);
3359 } else if (priv->ieee80211->pairwise_key_type == KEY_TYPE_CCMP) {
3361 if (priv->ieee80211->iw_mode == IW_MODE_ADHOC)
3362 setKey(dev, 4, 0, priv->ieee80211->pairwise_key_type,
3363 (u8 *)dev->dev_addr, 0, NULL);
3364 else
3365 setKey(dev, 4, 0, priv->ieee80211->pairwise_key_type,
3366 MacAddr, 0, NULL);
3371 if (priv->ieee80211->group_key_type == KEY_TYPE_TKIP) {
3372 MacAddr = CAM_CONST_BROAD;
3373 for (EntryId = 1; EntryId < 4; EntryId++) {
3374 setKey(dev, EntryId, EntryId,
3375 priv->ieee80211->group_key_type,
3376 MacAddr, 0, NULL);
3378 if (priv->ieee80211->iw_mode == IW_MODE_ADHOC)
3379 setKey(dev, 0, 0, priv->ieee80211->group_key_type,
3380 CAM_CONST_ADDR[0], 0, NULL);
3381 } else if (priv->ieee80211->group_key_type == KEY_TYPE_CCMP) {
3382 MacAddr = CAM_CONST_BROAD;
3383 for (EntryId = 1; EntryId < 4; EntryId++) {
3384 setKey(dev, EntryId, EntryId,
3385 priv->ieee80211->group_key_type,
3386 MacAddr, 0, NULL);
3389 if (priv->ieee80211->iw_mode == IW_MODE_ADHOC)
3390 setKey(dev, 0, 0, priv->ieee80211->group_key_type,
3391 CAM_CONST_ADDR[0], 0, NULL);
3394 //////////////////////////////////////////////////////////////
3395 // This function is used to fix Tx/Rx stop bug temporarily.
3396 // This function will do "system reset" to NIC when Tx or Rx is stuck.
3397 // The method checking Tx/Rx stuck of this function is supported by FW,
3398 // which reports Tx and Rx counter to register 0x128 and 0x130.
3399 //////////////////////////////////////////////////////////////
3400 void rtl819x_ifsilentreset(struct net_device *dev)
3402 struct r8192_priv *priv = ieee80211_priv(dev);
3403 u8 reset_times = 0;
3404 int reset_status = 0;
3405 struct ieee80211_device *ieee = priv->ieee80211;
3408 // 2007.07.20. If we need to check CCK stop, please uncomment this line.
3409 //bStuck = Adapter->HalFunc.CheckHWStopHandler(Adapter);
3411 if (priv->ResetProgress == RESET_TYPE_NORESET) {
3412 RESET_START:
3414 RT_TRACE(COMP_RESET, "=========>Reset progress!! \n");
3416 // Set the variable for reset.
3417 priv->ResetProgress = RESET_TYPE_SILENT;
3418 down(&priv->wx_sem);
3419 if (priv->up == 0) {
3420 RT_TRACE(COMP_ERR, "%s():the driver is not up! return\n", __func__);
3421 up(&priv->wx_sem);
3422 return;
3424 priv->up = 0;
3425 RT_TRACE(COMP_RESET, "%s():======>start to down the driver\n", __func__);
3427 rtl8192_rtx_disable(dev);
3428 rtl8192_cancel_deferred_work(priv);
3429 deinit_hal_dm(dev);
3430 del_timer_sync(&priv->watch_dog_timer);
3432 ieee->sync_scan_hurryup = 1;
3433 if (ieee->state == IEEE80211_LINKED) {
3434 down(&ieee->wx_sem);
3435 netdev_dbg(dev, "ieee->state is IEEE80211_LINKED\n");
3436 ieee80211_stop_send_beacons(priv->ieee80211);
3437 del_timer_sync(&ieee->associate_timer);
3438 cancel_delayed_work(&ieee->associate_retry_wq);
3439 ieee80211_stop_scan(ieee);
3440 netif_carrier_off(dev);
3441 up(&ieee->wx_sem);
3442 } else {
3443 netdev_dbg(dev, "ieee->state is NOT LINKED\n");
3444 ieee80211_softmac_stop_protocol(priv->ieee80211);
3446 up(&priv->wx_sem);
3447 RT_TRACE(COMP_RESET, "%s():<==========down process is finished\n", __func__);
3448 RT_TRACE(COMP_RESET, "%s():===========>start up the driver\n", __func__);
3449 reset_status = _rtl8192_up(dev);
3451 RT_TRACE(COMP_RESET, "%s():<===========up process is finished\n", __func__);
3452 if (reset_status == -EAGAIN) {
3453 if (reset_times < 3) {
3454 reset_times++;
3455 goto RESET_START;
3456 } else {
3457 RT_TRACE(COMP_ERR, " ERR!!! %s(): Reset Failed!!\n", __func__);
3460 ieee->is_silent_reset = 1;
3461 EnableHWSecurityConfig8192(dev);
3462 if (ieee->state == IEEE80211_LINKED && ieee->iw_mode == IW_MODE_INFRA) {
3463 ieee->set_chan(ieee->dev, ieee->current_network.channel);
3465 queue_work(ieee->wq, &ieee->associate_complete_wq);
3467 } else if (ieee->state == IEEE80211_LINKED && ieee->iw_mode == IW_MODE_ADHOC) {
3468 ieee->set_chan(ieee->dev, ieee->current_network.channel);
3469 ieee->link_change(ieee->dev);
3471 ieee80211_start_send_beacons(ieee);
3473 if (ieee->data_hard_resume)
3474 ieee->data_hard_resume(ieee->dev);
3475 netif_carrier_on(ieee->dev);
3478 CamRestoreAllEntry(dev);
3480 priv->ResetProgress = RESET_TYPE_NORESET;
3481 priv->reset_count++;
3483 priv->bForcedSilentReset = false;
3484 priv->bResetInProgress = false;
3486 // For test --> force write UFWP.
3487 write_nic_byte(dev, UFWP, 1);
3488 RT_TRACE(COMP_RESET, "Reset finished!! ====>[%d]\n", priv->reset_count);
3492 void CAM_read_entry(struct net_device *dev, u32 iIndex)
3494 u32 target_command = 0;
3495 u32 target_content = 0;
3496 u8 entry_i = 0;
3497 u32 ulStatus;
3498 s32 i = 100;
3499 for (entry_i = 0; entry_i < CAM_CONTENT_COUNT; entry_i++) {
3500 // polling bit, and No Write enable, and address
3501 target_command = entry_i+CAM_CONTENT_COUNT*iIndex;
3502 target_command = target_command | BIT31;
3504 //Check polling bit is clear
3505 while ((i--) >= 0) {
3506 read_nic_dword(dev, RWCAM, &ulStatus);
3507 if (ulStatus & BIT31)
3508 continue;
3509 else
3510 break;
3512 write_nic_dword(dev, RWCAM, target_command);
3513 RT_TRACE(COMP_SEC, "CAM_read_entry(): WRITE A0: %x \n", target_command);
3514 read_nic_dword(dev, RCAMO, &target_content);
3515 RT_TRACE(COMP_SEC, "CAM_read_entry(): WRITE A8: %x \n", target_content);
3517 printk("\n");
3520 void rtl819x_update_rxcounts(struct r8192_priv *priv, u32 *TotalRxBcnNum,
3521 u32 *TotalRxDataNum)
3523 u16 SlotIndex;
3524 u8 i;
3526 *TotalRxBcnNum = 0;
3527 *TotalRxDataNum = 0;
3529 SlotIndex = (priv->ieee80211->LinkDetectInfo.SlotIndex++)%(priv->ieee80211->LinkDetectInfo.SlotNum);
3530 priv->ieee80211->LinkDetectInfo.RxBcnNum[SlotIndex] = priv->ieee80211->LinkDetectInfo.NumRecvBcnInPeriod;
3531 priv->ieee80211->LinkDetectInfo.RxDataNum[SlotIndex] = priv->ieee80211->LinkDetectInfo.NumRecvDataInPeriod;
3532 for (i = 0; i < priv->ieee80211->LinkDetectInfo.SlotNum; i++) {
3533 *TotalRxBcnNum += priv->ieee80211->LinkDetectInfo.RxBcnNum[i];
3534 *TotalRxDataNum += priv->ieee80211->LinkDetectInfo.RxDataNum[i];
3539 extern void rtl819x_watchdog_wqcallback(struct work_struct *work)
3541 struct delayed_work *dwork = container_of(work, struct delayed_work, work);
3542 struct r8192_priv *priv = container_of(dwork, struct r8192_priv, watch_dog_wq);
3543 struct net_device *dev = priv->ieee80211->dev;
3544 struct ieee80211_device *ieee = priv->ieee80211;
3545 RESET_TYPE ResetType = RESET_TYPE_NORESET;
3546 static u8 check_reset_cnt;
3547 bool bBusyTraffic = false;
3548 u32 TotalRxBcnNum = 0;
3549 u32 TotalRxDataNum = 0;
3551 if (!priv->up)
3552 return;
3553 hal_dm_watchdog(dev);
3555 //to get busy traffic condition
3556 if (ieee->state == IEEE80211_LINKED) {
3557 if (ieee->LinkDetectInfo.NumRxOkInPeriod > 666 ||
3558 ieee->LinkDetectInfo.NumTxOkInPeriod > 666 ) {
3559 bBusyTraffic = true;
3561 ieee->LinkDetectInfo.NumRxOkInPeriod = 0;
3562 ieee->LinkDetectInfo.NumTxOkInPeriod = 0;
3563 ieee->LinkDetectInfo.bBusyTraffic = bBusyTraffic;
3565 //added by amy for AP roaming
3566 if (priv->ieee80211->state == IEEE80211_LINKED && priv->ieee80211->iw_mode == IW_MODE_INFRA) {
3568 rtl819x_update_rxcounts(priv, &TotalRxBcnNum, &TotalRxDataNum);
3569 if ((TotalRxBcnNum+TotalRxDataNum) == 0) {
3570 #ifdef TODO
3571 if (rfState == eRfOff)
3572 RT_TRACE(COMP_ERR, "========>%s()\n", __func__);
3573 #endif
3574 netdev_dbg(dev, "===>%s(): AP is power off, connect another one\n", __func__);
3575 priv->ieee80211->state = IEEE80211_ASSOCIATING;
3576 notify_wx_assoc_event(priv->ieee80211);
3577 RemovePeerTS(priv->ieee80211, priv->ieee80211->current_network.bssid);
3578 priv->ieee80211->link_change(dev);
3579 queue_work(priv->ieee80211->wq, &priv->ieee80211->associate_procedure_wq);
3583 priv->ieee80211->LinkDetectInfo.NumRecvBcnInPeriod = 0;
3584 priv->ieee80211->LinkDetectInfo.NumRecvDataInPeriod = 0;
3585 //check if reset the driver
3586 if (check_reset_cnt++ >= 3) {
3587 ResetType = rtl819x_ifcheck_resetornot(dev);
3588 check_reset_cnt = 3;
3590 if ((priv->force_reset) || (priv->ResetProgress == RESET_TYPE_NORESET &&
3591 (priv->bForcedSilentReset ||
3592 (!priv->bDisableNormalResetCheck && ResetType == RESET_TYPE_SILENT)))) { // This is control by OID set in Pomelo
3593 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);
3594 rtl819x_ifsilentreset(dev);
3596 priv->force_reset = false;
3597 priv->bForcedSilentReset = false;
3598 priv->bResetInProgress = false;
3599 RT_TRACE(COMP_TRACE, " <==RtUsbCheckForHangWorkItemCallback()\n");
3603 void watch_dog_timer_callback(unsigned long data)
3605 struct r8192_priv *priv = ieee80211_priv((struct net_device *) data);
3606 queue_delayed_work(priv->priv_wq, &priv->watch_dog_wq, 0);
3607 mod_timer(&priv->watch_dog_timer, jiffies + MSECS(IEEE80211_WATCH_DOG_TIME));
3609 int _rtl8192_up(struct net_device *dev)
3611 struct r8192_priv *priv = ieee80211_priv(dev);
3612 int init_status = 0;
3613 priv->up = 1;
3614 priv->ieee80211->ieee_up = 1;
3615 RT_TRACE(COMP_INIT, "Bringing up iface");
3616 init_status = rtl8192_adapter_start(dev);
3617 if (!init_status) {
3618 RT_TRACE(COMP_ERR, "ERR!!! %s(): initialization failed!\n", __func__);
3619 priv->up = priv->ieee80211->ieee_up = 0;
3620 return -EAGAIN;
3622 RT_TRACE(COMP_INIT, "start adapter finished\n");
3623 rtl8192_rx_enable(dev);
3624 if (priv->ieee80211->state != IEEE80211_LINKED)
3625 ieee80211_softmac_start_protocol(priv->ieee80211);
3626 ieee80211_reset_queue(priv->ieee80211);
3627 watch_dog_timer_callback((unsigned long) dev);
3628 if (!netif_queue_stopped(dev))
3629 netif_start_queue(dev);
3630 else
3631 netif_wake_queue(dev);
3633 return 0;
3637 int rtl8192_open(struct net_device *dev)
3639 struct r8192_priv *priv = ieee80211_priv(dev);
3640 int ret;
3641 down(&priv->wx_sem);
3642 ret = rtl8192_up(dev);
3643 up(&priv->wx_sem);
3644 return ret;
3649 int rtl8192_up(struct net_device *dev)
3651 struct r8192_priv *priv = ieee80211_priv(dev);
3653 if (priv->up == 1) return -1;
3655 return _rtl8192_up(dev);
3659 int rtl8192_close(struct net_device *dev)
3661 struct r8192_priv *priv = ieee80211_priv(dev);
3662 int ret;
3664 down(&priv->wx_sem);
3666 ret = rtl8192_down(dev);
3668 up(&priv->wx_sem);
3670 return ret;
3674 int rtl8192_down(struct net_device *dev)
3676 struct r8192_priv *priv = ieee80211_priv(dev);
3677 int i;
3679 if (priv->up == 0) return -1;
3681 priv->up = 0;
3682 priv->ieee80211->ieee_up = 0;
3683 RT_TRACE(COMP_DOWN, "==========>%s()\n", __func__);
3684 /* FIXME */
3685 if (!netif_queue_stopped(dev))
3686 netif_stop_queue(dev);
3688 rtl8192_rtx_disable(dev);
3690 /* Tx related queue release */
3691 for (i = 0; i < MAX_QUEUE_SIZE; i++)
3692 skb_queue_purge(&priv->ieee80211->skb_waitQ[i]);
3693 for (i = 0; i < MAX_QUEUE_SIZE; i++)
3694 skb_queue_purge(&priv->ieee80211->skb_aggQ[i]);
3696 for (i = 0; i < MAX_QUEUE_SIZE; i++)
3697 skb_queue_purge(&priv->ieee80211->skb_drv_aggQ[i]);
3699 //as cancel_delayed_work will del work->timer, so if work is not defined as struct delayed_work, it will corrupt
3700 rtl8192_cancel_deferred_work(priv);
3701 deinit_hal_dm(dev);
3702 del_timer_sync(&priv->watch_dog_timer);
3705 ieee80211_softmac_stop_protocol(priv->ieee80211);
3706 memset(&priv->ieee80211->current_network, 0, offsetof(struct ieee80211_network, list));
3707 RT_TRACE(COMP_DOWN, "<==========%s()\n", __func__);
3709 return 0;
3713 void rtl8192_commit(struct net_device *dev)
3715 struct r8192_priv *priv = ieee80211_priv(dev);
3716 int reset_status = 0;
3717 if (priv->up == 0) return;
3718 priv->up = 0;
3720 rtl8192_cancel_deferred_work(priv);
3721 del_timer_sync(&priv->watch_dog_timer);
3723 ieee80211_softmac_stop_protocol(priv->ieee80211);
3725 rtl8192_rtx_disable(dev);
3726 reset_status = _rtl8192_up(dev);
3730 void rtl8192_restart(struct work_struct *work)
3732 struct r8192_priv *priv = container_of(work, struct r8192_priv, reset_wq);
3733 struct net_device *dev = priv->ieee80211->dev;
3735 down(&priv->wx_sem);
3737 rtl8192_commit(dev);
3739 up(&priv->wx_sem);
3742 static void r8192_set_multicast(struct net_device *dev)
3744 struct r8192_priv *priv = ieee80211_priv(dev);
3745 short promisc;
3747 /* FIXME FIXME */
3749 promisc = (dev->flags & IFF_PROMISC) ? 1 : 0;
3751 if (promisc != priv->promisc)
3753 priv->promisc = promisc;
3757 int r8192_set_mac_adr(struct net_device *dev, void *mac)
3759 struct r8192_priv *priv = ieee80211_priv(dev);
3760 struct sockaddr *addr = mac;
3762 down(&priv->wx_sem);
3764 memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
3766 schedule_work(&priv->reset_wq);
3767 up(&priv->wx_sem);
3769 return 0;
3772 /* based on ipw2200 driver */
3773 int rtl8192_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
3775 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
3776 struct iwreq *wrq = (struct iwreq *)rq;
3777 int ret = -1;
3778 struct ieee80211_device *ieee = priv->ieee80211;
3779 u32 key[4];
3780 u8 broadcast_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
3781 struct iw_point *p = &wrq->u.data;
3782 struct ieee_param *ipw = NULL;
3784 down(&priv->wx_sem);
3787 if (p->length < sizeof(struct ieee_param) || !p->pointer) {
3788 ret = -EINVAL;
3789 goto out;
3792 ipw = kmalloc(p->length, GFP_KERNEL);
3793 if (ipw == NULL) {
3794 ret = -ENOMEM;
3795 goto out;
3797 if (copy_from_user(ipw, p->pointer, p->length)) {
3798 kfree(ipw);
3799 ret = -EFAULT;
3800 goto out;
3803 switch (cmd) {
3804 case RTL_IOCTL_WPA_SUPPLICANT:
3805 //parse here for HW security
3806 if (ipw->cmd == IEEE_CMD_SET_ENCRYPTION) {
3807 if (ipw->u.crypt.set_tx) {
3808 if (strcmp(ipw->u.crypt.alg, "CCMP") == 0) {
3809 ieee->pairwise_key_type = KEY_TYPE_CCMP;
3810 } else if (strcmp(ipw->u.crypt.alg, "TKIP") == 0) {
3811 ieee->pairwise_key_type = KEY_TYPE_TKIP;
3812 } else if (strcmp(ipw->u.crypt.alg, "WEP") == 0) {
3813 if (ipw->u.crypt.key_len == 13)
3814 ieee->pairwise_key_type = KEY_TYPE_WEP104;
3815 else if (ipw->u.crypt.key_len == 5)
3816 ieee->pairwise_key_type = KEY_TYPE_WEP40;
3817 } else {
3818 ieee->pairwise_key_type = KEY_TYPE_NA;
3821 if (ieee->pairwise_key_type) {
3822 memcpy((u8 *)key, ipw->u.crypt.key, 16);
3823 EnableHWSecurityConfig8192(dev);
3824 //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!
3825 //added by WB.
3826 setKey(dev, 4, ipw->u.crypt.idx, ieee->pairwise_key_type, (u8 *)ieee->ap_mac_addr, 0, key);
3827 if (ieee->auth_mode != 2)
3828 setKey(dev, ipw->u.crypt.idx, ipw->u.crypt.idx, ieee->pairwise_key_type, (u8 *)ieee->ap_mac_addr, 0, key);
3830 } else {
3831 memcpy((u8 *)key, ipw->u.crypt.key, 16);
3832 if (strcmp(ipw->u.crypt.alg, "CCMP") == 0) {
3833 ieee->group_key_type = KEY_TYPE_CCMP;
3834 } else if (strcmp(ipw->u.crypt.alg, "TKIP") == 0) {
3835 ieee->group_key_type = KEY_TYPE_TKIP;
3836 } else if (strcmp(ipw->u.crypt.alg, "WEP") == 0) {
3837 if (ipw->u.crypt.key_len == 13)
3838 ieee->group_key_type = KEY_TYPE_WEP104;
3839 else if (ipw->u.crypt.key_len == 5)
3840 ieee->group_key_type = KEY_TYPE_WEP40;
3841 } else {
3842 ieee->group_key_type = KEY_TYPE_NA;
3845 if (ieee->group_key_type) {
3846 setKey(dev, ipw->u.crypt.idx,
3847 ipw->u.crypt.idx, //KeyIndex
3848 ieee->group_key_type, //KeyType
3849 broadcast_addr, //MacAddr
3850 0, //DefaultKey
3851 key); //KeyContent
3855 ret = ieee80211_wpa_supplicant_ioctl(priv->ieee80211, &wrq->u.data);
3856 break;
3858 default:
3859 ret = -EOPNOTSUPP;
3860 break;
3862 kfree(ipw);
3863 ipw = NULL;
3864 out:
3865 up(&priv->wx_sem);
3866 return ret;
3869 u8 HwRateToMRate90(bool bIsHT, u8 rate)
3871 u8 ret_rate = 0xff;
3873 if (!bIsHT) {
3874 switch (rate) {
3875 case DESC90_RATE1M: ret_rate = MGN_1M; break;
3876 case DESC90_RATE2M: ret_rate = MGN_2M; break;
3877 case DESC90_RATE5_5M: ret_rate = MGN_5_5M; break;
3878 case DESC90_RATE11M: ret_rate = MGN_11M; break;
3879 case DESC90_RATE6M: ret_rate = MGN_6M; break;
3880 case DESC90_RATE9M: ret_rate = MGN_9M; break;
3881 case DESC90_RATE12M: ret_rate = MGN_12M; break;
3882 case DESC90_RATE18M: ret_rate = MGN_18M; break;
3883 case DESC90_RATE24M: ret_rate = MGN_24M; break;
3884 case DESC90_RATE36M: ret_rate = MGN_36M; break;
3885 case DESC90_RATE48M: ret_rate = MGN_48M; break;
3886 case DESC90_RATE54M: ret_rate = MGN_54M; break;
3888 default:
3889 ret_rate = 0xff;
3890 RT_TRACE(COMP_RECV, "HwRateToMRate90(): Non supported Rate [%x], bIsHT = %d!!!\n", rate, bIsHT);
3891 break;
3894 } else {
3895 switch (rate) {
3896 case DESC90_RATEMCS0: ret_rate = MGN_MCS0; break;
3897 case DESC90_RATEMCS1: ret_rate = MGN_MCS1; break;
3898 case DESC90_RATEMCS2: ret_rate = MGN_MCS2; break;
3899 case DESC90_RATEMCS3: ret_rate = MGN_MCS3; break;
3900 case DESC90_RATEMCS4: ret_rate = MGN_MCS4; break;
3901 case DESC90_RATEMCS5: ret_rate = MGN_MCS5; break;
3902 case DESC90_RATEMCS6: ret_rate = MGN_MCS6; break;
3903 case DESC90_RATEMCS7: ret_rate = MGN_MCS7; break;
3904 case DESC90_RATEMCS8: ret_rate = MGN_MCS8; break;
3905 case DESC90_RATEMCS9: ret_rate = MGN_MCS9; break;
3906 case DESC90_RATEMCS10: ret_rate = MGN_MCS10; break;
3907 case DESC90_RATEMCS11: ret_rate = MGN_MCS11; break;
3908 case DESC90_RATEMCS12: ret_rate = MGN_MCS12; break;
3909 case DESC90_RATEMCS13: ret_rate = MGN_MCS13; break;
3910 case DESC90_RATEMCS14: ret_rate = MGN_MCS14; break;
3911 case DESC90_RATEMCS15: ret_rate = MGN_MCS15; break;
3912 case DESC90_RATEMCS32: ret_rate = (0x80|0x20); break;
3914 default:
3915 ret_rate = 0xff;
3916 RT_TRACE(COMP_RECV, "HwRateToMRate90(): Non supported Rate [%x], bIsHT = %d!!!\n", rate, bIsHT);
3917 break;
3921 return ret_rate;
3925 * Function: UpdateRxPktTimeStamp
3926 * Overview: Record the TSF time stamp when receiving a packet
3928 * Input:
3929 * PADAPTER Adapter
3930 * PRT_RFD pRfd,
3932 * Output:
3933 * PRT_RFD pRfd
3934 * (pRfd->Status.TimeStampHigh is updated)
3935 * (pRfd->Status.TimeStampLow is updated)
3936 * Return:
3937 * None
3939 static void UpdateRxPktTimeStamp8190(struct net_device *dev,
3940 struct ieee80211_rx_stats *stats)
3942 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
3944 if (stats->bIsAMPDU && !stats->bFirstMPDU) {
3945 stats->mac_time[0] = priv->LastRxDescTSFLow;
3946 stats->mac_time[1] = priv->LastRxDescTSFHigh;
3947 } else {
3948 priv->LastRxDescTSFLow = stats->mac_time[0];
3949 priv->LastRxDescTSFHigh = stats->mac_time[1];
3953 //by amy 080606
3955 long rtl819x_translate_todbm(u8 signal_strength_index)// 0-100 index.
3957 long signal_power; // in dBm.
3959 // Translate to dBm (x=0.5y-95).
3960 signal_power = (long)((signal_strength_index + 1) >> 1);
3961 signal_power -= 95;
3963 return signal_power;
3967 /* 2008/01/22 MH We can not declare RSSI/EVM total value of sliding window to
3968 be a local static. Otherwise, it may increase when we return from S3/S4. The
3969 value will be kept in memory or disk. Declare the value in the adaptor
3970 and it will be reinitialized when returned from S3/S4. */
3971 void rtl8192_process_phyinfo(struct r8192_priv *priv, u8 *buffer, struct ieee80211_rx_stats *pprevious_stats, struct ieee80211_rx_stats *pcurrent_stats)
3973 bool bcheck = false;
3974 u8 rfpath;
3975 u32 nspatial_stream, tmp_val;
3976 static u32 slide_rssi_index, slide_rssi_statistics;
3977 static u32 slide_evm_index, slide_evm_statistics;
3978 static u32 last_rssi, last_evm;
3980 static u32 slide_beacon_adc_pwdb_index, slide_beacon_adc_pwdb_statistics;
3981 static u32 last_beacon_adc_pwdb;
3983 struct ieee80211_hdr_3addr *hdr;
3984 u16 sc;
3985 unsigned int frag, seq;
3986 hdr = (struct ieee80211_hdr_3addr *)buffer;
3987 sc = le16_to_cpu(hdr->seq_ctl);
3988 frag = WLAN_GET_SEQ_FRAG(sc);
3989 seq = WLAN_GET_SEQ_SEQ(sc);
3990 //cosa add 04292008 to record the sequence number
3991 pcurrent_stats->Seq_Num = seq;
3993 // Check whether we should take the previous packet into accounting
3995 if (!pprevious_stats->bIsAMPDU) {
3996 // if previous packet is not aggregated packet
3997 bcheck = true;
4000 if (slide_rssi_statistics++ >= PHY_RSSI_SLID_WIN_MAX) {
4001 slide_rssi_statistics = PHY_RSSI_SLID_WIN_MAX;
4002 last_rssi = priv->stats.slide_signal_strength[slide_rssi_index];
4003 priv->stats.slide_rssi_total -= last_rssi;
4005 priv->stats.slide_rssi_total += pprevious_stats->SignalStrength;
4007 priv->stats.slide_signal_strength[slide_rssi_index++] = pprevious_stats->SignalStrength;
4008 if (slide_rssi_index >= PHY_RSSI_SLID_WIN_MAX)
4009 slide_rssi_index = 0;
4011 // <1> Showed on UI for user, in dbm
4012 tmp_val = priv->stats.slide_rssi_total/slide_rssi_statistics;
4013 priv->stats.signal_strength = rtl819x_translate_todbm((u8)tmp_val);
4014 pcurrent_stats->rssi = priv->stats.signal_strength;
4016 // If the previous packet does not match the criteria, neglect it
4018 if (!pprevious_stats->bPacketMatchBSSID) {
4019 if (!pprevious_stats->bToSelfBA)
4020 return;
4023 if (!bcheck)
4024 return;
4027 //rtl8190_process_cck_rxpathsel(priv,pprevious_stats);//only rtl8190 supported
4030 // Check RSSI
4032 priv->stats.num_process_phyinfo++;
4034 /* record the general signal strength to the sliding window. */
4037 // <2> Showed on UI for engineering
4038 // hardware does not provide rssi information for each rf path in CCK
4039 if (!pprevious_stats->bIsCCK && (pprevious_stats->bPacketToSelf || pprevious_stats->bToSelfBA)) {
4040 for (rfpath = RF90_PATH_A; rfpath < priv->NumTotalRFPath; rfpath++) {
4041 if (!rtl8192_phy_CheckIsLegalRFPath(priv->ieee80211->dev, rfpath))
4042 continue;
4044 //Fixed by Jacken 2008-03-20
4045 if (priv->stats.rx_rssi_percentage[rfpath] == 0)
4046 priv->stats.rx_rssi_percentage[rfpath] = pprevious_stats->RxMIMOSignalStrength[rfpath];
4047 if (pprevious_stats->RxMIMOSignalStrength[rfpath] > priv->stats.rx_rssi_percentage[rfpath]) {
4048 priv->stats.rx_rssi_percentage[rfpath] =
4049 ((priv->stats.rx_rssi_percentage[rfpath]*(Rx_Smooth_Factor-1)) +
4050 (pprevious_stats->RxMIMOSignalStrength[rfpath])) /(Rx_Smooth_Factor);
4051 priv->stats.rx_rssi_percentage[rfpath] = priv->stats.rx_rssi_percentage[rfpath] + 1;
4052 } else {
4053 priv->stats.rx_rssi_percentage[rfpath] =
4054 ((priv->stats.rx_rssi_percentage[rfpath]*(Rx_Smooth_Factor-1)) +
4055 (pprevious_stats->RxMIMOSignalStrength[rfpath])) /(Rx_Smooth_Factor);
4057 RT_TRACE(COMP_DBG, "priv->stats.rx_rssi_percentage[rfPath] = %d \n", priv->stats.rx_rssi_percentage[rfpath]);
4063 // Check PWDB.
4065 RT_TRACE(COMP_RXDESC, "Smooth %s PWDB = %d\n",
4066 pprevious_stats->bIsCCK ? "CCK" : "OFDM",
4067 pprevious_stats->RxPWDBAll);
4069 if (pprevious_stats->bPacketBeacon) {
4070 /* record the beacon pwdb to the sliding window. */
4071 if (slide_beacon_adc_pwdb_statistics++ >= PHY_Beacon_RSSI_SLID_WIN_MAX) {
4072 slide_beacon_adc_pwdb_statistics = PHY_Beacon_RSSI_SLID_WIN_MAX;
4073 last_beacon_adc_pwdb = priv->stats.Slide_Beacon_pwdb[slide_beacon_adc_pwdb_index];
4074 priv->stats.Slide_Beacon_Total -= last_beacon_adc_pwdb;
4076 priv->stats.Slide_Beacon_Total += pprevious_stats->RxPWDBAll;
4077 priv->stats.Slide_Beacon_pwdb[slide_beacon_adc_pwdb_index] = pprevious_stats->RxPWDBAll;
4078 slide_beacon_adc_pwdb_index++;
4079 if (slide_beacon_adc_pwdb_index >= PHY_Beacon_RSSI_SLID_WIN_MAX)
4080 slide_beacon_adc_pwdb_index = 0;
4081 pprevious_stats->RxPWDBAll = priv->stats.Slide_Beacon_Total/slide_beacon_adc_pwdb_statistics;
4082 if (pprevious_stats->RxPWDBAll >= 3)
4083 pprevious_stats->RxPWDBAll -= 3;
4086 RT_TRACE(COMP_RXDESC, "Smooth %s PWDB = %d\n",
4087 pprevious_stats->bIsCCK ? "CCK" : "OFDM",
4088 pprevious_stats->RxPWDBAll);
4091 if (pprevious_stats->bPacketToSelf || pprevious_stats->bPacketBeacon || pprevious_stats->bToSelfBA) {
4092 if (priv->undecorated_smoothed_pwdb < 0) // initialize
4093 priv->undecorated_smoothed_pwdb = pprevious_stats->RxPWDBAll;
4094 if (pprevious_stats->RxPWDBAll > (u32)priv->undecorated_smoothed_pwdb) {
4095 priv->undecorated_smoothed_pwdb =
4096 (((priv->undecorated_smoothed_pwdb)*(Rx_Smooth_Factor-1)) +
4097 (pprevious_stats->RxPWDBAll)) /(Rx_Smooth_Factor);
4098 priv->undecorated_smoothed_pwdb = priv->undecorated_smoothed_pwdb + 1;
4099 } else {
4100 priv->undecorated_smoothed_pwdb =
4101 (((priv->undecorated_smoothed_pwdb)*(Rx_Smooth_Factor-1)) +
4102 (pprevious_stats->RxPWDBAll)) /(Rx_Smooth_Factor);
4108 // Check EVM
4110 /* record the general EVM to the sliding window. */
4111 if (pprevious_stats->SignalQuality) {
4112 if (pprevious_stats->bPacketToSelf || pprevious_stats->bPacketBeacon || pprevious_stats->bToSelfBA) {
4113 if (slide_evm_statistics++ >= PHY_RSSI_SLID_WIN_MAX) {
4114 slide_evm_statistics = PHY_RSSI_SLID_WIN_MAX;
4115 last_evm = priv->stats.slide_evm[slide_evm_index];
4116 priv->stats.slide_evm_total -= last_evm;
4119 priv->stats.slide_evm_total += pprevious_stats->SignalQuality;
4121 priv->stats.slide_evm[slide_evm_index++] = pprevious_stats->SignalQuality;
4122 if (slide_evm_index >= PHY_RSSI_SLID_WIN_MAX)
4123 slide_evm_index = 0;
4125 // <1> Showed on UI for user, in percentage.
4126 tmp_val = priv->stats.slide_evm_total/slide_evm_statistics;
4127 priv->stats.signal_quality = tmp_val;
4128 //cosa add 10/11/2007, Showed on UI for user in Windows Vista, for Link quality.
4129 priv->stats.last_signal_strength_inpercent = tmp_val;
4132 // <2> Showed on UI for engineering
4133 if (pprevious_stats->bPacketToSelf || pprevious_stats->bPacketBeacon || pprevious_stats->bToSelfBA) {
4134 for (nspatial_stream = 0; nspatial_stream < 2; nspatial_stream++) { // 2 spatial stream
4135 if (pprevious_stats->RxMIMOSignalQuality[nspatial_stream] != -1) {
4136 if (priv->stats.rx_evm_percentage[nspatial_stream] == 0) // initialize
4137 priv->stats.rx_evm_percentage[nspatial_stream] = pprevious_stats->RxMIMOSignalQuality[nspatial_stream];
4138 priv->stats.rx_evm_percentage[nspatial_stream] =
4139 ((priv->stats.rx_evm_percentage[nspatial_stream]* (Rx_Smooth_Factor-1)) +
4140 (pprevious_stats->RxMIMOSignalQuality[nspatial_stream]* 1)) / (Rx_Smooth_Factor);
4149 /*-----------------------------------------------------------------------------
4150 * Function: rtl819x_query_rxpwrpercentage()
4152 * Overview:
4154 * Input: char antpower
4156 * Output: NONE
4158 * Return: 0-100 percentage
4160 * Revised History:
4161 * When Who Remark
4162 * 05/26/2008 amy Create Version 0 porting from windows code.
4164 *---------------------------------------------------------------------------*/
4165 static u8 rtl819x_query_rxpwrpercentage(char antpower)
4167 if ((antpower <= -100) || (antpower >= 20))
4168 return 0;
4169 else if (antpower >= 0)
4170 return 100;
4171 else
4172 return 100 + antpower;
4174 } /* QueryRxPwrPercentage */
4176 static u8 rtl819x_evm_dbtopercentage(char value)
4178 char ret_val;
4180 ret_val = value;
4182 if (ret_val >= 0)
4183 ret_val = 0;
4184 if (ret_val <= -33)
4185 ret_val = -33;
4186 ret_val = 0 - ret_val;
4187 ret_val *= 3;
4188 if (ret_val == 99)
4189 ret_val = 100;
4190 return ret_val;
4193 // Description:
4194 // We want good-looking for signal strength/quality
4195 // 2007/7/19 01:09, by cosa.
4197 static long rtl819x_signal_scale_mapping(long currsig)
4199 long retsig;
4201 // Step 1. Scale mapping.
4202 if (currsig >= 61 && currsig <= 100)
4203 retsig = 90 + ((currsig - 60) / 4);
4204 else if (currsig >= 41 && currsig <= 60)
4205 retsig = 78 + ((currsig - 40) / 2);
4206 else if (currsig >= 31 && currsig <= 40)
4207 retsig = 66 + (currsig - 30);
4208 else if (currsig >= 21 && currsig <= 30)
4209 retsig = 54 + (currsig - 20);
4210 else if (currsig >= 5 && currsig <= 20)
4211 retsig = 42 + (((currsig - 5) * 2) / 3);
4212 else if (currsig == 4)
4213 retsig = 36;
4214 else if (currsig == 3)
4215 retsig = 27;
4216 else if (currsig == 2)
4217 retsig = 18;
4218 else if (currsig == 1)
4219 retsig = 9;
4220 else
4221 retsig = currsig;
4223 return retsig;
4226 static inline bool rx_hal_is_cck_rate(struct rx_drvinfo_819x_usb *pdrvinfo)
4228 if (pdrvinfo->RxHT)
4229 return false;
4231 switch (pdrvinfo->RxRate) {
4232 case DESC90_RATE1M:
4233 case DESC90_RATE2M:
4234 case DESC90_RATE5_5M:
4235 case DESC90_RATE11M:
4236 return true;
4237 default:
4238 return false;
4242 static void rtl8192_query_rxphystatus(struct r8192_priv *priv,
4243 struct ieee80211_rx_stats *pstats,
4244 rx_drvinfo_819x_usb *pdrvinfo,
4245 struct ieee80211_rx_stats *precord_stats,
4246 bool bpacket_match_bssid,
4247 bool bpacket_toself,
4248 bool bPacketBeacon,
4249 bool bToSelfBA)
4251 phy_sts_ofdm_819xusb_t *pofdm_buf;
4252 phy_sts_cck_819xusb_t *pcck_buf;
4253 phy_ofdm_rx_status_rxsc_sgien_exintfflag *prxsc;
4254 u8 *prxpkt;
4255 u8 i, max_spatial_stream, tmp_rxsnr, tmp_rxevm, rxsc_sgien_exflg;
4256 char rx_pwr[4], rx_pwr_all = 0;
4257 char rx_snrX, rx_evmX;
4258 u8 evm, pwdb_all;
4259 u32 RSSI, total_rssi = 0;
4260 u8 is_cck_rate = 0;
4261 u8 rf_rx_num = 0;
4262 u8 sq;
4265 priv->stats.numqry_phystatus++;
4267 is_cck_rate = rx_hal_is_cck_rate(pdrvinfo);
4269 // Record it for next packet processing
4270 memset(precord_stats, 0, sizeof(struct ieee80211_rx_stats));
4271 pstats->bPacketMatchBSSID = precord_stats->bPacketMatchBSSID = bpacket_match_bssid;
4272 pstats->bPacketToSelf = precord_stats->bPacketToSelf = bpacket_toself;
4273 pstats->bIsCCK = precord_stats->bIsCCK = is_cck_rate;
4274 pstats->bPacketBeacon = precord_stats->bPacketBeacon = bPacketBeacon;
4275 pstats->bToSelfBA = precord_stats->bToSelfBA = bToSelfBA;
4277 prxpkt = (u8 *)pdrvinfo;
4279 /* Move pointer to the 16th bytes. Phy status start address. */
4280 prxpkt += sizeof(rx_drvinfo_819x_usb);
4282 /* Initial the cck and ofdm buffer pointer */
4283 pcck_buf = (phy_sts_cck_819xusb_t *)prxpkt;
4284 pofdm_buf = (phy_sts_ofdm_819xusb_t *)prxpkt;
4286 pstats->RxMIMOSignalQuality[0] = -1;
4287 pstats->RxMIMOSignalQuality[1] = -1;
4288 precord_stats->RxMIMOSignalQuality[0] = -1;
4289 precord_stats->RxMIMOSignalQuality[1] = -1;
4291 if (is_cck_rate) {
4293 // (1)Hardware does not provide RSSI for CCK
4297 // (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive)
4299 u8 report;
4301 priv->stats.numqry_phystatusCCK++;
4303 if (!priv->bCckHighPower) {
4304 report = pcck_buf->cck_agc_rpt & 0xc0;
4305 report = report>>6;
4306 switch (report) {
4307 //Fixed by Jacken from Bryant 2008-03-20
4308 //Original value is -38 , -26 , -14 , -2
4309 //Fixed value is -35 , -23 , -11 , 6
4310 case 0x3:
4311 rx_pwr_all = -35 - (pcck_buf->cck_agc_rpt & 0x3e);
4312 break;
4313 case 0x2:
4314 rx_pwr_all = -23 - (pcck_buf->cck_agc_rpt & 0x3e);
4315 break;
4316 case 0x1:
4317 rx_pwr_all = -11 - (pcck_buf->cck_agc_rpt & 0x3e);
4318 break;
4319 case 0x0:
4320 rx_pwr_all = 6 - (pcck_buf->cck_agc_rpt & 0x3e);
4321 break;
4323 } else {
4324 report = pcck_buf->cck_agc_rpt & 0x60;
4325 report = report>>5;
4326 switch (report) {
4327 case 0x3:
4328 rx_pwr_all = -35 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1);
4329 break;
4330 case 0x2:
4331 rx_pwr_all = -23 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1);
4332 break;
4333 case 0x1:
4334 rx_pwr_all = -11 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1);
4335 break;
4336 case 0x0:
4337 rx_pwr_all = 6 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1);
4338 break;
4342 pwdb_all = rtl819x_query_rxpwrpercentage(rx_pwr_all);
4343 pstats->RxPWDBAll = precord_stats->RxPWDBAll = pwdb_all;
4344 pstats->RecvSignalPower = pwdb_all;
4347 // (3) Get Signal Quality (EVM)
4350 if (pstats->RxPWDBAll > 40) {
4351 sq = 100;
4352 } else {
4353 sq = pcck_buf->sq_rpt;
4355 if (pcck_buf->sq_rpt > 64)
4356 sq = 0;
4357 else if (pcck_buf->sq_rpt < 20)
4358 sq = 100;
4359 else
4360 sq = ((64-sq) * 100) / 44;
4362 pstats->SignalQuality = precord_stats->SignalQuality = sq;
4363 pstats->RxMIMOSignalQuality[0] = precord_stats->RxMIMOSignalQuality[0] = sq;
4364 pstats->RxMIMOSignalQuality[1] = precord_stats->RxMIMOSignalQuality[1] = -1;
4366 } else {
4367 priv->stats.numqry_phystatusHT++;
4369 // (1)Get RSSI for HT rate
4371 for (i = RF90_PATH_A; i < priv->NumTotalRFPath; i++) {
4372 // 2008/01/30 MH we will judge RF RX path now.
4373 if (priv->brfpath_rxenable[i])
4374 rf_rx_num++;
4375 else
4376 continue;
4378 if (!rtl8192_phy_CheckIsLegalRFPath(priv->ieee80211->dev, i))
4379 continue;
4381 //Fixed by Jacken from Bryant 2008-03-20
4382 //Original value is 106
4383 rx_pwr[i] = ((pofdm_buf->trsw_gain_X[i]&0x3F)*2) - 106;
4385 //Get Rx snr value in DB
4386 tmp_rxsnr = pofdm_buf->rxsnr_X[i];
4387 rx_snrX = (char)(tmp_rxsnr);
4388 rx_snrX /= 2;
4389 priv->stats.rxSNRdB[i] = (long)rx_snrX;
4391 /* Translate DBM to percentage. */
4392 RSSI = rtl819x_query_rxpwrpercentage(rx_pwr[i]);
4393 total_rssi += RSSI;
4395 /* Record Signal Strength for next packet */
4396 pstats->RxMIMOSignalStrength[i] = (u8) RSSI;
4397 precord_stats->RxMIMOSignalStrength[i] = (u8) RSSI;
4402 // (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive)
4404 //Fixed by Jacken from Bryant 2008-03-20
4405 //Original value is 106
4406 rx_pwr_all = (((pofdm_buf->pwdb_all) >> 1)& 0x7f) -106;
4407 pwdb_all = rtl819x_query_rxpwrpercentage(rx_pwr_all);
4409 pstats->RxPWDBAll = precord_stats->RxPWDBAll = pwdb_all;
4410 pstats->RxPower = precord_stats->RxPower = rx_pwr_all;
4413 // (3)EVM of HT rate
4415 if (pdrvinfo->RxHT && pdrvinfo->RxRate >= DESC90_RATEMCS8 &&
4416 pdrvinfo->RxRate <= DESC90_RATEMCS15)
4417 max_spatial_stream = 2; //both spatial stream make sense
4418 else
4419 max_spatial_stream = 1; //only spatial stream 1 makes sense
4421 for (i = 0; i < max_spatial_stream; i++) {
4422 tmp_rxevm = pofdm_buf->rxevm_X[i];
4423 rx_evmX = (char)(tmp_rxevm);
4425 // Do not use shift operation like "rx_evmX >>= 1" because the compiler of free build environment
4426 // will set the most significant bit to "zero" when doing shifting operation which may change a negative
4427 // value to positive one, then the dbm value (which is supposed to be negative) is not correct anymore.
4428 rx_evmX /= 2; //dbm
4430 evm = rtl819x_evm_dbtopercentage(rx_evmX);
4431 if (i == 0) // Fill value in RFD, Get the first spatial stream only
4432 pstats->SignalQuality = precord_stats->SignalQuality = (u8)(evm & 0xff);
4433 pstats->RxMIMOSignalQuality[i] = precord_stats->RxMIMOSignalQuality[i] = (u8)(evm & 0xff);
4437 /* record rx statistics for debug */
4438 rxsc_sgien_exflg = pofdm_buf->rxsc_sgien_exflg;
4439 prxsc = (phy_ofdm_rx_status_rxsc_sgien_exintfflag *)&rxsc_sgien_exflg;
4440 if (pdrvinfo->BW) //40M channel
4441 priv->stats.received_bwtype[1+prxsc->rxsc]++;
4442 else //20M channel
4443 priv->stats.received_bwtype[0]++;
4446 //UI BSS List signal strength(in percentage), make it good looking, from 0~100.
4447 //It is assigned to the BSS List in GetValueFromBeaconOrProbeRsp().
4448 if (is_cck_rate) {
4449 pstats->SignalStrength = precord_stats->SignalStrength = (u8)(rtl819x_signal_scale_mapping((long)pwdb_all));
4450 } else {
4451 // We can judge RX path number now.
4452 if (rf_rx_num != 0)
4453 pstats->SignalStrength = precord_stats->SignalStrength = (u8)(rtl819x_signal_scale_mapping((long)(total_rssi /= rf_rx_num)));
4455 } /* QueryRxPhyStatus8190Pci */
4457 void rtl8192_record_rxdesc_forlateruse(struct ieee80211_rx_stats *psrc_stats,
4458 struct ieee80211_rx_stats *ptarget_stats)
4460 ptarget_stats->bIsAMPDU = psrc_stats->bIsAMPDU;
4461 ptarget_stats->bFirstMPDU = psrc_stats->bFirstMPDU;
4462 ptarget_stats->Seq_Num = psrc_stats->Seq_Num;
4466 static void TranslateRxSignalStuff819xUsb(struct sk_buff *skb,
4467 struct ieee80211_rx_stats *pstats,
4468 rx_drvinfo_819x_usb *pdrvinfo)
4470 // TODO: We must only check packet for current MAC address. Not finish
4471 rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
4472 struct net_device *dev = info->dev;
4473 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
4474 bool bpacket_match_bssid, bpacket_toself;
4475 bool bPacketBeacon = FALSE, bToSelfBA = FALSE;
4476 static struct ieee80211_rx_stats previous_stats;
4477 struct ieee80211_hdr_3addr *hdr;//by amy
4478 u16 fc, type;
4480 // Get Signal Quality for only RX data queue (but not command queue)
4482 u8 *tmp_buf;
4483 u8 *praddr;
4485 /* Get MAC frame start address. */
4486 tmp_buf = (u8 *)skb->data;
4488 hdr = (struct ieee80211_hdr_3addr *)tmp_buf;
4489 fc = le16_to_cpu(hdr->frame_ctl);
4490 type = WLAN_FC_GET_TYPE(fc);
4491 praddr = hdr->addr1;
4493 /* Check if the received packet is acceptable. */
4494 bpacket_match_bssid = ((IEEE80211_FTYPE_CTL != type) &&
4495 (eqMacAddr(priv->ieee80211->current_network.bssid, (fc & IEEE80211_FCTL_TODS) ? hdr->addr1 : (fc & IEEE80211_FCTL_FROMDS) ? hdr->addr2 : hdr->addr3))
4496 && (!pstats->bHwError) && (!pstats->bCRC) && (!pstats->bICV));
4497 bpacket_toself = bpacket_match_bssid & (eqMacAddr(praddr, priv->ieee80211->dev->dev_addr));
4499 if (WLAN_FC_GET_FRAMETYPE(fc) == IEEE80211_STYPE_BEACON)
4500 bPacketBeacon = true;
4501 if (WLAN_FC_GET_FRAMETYPE(fc) == IEEE80211_STYPE_BLOCKACK) {
4502 if ((eqMacAddr(praddr, dev->dev_addr)))
4503 bToSelfBA = true;
4508 if (bpacket_match_bssid)
4509 priv->stats.numpacket_matchbssid++;
4510 if (bpacket_toself)
4511 priv->stats.numpacket_toself++;
4513 // Process PHY information for previous packet (RSSI/PWDB/EVM)
4515 // Because phy information is contained in the last packet of AMPDU only, so driver
4516 // should process phy information of previous packet
4517 rtl8192_process_phyinfo(priv, tmp_buf, &previous_stats, pstats);
4518 rtl8192_query_rxphystatus(priv, pstats, pdrvinfo, &previous_stats, bpacket_match_bssid, bpacket_toself, bPacketBeacon, bToSelfBA);
4519 rtl8192_record_rxdesc_forlateruse(pstats, &previous_stats);
4524 * Function: UpdateReceivedRateHistogramStatistics
4525 * Overview: Record the received data rate
4527 * Input:
4528 * struct net_device *dev
4529 * struct ieee80211_rx_stats *stats
4531 * Output:
4533 * (priv->stats.ReceivedRateHistogram[] is updated)
4534 * Return:
4535 * None
4537 static void
4538 UpdateReceivedRateHistogramStatistics8190(struct net_device *dev,
4539 struct ieee80211_rx_stats *stats)
4541 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
4542 u32 rcvType = 1; //0: Total, 1:OK, 2:CRC, 3:ICV
4543 u32 rateIndex;
4544 u32 preamble_guardinterval; //1: short preamble/GI, 0: long preamble/GI
4547 if (stats->bCRC)
4548 rcvType = 2;
4549 else if (stats->bICV)
4550 rcvType = 3;
4552 if (stats->bShortPreamble)
4553 preamble_guardinterval = 1;// short
4554 else
4555 preamble_guardinterval = 0;// long
4557 switch (stats->rate) {
4559 // CCK rate
4561 case MGN_1M: rateIndex = 0; break;
4562 case MGN_2M: rateIndex = 1; break;
4563 case MGN_5_5M: rateIndex = 2; break;
4564 case MGN_11M: rateIndex = 3; break;
4566 // Legacy OFDM rate
4568 case MGN_6M: rateIndex = 4; break;
4569 case MGN_9M: rateIndex = 5; break;
4570 case MGN_12M: rateIndex = 6; break;
4571 case MGN_18M: rateIndex = 7; break;
4572 case MGN_24M: rateIndex = 8; break;
4573 case MGN_36M: rateIndex = 9; break;
4574 case MGN_48M: rateIndex = 10; break;
4575 case MGN_54M: rateIndex = 11; break;
4577 // 11n High throughput rate
4579 case MGN_MCS0: rateIndex = 12; break;
4580 case MGN_MCS1: rateIndex = 13; break;
4581 case MGN_MCS2: rateIndex = 14; break;
4582 case MGN_MCS3: rateIndex = 15; break;
4583 case MGN_MCS4: rateIndex = 16; break;
4584 case MGN_MCS5: rateIndex = 17; break;
4585 case MGN_MCS6: rateIndex = 18; break;
4586 case MGN_MCS7: rateIndex = 19; break;
4587 case MGN_MCS8: rateIndex = 20; break;
4588 case MGN_MCS9: rateIndex = 21; break;
4589 case MGN_MCS10: rateIndex = 22; break;
4590 case MGN_MCS11: rateIndex = 23; break;
4591 case MGN_MCS12: rateIndex = 24; break;
4592 case MGN_MCS13: rateIndex = 25; break;
4593 case MGN_MCS14: rateIndex = 26; break;
4594 case MGN_MCS15: rateIndex = 27; break;
4595 default: rateIndex = 28; break;
4597 priv->stats.received_preamble_GI[preamble_guardinterval][rateIndex]++;
4598 priv->stats.received_rate_histogram[0][rateIndex]++; //total
4599 priv->stats.received_rate_histogram[rcvType][rateIndex]++;
4603 static void query_rxdesc_status(struct sk_buff *skb,
4604 struct ieee80211_rx_stats *stats,
4605 bool bIsRxAggrSubframe)
4607 rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
4608 struct net_device *dev = info->dev;
4609 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
4610 rx_drvinfo_819x_usb *driver_info = NULL;
4613 //Get Rx Descriptor Information
4615 #ifdef USB_RX_AGGREGATION_SUPPORT
4616 if (bIsRxAggrSubframe) {
4617 rx_desc_819x_usb_aggr_subframe *desc = (rx_desc_819x_usb_aggr_subframe *)skb->data;
4618 stats->Length = desc->Length;
4619 stats->RxDrvInfoSize = desc->RxDrvInfoSize;
4620 stats->RxBufShift = 0; //RxBufShift = 2 in RxDesc, but usb didn't shift bytes in fact.
4621 stats->bICV = desc->ICV;
4622 stats->bCRC = desc->CRC32;
4623 stats->bHwError = stats->bCRC|stats->bICV;
4624 stats->Decrypted = !desc->SWDec;//RTL8190 set this bit to indicate that Hw does not decrypt packet
4625 } else
4626 #endif
4628 rx_desc_819x_usb *desc = (rx_desc_819x_usb *)skb->data;
4630 stats->Length = desc->Length;
4631 stats->RxDrvInfoSize = desc->RxDrvInfoSize;
4632 stats->RxBufShift = 0;
4633 stats->bICV = desc->ICV;
4634 stats->bCRC = desc->CRC32;
4635 stats->bHwError = stats->bCRC|stats->bICV;
4636 //RTL8190 set this bit to indicate that Hw does not decrypt packet
4637 stats->Decrypted = !desc->SWDec;
4640 if ((priv->ieee80211->pHTInfo->bCurrentHTSupport == true) && (priv->ieee80211->pairwise_key_type == KEY_TYPE_CCMP))
4641 stats->bHwError = false;
4642 else
4643 stats->bHwError = stats->bCRC|stats->bICV;
4645 if (stats->Length < 24 || stats->Length > MAX_8192U_RX_SIZE)
4646 stats->bHwError |= 1;
4648 //Get Driver Info
4650 // TODO: Need to verify it on FGPA platform
4651 //Driver info are written to the RxBuffer following rx desc
4652 if (stats->RxDrvInfoSize != 0) {
4653 driver_info = (rx_drvinfo_819x_usb *)(skb->data + sizeof(rx_desc_819x_usb) +
4654 stats->RxBufShift);
4655 /* unit: 0.5M */
4656 /* TODO */
4657 if (!stats->bHwError) {
4658 u8 ret_rate;
4659 ret_rate = HwRateToMRate90(driver_info->RxHT, driver_info->RxRate);
4660 if (ret_rate == 0xff) {
4661 // Abnormal Case: Receive CRC OK packet with Rx descriptor indicating non supported rate.
4662 // Special Error Handling here, 2008.05.16, by Emily
4664 stats->bHwError = 1;
4665 stats->rate = MGN_1M; //Set 1M rate by default
4666 } else {
4667 stats->rate = ret_rate;
4669 } else {
4670 stats->rate = 0x02;
4673 stats->bShortPreamble = driver_info->SPLCP;
4676 UpdateReceivedRateHistogramStatistics8190(dev, stats);
4678 stats->bIsAMPDU = (driver_info->PartAggr == 1);
4679 stats->bFirstMPDU = (driver_info->PartAggr == 1) && (driver_info->FirstAGGR == 1);
4680 stats->TimeStampLow = driver_info->TSFL;
4681 // xiong mask it, 070514
4683 UpdateRxPktTimeStamp8190(dev, stats);
4686 // Rx A-MPDU
4688 if (driver_info->FirstAGGR == 1 || driver_info->PartAggr == 1)
4689 RT_TRACE(COMP_RXDESC, "driver_info->FirstAGGR = %d, driver_info->PartAggr = %d\n",
4690 driver_info->FirstAGGR, driver_info->PartAggr);
4694 skb_pull(skb, sizeof(rx_desc_819x_usb));
4696 // Get Total offset of MPDU Frame Body
4698 if ((stats->RxBufShift + stats->RxDrvInfoSize) > 0) {
4699 stats->bShift = 1;
4700 skb_pull(skb, stats->RxBufShift + stats->RxDrvInfoSize);
4703 #ifdef USB_RX_AGGREGATION_SUPPORT
4704 /* for the rx aggregated sub frame, the redundant space truly contained in the packet */
4705 if (bIsRxAggrSubframe)
4706 skb_pull(skb, 8);
4707 #endif
4708 /* for debug 2008.5.29 */
4710 //added by vivi, for MP, 20080108
4711 stats->RxIs40MHzPacket = driver_info->BW;
4712 if (stats->RxDrvInfoSize != 0)
4713 TranslateRxSignalStuff819xUsb(skb, stats, driver_info);
4717 u32 GetRxPacketShiftBytes819xUsb(struct ieee80211_rx_stats *Status, bool bIsRxAggrSubframe)
4719 #ifdef USB_RX_AGGREGATION_SUPPORT
4720 if (bIsRxAggrSubframe)
4721 return (sizeof(rx_desc_819x_usb) + Status->RxDrvInfoSize
4722 + Status->RxBufShift + 8);
4723 else
4724 #endif
4725 return (sizeof(rx_desc_819x_usb) + Status->RxDrvInfoSize
4726 + Status->RxBufShift);
4729 void rtl8192_rx_nomal(struct sk_buff *skb)
4731 rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
4732 struct net_device *dev = info->dev;
4733 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
4734 struct ieee80211_rx_stats stats = {
4735 .signal = 0,
4736 .noise = -98,
4737 .rate = 0,
4738 .freq = IEEE80211_24GHZ_BAND,
4740 u32 rx_pkt_len = 0;
4741 struct ieee80211_hdr_1addr *ieee80211_hdr = NULL;
4742 bool unicast_packet = false;
4743 #ifdef USB_RX_AGGREGATION_SUPPORT
4744 struct sk_buff *agg_skb = NULL;
4745 u32 TotalLength = 0;
4746 u32 TempDWord = 0;
4747 u32 PacketLength = 0;
4748 u32 PacketOccupiedLendth = 0;
4749 u8 TempByte = 0;
4750 u32 PacketShiftBytes = 0;
4751 rx_desc_819x_usb_aggr_subframe *RxDescr = NULL;
4752 u8 PaddingBytes = 0;
4753 //add just for testing
4754 u8 testing;
4756 #endif
4758 /* 20 is for ps-poll */
4759 if ((skb->len >= (20 + sizeof(rx_desc_819x_usb))) && (skb->len < RX_URB_SIZE)) {
4760 #ifdef USB_RX_AGGREGATION_SUPPORT
4761 TempByte = *(skb->data + sizeof(rx_desc_819x_usb));
4762 #endif
4763 /* first packet should not contain Rx aggregation header */
4764 query_rxdesc_status(skb, &stats, false);
4765 /* TODO */
4766 /* hardware related info */
4767 #ifdef USB_RX_AGGREGATION_SUPPORT
4768 if (TempByte & BIT0) {
4769 agg_skb = skb;
4770 TotalLength = stats.Length - 4; /*sCrcLng*/
4771 /* though the head pointer has passed this position */
4772 TempDWord = *(u32 *)(agg_skb->data - 4);
4773 PacketLength = (u16)(TempDWord & 0x3FFF); /*sCrcLng*/
4774 skb = dev_alloc_skb(PacketLength);
4775 memcpy(skb_put(skb, PacketLength), agg_skb->data, PacketLength);
4776 PacketShiftBytes = GetRxPacketShiftBytes819xUsb(&stats, false);
4778 #endif
4779 /* Process the MPDU received */
4780 skb_trim(skb, skb->len - 4/*sCrcLng*/);
4782 rx_pkt_len = skb->len;
4783 ieee80211_hdr = (struct ieee80211_hdr_1addr *)skb->data;
4784 unicast_packet = false;
4785 if (is_broadcast_ether_addr(ieee80211_hdr->addr1)) {
4786 //TODO
4787 } else if (is_multicast_ether_addr(ieee80211_hdr->addr1)) {
4788 //TODO
4789 } else {
4790 /* unicast packet */
4791 unicast_packet = true;
4794 if (!ieee80211_rx(priv->ieee80211, skb, &stats)) {
4795 dev_kfree_skb_any(skb);
4796 } else {
4797 priv->stats.rxoktotal++;
4798 if (unicast_packet)
4799 priv->stats.rxbytesunicast += rx_pkt_len;
4801 #ifdef USB_RX_AGGREGATION_SUPPORT
4802 testing = 1;
4803 if (TotalLength > 0) {
4804 PacketOccupiedLendth = PacketLength + (PacketShiftBytes + 8);
4805 if ((PacketOccupiedLendth & 0xFF) != 0)
4806 PacketOccupiedLendth = (PacketOccupiedLendth & 0xFFFFFF00) + 256;
4807 PacketOccupiedLendth -= 8;
4808 TempDWord = PacketOccupiedLendth - PacketShiftBytes; /*- PacketLength */
4809 if (agg_skb->len > TempDWord)
4810 skb_pull(agg_skb, TempDWord);
4811 else
4812 agg_skb->len = 0;
4814 while (agg_skb->len >= GetRxPacketShiftBytes819xUsb(&stats, true)) {
4815 u8 tmpCRC = 0, tmpICV = 0;
4816 RxDescr = (rx_desc_819x_usb_aggr_subframe *)(agg_skb->data);
4817 tmpCRC = RxDescr->CRC32;
4818 tmpICV = RxDescr->ICV;
4819 memcpy(agg_skb->data, &agg_skb->data[44], 2);
4820 RxDescr->CRC32 = tmpCRC;
4821 RxDescr->ICV = tmpICV;
4823 memset(&stats, 0, sizeof(struct ieee80211_rx_stats));
4824 stats.signal = 0;
4825 stats.noise = -98;
4826 stats.rate = 0;
4827 stats.freq = IEEE80211_24GHZ_BAND;
4828 query_rxdesc_status(agg_skb, &stats, true);
4829 PacketLength = stats.Length;
4831 if (PacketLength > agg_skb->len)
4832 break;
4833 /* Process the MPDU received */
4834 skb = dev_alloc_skb(PacketLength);
4835 memcpy(skb_put(skb, PacketLength), agg_skb->data, PacketLength);
4836 skb_trim(skb, skb->len - 4/*sCrcLng*/);
4838 rx_pkt_len = skb->len;
4839 ieee80211_hdr = (struct ieee80211_hdr_1addr *)skb->data;
4840 unicast_packet = false;
4841 if (is_broadcast_ether_addr(ieee80211_hdr->addr1)) {
4842 //TODO
4843 } else if (is_multicast_ether_addr(ieee80211_hdr->addr1)) {
4844 //TODO
4845 } else {
4846 /* unicast packet */
4847 unicast_packet = true;
4849 if (!ieee80211_rx(priv->ieee80211, skb, &stats)) {
4850 dev_kfree_skb_any(skb);
4851 } else {
4852 priv->stats.rxoktotal++;
4853 if (unicast_packet)
4854 priv->stats.rxbytesunicast += rx_pkt_len;
4856 /* should trim the packet which has been copied to target skb */
4857 skb_pull(agg_skb, PacketLength);
4858 PacketShiftBytes = GetRxPacketShiftBytes819xUsb(&stats, true);
4859 PacketOccupiedLendth = PacketLength + PacketShiftBytes;
4860 if ((PacketOccupiedLendth & 0xFF) != 0) {
4861 PaddingBytes = 256 - (PacketOccupiedLendth & 0xFF);
4862 if (agg_skb->len > PaddingBytes)
4863 skb_pull(agg_skb, PaddingBytes);
4864 else
4865 agg_skb->len = 0;
4868 dev_kfree_skb(agg_skb);
4870 #endif
4871 } else {
4872 priv->stats.rxurberr++;
4873 netdev_dbg(dev, "actual_length: %d\n", skb->len);
4874 dev_kfree_skb_any(skb);
4879 void rtl819xusb_process_received_packet(struct net_device *dev,
4880 struct ieee80211_rx_stats *pstats)
4882 u8 *frame;
4883 u16 frame_len = 0;
4884 struct r8192_priv *priv = ieee80211_priv(dev);
4886 // Get shifted bytes of Starting address of 802.11 header. 2006.09.28, by Emily
4887 //porting by amy 080508
4888 pstats->virtual_address += get_rxpacket_shiftbytes_819xusb(pstats);
4889 frame = pstats->virtual_address;
4890 frame_len = pstats->packetlength;
4891 #ifdef TODO // by amy about HCT
4892 if (!Adapter->bInHctTest)
4893 CountRxErrStatistics(Adapter, pRfd);
4894 #endif
4895 #ifdef ENABLE_PS //by amy for adding ps function in future
4896 RT_RF_POWER_STATE rtState;
4897 // When RF is off, we should not count the packet for hw/sw synchronize
4898 // reason, ie. there may be a duration while sw switch is changed and hw
4899 // switch is being changed. 2006.12.04, by shien chang.
4900 Adapter->HalFunc.GetHwRegHandler(Adapter, HW_VAR_RF_STATE, (u8 *)(&rtState));
4901 if (rtState == eRfOff)
4902 return;
4903 #endif
4904 priv->stats.rxframgment++;
4906 #ifdef TODO
4907 RmMonitorSignalStrength(Adapter, pRfd);
4908 #endif
4909 /* 2007/01/16 MH Add RX command packet handle here. */
4910 /* 2007/03/01 MH We have to release RFD and return if rx pkt is cmd pkt. */
4911 if (rtl819xusb_rx_command_packet(dev, pstats))
4912 return;
4914 #ifdef SW_CRC_CHECK
4915 SwCrcCheck();
4916 #endif
4921 static void query_rx_cmdpkt_desc_status(struct sk_buff *skb,
4922 struct ieee80211_rx_stats *stats)
4924 rx_desc_819x_usb *desc = (rx_desc_819x_usb *)skb->data;
4927 //Get Rx Descriptor Information
4929 stats->virtual_address = (u8 *)skb->data;
4930 stats->Length = desc->Length;
4931 stats->RxDrvInfoSize = 0;
4932 stats->RxBufShift = 0;
4933 stats->packetlength = stats->Length-scrclng;
4934 stats->fraglength = stats->packetlength;
4935 stats->fragoffset = 0;
4936 stats->ntotalfrag = 1;
4940 void rtl8192_rx_cmd(struct sk_buff *skb)
4942 struct rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
4943 struct net_device *dev = info->dev;
4944 /* TODO */
4945 struct ieee80211_rx_stats stats = {
4946 .signal = 0,
4947 .noise = -98,
4948 .rate = 0,
4949 .freq = IEEE80211_24GHZ_BAND,
4952 if ((skb->len >= (20 + sizeof(rx_desc_819x_usb))) && (skb->len < RX_URB_SIZE)) {
4954 query_rx_cmdpkt_desc_status(skb, &stats);
4955 // this is to be done by amy 080508 prfd->queue_id = 1;
4959 // Process the command packet received.
4962 rtl819xusb_process_received_packet(dev, &stats);
4964 dev_kfree_skb_any(skb);
4968 void rtl8192_irq_rx_tasklet(struct r8192_priv *priv)
4970 struct sk_buff *skb;
4971 struct rtl8192_rx_info *info;
4973 while (NULL != (skb = skb_dequeue(&priv->skb_queue))) {
4974 info = (struct rtl8192_rx_info *)skb->cb;
4975 switch (info->out_pipe) {
4976 /* Nomal packet pipe */
4977 case 3:
4978 priv->IrpPendingCount--;
4979 rtl8192_rx_nomal(skb);
4980 break;
4982 /* Command packet pipe */
4983 case 9:
4984 RT_TRACE(COMP_RECV, "command in-pipe index(%d)\n",
4985 info->out_pipe);
4987 rtl8192_rx_cmd(skb);
4988 break;
4990 default: /* should never get here! */
4991 RT_TRACE(COMP_ERR, "Unknown in-pipe index(%d)\n",
4992 info->out_pipe);
4993 dev_kfree_skb(skb);
4994 break;
5000 static const struct net_device_ops rtl8192_netdev_ops = {
5001 .ndo_open = rtl8192_open,
5002 .ndo_stop = rtl8192_close,
5003 .ndo_get_stats = rtl8192_stats,
5004 .ndo_tx_timeout = tx_timeout,
5005 .ndo_do_ioctl = rtl8192_ioctl,
5006 .ndo_set_rx_mode = r8192_set_multicast,
5007 .ndo_set_mac_address = r8192_set_mac_adr,
5008 .ndo_validate_addr = eth_validate_addr,
5009 .ndo_change_mtu = eth_change_mtu,
5010 .ndo_start_xmit = ieee80211_xmit,
5014 /****************************************************************************
5015 ---------------------------- USB_STUFF---------------------------
5016 *****************************************************************************/
5018 static int rtl8192_usb_probe(struct usb_interface *intf,
5019 const struct usb_device_id *id)
5021 struct net_device *dev = NULL;
5022 struct r8192_priv *priv = NULL;
5023 struct usb_device *udev = interface_to_usbdev(intf);
5024 int ret;
5025 RT_TRACE(COMP_INIT, "Oops: i'm coming\n");
5027 dev = alloc_ieee80211(sizeof(struct r8192_priv));
5028 if (dev == NULL)
5029 return -ENOMEM;
5031 usb_set_intfdata(intf, dev);
5032 SET_NETDEV_DEV(dev, &intf->dev);
5033 priv = ieee80211_priv(dev);
5034 priv->ieee80211 = netdev_priv(dev);
5035 priv->udev = udev;
5037 dev->netdev_ops = &rtl8192_netdev_ops;
5039 #if WIRELESS_EXT >= 12
5040 #if WIRELESS_EXT < 17
5041 dev->get_wireless_stats = r8192_get_wireless_stats;
5042 #endif
5043 dev->wireless_handlers = (struct iw_handler_def *) &r8192_wx_handlers_def;
5044 #endif
5045 dev->type = ARPHRD_ETHER;
5047 dev->watchdog_timeo = HZ*3; //modified by john, 0805
5049 if (dev_alloc_name(dev, ifname) < 0) {
5050 RT_TRACE(COMP_INIT, "Oops: devname already taken! Trying wlan%%d...\n");
5051 ifname = "wlan%d";
5052 dev_alloc_name(dev, ifname);
5055 RT_TRACE(COMP_INIT, "Driver probe completed1\n");
5056 if (rtl8192_init(dev) != 0) {
5057 RT_TRACE(COMP_ERR, "Initialization failed");
5058 ret = -ENODEV;
5059 goto fail;
5061 netif_carrier_off(dev);
5062 netif_stop_queue(dev);
5064 ret = register_netdev(dev);
5065 if (ret)
5066 goto fail2;
5068 RT_TRACE(COMP_INIT, "dev name=======> %s\n", dev->name);
5069 rtl8192_proc_init_one(dev);
5072 RT_TRACE(COMP_INIT, "Driver probe completed\n");
5073 return 0;
5075 fail2:
5076 rtl8192_down(dev);
5077 kfree(priv->pFirmware);
5078 priv->pFirmware = NULL;
5079 rtl8192_usb_deleteendpoints(dev);
5080 destroy_workqueue(priv->priv_wq);
5081 mdelay(10);
5082 fail:
5083 free_ieee80211(dev);
5085 RT_TRACE(COMP_ERR, "wlan driver load failed\n");
5086 return ret;
5089 //detach all the work and timer structure declared or inititialize in r8192U_init function.
5090 void rtl8192_cancel_deferred_work(struct r8192_priv *priv)
5093 cancel_work_sync(&priv->reset_wq);
5094 cancel_delayed_work(&priv->watch_dog_wq);
5095 cancel_delayed_work(&priv->update_beacon_wq);
5096 cancel_work_sync(&priv->qos_activate);
5100 static void rtl8192_usb_disconnect(struct usb_interface *intf)
5102 struct net_device *dev = usb_get_intfdata(intf);
5104 struct r8192_priv *priv = ieee80211_priv(dev);
5105 if (dev) {
5107 unregister_netdev(dev);
5109 RT_TRACE(COMP_DOWN, "=============>wlan driver to be removed\n");
5110 rtl8192_proc_remove_one(dev);
5112 rtl8192_down(dev);
5113 kfree(priv->pFirmware);
5114 priv->pFirmware = NULL;
5115 rtl8192_usb_deleteendpoints(dev);
5116 destroy_workqueue(priv->priv_wq);
5117 mdelay(10);
5120 free_ieee80211(dev);
5121 RT_TRACE(COMP_DOWN, "wlan driver removed\n");
5124 /* fun with the built-in ieee80211 stack... */
5125 extern int ieee80211_debug_init(void);
5126 extern void ieee80211_debug_exit(void);
5127 extern int ieee80211_crypto_init(void);
5128 extern void ieee80211_crypto_deinit(void);
5129 extern int ieee80211_crypto_tkip_init(void);
5130 extern void ieee80211_crypto_tkip_exit(void);
5131 extern int ieee80211_crypto_ccmp_init(void);
5132 extern void ieee80211_crypto_ccmp_exit(void);
5133 extern int ieee80211_crypto_wep_init(void);
5134 extern void ieee80211_crypto_wep_exit(void);
5136 static int __init rtl8192_usb_module_init(void)
5138 int ret;
5140 #ifdef CONFIG_IEEE80211_DEBUG
5141 ret = ieee80211_debug_init();
5142 if (ret) {
5143 pr_err("ieee80211_debug_init() failed %d\n", ret);
5144 return ret;
5146 #endif
5147 ret = ieee80211_crypto_init();
5148 if (ret) {
5149 pr_err("ieee80211_crypto_init() failed %d\n", ret);
5150 return ret;
5153 ret = ieee80211_crypto_tkip_init();
5154 if (ret) {
5155 pr_err("ieee80211_crypto_tkip_init() failed %d\n", ret);
5156 return ret;
5159 ret = ieee80211_crypto_ccmp_init();
5160 if (ret) {
5161 pr_err("ieee80211_crypto_ccmp_init() failed %d\n", ret);
5162 return ret;
5165 ret = ieee80211_crypto_wep_init();
5166 if (ret) {
5167 pr_err("ieee80211_crypto_wep_init() failed %d\n", ret);
5168 return ret;
5171 pr_info("\nLinux kernel driver for RTL8192 based WLAN cards\n");
5172 pr_info("Copyright (c) 2007-2008, Realsil Wlan\n");
5173 RT_TRACE(COMP_INIT, "Initializing module");
5174 RT_TRACE(COMP_INIT, "Wireless extensions version %d", WIRELESS_EXT);
5175 rtl8192_proc_module_init();
5176 return usb_register(&rtl8192_usb_driver);
5180 static void __exit rtl8192_usb_module_exit(void)
5182 usb_deregister(&rtl8192_usb_driver);
5184 RT_TRACE(COMP_DOWN, "Exiting");
5188 void rtl8192_try_wake_queue(struct net_device *dev, int pri)
5190 unsigned long flags;
5191 short enough_desc;
5192 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
5194 spin_lock_irqsave(&priv->tx_lock, flags);
5195 enough_desc = check_nic_enough_desc(dev, pri);
5196 spin_unlock_irqrestore(&priv->tx_lock, flags);
5198 if (enough_desc)
5199 ieee80211_wake_queue(priv->ieee80211);
5202 void EnableHWSecurityConfig8192(struct net_device *dev)
5204 u8 SECR_value = 0x0;
5205 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
5206 struct ieee80211_device *ieee = priv->ieee80211;
5207 SECR_value = SCR_TxEncEnable | SCR_RxDecEnable;
5208 if (((KEY_TYPE_WEP40 == ieee->pairwise_key_type) || (KEY_TYPE_WEP104 == ieee->pairwise_key_type)) && (priv->ieee80211->auth_mode != 2)) {
5209 SECR_value |= SCR_RxUseDK;
5210 SECR_value |= SCR_TxUseDK;
5211 } else if ((ieee->iw_mode == IW_MODE_ADHOC) && (ieee->pairwise_key_type & (KEY_TYPE_CCMP | KEY_TYPE_TKIP))) {
5212 SECR_value |= SCR_RxUseDK;
5213 SECR_value |= SCR_TxUseDK;
5215 //add HWSec active enable here.
5216 //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
5218 ieee->hwsec_active = 1;
5220 if ((ieee->pHTInfo->IOTAction&HT_IOT_ACT_PURE_N_MODE) || !hwwep) { //add hwsec_support flag to totol control hw_sec on/off
5221 ieee->hwsec_active = 0;
5222 SECR_value &= ~SCR_RxDecEnable;
5224 RT_TRACE(COMP_SEC, "%s:, hwsec:%d, pairwise_key:%d, SECR_value:%x\n", __func__,
5225 ieee->hwsec_active, ieee->pairwise_key_type, SECR_value);
5226 write_nic_byte(dev, SECR, SECR_value);
5230 void setKey(struct net_device *dev, u8 EntryNo, u8 KeyIndex, u16 KeyType,
5231 u8 *MacAddr, u8 DefaultKey, u32 *KeyContent)
5233 u32 TargetCommand = 0;
5234 u32 TargetContent = 0;
5235 u16 usConfig = 0;
5236 u8 i;
5237 if (EntryNo >= TOTAL_CAM_ENTRY)
5238 RT_TRACE(COMP_ERR, "cam entry exceeds in setKey()\n");
5240 RT_TRACE(COMP_SEC, "====>to setKey(), dev:%p, EntryNo:%d, KeyIndex:%d, KeyType:%d, MacAddr%pM\n", dev, EntryNo, KeyIndex, KeyType, MacAddr);
5242 if (DefaultKey)
5243 usConfig |= BIT15 | (KeyType<<2);
5244 else
5245 usConfig |= BIT15 | (KeyType<<2) | KeyIndex;
5248 for (i = 0; i < CAM_CONTENT_COUNT; i++) {
5249 TargetCommand = i+CAM_CONTENT_COUNT*EntryNo;
5250 TargetCommand |= BIT31|BIT16;
5252 if (i == 0) { //MAC|Config
5253 TargetContent = (u32)(*(MacAddr+0)) << 16|
5254 (u32)(*(MacAddr+1)) << 24|
5255 (u32)usConfig;
5257 write_nic_dword(dev, WCAMI, TargetContent);
5258 write_nic_dword(dev, RWCAM, TargetCommand);
5259 } else if (i == 1) { //MAC
5260 TargetContent = (u32)(*(MacAddr+2)) |
5261 (u32)(*(MacAddr+3)) << 8|
5262 (u32)(*(MacAddr+4)) << 16|
5263 (u32)(*(MacAddr+5)) << 24;
5264 write_nic_dword(dev, WCAMI, TargetContent);
5265 write_nic_dword(dev, RWCAM, TargetCommand);
5266 } else {
5267 //Key Material
5268 if (KeyContent != NULL) {
5269 write_nic_dword(dev, WCAMI, (u32)(*(KeyContent+i-2)));
5270 write_nic_dword(dev, RWCAM, TargetCommand);
5277 /***************************************************************************
5278 ------------------- module init / exit stubs ----------------
5279 ****************************************************************************/
5280 module_init(rtl8192_usb_module_init);
5281 module_exit(rtl8192_usb_module_exit);