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,
418 printk("read_nic_word TimeOut! status:%d\n", status);
423 u16 read_nic_word_E(struct net_device *dev, int indx)
427 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
428 struct usb_device *udev = priv->udev;
430 status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
431 RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
432 indx|0xfe00, 0, &data, 2, HZ / 2);
435 printk("read_nic_word TimeOut! status:%d\n", status);
440 u32 read_nic_dword(struct net_device *dev, int indx)
446 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
447 struct usb_device *udev = priv->udev;
449 status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
450 RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
451 (indx&0xff)|0xff00, (indx>>8)&0x0f,
454 * printk(KERN_WARNING "read size of data = %d\, date = %d\n",
460 printk("read_nic_dword TimeOut! status:%d\n", status);
465 /* u8 read_phy_cck(struct net_device *dev, u8 adr); */
466 /* u8 read_phy_ofdm(struct net_device *dev, u8 adr); */
467 /* this might still called in what was the PHY rtl8185/rtl8192 common code
468 * plans are to possibilty turn it again in one common code...
470 inline void force_pci_posting(struct net_device *dev)
474 static struct net_device_stats *rtl8192_stats(struct net_device *dev);
475 void rtl8192_commit(struct net_device *dev);
476 /* void rtl8192_restart(struct net_device *dev); */
477 void rtl8192_restart(struct work_struct *work);
478 /* void rtl8192_rq_tx_ack(struct work_struct *work); */
479 void watch_dog_timer_callback(unsigned long data);
481 /****************************************************************************
482 * -----------------------------PROCFS STUFF-------------------------
483 *****************************************************************************
486 static struct proc_dir_entry *rtl8192_proc;
488 static int proc_get_stats_ap(char *page, char **start, off_t offset, int count,
489 int *eof, void *data)
491 struct net_device *dev = data;
492 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
493 struct ieee80211_device *ieee = priv->ieee80211;
494 struct ieee80211_network *target;
498 list_for_each_entry(target, &ieee->network_list, list) {
500 len += snprintf(page + len, count - len, "%s ", target->ssid);
502 if (target->wpa_ie_len > 0 || target->rsn_ie_len > 0)
503 len += snprintf(page + len, count - len, "WPA\n");
505 len += snprintf(page + len, count - len, "non_WPA\n");
512 static int proc_get_registers(char *page, char **start,
513 off_t offset, int count,
514 int *eof, void *data)
516 struct net_device *dev = data;
517 // struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
524 /* This dump the current register page */
525 len += snprintf(page + len, count - len,
526 "\n####################page 0##################\n ");
530 //printk( "\nD: %2x> ", n);
531 len += snprintf(page + len, count - len,
534 for(i=0;i<16 && n<=max;i++,n++)
535 len += snprintf(page + len, count - len,
536 "%2x ",read_nic_byte(dev,0x000|n));
538 // printk("%2x ",read_nic_byte(dev,n));
540 len += snprintf(page + len, count - len,
541 "\n####################page 1##################\n ");
544 //printk( "\nD: %2x> ", n);
545 len += snprintf(page + len, count - len,
548 for(i=0;i<16 && n<=max;i++,n++)
549 len += snprintf(page + len, count - len,
550 "%2x ",read_nic_byte(dev,0x100|n));
552 // printk("%2x ",read_nic_byte(dev,n));
554 len += snprintf(page + len, count - len,
555 "\n####################page 3##################\n ");
558 //printk( "\nD: %2x> ", n);
559 len += snprintf(page + len, count - len,
562 for(i=0;i<16 && n<=max;i++,n++)
563 len += snprintf(page + len, count - len,
564 "%2x ",read_nic_byte(dev,0x300|n));
566 // printk("%2x ",read_nic_byte(dev,n));
570 len += snprintf(page + len, count - len,"\n");
580 static int proc_get_stats_tx(char *page, char **start,
581 off_t offset, int count,
582 int *eof, void *data)
584 struct net_device *dev = data;
585 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
589 len += snprintf(page + len, count - len,
590 "TX VI priority ok int: %lu\n"
591 "TX VI priority error int: %lu\n"
592 "TX VO priority ok int: %lu\n"
593 "TX VO priority error int: %lu\n"
594 "TX BE priority ok int: %lu\n"
595 "TX BE priority error int: %lu\n"
596 "TX BK priority ok int: %lu\n"
597 "TX BK priority error int: %lu\n"
598 "TX MANAGE priority ok int: %lu\n"
599 "TX MANAGE priority error int: %lu\n"
600 "TX BEACON priority ok int: %lu\n"
601 "TX BEACON priority error int: %lu\n"
602 // "TX high priority ok int: %lu\n"
603 // "TX high priority failed error int: %lu\n"
604 "TX queue resume: %lu\n"
605 "TX queue stopped?: %d\n"
606 "TX fifo overflow: %lu\n"
607 // "TX beacon: %lu\n"
612 // "TX HW queue: %d\n"
613 "TX VI dropped: %lu\n"
614 "TX VO dropped: %lu\n"
615 "TX BE dropped: %lu\n"
616 "TX BK dropped: %lu\n"
617 "TX total data packets %lu\n",
618 // "TX beacon aborted: %lu\n",
619 priv->stats.txviokint,
621 priv->stats.txvookint,
623 priv->stats.txbeokint,
625 priv->stats.txbkokint,
627 priv->stats.txmanageokint,
628 priv->stats.txmanageerr,
629 priv->stats.txbeaconokint,
630 priv->stats.txbeaconerr,
631 // priv->stats.txhpokint,
632 // priv->stats.txhperr,
633 priv->stats.txresumed,
634 netif_queue_stopped(dev),
635 priv->stats.txoverflow,
636 // priv->stats.txbeacon,
637 atomic_read(&(priv->tx_pending[VI_PRIORITY])),
638 atomic_read(&(priv->tx_pending[VO_PRIORITY])),
639 atomic_read(&(priv->tx_pending[BE_PRIORITY])),
640 atomic_read(&(priv->tx_pending[BK_PRIORITY])),
641 // read_nic_byte(dev, TXFIFOCOUNT),
642 priv->stats.txvidrop,
643 priv->stats.txvodrop,
644 priv->stats.txbedrop,
645 priv->stats.txbkdrop,
646 priv->stats.txdatapkt
647 // priv->stats.txbeaconerr
656 static int proc_get_stats_rx(char *page, char **start,
657 off_t offset, int count,
658 int *eof, void *data)
660 struct net_device *dev = data;
661 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
665 len += snprintf(page + len, count - len,
667 "RX urb status error: %lu\n"
668 "RX invalid urb error: %lu\n",
669 priv->stats.rxoktotal,
670 priv->stats.rxstaterr,
671 priv->stats.rxurberr);
676 void rtl8192_proc_module_init(void)
678 RT_TRACE(COMP_INIT, "Initializing proc filesystem");
679 rtl8192_proc=create_proc_entry(RTL819xU_MODULE_NAME, S_IFDIR, init_net.proc_net);
683 void rtl8192_proc_module_remove(void)
685 remove_proc_entry(RTL819xU_MODULE_NAME, init_net.proc_net);
689 void rtl8192_proc_remove_one(struct net_device *dev)
691 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
695 // remove_proc_entry("stats-hw", priv->dir_dev);
696 remove_proc_entry("stats-tx", priv->dir_dev);
697 remove_proc_entry("stats-rx", priv->dir_dev);
698 // remove_proc_entry("stats-ieee", priv->dir_dev);
699 remove_proc_entry("stats-ap", priv->dir_dev);
700 remove_proc_entry("registers", priv->dir_dev);
701 // remove_proc_entry("cck-registers",priv->dir_dev);
702 // remove_proc_entry("ofdm-registers",priv->dir_dev);
703 //remove_proc_entry(dev->name, rtl8192_proc);
704 remove_proc_entry("wlan0", rtl8192_proc);
705 priv->dir_dev = NULL;
710 void rtl8192_proc_init_one(struct net_device *dev)
712 struct proc_dir_entry *e;
713 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
714 priv->dir_dev = create_proc_entry(dev->name,
715 S_IFDIR | S_IRUGO | S_IXUGO,
717 if (!priv->dir_dev) {
718 RT_TRACE(COMP_ERR, "Unable to initialize /proc/net/rtl8192/%s\n",
722 e = create_proc_read_entry("stats-rx", S_IFREG | S_IRUGO,
723 priv->dir_dev, proc_get_stats_rx, dev);
726 RT_TRACE(COMP_ERR,"Unable to initialize "
727 "/proc/net/rtl8192/%s/stats-rx\n",
732 e = create_proc_read_entry("stats-tx", S_IFREG | S_IRUGO,
733 priv->dir_dev, proc_get_stats_tx, dev);
736 RT_TRACE(COMP_ERR, "Unable to initialize "
737 "/proc/net/rtl8192/%s/stats-tx\n",
741 e = create_proc_read_entry("stats-ap", S_IFREG | S_IRUGO,
742 priv->dir_dev, proc_get_stats_ap, dev);
745 RT_TRACE(COMP_ERR, "Unable to initialize "
746 "/proc/net/rtl8192/%s/stats-ap\n",
750 e = create_proc_read_entry("registers", S_IFREG | S_IRUGO,
751 priv->dir_dev, proc_get_registers, dev);
753 RT_TRACE(COMP_ERR, "Unable to initialize "
754 "/proc/net/rtl8192/%s/registers\n",
758 /****************************************************************************
759 -----------------------------MISC STUFF-------------------------
760 *****************************************************************************/
762 /* this is only for debugging */
763 void print_buffer(u32 *buffer, int len)
766 u8 *buf =(u8*)buffer;
768 printk("ASCII BUFFER DUMP (len: %x):\n",len);
773 printk("\nBINARY BUFFER DUMP (len: %x):\n",len);
781 //short check_nic_enough_desc(struct net_device *dev, priority_t priority)
782 short check_nic_enough_desc(struct net_device *dev,int queue_index)
784 struct r8192_priv *priv = ieee80211_priv(dev);
785 int used = atomic_read(&priv->tx_pending[queue_index]);
787 return (used < MAX_TX_URB);
790 void tx_timeout(struct net_device *dev)
792 struct r8192_priv *priv = ieee80211_priv(dev);
793 //rtl8192_commit(dev);
795 schedule_work(&priv->reset_wq);
796 //DMESG("TXTIMEOUT");
800 /* this is only for debug */
801 void dump_eprom(struct net_device *dev)
805 RT_TRACE(COMP_EPROM, "EEPROM addr %x : %x", i, eprom_read(dev,i));
808 /* this is only for debug */
809 void rtl8192_dump_reg(struct net_device *dev)
815 RT_TRACE(COMP_PHY, "Dumping NIC register map");
819 printk( "\nD: %2x> ", n);
820 for(i=0;i<16 && n<=max;i++,n++)
821 printk("%2x ",read_nic_byte(dev,n));
826 /****************************************************************************
827 ------------------------------HW STUFF---------------------------
828 *****************************************************************************/
831 void rtl8192_set_mode(struct net_device *dev,int mode)
834 ecmd=read_nic_byte(dev, EPROM_CMD);
835 ecmd=ecmd &~ EPROM_CMD_OPERATING_MODE_MASK;
836 ecmd=ecmd | (mode<<EPROM_CMD_OPERATING_MODE_SHIFT);
837 ecmd=ecmd &~ (1<<EPROM_CS_SHIFT);
838 ecmd=ecmd &~ (1<<EPROM_CK_SHIFT);
839 write_nic_byte(dev, EPROM_CMD, ecmd);
843 void rtl8192_update_msr(struct net_device *dev)
845 struct r8192_priv *priv = ieee80211_priv(dev);
848 msr = read_nic_byte(dev, MSR);
849 msr &= ~ MSR_LINK_MASK;
851 /* do not change in link_state != WLAN_LINK_ASSOCIATED.
852 * msr must be updated if the state is ASSOCIATING.
853 * this is intentional and make sense for ad-hoc and
854 * master (see the create BSS/IBSS func)
856 if (priv->ieee80211->state == IEEE80211_LINKED){
858 if (priv->ieee80211->iw_mode == IW_MODE_INFRA)
859 msr |= (MSR_LINK_MANAGED<<MSR_LINK_SHIFT);
860 else if (priv->ieee80211->iw_mode == IW_MODE_ADHOC)
861 msr |= (MSR_LINK_ADHOC<<MSR_LINK_SHIFT);
862 else if (priv->ieee80211->iw_mode == IW_MODE_MASTER)
863 msr |= (MSR_LINK_MASTER<<MSR_LINK_SHIFT);
866 msr |= (MSR_LINK_NONE<<MSR_LINK_SHIFT);
868 write_nic_byte(dev, MSR, msr);
871 void rtl8192_set_chan(struct net_device *dev,short ch)
873 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
875 RT_TRACE(COMP_CH, "=====>%s()====ch:%d\n", __FUNCTION__, ch);
878 /* this hack should avoid frame TX during channel setting*/
881 // tx = read_nic_dword(dev,TX_CONF);
882 // tx &= ~TX_LOOPBACK_MASK;
885 // write_nic_dword(dev,TX_CONF, tx |( TX_LOOPBACK_MAC<<TX_LOOPBACK_SHIFT));
887 //need to implement rf set channel here WB
889 if (priv->rf_set_chan)
890 priv->rf_set_chan(dev,priv->chan);
892 // write_nic_dword(dev,TX_CONF,tx | (TX_LOOPBACK_NONE<<TX_LOOPBACK_SHIFT));
896 static void rtl8192_rx_isr(struct urb *urb);
897 //static void rtl8192_rx_isr(struct urb *rx_urb);
899 u32 get_rxpacket_shiftbytes_819xusb(struct ieee80211_rx_stats *pstats)
902 #ifdef USB_RX_AGGREGATION_SUPPORT
903 if (pstats->bisrxaggrsubframe)
904 return (sizeof(rx_desc_819x_usb) + pstats->RxDrvInfoSize
905 + pstats->RxBufShift + 8);
908 return (sizeof(rx_desc_819x_usb) + pstats->RxDrvInfoSize
909 + pstats->RxBufShift);
912 static int rtl8192_rx_initiate(struct net_device*dev)
914 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
917 struct rtl8192_rx_info *info;
919 /* nomal packet rx procedure */
920 while (skb_queue_len(&priv->rx_queue) < MAX_RX_URB) {
921 skb = __dev_alloc_skb(RX_URB_SIZE, GFP_KERNEL);
924 entry = usb_alloc_urb(0, GFP_KERNEL);
929 // printk("nomal packet IN request!\n");
930 usb_fill_bulk_urb(entry, priv->udev,
931 usb_rcvbulkpipe(priv->udev, 3), skb_tail_pointer(skb),
932 RX_URB_SIZE, rtl8192_rx_isr, skb);
933 info = (struct rtl8192_rx_info *) skb->cb;
936 info->out_pipe = 3; //denote rx normal packet queue
937 skb_queue_tail(&priv->rx_queue, skb);
938 usb_submit_urb(entry, GFP_KERNEL);
941 /* command packet rx procedure */
942 while (skb_queue_len(&priv->rx_queue) < MAX_RX_URB + 3) {
943 // printk("command packet IN request!\n");
944 skb = __dev_alloc_skb(RX_URB_SIZE ,GFP_KERNEL);
947 entry = usb_alloc_urb(0, GFP_KERNEL);
952 usb_fill_bulk_urb(entry, priv->udev,
953 usb_rcvbulkpipe(priv->udev, 9), skb_tail_pointer(skb),
954 RX_URB_SIZE, rtl8192_rx_isr, skb);
955 info = (struct rtl8192_rx_info *) skb->cb;
958 info->out_pipe = 9; //denote rx cmd packet queue
959 skb_queue_tail(&priv->rx_queue, skb);
960 usb_submit_urb(entry, GFP_KERNEL);
966 void rtl8192_set_rxconf(struct net_device *dev)
968 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
971 rxconf=read_nic_dword(dev,RCR);
972 rxconf = rxconf &~ MAC_FILTER_MASK;
973 rxconf = rxconf | RCR_AMF;
974 rxconf = rxconf | RCR_ADF;
975 rxconf = rxconf | RCR_AB;
976 rxconf = rxconf | RCR_AM;
977 //rxconf = rxconf | RCR_ACF;
979 if (dev->flags & IFF_PROMISC) {DMESG ("NIC in promisc mode");}
981 if(priv->ieee80211->iw_mode == IW_MODE_MONITOR || \
982 dev->flags & IFF_PROMISC){
983 rxconf = rxconf | RCR_AAP;
984 } /*else if(priv->ieee80211->iw_mode == IW_MODE_MASTER){
985 rxconf = rxconf | (1<<ACCEPT_ALLMAC_FRAME_SHIFT);
986 rxconf = rxconf | (1<<RX_CHECK_BSSID_SHIFT);
988 rxconf = rxconf | RCR_APM;
989 rxconf = rxconf | RCR_CBSSID;
993 if(priv->ieee80211->iw_mode == IW_MODE_MONITOR){
994 rxconf = rxconf | RCR_AICV;
995 rxconf = rxconf | RCR_APWRMGT;
998 if( priv->crcmon == 1 && priv->ieee80211->iw_mode == IW_MODE_MONITOR)
999 rxconf = rxconf | RCR_ACRC32;
1002 rxconf = rxconf &~ RX_FIFO_THRESHOLD_MASK;
1003 rxconf = rxconf | (RX_FIFO_THRESHOLD_NONE<<RX_FIFO_THRESHOLD_SHIFT);
1004 rxconf = rxconf &~ MAX_RX_DMA_MASK;
1005 rxconf = rxconf | ((u32)7<<RCR_MXDMA_OFFSET);
1007 // rxconf = rxconf | (1<<RX_AUTORESETPHY_SHIFT);
1008 rxconf = rxconf | RCR_ONLYERLPKT;
1010 // rxconf = rxconf &~ RCR_CS_MASK;
1011 // rxconf = rxconf | (1<<RCR_CS_SHIFT);
1013 write_nic_dword(dev, RCR, rxconf);
1016 DMESG("rxconf: %x %x",rxconf ,read_nic_dword(dev,RCR));
1019 //wait to be removed
1020 void rtl8192_rx_enable(struct net_device *dev)
1024 //struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1026 rtl8192_rx_initiate(dev);
1028 // rtl8192_set_rxconf(dev);
1032 void rtl8192_tx_enable(struct net_device *dev)
1038 void rtl8192_rtx_disable(struct net_device *dev)
1041 struct r8192_priv *priv = ieee80211_priv(dev);
1042 struct sk_buff *skb;
1043 struct rtl8192_rx_info *info;
1045 cmd=read_nic_byte(dev,CMDR);
1046 write_nic_byte(dev, CMDR, cmd &~ \
1048 force_pci_posting(dev);
1051 while ((skb = __skb_dequeue(&priv->rx_queue))) {
1052 info = (struct rtl8192_rx_info *) skb->cb;
1056 usb_kill_urb(info->urb);
1060 if (skb_queue_len(&priv->skb_queue)) {
1061 printk(KERN_WARNING "skb_queue not empty\n");
1064 skb_queue_purge(&priv->skb_queue);
1069 int alloc_tx_beacon_desc_ring(struct net_device *dev, int count)
1074 inline u16 ieeerate2rtlrate(int rate)
1106 static u16 rtl_rate[] = {10,20,55,110,60,90,120,180,240,360,480,540};
1107 inline u16 rtl8192_rate2rate(short rate)
1109 if (rate >11) return 0;
1110 return rtl_rate[rate];
1114 /* The protype of rx_isr has changed since one verion of Linux Kernel */
1115 static void rtl8192_rx_isr(struct urb *urb)
1117 struct sk_buff *skb = (struct sk_buff *) urb->context;
1118 struct rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
1119 struct net_device *dev = info->dev;
1120 struct r8192_priv *priv = ieee80211_priv(dev);
1121 int out_pipe = info->out_pipe;
1125 if (unlikely(urb->status)) {
1127 priv->stats.rxstaterr++;
1128 priv->ieee80211->stats.rx_errors++;
1130 // printk("%s():rx status err\n",__FUNCTION__);
1133 skb_unlink(skb, &priv->rx_queue);
1134 skb_put(skb, urb->actual_length);
1136 skb_queue_tail(&priv->skb_queue, skb);
1137 tasklet_schedule(&priv->irq_rx_tasklet);
1139 skb = dev_alloc_skb(RX_URB_SIZE);
1140 if (unlikely(!skb)) {
1142 printk("%s():can,t alloc skb\n",__FUNCTION__);
1143 /* TODO check rx queue length and refill *somewhere* */
1147 usb_fill_bulk_urb(urb, priv->udev,
1148 usb_rcvbulkpipe(priv->udev, out_pipe), skb_tail_pointer(skb),
1149 RX_URB_SIZE, rtl8192_rx_isr, skb);
1151 info = (struct rtl8192_rx_info *) skb->cb;
1154 info->out_pipe = out_pipe;
1156 urb->transfer_buffer = skb_tail_pointer(skb);
1158 skb_queue_tail(&priv->rx_queue, skb);
1159 err = usb_submit_urb(urb, GFP_ATOMIC);
1160 if(err && err != EPERM)
1161 printk("can not submit rxurb, err is %x,URB status is %x\n",err,urb->status);
1165 rtl819xusb_rx_command_packet(
1166 struct net_device *dev,
1167 struct ieee80211_rx_stats *pstats
1172 //RT_TRACE(COMP_RECV, DBG_TRACE, ("---> RxCommandPacketHandle819xUsb()\n"));
1174 status = cmpk_message_handle_rx(dev, pstats);
1177 DMESG("rxcommandpackethandle819xusb: It is a command packet\n");
1181 //RT_TRACE(COMP_RECV, DBG_TRACE, ("RxCommandPacketHandle819xUsb: It is not a command packet\n"));
1184 //RT_TRACE(COMP_RECV, DBG_TRACE, ("<--- RxCommandPacketHandle819xUsb()\n"));
1189 void rtl8192_data_hard_stop(struct net_device *dev)
1195 void rtl8192_data_hard_resume(struct net_device *dev)
1200 /* this function TX data frames when the ieee80211 stack requires this.
1201 * It checks also if we need to stop the ieee tx queue, eventually do it
1203 void rtl8192_hard_data_xmit(struct sk_buff *skb, struct net_device *dev, int rate)
1205 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1207 unsigned long flags;
1208 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1209 u8 queue_index = tcb_desc->queue_index;
1211 /* shall not be referred by command packet */
1212 assert(queue_index != TXCMD_QUEUE);
1214 spin_lock_irqsave(&priv->tx_lock,flags);
1216 memcpy((unsigned char *)(skb->cb),&dev,sizeof(dev));
1217 // tcb_desc->RATRIndex = 7;
1218 // tcb_desc->bTxDisableRateFallBack = 1;
1219 // tcb_desc->bTxUseDriverAssingedRate = 1;
1220 tcb_desc->bTxEnableFwCalcDur = 1;
1221 skb_push(skb, priv->ieee80211->tx_headroom);
1222 ret = rtl8192_tx(dev, skb);
1224 //priv->ieee80211->stats.tx_bytes+=(skb->len - priv->ieee80211->tx_headroom);
1225 //priv->ieee80211->stats.tx_packets++;
1227 spin_unlock_irqrestore(&priv->tx_lock,flags);
1233 /* This is a rough attempt to TX a frame
1234 * This is called by the ieee 80211 stack to TX management frames.
1235 * If the ring is full packet are dropped (for data frame the queue
1236 * is stopped before this can happen).
1238 int rtl8192_hard_start_xmit(struct sk_buff *skb,struct net_device *dev)
1240 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1242 unsigned long flags;
1243 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1244 u8 queue_index = tcb_desc->queue_index;
1247 spin_lock_irqsave(&priv->tx_lock,flags);
1249 memcpy((unsigned char *)(skb->cb),&dev,sizeof(dev));
1250 if(queue_index == TXCMD_QUEUE) {
1251 skb_push(skb, USB_HWDESC_HEADER_LEN);
1252 rtl819xU_tx_cmd(dev, skb);
1254 spin_unlock_irqrestore(&priv->tx_lock,flags);
1257 skb_push(skb, priv->ieee80211->tx_headroom);
1258 ret = rtl8192_tx(dev, skb);
1261 spin_unlock_irqrestore(&priv->tx_lock,flags);
1267 void rtl8192_try_wake_queue(struct net_device *dev, int pri);
1269 #ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
1270 u16 DrvAggr_PaddingAdd(struct net_device *dev, struct sk_buff *skb)
1272 u16 PaddingNum = 256 - ((skb->len + TX_PACKET_DRVAGGR_SUBFRAME_SHIFT_BYTES) % 256);
1273 return (PaddingNum&0xff);
1276 u8 MRateToHwRate8190Pci(u8 rate);
1277 u8 QueryIsShort(u8 TxHT, u8 TxRate, cb_desc *tcb_desc);
1278 u8 MapHwQueueToFirmwareQueue(u8 QueueID);
1279 struct sk_buff *DrvAggr_Aggregation(struct net_device *dev, struct ieee80211_drv_agg_txb *pSendList)
1281 struct ieee80211_device *ieee = netdev_priv(dev);
1282 struct r8192_priv *priv = ieee80211_priv(dev);
1283 cb_desc *tcb_desc = NULL;
1286 struct sk_buff *skb;
1287 struct sk_buff *agg_skb;
1288 tx_desc_819x_usb_aggr_subframe *tx_agg_desc = NULL;
1289 tx_fwinfo_819x_usb *tx_fwinfo = NULL;
1292 // Local variable initialization.
1294 /* first skb initialization */
1295 skb = pSendList->tx_agg_frames[0];
1296 TotalLength = skb->len;
1298 /* Get the total aggregation length including the padding space and
1301 for(i = 1; i < pSendList->nr_drv_agg_frames; i++) {
1302 TotalLength += DrvAggr_PaddingAdd(dev, skb);
1303 skb = pSendList->tx_agg_frames[i];
1304 TotalLength += (skb->len + TX_PACKET_DRVAGGR_SUBFRAME_SHIFT_BYTES);
1307 /* allocate skb to contain the aggregated packets */
1308 agg_skb = dev_alloc_skb(TotalLength + ieee->tx_headroom);
1309 memset(agg_skb->data, 0, agg_skb->len);
1310 skb_reserve(agg_skb, ieee->tx_headroom);
1312 // RT_DEBUG_DATA(COMP_SEND, skb->cb, sizeof(skb->cb));
1313 /* reserve info for first subframe Tx descriptor to be set in the tx function */
1314 skb = pSendList->tx_agg_frames[0];
1315 tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1316 tcb_desc->drv_agg_enable = 1;
1317 tcb_desc->pkt_size = skb->len;
1318 tcb_desc->DrvAggrNum = pSendList->nr_drv_agg_frames;
1319 printk("DrvAggNum = %d\n", tcb_desc->DrvAggrNum);
1320 // RT_DEBUG_DATA(COMP_SEND, skb->cb, sizeof(skb->cb));
1321 // printk("========>skb->data ======> \n");
1322 // RT_DEBUG_DATA(COMP_SEND, skb->data, skb->len);
1323 memcpy(agg_skb->cb, skb->cb, sizeof(skb->cb));
1324 memcpy(skb_put(agg_skb,skb->len),skb->data,skb->len);
1326 for(i = 1; i < pSendList->nr_drv_agg_frames; i++) {
1327 /* push the next sub frame to be 256 byte aline */
1328 skb_put(agg_skb,DrvAggr_PaddingAdd(dev,skb));
1330 /* Subframe drv Tx descriptor and firmware info setting */
1331 skb = pSendList->tx_agg_frames[i];
1332 tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1333 tx_agg_desc = (tx_desc_819x_usb_aggr_subframe *)agg_skb->tail;
1334 tx_fwinfo = (tx_fwinfo_819x_usb *)(agg_skb->tail + sizeof(tx_desc_819x_usb_aggr_subframe));
1336 memset(tx_fwinfo,0,sizeof(tx_fwinfo_819x_usb));
1338 tx_fwinfo->TxHT = (tcb_desc->data_rate&0x80)?1:0;
1339 tx_fwinfo->TxRate = MRateToHwRate8190Pci(tcb_desc->data_rate);
1340 tx_fwinfo->EnableCPUDur = tcb_desc->bTxEnableFwCalcDur;
1341 tx_fwinfo->Short = QueryIsShort(tx_fwinfo->TxHT, tx_fwinfo->TxRate, tcb_desc);
1342 if(tcb_desc->bAMPDUEnable) {//AMPDU enabled
1343 tx_fwinfo->AllowAggregation = 1;
1345 tx_fwinfo->RxMF = tcb_desc->ampdu_factor;
1346 tx_fwinfo->RxAMD = tcb_desc->ampdu_density&0x07;//ampdudensity
1348 tx_fwinfo->AllowAggregation = 0;
1350 tx_fwinfo->RxMF = 0;
1351 tx_fwinfo->RxAMD = 0;
1354 /* Protection mode related */
1355 tx_fwinfo->RtsEnable = (tcb_desc->bRTSEnable)?1:0;
1356 tx_fwinfo->CtsEnable = (tcb_desc->bCTSEnable)?1:0;
1357 tx_fwinfo->RtsSTBC = (tcb_desc->bRTSSTBC)?1:0;
1358 tx_fwinfo->RtsHT = (tcb_desc->rts_rate&0x80)?1:0;
1359 tx_fwinfo->RtsRate = MRateToHwRate8190Pci((u8)tcb_desc->rts_rate);
1360 tx_fwinfo->RtsSubcarrier = (tx_fwinfo->RtsHT==0)?(tcb_desc->RTSSC):0;
1361 tx_fwinfo->RtsBandwidth = (tx_fwinfo->RtsHT==1)?((tcb_desc->bRTSBW)?1:0):0;
1362 tx_fwinfo->RtsShort = (tx_fwinfo->RtsHT==0)?(tcb_desc->bRTSUseShortPreamble?1:0):\
1363 (tcb_desc->bRTSUseShortGI?1:0);
1365 /* Set Bandwidth and sub-channel settings. */
1366 if(priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20_40)
1368 if(tcb_desc->bPacketBW) {
1369 tx_fwinfo->TxBandwidth = 1;
1370 tx_fwinfo->TxSubCarrier = 0; //By SD3's Jerry suggestion, use duplicated mode
1372 tx_fwinfo->TxBandwidth = 0;
1373 tx_fwinfo->TxSubCarrier = priv->nCur40MhzPrimeSC;
1376 tx_fwinfo->TxBandwidth = 0;
1377 tx_fwinfo->TxSubCarrier = 0;
1380 /* Fill Tx descriptor */
1381 memset(tx_agg_desc, 0, sizeof(tx_desc_819x_usb_aggr_subframe));
1383 //tx_agg_desc->LINIP = 0;
1384 //tx_agg_desc->CmdInit = 1;
1385 tx_agg_desc->Offset = sizeof(tx_fwinfo_819x_usb) + 8;
1386 /* already raw data, need not to substract header length */
1387 tx_agg_desc->PktSize = skb->len & 0xffff;
1390 tx_agg_desc->SecCAMID= 0;
1391 tx_agg_desc->RATid = tcb_desc->RATRIndex;
1394 tx_agg_desc->NoEnc = 1;
1396 tx_agg_desc->SecType = 0x0;
1398 if (tcb_desc->bHwSec) {
1399 switch (priv->ieee80211->pairwise_key_type)
1401 case KEY_TYPE_WEP40:
1402 case KEY_TYPE_WEP104:
1403 tx_agg_desc->SecType = 0x1;
1404 tx_agg_desc->NoEnc = 0;
1407 tx_agg_desc->SecType = 0x2;
1408 tx_agg_desc->NoEnc = 0;
1411 tx_agg_desc->SecType = 0x3;
1412 tx_agg_desc->NoEnc = 0;
1415 tx_agg_desc->SecType = 0x0;
1416 tx_agg_desc->NoEnc = 1;
1421 tx_agg_desc->QueueSelect = MapHwQueueToFirmwareQueue(tcb_desc->queue_index);
1422 tx_agg_desc->TxFWInfoSize = sizeof(tx_fwinfo_819x_usb);
1424 tx_agg_desc->DISFB = tcb_desc->bTxDisableRateFallBack;
1425 tx_agg_desc->USERATE = tcb_desc->bTxUseDriverAssingedRate;
1427 tx_agg_desc->OWN = 1;
1430 /* According windows driver, it seems that there no need to fill this field */
1431 //tx_agg_desc->TxBufferSize= (u32)(skb->len - USB_HWDESC_HEADER_LEN);
1433 /* to fill next packet */
1434 skb_put(agg_skb,TX_PACKET_DRVAGGR_SUBFRAME_SHIFT_BYTES);
1435 memcpy(skb_put(agg_skb,skb->len),skb->data,skb->len);
1438 for(i = 0; i < pSendList->nr_drv_agg_frames; i++) {
1439 dev_kfree_skb_any(pSendList->tx_agg_frames[i]);
1446 This function return a list of PTCB which is proper to be aggregate with the input TCB.
1447 If no proper TCB is found to do aggregation, SendList will only contain the input TCB.
1449 u8 DrvAggr_GetAggregatibleList(struct net_device *dev, struct sk_buff *skb,
1450 struct ieee80211_drv_agg_txb *pSendList)
1452 struct ieee80211_device *ieee = netdev_priv(dev);
1453 PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
1454 u16 nMaxAggrNum = pHTInfo->UsbTxAggrNum;
1455 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1456 u8 QueueID = tcb_desc->queue_index;
1459 pSendList->tx_agg_frames[pSendList->nr_drv_agg_frames++] = skb;
1460 if(pSendList->nr_drv_agg_frames >= nMaxAggrNum) {
1464 } while((skb = skb_dequeue(&ieee->skb_drv_aggQ[QueueID])));
1466 RT_TRACE(COMP_AMSDU, "DrvAggr_GetAggregatibleList, nAggrTcbNum = %d \n", pSendList->nr_drv_agg_frames);
1467 return pSendList->nr_drv_agg_frames;
1471 static void rtl8192_tx_isr(struct urb *tx_urb)
1473 struct sk_buff *skb = (struct sk_buff*)tx_urb->context;
1474 struct net_device *dev = NULL;
1475 struct r8192_priv *priv = NULL;
1476 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1477 u8 queue_index = tcb_desc->queue_index;
1478 // bool bToSend0Byte;
1479 // u16 BufLen = skb->len;
1481 memcpy(&dev,(struct net_device*)(skb->cb),sizeof(struct net_device*));
1482 priv = ieee80211_priv(dev);
1484 if(tcb_desc->queue_index != TXCMD_QUEUE) {
1485 if(tx_urb->status == 0) {
1486 dev->trans_start = jiffies;
1487 // As act as station mode, destion shall be unicast address.
1488 //priv->ieee80211->stats.tx_bytes+=(skb->len - priv->ieee80211->tx_headroom);
1489 //priv->ieee80211->stats.tx_packets++;
1490 priv->stats.txoktotal++;
1491 priv->ieee80211->LinkDetectInfo.NumTxOkInPeriod++;
1492 priv->stats.txbytesunicast += (skb->len - priv->ieee80211->tx_headroom);
1494 priv->ieee80211->stats.tx_errors++;
1495 //priv->stats.txmanageerr++;
1500 /* free skb and tx_urb */
1502 dev_kfree_skb_any(skb);
1503 usb_free_urb(tx_urb);
1504 atomic_dec(&priv->tx_pending[queue_index]);
1509 // Handle HW Beacon:
1510 // We had transfer our beacon frame to host controler at this moment.
1514 // Handling the wait queue of command packets.
1515 // For Tx command packets, we must not do TCB fragment because it is not handled right now.
1516 // We must cut the packets to match the size of TX_CMD_PKT before we send it.
1519 /* Handle MPDU in wait queue. */
1520 if(queue_index != BEACON_QUEUE) {
1521 /* Don't send data frame during scanning.*/
1522 if((skb_queue_len(&priv->ieee80211->skb_waitQ[queue_index]) != 0)&&\
1523 (!(priv->ieee80211->queue_stop))) {
1524 if(NULL != (skb = skb_dequeue(&(priv->ieee80211->skb_waitQ[queue_index]))))
1525 priv->ieee80211->softmac_hard_start_xmit(skb, dev);
1527 return; //modified by david to avoid further processing AMSDU
1529 #ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
1530 else if ((skb_queue_len(&priv->ieee80211->skb_drv_aggQ[queue_index])!= 0)&&\
1531 (!(priv->ieee80211->queue_stop))) {
1532 // Tx Driver Aggregation process
1533 /* The driver will aggregation the packets according to the following stets
1534 * 1. check whether there's tx irq available, for it's a completion return
1535 * function, it should contain enough tx irq;
1536 * 2. check pakcet type;
1537 * 3. intialize sendlist, check whether the to-be send packet no greater than 1
1538 * 4. aggregation the packets, and fill firmware info and tx desc to it, etc.
1539 * 5. check whehter the packet could be sent, otherwise just insert to wait head
1541 skb = skb_dequeue(&priv->ieee80211->skb_drv_aggQ[queue_index]);
1542 if(!check_nic_enough_desc(dev, queue_index)) {
1543 skb_queue_head(&(priv->ieee80211->skb_drv_aggQ[queue_index]), skb);
1550 u8* pHeader = skb->data;
1552 if(IsMgntQosData(pHeader) ||
1553 IsMgntQData_Ack(pHeader) ||
1554 IsMgntQData_Poll(pHeader) ||
1555 IsMgntQData_Poll_Ack(pHeader)
1559 struct ieee80211_drv_agg_txb SendList;
1561 memset(&SendList, 0, sizeof(struct ieee80211_drv_agg_txb));
1562 if(DrvAggr_GetAggregatibleList(dev, skb, &SendList) > 1) {
1563 skb = DrvAggr_Aggregation(dev, &SendList);
1567 priv->ieee80211->softmac_hard_start_xmit(skb, dev);
1576 void rtl8192_beacon_stop(struct net_device *dev)
1579 struct r8192_priv *priv = ieee80211_priv(dev);
1581 msr = read_nic_byte(dev, MSR);
1582 msrm = msr & MSR_LINK_MASK;
1583 msr2 = msr & ~MSR_LINK_MASK;
1585 if(NIC_8192U == priv->card_8192) {
1586 usb_kill_urb(priv->rx_urb[MAX_RX_URB]);
1588 if ((msrm == (MSR_LINK_ADHOC<<MSR_LINK_SHIFT) ||
1589 (msrm == (MSR_LINK_MASTER<<MSR_LINK_SHIFT)))){
1590 write_nic_byte(dev, MSR, msr2 | MSR_LINK_NONE);
1591 write_nic_byte(dev, MSR, msr);
1595 void rtl8192_config_rate(struct net_device* dev, u16* rate_config)
1597 struct r8192_priv *priv = ieee80211_priv(dev);
1598 struct ieee80211_network *net;
1599 u8 i=0, basic_rate = 0;
1600 net = & priv->ieee80211->current_network;
1602 for (i=0; i<net->rates_len; i++)
1604 basic_rate = net->rates[i]&0x7f;
1607 case MGN_1M: *rate_config |= RRSR_1M; break;
1608 case MGN_2M: *rate_config |= RRSR_2M; break;
1609 case MGN_5_5M: *rate_config |= RRSR_5_5M; break;
1610 case MGN_11M: *rate_config |= RRSR_11M; break;
1611 case MGN_6M: *rate_config |= RRSR_6M; break;
1612 case MGN_9M: *rate_config |= RRSR_9M; break;
1613 case MGN_12M: *rate_config |= RRSR_12M; break;
1614 case MGN_18M: *rate_config |= RRSR_18M; break;
1615 case MGN_24M: *rate_config |= RRSR_24M; break;
1616 case MGN_36M: *rate_config |= RRSR_36M; break;
1617 case MGN_48M: *rate_config |= RRSR_48M; break;
1618 case MGN_54M: *rate_config |= RRSR_54M; break;
1621 for (i=0; i<net->rates_ex_len; i++)
1623 basic_rate = net->rates_ex[i]&0x7f;
1626 case MGN_1M: *rate_config |= RRSR_1M; break;
1627 case MGN_2M: *rate_config |= RRSR_2M; break;
1628 case MGN_5_5M: *rate_config |= RRSR_5_5M; break;
1629 case MGN_11M: *rate_config |= RRSR_11M; break;
1630 case MGN_6M: *rate_config |= RRSR_6M; break;
1631 case MGN_9M: *rate_config |= RRSR_9M; break;
1632 case MGN_12M: *rate_config |= RRSR_12M; break;
1633 case MGN_18M: *rate_config |= RRSR_18M; break;
1634 case MGN_24M: *rate_config |= RRSR_24M; break;
1635 case MGN_36M: *rate_config |= RRSR_36M; break;
1636 case MGN_48M: *rate_config |= RRSR_48M; break;
1637 case MGN_54M: *rate_config |= RRSR_54M; break;
1643 #define SHORT_SLOT_TIME 9
1644 #define NON_SHORT_SLOT_TIME 20
1646 void rtl8192_update_cap(struct net_device* dev, u16 cap)
1649 struct r8192_priv *priv = ieee80211_priv(dev);
1650 struct ieee80211_network *net = &priv->ieee80211->current_network;
1651 priv->short_preamble = cap & WLAN_CAPABILITY_SHORT_PREAMBLE;
1652 tmp = priv->basic_rate;
1653 if (priv->short_preamble)
1654 tmp |= BRSR_AckShortPmb;
1655 write_nic_dword(dev, RRSR, tmp);
1657 if (net->mode & (IEEE_G|IEEE_N_24G))
1660 if ((cap & WLAN_CAPABILITY_SHORT_SLOT)&&(!priv->ieee80211->pHTInfo->bCurrentRT2RTLongSlotTime))
1662 slot_time = SHORT_SLOT_TIME;
1664 else //long slot time
1665 slot_time = NON_SHORT_SLOT_TIME;
1666 priv->slot_time = slot_time;
1667 write_nic_byte(dev, SLOT_TIME, slot_time);
1671 void rtl8192_net_update(struct net_device *dev)
1674 struct r8192_priv *priv = ieee80211_priv(dev);
1675 struct ieee80211_network *net;
1676 u16 BcnTimeCfg = 0, BcnCW = 6, BcnIFS = 0xf;
1677 u16 rate_config = 0;
1678 net = & priv->ieee80211->current_network;
1680 rtl8192_config_rate(dev, &rate_config);
1681 priv->basic_rate = rate_config &= 0x15f;
1683 write_nic_dword(dev,BSSIDR,((u32*)net->bssid)[0]);
1684 write_nic_word(dev,BSSIDR+4,((u16*)net->bssid)[2]);
1685 //for(i=0;i<ETH_ALEN;i++)
1686 // write_nic_byte(dev,BSSID+i,net->bssid[i]);
1688 rtl8192_update_msr(dev);
1689 // rtl8192_update_cap(dev, net->capability);
1690 if (priv->ieee80211->iw_mode == IW_MODE_ADHOC)
1692 write_nic_word(dev, ATIMWND, 2);
1693 write_nic_word(dev, BCN_DMATIME, 1023);
1694 write_nic_word(dev, BCN_INTERVAL, net->beacon_interval);
1695 // write_nic_word(dev, BcnIntTime, 100);
1696 write_nic_word(dev, BCN_DRV_EARLY_INT, 1);
1697 write_nic_byte(dev, BCN_ERR_THRESH, 100);
1698 BcnTimeCfg |= (BcnCW<<BCN_TCFG_CW_SHIFT);
1699 // TODO: BcnIFS may required to be changed on ASIC
1700 BcnTimeCfg |= BcnIFS<<BCN_TCFG_IFS;
1702 write_nic_word(dev, BCN_TCFG, BcnTimeCfg);
1709 //temporary hw beacon is not used any more.
1710 //open it when necessary
1711 void rtl819xusb_beacon_tx(struct net_device *dev,u16 tx_rate)
1715 inline u8 rtl8192_IsWirelessBMode(u16 rate)
1717 if( ((rate <= 110) && (rate != 60) && (rate != 90)) || (rate == 220) )
1722 u16 N_DBPSOfRate(u16 DataRate);
1727 u8 bManagementFrame,
1735 if( rtl8192_IsWirelessBMode(DataRate) )
1737 if( bManagementFrame || !bShortPreamble || DataRate == 10 )
1739 FrameTime = (u16)(144+48+(FrameLength*8/(DataRate/10)));
1743 FrameTime = (u16)(72+24+(FrameLength*8/(DataRate/10)));
1745 if( ( FrameLength*8 % (DataRate/10) ) != 0 ) //Get the Ceilling
1747 } else { //802.11g DSSS-OFDM PLCP length field calculation.
1748 N_DBPS = N_DBPSOfRate(DataRate);
1749 Ceiling = (16 + 8*FrameLength + 6) / N_DBPS
1750 + (((16 + 8*FrameLength + 6) % N_DBPS) ? 1 : 0);
1751 FrameTime = (u16)(16 + 4 + 4*Ceiling + 6);
1756 u16 N_DBPSOfRate(u16 DataRate)
1801 void rtl819xU_cmd_isr(struct urb *tx_cmd_urb, struct pt_regs *regs)
1803 usb_free_urb(tx_cmd_urb);
1806 unsigned int txqueue2outpipe(struct r8192_priv* priv,unsigned int tx_queue) {
1810 RT_TRACE(COMP_ERR,"%s():Unknown queue ID!!!\n",__FUNCTION__);
1813 return priv->txqueue_to_outpipemap[tx_queue];
1816 short rtl819xU_tx_cmd(struct net_device *dev, struct sk_buff *skb)
1818 struct r8192_priv *priv = ieee80211_priv(dev);
1823 unsigned int idx_pipe;
1824 tx_desc_cmd_819x_usb *pdesc = (tx_desc_cmd_819x_usb *)skb->data;
1825 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1826 u8 queue_index = tcb_desc->queue_index;
1828 //printk("\n %s::queue_index = %d\n",__FUNCTION__, queue_index);
1829 atomic_inc(&priv->tx_pending[queue_index]);
1830 tx_urb = usb_alloc_urb(0,GFP_ATOMIC);
1836 memset(pdesc, 0, USB_HWDESC_HEADER_LEN);
1837 /* Tx descriptor ought to be set according to the skb->cb */
1838 pdesc->FirstSeg = 1;//bFirstSeg;
1839 pdesc->LastSeg = 1;//bLastSeg;
1840 pdesc->CmdInit = tcb_desc->bCmdOrInit;
1841 pdesc->TxBufferSize = tcb_desc->txbuf_size;
1843 pdesc->LINIP = tcb_desc->bLastIniPkt;
1845 //----------------------------------------------------------------------------
1846 // Fill up USB_OUT_CONTEXT.
1847 //----------------------------------------------------------------------------
1848 // Get index to out pipe from specified QueueID.
1849 #ifndef USE_ONE_PIPE
1850 idx_pipe = txqueue2outpipe(priv,queue_index);
1854 #ifdef JOHN_DUMP_TXDESC
1856 printk("<Tx descriptor>--rate %x---",rate);
1857 for (i = 0; i < 8; i++)
1858 printk("%8x ", tx[i]);
1861 usb_fill_bulk_urb(tx_urb,priv->udev, usb_sndbulkpipe(priv->udev,idx_pipe), \
1862 skb->data, skb->len, rtl8192_tx_isr, skb);
1864 status = usb_submit_urb(tx_urb, GFP_ATOMIC);
1869 DMESGE("Error TX CMD URB, error %d",
1876 * Mapping Software/Hardware descriptor queue id to "Queue Select Field"
1877 * in TxFwInfo data structure
1878 * 2006.10.30 by Emily
1880 * \param QUEUEID Software Queue
1882 u8 MapHwQueueToFirmwareQueue(u8 QueueID)
1884 u8 QueueSelect = 0x0; //defualt set to
1888 QueueSelect = QSLT_BE; //or QSelect = pTcb->priority;
1892 QueueSelect = QSLT_BK; //or QSelect = pTcb->priority;
1896 QueueSelect = QSLT_VO; //or QSelect = pTcb->priority;
1900 QueueSelect = QSLT_VI; //or QSelect = pTcb->priority;
1903 QueueSelect = QSLT_MGNT;
1907 QueueSelect = QSLT_BEACON;
1910 // TODO: 2006.10.30 mark other queue selection until we verify it is OK
1911 // TODO: Remove Assertions
1912 //#if (RTL819X_FPGA_VER & RTL819X_FPGA_GUANGAN_070502)
1914 QueueSelect = QSLT_CMD;
1918 QueueSelect = QSLT_HIGH;
1922 RT_TRACE(COMP_ERR, "TransmitTCB(): Impossible Queue Selection: %d \n", QueueID);
1928 u8 MRateToHwRate8190Pci(u8 rate)
1930 u8 ret = DESC90_RATE1M;
1933 case MGN_1M: ret = DESC90_RATE1M; break;
1934 case MGN_2M: ret = DESC90_RATE2M; break;
1935 case MGN_5_5M: ret = DESC90_RATE5_5M; break;
1936 case MGN_11M: ret = DESC90_RATE11M; break;
1937 case MGN_6M: ret = DESC90_RATE6M; break;
1938 case MGN_9M: ret = DESC90_RATE9M; break;
1939 case MGN_12M: ret = DESC90_RATE12M; break;
1940 case MGN_18M: ret = DESC90_RATE18M; break;
1941 case MGN_24M: ret = DESC90_RATE24M; break;
1942 case MGN_36M: ret = DESC90_RATE36M; break;
1943 case MGN_48M: ret = DESC90_RATE48M; break;
1944 case MGN_54M: ret = DESC90_RATE54M; break;
1946 // HT rate since here
1947 case MGN_MCS0: ret = DESC90_RATEMCS0; break;
1948 case MGN_MCS1: ret = DESC90_RATEMCS1; break;
1949 case MGN_MCS2: ret = DESC90_RATEMCS2; break;
1950 case MGN_MCS3: ret = DESC90_RATEMCS3; break;
1951 case MGN_MCS4: ret = DESC90_RATEMCS4; break;
1952 case MGN_MCS5: ret = DESC90_RATEMCS5; break;
1953 case MGN_MCS6: ret = DESC90_RATEMCS6; break;
1954 case MGN_MCS7: ret = DESC90_RATEMCS7; break;
1955 case MGN_MCS8: ret = DESC90_RATEMCS8; break;
1956 case MGN_MCS9: ret = DESC90_RATEMCS9; break;
1957 case MGN_MCS10: ret = DESC90_RATEMCS10; break;
1958 case MGN_MCS11: ret = DESC90_RATEMCS11; break;
1959 case MGN_MCS12: ret = DESC90_RATEMCS12; break;
1960 case MGN_MCS13: ret = DESC90_RATEMCS13; break;
1961 case MGN_MCS14: ret = DESC90_RATEMCS14; break;
1962 case MGN_MCS15: ret = DESC90_RATEMCS15; break;
1963 case (0x80|0x20): ret = DESC90_RATEMCS32; break;
1971 u8 QueryIsShort(u8 TxHT, u8 TxRate, cb_desc *tcb_desc)
1975 tmp_Short = (TxHT==1)?((tcb_desc->bUseShortGI)?1:0):((tcb_desc->bUseShortPreamble)?1:0);
1977 if(TxHT==1 && TxRate != DESC90_RATEMCS15)
1983 static void tx_zero_isr(struct urb *tx_urb)
1989 * The tx procedure is just as following,
1990 * skb->cb will contain all the following information,
1991 * priority, morefrag, rate, &dev.
1993 short rtl8192_tx(struct net_device *dev, struct sk_buff* skb)
1995 struct r8192_priv *priv = ieee80211_priv(dev);
1996 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1997 tx_desc_819x_usb *tx_desc = (tx_desc_819x_usb *)skb->data;
1998 tx_fwinfo_819x_usb *tx_fwinfo = (tx_fwinfo_819x_usb *)(skb->data + USB_HWDESC_HEADER_LEN);
1999 struct usb_device *udev = priv->udev;
2002 struct urb *tx_urb = NULL, *tx_urb_zero = NULL;
2004 unsigned int idx_pipe;
2005 // RT_DEBUG_DATA(COMP_SEND, tcb_desc, sizeof(cb_desc));
2006 // printk("=============> %s\n", __FUNCTION__);
2007 pend = atomic_read(&priv->tx_pending[tcb_desc->queue_index]);
2008 /* we are locked here so the two atomic_read and inc are executed
2009 * without interleaves
2010 * !!! For debug purpose
2012 if( pend > MAX_TX_URB){
2013 printk("To discard skb packet!\n");
2014 dev_kfree_skb_any(skb);
2018 tx_urb = usb_alloc_urb(0,GFP_ATOMIC);
2020 dev_kfree_skb_any(skb);
2024 /* Fill Tx firmware info */
2025 memset(tx_fwinfo,0,sizeof(tx_fwinfo_819x_usb));
2027 tx_fwinfo->TxHT = (tcb_desc->data_rate&0x80)?1:0;
2028 tx_fwinfo->TxRate = MRateToHwRate8190Pci(tcb_desc->data_rate);
2029 tx_fwinfo->EnableCPUDur = tcb_desc->bTxEnableFwCalcDur;
2030 tx_fwinfo->Short = QueryIsShort(tx_fwinfo->TxHT, tx_fwinfo->TxRate, tcb_desc);
2031 if(tcb_desc->bAMPDUEnable) {//AMPDU enabled
2032 tx_fwinfo->AllowAggregation = 1;
2034 tx_fwinfo->RxMF = tcb_desc->ampdu_factor;
2035 tx_fwinfo->RxAMD = tcb_desc->ampdu_density&0x07;//ampdudensity
2037 tx_fwinfo->AllowAggregation = 0;
2039 tx_fwinfo->RxMF = 0;
2040 tx_fwinfo->RxAMD = 0;
2043 /* Protection mode related */
2044 tx_fwinfo->RtsEnable = (tcb_desc->bRTSEnable)?1:0;
2045 tx_fwinfo->CtsEnable = (tcb_desc->bCTSEnable)?1:0;
2046 tx_fwinfo->RtsSTBC = (tcb_desc->bRTSSTBC)?1:0;
2047 tx_fwinfo->RtsHT = (tcb_desc->rts_rate&0x80)?1:0;
2048 tx_fwinfo->RtsRate = MRateToHwRate8190Pci((u8)tcb_desc->rts_rate);
2049 tx_fwinfo->RtsSubcarrier = (tx_fwinfo->RtsHT==0)?(tcb_desc->RTSSC):0;
2050 tx_fwinfo->RtsBandwidth = (tx_fwinfo->RtsHT==1)?((tcb_desc->bRTSBW)?1:0):0;
2051 tx_fwinfo->RtsShort = (tx_fwinfo->RtsHT==0)?(tcb_desc->bRTSUseShortPreamble?1:0):\
2052 (tcb_desc->bRTSUseShortGI?1:0);
2054 /* Set Bandwidth and sub-channel settings. */
2055 if(priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20_40)
2057 if(tcb_desc->bPacketBW) {
2058 tx_fwinfo->TxBandwidth = 1;
2059 tx_fwinfo->TxSubCarrier = 0; //By SD3's Jerry suggestion, use duplicated mode
2061 tx_fwinfo->TxBandwidth = 0;
2062 tx_fwinfo->TxSubCarrier = priv->nCur40MhzPrimeSC;
2065 tx_fwinfo->TxBandwidth = 0;
2066 tx_fwinfo->TxSubCarrier = 0;
2069 #ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
2070 if (tcb_desc->drv_agg_enable)
2072 tx_fwinfo->Tx_INFO_RSVD = (tcb_desc->DrvAggrNum & 0x1f) << 1;
2075 /* Fill Tx descriptor */
2076 memset(tx_desc, 0, sizeof(tx_desc_819x_usb));
2079 tx_desc->CmdInit = 1;
2080 tx_desc->Offset = sizeof(tx_fwinfo_819x_usb) + 8;
2082 #ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
2083 if (tcb_desc->drv_agg_enable) {
2084 tx_desc->PktSize = tcb_desc->pkt_size;
2088 tx_desc->PktSize = (skb->len - TX_PACKET_SHIFT_BYTES) & 0xffff;
2092 tx_desc->SecCAMID= 0;
2093 tx_desc->RATid = tcb_desc->RATRIndex;
2098 tx_desc->SecType = 0x0;
2099 if (tcb_desc->bHwSec)
2101 switch (priv->ieee80211->pairwise_key_type)
2103 case KEY_TYPE_WEP40:
2104 case KEY_TYPE_WEP104:
2105 tx_desc->SecType = 0x1;
2109 tx_desc->SecType = 0x2;
2113 tx_desc->SecType = 0x3;
2117 tx_desc->SecType = 0x0;
2123 tx_desc->QueueSelect = MapHwQueueToFirmwareQueue(tcb_desc->queue_index);
2124 tx_desc->TxFWInfoSize = sizeof(tx_fwinfo_819x_usb);
2126 tx_desc->DISFB = tcb_desc->bTxDisableRateFallBack;
2127 tx_desc->USERATE = tcb_desc->bTxUseDriverAssingedRate;
2129 /* Fill fields that are required to be initialized in all of the descriptors */
2131 tx_desc->FirstSeg = 1;
2132 tx_desc->LastSeg = 1;
2135 #ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
2136 if (tcb_desc->drv_agg_enable) {
2137 tx_desc->TxBufferSize = tcb_desc->pkt_size + sizeof(tx_fwinfo_819x_usb);
2142 tx_desc->TxBufferSize = (u32)(skb->len - USB_HWDESC_HEADER_LEN);
2144 /* Get index to out pipe from specified QueueID */
2145 #ifndef USE_ONE_PIPE
2146 idx_pipe = txqueue2outpipe(priv,tcb_desc->queue_index);
2151 //RT_DEBUG_DATA(COMP_SEND,tx_fwinfo,sizeof(tx_fwinfo_819x_usb));
2152 //RT_DEBUG_DATA(COMP_SEND,tx_desc,sizeof(tx_desc_819x_usb));
2154 /* To submit bulk urb */
2155 usb_fill_bulk_urb(tx_urb,udev,
2156 usb_sndbulkpipe(udev,idx_pipe), skb->data,
2157 skb->len, rtl8192_tx_isr, skb);
2159 status = usb_submit_urb(tx_urb, GFP_ATOMIC);
2161 //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
2162 bool bSend0Byte = false;
2164 if(udev->speed == USB_SPEED_HIGH)
2166 if (skb->len > 0 && skb->len % 512 == 0)
2171 if (skb->len > 0 && skb->len % 64 == 0)
2176 tx_urb_zero = usb_alloc_urb(0,GFP_ATOMIC);
2178 RT_TRACE(COMP_ERR, "can't alloc urb for zero byte\n");
2181 usb_fill_bulk_urb(tx_urb_zero,udev,
2182 usb_sndbulkpipe(udev,idx_pipe), &zero,
2183 0, tx_zero_isr, dev);
2184 status = usb_submit_urb(tx_urb_zero, GFP_ATOMIC);
2186 RT_TRACE(COMP_ERR, "Error TX URB for zero byte %d, error %d", atomic_read(&priv->tx_pending[tcb_desc->queue_index]), status);
2190 dev->trans_start = jiffies;
2191 atomic_inc(&priv->tx_pending[tcb_desc->queue_index]);
2194 RT_TRACE(COMP_ERR, "Error TX URB %d, error %d", atomic_read(&priv->tx_pending[tcb_desc->queue_index]),
2200 short rtl8192_usb_initendpoints(struct net_device *dev)
2202 struct r8192_priv *priv = ieee80211_priv(dev);
2204 priv->rx_urb = kmalloc(sizeof(struct urb *) * (MAX_RX_URB+1),
2207 #ifndef JACKSON_NEW_RX
2208 for(i=0;i<(MAX_RX_URB+1);i++){
2210 priv->rx_urb[i] = usb_alloc_urb(0,GFP_KERNEL);
2212 priv->rx_urb[i]->transfer_buffer = kmalloc(RX_URB_SIZE, GFP_KERNEL);
2214 priv->rx_urb[i]->transfer_buffer_length = RX_URB_SIZE;
2218 #ifdef THOMAS_BEACON
2221 void *oldaddr, *newaddr;
2223 priv->rx_urb[16] = usb_alloc_urb(0, GFP_KERNEL);
2224 priv->oldaddr = kmalloc(16, GFP_KERNEL);
2225 oldaddr = priv->oldaddr;
2226 align = ((long)oldaddr) & 3;
2228 newaddr = oldaddr + 4 - align;
2229 priv->rx_urb[16]->transfer_buffer_length = 16 - 4 + align;
2232 priv->rx_urb[16]->transfer_buffer_length = 16;
2234 priv->rx_urb[16]->transfer_buffer = newaddr;
2238 memset(priv->rx_urb, 0, sizeof(struct urb*) * MAX_RX_URB);
2239 priv->pp_rxskb = kcalloc(MAX_RX_URB, sizeof(struct sk_buff *),
2241 if (priv->pp_rxskb == NULL)
2248 if (priv->pp_rxskb) {
2249 kfree(priv->pp_rxskb);
2252 kfree(priv->rx_urb);
2255 priv->pp_rxskb = NULL;
2256 priv->rx_urb = NULL;
2258 DMESGE("Endpoint Alloc Failure");
2264 printk("End of initendpoints\n");
2268 #ifdef THOMAS_BEACON
2269 void rtl8192_usb_deleteendpoints(struct net_device *dev)
2272 struct r8192_priv *priv = ieee80211_priv(dev);
2275 for(i=0;i<(MAX_RX_URB+1);i++){
2276 usb_kill_urb(priv->rx_urb[i]);
2277 usb_free_urb(priv->rx_urb[i]);
2279 kfree(priv->rx_urb);
2280 priv->rx_urb = NULL;
2283 kfree(priv->oldaddr);
2284 priv->oldaddr = NULL;
2286 if (priv->pp_rxskb) {
2287 kfree(priv->pp_rxskb);
2292 void rtl8192_usb_deleteendpoints(struct net_device *dev)
2295 struct r8192_priv *priv = ieee80211_priv(dev);
2297 #ifndef JACKSON_NEW_RX
2300 for(i=0;i<(MAX_RX_URB+1);i++){
2301 usb_kill_urb(priv->rx_urb[i]);
2302 kfree(priv->rx_urb[i]->transfer_buffer);
2303 usb_free_urb(priv->rx_urb[i]);
2305 kfree(priv->rx_urb);
2306 priv->rx_urb = NULL;
2311 kfree(priv->rx_urb);
2312 priv->rx_urb = NULL;
2315 kfree(priv->oldaddr);
2316 priv->oldaddr = NULL;
2318 if (priv->pp_rxskb) {
2319 kfree(priv->pp_rxskb);
2328 extern void rtl8192_update_ratr_table(struct net_device* dev);
2329 void rtl8192_link_change(struct net_device *dev)
2333 struct r8192_priv *priv = ieee80211_priv(dev);
2334 struct ieee80211_device* ieee = priv->ieee80211;
2335 //write_nic_word(dev, BCN_INTR_ITV, net->beacon_interval);
2336 if (ieee->state == IEEE80211_LINKED)
2338 rtl8192_net_update(dev);
2339 rtl8192_update_ratr_table(dev);
2340 //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
2341 if ((KEY_TYPE_WEP40 == ieee->pairwise_key_type) || (KEY_TYPE_WEP104 == ieee->pairwise_key_type))
2342 EnableHWSecurityConfig8192(dev);
2344 /*update timing params*/
2345 // RT_TRACE(COMP_CH, "========>%s(), chan:%d\n", __FUNCTION__, priv->chan);
2346 // rtl8192_set_chan(dev, priv->chan);
2347 if (ieee->iw_mode == IW_MODE_INFRA || ieee->iw_mode == IW_MODE_ADHOC)
2350 reg = read_nic_dword(dev, RCR);
2351 if (priv->ieee80211->state == IEEE80211_LINKED)
2352 priv->ReceiveConfig = reg |= RCR_CBSSID;
2354 priv->ReceiveConfig = reg &= ~RCR_CBSSID;
2355 write_nic_dword(dev, RCR, reg);
2358 // rtl8192_set_rxconf(dev);
2361 static struct ieee80211_qos_parameters def_qos_parameters = {
2362 {3,3,3,3},/* cw_min */
2363 {7,7,7,7},/* cw_max */
2364 {2,2,2,2},/* aifs */
2365 {0,0,0,0},/* flags */
2366 {0,0,0,0} /* tx_op_limit */
2370 void rtl8192_update_beacon(struct work_struct * work)
2372 struct r8192_priv *priv = container_of(work, struct r8192_priv, update_beacon_wq.work);
2373 struct net_device *dev = priv->ieee80211->dev;
2374 struct ieee80211_device* ieee = priv->ieee80211;
2375 struct ieee80211_network* net = &ieee->current_network;
2377 if (ieee->pHTInfo->bCurrentHTSupport)
2378 HTUpdateSelfAndPeerSetting(ieee, net);
2379 ieee->pHTInfo->bCurrentRT2RTLongSlotTime = net->bssht.bdRT2RTLongSlotTime;
2380 rtl8192_update_cap(dev, net->capability);
2383 * background support to run QoS activate functionality
2385 int WDCAPARA_ADD[] = {EDCAPARA_BE,EDCAPARA_BK,EDCAPARA_VI,EDCAPARA_VO};
2386 void rtl8192_qos_activate(struct work_struct * work)
2388 struct r8192_priv *priv = container_of(work, struct r8192_priv, qos_activate);
2389 struct net_device *dev = priv->ieee80211->dev;
2390 struct ieee80211_qos_parameters *qos_parameters = &priv->ieee80211->current_network.qos_data.parameters;
2391 u8 mode = priv->ieee80211->current_network.mode;
2392 //u32 size = sizeof(struct ieee80211_qos_parameters);
2400 mutex_lock(&priv->mutex);
2401 if(priv->ieee80211->state != IEEE80211_LINKED)
2403 RT_TRACE(COMP_QOS,"qos active process with associate response received\n");
2404 /* It better set slot time at first */
2405 /* For we just support b/g mode at present, let the slot time at 9/20 selection */
2406 /* update the ac parameter to related registers */
2407 for(i = 0; i < QOS_QUEUE_NUM; i++) {
2408 //Mode G/A: slotTimeTimer = 9; Mode B: 20
2409 u1bAIFS = qos_parameters->aifs[i] * ((mode&(IEEE_G|IEEE_N_24G)) ?9:20) + aSifsTime;
2410 u4bAcParam = ((((u32)(qos_parameters->tx_op_limit[i]))<< AC_PARAM_TXOP_LIMIT_OFFSET)|
2411 (((u32)(qos_parameters->cw_max[i]))<< AC_PARAM_ECW_MAX_OFFSET)|
2412 (((u32)(qos_parameters->cw_min[i]))<< AC_PARAM_ECW_MIN_OFFSET)|
2413 ((u32)u1bAIFS << AC_PARAM_AIFS_OFFSET));
2415 write_nic_dword(dev, WDCAPARA_ADD[i], u4bAcParam);
2416 //write_nic_dword(dev, WDCAPARA_ADD[i], 0x005e4332);
2420 mutex_unlock(&priv->mutex);
2423 static int rtl8192_qos_handle_probe_response(struct r8192_priv *priv,
2425 struct ieee80211_network *network)
2428 u32 size = sizeof(struct ieee80211_qos_parameters);
2430 if(priv->ieee80211->state !=IEEE80211_LINKED)
2433 if ((priv->ieee80211->iw_mode != IW_MODE_INFRA))
2436 if (network->flags & NETWORK_HAS_QOS_MASK) {
2437 if (active_network &&
2438 (network->flags & NETWORK_HAS_QOS_PARAMETERS))
2439 network->qos_data.active = network->qos_data.supported;
2441 if ((network->qos_data.active == 1) && (active_network == 1) &&
2442 (network->flags & NETWORK_HAS_QOS_PARAMETERS) &&
2443 (network->qos_data.old_param_count !=
2444 network->qos_data.param_count)) {
2445 network->qos_data.old_param_count =
2446 network->qos_data.param_count;
2447 queue_work(priv->priv_wq, &priv->qos_activate);
2448 RT_TRACE (COMP_QOS, "QoS parameters change call "
2452 memcpy(&priv->ieee80211->current_network.qos_data.parameters,\
2453 &def_qos_parameters, size);
2455 if ((network->qos_data.active == 1) && (active_network == 1)) {
2456 queue_work(priv->priv_wq, &priv->qos_activate);
2457 RT_TRACE(COMP_QOS, "QoS was disabled call qos_activate \n");
2459 network->qos_data.active = 0;
2460 network->qos_data.supported = 0;
2466 /* handle manage frame frame beacon and probe response */
2467 static int rtl8192_handle_beacon(struct net_device * dev,
2468 struct ieee80211_beacon * beacon,
2469 struct ieee80211_network * network)
2471 struct r8192_priv *priv = ieee80211_priv(dev);
2473 rtl8192_qos_handle_probe_response(priv,1,network);
2474 queue_delayed_work(priv->priv_wq, &priv->update_beacon_wq, 0);
2480 * handling the beaconing responses. if we get different QoS setting
2481 * off the network from the associated setting, adjust the QoS
2484 static int rtl8192_qos_association_resp(struct r8192_priv *priv,
2485 struct ieee80211_network *network)
2488 unsigned long flags;
2489 u32 size = sizeof(struct ieee80211_qos_parameters);
2490 int set_qos_param = 0;
2492 if ((priv == NULL) || (network == NULL))
2495 if(priv->ieee80211->state !=IEEE80211_LINKED)
2498 if ((priv->ieee80211->iw_mode != IW_MODE_INFRA))
2501 spin_lock_irqsave(&priv->ieee80211->lock, flags);
2502 if(network->flags & NETWORK_HAS_QOS_PARAMETERS) {
2503 memcpy(&priv->ieee80211->current_network.qos_data.parameters,\
2504 &network->qos_data.parameters,\
2505 sizeof(struct ieee80211_qos_parameters));
2506 priv->ieee80211->current_network.qos_data.active = 1;
2509 /* update qos parameter for current network */
2510 priv->ieee80211->current_network.qos_data.old_param_count = \
2511 priv->ieee80211->current_network.qos_data.param_count;
2512 priv->ieee80211->current_network.qos_data.param_count = \
2513 network->qos_data.param_count;
2516 memcpy(&priv->ieee80211->current_network.qos_data.parameters,\
2517 &def_qos_parameters, size);
2518 priv->ieee80211->current_network.qos_data.active = 0;
2519 priv->ieee80211->current_network.qos_data.supported = 0;
2523 spin_unlock_irqrestore(&priv->ieee80211->lock, flags);
2525 RT_TRACE(COMP_QOS, "%s: network->flags = %d,%d\n",__FUNCTION__,network->flags ,priv->ieee80211->current_network.qos_data.active);
2526 if (set_qos_param == 1)
2527 queue_work(priv->priv_wq, &priv->qos_activate);
2534 static int rtl8192_handle_assoc_response(struct net_device *dev,
2535 struct ieee80211_assoc_response_frame *resp,
2536 struct ieee80211_network *network)
2538 struct r8192_priv *priv = ieee80211_priv(dev);
2539 rtl8192_qos_association_resp(priv, network);
2544 void rtl8192_update_ratr_table(struct net_device* dev)
2545 // POCTET_STRING posLegacyRate,
2547 // PRT_WLAN_STA pEntry)
2549 struct r8192_priv* priv = ieee80211_priv(dev);
2550 struct ieee80211_device* ieee = priv->ieee80211;
2551 u8* pMcsRate = ieee->dot11HTOperationalRateSet;
2552 //struct ieee80211_network *net = &ieee->current_network;
2555 rtl8192_config_rate(dev, (u16*)(&ratr_value));
2556 ratr_value |= (*(u16*)(pMcsRate)) << 12;
2557 // switch (net->mode)
2561 ratr_value &= 0x00000FF0;
2564 ratr_value &= 0x0000000F;
2567 ratr_value &= 0x00000FF7;
2571 if (ieee->pHTInfo->PeerMimoPs == 0) //MIMO_PS_STATIC
2572 ratr_value &= 0x0007F007;
2574 if (priv->rf_type == RF_1T2R)
2575 ratr_value &= 0x000FF007;
2577 ratr_value &= 0x0F81F007;
2583 ratr_value &= 0x0FFFFFFF;
2584 if(ieee->pHTInfo->bCurTxBW40MHz && ieee->pHTInfo->bCurShortGI40MHz){
2585 ratr_value |= 0x80000000;
2586 }else if(!ieee->pHTInfo->bCurTxBW40MHz && ieee->pHTInfo->bCurShortGI20MHz){
2587 ratr_value |= 0x80000000;
2589 write_nic_dword(dev, RATR0+rate_index*4, ratr_value);
2590 write_nic_byte(dev, UFWP, 1);
2593 static u8 ccmp_ie[4] = {0x00,0x50,0xf2,0x04};
2594 static u8 ccmp_rsn_ie[4] = {0x00, 0x0f, 0xac, 0x04};
2595 bool GetNmodeSupportBySecCfg8192(struct net_device*dev)
2597 struct r8192_priv* priv = ieee80211_priv(dev);
2598 struct ieee80211_device* ieee = priv->ieee80211;
2599 struct ieee80211_network * network = &ieee->current_network;
2600 int wpa_ie_len= ieee->wpa_ie_len;
2601 struct ieee80211_crypt_data* crypt;
2604 crypt = ieee->crypt[ieee->tx_keyidx];
2605 //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
2606 encrypt = (network->capability & WLAN_CAPABILITY_PRIVACY) || (ieee->host_encrypt && crypt && crypt->ops && (0 == strcmp(crypt->ops->name,"WEP")));
2609 if(encrypt && (wpa_ie_len == 0)) {
2610 /* wep encryption, no N mode setting */
2612 // } else if((wpa_ie_len != 0)&&(memcmp(&(ieee->wpa_ie[14]),ccmp_ie,4))) {
2613 } else if((wpa_ie_len != 0)) {
2614 /* parse pairwise key type */
2615 //if((pairwisekey = WEP40)||(pairwisekey = WEP104)||(pairwisekey = TKIP))
2616 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))))
2627 bool GetHalfNmodeSupportByAPs819xUsb(struct net_device* dev)
2630 struct r8192_priv* priv = ieee80211_priv(dev);
2631 struct ieee80211_device* ieee = priv->ieee80211;
2633 if(ieee->bHalfWirelessN24GMode == true)
2641 void rtl8192_refresh_supportrate(struct r8192_priv* priv)
2643 struct ieee80211_device* ieee = priv->ieee80211;
2644 //we donot consider set support rate for ABG mode, only HT MCS rate is set here.
2645 if (ieee->mode == WIRELESS_MODE_N_24G || ieee->mode == WIRELESS_MODE_N_5G)
2647 memcpy(ieee->Regdot11HTOperationalRateSet, ieee->RegHTSuppRateSet, 16);
2648 //RT_DEBUG_DATA(COMP_INIT, ieee->RegHTSuppRateSet, 16);
2649 //RT_DEBUG_DATA(COMP_INIT, ieee->Regdot11HTOperationalRateSet, 16);
2652 memset(ieee->Regdot11HTOperationalRateSet, 0, 16);
2656 u8 rtl8192_getSupportedWireleeMode(struct net_device*dev)
2658 struct r8192_priv *priv = ieee80211_priv(dev);
2660 switch(priv->rf_chip)
2665 ret = (WIRELESS_MODE_N_24G|WIRELESS_MODE_G|WIRELESS_MODE_B);
2668 ret = (WIRELESS_MODE_A|WIRELESS_MODE_N_5G);
2671 ret = WIRELESS_MODE_B;
2676 void rtl8192_SetWirelessMode(struct net_device* dev, u8 wireless_mode)
2678 struct r8192_priv *priv = ieee80211_priv(dev);
2679 u8 bSupportMode = rtl8192_getSupportedWireleeMode(dev);
2681 if ((wireless_mode == WIRELESS_MODE_AUTO) || ((wireless_mode&bSupportMode)==0))
2683 if(bSupportMode & WIRELESS_MODE_N_24G)
2685 wireless_mode = WIRELESS_MODE_N_24G;
2687 else if(bSupportMode & WIRELESS_MODE_N_5G)
2689 wireless_mode = WIRELESS_MODE_N_5G;
2691 else if((bSupportMode & WIRELESS_MODE_A))
2693 wireless_mode = WIRELESS_MODE_A;
2695 else if((bSupportMode & WIRELESS_MODE_G))
2697 wireless_mode = WIRELESS_MODE_G;
2699 else if((bSupportMode & WIRELESS_MODE_B))
2701 wireless_mode = WIRELESS_MODE_B;
2704 RT_TRACE(COMP_ERR, "%s(), No valid wireless mode supported, SupportedWirelessMode(%x)!!!\n", __FUNCTION__,bSupportMode);
2705 wireless_mode = WIRELESS_MODE_B;
2708 #ifdef TO_DO_LIST //// TODO: this function doesn't work well at this time, we should wait for FPGA
2709 ActUpdateChannelAccessSetting( pAdapter, pHalData->CurrentWirelessMode, &pAdapter->MgntInfo.Info8185.ChannelAccessSetting );
2711 priv->ieee80211->mode = wireless_mode;
2713 if ((wireless_mode == WIRELESS_MODE_N_24G) || (wireless_mode == WIRELESS_MODE_N_5G))
2714 priv->ieee80211->pHTInfo->bEnableHT = 1;
2716 priv->ieee80211->pHTInfo->bEnableHT = 0;
2717 RT_TRACE(COMP_INIT, "Current Wireless Mode is %x\n", wireless_mode);
2718 rtl8192_refresh_supportrate(priv);
2721 //init priv variables here. only non_zero value should be initialized here.
2722 static void rtl8192_init_priv_variable(struct net_device* dev)
2724 struct r8192_priv *priv = ieee80211_priv(dev);
2726 priv->card_8192 = NIC_8192U;
2727 priv->chan = 1; //set to channel 1
2728 priv->ieee80211->mode = WIRELESS_MODE_AUTO; //SET AUTO
2729 priv->ieee80211->iw_mode = IW_MODE_INFRA;
2730 priv->ieee80211->ieee_up=0;
2731 priv->retry_rts = DEFAULT_RETRY_RTS;
2732 priv->retry_data = DEFAULT_RETRY_DATA;
2733 priv->ieee80211->rts = DEFAULT_RTS_THRESHOLD;
2734 priv->ieee80211->rate = 110; //11 mbps
2735 priv->ieee80211->short_slot = 1;
2736 priv->promisc = (dev->flags & IFF_PROMISC) ? 1:0;
2739 priv->IrpPendingCount = 1;
2740 priv->ResetProgress = RESET_TYPE_NORESET;
2741 priv->bForcedSilentReset = 0;
2742 priv->bDisableNormalResetCheck = false;
2743 priv->force_reset = false;
2745 priv->ieee80211->FwRWRF = 0; //we don't use FW read/write RF until stable firmware is available.
2746 priv->ieee80211->current_network.beacon_interval = DEFAULT_BEACONINTERVAL;
2747 priv->ieee80211->iw_mode = IW_MODE_INFRA;
2748 priv->ieee80211->softmac_features = IEEE_SOFTMAC_SCAN |
2749 IEEE_SOFTMAC_ASSOCIATE | IEEE_SOFTMAC_PROBERQ |
2750 IEEE_SOFTMAC_PROBERS | IEEE_SOFTMAC_TX_QUEUE |
2751 IEEE_SOFTMAC_BEACONS;//added by amy 080604 //| //IEEE_SOFTMAC_SINGLE_QUEUE;
2753 priv->ieee80211->active_scan = 1;
2754 priv->ieee80211->modulation = IEEE80211_CCK_MODULATION | IEEE80211_OFDM_MODULATION;
2755 priv->ieee80211->host_encrypt = 1;
2756 priv->ieee80211->host_decrypt = 1;
2757 priv->ieee80211->start_send_beacons = NULL;//rtl819xusb_beacon_tx;//-by amy 080604
2758 priv->ieee80211->stop_send_beacons = NULL;//rtl8192_beacon_stop;//-by amy 080604
2759 priv->ieee80211->softmac_hard_start_xmit = rtl8192_hard_start_xmit;
2760 priv->ieee80211->set_chan = rtl8192_set_chan;
2761 priv->ieee80211->link_change = rtl8192_link_change;
2762 priv->ieee80211->softmac_data_hard_start_xmit = rtl8192_hard_data_xmit;
2763 priv->ieee80211->data_hard_stop = rtl8192_data_hard_stop;
2764 priv->ieee80211->data_hard_resume = rtl8192_data_hard_resume;
2765 priv->ieee80211->init_wmmparam_flag = 0;
2766 priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD;
2767 priv->ieee80211->check_nic_enough_desc = check_nic_enough_desc;
2768 priv->ieee80211->tx_headroom = TX_PACKET_SHIFT_BYTES;
2769 priv->ieee80211->qos_support = 1;
2772 // priv->ieee80211->SwChnlByTimerHandler = rtl8192_phy_SwChnl;
2773 priv->ieee80211->SetBWModeHandler = rtl8192_SetBWMode;
2774 priv->ieee80211->handle_assoc_response = rtl8192_handle_assoc_response;
2775 priv->ieee80211->handle_beacon = rtl8192_handle_beacon;
2777 priv->ieee80211->GetNmodeSupportBySecCfg = GetNmodeSupportBySecCfg8192;
2778 priv->ieee80211->GetHalfNmodeSupportByAPsHandler = GetHalfNmodeSupportByAPs819xUsb;
2779 priv->ieee80211->SetWirelessMode = rtl8192_SetWirelessMode;
2781 priv->ieee80211->InitialGainHandler = InitialGain819xUsb;
2782 priv->card_type = USB;
2784 if(Adapter->bInHctTest)
2786 pHalData->ShortRetryLimit = 7;
2787 pHalData->LongRetryLimit = 7;
2791 priv->ShortRetryLimit = 0x30;
2792 priv->LongRetryLimit = 0x30;
2794 priv->EarlyRxThreshold = 7;
2795 priv->enable_gpio0 = 0;
2796 priv->TransmitConfig =
2797 // TCR_DurProcMode | //for RTL8185B, duration setting by HW
2798 //? TCR_DISReqQsize |
2799 (TCR_MXDMA_2048<<TCR_MXDMA_OFFSET)| // Max DMA Burst Size per Tx DMA Burst, 7: reservied.
2800 (priv->ShortRetryLimit<<TCR_SRL_OFFSET)| // Short retry limit
2801 (priv->LongRetryLimit<<TCR_LRL_OFFSET) | // Long retry limit
2802 (false ? TCR_SAT: 0); // FALSE: HW provies PLCP length and LENGEXT, TURE: SW proiveds them
2804 if(Adapter->bInHctTest)
2805 pHalData->ReceiveConfig = pHalData->CSMethod |
2806 RCR_AMF | RCR_ADF | //RCR_AAP | //accept management/data
2808 RCR_ACF | //accept control frame for SW AP needs PS-poll, 2005.07.07, by rcnjko.
2809 RCR_AB | RCR_AM | RCR_APM | //accept BC/MC/UC
2810 RCR_AICV | RCR_ACRC32 | //accept ICV/CRC error packet
2811 ((u32)7<<RCR_MXDMA_OFFSET) | // Max DMA Burst Size per Rx DMA Burst, 7: unlimited.
2812 (pHalData->EarlyRxThreshold<<RCR_FIFO_OFFSET) | // Rx FIFO Threshold, 7: No Rx threshold.
2813 (pHalData->EarlyRxThreshold == 7 ? RCR_OnlyErlPkt:0);
2817 priv->ReceiveConfig =
2818 RCR_AMF | RCR_ADF | //accept management/data
2819 RCR_ACF | //accept control frame for SW AP needs PS-poll, 2005.07.07, by rcnjko.
2820 RCR_AB | RCR_AM | RCR_APM | //accept BC/MC/UC
2821 //RCR_AICV | RCR_ACRC32 | //accept ICV/CRC error packet
2822 ((u32)7<<RCR_MXDMA_OFFSET)| // Max DMA Burst Size per Rx DMA Burst, 7: unlimited.
2823 (priv->EarlyRxThreshold<<RX_FIFO_THRESHOLD_SHIFT) | // Rx FIFO Threshold, 7: No Rx threshold.
2824 (priv->EarlyRxThreshold == 7 ? RCR_ONLYERLPKT:0);
2826 priv->AcmControl = 0;
2827 priv->pFirmware = kmalloc(sizeof(rt_firmware), GFP_KERNEL);
2828 if (priv->pFirmware)
2829 memset(priv->pFirmware, 0, sizeof(rt_firmware));
2831 /* rx related queue */
2832 skb_queue_head_init(&priv->rx_queue);
2833 skb_queue_head_init(&priv->skb_queue);
2835 /* Tx related queue */
2836 for(i = 0; i < MAX_QUEUE_SIZE; i++) {
2837 skb_queue_head_init(&priv->ieee80211->skb_waitQ [i]);
2839 for(i = 0; i < MAX_QUEUE_SIZE; i++) {
2840 skb_queue_head_init(&priv->ieee80211->skb_aggQ [i]);
2842 for(i = 0; i < MAX_QUEUE_SIZE; i++) {
2843 skb_queue_head_init(&priv->ieee80211->skb_drv_aggQ [i]);
2845 priv->rf_set_chan = rtl8192_phy_SwChnl;
2849 static void rtl8192_init_priv_lock(struct r8192_priv* priv)
2851 spin_lock_init(&priv->tx_lock);
2852 spin_lock_init(&priv->irq_lock);//added by thomas
2853 //spin_lock_init(&priv->rf_lock);
2854 sema_init(&priv->wx_sem,1);
2855 sema_init(&priv->rf_sem,1);
2856 mutex_init(&priv->mutex);
2859 extern void rtl819x_watchdog_wqcallback(struct work_struct *work);
2861 void rtl8192_irq_rx_tasklet(struct r8192_priv *priv);
2862 //init tasklet and wait_queue here. only 2.6 above kernel is considered
2863 #define DRV_NAME "wlan0"
2864 static void rtl8192_init_priv_task(struct net_device* dev)
2866 struct r8192_priv *priv = ieee80211_priv(dev);
2868 #ifdef PF_SYNCTHREAD
2869 priv->priv_wq = create_workqueue(DRV_NAME,0);
2871 priv->priv_wq = create_workqueue(DRV_NAME);
2874 INIT_WORK(&priv->reset_wq, rtl8192_restart);
2876 //INIT_DELAYED_WORK(&priv->watch_dog_wq, hal_dm_watchdog);
2877 INIT_DELAYED_WORK(&priv->watch_dog_wq, rtl819x_watchdog_wqcallback);
2878 INIT_DELAYED_WORK(&priv->txpower_tracking_wq, dm_txpower_trackingcallback);
2879 // INIT_DELAYED_WORK(&priv->gpio_change_rf_wq, dm_gpio_change_rf_callback);
2880 INIT_DELAYED_WORK(&priv->rfpath_check_wq, dm_rf_pathcheck_workitemcallback);
2881 INIT_DELAYED_WORK(&priv->update_beacon_wq, rtl8192_update_beacon);
2882 INIT_DELAYED_WORK(&priv->initialgain_operate_wq, InitialGainOperateWorkItemCallBack);
2883 //INIT_WORK(&priv->SwChnlWorkItem, rtl8192_SwChnl_WorkItem);
2884 //INIT_WORK(&priv->SetBWModeWorkItem, rtl8192_SetBWModeWorkItem);
2885 INIT_WORK(&priv->qos_activate, rtl8192_qos_activate);
2887 tasklet_init(&priv->irq_rx_tasklet,
2888 (void(*)(unsigned long))rtl8192_irq_rx_tasklet,
2889 (unsigned long)priv);
2892 static void rtl8192_get_eeprom_size(struct net_device* dev)
2895 struct r8192_priv *priv = ieee80211_priv(dev);
2896 RT_TRACE(COMP_EPROM, "===========>%s()\n", __FUNCTION__);
2897 curCR = read_nic_word_E(dev,EPROM_CMD);
2898 RT_TRACE(COMP_EPROM, "read from Reg EPROM_CMD(%x):%x\n", EPROM_CMD, curCR);
2899 //whether need I consider BIT5?
2900 priv->epromtype = (curCR & Cmd9346CR_9356SEL) ? EPROM_93c56 : EPROM_93c46;
2901 RT_TRACE(COMP_EPROM, "<===========%s(), epromtype:%d\n", __FUNCTION__, priv->epromtype);
2904 //used to swap endian. as ntohl & htonl are not neccessary to swap endian, so use this instead.
2905 static inline u16 endian_swap(u16* data)
2908 *data = (tmp >> 8) | (tmp << 8);
2911 static void rtl8192_read_eeprom_info(struct net_device* dev)
2914 u8 bMac_Tmp_Addr[6] = {0x00, 0xe0, 0x4c, 0x00, 0x00, 0x02};
2915 u8 bLoad_From_EEPOM = false;
2916 struct r8192_priv *priv = ieee80211_priv(dev);
2918 RT_TRACE(COMP_EPROM, "===========>%s()\n", __FUNCTION__);
2919 wEPROM_ID = eprom_read(dev, 0); //first read EEPROM ID out;
2920 RT_TRACE(COMP_EPROM, "EEPROM ID is 0x%x\n", wEPROM_ID);
2922 if (wEPROM_ID != RTL8190_EEPROM_ID)
2924 RT_TRACE(COMP_ERR, "EEPROM ID is invalid(is 0x%x(should be 0x%x)\n", wEPROM_ID, RTL8190_EEPROM_ID);
2927 bLoad_From_EEPOM = true;
2929 if (bLoad_From_EEPOM)
2931 tmpValue = eprom_read(dev, (EEPROM_VID>>1));
2932 priv->eeprom_vid = endian_swap(&tmpValue);
2933 priv->eeprom_pid = eprom_read(dev, (EEPROM_PID>>1));
2934 tmpValue = eprom_read(dev, (EEPROM_ChannelPlan>>1));
2935 priv->eeprom_ChannelPlan =((tmpValue&0xff00)>>8);
2936 priv->btxpowerdata_readfromEEPORM = true;
2937 priv->eeprom_CustomerID = eprom_read(dev, (EEPROM_Customer_ID>>1)) >>8;
2941 priv->eeprom_vid = 0;
2942 priv->eeprom_pid = 0;
2943 priv->card_8192_version = VERSION_819xU_B;
2944 priv->eeprom_ChannelPlan = 0;
2945 priv->eeprom_CustomerID = 0;
2947 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);
2948 //set channelplan from eeprom
2949 priv->ChannelPlan = priv->eeprom_ChannelPlan;
2950 if (bLoad_From_EEPOM)
2953 for (i=0; i<6; i+=2)
2956 tmp = eprom_read(dev, (u16)((EEPROM_NODE_ADDRESS_BYTE_0 + i)>>1));
2957 *(u16*)(&dev->dev_addr[i]) = tmp;
2962 memcpy(dev->dev_addr, bMac_Tmp_Addr, 6);
2963 //should I set IDR0 here?
2965 RT_TRACE(COMP_EPROM, "MAC addr:%pM\n", dev->dev_addr);
2966 priv->rf_type = RTL819X_DEFAULT_RF_TYPE; //default 1T2R
2967 priv->rf_chip = RF_8256;
2969 if (priv->card_8192_version == (u8)VERSION_819xU_A)
2971 //read Tx power gain offset of legacy OFDM to HT rate
2972 if (bLoad_From_EEPOM)
2973 priv->EEPROMTxPowerDiff = (eprom_read(dev, (EEPROM_TxPowerDiff>>1))&0xff00) >> 8;
2975 priv->EEPROMTxPowerDiff = EEPROM_Default_TxPower;
2976 RT_TRACE(COMP_EPROM, "TxPowerDiff:%d\n", priv->EEPROMTxPowerDiff);
2977 //read ThermalMeter from EEPROM
2978 if (bLoad_From_EEPOM)
2979 priv->EEPROMThermalMeter = (u8)(eprom_read(dev, (EEPROM_ThermalMeter>>1))&0x00ff);
2981 priv->EEPROMThermalMeter = EEPROM_Default_ThermalMeter;
2982 RT_TRACE(COMP_EPROM, "ThermalMeter:%d\n", priv->EEPROMThermalMeter);
2983 //vivi, for tx power track
2984 priv->TSSI_13dBm = priv->EEPROMThermalMeter *100;
2985 //read antenna tx power offset of B/C/D to A from EEPROM
2986 if (bLoad_From_EEPOM)
2987 priv->EEPROMPwDiff = (eprom_read(dev, (EEPROM_PwDiff>>1))&0x0f00)>>8;
2989 priv->EEPROMPwDiff = EEPROM_Default_PwDiff;
2990 RT_TRACE(COMP_EPROM, "TxPwDiff:%d\n", priv->EEPROMPwDiff);
2991 // Read CrystalCap from EEPROM
2992 if (bLoad_From_EEPOM)
2993 priv->EEPROMCrystalCap = (eprom_read(dev, (EEPROM_CrystalCap>>1))&0x0f);
2995 priv->EEPROMCrystalCap = EEPROM_Default_CrystalCap;
2996 RT_TRACE(COMP_EPROM, "CrystalCap = %d\n", priv->EEPROMCrystalCap);
2997 //get per-channel Tx power level
2998 if (bLoad_From_EEPOM)
2999 priv->EEPROM_Def_Ver = (eprom_read(dev, (EEPROM_TxPwIndex_Ver>>1))&0xff00)>>8;
3001 priv->EEPROM_Def_Ver = 1;
3002 RT_TRACE(COMP_EPROM, "EEPROM_DEF_VER:%d\n", priv->EEPROM_Def_Ver);
3003 if (priv->EEPROM_Def_Ver == 0) //old eeprom definition
3006 if (bLoad_From_EEPOM)
3007 priv->EEPROMTxPowerLevelCCK = (eprom_read(dev, (EEPROM_TxPwIndex_CCK>>1))&0xff) >> 8;
3009 priv->EEPROMTxPowerLevelCCK = 0x10;
3010 RT_TRACE(COMP_EPROM, "CCK Tx Power Levl: 0x%02x\n", priv->EEPROMTxPowerLevelCCK);
3013 if (bLoad_From_EEPOM)
3015 tmpValue = eprom_read(dev, (EEPROM_TxPwIndex_OFDM_24G+i)>>1);
3016 if (((EEPROM_TxPwIndex_OFDM_24G+i) % 2) == 0)
3017 tmpValue = tmpValue & 0x00ff;
3019 tmpValue = (tmpValue & 0xff00) >> 8;
3023 priv->EEPROMTxPowerLevelOFDM24G[i] = (u8) tmpValue;
3024 RT_TRACE(COMP_EPROM, "OFDM 2.4G Tx Power Level, Index %d = 0x%02x\n", i, priv->EEPROMTxPowerLevelCCK);
3026 }//end if EEPROM_DEF_VER == 0
3027 else if (priv->EEPROM_Def_Ver == 1)
3029 if (bLoad_From_EEPOM)
3031 tmpValue = eprom_read(dev, (EEPROM_TxPwIndex_CCK_V1>>1));
3032 tmpValue = (tmpValue & 0xff00) >> 8;
3036 priv->EEPROMTxPowerLevelCCK_V1[0] = (u8)tmpValue;
3038 if (bLoad_From_EEPOM)
3039 tmpValue = eprom_read(dev, (EEPROM_TxPwIndex_CCK_V1 + 2)>>1);
3042 *((u16*)(&priv->EEPROMTxPowerLevelCCK_V1[1])) = tmpValue;
3043 if (bLoad_From_EEPOM)
3044 tmpValue = eprom_read(dev, (EEPROM_TxPwIndex_OFDM_24G_V1>>1));
3047 *((u16*)(&priv->EEPROMTxPowerLevelOFDM24G[0])) = tmpValue;
3048 if (bLoad_From_EEPOM)
3049 tmpValue = eprom_read(dev, (EEPROM_TxPwIndex_OFDM_24G_V1+2)>>1);
3052 priv->EEPROMTxPowerLevelOFDM24G[2] = (u8)tmpValue;
3053 }//endif EEPROM_Def_Ver == 1
3055 //update HAL variables
3059 for (i=0; i<14; i++)
3062 priv->TxPowerLevelOFDM24G[i] = priv->EEPROMTxPowerLevelOFDM24G[0];
3063 else if (i>=4 && i<=9)
3064 priv->TxPowerLevelOFDM24G[i] = priv->EEPROMTxPowerLevelOFDM24G[1];
3066 priv->TxPowerLevelOFDM24G[i] = priv->EEPROMTxPowerLevelOFDM24G[2];
3069 for (i=0; i<14; i++)
3071 if (priv->EEPROM_Def_Ver == 0)
3074 priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelOFDM24G[0] + (priv->EEPROMTxPowerLevelCCK - priv->EEPROMTxPowerLevelOFDM24G[1]);
3075 else if (i>=4 && i<=9)
3076 priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelCCK;
3078 priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelOFDM24G[2] + (priv->EEPROMTxPowerLevelCCK - priv->EEPROMTxPowerLevelOFDM24G[1]);
3080 else if (priv->EEPROM_Def_Ver == 1)
3083 priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelCCK_V1[0];
3084 else if (i>=4 && i<=9)
3085 priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelCCK_V1[1];
3087 priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelCCK_V1[2];
3090 }//end update HAL variables
3091 priv->TxPowerDiff = priv->EEPROMPwDiff;
3092 // Antenna B gain offset to antenna A, bit0~3
3093 priv->AntennaTxPwDiff[0] = (priv->EEPROMTxPowerDiff & 0xf);
3094 // Antenna C gain offset to antenna A, bit4~7
3095 priv->AntennaTxPwDiff[1] = ((priv->EEPROMTxPowerDiff & 0xf0)>>4);
3096 // CrystalCap, bit12~15
3097 priv->CrystalCap = priv->EEPROMCrystalCap;
3098 // ThermalMeter, bit0~3 for RFIC1, bit4~7 for RFIC2
3099 // 92U does not enable TX power tracking.
3100 priv->ThermalMeter[0] = priv->EEPROMThermalMeter;
3101 }//end if VersionID == VERSION_819xU_A
3103 //added by vivi, for dlink led, 20080416
3104 switch(priv->eeprom_CustomerID)
3106 case EEPROM_CID_RUNTOP:
3107 priv->CustomerID = RT_CID_819x_RUNTOP;
3110 case EEPROM_CID_DLINK:
3111 priv->CustomerID = RT_CID_DLINK;
3115 priv->CustomerID = RT_CID_DEFAULT;
3120 switch(priv->CustomerID)
3122 case RT_CID_819x_RUNTOP:
3123 priv->LedStrategy = SW_LED_MODE2;
3127 priv->LedStrategy = SW_LED_MODE4;
3131 priv->LedStrategy = SW_LED_MODE0;
3137 if(priv->rf_type == RF_1T2R)
3139 RT_TRACE(COMP_EPROM, "\n1T2R config\n");
3143 RT_TRACE(COMP_EPROM, "\n2T4R config\n");
3146 // 2008/01/16 MH We can only know RF type in the function. So we have to init
3147 // DIG RATR table again.
3148 init_rate_adaptive(dev);
3149 //we need init DIG RATR table here again.
3151 RT_TRACE(COMP_EPROM, "<===========%s()\n", __FUNCTION__);
3155 short rtl8192_get_channel_map(struct net_device * dev)
3157 struct r8192_priv *priv = ieee80211_priv(dev);
3158 #ifdef ENABLE_DOT11D
3159 if(priv->ChannelPlan > COUNTRY_CODE_GLOBAL_DOMAIN){
3160 printk("rtl8180_init:Error channel plan! Set to default.\n");
3161 priv->ChannelPlan= 0;
3163 RT_TRACE(COMP_INIT, "Channel plan is %d\n",priv->ChannelPlan);
3165 rtl819x_set_channel_map(priv->ChannelPlan, priv);
3168 //Set Default Channel Plan
3170 DMESG("No channels, aborting");
3174 priv->ChannelPlan= 0;//hikaru
3175 // set channels 1..14 allowed in given locale
3176 for (i=1; i<=14; i++) {
3177 (priv->ieee80211->channel_map)[i] = (u8)(ch & 0x01);
3184 short rtl8192_init(struct net_device *dev)
3187 struct r8192_priv *priv = ieee80211_priv(dev);
3189 memset(&(priv->stats),0,sizeof(struct Stats));
3190 memset(priv->txqueue_to_outpipemap,0,9);
3194 u8 queuetopipe[]={3,2,1,0,4,8,7,6,5};
3195 memcpy(priv->txqueue_to_outpipemap,queuetopipe,9);
3197 printk("%d ",priv->txqueue_to_outpipemap[i]);
3202 u8 queuetopipe[]={3,2,1,0,4,4,0,4,4};
3203 memcpy(priv->txqueue_to_outpipemap,queuetopipe,9);
3205 printk("%d ",priv->txqueue_to_outpipemap[i]);
3209 rtl8192_init_priv_variable(dev);
3210 rtl8192_init_priv_lock(priv);
3211 rtl8192_init_priv_task(dev);
3212 rtl8192_get_eeprom_size(dev);
3213 rtl8192_read_eeprom_info(dev);
3214 rtl8192_get_channel_map(dev);
3216 init_timer(&priv->watch_dog_timer);
3217 priv->watch_dog_timer.data = (unsigned long)dev;
3218 priv->watch_dog_timer.function = watch_dog_timer_callback;
3219 if(rtl8192_usb_initendpoints(dev)!=0){
3220 DMESG("Endopoints initialization failed");
3224 //rtl8192_adapter_start(dev);
3231 /******************************************************************************
3232 *function: This function actually only set RRSR, RATR and BW_OPMODE registers
3233 * not to do all the hw config as its name says
3234 * input: net_device dev
3237 * notice: This part need to modified according to the rate set we filtered
3238 * ****************************************************************************/
3239 void rtl8192_hwconfig(struct net_device* dev)
3241 u32 regRATR = 0, regRRSR = 0;
3242 u8 regBwOpMode = 0, regTmp = 0;
3243 struct r8192_priv *priv = ieee80211_priv(dev);
3245 // Set RRSR, RATR, and BW_OPMODE registers
3247 switch(priv->ieee80211->mode)
3249 case WIRELESS_MODE_B:
3250 regBwOpMode = BW_OPMODE_20MHZ;
3251 regRATR = RATE_ALL_CCK;
3252 regRRSR = RATE_ALL_CCK;
3254 case WIRELESS_MODE_A:
3255 regBwOpMode = BW_OPMODE_5G |BW_OPMODE_20MHZ;
3256 regRATR = RATE_ALL_OFDM_AG;
3257 regRRSR = RATE_ALL_OFDM_AG;
3259 case WIRELESS_MODE_G:
3260 regBwOpMode = BW_OPMODE_20MHZ;
3261 regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
3262 regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
3264 case WIRELESS_MODE_AUTO:
3266 if (Adapter->bInHctTest)
3268 regBwOpMode = BW_OPMODE_20MHZ;
3269 regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
3270 regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
3275 regBwOpMode = BW_OPMODE_20MHZ;
3276 regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
3277 regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
3280 case WIRELESS_MODE_N_24G:
3281 // It support CCK rate by default.
3282 // CCK rate will be filtered out only when associated AP does not support it.
3283 regBwOpMode = BW_OPMODE_20MHZ;
3284 regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
3285 regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
3287 case WIRELESS_MODE_N_5G:
3288 regBwOpMode = BW_OPMODE_5G;
3289 regRATR = RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
3290 regRRSR = RATE_ALL_OFDM_AG;
3294 write_nic_byte(dev, BW_OPMODE, regBwOpMode);
3297 ratr_value = regRATR;
3298 if (priv->rf_type == RF_1T2R)
3300 ratr_value &= ~(RATE_ALL_OFDM_2SS);
3302 write_nic_dword(dev, RATR0, ratr_value);
3303 write_nic_byte(dev, UFWP, 1);
3305 regTmp = read_nic_byte(dev, 0x313);
3306 regRRSR = ((regTmp) << 24) | (regRRSR & 0x00ffffff);
3307 write_nic_dword(dev, RRSR, regRRSR);
3310 // Set Retry Limit here
3312 write_nic_word(dev, RETRY_LIMIT,
3313 priv->ShortRetryLimit << RETRY_LIMIT_SHORT_SHIFT | \
3314 priv->LongRetryLimit << RETRY_LIMIT_LONG_SHIFT);
3315 // Set Contention Window here
3319 // Set Tx Antenna including Feedback control
3321 // Set Auto Rate fallback control
3327 //InitializeAdapter and PhyCfg
3328 bool rtl8192_adapter_start(struct net_device *dev)
3330 struct r8192_priv *priv = ieee80211_priv(dev);
3332 bool init_status = true;
3333 RT_TRACE(COMP_INIT, "====>%s()\n", __FUNCTION__);
3334 priv->Rf_Mode = RF_OP_By_SW_3wire;
3335 //for ASIC power on sequence
3336 write_nic_byte_E(dev, 0x5f, 0x80);
3338 write_nic_byte_E(dev, 0x5f, 0xf0);
3339 write_nic_byte_E(dev, 0x5d, 0x00);
3340 write_nic_byte_E(dev, 0x5e, 0x80);
3341 write_nic_byte(dev, 0x17, 0x37);
3344 priv->pFirmware->firmware_status = FW_STATUS_0_INIT;
3345 //config CPUReset Register
3346 //Firmware Reset or not?
3347 dwRegRead = read_nic_dword(dev, CPU_GEN);
3348 if (priv->pFirmware->firmware_status == FW_STATUS_0_INIT)
3349 dwRegRead |= CPU_GEN_SYSTEM_RESET; //do nothing here?
3350 else if (priv->pFirmware->firmware_status == FW_STATUS_5_READY)
3351 dwRegRead |= CPU_GEN_FIRMWARE_RESET;
3353 RT_TRACE(COMP_ERR, "ERROR in %s(): undefined firmware state(%d)\n", __FUNCTION__, priv->pFirmware->firmware_status);
3355 write_nic_dword(dev, CPU_GEN, dwRegRead);
3358 rtl8192_BBConfig(dev);
3360 //Loopback mode or not
3361 priv->LoopbackMode = RTL819xU_NO_LOOPBACK;
3362 // priv->LoopbackMode = RTL819xU_MAC_LOOPBACK;
3364 dwRegRead = read_nic_dword(dev, CPU_GEN);
3365 if (priv->LoopbackMode == RTL819xU_NO_LOOPBACK)
3366 dwRegRead = ((dwRegRead & CPU_GEN_NO_LOOPBACK_MSK) | CPU_GEN_NO_LOOPBACK_SET);
3367 else if (priv->LoopbackMode == RTL819xU_MAC_LOOPBACK)
3368 dwRegRead |= CPU_CCK_LOOPBACK;
3370 RT_TRACE(COMP_ERR, "Serious error in %s(): wrong loopback mode setting(%d)\n", __FUNCTION__, priv->LoopbackMode);
3372 write_nic_dword(dev, CPU_GEN, dwRegRead);
3374 //after reset cpu, we need wait for a seconds to write in register.
3377 //xiong add for new bitfile:usb suspend reset pin set to 1. //do we need?
3378 write_nic_byte_E(dev, 0x5f, (read_nic_byte_E(dev, 0x5f)|0x20));
3381 rtl8192_hwconfig(dev);
3384 write_nic_byte(dev, CMDR, CR_RE|CR_TE);
3387 write_nic_dword(dev, MAC0, ((u32*)dev->dev_addr)[0]);
3388 write_nic_word(dev, MAC4, ((u16*)(dev->dev_addr + 4))[0]);
3391 write_nic_dword(dev, RCR, priv->ReceiveConfig);
3393 //Initialize Number of Reserved Pages in Firmware Queue
3394 write_nic_dword(dev, RQPN1, NUM_OF_PAGE_IN_FW_QUEUE_BK << RSVD_FW_QUEUE_PAGE_BK_SHIFT |\
3395 NUM_OF_PAGE_IN_FW_QUEUE_BE << RSVD_FW_QUEUE_PAGE_BE_SHIFT | \
3396 NUM_OF_PAGE_IN_FW_QUEUE_VI << RSVD_FW_QUEUE_PAGE_VI_SHIFT | \
3397 NUM_OF_PAGE_IN_FW_QUEUE_VO <<RSVD_FW_QUEUE_PAGE_VO_SHIFT);
3398 write_nic_dword(dev, RQPN2, NUM_OF_PAGE_IN_FW_QUEUE_MGNT << RSVD_FW_QUEUE_PAGE_MGNT_SHIFT |\
3399 NUM_OF_PAGE_IN_FW_QUEUE_CMD << RSVD_FW_QUEUE_PAGE_CMD_SHIFT);
3400 write_nic_dword(dev, RQPN3, APPLIED_RESERVED_QUEUE_IN_FW| \
3401 NUM_OF_PAGE_IN_FW_QUEUE_BCN<<RSVD_FW_QUEUE_PAGE_BCN_SHIFT
3402 // | NUM_OF_PAGE_IN_FW_QUEUE_PUB<<RSVD_FW_QUEUE_PAGE_PUB_SHIFT
3404 write_nic_dword(dev, RATR0+4*7, (RATE_ALL_OFDM_AG | RATE_ALL_CCK));
3407 // TODO: (it value is only for FPGA version). need to be changed!!2006.12.18, by Emily
3408 write_nic_byte(dev, ACK_TIMEOUT, 0x30);
3410 // RT_TRACE(COMP_INIT, "%s():priv->ResetProgress is %d\n", __FUNCTION__,priv->ResetProgress);
3411 if(priv->ResetProgress == RESET_TYPE_NORESET)
3412 rtl8192_SetWirelessMode(dev, priv->ieee80211->mode);
3413 if(priv->ResetProgress == RESET_TYPE_NORESET){
3414 CamResetAllEntry(dev);
3416 u8 SECR_value = 0x0;
3417 SECR_value |= SCR_TxEncEnable;
3418 SECR_value |= SCR_RxDecEnable;
3419 SECR_value |= SCR_NoSKMC;
3420 write_nic_byte(dev, SECR, SECR_value);
3425 write_nic_word(dev, ATIMWND, 2);
3426 write_nic_word(dev, BCN_INTERVAL, 100);
3429 #define DEFAULT_EDCA 0x005e4332
3431 for (i=0; i<QOS_QUEUE_NUM; i++)
3432 write_nic_dword(dev, WDCAPARA_ADD[i], DEFAULT_EDCA);
3434 #ifdef USB_RX_AGGREGATION_SUPPORT
3435 //3 For usb rx firmware aggregation control
3436 if(priv->ResetProgress == RESET_TYPE_NORESET)
3439 PRT_HIGH_THROUGHPUT pHTInfo = priv->ieee80211->pHTInfo;
3440 ulValue = (pHTInfo->UsbRxFwAggrEn<<24) | (pHTInfo->UsbRxFwAggrPageNum<<16) |
3441 (pHTInfo->UsbRxFwAggrPacketNum<<8) | (pHTInfo->UsbRxFwAggrTimeout);
3443 * If usb rx firmware aggregation is enabled,
3444 * when anyone of three threshold conditions above is reached,
3445 * firmware will send aggregated packet to driver.
3447 write_nic_dword(dev, 0x1a8, ulValue);
3448 priv->bCurrentRxAggrEnable = true;
3452 rtl8192_phy_configmac(dev);
3454 if (priv->card_8192_version == (u8) VERSION_819xU_A)
3456 rtl8192_phy_getTxPower(dev);
3457 rtl8192_phy_setTxPower(dev, priv->chan);
3461 init_status = init_firmware(dev);
3464 RT_TRACE(COMP_ERR,"ERR!!! %s(): Firmware download is failed\n", __FUNCTION__);
3467 RT_TRACE(COMP_INIT, "%s():after firmware download\n", __FUNCTION__);
3470 if(Adapter->ResetProgress == RESET_TYPE_NORESET)
3472 if(pMgntInfo->RegRfOff == TRUE)
3473 { // User disable RF via registry.
3474 RT_TRACE((COMP_INIT|COMP_RF), DBG_LOUD, ("InitializeAdapter819xUsb(): Turn off RF for RegRfOff ----------\n"));
3475 MgntActSet_RF_State(Adapter, eRfOff, RF_CHANGE_BY_SW);
3476 // Those action will be discard in MgntActSet_RF_State because off the same state
3477 for(eRFPath = 0; eRFPath <pHalData->NumTotalRFPath; eRFPath++)
3478 PHY_SetRFReg(Adapter, (RF90_RADIO_PATH_E)eRFPath, 0x4, 0xC00, 0x0);
3480 else if(pMgntInfo->RfOffReason > RF_CHANGE_BY_PS)
3481 { // H/W or S/W RF OFF before sleep.
3482 RT_TRACE((COMP_INIT|COMP_RF), DBG_LOUD, ("InitializeAdapter819xUsb(): Turn off RF for RfOffReason(%d) ----------\n", pMgntInfo->RfOffReason));
3483 MgntActSet_RF_State(Adapter, eRfOff, pMgntInfo->RfOffReason);
3487 pHalData->eRFPowerState = eRfOn;
3488 pMgntInfo->RfOffReason = 0;
3489 RT_TRACE((COMP_INIT|COMP_RF), DBG_LOUD, ("InitializeAdapter819xUsb(): RF is on ----------\n"));
3494 if(pHalData->eRFPowerState == eRfOff)
3496 MgntActSet_RF_State(Adapter, eRfOff, pMgntInfo->RfOffReason);
3497 // Those action will be discard in MgntActSet_RF_State because off the same state
3498 for(eRFPath = 0; eRFPath <pHalData->NumTotalRFPath; eRFPath++)
3499 PHY_SetRFReg(Adapter, (RF90_RADIO_PATH_E)eRFPath, 0x4, 0xC00, 0x0);
3504 if(priv->ResetProgress == RESET_TYPE_NORESET){
3505 rtl8192_phy_RFConfig(dev);
3506 RT_TRACE(COMP_INIT, "%s():after phy RF config\n", __FUNCTION__);
3510 if(priv->ieee80211->FwRWRF)
3511 // We can force firmware to do RF-R/W
3512 priv->Rf_Mode = RF_OP_By_FW;
3514 priv->Rf_Mode = RF_OP_By_SW_3wire;
3517 rtl8192_phy_updateInitGain(dev);
3518 /*--set CCK and OFDM Block "ON"--*/
3519 rtl8192_setBBreg(dev, rFPGA0_RFMOD, bCCKEn, 0x1);
3520 rtl8192_setBBreg(dev, rFPGA0_RFMOD, bOFDMEn, 0x1);
3522 if(priv->ResetProgress == RESET_TYPE_NORESET)
3525 u8 tmpvalue = read_nic_byte(dev, 0x301);
3529 RT_TRACE(COMP_POWER_TRACKING, "D-cut\n");
3533 priv->bDcut = FALSE;
3534 RT_TRACE(COMP_POWER_TRACKING, "C-cut\n");
3536 dm_initialize_txpower_tracking(dev);
3538 if(priv->bDcut == TRUE)
3541 u32 tmpRegA= rtl8192_QueryBBReg(dev,rOFDM0_XATxIQImbalance,bMaskDWord);
3542 // u32 tmpRegC= rtl8192_QueryBBReg(dev,rOFDM0_XCTxIQImbalance,bMaskDWord);
3543 for(i = 0; i<TxBBGainTableLength; i++)
3545 if(tmpRegA == priv->txbbgain_table[i].txbbgain_value)
3547 priv->rfa_txpowertrackingindex= (u8)i;
3548 priv->rfa_txpowertrackingindex_real= (u8)i;
3549 priv->rfa_txpowertracking_default= priv->rfa_txpowertrackingindex;
3554 TempCCk = rtl8192_QueryBBReg(dev, rCCK0_TxFilter1, bMaskByte2);
3556 for(i=0 ; i<CCKTxBBGainTableLength ; i++)
3559 if(TempCCk == priv->cck_txbbgain_table[i].ccktxbb_valuearray[0])
3561 priv->cck_present_attentuation_20Mdefault=(u8) i;
3565 priv->cck_present_attentuation_40Mdefault= 0;
3566 priv->cck_present_attentuation_difference= 0;
3567 priv->cck_present_attentuation = priv->cck_present_attentuation_20Mdefault;
3569 // pMgntInfo->bTXPowerTracking = FALSE;//TEMPLY DISABLE
3572 write_nic_byte(dev, 0x87, 0x0);
3578 /* this configures registers for beacon tx and enables it via
3579 * rtl8192_beacon_tx_enable(). rtl8192_beacon_tx_disable() might
3580 * be used to stop beacon transmission
3582 /***************************************************************************
3583 -------------------------------NET STUFF---------------------------
3584 ***************************************************************************/
3586 static struct net_device_stats *rtl8192_stats(struct net_device *dev)
3588 struct r8192_priv *priv = ieee80211_priv(dev);
3590 return &priv->ieee80211->stats;
3594 HalTxCheckStuck819xUsb(
3595 struct net_device *dev
3598 struct r8192_priv *priv = ieee80211_priv(dev);
3599 u16 RegTxCounter = read_nic_word(dev, 0x128);
3600 bool bStuck = FALSE;
3601 RT_TRACE(COMP_RESET,"%s():RegTxCounter is %d,TxCounter is %d\n",__FUNCTION__,RegTxCounter,priv->TxCounter);
3602 if(priv->TxCounter==RegTxCounter)
3605 priv->TxCounter = RegTxCounter;
3611 * <Assumption: RT_TX_SPINLOCK is acquired.>
3612 * First added: 2006.11.19 by emily
3615 TxCheckStuck(struct net_device *dev)
3617 struct r8192_priv *priv = ieee80211_priv(dev);
3620 // u8 ResetThreshold;
3621 bool bCheckFwTxCnt = false;
3622 //unsigned long flags;
3625 // Decide Stuch threshold according to current power save mode
3628 // RT_TRACE(COMP_RESET, " ==> TxCheckStuck()\n");
3629 // PlatformAcquireSpinLock(Adapter, RT_TX_SPINLOCK);
3630 // spin_lock_irqsave(&priv->ieee80211->lock,flags);
3631 for (QueueID = 0; QueueID<=BEACON_QUEUE;QueueID ++)
3633 if(QueueID == TXCMD_QUEUE)
3635 #ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
3636 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))
3638 if((skb_queue_len(&priv->ieee80211->skb_waitQ[QueueID]) == 0) && (skb_queue_len(&priv->ieee80211->skb_aggQ[QueueID]) == 0))
3642 bCheckFwTxCnt = true;
3644 // PlatformReleaseSpinLock(Adapter, RT_TX_SPINLOCK);
3645 // spin_unlock_irqrestore(&priv->ieee80211->lock,flags);
3646 // RT_TRACE(COMP_RESET,"bCheckFwTxCnt is %d\n",bCheckFwTxCnt);
3649 if(HalTxCheckStuck819xUsb(dev))
3651 RT_TRACE(COMP_RESET, "TxCheckStuck(): Fw indicates no Tx condition! \n");
3652 return RESET_TYPE_SILENT;
3655 return RESET_TYPE_NORESET;
3659 HalRxCheckStuck819xUsb(struct net_device *dev)
3661 u16 RegRxCounter = read_nic_word(dev, 0x130);
3662 struct r8192_priv *priv = ieee80211_priv(dev);
3663 bool bStuck = FALSE;
3664 static u8 rx_chk_cnt = 0;
3665 RT_TRACE(COMP_RESET,"%s(): RegRxCounter is %d,RxCounter is %d\n",__FUNCTION__,RegRxCounter,priv->RxCounter);
3666 // If rssi is small, we should check rx for long time because of bad rx.
3667 // or maybe it will continuous silent reset every 2 seconds.
3669 if(priv->undecorated_smoothed_pwdb >= (RateAdaptiveTH_High+5))
3671 rx_chk_cnt = 0; //high rssi, check rx stuck right now.
3673 else if(priv->undecorated_smoothed_pwdb < (RateAdaptiveTH_High+5) &&
3674 ((priv->CurrentChannelBW!=HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb>=RateAdaptiveTH_Low_40M) ||
3675 (priv->CurrentChannelBW==HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb>=RateAdaptiveTH_Low_20M)) )
3686 else if(((priv->CurrentChannelBW!=HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb<RateAdaptiveTH_Low_40M) ||
3687 (priv->CurrentChannelBW==HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb<RateAdaptiveTH_Low_20M)) &&
3688 priv->undecorated_smoothed_pwdb >= VeryLowRSSI)
3692 //DbgPrint("RSSI < %d && RSSI >= %d, no check this time \n", RateAdaptiveTH_Low, VeryLowRSSI);
3698 //DbgPrint("RSSI < %d && RSSI >= %d, check this time \n", RateAdaptiveTH_Low, VeryLowRSSI);
3705 //DbgPrint("RSSI <= %d, no check this time \n", VeryLowRSSI);
3711 //DbgPrint("RSSI <= %d, check this time \n", VeryLowRSSI);
3715 if(priv->RxCounter==RegRxCounter)
3718 priv->RxCounter = RegRxCounter;
3724 RxCheckStuck(struct net_device *dev)
3726 struct r8192_priv *priv = ieee80211_priv(dev);
3728 bool bRxCheck = FALSE;
3730 // RT_TRACE(COMP_RESET," ==> RxCheckStuck()\n");
3731 //PlatformAcquireSpinLock(Adapter, RT_RX_SPINLOCK);
3733 if(priv->IrpPendingCount > 1)
3735 //PlatformReleaseSpinLock(Adapter, RT_RX_SPINLOCK);
3737 // RT_TRACE(COMP_RESET,"bRxCheck is %d \n",bRxCheck);
3740 if(HalRxCheckStuck819xUsb(dev))
3742 RT_TRACE(COMP_RESET, "RxStuck Condition\n");
3743 return RESET_TYPE_SILENT;
3746 return RESET_TYPE_NORESET;
3751 * This function is called by Checkforhang to check whether we should ask OS to reset driver
3753 * \param pAdapter The adapter context for this miniport
3755 * Note:NIC with USB interface sholud not call this function because we cannot scan descriptor
3756 * to judge whether there is tx stuck.
3757 * Note: This function may be required to be rewrite for Vista OS.
3758 * <<<Assumption: Tx spinlock has been acquired >>>
3760 * 8185 and 8185b does not implement this function. This is added by Emily at 2006.11.24
3763 rtl819x_ifcheck_resetornot(struct net_device *dev)
3765 struct r8192_priv *priv = ieee80211_priv(dev);
3766 RESET_TYPE TxResetType = RESET_TYPE_NORESET;
3767 RESET_TYPE RxResetType = RESET_TYPE_NORESET;
3768 RT_RF_POWER_STATE rfState;
3770 rfState = priv->ieee80211->eRFPowerState;
3772 TxResetType = TxCheckStuck(dev);
3773 if( rfState != eRfOff ||
3774 /*ADAPTER_TEST_STATUS_FLAG(Adapter, ADAPTER_STATUS_FW_DOWNLOAD_FAILURE)) &&*/
3775 (priv->ieee80211->iw_mode != IW_MODE_ADHOC))
3777 // If driver is in the status of firmware download failure , driver skips RF initialization and RF is
3778 // in turned off state. Driver should check whether Rx stuck and do silent reset. And
3779 // if driver is in firmware download failure status, driver should initialize RF in the following
3780 // silent reset procedure Emily, 2008.01.21
3782 // Driver should not check RX stuck in IBSS mode because it is required to
3783 // set Check BSSID in order to send beacon, however, if check BSSID is
3784 // set, STA cannot hear any packet a all. Emily, 2008.04.12
3785 RxResetType = RxCheckStuck(dev);
3787 if(TxResetType==RESET_TYPE_NORMAL || RxResetType==RESET_TYPE_NORMAL)
3788 return RESET_TYPE_NORMAL;
3789 else if(TxResetType==RESET_TYPE_SILENT || RxResetType==RESET_TYPE_SILENT){
3790 RT_TRACE(COMP_RESET,"%s():silent reset\n",__FUNCTION__);
3791 return RESET_TYPE_SILENT;
3794 return RESET_TYPE_NORESET;
3798 void rtl8192_cancel_deferred_work(struct r8192_priv* priv);
3799 int _rtl8192_up(struct net_device *dev);
3800 int rtl8192_close(struct net_device *dev);
3805 CamRestoreAllEntry( struct net_device *dev)
3808 struct r8192_priv *priv = ieee80211_priv(dev);
3809 u8* MacAddr = priv->ieee80211->current_network.bssid;
3811 static u8 CAM_CONST_ADDR[4][6] = {
3812 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
3813 {0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
3814 {0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
3815 {0x00, 0x00, 0x00, 0x00, 0x00, 0x03}};
3816 static u8 CAM_CONST_BROAD[] =
3817 {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
3819 RT_TRACE(COMP_SEC, "CamRestoreAllEntry: \n");
3822 if ((priv->ieee80211->pairwise_key_type == KEY_TYPE_WEP40)||
3823 (priv->ieee80211->pairwise_key_type == KEY_TYPE_WEP104))
3826 for(EntryId=0; EntryId<4; EntryId++)
3829 MacAddr = CAM_CONST_ADDR[EntryId];
3833 priv->ieee80211->pairwise_key_type,
3841 else if(priv->ieee80211->pairwise_key_type == KEY_TYPE_TKIP)
3845 if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
3849 priv->ieee80211->pairwise_key_type,
3857 priv->ieee80211->pairwise_key_type,
3863 else if(priv->ieee80211->pairwise_key_type == KEY_TYPE_CCMP)
3867 if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
3871 priv->ieee80211->pairwise_key_type,
3879 priv->ieee80211->pairwise_key_type,
3888 if(priv->ieee80211->group_key_type == KEY_TYPE_TKIP)
3890 MacAddr = CAM_CONST_BROAD;
3891 for(EntryId=1 ; EntryId<4 ; EntryId++)
3897 priv->ieee80211->group_key_type,
3903 if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
3907 priv->ieee80211->group_key_type,
3912 else if(priv->ieee80211->group_key_type == KEY_TYPE_CCMP)
3914 MacAddr = CAM_CONST_BROAD;
3915 for(EntryId=1; EntryId<4 ; EntryId++)
3921 priv->ieee80211->group_key_type,
3928 if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
3932 priv->ieee80211->group_key_type,
3938 //////////////////////////////////////////////////////////////
3939 // This function is used to fix Tx/Rx stop bug temporarily.
3940 // This function will do "system reset" to NIC when Tx or Rx is stuck.
3941 // The method checking Tx/Rx stuck of this function is supported by FW,
3942 // which reports Tx and Rx counter to register 0x128 and 0x130.
3943 //////////////////////////////////////////////////////////////
3945 rtl819x_ifsilentreset(struct net_device *dev)
3947 //OCTET_STRING asocpdu;
3948 struct r8192_priv *priv = ieee80211_priv(dev);
3950 int reset_status = 0;
3951 struct ieee80211_device *ieee = priv->ieee80211;
3954 // 2007.07.20. If we need to check CCK stop, please uncomment this line.
3955 //bStuck = Adapter->HalFunc.CheckHWStopHandler(Adapter);
3957 if(priv->ResetProgress==RESET_TYPE_NORESET)
3961 RT_TRACE(COMP_RESET,"=========>Reset progress!! \n");
3963 // Set the variable for reset.
3964 priv->ResetProgress = RESET_TYPE_SILENT;
3965 // rtl8192_close(dev);
3966 down(&priv->wx_sem);
3969 RT_TRACE(COMP_ERR,"%s():the driver is not up! return\n",__FUNCTION__);
3974 RT_TRACE(COMP_RESET,"%s():======>start to down the driver\n",__FUNCTION__);
3975 // if(!netif_queue_stopped(dev))
3976 // netif_stop_queue(dev);
3978 rtl8192_rtx_disable(dev);
3979 rtl8192_cancel_deferred_work(priv);
3981 del_timer_sync(&priv->watch_dog_timer);
3983 ieee->sync_scan_hurryup = 1;
3984 if(ieee->state == IEEE80211_LINKED)
3986 down(&ieee->wx_sem);
3987 printk("ieee->state is IEEE80211_LINKED\n");
3988 ieee80211_stop_send_beacons(priv->ieee80211);
3989 del_timer_sync(&ieee->associate_timer);
3990 cancel_delayed_work(&ieee->associate_retry_wq);
3991 ieee80211_stop_scan(ieee);
3992 netif_carrier_off(dev);
3996 printk("ieee->state is NOT LINKED\n");
3997 ieee80211_softmac_stop_protocol(priv->ieee80211); }
3999 RT_TRACE(COMP_RESET,"%s():<==========down process is finished\n",__FUNCTION__);
4000 //rtl8192_irq_disable(dev);
4001 RT_TRACE(COMP_RESET,"%s():===========>start to up the driver\n",__FUNCTION__);
4002 reset_status = _rtl8192_up(dev);
4004 RT_TRACE(COMP_RESET,"%s():<===========up process is finished\n",__FUNCTION__);
4005 if(reset_status == -EAGAIN)
4014 RT_TRACE(COMP_ERR," ERR!!! %s(): Reset Failed!!\n", __FUNCTION__);
4017 ieee->is_silent_reset = 1;
4018 EnableHWSecurityConfig8192(dev);
4019 if(ieee->state == IEEE80211_LINKED && ieee->iw_mode == IW_MODE_INFRA)
4021 ieee->set_chan(ieee->dev, ieee->current_network.channel);
4023 queue_work(ieee->wq, &ieee->associate_complete_wq);
4026 else if(ieee->state == IEEE80211_LINKED && ieee->iw_mode == IW_MODE_ADHOC)
4028 ieee->set_chan(ieee->dev, ieee->current_network.channel);
4029 ieee->link_change(ieee->dev);
4031 // notify_wx_assoc_event(ieee);
4033 ieee80211_start_send_beacons(ieee);
4035 if (ieee->data_hard_resume)
4036 ieee->data_hard_resume(ieee->dev);
4037 netif_carrier_on(ieee->dev);
4040 CamRestoreAllEntry(dev);
4042 priv->ResetProgress = RESET_TYPE_NORESET;
4043 priv->reset_count++;
4045 priv->bForcedSilentReset =false;
4046 priv->bResetInProgress = false;
4048 // For test --> force write UFWP.
4049 write_nic_byte(dev, UFWP, 1);
4050 RT_TRACE(COMP_RESET, "Reset finished!! ====>[%d]\n", priv->reset_count);
4054 void CAM_read_entry(
4055 struct net_device *dev,
4059 u32 target_command=0;
4060 u32 target_content=0;
4064 // printk("=======>start read CAM\n");
4065 for(entry_i=0;entry_i<CAM_CONTENT_COUNT;entry_i++)
4067 // polling bit, and No Write enable, and address
4068 target_command= entry_i+CAM_CONTENT_COUNT*iIndex;
4069 target_command= target_command | BIT31;
4071 //Check polling bit is clear
4075 ulStatus = read_nic_dword(dev, RWCAM);
4076 if(ulStatus & BIT31){
4083 write_nic_dword(dev, RWCAM, target_command);
4084 RT_TRACE(COMP_SEC,"CAM_read_entry(): WRITE A0: %x \n",target_command);
4085 // printk("CAM_read_entry(): WRITE A0: %lx \n",target_command);
4086 target_content = read_nic_dword(dev, RCAMO);
4087 RT_TRACE(COMP_SEC, "CAM_read_entry(): WRITE A8: %x \n",target_content);
4088 // printk("CAM_read_entry(): WRITE A8: %lx \n",target_content);
4093 void rtl819x_update_rxcounts(
4094 struct r8192_priv *priv,
4103 *TotalRxDataNum = 0;
4105 SlotIndex = (priv->ieee80211->LinkDetectInfo.SlotIndex++)%(priv->ieee80211->LinkDetectInfo.SlotNum);
4106 priv->ieee80211->LinkDetectInfo.RxBcnNum[SlotIndex] = priv->ieee80211->LinkDetectInfo.NumRecvBcnInPeriod;
4107 priv->ieee80211->LinkDetectInfo.RxDataNum[SlotIndex] = priv->ieee80211->LinkDetectInfo.NumRecvDataInPeriod;
4108 for( i=0; i<priv->ieee80211->LinkDetectInfo.SlotNum; i++ ){
4109 *TotalRxBcnNum += priv->ieee80211->LinkDetectInfo.RxBcnNum[i];
4110 *TotalRxDataNum += priv->ieee80211->LinkDetectInfo.RxDataNum[i];
4115 extern void rtl819x_watchdog_wqcallback(struct work_struct *work)
4117 struct delayed_work *dwork = container_of(work,struct delayed_work,work);
4118 struct r8192_priv *priv = container_of(dwork,struct r8192_priv,watch_dog_wq);
4119 struct net_device *dev = priv->ieee80211->dev;
4120 struct ieee80211_device* ieee = priv->ieee80211;
4121 RESET_TYPE ResetType = RESET_TYPE_NORESET;
4122 static u8 check_reset_cnt=0;
4123 bool bBusyTraffic = false;
4127 hal_dm_watchdog(dev);
4129 {//to get busy traffic condition
4130 if(ieee->state == IEEE80211_LINKED)
4132 if( ieee->LinkDetectInfo.NumRxOkInPeriod> 666 ||
4133 ieee->LinkDetectInfo.NumTxOkInPeriod> 666 ) {
4134 bBusyTraffic = true;
4136 ieee->LinkDetectInfo.NumRxOkInPeriod = 0;
4137 ieee->LinkDetectInfo.NumTxOkInPeriod = 0;
4138 ieee->LinkDetectInfo.bBusyTraffic = bBusyTraffic;
4141 //added by amy for AP roaming
4143 if(priv->ieee80211->state == IEEE80211_LINKED && priv->ieee80211->iw_mode == IW_MODE_INFRA)
4145 u32 TotalRxBcnNum = 0;
4146 u32 TotalRxDataNum = 0;
4148 rtl819x_update_rxcounts(priv, &TotalRxBcnNum, &TotalRxDataNum);
4149 if((TotalRxBcnNum+TotalRxDataNum) == 0)
4152 if(rfState == eRfOff)
4153 RT_TRACE(COMP_ERR,"========>%s()\n",__FUNCTION__);
4155 printk("===>%s(): AP is power off,connect another one\n",__FUNCTION__);
4156 // Dot11d_Reset(dev);
4157 priv->ieee80211->state = IEEE80211_ASSOCIATING;
4158 notify_wx_assoc_event(priv->ieee80211);
4159 RemovePeerTS(priv->ieee80211,priv->ieee80211->current_network.bssid);
4160 priv->ieee80211->link_change(dev);
4161 queue_work(priv->ieee80211->wq, &priv->ieee80211->associate_procedure_wq);
4165 priv->ieee80211->LinkDetectInfo.NumRecvBcnInPeriod=0;
4166 priv->ieee80211->LinkDetectInfo.NumRecvDataInPeriod=0;
4168 // CAM_read_entry(dev,4);
4169 //check if reset the driver
4170 if(check_reset_cnt++ >= 3)
4172 ResetType = rtl819x_ifcheck_resetornot(dev);
4173 check_reset_cnt = 3;
4174 //DbgPrint("Start to check silent reset\n");
4176 // 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);
4177 if( (priv->force_reset) || (priv->ResetProgress==RESET_TYPE_NORESET &&
4178 (priv->bForcedSilentReset ||
4179 (!priv->bDisableNormalResetCheck && ResetType==RESET_TYPE_SILENT)))) // This is control by OID set in Pomelo
4181 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);
4182 rtl819x_ifsilentreset(dev);
4184 priv->force_reset = false;
4185 priv->bForcedSilentReset = false;
4186 priv->bResetInProgress = false;
4187 RT_TRACE(COMP_TRACE, " <==RtUsbCheckForHangWorkItemCallback()\n");
4191 void watch_dog_timer_callback(unsigned long data)
4193 struct r8192_priv *priv = ieee80211_priv((struct net_device *) data);
4194 //printk("===============>watch_dog timer\n");
4195 queue_delayed_work(priv->priv_wq,&priv->watch_dog_wq, 0);
4196 mod_timer(&priv->watch_dog_timer, jiffies + MSECS(IEEE80211_WATCH_DOG_TIME));
4198 int _rtl8192_up(struct net_device *dev)
4200 struct r8192_priv *priv = ieee80211_priv(dev);
4202 int init_status = 0;
4204 priv->ieee80211->ieee_up=1;
4205 RT_TRACE(COMP_INIT, "Bringing up iface");
4206 init_status = rtl8192_adapter_start(dev);
4209 RT_TRACE(COMP_ERR,"ERR!!! %s(): initialization is failed!\n", __FUNCTION__);
4210 priv->up=priv->ieee80211->ieee_up = 0;
4213 RT_TRACE(COMP_INIT, "start adapter finished\n");
4214 rtl8192_rx_enable(dev);
4215 // rtl8192_tx_enable(dev);
4216 if(priv->ieee80211->state != IEEE80211_LINKED)
4217 ieee80211_softmac_start_protocol(priv->ieee80211);
4218 ieee80211_reset_queue(priv->ieee80211);
4219 watch_dog_timer_callback((unsigned long) dev);
4220 if(!netif_queue_stopped(dev))
4221 netif_start_queue(dev);
4223 netif_wake_queue(dev);
4229 int rtl8192_open(struct net_device *dev)
4231 struct r8192_priv *priv = ieee80211_priv(dev);
4233 down(&priv->wx_sem);
4234 ret = rtl8192_up(dev);
4241 int rtl8192_up(struct net_device *dev)
4243 struct r8192_priv *priv = ieee80211_priv(dev);
4245 if (priv->up == 1) return -1;
4247 return _rtl8192_up(dev);
4251 int rtl8192_close(struct net_device *dev)
4253 struct r8192_priv *priv = ieee80211_priv(dev);
4256 down(&priv->wx_sem);
4258 ret = rtl8192_down(dev);
4266 int rtl8192_down(struct net_device *dev)
4268 struct r8192_priv *priv = ieee80211_priv(dev);
4271 if (priv->up == 0) return -1;
4274 priv->ieee80211->ieee_up = 0;
4275 RT_TRACE(COMP_DOWN, "==========>%s()\n", __FUNCTION__);
4277 if (!netif_queue_stopped(dev))
4278 netif_stop_queue(dev);
4280 rtl8192_rtx_disable(dev);
4281 //rtl8192_irq_disable(dev);
4283 /* Tx related queue release */
4284 for(i = 0; i < MAX_QUEUE_SIZE; i++) {
4285 skb_queue_purge(&priv->ieee80211->skb_waitQ [i]);
4287 for(i = 0; i < MAX_QUEUE_SIZE; i++) {
4288 skb_queue_purge(&priv->ieee80211->skb_aggQ [i]);
4291 for(i = 0; i < MAX_QUEUE_SIZE; i++) {
4292 skb_queue_purge(&priv->ieee80211->skb_drv_aggQ [i]);
4295 //as cancel_delayed_work will del work->timer, so if work is not definedas struct delayed_work, it will corrupt
4296 // flush_scheduled_work();
4297 rtl8192_cancel_deferred_work(priv);
4299 del_timer_sync(&priv->watch_dog_timer);
4302 ieee80211_softmac_stop_protocol(priv->ieee80211);
4303 memset(&priv->ieee80211->current_network, 0 , offsetof(struct ieee80211_network, list));
4304 RT_TRACE(COMP_DOWN, "<==========%s()\n", __FUNCTION__);
4310 void rtl8192_commit(struct net_device *dev)
4312 struct r8192_priv *priv = ieee80211_priv(dev);
4313 int reset_status = 0;
4314 //u8 reset_times = 0;
4315 if (priv->up == 0) return ;
4318 rtl8192_cancel_deferred_work(priv);
4319 del_timer_sync(&priv->watch_dog_timer);
4320 //cancel_delayed_work(&priv->SwChnlWorkItem);
4322 ieee80211_softmac_stop_protocol(priv->ieee80211);
4324 //rtl8192_irq_disable(dev);
4325 rtl8192_rtx_disable(dev);
4326 reset_status = _rtl8192_up(dev);
4331 void rtl8192_restart(struct net_device *dev)
4333 struct r8192_priv *priv = ieee80211_priv(dev);
4335 void rtl8192_restart(struct work_struct *work)
4337 struct r8192_priv *priv = container_of(work, struct r8192_priv, reset_wq);
4338 struct net_device *dev = priv->ieee80211->dev;
4340 down(&priv->wx_sem);
4342 rtl8192_commit(dev);
4347 static void r8192_set_multicast(struct net_device *dev)
4349 struct r8192_priv *priv = ieee80211_priv(dev);
4352 //down(&priv->wx_sem);
4356 promisc = (dev->flags & IFF_PROMISC) ? 1:0;
4358 if (promisc != priv->promisc)
4359 // rtl8192_commit(dev);
4361 priv->promisc = promisc;
4363 //schedule_work(&priv->reset_wq);
4364 //up(&priv->wx_sem);
4368 int r8192_set_mac_adr(struct net_device *dev, void *mac)
4370 struct r8192_priv *priv = ieee80211_priv(dev);
4371 struct sockaddr *addr = mac;
4373 down(&priv->wx_sem);
4375 memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
4377 schedule_work(&priv->reset_wq);
4383 /* based on ipw2200 driver */
4384 int rtl8192_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
4386 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
4387 struct iwreq *wrq = (struct iwreq *)rq;
4389 struct ieee80211_device *ieee = priv->ieee80211;
4391 u8 broadcast_addr[6] = {0xff,0xff,0xff,0xff,0xff,0xff};
4392 struct iw_point *p = &wrq->u.data;
4393 struct ieee_param *ipw = NULL;//(struct ieee_param *)wrq->u.data.pointer;
4395 down(&priv->wx_sem);
4398 if (p->length < sizeof(struct ieee_param) || !p->pointer){
4403 ipw = kmalloc(p->length, GFP_KERNEL);
4408 if (copy_from_user(ipw, p->pointer, p->length)) {
4415 case RTL_IOCTL_WPA_SUPPLICANT:
4416 //parse here for HW security
4417 if (ipw->cmd == IEEE_CMD_SET_ENCRYPTION)
4419 if (ipw->u.crypt.set_tx)
4421 if (strcmp(ipw->u.crypt.alg, "CCMP") == 0)
4422 ieee->pairwise_key_type = KEY_TYPE_CCMP;
4423 else if (strcmp(ipw->u.crypt.alg, "TKIP") == 0)
4424 ieee->pairwise_key_type = KEY_TYPE_TKIP;
4425 else if (strcmp(ipw->u.crypt.alg, "WEP") == 0)
4427 if (ipw->u.crypt.key_len == 13)
4428 ieee->pairwise_key_type = KEY_TYPE_WEP104;
4429 else if (ipw->u.crypt.key_len == 5)
4430 ieee->pairwise_key_type = KEY_TYPE_WEP40;
4433 ieee->pairwise_key_type = KEY_TYPE_NA;
4435 if (ieee->pairwise_key_type)
4437 memcpy((u8*)key, ipw->u.crypt.key, 16);
4438 EnableHWSecurityConfig8192(dev);
4439 //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!
4441 setKey(dev, 4, ipw->u.crypt.idx, ieee->pairwise_key_type, (u8*)ieee->ap_mac_addr, 0, key);
4442 if (ieee->auth_mode != 2)
4443 setKey(dev, ipw->u.crypt.idx, ipw->u.crypt.idx, ieee->pairwise_key_type, (u8*)ieee->ap_mac_addr, 0, key);
4446 else //if (ipw->u.crypt.idx) //group key use idx > 0
4448 memcpy((u8*)key, ipw->u.crypt.key, 16);
4449 if (strcmp(ipw->u.crypt.alg, "CCMP") == 0)
4450 ieee->group_key_type= KEY_TYPE_CCMP;
4451 else if (strcmp(ipw->u.crypt.alg, "TKIP") == 0)
4452 ieee->group_key_type = KEY_TYPE_TKIP;
4453 else if (strcmp(ipw->u.crypt.alg, "WEP") == 0)
4455 if (ipw->u.crypt.key_len == 13)
4456 ieee->group_key_type = KEY_TYPE_WEP104;
4457 else if (ipw->u.crypt.key_len == 5)
4458 ieee->group_key_type = KEY_TYPE_WEP40;
4461 ieee->group_key_type = KEY_TYPE_NA;
4463 if (ieee->group_key_type)
4467 ipw->u.crypt.idx, //KeyIndex
4468 ieee->group_key_type, //KeyType
4469 broadcast_addr, //MacAddr
4475 #ifdef JOHN_HWSEC_DEBUG
4477 printk("@@ wrq->u pointer = ");
4478 for(i=0;i<wrq->u.data.length;i++){
4479 if(i%10==0) printk("\n");
4480 printk( "%8x|", ((u32*)wrq->u.data.pointer)[i] );
4483 #endif /*JOHN_HWSEC_DEBUG*/
4484 ret = ieee80211_wpa_supplicant_ioctl(priv->ieee80211, &wrq->u.data);
4498 u8 HwRateToMRate90(bool bIsHT, u8 rate)
4504 case DESC90_RATE1M: ret_rate = MGN_1M; break;
4505 case DESC90_RATE2M: ret_rate = MGN_2M; break;
4506 case DESC90_RATE5_5M: ret_rate = MGN_5_5M; break;
4507 case DESC90_RATE11M: ret_rate = MGN_11M; break;
4508 case DESC90_RATE6M: ret_rate = MGN_6M; break;
4509 case DESC90_RATE9M: ret_rate = MGN_9M; break;
4510 case DESC90_RATE12M: ret_rate = MGN_12M; break;
4511 case DESC90_RATE18M: ret_rate = MGN_18M; break;
4512 case DESC90_RATE24M: ret_rate = MGN_24M; break;
4513 case DESC90_RATE36M: ret_rate = MGN_36M; break;
4514 case DESC90_RATE48M: ret_rate = MGN_48M; break;
4515 case DESC90_RATE54M: ret_rate = MGN_54M; break;
4519 RT_TRACE(COMP_RECV, "HwRateToMRate90(): Non supported Rate [%x], bIsHT = %d!!!\n", rate, bIsHT);
4525 case DESC90_RATEMCS0: ret_rate = MGN_MCS0; break;
4526 case DESC90_RATEMCS1: ret_rate = MGN_MCS1; break;
4527 case DESC90_RATEMCS2: ret_rate = MGN_MCS2; break;
4528 case DESC90_RATEMCS3: ret_rate = MGN_MCS3; break;
4529 case DESC90_RATEMCS4: ret_rate = MGN_MCS4; break;
4530 case DESC90_RATEMCS5: ret_rate = MGN_MCS5; break;
4531 case DESC90_RATEMCS6: ret_rate = MGN_MCS6; break;
4532 case DESC90_RATEMCS7: ret_rate = MGN_MCS7; break;
4533 case DESC90_RATEMCS8: ret_rate = MGN_MCS8; break;
4534 case DESC90_RATEMCS9: ret_rate = MGN_MCS9; break;
4535 case DESC90_RATEMCS10: ret_rate = MGN_MCS10; break;
4536 case DESC90_RATEMCS11: ret_rate = MGN_MCS11; break;
4537 case DESC90_RATEMCS12: ret_rate = MGN_MCS12; break;
4538 case DESC90_RATEMCS13: ret_rate = MGN_MCS13; break;
4539 case DESC90_RATEMCS14: ret_rate = MGN_MCS14; break;
4540 case DESC90_RATEMCS15: ret_rate = MGN_MCS15; break;
4541 case DESC90_RATEMCS32: ret_rate = (0x80|0x20); break;
4545 RT_TRACE(COMP_RECV, "HwRateToMRate90(): Non supported Rate [%x], bIsHT = %d!!!\n",rate, bIsHT);
4554 * Function: UpdateRxPktTimeStamp
4555 * Overview: Recored down the TSF time stamp when receiving a packet
4563 * (pRfd->Status.TimeStampHigh is updated)
4564 * (pRfd->Status.TimeStampLow is updated)
4568 void UpdateRxPktTimeStamp8190 (struct net_device *dev, struct ieee80211_rx_stats *stats)
4570 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
4572 if(stats->bIsAMPDU && !stats->bFirstMPDU) {
4573 stats->mac_time[0] = priv->LastRxDescTSFLow;
4574 stats->mac_time[1] = priv->LastRxDescTSFHigh;
4576 priv->LastRxDescTSFLow = stats->mac_time[0];
4577 priv->LastRxDescTSFHigh = stats->mac_time[1];
4583 long rtl819x_translate_todbm(u8 signal_strength_index )// 0-100 index.
4585 long signal_power; // in dBm.
4587 // Translate to dBm (x=0.5y-95).
4588 signal_power = (long)((signal_strength_index + 1) >> 1);
4591 return signal_power;
4595 /* 2008/01/22 MH We can not delcare RSSI/EVM total value of sliding window to
4596 be a local static. Otherwise, it may increase when we return from S3/S4. The
4597 value will be kept in memory or disk. We must delcare the value in adapter
4598 and it will be reinitialized when return from S3/S4. */
4599 void rtl8192_process_phyinfo(struct r8192_priv * priv,u8* buffer, struct ieee80211_rx_stats * pprevious_stats, struct ieee80211_rx_stats * pcurrent_stats)
4601 bool bcheck = false;
4603 u32 nspatial_stream, tmp_val;
4605 static u32 slide_rssi_index=0, slide_rssi_statistics=0;
4606 static u32 slide_evm_index=0, slide_evm_statistics=0;
4607 static u32 last_rssi=0, last_evm=0;
4609 static u32 slide_beacon_adc_pwdb_index=0, slide_beacon_adc_pwdb_statistics=0;
4610 static u32 last_beacon_adc_pwdb=0;
4612 struct ieee80211_hdr_3addr *hdr;
4614 unsigned int frag,seq;
4615 hdr = (struct ieee80211_hdr_3addr *)buffer;
4616 sc = le16_to_cpu(hdr->seq_ctl);
4617 frag = WLAN_GET_SEQ_FRAG(sc);
4618 seq = WLAN_GET_SEQ_SEQ(sc);
4619 //cosa add 04292008 to record the sequence number
4620 pcurrent_stats->Seq_Num = seq;
4622 // Check whether we should take the previous packet into accounting
4624 if(!pprevious_stats->bIsAMPDU)
4626 // if previous packet is not aggregated packet
4633 if(slide_rssi_statistics++ >= PHY_RSSI_SLID_WIN_MAX)
4635 slide_rssi_statistics = PHY_RSSI_SLID_WIN_MAX;
4636 last_rssi = priv->stats.slide_signal_strength[slide_rssi_index];
4637 priv->stats.slide_rssi_total -= last_rssi;
4639 priv->stats.slide_rssi_total += pprevious_stats->SignalStrength;
4641 priv->stats.slide_signal_strength[slide_rssi_index++] = pprevious_stats->SignalStrength;
4642 if(slide_rssi_index >= PHY_RSSI_SLID_WIN_MAX)
4643 slide_rssi_index = 0;
4645 // <1> Showed on UI for user, in dbm
4646 tmp_val = priv->stats.slide_rssi_total/slide_rssi_statistics;
4647 priv->stats.signal_strength = rtl819x_translate_todbm((u8)tmp_val);
4648 pcurrent_stats->rssi = priv->stats.signal_strength;
4650 // If the previous packet does not match the criteria, neglect it
4652 if(!pprevious_stats->bPacketMatchBSSID)
4654 if(!pprevious_stats->bToSelfBA)
4662 //rtl8190_process_cck_rxpathsel(priv,pprevious_stats);//only rtl8190 supported
4667 priv->stats.num_process_phyinfo++;
4669 /* record the general signal strength to the sliding window. */
4672 // <2> Showed on UI for engineering
4673 // hardware does not provide rssi information for each rf path in CCK
4674 if(!pprevious_stats->bIsCCK && (pprevious_stats->bPacketToSelf || pprevious_stats->bToSelfBA))
4676 for (rfpath = RF90_PATH_A; rfpath < priv->NumTotalRFPath; rfpath++)
4678 if (!rtl8192_phy_CheckIsLegalRFPath(priv->ieee80211->dev, rfpath))
4681 //Fixed by Jacken 2008-03-20
4682 if(priv->stats.rx_rssi_percentage[rfpath] == 0)
4684 priv->stats.rx_rssi_percentage[rfpath] = pprevious_stats->RxMIMOSignalStrength[rfpath];
4685 //DbgPrint("MIMO RSSI initialize \n");
4687 if(pprevious_stats->RxMIMOSignalStrength[rfpath] > priv->stats.rx_rssi_percentage[rfpath])
4689 priv->stats.rx_rssi_percentage[rfpath] =
4690 ( (priv->stats.rx_rssi_percentage[rfpath]*(Rx_Smooth_Factor-1)) +
4691 (pprevious_stats->RxMIMOSignalStrength[rfpath])) /(Rx_Smooth_Factor);
4692 priv->stats.rx_rssi_percentage[rfpath] = priv->stats.rx_rssi_percentage[rfpath] + 1;
4696 priv->stats.rx_rssi_percentage[rfpath] =
4697 ( (priv->stats.rx_rssi_percentage[rfpath]*(Rx_Smooth_Factor-1)) +
4698 (pprevious_stats->RxMIMOSignalStrength[rfpath])) /(Rx_Smooth_Factor);
4700 RT_TRACE(COMP_DBG,"priv->stats.rx_rssi_percentage[rfPath] = %d \n" ,priv->stats.rx_rssi_percentage[rfpath] );
4708 RT_TRACE(COMP_RXDESC, "Smooth %s PWDB = %d\n",
4709 pprevious_stats->bIsCCK? "CCK": "OFDM",
4710 pprevious_stats->RxPWDBAll);
4712 if(pprevious_stats->bPacketBeacon)
4714 /* record the beacon pwdb to the sliding window. */
4715 if(slide_beacon_adc_pwdb_statistics++ >= PHY_Beacon_RSSI_SLID_WIN_MAX)
4717 slide_beacon_adc_pwdb_statistics = PHY_Beacon_RSSI_SLID_WIN_MAX;
4718 last_beacon_adc_pwdb = priv->stats.Slide_Beacon_pwdb[slide_beacon_adc_pwdb_index];
4719 priv->stats.Slide_Beacon_Total -= last_beacon_adc_pwdb;
4720 //DbgPrint("slide_beacon_adc_pwdb_index = %d, last_beacon_adc_pwdb = %d, Adapter->RxStats.Slide_Beacon_Total = %d\n",
4721 // slide_beacon_adc_pwdb_index, last_beacon_adc_pwdb, Adapter->RxStats.Slide_Beacon_Total);
4723 priv->stats.Slide_Beacon_Total += pprevious_stats->RxPWDBAll;
4724 priv->stats.Slide_Beacon_pwdb[slide_beacon_adc_pwdb_index] = pprevious_stats->RxPWDBAll;
4725 //DbgPrint("slide_beacon_adc_pwdb_index = %d, pPreviousRfd->Status.RxPWDBAll = %d\n", slide_beacon_adc_pwdb_index, pPreviousRfd->Status.RxPWDBAll);
4726 slide_beacon_adc_pwdb_index++;
4727 if(slide_beacon_adc_pwdb_index >= PHY_Beacon_RSSI_SLID_WIN_MAX)
4728 slide_beacon_adc_pwdb_index = 0;
4729 pprevious_stats->RxPWDBAll = priv->stats.Slide_Beacon_Total/slide_beacon_adc_pwdb_statistics;
4730 if(pprevious_stats->RxPWDBAll >= 3)
4731 pprevious_stats->RxPWDBAll -= 3;
4734 RT_TRACE(COMP_RXDESC, "Smooth %s PWDB = %d\n",
4735 pprevious_stats->bIsCCK? "CCK": "OFDM",
4736 pprevious_stats->RxPWDBAll);
4739 if(pprevious_stats->bPacketToSelf || pprevious_stats->bPacketBeacon || pprevious_stats->bToSelfBA)
4741 if(priv->undecorated_smoothed_pwdb < 0) // initialize
4743 priv->undecorated_smoothed_pwdb = pprevious_stats->RxPWDBAll;
4744 //DbgPrint("First pwdb initialize \n");
4746 if(pprevious_stats->RxPWDBAll > (u32)priv->undecorated_smoothed_pwdb)
4748 priv->undecorated_smoothed_pwdb =
4749 ( ((priv->undecorated_smoothed_pwdb)*(Rx_Smooth_Factor-1)) +
4750 (pprevious_stats->RxPWDBAll)) /(Rx_Smooth_Factor);
4751 priv->undecorated_smoothed_pwdb = priv->undecorated_smoothed_pwdb + 1;
4755 priv->undecorated_smoothed_pwdb =
4756 ( ((priv->undecorated_smoothed_pwdb)*(Rx_Smooth_Factor-1)) +
4757 (pprevious_stats->RxPWDBAll)) /(Rx_Smooth_Factor);
4765 /* record the general EVM to the sliding window. */
4766 if(pprevious_stats->SignalQuality == 0)
4771 if(pprevious_stats->bPacketToSelf || pprevious_stats->bPacketBeacon || pprevious_stats->bToSelfBA){
4772 if(slide_evm_statistics++ >= PHY_RSSI_SLID_WIN_MAX){
4773 slide_evm_statistics = PHY_RSSI_SLID_WIN_MAX;
4774 last_evm = priv->stats.slide_evm[slide_evm_index];
4775 priv->stats.slide_evm_total -= last_evm;
4778 priv->stats.slide_evm_total += pprevious_stats->SignalQuality;
4780 priv->stats.slide_evm[slide_evm_index++] = pprevious_stats->SignalQuality;
4781 if(slide_evm_index >= PHY_RSSI_SLID_WIN_MAX)
4782 slide_evm_index = 0;
4784 // <1> Showed on UI for user, in percentage.
4785 tmp_val = priv->stats.slide_evm_total/slide_evm_statistics;
4786 priv->stats.signal_quality = tmp_val;
4787 //cosa add 10/11/2007, Showed on UI for user in Windows Vista, for Link quality.
4788 priv->stats.last_signal_strength_inpercent = tmp_val;
4791 // <2> Showed on UI for engineering
4792 if(pprevious_stats->bPacketToSelf || pprevious_stats->bPacketBeacon || pprevious_stats->bToSelfBA)
4794 for(nspatial_stream = 0; nspatial_stream<2 ; nspatial_stream++) // 2 spatial stream
4796 if(pprevious_stats->RxMIMOSignalQuality[nspatial_stream] != -1)
4798 if(priv->stats.rx_evm_percentage[nspatial_stream] == 0) // initialize
4800 priv->stats.rx_evm_percentage[nspatial_stream] = pprevious_stats->RxMIMOSignalQuality[nspatial_stream];
4802 priv->stats.rx_evm_percentage[nspatial_stream] =
4803 ( (priv->stats.rx_evm_percentage[nspatial_stream]* (Rx_Smooth_Factor-1)) +
4804 (pprevious_stats->RxMIMOSignalQuality[nspatial_stream]* 1)) / (Rx_Smooth_Factor);
4813 /*-----------------------------------------------------------------------------
4814 * Function: rtl819x_query_rxpwrpercentage()
4818 * Input: char antpower
4822 * Return: 0-100 percentage
4826 * 05/26/2008 amy Create Version 0 porting from windows code.
4828 *---------------------------------------------------------------------------*/
4829 static u8 rtl819x_query_rxpwrpercentage(
4833 if ((antpower <= -100) || (antpower >= 20))
4837 else if (antpower >= 0)
4843 return (100+antpower);
4846 } /* QueryRxPwrPercentage */
4849 rtl819x_evm_dbtopercentage(
4861 ret_val = 0 - ret_val;
4869 // We want good-looking for signal strength/quality
4870 // 2007/7/19 01:09, by cosa.
4873 rtl819x_signal_scale_mapping(
4879 // Step 1. Scale mapping.
4880 if(currsig >= 61 && currsig <= 100)
4882 retsig = 90 + ((currsig - 60) / 4);
4884 else if(currsig >= 41 && currsig <= 60)
4886 retsig = 78 + ((currsig - 40) / 2);
4888 else if(currsig >= 31 && currsig <= 40)
4890 retsig = 66 + (currsig - 30);
4892 else if(currsig >= 21 && currsig <= 30)
4894 retsig = 54 + (currsig - 20);
4896 else if(currsig >= 5 && currsig <= 20)
4898 retsig = 42 + (((currsig - 5) * 2) / 3);
4900 else if(currsig == 4)
4904 else if(currsig == 3)
4908 else if(currsig == 2)
4912 else if(currsig == 1)
4924 static void rtl8192_query_rxphystatus(
4925 struct r8192_priv * priv,
4926 struct ieee80211_rx_stats * pstats,
4927 rx_drvinfo_819x_usb * pdrvinfo,
4928 struct ieee80211_rx_stats * precord_stats,
4929 bool bpacket_match_bssid,
4930 bool bpacket_toself,
4935 //PRT_RFD_STATUS pRtRfdStatus = &(pRfd->Status);
4936 phy_sts_ofdm_819xusb_t* pofdm_buf;
4937 phy_sts_cck_819xusb_t * pcck_buf;
4938 phy_ofdm_rx_status_rxsc_sgien_exintfflag* prxsc;
4940 u8 i, max_spatial_stream, tmp_rxsnr, tmp_rxevm, rxsc_sgien_exflg;
4941 char rx_pwr[4], rx_pwr_all=0;
4942 //long rx_avg_pwr = 0;
4943 char rx_snrX, rx_evmX;
4945 u32 RSSI, total_rssi=0;//, total_evm=0;
4946 // long signal_strength_index = 0;
4951 priv->stats.numqry_phystatus++;
4953 is_cck_rate = rx_hal_is_cck_rate(pdrvinfo);
4955 // Record it for next packet processing
4956 memset(precord_stats, 0, sizeof(struct ieee80211_rx_stats));
4957 pstats->bPacketMatchBSSID = precord_stats->bPacketMatchBSSID = bpacket_match_bssid;
4958 pstats->bPacketToSelf = precord_stats->bPacketToSelf = bpacket_toself;
4959 pstats->bIsCCK = precord_stats->bIsCCK = is_cck_rate;//RX_HAL_IS_CCK_RATE(pDrvInfo);
4960 pstats->bPacketBeacon = precord_stats->bPacketBeacon = bPacketBeacon;
4961 pstats->bToSelfBA = precord_stats->bToSelfBA = bToSelfBA;
4963 prxpkt = (u8*)pdrvinfo;
4965 /* Move pointer to the 16th bytes. Phy status start address. */
4966 prxpkt += sizeof(rx_drvinfo_819x_usb);
4968 /* Initial the cck and ofdm buffer pointer */
4969 pcck_buf = (phy_sts_cck_819xusb_t *)prxpkt;
4970 pofdm_buf = (phy_sts_ofdm_819xusb_t *)prxpkt;
4972 pstats->RxMIMOSignalQuality[0] = -1;
4973 pstats->RxMIMOSignalQuality[1] = -1;
4974 precord_stats->RxMIMOSignalQuality[0] = -1;
4975 precord_stats->RxMIMOSignalQuality[1] = -1;
4980 // (1)Hardware does not provide RSSI for CCK
4984 // (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive)
4986 u8 report;//, cck_agc_rpt;
4988 priv->stats.numqry_phystatusCCK++;
4990 if(!priv->bCckHighPower)
4992 report = pcck_buf->cck_agc_rpt & 0xc0;
4996 //Fixed by Jacken from Bryant 2008-03-20
4997 //Original value is -38 , -26 , -14 , -2
4998 //Fixed value is -35 , -23 , -11 , 6
5000 rx_pwr_all = -35 - (pcck_buf->cck_agc_rpt & 0x3e);
5003 rx_pwr_all = -23 - (pcck_buf->cck_agc_rpt & 0x3e);
5006 rx_pwr_all = -11 - (pcck_buf->cck_agc_rpt & 0x3e);
5009 rx_pwr_all = 6 - (pcck_buf->cck_agc_rpt & 0x3e);
5015 report = pcck_buf->cck_agc_rpt & 0x60;
5020 rx_pwr_all = -35 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1) ;
5023 rx_pwr_all = -23 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1);
5026 rx_pwr_all = -11 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1) ;
5029 rx_pwr_all = 6 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1) ;
5034 pwdb_all = rtl819x_query_rxpwrpercentage(rx_pwr_all);
5035 pstats->RxPWDBAll = precord_stats->RxPWDBAll = pwdb_all;
5036 pstats->RecvSignalPower = pwdb_all;
5039 // (3) Get Signal Quality (EVM)
5041 //if(bpacket_match_bssid)
5045 if(pstats->RxPWDBAll > 40)
5050 sq = pcck_buf->sq_rpt;
5052 if(pcck_buf->sq_rpt > 64)
5054 else if (pcck_buf->sq_rpt < 20)
5057 sq = ((64-sq) * 100) / 44;
5059 pstats->SignalQuality = precord_stats->SignalQuality = sq;
5060 pstats->RxMIMOSignalQuality[0] = precord_stats->RxMIMOSignalQuality[0] = sq;
5061 pstats->RxMIMOSignalQuality[1] = precord_stats->RxMIMOSignalQuality[1] = -1;
5066 priv->stats.numqry_phystatusHT++;
5068 // (1)Get RSSI for HT rate
5070 for(i=RF90_PATH_A; i<priv->NumTotalRFPath; i++)
5072 // 2008/01/30 MH we will judge RF RX path now.
5073 if (priv->brfpath_rxenable[i])
5078 if (!rtl8192_phy_CheckIsLegalRFPath(priv->ieee80211->dev, i))
5081 //Fixed by Jacken from Bryant 2008-03-20
5082 //Original value is 106
5083 rx_pwr[i] = ((pofdm_buf->trsw_gain_X[i]&0x3F)*2) - 106;
5085 //Get Rx snr value in DB
5086 tmp_rxsnr = pofdm_buf->rxsnr_X[i];
5087 rx_snrX = (char)(tmp_rxsnr);
5090 priv->stats.rxSNRdB[i] = (long)rx_snrX;
5092 /* Translate DBM to percentage. */
5093 RSSI = rtl819x_query_rxpwrpercentage(rx_pwr[i]);
5096 /* Record Signal Strength for next packet */
5097 //if(bpacket_match_bssid)
5099 pstats->RxMIMOSignalStrength[i] =(u8) RSSI;
5100 precord_stats->RxMIMOSignalStrength[i] =(u8) RSSI;
5106 // (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive)
5108 //Fixed by Jacken from Bryant 2008-03-20
5109 //Original value is 106
5110 rx_pwr_all = (((pofdm_buf->pwdb_all ) >> 1 )& 0x7f) -106;
5111 pwdb_all = rtl819x_query_rxpwrpercentage(rx_pwr_all);
5113 pstats->RxPWDBAll = precord_stats->RxPWDBAll = pwdb_all;
5114 pstats->RxPower = precord_stats->RxPower = rx_pwr_all;
5117 // (3)EVM of HT rate
5119 if(pdrvinfo->RxHT && pdrvinfo->RxRate>=DESC90_RATEMCS8 &&
5120 pdrvinfo->RxRate<=DESC90_RATEMCS15)
5121 max_spatial_stream = 2; //both spatial stream make sense
5123 max_spatial_stream = 1; //only spatial stream 1 makes sense
5125 for(i=0; i<max_spatial_stream; i++)
5127 tmp_rxevm = pofdm_buf->rxevm_X[i];
5128 rx_evmX = (char)(tmp_rxevm);
5130 // Do not use shift operation like "rx_evmX >>= 1" because the compilor of free build environment
5131 // fill most significant bit to "zero" when doing shifting operation which may change a negative
5132 // value to positive one, then the dbm value (which is supposed to be negative) is not correct anymore.
5135 evm = rtl819x_evm_dbtopercentage(rx_evmX);
5136 //if(bpacket_match_bssid)
5138 if(i==0) // Fill value in RFD, Get the first spatial stream only
5139 pstats->SignalQuality = precord_stats->SignalQuality = (u8)(evm & 0xff);
5140 pstats->RxMIMOSignalQuality[i] = precord_stats->RxMIMOSignalQuality[i] = (u8)(evm & 0xff);
5145 /* record rx statistics for debug */
5146 rxsc_sgien_exflg = pofdm_buf->rxsc_sgien_exflg;
5147 prxsc = (phy_ofdm_rx_status_rxsc_sgien_exintfflag *)&rxsc_sgien_exflg;
5148 if(pdrvinfo->BW) //40M channel
5149 priv->stats.received_bwtype[1+prxsc->rxsc]++;
5151 priv->stats.received_bwtype[0]++;
5154 //UI BSS List signal strength(in percentage), make it good looking, from 0~100.
5155 //It is assigned to the BSS List in GetValueFromBeaconOrProbeRsp().
5158 pstats->SignalStrength = precord_stats->SignalStrength = (u8)(rtl819x_signal_scale_mapping((long)pwdb_all));//PWDB_ALL;
5163 //pRfd->Status.SignalStrength = pRecordRfd->Status.SignalStrength = (u8)(SignalScaleMapping(total_rssi/=RF90_PATH_MAX));//(u8)(total_rssi/=RF90_PATH_MAX);
5164 // We can judge RX path number now.
5166 pstats->SignalStrength = precord_stats->SignalStrength = (u8)(rtl819x_signal_scale_mapping((long)(total_rssi/=rf_rx_num)));
5168 } /* QueryRxPhyStatus8190Pci */
5171 rtl8192_record_rxdesc_forlateruse(
5172 struct ieee80211_rx_stats * psrc_stats,
5173 struct ieee80211_rx_stats * ptarget_stats
5176 ptarget_stats->bIsAMPDU = psrc_stats->bIsAMPDU;
5177 ptarget_stats->bFirstMPDU = psrc_stats->bFirstMPDU;
5178 ptarget_stats->Seq_Num = psrc_stats->Seq_Num;
5182 void TranslateRxSignalStuff819xUsb(struct sk_buff *skb,
5183 struct ieee80211_rx_stats * pstats,
5184 rx_drvinfo_819x_usb *pdrvinfo)
5186 // TODO: We must only check packet for current MAC address. Not finish
5187 rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
5188 struct net_device *dev=info->dev;
5189 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
5190 bool bpacket_match_bssid, bpacket_toself;
5191 bool bPacketBeacon=FALSE, bToSelfBA=FALSE;
5192 static struct ieee80211_rx_stats previous_stats;
5193 struct ieee80211_hdr_3addr *hdr;//by amy
5196 // Get Signal Quality for only RX data queue (but not command queue)
5199 //u16 tmp_buf_len = 0;
5202 /* Get MAC frame start address. */
5203 tmp_buf = (u8*)skb->data;// + get_rxpacket_shiftbytes_819xusb(pstats);
5205 hdr = (struct ieee80211_hdr_3addr *)tmp_buf;
5206 fc = le16_to_cpu(hdr->frame_ctl);
5207 type = WLAN_FC_GET_TYPE(fc);
5208 praddr = hdr->addr1;
5210 /* Check if the received packet is acceptabe. */
5211 bpacket_match_bssid = ((IEEE80211_FTYPE_CTL != type) &&
5212 (eqMacAddr(priv->ieee80211->current_network.bssid, (fc & IEEE80211_FCTL_TODS)? hdr->addr1 : (fc & IEEE80211_FCTL_FROMDS )? hdr->addr2 : hdr->addr3))
5213 && (!pstats->bHwError) && (!pstats->bCRC)&& (!pstats->bICV));
5214 bpacket_toself = bpacket_match_bssid & (eqMacAddr(praddr, priv->ieee80211->dev->dev_addr));
5216 if(WLAN_FC_GET_FRAMETYPE(fc)== IEEE80211_STYPE_BEACON)
5218 bPacketBeacon = true;
5219 //DbgPrint("Beacon 2, MatchBSSID = %d, ToSelf = %d \n", bPacketMatchBSSID, bPacketToSelf);
5221 if(WLAN_FC_GET_FRAMETYPE(fc) == IEEE80211_STYPE_BLOCKACK)
5223 if((eqMacAddr(praddr,dev->dev_addr)))
5225 //DbgPrint("BlockAck, MatchBSSID = %d, ToSelf = %d \n", bPacketMatchBSSID, bPacketToSelf);
5230 if(bpacket_match_bssid)
5232 priv->stats.numpacket_matchbssid++;
5235 priv->stats.numpacket_toself++;
5238 // Process PHY information for previous packet (RSSI/PWDB/EVM)
5240 // Because phy information is contained in the last packet of AMPDU only, so driver
5241 // should process phy information of previous packet
5242 rtl8192_process_phyinfo(priv, tmp_buf, &previous_stats, pstats);
5243 rtl8192_query_rxphystatus(priv, pstats, pdrvinfo, &previous_stats, bpacket_match_bssid,bpacket_toself,bPacketBeacon,bToSelfBA);
5244 rtl8192_record_rxdesc_forlateruse(pstats, &previous_stats);
5249 * Function: UpdateReceivedRateHistogramStatistics
5250 * Overview: Recored down the received data rate
5253 * struct net_device *dev
5254 * struct ieee80211_rx_stats *stats
5258 * (priv->stats.ReceivedRateHistogram[] is updated)
5263 UpdateReceivedRateHistogramStatistics8190(
5264 struct net_device *dev,
5265 struct ieee80211_rx_stats *stats
5268 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
5269 u32 rcvType=1; //0: Total, 1:OK, 2:CRC, 3:ICV
5271 u32 preamble_guardinterval; //1: short preamble/GI, 0: long preamble/GI
5276 else if(stats->bICV)
5279 if(stats->bShortPreamble)
5280 preamble_guardinterval = 1;// short
5282 preamble_guardinterval = 0;// long
5289 case MGN_1M: rateIndex = 0; break;
5290 case MGN_2M: rateIndex = 1; break;
5291 case MGN_5_5M: rateIndex = 2; break;
5292 case MGN_11M: rateIndex = 3; break;
5296 case MGN_6M: rateIndex = 4; break;
5297 case MGN_9M: rateIndex = 5; break;
5298 case MGN_12M: rateIndex = 6; break;
5299 case MGN_18M: rateIndex = 7; break;
5300 case MGN_24M: rateIndex = 8; break;
5301 case MGN_36M: rateIndex = 9; break;
5302 case MGN_48M: rateIndex = 10; break;
5303 case MGN_54M: rateIndex = 11; break;
5305 // 11n High throughput rate
5307 case MGN_MCS0: rateIndex = 12; break;
5308 case MGN_MCS1: rateIndex = 13; break;
5309 case MGN_MCS2: rateIndex = 14; break;
5310 case MGN_MCS3: rateIndex = 15; break;
5311 case MGN_MCS4: rateIndex = 16; break;
5312 case MGN_MCS5: rateIndex = 17; break;
5313 case MGN_MCS6: rateIndex = 18; break;
5314 case MGN_MCS7: rateIndex = 19; break;
5315 case MGN_MCS8: rateIndex = 20; break;
5316 case MGN_MCS9: rateIndex = 21; break;
5317 case MGN_MCS10: rateIndex = 22; break;
5318 case MGN_MCS11: rateIndex = 23; break;
5319 case MGN_MCS12: rateIndex = 24; break;
5320 case MGN_MCS13: rateIndex = 25; break;
5321 case MGN_MCS14: rateIndex = 26; break;
5322 case MGN_MCS15: rateIndex = 27; break;
5323 default: rateIndex = 28; break;
5325 priv->stats.received_preamble_GI[preamble_guardinterval][rateIndex]++;
5326 priv->stats.received_rate_histogram[0][rateIndex]++; //total
5327 priv->stats.received_rate_histogram[rcvType][rateIndex]++;
5331 void query_rxdesc_status(struct sk_buff *skb, struct ieee80211_rx_stats *stats, bool bIsRxAggrSubframe)
5333 rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
5334 struct net_device *dev=info->dev;
5335 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
5336 //rx_desc_819x_usb *desc = (rx_desc_819x_usb *)skb->data;
5337 rx_drvinfo_819x_usb *driver_info = NULL;
5340 //Get Rx Descriptor Information
5342 #ifdef USB_RX_AGGREGATION_SUPPORT
5343 if (bIsRxAggrSubframe)
5345 rx_desc_819x_usb_aggr_subframe *desc = (rx_desc_819x_usb_aggr_subframe *)skb->data;
5346 stats->Length = desc->Length ;
5347 stats->RxDrvInfoSize = desc->RxDrvInfoSize;
5348 stats->RxBufShift = 0; //RxBufShift = 2 in RxDesc, but usb didn't shift bytes in fact.
5349 stats->bICV = desc->ICV;
5350 stats->bCRC = desc->CRC32;
5351 stats->bHwError = stats->bCRC|stats->bICV;
5352 stats->Decrypted = !desc->SWDec;//RTL8190 set this bit to indicate that Hw does not decrypt packet
5356 rx_desc_819x_usb *desc = (rx_desc_819x_usb *)skb->data;
5358 stats->Length = desc->Length;
5359 stats->RxDrvInfoSize = desc->RxDrvInfoSize;
5360 stats->RxBufShift = 0;//desc->Shift&0x03;
5361 stats->bICV = desc->ICV;
5362 stats->bCRC = desc->CRC32;
5363 stats->bHwError = stats->bCRC|stats->bICV;
5364 //RTL8190 set this bit to indicate that Hw does not decrypt packet
5365 stats->Decrypted = !desc->SWDec;
5368 if((priv->ieee80211->pHTInfo->bCurrentHTSupport == true) && (priv->ieee80211->pairwise_key_type == KEY_TYPE_CCMP))
5370 stats->bHwError = false;
5374 stats->bHwError = stats->bCRC|stats->bICV;
5377 if(stats->Length < 24 || stats->Length > MAX_8192U_RX_SIZE)
5378 stats->bHwError |= 1;
5382 // TODO: Need to verify it on FGPA platform
5383 //Driver info are written to the RxBuffer following rx desc
5384 if (stats->RxDrvInfoSize != 0) {
5385 driver_info = (rx_drvinfo_819x_usb *)(skb->data + sizeof(rx_desc_819x_usb) + \
5389 if(!stats->bHwError){
5391 ret_rate = HwRateToMRate90(driver_info->RxHT, driver_info->RxRate);
5392 if(ret_rate == 0xff)
5394 // Abnormal Case: Receive CRC OK packet with Rx descriptor indicating non supported rate.
5395 // Special Error Handling here, 2008.05.16, by Emily
5397 stats->bHwError = 1;
5398 stats->rate = MGN_1M; //Set 1M rate by default
5401 stats->rate = ret_rate;
5407 stats->bShortPreamble = driver_info->SPLCP;
5410 UpdateReceivedRateHistogramStatistics8190(dev, stats);
5412 stats->bIsAMPDU = (driver_info->PartAggr==1);
5413 stats->bFirstMPDU = (driver_info->PartAggr==1) && (driver_info->FirstAGGR==1);
5414 stats->TimeStampLow = driver_info->TSFL;
5415 // xiong mask it, 070514
5416 //pRfd->Status.TimeStampHigh = PlatformEFIORead4Byte(Adapter, TSFR+4);
5417 // stats->TimeStampHigh = read_nic_dword(dev, TSFR+4);
5419 UpdateRxPktTimeStamp8190(dev, stats);
5424 if(driver_info->FirstAGGR==1 || driver_info->PartAggr == 1)
5425 RT_TRACE(COMP_RXDESC, "driver_info->FirstAGGR = %d, driver_info->PartAggr = %d\n",
5426 driver_info->FirstAGGR, driver_info->PartAggr);
5430 skb_pull(skb,sizeof(rx_desc_819x_usb));
5432 // Get Total offset of MPDU Frame Body
5434 if((stats->RxBufShift + stats->RxDrvInfoSize) > 0) {
5436 skb_pull(skb,stats->RxBufShift + stats->RxDrvInfoSize);
5439 #ifdef USB_RX_AGGREGATION_SUPPORT
5440 /* for the rx aggregated sub frame, the redundant space truelly contained in the packet */
5441 if(bIsRxAggrSubframe) {
5445 /* for debug 2008.5.29 */
5447 //added by vivi, for MP, 20080108
5448 stats->RxIs40MHzPacket = driver_info->BW;
5449 if(stats->RxDrvInfoSize != 0)
5450 TranslateRxSignalStuff819xUsb(skb, stats, driver_info);
5454 u32 GetRxPacketShiftBytes819xUsb(struct ieee80211_rx_stats *Status, bool bIsRxAggrSubframe)
5456 #ifdef USB_RX_AGGREGATION_SUPPORT
5457 if (bIsRxAggrSubframe)
5458 return (sizeof(rx_desc_819x_usb) + Status->RxDrvInfoSize
5459 + Status->RxBufShift + 8);
5462 return (sizeof(rx_desc_819x_usb) + Status->RxDrvInfoSize
5463 + Status->RxBufShift);
5466 void rtl8192_rx_nomal(struct sk_buff* skb)
5468 rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
5469 struct net_device *dev=info->dev;
5470 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
5471 struct ieee80211_rx_stats stats = {
5475 // .mac_time = jiffies,
5476 .freq = IEEE80211_24GHZ_BAND,
5479 struct ieee80211_hdr_1addr *ieee80211_hdr = NULL;
5480 bool unicast_packet = false;
5481 #ifdef USB_RX_AGGREGATION_SUPPORT
5482 struct sk_buff *agg_skb = NULL;
5483 u32 TotalLength = 0;
5485 u32 PacketLength = 0;
5486 u32 PacketOccupiedLendth = 0;
5488 u32 PacketShiftBytes = 0;
5489 rx_desc_819x_usb_aggr_subframe *RxDescr = NULL;
5490 u8 PaddingBytes = 0;
5491 //add just for testing
5496 /* 20 is for ps-poll */
5497 if((skb->len >=(20 + sizeof(rx_desc_819x_usb))) && (skb->len < RX_URB_SIZE)) {
5498 #ifdef USB_RX_AGGREGATION_SUPPORT
5499 TempByte = *(skb->data + sizeof(rx_desc_819x_usb));
5501 /* first packet should not contain Rx aggregation header */
5502 query_rxdesc_status(skb, &stats, false);
5504 /* hardware related info */
5505 #ifdef USB_RX_AGGREGATION_SUPPORT
5506 if (TempByte & BIT0) {
5508 //TotalLength = agg_skb->len - 4; /*sCrcLng*/
5509 TotalLength = stats.Length - 4; /*sCrcLng*/
5510 //RT_TRACE(COMP_RECV, "%s:first aggregated packet!Length=%d\n",__FUNCTION__,TotalLength);
5511 /* though the head pointer has passed this position */
5512 TempDWord = *(u32 *)(agg_skb->data - 4);
5513 PacketLength = (u16)(TempDWord & 0x3FFF); /*sCrcLng*/
5514 skb = dev_alloc_skb(PacketLength);
5515 memcpy(skb_put(skb,PacketLength),agg_skb->data,PacketLength);
5516 PacketShiftBytes = GetRxPacketShiftBytes819xUsb(&stats, false);
5519 /* Process the MPDU recevied */
5520 skb_trim(skb, skb->len - 4/*sCrcLng*/);
5522 rx_pkt_len = skb->len;
5523 ieee80211_hdr = (struct ieee80211_hdr_1addr *)skb->data;
5524 unicast_packet = false;
5525 if(is_broadcast_ether_addr(ieee80211_hdr->addr1)) {
5527 }else if(is_multicast_ether_addr(ieee80211_hdr->addr1)){
5530 /* unicast packet */
5531 unicast_packet = true;
5534 if(!ieee80211_rx(priv->ieee80211,skb, &stats)) {
5535 dev_kfree_skb_any(skb);
5537 priv->stats.rxoktotal++;
5538 if(unicast_packet) {
5539 priv->stats.rxbytesunicast += rx_pkt_len;
5542 #ifdef USB_RX_AGGREGATION_SUPPORT
5544 // (PipeIndex == 0) && (TempByte & BIT0) => TotalLength > 0.
5545 if (TotalLength > 0) {
5546 PacketOccupiedLendth = PacketLength + (PacketShiftBytes + 8);
5547 if ((PacketOccupiedLendth & 0xFF) != 0)
5548 PacketOccupiedLendth = (PacketOccupiedLendth & 0xFFFFFF00) + 256;
5549 PacketOccupiedLendth -= 8;
5550 TempDWord = PacketOccupiedLendth - PacketShiftBytes; /*- PacketLength */
5551 if (agg_skb->len > TempDWord)
5552 skb_pull(agg_skb, TempDWord);
5556 while (agg_skb->len>=GetRxPacketShiftBytes819xUsb(&stats, true)) {
5557 u8 tmpCRC = 0, tmpICV = 0;
5558 //RT_TRACE(COMP_RECV,"%s:aggred pkt,total_len = %d\n",__FUNCTION__,agg_skb->len);
5559 RxDescr = (rx_desc_819x_usb_aggr_subframe *)(agg_skb->data);
5560 tmpCRC = RxDescr->CRC32;
5561 tmpICV = RxDescr->ICV;
5562 memcpy(agg_skb->data, &agg_skb->data[44], 2);
5563 RxDescr->CRC32 = tmpCRC;
5564 RxDescr->ICV = tmpICV;
5566 memset(&stats, 0, sizeof(struct ieee80211_rx_stats));
5570 stats.freq = IEEE80211_24GHZ_BAND;
5571 query_rxdesc_status(agg_skb, &stats, true);
5572 PacketLength = stats.Length;
5574 if(PacketLength > agg_skb->len) {
5577 /* Process the MPDU recevied */
5578 skb = dev_alloc_skb(PacketLength);
5579 memcpy(skb_put(skb,PacketLength),agg_skb->data, PacketLength);
5580 skb_trim(skb, skb->len - 4/*sCrcLng*/);
5582 rx_pkt_len = skb->len;
5583 ieee80211_hdr = (struct ieee80211_hdr_1addr *)skb->data;
5584 unicast_packet = false;
5585 if(is_broadcast_ether_addr(ieee80211_hdr->addr1)) {
5587 }else if(is_multicast_ether_addr(ieee80211_hdr->addr1)){
5590 /* unicast packet */
5591 unicast_packet = true;
5593 if(!ieee80211_rx(priv->ieee80211,skb, &stats)) {
5594 dev_kfree_skb_any(skb);
5596 priv->stats.rxoktotal++;
5597 if(unicast_packet) {
5598 priv->stats.rxbytesunicast += rx_pkt_len;
5601 /* should trim the packet which has been copied to target skb */
5602 skb_pull(agg_skb, PacketLength);
5603 PacketShiftBytes = GetRxPacketShiftBytes819xUsb(&stats, true);
5604 PacketOccupiedLendth = PacketLength + PacketShiftBytes;
5605 if ((PacketOccupiedLendth & 0xFF) != 0) {
5606 PaddingBytes = 256 - (PacketOccupiedLendth & 0xFF);
5607 if (agg_skb->len > PaddingBytes)
5608 skb_pull(agg_skb, PaddingBytes);
5613 dev_kfree_skb(agg_skb);
5617 priv->stats.rxurberr++;
5618 printk("actual_length:%d\n", skb->len);
5619 dev_kfree_skb_any(skb);
5625 rtl819xusb_process_received_packet(
5626 struct net_device *dev,
5627 struct ieee80211_rx_stats *pstats
5630 // bool bfreerfd=false, bqueued=false;
5633 struct r8192_priv *priv = ieee80211_priv(dev);
5637 //PRX_TS_RECORD pts = NULL;
5639 // Get shifted bytes of Starting address of 802.11 header. 2006.09.28, by Emily
5640 //porting by amy 080508
5641 pstats->virtual_address += get_rxpacket_shiftbytes_819xusb(pstats);
5642 frame = pstats->virtual_address;
5643 frame_len = pstats->packetlength;
5644 #ifdef TODO // by amy about HCT
5645 if(!Adapter->bInHctTest)
5646 CountRxErrStatistics(Adapter, pRfd);
5649 #ifdef ENABLE_PS //by amy for adding ps function in future
5650 RT_RF_POWER_STATE rtState;
5651 // When RF is off, we should not count the packet for hw/sw synchronize
5652 // reason, ie. there may be a duration while sw switch is changed and hw
5653 // switch is being changed. 2006.12.04, by shien chang.
5654 Adapter->HalFunc.GetHwRegHandler(Adapter, HW_VAR_RF_STATE, (u8* )(&rtState));
5655 if (rtState == eRfOff)
5660 priv->stats.rxframgment++;
5664 RmMonitorSignalStrength(Adapter, pRfd);
5666 /* 2007/01/16 MH Add RX command packet handle here. */
5667 /* 2007/03/01 MH We have to release RFD and return if rx pkt is cmd pkt. */
5668 if (rtl819xusb_rx_command_packet(dev, pstats))
5680 void query_rx_cmdpkt_desc_status(struct sk_buff *skb, struct ieee80211_rx_stats *stats)
5682 // rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
5683 // struct net_device *dev=info->dev;
5684 // struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
5685 rx_desc_819x_usb *desc = (rx_desc_819x_usb *)skb->data;
5686 // rx_drvinfo_819x_usb *driver_info;
5689 //Get Rx Descriptor Information
5691 stats->virtual_address = (u8*)skb->data;
5692 stats->Length = desc->Length;
5693 stats->RxDrvInfoSize = 0;
5694 stats->RxBufShift = 0;
5695 stats->packetlength = stats->Length-scrclng;
5696 stats->fraglength = stats->packetlength;
5697 stats->fragoffset = 0;
5698 stats->ntotalfrag = 1;
5702 void rtl8192_rx_cmd(struct sk_buff *skb)
5704 struct rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
5705 struct net_device *dev = info->dev;
5707 // struct urb *rx_urb = info->urb;
5709 struct ieee80211_rx_stats stats = {
5713 // .mac_time = jiffies,
5714 .freq = IEEE80211_24GHZ_BAND,
5717 if((skb->len >=(20 + sizeof(rx_desc_819x_usb))) && (skb->len < RX_URB_SIZE))
5720 query_rx_cmdpkt_desc_status(skb,&stats);
5721 // this is to be done by amy 080508 prfd->queue_id = 1;
5725 // Process the command packet received.
5728 rtl819xusb_process_received_packet(dev,&stats);
5730 dev_kfree_skb_any(skb);
5738 void rtl8192_irq_rx_tasklet(struct r8192_priv *priv)
5740 struct sk_buff *skb;
5741 struct rtl8192_rx_info *info;
5743 while (NULL != (skb = skb_dequeue(&priv->skb_queue))) {
5744 info = (struct rtl8192_rx_info *)skb->cb;
5745 switch (info->out_pipe) {
5746 /* Nomal packet pipe */
5748 //RT_TRACE(COMP_RECV, "normal in-pipe index(%d)\n",info->out_pipe);
5749 priv->IrpPendingCount--;
5750 rtl8192_rx_nomal(skb);
5753 /* Command packet pipe */
5755 RT_TRACE(COMP_RECV, "command in-pipe index(%d)\n",\
5758 rtl8192_rx_cmd(skb);
5761 default: /* should never get here! */
5762 RT_TRACE(COMP_ERR, "Unknown in-pipe index(%d)\n",\
5771 static const struct net_device_ops rtl8192_netdev_ops = {
5772 .ndo_open = rtl8192_open,
5773 .ndo_stop = rtl8192_close,
5774 .ndo_get_stats = rtl8192_stats,
5775 .ndo_tx_timeout = tx_timeout,
5776 .ndo_do_ioctl = rtl8192_ioctl,
5777 .ndo_set_multicast_list = r8192_set_multicast,
5778 .ndo_set_mac_address = r8192_set_mac_adr,
5779 .ndo_validate_addr = eth_validate_addr,
5780 .ndo_change_mtu = eth_change_mtu,
5781 .ndo_start_xmit = ieee80211_xmit,
5785 /****************************************************************************
5786 ---------------------------- USB_STUFF---------------------------
5787 *****************************************************************************/
5789 static int __devinit rtl8192_usb_probe(struct usb_interface *intf,
5790 const struct usb_device_id *id)
5792 // unsigned long ioaddr = 0;
5793 struct net_device *dev = NULL;
5794 struct r8192_priv *priv= NULL;
5795 struct usb_device *udev = interface_to_usbdev(intf);
5796 RT_TRACE(COMP_INIT, "Oops: i'm coming\n");
5798 dev = alloc_ieee80211(sizeof(struct r8192_priv));
5801 usb_set_intfdata(intf, dev);
5802 SET_NETDEV_DEV(dev, &intf->dev);
5803 priv = ieee80211_priv(dev);
5804 priv->ieee80211 = netdev_priv(dev);
5807 dev->netdev_ops = &rtl8192_netdev_ops;
5809 //DMESG("Oops: i'm coming\n");
5810 #if WIRELESS_EXT >= 12
5811 #if WIRELESS_EXT < 17
5812 dev->get_wireless_stats = r8192_get_wireless_stats;
5814 dev->wireless_handlers = (struct iw_handler_def *) &r8192_wx_handlers_def;
5816 dev->type=ARPHRD_ETHER;
5818 dev->watchdog_timeo = HZ*3; //modified by john, 0805
5820 if (dev_alloc_name(dev, ifname) < 0){
5821 RT_TRACE(COMP_INIT, "Oops: devname already taken! Trying wlan%%d...\n");
5823 dev_alloc_name(dev, ifname);
5826 RT_TRACE(COMP_INIT, "Driver probe completed1\n");
5827 if(rtl8192_init(dev)!=0){
5828 RT_TRACE(COMP_ERR, "Initialization failed");
5831 netif_carrier_off(dev);
5832 netif_stop_queue(dev);
5834 register_netdev(dev);
5835 RT_TRACE(COMP_INIT, "dev name=======> %s\n",dev->name);
5836 rtl8192_proc_init_one(dev);
5839 RT_TRACE(COMP_INIT, "Driver probe completed\n");
5844 free_ieee80211(dev);
5846 RT_TRACE(COMP_ERR, "wlan driver load failed\n");
5851 //detach all the work and timer structure declared or inititialize in r8192U_init function.
5852 void rtl8192_cancel_deferred_work(struct r8192_priv* priv)
5855 cancel_work_sync(&priv->reset_wq);
5856 cancel_delayed_work(&priv->watch_dog_wq);
5857 cancel_delayed_work(&priv->update_beacon_wq);
5858 cancel_work_sync(&priv->qos_activate);
5859 //cancel_work_sync(&priv->SetBWModeWorkItem);
5860 //cancel_work_sync(&priv->SwChnlWorkItem);
5865 static void __devexit rtl8192_usb_disconnect(struct usb_interface *intf)
5867 struct net_device *dev = usb_get_intfdata(intf);
5869 struct r8192_priv *priv = ieee80211_priv(dev);
5872 unregister_netdev(dev);
5874 RT_TRACE(COMP_DOWN, "=============>wlan driver to be removed\n");
5875 rtl8192_proc_remove_one(dev);
5878 if (priv->pFirmware)
5880 kfree(priv->pFirmware);
5881 priv->pFirmware = NULL;
5883 // priv->rf_close(dev);
5884 // rtl8192_SetRFPowerState(dev, eRfOff);
5885 rtl8192_usb_deleteendpoints(dev);
5886 destroy_workqueue(priv->priv_wq);
5887 //rtl8192_irq_disable(dev);
5888 //rtl8192_reset(dev);
5892 free_ieee80211(dev);
5893 RT_TRACE(COMP_DOWN, "wlan driver removed\n");
5896 /* fun with the built-in ieee80211 stack... */
5897 extern int ieee80211_debug_init(void);
5898 extern void ieee80211_debug_exit(void);
5899 extern int ieee80211_crypto_init(void);
5900 extern void ieee80211_crypto_deinit(void);
5901 extern int ieee80211_crypto_tkip_init(void);
5902 extern void ieee80211_crypto_tkip_exit(void);
5903 extern int ieee80211_crypto_ccmp_init(void);
5904 extern void ieee80211_crypto_ccmp_exit(void);
5905 extern int ieee80211_crypto_wep_init(void);
5906 extern void ieee80211_crypto_wep_exit(void);
5908 static int __init rtl8192_usb_module_init(void)
5912 #ifdef CONFIG_IEEE80211_DEBUG
5913 ret = ieee80211_debug_init();
5915 printk(KERN_ERR "ieee80211_debug_init() failed %d\n", ret);
5919 ret = ieee80211_crypto_init();
5921 printk(KERN_ERR "ieee80211_crypto_init() failed %d\n", ret);
5925 ret = ieee80211_crypto_tkip_init();
5927 printk(KERN_ERR "ieee80211_crypto_tkip_init() failed %d\n",
5932 ret = ieee80211_crypto_ccmp_init();
5934 printk(KERN_ERR "ieee80211_crypto_ccmp_init() failed %d\n",
5939 ret = ieee80211_crypto_wep_init();
5941 printk(KERN_ERR "ieee80211_crypto_wep_init() failed %d\n", ret);
5945 printk(KERN_INFO "\nLinux kernel driver for RTL8192 based WLAN cards\n");
5946 printk(KERN_INFO "Copyright (c) 2007-2008, Realsil Wlan\n");
5947 RT_TRACE(COMP_INIT, "Initializing module");
5948 RT_TRACE(COMP_INIT, "Wireless extensions version %d", WIRELESS_EXT);
5949 rtl8192_proc_module_init();
5950 return usb_register(&rtl8192_usb_driver);
5954 static void __exit rtl8192_usb_module_exit(void)
5956 usb_deregister(&rtl8192_usb_driver);
5958 RT_TRACE(COMP_DOWN, "Exiting");
5959 // rtl8192_proc_module_remove();
5963 void rtl8192_try_wake_queue(struct net_device *dev, int pri)
5965 unsigned long flags;
5967 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
5969 spin_lock_irqsave(&priv->tx_lock,flags);
5970 enough_desc = check_nic_enough_desc(dev,pri);
5971 spin_unlock_irqrestore(&priv->tx_lock,flags);
5974 ieee80211_wake_queue(priv->ieee80211);
5977 void EnableHWSecurityConfig8192(struct net_device *dev)
5979 u8 SECR_value = 0x0;
5980 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
5981 struct ieee80211_device* ieee = priv->ieee80211;
5982 SECR_value = SCR_TxEncEnable | SCR_RxDecEnable;
5983 if (((KEY_TYPE_WEP40 == ieee->pairwise_key_type) || (KEY_TYPE_WEP104 == ieee->pairwise_key_type)) && (priv->ieee80211->auth_mode != 2))
5985 SECR_value |= SCR_RxUseDK;
5986 SECR_value |= SCR_TxUseDK;
5988 else if ((ieee->iw_mode == IW_MODE_ADHOC) && (ieee->pairwise_key_type & (KEY_TYPE_CCMP | KEY_TYPE_TKIP)))
5990 SECR_value |= SCR_RxUseDK;
5991 SECR_value |= SCR_TxUseDK;
5993 //add HWSec active enable here.
5994 //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
5996 ieee->hwsec_active = 1;
5998 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
6000 ieee->hwsec_active = 0;
6001 SECR_value &= ~SCR_RxDecEnable;
6003 RT_TRACE(COMP_SEC,"%s:, hwsec:%d, pairwise_key:%d, SECR_value:%x\n", __FUNCTION__, \
6004 ieee->hwsec_active, ieee->pairwise_key_type, SECR_value);
6006 write_nic_byte(dev, SECR, SECR_value);//SECR_value | SCR_UseDK );
6011 void setKey( struct net_device *dev,
6019 u32 TargetCommand = 0;
6020 u32 TargetContent = 0;
6023 if (EntryNo >= TOTAL_CAM_ENTRY)
6024 RT_TRACE(COMP_ERR, "cam entry exceeds in setKey()\n");
6026 RT_TRACE(COMP_SEC, "====>to setKey(), dev:%p, EntryNo:%d, KeyIndex:%d, KeyType:%d, MacAddr%pM\n", dev,EntryNo, KeyIndex, KeyType, MacAddr);
6029 usConfig |= BIT15 | (KeyType<<2);
6031 usConfig |= BIT15 | (KeyType<<2) | KeyIndex;
6032 // usConfig |= BIT15 | (KeyType<<2) | (DefaultKey<<5) | KeyIndex;
6035 for(i=0 ; i<CAM_CONTENT_COUNT; i++){
6036 TargetCommand = i+CAM_CONTENT_COUNT*EntryNo;
6037 TargetCommand |= BIT31|BIT16;
6039 if(i==0){//MAC|Config
6040 TargetContent = (u32)(*(MacAddr+0)) << 16|
6041 (u32)(*(MacAddr+1)) << 24|
6044 write_nic_dword(dev, WCAMI, TargetContent);
6045 write_nic_dword(dev, RWCAM, TargetCommand);
6046 // printk("setkey cam =%8x\n", read_cam(dev, i+6*EntryNo));
6049 TargetContent = (u32)(*(MacAddr+2)) |
6050 (u32)(*(MacAddr+3)) << 8|
6051 (u32)(*(MacAddr+4)) << 16|
6052 (u32)(*(MacAddr+5)) << 24;
6053 write_nic_dword(dev, WCAMI, TargetContent);
6054 write_nic_dword(dev, RWCAM, TargetCommand);
6058 if(KeyContent !=NULL){
6059 write_nic_dword(dev, WCAMI, (u32)(*(KeyContent+i-2)) );
6060 write_nic_dword(dev, RWCAM, TargetCommand);
6067 /***************************************************************************
6068 ------------------- module init / exit stubs ----------------
6069 ****************************************************************************/
6070 module_init(rtl8192_usb_module_init);
6071 module_exit(rtl8192_usb_module_exit);