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->iw_mode = IW_MODE_INFRA;
2467 priv->ieee80211->softmac_features = IEEE_SOFTMAC_SCAN |
2468 IEEE_SOFTMAC_ASSOCIATE | IEEE_SOFTMAC_PROBERQ |
2469 IEEE_SOFTMAC_PROBERS | IEEE_SOFTMAC_TX_QUEUE |
2470 IEEE_SOFTMAC_BEACONS;//added by amy 080604
2472 priv->ieee80211->active_scan = 1;
2473 priv->ieee80211->modulation = IEEE80211_CCK_MODULATION | IEEE80211_OFDM_MODULATION;
2474 priv->ieee80211->host_encrypt = 1;
2475 priv->ieee80211->host_decrypt = 1;
2476 priv->ieee80211->start_send_beacons = NULL; //-by amy 080604
2477 priv->ieee80211->stop_send_beacons = NULL; //-by amy 080604
2478 priv->ieee80211->softmac_hard_start_xmit = rtl8192_hard_start_xmit;
2479 priv->ieee80211->set_chan = rtl8192_set_chan;
2480 priv->ieee80211->link_change = rtl8192_link_change;
2481 priv->ieee80211->softmac_data_hard_start_xmit = rtl8192_hard_data_xmit;
2482 priv->ieee80211->data_hard_stop = rtl8192_data_hard_stop;
2483 priv->ieee80211->data_hard_resume = rtl8192_data_hard_resume;
2484 priv->ieee80211->init_wmmparam_flag = 0;
2485 priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD;
2486 priv->ieee80211->check_nic_enough_desc = check_nic_enough_desc;
2487 priv->ieee80211->tx_headroom = TX_PACKET_SHIFT_BYTES;
2488 priv->ieee80211->qos_support = 1;
2491 priv->ieee80211->SetBWModeHandler = rtl8192_SetBWMode;
2492 priv->ieee80211->handle_assoc_response = rtl8192_handle_assoc_response;
2493 priv->ieee80211->handle_beacon = rtl8192_handle_beacon;
2495 priv->ieee80211->GetNmodeSupportBySecCfg = GetNmodeSupportBySecCfg8192;
2496 priv->ieee80211->GetHalfNmodeSupportByAPsHandler = GetHalfNmodeSupportByAPs819xUsb;
2497 priv->ieee80211->SetWirelessMode = rtl8192_SetWirelessMode;
2499 priv->ieee80211->InitialGainHandler = InitialGain819xUsb;
2500 priv->card_type = USB;
2502 if (Adapter->bInHctTest) {
2503 pHalData->ShortRetryLimit = 7;
2504 pHalData->LongRetryLimit = 7;
2507 priv->ShortRetryLimit = 0x30;
2508 priv->LongRetryLimit = 0x30;
2509 priv->EarlyRxThreshold = 7;
2510 priv->enable_gpio0 = 0;
2511 priv->TransmitConfig =
2512 (TCR_MXDMA_2048<<TCR_MXDMA_OFFSET)| // Max DMA Burst Size per Tx DMA Burst, 7: reserved.
2513 (priv->ShortRetryLimit<<TCR_SRL_OFFSET)| // Short retry limit
2514 (priv->LongRetryLimit<<TCR_LRL_OFFSET) | // Long retry limit
2515 (false ? TCR_SAT : 0); // FALSE: HW provides PLCP length and LENGEXT, TRUE: SW provides them
2517 if (Adapter->bInHctTest)
2518 pHalData->ReceiveConfig = pHalData->CSMethod |
2519 RCR_AMF | RCR_ADF | //accept management/data
2521 RCR_ACF | //accept control frame for SW AP needs PS-poll, 2005.07.07, by rcnjko.
2522 RCR_AB | RCR_AM | RCR_APM | //accept BC/MC/UC
2523 RCR_AICV | RCR_ACRC32 | //accept ICV/CRC error packet
2524 ((u32)7<<RCR_MXDMA_OFFSET) | // Max DMA Burst Size per Rx DMA Burst, 7: unlimited.
2525 (pHalData->EarlyRxThreshold<<RCR_FIFO_OFFSET) | // Rx FIFO Threshold, 7: No Rx threshold.
2526 (pHalData->EarlyRxThreshold == 7 ? RCR_OnlyErlPkt : 0);
2530 priv->ReceiveConfig =
2531 RCR_AMF | RCR_ADF | //accept management/data
2532 RCR_ACF | //accept control frame for SW AP needs PS-poll, 2005.07.07, by rcnjko.
2533 RCR_AB | RCR_AM | RCR_APM | //accept BC/MC/UC
2534 ((u32)7<<RCR_MXDMA_OFFSET)| // Max DMA Burst Size per Rx DMA Burst, 7: unlimited.
2535 (priv->EarlyRxThreshold<<RX_FIFO_THRESHOLD_SHIFT) | // Rx FIFO Threshold, 7: No Rx threshold.
2536 (priv->EarlyRxThreshold == 7 ? RCR_ONLYERLPKT : 0);
2538 priv->AcmControl = 0;
2539 priv->pFirmware = kzalloc(sizeof(rt_firmware), GFP_KERNEL);
2541 /* rx related queue */
2542 skb_queue_head_init(&priv->rx_queue);
2543 skb_queue_head_init(&priv->skb_queue);
2545 /* Tx related queue */
2546 for (i = 0; i < MAX_QUEUE_SIZE; i++)
2547 skb_queue_head_init(&priv->ieee80211->skb_waitQ[i]);
2548 for (i = 0; i < MAX_QUEUE_SIZE; i++)
2549 skb_queue_head_init(&priv->ieee80211->skb_aggQ[i]);
2550 for (i = 0; i < MAX_QUEUE_SIZE; i++)
2551 skb_queue_head_init(&priv->ieee80211->skb_drv_aggQ[i]);
2552 priv->rf_set_chan = rtl8192_phy_SwChnl;
2556 static void rtl8192_init_priv_lock(struct r8192_priv *priv)
2558 spin_lock_init(&priv->tx_lock);
2559 spin_lock_init(&priv->irq_lock);//added by thomas
2560 sema_init(&priv->wx_sem, 1);
2561 sema_init(&priv->rf_sem, 1);
2562 mutex_init(&priv->mutex);
2565 extern void rtl819x_watchdog_wqcallback(struct work_struct *work);
2567 void rtl8192_irq_rx_tasklet(struct r8192_priv *priv);
2568 //init tasklet and wait_queue here. only 2.6 above kernel is considered
2569 #define DRV_NAME "wlan0"
2570 static void rtl8192_init_priv_task(struct net_device *dev)
2572 struct r8192_priv *priv = ieee80211_priv(dev);
2574 priv->priv_wq = create_workqueue(DRV_NAME);
2576 INIT_WORK(&priv->reset_wq, rtl8192_restart);
2578 INIT_DELAYED_WORK(&priv->watch_dog_wq, rtl819x_watchdog_wqcallback);
2579 INIT_DELAYED_WORK(&priv->txpower_tracking_wq, dm_txpower_trackingcallback);
2580 INIT_DELAYED_WORK(&priv->rfpath_check_wq, dm_rf_pathcheck_workitemcallback);
2581 INIT_DELAYED_WORK(&priv->update_beacon_wq, rtl8192_update_beacon);
2582 INIT_DELAYED_WORK(&priv->initialgain_operate_wq, InitialGainOperateWorkItemCallBack);
2583 INIT_WORK(&priv->qos_activate, rtl8192_qos_activate);
2585 tasklet_init(&priv->irq_rx_tasklet,
2586 (void(*)(unsigned long))rtl8192_irq_rx_tasklet,
2587 (unsigned long)priv);
2590 static void rtl8192_get_eeprom_size(struct net_device *dev)
2593 struct r8192_priv *priv = ieee80211_priv(dev);
2594 RT_TRACE(COMP_EPROM, "===========>%s()\n", __func__);
2595 read_nic_word_E(dev, EPROM_CMD, &curCR);
2596 RT_TRACE(COMP_EPROM, "read from Reg EPROM_CMD(%x):%x\n", EPROM_CMD, curCR);
2597 //whether need I consider BIT5?
2598 priv->epromtype = (curCR & Cmd9346CR_9356SEL) ? EPROM_93c56 : EPROM_93c46;
2599 RT_TRACE(COMP_EPROM, "<===========%s(), epromtype:%d\n", __func__, priv->epromtype);
2602 //used to swap endian. as ntohl & htonl are not necessary to swap endian, so use this instead.
2603 static inline u16 endian_swap(u16 *data)
2606 *data = (tmp >> 8) | (tmp << 8);
2609 static void rtl8192_read_eeprom_info(struct net_device *dev)
2612 u8 bMac_Tmp_Addr[6] = {0x00, 0xe0, 0x4c, 0x00, 0x00, 0x02};
2613 u8 bLoad_From_EEPOM = false;
2614 struct r8192_priv *priv = ieee80211_priv(dev);
2617 RT_TRACE(COMP_EPROM, "===========>%s()\n", __func__);
2618 wEPROM_ID = eprom_read(dev, 0); //first read EEPROM ID out;
2619 RT_TRACE(COMP_EPROM, "EEPROM ID is 0x%x\n", wEPROM_ID);
2621 if (wEPROM_ID != RTL8190_EEPROM_ID) {
2622 RT_TRACE(COMP_ERR, "EEPROM ID is invalid(is 0x%x(should be 0x%x)\n", wEPROM_ID, RTL8190_EEPROM_ID);
2624 bLoad_From_EEPOM = true;
2627 if (bLoad_From_EEPOM) {
2628 tmpValue = eprom_read(dev, (EEPROM_VID>>1));
2629 priv->eeprom_vid = endian_swap(&tmpValue);
2630 priv->eeprom_pid = eprom_read(dev, (EEPROM_PID>>1));
2631 tmpValue = eprom_read(dev, (EEPROM_ChannelPlan>>1));
2632 priv->eeprom_ChannelPlan = ((tmpValue&0xff00)>>8);
2633 priv->btxpowerdata_readfromEEPORM = true;
2634 priv->eeprom_CustomerID = eprom_read(dev, (EEPROM_Customer_ID>>1)) >>8;
2636 priv->eeprom_vid = 0;
2637 priv->eeprom_pid = 0;
2638 priv->card_8192_version = VERSION_819xU_B;
2639 priv->eeprom_ChannelPlan = 0;
2640 priv->eeprom_CustomerID = 0;
2642 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);
2643 //set channelplan from eeprom
2644 priv->ChannelPlan = priv->eeprom_ChannelPlan;
2645 if (bLoad_From_EEPOM) {
2647 for (i = 0; i < 6; i += 2) {
2649 tmp = eprom_read(dev, (u16)((EEPROM_NODE_ADDRESS_BYTE_0 + i)>>1));
2650 *(u16 *)(&dev->dev_addr[i]) = tmp;
2653 memcpy(dev->dev_addr, bMac_Tmp_Addr, 6);
2654 //should I set IDR0 here?
2656 RT_TRACE(COMP_EPROM, "MAC addr:%pM\n", dev->dev_addr);
2657 priv->rf_type = RTL819X_DEFAULT_RF_TYPE; //default 1T2R
2658 priv->rf_chip = RF_8256;
2660 if (priv->card_8192_version == (u8)VERSION_819xU_A) {
2661 //read Tx power gain offset of legacy OFDM to HT rate
2662 if (bLoad_From_EEPOM)
2663 priv->EEPROMTxPowerDiff = (eprom_read(dev, (EEPROM_TxPowerDiff>>1))&0xff00) >> 8;
2665 priv->EEPROMTxPowerDiff = EEPROM_Default_TxPower;
2666 RT_TRACE(COMP_EPROM, "TxPowerDiff:%d\n", priv->EEPROMTxPowerDiff);
2667 //read ThermalMeter from EEPROM
2668 if (bLoad_From_EEPOM)
2669 priv->EEPROMThermalMeter = (u8)(eprom_read(dev, (EEPROM_ThermalMeter>>1))&0x00ff);
2671 priv->EEPROMThermalMeter = EEPROM_Default_ThermalMeter;
2672 RT_TRACE(COMP_EPROM, "ThermalMeter:%d\n", priv->EEPROMThermalMeter);
2673 //vivi, for tx power track
2674 priv->TSSI_13dBm = priv->EEPROMThermalMeter *100;
2675 //read antenna tx power offset of B/C/D to A from EEPROM
2676 if (bLoad_From_EEPOM)
2677 priv->EEPROMPwDiff = (eprom_read(dev, (EEPROM_PwDiff>>1))&0x0f00)>>8;
2679 priv->EEPROMPwDiff = EEPROM_Default_PwDiff;
2680 RT_TRACE(COMP_EPROM, "TxPwDiff:%d\n", priv->EEPROMPwDiff);
2681 // Read CrystalCap from EEPROM
2682 if (bLoad_From_EEPOM)
2683 priv->EEPROMCrystalCap = (eprom_read(dev, (EEPROM_CrystalCap>>1))&0x0f);
2685 priv->EEPROMCrystalCap = EEPROM_Default_CrystalCap;
2686 RT_TRACE(COMP_EPROM, "CrystalCap = %d\n", priv->EEPROMCrystalCap);
2687 //get per-channel Tx power level
2688 if (bLoad_From_EEPOM)
2689 priv->EEPROM_Def_Ver = (eprom_read(dev, (EEPROM_TxPwIndex_Ver>>1))&0xff00)>>8;
2691 priv->EEPROM_Def_Ver = 1;
2692 RT_TRACE(COMP_EPROM, "EEPROM_DEF_VER:%d\n", priv->EEPROM_Def_Ver);
2693 if (priv->EEPROM_Def_Ver == 0) { /* old eeprom definition */
2695 if (bLoad_From_EEPOM)
2696 priv->EEPROMTxPowerLevelCCK = (eprom_read(dev, (EEPROM_TxPwIndex_CCK>>1))&0xff) >> 8;
2698 priv->EEPROMTxPowerLevelCCK = 0x10;
2699 RT_TRACE(COMP_EPROM, "CCK Tx Power Levl: 0x%02x\n", priv->EEPROMTxPowerLevelCCK);
2700 for (i = 0; i < 3; i++) {
2701 if (bLoad_From_EEPOM) {
2702 tmpValue = eprom_read(dev, (EEPROM_TxPwIndex_OFDM_24G+i)>>1);
2703 if (((EEPROM_TxPwIndex_OFDM_24G+i) % 2) == 0)
2704 tmpValue = tmpValue & 0x00ff;
2706 tmpValue = (tmpValue & 0xff00) >> 8;
2710 priv->EEPROMTxPowerLevelOFDM24G[i] = (u8) tmpValue;
2711 RT_TRACE(COMP_EPROM, "OFDM 2.4G Tx Power Level, Index %d = 0x%02x\n", i, priv->EEPROMTxPowerLevelCCK);
2713 } else if (priv->EEPROM_Def_Ver == 1) {
2714 if (bLoad_From_EEPOM) {
2715 tmpValue = eprom_read(dev, (EEPROM_TxPwIndex_CCK_V1>>1));
2716 tmpValue = (tmpValue & 0xff00) >> 8;
2720 priv->EEPROMTxPowerLevelCCK_V1[0] = (u8)tmpValue;
2722 if (bLoad_From_EEPOM)
2723 tmpValue = eprom_read(dev, (EEPROM_TxPwIndex_CCK_V1 + 2)>>1);
2726 *((u16 *)(&priv->EEPROMTxPowerLevelCCK_V1[1])) = tmpValue;
2727 if (bLoad_From_EEPOM)
2728 tmpValue = eprom_read(dev, (EEPROM_TxPwIndex_OFDM_24G_V1>>1));
2731 *((u16 *)(&priv->EEPROMTxPowerLevelOFDM24G[0])) = tmpValue;
2732 if (bLoad_From_EEPOM)
2733 tmpValue = eprom_read(dev, (EEPROM_TxPwIndex_OFDM_24G_V1+2)>>1);
2736 priv->EEPROMTxPowerLevelOFDM24G[2] = (u8)tmpValue;
2737 }//endif EEPROM_Def_Ver == 1
2739 //update HAL variables
2741 for (i = 0; i < 14; i++) {
2743 priv->TxPowerLevelOFDM24G[i] = priv->EEPROMTxPowerLevelOFDM24G[0];
2744 else if (i >= 4 && i <= 9)
2745 priv->TxPowerLevelOFDM24G[i] = priv->EEPROMTxPowerLevelOFDM24G[1];
2747 priv->TxPowerLevelOFDM24G[i] = priv->EEPROMTxPowerLevelOFDM24G[2];
2750 for (i = 0; i < 14; i++) {
2751 if (priv->EEPROM_Def_Ver == 0) {
2753 priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelOFDM24G[0] + (priv->EEPROMTxPowerLevelCCK - priv->EEPROMTxPowerLevelOFDM24G[1]);
2754 else if (i >= 4 && i <= 9)
2755 priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelCCK;
2757 priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelOFDM24G[2] + (priv->EEPROMTxPowerLevelCCK - priv->EEPROMTxPowerLevelOFDM24G[1]);
2758 } else if (priv->EEPROM_Def_Ver == 1) {
2760 priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelCCK_V1[0];
2761 else if (i >= 4 && i <= 9)
2762 priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelCCK_V1[1];
2764 priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelCCK_V1[2];
2767 priv->TxPowerDiff = priv->EEPROMPwDiff;
2768 // Antenna B gain offset to antenna A, bit0~3
2769 priv->AntennaTxPwDiff[0] = (priv->EEPROMTxPowerDiff & 0xf);
2770 // Antenna C gain offset to antenna A, bit4~7
2771 priv->AntennaTxPwDiff[1] = ((priv->EEPROMTxPowerDiff & 0xf0)>>4);
2772 // CrystalCap, bit12~15
2773 priv->CrystalCap = priv->EEPROMCrystalCap;
2774 // ThermalMeter, bit0~3 for RFIC1, bit4~7 for RFIC2
2775 // 92U does not enable TX power tracking.
2776 priv->ThermalMeter[0] = priv->EEPROMThermalMeter;
2777 }//end if VersionID == VERSION_819xU_A
2779 //added by vivi, for dlink led, 20080416
2780 switch (priv->eeprom_CustomerID) {
2781 case EEPROM_CID_RUNTOP:
2782 priv->CustomerID = RT_CID_819x_RUNTOP;
2785 case EEPROM_CID_DLINK:
2786 priv->CustomerID = RT_CID_DLINK;
2790 priv->CustomerID = RT_CID_DEFAULT;
2795 switch (priv->CustomerID) {
2796 case RT_CID_819x_RUNTOP:
2797 priv->LedStrategy = SW_LED_MODE2;
2801 priv->LedStrategy = SW_LED_MODE4;
2805 priv->LedStrategy = SW_LED_MODE0;
2811 if (priv->rf_type == RF_1T2R) {
2812 RT_TRACE(COMP_EPROM, "\n1T2R config\n");
2814 RT_TRACE(COMP_EPROM, "\n2T4R config\n");
2817 // 2008/01/16 MH We can only know RF type in the function. So we have to init
2818 // DIG RATR table again.
2819 init_rate_adaptive(dev);
2820 //we need init DIG RATR table here again.
2822 RT_TRACE(COMP_EPROM, "<===========%s()\n", __func__);
2826 static short rtl8192_get_channel_map(struct net_device *dev)
2828 struct r8192_priv *priv = ieee80211_priv(dev);
2829 if (priv->ChannelPlan > COUNTRY_CODE_GLOBAL_DOMAIN) {
2830 netdev_err(dev, "rtl8180_init: Error channel plan! Set to default.\n");
2831 priv->ChannelPlan = 0;
2833 RT_TRACE(COMP_INIT, "Channel plan is %d\n", priv->ChannelPlan);
2835 rtl819x_set_channel_map(priv->ChannelPlan, priv);
2839 static short rtl8192_init(struct net_device *dev)
2842 struct r8192_priv *priv = ieee80211_priv(dev);
2844 memset(&(priv->stats), 0, sizeof(struct Stats));
2845 memset(priv->txqueue_to_outpipemap, 0, 9);
2849 u8 queuetopipe[] = {3, 2, 1, 0, 4, 8, 7, 6, 5};
2850 memcpy(priv->txqueue_to_outpipemap, queuetopipe, 9);
2854 u8 queuetopipe[] = {3, 2, 1, 0, 4, 4, 0, 4, 4};
2855 memcpy(priv->txqueue_to_outpipemap, queuetopipe, 9);
2858 rtl8192_init_priv_variable(dev);
2859 rtl8192_init_priv_lock(priv);
2860 rtl8192_init_priv_task(dev);
2861 rtl8192_get_eeprom_size(dev);
2862 rtl8192_read_eeprom_info(dev);
2863 rtl8192_get_channel_map(dev);
2865 init_timer(&priv->watch_dog_timer);
2866 priv->watch_dog_timer.data = (unsigned long)dev;
2867 priv->watch_dog_timer.function = watch_dog_timer_callback;
2868 if (rtl8192_usb_initendpoints(dev) != 0) {
2869 DMESG("Endopoints initialization failed");
2879 /******************************************************************************
2880 *function: This function actually only set RRSR, RATR and BW_OPMODE registers
2881 * not to do all the hw config as its name says
2882 * input: net_device dev
2885 * notice: This part need to modified according to the rate set we filtered
2886 * ****************************************************************************/
2887 static void rtl8192_hwconfig(struct net_device *dev)
2889 u32 regRATR = 0, regRRSR = 0;
2890 u8 regBwOpMode = 0, regTmp = 0;
2891 struct r8192_priv *priv = ieee80211_priv(dev);
2894 // Set RRSR, RATR, and BW_OPMODE registers
2896 switch (priv->ieee80211->mode) {
2897 case WIRELESS_MODE_B:
2898 regBwOpMode = BW_OPMODE_20MHZ;
2899 regRATR = RATE_ALL_CCK;
2900 regRRSR = RATE_ALL_CCK;
2902 case WIRELESS_MODE_A:
2903 regBwOpMode = BW_OPMODE_5G |BW_OPMODE_20MHZ;
2904 regRATR = RATE_ALL_OFDM_AG;
2905 regRRSR = RATE_ALL_OFDM_AG;
2907 case WIRELESS_MODE_G:
2908 regBwOpMode = BW_OPMODE_20MHZ;
2909 regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
2910 regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
2912 case WIRELESS_MODE_AUTO:
2914 if (Adapter->bInHctTest) {
2915 regBwOpMode = BW_OPMODE_20MHZ;
2916 regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
2917 regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
2922 regBwOpMode = BW_OPMODE_20MHZ;
2923 regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
2924 regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
2927 case WIRELESS_MODE_N_24G:
2928 // It support CCK rate by default.
2929 // CCK rate will be filtered out only when associated AP does not support it.
2930 regBwOpMode = BW_OPMODE_20MHZ;
2931 regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
2932 regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
2934 case WIRELESS_MODE_N_5G:
2935 regBwOpMode = BW_OPMODE_5G;
2936 regRATR = RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
2937 regRRSR = RATE_ALL_OFDM_AG;
2941 write_nic_byte(dev, BW_OPMODE, regBwOpMode);
2942 ratr_value = regRATR;
2943 if (priv->rf_type == RF_1T2R)
2944 ratr_value &= ~(RATE_ALL_OFDM_2SS);
2945 write_nic_dword(dev, RATR0, ratr_value);
2946 write_nic_byte(dev, UFWP, 1);
2947 read_nic_byte(dev, 0x313, ®Tmp);
2948 regRRSR = ((regTmp) << 24) | (regRRSR & 0x00ffffff);
2949 write_nic_dword(dev, RRSR, regRRSR);
2952 // Set Retry Limit here
2954 write_nic_word(dev, RETRY_LIMIT,
2955 priv->ShortRetryLimit << RETRY_LIMIT_SHORT_SHIFT |
2956 priv->LongRetryLimit << RETRY_LIMIT_LONG_SHIFT);
2957 // Set Contention Window here
2961 // Set Tx Antenna including Feedback control
2963 // Set Auto Rate fallback control
2969 //InitializeAdapter and PhyCfg
2970 static bool rtl8192_adapter_start(struct net_device *dev)
2972 struct r8192_priv *priv = ieee80211_priv(dev);
2974 bool init_status = true;
2975 u8 SECR_value = 0x0;
2977 RT_TRACE(COMP_INIT, "====>%s()\n", __func__);
2978 priv->Rf_Mode = RF_OP_By_SW_3wire;
2979 //for ASIC power on sequence
2980 write_nic_byte_E(dev, 0x5f, 0x80);
2982 write_nic_byte_E(dev, 0x5f, 0xf0);
2983 write_nic_byte_E(dev, 0x5d, 0x00);
2984 write_nic_byte_E(dev, 0x5e, 0x80);
2985 write_nic_byte(dev, 0x17, 0x37);
2987 priv->pFirmware->firmware_status = FW_STATUS_0_INIT;
2988 //config CPUReset Register
2989 //Firmware Reset or not?
2990 read_nic_dword(dev, CPU_GEN, &dwRegRead);
2991 if (priv->pFirmware->firmware_status == FW_STATUS_0_INIT)
2992 dwRegRead |= CPU_GEN_SYSTEM_RESET; //do nothing here?
2993 else if (priv->pFirmware->firmware_status == FW_STATUS_5_READY)
2994 dwRegRead |= CPU_GEN_FIRMWARE_RESET;
2996 RT_TRACE(COMP_ERR, "ERROR in %s(): undefined firmware state(%d)\n", __func__, priv->pFirmware->firmware_status);
2998 write_nic_dword(dev, CPU_GEN, dwRegRead);
3000 rtl8192_BBConfig(dev);
3002 //Loopback mode or not
3003 priv->LoopbackMode = RTL819xU_NO_LOOPBACK;
3005 read_nic_dword(dev, CPU_GEN, &dwRegRead);
3006 if (priv->LoopbackMode == RTL819xU_NO_LOOPBACK)
3007 dwRegRead = ((dwRegRead & CPU_GEN_NO_LOOPBACK_MSK) | CPU_GEN_NO_LOOPBACK_SET);
3008 else if (priv->LoopbackMode == RTL819xU_MAC_LOOPBACK)
3009 dwRegRead |= CPU_CCK_LOOPBACK;
3011 RT_TRACE(COMP_ERR, "Serious error in %s(): wrong loopback mode setting(%d)\n", __func__, priv->LoopbackMode);
3013 write_nic_dword(dev, CPU_GEN, dwRegRead);
3015 //after reset cpu, we need wait for a seconds to write in register.
3018 //xiong add for new bitfile:usb suspend reset pin set to 1. //do we need?
3019 read_nic_byte_E(dev, 0x5f, &tmp);
3020 write_nic_byte_E(dev, 0x5f, tmp|0x20);
3023 rtl8192_hwconfig(dev);
3026 write_nic_byte(dev, CMDR, CR_RE|CR_TE);
3029 write_nic_dword(dev, MAC0, ((u32 *)dev->dev_addr)[0]);
3030 write_nic_word(dev, MAC4, ((u16 *)(dev->dev_addr + 4))[0]);
3033 write_nic_dword(dev, RCR, priv->ReceiveConfig);
3035 //Initialize Number of Reserved Pages in Firmware Queue
3036 write_nic_dword(dev, RQPN1, NUM_OF_PAGE_IN_FW_QUEUE_BK << RSVD_FW_QUEUE_PAGE_BK_SHIFT |
3037 NUM_OF_PAGE_IN_FW_QUEUE_BE << RSVD_FW_QUEUE_PAGE_BE_SHIFT |
3038 NUM_OF_PAGE_IN_FW_QUEUE_VI << RSVD_FW_QUEUE_PAGE_VI_SHIFT |
3039 NUM_OF_PAGE_IN_FW_QUEUE_VO <<RSVD_FW_QUEUE_PAGE_VO_SHIFT);
3040 write_nic_dword(dev, RQPN2, NUM_OF_PAGE_IN_FW_QUEUE_MGNT << RSVD_FW_QUEUE_PAGE_MGNT_SHIFT |
3041 NUM_OF_PAGE_IN_FW_QUEUE_CMD << RSVD_FW_QUEUE_PAGE_CMD_SHIFT);
3042 write_nic_dword(dev, RQPN3, APPLIED_RESERVED_QUEUE_IN_FW|
3043 NUM_OF_PAGE_IN_FW_QUEUE_BCN<<RSVD_FW_QUEUE_PAGE_BCN_SHIFT);
3044 write_nic_dword(dev, RATR0+4*7, (RATE_ALL_OFDM_AG | RATE_ALL_CCK));
3047 // TODO: (it value is only for FPGA version). need to be changed!!2006.12.18, by Emily
3048 write_nic_byte(dev, ACK_TIMEOUT, 0x30);
3050 if (priv->ResetProgress == RESET_TYPE_NORESET)
3051 rtl8192_SetWirelessMode(dev, priv->ieee80211->mode);
3052 if (priv->ResetProgress == RESET_TYPE_NORESET) {
3053 CamResetAllEntry(dev);
3054 SECR_value |= SCR_TxEncEnable;
3055 SECR_value |= SCR_RxDecEnable;
3056 SECR_value |= SCR_NoSKMC;
3057 write_nic_byte(dev, SECR, SECR_value);
3061 write_nic_word(dev, ATIMWND, 2);
3062 write_nic_word(dev, BCN_INTERVAL, 100);
3064 #define DEFAULT_EDCA 0x005e4332
3067 for (i = 0; i < QOS_QUEUE_NUM; i++)
3068 write_nic_dword(dev, WDCAPARA_ADD[i], DEFAULT_EDCA);
3070 #ifdef USB_RX_AGGREGATION_SUPPORT
3071 //3 For usb rx firmware aggregation control
3072 if (priv->ResetProgress == RESET_TYPE_NORESET) {
3074 PRT_HIGH_THROUGHPUT pHTInfo = priv->ieee80211->pHTInfo;
3075 ulValue = (pHTInfo->UsbRxFwAggrEn<<24) | (pHTInfo->UsbRxFwAggrPageNum<<16) |
3076 (pHTInfo->UsbRxFwAggrPacketNum<<8) | (pHTInfo->UsbRxFwAggrTimeout);
3078 * If usb rx firmware aggregation is enabled,
3079 * when anyone of three threshold conditions above is reached,
3080 * firmware will send aggregated packet to driver.
3082 write_nic_dword(dev, 0x1a8, ulValue);
3083 priv->bCurrentRxAggrEnable = true;
3087 rtl8192_phy_configmac(dev);
3089 if (priv->card_8192_version == (u8) VERSION_819xU_A) {
3090 rtl8192_phy_getTxPower(dev);
3091 rtl8192_phy_setTxPower(dev, priv->chan);
3095 init_status = init_firmware(dev);
3097 RT_TRACE(COMP_ERR, "ERR!!! %s(): Firmware download is failed\n", __func__);
3100 RT_TRACE(COMP_INIT, "%s():after firmware download\n", __func__);
3103 if (Adapter->ResetProgress == RESET_TYPE_NORESET) {
3104 if (pMgntInfo->RegRfOff == TRUE) { /* User disable RF via registry. */
3105 RT_TRACE((COMP_INIT|COMP_RF), DBG_LOUD, ("InitializeAdapter819xUsb(): Turn off RF for RegRfOff ----------\n"));
3106 MgntActSet_RF_State(Adapter, eRfOff, RF_CHANGE_BY_SW);
3107 // Those actions will be discard in MgntActSet_RF_State because of the same state
3108 for (eRFPath = 0; eRFPath < pHalData->NumTotalRFPath; eRFPath++)
3109 PHY_SetRFReg(Adapter, (RF90_RADIO_PATH_E)eRFPath, 0x4, 0xC00, 0x0);
3110 } else if (pMgntInfo->RfOffReason > RF_CHANGE_BY_PS) { /* H/W or S/W RF OFF before sleep. */
3111 RT_TRACE((COMP_INIT|COMP_RF), DBG_LOUD, ("InitializeAdapter819xUsb(): Turn off RF for RfOffReason(%d) ----------\n", pMgntInfo->RfOffReason));
3112 MgntActSet_RF_State(Adapter, eRfOff, pMgntInfo->RfOffReason);
3114 pHalData->eRFPowerState = eRfOn;
3115 pMgntInfo->RfOffReason = 0;
3116 RT_TRACE((COMP_INIT|COMP_RF), DBG_LOUD, ("InitializeAdapter819xUsb(): RF is on ----------\n"));
3119 if (pHalData->eRFPowerState == eRfOff) {
3120 MgntActSet_RF_State(Adapter, eRfOff, pMgntInfo->RfOffReason);
3121 // Those actions will be discard in MgntActSet_RF_State because of the same state
3122 for (eRFPath = 0; eRFPath < pHalData->NumTotalRFPath; eRFPath++)
3123 PHY_SetRFReg(Adapter, (RF90_RADIO_PATH_E)eRFPath, 0x4, 0xC00, 0x0);
3128 if (priv->ResetProgress == RESET_TYPE_NORESET) {
3129 rtl8192_phy_RFConfig(dev);
3130 RT_TRACE(COMP_INIT, "%s():after phy RF config\n", __func__);
3134 if (priv->ieee80211->FwRWRF)
3135 // We can force firmware to do RF-R/W
3136 priv->Rf_Mode = RF_OP_By_FW;
3138 priv->Rf_Mode = RF_OP_By_SW_3wire;
3141 rtl8192_phy_updateInitGain(dev);
3142 /*--set CCK and OFDM Block "ON"--*/
3143 rtl8192_setBBreg(dev, rFPGA0_RFMOD, bCCKEn, 0x1);
3144 rtl8192_setBBreg(dev, rFPGA0_RFMOD, bOFDMEn, 0x1);
3146 if (priv->ResetProgress == RESET_TYPE_NORESET) {
3149 read_nic_byte(dev, 0x301, &tmpvalue);
3150 if (tmpvalue == 0x03) {
3152 RT_TRACE(COMP_POWER_TRACKING, "D-cut\n");
3154 priv->bDcut = FALSE;
3155 RT_TRACE(COMP_POWER_TRACKING, "C-cut\n");
3157 dm_initialize_txpower_tracking(dev);
3159 if (priv->bDcut == TRUE) {
3161 u32 tmpRegA = rtl8192_QueryBBReg(dev, rOFDM0_XATxIQImbalance, bMaskDWord);
3162 for (i = 0; i < TxBBGainTableLength; i++) {
3163 if (tmpRegA == priv->txbbgain_table[i].txbbgain_value) {
3164 priv->rfa_txpowertrackingindex = (u8)i;
3165 priv->rfa_txpowertrackingindex_real = (u8)i;
3166 priv->rfa_txpowertracking_default = priv->rfa_txpowertrackingindex;
3171 TempCCk = rtl8192_QueryBBReg(dev, rCCK0_TxFilter1, bMaskByte2);
3173 for (i = 0; i < CCKTxBBGainTableLength; i++) {
3175 if (TempCCk == priv->cck_txbbgain_table[i].ccktxbb_valuearray[0]) {
3176 priv->cck_present_attentuation_20Mdefault = (u8) i;
3180 priv->cck_present_attentuation_40Mdefault = 0;
3181 priv->cck_present_attentuation_difference = 0;
3182 priv->cck_present_attentuation = priv->cck_present_attentuation_20Mdefault;
3186 write_nic_byte(dev, 0x87, 0x0);
3192 /* this configures registers for beacon tx and enables it via
3193 * rtl8192_beacon_tx_enable(). rtl8192_beacon_tx_disable() might
3194 * be used to stop beacon transmission
3196 /***************************************************************************
3197 -------------------------------NET STUFF---------------------------
3198 ***************************************************************************/
3200 static struct net_device_stats *rtl8192_stats(struct net_device *dev)
3202 struct r8192_priv *priv = ieee80211_priv(dev);
3204 return &priv->ieee80211->stats;
3207 static bool HalTxCheckStuck819xUsb(struct net_device *dev)
3209 struct r8192_priv *priv = ieee80211_priv(dev);
3211 bool bStuck = FALSE;
3212 read_nic_word(dev, 0x128, &RegTxCounter);
3213 RT_TRACE(COMP_RESET, "%s():RegTxCounter is %d,TxCounter is %d\n", __func__, RegTxCounter, priv->TxCounter);
3214 if (priv->TxCounter == RegTxCounter)
3217 priv->TxCounter = RegTxCounter;
3223 * <Assumption: RT_TX_SPINLOCK is acquired.>
3224 * First added: 2006.11.19 by emily
3226 static RESET_TYPE TxCheckStuck(struct net_device *dev)
3228 struct r8192_priv *priv = ieee80211_priv(dev);
3230 bool bCheckFwTxCnt = false;
3233 // Decide such threshold according to current power save mode
3236 for (QueueID = 0; QueueID <= BEACON_QUEUE; QueueID++) {
3237 if (QueueID == TXCMD_QUEUE)
3239 #ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
3240 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))
3242 if ((skb_queue_len(&priv->ieee80211->skb_waitQ[QueueID]) == 0) && (skb_queue_len(&priv->ieee80211->skb_aggQ[QueueID]) == 0))
3246 bCheckFwTxCnt = true;
3248 if (bCheckFwTxCnt) {
3249 if (HalTxCheckStuck819xUsb(dev)) {
3250 RT_TRACE(COMP_RESET, "TxCheckStuck(): Fw indicates no Tx condition! \n");
3251 return RESET_TYPE_SILENT;
3254 return RESET_TYPE_NORESET;
3257 static bool HalRxCheckStuck819xUsb(struct net_device *dev)
3260 struct r8192_priv *priv = ieee80211_priv(dev);
3261 bool bStuck = FALSE;
3262 static u8 rx_chk_cnt;
3263 read_nic_word(dev, 0x130, &RegRxCounter);
3264 RT_TRACE(COMP_RESET, "%s(): RegRxCounter is %d,RxCounter is %d\n", __func__, RegRxCounter, priv->RxCounter);
3265 // If rssi is small, we should check rx for long time because of bad rx.
3266 // or maybe it will continuous silent reset every 2 seconds.
3268 if (priv->undecorated_smoothed_pwdb >= (RateAdaptiveTH_High+5)) {
3269 rx_chk_cnt = 0; //high rssi, check rx stuck right now.
3270 } else if (priv->undecorated_smoothed_pwdb < (RateAdaptiveTH_High+5) &&
3271 ((priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20 && priv->undecorated_smoothed_pwdb >= RateAdaptiveTH_Low_40M) ||
3272 (priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20 && priv->undecorated_smoothed_pwdb >= RateAdaptiveTH_Low_20M))) {
3277 } else if (((priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20 && priv->undecorated_smoothed_pwdb < RateAdaptiveTH_Low_40M) ||
3278 (priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20 && priv->undecorated_smoothed_pwdb < RateAdaptiveTH_Low_20M)) &&
3279 priv->undecorated_smoothed_pwdb >= VeryLowRSSI) {
3291 if (priv->RxCounter == RegRxCounter)
3294 priv->RxCounter = RegRxCounter;
3299 static RESET_TYPE RxCheckStuck(struct net_device *dev)
3301 struct r8192_priv *priv = ieee80211_priv(dev);
3302 bool bRxCheck = FALSE;
3304 if (priv->IrpPendingCount > 1)
3308 if (HalRxCheckStuck819xUsb(dev)) {
3309 RT_TRACE(COMP_RESET, "RxStuck Condition\n");
3310 return RESET_TYPE_SILENT;
3313 return RESET_TYPE_NORESET;
3318 * This function is called by Checkforhang to check whether we should ask OS to reset driver
3320 * \param pAdapter The adapter context for this miniport
3322 * Note:NIC with USB interface sholud not call this function because we cannot scan descriptor
3323 * to judge whether there is tx stuck.
3324 * Note: This function may be required to be rewrite for Vista OS.
3325 * <<<Assumption: Tx spinlock has been acquired >>>
3327 * 8185 and 8185b does not implement this function. This is added by Emily at 2006.11.24
3329 static RESET_TYPE rtl819x_ifcheck_resetornot(struct net_device *dev)
3331 struct r8192_priv *priv = ieee80211_priv(dev);
3332 RESET_TYPE TxResetType = RESET_TYPE_NORESET;
3333 RESET_TYPE RxResetType = RESET_TYPE_NORESET;
3334 RT_RF_POWER_STATE rfState;
3336 rfState = priv->ieee80211->eRFPowerState;
3338 TxResetType = TxCheckStuck(dev);
3339 if (rfState != eRfOff ||
3340 (priv->ieee80211->iw_mode != IW_MODE_ADHOC)) {
3341 // If driver is in the status of firmware download failure , driver skips RF initialization and RF is
3342 // in turned off state. Driver should check whether Rx stuck and do silent reset. And
3343 // if driver is in firmware download failure status, driver should initialize RF in the following
3344 // silent reset procedure Emily, 2008.01.21
3346 // Driver should not check RX stuck in IBSS mode because it is required to
3347 // set Check BSSID in order to send beacon, however, if check BSSID is
3348 // set, STA cannot hear any packet at all. Emily, 2008.04.12
3349 RxResetType = RxCheckStuck(dev);
3351 if (TxResetType == RESET_TYPE_NORMAL || RxResetType == RESET_TYPE_NORMAL) {
3352 return RESET_TYPE_NORMAL;
3353 } else if (TxResetType == RESET_TYPE_SILENT || RxResetType == RESET_TYPE_SILENT) {
3354 RT_TRACE(COMP_RESET, "%s():silent reset\n", __func__);
3355 return RESET_TYPE_SILENT;
3357 return RESET_TYPE_NORESET;
3362 void rtl8192_cancel_deferred_work(struct r8192_priv *priv);
3363 int _rtl8192_up(struct net_device *dev);
3364 int rtl8192_close(struct net_device *dev);
3368 static void CamRestoreAllEntry(struct net_device *dev)
3371 struct r8192_priv *priv = ieee80211_priv(dev);
3372 u8 *MacAddr = priv->ieee80211->current_network.bssid;
3374 static u8 CAM_CONST_ADDR[4][6] = {
3375 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
3376 {0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
3377 {0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
3378 {0x00, 0x00, 0x00, 0x00, 0x00, 0x03} };
3379 static u8 CAM_CONST_BROAD[] = {
3380 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
3382 RT_TRACE(COMP_SEC, "CamRestoreAllEntry: \n");
3385 if ((priv->ieee80211->pairwise_key_type == KEY_TYPE_WEP40) ||
3386 (priv->ieee80211->pairwise_key_type == KEY_TYPE_WEP104)) {
3388 for (EntryId = 0; EntryId < 4; EntryId++) {
3389 MacAddr = CAM_CONST_ADDR[EntryId];
3390 setKey(dev, EntryId, EntryId,
3391 priv->ieee80211->pairwise_key_type,
3395 } else if (priv->ieee80211->pairwise_key_type == KEY_TYPE_TKIP) {
3397 if (priv->ieee80211->iw_mode == IW_MODE_ADHOC)
3398 setKey(dev, 4, 0, priv->ieee80211->pairwise_key_type,
3399 (u8 *)dev->dev_addr, 0, NULL);
3401 setKey(dev, 4, 0, priv->ieee80211->pairwise_key_type,
3403 } else if (priv->ieee80211->pairwise_key_type == KEY_TYPE_CCMP) {
3405 if (priv->ieee80211->iw_mode == IW_MODE_ADHOC)
3406 setKey(dev, 4, 0, priv->ieee80211->pairwise_key_type,
3407 (u8 *)dev->dev_addr, 0, NULL);
3409 setKey(dev, 4, 0, priv->ieee80211->pairwise_key_type,
3415 if (priv->ieee80211->group_key_type == KEY_TYPE_TKIP) {
3416 MacAddr = CAM_CONST_BROAD;
3417 for (EntryId = 1; EntryId < 4; EntryId++) {
3418 setKey(dev, EntryId, EntryId,
3419 priv->ieee80211->group_key_type,
3422 if (priv->ieee80211->iw_mode == IW_MODE_ADHOC)
3423 setKey(dev, 0, 0, priv->ieee80211->group_key_type,
3424 CAM_CONST_ADDR[0], 0, NULL);
3425 } else if (priv->ieee80211->group_key_type == KEY_TYPE_CCMP) {
3426 MacAddr = CAM_CONST_BROAD;
3427 for (EntryId = 1; EntryId < 4; EntryId++) {
3428 setKey(dev, EntryId, EntryId,
3429 priv->ieee80211->group_key_type,
3433 if (priv->ieee80211->iw_mode == IW_MODE_ADHOC)
3434 setKey(dev, 0, 0, priv->ieee80211->group_key_type,
3435 CAM_CONST_ADDR[0], 0, NULL);
3438 //////////////////////////////////////////////////////////////
3439 // This function is used to fix Tx/Rx stop bug temporarily.
3440 // This function will do "system reset" to NIC when Tx or Rx is stuck.
3441 // The method checking Tx/Rx stuck of this function is supported by FW,
3442 // which reports Tx and Rx counter to register 0x128 and 0x130.
3443 //////////////////////////////////////////////////////////////
3444 static void rtl819x_ifsilentreset(struct net_device *dev)
3446 struct r8192_priv *priv = ieee80211_priv(dev);
3448 int reset_status = 0;
3449 struct ieee80211_device *ieee = priv->ieee80211;
3452 // 2007.07.20. If we need to check CCK stop, please uncomment this line.
3453 //bStuck = Adapter->HalFunc.CheckHWStopHandler(Adapter);
3455 if (priv->ResetProgress == RESET_TYPE_NORESET) {
3458 RT_TRACE(COMP_RESET, "=========>Reset progress!! \n");
3460 // Set the variable for reset.
3461 priv->ResetProgress = RESET_TYPE_SILENT;
3462 down(&priv->wx_sem);
3463 if (priv->up == 0) {
3464 RT_TRACE(COMP_ERR, "%s():the driver is not up! return\n", __func__);
3469 RT_TRACE(COMP_RESET, "%s():======>start to down the driver\n", __func__);
3471 rtl8192_rtx_disable(dev);
3472 rtl8192_cancel_deferred_work(priv);
3474 del_timer_sync(&priv->watch_dog_timer);
3476 ieee->sync_scan_hurryup = 1;
3477 if (ieee->state == IEEE80211_LINKED) {
3478 down(&ieee->wx_sem);
3479 netdev_dbg(dev, "ieee->state is IEEE80211_LINKED\n");
3480 ieee80211_stop_send_beacons(priv->ieee80211);
3481 del_timer_sync(&ieee->associate_timer);
3482 cancel_delayed_work(&ieee->associate_retry_wq);
3483 ieee80211_stop_scan(ieee);
3484 netif_carrier_off(dev);
3487 netdev_dbg(dev, "ieee->state is NOT LINKED\n");
3488 ieee80211_softmac_stop_protocol(priv->ieee80211);
3491 RT_TRACE(COMP_RESET, "%s():<==========down process is finished\n", __func__);
3492 RT_TRACE(COMP_RESET, "%s():===========>start up the driver\n", __func__);
3493 reset_status = _rtl8192_up(dev);
3495 RT_TRACE(COMP_RESET, "%s():<===========up process is finished\n", __func__);
3496 if (reset_status == -EAGAIN) {
3497 if (reset_times < 3) {
3501 RT_TRACE(COMP_ERR, " ERR!!! %s(): Reset Failed!!\n", __func__);
3504 ieee->is_silent_reset = 1;
3505 EnableHWSecurityConfig8192(dev);
3506 if (ieee->state == IEEE80211_LINKED && ieee->iw_mode == IW_MODE_INFRA) {
3507 ieee->set_chan(ieee->dev, ieee->current_network.channel);
3509 queue_work(ieee->wq, &ieee->associate_complete_wq);
3511 } else if (ieee->state == IEEE80211_LINKED && ieee->iw_mode == IW_MODE_ADHOC) {
3512 ieee->set_chan(ieee->dev, ieee->current_network.channel);
3513 ieee->link_change(ieee->dev);
3515 ieee80211_start_send_beacons(ieee);
3517 if (ieee->data_hard_resume)
3518 ieee->data_hard_resume(ieee->dev);
3519 netif_carrier_on(ieee->dev);
3522 CamRestoreAllEntry(dev);
3524 priv->ResetProgress = RESET_TYPE_NORESET;
3525 priv->reset_count++;
3527 priv->bForcedSilentReset = false;
3528 priv->bResetInProgress = false;
3530 // For test --> force write UFWP.
3531 write_nic_byte(dev, UFWP, 1);
3532 RT_TRACE(COMP_RESET, "Reset finished!! ====>[%d]\n", priv->reset_count);
3536 void CAM_read_entry(struct net_device *dev, u32 iIndex)
3538 u32 target_command = 0;
3539 u32 target_content = 0;
3543 for (entry_i = 0; entry_i < CAM_CONTENT_COUNT; entry_i++) {
3544 // polling bit, and No Write enable, and address
3545 target_command = entry_i+CAM_CONTENT_COUNT*iIndex;
3546 target_command = target_command | BIT31;
3548 //Check polling bit is clear
3549 while ((i--) >= 0) {
3550 read_nic_dword(dev, RWCAM, &ulStatus);
3551 if (ulStatus & BIT31)
3556 write_nic_dword(dev, RWCAM, target_command);
3557 RT_TRACE(COMP_SEC, "CAM_read_entry(): WRITE A0: %x \n", target_command);
3558 read_nic_dword(dev, RCAMO, &target_content);
3559 RT_TRACE(COMP_SEC, "CAM_read_entry(): WRITE A8: %x \n", target_content);
3564 static void rtl819x_update_rxcounts(struct r8192_priv *priv, u32 *TotalRxBcnNum,
3565 u32 *TotalRxDataNum)
3571 *TotalRxDataNum = 0;
3573 SlotIndex = (priv->ieee80211->LinkDetectInfo.SlotIndex++)%(priv->ieee80211->LinkDetectInfo.SlotNum);
3574 priv->ieee80211->LinkDetectInfo.RxBcnNum[SlotIndex] = priv->ieee80211->LinkDetectInfo.NumRecvBcnInPeriod;
3575 priv->ieee80211->LinkDetectInfo.RxDataNum[SlotIndex] = priv->ieee80211->LinkDetectInfo.NumRecvDataInPeriod;
3576 for (i = 0; i < priv->ieee80211->LinkDetectInfo.SlotNum; i++) {
3577 *TotalRxBcnNum += priv->ieee80211->LinkDetectInfo.RxBcnNum[i];
3578 *TotalRxDataNum += priv->ieee80211->LinkDetectInfo.RxDataNum[i];
3583 void rtl819x_watchdog_wqcallback(struct work_struct *work)
3585 struct delayed_work *dwork = container_of(work, struct delayed_work, work);
3586 struct r8192_priv *priv = container_of(dwork, struct r8192_priv, watch_dog_wq);
3587 struct net_device *dev = priv->ieee80211->dev;
3588 struct ieee80211_device *ieee = priv->ieee80211;
3589 RESET_TYPE ResetType = RESET_TYPE_NORESET;
3590 static u8 check_reset_cnt;
3591 bool bBusyTraffic = false;
3592 u32 TotalRxBcnNum = 0;
3593 u32 TotalRxDataNum = 0;
3597 hal_dm_watchdog(dev);
3599 //to get busy traffic condition
3600 if (ieee->state == IEEE80211_LINKED) {
3601 if (ieee->LinkDetectInfo.NumRxOkInPeriod > 666 ||
3602 ieee->LinkDetectInfo.NumTxOkInPeriod > 666 ) {
3603 bBusyTraffic = true;
3605 ieee->LinkDetectInfo.NumRxOkInPeriod = 0;
3606 ieee->LinkDetectInfo.NumTxOkInPeriod = 0;
3607 ieee->LinkDetectInfo.bBusyTraffic = bBusyTraffic;
3609 //added by amy for AP roaming
3610 if (priv->ieee80211->state == IEEE80211_LINKED && priv->ieee80211->iw_mode == IW_MODE_INFRA) {
3612 rtl819x_update_rxcounts(priv, &TotalRxBcnNum, &TotalRxDataNum);
3613 if ((TotalRxBcnNum+TotalRxDataNum) == 0) {
3615 if (rfState == eRfOff)
3616 RT_TRACE(COMP_ERR, "========>%s()\n", __func__);
3618 netdev_dbg(dev, "===>%s(): AP is power off, connect another one\n", __func__);
3619 priv->ieee80211->state = IEEE80211_ASSOCIATING;
3620 notify_wx_assoc_event(priv->ieee80211);
3621 RemovePeerTS(priv->ieee80211, priv->ieee80211->current_network.bssid);
3622 priv->ieee80211->link_change(dev);
3623 queue_work(priv->ieee80211->wq, &priv->ieee80211->associate_procedure_wq);
3627 priv->ieee80211->LinkDetectInfo.NumRecvBcnInPeriod = 0;
3628 priv->ieee80211->LinkDetectInfo.NumRecvDataInPeriod = 0;
3629 //check if reset the driver
3630 if (check_reset_cnt++ >= 3) {
3631 ResetType = rtl819x_ifcheck_resetornot(dev);
3632 check_reset_cnt = 3;
3634 if ((priv->force_reset) || (priv->ResetProgress == RESET_TYPE_NORESET &&
3635 (priv->bForcedSilentReset ||
3636 (!priv->bDisableNormalResetCheck && ResetType == RESET_TYPE_SILENT)))) { /* This is control by OID set in Pomelo */
3637 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);
3638 rtl819x_ifsilentreset(dev);
3640 priv->force_reset = false;
3641 priv->bForcedSilentReset = false;
3642 priv->bResetInProgress = false;
3643 RT_TRACE(COMP_TRACE, " <==RtUsbCheckForHangWorkItemCallback()\n");
3647 void watch_dog_timer_callback(unsigned long data)
3649 struct r8192_priv *priv = ieee80211_priv((struct net_device *) data);
3650 queue_delayed_work(priv->priv_wq, &priv->watch_dog_wq, 0);
3651 mod_timer(&priv->watch_dog_timer, jiffies + MSECS(IEEE80211_WATCH_DOG_TIME));
3653 int _rtl8192_up(struct net_device *dev)
3655 struct r8192_priv *priv = ieee80211_priv(dev);
3656 int init_status = 0;
3658 priv->ieee80211->ieee_up = 1;
3659 RT_TRACE(COMP_INIT, "Bringing up iface");
3660 init_status = rtl8192_adapter_start(dev);
3662 RT_TRACE(COMP_ERR, "ERR!!! %s(): initialization failed!\n", __func__);
3663 priv->up = priv->ieee80211->ieee_up = 0;
3666 RT_TRACE(COMP_INIT, "start adapter finished\n");
3667 rtl8192_rx_enable(dev);
3668 if (priv->ieee80211->state != IEEE80211_LINKED)
3669 ieee80211_softmac_start_protocol(priv->ieee80211);
3670 ieee80211_reset_queue(priv->ieee80211);
3671 watch_dog_timer_callback((unsigned long) dev);
3672 if (!netif_queue_stopped(dev))
3673 netif_start_queue(dev);
3675 netif_wake_queue(dev);
3681 static int rtl8192_open(struct net_device *dev)
3683 struct r8192_priv *priv = ieee80211_priv(dev);
3685 down(&priv->wx_sem);
3686 ret = rtl8192_up(dev);
3693 int rtl8192_up(struct net_device *dev)
3695 struct r8192_priv *priv = ieee80211_priv(dev);
3700 return _rtl8192_up(dev);
3704 int rtl8192_close(struct net_device *dev)
3706 struct r8192_priv *priv = ieee80211_priv(dev);
3709 down(&priv->wx_sem);
3711 ret = rtl8192_down(dev);
3719 int rtl8192_down(struct net_device *dev)
3721 struct r8192_priv *priv = ieee80211_priv(dev);
3728 priv->ieee80211->ieee_up = 0;
3729 RT_TRACE(COMP_DOWN, "==========>%s()\n", __func__);
3731 if (!netif_queue_stopped(dev))
3732 netif_stop_queue(dev);
3734 rtl8192_rtx_disable(dev);
3736 /* Tx related queue release */
3737 for (i = 0; i < MAX_QUEUE_SIZE; i++)
3738 skb_queue_purge(&priv->ieee80211->skb_waitQ[i]);
3739 for (i = 0; i < MAX_QUEUE_SIZE; i++)
3740 skb_queue_purge(&priv->ieee80211->skb_aggQ[i]);
3742 for (i = 0; i < MAX_QUEUE_SIZE; i++)
3743 skb_queue_purge(&priv->ieee80211->skb_drv_aggQ[i]);
3745 //as cancel_delayed_work will del work->timer, so if work is not defined as struct delayed_work, it will corrupt
3746 rtl8192_cancel_deferred_work(priv);
3748 del_timer_sync(&priv->watch_dog_timer);
3751 ieee80211_softmac_stop_protocol(priv->ieee80211);
3752 memset(&priv->ieee80211->current_network, 0, offsetof(struct ieee80211_network, list));
3753 RT_TRACE(COMP_DOWN, "<==========%s()\n", __func__);
3759 void rtl8192_commit(struct net_device *dev)
3761 struct r8192_priv *priv = ieee80211_priv(dev);
3762 int reset_status = 0;
3767 rtl8192_cancel_deferred_work(priv);
3768 del_timer_sync(&priv->watch_dog_timer);
3770 ieee80211_softmac_stop_protocol(priv->ieee80211);
3772 rtl8192_rtx_disable(dev);
3773 reset_status = _rtl8192_up(dev);
3777 void rtl8192_restart(struct work_struct *work)
3779 struct r8192_priv *priv = container_of(work, struct r8192_priv, reset_wq);
3780 struct net_device *dev = priv->ieee80211->dev;
3782 down(&priv->wx_sem);
3784 rtl8192_commit(dev);
3789 static void r8192_set_multicast(struct net_device *dev)
3791 struct r8192_priv *priv = ieee80211_priv(dev);
3796 promisc = (dev->flags & IFF_PROMISC) ? 1 : 0;
3798 if (promisc != priv->promisc)
3800 priv->promisc = promisc;
3804 static int r8192_set_mac_adr(struct net_device *dev, void *mac)
3806 struct r8192_priv *priv = ieee80211_priv(dev);
3807 struct sockaddr *addr = mac;
3809 down(&priv->wx_sem);
3811 memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
3813 schedule_work(&priv->reset_wq);
3819 /* based on ipw2200 driver */
3820 static int rtl8192_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
3822 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
3823 struct iwreq *wrq = (struct iwreq *)rq;
3825 struct ieee80211_device *ieee = priv->ieee80211;
3827 u8 broadcast_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
3828 struct iw_point *p = &wrq->u.data;
3829 struct ieee_param *ipw = NULL;
3831 down(&priv->wx_sem);
3834 if (p->length < sizeof(struct ieee_param) || !p->pointer) {
3839 ipw = memdup_user(p->pointer, p->length);
3846 case RTL_IOCTL_WPA_SUPPLICANT:
3847 //parse here for HW security
3848 if (ipw->cmd == IEEE_CMD_SET_ENCRYPTION) {
3849 if (ipw->u.crypt.set_tx) {
3850 if (strcmp(ipw->u.crypt.alg, "CCMP") == 0) {
3851 ieee->pairwise_key_type = KEY_TYPE_CCMP;
3852 } else if (strcmp(ipw->u.crypt.alg, "TKIP") == 0) {
3853 ieee->pairwise_key_type = KEY_TYPE_TKIP;
3854 } else if (strcmp(ipw->u.crypt.alg, "WEP") == 0) {
3855 if (ipw->u.crypt.key_len == 13)
3856 ieee->pairwise_key_type = KEY_TYPE_WEP104;
3857 else if (ipw->u.crypt.key_len == 5)
3858 ieee->pairwise_key_type = KEY_TYPE_WEP40;
3860 ieee->pairwise_key_type = KEY_TYPE_NA;
3863 if (ieee->pairwise_key_type) {
3864 memcpy((u8 *)key, ipw->u.crypt.key, 16);
3865 EnableHWSecurityConfig8192(dev);
3866 //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!
3868 setKey(dev, 4, ipw->u.crypt.idx, ieee->pairwise_key_type, (u8 *)ieee->ap_mac_addr, 0, key);
3869 if (ieee->auth_mode != 2)
3870 setKey(dev, ipw->u.crypt.idx, ipw->u.crypt.idx, ieee->pairwise_key_type, (u8 *)ieee->ap_mac_addr, 0, key);
3873 memcpy((u8 *)key, ipw->u.crypt.key, 16);
3874 if (strcmp(ipw->u.crypt.alg, "CCMP") == 0) {
3875 ieee->group_key_type = KEY_TYPE_CCMP;
3876 } else if (strcmp(ipw->u.crypt.alg, "TKIP") == 0) {
3877 ieee->group_key_type = KEY_TYPE_TKIP;
3878 } else if (strcmp(ipw->u.crypt.alg, "WEP") == 0) {
3879 if (ipw->u.crypt.key_len == 13)
3880 ieee->group_key_type = KEY_TYPE_WEP104;
3881 else if (ipw->u.crypt.key_len == 5)
3882 ieee->group_key_type = KEY_TYPE_WEP40;
3884 ieee->group_key_type = KEY_TYPE_NA;
3887 if (ieee->group_key_type) {
3888 setKey(dev, ipw->u.crypt.idx,
3889 ipw->u.crypt.idx, //KeyIndex
3890 ieee->group_key_type, //KeyType
3891 broadcast_addr, //MacAddr
3897 ret = ieee80211_wpa_supplicant_ioctl(priv->ieee80211, &wrq->u.data);
3911 static u8 HwRateToMRate90(bool bIsHT, u8 rate)
3923 case DESC90_RATE5_5M:
3924 ret_rate = MGN_5_5M;
3926 case DESC90_RATE11M:
3935 case DESC90_RATE12M:
3938 case DESC90_RATE18M:
3941 case DESC90_RATE24M:
3944 case DESC90_RATE36M:
3947 case DESC90_RATE48M:
3950 case DESC90_RATE54M:
3956 RT_TRACE(COMP_RECV, "HwRateToMRate90(): Non supported Rate [%x], bIsHT = %d!!!\n", rate, bIsHT);
3962 case DESC90_RATEMCS0:
3963 ret_rate = MGN_MCS0;
3965 case DESC90_RATEMCS1:
3966 ret_rate = MGN_MCS1;
3968 case DESC90_RATEMCS2:
3969 ret_rate = MGN_MCS2;
3971 case DESC90_RATEMCS3:
3972 ret_rate = MGN_MCS3;
3974 case DESC90_RATEMCS4:
3975 ret_rate = MGN_MCS4;
3977 case DESC90_RATEMCS5:
3978 ret_rate = MGN_MCS5;
3980 case DESC90_RATEMCS6:
3981 ret_rate = MGN_MCS6;
3983 case DESC90_RATEMCS7:
3984 ret_rate = MGN_MCS7;
3986 case DESC90_RATEMCS8:
3987 ret_rate = MGN_MCS8;
3989 case DESC90_RATEMCS9:
3990 ret_rate = MGN_MCS9;
3992 case DESC90_RATEMCS10:
3993 ret_rate = MGN_MCS10;
3995 case DESC90_RATEMCS11:
3996 ret_rate = MGN_MCS11;
3998 case DESC90_RATEMCS12:
3999 ret_rate = MGN_MCS12;
4001 case DESC90_RATEMCS13:
4002 ret_rate = MGN_MCS13;
4004 case DESC90_RATEMCS14:
4005 ret_rate = MGN_MCS14;
4007 case DESC90_RATEMCS15:
4008 ret_rate = MGN_MCS15;
4010 case DESC90_RATEMCS32:
4011 ret_rate = (0x80|0x20);
4016 RT_TRACE(COMP_RECV, "HwRateToMRate90(): Non supported Rate [%x], bIsHT = %d!!!\n", rate, bIsHT);
4025 * Function: UpdateRxPktTimeStamp
4026 * Overview: Record the TSF time stamp when receiving a packet
4034 * (pRfd->Status.TimeStampHigh is updated)
4035 * (pRfd->Status.TimeStampLow is updated)
4039 static void UpdateRxPktTimeStamp8190(struct net_device *dev,
4040 struct ieee80211_rx_stats *stats)
4042 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
4044 if (stats->bIsAMPDU && !stats->bFirstMPDU) {
4045 stats->mac_time[0] = priv->LastRxDescTSFLow;
4046 stats->mac_time[1] = priv->LastRxDescTSFHigh;
4048 priv->LastRxDescTSFLow = stats->mac_time[0];
4049 priv->LastRxDescTSFHigh = stats->mac_time[1];
4055 static long rtl819x_translate_todbm(u8 signal_strength_index)// 0-100 index.
4057 long signal_power; // in dBm.
4059 // Translate to dBm (x=0.5y-95).
4060 signal_power = (long)((signal_strength_index + 1) >> 1);
4063 return signal_power;
4067 /* 2008/01/22 MH We can not declare RSSI/EVM total value of sliding window to
4068 be a local static. Otherwise, it may increase when we return from S3/S4. The
4069 value will be kept in memory or disk. Declare the value in the adaptor
4070 and it will be reinitialized when returned from S3/S4. */
4071 static void rtl8192_process_phyinfo(struct r8192_priv *priv, u8 *buffer,
4072 struct ieee80211_rx_stats *pprevious_stats,
4073 struct ieee80211_rx_stats *pcurrent_stats)
4075 bool bcheck = false;
4077 u32 nspatial_stream, tmp_val;
4078 static u32 slide_rssi_index, slide_rssi_statistics;
4079 static u32 slide_evm_index, slide_evm_statistics;
4080 static u32 last_rssi, last_evm;
4082 static u32 slide_beacon_adc_pwdb_index, slide_beacon_adc_pwdb_statistics;
4083 static u32 last_beacon_adc_pwdb;
4085 struct ieee80211_hdr_3addr *hdr;
4087 unsigned int frag, seq;
4088 hdr = (struct ieee80211_hdr_3addr *)buffer;
4089 sc = le16_to_cpu(hdr->seq_ctl);
4090 frag = WLAN_GET_SEQ_FRAG(sc);
4091 seq = WLAN_GET_SEQ_SEQ(sc);
4092 //cosa add 04292008 to record the sequence number
4093 pcurrent_stats->Seq_Num = seq;
4095 // Check whether we should take the previous packet into accounting
4097 if (!pprevious_stats->bIsAMPDU) {
4098 // if previous packet is not aggregated packet
4102 if (slide_rssi_statistics++ >= PHY_RSSI_SLID_WIN_MAX) {
4103 slide_rssi_statistics = PHY_RSSI_SLID_WIN_MAX;
4104 last_rssi = priv->stats.slide_signal_strength[slide_rssi_index];
4105 priv->stats.slide_rssi_total -= last_rssi;
4107 priv->stats.slide_rssi_total += pprevious_stats->SignalStrength;
4109 priv->stats.slide_signal_strength[slide_rssi_index++] = pprevious_stats->SignalStrength;
4110 if (slide_rssi_index >= PHY_RSSI_SLID_WIN_MAX)
4111 slide_rssi_index = 0;
4113 // <1> Showed on UI for user, in dbm
4114 tmp_val = priv->stats.slide_rssi_total/slide_rssi_statistics;
4115 priv->stats.signal_strength = rtl819x_translate_todbm((u8)tmp_val);
4116 pcurrent_stats->rssi = priv->stats.signal_strength;
4118 // If the previous packet does not match the criteria, neglect it
4120 if (!pprevious_stats->bPacketMatchBSSID) {
4121 if (!pprevious_stats->bToSelfBA)
4129 //rtl8190_process_cck_rxpathsel(priv,pprevious_stats);//only rtl8190 supported
4134 priv->stats.num_process_phyinfo++;
4136 /* record the general signal strength to the sliding window. */
4139 // <2> Showed on UI for engineering
4140 // hardware does not provide rssi information for each rf path in CCK
4141 if (!pprevious_stats->bIsCCK && (pprevious_stats->bPacketToSelf || pprevious_stats->bToSelfBA)) {
4142 for (rfpath = RF90_PATH_A; rfpath < priv->NumTotalRFPath; rfpath++) {
4143 if (!rtl8192_phy_CheckIsLegalRFPath(priv->ieee80211->dev, rfpath))
4146 //Fixed by Jacken 2008-03-20
4147 if (priv->stats.rx_rssi_percentage[rfpath] == 0)
4148 priv->stats.rx_rssi_percentage[rfpath] = pprevious_stats->RxMIMOSignalStrength[rfpath];
4149 if (pprevious_stats->RxMIMOSignalStrength[rfpath] > priv->stats.rx_rssi_percentage[rfpath]) {
4150 priv->stats.rx_rssi_percentage[rfpath] =
4151 ((priv->stats.rx_rssi_percentage[rfpath]*(Rx_Smooth_Factor-1)) +
4152 (pprevious_stats->RxMIMOSignalStrength[rfpath])) /(Rx_Smooth_Factor);
4153 priv->stats.rx_rssi_percentage[rfpath] = priv->stats.rx_rssi_percentage[rfpath] + 1;
4155 priv->stats.rx_rssi_percentage[rfpath] =
4156 ((priv->stats.rx_rssi_percentage[rfpath]*(Rx_Smooth_Factor-1)) +
4157 (pprevious_stats->RxMIMOSignalStrength[rfpath])) /(Rx_Smooth_Factor);
4159 RT_TRACE(COMP_DBG, "priv->stats.rx_rssi_percentage[rfPath] = %d \n", priv->stats.rx_rssi_percentage[rfpath]);
4167 RT_TRACE(COMP_RXDESC, "Smooth %s PWDB = %d\n",
4168 pprevious_stats->bIsCCK ? "CCK" : "OFDM",
4169 pprevious_stats->RxPWDBAll);
4171 if (pprevious_stats->bPacketBeacon) {
4172 /* record the beacon pwdb to the sliding window. */
4173 if (slide_beacon_adc_pwdb_statistics++ >= PHY_Beacon_RSSI_SLID_WIN_MAX) {
4174 slide_beacon_adc_pwdb_statistics = PHY_Beacon_RSSI_SLID_WIN_MAX;
4175 last_beacon_adc_pwdb = priv->stats.Slide_Beacon_pwdb[slide_beacon_adc_pwdb_index];
4176 priv->stats.Slide_Beacon_Total -= last_beacon_adc_pwdb;
4178 priv->stats.Slide_Beacon_Total += pprevious_stats->RxPWDBAll;
4179 priv->stats.Slide_Beacon_pwdb[slide_beacon_adc_pwdb_index] = pprevious_stats->RxPWDBAll;
4180 slide_beacon_adc_pwdb_index++;
4181 if (slide_beacon_adc_pwdb_index >= PHY_Beacon_RSSI_SLID_WIN_MAX)
4182 slide_beacon_adc_pwdb_index = 0;
4183 pprevious_stats->RxPWDBAll = priv->stats.Slide_Beacon_Total/slide_beacon_adc_pwdb_statistics;
4184 if (pprevious_stats->RxPWDBAll >= 3)
4185 pprevious_stats->RxPWDBAll -= 3;
4188 RT_TRACE(COMP_RXDESC, "Smooth %s PWDB = %d\n",
4189 pprevious_stats->bIsCCK ? "CCK" : "OFDM",
4190 pprevious_stats->RxPWDBAll);
4193 if (pprevious_stats->bPacketToSelf || pprevious_stats->bPacketBeacon || pprevious_stats->bToSelfBA) {
4194 if (priv->undecorated_smoothed_pwdb < 0) /* initialize */
4195 priv->undecorated_smoothed_pwdb = pprevious_stats->RxPWDBAll;
4196 if (pprevious_stats->RxPWDBAll > (u32)priv->undecorated_smoothed_pwdb) {
4197 priv->undecorated_smoothed_pwdb =
4198 (((priv->undecorated_smoothed_pwdb)*(Rx_Smooth_Factor-1)) +
4199 (pprevious_stats->RxPWDBAll)) /(Rx_Smooth_Factor);
4200 priv->undecorated_smoothed_pwdb = priv->undecorated_smoothed_pwdb + 1;
4202 priv->undecorated_smoothed_pwdb =
4203 (((priv->undecorated_smoothed_pwdb)*(Rx_Smooth_Factor-1)) +
4204 (pprevious_stats->RxPWDBAll)) /(Rx_Smooth_Factor);
4212 /* record the general EVM to the sliding window. */
4213 if (pprevious_stats->SignalQuality) {
4214 if (pprevious_stats->bPacketToSelf || pprevious_stats->bPacketBeacon || pprevious_stats->bToSelfBA) {
4215 if (slide_evm_statistics++ >= PHY_RSSI_SLID_WIN_MAX) {
4216 slide_evm_statistics = PHY_RSSI_SLID_WIN_MAX;
4217 last_evm = priv->stats.slide_evm[slide_evm_index];
4218 priv->stats.slide_evm_total -= last_evm;
4221 priv->stats.slide_evm_total += pprevious_stats->SignalQuality;
4223 priv->stats.slide_evm[slide_evm_index++] = pprevious_stats->SignalQuality;
4224 if (slide_evm_index >= PHY_RSSI_SLID_WIN_MAX)
4225 slide_evm_index = 0;
4227 // <1> Showed on UI for user, in percentage.
4228 tmp_val = priv->stats.slide_evm_total/slide_evm_statistics;
4229 priv->stats.signal_quality = tmp_val;
4230 //cosa add 10/11/2007, Showed on UI for user in Windows Vista, for Link quality.
4231 priv->stats.last_signal_strength_inpercent = tmp_val;
4234 // <2> Showed on UI for engineering
4235 if (pprevious_stats->bPacketToSelf || pprevious_stats->bPacketBeacon || pprevious_stats->bToSelfBA) {
4236 for (nspatial_stream = 0; nspatial_stream < 2; nspatial_stream++) { /* 2 spatial stream */
4237 if (pprevious_stats->RxMIMOSignalQuality[nspatial_stream] != -1) {
4238 if (priv->stats.rx_evm_percentage[nspatial_stream] == 0) /* initialize */
4239 priv->stats.rx_evm_percentage[nspatial_stream] = pprevious_stats->RxMIMOSignalQuality[nspatial_stream];
4240 priv->stats.rx_evm_percentage[nspatial_stream] =
4241 ((priv->stats.rx_evm_percentage[nspatial_stream]* (Rx_Smooth_Factor-1)) +
4242 (pprevious_stats->RxMIMOSignalQuality[nspatial_stream]* 1)) / (Rx_Smooth_Factor);
4251 /*-----------------------------------------------------------------------------
4252 * Function: rtl819x_query_rxpwrpercentage()
4256 * Input: char antpower
4260 * Return: 0-100 percentage
4264 * 05/26/2008 amy Create Version 0 porting from windows code.
4266 *---------------------------------------------------------------------------*/
4267 static u8 rtl819x_query_rxpwrpercentage(char antpower)
4269 if ((antpower <= -100) || (antpower >= 20))
4271 else if (antpower >= 0)
4274 return 100 + antpower;
4276 } /* QueryRxPwrPercentage */
4278 static u8 rtl819x_evm_dbtopercentage(char value)
4288 ret_val = 0 - ret_val;
4296 // We want good-looking for signal strength/quality
4297 // 2007/7/19 01:09, by cosa.
4299 static long rtl819x_signal_scale_mapping(long currsig)
4303 // Step 1. Scale mapping.
4304 if (currsig >= 61 && currsig <= 100)
4305 retsig = 90 + ((currsig - 60) / 4);
4306 else if (currsig >= 41 && currsig <= 60)
4307 retsig = 78 + ((currsig - 40) / 2);
4308 else if (currsig >= 31 && currsig <= 40)
4309 retsig = 66 + (currsig - 30);
4310 else if (currsig >= 21 && currsig <= 30)
4311 retsig = 54 + (currsig - 20);
4312 else if (currsig >= 5 && currsig <= 20)
4313 retsig = 42 + (((currsig - 5) * 2) / 3);
4314 else if (currsig == 4)
4316 else if (currsig == 3)
4318 else if (currsig == 2)
4320 else if (currsig == 1)
4328 static inline bool rx_hal_is_cck_rate(struct rx_drvinfo_819x_usb *pdrvinfo)
4333 switch (pdrvinfo->RxRate) {
4336 case DESC90_RATE5_5M:
4337 case DESC90_RATE11M:
4344 static void rtl8192_query_rxphystatus(struct r8192_priv *priv,
4345 struct ieee80211_rx_stats *pstats,
4346 rx_drvinfo_819x_usb *pdrvinfo,
4347 struct ieee80211_rx_stats *precord_stats,
4348 bool bpacket_match_bssid,
4349 bool bpacket_toself,
4353 phy_sts_ofdm_819xusb_t *pofdm_buf;
4354 phy_sts_cck_819xusb_t *pcck_buf;
4355 phy_ofdm_rx_status_rxsc_sgien_exintfflag *prxsc;
4357 u8 i, max_spatial_stream, tmp_rxsnr, tmp_rxevm, rxsc_sgien_exflg;
4358 char rx_pwr[4], rx_pwr_all = 0;
4359 char rx_snrX, rx_evmX;
4361 u32 RSSI, total_rssi = 0;
4367 priv->stats.numqry_phystatus++;
4369 is_cck_rate = rx_hal_is_cck_rate(pdrvinfo);
4371 // Record it for next packet processing
4372 memset(precord_stats, 0, sizeof(struct ieee80211_rx_stats));
4373 pstats->bPacketMatchBSSID = precord_stats->bPacketMatchBSSID = bpacket_match_bssid;
4374 pstats->bPacketToSelf = precord_stats->bPacketToSelf = bpacket_toself;
4375 pstats->bIsCCK = precord_stats->bIsCCK = is_cck_rate;
4376 pstats->bPacketBeacon = precord_stats->bPacketBeacon = bPacketBeacon;
4377 pstats->bToSelfBA = precord_stats->bToSelfBA = bToSelfBA;
4379 prxpkt = (u8 *)pdrvinfo;
4381 /* Move pointer to the 16th bytes. Phy status start address. */
4382 prxpkt += sizeof(rx_drvinfo_819x_usb);
4384 /* Initial the cck and ofdm buffer pointer */
4385 pcck_buf = (phy_sts_cck_819xusb_t *)prxpkt;
4386 pofdm_buf = (phy_sts_ofdm_819xusb_t *)prxpkt;
4388 pstats->RxMIMOSignalQuality[0] = -1;
4389 pstats->RxMIMOSignalQuality[1] = -1;
4390 precord_stats->RxMIMOSignalQuality[0] = -1;
4391 precord_stats->RxMIMOSignalQuality[1] = -1;
4395 // (1)Hardware does not provide RSSI for CCK
4399 // (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive)
4403 priv->stats.numqry_phystatusCCK++;
4405 if (!priv->bCckHighPower) {
4406 report = pcck_buf->cck_agc_rpt & 0xc0;
4409 //Fixed by Jacken from Bryant 2008-03-20
4410 //Original value is -38 , -26 , -14 , -2
4411 //Fixed value is -35 , -23 , -11 , 6
4413 rx_pwr_all = -35 - (pcck_buf->cck_agc_rpt & 0x3e);
4416 rx_pwr_all = -23 - (pcck_buf->cck_agc_rpt & 0x3e);
4419 rx_pwr_all = -11 - (pcck_buf->cck_agc_rpt & 0x3e);
4422 rx_pwr_all = 6 - (pcck_buf->cck_agc_rpt & 0x3e);
4426 report = pcck_buf->cck_agc_rpt & 0x60;
4430 rx_pwr_all = -35 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1);
4433 rx_pwr_all = -23 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1);
4436 rx_pwr_all = -11 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1);
4439 rx_pwr_all = 6 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1);
4444 pwdb_all = rtl819x_query_rxpwrpercentage(rx_pwr_all);
4445 pstats->RxPWDBAll = precord_stats->RxPWDBAll = pwdb_all;
4446 pstats->RecvSignalPower = pwdb_all;
4449 // (3) Get Signal Quality (EVM)
4452 if (pstats->RxPWDBAll > 40) {
4455 sq = pcck_buf->sq_rpt;
4457 if (pcck_buf->sq_rpt > 64)
4459 else if (pcck_buf->sq_rpt < 20)
4462 sq = ((64-sq) * 100) / 44;
4464 pstats->SignalQuality = precord_stats->SignalQuality = sq;
4465 pstats->RxMIMOSignalQuality[0] = precord_stats->RxMIMOSignalQuality[0] = sq;
4466 pstats->RxMIMOSignalQuality[1] = precord_stats->RxMIMOSignalQuality[1] = -1;
4469 priv->stats.numqry_phystatusHT++;
4471 // (1)Get RSSI for HT rate
4473 for (i = RF90_PATH_A; i < priv->NumTotalRFPath; i++) {
4474 // 2008/01/30 MH we will judge RF RX path now.
4475 if (priv->brfpath_rxenable[i])
4480 if (!rtl8192_phy_CheckIsLegalRFPath(priv->ieee80211->dev, i))
4483 //Fixed by Jacken from Bryant 2008-03-20
4484 //Original value is 106
4485 rx_pwr[i] = ((pofdm_buf->trsw_gain_X[i]&0x3F)*2) - 106;
4487 //Get Rx snr value in DB
4488 tmp_rxsnr = pofdm_buf->rxsnr_X[i];
4489 rx_snrX = (char)(tmp_rxsnr);
4491 priv->stats.rxSNRdB[i] = (long)rx_snrX;
4493 /* Translate DBM to percentage. */
4494 RSSI = rtl819x_query_rxpwrpercentage(rx_pwr[i]);
4497 /* Record Signal Strength for next packet */
4498 pstats->RxMIMOSignalStrength[i] = (u8) RSSI;
4499 precord_stats->RxMIMOSignalStrength[i] = (u8) RSSI;
4504 // (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive)
4506 //Fixed by Jacken from Bryant 2008-03-20
4507 //Original value is 106
4508 rx_pwr_all = (((pofdm_buf->pwdb_all) >> 1)& 0x7f) -106;
4509 pwdb_all = rtl819x_query_rxpwrpercentage(rx_pwr_all);
4511 pstats->RxPWDBAll = precord_stats->RxPWDBAll = pwdb_all;
4512 pstats->RxPower = precord_stats->RxPower = rx_pwr_all;
4515 // (3)EVM of HT rate
4517 if (pdrvinfo->RxHT && pdrvinfo->RxRate >= DESC90_RATEMCS8 &&
4518 pdrvinfo->RxRate <= DESC90_RATEMCS15)
4519 max_spatial_stream = 2; //both spatial stream make sense
4521 max_spatial_stream = 1; //only spatial stream 1 makes sense
4523 for (i = 0; i < max_spatial_stream; i++) {
4524 tmp_rxevm = pofdm_buf->rxevm_X[i];
4525 rx_evmX = (char)(tmp_rxevm);
4527 // Do not use shift operation like "rx_evmX >>= 1" because the compiler of free build environment
4528 // will set the most significant bit to "zero" when doing shifting operation which may change a negative
4529 // value to positive one, then the dbm value (which is supposed to be negative) is not correct anymore.
4532 evm = rtl819x_evm_dbtopercentage(rx_evmX);
4533 if (i == 0) /* Fill value in RFD, Get the first spatial stream only */
4534 pstats->SignalQuality = precord_stats->SignalQuality = (u8)(evm & 0xff);
4535 pstats->RxMIMOSignalQuality[i] = precord_stats->RxMIMOSignalQuality[i] = (u8)(evm & 0xff);
4539 /* record rx statistics for debug */
4540 rxsc_sgien_exflg = pofdm_buf->rxsc_sgien_exflg;
4541 prxsc = (phy_ofdm_rx_status_rxsc_sgien_exintfflag *)&rxsc_sgien_exflg;
4542 if (pdrvinfo->BW) /* 40M channel */
4543 priv->stats.received_bwtype[1+prxsc->rxsc]++;
4545 priv->stats.received_bwtype[0]++;
4548 //UI BSS List signal strength(in percentage), make it good looking, from 0~100.
4549 //It is assigned to the BSS List in GetValueFromBeaconOrProbeRsp().
4551 pstats->SignalStrength = precord_stats->SignalStrength = (u8)(rtl819x_signal_scale_mapping((long)pwdb_all));
4553 // We can judge RX path number now.
4555 pstats->SignalStrength = precord_stats->SignalStrength = (u8)(rtl819x_signal_scale_mapping((long)(total_rssi /= rf_rx_num)));
4557 } /* QueryRxPhyStatus8190Pci */
4559 static void rtl8192_record_rxdesc_forlateruse(struct ieee80211_rx_stats *psrc_stats,
4560 struct ieee80211_rx_stats *ptarget_stats)
4562 ptarget_stats->bIsAMPDU = psrc_stats->bIsAMPDU;
4563 ptarget_stats->bFirstMPDU = psrc_stats->bFirstMPDU;
4564 ptarget_stats->Seq_Num = psrc_stats->Seq_Num;
4568 static void TranslateRxSignalStuff819xUsb(struct sk_buff *skb,
4569 struct ieee80211_rx_stats *pstats,
4570 rx_drvinfo_819x_usb *pdrvinfo)
4572 // TODO: We must only check packet for current MAC address. Not finish
4573 rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
4574 struct net_device *dev = info->dev;
4575 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
4576 bool bpacket_match_bssid, bpacket_toself;
4577 bool bPacketBeacon = FALSE, bToSelfBA = FALSE;
4578 static struct ieee80211_rx_stats previous_stats;
4579 struct ieee80211_hdr_3addr *hdr;//by amy
4582 // Get Signal Quality for only RX data queue (but not command queue)
4587 /* Get MAC frame start address. */
4588 tmp_buf = (u8 *)skb->data;
4590 hdr = (struct ieee80211_hdr_3addr *)tmp_buf;
4591 fc = le16_to_cpu(hdr->frame_ctl);
4592 type = WLAN_FC_GET_TYPE(fc);
4593 praddr = hdr->addr1;
4595 /* Check if the received packet is acceptable. */
4596 bpacket_match_bssid = ((IEEE80211_FTYPE_CTL != type) &&
4597 (eqMacAddr(priv->ieee80211->current_network.bssid, (fc & IEEE80211_FCTL_TODS) ? hdr->addr1 : (fc & IEEE80211_FCTL_FROMDS) ? hdr->addr2 : hdr->addr3))
4598 && (!pstats->bHwError) && (!pstats->bCRC) && (!pstats->bICV));
4599 bpacket_toself = bpacket_match_bssid & (eqMacAddr(praddr, priv->ieee80211->dev->dev_addr));
4601 if (WLAN_FC_GET_FRAMETYPE(fc) == IEEE80211_STYPE_BEACON)
4602 bPacketBeacon = true;
4603 if (WLAN_FC_GET_FRAMETYPE(fc) == IEEE80211_STYPE_BLOCKACK) {
4604 if ((eqMacAddr(praddr, dev->dev_addr)))
4610 if (bpacket_match_bssid)
4611 priv->stats.numpacket_matchbssid++;
4613 priv->stats.numpacket_toself++;
4615 // Process PHY information for previous packet (RSSI/PWDB/EVM)
4617 // Because phy information is contained in the last packet of AMPDU only, so driver
4618 // should process phy information of previous packet
4619 rtl8192_process_phyinfo(priv, tmp_buf, &previous_stats, pstats);
4620 rtl8192_query_rxphystatus(priv, pstats, pdrvinfo, &previous_stats, bpacket_match_bssid, bpacket_toself, bPacketBeacon, bToSelfBA);
4621 rtl8192_record_rxdesc_forlateruse(pstats, &previous_stats);
4626 * Function: UpdateReceivedRateHistogramStatistics
4627 * Overview: Record the received data rate
4630 * struct net_device *dev
4631 * struct ieee80211_rx_stats *stats
4635 * (priv->stats.ReceivedRateHistogram[] is updated)
4640 UpdateReceivedRateHistogramStatistics8190(struct net_device *dev,
4641 struct ieee80211_rx_stats *stats)
4643 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
4644 u32 rcvType = 1; //0: Total, 1:OK, 2:CRC, 3:ICV
4646 u32 preamble_guardinterval; //1: short preamble/GI, 0: long preamble/GI
4651 else if (stats->bICV)
4654 if (stats->bShortPreamble)
4655 preamble_guardinterval = 1;// short
4657 preamble_guardinterval = 0;// long
4659 switch (stats->rate) {
4703 // 11n High throughput rate
4757 priv->stats.received_preamble_GI[preamble_guardinterval][rateIndex]++;
4758 priv->stats.received_rate_histogram[0][rateIndex]++; //total
4759 priv->stats.received_rate_histogram[rcvType][rateIndex]++;
4763 static void query_rxdesc_status(struct sk_buff *skb,
4764 struct ieee80211_rx_stats *stats,
4765 bool bIsRxAggrSubframe)
4767 rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
4768 struct net_device *dev = info->dev;
4769 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
4770 rx_drvinfo_819x_usb *driver_info = NULL;
4773 //Get Rx Descriptor Information
4775 #ifdef USB_RX_AGGREGATION_SUPPORT
4776 if (bIsRxAggrSubframe) {
4777 rx_desc_819x_usb_aggr_subframe *desc = (rx_desc_819x_usb_aggr_subframe *)skb->data;
4778 stats->Length = desc->Length;
4779 stats->RxDrvInfoSize = desc->RxDrvInfoSize;
4780 stats->RxBufShift = 0; //RxBufShift = 2 in RxDesc, but usb didn't shift bytes in fact.
4781 stats->bICV = desc->ICV;
4782 stats->bCRC = desc->CRC32;
4783 stats->bHwError = stats->bCRC|stats->bICV;
4784 stats->Decrypted = !desc->SWDec;//RTL8190 set this bit to indicate that Hw does not decrypt packet
4788 rx_desc_819x_usb *desc = (rx_desc_819x_usb *)skb->data;
4790 stats->Length = desc->Length;
4791 stats->RxDrvInfoSize = desc->RxDrvInfoSize;
4792 stats->RxBufShift = 0;
4793 stats->bICV = desc->ICV;
4794 stats->bCRC = desc->CRC32;
4795 stats->bHwError = stats->bCRC|stats->bICV;
4796 //RTL8190 set this bit to indicate that Hw does not decrypt packet
4797 stats->Decrypted = !desc->SWDec;
4800 if ((priv->ieee80211->pHTInfo->bCurrentHTSupport == true) && (priv->ieee80211->pairwise_key_type == KEY_TYPE_CCMP))
4801 stats->bHwError = false;
4803 stats->bHwError = stats->bCRC|stats->bICV;
4805 if (stats->Length < 24 || stats->Length > MAX_8192U_RX_SIZE)
4806 stats->bHwError |= 1;
4810 // TODO: Need to verify it on FGPA platform
4811 //Driver info are written to the RxBuffer following rx desc
4812 if (stats->RxDrvInfoSize != 0) {
4813 driver_info = (rx_drvinfo_819x_usb *)(skb->data + sizeof(rx_desc_819x_usb) +
4817 if (!stats->bHwError) {
4819 ret_rate = HwRateToMRate90(driver_info->RxHT, driver_info->RxRate);
4820 if (ret_rate == 0xff) {
4821 // Abnormal Case: Receive CRC OK packet with Rx descriptor indicating non supported rate.
4822 // Special Error Handling here, 2008.05.16, by Emily
4824 stats->bHwError = 1;
4825 stats->rate = MGN_1M; //Set 1M rate by default
4827 stats->rate = ret_rate;
4833 stats->bShortPreamble = driver_info->SPLCP;
4836 UpdateReceivedRateHistogramStatistics8190(dev, stats);
4838 stats->bIsAMPDU = (driver_info->PartAggr == 1);
4839 stats->bFirstMPDU = (driver_info->PartAggr == 1) && (driver_info->FirstAGGR == 1);
4840 stats->TimeStampLow = driver_info->TSFL;
4841 // xiong mask it, 070514
4843 UpdateRxPktTimeStamp8190(dev, stats);
4848 if (driver_info->FirstAGGR == 1 || driver_info->PartAggr == 1)
4849 RT_TRACE(COMP_RXDESC, "driver_info->FirstAGGR = %d, driver_info->PartAggr = %d\n",
4850 driver_info->FirstAGGR, driver_info->PartAggr);
4854 skb_pull(skb, sizeof(rx_desc_819x_usb));
4856 // Get Total offset of MPDU Frame Body
4858 if ((stats->RxBufShift + stats->RxDrvInfoSize) > 0) {
4860 skb_pull(skb, stats->RxBufShift + stats->RxDrvInfoSize);
4863 #ifdef USB_RX_AGGREGATION_SUPPORT
4864 /* for the rx aggregated sub frame, the redundant space truly contained in the packet */
4865 if (bIsRxAggrSubframe)
4868 /* for debug 2008.5.29 */
4870 //added by vivi, for MP, 20080108
4871 stats->RxIs40MHzPacket = driver_info->BW;
4872 if (stats->RxDrvInfoSize != 0)
4873 TranslateRxSignalStuff819xUsb(skb, stats, driver_info);
4877 u32 GetRxPacketShiftBytes819xUsb(struct ieee80211_rx_stats *Status, bool bIsRxAggrSubframe)
4879 #ifdef USB_RX_AGGREGATION_SUPPORT
4880 if (bIsRxAggrSubframe)
4881 return (sizeof(rx_desc_819x_usb) + Status->RxDrvInfoSize
4882 + Status->RxBufShift + 8);
4885 return (sizeof(rx_desc_819x_usb) + Status->RxDrvInfoSize
4886 + Status->RxBufShift);
4889 static void rtl8192_rx_nomal(struct sk_buff *skb)
4891 rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
4892 struct net_device *dev = info->dev;
4893 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
4894 struct ieee80211_rx_stats stats = {
4898 .freq = IEEE80211_24GHZ_BAND,
4901 struct ieee80211_hdr_1addr *ieee80211_hdr = NULL;
4902 bool unicast_packet = false;
4903 #ifdef USB_RX_AGGREGATION_SUPPORT
4904 struct sk_buff *agg_skb = NULL;
4905 u32 TotalLength = 0;
4907 u32 PacketLength = 0;
4908 u32 PacketOccupiedLendth = 0;
4910 u32 PacketShiftBytes = 0;
4911 rx_desc_819x_usb_aggr_subframe *RxDescr = NULL;
4912 u8 PaddingBytes = 0;
4913 //add just for testing
4918 /* 20 is for ps-poll */
4919 if ((skb->len >= (20 + sizeof(rx_desc_819x_usb))) && (skb->len < RX_URB_SIZE)) {
4920 #ifdef USB_RX_AGGREGATION_SUPPORT
4921 TempByte = *(skb->data + sizeof(rx_desc_819x_usb));
4923 /* first packet should not contain Rx aggregation header */
4924 query_rxdesc_status(skb, &stats, false);
4926 /* hardware related info */
4927 #ifdef USB_RX_AGGREGATION_SUPPORT
4928 if (TempByte & BIT0) {
4930 TotalLength = stats.Length - 4; /*sCrcLng*/
4931 /* though the head pointer has passed this position */
4932 TempDWord = *(u32 *)(agg_skb->data - 4);
4933 PacketLength = (u16)(TempDWord & 0x3FFF); /*sCrcLng*/
4934 skb = dev_alloc_skb(PacketLength);
4935 memcpy(skb_put(skb, PacketLength), agg_skb->data, PacketLength);
4936 PacketShiftBytes = GetRxPacketShiftBytes819xUsb(&stats, false);
4939 /* Process the MPDU received */
4940 skb_trim(skb, skb->len - 4/*sCrcLng*/);
4942 rx_pkt_len = skb->len;
4943 ieee80211_hdr = (struct ieee80211_hdr_1addr *)skb->data;
4944 unicast_packet = false;
4945 if (is_broadcast_ether_addr(ieee80211_hdr->addr1)) {
4947 } else if (is_multicast_ether_addr(ieee80211_hdr->addr1)) {
4950 /* unicast packet */
4951 unicast_packet = true;
4954 if (!ieee80211_rx(priv->ieee80211, skb, &stats)) {
4955 dev_kfree_skb_any(skb);
4957 priv->stats.rxoktotal++;
4959 priv->stats.rxbytesunicast += rx_pkt_len;
4961 #ifdef USB_RX_AGGREGATION_SUPPORT
4963 if (TotalLength > 0) {
4964 PacketOccupiedLendth = PacketLength + (PacketShiftBytes + 8);
4965 if ((PacketOccupiedLendth & 0xFF) != 0)
4966 PacketOccupiedLendth = (PacketOccupiedLendth & 0xFFFFFF00) + 256;
4967 PacketOccupiedLendth -= 8;
4968 TempDWord = PacketOccupiedLendth - PacketShiftBytes; /*- PacketLength */
4969 if (agg_skb->len > TempDWord)
4970 skb_pull(agg_skb, TempDWord);
4974 while (agg_skb->len >= GetRxPacketShiftBytes819xUsb(&stats, true)) {
4975 u8 tmpCRC = 0, tmpICV = 0;
4976 RxDescr = (rx_desc_819x_usb_aggr_subframe *)(agg_skb->data);
4977 tmpCRC = RxDescr->CRC32;
4978 tmpICV = RxDescr->ICV;
4979 memcpy(agg_skb->data, &agg_skb->data[44], 2);
4980 RxDescr->CRC32 = tmpCRC;
4981 RxDescr->ICV = tmpICV;
4983 memset(&stats, 0, sizeof(struct ieee80211_rx_stats));
4987 stats.freq = IEEE80211_24GHZ_BAND;
4988 query_rxdesc_status(agg_skb, &stats, true);
4989 PacketLength = stats.Length;
4991 if (PacketLength > agg_skb->len)
4993 /* Process the MPDU received */
4994 skb = dev_alloc_skb(PacketLength);
4995 memcpy(skb_put(skb, PacketLength), agg_skb->data, PacketLength);
4996 skb_trim(skb, skb->len - 4/*sCrcLng*/);
4998 rx_pkt_len = skb->len;
4999 ieee80211_hdr = (struct ieee80211_hdr_1addr *)skb->data;
5000 unicast_packet = false;
5001 if (is_broadcast_ether_addr(ieee80211_hdr->addr1)) {
5003 } else if (is_multicast_ether_addr(ieee80211_hdr->addr1)) {
5006 /* unicast packet */
5007 unicast_packet = true;
5009 if (!ieee80211_rx(priv->ieee80211, skb, &stats)) {
5010 dev_kfree_skb_any(skb);
5012 priv->stats.rxoktotal++;
5014 priv->stats.rxbytesunicast += rx_pkt_len;
5016 /* should trim the packet which has been copied to target skb */
5017 skb_pull(agg_skb, PacketLength);
5018 PacketShiftBytes = GetRxPacketShiftBytes819xUsb(&stats, true);
5019 PacketOccupiedLendth = PacketLength + PacketShiftBytes;
5020 if ((PacketOccupiedLendth & 0xFF) != 0) {
5021 PaddingBytes = 256 - (PacketOccupiedLendth & 0xFF);
5022 if (agg_skb->len > PaddingBytes)
5023 skb_pull(agg_skb, PaddingBytes);
5028 dev_kfree_skb(agg_skb);
5032 priv->stats.rxurberr++;
5033 netdev_dbg(dev, "actual_length: %d\n", skb->len);
5034 dev_kfree_skb_any(skb);
5039 static void rtl819xusb_process_received_packet(struct net_device *dev,
5040 struct ieee80211_rx_stats *pstats)
5044 struct r8192_priv *priv = ieee80211_priv(dev);
5046 // Get shifted bytes of Starting address of 802.11 header. 2006.09.28, by Emily
5047 //porting by amy 080508
5048 pstats->virtual_address += get_rxpacket_shiftbytes_819xusb(pstats);
5049 frame = pstats->virtual_address;
5050 frame_len = pstats->packetlength;
5051 #ifdef TODO // by amy about HCT
5052 if (!Adapter->bInHctTest)
5053 CountRxErrStatistics(Adapter, pRfd);
5055 #ifdef ENABLE_PS //by amy for adding ps function in future
5056 RT_RF_POWER_STATE rtState;
5057 // When RF is off, we should not count the packet for hw/sw synchronize
5058 // reason, ie. there may be a duration while sw switch is changed and hw
5059 // switch is being changed. 2006.12.04, by shien chang.
5060 Adapter->HalFunc.GetHwRegHandler(Adapter, HW_VAR_RF_STATE, (u8 *)(&rtState));
5061 if (rtState == eRfOff)
5064 priv->stats.rxframgment++;
5067 RmMonitorSignalStrength(Adapter, pRfd);
5069 /* 2007/01/16 MH Add RX command packet handle here. */
5070 /* 2007/03/01 MH We have to release RFD and return if rx pkt is cmd pkt. */
5071 if (rtl819xusb_rx_command_packet(dev, pstats))
5081 static void query_rx_cmdpkt_desc_status(struct sk_buff *skb,
5082 struct ieee80211_rx_stats *stats)
5084 rx_desc_819x_usb *desc = (rx_desc_819x_usb *)skb->data;
5087 //Get Rx Descriptor Information
5089 stats->virtual_address = (u8 *)skb->data;
5090 stats->Length = desc->Length;
5091 stats->RxDrvInfoSize = 0;
5092 stats->RxBufShift = 0;
5093 stats->packetlength = stats->Length-scrclng;
5094 stats->fraglength = stats->packetlength;
5095 stats->fragoffset = 0;
5096 stats->ntotalfrag = 1;
5100 static void rtl8192_rx_cmd(struct sk_buff *skb)
5102 struct rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
5103 struct net_device *dev = info->dev;
5105 struct ieee80211_rx_stats stats = {
5109 .freq = IEEE80211_24GHZ_BAND,
5112 if ((skb->len >= (20 + sizeof(rx_desc_819x_usb))) && (skb->len < RX_URB_SIZE)) {
5114 query_rx_cmdpkt_desc_status(skb, &stats);
5115 // this is to be done by amy 080508 prfd->queue_id = 1;
5119 // Process the command packet received.
5122 rtl819xusb_process_received_packet(dev, &stats);
5124 dev_kfree_skb_any(skb);
5128 void rtl8192_irq_rx_tasklet(struct r8192_priv *priv)
5130 struct sk_buff *skb;
5131 struct rtl8192_rx_info *info;
5133 while (NULL != (skb = skb_dequeue(&priv->skb_queue))) {
5134 info = (struct rtl8192_rx_info *)skb->cb;
5135 switch (info->out_pipe) {
5136 /* Nomal packet pipe */
5138 priv->IrpPendingCount--;
5139 rtl8192_rx_nomal(skb);
5142 /* Command packet pipe */
5144 RT_TRACE(COMP_RECV, "command in-pipe index(%d)\n",
5147 rtl8192_rx_cmd(skb);
5150 default: /* should never get here! */
5151 RT_TRACE(COMP_ERR, "Unknown in-pipe index(%d)\n",
5160 static const struct net_device_ops rtl8192_netdev_ops = {
5161 .ndo_open = rtl8192_open,
5162 .ndo_stop = rtl8192_close,
5163 .ndo_get_stats = rtl8192_stats,
5164 .ndo_tx_timeout = tx_timeout,
5165 .ndo_do_ioctl = rtl8192_ioctl,
5166 .ndo_set_rx_mode = r8192_set_multicast,
5167 .ndo_set_mac_address = r8192_set_mac_adr,
5168 .ndo_validate_addr = eth_validate_addr,
5169 .ndo_change_mtu = eth_change_mtu,
5170 .ndo_start_xmit = ieee80211_xmit,
5174 /****************************************************************************
5175 ---------------------------- USB_STUFF---------------------------
5176 *****************************************************************************/
5178 static int rtl8192_usb_probe(struct usb_interface *intf,
5179 const struct usb_device_id *id)
5181 struct net_device *dev = NULL;
5182 struct r8192_priv *priv = NULL;
5183 struct usb_device *udev = interface_to_usbdev(intf);
5185 RT_TRACE(COMP_INIT, "Oops: i'm coming\n");
5187 dev = alloc_ieee80211(sizeof(struct r8192_priv));
5191 usb_set_intfdata(intf, dev);
5192 SET_NETDEV_DEV(dev, &intf->dev);
5193 priv = ieee80211_priv(dev);
5194 priv->ieee80211 = netdev_priv(dev);
5197 dev->netdev_ops = &rtl8192_netdev_ops;
5199 dev->wireless_handlers = (struct iw_handler_def *) &r8192_wx_handlers_def;
5201 dev->type = ARPHRD_ETHER;
5203 dev->watchdog_timeo = HZ*3; //modified by john, 0805
5205 if (dev_alloc_name(dev, ifname) < 0) {
5206 RT_TRACE(COMP_INIT, "Oops: devname already taken! Trying wlan%%d...\n");
5208 dev_alloc_name(dev, ifname);
5211 RT_TRACE(COMP_INIT, "Driver probe completed1\n");
5212 if (rtl8192_init(dev) != 0) {
5213 RT_TRACE(COMP_ERR, "Initialization failed");
5217 netif_carrier_off(dev);
5218 netif_stop_queue(dev);
5220 ret = register_netdev(dev);
5224 RT_TRACE(COMP_INIT, "dev name=======> %s\n", dev->name);
5225 rtl8192_proc_init_one(dev);
5228 RT_TRACE(COMP_INIT, "Driver probe completed\n");
5233 kfree(priv->pFirmware);
5234 priv->pFirmware = NULL;
5235 rtl8192_usb_deleteendpoints(dev);
5236 destroy_workqueue(priv->priv_wq);
5239 free_ieee80211(dev);
5241 RT_TRACE(COMP_ERR, "wlan driver load failed\n");
5245 //detach all the work and timer structure declared or inititialize in r8192U_init function.
5246 void rtl8192_cancel_deferred_work(struct r8192_priv *priv)
5249 cancel_work_sync(&priv->reset_wq);
5250 cancel_delayed_work(&priv->watch_dog_wq);
5251 cancel_delayed_work(&priv->update_beacon_wq);
5252 cancel_work_sync(&priv->qos_activate);
5256 static void rtl8192_usb_disconnect(struct usb_interface *intf)
5258 struct net_device *dev = usb_get_intfdata(intf);
5260 struct r8192_priv *priv = ieee80211_priv(dev);
5263 unregister_netdev(dev);
5265 RT_TRACE(COMP_DOWN, "=============>wlan driver to be removed\n");
5266 rtl8192_proc_remove_one(dev);
5269 kfree(priv->pFirmware);
5270 priv->pFirmware = NULL;
5271 rtl8192_usb_deleteendpoints(dev);
5272 destroy_workqueue(priv->priv_wq);
5276 free_ieee80211(dev);
5277 RT_TRACE(COMP_DOWN, "wlan driver removed\n");
5280 /* fun with the built-in ieee80211 stack... */
5281 extern int ieee80211_debug_init(void);
5282 extern void ieee80211_debug_exit(void);
5283 extern int ieee80211_crypto_init(void);
5284 extern void ieee80211_crypto_deinit(void);
5285 extern int ieee80211_crypto_tkip_init(void);
5286 extern void ieee80211_crypto_tkip_exit(void);
5287 extern int ieee80211_crypto_ccmp_init(void);
5288 extern void ieee80211_crypto_ccmp_exit(void);
5289 extern int ieee80211_crypto_wep_init(void);
5290 extern void ieee80211_crypto_wep_exit(void);
5292 static int __init rtl8192_usb_module_init(void)
5296 #ifdef CONFIG_IEEE80211_DEBUG
5297 ret = ieee80211_debug_init();
5299 pr_err("ieee80211_debug_init() failed %d\n", ret);
5303 ret = ieee80211_crypto_init();
5305 pr_err("ieee80211_crypto_init() failed %d\n", ret);
5309 ret = ieee80211_crypto_tkip_init();
5311 pr_err("ieee80211_crypto_tkip_init() failed %d\n", ret);
5315 ret = ieee80211_crypto_ccmp_init();
5317 pr_err("ieee80211_crypto_ccmp_init() failed %d\n", ret);
5321 ret = ieee80211_crypto_wep_init();
5323 pr_err("ieee80211_crypto_wep_init() failed %d\n", ret);
5327 pr_info("\nLinux kernel driver for RTL8192 based WLAN cards\n");
5328 pr_info("Copyright (c) 2007-2008, Realsil Wlan\n");
5329 RT_TRACE(COMP_INIT, "Initializing module");
5330 RT_TRACE(COMP_INIT, "Wireless extensions version %d", WIRELESS_EXT);
5331 rtl8192_proc_module_init();
5332 return usb_register(&rtl8192_usb_driver);
5336 static void __exit rtl8192_usb_module_exit(void)
5338 usb_deregister(&rtl8192_usb_driver);
5340 RT_TRACE(COMP_DOWN, "Exiting");
5344 void rtl8192_try_wake_queue(struct net_device *dev, int pri)
5346 unsigned long flags;
5348 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
5350 spin_lock_irqsave(&priv->tx_lock, flags);
5351 enough_desc = check_nic_enough_desc(dev, pri);
5352 spin_unlock_irqrestore(&priv->tx_lock, flags);
5355 ieee80211_wake_queue(priv->ieee80211);
5358 void EnableHWSecurityConfig8192(struct net_device *dev)
5360 u8 SECR_value = 0x0;
5361 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
5362 struct ieee80211_device *ieee = priv->ieee80211;
5363 SECR_value = SCR_TxEncEnable | SCR_RxDecEnable;
5364 if (((KEY_TYPE_WEP40 == ieee->pairwise_key_type) || (KEY_TYPE_WEP104 == ieee->pairwise_key_type)) && (priv->ieee80211->auth_mode != 2)) {
5365 SECR_value |= SCR_RxUseDK;
5366 SECR_value |= SCR_TxUseDK;
5367 } else if ((ieee->iw_mode == IW_MODE_ADHOC) && (ieee->pairwise_key_type & (KEY_TYPE_CCMP | KEY_TYPE_TKIP))) {
5368 SECR_value |= SCR_RxUseDK;
5369 SECR_value |= SCR_TxUseDK;
5371 //add HWSec active enable here.
5372 //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
5374 ieee->hwsec_active = 1;
5376 if ((ieee->pHTInfo->IOTAction&HT_IOT_ACT_PURE_N_MODE) || !hwwep) { /* add hwsec_support flag to totol control hw_sec on/off */
5377 ieee->hwsec_active = 0;
5378 SECR_value &= ~SCR_RxDecEnable;
5380 RT_TRACE(COMP_SEC, "%s:, hwsec:%d, pairwise_key:%d, SECR_value:%x\n", __func__,
5381 ieee->hwsec_active, ieee->pairwise_key_type, SECR_value);
5382 write_nic_byte(dev, SECR, SECR_value);
5386 void setKey(struct net_device *dev, u8 EntryNo, u8 KeyIndex, u16 KeyType,
5387 u8 *MacAddr, u8 DefaultKey, u32 *KeyContent)
5389 u32 TargetCommand = 0;
5390 u32 TargetContent = 0;
5393 if (EntryNo >= TOTAL_CAM_ENTRY)
5394 RT_TRACE(COMP_ERR, "cam entry exceeds in setKey()\n");
5396 RT_TRACE(COMP_SEC, "====>to setKey(), dev:%p, EntryNo:%d, KeyIndex:%d, KeyType:%d, MacAddr%pM\n", dev, EntryNo, KeyIndex, KeyType, MacAddr);
5399 usConfig |= BIT15 | (KeyType<<2);
5401 usConfig |= BIT15 | (KeyType<<2) | KeyIndex;
5404 for (i = 0; i < CAM_CONTENT_COUNT; i++) {
5405 TargetCommand = i+CAM_CONTENT_COUNT*EntryNo;
5406 TargetCommand |= BIT31|BIT16;
5408 if (i == 0) { /* MAC|Config */
5409 TargetContent = (u32)(*(MacAddr+0)) << 16|
5410 (u32)(*(MacAddr+1)) << 24|
5413 write_nic_dword(dev, WCAMI, TargetContent);
5414 write_nic_dword(dev, RWCAM, TargetCommand);
5415 } else if (i == 1) { /* MAC */
5416 TargetContent = (u32)(*(MacAddr+2)) |
5417 (u32)(*(MacAddr+3)) << 8|
5418 (u32)(*(MacAddr+4)) << 16|
5419 (u32)(*(MacAddr+5)) << 24;
5420 write_nic_dword(dev, WCAMI, TargetContent);
5421 write_nic_dword(dev, RWCAM, TargetCommand);
5424 if (KeyContent != NULL) {
5425 write_nic_dword(dev, WCAMI, (u32)(*(KeyContent+i-2)));
5426 write_nic_dword(dev, RWCAM, TargetCommand);
5433 /***************************************************************************
5434 ------------------- module init / exit stubs ----------------
5435 ****************************************************************************/
5436 module_init(rtl8192_usb_module_init);
5437 module_exit(rtl8192_usb_module_exit);