Staging: Merge staging-next into Linus's tree
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / drivers / staging / rtl8192su / r8192U_core.c
blob6970c97713d8e8611df165dbfaafaf3489bc995e
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
14 * more details.
16 * You should have received a copy of the GNU General Public License along with
17 * this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
20 * The full GNU General Public License is included in this distribution in the
21 * file called LICENSE.
23 * Contact Information:
24 * Jerry chuang <wlanfae@realtek.com>
27 #include <linux/vmalloc.h>
28 #include <linux/slab.h>
29 #include <linux/eeprom_93cx6.h>
30 #include <linux/notifier.h>
32 #undef LOOP_TEST
33 #undef DUMP_RX
34 #undef DUMP_TX
35 #undef DEBUG_TX_DESC2
36 #undef RX_DONT_PASS_UL
37 #undef DEBUG_EPROM
38 #undef DEBUG_RX_VERBOSE
39 #undef DUMMY_RX
40 #undef DEBUG_ZERO_RX
41 #undef DEBUG_RX_SKB
42 #undef DEBUG_TX_FRAG
43 #undef DEBUG_RX_FRAG
44 #undef DEBUG_TX_FILLDESC
45 #undef DEBUG_TX
46 #undef DEBUG_IRQ
47 #undef DEBUG_RX
48 #undef DEBUG_RXALLOC
49 #undef DEBUG_REGISTERS
50 #undef DEBUG_RING
51 #undef DEBUG_IRQ_TASKLET
52 #undef DEBUG_TX_ALLOC
53 #undef DEBUG_TX_DESC
55 #define CONFIG_RTL8192_IO_MAP
57 #include <asm/uaccess.h>
58 #include "r8192U.h"
59 #include "r8192U_wx.h"
61 #include "r8192S_rtl8225.h"
62 #include "r8192S_hw.h"
63 #include "r8192S_phy.h"
64 #include "r8192S_phyreg.h"
65 #include "r8192S_Efuse.h"
67 #include "r819xU_cmdpkt.h"
68 #include "r8192U_dm.h"
69 //#include "r8192xU_phyreg.h"
70 #include <linux/usb.h>
72 #include "r8192U_pm.h"
74 #include "ieee80211/dot11d.h"
78 u32 rt_global_debug_component = \
79 // COMP_TRACE |
80 // COMP_DBG |
81 // COMP_INIT |
82 // COMP_RECV |
83 // COMP_SEND |
84 // COMP_IO |
85 COMP_POWER |
86 // COMP_EPROM |
87 COMP_SWBW |
88 COMP_POWER_TRACKING |
89 COMP_TURBO |
90 COMP_QOS |
91 // COMP_RATE |
92 // COMP_RM |
93 COMP_DIG |
94 // COMP_EFUSE |
95 // COMP_CH |
96 // COMP_TXAGC |
97 COMP_HIPWR |
98 // COMP_HALDM |
99 COMP_SEC |
100 COMP_LED |
101 // COMP_RF |
102 // COMP_RXDESC |
103 COMP_FIRMWARE |
104 COMP_HT |
105 COMP_AMSDU |
106 COMP_SCAN |
107 // COMP_CMD |
108 COMP_DOWN |
109 COMP_RESET |
110 COMP_ERR; //always open err flags on
112 #define TOTAL_CAM_ENTRY 32
113 #define CAM_CONTENT_COUNT 8
115 static const struct usb_device_id rtl8192_usb_id_tbl[] = {
116 {USB_DEVICE(0x0bda, 0x8171)}, /* Realtek */
117 {USB_DEVICE(0x0bda, 0x8172)},
118 {USB_DEVICE(0x0bda, 0x8173)},
119 {USB_DEVICE(0x0bda, 0x8174)},
120 {USB_DEVICE(0x0bda, 0x8712)},
121 {USB_DEVICE(0x0bda, 0x8713)},
122 {USB_DEVICE(0x07aa, 0x0047)},
123 {USB_DEVICE(0x07d1, 0x3303)},
124 {USB_DEVICE(0x07d1, 0x3302)},
125 {USB_DEVICE(0x07d1, 0x3300)},
126 {USB_DEVICE(0x1740, 0x9603)},
127 {USB_DEVICE(0x1740, 0x9605)},
128 {USB_DEVICE(0x050d, 0x815F)},
129 {USB_DEVICE(0x06f8, 0xe031)},
130 {USB_DEVICE(0x7392, 0x7611)},
131 {USB_DEVICE(0x7392, 0x7612)},
132 {USB_DEVICE(0x7392, 0x7622)},
133 {USB_DEVICE(0x0DF6, 0x0045)},
134 {USB_DEVICE(0x0E66, 0x0015)},
135 {USB_DEVICE(0x0E66, 0x0016)},
136 {USB_DEVICE(0x0b05, 0x1786)},
137 /* these are not in the official list */
138 {USB_DEVICE(0x0df6, 0x004b)}, /* WL-349 */
142 MODULE_LICENSE("GPL");
143 MODULE_VERSION("V 1.1");
144 MODULE_DEVICE_TABLE(usb, rtl8192_usb_id_tbl);
145 MODULE_DESCRIPTION("Linux driver for Realtek RTL8192 USB WiFi cards");
147 static char* ifname = "wlan%d";
148 static int hwwep = 1; //default use hw. set 0 to use software security
149 static int channels = 0x3fff;
153 module_param(ifname, charp, S_IRUGO|S_IWUSR );
154 //module_param(hwseqnum,int, S_IRUGO|S_IWUSR);
155 module_param(hwwep,int, S_IRUGO|S_IWUSR);
156 module_param(channels,int, S_IRUGO|S_IWUSR);
158 MODULE_PARM_DESC(ifname," Net interface name, wlan%d=default");
159 //MODULE_PARM_DESC(hwseqnum," Try to use hardware 802.11 header sequence numbers. Zero=default");
160 MODULE_PARM_DESC(hwwep," Try to use hardware security support. ");
161 MODULE_PARM_DESC(channels," Channel bitmask for specific locales. NYI");
163 static int __devinit rtl8192_usb_probe(struct usb_interface *intf,
164 const struct usb_device_id *id);
165 static void __devexit rtl8192_usb_disconnect(struct usb_interface *intf);
166 static const struct net_device_ops rtl8192_netdev_ops;
167 static struct notifier_block proc_netdev_notifier;
169 static struct usb_driver rtl8192_usb_driver = {
170 .name = RTL819xU_MODULE_NAME, /* Driver name */
171 .id_table = rtl8192_usb_id_tbl, /* PCI_ID table */
172 .probe = rtl8192_usb_probe, /* probe fn */
173 .disconnect = rtl8192_usb_disconnect, /* remove fn */
174 .suspend = rtl8192U_suspend, /* PM suspend fn */
175 .resume = rtl8192U_resume, /* PM resume fn */
176 .reset_resume = rtl8192U_resume, /* PM reset resume fn */
180 static void rtl8192SU_read_eeprom_info(struct net_device *dev);
181 short rtl8192SU_tx(struct net_device *dev, struct sk_buff* skb);
182 void rtl8192SU_rx_nomal(struct sk_buff* skb);
183 void rtl8192SU_rx_cmd(struct sk_buff *skb);
184 bool rtl8192SU_adapter_start(struct net_device *dev);
185 short rtl8192SU_tx_cmd(struct net_device *dev, struct sk_buff *skb);
186 void rtl8192SU_link_change(struct net_device *dev);
187 void InitialGain8192S(struct net_device *dev,u8 Operation);
188 void rtl8192SU_query_rxdesc_status(struct sk_buff *skb, struct ieee80211_rx_stats *stats, bool bIsRxAggrSubframe);
190 struct rtl819x_ops rtl8192su_ops = {
191 .nic_type = NIC_8192SU,
192 .rtl819x_read_eeprom_info = rtl8192SU_read_eeprom_info,
193 .rtl819x_tx = rtl8192SU_tx,
194 .rtl819x_tx_cmd = rtl8192SU_tx_cmd,
195 .rtl819x_rx_nomal = rtl8192SU_rx_nomal,
196 .rtl819x_rx_cmd = rtl8192SU_rx_cmd,
197 .rtl819x_adapter_start = rtl8192SU_adapter_start,
198 .rtl819x_link_change = rtl8192SU_link_change,
199 .rtl819x_initial_gain = InitialGain8192S,
200 .rtl819x_query_rxdesc_status = rtl8192SU_query_rxdesc_status,
204 typedef struct _CHANNEL_LIST
206 u8 Channel[32];
207 u8 Len;
208 }CHANNEL_LIST, *PCHANNEL_LIST;
210 static CHANNEL_LIST ChannelPlan[] = {
211 {{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
212 {{1,2,3,4,5,6,7,8,9,10,11},11}, //IC
213 {{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48,52,56,60,64},21}, //ETSI
214 {{1,2,3,4,5,6,7,8,9,10,11,12,13},13}, //Spain. Change to ETSI.
215 {{1,2,3,4,5,6,7,8,9,10,11,12,13},13}, //France. Change to ETSI.
216 {{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
217 {{1,2,3,4,5,6,7,8,9,10,11,12,13,14,36,40,44,48,52,56,60,64},22},//MKK1
218 {{1,2,3,4,5,6,7,8,9,10,11,12,13},13}, //Israel.
219 {{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
220 {{1,2,3,4,5,6,7,8,9,10,11,12,13,14,36,40,44,48,52,56,60,64}, 22}, //MIC
221 {{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
224 static void rtl819x_eeprom_register_read(struct eeprom_93cx6 *eeprom)
226 struct net_device *dev = eeprom->data;
227 u8 reg = read_nic_byte(dev, EPROM_CMD);
229 eeprom->reg_data_in = reg & RTL819X_EEPROM_CMD_WRITE;
230 eeprom->reg_data_out = reg & RTL819X_EEPROM_CMD_READ;
231 eeprom->reg_data_clock = reg & RTL819X_EEPROM_CMD_CK;
232 eeprom->reg_chip_select = reg & RTL819X_EEPROM_CMD_CS;
235 static void rtl819x_eeprom_register_write(struct eeprom_93cx6 *eeprom)
237 struct net_device *dev = eeprom->data;
238 u8 reg = 2 << 6;
240 if (eeprom->reg_data_in)
241 reg |= RTL819X_EEPROM_CMD_WRITE;
242 if (eeprom->reg_data_out)
243 reg |= RTL819X_EEPROM_CMD_READ;
244 if (eeprom->reg_data_clock)
245 reg |= RTL819X_EEPROM_CMD_CK;
246 if (eeprom->reg_chip_select)
247 reg |= RTL819X_EEPROM_CMD_CS;
249 write_nic_byte(dev, EPROM_CMD, reg);
250 read_nic_byte(dev, EPROM_CMD);
251 udelay(10);
254 static void rtl819x_set_channel_map(u8 channel_plan, struct r8192_priv* priv)
256 int i, max_chan=-1, min_chan=-1;
257 struct ieee80211_device* ieee = priv->ieee80211;
259 ieee->bGlobalDomain = false;
260 switch (priv->rf_chip) {
261 case RF_8225:
262 case RF_8256:
263 case RF_6052:
264 min_chan = 1;
265 max_chan = 14;
266 break;
267 default:
268 pr_err("%s(): unknown rf chip, can't set channel map\n",
269 __func__);
270 break;
272 if (ChannelPlan[channel_plan].Len != 0) {
273 memset(GET_DOT11D_INFO(ieee)->channel_map, 0,
274 sizeof(GET_DOT11D_INFO(ieee)->channel_map));
276 for (i = 0; i < ChannelPlan[channel_plan].Len; i++) {
277 if (ChannelPlan[channel_plan].Channel[i] < min_chan || ChannelPlan[channel_plan].Channel[i] > max_chan)
278 break;
279 GET_DOT11D_INFO(ieee)->channel_map[ChannelPlan[channel_plan].Channel[i]] = 1;
282 switch (channel_plan) {
283 case COUNTRY_CODE_GLOBAL_DOMAIN:
284 ieee->bGlobalDomain = true;
285 for (i = 12; i <= 14; i++)
286 GET_DOT11D_INFO(ieee)->channel_map[i] = 2;
287 ieee->IbssStartChnl = 10;
288 ieee->ibss_maxjoin_chal = 11;
289 break;
290 case COUNTRY_CODE_WORLD_WIDE_13:
291 printk(KERN_INFO "world wide 13\n");
292 for (i = 12; i <= 13; i++)
293 GET_DOT11D_INFO(ieee)->channel_map[i] = 2;
294 ieee->IbssStartChnl = 10;
295 ieee->ibss_maxjoin_chal = 11;
296 break;
297 default:
298 ieee->IbssStartChnl = 1;
299 ieee->ibss_maxjoin_chal = 14;
300 break;
302 return;
305 #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 )
307 #define rx_hal_is_cck_rate(_pDesc)\
308 ((_pDesc->RxMCS == DESC92S_RATE1M ||\
309 _pDesc->RxMCS == DESC92S_RATE2M ||\
310 _pDesc->RxMCS == DESC92S_RATE5_5M ||\
311 _pDesc->RxMCS == DESC92S_RATE11M) &&\
312 !_pDesc->RxHT)
314 #define tx_hal_is_cck_rate(_DataRate)\
315 ( _DataRate == MGN_1M ||\
316 _DataRate == MGN_2M ||\
317 _DataRate == MGN_5_5M ||\
318 _DataRate == MGN_11M )
323 void CamResetAllEntry(struct net_device *dev)
325 #if 1
326 u32 ulcommand = 0;
327 //2004/02/11 In static WEP, OID_ADD_KEY or OID_ADD_WEP are set before STA associate to AP.
328 // However, ResetKey is called on OID_802_11_INFRASTRUCTURE_MODE and MlmeAssociateRequest
329 // In this condition, Cam can not be reset because upper layer will not set this static key again.
330 //if(Adapter->EncAlgorithm == WEP_Encryption)
331 // return;
332 //debug
333 //DbgPrint("========================================\n");
334 //DbgPrint(" Call ResetAllEntry \n");
335 //DbgPrint("========================================\n\n");
336 ulcommand |= BIT31|BIT30;
337 write_nic_dword(dev, RWCAM, ulcommand);
338 #else
339 for(ucIndex=0;ucIndex<TOTAL_CAM_ENTRY;ucIndex++)
340 CAM_mark_invalid(dev, ucIndex);
341 for(ucIndex=0;ucIndex<TOTAL_CAM_ENTRY;ucIndex++)
342 CAM_empty_entry(dev, ucIndex);
343 #endif
348 void write_cam(struct net_device *dev, u8 addr, u32 data)
350 write_nic_dword(dev, WCAMI, data);
351 write_nic_dword(dev, RWCAM, BIT31|BIT16|(addr&0xff) );
354 u32 read_cam(struct net_device *dev, u8 addr)
356 write_nic_dword(dev, RWCAM, 0x80000000|(addr&0xff) );
357 return read_nic_dword(dev, 0xa8);
360 void write_nic_byte_E(struct net_device *dev, int indx, u8 data)
362 int status;
363 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
364 struct usb_device *udev = priv->udev;
366 status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
367 RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
368 indx|0xfe00, 0, &data, 1, HZ / 2);
370 if (status < 0)
372 printk("write_nic_byte_E TimeOut! status:%d\n", status);
376 u8 read_nic_byte_E(struct net_device *dev, int indx)
378 int status;
379 u8 data;
380 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
381 struct usb_device *udev = priv->udev;
383 status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
384 RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
385 indx|0xfe00, 0, &data, 1, HZ / 2);
387 if (status < 0)
389 printk("read_nic_byte_E TimeOut! status:%d\n", status);
392 return data;
394 //as 92U has extend page from 4 to 16, so modify functions below.
395 void write_nic_byte(struct net_device *dev, int indx, u8 data)
397 int status;
399 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
400 struct usb_device *udev = priv->udev;
402 status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
403 RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
404 indx, 0, &data, 1, HZ / 2);
406 if (status < 0)
408 printk("write_nic_byte TimeOut! status:%d\n", status);
415 void write_nic_word(struct net_device *dev, int indx, u16 data)
418 int status;
420 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
421 struct usb_device *udev = priv->udev;
423 status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
424 RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
425 indx, 0, &data, 2, HZ / 2);
427 if (status < 0)
429 printk("write_nic_word TimeOut! status:%d\n", status);
435 void write_nic_dword(struct net_device *dev, int indx, u32 data)
438 int status;
440 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
441 struct usb_device *udev = priv->udev;
443 status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
444 RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
445 indx, 0, &data, 4, HZ / 2);
448 if (status < 0)
450 printk("write_nic_dword TimeOut! status:%d\n", status);
457 u8 read_nic_byte(struct net_device *dev, int indx)
459 u8 data;
460 int status;
461 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
462 struct usb_device *udev = priv->udev;
464 status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
465 RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
466 indx, 0, &data, 1, HZ / 2);
468 if (status < 0)
470 printk("read_nic_byte TimeOut! status:%d\n", status);
473 return data;
478 u16 read_nic_word(struct net_device *dev, int indx)
480 u16 data;
481 int status;
482 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
483 struct usb_device *udev = priv->udev;
485 status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
486 RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
487 indx, 0, &data, 2, HZ / 2);
489 if (status < 0)
491 printk("read_nic_word TimeOut! status:%d\n", status);
495 return data;
498 u16 read_nic_word_E(struct net_device *dev, int indx)
500 u16 data;
501 int status;
502 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
503 struct usb_device *udev = priv->udev;
505 status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
506 RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
507 indx|0xfe00, 0, &data, 2, HZ / 2);
509 if (status < 0)
511 printk("read_nic_word TimeOut! status:%d\n", status);
515 return data;
518 u32 read_nic_dword(struct net_device *dev, int indx)
520 u32 data;
521 int status;
522 // int result;
524 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
525 struct usb_device *udev = priv->udev;
527 status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
528 RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
529 indx, 0, &data, 4, HZ / 2);
530 // if(0 != result) {
531 // printk(KERN_WARNING "read size of data = %d\, date = %d\n", result, data);
532 // }
534 if (status < 0)
536 printk("read_nic_dword TimeOut! status:%d\n", status);
537 if(status == -ENODEV) {
538 priv->usb_error = true;
544 return data;
548 //u8 read_phy_cck(struct net_device *dev, u8 adr);
549 //u8 read_phy_ofdm(struct net_device *dev, u8 adr);
550 /* this might still called in what was the PHY rtl8185/rtl8192 common code
551 * plans are to possibilty turn it again in one common code...
553 inline void force_pci_posting(struct net_device *dev)
558 static struct net_device_stats *rtl8192_stats(struct net_device *dev);
559 void rtl8192_commit(struct net_device *dev);
560 //void rtl8192_restart(struct net_device *dev);
561 void rtl8192_restart(struct work_struct *work);
562 //void rtl8192_rq_tx_ack(struct work_struct *work);
564 void watch_dog_timer_callback(unsigned long data);
566 /****************************************************************************
567 -----------------------------PROCFS STUFF-------------------------
568 *****************************************************************************/
570 static struct proc_dir_entry *rtl8192_proc = NULL;
574 static int proc_get_stats_ap(char *page, char **start,
575 off_t offset, int count,
576 int *eof, void *data)
578 struct net_device *dev = data;
579 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
580 struct ieee80211_device *ieee = priv->ieee80211;
581 struct ieee80211_network *target;
583 int len = 0;
585 list_for_each_entry(target, &ieee->network_list, list) {
587 len += snprintf(page + len, count - len,
588 "%s ", target->ssid);
590 if(target->wpa_ie_len>0 || target->rsn_ie_len>0){
591 len += snprintf(page + len, count - len,
592 "WPA\n");
594 else{
595 len += snprintf(page + len, count - len,
596 "non_WPA\n");
601 *eof = 1;
602 return len;
605 static int proc_get_registers(char *page, char **start,
606 off_t offset, int count,
607 int *eof, void *data)
609 struct net_device *dev = data;
610 // struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
612 int len = 0;
613 int i,n,page0,page1,page2;
615 int max=0xff;
616 page0 = 0x000;
617 page1 = 0x100;
618 page2 = 0x800;
620 /* This dump the current register page */
621 if(!IS_BB_REG_OFFSET_92S(page0)){
622 len += snprintf(page + len, count - len,
623 "\n####################page %x##################\n ", (page0>>8));
624 for(n=0;n<=max;)
626 len += snprintf(page + len, count - len,
627 "\nD: %2x > ",n);
628 for(i=0;i<16 && n<=max;i++,n++)
629 len += snprintf(page + len, count - len,
630 "%2.2x ",read_nic_byte(dev,(page0|n)));
632 }else{
633 len += snprintf(page + len, count - len,
634 "\n####################page %x##################\n ", (page0>>8));
635 for(n=0;n<=max;)
637 len += snprintf(page + len, count - len, "\nD: %2x > ",n);
638 for(i=0;i<4 && n<=max;n+=4,i++)
639 len += snprintf(page + len, count - len,
640 "%8.8x ",rtl8192_QueryBBReg(dev,(page0|n), bMaskDWord));
643 len += snprintf(page + len, count - len,"\n");
644 *eof = 1;
645 return len;
648 static int proc_get_registers_1(char *page, char **start,
649 off_t offset, int count,
650 int *eof, void *data)
652 struct net_device *dev = data;
653 // struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
655 int len = 0;
656 int i,n,page0;
658 int max=0xff;
659 page0 = 0x100;
661 /* This dump the current register page */
662 len += snprintf(page + len, count - len,
663 "\n####################page %x##################\n ", (page0>>8));
664 for(n=0;n<=max;)
666 len += snprintf(page + len, count - len,
667 "\nD: %2x > ",n);
668 for(i=0;i<16 && n<=max;i++,n++)
669 len += snprintf(page + len, count - len,
670 "%2.2x ",read_nic_byte(dev,(page0|n)));
672 len += snprintf(page + len, count - len,"\n");
673 *eof = 1;
674 return len;
677 static int proc_get_registers_2(char *page, char **start,
678 off_t offset, int count,
679 int *eof, void *data)
681 struct net_device *dev = data;
682 // struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
684 int len = 0;
685 int i,n,page0;
687 int max=0xff;
688 page0 = 0x200;
690 /* This dump the current register page */
691 len += snprintf(page + len, count - len,
692 "\n####################page %x##################\n ", (page0>>8));
693 for(n=0;n<=max;)
695 len += snprintf(page + len, count - len,
696 "\nD: %2x > ",n);
697 for(i=0;i<16 && n<=max;i++,n++)
698 len += snprintf(page + len, count - len,
699 "%2.2x ",read_nic_byte(dev,(page0|n)));
701 len += snprintf(page + len, count - len,"\n");
702 *eof = 1;
703 return len;
706 static int proc_get_registers_8(char *page, char **start,
707 off_t offset, int count,
708 int *eof, void *data)
710 struct net_device *dev = data;
712 int len = 0;
713 int i,n,page0;
715 int max=0xff;
716 page0 = 0x800;
718 /* This dump the current register page */
719 len += snprintf(page + len, count - len,
720 "\n####################page %x##################\n ", (page0>>8));
721 for(n=0;n<=max;)
723 len += snprintf(page + len, count - len, "\nD: %2x > ",n);
724 for(i=0;i<4 && n<=max;n+=4,i++)
725 len += snprintf(page + len, count - len,
726 "%8.8x ",rtl8192_QueryBBReg(dev,(page0|n), bMaskDWord));
728 len += snprintf(page + len, count - len,"\n");
729 *eof = 1;
730 return len;
733 static int proc_get_registers_9(char *page, char **start,
734 off_t offset, int count,
735 int *eof, void *data)
737 struct net_device *dev = data;
738 // struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
740 int len = 0;
741 int i,n,page0;
743 int max=0xff;
744 page0 = 0x900;
746 /* This dump the current register page */
747 len += snprintf(page + len, count - len,
748 "\n####################page %x##################\n ", (page0>>8));
749 for(n=0;n<=max;)
751 len += snprintf(page + len, count - len, "\nD: %2x > ",n);
752 for(i=0;i<4 && n<=max;n+=4,i++)
753 len += snprintf(page + len, count - len,
754 "%8.8x ",rtl8192_QueryBBReg(dev,(page0|n), bMaskDWord));
756 len += snprintf(page + len, count - len,"\n");
757 *eof = 1;
758 return len;
760 static int proc_get_registers_a(char *page, char **start,
761 off_t offset, int count,
762 int *eof, void *data)
764 struct net_device *dev = data;
765 // struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
767 int len = 0;
768 int i,n,page0;
770 int max=0xff;
771 page0 = 0xa00;
773 /* This dump the current register page */
774 len += snprintf(page + len, count - len,
775 "\n####################page %x##################\n ", (page0>>8));
776 for(n=0;n<=max;)
778 len += snprintf(page + len, count - len, "\nD: %2x > ",n);
779 for(i=0;i<4 && n<=max;n+=4,i++)
780 len += snprintf(page + len, count - len,
781 "%8.8x ",rtl8192_QueryBBReg(dev,(page0|n), bMaskDWord));
783 len += snprintf(page + len, count - len,"\n");
784 *eof = 1;
785 return len;
787 static int proc_get_registers_b(char *page, char **start,
788 off_t offset, int count,
789 int *eof, void *data)
791 struct net_device *dev = data;
792 // struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
794 int len = 0;
795 int i,n,page0;
797 int max=0xff;
798 page0 = 0xb00;
800 /* This dump the current register page */
801 len += snprintf(page + len, count - len,
802 "\n####################page %x##################\n ", (page0>>8));
803 for(n=0;n<=max;)
805 len += snprintf(page + len, count - len, "\nD: %2x > ",n);
806 for(i=0;i<4 && n<=max;n+=4,i++)
807 len += snprintf(page + len, count - len,
808 "%8.8x ",rtl8192_QueryBBReg(dev,(page0|n), bMaskDWord));
810 len += snprintf(page + len, count - len,"\n");
811 *eof = 1;
812 return len;
814 static int proc_get_registers_c(char *page, char **start,
815 off_t offset, int count,
816 int *eof, void *data)
818 struct net_device *dev = data;
819 // struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
821 int len = 0;
822 int i,n,page0;
824 int max=0xff;
825 page0 = 0xc00;
827 /* This dump the current register page */
828 len += snprintf(page + len, count - len,
829 "\n####################page %x##################\n ", (page0>>8));
830 for(n=0;n<=max;)
832 len += snprintf(page + len, count - len, "\nD: %2x > ",n);
833 for(i=0;i<4 && n<=max;n+=4,i++)
834 len += snprintf(page + len, count - len,
835 "%8.8x ",rtl8192_QueryBBReg(dev,(page0|n), bMaskDWord));
837 len += snprintf(page + len, count - len,"\n");
838 *eof = 1;
839 return len;
841 static int proc_get_registers_d(char *page, char **start,
842 off_t offset, int count,
843 int *eof, void *data)
845 struct net_device *dev = data;
846 // struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
848 int len = 0;
849 int i,n,page0;
851 int max=0xff;
852 page0 = 0xd00;
854 /* This dump the current register page */
855 len += snprintf(page + len, count - len,
856 "\n####################page %x##################\n ", (page0>>8));
857 for(n=0;n<=max;)
859 len += snprintf(page + len, count - len, "\nD: %2x > ",n);
860 for(i=0;i<4 && n<=max;n+=4,i++)
861 len += snprintf(page + len, count - len,
862 "%8.8x ",rtl8192_QueryBBReg(dev,(page0|n), bMaskDWord));
864 len += snprintf(page + len, count - len,"\n");
865 *eof = 1;
866 return len;
868 static int proc_get_registers_e(char *page, char **start,
869 off_t offset, int count,
870 int *eof, void *data)
872 struct net_device *dev = data;
873 // struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
875 int len = 0;
876 int i,n,page0;
878 int max=0xff;
879 page0 = 0xe00;
881 /* This dump the current register page */
882 len += snprintf(page + len, count - len,
883 "\n####################page %x##################\n ", (page0>>8));
884 for(n=0;n<=max;)
886 len += snprintf(page + len, count - len, "\nD: %2x > ",n);
887 for(i=0;i<4 && n<=max;n+=4,i++)
888 len += snprintf(page + len, count - len,
889 "%8.8x ",rtl8192_QueryBBReg(dev,(page0|n), bMaskDWord));
891 len += snprintf(page + len, count - len,"\n");
892 *eof = 1;
893 return len;
896 static int proc_get_stats_tx(char *page, char **start,
897 off_t offset, int count,
898 int *eof, void *data)
900 struct net_device *dev = data;
901 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
903 int len = 0;
905 len += snprintf(page + len, count - len,
906 "TX VI priority ok int: %lu\n"
907 "TX VI priority error int: %lu\n"
908 "TX VO priority ok int: %lu\n"
909 "TX VO priority error int: %lu\n"
910 "TX BE priority ok int: %lu\n"
911 "TX BE priority error int: %lu\n"
912 "TX BK priority ok int: %lu\n"
913 "TX BK priority error int: %lu\n"
914 "TX MANAGE priority ok int: %lu\n"
915 "TX MANAGE priority error int: %lu\n"
916 "TX BEACON priority ok int: %lu\n"
917 "TX BEACON priority error int: %lu\n"
918 // "TX high priority ok int: %lu\n"
919 // "TX high priority failed error int: %lu\n"
920 "TX queue resume: %lu\n"
921 "TX queue stopped?: %d\n"
922 "TX fifo overflow: %lu\n"
923 // "TX beacon: %lu\n"
924 "TX VI queue: %d\n"
925 "TX VO queue: %d\n"
926 "TX BE queue: %d\n"
927 "TX BK queue: %d\n"
928 // "TX HW queue: %d\n"
929 "TX VI dropped: %lu\n"
930 "TX VO dropped: %lu\n"
931 "TX BE dropped: %lu\n"
932 "TX BK dropped: %lu\n"
933 "TX total data packets %lu\n",
934 // "TX beacon aborted: %lu\n",
935 priv->stats.txviokint,
936 priv->stats.txvierr,
937 priv->stats.txvookint,
938 priv->stats.txvoerr,
939 priv->stats.txbeokint,
940 priv->stats.txbeerr,
941 priv->stats.txbkokint,
942 priv->stats.txbkerr,
943 priv->stats.txmanageokint,
944 priv->stats.txmanageerr,
945 priv->stats.txbeaconokint,
946 priv->stats.txbeaconerr,
947 // priv->stats.txhpokint,
948 // priv->stats.txhperr,
949 priv->stats.txresumed,
950 netif_queue_stopped(dev),
951 priv->stats.txoverflow,
952 // priv->stats.txbeacon,
953 atomic_read(&(priv->tx_pending[VI_PRIORITY])),
954 atomic_read(&(priv->tx_pending[VO_PRIORITY])),
955 atomic_read(&(priv->tx_pending[BE_PRIORITY])),
956 atomic_read(&(priv->tx_pending[BK_PRIORITY])),
957 // read_nic_byte(dev, TXFIFOCOUNT),
958 priv->stats.txvidrop,
959 priv->stats.txvodrop,
960 priv->stats.txbedrop,
961 priv->stats.txbkdrop,
962 priv->stats.txdatapkt
963 // priv->stats.txbeaconerr
966 *eof = 1;
967 return len;
972 static int proc_get_stats_rx(char *page, char **start,
973 off_t offset, int count,
974 int *eof, void *data)
976 struct net_device *dev = data;
977 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
979 int len = 0;
981 len += snprintf(page + len, count - len,
982 "RX packets: %lu\n"
983 "RX urb status error: %lu\n"
984 "RX invalid urb error: %lu\n",
985 priv->stats.rxoktotal,
986 priv->stats.rxstaterr,
987 priv->stats.rxurberr);
989 *eof = 1;
990 return len;
993 int rtl8192_proc_module_init(void)
995 int ret;
997 RT_TRACE(COMP_INIT, "Initializing proc filesystem");
998 rtl8192_proc=create_proc_entry(RTL819xU_MODULE_NAME, S_IFDIR, init_net.proc_net);
999 if (!rtl8192_proc)
1000 return -ENOMEM;
1001 ret = register_netdevice_notifier(&proc_netdev_notifier);
1002 if (ret)
1003 remove_proc_entry(RTL819xU_MODULE_NAME, init_net.proc_net);
1004 return ret;
1008 void rtl8192_proc_module_remove(void)
1010 unregister_netdevice_notifier(&proc_netdev_notifier);
1011 remove_proc_entry(RTL819xU_MODULE_NAME, init_net.proc_net);
1015 void rtl8192_proc_remove_one(struct net_device *dev)
1017 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1020 if (priv->dir_dev) {
1021 // remove_proc_entry("stats-hw", priv->dir_dev);
1022 remove_proc_entry("stats-tx", priv->dir_dev);
1023 remove_proc_entry("stats-rx", priv->dir_dev);
1024 // remove_proc_entry("stats-ieee", priv->dir_dev);
1025 remove_proc_entry("stats-ap", priv->dir_dev);
1026 remove_proc_entry("registers", priv->dir_dev);
1027 remove_proc_entry("registers-1", priv->dir_dev);
1028 remove_proc_entry("registers-2", priv->dir_dev);
1029 remove_proc_entry("registers-8", priv->dir_dev);
1030 remove_proc_entry("registers-9", priv->dir_dev);
1031 remove_proc_entry("registers-a", priv->dir_dev);
1032 remove_proc_entry("registers-b", priv->dir_dev);
1033 remove_proc_entry("registers-c", priv->dir_dev);
1034 remove_proc_entry("registers-d", priv->dir_dev);
1035 remove_proc_entry("registers-e", priv->dir_dev);
1036 // remove_proc_entry("cck-registers",priv->dir_dev);
1037 // remove_proc_entry("ofdm-registers",priv->dir_dev);
1038 remove_proc_entry(priv->dir_dev->name, rtl8192_proc);
1039 priv->dir_dev = NULL;
1044 void rtl8192_proc_init_one(struct net_device *dev)
1046 struct proc_dir_entry *e;
1047 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1048 priv->dir_dev = create_proc_entry(dev->name,
1049 S_IFDIR | S_IRUGO | S_IXUGO,
1050 rtl8192_proc);
1051 if (!priv->dir_dev) {
1052 RT_TRACE(COMP_ERR, "Unable to initialize /proc/net/rtl8192/%s\n",
1053 dev->name);
1054 return;
1056 e = create_proc_read_entry("stats-rx", S_IFREG | S_IRUGO,
1057 priv->dir_dev, proc_get_stats_rx, dev);
1059 if (!e) {
1060 RT_TRACE(COMP_ERR,"Unable to initialize "
1061 "/proc/net/rtl8192/%s/stats-rx\n",
1062 dev->name);
1066 e = create_proc_read_entry("stats-tx", S_IFREG | S_IRUGO,
1067 priv->dir_dev, proc_get_stats_tx, dev);
1069 if (!e) {
1070 RT_TRACE(COMP_ERR, "Unable to initialize "
1071 "/proc/net/rtl8192/%s/stats-tx\n",
1072 dev->name);
1075 e = create_proc_read_entry("stats-ap", S_IFREG | S_IRUGO,
1076 priv->dir_dev, proc_get_stats_ap, dev);
1078 if (!e) {
1079 RT_TRACE(COMP_ERR, "Unable to initialize "
1080 "/proc/net/rtl8192/%s/stats-ap\n",
1081 dev->name);
1084 e = create_proc_read_entry("registers", S_IFREG | S_IRUGO,
1085 priv->dir_dev, proc_get_registers, dev);
1086 if (!e) {
1087 RT_TRACE(COMP_ERR, "Unable to initialize "
1088 "/proc/net/rtl8192/%s/registers\n",
1089 dev->name);
1091 e = create_proc_read_entry("registers-1", S_IFREG | S_IRUGO,
1092 priv->dir_dev, proc_get_registers_1, dev);
1093 if (!e) {
1094 RT_TRACE(COMP_ERR, "Unable to initialize "
1095 "/proc/net/rtl8192/%s/registers-1\n",
1096 dev->name);
1098 e = create_proc_read_entry("registers-2", S_IFREG | S_IRUGO,
1099 priv->dir_dev, proc_get_registers_2, dev);
1100 if (!e) {
1101 RT_TRACE(COMP_ERR, "Unable to initialize "
1102 "/proc/net/rtl8192/%s/registers-2\n",
1103 dev->name);
1105 e = create_proc_read_entry("registers-8", S_IFREG | S_IRUGO,
1106 priv->dir_dev, proc_get_registers_8, dev);
1107 if (!e) {
1108 RT_TRACE(COMP_ERR, "Unable to initialize "
1109 "/proc/net/rtl8192/%s/registers-8\n",
1110 dev->name);
1112 e = create_proc_read_entry("registers-9", S_IFREG | S_IRUGO,
1113 priv->dir_dev, proc_get_registers_9, dev);
1114 if (!e) {
1115 RT_TRACE(COMP_ERR, "Unable to initialize "
1116 "/proc/net/rtl8192/%s/registers-9\n",
1117 dev->name);
1119 e = create_proc_read_entry("registers-a", S_IFREG | S_IRUGO,
1120 priv->dir_dev, proc_get_registers_a, dev);
1121 if (!e) {
1122 RT_TRACE(COMP_ERR, "Unable to initialize "
1123 "/proc/net/rtl8192/%s/registers-a\n",
1124 dev->name);
1126 e = create_proc_read_entry("registers-b", S_IFREG | S_IRUGO,
1127 priv->dir_dev, proc_get_registers_b, dev);
1128 if (!e) {
1129 RT_TRACE(COMP_ERR, "Unable to initialize "
1130 "/proc/net/rtl8192/%s/registers-b\n",
1131 dev->name);
1133 e = create_proc_read_entry("registers-c", S_IFREG | S_IRUGO,
1134 priv->dir_dev, proc_get_registers_c, dev);
1135 if (!e) {
1136 RT_TRACE(COMP_ERR, "Unable to initialize "
1137 "/proc/net/rtl8192/%s/registers-c\n",
1138 dev->name);
1140 e = create_proc_read_entry("registers-d", S_IFREG | S_IRUGO,
1141 priv->dir_dev, proc_get_registers_d, dev);
1142 if (!e) {
1143 RT_TRACE(COMP_ERR, "Unable to initialize "
1144 "/proc/net/rtl8192/%s/registers-d\n",
1145 dev->name);
1147 e = create_proc_read_entry("registers-e", S_IFREG | S_IRUGO,
1148 priv->dir_dev, proc_get_registers_e, dev);
1149 if (!e) {
1150 RT_TRACE(COMP_ERR, "Unable to initialize "
1151 "/proc/net/rtl8192/%s/registers-e\n",
1152 dev->name);
1156 static int proc_netdev_event(struct notifier_block *this,
1157 unsigned long event, void *ptr)
1159 struct net_device *net_dev = ptr;
1161 if (net_dev->netdev_ops == &rtl8192_netdev_ops &&
1162 event == NETDEV_CHANGENAME) {
1163 rtl8192_proc_remove_one(net_dev);
1164 rtl8192_proc_init_one(net_dev);
1167 return NOTIFY_DONE;
1170 static struct notifier_block proc_netdev_notifier = {
1171 .notifier_call = proc_netdev_event,
1174 /****************************************************************************
1175 -----------------------------MISC STUFF-------------------------
1176 *****************************************************************************/
1178 /* this is only for debugging */
1179 void print_buffer(u32 *buffer, int len)
1181 int i;
1182 u8 *buf =(u8*)buffer;
1184 printk("ASCII BUFFER DUMP (len: %x):\n",len);
1186 for(i=0;i<len;i++)
1187 printk("%c",buf[i]);
1189 printk("\nBINARY BUFFER DUMP (len: %x):\n",len);
1191 for(i=0;i<len;i++)
1192 printk("%x",buf[i]);
1194 printk("\n");
1197 //short check_nic_enough_desc(struct net_device *dev, priority_t priority)
1198 short check_nic_enough_desc(struct net_device *dev,int queue_index)
1200 struct r8192_priv *priv = ieee80211_priv(dev);
1201 int used = atomic_read(&priv->tx_pending[queue_index]);
1203 return (used < MAX_TX_URB);
1206 void tx_timeout(struct net_device *dev)
1208 struct r8192_priv *priv = ieee80211_priv(dev);
1209 //rtl8192_commit(dev);
1211 schedule_work(&priv->reset_wq);
1212 //DMESG("TXTIMEOUT");
1215 /* this is only for debug */
1216 void rtl8192_dump_reg(struct net_device *dev)
1218 int i;
1219 int n;
1220 int max=0x1ff;
1222 RT_TRACE(COMP_PHY, "Dumping NIC register map");
1224 for(n=0;n<=max;)
1226 printk( "\nD: %2x> ", n);
1227 for(i=0;i<16 && n<=max;i++,n++)
1228 printk("%2x ",read_nic_byte(dev,n));
1230 printk("\n");
1233 /****************************************************************************
1234 ------------------------------HW STUFF---------------------------
1235 *****************************************************************************/
1237 void rtl8192_set_mode(struct net_device *dev,int mode)
1239 u8 ecmd;
1240 ecmd=read_nic_byte(dev, EPROM_CMD);
1241 ecmd=ecmd &~ EPROM_CMD_OPERATING_MODE_MASK;
1242 ecmd=ecmd | (mode<<EPROM_CMD_OPERATING_MODE_SHIFT);
1243 ecmd=ecmd &~ (1<<EPROM_CS_SHIFT);
1244 ecmd=ecmd &~ (1<<EPROM_CK_SHIFT);
1245 write_nic_byte(dev, EPROM_CMD, ecmd);
1249 void rtl8192_update_msr(struct net_device *dev)
1251 struct r8192_priv *priv = ieee80211_priv(dev);
1252 LED_CTL_MODE LedAction = LED_CTL_NO_LINK;
1253 u8 msr;
1255 msr = read_nic_byte(dev, MSR);
1256 msr &= ~ MSR_LINK_MASK;
1258 /* do not change in link_state != WLAN_LINK_ASSOCIATED.
1259 * msr must be updated if the state is ASSOCIATING.
1260 * this is intentional and make sense for ad-hoc and
1261 * master (see the create BSS/IBSS func)
1263 if (priv->ieee80211->state == IEEE80211_LINKED) {
1265 if (priv->ieee80211->iw_mode == IW_MODE_INFRA) {
1266 msr |= (MSR_LINK_MANAGED<<MSR_LINK_SHIFT);
1267 LedAction = LED_CTL_LINK;
1268 } else if (priv->ieee80211->iw_mode == IW_MODE_ADHOC)
1269 msr |= (MSR_LINK_ADHOC<<MSR_LINK_SHIFT);
1270 else if (priv->ieee80211->iw_mode == IW_MODE_MASTER)
1271 msr |= (MSR_LINK_MASTER<<MSR_LINK_SHIFT);
1273 } else
1274 msr |= (MSR_LINK_NONE<<MSR_LINK_SHIFT);
1276 write_nic_byte(dev, MSR, msr);
1278 if(priv->ieee80211->LedControlHandler != NULL)
1279 priv->ieee80211->LedControlHandler(dev, LedAction);
1282 void rtl8192_set_chan(struct net_device *dev,short ch)
1284 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1285 // u32 tx;
1286 RT_TRACE(COMP_CH, "=====>%s()====ch:%d\n", __FUNCTION__, ch);
1287 //printk("=====>%s()====ch:%d\n", __FUNCTION__, ch);
1288 priv->chan=ch;
1290 /* this hack should avoid frame TX during channel setting*/
1293 // tx = read_nic_dword(dev,TX_CONF);
1294 // tx &= ~TX_LOOPBACK_MASK;
1296 #ifndef LOOP_TEST
1297 // write_nic_dword(dev,TX_CONF, tx |( TX_LOOPBACK_MAC<<TX_LOOPBACK_SHIFT));
1299 //need to implement rf set channel here WB
1301 if (priv->rf_set_chan)
1302 priv->rf_set_chan(dev,priv->chan);
1303 mdelay(10);
1304 // write_nic_dword(dev,TX_CONF,tx | (TX_LOOPBACK_NONE<<TX_LOOPBACK_SHIFT));
1305 #endif
1308 static void rtl8192_rx_isr(struct urb *urb);
1310 u32 get_rxpacket_shiftbytes_819xusb(struct ieee80211_rx_stats *pstats)
1313 return (sizeof(rx_desc_819x_usb) + pstats->RxDrvInfoSize
1314 + pstats->RxBufShift);
1317 static int rtl8192_rx_initiate(struct net_device*dev)
1319 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1320 struct urb *entry;
1321 struct sk_buff *skb;
1322 struct rtl8192_rx_info *info;
1324 /* nomal packet rx procedure */
1325 while (skb_queue_len(&priv->rx_queue) < MAX_RX_URB) {
1326 skb = __dev_alloc_skb(RX_URB_SIZE, GFP_KERNEL);
1327 if (!skb)
1328 break;
1329 entry = usb_alloc_urb(0, GFP_KERNEL);
1330 if (!entry) {
1331 kfree_skb(skb);
1332 break;
1334 usb_fill_bulk_urb(entry, priv->udev,
1335 usb_rcvbulkpipe(priv->udev, 3), skb_tail_pointer(skb),
1336 RX_URB_SIZE, rtl8192_rx_isr, skb);
1337 info = (struct rtl8192_rx_info *) skb->cb;
1338 info->urb = entry;
1339 info->dev = dev;
1340 info->out_pipe = 3; //denote rx normal packet queue
1341 skb_queue_tail(&priv->rx_queue, skb);
1342 usb_submit_urb(entry, GFP_KERNEL);
1345 /* command packet rx procedure */
1346 while (skb_queue_len(&priv->rx_queue) < MAX_RX_URB + 3) {
1347 skb = __dev_alloc_skb(RX_URB_SIZE ,GFP_KERNEL);
1348 if (!skb)
1349 break;
1350 entry = usb_alloc_urb(0, GFP_KERNEL);
1351 if (!entry) {
1352 kfree_skb(skb);
1353 break;
1355 usb_fill_bulk_urb(entry, priv->udev,
1356 usb_rcvbulkpipe(priv->udev, 9), skb_tail_pointer(skb),
1357 RX_URB_SIZE, rtl8192_rx_isr, skb);
1358 info = (struct rtl8192_rx_info *) skb->cb;
1359 info->urb = entry;
1360 info->dev = dev;
1361 info->out_pipe = 9; //denote rx cmd packet queue
1362 skb_queue_tail(&priv->rx_queue, skb);
1363 usb_submit_urb(entry, GFP_KERNEL);
1366 return 0;
1369 void rtl8192_set_rxconf(struct net_device *dev)
1371 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1372 u32 rxconf;
1374 rxconf=read_nic_dword(dev,RCR);
1375 rxconf = rxconf &~ MAC_FILTER_MASK;
1376 rxconf = rxconf | RCR_AMF;
1377 rxconf = rxconf | RCR_ADF;
1378 rxconf = rxconf | RCR_AB;
1379 rxconf = rxconf | RCR_AM;
1380 //rxconf = rxconf | RCR_ACF;
1382 if (dev->flags & IFF_PROMISC) {DMESG ("NIC in promisc mode");}
1384 if(priv->ieee80211->iw_mode == IW_MODE_MONITOR || \
1385 dev->flags & IFF_PROMISC){
1386 rxconf = rxconf | RCR_AAP;
1387 } /*else if(priv->ieee80211->iw_mode == IW_MODE_MASTER){
1388 rxconf = rxconf | (1<<ACCEPT_ALLMAC_FRAME_SHIFT);
1389 rxconf = rxconf | (1<<RX_CHECK_BSSID_SHIFT);
1390 }*/else{
1391 rxconf = rxconf | RCR_APM;
1392 rxconf = rxconf | RCR_CBSSID;
1396 if(priv->ieee80211->iw_mode == IW_MODE_MONITOR){
1397 rxconf = rxconf | RCR_AICV;
1398 rxconf = rxconf | RCR_APWRMGT;
1401 if( priv->crcmon == 1 && priv->ieee80211->iw_mode == IW_MODE_MONITOR)
1402 rxconf = rxconf | RCR_ACRC32;
1405 rxconf = rxconf &~ RX_FIFO_THRESHOLD_MASK;
1406 rxconf = rxconf | (RX_FIFO_THRESHOLD_NONE<<RX_FIFO_THRESHOLD_SHIFT);
1407 rxconf = rxconf &~ MAX_RX_DMA_MASK;
1408 rxconf = rxconf | ((u32)7<<RCR_MXDMA_OFFSET);
1410 // rxconf = rxconf | (1<<RX_AUTORESETPHY_SHIFT);
1411 rxconf = rxconf | RCR_ONLYERLPKT;
1413 // rxconf = rxconf &~ RCR_CS_MASK;
1414 // rxconf = rxconf | (1<<RCR_CS_SHIFT);
1416 write_nic_dword(dev, RCR, rxconf);
1418 #ifdef DEBUG_RX
1419 DMESG("rxconf: %x %x",rxconf ,read_nic_dword(dev,RCR));
1420 #endif
1422 //wait to be removed
1423 void rtl8192_rx_enable(struct net_device *dev)
1425 //u8 cmd;
1427 //struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1429 rtl8192_rx_initiate(dev);
1431 // rtl8192_set_rxconf(dev);
1435 void rtl8192_tx_enable(struct net_device *dev)
1439 void rtl8192_rtx_disable(struct net_device *dev)
1441 u8 cmd;
1442 struct r8192_priv *priv = ieee80211_priv(dev);
1443 struct sk_buff *skb;
1444 struct rtl8192_rx_info *info;
1446 cmd=read_nic_byte(dev,CMDR);
1447 write_nic_byte(dev, CMDR, cmd &~ \
1448 (CR_TE|CR_RE));
1449 force_pci_posting(dev);
1450 mdelay(10);
1452 while ((skb = __skb_dequeue(&priv->rx_queue))) {
1453 info = (struct rtl8192_rx_info *) skb->cb;
1454 if (!info->urb)
1455 continue;
1457 usb_kill_urb(info->urb);
1458 kfree_skb(skb);
1461 if (skb_queue_len(&priv->skb_queue)) {
1462 printk(KERN_WARNING "skb_queue not empty\n");
1465 skb_queue_purge(&priv->skb_queue);
1466 return;
1470 int alloc_tx_beacon_desc_ring(struct net_device *dev, int count)
1472 return 0;
1475 inline u16 ieeerate2rtlrate(int rate)
1477 switch(rate){
1478 case 10:
1479 return 0;
1480 case 20:
1481 return 1;
1482 case 55:
1483 return 2;
1484 case 110:
1485 return 3;
1486 case 60:
1487 return 4;
1488 case 90:
1489 return 5;
1490 case 120:
1491 return 6;
1492 case 180:
1493 return 7;
1494 case 240:
1495 return 8;
1496 case 360:
1497 return 9;
1498 case 480:
1499 return 10;
1500 case 540:
1501 return 11;
1502 default:
1503 return 3;
1507 static u16 rtl_rate[] = {10,20,55,110,60,90,120,180,240,360,480,540};
1508 inline u16 rtl8192_rate2rate(short rate)
1510 if (rate >11) return 0;
1511 return rtl_rate[rate];
1514 static void rtl8192_rx_isr(struct urb *urb)
1516 struct sk_buff *skb = (struct sk_buff *) urb->context;
1517 struct rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
1518 struct net_device *dev = info->dev;
1519 struct r8192_priv *priv = ieee80211_priv(dev);
1520 int out_pipe = info->out_pipe;
1521 int err;
1522 if(!priv->up)
1523 return;
1524 if (unlikely(urb->status)) {
1525 info->urb = NULL;
1526 priv->stats.rxstaterr++;
1527 priv->ieee80211->stats.rx_errors++;
1528 usb_free_urb(urb);
1529 // printk("%s():rx status err\n",__FUNCTION__);
1530 return;
1533 skb_unlink(skb, &priv->rx_queue);
1534 skb_put(skb, urb->actual_length);
1536 skb_queue_tail(&priv->skb_queue, skb);
1537 tasklet_schedule(&priv->irq_rx_tasklet);
1539 skb = dev_alloc_skb(RX_URB_SIZE);
1540 if (unlikely(!skb)) {
1541 usb_free_urb(urb);
1542 printk("%s():can,t alloc skb\n",__FUNCTION__);
1543 /* TODO check rx queue length and refill *somewhere* */
1544 return;
1547 usb_fill_bulk_urb(urb, priv->udev,
1548 usb_rcvbulkpipe(priv->udev, out_pipe),
1549 skb_tail_pointer(skb),
1550 RX_URB_SIZE, rtl8192_rx_isr, skb);
1552 info = (struct rtl8192_rx_info *) skb->cb;
1553 info->urb = urb;
1554 info->dev = dev;
1555 info->out_pipe = out_pipe;
1557 urb->transfer_buffer = skb_tail_pointer(skb);
1558 urb->context = skb;
1559 skb_queue_tail(&priv->rx_queue, skb);
1560 err = usb_submit_urb(urb, GFP_ATOMIC);
1561 if(err && err != -EPERM)
1562 printk("can not submit rxurb, err is %x,URB status is %x\n",err,urb->status);
1566 rtl819xusb_rx_command_packet(
1567 struct net_device *dev,
1568 struct ieee80211_rx_stats *pstats
1571 u32 status;
1573 //RT_TRACE(COMP_RECV, DBG_TRACE, ("---> RxCommandPacketHandle819xUsb()\n"));
1575 status = cmpk_message_handle_rx(dev, pstats);
1576 if (status)
1578 DMESG("rxcommandpackethandle819xusb: It is a command packet\n");
1580 else
1582 //RT_TRACE(COMP_RECV, DBG_TRACE, ("RxCommandPacketHandle819xUsb: It is not a command packet\n"));
1585 //RT_TRACE(COMP_RECV, DBG_TRACE, ("<--- RxCommandPacketHandle819xUsb()\n"));
1586 return status;
1589 void rtl8192_data_hard_stop(struct net_device *dev)
1591 //FIXME !!
1595 void rtl8192_data_hard_resume(struct net_device *dev)
1597 // FIXME !!
1600 /* this function TX data frames when the ieee80211 stack requires this.
1601 * It checks also if we need to stop the ieee tx queue, eventually do it
1603 void rtl8192_hard_data_xmit(struct sk_buff *skb, struct net_device *dev, int rate)
1605 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1606 int ret;
1607 unsigned long flags;
1608 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1609 u8 queue_index = tcb_desc->queue_index;
1611 /* shall not be referred by command packet */
1612 assert(queue_index != TXCMD_QUEUE);
1614 spin_lock_irqsave(&priv->tx_lock,flags);
1616 memcpy((unsigned char *)(skb->cb),&dev,sizeof(dev));
1617 // tcb_desc->RATRIndex = 7;
1618 // tcb_desc->bTxDisableRateFallBack = 1;
1619 // tcb_desc->bTxUseDriverAssingedRate = 1;
1620 tcb_desc->bTxEnableFwCalcDur = 1;
1621 skb_push(skb, priv->ieee80211->tx_headroom);
1622 ret = priv->ops->rtl819x_tx(dev, skb);
1624 //priv->ieee80211->stats.tx_bytes+=(skb->len - priv->ieee80211->tx_headroom);
1625 //priv->ieee80211->stats.tx_packets++;
1627 spin_unlock_irqrestore(&priv->tx_lock,flags);
1629 // return ret;
1630 return;
1633 /* This is a rough attempt to TX a frame
1634 * This is called by the ieee 80211 stack to TX management frames.
1635 * If the ring is full packet are dropped (for data frame the queue
1636 * is stopped before this can happen).
1638 int rtl8192_hard_start_xmit(struct sk_buff *skb,struct net_device *dev)
1640 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1641 int ret;
1642 unsigned long flags;
1643 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1644 u8 queue_index = tcb_desc->queue_index;
1647 spin_lock_irqsave(&priv->tx_lock,flags);
1649 memcpy((unsigned char *)(skb->cb),&dev,sizeof(dev));
1650 if(queue_index == TXCMD_QUEUE) {
1651 skb_push(skb, USB_HWDESC_HEADER_LEN);
1652 priv->ops->rtl819x_tx_cmd(dev, skb);
1653 ret = 1;
1654 spin_unlock_irqrestore(&priv->tx_lock,flags);
1655 return ret;
1656 } else {
1657 skb_push(skb, priv->ieee80211->tx_headroom);
1658 ret = priv->ops->rtl819x_tx(dev, skb);
1661 spin_unlock_irqrestore(&priv->tx_lock,flags);
1663 return ret;
1667 void rtl8192_try_wake_queue(struct net_device *dev, int pri);
1670 static void rtl8192_tx_isr(struct urb *tx_urb)
1672 struct sk_buff *skb = (struct sk_buff*)tx_urb->context;
1673 struct net_device *dev = NULL;
1674 struct r8192_priv *priv = NULL;
1675 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1676 u8 queue_index = tcb_desc->queue_index;
1677 // bool bToSend0Byte;
1678 // u16 BufLen = skb->len;
1680 memcpy(&dev,(struct net_device*)(skb->cb),sizeof(struct net_device*));
1681 priv = ieee80211_priv(dev);
1683 if(tcb_desc->queue_index != TXCMD_QUEUE) {
1684 if(tx_urb->status == 0) {
1685 // dev->trans_start = jiffies;
1686 // As act as station mode, destion shall be unicast address.
1687 //priv->ieee80211->stats.tx_bytes+=(skb->len - priv->ieee80211->tx_headroom);
1688 //priv->ieee80211->stats.tx_packets++;
1689 priv->stats.txoktotal++;
1690 priv->ieee80211->LinkDetectInfo.NumTxOkInPeriod++;
1691 priv->stats.txbytesunicast += (skb->len - priv->ieee80211->tx_headroom);
1692 } else {
1693 priv->ieee80211->stats.tx_errors++;
1694 //priv->stats.txmanageerr++;
1695 /* TODO */
1699 /* free skb and tx_urb */
1700 if(skb != NULL) {
1701 dev_kfree_skb_any(skb);
1702 usb_free_urb(tx_urb);
1703 atomic_dec(&priv->tx_pending[queue_index]);
1708 // Handle HW Beacon:
1709 // We had transfer our beacon frame to host controler at this moment.
1712 // Caution:
1713 // Handling the wait queue of command packets.
1714 // For Tx command packets, we must not do TCB fragment because it is not handled right now.
1715 // We must cut the packets to match the size of TX_CMD_PKT before we send it.
1717 if (queue_index == MGNT_QUEUE){
1718 if (priv->ieee80211->ack_tx_to_ieee){
1719 if (rtl8192_is_tx_queue_empty(dev)){
1720 priv->ieee80211->ack_tx_to_ieee = 0;
1721 ieee80211_ps_tx_ack(priv->ieee80211, 1);
1725 /* Handle MPDU in wait queue. */
1726 if(queue_index != BEACON_QUEUE) {
1727 /* Don't send data frame during scanning.*/
1728 if((skb_queue_len(&priv->ieee80211->skb_waitQ[queue_index]) != 0)&&\
1729 (!(priv->ieee80211->queue_stop))) {
1730 if(NULL != (skb = skb_dequeue(&(priv->ieee80211->skb_waitQ[queue_index]))))
1731 priv->ieee80211->softmac_hard_start_xmit(skb, dev);
1733 return; //modified by david to avoid further processing AMSDU
1739 void rtl8192_beacon_stop(struct net_device *dev)
1741 u8 msr, msrm, msr2;
1742 struct r8192_priv *priv = ieee80211_priv(dev);
1744 msr = read_nic_byte(dev, MSR);
1745 msrm = msr & MSR_LINK_MASK;
1746 msr2 = msr & ~MSR_LINK_MASK;
1748 if(NIC_8192U == priv->card_8192) {
1749 usb_kill_urb(priv->rx_urb[MAX_RX_URB]);
1751 if ((msrm == (MSR_LINK_ADHOC<<MSR_LINK_SHIFT) ||
1752 (msrm == (MSR_LINK_MASTER<<MSR_LINK_SHIFT)))){
1753 write_nic_byte(dev, MSR, msr2 | MSR_LINK_NONE);
1754 write_nic_byte(dev, MSR, msr);
1758 void rtl8192_config_rate(struct net_device* dev, u16* rate_config)
1760 struct r8192_priv *priv = ieee80211_priv(dev);
1761 struct ieee80211_network *net;
1762 u8 i=0, basic_rate = 0;
1763 net = & priv->ieee80211->current_network;
1765 for (i=0; i<net->rates_len; i++)
1767 basic_rate = net->rates[i]&0x7f;
1768 switch(basic_rate)
1770 case MGN_1M: *rate_config |= RRSR_1M; break;
1771 case MGN_2M: *rate_config |= RRSR_2M; break;
1772 case MGN_5_5M: *rate_config |= RRSR_5_5M; break;
1773 case MGN_11M: *rate_config |= RRSR_11M; break;
1774 case MGN_6M: *rate_config |= RRSR_6M; break;
1775 case MGN_9M: *rate_config |= RRSR_9M; break;
1776 case MGN_12M: *rate_config |= RRSR_12M; break;
1777 case MGN_18M: *rate_config |= RRSR_18M; break;
1778 case MGN_24M: *rate_config |= RRSR_24M; break;
1779 case MGN_36M: *rate_config |= RRSR_36M; break;
1780 case MGN_48M: *rate_config |= RRSR_48M; break;
1781 case MGN_54M: *rate_config |= RRSR_54M; break;
1784 for (i=0; i<net->rates_ex_len; i++)
1786 basic_rate = net->rates_ex[i]&0x7f;
1787 switch(basic_rate)
1789 case MGN_1M: *rate_config |= RRSR_1M; break;
1790 case MGN_2M: *rate_config |= RRSR_2M; break;
1791 case MGN_5_5M: *rate_config |= RRSR_5_5M; break;
1792 case MGN_11M: *rate_config |= RRSR_11M; break;
1793 case MGN_6M: *rate_config |= RRSR_6M; break;
1794 case MGN_9M: *rate_config |= RRSR_9M; break;
1795 case MGN_12M: *rate_config |= RRSR_12M; break;
1796 case MGN_18M: *rate_config |= RRSR_18M; break;
1797 case MGN_24M: *rate_config |= RRSR_24M; break;
1798 case MGN_36M: *rate_config |= RRSR_36M; break;
1799 case MGN_48M: *rate_config |= RRSR_48M; break;
1800 case MGN_54M: *rate_config |= RRSR_54M; break;
1806 #define SHORT_SLOT_TIME 9
1807 #define NON_SHORT_SLOT_TIME 20
1809 void rtl8192_update_cap(struct net_device* dev, u16 cap)
1811 //u32 tmp = 0;
1812 struct r8192_priv *priv = ieee80211_priv(dev);
1813 struct ieee80211_network *net = &priv->ieee80211->current_network;
1814 priv->short_preamble = cap & WLAN_CAPABILITY_SHORT_PREAMBLE;
1816 //LZM MOD 090303 HW_VAR_ACK_PREAMBLE
1817 if(0)
1819 u8 tmp = 0;
1820 tmp = ((priv->nCur40MhzPrimeSC) << 5);
1821 if (priv->short_preamble)
1822 tmp |= 0x80;
1823 write_nic_byte(dev, RRSR+2, tmp);
1826 if (net->mode & (IEEE_G|IEEE_N_24G))
1828 u8 slot_time = 0;
1829 if ((cap & WLAN_CAPABILITY_SHORT_SLOT)&&(!priv->ieee80211->pHTInfo->bCurrentRT2RTLongSlotTime))
1830 {//short slot time
1831 slot_time = SHORT_SLOT_TIME;
1833 else //long slot time
1834 slot_time = NON_SHORT_SLOT_TIME;
1835 priv->slot_time = slot_time;
1836 write_nic_byte(dev, SLOT_TIME, slot_time);
1840 void rtl8192_net_update(struct net_device *dev)
1843 struct r8192_priv *priv = ieee80211_priv(dev);
1844 struct ieee80211_network *net;
1845 u16 BcnTimeCfg = 0, BcnCW = 6, BcnIFS = 0xf;
1846 u16 rate_config = 0;
1847 net = & priv->ieee80211->current_network;
1849 rtl8192_config_rate(dev, &rate_config);
1850 priv->basic_rate = rate_config &= 0x15f;
1852 write_nic_dword(dev,BSSIDR,((u32*)net->bssid)[0]);
1853 write_nic_word(dev,BSSIDR+4,((u16*)net->bssid)[2]);
1854 //for(i=0;i<ETH_ALEN;i++)
1855 // write_nic_byte(dev,BSSID+i,net->bssid[i]);
1857 rtl8192_update_msr(dev);
1858 // rtl8192_update_cap(dev, net->capability);
1859 if (priv->ieee80211->iw_mode == IW_MODE_ADHOC)
1861 write_nic_word(dev, ATIMWND, 2);
1862 write_nic_word(dev, BCN_DMATIME, 1023);
1863 write_nic_word(dev, BCN_INTERVAL, net->beacon_interval);
1864 // write_nic_word(dev, BcnIntTime, 100);
1865 write_nic_word(dev, BCN_DRV_EARLY_INT, 1);
1866 write_nic_byte(dev, BCN_ERR_THRESH, 100);
1867 BcnTimeCfg |= (BcnCW<<BCN_TCFG_CW_SHIFT);
1868 // TODO: BcnIFS may required to be changed on ASIC
1869 BcnTimeCfg |= BcnIFS<<BCN_TCFG_IFS;
1871 write_nic_word(dev, BCN_TCFG, BcnTimeCfg);
1878 //temporary hw beacon is not used any more.
1879 //open it when necessary
1880 #if 1
1881 void rtl819xusb_beacon_tx(struct net_device *dev,u16 tx_rate)
1884 #endif
1885 inline u8 rtl8192_IsWirelessBMode(u16 rate)
1887 if( ((rate <= 110) && (rate != 60) && (rate != 90)) || (rate == 220) )
1888 return 1;
1889 else return 0;
1892 u16 N_DBPSOfRate(u16 DataRate);
1894 u16 ComputeTxTime(
1895 u16 FrameLength,
1896 u16 DataRate,
1897 u8 bManagementFrame,
1898 u8 bShortPreamble
1901 u16 FrameTime;
1902 u16 N_DBPS;
1903 u16 Ceiling;
1905 if( rtl8192_IsWirelessBMode(DataRate) )
1907 if( bManagementFrame || !bShortPreamble || DataRate == 10 )
1908 { // long preamble
1909 FrameTime = (u16)(144+48+(FrameLength*8/(DataRate/10)));
1911 else
1912 { // Short preamble
1913 FrameTime = (u16)(72+24+(FrameLength*8/(DataRate/10)));
1915 if( ( FrameLength*8 % (DataRate/10) ) != 0 ) //Get the Ceilling
1916 FrameTime ++;
1917 } else { //802.11g DSSS-OFDM PLCP length field calculation.
1918 N_DBPS = N_DBPSOfRate(DataRate);
1919 Ceiling = (16 + 8*FrameLength + 6) / N_DBPS
1920 + (((16 + 8*FrameLength + 6) % N_DBPS) ? 1 : 0);
1921 FrameTime = (u16)(16 + 4 + 4*Ceiling + 6);
1923 return FrameTime;
1926 u16 N_DBPSOfRate(u16 DataRate)
1928 u16 N_DBPS = 24;
1930 switch(DataRate)
1932 case 60:
1933 N_DBPS = 24;
1934 break;
1936 case 90:
1937 N_DBPS = 36;
1938 break;
1940 case 120:
1941 N_DBPS = 48;
1942 break;
1944 case 180:
1945 N_DBPS = 72;
1946 break;
1948 case 240:
1949 N_DBPS = 96;
1950 break;
1952 case 360:
1953 N_DBPS = 144;
1954 break;
1956 case 480:
1957 N_DBPS = 192;
1958 break;
1960 case 540:
1961 N_DBPS = 216;
1962 break;
1964 default:
1965 break;
1968 return N_DBPS;
1971 void rtl819xU_cmd_isr(struct urb *tx_cmd_urb, struct pt_regs *regs)
1973 usb_free_urb(tx_cmd_urb);
1976 unsigned int txqueue2outpipe(struct r8192_priv* priv,unsigned int tx_queue) {
1978 if(tx_queue >= 9)
1980 RT_TRACE(COMP_ERR,"%s():Unknown queue ID!!!\n",__FUNCTION__);
1981 return 0x04;
1983 return priv->txqueue_to_outpipemap[tx_queue];
1986 short rtl8192SU_tx_cmd(struct net_device *dev, struct sk_buff *skb)
1988 struct r8192_priv *priv = ieee80211_priv(dev);
1989 int status;
1990 struct urb *tx_urb;
1991 unsigned int idx_pipe;
1992 tx_desc_cmd_819x_usb *pdesc = (tx_desc_cmd_819x_usb *)skb->data;
1993 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1994 u8 queue_index = tcb_desc->queue_index;
1995 u32 PktSize = 0;
1997 //printk("\n %s::::::::::::::::::::::queue_index = %d\n",__FUNCTION__, queue_index);
1998 atomic_inc(&priv->tx_pending[queue_index]);
2000 tx_urb = usb_alloc_urb(0,GFP_ATOMIC);
2001 if(!tx_urb){
2002 dev_kfree_skb(skb);
2003 return -ENOMEM;
2006 memset(pdesc, 0, USB_HWDESC_HEADER_LEN);
2008 /* Tx descriptor ought to be set according to the skb->cb */
2009 pdesc->LINIP = tcb_desc->bLastIniPkt;
2010 PktSize = (u16)(skb->len - USB_HWDESC_HEADER_LEN);
2011 pdesc->PktSize = PktSize;
2012 //printk("PKTSize = %d %x\n",pdesc->PktSize,pdesc->PktSize);
2013 //----------------------------------------------------------------------------
2014 // Fill up USB_OUT_CONTEXT.
2015 //----------------------------------------------------------------------------
2016 // Get index to out pipe from specified QueueID.
2017 idx_pipe = txqueue2outpipe(priv,queue_index);
2018 //printk("=============>%s queue_index:%d, outpipe:%d\n", __func__,queue_index,priv->RtOutPipes[idx_pipe]);
2020 usb_fill_bulk_urb(tx_urb,
2021 priv->udev,
2022 usb_sndbulkpipe(priv->udev,priv->RtOutPipes[idx_pipe]),
2023 skb->data,
2024 skb->len,
2025 rtl8192_tx_isr,
2026 skb);
2028 status = usb_submit_urb(tx_urb, GFP_ATOMIC);
2029 if (!status){
2030 return 0;
2031 }else{
2032 printk("Error TX CMD URB, error %d",
2033 status);
2034 return -1;
2039 * Mapping Software/Hardware descriptor queue id to "Queue Select Field"
2040 * in TxFwInfo data structure
2041 * 2006.10.30 by Emily
2043 * \param QUEUEID Software Queue
2045 u8 MapHwQueueToFirmwareQueue(u8 QueueID)
2047 u8 QueueSelect = 0x0; //defualt set to
2049 switch(QueueID) {
2050 case BE_QUEUE:
2051 QueueSelect = QSLT_BE; //or QSelect = pTcb->priority;
2052 break;
2054 case BK_QUEUE:
2055 QueueSelect = QSLT_BK; //or QSelect = pTcb->priority;
2056 break;
2058 case VO_QUEUE:
2059 QueueSelect = QSLT_VO; //or QSelect = pTcb->priority;
2060 break;
2062 case VI_QUEUE:
2063 QueueSelect = QSLT_VI; //or QSelect = pTcb->priority;
2064 break;
2065 case MGNT_QUEUE:
2066 QueueSelect = QSLT_MGNT;
2067 break;
2069 case BEACON_QUEUE:
2070 QueueSelect = QSLT_BEACON;
2071 break;
2073 // TODO: 2006.10.30 mark other queue selection until we verify it is OK
2074 // TODO: Remove Assertions
2075 //#if (RTL819X_FPGA_VER & RTL819X_FPGA_GUANGAN_070502)
2076 case TXCMD_QUEUE:
2077 QueueSelect = QSLT_CMD;
2078 break;
2079 //#endif
2080 case HIGH_QUEUE:
2081 QueueSelect = QSLT_HIGH;
2082 break;
2084 default:
2085 RT_TRACE(COMP_ERR, "TransmitTCB(): Impossible Queue Selection: %d \n", QueueID);
2086 break;
2088 return QueueSelect;
2091 u8 MRateToHwRate8190Pci(u8 rate)
2093 u8 ret = DESC92S_RATE1M;
2095 switch(rate)
2097 // CCK and OFDM non-HT rates
2098 case MGN_1M: ret = DESC92S_RATE1M; break;
2099 case MGN_2M: ret = DESC92S_RATE2M; break;
2100 case MGN_5_5M: ret = DESC92S_RATE5_5M; break;
2101 case MGN_11M: ret = DESC92S_RATE11M; break;
2102 case MGN_6M: ret = DESC92S_RATE6M; break;
2103 case MGN_9M: ret = DESC92S_RATE9M; break;
2104 case MGN_12M: ret = DESC92S_RATE12M; break;
2105 case MGN_18M: ret = DESC92S_RATE18M; break;
2106 case MGN_24M: ret = DESC92S_RATE24M; break;
2107 case MGN_36M: ret = DESC92S_RATE36M; break;
2108 case MGN_48M: ret = DESC92S_RATE48M; break;
2109 case MGN_54M: ret = DESC92S_RATE54M; break;
2111 // HT rates since here
2112 case MGN_MCS0: ret = DESC92S_RATEMCS0; break;
2113 case MGN_MCS1: ret = DESC92S_RATEMCS1; break;
2114 case MGN_MCS2: ret = DESC92S_RATEMCS2; break;
2115 case MGN_MCS3: ret = DESC92S_RATEMCS3; break;
2116 case MGN_MCS4: ret = DESC92S_RATEMCS4; break;
2117 case MGN_MCS5: ret = DESC92S_RATEMCS5; break;
2118 case MGN_MCS6: ret = DESC92S_RATEMCS6; break;
2119 case MGN_MCS7: ret = DESC92S_RATEMCS7; break;
2120 case MGN_MCS8: ret = DESC92S_RATEMCS8; break;
2121 case MGN_MCS9: ret = DESC92S_RATEMCS9; break;
2122 case MGN_MCS10: ret = DESC92S_RATEMCS10; break;
2123 case MGN_MCS11: ret = DESC92S_RATEMCS11; break;
2124 case MGN_MCS12: ret = DESC92S_RATEMCS12; break;
2125 case MGN_MCS13: ret = DESC92S_RATEMCS13; break;
2126 case MGN_MCS14: ret = DESC92S_RATEMCS14; break;
2127 case MGN_MCS15: ret = DESC92S_RATEMCS15; break;
2129 // Set the highest SG rate
2130 case MGN_MCS0_SG:
2131 case MGN_MCS1_SG:
2132 case MGN_MCS2_SG:
2133 case MGN_MCS3_SG:
2134 case MGN_MCS4_SG:
2135 case MGN_MCS5_SG:
2136 case MGN_MCS6_SG:
2137 case MGN_MCS7_SG:
2138 case MGN_MCS8_SG:
2139 case MGN_MCS9_SG:
2140 case MGN_MCS10_SG:
2141 case MGN_MCS11_SG:
2142 case MGN_MCS12_SG:
2143 case MGN_MCS13_SG:
2144 case MGN_MCS14_SG:
2145 case MGN_MCS15_SG:
2147 ret = DESC92S_RATEMCS15_SG;
2148 break;
2151 default: break;
2153 return ret;
2156 u8 QueryIsShort(u8 TxHT, u8 TxRate, cb_desc *tcb_desc)
2158 u8 tmp_Short;
2160 tmp_Short = (TxHT==1)?((tcb_desc->bUseShortGI)?1:0):((tcb_desc->bUseShortPreamble)?1:0);
2162 if(TxHT==1 && TxRate != DESC90_RATEMCS15)
2163 tmp_Short = 0;
2165 return tmp_Short;
2168 static void tx_zero_isr(struct urb *tx_urb)
2170 return;
2175 * The tx procedure is just as following, skb->cb will contain all the following
2176 *information: * priority, morefrag, rate, &dev.
2177 * */
2178 // <Note> Buffer format for 8192S Usb bulk out:
2180 // --------------------------------------------------
2181 // | 8192S Usb Tx Desc | 802_11_MAC_header | data |
2182 // --------------------------------------------------
2183 // | 32 bytes | 24 bytes |0-2318 bytes|
2184 // --------------------------------------------------
2185 // |<------------ BufferLen ------------------------->|
2187 short rtl8192SU_tx(struct net_device *dev, struct sk_buff* skb)
2189 struct r8192_priv *priv = ieee80211_priv(dev);
2190 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
2191 tx_desc_819x_usb *tx_desc = (tx_desc_819x_usb *)skb->data;
2192 struct usb_device *udev = priv->udev;
2193 int pend;
2194 int status;
2195 struct urb *tx_urb = NULL, *tx_urb_zero = NULL;
2196 unsigned int idx_pipe;
2197 u16 MPDUOverhead = 0;
2198 u16 type = 0;
2200 pend = atomic_read(&priv->tx_pending[tcb_desc->queue_index]);
2201 /* we are locked here so the two atomic_read and inc are executed
2202 * without interleaves * !!! For debug purpose */
2203 if( pend > MAX_TX_URB){
2204 switch (tcb_desc->queue_index) {
2205 case VO_PRIORITY:
2206 priv->stats.txvodrop++;
2207 break;
2208 case VI_PRIORITY:
2209 priv->stats.txvidrop++;
2210 break;
2211 case BE_PRIORITY:
2212 priv->stats.txbedrop++;
2213 break;
2214 default://BK_PRIORITY
2215 priv->stats.txbkdrop++;
2216 break;
2218 printk("To discard skb packet!\n");
2219 dev_kfree_skb_any(skb);
2220 return -1;
2223 tx_urb = usb_alloc_urb(0,GFP_ATOMIC);
2224 if(!tx_urb){
2225 dev_kfree_skb_any(skb);
2226 return -ENOMEM;
2229 memset(tx_desc, 0, sizeof(tx_desc_819x_usb));
2232 tx_desc->NonQos = (IsQoSDataFrame(skb->data)==TRUE)? 0:1;
2234 /* Fill Tx descriptor */
2235 //memset(tx_fwinfo,0,sizeof(tx_fwinfo_819x_usb));
2237 // This part can just fill to the first descriptor of the frame.
2238 /* DWORD 0 */
2239 tx_desc->TxHT = (tcb_desc->data_rate&0x80)?1:0;
2242 tx_desc->TxRate = MRateToHwRate8190Pci(tcb_desc->data_rate);
2243 //tx_desc->EnableCPUDur = tcb_desc->bTxEnableFwCalcDur;
2244 tx_desc->TxShort = QueryIsShort(tx_desc->TxHT, tx_desc->TxRate, tcb_desc);
2247 // Aggregation related
2248 if(tcb_desc->bAMPDUEnable) {//AMPDU enabled
2249 tx_desc->AllowAggregation = 1;
2250 /* DWORD 1 */
2251 //tx_fwinfo->RxMF = tcb_desc->ampdu_factor;
2252 //tx_fwinfo->RxAMD = tcb_desc->ampdu_density&0x07;//ampdudensity
2253 } else {
2254 tx_desc->AllowAggregation = 0;
2255 /* DWORD 1 */
2256 //tx_fwinfo->RxMF = 0;
2257 //tx_fwinfo->RxAMD = 0;
2261 // <Roger_Notes> For AMPDU case, we must insert SSN into TX_DESC,
2262 // FW according as this SSN to do necessary packet retry.
2263 // 2008.06.06.
2266 u8 *pSeq;
2267 u16 Temp;
2268 //pSeq = (u8 *)(VirtualAddress+USB_HWDESC_HEADER_LEN + FRAME_OFFSET_SEQUENCE);
2269 pSeq = (u8 *)(skb->data+USB_HWDESC_HEADER_LEN + 22);
2270 Temp = pSeq[0];
2271 Temp <<= 12;
2272 Temp |= (*(u16 *)pSeq)>>4;
2273 tx_desc->Seq = Temp;
2276 /* Protection mode related */
2277 tx_desc->RTSEn = (tcb_desc->bRTSEnable)?1:0;
2278 tx_desc->CTS2Self = (tcb_desc->bCTSEnable)?1:0;
2279 tx_desc->RTSSTBC = (tcb_desc->bRTSSTBC)?1:0;
2280 tx_desc->RTSHT = (tcb_desc->rts_rate&0x80)?1:0;
2281 tx_desc->RTSRate = MRateToHwRate8190Pci((u8)tcb_desc->rts_rate);
2282 tx_desc->RTSSubcarrier = (tx_desc->RTSHT==0)?(tcb_desc->RTSSC):0;
2283 tx_desc->RTSBW = (tx_desc->RTSHT==1)?((tcb_desc->bRTSBW)?1:0):0;
2284 tx_desc->RTSShort = (tx_desc->RTSHT==0)?(tcb_desc->bRTSUseShortPreamble?1:0):\
2285 (tcb_desc->bRTSUseShortGI?1:0);
2286 //LZM 090219
2287 tx_desc->DisRTSFB = 0;
2288 tx_desc->RTSRateFBLmt = 0xf;
2290 // <Roger_EXP> 2008.09.22. We disable RTS rate fallback temporarily.
2291 //tx_desc->DisRTSFB = 0x01;
2293 /* Set Bandwidth and sub-channel settings. */
2294 if(priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20_40)
2296 if(tcb_desc->bPacketBW) {
2297 tx_desc->TxBandwidth = 1;
2298 tx_desc->TxSubCarrier = 0; //By SD3's Jerry suggestion, use duplicated mode
2299 } else {
2300 tx_desc->TxBandwidth = 0;
2301 tx_desc->TxSubCarrier = priv->nCur40MhzPrimeSC;
2303 } else {
2304 tx_desc->TxBandwidth = 0;
2305 tx_desc->TxSubCarrier = 0;
2309 //memset(tx_desc, 0, sizeof(tx_desc_819x_usb));
2310 /* DWORD 0 */
2311 tx_desc->LINIP = 0;
2312 //tx_desc->CmdInit = 1; //92su del
2313 tx_desc->Offset = USB_HWDESC_HEADER_LEN;
2316 tx_desc->PktSize = (skb->len - USB_HWDESC_HEADER_LEN) & 0xffff;
2319 /*DWORD 1*/
2320 //tx_desc->SecCAMID= 0;//92su del
2321 tx_desc->RaBRSRID= tcb_desc->RATRIndex;
2322 //#ifdef RTL8192S_PREPARE_FOR_NORMAL_RELEASE
2325 MPDUOverhead = 0;
2326 //tx_desc->NoEnc = 1;//92su del
2329 tx_desc->SecType = 0x0;
2331 if (tcb_desc->bHwSec)
2333 switch (priv->ieee80211->pairwise_key_type)
2335 case KEY_TYPE_WEP40:
2336 case KEY_TYPE_WEP104:
2337 tx_desc->SecType = 0x1;
2338 //tx_desc->NoEnc = 0;//92su del
2339 break;
2340 case KEY_TYPE_TKIP:
2341 tx_desc->SecType = 0x2;
2342 //tx_desc->NoEnc = 0;//92su del
2343 break;
2344 case KEY_TYPE_CCMP:
2345 tx_desc->SecType = 0x3;
2346 //tx_desc->NoEnc = 0;//92su del
2347 break;
2348 case KEY_TYPE_NA:
2349 tx_desc->SecType = 0x0;
2350 //tx_desc->NoEnc = 1;//92su del
2351 break;
2352 default:
2353 tx_desc->SecType = 0x0;
2354 //tx_desc->NoEnc = 1;//92su del
2355 break;
2359 //tx_desc->TxFWInfoSize = sizeof(tx_fwinfo_819x_usb);//92su del
2362 tx_desc->USERATE = tcb_desc->bTxUseDriverAssingedRate;
2363 tx_desc->DISFB = tcb_desc->bTxDisableRateFallBack;
2364 tx_desc->DataRateFBLmt = 0x1F;// Alwasy enable all rate fallback range
2366 tx_desc->QueueSelect = MapHwQueueToFirmwareQueue(tcb_desc->queue_index);
2369 /* Fill fields that are required to be initialized in all of the descriptors */
2370 //DWORD 0
2371 tx_desc->FirstSeg = 1;
2372 tx_desc->LastSeg = 1;
2373 tx_desc->OWN = 1;
2376 //DWORD 2
2377 //tx_desc->TxBufferSize = (u32)(skb->len - USB_HWDESC_HEADER_LEN);
2378 tx_desc->TxBufferSize = (u32)(skb->len);//92su mod FIXLZM
2381 /* Get index to out pipe from specified QueueID */
2382 idx_pipe = txqueue2outpipe(priv,tcb_desc->queue_index);
2383 //printk("=============>%s queue_index:%d, outpipe:%d\n", __func__,tcb_desc->queue_index,priv->RtOutPipes[idx_pipe]);
2385 //RT_DEBUG_DATA(COMP_SEND,tx_fwinfo,sizeof(tx_fwinfo_819x_usb));
2386 //RT_DEBUG_DATA(COMP_SEND,tx_desc,sizeof(tx_desc_819x_usb));
2388 /* To submit bulk urb */
2389 usb_fill_bulk_urb(tx_urb,
2390 udev,
2391 usb_sndbulkpipe(udev,priv->RtOutPipes[idx_pipe]),
2392 skb->data,
2393 skb->len, rtl8192_tx_isr, skb);
2395 if (type == IEEE80211_FTYPE_DATA) {
2396 if (priv->ieee80211->LedControlHandler != NULL)
2397 priv->ieee80211->LedControlHandler(dev, LED_CTL_TX);
2400 status = usb_submit_urb(tx_urb, GFP_ATOMIC);
2401 if (!status) {
2403 * we need to send 0 byte packet whenever 512N bytes/64N(HIGN SPEED/NORMAL SPEED) bytes packet has been transmitted.
2404 * Otherwise, it will be halt to wait for another packet. WB. 2008.08.27
2406 bool bSend0Byte = false;
2407 u8 zero = 0;
2408 if(udev->speed == USB_SPEED_HIGH) {
2409 if (skb->len > 0 && skb->len % 512 == 0)
2410 bSend0Byte = true;
2412 else {
2413 if (skb->len > 0 && skb->len % 64 == 0)
2414 bSend0Byte = true;
2416 if (bSend0Byte) {
2417 tx_urb_zero = usb_alloc_urb(0,GFP_ATOMIC);
2418 if(!tx_urb_zero) {
2419 RT_TRACE(COMP_ERR, "can't alloc urb for zero byte\n");
2420 return -ENOMEM;
2422 usb_fill_bulk_urb(tx_urb_zero,udev,
2423 usb_sndbulkpipe(udev,idx_pipe), &zero,
2424 0, tx_zero_isr, dev);
2425 status = usb_submit_urb(tx_urb_zero, GFP_ATOMIC);
2426 switch (status) {
2427 case 0:
2428 break;
2429 case -ECONNRESET:
2430 case -ENOENT:
2431 case -ESHUTDOWN:
2432 break;
2433 default:
2434 RT_TRACE(COMP_ERR, "Error TX URB for zero byte %d, error %d",
2435 atomic_read(&priv->tx_pending[tcb_desc->queue_index]), status);
2436 return -1;
2439 dev->trans_start = jiffies;
2440 atomic_inc(&priv->tx_pending[tcb_desc->queue_index]);
2441 return 0;
2442 } else {
2443 RT_TRACE(COMP_ERR, "Error TX URB %d, error %d", atomic_read(&priv->tx_pending[tcb_desc->queue_index]),
2444 status);
2445 return -1;
2449 void rtl8192SU_net_update(struct net_device *dev)
2452 struct r8192_priv *priv = ieee80211_priv(dev);
2453 struct ieee80211_device* ieee = priv->ieee80211;
2454 struct ieee80211_network *net = &priv->ieee80211->current_network;
2455 //u16 BcnTimeCfg = 0, BcnCW = 6, BcnIFS = 0xf;
2456 u16 rate_config = 0;
2457 u32 regTmp = 0;
2458 u8 rateIndex = 0;
2459 u8 retrylimit = 0x30;
2460 u16 cap = net->capability;
2462 priv->short_preamble = cap & WLAN_CAPABILITY_SHORT_PREAMBLE;
2464 //HW_VAR_BASIC_RATE
2465 //update Basic rate: RR, BRSR
2466 rtl8192_config_rate(dev, &rate_config); //HalSetBrateCfg
2468 priv->basic_rate = rate_config = rate_config & 0x15f;
2470 // Set RRSR rate table.
2471 write_nic_byte(dev, RRSR, rate_config&0xff);
2472 write_nic_byte(dev, RRSR+1, (rate_config>>8)&0xff);
2474 // Set RTS initial rate
2475 while(rate_config > 0x1)
2477 rate_config = (rate_config>> 1);
2478 rateIndex++;
2480 write_nic_byte(dev, INIRTSMCS_SEL, rateIndex);
2481 //HW_VAR_BASIC_RATE
2483 //set ack preample
2484 regTmp = (priv->nCur40MhzPrimeSC) << 5;
2485 if (priv->short_preamble)
2486 regTmp |= 0x80;
2487 write_nic_byte(dev, RRSR+2, regTmp);
2489 write_nic_dword(dev,BSSIDR,((u32*)net->bssid)[0]);
2490 write_nic_word(dev,BSSIDR+4,((u16*)net->bssid)[2]);
2492 write_nic_word(dev, BCN_INTERVAL, net->beacon_interval);
2493 //2008.10.24 added by tynli for beacon changed.
2494 PHY_SetBeaconHwReg( dev, net->beacon_interval);
2496 rtl8192_update_cap(dev, cap);
2498 if (ieee->iw_mode == IW_MODE_ADHOC){
2499 retrylimit = 7;
2500 //we should enable ibss interrupt here, but disable it temporarily
2501 if (0){
2502 priv->irq_mask |= (IMR_BcnInt | IMR_BcnInt | IMR_TBDOK | IMR_TBDER);
2503 //rtl8192_irq_disable(dev);
2504 //rtl8192_irq_enable(dev);
2507 else{
2508 if (0){
2509 priv->irq_mask &= ~(IMR_BcnInt | IMR_BcnInt | IMR_TBDOK | IMR_TBDER);
2510 //rtl8192_irq_disable(dev);
2511 //rtl8192_irq_enable(dev);
2515 priv->ShortRetryLimit = priv->LongRetryLimit = retrylimit;
2517 write_nic_word(dev, RETRY_LIMIT,
2518 retrylimit << RETRY_LIMIT_SHORT_SHIFT | \
2519 retrylimit << RETRY_LIMIT_LONG_SHIFT);
2522 void rtl8192SU_update_ratr_table(struct net_device* dev)
2524 struct r8192_priv* priv = ieee80211_priv(dev);
2525 struct ieee80211_device* ieee = priv->ieee80211;
2526 u8* pMcsRate = ieee->dot11HTOperationalRateSet;
2527 //struct ieee80211_network *net = &ieee->current_network;
2528 u32 ratr_value = 0;
2530 u8 rate_index = 0;
2531 int WirelessMode = ieee->mode;
2532 u8 MimoPs = ieee->pHTInfo->PeerMimoPs;
2534 u8 bNMode = 0;
2536 rtl8192_config_rate(dev, (u16*)(&ratr_value));
2537 ratr_value |= (*(u16*)(pMcsRate)) << 12;
2539 //switch (ieee->mode)
2540 switch (WirelessMode)
2542 case IEEE_A:
2543 ratr_value &= 0x00000FF0;
2544 break;
2545 case IEEE_B:
2546 ratr_value &= 0x0000000D;
2547 break;
2548 case IEEE_G:
2549 ratr_value &= 0x00000FF5;
2550 break;
2551 case IEEE_N_24G:
2552 case IEEE_N_5G:
2554 bNMode = 1;
2556 if (MimoPs == 0) //MIMO_PS_STATIC
2558 ratr_value &= 0x0007F005;
2560 else
2561 { // MCS rate only => for 11N mode.
2562 u32 ratr_mask;
2564 // 1T2R or 1T1R, Spatial Stream 2 should be disabled
2565 if ( priv->rf_type == RF_1T2R ||
2566 priv->rf_type == RF_1T1R ||
2567 (ieee->pHTInfo->IOTAction & HT_IOT_ACT_DISABLE_TX_2SS) )
2568 ratr_mask = 0x000ff005;
2569 else
2570 ratr_mask = 0x0f0ff005;
2572 if((ieee->pHTInfo->bCurTxBW40MHz) &&
2573 !(ieee->pHTInfo->IOTAction & HT_IOT_ACT_DISABLE_TX_40_MHZ))
2574 ratr_mask |= 0x00000010; // Set 6MBps
2576 // Select rates for rate adaptive mechanism.
2577 ratr_value &= ratr_mask;
2580 break;
2581 default:
2582 if(0)
2584 if(priv->rf_type == RF_1T2R) // 1T2R, Spatial Stream 2 should be disabled
2586 ratr_value &= 0x000ff0f5;
2588 else
2590 ratr_value &= 0x0f0ff0f5;
2593 //printk("====>%s(), mode is not correct:%x\n", __FUNCTION__, ieee->mode);
2594 break;
2597 ratr_value &= 0x0FFFFFFF;
2599 // Get MAX MCS available.
2600 if ( (bNMode && ((ieee->pHTInfo->IOTAction & HT_IOT_ACT_DISABLE_SHORT_GI)==0)) &&
2601 ((ieee->pHTInfo->bCurBW40MHz && ieee->pHTInfo->bCurShortGI40MHz) ||
2602 (!ieee->pHTInfo->bCurBW40MHz && ieee->pHTInfo->bCurShortGI20MHz)))
2604 u8 shortGI_rate = 0;
2605 u32 tmp_ratr_value = 0;
2606 ratr_value |= 0x10000000;//???
2607 tmp_ratr_value = (ratr_value>>12);
2608 for(shortGI_rate=15; shortGI_rate>0; shortGI_rate--)
2610 if((1<<shortGI_rate) & tmp_ratr_value)
2611 break;
2613 shortGI_rate = (shortGI_rate<<12)|(shortGI_rate<<8)|(shortGI_rate<<4)|(shortGI_rate);
2614 write_nic_byte(dev, SG_RATE, shortGI_rate);
2615 //printk("==>SG_RATE:%x\n", read_nic_byte(dev, SG_RATE));
2617 write_nic_dword(dev, ARFR0+rate_index*4, ratr_value);
2618 printk("=============>ARFR0+rate_index*4:%#x\n", ratr_value);
2620 //2 UFWP
2621 if (ratr_value & 0xfffff000){
2622 //printk("===>set to N mode\n");
2623 HalSetFwCmd8192S(dev, FW_CMD_RA_REFRESH_N);
2625 else {
2626 //printk("===>set to B/G mode\n");
2627 HalSetFwCmd8192S(dev, FW_CMD_RA_REFRESH_BG);
2631 void rtl8192SU_link_change(struct net_device *dev)
2633 struct r8192_priv *priv = ieee80211_priv(dev);
2634 struct ieee80211_device *ieee = priv->ieee80211;
2635 u32 reg = 0;
2637 reg = read_nic_dword(dev, RCR);
2638 if (ieee->state == IEEE80211_LINKED) {
2639 rtl8192SU_net_update(dev);
2640 rtl8192SU_update_ratr_table(dev);
2641 ieee->SetFwCmdHandler(dev, FW_CMD_HIGH_PWR_ENABLE);
2642 priv->ReceiveConfig = reg |= RCR_CBSSID;
2644 } else
2645 priv->ReceiveConfig = reg &= ~RCR_CBSSID;
2646 write_nic_dword(dev, RCR, reg);
2647 rtl8192_update_msr(dev);
2650 static struct ieee80211_qos_parameters def_qos_parameters = {
2651 {3,3,3,3},/* cw_min */
2652 {7,7,7,7},/* cw_max */
2653 {2,2,2,2},/* aifs */
2654 {0,0,0,0},/* flags */
2655 {0,0,0,0} /* tx_op_limit */
2659 void rtl8192_update_beacon(struct work_struct * work)
2661 struct r8192_priv *priv = container_of(work, struct r8192_priv, update_beacon_wq.work);
2662 struct net_device *dev = priv->ieee80211->dev;
2663 struct ieee80211_device* ieee = priv->ieee80211;
2664 struct ieee80211_network* net = &ieee->current_network;
2666 if (ieee->pHTInfo->bCurrentHTSupport)
2667 HTUpdateSelfAndPeerSetting(ieee, net);
2668 ieee->pHTInfo->bCurrentRT2RTLongSlotTime = net->bssht.bdRT2RTLongSlotTime;
2669 // Joseph test for turbo mode with AP
2670 ieee->pHTInfo->RT2RT_HT_Mode = net->bssht.RT2RT_HT_Mode;
2671 rtl8192_update_cap(dev, net->capability);
2674 * background support to run QoS activate functionality
2676 int WDCAPARA_ADD[] = {EDCAPARA_BE,EDCAPARA_BK,EDCAPARA_VI,EDCAPARA_VO};
2678 void rtl8192_qos_activate(struct work_struct * work)
2680 struct r8192_priv *priv = container_of(work, struct r8192_priv, qos_activate);
2681 struct net_device *dev = priv->ieee80211->dev;
2682 struct ieee80211_qos_parameters *qos_parameters = &priv->ieee80211->current_network.qos_data.parameters;
2683 u8 mode = priv->ieee80211->current_network.mode;
2684 //u32 size = sizeof(struct ieee80211_qos_parameters);
2685 u8 u1bAIFS;
2686 u32 u4bAcParam;
2687 int i;
2689 if (priv == NULL)
2690 return;
2692 mutex_lock(&priv->mutex);
2694 if(priv->ieee80211->state != IEEE80211_LINKED)
2695 goto success;
2696 RT_TRACE(COMP_QOS,"qos active process with associate response received\n");
2697 /* It better set slot time at first */
2698 /* For we just support b/g mode at present, let the slot time at 9/20 selection */
2699 /* update the ac parameter to related registers */
2700 for(i = 0; i < QOS_QUEUE_NUM; i++) {
2701 //Mode G/A: slotTimeTimer = 9; Mode B: 20
2702 u1bAIFS = qos_parameters->aifs[i] * ((mode&(IEEE_G|IEEE_N_24G)) ?9:20) + aSifsTime;
2703 u4bAcParam = ((((u32)(qos_parameters->tx_op_limit[i]))<< AC_PARAM_TXOP_LIMIT_OFFSET)|
2704 (((u32)(qos_parameters->cw_max[i]))<< AC_PARAM_ECW_MAX_OFFSET)|
2705 (((u32)(qos_parameters->cw_min[i]))<< AC_PARAM_ECW_MIN_OFFSET)|
2706 ((u32)u1bAIFS << AC_PARAM_AIFS_OFFSET));
2708 write_nic_dword(dev, WDCAPARA_ADD[i], u4bAcParam);
2709 //write_nic_dword(dev, WDCAPARA_ADD[i], 0x005e4322);
2712 success:
2713 mutex_unlock(&priv->mutex);
2716 static int rtl8192_qos_handle_probe_response(struct r8192_priv *priv,
2717 int active_network,
2718 struct ieee80211_network *network)
2720 int ret = 0;
2721 u32 size = sizeof(struct ieee80211_qos_parameters);
2723 if(priv->ieee80211->state !=IEEE80211_LINKED)
2724 return ret;
2726 if ((priv->ieee80211->iw_mode != IW_MODE_INFRA))
2727 return ret;
2729 if (network->flags & NETWORK_HAS_QOS_MASK) {
2730 if (active_network &&
2731 (network->flags & NETWORK_HAS_QOS_PARAMETERS))
2732 network->qos_data.active = network->qos_data.supported;
2734 if ((network->qos_data.active == 1) && (active_network == 1) &&
2735 (network->flags & NETWORK_HAS_QOS_PARAMETERS) &&
2736 (network->qos_data.old_param_count !=
2737 network->qos_data.param_count)) {
2738 network->qos_data.old_param_count =
2739 network->qos_data.param_count;
2740 queue_work(priv->priv_wq, &priv->qos_activate);
2741 RT_TRACE (COMP_QOS, "QoS parameters change call "
2742 "qos_activate\n");
2744 } else {
2745 memcpy(&priv->ieee80211->current_network.qos_data.parameters,\
2746 &def_qos_parameters, size);
2748 if ((network->qos_data.active == 1) && (active_network == 1)) {
2749 queue_work(priv->priv_wq, &priv->qos_activate);
2750 RT_TRACE(COMP_QOS, "QoS was disabled call qos_activate \n");
2752 network->qos_data.active = 0;
2753 network->qos_data.supported = 0;
2756 return 0;
2759 /* handle manage frame frame beacon and probe response */
2760 static int rtl8192_handle_beacon(struct net_device * dev,
2761 struct ieee80211_probe_response *beacon,
2762 struct ieee80211_network *network)
2764 struct r8192_priv *priv = ieee80211_priv(dev);
2766 rtl8192_qos_handle_probe_response(priv,1,network);
2767 queue_delayed_work(priv->priv_wq, &priv->update_beacon_wq, 0);
2769 return 0;
2774 * handling the beaconing responses. if we get different QoS setting
2775 * off the network from the associated setting, adjust the QoS
2776 * setting
2778 static int rtl8192_qos_association_resp(struct r8192_priv *priv,
2779 struct ieee80211_network *network)
2781 int ret = 0;
2782 unsigned long flags;
2783 u32 size = sizeof(struct ieee80211_qos_parameters);
2784 int set_qos_param = 0;
2786 if ((priv == NULL) || (network == NULL))
2787 return ret;
2789 if(priv->ieee80211->state !=IEEE80211_LINKED)
2790 return ret;
2792 if ((priv->ieee80211->iw_mode != IW_MODE_INFRA))
2793 return ret;
2795 spin_lock_irqsave(&priv->ieee80211->lock, flags);
2796 if(network->flags & NETWORK_HAS_QOS_PARAMETERS) {
2797 memcpy(&priv->ieee80211->current_network.qos_data.parameters,\
2798 &network->qos_data.parameters,\
2799 sizeof(struct ieee80211_qos_parameters));
2800 priv->ieee80211->current_network.qos_data.active = 1;
2802 set_qos_param = 1;
2803 /* update qos parameter for current network */
2804 priv->ieee80211->current_network.qos_data.old_param_count = \
2805 priv->ieee80211->current_network.qos_data.param_count;
2806 priv->ieee80211->current_network.qos_data.param_count = \
2807 network->qos_data.param_count;
2809 } else {
2810 memcpy(&priv->ieee80211->current_network.qos_data.parameters,\
2811 &def_qos_parameters, size);
2812 priv->ieee80211->current_network.qos_data.active = 0;
2813 priv->ieee80211->current_network.qos_data.supported = 0;
2814 set_qos_param = 1;
2817 spin_unlock_irqrestore(&priv->ieee80211->lock, flags);
2819 RT_TRACE(COMP_QOS, "%s: network->flags = %d,%d\n",__FUNCTION__,network->flags ,priv->ieee80211->current_network.qos_data.active);
2820 if (set_qos_param == 1)
2821 queue_work(priv->priv_wq, &priv->qos_activate);
2823 return ret;
2827 static int rtl8192_handle_assoc_response(struct net_device *dev,
2828 struct ieee80211_assoc_response_frame *resp,
2829 struct ieee80211_network *network)
2831 struct r8192_priv *priv = ieee80211_priv(dev);
2832 rtl8192_qos_association_resp(priv, network);
2833 return 0;
2837 void rtl8192_update_ratr_table(struct net_device* dev)
2838 // POCTET_STRING posLegacyRate,
2839 // u8* pMcsRate)
2840 // PRT_WLAN_STA pEntry)
2842 struct r8192_priv* priv = ieee80211_priv(dev);
2843 struct ieee80211_device* ieee = priv->ieee80211;
2844 u8* pMcsRate = ieee->dot11HTOperationalRateSet;
2845 //struct ieee80211_network *net = &ieee->current_network;
2846 u32 ratr_value = 0;
2847 u8 rate_index = 0;
2848 rtl8192_config_rate(dev, (u16*)(&ratr_value));
2849 ratr_value |= (*(u16*)(pMcsRate)) << 12;
2850 // switch (net->mode)
2851 switch (ieee->mode)
2853 case IEEE_A:
2854 ratr_value &= 0x00000FF0;
2855 break;
2856 case IEEE_B:
2857 ratr_value &= 0x0000000F;
2858 break;
2859 case IEEE_G:
2860 ratr_value &= 0x00000FF7;
2861 break;
2862 case IEEE_N_24G:
2863 case IEEE_N_5G:
2864 if (ieee->pHTInfo->PeerMimoPs == 0) //MIMO_PS_STATIC
2865 ratr_value &= 0x0007F007;
2866 else{
2867 if (priv->rf_type == RF_1T2R)
2868 ratr_value &= 0x000FF007;
2869 else
2870 ratr_value &= 0x0F81F007;
2872 break;
2873 default:
2874 break;
2876 ratr_value &= 0x0FFFFFFF;
2877 if(ieee->pHTInfo->bCurTxBW40MHz && ieee->pHTInfo->bCurShortGI40MHz){
2878 ratr_value |= 0x80000000;
2879 }else if(!ieee->pHTInfo->bCurTxBW40MHz && ieee->pHTInfo->bCurShortGI20MHz){
2880 ratr_value |= 0x80000000;
2882 write_nic_dword(dev, RATR0+rate_index*4, ratr_value);
2883 write_nic_byte(dev, UFWP, 1);
2886 static u8 ccmp_ie[4] = {0x00,0x50,0xf2,0x04};
2887 static u8 ccmp_rsn_ie[4] = {0x00, 0x0f, 0xac, 0x04};
2888 bool GetNmodeSupportBySecCfg8192(struct net_device*dev)
2890 #if 1
2891 struct r8192_priv* priv = ieee80211_priv(dev);
2892 struct ieee80211_device* ieee = priv->ieee80211;
2893 struct ieee80211_network * network = &ieee->current_network;
2894 int wpa_ie_len= ieee->wpa_ie_len;
2895 struct ieee80211_crypt_data* crypt;
2896 int encrypt;
2897 return TRUE;
2899 crypt = ieee->crypt[ieee->tx_keyidx];
2900 //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
2901 encrypt = (network->capability & WLAN_CAPABILITY_PRIVACY) || (ieee->host_encrypt && crypt && crypt->ops && (0 == strcmp(crypt->ops->name,"WEP")));
2903 /* simply judge */
2904 if(encrypt && (wpa_ie_len == 0)) {
2905 /* wep encryption, no N mode setting */
2906 return false;
2907 // } else if((wpa_ie_len != 0)&&(memcmp(&(ieee->wpa_ie[14]),ccmp_ie,4))) {
2908 } else if((wpa_ie_len != 0)) {
2909 /* parse pairwise key type */
2910 //if((pairwisekey = WEP40)||(pairwisekey = WEP104)||(pairwisekey = TKIP))
2911 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))))
2912 return true;
2913 else
2914 return false;
2915 } else {
2916 return true;
2919 return true;
2920 #endif
2923 bool GetHalfNmodeSupportByAPs819xUsb(struct net_device* dev)
2925 bool Reval;
2926 struct r8192_priv* priv = ieee80211_priv(dev);
2927 struct ieee80211_device* ieee = priv->ieee80211;
2929 // Added by Roger, 2008.08.29.
2930 return false;
2932 if(ieee->bHalfWirelessN24GMode == true)
2933 Reval = true;
2934 else
2935 Reval = false;
2937 return Reval;
2940 void rtl8192_refresh_supportrate(struct r8192_priv* priv)
2942 struct ieee80211_device* ieee = priv->ieee80211;
2943 //we donot consider set support rate for ABG mode, only HT MCS rate is set here.
2944 if (ieee->mode == WIRELESS_MODE_N_24G || ieee->mode == WIRELESS_MODE_N_5G)
2946 memcpy(ieee->Regdot11HTOperationalRateSet, ieee->RegHTSuppRateSet, 16);
2947 //RT_DEBUG_DATA(COMP_INIT, ieee->RegHTSuppRateSet, 16);
2948 //RT_DEBUG_DATA(COMP_INIT, ieee->Regdot11HTOperationalRateSet, 16);
2950 else
2951 memset(ieee->Regdot11HTOperationalRateSet, 0, 16);
2952 return;
2955 u8 rtl8192_getSupportedWireleeMode(struct net_device*dev)
2957 struct r8192_priv *priv = ieee80211_priv(dev);
2958 u8 ret = 0;
2959 switch(priv->rf_chip)
2961 case RF_8225:
2962 case RF_8256:
2963 case RF_PSEUDO_11N:
2964 case RF_6052:
2965 ret = (WIRELESS_MODE_N_24G|WIRELESS_MODE_G|WIRELESS_MODE_B);
2966 break;
2967 case RF_8258:
2968 ret = (WIRELESS_MODE_A|WIRELESS_MODE_N_5G);
2969 break;
2970 default:
2971 ret = WIRELESS_MODE_B;
2972 break;
2974 return ret;
2976 void rtl8192_SetWirelessMode(struct net_device* dev, u8 wireless_mode)
2978 struct r8192_priv *priv = ieee80211_priv(dev);
2979 u8 bSupportMode = rtl8192_getSupportedWireleeMode(dev);
2981 #if 1
2982 if ((wireless_mode == WIRELESS_MODE_AUTO) || ((wireless_mode&bSupportMode)==0))
2984 if(bSupportMode & WIRELESS_MODE_N_24G)
2986 wireless_mode = WIRELESS_MODE_N_24G;
2988 else if(bSupportMode & WIRELESS_MODE_N_5G)
2990 wireless_mode = WIRELESS_MODE_N_5G;
2992 else if((bSupportMode & WIRELESS_MODE_A))
2994 wireless_mode = WIRELESS_MODE_A;
2996 else if((bSupportMode & WIRELESS_MODE_G))
2998 wireless_mode = WIRELESS_MODE_G;
3000 else if((bSupportMode & WIRELESS_MODE_B))
3002 wireless_mode = WIRELESS_MODE_B;
3004 else{
3005 RT_TRACE(COMP_ERR, "%s(), No valid wireless mode supported, SupportedWirelessMode(%x)!!!\n", __FUNCTION__,bSupportMode);
3006 wireless_mode = WIRELESS_MODE_B;
3009 #ifdef TO_DO_LIST //// TODO: this function doesn't work well at this time, we should wait for FPGA
3010 ActUpdateChannelAccessSetting( pAdapter, pHalData->CurrentWirelessMode, &pAdapter->MgntInfo.Info8185.ChannelAccessSetting );
3011 #endif
3012 //LZM 090306 usb crash here, mark it temp
3013 //write_nic_word(dev, SIFS_OFDM, 0x0e0e);
3014 priv->ieee80211->mode = wireless_mode;
3016 if ((wireless_mode == WIRELESS_MODE_N_24G) || (wireless_mode == WIRELESS_MODE_N_5G))
3017 priv->ieee80211->pHTInfo->bEnableHT = 1;
3018 else
3019 priv->ieee80211->pHTInfo->bEnableHT = 0;
3020 RT_TRACE(COMP_INIT, "Current Wireless Mode is %x\n", wireless_mode);
3021 rtl8192_refresh_supportrate(priv);
3022 #endif
3027 short rtl8192_is_tx_queue_empty(struct net_device *dev)
3029 int i=0;
3030 struct r8192_priv *priv = ieee80211_priv(dev);
3031 //struct ieee80211_device* ieee = priv->ieee80211;
3032 for (i=0; i<=MGNT_QUEUE; i++)
3034 if ((i== TXCMD_QUEUE) || (i == HCCA_QUEUE) )
3035 continue;
3036 if (atomic_read(&priv->tx_pending[i]))
3038 printk("===>tx queue is not empty:%d, %d\n", i, atomic_read(&priv->tx_pending[i]));
3039 return 0;
3042 return 1;
3045 void rtl8192_hw_sleep_down(struct net_device *dev)
3047 RT_TRACE(COMP_POWER, "%s()============>come to sleep down\n", __FUNCTION__);
3048 #ifdef TODO
3049 // MgntActSet_RF_State(dev, eRfSleep, RF_CHANGE_BY_PS);
3050 #endif
3053 void rtl8192_hw_sleep_wq (struct work_struct *work)
3055 // struct r8180_priv *priv = container_of(work, struct r8180_priv, watch_dog_wq);
3056 // struct ieee80211_device * ieee = (struct ieee80211_device*)
3057 // container_of(work, struct ieee80211_device, watch_dog_wq);
3058 struct delayed_work *dwork = container_of(work,struct delayed_work,work);
3059 struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,hw_sleep_wq);
3060 struct net_device *dev = ieee->dev;
3062 //printk("=========>%s()\n", __FUNCTION__);
3063 rtl8192_hw_sleep_down(dev);
3065 // printk("dev is %d\n",dev);
3066 // printk("&*&(^*(&(&=========>%s()\n", __FUNCTION__);
3067 void rtl8192_hw_wakeup(struct net_device* dev)
3069 // u32 flags = 0;
3071 // spin_lock_irqsave(&priv->ps_lock,flags);
3072 RT_TRACE(COMP_POWER, "%s()============>come to wake up\n", __FUNCTION__);
3073 #ifdef TODO
3074 // MgntActSet_RF_State(dev, eRfSleep, RF_CHANGE_BY_PS);
3075 #endif
3076 //FIXME: will we send package stored while nic is sleep?
3077 // spin_unlock_irqrestore(&priv->ps_lock,flags);
3080 void rtl8192_hw_wakeup_wq (struct work_struct *work)
3082 // struct r8180_priv *priv = container_of(work, struct r8180_priv, watch_dog_wq);
3083 // struct ieee80211_device * ieee = (struct ieee80211_device*)
3084 // container_of(work, struct ieee80211_device, watch_dog_wq);
3085 struct delayed_work *dwork = container_of(work,struct delayed_work,work);
3086 struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,hw_wakeup_wq);
3087 struct net_device *dev = ieee->dev;
3089 rtl8192_hw_wakeup(dev);
3092 #define MIN_SLEEP_TIME 50
3093 #define MAX_SLEEP_TIME 10000
3094 void rtl8192_hw_to_sleep(struct net_device *dev, u32 th, u32 tl)
3097 struct r8192_priv *priv = ieee80211_priv(dev);
3099 u32 rb = jiffies;
3100 unsigned long flags;
3102 spin_lock_irqsave(&priv->ps_lock,flags);
3104 /* Writing HW register with 0 equals to disable
3105 * the timer, that is not really what we want
3107 tl -= MSECS(4+16+7);
3109 //if(tl == 0) tl = 1;
3111 /* FIXME HACK FIXME HACK */
3112 // force_pci_posting(dev);
3113 //mdelay(1);
3115 // rb = read_nic_dword(dev, TSFTR);
3117 /* If the interval in witch we are requested to sleep is too
3118 * short then give up and remain awake
3120 if(((tl>=rb)&& (tl-rb) <= MSECS(MIN_SLEEP_TIME))
3121 ||((rb>tl)&& (rb-tl) < MSECS(MIN_SLEEP_TIME))) {
3122 spin_unlock_irqrestore(&priv->ps_lock,flags);
3123 printk("too short to sleep\n");
3124 return;
3127 // write_nic_dword(dev, TimerInt, tl);
3128 // rb = read_nic_dword(dev, TSFTR);
3130 u32 tmp = (tl>rb)?(tl-rb):(rb-tl);
3131 // if (tl<rb)
3133 queue_delayed_work(priv->ieee80211->wq, &priv->ieee80211->hw_wakeup_wq, tmp); //as tl may be less than rb
3135 /* if we suspect the TimerInt is gone beyond tl
3136 * while setting it, then give up
3138 #if 1
3139 if(((tl > rb) && ((tl-rb) > MSECS(MAX_SLEEP_TIME)))||
3140 ((tl < rb) && ((rb-tl) > MSECS(MAX_SLEEP_TIME)))) {
3141 printk("========>too long to sleep:%x, %x, %lx\n", tl, rb, MSECS(MAX_SLEEP_TIME));
3142 spin_unlock_irqrestore(&priv->ps_lock,flags);
3143 return;
3145 #endif
3146 // if(priv->rf_sleep)
3147 // priv->rf_sleep(dev);
3149 //printk("<=========%s()\n", __FUNCTION__);
3150 queue_delayed_work(priv->ieee80211->wq, (void *)&priv->ieee80211->hw_sleep_wq,0);
3152 spin_unlock_irqrestore(&priv->ps_lock,flags);
3154 //init priv variables here. only non_zero value should be initialized here.
3155 static void rtl8192_init_priv_variable(struct net_device* dev)
3157 struct r8192_priv *priv = ieee80211_priv(dev);
3158 u8 i;
3159 priv->card_8192 = NIC_8192U;
3160 priv->chan = 1; //set to channel 1
3161 priv->ieee80211->mode = WIRELESS_MODE_AUTO; //SET AUTO
3162 priv->ieee80211->iw_mode = IW_MODE_INFRA;
3163 priv->ieee80211->ieee_up=0;
3164 priv->retry_rts = DEFAULT_RETRY_RTS;
3165 priv->retry_data = DEFAULT_RETRY_DATA;
3166 priv->ieee80211->rts = DEFAULT_RTS_THRESHOLD;
3167 priv->ieee80211->rate = 110; //11 mbps
3168 priv->ieee80211->short_slot = 1;
3169 priv->promisc = (dev->flags & IFF_PROMISC) ? 1:0;
3170 priv->CckPwEnl = 6;
3171 //for silent reset
3172 priv->IrpPendingCount = 1;
3173 priv->ResetProgress = RESET_TYPE_NORESET;
3174 priv->bForcedSilentReset = 0;
3175 priv->bDisableNormalResetCheck = false;
3176 priv->force_reset = false;
3178 priv->ieee80211->FwRWRF = 0; //we don't use FW read/write RF until stable firmware is available.
3179 priv->ieee80211->current_network.beacon_interval = DEFAULT_BEACONINTERVAL;
3180 priv->ieee80211->iw_mode = IW_MODE_INFRA;
3181 priv->ieee80211->softmac_features = IEEE_SOFTMAC_SCAN |
3182 IEEE_SOFTMAC_ASSOCIATE | IEEE_SOFTMAC_PROBERQ |
3183 IEEE_SOFTMAC_PROBERS | IEEE_SOFTMAC_TX_QUEUE |
3184 IEEE_SOFTMAC_BEACONS;//added by amy 080604 //| //IEEE_SOFTMAC_SINGLE_QUEUE;
3186 priv->ieee80211->active_scan = 1;
3187 priv->ieee80211->modulation = IEEE80211_CCK_MODULATION | IEEE80211_OFDM_MODULATION;
3188 priv->ieee80211->host_encrypt = 1;
3189 priv->ieee80211->host_decrypt = 1;
3190 priv->ieee80211->start_send_beacons = NULL;//rtl819xusb_beacon_tx;//-by amy 080604
3191 priv->ieee80211->stop_send_beacons = NULL;//rtl8192_beacon_stop;//-by amy 080604
3192 priv->ieee80211->softmac_hard_start_xmit = rtl8192_hard_start_xmit;
3193 priv->ieee80211->set_chan = rtl8192_set_chan;
3194 priv->ieee80211->link_change = priv->ops->rtl819x_link_change;
3195 priv->ieee80211->softmac_data_hard_start_xmit = rtl8192_hard_data_xmit;
3196 priv->ieee80211->data_hard_stop = rtl8192_data_hard_stop;
3197 priv->ieee80211->data_hard_resume = rtl8192_data_hard_resume;
3198 priv->ieee80211->init_wmmparam_flag = 0;
3199 priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD;
3200 priv->ieee80211->check_nic_enough_desc = check_nic_enough_desc;
3201 priv->ieee80211->tx_headroom = TX_PACKET_SHIFT_BYTES;
3202 priv->ieee80211->qos_support = 1;
3204 //added by WB
3205 // priv->ieee80211->SwChnlByTimerHandler = rtl8192_phy_SwChnl;
3206 priv->ieee80211->SetBWModeHandler = rtl8192_SetBWMode;
3207 priv->ieee80211->handle_assoc_response = rtl8192_handle_assoc_response;
3208 priv->ieee80211->handle_beacon = rtl8192_handle_beacon;
3209 //for LPS
3210 priv->ieee80211->sta_wake_up = rtl8192_hw_wakeup;
3211 // priv->ieee80211->ps_request_tx_ack = rtl8192_rq_tx_ack;
3212 priv->ieee80211->enter_sleep_state = rtl8192_hw_to_sleep;
3213 priv->ieee80211->ps_is_queue_empty = rtl8192_is_tx_queue_empty;
3214 //added by david
3215 priv->ieee80211->GetNmodeSupportBySecCfg = GetNmodeSupportBySecCfg8192;
3216 priv->ieee80211->GetHalfNmodeSupportByAPsHandler = GetHalfNmodeSupportByAPs819xUsb;
3217 priv->ieee80211->SetWirelessMode = rtl8192_SetWirelessMode;
3218 //added by amy
3219 priv->ieee80211->InitialGainHandler = priv->ops->rtl819x_initial_gain;
3220 priv->card_type = USB;
3222 //1 RTL8192SU/
3223 priv->ieee80211->current_network.beacon_interval = DEFAULT_BEACONINTERVAL;
3224 priv->ieee80211->SetFwCmdHandler = HalSetFwCmd8192S;
3225 priv->bRFSiOrPi = 0;//o=si,1=pi;
3226 //lzm add
3227 priv->bInHctTest = false;
3229 priv->MidHighPwrTHR_L1 = 0x3B;
3230 priv->MidHighPwrTHR_L2 = 0x40;
3232 if(priv->bInHctTest)
3234 priv->ShortRetryLimit = HAL_RETRY_LIMIT_AP_ADHOC;
3235 priv->LongRetryLimit = HAL_RETRY_LIMIT_AP_ADHOC;
3237 else
3239 priv->ShortRetryLimit = HAL_RETRY_LIMIT_INFRA;
3240 priv->LongRetryLimit = HAL_RETRY_LIMIT_INFRA;
3243 priv->SetFwCmdInProgress = false; //is set FW CMD in Progress? 92S only
3244 priv->CurrentFwCmdIO = 0;
3246 priv->MinSpaceCfg = 0;
3248 priv->EarlyRxThreshold = 7;
3249 priv->enable_gpio0 = 0;
3250 priv->TransmitConfig =
3251 ((u32)TCR_MXDMA_2048<<TCR_MXDMA_OFFSET) | // Max DMA Burst Size per Tx DMA Burst, 7: reservied.
3252 (priv->ShortRetryLimit<<TCR_SRL_OFFSET) | // Short retry limit
3253 (priv->LongRetryLimit<<TCR_LRL_OFFSET) | // Long retry limit
3254 (false ? TCR_SAT : 0); // FALSE: HW provies PLCP length and LENGEXT, TURE: SW proiveds them
3255 if(priv->bInHctTest)
3256 priv->ReceiveConfig = //priv->CSMethod |
3257 RCR_AMF | RCR_ADF | //RCR_AAP | //accept management/data
3258 RCR_ACF |RCR_APPFCS| //accept control frame for SW AP needs PS-poll, 2005.07.07, by rcnjko.
3259 RCR_AB | RCR_AM | RCR_APM | //accept BC/MC/UC
3260 RCR_AICV | RCR_ACRC32 | //accept ICV/CRC error packet
3261 RCR_APP_PHYST_STAFF | RCR_APP_PHYST_RXFF | // Accept PHY status
3262 ((u32)7<<RCR_MXDMA_OFFSET) | // Max DMA Burst Size per Rx DMA Burst, 7: unlimited.
3263 (priv->EarlyRxThreshold<<RCR_FIFO_OFFSET) | // Rx FIFO Threshold, 7: No Rx threshold.
3264 (priv->EarlyRxThreshold == 7 ? RCR_OnlyErlPkt:0);
3265 else
3266 priv->ReceiveConfig = //priv->CSMethod |
3267 RCR_AMF | RCR_ADF | RCR_AB |
3268 RCR_AM | RCR_APM |RCR_AAP |RCR_ADD3|RCR_APP_ICV|
3269 RCR_APP_PHYST_STAFF | RCR_APP_PHYST_RXFF | // Accept PHY status
3270 RCR_APP_MIC | RCR_APPFCS;
3272 // <Roger_EXP> 2008.06.16.
3273 priv->IntrMask = (u16)(IMR_ROK | IMR_VODOK | IMR_VIDOK | IMR_BEDOK | IMR_BKDOK | \
3274 IMR_HCCADOK | IMR_MGNTDOK | IMR_COMDOK | IMR_HIGHDOK | \
3275 IMR_BDOK | IMR_RXCMDOK | /*IMR_TIMEOUT0 |*/ IMR_RDU | IMR_RXFOVW | \
3276 IMR_TXFOVW | IMR_BcnInt | IMR_TBDOK | IMR_TBDER);
3278 //1 End
3281 priv->AcmControl = 0;
3282 priv->pFirmware = (rt_firmware*)vmalloc(sizeof(rt_firmware));
3283 if (priv->pFirmware)
3284 memset(priv->pFirmware, 0, sizeof(rt_firmware));
3286 /* rx related queue */
3287 skb_queue_head_init(&priv->rx_queue);
3288 skb_queue_head_init(&priv->skb_queue);
3290 /* Tx related queue */
3291 for(i = 0; i < MAX_QUEUE_SIZE; i++) {
3292 skb_queue_head_init(&priv->ieee80211->skb_waitQ [i]);
3294 for(i = 0; i < MAX_QUEUE_SIZE; i++) {
3295 skb_queue_head_init(&priv->ieee80211->skb_aggQ [i]);
3297 for(i = 0; i < MAX_QUEUE_SIZE; i++) {
3298 skb_queue_head_init(&priv->ieee80211->skb_drv_aggQ [i]);
3300 priv->rf_set_chan = rtl8192_phy_SwChnl;
3303 //init lock here
3304 static void rtl8192_init_priv_lock(struct r8192_priv* priv)
3306 spin_lock_init(&priv->tx_lock);
3307 spin_lock_init(&priv->irq_lock);//added by thomas
3308 //spin_lock_init(&priv->rf_lock);//use rf_sem, or will crash in some OS.
3309 sema_init(&priv->wx_sem,1);
3310 sema_init(&priv->rf_sem,1);
3311 spin_lock_init(&priv->ps_lock);
3312 mutex_init(&priv->mutex);
3315 extern void rtl819x_watchdog_wqcallback(struct work_struct *work);
3317 void rtl8192_irq_rx_tasklet(struct r8192_priv *priv);
3318 //init tasklet and wait_queue here. only 2.6 above kernel is considered
3319 #define DRV_NAME "wlan0"
3320 static void rtl8192_init_priv_task(struct net_device* dev)
3322 struct r8192_priv *priv = ieee80211_priv(dev);
3324 #ifdef PF_SYNCTHREAD
3325 priv->priv_wq = create_workqueue(DRV_NAME,0);
3326 #else
3327 priv->priv_wq = create_workqueue(DRV_NAME);
3328 #endif
3330 INIT_WORK(&priv->reset_wq, rtl8192_restart);
3332 //INIT_DELAYED_WORK(&priv->watch_dog_wq, hal_dm_watchdog);
3333 INIT_DELAYED_WORK(&priv->watch_dog_wq, rtl819x_watchdog_wqcallback);
3334 INIT_DELAYED_WORK(&priv->txpower_tracking_wq, dm_txpower_trackingcallback);
3335 // INIT_DELAYED_WORK(&priv->gpio_change_rf_wq, dm_gpio_change_rf_callback);
3336 INIT_DELAYED_WORK(&priv->rfpath_check_wq, dm_rf_pathcheck_workitemcallback);
3337 INIT_DELAYED_WORK(&priv->update_beacon_wq, rtl8192_update_beacon);
3338 INIT_DELAYED_WORK(&priv->initialgain_operate_wq, InitialGainOperateWorkItemCallBack);
3339 //INIT_WORK(&priv->SwChnlWorkItem, rtl8192_SwChnl_WorkItem);
3340 //INIT_WORK(&priv->SetBWModeWorkItem, rtl8192_SetBWModeWorkItem);
3341 INIT_WORK(&priv->qos_activate, rtl8192_qos_activate);
3342 INIT_DELAYED_WORK(&priv->ieee80211->hw_wakeup_wq,(void*) rtl8192_hw_wakeup_wq);
3343 INIT_DELAYED_WORK(&priv->ieee80211->hw_sleep_wq,(void*) rtl8192_hw_sleep_wq);
3345 tasklet_init(&priv->irq_rx_tasklet,
3346 (void(*)(unsigned long))rtl8192_irq_rx_tasklet,
3347 (unsigned long)priv);
3350 //used to swap endian. as ntohl & htonl are not neccessary to swap endian, so use this instead.
3351 static inline u16 endian_swap(u16* data)
3353 u16 tmp = *data;
3354 *data = (tmp >> 8) | (tmp << 8);
3355 return *data;
3358 u8 rtl8192SU_UsbOptionToEndPointNumber(u8 UsbOption)
3360 u8 nEndPoint = 0;
3361 switch(UsbOption)
3363 case 0:
3364 nEndPoint = 6;
3365 break;
3366 case 1:
3367 nEndPoint = 11;
3368 break;
3369 case 2:
3370 nEndPoint = 4;
3371 break;
3372 default:
3373 RT_TRACE(COMP_INIT, "UsbOptionToEndPointNumber(): Invalid UsbOption(%#x)\n", UsbOption);
3374 break;
3376 return nEndPoint;
3379 u8 rtl8192SU_BoardTypeToRFtype(struct net_device* dev, u8 Boardtype)
3381 u8 RFtype = RF_1T2R;
3383 switch(Boardtype)
3385 case 0:
3386 RFtype = RF_1T1R;
3387 break;
3388 case 1:
3389 RFtype = RF_1T2R;
3390 break;
3391 case 2:
3392 RFtype = RF_2T2R;
3393 break;
3394 case 3:
3395 RFtype = RF_2T2R_GREEN;
3396 break;
3397 default:
3398 break;
3401 return RFtype;
3404 void update_hal_variables(struct r8192_priv *priv)
3406 int rf_path;
3407 int i;
3408 u8 index;
3410 for (rf_path = 0; rf_path < 2; rf_path++) {
3411 for (i = 0; i < 3; i++) {
3412 RT_TRACE((COMP_INIT), "CCK RF-%d CHan_Area-%d = 0x%x\n", rf_path, i, priv->RfCckChnlAreaTxPwr[rf_path][i]);
3413 RT_TRACE((COMP_INIT), "OFDM-1T RF-%d CHan_Area-%d = 0x%x\n", rf_path, i, priv->RfOfdmChnlAreaTxPwr1T[rf_path][i]);
3414 RT_TRACE((COMP_INIT), "OFDM-2T RF-%d CHan_Area-%d = 0x%x\n", rf_path, i, priv->RfOfdmChnlAreaTxPwr2T[rf_path][i]);
3416 /* Assign dedicated channel tx power */
3417 for(i = 0; i < 14; i++) {
3418 /* channel 1-3 use the same Tx Power Level. */
3419 if (i < 3) /* Channel 1-3 */
3420 index = 0;
3421 else if (i < 9) /* Channel 4-9 */
3422 index = 1;
3423 else /* Channel 10-14 */
3424 index = 2;
3425 /* Record A & B CCK /OFDM - 1T/2T Channel area tx power */
3426 priv->RfTxPwrLevelCck[rf_path][i] = priv->RfCckChnlAreaTxPwr[rf_path][index];
3427 priv->RfTxPwrLevelOfdm1T[rf_path][i] = priv->RfOfdmChnlAreaTxPwr1T[rf_path][index];
3428 priv->RfTxPwrLevelOfdm2T[rf_path][i] = priv->RfOfdmChnlAreaTxPwr2T[rf_path][index];
3429 if (rf_path == 0) {
3430 priv->TxPowerLevelOFDM24G[i] = priv->RfTxPwrLevelOfdm1T[rf_path][i] ;
3431 priv->TxPowerLevelCCK[i] = priv->RfTxPwrLevelCck[rf_path][i];
3434 for(i = 0; i < 14; i++) {
3435 RT_TRACE((COMP_INIT),
3436 "Rf-%d TxPwr CH-%d CCK OFDM_1T OFDM_2T= 0x%x/0x%x/0x%x\n",
3437 rf_path, i, priv->RfTxPwrLevelCck[rf_path][i],
3438 priv->RfTxPwrLevelOfdm1T[rf_path][i] ,
3439 priv->RfTxPwrLevelOfdm2T[rf_path][i] );
3445 * Description:
3446 * Config HW adapter information into initial value.
3448 * Assumption:
3449 * 1. After Auto load fail(i.e, check CR9346 fail)
3452 void rtl8192SU_ConfigAdapterInfo8192SForAutoLoadFail(struct net_device *dev)
3454 struct r8192_priv *priv = ieee80211_priv(dev);
3455 u8 rf_path; /* For EEPROM/EFUSE After V0.6_1117 */
3456 int i;
3458 RT_TRACE(COMP_INIT, "====> ConfigAdapterInfo8192SForAutoLoadFail\n");
3460 /* Isolation signals from Loader */
3461 write_nic_byte(dev, SYS_ISO_CTRL+1, 0xE8);
3462 mdelay(10);
3463 write_nic_byte(dev, PMC_FSM, 0x02); /* Enable Loader Data Keep */
3465 /* Initialize IC Version && Channel Plan */
3466 priv->eeprom_vid = 0;
3467 priv->eeprom_pid = 0;
3468 priv->card_8192_version = 0;
3469 priv->eeprom_ChannelPlan = 0;
3470 priv->eeprom_CustomerID = 0;
3471 priv->eeprom_SubCustomerID = 0;
3472 priv->bIgnoreDiffRateTxPowerOffset = false;
3474 RT_TRACE(COMP_INIT, "EEPROM VID = 0x%4x\n", priv->eeprom_vid);
3475 RT_TRACE(COMP_INIT, "EEPROM PID = 0x%4x\n", priv->eeprom_pid);
3476 RT_TRACE(COMP_INIT, "EEPROM Customer ID: 0x%2x\n",
3477 priv->eeprom_CustomerID);
3478 RT_TRACE(COMP_INIT, "EEPROM SubCustomer ID: 0x%2x\n",
3479 priv->eeprom_SubCustomerID);
3480 RT_TRACE(COMP_INIT, "EEPROM ChannelPlan = 0x%4x\n",
3481 priv->eeprom_ChannelPlan);
3482 RT_TRACE(COMP_INIT, "IgnoreDiffRateTxPowerOffset = %d\n",
3483 priv->bIgnoreDiffRateTxPowerOffset);
3485 priv->EEPROMUsbOption = EEPROM_USB_Default_OPTIONAL_FUNC;
3486 RT_TRACE(COMP_INIT, "USB Option = %#x\n", priv->EEPROMUsbOption);
3488 for(i=0; i<5; i++)
3489 priv->EEPROMUsbPhyParam[i] = EEPROM_USB_Default_PHY_PARAM;
3493 * In this case, we randomly assign a MAC address here.
3495 static u8 sMacAddr[6] = {0x00, 0xE0, 0x4C, 0x81, 0x92, 0x00};
3496 for(i = 0; i < 6; i++)
3497 dev->dev_addr[i] = sMacAddr[i];
3499 /* NicIFSetMacAddress(Adapter, Adapter->PermanentAddress); */
3500 write_nic_dword(dev, IDR0, ((u32*)dev->dev_addr)[0]);
3501 write_nic_word(dev, IDR4, ((u16*)(dev->dev_addr + 4))[0]);
3503 RT_TRACE(COMP_INIT,
3504 "ReadAdapterInfo8192SEFuse(), Permanent Address = %pM\n",
3505 dev->dev_addr);
3507 priv->EEPROMBoardType = EEPROM_Default_BoardType;
3508 priv->rf_type = RF_1T2R; /* RF_2T2R */
3509 priv->EEPROMTxPowerDiff = EEPROM_Default_PwDiff;
3510 priv->EEPROMThermalMeter = EEPROM_Default_ThermalMeter;
3511 priv->EEPROMCrystalCap = EEPROM_Default_CrystalCap;
3512 priv->EEPROMTxPwrBase = EEPROM_Default_TxPowerBase;
3513 priv->EEPROMTSSI_A = EEPROM_Default_TSSI;
3514 priv->EEPROMTSSI_B = EEPROM_Default_TSSI;
3515 priv->EEPROMTxPwrTkMode = EEPROM_Default_TxPwrTkMode;
3517 for (rf_path = 0; rf_path < 2; rf_path++)
3519 for (i = 0; i < 3; i++)
3521 /* Read CCK RF A & B Tx power */
3522 priv->RfCckChnlAreaTxPwr[rf_path][i] =
3523 priv->RfOfdmChnlAreaTxPwr1T[rf_path][i] =
3524 priv->RfOfdmChnlAreaTxPwr2T[rf_path][i] =
3525 (u8)(EEPROM_Default_TxPower & 0xff);
3529 update_hal_variables(priv);
3532 * Update remaining HAL variables.
3534 priv->TSSI_13dBm = priv->EEPROMThermalMeter *100;
3535 priv->LegacyHTTxPowerDiff = priv->EEPROMTxPowerDiff; /* new */
3536 priv->TxPowerDiff = priv->EEPROMTxPowerDiff;
3537 /* Antenna B gain offset to antenna A, bit0~3 */
3538 /* priv->AntennaTxPwDiff[0] = (priv->EEPROMTxPowerDiff & 0xf); */
3539 /* Antenna C gain offset to antenna A, bit4~7 */
3540 /* priv->AntennaTxPwDiff[1] = ((priv->EEPROMTxPowerDiff & 0xf0)>>4); */
3541 /* CrystalCap, bit12~15 */
3542 priv->CrystalCap = priv->EEPROMCrystalCap;
3543 /* ThermalMeter, bit0~3 for RFIC1, bit4~7 for RFIC2 */
3544 priv->ThermalMeter[0] = priv->EEPROMThermalMeter;
3545 priv->LedStrategy = SW_LED_MODE0;
3547 init_rate_adaptive(dev);
3549 RT_TRACE(COMP_INIT, "<==== ConfigAdapterInfo8192SForAutoLoadFail\n");
3553 * Description:
3554 * Read HW adapter information by E-Fuse
3555 * or EEPROM according CR9346 reported.
3557 * Assumption:
3558 * 1. CR9346 regiser has verified.
3559 * 2. PASSIVE_LEVEL (USB interface)
3561 void rtl8192SU_ReadAdapterInfo8192SUsb(struct net_device *dev)
3563 struct r8192_priv *priv = ieee80211_priv(dev);
3564 u16 i;
3565 u8 tmpU1b, tempval;
3566 u16 EEPROMId;
3567 u8 hwinfo[HWSET_MAX_SIZE_92S];
3568 u8 rf_path, index; /* For EEPROM/EFUSE After V0.6_1117 */
3569 struct eeprom_93cx6 eeprom;
3570 u16 eeprom_val;
3572 eeprom.data = dev;
3573 eeprom.register_read = rtl819x_eeprom_register_read;
3574 eeprom.register_write = rtl819x_eeprom_register_write;
3575 eeprom.width = PCI_EEPROM_WIDTH_93C46;
3578 * The following operation are prevent Efuse leakage by turn on 2.5V.
3580 tmpU1b = read_nic_byte(dev, EFUSE_TEST+3);
3581 write_nic_byte(dev, EFUSE_TEST+3, tmpU1b|0x80);
3582 mdelay(10);
3583 write_nic_byte(dev, EFUSE_TEST+3, (tmpU1b&(~BIT7)));
3585 /* Retrieve Chip version. */
3586 priv->card_8192_version = (VERSION_8192S)((read_nic_dword(dev, PMC_FSM)>>16)&0xF);
3587 RT_TRACE(COMP_INIT, "Chip Version ID: 0x%2x\n", priv->card_8192_version);
3589 switch (priv->card_8192_version) {
3590 case 0:
3591 RT_TRACE(COMP_INIT, "Chip Version ID: VERSION_8192S_ACUT.\n");
3592 break;
3593 case 1:
3594 RT_TRACE(COMP_INIT, "Chip Version ID: VERSION_8192S_BCUT.\n");
3595 break;
3596 case 2:
3597 RT_TRACE(COMP_INIT, "Chip Version ID: VERSION_8192S_CCUT.\n");
3598 break;
3599 default:
3600 RT_TRACE(COMP_INIT, "Unknown Chip Version!!\n");
3601 priv->card_8192_version = VERSION_8192S_BCUT;
3602 break;
3605 if (priv->EepromOrEfuse) { /* Read from EEPROM */
3606 /* Isolation signals from Loader */
3607 write_nic_byte(dev, SYS_ISO_CTRL+1, 0xE8);
3608 mdelay(10);
3609 /* Enable Loader Data Keep */
3610 write_nic_byte(dev, PMC_FSM, 0x02);
3611 /* Read all Content from EEPROM or EFUSE. */
3612 for (i = 0; i < HWSET_MAX_SIZE_92S; i += 2) {
3613 eeprom_93cx6_read(&eeprom, (u16) (i>>1), &eeprom_val);
3614 *((u16 *)(&hwinfo[i])) = eeprom_val;
3616 } else if (!(priv->EepromOrEfuse)) { /* Read from EFUSE */
3617 /* Read EFUSE real map to shadow. */
3618 EFUSE_ShadowMapUpdate(dev);
3619 memcpy(hwinfo, &priv->EfuseMap[EFUSE_INIT_MAP][0], HWSET_MAX_SIZE_92S);
3620 } else {
3621 RT_TRACE(COMP_INIT, "%s(): Invalid boot type", __func__);
3625 * Even though CR9346 regiser can verify whether Autoload
3626 * is success or not, but we still double check ID codes for 92S here
3627 * (e.g., due to HW GPIO polling fail issue)
3629 EEPROMId = *((u16 *)&hwinfo[0]);
3630 if (EEPROMId != RTL8190_EEPROM_ID) {
3631 RT_TRACE(COMP_INIT, "ID(%#x) is invalid!!\n", EEPROMId);
3632 priv->bTXPowerDataReadFromEEPORM = FALSE;
3633 priv->AutoloadFailFlag=TRUE;
3634 } else {
3635 priv->AutoloadFailFlag=FALSE;
3636 priv->bTXPowerDataReadFromEEPORM = TRUE;
3638 /* Read IC Version && Channel Plan */
3639 if (!priv->AutoloadFailFlag) {
3640 /* VID, PID */
3641 priv->eeprom_vid = *(u16 *)&hwinfo[EEPROM_VID];
3642 priv->eeprom_pid = *(u16 *)&hwinfo[EEPROM_PID];
3643 priv->bIgnoreDiffRateTxPowerOffset = false; //cosa for test
3646 /* EEPROM Version ID, Channel plan */
3647 priv->EEPROMVersion = *(u8 *)&hwinfo[EEPROM_Version];
3648 priv->eeprom_ChannelPlan = *(u8 *)&hwinfo[EEPROM_ChannelPlan];
3650 /* Customer ID, 0x00 and 0xff are reserved for Realtek. */
3651 priv->eeprom_CustomerID = *(u8 *)&hwinfo[EEPROM_CustomID];
3652 priv->eeprom_SubCustomerID = *(u8 *)&hwinfo[EEPROM_SubCustomID];
3653 } else {
3654 rtl8192SU_ConfigAdapterInfo8192SForAutoLoadFail(dev);
3655 return;
3658 RT_TRACE(COMP_INIT, "EEPROM Id = 0x%4x\n", EEPROMId);
3659 RT_TRACE(COMP_INIT, "EEPROM VID = 0x%4x\n", priv->eeprom_vid);
3660 RT_TRACE(COMP_INIT, "EEPROM PID = 0x%4x\n", priv->eeprom_pid);
3661 RT_TRACE(COMP_INIT, "EEPROM Version ID: 0x%2x\n", priv->EEPROMVersion);
3662 RT_TRACE(COMP_INIT, "EEPROM Customer ID: 0x%2x\n", priv->eeprom_CustomerID);
3663 RT_TRACE(COMP_INIT, "EEPROM SubCustomer ID: 0x%2x\n", priv->eeprom_SubCustomerID);
3664 RT_TRACE(COMP_INIT, "EEPROM ChannelPlan = 0x%4x\n", priv->eeprom_ChannelPlan);
3665 RT_TRACE(COMP_INIT, "bIgnoreDiffRateTxPowerOffset = %d\n", priv->bIgnoreDiffRateTxPowerOffset);
3667 /* Read USB optional function. */
3668 if (!priv->AutoloadFailFlag) {
3669 priv->EEPROMUsbOption = *(u8 *)&hwinfo[EEPROM_USB_OPTIONAL];
3670 } else {
3671 priv->EEPROMUsbOption = EEPROM_USB_Default_OPTIONAL_FUNC;
3674 priv->EEPROMUsbEndPointNumber = rtl8192SU_UsbOptionToEndPointNumber((priv->EEPROMUsbOption&EEPROM_EP_NUMBER)>>3);
3676 RT_TRACE(COMP_INIT, "USB Option = %#x\n", priv->EEPROMUsbOption);
3677 RT_TRACE(COMP_INIT, "EndPoint Number = %#x\n", priv->EEPROMUsbEndPointNumber);
3679 #ifdef TO_DO_LIST
3681 // Decide CustomerID according to VID/DID or EEPROM
3683 switch(pHalData->EEPROMCustomerID)
3685 case EEPROM_CID_ALPHA:
3686 pMgntInfo->CustomerID = RT_CID_819x_ALPHA;
3687 break;
3689 case EEPROM_CID_CAMEO:
3690 pMgntInfo->CustomerID = RT_CID_819x_CAMEO;
3691 break;
3693 case EEPROM_CID_SITECOM:
3694 pMgntInfo->CustomerID = RT_CID_819x_Sitecom;
3695 RT_TRACE(COMP_INIT, DBG_LOUD, ("CustomerID = 0x%4x\n", pMgntInfo->CustomerID));
3697 break;
3699 case EEPROM_CID_WHQL:
3700 Adapter->bInHctTest = TRUE;
3702 pMgntInfo->bSupportTurboMode = FALSE;
3703 pMgntInfo->bAutoTurboBy8186 = FALSE;
3705 pMgntInfo->PowerSaveControl.bInactivePs = FALSE;
3706 pMgntInfo->PowerSaveControl.bIPSModeBackup = FALSE;
3707 pMgntInfo->PowerSaveControl.bLeisurePs = FALSE;
3708 pMgntInfo->keepAliveLevel = 0;
3709 break;
3711 default:
3712 pMgntInfo->CustomerID = RT_CID_DEFAULT;
3713 break;
3718 // Led mode
3720 switch(pMgntInfo->CustomerID)
3722 case RT_CID_DEFAULT:
3723 case RT_CID_819x_ALPHA:
3724 pHalData->LedStrategy = SW_LED_MODE1;
3725 pHalData->bRegUseLed = TRUE;
3726 pHalData->SwLed1.bLedOn = TRUE;
3727 break;
3728 case RT_CID_819x_CAMEO:
3729 pHalData->LedStrategy = SW_LED_MODE1;
3730 pHalData->bRegUseLed = TRUE;
3731 break;
3733 case RT_CID_819x_Sitecom:
3734 pHalData->LedStrategy = SW_LED_MODE2;
3735 pHalData->bRegUseLed = TRUE;
3736 break;
3738 default:
3739 pHalData->LedStrategy = SW_LED_MODE0;
3740 break;
3742 #endif
3744 // Read USB PHY parameters.
3745 for(i=0; i<5; i++)
3746 priv->EEPROMUsbPhyParam[i] = *(u8 *)&hwinfo[EEPROM_USB_PHY_PARA1+i];
3748 //RT_PRINT_DATA(COMP_EFUSE, DBG_LOUD, ("USB PHY Param: \n"), pHalData->EEPROMUsbPhyParam, 5);
3751 //Read Permanent MAC address
3752 for(i=0; i<6; i++)
3753 dev->dev_addr[i] = *(u8 *)&hwinfo[EEPROM_NODE_ADDRESS_BYTE_0+i];
3755 //NicIFSetMacAddress(Adapter, Adapter->PermanentAddress);
3756 write_nic_dword(dev, IDR0, ((u32*)dev->dev_addr)[0]);
3757 write_nic_word(dev, IDR4, ((u16*)(dev->dev_addr + 4))[0]);
3759 RT_TRACE(COMP_INIT,
3760 "ReadAdapterInfo8192SEFuse(), Permanent Address = %pM\n",
3761 dev->dev_addr);
3764 // Get CustomerID(Boad Type)
3765 // i.e., 0x0: RTL8188SU, 0x1: RTL8191SU, 0x2: RTL8192SU, 0x3: RTL8191GU.
3766 // Others: Reserved. Default is 0x2: RTL8192SU.
3768 //if(!priv->AutoloadFailFlag)
3770 priv->EEPROMBoardType = *(u8 *)&hwinfo[EEPROM_BoardType];
3771 priv->rf_type = rtl8192SU_BoardTypeToRFtype(dev, priv->EEPROMBoardType);
3773 //else
3775 // priv->EEPROMBoardType = EEPROM_Default_BoardType;
3776 // priv->rf_type = RF_1T2R;
3779 priv->rf_chip = RF_6052;
3781 priv->rf_chip = RF_6052;//lzm test
3782 RT_TRACE(COMP_INIT, "BoardType = 0x%2x\n", priv->EEPROMBoardType);
3783 RT_TRACE(COMP_INIT, "RF_Type = 0x%2x\n", priv->rf_type);
3786 // Read antenna tx power offset of B/C/D to A from EEPROM
3787 // and read ThermalMeter from EEPROM
3789 //if(!priv->AutoloadFailFlag)
3791 priv->EEPROMTxPowerDiff = *(u8 *)&hwinfo[EEPROM_PwDiff];
3792 priv->EEPROMThermalMeter = *(u8 *)&hwinfo[EEPROM_ThermalMeter];
3794 //else
3796 // priv->EEPROMTxPowerDiff = EEPROM_Default_PwDiff;
3797 // priv->EEPROMThermalMeter = EEPROM_Default_ThermalMeter;
3800 RT_TRACE(COMP_INIT, "PwDiff = %#x\n", priv->EEPROMTxPowerDiff);
3801 RT_TRACE(COMP_INIT, "ThermalMeter = %#x\n", priv->EEPROMThermalMeter);
3804 // Read Tx Power gain offset of legacy OFDM to HT rate.
3805 // Read CrystalCap from EEPROM
3807 //if(!priv->AutoloadFailFlag)
3809 priv->EEPROMCrystalCap = *(u8 *)&hwinfo[EEPROM_CrystalCap];
3811 //else
3813 // priv->EEPROMCrystalCap = EEPROM_Default_CrystalCap;
3816 RT_TRACE(COMP_INIT, "CrystalCap = %#x\n", priv->EEPROMCrystalCap);
3819 // Get Tx Power Base.
3821 //if(!priv->AutoloadFailFlag)
3823 priv->EEPROMTxPwrBase = *(u8 *)&hwinfo[EEPROM_TxPowerBase];
3825 //else
3827 // priv->EEPROMTxPwrBase = EEPROM_Default_TxPowerBase;
3830 RT_TRACE(COMP_INIT, "TxPwrBase = %#x\n", priv->EEPROMTxPwrBase);
3834 // Get TSSI value for each path.
3836 //if(!priv->AutoloadFailFlag)
3838 priv->EEPROMTSSI_A = *(u8 *)&hwinfo[EEPROM_TSSI_A];
3839 priv->EEPROMTSSI_B = *(u8 *)&hwinfo[EEPROM_TSSI_B];
3841 //else
3842 //{ // Default setting for Empty EEPROM
3843 // priv->EEPROMTSSI_A = EEPROM_Default_TSSI;
3844 // priv->EEPROMTSSI_B = EEPROM_Default_TSSI;
3847 RT_TRACE(COMP_INIT, "TSSI_A = %#x, TSSI_B = %#x\n", priv->EEPROMTSSI_A, priv->EEPROMTSSI_B);
3850 // Get Tx Power tracking mode.
3852 //if(!priv->AutoloadFailFlag)
3854 priv->EEPROMTxPwrTkMode = *(u8 *)&hwinfo[EEPROM_TxPwTkMode];
3857 RT_TRACE(COMP_INIT, "TxPwrTkMod = %#x\n", priv->EEPROMTxPwrTkMode);
3862 // Buffer TxPwIdx(i.e., from offset 0x55~0x66, total 18Bytes)
3863 // Update CCK, OFDM (1T/2T)Tx Power Index from above buffer.
3867 // Get Tx Power Level by Channel
3869 //if(!priv->AutoloadFailFlag)
3871 // Read Tx power of Channel 1 ~ 14 from EFUSE.
3872 // 92S suupport RF A & B
3873 for (rf_path = 0; rf_path < 2; rf_path++)
3875 for (i = 0; i < 3; i++)
3877 // Read CCK RF A & B Tx power
3878 priv->RfCckChnlAreaTxPwr[rf_path][i] =
3879 hwinfo[EEPROM_TxPwIndex+rf_path*3+i];
3881 // Read OFDM RF A & B Tx power for 1T
3882 priv->RfOfdmChnlAreaTxPwr1T[rf_path][i] =
3883 hwinfo[EEPROM_TxPwIndex+6+rf_path*3+i];
3885 // Read OFDM RF A & B Tx power for 2T
3886 priv->RfOfdmChnlAreaTxPwr2T[rf_path][i] =
3887 hwinfo[EEPROM_TxPwIndex+12+rf_path*3+i];
3892 update_hal_variables(priv);
3896 // 2009/02/09 Cosa add for new EEPROM format
3898 for(i=0; i<14; i++) // channel 1~3 use the same Tx Power Level.
3900 // Read tx power difference between HT OFDM 20/40 MHZ
3901 if (i < 3) // Cjanel 1-3
3902 index = 0;
3903 else if (i < 9) // Channel 4-9
3904 index = 1;
3905 else // Channel 10-14
3906 index = 2;
3908 tempval = (*(u8 *)&hwinfo[EEPROM_TX_PWR_HT20_DIFF+index])&0xff;
3909 priv->TxPwrHt20Diff[RF90_PATH_A][i] = (tempval&0xF);
3910 priv->TxPwrHt20Diff[RF90_PATH_B][i] = ((tempval>>4)&0xF);
3912 // Read OFDM<->HT tx power diff
3913 if (i < 3) // Cjanel 1-3
3914 tempval = (*(u8 *)&hwinfo[EEPROM_TX_PWR_OFDM_DIFF])&0xff;
3915 else if (i < 9) // Channel 4-9
3916 tempval = (*(u8 *)&hwinfo[EEPROM_PwDiff])&0xff;
3917 else // Channel 10-14
3918 tempval = (*(u8 *)&hwinfo[EEPROM_TX_PWR_OFDM_DIFF+1])&0xff;
3920 //cosa tempval = (*(u1Byte *)&hwinfo[EEPROM_TX_PWR_OFDM_DIFF+index])&0xff;
3921 priv->TxPwrLegacyHtDiff[RF90_PATH_A][i] = (tempval&0xF);
3922 priv->TxPwrLegacyHtDiff[RF90_PATH_B][i] = ((tempval>>4)&0xF);
3925 // Read Band Edge tx power offset and check if user enable the ability
3927 // HT 40 band edge channel
3928 tempval = (*(u8 *)&hwinfo[EEPROM_TX_PWR_BAND_EDGE])&0xff;
3929 priv->TxPwrbandEdgeHt40[RF90_PATH_A][0] = (tempval&0xF); // Band edge low channel
3930 priv->TxPwrbandEdgeHt40[RF90_PATH_A][1] = ((tempval>>4)&0xF); // Band edge high channel
3931 tempval = (*(u8 *)&hwinfo[EEPROM_TX_PWR_BAND_EDGE+1])&0xff;
3932 priv->TxPwrbandEdgeHt40[RF90_PATH_B][0] = (tempval&0xF); // Band edge low channel
3933 priv->TxPwrbandEdgeHt40[RF90_PATH_B][1] = ((tempval>>4)&0xF); // Band edge high channel
3934 // HT 20 band edge channel
3935 tempval = (*(u8 *)&hwinfo[EEPROM_TX_PWR_BAND_EDGE+2])&0xff;
3936 priv->TxPwrbandEdgeHt20[RF90_PATH_A][0] = (tempval&0xF); // Band edge low channel
3937 priv->TxPwrbandEdgeHt20[RF90_PATH_A][1] = ((tempval>>4)&0xF); // Band edge high channel
3938 tempval = (*(u8 *)&hwinfo[EEPROM_TX_PWR_BAND_EDGE+3])&0xff;
3939 priv->TxPwrbandEdgeHt20[RF90_PATH_B][0] = (tempval&0xF); // Band edge low channel
3940 priv->TxPwrbandEdgeHt20[RF90_PATH_B][1] = ((tempval>>4)&0xF); // Band edge high channel
3941 // OFDM band edge channel
3942 tempval = (*(u8 *)&hwinfo[EEPROM_TX_PWR_BAND_EDGE+4])&0xff;
3943 priv->TxPwrbandEdgeLegacyOfdm[RF90_PATH_A][0] = (tempval&0xF); // Band edge low channel
3944 priv->TxPwrbandEdgeLegacyOfdm[RF90_PATH_A][1] = ((tempval>>4)&0xF); // Band edge high channel
3945 tempval = (*(u8 *)&hwinfo[EEPROM_TX_PWR_BAND_EDGE+5])&0xff;
3946 priv->TxPwrbandEdgeLegacyOfdm[RF90_PATH_B][0] = (tempval&0xF); // Band edge low channel
3947 priv->TxPwrbandEdgeLegacyOfdm[RF90_PATH_B][1] = ((tempval>>4)&0xF); // Band edge high channel
3949 priv->TxPwrbandEdgeFlag = (*(u8 *)&hwinfo[TX_PWR_BAND_EDGE_CHK]);
3952 for(i=0; i<14; i++)
3953 RT_TRACE(COMP_INIT, "RF-A Ht20 to HT40 Diff[%d] = 0x%x\n", i, priv->TxPwrHt20Diff[RF90_PATH_A][i]);
3954 for(i=0; i<14; i++)
3955 RT_TRACE(COMP_INIT, "RF-A Legacy to Ht40 Diff[%d] = 0x%x\n", i, priv->TxPwrLegacyHtDiff[RF90_PATH_A][i]);
3956 for(i=0; i<14; i++)
3957 RT_TRACE(COMP_INIT, "RF-B Ht20 to HT40 Diff[%d] = 0x%x\n", i, priv->TxPwrHt20Diff[RF90_PATH_B][i]);
3958 for(i=0; i<14; i++)
3959 RT_TRACE(COMP_INIT, "RF-B Legacy to HT40 Diff[%d] = 0x%x\n", i, priv->TxPwrLegacyHtDiff[RF90_PATH_B][i]);
3960 RT_TRACE(COMP_INIT, "RF-A HT40 band-edge low/high power diff = 0x%x/0x%x\n",
3961 priv->TxPwrbandEdgeHt40[RF90_PATH_A][0],
3962 priv->TxPwrbandEdgeHt40[RF90_PATH_A][1]);
3963 RT_TRACE((COMP_INIT&COMP_DBG), "RF-B HT40 band-edge low/high power diff = 0x%x/0x%x\n",
3964 priv->TxPwrbandEdgeHt40[RF90_PATH_B][0],
3965 priv->TxPwrbandEdgeHt40[RF90_PATH_B][1]);
3967 RT_TRACE((COMP_INIT&COMP_DBG), "RF-A HT20 band-edge low/high power diff = 0x%x/0x%x\n",
3968 priv->TxPwrbandEdgeHt20[RF90_PATH_A][0],
3969 priv->TxPwrbandEdgeHt20[RF90_PATH_A][1]);
3970 RT_TRACE((COMP_INIT&COMP_DBG), "RF-B HT20 band-edge low/high power diff = 0x%x/0x%x\n",
3971 priv->TxPwrbandEdgeHt20[RF90_PATH_B][0],
3972 priv->TxPwrbandEdgeHt20[RF90_PATH_B][1]);
3974 RT_TRACE((COMP_INIT&COMP_DBG), "RF-A OFDM band-edge low/high power diff = 0x%x/0x%x\n",
3975 priv->TxPwrbandEdgeLegacyOfdm[RF90_PATH_A][0],
3976 priv->TxPwrbandEdgeLegacyOfdm[RF90_PATH_A][1]);
3977 RT_TRACE((COMP_INIT&COMP_DBG), "RF-B OFDM band-edge low/high power diff = 0x%x/0x%x\n",
3978 priv->TxPwrbandEdgeLegacyOfdm[RF90_PATH_B][0],
3979 priv->TxPwrbandEdgeLegacyOfdm[RF90_PATH_B][1]);
3980 RT_TRACE((COMP_INIT&COMP_DBG), "Band-edge enable flag = %d\n", priv->TxPwrbandEdgeFlag);
3983 // Update remained HAL variables.
3985 priv->TSSI_13dBm = priv->EEPROMThermalMeter *100;
3986 priv->LegacyHTTxPowerDiff = priv->EEPROMTxPowerDiff;
3987 priv->TxPowerDiff = priv->EEPROMTxPowerDiff;
3988 //priv->AntennaTxPwDiff[0] = (priv->EEPROMTxPowerDiff & 0xf);// Antenna B gain offset to antenna A, bit[3:0]
3989 //priv->AntennaTxPwDiff[1] = ((priv->EEPROMTxPowerDiff & 0xf0)>>4);// Antenna C gain offset to antenna A, bit[7:4]
3990 priv->CrystalCap = priv->EEPROMCrystalCap; // CrystalCap, bit[15:12]
3991 priv->ThermalMeter[0] = (priv->EEPROMThermalMeter&0x1f);// ThermalMeter, bit0~3 for RFIC1, bit4~7 for RFIC2
3992 priv->LedStrategy = SW_LED_MODE0;
3994 init_rate_adaptive(dev);
3996 RT_TRACE(COMP_INIT, "<==== ReadAdapterInfo8192SUsb\n");
3998 //return RT_STATUS_SUCCESS;
4003 // Description:
4004 // Read HW adapter information by E-Fuse or EEPROM according CR9346 reported.
4006 // Assumption:
4007 // 1. CR9346 regiser has verified.
4008 // 2. PASSIVE_LEVEL (USB interface)
4010 // Created by Roger, 2008.10.21.
4012 static void rtl8192SU_read_eeprom_info(struct net_device *dev)
4014 struct r8192_priv *priv = ieee80211_priv(dev);
4015 u8 tmpU1b;
4017 RT_TRACE(COMP_INIT, "====> ReadAdapterInfo8192SUsb\n");
4019 // Retrieve Chip version.
4020 priv->card_8192_version = (VERSION_8192S)((read_nic_dword(dev, PMC_FSM)>>16)&0xF);
4021 RT_TRACE(COMP_INIT, "Chip Version ID: 0x%2x\n", priv->card_8192_version);
4023 tmpU1b = read_nic_byte(dev, EPROM_CMD);//CR9346
4025 // To check system boot selection.
4026 if (tmpU1b & CmdEERPOMSEL)
4028 RT_TRACE(COMP_INIT, "Boot from EEPROM\n");
4029 priv->EepromOrEfuse = TRUE;
4031 else
4033 RT_TRACE(COMP_INIT, "Boot from EFUSE\n");
4034 priv->EepromOrEfuse = FALSE;
4037 // To check autoload success or not.
4038 if (tmpU1b & CmdEEPROM_En)
4040 RT_TRACE(COMP_INIT, "Autoload OK!!\n");
4041 priv->AutoloadFailFlag=FALSE;
4042 rtl8192SU_ReadAdapterInfo8192SUsb(dev);//eeprom or e-fuse
4044 else
4045 { // Auto load fail.
4046 RT_TRACE(COMP_INIT, "AutoLoad Fail reported from CR9346!!\n");
4047 priv->AutoloadFailFlag=TRUE;
4048 rtl8192SU_ConfigAdapterInfo8192SForAutoLoadFail(dev);
4050 //if (IS_BOOT_FROM_EFUSE(Adapter))
4051 if(!priv->EepromOrEfuse)
4053 RT_TRACE(COMP_INIT, "Update shadow map for EFuse future use!!\n");
4054 EFUSE_ShadowMapUpdate(dev);
4057 #ifdef TO_DO_LIST
4058 if((priv->RegChannelPlan >= RT_CHANNEL_DOMAIN_MAX) || (pHalData->EEPROMChannelPlan & EEPROM_CHANNEL_PLAN_BY_HW_MASK))
4060 pMgntInfo->ChannelPlan = HalMapChannelPlan8192S(Adapter, (pHalData->EEPROMChannelPlan & (~(EEPROM_CHANNEL_PLAN_BY_HW_MASK))));
4061 pMgntInfo->bChnlPlanFromHW = (pHalData->EEPROMChannelPlan & EEPROM_CHANNEL_PLAN_BY_HW_MASK) ? TRUE : FALSE; // User cannot change channel plan.
4063 else
4065 pMgntInfo->ChannelPlan = (RT_CHANNEL_DOMAIN)pMgntInfo->RegChannelPlan;
4068 switch(pMgntInfo->ChannelPlan)
4070 case RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN:
4072 PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(pMgntInfo);
4074 pDot11dInfo->bEnabled = TRUE;
4076 RT_TRACE(COMP_INIT, DBG_LOUD, ("ReadAdapterInfo8187(): Enable dot11d when RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN!\n"));
4077 break;
4080 RT_TRACE(COMP_INIT, DBG_LOUD, ("RegChannelPlan(%d) EEPROMChannelPlan(%d)", pMgntInfo->RegChannelPlan, pHalData->EEPROMChannelPlan));
4081 RT_TRACE(COMP_INIT, DBG_LOUD, ("ChannelPlan = %d\n" , pMgntInfo->ChannelPlan));
4083 RT_TRACE(COMP_INIT, DBG_LOUD, ("<==== ReadAdapterInfo8192S\n"));
4084 #endif
4086 RT_TRACE(COMP_INIT, "<==== ReadAdapterInfo8192SUsb\n");
4088 //return RT_STATUS_SUCCESS;
4091 short rtl8192_get_channel_map(struct net_device * dev)
4093 struct r8192_priv *priv = ieee80211_priv(dev);
4094 if(priv->ChannelPlan > COUNTRY_CODE_GLOBAL_DOMAIN){
4095 printk("rtl8180_init:Error channel plan! Set to default.\n");
4096 priv->ChannelPlan= 0;
4098 RT_TRACE(COMP_INIT, "Channel plan is %d\n",priv->ChannelPlan);
4100 rtl819x_set_channel_map(priv->ChannelPlan, priv);
4101 return 0;
4104 short rtl8192_init(struct net_device *dev)
4107 struct r8192_priv *priv = ieee80211_priv(dev);
4109 rtl8192_init_priv_variable(dev);
4110 rtl8192_init_priv_lock(priv);
4111 rtl8192_init_priv_task(dev);
4112 priv->ops->rtl819x_read_eeprom_info(dev);
4113 rtl8192_get_channel_map(dev);
4114 init_hal_dm(dev);
4115 init_timer(&priv->watch_dog_timer);
4116 priv->watch_dog_timer.data = (unsigned long)dev;
4117 priv->watch_dog_timer.function = watch_dog_timer_callback;
4118 return 0;
4121 /******************************************************************************
4122 *function: This function actually only set RRSR, RATR and BW_OPMODE registers
4123 * not to do all the hw config as its name says
4124 * input: net_device dev
4125 * output: none
4126 * return: none
4127 * notice: This part need to modified according to the rate set we filtered
4128 * ****************************************************************************/
4129 void rtl8192_hwconfig(struct net_device* dev)
4131 u32 regRATR = 0, regRRSR = 0;
4132 u8 regBwOpMode = 0, regTmp = 0;
4133 struct r8192_priv *priv = ieee80211_priv(dev);
4135 // Set RRSR, RATR, and BW_OPMODE registers
4137 switch(priv->ieee80211->mode)
4139 case WIRELESS_MODE_B:
4140 regBwOpMode = BW_OPMODE_20MHZ;
4141 regRATR = RATE_ALL_CCK;
4142 regRRSR = RATE_ALL_CCK;
4143 break;
4144 case WIRELESS_MODE_A:
4145 regBwOpMode = BW_OPMODE_5G |BW_OPMODE_20MHZ;
4146 regRATR = RATE_ALL_OFDM_AG;
4147 regRRSR = RATE_ALL_OFDM_AG;
4148 break;
4149 case WIRELESS_MODE_G:
4150 regBwOpMode = BW_OPMODE_20MHZ;
4151 regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
4152 regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
4153 break;
4154 case WIRELESS_MODE_AUTO:
4155 #ifdef TO_DO_LIST
4156 if (Adapter->bInHctTest)
4158 regBwOpMode = BW_OPMODE_20MHZ;
4159 regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
4160 regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
4162 else
4163 #endif
4165 regBwOpMode = BW_OPMODE_20MHZ;
4166 regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
4167 regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
4169 break;
4170 case WIRELESS_MODE_N_24G:
4171 // It support CCK rate by default.
4172 // CCK rate will be filtered out only when associated AP does not support it.
4173 regBwOpMode = BW_OPMODE_20MHZ;
4174 regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
4175 regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
4176 break;
4177 case WIRELESS_MODE_N_5G:
4178 regBwOpMode = BW_OPMODE_5G;
4179 regRATR = RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
4180 regRRSR = RATE_ALL_OFDM_AG;
4181 break;
4184 write_nic_byte(dev, BW_OPMODE, regBwOpMode);
4186 u32 ratr_value = 0;
4187 ratr_value = regRATR;
4188 if (priv->rf_type == RF_1T2R)
4190 ratr_value &= ~(RATE_ALL_OFDM_2SS);
4192 write_nic_dword(dev, RATR0, ratr_value);
4193 write_nic_byte(dev, UFWP, 1);
4195 regTmp = read_nic_byte(dev, 0x313);
4196 regRRSR = ((regTmp) << 24) | (regRRSR & 0x00ffffff);
4197 write_nic_dword(dev, RRSR, regRRSR);
4200 // Set Retry Limit here
4202 write_nic_word(dev, RETRY_LIMIT,
4203 priv->ShortRetryLimit << RETRY_LIMIT_SHORT_SHIFT | \
4204 priv->LongRetryLimit << RETRY_LIMIT_LONG_SHIFT);
4205 // Set Contention Window here
4207 // Set Tx AGC
4209 // Set Tx Antenna including Feedback control
4211 // Set Auto Rate fallback control
4218 // Description:
4219 // Initial HW relted registers.
4221 // Assumption:
4222 // Config RTL8192S USB MAC, we should config MAC before download FW.
4224 // 2008.09.03, Added by Roger.
4226 static void rtl8192SU_MacConfigBeforeFwDownloadASIC(struct net_device *dev)
4228 u8 tmpU1b;// i;
4229 // u16 tmpU2b;
4230 // u32 tmpU4b;
4231 u8 PollingCnt = 20;
4233 RT_TRACE(COMP_INIT, "--->MacConfigBeforeFwDownloadASIC()\n");
4235 //2MAC Initialization for power on sequence, Revised by Roger. 2008.09.03.
4238 //<Roger_Notes> Set control path switch to HW control and reset Digital Core, CPU Core and
4239 // MAC I/O to solve FW download fail when system from resume sate.
4240 // 2008.11.04.
4242 tmpU1b = read_nic_byte(dev, SYS_CLKR+1);
4243 if(tmpU1b & 0x80)
4245 tmpU1b &= 0x3f;
4246 write_nic_byte(dev, SYS_CLKR+1, tmpU1b);
4248 // Clear FW RPWM for FW control LPS. by tynli. 2009.02.23
4249 write_nic_byte(dev, RPWM, 0x0);
4251 tmpU1b = read_nic_byte(dev, SYS_FUNC_EN+1);
4252 tmpU1b &= 0x73;
4253 write_nic_byte(dev, SYS_FUNC_EN+1, tmpU1b);
4254 udelay(1000);
4256 //Revised POS, suggested by SD1 Alex, 2008.09.27.
4257 write_nic_byte(dev, SPS0_CTRL+1, 0x53);
4258 write_nic_byte(dev, SPS0_CTRL, 0x57);
4260 //Enable AFE Macro Block's Bandgap adn Enable AFE Macro Block's Mbias
4261 tmpU1b = read_nic_byte(dev, AFE_MISC);
4262 write_nic_byte(dev, AFE_MISC, (tmpU1b|AFE_BGEN|AFE_MBEN));
4264 //Enable PLL Power (LDOA15V)
4265 tmpU1b = read_nic_byte(dev, LDOA15_CTRL);
4266 write_nic_byte(dev, LDOA15_CTRL, (tmpU1b|LDA15_EN));
4268 //Enable LDOV12D block
4269 tmpU1b = read_nic_byte(dev, LDOV12D_CTRL);
4270 write_nic_byte(dev, LDOV12D_CTRL, (tmpU1b|LDV12_EN));
4272 //mpU1b = read_nic_byte(Adapter, SPS1_CTRL);
4273 //write_nic_byte(dev, SPS1_CTRL, (tmpU1b|SPS1_LDEN));
4275 //PlatformSleepUs(2000);
4277 //Enable Switch Regulator Block
4278 //tmpU1b = read_nic_byte(Adapter, SPS1_CTRL);
4279 //write_nic_byte(dev, SPS1_CTRL, (tmpU1b|SPS1_SWEN));
4281 //write_nic_dword(Adapter, SPS1_CTRL, 0x00a7b267);
4283 tmpU1b = read_nic_byte(dev, SYS_ISO_CTRL+1);
4284 write_nic_byte(dev, SYS_ISO_CTRL+1, (tmpU1b|0x08));
4286 //Engineer Packet CP test Enable
4287 tmpU1b = read_nic_byte(dev, SYS_FUNC_EN+1);
4288 write_nic_byte(dev, SYS_FUNC_EN+1, (tmpU1b|0x20));
4290 //Support 64k IMEM, suggested by SD1 Alex.
4291 tmpU1b = read_nic_byte(dev, SYS_ISO_CTRL+1);
4292 write_nic_byte(dev, SYS_ISO_CTRL+1, (tmpU1b& 0x68));
4294 //Enable AFE clock
4295 tmpU1b = read_nic_byte(dev, AFE_XTAL_CTRL+1);
4296 write_nic_byte(dev, AFE_XTAL_CTRL+1, (tmpU1b& 0xfb));
4298 //Enable AFE PLL Macro Block
4299 tmpU1b = read_nic_byte(dev, AFE_PLL_CTRL);
4300 write_nic_byte(dev, AFE_PLL_CTRL, (tmpU1b|0x11));
4302 //Attatch AFE PLL to MACTOP/BB/PCIe Digital
4303 tmpU1b = read_nic_byte(dev, SYS_ISO_CTRL);
4304 write_nic_byte(dev, SYS_ISO_CTRL, (tmpU1b&0xEE));
4306 // Switch to 40M clock
4307 write_nic_byte(dev, SYS_CLKR, 0x00);
4309 //SSC Disable
4310 tmpU1b = read_nic_byte(dev, SYS_CLKR);
4311 //write_nic_byte(dev, SYS_CLKR, (tmpU1b&0x5f));
4312 write_nic_byte(dev, SYS_CLKR, (tmpU1b|0xa0));
4314 //Enable MAC clock
4315 tmpU1b = read_nic_byte(dev, SYS_CLKR+1);
4316 write_nic_byte(dev, SYS_CLKR+1, (tmpU1b|0x18));
4318 //Revised POS, suggested by SD1 Alex, 2008.09.27.
4319 write_nic_byte(dev, PMC_FSM, 0x02);
4321 //Enable Core digital and enable IOREG R/W
4322 tmpU1b = read_nic_byte(dev, SYS_FUNC_EN+1);
4323 write_nic_byte(dev, SYS_FUNC_EN+1, (tmpU1b|0x08));
4325 //Enable REG_EN
4326 tmpU1b = read_nic_byte(dev, SYS_FUNC_EN+1);
4327 write_nic_byte(dev, SYS_FUNC_EN+1, (tmpU1b|0x80));
4329 //Switch the control path to FW
4330 tmpU1b = read_nic_byte(dev, SYS_CLKR+1);
4331 write_nic_byte(dev, SYS_CLKR+1, (tmpU1b|0x80)& 0xBF);
4333 write_nic_byte(dev, CMDR, 0xFC);
4334 write_nic_byte(dev, CMDR+1, 0x37);
4336 //Fix the RX FIFO issue(usb error), 970410
4337 tmpU1b = read_nic_byte_E(dev, 0x5c);
4338 write_nic_byte_E(dev, 0x5c, (tmpU1b|BIT7));
4340 //For power save, used this in the bit file after 970621
4341 tmpU1b = read_nic_byte(dev, SYS_CLKR);
4342 write_nic_byte(dev, SYS_CLKR, tmpU1b&(~SYS_CPU_CLKSEL));
4344 // Revised for 8051 ROM code wrong operation. Added by Roger. 2008.10.16.
4345 write_nic_byte_E(dev, 0x1c, 0x80);
4348 // <Roger_EXP> To make sure that TxDMA can ready to download FW.
4349 // We should reset TxDMA if IMEM RPT was not ready.
4350 // Suggested by SD1 Alex. 2008.10.23.
4354 tmpU1b = read_nic_byte(dev, TCR);
4355 if((tmpU1b & TXDMA_INIT_VALUE) == TXDMA_INIT_VALUE)
4356 break;
4357 //PlatformStallExecution(5);
4358 udelay(5);
4359 }while(PollingCnt--); // Delay 1ms
4361 if(PollingCnt <= 0 )
4363 RT_TRACE(COMP_INIT, "MacConfigBeforeFwDownloadASIC(): Polling TXDMA_INIT_VALUE timeout!! Current TCR(%#x)\n", tmpU1b);
4364 tmpU1b = read_nic_byte(dev, CMDR);
4365 write_nic_byte(dev, CMDR, tmpU1b&(~TXDMA_EN));
4366 udelay(2);
4367 write_nic_byte(dev, CMDR, tmpU1b|TXDMA_EN);// Reset TxDMA
4371 RT_TRACE(COMP_INIT, "<---MacConfigBeforeFwDownloadASIC()\n");
4375 // Description:
4376 // Initial HW relted registers.
4378 // Assumption:
4379 // 1. This function is only invoked at driver intialization once.
4380 // 2. PASSIVE LEVEL.
4382 // 2008.06.10, Added by Roger.
4384 static void rtl8192SU_MacConfigAfterFwDownload(struct net_device *dev)
4386 struct r8192_priv *priv = ieee80211_priv((struct net_device *)dev);
4387 //PRT_HIGH_THROUGHPUT pHTInfo = priv->ieee80211->pHTInfo;
4388 //u8 tmpU1b, RxPageCfg, i;
4389 u16 tmpU2b;
4390 u8 tmpU1b;//, i;
4393 RT_TRACE(COMP_INIT, "--->MacConfigAfterFwDownload()\n");
4395 // Enable Tx/Rx
4396 tmpU2b = (BBRSTn|BB_GLB_RSTn|SCHEDULE_EN|MACRXEN|MACTXEN|DDMA_EN|
4397 FW2HW_EN|RXDMA_EN|TXDMA_EN|HCI_RXDMA_EN|HCI_TXDMA_EN); //3
4398 //Adapter->HalFunc.SetHwRegHandler( Adapter, HW_VAR_COMMAND, &tmpU1b );
4399 write_nic_word(dev, CMDR, tmpU2b); //LZM REGISTER COM 090305
4401 // Loopback mode or not
4402 priv->LoopbackMode = RTL8192SU_NO_LOOPBACK; // Set no loopback as default.
4403 if(priv->LoopbackMode == RTL8192SU_NO_LOOPBACK)
4404 tmpU1b = LBK_NORMAL;
4405 else if (priv->LoopbackMode == RTL8192SU_MAC_LOOPBACK )
4406 tmpU1b = LBK_MAC_DLB;
4407 else
4408 RT_TRACE(COMP_INIT, "Serious error: wrong loopback mode setting\n");
4410 //Adapter->HalFunc.SetHwRegHandler( Adapter, HW_VAR_LBK_MODE, &tmpU1b);
4411 write_nic_byte(dev, LBKMD_SEL, tmpU1b);
4413 // Set RCR
4414 write_nic_dword(dev, RCR, priv->ReceiveConfig);
4415 RT_TRACE(COMP_INIT, "MacConfigAfterFwDownload(): Current RCR settings(%#x)\n", priv->ReceiveConfig);
4418 // Set RQPN
4420 // <Roger_Notes> 2008.08.18.
4421 // 6 endpoints:
4422 // (1) Page number on CMDQ is 0x03.
4423 // (2) Page number on BCNQ, HQ and MGTQ is 0.
4424 // (3) Page number on BKQ, BEQ, VIQ and VOQ are 0x07.
4425 // (4) Page number on PUBQ is 0xdd
4427 // 11 endpoints:
4428 // (1) Page number on CMDQ is 0x00.
4429 // (2) Page number on BCNQ is 0x02, HQ and MGTQ are 0x03.
4430 // (3) Page number on BKQ, BEQ, VIQ and VOQ are 0x07.
4431 // (4) Page number on PUBQ is 0xd8
4433 //write_nic_dword(Adapter, 0xa0, 0x07070707); //BKQ, BEQ, VIQ and VOQ
4434 //write_nic_byte(dev, 0xa4, 0x00); // HCCAQ
4436 // Fix the RX FIFO issue(USB error), Rivesed by Roger, 2008-06-14
4437 tmpU1b = read_nic_byte_E(dev, 0x5C);
4438 write_nic_byte_E(dev, 0x5C, tmpU1b|BIT7);
4440 // For EFUSE init configuration.
4441 //if (IS_BOOT_FROM_EFUSE(Adapter)) // We may R/W EFUSE in EFUSE mode
4442 if (priv->bBootFromEfuse)
4444 u8 tempval;
4446 tempval = read_nic_byte(dev, SYS_ISO_CTRL+1);
4447 tempval &= 0xFE;
4448 write_nic_byte(dev, SYS_ISO_CTRL+1, tempval);
4450 // Enable LDO 2.5V for write action
4451 //tempval = read_nic_byte(Adapter, EFUSE_TEST+3);
4452 //write_nic_byte(Adapter, EFUSE_TEST+3, (tempval | 0x80));
4454 // Change Efuse Clock for write action
4455 //write_nic_byte(Adapter, EFUSE_CLK, 0x03);
4457 // Change Program timing
4458 write_nic_byte(dev, EFUSE_CTRL+3, 0x72);
4459 //printk("!!!!!!!!!!!!!!!!!!!!!%s: write 0x33 with 0x72\n",__FUNCTION__);
4460 RT_TRACE(COMP_INIT, "EFUSE CONFIG OK\n");
4464 RT_TRACE(COMP_INIT, "<---MacConfigAfterFwDownload()\n");
4467 void rtl8192SU_HwConfigureRTL8192SUsb(struct net_device *dev)
4470 struct r8192_priv *priv = ieee80211_priv(dev);
4471 u8 regBwOpMode = 0;
4472 u32 regRATR = 0, regRRSR = 0;
4473 u8 regTmp = 0;
4474 u32 i = 0;
4476 //1 This part need to modified according to the rate set we filtered!!
4478 // Set RRSR, RATR, and BW_OPMODE registers
4480 switch(priv->ieee80211->mode)
4482 case WIRELESS_MODE_B:
4483 regBwOpMode = BW_OPMODE_20MHZ;
4484 regRATR = RATE_ALL_CCK;
4485 regRRSR = RATE_ALL_CCK;
4486 break;
4487 case WIRELESS_MODE_A:
4488 regBwOpMode = BW_OPMODE_5G |BW_OPMODE_20MHZ;
4489 regRATR = RATE_ALL_OFDM_AG;
4490 regRRSR = RATE_ALL_OFDM_AG;
4491 break;
4492 case WIRELESS_MODE_G:
4493 regBwOpMode = BW_OPMODE_20MHZ;
4494 regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
4495 regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
4496 break;
4497 case WIRELESS_MODE_AUTO:
4498 if (priv->bInHctTest)
4500 regBwOpMode = BW_OPMODE_20MHZ;
4501 regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
4502 regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
4504 else
4506 regBwOpMode = BW_OPMODE_20MHZ;
4507 regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
4508 regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
4510 break;
4511 case WIRELESS_MODE_N_24G:
4512 // It support CCK rate by default.
4513 // CCK rate will be filtered out only when associated AP does not support it.
4514 regBwOpMode = BW_OPMODE_20MHZ;
4515 regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
4516 regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
4517 break;
4518 case WIRELESS_MODE_N_5G:
4519 regBwOpMode = BW_OPMODE_5G;
4520 regRATR = RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
4521 regRRSR = RATE_ALL_OFDM_AG;
4522 break;
4526 // <Roger_Notes> We disable CCK response rate until FIB CCK rate IC's back.
4527 // 2008.09.23.
4529 regTmp = read_nic_byte(dev, INIRTSMCS_SEL);
4530 regRRSR = ((regRRSR & 0x000fffff)<<8) | regTmp;
4533 // Update SIFS timing.
4535 //priv->SifsTime = 0x0e0e0a0a;
4536 //Adapter->HalFunc.SetHwRegHandler( Adapter, HW_VAR_SIFS, (pu1Byte)&pHalData->SifsTime);
4537 { u8 val[4] = {0x0e, 0x0e, 0x0a, 0x0a};
4538 // SIFS for CCK Data ACK
4539 write_nic_byte(dev, SIFS_CCK, val[0]);
4540 // SIFS for CCK consecutive tx like CTS data!
4541 write_nic_byte(dev, SIFS_CCK+1, val[1]);
4543 // SIFS for OFDM Data ACK
4544 write_nic_byte(dev, SIFS_OFDM, val[2]);
4545 // SIFS for OFDM consecutive tx like CTS data!
4546 write_nic_byte(dev, SIFS_OFDM+1, val[3]);
4549 write_nic_dword(dev, INIRTSMCS_SEL, regRRSR);
4550 write_nic_byte(dev, BW_OPMODE, regBwOpMode);
4553 // Suggested by SD1 Alex, 2008-06-14.
4555 //PlatformEFIOWrite1Byte(Adapter, TXOP_STALL_CTRL, 0x80);//NAV to protect all TXOP.
4558 // Set Data Auto Rate Fallback Retry Count register.
4560 write_nic_dword(dev, DARFRC, 0x02010000);
4561 write_nic_dword(dev, DARFRC+4, 0x06050403);
4562 write_nic_dword(dev, RARFRC, 0x02010000);
4563 write_nic_dword(dev, RARFRC+4, 0x06050403);
4565 // Set Data Auto Rate Fallback Reg. Added by Roger, 2008.09.22.
4566 for (i = 0; i < 8; i++)
4567 write_nic_dword(dev, ARFR0+i*4, 0x1f0ffff0);
4570 // Aggregation length limit. Revised by Roger. 2008.09.22.
4572 write_nic_byte(dev, AGGLEN_LMT_H, 0x0f); // Set AMPDU length to 12Kbytes for ShortGI case.
4573 write_nic_dword(dev, AGGLEN_LMT_L, 0xddd77442); // Long GI
4574 write_nic_dword(dev, AGGLEN_LMT_L+4, 0xfffdd772);
4576 // Set NAV protection length
4577 write_nic_word(dev, NAV_PROT_LEN, 0x0080);
4579 // Set TXOP stall control for several queue/HI/BCN/MGT/
4580 write_nic_byte(dev, TXOP_STALL_CTRL, 0x00); // NAV Protect next packet.
4582 // Set MSDU lifetime.
4583 write_nic_byte(dev, MLT, 0x8f);
4585 // Set CCK/OFDM SIFS
4586 write_nic_word(dev, SIFS_CCK, 0x0a0a); // CCK SIFS shall always be 10us.
4587 write_nic_word(dev, SIFS_OFDM, 0x0e0e);
4589 write_nic_byte(dev, ACK_TIMEOUT, 0x40);
4591 // CF-END Threshold
4592 write_nic_byte(dev, CFEND_TH, 0xFF);
4595 // For Min Spacing configuration.
4597 switch(priv->rf_type)
4599 case RF_1T2R:
4600 case RF_1T1R:
4601 RT_TRACE(COMP_INIT, "Initializeadapter: RF_Type%s\n", (priv->rf_type==RF_1T1R? "(1T1R)":"(1T2R)"));
4602 priv->MinSpaceCfg = (MAX_MSS_DENSITY_1T<<3);
4603 break;
4604 case RF_2T2R:
4605 case RF_2T2R_GREEN:
4606 RT_TRACE(COMP_INIT, "Initializeadapter:RF_Type(2T2R)\n");
4607 priv->MinSpaceCfg = (MAX_MSS_DENSITY_2T<<3);
4608 break;
4610 write_nic_byte(dev, AMPDU_MIN_SPACE, priv->MinSpaceCfg);
4612 //LZM 090219
4614 // For Min Spacing configuration.
4616 //priv->MinSpaceCfg = 0x00;
4617 //rtl8192SU_SetHwRegAmpduMinSpace(dev, priv->MinSpaceCfg);
4621 // Description: Initial HW relted registers.
4623 // Assumption: This function is only invoked at driver intialization once.
4625 // 2008.06.10, Added by Roger.
4626 bool rtl8192SU_adapter_start(struct net_device *dev)
4628 struct r8192_priv *priv = ieee80211_priv(dev);
4629 //u32 dwRegRead = 0;
4630 //bool init_status = true;
4631 //u32 ulRegRead;
4632 bool rtStatus = true;
4633 //u8 PipeIndex;
4634 //u8 eRFPath, tmpU1b;
4635 u8 fw_download_times = 1;
4638 RT_TRACE(COMP_INIT, "--->InitializeAdapter8192SUsb()\n");
4640 //pHalData->bGPIOChangeRF = FALSE;
4644 // <Roger_Notes> 2008.06.15.
4646 // Initialization Steps on RTL8192SU:
4647 // a. MAC initialization prior to sending down firmware code.
4648 // b. Download firmware code step by step(i.e., IMEM, EMEM, DMEM).
4649 // c. MAC configuration after firmware has been download successfully.
4650 // d. Initialize BB related configurations.
4651 // e. Initialize RF related configurations.
4652 // f. Start to BulkIn transfer.
4656 //a. MAC initialization prior to send down firmware code.
4658 start:
4659 rtl8192SU_MacConfigBeforeFwDownloadASIC(dev);
4662 //b. Download firmware code step by step(i.e., IMEM, EMEM, DMEM).
4664 rtStatus = FirmwareDownload92S(dev);
4665 if(rtStatus != true)
4667 if(fw_download_times == 1){
4668 RT_TRACE(COMP_INIT, "InitializeAdapter8192SUsb(): Download Firmware failed once, Download again!!\n");
4669 fw_download_times = fw_download_times + 1;
4670 goto start;
4671 }else{
4672 RT_TRACE(COMP_INIT, "InitializeAdapter8192SUsb(): Download Firmware failed twice, end!!\n");
4673 goto end;
4677 //c. MAC configuration after firmware has been download successfully.
4679 rtl8192SU_MacConfigAfterFwDownload(dev);
4681 //priv->bLbusEnable = TRUE;
4682 //if(priv->RegRfOff == TRUE)
4683 // priv->eRFPowerState = eRfOff;
4685 // Save target channel
4686 // <Roger_Notes> Current Channel will be updated again later.
4687 //priv->CurrentChannel = Channel;
4688 rtStatus = PHY_MACConfig8192S(dev);//===>ok
4689 if(rtStatus != true)
4691 RT_TRACE(COMP_INIT, "InitializeAdapter8192SUsb(): Fail to configure MAC!!\n");
4692 goto end;
4694 if (1){
4695 int i;
4696 for (i=0; i<4; i++)
4697 write_nic_dword(dev,WDCAPARA_ADD[i], 0x5e4322);
4698 write_nic_byte(dev,AcmHwCtrl, 0x01);
4703 //d. Initialize BB related configurations.
4706 rtStatus = PHY_BBConfig8192S(dev);//===>ok
4707 if(rtStatus != true)
4709 RT_TRACE(COMP_INIT, "InitializeAdapter8192SUsb(): Fail to configure BB!!\n");
4710 goto end;
4713 rtl8192_setBBreg(dev, rFPGA0_AnalogParameter2, 0xff, 0x58);//===>ok
4716 // e. Initialize RF related configurations.
4718 // 2007/11/02 MH Before initalizing RF. We can not use FW to do RF-R/W.
4719 priv->Rf_Mode = RF_OP_By_SW_3wire;
4721 // For RF test only from Scott's suggestion
4722 //write_nic_byte(dev, 0x27, 0xDB);
4723 //write_nic_byte(dev, 0x1B, 0x07);
4726 write_nic_byte(dev, AFE_XTAL_CTRL+1, 0xDB);
4728 // <Roger_Notes> The following IOs are configured for each RF modules.
4729 // Enable RF module and reset RF and SDM module. 2008.11.17.
4730 if(priv->card_8192_version == VERSION_8192S_ACUT)
4731 write_nic_byte(dev, SPS1_CTRL+3, (u8)(RF_EN|RF_RSTB|RF_SDMRSTB)); // Fix A-Cut bug.
4732 else
4733 write_nic_byte(dev, RF_CTRL, (u8)(RF_EN|RF_RSTB|RF_SDMRSTB));
4735 rtStatus = PHY_RFConfig8192S(dev);//===>ok
4736 if(rtStatus != true)
4738 RT_TRACE(COMP_INIT, "InitializeAdapter8192SUsb(): Fail to configure RF!!\n");
4739 goto end;
4743 // Set CCK and OFDM Block "ON"
4744 rtl8192_setBBreg(dev, rFPGA0_RFMOD, bCCKEn, 0x1);
4745 rtl8192_setBBreg(dev, rFPGA0_RFMOD, bOFDMEn, 0x1);
4748 // Turn off Radio B while RF type is 1T1R by SD3 Wilsion's request.
4749 // Revised by Roger, 2008.12.18.
4751 if(priv->rf_type == RF_1T1R)
4753 // This is needed for PHY_REG after 20081219
4754 rtl8192_setBBreg(dev, rFPGA0_RFMOD, 0xff000000, 0x03);
4755 // This is needed for PHY_REG before 20081219
4756 //PHY_SetBBReg(Adapter, rOFDM0_TRxPathEnable, bMaskByte0, 0x11);
4760 //LZM 090219
4761 // Set CCK and OFDM Block "ON"
4762 //rtl8192_setBBreg(dev, rFPGA0_RFMOD, bCCKEn, 0x1);
4763 //rtl8192_setBBreg(dev, rFPGA0_RFMOD, bOFDMEn, 0x1);
4766 //3//Get hardware version, do it in read eeprom?
4767 //GetHardwareVersion819xUsb(Adapter);
4769 //3//
4770 //3 //Set Hardware
4771 //3//
4772 rtl8192SU_HwConfigureRTL8192SUsb(dev);//==>ok
4775 // <Roger_Notes> We set MAC address here if autoload was failed before,
4776 // otherwise IDR0 will NOT contain any value.
4778 write_nic_dword(dev, IDR0, ((u32*)dev->dev_addr)[0]);
4779 write_nic_word(dev, IDR4, ((u16*)(dev->dev_addr + 4))[0]);
4780 if(!priv->bInHctTest)
4782 if(priv->ResetProgress == RESET_TYPE_NORESET)
4784 //RT_TRACE(COMP_MLME, DBG_LOUD, ("Initializeadapter8192SUsb():RegWirelessMode(%#x) \n", Adapter->RegWirelessMode));
4785 //Adapter->HalFunc.SetWirelessModeHandler(Adapter, Adapter->RegWirelessMode);
4786 rtl8192_SetWirelessMode(dev, priv->ieee80211->mode);//===>ok
4789 else
4791 priv->ieee80211->mode = WIRELESS_MODE_G;
4792 rtl8192_SetWirelessMode(dev, WIRELESS_MODE_G);
4795 //Security related.
4796 //-----------------------------------------------------------------------------
4797 // Set up security related. 070106, by rcnjko:
4798 // 1. Clear all H/W keys.
4799 // 2. Enable H/W encryption/decryption.
4800 //-----------------------------------------------------------------------------
4801 //CamResetAllEntry(Adapter);
4802 //Adapter->HalFunc.EnableHWSecCfgHandler(Adapter);
4804 //SecClearAllKeys(Adapter);
4805 CamResetAllEntry(dev);
4806 //SecInit(Adapter);
4808 u8 SECR_value = 0x0;
4809 SECR_value |= SCR_TxEncEnable;
4810 SECR_value |= SCR_RxDecEnable;
4811 SECR_value |= SCR_NoSKMC;
4812 write_nic_byte(dev, SECR, SECR_value);
4815 #ifdef TO_DO_LIST
4817 //PHY_UpdateInitialGain(dev);
4819 if(priv->RegRfOff == true)
4820 { // User disable RF via registry.
4821 u8 eRFPath = 0;
4823 RT_TRACE((COMP_INIT|COMP_RF), "InitializeAdapter8192SUsb(): Turn off RF for RegRfOff ----------\n");
4824 MgntActSet_RF_State(dev, eRfOff, RF_CHANGE_BY_SW);
4825 // Those action will be discard in MgntActSet_RF_State because off the same state
4826 for(eRFPath = 0; eRFPath <priv->NumTotalRFPath; eRFPath++)
4827 rtl8192_setBBreg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x4, 0xC00, 0x0);
4829 else if(priv->RfOffReason > RF_CHANGE_BY_PS)
4830 { // H/W or S/W RF OFF before sleep.
4831 RT_TRACE((COMP_INIT|COMP_RF), "InitializeAdapter8192SUsb(): Turn off RF for RfOffReason(%d) ----------\n", priv->RfOffReason);
4832 MgntActSet_RF_State(dev, eRfOff, priv->RfOffReason);
4834 else
4836 priv->eRFPowerState = eRfOn;
4837 priv->RfOffReason = 0;
4838 RT_TRACE((COMP_INIT|COMP_RF), "InitializeAdapter8192SUsb(): RF is on ----------\n");
4841 #endif
4845 // f. Start to BulkIn transfer.
4847 #ifdef TO_DO_LIST
4849 #ifndef UNDER_VISTA
4851 u8 i;
4852 PlatformAcquireSpinLock(Adapter, RT_RX_SPINLOCK);
4854 for(PipeIndex=0; PipeIndex < MAX_RX_QUEUE; PipeIndex++)
4856 if (PipeIndex == 0)
4858 for(i=0; i<32; i++)
4859 HalUsbInMpdu(Adapter, PipeIndex);
4861 else
4863 //HalUsbInMpdu(Adapter, PipeIndex);
4864 //HalUsbInMpdu(Adapter, PipeIndex);
4865 //HalUsbInMpdu(Adapter, PipeIndex);
4868 PlatformReleaseSpinLock(Adapter, RT_RX_SPINLOCK);
4870 #else
4871 // Joseph add to 819X code base for Vista USB platform.
4872 // This part may need to be add to Hal819xU code base. too.
4873 PlatformUsbEnableInPipes(Adapter);
4874 #endif
4876 RT_TRACE(COMP_INIT, "HighestOperaRate = %x\n", Adapter->MgntInfo.HighestOperaRate);
4878 PlatformStartWorkItem( &(pHalData->RtUsbCheckForHangWorkItem) );
4881 // <Roger_EXP> The following configurations are for ASIC verification temporally.
4882 // 2008.07.10.
4885 #endif
4888 // Read EEPROM TX power index and PHY_REG_PG.txt to capture correct
4889 // TX power index for different rate set.
4891 //if(priv->card_8192_version >= VERSION_8192S_ACUT)
4893 // Get original hw reg values
4894 PHY_GetHWRegOriginalValue(dev);
4896 // Write correct tx power index//FIXLZM
4897 PHY_SetTxPowerLevel8192S(dev, priv->chan);
4901 u8 tmpU1b = 0;
4902 // EEPROM R/W workaround
4903 tmpU1b = read_nic_byte(dev, MAC_PINMUX_CFG);
4904 write_nic_byte(dev, MAC_PINMUX_CFG, tmpU1b&(~GPIOMUX_EN));
4908 //<Roger_Notes> 2008.08.19.
4909 // We return status here for temporal FPGA verification, 2008.08.19.
4911 #ifdef RTL8192SU_FW_IQK
4912 write_nic_dword(dev, WFM5, FW_IQK_ENABLE);
4913 ChkFwCmdIoDone(dev);
4914 #endif
4917 // <Roger_Notes> We enable high power mechanism after NIC initialized.
4918 // 2008.11.27.
4920 write_nic_dword(dev, WFM5, FW_RA_RESET);
4921 ChkFwCmdIoDone(dev);
4922 write_nic_dword(dev, WFM5, FW_RA_ACTIVE);
4923 ChkFwCmdIoDone(dev);
4924 write_nic_dword(dev, WFM5, FW_RA_REFRESH);
4925 ChkFwCmdIoDone(dev);
4926 write_nic_dword(dev, WFM5, FW_BB_RESET_ENABLE);
4928 // <Roger_Notes> We return status here for temporal FPGA verification. 2008.05.12.
4931 end:
4932 return rtStatus;
4935 /***************************************************************************
4936 -------------------------------NET STUFF---------------------------
4937 ***************************************************************************/
4939 static struct net_device_stats *rtl8192_stats(struct net_device *dev)
4941 struct r8192_priv *priv = ieee80211_priv(dev);
4943 return &priv->ieee80211->stats;
4946 bool
4947 HalTxCheckStuck819xUsb(
4948 struct net_device *dev
4951 struct r8192_priv *priv = ieee80211_priv(dev);
4952 u16 RegTxCounter = read_nic_word(dev, 0x128);
4953 bool bStuck = FALSE;
4954 RT_TRACE(COMP_RESET,"%s():RegTxCounter is %d,TxCounter is %d\n",__FUNCTION__,RegTxCounter,priv->TxCounter);
4955 if(priv->TxCounter==RegTxCounter)
4956 bStuck = TRUE;
4958 priv->TxCounter = RegTxCounter;
4960 return bStuck;
4964 * <Assumption: RT_TX_SPINLOCK is acquired.>
4965 * First added: 2006.11.19 by emily
4967 RESET_TYPE
4968 TxCheckStuck(struct net_device *dev)
4970 struct r8192_priv *priv = ieee80211_priv(dev);
4971 u8 QueueID;
4972 // PRT_TCB pTcb;
4973 // u8 ResetThreshold;
4974 bool bCheckFwTxCnt = false;
4975 //unsigned long flags;
4978 // Decide Stuch threshold according to current power save mode
4981 // RT_TRACE(COMP_RESET, " ==> TxCheckStuck()\n");
4982 // PlatformAcquireSpinLock(Adapter, RT_TX_SPINLOCK);
4983 // spin_lock_irqsave(&priv->ieee80211->lock,flags);
4984 for (QueueID = 0; QueueID<=BEACON_QUEUE;QueueID ++)
4986 if(QueueID == TXCMD_QUEUE)
4987 continue;
4988 #if 1
4989 if((skb_queue_len(&priv->ieee80211->skb_waitQ[QueueID]) == 0) && (skb_queue_len(&priv->ieee80211->skb_aggQ[QueueID]) == 0))
4990 continue;
4991 #endif
4993 bCheckFwTxCnt = true;
4995 // PlatformReleaseSpinLock(Adapter, RT_TX_SPINLOCK);
4996 // spin_unlock_irqrestore(&priv->ieee80211->lock,flags);
4997 // RT_TRACE(COMP_RESET,"bCheckFwTxCnt is %d\n",bCheckFwTxCnt);
4998 #if 1
4999 if(bCheckFwTxCnt)
5001 if(HalTxCheckStuck819xUsb(dev))
5003 RT_TRACE(COMP_RESET, "TxCheckStuck(): Fw indicates no Tx condition! \n");
5004 return RESET_TYPE_SILENT;
5007 #endif
5008 return RESET_TYPE_NORESET;
5011 bool
5012 HalRxCheckStuck819xUsb(struct net_device *dev)
5014 u16 RegRxCounter = read_nic_word(dev, 0x130);
5015 struct r8192_priv *priv = ieee80211_priv(dev);
5016 bool bStuck = FALSE;
5017 //#ifdef RTL8192SU
5019 //#else
5020 static u8 rx_chk_cnt = 0;
5021 RT_TRACE(COMP_RESET,"%s(): RegRxCounter is %d,RxCounter is %d\n",__FUNCTION__,RegRxCounter,priv->RxCounter);
5022 // If rssi is small, we should check rx for long time because of bad rx.
5023 // or maybe it will continuous silent reset every 2 seconds.
5024 rx_chk_cnt++;
5025 if(priv->undecorated_smoothed_pwdb >= (RateAdaptiveTH_High+5))
5027 rx_chk_cnt = 0; //high rssi, check rx stuck right now.
5029 else if(priv->undecorated_smoothed_pwdb < (RateAdaptiveTH_High+5) &&
5030 ((priv->CurrentChannelBW!=HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb>=RateAdaptiveTH_Low_40M) ||
5031 (priv->CurrentChannelBW==HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb>=RateAdaptiveTH_Low_20M)) )
5033 if(rx_chk_cnt < 2)
5035 return bStuck;
5037 else
5039 rx_chk_cnt = 0;
5042 else if(((priv->CurrentChannelBW!=HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb<RateAdaptiveTH_Low_40M) ||
5043 (priv->CurrentChannelBW==HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb<RateAdaptiveTH_Low_20M)) &&
5044 priv->undecorated_smoothed_pwdb >= VeryLowRSSI)
5046 if(rx_chk_cnt < 4)
5048 //DbgPrint("RSSI < %d && RSSI >= %d, no check this time \n", RateAdaptiveTH_Low, VeryLowRSSI);
5049 return bStuck;
5051 else
5053 rx_chk_cnt = 0;
5054 //DbgPrint("RSSI < %d && RSSI >= %d, check this time \n", RateAdaptiveTH_Low, VeryLowRSSI);
5057 else
5059 if(rx_chk_cnt < 8)
5061 //DbgPrint("RSSI <= %d, no check this time \n", VeryLowRSSI);
5062 return bStuck;
5064 else
5066 rx_chk_cnt = 0;
5067 //DbgPrint("RSSI <= %d, check this time \n", VeryLowRSSI);
5070 //#endif
5072 if(priv->RxCounter==RegRxCounter)
5073 bStuck = TRUE;
5075 priv->RxCounter = RegRxCounter;
5077 return bStuck;
5080 RESET_TYPE
5081 RxCheckStuck(struct net_device *dev)
5083 struct r8192_priv *priv = ieee80211_priv(dev);
5084 //int i;
5085 bool bRxCheck = FALSE;
5087 // RT_TRACE(COMP_RESET," ==> RxCheckStuck()\n");
5088 //PlatformAcquireSpinLock(Adapter, RT_RX_SPINLOCK);
5090 if(priv->IrpPendingCount > 1)
5091 bRxCheck = TRUE;
5092 //PlatformReleaseSpinLock(Adapter, RT_RX_SPINLOCK);
5094 // RT_TRACE(COMP_RESET,"bRxCheck is %d \n",bRxCheck);
5095 if(bRxCheck)
5097 if(HalRxCheckStuck819xUsb(dev))
5099 RT_TRACE(COMP_RESET, "RxStuck Condition\n");
5100 return RESET_TYPE_SILENT;
5103 return RESET_TYPE_NORESET;
5108 * This function is called by Checkforhang to check whether we should ask OS to reset driver
5110 * \param pAdapter The adapter context for this miniport
5112 * Note:NIC with USB interface sholud not call this function because we cannot scan descriptor
5113 * to judge whether there is tx stuck.
5114 * Note: This function may be required to be rewrite for Vista OS.
5115 * <<<Assumption: Tx spinlock has been acquired >>>
5117 * 8185 and 8185b does not implement this function. This is added by Emily at 2006.11.24
5119 RESET_TYPE
5120 rtl819x_ifcheck_resetornot(struct net_device *dev)
5122 struct r8192_priv *priv = ieee80211_priv(dev);
5123 RESET_TYPE TxResetType = RESET_TYPE_NORESET;
5124 RESET_TYPE RxResetType = RESET_TYPE_NORESET;
5125 RT_RF_POWER_STATE rfState;
5127 return RESET_TYPE_NORESET;
5129 rfState = priv->ieee80211->eRFPowerState;
5131 TxResetType = TxCheckStuck(dev);
5132 #if 1
5133 if( rfState != eRfOff ||
5134 /*ADAPTER_TEST_STATUS_FLAG(Adapter, ADAPTER_STATUS_FW_DOWNLOAD_FAILURE)) &&*/
5135 (priv->ieee80211->iw_mode != IW_MODE_ADHOC))
5137 // If driver is in the status of firmware download failure , driver skips RF initialization and RF is
5138 // in turned off state. Driver should check whether Rx stuck and do silent reset. And
5139 // if driver is in firmware download failure status, driver should initialize RF in the following
5140 // silent reset procedure Emily, 2008.01.21
5142 // Driver should not check RX stuck in IBSS mode because it is required to
5143 // set Check BSSID in order to send beacon, however, if check BSSID is
5144 // set, STA cannot hear any packet a all. Emily, 2008.04.12
5145 RxResetType = RxCheckStuck(dev);
5147 #endif
5148 if(TxResetType==RESET_TYPE_NORMAL || RxResetType==RESET_TYPE_NORMAL)
5149 return RESET_TYPE_NORMAL;
5150 else if(TxResetType==RESET_TYPE_SILENT || RxResetType==RESET_TYPE_SILENT){
5151 RT_TRACE(COMP_RESET,"%s():silent reset\n",__FUNCTION__);
5152 return RESET_TYPE_SILENT;
5154 else
5155 return RESET_TYPE_NORESET;
5159 void rtl8192_cancel_deferred_work(struct r8192_priv* priv);
5160 int _rtl8192_up(struct net_device *dev);
5161 int rtl8192_close(struct net_device *dev);
5165 void
5166 CamRestoreAllEntry( struct net_device *dev)
5168 u8 EntryId = 0;
5169 struct r8192_priv *priv = ieee80211_priv(dev);
5170 u8* MacAddr = priv->ieee80211->current_network.bssid;
5172 static u8 CAM_CONST_ADDR[4][6] = {
5173 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
5174 {0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
5175 {0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
5176 {0x00, 0x00, 0x00, 0x00, 0x00, 0x03}};
5177 static u8 CAM_CONST_BROAD[] =
5178 {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
5180 RT_TRACE(COMP_SEC, "CamRestoreAllEntry: \n");
5183 if ((priv->ieee80211->pairwise_key_type == KEY_TYPE_WEP40)||
5184 (priv->ieee80211->pairwise_key_type == KEY_TYPE_WEP104))
5187 for(EntryId=0; EntryId<4; EntryId++)
5190 MacAddr = CAM_CONST_ADDR[EntryId];
5191 setKey(dev,
5192 EntryId ,
5193 EntryId,
5194 priv->ieee80211->pairwise_key_type,
5195 MacAddr,
5197 NULL);
5202 else if(priv->ieee80211->pairwise_key_type == KEY_TYPE_TKIP)
5206 if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
5207 setKey(dev,
5210 priv->ieee80211->pairwise_key_type,
5211 (u8*)dev->dev_addr,
5213 NULL);
5214 else
5215 setKey(dev,
5218 priv->ieee80211->pairwise_key_type,
5219 MacAddr,
5221 NULL);
5224 else if(priv->ieee80211->pairwise_key_type == KEY_TYPE_CCMP)
5228 if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
5229 setKey(dev,
5232 priv->ieee80211->pairwise_key_type,
5233 (u8*)dev->dev_addr,
5235 NULL);
5236 else
5237 setKey(dev,
5240 priv->ieee80211->pairwise_key_type,
5241 MacAddr,
5243 NULL);
5249 if(priv->ieee80211->group_key_type == KEY_TYPE_TKIP)
5251 MacAddr = CAM_CONST_BROAD;
5252 for(EntryId=1 ; EntryId<4 ; EntryId++)
5255 setKey(dev,
5256 EntryId,
5257 EntryId,
5258 priv->ieee80211->group_key_type,
5259 MacAddr,
5261 NULL);
5264 if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
5265 setKey(dev,
5268 priv->ieee80211->group_key_type,
5269 CAM_CONST_ADDR[0],
5271 NULL);
5273 else if(priv->ieee80211->group_key_type == KEY_TYPE_CCMP)
5275 MacAddr = CAM_CONST_BROAD;
5276 for(EntryId=1; EntryId<4 ; EntryId++)
5279 setKey(dev,
5280 EntryId ,
5281 EntryId,
5282 priv->ieee80211->group_key_type,
5283 MacAddr,
5285 NULL);
5289 if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
5290 setKey(dev,
5293 priv->ieee80211->group_key_type,
5294 CAM_CONST_ADDR[0],
5296 NULL);
5299 //////////////////////////////////////////////////////////////
5300 // This function is used to fix Tx/Rx stop bug temporarily.
5301 // This function will do "system reset" to NIC when Tx or Rx is stuck.
5302 // The method checking Tx/Rx stuck of this function is supported by FW,
5303 // which reports Tx and Rx counter to register 0x128 and 0x130.
5304 //////////////////////////////////////////////////////////////
5305 void
5306 rtl819x_ifsilentreset(struct net_device *dev)
5308 //OCTET_STRING asocpdu;
5309 struct r8192_priv *priv = ieee80211_priv(dev);
5310 u8 reset_times = 0;
5311 int reset_status = 0;
5312 struct ieee80211_device *ieee = priv->ieee80211;
5315 // 2007.07.20. If we need to check CCK stop, please uncomment this line.
5316 //bStuck = Adapter->HalFunc.CheckHWStopHandler(Adapter);
5318 if(priv->ResetProgress==RESET_TYPE_NORESET)
5320 RESET_START:
5322 RT_TRACE(COMP_RESET,"=========>Reset progress!! \n");
5324 // Set the variable for reset.
5325 priv->ResetProgress = RESET_TYPE_SILENT;
5326 // rtl8192_close(dev);
5327 #if 1
5328 down(&priv->wx_sem);
5329 if(priv->up == 0)
5331 RT_TRACE(COMP_ERR,"%s():the driver is not up! return\n",__FUNCTION__);
5332 up(&priv->wx_sem);
5333 return ;
5335 priv->up = 0;
5336 RT_TRACE(COMP_RESET,"%s():======>start to down the driver\n",__FUNCTION__);
5337 // if(!netif_queue_stopped(dev))
5338 // netif_stop_queue(dev);
5340 rtl8192_rtx_disable(dev);
5341 rtl8192_cancel_deferred_work(priv);
5342 deinit_hal_dm(dev);
5343 del_timer_sync(&priv->watch_dog_timer);
5345 ieee->sync_scan_hurryup = 1;
5346 if(ieee->state == IEEE80211_LINKED)
5348 down(&ieee->wx_sem);
5349 printk("ieee->state is IEEE80211_LINKED\n");
5350 ieee80211_stop_send_beacons(priv->ieee80211);
5351 del_timer_sync(&ieee->associate_timer);
5352 cancel_delayed_work(&ieee->associate_retry_wq);
5353 ieee80211_stop_scan(ieee);
5354 netif_carrier_off(dev);
5355 up(&ieee->wx_sem);
5357 else{
5358 printk("ieee->state is NOT LINKED\n");
5359 ieee80211_softmac_stop_protocol(priv->ieee80211); }
5360 up(&priv->wx_sem);
5361 RT_TRACE(COMP_RESET,"%s():<==========down process is finished\n",__FUNCTION__);
5362 //rtl8192_irq_disable(dev);
5363 RT_TRACE(COMP_RESET,"%s():===========>start to up the driver\n",__FUNCTION__);
5364 reset_status = _rtl8192_up(dev);
5366 RT_TRACE(COMP_RESET,"%s():<===========up process is finished\n",__FUNCTION__);
5367 if(reset_status == -EAGAIN)
5369 if(reset_times < 3)
5371 reset_times++;
5372 goto RESET_START;
5374 else
5376 RT_TRACE(COMP_ERR," ERR!!! %s(): Reset Failed!!\n", __FUNCTION__);
5379 #endif
5380 ieee->is_silent_reset = 1;
5381 #if 1
5382 EnableHWSecurityConfig8192(dev);
5383 #if 1
5384 if(ieee->state == IEEE80211_LINKED && ieee->iw_mode == IW_MODE_INFRA)
5386 ieee->set_chan(ieee->dev, ieee->current_network.channel);
5388 #if 1
5389 queue_work(ieee->wq, &ieee->associate_complete_wq);
5390 #endif
5393 else if(ieee->state == IEEE80211_LINKED && ieee->iw_mode == IW_MODE_ADHOC)
5395 ieee->set_chan(ieee->dev, ieee->current_network.channel);
5396 ieee->link_change(ieee->dev);
5398 // notify_wx_assoc_event(ieee);
5400 ieee80211_start_send_beacons(ieee);
5402 if (ieee->data_hard_resume)
5403 ieee->data_hard_resume(ieee->dev);
5404 netif_carrier_on(ieee->dev);
5406 #endif
5408 CamRestoreAllEntry(dev);
5410 priv->ResetProgress = RESET_TYPE_NORESET;
5411 priv->reset_count++;
5413 priv->bForcedSilentReset =false;
5414 priv->bResetInProgress = false;
5416 // For test --> force write UFWP.
5417 write_nic_byte(dev, UFWP, 1);
5418 RT_TRACE(COMP_RESET, "Reset finished!! ====>[%d]\n", priv->reset_count);
5419 #endif
5423 void CAM_read_entry(
5424 struct net_device *dev,
5425 u32 iIndex
5428 u32 target_command=0;
5429 u32 target_content=0;
5430 u8 entry_i=0;
5431 u32 ulStatus;
5432 s32 i=100;
5433 // printk("=======>start read CAM\n");
5434 for(entry_i=0;entry_i<CAM_CONTENT_COUNT;entry_i++)
5436 // polling bit, and No Write enable, and address
5437 target_command= entry_i+CAM_CONTENT_COUNT*iIndex;
5438 target_command= target_command | BIT31;
5440 //Check polling bit is clear
5441 // mdelay(1);
5442 #if 1
5443 while((i--)>=0)
5445 ulStatus = read_nic_dword(dev, RWCAM);
5446 if(ulStatus & BIT31){
5447 continue;
5449 else{
5450 break;
5453 #endif
5454 write_nic_dword(dev, RWCAM, target_command);
5455 RT_TRACE(COMP_SEC,"CAM_read_entry(): WRITE A0: %x \n",target_command);
5456 // printk("CAM_read_entry(): WRITE A0: %lx \n",target_command);
5457 target_content = read_nic_dword(dev, RCAMO);
5458 RT_TRACE(COMP_SEC, "CAM_read_entry(): WRITE A8: %x \n",target_content);
5459 // printk("CAM_read_entry(): WRITE A8: %lx \n",target_content);
5461 printk("\n");
5464 void rtl819x_update_rxcounts(
5465 struct r8192_priv *priv,
5466 u32* TotalRxBcnNum,
5467 u32* TotalRxDataNum
5470 u16 SlotIndex;
5471 u8 i;
5473 *TotalRxBcnNum = 0;
5474 *TotalRxDataNum = 0;
5476 SlotIndex = (priv->ieee80211->LinkDetectInfo.SlotIndex++)%(priv->ieee80211->LinkDetectInfo.SlotNum);
5477 priv->ieee80211->LinkDetectInfo.RxBcnNum[SlotIndex] = priv->ieee80211->LinkDetectInfo.NumRecvBcnInPeriod;
5478 priv->ieee80211->LinkDetectInfo.RxDataNum[SlotIndex] = priv->ieee80211->LinkDetectInfo.NumRecvDataInPeriod;
5479 for( i=0; i<priv->ieee80211->LinkDetectInfo.SlotNum; i++ ){
5480 *TotalRxBcnNum += priv->ieee80211->LinkDetectInfo.RxBcnNum[i];
5481 *TotalRxDataNum += priv->ieee80211->LinkDetectInfo.RxDataNum[i];
5485 void rtl819x_watchdog_wqcallback(struct work_struct *work)
5487 struct delayed_work *dwork = container_of(work,
5488 struct delayed_work,
5489 work);
5490 struct r8192_priv *priv = container_of(dwork,
5491 struct r8192_priv,
5492 watch_dog_wq);
5493 struct net_device *dev = priv->ieee80211->dev;
5494 struct ieee80211_device* ieee = priv->ieee80211;
5495 RESET_TYPE ResetType = RESET_TYPE_NORESET;
5496 static u8 check_reset_cnt;
5497 u32 TotalRxBcnNum = 0;
5498 u32 TotalRxDataNum = 0;
5499 bool bBusyTraffic = false;
5501 if(!priv->up)
5502 return;
5503 hal_dm_watchdog(dev);
5504 /* to get busy traffic condition */
5505 if (ieee->state == IEEE80211_LINKED) {
5506 if (ieee->LinkDetectInfo.NumRxOkInPeriod > 666 ||
5507 ieee->LinkDetectInfo.NumTxOkInPeriod > 666)
5508 bBusyTraffic = true;
5510 ieee->LinkDetectInfo.NumRxOkInPeriod = 0;
5511 ieee->LinkDetectInfo.NumTxOkInPeriod = 0;
5512 ieee->LinkDetectInfo.bBusyTraffic = bBusyTraffic;
5515 if (priv->ieee80211->state == IEEE80211_LINKED &&
5516 priv->ieee80211->iw_mode == IW_MODE_INFRA) {
5517 rtl819x_update_rxcounts(priv, &TotalRxBcnNum, &TotalRxDataNum);
5518 if ((TotalRxBcnNum + TotalRxDataNum) == 0) {
5519 RT_TRACE(COMP_ERR, "%s(): AP is powered off,"
5520 "connect another one\n", __func__);
5521 /* Dot11d_Reset(dev); */
5522 priv->ieee80211->state = IEEE80211_ASSOCIATING;
5523 notify_wx_assoc_event(priv->ieee80211);
5524 RemovePeerTS(priv->ieee80211,
5525 priv->ieee80211->current_network.bssid);
5526 ieee->is_roaming = true;
5527 priv->ieee80211->link_change(dev);
5528 if(ieee->LedControlHandler != NULL)
5529 ieee->LedControlHandler(ieee->dev,
5530 LED_CTL_START_TO_LINK);
5531 queue_work(priv->ieee80211->wq,
5532 &priv->ieee80211->associate_procedure_wq);
5535 priv->ieee80211->LinkDetectInfo.NumRecvBcnInPeriod = 0;
5536 priv->ieee80211->LinkDetectInfo.NumRecvDataInPeriod = 0;
5539 * CAM_read_entry(dev,4);
5540 * check if reset the driver
5542 if (check_reset_cnt++ >= 3 && !ieee->is_roaming) {
5543 ResetType = rtl819x_ifcheck_resetornot(dev);
5544 check_reset_cnt = 3;
5546 if ((priv->force_reset) || (priv->ResetProgress == RESET_TYPE_NORESET &&
5547 (priv->bForcedSilentReset ||
5548 (!priv->bDisableNormalResetCheck &&
5549 /* This is control by OID set in Pomelo */
5550 ResetType == RESET_TYPE_SILENT)))) {
5551 RT_TRACE(COMP_RESET, "%s(): priv->force_reset is %d,"
5552 "priv->ResetProgress is %d, "
5553 "priv->bForcedSilentReset is %d, "
5554 "priv->bDisableNormalResetCheck is %d, "
5555 "ResetType is %d",
5556 __func__,
5557 priv->force_reset,
5558 priv->ResetProgress,
5559 priv->bForcedSilentReset,
5560 priv->bDisableNormalResetCheck,
5561 ResetType);
5562 rtl819x_ifsilentreset(dev);
5564 priv->force_reset = false;
5565 priv->bForcedSilentReset = false;
5566 priv->bResetInProgress = false;
5569 void watch_dog_timer_callback(unsigned long data)
5571 struct r8192_priv *priv = ieee80211_priv((struct net_device *) data);
5572 //printk("===============>watch_dog timer\n");
5573 queue_delayed_work(priv->priv_wq,&priv->watch_dog_wq, 0);
5574 mod_timer(&priv->watch_dog_timer, jiffies + MSECS(IEEE80211_WATCH_DOG_TIME));
5576 int _rtl8192_up(struct net_device *dev)
5578 struct r8192_priv *priv = ieee80211_priv(dev);
5579 //int i;
5580 int init_status = 0;
5581 priv->up=1;
5582 priv->ieee80211->ieee_up=1;
5583 RT_TRACE(COMP_INIT, "Bringing up iface");
5584 init_status = priv->ops->rtl819x_adapter_start(dev);
5585 if(!init_status)
5587 RT_TRACE(COMP_ERR,"ERR!!! %s(): initialization is failed!\n", __FUNCTION__);
5588 priv->up=priv->ieee80211->ieee_up = 0;
5589 return -EAGAIN;
5591 RT_TRACE(COMP_INIT, "start adapter finished\n");
5592 rtl8192_rx_enable(dev);
5593 // rtl8192_tx_enable(dev);
5594 if(priv->ieee80211->state != IEEE80211_LINKED)
5595 ieee80211_softmac_start_protocol(priv->ieee80211);
5596 ieee80211_reset_queue(priv->ieee80211);
5597 watch_dog_timer_callback((unsigned long) dev);
5598 if(!netif_queue_stopped(dev))
5599 netif_start_queue(dev);
5600 else
5601 netif_wake_queue(dev);
5604 * Make sure that drop_unencrypted is initialized as "0"
5605 * No packets will be sent in non-security mode if we had set drop_unencrypted.
5606 * ex, After kill wpa_supplicant process, make the driver up again.
5607 * drop_unencrypted remains as "1", which is set by wpa_supplicant. 2008/12/04.john
5609 priv->ieee80211->drop_unencrypted = 0;
5611 return 0;
5615 int rtl8192_open(struct net_device *dev)
5617 struct r8192_priv *priv = ieee80211_priv(dev);
5618 int ret;
5619 down(&priv->wx_sem);
5620 ret = rtl8192_up(dev);
5621 up(&priv->wx_sem);
5622 return ret;
5627 int rtl8192_up(struct net_device *dev)
5629 struct r8192_priv *priv = ieee80211_priv(dev);
5631 if (priv->up == 1) return -1;
5633 return _rtl8192_up(dev);
5637 int rtl8192_close(struct net_device *dev)
5639 struct r8192_priv *priv = ieee80211_priv(dev);
5640 int ret;
5642 down(&priv->wx_sem);
5644 ret = rtl8192_down(dev);
5646 up(&priv->wx_sem);
5648 return ret;
5652 int rtl8192_down(struct net_device *dev)
5654 struct r8192_priv *priv = ieee80211_priv(dev);
5655 int i;
5657 if (priv->up == 0) return -1;
5659 priv->up=0;
5660 priv->ieee80211->ieee_up = 0;
5661 RT_TRACE(COMP_DOWN, "==========>%s()\n", __FUNCTION__);
5662 /* FIXME */
5663 if (!netif_queue_stopped(dev))
5664 netif_stop_queue(dev);
5666 rtl8192_rtx_disable(dev);
5667 //rtl8192_irq_disable(dev);
5669 /* Tx related queue release */
5670 for(i = 0; i < MAX_QUEUE_SIZE; i++) {
5671 skb_queue_purge(&priv->ieee80211->skb_waitQ [i]);
5673 for(i = 0; i < MAX_QUEUE_SIZE; i++) {
5674 skb_queue_purge(&priv->ieee80211->skb_aggQ [i]);
5677 for(i = 0; i < MAX_QUEUE_SIZE; i++) {
5678 skb_queue_purge(&priv->ieee80211->skb_drv_aggQ [i]);
5681 //as cancel_delayed_work will del work->timer, so if work is not definedas struct delayed_work, it will corrupt
5682 // flush_scheduled_work();
5683 rtl8192_cancel_deferred_work(priv);
5684 deinit_hal_dm(dev);
5685 del_timer_sync(&priv->watch_dog_timer);
5688 ieee80211_softmac_stop_protocol(priv->ieee80211);
5689 memset(&priv->ieee80211->current_network, 0 , offsetof(struct ieee80211_network, list));
5690 RT_TRACE(COMP_DOWN, "<==========%s()\n", __FUNCTION__);
5692 return 0;
5696 void rtl8192_commit(struct net_device *dev)
5698 struct r8192_priv *priv = ieee80211_priv(dev);
5699 int reset_status = 0;
5700 //u8 reset_times = 0;
5701 if (priv->up == 0) return ;
5702 priv->up = 0;
5704 rtl8192_cancel_deferred_work(priv);
5705 del_timer_sync(&priv->watch_dog_timer);
5706 //cancel_delayed_work(&priv->SwChnlWorkItem);
5708 ieee80211_softmac_stop_protocol(priv->ieee80211);
5710 //rtl8192_irq_disable(dev);
5711 rtl8192_rtx_disable(dev);
5712 reset_status = _rtl8192_up(dev);
5717 void rtl8192_restart(struct net_device *dev)
5719 struct r8192_priv *priv = ieee80211_priv(dev);
5721 void rtl8192_restart(struct work_struct *work)
5723 struct r8192_priv *priv = container_of(work, struct r8192_priv, reset_wq);
5724 struct net_device *dev = priv->ieee80211->dev;
5726 down(&priv->wx_sem);
5728 rtl8192_commit(dev);
5730 up(&priv->wx_sem);
5733 static void r8192_set_multicast(struct net_device *dev)
5735 struct r8192_priv *priv = ieee80211_priv(dev);
5736 short promisc;
5738 //down(&priv->wx_sem);
5740 /* FIXME FIXME */
5742 promisc = (dev->flags & IFF_PROMISC) ? 1:0;
5744 if (promisc != priv->promisc)
5745 // rtl8192_commit(dev);
5747 priv->promisc = promisc;
5749 //schedule_work(&priv->reset_wq);
5750 //up(&priv->wx_sem);
5754 int r8192_set_mac_adr(struct net_device *dev, void *mac)
5756 struct r8192_priv *priv = ieee80211_priv(dev);
5757 struct sockaddr *addr = mac;
5759 down(&priv->wx_sem);
5761 memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
5763 schedule_work(&priv->reset_wq);
5765 up(&priv->wx_sem);
5767 return 0;
5770 /* based on ipw2200 driver */
5771 int rtl8192_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
5773 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
5774 struct iwreq *wrq = (struct iwreq *)rq;
5775 int ret=-1;
5776 struct ieee80211_device *ieee = priv->ieee80211;
5777 u32 key[4];
5778 u8 broadcast_addr[6] = {0xff,0xff,0xff,0xff,0xff,0xff};
5779 u8 zero_addr[6] = {0};
5780 struct iw_point *p = &wrq->u.data;
5781 struct ieee_param *ipw = NULL;//(struct ieee_param *)wrq->u.data.pointer;
5783 down(&priv->wx_sem);
5786 if (p->length < sizeof(struct ieee_param) || !p->pointer){
5787 ret = -EINVAL;
5788 goto out;
5791 ipw = kmalloc(p->length, GFP_KERNEL);
5792 if (ipw == NULL){
5793 ret = -ENOMEM;
5794 goto out;
5796 if (copy_from_user(ipw, p->pointer, p->length)) {
5797 kfree(ipw);
5798 ret = -EFAULT;
5799 goto out;
5802 switch (cmd) {
5803 case RTL_IOCTL_WPA_SUPPLICANT:
5804 //parse here for HW security
5805 if (ipw->cmd == IEEE_CMD_SET_ENCRYPTION)
5807 if (ipw->u.crypt.set_tx)
5809 if (strcmp(ipw->u.crypt.alg, "CCMP") == 0)
5810 ieee->pairwise_key_type = KEY_TYPE_CCMP;
5811 else if (strcmp(ipw->u.crypt.alg, "TKIP") == 0)
5812 ieee->pairwise_key_type = KEY_TYPE_TKIP;
5813 else if (strcmp(ipw->u.crypt.alg, "WEP") == 0)
5815 if (ipw->u.crypt.key_len == 13)
5816 ieee->pairwise_key_type = KEY_TYPE_WEP104;
5817 else if (ipw->u.crypt.key_len == 5)
5818 ieee->pairwise_key_type = KEY_TYPE_WEP40;
5820 else
5821 ieee->pairwise_key_type = KEY_TYPE_NA;
5823 if (ieee->pairwise_key_type)
5825 // FIXME:these two lines below just to fix ipw interface bug, that is, it will never set mode down to driver. So treat it as ADHOC mode, if no association procedure. WB. 2009.02.04
5826 if (memcmp(ieee->ap_mac_addr, zero_addr, 6) == 0)
5827 ieee->iw_mode = IW_MODE_ADHOC;
5828 memcpy((u8*)key, ipw->u.crypt.key, 16);
5829 EnableHWSecurityConfig8192(dev);
5830 //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!
5831 //added by WB.
5832 setKey(dev, 4, ipw->u.crypt.idx, ieee->pairwise_key_type, (u8*)ieee->ap_mac_addr, 0, key);
5833 if (ieee->iw_mode == IW_MODE_ADHOC)
5834 setKey(dev, ipw->u.crypt.idx, ipw->u.crypt.idx, ieee->pairwise_key_type, (u8*)ieee->ap_mac_addr, 0, key);
5837 else //if (ipw->u.crypt.idx) //group key use idx > 0
5839 memcpy((u8*)key, ipw->u.crypt.key, 16);
5840 if (strcmp(ipw->u.crypt.alg, "CCMP") == 0)
5841 ieee->group_key_type= KEY_TYPE_CCMP;
5842 else if (strcmp(ipw->u.crypt.alg, "TKIP") == 0)
5843 ieee->group_key_type = KEY_TYPE_TKIP;
5844 else if (strcmp(ipw->u.crypt.alg, "WEP") == 0)
5846 if (ipw->u.crypt.key_len == 13)
5847 ieee->group_key_type = KEY_TYPE_WEP104;
5848 else if (ipw->u.crypt.key_len == 5)
5849 ieee->group_key_type = KEY_TYPE_WEP40;
5851 else
5852 ieee->group_key_type = KEY_TYPE_NA;
5854 if (ieee->group_key_type)
5856 setKey( dev,
5857 ipw->u.crypt.idx,
5858 ipw->u.crypt.idx, //KeyIndex
5859 ieee->group_key_type, //KeyType
5860 broadcast_addr, //MacAddr
5861 0, //DefaultKey
5862 key); //KeyContent
5866 #ifdef JOHN_HWSEC_DEBUG
5867 //john's test 0711
5868 printk("@@ wrq->u pointer = ");
5869 for(i=0;i<wrq->u.data.length;i++){
5870 if(i%10==0) printk("\n");
5871 printk( "%8x|", ((u32*)wrq->u.data.pointer)[i] );
5873 printk("\n");
5874 #endif /*JOHN_HWSEC_DEBUG*/
5875 ret = ieee80211_wpa_supplicant_ioctl(priv->ieee80211, &wrq->u.data);
5876 break;
5878 default:
5879 ret = -EOPNOTSUPP;
5880 break;
5882 kfree(ipw);
5883 ipw = NULL;
5884 out:
5885 up(&priv->wx_sem);
5886 return ret;
5889 u8 rtl8192SU_HwRateToMRate(bool bIsHT, u8 rate,bool bFirstAMPDU)
5892 u8 ret_rate = 0x02;
5894 if( bFirstAMPDU )
5896 if(!bIsHT)
5898 switch(rate)
5901 case DESC92S_RATE1M: ret_rate = MGN_1M; break;
5902 case DESC92S_RATE2M: ret_rate = MGN_2M; break;
5903 case DESC92S_RATE5_5M: ret_rate = MGN_5_5M; break;
5904 case DESC92S_RATE11M: ret_rate = MGN_11M; break;
5905 case DESC92S_RATE6M: ret_rate = MGN_6M; break;
5906 case DESC92S_RATE9M: ret_rate = MGN_9M; break;
5907 case DESC92S_RATE12M: ret_rate = MGN_12M; break;
5908 case DESC92S_RATE18M: ret_rate = MGN_18M; break;
5909 case DESC92S_RATE24M: ret_rate = MGN_24M; break;
5910 case DESC92S_RATE36M: ret_rate = MGN_36M; break;
5911 case DESC92S_RATE48M: ret_rate = MGN_48M; break;
5912 case DESC92S_RATE54M: ret_rate = MGN_54M; break;
5914 default:
5915 RT_TRACE(COMP_RECV, "HwRateToMRate90(): Non supported Rate [%x], bIsHT = %d!!!\n", rate, bIsHT);
5916 break;
5919 else
5921 switch(rate)
5924 case DESC92S_RATEMCS0: ret_rate = MGN_MCS0; break;
5925 case DESC92S_RATEMCS1: ret_rate = MGN_MCS1; break;
5926 case DESC92S_RATEMCS2: ret_rate = MGN_MCS2; break;
5927 case DESC92S_RATEMCS3: ret_rate = MGN_MCS3; break;
5928 case DESC92S_RATEMCS4: ret_rate = MGN_MCS4; break;
5929 case DESC92S_RATEMCS5: ret_rate = MGN_MCS5; break;
5930 case DESC92S_RATEMCS6: ret_rate = MGN_MCS6; break;
5931 case DESC92S_RATEMCS7: ret_rate = MGN_MCS7; break;
5932 case DESC92S_RATEMCS8: ret_rate = MGN_MCS8; break;
5933 case DESC92S_RATEMCS9: ret_rate = MGN_MCS9; break;
5934 case DESC92S_RATEMCS10: ret_rate = MGN_MCS10; break;
5935 case DESC92S_RATEMCS11: ret_rate = MGN_MCS11; break;
5936 case DESC92S_RATEMCS12: ret_rate = MGN_MCS12; break;
5937 case DESC92S_RATEMCS13: ret_rate = MGN_MCS13; break;
5938 case DESC92S_RATEMCS14: ret_rate = MGN_MCS14; break;
5939 case DESC92S_RATEMCS15: ret_rate = MGN_MCS15; break;
5940 case DESC92S_RATEMCS32: ret_rate = (0x80|0x20); break;
5942 default:
5943 RT_TRACE(COMP_RECV, "HwRateToMRate92S(): Non supported Rate [%x], bIsHT = %d!!!\n",rate, bIsHT );
5944 break;
5949 else
5951 switch(rate)
5954 case DESC92S_RATE1M: ret_rate = MGN_1M; break;
5955 case DESC92S_RATE2M: ret_rate = MGN_2M; break;
5956 case DESC92S_RATE5_5M: ret_rate = MGN_5_5M; break;
5957 case DESC92S_RATE11M: ret_rate = MGN_11M; break;
5958 case DESC92S_RATE6M: ret_rate = MGN_6M; break;
5959 case DESC92S_RATE9M: ret_rate = MGN_9M; break;
5960 case DESC92S_RATE12M: ret_rate = MGN_12M; break;
5961 case DESC92S_RATE18M: ret_rate = MGN_18M; break;
5962 case DESC92S_RATE24M: ret_rate = MGN_24M; break;
5963 case DESC92S_RATE36M: ret_rate = MGN_36M; break;
5964 case DESC92S_RATE48M: ret_rate = MGN_48M; break;
5965 case DESC92S_RATE54M: ret_rate = MGN_54M; break;
5966 case DESC92S_RATEMCS0: ret_rate = MGN_MCS0; break;
5967 case DESC92S_RATEMCS1: ret_rate = MGN_MCS1; break;
5968 case DESC92S_RATEMCS2: ret_rate = MGN_MCS2; break;
5969 case DESC92S_RATEMCS3: ret_rate = MGN_MCS3; break;
5970 case DESC92S_RATEMCS4: ret_rate = MGN_MCS4; break;
5971 case DESC92S_RATEMCS5: ret_rate = MGN_MCS5; break;
5972 case DESC92S_RATEMCS6: ret_rate = MGN_MCS6; break;
5973 case DESC92S_RATEMCS7: ret_rate = MGN_MCS7; break;
5974 case DESC92S_RATEMCS8: ret_rate = MGN_MCS8; break;
5975 case DESC92S_RATEMCS9: ret_rate = MGN_MCS9; break;
5976 case DESC92S_RATEMCS10: ret_rate = MGN_MCS10; break;
5977 case DESC92S_RATEMCS11: ret_rate = MGN_MCS11; break;
5978 case DESC92S_RATEMCS12: ret_rate = MGN_MCS12; break;
5979 case DESC92S_RATEMCS13: ret_rate = MGN_MCS13; break;
5980 case DESC92S_RATEMCS14: ret_rate = MGN_MCS14; break;
5981 case DESC92S_RATEMCS15: ret_rate = MGN_MCS15; break;
5982 case DESC92S_RATEMCS32: ret_rate = (0x80|0x20); break;
5984 default:
5985 RT_TRACE(COMP_RECV, "HwRateToMRate92S(): Non supported Rate [%x], bIsHT = %d!!!\n",rate, bIsHT );
5986 break;
5989 return ret_rate;
5992 u8 HwRateToMRate90(bool bIsHT, u8 rate)
5994 u8 ret_rate = 0xff;
5996 if(!bIsHT) {
5997 switch(rate) {
5998 case DESC90_RATE1M: ret_rate = MGN_1M; break;
5999 case DESC90_RATE2M: ret_rate = MGN_2M; break;
6000 case DESC90_RATE5_5M: ret_rate = MGN_5_5M; break;
6001 case DESC90_RATE11M: ret_rate = MGN_11M; break;
6002 case DESC90_RATE6M: ret_rate = MGN_6M; break;
6003 case DESC90_RATE9M: ret_rate = MGN_9M; break;
6004 case DESC90_RATE12M: ret_rate = MGN_12M; break;
6005 case DESC90_RATE18M: ret_rate = MGN_18M; break;
6006 case DESC90_RATE24M: ret_rate = MGN_24M; break;
6007 case DESC90_RATE36M: ret_rate = MGN_36M; break;
6008 case DESC90_RATE48M: ret_rate = MGN_48M; break;
6009 case DESC90_RATE54M: ret_rate = MGN_54M; break;
6011 default:
6012 ret_rate = 0xff;
6013 RT_TRACE(COMP_RECV, "HwRateToMRate90(): Non supported Rate [%x], bIsHT = %d!!!\n", rate, bIsHT);
6014 break;
6017 } else {
6018 switch(rate) {
6019 case DESC90_RATEMCS0: ret_rate = MGN_MCS0; break;
6020 case DESC90_RATEMCS1: ret_rate = MGN_MCS1; break;
6021 case DESC90_RATEMCS2: ret_rate = MGN_MCS2; break;
6022 case DESC90_RATEMCS3: ret_rate = MGN_MCS3; break;
6023 case DESC90_RATEMCS4: ret_rate = MGN_MCS4; break;
6024 case DESC90_RATEMCS5: ret_rate = MGN_MCS5; break;
6025 case DESC90_RATEMCS6: ret_rate = MGN_MCS6; break;
6026 case DESC90_RATEMCS7: ret_rate = MGN_MCS7; break;
6027 case DESC90_RATEMCS8: ret_rate = MGN_MCS8; break;
6028 case DESC90_RATEMCS9: ret_rate = MGN_MCS9; break;
6029 case DESC90_RATEMCS10: ret_rate = MGN_MCS10; break;
6030 case DESC90_RATEMCS11: ret_rate = MGN_MCS11; break;
6031 case DESC90_RATEMCS12: ret_rate = MGN_MCS12; break;
6032 case DESC90_RATEMCS13: ret_rate = MGN_MCS13; break;
6033 case DESC90_RATEMCS14: ret_rate = MGN_MCS14; break;
6034 case DESC90_RATEMCS15: ret_rate = MGN_MCS15; break;
6035 case DESC90_RATEMCS32: ret_rate = (0x80|0x20); break;
6037 default:
6038 ret_rate = 0xff;
6039 RT_TRACE(COMP_RECV, "HwRateToMRate90(): Non supported Rate [%x], bIsHT = %d!!!\n",rate, bIsHT);
6040 break;
6044 return ret_rate;
6048 * Function: UpdateRxPktTimeStamp
6049 * Overview: Recored down the TSF time stamp when receiving a packet
6051 * Input:
6052 * PADAPTER Adapter
6053 * PRT_RFD pRfd,
6055 * Output:
6056 * PRT_RFD pRfd
6057 * (pRfd->Status.TimeStampHigh is updated)
6058 * (pRfd->Status.TimeStampLow is updated)
6059 * Return:
6060 * None
6062 void UpdateRxPktTimeStamp8190 (struct net_device *dev, struct ieee80211_rx_stats *stats)
6064 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
6066 if(stats->bIsAMPDU && !stats->bFirstMPDU) {
6067 stats->mac_time[0] = priv->LastRxDescTSFLow;
6068 stats->mac_time[1] = priv->LastRxDescTSFHigh;
6069 } else {
6070 priv->LastRxDescTSFLow = stats->mac_time[0];
6071 priv->LastRxDescTSFHigh = stats->mac_time[1];
6075 //by amy 080606
6077 long rtl819x_translate_todbm(u8 signal_strength_index )// 0-100 index.
6079 long signal_power; // in dBm.
6081 // Translate to dBm (x=0.5y-95).
6082 signal_power = (long)((signal_strength_index + 1) >> 1);
6083 signal_power -= 95;
6085 return signal_power;
6089 /* 2008/01/22 MH We can not delcare RSSI/EVM total value of sliding window to
6090 be a local static. Otherwise, it may increase when we return from S3/S4. The
6091 value will be kept in memory or disk. We must delcare the value in adapter
6092 and it will be reinitialized when return from S3/S4. */
6093 void rtl8192_process_phyinfo(struct r8192_priv * priv,u8* buffer, struct ieee80211_rx_stats * pprevious_stats, struct ieee80211_rx_stats * pcurrent_stats)
6095 bool bcheck = false;
6096 u8 rfpath;
6097 u32 nspatial_stream, tmp_val;
6098 //u8 i;
6099 static u32 slide_rssi_index=0, slide_rssi_statistics=0;
6100 static u32 slide_evm_index=0, slide_evm_statistics=0;
6101 static u32 last_rssi=0, last_evm=0;
6103 static u32 slide_beacon_adc_pwdb_index=0, slide_beacon_adc_pwdb_statistics=0;
6104 static u32 last_beacon_adc_pwdb=0;
6106 struct ieee80211_hdr_3addr *hdr;
6107 u16 sc ;
6108 unsigned int frag,seq;
6109 hdr = (struct ieee80211_hdr_3addr *)buffer;
6110 sc = le16_to_cpu(hdr->seq_ctrl);
6111 frag = WLAN_GET_SEQ_FRAG(sc);
6112 seq = WLAN_GET_SEQ_SEQ(sc);
6113 //cosa add 04292008 to record the sequence number
6114 pcurrent_stats->Seq_Num = seq;
6116 // Check whether we should take the previous packet into accounting
6118 if(!pprevious_stats->bIsAMPDU)
6120 // if previous packet is not aggregated packet
6121 bcheck = true;
6122 }else
6127 if(slide_rssi_statistics++ >= PHY_RSSI_SLID_WIN_MAX)
6129 slide_rssi_statistics = PHY_RSSI_SLID_WIN_MAX;
6130 last_rssi = priv->stats.slide_signal_strength[slide_rssi_index];
6131 priv->stats.slide_rssi_total -= last_rssi;
6133 priv->stats.slide_rssi_total += pprevious_stats->SignalStrength;
6135 priv->stats.slide_signal_strength[slide_rssi_index++] = pprevious_stats->SignalStrength;
6136 if(slide_rssi_index >= PHY_RSSI_SLID_WIN_MAX)
6137 slide_rssi_index = 0;
6139 // <1> Showed on UI for user, in dbm
6140 tmp_val = priv->stats.slide_rssi_total/slide_rssi_statistics;
6141 priv->stats.signal_strength = rtl819x_translate_todbm((u8)tmp_val);
6142 pcurrent_stats->rssi = priv->stats.signal_strength;
6144 // If the previous packet does not match the criteria, neglect it
6146 if(!pprevious_stats->bPacketMatchBSSID)
6148 if(!pprevious_stats->bToSelfBA)
6149 return;
6152 if(!bcheck)
6153 return;
6156 //rtl8190_process_cck_rxpathsel(priv,pprevious_stats);//only rtl8190 supported
6159 // Check RSSI
6161 priv->stats.num_process_phyinfo++;
6163 /* record the general signal strength to the sliding window. */
6166 // <2> Showed on UI for engineering
6167 // hardware does not provide rssi information for each rf path in CCK
6168 if(!pprevious_stats->bIsCCK && (pprevious_stats->bPacketToSelf || pprevious_stats->bToSelfBA))
6170 for (rfpath = RF90_PATH_A; rfpath < priv->NumTotalRFPath; rfpath++)
6172 if (!rtl8192_phy_CheckIsLegalRFPath(priv->ieee80211->dev, rfpath))
6173 continue;
6175 //Fixed by Jacken 2008-03-20
6176 if(priv->stats.rx_rssi_percentage[rfpath] == 0)
6178 priv->stats.rx_rssi_percentage[rfpath] = pprevious_stats->RxMIMOSignalStrength[rfpath];
6179 //DbgPrint("MIMO RSSI initialize \n");
6181 if(pprevious_stats->RxMIMOSignalStrength[rfpath] > priv->stats.rx_rssi_percentage[rfpath])
6183 priv->stats.rx_rssi_percentage[rfpath] =
6184 ( (priv->stats.rx_rssi_percentage[rfpath]*(Rx_Smooth_Factor-1)) +
6185 (pprevious_stats->RxMIMOSignalStrength[rfpath])) /(Rx_Smooth_Factor);
6186 priv->stats.rx_rssi_percentage[rfpath] = priv->stats.rx_rssi_percentage[rfpath] + 1;
6188 else
6190 priv->stats.rx_rssi_percentage[rfpath] =
6191 ( (priv->stats.rx_rssi_percentage[rfpath]*(Rx_Smooth_Factor-1)) +
6192 (pprevious_stats->RxMIMOSignalStrength[rfpath])) /(Rx_Smooth_Factor);
6194 RT_TRACE(COMP_DBG,"priv->stats.rx_rssi_percentage[rfPath] = %d \n" ,priv->stats.rx_rssi_percentage[rfpath] );
6200 // Check PWDB.
6202 RT_TRACE(COMP_RXDESC, "Smooth %s PWDB = %d\n",
6203 pprevious_stats->bIsCCK? "CCK": "OFDM",
6204 pprevious_stats->RxPWDBAll);
6206 if(pprevious_stats->bPacketBeacon)
6208 /* record the beacon pwdb to the sliding window. */
6209 if(slide_beacon_adc_pwdb_statistics++ >= PHY_Beacon_RSSI_SLID_WIN_MAX)
6211 slide_beacon_adc_pwdb_statistics = PHY_Beacon_RSSI_SLID_WIN_MAX;
6212 last_beacon_adc_pwdb = priv->stats.Slide_Beacon_pwdb[slide_beacon_adc_pwdb_index];
6213 priv->stats.Slide_Beacon_Total -= last_beacon_adc_pwdb;
6214 //DbgPrint("slide_beacon_adc_pwdb_index = %d, last_beacon_adc_pwdb = %d, Adapter->RxStats.Slide_Beacon_Total = %d\n",
6215 // slide_beacon_adc_pwdb_index, last_beacon_adc_pwdb, Adapter->RxStats.Slide_Beacon_Total);
6217 priv->stats.Slide_Beacon_Total += pprevious_stats->RxPWDBAll;
6218 priv->stats.Slide_Beacon_pwdb[slide_beacon_adc_pwdb_index] = pprevious_stats->RxPWDBAll;
6219 //DbgPrint("slide_beacon_adc_pwdb_index = %d, pPreviousRfd->Status.RxPWDBAll = %d\n", slide_beacon_adc_pwdb_index, pPreviousRfd->Status.RxPWDBAll);
6220 slide_beacon_adc_pwdb_index++;
6221 if(slide_beacon_adc_pwdb_index >= PHY_Beacon_RSSI_SLID_WIN_MAX)
6222 slide_beacon_adc_pwdb_index = 0;
6223 pprevious_stats->RxPWDBAll = priv->stats.Slide_Beacon_Total/slide_beacon_adc_pwdb_statistics;
6224 if(pprevious_stats->RxPWDBAll >= 3)
6225 pprevious_stats->RxPWDBAll -= 3;
6228 RT_TRACE(COMP_RXDESC, "Smooth %s PWDB = %d\n",
6229 pprevious_stats->bIsCCK? "CCK": "OFDM",
6230 pprevious_stats->RxPWDBAll);
6233 if(pprevious_stats->bPacketToSelf || pprevious_stats->bPacketBeacon || pprevious_stats->bToSelfBA)
6235 if(priv->undecorated_smoothed_pwdb < 0) // initialize
6237 priv->undecorated_smoothed_pwdb = pprevious_stats->RxPWDBAll;
6238 //DbgPrint("First pwdb initialize \n");
6240 #if 1
6241 if(pprevious_stats->RxPWDBAll > (u32)priv->undecorated_smoothed_pwdb)
6243 priv->undecorated_smoothed_pwdb =
6244 ( ((priv->undecorated_smoothed_pwdb)*(Rx_Smooth_Factor-1)) +
6245 (pprevious_stats->RxPWDBAll)) /(Rx_Smooth_Factor);
6246 priv->undecorated_smoothed_pwdb = priv->undecorated_smoothed_pwdb + 1;
6248 else
6250 priv->undecorated_smoothed_pwdb =
6251 ( ((priv->undecorated_smoothed_pwdb)*(Rx_Smooth_Factor-1)) +
6252 (pprevious_stats->RxPWDBAll)) /(Rx_Smooth_Factor);
6254 #else
6255 //Fixed by Jacken 2008-03-20
6256 if(pPreviousRfd->Status.RxPWDBAll > (u32)pHalData->UndecoratedSmoothedPWDB)
6258 pHalData->UndecoratedSmoothedPWDB =
6259 ( ((pHalData->UndecoratedSmoothedPWDB)* 5) + (pPreviousRfd->Status.RxPWDBAll)) / 6;
6260 pHalData->UndecoratedSmoothedPWDB = pHalData->UndecoratedSmoothedPWDB + 1;
6262 else
6264 pHalData->UndecoratedSmoothedPWDB =
6265 ( ((pHalData->UndecoratedSmoothedPWDB)* 5) + (pPreviousRfd->Status.RxPWDBAll)) / 6;
6267 #endif
6272 // Check EVM
6274 /* record the general EVM to the sliding window. */
6275 if(pprevious_stats->SignalQuality == 0)
6278 else
6280 if(pprevious_stats->bPacketToSelf || pprevious_stats->bPacketBeacon || pprevious_stats->bToSelfBA){
6281 if(slide_evm_statistics++ >= PHY_RSSI_SLID_WIN_MAX){
6282 slide_evm_statistics = PHY_RSSI_SLID_WIN_MAX;
6283 last_evm = priv->stats.slide_evm[slide_evm_index];
6284 priv->stats.slide_evm_total -= last_evm;
6287 priv->stats.slide_evm_total += pprevious_stats->SignalQuality;
6289 priv->stats.slide_evm[slide_evm_index++] = pprevious_stats->SignalQuality;
6290 if(slide_evm_index >= PHY_RSSI_SLID_WIN_MAX)
6291 slide_evm_index = 0;
6293 // <1> Showed on UI for user, in percentage.
6294 tmp_val = priv->stats.slide_evm_total/slide_evm_statistics;
6295 priv->stats.signal_quality = tmp_val;
6296 //cosa add 10/11/2007, Showed on UI for user in Windows Vista, for Link quality.
6297 priv->stats.last_signal_strength_inpercent = tmp_val;
6300 // <2> Showed on UI for engineering
6301 if(pprevious_stats->bPacketToSelf || pprevious_stats->bPacketBeacon || pprevious_stats->bToSelfBA)
6303 for(nspatial_stream = 0; nspatial_stream<2 ; nspatial_stream++) // 2 spatial stream
6305 if(pprevious_stats->RxMIMOSignalQuality[nspatial_stream] != -1)
6307 if(priv->stats.rx_evm_percentage[nspatial_stream] == 0) // initialize
6309 priv->stats.rx_evm_percentage[nspatial_stream] = pprevious_stats->RxMIMOSignalQuality[nspatial_stream];
6311 priv->stats.rx_evm_percentage[nspatial_stream] =
6312 ( (priv->stats.rx_evm_percentage[nspatial_stream]* (Rx_Smooth_Factor-1)) +
6313 (pprevious_stats->RxMIMOSignalQuality[nspatial_stream]* 1)) / (Rx_Smooth_Factor);
6322 /*-----------------------------------------------------------------------------
6323 * Function: rtl819x_query_rxpwrpercentage()
6325 * Overview:
6327 * Input: char antpower
6329 * Output: NONE
6331 * Return: 0-100 percentage
6333 * Revised History:
6334 * When Who Remark
6335 * 05/26/2008 amy Create Version 0 porting from windows code.
6337 *---------------------------------------------------------------------------*/
6338 static u8 rtl819x_query_rxpwrpercentage(
6339 char antpower
6342 if ((antpower <= -100) || (antpower >= 20))
6344 return 0;
6346 else if (antpower >= 0)
6348 return 100;
6350 else
6352 return (100+antpower);
6355 } /* QueryRxPwrPercentage */
6357 static u8
6358 rtl819x_evm_dbtopercentage(
6359 char value
6362 char ret_val;
6364 ret_val = value;
6366 if(ret_val >= 0)
6367 ret_val = 0;
6368 if(ret_val <= -33)
6369 ret_val = -33;
6370 ret_val = 0 - ret_val;
6371 ret_val*=3;
6372 if(ret_val == 99)
6373 ret_val = 100;
6374 return(ret_val);
6377 // Description:
6378 // We want good-looking for signal strength/quality
6379 // 2007/7/19 01:09, by cosa.
6381 long
6382 rtl819x_signal_scale_mapping(
6383 long currsig
6386 long retsig;
6388 // Step 1. Scale mapping.
6389 if(currsig >= 61 && currsig <= 100)
6391 retsig = 90 + ((currsig - 60) / 4);
6393 else if(currsig >= 41 && currsig <= 60)
6395 retsig = 78 + ((currsig - 40) / 2);
6397 else if(currsig >= 31 && currsig <= 40)
6399 retsig = 66 + (currsig - 30);
6401 else if(currsig >= 21 && currsig <= 30)
6403 retsig = 54 + (currsig - 20);
6405 else if(currsig >= 5 && currsig <= 20)
6407 retsig = 42 + (((currsig - 5) * 2) / 3);
6409 else if(currsig == 4)
6411 retsig = 36;
6413 else if(currsig == 3)
6415 retsig = 27;
6417 else if(currsig == 2)
6419 retsig = 18;
6421 else if(currsig == 1)
6423 retsig = 9;
6425 else
6427 retsig = currsig;
6430 return retsig;
6433 /*-----------------------------------------------------------------------------
6434 * Function: QueryRxPhyStatus8192S()
6436 * Overview:
6438 * Input: NONE
6440 * Output: NONE
6442 * Return: NONE
6444 * Revised History:
6445 * When Who Remark
6446 * 06/01/2007 MHC Create Version 0.
6447 * 06/05/2007 MHC Accordign to HW's new data sheet, we add CCK and OFDM
6448 * descriptor definition.
6449 * 07/04/2007 MHC According to Jerry and Bryant's document. We read
6450 * ir_isolation and ext_lna for RF's init value and use
6451 * to compensate RSSI after receiving packets.
6452 * 09/10/2008 MHC Modify name and PHY status field for 92SE.
6453 * 09/19/2008 MHC Add CCK/OFDM SS/SQ for 92S series.
6455 *---------------------------------------------------------------------------*/
6456 static void rtl8192SU_query_rxphystatus(
6457 struct r8192_priv * priv,
6458 struct ieee80211_rx_stats * pstats,
6459 rx_desc_819x_usb *pDesc,
6460 rx_drvinfo_819x_usb * pdrvinfo,
6461 struct ieee80211_rx_stats * precord_stats,
6462 bool bpacket_match_bssid,
6463 bool bpacket_toself,
6464 bool bPacketBeacon,
6465 bool bToSelfBA
6468 //PRT_RFD_STATUS pRtRfdStatus = &(pRfd->Status);
6469 //PHY_STS_CCK_8192S_T *pCck_buf;
6470 phy_sts_cck_819xusb_t * pcck_buf;
6471 phy_ofdm_rx_status_rxsc_sgien_exintfflag* prxsc;
6472 //u8 *prxpkt;
6473 //u8 i, max_spatial_stream, tmp_rxsnr, tmp_rxevm, rxsc_sgien_exflg;
6474 u8 i, max_spatial_stream, rxsc_sgien_exflg;
6475 char rx_pwr[4], rx_pwr_all=0;
6476 //long rx_avg_pwr = 0;
6477 //char rx_snrX, rx_evmX;
6478 u8 evm, pwdb_all;
6479 u32 RSSI, total_rssi=0;//, total_evm=0;
6480 // long signal_strength_index = 0;
6481 u8 is_cck_rate=0;
6482 u8 rf_rx_num = 0;
6486 priv->stats.numqry_phystatus++;
6488 is_cck_rate = rx_hal_is_cck_rate(pDesc);
6490 // Record it for next packet processing
6491 memset(precord_stats, 0, sizeof(struct ieee80211_rx_stats));
6492 pstats->bPacketMatchBSSID = precord_stats->bPacketMatchBSSID = bpacket_match_bssid;
6493 pstats->bPacketToSelf = precord_stats->bPacketToSelf = bpacket_toself;
6494 pstats->bIsCCK = precord_stats->bIsCCK = is_cck_rate;//RX_HAL_IS_CCK_RATE(pDrvInfo);
6495 pstats->bPacketBeacon = precord_stats->bPacketBeacon = bPacketBeacon;
6496 pstats->bToSelfBA = precord_stats->bToSelfBA = bToSelfBA;
6499 pstats->RxMIMOSignalQuality[0] = -1;
6500 pstats->RxMIMOSignalQuality[1] = -1;
6501 precord_stats->RxMIMOSignalQuality[0] = -1;
6502 precord_stats->RxMIMOSignalQuality[1] = -1;
6504 if(is_cck_rate)
6506 u8 report;//, tmp_pwdb;
6507 //char cck_adc_pwdb[4];
6509 // CCK Driver info Structure is not the same as OFDM packet.
6510 pcck_buf = (phy_sts_cck_819xusb_t *)pdrvinfo;
6513 // (1)Hardware does not provide RSSI for CCK
6517 // (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive)
6520 priv->stats.numqry_phystatusCCK++;
6522 if(!priv->bCckHighPower)
6524 report = pcck_buf->cck_agc_rpt & 0xc0;
6525 report = report>>6;
6526 switch(report)
6528 //Fixed by Jacken from Bryant 2008-03-20
6529 //Original value is -38 , -26 , -14 , -2
6530 //Fixed value is -35 , -23 , -11 , 6
6531 case 0x3:
6532 rx_pwr_all = -35 - (pcck_buf->cck_agc_rpt & 0x3e);
6533 break;
6534 case 0x2:
6535 rx_pwr_all = -23 - (pcck_buf->cck_agc_rpt & 0x3e);
6536 break;
6537 case 0x1:
6538 rx_pwr_all = -11 - (pcck_buf->cck_agc_rpt & 0x3e);
6539 break;
6540 case 0x0:
6541 rx_pwr_all = 8 - (pcck_buf->cck_agc_rpt & 0x3e);//6->8
6542 break;
6545 else
6547 report = pdrvinfo->cfosho[0] & 0x60;
6548 report = report>>5;
6549 switch(report)
6551 case 0x3:
6552 rx_pwr_all = -35 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1) ;
6553 break;
6554 case 0x2:
6555 rx_pwr_all = -23 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1);
6556 break;
6557 case 0x1:
6558 rx_pwr_all = -11 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1) ;
6559 break;
6560 case 0x0:
6561 rx_pwr_all = -8 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1) ;//6->-8
6562 break;
6566 pwdb_all = rtl819x_query_rxpwrpercentage(rx_pwr_all);//check it
6567 pstats->RxPWDBAll = precord_stats->RxPWDBAll = pwdb_all;
6568 //pstats->RecvSignalPower = pwdb_all;
6569 pstats->RecvSignalPower = rx_pwr_all;
6572 // (3) Get Signal Quality (EVM)
6574 //if(bpacket_match_bssid)
6576 u8 sq;
6578 if(pstats->RxPWDBAll > 40)
6580 sq = 100;
6581 }else
6583 sq = pcck_buf->sq_rpt;
6585 if(pcck_buf->sq_rpt > 64)
6586 sq = 0;
6587 else if (pcck_buf->sq_rpt < 20)
6588 sq = 100;
6589 else
6590 sq = ((64-sq) * 100) / 44;
6592 pstats->SignalQuality = precord_stats->SignalQuality = sq;
6593 pstats->RxMIMOSignalQuality[0] = precord_stats->RxMIMOSignalQuality[0] = sq;
6594 pstats->RxMIMOSignalQuality[1] = precord_stats->RxMIMOSignalQuality[1] = -1;
6597 else
6599 priv->stats.numqry_phystatusHT++;
6601 // 2008/09/19 MH For 92S debug, RX RF path always enable!!
6602 priv->brfpath_rxenable[0] = priv->brfpath_rxenable[1] = TRUE;
6605 // (1)Get RSSI for HT rate
6607 //for(i=RF90_PATH_A; i<priv->NumTotalRFPath; i++)
6608 for(i=RF90_PATH_A; i<RF90_PATH_MAX; i++)
6610 // 2008/01/30 MH we will judge RF RX path now.
6611 if (priv->brfpath_rxenable[i])
6612 rf_rx_num++;
6613 //else
6614 // continue;
6616 //if (!rtl8192_phy_CheckIsLegalRFPath(priv->ieee80211->dev, i))
6617 // continue;
6619 //Fixed by Jacken from Bryant 2008-03-20
6620 //Original value is 106
6621 //rx_pwr[i] = ((pofdm_buf->trsw_gain_X[i]&0x3F)*2) - 106;
6622 rx_pwr[i] = ((pdrvinfo->gain_trsw[i]&0x3F)*2) - 110;
6624 /* Translate DBM to percentage. */
6625 RSSI = rtl819x_query_rxpwrpercentage(rx_pwr[i]); //check ok
6626 total_rssi += RSSI;
6627 RT_TRACE(COMP_RF, "RF-%d RXPWR=%x RSSI=%d\n", i, rx_pwr[i], RSSI);
6629 //Get Rx snr value in DB
6630 //tmp_rxsnr = pofdm_buf->rxsnr_X[i];
6631 //rx_snrX = (char)(tmp_rxsnr);
6632 //rx_snrX /= 2;
6633 //priv->stats.rxSNRdB[i] = (long)rx_snrX;
6634 priv->stats.rxSNRdB[i] = (long)(pdrvinfo->rxsnr[i]/2);
6636 /* Translate DBM to percentage. */
6637 //RSSI = rtl819x_query_rxpwrpercentage(rx_pwr[i]);
6638 //total_rssi += RSSI;
6640 /* Record Signal Strength for next packet */
6641 //if(bpacket_match_bssid)
6643 pstats->RxMIMOSignalStrength[i] =(u8) RSSI;
6644 precord_stats->RxMIMOSignalStrength[i] =(u8) RSSI;
6650 // (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive)
6652 //Fixed by Jacken from Bryant 2008-03-20
6653 //Original value is 106
6654 //rx_pwr_all = (((pofdm_buf->pwdb_all ) >> 1 )& 0x7f) -106;
6655 rx_pwr_all = (((pdrvinfo->pwdb_all ) >> 1 )& 0x7f) -106;
6656 pwdb_all = rtl819x_query_rxpwrpercentage(rx_pwr_all);
6658 pstats->RxPWDBAll = precord_stats->RxPWDBAll = pwdb_all;
6659 pstats->RxPower = precord_stats->RxPower = rx_pwr_all;
6660 pstats->RecvSignalPower = rx_pwr_all;
6663 // (3)EVM of HT rate
6665 //if(pdrvinfo->RxHT && pdrvinfo->RxRate>=DESC90_RATEMCS8 &&
6666 // pdrvinfo->RxRate<=DESC90_RATEMCS15)
6667 if(pDesc->RxHT && pDesc->RxMCS>=DESC92S_RATEMCS8 &&
6668 pDesc->RxMCS<=DESC92S_RATEMCS15)
6669 max_spatial_stream = 2; //both spatial stream make sense
6670 else
6671 max_spatial_stream = 1; //only spatial stream 1 makes sense
6673 for(i=0; i<max_spatial_stream; i++)
6675 //tmp_rxevm = pofdm_buf->rxevm_X[i];
6676 //rx_evmX = (char)(tmp_rxevm);
6678 // Do not use shift operation like "rx_evmX >>= 1" because the compilor of free build environment
6679 // fill most significant bit to "zero" when doing shifting operation which may change a negative
6680 // value to positive one, then the dbm value (which is supposed to be negative) is not correct anymore.
6681 //rx_evmX /= 2; //dbm
6683 //evm = rtl819x_evm_dbtopercentage(rx_evmX);
6684 evm = rtl819x_evm_dbtopercentage( (pdrvinfo->rxevm[i] /*/ 2*/)); //dbm
6685 RT_TRACE(COMP_RF, "RXRATE=%x RXEVM=%x EVM=%s%d\n", pDesc->RxMCS, pdrvinfo->rxevm[i], "%", evm);
6687 //if(bpacket_match_bssid)
6689 if(i==0) // Fill value in RFD, Get the first spatial stream only
6690 pstats->SignalQuality = precord_stats->SignalQuality = (u8)(evm & 0xff);
6691 pstats->RxMIMOSignalQuality[i] = precord_stats->RxMIMOSignalQuality[i] = (u8)(evm & 0xff);
6696 /* record rx statistics for debug */
6697 //rxsc_sgien_exflg = pofdm_buf->rxsc_sgien_exflg;
6698 prxsc = (phy_ofdm_rx_status_rxsc_sgien_exintfflag *)&rxsc_sgien_exflg;
6699 //if(pdrvinfo->BW) //40M channel
6700 if(pDesc->BW) //40M channel
6701 priv->stats.received_bwtype[1+pdrvinfo->rxsc]++;
6702 else //20M channel
6703 priv->stats.received_bwtype[0]++;
6706 //UI BSS List signal strength(in percentage), make it good looking, from 0~100.
6707 //It is assigned to the BSS List in GetValueFromBeaconOrProbeRsp().
6708 if(is_cck_rate)
6710 pstats->SignalStrength = precord_stats->SignalStrength = (u8)(rtl819x_signal_scale_mapping((long)pwdb_all));//PWDB_ALL;//check ok
6713 else
6715 //pRfd->Status.SignalStrength = pRecordRfd->Status.SignalStrength = (u8)(SignalScaleMapping(total_rssi/=RF90_PATH_MAX));//(u8)(total_rssi/=RF90_PATH_MAX);
6716 // We can judge RX path number now.
6717 if (rf_rx_num != 0)
6718 pstats->SignalStrength = precord_stats->SignalStrength = (u8)(rtl819x_signal_scale_mapping((long)(total_rssi/=rf_rx_num)));
6720 }/* QueryRxPhyStatus8192S */
6722 void
6723 rtl8192_record_rxdesc_forlateruse(
6724 struct ieee80211_rx_stats * psrc_stats,
6725 struct ieee80211_rx_stats * ptarget_stats
6728 ptarget_stats->bIsAMPDU = psrc_stats->bIsAMPDU;
6729 ptarget_stats->bFirstMPDU = psrc_stats->bFirstMPDU;
6730 ptarget_stats->Seq_Num = psrc_stats->Seq_Num;
6733 static void rtl8192SU_query_rxphystatus(
6734 struct r8192_priv * priv,
6735 struct ieee80211_rx_stats * pstats,
6736 rx_desc_819x_usb *pDesc,
6737 rx_drvinfo_819x_usb * pdrvinfo,
6738 struct ieee80211_rx_stats * precord_stats,
6739 bool bpacket_match_bssid,
6740 bool bpacket_toself,
6741 bool bPacketBeacon,
6742 bool bToSelfBA
6744 void rtl8192SU_TranslateRxSignalStuff(struct sk_buff *skb,
6745 struct ieee80211_rx_stats * pstats,
6746 rx_desc_819x_usb *pDesc,
6747 rx_drvinfo_819x_usb *pdrvinfo)
6749 // TODO: We must only check packet for current MAC address. Not finish
6750 rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
6751 struct net_device *dev=info->dev;
6752 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
6753 bool bpacket_match_bssid, bpacket_toself;
6754 bool bPacketBeacon=FALSE, bToSelfBA=FALSE;
6755 static struct ieee80211_rx_stats previous_stats;
6756 struct ieee80211_hdr_3addr *hdr;//by amy
6757 u16 fc,type;
6759 // Get Signal Quality for only RX data queue (but not command queue)
6761 u8* tmp_buf;
6762 //u16 tmp_buf_len = 0;
6763 u8 *praddr;
6765 /* Get MAC frame start address. */
6766 tmp_buf = (u8*)skb->data;// + get_rxpacket_shiftbytes_819xusb(pstats);
6768 hdr = (struct ieee80211_hdr_3addr *)tmp_buf;
6769 fc = le16_to_cpu(hdr->frame_control);
6770 type = WLAN_FC_GET_TYPE(fc);
6771 praddr = hdr->addr1;
6773 /* Check if the received packet is acceptabe. */
6774 bpacket_match_bssid = ((IEEE80211_FTYPE_CTL != type) &&
6775 (eqMacAddr(priv->ieee80211->current_network.bssid, (fc & IEEE80211_FCTL_TODS)? hdr->addr1 : (fc & IEEE80211_FCTL_FROMDS )? hdr->addr2 : hdr->addr3))
6776 && (!pstats->bHwError) && (!pstats->bCRC)&& (!pstats->bICV));
6777 bpacket_toself = bpacket_match_bssid & (eqMacAddr(praddr, priv->ieee80211->dev->dev_addr));
6779 #if 1//cosa
6780 if(WLAN_FC_GET_FRAMETYPE(fc)== IEEE80211_STYPE_BEACON)
6782 bPacketBeacon = true;
6783 //DbgPrint("Beacon 2, MatchBSSID = %d, ToSelf = %d \n", bPacketMatchBSSID, bPacketToSelf);
6785 if(WLAN_FC_GET_FRAMETYPE(fc) == IEEE80211_STYPE_BLOCKACK)
6787 if((eqMacAddr(praddr,dev->dev_addr)))
6788 bToSelfBA = true;
6789 //DbgPrint("BlockAck, MatchBSSID = %d, ToSelf = %d \n", bPacketMatchBSSID, bPacketToSelf);
6792 #endif
6795 if(bpacket_match_bssid)
6797 priv->stats.numpacket_matchbssid++;
6799 if(bpacket_toself){
6800 priv->stats.numpacket_toself++;
6803 // Process PHY information for previous packet (RSSI/PWDB/EVM)
6805 // Because phy information is contained in the last packet of AMPDU only, so driver
6806 // should process phy information of previous packet
6807 rtl8192_process_phyinfo(priv, tmp_buf, &previous_stats, pstats);
6808 rtl8192SU_query_rxphystatus(priv, pstats, pDesc, pdrvinfo, &previous_stats, bpacket_match_bssid,bpacket_toself,bPacketBeacon,bToSelfBA);
6809 rtl8192_record_rxdesc_forlateruse(pstats, &previous_stats);
6814 * Function: UpdateReceivedRateHistogramStatistics
6815 * Overview: Recored down the received data rate
6817 * Input:
6818 * struct net_device *dev
6819 * struct ieee80211_rx_stats *stats
6821 * Output:
6823 * (priv->stats.ReceivedRateHistogram[] is updated)
6824 * Return:
6825 * None
6827 void
6828 UpdateReceivedRateHistogramStatistics8190(
6829 struct net_device *dev,
6830 struct ieee80211_rx_stats *stats
6833 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
6834 u32 rcvType=1; //0: Total, 1:OK, 2:CRC, 3:ICV
6835 u32 rateIndex;
6836 u32 preamble_guardinterval; //1: short preamble/GI, 0: long preamble/GI
6839 if(stats->bCRC)
6840 rcvType = 2;
6841 else if(stats->bICV)
6842 rcvType = 3;
6844 if(stats->bShortPreamble)
6845 preamble_guardinterval = 1;// short
6846 else
6847 preamble_guardinterval = 0;// long
6849 switch(stats->rate)
6852 // CCK rate
6854 case MGN_1M: rateIndex = 0; break;
6855 case MGN_2M: rateIndex = 1; break;
6856 case MGN_5_5M: rateIndex = 2; break;
6857 case MGN_11M: rateIndex = 3; break;
6859 // Legacy OFDM rate
6861 case MGN_6M: rateIndex = 4; break;
6862 case MGN_9M: rateIndex = 5; break;
6863 case MGN_12M: rateIndex = 6; break;
6864 case MGN_18M: rateIndex = 7; break;
6865 case MGN_24M: rateIndex = 8; break;
6866 case MGN_36M: rateIndex = 9; break;
6867 case MGN_48M: rateIndex = 10; break;
6868 case MGN_54M: rateIndex = 11; break;
6870 // 11n High throughput rate
6872 case MGN_MCS0: rateIndex = 12; break;
6873 case MGN_MCS1: rateIndex = 13; break;
6874 case MGN_MCS2: rateIndex = 14; break;
6875 case MGN_MCS3: rateIndex = 15; break;
6876 case MGN_MCS4: rateIndex = 16; break;
6877 case MGN_MCS5: rateIndex = 17; break;
6878 case MGN_MCS6: rateIndex = 18; break;
6879 case MGN_MCS7: rateIndex = 19; break;
6880 case MGN_MCS8: rateIndex = 20; break;
6881 case MGN_MCS9: rateIndex = 21; break;
6882 case MGN_MCS10: rateIndex = 22; break;
6883 case MGN_MCS11: rateIndex = 23; break;
6884 case MGN_MCS12: rateIndex = 24; break;
6885 case MGN_MCS13: rateIndex = 25; break;
6886 case MGN_MCS14: rateIndex = 26; break;
6887 case MGN_MCS15: rateIndex = 27; break;
6888 default: rateIndex = 28; break;
6890 priv->stats.received_preamble_GI[preamble_guardinterval][rateIndex]++;
6891 priv->stats.received_rate_histogram[0][rateIndex]++; //total
6892 priv->stats.received_rate_histogram[rcvType][rateIndex]++;
6895 void rtl8192SU_query_rxdesc_status(struct sk_buff *skb, struct ieee80211_rx_stats *stats, bool bIsRxAggrSubframe)
6897 rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
6898 struct net_device *dev=info->dev;
6899 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
6900 //rx_desc_819x_usb *desc = (rx_desc_819x_usb *)skb->data;
6901 rx_drvinfo_819x_usb *driver_info = NULL;
6903 //PRT_RFD_STATUS pRtRfdStatus = &pRfd->Status;
6904 //PHAL_DATA_8192SUSB pHalData = GET_HAL_DATA(Adapter);
6905 //pu1Byte pDesc = (pu1Byte)pDescIn;
6906 //PRX_DRIVER_INFO_8192S pDrvInfo;
6908 rx_desc_819x_usb *desc = (rx_desc_819x_usb *)skb->data;
6910 if(0)
6912 int m = 0;
6913 printk("========================");
6914 for(m=0; m<skb->len; m++){
6915 if((m%32) == 0)
6916 printk("\n");
6917 printk("%2x ",((u8*)skb->data)[m]);
6919 printk("\n========================\n");
6925 //Get Rx Descriptor Raw Information
6927 stats->Length = desc->Length ;
6928 stats->RxDrvInfoSize = desc->RxDrvInfoSize*RX_DRV_INFO_SIZE_UNIT;
6929 stats->RxBufShift = (desc->Shift)&0x03;
6930 stats->bICV = desc->ICV;
6931 stats->bCRC = desc->CRC32;
6932 stats->bHwError = stats->bCRC|stats->bICV;
6933 stats->Decrypted = !desc->SWDec;//RTL8190 set this bit to indicate that Hw does not decrypt packet
6934 stats->bIsAMPDU = (desc->AMSDU==1);
6935 stats->bFirstMPDU = (desc->PAGGR==1) && (desc->FAGGR==1);
6936 stats->bShortPreamble = desc->SPLCP;
6937 stats->RxIs40MHzPacket = (desc->BW==1);
6938 stats->TimeStampLow = desc->TSFL;
6940 if((desc->FAGGR==1) || (desc->PAGGR==1))
6941 {// Rx A-MPDU
6942 RT_TRACE(COMP_RXDESC, "FirstAGGR = %d, PartAggr = %d\n", desc->FAGGR, desc->PAGGR);
6944 //YJ,test,090310
6945 if(stats->bHwError)
6947 if(stats->bICV)
6948 printk("%s: Receive ICV error!!!!!!!!!!!!!!!!!!!!!!\n", __FUNCTION__);
6949 if(stats->bCRC)
6950 printk("%s: Receive CRC error!!!!!!!!!!!!!!!!!!!!!!\n", __FUNCTION__);
6953 if(IS_UNDER_11N_AES_MODE(priv->ieee80211))
6955 // Always received ICV error packets in AES mode.
6956 // This fixed HW later MIC write bug.
6957 if(stats->bICV && !stats->bCRC)
6959 stats->bICV = FALSE;
6960 stats->bHwError = FALSE;
6964 // Transform HwRate to MRate
6965 if(!stats->bHwError)
6966 //stats->DataRate = HwRateToMRate(
6967 // (BOOLEAN)GET_RX_DESC_RXHT(pDesc),
6968 // (u1Byte)GET_RX_DESC_RXMCS(pDesc),
6969 // (BOOLEAN)GET_RX_DESC_PAGGR(pDesc));
6970 stats->rate = rtl8192SU_HwRateToMRate(desc->RxHT, desc->RxMCS, desc->PAGGR);
6971 else
6972 stats->rate = MGN_1M;
6975 // Collect Rx rate/AMPDU/TSFL
6977 //UpdateRxdRateHistogramStatistics8192S(Adapter, pRfd);
6978 //UpdateRxAMPDUHistogramStatistics8192S(Adapter, pRfd);
6979 //UpdateRxPktTimeStamp8192S(Adapter, pRfd);
6980 UpdateReceivedRateHistogramStatistics8190(dev, stats);
6981 //UpdateRxAMPDUHistogramStatistics8192S(dev, stats); //FIXLZM
6982 UpdateRxPktTimeStamp8190(dev, stats);
6985 // Get PHY Status and RSVD parts.
6986 // <Roger_Notes> It only appears on last aggregated packet.
6988 if (desc->PHYStatus)
6990 //driver_info = (rx_drvinfo_819x_usb *)(skb->data + RX_DESC_SIZE + stats->RxBufShift);
6991 driver_info = (rx_drvinfo_819x_usb *)(skb->data + sizeof(rx_desc_819x_usb) + \
6992 stats->RxBufShift);
6993 if(0)
6995 int m = 0;
6996 printk("========================\n");
6997 printk("RX_DESC_SIZE:%d, RxBufShift:%d, RxDrvInfoSize:%d\n",
6998 RX_DESC_SIZE, stats->RxBufShift, stats->RxDrvInfoSize);
6999 for(m=0; m<32; m++){
7000 printk("%2x ",((u8*)driver_info)[m]);
7002 printk("\n========================\n");
7008 //YJ,add,090107
7009 skb_pull(skb, sizeof(rx_desc_819x_usb));
7010 //YJ,add,090107,end
7013 // Get Total offset of MPDU Frame Body
7015 if((stats->RxBufShift + stats->RxDrvInfoSize) > 0)
7017 stats->bShift = 1;
7018 //YJ,add,090107
7019 skb_pull(skb, stats->RxBufShift + stats->RxDrvInfoSize);
7020 //YJ,add,090107,end
7024 // Get PHY Status and RSVD parts.
7025 // <Roger_Notes> It only appears on last aggregated packet.
7027 if (desc->PHYStatus)
7029 rtl8192SU_TranslateRxSignalStuff(skb, stats, desc, driver_info);
7034 // Description:
7035 // The strarting address of wireless lan header will shift 1 or 2 or 3 or "more" bytes for the following reason :
7036 // (1) QoS control : shift 2 bytes
7037 // (2) Mesh Network : shift 1 or 3 bytes
7038 // (3) RxDriverInfo occupies the front parts of Rx Packets buffer(shift units is in 8Bytes)
7040 // It is because Lextra CPU used by 8186 or 865x series assert exception if the statrting address
7041 // of IP header is not double word alignment.
7042 // This features is supported in 818xb and 8190 only, but not 818x.
7044 // parameter: PRT_RFD, Pointer of Reeceive frame descriptor which is initialized according to
7045 // Rx Descriptor
7046 // return value: unsigned int, number of total shifted bytes
7048 // Notes: 2008/06/28, created by Roger
7050 u32 GetRxPacketShiftBytes8192SU(struct ieee80211_rx_stats *Status, bool bIsRxAggrSubframe)
7052 //PRT_RFD_STATUS pRtRfdStatus = &pRfd->Status;
7054 return (sizeof(rx_desc_819x_usb) + Status->RxDrvInfoSize + Status->RxBufShift);
7057 void rtl8192SU_rx_nomal(struct sk_buff* skb)
7059 rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
7060 struct net_device *dev=info->dev;
7061 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
7062 struct ieee80211_rx_stats stats = {
7063 .signal = 0,
7064 .noise = -98,
7065 .rate = 0,
7066 // .mac_time = jiffies,
7067 .freq = IEEE80211_24GHZ_BAND,
7069 u32 rx_pkt_len = 0;
7070 struct ieee80211_hdr_1addr *ieee80211_hdr = NULL;
7071 bool unicast_packet = false;
7073 //printk("**********skb->len = %d\n", skb->len);
7074 /* 20 is for ps-poll */
7075 if((skb->len >=(20 + sizeof(rx_desc_819x_usb))) && (skb->len < RX_URB_SIZE)) {
7077 /* first packet should not contain Rx aggregation header */
7078 rtl8192SU_query_rxdesc_status(skb, &stats, false);
7079 /* TODO */
7081 /* hardware related info */
7082 priv->stats.rxoktotal++; //YJ,test,090108
7084 /* Process the MPDU recevied */
7085 skb_trim(skb, skb->len - 4/*sCrcLng*/);//FIXLZM
7087 rx_pkt_len = skb->len;
7088 ieee80211_hdr = (struct ieee80211_hdr_1addr *)skb->data;
7089 unicast_packet = false;
7090 if(is_broadcast_ether_addr(ieee80211_hdr->addr1)) {
7091 //TODO
7092 }else if(is_multicast_ether_addr(ieee80211_hdr->addr1)){
7093 //TODO
7094 }else {
7095 /* unicast packet */
7096 unicast_packet = true;
7099 if(!ieee80211_rtl_rx(priv->ieee80211,skb, &stats)) {
7100 dev_kfree_skb_any(skb);
7101 } else {
7102 // priv->stats.rxoktotal++; //YJ,test,090108
7103 if(unicast_packet) {
7104 priv->stats.rxbytesunicast += rx_pkt_len;
7108 //up is firs pkt, follow is next and next
7110 else
7112 priv->stats.rxurberr++;
7113 printk("actual_length:%d\n", skb->len);
7114 dev_kfree_skb_any(skb);
7119 void
7120 rtl819xusb_process_received_packet(
7121 struct net_device *dev,
7122 struct ieee80211_rx_stats *pstats
7125 // bool bfreerfd=false, bqueued=false;
7126 u8* frame;
7127 u16 frame_len=0;
7128 struct r8192_priv *priv = ieee80211_priv(dev);
7129 // u8 index = 0;
7130 // u8 TID = 0;
7131 //u16 seqnum = 0;
7132 //PRX_TS_RECORD pts = NULL;
7134 // Get shifted bytes of Starting address of 802.11 header. 2006.09.28, by Emily
7135 //porting by amy 080508
7136 pstats->virtual_address += get_rxpacket_shiftbytes_819xusb(pstats);
7137 frame = pstats->virtual_address;
7138 frame_len = pstats->packetlength;
7139 #ifdef TODO // by amy about HCT
7140 if(!Adapter->bInHctTest)
7141 CountRxErrStatistics(Adapter, pRfd);
7142 #endif
7144 #ifdef ENABLE_PS //by amy for adding ps function in future
7145 RT_RF_POWER_STATE rtState;
7146 // When RF is off, we should not count the packet for hw/sw synchronize
7147 // reason, ie. there may be a duration while sw switch is changed and hw
7148 // switch is being changed. 2006.12.04, by shien chang.
7149 Adapter->HalFunc.GetHwRegHandler(Adapter, HW_VAR_RF_STATE, (u8* )(&rtState));
7150 if (rtState == eRfOff)
7152 return;
7154 #endif
7155 priv->stats.rxframgment++;
7158 #ifdef TODO
7159 RmMonitorSignalStrength(Adapter, pRfd);
7160 #endif
7161 /* 2007/01/16 MH Add RX command packet handle here. */
7162 /* 2007/03/01 MH We have to release RFD and return if rx pkt is cmd pkt. */
7163 if (rtl819xusb_rx_command_packet(dev, pstats))
7165 return;
7168 #ifdef SW_CRC_CHECK
7169 SwCrcCheck();
7170 #endif
7175 void query_rx_cmdpkt_desc_status(struct sk_buff *skb, struct ieee80211_rx_stats *stats)
7177 // rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
7178 // struct net_device *dev=info->dev;
7179 // struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
7180 rx_desc_819x_usb *desc = (rx_desc_819x_usb *)skb->data;
7181 // rx_drvinfo_819x_usb *driver_info;
7184 //Get Rx Descriptor Information
7186 stats->virtual_address = (u8*)skb->data;
7187 stats->Length = desc->Length;
7188 stats->RxDrvInfoSize = 0;
7189 stats->RxBufShift = 0;
7190 stats->packetlength = stats->Length-scrclng;
7191 stats->fraglength = stats->packetlength;
7192 stats->fragoffset = 0;
7193 stats->ntotalfrag = 1;
7196 void rtl8192SU_rx_cmd(struct sk_buff *skb)
7198 struct rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
7199 struct net_device *dev = info->dev;
7201 /* TODO */
7202 struct ieee80211_rx_stats stats = {
7203 .signal = 0,
7204 .noise = -98,
7205 .rate = 0,
7206 // .mac_time = jiffies,
7207 .freq = IEEE80211_24GHZ_BAND,
7211 // Check buffer length to determine if this is a valid MPDU.
7213 if( (skb->len >= sizeof(rx_desc_819x_usb)) && (skb->len <= RX_URB_SIZE) )//&&
7214 //(pHalData->SwChnlInProgress == FALSE))
7217 // Collection information in Rx descriptor.
7219 query_rx_cmdpkt_desc_status(skb,&stats);
7220 // this is to be done by amy 080508 prfd->queue_id = 1;
7223 // Process the MPDU recevied.
7225 rtl819xusb_process_received_packet(dev,&stats);
7227 dev_kfree_skb_any(skb);
7229 else
7231 //RTInsertTailListWithCnt(&pAdapter->RfdIdleQueue, &pRfd->List, &pAdapter->NumIdleRfd);
7232 //RT_ASSERT(pAdapter->NumIdleRfd <= pAdapter->NumRfd, ("HalUsbInCommandComplete8192SUsb(): Adapter->NumIdleRfd(%d)\n", pAdapter->NumIdleRfd));
7233 //RT_TRACE(COMP_RECV, DBG_LOUD, ("HalUsbInCommandComplete8192SUsb(): NOT enough Resources!! BufLenUsed(%d), NumIdleRfd(%d)\n",
7234 //pContext->BufLenUsed, pAdapter->NumIdleRfd));
7238 // Reuse USB_IN_CONTEXT since we had finished processing the
7239 // buffer in USB_IN_CONTEXT.
7241 //HalUsbReturnInContext(pAdapter, pContext);
7244 // Issue another bulk IN transfer.
7246 //HalUsbInMpdu(pAdapter, PipeIndex);
7248 RT_TRACE(COMP_RECV, "<--- HalUsbInCommandComplete8192SUsb()\n");
7252 void rtl8192_irq_rx_tasklet(struct r8192_priv *priv)
7254 struct sk_buff *skb;
7255 struct rtl8192_rx_info *info;
7257 while (NULL != (skb = skb_dequeue(&priv->skb_queue))) {
7258 info = (struct rtl8192_rx_info *)skb->cb;
7259 switch (info->out_pipe) {
7260 /* Nomal packet pipe */
7261 case 3:
7262 //RT_TRACE(COMP_RECV, "normal in-pipe index(%d)\n",info->out_pipe);
7263 priv->IrpPendingCount--;
7264 priv->ops->rtl819x_rx_nomal(skb);
7265 break;
7267 /* Command packet pipe */
7268 case 9:
7269 RT_TRACE(COMP_RECV, "command in-pipe index(%d)\n",\
7270 info->out_pipe);
7271 priv->ops->rtl819x_rx_cmd(skb);
7272 break;
7274 default: /* should never get here! */
7275 RT_TRACE(COMP_ERR, "Unknown in-pipe index(%d)\n",\
7276 info->out_pipe);
7277 dev_kfree_skb(skb);
7278 break;
7286 /****************************************************************************
7287 ---------------------------- USB_STUFF---------------------------
7288 *****************************************************************************/
7289 //LZM Merge from windows HalUsbSetQueuePipeMapping8192SUsb 090319
7290 static void HalUsbSetQueuePipeMapping8192SUsb(struct usb_interface *intf, struct net_device *dev)
7292 struct r8192_priv *priv = ieee80211_priv(dev);
7293 struct usb_host_interface *iface_desc;
7294 struct usb_endpoint_descriptor *endpoint;
7295 u8 i = 0;
7297 priv->ep_in_num = 0;
7298 priv->ep_out_num = 0;
7299 memset(priv->RtOutPipes,0,16);
7300 memset(priv->RtInPipes,0,16);
7302 iface_desc = intf->cur_altsetting;
7303 priv->ep_num = iface_desc->desc.bNumEndpoints;
7305 for (i = 0; i < priv->ep_num; ++i) {
7306 endpoint = &iface_desc->endpoint[i].desc;
7307 if (usb_endpoint_is_bulk_in(endpoint)) {
7308 priv->RtInPipes[priv->ep_in_num] = usb_endpoint_num(endpoint);
7309 priv->ep_in_num ++;
7310 //printk("in_endpoint_idx = %d\n", usb_endpoint_num(endpoint));
7311 } else if (usb_endpoint_is_bulk_out(endpoint)) {
7312 priv->RtOutPipes[priv->ep_out_num] = usb_endpoint_num(endpoint);
7313 priv->ep_out_num ++;
7314 //printk("out_endpoint_idx = %d\n", usb_endpoint_num(endpoint));
7318 memset(priv->txqueue_to_outpipemap,0,9);
7319 if (priv->ep_num == 6) {
7320 // BK, BE, VI, VO, HCCA, TXCMD, MGNT, HIGH, BEACON
7321 u8 queuetopipe[] = {3, 2, 1, 0, 4, 4, 4, 4, 4};
7323 memcpy(priv->txqueue_to_outpipemap,queuetopipe,9);
7324 } else if (priv->ep_num == 4) {
7325 // BK, BE, VI, VO, HCCA, TXCMD, MGNT, HIGH, BEACON
7326 u8 queuetopipe[] = {1, 1, 0, 0, 2, 2, 2, 2, 2};
7328 memcpy(priv->txqueue_to_outpipemap,queuetopipe,9);
7329 } else if (priv->ep_num > 9) {
7330 // BK, BE, VI, VO, HCCA, TXCMD, MGNT, HIGH, BEACON
7331 u8 queuetopipe[] = {3, 2, 1, 0, 4, 8, 7, 6, 5};
7333 memcpy(priv->txqueue_to_outpipemap,queuetopipe,9);
7334 } else {//use sigle pipe
7335 // BK, BE, VI, VO, HCCA, TXCMD, MGNT, HIGH, BEACON
7336 u8 queuetopipe[] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
7337 memcpy(priv->txqueue_to_outpipemap,queuetopipe,9);
7340 printk("==>ep_num:%d, in_ep_num:%d, out_ep_num:%d\n", priv->ep_num, priv->ep_in_num, priv->ep_out_num);
7342 printk("==>RtInPipes:");
7343 for(i=0; i < priv->ep_in_num; i++)
7344 printk("%d ", priv->RtInPipes[i]);
7345 printk("\n");
7347 printk("==>RtOutPipes:");
7348 for(i=0; i < priv->ep_out_num; i++)
7349 printk("%d ", priv->RtOutPipes[i]);
7350 printk("\n");
7352 printk("==>txqueue_to_outpipemap for BK, BE, VI, VO, HCCA, TXCMD, MGNT, HIGH, BEACON:\n");
7353 for(i=0; i < 9; i++)
7354 printk("%d ", priv->txqueue_to_outpipemap[i]);
7355 printk("\n");
7357 return;
7360 static const struct net_device_ops rtl8192_netdev_ops = {
7361 .ndo_open = rtl8192_open,
7362 .ndo_stop = rtl8192_close,
7363 .ndo_get_stats = rtl8192_stats,
7364 .ndo_tx_timeout = tx_timeout,
7365 .ndo_do_ioctl = rtl8192_ioctl,
7366 .ndo_set_multicast_list = r8192_set_multicast,
7367 .ndo_set_mac_address = r8192_set_mac_adr,
7368 .ndo_validate_addr = eth_validate_addr,
7369 .ndo_change_mtu = eth_change_mtu,
7370 .ndo_start_xmit = rtl8192_ieee80211_rtl_xmit,
7373 static int __devinit rtl8192_usb_probe(struct usb_interface *intf,
7374 const struct usb_device_id *id)
7376 // unsigned long ioaddr = 0;
7377 struct net_device *dev = NULL;
7378 struct r8192_priv *priv= NULL;
7379 struct usb_device *udev = interface_to_usbdev(intf);
7381 RT_TRACE(COMP_INIT, "Oops: i'm coming\n");
7383 dev = alloc_ieee80211(sizeof(struct r8192_priv));
7384 if (dev == NULL)
7385 return -ENOMEM;
7387 usb_set_intfdata(intf, dev);
7388 SET_NETDEV_DEV(dev, &intf->dev);
7389 priv = ieee80211_priv(dev);
7390 priv->ieee80211 = netdev_priv(dev);
7391 priv->udev=udev;
7393 HalUsbSetQueuePipeMapping8192SUsb(intf, dev);
7395 //printk("===============>NIC 8192SU\n");
7396 priv->ops = &rtl8192su_ops;
7398 dev->netdev_ops = &rtl8192_netdev_ops;
7400 //DMESG("Oops: i'm coming\n");
7401 dev->wireless_handlers = (struct iw_handler_def *) &r8192_wx_handlers_def;
7403 dev->type=ARPHRD_ETHER;
7405 dev->watchdog_timeo = HZ*3; //modified by john, 0805
7407 if (dev_alloc_name(dev, ifname) < 0){
7408 RT_TRACE(COMP_INIT, "Oops: devname already taken! Trying wlan%%d...\n");
7409 ifname = "wlan%d";
7410 dev_alloc_name(dev, ifname);
7413 RT_TRACE(COMP_INIT, "Driver probe completed1\n");
7414 #if 1
7415 if(rtl8192_init(dev)!=0){
7416 RT_TRACE(COMP_ERR, "Initialization failed");
7417 goto fail;
7419 #endif
7420 netif_carrier_off(dev);
7421 netif_stop_queue(dev);
7423 if (register_netdev(dev))
7424 goto fail;
7425 RT_TRACE(COMP_INIT, "dev name=======> %s\n",dev->name);
7426 rtl8192_proc_init_one(dev);
7429 RT_TRACE(COMP_INIT, "Driver probe completed\n");
7430 return 0;
7431 fail:
7432 free_ieee80211(dev);
7434 RT_TRACE(COMP_ERR, "wlan driver load failed\n");
7435 return -ENODEV;
7438 //detach all the work and timer structure declared or inititialize in r8192U_init function.
7439 void rtl8192_cancel_deferred_work(struct r8192_priv* priv)
7441 cancel_work_sync(&priv->reset_wq);
7442 cancel_work_sync(&priv->qos_activate);
7443 cancel_delayed_work(&priv->watch_dog_wq);
7444 cancel_delayed_work(&priv->update_beacon_wq);
7445 cancel_delayed_work(&priv->ieee80211->hw_wakeup_wq);
7446 cancel_delayed_work(&priv->ieee80211->hw_sleep_wq);
7447 //cancel_work_sync(&priv->SetBWModeWorkItem);
7448 //cancel_work_sync(&priv->SwChnlWorkItem);
7451 static void __devexit rtl8192_usb_disconnect(struct usb_interface *intf)
7453 struct net_device *dev = usb_get_intfdata(intf);
7454 struct r8192_priv *priv = ieee80211_priv(dev);
7455 if(dev){
7457 unregister_netdev(dev);
7459 RT_TRACE(COMP_DOWN, "=============>wlan driver to be removed\n");
7460 rtl8192_proc_remove_one(dev);
7462 rtl8192_down(dev);
7463 if (priv->pFirmware)
7465 vfree(priv->pFirmware);
7466 priv->pFirmware = NULL;
7468 // priv->rf_close(dev);
7469 // rtl8192_SetRFPowerState(dev, eRfOff);
7470 destroy_workqueue(priv->priv_wq);
7471 //rtl8192_irq_disable(dev);
7472 //rtl8192_reset(dev);
7473 mdelay(10);
7476 free_ieee80211(dev);
7477 RT_TRACE(COMP_DOWN, "wlan driver removed\n");
7480 /* fun with the built-in ieee80211 stack... */
7481 extern int ieee80211_debug_init(void);
7482 extern void ieee80211_debug_exit(void);
7483 extern int ieee80211_crypto_init(void);
7484 extern void ieee80211_crypto_deinit(void);
7485 extern int ieee80211_crypto_tkip_init(void);
7486 extern void ieee80211_crypto_tkip_exit(void);
7487 extern int ieee80211_crypto_ccmp_init(void);
7488 extern void ieee80211_crypto_ccmp_exit(void);
7489 extern int ieee80211_crypto_wep_init(void);
7490 extern void ieee80211_crypto_wep_exit(void);
7492 static int __init rtl8192_usb_module_init(void)
7494 int ret;
7496 #ifdef CONFIG_IEEE80211_DEBUG
7497 ret = ieee80211_debug_init();
7498 if (ret) {
7499 printk(KERN_ERR "ieee80211_debug_init() failed %d\n", ret);
7500 return ret;
7502 #endif
7503 ret = ieee80211_crypto_init();
7504 if (ret) {
7505 printk(KERN_ERR "ieee80211_crypto_init() failed %d\n", ret);
7506 goto fail_crypto;
7509 ret = ieee80211_crypto_tkip_init();
7510 if (ret) {
7511 printk(KERN_ERR "ieee80211_crypto_tkip_init() failed %d\n",
7512 ret);
7513 goto fail_crypto_tkip;
7516 ret = ieee80211_crypto_ccmp_init();
7517 if (ret) {
7518 printk(KERN_ERR "ieee80211_crypto_ccmp_init() failed %d\n",
7519 ret);
7520 goto fail_crypto_ccmp;
7523 ret = ieee80211_crypto_wep_init();
7524 if (ret) {
7525 printk(KERN_ERR "ieee80211_crypto_wep_init() failed %d\n", ret);
7526 goto fail_crypto_wep;
7529 printk(KERN_INFO "\nLinux kernel driver for RTL8192 based WLAN cards\n");
7530 printk(KERN_INFO "Copyright (c) 2007-2008, Realsil Wlan\n");
7531 RT_TRACE(COMP_INIT, "Initializing module");
7532 RT_TRACE(COMP_INIT, "Wireless extensions version %d", WIRELESS_EXT);
7534 ret = rtl8192_proc_module_init();
7535 if (ret) {
7536 pr_err("rtl8192_proc_module_init() failed %d\n", ret);
7537 goto fail_proc;
7540 ret = usb_register(&rtl8192_usb_driver);
7541 if (ret) {
7542 pr_err("usb_register() failed %d\n", ret);
7543 goto fail_usb;
7546 return 0;
7548 fail_usb:
7549 rtl8192_proc_module_remove();
7550 fail_proc:
7551 ieee80211_crypto_wep_exit();
7552 fail_crypto_wep:
7553 ieee80211_crypto_ccmp_exit();
7554 fail_crypto_ccmp:
7555 ieee80211_crypto_tkip_exit();
7556 fail_crypto_tkip:
7557 ieee80211_crypto_deinit();
7558 fail_crypto:
7559 #ifdef CONFIG_IEEE80211_DEBUG
7560 ieee80211_debug_exit();
7561 #endif
7562 return ret;
7566 static void __exit rtl8192_usb_module_exit(void)
7568 usb_deregister(&rtl8192_usb_driver);
7570 RT_TRACE(COMP_DOWN, "Exiting");
7571 rtl8192_proc_module_remove();
7573 ieee80211_crypto_tkip_exit();
7574 ieee80211_crypto_ccmp_exit();
7575 ieee80211_crypto_wep_exit();
7576 ieee80211_crypto_deinit();
7577 #ifdef CONFIG_IEEE80211_DEBUG
7578 ieee80211_debug_exit();
7579 #endif
7583 void rtl8192_try_wake_queue(struct net_device *dev, int pri)
7585 unsigned long flags;
7586 short enough_desc;
7587 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
7589 spin_lock_irqsave(&priv->tx_lock,flags);
7590 enough_desc = check_nic_enough_desc(dev,pri);
7591 spin_unlock_irqrestore(&priv->tx_lock,flags);
7593 if(enough_desc)
7594 ieee80211_rtl_wake_queue(priv->ieee80211);
7597 void EnableHWSecurityConfig8192(struct net_device *dev)
7599 u8 SECR_value = 0x0;
7600 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
7601 struct ieee80211_device *ieee = priv->ieee80211;
7603 SECR_value = SCR_TxEncEnable | SCR_RxDecEnable;
7604 switch (ieee->pairwise_key_type) {
7605 case KEY_TYPE_WEP40:
7606 case KEY_TYPE_WEP104:
7607 if (priv->ieee80211->auth_mode != 2) {
7608 SECR_value |= SCR_RxUseDK;
7609 SECR_value |= SCR_TxUseDK;
7611 break;
7612 case KEY_TYPE_TKIP:
7613 case KEY_TYPE_CCMP:
7614 if (ieee->iw_mode == IW_MODE_ADHOC) {
7615 SECR_value |= SCR_RxUseDK;
7616 SECR_value |= SCR_TxUseDK;
7618 break;
7619 default:
7620 break;
7624 * add HWSec active enable here.
7625 * default using hwsec.
7626 * when peer AP is in N mode only and pairwise_key_type is none_aes
7627 * (which HT_IOT_ACT_PURE_N_MODE indicates it),
7628 * use software security.
7629 * when peer AP is in b,g,n mode mixed and pairwise_key_type is none_aes
7630 * use g mode hw security.
7632 ieee->hwsec_active = 1;
7634 /* add hwsec_support flag to totol control hw_sec on/off */
7635 if ((ieee->pHTInfo->IOTAction&HT_IOT_ACT_PURE_N_MODE) || !hwwep) {
7636 ieee->hwsec_active = 0;
7637 SECR_value &= ~SCR_RxDecEnable;
7640 RT_TRACE(COMP_SEC, "%s(): hwsec: %d, pairwise_key: %d, "
7641 "SECR_value: %x",
7642 __func__, ieee->hwsec_active,
7643 ieee->pairwise_key_type, SECR_value);
7645 write_nic_byte(dev, SECR, SECR_value); /* SECR_value | SCR_UseDK ); */
7649 void setKey(struct net_device *dev,
7650 u8 EntryNo,
7651 u8 KeyIndex,
7652 u16 KeyType,
7653 u8 *MacAddr,
7654 u8 DefaultKey,
7655 u32 *KeyContent)
7657 u32 TargetCommand = 0;
7658 u32 TargetContent = 0;
7659 u16 usConfig = 0;
7660 u8 i;
7662 if (EntryNo >= TOTAL_CAM_ENTRY)
7663 RT_TRACE(COMP_ERR, "%s(): cam entry exceeds TOTAL_CAM_ENTRY",
7664 __func__);
7666 RT_TRACE(COMP_SEC, "%s(): dev: %p, EntryNo: %d, "
7667 "KeyIndex: %d, KeyType: %d, MacAddr: %pM",
7668 __func__, dev, EntryNo,
7669 KeyIndex, KeyType, MacAddr);
7671 if (DefaultKey)
7672 usConfig |= BIT15 | (KeyType << 2);
7673 else
7674 usConfig |= BIT15 | (KeyType << 2) | KeyIndex;
7676 for (i = 0 ; i < CAM_CONTENT_COUNT; i++) {
7677 TargetCommand = i + CAM_CONTENT_COUNT * EntryNo;
7678 TargetCommand |= BIT31|BIT16;
7679 switch (i) {
7680 case 0: /* MAC|Config */
7681 TargetContent = (u32)(*(MacAddr + 0)) << 16|
7682 (u32)(*(MacAddr + 1)) << 24|
7683 (u32)usConfig;
7685 write_nic_dword(dev, WCAMI, TargetContent);
7686 write_nic_dword(dev, RWCAM, TargetCommand);
7687 continue;
7688 case 1: /* MAC */
7689 TargetContent = (u32)(*(MacAddr + 2))|
7690 (u32)(*(MacAddr + 3)) << 8|
7691 (u32)(*(MacAddr + 4)) << 16|
7692 (u32)(*(MacAddr + 5)) << 24;
7693 write_nic_dword(dev, WCAMI, TargetContent);
7694 write_nic_dword(dev, RWCAM, TargetCommand);
7695 continue;
7696 default: /* Key Material */
7697 if (KeyContent != NULL) {
7698 write_nic_dword(dev, WCAMI,
7699 (u32)(*(KeyContent+i-2)));
7700 write_nic_dword(dev, RWCAM,
7701 TargetCommand);
7703 continue;
7708 /***************************************************************************
7709 ------------------- module init / exit stubs ----------------
7710 ****************************************************************************/
7711 module_init(rtl8192_usb_module_init);
7712 module_exit(rtl8192_usb_module_exit);