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
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)
33 unsigned int __fixunsdfsi(double d)
38 double __adddf3(double a, double b)
43 double __addsf3(float a, float b)
48 double __subdf3(double a, double b)
53 double __extendsfdf2(float a)
63 #undef RX_DONT_PASS_UL
65 #undef DEBUG_RX_VERBOSE
71 #undef DEBUG_TX_FILLDESC
76 #undef DEBUG_REGISTERS
78 #undef DEBUG_IRQ_TASKLET
82 #define CONFIG_RTL8192_IO_MAP
84 #include <asm/uaccess.h>
85 #include "r8192U_hw.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
101 //set here to open your trace code. //WB
102 u32 rt_global_debug_component = COMP_DOWN |
104 COMP_ERR; //always open err flags on
106 #define TOTAL_CAM_ENTRY 32
107 #define CAM_CONTENT_COUNT 8
109 static const struct usb_device_id rtl8192_usb_id_tbl[] = {
111 {USB_DEVICE(0x0bda, 0x8709)},
113 {USB_DEVICE(0x07aa, 0x0043)},
115 {USB_DEVICE(0x050d, 0x805E)},
117 {USB_DEVICE(0x0df6, 0x0031)},
119 {USB_DEVICE(0x1740, 0x9201)},
121 {USB_DEVICE(0x2001, 0x3301)},
123 {USB_DEVICE(0x5a57, 0x0290)},
125 {USB_DEVICE(0x043e, 0x7a01)},
129 MODULE_LICENSE("GPL");
130 MODULE_VERSION("V 1.1");
131 MODULE_DEVICE_TABLE(usb, rtl8192_usb_id_tbl);
132 MODULE_DESCRIPTION("Linux driver for Realtek RTL8192 USB WiFi cards");
134 static char *ifname = "wlan%d";
135 static int hwwep = 1; //default use hw. set 0 to use software security
136 static int channels = 0x3fff;
140 module_param(ifname, charp, S_IRUGO|S_IWUSR);
141 module_param(hwwep, int, S_IRUGO|S_IWUSR);
142 module_param(channels, int, S_IRUGO|S_IWUSR);
144 MODULE_PARM_DESC(ifname, " Net interface name, wlan%d=default");
145 MODULE_PARM_DESC(hwwep, " Try to use hardware security support. ");
146 MODULE_PARM_DESC(channels, " Channel bitmask for specific locales. NYI");
148 static int rtl8192_usb_probe(struct usb_interface *intf,
149 const struct usb_device_id *id);
150 static void rtl8192_usb_disconnect(struct usb_interface *intf);
153 static struct usb_driver rtl8192_usb_driver = {
154 .name = RTL819xU_MODULE_NAME, /* Driver name */
155 .id_table = rtl8192_usb_id_tbl, /* PCI_ID table */
156 .probe = rtl8192_usb_probe, /* probe fn */
157 .disconnect = rtl8192_usb_disconnect, /* remove fn */
158 .suspend = NULL, /* PM suspend fn */
159 .resume = NULL, /* PM resume fn */
163 typedef struct _CHANNEL_LIST {
166 } CHANNEL_LIST, *PCHANNEL_LIST;
168 static CHANNEL_LIST ChannelPlan[] = {
169 {{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
170 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}, 11}, //IC
171 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 36, 40, 44, 48, 52, 56, 60, 64}, 21}, //ETSI
172 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13}, //Spain. Change to ETSI.
173 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13}, //France. Change to ETSI.
174 {{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
175 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 36, 40, 44, 48, 52, 56, 60, 64}, 22},//MKK1
176 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13}, //Israel.
177 {{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
178 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 36, 40, 44, 48, 52, 56, 60, 64}, 22}, //MIC
179 {{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
182 static void rtl819x_set_channel_map(u8 channel_plan, struct r8192_priv *priv)
184 int i, max_chan = -1, min_chan = -1;
185 struct ieee80211_device *ieee = priv->ieee80211;
186 switch (channel_plan) {
187 case COUNTRY_CODE_FCC:
188 case COUNTRY_CODE_IC:
189 case COUNTRY_CODE_ETSI:
190 case COUNTRY_CODE_SPAIN:
191 case COUNTRY_CODE_FRANCE:
192 case COUNTRY_CODE_MKK:
193 case COUNTRY_CODE_MKK1:
194 case COUNTRY_CODE_ISRAEL:
195 case COUNTRY_CODE_TELEC:
196 case COUNTRY_CODE_MIC:
198 ieee->bGlobalDomain = false;
199 //actually 8225 & 8256 rf chips only support B,G,24N mode
200 if ((priv->rf_chip == RF_8225) || (priv->rf_chip == RF_8256)) {
204 RT_TRACE(COMP_ERR, "unknown rf chip, can't set channel map in function:%s()\n", __func__);
206 if (ChannelPlan[channel_plan].Len != 0) {
207 // Clear old channel map
208 memset(GET_DOT11D_INFO(ieee)->channel_map, 0, sizeof(GET_DOT11D_INFO(ieee)->channel_map));
209 // Set new channel map
210 for (i = 0; i < ChannelPlan[channel_plan].Len; i++) {
211 if (ChannelPlan[channel_plan].Channel[i] < min_chan || ChannelPlan[channel_plan].Channel[i] > max_chan)
213 GET_DOT11D_INFO(ieee)->channel_map[ChannelPlan[channel_plan].Channel[i]] = 1;
218 case COUNTRY_CODE_GLOBAL_DOMAIN:
219 GET_DOT11D_INFO(ieee)->bEnabled = 0;//this flag enabled to follow 11d country IE setting, otherwise, it shall follow global domain settings.
221 ieee->bGlobalDomain = true;
232 static void CamResetAllEntry(struct net_device *dev)
235 //2004/02/11 In static WEP, OID_ADD_KEY or OID_ADD_WEP are set before STA associate to AP.
236 // However, ResetKey is called on OID_802_11_INFRASTRUCTURE_MODE and MlmeAssociateRequest
237 // In this condition, Cam can not be reset because upper layer will not set this static key again.
238 ulcommand |= BIT31|BIT30;
239 write_nic_dword(dev, RWCAM, ulcommand);
244 void write_cam(struct net_device *dev, u8 addr, u32 data)
246 write_nic_dword(dev, WCAMI, data);
247 write_nic_dword(dev, RWCAM, BIT31|BIT16|(addr&0xff));
250 u32 read_cam(struct net_device *dev, u8 addr)
254 write_nic_dword(dev, RWCAM, 0x80000000|(addr&0xff));
255 read_nic_dword(dev, 0xa8, &data);
259 void write_nic_byte_E(struct net_device *dev, int indx, u8 data)
262 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
263 struct usb_device *udev = priv->udev;
265 status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
266 RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
267 indx|0xfe00, 0, &data, 1, HZ / 2);
270 netdev_err(dev, "write_nic_byte_E TimeOut! status: %d\n", status);
273 int read_nic_byte_E(struct net_device *dev, int indx, u8 *data)
276 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
277 struct usb_device *udev = priv->udev;
279 status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
280 RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
281 indx|0xfe00, 0, data, 1, HZ / 2);
284 netdev_err(dev, "%s failure status: %d\n", __func__, status);
290 //as 92U has extend page from 4 to 16, so modify functions below.
291 void write_nic_byte(struct net_device *dev, int indx, u8 data)
295 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
296 struct usb_device *udev = priv->udev;
298 status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
299 RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
300 (indx&0xff)|0xff00, (indx>>8)&0x0f, &data, 1, HZ / 2);
303 netdev_err(dev, "write_nic_byte TimeOut! status: %d\n", status);
309 void write_nic_word(struct net_device *dev, int indx, u16 data)
314 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
315 struct usb_device *udev = priv->udev;
317 status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
318 RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
319 (indx&0xff)|0xff00, (indx>>8)&0x0f, &data, 2, HZ / 2);
322 netdev_err(dev, "write_nic_word TimeOut! status: %d\n", status);
327 void write_nic_dword(struct net_device *dev, int indx, u32 data)
332 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
333 struct usb_device *udev = priv->udev;
335 status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
336 RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
337 (indx&0xff)|0xff00, (indx>>8)&0x0f, &data, 4, HZ / 2);
341 netdev_err(dev, "write_nic_dword TimeOut! status: %d\n", status);
347 int read_nic_byte(struct net_device *dev, int indx, u8 *data)
350 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
351 struct usb_device *udev = priv->udev;
353 status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
354 RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
355 (indx&0xff)|0xff00, (indx>>8)&0x0f, data, 1, HZ / 2);
358 netdev_err(dev, "%s failure status: %d\n", __func__, status);
367 int read_nic_word(struct net_device *dev, int indx, u16 *data)
370 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
371 struct usb_device *udev = priv->udev;
373 status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
374 RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
375 (indx&0xff)|0xff00, (indx>>8)&0x0f,
379 netdev_err(dev, "%s failure status: %d\n", __func__, status);
386 static int read_nic_word_E(struct net_device *dev, int indx, u16 *data)
389 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
390 struct usb_device *udev = priv->udev;
392 status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
393 RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
394 indx|0xfe00, 0, data, 2, HZ / 2);
397 netdev_err(dev, "%s failure status: %d\n", __func__, status);
404 int read_nic_dword(struct net_device *dev, int indx, u32 *data)
408 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
409 struct usb_device *udev = priv->udev;
411 status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
412 RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
413 (indx&0xff)|0xff00, (indx>>8)&0x0f,
417 netdev_err(dev, "%s failure status: %d\n", __func__, status);
424 /* u8 read_phy_cck(struct net_device *dev, u8 adr); */
425 /* u8 read_phy_ofdm(struct net_device *dev, u8 adr); */
426 /* this might still called in what was the PHY rtl8185/rtl8192 common code
427 * plans are to possibility turn it again in one common code...
429 inline void force_pci_posting(struct net_device *dev)
433 static struct net_device_stats *rtl8192_stats(struct net_device *dev);
434 void rtl8192_commit(struct net_device *dev);
435 void rtl8192_restart(struct work_struct *work);
436 void watch_dog_timer_callback(unsigned long data);
438 /****************************************************************************
439 * -----------------------------PROCFS STUFF-------------------------
440 *****************************************************************************
443 static struct proc_dir_entry *rtl8192_proc;
445 static int proc_get_stats_ap(struct seq_file *m, void *v)
447 struct net_device *dev = m->private;
448 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
449 struct ieee80211_device *ieee = priv->ieee80211;
450 struct ieee80211_network *target;
452 list_for_each_entry(target, &ieee->network_list, list) {
453 const char *wpa = "non_WPA";
454 if (target->wpa_ie_len > 0 || target->rsn_ie_len > 0)
457 seq_printf(m, "%s %s\n", target->ssid, wpa);
463 static int proc_get_registers(struct seq_file *m, void *v)
465 struct net_device *dev = m->private;
466 int i, n, max = 0xff;
469 seq_puts(m, "\n####################page 0##################\n ");
471 for (n = 0; n <= max;) {
472 seq_printf(m, "\nD: %2x > ", n);
474 for (i = 0; i < 16 && n <= max; i++, n++) {
475 read_nic_byte(dev, 0x000|n, &byte_rd);
476 seq_printf(m, "%2x ", byte_rd);
480 seq_puts(m, "\n####################page 1##################\n ");
481 for (n = 0; n <= max;) {
482 seq_printf(m, "\nD: %2x > ", n);
484 for (i = 0; i < 16 && n <= max; i++, n++) {
485 read_nic_byte(dev, 0x100|n, &byte_rd);
486 seq_printf(m, "%2x ", byte_rd);
490 seq_puts(m, "\n####################page 3##################\n ");
491 for (n = 0; n <= max;) {
492 seq_printf(m, "\nD: %2x > ", n);
494 for (i = 0; i < 16 && n <= max; i++, n++) {
495 read_nic_byte(dev, 0x300|n, &byte_rd);
496 seq_printf(m, "%2x ", byte_rd);
504 static int proc_get_stats_tx(struct seq_file *m, void *v)
506 struct net_device *dev = m->private;
507 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
510 "TX VI priority ok int: %lu\n"
511 "TX VI priority error int: %lu\n"
512 "TX VO priority ok int: %lu\n"
513 "TX VO priority error int: %lu\n"
514 "TX BE priority ok int: %lu\n"
515 "TX BE priority error int: %lu\n"
516 "TX BK priority ok int: %lu\n"
517 "TX BK priority error int: %lu\n"
518 "TX MANAGE priority ok int: %lu\n"
519 "TX MANAGE priority error int: %lu\n"
520 "TX BEACON priority ok int: %lu\n"
521 "TX BEACON priority error int: %lu\n"
522 "TX queue resume: %lu\n"
523 "TX queue stopped?: %d\n"
524 "TX fifo overflow: %lu\n"
529 "TX VI dropped: %lu\n"
530 "TX VO dropped: %lu\n"
531 "TX BE dropped: %lu\n"
532 "TX BK dropped: %lu\n"
533 "TX total data packets %lu\n",
534 priv->stats.txviokint,
536 priv->stats.txvookint,
538 priv->stats.txbeokint,
540 priv->stats.txbkokint,
542 priv->stats.txmanageokint,
543 priv->stats.txmanageerr,
544 priv->stats.txbeaconokint,
545 priv->stats.txbeaconerr,
546 priv->stats.txresumed,
547 netif_queue_stopped(dev),
548 priv->stats.txoverflow,
549 atomic_read(&(priv->tx_pending[VI_PRIORITY])),
550 atomic_read(&(priv->tx_pending[VO_PRIORITY])),
551 atomic_read(&(priv->tx_pending[BE_PRIORITY])),
552 atomic_read(&(priv->tx_pending[BK_PRIORITY])),
553 priv->stats.txvidrop,
554 priv->stats.txvodrop,
555 priv->stats.txbedrop,
556 priv->stats.txbkdrop,
557 priv->stats.txdatapkt
563 static int proc_get_stats_rx(struct seq_file *m, void *v)
565 struct net_device *dev = m->private;
566 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
570 "RX urb status error: %lu\n"
571 "RX invalid urb error: %lu\n",
572 priv->stats.rxoktotal,
573 priv->stats.rxstaterr,
574 priv->stats.rxurberr);
579 static void rtl8192_proc_module_init(void)
581 RT_TRACE(COMP_INIT, "Initializing proc filesystem");
582 rtl8192_proc = proc_mkdir(RTL819xU_MODULE_NAME, init_net.proc_net);
586 * seq_file wrappers for procfile show routines.
588 static int rtl8192_proc_open(struct inode *inode, struct file *file)
590 struct net_device *dev = proc_get_parent_data(inode);
591 int (*show)(struct seq_file *, void *) = PDE_DATA(inode);
593 return single_open(file, show, dev);
596 static const struct file_operations rtl8192_proc_fops = {
597 .open = rtl8192_proc_open,
600 .release = single_release,
604 * Table of proc files we need to create.
606 struct rtl8192_proc_file {
608 int (*show)(struct seq_file *, void *);
611 static const struct rtl8192_proc_file rtl8192_proc_files[] = {
612 { "stats-rx", &proc_get_stats_rx },
613 { "stats-tx", &proc_get_stats_tx },
614 { "stats-ap", &proc_get_stats_ap },
615 { "registers", &proc_get_registers },
619 static void rtl8192_proc_init_one(struct net_device *dev)
621 const struct rtl8192_proc_file *f;
622 struct proc_dir_entry *dir;
625 dir = proc_mkdir_data(dev->name, 0, rtl8192_proc, dev);
627 RT_TRACE(COMP_ERR, "Unable to initialize /proc/net/rtl8192/%s\n",
632 for (f = rtl8192_proc_files; f->name[0]; f++) {
633 if (!proc_create_data(f->name, S_IFREG | S_IRUGO, dir,
634 &rtl8192_proc_fops, f->show)) {
635 RT_TRACE(COMP_ERR, "Unable to initialize "
636 "/proc/net/rtl8192/%s/%s\n",
644 static void rtl8192_proc_remove_one(struct net_device *dev)
646 remove_proc_subtree(dev->name, rtl8192_proc);
649 /****************************************************************************
650 -----------------------------MISC STUFF-------------------------
651 *****************************************************************************/
653 short check_nic_enough_desc(struct net_device *dev, int queue_index)
655 struct r8192_priv *priv = ieee80211_priv(dev);
656 int used = atomic_read(&priv->tx_pending[queue_index]);
658 return (used < MAX_TX_URB);
661 static void tx_timeout(struct net_device *dev)
663 struct r8192_priv *priv = ieee80211_priv(dev);
665 schedule_work(&priv->reset_wq);
669 /* this is only for debug */
670 void dump_eprom(struct net_device *dev)
673 for (i = 0; i < 63; i++)
674 RT_TRACE(COMP_EPROM, "EEPROM addr %x : %x", i, eprom_read(dev, i));
677 void rtl8192_update_msr(struct net_device *dev)
679 struct r8192_priv *priv = ieee80211_priv(dev);
682 read_nic_byte(dev, MSR, &msr);
683 msr &= ~MSR_LINK_MASK;
685 /* do not change in link_state != WLAN_LINK_ASSOCIATED.
686 * msr must be updated if the state is ASSOCIATING.
687 * this is intentional and make sense for ad-hoc and
688 * master (see the create BSS/IBSS func)
690 if (priv->ieee80211->state == IEEE80211_LINKED) {
692 if (priv->ieee80211->iw_mode == IW_MODE_INFRA)
693 msr |= (MSR_LINK_MANAGED<<MSR_LINK_SHIFT);
694 else if (priv->ieee80211->iw_mode == IW_MODE_ADHOC)
695 msr |= (MSR_LINK_ADHOC<<MSR_LINK_SHIFT);
696 else if (priv->ieee80211->iw_mode == IW_MODE_MASTER)
697 msr |= (MSR_LINK_MASTER<<MSR_LINK_SHIFT);
700 msr |= (MSR_LINK_NONE<<MSR_LINK_SHIFT);
703 write_nic_byte(dev, MSR, msr);
706 void rtl8192_set_chan(struct net_device *dev, short ch)
708 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
709 RT_TRACE(COMP_CH, "=====>%s()====ch:%d\n", __func__, ch);
712 /* this hack should avoid frame TX during channel setting*/
715 //need to implement rf set channel here WB
717 if (priv->rf_set_chan)
718 priv->rf_set_chan(dev, priv->chan);
723 static void rtl8192_rx_isr(struct urb *urb);
725 static u32 get_rxpacket_shiftbytes_819xusb(struct ieee80211_rx_stats *pstats)
728 #ifdef USB_RX_AGGREGATION_SUPPORT
729 if (pstats->bisrxaggrsubframe)
730 return (sizeof(rx_desc_819x_usb) + pstats->RxDrvInfoSize
731 + pstats->RxBufShift + 8);
734 return (sizeof(rx_desc_819x_usb) + pstats->RxDrvInfoSize
735 + pstats->RxBufShift);
738 static int rtl8192_rx_initiate(struct net_device *dev)
740 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
743 struct rtl8192_rx_info *info;
745 /* nomal packet rx procedure */
746 while (skb_queue_len(&priv->rx_queue) < MAX_RX_URB) {
747 skb = __dev_alloc_skb(RX_URB_SIZE, GFP_KERNEL);
750 entry = usb_alloc_urb(0, GFP_KERNEL);
755 usb_fill_bulk_urb(entry, priv->udev,
756 usb_rcvbulkpipe(priv->udev, 3), skb_tail_pointer(skb),
757 RX_URB_SIZE, rtl8192_rx_isr, skb);
758 info = (struct rtl8192_rx_info *) skb->cb;
761 info->out_pipe = 3; //denote rx normal packet queue
762 skb_queue_tail(&priv->rx_queue, skb);
763 usb_submit_urb(entry, GFP_KERNEL);
766 /* command packet rx procedure */
767 while (skb_queue_len(&priv->rx_queue) < MAX_RX_URB + 3) {
768 skb = __dev_alloc_skb(RX_URB_SIZE, GFP_KERNEL);
771 entry = usb_alloc_urb(0, GFP_KERNEL);
776 usb_fill_bulk_urb(entry, priv->udev,
777 usb_rcvbulkpipe(priv->udev, 9), skb_tail_pointer(skb),
778 RX_URB_SIZE, rtl8192_rx_isr, skb);
779 info = (struct rtl8192_rx_info *) skb->cb;
782 info->out_pipe = 9; //denote rx cmd packet queue
783 skb_queue_tail(&priv->rx_queue, skb);
784 usb_submit_urb(entry, GFP_KERNEL);
790 void rtl8192_set_rxconf(struct net_device *dev)
792 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
795 read_nic_dword(dev, RCR, &rxconf);
796 rxconf = rxconf & ~MAC_FILTER_MASK;
797 rxconf = rxconf | RCR_AMF;
798 rxconf = rxconf | RCR_ADF;
799 rxconf = rxconf | RCR_AB;
800 rxconf = rxconf | RCR_AM;
802 if (dev->flags & IFF_PROMISC)
803 DMESG("NIC in promisc mode");
805 if (priv->ieee80211->iw_mode == IW_MODE_MONITOR ||
806 dev->flags & IFF_PROMISC) {
807 rxconf = rxconf | RCR_AAP;
809 rxconf = rxconf | RCR_APM;
810 rxconf = rxconf | RCR_CBSSID;
814 if (priv->ieee80211->iw_mode == IW_MODE_MONITOR) {
815 rxconf = rxconf | RCR_AICV;
816 rxconf = rxconf | RCR_APWRMGT;
819 if (priv->crcmon == 1 && priv->ieee80211->iw_mode == IW_MODE_MONITOR)
820 rxconf = rxconf | RCR_ACRC32;
823 rxconf = rxconf & ~RX_FIFO_THRESHOLD_MASK;
824 rxconf = rxconf | (RX_FIFO_THRESHOLD_NONE<<RX_FIFO_THRESHOLD_SHIFT);
825 rxconf = rxconf & ~MAX_RX_DMA_MASK;
826 rxconf = rxconf | ((u32)7<<RCR_MXDMA_OFFSET);
828 rxconf = rxconf | RCR_ONLYERLPKT;
830 write_nic_dword(dev, RCR, rxconf);
833 void rtl8192_rx_enable(struct net_device *dev)
835 rtl8192_rx_initiate(dev);
839 void rtl8192_tx_enable(struct net_device *dev)
845 void rtl8192_rtx_disable(struct net_device *dev)
848 struct r8192_priv *priv = ieee80211_priv(dev);
850 struct rtl8192_rx_info *info;
852 read_nic_byte(dev, CMDR, &cmd);
853 write_nic_byte(dev, CMDR, cmd & ~(CR_TE|CR_RE));
854 force_pci_posting(dev);
857 while ((skb = __skb_dequeue(&priv->rx_queue))) {
858 info = (struct rtl8192_rx_info *) skb->cb;
862 usb_kill_urb(info->urb);
866 if (skb_queue_len(&priv->skb_queue))
867 netdev_warn(dev, "skb_queue not empty\n");
869 skb_queue_purge(&priv->skb_queue);
873 inline u16 ieeerate2rtlrate(int rate)
905 static u16 rtl_rate[] = {10, 20, 55, 110, 60, 90, 120, 180, 240, 360, 480, 540};
906 inline u16 rtl8192_rate2rate(short rate)
910 return rtl_rate[rate];
914 /* The prototype of rx_isr has changed since one version of Linux Kernel */
915 static void rtl8192_rx_isr(struct urb *urb)
917 struct sk_buff *skb = (struct sk_buff *) urb->context;
918 struct rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
919 struct net_device *dev = info->dev;
920 struct r8192_priv *priv = ieee80211_priv(dev);
921 int out_pipe = info->out_pipe;
925 if (unlikely(urb->status)) {
927 priv->stats.rxstaterr++;
928 priv->ieee80211->stats.rx_errors++;
932 skb_unlink(skb, &priv->rx_queue);
933 skb_put(skb, urb->actual_length);
935 skb_queue_tail(&priv->skb_queue, skb);
936 tasklet_schedule(&priv->irq_rx_tasklet);
938 skb = dev_alloc_skb(RX_URB_SIZE);
939 if (unlikely(!skb)) {
941 netdev_err(dev, "%s(): can't alloc skb\n", __func__);
942 /* TODO check rx queue length and refill *somewhere* */
946 usb_fill_bulk_urb(urb, priv->udev,
947 usb_rcvbulkpipe(priv->udev, out_pipe), skb_tail_pointer(skb),
948 RX_URB_SIZE, rtl8192_rx_isr, skb);
950 info = (struct rtl8192_rx_info *) skb->cb;
953 info->out_pipe = out_pipe;
955 urb->transfer_buffer = skb_tail_pointer(skb);
957 skb_queue_tail(&priv->rx_queue, skb);
958 err = usb_submit_urb(urb, GFP_ATOMIC);
959 if (err && err != EPERM)
960 netdev_err(dev, "can not submit rxurb, err is %x, URB status is %x\n", err, urb->status);
963 static u32 rtl819xusb_rx_command_packet(struct net_device *dev,
964 struct ieee80211_rx_stats *pstats)
968 status = cmpk_message_handle_rx(dev, pstats);
970 DMESG("rxcommandpackethandle819xusb: It is a command packet\n");
976 static void rtl8192_data_hard_stop(struct net_device *dev)
982 static void rtl8192_data_hard_resume(struct net_device *dev)
987 /* this function TX data frames when the ieee80211 stack requires this.
988 * It checks also if we need to stop the ieee tx queue, eventually do it
990 static void rtl8192_hard_data_xmit(struct sk_buff *skb, struct net_device *dev, int rate)
992 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
995 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
996 u8 queue_index = tcb_desc->queue_index;
998 /* shall not be referred by command packet */
999 RTL8192U_ASSERT(queue_index != TXCMD_QUEUE);
1001 spin_lock_irqsave(&priv->tx_lock, flags);
1003 memcpy((unsigned char *)(skb->cb), &dev, sizeof(dev));
1004 tcb_desc->bTxEnableFwCalcDur = 1;
1005 skb_push(skb, priv->ieee80211->tx_headroom);
1006 ret = rtl8192_tx(dev, skb);
1008 spin_unlock_irqrestore(&priv->tx_lock, flags);
1013 /* This is a rough attempt to TX a frame
1014 * This is called by the ieee 80211 stack to TX management frames.
1015 * If the ring is full packet are dropped (for data frame the queue
1016 * is stopped before this can happen).
1018 static int rtl8192_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
1020 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1022 unsigned long flags;
1023 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1024 u8 queue_index = tcb_desc->queue_index;
1027 spin_lock_irqsave(&priv->tx_lock, flags);
1029 memcpy((unsigned char *)(skb->cb), &dev, sizeof(dev));
1030 if (queue_index == TXCMD_QUEUE) {
1031 skb_push(skb, USB_HWDESC_HEADER_LEN);
1032 rtl819xU_tx_cmd(dev, skb);
1034 spin_unlock_irqrestore(&priv->tx_lock, flags);
1037 skb_push(skb, priv->ieee80211->tx_headroom);
1038 ret = rtl8192_tx(dev, skb);
1041 spin_unlock_irqrestore(&priv->tx_lock, flags);
1047 void rtl8192_try_wake_queue(struct net_device *dev, int pri);
1049 #ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
1050 u16 DrvAggr_PaddingAdd(struct net_device *dev, struct sk_buff *skb)
1052 u16 PaddingNum = 256 - ((skb->len + TX_PACKET_DRVAGGR_SUBFRAME_SHIFT_BYTES) % 256);
1053 return PaddingNum & 0xff;
1056 u8 MRateToHwRate8190Pci(u8 rate);
1057 u8 QueryIsShort(u8 TxHT, u8 TxRate, cb_desc *tcb_desc);
1058 u8 MapHwQueueToFirmwareQueue(u8 QueueID);
1059 struct sk_buff *DrvAggr_Aggregation(struct net_device *dev, struct ieee80211_drv_agg_txb *pSendList)
1061 struct ieee80211_device *ieee = netdev_priv(dev);
1062 struct r8192_priv *priv = ieee80211_priv(dev);
1063 cb_desc *tcb_desc = NULL;
1066 struct sk_buff *skb;
1067 struct sk_buff *agg_skb;
1068 tx_desc_819x_usb_aggr_subframe *tx_agg_desc = NULL;
1069 tx_fwinfo_819x_usb *tx_fwinfo = NULL;
1072 // Local variable initialization.
1074 /* first skb initialization */
1075 skb = pSendList->tx_agg_frames[0];
1076 TotalLength = skb->len;
1078 /* Get the total aggregation length including the padding space and
1081 for (i = 1; i < pSendList->nr_drv_agg_frames; i++) {
1082 TotalLength += DrvAggr_PaddingAdd(dev, skb);
1083 skb = pSendList->tx_agg_frames[i];
1084 TotalLength += (skb->len + TX_PACKET_DRVAGGR_SUBFRAME_SHIFT_BYTES);
1087 /* allocate skb to contain the aggregated packets */
1088 agg_skb = dev_alloc_skb(TotalLength + ieee->tx_headroom);
1089 memset(agg_skb->data, 0, agg_skb->len);
1090 skb_reserve(agg_skb, ieee->tx_headroom);
1092 /* reserve info for first subframe Tx descriptor to be set in the tx function */
1093 skb = pSendList->tx_agg_frames[0];
1094 tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1095 tcb_desc->drv_agg_enable = 1;
1096 tcb_desc->pkt_size = skb->len;
1097 tcb_desc->DrvAggrNum = pSendList->nr_drv_agg_frames;
1098 netdev_dbg(dev, "DrvAggNum = %d\n", tcb_desc->DrvAggrNum);
1099 memcpy(agg_skb->cb, skb->cb, sizeof(skb->cb));
1100 memcpy(skb_put(agg_skb, skb->len), skb->data, skb->len);
1102 for (i = 1; i < pSendList->nr_drv_agg_frames; i++) {
1103 /* push the next sub frame to be 256 byte aline */
1104 skb_put(agg_skb, DrvAggr_PaddingAdd(dev, skb));
1106 /* Subframe drv Tx descriptor and firmware info setting */
1107 skb = pSendList->tx_agg_frames[i];
1108 tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1109 tx_agg_desc = (tx_desc_819x_usb_aggr_subframe *)skb_tail_pointer(agg_skb);
1110 tx_fwinfo = (tx_fwinfo_819x_usb *)(skb_tail_pointer(agg_skb) + sizeof(tx_desc_819x_usb_aggr_subframe));
1112 memset(tx_fwinfo, 0, sizeof(tx_fwinfo_819x_usb));
1114 tx_fwinfo->TxHT = (tcb_desc->data_rate&0x80) ? 1 : 0;
1115 tx_fwinfo->TxRate = MRateToHwRate8190Pci(tcb_desc->data_rate);
1116 tx_fwinfo->EnableCPUDur = tcb_desc->bTxEnableFwCalcDur;
1117 tx_fwinfo->Short = QueryIsShort(tx_fwinfo->TxHT, tx_fwinfo->TxRate, tcb_desc);
1118 if (tcb_desc->bAMPDUEnable) { /* AMPDU enabled */
1119 tx_fwinfo->AllowAggregation = 1;
1121 tx_fwinfo->RxMF = tcb_desc->ampdu_factor;
1122 tx_fwinfo->RxAMD = tcb_desc->ampdu_density&0x07;//ampdudensity
1124 tx_fwinfo->AllowAggregation = 0;
1126 tx_fwinfo->RxMF = 0;
1127 tx_fwinfo->RxAMD = 0;
1130 /* Protection mode related */
1131 tx_fwinfo->RtsEnable = (tcb_desc->bRTSEnable) ? 1 : 0;
1132 tx_fwinfo->CtsEnable = (tcb_desc->bCTSEnable) ? 1 : 0;
1133 tx_fwinfo->RtsSTBC = (tcb_desc->bRTSSTBC) ? 1 : 0;
1134 tx_fwinfo->RtsHT = (tcb_desc->rts_rate&0x80) ? 1 : 0;
1135 tx_fwinfo->RtsRate = MRateToHwRate8190Pci((u8)tcb_desc->rts_rate);
1136 tx_fwinfo->RtsSubcarrier = (tx_fwinfo->RtsHT == 0) ? (tcb_desc->RTSSC) : 0;
1137 tx_fwinfo->RtsBandwidth = (tx_fwinfo->RtsHT == 1) ? ((tcb_desc->bRTSBW) ? 1 : 0) : 0;
1138 tx_fwinfo->RtsShort = (tx_fwinfo->RtsHT == 0) ? (tcb_desc->bRTSUseShortPreamble ? 1 : 0) :
1139 (tcb_desc->bRTSUseShortGI ? 1 : 0);
1141 /* Set Bandwidth and sub-channel settings. */
1142 if (priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20_40) {
1143 if (tcb_desc->bPacketBW) {
1144 tx_fwinfo->TxBandwidth = 1;
1145 tx_fwinfo->TxSubCarrier = 0; //By SD3's Jerry suggestion, use duplicated mode
1147 tx_fwinfo->TxBandwidth = 0;
1148 tx_fwinfo->TxSubCarrier = priv->nCur40MhzPrimeSC;
1151 tx_fwinfo->TxBandwidth = 0;
1152 tx_fwinfo->TxSubCarrier = 0;
1155 /* Fill Tx descriptor */
1156 memset(tx_agg_desc, 0, sizeof(tx_desc_819x_usb_aggr_subframe));
1158 tx_agg_desc->Offset = sizeof(tx_fwinfo_819x_usb) + 8;
1159 /* already raw data, need not to subtract header length */
1160 tx_agg_desc->PktSize = skb->len & 0xffff;
1163 tx_agg_desc->SecCAMID = 0;
1164 tx_agg_desc->RATid = tcb_desc->RATRIndex;
1165 tx_agg_desc->NoEnc = 1;
1166 tx_agg_desc->SecType = 0x0;
1168 if (tcb_desc->bHwSec) {
1169 switch (priv->ieee80211->pairwise_key_type) {
1170 case KEY_TYPE_WEP40:
1171 case KEY_TYPE_WEP104:
1172 tx_agg_desc->SecType = 0x1;
1173 tx_agg_desc->NoEnc = 0;
1176 tx_agg_desc->SecType = 0x2;
1177 tx_agg_desc->NoEnc = 0;
1180 tx_agg_desc->SecType = 0x3;
1181 tx_agg_desc->NoEnc = 0;
1184 tx_agg_desc->SecType = 0x0;
1185 tx_agg_desc->NoEnc = 1;
1190 tx_agg_desc->QueueSelect = MapHwQueueToFirmwareQueue(tcb_desc->queue_index);
1191 tx_agg_desc->TxFWInfoSize = sizeof(tx_fwinfo_819x_usb);
1193 tx_agg_desc->DISFB = tcb_desc->bTxDisableRateFallBack;
1194 tx_agg_desc->USERATE = tcb_desc->bTxUseDriverAssingedRate;
1196 tx_agg_desc->OWN = 1;
1199 /* According windows driver, it seems that there no need to fill this field */
1201 /* to fill next packet */
1202 skb_put(agg_skb, TX_PACKET_DRVAGGR_SUBFRAME_SHIFT_BYTES);
1203 memcpy(skb_put(agg_skb, skb->len), skb->data, skb->len);
1206 for (i = 0; i < pSendList->nr_drv_agg_frames; i++)
1207 dev_kfree_skb_any(pSendList->tx_agg_frames[i]);
1213 This function return a list of PTCB which is proper to be aggregate with the input TCB.
1214 If no proper TCB is found to do aggregation, SendList will only contain the input TCB.
1216 u8 DrvAggr_GetAggregatibleList(struct net_device *dev, struct sk_buff *skb,
1217 struct ieee80211_drv_agg_txb *pSendList)
1219 struct ieee80211_device *ieee = netdev_priv(dev);
1220 PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
1221 u16 nMaxAggrNum = pHTInfo->UsbTxAggrNum;
1222 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1223 u8 QueueID = tcb_desc->queue_index;
1226 pSendList->tx_agg_frames[pSendList->nr_drv_agg_frames++] = skb;
1227 if (pSendList->nr_drv_agg_frames >= nMaxAggrNum)
1230 } while ((skb = skb_dequeue(&ieee->skb_drv_aggQ[QueueID])));
1232 RT_TRACE(COMP_AMSDU, "DrvAggr_GetAggregatibleList, nAggrTcbNum = %d \n", pSendList->nr_drv_agg_frames);
1233 return pSendList->nr_drv_agg_frames;
1237 static void rtl8192_tx_isr(struct urb *tx_urb)
1239 struct sk_buff *skb = (struct sk_buff *)tx_urb->context;
1240 struct net_device *dev = (struct net_device *)(skb->cb);
1241 struct r8192_priv *priv = NULL;
1242 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1243 u8 queue_index = tcb_desc->queue_index;
1245 priv = ieee80211_priv(dev);
1247 if (tcb_desc->queue_index != TXCMD_QUEUE) {
1248 if (tx_urb->status == 0) {
1249 dev->trans_start = jiffies;
1250 priv->stats.txoktotal++;
1251 priv->ieee80211->LinkDetectInfo.NumTxOkInPeriod++;
1252 priv->stats.txbytesunicast += (skb->len - priv->ieee80211->tx_headroom);
1254 priv->ieee80211->stats.tx_errors++;
1259 /* free skb and tx_urb */
1261 dev_kfree_skb_any(skb);
1262 usb_free_urb(tx_urb);
1263 atomic_dec(&priv->tx_pending[queue_index]);
1267 // Handle HW Beacon:
1268 // We had transfer our beacon frame to host controller at this moment.
1272 // Handling the wait queue of command packets.
1273 // For Tx command packets, we must not do TCB fragment because it is not handled right now.
1274 // We must cut the packets to match the size of TX_CMD_PKT before we send it.
1277 /* Handle MPDU in wait queue. */
1278 if (queue_index != BEACON_QUEUE) {
1279 /* Don't send data frame during scanning.*/
1280 if ((skb_queue_len(&priv->ieee80211->skb_waitQ[queue_index]) != 0) &&
1281 (!(priv->ieee80211->queue_stop))) {
1282 skb = skb_dequeue(&(priv->ieee80211->skb_waitQ[queue_index]));
1284 priv->ieee80211->softmac_hard_start_xmit(skb, dev);
1286 return; //modified by david to avoid further processing AMSDU
1288 #ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
1289 else if ((skb_queue_len(&priv->ieee80211->skb_drv_aggQ[queue_index]) != 0) &&
1290 (!(priv->ieee80211->queue_stop))) {
1291 // Tx Driver Aggregation process
1292 /* The driver will aggregation the packets according to the following stats
1293 * 1. check whether there's tx irq available, for it's a completion return
1294 * function, it should contain enough tx irq;
1295 * 2. check packet type;
1296 * 3. initialize sendlist, check whether the to-be send packet no greater than 1
1297 * 4. aggregates the packets, and fill firmware info and tx desc into it, etc.
1298 * 5. check whether the packet could be sent, otherwise just insert into wait head
1300 skb = skb_dequeue(&priv->ieee80211->skb_drv_aggQ[queue_index]);
1301 if (!check_nic_enough_desc(dev, queue_index)) {
1302 skb_queue_head(&(priv->ieee80211->skb_drv_aggQ[queue_index]), skb);
1308 struct ieee80211_drv_agg_txb SendList;
1310 memset(&SendList, 0, sizeof(struct ieee80211_drv_agg_txb));
1311 if (DrvAggr_GetAggregatibleList(dev, skb, &SendList) > 1) {
1312 skb = DrvAggr_Aggregation(dev, &SendList);
1316 priv->ieee80211->softmac_hard_start_xmit(skb, dev);
1323 static void rtl8192_config_rate(struct net_device *dev, u16 *rate_config)
1325 struct r8192_priv *priv = ieee80211_priv(dev);
1326 struct ieee80211_network *net;
1327 u8 i = 0, basic_rate = 0;
1328 net = &priv->ieee80211->current_network;
1330 for (i = 0; i < net->rates_len; i++) {
1331 basic_rate = net->rates[i]&0x7f;
1332 switch (basic_rate) {
1334 *rate_config |= RRSR_1M;
1337 *rate_config |= RRSR_2M;
1340 *rate_config |= RRSR_5_5M;
1343 *rate_config |= RRSR_11M;
1346 *rate_config |= RRSR_6M;
1349 *rate_config |= RRSR_9M;
1352 *rate_config |= RRSR_12M;
1355 *rate_config |= RRSR_18M;
1358 *rate_config |= RRSR_24M;
1361 *rate_config |= RRSR_36M;
1364 *rate_config |= RRSR_48M;
1367 *rate_config |= RRSR_54M;
1371 for (i = 0; i < net->rates_ex_len; i++) {
1372 basic_rate = net->rates_ex[i]&0x7f;
1373 switch (basic_rate) {
1375 *rate_config |= RRSR_1M;
1378 *rate_config |= RRSR_2M;
1381 *rate_config |= RRSR_5_5M;
1384 *rate_config |= RRSR_11M;
1387 *rate_config |= RRSR_6M;
1390 *rate_config |= RRSR_9M;
1393 *rate_config |= RRSR_12M;
1396 *rate_config |= RRSR_18M;
1399 *rate_config |= RRSR_24M;
1402 *rate_config |= RRSR_36M;
1405 *rate_config |= RRSR_48M;
1408 *rate_config |= RRSR_54M;
1415 #define SHORT_SLOT_TIME 9
1416 #define NON_SHORT_SLOT_TIME 20
1418 static void rtl8192_update_cap(struct net_device *dev, u16 cap)
1421 struct r8192_priv *priv = ieee80211_priv(dev);
1422 struct ieee80211_network *net = &priv->ieee80211->current_network;
1423 priv->short_preamble = cap & WLAN_CAPABILITY_SHORT_PREAMBLE;
1424 tmp = priv->basic_rate;
1425 if (priv->short_preamble)
1426 tmp |= BRSR_AckShortPmb;
1427 write_nic_dword(dev, RRSR, tmp);
1429 if (net->mode & (IEEE_G|IEEE_N_24G)) {
1431 if ((cap & WLAN_CAPABILITY_SHORT_SLOT) && (!priv->ieee80211->pHTInfo->bCurrentRT2RTLongSlotTime)) /* short slot time */
1432 slot_time = SHORT_SLOT_TIME;
1433 else //long slot time
1434 slot_time = NON_SHORT_SLOT_TIME;
1435 priv->slot_time = slot_time;
1436 write_nic_byte(dev, SLOT_TIME, slot_time);
1440 static void rtl8192_net_update(struct net_device *dev)
1443 struct r8192_priv *priv = ieee80211_priv(dev);
1444 struct ieee80211_network *net;
1445 u16 BcnTimeCfg = 0, BcnCW = 6, BcnIFS = 0xf;
1446 u16 rate_config = 0;
1447 net = &priv->ieee80211->current_network;
1449 rtl8192_config_rate(dev, &rate_config);
1450 priv->basic_rate = rate_config & 0x15f;
1452 write_nic_dword(dev, BSSIDR, ((u32 *)net->bssid)[0]);
1453 write_nic_word(dev, BSSIDR+4, ((u16 *)net->bssid)[2]);
1455 rtl8192_update_msr(dev);
1456 if (priv->ieee80211->iw_mode == IW_MODE_ADHOC) {
1457 write_nic_word(dev, ATIMWND, 2);
1458 write_nic_word(dev, BCN_DMATIME, 1023);
1459 write_nic_word(dev, BCN_INTERVAL, net->beacon_interval);
1460 write_nic_word(dev, BCN_DRV_EARLY_INT, 1);
1461 write_nic_byte(dev, BCN_ERR_THRESH, 100);
1462 BcnTimeCfg |= (BcnCW<<BCN_TCFG_CW_SHIFT);
1463 // TODO: BcnIFS may required to be changed on ASIC
1464 BcnTimeCfg |= BcnIFS<<BCN_TCFG_IFS;
1466 write_nic_word(dev, BCN_TCFG, BcnTimeCfg);
1473 //temporary hw beacon is not used any more.
1474 //open it when necessary
1475 void rtl819xusb_beacon_tx(struct net_device *dev, u16 tx_rate)
1479 inline u8 rtl8192_IsWirelessBMode(u16 rate)
1481 if (((rate <= 110) && (rate != 60) && (rate != 90)) || (rate == 220))
1487 u16 N_DBPSOfRate(u16 DataRate);
1489 u16 ComputeTxTime(u16 FrameLength, u16 DataRate, u8 bManagementFrame,
1496 if (rtl8192_IsWirelessBMode(DataRate)) {
1497 if (bManagementFrame || !bShortPreamble || DataRate == 10) /* long preamble */
1498 FrameTime = (u16)(144+48+(FrameLength*8/(DataRate/10)));
1499 else // Short preamble
1500 FrameTime = (u16)(72+24+(FrameLength*8/(DataRate/10)));
1501 if ((FrameLength*8 % (DataRate/10)) != 0) /* Get the Ceilling */
1503 } else { //802.11g DSSS-OFDM PLCP length field calculation.
1504 N_DBPS = N_DBPSOfRate(DataRate);
1505 Ceiling = (16 + 8*FrameLength + 6) / N_DBPS
1506 + (((16 + 8*FrameLength + 6) % N_DBPS) ? 1 : 0);
1507 FrameTime = (u16)(16 + 4 + 4*Ceiling + 6);
1512 u16 N_DBPSOfRate(u16 DataRate)
1556 unsigned int txqueue2outpipe(struct r8192_priv *priv, unsigned int tx_queue)
1558 if (tx_queue >= 9) {
1559 RT_TRACE(COMP_ERR, "%s():Unknown queue ID!!!\n", __func__);
1562 return priv->txqueue_to_outpipemap[tx_queue];
1565 short rtl819xU_tx_cmd(struct net_device *dev, struct sk_buff *skb)
1567 struct r8192_priv *priv = ieee80211_priv(dev);
1570 unsigned int idx_pipe;
1571 tx_desc_cmd_819x_usb *pdesc = (tx_desc_cmd_819x_usb *)skb->data;
1572 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1573 u8 queue_index = tcb_desc->queue_index;
1575 atomic_inc(&priv->tx_pending[queue_index]);
1576 tx_urb = usb_alloc_urb(0, GFP_ATOMIC);
1582 memset(pdesc, 0, USB_HWDESC_HEADER_LEN);
1583 /* Tx descriptor ought to be set according to the skb->cb */
1584 pdesc->FirstSeg = 1;//bFirstSeg;
1585 pdesc->LastSeg = 1;//bLastSeg;
1586 pdesc->CmdInit = tcb_desc->bCmdOrInit;
1587 pdesc->TxBufferSize = tcb_desc->txbuf_size;
1589 pdesc->LINIP = tcb_desc->bLastIniPkt;
1591 //----------------------------------------------------------------------------
1592 // Fill up USB_OUT_CONTEXT.
1593 //----------------------------------------------------------------------------
1594 // Get index to out pipe from specified QueueID.
1595 #ifndef USE_ONE_PIPE
1596 idx_pipe = txqueue2outpipe(priv, queue_index);
1600 usb_fill_bulk_urb(tx_urb, priv->udev, usb_sndbulkpipe(priv->udev, idx_pipe),
1601 skb->data, skb->len, rtl8192_tx_isr, skb);
1603 status = usb_submit_urb(tx_urb, GFP_ATOMIC);
1608 DMESGE("Error TX CMD URB, error %d", status);
1614 * Mapping Software/Hardware descriptor queue id to "Queue Select Field"
1615 * in TxFwInfo data structure
1616 * 2006.10.30 by Emily
1618 * \param QUEUEID Software Queue
1620 static u8 MapHwQueueToFirmwareQueue(u8 QueueID)
1622 u8 QueueSelect = 0x0; //defualt set to
1626 QueueSelect = QSLT_BE;
1630 QueueSelect = QSLT_BK;
1634 QueueSelect = QSLT_VO;
1638 QueueSelect = QSLT_VI;
1641 QueueSelect = QSLT_MGNT;
1645 QueueSelect = QSLT_BEACON;
1648 // TODO: 2006.10.30 mark other queue selection until we verify it is OK
1649 // TODO: Remove Assertions
1651 QueueSelect = QSLT_CMD;
1654 QueueSelect = QSLT_HIGH;
1658 RT_TRACE(COMP_ERR, "TransmitTCB(): Impossible Queue Selection: %d \n", QueueID);
1664 static u8 MRateToHwRate8190Pci(u8 rate)
1666 u8 ret = DESC90_RATE1M;
1670 ret = DESC90_RATE1M;
1673 ret = DESC90_RATE2M;
1676 ret = DESC90_RATE5_5M;
1679 ret = DESC90_RATE11M;
1682 ret = DESC90_RATE6M;
1685 ret = DESC90_RATE9M;
1688 ret = DESC90_RATE12M;
1691 ret = DESC90_RATE18M;
1694 ret = DESC90_RATE24M;
1697 ret = DESC90_RATE36M;
1700 ret = DESC90_RATE48M;
1703 ret = DESC90_RATE54M;
1706 // HT rate since here
1708 ret = DESC90_RATEMCS0;
1711 ret = DESC90_RATEMCS1;
1714 ret = DESC90_RATEMCS2;
1717 ret = DESC90_RATEMCS3;
1720 ret = DESC90_RATEMCS4;
1723 ret = DESC90_RATEMCS5;
1726 ret = DESC90_RATEMCS6;
1729 ret = DESC90_RATEMCS7;
1732 ret = DESC90_RATEMCS8;
1735 ret = DESC90_RATEMCS9;
1738 ret = DESC90_RATEMCS10;
1741 ret = DESC90_RATEMCS11;
1744 ret = DESC90_RATEMCS12;
1747 ret = DESC90_RATEMCS13;
1750 ret = DESC90_RATEMCS14;
1753 ret = DESC90_RATEMCS15;
1756 ret = DESC90_RATEMCS32;
1766 static u8 QueryIsShort(u8 TxHT, u8 TxRate, cb_desc *tcb_desc)
1770 tmp_Short = (TxHT == 1) ? ((tcb_desc->bUseShortGI) ? 1 : 0) : ((tcb_desc->bUseShortPreamble) ? 1 : 0);
1772 if (TxHT == 1 && TxRate != DESC90_RATEMCS15)
1778 static void tx_zero_isr(struct urb *tx_urb)
1784 * The tx procedure is just as following,
1785 * skb->cb will contain all the following information,
1786 * priority, morefrag, rate, &dev.
1788 short rtl8192_tx(struct net_device *dev, struct sk_buff *skb)
1790 struct r8192_priv *priv = ieee80211_priv(dev);
1791 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1792 tx_desc_819x_usb *tx_desc = (tx_desc_819x_usb *)skb->data;
1793 tx_fwinfo_819x_usb *tx_fwinfo = (tx_fwinfo_819x_usb *)(skb->data + USB_HWDESC_HEADER_LEN);
1794 struct usb_device *udev = priv->udev;
1797 struct urb *tx_urb = NULL, *tx_urb_zero = NULL;
1798 unsigned int idx_pipe;
1799 pend = atomic_read(&priv->tx_pending[tcb_desc->queue_index]);
1800 /* we are locked here so the two atomic_read and inc are executed
1801 * without interleaves
1802 * !!! For debug purpose
1804 if (pend > MAX_TX_URB) {
1805 netdev_dbg(dev, "To discard skb packet!\n");
1806 dev_kfree_skb_any(skb);
1810 tx_urb = usb_alloc_urb(0, GFP_ATOMIC);
1812 dev_kfree_skb_any(skb);
1816 /* Fill Tx firmware info */
1817 memset(tx_fwinfo, 0, sizeof(tx_fwinfo_819x_usb));
1819 tx_fwinfo->TxHT = (tcb_desc->data_rate&0x80) ? 1 : 0;
1820 tx_fwinfo->TxRate = MRateToHwRate8190Pci(tcb_desc->data_rate);
1821 tx_fwinfo->EnableCPUDur = tcb_desc->bTxEnableFwCalcDur;
1822 tx_fwinfo->Short = QueryIsShort(tx_fwinfo->TxHT, tx_fwinfo->TxRate, tcb_desc);
1823 if (tcb_desc->bAMPDUEnable) { /* AMPDU enabled */
1824 tx_fwinfo->AllowAggregation = 1;
1826 tx_fwinfo->RxMF = tcb_desc->ampdu_factor;
1827 tx_fwinfo->RxAMD = tcb_desc->ampdu_density&0x07;//ampdudensity
1829 tx_fwinfo->AllowAggregation = 0;
1831 tx_fwinfo->RxMF = 0;
1832 tx_fwinfo->RxAMD = 0;
1835 /* Protection mode related */
1836 tx_fwinfo->RtsEnable = (tcb_desc->bRTSEnable) ? 1 : 0;
1837 tx_fwinfo->CtsEnable = (tcb_desc->bCTSEnable) ? 1 : 0;
1838 tx_fwinfo->RtsSTBC = (tcb_desc->bRTSSTBC) ? 1 : 0;
1839 tx_fwinfo->RtsHT = (tcb_desc->rts_rate&0x80) ? 1 : 0;
1840 tx_fwinfo->RtsRate = MRateToHwRate8190Pci((u8)tcb_desc->rts_rate);
1841 tx_fwinfo->RtsSubcarrier = (tx_fwinfo->RtsHT == 0) ? (tcb_desc->RTSSC) : 0;
1842 tx_fwinfo->RtsBandwidth = (tx_fwinfo->RtsHT == 1) ? ((tcb_desc->bRTSBW) ? 1 : 0) : 0;
1843 tx_fwinfo->RtsShort = (tx_fwinfo->RtsHT == 0) ? (tcb_desc->bRTSUseShortPreamble ? 1 : 0) :
1844 (tcb_desc->bRTSUseShortGI ? 1 : 0);
1846 /* Set Bandwidth and sub-channel settings. */
1847 if (priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20_40) {
1848 if (tcb_desc->bPacketBW) {
1849 tx_fwinfo->TxBandwidth = 1;
1850 tx_fwinfo->TxSubCarrier = 0; //By SD3's Jerry suggestion, use duplicated mode
1852 tx_fwinfo->TxBandwidth = 0;
1853 tx_fwinfo->TxSubCarrier = priv->nCur40MhzPrimeSC;
1856 tx_fwinfo->TxBandwidth = 0;
1857 tx_fwinfo->TxSubCarrier = 0;
1860 #ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
1861 if (tcb_desc->drv_agg_enable)
1862 tx_fwinfo->Tx_INFO_RSVD = (tcb_desc->DrvAggrNum & 0x1f) << 1;
1864 /* Fill Tx descriptor */
1865 memset(tx_desc, 0, sizeof(tx_desc_819x_usb));
1868 tx_desc->CmdInit = 1;
1869 tx_desc->Offset = sizeof(tx_fwinfo_819x_usb) + 8;
1871 #ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
1872 if (tcb_desc->drv_agg_enable)
1873 tx_desc->PktSize = tcb_desc->pkt_size;
1877 tx_desc->PktSize = (skb->len - TX_PACKET_SHIFT_BYTES) & 0xffff;
1881 tx_desc->SecCAMID = 0;
1882 tx_desc->RATid = tcb_desc->RATRIndex;
1884 tx_desc->SecType = 0x0;
1885 if (tcb_desc->bHwSec) {
1886 switch (priv->ieee80211->pairwise_key_type) {
1887 case KEY_TYPE_WEP40:
1888 case KEY_TYPE_WEP104:
1889 tx_desc->SecType = 0x1;
1893 tx_desc->SecType = 0x2;
1897 tx_desc->SecType = 0x3;
1901 tx_desc->SecType = 0x0;
1907 tx_desc->QueueSelect = MapHwQueueToFirmwareQueue(tcb_desc->queue_index);
1908 tx_desc->TxFWInfoSize = sizeof(tx_fwinfo_819x_usb);
1910 tx_desc->DISFB = tcb_desc->bTxDisableRateFallBack;
1911 tx_desc->USERATE = tcb_desc->bTxUseDriverAssingedRate;
1913 /* Fill fields that are required to be initialized in all of the descriptors */
1915 tx_desc->FirstSeg = 1;
1916 tx_desc->LastSeg = 1;
1919 #ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
1920 if (tcb_desc->drv_agg_enable) {
1921 tx_desc->TxBufferSize = tcb_desc->pkt_size + sizeof(tx_fwinfo_819x_usb);
1926 tx_desc->TxBufferSize = (u32)(skb->len - USB_HWDESC_HEADER_LEN);
1928 /* Get index to out pipe from specified QueueID */
1929 #ifndef USE_ONE_PIPE
1930 idx_pipe = txqueue2outpipe(priv, tcb_desc->queue_index);
1935 /* To submit bulk urb */
1936 usb_fill_bulk_urb(tx_urb, udev,
1937 usb_sndbulkpipe(udev, idx_pipe), skb->data,
1938 skb->len, rtl8192_tx_isr, skb);
1940 status = usb_submit_urb(tx_urb, GFP_ATOMIC);
1942 //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
1943 bool bSend0Byte = false;
1945 if (udev->speed == USB_SPEED_HIGH) {
1946 if (skb->len > 0 && skb->len % 512 == 0)
1949 if (skb->len > 0 && skb->len % 64 == 0)
1953 tx_urb_zero = usb_alloc_urb(0, GFP_ATOMIC);
1955 RT_TRACE(COMP_ERR, "can't alloc urb for zero byte\n");
1958 usb_fill_bulk_urb(tx_urb_zero, udev,
1959 usb_sndbulkpipe(udev, idx_pipe), &zero,
1960 0, tx_zero_isr, dev);
1961 status = usb_submit_urb(tx_urb_zero, GFP_ATOMIC);
1963 RT_TRACE(COMP_ERR, "Error TX URB for zero byte %d, error %d", atomic_read(&priv->tx_pending[tcb_desc->queue_index]), status);
1967 dev->trans_start = jiffies;
1968 atomic_inc(&priv->tx_pending[tcb_desc->queue_index]);
1971 RT_TRACE(COMP_ERR, "Error TX URB %d, error %d", atomic_read(&priv->tx_pending[tcb_desc->queue_index]),
1977 static short rtl8192_usb_initendpoints(struct net_device *dev)
1979 struct r8192_priv *priv = ieee80211_priv(dev);
1981 priv->rx_urb = kmalloc(sizeof(struct urb *) * (MAX_RX_URB+1),
1983 if (priv->rx_urb == NULL)
1986 #ifndef JACKSON_NEW_RX
1987 for (i = 0; i < (MAX_RX_URB+1); i++) {
1989 priv->rx_urb[i] = usb_alloc_urb(0, GFP_KERNEL);
1991 priv->rx_urb[i]->transfer_buffer = kmalloc(RX_URB_SIZE, GFP_KERNEL);
1993 priv->rx_urb[i]->transfer_buffer_length = RX_URB_SIZE;
1997 #ifdef THOMAS_BEACON
2000 void *oldaddr, *newaddr;
2002 priv->rx_urb[16] = usb_alloc_urb(0, GFP_KERNEL);
2003 priv->oldaddr = kmalloc(16, GFP_KERNEL);
2004 oldaddr = priv->oldaddr;
2005 align = ((long)oldaddr) & 3;
2007 newaddr = oldaddr + 4 - align;
2008 priv->rx_urb[16]->transfer_buffer_length = 16 - 4 + align;
2011 priv->rx_urb[16]->transfer_buffer_length = 16;
2013 priv->rx_urb[16]->transfer_buffer = newaddr;
2017 memset(priv->rx_urb, 0, sizeof(struct urb *) * MAX_RX_URB);
2018 priv->pp_rxskb = kcalloc(MAX_RX_URB, sizeof(struct sk_buff *),
2020 if (!priv->pp_rxskb) {
2021 kfree(priv->rx_urb);
2023 priv->pp_rxskb = NULL;
2024 priv->rx_urb = NULL;
2026 DMESGE("Endpoint Alloc Failure");
2030 netdev_dbg(dev, "End of initendpoints\n");
2034 #ifdef THOMAS_BEACON
2035 static void rtl8192_usb_deleteendpoints(struct net_device *dev)
2038 struct r8192_priv *priv = ieee80211_priv(dev);
2041 for (i = 0; i < (MAX_RX_URB+1); i++) {
2042 usb_kill_urb(priv->rx_urb[i]);
2043 usb_free_urb(priv->rx_urb[i]);
2045 kfree(priv->rx_urb);
2046 priv->rx_urb = NULL;
2048 kfree(priv->oldaddr);
2049 priv->oldaddr = NULL;
2050 if (priv->pp_rxskb) {
2051 kfree(priv->pp_rxskb);
2052 priv->pp_rxskb = NULL;
2056 void rtl8192_usb_deleteendpoints(struct net_device *dev)
2059 struct r8192_priv *priv = ieee80211_priv(dev);
2061 #ifndef JACKSON_NEW_RX
2064 for (i = 0; i < (MAX_RX_URB+1); i++) {
2065 usb_kill_urb(priv->rx_urb[i]);
2066 kfree(priv->rx_urb[i]->transfer_buffer);
2067 usb_free_urb(priv->rx_urb[i]);
2069 kfree(priv->rx_urb);
2070 priv->rx_urb = NULL;
2074 kfree(priv->rx_urb);
2075 priv->rx_urb = NULL;
2076 kfree(priv->oldaddr);
2077 priv->oldaddr = NULL;
2078 if (priv->pp_rxskb) {
2079 kfree(priv->pp_rxskb);
2088 extern void rtl8192_update_ratr_table(struct net_device *dev);
2089 static void rtl8192_link_change(struct net_device *dev)
2091 struct r8192_priv *priv = ieee80211_priv(dev);
2092 struct ieee80211_device *ieee = priv->ieee80211;
2093 if (ieee->state == IEEE80211_LINKED) {
2094 rtl8192_net_update(dev);
2095 rtl8192_update_ratr_table(dev);
2096 //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
2097 if ((KEY_TYPE_WEP40 == ieee->pairwise_key_type) || (KEY_TYPE_WEP104 == ieee->pairwise_key_type))
2098 EnableHWSecurityConfig8192(dev);
2100 /*update timing params*/
2101 if (ieee->iw_mode == IW_MODE_INFRA || ieee->iw_mode == IW_MODE_ADHOC) {
2103 read_nic_dword(dev, RCR, ®);
2104 if (priv->ieee80211->state == IEEE80211_LINKED)
2105 priv->ReceiveConfig = reg |= RCR_CBSSID;
2107 priv->ReceiveConfig = reg &= ~RCR_CBSSID;
2108 write_nic_dword(dev, RCR, reg);
2112 static struct ieee80211_qos_parameters def_qos_parameters = {
2113 {3, 3, 3, 3},/* cw_min */
2114 {7, 7, 7, 7},/* cw_max */
2115 {2, 2, 2, 2},/* aifs */
2116 {0, 0, 0, 0},/* flags */
2117 {0, 0, 0, 0} /* tx_op_limit */
2121 static void rtl8192_update_beacon(struct work_struct *work)
2123 struct r8192_priv *priv = container_of(work, struct r8192_priv, update_beacon_wq.work);
2124 struct net_device *dev = priv->ieee80211->dev;
2125 struct ieee80211_device *ieee = priv->ieee80211;
2126 struct ieee80211_network *net = &ieee->current_network;
2128 if (ieee->pHTInfo->bCurrentHTSupport)
2129 HTUpdateSelfAndPeerSetting(ieee, net);
2130 ieee->pHTInfo->bCurrentRT2RTLongSlotTime = net->bssht.bdRT2RTLongSlotTime;
2131 rtl8192_update_cap(dev, net->capability);
2134 * background support to run QoS activate functionality
2136 static int WDCAPARA_ADD[] = {EDCAPARA_BE, EDCAPARA_BK, EDCAPARA_VI, EDCAPARA_VO};
2137 static void rtl8192_qos_activate(struct work_struct *work)
2139 struct r8192_priv *priv = container_of(work, struct r8192_priv, qos_activate);
2140 struct net_device *dev = priv->ieee80211->dev;
2141 struct ieee80211_qos_parameters *qos_parameters = &priv->ieee80211->current_network.qos_data.parameters;
2142 u8 mode = priv->ieee80211->current_network.mode;
2147 mutex_lock(&priv->mutex);
2148 if (priv->ieee80211->state != IEEE80211_LINKED)
2150 RT_TRACE(COMP_QOS, "qos active process with associate response received\n");
2151 /* It better set slot time at first */
2152 /* For we just support b/g mode at present, let the slot time at 9/20 selection */
2153 /* update the ac parameter to related registers */
2154 for (i = 0; i < QOS_QUEUE_NUM; i++) {
2155 //Mode G/A: slotTimeTimer = 9; Mode B: 20
2156 u1bAIFS = qos_parameters->aifs[i] * ((mode&(IEEE_G|IEEE_N_24G)) ? 9 : 20) + aSifsTime;
2157 u4bAcParam = ((((u32)(qos_parameters->tx_op_limit[i]))<< AC_PARAM_TXOP_LIMIT_OFFSET)|
2158 (((u32)(qos_parameters->cw_max[i]))<< AC_PARAM_ECW_MAX_OFFSET)|
2159 (((u32)(qos_parameters->cw_min[i]))<< AC_PARAM_ECW_MIN_OFFSET)|
2160 ((u32)u1bAIFS << AC_PARAM_AIFS_OFFSET));
2162 write_nic_dword(dev, WDCAPARA_ADD[i], u4bAcParam);
2166 mutex_unlock(&priv->mutex);
2169 static int rtl8192_qos_handle_probe_response(struct r8192_priv *priv,
2171 struct ieee80211_network *network)
2174 u32 size = sizeof(struct ieee80211_qos_parameters);
2176 if (priv->ieee80211->state != IEEE80211_LINKED)
2179 if ((priv->ieee80211->iw_mode != IW_MODE_INFRA))
2182 if (network->flags & NETWORK_HAS_QOS_MASK) {
2183 if (active_network &&
2184 (network->flags & NETWORK_HAS_QOS_PARAMETERS))
2185 network->qos_data.active = network->qos_data.supported;
2187 if ((network->qos_data.active == 1) && (active_network == 1) &&
2188 (network->flags & NETWORK_HAS_QOS_PARAMETERS) &&
2189 (network->qos_data.old_param_count !=
2190 network->qos_data.param_count)) {
2191 network->qos_data.old_param_count =
2192 network->qos_data.param_count;
2193 queue_work(priv->priv_wq, &priv->qos_activate);
2194 RT_TRACE(COMP_QOS, "QoS parameters change call "
2198 memcpy(&priv->ieee80211->current_network.qos_data.parameters,
2199 &def_qos_parameters, size);
2201 if ((network->qos_data.active == 1) && (active_network == 1)) {
2202 queue_work(priv->priv_wq, &priv->qos_activate);
2203 RT_TRACE(COMP_QOS, "QoS was disabled call qos_activate \n");
2205 network->qos_data.active = 0;
2206 network->qos_data.supported = 0;
2212 /* handle and manage frame from beacon and probe response */
2213 static int rtl8192_handle_beacon(struct net_device *dev,
2214 struct ieee80211_beacon *beacon,
2215 struct ieee80211_network *network)
2217 struct r8192_priv *priv = ieee80211_priv(dev);
2219 rtl8192_qos_handle_probe_response(priv, 1, network);
2220 queue_delayed_work(priv->priv_wq, &priv->update_beacon_wq, 0);
2226 * handling the beaconing responses. if we get different QoS setting
2227 * off the network from the associated setting, adjust the QoS
2230 static int rtl8192_qos_association_resp(struct r8192_priv *priv,
2231 struct ieee80211_network *network)
2234 unsigned long flags;
2235 u32 size = sizeof(struct ieee80211_qos_parameters);
2236 int set_qos_param = 0;
2238 if ((priv == NULL) || (network == NULL))
2241 if (priv->ieee80211->state != IEEE80211_LINKED)
2244 if ((priv->ieee80211->iw_mode != IW_MODE_INFRA))
2247 spin_lock_irqsave(&priv->ieee80211->lock, flags);
2248 if (network->flags & NETWORK_HAS_QOS_PARAMETERS) {
2249 memcpy(&priv->ieee80211->current_network.qos_data.parameters,
2250 &network->qos_data.parameters,
2251 sizeof(struct ieee80211_qos_parameters));
2252 priv->ieee80211->current_network.qos_data.active = 1;
2254 /* update qos parameter for current network */
2255 priv->ieee80211->current_network.qos_data.old_param_count =
2256 priv->ieee80211->current_network.qos_data.param_count;
2257 priv->ieee80211->current_network.qos_data.param_count =
2258 network->qos_data.param_count;
2260 memcpy(&priv->ieee80211->current_network.qos_data.parameters,
2261 &def_qos_parameters, size);
2262 priv->ieee80211->current_network.qos_data.active = 0;
2263 priv->ieee80211->current_network.qos_data.supported = 0;
2267 spin_unlock_irqrestore(&priv->ieee80211->lock, flags);
2269 RT_TRACE(COMP_QOS, "%s: network->flags = %d,%d\n", __func__, network->flags, priv->ieee80211->current_network.qos_data.active);
2270 if (set_qos_param == 1)
2271 queue_work(priv->priv_wq, &priv->qos_activate);
2278 static int rtl8192_handle_assoc_response(struct net_device *dev,
2279 struct ieee80211_assoc_response_frame *resp,
2280 struct ieee80211_network *network)
2282 struct r8192_priv *priv = ieee80211_priv(dev);
2283 rtl8192_qos_association_resp(priv, network);
2288 void rtl8192_update_ratr_table(struct net_device *dev)
2290 struct r8192_priv *priv = ieee80211_priv(dev);
2291 struct ieee80211_device *ieee = priv->ieee80211;
2292 u8 *pMcsRate = ieee->dot11HTOperationalRateSet;
2295 rtl8192_config_rate(dev, (u16 *)(&ratr_value));
2296 ratr_value |= (*(u16 *)(pMcsRate)) << 12;
2297 switch (ieee->mode) {
2299 ratr_value &= 0x00000FF0;
2302 ratr_value &= 0x0000000F;
2305 ratr_value &= 0x00000FF7;
2309 if (ieee->pHTInfo->PeerMimoPs == 0) { /* MIMO_PS_STATIC */
2310 ratr_value &= 0x0007F007;
2312 if (priv->rf_type == RF_1T2R)
2313 ratr_value &= 0x000FF007;
2315 ratr_value &= 0x0F81F007;
2321 ratr_value &= 0x0FFFFFFF;
2322 if (ieee->pHTInfo->bCurTxBW40MHz && ieee->pHTInfo->bCurShortGI40MHz)
2323 ratr_value |= 0x80000000;
2324 else if (!ieee->pHTInfo->bCurTxBW40MHz && ieee->pHTInfo->bCurShortGI20MHz)
2325 ratr_value |= 0x80000000;
2326 write_nic_dword(dev, RATR0+rate_index*4, ratr_value);
2327 write_nic_byte(dev, UFWP, 1);
2330 static u8 ccmp_ie[4] = {0x00, 0x50, 0xf2, 0x04};
2331 static u8 ccmp_rsn_ie[4] = {0x00, 0x0f, 0xac, 0x04};
2332 static bool GetNmodeSupportBySecCfg8192(struct net_device *dev)
2334 struct r8192_priv *priv = ieee80211_priv(dev);
2335 struct ieee80211_device *ieee = priv->ieee80211;
2336 struct ieee80211_network *network = &ieee->current_network;
2337 int wpa_ie_len = ieee->wpa_ie_len;
2338 struct ieee80211_crypt_data *crypt;
2341 crypt = ieee->crypt[ieee->tx_keyidx];
2342 //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
2343 encrypt = (network->capability & WLAN_CAPABILITY_PRIVACY) || (ieee->host_encrypt && crypt && crypt->ops && (0 == strcmp(crypt->ops->name, "WEP")));
2346 if (encrypt && (wpa_ie_len == 0)) {
2347 /* wep encryption, no N mode setting */
2349 } else if ((wpa_ie_len != 0)) {
2350 /* parse pairwise key type */
2351 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))))
2362 static bool GetHalfNmodeSupportByAPs819xUsb(struct net_device *dev)
2365 struct r8192_priv *priv = ieee80211_priv(dev);
2366 struct ieee80211_device *ieee = priv->ieee80211;
2368 if (ieee->bHalfWirelessN24GMode == true)
2376 static void rtl8192_refresh_supportrate(struct r8192_priv *priv)
2378 struct ieee80211_device *ieee = priv->ieee80211;
2379 //we do not consider set support rate for ABG mode, only HT MCS rate is set here.
2380 if (ieee->mode == WIRELESS_MODE_N_24G || ieee->mode == WIRELESS_MODE_N_5G)
2381 memcpy(ieee->Regdot11HTOperationalRateSet, ieee->RegHTSuppRateSet, 16);
2383 memset(ieee->Regdot11HTOperationalRateSet, 0, 16);
2387 static u8 rtl8192_getSupportedWireleeMode(struct net_device *dev)
2389 struct r8192_priv *priv = ieee80211_priv(dev);
2391 switch (priv->rf_chip) {
2395 ret = (WIRELESS_MODE_N_24G|WIRELESS_MODE_G|WIRELESS_MODE_B);
2398 ret = (WIRELESS_MODE_A|WIRELESS_MODE_N_5G);
2401 ret = WIRELESS_MODE_B;
2406 static void rtl8192_SetWirelessMode(struct net_device *dev, u8 wireless_mode)
2408 struct r8192_priv *priv = ieee80211_priv(dev);
2409 u8 bSupportMode = rtl8192_getSupportedWireleeMode(dev);
2411 if ((wireless_mode == WIRELESS_MODE_AUTO) || ((wireless_mode&bSupportMode) == 0)) {
2412 if (bSupportMode & WIRELESS_MODE_N_24G) {
2413 wireless_mode = WIRELESS_MODE_N_24G;
2414 } else if (bSupportMode & WIRELESS_MODE_N_5G) {
2415 wireless_mode = WIRELESS_MODE_N_5G;
2416 } else if ((bSupportMode & WIRELESS_MODE_A)) {
2417 wireless_mode = WIRELESS_MODE_A;
2418 } else if ((bSupportMode & WIRELESS_MODE_G)) {
2419 wireless_mode = WIRELESS_MODE_G;
2420 } else if ((bSupportMode & WIRELESS_MODE_B)) {
2421 wireless_mode = WIRELESS_MODE_B;
2423 RT_TRACE(COMP_ERR, "%s(), No valid wireless mode supported, SupportedWirelessMode(%x)!!!\n", __func__, bSupportMode);
2424 wireless_mode = WIRELESS_MODE_B;
2427 #ifdef TO_DO_LIST //// TODO: this function doesn't work well at this time, we should wait for FPGA
2428 ActUpdateChannelAccessSetting(pAdapter, pHalData->CurrentWirelessMode, &pAdapter->MgntInfo.Info8185.ChannelAccessSetting);
2430 priv->ieee80211->mode = wireless_mode;
2432 if ((wireless_mode == WIRELESS_MODE_N_24G) || (wireless_mode == WIRELESS_MODE_N_5G))
2433 priv->ieee80211->pHTInfo->bEnableHT = 1;
2435 priv->ieee80211->pHTInfo->bEnableHT = 0;
2436 RT_TRACE(COMP_INIT, "Current Wireless Mode is %x\n", wireless_mode);
2437 rtl8192_refresh_supportrate(priv);
2440 //init priv variables here. only non_zero value should be initialized here.
2441 static void rtl8192_init_priv_variable(struct net_device *dev)
2443 struct r8192_priv *priv = ieee80211_priv(dev);
2445 priv->card_8192 = NIC_8192U;
2446 priv->chan = 1; //set to channel 1
2447 priv->ieee80211->mode = WIRELESS_MODE_AUTO; //SET AUTO
2448 priv->ieee80211->iw_mode = IW_MODE_INFRA;
2449 priv->ieee80211->ieee_up = 0;
2450 priv->retry_rts = DEFAULT_RETRY_RTS;
2451 priv->retry_data = DEFAULT_RETRY_DATA;
2452 priv->ieee80211->rts = DEFAULT_RTS_THRESHOLD;
2453 priv->ieee80211->rate = 110; //11 mbps
2454 priv->ieee80211->short_slot = 1;
2455 priv->promisc = (dev->flags & IFF_PROMISC) ? 1 : 0;
2458 priv->IrpPendingCount = 1;
2459 priv->ResetProgress = RESET_TYPE_NORESET;
2460 priv->bForcedSilentReset = 0;
2461 priv->bDisableNormalResetCheck = false;
2462 priv->force_reset = false;
2464 priv->ieee80211->FwRWRF = 0; //we don't use FW read/write RF until stable firmware is available.
2465 priv->ieee80211->current_network.beacon_interval = DEFAULT_BEACONINTERVAL;
2466 priv->ieee80211->softmac_features = IEEE_SOFTMAC_SCAN |
2467 IEEE_SOFTMAC_ASSOCIATE | IEEE_SOFTMAC_PROBERQ |
2468 IEEE_SOFTMAC_PROBERS | IEEE_SOFTMAC_TX_QUEUE |
2469 IEEE_SOFTMAC_BEACONS;//added by amy 080604
2471 priv->ieee80211->active_scan = 1;
2472 priv->ieee80211->modulation = IEEE80211_CCK_MODULATION | IEEE80211_OFDM_MODULATION;
2473 priv->ieee80211->host_encrypt = 1;
2474 priv->ieee80211->host_decrypt = 1;
2475 priv->ieee80211->start_send_beacons = NULL; //-by amy 080604
2476 priv->ieee80211->stop_send_beacons = NULL; //-by amy 080604
2477 priv->ieee80211->softmac_hard_start_xmit = rtl8192_hard_start_xmit;
2478 priv->ieee80211->set_chan = rtl8192_set_chan;
2479 priv->ieee80211->link_change = rtl8192_link_change;
2480 priv->ieee80211->softmac_data_hard_start_xmit = rtl8192_hard_data_xmit;
2481 priv->ieee80211->data_hard_stop = rtl8192_data_hard_stop;
2482 priv->ieee80211->data_hard_resume = rtl8192_data_hard_resume;
2483 priv->ieee80211->init_wmmparam_flag = 0;
2484 priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD;
2485 priv->ieee80211->check_nic_enough_desc = check_nic_enough_desc;
2486 priv->ieee80211->tx_headroom = TX_PACKET_SHIFT_BYTES;
2487 priv->ieee80211->qos_support = 1;
2490 priv->ieee80211->SetBWModeHandler = rtl8192_SetBWMode;
2491 priv->ieee80211->handle_assoc_response = rtl8192_handle_assoc_response;
2492 priv->ieee80211->handle_beacon = rtl8192_handle_beacon;
2494 priv->ieee80211->GetNmodeSupportBySecCfg = GetNmodeSupportBySecCfg8192;
2495 priv->ieee80211->GetHalfNmodeSupportByAPsHandler = GetHalfNmodeSupportByAPs819xUsb;
2496 priv->ieee80211->SetWirelessMode = rtl8192_SetWirelessMode;
2498 priv->ieee80211->InitialGainHandler = InitialGain819xUsb;
2499 priv->card_type = USB;
2501 if (Adapter->bInHctTest) {
2502 pHalData->ShortRetryLimit = 7;
2503 pHalData->LongRetryLimit = 7;
2506 priv->ShortRetryLimit = 0x30;
2507 priv->LongRetryLimit = 0x30;
2508 priv->EarlyRxThreshold = 7;
2509 priv->enable_gpio0 = 0;
2510 priv->TransmitConfig =
2511 (TCR_MXDMA_2048<<TCR_MXDMA_OFFSET)| // Max DMA Burst Size per Tx DMA Burst, 7: reserved.
2512 (priv->ShortRetryLimit<<TCR_SRL_OFFSET)| // Short retry limit
2513 (priv->LongRetryLimit<<TCR_LRL_OFFSET) | // Long retry limit
2514 (false ? TCR_SAT : 0); // FALSE: HW provides PLCP length and LENGEXT, TRUE: SW provides them
2516 if (Adapter->bInHctTest)
2517 pHalData->ReceiveConfig = pHalData->CSMethod |
2518 RCR_AMF | RCR_ADF | //accept management/data
2520 RCR_ACF | //accept control frame for SW AP needs PS-poll, 2005.07.07, by rcnjko.
2521 RCR_AB | RCR_AM | RCR_APM | //accept BC/MC/UC
2522 RCR_AICV | RCR_ACRC32 | //accept ICV/CRC error packet
2523 ((u32)7<<RCR_MXDMA_OFFSET) | // Max DMA Burst Size per Rx DMA Burst, 7: unlimited.
2524 (pHalData->EarlyRxThreshold<<RCR_FIFO_OFFSET) | // Rx FIFO Threshold, 7: No Rx threshold.
2525 (pHalData->EarlyRxThreshold == 7 ? RCR_OnlyErlPkt : 0);
2529 priv->ReceiveConfig =
2530 RCR_AMF | RCR_ADF | //accept management/data
2531 RCR_ACF | //accept control frame for SW AP needs PS-poll, 2005.07.07, by rcnjko.
2532 RCR_AB | RCR_AM | RCR_APM | //accept BC/MC/UC
2533 ((u32)7<<RCR_MXDMA_OFFSET)| // Max DMA Burst Size per Rx DMA Burst, 7: unlimited.
2534 (priv->EarlyRxThreshold<<RX_FIFO_THRESHOLD_SHIFT) | // Rx FIFO Threshold, 7: No Rx threshold.
2535 (priv->EarlyRxThreshold == 7 ? RCR_ONLYERLPKT : 0);
2537 priv->AcmControl = 0;
2538 priv->pFirmware = kzalloc(sizeof(rt_firmware), GFP_KERNEL);
2540 /* rx related queue */
2541 skb_queue_head_init(&priv->rx_queue);
2542 skb_queue_head_init(&priv->skb_queue);
2544 /* Tx related queue */
2545 for (i = 0; i < MAX_QUEUE_SIZE; i++)
2546 skb_queue_head_init(&priv->ieee80211->skb_waitQ[i]);
2547 for (i = 0; i < MAX_QUEUE_SIZE; i++)
2548 skb_queue_head_init(&priv->ieee80211->skb_aggQ[i]);
2549 for (i = 0; i < MAX_QUEUE_SIZE; i++)
2550 skb_queue_head_init(&priv->ieee80211->skb_drv_aggQ[i]);
2551 priv->rf_set_chan = rtl8192_phy_SwChnl;
2555 static void rtl8192_init_priv_lock(struct r8192_priv *priv)
2557 spin_lock_init(&priv->tx_lock);
2558 spin_lock_init(&priv->irq_lock);//added by thomas
2559 sema_init(&priv->wx_sem, 1);
2560 sema_init(&priv->rf_sem, 1);
2561 mutex_init(&priv->mutex);
2564 extern void rtl819x_watchdog_wqcallback(struct work_struct *work);
2566 void rtl8192_irq_rx_tasklet(struct r8192_priv *priv);
2567 //init tasklet and wait_queue here. only 2.6 above kernel is considered
2568 #define DRV_NAME "wlan0"
2569 static void rtl8192_init_priv_task(struct net_device *dev)
2571 struct r8192_priv *priv = ieee80211_priv(dev);
2573 priv->priv_wq = create_workqueue(DRV_NAME);
2575 INIT_WORK(&priv->reset_wq, rtl8192_restart);
2577 INIT_DELAYED_WORK(&priv->watch_dog_wq, rtl819x_watchdog_wqcallback);
2578 INIT_DELAYED_WORK(&priv->txpower_tracking_wq, dm_txpower_trackingcallback);
2579 INIT_DELAYED_WORK(&priv->rfpath_check_wq, dm_rf_pathcheck_workitemcallback);
2580 INIT_DELAYED_WORK(&priv->update_beacon_wq, rtl8192_update_beacon);
2581 INIT_DELAYED_WORK(&priv->initialgain_operate_wq, InitialGainOperateWorkItemCallBack);
2582 INIT_WORK(&priv->qos_activate, rtl8192_qos_activate);
2584 tasklet_init(&priv->irq_rx_tasklet,
2585 (void(*)(unsigned long))rtl8192_irq_rx_tasklet,
2586 (unsigned long)priv);
2589 static void rtl8192_get_eeprom_size(struct net_device *dev)
2592 struct r8192_priv *priv = ieee80211_priv(dev);
2593 RT_TRACE(COMP_EPROM, "===========>%s()\n", __func__);
2594 read_nic_word_E(dev, EPROM_CMD, &curCR);
2595 RT_TRACE(COMP_EPROM, "read from Reg EPROM_CMD(%x):%x\n", EPROM_CMD, curCR);
2596 //whether need I consider BIT5?
2597 priv->epromtype = (curCR & Cmd9346CR_9356SEL) ? EPROM_93c56 : EPROM_93c46;
2598 RT_TRACE(COMP_EPROM, "<===========%s(), epromtype:%d\n", __func__, priv->epromtype);
2601 //used to swap endian. as ntohl & htonl are not necessary to swap endian, so use this instead.
2602 static inline u16 endian_swap(u16 *data)
2605 *data = (tmp >> 8) | (tmp << 8);
2608 static void rtl8192_read_eeprom_info(struct net_device *dev)
2611 u8 bMac_Tmp_Addr[6] = {0x00, 0xe0, 0x4c, 0x00, 0x00, 0x02};
2612 u8 bLoad_From_EEPOM = false;
2613 struct r8192_priv *priv = ieee80211_priv(dev);
2616 RT_TRACE(COMP_EPROM, "===========>%s()\n", __func__);
2617 wEPROM_ID = eprom_read(dev, 0); //first read EEPROM ID out;
2618 RT_TRACE(COMP_EPROM, "EEPROM ID is 0x%x\n", wEPROM_ID);
2620 if (wEPROM_ID != RTL8190_EEPROM_ID) {
2621 RT_TRACE(COMP_ERR, "EEPROM ID is invalid(is 0x%x(should be 0x%x)\n", wEPROM_ID, RTL8190_EEPROM_ID);
2623 bLoad_From_EEPOM = true;
2626 if (bLoad_From_EEPOM) {
2627 tmpValue = eprom_read(dev, (EEPROM_VID>>1));
2628 priv->eeprom_vid = endian_swap(&tmpValue);
2629 priv->eeprom_pid = eprom_read(dev, (EEPROM_PID>>1));
2630 tmpValue = eprom_read(dev, (EEPROM_ChannelPlan>>1));
2631 priv->eeprom_ChannelPlan = ((tmpValue&0xff00)>>8);
2632 priv->btxpowerdata_readfromEEPORM = true;
2633 priv->eeprom_CustomerID = eprom_read(dev, (EEPROM_Customer_ID>>1)) >>8;
2635 priv->eeprom_vid = 0;
2636 priv->eeprom_pid = 0;
2637 priv->card_8192_version = VERSION_819xU_B;
2638 priv->eeprom_ChannelPlan = 0;
2639 priv->eeprom_CustomerID = 0;
2641 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);
2642 //set channelplan from eeprom
2643 priv->ChannelPlan = priv->eeprom_ChannelPlan;
2644 if (bLoad_From_EEPOM) {
2646 for (i = 0; i < 6; i += 2) {
2648 tmp = eprom_read(dev, (u16)((EEPROM_NODE_ADDRESS_BYTE_0 + i)>>1));
2649 *(u16 *)(&dev->dev_addr[i]) = tmp;
2652 memcpy(dev->dev_addr, bMac_Tmp_Addr, 6);
2653 //should I set IDR0 here?
2655 RT_TRACE(COMP_EPROM, "MAC addr:%pM\n", dev->dev_addr);
2656 priv->rf_type = RTL819X_DEFAULT_RF_TYPE; //default 1T2R
2657 priv->rf_chip = RF_8256;
2659 if (priv->card_8192_version == (u8)VERSION_819xU_A) {
2660 //read Tx power gain offset of legacy OFDM to HT rate
2661 if (bLoad_From_EEPOM)
2662 priv->EEPROMTxPowerDiff = (eprom_read(dev, (EEPROM_TxPowerDiff>>1))&0xff00) >> 8;
2664 priv->EEPROMTxPowerDiff = EEPROM_Default_TxPower;
2665 RT_TRACE(COMP_EPROM, "TxPowerDiff:%d\n", priv->EEPROMTxPowerDiff);
2666 //read ThermalMeter from EEPROM
2667 if (bLoad_From_EEPOM)
2668 priv->EEPROMThermalMeter = (u8)(eprom_read(dev, (EEPROM_ThermalMeter>>1))&0x00ff);
2670 priv->EEPROMThermalMeter = EEPROM_Default_ThermalMeter;
2671 RT_TRACE(COMP_EPROM, "ThermalMeter:%d\n", priv->EEPROMThermalMeter);
2672 //vivi, for tx power track
2673 priv->TSSI_13dBm = priv->EEPROMThermalMeter *100;
2674 //read antenna tx power offset of B/C/D to A from EEPROM
2675 if (bLoad_From_EEPOM)
2676 priv->EEPROMPwDiff = (eprom_read(dev, (EEPROM_PwDiff>>1))&0x0f00)>>8;
2678 priv->EEPROMPwDiff = EEPROM_Default_PwDiff;
2679 RT_TRACE(COMP_EPROM, "TxPwDiff:%d\n", priv->EEPROMPwDiff);
2680 // Read CrystalCap from EEPROM
2681 if (bLoad_From_EEPOM)
2682 priv->EEPROMCrystalCap = (eprom_read(dev, (EEPROM_CrystalCap>>1))&0x0f);
2684 priv->EEPROMCrystalCap = EEPROM_Default_CrystalCap;
2685 RT_TRACE(COMP_EPROM, "CrystalCap = %d\n", priv->EEPROMCrystalCap);
2686 //get per-channel Tx power level
2687 if (bLoad_From_EEPOM)
2688 priv->EEPROM_Def_Ver = (eprom_read(dev, (EEPROM_TxPwIndex_Ver>>1))&0xff00)>>8;
2690 priv->EEPROM_Def_Ver = 1;
2691 RT_TRACE(COMP_EPROM, "EEPROM_DEF_VER:%d\n", priv->EEPROM_Def_Ver);
2692 if (priv->EEPROM_Def_Ver == 0) { /* old eeprom definition */
2694 if (bLoad_From_EEPOM)
2695 priv->EEPROMTxPowerLevelCCK = (eprom_read(dev, (EEPROM_TxPwIndex_CCK>>1))&0xff) >> 8;
2697 priv->EEPROMTxPowerLevelCCK = 0x10;
2698 RT_TRACE(COMP_EPROM, "CCK Tx Power Levl: 0x%02x\n", priv->EEPROMTxPowerLevelCCK);
2699 for (i = 0; i < 3; i++) {
2700 if (bLoad_From_EEPOM) {
2701 tmpValue = eprom_read(dev, (EEPROM_TxPwIndex_OFDM_24G+i)>>1);
2702 if (((EEPROM_TxPwIndex_OFDM_24G+i) % 2) == 0)
2703 tmpValue = tmpValue & 0x00ff;
2705 tmpValue = (tmpValue & 0xff00) >> 8;
2709 priv->EEPROMTxPowerLevelOFDM24G[i] = (u8) tmpValue;
2710 RT_TRACE(COMP_EPROM, "OFDM 2.4G Tx Power Level, Index %d = 0x%02x\n", i, priv->EEPROMTxPowerLevelCCK);
2712 } else if (priv->EEPROM_Def_Ver == 1) {
2713 if (bLoad_From_EEPOM) {
2714 tmpValue = eprom_read(dev, (EEPROM_TxPwIndex_CCK_V1>>1));
2715 tmpValue = (tmpValue & 0xff00) >> 8;
2719 priv->EEPROMTxPowerLevelCCK_V1[0] = (u8)tmpValue;
2721 if (bLoad_From_EEPOM)
2722 tmpValue = eprom_read(dev, (EEPROM_TxPwIndex_CCK_V1 + 2)>>1);
2725 *((u16 *)(&priv->EEPROMTxPowerLevelCCK_V1[1])) = tmpValue;
2726 if (bLoad_From_EEPOM)
2727 tmpValue = eprom_read(dev, (EEPROM_TxPwIndex_OFDM_24G_V1>>1));
2730 *((u16 *)(&priv->EEPROMTxPowerLevelOFDM24G[0])) = tmpValue;
2731 if (bLoad_From_EEPOM)
2732 tmpValue = eprom_read(dev, (EEPROM_TxPwIndex_OFDM_24G_V1+2)>>1);
2735 priv->EEPROMTxPowerLevelOFDM24G[2] = (u8)tmpValue;
2736 }//endif EEPROM_Def_Ver == 1
2738 //update HAL variables
2740 for (i = 0; i < 14; i++) {
2742 priv->TxPowerLevelOFDM24G[i] = priv->EEPROMTxPowerLevelOFDM24G[0];
2743 else if (i >= 4 && i <= 9)
2744 priv->TxPowerLevelOFDM24G[i] = priv->EEPROMTxPowerLevelOFDM24G[1];
2746 priv->TxPowerLevelOFDM24G[i] = priv->EEPROMTxPowerLevelOFDM24G[2];
2749 for (i = 0; i < 14; i++) {
2750 if (priv->EEPROM_Def_Ver == 0) {
2752 priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelOFDM24G[0] + (priv->EEPROMTxPowerLevelCCK - priv->EEPROMTxPowerLevelOFDM24G[1]);
2753 else if (i >= 4 && i <= 9)
2754 priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelCCK;
2756 priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelOFDM24G[2] + (priv->EEPROMTxPowerLevelCCK - priv->EEPROMTxPowerLevelOFDM24G[1]);
2757 } else if (priv->EEPROM_Def_Ver == 1) {
2759 priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelCCK_V1[0];
2760 else if (i >= 4 && i <= 9)
2761 priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelCCK_V1[1];
2763 priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelCCK_V1[2];
2766 priv->TxPowerDiff = priv->EEPROMPwDiff;
2767 // Antenna B gain offset to antenna A, bit0~3
2768 priv->AntennaTxPwDiff[0] = (priv->EEPROMTxPowerDiff & 0xf);
2769 // Antenna C gain offset to antenna A, bit4~7
2770 priv->AntennaTxPwDiff[1] = ((priv->EEPROMTxPowerDiff & 0xf0)>>4);
2771 // CrystalCap, bit12~15
2772 priv->CrystalCap = priv->EEPROMCrystalCap;
2773 // ThermalMeter, bit0~3 for RFIC1, bit4~7 for RFIC2
2774 // 92U does not enable TX power tracking.
2775 priv->ThermalMeter[0] = priv->EEPROMThermalMeter;
2776 }//end if VersionID == VERSION_819xU_A
2778 //added by vivi, for dlink led, 20080416
2779 switch (priv->eeprom_CustomerID) {
2780 case EEPROM_CID_RUNTOP:
2781 priv->CustomerID = RT_CID_819x_RUNTOP;
2784 case EEPROM_CID_DLINK:
2785 priv->CustomerID = RT_CID_DLINK;
2789 priv->CustomerID = RT_CID_DEFAULT;
2794 switch (priv->CustomerID) {
2795 case RT_CID_819x_RUNTOP:
2796 priv->LedStrategy = SW_LED_MODE2;
2800 priv->LedStrategy = SW_LED_MODE4;
2804 priv->LedStrategy = SW_LED_MODE0;
2810 if (priv->rf_type == RF_1T2R) {
2811 RT_TRACE(COMP_EPROM, "\n1T2R config\n");
2813 RT_TRACE(COMP_EPROM, "\n2T4R config\n");
2816 // 2008/01/16 MH We can only know RF type in the function. So we have to init
2817 // DIG RATR table again.
2818 init_rate_adaptive(dev);
2819 //we need init DIG RATR table here again.
2821 RT_TRACE(COMP_EPROM, "<===========%s()\n", __func__);
2825 static short rtl8192_get_channel_map(struct net_device *dev)
2827 struct r8192_priv *priv = ieee80211_priv(dev);
2828 if (priv->ChannelPlan > COUNTRY_CODE_GLOBAL_DOMAIN) {
2829 netdev_err(dev, "rtl8180_init: Error channel plan! Set to default.\n");
2830 priv->ChannelPlan = 0;
2832 RT_TRACE(COMP_INIT, "Channel plan is %d\n", priv->ChannelPlan);
2834 rtl819x_set_channel_map(priv->ChannelPlan, priv);
2838 static short rtl8192_init(struct net_device *dev)
2841 struct r8192_priv *priv = ieee80211_priv(dev);
2843 memset(&(priv->stats), 0, sizeof(struct Stats));
2844 memset(priv->txqueue_to_outpipemap, 0, 9);
2848 u8 queuetopipe[] = {3, 2, 1, 0, 4, 8, 7, 6, 5};
2849 memcpy(priv->txqueue_to_outpipemap, queuetopipe, 9);
2853 u8 queuetopipe[] = {3, 2, 1, 0, 4, 4, 0, 4, 4};
2854 memcpy(priv->txqueue_to_outpipemap, queuetopipe, 9);
2857 rtl8192_init_priv_variable(dev);
2858 rtl8192_init_priv_lock(priv);
2859 rtl8192_init_priv_task(dev);
2860 rtl8192_get_eeprom_size(dev);
2861 rtl8192_read_eeprom_info(dev);
2862 rtl8192_get_channel_map(dev);
2864 init_timer(&priv->watch_dog_timer);
2865 priv->watch_dog_timer.data = (unsigned long)dev;
2866 priv->watch_dog_timer.function = watch_dog_timer_callback;
2867 if (rtl8192_usb_initendpoints(dev) != 0) {
2868 DMESG("Endopoints initialization failed");
2878 /******************************************************************************
2879 *function: This function actually only set RRSR, RATR and BW_OPMODE registers
2880 * not to do all the hw config as its name says
2881 * input: net_device dev
2884 * notice: This part need to modified according to the rate set we filtered
2885 * ****************************************************************************/
2886 static void rtl8192_hwconfig(struct net_device *dev)
2888 u32 regRATR = 0, regRRSR = 0;
2889 u8 regBwOpMode = 0, regTmp = 0;
2890 struct r8192_priv *priv = ieee80211_priv(dev);
2893 // Set RRSR, RATR, and BW_OPMODE registers
2895 switch (priv->ieee80211->mode) {
2896 case WIRELESS_MODE_B:
2897 regBwOpMode = BW_OPMODE_20MHZ;
2898 regRATR = RATE_ALL_CCK;
2899 regRRSR = RATE_ALL_CCK;
2901 case WIRELESS_MODE_A:
2902 regBwOpMode = BW_OPMODE_5G |BW_OPMODE_20MHZ;
2903 regRATR = RATE_ALL_OFDM_AG;
2904 regRRSR = RATE_ALL_OFDM_AG;
2906 case WIRELESS_MODE_G:
2907 regBwOpMode = BW_OPMODE_20MHZ;
2908 regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
2909 regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
2911 case WIRELESS_MODE_AUTO:
2913 if (Adapter->bInHctTest) {
2914 regBwOpMode = BW_OPMODE_20MHZ;
2915 regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
2916 regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
2921 regBwOpMode = BW_OPMODE_20MHZ;
2922 regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
2923 regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
2926 case WIRELESS_MODE_N_24G:
2927 // It support CCK rate by default.
2928 // CCK rate will be filtered out only when associated AP does not support it.
2929 regBwOpMode = BW_OPMODE_20MHZ;
2930 regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
2931 regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
2933 case WIRELESS_MODE_N_5G:
2934 regBwOpMode = BW_OPMODE_5G;
2935 regRATR = RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
2936 regRRSR = RATE_ALL_OFDM_AG;
2940 write_nic_byte(dev, BW_OPMODE, regBwOpMode);
2941 ratr_value = regRATR;
2942 if (priv->rf_type == RF_1T2R)
2943 ratr_value &= ~(RATE_ALL_OFDM_2SS);
2944 write_nic_dword(dev, RATR0, ratr_value);
2945 write_nic_byte(dev, UFWP, 1);
2946 read_nic_byte(dev, 0x313, ®Tmp);
2947 regRRSR = ((regTmp) << 24) | (regRRSR & 0x00ffffff);
2948 write_nic_dword(dev, RRSR, regRRSR);
2951 // Set Retry Limit here
2953 write_nic_word(dev, RETRY_LIMIT,
2954 priv->ShortRetryLimit << RETRY_LIMIT_SHORT_SHIFT |
2955 priv->LongRetryLimit << RETRY_LIMIT_LONG_SHIFT);
2956 // Set Contention Window here
2960 // Set Tx Antenna including Feedback control
2962 // Set Auto Rate fallback control
2968 //InitializeAdapter and PhyCfg
2969 static bool rtl8192_adapter_start(struct net_device *dev)
2971 struct r8192_priv *priv = ieee80211_priv(dev);
2973 bool init_status = true;
2974 u8 SECR_value = 0x0;
2976 RT_TRACE(COMP_INIT, "====>%s()\n", __func__);
2977 priv->Rf_Mode = RF_OP_By_SW_3wire;
2978 //for ASIC power on sequence
2979 write_nic_byte_E(dev, 0x5f, 0x80);
2981 write_nic_byte_E(dev, 0x5f, 0xf0);
2982 write_nic_byte_E(dev, 0x5d, 0x00);
2983 write_nic_byte_E(dev, 0x5e, 0x80);
2984 write_nic_byte(dev, 0x17, 0x37);
2986 priv->pFirmware->firmware_status = FW_STATUS_0_INIT;
2987 //config CPUReset Register
2988 //Firmware Reset or not?
2989 read_nic_dword(dev, CPU_GEN, &dwRegRead);
2990 if (priv->pFirmware->firmware_status == FW_STATUS_0_INIT)
2991 dwRegRead |= CPU_GEN_SYSTEM_RESET; //do nothing here?
2992 else if (priv->pFirmware->firmware_status == FW_STATUS_5_READY)
2993 dwRegRead |= CPU_GEN_FIRMWARE_RESET;
2995 RT_TRACE(COMP_ERR, "ERROR in %s(): undefined firmware state(%d)\n", __func__, priv->pFirmware->firmware_status);
2997 write_nic_dword(dev, CPU_GEN, dwRegRead);
2999 rtl8192_BBConfig(dev);
3001 //Loopback mode or not
3002 priv->LoopbackMode = RTL819xU_NO_LOOPBACK;
3004 read_nic_dword(dev, CPU_GEN, &dwRegRead);
3005 if (priv->LoopbackMode == RTL819xU_NO_LOOPBACK)
3006 dwRegRead = ((dwRegRead & CPU_GEN_NO_LOOPBACK_MSK) | CPU_GEN_NO_LOOPBACK_SET);
3007 else if (priv->LoopbackMode == RTL819xU_MAC_LOOPBACK)
3008 dwRegRead |= CPU_CCK_LOOPBACK;
3010 RT_TRACE(COMP_ERR, "Serious error in %s(): wrong loopback mode setting(%d)\n", __func__, priv->LoopbackMode);
3012 write_nic_dword(dev, CPU_GEN, dwRegRead);
3014 //after reset cpu, we need wait for a seconds to write in register.
3017 //xiong add for new bitfile:usb suspend reset pin set to 1. //do we need?
3018 read_nic_byte_E(dev, 0x5f, &tmp);
3019 write_nic_byte_E(dev, 0x5f, tmp|0x20);
3022 rtl8192_hwconfig(dev);
3025 write_nic_byte(dev, CMDR, CR_RE|CR_TE);
3028 write_nic_dword(dev, MAC0, ((u32 *)dev->dev_addr)[0]);
3029 write_nic_word(dev, MAC4, ((u16 *)(dev->dev_addr + 4))[0]);
3032 write_nic_dword(dev, RCR, priv->ReceiveConfig);
3034 //Initialize Number of Reserved Pages in Firmware Queue
3035 write_nic_dword(dev, RQPN1, NUM_OF_PAGE_IN_FW_QUEUE_BK << RSVD_FW_QUEUE_PAGE_BK_SHIFT |
3036 NUM_OF_PAGE_IN_FW_QUEUE_BE << RSVD_FW_QUEUE_PAGE_BE_SHIFT |
3037 NUM_OF_PAGE_IN_FW_QUEUE_VI << RSVD_FW_QUEUE_PAGE_VI_SHIFT |
3038 NUM_OF_PAGE_IN_FW_QUEUE_VO <<RSVD_FW_QUEUE_PAGE_VO_SHIFT);
3039 write_nic_dword(dev, RQPN2, NUM_OF_PAGE_IN_FW_QUEUE_MGNT << RSVD_FW_QUEUE_PAGE_MGNT_SHIFT |
3040 NUM_OF_PAGE_IN_FW_QUEUE_CMD << RSVD_FW_QUEUE_PAGE_CMD_SHIFT);
3041 write_nic_dword(dev, RQPN3, APPLIED_RESERVED_QUEUE_IN_FW|
3042 NUM_OF_PAGE_IN_FW_QUEUE_BCN<<RSVD_FW_QUEUE_PAGE_BCN_SHIFT);
3043 write_nic_dword(dev, RATR0+4*7, (RATE_ALL_OFDM_AG | RATE_ALL_CCK));
3046 // TODO: (it value is only for FPGA version). need to be changed!!2006.12.18, by Emily
3047 write_nic_byte(dev, ACK_TIMEOUT, 0x30);
3049 if (priv->ResetProgress == RESET_TYPE_NORESET)
3050 rtl8192_SetWirelessMode(dev, priv->ieee80211->mode);
3051 if (priv->ResetProgress == RESET_TYPE_NORESET) {
3052 CamResetAllEntry(dev);
3053 SECR_value |= SCR_TxEncEnable;
3054 SECR_value |= SCR_RxDecEnable;
3055 SECR_value |= SCR_NoSKMC;
3056 write_nic_byte(dev, SECR, SECR_value);
3060 write_nic_word(dev, ATIMWND, 2);
3061 write_nic_word(dev, BCN_INTERVAL, 100);
3063 #define DEFAULT_EDCA 0x005e4332
3066 for (i = 0; i < QOS_QUEUE_NUM; i++)
3067 write_nic_dword(dev, WDCAPARA_ADD[i], DEFAULT_EDCA);
3069 #ifdef USB_RX_AGGREGATION_SUPPORT
3070 //3 For usb rx firmware aggregation control
3071 if (priv->ResetProgress == RESET_TYPE_NORESET) {
3073 PRT_HIGH_THROUGHPUT pHTInfo = priv->ieee80211->pHTInfo;
3074 ulValue = (pHTInfo->UsbRxFwAggrEn<<24) | (pHTInfo->UsbRxFwAggrPageNum<<16) |
3075 (pHTInfo->UsbRxFwAggrPacketNum<<8) | (pHTInfo->UsbRxFwAggrTimeout);
3077 * If usb rx firmware aggregation is enabled,
3078 * when anyone of three threshold conditions above is reached,
3079 * firmware will send aggregated packet to driver.
3081 write_nic_dword(dev, 0x1a8, ulValue);
3082 priv->bCurrentRxAggrEnable = true;
3086 rtl8192_phy_configmac(dev);
3088 if (priv->card_8192_version == (u8) VERSION_819xU_A) {
3089 rtl8192_phy_getTxPower(dev);
3090 rtl8192_phy_setTxPower(dev, priv->chan);
3094 init_status = init_firmware(dev);
3096 RT_TRACE(COMP_ERR, "ERR!!! %s(): Firmware download is failed\n", __func__);
3099 RT_TRACE(COMP_INIT, "%s():after firmware download\n", __func__);
3102 if (Adapter->ResetProgress == RESET_TYPE_NORESET) {
3103 if (pMgntInfo->RegRfOff == TRUE) { /* User disable RF via registry. */
3104 RT_TRACE((COMP_INIT|COMP_RF), DBG_LOUD, ("InitializeAdapter819xUsb(): Turn off RF for RegRfOff ----------\n"));
3105 MgntActSet_RF_State(Adapter, eRfOff, RF_CHANGE_BY_SW);
3106 // Those actions will be discard in MgntActSet_RF_State because of the same state
3107 for (eRFPath = 0; eRFPath < pHalData->NumTotalRFPath; eRFPath++)
3108 PHY_SetRFReg(Adapter, (RF90_RADIO_PATH_E)eRFPath, 0x4, 0xC00, 0x0);
3109 } else if (pMgntInfo->RfOffReason > RF_CHANGE_BY_PS) { /* H/W or S/W RF OFF before sleep. */
3110 RT_TRACE((COMP_INIT|COMP_RF), DBG_LOUD, ("InitializeAdapter819xUsb(): Turn off RF for RfOffReason(%d) ----------\n", pMgntInfo->RfOffReason));
3111 MgntActSet_RF_State(Adapter, eRfOff, pMgntInfo->RfOffReason);
3113 pHalData->eRFPowerState = eRfOn;
3114 pMgntInfo->RfOffReason = 0;
3115 RT_TRACE((COMP_INIT|COMP_RF), DBG_LOUD, ("InitializeAdapter819xUsb(): RF is on ----------\n"));
3118 if (pHalData->eRFPowerState == eRfOff) {
3119 MgntActSet_RF_State(Adapter, eRfOff, pMgntInfo->RfOffReason);
3120 // Those actions will be discard in MgntActSet_RF_State because of the same state
3121 for (eRFPath = 0; eRFPath < pHalData->NumTotalRFPath; eRFPath++)
3122 PHY_SetRFReg(Adapter, (RF90_RADIO_PATH_E)eRFPath, 0x4, 0xC00, 0x0);
3127 if (priv->ResetProgress == RESET_TYPE_NORESET) {
3128 rtl8192_phy_RFConfig(dev);
3129 RT_TRACE(COMP_INIT, "%s():after phy RF config\n", __func__);
3133 if (priv->ieee80211->FwRWRF)
3134 // We can force firmware to do RF-R/W
3135 priv->Rf_Mode = RF_OP_By_FW;
3137 priv->Rf_Mode = RF_OP_By_SW_3wire;
3140 rtl8192_phy_updateInitGain(dev);
3141 /*--set CCK and OFDM Block "ON"--*/
3142 rtl8192_setBBreg(dev, rFPGA0_RFMOD, bCCKEn, 0x1);
3143 rtl8192_setBBreg(dev, rFPGA0_RFMOD, bOFDMEn, 0x1);
3145 if (priv->ResetProgress == RESET_TYPE_NORESET) {
3148 read_nic_byte(dev, 0x301, &tmpvalue);
3149 if (tmpvalue == 0x03) {
3151 RT_TRACE(COMP_POWER_TRACKING, "D-cut\n");
3153 priv->bDcut = FALSE;
3154 RT_TRACE(COMP_POWER_TRACKING, "C-cut\n");
3156 dm_initialize_txpower_tracking(dev);
3158 if (priv->bDcut == TRUE) {
3160 u32 tmpRegA = rtl8192_QueryBBReg(dev, rOFDM0_XATxIQImbalance, bMaskDWord);
3161 for (i = 0; i < TxBBGainTableLength; i++) {
3162 if (tmpRegA == priv->txbbgain_table[i].txbbgain_value) {
3163 priv->rfa_txpowertrackingindex = (u8)i;
3164 priv->rfa_txpowertrackingindex_real = (u8)i;
3165 priv->rfa_txpowertracking_default = priv->rfa_txpowertrackingindex;
3170 TempCCk = rtl8192_QueryBBReg(dev, rCCK0_TxFilter1, bMaskByte2);
3172 for (i = 0; i < CCKTxBBGainTableLength; i++) {
3174 if (TempCCk == priv->cck_txbbgain_table[i].ccktxbb_valuearray[0]) {
3175 priv->cck_present_attentuation_20Mdefault = (u8) i;
3179 priv->cck_present_attentuation_40Mdefault = 0;
3180 priv->cck_present_attentuation_difference = 0;
3181 priv->cck_present_attentuation = priv->cck_present_attentuation_20Mdefault;
3185 write_nic_byte(dev, 0x87, 0x0);
3191 /* this configures registers for beacon tx and enables it via
3192 * rtl8192_beacon_tx_enable(). rtl8192_beacon_tx_disable() might
3193 * be used to stop beacon transmission
3195 /***************************************************************************
3196 -------------------------------NET STUFF---------------------------
3197 ***************************************************************************/
3199 static struct net_device_stats *rtl8192_stats(struct net_device *dev)
3201 struct r8192_priv *priv = ieee80211_priv(dev);
3203 return &priv->ieee80211->stats;
3206 static bool HalTxCheckStuck819xUsb(struct net_device *dev)
3208 struct r8192_priv *priv = ieee80211_priv(dev);
3210 bool bStuck = FALSE;
3211 read_nic_word(dev, 0x128, &RegTxCounter);
3212 RT_TRACE(COMP_RESET, "%s():RegTxCounter is %d,TxCounter is %d\n", __func__, RegTxCounter, priv->TxCounter);
3213 if (priv->TxCounter == RegTxCounter)
3216 priv->TxCounter = RegTxCounter;
3222 * <Assumption: RT_TX_SPINLOCK is acquired.>
3223 * First added: 2006.11.19 by emily
3225 static RESET_TYPE TxCheckStuck(struct net_device *dev)
3227 struct r8192_priv *priv = ieee80211_priv(dev);
3229 bool bCheckFwTxCnt = false;
3232 // Decide such threshold according to current power save mode
3235 for (QueueID = 0; QueueID <= BEACON_QUEUE; QueueID++) {
3236 if (QueueID == TXCMD_QUEUE)
3238 #ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
3239 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))
3241 if ((skb_queue_len(&priv->ieee80211->skb_waitQ[QueueID]) == 0) && (skb_queue_len(&priv->ieee80211->skb_aggQ[QueueID]) == 0))
3245 bCheckFwTxCnt = true;
3247 if (bCheckFwTxCnt) {
3248 if (HalTxCheckStuck819xUsb(dev)) {
3249 RT_TRACE(COMP_RESET, "TxCheckStuck(): Fw indicates no Tx condition! \n");
3250 return RESET_TYPE_SILENT;
3253 return RESET_TYPE_NORESET;
3256 static bool HalRxCheckStuck819xUsb(struct net_device *dev)
3259 struct r8192_priv *priv = ieee80211_priv(dev);
3260 bool bStuck = FALSE;
3261 static u8 rx_chk_cnt;
3262 read_nic_word(dev, 0x130, &RegRxCounter);
3263 RT_TRACE(COMP_RESET, "%s(): RegRxCounter is %d,RxCounter is %d\n", __func__, RegRxCounter, priv->RxCounter);
3264 // If rssi is small, we should check rx for long time because of bad rx.
3265 // or maybe it will continuous silent reset every 2 seconds.
3267 if (priv->undecorated_smoothed_pwdb >= (RateAdaptiveTH_High+5)) {
3268 rx_chk_cnt = 0; //high rssi, check rx stuck right now.
3269 } else if (priv->undecorated_smoothed_pwdb < (RateAdaptiveTH_High+5) &&
3270 ((priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20 && priv->undecorated_smoothed_pwdb >= RateAdaptiveTH_Low_40M) ||
3271 (priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20 && priv->undecorated_smoothed_pwdb >= RateAdaptiveTH_Low_20M))) {
3276 } else if (((priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20 && priv->undecorated_smoothed_pwdb < RateAdaptiveTH_Low_40M) ||
3277 (priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20 && priv->undecorated_smoothed_pwdb < RateAdaptiveTH_Low_20M)) &&
3278 priv->undecorated_smoothed_pwdb >= VeryLowRSSI) {
3290 if (priv->RxCounter == RegRxCounter)
3293 priv->RxCounter = RegRxCounter;
3298 static RESET_TYPE RxCheckStuck(struct net_device *dev)
3300 struct r8192_priv *priv = ieee80211_priv(dev);
3301 bool bRxCheck = FALSE;
3303 if (priv->IrpPendingCount > 1)
3307 if (HalRxCheckStuck819xUsb(dev)) {
3308 RT_TRACE(COMP_RESET, "RxStuck Condition\n");
3309 return RESET_TYPE_SILENT;
3312 return RESET_TYPE_NORESET;
3317 * This function is called by Checkforhang to check whether we should ask OS to reset driver
3319 * \param pAdapter The adapter context for this miniport
3321 * Note:NIC with USB interface sholud not call this function because we cannot scan descriptor
3322 * to judge whether there is tx stuck.
3323 * Note: This function may be required to be rewrite for Vista OS.
3324 * <<<Assumption: Tx spinlock has been acquired >>>
3326 * 8185 and 8185b does not implement this function. This is added by Emily at 2006.11.24
3328 static RESET_TYPE rtl819x_ifcheck_resetornot(struct net_device *dev)
3330 struct r8192_priv *priv = ieee80211_priv(dev);
3331 RESET_TYPE TxResetType = RESET_TYPE_NORESET;
3332 RESET_TYPE RxResetType = RESET_TYPE_NORESET;
3333 RT_RF_POWER_STATE rfState;
3335 rfState = priv->ieee80211->eRFPowerState;
3337 TxResetType = TxCheckStuck(dev);
3338 if (rfState != eRfOff ||
3339 (priv->ieee80211->iw_mode != IW_MODE_ADHOC)) {
3340 // If driver is in the status of firmware download failure , driver skips RF initialization and RF is
3341 // in turned off state. Driver should check whether Rx stuck and do silent reset. And
3342 // if driver is in firmware download failure status, driver should initialize RF in the following
3343 // silent reset procedure Emily, 2008.01.21
3345 // Driver should not check RX stuck in IBSS mode because it is required to
3346 // set Check BSSID in order to send beacon, however, if check BSSID is
3347 // set, STA cannot hear any packet at all. Emily, 2008.04.12
3348 RxResetType = RxCheckStuck(dev);
3350 if (TxResetType == RESET_TYPE_NORMAL || RxResetType == RESET_TYPE_NORMAL) {
3351 return RESET_TYPE_NORMAL;
3352 } else if (TxResetType == RESET_TYPE_SILENT || RxResetType == RESET_TYPE_SILENT) {
3353 RT_TRACE(COMP_RESET, "%s():silent reset\n", __func__);
3354 return RESET_TYPE_SILENT;
3356 return RESET_TYPE_NORESET;
3361 void rtl8192_cancel_deferred_work(struct r8192_priv *priv);
3362 int _rtl8192_up(struct net_device *dev);
3363 int rtl8192_close(struct net_device *dev);
3367 static void CamRestoreAllEntry(struct net_device *dev)
3370 struct r8192_priv *priv = ieee80211_priv(dev);
3371 u8 *MacAddr = priv->ieee80211->current_network.bssid;
3373 static u8 CAM_CONST_ADDR[4][6] = {
3374 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
3375 {0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
3376 {0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
3377 {0x00, 0x00, 0x00, 0x00, 0x00, 0x03} };
3378 static u8 CAM_CONST_BROAD[] = {
3379 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
3381 RT_TRACE(COMP_SEC, "CamRestoreAllEntry: \n");
3384 if ((priv->ieee80211->pairwise_key_type == KEY_TYPE_WEP40) ||
3385 (priv->ieee80211->pairwise_key_type == KEY_TYPE_WEP104)) {
3387 for (EntryId = 0; EntryId < 4; EntryId++) {
3388 MacAddr = CAM_CONST_ADDR[EntryId];
3389 setKey(dev, EntryId, EntryId,
3390 priv->ieee80211->pairwise_key_type,
3394 } else if (priv->ieee80211->pairwise_key_type == KEY_TYPE_TKIP) {
3396 if (priv->ieee80211->iw_mode == IW_MODE_ADHOC)
3397 setKey(dev, 4, 0, priv->ieee80211->pairwise_key_type,
3398 (u8 *)dev->dev_addr, 0, NULL);
3400 setKey(dev, 4, 0, priv->ieee80211->pairwise_key_type,
3402 } else if (priv->ieee80211->pairwise_key_type == KEY_TYPE_CCMP) {
3404 if (priv->ieee80211->iw_mode == IW_MODE_ADHOC)
3405 setKey(dev, 4, 0, priv->ieee80211->pairwise_key_type,
3406 (u8 *)dev->dev_addr, 0, NULL);
3408 setKey(dev, 4, 0, priv->ieee80211->pairwise_key_type,
3414 if (priv->ieee80211->group_key_type == KEY_TYPE_TKIP) {
3415 MacAddr = CAM_CONST_BROAD;
3416 for (EntryId = 1; EntryId < 4; EntryId++) {
3417 setKey(dev, EntryId, EntryId,
3418 priv->ieee80211->group_key_type,
3421 if (priv->ieee80211->iw_mode == IW_MODE_ADHOC)
3422 setKey(dev, 0, 0, priv->ieee80211->group_key_type,
3423 CAM_CONST_ADDR[0], 0, NULL);
3424 } else if (priv->ieee80211->group_key_type == KEY_TYPE_CCMP) {
3425 MacAddr = CAM_CONST_BROAD;
3426 for (EntryId = 1; EntryId < 4; EntryId++) {
3427 setKey(dev, EntryId, EntryId,
3428 priv->ieee80211->group_key_type,
3432 if (priv->ieee80211->iw_mode == IW_MODE_ADHOC)
3433 setKey(dev, 0, 0, priv->ieee80211->group_key_type,
3434 CAM_CONST_ADDR[0], 0, NULL);
3437 //////////////////////////////////////////////////////////////
3438 // This function is used to fix Tx/Rx stop bug temporarily.
3439 // This function will do "system reset" to NIC when Tx or Rx is stuck.
3440 // The method checking Tx/Rx stuck of this function is supported by FW,
3441 // which reports Tx and Rx counter to register 0x128 and 0x130.
3442 //////////////////////////////////////////////////////////////
3443 static void rtl819x_ifsilentreset(struct net_device *dev)
3445 struct r8192_priv *priv = ieee80211_priv(dev);
3447 int reset_status = 0;
3448 struct ieee80211_device *ieee = priv->ieee80211;
3451 // 2007.07.20. If we need to check CCK stop, please uncomment this line.
3452 //bStuck = Adapter->HalFunc.CheckHWStopHandler(Adapter);
3454 if (priv->ResetProgress == RESET_TYPE_NORESET) {
3457 RT_TRACE(COMP_RESET, "=========>Reset progress!! \n");
3459 // Set the variable for reset.
3460 priv->ResetProgress = RESET_TYPE_SILENT;
3461 down(&priv->wx_sem);
3462 if (priv->up == 0) {
3463 RT_TRACE(COMP_ERR, "%s():the driver is not up! return\n", __func__);
3468 RT_TRACE(COMP_RESET, "%s():======>start to down the driver\n", __func__);
3470 rtl8192_rtx_disable(dev);
3471 rtl8192_cancel_deferred_work(priv);
3473 del_timer_sync(&priv->watch_dog_timer);
3475 ieee->sync_scan_hurryup = 1;
3476 if (ieee->state == IEEE80211_LINKED) {
3477 down(&ieee->wx_sem);
3478 netdev_dbg(dev, "ieee->state is IEEE80211_LINKED\n");
3479 ieee80211_stop_send_beacons(priv->ieee80211);
3480 del_timer_sync(&ieee->associate_timer);
3481 cancel_delayed_work(&ieee->associate_retry_wq);
3482 ieee80211_stop_scan(ieee);
3483 netif_carrier_off(dev);
3486 netdev_dbg(dev, "ieee->state is NOT LINKED\n");
3487 ieee80211_softmac_stop_protocol(priv->ieee80211);
3490 RT_TRACE(COMP_RESET, "%s():<==========down process is finished\n", __func__);
3491 RT_TRACE(COMP_RESET, "%s():===========>start up the driver\n", __func__);
3492 reset_status = _rtl8192_up(dev);
3494 RT_TRACE(COMP_RESET, "%s():<===========up process is finished\n", __func__);
3495 if (reset_status == -EAGAIN) {
3496 if (reset_times < 3) {
3500 RT_TRACE(COMP_ERR, " ERR!!! %s(): Reset Failed!!\n", __func__);
3503 ieee->is_silent_reset = 1;
3504 EnableHWSecurityConfig8192(dev);
3505 if (ieee->state == IEEE80211_LINKED && ieee->iw_mode == IW_MODE_INFRA) {
3506 ieee->set_chan(ieee->dev, ieee->current_network.channel);
3508 queue_work(ieee->wq, &ieee->associate_complete_wq);
3510 } else if (ieee->state == IEEE80211_LINKED && ieee->iw_mode == IW_MODE_ADHOC) {
3511 ieee->set_chan(ieee->dev, ieee->current_network.channel);
3512 ieee->link_change(ieee->dev);
3514 ieee80211_start_send_beacons(ieee);
3516 if (ieee->data_hard_resume)
3517 ieee->data_hard_resume(ieee->dev);
3518 netif_carrier_on(ieee->dev);
3521 CamRestoreAllEntry(dev);
3523 priv->ResetProgress = RESET_TYPE_NORESET;
3524 priv->reset_count++;
3526 priv->bForcedSilentReset = false;
3527 priv->bResetInProgress = false;
3529 // For test --> force write UFWP.
3530 write_nic_byte(dev, UFWP, 1);
3531 RT_TRACE(COMP_RESET, "Reset finished!! ====>[%d]\n", priv->reset_count);
3535 void CAM_read_entry(struct net_device *dev, u32 iIndex)
3537 u32 target_command = 0;
3538 u32 target_content = 0;
3542 for (entry_i = 0; entry_i < CAM_CONTENT_COUNT; entry_i++) {
3543 // polling bit, and No Write enable, and address
3544 target_command = entry_i+CAM_CONTENT_COUNT*iIndex;
3545 target_command = target_command | BIT31;
3547 //Check polling bit is clear
3548 while ((i--) >= 0) {
3549 read_nic_dword(dev, RWCAM, &ulStatus);
3550 if (ulStatus & BIT31)
3555 write_nic_dword(dev, RWCAM, target_command);
3556 RT_TRACE(COMP_SEC, "CAM_read_entry(): WRITE A0: %x \n", target_command);
3557 read_nic_dword(dev, RCAMO, &target_content);
3558 RT_TRACE(COMP_SEC, "CAM_read_entry(): WRITE A8: %x \n", target_content);
3563 static void rtl819x_update_rxcounts(struct r8192_priv *priv, u32 *TotalRxBcnNum,
3564 u32 *TotalRxDataNum)
3570 *TotalRxDataNum = 0;
3572 SlotIndex = (priv->ieee80211->LinkDetectInfo.SlotIndex++)%(priv->ieee80211->LinkDetectInfo.SlotNum);
3573 priv->ieee80211->LinkDetectInfo.RxBcnNum[SlotIndex] = priv->ieee80211->LinkDetectInfo.NumRecvBcnInPeriod;
3574 priv->ieee80211->LinkDetectInfo.RxDataNum[SlotIndex] = priv->ieee80211->LinkDetectInfo.NumRecvDataInPeriod;
3575 for (i = 0; i < priv->ieee80211->LinkDetectInfo.SlotNum; i++) {
3576 *TotalRxBcnNum += priv->ieee80211->LinkDetectInfo.RxBcnNum[i];
3577 *TotalRxDataNum += priv->ieee80211->LinkDetectInfo.RxDataNum[i];
3582 void rtl819x_watchdog_wqcallback(struct work_struct *work)
3584 struct delayed_work *dwork = container_of(work, struct delayed_work, work);
3585 struct r8192_priv *priv = container_of(dwork, struct r8192_priv, watch_dog_wq);
3586 struct net_device *dev = priv->ieee80211->dev;
3587 struct ieee80211_device *ieee = priv->ieee80211;
3588 RESET_TYPE ResetType = RESET_TYPE_NORESET;
3589 static u8 check_reset_cnt;
3590 bool bBusyTraffic = false;
3591 u32 TotalRxBcnNum = 0;
3592 u32 TotalRxDataNum = 0;
3596 hal_dm_watchdog(dev);
3598 //to get busy traffic condition
3599 if (ieee->state == IEEE80211_LINKED) {
3600 if (ieee->LinkDetectInfo.NumRxOkInPeriod > 666 ||
3601 ieee->LinkDetectInfo.NumTxOkInPeriod > 666 ) {
3602 bBusyTraffic = true;
3604 ieee->LinkDetectInfo.NumRxOkInPeriod = 0;
3605 ieee->LinkDetectInfo.NumTxOkInPeriod = 0;
3606 ieee->LinkDetectInfo.bBusyTraffic = bBusyTraffic;
3608 //added by amy for AP roaming
3609 if (priv->ieee80211->state == IEEE80211_LINKED && priv->ieee80211->iw_mode == IW_MODE_INFRA) {
3611 rtl819x_update_rxcounts(priv, &TotalRxBcnNum, &TotalRxDataNum);
3612 if ((TotalRxBcnNum+TotalRxDataNum) == 0) {
3614 if (rfState == eRfOff)
3615 RT_TRACE(COMP_ERR, "========>%s()\n", __func__);
3617 netdev_dbg(dev, "===>%s(): AP is power off, connect another one\n", __func__);
3618 priv->ieee80211->state = IEEE80211_ASSOCIATING;
3619 notify_wx_assoc_event(priv->ieee80211);
3620 RemovePeerTS(priv->ieee80211, priv->ieee80211->current_network.bssid);
3621 priv->ieee80211->link_change(dev);
3622 queue_work(priv->ieee80211->wq, &priv->ieee80211->associate_procedure_wq);
3626 priv->ieee80211->LinkDetectInfo.NumRecvBcnInPeriod = 0;
3627 priv->ieee80211->LinkDetectInfo.NumRecvDataInPeriod = 0;
3628 //check if reset the driver
3629 if (check_reset_cnt++ >= 3) {
3630 ResetType = rtl819x_ifcheck_resetornot(dev);
3631 check_reset_cnt = 3;
3633 if ((priv->force_reset) || (priv->ResetProgress == RESET_TYPE_NORESET &&
3634 (priv->bForcedSilentReset ||
3635 (!priv->bDisableNormalResetCheck && ResetType == RESET_TYPE_SILENT)))) { /* This is control by OID set in Pomelo */
3636 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);
3637 rtl819x_ifsilentreset(dev);
3639 priv->force_reset = false;
3640 priv->bForcedSilentReset = false;
3641 priv->bResetInProgress = false;
3642 RT_TRACE(COMP_TRACE, " <==RtUsbCheckForHangWorkItemCallback()\n");
3646 void watch_dog_timer_callback(unsigned long data)
3648 struct r8192_priv *priv = ieee80211_priv((struct net_device *) data);
3649 queue_delayed_work(priv->priv_wq, &priv->watch_dog_wq, 0);
3650 mod_timer(&priv->watch_dog_timer, jiffies + MSECS(IEEE80211_WATCH_DOG_TIME));
3652 int _rtl8192_up(struct net_device *dev)
3654 struct r8192_priv *priv = ieee80211_priv(dev);
3655 int init_status = 0;
3657 priv->ieee80211->ieee_up = 1;
3658 RT_TRACE(COMP_INIT, "Bringing up iface");
3659 init_status = rtl8192_adapter_start(dev);
3661 RT_TRACE(COMP_ERR, "ERR!!! %s(): initialization failed!\n", __func__);
3662 priv->up = priv->ieee80211->ieee_up = 0;
3665 RT_TRACE(COMP_INIT, "start adapter finished\n");
3666 rtl8192_rx_enable(dev);
3667 if (priv->ieee80211->state != IEEE80211_LINKED)
3668 ieee80211_softmac_start_protocol(priv->ieee80211);
3669 ieee80211_reset_queue(priv->ieee80211);
3670 watch_dog_timer_callback((unsigned long) dev);
3671 if (!netif_queue_stopped(dev))
3672 netif_start_queue(dev);
3674 netif_wake_queue(dev);
3680 static int rtl8192_open(struct net_device *dev)
3682 struct r8192_priv *priv = ieee80211_priv(dev);
3684 down(&priv->wx_sem);
3685 ret = rtl8192_up(dev);
3692 int rtl8192_up(struct net_device *dev)
3694 struct r8192_priv *priv = ieee80211_priv(dev);
3699 return _rtl8192_up(dev);
3703 int rtl8192_close(struct net_device *dev)
3705 struct r8192_priv *priv = ieee80211_priv(dev);
3708 down(&priv->wx_sem);
3710 ret = rtl8192_down(dev);
3718 int rtl8192_down(struct net_device *dev)
3720 struct r8192_priv *priv = ieee80211_priv(dev);
3727 priv->ieee80211->ieee_up = 0;
3728 RT_TRACE(COMP_DOWN, "==========>%s()\n", __func__);
3730 if (!netif_queue_stopped(dev))
3731 netif_stop_queue(dev);
3733 rtl8192_rtx_disable(dev);
3735 /* Tx related queue release */
3736 for (i = 0; i < MAX_QUEUE_SIZE; i++)
3737 skb_queue_purge(&priv->ieee80211->skb_waitQ[i]);
3738 for (i = 0; i < MAX_QUEUE_SIZE; i++)
3739 skb_queue_purge(&priv->ieee80211->skb_aggQ[i]);
3741 for (i = 0; i < MAX_QUEUE_SIZE; i++)
3742 skb_queue_purge(&priv->ieee80211->skb_drv_aggQ[i]);
3744 //as cancel_delayed_work will del work->timer, so if work is not defined as struct delayed_work, it will corrupt
3745 rtl8192_cancel_deferred_work(priv);
3747 del_timer_sync(&priv->watch_dog_timer);
3750 ieee80211_softmac_stop_protocol(priv->ieee80211);
3751 memset(&priv->ieee80211->current_network, 0, offsetof(struct ieee80211_network, list));
3752 RT_TRACE(COMP_DOWN, "<==========%s()\n", __func__);
3758 void rtl8192_commit(struct net_device *dev)
3760 struct r8192_priv *priv = ieee80211_priv(dev);
3761 int reset_status = 0;
3766 rtl8192_cancel_deferred_work(priv);
3767 del_timer_sync(&priv->watch_dog_timer);
3769 ieee80211_softmac_stop_protocol(priv->ieee80211);
3771 rtl8192_rtx_disable(dev);
3772 reset_status = _rtl8192_up(dev);
3776 void rtl8192_restart(struct work_struct *work)
3778 struct r8192_priv *priv = container_of(work, struct r8192_priv, reset_wq);
3779 struct net_device *dev = priv->ieee80211->dev;
3781 down(&priv->wx_sem);
3783 rtl8192_commit(dev);
3788 static void r8192_set_multicast(struct net_device *dev)
3790 struct r8192_priv *priv = ieee80211_priv(dev);
3795 promisc = (dev->flags & IFF_PROMISC) ? 1 : 0;
3797 if (promisc != priv->promisc)
3799 priv->promisc = promisc;
3803 static int r8192_set_mac_adr(struct net_device *dev, void *mac)
3805 struct r8192_priv *priv = ieee80211_priv(dev);
3806 struct sockaddr *addr = mac;
3808 down(&priv->wx_sem);
3810 memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
3812 schedule_work(&priv->reset_wq);
3818 /* based on ipw2200 driver */
3819 static int rtl8192_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
3821 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
3822 struct iwreq *wrq = (struct iwreq *)rq;
3824 struct ieee80211_device *ieee = priv->ieee80211;
3826 u8 broadcast_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
3827 struct iw_point *p = &wrq->u.data;
3828 struct ieee_param *ipw = NULL;
3830 down(&priv->wx_sem);
3833 if (p->length < sizeof(struct ieee_param) || !p->pointer) {
3838 ipw = memdup_user(p->pointer, p->length);
3845 case RTL_IOCTL_WPA_SUPPLICANT:
3846 //parse here for HW security
3847 if (ipw->cmd == IEEE_CMD_SET_ENCRYPTION) {
3848 if (ipw->u.crypt.set_tx) {
3849 if (strcmp(ipw->u.crypt.alg, "CCMP") == 0) {
3850 ieee->pairwise_key_type = KEY_TYPE_CCMP;
3851 } else if (strcmp(ipw->u.crypt.alg, "TKIP") == 0) {
3852 ieee->pairwise_key_type = KEY_TYPE_TKIP;
3853 } else if (strcmp(ipw->u.crypt.alg, "WEP") == 0) {
3854 if (ipw->u.crypt.key_len == 13)
3855 ieee->pairwise_key_type = KEY_TYPE_WEP104;
3856 else if (ipw->u.crypt.key_len == 5)
3857 ieee->pairwise_key_type = KEY_TYPE_WEP40;
3859 ieee->pairwise_key_type = KEY_TYPE_NA;
3862 if (ieee->pairwise_key_type) {
3863 memcpy((u8 *)key, ipw->u.crypt.key, 16);
3864 EnableHWSecurityConfig8192(dev);
3865 //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!
3867 setKey(dev, 4, ipw->u.crypt.idx, ieee->pairwise_key_type, (u8 *)ieee->ap_mac_addr, 0, key);
3868 if (ieee->auth_mode != 2)
3869 setKey(dev, ipw->u.crypt.idx, ipw->u.crypt.idx, ieee->pairwise_key_type, (u8 *)ieee->ap_mac_addr, 0, key);
3872 memcpy((u8 *)key, ipw->u.crypt.key, 16);
3873 if (strcmp(ipw->u.crypt.alg, "CCMP") == 0) {
3874 ieee->group_key_type = KEY_TYPE_CCMP;
3875 } else if (strcmp(ipw->u.crypt.alg, "TKIP") == 0) {
3876 ieee->group_key_type = KEY_TYPE_TKIP;
3877 } else if (strcmp(ipw->u.crypt.alg, "WEP") == 0) {
3878 if (ipw->u.crypt.key_len == 13)
3879 ieee->group_key_type = KEY_TYPE_WEP104;
3880 else if (ipw->u.crypt.key_len == 5)
3881 ieee->group_key_type = KEY_TYPE_WEP40;
3883 ieee->group_key_type = KEY_TYPE_NA;
3886 if (ieee->group_key_type) {
3887 setKey(dev, ipw->u.crypt.idx,
3888 ipw->u.crypt.idx, //KeyIndex
3889 ieee->group_key_type, //KeyType
3890 broadcast_addr, //MacAddr
3896 ret = ieee80211_wpa_supplicant_ioctl(priv->ieee80211, &wrq->u.data);
3910 static u8 HwRateToMRate90(bool bIsHT, u8 rate)
3922 case DESC90_RATE5_5M:
3923 ret_rate = MGN_5_5M;
3925 case DESC90_RATE11M:
3934 case DESC90_RATE12M:
3937 case DESC90_RATE18M:
3940 case DESC90_RATE24M:
3943 case DESC90_RATE36M:
3946 case DESC90_RATE48M:
3949 case DESC90_RATE54M:
3955 RT_TRACE(COMP_RECV, "HwRateToMRate90(): Non supported Rate [%x], bIsHT = %d!!!\n", rate, bIsHT);
3961 case DESC90_RATEMCS0:
3962 ret_rate = MGN_MCS0;
3964 case DESC90_RATEMCS1:
3965 ret_rate = MGN_MCS1;
3967 case DESC90_RATEMCS2:
3968 ret_rate = MGN_MCS2;
3970 case DESC90_RATEMCS3:
3971 ret_rate = MGN_MCS3;
3973 case DESC90_RATEMCS4:
3974 ret_rate = MGN_MCS4;
3976 case DESC90_RATEMCS5:
3977 ret_rate = MGN_MCS5;
3979 case DESC90_RATEMCS6:
3980 ret_rate = MGN_MCS6;
3982 case DESC90_RATEMCS7:
3983 ret_rate = MGN_MCS7;
3985 case DESC90_RATEMCS8:
3986 ret_rate = MGN_MCS8;
3988 case DESC90_RATEMCS9:
3989 ret_rate = MGN_MCS9;
3991 case DESC90_RATEMCS10:
3992 ret_rate = MGN_MCS10;
3994 case DESC90_RATEMCS11:
3995 ret_rate = MGN_MCS11;
3997 case DESC90_RATEMCS12:
3998 ret_rate = MGN_MCS12;
4000 case DESC90_RATEMCS13:
4001 ret_rate = MGN_MCS13;
4003 case DESC90_RATEMCS14:
4004 ret_rate = MGN_MCS14;
4006 case DESC90_RATEMCS15:
4007 ret_rate = MGN_MCS15;
4009 case DESC90_RATEMCS32:
4010 ret_rate = (0x80|0x20);
4015 RT_TRACE(COMP_RECV, "HwRateToMRate90(): Non supported Rate [%x], bIsHT = %d!!!\n", rate, bIsHT);
4024 * Function: UpdateRxPktTimeStamp
4025 * Overview: Record the TSF time stamp when receiving a packet
4033 * (pRfd->Status.TimeStampHigh is updated)
4034 * (pRfd->Status.TimeStampLow is updated)
4038 static void UpdateRxPktTimeStamp8190(struct net_device *dev,
4039 struct ieee80211_rx_stats *stats)
4041 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
4043 if (stats->bIsAMPDU && !stats->bFirstMPDU) {
4044 stats->mac_time[0] = priv->LastRxDescTSFLow;
4045 stats->mac_time[1] = priv->LastRxDescTSFHigh;
4047 priv->LastRxDescTSFLow = stats->mac_time[0];
4048 priv->LastRxDescTSFHigh = stats->mac_time[1];
4054 static long rtl819x_translate_todbm(u8 signal_strength_index)// 0-100 index.
4056 long signal_power; // in dBm.
4058 // Translate to dBm (x=0.5y-95).
4059 signal_power = (long)((signal_strength_index + 1) >> 1);
4062 return signal_power;
4066 /* 2008/01/22 MH We can not declare RSSI/EVM total value of sliding window to
4067 be a local static. Otherwise, it may increase when we return from S3/S4. The
4068 value will be kept in memory or disk. Declare the value in the adaptor
4069 and it will be reinitialized when returned from S3/S4. */
4070 static void rtl8192_process_phyinfo(struct r8192_priv *priv, u8 *buffer,
4071 struct ieee80211_rx_stats *pprevious_stats,
4072 struct ieee80211_rx_stats *pcurrent_stats)
4074 bool bcheck = false;
4076 u32 nspatial_stream, tmp_val;
4077 static u32 slide_rssi_index, slide_rssi_statistics;
4078 static u32 slide_evm_index, slide_evm_statistics;
4079 static u32 last_rssi, last_evm;
4081 static u32 slide_beacon_adc_pwdb_index, slide_beacon_adc_pwdb_statistics;
4082 static u32 last_beacon_adc_pwdb;
4084 struct ieee80211_hdr_3addr *hdr;
4086 unsigned int frag, seq;
4087 hdr = (struct ieee80211_hdr_3addr *)buffer;
4088 sc = le16_to_cpu(hdr->seq_ctl);
4089 frag = WLAN_GET_SEQ_FRAG(sc);
4090 seq = WLAN_GET_SEQ_SEQ(sc);
4091 //cosa add 04292008 to record the sequence number
4092 pcurrent_stats->Seq_Num = seq;
4094 // Check whether we should take the previous packet into accounting
4096 if (!pprevious_stats->bIsAMPDU) {
4097 // if previous packet is not aggregated packet
4101 if (slide_rssi_statistics++ >= PHY_RSSI_SLID_WIN_MAX) {
4102 slide_rssi_statistics = PHY_RSSI_SLID_WIN_MAX;
4103 last_rssi = priv->stats.slide_signal_strength[slide_rssi_index];
4104 priv->stats.slide_rssi_total -= last_rssi;
4106 priv->stats.slide_rssi_total += pprevious_stats->SignalStrength;
4108 priv->stats.slide_signal_strength[slide_rssi_index++] = pprevious_stats->SignalStrength;
4109 if (slide_rssi_index >= PHY_RSSI_SLID_WIN_MAX)
4110 slide_rssi_index = 0;
4112 // <1> Showed on UI for user, in dbm
4113 tmp_val = priv->stats.slide_rssi_total/slide_rssi_statistics;
4114 priv->stats.signal_strength = rtl819x_translate_todbm((u8)tmp_val);
4115 pcurrent_stats->rssi = priv->stats.signal_strength;
4117 // If the previous packet does not match the criteria, neglect it
4119 if (!pprevious_stats->bPacketMatchBSSID) {
4120 if (!pprevious_stats->bToSelfBA)
4128 //rtl8190_process_cck_rxpathsel(priv,pprevious_stats);//only rtl8190 supported
4133 priv->stats.num_process_phyinfo++;
4135 /* record the general signal strength to the sliding window. */
4138 // <2> Showed on UI for engineering
4139 // hardware does not provide rssi information for each rf path in CCK
4140 if (!pprevious_stats->bIsCCK && (pprevious_stats->bPacketToSelf || pprevious_stats->bToSelfBA)) {
4141 for (rfpath = RF90_PATH_A; rfpath < priv->NumTotalRFPath; rfpath++) {
4142 if (!rtl8192_phy_CheckIsLegalRFPath(priv->ieee80211->dev, rfpath))
4145 //Fixed by Jacken 2008-03-20
4146 if (priv->stats.rx_rssi_percentage[rfpath] == 0)
4147 priv->stats.rx_rssi_percentage[rfpath] = pprevious_stats->RxMIMOSignalStrength[rfpath];
4148 if (pprevious_stats->RxMIMOSignalStrength[rfpath] > priv->stats.rx_rssi_percentage[rfpath]) {
4149 priv->stats.rx_rssi_percentage[rfpath] =
4150 ((priv->stats.rx_rssi_percentage[rfpath]*(Rx_Smooth_Factor-1)) +
4151 (pprevious_stats->RxMIMOSignalStrength[rfpath])) /(Rx_Smooth_Factor);
4152 priv->stats.rx_rssi_percentage[rfpath] = priv->stats.rx_rssi_percentage[rfpath] + 1;
4154 priv->stats.rx_rssi_percentage[rfpath] =
4155 ((priv->stats.rx_rssi_percentage[rfpath]*(Rx_Smooth_Factor-1)) +
4156 (pprevious_stats->RxMIMOSignalStrength[rfpath])) /(Rx_Smooth_Factor);
4158 RT_TRACE(COMP_DBG, "priv->stats.rx_rssi_percentage[rfPath] = %d \n", priv->stats.rx_rssi_percentage[rfpath]);
4166 RT_TRACE(COMP_RXDESC, "Smooth %s PWDB = %d\n",
4167 pprevious_stats->bIsCCK ? "CCK" : "OFDM",
4168 pprevious_stats->RxPWDBAll);
4170 if (pprevious_stats->bPacketBeacon) {
4171 /* record the beacon pwdb to the sliding window. */
4172 if (slide_beacon_adc_pwdb_statistics++ >= PHY_Beacon_RSSI_SLID_WIN_MAX) {
4173 slide_beacon_adc_pwdb_statistics = PHY_Beacon_RSSI_SLID_WIN_MAX;
4174 last_beacon_adc_pwdb = priv->stats.Slide_Beacon_pwdb[slide_beacon_adc_pwdb_index];
4175 priv->stats.Slide_Beacon_Total -= last_beacon_adc_pwdb;
4177 priv->stats.Slide_Beacon_Total += pprevious_stats->RxPWDBAll;
4178 priv->stats.Slide_Beacon_pwdb[slide_beacon_adc_pwdb_index] = pprevious_stats->RxPWDBAll;
4179 slide_beacon_adc_pwdb_index++;
4180 if (slide_beacon_adc_pwdb_index >= PHY_Beacon_RSSI_SLID_WIN_MAX)
4181 slide_beacon_adc_pwdb_index = 0;
4182 pprevious_stats->RxPWDBAll = priv->stats.Slide_Beacon_Total/slide_beacon_adc_pwdb_statistics;
4183 if (pprevious_stats->RxPWDBAll >= 3)
4184 pprevious_stats->RxPWDBAll -= 3;
4187 RT_TRACE(COMP_RXDESC, "Smooth %s PWDB = %d\n",
4188 pprevious_stats->bIsCCK ? "CCK" : "OFDM",
4189 pprevious_stats->RxPWDBAll);
4192 if (pprevious_stats->bPacketToSelf || pprevious_stats->bPacketBeacon || pprevious_stats->bToSelfBA) {
4193 if (priv->undecorated_smoothed_pwdb < 0) /* initialize */
4194 priv->undecorated_smoothed_pwdb = pprevious_stats->RxPWDBAll;
4195 if (pprevious_stats->RxPWDBAll > (u32)priv->undecorated_smoothed_pwdb) {
4196 priv->undecorated_smoothed_pwdb =
4197 (((priv->undecorated_smoothed_pwdb)*(Rx_Smooth_Factor-1)) +
4198 (pprevious_stats->RxPWDBAll)) /(Rx_Smooth_Factor);
4199 priv->undecorated_smoothed_pwdb = priv->undecorated_smoothed_pwdb + 1;
4201 priv->undecorated_smoothed_pwdb =
4202 (((priv->undecorated_smoothed_pwdb)*(Rx_Smooth_Factor-1)) +
4203 (pprevious_stats->RxPWDBAll)) /(Rx_Smooth_Factor);
4211 /* record the general EVM to the sliding window. */
4212 if (pprevious_stats->SignalQuality) {
4213 if (pprevious_stats->bPacketToSelf || pprevious_stats->bPacketBeacon || pprevious_stats->bToSelfBA) {
4214 if (slide_evm_statistics++ >= PHY_RSSI_SLID_WIN_MAX) {
4215 slide_evm_statistics = PHY_RSSI_SLID_WIN_MAX;
4216 last_evm = priv->stats.slide_evm[slide_evm_index];
4217 priv->stats.slide_evm_total -= last_evm;
4220 priv->stats.slide_evm_total += pprevious_stats->SignalQuality;
4222 priv->stats.slide_evm[slide_evm_index++] = pprevious_stats->SignalQuality;
4223 if (slide_evm_index >= PHY_RSSI_SLID_WIN_MAX)
4224 slide_evm_index = 0;
4226 // <1> Showed on UI for user, in percentage.
4227 tmp_val = priv->stats.slide_evm_total/slide_evm_statistics;
4228 priv->stats.signal_quality = tmp_val;
4229 //cosa add 10/11/2007, Showed on UI for user in Windows Vista, for Link quality.
4230 priv->stats.last_signal_strength_inpercent = tmp_val;
4233 // <2> Showed on UI for engineering
4234 if (pprevious_stats->bPacketToSelf || pprevious_stats->bPacketBeacon || pprevious_stats->bToSelfBA) {
4235 for (nspatial_stream = 0; nspatial_stream < 2; nspatial_stream++) { /* 2 spatial stream */
4236 if (pprevious_stats->RxMIMOSignalQuality[nspatial_stream] != -1) {
4237 if (priv->stats.rx_evm_percentage[nspatial_stream] == 0) /* initialize */
4238 priv->stats.rx_evm_percentage[nspatial_stream] = pprevious_stats->RxMIMOSignalQuality[nspatial_stream];
4239 priv->stats.rx_evm_percentage[nspatial_stream] =
4240 ((priv->stats.rx_evm_percentage[nspatial_stream]* (Rx_Smooth_Factor-1)) +
4241 (pprevious_stats->RxMIMOSignalQuality[nspatial_stream]* 1)) / (Rx_Smooth_Factor);
4250 /*-----------------------------------------------------------------------------
4251 * Function: rtl819x_query_rxpwrpercentage()
4255 * Input: char antpower
4259 * Return: 0-100 percentage
4263 * 05/26/2008 amy Create Version 0 porting from windows code.
4265 *---------------------------------------------------------------------------*/
4266 static u8 rtl819x_query_rxpwrpercentage(char antpower)
4268 if ((antpower <= -100) || (antpower >= 20))
4270 else if (antpower >= 0)
4273 return 100 + antpower;
4275 } /* QueryRxPwrPercentage */
4277 static u8 rtl819x_evm_dbtopercentage(char value)
4287 ret_val = 0 - ret_val;
4295 // We want good-looking for signal strength/quality
4296 // 2007/7/19 01:09, by cosa.
4298 static long rtl819x_signal_scale_mapping(long currsig)
4302 // Step 1. Scale mapping.
4303 if (currsig >= 61 && currsig <= 100)
4304 retsig = 90 + ((currsig - 60) / 4);
4305 else if (currsig >= 41 && currsig <= 60)
4306 retsig = 78 + ((currsig - 40) / 2);
4307 else if (currsig >= 31 && currsig <= 40)
4308 retsig = 66 + (currsig - 30);
4309 else if (currsig >= 21 && currsig <= 30)
4310 retsig = 54 + (currsig - 20);
4311 else if (currsig >= 5 && currsig <= 20)
4312 retsig = 42 + (((currsig - 5) * 2) / 3);
4313 else if (currsig == 4)
4315 else if (currsig == 3)
4317 else if (currsig == 2)
4319 else if (currsig == 1)
4327 static inline bool rx_hal_is_cck_rate(struct rx_drvinfo_819x_usb *pdrvinfo)
4332 switch (pdrvinfo->RxRate) {
4335 case DESC90_RATE5_5M:
4336 case DESC90_RATE11M:
4343 static void rtl8192_query_rxphystatus(struct r8192_priv *priv,
4344 struct ieee80211_rx_stats *pstats,
4345 rx_drvinfo_819x_usb *pdrvinfo,
4346 struct ieee80211_rx_stats *precord_stats,
4347 bool bpacket_match_bssid,
4348 bool bpacket_toself,
4352 phy_sts_ofdm_819xusb_t *pofdm_buf;
4353 phy_sts_cck_819xusb_t *pcck_buf;
4354 phy_ofdm_rx_status_rxsc_sgien_exintfflag *prxsc;
4356 u8 i, max_spatial_stream, tmp_rxsnr, tmp_rxevm, rxsc_sgien_exflg;
4357 char rx_pwr[4], rx_pwr_all = 0;
4358 char rx_snrX, rx_evmX;
4360 u32 RSSI, total_rssi = 0;
4366 priv->stats.numqry_phystatus++;
4368 is_cck_rate = rx_hal_is_cck_rate(pdrvinfo);
4370 // Record it for next packet processing
4371 memset(precord_stats, 0, sizeof(struct ieee80211_rx_stats));
4372 pstats->bPacketMatchBSSID = precord_stats->bPacketMatchBSSID = bpacket_match_bssid;
4373 pstats->bPacketToSelf = precord_stats->bPacketToSelf = bpacket_toself;
4374 pstats->bIsCCK = precord_stats->bIsCCK = is_cck_rate;
4375 pstats->bPacketBeacon = precord_stats->bPacketBeacon = bPacketBeacon;
4376 pstats->bToSelfBA = precord_stats->bToSelfBA = bToSelfBA;
4378 prxpkt = (u8 *)pdrvinfo;
4380 /* Move pointer to the 16th bytes. Phy status start address. */
4381 prxpkt += sizeof(rx_drvinfo_819x_usb);
4383 /* Initial the cck and ofdm buffer pointer */
4384 pcck_buf = (phy_sts_cck_819xusb_t *)prxpkt;
4385 pofdm_buf = (phy_sts_ofdm_819xusb_t *)prxpkt;
4387 pstats->RxMIMOSignalQuality[0] = -1;
4388 pstats->RxMIMOSignalQuality[1] = -1;
4389 precord_stats->RxMIMOSignalQuality[0] = -1;
4390 precord_stats->RxMIMOSignalQuality[1] = -1;
4394 // (1)Hardware does not provide RSSI for CCK
4398 // (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive)
4402 priv->stats.numqry_phystatusCCK++;
4404 if (!priv->bCckHighPower) {
4405 report = pcck_buf->cck_agc_rpt & 0xc0;
4408 //Fixed by Jacken from Bryant 2008-03-20
4409 //Original value is -38 , -26 , -14 , -2
4410 //Fixed value is -35 , -23 , -11 , 6
4412 rx_pwr_all = -35 - (pcck_buf->cck_agc_rpt & 0x3e);
4415 rx_pwr_all = -23 - (pcck_buf->cck_agc_rpt & 0x3e);
4418 rx_pwr_all = -11 - (pcck_buf->cck_agc_rpt & 0x3e);
4421 rx_pwr_all = 6 - (pcck_buf->cck_agc_rpt & 0x3e);
4425 report = pcck_buf->cck_agc_rpt & 0x60;
4429 rx_pwr_all = -35 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1);
4432 rx_pwr_all = -23 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1);
4435 rx_pwr_all = -11 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1);
4438 rx_pwr_all = 6 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1);
4443 pwdb_all = rtl819x_query_rxpwrpercentage(rx_pwr_all);
4444 pstats->RxPWDBAll = precord_stats->RxPWDBAll = pwdb_all;
4445 pstats->RecvSignalPower = pwdb_all;
4448 // (3) Get Signal Quality (EVM)
4451 if (pstats->RxPWDBAll > 40) {
4454 sq = pcck_buf->sq_rpt;
4456 if (pcck_buf->sq_rpt > 64)
4458 else if (pcck_buf->sq_rpt < 20)
4461 sq = ((64-sq) * 100) / 44;
4463 pstats->SignalQuality = precord_stats->SignalQuality = sq;
4464 pstats->RxMIMOSignalQuality[0] = precord_stats->RxMIMOSignalQuality[0] = sq;
4465 pstats->RxMIMOSignalQuality[1] = precord_stats->RxMIMOSignalQuality[1] = -1;
4468 priv->stats.numqry_phystatusHT++;
4470 // (1)Get RSSI for HT rate
4472 for (i = RF90_PATH_A; i < priv->NumTotalRFPath; i++) {
4473 // 2008/01/30 MH we will judge RF RX path now.
4474 if (priv->brfpath_rxenable[i])
4479 if (!rtl8192_phy_CheckIsLegalRFPath(priv->ieee80211->dev, i))
4482 //Fixed by Jacken from Bryant 2008-03-20
4483 //Original value is 106
4484 rx_pwr[i] = ((pofdm_buf->trsw_gain_X[i]&0x3F)*2) - 106;
4486 //Get Rx snr value in DB
4487 tmp_rxsnr = pofdm_buf->rxsnr_X[i];
4488 rx_snrX = (char)(tmp_rxsnr);
4490 priv->stats.rxSNRdB[i] = (long)rx_snrX;
4492 /* Translate DBM to percentage. */
4493 RSSI = rtl819x_query_rxpwrpercentage(rx_pwr[i]);
4496 /* Record Signal Strength for next packet */
4497 pstats->RxMIMOSignalStrength[i] = (u8) RSSI;
4498 precord_stats->RxMIMOSignalStrength[i] = (u8) RSSI;
4503 // (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive)
4505 //Fixed by Jacken from Bryant 2008-03-20
4506 //Original value is 106
4507 rx_pwr_all = (((pofdm_buf->pwdb_all) >> 1)& 0x7f) -106;
4508 pwdb_all = rtl819x_query_rxpwrpercentage(rx_pwr_all);
4510 pstats->RxPWDBAll = precord_stats->RxPWDBAll = pwdb_all;
4511 pstats->RxPower = precord_stats->RxPower = rx_pwr_all;
4514 // (3)EVM of HT rate
4516 if (pdrvinfo->RxHT && pdrvinfo->RxRate >= DESC90_RATEMCS8 &&
4517 pdrvinfo->RxRate <= DESC90_RATEMCS15)
4518 max_spatial_stream = 2; //both spatial stream make sense
4520 max_spatial_stream = 1; //only spatial stream 1 makes sense
4522 for (i = 0; i < max_spatial_stream; i++) {
4523 tmp_rxevm = pofdm_buf->rxevm_X[i];
4524 rx_evmX = (char)(tmp_rxevm);
4526 // Do not use shift operation like "rx_evmX >>= 1" because the compiler of free build environment
4527 // will set the most significant bit to "zero" when doing shifting operation which may change a negative
4528 // value to positive one, then the dbm value (which is supposed to be negative) is not correct anymore.
4531 evm = rtl819x_evm_dbtopercentage(rx_evmX);
4532 if (i == 0) /* Fill value in RFD, Get the first spatial stream only */
4533 pstats->SignalQuality = precord_stats->SignalQuality = (u8)(evm & 0xff);
4534 pstats->RxMIMOSignalQuality[i] = precord_stats->RxMIMOSignalQuality[i] = (u8)(evm & 0xff);
4538 /* record rx statistics for debug */
4539 rxsc_sgien_exflg = pofdm_buf->rxsc_sgien_exflg;
4540 prxsc = (phy_ofdm_rx_status_rxsc_sgien_exintfflag *)&rxsc_sgien_exflg;
4541 if (pdrvinfo->BW) /* 40M channel */
4542 priv->stats.received_bwtype[1+prxsc->rxsc]++;
4544 priv->stats.received_bwtype[0]++;
4547 //UI BSS List signal strength(in percentage), make it good looking, from 0~100.
4548 //It is assigned to the BSS List in GetValueFromBeaconOrProbeRsp().
4550 pstats->SignalStrength = precord_stats->SignalStrength = (u8)(rtl819x_signal_scale_mapping((long)pwdb_all));
4552 // We can judge RX path number now.
4554 pstats->SignalStrength = precord_stats->SignalStrength = (u8)(rtl819x_signal_scale_mapping((long)(total_rssi /= rf_rx_num)));
4556 } /* QueryRxPhyStatus8190Pci */
4558 static void rtl8192_record_rxdesc_forlateruse(struct ieee80211_rx_stats *psrc_stats,
4559 struct ieee80211_rx_stats *ptarget_stats)
4561 ptarget_stats->bIsAMPDU = psrc_stats->bIsAMPDU;
4562 ptarget_stats->bFirstMPDU = psrc_stats->bFirstMPDU;
4563 ptarget_stats->Seq_Num = psrc_stats->Seq_Num;
4567 static void TranslateRxSignalStuff819xUsb(struct sk_buff *skb,
4568 struct ieee80211_rx_stats *pstats,
4569 rx_drvinfo_819x_usb *pdrvinfo)
4571 // TODO: We must only check packet for current MAC address. Not finish
4572 rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
4573 struct net_device *dev = info->dev;
4574 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
4575 bool bpacket_match_bssid, bpacket_toself;
4576 bool bPacketBeacon = FALSE, bToSelfBA = FALSE;
4577 static struct ieee80211_rx_stats previous_stats;
4578 struct ieee80211_hdr_3addr *hdr;//by amy
4581 // Get Signal Quality for only RX data queue (but not command queue)
4586 /* Get MAC frame start address. */
4587 tmp_buf = (u8 *)skb->data;
4589 hdr = (struct ieee80211_hdr_3addr *)tmp_buf;
4590 fc = le16_to_cpu(hdr->frame_ctl);
4591 type = WLAN_FC_GET_TYPE(fc);
4592 praddr = hdr->addr1;
4594 /* Check if the received packet is acceptable. */
4595 bpacket_match_bssid = ((IEEE80211_FTYPE_CTL != type) &&
4596 (eqMacAddr(priv->ieee80211->current_network.bssid, (fc & IEEE80211_FCTL_TODS) ? hdr->addr1 : (fc & IEEE80211_FCTL_FROMDS) ? hdr->addr2 : hdr->addr3))
4597 && (!pstats->bHwError) && (!pstats->bCRC) && (!pstats->bICV));
4598 bpacket_toself = bpacket_match_bssid & (eqMacAddr(praddr, priv->ieee80211->dev->dev_addr));
4600 if (WLAN_FC_GET_FRAMETYPE(fc) == IEEE80211_STYPE_BEACON)
4601 bPacketBeacon = true;
4602 if (WLAN_FC_GET_FRAMETYPE(fc) == IEEE80211_STYPE_BLOCKACK) {
4603 if ((eqMacAddr(praddr, dev->dev_addr)))
4609 if (bpacket_match_bssid)
4610 priv->stats.numpacket_matchbssid++;
4612 priv->stats.numpacket_toself++;
4614 // Process PHY information for previous packet (RSSI/PWDB/EVM)
4616 // Because phy information is contained in the last packet of AMPDU only, so driver
4617 // should process phy information of previous packet
4618 rtl8192_process_phyinfo(priv, tmp_buf, &previous_stats, pstats);
4619 rtl8192_query_rxphystatus(priv, pstats, pdrvinfo, &previous_stats, bpacket_match_bssid, bpacket_toself, bPacketBeacon, bToSelfBA);
4620 rtl8192_record_rxdesc_forlateruse(pstats, &previous_stats);
4625 * Function: UpdateReceivedRateHistogramStatistics
4626 * Overview: Record the received data rate
4629 * struct net_device *dev
4630 * struct ieee80211_rx_stats *stats
4634 * (priv->stats.ReceivedRateHistogram[] is updated)
4639 UpdateReceivedRateHistogramStatistics8190(struct net_device *dev,
4640 struct ieee80211_rx_stats *stats)
4642 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
4643 u32 rcvType = 1; //0: Total, 1:OK, 2:CRC, 3:ICV
4645 u32 preamble_guardinterval; //1: short preamble/GI, 0: long preamble/GI
4650 else if (stats->bICV)
4653 if (stats->bShortPreamble)
4654 preamble_guardinterval = 1;// short
4656 preamble_guardinterval = 0;// long
4658 switch (stats->rate) {
4702 // 11n High throughput rate
4756 priv->stats.received_preamble_GI[preamble_guardinterval][rateIndex]++;
4757 priv->stats.received_rate_histogram[0][rateIndex]++; //total
4758 priv->stats.received_rate_histogram[rcvType][rateIndex]++;
4762 static void query_rxdesc_status(struct sk_buff *skb,
4763 struct ieee80211_rx_stats *stats,
4764 bool bIsRxAggrSubframe)
4766 rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
4767 struct net_device *dev = info->dev;
4768 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
4769 rx_drvinfo_819x_usb *driver_info = NULL;
4772 //Get Rx Descriptor Information
4774 #ifdef USB_RX_AGGREGATION_SUPPORT
4775 if (bIsRxAggrSubframe) {
4776 rx_desc_819x_usb_aggr_subframe *desc = (rx_desc_819x_usb_aggr_subframe *)skb->data;
4777 stats->Length = desc->Length;
4778 stats->RxDrvInfoSize = desc->RxDrvInfoSize;
4779 stats->RxBufShift = 0; //RxBufShift = 2 in RxDesc, but usb didn't shift bytes in fact.
4780 stats->bICV = desc->ICV;
4781 stats->bCRC = desc->CRC32;
4782 stats->bHwError = stats->bCRC|stats->bICV;
4783 stats->Decrypted = !desc->SWDec;//RTL8190 set this bit to indicate that Hw does not decrypt packet
4787 rx_desc_819x_usb *desc = (rx_desc_819x_usb *)skb->data;
4789 stats->Length = desc->Length;
4790 stats->RxDrvInfoSize = desc->RxDrvInfoSize;
4791 stats->RxBufShift = 0;
4792 stats->bICV = desc->ICV;
4793 stats->bCRC = desc->CRC32;
4794 stats->bHwError = stats->bCRC|stats->bICV;
4795 //RTL8190 set this bit to indicate that Hw does not decrypt packet
4796 stats->Decrypted = !desc->SWDec;
4799 if ((priv->ieee80211->pHTInfo->bCurrentHTSupport == true) && (priv->ieee80211->pairwise_key_type == KEY_TYPE_CCMP))
4800 stats->bHwError = false;
4802 stats->bHwError = stats->bCRC|stats->bICV;
4804 if (stats->Length < 24 || stats->Length > MAX_8192U_RX_SIZE)
4805 stats->bHwError |= 1;
4809 // TODO: Need to verify it on FGPA platform
4810 //Driver info are written to the RxBuffer following rx desc
4811 if (stats->RxDrvInfoSize != 0) {
4812 driver_info = (rx_drvinfo_819x_usb *)(skb->data + sizeof(rx_desc_819x_usb) +
4816 if (!stats->bHwError) {
4818 ret_rate = HwRateToMRate90(driver_info->RxHT, driver_info->RxRate);
4819 if (ret_rate == 0xff) {
4820 // Abnormal Case: Receive CRC OK packet with Rx descriptor indicating non supported rate.
4821 // Special Error Handling here, 2008.05.16, by Emily
4823 stats->bHwError = 1;
4824 stats->rate = MGN_1M; //Set 1M rate by default
4826 stats->rate = ret_rate;
4832 stats->bShortPreamble = driver_info->SPLCP;
4835 UpdateReceivedRateHistogramStatistics8190(dev, stats);
4837 stats->bIsAMPDU = (driver_info->PartAggr == 1);
4838 stats->bFirstMPDU = (driver_info->PartAggr == 1) && (driver_info->FirstAGGR == 1);
4839 stats->TimeStampLow = driver_info->TSFL;
4840 // xiong mask it, 070514
4842 UpdateRxPktTimeStamp8190(dev, stats);
4847 if (driver_info->FirstAGGR == 1 || driver_info->PartAggr == 1)
4848 RT_TRACE(COMP_RXDESC, "driver_info->FirstAGGR = %d, driver_info->PartAggr = %d\n",
4849 driver_info->FirstAGGR, driver_info->PartAggr);
4853 skb_pull(skb, sizeof(rx_desc_819x_usb));
4855 // Get Total offset of MPDU Frame Body
4857 if ((stats->RxBufShift + stats->RxDrvInfoSize) > 0) {
4859 skb_pull(skb, stats->RxBufShift + stats->RxDrvInfoSize);
4862 #ifdef USB_RX_AGGREGATION_SUPPORT
4863 /* for the rx aggregated sub frame, the redundant space truly contained in the packet */
4864 if (bIsRxAggrSubframe)
4867 /* for debug 2008.5.29 */
4869 //added by vivi, for MP, 20080108
4870 stats->RxIs40MHzPacket = driver_info->BW;
4871 if (stats->RxDrvInfoSize != 0)
4872 TranslateRxSignalStuff819xUsb(skb, stats, driver_info);
4876 u32 GetRxPacketShiftBytes819xUsb(struct ieee80211_rx_stats *Status, bool bIsRxAggrSubframe)
4878 #ifdef USB_RX_AGGREGATION_SUPPORT
4879 if (bIsRxAggrSubframe)
4880 return (sizeof(rx_desc_819x_usb) + Status->RxDrvInfoSize
4881 + Status->RxBufShift + 8);
4884 return (sizeof(rx_desc_819x_usb) + Status->RxDrvInfoSize
4885 + Status->RxBufShift);
4888 static void rtl8192_rx_nomal(struct sk_buff *skb)
4890 rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
4891 struct net_device *dev = info->dev;
4892 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
4893 struct ieee80211_rx_stats stats = {
4897 .freq = IEEE80211_24GHZ_BAND,
4900 struct ieee80211_hdr_1addr *ieee80211_hdr = NULL;
4901 bool unicast_packet = false;
4902 #ifdef USB_RX_AGGREGATION_SUPPORT
4903 struct sk_buff *agg_skb = NULL;
4904 u32 TotalLength = 0;
4906 u32 PacketLength = 0;
4907 u32 PacketOccupiedLendth = 0;
4909 u32 PacketShiftBytes = 0;
4910 rx_desc_819x_usb_aggr_subframe *RxDescr = NULL;
4911 u8 PaddingBytes = 0;
4912 //add just for testing
4917 /* 20 is for ps-poll */
4918 if ((skb->len >= (20 + sizeof(rx_desc_819x_usb))) && (skb->len < RX_URB_SIZE)) {
4919 #ifdef USB_RX_AGGREGATION_SUPPORT
4920 TempByte = *(skb->data + sizeof(rx_desc_819x_usb));
4922 /* first packet should not contain Rx aggregation header */
4923 query_rxdesc_status(skb, &stats, false);
4925 /* hardware related info */
4926 #ifdef USB_RX_AGGREGATION_SUPPORT
4927 if (TempByte & BIT0) {
4929 TotalLength = stats.Length - 4; /*sCrcLng*/
4930 /* though the head pointer has passed this position */
4931 TempDWord = *(u32 *)(agg_skb->data - 4);
4932 PacketLength = (u16)(TempDWord & 0x3FFF); /*sCrcLng*/
4933 skb = dev_alloc_skb(PacketLength);
4934 memcpy(skb_put(skb, PacketLength), agg_skb->data, PacketLength);
4935 PacketShiftBytes = GetRxPacketShiftBytes819xUsb(&stats, false);
4938 /* Process the MPDU received */
4939 skb_trim(skb, skb->len - 4/*sCrcLng*/);
4941 rx_pkt_len = skb->len;
4942 ieee80211_hdr = (struct ieee80211_hdr_1addr *)skb->data;
4943 unicast_packet = false;
4944 if (is_broadcast_ether_addr(ieee80211_hdr->addr1)) {
4946 } else if (is_multicast_ether_addr(ieee80211_hdr->addr1)) {
4949 /* unicast packet */
4950 unicast_packet = true;
4953 if (!ieee80211_rx(priv->ieee80211, skb, &stats)) {
4954 dev_kfree_skb_any(skb);
4956 priv->stats.rxoktotal++;
4958 priv->stats.rxbytesunicast += rx_pkt_len;
4960 #ifdef USB_RX_AGGREGATION_SUPPORT
4962 if (TotalLength > 0) {
4963 PacketOccupiedLendth = PacketLength + (PacketShiftBytes + 8);
4964 if ((PacketOccupiedLendth & 0xFF) != 0)
4965 PacketOccupiedLendth = (PacketOccupiedLendth & 0xFFFFFF00) + 256;
4966 PacketOccupiedLendth -= 8;
4967 TempDWord = PacketOccupiedLendth - PacketShiftBytes; /*- PacketLength */
4968 if (agg_skb->len > TempDWord)
4969 skb_pull(agg_skb, TempDWord);
4973 while (agg_skb->len >= GetRxPacketShiftBytes819xUsb(&stats, true)) {
4974 u8 tmpCRC = 0, tmpICV = 0;
4975 RxDescr = (rx_desc_819x_usb_aggr_subframe *)(agg_skb->data);
4976 tmpCRC = RxDescr->CRC32;
4977 tmpICV = RxDescr->ICV;
4978 memcpy(agg_skb->data, &agg_skb->data[44], 2);
4979 RxDescr->CRC32 = tmpCRC;
4980 RxDescr->ICV = tmpICV;
4982 memset(&stats, 0, sizeof(struct ieee80211_rx_stats));
4986 stats.freq = IEEE80211_24GHZ_BAND;
4987 query_rxdesc_status(agg_skb, &stats, true);
4988 PacketLength = stats.Length;
4990 if (PacketLength > agg_skb->len)
4992 /* Process the MPDU received */
4993 skb = dev_alloc_skb(PacketLength);
4994 memcpy(skb_put(skb, PacketLength), agg_skb->data, PacketLength);
4995 skb_trim(skb, skb->len - 4/*sCrcLng*/);
4997 rx_pkt_len = skb->len;
4998 ieee80211_hdr = (struct ieee80211_hdr_1addr *)skb->data;
4999 unicast_packet = false;
5000 if (is_broadcast_ether_addr(ieee80211_hdr->addr1)) {
5002 } else if (is_multicast_ether_addr(ieee80211_hdr->addr1)) {
5005 /* unicast packet */
5006 unicast_packet = true;
5008 if (!ieee80211_rx(priv->ieee80211, skb, &stats)) {
5009 dev_kfree_skb_any(skb);
5011 priv->stats.rxoktotal++;
5013 priv->stats.rxbytesunicast += rx_pkt_len;
5015 /* should trim the packet which has been copied to target skb */
5016 skb_pull(agg_skb, PacketLength);
5017 PacketShiftBytes = GetRxPacketShiftBytes819xUsb(&stats, true);
5018 PacketOccupiedLendth = PacketLength + PacketShiftBytes;
5019 if ((PacketOccupiedLendth & 0xFF) != 0) {
5020 PaddingBytes = 256 - (PacketOccupiedLendth & 0xFF);
5021 if (agg_skb->len > PaddingBytes)
5022 skb_pull(agg_skb, PaddingBytes);
5027 dev_kfree_skb(agg_skb);
5031 priv->stats.rxurberr++;
5032 netdev_dbg(dev, "actual_length: %d\n", skb->len);
5033 dev_kfree_skb_any(skb);
5038 static void rtl819xusb_process_received_packet(struct net_device *dev,
5039 struct ieee80211_rx_stats *pstats)
5043 struct r8192_priv *priv = ieee80211_priv(dev);
5045 // Get shifted bytes of Starting address of 802.11 header. 2006.09.28, by Emily
5046 //porting by amy 080508
5047 pstats->virtual_address += get_rxpacket_shiftbytes_819xusb(pstats);
5048 frame = pstats->virtual_address;
5049 frame_len = pstats->packetlength;
5050 #ifdef TODO // by amy about HCT
5051 if (!Adapter->bInHctTest)
5052 CountRxErrStatistics(Adapter, pRfd);
5054 #ifdef ENABLE_PS //by amy for adding ps function in future
5055 RT_RF_POWER_STATE rtState;
5056 // When RF is off, we should not count the packet for hw/sw synchronize
5057 // reason, ie. there may be a duration while sw switch is changed and hw
5058 // switch is being changed. 2006.12.04, by shien chang.
5059 Adapter->HalFunc.GetHwRegHandler(Adapter, HW_VAR_RF_STATE, (u8 *)(&rtState));
5060 if (rtState == eRfOff)
5063 priv->stats.rxframgment++;
5066 RmMonitorSignalStrength(Adapter, pRfd);
5068 /* 2007/01/16 MH Add RX command packet handle here. */
5069 /* 2007/03/01 MH We have to release RFD and return if rx pkt is cmd pkt. */
5070 if (rtl819xusb_rx_command_packet(dev, pstats))
5080 static void query_rx_cmdpkt_desc_status(struct sk_buff *skb,
5081 struct ieee80211_rx_stats *stats)
5083 rx_desc_819x_usb *desc = (rx_desc_819x_usb *)skb->data;
5086 //Get Rx Descriptor Information
5088 stats->virtual_address = (u8 *)skb->data;
5089 stats->Length = desc->Length;
5090 stats->RxDrvInfoSize = 0;
5091 stats->RxBufShift = 0;
5092 stats->packetlength = stats->Length-scrclng;
5093 stats->fraglength = stats->packetlength;
5094 stats->fragoffset = 0;
5095 stats->ntotalfrag = 1;
5099 static void rtl8192_rx_cmd(struct sk_buff *skb)
5101 struct rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
5102 struct net_device *dev = info->dev;
5104 struct ieee80211_rx_stats stats = {
5108 .freq = IEEE80211_24GHZ_BAND,
5111 if ((skb->len >= (20 + sizeof(rx_desc_819x_usb))) && (skb->len < RX_URB_SIZE)) {
5113 query_rx_cmdpkt_desc_status(skb, &stats);
5114 // this is to be done by amy 080508 prfd->queue_id = 1;
5118 // Process the command packet received.
5121 rtl819xusb_process_received_packet(dev, &stats);
5123 dev_kfree_skb_any(skb);
5127 void rtl8192_irq_rx_tasklet(struct r8192_priv *priv)
5129 struct sk_buff *skb;
5130 struct rtl8192_rx_info *info;
5132 while (NULL != (skb = skb_dequeue(&priv->skb_queue))) {
5133 info = (struct rtl8192_rx_info *)skb->cb;
5134 switch (info->out_pipe) {
5135 /* Nomal packet pipe */
5137 priv->IrpPendingCount--;
5138 rtl8192_rx_nomal(skb);
5141 /* Command packet pipe */
5143 RT_TRACE(COMP_RECV, "command in-pipe index(%d)\n",
5146 rtl8192_rx_cmd(skb);
5149 default: /* should never get here! */
5150 RT_TRACE(COMP_ERR, "Unknown in-pipe index(%d)\n",
5159 static const struct net_device_ops rtl8192_netdev_ops = {
5160 .ndo_open = rtl8192_open,
5161 .ndo_stop = rtl8192_close,
5162 .ndo_get_stats = rtl8192_stats,
5163 .ndo_tx_timeout = tx_timeout,
5164 .ndo_do_ioctl = rtl8192_ioctl,
5165 .ndo_set_rx_mode = r8192_set_multicast,
5166 .ndo_set_mac_address = r8192_set_mac_adr,
5167 .ndo_validate_addr = eth_validate_addr,
5168 .ndo_change_mtu = eth_change_mtu,
5169 .ndo_start_xmit = ieee80211_xmit,
5173 /****************************************************************************
5174 ---------------------------- USB_STUFF---------------------------
5175 *****************************************************************************/
5177 static int rtl8192_usb_probe(struct usb_interface *intf,
5178 const struct usb_device_id *id)
5180 struct net_device *dev = NULL;
5181 struct r8192_priv *priv = NULL;
5182 struct usb_device *udev = interface_to_usbdev(intf);
5184 RT_TRACE(COMP_INIT, "Oops: i'm coming\n");
5186 dev = alloc_ieee80211(sizeof(struct r8192_priv));
5190 usb_set_intfdata(intf, dev);
5191 SET_NETDEV_DEV(dev, &intf->dev);
5192 priv = ieee80211_priv(dev);
5193 priv->ieee80211 = netdev_priv(dev);
5196 dev->netdev_ops = &rtl8192_netdev_ops;
5198 dev->wireless_handlers = (struct iw_handler_def *) &r8192_wx_handlers_def;
5200 dev->type = ARPHRD_ETHER;
5202 dev->watchdog_timeo = HZ*3; //modified by john, 0805
5204 if (dev_alloc_name(dev, ifname) < 0) {
5205 RT_TRACE(COMP_INIT, "Oops: devname already taken! Trying wlan%%d...\n");
5207 dev_alloc_name(dev, ifname);
5210 RT_TRACE(COMP_INIT, "Driver probe completed1\n");
5211 if (rtl8192_init(dev) != 0) {
5212 RT_TRACE(COMP_ERR, "Initialization failed");
5216 netif_carrier_off(dev);
5217 netif_stop_queue(dev);
5219 ret = register_netdev(dev);
5223 RT_TRACE(COMP_INIT, "dev name=======> %s\n", dev->name);
5224 rtl8192_proc_init_one(dev);
5227 RT_TRACE(COMP_INIT, "Driver probe completed\n");
5232 kfree(priv->pFirmware);
5233 priv->pFirmware = NULL;
5234 rtl8192_usb_deleteendpoints(dev);
5235 destroy_workqueue(priv->priv_wq);
5238 free_ieee80211(dev);
5240 RT_TRACE(COMP_ERR, "wlan driver load failed\n");
5244 //detach all the work and timer structure declared or inititialize in r8192U_init function.
5245 void rtl8192_cancel_deferred_work(struct r8192_priv *priv)
5248 cancel_work_sync(&priv->reset_wq);
5249 cancel_delayed_work(&priv->watch_dog_wq);
5250 cancel_delayed_work(&priv->update_beacon_wq);
5251 cancel_work_sync(&priv->qos_activate);
5255 static void rtl8192_usb_disconnect(struct usb_interface *intf)
5257 struct net_device *dev = usb_get_intfdata(intf);
5259 struct r8192_priv *priv = ieee80211_priv(dev);
5262 unregister_netdev(dev);
5264 RT_TRACE(COMP_DOWN, "=============>wlan driver to be removed\n");
5265 rtl8192_proc_remove_one(dev);
5268 kfree(priv->pFirmware);
5269 priv->pFirmware = NULL;
5270 rtl8192_usb_deleteendpoints(dev);
5271 destroy_workqueue(priv->priv_wq);
5275 free_ieee80211(dev);
5276 RT_TRACE(COMP_DOWN, "wlan driver removed\n");
5279 /* fun with the built-in ieee80211 stack... */
5280 extern int ieee80211_debug_init(void);
5281 extern void ieee80211_debug_exit(void);
5282 extern int ieee80211_crypto_init(void);
5283 extern void ieee80211_crypto_deinit(void);
5284 extern int ieee80211_crypto_tkip_init(void);
5285 extern void ieee80211_crypto_tkip_exit(void);
5286 extern int ieee80211_crypto_ccmp_init(void);
5287 extern void ieee80211_crypto_ccmp_exit(void);
5288 extern int ieee80211_crypto_wep_init(void);
5289 extern void ieee80211_crypto_wep_exit(void);
5291 static int __init rtl8192_usb_module_init(void)
5295 #ifdef CONFIG_IEEE80211_DEBUG
5296 ret = ieee80211_debug_init();
5298 pr_err("ieee80211_debug_init() failed %d\n", ret);
5302 ret = ieee80211_crypto_init();
5304 pr_err("ieee80211_crypto_init() failed %d\n", ret);
5308 ret = ieee80211_crypto_tkip_init();
5310 pr_err("ieee80211_crypto_tkip_init() failed %d\n", ret);
5314 ret = ieee80211_crypto_ccmp_init();
5316 pr_err("ieee80211_crypto_ccmp_init() failed %d\n", ret);
5320 ret = ieee80211_crypto_wep_init();
5322 pr_err("ieee80211_crypto_wep_init() failed %d\n", ret);
5326 pr_info("\nLinux kernel driver for RTL8192 based WLAN cards\n");
5327 pr_info("Copyright (c) 2007-2008, Realsil Wlan\n");
5328 RT_TRACE(COMP_INIT, "Initializing module");
5329 RT_TRACE(COMP_INIT, "Wireless extensions version %d", WIRELESS_EXT);
5330 rtl8192_proc_module_init();
5331 return usb_register(&rtl8192_usb_driver);
5335 static void __exit rtl8192_usb_module_exit(void)
5337 usb_deregister(&rtl8192_usb_driver);
5339 RT_TRACE(COMP_DOWN, "Exiting");
5343 void rtl8192_try_wake_queue(struct net_device *dev, int pri)
5345 unsigned long flags;
5347 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
5349 spin_lock_irqsave(&priv->tx_lock, flags);
5350 enough_desc = check_nic_enough_desc(dev, pri);
5351 spin_unlock_irqrestore(&priv->tx_lock, flags);
5354 ieee80211_wake_queue(priv->ieee80211);
5357 void EnableHWSecurityConfig8192(struct net_device *dev)
5359 u8 SECR_value = 0x0;
5360 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
5361 struct ieee80211_device *ieee = priv->ieee80211;
5362 SECR_value = SCR_TxEncEnable | SCR_RxDecEnable;
5363 if (((KEY_TYPE_WEP40 == ieee->pairwise_key_type) || (KEY_TYPE_WEP104 == ieee->pairwise_key_type)) && (priv->ieee80211->auth_mode != 2)) {
5364 SECR_value |= SCR_RxUseDK;
5365 SECR_value |= SCR_TxUseDK;
5366 } else if ((ieee->iw_mode == IW_MODE_ADHOC) && (ieee->pairwise_key_type & (KEY_TYPE_CCMP | KEY_TYPE_TKIP))) {
5367 SECR_value |= SCR_RxUseDK;
5368 SECR_value |= SCR_TxUseDK;
5370 //add HWSec active enable here.
5371 //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
5373 ieee->hwsec_active = 1;
5375 if ((ieee->pHTInfo->IOTAction&HT_IOT_ACT_PURE_N_MODE) || !hwwep) { /* add hwsec_support flag to totol control hw_sec on/off */
5376 ieee->hwsec_active = 0;
5377 SECR_value &= ~SCR_RxDecEnable;
5379 RT_TRACE(COMP_SEC, "%s:, hwsec:%d, pairwise_key:%d, SECR_value:%x\n", __func__,
5380 ieee->hwsec_active, ieee->pairwise_key_type, SECR_value);
5381 write_nic_byte(dev, SECR, SECR_value);
5385 void setKey(struct net_device *dev, u8 EntryNo, u8 KeyIndex, u16 KeyType,
5386 u8 *MacAddr, u8 DefaultKey, u32 *KeyContent)
5388 u32 TargetCommand = 0;
5389 u32 TargetContent = 0;
5392 if (EntryNo >= TOTAL_CAM_ENTRY)
5393 RT_TRACE(COMP_ERR, "cam entry exceeds in setKey()\n");
5395 RT_TRACE(COMP_SEC, "====>to setKey(), dev:%p, EntryNo:%d, KeyIndex:%d, KeyType:%d, MacAddr%pM\n", dev, EntryNo, KeyIndex, KeyType, MacAddr);
5398 usConfig |= BIT15 | (KeyType<<2);
5400 usConfig |= BIT15 | (KeyType<<2) | KeyIndex;
5403 for (i = 0; i < CAM_CONTENT_COUNT; i++) {
5404 TargetCommand = i+CAM_CONTENT_COUNT*EntryNo;
5405 TargetCommand |= BIT31|BIT16;
5407 if (i == 0) { /* MAC|Config */
5408 TargetContent = (u32)(*(MacAddr+0)) << 16|
5409 (u32)(*(MacAddr+1)) << 24|
5412 write_nic_dword(dev, WCAMI, TargetContent);
5413 write_nic_dword(dev, RWCAM, TargetCommand);
5414 } else if (i == 1) { /* MAC */
5415 TargetContent = (u32)(*(MacAddr+2)) |
5416 (u32)(*(MacAddr+3)) << 8|
5417 (u32)(*(MacAddr+4)) << 16|
5418 (u32)(*(MacAddr+5)) << 24;
5419 write_nic_dword(dev, WCAMI, TargetContent);
5420 write_nic_dword(dev, RWCAM, TargetCommand);
5423 if (KeyContent != NULL) {
5424 write_nic_dword(dev, WCAMI, (u32)(*(KeyContent+i-2)));
5425 write_nic_dword(dev, RWCAM, TargetCommand);
5432 /***************************************************************************
5433 ------------------- module init / exit stubs ----------------
5434 ****************************************************************************/
5435 module_init(rtl8192_usb_module_init);
5436 module_exit(rtl8192_usb_module_exit);