1 /******************************************************************************
2 * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
3 * Linux device driver for RTL8192U
5 * Based on the r8187 driver, which is:
6 * Copyright 2004-2005 Andrea Merello <andreamrl@tiscali.it>, et al.
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of version 2 of the GNU General Public License as
9 * published by the Free Software Foundation.
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 * You should have received a copy of the GNU General Public License along with
17 * this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
20 * The full GNU General Public License is included in this distribution in the
21 * file called LICENSE.
23 * Contact Information:
24 * Jerry chuang <wlanfae@realtek.com>
27 #ifndef CONFIG_FORCE_HARD_FLOAT
28 double __floatsidf (int i) { return i; }
29 unsigned int __fixunsdfsi (double d) { return d; }
30 double __adddf3(double a, double b) { return a+b; }
31 double __addsf3(float a, float b) { return a+b; }
32 double __subdf3(double a, double b) { return a-b; }
33 double __extendsfdf2(float a) {return a;}
40 #undef RX_DONT_PASS_UL
42 #undef DEBUG_RX_VERBOSE
48 #undef DEBUG_TX_FILLDESC
53 #undef DEBUG_REGISTERS
55 #undef DEBUG_IRQ_TASKLET
59 #define CONFIG_RTL8192_IO_MAP
61 #include <asm/uaccess.h>
62 #include "r8192U_hw.h"
64 #include "r8190_rtl8256.h" /* RTL8225 Radio frontend */
65 #include "r8180_93cx6.h" /* Card EEPROM */
66 #include "r8192U_wx.h"
67 #include "r819xU_phy.h" //added by WB 4.30.2008
68 #include "r819xU_phyreg.h"
69 #include "r819xU_cmdpkt.h"
70 #include "r8192U_dm.h"
71 //#include "r8192xU_phyreg.h"
72 #include <linux/usb.h>
73 #include <linux/slab.h>
74 // FIXME: check if 2.6.7 is ok
76 #ifdef CONFIG_RTL8192_PM
83 //set here to open your trace code. //WB
84 u32 rt_global_debug_component = \
92 // COMP_POWER_TRACKING |
103 COMP_ERR ; //always open err flags on
105 #define TOTAL_CAM_ENTRY 32
106 #define CAM_CONTENT_COUNT 8
108 static const struct usb_device_id rtl8192_usb_id_tbl[] = {
110 {USB_DEVICE(0x0bda, 0x8192)},
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(hwseqnum,int, S_IRUGO|S_IWUSR);
142 module_param(hwwep,int, S_IRUGO|S_IWUSR);
143 module_param(channels,int, S_IRUGO|S_IWUSR);
145 MODULE_PARM_DESC(ifname," Net interface name, wlan%d=default");
146 //MODULE_PARM_DESC(hwseqnum," Try to use hardware 802.11 header sequence numbers. Zero=default");
147 MODULE_PARM_DESC(hwwep," Try to use hardware security support. ");
148 MODULE_PARM_DESC(channels," Channel bitmask for specific locales. NYI");
150 static int __devinit rtl8192_usb_probe(struct usb_interface *intf,
151 const struct usb_device_id *id);
152 static void __devexit rtl8192_usb_disconnect(struct usb_interface *intf);
155 static struct usb_driver rtl8192_usb_driver = {
156 .name = RTL819xU_MODULE_NAME, /* Driver name */
157 .id_table = rtl8192_usb_id_tbl, /* PCI_ID table */
158 .probe = rtl8192_usb_probe, /* probe fn */
159 .disconnect = rtl8192_usb_disconnect, /* remove fn */
160 #ifdef CONFIG_RTL8192_PM
161 .suspend = rtl8192_suspend, /* PM suspend fn */
162 .resume = rtl8192_resume, /* PM resume fn */
164 .suspend = NULL, /* PM suspend fn */
165 .resume = NULL, /* PM resume fn */
171 typedef struct _CHANNEL_LIST
175 }CHANNEL_LIST, *PCHANNEL_LIST;
177 static CHANNEL_LIST ChannelPlan[] = {
178 {{1,2,3,4,5,6,7,8,9,10,11,36,40,44,48,52,56,60,64,149,153,157,161,165},24}, //FCC
179 {{1,2,3,4,5,6,7,8,9,10,11},11}, //IC
180 {{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48,52,56,60,64},21}, //ETSI
181 {{1,2,3,4,5,6,7,8,9,10,11,12,13},13}, //Spain. Change to ETSI.
182 {{1,2,3,4,5,6,7,8,9,10,11,12,13},13}, //France. Change to ETSI.
183 {{1,2,3,4,5,6,7,8,9,10,11,12,13,14,36,40,44,48,52,56,60,64},22}, //MKK //MKK
184 {{1,2,3,4,5,6,7,8,9,10,11,12,13,14,36,40,44,48,52,56,60,64},22},//MKK1
185 {{1,2,3,4,5,6,7,8,9,10,11,12,13},13}, //Israel.
186 {{1,2,3,4,5,6,7,8,9,10,11,12,13,14,36,40,44,48,52,56,60,64},22}, // For 11a , TELEC
187 {{1,2,3,4,5,6,7,8,9,10,11,12,13,14,36,40,44,48,52,56,60,64}, 22}, //MIC
188 {{1,2,3,4,5,6,7,8,9,10,11,12,13,14},14} //For Global Domain. 1-11:active scan, 12-14 passive scan. //+YJ, 080626
191 static void rtl819x_set_channel_map(u8 channel_plan, struct r8192_priv* priv)
193 int i, max_chan=-1, min_chan=-1;
194 struct ieee80211_device* ieee = priv->ieee80211;
195 switch (channel_plan)
197 case COUNTRY_CODE_FCC:
198 case COUNTRY_CODE_IC:
199 case COUNTRY_CODE_ETSI:
200 case COUNTRY_CODE_SPAIN:
201 case COUNTRY_CODE_FRANCE:
202 case COUNTRY_CODE_MKK:
203 case COUNTRY_CODE_MKK1:
204 case COUNTRY_CODE_ISRAEL:
205 case COUNTRY_CODE_TELEC:
206 case COUNTRY_CODE_MIC:
209 ieee->bGlobalDomain = false;
210 //acturally 8225 & 8256 rf chip only support B,G,24N mode
211 if ((priv->rf_chip == RF_8225) || (priv->rf_chip == RF_8256))
218 RT_TRACE(COMP_ERR, "unknown rf chip, can't set channel map in function:%s()\n", __FUNCTION__);
220 if (ChannelPlan[channel_plan].Len != 0){
221 // Clear old channel map
222 memset(GET_DOT11D_INFO(ieee)->channel_map, 0, sizeof(GET_DOT11D_INFO(ieee)->channel_map));
223 // Set new channel map
224 for (i=0;i<ChannelPlan[channel_plan].Len;i++)
226 if (ChannelPlan[channel_plan].Channel[i] < min_chan || ChannelPlan[channel_plan].Channel[i] > max_chan)
228 GET_DOT11D_INFO(ieee)->channel_map[ChannelPlan[channel_plan].Channel[i]] = 1;
233 case COUNTRY_CODE_GLOBAL_DOMAIN:
235 GET_DOT11D_INFO(ieee)->bEnabled = 0;//this flag enabled to follow 11d country IE setting, otherwise, it shall follow global domain settings.
237 ieee->bGlobalDomain = true;
247 #define eqMacAddr(a,b) ( ((a)[0]==(b)[0] && (a)[1]==(b)[1] && (a)[2]==(b)[2] && (a)[3]==(b)[3] && (a)[4]==(b)[4] && (a)[5]==(b)[5]) ? 1:0 )
249 #define rx_hal_is_cck_rate(_pdrvinfo)\
250 (_pdrvinfo->RxRate == DESC90_RATE1M ||\
251 _pdrvinfo->RxRate == DESC90_RATE2M ||\
252 _pdrvinfo->RxRate == DESC90_RATE5_5M ||\
253 _pdrvinfo->RxRate == DESC90_RATE11M) &&\
257 void CamResetAllEntry(struct net_device *dev)
260 //2004/02/11 In static WEP, OID_ADD_KEY or OID_ADD_WEP are set before STA associate to AP.
261 // However, ResetKey is called on OID_802_11_INFRASTRUCTURE_MODE and MlmeAssociateRequest
262 // In this condition, Cam can not be reset because upper layer will not set this static key again.
263 //if(Adapter->EncAlgorithm == WEP_Encryption)
266 //DbgPrint("========================================\n");
267 //DbgPrint(" Call ResetAllEntry \n");
268 //DbgPrint("========================================\n\n");
269 ulcommand |= BIT31|BIT30;
270 write_nic_dword(dev, RWCAM, ulcommand);
275 void write_cam(struct net_device *dev, u8 addr, u32 data)
277 write_nic_dword(dev, WCAMI, data);
278 write_nic_dword(dev, RWCAM, BIT31|BIT16|(addr&0xff) );
281 u32 read_cam(struct net_device *dev, u8 addr)
283 write_nic_dword(dev, RWCAM, 0x80000000|(addr&0xff) );
284 return read_nic_dword(dev, 0xa8);
287 void write_nic_byte_E(struct net_device *dev, int indx, u8 data)
290 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
291 struct usb_device *udev = priv->udev;
293 status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
294 RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
295 indx|0xfe00, 0, &data, 1, HZ / 2);
299 printk("write_nic_byte_E TimeOut! status:%d\n", status);
303 u8 read_nic_byte_E(struct net_device *dev, int indx)
307 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
308 struct usb_device *udev = priv->udev;
310 status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
311 RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
312 indx|0xfe00, 0, &data, 1, HZ / 2);
316 printk("read_nic_byte_E TimeOut! status:%d\n", status);
321 //as 92U has extend page from 4 to 16, so modify functions below.
322 void write_nic_byte(struct net_device *dev, int indx, u8 data)
326 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
327 struct usb_device *udev = priv->udev;
329 status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
330 RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
331 (indx&0xff)|0xff00, (indx>>8)&0x0f, &data, 1, HZ / 2);
335 printk("write_nic_byte TimeOut! status:%d\n", status);
342 void write_nic_word(struct net_device *dev, int indx, u16 data)
347 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
348 struct usb_device *udev = priv->udev;
350 status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
351 RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
352 (indx&0xff)|0xff00, (indx>>8)&0x0f, &data, 2, HZ / 2);
356 printk("write_nic_word TimeOut! status:%d\n", status);
362 void write_nic_dword(struct net_device *dev, int indx, u32 data)
367 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
368 struct usb_device *udev = priv->udev;
370 status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
371 RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
372 (indx&0xff)|0xff00, (indx>>8)&0x0f, &data, 4, HZ / 2);
377 printk("write_nic_dword TimeOut! status:%d\n", status);
384 u8 read_nic_byte(struct net_device *dev, int indx)
388 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
389 struct usb_device *udev = priv->udev;
391 status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
392 RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
393 (indx&0xff)|0xff00, (indx>>8)&0x0f, &data, 1, HZ / 2);
397 printk("read_nic_byte TimeOut! status:%d\n", status);
405 u16 read_nic_word(struct net_device *dev, int indx)
409 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
410 struct usb_device *udev = priv->udev;
412 status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
413 RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
414 (indx&0xff)|0xff00, (indx>>8)&0x0f, &data, 2, HZ / 2);
418 printk("read_nic_word TimeOut! status:%d\n", status);
425 u16 read_nic_word_E(struct net_device *dev, int indx)
429 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
430 struct usb_device *udev = priv->udev;
432 status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
433 RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
434 indx|0xfe00, 0, &data, 2, HZ / 2);
438 printk("read_nic_word TimeOut! status:%d\n", status);
445 u32 read_nic_dword(struct net_device *dev, int indx)
451 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
452 struct usb_device *udev = priv->udev;
454 status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
455 RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
456 (indx&0xff)|0xff00, (indx>>8)&0x0f, &data, 4, HZ / 2);
458 // printk(KERN_WARNING "read size of data = %d\, date = %d\n", result, data);
463 printk("read_nic_dword TimeOut! status:%d\n", status);
472 //u8 read_phy_cck(struct net_device *dev, u8 adr);
473 //u8 read_phy_ofdm(struct net_device *dev, u8 adr);
474 /* this might still called in what was the PHY rtl8185/rtl8192 common code
475 * plans are to possibilty turn it again in one common code...
477 inline void force_pci_posting(struct net_device *dev)
482 static struct net_device_stats *rtl8192_stats(struct net_device *dev);
483 void rtl8192_commit(struct net_device *dev);
484 //void rtl8192_restart(struct net_device *dev);
485 void rtl8192_restart(struct work_struct *work);
486 //void rtl8192_rq_tx_ack(struct work_struct *work);
488 void watch_dog_timer_callback(unsigned long data);
490 /****************************************************************************
491 -----------------------------PROCFS STUFF-------------------------
492 *****************************************************************************/
494 static struct proc_dir_entry *rtl8192_proc = NULL;
498 static int proc_get_stats_ap(char *page, char **start,
499 off_t offset, int count,
500 int *eof, void *data)
502 struct net_device *dev = data;
503 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
504 struct ieee80211_device *ieee = priv->ieee80211;
505 struct ieee80211_network *target;
509 list_for_each_entry(target, &ieee->network_list, list) {
511 len += snprintf(page + len, count - len,
512 "%s ", target->ssid);
514 if(target->wpa_ie_len>0 || target->rsn_ie_len>0){
515 len += snprintf(page + len, count - len,
519 len += snprintf(page + len, count - len,
529 static int proc_get_registers(char *page, char **start,
530 off_t offset, int count,
531 int *eof, void *data)
533 struct net_device *dev = data;
534 // struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
541 /* This dump the current register page */
542 len += snprintf(page + len, count - len,
543 "\n####################page 0##################\n ");
547 //printk( "\nD: %2x> ", n);
548 len += snprintf(page + len, count - len,
551 for(i=0;i<16 && n<=max;i++,n++)
552 len += snprintf(page + len, count - len,
553 "%2x ",read_nic_byte(dev,0x000|n));
555 // printk("%2x ",read_nic_byte(dev,n));
557 len += snprintf(page + len, count - len,
558 "\n####################page 1##################\n ");
561 //printk( "\nD: %2x> ", n);
562 len += snprintf(page + len, count - len,
565 for(i=0;i<16 && n<=max;i++,n++)
566 len += snprintf(page + len, count - len,
567 "%2x ",read_nic_byte(dev,0x100|n));
569 // printk("%2x ",read_nic_byte(dev,n));
571 len += snprintf(page + len, count - len,
572 "\n####################page 3##################\n ");
575 //printk( "\nD: %2x> ", n);
576 len += snprintf(page + len, count - len,
579 for(i=0;i<16 && n<=max;i++,n++)
580 len += snprintf(page + len, count - len,
581 "%2x ",read_nic_byte(dev,0x300|n));
583 // printk("%2x ",read_nic_byte(dev,n));
587 len += snprintf(page + len, count - len,"\n");
597 static int proc_get_stats_tx(char *page, char **start,
598 off_t offset, int count,
599 int *eof, void *data)
601 struct net_device *dev = data;
602 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
606 len += snprintf(page + len, count - len,
607 "TX VI priority ok int: %lu\n"
608 "TX VI priority error int: %lu\n"
609 "TX VO priority ok int: %lu\n"
610 "TX VO priority error int: %lu\n"
611 "TX BE priority ok int: %lu\n"
612 "TX BE priority error int: %lu\n"
613 "TX BK priority ok int: %lu\n"
614 "TX BK priority error int: %lu\n"
615 "TX MANAGE priority ok int: %lu\n"
616 "TX MANAGE priority error int: %lu\n"
617 "TX BEACON priority ok int: %lu\n"
618 "TX BEACON priority error int: %lu\n"
619 // "TX high priority ok int: %lu\n"
620 // "TX high priority failed error int: %lu\n"
621 "TX queue resume: %lu\n"
622 "TX queue stopped?: %d\n"
623 "TX fifo overflow: %lu\n"
624 // "TX beacon: %lu\n"
629 // "TX HW queue: %d\n"
630 "TX VI dropped: %lu\n"
631 "TX VO dropped: %lu\n"
632 "TX BE dropped: %lu\n"
633 "TX BK dropped: %lu\n"
634 "TX total data packets %lu\n",
635 // "TX beacon aborted: %lu\n",
636 priv->stats.txviokint,
638 priv->stats.txvookint,
640 priv->stats.txbeokint,
642 priv->stats.txbkokint,
644 priv->stats.txmanageokint,
645 priv->stats.txmanageerr,
646 priv->stats.txbeaconokint,
647 priv->stats.txbeaconerr,
648 // priv->stats.txhpokint,
649 // priv->stats.txhperr,
650 priv->stats.txresumed,
651 netif_queue_stopped(dev),
652 priv->stats.txoverflow,
653 // priv->stats.txbeacon,
654 atomic_read(&(priv->tx_pending[VI_PRIORITY])),
655 atomic_read(&(priv->tx_pending[VO_PRIORITY])),
656 atomic_read(&(priv->tx_pending[BE_PRIORITY])),
657 atomic_read(&(priv->tx_pending[BK_PRIORITY])),
658 // read_nic_byte(dev, TXFIFOCOUNT),
659 priv->stats.txvidrop,
660 priv->stats.txvodrop,
661 priv->stats.txbedrop,
662 priv->stats.txbkdrop,
663 priv->stats.txdatapkt
664 // priv->stats.txbeaconerr
673 static int proc_get_stats_rx(char *page, char **start,
674 off_t offset, int count,
675 int *eof, void *data)
677 struct net_device *dev = data;
678 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
682 len += snprintf(page + len, count - len,
684 "RX urb status error: %lu\n"
685 "RX invalid urb error: %lu\n",
686 priv->stats.rxoktotal,
687 priv->stats.rxstaterr,
688 priv->stats.rxurberr);
693 void rtl8192_proc_module_init(void)
695 RT_TRACE(COMP_INIT, "Initializing proc filesystem");
696 rtl8192_proc=create_proc_entry(RTL819xU_MODULE_NAME, S_IFDIR, init_net.proc_net);
700 void rtl8192_proc_module_remove(void)
702 remove_proc_entry(RTL819xU_MODULE_NAME, init_net.proc_net);
706 void rtl8192_proc_remove_one(struct net_device *dev)
708 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
712 // remove_proc_entry("stats-hw", priv->dir_dev);
713 remove_proc_entry("stats-tx", priv->dir_dev);
714 remove_proc_entry("stats-rx", priv->dir_dev);
715 // remove_proc_entry("stats-ieee", priv->dir_dev);
716 remove_proc_entry("stats-ap", priv->dir_dev);
717 remove_proc_entry("registers", priv->dir_dev);
718 // remove_proc_entry("cck-registers",priv->dir_dev);
719 // remove_proc_entry("ofdm-registers",priv->dir_dev);
720 //remove_proc_entry(dev->name, rtl8192_proc);
721 remove_proc_entry("wlan0", rtl8192_proc);
722 priv->dir_dev = NULL;
727 void rtl8192_proc_init_one(struct net_device *dev)
729 struct proc_dir_entry *e;
730 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
731 priv->dir_dev = create_proc_entry(dev->name,
732 S_IFDIR | S_IRUGO | S_IXUGO,
734 if (!priv->dir_dev) {
735 RT_TRACE(COMP_ERR, "Unable to initialize /proc/net/rtl8192/%s\n",
739 e = create_proc_read_entry("stats-rx", S_IFREG | S_IRUGO,
740 priv->dir_dev, proc_get_stats_rx, dev);
743 RT_TRACE(COMP_ERR,"Unable to initialize "
744 "/proc/net/rtl8192/%s/stats-rx\n",
749 e = create_proc_read_entry("stats-tx", S_IFREG | S_IRUGO,
750 priv->dir_dev, proc_get_stats_tx, dev);
753 RT_TRACE(COMP_ERR, "Unable to initialize "
754 "/proc/net/rtl8192/%s/stats-tx\n",
758 e = create_proc_read_entry("stats-ap", S_IFREG | S_IRUGO,
759 priv->dir_dev, proc_get_stats_ap, dev);
762 RT_TRACE(COMP_ERR, "Unable to initialize "
763 "/proc/net/rtl8192/%s/stats-ap\n",
767 e = create_proc_read_entry("registers", S_IFREG | S_IRUGO,
768 priv->dir_dev, proc_get_registers, dev);
770 RT_TRACE(COMP_ERR, "Unable to initialize "
771 "/proc/net/rtl8192/%s/registers\n",
775 /****************************************************************************
776 -----------------------------MISC STUFF-------------------------
777 *****************************************************************************/
779 /* this is only for debugging */
780 void print_buffer(u32 *buffer, int len)
783 u8 *buf =(u8*)buffer;
785 printk("ASCII BUFFER DUMP (len: %x):\n",len);
790 printk("\nBINARY BUFFER DUMP (len: %x):\n",len);
798 //short check_nic_enough_desc(struct net_device *dev, priority_t priority)
799 short check_nic_enough_desc(struct net_device *dev,int queue_index)
801 struct r8192_priv *priv = ieee80211_priv(dev);
802 int used = atomic_read(&priv->tx_pending[queue_index]);
804 return (used < MAX_TX_URB);
807 void tx_timeout(struct net_device *dev)
809 struct r8192_priv *priv = ieee80211_priv(dev);
810 //rtl8192_commit(dev);
812 schedule_work(&priv->reset_wq);
813 //DMESG("TXTIMEOUT");
817 /* this is only for debug */
818 void dump_eprom(struct net_device *dev)
822 RT_TRACE(COMP_EPROM, "EEPROM addr %x : %x", i, eprom_read(dev,i));
825 /* this is only for debug */
826 void rtl8192_dump_reg(struct net_device *dev)
832 RT_TRACE(COMP_PHY, "Dumping NIC register map");
836 printk( "\nD: %2x> ", n);
837 for(i=0;i<16 && n<=max;i++,n++)
838 printk("%2x ",read_nic_byte(dev,n));
843 /****************************************************************************
844 ------------------------------HW STUFF---------------------------
845 *****************************************************************************/
848 void rtl8192_set_mode(struct net_device *dev,int mode)
851 ecmd=read_nic_byte(dev, EPROM_CMD);
852 ecmd=ecmd &~ EPROM_CMD_OPERATING_MODE_MASK;
853 ecmd=ecmd | (mode<<EPROM_CMD_OPERATING_MODE_SHIFT);
854 ecmd=ecmd &~ (1<<EPROM_CS_SHIFT);
855 ecmd=ecmd &~ (1<<EPROM_CK_SHIFT);
856 write_nic_byte(dev, EPROM_CMD, ecmd);
860 void rtl8192_update_msr(struct net_device *dev)
862 struct r8192_priv *priv = ieee80211_priv(dev);
865 msr = read_nic_byte(dev, MSR);
866 msr &= ~ MSR_LINK_MASK;
868 /* do not change in link_state != WLAN_LINK_ASSOCIATED.
869 * msr must be updated if the state is ASSOCIATING.
870 * this is intentional and make sense for ad-hoc and
871 * master (see the create BSS/IBSS func)
873 if (priv->ieee80211->state == IEEE80211_LINKED){
875 if (priv->ieee80211->iw_mode == IW_MODE_INFRA)
876 msr |= (MSR_LINK_MANAGED<<MSR_LINK_SHIFT);
877 else if (priv->ieee80211->iw_mode == IW_MODE_ADHOC)
878 msr |= (MSR_LINK_ADHOC<<MSR_LINK_SHIFT);
879 else if (priv->ieee80211->iw_mode == IW_MODE_MASTER)
880 msr |= (MSR_LINK_MASTER<<MSR_LINK_SHIFT);
883 msr |= (MSR_LINK_NONE<<MSR_LINK_SHIFT);
885 write_nic_byte(dev, MSR, msr);
888 void rtl8192_set_chan(struct net_device *dev,short ch)
890 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
892 RT_TRACE(COMP_CH, "=====>%s()====ch:%d\n", __FUNCTION__, ch);
895 /* this hack should avoid frame TX during channel setting*/
898 // tx = read_nic_dword(dev,TX_CONF);
899 // tx &= ~TX_LOOPBACK_MASK;
902 // write_nic_dword(dev,TX_CONF, tx |( TX_LOOPBACK_MAC<<TX_LOOPBACK_SHIFT));
904 //need to implement rf set channel here WB
906 if (priv->rf_set_chan)
907 priv->rf_set_chan(dev,priv->chan);
909 // write_nic_dword(dev,TX_CONF,tx | (TX_LOOPBACK_NONE<<TX_LOOPBACK_SHIFT));
913 static void rtl8192_rx_isr(struct urb *urb);
914 //static void rtl8192_rx_isr(struct urb *rx_urb);
916 u32 get_rxpacket_shiftbytes_819xusb(struct ieee80211_rx_stats *pstats)
919 #ifdef USB_RX_AGGREGATION_SUPPORT
920 if (pstats->bisrxaggrsubframe)
921 return (sizeof(rx_desc_819x_usb) + pstats->RxDrvInfoSize
922 + pstats->RxBufShift + 8);
925 return (sizeof(rx_desc_819x_usb) + pstats->RxDrvInfoSize
926 + pstats->RxBufShift);
929 static int rtl8192_rx_initiate(struct net_device*dev)
931 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
934 struct rtl8192_rx_info *info;
936 /* nomal packet rx procedure */
937 while (skb_queue_len(&priv->rx_queue) < MAX_RX_URB) {
938 skb = __dev_alloc_skb(RX_URB_SIZE, GFP_KERNEL);
941 entry = usb_alloc_urb(0, GFP_KERNEL);
946 // printk("nomal packet IN request!\n");
947 usb_fill_bulk_urb(entry, priv->udev,
948 usb_rcvbulkpipe(priv->udev, 3), skb_tail_pointer(skb),
949 RX_URB_SIZE, rtl8192_rx_isr, skb);
950 info = (struct rtl8192_rx_info *) skb->cb;
953 info->out_pipe = 3; //denote rx normal packet queue
954 skb_queue_tail(&priv->rx_queue, skb);
955 usb_submit_urb(entry, GFP_KERNEL);
958 /* command packet rx procedure */
959 while (skb_queue_len(&priv->rx_queue) < MAX_RX_URB + 3) {
960 // printk("command packet IN request!\n");
961 skb = __dev_alloc_skb(RX_URB_SIZE ,GFP_KERNEL);
964 entry = usb_alloc_urb(0, GFP_KERNEL);
969 usb_fill_bulk_urb(entry, priv->udev,
970 usb_rcvbulkpipe(priv->udev, 9), skb_tail_pointer(skb),
971 RX_URB_SIZE, rtl8192_rx_isr, skb);
972 info = (struct rtl8192_rx_info *) skb->cb;
975 info->out_pipe = 9; //denote rx cmd packet queue
976 skb_queue_tail(&priv->rx_queue, skb);
977 usb_submit_urb(entry, GFP_KERNEL);
983 void rtl8192_set_rxconf(struct net_device *dev)
985 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
988 rxconf=read_nic_dword(dev,RCR);
989 rxconf = rxconf &~ MAC_FILTER_MASK;
990 rxconf = rxconf | RCR_AMF;
991 rxconf = rxconf | RCR_ADF;
992 rxconf = rxconf | RCR_AB;
993 rxconf = rxconf | RCR_AM;
994 //rxconf = rxconf | RCR_ACF;
996 if (dev->flags & IFF_PROMISC) {DMESG ("NIC in promisc mode");}
998 if(priv->ieee80211->iw_mode == IW_MODE_MONITOR || \
999 dev->flags & IFF_PROMISC){
1000 rxconf = rxconf | RCR_AAP;
1001 } /*else if(priv->ieee80211->iw_mode == IW_MODE_MASTER){
1002 rxconf = rxconf | (1<<ACCEPT_ALLMAC_FRAME_SHIFT);
1003 rxconf = rxconf | (1<<RX_CHECK_BSSID_SHIFT);
1005 rxconf = rxconf | RCR_APM;
1006 rxconf = rxconf | RCR_CBSSID;
1010 if(priv->ieee80211->iw_mode == IW_MODE_MONITOR){
1011 rxconf = rxconf | RCR_AICV;
1012 rxconf = rxconf | RCR_APWRMGT;
1015 if( priv->crcmon == 1 && priv->ieee80211->iw_mode == IW_MODE_MONITOR)
1016 rxconf = rxconf | RCR_ACRC32;
1019 rxconf = rxconf &~ RX_FIFO_THRESHOLD_MASK;
1020 rxconf = rxconf | (RX_FIFO_THRESHOLD_NONE<<RX_FIFO_THRESHOLD_SHIFT);
1021 rxconf = rxconf &~ MAX_RX_DMA_MASK;
1022 rxconf = rxconf | ((u32)7<<RCR_MXDMA_OFFSET);
1024 // rxconf = rxconf | (1<<RX_AUTORESETPHY_SHIFT);
1025 rxconf = rxconf | RCR_ONLYERLPKT;
1027 // rxconf = rxconf &~ RCR_CS_MASK;
1028 // rxconf = rxconf | (1<<RCR_CS_SHIFT);
1030 write_nic_dword(dev, RCR, rxconf);
1033 DMESG("rxconf: %x %x",rxconf ,read_nic_dword(dev,RCR));
1036 //wait to be removed
1037 void rtl8192_rx_enable(struct net_device *dev)
1041 //struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1043 rtl8192_rx_initiate(dev);
1045 // rtl8192_set_rxconf(dev);
1049 void rtl8192_tx_enable(struct net_device *dev)
1055 void rtl8192_rtx_disable(struct net_device *dev)
1058 struct r8192_priv *priv = ieee80211_priv(dev);
1059 struct sk_buff *skb;
1060 struct rtl8192_rx_info *info;
1062 cmd=read_nic_byte(dev,CMDR);
1063 write_nic_byte(dev, CMDR, cmd &~ \
1065 force_pci_posting(dev);
1068 while ((skb = __skb_dequeue(&priv->rx_queue))) {
1069 info = (struct rtl8192_rx_info *) skb->cb;
1073 usb_kill_urb(info->urb);
1077 if (skb_queue_len(&priv->skb_queue)) {
1078 printk(KERN_WARNING "skb_queue not empty\n");
1081 skb_queue_purge(&priv->skb_queue);
1086 int alloc_tx_beacon_desc_ring(struct net_device *dev, int count)
1091 inline u16 ieeerate2rtlrate(int rate)
1123 static u16 rtl_rate[] = {10,20,55,110,60,90,120,180,240,360,480,540};
1124 inline u16 rtl8192_rate2rate(short rate)
1126 if (rate >11) return 0;
1127 return rtl_rate[rate];
1131 /* The protype of rx_isr has changed since one verion of Linux Kernel */
1132 static void rtl8192_rx_isr(struct urb *urb)
1134 struct sk_buff *skb = (struct sk_buff *) urb->context;
1135 struct rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
1136 struct net_device *dev = info->dev;
1137 struct r8192_priv *priv = ieee80211_priv(dev);
1138 int out_pipe = info->out_pipe;
1142 if (unlikely(urb->status)) {
1144 priv->stats.rxstaterr++;
1145 priv->ieee80211->stats.rx_errors++;
1147 // printk("%s():rx status err\n",__FUNCTION__);
1150 skb_unlink(skb, &priv->rx_queue);
1151 skb_put(skb, urb->actual_length);
1153 skb_queue_tail(&priv->skb_queue, skb);
1154 tasklet_schedule(&priv->irq_rx_tasklet);
1156 skb = dev_alloc_skb(RX_URB_SIZE);
1157 if (unlikely(!skb)) {
1159 printk("%s():can,t alloc skb\n",__FUNCTION__);
1160 /* TODO check rx queue length and refill *somewhere* */
1164 usb_fill_bulk_urb(urb, priv->udev,
1165 usb_rcvbulkpipe(priv->udev, out_pipe), skb_tail_pointer(skb),
1166 RX_URB_SIZE, rtl8192_rx_isr, skb);
1168 info = (struct rtl8192_rx_info *) skb->cb;
1171 info->out_pipe = out_pipe;
1173 urb->transfer_buffer = skb_tail_pointer(skb);
1175 skb_queue_tail(&priv->rx_queue, skb);
1176 err = usb_submit_urb(urb, GFP_ATOMIC);
1177 if(err && err != EPERM)
1178 printk("can not submit rxurb, err is %x,URB status is %x\n",err,urb->status);
1182 rtl819xusb_rx_command_packet(
1183 struct net_device *dev,
1184 struct ieee80211_rx_stats *pstats
1189 //RT_TRACE(COMP_RECV, DBG_TRACE, ("---> RxCommandPacketHandle819xUsb()\n"));
1191 status = cmpk_message_handle_rx(dev, pstats);
1194 DMESG("rxcommandpackethandle819xusb: It is a command packet\n");
1198 //RT_TRACE(COMP_RECV, DBG_TRACE, ("RxCommandPacketHandle819xUsb: It is not a command packet\n"));
1201 //RT_TRACE(COMP_RECV, DBG_TRACE, ("<--- RxCommandPacketHandle819xUsb()\n"));
1206 void rtl8192_data_hard_stop(struct net_device *dev)
1212 void rtl8192_data_hard_resume(struct net_device *dev)
1217 /* this function TX data frames when the ieee80211 stack requires this.
1218 * It checks also if we need to stop the ieee tx queue, eventually do it
1220 void rtl8192_hard_data_xmit(struct sk_buff *skb, struct net_device *dev, int rate)
1222 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1224 unsigned long flags;
1225 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1226 u8 queue_index = tcb_desc->queue_index;
1228 /* shall not be referred by command packet */
1229 assert(queue_index != TXCMD_QUEUE);
1231 spin_lock_irqsave(&priv->tx_lock,flags);
1233 memcpy((unsigned char *)(skb->cb),&dev,sizeof(dev));
1234 // tcb_desc->RATRIndex = 7;
1235 // tcb_desc->bTxDisableRateFallBack = 1;
1236 // tcb_desc->bTxUseDriverAssingedRate = 1;
1237 tcb_desc->bTxEnableFwCalcDur = 1;
1238 skb_push(skb, priv->ieee80211->tx_headroom);
1239 ret = rtl8192_tx(dev, skb);
1241 //priv->ieee80211->stats.tx_bytes+=(skb->len - priv->ieee80211->tx_headroom);
1242 //priv->ieee80211->stats.tx_packets++;
1244 spin_unlock_irqrestore(&priv->tx_lock,flags);
1250 /* This is a rough attempt to TX a frame
1251 * This is called by the ieee 80211 stack to TX management frames.
1252 * If the ring is full packet are dropped (for data frame the queue
1253 * is stopped before this can happen).
1255 int rtl8192_hard_start_xmit(struct sk_buff *skb,struct net_device *dev)
1257 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1259 unsigned long flags;
1260 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1261 u8 queue_index = tcb_desc->queue_index;
1264 spin_lock_irqsave(&priv->tx_lock,flags);
1266 memcpy((unsigned char *)(skb->cb),&dev,sizeof(dev));
1267 if(queue_index == TXCMD_QUEUE) {
1268 skb_push(skb, USB_HWDESC_HEADER_LEN);
1269 rtl819xU_tx_cmd(dev, skb);
1271 spin_unlock_irqrestore(&priv->tx_lock,flags);
1274 skb_push(skb, priv->ieee80211->tx_headroom);
1275 ret = rtl8192_tx(dev, skb);
1278 spin_unlock_irqrestore(&priv->tx_lock,flags);
1284 void rtl8192_try_wake_queue(struct net_device *dev, int pri);
1286 #ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
1287 u16 DrvAggr_PaddingAdd(struct net_device *dev, struct sk_buff *skb)
1289 u16 PaddingNum = 256 - ((skb->len + TX_PACKET_DRVAGGR_SUBFRAME_SHIFT_BYTES) % 256);
1290 return (PaddingNum&0xff);
1293 u8 MRateToHwRate8190Pci(u8 rate);
1294 u8 QueryIsShort(u8 TxHT, u8 TxRate, cb_desc *tcb_desc);
1295 u8 MapHwQueueToFirmwareQueue(u8 QueueID);
1296 struct sk_buff *DrvAggr_Aggregation(struct net_device *dev, struct ieee80211_drv_agg_txb *pSendList)
1298 struct ieee80211_device *ieee = netdev_priv(dev);
1299 struct r8192_priv *priv = ieee80211_priv(dev);
1300 cb_desc *tcb_desc = NULL;
1303 struct sk_buff *skb;
1304 struct sk_buff *agg_skb;
1305 tx_desc_819x_usb_aggr_subframe *tx_agg_desc = NULL;
1306 tx_fwinfo_819x_usb *tx_fwinfo = NULL;
1309 // Local variable initialization.
1311 /* first skb initialization */
1312 skb = pSendList->tx_agg_frames[0];
1313 TotalLength = skb->len;
1315 /* Get the total aggregation length including the padding space and
1318 for(i = 1; i < pSendList->nr_drv_agg_frames; i++) {
1319 TotalLength += DrvAggr_PaddingAdd(dev, skb);
1320 skb = pSendList->tx_agg_frames[i];
1321 TotalLength += (skb->len + TX_PACKET_DRVAGGR_SUBFRAME_SHIFT_BYTES);
1324 /* allocate skb to contain the aggregated packets */
1325 agg_skb = dev_alloc_skb(TotalLength + ieee->tx_headroom);
1326 memset(agg_skb->data, 0, agg_skb->len);
1327 skb_reserve(agg_skb, ieee->tx_headroom);
1329 // RT_DEBUG_DATA(COMP_SEND, skb->cb, sizeof(skb->cb));
1330 /* reserve info for first subframe Tx descriptor to be set in the tx function */
1331 skb = pSendList->tx_agg_frames[0];
1332 tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1333 tcb_desc->drv_agg_enable = 1;
1334 tcb_desc->pkt_size = skb->len;
1335 tcb_desc->DrvAggrNum = pSendList->nr_drv_agg_frames;
1336 printk("DrvAggNum = %d\n", tcb_desc->DrvAggrNum);
1337 // RT_DEBUG_DATA(COMP_SEND, skb->cb, sizeof(skb->cb));
1338 // printk("========>skb->data ======> \n");
1339 // RT_DEBUG_DATA(COMP_SEND, skb->data, skb->len);
1340 memcpy(agg_skb->cb, skb->cb, sizeof(skb->cb));
1341 memcpy(skb_put(agg_skb,skb->len),skb->data,skb->len);
1343 for(i = 1; i < pSendList->nr_drv_agg_frames; i++) {
1344 /* push the next sub frame to be 256 byte aline */
1345 skb_put(agg_skb,DrvAggr_PaddingAdd(dev,skb));
1347 /* Subframe drv Tx descriptor and firmware info setting */
1348 skb = pSendList->tx_agg_frames[i];
1349 tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1350 tx_agg_desc = (tx_desc_819x_usb_aggr_subframe *)agg_skb->tail;
1351 tx_fwinfo = (tx_fwinfo_819x_usb *)(agg_skb->tail + sizeof(tx_desc_819x_usb_aggr_subframe));
1353 memset(tx_fwinfo,0,sizeof(tx_fwinfo_819x_usb));
1355 tx_fwinfo->TxHT = (tcb_desc->data_rate&0x80)?1:0;
1356 tx_fwinfo->TxRate = MRateToHwRate8190Pci(tcb_desc->data_rate);
1357 tx_fwinfo->EnableCPUDur = tcb_desc->bTxEnableFwCalcDur;
1358 tx_fwinfo->Short = QueryIsShort(tx_fwinfo->TxHT, tx_fwinfo->TxRate, tcb_desc);
1359 if(tcb_desc->bAMPDUEnable) {//AMPDU enabled
1360 tx_fwinfo->AllowAggregation = 1;
1362 tx_fwinfo->RxMF = tcb_desc->ampdu_factor;
1363 tx_fwinfo->RxAMD = tcb_desc->ampdu_density&0x07;//ampdudensity
1365 tx_fwinfo->AllowAggregation = 0;
1367 tx_fwinfo->RxMF = 0;
1368 tx_fwinfo->RxAMD = 0;
1371 /* Protection mode related */
1372 tx_fwinfo->RtsEnable = (tcb_desc->bRTSEnable)?1:0;
1373 tx_fwinfo->CtsEnable = (tcb_desc->bCTSEnable)?1:0;
1374 tx_fwinfo->RtsSTBC = (tcb_desc->bRTSSTBC)?1:0;
1375 tx_fwinfo->RtsHT = (tcb_desc->rts_rate&0x80)?1:0;
1376 tx_fwinfo->RtsRate = MRateToHwRate8190Pci((u8)tcb_desc->rts_rate);
1377 tx_fwinfo->RtsSubcarrier = (tx_fwinfo->RtsHT==0)?(tcb_desc->RTSSC):0;
1378 tx_fwinfo->RtsBandwidth = (tx_fwinfo->RtsHT==1)?((tcb_desc->bRTSBW)?1:0):0;
1379 tx_fwinfo->RtsShort = (tx_fwinfo->RtsHT==0)?(tcb_desc->bRTSUseShortPreamble?1:0):\
1380 (tcb_desc->bRTSUseShortGI?1:0);
1382 /* Set Bandwidth and sub-channel settings. */
1383 if(priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20_40)
1385 if(tcb_desc->bPacketBW) {
1386 tx_fwinfo->TxBandwidth = 1;
1387 tx_fwinfo->TxSubCarrier = 0; //By SD3's Jerry suggestion, use duplicated mode
1389 tx_fwinfo->TxBandwidth = 0;
1390 tx_fwinfo->TxSubCarrier = priv->nCur40MhzPrimeSC;
1393 tx_fwinfo->TxBandwidth = 0;
1394 tx_fwinfo->TxSubCarrier = 0;
1397 /* Fill Tx descriptor */
1398 memset(tx_agg_desc, 0, sizeof(tx_desc_819x_usb_aggr_subframe));
1400 //tx_agg_desc->LINIP = 0;
1401 //tx_agg_desc->CmdInit = 1;
1402 tx_agg_desc->Offset = sizeof(tx_fwinfo_819x_usb) + 8;
1403 /* already raw data, need not to substract header length */
1404 tx_agg_desc->PktSize = skb->len & 0xffff;
1407 tx_agg_desc->SecCAMID= 0;
1408 tx_agg_desc->RATid = tcb_desc->RATRIndex;
1411 tx_agg_desc->NoEnc = 1;
1413 tx_agg_desc->SecType = 0x0;
1415 if (tcb_desc->bHwSec) {
1416 switch (priv->ieee80211->pairwise_key_type)
1418 case KEY_TYPE_WEP40:
1419 case KEY_TYPE_WEP104:
1420 tx_agg_desc->SecType = 0x1;
1421 tx_agg_desc->NoEnc = 0;
1424 tx_agg_desc->SecType = 0x2;
1425 tx_agg_desc->NoEnc = 0;
1428 tx_agg_desc->SecType = 0x3;
1429 tx_agg_desc->NoEnc = 0;
1432 tx_agg_desc->SecType = 0x0;
1433 tx_agg_desc->NoEnc = 1;
1438 tx_agg_desc->QueueSelect = MapHwQueueToFirmwareQueue(tcb_desc->queue_index);
1439 tx_agg_desc->TxFWInfoSize = sizeof(tx_fwinfo_819x_usb);
1441 tx_agg_desc->DISFB = tcb_desc->bTxDisableRateFallBack;
1442 tx_agg_desc->USERATE = tcb_desc->bTxUseDriverAssingedRate;
1444 tx_agg_desc->OWN = 1;
1447 /* According windows driver, it seems that there no need to fill this field */
1448 //tx_agg_desc->TxBufferSize= (u32)(skb->len - USB_HWDESC_HEADER_LEN);
1450 /* to fill next packet */
1451 skb_put(agg_skb,TX_PACKET_DRVAGGR_SUBFRAME_SHIFT_BYTES);
1452 memcpy(skb_put(agg_skb,skb->len),skb->data,skb->len);
1455 for(i = 0; i < pSendList->nr_drv_agg_frames; i++) {
1456 dev_kfree_skb_any(pSendList->tx_agg_frames[i]);
1463 This function return a list of PTCB which is proper to be aggregate with the input TCB.
1464 If no proper TCB is found to do aggregation, SendList will only contain the input TCB.
1466 u8 DrvAggr_GetAggregatibleList(struct net_device *dev, struct sk_buff *skb,
1467 struct ieee80211_drv_agg_txb *pSendList)
1469 struct ieee80211_device *ieee = netdev_priv(dev);
1470 PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
1471 u16 nMaxAggrNum = pHTInfo->UsbTxAggrNum;
1472 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1473 u8 QueueID = tcb_desc->queue_index;
1476 pSendList->tx_agg_frames[pSendList->nr_drv_agg_frames++] = skb;
1477 if(pSendList->nr_drv_agg_frames >= nMaxAggrNum) {
1481 } while((skb = skb_dequeue(&ieee->skb_drv_aggQ[QueueID])));
1483 RT_TRACE(COMP_AMSDU, "DrvAggr_GetAggregatibleList, nAggrTcbNum = %d \n", pSendList->nr_drv_agg_frames);
1484 return pSendList->nr_drv_agg_frames;
1488 static void rtl8192_tx_isr(struct urb *tx_urb)
1490 struct sk_buff *skb = (struct sk_buff*)tx_urb->context;
1491 struct net_device *dev = NULL;
1492 struct r8192_priv *priv = NULL;
1493 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1494 u8 queue_index = tcb_desc->queue_index;
1495 // bool bToSend0Byte;
1496 // u16 BufLen = skb->len;
1498 memcpy(&dev,(struct net_device*)(skb->cb),sizeof(struct net_device*));
1499 priv = ieee80211_priv(dev);
1501 if(tcb_desc->queue_index != TXCMD_QUEUE) {
1502 if(tx_urb->status == 0) {
1503 dev->trans_start = jiffies;
1504 // As act as station mode, destion shall be unicast address.
1505 //priv->ieee80211->stats.tx_bytes+=(skb->len - priv->ieee80211->tx_headroom);
1506 //priv->ieee80211->stats.tx_packets++;
1507 priv->stats.txoktotal++;
1508 priv->ieee80211->LinkDetectInfo.NumTxOkInPeriod++;
1509 priv->stats.txbytesunicast += (skb->len - priv->ieee80211->tx_headroom);
1511 priv->ieee80211->stats.tx_errors++;
1512 //priv->stats.txmanageerr++;
1517 /* free skb and tx_urb */
1519 dev_kfree_skb_any(skb);
1520 usb_free_urb(tx_urb);
1521 atomic_dec(&priv->tx_pending[queue_index]);
1526 // Handle HW Beacon:
1527 // We had transfer our beacon frame to host controler at this moment.
1531 // Handling the wait queue of command packets.
1532 // For Tx command packets, we must not do TCB fragment because it is not handled right now.
1533 // We must cut the packets to match the size of TX_CMD_PKT before we send it.
1536 /* Handle MPDU in wait queue. */
1537 if(queue_index != BEACON_QUEUE) {
1538 /* Don't send data frame during scanning.*/
1539 if((skb_queue_len(&priv->ieee80211->skb_waitQ[queue_index]) != 0)&&\
1540 (!(priv->ieee80211->queue_stop))) {
1541 if(NULL != (skb = skb_dequeue(&(priv->ieee80211->skb_waitQ[queue_index]))))
1542 priv->ieee80211->softmac_hard_start_xmit(skb, dev);
1544 return; //modified by david to avoid further processing AMSDU
1546 #ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
1547 else if ((skb_queue_len(&priv->ieee80211->skb_drv_aggQ[queue_index])!= 0)&&\
1548 (!(priv->ieee80211->queue_stop))) {
1549 // Tx Driver Aggregation process
1550 /* The driver will aggregation the packets according to the following stets
1551 * 1. check whether there's tx irq available, for it's a completion return
1552 * function, it should contain enough tx irq;
1553 * 2. check pakcet type;
1554 * 3. intialize sendlist, check whether the to-be send packet no greater than 1
1555 * 4. aggregation the packets, and fill firmware info and tx desc to it, etc.
1556 * 5. check whehter the packet could be sent, otherwise just insert to wait head
1558 skb = skb_dequeue(&priv->ieee80211->skb_drv_aggQ[queue_index]);
1559 if(!check_nic_enough_desc(dev, queue_index)) {
1560 skb_queue_head(&(priv->ieee80211->skb_drv_aggQ[queue_index]), skb);
1567 u8* pHeader = skb->data;
1569 if(IsMgntQosData(pHeader) ||
1570 IsMgntQData_Ack(pHeader) ||
1571 IsMgntQData_Poll(pHeader) ||
1572 IsMgntQData_Poll_Ack(pHeader)
1576 struct ieee80211_drv_agg_txb SendList;
1578 memset(&SendList, 0, sizeof(struct ieee80211_drv_agg_txb));
1579 if(DrvAggr_GetAggregatibleList(dev, skb, &SendList) > 1) {
1580 skb = DrvAggr_Aggregation(dev, &SendList);
1584 priv->ieee80211->softmac_hard_start_xmit(skb, dev);
1593 void rtl8192_beacon_stop(struct net_device *dev)
1596 struct r8192_priv *priv = ieee80211_priv(dev);
1598 msr = read_nic_byte(dev, MSR);
1599 msrm = msr & MSR_LINK_MASK;
1600 msr2 = msr & ~MSR_LINK_MASK;
1602 if(NIC_8192U == priv->card_8192) {
1603 usb_kill_urb(priv->rx_urb[MAX_RX_URB]);
1605 if ((msrm == (MSR_LINK_ADHOC<<MSR_LINK_SHIFT) ||
1606 (msrm == (MSR_LINK_MASTER<<MSR_LINK_SHIFT)))){
1607 write_nic_byte(dev, MSR, msr2 | MSR_LINK_NONE);
1608 write_nic_byte(dev, MSR, msr);
1612 void rtl8192_config_rate(struct net_device* dev, u16* rate_config)
1614 struct r8192_priv *priv = ieee80211_priv(dev);
1615 struct ieee80211_network *net;
1616 u8 i=0, basic_rate = 0;
1617 net = & priv->ieee80211->current_network;
1619 for (i=0; i<net->rates_len; i++)
1621 basic_rate = net->rates[i]&0x7f;
1624 case MGN_1M: *rate_config |= RRSR_1M; break;
1625 case MGN_2M: *rate_config |= RRSR_2M; break;
1626 case MGN_5_5M: *rate_config |= RRSR_5_5M; break;
1627 case MGN_11M: *rate_config |= RRSR_11M; break;
1628 case MGN_6M: *rate_config |= RRSR_6M; break;
1629 case MGN_9M: *rate_config |= RRSR_9M; break;
1630 case MGN_12M: *rate_config |= RRSR_12M; break;
1631 case MGN_18M: *rate_config |= RRSR_18M; break;
1632 case MGN_24M: *rate_config |= RRSR_24M; break;
1633 case MGN_36M: *rate_config |= RRSR_36M; break;
1634 case MGN_48M: *rate_config |= RRSR_48M; break;
1635 case MGN_54M: *rate_config |= RRSR_54M; break;
1638 for (i=0; i<net->rates_ex_len; i++)
1640 basic_rate = net->rates_ex[i]&0x7f;
1643 case MGN_1M: *rate_config |= RRSR_1M; break;
1644 case MGN_2M: *rate_config |= RRSR_2M; break;
1645 case MGN_5_5M: *rate_config |= RRSR_5_5M; break;
1646 case MGN_11M: *rate_config |= RRSR_11M; break;
1647 case MGN_6M: *rate_config |= RRSR_6M; break;
1648 case MGN_9M: *rate_config |= RRSR_9M; break;
1649 case MGN_12M: *rate_config |= RRSR_12M; break;
1650 case MGN_18M: *rate_config |= RRSR_18M; break;
1651 case MGN_24M: *rate_config |= RRSR_24M; break;
1652 case MGN_36M: *rate_config |= RRSR_36M; break;
1653 case MGN_48M: *rate_config |= RRSR_48M; break;
1654 case MGN_54M: *rate_config |= RRSR_54M; break;
1660 #define SHORT_SLOT_TIME 9
1661 #define NON_SHORT_SLOT_TIME 20
1663 void rtl8192_update_cap(struct net_device* dev, u16 cap)
1666 struct r8192_priv *priv = ieee80211_priv(dev);
1667 struct ieee80211_network *net = &priv->ieee80211->current_network;
1668 priv->short_preamble = cap & WLAN_CAPABILITY_SHORT_PREAMBLE;
1669 tmp = priv->basic_rate;
1670 if (priv->short_preamble)
1671 tmp |= BRSR_AckShortPmb;
1672 write_nic_dword(dev, RRSR, tmp);
1674 if (net->mode & (IEEE_G|IEEE_N_24G))
1677 if ((cap & WLAN_CAPABILITY_SHORT_SLOT)&&(!priv->ieee80211->pHTInfo->bCurrentRT2RTLongSlotTime))
1679 slot_time = SHORT_SLOT_TIME;
1681 else //long slot time
1682 slot_time = NON_SHORT_SLOT_TIME;
1683 priv->slot_time = slot_time;
1684 write_nic_byte(dev, SLOT_TIME, slot_time);
1688 void rtl8192_net_update(struct net_device *dev)
1691 struct r8192_priv *priv = ieee80211_priv(dev);
1692 struct ieee80211_network *net;
1693 u16 BcnTimeCfg = 0, BcnCW = 6, BcnIFS = 0xf;
1694 u16 rate_config = 0;
1695 net = & priv->ieee80211->current_network;
1697 rtl8192_config_rate(dev, &rate_config);
1698 priv->basic_rate = rate_config &= 0x15f;
1700 write_nic_dword(dev,BSSIDR,((u32*)net->bssid)[0]);
1701 write_nic_word(dev,BSSIDR+4,((u16*)net->bssid)[2]);
1702 //for(i=0;i<ETH_ALEN;i++)
1703 // write_nic_byte(dev,BSSID+i,net->bssid[i]);
1705 rtl8192_update_msr(dev);
1706 // rtl8192_update_cap(dev, net->capability);
1707 if (priv->ieee80211->iw_mode == IW_MODE_ADHOC)
1709 write_nic_word(dev, ATIMWND, 2);
1710 write_nic_word(dev, BCN_DMATIME, 1023);
1711 write_nic_word(dev, BCN_INTERVAL, net->beacon_interval);
1712 // write_nic_word(dev, BcnIntTime, 100);
1713 write_nic_word(dev, BCN_DRV_EARLY_INT, 1);
1714 write_nic_byte(dev, BCN_ERR_THRESH, 100);
1715 BcnTimeCfg |= (BcnCW<<BCN_TCFG_CW_SHIFT);
1716 // TODO: BcnIFS may required to be changed on ASIC
1717 BcnTimeCfg |= BcnIFS<<BCN_TCFG_IFS;
1719 write_nic_word(dev, BCN_TCFG, BcnTimeCfg);
1726 //temporary hw beacon is not used any more.
1727 //open it when necessary
1728 void rtl819xusb_beacon_tx(struct net_device *dev,u16 tx_rate)
1732 inline u8 rtl8192_IsWirelessBMode(u16 rate)
1734 if( ((rate <= 110) && (rate != 60) && (rate != 90)) || (rate == 220) )
1739 u16 N_DBPSOfRate(u16 DataRate);
1744 u8 bManagementFrame,
1752 if( rtl8192_IsWirelessBMode(DataRate) )
1754 if( bManagementFrame || !bShortPreamble || DataRate == 10 )
1756 FrameTime = (u16)(144+48+(FrameLength*8/(DataRate/10)));
1760 FrameTime = (u16)(72+24+(FrameLength*8/(DataRate/10)));
1762 if( ( FrameLength*8 % (DataRate/10) ) != 0 ) //Get the Ceilling
1764 } else { //802.11g DSSS-OFDM PLCP length field calculation.
1765 N_DBPS = N_DBPSOfRate(DataRate);
1766 Ceiling = (16 + 8*FrameLength + 6) / N_DBPS
1767 + (((16 + 8*FrameLength + 6) % N_DBPS) ? 1 : 0);
1768 FrameTime = (u16)(16 + 4 + 4*Ceiling + 6);
1773 u16 N_DBPSOfRate(u16 DataRate)
1818 void rtl819xU_cmd_isr(struct urb *tx_cmd_urb, struct pt_regs *regs)
1820 usb_free_urb(tx_cmd_urb);
1823 unsigned int txqueue2outpipe(struct r8192_priv* priv,unsigned int tx_queue) {
1827 RT_TRACE(COMP_ERR,"%s():Unknown queue ID!!!\n",__FUNCTION__);
1830 return priv->txqueue_to_outpipemap[tx_queue];
1833 short rtl819xU_tx_cmd(struct net_device *dev, struct sk_buff *skb)
1835 struct r8192_priv *priv = ieee80211_priv(dev);
1840 unsigned int idx_pipe;
1841 tx_desc_cmd_819x_usb *pdesc = (tx_desc_cmd_819x_usb *)skb->data;
1842 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1843 u8 queue_index = tcb_desc->queue_index;
1845 //printk("\n %s::queue_index = %d\n",__FUNCTION__, queue_index);
1846 atomic_inc(&priv->tx_pending[queue_index]);
1847 tx_urb = usb_alloc_urb(0,GFP_ATOMIC);
1853 memset(pdesc, 0, USB_HWDESC_HEADER_LEN);
1854 /* Tx descriptor ought to be set according to the skb->cb */
1855 pdesc->FirstSeg = 1;//bFirstSeg;
1856 pdesc->LastSeg = 1;//bLastSeg;
1857 pdesc->CmdInit = tcb_desc->bCmdOrInit;
1858 pdesc->TxBufferSize = tcb_desc->txbuf_size;
1860 pdesc->LINIP = tcb_desc->bLastIniPkt;
1862 //----------------------------------------------------------------------------
1863 // Fill up USB_OUT_CONTEXT.
1864 //----------------------------------------------------------------------------
1865 // Get index to out pipe from specified QueueID.
1866 #ifndef USE_ONE_PIPE
1867 idx_pipe = txqueue2outpipe(priv,queue_index);
1871 #ifdef JOHN_DUMP_TXDESC
1873 printk("<Tx descriptor>--rate %x---",rate);
1874 for (i = 0; i < 8; i++)
1875 printk("%8x ", tx[i]);
1878 usb_fill_bulk_urb(tx_urb,priv->udev, usb_sndbulkpipe(priv->udev,idx_pipe), \
1879 skb->data, skb->len, rtl8192_tx_isr, skb);
1881 status = usb_submit_urb(tx_urb, GFP_ATOMIC);
1886 DMESGE("Error TX CMD URB, error %d",
1893 * Mapping Software/Hardware descriptor queue id to "Queue Select Field"
1894 * in TxFwInfo data structure
1895 * 2006.10.30 by Emily
1897 * \param QUEUEID Software Queue
1899 u8 MapHwQueueToFirmwareQueue(u8 QueueID)
1901 u8 QueueSelect = 0x0; //defualt set to
1905 QueueSelect = QSLT_BE; //or QSelect = pTcb->priority;
1909 QueueSelect = QSLT_BK; //or QSelect = pTcb->priority;
1913 QueueSelect = QSLT_VO; //or QSelect = pTcb->priority;
1917 QueueSelect = QSLT_VI; //or QSelect = pTcb->priority;
1920 QueueSelect = QSLT_MGNT;
1924 QueueSelect = QSLT_BEACON;
1927 // TODO: 2006.10.30 mark other queue selection until we verify it is OK
1928 // TODO: Remove Assertions
1929 //#if (RTL819X_FPGA_VER & RTL819X_FPGA_GUANGAN_070502)
1931 QueueSelect = QSLT_CMD;
1935 QueueSelect = QSLT_HIGH;
1939 RT_TRACE(COMP_ERR, "TransmitTCB(): Impossible Queue Selection: %d \n", QueueID);
1945 u8 MRateToHwRate8190Pci(u8 rate)
1947 u8 ret = DESC90_RATE1M;
1950 case MGN_1M: ret = DESC90_RATE1M; break;
1951 case MGN_2M: ret = DESC90_RATE2M; break;
1952 case MGN_5_5M: ret = DESC90_RATE5_5M; break;
1953 case MGN_11M: ret = DESC90_RATE11M; break;
1954 case MGN_6M: ret = DESC90_RATE6M; break;
1955 case MGN_9M: ret = DESC90_RATE9M; break;
1956 case MGN_12M: ret = DESC90_RATE12M; break;
1957 case MGN_18M: ret = DESC90_RATE18M; break;
1958 case MGN_24M: ret = DESC90_RATE24M; break;
1959 case MGN_36M: ret = DESC90_RATE36M; break;
1960 case MGN_48M: ret = DESC90_RATE48M; break;
1961 case MGN_54M: ret = DESC90_RATE54M; break;
1963 // HT rate since here
1964 case MGN_MCS0: ret = DESC90_RATEMCS0; break;
1965 case MGN_MCS1: ret = DESC90_RATEMCS1; break;
1966 case MGN_MCS2: ret = DESC90_RATEMCS2; break;
1967 case MGN_MCS3: ret = DESC90_RATEMCS3; break;
1968 case MGN_MCS4: ret = DESC90_RATEMCS4; break;
1969 case MGN_MCS5: ret = DESC90_RATEMCS5; break;
1970 case MGN_MCS6: ret = DESC90_RATEMCS6; break;
1971 case MGN_MCS7: ret = DESC90_RATEMCS7; break;
1972 case MGN_MCS8: ret = DESC90_RATEMCS8; break;
1973 case MGN_MCS9: ret = DESC90_RATEMCS9; break;
1974 case MGN_MCS10: ret = DESC90_RATEMCS10; break;
1975 case MGN_MCS11: ret = DESC90_RATEMCS11; break;
1976 case MGN_MCS12: ret = DESC90_RATEMCS12; break;
1977 case MGN_MCS13: ret = DESC90_RATEMCS13; break;
1978 case MGN_MCS14: ret = DESC90_RATEMCS14; break;
1979 case MGN_MCS15: ret = DESC90_RATEMCS15; break;
1980 case (0x80|0x20): ret = DESC90_RATEMCS32; break;
1988 u8 QueryIsShort(u8 TxHT, u8 TxRate, cb_desc *tcb_desc)
1992 tmp_Short = (TxHT==1)?((tcb_desc->bUseShortGI)?1:0):((tcb_desc->bUseShortPreamble)?1:0);
1994 if(TxHT==1 && TxRate != DESC90_RATEMCS15)
2000 static void tx_zero_isr(struct urb *tx_urb)
2006 * The tx procedure is just as following,
2007 * skb->cb will contain all the following information,
2008 * priority, morefrag, rate, &dev.
2010 short rtl8192_tx(struct net_device *dev, struct sk_buff* skb)
2012 struct r8192_priv *priv = ieee80211_priv(dev);
2013 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
2014 tx_desc_819x_usb *tx_desc = (tx_desc_819x_usb *)skb->data;
2015 tx_fwinfo_819x_usb *tx_fwinfo = (tx_fwinfo_819x_usb *)(skb->data + USB_HWDESC_HEADER_LEN);
2016 struct usb_device *udev = priv->udev;
2019 struct urb *tx_urb = NULL, *tx_urb_zero = NULL;
2021 unsigned int idx_pipe;
2022 // RT_DEBUG_DATA(COMP_SEND, tcb_desc, sizeof(cb_desc));
2023 // printk("=============> %s\n", __FUNCTION__);
2024 pend = atomic_read(&priv->tx_pending[tcb_desc->queue_index]);
2025 /* we are locked here so the two atomic_read and inc are executed
2026 * without interleaves
2027 * !!! For debug purpose
2029 if( pend > MAX_TX_URB){
2030 printk("To discard skb packet!\n");
2031 dev_kfree_skb_any(skb);
2035 tx_urb = usb_alloc_urb(0,GFP_ATOMIC);
2037 dev_kfree_skb_any(skb);
2041 /* Fill Tx firmware info */
2042 memset(tx_fwinfo,0,sizeof(tx_fwinfo_819x_usb));
2044 tx_fwinfo->TxHT = (tcb_desc->data_rate&0x80)?1:0;
2045 tx_fwinfo->TxRate = MRateToHwRate8190Pci(tcb_desc->data_rate);
2046 tx_fwinfo->EnableCPUDur = tcb_desc->bTxEnableFwCalcDur;
2047 tx_fwinfo->Short = QueryIsShort(tx_fwinfo->TxHT, tx_fwinfo->TxRate, tcb_desc);
2048 if(tcb_desc->bAMPDUEnable) {//AMPDU enabled
2049 tx_fwinfo->AllowAggregation = 1;
2051 tx_fwinfo->RxMF = tcb_desc->ampdu_factor;
2052 tx_fwinfo->RxAMD = tcb_desc->ampdu_density&0x07;//ampdudensity
2054 tx_fwinfo->AllowAggregation = 0;
2056 tx_fwinfo->RxMF = 0;
2057 tx_fwinfo->RxAMD = 0;
2060 /* Protection mode related */
2061 tx_fwinfo->RtsEnable = (tcb_desc->bRTSEnable)?1:0;
2062 tx_fwinfo->CtsEnable = (tcb_desc->bCTSEnable)?1:0;
2063 tx_fwinfo->RtsSTBC = (tcb_desc->bRTSSTBC)?1:0;
2064 tx_fwinfo->RtsHT = (tcb_desc->rts_rate&0x80)?1:0;
2065 tx_fwinfo->RtsRate = MRateToHwRate8190Pci((u8)tcb_desc->rts_rate);
2066 tx_fwinfo->RtsSubcarrier = (tx_fwinfo->RtsHT==0)?(tcb_desc->RTSSC):0;
2067 tx_fwinfo->RtsBandwidth = (tx_fwinfo->RtsHT==1)?((tcb_desc->bRTSBW)?1:0):0;
2068 tx_fwinfo->RtsShort = (tx_fwinfo->RtsHT==0)?(tcb_desc->bRTSUseShortPreamble?1:0):\
2069 (tcb_desc->bRTSUseShortGI?1:0);
2071 /* Set Bandwidth and sub-channel settings. */
2072 if(priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20_40)
2074 if(tcb_desc->bPacketBW) {
2075 tx_fwinfo->TxBandwidth = 1;
2076 tx_fwinfo->TxSubCarrier = 0; //By SD3's Jerry suggestion, use duplicated mode
2078 tx_fwinfo->TxBandwidth = 0;
2079 tx_fwinfo->TxSubCarrier = priv->nCur40MhzPrimeSC;
2082 tx_fwinfo->TxBandwidth = 0;
2083 tx_fwinfo->TxSubCarrier = 0;
2086 #ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
2087 if (tcb_desc->drv_agg_enable)
2089 tx_fwinfo->Tx_INFO_RSVD = (tcb_desc->DrvAggrNum & 0x1f) << 1;
2092 /* Fill Tx descriptor */
2093 memset(tx_desc, 0, sizeof(tx_desc_819x_usb));
2096 tx_desc->CmdInit = 1;
2097 tx_desc->Offset = sizeof(tx_fwinfo_819x_usb) + 8;
2099 #ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
2100 if (tcb_desc->drv_agg_enable) {
2101 tx_desc->PktSize = tcb_desc->pkt_size;
2105 tx_desc->PktSize = (skb->len - TX_PACKET_SHIFT_BYTES) & 0xffff;
2109 tx_desc->SecCAMID= 0;
2110 tx_desc->RATid = tcb_desc->RATRIndex;
2115 tx_desc->SecType = 0x0;
2116 if (tcb_desc->bHwSec)
2118 switch (priv->ieee80211->pairwise_key_type)
2120 case KEY_TYPE_WEP40:
2121 case KEY_TYPE_WEP104:
2122 tx_desc->SecType = 0x1;
2126 tx_desc->SecType = 0x2;
2130 tx_desc->SecType = 0x3;
2134 tx_desc->SecType = 0x0;
2140 tx_desc->QueueSelect = MapHwQueueToFirmwareQueue(tcb_desc->queue_index);
2141 tx_desc->TxFWInfoSize = sizeof(tx_fwinfo_819x_usb);
2143 tx_desc->DISFB = tcb_desc->bTxDisableRateFallBack;
2144 tx_desc->USERATE = tcb_desc->bTxUseDriverAssingedRate;
2146 /* Fill fields that are required to be initialized in all of the descriptors */
2148 tx_desc->FirstSeg = 1;
2149 tx_desc->LastSeg = 1;
2152 #ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
2153 if (tcb_desc->drv_agg_enable) {
2154 tx_desc->TxBufferSize = tcb_desc->pkt_size + sizeof(tx_fwinfo_819x_usb);
2159 tx_desc->TxBufferSize = (u32)(skb->len - USB_HWDESC_HEADER_LEN);
2161 /* Get index to out pipe from specified QueueID */
2162 #ifndef USE_ONE_PIPE
2163 idx_pipe = txqueue2outpipe(priv,tcb_desc->queue_index);
2168 //RT_DEBUG_DATA(COMP_SEND,tx_fwinfo,sizeof(tx_fwinfo_819x_usb));
2169 //RT_DEBUG_DATA(COMP_SEND,tx_desc,sizeof(tx_desc_819x_usb));
2171 /* To submit bulk urb */
2172 usb_fill_bulk_urb(tx_urb,udev,
2173 usb_sndbulkpipe(udev,idx_pipe), skb->data,
2174 skb->len, rtl8192_tx_isr, skb);
2176 status = usb_submit_urb(tx_urb, GFP_ATOMIC);
2178 //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
2179 bool bSend0Byte = false;
2181 if(udev->speed == USB_SPEED_HIGH)
2183 if (skb->len > 0 && skb->len % 512 == 0)
2188 if (skb->len > 0 && skb->len % 64 == 0)
2193 tx_urb_zero = usb_alloc_urb(0,GFP_ATOMIC);
2195 RT_TRACE(COMP_ERR, "can't alloc urb for zero byte\n");
2198 usb_fill_bulk_urb(tx_urb_zero,udev,
2199 usb_sndbulkpipe(udev,idx_pipe), &zero,
2200 0, tx_zero_isr, dev);
2201 status = usb_submit_urb(tx_urb_zero, GFP_ATOMIC);
2203 RT_TRACE(COMP_ERR, "Error TX URB for zero byte %d, error %d", atomic_read(&priv->tx_pending[tcb_desc->queue_index]), status);
2207 dev->trans_start = jiffies;
2208 atomic_inc(&priv->tx_pending[tcb_desc->queue_index]);
2211 RT_TRACE(COMP_ERR, "Error TX URB %d, error %d", atomic_read(&priv->tx_pending[tcb_desc->queue_index]),
2217 short rtl8192_usb_initendpoints(struct net_device *dev)
2219 struct r8192_priv *priv = ieee80211_priv(dev);
2221 priv->rx_urb = kmalloc(sizeof(struct urb *) * (MAX_RX_URB+1),
2224 #ifndef JACKSON_NEW_RX
2225 for(i=0;i<(MAX_RX_URB+1);i++){
2227 priv->rx_urb[i] = usb_alloc_urb(0,GFP_KERNEL);
2229 priv->rx_urb[i]->transfer_buffer = kmalloc(RX_URB_SIZE, GFP_KERNEL);
2231 priv->rx_urb[i]->transfer_buffer_length = RX_URB_SIZE;
2235 #ifdef THOMAS_BEACON
2238 void *oldaddr, *newaddr;
2240 priv->rx_urb[16] = usb_alloc_urb(0, GFP_KERNEL);
2241 priv->oldaddr = kmalloc(16, GFP_KERNEL);
2242 oldaddr = priv->oldaddr;
2243 align = ((long)oldaddr) & 3;
2245 newaddr = oldaddr + 4 - align;
2246 priv->rx_urb[16]->transfer_buffer_length = 16 - 4 + align;
2249 priv->rx_urb[16]->transfer_buffer_length = 16;
2251 priv->rx_urb[16]->transfer_buffer = newaddr;
2255 memset(priv->rx_urb, 0, sizeof(struct urb*) * MAX_RX_URB);
2256 priv->pp_rxskb = kcalloc(MAX_RX_URB, sizeof(struct sk_buff *),
2258 if (priv->pp_rxskb == NULL)
2265 if (priv->pp_rxskb) {
2266 kfree(priv->pp_rxskb);
2269 kfree(priv->rx_urb);
2272 priv->pp_rxskb = NULL;
2273 priv->rx_urb = NULL;
2275 DMESGE("Endpoint Alloc Failure");
2281 printk("End of initendpoints\n");
2285 #ifdef THOMAS_BEACON
2286 void rtl8192_usb_deleteendpoints(struct net_device *dev)
2289 struct r8192_priv *priv = ieee80211_priv(dev);
2292 for(i=0;i<(MAX_RX_URB+1);i++){
2293 usb_kill_urb(priv->rx_urb[i]);
2294 usb_free_urb(priv->rx_urb[i]);
2296 kfree(priv->rx_urb);
2297 priv->rx_urb = NULL;
2300 kfree(priv->oldaddr);
2301 priv->oldaddr = NULL;
2303 if (priv->pp_rxskb) {
2304 kfree(priv->pp_rxskb);
2309 void rtl8192_usb_deleteendpoints(struct net_device *dev)
2312 struct r8192_priv *priv = ieee80211_priv(dev);
2314 #ifndef JACKSON_NEW_RX
2317 for(i=0;i<(MAX_RX_URB+1);i++){
2318 usb_kill_urb(priv->rx_urb[i]);
2319 kfree(priv->rx_urb[i]->transfer_buffer);
2320 usb_free_urb(priv->rx_urb[i]);
2322 kfree(priv->rx_urb);
2323 priv->rx_urb = NULL;
2328 kfree(priv->rx_urb);
2329 priv->rx_urb = NULL;
2332 kfree(priv->oldaddr);
2333 priv->oldaddr = NULL;
2335 if (priv->pp_rxskb) {
2336 kfree(priv->pp_rxskb);
2345 extern void rtl8192_update_ratr_table(struct net_device* dev);
2346 void rtl8192_link_change(struct net_device *dev)
2350 struct r8192_priv *priv = ieee80211_priv(dev);
2351 struct ieee80211_device* ieee = priv->ieee80211;
2352 //write_nic_word(dev, BCN_INTR_ITV, net->beacon_interval);
2353 if (ieee->state == IEEE80211_LINKED)
2355 rtl8192_net_update(dev);
2356 rtl8192_update_ratr_table(dev);
2357 //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
2358 if ((KEY_TYPE_WEP40 == ieee->pairwise_key_type) || (KEY_TYPE_WEP104 == ieee->pairwise_key_type))
2359 EnableHWSecurityConfig8192(dev);
2361 /*update timing params*/
2362 // RT_TRACE(COMP_CH, "========>%s(), chan:%d\n", __FUNCTION__, priv->chan);
2363 // rtl8192_set_chan(dev, priv->chan);
2364 if (ieee->iw_mode == IW_MODE_INFRA || ieee->iw_mode == IW_MODE_ADHOC)
2367 reg = read_nic_dword(dev, RCR);
2368 if (priv->ieee80211->state == IEEE80211_LINKED)
2369 priv->ReceiveConfig = reg |= RCR_CBSSID;
2371 priv->ReceiveConfig = reg &= ~RCR_CBSSID;
2372 write_nic_dword(dev, RCR, reg);
2375 // rtl8192_set_rxconf(dev);
2378 static struct ieee80211_qos_parameters def_qos_parameters = {
2379 {3,3,3,3},/* cw_min */
2380 {7,7,7,7},/* cw_max */
2381 {2,2,2,2},/* aifs */
2382 {0,0,0,0},/* flags */
2383 {0,0,0,0} /* tx_op_limit */
2387 void rtl8192_update_beacon(struct work_struct * work)
2389 struct r8192_priv *priv = container_of(work, struct r8192_priv, update_beacon_wq.work);
2390 struct net_device *dev = priv->ieee80211->dev;
2391 struct ieee80211_device* ieee = priv->ieee80211;
2392 struct ieee80211_network* net = &ieee->current_network;
2394 if (ieee->pHTInfo->bCurrentHTSupport)
2395 HTUpdateSelfAndPeerSetting(ieee, net);
2396 ieee->pHTInfo->bCurrentRT2RTLongSlotTime = net->bssht.bdRT2RTLongSlotTime;
2397 rtl8192_update_cap(dev, net->capability);
2400 * background support to run QoS activate functionality
2402 int WDCAPARA_ADD[] = {EDCAPARA_BE,EDCAPARA_BK,EDCAPARA_VI,EDCAPARA_VO};
2403 void rtl8192_qos_activate(struct work_struct * work)
2405 struct r8192_priv *priv = container_of(work, struct r8192_priv, qos_activate);
2406 struct net_device *dev = priv->ieee80211->dev;
2407 struct ieee80211_qos_parameters *qos_parameters = &priv->ieee80211->current_network.qos_data.parameters;
2408 u8 mode = priv->ieee80211->current_network.mode;
2409 //u32 size = sizeof(struct ieee80211_qos_parameters);
2417 mutex_lock(&priv->mutex);
2418 if(priv->ieee80211->state != IEEE80211_LINKED)
2420 RT_TRACE(COMP_QOS,"qos active process with associate response received\n");
2421 /* It better set slot time at first */
2422 /* For we just support b/g mode at present, let the slot time at 9/20 selection */
2423 /* update the ac parameter to related registers */
2424 for(i = 0; i < QOS_QUEUE_NUM; i++) {
2425 //Mode G/A: slotTimeTimer = 9; Mode B: 20
2426 u1bAIFS = qos_parameters->aifs[i] * ((mode&(IEEE_G|IEEE_N_24G)) ?9:20) + aSifsTime;
2427 u4bAcParam = ((((u32)(qos_parameters->tx_op_limit[i]))<< AC_PARAM_TXOP_LIMIT_OFFSET)|
2428 (((u32)(qos_parameters->cw_max[i]))<< AC_PARAM_ECW_MAX_OFFSET)|
2429 (((u32)(qos_parameters->cw_min[i]))<< AC_PARAM_ECW_MIN_OFFSET)|
2430 ((u32)u1bAIFS << AC_PARAM_AIFS_OFFSET));
2432 write_nic_dword(dev, WDCAPARA_ADD[i], u4bAcParam);
2433 //write_nic_dword(dev, WDCAPARA_ADD[i], 0x005e4332);
2437 mutex_unlock(&priv->mutex);
2440 static int rtl8192_qos_handle_probe_response(struct r8192_priv *priv,
2442 struct ieee80211_network *network)
2445 u32 size = sizeof(struct ieee80211_qos_parameters);
2447 if(priv->ieee80211->state !=IEEE80211_LINKED)
2450 if ((priv->ieee80211->iw_mode != IW_MODE_INFRA))
2453 if (network->flags & NETWORK_HAS_QOS_MASK) {
2454 if (active_network &&
2455 (network->flags & NETWORK_HAS_QOS_PARAMETERS))
2456 network->qos_data.active = network->qos_data.supported;
2458 if ((network->qos_data.active == 1) && (active_network == 1) &&
2459 (network->flags & NETWORK_HAS_QOS_PARAMETERS) &&
2460 (network->qos_data.old_param_count !=
2461 network->qos_data.param_count)) {
2462 network->qos_data.old_param_count =
2463 network->qos_data.param_count;
2464 queue_work(priv->priv_wq, &priv->qos_activate);
2465 RT_TRACE (COMP_QOS, "QoS parameters change call "
2469 memcpy(&priv->ieee80211->current_network.qos_data.parameters,\
2470 &def_qos_parameters, size);
2472 if ((network->qos_data.active == 1) && (active_network == 1)) {
2473 queue_work(priv->priv_wq, &priv->qos_activate);
2474 RT_TRACE(COMP_QOS, "QoS was disabled call qos_activate \n");
2476 network->qos_data.active = 0;
2477 network->qos_data.supported = 0;
2483 /* handle manage frame frame beacon and probe response */
2484 static int rtl8192_handle_beacon(struct net_device * dev,
2485 struct ieee80211_beacon * beacon,
2486 struct ieee80211_network * network)
2488 struct r8192_priv *priv = ieee80211_priv(dev);
2490 rtl8192_qos_handle_probe_response(priv,1,network);
2491 queue_delayed_work(priv->priv_wq, &priv->update_beacon_wq, 0);
2497 * handling the beaconing responses. if we get different QoS setting
2498 * off the network from the associated setting, adjust the QoS
2501 static int rtl8192_qos_association_resp(struct r8192_priv *priv,
2502 struct ieee80211_network *network)
2505 unsigned long flags;
2506 u32 size = sizeof(struct ieee80211_qos_parameters);
2507 int set_qos_param = 0;
2509 if ((priv == NULL) || (network == NULL))
2512 if(priv->ieee80211->state !=IEEE80211_LINKED)
2515 if ((priv->ieee80211->iw_mode != IW_MODE_INFRA))
2518 spin_lock_irqsave(&priv->ieee80211->lock, flags);
2519 if(network->flags & NETWORK_HAS_QOS_PARAMETERS) {
2520 memcpy(&priv->ieee80211->current_network.qos_data.parameters,\
2521 &network->qos_data.parameters,\
2522 sizeof(struct ieee80211_qos_parameters));
2523 priv->ieee80211->current_network.qos_data.active = 1;
2526 /* update qos parameter for current network */
2527 priv->ieee80211->current_network.qos_data.old_param_count = \
2528 priv->ieee80211->current_network.qos_data.param_count;
2529 priv->ieee80211->current_network.qos_data.param_count = \
2530 network->qos_data.param_count;
2533 memcpy(&priv->ieee80211->current_network.qos_data.parameters,\
2534 &def_qos_parameters, size);
2535 priv->ieee80211->current_network.qos_data.active = 0;
2536 priv->ieee80211->current_network.qos_data.supported = 0;
2540 spin_unlock_irqrestore(&priv->ieee80211->lock, flags);
2542 RT_TRACE(COMP_QOS, "%s: network->flags = %d,%d\n",__FUNCTION__,network->flags ,priv->ieee80211->current_network.qos_data.active);
2543 if (set_qos_param == 1)
2544 queue_work(priv->priv_wq, &priv->qos_activate);
2551 static int rtl8192_handle_assoc_response(struct net_device *dev,
2552 struct ieee80211_assoc_response_frame *resp,
2553 struct ieee80211_network *network)
2555 struct r8192_priv *priv = ieee80211_priv(dev);
2556 rtl8192_qos_association_resp(priv, network);
2561 void rtl8192_update_ratr_table(struct net_device* dev)
2562 // POCTET_STRING posLegacyRate,
2564 // PRT_WLAN_STA pEntry)
2566 struct r8192_priv* priv = ieee80211_priv(dev);
2567 struct ieee80211_device* ieee = priv->ieee80211;
2568 u8* pMcsRate = ieee->dot11HTOperationalRateSet;
2569 //struct ieee80211_network *net = &ieee->current_network;
2572 rtl8192_config_rate(dev, (u16*)(&ratr_value));
2573 ratr_value |= (*(u16*)(pMcsRate)) << 12;
2574 // switch (net->mode)
2578 ratr_value &= 0x00000FF0;
2581 ratr_value &= 0x0000000F;
2584 ratr_value &= 0x00000FF7;
2588 if (ieee->pHTInfo->PeerMimoPs == 0) //MIMO_PS_STATIC
2589 ratr_value &= 0x0007F007;
2591 if (priv->rf_type == RF_1T2R)
2592 ratr_value &= 0x000FF007;
2594 ratr_value &= 0x0F81F007;
2600 ratr_value &= 0x0FFFFFFF;
2601 if(ieee->pHTInfo->bCurTxBW40MHz && ieee->pHTInfo->bCurShortGI40MHz){
2602 ratr_value |= 0x80000000;
2603 }else if(!ieee->pHTInfo->bCurTxBW40MHz && ieee->pHTInfo->bCurShortGI20MHz){
2604 ratr_value |= 0x80000000;
2606 write_nic_dword(dev, RATR0+rate_index*4, ratr_value);
2607 write_nic_byte(dev, UFWP, 1);
2610 static u8 ccmp_ie[4] = {0x00,0x50,0xf2,0x04};
2611 static u8 ccmp_rsn_ie[4] = {0x00, 0x0f, 0xac, 0x04};
2612 bool GetNmodeSupportBySecCfg8192(struct net_device*dev)
2614 struct r8192_priv* priv = ieee80211_priv(dev);
2615 struct ieee80211_device* ieee = priv->ieee80211;
2616 struct ieee80211_network * network = &ieee->current_network;
2617 int wpa_ie_len= ieee->wpa_ie_len;
2618 struct ieee80211_crypt_data* crypt;
2621 crypt = ieee->crypt[ieee->tx_keyidx];
2622 //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
2623 encrypt = (network->capability & WLAN_CAPABILITY_PRIVACY) || (ieee->host_encrypt && crypt && crypt->ops && (0 == strcmp(crypt->ops->name,"WEP")));
2626 if(encrypt && (wpa_ie_len == 0)) {
2627 /* wep encryption, no N mode setting */
2629 // } else if((wpa_ie_len != 0)&&(memcmp(&(ieee->wpa_ie[14]),ccmp_ie,4))) {
2630 } else if((wpa_ie_len != 0)) {
2631 /* parse pairwise key type */
2632 //if((pairwisekey = WEP40)||(pairwisekey = WEP104)||(pairwisekey = TKIP))
2633 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))))
2644 bool GetHalfNmodeSupportByAPs819xUsb(struct net_device* dev)
2647 struct r8192_priv* priv = ieee80211_priv(dev);
2648 struct ieee80211_device* ieee = priv->ieee80211;
2650 if(ieee->bHalfWirelessN24GMode == true)
2658 void rtl8192_refresh_supportrate(struct r8192_priv* priv)
2660 struct ieee80211_device* ieee = priv->ieee80211;
2661 //we donot consider set support rate for ABG mode, only HT MCS rate is set here.
2662 if (ieee->mode == WIRELESS_MODE_N_24G || ieee->mode == WIRELESS_MODE_N_5G)
2664 memcpy(ieee->Regdot11HTOperationalRateSet, ieee->RegHTSuppRateSet, 16);
2665 //RT_DEBUG_DATA(COMP_INIT, ieee->RegHTSuppRateSet, 16);
2666 //RT_DEBUG_DATA(COMP_INIT, ieee->Regdot11HTOperationalRateSet, 16);
2669 memset(ieee->Regdot11HTOperationalRateSet, 0, 16);
2673 u8 rtl8192_getSupportedWireleeMode(struct net_device*dev)
2675 struct r8192_priv *priv = ieee80211_priv(dev);
2677 switch(priv->rf_chip)
2682 ret = (WIRELESS_MODE_N_24G|WIRELESS_MODE_G|WIRELESS_MODE_B);
2685 ret = (WIRELESS_MODE_A|WIRELESS_MODE_N_5G);
2688 ret = WIRELESS_MODE_B;
2693 void rtl8192_SetWirelessMode(struct net_device* dev, u8 wireless_mode)
2695 struct r8192_priv *priv = ieee80211_priv(dev);
2696 u8 bSupportMode = rtl8192_getSupportedWireleeMode(dev);
2698 if ((wireless_mode == WIRELESS_MODE_AUTO) || ((wireless_mode&bSupportMode)==0))
2700 if(bSupportMode & WIRELESS_MODE_N_24G)
2702 wireless_mode = WIRELESS_MODE_N_24G;
2704 else if(bSupportMode & WIRELESS_MODE_N_5G)
2706 wireless_mode = WIRELESS_MODE_N_5G;
2708 else if((bSupportMode & WIRELESS_MODE_A))
2710 wireless_mode = WIRELESS_MODE_A;
2712 else if((bSupportMode & WIRELESS_MODE_G))
2714 wireless_mode = WIRELESS_MODE_G;
2716 else if((bSupportMode & WIRELESS_MODE_B))
2718 wireless_mode = WIRELESS_MODE_B;
2721 RT_TRACE(COMP_ERR, "%s(), No valid wireless mode supported, SupportedWirelessMode(%x)!!!\n", __FUNCTION__,bSupportMode);
2722 wireless_mode = WIRELESS_MODE_B;
2725 #ifdef TO_DO_LIST //// TODO: this function doesn't work well at this time, we should wait for FPGA
2726 ActUpdateChannelAccessSetting( pAdapter, pHalData->CurrentWirelessMode, &pAdapter->MgntInfo.Info8185.ChannelAccessSetting );
2728 priv->ieee80211->mode = wireless_mode;
2730 if ((wireless_mode == WIRELESS_MODE_N_24G) || (wireless_mode == WIRELESS_MODE_N_5G))
2731 priv->ieee80211->pHTInfo->bEnableHT = 1;
2733 priv->ieee80211->pHTInfo->bEnableHT = 0;
2734 RT_TRACE(COMP_INIT, "Current Wireless Mode is %x\n", wireless_mode);
2735 rtl8192_refresh_supportrate(priv);
2738 //init priv variables here. only non_zero value should be initialized here.
2739 static void rtl8192_init_priv_variable(struct net_device* dev)
2741 struct r8192_priv *priv = ieee80211_priv(dev);
2743 priv->card_8192 = NIC_8192U;
2744 priv->chan = 1; //set to channel 1
2745 priv->ieee80211->mode = WIRELESS_MODE_AUTO; //SET AUTO
2746 priv->ieee80211->iw_mode = IW_MODE_INFRA;
2747 priv->ieee80211->ieee_up=0;
2748 priv->retry_rts = DEFAULT_RETRY_RTS;
2749 priv->retry_data = DEFAULT_RETRY_DATA;
2750 priv->ieee80211->rts = DEFAULT_RTS_THRESHOLD;
2751 priv->ieee80211->rate = 110; //11 mbps
2752 priv->ieee80211->short_slot = 1;
2753 priv->promisc = (dev->flags & IFF_PROMISC) ? 1:0;
2756 priv->IrpPendingCount = 1;
2757 priv->ResetProgress = RESET_TYPE_NORESET;
2758 priv->bForcedSilentReset = 0;
2759 priv->bDisableNormalResetCheck = false;
2760 priv->force_reset = false;
2762 priv->ieee80211->FwRWRF = 0; //we don't use FW read/write RF until stable firmware is available.
2763 priv->ieee80211->current_network.beacon_interval = DEFAULT_BEACONINTERVAL;
2764 priv->ieee80211->iw_mode = IW_MODE_INFRA;
2765 priv->ieee80211->softmac_features = IEEE_SOFTMAC_SCAN |
2766 IEEE_SOFTMAC_ASSOCIATE | IEEE_SOFTMAC_PROBERQ |
2767 IEEE_SOFTMAC_PROBERS | IEEE_SOFTMAC_TX_QUEUE |
2768 IEEE_SOFTMAC_BEACONS;//added by amy 080604 //| //IEEE_SOFTMAC_SINGLE_QUEUE;
2770 priv->ieee80211->active_scan = 1;
2771 priv->ieee80211->modulation = IEEE80211_CCK_MODULATION | IEEE80211_OFDM_MODULATION;
2772 priv->ieee80211->host_encrypt = 1;
2773 priv->ieee80211->host_decrypt = 1;
2774 priv->ieee80211->start_send_beacons = NULL;//rtl819xusb_beacon_tx;//-by amy 080604
2775 priv->ieee80211->stop_send_beacons = NULL;//rtl8192_beacon_stop;//-by amy 080604
2776 priv->ieee80211->softmac_hard_start_xmit = rtl8192_hard_start_xmit;
2777 priv->ieee80211->set_chan = rtl8192_set_chan;
2778 priv->ieee80211->link_change = rtl8192_link_change;
2779 priv->ieee80211->softmac_data_hard_start_xmit = rtl8192_hard_data_xmit;
2780 priv->ieee80211->data_hard_stop = rtl8192_data_hard_stop;
2781 priv->ieee80211->data_hard_resume = rtl8192_data_hard_resume;
2782 priv->ieee80211->init_wmmparam_flag = 0;
2783 priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD;
2784 priv->ieee80211->check_nic_enough_desc = check_nic_enough_desc;
2785 priv->ieee80211->tx_headroom = TX_PACKET_SHIFT_BYTES;
2786 priv->ieee80211->qos_support = 1;
2789 // priv->ieee80211->SwChnlByTimerHandler = rtl8192_phy_SwChnl;
2790 priv->ieee80211->SetBWModeHandler = rtl8192_SetBWMode;
2791 priv->ieee80211->handle_assoc_response = rtl8192_handle_assoc_response;
2792 priv->ieee80211->handle_beacon = rtl8192_handle_beacon;
2794 priv->ieee80211->GetNmodeSupportBySecCfg = GetNmodeSupportBySecCfg8192;
2795 priv->ieee80211->GetHalfNmodeSupportByAPsHandler = GetHalfNmodeSupportByAPs819xUsb;
2796 priv->ieee80211->SetWirelessMode = rtl8192_SetWirelessMode;
2798 priv->ieee80211->InitialGainHandler = InitialGain819xUsb;
2799 priv->card_type = USB;
2801 if(Adapter->bInHctTest)
2803 pHalData->ShortRetryLimit = 7;
2804 pHalData->LongRetryLimit = 7;
2808 priv->ShortRetryLimit = 0x30;
2809 priv->LongRetryLimit = 0x30;
2811 priv->EarlyRxThreshold = 7;
2812 priv->enable_gpio0 = 0;
2813 priv->TransmitConfig =
2814 // TCR_DurProcMode | //for RTL8185B, duration setting by HW
2815 //? TCR_DISReqQsize |
2816 (TCR_MXDMA_2048<<TCR_MXDMA_OFFSET)| // Max DMA Burst Size per Tx DMA Burst, 7: reservied.
2817 (priv->ShortRetryLimit<<TCR_SRL_OFFSET)| // Short retry limit
2818 (priv->LongRetryLimit<<TCR_LRL_OFFSET) | // Long retry limit
2819 (false ? TCR_SAT: 0); // FALSE: HW provies PLCP length and LENGEXT, TURE: SW proiveds them
2821 if(Adapter->bInHctTest)
2822 pHalData->ReceiveConfig = pHalData->CSMethod |
2823 RCR_AMF | RCR_ADF | //RCR_AAP | //accept management/data
2825 RCR_ACF | //accept control frame for SW AP needs PS-poll, 2005.07.07, by rcnjko.
2826 RCR_AB | RCR_AM | RCR_APM | //accept BC/MC/UC
2827 RCR_AICV | RCR_ACRC32 | //accept ICV/CRC error packet
2828 ((u32)7<<RCR_MXDMA_OFFSET) | // Max DMA Burst Size per Rx DMA Burst, 7: unlimited.
2829 (pHalData->EarlyRxThreshold<<RCR_FIFO_OFFSET) | // Rx FIFO Threshold, 7: No Rx threshold.
2830 (pHalData->EarlyRxThreshold == 7 ? RCR_OnlyErlPkt:0);
2834 priv->ReceiveConfig =
2835 RCR_AMF | RCR_ADF | //accept management/data
2836 RCR_ACF | //accept control frame for SW AP needs PS-poll, 2005.07.07, by rcnjko.
2837 RCR_AB | RCR_AM | RCR_APM | //accept BC/MC/UC
2838 //RCR_AICV | RCR_ACRC32 | //accept ICV/CRC error packet
2839 ((u32)7<<RCR_MXDMA_OFFSET)| // Max DMA Burst Size per Rx DMA Burst, 7: unlimited.
2840 (priv->EarlyRxThreshold<<RX_FIFO_THRESHOLD_SHIFT) | // Rx FIFO Threshold, 7: No Rx threshold.
2841 (priv->EarlyRxThreshold == 7 ? RCR_ONLYERLPKT:0);
2843 priv->AcmControl = 0;
2844 priv->pFirmware = kmalloc(sizeof(rt_firmware), GFP_KERNEL);
2845 if (priv->pFirmware)
2846 memset(priv->pFirmware, 0, sizeof(rt_firmware));
2848 /* rx related queue */
2849 skb_queue_head_init(&priv->rx_queue);
2850 skb_queue_head_init(&priv->skb_queue);
2852 /* Tx related queue */
2853 for(i = 0; i < MAX_QUEUE_SIZE; i++) {
2854 skb_queue_head_init(&priv->ieee80211->skb_waitQ [i]);
2856 for(i = 0; i < MAX_QUEUE_SIZE; i++) {
2857 skb_queue_head_init(&priv->ieee80211->skb_aggQ [i]);
2859 for(i = 0; i < MAX_QUEUE_SIZE; i++) {
2860 skb_queue_head_init(&priv->ieee80211->skb_drv_aggQ [i]);
2862 priv->rf_set_chan = rtl8192_phy_SwChnl;
2866 static void rtl8192_init_priv_lock(struct r8192_priv* priv)
2868 spin_lock_init(&priv->tx_lock);
2869 spin_lock_init(&priv->irq_lock);//added by thomas
2870 //spin_lock_init(&priv->rf_lock);
2871 sema_init(&priv->wx_sem,1);
2872 sema_init(&priv->rf_sem,1);
2873 mutex_init(&priv->mutex);
2876 extern void rtl819x_watchdog_wqcallback(struct work_struct *work);
2878 void rtl8192_irq_rx_tasklet(struct r8192_priv *priv);
2879 //init tasklet and wait_queue here. only 2.6 above kernel is considered
2880 #define DRV_NAME "wlan0"
2881 static void rtl8192_init_priv_task(struct net_device* dev)
2883 struct r8192_priv *priv = ieee80211_priv(dev);
2885 #ifdef PF_SYNCTHREAD
2886 priv->priv_wq = create_workqueue(DRV_NAME,0);
2888 priv->priv_wq = create_workqueue(DRV_NAME);
2891 INIT_WORK(&priv->reset_wq, rtl8192_restart);
2893 //INIT_DELAYED_WORK(&priv->watch_dog_wq, hal_dm_watchdog);
2894 INIT_DELAYED_WORK(&priv->watch_dog_wq, rtl819x_watchdog_wqcallback);
2895 INIT_DELAYED_WORK(&priv->txpower_tracking_wq, dm_txpower_trackingcallback);
2896 // INIT_DELAYED_WORK(&priv->gpio_change_rf_wq, dm_gpio_change_rf_callback);
2897 INIT_DELAYED_WORK(&priv->rfpath_check_wq, dm_rf_pathcheck_workitemcallback);
2898 INIT_DELAYED_WORK(&priv->update_beacon_wq, rtl8192_update_beacon);
2899 INIT_DELAYED_WORK(&priv->initialgain_operate_wq, InitialGainOperateWorkItemCallBack);
2900 //INIT_WORK(&priv->SwChnlWorkItem, rtl8192_SwChnl_WorkItem);
2901 //INIT_WORK(&priv->SetBWModeWorkItem, rtl8192_SetBWModeWorkItem);
2902 INIT_WORK(&priv->qos_activate, rtl8192_qos_activate);
2904 tasklet_init(&priv->irq_rx_tasklet,
2905 (void(*)(unsigned long))rtl8192_irq_rx_tasklet,
2906 (unsigned long)priv);
2909 static void rtl8192_get_eeprom_size(struct net_device* dev)
2912 struct r8192_priv *priv = ieee80211_priv(dev);
2913 RT_TRACE(COMP_EPROM, "===========>%s()\n", __FUNCTION__);
2914 curCR = read_nic_word_E(dev,EPROM_CMD);
2915 RT_TRACE(COMP_EPROM, "read from Reg EPROM_CMD(%x):%x\n", EPROM_CMD, curCR);
2916 //whether need I consider BIT5?
2917 priv->epromtype = (curCR & Cmd9346CR_9356SEL) ? EPROM_93c56 : EPROM_93c46;
2918 RT_TRACE(COMP_EPROM, "<===========%s(), epromtype:%d\n", __FUNCTION__, priv->epromtype);
2921 //used to swap endian. as ntohl & htonl are not neccessary to swap endian, so use this instead.
2922 static inline u16 endian_swap(u16* data)
2925 *data = (tmp >> 8) | (tmp << 8);
2928 static void rtl8192_read_eeprom_info(struct net_device* dev)
2931 u8 bMac_Tmp_Addr[6] = {0x00, 0xe0, 0x4c, 0x00, 0x00, 0x02};
2932 u8 bLoad_From_EEPOM = false;
2933 struct r8192_priv *priv = ieee80211_priv(dev);
2935 RT_TRACE(COMP_EPROM, "===========>%s()\n", __FUNCTION__);
2936 wEPROM_ID = eprom_read(dev, 0); //first read EEPROM ID out;
2937 RT_TRACE(COMP_EPROM, "EEPROM ID is 0x%x\n", wEPROM_ID);
2939 if (wEPROM_ID != RTL8190_EEPROM_ID)
2941 RT_TRACE(COMP_ERR, "EEPROM ID is invalid(is 0x%x(should be 0x%x)\n", wEPROM_ID, RTL8190_EEPROM_ID);
2944 bLoad_From_EEPOM = true;
2946 if (bLoad_From_EEPOM)
2948 tmpValue = eprom_read(dev, (EEPROM_VID>>1));
2949 priv->eeprom_vid = endian_swap(&tmpValue);
2950 priv->eeprom_pid = eprom_read(dev, (EEPROM_PID>>1));
2951 tmpValue = eprom_read(dev, (EEPROM_ChannelPlan>>1));
2952 priv->eeprom_ChannelPlan =((tmpValue&0xff00)>>8);
2953 priv->btxpowerdata_readfromEEPORM = true;
2954 priv->eeprom_CustomerID = eprom_read(dev, (EEPROM_Customer_ID>>1)) >>8;
2958 priv->eeprom_vid = 0;
2959 priv->eeprom_pid = 0;
2960 priv->card_8192_version = VERSION_819xU_B;
2961 priv->eeprom_ChannelPlan = 0;
2962 priv->eeprom_CustomerID = 0;
2964 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);
2965 //set channelplan from eeprom
2966 priv->ChannelPlan = priv->eeprom_ChannelPlan;
2967 if (bLoad_From_EEPOM)
2970 for (i=0; i<6; i+=2)
2973 tmp = eprom_read(dev, (u16)((EEPROM_NODE_ADDRESS_BYTE_0 + i)>>1));
2974 *(u16*)(&dev->dev_addr[i]) = tmp;
2979 memcpy(dev->dev_addr, bMac_Tmp_Addr, 6);
2980 //should I set IDR0 here?
2982 RT_TRACE(COMP_EPROM, "MAC addr:%pM\n", dev->dev_addr);
2983 priv->rf_type = RTL819X_DEFAULT_RF_TYPE; //default 1T2R
2984 priv->rf_chip = RF_8256;
2986 if (priv->card_8192_version == (u8)VERSION_819xU_A)
2988 //read Tx power gain offset of legacy OFDM to HT rate
2989 if (bLoad_From_EEPOM)
2990 priv->EEPROMTxPowerDiff = (eprom_read(dev, (EEPROM_TxPowerDiff>>1))&0xff00) >> 8;
2992 priv->EEPROMTxPowerDiff = EEPROM_Default_TxPower;
2993 RT_TRACE(COMP_EPROM, "TxPowerDiff:%d\n", priv->EEPROMTxPowerDiff);
2994 //read ThermalMeter from EEPROM
2995 if (bLoad_From_EEPOM)
2996 priv->EEPROMThermalMeter = (u8)(eprom_read(dev, (EEPROM_ThermalMeter>>1))&0x00ff);
2998 priv->EEPROMThermalMeter = EEPROM_Default_ThermalMeter;
2999 RT_TRACE(COMP_EPROM, "ThermalMeter:%d\n", priv->EEPROMThermalMeter);
3000 //vivi, for tx power track
3001 priv->TSSI_13dBm = priv->EEPROMThermalMeter *100;
3002 //read antenna tx power offset of B/C/D to A from EEPROM
3003 if (bLoad_From_EEPOM)
3004 priv->EEPROMPwDiff = (eprom_read(dev, (EEPROM_PwDiff>>1))&0x0f00)>>8;
3006 priv->EEPROMPwDiff = EEPROM_Default_PwDiff;
3007 RT_TRACE(COMP_EPROM, "TxPwDiff:%d\n", priv->EEPROMPwDiff);
3008 // Read CrystalCap from EEPROM
3009 if (bLoad_From_EEPOM)
3010 priv->EEPROMCrystalCap = (eprom_read(dev, (EEPROM_CrystalCap>>1))&0x0f);
3012 priv->EEPROMCrystalCap = EEPROM_Default_CrystalCap;
3013 RT_TRACE(COMP_EPROM, "CrystalCap = %d\n", priv->EEPROMCrystalCap);
3014 //get per-channel Tx power level
3015 if (bLoad_From_EEPOM)
3016 priv->EEPROM_Def_Ver = (eprom_read(dev, (EEPROM_TxPwIndex_Ver>>1))&0xff00)>>8;
3018 priv->EEPROM_Def_Ver = 1;
3019 RT_TRACE(COMP_EPROM, "EEPROM_DEF_VER:%d\n", priv->EEPROM_Def_Ver);
3020 if (priv->EEPROM_Def_Ver == 0) //old eeprom definition
3023 if (bLoad_From_EEPOM)
3024 priv->EEPROMTxPowerLevelCCK = (eprom_read(dev, (EEPROM_TxPwIndex_CCK>>1))&0xff) >> 8;
3026 priv->EEPROMTxPowerLevelCCK = 0x10;
3027 RT_TRACE(COMP_EPROM, "CCK Tx Power Levl: 0x%02x\n", priv->EEPROMTxPowerLevelCCK);
3030 if (bLoad_From_EEPOM)
3032 tmpValue = eprom_read(dev, (EEPROM_TxPwIndex_OFDM_24G+i)>>1);
3033 if (((EEPROM_TxPwIndex_OFDM_24G+i) % 2) == 0)
3034 tmpValue = tmpValue & 0x00ff;
3036 tmpValue = (tmpValue & 0xff00) >> 8;
3040 priv->EEPROMTxPowerLevelOFDM24G[i] = (u8) tmpValue;
3041 RT_TRACE(COMP_EPROM, "OFDM 2.4G Tx Power Level, Index %d = 0x%02x\n", i, priv->EEPROMTxPowerLevelCCK);
3043 }//end if EEPROM_DEF_VER == 0
3044 else if (priv->EEPROM_Def_Ver == 1)
3046 if (bLoad_From_EEPOM)
3048 tmpValue = eprom_read(dev, (EEPROM_TxPwIndex_CCK_V1>>1));
3049 tmpValue = (tmpValue & 0xff00) >> 8;
3053 priv->EEPROMTxPowerLevelCCK_V1[0] = (u8)tmpValue;
3055 if (bLoad_From_EEPOM)
3056 tmpValue = eprom_read(dev, (EEPROM_TxPwIndex_CCK_V1 + 2)>>1);
3059 *((u16*)(&priv->EEPROMTxPowerLevelCCK_V1[1])) = tmpValue;
3060 if (bLoad_From_EEPOM)
3061 tmpValue = eprom_read(dev, (EEPROM_TxPwIndex_OFDM_24G_V1>>1));
3064 *((u16*)(&priv->EEPROMTxPowerLevelOFDM24G[0])) = tmpValue;
3065 if (bLoad_From_EEPOM)
3066 tmpValue = eprom_read(dev, (EEPROM_TxPwIndex_OFDM_24G_V1+2)>>1);
3069 priv->EEPROMTxPowerLevelOFDM24G[2] = (u8)tmpValue;
3070 }//endif EEPROM_Def_Ver == 1
3072 //update HAL variables
3076 for (i=0; i<14; i++)
3079 priv->TxPowerLevelOFDM24G[i] = priv->EEPROMTxPowerLevelOFDM24G[0];
3080 else if (i>=4 && i<=9)
3081 priv->TxPowerLevelOFDM24G[i] = priv->EEPROMTxPowerLevelOFDM24G[1];
3083 priv->TxPowerLevelOFDM24G[i] = priv->EEPROMTxPowerLevelOFDM24G[2];
3086 for (i=0; i<14; i++)
3088 if (priv->EEPROM_Def_Ver == 0)
3091 priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelOFDM24G[0] + (priv->EEPROMTxPowerLevelCCK - priv->EEPROMTxPowerLevelOFDM24G[1]);
3092 else if (i>=4 && i<=9)
3093 priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelCCK;
3095 priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelOFDM24G[2] + (priv->EEPROMTxPowerLevelCCK - priv->EEPROMTxPowerLevelOFDM24G[1]);
3097 else if (priv->EEPROM_Def_Ver == 1)
3100 priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelCCK_V1[0];
3101 else if (i>=4 && i<=9)
3102 priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelCCK_V1[1];
3104 priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelCCK_V1[2];
3107 }//end update HAL variables
3108 priv->TxPowerDiff = priv->EEPROMPwDiff;
3109 // Antenna B gain offset to antenna A, bit0~3
3110 priv->AntennaTxPwDiff[0] = (priv->EEPROMTxPowerDiff & 0xf);
3111 // Antenna C gain offset to antenna A, bit4~7
3112 priv->AntennaTxPwDiff[1] = ((priv->EEPROMTxPowerDiff & 0xf0)>>4);
3113 // CrystalCap, bit12~15
3114 priv->CrystalCap = priv->EEPROMCrystalCap;
3115 // ThermalMeter, bit0~3 for RFIC1, bit4~7 for RFIC2
3116 // 92U does not enable TX power tracking.
3117 priv->ThermalMeter[0] = priv->EEPROMThermalMeter;
3118 }//end if VersionID == VERSION_819xU_A
3120 //added by vivi, for dlink led, 20080416
3121 switch(priv->eeprom_CustomerID)
3123 case EEPROM_CID_RUNTOP:
3124 priv->CustomerID = RT_CID_819x_RUNTOP;
3127 case EEPROM_CID_DLINK:
3128 priv->CustomerID = RT_CID_DLINK;
3132 priv->CustomerID = RT_CID_DEFAULT;
3137 switch(priv->CustomerID)
3139 case RT_CID_819x_RUNTOP:
3140 priv->LedStrategy = SW_LED_MODE2;
3144 priv->LedStrategy = SW_LED_MODE4;
3148 priv->LedStrategy = SW_LED_MODE0;
3154 if(priv->rf_type == RF_1T2R)
3156 RT_TRACE(COMP_EPROM, "\n1T2R config\n");
3160 RT_TRACE(COMP_EPROM, "\n2T4R config\n");
3163 // 2008/01/16 MH We can only know RF type in the function. So we have to init
3164 // DIG RATR table again.
3165 init_rate_adaptive(dev);
3166 //we need init DIG RATR table here again.
3168 RT_TRACE(COMP_EPROM, "<===========%s()\n", __FUNCTION__);
3172 short rtl8192_get_channel_map(struct net_device * dev)
3174 struct r8192_priv *priv = ieee80211_priv(dev);
3175 #ifdef ENABLE_DOT11D
3176 if(priv->ChannelPlan > COUNTRY_CODE_GLOBAL_DOMAIN){
3177 printk("rtl8180_init:Error channel plan! Set to default.\n");
3178 priv->ChannelPlan= 0;
3180 RT_TRACE(COMP_INIT, "Channel plan is %d\n",priv->ChannelPlan);
3182 rtl819x_set_channel_map(priv->ChannelPlan, priv);
3185 //Set Default Channel Plan
3187 DMESG("No channels, aborting");
3191 priv->ChannelPlan= 0;//hikaru
3192 // set channels 1..14 allowed in given locale
3193 for (i=1; i<=14; i++) {
3194 (priv->ieee80211->channel_map)[i] = (u8)(ch & 0x01);
3201 short rtl8192_init(struct net_device *dev)
3204 struct r8192_priv *priv = ieee80211_priv(dev);
3206 memset(&(priv->stats),0,sizeof(struct Stats));
3207 memset(priv->txqueue_to_outpipemap,0,9);
3211 u8 queuetopipe[]={3,2,1,0,4,8,7,6,5};
3212 memcpy(priv->txqueue_to_outpipemap,queuetopipe,9);
3214 printk("%d ",priv->txqueue_to_outpipemap[i]);
3219 u8 queuetopipe[]={3,2,1,0,4,4,0,4,4};
3220 memcpy(priv->txqueue_to_outpipemap,queuetopipe,9);
3222 printk("%d ",priv->txqueue_to_outpipemap[i]);
3226 rtl8192_init_priv_variable(dev);
3227 rtl8192_init_priv_lock(priv);
3228 rtl8192_init_priv_task(dev);
3229 rtl8192_get_eeprom_size(dev);
3230 rtl8192_read_eeprom_info(dev);
3231 rtl8192_get_channel_map(dev);
3233 init_timer(&priv->watch_dog_timer);
3234 priv->watch_dog_timer.data = (unsigned long)dev;
3235 priv->watch_dog_timer.function = watch_dog_timer_callback;
3236 if(rtl8192_usb_initendpoints(dev)!=0){
3237 DMESG("Endopoints initialization failed");
3241 //rtl8192_adapter_start(dev);
3248 /******************************************************************************
3249 *function: This function actually only set RRSR, RATR and BW_OPMODE registers
3250 * not to do all the hw config as its name says
3251 * input: net_device dev
3254 * notice: This part need to modified according to the rate set we filtered
3255 * ****************************************************************************/
3256 void rtl8192_hwconfig(struct net_device* dev)
3258 u32 regRATR = 0, regRRSR = 0;
3259 u8 regBwOpMode = 0, regTmp = 0;
3260 struct r8192_priv *priv = ieee80211_priv(dev);
3262 // Set RRSR, RATR, and BW_OPMODE registers
3264 switch(priv->ieee80211->mode)
3266 case WIRELESS_MODE_B:
3267 regBwOpMode = BW_OPMODE_20MHZ;
3268 regRATR = RATE_ALL_CCK;
3269 regRRSR = RATE_ALL_CCK;
3271 case WIRELESS_MODE_A:
3272 regBwOpMode = BW_OPMODE_5G |BW_OPMODE_20MHZ;
3273 regRATR = RATE_ALL_OFDM_AG;
3274 regRRSR = RATE_ALL_OFDM_AG;
3276 case WIRELESS_MODE_G:
3277 regBwOpMode = BW_OPMODE_20MHZ;
3278 regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
3279 regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
3281 case WIRELESS_MODE_AUTO:
3283 if (Adapter->bInHctTest)
3285 regBwOpMode = BW_OPMODE_20MHZ;
3286 regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
3287 regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
3292 regBwOpMode = BW_OPMODE_20MHZ;
3293 regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
3294 regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
3297 case WIRELESS_MODE_N_24G:
3298 // It support CCK rate by default.
3299 // CCK rate will be filtered out only when associated AP does not support it.
3300 regBwOpMode = BW_OPMODE_20MHZ;
3301 regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
3302 regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
3304 case WIRELESS_MODE_N_5G:
3305 regBwOpMode = BW_OPMODE_5G;
3306 regRATR = RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
3307 regRRSR = RATE_ALL_OFDM_AG;
3311 write_nic_byte(dev, BW_OPMODE, regBwOpMode);
3314 ratr_value = regRATR;
3315 if (priv->rf_type == RF_1T2R)
3317 ratr_value &= ~(RATE_ALL_OFDM_2SS);
3319 write_nic_dword(dev, RATR0, ratr_value);
3320 write_nic_byte(dev, UFWP, 1);
3322 regTmp = read_nic_byte(dev, 0x313);
3323 regRRSR = ((regTmp) << 24) | (regRRSR & 0x00ffffff);
3324 write_nic_dword(dev, RRSR, regRRSR);
3327 // Set Retry Limit here
3329 write_nic_word(dev, RETRY_LIMIT,
3330 priv->ShortRetryLimit << RETRY_LIMIT_SHORT_SHIFT | \
3331 priv->LongRetryLimit << RETRY_LIMIT_LONG_SHIFT);
3332 // Set Contention Window here
3336 // Set Tx Antenna including Feedback control
3338 // Set Auto Rate fallback control
3344 //InitializeAdapter and PhyCfg
3345 bool rtl8192_adapter_start(struct net_device *dev)
3347 struct r8192_priv *priv = ieee80211_priv(dev);
3349 bool init_status = true;
3350 RT_TRACE(COMP_INIT, "====>%s()\n", __FUNCTION__);
3351 priv->Rf_Mode = RF_OP_By_SW_3wire;
3352 //for ASIC power on sequence
3353 write_nic_byte_E(dev, 0x5f, 0x80);
3355 write_nic_byte_E(dev, 0x5f, 0xf0);
3356 write_nic_byte_E(dev, 0x5d, 0x00);
3357 write_nic_byte_E(dev, 0x5e, 0x80);
3358 write_nic_byte(dev, 0x17, 0x37);
3361 priv->pFirmware->firmware_status = FW_STATUS_0_INIT;
3362 //config CPUReset Register
3363 //Firmware Reset or not?
3364 dwRegRead = read_nic_dword(dev, CPU_GEN);
3365 if (priv->pFirmware->firmware_status == FW_STATUS_0_INIT)
3366 dwRegRead |= CPU_GEN_SYSTEM_RESET; //do nothing here?
3367 else if (priv->pFirmware->firmware_status == FW_STATUS_5_READY)
3368 dwRegRead |= CPU_GEN_FIRMWARE_RESET;
3370 RT_TRACE(COMP_ERR, "ERROR in %s(): undefined firmware state(%d)\n", __FUNCTION__, priv->pFirmware->firmware_status);
3372 write_nic_dword(dev, CPU_GEN, dwRegRead);
3375 rtl8192_BBConfig(dev);
3377 //Loopback mode or not
3378 priv->LoopbackMode = RTL819xU_NO_LOOPBACK;
3379 // priv->LoopbackMode = RTL819xU_MAC_LOOPBACK;
3381 dwRegRead = read_nic_dword(dev, CPU_GEN);
3382 if (priv->LoopbackMode == RTL819xU_NO_LOOPBACK)
3383 dwRegRead = ((dwRegRead & CPU_GEN_NO_LOOPBACK_MSK) | CPU_GEN_NO_LOOPBACK_SET);
3384 else if (priv->LoopbackMode == RTL819xU_MAC_LOOPBACK)
3385 dwRegRead |= CPU_CCK_LOOPBACK;
3387 RT_TRACE(COMP_ERR, "Serious error in %s(): wrong loopback mode setting(%d)\n", __FUNCTION__, priv->LoopbackMode);
3389 write_nic_dword(dev, CPU_GEN, dwRegRead);
3391 //after reset cpu, we need wait for a seconds to write in register.
3394 //xiong add for new bitfile:usb suspend reset pin set to 1. //do we need?
3395 write_nic_byte_E(dev, 0x5f, (read_nic_byte_E(dev, 0x5f)|0x20));
3398 rtl8192_hwconfig(dev);
3401 write_nic_byte(dev, CMDR, CR_RE|CR_TE);
3404 write_nic_dword(dev, MAC0, ((u32*)dev->dev_addr)[0]);
3405 write_nic_word(dev, MAC4, ((u16*)(dev->dev_addr + 4))[0]);
3408 write_nic_dword(dev, RCR, priv->ReceiveConfig);
3410 //Initialize Number of Reserved Pages in Firmware Queue
3411 write_nic_dword(dev, RQPN1, NUM_OF_PAGE_IN_FW_QUEUE_BK << RSVD_FW_QUEUE_PAGE_BK_SHIFT |\
3412 NUM_OF_PAGE_IN_FW_QUEUE_BE << RSVD_FW_QUEUE_PAGE_BE_SHIFT | \
3413 NUM_OF_PAGE_IN_FW_QUEUE_VI << RSVD_FW_QUEUE_PAGE_VI_SHIFT | \
3414 NUM_OF_PAGE_IN_FW_QUEUE_VO <<RSVD_FW_QUEUE_PAGE_VO_SHIFT);
3415 write_nic_dword(dev, RQPN2, NUM_OF_PAGE_IN_FW_QUEUE_MGNT << RSVD_FW_QUEUE_PAGE_MGNT_SHIFT |\
3416 NUM_OF_PAGE_IN_FW_QUEUE_CMD << RSVD_FW_QUEUE_PAGE_CMD_SHIFT);
3417 write_nic_dword(dev, RQPN3, APPLIED_RESERVED_QUEUE_IN_FW| \
3418 NUM_OF_PAGE_IN_FW_QUEUE_BCN<<RSVD_FW_QUEUE_PAGE_BCN_SHIFT
3419 // | NUM_OF_PAGE_IN_FW_QUEUE_PUB<<RSVD_FW_QUEUE_PAGE_PUB_SHIFT
3421 write_nic_dword(dev, RATR0+4*7, (RATE_ALL_OFDM_AG | RATE_ALL_CCK));
3424 // TODO: (it value is only for FPGA version). need to be changed!!2006.12.18, by Emily
3425 write_nic_byte(dev, ACK_TIMEOUT, 0x30);
3427 // RT_TRACE(COMP_INIT, "%s():priv->ResetProgress is %d\n", __FUNCTION__,priv->ResetProgress);
3428 if(priv->ResetProgress == RESET_TYPE_NORESET)
3429 rtl8192_SetWirelessMode(dev, priv->ieee80211->mode);
3430 if(priv->ResetProgress == RESET_TYPE_NORESET){
3431 CamResetAllEntry(dev);
3433 u8 SECR_value = 0x0;
3434 SECR_value |= SCR_TxEncEnable;
3435 SECR_value |= SCR_RxDecEnable;
3436 SECR_value |= SCR_NoSKMC;
3437 write_nic_byte(dev, SECR, SECR_value);
3442 write_nic_word(dev, ATIMWND, 2);
3443 write_nic_word(dev, BCN_INTERVAL, 100);
3446 #define DEFAULT_EDCA 0x005e4332
3448 for (i=0; i<QOS_QUEUE_NUM; i++)
3449 write_nic_dword(dev, WDCAPARA_ADD[i], DEFAULT_EDCA);
3451 #ifdef USB_RX_AGGREGATION_SUPPORT
3452 //3 For usb rx firmware aggregation control
3453 if(priv->ResetProgress == RESET_TYPE_NORESET)
3456 PRT_HIGH_THROUGHPUT pHTInfo = priv->ieee80211->pHTInfo;
3457 ulValue = (pHTInfo->UsbRxFwAggrEn<<24) | (pHTInfo->UsbRxFwAggrPageNum<<16) |
3458 (pHTInfo->UsbRxFwAggrPacketNum<<8) | (pHTInfo->UsbRxFwAggrTimeout);
3460 * If usb rx firmware aggregation is enabled,
3461 * when anyone of three threshold conditions above is reached,
3462 * firmware will send aggregated packet to driver.
3464 write_nic_dword(dev, 0x1a8, ulValue);
3465 priv->bCurrentRxAggrEnable = true;
3469 rtl8192_phy_configmac(dev);
3471 if (priv->card_8192_version == (u8) VERSION_819xU_A)
3473 rtl8192_phy_getTxPower(dev);
3474 rtl8192_phy_setTxPower(dev, priv->chan);
3478 init_status = init_firmware(dev);
3481 RT_TRACE(COMP_ERR,"ERR!!! %s(): Firmware download is failed\n", __FUNCTION__);
3484 RT_TRACE(COMP_INIT, "%s():after firmware download\n", __FUNCTION__);
3487 if(Adapter->ResetProgress == RESET_TYPE_NORESET)
3489 if(pMgntInfo->RegRfOff == TRUE)
3490 { // User disable RF via registry.
3491 RT_TRACE((COMP_INIT|COMP_RF), DBG_LOUD, ("InitializeAdapter819xUsb(): Turn off RF for RegRfOff ----------\n"));
3492 MgntActSet_RF_State(Adapter, eRfOff, RF_CHANGE_BY_SW);
3493 // Those action will be discard in MgntActSet_RF_State because off the same state
3494 for(eRFPath = 0; eRFPath <pHalData->NumTotalRFPath; eRFPath++)
3495 PHY_SetRFReg(Adapter, (RF90_RADIO_PATH_E)eRFPath, 0x4, 0xC00, 0x0);
3497 else if(pMgntInfo->RfOffReason > RF_CHANGE_BY_PS)
3498 { // H/W or S/W RF OFF before sleep.
3499 RT_TRACE((COMP_INIT|COMP_RF), DBG_LOUD, ("InitializeAdapter819xUsb(): Turn off RF for RfOffReason(%d) ----------\n", pMgntInfo->RfOffReason));
3500 MgntActSet_RF_State(Adapter, eRfOff, pMgntInfo->RfOffReason);
3504 pHalData->eRFPowerState = eRfOn;
3505 pMgntInfo->RfOffReason = 0;
3506 RT_TRACE((COMP_INIT|COMP_RF), DBG_LOUD, ("InitializeAdapter819xUsb(): RF is on ----------\n"));
3511 if(pHalData->eRFPowerState == eRfOff)
3513 MgntActSet_RF_State(Adapter, eRfOff, pMgntInfo->RfOffReason);
3514 // Those action will be discard in MgntActSet_RF_State because off the same state
3515 for(eRFPath = 0; eRFPath <pHalData->NumTotalRFPath; eRFPath++)
3516 PHY_SetRFReg(Adapter, (RF90_RADIO_PATH_E)eRFPath, 0x4, 0xC00, 0x0);
3521 if(priv->ResetProgress == RESET_TYPE_NORESET){
3522 rtl8192_phy_RFConfig(dev);
3523 RT_TRACE(COMP_INIT, "%s():after phy RF config\n", __FUNCTION__);
3527 if(priv->ieee80211->FwRWRF)
3528 // We can force firmware to do RF-R/W
3529 priv->Rf_Mode = RF_OP_By_FW;
3531 priv->Rf_Mode = RF_OP_By_SW_3wire;
3534 rtl8192_phy_updateInitGain(dev);
3535 /*--set CCK and OFDM Block "ON"--*/
3536 rtl8192_setBBreg(dev, rFPGA0_RFMOD, bCCKEn, 0x1);
3537 rtl8192_setBBreg(dev, rFPGA0_RFMOD, bOFDMEn, 0x1);
3539 if(priv->ResetProgress == RESET_TYPE_NORESET)
3542 u8 tmpvalue = read_nic_byte(dev, 0x301);
3546 RT_TRACE(COMP_POWER_TRACKING, "D-cut\n");
3550 priv->bDcut = FALSE;
3551 RT_TRACE(COMP_POWER_TRACKING, "C-cut\n");
3553 dm_initialize_txpower_tracking(dev);
3555 if(priv->bDcut == TRUE)
3558 u32 tmpRegA= rtl8192_QueryBBReg(dev,rOFDM0_XATxIQImbalance,bMaskDWord);
3559 // u32 tmpRegC= rtl8192_QueryBBReg(dev,rOFDM0_XCTxIQImbalance,bMaskDWord);
3560 for(i = 0; i<TxBBGainTableLength; i++)
3562 if(tmpRegA == priv->txbbgain_table[i].txbbgain_value)
3564 priv->rfa_txpowertrackingindex= (u8)i;
3565 priv->rfa_txpowertrackingindex_real= (u8)i;
3566 priv->rfa_txpowertracking_default= priv->rfa_txpowertrackingindex;
3571 TempCCk = rtl8192_QueryBBReg(dev, rCCK0_TxFilter1, bMaskByte2);
3573 for(i=0 ; i<CCKTxBBGainTableLength ; i++)
3576 if(TempCCk == priv->cck_txbbgain_table[i].ccktxbb_valuearray[0])
3578 priv->cck_present_attentuation_20Mdefault=(u8) i;
3582 priv->cck_present_attentuation_40Mdefault= 0;
3583 priv->cck_present_attentuation_difference= 0;
3584 priv->cck_present_attentuation = priv->cck_present_attentuation_20Mdefault;
3586 // pMgntInfo->bTXPowerTracking = FALSE;//TEMPLY DISABLE
3589 write_nic_byte(dev, 0x87, 0x0);
3595 /* this configures registers for beacon tx and enables it via
3596 * rtl8192_beacon_tx_enable(). rtl8192_beacon_tx_disable() might
3597 * be used to stop beacon transmission
3599 /***************************************************************************
3600 -------------------------------NET STUFF---------------------------
3601 ***************************************************************************/
3603 static struct net_device_stats *rtl8192_stats(struct net_device *dev)
3605 struct r8192_priv *priv = ieee80211_priv(dev);
3607 return &priv->ieee80211->stats;
3611 HalTxCheckStuck819xUsb(
3612 struct net_device *dev
3615 struct r8192_priv *priv = ieee80211_priv(dev);
3616 u16 RegTxCounter = read_nic_word(dev, 0x128);
3617 bool bStuck = FALSE;
3618 RT_TRACE(COMP_RESET,"%s():RegTxCounter is %d,TxCounter is %d\n",__FUNCTION__,RegTxCounter,priv->TxCounter);
3619 if(priv->TxCounter==RegTxCounter)
3622 priv->TxCounter = RegTxCounter;
3628 * <Assumption: RT_TX_SPINLOCK is acquired.>
3629 * First added: 2006.11.19 by emily
3632 TxCheckStuck(struct net_device *dev)
3634 struct r8192_priv *priv = ieee80211_priv(dev);
3637 // u8 ResetThreshold;
3638 bool bCheckFwTxCnt = false;
3639 //unsigned long flags;
3642 // Decide Stuch threshold according to current power save mode
3645 // RT_TRACE(COMP_RESET, " ==> TxCheckStuck()\n");
3646 // PlatformAcquireSpinLock(Adapter, RT_TX_SPINLOCK);
3647 // spin_lock_irqsave(&priv->ieee80211->lock,flags);
3648 for (QueueID = 0; QueueID<=BEACON_QUEUE;QueueID ++)
3650 if(QueueID == TXCMD_QUEUE)
3652 #ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
3653 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))
3655 if((skb_queue_len(&priv->ieee80211->skb_waitQ[QueueID]) == 0) && (skb_queue_len(&priv->ieee80211->skb_aggQ[QueueID]) == 0))
3659 bCheckFwTxCnt = true;
3661 // PlatformReleaseSpinLock(Adapter, RT_TX_SPINLOCK);
3662 // spin_unlock_irqrestore(&priv->ieee80211->lock,flags);
3663 // RT_TRACE(COMP_RESET,"bCheckFwTxCnt is %d\n",bCheckFwTxCnt);
3666 if(HalTxCheckStuck819xUsb(dev))
3668 RT_TRACE(COMP_RESET, "TxCheckStuck(): Fw indicates no Tx condition! \n");
3669 return RESET_TYPE_SILENT;
3672 return RESET_TYPE_NORESET;
3676 HalRxCheckStuck819xUsb(struct net_device *dev)
3678 u16 RegRxCounter = read_nic_word(dev, 0x130);
3679 struct r8192_priv *priv = ieee80211_priv(dev);
3680 bool bStuck = FALSE;
3681 static u8 rx_chk_cnt = 0;
3682 RT_TRACE(COMP_RESET,"%s(): RegRxCounter is %d,RxCounter is %d\n",__FUNCTION__,RegRxCounter,priv->RxCounter);
3683 // If rssi is small, we should check rx for long time because of bad rx.
3684 // or maybe it will continuous silent reset every 2 seconds.
3686 if(priv->undecorated_smoothed_pwdb >= (RateAdaptiveTH_High+5))
3688 rx_chk_cnt = 0; //high rssi, check rx stuck right now.
3690 else if(priv->undecorated_smoothed_pwdb < (RateAdaptiveTH_High+5) &&
3691 ((priv->CurrentChannelBW!=HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb>=RateAdaptiveTH_Low_40M) ||
3692 (priv->CurrentChannelBW==HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb>=RateAdaptiveTH_Low_20M)) )
3703 else if(((priv->CurrentChannelBW!=HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb<RateAdaptiveTH_Low_40M) ||
3704 (priv->CurrentChannelBW==HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb<RateAdaptiveTH_Low_20M)) &&
3705 priv->undecorated_smoothed_pwdb >= VeryLowRSSI)
3709 //DbgPrint("RSSI < %d && RSSI >= %d, no check this time \n", RateAdaptiveTH_Low, VeryLowRSSI);
3715 //DbgPrint("RSSI < %d && RSSI >= %d, check this time \n", RateAdaptiveTH_Low, VeryLowRSSI);
3722 //DbgPrint("RSSI <= %d, no check this time \n", VeryLowRSSI);
3728 //DbgPrint("RSSI <= %d, check this time \n", VeryLowRSSI);
3732 if(priv->RxCounter==RegRxCounter)
3735 priv->RxCounter = RegRxCounter;
3741 RxCheckStuck(struct net_device *dev)
3743 struct r8192_priv *priv = ieee80211_priv(dev);
3745 bool bRxCheck = FALSE;
3747 // RT_TRACE(COMP_RESET," ==> RxCheckStuck()\n");
3748 //PlatformAcquireSpinLock(Adapter, RT_RX_SPINLOCK);
3750 if(priv->IrpPendingCount > 1)
3752 //PlatformReleaseSpinLock(Adapter, RT_RX_SPINLOCK);
3754 // RT_TRACE(COMP_RESET,"bRxCheck is %d \n",bRxCheck);
3757 if(HalRxCheckStuck819xUsb(dev))
3759 RT_TRACE(COMP_RESET, "RxStuck Condition\n");
3760 return RESET_TYPE_SILENT;
3763 return RESET_TYPE_NORESET;
3768 * This function is called by Checkforhang to check whether we should ask OS to reset driver
3770 * \param pAdapter The adapter context for this miniport
3772 * Note:NIC with USB interface sholud not call this function because we cannot scan descriptor
3773 * to judge whether there is tx stuck.
3774 * Note: This function may be required to be rewrite for Vista OS.
3775 * <<<Assumption: Tx spinlock has been acquired >>>
3777 * 8185 and 8185b does not implement this function. This is added by Emily at 2006.11.24
3780 rtl819x_ifcheck_resetornot(struct net_device *dev)
3782 struct r8192_priv *priv = ieee80211_priv(dev);
3783 RESET_TYPE TxResetType = RESET_TYPE_NORESET;
3784 RESET_TYPE RxResetType = RESET_TYPE_NORESET;
3785 RT_RF_POWER_STATE rfState;
3787 rfState = priv->ieee80211->eRFPowerState;
3789 TxResetType = TxCheckStuck(dev);
3790 if( rfState != eRfOff ||
3791 /*ADAPTER_TEST_STATUS_FLAG(Adapter, ADAPTER_STATUS_FW_DOWNLOAD_FAILURE)) &&*/
3792 (priv->ieee80211->iw_mode != IW_MODE_ADHOC))
3794 // If driver is in the status of firmware download failure , driver skips RF initialization and RF is
3795 // in turned off state. Driver should check whether Rx stuck and do silent reset. And
3796 // if driver is in firmware download failure status, driver should initialize RF in the following
3797 // silent reset procedure Emily, 2008.01.21
3799 // Driver should not check RX stuck in IBSS mode because it is required to
3800 // set Check BSSID in order to send beacon, however, if check BSSID is
3801 // set, STA cannot hear any packet a all. Emily, 2008.04.12
3802 RxResetType = RxCheckStuck(dev);
3804 if(TxResetType==RESET_TYPE_NORMAL || RxResetType==RESET_TYPE_NORMAL)
3805 return RESET_TYPE_NORMAL;
3806 else if(TxResetType==RESET_TYPE_SILENT || RxResetType==RESET_TYPE_SILENT){
3807 RT_TRACE(COMP_RESET,"%s():silent reset\n",__FUNCTION__);
3808 return RESET_TYPE_SILENT;
3811 return RESET_TYPE_NORESET;
3815 void rtl8192_cancel_deferred_work(struct r8192_priv* priv);
3816 int _rtl8192_up(struct net_device *dev);
3817 int rtl8192_close(struct net_device *dev);
3822 CamRestoreAllEntry( struct net_device *dev)
3825 struct r8192_priv *priv = ieee80211_priv(dev);
3826 u8* MacAddr = priv->ieee80211->current_network.bssid;
3828 static u8 CAM_CONST_ADDR[4][6] = {
3829 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
3830 {0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
3831 {0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
3832 {0x00, 0x00, 0x00, 0x00, 0x00, 0x03}};
3833 static u8 CAM_CONST_BROAD[] =
3834 {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
3836 RT_TRACE(COMP_SEC, "CamRestoreAllEntry: \n");
3839 if ((priv->ieee80211->pairwise_key_type == KEY_TYPE_WEP40)||
3840 (priv->ieee80211->pairwise_key_type == KEY_TYPE_WEP104))
3843 for(EntryId=0; EntryId<4; EntryId++)
3846 MacAddr = CAM_CONST_ADDR[EntryId];
3850 priv->ieee80211->pairwise_key_type,
3858 else if(priv->ieee80211->pairwise_key_type == KEY_TYPE_TKIP)
3862 if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
3866 priv->ieee80211->pairwise_key_type,
3874 priv->ieee80211->pairwise_key_type,
3880 else if(priv->ieee80211->pairwise_key_type == KEY_TYPE_CCMP)
3884 if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
3888 priv->ieee80211->pairwise_key_type,
3896 priv->ieee80211->pairwise_key_type,
3905 if(priv->ieee80211->group_key_type == KEY_TYPE_TKIP)
3907 MacAddr = CAM_CONST_BROAD;
3908 for(EntryId=1 ; EntryId<4 ; EntryId++)
3914 priv->ieee80211->group_key_type,
3920 if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
3924 priv->ieee80211->group_key_type,
3929 else if(priv->ieee80211->group_key_type == KEY_TYPE_CCMP)
3931 MacAddr = CAM_CONST_BROAD;
3932 for(EntryId=1; EntryId<4 ; EntryId++)
3938 priv->ieee80211->group_key_type,
3945 if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
3949 priv->ieee80211->group_key_type,
3955 //////////////////////////////////////////////////////////////
3956 // This function is used to fix Tx/Rx stop bug temporarily.
3957 // This function will do "system reset" to NIC when Tx or Rx is stuck.
3958 // The method checking Tx/Rx stuck of this function is supported by FW,
3959 // which reports Tx and Rx counter to register 0x128 and 0x130.
3960 //////////////////////////////////////////////////////////////
3962 rtl819x_ifsilentreset(struct net_device *dev)
3964 //OCTET_STRING asocpdu;
3965 struct r8192_priv *priv = ieee80211_priv(dev);
3967 int reset_status = 0;
3968 struct ieee80211_device *ieee = priv->ieee80211;
3971 // 2007.07.20. If we need to check CCK stop, please uncomment this line.
3972 //bStuck = Adapter->HalFunc.CheckHWStopHandler(Adapter);
3974 if(priv->ResetProgress==RESET_TYPE_NORESET)
3978 RT_TRACE(COMP_RESET,"=========>Reset progress!! \n");
3980 // Set the variable for reset.
3981 priv->ResetProgress = RESET_TYPE_SILENT;
3982 // rtl8192_close(dev);
3983 down(&priv->wx_sem);
3986 RT_TRACE(COMP_ERR,"%s():the driver is not up! return\n",__FUNCTION__);
3991 RT_TRACE(COMP_RESET,"%s():======>start to down the driver\n",__FUNCTION__);
3992 // if(!netif_queue_stopped(dev))
3993 // netif_stop_queue(dev);
3995 rtl8192_rtx_disable(dev);
3996 rtl8192_cancel_deferred_work(priv);
3998 del_timer_sync(&priv->watch_dog_timer);
4000 ieee->sync_scan_hurryup = 1;
4001 if(ieee->state == IEEE80211_LINKED)
4003 down(&ieee->wx_sem);
4004 printk("ieee->state is IEEE80211_LINKED\n");
4005 ieee80211_stop_send_beacons(priv->ieee80211);
4006 del_timer_sync(&ieee->associate_timer);
4007 cancel_delayed_work(&ieee->associate_retry_wq);
4008 ieee80211_stop_scan(ieee);
4009 netif_carrier_off(dev);
4013 printk("ieee->state is NOT LINKED\n");
4014 ieee80211_softmac_stop_protocol(priv->ieee80211); }
4016 RT_TRACE(COMP_RESET,"%s():<==========down process is finished\n",__FUNCTION__);
4017 //rtl8192_irq_disable(dev);
4018 RT_TRACE(COMP_RESET,"%s():===========>start to up the driver\n",__FUNCTION__);
4019 reset_status = _rtl8192_up(dev);
4021 RT_TRACE(COMP_RESET,"%s():<===========up process is finished\n",__FUNCTION__);
4022 if(reset_status == -EAGAIN)
4031 RT_TRACE(COMP_ERR," ERR!!! %s(): Reset Failed!!\n", __FUNCTION__);
4034 ieee->is_silent_reset = 1;
4035 EnableHWSecurityConfig8192(dev);
4036 if(ieee->state == IEEE80211_LINKED && ieee->iw_mode == IW_MODE_INFRA)
4038 ieee->set_chan(ieee->dev, ieee->current_network.channel);
4040 queue_work(ieee->wq, &ieee->associate_complete_wq);
4043 else if(ieee->state == IEEE80211_LINKED && ieee->iw_mode == IW_MODE_ADHOC)
4045 ieee->set_chan(ieee->dev, ieee->current_network.channel);
4046 ieee->link_change(ieee->dev);
4048 // notify_wx_assoc_event(ieee);
4050 ieee80211_start_send_beacons(ieee);
4052 if (ieee->data_hard_resume)
4053 ieee->data_hard_resume(ieee->dev);
4054 netif_carrier_on(ieee->dev);
4057 CamRestoreAllEntry(dev);
4059 priv->ResetProgress = RESET_TYPE_NORESET;
4060 priv->reset_count++;
4062 priv->bForcedSilentReset =false;
4063 priv->bResetInProgress = false;
4065 // For test --> force write UFWP.
4066 write_nic_byte(dev, UFWP, 1);
4067 RT_TRACE(COMP_RESET, "Reset finished!! ====>[%d]\n", priv->reset_count);
4071 void CAM_read_entry(
4072 struct net_device *dev,
4076 u32 target_command=0;
4077 u32 target_content=0;
4081 // printk("=======>start read CAM\n");
4082 for(entry_i=0;entry_i<CAM_CONTENT_COUNT;entry_i++)
4084 // polling bit, and No Write enable, and address
4085 target_command= entry_i+CAM_CONTENT_COUNT*iIndex;
4086 target_command= target_command | BIT31;
4088 //Check polling bit is clear
4092 ulStatus = read_nic_dword(dev, RWCAM);
4093 if(ulStatus & BIT31){
4100 write_nic_dword(dev, RWCAM, target_command);
4101 RT_TRACE(COMP_SEC,"CAM_read_entry(): WRITE A0: %x \n",target_command);
4102 // printk("CAM_read_entry(): WRITE A0: %lx \n",target_command);
4103 target_content = read_nic_dword(dev, RCAMO);
4104 RT_TRACE(COMP_SEC, "CAM_read_entry(): WRITE A8: %x \n",target_content);
4105 // printk("CAM_read_entry(): WRITE A8: %lx \n",target_content);
4110 void rtl819x_update_rxcounts(
4111 struct r8192_priv *priv,
4120 *TotalRxDataNum = 0;
4122 SlotIndex = (priv->ieee80211->LinkDetectInfo.SlotIndex++)%(priv->ieee80211->LinkDetectInfo.SlotNum);
4123 priv->ieee80211->LinkDetectInfo.RxBcnNum[SlotIndex] = priv->ieee80211->LinkDetectInfo.NumRecvBcnInPeriod;
4124 priv->ieee80211->LinkDetectInfo.RxDataNum[SlotIndex] = priv->ieee80211->LinkDetectInfo.NumRecvDataInPeriod;
4125 for( i=0; i<priv->ieee80211->LinkDetectInfo.SlotNum; i++ ){
4126 *TotalRxBcnNum += priv->ieee80211->LinkDetectInfo.RxBcnNum[i];
4127 *TotalRxDataNum += priv->ieee80211->LinkDetectInfo.RxDataNum[i];
4132 extern void rtl819x_watchdog_wqcallback(struct work_struct *work)
4134 struct delayed_work *dwork = container_of(work,struct delayed_work,work);
4135 struct r8192_priv *priv = container_of(dwork,struct r8192_priv,watch_dog_wq);
4136 struct net_device *dev = priv->ieee80211->dev;
4137 struct ieee80211_device* ieee = priv->ieee80211;
4138 RESET_TYPE ResetType = RESET_TYPE_NORESET;
4139 static u8 check_reset_cnt=0;
4140 bool bBusyTraffic = false;
4144 hal_dm_watchdog(dev);
4146 {//to get busy traffic condition
4147 if(ieee->state == IEEE80211_LINKED)
4149 if( ieee->LinkDetectInfo.NumRxOkInPeriod> 666 ||
4150 ieee->LinkDetectInfo.NumTxOkInPeriod> 666 ) {
4151 bBusyTraffic = true;
4153 ieee->LinkDetectInfo.NumRxOkInPeriod = 0;
4154 ieee->LinkDetectInfo.NumTxOkInPeriod = 0;
4155 ieee->LinkDetectInfo.bBusyTraffic = bBusyTraffic;
4158 //added by amy for AP roaming
4160 if(priv->ieee80211->state == IEEE80211_LINKED && priv->ieee80211->iw_mode == IW_MODE_INFRA)
4162 u32 TotalRxBcnNum = 0;
4163 u32 TotalRxDataNum = 0;
4165 rtl819x_update_rxcounts(priv, &TotalRxBcnNum, &TotalRxDataNum);
4166 if((TotalRxBcnNum+TotalRxDataNum) == 0)
4169 if(rfState == eRfOff)
4170 RT_TRACE(COMP_ERR,"========>%s()\n",__FUNCTION__);
4172 printk("===>%s(): AP is power off,connect another one\n",__FUNCTION__);
4173 // Dot11d_Reset(dev);
4174 priv->ieee80211->state = IEEE80211_ASSOCIATING;
4175 notify_wx_assoc_event(priv->ieee80211);
4176 RemovePeerTS(priv->ieee80211,priv->ieee80211->current_network.bssid);
4177 priv->ieee80211->link_change(dev);
4178 queue_work(priv->ieee80211->wq, &priv->ieee80211->associate_procedure_wq);
4182 priv->ieee80211->LinkDetectInfo.NumRecvBcnInPeriod=0;
4183 priv->ieee80211->LinkDetectInfo.NumRecvDataInPeriod=0;
4185 // CAM_read_entry(dev,4);
4186 //check if reset the driver
4187 if(check_reset_cnt++ >= 3)
4189 ResetType = rtl819x_ifcheck_resetornot(dev);
4190 check_reset_cnt = 3;
4191 //DbgPrint("Start to check silent reset\n");
4193 // RT_TRACE(COMP_RESET,"%s():priv->force_reset is %d,priv->ResetProgress is %d, priv->bForcedSilentReset is %d,priv->bDisableNormalResetCheck is %d,ResetType is %d\n",__FUNCTION__,priv->force_reset,priv->ResetProgress,priv->bForcedSilentReset,priv->bDisableNormalResetCheck,ResetType);
4194 if( (priv->force_reset) || (priv->ResetProgress==RESET_TYPE_NORESET &&
4195 (priv->bForcedSilentReset ||
4196 (!priv->bDisableNormalResetCheck && ResetType==RESET_TYPE_SILENT)))) // This is control by OID set in Pomelo
4198 RT_TRACE(COMP_RESET,"%s():priv->force_reset is %d,priv->ResetProgress is %d, priv->bForcedSilentReset is %d,priv->bDisableNormalResetCheck is %d,ResetType is %d\n",__FUNCTION__,priv->force_reset,priv->ResetProgress,priv->bForcedSilentReset,priv->bDisableNormalResetCheck,ResetType);
4199 rtl819x_ifsilentreset(dev);
4201 priv->force_reset = false;
4202 priv->bForcedSilentReset = false;
4203 priv->bResetInProgress = false;
4204 RT_TRACE(COMP_TRACE, " <==RtUsbCheckForHangWorkItemCallback()\n");
4208 void watch_dog_timer_callback(unsigned long data)
4210 struct r8192_priv *priv = ieee80211_priv((struct net_device *) data);
4211 //printk("===============>watch_dog timer\n");
4212 queue_delayed_work(priv->priv_wq,&priv->watch_dog_wq, 0);
4213 mod_timer(&priv->watch_dog_timer, jiffies + MSECS(IEEE80211_WATCH_DOG_TIME));
4215 int _rtl8192_up(struct net_device *dev)
4217 struct r8192_priv *priv = ieee80211_priv(dev);
4219 int init_status = 0;
4221 priv->ieee80211->ieee_up=1;
4222 RT_TRACE(COMP_INIT, "Bringing up iface");
4223 init_status = rtl8192_adapter_start(dev);
4226 RT_TRACE(COMP_ERR,"ERR!!! %s(): initialization is failed!\n", __FUNCTION__);
4227 priv->up=priv->ieee80211->ieee_up = 0;
4230 RT_TRACE(COMP_INIT, "start adapter finished\n");
4231 rtl8192_rx_enable(dev);
4232 // rtl8192_tx_enable(dev);
4233 if(priv->ieee80211->state != IEEE80211_LINKED)
4234 ieee80211_softmac_start_protocol(priv->ieee80211);
4235 ieee80211_reset_queue(priv->ieee80211);
4236 watch_dog_timer_callback((unsigned long) dev);
4237 if(!netif_queue_stopped(dev))
4238 netif_start_queue(dev);
4240 netif_wake_queue(dev);
4246 int rtl8192_open(struct net_device *dev)
4248 struct r8192_priv *priv = ieee80211_priv(dev);
4250 down(&priv->wx_sem);
4251 ret = rtl8192_up(dev);
4258 int rtl8192_up(struct net_device *dev)
4260 struct r8192_priv *priv = ieee80211_priv(dev);
4262 if (priv->up == 1) return -1;
4264 return _rtl8192_up(dev);
4268 int rtl8192_close(struct net_device *dev)
4270 struct r8192_priv *priv = ieee80211_priv(dev);
4273 down(&priv->wx_sem);
4275 ret = rtl8192_down(dev);
4283 int rtl8192_down(struct net_device *dev)
4285 struct r8192_priv *priv = ieee80211_priv(dev);
4288 if (priv->up == 0) return -1;
4291 priv->ieee80211->ieee_up = 0;
4292 RT_TRACE(COMP_DOWN, "==========>%s()\n", __FUNCTION__);
4294 if (!netif_queue_stopped(dev))
4295 netif_stop_queue(dev);
4297 rtl8192_rtx_disable(dev);
4298 //rtl8192_irq_disable(dev);
4300 /* Tx related queue release */
4301 for(i = 0; i < MAX_QUEUE_SIZE; i++) {
4302 skb_queue_purge(&priv->ieee80211->skb_waitQ [i]);
4304 for(i = 0; i < MAX_QUEUE_SIZE; i++) {
4305 skb_queue_purge(&priv->ieee80211->skb_aggQ [i]);
4308 for(i = 0; i < MAX_QUEUE_SIZE; i++) {
4309 skb_queue_purge(&priv->ieee80211->skb_drv_aggQ [i]);
4312 //as cancel_delayed_work will del work->timer, so if work is not definedas struct delayed_work, it will corrupt
4313 // flush_scheduled_work();
4314 rtl8192_cancel_deferred_work(priv);
4316 del_timer_sync(&priv->watch_dog_timer);
4319 ieee80211_softmac_stop_protocol(priv->ieee80211);
4320 memset(&priv->ieee80211->current_network, 0 , offsetof(struct ieee80211_network, list));
4321 RT_TRACE(COMP_DOWN, "<==========%s()\n", __FUNCTION__);
4327 void rtl8192_commit(struct net_device *dev)
4329 struct r8192_priv *priv = ieee80211_priv(dev);
4330 int reset_status = 0;
4331 //u8 reset_times = 0;
4332 if (priv->up == 0) return ;
4335 rtl8192_cancel_deferred_work(priv);
4336 del_timer_sync(&priv->watch_dog_timer);
4337 //cancel_delayed_work(&priv->SwChnlWorkItem);
4339 ieee80211_softmac_stop_protocol(priv->ieee80211);
4341 //rtl8192_irq_disable(dev);
4342 rtl8192_rtx_disable(dev);
4343 reset_status = _rtl8192_up(dev);
4348 void rtl8192_restart(struct net_device *dev)
4350 struct r8192_priv *priv = ieee80211_priv(dev);
4352 void rtl8192_restart(struct work_struct *work)
4354 struct r8192_priv *priv = container_of(work, struct r8192_priv, reset_wq);
4355 struct net_device *dev = priv->ieee80211->dev;
4357 down(&priv->wx_sem);
4359 rtl8192_commit(dev);
4364 static void r8192_set_multicast(struct net_device *dev)
4366 struct r8192_priv *priv = ieee80211_priv(dev);
4369 //down(&priv->wx_sem);
4373 promisc = (dev->flags & IFF_PROMISC) ? 1:0;
4375 if (promisc != priv->promisc)
4376 // rtl8192_commit(dev);
4378 priv->promisc = promisc;
4380 //schedule_work(&priv->reset_wq);
4381 //up(&priv->wx_sem);
4385 int r8192_set_mac_adr(struct net_device *dev, void *mac)
4387 struct r8192_priv *priv = ieee80211_priv(dev);
4388 struct sockaddr *addr = mac;
4390 down(&priv->wx_sem);
4392 memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
4394 schedule_work(&priv->reset_wq);
4400 /* based on ipw2200 driver */
4401 int rtl8192_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
4403 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
4404 struct iwreq *wrq = (struct iwreq *)rq;
4406 struct ieee80211_device *ieee = priv->ieee80211;
4408 u8 broadcast_addr[6] = {0xff,0xff,0xff,0xff,0xff,0xff};
4409 struct iw_point *p = &wrq->u.data;
4410 struct ieee_param *ipw = NULL;//(struct ieee_param *)wrq->u.data.pointer;
4412 down(&priv->wx_sem);
4415 if (p->length < sizeof(struct ieee_param) || !p->pointer){
4420 ipw = kmalloc(p->length, GFP_KERNEL);
4425 if (copy_from_user(ipw, p->pointer, p->length)) {
4432 case RTL_IOCTL_WPA_SUPPLICANT:
4433 //parse here for HW security
4434 if (ipw->cmd == IEEE_CMD_SET_ENCRYPTION)
4436 if (ipw->u.crypt.set_tx)
4438 if (strcmp(ipw->u.crypt.alg, "CCMP") == 0)
4439 ieee->pairwise_key_type = KEY_TYPE_CCMP;
4440 else if (strcmp(ipw->u.crypt.alg, "TKIP") == 0)
4441 ieee->pairwise_key_type = KEY_TYPE_TKIP;
4442 else if (strcmp(ipw->u.crypt.alg, "WEP") == 0)
4444 if (ipw->u.crypt.key_len == 13)
4445 ieee->pairwise_key_type = KEY_TYPE_WEP104;
4446 else if (ipw->u.crypt.key_len == 5)
4447 ieee->pairwise_key_type = KEY_TYPE_WEP40;
4450 ieee->pairwise_key_type = KEY_TYPE_NA;
4452 if (ieee->pairwise_key_type)
4454 memcpy((u8*)key, ipw->u.crypt.key, 16);
4455 EnableHWSecurityConfig8192(dev);
4456 //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!
4458 setKey(dev, 4, ipw->u.crypt.idx, ieee->pairwise_key_type, (u8*)ieee->ap_mac_addr, 0, key);
4459 if (ieee->auth_mode != 2)
4460 setKey(dev, ipw->u.crypt.idx, ipw->u.crypt.idx, ieee->pairwise_key_type, (u8*)ieee->ap_mac_addr, 0, key);
4463 else //if (ipw->u.crypt.idx) //group key use idx > 0
4465 memcpy((u8*)key, ipw->u.crypt.key, 16);
4466 if (strcmp(ipw->u.crypt.alg, "CCMP") == 0)
4467 ieee->group_key_type= KEY_TYPE_CCMP;
4468 else if (strcmp(ipw->u.crypt.alg, "TKIP") == 0)
4469 ieee->group_key_type = KEY_TYPE_TKIP;
4470 else if (strcmp(ipw->u.crypt.alg, "WEP") == 0)
4472 if (ipw->u.crypt.key_len == 13)
4473 ieee->group_key_type = KEY_TYPE_WEP104;
4474 else if (ipw->u.crypt.key_len == 5)
4475 ieee->group_key_type = KEY_TYPE_WEP40;
4478 ieee->group_key_type = KEY_TYPE_NA;
4480 if (ieee->group_key_type)
4484 ipw->u.crypt.idx, //KeyIndex
4485 ieee->group_key_type, //KeyType
4486 broadcast_addr, //MacAddr
4492 #ifdef JOHN_HWSEC_DEBUG
4494 printk("@@ wrq->u pointer = ");
4495 for(i=0;i<wrq->u.data.length;i++){
4496 if(i%10==0) printk("\n");
4497 printk( "%8x|", ((u32*)wrq->u.data.pointer)[i] );
4500 #endif /*JOHN_HWSEC_DEBUG*/
4501 ret = ieee80211_wpa_supplicant_ioctl(priv->ieee80211, &wrq->u.data);
4515 u8 HwRateToMRate90(bool bIsHT, u8 rate)
4521 case DESC90_RATE1M: ret_rate = MGN_1M; break;
4522 case DESC90_RATE2M: ret_rate = MGN_2M; break;
4523 case DESC90_RATE5_5M: ret_rate = MGN_5_5M; break;
4524 case DESC90_RATE11M: ret_rate = MGN_11M; break;
4525 case DESC90_RATE6M: ret_rate = MGN_6M; break;
4526 case DESC90_RATE9M: ret_rate = MGN_9M; break;
4527 case DESC90_RATE12M: ret_rate = MGN_12M; break;
4528 case DESC90_RATE18M: ret_rate = MGN_18M; break;
4529 case DESC90_RATE24M: ret_rate = MGN_24M; break;
4530 case DESC90_RATE36M: ret_rate = MGN_36M; break;
4531 case DESC90_RATE48M: ret_rate = MGN_48M; break;
4532 case DESC90_RATE54M: ret_rate = MGN_54M; break;
4536 RT_TRACE(COMP_RECV, "HwRateToMRate90(): Non supported Rate [%x], bIsHT = %d!!!\n", rate, bIsHT);
4542 case DESC90_RATEMCS0: ret_rate = MGN_MCS0; break;
4543 case DESC90_RATEMCS1: ret_rate = MGN_MCS1; break;
4544 case DESC90_RATEMCS2: ret_rate = MGN_MCS2; break;
4545 case DESC90_RATEMCS3: ret_rate = MGN_MCS3; break;
4546 case DESC90_RATEMCS4: ret_rate = MGN_MCS4; break;
4547 case DESC90_RATEMCS5: ret_rate = MGN_MCS5; break;
4548 case DESC90_RATEMCS6: ret_rate = MGN_MCS6; break;
4549 case DESC90_RATEMCS7: ret_rate = MGN_MCS7; break;
4550 case DESC90_RATEMCS8: ret_rate = MGN_MCS8; break;
4551 case DESC90_RATEMCS9: ret_rate = MGN_MCS9; break;
4552 case DESC90_RATEMCS10: ret_rate = MGN_MCS10; break;
4553 case DESC90_RATEMCS11: ret_rate = MGN_MCS11; break;
4554 case DESC90_RATEMCS12: ret_rate = MGN_MCS12; break;
4555 case DESC90_RATEMCS13: ret_rate = MGN_MCS13; break;
4556 case DESC90_RATEMCS14: ret_rate = MGN_MCS14; break;
4557 case DESC90_RATEMCS15: ret_rate = MGN_MCS15; break;
4558 case DESC90_RATEMCS32: ret_rate = (0x80|0x20); break;
4562 RT_TRACE(COMP_RECV, "HwRateToMRate90(): Non supported Rate [%x], bIsHT = %d!!!\n",rate, bIsHT);
4571 * Function: UpdateRxPktTimeStamp
4572 * Overview: Recored down the TSF time stamp when receiving a packet
4580 * (pRfd->Status.TimeStampHigh is updated)
4581 * (pRfd->Status.TimeStampLow is updated)
4585 void UpdateRxPktTimeStamp8190 (struct net_device *dev, struct ieee80211_rx_stats *stats)
4587 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
4589 if(stats->bIsAMPDU && !stats->bFirstMPDU) {
4590 stats->mac_time[0] = priv->LastRxDescTSFLow;
4591 stats->mac_time[1] = priv->LastRxDescTSFHigh;
4593 priv->LastRxDescTSFLow = stats->mac_time[0];
4594 priv->LastRxDescTSFHigh = stats->mac_time[1];
4600 long rtl819x_translate_todbm(u8 signal_strength_index )// 0-100 index.
4602 long signal_power; // in dBm.
4604 // Translate to dBm (x=0.5y-95).
4605 signal_power = (long)((signal_strength_index + 1) >> 1);
4608 return signal_power;
4612 /* 2008/01/22 MH We can not delcare RSSI/EVM total value of sliding window to
4613 be a local static. Otherwise, it may increase when we return from S3/S4. The
4614 value will be kept in memory or disk. We must delcare the value in adapter
4615 and it will be reinitialized when return from S3/S4. */
4616 void rtl8192_process_phyinfo(struct r8192_priv * priv,u8* buffer, struct ieee80211_rx_stats * pprevious_stats, struct ieee80211_rx_stats * pcurrent_stats)
4618 bool bcheck = false;
4620 u32 nspatial_stream, tmp_val;
4622 static u32 slide_rssi_index=0, slide_rssi_statistics=0;
4623 static u32 slide_evm_index=0, slide_evm_statistics=0;
4624 static u32 last_rssi=0, last_evm=0;
4626 static u32 slide_beacon_adc_pwdb_index=0, slide_beacon_adc_pwdb_statistics=0;
4627 static u32 last_beacon_adc_pwdb=0;
4629 struct ieee80211_hdr_3addr *hdr;
4631 unsigned int frag,seq;
4632 hdr = (struct ieee80211_hdr_3addr *)buffer;
4633 sc = le16_to_cpu(hdr->seq_ctl);
4634 frag = WLAN_GET_SEQ_FRAG(sc);
4635 seq = WLAN_GET_SEQ_SEQ(sc);
4636 //cosa add 04292008 to record the sequence number
4637 pcurrent_stats->Seq_Num = seq;
4639 // Check whether we should take the previous packet into accounting
4641 if(!pprevious_stats->bIsAMPDU)
4643 // if previous packet is not aggregated packet
4650 if(slide_rssi_statistics++ >= PHY_RSSI_SLID_WIN_MAX)
4652 slide_rssi_statistics = PHY_RSSI_SLID_WIN_MAX;
4653 last_rssi = priv->stats.slide_signal_strength[slide_rssi_index];
4654 priv->stats.slide_rssi_total -= last_rssi;
4656 priv->stats.slide_rssi_total += pprevious_stats->SignalStrength;
4658 priv->stats.slide_signal_strength[slide_rssi_index++] = pprevious_stats->SignalStrength;
4659 if(slide_rssi_index >= PHY_RSSI_SLID_WIN_MAX)
4660 slide_rssi_index = 0;
4662 // <1> Showed on UI for user, in dbm
4663 tmp_val = priv->stats.slide_rssi_total/slide_rssi_statistics;
4664 priv->stats.signal_strength = rtl819x_translate_todbm((u8)tmp_val);
4665 pcurrent_stats->rssi = priv->stats.signal_strength;
4667 // If the previous packet does not match the criteria, neglect it
4669 if(!pprevious_stats->bPacketMatchBSSID)
4671 if(!pprevious_stats->bToSelfBA)
4679 //rtl8190_process_cck_rxpathsel(priv,pprevious_stats);//only rtl8190 supported
4684 priv->stats.num_process_phyinfo++;
4686 /* record the general signal strength to the sliding window. */
4689 // <2> Showed on UI for engineering
4690 // hardware does not provide rssi information for each rf path in CCK
4691 if(!pprevious_stats->bIsCCK && (pprevious_stats->bPacketToSelf || pprevious_stats->bToSelfBA))
4693 for (rfpath = RF90_PATH_A; rfpath < priv->NumTotalRFPath; rfpath++)
4695 if (!rtl8192_phy_CheckIsLegalRFPath(priv->ieee80211->dev, rfpath))
4698 //Fixed by Jacken 2008-03-20
4699 if(priv->stats.rx_rssi_percentage[rfpath] == 0)
4701 priv->stats.rx_rssi_percentage[rfpath] = pprevious_stats->RxMIMOSignalStrength[rfpath];
4702 //DbgPrint("MIMO RSSI initialize \n");
4704 if(pprevious_stats->RxMIMOSignalStrength[rfpath] > priv->stats.rx_rssi_percentage[rfpath])
4706 priv->stats.rx_rssi_percentage[rfpath] =
4707 ( (priv->stats.rx_rssi_percentage[rfpath]*(Rx_Smooth_Factor-1)) +
4708 (pprevious_stats->RxMIMOSignalStrength[rfpath])) /(Rx_Smooth_Factor);
4709 priv->stats.rx_rssi_percentage[rfpath] = priv->stats.rx_rssi_percentage[rfpath] + 1;
4713 priv->stats.rx_rssi_percentage[rfpath] =
4714 ( (priv->stats.rx_rssi_percentage[rfpath]*(Rx_Smooth_Factor-1)) +
4715 (pprevious_stats->RxMIMOSignalStrength[rfpath])) /(Rx_Smooth_Factor);
4717 RT_TRACE(COMP_DBG,"priv->stats.rx_rssi_percentage[rfPath] = %d \n" ,priv->stats.rx_rssi_percentage[rfpath] );
4725 RT_TRACE(COMP_RXDESC, "Smooth %s PWDB = %d\n",
4726 pprevious_stats->bIsCCK? "CCK": "OFDM",
4727 pprevious_stats->RxPWDBAll);
4729 if(pprevious_stats->bPacketBeacon)
4731 /* record the beacon pwdb to the sliding window. */
4732 if(slide_beacon_adc_pwdb_statistics++ >= PHY_Beacon_RSSI_SLID_WIN_MAX)
4734 slide_beacon_adc_pwdb_statistics = PHY_Beacon_RSSI_SLID_WIN_MAX;
4735 last_beacon_adc_pwdb = priv->stats.Slide_Beacon_pwdb[slide_beacon_adc_pwdb_index];
4736 priv->stats.Slide_Beacon_Total -= last_beacon_adc_pwdb;
4737 //DbgPrint("slide_beacon_adc_pwdb_index = %d, last_beacon_adc_pwdb = %d, Adapter->RxStats.Slide_Beacon_Total = %d\n",
4738 // slide_beacon_adc_pwdb_index, last_beacon_adc_pwdb, Adapter->RxStats.Slide_Beacon_Total);
4740 priv->stats.Slide_Beacon_Total += pprevious_stats->RxPWDBAll;
4741 priv->stats.Slide_Beacon_pwdb[slide_beacon_adc_pwdb_index] = pprevious_stats->RxPWDBAll;
4742 //DbgPrint("slide_beacon_adc_pwdb_index = %d, pPreviousRfd->Status.RxPWDBAll = %d\n", slide_beacon_adc_pwdb_index, pPreviousRfd->Status.RxPWDBAll);
4743 slide_beacon_adc_pwdb_index++;
4744 if(slide_beacon_adc_pwdb_index >= PHY_Beacon_RSSI_SLID_WIN_MAX)
4745 slide_beacon_adc_pwdb_index = 0;
4746 pprevious_stats->RxPWDBAll = priv->stats.Slide_Beacon_Total/slide_beacon_adc_pwdb_statistics;
4747 if(pprevious_stats->RxPWDBAll >= 3)
4748 pprevious_stats->RxPWDBAll -= 3;
4751 RT_TRACE(COMP_RXDESC, "Smooth %s PWDB = %d\n",
4752 pprevious_stats->bIsCCK? "CCK": "OFDM",
4753 pprevious_stats->RxPWDBAll);
4756 if(pprevious_stats->bPacketToSelf || pprevious_stats->bPacketBeacon || pprevious_stats->bToSelfBA)
4758 if(priv->undecorated_smoothed_pwdb < 0) // initialize
4760 priv->undecorated_smoothed_pwdb = pprevious_stats->RxPWDBAll;
4761 //DbgPrint("First pwdb initialize \n");
4763 if(pprevious_stats->RxPWDBAll > (u32)priv->undecorated_smoothed_pwdb)
4765 priv->undecorated_smoothed_pwdb =
4766 ( ((priv->undecorated_smoothed_pwdb)*(Rx_Smooth_Factor-1)) +
4767 (pprevious_stats->RxPWDBAll)) /(Rx_Smooth_Factor);
4768 priv->undecorated_smoothed_pwdb = priv->undecorated_smoothed_pwdb + 1;
4772 priv->undecorated_smoothed_pwdb =
4773 ( ((priv->undecorated_smoothed_pwdb)*(Rx_Smooth_Factor-1)) +
4774 (pprevious_stats->RxPWDBAll)) /(Rx_Smooth_Factor);
4782 /* record the general EVM to the sliding window. */
4783 if(pprevious_stats->SignalQuality == 0)
4788 if(pprevious_stats->bPacketToSelf || pprevious_stats->bPacketBeacon || pprevious_stats->bToSelfBA){
4789 if(slide_evm_statistics++ >= PHY_RSSI_SLID_WIN_MAX){
4790 slide_evm_statistics = PHY_RSSI_SLID_WIN_MAX;
4791 last_evm = priv->stats.slide_evm[slide_evm_index];
4792 priv->stats.slide_evm_total -= last_evm;
4795 priv->stats.slide_evm_total += pprevious_stats->SignalQuality;
4797 priv->stats.slide_evm[slide_evm_index++] = pprevious_stats->SignalQuality;
4798 if(slide_evm_index >= PHY_RSSI_SLID_WIN_MAX)
4799 slide_evm_index = 0;
4801 // <1> Showed on UI for user, in percentage.
4802 tmp_val = priv->stats.slide_evm_total/slide_evm_statistics;
4803 priv->stats.signal_quality = tmp_val;
4804 //cosa add 10/11/2007, Showed on UI for user in Windows Vista, for Link quality.
4805 priv->stats.last_signal_strength_inpercent = tmp_val;
4808 // <2> Showed on UI for engineering
4809 if(pprevious_stats->bPacketToSelf || pprevious_stats->bPacketBeacon || pprevious_stats->bToSelfBA)
4811 for(nspatial_stream = 0; nspatial_stream<2 ; nspatial_stream++) // 2 spatial stream
4813 if(pprevious_stats->RxMIMOSignalQuality[nspatial_stream] != -1)
4815 if(priv->stats.rx_evm_percentage[nspatial_stream] == 0) // initialize
4817 priv->stats.rx_evm_percentage[nspatial_stream] = pprevious_stats->RxMIMOSignalQuality[nspatial_stream];
4819 priv->stats.rx_evm_percentage[nspatial_stream] =
4820 ( (priv->stats.rx_evm_percentage[nspatial_stream]* (Rx_Smooth_Factor-1)) +
4821 (pprevious_stats->RxMIMOSignalQuality[nspatial_stream]* 1)) / (Rx_Smooth_Factor);
4830 /*-----------------------------------------------------------------------------
4831 * Function: rtl819x_query_rxpwrpercentage()
4835 * Input: char antpower
4839 * Return: 0-100 percentage
4843 * 05/26/2008 amy Create Version 0 porting from windows code.
4845 *---------------------------------------------------------------------------*/
4846 static u8 rtl819x_query_rxpwrpercentage(
4850 if ((antpower <= -100) || (antpower >= 20))
4854 else if (antpower >= 0)
4860 return (100+antpower);
4863 } /* QueryRxPwrPercentage */
4866 rtl819x_evm_dbtopercentage(
4878 ret_val = 0 - ret_val;
4886 // We want good-looking for signal strength/quality
4887 // 2007/7/19 01:09, by cosa.
4890 rtl819x_signal_scale_mapping(
4896 // Step 1. Scale mapping.
4897 if(currsig >= 61 && currsig <= 100)
4899 retsig = 90 + ((currsig - 60) / 4);
4901 else if(currsig >= 41 && currsig <= 60)
4903 retsig = 78 + ((currsig - 40) / 2);
4905 else if(currsig >= 31 && currsig <= 40)
4907 retsig = 66 + (currsig - 30);
4909 else if(currsig >= 21 && currsig <= 30)
4911 retsig = 54 + (currsig - 20);
4913 else if(currsig >= 5 && currsig <= 20)
4915 retsig = 42 + (((currsig - 5) * 2) / 3);
4917 else if(currsig == 4)
4921 else if(currsig == 3)
4925 else if(currsig == 2)
4929 else if(currsig == 1)
4941 static void rtl8192_query_rxphystatus(
4942 struct r8192_priv * priv,
4943 struct ieee80211_rx_stats * pstats,
4944 rx_drvinfo_819x_usb * pdrvinfo,
4945 struct ieee80211_rx_stats * precord_stats,
4946 bool bpacket_match_bssid,
4947 bool bpacket_toself,
4952 //PRT_RFD_STATUS pRtRfdStatus = &(pRfd->Status);
4953 phy_sts_ofdm_819xusb_t* pofdm_buf;
4954 phy_sts_cck_819xusb_t * pcck_buf;
4955 phy_ofdm_rx_status_rxsc_sgien_exintfflag* prxsc;
4957 u8 i, max_spatial_stream, tmp_rxsnr, tmp_rxevm, rxsc_sgien_exflg;
4958 char rx_pwr[4], rx_pwr_all=0;
4959 //long rx_avg_pwr = 0;
4960 char rx_snrX, rx_evmX;
4962 u32 RSSI, total_rssi=0;//, total_evm=0;
4963 // long signal_strength_index = 0;
4968 priv->stats.numqry_phystatus++;
4970 is_cck_rate = rx_hal_is_cck_rate(pdrvinfo);
4972 // Record it for next packet processing
4973 memset(precord_stats, 0, sizeof(struct ieee80211_rx_stats));
4974 pstats->bPacketMatchBSSID = precord_stats->bPacketMatchBSSID = bpacket_match_bssid;
4975 pstats->bPacketToSelf = precord_stats->bPacketToSelf = bpacket_toself;
4976 pstats->bIsCCK = precord_stats->bIsCCK = is_cck_rate;//RX_HAL_IS_CCK_RATE(pDrvInfo);
4977 pstats->bPacketBeacon = precord_stats->bPacketBeacon = bPacketBeacon;
4978 pstats->bToSelfBA = precord_stats->bToSelfBA = bToSelfBA;
4980 prxpkt = (u8*)pdrvinfo;
4982 /* Move pointer to the 16th bytes. Phy status start address. */
4983 prxpkt += sizeof(rx_drvinfo_819x_usb);
4985 /* Initial the cck and ofdm buffer pointer */
4986 pcck_buf = (phy_sts_cck_819xusb_t *)prxpkt;
4987 pofdm_buf = (phy_sts_ofdm_819xusb_t *)prxpkt;
4989 pstats->RxMIMOSignalQuality[0] = -1;
4990 pstats->RxMIMOSignalQuality[1] = -1;
4991 precord_stats->RxMIMOSignalQuality[0] = -1;
4992 precord_stats->RxMIMOSignalQuality[1] = -1;
4997 // (1)Hardware does not provide RSSI for CCK
5001 // (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive)
5003 u8 report;//, cck_agc_rpt;
5005 priv->stats.numqry_phystatusCCK++;
5007 if(!priv->bCckHighPower)
5009 report = pcck_buf->cck_agc_rpt & 0xc0;
5013 //Fixed by Jacken from Bryant 2008-03-20
5014 //Original value is -38 , -26 , -14 , -2
5015 //Fixed value is -35 , -23 , -11 , 6
5017 rx_pwr_all = -35 - (pcck_buf->cck_agc_rpt & 0x3e);
5020 rx_pwr_all = -23 - (pcck_buf->cck_agc_rpt & 0x3e);
5023 rx_pwr_all = -11 - (pcck_buf->cck_agc_rpt & 0x3e);
5026 rx_pwr_all = 6 - (pcck_buf->cck_agc_rpt & 0x3e);
5032 report = pcck_buf->cck_agc_rpt & 0x60;
5037 rx_pwr_all = -35 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1) ;
5040 rx_pwr_all = -23 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1);
5043 rx_pwr_all = -11 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1) ;
5046 rx_pwr_all = 6 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1) ;
5051 pwdb_all = rtl819x_query_rxpwrpercentage(rx_pwr_all);
5052 pstats->RxPWDBAll = precord_stats->RxPWDBAll = pwdb_all;
5053 pstats->RecvSignalPower = pwdb_all;
5056 // (3) Get Signal Quality (EVM)
5058 //if(bpacket_match_bssid)
5062 if(pstats->RxPWDBAll > 40)
5067 sq = pcck_buf->sq_rpt;
5069 if(pcck_buf->sq_rpt > 64)
5071 else if (pcck_buf->sq_rpt < 20)
5074 sq = ((64-sq) * 100) / 44;
5076 pstats->SignalQuality = precord_stats->SignalQuality = sq;
5077 pstats->RxMIMOSignalQuality[0] = precord_stats->RxMIMOSignalQuality[0] = sq;
5078 pstats->RxMIMOSignalQuality[1] = precord_stats->RxMIMOSignalQuality[1] = -1;
5083 priv->stats.numqry_phystatusHT++;
5085 // (1)Get RSSI for HT rate
5087 for(i=RF90_PATH_A; i<priv->NumTotalRFPath; i++)
5089 // 2008/01/30 MH we will judge RF RX path now.
5090 if (priv->brfpath_rxenable[i])
5095 if (!rtl8192_phy_CheckIsLegalRFPath(priv->ieee80211->dev, i))
5098 //Fixed by Jacken from Bryant 2008-03-20
5099 //Original value is 106
5100 rx_pwr[i] = ((pofdm_buf->trsw_gain_X[i]&0x3F)*2) - 106;
5102 //Get Rx snr value in DB
5103 tmp_rxsnr = pofdm_buf->rxsnr_X[i];
5104 rx_snrX = (char)(tmp_rxsnr);
5107 priv->stats.rxSNRdB[i] = (long)rx_snrX;
5109 /* Translate DBM to percentage. */
5110 RSSI = rtl819x_query_rxpwrpercentage(rx_pwr[i]);
5113 /* Record Signal Strength for next packet */
5114 //if(bpacket_match_bssid)
5116 pstats->RxMIMOSignalStrength[i] =(u8) RSSI;
5117 precord_stats->RxMIMOSignalStrength[i] =(u8) RSSI;
5123 // (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive)
5125 //Fixed by Jacken from Bryant 2008-03-20
5126 //Original value is 106
5127 rx_pwr_all = (((pofdm_buf->pwdb_all ) >> 1 )& 0x7f) -106;
5128 pwdb_all = rtl819x_query_rxpwrpercentage(rx_pwr_all);
5130 pstats->RxPWDBAll = precord_stats->RxPWDBAll = pwdb_all;
5131 pstats->RxPower = precord_stats->RxPower = rx_pwr_all;
5134 // (3)EVM of HT rate
5136 if(pdrvinfo->RxHT && pdrvinfo->RxRate>=DESC90_RATEMCS8 &&
5137 pdrvinfo->RxRate<=DESC90_RATEMCS15)
5138 max_spatial_stream = 2; //both spatial stream make sense
5140 max_spatial_stream = 1; //only spatial stream 1 makes sense
5142 for(i=0; i<max_spatial_stream; i++)
5144 tmp_rxevm = pofdm_buf->rxevm_X[i];
5145 rx_evmX = (char)(tmp_rxevm);
5147 // Do not use shift operation like "rx_evmX >>= 1" because the compilor of free build environment
5148 // fill most significant bit to "zero" when doing shifting operation which may change a negative
5149 // value to positive one, then the dbm value (which is supposed to be negative) is not correct anymore.
5152 evm = rtl819x_evm_dbtopercentage(rx_evmX);
5153 //if(bpacket_match_bssid)
5155 if(i==0) // Fill value in RFD, Get the first spatial stream only
5156 pstats->SignalQuality = precord_stats->SignalQuality = (u8)(evm & 0xff);
5157 pstats->RxMIMOSignalQuality[i] = precord_stats->RxMIMOSignalQuality[i] = (u8)(evm & 0xff);
5162 /* record rx statistics for debug */
5163 rxsc_sgien_exflg = pofdm_buf->rxsc_sgien_exflg;
5164 prxsc = (phy_ofdm_rx_status_rxsc_sgien_exintfflag *)&rxsc_sgien_exflg;
5165 if(pdrvinfo->BW) //40M channel
5166 priv->stats.received_bwtype[1+prxsc->rxsc]++;
5168 priv->stats.received_bwtype[0]++;
5171 //UI BSS List signal strength(in percentage), make it good looking, from 0~100.
5172 //It is assigned to the BSS List in GetValueFromBeaconOrProbeRsp().
5175 pstats->SignalStrength = precord_stats->SignalStrength = (u8)(rtl819x_signal_scale_mapping((long)pwdb_all));//PWDB_ALL;
5180 //pRfd->Status.SignalStrength = pRecordRfd->Status.SignalStrength = (u8)(SignalScaleMapping(total_rssi/=RF90_PATH_MAX));//(u8)(total_rssi/=RF90_PATH_MAX);
5181 // We can judge RX path number now.
5183 pstats->SignalStrength = precord_stats->SignalStrength = (u8)(rtl819x_signal_scale_mapping((long)(total_rssi/=rf_rx_num)));
5185 } /* QueryRxPhyStatus8190Pci */
5188 rtl8192_record_rxdesc_forlateruse(
5189 struct ieee80211_rx_stats * psrc_stats,
5190 struct ieee80211_rx_stats * ptarget_stats
5193 ptarget_stats->bIsAMPDU = psrc_stats->bIsAMPDU;
5194 ptarget_stats->bFirstMPDU = psrc_stats->bFirstMPDU;
5195 ptarget_stats->Seq_Num = psrc_stats->Seq_Num;
5199 void TranslateRxSignalStuff819xUsb(struct sk_buff *skb,
5200 struct ieee80211_rx_stats * pstats,
5201 rx_drvinfo_819x_usb *pdrvinfo)
5203 // TODO: We must only check packet for current MAC address. Not finish
5204 rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
5205 struct net_device *dev=info->dev;
5206 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
5207 bool bpacket_match_bssid, bpacket_toself;
5208 bool bPacketBeacon=FALSE, bToSelfBA=FALSE;
5209 static struct ieee80211_rx_stats previous_stats;
5210 struct ieee80211_hdr_3addr *hdr;//by amy
5213 // Get Signal Quality for only RX data queue (but not command queue)
5216 //u16 tmp_buf_len = 0;
5219 /* Get MAC frame start address. */
5220 tmp_buf = (u8*)skb->data;// + get_rxpacket_shiftbytes_819xusb(pstats);
5222 hdr = (struct ieee80211_hdr_3addr *)tmp_buf;
5223 fc = le16_to_cpu(hdr->frame_ctl);
5224 type = WLAN_FC_GET_TYPE(fc);
5225 praddr = hdr->addr1;
5227 /* Check if the received packet is acceptabe. */
5228 bpacket_match_bssid = ((IEEE80211_FTYPE_CTL != type) &&
5229 (eqMacAddr(priv->ieee80211->current_network.bssid, (fc & IEEE80211_FCTL_TODS)? hdr->addr1 : (fc & IEEE80211_FCTL_FROMDS )? hdr->addr2 : hdr->addr3))
5230 && (!pstats->bHwError) && (!pstats->bCRC)&& (!pstats->bICV));
5231 bpacket_toself = bpacket_match_bssid & (eqMacAddr(praddr, priv->ieee80211->dev->dev_addr));
5233 if(WLAN_FC_GET_FRAMETYPE(fc)== IEEE80211_STYPE_BEACON)
5235 bPacketBeacon = true;
5236 //DbgPrint("Beacon 2, MatchBSSID = %d, ToSelf = %d \n", bPacketMatchBSSID, bPacketToSelf);
5238 if(WLAN_FC_GET_FRAMETYPE(fc) == IEEE80211_STYPE_BLOCKACK)
5240 if((eqMacAddr(praddr,dev->dev_addr)))
5242 //DbgPrint("BlockAck, MatchBSSID = %d, ToSelf = %d \n", bPacketMatchBSSID, bPacketToSelf);
5247 if(bpacket_match_bssid)
5249 priv->stats.numpacket_matchbssid++;
5252 priv->stats.numpacket_toself++;
5255 // Process PHY information for previous packet (RSSI/PWDB/EVM)
5257 // Because phy information is contained in the last packet of AMPDU only, so driver
5258 // should process phy information of previous packet
5259 rtl8192_process_phyinfo(priv, tmp_buf, &previous_stats, pstats);
5260 rtl8192_query_rxphystatus(priv, pstats, pdrvinfo, &previous_stats, bpacket_match_bssid,bpacket_toself,bPacketBeacon,bToSelfBA);
5261 rtl8192_record_rxdesc_forlateruse(pstats, &previous_stats);
5266 * Function: UpdateReceivedRateHistogramStatistics
5267 * Overview: Recored down the received data rate
5270 * struct net_device *dev
5271 * struct ieee80211_rx_stats *stats
5275 * (priv->stats.ReceivedRateHistogram[] is updated)
5280 UpdateReceivedRateHistogramStatistics8190(
5281 struct net_device *dev,
5282 struct ieee80211_rx_stats *stats
5285 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
5286 u32 rcvType=1; //0: Total, 1:OK, 2:CRC, 3:ICV
5288 u32 preamble_guardinterval; //1: short preamble/GI, 0: long preamble/GI
5293 else if(stats->bICV)
5296 if(stats->bShortPreamble)
5297 preamble_guardinterval = 1;// short
5299 preamble_guardinterval = 0;// long
5306 case MGN_1M: rateIndex = 0; break;
5307 case MGN_2M: rateIndex = 1; break;
5308 case MGN_5_5M: rateIndex = 2; break;
5309 case MGN_11M: rateIndex = 3; break;
5313 case MGN_6M: rateIndex = 4; break;
5314 case MGN_9M: rateIndex = 5; break;
5315 case MGN_12M: rateIndex = 6; break;
5316 case MGN_18M: rateIndex = 7; break;
5317 case MGN_24M: rateIndex = 8; break;
5318 case MGN_36M: rateIndex = 9; break;
5319 case MGN_48M: rateIndex = 10; break;
5320 case MGN_54M: rateIndex = 11; break;
5322 // 11n High throughput rate
5324 case MGN_MCS0: rateIndex = 12; break;
5325 case MGN_MCS1: rateIndex = 13; break;
5326 case MGN_MCS2: rateIndex = 14; break;
5327 case MGN_MCS3: rateIndex = 15; break;
5328 case MGN_MCS4: rateIndex = 16; break;
5329 case MGN_MCS5: rateIndex = 17; break;
5330 case MGN_MCS6: rateIndex = 18; break;
5331 case MGN_MCS7: rateIndex = 19; break;
5332 case MGN_MCS8: rateIndex = 20; break;
5333 case MGN_MCS9: rateIndex = 21; break;
5334 case MGN_MCS10: rateIndex = 22; break;
5335 case MGN_MCS11: rateIndex = 23; break;
5336 case MGN_MCS12: rateIndex = 24; break;
5337 case MGN_MCS13: rateIndex = 25; break;
5338 case MGN_MCS14: rateIndex = 26; break;
5339 case MGN_MCS15: rateIndex = 27; break;
5340 default: rateIndex = 28; break;
5342 priv->stats.received_preamble_GI[preamble_guardinterval][rateIndex]++;
5343 priv->stats.received_rate_histogram[0][rateIndex]++; //total
5344 priv->stats.received_rate_histogram[rcvType][rateIndex]++;
5348 void query_rxdesc_status(struct sk_buff *skb, struct ieee80211_rx_stats *stats, bool bIsRxAggrSubframe)
5350 rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
5351 struct net_device *dev=info->dev;
5352 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
5353 //rx_desc_819x_usb *desc = (rx_desc_819x_usb *)skb->data;
5354 rx_drvinfo_819x_usb *driver_info = NULL;
5357 //Get Rx Descriptor Information
5359 #ifdef USB_RX_AGGREGATION_SUPPORT
5360 if (bIsRxAggrSubframe)
5362 rx_desc_819x_usb_aggr_subframe *desc = (rx_desc_819x_usb_aggr_subframe *)skb->data;
5363 stats->Length = desc->Length ;
5364 stats->RxDrvInfoSize = desc->RxDrvInfoSize;
5365 stats->RxBufShift = 0; //RxBufShift = 2 in RxDesc, but usb didn't shift bytes in fact.
5366 stats->bICV = desc->ICV;
5367 stats->bCRC = desc->CRC32;
5368 stats->bHwError = stats->bCRC|stats->bICV;
5369 stats->Decrypted = !desc->SWDec;//RTL8190 set this bit to indicate that Hw does not decrypt packet
5373 rx_desc_819x_usb *desc = (rx_desc_819x_usb *)skb->data;
5375 stats->Length = desc->Length;
5376 stats->RxDrvInfoSize = desc->RxDrvInfoSize;
5377 stats->RxBufShift = 0;//desc->Shift&0x03;
5378 stats->bICV = desc->ICV;
5379 stats->bCRC = desc->CRC32;
5380 stats->bHwError = stats->bCRC|stats->bICV;
5381 //RTL8190 set this bit to indicate that Hw does not decrypt packet
5382 stats->Decrypted = !desc->SWDec;
5385 if((priv->ieee80211->pHTInfo->bCurrentHTSupport == true) && (priv->ieee80211->pairwise_key_type == KEY_TYPE_CCMP))
5387 stats->bHwError = false;
5391 stats->bHwError = stats->bCRC|stats->bICV;
5394 if(stats->Length < 24 || stats->Length > MAX_8192U_RX_SIZE)
5395 stats->bHwError |= 1;
5399 // TODO: Need to verify it on FGPA platform
5400 //Driver info are written to the RxBuffer following rx desc
5401 if (stats->RxDrvInfoSize != 0) {
5402 driver_info = (rx_drvinfo_819x_usb *)(skb->data + sizeof(rx_desc_819x_usb) + \
5406 if(!stats->bHwError){
5408 ret_rate = HwRateToMRate90(driver_info->RxHT, driver_info->RxRate);
5409 if(ret_rate == 0xff)
5411 // Abnormal Case: Receive CRC OK packet with Rx descriptor indicating non supported rate.
5412 // Special Error Handling here, 2008.05.16, by Emily
5414 stats->bHwError = 1;
5415 stats->rate = MGN_1M; //Set 1M rate by default
5418 stats->rate = ret_rate;
5424 stats->bShortPreamble = driver_info->SPLCP;
5427 UpdateReceivedRateHistogramStatistics8190(dev, stats);
5429 stats->bIsAMPDU = (driver_info->PartAggr==1);
5430 stats->bFirstMPDU = (driver_info->PartAggr==1) && (driver_info->FirstAGGR==1);
5431 stats->TimeStampLow = driver_info->TSFL;
5432 // xiong mask it, 070514
5433 //pRfd->Status.TimeStampHigh = PlatformEFIORead4Byte(Adapter, TSFR+4);
5434 // stats->TimeStampHigh = read_nic_dword(dev, TSFR+4);
5436 UpdateRxPktTimeStamp8190(dev, stats);
5441 if(driver_info->FirstAGGR==1 || driver_info->PartAggr == 1)
5442 RT_TRACE(COMP_RXDESC, "driver_info->FirstAGGR = %d, driver_info->PartAggr = %d\n",
5443 driver_info->FirstAGGR, driver_info->PartAggr);
5447 skb_pull(skb,sizeof(rx_desc_819x_usb));
5449 // Get Total offset of MPDU Frame Body
5451 if((stats->RxBufShift + stats->RxDrvInfoSize) > 0) {
5453 skb_pull(skb,stats->RxBufShift + stats->RxDrvInfoSize);
5456 #ifdef USB_RX_AGGREGATION_SUPPORT
5457 /* for the rx aggregated sub frame, the redundant space truelly contained in the packet */
5458 if(bIsRxAggrSubframe) {
5462 /* for debug 2008.5.29 */
5464 //added by vivi, for MP, 20080108
5465 stats->RxIs40MHzPacket = driver_info->BW;
5466 if(stats->RxDrvInfoSize != 0)
5467 TranslateRxSignalStuff819xUsb(skb, stats, driver_info);
5471 u32 GetRxPacketShiftBytes819xUsb(struct ieee80211_rx_stats *Status, bool bIsRxAggrSubframe)
5473 #ifdef USB_RX_AGGREGATION_SUPPORT
5474 if (bIsRxAggrSubframe)
5475 return (sizeof(rx_desc_819x_usb) + Status->RxDrvInfoSize
5476 + Status->RxBufShift + 8);
5479 return (sizeof(rx_desc_819x_usb) + Status->RxDrvInfoSize
5480 + Status->RxBufShift);
5483 void rtl8192_rx_nomal(struct sk_buff* skb)
5485 rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
5486 struct net_device *dev=info->dev;
5487 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
5488 struct ieee80211_rx_stats stats = {
5492 // .mac_time = jiffies,
5493 .freq = IEEE80211_24GHZ_BAND,
5496 struct ieee80211_hdr_1addr *ieee80211_hdr = NULL;
5497 bool unicast_packet = false;
5498 #ifdef USB_RX_AGGREGATION_SUPPORT
5499 struct sk_buff *agg_skb = NULL;
5500 u32 TotalLength = 0;
5502 u32 PacketLength = 0;
5503 u32 PacketOccupiedLendth = 0;
5505 u32 PacketShiftBytes = 0;
5506 rx_desc_819x_usb_aggr_subframe *RxDescr = NULL;
5507 u8 PaddingBytes = 0;
5508 //add just for testing
5513 /* 20 is for ps-poll */
5514 if((skb->len >=(20 + sizeof(rx_desc_819x_usb))) && (skb->len < RX_URB_SIZE)) {
5515 #ifdef USB_RX_AGGREGATION_SUPPORT
5516 TempByte = *(skb->data + sizeof(rx_desc_819x_usb));
5518 /* first packet should not contain Rx aggregation header */
5519 query_rxdesc_status(skb, &stats, false);
5521 /* hardware related info */
5522 #ifdef USB_RX_AGGREGATION_SUPPORT
5523 if (TempByte & BIT0) {
5525 //TotalLength = agg_skb->len - 4; /*sCrcLng*/
5526 TotalLength = stats.Length - 4; /*sCrcLng*/
5527 //RT_TRACE(COMP_RECV, "%s:first aggregated packet!Length=%d\n",__FUNCTION__,TotalLength);
5528 /* though the head pointer has passed this position */
5529 TempDWord = *(u32 *)(agg_skb->data - 4);
5530 PacketLength = (u16)(TempDWord & 0x3FFF); /*sCrcLng*/
5531 skb = dev_alloc_skb(PacketLength);
5532 memcpy(skb_put(skb,PacketLength),agg_skb->data,PacketLength);
5533 PacketShiftBytes = GetRxPacketShiftBytes819xUsb(&stats, false);
5536 /* Process the MPDU recevied */
5537 skb_trim(skb, skb->len - 4/*sCrcLng*/);
5539 rx_pkt_len = skb->len;
5540 ieee80211_hdr = (struct ieee80211_hdr_1addr *)skb->data;
5541 unicast_packet = false;
5542 if(is_broadcast_ether_addr(ieee80211_hdr->addr1)) {
5544 }else if(is_multicast_ether_addr(ieee80211_hdr->addr1)){
5547 /* unicast packet */
5548 unicast_packet = true;
5551 if(!ieee80211_rx(priv->ieee80211,skb, &stats)) {
5552 dev_kfree_skb_any(skb);
5554 priv->stats.rxoktotal++;
5555 if(unicast_packet) {
5556 priv->stats.rxbytesunicast += rx_pkt_len;
5559 #ifdef USB_RX_AGGREGATION_SUPPORT
5561 // (PipeIndex == 0) && (TempByte & BIT0) => TotalLength > 0.
5562 if (TotalLength > 0) {
5563 PacketOccupiedLendth = PacketLength + (PacketShiftBytes + 8);
5564 if ((PacketOccupiedLendth & 0xFF) != 0)
5565 PacketOccupiedLendth = (PacketOccupiedLendth & 0xFFFFFF00) + 256;
5566 PacketOccupiedLendth -= 8;
5567 TempDWord = PacketOccupiedLendth - PacketShiftBytes; /*- PacketLength */
5568 if (agg_skb->len > TempDWord)
5569 skb_pull(agg_skb, TempDWord);
5573 while (agg_skb->len>=GetRxPacketShiftBytes819xUsb(&stats, true)) {
5574 u8 tmpCRC = 0, tmpICV = 0;
5575 //RT_TRACE(COMP_RECV,"%s:aggred pkt,total_len = %d\n",__FUNCTION__,agg_skb->len);
5576 RxDescr = (rx_desc_819x_usb_aggr_subframe *)(agg_skb->data);
5577 tmpCRC = RxDescr->CRC32;
5578 tmpICV = RxDescr->ICV;
5579 memcpy(agg_skb->data, &agg_skb->data[44], 2);
5580 RxDescr->CRC32 = tmpCRC;
5581 RxDescr->ICV = tmpICV;
5583 memset(&stats, 0, sizeof(struct ieee80211_rx_stats));
5587 stats.freq = IEEE80211_24GHZ_BAND;
5588 query_rxdesc_status(agg_skb, &stats, true);
5589 PacketLength = stats.Length;
5591 if(PacketLength > agg_skb->len) {
5594 /* Process the MPDU recevied */
5595 skb = dev_alloc_skb(PacketLength);
5596 memcpy(skb_put(skb,PacketLength),agg_skb->data, PacketLength);
5597 skb_trim(skb, skb->len - 4/*sCrcLng*/);
5599 rx_pkt_len = skb->len;
5600 ieee80211_hdr = (struct ieee80211_hdr_1addr *)skb->data;
5601 unicast_packet = false;
5602 if(is_broadcast_ether_addr(ieee80211_hdr->addr1)) {
5604 }else if(is_multicast_ether_addr(ieee80211_hdr->addr1)){
5607 /* unicast packet */
5608 unicast_packet = true;
5610 if(!ieee80211_rx(priv->ieee80211,skb, &stats)) {
5611 dev_kfree_skb_any(skb);
5613 priv->stats.rxoktotal++;
5614 if(unicast_packet) {
5615 priv->stats.rxbytesunicast += rx_pkt_len;
5618 /* should trim the packet which has been copied to target skb */
5619 skb_pull(agg_skb, PacketLength);
5620 PacketShiftBytes = GetRxPacketShiftBytes819xUsb(&stats, true);
5621 PacketOccupiedLendth = PacketLength + PacketShiftBytes;
5622 if ((PacketOccupiedLendth & 0xFF) != 0) {
5623 PaddingBytes = 256 - (PacketOccupiedLendth & 0xFF);
5624 if (agg_skb->len > PaddingBytes)
5625 skb_pull(agg_skb, PaddingBytes);
5630 dev_kfree_skb(agg_skb);
5634 priv->stats.rxurberr++;
5635 printk("actual_length:%d\n", skb->len);
5636 dev_kfree_skb_any(skb);
5642 rtl819xusb_process_received_packet(
5643 struct net_device *dev,
5644 struct ieee80211_rx_stats *pstats
5647 // bool bfreerfd=false, bqueued=false;
5650 struct r8192_priv *priv = ieee80211_priv(dev);
5654 //PRX_TS_RECORD pts = NULL;
5656 // Get shifted bytes of Starting address of 802.11 header. 2006.09.28, by Emily
5657 //porting by amy 080508
5658 pstats->virtual_address += get_rxpacket_shiftbytes_819xusb(pstats);
5659 frame = pstats->virtual_address;
5660 frame_len = pstats->packetlength;
5661 #ifdef TODO // by amy about HCT
5662 if(!Adapter->bInHctTest)
5663 CountRxErrStatistics(Adapter, pRfd);
5666 #ifdef ENABLE_PS //by amy for adding ps function in future
5667 RT_RF_POWER_STATE rtState;
5668 // When RF is off, we should not count the packet for hw/sw synchronize
5669 // reason, ie. there may be a duration while sw switch is changed and hw
5670 // switch is being changed. 2006.12.04, by shien chang.
5671 Adapter->HalFunc.GetHwRegHandler(Adapter, HW_VAR_RF_STATE, (u8* )(&rtState));
5672 if (rtState == eRfOff)
5677 priv->stats.rxframgment++;
5681 RmMonitorSignalStrength(Adapter, pRfd);
5683 /* 2007/01/16 MH Add RX command packet handle here. */
5684 /* 2007/03/01 MH We have to release RFD and return if rx pkt is cmd pkt. */
5685 if (rtl819xusb_rx_command_packet(dev, pstats))
5697 void query_rx_cmdpkt_desc_status(struct sk_buff *skb, struct ieee80211_rx_stats *stats)
5699 // rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
5700 // struct net_device *dev=info->dev;
5701 // struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
5702 rx_desc_819x_usb *desc = (rx_desc_819x_usb *)skb->data;
5703 // rx_drvinfo_819x_usb *driver_info;
5706 //Get Rx Descriptor Information
5708 stats->virtual_address = (u8*)skb->data;
5709 stats->Length = desc->Length;
5710 stats->RxDrvInfoSize = 0;
5711 stats->RxBufShift = 0;
5712 stats->packetlength = stats->Length-scrclng;
5713 stats->fraglength = stats->packetlength;
5714 stats->fragoffset = 0;
5715 stats->ntotalfrag = 1;
5719 void rtl8192_rx_cmd(struct sk_buff *skb)
5721 struct rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
5722 struct net_device *dev = info->dev;
5724 // struct urb *rx_urb = info->urb;
5726 struct ieee80211_rx_stats stats = {
5730 // .mac_time = jiffies,
5731 .freq = IEEE80211_24GHZ_BAND,
5734 if((skb->len >=(20 + sizeof(rx_desc_819x_usb))) && (skb->len < RX_URB_SIZE))
5737 query_rx_cmdpkt_desc_status(skb,&stats);
5738 // this is to be done by amy 080508 prfd->queue_id = 1;
5742 // Process the command packet received.
5745 rtl819xusb_process_received_packet(dev,&stats);
5747 dev_kfree_skb_any(skb);
5755 void rtl8192_irq_rx_tasklet(struct r8192_priv *priv)
5757 struct sk_buff *skb;
5758 struct rtl8192_rx_info *info;
5760 while (NULL != (skb = skb_dequeue(&priv->skb_queue))) {
5761 info = (struct rtl8192_rx_info *)skb->cb;
5762 switch (info->out_pipe) {
5763 /* Nomal packet pipe */
5765 //RT_TRACE(COMP_RECV, "normal in-pipe index(%d)\n",info->out_pipe);
5766 priv->IrpPendingCount--;
5767 rtl8192_rx_nomal(skb);
5770 /* Command packet pipe */
5772 RT_TRACE(COMP_RECV, "command in-pipe index(%d)\n",\
5775 rtl8192_rx_cmd(skb);
5778 default: /* should never get here! */
5779 RT_TRACE(COMP_ERR, "Unknown in-pipe index(%d)\n",\
5788 static const struct net_device_ops rtl8192_netdev_ops = {
5789 .ndo_open = rtl8192_open,
5790 .ndo_stop = rtl8192_close,
5791 .ndo_get_stats = rtl8192_stats,
5792 .ndo_tx_timeout = tx_timeout,
5793 .ndo_do_ioctl = rtl8192_ioctl,
5794 .ndo_set_multicast_list = r8192_set_multicast,
5795 .ndo_set_mac_address = r8192_set_mac_adr,
5796 .ndo_validate_addr = eth_validate_addr,
5797 .ndo_change_mtu = eth_change_mtu,
5798 .ndo_start_xmit = ieee80211_xmit,
5802 /****************************************************************************
5803 ---------------------------- USB_STUFF---------------------------
5804 *****************************************************************************/
5806 static int __devinit rtl8192_usb_probe(struct usb_interface *intf,
5807 const struct usb_device_id *id)
5809 // unsigned long ioaddr = 0;
5810 struct net_device *dev = NULL;
5811 struct r8192_priv *priv= NULL;
5812 struct usb_device *udev = interface_to_usbdev(intf);
5813 RT_TRACE(COMP_INIT, "Oops: i'm coming\n");
5815 dev = alloc_ieee80211(sizeof(struct r8192_priv));
5818 usb_set_intfdata(intf, dev);
5819 SET_NETDEV_DEV(dev, &intf->dev);
5820 priv = ieee80211_priv(dev);
5821 priv->ieee80211 = netdev_priv(dev);
5824 dev->netdev_ops = &rtl8192_netdev_ops;
5826 //DMESG("Oops: i'm coming\n");
5827 #if WIRELESS_EXT >= 12
5828 #if WIRELESS_EXT < 17
5829 dev->get_wireless_stats = r8192_get_wireless_stats;
5831 dev->wireless_handlers = (struct iw_handler_def *) &r8192_wx_handlers_def;
5833 dev->type=ARPHRD_ETHER;
5835 dev->watchdog_timeo = HZ*3; //modified by john, 0805
5837 if (dev_alloc_name(dev, ifname) < 0){
5838 RT_TRACE(COMP_INIT, "Oops: devname already taken! Trying wlan%%d...\n");
5840 dev_alloc_name(dev, ifname);
5843 RT_TRACE(COMP_INIT, "Driver probe completed1\n");
5844 if(rtl8192_init(dev)!=0){
5845 RT_TRACE(COMP_ERR, "Initialization failed");
5848 netif_carrier_off(dev);
5849 netif_stop_queue(dev);
5851 register_netdev(dev);
5852 RT_TRACE(COMP_INIT, "dev name=======> %s\n",dev->name);
5853 rtl8192_proc_init_one(dev);
5856 RT_TRACE(COMP_INIT, "Driver probe completed\n");
5861 free_ieee80211(dev);
5863 RT_TRACE(COMP_ERR, "wlan driver load failed\n");
5868 //detach all the work and timer structure declared or inititialize in r8192U_init function.
5869 void rtl8192_cancel_deferred_work(struct r8192_priv* priv)
5872 cancel_work_sync(&priv->reset_wq);
5873 cancel_delayed_work(&priv->watch_dog_wq);
5874 cancel_delayed_work(&priv->update_beacon_wq);
5875 cancel_work_sync(&priv->qos_activate);
5876 //cancel_work_sync(&priv->SetBWModeWorkItem);
5877 //cancel_work_sync(&priv->SwChnlWorkItem);
5882 static void __devexit rtl8192_usb_disconnect(struct usb_interface *intf)
5884 struct net_device *dev = usb_get_intfdata(intf);
5886 struct r8192_priv *priv = ieee80211_priv(dev);
5889 unregister_netdev(dev);
5891 RT_TRACE(COMP_DOWN, "=============>wlan driver to be removed\n");
5892 rtl8192_proc_remove_one(dev);
5895 if (priv->pFirmware)
5897 kfree(priv->pFirmware);
5898 priv->pFirmware = NULL;
5900 // priv->rf_close(dev);
5901 // rtl8192_SetRFPowerState(dev, eRfOff);
5902 rtl8192_usb_deleteendpoints(dev);
5903 destroy_workqueue(priv->priv_wq);
5904 //rtl8192_irq_disable(dev);
5905 //rtl8192_reset(dev);
5909 free_ieee80211(dev);
5910 RT_TRACE(COMP_DOWN, "wlan driver removed\n");
5913 /* fun with the built-in ieee80211 stack... */
5914 extern int ieee80211_debug_init(void);
5915 extern void ieee80211_debug_exit(void);
5916 extern int ieee80211_crypto_init(void);
5917 extern void ieee80211_crypto_deinit(void);
5918 extern int ieee80211_crypto_tkip_init(void);
5919 extern void ieee80211_crypto_tkip_exit(void);
5920 extern int ieee80211_crypto_ccmp_init(void);
5921 extern void ieee80211_crypto_ccmp_exit(void);
5922 extern int ieee80211_crypto_wep_init(void);
5923 extern void ieee80211_crypto_wep_exit(void);
5925 static int __init rtl8192_usb_module_init(void)
5929 #ifdef CONFIG_IEEE80211_DEBUG
5930 ret = ieee80211_debug_init();
5932 printk(KERN_ERR "ieee80211_debug_init() failed %d\n", ret);
5936 ret = ieee80211_crypto_init();
5938 printk(KERN_ERR "ieee80211_crypto_init() failed %d\n", ret);
5942 ret = ieee80211_crypto_tkip_init();
5944 printk(KERN_ERR "ieee80211_crypto_tkip_init() failed %d\n",
5949 ret = ieee80211_crypto_ccmp_init();
5951 printk(KERN_ERR "ieee80211_crypto_ccmp_init() failed %d\n",
5956 ret = ieee80211_crypto_wep_init();
5958 printk(KERN_ERR "ieee80211_crypto_wep_init() failed %d\n", ret);
5962 printk(KERN_INFO "\nLinux kernel driver for RTL8192 based WLAN cards\n");
5963 printk(KERN_INFO "Copyright (c) 2007-2008, Realsil Wlan\n");
5964 RT_TRACE(COMP_INIT, "Initializing module");
5965 RT_TRACE(COMP_INIT, "Wireless extensions version %d", WIRELESS_EXT);
5966 rtl8192_proc_module_init();
5967 return usb_register(&rtl8192_usb_driver);
5971 static void __exit rtl8192_usb_module_exit(void)
5973 usb_deregister(&rtl8192_usb_driver);
5975 RT_TRACE(COMP_DOWN, "Exiting");
5976 // rtl8192_proc_module_remove();
5980 void rtl8192_try_wake_queue(struct net_device *dev, int pri)
5982 unsigned long flags;
5984 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
5986 spin_lock_irqsave(&priv->tx_lock,flags);
5987 enough_desc = check_nic_enough_desc(dev,pri);
5988 spin_unlock_irqrestore(&priv->tx_lock,flags);
5991 ieee80211_wake_queue(priv->ieee80211);
5994 void EnableHWSecurityConfig8192(struct net_device *dev)
5996 u8 SECR_value = 0x0;
5997 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
5998 struct ieee80211_device* ieee = priv->ieee80211;
5999 SECR_value = SCR_TxEncEnable | SCR_RxDecEnable;
6000 if (((KEY_TYPE_WEP40 == ieee->pairwise_key_type) || (KEY_TYPE_WEP104 == ieee->pairwise_key_type)) && (priv->ieee80211->auth_mode != 2))
6002 SECR_value |= SCR_RxUseDK;
6003 SECR_value |= SCR_TxUseDK;
6005 else if ((ieee->iw_mode == IW_MODE_ADHOC) && (ieee->pairwise_key_type & (KEY_TYPE_CCMP | KEY_TYPE_TKIP)))
6007 SECR_value |= SCR_RxUseDK;
6008 SECR_value |= SCR_TxUseDK;
6010 //add HWSec active enable here.
6011 //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
6013 ieee->hwsec_active = 1;
6015 if ((ieee->pHTInfo->IOTAction&HT_IOT_ACT_PURE_N_MODE) || !hwwep)//!ieee->hwsec_support) //add hwsec_support flag to totol control hw_sec on/off
6017 ieee->hwsec_active = 0;
6018 SECR_value &= ~SCR_RxDecEnable;
6020 RT_TRACE(COMP_SEC,"%s:, hwsec:%d, pairwise_key:%d, SECR_value:%x\n", __FUNCTION__, \
6021 ieee->hwsec_active, ieee->pairwise_key_type, SECR_value);
6023 write_nic_byte(dev, SECR, SECR_value);//SECR_value | SCR_UseDK );
6028 void setKey( struct net_device *dev,
6036 u32 TargetCommand = 0;
6037 u32 TargetContent = 0;
6040 if (EntryNo >= TOTAL_CAM_ENTRY)
6041 RT_TRACE(COMP_ERR, "cam entry exceeds in setKey()\n");
6043 RT_TRACE(COMP_SEC, "====>to setKey(), dev:%p, EntryNo:%d, KeyIndex:%d, KeyType:%d, MacAddr%pM\n", dev,EntryNo, KeyIndex, KeyType, MacAddr);
6046 usConfig |= BIT15 | (KeyType<<2);
6048 usConfig |= BIT15 | (KeyType<<2) | KeyIndex;
6049 // usConfig |= BIT15 | (KeyType<<2) | (DefaultKey<<5) | KeyIndex;
6052 for(i=0 ; i<CAM_CONTENT_COUNT; i++){
6053 TargetCommand = i+CAM_CONTENT_COUNT*EntryNo;
6054 TargetCommand |= BIT31|BIT16;
6056 if(i==0){//MAC|Config
6057 TargetContent = (u32)(*(MacAddr+0)) << 16|
6058 (u32)(*(MacAddr+1)) << 24|
6061 write_nic_dword(dev, WCAMI, TargetContent);
6062 write_nic_dword(dev, RWCAM, TargetCommand);
6063 // printk("setkey cam =%8x\n", read_cam(dev, i+6*EntryNo));
6066 TargetContent = (u32)(*(MacAddr+2)) |
6067 (u32)(*(MacAddr+3)) << 8|
6068 (u32)(*(MacAddr+4)) << 16|
6069 (u32)(*(MacAddr+5)) << 24;
6070 write_nic_dword(dev, WCAMI, TargetContent);
6071 write_nic_dword(dev, RWCAM, TargetCommand);
6075 if(KeyContent !=NULL){
6076 write_nic_dword(dev, WCAMI, (u32)(*(KeyContent+i-2)) );
6077 write_nic_dword(dev, RWCAM, TargetCommand);
6084 /***************************************************************************
6085 ------------------- module init / exit stubs ----------------
6086 ****************************************************************************/
6087 module_init(rtl8192_usb_module_init);
6088 module_exit(rtl8192_usb_module_exit);