hrtimer: Add tracepoint for hrtimers
[linux-2.6/cjktty.git] / drivers / staging / rtl8192su / r8192U_core.c
blob70f81a8f12913b7e2ccda789331f2343fc28eda5
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 #ifndef CONFIG_FORCE_HARD_FLOAT
28 double __floatsidf (int i) { return i; }
29 unsigned int __fixunsdfsi (double d) { return d; }
30 double __adddf3(double a, double b) { return a+b; }
31 double __addsf3(float a, float b) { return a+b; }
32 double __subdf3(double a, double b) { return a-b; }
33 double __extendsfdf2(float a) {return a;}
34 #endif
36 #undef LOOP_TEST
37 #undef DUMP_RX
38 #undef DUMP_TX
39 #undef DEBUG_TX_DESC2
40 #undef RX_DONT_PASS_UL
41 #undef DEBUG_EPROM
42 #undef DEBUG_RX_VERBOSE
43 #undef DUMMY_RX
44 #undef DEBUG_ZERO_RX
45 #undef DEBUG_RX_SKB
46 #undef DEBUG_TX_FRAG
47 #undef DEBUG_RX_FRAG
48 #undef DEBUG_TX_FILLDESC
49 #undef DEBUG_TX
50 #undef DEBUG_IRQ
51 #undef DEBUG_RX
52 #undef DEBUG_RXALLOC
53 #undef DEBUG_REGISTERS
54 #undef DEBUG_RING
55 #undef DEBUG_IRQ_TASKLET
56 #undef DEBUG_TX_ALLOC
57 #undef DEBUG_TX_DESC
59 #define CONFIG_RTL8192_IO_MAP
61 #ifdef RTL8192SU
62 #include <asm/uaccess.h>
63 #include "r8192U.h"
64 //#include "r8190_rtl8256.h" /* RTL8225 Radio frontend */
65 #include "r8180_93cx6.h" /* Card EEPROM */
66 #include "r8192U_wx.h"
68 #include "r8192S_rtl8225.h"
69 #include "r8192S_hw.h"
70 #include "r8192S_phy.h"
71 #include "r8192S_phyreg.h"
72 #include "r8192S_Efuse.h"
74 #include "r819xU_cmdpkt.h"
75 #include "r8192U_dm.h"
76 //#include "r8192xU_phyreg.h"
77 #include <linux/usb.h>
78 // FIXME: check if 2.6.7 is ok
79 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,7))
80 #define usb_kill_urb usb_unlink_urb
81 #endif
83 #ifdef CONFIG_RTL8192_PM
84 #include "r8192U_pm.h"
85 #endif
87 #ifdef ENABLE_DOT11D
88 #include "dot11d.h"
89 #endif
91 #else
93 #include <asm/uaccess.h>
94 #include "r8192U_hw.h"
95 #include "r8192U.h"
96 #include "r8190_rtl8256.h" /* RTL8225 Radio frontend */
97 #include "r8180_93cx6.h" /* Card EEPROM */
98 #include "r8192U_wx.h"
99 #include "r819xU_phy.h" //added by WB 4.30.2008
100 #include "r819xU_phyreg.h"
101 #include "r819xU_cmdpkt.h"
102 #include "r8192U_dm.h"
103 //#include "r8192xU_phyreg.h"
104 #include <linux/usb.h>
105 // FIXME: check if 2.6.7 is ok
106 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,7))
107 #define usb_kill_urb usb_unlink_urb
108 #endif
110 #ifdef CONFIG_RTL8192_PM
111 #include "r8192U_pm.h"
112 #endif
114 #ifdef ENABLE_DOT11D
115 #include "dot11d.h"
116 #endif
118 #endif
121 #ifdef RTL8192SU
122 u32 rt_global_debug_component = \
123 // COMP_TRACE |
124 // COMP_DBG |
125 // COMP_INIT |
126 // COMP_RECV |
127 // COMP_SEND |
128 // COMP_IO |
129 COMP_POWER |
130 // COMP_EPROM |
131 COMP_SWBW |
132 COMP_POWER_TRACKING |
133 COMP_TURBO |
134 COMP_QOS |
135 // COMP_RATE |
136 // COMP_RM |
137 COMP_DIG |
138 // COMP_EFUSE |
139 // COMP_CH |
140 // COMP_TXAGC |
141 COMP_HIPWR |
142 // COMP_HALDM |
143 COMP_SEC |
144 COMP_LED |
145 // COMP_RF |
146 // COMP_RXDESC |
147 COMP_FIRMWARE |
148 COMP_HT |
149 COMP_AMSDU |
150 COMP_SCAN |
151 // COMP_CMD |
152 COMP_DOWN |
153 COMP_RESET |
154 COMP_ERR; //always open err flags on
155 #else
156 //set here to open your trace code. //WB
157 u32 rt_global_debug_component = \
158 // COMP_INIT |
159 // COMP_DBG |
160 // COMP_EPROM |
161 // COMP_PHY |
162 // COMP_RF |
163 // COMP_FIRMWARE |
164 // COMP_CH |
165 // COMP_POWER_TRACKING |
166 // COMP_RATE |
167 // COMP_TXAGC |
168 // COMP_TRACE |
169 COMP_DOWN |
170 // COMP_RECV |
171 // COMP_SWBW |
172 COMP_SEC |
173 // COMP_RESET |
174 // COMP_SEND |
175 // COMP_EVENTS |
176 COMP_ERR ; //always open err flags on
177 #endif
179 #define TOTAL_CAM_ENTRY 32
180 #define CAM_CONTENT_COUNT 8
182 static struct usb_device_id rtl8192_usb_id_tbl[] = {
183 /* Realtek */
184 {USB_DEVICE(0x0bda, 0x8192)},
185 {USB_DEVICE(0x0bda, 0x8709)},
186 /* Corega */
187 {USB_DEVICE(0x07aa, 0x0043)},
188 /* Belkin */
189 {USB_DEVICE(0x050d, 0x805E)},
190 /* Sitecom */
191 {USB_DEVICE(0x0df6, 0x0031)},
192 /* EnGenius */
193 {USB_DEVICE(0x1740, 0x9201)},
194 /* Dlink */
195 {USB_DEVICE(0x2001, 0x3301)},
196 /* Zinwell */
197 {USB_DEVICE(0x5a57, 0x0290)},
198 //92SU
199 {USB_DEVICE(0x0bda, 0x8172)},
203 MODULE_LICENSE("GPL");
204 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
205 MODULE_VERSION("V 1.1");
206 #endif
207 MODULE_DEVICE_TABLE(usb, rtl8192_usb_id_tbl);
208 MODULE_DESCRIPTION("Linux driver for Realtek RTL8192 USB WiFi cards");
210 static char* ifname = "wlan%d";
211 #if 0
212 static int hwseqnum = 0;
213 static int hwwep = 0;
214 #endif
215 static int hwwep = 1; //default use hw. set 0 to use software security
216 static int channels = 0x3fff;
220 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 9)
221 module_param(ifname, charp, S_IRUGO|S_IWUSR );
222 //module_param(hwseqnum,int, S_IRUGO|S_IWUSR);
223 module_param(hwwep,int, S_IRUGO|S_IWUSR);
224 module_param(channels,int, S_IRUGO|S_IWUSR);
225 #else
226 MODULE_PARM(ifname, "s");
227 //MODULE_PARM(hwseqnum,"i");
228 MODULE_PARM(hwwep,"i");
229 MODULE_PARM(channels,"i");
230 #endif
232 MODULE_PARM_DESC(ifname," Net interface name, wlan%d=default");
233 //MODULE_PARM_DESC(hwseqnum," Try to use hardware 802.11 header sequence numbers. Zero=default");
234 MODULE_PARM_DESC(hwwep," Try to use hardware security support. ");
235 MODULE_PARM_DESC(channels," Channel bitmask for specific locales. NYI");
237 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
238 static int __devinit rtl8192_usb_probe(struct usb_interface *intf,
239 const struct usb_device_id *id);
240 static void __devexit rtl8192_usb_disconnect(struct usb_interface *intf);
241 #else
242 static void *__devinit rtl8192_usb_probe(struct usb_device *udev,unsigned int ifnum,
243 const struct usb_device_id *id);
244 static void __devexit rtl8192_usb_disconnect(struct usb_device *udev, void *ptr);
245 #endif
248 static struct usb_driver rtl8192_usb_driver = {
249 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 15)
250 .owner = THIS_MODULE,
251 #endif
252 .name = RTL819xU_MODULE_NAME, /* Driver name */
253 .id_table = rtl8192_usb_id_tbl, /* PCI_ID table */
254 .probe = rtl8192_usb_probe, /* probe fn */
255 .disconnect = rtl8192_usb_disconnect, /* remove fn */
256 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0)
257 #ifdef CONFIG_RTL8192_PM
258 .suspend = rtl8192U_suspend, /* PM suspend fn */
259 .resume = rtl8192U_resume, /* PM resume fn */
260 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 22)
261 .reset_resume = rtl8192U_resume, /* PM reset resume fn */
262 #endif
263 #else
264 .suspend = NULL, /* PM suspend fn */
265 .resume = NULL, /* PM resume fn */
266 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 22)
267 .reset_resume = NULL, /* PM reset resume fn */
268 #endif
269 #endif
270 #endif
274 #ifdef RTL8192SU
275 static void rtl8192SU_read_eeprom_info(struct net_device *dev);
276 short rtl8192SU_tx(struct net_device *dev, struct sk_buff* skb);
277 void rtl8192SU_rx_nomal(struct sk_buff* skb);
278 void rtl8192SU_rx_cmd(struct sk_buff *skb);
279 bool rtl8192SU_adapter_start(struct net_device *dev);
280 short rtl8192SU_tx_cmd(struct net_device *dev, struct sk_buff *skb);
281 void rtl8192SU_link_change(struct net_device *dev);
282 void InitialGain8192S(struct net_device *dev,u8 Operation);
283 void rtl8192SU_query_rxdesc_status(struct sk_buff *skb, struct ieee80211_rx_stats *stats, bool bIsRxAggrSubframe);
285 struct rtl819x_ops rtl8192su_ops = {
286 .nic_type = NIC_8192SU,
287 .rtl819x_read_eeprom_info = rtl8192SU_read_eeprom_info,
288 .rtl819x_tx = rtl8192SU_tx,
289 .rtl819x_tx_cmd = rtl8192SU_tx_cmd,
290 .rtl819x_rx_nomal = rtl8192SU_rx_nomal,
291 .rtl819x_rx_cmd = rtl8192SU_rx_cmd,
292 .rtl819x_adapter_start = rtl8192SU_adapter_start,
293 .rtl819x_link_change = rtl8192SU_link_change,
294 .rtl819x_initial_gain = InitialGain8192S,
295 .rtl819x_query_rxdesc_status = rtl8192SU_query_rxdesc_status,
297 #else
298 static void rtl8192_read_eeprom_info(struct net_device *dev);
299 short rtl8192_tx(struct net_device *dev, struct sk_buff* skb);
300 void rtl8192_rx_nomal(struct sk_buff* skb);
301 void rtl8192_rx_cmd(struct sk_buff *skb);
302 bool rtl8192_adapter_start(struct net_device *dev);
303 short rtl819xU_tx_cmd(struct net_device *dev, struct sk_buff *skb);
304 void rtl8192_link_change(struct net_device *dev);
305 void InitialGain819xUsb(struct net_device *dev,u8 Operation);
306 void query_rxdesc_status(struct sk_buff *skb, struct ieee80211_rx_stats *stats, bool bIsRxAggrSubframe);
308 struct rtl819x_ops rtl8192u_ops = {
309 .nic_type = NIC_8192U,
310 .rtl819x_read_eeprom_info = rtl8192_read_eeprom_info,
311 .rtl819x_tx = rtl8192_tx,
312 .rtl819x_tx_cmd = rtl819xU_tx_cmd,
313 .rtl819x_rx_nomal = rtl8192_rx_nomal,
314 .rtl819x_rx_cmd = rtl8192_rx_cmd,
315 .rtl819x_adapter_start = rtl8192_adapter_start,
316 .rtl819x_link_change = rtl8192_link_change,
317 .rtl819x_initial_gain = InitialGain819xUsb,
318 .rtl819x_query_rxdesc_status = query_rxdesc_status,
320 #endif
322 #ifdef ENABLE_DOT11D
324 typedef struct _CHANNEL_LIST
326 u8 Channel[32];
327 u8 Len;
328 }CHANNEL_LIST, *PCHANNEL_LIST;
330 static CHANNEL_LIST ChannelPlan[] = {
331 {{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
332 {{1,2,3,4,5,6,7,8,9,10,11},11}, //IC
333 {{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48,52,56,60,64},21}, //ETSI
334 {{1,2,3,4,5,6,7,8,9,10,11,12,13},13}, //Spain. Change to ETSI.
335 {{1,2,3,4,5,6,7,8,9,10,11,12,13},13}, //France. Change to ETSI.
336 {{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
337 {{1,2,3,4,5,6,7,8,9,10,11,12,13,14,36,40,44,48,52,56,60,64},22},//MKK1
338 {{1,2,3,4,5,6,7,8,9,10,11,12,13},13}, //Israel.
339 {{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
340 {{1,2,3,4,5,6,7,8,9,10,11,12,13,14,36,40,44,48,52,56,60,64}, 22}, //MIC
341 {{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
344 static void rtl819x_set_channel_map(u8 channel_plan, struct r8192_priv* priv)
346 int i, max_chan=-1, min_chan=-1;
347 struct ieee80211_device* ieee = priv->ieee80211;
348 switch (channel_plan)
350 case COUNTRY_CODE_FCC:
351 case COUNTRY_CODE_IC:
352 case COUNTRY_CODE_ETSI:
353 case COUNTRY_CODE_SPAIN:
354 case COUNTRY_CODE_FRANCE:
355 case COUNTRY_CODE_MKK:
356 case COUNTRY_CODE_MKK1:
357 case COUNTRY_CODE_ISRAEL:
358 case COUNTRY_CODE_TELEC:
359 case COUNTRY_CODE_MIC:
361 Dot11d_Init(ieee);
362 ieee->bGlobalDomain = false;
363 //acturally 8225 & 8256 rf chip only support B,G,24N mode
364 if ((priv->rf_chip == RF_8225) || (priv->rf_chip == RF_8256) || (priv->rf_chip == RF_6052))
366 min_chan = 1;
367 max_chan = 14;
369 else
371 RT_TRACE(COMP_ERR, "unknown rf chip, can't set channel map in function:%s()\n", __FUNCTION__);
373 if (ChannelPlan[channel_plan].Len != 0){
374 // Clear old channel map
375 memset(GET_DOT11D_INFO(ieee)->channel_map, 0, sizeof(GET_DOT11D_INFO(ieee)->channel_map));
376 // Set new channel map
377 for (i=0;i<ChannelPlan[channel_plan].Len;i++)
379 if (ChannelPlan[channel_plan].Channel[i] < min_chan || ChannelPlan[channel_plan].Channel[i] > max_chan)
380 break;
381 GET_DOT11D_INFO(ieee)->channel_map[ChannelPlan[channel_plan].Channel[i]] = 1;
384 break;
386 case COUNTRY_CODE_GLOBAL_DOMAIN:
388 GET_DOT11D_INFO(ieee)->bEnabled = 0;//this flag enabled to follow 11d country IE setting, otherwise, it shall follow global domain settings.
389 Dot11d_Reset(ieee);
390 ieee->bGlobalDomain = true;
391 break;
393 default:
394 break;
396 return;
398 #endif
400 #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 )
402 #ifdef RTL8192SU
403 #define rx_hal_is_cck_rate(_pDesc)\
404 ((_pDesc->RxMCS == DESC92S_RATE1M ||\
405 _pDesc->RxMCS == DESC92S_RATE2M ||\
406 _pDesc->RxMCS == DESC92S_RATE5_5M ||\
407 _pDesc->RxMCS == DESC92S_RATE11M) &&\
408 !_pDesc->RxHT)
410 #define tx_hal_is_cck_rate(_DataRate)\
411 ( _DataRate == MGN_1M ||\
412 _DataRate == MGN_2M ||\
413 _DataRate == MGN_5_5M ||\
414 _DataRate == MGN_11M )
416 #else
417 #define rx_hal_is_cck_rate(_pdrvinfo)\
418 ((_pdrvinfo->RxRate == DESC90_RATE1M ||\
419 _pdrvinfo->RxRate == DESC90_RATE2M ||\
420 _pdrvinfo->RxRate == DESC90_RATE5_5M ||\
421 _pdrvinfo->RxRate == DESC90_RATE11M) &&\
422 !_pdrvinfo->RxHT)
423 #endif
427 void CamResetAllEntry(struct net_device *dev)
429 #if 1
430 u32 ulcommand = 0;
431 //2004/02/11 In static WEP, OID_ADD_KEY or OID_ADD_WEP are set before STA associate to AP.
432 // However, ResetKey is called on OID_802_11_INFRASTRUCTURE_MODE and MlmeAssociateRequest
433 // In this condition, Cam can not be reset because upper layer will not set this static key again.
434 //if(Adapter->EncAlgorithm == WEP_Encryption)
435 // return;
436 //debug
437 //DbgPrint("========================================\n");
438 //DbgPrint(" Call ResetAllEntry \n");
439 //DbgPrint("========================================\n\n");
440 ulcommand |= BIT31|BIT30;
441 write_nic_dword(dev, RWCAM, ulcommand);
442 #else
443 for(ucIndex=0;ucIndex<TOTAL_CAM_ENTRY;ucIndex++)
444 CAM_mark_invalid(dev, ucIndex);
445 for(ucIndex=0;ucIndex<TOTAL_CAM_ENTRY;ucIndex++)
446 CAM_empty_entry(dev, ucIndex);
447 #endif
452 void write_cam(struct net_device *dev, u8 addr, u32 data)
454 write_nic_dword(dev, WCAMI, data);
455 write_nic_dword(dev, RWCAM, BIT31|BIT16|(addr&0xff) );
458 u32 read_cam(struct net_device *dev, u8 addr)
460 write_nic_dword(dev, RWCAM, 0x80000000|(addr&0xff) );
461 return read_nic_dword(dev, 0xa8);
464 void write_nic_byte_E(struct net_device *dev, int indx, u8 data)
466 int status;
467 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
468 struct usb_device *udev = priv->udev;
470 status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
471 RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
472 indx|0xfe00, 0, &data, 1, HZ / 2);
474 if (status < 0)
476 printk("write_nic_byte_E TimeOut! status:%d\n", status);
480 u8 read_nic_byte_E(struct net_device *dev, int indx)
482 int status;
483 u8 data;
484 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
485 struct usb_device *udev = priv->udev;
487 status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
488 RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
489 indx|0xfe00, 0, &data, 1, HZ / 2);
491 if (status < 0)
493 printk("read_nic_byte_E TimeOut! status:%d\n", status);
496 return data;
498 //as 92U has extend page from 4 to 16, so modify functions below.
499 void write_nic_byte(struct net_device *dev, int indx, u8 data)
501 int status;
503 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
504 struct usb_device *udev = priv->udev;
506 status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
507 RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
508 #ifdef RTL8192SU
509 indx, 0, &data, 1, HZ / 2);
510 #else
511 (indx&0xff)|0xff00, (indx>>8)&0x0f, &data, 1, HZ / 2);
512 #endif
514 if (status < 0)
516 printk("write_nic_byte TimeOut! status:%d\n", status);
523 void write_nic_word(struct net_device *dev, int indx, u16 data)
526 int status;
528 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
529 struct usb_device *udev = priv->udev;
531 status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
532 RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
533 #ifdef RTL8192SU
534 indx, 0, &data, 2, HZ / 2);
535 #else
536 (indx&0xff)|0xff00, (indx>>8)&0x0f, &data, 2, HZ / 2);
537 #endif
539 if (status < 0)
541 printk("write_nic_word TimeOut! status:%d\n", status);
547 void write_nic_dword(struct net_device *dev, int indx, u32 data)
550 int status;
552 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
553 struct usb_device *udev = priv->udev;
555 status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
556 RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
557 #ifdef RTL8192SU
558 indx, 0, &data, 4, HZ / 2);
559 #else
560 (indx&0xff)|0xff00, (indx>>8)&0x0f, &data, 4, HZ / 2);
561 #endif
564 if (status < 0)
566 printk("write_nic_dword TimeOut! status:%d\n", status);
573 u8 read_nic_byte(struct net_device *dev, int indx)
575 u8 data;
576 int status;
577 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
578 struct usb_device *udev = priv->udev;
580 status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
581 RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
582 #ifdef RTL8192SU
583 indx, 0, &data, 1, HZ / 2);
584 #else
585 (indx&0xff)|0xff00, (indx>>8)&0x0f, &data, 1, HZ / 2);
586 #endif
588 if (status < 0)
590 printk("read_nic_byte TimeOut! status:%d\n", status);
593 return data;
598 u16 read_nic_word(struct net_device *dev, int indx)
600 u16 data;
601 int status;
602 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
603 struct usb_device *udev = priv->udev;
605 status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
606 RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
607 #ifdef RTL8192SU
608 indx, 0, &data, 2, HZ / 2);
609 #else
610 (indx&0xff)|0xff00, (indx>>8)&0x0f, &data, 2, HZ / 2);
611 #endif
613 if (status < 0)
615 printk("read_nic_word TimeOut! status:%d\n", status);
619 return data;
622 u16 read_nic_word_E(struct net_device *dev, int indx)
624 u16 data;
625 int status;
626 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
627 struct usb_device *udev = priv->udev;
629 status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
630 RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
631 indx|0xfe00, 0, &data, 2, HZ / 2);
633 if (status < 0)
635 printk("read_nic_word TimeOut! status:%d\n", status);
639 return data;
642 u32 read_nic_dword(struct net_device *dev, int indx)
644 u32 data;
645 int status;
646 // int result;
648 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
649 struct usb_device *udev = priv->udev;
651 status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
652 RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
653 #ifdef RTL8192SU
654 indx, 0, &data, 4, HZ / 2);
655 #else
656 (indx&0xff)|0xff00, (indx>>8)&0x0f, &data, 4, HZ / 2);
657 #endif
658 // if(0 != result) {
659 // printk(KERN_WARNING "read size of data = %d\, date = %d\n", result, data);
660 // }
662 if (status < 0)
664 printk("read_nic_dword TimeOut! status:%d\n", status);
665 if(status == -ENODEV) {
666 priv->usb_error = true;
672 return data;
676 //u8 read_phy_cck(struct net_device *dev, u8 adr);
677 //u8 read_phy_ofdm(struct net_device *dev, u8 adr);
678 /* this might still called in what was the PHY rtl8185/rtl8192 common code
679 * plans are to possibilty turn it again in one common code...
681 inline void force_pci_posting(struct net_device *dev)
686 static struct net_device_stats *rtl8192_stats(struct net_device *dev);
687 void rtl8192_commit(struct net_device *dev);
688 //void rtl8192_restart(struct net_device *dev);
689 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
690 void rtl8192_restart(struct work_struct *work);
691 //void rtl8192_rq_tx_ack(struct work_struct *work);
692 #else
693 void rtl8192_restart(struct net_device *dev);
694 // //void rtl8192_rq_tx_ack(struct net_device *dev);
695 #endif
697 void watch_dog_timer_callback(unsigned long data);
699 /****************************************************************************
700 -----------------------------PROCFS STUFF-------------------------
701 *****************************************************************************/
703 static struct proc_dir_entry *rtl8192_proc = NULL;
707 static int proc_get_stats_ap(char *page, char **start,
708 off_t offset, int count,
709 int *eof, void *data)
711 struct net_device *dev = data;
712 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
713 struct ieee80211_device *ieee = priv->ieee80211;
714 struct ieee80211_network *target;
716 int len = 0;
718 list_for_each_entry(target, &ieee->network_list, list) {
720 len += snprintf(page + len, count - len,
721 "%s ", target->ssid);
723 if(target->wpa_ie_len>0 || target->rsn_ie_len>0){
724 len += snprintf(page + len, count - len,
725 "WPA\n");
727 else{
728 len += snprintf(page + len, count - len,
729 "non_WPA\n");
734 *eof = 1;
735 return len;
738 #ifdef RTL8192SU
739 static int proc_get_registers(char *page, char **start,
740 off_t offset, int count,
741 int *eof, void *data)
743 struct net_device *dev = data;
744 // struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
746 int len = 0;
747 int i,n,page0,page1,page2;
749 int max=0xff;
750 page0 = 0x000;
751 page1 = 0x100;
752 page2 = 0x800;
754 /* This dump the current register page */
755 if(!IS_BB_REG_OFFSET_92S(page0)){
756 len += snprintf(page + len, count - len,
757 "\n####################page %x##################\n ", (page0>>8));
758 for(n=0;n<=max;)
760 len += snprintf(page + len, count - len,
761 "\nD: %2x > ",n);
762 for(i=0;i<16 && n<=max;i++,n++)
763 len += snprintf(page + len, count - len,
764 "%2.2x ",read_nic_byte(dev,(page0|n)));
766 }else{
767 len += snprintf(page + len, count - len,
768 "\n####################page %x##################\n ", (page0>>8));
769 for(n=0;n<=max;)
771 len += snprintf(page + len, count - len, "\nD: %2x > ",n);
772 for(i=0;i<4 && n<=max;n+=4,i++)
773 len += snprintf(page + len, count - len,
774 "%8.8x ",rtl8192_QueryBBReg(dev,(page0|n), bMaskDWord));
777 len += snprintf(page + len, count - len,"\n");
778 *eof = 1;
779 return len;
782 static int proc_get_registers_1(char *page, char **start,
783 off_t offset, int count,
784 int *eof, void *data)
786 struct net_device *dev = data;
787 // struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
789 int len = 0;
790 int i,n,page0;
792 int max=0xff;
793 page0 = 0x100;
795 /* This dump the current register page */
796 len += snprintf(page + len, count - len,
797 "\n####################page %x##################\n ", (page0>>8));
798 for(n=0;n<=max;)
800 len += snprintf(page + len, count - len,
801 "\nD: %2x > ",n);
802 for(i=0;i<16 && n<=max;i++,n++)
803 len += snprintf(page + len, count - len,
804 "%2.2x ",read_nic_byte(dev,(page0|n)));
806 len += snprintf(page + len, count - len,"\n");
807 *eof = 1;
808 return len;
811 static int proc_get_registers_2(char *page, char **start,
812 off_t offset, int count,
813 int *eof, void *data)
815 struct net_device *dev = data;
816 // struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
818 int len = 0;
819 int i,n,page0;
821 int max=0xff;
822 page0 = 0x200;
824 /* This dump the current register page */
825 len += snprintf(page + len, count - len,
826 "\n####################page %x##################\n ", (page0>>8));
827 for(n=0;n<=max;)
829 len += snprintf(page + len, count - len,
830 "\nD: %2x > ",n);
831 for(i=0;i<16 && n<=max;i++,n++)
832 len += snprintf(page + len, count - len,
833 "%2.2x ",read_nic_byte(dev,(page0|n)));
835 len += snprintf(page + len, count - len,"\n");
836 *eof = 1;
837 return len;
840 static int proc_get_registers_8(char *page, char **start,
841 off_t offset, int count,
842 int *eof, void *data)
844 struct net_device *dev = data;
846 int len = 0;
847 int i,n,page0;
849 int max=0xff;
850 page0 = 0x800;
852 /* This dump the current register page */
853 len += snprintf(page + len, count - len,
854 "\n####################page %x##################\n ", (page0>>8));
855 for(n=0;n<=max;)
857 len += snprintf(page + len, count - len, "\nD: %2x > ",n);
858 for(i=0;i<4 && n<=max;n+=4,i++)
859 len += snprintf(page + len, count - len,
860 "%8.8x ",rtl8192_QueryBBReg(dev,(page0|n), bMaskDWord));
862 len += snprintf(page + len, count - len,"\n");
863 *eof = 1;
864 return len;
867 static int proc_get_registers_9(char *page, char **start,
868 off_t offset, int count,
869 int *eof, void *data)
871 struct net_device *dev = data;
872 // struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
874 int len = 0;
875 int i,n,page0;
877 int max=0xff;
878 page0 = 0x900;
880 /* This dump the current register page */
881 len += snprintf(page + len, count - len,
882 "\n####################page %x##################\n ", (page0>>8));
883 for(n=0;n<=max;)
885 len += snprintf(page + len, count - len, "\nD: %2x > ",n);
886 for(i=0;i<4 && n<=max;n+=4,i++)
887 len += snprintf(page + len, count - len,
888 "%8.8x ",rtl8192_QueryBBReg(dev,(page0|n), bMaskDWord));
890 len += snprintf(page + len, count - len,"\n");
891 *eof = 1;
892 return len;
894 static int proc_get_registers_a(char *page, char **start,
895 off_t offset, int count,
896 int *eof, void *data)
898 struct net_device *dev = data;
899 // struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
901 int len = 0;
902 int i,n,page0;
904 int max=0xff;
905 page0 = 0xa00;
907 /* This dump the current register page */
908 len += snprintf(page + len, count - len,
909 "\n####################page %x##################\n ", (page0>>8));
910 for(n=0;n<=max;)
912 len += snprintf(page + len, count - len, "\nD: %2x > ",n);
913 for(i=0;i<4 && n<=max;n+=4,i++)
914 len += snprintf(page + len, count - len,
915 "%8.8x ",rtl8192_QueryBBReg(dev,(page0|n), bMaskDWord));
917 len += snprintf(page + len, count - len,"\n");
918 *eof = 1;
919 return len;
921 static int proc_get_registers_b(char *page, char **start,
922 off_t offset, int count,
923 int *eof, void *data)
925 struct net_device *dev = data;
926 // struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
928 int len = 0;
929 int i,n,page0;
931 int max=0xff;
932 page0 = 0xb00;
934 /* This dump the current register page */
935 len += snprintf(page + len, count - len,
936 "\n####################page %x##################\n ", (page0>>8));
937 for(n=0;n<=max;)
939 len += snprintf(page + len, count - len, "\nD: %2x > ",n);
940 for(i=0;i<4 && n<=max;n+=4,i++)
941 len += snprintf(page + len, count - len,
942 "%8.8x ",rtl8192_QueryBBReg(dev,(page0|n), bMaskDWord));
944 len += snprintf(page + len, count - len,"\n");
945 *eof = 1;
946 return len;
948 static int proc_get_registers_c(char *page, char **start,
949 off_t offset, int count,
950 int *eof, void *data)
952 struct net_device *dev = data;
953 // struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
955 int len = 0;
956 int i,n,page0;
958 int max=0xff;
959 page0 = 0xc00;
961 /* This dump the current register page */
962 len += snprintf(page + len, count - len,
963 "\n####################page %x##################\n ", (page0>>8));
964 for(n=0;n<=max;)
966 len += snprintf(page + len, count - len, "\nD: %2x > ",n);
967 for(i=0;i<4 && n<=max;n+=4,i++)
968 len += snprintf(page + len, count - len,
969 "%8.8x ",rtl8192_QueryBBReg(dev,(page0|n), bMaskDWord));
971 len += snprintf(page + len, count - len,"\n");
972 *eof = 1;
973 return len;
975 static int proc_get_registers_d(char *page, char **start,
976 off_t offset, int count,
977 int *eof, void *data)
979 struct net_device *dev = data;
980 // struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
982 int len = 0;
983 int i,n,page0;
985 int max=0xff;
986 page0 = 0xd00;
988 /* This dump the current register page */
989 len += snprintf(page + len, count - len,
990 "\n####################page %x##################\n ", (page0>>8));
991 for(n=0;n<=max;)
993 len += snprintf(page + len, count - len, "\nD: %2x > ",n);
994 for(i=0;i<4 && n<=max;n+=4,i++)
995 len += snprintf(page + len, count - len,
996 "%8.8x ",rtl8192_QueryBBReg(dev,(page0|n), bMaskDWord));
998 len += snprintf(page + len, count - len,"\n");
999 *eof = 1;
1000 return len;
1002 static int proc_get_registers_e(char *page, char **start,
1003 off_t offset, int count,
1004 int *eof, void *data)
1006 struct net_device *dev = data;
1007 // struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1009 int len = 0;
1010 int i,n,page0;
1012 int max=0xff;
1013 page0 = 0xe00;
1015 /* This dump the current register page */
1016 len += snprintf(page + len, count - len,
1017 "\n####################page %x##################\n ", (page0>>8));
1018 for(n=0;n<=max;)
1020 len += snprintf(page + len, count - len, "\nD: %2x > ",n);
1021 for(i=0;i<4 && n<=max;n+=4,i++)
1022 len += snprintf(page + len, count - len,
1023 "%8.8x ",rtl8192_QueryBBReg(dev,(page0|n), bMaskDWord));
1025 len += snprintf(page + len, count - len,"\n");
1026 *eof = 1;
1027 return len;
1029 #else
1030 static int proc_get_registers(char *page, char **start,
1031 off_t offset, int count,
1032 int *eof, void *data)
1034 struct net_device *dev = data;
1035 // struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1037 int len = 0;
1038 int i,n;
1040 int max=0xff;
1042 /* This dump the current register page */
1043 len += snprintf(page + len, count - len,
1044 "\n####################page 0##################\n ");
1046 for(n=0;n<=max;)
1048 //printk( "\nD: %2x> ", n);
1049 len += snprintf(page + len, count - len,
1050 "\nD: %2x > ",n);
1052 for(i=0;i<16 && n<=max;i++,n++)
1053 len += snprintf(page + len, count - len,
1054 "%2x ",read_nic_byte(dev,0x000|n));
1056 // printk("%2x ",read_nic_byte(dev,n));
1058 #if 1
1059 len += snprintf(page + len, count - len,
1060 "\n####################page 1##################\n ");
1061 for(n=0;n<=max;)
1063 //printk( "\nD: %2x> ", n);
1064 len += snprintf(page + len, count - len,
1065 "\nD: %2x > ",n);
1067 for(i=0;i<16 && n<=max;i++,n++)
1068 len += snprintf(page + len, count - len,
1069 "%2x ",read_nic_byte(dev,0x100|n));
1071 // printk("%2x ",read_nic_byte(dev,n));
1073 len += snprintf(page + len, count - len,
1074 "\n####################page 3##################\n ");
1075 for(n=0;n<=max;)
1077 //printk( "\nD: %2x> ", n);
1078 len += snprintf(page + len, count - len,
1079 "\nD: %2x > ",n);
1081 for(i=0;i<16 && n<=max;i++,n++)
1082 len += snprintf(page + len, count - len,
1083 "%2x ",read_nic_byte(dev,0x300|n));
1085 // printk("%2x ",read_nic_byte(dev,n));
1088 #endif
1090 len += snprintf(page + len, count - len,"\n");
1091 *eof = 1;
1092 return len;
1095 #endif
1097 #if 0
1098 static int proc_get_cck_reg(char *page, char **start,
1099 off_t offset, int count,
1100 int *eof, void *data)
1102 struct net_device *dev = data;
1103 // struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1105 int len = 0;
1106 int i,n;
1108 int max = 0x5F;
1110 /* This dump the current register page */
1111 for(n=0;n<=max;)
1113 //printk( "\nD: %2x> ", n);
1114 len += snprintf(page + len, count - len,
1115 "\nD: %2x > ",n);
1117 for(i=0;i<16 && n<=max;i++,n++)
1118 len += snprintf(page + len, count - len,
1119 "%2x ",read_phy_cck(dev,n));
1121 // printk("%2x ",read_nic_byte(dev,n));
1123 len += snprintf(page + len, count - len,"\n");
1126 *eof = 1;
1127 return len;
1130 #endif
1132 #if 0
1133 static int proc_get_ofdm_reg(char *page, char **start,
1134 off_t offset, int count,
1135 int *eof, void *data)
1137 struct net_device *dev = data;
1138 // struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1140 int len = 0;
1141 int i,n;
1143 //int max=0xff;
1144 int max = 0x40;
1146 /* This dump the current register page */
1147 for(n=0;n<=max;)
1149 //printk( "\nD: %2x> ", n);
1150 len += snprintf(page + len, count - len,
1151 "\nD: %2x > ",n);
1153 for(i=0;i<16 && n<=max;i++,n++)
1154 len += snprintf(page + len, count - len,
1155 "%2x ",read_phy_ofdm(dev,n));
1157 // printk("%2x ",read_nic_byte(dev,n));
1159 len += snprintf(page + len, count - len,"\n");
1163 *eof = 1;
1164 return len;
1167 #endif
1169 #if 0
1170 static int proc_get_stats_hw(char *page, char **start,
1171 off_t offset, int count,
1172 int *eof, void *data)
1174 struct net_device *dev = data;
1175 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1177 int len = 0;
1179 len += snprintf(page + len, count - len,
1180 "NIC int: %lu\n"
1181 "Total int: %lu\n",
1182 priv->stats.ints,
1183 priv->stats.shints);
1185 *eof = 1;
1186 return len;
1188 #endif
1190 static int proc_get_stats_tx(char *page, char **start,
1191 off_t offset, int count,
1192 int *eof, void *data)
1194 struct net_device *dev = data;
1195 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1197 int len = 0;
1199 len += snprintf(page + len, count - len,
1200 "TX VI priority ok int: %lu\n"
1201 "TX VI priority error int: %lu\n"
1202 "TX VO priority ok int: %lu\n"
1203 "TX VO priority error int: %lu\n"
1204 "TX BE priority ok int: %lu\n"
1205 "TX BE priority error int: %lu\n"
1206 "TX BK priority ok int: %lu\n"
1207 "TX BK priority error int: %lu\n"
1208 "TX MANAGE priority ok int: %lu\n"
1209 "TX MANAGE priority error int: %lu\n"
1210 "TX BEACON priority ok int: %lu\n"
1211 "TX BEACON priority error int: %lu\n"
1212 // "TX high priority ok int: %lu\n"
1213 // "TX high priority failed error int: %lu\n"
1214 "TX queue resume: %lu\n"
1215 "TX queue stopped?: %d\n"
1216 "TX fifo overflow: %lu\n"
1217 // "TX beacon: %lu\n"
1218 "TX VI queue: %d\n"
1219 "TX VO queue: %d\n"
1220 "TX BE queue: %d\n"
1221 "TX BK queue: %d\n"
1222 // "TX HW queue: %d\n"
1223 "TX VI dropped: %lu\n"
1224 "TX VO dropped: %lu\n"
1225 "TX BE dropped: %lu\n"
1226 "TX BK dropped: %lu\n"
1227 "TX total data packets %lu\n",
1228 // "TX beacon aborted: %lu\n",
1229 priv->stats.txviokint,
1230 priv->stats.txvierr,
1231 priv->stats.txvookint,
1232 priv->stats.txvoerr,
1233 priv->stats.txbeokint,
1234 priv->stats.txbeerr,
1235 priv->stats.txbkokint,
1236 priv->stats.txbkerr,
1237 priv->stats.txmanageokint,
1238 priv->stats.txmanageerr,
1239 priv->stats.txbeaconokint,
1240 priv->stats.txbeaconerr,
1241 // priv->stats.txhpokint,
1242 // priv->stats.txhperr,
1243 priv->stats.txresumed,
1244 netif_queue_stopped(dev),
1245 priv->stats.txoverflow,
1246 // priv->stats.txbeacon,
1247 atomic_read(&(priv->tx_pending[VI_PRIORITY])),
1248 atomic_read(&(priv->tx_pending[VO_PRIORITY])),
1249 atomic_read(&(priv->tx_pending[BE_PRIORITY])),
1250 atomic_read(&(priv->tx_pending[BK_PRIORITY])),
1251 // read_nic_byte(dev, TXFIFOCOUNT),
1252 priv->stats.txvidrop,
1253 priv->stats.txvodrop,
1254 priv->stats.txbedrop,
1255 priv->stats.txbkdrop,
1256 priv->stats.txdatapkt
1257 // priv->stats.txbeaconerr
1260 *eof = 1;
1261 return len;
1266 static int proc_get_stats_rx(char *page, char **start,
1267 off_t offset, int count,
1268 int *eof, void *data)
1270 struct net_device *dev = data;
1271 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1273 int len = 0;
1275 len += snprintf(page + len, count - len,
1276 "RX packets: %lu\n"
1277 "RX urb status error: %lu\n"
1278 "RX invalid urb error: %lu\n",
1279 priv->stats.rxoktotal,
1280 priv->stats.rxstaterr,
1281 priv->stats.rxurberr);
1283 *eof = 1;
1284 return len;
1286 #if 0
1287 #if WIRELESS_EXT >= 12 && WIRELESS_EXT < 17
1289 static struct iw_statistics *r8192_get_wireless_stats(struct net_device *dev)
1291 struct r8192_priv *priv = ieee80211_priv(dev);
1293 return &priv->wstats;
1295 #endif
1296 #endif
1297 void rtl8192_proc_module_init(void)
1299 RT_TRACE(COMP_INIT, "Initializing proc filesystem");
1300 #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24))
1301 rtl8192_proc=create_proc_entry(RTL819xU_MODULE_NAME, S_IFDIR, proc_net);
1302 #else
1303 rtl8192_proc=create_proc_entry(RTL819xU_MODULE_NAME, S_IFDIR, init_net.proc_net);
1304 #endif
1308 void rtl8192_proc_module_remove(void)
1310 #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24))
1311 remove_proc_entry(RTL819xU_MODULE_NAME, proc_net);
1312 #else
1313 remove_proc_entry(RTL819xU_MODULE_NAME, init_net.proc_net);
1314 #endif
1318 void rtl8192_proc_remove_one(struct net_device *dev)
1320 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1323 if (priv->dir_dev) {
1324 // remove_proc_entry("stats-hw", priv->dir_dev);
1325 remove_proc_entry("stats-tx", priv->dir_dev);
1326 remove_proc_entry("stats-rx", priv->dir_dev);
1327 // remove_proc_entry("stats-ieee", priv->dir_dev);
1328 remove_proc_entry("stats-ap", priv->dir_dev);
1329 remove_proc_entry("registers", priv->dir_dev);
1330 remove_proc_entry("registers-1", priv->dir_dev);
1331 remove_proc_entry("registers-2", priv->dir_dev);
1332 remove_proc_entry("registers-8", priv->dir_dev);
1333 remove_proc_entry("registers-9", priv->dir_dev);
1334 remove_proc_entry("registers-a", priv->dir_dev);
1335 remove_proc_entry("registers-b", priv->dir_dev);
1336 remove_proc_entry("registers-c", priv->dir_dev);
1337 remove_proc_entry("registers-d", priv->dir_dev);
1338 remove_proc_entry("registers-e", priv->dir_dev);
1339 // remove_proc_entry("cck-registers",priv->dir_dev);
1340 // remove_proc_entry("ofdm-registers",priv->dir_dev);
1341 //remove_proc_entry(dev->name, rtl8192_proc);
1342 remove_proc_entry("wlan0", rtl8192_proc);
1343 priv->dir_dev = NULL;
1348 void rtl8192_proc_init_one(struct net_device *dev)
1350 struct proc_dir_entry *e;
1351 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1352 priv->dir_dev = create_proc_entry(dev->name,
1353 S_IFDIR | S_IRUGO | S_IXUGO,
1354 rtl8192_proc);
1355 if (!priv->dir_dev) {
1356 RT_TRACE(COMP_ERR, "Unable to initialize /proc/net/rtl8192/%s\n",
1357 dev->name);
1358 return;
1360 #if 0
1361 e = create_proc_read_entry("stats-hw", S_IFREG | S_IRUGO,
1362 priv->dir_dev, proc_get_stats_hw, dev);
1364 if (!e) {
1365 DMESGE("Unable to initialize "
1366 "/proc/net/rtl8192/%s/stats-hw\n",
1367 dev->name);
1369 #endif
1370 e = create_proc_read_entry("stats-rx", S_IFREG | S_IRUGO,
1371 priv->dir_dev, proc_get_stats_rx, dev);
1373 if (!e) {
1374 RT_TRACE(COMP_ERR,"Unable to initialize "
1375 "/proc/net/rtl8192/%s/stats-rx\n",
1376 dev->name);
1380 e = create_proc_read_entry("stats-tx", S_IFREG | S_IRUGO,
1381 priv->dir_dev, proc_get_stats_tx, dev);
1383 if (!e) {
1384 RT_TRACE(COMP_ERR, "Unable to initialize "
1385 "/proc/net/rtl8192/%s/stats-tx\n",
1386 dev->name);
1388 #if 0
1389 e = create_proc_read_entry("stats-ieee", S_IFREG | S_IRUGO,
1390 priv->dir_dev, proc_get_stats_ieee, dev);
1392 if (!e) {
1393 DMESGE("Unable to initialize "
1394 "/proc/net/rtl8192/%s/stats-ieee\n",
1395 dev->name);
1398 #endif
1400 e = create_proc_read_entry("stats-ap", S_IFREG | S_IRUGO,
1401 priv->dir_dev, proc_get_stats_ap, dev);
1403 if (!e) {
1404 RT_TRACE(COMP_ERR, "Unable to initialize "
1405 "/proc/net/rtl8192/%s/stats-ap\n",
1406 dev->name);
1409 e = create_proc_read_entry("registers", S_IFREG | S_IRUGO,
1410 priv->dir_dev, proc_get_registers, dev);
1411 if (!e) {
1412 RT_TRACE(COMP_ERR, "Unable to initialize "
1413 "/proc/net/rtl8192/%s/registers\n",
1414 dev->name);
1416 #ifdef RTL8192SU
1417 e = create_proc_read_entry("registers-1", S_IFREG | S_IRUGO,
1418 priv->dir_dev, proc_get_registers_1, dev);
1419 if (!e) {
1420 RT_TRACE(COMP_ERR, "Unable to initialize "
1421 "/proc/net/rtl8192/%s/registers-1\n",
1422 dev->name);
1424 e = create_proc_read_entry("registers-2", S_IFREG | S_IRUGO,
1425 priv->dir_dev, proc_get_registers_2, dev);
1426 if (!e) {
1427 RT_TRACE(COMP_ERR, "Unable to initialize "
1428 "/proc/net/rtl8192/%s/registers-2\n",
1429 dev->name);
1431 e = create_proc_read_entry("registers-8", S_IFREG | S_IRUGO,
1432 priv->dir_dev, proc_get_registers_8, dev);
1433 if (!e) {
1434 RT_TRACE(COMP_ERR, "Unable to initialize "
1435 "/proc/net/rtl8192/%s/registers-8\n",
1436 dev->name);
1438 e = create_proc_read_entry("registers-9", S_IFREG | S_IRUGO,
1439 priv->dir_dev, proc_get_registers_9, dev);
1440 if (!e) {
1441 RT_TRACE(COMP_ERR, "Unable to initialize "
1442 "/proc/net/rtl8192/%s/registers-9\n",
1443 dev->name);
1445 e = create_proc_read_entry("registers-a", S_IFREG | S_IRUGO,
1446 priv->dir_dev, proc_get_registers_a, dev);
1447 if (!e) {
1448 RT_TRACE(COMP_ERR, "Unable to initialize "
1449 "/proc/net/rtl8192/%s/registers-a\n",
1450 dev->name);
1452 e = create_proc_read_entry("registers-b", S_IFREG | S_IRUGO,
1453 priv->dir_dev, proc_get_registers_b, dev);
1454 if (!e) {
1455 RT_TRACE(COMP_ERR, "Unable to initialize "
1456 "/proc/net/rtl8192/%s/registers-b\n",
1457 dev->name);
1459 e = create_proc_read_entry("registers-c", S_IFREG | S_IRUGO,
1460 priv->dir_dev, proc_get_registers_c, dev);
1461 if (!e) {
1462 RT_TRACE(COMP_ERR, "Unable to initialize "
1463 "/proc/net/rtl8192/%s/registers-c\n",
1464 dev->name);
1466 e = create_proc_read_entry("registers-d", S_IFREG | S_IRUGO,
1467 priv->dir_dev, proc_get_registers_d, dev);
1468 if (!e) {
1469 RT_TRACE(COMP_ERR, "Unable to initialize "
1470 "/proc/net/rtl8192/%s/registers-d\n",
1471 dev->name);
1473 e = create_proc_read_entry("registers-e", S_IFREG | S_IRUGO,
1474 priv->dir_dev, proc_get_registers_e, dev);
1475 if (!e) {
1476 RT_TRACE(COMP_ERR, "Unable to initialize "
1477 "/proc/net/rtl8192/%s/registers-e\n",
1478 dev->name);
1480 #endif
1481 #if 0
1482 e = create_proc_read_entry("cck-registers", S_IFREG | S_IRUGO,
1483 priv->dir_dev, proc_get_cck_reg, dev);
1484 if (!e) {
1485 RT_TRACE(COMP_ERR, "Unable to initialize "
1486 "/proc/net/rtl8192/%s/cck-registers\n",
1487 dev->name);
1490 e = create_proc_read_entry("ofdm-registers", S_IFREG | S_IRUGO,
1491 priv->dir_dev, proc_get_ofdm_reg, dev);
1492 if (!e) {
1493 RT_TRACE(COMP_ERR, "Unable to initialize "
1494 "/proc/net/rtl8192/%s/ofdm-registers\n",
1495 dev->name);
1497 #endif
1499 /****************************************************************************
1500 -----------------------------MISC STUFF-------------------------
1501 *****************************************************************************/
1503 /* this is only for debugging */
1504 void print_buffer(u32 *buffer, int len)
1506 int i;
1507 u8 *buf =(u8*)buffer;
1509 printk("ASCII BUFFER DUMP (len: %x):\n",len);
1511 for(i=0;i<len;i++)
1512 printk("%c",buf[i]);
1514 printk("\nBINARY BUFFER DUMP (len: %x):\n",len);
1516 for(i=0;i<len;i++)
1517 printk("%x",buf[i]);
1519 printk("\n");
1522 //short check_nic_enough_desc(struct net_device *dev, priority_t priority)
1523 short check_nic_enough_desc(struct net_device *dev,int queue_index)
1525 struct r8192_priv *priv = ieee80211_priv(dev);
1526 int used = atomic_read(&priv->tx_pending[queue_index]);
1528 return (used < MAX_TX_URB);
1531 void tx_timeout(struct net_device *dev)
1533 struct r8192_priv *priv = ieee80211_priv(dev);
1534 //rtl8192_commit(dev);
1536 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
1537 schedule_work(&priv->reset_wq);
1538 #else
1539 schedule_task(&priv->reset_wq);
1540 #endif
1541 //DMESG("TXTIMEOUT");
1545 /* this is only for debug */
1546 void dump_eprom(struct net_device *dev)
1548 int i;
1549 for(i=0; i<63; i++)
1550 RT_TRACE(COMP_EPROM, "EEPROM addr %x : %x", i, eprom_read(dev,i));
1553 /* this is only for debug */
1554 void rtl8192_dump_reg(struct net_device *dev)
1556 int i;
1557 int n;
1558 int max=0x1ff;
1560 RT_TRACE(COMP_PHY, "Dumping NIC register map");
1562 for(n=0;n<=max;)
1564 printk( "\nD: %2x> ", n);
1565 for(i=0;i<16 && n<=max;i++,n++)
1566 printk("%2x ",read_nic_byte(dev,n));
1568 printk("\n");
1571 /****************************************************************************
1572 ------------------------------HW STUFF---------------------------
1573 *****************************************************************************/
1575 #if 0
1576 void rtl8192_irq_enable(struct net_device *dev)
1578 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1579 //priv->irq_enabled = 1;
1581 write_nic_word(dev,INTA_MASK,INTA_RXOK | INTA_RXDESCERR | INTA_RXOVERFLOW |\
1582 INTA_TXOVERFLOW | INTA_HIPRIORITYDESCERR | INTA_HIPRIORITYDESCOK |\
1583 INTA_NORMPRIORITYDESCERR | INTA_NORMPRIORITYDESCOK |\
1584 INTA_LOWPRIORITYDESCERR | INTA_LOWPRIORITYDESCOK | INTA_TIMEOUT);
1586 write_nic_word(dev,INTA_MASK, priv->irq_mask);
1590 void rtl8192_irq_disable(struct net_device *dev)
1592 // struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1594 write_nic_word(dev,INTA_MASK,0);
1595 force_pci_posting(dev);
1596 // priv->irq_enabled = 0;
1598 #endif
1600 void rtl8192_set_mode(struct net_device *dev,int mode)
1602 u8 ecmd;
1603 ecmd=read_nic_byte(dev, EPROM_CMD);
1604 ecmd=ecmd &~ EPROM_CMD_OPERATING_MODE_MASK;
1605 ecmd=ecmd | (mode<<EPROM_CMD_OPERATING_MODE_SHIFT);
1606 ecmd=ecmd &~ (1<<EPROM_CS_SHIFT);
1607 ecmd=ecmd &~ (1<<EPROM_CK_SHIFT);
1608 write_nic_byte(dev, EPROM_CMD, ecmd);
1612 void rtl8192_update_msr(struct net_device *dev)
1614 struct r8192_priv *priv = ieee80211_priv(dev);
1615 u8 msr;
1617 msr = read_nic_byte(dev, MSR);
1618 msr &= ~ MSR_LINK_MASK;
1620 /* do not change in link_state != WLAN_LINK_ASSOCIATED.
1621 * msr must be updated if the state is ASSOCIATING.
1622 * this is intentional and make sense for ad-hoc and
1623 * master (see the create BSS/IBSS func)
1625 if (priv->ieee80211->state == IEEE80211_LINKED){
1627 if (priv->ieee80211->iw_mode == IW_MODE_INFRA)
1628 msr |= (MSR_LINK_MANAGED<<MSR_LINK_SHIFT);
1629 else if (priv->ieee80211->iw_mode == IW_MODE_ADHOC)
1630 msr |= (MSR_LINK_ADHOC<<MSR_LINK_SHIFT);
1631 else if (priv->ieee80211->iw_mode == IW_MODE_MASTER)
1632 msr |= (MSR_LINK_MASTER<<MSR_LINK_SHIFT);
1634 }else
1635 msr |= (MSR_LINK_NONE<<MSR_LINK_SHIFT);
1637 write_nic_byte(dev, MSR, msr);
1640 void rtl8192_set_chan(struct net_device *dev,short ch)
1642 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1643 // u32 tx;
1644 RT_TRACE(COMP_CH, "=====>%s()====ch:%d\n", __FUNCTION__, ch);
1645 //printk("=====>%s()====ch:%d\n", __FUNCTION__, ch);
1646 priv->chan=ch;
1647 #if 0
1648 if(priv->ieee80211->iw_mode == IW_MODE_ADHOC ||
1649 priv->ieee80211->iw_mode == IW_MODE_MASTER){
1651 priv->ieee80211->link_state = WLAN_LINK_ASSOCIATED;
1652 priv->ieee80211->master_chan = ch;
1653 rtl8192_update_beacon_ch(dev);
1655 #endif
1657 /* this hack should avoid frame TX during channel setting*/
1660 // tx = read_nic_dword(dev,TX_CONF);
1661 // tx &= ~TX_LOOPBACK_MASK;
1663 #ifndef LOOP_TEST
1664 // write_nic_dword(dev,TX_CONF, tx |( TX_LOOPBACK_MAC<<TX_LOOPBACK_SHIFT));
1666 //need to implement rf set channel here WB
1668 if (priv->rf_set_chan)
1669 priv->rf_set_chan(dev,priv->chan);
1670 mdelay(10);
1671 // write_nic_dword(dev,TX_CONF,tx | (TX_LOOPBACK_NONE<<TX_LOOPBACK_SHIFT));
1672 #endif
1675 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
1676 static void rtl8192_rx_isr(struct urb *urb, struct pt_regs *regs);
1677 #else
1678 static void rtl8192_rx_isr(struct urb *urb);
1679 #endif
1680 //static void rtl8192_rx_isr(struct urb *rx_urb);
1682 u32 get_rxpacket_shiftbytes_819xusb(struct ieee80211_rx_stats *pstats)
1685 #ifdef USB_RX_AGGREGATION_SUPPORT
1686 if (pstats->bisrxaggrsubframe)
1687 return (sizeof(rx_desc_819x_usb) + pstats->RxDrvInfoSize
1688 + pstats->RxBufShift + 8);
1689 else
1690 #endif
1691 return (sizeof(rx_desc_819x_usb) + pstats->RxDrvInfoSize
1692 + pstats->RxBufShift);
1695 static int rtl8192_rx_initiate(struct net_device*dev)
1697 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1698 struct urb *entry;
1699 struct sk_buff *skb;
1700 struct rtl8192_rx_info *info;
1702 /* nomal packet rx procedure */
1703 while (skb_queue_len(&priv->rx_queue) < MAX_RX_URB) {
1704 skb = __dev_alloc_skb(RX_URB_SIZE, GFP_KERNEL);
1705 if (!skb)
1706 break;
1707 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
1708 entry = usb_alloc_urb(0, GFP_KERNEL);
1709 #else
1710 entry = usb_alloc_urb(0);
1711 #endif
1712 if (!entry) {
1713 kfree_skb(skb);
1714 break;
1716 // printk("nomal packet IN request!\n");
1717 usb_fill_bulk_urb(entry, priv->udev,
1718 usb_rcvbulkpipe(priv->udev, 3), skb->tail,
1719 RX_URB_SIZE, rtl8192_rx_isr, skb);
1720 info = (struct rtl8192_rx_info *) skb->cb;
1721 info->urb = entry;
1722 info->dev = dev;
1723 info->out_pipe = 3; //denote rx normal packet queue
1724 skb_queue_tail(&priv->rx_queue, skb);
1725 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
1726 usb_submit_urb(entry, GFP_KERNEL);
1727 #else
1728 usb_submit_urb(entry);
1729 #endif
1732 /* command packet rx procedure */
1733 while (skb_queue_len(&priv->rx_queue) < MAX_RX_URB + 3) {
1734 // printk("command packet IN request!\n");
1735 skb = __dev_alloc_skb(RX_URB_SIZE ,GFP_KERNEL);
1736 if (!skb)
1737 break;
1738 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
1739 entry = usb_alloc_urb(0, GFP_KERNEL);
1740 #else
1741 entry = usb_alloc_urb(0);
1742 #endif
1743 if (!entry) {
1744 kfree_skb(skb);
1745 break;
1747 usb_fill_bulk_urb(entry, priv->udev,
1748 usb_rcvbulkpipe(priv->udev, 9), skb->tail,
1749 RX_URB_SIZE, rtl8192_rx_isr, skb);
1750 info = (struct rtl8192_rx_info *) skb->cb;
1751 info->urb = entry;
1752 info->dev = dev;
1753 info->out_pipe = 9; //denote rx cmd packet queue
1754 skb_queue_tail(&priv->rx_queue, skb);
1755 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
1756 usb_submit_urb(entry, GFP_KERNEL);
1757 #else
1758 usb_submit_urb(entry);
1759 #endif
1762 return 0;
1765 void rtl8192_set_rxconf(struct net_device *dev)
1767 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1768 u32 rxconf;
1770 rxconf=read_nic_dword(dev,RCR);
1771 rxconf = rxconf &~ MAC_FILTER_MASK;
1772 rxconf = rxconf | RCR_AMF;
1773 rxconf = rxconf | RCR_ADF;
1774 rxconf = rxconf | RCR_AB;
1775 rxconf = rxconf | RCR_AM;
1776 //rxconf = rxconf | RCR_ACF;
1778 if (dev->flags & IFF_PROMISC) {DMESG ("NIC in promisc mode");}
1780 if(priv->ieee80211->iw_mode == IW_MODE_MONITOR || \
1781 dev->flags & IFF_PROMISC){
1782 rxconf = rxconf | RCR_AAP;
1783 } /*else if(priv->ieee80211->iw_mode == IW_MODE_MASTER){
1784 rxconf = rxconf | (1<<ACCEPT_ALLMAC_FRAME_SHIFT);
1785 rxconf = rxconf | (1<<RX_CHECK_BSSID_SHIFT);
1786 }*/else{
1787 rxconf = rxconf | RCR_APM;
1788 rxconf = rxconf | RCR_CBSSID;
1792 if(priv->ieee80211->iw_mode == IW_MODE_MONITOR){
1793 rxconf = rxconf | RCR_AICV;
1794 rxconf = rxconf | RCR_APWRMGT;
1797 if( priv->crcmon == 1 && priv->ieee80211->iw_mode == IW_MODE_MONITOR)
1798 rxconf = rxconf | RCR_ACRC32;
1801 rxconf = rxconf &~ RX_FIFO_THRESHOLD_MASK;
1802 rxconf = rxconf | (RX_FIFO_THRESHOLD_NONE<<RX_FIFO_THRESHOLD_SHIFT);
1803 rxconf = rxconf &~ MAX_RX_DMA_MASK;
1804 rxconf = rxconf | ((u32)7<<RCR_MXDMA_OFFSET);
1806 // rxconf = rxconf | (1<<RX_AUTORESETPHY_SHIFT);
1807 rxconf = rxconf | RCR_ONLYERLPKT;
1809 // rxconf = rxconf &~ RCR_CS_MASK;
1810 // rxconf = rxconf | (1<<RCR_CS_SHIFT);
1812 write_nic_dword(dev, RCR, rxconf);
1814 #ifdef DEBUG_RX
1815 DMESG("rxconf: %x %x",rxconf ,read_nic_dword(dev,RCR));
1816 #endif
1818 //wait to be removed
1819 void rtl8192_rx_enable(struct net_device *dev)
1821 //u8 cmd;
1823 //struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1825 rtl8192_rx_initiate(dev);
1827 // rtl8192_set_rxconf(dev);
1828 #if 0
1829 if(NIC_8187 == priv->card_8187) {
1830 cmd=read_nic_byte(dev,CMD);
1831 write_nic_byte(dev,CMD,cmd | (1<<CMD_RX_ENABLE_SHIFT));
1833 else {
1834 //write_nic_dword(dev, RX_CONF, priv->ReceiveConfig);
1836 #endif
1840 void rtl8192_tx_enable(struct net_device *dev)
1842 #if 0
1843 u8 cmd;
1844 u8 byte;
1845 u32 txconf;
1846 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1847 //test loopback
1848 // priv->TransmitConfig |= (TX_LOOPBACK_BASEBAND<<TX_LOOPBACK_SHIFT);
1849 if(NIC_8187B == priv->card_8187){
1850 write_nic_dword(dev, TX_CONF, priv->TransmitConfig);
1851 byte = read_nic_byte(dev, MSR);
1852 byte |= MSR_LINK_ENEDCA;
1853 write_nic_byte(dev, MSR, byte);
1854 } else {
1855 byte = read_nic_byte(dev,CW_CONF);
1856 byte &= ~(1<<CW_CONF_PERPACKET_CW_SHIFT);
1857 byte &= ~(1<<CW_CONF_PERPACKET_RETRY_SHIFT);
1858 write_nic_byte(dev, CW_CONF, byte);
1860 byte = read_nic_byte(dev, TX_AGC_CTL);
1861 byte &= ~(1<<TX_AGC_CTL_PERPACKET_GAIN_SHIFT);
1862 byte &= ~(1<<TX_AGC_CTL_PERPACKET_ANTSEL_SHIFT);
1863 byte &= ~(1<<TX_AGC_CTL_FEEDBACK_ANT);
1864 write_nic_byte(dev, TX_AGC_CTL, byte);
1866 txconf= read_nic_dword(dev,TX_CONF);
1869 txconf = txconf &~ TX_LOOPBACK_MASK;
1871 #ifndef LOOP_TEST
1872 txconf = txconf | (TX_LOOPBACK_NONE<<TX_LOOPBACK_SHIFT);
1873 #else
1874 txconf = txconf | (TX_LOOPBACK_BASEBAND<<TX_LOOPBACK_SHIFT);
1875 #endif
1876 txconf = txconf &~ TCR_SRL_MASK;
1877 txconf = txconf &~ TCR_LRL_MASK;
1879 txconf = txconf | (priv->retry_data<<TX_LRLRETRY_SHIFT); // long
1880 txconf = txconf | (priv->retry_rts<<TX_SRLRETRY_SHIFT); // short
1882 txconf = txconf &~ (1<<TX_NOCRC_SHIFT);
1884 txconf = txconf &~ TCR_MXDMA_MASK;
1885 txconf = txconf | (TCR_MXDMA_2048<<TCR_MXDMA_SHIFT);
1887 txconf = txconf | TCR_DISReqQsize;
1888 txconf = txconf | TCR_DISCW;
1889 txconf = txconf &~ TCR_SWPLCPLEN;
1891 txconf=txconf | (1<<TX_NOICV_SHIFT);
1893 write_nic_dword(dev,TX_CONF,txconf);
1895 #ifdef DEBUG_TX
1896 DMESG("txconf: %x %x",txconf,read_nic_dword(dev,TX_CONF));
1897 #endif
1899 cmd=read_nic_byte(dev,CMD);
1900 write_nic_byte(dev,CMD,cmd | (1<<CMD_TX_ENABLE_SHIFT));
1902 #endif
1905 #if 0
1906 void rtl8192_beacon_tx_enable(struct net_device *dev)
1908 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1909 priv->dma_poll_mask &=~(1<<TX_DMA_STOP_BEACON_SHIFT);
1910 rtl8192_set_mode(dev,EPROM_CMD_CONFIG);
1911 write_nic_byte(dev,TX_DMA_POLLING,priv->dma_poll_mask);
1912 rtl8192_set_mode(dev,EPROM_CMD_NORMAL);
1916 void rtl8192_
1917 _disable(struct net_device *dev)
1919 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1920 priv->dma_poll_mask |= (1<<TX_DMA_STOP_BEACON_SHIFT);
1921 rtl8192_set_mode(dev,EPROM_CMD_CONFIG);
1922 write_nic_byte(dev,TX_DMA_POLLING,priv->dma_poll_mask);
1923 rtl8192_set_mode(dev,EPROM_CMD_NORMAL);
1926 #endif
1929 void rtl8192_rtx_disable(struct net_device *dev)
1931 u8 cmd;
1932 struct r8192_priv *priv = ieee80211_priv(dev);
1933 struct sk_buff *skb;
1934 struct rtl8192_rx_info *info;
1936 cmd=read_nic_byte(dev,CMDR);
1937 write_nic_byte(dev, CMDR, cmd &~ \
1938 (CR_TE|CR_RE));
1939 force_pci_posting(dev);
1940 mdelay(10);
1942 while ((skb = __skb_dequeue(&priv->rx_queue))) {
1943 info = (struct rtl8192_rx_info *) skb->cb;
1944 if (!info->urb)
1945 continue;
1947 usb_kill_urb(info->urb);
1948 kfree_skb(skb);
1951 if (skb_queue_len(&priv->skb_queue)) {
1952 printk(KERN_WARNING "skb_queue not empty\n");
1955 skb_queue_purge(&priv->skb_queue);
1956 return;
1960 int alloc_tx_beacon_desc_ring(struct net_device *dev, int count)
1962 #if 0
1963 int i;
1964 u32 *tmp;
1965 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1967 priv->txbeaconring = (u32*)pci_alloc_consistent(priv->pdev,
1968 sizeof(u32)*8*count,
1969 &priv->txbeaconringdma);
1970 if (!priv->txbeaconring) return -1;
1971 for (tmp=priv->txbeaconring,i=0;i<count;i++){
1972 *tmp = *tmp &~ (1<<31); // descriptor empty, owned by the drv
1974 *(tmp+2) = (u32)dma_tmp;
1975 *(tmp+3) = bufsize;
1977 if(i+1<count)
1978 *(tmp+4) = (u32)priv->txbeaconringdma+((i+1)*8*4);
1979 else
1980 *(tmp+4) = (u32)priv->txbeaconringdma;
1982 tmp=tmp+8;
1984 #endif
1985 return 0;
1988 #if 0
1989 void rtl8192_reset(struct net_device *dev)
1992 //struct r8192_priv *priv = ieee80211_priv(dev);
1993 //u8 cr;
1996 /* make sure the analog power is on before
1997 * reset, otherwise reset may fail
1999 #if 0
2000 if(NIC_8187 == priv->card_8187) {
2001 rtl8192_set_anaparam(dev, RTL8225_ANAPARAM_ON);
2002 rtl8185_set_anaparam2(dev, RTL8225_ANAPARAM2_ON);
2003 rtl8192_irq_disable(dev);
2004 mdelay(200);
2005 write_nic_byte_E(dev,0x18,0x10);
2006 write_nic_byte_E(dev,0x18,0x11);
2007 write_nic_byte_E(dev,0x18,0x00);
2008 mdelay(200);
2010 #endif
2011 printk("=====>reset?\n");
2012 #if 0
2013 cr=read_nic_byte(dev,CMD);
2014 cr = cr & 2;
2015 cr = cr | (1<<CMD_RST_SHIFT);
2016 write_nic_byte(dev,CMD,cr);
2018 force_pci_posting(dev);
2020 mdelay(200);
2022 if(read_nic_byte(dev,CMD) & (1<<CMD_RST_SHIFT))
2023 RT_TRACE(COMP_ERR, "Card reset timeout!\n");
2024 else
2025 RT_TRACE(COMP_DOWN, "Card successfully reset\n");
2026 #endif
2027 #if 0
2028 if(NIC_8187 == priv->card_8187) {
2030 printk("This is RTL8187 Reset procedure\n");
2031 rtl8192_set_mode(dev,EPROM_CMD_LOAD);
2032 force_pci_posting(dev);
2033 mdelay(200);
2035 /* after the eeprom load cycle, make sure we have
2036 * correct anaparams
2038 rtl8192_set_anaparam(dev, RTL8225_ANAPARAM_ON);
2039 rtl8185_set_anaparam2(dev, RTL8225_ANAPARAM2_ON);
2041 else
2042 #endif
2043 printk("This is RTL8187B Reset procedure\n");
2046 #endif
2047 inline u16 ieeerate2rtlrate(int rate)
2049 switch(rate){
2050 case 10:
2051 return 0;
2052 case 20:
2053 return 1;
2054 case 55:
2055 return 2;
2056 case 110:
2057 return 3;
2058 case 60:
2059 return 4;
2060 case 90:
2061 return 5;
2062 case 120:
2063 return 6;
2064 case 180:
2065 return 7;
2066 case 240:
2067 return 8;
2068 case 360:
2069 return 9;
2070 case 480:
2071 return 10;
2072 case 540:
2073 return 11;
2074 default:
2075 return 3;
2079 static u16 rtl_rate[] = {10,20,55,110,60,90,120,180,240,360,480,540};
2080 inline u16 rtl8192_rate2rate(short rate)
2082 if (rate >11) return 0;
2083 return rtl_rate[rate];
2087 /* The protype of rx_isr has changed since one verion of Linux Kernel */
2088 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
2089 static void rtl8192_rx_isr(struct urb *urb, struct pt_regs *regs)
2090 #else
2091 static void rtl8192_rx_isr(struct urb *urb)
2092 #endif
2094 struct sk_buff *skb = (struct sk_buff *) urb->context;
2095 struct rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
2096 struct net_device *dev = info->dev;
2097 struct r8192_priv *priv = ieee80211_priv(dev);
2098 int out_pipe = info->out_pipe;
2099 int err;
2100 if(!priv->up)
2101 return;
2102 if (unlikely(urb->status)) {
2103 info->urb = NULL;
2104 priv->stats.rxstaterr++;
2105 priv->ieee80211->stats.rx_errors++;
2106 usb_free_urb(urb);
2107 // printk("%s():rx status err\n",__FUNCTION__);
2108 return;
2110 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,14)
2111 skb_unlink(skb, &priv->rx_queue);
2112 #else
2114 * __skb_unlink before linux2.6.14 does not use spinlock to protect list head.
2115 * add spinlock function manually. john,2008/12/03
2118 unsigned long flags;
2119 spin_lock_irqsave(&(priv->rx_queue.lock), flags);
2120 __skb_unlink(skb,&priv->rx_queue);
2121 spin_unlock_irqrestore(&(priv->rx_queue.lock), flags);
2123 #endif
2124 skb_put(skb, urb->actual_length);
2126 skb_queue_tail(&priv->skb_queue, skb);
2127 tasklet_schedule(&priv->irq_rx_tasklet);
2129 skb = dev_alloc_skb(RX_URB_SIZE);
2130 if (unlikely(!skb)) {
2131 usb_free_urb(urb);
2132 printk("%s():can,t alloc skb\n",__FUNCTION__);
2133 /* TODO check rx queue length and refill *somewhere* */
2134 return;
2137 usb_fill_bulk_urb(urb, priv->udev,
2138 usb_rcvbulkpipe(priv->udev, out_pipe), skb->tail,
2139 RX_URB_SIZE, rtl8192_rx_isr, skb);
2141 info = (struct rtl8192_rx_info *) skb->cb;
2142 info->urb = urb;
2143 info->dev = dev;
2144 info->out_pipe = out_pipe;
2146 urb->transfer_buffer = skb->tail;
2147 urb->context = skb;
2148 skb_queue_tail(&priv->rx_queue, skb);
2149 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
2150 err = usb_submit_urb(urb, GFP_ATOMIC);
2151 #else
2152 err = usb_submit_urb(urb);
2153 #endif
2154 if(err && err != EPERM)
2155 printk("can not submit rxurb, err is %x,URB status is %x\n",err,urb->status);
2159 rtl819xusb_rx_command_packet(
2160 struct net_device *dev,
2161 struct ieee80211_rx_stats *pstats
2164 u32 status;
2166 //RT_TRACE(COMP_RECV, DBG_TRACE, ("---> RxCommandPacketHandle819xUsb()\n"));
2168 status = cmpk_message_handle_rx(dev, pstats);
2169 if (status)
2171 DMESG("rxcommandpackethandle819xusb: It is a command packet\n");
2173 else
2175 //RT_TRACE(COMP_RECV, DBG_TRACE, ("RxCommandPacketHandle819xUsb: It is not a command packet\n"));
2178 //RT_TRACE(COMP_RECV, DBG_TRACE, ("<--- RxCommandPacketHandle819xUsb()\n"));
2179 return status;
2182 #if 0
2183 void rtl8192_tx_queues_stop(struct net_device *dev)
2185 //struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
2186 u8 dma_poll_mask = (1<<TX_DMA_STOP_LOWPRIORITY_SHIFT);
2187 dma_poll_mask |= (1<<TX_DMA_STOP_HIPRIORITY_SHIFT);
2188 dma_poll_mask |= (1<<TX_DMA_STOP_NORMPRIORITY_SHIFT);
2189 dma_poll_mask |= (1<<TX_DMA_STOP_BEACON_SHIFT);
2191 rtl8192_set_mode(dev,EPROM_CMD_CONFIG);
2192 write_nic_byte(dev,TX_DMA_POLLING,dma_poll_mask);
2193 rtl8192_set_mode(dev,EPROM_CMD_NORMAL);
2195 #endif
2197 void rtl8192_data_hard_stop(struct net_device *dev)
2199 //FIXME !!
2200 #if 0
2201 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
2202 priv->dma_poll_mask |= (1<<TX_DMA_STOP_LOWPRIORITY_SHIFT);
2203 rtl8192_set_mode(dev,EPROM_CMD_CONFIG);
2204 write_nic_byte(dev,TX_DMA_POLLING,priv->dma_poll_mask);
2205 rtl8192_set_mode(dev,EPROM_CMD_NORMAL);
2206 #endif
2210 void rtl8192_data_hard_resume(struct net_device *dev)
2212 // FIXME !!
2213 #if 0
2214 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
2215 priv->dma_poll_mask &= ~(1<<TX_DMA_STOP_LOWPRIORITY_SHIFT);
2216 rtl8192_set_mode(dev,EPROM_CMD_CONFIG);
2217 write_nic_byte(dev,TX_DMA_POLLING,priv->dma_poll_mask);
2218 rtl8192_set_mode(dev,EPROM_CMD_NORMAL);
2219 #endif
2222 /* this function TX data frames when the ieee80211 stack requires this.
2223 * It checks also if we need to stop the ieee tx queue, eventually do it
2225 void rtl8192_hard_data_xmit(struct sk_buff *skb, struct net_device *dev, int rate)
2227 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
2228 int ret;
2229 unsigned long flags;
2230 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
2231 u8 queue_index = tcb_desc->queue_index;
2233 /* shall not be referred by command packet */
2234 assert(queue_index != TXCMD_QUEUE);
2236 spin_lock_irqsave(&priv->tx_lock,flags);
2238 memcpy((unsigned char *)(skb->cb),&dev,sizeof(dev));
2239 // tcb_desc->RATRIndex = 7;
2240 // tcb_desc->bTxDisableRateFallBack = 1;
2241 // tcb_desc->bTxUseDriverAssingedRate = 1;
2242 tcb_desc->bTxEnableFwCalcDur = 1;
2243 skb_push(skb, priv->ieee80211->tx_headroom);
2244 ret = priv->ops->rtl819x_tx(dev, skb);
2246 //priv->ieee80211->stats.tx_bytes+=(skb->len - priv->ieee80211->tx_headroom);
2247 //priv->ieee80211->stats.tx_packets++;
2249 spin_unlock_irqrestore(&priv->tx_lock,flags);
2251 // return ret;
2252 return;
2255 /* This is a rough attempt to TX a frame
2256 * This is called by the ieee 80211 stack to TX management frames.
2257 * If the ring is full packet are dropped (for data frame the queue
2258 * is stopped before this can happen).
2260 int rtl8192_hard_start_xmit(struct sk_buff *skb,struct net_device *dev)
2262 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
2263 int ret;
2264 unsigned long flags;
2265 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
2266 u8 queue_index = tcb_desc->queue_index;
2269 spin_lock_irqsave(&priv->tx_lock,flags);
2271 memcpy((unsigned char *)(skb->cb),&dev,sizeof(dev));
2272 if(queue_index == TXCMD_QUEUE) {
2273 skb_push(skb, USB_HWDESC_HEADER_LEN);
2274 priv->ops->rtl819x_tx_cmd(dev, skb);
2275 ret = 1;
2276 spin_unlock_irqrestore(&priv->tx_lock,flags);
2277 return ret;
2278 } else {
2279 skb_push(skb, priv->ieee80211->tx_headroom);
2280 ret = priv->ops->rtl819x_tx(dev, skb);
2283 spin_unlock_irqrestore(&priv->tx_lock,flags);
2285 return ret;
2289 void rtl8192_try_wake_queue(struct net_device *dev, int pri);
2291 #ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
2292 u16 DrvAggr_PaddingAdd(struct net_device *dev, struct sk_buff *skb)
2294 u16 PaddingNum = 256 - ((skb->len + TX_PACKET_DRVAGGR_SUBFRAME_SHIFT_BYTES) % 256);
2295 return (PaddingNum&0xff);
2298 u8 MRateToHwRate8190Pci(u8 rate);
2299 u8 QueryIsShort(u8 TxHT, u8 TxRate, cb_desc *tcb_desc);
2300 u8 MapHwQueueToFirmwareQueue(u8 QueueID);
2301 struct sk_buff *DrvAggr_Aggregation(struct net_device *dev, struct ieee80211_drv_agg_txb *pSendList)
2303 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
2304 struct ieee80211_device *ieee = netdev_priv(dev);
2305 #else
2306 struct ieee80211_device *ieee = (struct ieee80211_device *)dev->priv;
2307 #endif
2308 struct r8192_priv *priv = ieee80211_priv(dev);
2309 cb_desc *tcb_desc = NULL;
2310 u8 i;
2311 u32 TotalLength;
2312 struct sk_buff *skb;
2313 struct sk_buff *agg_skb;
2314 tx_desc_819x_usb_aggr_subframe *tx_agg_desc = NULL;
2315 tx_fwinfo_819x_usb *tx_fwinfo = NULL;
2318 // Local variable initialization.
2320 /* first skb initialization */
2321 skb = pSendList->tx_agg_frames[0];
2322 TotalLength = skb->len;
2324 /* Get the total aggregation length including the padding space and
2325 * sub frame header.
2327 for(i = 1; i < pSendList->nr_drv_agg_frames; i++) {
2328 TotalLength += DrvAggr_PaddingAdd(dev, skb);
2329 skb = pSendList->tx_agg_frames[i];
2330 TotalLength += (skb->len + TX_PACKET_DRVAGGR_SUBFRAME_SHIFT_BYTES);
2333 /* allocate skb to contain the aggregated packets */
2334 agg_skb = dev_alloc_skb(TotalLength + ieee->tx_headroom);
2335 memset(agg_skb->data, 0, agg_skb->len);
2336 skb_reserve(agg_skb, ieee->tx_headroom);
2338 // RT_DEBUG_DATA(COMP_SEND, skb->cb, sizeof(skb->cb));
2339 /* reserve info for first subframe Tx descriptor to be set in the tx function */
2340 skb = pSendList->tx_agg_frames[0];
2341 tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
2342 tcb_desc->drv_agg_enable = 1;
2343 tcb_desc->pkt_size = skb->len;
2344 tcb_desc->DrvAggrNum = pSendList->nr_drv_agg_frames;
2345 printk("DrvAggNum = %d\n", tcb_desc->DrvAggrNum);
2346 // RT_DEBUG_DATA(COMP_SEND, skb->cb, sizeof(skb->cb));
2347 // printk("========>skb->data ======> \n");
2348 // RT_DEBUG_DATA(COMP_SEND, skb->data, skb->len);
2349 memcpy(agg_skb->cb, skb->cb, sizeof(skb->cb));
2350 memcpy(skb_put(agg_skb,skb->len),skb->data,skb->len);
2352 for(i = 1; i < pSendList->nr_drv_agg_frames; i++) {
2353 /* push the next sub frame to be 256 byte aline */
2354 skb_put(agg_skb,DrvAggr_PaddingAdd(dev,skb));
2356 /* Subframe drv Tx descriptor and firmware info setting */
2357 skb = pSendList->tx_agg_frames[i];
2358 tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
2359 tx_agg_desc = (tx_desc_819x_usb_aggr_subframe *)agg_skb->tail;
2360 tx_fwinfo = (tx_fwinfo_819x_usb *)(agg_skb->tail + sizeof(tx_desc_819x_usb_aggr_subframe));
2362 memset(tx_fwinfo,0,sizeof(tx_fwinfo_819x_usb));
2363 /* DWORD 0 */
2364 tx_fwinfo->TxHT = (tcb_desc->data_rate&0x80)?1:0;
2365 tx_fwinfo->TxRate = MRateToHwRate8190Pci(tcb_desc->data_rate);
2366 tx_fwinfo->EnableCPUDur = tcb_desc->bTxEnableFwCalcDur;
2367 tx_fwinfo->Short = QueryIsShort(tx_fwinfo->TxHT, tx_fwinfo->TxRate, tcb_desc);
2368 if(tcb_desc->bAMPDUEnable) {//AMPDU enabled
2369 tx_fwinfo->AllowAggregation = 1;
2370 /* DWORD 1 */
2371 tx_fwinfo->RxMF = tcb_desc->ampdu_factor;
2372 tx_fwinfo->RxAMD = tcb_desc->ampdu_density&0x07;//ampdudensity
2373 } else {
2374 tx_fwinfo->AllowAggregation = 0;
2375 /* DWORD 1 */
2376 tx_fwinfo->RxMF = 0;
2377 tx_fwinfo->RxAMD = 0;
2380 /* Protection mode related */
2381 tx_fwinfo->RtsEnable = (tcb_desc->bRTSEnable)?1:0;
2382 tx_fwinfo->CtsEnable = (tcb_desc->bCTSEnable)?1:0;
2383 tx_fwinfo->RtsSTBC = (tcb_desc->bRTSSTBC)?1:0;
2384 tx_fwinfo->RtsHT = (tcb_desc->rts_rate&0x80)?1:0;
2385 tx_fwinfo->RtsRate = MRateToHwRate8190Pci((u8)tcb_desc->rts_rate);
2386 tx_fwinfo->RtsSubcarrier = (tx_fwinfo->RtsHT==0)?(tcb_desc->RTSSC):0;
2387 tx_fwinfo->RtsBandwidth = (tx_fwinfo->RtsHT==1)?((tcb_desc->bRTSBW)?1:0):0;
2388 tx_fwinfo->RtsShort = (tx_fwinfo->RtsHT==0)?(tcb_desc->bRTSUseShortPreamble?1:0):\
2389 (tcb_desc->bRTSUseShortGI?1:0);
2391 /* Set Bandwidth and sub-channel settings. */
2392 if(priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20_40)
2394 if(tcb_desc->bPacketBW) {
2395 tx_fwinfo->TxBandwidth = 1;
2396 tx_fwinfo->TxSubCarrier = 0; //By SD3's Jerry suggestion, use duplicated mode
2397 } else {
2398 tx_fwinfo->TxBandwidth = 0;
2399 tx_fwinfo->TxSubCarrier = priv->nCur40MhzPrimeSC;
2401 } else {
2402 tx_fwinfo->TxBandwidth = 0;
2403 tx_fwinfo->TxSubCarrier = 0;
2406 /* Fill Tx descriptor */
2407 memset(tx_agg_desc, 0, sizeof(tx_desc_819x_usb_aggr_subframe));
2408 /* DWORD 0 */
2409 //tx_agg_desc->LINIP = 0;
2410 //tx_agg_desc->CmdInit = 1;
2411 tx_agg_desc->Offset = sizeof(tx_fwinfo_819x_usb) + 8;
2412 /* already raw data, need not to substract header length */
2413 tx_agg_desc->PktSize = skb->len & 0xffff;
2415 /*DWORD 1*/
2416 tx_agg_desc->SecCAMID= 0;
2417 tx_agg_desc->RATid = tcb_desc->RATRIndex;
2418 #if 0
2419 /* Fill security related */
2420 if( pTcb->bEncrypt && !Adapter->MgntInfo.SecurityInfo.SWTxEncryptFlag)
2422 EncAlg = SecGetEncryptionOverhead(
2423 Adapter,
2424 &EncryptionMPDUHeadOverhead,
2425 &EncryptionMPDUTailOverhead,
2426 NULL,
2427 NULL,
2428 FALSE,
2429 FALSE);
2430 //2004/07/22, kcwu, EncryptionMPDUHeadOverhead has been added in previous code
2431 //MPDUOverhead = EncryptionMPDUHeadOverhead + EncryptionMPDUTailOverhead;
2432 MPDUOverhead = EncryptionMPDUTailOverhead;
2433 tx_agg_desc->NoEnc = 0;
2434 RT_TRACE(COMP_SEC, DBG_LOUD, ("******We in the loop SecCAMID is %d SecDescAssign is %d The Sec is %d********\n",tx_agg_desc->SecCAMID,tx_agg_desc->SecDescAssign,EncAlg));
2435 //CamDumpAll(Adapter);
2437 else
2438 #endif
2440 //MPDUOverhead = 0;
2441 tx_agg_desc->NoEnc = 1;
2443 #if 0
2444 switch(EncAlg){
2445 case NO_Encryption:
2446 tx_agg_desc->SecType = 0x0;
2447 break;
2448 case WEP40_Encryption:
2449 case WEP104_Encryption:
2450 tx_agg_desc->SecType = 0x1;
2451 break;
2452 case TKIP_Encryption:
2453 tx_agg_desc->SecType = 0x2;
2454 break;
2455 case AESCCMP_Encryption:
2456 tx_agg_desc->SecType = 0x3;
2457 break;
2458 default:
2459 tx_agg_desc->SecType = 0x0;
2460 break;
2462 #else
2463 tx_agg_desc->SecType = 0x0;
2464 #endif
2466 if (tcb_desc->bHwSec) {
2467 switch (priv->ieee80211->pairwise_key_type)
2469 case KEY_TYPE_WEP40:
2470 case KEY_TYPE_WEP104:
2471 tx_agg_desc->SecType = 0x1;
2472 tx_agg_desc->NoEnc = 0;
2473 break;
2474 case KEY_TYPE_TKIP:
2475 tx_agg_desc->SecType = 0x2;
2476 tx_agg_desc->NoEnc = 0;
2477 break;
2478 case KEY_TYPE_CCMP:
2479 tx_agg_desc->SecType = 0x3;
2480 tx_agg_desc->NoEnc = 0;
2481 break;
2482 case KEY_TYPE_NA:
2483 tx_agg_desc->SecType = 0x0;
2484 tx_agg_desc->NoEnc = 1;
2485 break;
2489 tx_agg_desc->QueueSelect = MapHwQueueToFirmwareQueue(tcb_desc->queue_index);
2490 tx_agg_desc->TxFWInfoSize = sizeof(tx_fwinfo_819x_usb);
2492 tx_agg_desc->DISFB = tcb_desc->bTxDisableRateFallBack;
2493 tx_agg_desc->USERATE = tcb_desc->bTxUseDriverAssingedRate;
2495 tx_agg_desc->OWN = 1;
2497 //DWORD 2
2498 /* According windows driver, it seems that there no need to fill this field */
2499 //tx_agg_desc->TxBufferSize= (u32)(skb->len - USB_HWDESC_HEADER_LEN);
2501 /* to fill next packet */
2502 skb_put(agg_skb,TX_PACKET_DRVAGGR_SUBFRAME_SHIFT_BYTES);
2503 memcpy(skb_put(agg_skb,skb->len),skb->data,skb->len);
2506 for(i = 0; i < pSendList->nr_drv_agg_frames; i++) {
2507 dev_kfree_skb_any(pSendList->tx_agg_frames[i]);
2510 return agg_skb;
2513 /* NOTE:
2514 This function return a list of PTCB which is proper to be aggregate with the input TCB.
2515 If no proper TCB is found to do aggregation, SendList will only contain the input TCB.
2517 u8 DrvAggr_GetAggregatibleList(struct net_device *dev, struct sk_buff *skb,
2518 struct ieee80211_drv_agg_txb *pSendList)
2520 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
2521 struct ieee80211_device *ieee = netdev_priv(dev);
2522 #else
2523 struct ieee80211_device *ieee = (struct ieee80211_device *)dev->priv;
2524 #endif
2525 PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
2526 u16 nMaxAggrNum = pHTInfo->UsbTxAggrNum;
2527 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
2528 u8 QueueID = tcb_desc->queue_index;
2530 do {
2531 pSendList->tx_agg_frames[pSendList->nr_drv_agg_frames++] = skb;
2532 if(pSendList->nr_drv_agg_frames >= nMaxAggrNum) {
2533 break;
2536 } while((skb = skb_dequeue(&ieee->skb_drv_aggQ[QueueID])));
2538 RT_TRACE(COMP_AMSDU, "DrvAggr_GetAggregatibleList, nAggrTcbNum = %d \n", pSendList->nr_drv_agg_frames);
2539 return pSendList->nr_drv_agg_frames;
2541 #endif
2543 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
2544 static void rtl8192_tx_isr(struct urb *tx_urb, struct pt_regs *reg)
2545 #else
2546 static void rtl8192_tx_isr(struct urb *tx_urb)
2547 #endif
2549 struct sk_buff *skb = (struct sk_buff*)tx_urb->context;
2550 struct net_device *dev = NULL;
2551 struct r8192_priv *priv = NULL;
2552 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
2553 u8 queue_index = tcb_desc->queue_index;
2554 // bool bToSend0Byte;
2555 // u16 BufLen = skb->len;
2557 memcpy(&dev,(struct net_device*)(skb->cb),sizeof(struct net_device*));
2558 priv = ieee80211_priv(dev);
2560 if(tcb_desc->queue_index != TXCMD_QUEUE) {
2561 if(tx_urb->status == 0) {
2562 // dev->trans_start = jiffies;
2563 // As act as station mode, destion shall be unicast address.
2564 //priv->ieee80211->stats.tx_bytes+=(skb->len - priv->ieee80211->tx_headroom);
2565 //priv->ieee80211->stats.tx_packets++;
2566 priv->stats.txoktotal++;
2567 priv->ieee80211->LinkDetectInfo.NumTxOkInPeriod++;
2568 priv->stats.txbytesunicast += (skb->len - priv->ieee80211->tx_headroom);
2569 } else {
2570 priv->ieee80211->stats.tx_errors++;
2571 //priv->stats.txmanageerr++;
2572 /* TODO */
2576 /* free skb and tx_urb */
2577 if(skb != NULL) {
2578 dev_kfree_skb_any(skb);
2579 usb_free_urb(tx_urb);
2580 atomic_dec(&priv->tx_pending[queue_index]);
2583 #if 0 //we need to send zero byte packet just after 512 byte(64 byte)packet is transmitted, or we will halt. It will greatly reduced available page in FW, and ruin our throughput. WB 2008.08.27
2584 if(BufLen > 0 && ((BufLen % 512 == 0)||(BufLen % 64 == 0))) {
2585 bToSend0Byte = true;
2588 bToSend0Byte = false;
2590 // Note that, we at most handle 1 MPDU to send here, either
2591 // fragment or MPDU in wait queue.
2593 if(!bToSend0Byte)
2594 #endif
2597 // Handle HW Beacon:
2598 // We had transfer our beacon frame to host controler at this moment.
2600 #if 0
2601 if(tcb_desc->tx_queue == BEACON_QUEUE)
2603 priv->bSendingBeacon = FALSE;
2605 #endif
2607 // Caution:
2608 // Handling the wait queue of command packets.
2609 // For Tx command packets, we must not do TCB fragment because it is not handled right now.
2610 // We must cut the packets to match the size of TX_CMD_PKT before we send it.
2612 if (queue_index == MGNT_QUEUE){
2613 if (priv->ieee80211->ack_tx_to_ieee){
2614 if (rtl8192_is_tx_queue_empty(dev)){
2615 priv->ieee80211->ack_tx_to_ieee = 0;
2616 ieee80211_ps_tx_ack(priv->ieee80211, 1);
2620 /* Handle MPDU in wait queue. */
2621 if(queue_index != BEACON_QUEUE) {
2622 /* Don't send data frame during scanning.*/
2623 if((skb_queue_len(&priv->ieee80211->skb_waitQ[queue_index]) != 0)&&\
2624 (!(priv->ieee80211->queue_stop))) {
2625 if(NULL != (skb = skb_dequeue(&(priv->ieee80211->skb_waitQ[queue_index]))))
2626 priv->ieee80211->softmac_hard_start_xmit(skb, dev);
2628 return; //modified by david to avoid further processing AMSDU
2630 #ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
2631 else if ((skb_queue_len(&priv->ieee80211->skb_drv_aggQ[queue_index])!= 0)&&\
2632 (!(priv->ieee80211->queue_stop))) {
2633 // Tx Driver Aggregation process
2634 /* The driver will aggregation the packets according to the following stets
2635 * 1. check whether there's tx irq available, for it's a completion return
2636 * function, it should contain enough tx irq;
2637 * 2. check pakcet type;
2638 * 3. intialize sendlist, check whether the to-be send packet no greater than 1
2639 * 4. aggregation the packets, and fill firmware info and tx desc to it, etc.
2640 * 5. check whehter the packet could be sent, otherwise just insert to wait head
2641 * */
2642 skb = skb_dequeue(&priv->ieee80211->skb_drv_aggQ[queue_index]);
2643 if(!check_nic_enough_desc(dev, queue_index)) {
2644 skb_queue_head(&(priv->ieee80211->skb_drv_aggQ[queue_index]), skb);
2645 return;
2649 /*TODO*/
2651 u8* pHeader = skb->data;
2653 if(IsMgntQosData(pHeader) ||
2654 IsMgntQData_Ack(pHeader) ||
2655 IsMgntQData_Poll(pHeader) ||
2656 IsMgntQData_Poll_Ack(pHeader)
2660 struct ieee80211_drv_agg_txb SendList;
2662 memset(&SendList, 0, sizeof(struct ieee80211_drv_agg_txb));
2663 if(DrvAggr_GetAggregatibleList(dev, skb, &SendList) > 1) {
2664 skb = DrvAggr_Aggregation(dev, &SendList);
2666 #if 0
2667 printk("=============>to send aggregated packet!\n");
2668 RT_DEBUG_DATA(COMP_SEND, skb->cb, sizeof(skb->cb));
2669 printk("\n=================skb->len = %d\n", skb->len);
2670 RT_DEBUG_DATA(COMP_SEND, skb->data, skb->len);
2671 #endif
2674 priv->ieee80211->softmac_hard_start_xmit(skb, dev);
2677 #endif
2681 #if 0
2682 else
2684 RT_TRACE( COMP_SEND,"HalUsbOutComplete(%d): bToSend0Byte.\n", PipeIndex);
2687 // In this case, we don't return skb now.
2688 // It will be returned when the 0-byte request completed.
2692 // Bulk out an 0-byte padding transfer.
2694 HalUsbOut0Byte(pAdapter, PipeIndex, skb);
2697 #endif
2700 void rtl8192_beacon_stop(struct net_device *dev)
2702 u8 msr, msrm, msr2;
2703 struct r8192_priv *priv = ieee80211_priv(dev);
2705 msr = read_nic_byte(dev, MSR);
2706 msrm = msr & MSR_LINK_MASK;
2707 msr2 = msr & ~MSR_LINK_MASK;
2709 if(NIC_8192U == priv->card_8192) {
2710 usb_kill_urb(priv->rx_urb[MAX_RX_URB]);
2712 if ((msrm == (MSR_LINK_ADHOC<<MSR_LINK_SHIFT) ||
2713 (msrm == (MSR_LINK_MASTER<<MSR_LINK_SHIFT)))){
2714 write_nic_byte(dev, MSR, msr2 | MSR_LINK_NONE);
2715 write_nic_byte(dev, MSR, msr);
2719 void rtl8192_config_rate(struct net_device* dev, u16* rate_config)
2721 struct r8192_priv *priv = ieee80211_priv(dev);
2722 struct ieee80211_network *net;
2723 u8 i=0, basic_rate = 0;
2724 net = & priv->ieee80211->current_network;
2726 for (i=0; i<net->rates_len; i++)
2728 basic_rate = net->rates[i]&0x7f;
2729 switch(basic_rate)
2731 case MGN_1M: *rate_config |= RRSR_1M; break;
2732 case MGN_2M: *rate_config |= RRSR_2M; break;
2733 case MGN_5_5M: *rate_config |= RRSR_5_5M; break;
2734 case MGN_11M: *rate_config |= RRSR_11M; break;
2735 case MGN_6M: *rate_config |= RRSR_6M; break;
2736 case MGN_9M: *rate_config |= RRSR_9M; break;
2737 case MGN_12M: *rate_config |= RRSR_12M; break;
2738 case MGN_18M: *rate_config |= RRSR_18M; break;
2739 case MGN_24M: *rate_config |= RRSR_24M; break;
2740 case MGN_36M: *rate_config |= RRSR_36M; break;
2741 case MGN_48M: *rate_config |= RRSR_48M; break;
2742 case MGN_54M: *rate_config |= RRSR_54M; break;
2745 for (i=0; i<net->rates_ex_len; i++)
2747 basic_rate = net->rates_ex[i]&0x7f;
2748 switch(basic_rate)
2750 case MGN_1M: *rate_config |= RRSR_1M; break;
2751 case MGN_2M: *rate_config |= RRSR_2M; break;
2752 case MGN_5_5M: *rate_config |= RRSR_5_5M; break;
2753 case MGN_11M: *rate_config |= RRSR_11M; break;
2754 case MGN_6M: *rate_config |= RRSR_6M; break;
2755 case MGN_9M: *rate_config |= RRSR_9M; break;
2756 case MGN_12M: *rate_config |= RRSR_12M; break;
2757 case MGN_18M: *rate_config |= RRSR_18M; break;
2758 case MGN_24M: *rate_config |= RRSR_24M; break;
2759 case MGN_36M: *rate_config |= RRSR_36M; break;
2760 case MGN_48M: *rate_config |= RRSR_48M; break;
2761 case MGN_54M: *rate_config |= RRSR_54M; break;
2767 #define SHORT_SLOT_TIME 9
2768 #define NON_SHORT_SLOT_TIME 20
2770 void rtl8192_update_cap(struct net_device* dev, u16 cap)
2772 //u32 tmp = 0;
2773 struct r8192_priv *priv = ieee80211_priv(dev);
2774 struct ieee80211_network *net = &priv->ieee80211->current_network;
2775 priv->short_preamble = cap & WLAN_CAPABILITY_SHORT_PREAMBLE;
2777 //LZM MOD 090303 HW_VAR_ACK_PREAMBLE
2778 #ifdef RTL8192SU
2779 if(0)
2781 u8 tmp = 0;
2782 tmp = ((priv->nCur40MhzPrimeSC) << 5);
2783 if (priv->short_preamble)
2784 tmp |= 0x80;
2785 write_nic_byte(dev, RRSR+2, tmp);
2787 #else
2789 u32 tmp = 0;
2790 tmp = priv->basic_rate;
2791 if (priv->short_preamble)
2792 tmp |= BRSR_AckShortPmb;
2793 write_nic_dword(dev, RRSR, tmp);
2795 #endif
2797 if (net->mode & (IEEE_G|IEEE_N_24G))
2799 u8 slot_time = 0;
2800 if ((cap & WLAN_CAPABILITY_SHORT_SLOT)&&(!priv->ieee80211->pHTInfo->bCurrentRT2RTLongSlotTime))
2801 {//short slot time
2802 slot_time = SHORT_SLOT_TIME;
2804 else //long slot time
2805 slot_time = NON_SHORT_SLOT_TIME;
2806 priv->slot_time = slot_time;
2807 write_nic_byte(dev, SLOT_TIME, slot_time);
2811 void rtl8192_net_update(struct net_device *dev)
2814 struct r8192_priv *priv = ieee80211_priv(dev);
2815 struct ieee80211_network *net;
2816 u16 BcnTimeCfg = 0, BcnCW = 6, BcnIFS = 0xf;
2817 u16 rate_config = 0;
2818 net = & priv->ieee80211->current_network;
2820 rtl8192_config_rate(dev, &rate_config);
2821 priv->basic_rate = rate_config &= 0x15f;
2823 write_nic_dword(dev,BSSIDR,((u32*)net->bssid)[0]);
2824 write_nic_word(dev,BSSIDR+4,((u16*)net->bssid)[2]);
2825 //for(i=0;i<ETH_ALEN;i++)
2826 // write_nic_byte(dev,BSSID+i,net->bssid[i]);
2828 rtl8192_update_msr(dev);
2829 // rtl8192_update_cap(dev, net->capability);
2830 if (priv->ieee80211->iw_mode == IW_MODE_ADHOC)
2832 write_nic_word(dev, ATIMWND, 2);
2833 write_nic_word(dev, BCN_DMATIME, 1023);
2834 write_nic_word(dev, BCN_INTERVAL, net->beacon_interval);
2835 // write_nic_word(dev, BcnIntTime, 100);
2836 write_nic_word(dev, BCN_DRV_EARLY_INT, 1);
2837 write_nic_byte(dev, BCN_ERR_THRESH, 100);
2838 BcnTimeCfg |= (BcnCW<<BCN_TCFG_CW_SHIFT);
2839 // TODO: BcnIFS may required to be changed on ASIC
2840 BcnTimeCfg |= BcnIFS<<BCN_TCFG_IFS;
2842 write_nic_word(dev, BCN_TCFG, BcnTimeCfg);
2849 //temporary hw beacon is not used any more.
2850 //open it when necessary
2851 #if 1
2852 void rtl819xusb_beacon_tx(struct net_device *dev,u16 tx_rate)
2855 #if 0
2856 struct r8192_priv *priv = ieee80211_priv(dev);
2857 struct sk_buff *skb;
2858 int i = 0;
2859 //u8 cr;
2861 rtl8192_net_update(dev);
2863 skb = ieee80211_get_beacon(priv->ieee80211);
2864 if(!skb){
2865 DMESG("not enought memory for allocating beacon");
2866 return;
2870 write_nic_byte(dev, BQREQ, read_nic_byte(dev, BQREQ) | (1<<7));
2872 i=0;
2873 //while(!read_nic_byte(dev,BQREQ & (1<<7)))
2874 while( (read_nic_byte(dev, BQREQ) & (1<<7)) == 0 )
2876 msleep_interruptible_rtl(HZ/2);
2877 if(i++ > 10){
2878 DMESGW("get stuck to wait HW beacon to be ready");
2879 return ;
2882 skb->cb[0] = NORM_PRIORITY;
2883 skb->cb[1] = 0; //morefragment = 0
2884 skb->cb[2] = ieeerate2rtlrate(tx_rate);
2886 rtl8192_tx(dev,skb);
2888 #endif
2890 #endif
2891 inline u8 rtl8192_IsWirelessBMode(u16 rate)
2893 if( ((rate <= 110) && (rate != 60) && (rate != 90)) || (rate == 220) )
2894 return 1;
2895 else return 0;
2898 u16 N_DBPSOfRate(u16 DataRate);
2900 u16 ComputeTxTime(
2901 u16 FrameLength,
2902 u16 DataRate,
2903 u8 bManagementFrame,
2904 u8 bShortPreamble
2907 u16 FrameTime;
2908 u16 N_DBPS;
2909 u16 Ceiling;
2911 if( rtl8192_IsWirelessBMode(DataRate) )
2913 if( bManagementFrame || !bShortPreamble || DataRate == 10 )
2914 { // long preamble
2915 FrameTime = (u16)(144+48+(FrameLength*8/(DataRate/10)));
2917 else
2918 { // Short preamble
2919 FrameTime = (u16)(72+24+(FrameLength*8/(DataRate/10)));
2921 if( ( FrameLength*8 % (DataRate/10) ) != 0 ) //Get the Ceilling
2922 FrameTime ++;
2923 } else { //802.11g DSSS-OFDM PLCP length field calculation.
2924 N_DBPS = N_DBPSOfRate(DataRate);
2925 Ceiling = (16 + 8*FrameLength + 6) / N_DBPS
2926 + (((16 + 8*FrameLength + 6) % N_DBPS) ? 1 : 0);
2927 FrameTime = (u16)(16 + 4 + 4*Ceiling + 6);
2929 return FrameTime;
2932 u16 N_DBPSOfRate(u16 DataRate)
2934 u16 N_DBPS = 24;
2936 switch(DataRate)
2938 case 60:
2939 N_DBPS = 24;
2940 break;
2942 case 90:
2943 N_DBPS = 36;
2944 break;
2946 case 120:
2947 N_DBPS = 48;
2948 break;
2950 case 180:
2951 N_DBPS = 72;
2952 break;
2954 case 240:
2955 N_DBPS = 96;
2956 break;
2958 case 360:
2959 N_DBPS = 144;
2960 break;
2962 case 480:
2963 N_DBPS = 192;
2964 break;
2966 case 540:
2967 N_DBPS = 216;
2968 break;
2970 default:
2971 break;
2974 return N_DBPS;
2977 void rtl819xU_cmd_isr(struct urb *tx_cmd_urb, struct pt_regs *regs)
2979 #if 0
2980 struct net_device *dev = (struct net_device*)tx_cmd_urb->context;
2981 struct r8192_priv *priv = ieee80211_priv(dev);
2982 int last_init_packet = 0;
2983 u8 *ptr_cmd_buf;
2984 u16 cmd_buf_len;
2986 if(tx_cmd_urb->status != 0) {
2987 priv->pFirmware.firmware_seg_index = 0; //only begin transter, should it can be set to 1
2990 /* Free the urb and the corresponding buf for common Tx cmd packet, or
2991 * last segment of each firmware img.
2993 if((priv->pFirmware.firmware_seg_index == 0) ||(priv->pFirmware.firmware_seg_index == priv->pFirmware.firmware_seg_maxnum)) {
2994 priv->pFirmware.firmware_seg_index = 0;//only begin transter, should it can be set to 1
2995 } else {
2996 /* prepare for last transfer */
2997 /* update some infomation for */
2998 /* last segment of the firmware img need indicate to device */
2999 priv->pFirmware.firmware_seg_index++;
3000 if(priv->pFirmware.firmware_seg_index == priv->pFirmware.firmware_seg_maxnum) {
3001 last_init_packet = 1;
3004 cmd_buf_len = priv->pFirmware.firmware_seg_container[priv->pFirmware.firmware_seg_index-1].seg_size;
3005 ptr_cmd_buf = priv->pFfirmware.firmware_seg_container[priv->pFfirmware.firmware_seg_index-1].seg_ptr;
3006 rtl819xU_tx_cmd(dev, ptr_cmd_buf, cmd_buf_len, last_init_packet, DESC_PACKET_TYPE_INIT);
3009 kfree(tx_cmd_urb->transfer_buffer);
3010 #endif
3011 usb_free_urb(tx_cmd_urb);
3014 unsigned int txqueue2outpipe(struct r8192_priv* priv,unsigned int tx_queue) {
3016 if(tx_queue >= 9)
3018 RT_TRACE(COMP_ERR,"%s():Unknown queue ID!!!\n",__FUNCTION__);
3019 return 0x04;
3021 return priv->txqueue_to_outpipemap[tx_queue];
3024 #ifdef RTL8192SU
3025 short rtl8192SU_tx_cmd(struct net_device *dev, struct sk_buff *skb)
3027 struct r8192_priv *priv = ieee80211_priv(dev);
3028 int status;
3029 struct urb *tx_urb;
3030 unsigned int idx_pipe;
3031 tx_desc_cmd_819x_usb *pdesc = (tx_desc_cmd_819x_usb *)skb->data;
3032 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
3033 u8 queue_index = tcb_desc->queue_index;
3034 u32 PktSize = 0;
3036 //printk("\n %s::::::::::::::::::::::queue_index = %d\n",__FUNCTION__, queue_index);
3037 atomic_inc(&priv->tx_pending[queue_index]);
3039 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
3040 tx_urb = usb_alloc_urb(0,GFP_ATOMIC);
3041 #else
3042 tx_urb = usb_alloc_urb(0);
3043 #endif
3044 if(!tx_urb){
3045 dev_kfree_skb(skb);
3046 return -ENOMEM;
3049 memset(pdesc, 0, USB_HWDESC_HEADER_LEN);
3051 /* Tx descriptor ought to be set according to the skb->cb */
3052 pdesc->LINIP = tcb_desc->bLastIniPkt;
3053 PktSize = (u16)(skb->len - USB_HWDESC_HEADER_LEN);
3054 pdesc->PktSize = PktSize;
3055 //printk("PKTSize = %d %x\n",pdesc->PktSize,pdesc->PktSize);
3056 //----------------------------------------------------------------------------
3057 // Fill up USB_OUT_CONTEXT.
3058 //----------------------------------------------------------------------------
3059 // Get index to out pipe from specified QueueID.
3060 idx_pipe = txqueue2outpipe(priv,queue_index);
3061 //printk("=============>%s queue_index:%d, outpipe:%d\n", __func__,queue_index,priv->RtOutPipes[idx_pipe]);
3063 #ifdef JOHN_DUMP_TXDESC
3064 int i;
3065 printk("Len = %d\n", skb->len);
3066 for (i = 0; i < 8; i++)
3067 printk("%2.2x ", *((u8*)skb->data+i));
3068 printk("\n");
3069 #endif
3071 usb_fill_bulk_urb(tx_urb,
3072 priv->udev,
3073 usb_sndbulkpipe(priv->udev,priv->RtOutPipes[idx_pipe]),
3074 skb->data,
3075 skb->len,
3076 rtl8192_tx_isr,
3077 skb);
3079 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
3080 status = usb_submit_urb(tx_urb, GFP_ATOMIC);
3081 #else
3082 status = usb_submit_urb(tx_urb);
3083 #endif
3085 if (!status){
3086 return 0;
3087 }else{
3088 printk("Error TX CMD URB, error %d",
3089 status);
3090 return -1;
3093 #else
3094 short rtl819xU_tx_cmd(struct net_device *dev, struct sk_buff *skb)
3096 struct r8192_priv *priv = ieee80211_priv(dev);
3097 //u8 *tx;
3098 int status;
3099 struct urb *tx_urb;
3100 //int urb_buf_len;
3101 unsigned int idx_pipe;
3102 tx_desc_cmd_819x_usb *pdesc = (tx_desc_cmd_819x_usb *)skb->data;
3103 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
3104 u8 queue_index = tcb_desc->queue_index;
3106 //printk("\n %s::queue_index = %d\n",__FUNCTION__, queue_index);
3107 atomic_inc(&priv->tx_pending[queue_index]);
3108 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
3109 tx_urb = usb_alloc_urb(0,GFP_ATOMIC);
3110 #else
3111 tx_urb = usb_alloc_urb(0);
3112 #endif
3113 if(!tx_urb){
3114 dev_kfree_skb(skb);
3115 return -ENOMEM;
3118 memset(pdesc, 0, USB_HWDESC_HEADER_LEN);
3119 /* Tx descriptor ought to be set according to the skb->cb */
3120 pdesc->FirstSeg = 1;//bFirstSeg;
3121 pdesc->LastSeg = 1;//bLastSeg;
3122 pdesc->CmdInit = tcb_desc->bCmdOrInit;
3123 pdesc->TxBufferSize = tcb_desc->txbuf_size;
3124 pdesc->OWN = 1;
3125 pdesc->LINIP = tcb_desc->bLastIniPkt;
3127 //----------------------------------------------------------------------------
3128 // Fill up USB_OUT_CONTEXT.
3129 //----------------------------------------------------------------------------
3130 // Get index to out pipe from specified QueueID.
3131 #ifndef USE_ONE_PIPE
3132 idx_pipe = txqueue2outpipe(priv,queue_index);
3133 #else
3134 idx_pipe = 0x04;
3135 #endif
3136 #ifdef JOHN_DUMP_TXDESC
3137 int i;
3138 printk("<Tx descriptor>--rate %x---",rate);
3139 for (i = 0; i < 8; i++)
3140 printk("%8x ", tx[i]);
3141 printk("\n");
3142 #endif
3143 usb_fill_bulk_urb(tx_urb,priv->udev, usb_sndbulkpipe(priv->udev,idx_pipe), \
3144 skb->data, skb->len, rtl8192_tx_isr, skb);
3146 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
3147 status = usb_submit_urb(tx_urb, GFP_ATOMIC);
3148 #else
3149 status = usb_submit_urb(tx_urb);
3150 #endif
3152 if (!status){
3153 return 0;
3154 }else{
3155 DMESGE("Error TX CMD URB, error %d",
3156 status);
3157 return -1;
3160 #endif
3163 * Mapping Software/Hardware descriptor queue id to "Queue Select Field"
3164 * in TxFwInfo data structure
3165 * 2006.10.30 by Emily
3167 * \param QUEUEID Software Queue
3169 u8 MapHwQueueToFirmwareQueue(u8 QueueID)
3171 u8 QueueSelect = 0x0; //defualt set to
3173 switch(QueueID) {
3174 case BE_QUEUE:
3175 QueueSelect = QSLT_BE; //or QSelect = pTcb->priority;
3176 break;
3178 case BK_QUEUE:
3179 QueueSelect = QSLT_BK; //or QSelect = pTcb->priority;
3180 break;
3182 case VO_QUEUE:
3183 QueueSelect = QSLT_VO; //or QSelect = pTcb->priority;
3184 break;
3186 case VI_QUEUE:
3187 QueueSelect = QSLT_VI; //or QSelect = pTcb->priority;
3188 break;
3189 case MGNT_QUEUE:
3190 QueueSelect = QSLT_MGNT;
3191 break;
3193 case BEACON_QUEUE:
3194 QueueSelect = QSLT_BEACON;
3195 break;
3197 // TODO: 2006.10.30 mark other queue selection until we verify it is OK
3198 // TODO: Remove Assertions
3199 //#if (RTL819X_FPGA_VER & RTL819X_FPGA_GUANGAN_070502)
3200 case TXCMD_QUEUE:
3201 QueueSelect = QSLT_CMD;
3202 break;
3203 //#endif
3204 case HIGH_QUEUE:
3205 QueueSelect = QSLT_HIGH;
3206 break;
3208 default:
3209 RT_TRACE(COMP_ERR, "TransmitTCB(): Impossible Queue Selection: %d \n", QueueID);
3210 break;
3212 return QueueSelect;
3215 #ifdef RTL8192SU
3216 u8 MRateToHwRate8190Pci(u8 rate)
3218 u8 ret = DESC92S_RATE1M;
3220 switch(rate)
3222 // CCK and OFDM non-HT rates
3223 case MGN_1M: ret = DESC92S_RATE1M; break;
3224 case MGN_2M: ret = DESC92S_RATE2M; break;
3225 case MGN_5_5M: ret = DESC92S_RATE5_5M; break;
3226 case MGN_11M: ret = DESC92S_RATE11M; break;
3227 case MGN_6M: ret = DESC92S_RATE6M; break;
3228 case MGN_9M: ret = DESC92S_RATE9M; break;
3229 case MGN_12M: ret = DESC92S_RATE12M; break;
3230 case MGN_18M: ret = DESC92S_RATE18M; break;
3231 case MGN_24M: ret = DESC92S_RATE24M; break;
3232 case MGN_36M: ret = DESC92S_RATE36M; break;
3233 case MGN_48M: ret = DESC92S_RATE48M; break;
3234 case MGN_54M: ret = DESC92S_RATE54M; break;
3236 // HT rates since here
3237 case MGN_MCS0: ret = DESC92S_RATEMCS0; break;
3238 case MGN_MCS1: ret = DESC92S_RATEMCS1; break;
3239 case MGN_MCS2: ret = DESC92S_RATEMCS2; break;
3240 case MGN_MCS3: ret = DESC92S_RATEMCS3; break;
3241 case MGN_MCS4: ret = DESC92S_RATEMCS4; break;
3242 case MGN_MCS5: ret = DESC92S_RATEMCS5; break;
3243 case MGN_MCS6: ret = DESC92S_RATEMCS6; break;
3244 case MGN_MCS7: ret = DESC92S_RATEMCS7; break;
3245 case MGN_MCS8: ret = DESC92S_RATEMCS8; break;
3246 case MGN_MCS9: ret = DESC92S_RATEMCS9; break;
3247 case MGN_MCS10: ret = DESC92S_RATEMCS10; break;
3248 case MGN_MCS11: ret = DESC92S_RATEMCS11; break;
3249 case MGN_MCS12: ret = DESC92S_RATEMCS12; break;
3250 case MGN_MCS13: ret = DESC92S_RATEMCS13; break;
3251 case MGN_MCS14: ret = DESC92S_RATEMCS14; break;
3252 case MGN_MCS15: ret = DESC92S_RATEMCS15; break;
3254 // Set the highest SG rate
3255 case MGN_MCS0_SG:
3256 case MGN_MCS1_SG:
3257 case MGN_MCS2_SG:
3258 case MGN_MCS3_SG:
3259 case MGN_MCS4_SG:
3260 case MGN_MCS5_SG:
3261 case MGN_MCS6_SG:
3262 case MGN_MCS7_SG:
3263 case MGN_MCS8_SG:
3264 case MGN_MCS9_SG:
3265 case MGN_MCS10_SG:
3266 case MGN_MCS11_SG:
3267 case MGN_MCS12_SG:
3268 case MGN_MCS13_SG:
3269 case MGN_MCS14_SG:
3270 case MGN_MCS15_SG:
3272 ret = DESC92S_RATEMCS15_SG;
3273 break;
3276 default: break;
3278 return ret;
3280 #else
3281 u8 MRateToHwRate8190Pci(u8 rate)
3283 u8 ret = DESC90_RATE1M;
3285 switch(rate) {
3286 case MGN_1M: ret = DESC90_RATE1M; break;
3287 case MGN_2M: ret = DESC90_RATE2M; break;
3288 case MGN_5_5M: ret = DESC90_RATE5_5M; break;
3289 case MGN_11M: ret = DESC90_RATE11M; break;
3290 case MGN_6M: ret = DESC90_RATE6M; break;
3291 case MGN_9M: ret = DESC90_RATE9M; break;
3292 case MGN_12M: ret = DESC90_RATE12M; break;
3293 case MGN_18M: ret = DESC90_RATE18M; break;
3294 case MGN_24M: ret = DESC90_RATE24M; break;
3295 case MGN_36M: ret = DESC90_RATE36M; break;
3296 case MGN_48M: ret = DESC90_RATE48M; break;
3297 case MGN_54M: ret = DESC90_RATE54M; break;
3299 // HT rate since here
3300 case MGN_MCS0: ret = DESC90_RATEMCS0; break;
3301 case MGN_MCS1: ret = DESC90_RATEMCS1; break;
3302 case MGN_MCS2: ret = DESC90_RATEMCS2; break;
3303 case MGN_MCS3: ret = DESC90_RATEMCS3; break;
3304 case MGN_MCS4: ret = DESC90_RATEMCS4; break;
3305 case MGN_MCS5: ret = DESC90_RATEMCS5; break;
3306 case MGN_MCS6: ret = DESC90_RATEMCS6; break;
3307 case MGN_MCS7: ret = DESC90_RATEMCS7; break;
3308 case MGN_MCS8: ret = DESC90_RATEMCS8; break;
3309 case MGN_MCS9: ret = DESC90_RATEMCS9; break;
3310 case MGN_MCS10: ret = DESC90_RATEMCS10; break;
3311 case MGN_MCS11: ret = DESC90_RATEMCS11; break;
3312 case MGN_MCS12: ret = DESC90_RATEMCS12; break;
3313 case MGN_MCS13: ret = DESC90_RATEMCS13; break;
3314 case MGN_MCS14: ret = DESC90_RATEMCS14; break;
3315 case MGN_MCS15: ret = DESC90_RATEMCS15; break;
3316 case (0x80|0x20): ret = DESC90_RATEMCS32; break;
3318 default: break;
3320 return ret;
3322 #endif
3324 u8 QueryIsShort(u8 TxHT, u8 TxRate, cb_desc *tcb_desc)
3326 u8 tmp_Short;
3328 tmp_Short = (TxHT==1)?((tcb_desc->bUseShortGI)?1:0):((tcb_desc->bUseShortPreamble)?1:0);
3330 if(TxHT==1 && TxRate != DESC90_RATEMCS15)
3331 tmp_Short = 0;
3333 return tmp_Short;
3336 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
3337 static void tx_zero_isr(struct urb *tx_urb, struct pt_regs *reg)
3338 #else
3339 static void tx_zero_isr(struct urb *tx_urb)
3340 #endif
3342 return;
3346 #ifdef RTL8192SU
3348 * The tx procedure is just as following, skb->cb will contain all the following
3349 *information: * priority, morefrag, rate, &dev.
3350 * */
3351 // <Note> Buffer format for 8192S Usb bulk out:
3353 // --------------------------------------------------
3354 // | 8192S Usb Tx Desc | 802_11_MAC_header | data |
3355 // --------------------------------------------------
3356 // | 32 bytes | 24 bytes |0-2318 bytes|
3357 // --------------------------------------------------
3358 // |<------------ BufferLen ------------------------->|
3360 short rtl8192SU_tx(struct net_device *dev, struct sk_buff* skb)
3362 struct r8192_priv *priv = ieee80211_priv(dev);
3363 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
3364 tx_desc_819x_usb *tx_desc = (tx_desc_819x_usb *)skb->data;
3365 //tx_fwinfo_819x_usb *tx_fwinfo = (tx_fwinfo_819x_usb *)(skb->data + USB_HWDESC_HEADER_LEN);//92su del
3366 struct usb_device *udev = priv->udev;
3367 int pend;
3368 int status;
3369 struct urb *tx_urb = NULL, *tx_urb_zero = NULL;
3370 //int urb_len;
3371 unsigned int idx_pipe;
3372 u16 MPDUOverhead = 0;
3373 //RT_DEBUG_DATA(COMP_SEND, tcb_desc, sizeof(cb_desc));
3375 #if 0
3376 /* Added by Annie for filling Len_Adjust field. 2005-12-14. */
3377 RT_ENC_ALG EncAlg = NO_Encryption;
3378 #endif
3381 pend = atomic_read(&priv->tx_pending[tcb_desc->queue_index]);
3382 /* we are locked here so the two atomic_read and inc are executed
3383 * without interleaves * !!! For debug purpose */
3384 if( pend > MAX_TX_URB){
3385 switch (tcb_desc->queue_index) {
3386 case VO_PRIORITY:
3387 priv->stats.txvodrop++;
3388 break;
3389 case VI_PRIORITY:
3390 priv->stats.txvidrop++;
3391 break;
3392 case BE_PRIORITY:
3393 priv->stats.txbedrop++;
3394 break;
3395 default://BK_PRIORITY
3396 priv->stats.txbkdrop++;
3397 break;
3399 printk("To discard skb packet!\n");
3400 dev_kfree_skb_any(skb);
3401 return -1;
3404 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
3405 tx_urb = usb_alloc_urb(0,GFP_ATOMIC);
3406 #else
3407 tx_urb = usb_alloc_urb(0);
3408 #endif
3409 if(!tx_urb){
3410 dev_kfree_skb_any(skb);
3411 return -ENOMEM;
3414 memset(tx_desc, 0, sizeof(tx_desc_819x_usb));
3417 #if RTL8192SU_FPGA_UNSPECIFIED_NETWORK
3418 if(IsQoSDataFrame(skb->data))
3420 tcb_desc->bAMPDUEnable = TRUE;
3421 tx_desc->NonQos = 0;
3423 else
3424 tcb_desc->bAMPDUEnable = FALSE;
3426 tcb_desc->bPacketBW = TRUE;
3427 priv->CurrentChannelBW = HT_CHANNEL_WIDTH_20_40;
3428 #endif
3430 #if (defined (RTL8192SU_FPGA_2MAC_VERIFICATION)||defined (RTL8192SU_ASIC_VERIFICATION))
3431 tx_desc->NonQos = (IsQoSDataFrame(skb->data)==TRUE)? 0:1;
3432 #endif
3434 /* Fill Tx descriptor */
3435 //memset(tx_fwinfo,0,sizeof(tx_fwinfo_819x_usb));
3437 // This part can just fill to the first descriptor of the frame.
3438 /* DWORD 0 */
3439 tx_desc->TxHT = (tcb_desc->data_rate&0x80)?1:0;
3441 #ifdef RTL8192SU_DISABLE_CCK_RATE
3442 if(tx_hal_is_cck_rate(tcb_desc->data_rate))
3443 tcb_desc->data_rate = MGN_6M;
3444 #endif
3446 tx_desc->TxRate = MRateToHwRate8190Pci(tcb_desc->data_rate);
3447 //tx_desc->EnableCPUDur = tcb_desc->bTxEnableFwCalcDur;
3448 tx_desc->TxShort = QueryIsShort(tx_desc->TxHT, tx_desc->TxRate, tcb_desc);
3451 // Aggregation related
3452 if(tcb_desc->bAMPDUEnable) {//AMPDU enabled
3453 tx_desc->AllowAggregation = 1;
3454 /* DWORD 1 */
3455 //tx_fwinfo->RxMF = tcb_desc->ampdu_factor;
3456 //tx_fwinfo->RxAMD = tcb_desc->ampdu_density&0x07;//ampdudensity
3457 } else {
3458 tx_desc->AllowAggregation = 0;
3459 /* DWORD 1 */
3460 //tx_fwinfo->RxMF = 0;
3461 //tx_fwinfo->RxAMD = 0;
3465 // <Roger_Notes> For AMPDU case, we must insert SSN into TX_DESC,
3466 // FW according as this SSN to do necessary packet retry.
3467 // 2008.06.06.
3470 u8 *pSeq;
3471 u16 Temp;
3472 //pSeq = (u8 *)(VirtualAddress+USB_HWDESC_HEADER_LEN + FRAME_OFFSET_SEQUENCE);
3473 pSeq = (u8 *)(skb->data+USB_HWDESC_HEADER_LEN + 22);
3474 Temp = pSeq[0];
3475 Temp <<= 12;
3476 Temp |= (*(u16 *)pSeq)>>4;
3477 tx_desc->Seq = Temp;
3480 /* Protection mode related */
3481 tx_desc->RTSEn = (tcb_desc->bRTSEnable)?1:0;
3482 tx_desc->CTS2Self = (tcb_desc->bCTSEnable)?1:0;
3483 tx_desc->RTSSTBC = (tcb_desc->bRTSSTBC)?1:0;
3484 tx_desc->RTSHT = (tcb_desc->rts_rate&0x80)?1:0;
3485 tx_desc->RTSRate = MRateToHwRate8190Pci((u8)tcb_desc->rts_rate);
3486 tx_desc->RTSSubcarrier = (tx_desc->RTSHT==0)?(tcb_desc->RTSSC):0;
3487 tx_desc->RTSBW = (tx_desc->RTSHT==1)?((tcb_desc->bRTSBW)?1:0):0;
3488 tx_desc->RTSShort = (tx_desc->RTSHT==0)?(tcb_desc->bRTSUseShortPreamble?1:0):\
3489 (tcb_desc->bRTSUseShortGI?1:0);
3490 //LZM 090219
3491 tx_desc->DisRTSFB = 0;
3492 tx_desc->RTSRateFBLmt = 0xf;
3494 // <Roger_EXP> 2008.09.22. We disable RTS rate fallback temporarily.
3495 //tx_desc->DisRTSFB = 0x01;
3497 /* Set Bandwidth and sub-channel settings. */
3498 if(priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20_40)
3500 if(tcb_desc->bPacketBW) {
3501 tx_desc->TxBandwidth = 1;
3502 tx_desc->TxSubCarrier = 0; //By SD3's Jerry suggestion, use duplicated mode
3503 } else {
3504 tx_desc->TxBandwidth = 0;
3505 tx_desc->TxSubCarrier = priv->nCur40MhzPrimeSC;
3507 } else {
3508 tx_desc->TxBandwidth = 0;
3509 tx_desc->TxSubCarrier = 0;
3512 #ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
3513 if (tcb_desc->drv_agg_enable)
3515 //tx_desc->Tx_INFO_RSVD = (tcb_desc->DrvAggrNum & 0x1f) << 1; //92su del
3517 #endif
3519 //memset(tx_desc, 0, sizeof(tx_desc_819x_usb));
3520 /* DWORD 0 */
3521 tx_desc->LINIP = 0;
3522 //tx_desc->CmdInit = 1; //92su del
3523 tx_desc->Offset = USB_HWDESC_HEADER_LEN;
3525 #ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
3526 if (tcb_desc->drv_agg_enable) {
3527 tx_desc->PktSize = tcb_desc->pkt_size;//FIXLZM
3528 } else
3529 #endif
3531 tx_desc->PktSize = (skb->len - USB_HWDESC_HEADER_LEN) & 0xffff;
3534 /*DWORD 1*/
3535 //tx_desc->SecCAMID= 0;//92su del
3536 tx_desc->RaBRSRID= tcb_desc->RATRIndex;
3537 //#ifdef RTL8192S_PREPARE_FOR_NORMAL_RELEASE
3538 #if 0//LZM 090219
3539 tx_desc->RaBRSRID= 1;
3540 #endif
3542 #if 0
3543 /* Fill security related */
3544 if( pTcb->bEncrypt && !Adapter->MgntInfo.SecurityInfo.SWTxEncryptFlag)
3546 EncAlg = SecGetEncryptionOverhead(
3547 Adapter,
3548 &EncryptionMPDUHeadOverhead,
3549 &EncryptionMPDUTailOverhead,
3550 NULL,
3551 NULL,
3552 FALSE,
3553 FALSE);
3554 //2004/07/22, kcwu, EncryptionMPDUHeadOverhead has been added in previous code
3555 //MPDUOverhead = EncryptionMPDUHeadOverhead + EncryptionMPDUTailOverhead;
3556 MPDUOverhead = EncryptionMPDUTailOverhead;
3557 tx_desc->NoEnc = 0;
3558 RT_TRACE(COMP_SEC, DBG_LOUD, ("******We in the loop SecCAMID is %d SecDescAssign is %d The Sec is %d********\n",tx_desc->SecCAMID,tx_desc->SecDescAssign,EncAlg));
3559 //CamDumpAll(Adapter);
3561 else
3562 #endif
3564 MPDUOverhead = 0;
3565 //tx_desc->NoEnc = 1;//92su del
3567 #if 0
3568 switch(EncAlg){
3569 case NO_Encryption:
3570 tx_desc->SecType = 0x0;
3571 break;
3572 case WEP40_Encryption:
3573 case WEP104_Encryption:
3574 tx_desc->SecType = 0x1;
3575 break;
3576 case TKIP_Encryption:
3577 tx_desc->SecType = 0x2;
3578 break;
3579 case AESCCMP_Encryption:
3580 tx_desc->SecType = 0x3;
3581 break;
3582 default:
3583 tx_desc->SecType = 0x0;
3584 break;
3586 #else
3587 tx_desc->SecType = 0x0;
3588 #endif
3589 if (tcb_desc->bHwSec)
3591 switch (priv->ieee80211->pairwise_key_type)
3593 case KEY_TYPE_WEP40:
3594 case KEY_TYPE_WEP104:
3595 tx_desc->SecType = 0x1;
3596 //tx_desc->NoEnc = 0;//92su del
3597 break;
3598 case KEY_TYPE_TKIP:
3599 tx_desc->SecType = 0x2;
3600 //tx_desc->NoEnc = 0;//92su del
3601 break;
3602 case KEY_TYPE_CCMP:
3603 tx_desc->SecType = 0x3;
3604 //tx_desc->NoEnc = 0;//92su del
3605 break;
3606 case KEY_TYPE_NA:
3607 tx_desc->SecType = 0x0;
3608 //tx_desc->NoEnc = 1;//92su del
3609 break;
3610 default:
3611 tx_desc->SecType = 0x0;
3612 //tx_desc->NoEnc = 1;//92su del
3613 break;
3617 //tx_desc->TxFWInfoSize = sizeof(tx_fwinfo_819x_usb);//92su del
3620 tx_desc->USERATE = tcb_desc->bTxUseDriverAssingedRate;
3621 tx_desc->DISFB = tcb_desc->bTxDisableRateFallBack;
3622 tx_desc->DataRateFBLmt = 0x1F;// Alwasy enable all rate fallback range
3624 tx_desc->QueueSelect = MapHwQueueToFirmwareQueue(tcb_desc->queue_index);
3627 /* Fill fields that are required to be initialized in all of the descriptors */
3628 //DWORD 0
3629 #if 0
3630 tx_desc->FirstSeg = (tcb_desc->bFirstSeg)? 1:0;
3631 tx_desc->LastSeg = (tcb_desc->bLastSeg)?1:0;
3632 #else
3633 tx_desc->FirstSeg = 1;
3634 tx_desc->LastSeg = 1;
3635 #endif
3636 tx_desc->OWN = 1;
3638 #ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
3639 if (tcb_desc->drv_agg_enable) {
3640 tx_desc->TxBufferSize = tcb_desc->pkt_size + sizeof(tx_fwinfo_819x_usb);
3641 } else
3642 #endif
3644 //DWORD 2
3645 //tx_desc->TxBufferSize = (u32)(skb->len - USB_HWDESC_HEADER_LEN);
3646 tx_desc->TxBufferSize = (u32)(skb->len);//92su mod FIXLZM
3649 #if 0
3650 RT_TRACE(COMP_FPGA, DBG_LOUD, ("(1)TxFillDescriptor8192SUsb(): DataRate(%#x)\n", pTcb->DataRate));
3651 RT_TRACE(COMP_FPGA, DBG_LOUD, ("(2)TxFillDescriptor8192SUsb(): bTxUseDriverAssingedRate(%#x)\n", pTcb->bTxUseDriverAssingedRate));
3652 RT_TRACE(COMP_FPGA, DBG_LOUD, ("(3)TxFillDescriptor8192SUsb(): bAMPDUEnable(%d)\n", pTcb->bAMPDUEnable));
3653 RT_TRACE(COMP_FPGA, DBG_LOUD, ("(4)TxFillDescriptor8192SUsb(): bRTSEnable(%d)\n", pTcb->bRTSEnable));
3654 RT_TRACE(COMP_FPGA, DBG_LOUD, ("(5)TxFillDescriptor8192SUsb(): RTSRate(%#x)\n", pTcb->RTSRate));
3655 RT_TRACE(COMP_FPGA, DBG_LOUD, ("(6)TxFillDescriptor8192SUsb(): bCTSEnable(%d)\n", pTcb->bCTSEnable));
3656 RT_TRACE(COMP_FPGA, DBG_LOUD, ("(7)TxFillDescriptor8192SUsb(): bUseShortGI(%d)\n", pTcb->bUseShortGI));
3657 RT_TRACE(COMP_FPGA, DBG_LOUD, ("(8)TxFillDescriptor8192SUsb(): bPacketBW(%d)\n", pTcb->bPacketBW));
3658 RT_TRACE(COMP_FPGA, DBG_LOUD, ("(9)TxFillDescriptor8192SUsb(): CurrentChannelBW(%d)\n", pHalData->CurrentChannelBW));
3659 RT_TRACE(COMP_FPGA, DBG_LOUD, ("(10)TxFillDescriptor8192SUsb(): bTxDisableRateFallBack(%d)\n", pTcb->bTxDisableRateFallBack));
3660 RT_TRACE(COMP_FPGA, DBG_LOUD, ("(11)TxFillDescriptor8192SUsb(): RATRIndex(%d)\n", pTcb->RATRIndex));
3661 #endif
3663 /* Get index to out pipe from specified QueueID */
3664 idx_pipe = txqueue2outpipe(priv,tcb_desc->queue_index);
3665 //printk("=============>%s queue_index:%d, outpipe:%d\n", __func__,tcb_desc->queue_index,priv->RtOutPipes[idx_pipe]);
3667 //RT_DEBUG_DATA(COMP_SEND,tx_fwinfo,sizeof(tx_fwinfo_819x_usb));
3668 //RT_DEBUG_DATA(COMP_SEND,tx_desc,sizeof(tx_desc_819x_usb));
3670 /* To submit bulk urb */
3671 usb_fill_bulk_urb(tx_urb,
3672 udev,
3673 usb_sndbulkpipe(udev,priv->RtOutPipes[idx_pipe]),
3674 skb->data,
3675 skb->len, rtl8192_tx_isr, skb);
3677 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
3678 status = usb_submit_urb(tx_urb, GFP_ATOMIC);
3679 #else
3680 status = usb_submit_urb(tx_urb);
3681 #endif
3682 if (!status){
3683 //we need to send 0 byte packet whenever 512N bytes/64N(HIGN SPEED/NORMAL SPEED) bytes packet has been transmitted. Otherwise, it will be halt to wait for another packet. WB. 2008.08.27
3684 bool bSend0Byte = false;
3685 u8 zero = 0;
3686 if(udev->speed == USB_SPEED_HIGH)
3688 if (skb->len > 0 && skb->len % 512 == 0)
3689 bSend0Byte = true;
3691 else
3693 if (skb->len > 0 && skb->len % 64 == 0)
3694 bSend0Byte = true;
3696 if (bSend0Byte)
3698 #if 1
3699 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
3700 tx_urb_zero = usb_alloc_urb(0,GFP_ATOMIC);
3701 #else
3702 tx_urb_zero = usb_alloc_urb(0);
3703 #endif
3704 if(!tx_urb_zero){
3705 RT_TRACE(COMP_ERR, "can't alloc urb for zero byte\n");
3706 return -ENOMEM;
3708 usb_fill_bulk_urb(tx_urb_zero,udev,
3709 usb_sndbulkpipe(udev,idx_pipe), &zero,
3710 0, tx_zero_isr, dev);
3711 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
3712 status = usb_submit_urb(tx_urb_zero, GFP_ATOMIC);
3713 #else
3714 status = usb_submit_urb(tx_urb_zero);
3715 #endif
3716 if (status){
3717 RT_TRACE(COMP_ERR, "Error TX URB for zero byte %d, error %d", atomic_read(&priv->tx_pending[tcb_desc->queue_index]), status);
3718 return -1;
3720 #endif
3722 dev->trans_start = jiffies;
3723 atomic_inc(&priv->tx_pending[tcb_desc->queue_index]);
3724 return 0;
3725 }else{
3726 RT_TRACE(COMP_ERR, "Error TX URB %d, error %d", atomic_read(&priv->tx_pending[tcb_desc->queue_index]),
3727 status);
3728 return -1;
3731 #else
3734 * The tx procedure is just as following,
3735 * skb->cb will contain all the following information,
3736 * priority, morefrag, rate, &dev.
3737 * */
3738 short rtl8192_tx(struct net_device *dev, struct sk_buff* skb)
3740 struct r8192_priv *priv = ieee80211_priv(dev);
3741 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
3742 tx_desc_819x_usb *tx_desc = (tx_desc_819x_usb *)skb->data;
3743 tx_fwinfo_819x_usb *tx_fwinfo = (tx_fwinfo_819x_usb *)(skb->data + USB_HWDESC_HEADER_LEN);
3744 struct usb_device *udev = priv->udev;
3745 int pend;
3746 int status;
3747 struct urb *tx_urb = NULL, *tx_urb_zero = NULL;
3748 //int urb_len;
3749 unsigned int idx_pipe;
3750 // RT_DEBUG_DATA(COMP_SEND, tcb_desc, sizeof(cb_desc));
3751 #if 0
3752 /* Added by Annie for filling Len_Adjust field. 2005-12-14. */
3753 RT_ENC_ALG EncAlg = NO_Encryption;
3754 #endif
3755 // printk("=============> %s\n", __FUNCTION__);
3756 pend = atomic_read(&priv->tx_pending[tcb_desc->queue_index]);
3757 /* we are locked here so the two atomic_read and inc are executed
3758 * without interleaves
3759 * !!! For debug purpose
3761 if( pend > MAX_TX_URB){
3762 #if 0
3763 switch (tcb_desc->queue_index) {
3764 case VO_PRIORITY:
3765 priv->stats.txvodrop++;
3766 break;
3767 case VI_PRIORITY:
3768 priv->stats.txvidrop++;
3769 break;
3770 case BE_PRIORITY:
3771 priv->stats.txbedrop++;
3772 break;
3773 default://BK_PRIORITY
3774 priv->stats.txbkdrop++;
3775 break;
3777 #endif
3778 printk("To discard skb packet!\n");
3779 dev_kfree_skb_any(skb);
3780 return -1;
3783 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
3784 tx_urb = usb_alloc_urb(0,GFP_ATOMIC);
3785 #else
3786 tx_urb = usb_alloc_urb(0);
3787 #endif
3788 if(!tx_urb){
3789 dev_kfree_skb_any(skb);
3790 return -ENOMEM;
3793 /* Fill Tx firmware info */
3794 memset(tx_fwinfo,0,sizeof(tx_fwinfo_819x_usb));
3795 /* DWORD 0 */
3796 tx_fwinfo->TxHT = (tcb_desc->data_rate&0x80)?1:0;
3797 tx_fwinfo->TxRate = MRateToHwRate8190Pci(tcb_desc->data_rate);
3798 tx_fwinfo->EnableCPUDur = tcb_desc->bTxEnableFwCalcDur;
3799 tx_fwinfo->Short = QueryIsShort(tx_fwinfo->TxHT, tx_fwinfo->TxRate, tcb_desc);
3800 if(tcb_desc->bAMPDUEnable) {//AMPDU enabled
3801 tx_fwinfo->AllowAggregation = 1;
3802 /* DWORD 1 */
3803 tx_fwinfo->RxMF = tcb_desc->ampdu_factor;
3804 tx_fwinfo->RxAMD = tcb_desc->ampdu_density&0x07;//ampdudensity
3805 } else {
3806 tx_fwinfo->AllowAggregation = 0;
3807 /* DWORD 1 */
3808 tx_fwinfo->RxMF = 0;
3809 tx_fwinfo->RxAMD = 0;
3812 /* Protection mode related */
3813 tx_fwinfo->RtsEnable = (tcb_desc->bRTSEnable)?1:0;
3814 tx_fwinfo->CtsEnable = (tcb_desc->bCTSEnable)?1:0;
3815 tx_fwinfo->RtsSTBC = (tcb_desc->bRTSSTBC)?1:0;
3816 tx_fwinfo->RtsHT = (tcb_desc->rts_rate&0x80)?1:0;
3817 tx_fwinfo->RtsRate = MRateToHwRate8190Pci((u8)tcb_desc->rts_rate);
3818 tx_fwinfo->RtsSubcarrier = (tx_fwinfo->RtsHT==0)?(tcb_desc->RTSSC):0;
3819 tx_fwinfo->RtsBandwidth = (tx_fwinfo->RtsHT==1)?((tcb_desc->bRTSBW)?1:0):0;
3820 tx_fwinfo->RtsShort = (tx_fwinfo->RtsHT==0)?(tcb_desc->bRTSUseShortPreamble?1:0):\
3821 (tcb_desc->bRTSUseShortGI?1:0);
3823 /* Set Bandwidth and sub-channel settings. */
3824 if(priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20_40)
3826 if(tcb_desc->bPacketBW) {
3827 tx_fwinfo->TxBandwidth = 1;
3828 tx_fwinfo->TxSubCarrier = 0; //By SD3's Jerry suggestion, use duplicated mode
3829 } else {
3830 tx_fwinfo->TxBandwidth = 0;
3831 tx_fwinfo->TxSubCarrier = priv->nCur40MhzPrimeSC;
3833 } else {
3834 tx_fwinfo->TxBandwidth = 0;
3835 tx_fwinfo->TxSubCarrier = 0;
3838 #ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
3839 if (tcb_desc->drv_agg_enable)
3841 tx_fwinfo->Tx_INFO_RSVD = (tcb_desc->DrvAggrNum & 0x1f) << 1;
3843 #endif
3844 /* Fill Tx descriptor */
3845 memset(tx_desc, 0, sizeof(tx_desc_819x_usb));
3846 /* DWORD 0 */
3847 tx_desc->LINIP = 0;
3848 tx_desc->CmdInit = 1;
3849 tx_desc->Offset = sizeof(tx_fwinfo_819x_usb) + 8;
3851 #ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
3852 if (tcb_desc->drv_agg_enable) {
3853 tx_desc->PktSize = tcb_desc->pkt_size;
3854 } else
3855 #endif
3857 tx_desc->PktSize = (skb->len - TX_PACKET_SHIFT_BYTES) & 0xffff;
3860 /*DWORD 1*/
3861 tx_desc->SecCAMID= 0;
3862 tx_desc->RATid = tcb_desc->RATRIndex;
3863 #if 0
3864 /* Fill security related */
3865 if( pTcb->bEncrypt && !Adapter->MgntInfo.SecurityInfo.SWTxEncryptFlag)
3867 EncAlg = SecGetEncryptionOverhead(
3868 Adapter,
3869 &EncryptionMPDUHeadOverhead,
3870 &EncryptionMPDUTailOverhead,
3871 NULL,
3872 NULL,
3873 FALSE,
3874 FALSE);
3875 //2004/07/22, kcwu, EncryptionMPDUHeadOverhead has been added in previous code
3876 //MPDUOverhead = EncryptionMPDUHeadOverhead + EncryptionMPDUTailOverhead;
3877 MPDUOverhead = EncryptionMPDUTailOverhead;
3878 tx_desc->NoEnc = 0;
3879 RT_TRACE(COMP_SEC, DBG_LOUD, ("******We in the loop SecCAMID is %d SecDescAssign is %d The Sec is %d********\n",tx_desc->SecCAMID,tx_desc->SecDescAssign,EncAlg));
3880 //CamDumpAll(Adapter);
3882 else
3883 #endif
3885 //MPDUOverhead = 0;
3886 tx_desc->NoEnc = 1;
3888 #if 0
3889 switch(EncAlg){
3890 case NO_Encryption:
3891 tx_desc->SecType = 0x0;
3892 break;
3893 case WEP40_Encryption:
3894 case WEP104_Encryption:
3895 tx_desc->SecType = 0x1;
3896 break;
3897 case TKIP_Encryption:
3898 tx_desc->SecType = 0x2;
3899 break;
3900 case AESCCMP_Encryption:
3901 tx_desc->SecType = 0x3;
3902 break;
3903 default:
3904 tx_desc->SecType = 0x0;
3905 break;
3907 #else
3908 tx_desc->SecType = 0x0;
3909 #endif
3910 if (tcb_desc->bHwSec)
3912 switch (priv->ieee80211->pairwise_key_type)
3914 case KEY_TYPE_WEP40:
3915 case KEY_TYPE_WEP104:
3916 tx_desc->SecType = 0x1;
3917 tx_desc->NoEnc = 0;
3918 break;
3919 case KEY_TYPE_TKIP:
3920 tx_desc->SecType = 0x2;
3921 tx_desc->NoEnc = 0;
3922 break;
3923 case KEY_TYPE_CCMP:
3924 tx_desc->SecType = 0x3;
3925 tx_desc->NoEnc = 0;
3926 break;
3927 case KEY_TYPE_NA:
3928 tx_desc->SecType = 0x0;
3929 tx_desc->NoEnc = 1;
3930 break;
3934 tx_desc->QueueSelect = MapHwQueueToFirmwareQueue(tcb_desc->queue_index);
3935 tx_desc->TxFWInfoSize = sizeof(tx_fwinfo_819x_usb);
3937 tx_desc->DISFB = tcb_desc->bTxDisableRateFallBack;
3938 tx_desc->USERATE = tcb_desc->bTxUseDriverAssingedRate;
3940 /* Fill fields that are required to be initialized in all of the descriptors */
3941 //DWORD 0
3942 #if 0
3943 tx_desc->FirstSeg = (tcb_desc->bFirstSeg)? 1:0;
3944 tx_desc->LastSeg = (tcb_desc->bLastSeg)?1:0;
3945 #else
3946 tx_desc->FirstSeg = 1;
3947 tx_desc->LastSeg = 1;
3948 #endif
3949 tx_desc->OWN = 1;
3951 #ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
3952 if (tcb_desc->drv_agg_enable) {
3953 tx_desc->TxBufferSize = tcb_desc->pkt_size + sizeof(tx_fwinfo_819x_usb);
3954 } else
3955 #endif
3957 //DWORD 2
3958 tx_desc->TxBufferSize = (u32)(skb->len - USB_HWDESC_HEADER_LEN);
3960 /* Get index to out pipe from specified QueueID */
3961 #ifndef USE_ONE_PIPE
3962 idx_pipe = txqueue2outpipe(priv,tcb_desc->queue_index);
3963 #else
3964 idx_pipe = 0x5;
3965 #endif
3967 //RT_DEBUG_DATA(COMP_SEND,tx_fwinfo,sizeof(tx_fwinfo_819x_usb));
3968 //RT_DEBUG_DATA(COMP_SEND,tx_desc,sizeof(tx_desc_819x_usb));
3970 /* To submit bulk urb */
3971 usb_fill_bulk_urb(tx_urb,udev,
3972 usb_sndbulkpipe(udev,idx_pipe), skb->data,
3973 skb->len, rtl8192_tx_isr, skb);
3975 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
3976 status = usb_submit_urb(tx_urb, GFP_ATOMIC);
3977 #else
3978 status = usb_submit_urb(tx_urb);
3979 #endif
3980 if (!status){
3981 //we need to send 0 byte packet whenever 512N bytes/64N(HIGN SPEED/NORMAL SPEED) bytes packet has been transmitted. Otherwise, it will be halt to wait for another packet. WB. 2008.08.27
3982 bool bSend0Byte = false;
3983 u8 zero = 0;
3984 if(udev->speed == USB_SPEED_HIGH)
3986 if (skb->len > 0 && skb->len % 512 == 0)
3987 bSend0Byte = true;
3989 else
3991 if (skb->len > 0 && skb->len % 64 == 0)
3992 bSend0Byte = true;
3994 if (bSend0Byte)
3996 #if 1
3997 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
3998 tx_urb_zero = usb_alloc_urb(0,GFP_ATOMIC);
3999 #else
4000 tx_urb_zero = usb_alloc_urb(0);
4001 #endif
4002 if(!tx_urb_zero){
4003 RT_TRACE(COMP_ERR, "can't alloc urb for zero byte\n");
4004 return -ENOMEM;
4006 usb_fill_bulk_urb(tx_urb_zero,udev,
4007 usb_sndbulkpipe(udev,idx_pipe), &zero,
4008 0, tx_zero_isr, dev);
4009 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
4010 status = usb_submit_urb(tx_urb_zero, GFP_ATOMIC);
4011 #else
4012 status = usb_submit_urb(tx_urb_zero);
4013 #endif
4014 if (status){
4015 RT_TRACE(COMP_ERR, "Error TX URB for zero byte %d, error %d", atomic_read(&priv->tx_pending[tcb_desc->queue_index]), status);
4016 return -1;
4018 #endif
4020 dev->trans_start = jiffies;
4021 atomic_inc(&priv->tx_pending[tcb_desc->queue_index]);
4022 return 0;
4023 }else{
4024 RT_TRACE(COMP_ERR, "Error TX URB %d, error %d", atomic_read(&priv->tx_pending[tcb_desc->queue_index]),
4025 status);
4026 return -1;
4029 #endif
4031 #if 0
4032 void rtl8192_set_rate(struct net_device *dev)
4034 int i;
4035 u16 word;
4036 int basic_rate,min_rr_rate,max_rr_rate;
4038 // struct r8192_priv *priv = ieee80211_priv(dev);
4040 //if (ieee80211_is_54g(priv->ieee80211->current_network) &&
4041 // priv->ieee80211->state == IEEE80211_LINKED){
4042 basic_rate = ieeerate2rtlrate(240);
4043 min_rr_rate = ieeerate2rtlrate(60);
4044 max_rr_rate = ieeerate2rtlrate(240);
4047 // }else{
4048 // basic_rate = ieeerate2rtlrate(20);
4049 // min_rr_rate = ieeerate2rtlrate(10);
4050 // max_rr_rate = ieeerate2rtlrate(110);
4051 // }
4053 write_nic_byte(dev, RESP_RATE,
4054 max_rr_rate<<MAX_RESP_RATE_SHIFT| min_rr_rate<<MIN_RESP_RATE_SHIFT);
4056 //word = read_nic_word(dev, BRSR);
4057 word = read_nic_word(dev, BRSR_8187);
4058 word &= ~BRSR_MBR_8185;
4061 for(i=0;i<=basic_rate;i++)
4062 word |= (1<<i);
4064 //write_nic_word(dev, BRSR, word);
4065 write_nic_word(dev, BRSR_8187, word);
4066 //DMESG("RR:%x BRSR: %x", read_nic_byte(dev,RESP_RATE), read_nic_word(dev,BRSR));
4068 #endif
4071 #ifdef RTL8192SU
4072 void rtl8192SU_net_update(struct net_device *dev)
4075 struct r8192_priv *priv = ieee80211_priv(dev);
4076 struct ieee80211_device* ieee = priv->ieee80211;
4077 struct ieee80211_network *net = &priv->ieee80211->current_network;
4078 //u16 BcnTimeCfg = 0, BcnCW = 6, BcnIFS = 0xf;
4079 u16 rate_config = 0;
4080 u32 regTmp = 0;
4081 u8 rateIndex = 0;
4082 u8 retrylimit = 0x30;
4083 u16 cap = net->capability;
4085 priv->short_preamble = cap & WLAN_CAPABILITY_SHORT_PREAMBLE;
4087 //HW_VAR_BASIC_RATE
4088 //update Basic rate: RR, BRSR
4089 rtl8192_config_rate(dev, &rate_config); //HalSetBrateCfg
4091 #ifdef RTL8192SU_DISABLE_CCK_RATE
4092 priv->basic_rate = rate_config = rate_config & 0x150; // Disable CCK 11M, 5.5M, 2M, and 1M rates.
4093 #else
4094 priv->basic_rate = rate_config = rate_config & 0x15f;
4095 #endif
4097 // Set RRSR rate table.
4098 write_nic_byte(dev, RRSR, rate_config&0xff);
4099 write_nic_byte(dev, RRSR+1, (rate_config>>8)&0xff);
4101 // Set RTS initial rate
4102 while(rate_config > 0x1)
4104 rate_config = (rate_config>> 1);
4105 rateIndex++;
4107 write_nic_byte(dev, INIRTSMCS_SEL, rateIndex);
4108 //HW_VAR_BASIC_RATE
4110 //set ack preample
4111 regTmp = (priv->nCur40MhzPrimeSC) << 5;
4112 if (priv->short_preamble)
4113 regTmp |= 0x80;
4114 write_nic_byte(dev, RRSR+2, regTmp);
4116 write_nic_dword(dev,BSSIDR,((u32*)net->bssid)[0]);
4117 write_nic_word(dev,BSSIDR+4,((u16*)net->bssid)[2]);
4119 write_nic_word(dev, BCN_INTERVAL, net->beacon_interval);
4120 //2008.10.24 added by tynli for beacon changed.
4121 PHY_SetBeaconHwReg( dev, net->beacon_interval);
4123 rtl8192_update_cap(dev, cap);
4125 if (ieee->iw_mode == IW_MODE_ADHOC){
4126 retrylimit = 7;
4127 //we should enable ibss interrupt here, but disable it temporarily
4128 if (0){
4129 priv->irq_mask |= (IMR_BcnInt | IMR_BcnInt | IMR_TBDOK | IMR_TBDER);
4130 //rtl8192_irq_disable(dev);
4131 //rtl8192_irq_enable(dev);
4134 else{
4135 if (0){
4136 priv->irq_mask &= ~(IMR_BcnInt | IMR_BcnInt | IMR_TBDOK | IMR_TBDER);
4137 //rtl8192_irq_disable(dev);
4138 //rtl8192_irq_enable(dev);
4142 priv->ShortRetryLimit = priv->LongRetryLimit = retrylimit;
4144 write_nic_word(dev, RETRY_LIMIT,
4145 retrylimit << RETRY_LIMIT_SHORT_SHIFT | \
4146 retrylimit << RETRY_LIMIT_LONG_SHIFT);
4149 void rtl8192SU_update_ratr_table(struct net_device* dev)
4151 struct r8192_priv* priv = ieee80211_priv(dev);
4152 struct ieee80211_device* ieee = priv->ieee80211;
4153 u8* pMcsRate = ieee->dot11HTOperationalRateSet;
4154 //struct ieee80211_network *net = &ieee->current_network;
4155 u32 ratr_value = 0;
4157 u8 rate_index = 0;
4158 int WirelessMode = ieee->mode;
4159 u8 MimoPs = ieee->pHTInfo->PeerMimoPs;
4161 u8 bNMode = 0;
4163 rtl8192_config_rate(dev, (u16*)(&ratr_value));
4164 ratr_value |= (*(u16*)(pMcsRate)) << 12;
4166 //switch (ieee->mode)
4167 switch (WirelessMode)
4169 case IEEE_A:
4170 ratr_value &= 0x00000FF0;
4171 break;
4172 case IEEE_B:
4173 ratr_value &= 0x0000000D;
4174 break;
4175 case IEEE_G:
4176 ratr_value &= 0x00000FF5;
4177 break;
4178 case IEEE_N_24G:
4179 case IEEE_N_5G:
4181 bNMode = 1;
4183 if (MimoPs == 0) //MIMO_PS_STATIC
4185 ratr_value &= 0x0007F005;
4187 else
4188 { // MCS rate only => for 11N mode.
4189 u32 ratr_mask;
4191 // 1T2R or 1T1R, Spatial Stream 2 should be disabled
4192 if ( priv->rf_type == RF_1T2R ||
4193 priv->rf_type == RF_1T1R ||
4194 (ieee->pHTInfo->IOTAction & HT_IOT_ACT_DISABLE_TX_2SS) )
4195 ratr_mask = 0x000ff005;
4196 else
4197 ratr_mask = 0x0f0ff005;
4199 if((ieee->pHTInfo->bCurTxBW40MHz) &&
4200 !(ieee->pHTInfo->IOTAction & HT_IOT_ACT_DISABLE_TX_40_MHZ))
4201 ratr_mask |= 0x00000010; // Set 6MBps
4203 // Select rates for rate adaptive mechanism.
4204 ratr_value &= ratr_mask;
4207 break;
4208 default:
4209 if(0)
4211 if(priv->rf_type == RF_1T2R) // 1T2R, Spatial Stream 2 should be disabled
4213 ratr_value &= 0x000ff0f5;
4215 else
4217 ratr_value &= 0x0f0ff0f5;
4220 //printk("====>%s(), mode is not correct:%x\n", __FUNCTION__, ieee->mode);
4221 break;
4224 #ifdef RTL8192SU_DISABLE_CCK_RATE
4225 ratr_value &= 0x0FFFFFF0;
4226 #else
4227 ratr_value &= 0x0FFFFFFF;
4228 #endif
4230 // Get MAX MCS available.
4231 if ( (bNMode && ((ieee->pHTInfo->IOTAction & HT_IOT_ACT_DISABLE_SHORT_GI)==0)) &&
4232 ((ieee->pHTInfo->bCurBW40MHz && ieee->pHTInfo->bCurShortGI40MHz) ||
4233 (!ieee->pHTInfo->bCurBW40MHz && ieee->pHTInfo->bCurShortGI20MHz)))
4235 u8 shortGI_rate = 0;
4236 u32 tmp_ratr_value = 0;
4237 ratr_value |= 0x10000000;//???
4238 tmp_ratr_value = (ratr_value>>12);
4239 for(shortGI_rate=15; shortGI_rate>0; shortGI_rate--)
4241 if((1<<shortGI_rate) & tmp_ratr_value)
4242 break;
4244 shortGI_rate = (shortGI_rate<<12)|(shortGI_rate<<8)|(shortGI_rate<<4)|(shortGI_rate);
4245 write_nic_byte(dev, SG_RATE, shortGI_rate);
4246 //printk("==>SG_RATE:%x\n", read_nic_byte(dev, SG_RATE));
4248 write_nic_dword(dev, ARFR0+rate_index*4, ratr_value);
4249 printk("=============>ARFR0+rate_index*4:%#x\n", ratr_value);
4251 //2 UFWP
4252 if (ratr_value & 0xfffff000){
4253 //printk("===>set to N mode\n");
4254 HalSetFwCmd8192S(dev, FW_CMD_RA_REFRESH_N);
4256 else {
4257 //printk("===>set to B/G mode\n");
4258 HalSetFwCmd8192S(dev, FW_CMD_RA_REFRESH_BG);
4262 void rtl8192SU_link_change(struct net_device *dev)
4264 struct r8192_priv *priv = ieee80211_priv(dev);
4265 struct ieee80211_device* ieee = priv->ieee80211;
4266 //unsigned long flags;
4267 u32 reg = 0;
4269 printk("=====>%s 1\n", __func__);
4270 reg = read_nic_dword(dev, RCR);
4272 if (ieee->state == IEEE80211_LINKED)
4275 rtl8192SU_net_update(dev);
4276 rtl8192SU_update_ratr_table(dev);
4277 ieee->SetFwCmdHandler(dev, FW_CMD_HIGH_PWR_ENABLE);
4278 priv->ReceiveConfig = reg |= RCR_CBSSID;
4280 }else{
4281 priv->ReceiveConfig = reg &= ~RCR_CBSSID;
4285 write_nic_dword(dev, RCR, reg);
4286 rtl8192_update_msr(dev);
4288 printk("<=====%s 2\n", __func__);
4290 #else
4291 extern void rtl8192_update_ratr_table(struct net_device* dev);
4292 void rtl8192_link_change(struct net_device *dev)
4294 // int i;
4296 struct r8192_priv *priv = ieee80211_priv(dev);
4297 struct ieee80211_device* ieee = priv->ieee80211;
4298 //write_nic_word(dev, BCN_INTR_ITV, net->beacon_interval);
4299 if (ieee->state == IEEE80211_LINKED)
4301 rtl8192_net_update(dev);
4302 rtl8192_update_ratr_table(dev);
4303 #if 1
4304 //add this as in pure N mode, wep encryption will use software way, but there is no chance to set this as wep will not set group key in wext. WB.2008.07.08
4305 if ((KEY_TYPE_WEP40 == ieee->pairwise_key_type) || (KEY_TYPE_WEP104 == ieee->pairwise_key_type))
4306 EnableHWSecurityConfig8192(dev);
4307 #endif
4309 /*update timing params*/
4310 // RT_TRACE(COMP_CH, "========>%s(), chan:%d\n", __FUNCTION__, priv->chan);
4311 // rtl8192_set_chan(dev, priv->chan);
4312 if (ieee->iw_mode == IW_MODE_INFRA || ieee->iw_mode == IW_MODE_ADHOC)
4314 u32 reg = 0;
4315 reg = read_nic_dword(dev, RCR);
4316 if (priv->ieee80211->state == IEEE80211_LINKED)
4317 priv->ReceiveConfig = reg |= RCR_CBSSID;
4318 else
4319 priv->ReceiveConfig = reg &= ~RCR_CBSSID;
4320 write_nic_dword(dev, RCR, reg);
4323 // rtl8192_set_rxconf(dev);
4325 #endif
4327 static struct ieee80211_qos_parameters def_qos_parameters = {
4328 {3,3,3,3},/* cw_min */
4329 {7,7,7,7},/* cw_max */
4330 {2,2,2,2},/* aifs */
4331 {0,0,0,0},/* flags */
4332 {0,0,0,0} /* tx_op_limit */
4336 #if LINUX_VERSION_CODE >=KERNEL_VERSION(2,6,20)
4337 void rtl8192_update_beacon(struct work_struct * work)
4339 struct r8192_priv *priv = container_of(work, struct r8192_priv, update_beacon_wq.work);
4340 struct net_device *dev = priv->ieee80211->dev;
4341 #else
4342 void rtl8192_update_beacon(struct net_device *dev)
4344 struct r8192_priv *priv = ieee80211_priv(dev);
4345 #endif
4346 struct ieee80211_device* ieee = priv->ieee80211;
4347 struct ieee80211_network* net = &ieee->current_network;
4349 if (ieee->pHTInfo->bCurrentHTSupport)
4350 HTUpdateSelfAndPeerSetting(ieee, net);
4351 ieee->pHTInfo->bCurrentRT2RTLongSlotTime = net->bssht.bdRT2RTLongSlotTime;
4352 // Joseph test for turbo mode with AP
4353 ieee->pHTInfo->RT2RT_HT_Mode = net->bssht.RT2RT_HT_Mode;
4354 rtl8192_update_cap(dev, net->capability);
4357 * background support to run QoS activate functionality
4359 int WDCAPARA_ADD[] = {EDCAPARA_BE,EDCAPARA_BK,EDCAPARA_VI,EDCAPARA_VO};
4360 #if LINUX_VERSION_CODE >=KERNEL_VERSION(2,6,20)
4361 void rtl8192_qos_activate(struct work_struct * work)
4363 struct r8192_priv *priv = container_of(work, struct r8192_priv, qos_activate);
4364 struct net_device *dev = priv->ieee80211->dev;
4365 #else
4366 void rtl8192_qos_activate(struct net_device *dev)
4368 struct r8192_priv *priv = ieee80211_priv(dev);
4369 #endif
4370 struct ieee80211_qos_parameters *qos_parameters = &priv->ieee80211->current_network.qos_data.parameters;
4371 u8 mode = priv->ieee80211->current_network.mode;
4372 //u32 size = sizeof(struct ieee80211_qos_parameters);
4373 u8 u1bAIFS;
4374 u32 u4bAcParam;
4375 int i;
4377 if (priv == NULL)
4378 return;
4380 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16))
4381 down(&priv->mutex);
4382 #else
4383 mutex_lock(&priv->mutex);
4384 #endif
4385 if(priv->ieee80211->state != IEEE80211_LINKED)
4386 goto success;
4387 RT_TRACE(COMP_QOS,"qos active process with associate response received\n");
4388 /* It better set slot time at first */
4389 /* For we just support b/g mode at present, let the slot time at 9/20 selection */
4390 /* update the ac parameter to related registers */
4391 for(i = 0; i < QOS_QUEUE_NUM; i++) {
4392 //Mode G/A: slotTimeTimer = 9; Mode B: 20
4393 u1bAIFS = qos_parameters->aifs[i] * ((mode&(IEEE_G|IEEE_N_24G)) ?9:20) + aSifsTime;
4394 u4bAcParam = ((((u32)(qos_parameters->tx_op_limit[i]))<< AC_PARAM_TXOP_LIMIT_OFFSET)|
4395 (((u32)(qos_parameters->cw_max[i]))<< AC_PARAM_ECW_MAX_OFFSET)|
4396 (((u32)(qos_parameters->cw_min[i]))<< AC_PARAM_ECW_MIN_OFFSET)|
4397 ((u32)u1bAIFS << AC_PARAM_AIFS_OFFSET));
4399 write_nic_dword(dev, WDCAPARA_ADD[i], u4bAcParam);
4400 //write_nic_dword(dev, WDCAPARA_ADD[i], 0x005e4322);
4403 success:
4404 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16))
4405 up(&priv->mutex);
4406 #else
4407 mutex_unlock(&priv->mutex);
4408 #endif
4411 static int rtl8192_qos_handle_probe_response(struct r8192_priv *priv,
4412 int active_network,
4413 struct ieee80211_network *network)
4415 int ret = 0;
4416 u32 size = sizeof(struct ieee80211_qos_parameters);
4418 if(priv->ieee80211->state !=IEEE80211_LINKED)
4419 return ret;
4421 if ((priv->ieee80211->iw_mode != IW_MODE_INFRA))
4422 return ret;
4424 if (network->flags & NETWORK_HAS_QOS_MASK) {
4425 if (active_network &&
4426 (network->flags & NETWORK_HAS_QOS_PARAMETERS))
4427 network->qos_data.active = network->qos_data.supported;
4429 if ((network->qos_data.active == 1) && (active_network == 1) &&
4430 (network->flags & NETWORK_HAS_QOS_PARAMETERS) &&
4431 (network->qos_data.old_param_count !=
4432 network->qos_data.param_count)) {
4433 network->qos_data.old_param_count =
4434 network->qos_data.param_count;
4435 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
4436 queue_work(priv->priv_wq, &priv->qos_activate);
4437 #else
4438 schedule_task(&priv->qos_activate);
4439 #endif
4440 RT_TRACE (COMP_QOS, "QoS parameters change call "
4441 "qos_activate\n");
4443 } else {
4444 memcpy(&priv->ieee80211->current_network.qos_data.parameters,\
4445 &def_qos_parameters, size);
4447 if ((network->qos_data.active == 1) && (active_network == 1)) {
4448 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
4449 queue_work(priv->priv_wq, &priv->qos_activate);
4450 #else
4451 schedule_task(&priv->qos_activate);
4452 #endif
4453 RT_TRACE(COMP_QOS, "QoS was disabled call qos_activate \n");
4455 network->qos_data.active = 0;
4456 network->qos_data.supported = 0;
4459 return 0;
4462 /* handle manage frame frame beacon and probe response */
4463 static int rtl8192_handle_beacon(struct net_device * dev,
4464 struct ieee80211_beacon * beacon,
4465 struct ieee80211_network * network)
4467 struct r8192_priv *priv = ieee80211_priv(dev);
4469 rtl8192_qos_handle_probe_response(priv,1,network);
4470 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
4471 queue_delayed_work(priv->priv_wq, &priv->update_beacon_wq, 0);
4472 #else
4473 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
4474 schedule_task(&priv->update_beacon_wq);
4475 #else
4476 queue_work(priv->priv_wq, &priv->update_beacon_wq);
4477 #endif
4479 #endif
4480 return 0;
4485 * handling the beaconing responses. if we get different QoS setting
4486 * off the network from the associated setting, adjust the QoS
4487 * setting
4489 static int rtl8192_qos_association_resp(struct r8192_priv *priv,
4490 struct ieee80211_network *network)
4492 int ret = 0;
4493 unsigned long flags;
4494 u32 size = sizeof(struct ieee80211_qos_parameters);
4495 int set_qos_param = 0;
4497 if ((priv == NULL) || (network == NULL))
4498 return ret;
4500 if(priv->ieee80211->state !=IEEE80211_LINKED)
4501 return ret;
4503 if ((priv->ieee80211->iw_mode != IW_MODE_INFRA))
4504 return ret;
4506 spin_lock_irqsave(&priv->ieee80211->lock, flags);
4507 if(network->flags & NETWORK_HAS_QOS_PARAMETERS) {
4508 memcpy(&priv->ieee80211->current_network.qos_data.parameters,\
4509 &network->qos_data.parameters,\
4510 sizeof(struct ieee80211_qos_parameters));
4511 priv->ieee80211->current_network.qos_data.active = 1;
4512 #if 0
4513 if((priv->ieee80211->current_network.qos_data.param_count != \
4514 network->qos_data.param_count))
4515 #endif
4517 set_qos_param = 1;
4518 /* update qos parameter for current network */
4519 priv->ieee80211->current_network.qos_data.old_param_count = \
4520 priv->ieee80211->current_network.qos_data.param_count;
4521 priv->ieee80211->current_network.qos_data.param_count = \
4522 network->qos_data.param_count;
4524 } else {
4525 memcpy(&priv->ieee80211->current_network.qos_data.parameters,\
4526 &def_qos_parameters, size);
4527 priv->ieee80211->current_network.qos_data.active = 0;
4528 priv->ieee80211->current_network.qos_data.supported = 0;
4529 set_qos_param = 1;
4532 spin_unlock_irqrestore(&priv->ieee80211->lock, flags);
4534 RT_TRACE(COMP_QOS, "%s: network->flags = %d,%d\n",__FUNCTION__,network->flags ,priv->ieee80211->current_network.qos_data.active);
4535 if (set_qos_param == 1)
4536 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
4537 queue_work(priv->priv_wq, &priv->qos_activate);
4538 #else
4539 schedule_task(&priv->qos_activate);
4540 #endif
4543 return ret;
4547 static int rtl8192_handle_assoc_response(struct net_device *dev,
4548 struct ieee80211_assoc_response_frame *resp,
4549 struct ieee80211_network *network)
4551 struct r8192_priv *priv = ieee80211_priv(dev);
4552 rtl8192_qos_association_resp(priv, network);
4553 return 0;
4557 void rtl8192_update_ratr_table(struct net_device* dev)
4558 // POCTET_STRING posLegacyRate,
4559 // u8* pMcsRate)
4560 // PRT_WLAN_STA pEntry)
4562 struct r8192_priv* priv = ieee80211_priv(dev);
4563 struct ieee80211_device* ieee = priv->ieee80211;
4564 u8* pMcsRate = ieee->dot11HTOperationalRateSet;
4565 //struct ieee80211_network *net = &ieee->current_network;
4566 u32 ratr_value = 0;
4567 u8 rate_index = 0;
4568 rtl8192_config_rate(dev, (u16*)(&ratr_value));
4569 ratr_value |= (*(u16*)(pMcsRate)) << 12;
4570 // switch (net->mode)
4571 switch (ieee->mode)
4573 case IEEE_A:
4574 ratr_value &= 0x00000FF0;
4575 break;
4576 case IEEE_B:
4577 ratr_value &= 0x0000000F;
4578 break;
4579 case IEEE_G:
4580 ratr_value &= 0x00000FF7;
4581 break;
4582 case IEEE_N_24G:
4583 case IEEE_N_5G:
4584 if (ieee->pHTInfo->PeerMimoPs == 0) //MIMO_PS_STATIC
4585 ratr_value &= 0x0007F007;
4586 else{
4587 if (priv->rf_type == RF_1T2R)
4588 ratr_value &= 0x000FF007;
4589 else
4590 ratr_value &= 0x0F81F007;
4592 break;
4593 default:
4594 break;
4596 ratr_value &= 0x0FFFFFFF;
4597 if(ieee->pHTInfo->bCurTxBW40MHz && ieee->pHTInfo->bCurShortGI40MHz){
4598 ratr_value |= 0x80000000;
4599 }else if(!ieee->pHTInfo->bCurTxBW40MHz && ieee->pHTInfo->bCurShortGI20MHz){
4600 ratr_value |= 0x80000000;
4602 write_nic_dword(dev, RATR0+rate_index*4, ratr_value);
4603 write_nic_byte(dev, UFWP, 1);
4606 static u8 ccmp_ie[4] = {0x00,0x50,0xf2,0x04};
4607 static u8 ccmp_rsn_ie[4] = {0x00, 0x0f, 0xac, 0x04};
4608 bool GetNmodeSupportBySecCfg8192(struct net_device*dev)
4610 #if 1
4611 struct r8192_priv* priv = ieee80211_priv(dev);
4612 struct ieee80211_device* ieee = priv->ieee80211;
4613 struct ieee80211_network * network = &ieee->current_network;
4614 int wpa_ie_len= ieee->wpa_ie_len;
4615 struct ieee80211_crypt_data* crypt;
4616 int encrypt;
4617 #if (defined (RTL8192SU_FPGA_2MAC_VERIFICATION)||defined (RTL8192SU_ASIC_VERIFICATION))
4618 return TRUE;
4619 #endif
4621 crypt = ieee->crypt[ieee->tx_keyidx];
4622 //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
4623 encrypt = (network->capability & WLAN_CAPABILITY_PRIVACY) || (ieee->host_encrypt && crypt && crypt->ops && (0 == strcmp(crypt->ops->name,"WEP")));
4625 /* simply judge */
4626 if(encrypt && (wpa_ie_len == 0)) {
4627 /* wep encryption, no N mode setting */
4628 return false;
4629 // } else if((wpa_ie_len != 0)&&(memcmp(&(ieee->wpa_ie[14]),ccmp_ie,4))) {
4630 } else if((wpa_ie_len != 0)) {
4631 /* parse pairwise key type */
4632 //if((pairwisekey = WEP40)||(pairwisekey = WEP104)||(pairwisekey = TKIP))
4633 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))))
4634 return true;
4635 else
4636 return false;
4637 } else {
4638 return true;
4641 #if 0
4642 //In here we discuss with SD4 David. He think we still can send TKIP in broadcast group key in MCS rate.
4643 //We can't force in G mode if Pairwie key is AES and group key is TKIP
4644 if((pSecInfo->GroupEncAlgorithm == WEP104_Encryption) || (pSecInfo->GroupEncAlgorithm == WEP40_Encryption) ||
4645 (pSecInfo->PairwiseEncAlgorithm == WEP104_Encryption) ||
4646 (pSecInfo->PairwiseEncAlgorithm == WEP40_Encryption) || (pSecInfo->PairwiseEncAlgorithm == TKIP_Encryption))
4648 return false;
4650 else
4651 return true;
4652 #endif
4653 return true;
4654 #endif
4657 bool GetHalfNmodeSupportByAPs819xUsb(struct net_device* dev)
4659 bool Reval;
4660 struct r8192_priv* priv = ieee80211_priv(dev);
4661 struct ieee80211_device* ieee = priv->ieee80211;
4663 // Added by Roger, 2008.08.29.
4664 #ifdef RTL8192SU
4665 return false;
4666 #endif
4668 if(ieee->bHalfWirelessN24GMode == true)
4669 Reval = true;
4670 else
4671 Reval = false;
4673 return Reval;
4676 void rtl8192_refresh_supportrate(struct r8192_priv* priv)
4678 struct ieee80211_device* ieee = priv->ieee80211;
4679 //we donot consider set support rate for ABG mode, only HT MCS rate is set here.
4680 if (ieee->mode == WIRELESS_MODE_N_24G || ieee->mode == WIRELESS_MODE_N_5G)
4682 memcpy(ieee->Regdot11HTOperationalRateSet, ieee->RegHTSuppRateSet, 16);
4683 //RT_DEBUG_DATA(COMP_INIT, ieee->RegHTSuppRateSet, 16);
4684 //RT_DEBUG_DATA(COMP_INIT, ieee->Regdot11HTOperationalRateSet, 16);
4686 else
4687 memset(ieee->Regdot11HTOperationalRateSet, 0, 16);
4688 return;
4691 u8 rtl8192_getSupportedWireleeMode(struct net_device*dev)
4693 struct r8192_priv *priv = ieee80211_priv(dev);
4694 u8 ret = 0;
4695 switch(priv->rf_chip)
4697 case RF_8225:
4698 case RF_8256:
4699 case RF_PSEUDO_11N:
4700 case RF_6052:
4701 ret = (WIRELESS_MODE_N_24G|WIRELESS_MODE_G|WIRELESS_MODE_B);
4702 break;
4703 case RF_8258:
4704 ret = (WIRELESS_MODE_A|WIRELESS_MODE_N_5G);
4705 break;
4706 default:
4707 ret = WIRELESS_MODE_B;
4708 break;
4710 return ret;
4712 void rtl8192_SetWirelessMode(struct net_device* dev, u8 wireless_mode)
4714 struct r8192_priv *priv = ieee80211_priv(dev);
4715 u8 bSupportMode = rtl8192_getSupportedWireleeMode(dev);
4717 #if 1
4718 if ((wireless_mode == WIRELESS_MODE_AUTO) || ((wireless_mode&bSupportMode)==0))
4720 if(bSupportMode & WIRELESS_MODE_N_24G)
4722 wireless_mode = WIRELESS_MODE_N_24G;
4724 else if(bSupportMode & WIRELESS_MODE_N_5G)
4726 wireless_mode = WIRELESS_MODE_N_5G;
4728 else if((bSupportMode & WIRELESS_MODE_A))
4730 wireless_mode = WIRELESS_MODE_A;
4732 else if((bSupportMode & WIRELESS_MODE_G))
4734 wireless_mode = WIRELESS_MODE_G;
4736 else if((bSupportMode & WIRELESS_MODE_B))
4738 wireless_mode = WIRELESS_MODE_B;
4740 else{
4741 RT_TRACE(COMP_ERR, "%s(), No valid wireless mode supported, SupportedWirelessMode(%x)!!!\n", __FUNCTION__,bSupportMode);
4742 wireless_mode = WIRELESS_MODE_B;
4745 #ifdef TO_DO_LIST //// TODO: this function doesn't work well at this time, we shoud wait for FPGA
4746 ActUpdateChannelAccessSetting( pAdapter, pHalData->CurrentWirelessMode, &pAdapter->MgntInfo.Info8185.ChannelAccessSetting );
4747 #endif
4748 #ifdef RTL8192SU
4749 //LZM 090306 usb crash here, mark it temp
4750 //write_nic_word(dev, SIFS_OFDM, 0x0e0e);
4751 #endif
4752 priv->ieee80211->mode = wireless_mode;
4754 if ((wireless_mode == WIRELESS_MODE_N_24G) || (wireless_mode == WIRELESS_MODE_N_5G))
4755 priv->ieee80211->pHTInfo->bEnableHT = 1;
4756 else
4757 priv->ieee80211->pHTInfo->bEnableHT = 0;
4758 RT_TRACE(COMP_INIT, "Current Wireless Mode is %x\n", wireless_mode);
4759 rtl8192_refresh_supportrate(priv);
4760 #endif
4765 short rtl8192_is_tx_queue_empty(struct net_device *dev)
4767 int i=0;
4768 struct r8192_priv *priv = ieee80211_priv(dev);
4769 //struct ieee80211_device* ieee = priv->ieee80211;
4770 for (i=0; i<=MGNT_QUEUE; i++)
4772 if ((i== TXCMD_QUEUE) || (i == HCCA_QUEUE) )
4773 continue;
4774 if (atomic_read(&priv->tx_pending[i]))
4776 printk("===>tx queue is not empty:%d, %d\n", i, atomic_read(&priv->tx_pending[i]));
4777 return 0;
4780 return 1;
4782 #if 0
4783 void rtl8192_rq_tx_ack(struct net_device *dev)
4785 struct r8192_priv *priv = ieee80211_priv(dev);
4786 priv->ieee80211->ack_tx_to_ieee = 1;
4788 #endif
4789 void rtl8192_hw_sleep_down(struct net_device *dev)
4791 RT_TRACE(COMP_POWER, "%s()============>come to sleep down\n", __FUNCTION__);
4792 #ifdef TODO
4793 // MgntActSet_RF_State(dev, eRfSleep, RF_CHANGE_BY_PS);
4794 #endif
4796 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
4797 void rtl8192_hw_sleep_wq (struct work_struct *work)
4799 // struct r8180_priv *priv = container_of(work, struct r8180_priv, watch_dog_wq);
4800 // struct ieee80211_device * ieee = (struct ieee80211_device*)
4801 // container_of(work, struct ieee80211_device, watch_dog_wq);
4802 struct delayed_work *dwork = container_of(work,struct delayed_work,work);
4803 struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,hw_sleep_wq);
4804 struct net_device *dev = ieee->dev;
4805 #else
4806 void rtl8192_hw_sleep_wq(struct net_device* dev)
4808 #endif
4809 //printk("=========>%s()\n", __FUNCTION__);
4810 rtl8192_hw_sleep_down(dev);
4812 // printk("dev is %d\n",dev);
4813 // printk("&*&(^*(&(&=========>%s()\n", __FUNCTION__);
4814 void rtl8192_hw_wakeup(struct net_device* dev)
4816 // u32 flags = 0;
4818 // spin_lock_irqsave(&priv->ps_lock,flags);
4819 RT_TRACE(COMP_POWER, "%s()============>come to wake up\n", __FUNCTION__);
4820 #ifdef TODO
4821 // MgntActSet_RF_State(dev, eRfSleep, RF_CHANGE_BY_PS);
4822 #endif
4823 //FIXME: will we send package stored while nic is sleep?
4824 // spin_unlock_irqrestore(&priv->ps_lock,flags);
4826 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
4827 void rtl8192_hw_wakeup_wq (struct work_struct *work)
4829 // struct r8180_priv *priv = container_of(work, struct r8180_priv, watch_dog_wq);
4830 // struct ieee80211_device * ieee = (struct ieee80211_device*)
4831 // container_of(work, struct ieee80211_device, watch_dog_wq);
4832 struct delayed_work *dwork = container_of(work,struct delayed_work,work);
4833 struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,hw_wakeup_wq);
4834 struct net_device *dev = ieee->dev;
4835 #else
4836 void rtl8192_hw_wakeup_wq(struct net_device* dev)
4838 #endif
4839 rtl8192_hw_wakeup(dev);
4843 #define MIN_SLEEP_TIME 50
4844 #define MAX_SLEEP_TIME 10000
4845 void rtl8192_hw_to_sleep(struct net_device *dev, u32 th, u32 tl)
4848 struct r8192_priv *priv = ieee80211_priv(dev);
4850 u32 rb = jiffies;
4851 unsigned long flags;
4853 spin_lock_irqsave(&priv->ps_lock,flags);
4855 /* Writing HW register with 0 equals to disable
4856 * the timer, that is not really what we want
4858 tl -= MSECS(4+16+7);
4860 //if(tl == 0) tl = 1;
4862 /* FIXME HACK FIXME HACK */
4863 // force_pci_posting(dev);
4864 //mdelay(1);
4866 // rb = read_nic_dword(dev, TSFTR);
4868 /* If the interval in witch we are requested to sleep is too
4869 * short then give up and remain awake
4871 if(((tl>=rb)&& (tl-rb) <= MSECS(MIN_SLEEP_TIME))
4872 ||((rb>tl)&& (rb-tl) < MSECS(MIN_SLEEP_TIME))) {
4873 spin_unlock_irqrestore(&priv->ps_lock,flags);
4874 printk("too short to sleep\n");
4875 return;
4878 // write_nic_dword(dev, TimerInt, tl);
4879 // rb = read_nic_dword(dev, TSFTR);
4881 u32 tmp = (tl>rb)?(tl-rb):(rb-tl);
4882 // if (tl<rb)
4884 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
4885 schedule_task(&priv->ieee80211->hw_wakeup_wq);
4886 #else
4887 queue_delayed_work(priv->ieee80211->wq, &priv->ieee80211->hw_wakeup_wq, tmp); //as tl may be less than rb
4888 #endif
4890 /* if we suspect the TimerInt is gone beyond tl
4891 * while setting it, then give up
4893 #if 1
4894 if(((tl > rb) && ((tl-rb) > MSECS(MAX_SLEEP_TIME)))||
4895 ((tl < rb) && ((rb-tl) > MSECS(MAX_SLEEP_TIME)))) {
4896 printk("========>too long to sleep:%x, %x, %lx\n", tl, rb, MSECS(MAX_SLEEP_TIME));
4897 spin_unlock_irqrestore(&priv->ps_lock,flags);
4898 return;
4900 #endif
4901 // if(priv->rf_sleep)
4902 // priv->rf_sleep(dev);
4904 //printk("<=========%s()\n", __FUNCTION__);
4905 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
4906 schedule_task(&priv->ieee80211->hw_sleep_wq);
4907 #else
4908 queue_delayed_work(priv->ieee80211->wq, (void *)&priv->ieee80211->hw_sleep_wq,0);
4909 #endif
4910 spin_unlock_irqrestore(&priv->ps_lock,flags);
4912 //init priv variables here. only non_zero value should be initialized here.
4913 static void rtl8192_init_priv_variable(struct net_device* dev)
4915 struct r8192_priv *priv = ieee80211_priv(dev);
4916 u8 i;
4917 priv->card_8192 = NIC_8192U;
4918 priv->chan = 1; //set to channel 1
4919 priv->ieee80211->mode = WIRELESS_MODE_AUTO; //SET AUTO
4920 priv->ieee80211->iw_mode = IW_MODE_INFRA;
4921 priv->ieee80211->ieee_up=0;
4922 priv->retry_rts = DEFAULT_RETRY_RTS;
4923 priv->retry_data = DEFAULT_RETRY_DATA;
4924 priv->ieee80211->rts = DEFAULT_RTS_THRESHOLD;
4925 priv->ieee80211->rate = 110; //11 mbps
4926 priv->ieee80211->short_slot = 1;
4927 priv->promisc = (dev->flags & IFF_PROMISC) ? 1:0;
4928 priv->CckPwEnl = 6;
4929 //for silent reset
4930 priv->IrpPendingCount = 1;
4931 priv->ResetProgress = RESET_TYPE_NORESET;
4932 priv->bForcedSilentReset = 0;
4933 priv->bDisableNormalResetCheck = false;
4934 priv->force_reset = false;
4936 priv->ieee80211->FwRWRF = 0; //we don't use FW read/write RF until stable firmware is available.
4937 priv->ieee80211->current_network.beacon_interval = DEFAULT_BEACONINTERVAL;
4938 priv->ieee80211->iw_mode = IW_MODE_INFRA;
4939 priv->ieee80211->softmac_features = IEEE_SOFTMAC_SCAN |
4940 IEEE_SOFTMAC_ASSOCIATE | IEEE_SOFTMAC_PROBERQ |
4941 IEEE_SOFTMAC_PROBERS | IEEE_SOFTMAC_TX_QUEUE |
4942 IEEE_SOFTMAC_BEACONS;//added by amy 080604 //| //IEEE_SOFTMAC_SINGLE_QUEUE;
4944 priv->ieee80211->active_scan = 1;
4945 priv->ieee80211->modulation = IEEE80211_CCK_MODULATION | IEEE80211_OFDM_MODULATION;
4946 priv->ieee80211->host_encrypt = 1;
4947 priv->ieee80211->host_decrypt = 1;
4948 priv->ieee80211->start_send_beacons = NULL;//rtl819xusb_beacon_tx;//-by amy 080604
4949 priv->ieee80211->stop_send_beacons = NULL;//rtl8192_beacon_stop;//-by amy 080604
4950 priv->ieee80211->softmac_hard_start_xmit = rtl8192_hard_start_xmit;
4951 priv->ieee80211->set_chan = rtl8192_set_chan;
4952 priv->ieee80211->link_change = priv->ops->rtl819x_link_change;
4953 priv->ieee80211->softmac_data_hard_start_xmit = rtl8192_hard_data_xmit;
4954 priv->ieee80211->data_hard_stop = rtl8192_data_hard_stop;
4955 priv->ieee80211->data_hard_resume = rtl8192_data_hard_resume;
4956 priv->ieee80211->init_wmmparam_flag = 0;
4957 priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD;
4958 priv->ieee80211->check_nic_enough_desc = check_nic_enough_desc;
4959 priv->ieee80211->tx_headroom = TX_PACKET_SHIFT_BYTES;
4960 priv->ieee80211->qos_support = 1;
4962 //added by WB
4963 // priv->ieee80211->SwChnlByTimerHandler = rtl8192_phy_SwChnl;
4964 priv->ieee80211->SetBWModeHandler = rtl8192_SetBWMode;
4965 priv->ieee80211->handle_assoc_response = rtl8192_handle_assoc_response;
4966 priv->ieee80211->handle_beacon = rtl8192_handle_beacon;
4967 //for LPS
4968 priv->ieee80211->sta_wake_up = rtl8192_hw_wakeup;
4969 // priv->ieee80211->ps_request_tx_ack = rtl8192_rq_tx_ack;
4970 priv->ieee80211->enter_sleep_state = rtl8192_hw_to_sleep;
4971 priv->ieee80211->ps_is_queue_empty = rtl8192_is_tx_queue_empty;
4972 //added by david
4973 priv->ieee80211->GetNmodeSupportBySecCfg = GetNmodeSupportBySecCfg8192;
4974 priv->ieee80211->GetHalfNmodeSupportByAPsHandler = GetHalfNmodeSupportByAPs819xUsb;
4975 priv->ieee80211->SetWirelessMode = rtl8192_SetWirelessMode;
4976 //added by amy
4977 priv->ieee80211->InitialGainHandler = priv->ops->rtl819x_initial_gain;
4978 priv->card_type = USB;
4980 #ifdef RTL8192SU
4981 //1 RTL8192SU/
4982 priv->ieee80211->current_network.beacon_interval = DEFAULT_BEACONINTERVAL;
4983 priv->ieee80211->SetFwCmdHandler = HalSetFwCmd8192S;
4984 priv->bRFSiOrPi = 0;//o=si,1=pi;
4985 //lzm add
4986 priv->bInHctTest = false;
4988 priv->MidHighPwrTHR_L1 = 0x3B;
4989 priv->MidHighPwrTHR_L2 = 0x40;
4991 if(priv->bInHctTest)
4993 priv->ShortRetryLimit = HAL_RETRY_LIMIT_AP_ADHOC;
4994 priv->LongRetryLimit = HAL_RETRY_LIMIT_AP_ADHOC;
4996 else
4998 priv->ShortRetryLimit = HAL_RETRY_LIMIT_INFRA;
4999 priv->LongRetryLimit = HAL_RETRY_LIMIT_INFRA;
5002 priv->SetFwCmdInProgress = false; //is set FW CMD in Progress? 92S only
5003 priv->CurrentFwCmdIO = 0;
5005 priv->MinSpaceCfg = 0;
5007 priv->EarlyRxThreshold = 7;
5008 priv->enable_gpio0 = 0;
5009 priv->TransmitConfig =
5010 ((u32)TCR_MXDMA_2048<<TCR_MXDMA_OFFSET) | // Max DMA Burst Size per Tx DMA Burst, 7: reservied.
5011 (priv->ShortRetryLimit<<TCR_SRL_OFFSET) | // Short retry limit
5012 (priv->LongRetryLimit<<TCR_LRL_OFFSET) | // Long retry limit
5013 (false ? TCR_SAT : 0); // FALSE: HW provies PLCP length and LENGEXT, TURE: SW proiveds them
5014 if(priv->bInHctTest)
5015 priv->ReceiveConfig = //priv->CSMethod |
5016 RCR_AMF | RCR_ADF | //RCR_AAP | //accept management/data
5017 RCR_ACF |RCR_APPFCS| //accept control frame for SW AP needs PS-poll, 2005.07.07, by rcnjko.
5018 RCR_AB | RCR_AM | RCR_APM | //accept BC/MC/UC
5019 RCR_AICV | RCR_ACRC32 | //accept ICV/CRC error packet
5020 RCR_APP_PHYST_STAFF | RCR_APP_PHYST_RXFF | // Accept PHY status
5021 ((u32)7<<RCR_MXDMA_OFFSET) | // Max DMA Burst Size per Rx DMA Burst, 7: unlimited.
5022 (priv->EarlyRxThreshold<<RCR_FIFO_OFFSET) | // Rx FIFO Threshold, 7: No Rx threshold.
5023 (priv->EarlyRxThreshold == 7 ? RCR_OnlyErlPkt:0);
5024 else
5025 priv->ReceiveConfig = //priv->CSMethod |
5026 RCR_AMF | RCR_ADF | RCR_AB |
5027 RCR_AM | RCR_APM |RCR_AAP |RCR_ADD3|RCR_APP_ICV|
5028 RCR_APP_PHYST_STAFF | RCR_APP_PHYST_RXFF | // Accept PHY status
5029 RCR_APP_MIC | RCR_APPFCS;
5031 // <Roger_EXP> 2008.06.16.
5032 priv->IntrMask = (u16)(IMR_ROK | IMR_VODOK | IMR_VIDOK | IMR_BEDOK | IMR_BKDOK | \
5033 IMR_HCCADOK | IMR_MGNTDOK | IMR_COMDOK | IMR_HIGHDOK | \
5034 IMR_BDOK | IMR_RXCMDOK | /*IMR_TIMEOUT0 |*/ IMR_RDU | IMR_RXFOVW | \
5035 IMR_TXFOVW | IMR_BcnInt | IMR_TBDOK | IMR_TBDER);
5037 //1 End
5039 #else
5041 #ifdef TO_DO_LIST
5042 if(Adapter->bInHctTest)
5044 pHalData->ShortRetryLimit = 7;
5045 pHalData->LongRetryLimit = 7;
5047 #endif
5049 priv->ShortRetryLimit = 0x30;
5050 priv->LongRetryLimit = 0x30;
5052 priv->EarlyRxThreshold = 7;
5053 priv->enable_gpio0 = 0;
5054 priv->TransmitConfig =
5055 // TCR_DurProcMode | //for RTL8185B, duration setting by HW
5056 //? TCR_DISReqQsize |
5057 (TCR_MXDMA_2048<<TCR_MXDMA_OFFSET)| // Max DMA Burst Size per Tx DMA Burst, 7: reservied.
5058 (priv->ShortRetryLimit<<TCR_SRL_OFFSET)| // Short retry limit
5059 (priv->LongRetryLimit<<TCR_LRL_OFFSET) | // Long retry limit
5060 (false ? TCR_SAT: 0); // FALSE: HW provies PLCP length and LENGEXT, TURE: SW proiveds them
5061 #ifdef TO_DO_LIST
5062 if(Adapter->bInHctTest)
5063 pHalData->ReceiveConfig = pHalData->CSMethod |
5064 RCR_AMF | RCR_ADF | //RCR_AAP | //accept management/data
5065 //guangan200710
5066 RCR_ACF | //accept control frame for SW AP needs PS-poll, 2005.07.07, by rcnjko.
5067 RCR_AB | RCR_AM | RCR_APM | //accept BC/MC/UC
5068 RCR_AICV | RCR_ACRC32 | //accept ICV/CRC error packet
5069 ((u32)7<<RCR_MXDMA_OFFSET) | // Max DMA Burst Size per Rx DMA Burst, 7: unlimited.
5070 (pHalData->EarlyRxThreshold<<RCR_FIFO_OFFSET) | // Rx FIFO Threshold, 7: No Rx threshold.
5071 (pHalData->EarlyRxThreshold == 7 ? RCR_OnlyErlPkt:0);
5072 else
5074 #endif
5075 priv->ReceiveConfig =
5076 RCR_AMF | RCR_ADF | //accept management/data
5077 RCR_ACF | //accept control frame for SW AP needs PS-poll, 2005.07.07, by rcnjko.
5078 RCR_AB | RCR_AM | RCR_APM | //accept BC/MC/UC
5079 //RCR_AICV | RCR_ACRC32 | //accept ICV/CRC error packet
5080 ((u32)7<<RCR_MXDMA_OFFSET)| // Max DMA Burst Size per Rx DMA Burst, 7: unlimited.
5081 (priv->EarlyRxThreshold<<RX_FIFO_THRESHOLD_SHIFT) | // Rx FIFO Threshold, 7: No Rx threshold.
5082 (priv->EarlyRxThreshold == 7 ? RCR_ONLYERLPKT:0);
5083 #endif
5085 priv->AcmControl = 0;
5086 priv->pFirmware = (rt_firmware*)vmalloc(sizeof(rt_firmware));
5087 if (priv->pFirmware)
5088 memset(priv->pFirmware, 0, sizeof(rt_firmware));
5090 /* rx related queue */
5091 skb_queue_head_init(&priv->rx_queue);
5092 skb_queue_head_init(&priv->skb_queue);
5094 /* Tx related queue */
5095 for(i = 0; i < MAX_QUEUE_SIZE; i++) {
5096 skb_queue_head_init(&priv->ieee80211->skb_waitQ [i]);
5098 for(i = 0; i < MAX_QUEUE_SIZE; i++) {
5099 skb_queue_head_init(&priv->ieee80211->skb_aggQ [i]);
5101 for(i = 0; i < MAX_QUEUE_SIZE; i++) {
5102 skb_queue_head_init(&priv->ieee80211->skb_drv_aggQ [i]);
5104 priv->rf_set_chan = rtl8192_phy_SwChnl;
5107 //init lock here
5108 static void rtl8192_init_priv_lock(struct r8192_priv* priv)
5110 spin_lock_init(&priv->tx_lock);
5111 spin_lock_init(&priv->irq_lock);//added by thomas
5112 //spin_lock_init(&priv->rf_lock);//use rf_sem, or will crash in some OS.
5113 sema_init(&priv->wx_sem,1);
5114 sema_init(&priv->rf_sem,1);
5115 spin_lock_init(&priv->ps_lock);
5116 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16))
5117 sema_init(&priv->mutex, 1);
5118 #else
5119 mutex_init(&priv->mutex);
5120 #endif
5123 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
5124 extern void rtl819x_watchdog_wqcallback(struct work_struct *work);
5125 #else
5126 extern void rtl819x_watchdog_wqcallback(struct net_device *dev);
5127 #endif
5129 void rtl8192_irq_rx_tasklet(struct r8192_priv *priv);
5130 //init tasklet and wait_queue here. only 2.6 above kernel is considered
5131 #define DRV_NAME "wlan0"
5132 static void rtl8192_init_priv_task(struct net_device* dev)
5134 struct r8192_priv *priv = ieee80211_priv(dev);
5136 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
5137 #ifdef PF_SYNCTHREAD
5138 priv->priv_wq = create_workqueue(DRV_NAME,0);
5139 #else
5140 priv->priv_wq = create_workqueue(DRV_NAME);
5141 #endif
5142 #endif
5144 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
5145 INIT_WORK(&priv->reset_wq, rtl8192_restart);
5147 //INIT_DELAYED_WORK(&priv->watch_dog_wq, hal_dm_watchdog);
5148 INIT_DELAYED_WORK(&priv->watch_dog_wq, rtl819x_watchdog_wqcallback);
5149 INIT_DELAYED_WORK(&priv->txpower_tracking_wq, dm_txpower_trackingcallback);
5150 // INIT_DELAYED_WORK(&priv->gpio_change_rf_wq, dm_gpio_change_rf_callback);
5151 INIT_DELAYED_WORK(&priv->rfpath_check_wq, dm_rf_pathcheck_workitemcallback);
5152 INIT_DELAYED_WORK(&priv->update_beacon_wq, rtl8192_update_beacon);
5153 INIT_DELAYED_WORK(&priv->initialgain_operate_wq, InitialGainOperateWorkItemCallBack);
5154 //INIT_WORK(&priv->SwChnlWorkItem, rtl8192_SwChnl_WorkItem);
5155 //INIT_WORK(&priv->SetBWModeWorkItem, rtl8192_SetBWModeWorkItem);
5156 INIT_WORK(&priv->qos_activate, rtl8192_qos_activate);
5157 INIT_DELAYED_WORK(&priv->ieee80211->hw_wakeup_wq,(void*) rtl8192_hw_wakeup_wq);
5158 INIT_DELAYED_WORK(&priv->ieee80211->hw_sleep_wq,(void*) rtl8192_hw_sleep_wq);
5160 #else
5161 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
5162 tq_init(&priv->reset_wq, (void*)rtl8192_restart, dev);
5163 tq_init(&priv->watch_dog_wq, (void*)rtl819x_watchdog_wqcallback, dev);
5164 tq_init(&priv->txpower_tracking_wq, (void*)dm_txpower_trackingcallback, dev);
5165 tq_init(&priv->rfpath_check_wq, (void*)dm_rf_pathcheck_workitemcallback, dev);
5166 tq_init(&priv->update_beacon_wq, (void*)rtl8192_update_beacon, dev);
5167 //tq_init(&priv->SwChnlWorkItem, (void*) rtl8192_SwChnl_WorkItem, dev);
5168 //tq_init(&priv->SetBWModeWorkItem, (void*)rtl8192_SetBWModeWorkItem, dev);
5169 tq_init(&priv->qos_activate, (void *)rtl8192_qos_activate, dev);
5170 tq_init(&priv->ieee80211->hw_wakeup_wq,(void*) rtl8192_hw_wakeup_wq, dev);
5171 tq_init(&priv->ieee80211->hw_sleep_wq,(void*) rtl8192_hw_sleep_wq, dev);
5173 #else
5174 INIT_WORK(&priv->reset_wq,(void(*)(void*)) rtl8192_restart,dev);
5175 //INIT_WORK(&priv->watch_dog_wq, (void(*)(void*)) hal_dm_watchdog,dev);
5176 INIT_WORK(&priv->watch_dog_wq, (void(*)(void*)) rtl819x_watchdog_wqcallback,dev);
5177 INIT_WORK(&priv->txpower_tracking_wq, (void(*)(void*)) dm_txpower_trackingcallback,dev);
5178 // INIT_WORK(&priv->gpio_change_rf_wq, (void(*)(void*)) dm_gpio_change_rf_callback,dev);
5179 INIT_WORK(&priv->rfpath_check_wq, (void(*)(void*)) dm_rf_pathcheck_workitemcallback,dev);
5180 INIT_WORK(&priv->update_beacon_wq, (void(*)(void*))rtl8192_update_beacon,dev);
5181 INIT_WORK(&priv->initialgain_operate_wq, (void(*)(void*))InitialGainOperateWorkItemCallBack,dev);
5182 //INIT_WORK(&priv->SwChnlWorkItem, (void(*)(void*)) rtl8192_SwChnl_WorkItem, dev);
5183 //INIT_WORK(&priv->SetBWModeWorkItem, (void(*)(void*)) rtl8192_SetBWModeWorkItem, dev);
5184 INIT_WORK(&priv->qos_activate, (void(*)(void *))rtl8192_qos_activate, dev);
5185 INIT_WORK(&priv->ieee80211->hw_wakeup_wq,(void*) rtl8192_hw_wakeup_wq, dev);
5186 INIT_WORK(&priv->ieee80211->hw_sleep_wq,(void*) rtl8192_hw_sleep_wq, dev);
5187 #endif
5188 #endif
5190 tasklet_init(&priv->irq_rx_tasklet,
5191 (void(*)(unsigned long))rtl8192_irq_rx_tasklet,
5192 (unsigned long)priv);
5195 static void rtl8192_get_eeprom_size(struct net_device* dev)
5197 u16 curCR = 0;
5198 struct r8192_priv *priv = ieee80211_priv(dev);
5199 RT_TRACE(COMP_EPROM, "===========>%s()\n", __FUNCTION__);
5200 curCR = read_nic_word_E(dev,EPROM_CMD);
5201 RT_TRACE(COMP_EPROM, "read from Reg EPROM_CMD(%x):%x\n", EPROM_CMD, curCR);
5202 //whether need I consider BIT5?
5203 priv->epromtype = (curCR & Cmd9346CR_9356SEL) ? EPROM_93c56 : EPROM_93c46;
5204 RT_TRACE(COMP_EPROM, "<===========%s(), epromtype:%d\n", __FUNCTION__, priv->epromtype);
5207 //used to swap endian. as ntohl & htonl are not neccessary to swap endian, so use this instead.
5208 static inline u16 endian_swap(u16* data)
5210 u16 tmp = *data;
5211 *data = (tmp >> 8) | (tmp << 8);
5212 return *data;
5215 #ifdef RTL8192SU
5216 u8 rtl8192SU_UsbOptionToEndPointNumber(u8 UsbOption)
5218 u8 nEndPoint = 0;
5219 switch(UsbOption)
5221 case 0:
5222 nEndPoint = 6;
5223 break;
5224 case 1:
5225 nEndPoint = 11;
5226 break;
5227 case 2:
5228 nEndPoint = 4;
5229 break;
5230 default:
5231 RT_TRACE(COMP_INIT, "UsbOptionToEndPointNumber(): Invalid UsbOption(%#x)\n", UsbOption);
5232 break;
5234 return nEndPoint;
5237 u8 rtl8192SU_BoardTypeToRFtype(struct net_device* dev, u8 Boardtype)
5239 u8 RFtype = RF_1T2R;
5241 switch(Boardtype)
5243 case 0:
5244 RFtype = RF_1T1R;
5245 break;
5246 case 1:
5247 RFtype = RF_1T2R;
5248 break;
5249 case 2:
5250 RFtype = RF_2T2R;
5251 break;
5252 case 3:
5253 RFtype = RF_2T2R_GREEN;
5254 break;
5255 default:
5256 break;
5259 return RFtype;
5263 // Description:
5264 // Config HW adapter information into initial value.
5266 // Assumption:
5267 // 1. After Auto load fail(i.e, check CR9346 fail)
5269 // Created by Roger, 2008.10.21.
5271 void
5272 rtl8192SU_ConfigAdapterInfo8192SForAutoLoadFail(struct net_device* dev)
5274 struct r8192_priv *priv = ieee80211_priv(dev);
5275 //u16 i,usValue;
5276 //u8 sMacAddr[6] = {0x00, 0xE0, 0x4C, 0x81, 0x92, 0x00};
5277 u8 rf_path, index; // For EEPROM/EFUSE After V0.6_1117
5278 int i;
5280 RT_TRACE(COMP_INIT, "====> ConfigAdapterInfo8192SForAutoLoadFail\n");
5282 write_nic_byte(dev, SYS_ISO_CTRL+1, 0xE8); // Isolation signals from Loader
5283 //PlatformStallExecution(10000);
5284 mdelay(10);
5285 write_nic_byte(dev, PMC_FSM, 0x02); // Enable Loader Data Keep
5287 //RT_ASSERT(priv->AutoloadFailFlag==TRUE, ("ReadAdapterInfo8192SEEPROM(): AutoloadFailFlag !=TRUE\n"));
5289 // Initialize IC Version && Channel Plan
5290 priv->eeprom_vid = 0;
5291 priv->eeprom_pid = 0;
5292 priv->card_8192_version = 0;
5293 priv->eeprom_ChannelPlan = 0;
5294 priv->eeprom_CustomerID = 0;
5295 priv->eeprom_SubCustomerID = 0;
5296 priv->bIgnoreDiffRateTxPowerOffset = false;
5298 RT_TRACE(COMP_INIT, "EEPROM VID = 0x%4x\n", priv->eeprom_vid);
5299 RT_TRACE(COMP_INIT, "EEPROM PID = 0x%4x\n", priv->eeprom_pid);
5300 RT_TRACE(COMP_INIT, "EEPROM Customer ID: 0x%2x\n", priv->eeprom_CustomerID);
5301 RT_TRACE(COMP_INIT, "EEPROM SubCustomer ID: 0x%2x\n", priv->eeprom_SubCustomerID);
5302 RT_TRACE(COMP_INIT, "EEPROM ChannelPlan = 0x%4x\n", priv->eeprom_ChannelPlan);
5303 RT_TRACE(COMP_INIT, "IgnoreDiffRateTxPowerOffset = %d\n", priv->bIgnoreDiffRateTxPowerOffset);
5307 priv->EEPROMUsbOption = EEPROM_USB_Default_OPTIONAL_FUNC;
5308 RT_TRACE(COMP_INIT, "USB Option = %#x\n", priv->EEPROMUsbOption);
5310 for(i=0; i<5; i++)
5311 priv->EEPROMUsbPhyParam[i] = EEPROM_USB_Default_PHY_PARAM;
5313 //RT_PRINT_DATA(COMP_INIT|COMP_EFUSE, DBG_LOUD, ("EFUSE USB PHY Param: \n"), priv->EEPROMUsbPhyParam, 5);
5316 //<Roger_Notes> In this case, we random assigh MAC address here. 2008.10.15.
5317 static u8 sMacAddr[6] = {0x00, 0xE0, 0x4C, 0x81, 0x92, 0x00};
5318 u8 i;
5320 //sMacAddr[5] = (u8)GetRandomNumber(1, 254);
5322 for(i = 0; i < 6; i++)
5323 dev->dev_addr[i] = sMacAddr[i];
5325 //NicIFSetMacAddress(Adapter, Adapter->PermanentAddress);
5326 write_nic_dword(dev, IDR0, ((u32*)dev->dev_addr)[0]);
5327 write_nic_word(dev, IDR4, ((u16*)(dev->dev_addr + 4))[0]);
5329 RT_TRACE(COMP_INIT, "ReadAdapterInfo8192SEFuse(), Permanent Address = %02x-%02x-%02x-%02x-%02x-%02x\n",
5330 dev->dev_addr[0], dev->dev_addr[1],
5331 dev->dev_addr[2], dev->dev_addr[3],
5332 dev->dev_addr[4], dev->dev_addr[5]);
5334 priv->EEPROMBoardType = EEPROM_Default_BoardType;
5335 priv->rf_type = RF_1T2R; //RF_2T2R
5336 priv->EEPROMTxPowerDiff = EEPROM_Default_PwDiff;
5337 priv->EEPROMThermalMeter = EEPROM_Default_ThermalMeter;
5338 priv->EEPROMCrystalCap = EEPROM_Default_CrystalCap;
5339 priv->EEPROMTxPwrBase = EEPROM_Default_TxPowerBase;
5340 priv->EEPROMTSSI_A = EEPROM_Default_TSSI;
5341 priv->EEPROMTSSI_B = EEPROM_Default_TSSI;
5342 priv->EEPROMTxPwrTkMode = EEPROM_Default_TxPwrTkMode;
5345 #ifdef EEPROM_OLD_FORMAT_SUPPORT
5346 for(i=0; i<6; i++)
5348 priv->EEPROMHT2T_TxPwr[i] = EEPROM_Default_HT2T_TxPwr;
5351 for(i=0; i<14; i++)
5353 priv->EEPROMTxPowerLevelCCK24G[i] = (u8)(EEPROM_Default_TxPower & 0xff);
5354 priv->EEPROMTxPowerLevelOFDM24G[i] = (u8)(EEPROM_Default_TxPower & 0xff);
5358 // Update HAL variables.
5360 memcpy( priv->TxPowerLevelOFDM24G, priv->EEPROMTxPowerLevelOFDM24G, 14);
5361 memcpy( priv->TxPowerLevelCCK, priv->EEPROMTxPowerLevelCCK24G, 14);
5362 //RT_PRINT_DATA(COMP_INIT|COMP_EFUSE, DBG_LOUD, ("HAL CCK 2.4G TxPwr: \n"), priv->TxPowerLevelCCK, 14);
5363 //RT_PRINT_DATA(COMP_INIT|COMP_EFUSE, DBG_LOUD, ("HAL OFDM 2.4G TxPwr: \n"), priv->TxPowerLevelOFDM24G, 14);
5364 #else
5366 for (rf_path = 0; rf_path < 2; rf_path++)
5368 for (i = 0; i < 3; i++)
5370 // Read CCK RF A & B Tx power
5371 priv->RfCckChnlAreaTxPwr[rf_path][i] =
5372 priv->RfOfdmChnlAreaTxPwr1T[rf_path][i] =
5373 priv->RfOfdmChnlAreaTxPwr2T[rf_path][i] =
5374 (u8)(EEPROM_Default_TxPower & 0xff);
5378 for (i = 0; i < 3; i++)
5380 //RT_TRACE((COMP_EFUSE), "CCK RF-%d CHan_Area-%d = 0x%x\n", rf_path, i,
5381 //priv->RfCckChnlAreaTxPwr[rf_path][i]);
5382 //RT_TRACE((COMP_EFUSE), "OFDM-1T RF-%d CHan_Area-%d = 0x%x\n", rf_path, i,
5383 //priv->RfOfdmChnlAreaTxPwr1T[rf_path][i]);
5384 //RT_TRACE((COMP_EFUSE), "OFDM-2T RF-%d CHan_Area-%d = 0x%x\n", rf_path, i,
5385 //priv->RfOfdmChnlAreaTxPwr2T[rf_path][i]);
5388 // Assign dedicated channel tx power
5389 for(i=0; i<14; i++) // channel 1~3 use the same Tx Power Level.
5391 if (i < 3) // Cjanel 1-3
5392 index = 0;
5393 else if (i < 9) // Channel 4-9
5394 index = 1;
5395 else // Channel 10-14
5396 index = 2;
5398 // Record A & B CCK /OFDM - 1T/2T Channel area tx power
5399 priv->RfTxPwrLevelCck[rf_path][i] =
5400 priv->RfCckChnlAreaTxPwr[rf_path][index];
5401 priv->RfTxPwrLevelOfdm1T[rf_path][i] =
5402 priv->RfOfdmChnlAreaTxPwr1T[rf_path][index];
5403 priv->RfTxPwrLevelOfdm2T[rf_path][i] =
5404 priv->RfOfdmChnlAreaTxPwr2T[rf_path][index];
5407 for(i=0; i<14; i++)
5409 //RT_TRACE((COMP_EFUSE), "Rf-%d TxPwr CH-%d CCK OFDM_1T OFDM_2T= 0x%x/0x%x/0x%x\n",
5410 //rf_path, i, priv->RfTxPwrLevelCck[0][i],
5411 //priv->RfTxPwrLevelOfdm1T[0][i] ,
5412 //priv->RfTxPwrLevelOfdm2T[0][i] );
5414 #endif
5417 // Update remained HAL variables.
5419 priv->TSSI_13dBm = priv->EEPROMThermalMeter *100;
5420 priv->LegacyHTTxPowerDiff = priv->EEPROMTxPowerDiff;//new
5421 priv->TxPowerDiff = priv->EEPROMTxPowerDiff;
5422 //priv->AntennaTxPwDiff[0] = (priv->EEPROMTxPowerDiff & 0xf);// Antenna B gain offset to antenna A, bit0~3
5423 //priv->AntennaTxPwDiff[1] = ((priv->EEPROMTxPowerDiff & 0xf0)>>4);// Antenna C gain offset to antenna A, bit4~7
5424 priv->CrystalCap = priv->EEPROMCrystalCap; // CrystalCap, bit12~15
5425 priv->ThermalMeter[0] = priv->EEPROMThermalMeter;// ThermalMeter, bit0~3 for RFIC1, bit4~7 for RFIC2
5426 priv->LedStrategy = SW_LED_MODE0;
5428 init_rate_adaptive(dev);
5430 RT_TRACE(COMP_INIT, "<==== ConfigAdapterInfo8192SForAutoLoadFail\n");
5434 #if 0
5435 static void rtl8192SU_ReadAdapterInfo8192SEEPROM(struct net_device* dev)
5437 u16 EEPROMId = 0;
5438 u8 bLoad_From_EEPOM = false;
5439 struct r8192_priv *priv = ieee80211_priv(dev);
5440 u16 tmpValue = 0;
5441 u8 tmpBuffer[30];
5442 int i;
5444 RT_TRACE(COMP_EPROM, "===========>%s()\n", __FUNCTION__);
5447 write_nic_byte(dev, SYS_ISO_CTRL+1, 0xE8); // Isolation signals from Loader
5448 udelay(10000);
5449 write_nic_byte(dev, PMC_FSM, 0x02); // Enable Loader Data Keep
5452 EEPROMId = eprom_read(dev, 0); //first read EEPROM ID out;
5453 RT_TRACE(COMP_EPROM, "EEPROM ID is 0x%x\n", EEPROMId);
5455 if (EEPROMId != RTL8190_EEPROM_ID)
5457 priv->AutoloadFailFlag = true;
5458 RT_TRACE(COMP_ERR, "EEPROM ID is invalid(is 0x%x(should be 0x%x)\n", EEPROMId, RTL8190_EEPROM_ID);
5460 else
5462 priv->AutoloadFailFlag = false;
5463 bLoad_From_EEPOM = true;
5466 if (bLoad_From_EEPOM)
5468 tmpValue = eprom_read(dev, (EEPROM_VID>>1));
5469 priv->eeprom_vid = endian_swap(&tmpValue);
5470 priv->eeprom_pid = eprom_read(dev, (EEPROM_PID>>1));
5472 // Version ID, Channel plan
5473 tmpValue = eprom_read(dev, (EEPROM_Version>>1));
5474 //pHalData->card_8192_version = (VERSION_8192S)((usValue&0x00ff));
5475 priv->eeprom_ChannelPlan =(tmpValue&0xff00)>>8;
5476 priv->bTXPowerDataReadFromEEPORM = true;
5478 // Customer ID, 0x00 and 0xff are reserved for Realtek.
5479 tmpValue = eprom_read(dev, (u16)(EEPROM_CustomID>>1)) ;
5480 priv->eeprom_CustomerID = (u8)( tmpValue & 0xff);
5481 priv->eeprom_SubCustomerID = (u8)((tmpValue & 0xff00)>>8);
5483 else
5485 priv->eeprom_vid = 0;
5486 priv->eeprom_pid = 0;
5487 //priv->card_8192_version = VERSION_8192SU_A;
5488 priv->eeprom_ChannelPlan = 0;
5489 priv->eeprom_CustomerID = 0;
5490 priv->eeprom_SubCustomerID = 0;
5492 RT_TRACE(COMP_EPROM, "vid:0x%4x, pid:0x%4x, CustomID:0x%2x, ChanPlan:0x%x\n", priv->eeprom_vid, priv->eeprom_pid, priv->eeprom_CustomerID, priv->eeprom_ChannelPlan);
5493 //set channelplan from eeprom
5494 priv->ChannelPlan = priv->eeprom_ChannelPlan;// FIXLZM
5496 RT_TRACE(COMP_INIT, "EEPROMId = 0x%4x\n", EEPROMId);
5497 RT_TRACE(COMP_INIT, "EEPROM VID = 0x%4x\n", priv->eeprom_vid);
5498 RT_TRACE(COMP_INIT, "EEPROM PID = 0x%4x\n", priv->eeprom_pid);
5499 //RT_TRACE(COMP_INIT, DBG_LOUD, ("EEPROM Version ID: 0x%2x\n", pHalData->VersionID));
5500 RT_TRACE(COMP_INIT, "EEPROM Customer ID: 0x%2x\n", priv->eeprom_CustomerID);
5501 RT_TRACE(COMP_INIT, "EEPROM SubCustomer ID: 0x%2x\n", priv->eeprom_SubCustomerID);
5502 RT_TRACE(COMP_INIT, "EEPROM ChannelPlan = 0x%4x\n", priv->eeprom_ChannelPlan);
5504 // Read USB optional function.
5505 if(bLoad_From_EEPOM)
5507 tmpValue = eprom_read(dev, (EEPROM_USB_OPTIONAL>>1));
5508 priv->EEPROMUsbOption = (u8)(tmpValue&0xff);
5510 else
5512 priv->EEPROMUsbOption = EEPROM_USB_Default_OPTIONAL_FUNC;
5515 RT_TRACE(COMP_INIT, "USB Option = %#x\n", priv->EEPROMUsbOption);
5518 if (bLoad_From_EEPOM)
5520 int i;
5521 for (i=0; i<6; i+=2)
5523 u16 tmp = 0;
5524 tmp = eprom_read(dev, (u16)((EEPROM_NODE_ADDRESS_BYTE_0 + i)>>1));
5525 *(u16*)(&dev->dev_addr[i]) = tmp;
5528 else
5530 //<Roger_Notes> In this case, we random assigh MAC address here. 2008.10.15.
5531 static u8 sMacAddr[6] = {0x00, 0xE0, 0x4C, 0x81, 0x92, 0x00};
5532 u8 i;
5534 //sMacAddr[5] = (u8)GetRandomNumber(1, 254);
5536 for(i = 0; i < 6; i++)
5537 dev->dev_addr[i] = sMacAddr[i];
5539 //memcpy(dev->dev_addr, sMacAddr, 6);
5540 //should I set IDR0 here?
5542 write_nic_dword(dev, IDR0, ((u32*)dev->dev_addr)[0]);
5543 write_nic_word(dev, IDR4, ((u16*)(dev->dev_addr + 4))[0]);
5544 RT_TRACE(COMP_EPROM, "MAC addr:"MAC_FMT"\n", MAC_ARG(dev->dev_addr));
5546 priv->rf_type = RTL819X_DEFAULT_RF_TYPE; //default 1T2R
5547 #if (defined (RTL8192SU_FPGA_2MAC_VERIFICATION)||defined (RTL8192SU_ASIC_VERIFICATION))
5548 priv->rf_chip = RF_6052;
5549 priv->rf_type = RTL819X_DEFAULT_RF_TYPE;
5550 //priv->card_8192_version = VERSION_8192SU_A; //Over write for temporally experiment. 2008.10.16. By Roger.
5551 #else
5552 priv->rf_chip = RF_8256;
5553 #endif
5556 #if 0
5557 if(bLoad_From_EEPOM)
5559 tempval = (ReadEEprom(Adapter, (EEPROM_RFInd_PowerDiff>>1))) & 0xff;
5560 if (tempval&0x80) //RF-indication, bit[7]
5561 pHalData->RF_Type = RF_1T2R;
5562 else
5563 pHalData->RF_Type = RF_2T4R;
5565 #endif
5567 priv->EEPROMTxPowerDiff = EEPROM_Default_TxPowerDiff;
5568 RT_TRACE(COMP_INIT, "TxPowerDiff = %#x\n", priv->EEPROMTxPowerDiff);
5572 // Read antenna tx power offset of B/C/D to A from EEPROM
5573 // and read ThermalMeter from EEPROM
5575 if(bLoad_From_EEPOM)
5577 tmpValue = eprom_read(dev, (EEPROM_PwDiff>>1));
5578 priv->EEPROMPwDiff = tmpValue&0x00ff;
5579 priv->EEPROMThermalMeter = (tmpValue&0xff00)>>8;
5581 else
5583 priv->EEPROMPwDiff = EEPROM_Default_PwDiff;
5584 priv->EEPROMThermalMeter = EEPROM_Default_ThermalMeter;
5586 RT_TRACE(COMP_INIT, "PwDiff = %#x\n", priv->EEPROMPwDiff);
5587 RT_TRACE(COMP_INIT, "ThermalMeter = %#x\n", priv->EEPROMThermalMeter);
5589 priv->TSSI_13dBm = priv->EEPROMThermalMeter *100;
5592 // Read CrystalCap from EEPROM
5593 if(bLoad_From_EEPOM)
5595 priv->EEPROMCrystalCap =(u8) (((eprom_read(dev, (EEPROM_CrystalCap>>1)))&0xf000)>>12);
5597 else
5599 priv->EEPROMCrystalCap = EEPROM_Default_CrystalCap;
5601 RT_TRACE(COMP_INIT, "CrystalCap = %#x\n", priv->EEPROMCrystalCap);
5604 //if(pHalData->EEPROM_Def_Ver == 0) // old eeprom definition
5608 // Get Tx Power Base.//===>
5610 if(bLoad_From_EEPOM)
5612 priv->EEPROMTxPwrBase =(u8) ((eprom_read(dev, (EEPROM_TxPowerBase>>1)))&0xff);
5614 else
5616 priv->EEPROMTxPwrBase = EEPROM_Default_TxPowerBase;
5619 RT_TRACE(COMP_INIT, "TxPwrBase = %#x\n", priv->EEPROMTxPwrBase);
5622 // Get CustomerID(Boad Type)
5623 // i.e., 0x0: RTL8188SU, 0x1: RTL8191SU, 0x2: RTL8192SU, 0x3: RTL8191GU.
5624 // Others: Reserved. Default is 0x2: RTL8192SU.
5626 if(bLoad_From_EEPOM)
5628 tmpValue = eprom_read(dev, (u16) (EEPROM_BoardType>>1));
5629 priv->EEPROMBoardType = (u8)(tmpValue&0xff);
5631 else
5633 priv->EEPROMBoardType = EEPROM_Default_BoardType;
5636 RT_TRACE(COMP_INIT, "BoardType = %#x\n", priv->EEPROMBoardType);
5638 #ifdef EEPROM_OLD_FORMAT_SUPPORT
5641 // Buffer TxPwIdx(i.e., from offset 0x58~0x75, total 30Bytes)
5643 if(bLoad_From_EEPOM)
5645 for(i = 0; i < 30; i += 2)
5647 tmpValue = eprom_read(dev, (u16) ((EEPROM_TxPowerBase+i)>>1));
5648 *((u16 *)(&tmpBuffer[i])) = tmpValue;
5653 // Update CCK, OFDM Tx Power Index from above buffer.
5655 if(bLoad_From_EEPOM)
5657 for(i=0; i<14; i++)
5659 priv->EEPROMTxPowerLevelCCK24G[i] = (u8)tmpBuffer[i+1];
5660 priv->EEPROMTxPowerLevelOFDM24G[i] = (u8)tmpBuffer[i+15];
5664 else
5666 for(i=0; i<14; i++)
5668 priv->EEPROMTxPowerLevelCCK24G[i] = (u8)(EEPROM_Default_TxPower & 0xff);
5669 priv->EEPROMTxPowerLevelOFDM24G[i] = (u8)(EEPROM_Default_TxPower & 0xff);
5673 for(i=0; i<14; i++)
5675 RT_TRACE(COMP_INIT, "CCK 2.4G Tx Power Level, Index %d = 0x%02x\n", i, priv->EEPROMTxPowerLevelCCK24G[i]);
5676 RT_TRACE(COMP_INIT, "OFDM 2.4G Tx Power Level, Index %d = 0x%02x\n", i, priv->EEPROMTxPowerLevelOFDM24G[i]);
5678 #else
5679 // Please add code in the section!!!!
5680 // And merge tx power difference section.
5681 #endif
5684 // Get TSSI value for each path.
5686 if(bLoad_From_EEPOM)
5688 tmpValue = eprom_read(dev, (u16) ((EEPROM_TSSI_A)>>1));
5689 priv->EEPROMTSSI_A = (u8)((tmpValue&0xff00)>>8);
5691 else
5692 { // Default setting for Empty EEPROM
5693 priv->EEPROMTSSI_A = EEPROM_Default_TSSI;
5696 if(bLoad_From_EEPOM)
5698 tmpValue = eprom_read(dev, (u16) ((EEPROM_TSSI_B)>>1));
5699 priv->EEPROMTSSI_B = (u8)(tmpValue&0xff);
5700 priv->EEPROMTxPwrTkMode = (u8)((tmpValue&0xff00)>>8);
5702 else
5703 { // Default setting for Empty EEPROM
5704 priv->EEPROMTSSI_B = EEPROM_Default_TSSI;
5705 priv->EEPROMTxPwrTkMode = EEPROM_Default_TxPwrTkMode;
5708 RT_TRACE(COMP_INIT, "TSSI_A = %#x, TSSI_B = %#x\n", priv->EEPROMTSSI_A, priv->EEPROMTSSI_B);
5709 RT_TRACE(COMP_INIT, "TxPwrTkMod = %#x\n", priv->EEPROMTxPwrTkMode);
5711 #ifdef EEPROM_OLD_FORMAT_SUPPORT
5713 // Get HT 2T Path A and B Power Index.
5715 if(bLoad_From_EEPOM)
5717 for(i = 0; i < 6; i += 2)
5719 tmpValue = eprom_read(dev, (u16) ((EEPROM_HT2T_CH1_A+i)>>1));
5720 *((u16*)(&priv->EEPROMHT2T_TxPwr[i])) = tmpValue;
5723 else
5724 { // Default setting for Empty EEPROM
5725 for(i=0; i<6; i++)
5727 priv->EEPROMHT2T_TxPwr[i] = EEPROM_Default_HT2T_TxPwr;
5731 for(i=0; i<6; i++)
5733 RT_TRACE(COMP_INIT, "EEPROMHT2T_TxPwr, Index %d = 0x%02x\n", i, priv->EEPROMHT2T_TxPwr[i]);
5735 #else
5737 #endif
5740 #ifdef EEPROM_OLD_FORMAT_SUPPORT
5742 // Update HAL variables.
5744 for(i=0; i<14; i++)
5746 priv->TxPowerLevelOFDM24G[i] = priv->EEPROMTxPowerLevelOFDM24G[i];
5747 priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelCCK24G[i];
5749 #else
5751 #endif
5752 priv->TxPowerDiff = priv->EEPROMPwDiff;
5753 // Antenna B gain offset to antenna A, bit0~3
5754 priv->AntennaTxPwDiff[0] = (priv->EEPROMTxPowerDiff & 0xf);
5755 // Antenna C gain offset to antenna A, bit4~7
5756 priv->AntennaTxPwDiff[1] = ((priv->EEPROMTxPowerDiff & 0xf0)>>4);
5757 // CrystalCap, bit12~15
5758 priv->CrystalCap = priv->EEPROMCrystalCap;
5759 // ThermalMeter, bit0~3 for RFIC1, bit4~7 for RFIC2
5760 // 92U does not enable TX power tracking.
5761 priv->ThermalMeter[0] = priv->EEPROMThermalMeter;
5764 priv->LedStrategy = SW_LED_MODE0;
5766 if(priv->rf_type == RF_1T2R)
5768 RT_TRACE(COMP_EPROM, "\n1T2R config\n");
5770 else
5772 RT_TRACE(COMP_EPROM, "\n2T4R config\n");
5775 // 2008/01/16 MH We can only know RF type in the function. So we have to init
5776 // DIG RATR table again.
5777 init_rate_adaptive(dev);
5778 //we need init DIG RATR table here again.
5780 RT_TRACE(COMP_EPROM, "<===========%s()\n", __FUNCTION__);
5781 return;
5785 // Description:
5786 // 1. Read HW adapter information by E-Fuse.
5787 // 2. Refered from SD1 Richard.
5789 // Assumption:
5790 // 1. Boot from E-Fuse and CR9346 regiser has verified.
5791 // 2. PASSIVE_LEVEL (USB interface)
5793 // Created by Roger, 2008.10.21.
5795 void
5796 rtl8192SU_ReadAdapterInfo8192SEFuse(struct net_device* dev)
5798 struct r8192_priv *priv = ieee80211_priv(dev);
5799 u16 i,usValue;
5800 u16 EEPROMId;
5801 u8 readbyte;
5802 u8 OFDMTxPwr[14];
5803 u8 CCKTxPwr[14];
5804 u8 HT2T_TxPwr[6];
5805 u8 UsbPhyParam[5];
5806 u8 hwinfo[HWSET_MAX_SIZE_92S];
5809 RT_TRACE(COMP_INIT, "====> ReadAdapterInfo8192SEFuse\n");
5812 // <Roger_Notes> We set Isolation signals from Loader and reset EEPROM after system resuming
5813 // from suspend mode.
5814 // 2008.10.21.
5816 write_nic_byte(dev, SYS_ISO_CTRL+1, 0xE8); // Isolation signals from Loader
5817 //PlatformStallExecution(10000);
5818 mdelay(10);
5819 write_nic_byte(dev, SYS_FUNC_EN+1, 0x40);
5820 write_nic_byte(dev, SYS_FUNC_EN+1, 0x50);
5822 readbyte = read_nic_byte(dev, EFUSE_TEST+3);
5823 write_nic_byte(dev, EFUSE_TEST+3, (readbyte | 0x80));
5824 write_nic_byte(dev, EFUSE_TEST+3, 0x72);
5825 write_nic_byte(dev, EFUSE_CLK, 0x03);
5828 // Dump EFUSe at init time for later use
5830 // Read EFUSE real map to shadow!!
5831 EFUSE_ShadowMapUpdate(dev);
5833 memcpy(hwinfo, (void*)&priv->EfuseMap[EFUSE_INIT_MAP][0], HWSET_MAX_SIZE_92S);
5834 //RT_PRINT_DATA(COMP_INIT, DBG_LOUD, ("MAP \n"), hwinfo, HWSET_MAX_SIZE_92S);
5837 // <Roger_Notes> Event though CR9346 regiser can verify whether Autoload is success or not, but we still
5838 // double check ID codes for 92S here(e.g., due to HW GPIO polling fail issue).
5839 // 2008.10.21.
5841 ReadEFuse(dev, 0, 2, (unsigned char*) &EEPROMId);
5843 if( EEPROMId != RTL8190_EEPROM_ID )
5845 RT_TRACE(COMP_INIT, "EEPROM ID(%#x) is invalid!!\n", EEPROMId);
5846 priv->AutoloadFailFlag=true;
5848 else
5850 priv->AutoloadFailFlag=false;
5853 // Read IC Version && Channel Plan
5854 if(!priv->AutoloadFailFlag)
5857 // VID, PID
5858 ReadEFuse(dev, EEPROM_VID, 2, (unsigned char*) &priv->eeprom_vid);
5859 ReadEFuse(dev, EEPROM_PID, 2, (unsigned char*) &priv->eeprom_pid);
5861 // Version ID, Channel plan
5862 ReadEFuse(dev, EEPROM_Version, 2, (unsigned char*) &usValue);
5863 //pHalData->VersionID = (VERSION_8192S)(usValue&0x00ff);
5864 priv->eeprom_ChannelPlan = (usValue&0xff00>>8);
5865 priv->bTXPowerDataReadFromEEPORM = true;
5867 // Customer ID, 0x00 and 0xff are reserved for Realtek.
5868 ReadEFuse(dev, EEPROM_CustomID, 2, (unsigned char*) &usValue);
5869 priv->eeprom_CustomerID = (u8)( usValue & 0xff);
5870 priv->eeprom_SubCustomerID = (u8)((usValue & 0xff00)>>8);
5872 else
5874 priv->eeprom_vid = 0;
5875 priv->eeprom_pid = 0;
5876 priv->eeprom_ChannelPlan = 0;
5877 priv->eeprom_CustomerID = 0;
5878 priv->eeprom_SubCustomerID = 0;
5881 RT_TRACE(COMP_INIT, "EEPROM Id = 0x%4x\n", EEPROMId);
5882 RT_TRACE(COMP_INIT, "EEPROM VID = 0x%4x\n", priv->eeprom_vid);
5883 RT_TRACE(COMP_INIT, "EEPROM PID = 0x%4x\n", priv->eeprom_pid);
5884 //RT_TRACE(COMP_INIT, DBG_LOUD, ("EEPROM Version ID: 0x%2x\n", pHalData->VersionID));
5885 RT_TRACE(COMP_INIT, "EEPROM Customer ID: 0x%2x\n", priv->eeprom_CustomerID);
5886 RT_TRACE(COMP_INIT, "EEPROM SubCustomer ID: 0x%2x\n", priv->eeprom_SubCustomerID);
5887 RT_TRACE(COMP_INIT, "EEPROM ChannelPlan = 0x%4x\n", priv->eeprom_ChannelPlan);
5890 // Read USB optional function.
5891 if(!priv->AutoloadFailFlag)
5893 ReadEFuse(dev, EEPROM_USB_OPTIONAL, 1, (unsigned char*) &priv->EEPROMUsbOption);
5895 else
5897 priv->EEPROMUsbOption = EEPROM_USB_Default_OPTIONAL_FUNC;
5900 RT_TRACE(COMP_INIT, "USB Option = %#x\n", priv->EEPROMUsbOption);
5903 // Read USB PHY parameters.
5904 if(!priv->AutoloadFailFlag)
5906 ReadEFuse(dev, EEPROM_USB_PHY_PARA1, 5, (unsigned char*)UsbPhyParam);
5907 for(i=0; i<5; i++)
5909 priv->EEPROMUsbPhyParam[i] = UsbPhyParam[i];
5910 RT_TRACE(COMP_INIT, "USB Param = index(%d) = %#x\n", i, priv->EEPROMUsbPhyParam[i]);
5913 else
5915 for(i=0; i<5; i++)
5917 priv->EEPROMUsbPhyParam[i] = EEPROM_USB_Default_PHY_PARAM;
5918 RT_TRACE(COMP_INIT, "USB Param = index(%d) = %#x\n", i, priv->EEPROMUsbPhyParam[i]);
5923 //Read Permanent MAC address
5924 if(!priv->AutoloadFailFlag)
5926 u8 macaddr[6] = {0x00, 0xe1, 0x86, 0x4c, 0x92, 0x00};
5928 ReadEFuse(dev, EEPROM_NODE_ADDRESS_BYTE_0, 6, (unsigned char*)macaddr);
5929 for(i=0; i<6; i++)
5930 dev->dev_addr[i] = macaddr[i];
5932 else
5933 {//Auto load fail
5935 //<Roger_Notes> In this case, we random assigh MAC address here. 2008.10.15.
5936 static u8 sMacAddr[6] = {0x00, 0xE0, 0x4C, 0x81, 0x92, 0x00};
5937 u8 i;
5939 //if(!Adapter->bInHctTest)
5940 //sMacAddr[5] = (u8)GetRandomNumber(1, 254);
5942 for(i = 0; i < 6; i++)
5943 dev->dev_addr[i] = sMacAddr[i];
5946 //NicIFSetMacAddress(Adapter, Adapter->PermanentAddress);
5947 write_nic_dword(dev, IDR0, ((u32*)dev->dev_addr)[0]);
5948 write_nic_word(dev, IDR4, ((u16*)(dev->dev_addr + 4))[0]);
5950 RT_TRACE(COMP_INIT, "ReadAdapterInfo8192SEFuse(), Permanent Address = %02x-%02x-%02x-%02x-%02x-%02x\n",
5951 dev->dev_addr[0], dev->dev_addr[1],
5952 dev->dev_addr[2], dev->dev_addr[3],
5953 dev->dev_addr[4], dev->dev_addr[5]);
5955 // 2007/11/15 MH For RTL8192USB we assign as 1T2R now.
5956 priv->rf_type = RTL819X_DEFAULT_RF_TYPE; // default : 1T2R
5958 #if (defined (RTL8192SU_FPGA_2MAC_VERIFICATION)||defined (RTL8192SU_ASIC_VERIFICATION))
5959 priv->rf_chip = RF_6052;
5960 priv->rf_type = RTL819X_DEFAULT_RF_TYPE;
5961 #else
5962 priv->rf_chip = RF_8256;
5963 #endif
5967 // Read antenna tx power offset of B/C/D to A from EEPROM
5968 // and read ThermalMeter from EEPROM
5970 if(!priv->AutoloadFailFlag)
5972 ReadEFuse(dev, EEPROM_PwDiff, 2, (unsigned char*) &usValue);
5973 priv->EEPROMPwDiff = usValue&0x00ff;
5974 priv->EEPROMThermalMeter = (usValue&0xff00)>>8;
5976 else
5978 priv->EEPROMPwDiff = EEPROM_Default_PwDiff;
5979 priv->EEPROMThermalMeter = EEPROM_Default_ThermalMeter;
5982 RT_TRACE(COMP_INIT, "PwDiff = %#x\n", priv->EEPROMPwDiff);
5983 RT_TRACE(COMP_INIT, "ThermalMeter = %#x\n", priv->EEPROMThermalMeter);
5985 priv->TSSI_13dBm = priv->EEPROMThermalMeter *100;
5988 // Read Tx Power gain offset of legacy OFDM to HT rate.
5989 // Read CrystalCap from EEPROM
5991 if(!priv->AutoloadFailFlag)
5993 ReadEFuse(dev, EEPROM_CrystalCap, 1, (unsigned char*) &usValue);
5994 priv->EEPROMCrystalCap = (u8)((usValue&0xf0)>>4);
5996 else
5998 priv->EEPROMCrystalCap = EEPROM_Default_CrystalCap;
6001 RT_TRACE(COMP_INIT, "CrystalCap = %#x\n", priv->EEPROMCrystalCap);
6003 priv->EEPROMTxPowerDiff = EEPROM_Default_TxPowerDiff;
6004 RT_TRACE(COMP_INIT, "TxPowerDiff = %d\n", priv->EEPROMTxPowerDiff);
6008 // Get Tx Power Base.
6010 if(!priv->AutoloadFailFlag)
6012 ReadEFuse(dev, EEPROM_TxPowerBase, 1, (unsigned char*) &priv->EEPROMTxPwrBase );
6014 else
6016 priv->EEPROMTxPwrBase = EEPROM_Default_TxPowerBase;
6019 RT_TRACE(COMP_INIT, "TxPwrBase = %#x\n", priv->EEPROMTxPwrBase);
6022 // Get CustomerID(Boad Type)
6023 // i.e., 0x0: RTL8188SU, 0x1: RTL8191SU, 0x2: RTL8192SU, 0x3: RTL8191GU.
6024 // Others: Reserved. Default is 0x2: RTL8192SU.
6026 if(!priv->AutoloadFailFlag)
6028 ReadEFuse(dev, EEPROM_BoardType, 1, (unsigned char*) &priv->EEPROMBoardType );
6030 else
6032 priv->EEPROMBoardType = EEPROM_Default_BoardType;
6035 RT_TRACE(COMP_INIT, "BoardType = %#x\n", priv->EEPROMBoardType);
6037 //if(pHalData->EEPROM_Def_Ver == 0)
6039 #ifdef EEPROM_OLD_FORMAT_SUPPORT
6041 // Get CCK Tx Power Index.
6043 if(!priv->AutoloadFailFlag)
6045 ReadEFuse(dev, EEPROM_TxPwIndex_CCK_24G, 14, (unsigned char*)CCKTxPwr);
6046 for(i=0; i<14; i++)
6048 RT_TRACE(COMP_INIT, "CCK 2.4G Tx Power Level, Index %d = 0x%02x\n", i, CCKTxPwr[i]);
6049 priv->EEPROMTxPowerLevelCCK24G[i] = CCKTxPwr[i];
6052 else
6053 { // Default setting for Empty EEPROM
6054 for(i=0; i<14; i++)
6055 priv->EEPROMTxPowerLevelCCK24G[i] = (u8)(EEPROM_Default_TxPower & 0xff);
6059 // Get OFDM Tx Power Index.
6061 if(!priv->AutoloadFailFlag)
6063 ReadEFuse(dev, EEPROM_TxPwIndex_OFDM_24G, 14, (unsigned char*)OFDMTxPwr);
6064 for(i=0; i<14; i++)
6066 RT_TRACE(COMP_INIT, "OFDM 2.4G Tx Power Level, Index %d = 0x%02x\n", i, OFDMTxPwr[i]);
6067 priv->EEPROMTxPowerLevelOFDM24G[i] = OFDMTxPwr[i];
6070 else
6071 { // Default setting for Empty EEPROM
6072 usValue = 0x10;
6073 for(i=0; i<14; i++)
6074 priv->EEPROMTxPowerLevelOFDM24G[i] = (u8)usValue;
6076 #else
6077 // Please add code in the section!!!!
6078 // And merge tx power difference section.
6079 #endif
6082 // Get TSSI value for each path.
6084 if(!priv->AutoloadFailFlag)
6086 ReadEFuse(dev, EEPROM_TSSI_A, 2, (unsigned char*)&usValue);
6087 priv->EEPROMTSSI_A = (u8)(usValue&0xff);
6088 priv->EEPROMTSSI_B = (u8)((usValue&0xff00)>>8);
6090 else
6091 { // Default setting for Empty EEPROM
6092 priv->EEPROMTSSI_A = EEPROM_Default_TSSI;
6093 priv->EEPROMTSSI_B = EEPROM_Default_TSSI;
6096 RT_TRACE(COMP_INIT, "TSSI_A = %#x, TSSI_B = %#x\n",
6097 priv->EEPROMTSSI_A, priv->EEPROMTSSI_B);
6100 // Get Tx Power tracking mode.
6102 if(!priv->AutoloadFailFlag)
6104 ReadEFuse(dev, EEPROM_TxPwTkMode, 1, (unsigned char*)&priv->EEPROMTxPwrTkMode);
6106 else
6107 { // Default setting for Empty EEPROM
6108 priv->EEPROMTxPwrTkMode = EEPROM_Default_TxPwrTkMode;
6111 RT_TRACE(COMP_INIT, "TxPwrTkMod = %#x\n", priv->EEPROMTxPwrTkMode);
6114 // TODO: The following HT 2T Path A and B Power Index should be updated.!! Added by Roger, 2008.20.23.
6117 // Get HT 2T Path A and B Power Index.
6119 if(!priv->AutoloadFailFlag)
6121 ReadEFuse(dev, EEPROM_HT2T_CH1_A, 6, (unsigned char*)HT2T_TxPwr);
6122 for(i=0; i<6; i++)
6124 priv->EEPROMHT2T_TxPwr[i] = HT2T_TxPwr[i];
6127 else
6128 { // Default setting for Empty EEPROM
6129 for(i=0; i<6; i++)
6131 priv->EEPROMHT2T_TxPwr[i] = EEPROM_Default_HT2T_TxPwr;
6135 for(i=0; i<6; i++)
6137 RT_TRACE(COMP_INIT, "EEPROMHT2T_TxPwr, Index %d = 0x%02x\n",
6138 i, priv->EEPROMHT2T_TxPwr[i]);
6142 #ifdef EEPROM_OLD_FORMAT_SUPPORT
6144 // Update HAL variables.
6146 for(i=0; i<14; i++)
6148 priv->TxPowerLevelOFDM24G[i] = priv->EEPROMTxPowerLevelOFDM24G[i];
6149 priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelCCK24G[i];
6151 #else
6153 #endif
6154 priv->TxPowerDiff = priv->EEPROMPwDiff;
6155 // Antenna B gain offset to antenna A, bit0~3
6156 priv->AntennaTxPwDiff[0] = (priv->EEPROMTxPowerDiff & 0xf);
6157 // Antenna C gain offset to antenna A, bit4~7
6158 priv->AntennaTxPwDiff[1] = ((priv->EEPROMTxPowerDiff & 0xf0)>>4);
6159 // CrystalCap, bit12~15
6160 priv->CrystalCap = priv->EEPROMCrystalCap;
6161 // ThermalMeter, bit0~3 for RFIC1, bit4~7 for RFIC2
6162 // 92U does not enable TX power tracking.
6163 priv->ThermalMeter[0] = priv->EEPROMThermalMeter;
6166 priv->LedStrategy = SW_LED_MODE0;
6168 init_rate_adaptive(dev);
6170 RT_TRACE(COMP_INIT, "<==== ReadAdapterInfo8192SEFuse\n");
6173 #endif
6176 // Description:
6177 // Read HW adapter information by E-Fuse or EEPROM according CR9346 reported.
6179 // Assumption:
6180 // 1. CR9346 regiser has verified.
6181 // 2. PASSIVE_LEVEL (USB interface)
6183 // Created by Roger, 2008.10.21.
6185 void
6186 rtl8192SU_ReadAdapterInfo8192SUsb(struct net_device* dev)
6188 struct r8192_priv *priv = ieee80211_priv(dev);
6189 u16 i,usValue;
6190 u8 tmpU1b, tempval;
6191 u16 EEPROMId;
6192 u8 hwinfo[HWSET_MAX_SIZE_92S];
6193 u8 rf_path, index; // For EEPROM/EFUSE After V0.6_1117
6196 RT_TRACE(COMP_INIT, "====> ReadAdapterInfo8192SUsb\n");
6199 // <Roger_Note> The following operation are prevent Efuse leakage by turn on 2.5V.
6200 // 2008.11.25.
6202 tmpU1b = read_nic_byte(dev, EFUSE_TEST+3);
6203 write_nic_byte(dev, EFUSE_TEST+3, tmpU1b|0x80);
6204 //PlatformStallExecution(1000);
6205 mdelay(10);
6206 write_nic_byte(dev, EFUSE_TEST+3, (tmpU1b&(~BIT7)));
6208 // Retrieve Chip version.
6209 priv->card_8192_version = (VERSION_8192S)((read_nic_dword(dev, PMC_FSM)>>16)&0xF);
6210 RT_TRACE(COMP_INIT, "Chip Version ID: 0x%2x\n", priv->card_8192_version);
6212 switch(priv->card_8192_version)
6214 case 0:
6215 RT_TRACE(COMP_INIT, "Chip Version ID: VERSION_8192S_ACUT.\n");
6216 break;
6217 case 1:
6218 RT_TRACE(COMP_INIT, "Chip Version ID: VERSION_8192S_BCUT.\n");
6219 break;
6220 case 2:
6221 RT_TRACE(COMP_INIT, "Chip Version ID: VERSION_8192S_CCUT.\n");
6222 break;
6223 default:
6224 RT_TRACE(COMP_INIT, "Unknown Chip Version!!\n");
6225 priv->card_8192_version = VERSION_8192S_BCUT;
6226 break;
6229 //if (IS_BOOT_FROM_EEPROM(Adapter))
6230 if(priv->EepromOrEfuse)
6231 { // Read frin EEPROM
6232 write_nic_byte(dev, SYS_ISO_CTRL+1, 0xE8); // Isolation signals from Loader
6233 //PlatformStallExecution(10000);
6234 mdelay(10);
6235 write_nic_byte(dev, PMC_FSM, 0x02); // Enable Loader Data Keep
6236 // Read all Content from EEPROM or EFUSE.
6237 for(i = 0; i < HWSET_MAX_SIZE_92S; i += 2)
6239 usValue = eprom_read(dev, (u16) (i>>1));
6240 *((u16*)(&hwinfo[i])) = usValue;
6243 else if (!(priv->EepromOrEfuse))
6244 { // Read from EFUSE
6247 // <Roger_Notes> We set Isolation signals from Loader and reset EEPROM after system resuming
6248 // from suspend mode.
6249 // 2008.10.21.
6251 //PlatformEFIOWrite1Byte(Adapter, SYS_ISO_CTRL+1, 0xE8); // Isolation signals from Loader
6252 //PlatformStallExecution(10000);
6253 //PlatformEFIOWrite1Byte(Adapter, SYS_FUNC_EN+1, 0x40);
6254 //PlatformEFIOWrite1Byte(Adapter, SYS_FUNC_EN+1, 0x50);
6256 //tmpU1b = PlatformEFIORead1Byte(Adapter, EFUSE_TEST+3);
6257 //PlatformEFIOWrite1Byte(Adapter, EFUSE_TEST+3, (tmpU1b | 0x80));
6258 //PlatformEFIOWrite1Byte(Adapter, EFUSE_TEST+3, 0x72);
6259 //PlatformEFIOWrite1Byte(Adapter, EFUSE_CLK, 0x03);
6261 // Read EFUSE real map to shadow.
6262 EFUSE_ShadowMapUpdate(dev);
6263 memcpy(hwinfo, &priv->EfuseMap[EFUSE_INIT_MAP][0], HWSET_MAX_SIZE_92S);
6265 else
6267 RT_TRACE(COMP_INIT, "ReadAdapterInfo8192SUsb(): Invalid boot type!!\n");
6270 //YJ,test,090106
6271 //dump_buf(hwinfo,HWSET_MAX_SIZE_92S);
6273 // <Roger_Notes> The following are EFUSE/EEPROM independent operations!!
6275 //RT_PRINT_DATA(COMP_EFUSE, DBG_LOUD, ("MAP: \n"), hwinfo, HWSET_MAX_SIZE_92S);
6278 // <Roger_Notes> Event though CR9346 regiser can verify whether Autoload is success or not, but we still
6279 // double check ID codes for 92S here(e.g., due to HW GPIO polling fail issue).
6280 // 2008.10.21.
6282 EEPROMId = *((u16 *)&hwinfo[0]);
6284 if( EEPROMId != RTL8190_EEPROM_ID )
6286 RT_TRACE(COMP_INIT, "ID(%#x) is invalid!!\n", EEPROMId);
6287 priv->bTXPowerDataReadFromEEPORM = FALSE;
6288 priv->AutoloadFailFlag=TRUE;
6290 else
6292 priv->AutoloadFailFlag=FALSE;
6293 #if RTL8192SU_USE_PARAM_TXPWR
6294 priv->bTXPowerDataReadFromEEPORM = FALSE;
6295 #else
6296 priv->bTXPowerDataReadFromEEPORM = TRUE;
6297 #endif
6300 // Read IC Version && Channel Plan
6301 if(!priv->AutoloadFailFlag)
6303 // VID, PID
6304 priv->eeprom_vid = *(u16 *)&hwinfo[EEPROM_VID];
6305 priv->eeprom_pid = *(u16 *)&hwinfo[EEPROM_PID];
6306 priv->bIgnoreDiffRateTxPowerOffset = false; //cosa for test
6309 // EEPROM Version ID, Channel plan
6310 priv->EEPROMVersion = *(u8 *)&hwinfo[EEPROM_Version];
6311 priv->eeprom_ChannelPlan = *(u8 *)&hwinfo[EEPROM_ChannelPlan];
6313 // Customer ID, 0x00 and 0xff are reserved for Realtek.
6314 priv->eeprom_CustomerID = *(u8 *)&hwinfo[EEPROM_CustomID];
6315 priv->eeprom_SubCustomerID = *(u8 *)&hwinfo[EEPROM_SubCustomID];
6317 else
6319 //priv->eeprom_vid = 0;
6320 //priv->eeprom_pid = 0;
6321 //priv->EEPROMVersion = 0;
6322 //priv->eeprom_ChannelPlan = 0;
6323 //priv->eeprom_CustomerID = 0;
6324 //priv->eeprom_SubCustomerID = 0;
6326 rtl8192SU_ConfigAdapterInfo8192SForAutoLoadFail(dev);
6327 return;
6331 RT_TRACE(COMP_INIT, "EEPROM Id = 0x%4x\n", EEPROMId);
6332 RT_TRACE(COMP_INIT, "EEPROM VID = 0x%4x\n", priv->eeprom_vid);
6333 RT_TRACE(COMP_INIT, "EEPROM PID = 0x%4x\n", priv->eeprom_pid);
6334 RT_TRACE(COMP_INIT, "EEPROM Version ID: 0x%2x\n", priv->EEPROMVersion);
6335 RT_TRACE(COMP_INIT, "EEPROM Customer ID: 0x%2x\n", priv->eeprom_CustomerID);
6336 RT_TRACE(COMP_INIT, "EEPROM SubCustomer ID: 0x%2x\n", priv->eeprom_SubCustomerID);
6337 RT_TRACE(COMP_INIT, "EEPROM ChannelPlan = 0x%4x\n", priv->eeprom_ChannelPlan);
6338 RT_TRACE(COMP_INIT, "bIgnoreDiffRateTxPowerOffset = %d\n", priv->bIgnoreDiffRateTxPowerOffset);
6341 // Read USB optional function.
6342 if(!priv->AutoloadFailFlag)
6344 priv->EEPROMUsbOption = *(u8 *)&hwinfo[EEPROM_USB_OPTIONAL];
6346 else
6348 priv->EEPROMUsbOption = EEPROM_USB_Default_OPTIONAL_FUNC;
6352 priv->EEPROMUsbEndPointNumber = rtl8192SU_UsbOptionToEndPointNumber((priv->EEPROMUsbOption&EEPROM_EP_NUMBER)>>3);
6354 RT_TRACE(COMP_INIT, "USB Option = %#x\n", priv->EEPROMUsbOption);
6355 RT_TRACE(COMP_INIT, "EndPoint Number = %#x\n", priv->EEPROMUsbEndPointNumber);
6357 #ifdef TO_DO_LIST
6359 // Decide CustomerID according to VID/DID or EEPROM
6361 switch(pHalData->EEPROMCustomerID)
6363 case EEPROM_CID_ALPHA:
6364 pMgntInfo->CustomerID = RT_CID_819x_ALPHA;
6365 break;
6367 case EEPROM_CID_CAMEO:
6368 pMgntInfo->CustomerID = RT_CID_819x_CAMEO;
6369 break;
6371 case EEPROM_CID_SITECOM:
6372 pMgntInfo->CustomerID = RT_CID_819x_Sitecom;
6373 RT_TRACE(COMP_INIT, DBG_LOUD, ("CustomerID = 0x%4x\n", pMgntInfo->CustomerID));
6375 break;
6377 case EEPROM_CID_WHQL:
6378 Adapter->bInHctTest = TRUE;
6380 pMgntInfo->bSupportTurboMode = FALSE;
6381 pMgntInfo->bAutoTurboBy8186 = FALSE;
6383 pMgntInfo->PowerSaveControl.bInactivePs = FALSE;
6384 pMgntInfo->PowerSaveControl.bIPSModeBackup = FALSE;
6385 pMgntInfo->PowerSaveControl.bLeisurePs = FALSE;
6386 pMgntInfo->keepAliveLevel = 0;
6387 break;
6389 default:
6390 pMgntInfo->CustomerID = RT_CID_DEFAULT;
6391 break;
6396 // Led mode
6398 switch(pMgntInfo->CustomerID)
6400 case RT_CID_DEFAULT:
6401 case RT_CID_819x_ALPHA:
6402 pHalData->LedStrategy = SW_LED_MODE1;
6403 pHalData->bRegUseLed = TRUE;
6404 pHalData->SwLed1.bLedOn = TRUE;
6405 break;
6406 case RT_CID_819x_CAMEO:
6407 pHalData->LedStrategy = SW_LED_MODE1;
6408 pHalData->bRegUseLed = TRUE;
6409 break;
6411 case RT_CID_819x_Sitecom:
6412 pHalData->LedStrategy = SW_LED_MODE2;
6413 pHalData->bRegUseLed = TRUE;
6414 break;
6416 default:
6417 pHalData->LedStrategy = SW_LED_MODE0;
6418 break;
6420 #endif
6422 // Read USB PHY parameters.
6423 for(i=0; i<5; i++)
6424 priv->EEPROMUsbPhyParam[i] = *(u8 *)&hwinfo[EEPROM_USB_PHY_PARA1+i];
6426 //RT_PRINT_DATA(COMP_EFUSE, DBG_LOUD, ("USB PHY Param: \n"), pHalData->EEPROMUsbPhyParam, 5);
6429 //Read Permanent MAC address
6430 for(i=0; i<6; i++)
6431 dev->dev_addr[i] = *(u8 *)&hwinfo[EEPROM_NODE_ADDRESS_BYTE_0+i];
6433 //NicIFSetMacAddress(Adapter, Adapter->PermanentAddress);
6434 write_nic_dword(dev, IDR0, ((u32*)dev->dev_addr)[0]);
6435 write_nic_word(dev, IDR4, ((u16*)(dev->dev_addr + 4))[0]);
6437 RT_TRACE(COMP_INIT, "ReadAdapterInfo8192SEFuse(), Permanent Address = %02x-%02x-%02x-%02x-%02x-%02x\n",
6438 dev->dev_addr[0], dev->dev_addr[1],
6439 dev->dev_addr[2], dev->dev_addr[3],
6440 dev->dev_addr[4], dev->dev_addr[5]);
6443 // Get CustomerID(Boad Type)
6444 // i.e., 0x0: RTL8188SU, 0x1: RTL8191SU, 0x2: RTL8192SU, 0x3: RTL8191GU.
6445 // Others: Reserved. Default is 0x2: RTL8192SU.
6447 //if(!priv->AutoloadFailFlag)
6449 priv->EEPROMBoardType = *(u8 *)&hwinfo[EEPROM_BoardType];
6450 priv->rf_type = rtl8192SU_BoardTypeToRFtype(dev, priv->EEPROMBoardType);
6452 //else
6454 // priv->EEPROMBoardType = EEPROM_Default_BoardType;
6455 // priv->rf_type = RF_1T2R;
6458 #if (defined (RTL8192SU_FPGA_2MAC_VERIFICATION)||defined (RTL8192SU_ASIC_VERIFICATION))
6459 priv->rf_chip = RF_6052;
6460 #else
6461 priv->rf_chip = RF_8256;
6462 #endif
6464 priv->rf_chip = RF_6052;//lzm test
6465 RT_TRACE(COMP_INIT, "BoardType = 0x%2x\n", priv->EEPROMBoardType);
6466 RT_TRACE(COMP_INIT, "RF_Type = 0x%2x\n", priv->rf_type);
6469 // Read antenna tx power offset of B/C/D to A from EEPROM
6470 // and read ThermalMeter from EEPROM
6472 //if(!priv->AutoloadFailFlag)
6474 priv->EEPROMTxPowerDiff = *(u8 *)&hwinfo[EEPROM_PwDiff];
6475 priv->EEPROMThermalMeter = *(u8 *)&hwinfo[EEPROM_ThermalMeter];
6477 //else
6479 // priv->EEPROMTxPowerDiff = EEPROM_Default_PwDiff;
6480 // priv->EEPROMThermalMeter = EEPROM_Default_ThermalMeter;
6483 RT_TRACE(COMP_INIT, "PwDiff = %#x\n", priv->EEPROMTxPowerDiff);
6484 RT_TRACE(COMP_INIT, "ThermalMeter = %#x\n", priv->EEPROMThermalMeter);
6487 // Read Tx Power gain offset of legacy OFDM to HT rate.
6488 // Read CrystalCap from EEPROM
6490 //if(!priv->AutoloadFailFlag)
6492 priv->EEPROMCrystalCap = *(u8 *)&hwinfo[EEPROM_CrystalCap];
6494 //else
6496 // priv->EEPROMCrystalCap = EEPROM_Default_CrystalCap;
6499 RT_TRACE(COMP_INIT, "CrystalCap = %#x\n", priv->EEPROMCrystalCap);
6502 // Get Tx Power Base.
6504 //if(!priv->AutoloadFailFlag)
6506 priv->EEPROMTxPwrBase = *(u8 *)&hwinfo[EEPROM_TxPowerBase];
6508 //else
6510 // priv->EEPROMTxPwrBase = EEPROM_Default_TxPowerBase;
6513 RT_TRACE(COMP_INIT, "TxPwrBase = %#x\n", priv->EEPROMTxPwrBase);
6517 // Get TSSI value for each path.
6519 //if(!priv->AutoloadFailFlag)
6521 priv->EEPROMTSSI_A = *(u8 *)&hwinfo[EEPROM_TSSI_A];
6522 priv->EEPROMTSSI_B = *(u8 *)&hwinfo[EEPROM_TSSI_B];
6524 //else
6525 //{ // Default setting for Empty EEPROM
6526 // priv->EEPROMTSSI_A = EEPROM_Default_TSSI;
6527 // priv->EEPROMTSSI_B = EEPROM_Default_TSSI;
6530 RT_TRACE(COMP_INIT, "TSSI_A = %#x, TSSI_B = %#x\n", priv->EEPROMTSSI_A, priv->EEPROMTSSI_B);
6533 // Get Tx Power tracking mode.
6535 //if(!priv->AutoloadFailFlag)
6537 priv->EEPROMTxPwrTkMode = *(u8 *)&hwinfo[EEPROM_TxPwTkMode];
6540 RT_TRACE(COMP_INIT, "TxPwrTkMod = %#x\n", priv->EEPROMTxPwrTkMode);
6543 #ifdef EEPROM_OLD_FORMAT_SUPPORT
6546 // <Roger_Notes> The following settings are EFUSE version dependence.
6547 // So we need to adjust reading offset.
6548 // 2008.11.22.
6552 // Get HT 2T Path A and B Power Index.
6554 //if(!priv->AutoloadFailFlag)
6556 for(i=0; i<6; i++)
6558 priv->EEPROMHT2T_TxPwr[i] = *(u8 *)&hwinfo[EEPROM_HT2T_CH1_A+i];
6562 //RT_PRINT_DATA(COMP_EFUSE, "HT2T TxPwr: \n"), pHalData->EEPROMHT2T_TxPwr, 6);
6565 // Get CCK and OFDM Tx Power Index.
6567 //if(!priv->AutoloadFailFlag)
6569 for(i=0; i<14; i++)
6571 priv->EEPROMTxPowerLevelCCK24G[i] = *(u8 *)&hwinfo[EEPROM_TxPwIndex_CCK_24G+i];
6572 priv->EEPROMTxPowerLevelOFDM24G[i] = *(u8 *)&hwinfo[EEPROM_TxPwIndex_OFDM_24G+i];
6576 //RT_PRINT_DATA(COMP_EFUSE, DBG_LOUD, ("CCK 2.4G TxPwr: \n"), pHalData->EEPROMTxPowerLevelCCK24G, 14);
6577 //RT_PRINT_DATA(COMP_EFUSE, DBG_LOUD, ("OFDM 2.4G TxPwr: \n"), pHalData->EEPROMTxPowerLevelOFDM24G, 14);
6580 // Update HAL variables.
6582 memcpy( priv->TxPowerLevelOFDM24G, priv->EEPROMTxPowerLevelOFDM24G, 14);
6583 memcpy( priv->TxPowerLevelCCK, priv->EEPROMTxPowerLevelCCK24G, 14);
6584 //RT_PRINT_DATA(COMP_EFUSE, DBG_LOUD, ("HAL CCK 2.4G TxPwr: \n"), pHalData->TxPowerLevelCCK, 14);
6585 //RT_PRINT_DATA(COMP_EFUSE, DBG_LOUD, ("HAL OFDM 2.4G TxPwr: \n"), pHalData->TxPowerLevelOFDM24G, 14);
6588 #else // Support new version of EFUSE content, 2008.11.22.
6591 // Buffer TxPwIdx(i.e., from offset 0x55~0x66, total 18Bytes)
6592 // Update CCK, OFDM (1T/2T)Tx Power Index from above buffer.
6596 // Get Tx Power Level by Channel
6598 //if(!priv->AutoloadFailFlag)
6600 // Read Tx power of Channel 1 ~ 14 from EFUSE.
6601 // 92S suupport RF A & B
6602 for (rf_path = 0; rf_path < 2; rf_path++)
6604 for (i = 0; i < 3; i++)
6606 // Read CCK RF A & B Tx power
6607 priv->RfCckChnlAreaTxPwr[rf_path][i] =
6608 hwinfo[EEPROM_TxPwIndex+rf_path*3+i];
6610 // Read OFDM RF A & B Tx power for 1T
6611 priv->RfOfdmChnlAreaTxPwr1T[rf_path][i] =
6612 hwinfo[EEPROM_TxPwIndex+6+rf_path*3+i];
6614 // Read OFDM RF A & B Tx power for 2T
6615 priv->RfOfdmChnlAreaTxPwr2T[rf_path][i] =
6616 hwinfo[EEPROM_TxPwIndex+12+rf_path*3+i];
6622 // Update Tx Power HAL variables.
6624 for (rf_path = 0; rf_path < 2; rf_path++)
6626 for (i = 0; i < 3; i++)
6628 RT_TRACE((COMP_INIT), "CCK RF-%d CHan_Area-%d = 0x%x\n", rf_path, i,
6629 priv->RfCckChnlAreaTxPwr[rf_path][i]);
6630 RT_TRACE((COMP_INIT), "OFDM-1T RF-%d CHan_Area-%d = 0x%x\n", rf_path, i,
6631 priv->RfOfdmChnlAreaTxPwr1T[rf_path][i]);
6632 RT_TRACE((COMP_INIT), "OFDM-2T RF-%d CHan_Area-%d = 0x%x\n", rf_path, i, priv->RfOfdmChnlAreaTxPwr2T[rf_path][i]);
6635 // Assign dedicated channel tx power
6636 for(i=0; i<14; i++) // channel 1~3 use the same Tx Power Level.
6638 if (i < 3) // Cjanel 1-3
6639 index = 0;
6640 else if (i < 9) // Channel 4-9
6641 index = 1;
6642 else // Channel 10-14
6643 index = 2;
6645 // Record A & B CCK /OFDM - 1T/2T Channel area tx power
6646 priv->RfTxPwrLevelCck[rf_path][i] =
6647 priv->RfCckChnlAreaTxPwr[rf_path][index];
6648 priv->RfTxPwrLevelOfdm1T[rf_path][i] =
6649 priv->RfOfdmChnlAreaTxPwr1T[rf_path][index];
6650 priv->RfTxPwrLevelOfdm2T[rf_path][i] =
6651 priv->RfOfdmChnlAreaTxPwr2T[rf_path][index];
6652 if (rf_path == 0)
6654 priv->TxPowerLevelOFDM24G[i] = priv->RfTxPwrLevelOfdm1T[rf_path][i] ;
6655 priv->TxPowerLevelCCK[i] = priv->RfTxPwrLevelCck[rf_path][i];
6659 for(i=0; i<14; i++)
6661 RT_TRACE((COMP_INIT),
6662 "Rf-%d TxPwr CH-%d CCK OFDM_1T OFDM_2T= 0x%x/0x%x/0x%x\n",
6663 rf_path, i, priv->RfTxPwrLevelCck[rf_path][i],
6664 priv->RfTxPwrLevelOfdm1T[rf_path][i] ,
6665 priv->RfTxPwrLevelOfdm2T[rf_path][i] );
6671 // 2009/02/09 Cosa add for new EEPROM format
6673 for(i=0; i<14; i++) // channel 1~3 use the same Tx Power Level.
6675 // Read tx power difference between HT OFDM 20/40 MHZ
6676 if (i < 3) // Cjanel 1-3
6677 index = 0;
6678 else if (i < 9) // Channel 4-9
6679 index = 1;
6680 else // Channel 10-14
6681 index = 2;
6683 tempval = (*(u8 *)&hwinfo[EEPROM_TX_PWR_HT20_DIFF+index])&0xff;
6684 priv->TxPwrHt20Diff[RF90_PATH_A][i] = (tempval&0xF);
6685 priv->TxPwrHt20Diff[RF90_PATH_B][i] = ((tempval>>4)&0xF);
6687 // Read OFDM<->HT tx power diff
6688 if (i < 3) // Cjanel 1-3
6689 tempval = (*(u8 *)&hwinfo[EEPROM_TX_PWR_OFDM_DIFF])&0xff;
6690 else if (i < 9) // Channel 4-9
6691 tempval = (*(u8 *)&hwinfo[EEPROM_PwDiff])&0xff;
6692 else // Channel 10-14
6693 tempval = (*(u8 *)&hwinfo[EEPROM_TX_PWR_OFDM_DIFF+1])&0xff;
6695 //cosa tempval = (*(u1Byte *)&hwinfo[EEPROM_TX_PWR_OFDM_DIFF+index])&0xff;
6696 priv->TxPwrLegacyHtDiff[RF90_PATH_A][i] = (tempval&0xF);
6697 priv->TxPwrLegacyHtDiff[RF90_PATH_B][i] = ((tempval>>4)&0xF);
6700 // Read Band Edge tx power offset and check if user enable the ability
6702 // HT 40 band edge channel
6703 tempval = (*(u8 *)&hwinfo[EEPROM_TX_PWR_BAND_EDGE])&0xff;
6704 priv->TxPwrbandEdgeHt40[RF90_PATH_A][0] = (tempval&0xF); // Band edge low channel
6705 priv->TxPwrbandEdgeHt40[RF90_PATH_A][1] = ((tempval>>4)&0xF); // Band edge high channel
6706 tempval = (*(u8 *)&hwinfo[EEPROM_TX_PWR_BAND_EDGE+1])&0xff;
6707 priv->TxPwrbandEdgeHt40[RF90_PATH_B][0] = (tempval&0xF); // Band edge low channel
6708 priv->TxPwrbandEdgeHt40[RF90_PATH_B][1] = ((tempval>>4)&0xF); // Band edge high channel
6709 // HT 20 band edge channel
6710 tempval = (*(u8 *)&hwinfo[EEPROM_TX_PWR_BAND_EDGE+2])&0xff;
6711 priv->TxPwrbandEdgeHt20[RF90_PATH_A][0] = (tempval&0xF); // Band edge low channel
6712 priv->TxPwrbandEdgeHt20[RF90_PATH_A][1] = ((tempval>>4)&0xF); // Band edge high channel
6713 tempval = (*(u8 *)&hwinfo[EEPROM_TX_PWR_BAND_EDGE+3])&0xff;
6714 priv->TxPwrbandEdgeHt20[RF90_PATH_B][0] = (tempval&0xF); // Band edge low channel
6715 priv->TxPwrbandEdgeHt20[RF90_PATH_B][1] = ((tempval>>4)&0xF); // Band edge high channel
6716 // OFDM band edge channel
6717 tempval = (*(u8 *)&hwinfo[EEPROM_TX_PWR_BAND_EDGE+4])&0xff;
6718 priv->TxPwrbandEdgeLegacyOfdm[RF90_PATH_A][0] = (tempval&0xF); // Band edge low channel
6719 priv->TxPwrbandEdgeLegacyOfdm[RF90_PATH_A][1] = ((tempval>>4)&0xF); // Band edge high channel
6720 tempval = (*(u8 *)&hwinfo[EEPROM_TX_PWR_BAND_EDGE+5])&0xff;
6721 priv->TxPwrbandEdgeLegacyOfdm[RF90_PATH_B][0] = (tempval&0xF); // Band edge low channel
6722 priv->TxPwrbandEdgeLegacyOfdm[RF90_PATH_B][1] = ((tempval>>4)&0xF); // Band edge high channel
6724 priv->TxPwrbandEdgeFlag = (*(u8 *)&hwinfo[TX_PWR_BAND_EDGE_CHK]);
6727 for(i=0; i<14; i++)
6728 RT_TRACE(COMP_INIT, "RF-A Ht20 to HT40 Diff[%d] = 0x%x\n", i, priv->TxPwrHt20Diff[RF90_PATH_A][i]);
6729 for(i=0; i<14; i++)
6730 RT_TRACE(COMP_INIT, "RF-A Legacy to Ht40 Diff[%d] = 0x%x\n", i, priv->TxPwrLegacyHtDiff[RF90_PATH_A][i]);
6731 for(i=0; i<14; i++)
6732 RT_TRACE(COMP_INIT, "RF-B Ht20 to HT40 Diff[%d] = 0x%x\n", i, priv->TxPwrHt20Diff[RF90_PATH_B][i]);
6733 for(i=0; i<14; i++)
6734 RT_TRACE(COMP_INIT, "RF-B Legacy to HT40 Diff[%d] = 0x%x\n", i, priv->TxPwrLegacyHtDiff[RF90_PATH_B][i]);
6735 RT_TRACE(COMP_INIT, "RF-A HT40 band-edge low/high power diff = 0x%x/0x%x\n",
6736 priv->TxPwrbandEdgeHt40[RF90_PATH_A][0],
6737 priv->TxPwrbandEdgeHt40[RF90_PATH_A][1]);
6738 RT_TRACE((COMP_INIT&COMP_DBG), "RF-B HT40 band-edge low/high power diff = 0x%x/0x%x\n",
6739 priv->TxPwrbandEdgeHt40[RF90_PATH_B][0],
6740 priv->TxPwrbandEdgeHt40[RF90_PATH_B][1]);
6742 RT_TRACE((COMP_INIT&COMP_DBG), "RF-A HT20 band-edge low/high power diff = 0x%x/0x%x\n",
6743 priv->TxPwrbandEdgeHt20[RF90_PATH_A][0],
6744 priv->TxPwrbandEdgeHt20[RF90_PATH_A][1]);
6745 RT_TRACE((COMP_INIT&COMP_DBG), "RF-B HT20 band-edge low/high power diff = 0x%x/0x%x\n",
6746 priv->TxPwrbandEdgeHt20[RF90_PATH_B][0],
6747 priv->TxPwrbandEdgeHt20[RF90_PATH_B][1]);
6749 RT_TRACE((COMP_INIT&COMP_DBG), "RF-A OFDM band-edge low/high power diff = 0x%x/0x%x\n",
6750 priv->TxPwrbandEdgeLegacyOfdm[RF90_PATH_A][0],
6751 priv->TxPwrbandEdgeLegacyOfdm[RF90_PATH_A][1]);
6752 RT_TRACE((COMP_INIT&COMP_DBG), "RF-B OFDM band-edge low/high power diff = 0x%x/0x%x\n",
6753 priv->TxPwrbandEdgeLegacyOfdm[RF90_PATH_B][0],
6754 priv->TxPwrbandEdgeLegacyOfdm[RF90_PATH_B][1]);
6755 RT_TRACE((COMP_INIT&COMP_DBG), "Band-edge enable flag = %d\n", priv->TxPwrbandEdgeFlag);
6756 #endif
6759 // Update remained HAL variables.
6761 priv->TSSI_13dBm = priv->EEPROMThermalMeter *100;
6762 priv->LegacyHTTxPowerDiff = priv->EEPROMTxPowerDiff;
6763 priv->TxPowerDiff = priv->EEPROMTxPowerDiff;
6764 //priv->AntennaTxPwDiff[0] = (priv->EEPROMTxPowerDiff & 0xf);// Antenna B gain offset to antenna A, bit[3:0]
6765 //priv->AntennaTxPwDiff[1] = ((priv->EEPROMTxPowerDiff & 0xf0)>>4);// Antenna C gain offset to antenna A, bit[7:4]
6766 priv->CrystalCap = priv->EEPROMCrystalCap; // CrystalCap, bit[15:12]
6767 priv->ThermalMeter[0] = (priv->EEPROMThermalMeter&0x1f);// ThermalMeter, bit0~3 for RFIC1, bit4~7 for RFIC2
6768 priv->LedStrategy = SW_LED_MODE0;
6770 init_rate_adaptive(dev);
6772 RT_TRACE(COMP_INIT, "<==== ReadAdapterInfo8192SUsb\n");
6774 //return RT_STATUS_SUCCESS;
6779 // Description:
6780 // Read HW adapter information by E-Fuse or EEPROM according CR9346 reported.
6782 // Assumption:
6783 // 1. CR9346 regiser has verified.
6784 // 2. PASSIVE_LEVEL (USB interface)
6786 // Created by Roger, 2008.10.21.
6788 static void rtl8192SU_read_eeprom_info(struct net_device *dev)
6790 struct r8192_priv *priv = ieee80211_priv(dev);
6791 u8 tmpU1b;
6793 RT_TRACE(COMP_INIT, "====> ReadAdapterInfo8192SUsb\n");
6795 // Retrieve Chip version.
6796 priv->card_8192_version = (VERSION_8192S)((read_nic_dword(dev, PMC_FSM)>>16)&0xF);
6797 RT_TRACE(COMP_INIT, "Chip Version ID: 0x%2x\n", priv->card_8192_version);
6799 tmpU1b = read_nic_byte(dev, EPROM_CMD);//CR9346
6801 // To check system boot selection.
6802 if (tmpU1b & CmdEERPOMSEL)
6804 RT_TRACE(COMP_INIT, "Boot from EEPROM\n");
6805 priv->EepromOrEfuse = TRUE;
6807 else
6809 RT_TRACE(COMP_INIT, "Boot from EFUSE\n");
6810 priv->EepromOrEfuse = FALSE;
6813 // To check autoload success or not.
6814 if (tmpU1b & CmdEEPROM_En)
6816 RT_TRACE(COMP_INIT, "Autoload OK!!\n");
6817 priv->AutoloadFailFlag=FALSE;
6818 rtl8192SU_ReadAdapterInfo8192SUsb(dev);//eeprom or e-fuse
6820 else
6821 { // Auto load fail.
6822 RT_TRACE(COMP_INIT, "AutoLoad Fail reported from CR9346!!\n");
6823 priv->AutoloadFailFlag=TRUE;
6824 rtl8192SU_ConfigAdapterInfo8192SForAutoLoadFail(dev);
6826 //if (IS_BOOT_FROM_EFUSE(Adapter))
6827 if(!priv->EepromOrEfuse)
6829 RT_TRACE(COMP_INIT, "Update shadow map for EFuse future use!!\n");
6830 EFUSE_ShadowMapUpdate(dev);
6833 #ifdef TO_DO_LIST
6834 if((priv->RegChannelPlan >= RT_CHANNEL_DOMAIN_MAX) || (pHalData->EEPROMChannelPlan & EEPROM_CHANNEL_PLAN_BY_HW_MASK))
6836 pMgntInfo->ChannelPlan = HalMapChannelPlan8192S(Adapter, (pHalData->EEPROMChannelPlan & (~(EEPROM_CHANNEL_PLAN_BY_HW_MASK))));
6837 pMgntInfo->bChnlPlanFromHW = (pHalData->EEPROMChannelPlan & EEPROM_CHANNEL_PLAN_BY_HW_MASK) ? TRUE : FALSE; // User cannot change channel plan.
6839 else
6841 pMgntInfo->ChannelPlan = (RT_CHANNEL_DOMAIN)pMgntInfo->RegChannelPlan;
6844 switch(pMgntInfo->ChannelPlan)
6846 case RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN:
6848 PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(pMgntInfo);
6850 pDot11dInfo->bEnabled = TRUE;
6852 RT_TRACE(COMP_INIT, DBG_LOUD, ("ReadAdapterInfo8187(): Enable dot11d when RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN!\n"));
6853 break;
6856 RT_TRACE(COMP_INIT, DBG_LOUD, ("RegChannelPlan(%d) EEPROMChannelPlan(%d)", pMgntInfo->RegChannelPlan, pHalData->EEPROMChannelPlan));
6857 RT_TRACE(COMP_INIT, DBG_LOUD, ("ChannelPlan = %d\n" , pMgntInfo->ChannelPlan));
6859 RT_TRACE(COMP_INIT, DBG_LOUD, ("<==== ReadAdapterInfo8192S\n"));
6860 #endif
6862 RT_TRACE(COMP_INIT, "<==== ReadAdapterInfo8192SUsb\n");
6864 //return RT_STATUS_SUCCESS;
6866 #else
6867 static void rtl8192_read_eeprom_info(struct net_device* dev)
6869 u16 wEPROM_ID = 0;
6870 u8 bMac_Tmp_Addr[6] = {0x00, 0xe0, 0x4c, 0x00, 0x00, 0x02};
6871 u8 bLoad_From_EEPOM = false;
6872 struct r8192_priv *priv = ieee80211_priv(dev);
6873 u16 tmpValue = 0;
6874 RT_TRACE(COMP_EPROM, "===========>%s()\n", __FUNCTION__);
6875 wEPROM_ID = eprom_read(dev, 0); //first read EEPROM ID out;
6876 RT_TRACE(COMP_EPROM, "EEPROM ID is 0x%x\n", wEPROM_ID);
6878 if (wEPROM_ID != RTL8190_EEPROM_ID)
6880 RT_TRACE(COMP_ERR, "EEPROM ID is invalid(is 0x%x(should be 0x%x)\n", wEPROM_ID, RTL8190_EEPROM_ID);
6882 else
6883 bLoad_From_EEPOM = true;
6885 if (bLoad_From_EEPOM)
6887 tmpValue = eprom_read(dev, (EEPROM_VID>>1));
6888 priv->eeprom_vid = endian_swap(&tmpValue);
6889 priv->eeprom_pid = eprom_read(dev, (EEPROM_PID>>1));
6890 tmpValue = eprom_read(dev, (EEPROM_ChannelPlan>>1));
6891 priv->eeprom_ChannelPlan =((tmpValue&0xff00)>>8);
6892 priv->btxpowerdata_readfromEEPORM = true;
6893 priv->eeprom_CustomerID = eprom_read(dev, (EEPROM_Customer_ID>>1)) >>8;
6895 else
6897 priv->eeprom_vid = 0;
6898 priv->eeprom_pid = 0;
6899 priv->card_8192_version = VERSION_819xU_B;
6900 priv->eeprom_ChannelPlan = 0;
6901 priv->eeprom_CustomerID = 0;
6903 RT_TRACE(COMP_EPROM, "vid:0x%4x, pid:0x%4x, CustomID:0x%2x, ChanPlan:0x%x\n", priv->eeprom_vid, priv->eeprom_pid, priv->eeprom_CustomerID, priv->eeprom_ChannelPlan);
6904 //set channelplan from eeprom
6905 priv->ChannelPlan = priv->eeprom_ChannelPlan;
6906 if (bLoad_From_EEPOM)
6908 int i;
6909 for (i=0; i<6; i+=2)
6911 u16 tmp = 0;
6912 tmp = eprom_read(dev, (u16)((EEPROM_NODE_ADDRESS_BYTE_0 + i)>>1));
6913 *(u16*)(&dev->dev_addr[i]) = tmp;
6916 else
6918 memcpy(dev->dev_addr, bMac_Tmp_Addr, 6);
6919 //should I set IDR0 here?
6921 RT_TRACE(COMP_EPROM, "MAC addr:"MAC_FMT"\n", MAC_ARG(dev->dev_addr));
6922 priv->rf_type = RTL819X_DEFAULT_RF_TYPE; //default 1T2R
6923 priv->rf_chip = RF_8256;
6925 if (priv->card_8192_version == (u8)VERSION_819xU_A)
6927 //read Tx power gain offset of legacy OFDM to HT rate
6928 if (bLoad_From_EEPOM)
6929 priv->EEPROMTxPowerDiff = (eprom_read(dev, (EEPROM_TxPowerDiff>>1))&0xff00) >> 8;
6930 else
6931 priv->EEPROMTxPowerDiff = EEPROM_Default_TxPower;
6932 RT_TRACE(COMP_EPROM, "TxPowerDiff:%d\n", priv->EEPROMTxPowerDiff);
6933 //read ThermalMeter from EEPROM
6934 if (bLoad_From_EEPOM)
6935 priv->EEPROMThermalMeter = (u8)(eprom_read(dev, (EEPROM_ThermalMeter>>1))&0x00ff);
6936 else
6937 priv->EEPROMThermalMeter = EEPROM_Default_ThermalMeter;
6938 RT_TRACE(COMP_EPROM, "ThermalMeter:%d\n", priv->EEPROMThermalMeter);
6939 //vivi, for tx power track
6940 priv->TSSI_13dBm = priv->EEPROMThermalMeter *100;
6941 //read antenna tx power offset of B/C/D to A from EEPROM
6942 if (bLoad_From_EEPOM)
6943 priv->EEPROMPwDiff = (eprom_read(dev, (EEPROM_PwDiff>>1))&0x0f00)>>8;
6944 else
6945 priv->EEPROMPwDiff = EEPROM_Default_PwDiff;
6946 RT_TRACE(COMP_EPROM, "TxPwDiff:%d\n", priv->EEPROMPwDiff);
6947 // Read CrystalCap from EEPROM
6948 if (bLoad_From_EEPOM)
6949 priv->EEPROMCrystalCap = (eprom_read(dev, (EEPROM_CrystalCap>>1))&0x0f);
6950 else
6951 priv->EEPROMCrystalCap = EEPROM_Default_CrystalCap;
6952 RT_TRACE(COMP_EPROM, "CrystalCap = %d\n", priv->EEPROMCrystalCap);
6953 //get per-channel Tx power level
6954 if (bLoad_From_EEPOM)
6955 priv->EEPROM_Def_Ver = (eprom_read(dev, (EEPROM_TxPwIndex_Ver>>1))&0xff00)>>8;
6956 else
6957 priv->EEPROM_Def_Ver = 1;
6958 RT_TRACE(COMP_EPROM, "EEPROM_DEF_VER:%d\n", priv->EEPROM_Def_Ver);
6959 if (priv->EEPROM_Def_Ver == 0) //old eeprom definition
6961 int i;
6962 if (bLoad_From_EEPOM)
6963 priv->EEPROMTxPowerLevelCCK = (eprom_read(dev, (EEPROM_TxPwIndex_CCK>>1))&0xff) >> 8;
6964 else
6965 priv->EEPROMTxPowerLevelCCK = 0x10;
6966 RT_TRACE(COMP_EPROM, "CCK Tx Power Levl: 0x%02x\n", priv->EEPROMTxPowerLevelCCK);
6967 for (i=0; i<3; i++)
6969 if (bLoad_From_EEPOM)
6971 tmpValue = eprom_read(dev, (EEPROM_TxPwIndex_OFDM_24G+i)>>1);
6972 if (((EEPROM_TxPwIndex_OFDM_24G+i) % 2) == 0)
6973 tmpValue = tmpValue & 0x00ff;
6974 else
6975 tmpValue = (tmpValue & 0xff00) >> 8;
6977 else
6978 tmpValue = 0x10;
6979 priv->EEPROMTxPowerLevelOFDM24G[i] = (u8) tmpValue;
6980 RT_TRACE(COMP_EPROM, "OFDM 2.4G Tx Power Level, Index %d = 0x%02x\n", i, priv->EEPROMTxPowerLevelCCK);
6982 }//end if EEPROM_DEF_VER == 0
6983 else if (priv->EEPROM_Def_Ver == 1)
6985 if (bLoad_From_EEPOM)
6987 tmpValue = eprom_read(dev, (EEPROM_TxPwIndex_CCK_V1>>1));
6988 tmpValue = (tmpValue & 0xff00) >> 8;
6990 else
6991 tmpValue = 0x10;
6992 priv->EEPROMTxPowerLevelCCK_V1[0] = (u8)tmpValue;
6994 if (bLoad_From_EEPOM)
6995 tmpValue = eprom_read(dev, (EEPROM_TxPwIndex_CCK_V1 + 2)>>1);
6996 else
6997 tmpValue = 0x1010;
6998 *((u16*)(&priv->EEPROMTxPowerLevelCCK_V1[1])) = tmpValue;
6999 if (bLoad_From_EEPOM)
7000 tmpValue = eprom_read(dev, (EEPROM_TxPwIndex_OFDM_24G_V1>>1));
7001 else
7002 tmpValue = 0x1010;
7003 *((u16*)(&priv->EEPROMTxPowerLevelOFDM24G[0])) = tmpValue;
7004 if (bLoad_From_EEPOM)
7005 tmpValue = eprom_read(dev, (EEPROM_TxPwIndex_OFDM_24G_V1+2)>>1);
7006 else
7007 tmpValue = 0x10;
7008 priv->EEPROMTxPowerLevelOFDM24G[2] = (u8)tmpValue;
7009 }//endif EEPROM_Def_Ver == 1
7011 //update HAL variables
7014 int i;
7015 for (i=0; i<14; i++)
7017 if (i<=3)
7018 priv->TxPowerLevelOFDM24G[i] = priv->EEPROMTxPowerLevelOFDM24G[0];
7019 else if (i>=4 && i<=9)
7020 priv->TxPowerLevelOFDM24G[i] = priv->EEPROMTxPowerLevelOFDM24G[1];
7021 else
7022 priv->TxPowerLevelOFDM24G[i] = priv->EEPROMTxPowerLevelOFDM24G[2];
7025 for (i=0; i<14; i++)
7027 if (priv->EEPROM_Def_Ver == 0)
7029 if (i<=3)
7030 priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelOFDM24G[0] + (priv->EEPROMTxPowerLevelCCK - priv->EEPROMTxPowerLevelOFDM24G[1]);
7031 else if (i>=4 && i<=9)
7032 priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelCCK;
7033 else
7034 priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelOFDM24G[2] + (priv->EEPROMTxPowerLevelCCK - priv->EEPROMTxPowerLevelOFDM24G[1]);
7036 else if (priv->EEPROM_Def_Ver == 1)
7038 if (i<=3)
7039 priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelCCK_V1[0];
7040 else if (i>=4 && i<=9)
7041 priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelCCK_V1[1];
7042 else
7043 priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelCCK_V1[2];
7046 }//end update HAL variables
7047 priv->TxPowerDiff = priv->EEPROMPwDiff;
7048 // Antenna B gain offset to antenna A, bit0~3
7049 priv->AntennaTxPwDiff[0] = (priv->EEPROMTxPowerDiff & 0xf);
7050 // Antenna C gain offset to antenna A, bit4~7
7051 priv->AntennaTxPwDiff[1] = ((priv->EEPROMTxPowerDiff & 0xf0)>>4);
7052 // CrystalCap, bit12~15
7053 priv->CrystalCap = priv->EEPROMCrystalCap;
7054 // ThermalMeter, bit0~3 for RFIC1, bit4~7 for RFIC2
7055 // 92U does not enable TX power tracking.
7056 priv->ThermalMeter[0] = priv->EEPROMThermalMeter;
7057 }//end if VersionID == VERSION_819xU_A
7059 //added by vivi, for dlink led, 20080416
7060 switch(priv->eeprom_CustomerID)
7062 case EEPROM_CID_RUNTOP:
7063 priv->CustomerID = RT_CID_819x_RUNTOP;
7064 break;
7066 case EEPROM_CID_DLINK:
7067 priv->CustomerID = RT_CID_DLINK;
7068 break;
7070 default:
7071 priv->CustomerID = RT_CID_DEFAULT;
7072 break;
7076 switch(priv->CustomerID)
7078 case RT_CID_819x_RUNTOP:
7079 priv->LedStrategy = SW_LED_MODE2;
7080 break;
7082 case RT_CID_DLINK:
7083 priv->LedStrategy = SW_LED_MODE4;
7084 break;
7086 default:
7087 priv->LedStrategy = SW_LED_MODE0;
7088 break;
7093 if(priv->rf_type == RF_1T2R)
7095 RT_TRACE(COMP_EPROM, "\n1T2R config\n");
7097 else
7099 RT_TRACE(COMP_EPROM, "\n2T4R config\n");
7102 // 2008/01/16 MH We can only know RF type in the function. So we have to init
7103 // DIG RATR table again.
7104 init_rate_adaptive(dev);
7105 //we need init DIG RATR table here again.
7107 RT_TRACE(COMP_EPROM, "<===========%s()\n", __FUNCTION__);
7108 return;
7110 #endif
7112 short rtl8192_get_channel_map(struct net_device * dev)
7114 struct r8192_priv *priv = ieee80211_priv(dev);
7115 #ifdef ENABLE_DOT11D
7116 if(priv->ChannelPlan > COUNTRY_CODE_GLOBAL_DOMAIN){
7117 printk("rtl8180_init:Error channel plan! Set to default.\n");
7118 priv->ChannelPlan= 0;
7120 RT_TRACE(COMP_INIT, "Channel plan is %d\n",priv->ChannelPlan);
7122 rtl819x_set_channel_map(priv->ChannelPlan, priv);
7123 #else
7124 int ch,i;
7125 //Set Default Channel Plan
7126 if(!channels){
7127 DMESG("No channels, aborting");
7128 return -1;
7130 ch=channels;
7131 priv->ChannelPlan= 0;//hikaru
7132 // set channels 1..14 allowed in given locale
7133 for (i=1; i<=14; i++) {
7134 (priv->ieee80211->channel_map)[i] = (u8)(ch & 0x01);
7135 ch >>= 1;
7137 #endif
7138 return 0;
7141 short rtl8192_init(struct net_device *dev)
7144 struct r8192_priv *priv = ieee80211_priv(dev);
7146 #ifndef RTL8192SU
7147 memset(&(priv->stats),0,sizeof(struct Stats));
7148 memset(priv->txqueue_to_outpipemap,0,9);
7149 #ifdef PIPE12
7151 int i=0;
7152 u8 queuetopipe[]={3,2,1,0,4,8,7,6,5};
7153 memcpy(priv->txqueue_to_outpipemap,queuetopipe,9);
7154 /* for(i=0;i<9;i++)
7155 printk("%d ",priv->txqueue_to_outpipemap[i]);
7156 printk("\n");*/
7158 #else
7160 u8 queuetopipe[]={3,2,1,0,4,4,0,4,4};
7161 memcpy(priv->txqueue_to_outpipemap,queuetopipe,9);
7162 /* for(i=0;i<9;i++)
7163 printk("%d ",priv->txqueue_to_outpipemap[i]);
7164 printk("\n");*/
7166 #endif
7167 #endif
7168 rtl8192_init_priv_variable(dev);
7169 rtl8192_init_priv_lock(priv);
7170 rtl8192_init_priv_task(dev);
7171 rtl8192_get_eeprom_size(dev);
7172 priv->ops->rtl819x_read_eeprom_info(dev);
7173 rtl8192_get_channel_map(dev);
7174 init_hal_dm(dev);
7175 init_timer(&priv->watch_dog_timer);
7176 priv->watch_dog_timer.data = (unsigned long)dev;
7177 priv->watch_dog_timer.function = watch_dog_timer_callback;
7179 //rtl8192_adapter_start(dev);
7180 #ifdef DEBUG_EPROM
7181 dump_eprom(dev);
7182 #endif
7183 return 0;
7186 /******************************************************************************
7187 *function: This function actually only set RRSR, RATR and BW_OPMODE registers
7188 * not to do all the hw config as its name says
7189 * input: net_device dev
7190 * output: none
7191 * return: none
7192 * notice: This part need to modified according to the rate set we filtered
7193 * ****************************************************************************/
7194 void rtl8192_hwconfig(struct net_device* dev)
7196 u32 regRATR = 0, regRRSR = 0;
7197 u8 regBwOpMode = 0, regTmp = 0;
7198 struct r8192_priv *priv = ieee80211_priv(dev);
7200 // Set RRSR, RATR, and BW_OPMODE registers
7202 switch(priv->ieee80211->mode)
7204 case WIRELESS_MODE_B:
7205 regBwOpMode = BW_OPMODE_20MHZ;
7206 regRATR = RATE_ALL_CCK;
7207 regRRSR = RATE_ALL_CCK;
7208 break;
7209 case WIRELESS_MODE_A:
7210 regBwOpMode = BW_OPMODE_5G |BW_OPMODE_20MHZ;
7211 regRATR = RATE_ALL_OFDM_AG;
7212 regRRSR = RATE_ALL_OFDM_AG;
7213 break;
7214 case WIRELESS_MODE_G:
7215 regBwOpMode = BW_OPMODE_20MHZ;
7216 regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
7217 regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
7218 break;
7219 case WIRELESS_MODE_AUTO:
7220 #ifdef TO_DO_LIST
7221 if (Adapter->bInHctTest)
7223 regBwOpMode = BW_OPMODE_20MHZ;
7224 regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
7225 regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
7227 else
7228 #endif
7230 regBwOpMode = BW_OPMODE_20MHZ;
7231 regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
7232 regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
7234 break;
7235 case WIRELESS_MODE_N_24G:
7236 // It support CCK rate by default.
7237 // CCK rate will be filtered out only when associated AP does not support it.
7238 regBwOpMode = BW_OPMODE_20MHZ;
7239 regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
7240 regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
7241 break;
7242 case WIRELESS_MODE_N_5G:
7243 regBwOpMode = BW_OPMODE_5G;
7244 regRATR = RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
7245 regRRSR = RATE_ALL_OFDM_AG;
7246 break;
7249 write_nic_byte(dev, BW_OPMODE, regBwOpMode);
7251 u32 ratr_value = 0;
7252 ratr_value = regRATR;
7253 if (priv->rf_type == RF_1T2R)
7255 ratr_value &= ~(RATE_ALL_OFDM_2SS);
7257 write_nic_dword(dev, RATR0, ratr_value);
7258 write_nic_byte(dev, UFWP, 1);
7260 regTmp = read_nic_byte(dev, 0x313);
7261 regRRSR = ((regTmp) << 24) | (regRRSR & 0x00ffffff);
7262 write_nic_dword(dev, RRSR, regRRSR);
7265 // Set Retry Limit here
7267 write_nic_word(dev, RETRY_LIMIT,
7268 priv->ShortRetryLimit << RETRY_LIMIT_SHORT_SHIFT | \
7269 priv->LongRetryLimit << RETRY_LIMIT_LONG_SHIFT);
7270 // Set Contention Window here
7272 // Set Tx AGC
7274 // Set Tx Antenna including Feedback control
7276 // Set Auto Rate fallback control
7281 #ifdef RTL8192SU
7282 #ifdef USB_RX_AGGREGATION_SUPPORT
7283 u8 rtl8192SU_MapRxPageSizeToIdx(u16 RxPktSize )
7285 switch(RxPktSize)
7287 case 64: return 0; break;
7288 case 128 : return 1; break;
7289 case 256: return 2; break;
7290 case 512: return 3; break;
7291 case 1024: return 4; break;
7292 default: return 0; // We use 64bytes in defult.
7295 #endif
7298 // Description:
7299 // Initial HW relted registers.
7301 // Assumption:
7302 // Config RTL8192S USB MAC, we should config MAC before download FW.
7304 // 2008.09.03, Added by Roger.
7306 static void rtl8192SU_MacConfigBeforeFwDownloadASIC(struct net_device *dev)
7308 u8 tmpU1b;// i;
7309 // u16 tmpU2b;
7310 // u32 tmpU4b;
7311 u8 PollingCnt = 20;
7313 RT_TRACE(COMP_INIT, "--->MacConfigBeforeFwDownloadASIC()\n");
7315 //2MAC Initialization for power on sequence, Revised by Roger. 2008.09.03.
7318 //<Roger_Notes> Set control path switch to HW control and reset Digital Core, CPU Core and
7319 // MAC I/O to solve FW download fail when system from resume sate.
7320 // 2008.11.04.
7322 tmpU1b = read_nic_byte(dev, SYS_CLKR+1);
7323 if(tmpU1b & 0x80)
7325 tmpU1b &= 0x3f;
7326 write_nic_byte(dev, SYS_CLKR+1, tmpU1b);
7328 // Clear FW RPWM for FW control LPS. by tynli. 2009.02.23
7329 write_nic_byte(dev, RPWM, 0x0);
7331 tmpU1b = read_nic_byte(dev, SYS_FUNC_EN+1);
7332 tmpU1b &= 0x73;
7333 write_nic_byte(dev, SYS_FUNC_EN+1, tmpU1b);
7334 udelay(1000);
7336 //Revised POS, suggested by SD1 Alex, 2008.09.27.
7337 write_nic_byte(dev, SPS0_CTRL+1, 0x53);
7338 write_nic_byte(dev, SPS0_CTRL, 0x57);
7340 //Enable AFE Macro Block's Bandgap adn Enable AFE Macro Block's Mbias
7341 tmpU1b = read_nic_byte(dev, AFE_MISC);
7342 write_nic_byte(dev, AFE_MISC, (tmpU1b|AFE_BGEN|AFE_MBEN));
7344 //Enable PLL Power (LDOA15V)
7345 tmpU1b = read_nic_byte(dev, LDOA15_CTRL);
7346 write_nic_byte(dev, LDOA15_CTRL, (tmpU1b|LDA15_EN));
7348 //Enable LDOV12D block
7349 tmpU1b = read_nic_byte(dev, LDOV12D_CTRL);
7350 write_nic_byte(dev, LDOV12D_CTRL, (tmpU1b|LDV12_EN));
7352 //mpU1b = read_nic_byte(Adapter, SPS1_CTRL);
7353 //write_nic_byte(dev, SPS1_CTRL, (tmpU1b|SPS1_LDEN));
7355 //PlatformSleepUs(2000);
7357 //Enable Switch Regulator Block
7358 //tmpU1b = read_nic_byte(Adapter, SPS1_CTRL);
7359 //write_nic_byte(dev, SPS1_CTRL, (tmpU1b|SPS1_SWEN));
7361 //write_nic_dword(Adapter, SPS1_CTRL, 0x00a7b267);
7363 tmpU1b = read_nic_byte(dev, SYS_ISO_CTRL+1);
7364 write_nic_byte(dev, SYS_ISO_CTRL+1, (tmpU1b|0x08));
7366 //Engineer Packet CP test Enable
7367 tmpU1b = read_nic_byte(dev, SYS_FUNC_EN+1);
7368 write_nic_byte(dev, SYS_FUNC_EN+1, (tmpU1b|0x20));
7370 //Support 64k IMEM, suggested by SD1 Alex.
7371 tmpU1b = read_nic_byte(dev, SYS_ISO_CTRL+1);
7372 write_nic_byte(dev, SYS_ISO_CTRL+1, (tmpU1b& 0x68));
7374 //Enable AFE clock
7375 tmpU1b = read_nic_byte(dev, AFE_XTAL_CTRL+1);
7376 write_nic_byte(dev, AFE_XTAL_CTRL+1, (tmpU1b& 0xfb));
7378 //Enable AFE PLL Macro Block
7379 tmpU1b = read_nic_byte(dev, AFE_PLL_CTRL);
7380 write_nic_byte(dev, AFE_PLL_CTRL, (tmpU1b|0x11));
7382 //Attatch AFE PLL to MACTOP/BB/PCIe Digital
7383 tmpU1b = read_nic_byte(dev, SYS_ISO_CTRL);
7384 write_nic_byte(dev, SYS_ISO_CTRL, (tmpU1b&0xEE));
7386 // Switch to 40M clock
7387 write_nic_byte(dev, SYS_CLKR, 0x00);
7389 //SSC Disable
7390 tmpU1b = read_nic_byte(dev, SYS_CLKR);
7391 //write_nic_byte(dev, SYS_CLKR, (tmpU1b&0x5f));
7392 write_nic_byte(dev, SYS_CLKR, (tmpU1b|0xa0));
7394 //Enable MAC clock
7395 tmpU1b = read_nic_byte(dev, SYS_CLKR+1);
7396 write_nic_byte(dev, SYS_CLKR+1, (tmpU1b|0x18));
7398 //Revised POS, suggested by SD1 Alex, 2008.09.27.
7399 write_nic_byte(dev, PMC_FSM, 0x02);
7401 //Enable Core digital and enable IOREG R/W
7402 tmpU1b = read_nic_byte(dev, SYS_FUNC_EN+1);
7403 write_nic_byte(dev, SYS_FUNC_EN+1, (tmpU1b|0x08));
7405 //Enable REG_EN
7406 tmpU1b = read_nic_byte(dev, SYS_FUNC_EN+1);
7407 write_nic_byte(dev, SYS_FUNC_EN+1, (tmpU1b|0x80));
7409 //Switch the control path to FW
7410 tmpU1b = read_nic_byte(dev, SYS_CLKR+1);
7411 write_nic_byte(dev, SYS_CLKR+1, (tmpU1b|0x80)& 0xBF);
7413 write_nic_byte(dev, CMDR, 0xFC);
7414 write_nic_byte(dev, CMDR+1, 0x37);
7416 //Fix the RX FIFO issue(usb error), 970410
7417 tmpU1b = read_nic_byte_E(dev, 0x5c);
7418 write_nic_byte_E(dev, 0x5c, (tmpU1b|BIT7));
7420 //For power save, used this in the bit file after 970621
7421 tmpU1b = read_nic_byte(dev, SYS_CLKR);
7422 write_nic_byte(dev, SYS_CLKR, tmpU1b&(~SYS_CPU_CLKSEL));
7424 // Revised for 8051 ROM code wrong operation. Added by Roger. 2008.10.16.
7425 write_nic_byte_E(dev, 0x1c, 0x80);
7428 // <Roger_EXP> To make sure that TxDMA can ready to download FW.
7429 // We should reset TxDMA if IMEM RPT was not ready.
7430 // Suggested by SD1 Alex. 2008.10.23.
7434 tmpU1b = read_nic_byte(dev, TCR);
7435 if((tmpU1b & TXDMA_INIT_VALUE) == TXDMA_INIT_VALUE)
7436 break;
7437 //PlatformStallExecution(5);
7438 udelay(5);
7439 }while(PollingCnt--); // Delay 1ms
7441 if(PollingCnt <= 0 )
7443 RT_TRACE(COMP_INIT, "MacConfigBeforeFwDownloadASIC(): Polling TXDMA_INIT_VALUE timeout!! Current TCR(%#x)\n", tmpU1b);
7444 tmpU1b = read_nic_byte(dev, CMDR);
7445 write_nic_byte(dev, CMDR, tmpU1b&(~TXDMA_EN));
7446 udelay(2);
7447 write_nic_byte(dev, CMDR, tmpU1b|TXDMA_EN);// Reset TxDMA
7451 RT_TRACE(COMP_INIT, "<---MacConfigBeforeFwDownloadASIC()\n");
7453 #ifdef USB_RX_AGGREGATION_SUPPORT
7454 void rtl8192SU_HalUsbRxAggr8192SUsb(struct net_device *dev, bool Value)
7456 struct r8192_priv *priv = ieee80211_priv((struct net_device *)dev);
7457 PRT_HIGH_THROUGHPUT pHTInfo = priv->ieee80211->pHTInfo;;
7461 // <Roger_Notes> We decrease Rx page aggregated threshold in B/G mode.
7462 // 2008.10.29
7464 if(priv->ieee80211->mode == WIRELESS_MODE_B || priv->ieee80211->mode == WIRELESS_MODE_G)
7465 {// Overwrite current settings to disable Rx Aggregation.
7466 Value = false;
7469 // Alway set Rx Aggregation to Disable if current platform is Win2K USB 1.1, by Emily
7470 //if(PLATFORM_LIMITED_RX_BUF_SIZE(Adapter))
7471 // Value = FALSE;
7473 // Always set Rx Aggregation to Disable if connected AP is Realtek AP, by Joseph
7474 //if(pHTInfo->bCurrentRT2RTAggregation)
7475 // Value = FALSE;
7477 // The RX aggregation may be enabled/disabled dynamically according current traffic stream.
7478 //Enable Rx aggregation if downlink traffic is busier than uplink traffic. by Guangan
7479 if(priv->bCurrentRxAggrEnable != Value)
7481 priv->bCurrentRxAggrEnable = Value;
7482 //Adapter->HalFunc.SetHwRegHandler(Adapter, HW_VAR_USB_RX_AGGR, (pu1Byte)&pHalData->bCurrentRxAggrEnable);
7484 //u8 Setting = ((pu1Byte)(val))[0];
7485 u8 Setting = priv->bCurrentRxAggrEnable
7486 u32 ulValue;
7488 if(Setting==0)
7491 // <Roger_Notes> Reduce aggregated page threshold to 0x01 and set minimal threshold 0x0a.
7492 // i.e., disable Rx aggregation.
7494 ulValue = 0x0001000a;
7496 else
7498 //PRT_HIGH_THROUGHPUT pHTInfo = priv->ieee80211->pHTInfo;
7499 //HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
7501 if (priv->bForcedUsbRxAggr)
7502 {// Using forced settings.
7503 ulValue = priv->ForcedUsbRxAggrInfo;
7505 else
7506 {// Using default settings.
7508 ulValue = (pHTInfo->UsbRxFwAggrEn<<24) | (pHTInfo->UsbRxFwAggrPageNum<<16) |
7509 (pHTInfo->UsbRxFwAggrPacketNum<<8) | (pHTInfo->UsbRxFwAggrTimeout);
7513 write_nic_byte(dev, RXDMA_AGG_PG_TH, (u8)((ulValue&0xff0000)>>16));
7514 write_nic_byte_E(dev, USB_RX_AGG_TIMEOUT, (u8)(ulValue&0xff));
7516 priv->LastUsbRxAggrInfoSetting = ulValue;
7518 RT_TRACE(COMP_HT|COMP_RECV, "Set HW_VAR_USB_RX_AGGR: ulValue(%#x)\n", ulValue);
7520 RT_TRACE(COMP_RECV, "HalUsbRxAggr8192SUsb() : Set RxAggregation to %s\n", Value?"ON":"OFF");
7524 #endif
7526 #ifdef USB_RX_AGGREGATION_SUPPORT
7527 void rtl8192SU_HalUsbRxAggr8192SUsb(struct net_device *dev, bool Value)
7529 struct r8192_priv *priv = ieee80211_priv((struct net_device *)dev);
7530 PRT_HIGH_THROUGHPUT pHTInfo = priv->ieee80211->pHTInfo;;
7534 // <Roger_Notes> We decrease Rx page aggregated threshold in B/G mode.
7535 // 2008.10.29
7537 if((priv->ieee80211->mode & WIRELESS_MODE_B) || (priv->ieee80211->mode & WIRELESS_MODE_G))
7538 {// Overwrite current settings to disable Rx Aggregation.
7539 Value = false;
7542 // Alway set Rx Aggregation to Disable if current platform is Win2K USB 1.1, by Emily
7543 //if(PLATFORM_LIMITED_RX_BUF_SIZE(Adapter))
7544 // Value = FALSE;
7546 // Always set Rx Aggregation to Disable if connected AP is Realtek AP, by Joseph
7547 //if(pHTInfo->bCurrentRT2RTAggregation)
7548 // Value = FALSE;
7550 // The RX aggregation may be enabled/disabled dynamically according current traffic stream.
7551 //Enable Rx aggregation if downlink traffic is busier than uplink traffic. by Guangan
7552 if(priv->bCurrentRxAggrEnable != Value)
7554 priv->bCurrentRxAggrEnable = Value;
7555 //Adapter->HalFunc.SetHwRegHandler(Adapter, HW_VAR_USB_RX_AGGR, (pu1Byte)&pHalData->bCurrentRxAggrEnable);
7557 //u8 Setting = ((pu1Byte)(val))[0];
7558 u8 Setting = priv->bCurrentRxAggrEnable
7559 u32 ulValue;
7561 if(Setting==0)
7564 // <Roger_Notes> Reduce aggregated page threshold to 0x01 and set minimal threshold 0x0a.
7565 // i.e., disable Rx aggregation.
7567 ulValue = 0x0001000a;
7569 else
7571 //PRT_HIGH_THROUGHPUT pHTInfo = priv->ieee80211->pHTInfo;
7572 //HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
7574 if (priv->bForcedUsbRxAggr)
7575 {// Using forced settings.
7576 ulValue = priv->ForcedUsbRxAggrInfo;
7578 else
7579 {// Using default settings.
7581 ulValue = (pHTInfo->UsbRxFwAggrEn<<24) | (pHTInfo->UsbRxFwAggrPageNum<<16) |
7582 (pHTInfo->UsbRxFwAggrPacketNum<<8) | (pHTInfo->UsbRxFwAggrTimeout);
7586 write_nic_byte(dev, RXDMA_AGG_PG_TH, (u8)((ulValue&0xff0000)>>16));
7587 write_nic_byte_E(dev, USB_RX_AGG_TIMEOUT, (u8)(ulValue&0xff));
7589 priv->LastUsbRxAggrInfoSetting = ulValue;
7591 RT_TRACE(COMP_HT|COMP_RECV, "Set HW_VAR_USB_RX_AGGR: ulValue(%#x)\n", ulValue);
7593 RT_TRACE(COMP_RECV, "HalUsbRxAggr8192SUsb() : Set RxAggregation to %s\n", Value?"ON":"OFF");
7598 u8 rtl8192SU_MapRxPageSizeToIdx(u16 RxPktSize )
7600 switch(RxPktSize)
7602 case 64: return 0; break;
7603 case 128 : return 1; break;
7604 case 256: return 2; break;
7605 case 512: return 3; break;
7606 case 1024: return 4; break;
7607 default: return 0; // We use 64bytes in defult.
7610 #endif
7612 #if 0
7613 static void rtl8192SU_SetHwRegAmpduMinSpace(struct net_device *dev, u8 MinSpaceCfg)
7615 struct r8192_priv *priv = ieee80211_priv((struct net_device *)dev);
7616 struct ieee80211_device* ieee = priv->ieee80211;
7617 u8 MinSpacingToSet;
7618 u8 SecMinSpace;
7620 #ifdef RTL8192S_PREPARE_FOR_NORMAL_RELEASE
7621 MinSpacingToSet = MinSpaceCfg;
7622 if(MinSpacingToSet <= 7)
7624 switch(ieee->pairwise_key_type)
7626 case KEY_TYPE_NA: SecMinSpace = 0; break;
7627 case KEY_TYPE_CCMP:
7628 case KEY_TYPE_WEP40:
7629 case KEY_TYPE_WEP104:
7630 case KEY_TYPE_TKIP: SecMinSpace = 6; break;
7631 default: SecMinSpace = 7; break;
7634 if(MinSpacingToSet < SecMinSpace)
7635 MinSpacingToSet = SecMinSpace;
7636 priv->MinSpaceCfg = ((priv->MinSpaceCfg&0xf8) |MinSpacingToSet);
7637 RT_TRACE(COMP_SEC, "Set AMPDU_MIN_SPACE: %x\n", priv->MinSpaceCfg);
7638 write_nic_byte(dev, AMPDU_MIN_SPACE, priv->MinSpaceCfg);
7641 #else
7642 MinSpacingToSet = MinSpaceCfg;
7643 MinSpacingToSet &= 0x07; // We only care about bit[2:0]
7644 priv->MinSpaceCfg |= MinSpacingToSet;
7645 RT_TRACE(COMP_SEC, "Set AMPDU_MIN_SPACE: %x\n", priv->MinSpaceCfg);
7646 write_nic_byte(dev, AMPDU_MIN_SPACE, priv->MinSpaceCfg);//FIXLZM
7647 #endif
7649 #endif
7652 // Description:
7653 // Initial HW relted registers.
7655 // Assumption:
7656 // 1. This function is only invoked at driver intialization once.
7657 // 2. PASSIVE LEVEL.
7659 // 2008.06.10, Added by Roger.
7661 static void rtl8192SU_MacConfigAfterFwDownload(struct net_device *dev)
7663 struct r8192_priv *priv = ieee80211_priv((struct net_device *)dev);
7664 //PRT_HIGH_THROUGHPUT pHTInfo = priv->ieee80211->pHTInfo;
7665 //u8 tmpU1b, RxPageCfg, i;
7666 u16 tmpU2b;
7667 u8 tmpU1b;//, i;
7670 RT_TRACE(COMP_INIT, "--->MacConfigAfterFwDownload()\n");
7672 // Enable Tx/Rx
7673 tmpU2b = (BBRSTn|BB_GLB_RSTn|SCHEDULE_EN|MACRXEN|MACTXEN|DDMA_EN|
7674 FW2HW_EN|RXDMA_EN|TXDMA_EN|HCI_RXDMA_EN|HCI_TXDMA_EN); //3
7675 //Adapter->HalFunc.SetHwRegHandler( Adapter, HW_VAR_COMMAND, &tmpU1b );
7676 write_nic_word(dev, CMDR, tmpU2b); //LZM REGISTER COM 090305
7678 // Loopback mode or not
7679 priv->LoopbackMode = RTL8192SU_NO_LOOPBACK; // Set no loopback as default.
7680 if(priv->LoopbackMode == RTL8192SU_NO_LOOPBACK)
7681 tmpU1b = LBK_NORMAL;
7682 else if (priv->LoopbackMode == RTL8192SU_MAC_LOOPBACK )
7683 tmpU1b = LBK_MAC_DLB;
7684 else
7685 RT_TRACE(COMP_INIT, "Serious error: wrong loopback mode setting\n");
7687 //Adapter->HalFunc.SetHwRegHandler( Adapter, HW_VAR_LBK_MODE, &tmpU1b);
7688 write_nic_byte(dev, LBKMD_SEL, tmpU1b);
7690 // Set RCR
7691 write_nic_dword(dev, RCR, priv->ReceiveConfig);
7692 RT_TRACE(COMP_INIT, "MacConfigAfterFwDownload(): Current RCR settings(%#x)\n", priv->ReceiveConfig);
7695 // Set RQPN
7697 // <Roger_Notes> 2008.08.18.
7698 // 6 endpoints:
7699 // (1) Page number on CMDQ is 0x03.
7700 // (2) Page number on BCNQ, HQ and MGTQ is 0.
7701 // (3) Page number on BKQ, BEQ, VIQ and VOQ are 0x07.
7702 // (4) Page number on PUBQ is 0xdd
7704 // 11 endpoints:
7705 // (1) Page number on CMDQ is 0x00.
7706 // (2) Page number on BCNQ is 0x02, HQ and MGTQ are 0x03.
7707 // (3) Page number on BKQ, BEQ, VIQ and VOQ are 0x07.
7708 // (4) Page number on PUBQ is 0xd8
7710 //write_nic_dword(Adapter, 0xa0, 0x07070707); //BKQ, BEQ, VIQ and VOQ
7711 //write_nic_byte(dev, 0xa4, 0x00); // HCCAQ
7712 #if 0 //LZM 090219
7713 #ifdef USE_SIX_USB_ENDPOINT
7714 //write_nic_dword(Adapter, 0xa5, 0x00000003); //CMDQ, MGTQ, HQ and BCNQ
7715 //write_nic_byte(dev, 0xa9, 0xdd); // PUBQ
7716 tmpU1b = read_nic_byte(dev, 0xab); // RQPN
7717 write_nic_byte(dev, 0xab, tmpU1b|BIT7|BIT6);// reduce to 6 endpoints.
7718 #else
7719 write_nic_dword(dev, 0xa5, 0x02030300); //CMDQ, MGTQ, HQ and BCNQ
7720 write_nic_byte(dev, 0xa9, 0xd8); // PUBQ
7721 tmpU1b = read_nic_byte(dev, 0xab); // RQPN
7722 write_nic_byte(dev, 0xab, (tmpU1b&(~BIT6))|BIT7); // Disable reduced endpoint.
7723 #endif
7724 #endif
7726 #ifdef USB_RX_AGGREGATION_SUPPORT
7727 // Size of Tx/Rx packet buffer.
7728 tmpU1b = read_nic_byte(dev, PBP);
7729 RxPageCfg = rtl8192SU_MapRxPageSizeToIdx(priv->ieee80211->pHTInfo.UsbRxPageSize);
7730 write_nic_byte(dev, PBP, tmpU1b|RxPageCfg); // Set page size of Rx packet buffer to 128 bytes.
7731 tmpU1b = read_nic_byte(dev, RXDMA);
7733 write_nic_byte(dev, RXDMA, tmpU1b|RXDMA_AGG_EN); // Rx aggregation enable.
7734 //PlatformIOWrite1Byte(Adapter, RXDMA_AGG_PG_TH, 0x14); // Set page size of RxDMA aggregation threshold, default: 20.
7735 //write_nic_byte(dev, RXDMA_AGG_PG_TH, 0x40); // By Scott's suggestion, 2008.09.30.//92su del
7736 //write_nic_byte(dev, USB_RX_AGG_TIMEOUT, RXDMA_AGG_TIMEOUT_17_4_MS); // Set aggregation time-out to 17ms/4.
7737 rtl8192SU_HalUsbRxAggr8192SUsb(dev, true);
7738 #endif
7740 // Fix the RX FIFO issue(USB error), Rivesed by Roger, 2008-06-14
7741 tmpU1b = read_nic_byte_E(dev, 0x5C);
7742 write_nic_byte_E(dev, 0x5C, tmpU1b|BIT7);
7745 // Revise USB PHY to solve the issue of Rx payload error, Rivesed by Roger, 2008-04-10
7746 // Suggest by SD1 Alex.
7748 // <Roger_Notes> The following operation are ONLY for USB PHY test chip.
7749 // 2008.10.07.
7751 #if RTL8192SU_USB_PHY_TEST
7752 write_nic_byte(dev, 0x41,0xf4);
7753 write_nic_byte(dev, 0x40,0x00);
7754 write_nic_byte(dev, 0x42,0x00);
7755 write_nic_byte(dev, 0x42,0x01);
7756 write_nic_byte(dev, 0x40,0x0f);
7757 write_nic_byte(dev, 0x42,0x00);
7758 write_nic_byte(dev, 0x42,0x01);
7759 #endif
7761 #if 0 //LZM 090219
7763 // Suggested by SD1 Alex, 2008-06-14.
7765 write_nic_byte(dev, TXOP_STALL_CTRL, 0x80);//NAV
7769 // Set Data Auto Rate Fallback Retry Count register.
7771 write_nic_dword(dev, DARFRC, 0x04010000);
7772 write_nic_dword(dev, DARFRC+4, 0x09070605);
7773 write_nic_dword(dev, RARFRC, 0x04010000);
7774 write_nic_dword(dev, RARFRC+4, 0x09070605);
7776 // Set Data Auto Rate Fallback Reg. Added by Roger, 2008.09.22.
7777 for (i = 0; i < 8; i++)
7778 #ifdef RTL8192SU_DISABLE_CCK_RATE
7779 write_nic_dword(dev, ARFR0+i*4, 0x1f0ff0f0);
7780 #else
7781 write_nic_dword(dev, ARFR0+i*4, 0x1f0ffff0);
7782 #endif
7785 // Set driver info, we only accept PHY status now.
7787 //write_nic_byte(dev, RXDRVINFO_SZ, 4);
7790 // Aggregation length limit. Revised by Roger. 2008.09.22.
7792 write_nic_dword(dev, AGGLEN_LMT_L, 0x66666666); // Long GI
7793 write_nic_byte(dev, AGGLEN_LMT_H, 0x06); // Set AMPDU length to 12Kbytes for ShortGI case.
7796 // For Min Spacing configuration.
7798 //Adapter->HalFunc.SetHwRegHandler(Adapter, HW_VAR_AMPDU_MIN_SPACE, (u8*)(&Adapter->MgntInfo.MinSpaceCfg));
7799 rtl8192SU_SetHwRegAmpduMinSpace(dev,priv->MinSpaceCfg);
7800 #endif
7802 // For EFUSE init configuration.
7803 //if (IS_BOOT_FROM_EFUSE(Adapter)) // We may R/W EFUSE in EFUSE mode
7804 if (priv->bBootFromEfuse)
7806 u8 tempval;
7808 tempval = read_nic_byte(dev, SYS_ISO_CTRL+1);
7809 tempval &= 0xFE;
7810 write_nic_byte(dev, SYS_ISO_CTRL+1, tempval);
7812 // Enable LDO 2.5V for write action
7813 //tempval = read_nic_byte(Adapter, EFUSE_TEST+3);
7814 //write_nic_byte(Adapter, EFUSE_TEST+3, (tempval | 0x80));
7816 // Change Efuse Clock for write action
7817 //write_nic_byte(Adapter, EFUSE_CLK, 0x03);
7819 // Change Program timing
7820 write_nic_byte(dev, EFUSE_CTRL+3, 0x72);
7821 //printk("!!!!!!!!!!!!!!!!!!!!!%s: write 0x33 with 0x72\n",__FUNCTION__);
7822 RT_TRACE(COMP_INIT, "EFUSE CONFIG OK\n");
7826 RT_TRACE(COMP_INIT, "<---MacConfigAfterFwDownload()\n");
7829 void rtl8192SU_HwConfigureRTL8192SUsb(struct net_device *dev)
7832 struct r8192_priv *priv = ieee80211_priv(dev);
7833 u8 regBwOpMode = 0;
7834 u32 regRATR = 0, regRRSR = 0;
7835 u8 regTmp = 0;
7836 u32 i = 0;
7838 //1 This part need to modified according to the rate set we filtered!!
7840 // Set RRSR, RATR, and BW_OPMODE registers
7842 switch(priv->ieee80211->mode)
7844 case WIRELESS_MODE_B:
7845 regBwOpMode = BW_OPMODE_20MHZ;
7846 regRATR = RATE_ALL_CCK;
7847 regRRSR = RATE_ALL_CCK;
7848 break;
7849 case WIRELESS_MODE_A:
7850 regBwOpMode = BW_OPMODE_5G |BW_OPMODE_20MHZ;
7851 regRATR = RATE_ALL_OFDM_AG;
7852 regRRSR = RATE_ALL_OFDM_AG;
7853 break;
7854 case WIRELESS_MODE_G:
7855 regBwOpMode = BW_OPMODE_20MHZ;
7856 regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
7857 regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
7858 break;
7859 case WIRELESS_MODE_AUTO:
7860 if (priv->bInHctTest)
7862 regBwOpMode = BW_OPMODE_20MHZ;
7863 regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
7864 regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
7866 else
7868 regBwOpMode = BW_OPMODE_20MHZ;
7869 regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
7870 regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
7872 break;
7873 case WIRELESS_MODE_N_24G:
7874 // It support CCK rate by default.
7875 // CCK rate will be filtered out only when associated AP does not support it.
7876 regBwOpMode = BW_OPMODE_20MHZ;
7877 regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
7878 regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
7879 break;
7880 case WIRELESS_MODE_N_5G:
7881 regBwOpMode = BW_OPMODE_5G;
7882 regRATR = RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
7883 regRRSR = RATE_ALL_OFDM_AG;
7884 break;
7888 // <Roger_Notes> We disable CCK response rate until FIB CCK rate IC's back.
7889 // 2008.09.23.
7891 regTmp = read_nic_byte(dev, INIRTSMCS_SEL);
7892 #ifdef RTL8192SU_DISABLE_CCK_RATE
7893 regRRSR = ((regRRSR & 0x000ffff0)<<8) | regTmp;
7894 #else
7895 regRRSR = ((regRRSR & 0x000fffff)<<8) | regTmp;
7896 #endif
7899 // Update SIFS timing.
7901 //priv->SifsTime = 0x0e0e0a0a;
7902 //Adapter->HalFunc.SetHwRegHandler( Adapter, HW_VAR_SIFS, (pu1Byte)&pHalData->SifsTime);
7903 { u8 val[4] = {0x0e, 0x0e, 0x0a, 0x0a};
7904 // SIFS for CCK Data ACK
7905 write_nic_byte(dev, SIFS_CCK, val[0]);
7906 // SIFS for CCK consecutive tx like CTS data!
7907 write_nic_byte(dev, SIFS_CCK+1, val[1]);
7909 // SIFS for OFDM Data ACK
7910 write_nic_byte(dev, SIFS_OFDM, val[2]);
7911 // SIFS for OFDM consecutive tx like CTS data!
7912 write_nic_byte(dev, SIFS_OFDM+1, val[3]);
7915 write_nic_dword(dev, INIRTSMCS_SEL, regRRSR);
7916 write_nic_byte(dev, BW_OPMODE, regBwOpMode);
7919 // Suggested by SD1 Alex, 2008-06-14.
7921 //PlatformEFIOWrite1Byte(Adapter, TXOP_STALL_CTRL, 0x80);//NAV to protect all TXOP.
7924 // Set Data Auto Rate Fallback Retry Count register.
7926 write_nic_dword(dev, DARFRC, 0x02010000);
7927 write_nic_dword(dev, DARFRC+4, 0x06050403);
7928 write_nic_dword(dev, RARFRC, 0x02010000);
7929 write_nic_dword(dev, RARFRC+4, 0x06050403);
7931 // Set Data Auto Rate Fallback Reg. Added by Roger, 2008.09.22.
7932 for (i = 0; i < 8; i++)
7933 #ifdef RTL8192SU_DISABLE_CCK_RATE
7934 write_nic_dword(dev, ARFR0+i*4, 0x1f0ff0f0);
7935 #else
7936 write_nic_dword(dev, ARFR0+i*4, 0x1f0ffff0);
7937 #endif
7940 // Aggregation length limit. Revised by Roger. 2008.09.22.
7942 write_nic_byte(dev, AGGLEN_LMT_H, 0x0f); // Set AMPDU length to 12Kbytes for ShortGI case.
7943 write_nic_dword(dev, AGGLEN_LMT_L, 0xddd77442); // Long GI
7944 write_nic_dword(dev, AGGLEN_LMT_L+4, 0xfffdd772);
7946 // Set NAV protection length
7947 write_nic_word(dev, NAV_PROT_LEN, 0x0080);
7949 // Set TXOP stall control for several queue/HI/BCN/MGT/
7950 write_nic_byte(dev, TXOP_STALL_CTRL, 0x00); // NAV Protect next packet.
7952 // Set MSDU lifetime.
7953 write_nic_byte(dev, MLT, 0x8f);
7955 // Set CCK/OFDM SIFS
7956 write_nic_word(dev, SIFS_CCK, 0x0a0a); // CCK SIFS shall always be 10us.
7957 write_nic_word(dev, SIFS_OFDM, 0x0e0e);
7959 write_nic_byte(dev, ACK_TIMEOUT, 0x40);
7961 // CF-END Threshold
7962 write_nic_byte(dev, CFEND_TH, 0xFF);
7965 // For Min Spacing configuration.
7967 switch(priv->rf_type)
7969 case RF_1T2R:
7970 case RF_1T1R:
7971 RT_TRACE(COMP_INIT, "Initializeadapter: RF_Type%s\n", (priv->rf_type==RF_1T1R? "(1T1R)":"(1T2R)"));
7972 priv->MinSpaceCfg = (MAX_MSS_DENSITY_1T<<3);
7973 break;
7974 case RF_2T2R:
7975 case RF_2T2R_GREEN:
7976 RT_TRACE(COMP_INIT, "Initializeadapter:RF_Type(2T2R)\n");
7977 priv->MinSpaceCfg = (MAX_MSS_DENSITY_2T<<3);
7978 break;
7980 write_nic_byte(dev, AMPDU_MIN_SPACE, priv->MinSpaceCfg);
7982 //LZM 090219
7984 // For Min Spacing configuration.
7986 //priv->MinSpaceCfg = 0x00;
7987 //rtl8192SU_SetHwRegAmpduMinSpace(dev, priv->MinSpaceCfg);
7990 #endif
7992 #ifdef RTL8192SU
7993 // Description: Initial HW relted registers.
7995 // Assumption: This function is only invoked at driver intialization once.
7997 // 2008.06.10, Added by Roger.
7998 bool rtl8192SU_adapter_start(struct net_device *dev)
8000 struct r8192_priv *priv = ieee80211_priv(dev);
8001 //u32 dwRegRead = 0;
8002 //bool init_status = true;
8003 //u32 ulRegRead;
8004 bool rtStatus = true;
8005 //u8 PipeIndex;
8006 //u8 eRFPath, tmpU1b;
8007 u8 fw_download_times = 1;
8010 RT_TRACE(COMP_INIT, "--->InitializeAdapter8192SUsb()\n");
8012 //pHalData->bGPIOChangeRF = FALSE;
8016 // <Roger_Notes> 2008.06.15.
8018 // Initialization Steps on RTL8192SU:
8019 // a. MAC initialization prior to sending down firmware code.
8020 // b. Download firmware code step by step(i.e., IMEM, EMEM, DMEM).
8021 // c. MAC configuration after firmware has been download successfully.
8022 // d. Initialize BB related configurations.
8023 // e. Initialize RF related configurations.
8024 // f. Start to BulkIn transfer.
8028 //a. MAC initialization prior to send down firmware code.
8030 start:
8031 rtl8192SU_MacConfigBeforeFwDownloadASIC(dev);
8034 //b. Download firmware code step by step(i.e., IMEM, EMEM, DMEM).
8036 rtStatus = FirmwareDownload92S(dev);
8037 if(rtStatus != true)
8039 if(fw_download_times == 1){
8040 RT_TRACE(COMP_INIT, "InitializeAdapter8192SUsb(): Download Firmware failed once, Download again!!\n");
8041 fw_download_times = fw_download_times + 1;
8042 goto start;
8043 }else{
8044 RT_TRACE(COMP_INIT, "InitializeAdapter8192SUsb(): Download Firmware failed twice, end!!\n");
8045 goto end;
8049 //c. MAC configuration after firmware has been download successfully.
8051 rtl8192SU_MacConfigAfterFwDownload(dev);
8053 #if (RTL8192S_DISABLE_FW_DM == 1)
8054 write_nic_dword(dev, WFM5, FW_DM_DISABLE);
8055 #endif
8056 //priv->bLbusEnable = TRUE;
8057 //if(priv->RegRfOff == TRUE)
8058 // priv->eRFPowerState = eRfOff;
8060 // Save target channel
8061 // <Roger_Notes> Current Channel will be updated again later.
8062 //priv->CurrentChannel = Channel;
8063 rtStatus = PHY_MACConfig8192S(dev);//===>ok
8064 if(rtStatus != true)
8066 RT_TRACE(COMP_INIT, "InitializeAdapter8192SUsb(): Fail to configure MAC!!\n");
8067 goto end;
8069 if (1){
8070 int i;
8071 for (i=0; i<4; i++)
8072 write_nic_dword(dev,WDCAPARA_ADD[i], 0x5e4322);
8073 write_nic_byte(dev,AcmHwCtrl, 0x01);
8078 //d. Initialize BB related configurations.
8081 rtStatus = PHY_BBConfig8192S(dev);//===>ok
8082 if(rtStatus != true)
8084 RT_TRACE(COMP_INIT, "InitializeAdapter8192SUsb(): Fail to configure BB!!\n");
8085 goto end;
8088 rtl8192_setBBreg(dev, rFPGA0_AnalogParameter2, 0xff, 0x58);//===>ok
8091 // e. Initialize RF related configurations.
8093 // 2007/11/02 MH Before initalizing RF. We can not use FW to do RF-R/W.
8094 priv->Rf_Mode = RF_OP_By_SW_3wire;
8096 // For RF test only from Scott's suggestion
8097 //write_nic_byte(dev, 0x27, 0xDB);
8098 //write_nic_byte(dev, 0x1B, 0x07);
8101 write_nic_byte(dev, AFE_XTAL_CTRL+1, 0xDB);
8103 // <Roger_Notes> The following IOs are configured for each RF modules.
8104 // Enable RF module and reset RF and SDM module. 2008.11.17.
8105 if(priv->card_8192_version == VERSION_8192S_ACUT)
8106 write_nic_byte(dev, SPS1_CTRL+3, (u8)(RF_EN|RF_RSTB|RF_SDMRSTB)); // Fix A-Cut bug.
8107 else
8108 write_nic_byte(dev, RF_CTRL, (u8)(RF_EN|RF_RSTB|RF_SDMRSTB));
8110 rtStatus = PHY_RFConfig8192S(dev);//===>ok
8111 if(rtStatus != true)
8113 RT_TRACE(COMP_INIT, "InitializeAdapter8192SUsb(): Fail to configure RF!!\n");
8114 goto end;
8118 // Set CCK and OFDM Block "ON"
8119 rtl8192_setBBreg(dev, rFPGA0_RFMOD, bCCKEn, 0x1);
8120 rtl8192_setBBreg(dev, rFPGA0_RFMOD, bOFDMEn, 0x1);
8123 // Turn off Radio B while RF type is 1T1R by SD3 Wilsion's request.
8124 // Revised by Roger, 2008.12.18.
8126 if(priv->rf_type == RF_1T1R)
8128 // This is needed for PHY_REG after 20081219
8129 rtl8192_setBBreg(dev, rFPGA0_RFMOD, 0xff000000, 0x03);
8130 // This is needed for PHY_REG before 20081219
8131 //PHY_SetBBReg(Adapter, rOFDM0_TRxPathEnable, bMaskByte0, 0x11);
8134 #if (RTL8192SU_DISABLE_IQK==0)
8135 // For 1T2R IQK only currently.
8136 if (priv->card_8192_version == VERSION_8192S_BCUT)
8138 PHY_IQCalibrateBcut(dev);
8140 else if (priv->card_8192_version == VERSION_8192S_ACUT)
8142 PHY_IQCalibrate(dev);
8144 #endif
8146 //LZM 090219
8147 // Set CCK and OFDM Block "ON"
8148 //rtl8192_setBBreg(dev, rFPGA0_RFMOD, bCCKEn, 0x1);
8149 //rtl8192_setBBreg(dev, rFPGA0_RFMOD, bOFDMEn, 0x1);
8152 //3//Get hardware version, do it in read eeprom?
8153 //GetHardwareVersion819xUsb(Adapter);
8155 //3//
8156 //3 //Set Hardware
8157 //3//
8158 rtl8192SU_HwConfigureRTL8192SUsb(dev);//==>ok
8161 // <Roger_Notes> We set MAC address here if autoload was failed before,
8162 // otherwise IDR0 will NOT contain any value.
8164 write_nic_dword(dev, IDR0, ((u32*)dev->dev_addr)[0]);
8165 write_nic_word(dev, IDR4, ((u16*)(dev->dev_addr + 4))[0]);
8166 if(!priv->bInHctTest)
8168 if(priv->ResetProgress == RESET_TYPE_NORESET)
8170 //RT_TRACE(COMP_MLME, DBG_LOUD, ("Initializeadapter8192SUsb():RegWirelessMode(%#x) \n", Adapter->RegWirelessMode));
8171 //Adapter->HalFunc.SetWirelessModeHandler(Adapter, Adapter->RegWirelessMode);
8172 rtl8192_SetWirelessMode(dev, priv->ieee80211->mode);//===>ok
8175 else
8177 priv->ieee80211->mode = WIRELESS_MODE_G;
8178 rtl8192_SetWirelessMode(dev, WIRELESS_MODE_G);
8181 //Security related.
8182 //-----------------------------------------------------------------------------
8183 // Set up security related. 070106, by rcnjko:
8184 // 1. Clear all H/W keys.
8185 // 2. Enable H/W encryption/decryption.
8186 //-----------------------------------------------------------------------------
8187 //CamResetAllEntry(Adapter);
8188 //Adapter->HalFunc.EnableHWSecCfgHandler(Adapter);
8190 //SecClearAllKeys(Adapter);
8191 CamResetAllEntry(dev);
8192 //SecInit(Adapter);
8194 u8 SECR_value = 0x0;
8195 SECR_value |= SCR_TxEncEnable;
8196 SECR_value |= SCR_RxDecEnable;
8197 SECR_value |= SCR_NoSKMC;
8198 write_nic_byte(dev, SECR, SECR_value);
8201 #if 0
8203 if(pHalData->VersionID == VERSION_8192SU_A)
8205 // cosa add for tx power level initialization.
8206 GetTxPowerOriginalOffset(Adapter);
8207 SetTxPowerLevel819xUsb(Adapter, Channel);
8209 #endif
8212 #ifdef TO_DO_LIST
8214 //PHY_UpdateInitialGain(dev);
8216 if(priv->RegRfOff == true)
8217 { // User disable RF via registry.
8218 u8 eRFPath = 0;
8220 RT_TRACE((COMP_INIT|COMP_RF), "InitializeAdapter8192SUsb(): Turn off RF for RegRfOff ----------\n");
8221 MgntActSet_RF_State(dev, eRfOff, RF_CHANGE_BY_SW);
8222 // Those action will be discard in MgntActSet_RF_State because off the same state
8223 for(eRFPath = 0; eRFPath <priv->NumTotalRFPath; eRFPath++)
8224 rtl8192_setBBreg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x4, 0xC00, 0x0);
8226 else if(priv->RfOffReason > RF_CHANGE_BY_PS)
8227 { // H/W or S/W RF OFF before sleep.
8228 RT_TRACE((COMP_INIT|COMP_RF), "InitializeAdapter8192SUsb(): Turn off RF for RfOffReason(%d) ----------\n", priv->RfOffReason);
8229 MgntActSet_RF_State(dev, eRfOff, priv->RfOffReason);
8231 else
8233 priv->eRFPowerState = eRfOn;
8234 priv->RfOffReason = 0;
8235 RT_TRACE((COMP_INIT|COMP_RF), "InitializeAdapter8192SUsb(): RF is on ----------\n");
8238 #endif
8242 // f. Start to BulkIn transfer.
8244 #ifdef TO_DO_LIST
8246 #ifndef UNDER_VISTA
8248 u8 i;
8249 PlatformAcquireSpinLock(Adapter, RT_RX_SPINLOCK);
8251 for(PipeIndex=0; PipeIndex < MAX_RX_QUEUE; PipeIndex++)
8253 if (PipeIndex == 0)
8255 for(i=0; i<32; i++)
8256 HalUsbInMpdu(Adapter, PipeIndex);
8258 else
8260 //HalUsbInMpdu(Adapter, PipeIndex);
8261 //HalUsbInMpdu(Adapter, PipeIndex);
8262 //HalUsbInMpdu(Adapter, PipeIndex);
8265 PlatformReleaseSpinLock(Adapter, RT_RX_SPINLOCK);
8267 #else
8268 // Joseph add to 819X code base for Vista USB platform.
8269 // This part may need to be add to Hal819xU code base. too.
8270 PlatformUsbEnableInPipes(Adapter);
8271 #endif
8273 RT_TRACE(COMP_INIT, "HighestOperaRate = %x\n", Adapter->MgntInfo.HighestOperaRate);
8275 PlatformStartWorkItem( &(pHalData->RtUsbCheckForHangWorkItem) );
8278 // <Roger_EXP> The following configurations are for ASIC verification temporally.
8279 // 2008.07.10.
8282 #endif
8285 // Read EEPROM TX power index and PHY_REG_PG.txt to capture correct
8286 // TX power index for different rate set.
8288 //if(priv->card_8192_version >= VERSION_8192S_ACUT)
8290 // Get original hw reg values
8291 PHY_GetHWRegOriginalValue(dev);
8293 // Write correct tx power index//FIXLZM
8294 PHY_SetTxPowerLevel8192S(dev, priv->chan);
8298 u8 tmpU1b = 0;
8299 // EEPROM R/W workaround
8300 tmpU1b = read_nic_byte(dev, MAC_PINMUX_CFG);
8301 write_nic_byte(dev, MAC_PINMUX_CFG, tmpU1b&(~GPIOMUX_EN));
8305 //<Roger_Notes> 2008.08.19.
8306 // We return status here for temporal FPGA verification, 2008.08.19.
8308 #ifdef RTL8192SU_FW_IQK
8309 write_nic_dword(dev, WFM5, FW_IQK_ENABLE);
8310 ChkFwCmdIoDone(dev);
8311 #endif
8314 // <Roger_Notes> We enable high power mechanism after NIC initialized.
8315 // 2008.11.27.
8317 write_nic_dword(dev, WFM5, FW_RA_RESET);
8318 ChkFwCmdIoDone(dev);
8319 write_nic_dword(dev, WFM5, FW_RA_ACTIVE);
8320 ChkFwCmdIoDone(dev);
8321 write_nic_dword(dev, WFM5, FW_RA_REFRESH);
8322 ChkFwCmdIoDone(dev);
8323 write_nic_dword(dev, WFM5, FW_BB_RESET_ENABLE);
8325 // <Roger_Notes> We return status here for temporal FPGA verification. 2008.05.12.
8327 #if RTL8192SU_FPGA_UNSPECIFIED_NETWORK
8329 // To send specific number of packets to verify MAC Lookback mode.
8331 //SendRandomTxPkt(Adapter, 0); // Burst mode for verification.
8332 //rtStatus = RT_STATUS_FAILURE;
8333 rtStatus = true;
8334 goto end;
8335 #endif
8337 // The following IO was for FPGA verification purpose. Added by Roger, 2008.09.11.
8338 #if 0
8339 // 2008/08/19 MH From SD1 Jong, we must write some register for true PHY/MAC FPGA.
8340 write_nic_byte(dev, rOFDM0_XAAGCCore1, 0x30);
8341 write_nic_byte(dev, rOFDM0_XBAGCCore1, 0x30);
8343 write_nic_byte(dev, rOFDM0_RxDetector1, 0x42);
8345 //write_nic_dword(Adapter, RCR, 0x817FF02F);
8347 write_nic_dword(Adapter, rTxAGC_Mcs15_Mcs12, 0x06060606);
8348 #endif
8349 end:
8350 return rtStatus;
8353 #else
8355 //InitializeAdapter and PhyCfg
8356 bool rtl8192_adapter_start(struct net_device *dev)
8358 struct r8192_priv *priv = ieee80211_priv(dev);
8359 u32 dwRegRead = 0;
8360 bool init_status = true;
8361 RT_TRACE(COMP_INIT, "====>%s()\n", __FUNCTION__);
8362 priv->Rf_Mode = RF_OP_By_SW_3wire;
8363 //for ASIC power on sequence
8364 write_nic_byte_E(dev, 0x5f, 0x80);
8365 mdelay(50);
8366 write_nic_byte_E(dev, 0x5f, 0xf0);
8367 write_nic_byte_E(dev, 0x5d, 0x00);
8368 write_nic_byte_E(dev, 0x5e, 0x80);
8369 write_nic_byte(dev, 0x17, 0x37);
8370 mdelay(10);
8371 //#ifdef TO_DO_LIST
8372 priv->pFirmware->firmware_status = FW_STATUS_0_INIT;
8373 //config CPUReset Register
8374 //Firmware Reset or not?
8375 dwRegRead = read_nic_dword(dev, CPU_GEN);
8376 if (priv->pFirmware->firmware_status == FW_STATUS_0_INIT)
8377 dwRegRead |= CPU_GEN_SYSTEM_RESET; //do nothing here?
8378 else if (priv->pFirmware->firmware_status == FW_STATUS_5_READY)
8379 dwRegRead |= CPU_GEN_FIRMWARE_RESET;
8380 else
8381 RT_TRACE(COMP_ERR, "ERROR in %s(): undefined firmware state(%d)\n", __FUNCTION__, priv->pFirmware->firmware_status);
8383 write_nic_dword(dev, CPU_GEN, dwRegRead);
8384 //mdelay(30);
8385 //config BB.
8386 rtl8192_BBConfig(dev);
8388 #if 1
8389 //Loopback mode or not
8390 priv->LoopbackMode = RTL819xU_NO_LOOPBACK;
8391 // priv->LoopbackMode = RTL819xU_MAC_LOOPBACK;
8393 dwRegRead = read_nic_dword(dev, CPU_GEN);
8394 if (priv->LoopbackMode == RTL819xU_NO_LOOPBACK)
8395 dwRegRead = ((dwRegRead & CPU_GEN_NO_LOOPBACK_MSK) | CPU_GEN_NO_LOOPBACK_SET);
8396 else if (priv->LoopbackMode == RTL819xU_MAC_LOOPBACK)
8397 dwRegRead |= CPU_CCK_LOOPBACK;
8398 else
8399 RT_TRACE(COMP_ERR, "Serious error in %s(): wrong loopback mode setting(%d)\n", __FUNCTION__, priv->LoopbackMode);
8401 write_nic_dword(dev, CPU_GEN, dwRegRead);
8403 //after reset cpu, we need wait for a seconds to write in register.
8404 udelay(500);
8406 //xiong add for new bitfile:usb suspend reset pin set to 1. //do we need?
8407 write_nic_byte_E(dev, 0x5f, (read_nic_byte_E(dev, 0x5f)|0x20));
8409 //Set Hardware
8410 rtl8192_hwconfig(dev);
8412 //turn on Tx/Rx
8413 write_nic_byte(dev, CMDR, CR_RE|CR_TE);
8415 //set IDR0 here
8416 write_nic_dword(dev, MAC0, ((u32*)dev->dev_addr)[0]);
8417 write_nic_word(dev, MAC4, ((u16*)(dev->dev_addr + 4))[0]);
8419 //set RCR
8420 write_nic_dword(dev, RCR, priv->ReceiveConfig);
8422 //Initialize Number of Reserved Pages in Firmware Queue
8423 write_nic_dword(dev, RQPN1, NUM_OF_PAGE_IN_FW_QUEUE_BK << RSVD_FW_QUEUE_PAGE_BK_SHIFT |\
8424 NUM_OF_PAGE_IN_FW_QUEUE_BE << RSVD_FW_QUEUE_PAGE_BE_SHIFT | \
8425 NUM_OF_PAGE_IN_FW_QUEUE_VI << RSVD_FW_QUEUE_PAGE_VI_SHIFT | \
8426 NUM_OF_PAGE_IN_FW_QUEUE_VO <<RSVD_FW_QUEUE_PAGE_VO_SHIFT);
8427 write_nic_dword(dev, RQPN2, NUM_OF_PAGE_IN_FW_QUEUE_MGNT << RSVD_FW_QUEUE_PAGE_MGNT_SHIFT |\
8428 NUM_OF_PAGE_IN_FW_QUEUE_CMD << RSVD_FW_QUEUE_PAGE_CMD_SHIFT);
8429 write_nic_dword(dev, RQPN3, APPLIED_RESERVED_QUEUE_IN_FW| \
8430 NUM_OF_PAGE_IN_FW_QUEUE_BCN<<RSVD_FW_QUEUE_PAGE_BCN_SHIFT
8431 // | NUM_OF_PAGE_IN_FW_QUEUE_PUB<<RSVD_FW_QUEUE_PAGE_PUB_SHIFT
8433 write_nic_dword(dev, RATR0+4*7, (RATE_ALL_OFDM_AG | RATE_ALL_CCK));
8435 //Set AckTimeout
8436 // TODO: (it value is only for FPGA version). need to be changed!!2006.12.18, by Emily
8437 write_nic_byte(dev, ACK_TIMEOUT, 0x30);
8439 // RT_TRACE(COMP_INIT, "%s():priv->ResetProgress is %d\n", __FUNCTION__,priv->ResetProgress);
8440 if(priv->ResetProgress == RESET_TYPE_NORESET)
8441 rtl8192_SetWirelessMode(dev, priv->ieee80211->mode);
8442 if(priv->ResetProgress == RESET_TYPE_NORESET){
8443 CamResetAllEntry(dev);
8445 u8 SECR_value = 0x0;
8446 SECR_value |= SCR_TxEncEnable;
8447 SECR_value |= SCR_RxDecEnable;
8448 SECR_value |= SCR_NoSKMC;
8449 write_nic_byte(dev, SECR, SECR_value);
8453 //Beacon related
8454 write_nic_word(dev, ATIMWND, 2);
8455 write_nic_word(dev, BCN_INTERVAL, 100);
8458 #define DEFAULT_EDCA 0x005e4332
8459 int i;
8460 for (i=0; i<QOS_QUEUE_NUM; i++)
8461 write_nic_dword(dev, WDCAPARA_ADD[i], DEFAULT_EDCA);
8463 #ifdef USB_RX_AGGREGATION_SUPPORT
8464 //3 For usb rx firmware aggregation control
8465 if(priv->ResetProgress == RESET_TYPE_NORESET)
8467 u32 ulValue;
8468 PRT_HIGH_THROUGHPUT pHTInfo = priv->ieee80211->pHTInfo;
8469 ulValue = (pHTInfo->UsbRxFwAggrEn<<24) | (pHTInfo->UsbRxFwAggrPageNum<<16) |
8470 (pHTInfo->UsbRxFwAggrPacketNum<<8) | (pHTInfo->UsbRxFwAggrTimeout);
8472 * If usb rx firmware aggregation is enabled,
8473 * when anyone of three threshold conditions above is reached,
8474 * firmware will send aggregated packet to driver.
8476 write_nic_dword(dev, 0x1a8, ulValue);
8477 priv->bCurrentRxAggrEnable = true;
8479 #endif
8481 rtl8192_phy_configmac(dev);
8483 if (priv->card_8192_version == (u8) VERSION_819xU_A)
8485 rtl8192_phy_getTxPower(dev);
8486 rtl8192_phy_setTxPower(dev, priv->chan);
8490 priv->usb_error = false;
8491 //Firmware download
8492 init_status = init_firmware(dev);
8493 if(!init_status)
8495 RT_TRACE(COMP_ERR,"ERR!!! %s(): Firmware download is failed\n", __FUNCTION__);
8496 return init_status;
8498 RT_TRACE(COMP_INIT, "%s():after firmware download\n", __FUNCTION__);
8500 #ifdef TO_DO_LIST
8501 if(Adapter->ResetProgress == RESET_TYPE_NORESET)
8503 if(pMgntInfo->RegRfOff == TRUE)
8504 { // User disable RF via registry.
8505 RT_TRACE((COMP_INIT|COMP_RF), DBG_LOUD, ("InitializeAdapter819xUsb(): Turn off RF for RegRfOff ----------\n"));
8506 MgntActSet_RF_State(Adapter, eRfOff, RF_CHANGE_BY_SW);
8507 // Those action will be discard in MgntActSet_RF_State because off the same state
8508 for(eRFPath = 0; eRFPath <pHalData->NumTotalRFPath; eRFPath++)
8509 PHY_SetRFReg(Adapter, (RF90_RADIO_PATH_E)eRFPath, 0x4, 0xC00, 0x0);
8511 else if(pMgntInfo->RfOffReason > RF_CHANGE_BY_PS)
8512 { // H/W or S/W RF OFF before sleep.
8513 RT_TRACE((COMP_INIT|COMP_RF), DBG_LOUD, ("InitializeAdapter819xUsb(): Turn off RF for RfOffReason(%d) ----------\n", pMgntInfo->RfOffReason));
8514 MgntActSet_RF_State(Adapter, eRfOff, pMgntInfo->RfOffReason);
8516 else
8518 pHalData->eRFPowerState = eRfOn;
8519 pMgntInfo->RfOffReason = 0;
8520 RT_TRACE((COMP_INIT|COMP_RF), DBG_LOUD, ("InitializeAdapter819xUsb(): RF is on ----------\n"));
8523 else
8525 if(pHalData->eRFPowerState == eRfOff)
8527 MgntActSet_RF_State(Adapter, eRfOff, pMgntInfo->RfOffReason);
8528 // Those action will be discard in MgntActSet_RF_State because off the same state
8529 for(eRFPath = 0; eRFPath <pHalData->NumTotalRFPath; eRFPath++)
8530 PHY_SetRFReg(Adapter, (RF90_RADIO_PATH_E)eRFPath, 0x4, 0xC00, 0x0);
8533 #endif
8534 //config RF.
8535 if(priv->ResetProgress == RESET_TYPE_NORESET){
8536 rtl8192_phy_RFConfig(dev);
8537 RT_TRACE(COMP_INIT, "%s():after phy RF config\n", __FUNCTION__);
8541 if(priv->ieee80211->FwRWRF)
8542 // We can force firmware to do RF-R/W
8543 priv->Rf_Mode = RF_OP_By_FW;
8544 else
8545 priv->Rf_Mode = RF_OP_By_SW_3wire;
8548 rtl8192_phy_updateInitGain(dev);
8549 /*--set CCK and OFDM Block "ON"--*/
8550 rtl8192_setBBreg(dev, rFPGA0_RFMOD, bCCKEn, 0x1);
8551 rtl8192_setBBreg(dev, rFPGA0_RFMOD, bOFDMEn, 0x1);
8553 if(priv->ResetProgress == RESET_TYPE_NORESET)
8555 //if D or C cut
8556 u8 tmpvalue = read_nic_byte(dev, 0x301);
8557 if(tmpvalue ==0x03)
8559 priv->bDcut = TRUE;
8560 RT_TRACE(COMP_POWER_TRACKING, "D-cut\n");
8562 else
8564 priv->bDcut = FALSE;
8565 RT_TRACE(COMP_POWER_TRACKING, "C-cut\n");
8567 dm_initialize_txpower_tracking(dev);
8569 if(priv->bDcut == TRUE)
8571 u32 i, TempCCk;
8572 u32 tmpRegA= rtl8192_QueryBBReg(dev,rOFDM0_XATxIQImbalance,bMaskDWord);
8573 // u32 tmpRegC= rtl8192_QueryBBReg(dev,rOFDM0_XCTxIQImbalance,bMaskDWord);
8574 for(i = 0; i<TxBBGainTableLength; i++)
8576 if(tmpRegA == priv->txbbgain_table[i].txbbgain_value)
8578 priv->rfa_txpowertrackingindex= (u8)i;
8579 priv->rfa_txpowertrackingindex_real= (u8)i;
8580 priv->rfa_txpowertracking_default= priv->rfa_txpowertrackingindex;
8581 break;
8585 TempCCk = rtl8192_QueryBBReg(dev, rCCK0_TxFilter1, bMaskByte2);
8587 for(i=0 ; i<CCKTxBBGainTableLength ; i++)
8590 if(TempCCk == priv->cck_txbbgain_table[i].ccktxbb_valuearray[0])
8592 priv->cck_present_attentuation_20Mdefault=(u8) i;
8593 break;
8596 priv->cck_present_attentuation_40Mdefault= 0;
8597 priv->cck_present_attentuation_difference= 0;
8598 priv->cck_present_attentuation = priv->cck_present_attentuation_20Mdefault;
8600 // pMgntInfo->bTXPowerTracking = FALSE;//TEMPLY DISABLE
8603 write_nic_byte(dev, 0x87, 0x0);
8606 #endif
8607 return init_status;
8610 #endif
8611 /* this configures registers for beacon tx and enables it via
8612 * rtl8192_beacon_tx_enable(). rtl8192_beacon_tx_disable() might
8613 * be used to stop beacon transmission
8615 #if 0
8616 void rtl8192_start_tx_beacon(struct net_device *dev)
8618 int i;
8619 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
8620 u16 word;
8621 DMESG("Enabling beacon TX");
8622 //write_nic_byte(dev, TX_CONF,0xe6);// TX_CONF
8623 //rtl8192_init_beacon(dev);
8624 //set_nic_txring(dev);
8625 // rtl8192_prepare_beacon(dev);
8626 rtl8192_irq_disable(dev);
8627 // rtl8192_beacon_tx_enable(dev);
8628 rtl8192_set_mode(dev,EPROM_CMD_CONFIG);
8629 //write_nic_byte(dev,0x9d,0x20); //DMA Poll
8630 //write_nic_word(dev,0x7a,0);
8631 //write_nic_word(dev,0x7a,0x8000);
8634 word = read_nic_word(dev, BcnItv);
8635 word &= ~BcnItv_BcnItv; // clear Bcn_Itv
8636 write_nic_word(dev, BcnItv, word);
8638 write_nic_word(dev, AtimWnd,
8639 read_nic_word(dev, AtimWnd) &~ AtimWnd_AtimWnd);
8641 word = read_nic_word(dev, BCN_INTR_ITV);
8642 word &= ~BCN_INTR_ITV_MASK;
8644 //word |= priv->ieee80211->beacon_interval *
8645 // ((priv->txbeaconcount > 1)?(priv->txbeaconcount-1):1);
8646 // FIXME:FIXME check if correct ^^ worked with 0x3e8;
8648 write_nic_word(dev, BCN_INTR_ITV, word);
8650 //write_nic_word(dev,0x2e,0xe002);
8651 //write_nic_dword(dev,0x30,0xb8c7832e);
8652 for(i=0; i<ETH_ALEN; i++)
8653 write_nic_byte(dev, BSSID+i, priv->ieee80211->beacon_cell_ssid[i]);
8655 // rtl8192_update_msr(dev);
8658 //write_nic_byte(dev,CONFIG4,3); /* !!!!!!!!!! */
8660 rtl8192_set_mode(dev, EPROM_CMD_NORMAL);
8662 rtl8192_irq_enable(dev);
8664 /* VV !!!!!!!!!! VV*/
8666 rtl8192_set_mode(dev,EPROM_CMD_CONFIG);
8667 write_nic_byte(dev,0x9d,0x00);
8668 rtl8192_set_mode(dev,EPROM_CMD_NORMAL);
8671 #endif
8672 /***************************************************************************
8673 -------------------------------NET STUFF---------------------------
8674 ***************************************************************************/
8676 static struct net_device_stats *rtl8192_stats(struct net_device *dev)
8678 struct r8192_priv *priv = ieee80211_priv(dev);
8680 return &priv->ieee80211->stats;
8683 bool
8684 HalTxCheckStuck819xUsb(
8685 struct net_device *dev
8688 struct r8192_priv *priv = ieee80211_priv(dev);
8689 u16 RegTxCounter = read_nic_word(dev, 0x128);
8690 bool bStuck = FALSE;
8691 RT_TRACE(COMP_RESET,"%s():RegTxCounter is %d,TxCounter is %d\n",__FUNCTION__,RegTxCounter,priv->TxCounter);
8692 if(priv->TxCounter==RegTxCounter)
8693 bStuck = TRUE;
8695 priv->TxCounter = RegTxCounter;
8697 return bStuck;
8701 * <Assumption: RT_TX_SPINLOCK is acquired.>
8702 * First added: 2006.11.19 by emily
8704 RESET_TYPE
8705 TxCheckStuck(struct net_device *dev)
8707 struct r8192_priv *priv = ieee80211_priv(dev);
8708 u8 QueueID;
8709 // PRT_TCB pTcb;
8710 // u8 ResetThreshold;
8711 bool bCheckFwTxCnt = false;
8712 //unsigned long flags;
8715 // Decide Stuch threshold according to current power save mode
8718 // RT_TRACE(COMP_RESET, " ==> TxCheckStuck()\n");
8719 // PlatformAcquireSpinLock(Adapter, RT_TX_SPINLOCK);
8720 // spin_lock_irqsave(&priv->ieee80211->lock,flags);
8721 for (QueueID = 0; QueueID<=BEACON_QUEUE;QueueID ++)
8723 if(QueueID == TXCMD_QUEUE)
8724 continue;
8725 #if 1
8726 #ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
8727 if((skb_queue_len(&priv->ieee80211->skb_waitQ[QueueID]) == 0) && (skb_queue_len(&priv->ieee80211->skb_aggQ[QueueID]) == 0) && (skb_queue_len(&priv->ieee80211->skb_drv_aggQ[QueueID]) == 0))
8728 #else
8729 if((skb_queue_len(&priv->ieee80211->skb_waitQ[QueueID]) == 0) && (skb_queue_len(&priv->ieee80211->skb_aggQ[QueueID]) == 0))
8730 #endif
8731 continue;
8732 #endif
8734 bCheckFwTxCnt = true;
8736 // PlatformReleaseSpinLock(Adapter, RT_TX_SPINLOCK);
8737 // spin_unlock_irqrestore(&priv->ieee80211->lock,flags);
8738 // RT_TRACE(COMP_RESET,"bCheckFwTxCnt is %d\n",bCheckFwTxCnt);
8739 #if 1
8740 if(bCheckFwTxCnt)
8742 if(HalTxCheckStuck819xUsb(dev))
8744 RT_TRACE(COMP_RESET, "TxCheckStuck(): Fw indicates no Tx condition! \n");
8745 return RESET_TYPE_SILENT;
8748 #endif
8749 return RESET_TYPE_NORESET;
8752 bool
8753 HalRxCheckStuck819xUsb(struct net_device *dev)
8755 u16 RegRxCounter = read_nic_word(dev, 0x130);
8756 struct r8192_priv *priv = ieee80211_priv(dev);
8757 bool bStuck = FALSE;
8758 //#ifdef RTL8192SU
8760 //#else
8761 static u8 rx_chk_cnt = 0;
8762 RT_TRACE(COMP_RESET,"%s(): RegRxCounter is %d,RxCounter is %d\n",__FUNCTION__,RegRxCounter,priv->RxCounter);
8763 // If rssi is small, we should check rx for long time because of bad rx.
8764 // or maybe it will continuous silent reset every 2 seconds.
8765 rx_chk_cnt++;
8766 if(priv->undecorated_smoothed_pwdb >= (RateAdaptiveTH_High+5))
8768 rx_chk_cnt = 0; //high rssi, check rx stuck right now.
8770 else if(priv->undecorated_smoothed_pwdb < (RateAdaptiveTH_High+5) &&
8771 ((priv->CurrentChannelBW!=HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb>=RateAdaptiveTH_Low_40M) ||
8772 (priv->CurrentChannelBW==HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb>=RateAdaptiveTH_Low_20M)) )
8774 if(rx_chk_cnt < 2)
8776 return bStuck;
8778 else
8780 rx_chk_cnt = 0;
8783 else if(((priv->CurrentChannelBW!=HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb<RateAdaptiveTH_Low_40M) ||
8784 (priv->CurrentChannelBW==HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb<RateAdaptiveTH_Low_20M)) &&
8785 priv->undecorated_smoothed_pwdb >= VeryLowRSSI)
8787 if(rx_chk_cnt < 4)
8789 //DbgPrint("RSSI < %d && RSSI >= %d, no check this time \n", RateAdaptiveTH_Low, VeryLowRSSI);
8790 return bStuck;
8792 else
8794 rx_chk_cnt = 0;
8795 //DbgPrint("RSSI < %d && RSSI >= %d, check this time \n", RateAdaptiveTH_Low, VeryLowRSSI);
8798 else
8800 if(rx_chk_cnt < 8)
8802 //DbgPrint("RSSI <= %d, no check this time \n", VeryLowRSSI);
8803 return bStuck;
8805 else
8807 rx_chk_cnt = 0;
8808 //DbgPrint("RSSI <= %d, check this time \n", VeryLowRSSI);
8811 //#endif
8813 if(priv->RxCounter==RegRxCounter)
8814 bStuck = TRUE;
8816 priv->RxCounter = RegRxCounter;
8818 return bStuck;
8821 RESET_TYPE
8822 RxCheckStuck(struct net_device *dev)
8824 struct r8192_priv *priv = ieee80211_priv(dev);
8825 //int i;
8826 bool bRxCheck = FALSE;
8828 // RT_TRACE(COMP_RESET," ==> RxCheckStuck()\n");
8829 //PlatformAcquireSpinLock(Adapter, RT_RX_SPINLOCK);
8831 if(priv->IrpPendingCount > 1)
8832 bRxCheck = TRUE;
8833 //PlatformReleaseSpinLock(Adapter, RT_RX_SPINLOCK);
8835 // RT_TRACE(COMP_RESET,"bRxCheck is %d \n",bRxCheck);
8836 if(bRxCheck)
8838 if(HalRxCheckStuck819xUsb(dev))
8840 RT_TRACE(COMP_RESET, "RxStuck Condition\n");
8841 return RESET_TYPE_SILENT;
8844 return RESET_TYPE_NORESET;
8849 * This function is called by Checkforhang to check whether we should ask OS to reset driver
8851 * \param pAdapter The adapter context for this miniport
8853 * Note:NIC with USB interface sholud not call this function because we cannot scan descriptor
8854 * to judge whether there is tx stuck.
8855 * Note: This function may be required to be rewrite for Vista OS.
8856 * <<<Assumption: Tx spinlock has been acquired >>>
8858 * 8185 and 8185b does not implement this function. This is added by Emily at 2006.11.24
8860 RESET_TYPE
8861 rtl819x_ifcheck_resetornot(struct net_device *dev)
8863 struct r8192_priv *priv = ieee80211_priv(dev);
8864 RESET_TYPE TxResetType = RESET_TYPE_NORESET;
8865 RESET_TYPE RxResetType = RESET_TYPE_NORESET;
8866 RT_RF_POWER_STATE rfState;
8868 #if (defined (RTL8192SU_FPGA_2MAC_VERIFICATION)||defined (RTL8192SU_ASIC_VERIFICATION))
8869 return RESET_TYPE_NORESET;
8870 #endif
8872 rfState = priv->ieee80211->eRFPowerState;
8874 TxResetType = TxCheckStuck(dev);
8875 #if 1
8876 if( rfState != eRfOff ||
8877 /*ADAPTER_TEST_STATUS_FLAG(Adapter, ADAPTER_STATUS_FW_DOWNLOAD_FAILURE)) &&*/
8878 (priv->ieee80211->iw_mode != IW_MODE_ADHOC))
8880 // If driver is in the status of firmware download failure , driver skips RF initialization and RF is
8881 // in turned off state. Driver should check whether Rx stuck and do silent reset. And
8882 // if driver is in firmware download failure status, driver should initialize RF in the following
8883 // silent reset procedure Emily, 2008.01.21
8885 // Driver should not check RX stuck in IBSS mode because it is required to
8886 // set Check BSSID in order to send beacon, however, if check BSSID is
8887 // set, STA cannot hear any packet a all. Emily, 2008.04.12
8888 RxResetType = RxCheckStuck(dev);
8890 #endif
8891 if(TxResetType==RESET_TYPE_NORMAL || RxResetType==RESET_TYPE_NORMAL)
8892 return RESET_TYPE_NORMAL;
8893 else if(TxResetType==RESET_TYPE_SILENT || RxResetType==RESET_TYPE_SILENT){
8894 RT_TRACE(COMP_RESET,"%s():silent reset\n",__FUNCTION__);
8895 return RESET_TYPE_SILENT;
8897 else
8898 return RESET_TYPE_NORESET;
8902 void rtl8192_cancel_deferred_work(struct r8192_priv* priv);
8903 int _rtl8192_up(struct net_device *dev);
8904 int rtl8192_close(struct net_device *dev);
8908 void
8909 CamRestoreAllEntry( struct net_device *dev)
8911 u8 EntryId = 0;
8912 struct r8192_priv *priv = ieee80211_priv(dev);
8913 u8* MacAddr = priv->ieee80211->current_network.bssid;
8915 static u8 CAM_CONST_ADDR[4][6] = {
8916 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
8917 {0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
8918 {0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
8919 {0x00, 0x00, 0x00, 0x00, 0x00, 0x03}};
8920 static u8 CAM_CONST_BROAD[] =
8921 {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
8923 RT_TRACE(COMP_SEC, "CamRestoreAllEntry: \n");
8926 if ((priv->ieee80211->pairwise_key_type == KEY_TYPE_WEP40)||
8927 (priv->ieee80211->pairwise_key_type == KEY_TYPE_WEP104))
8930 for(EntryId=0; EntryId<4; EntryId++)
8933 MacAddr = CAM_CONST_ADDR[EntryId];
8934 setKey(dev,
8935 EntryId ,
8936 EntryId,
8937 priv->ieee80211->pairwise_key_type,
8938 MacAddr,
8940 NULL);
8945 else if(priv->ieee80211->pairwise_key_type == KEY_TYPE_TKIP)
8949 if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
8950 setKey(dev,
8953 priv->ieee80211->pairwise_key_type,
8954 (u8*)dev->dev_addr,
8956 NULL);
8957 else
8958 setKey(dev,
8961 priv->ieee80211->pairwise_key_type,
8962 MacAddr,
8964 NULL);
8967 else if(priv->ieee80211->pairwise_key_type == KEY_TYPE_CCMP)
8971 if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
8972 setKey(dev,
8975 priv->ieee80211->pairwise_key_type,
8976 (u8*)dev->dev_addr,
8978 NULL);
8979 else
8980 setKey(dev,
8983 priv->ieee80211->pairwise_key_type,
8984 MacAddr,
8986 NULL);
8992 if(priv->ieee80211->group_key_type == KEY_TYPE_TKIP)
8994 MacAddr = CAM_CONST_BROAD;
8995 for(EntryId=1 ; EntryId<4 ; EntryId++)
8998 setKey(dev,
8999 EntryId,
9000 EntryId,
9001 priv->ieee80211->group_key_type,
9002 MacAddr,
9004 NULL);
9007 if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
9008 setKey(dev,
9011 priv->ieee80211->group_key_type,
9012 CAM_CONST_ADDR[0],
9014 NULL);
9016 else if(priv->ieee80211->group_key_type == KEY_TYPE_CCMP)
9018 MacAddr = CAM_CONST_BROAD;
9019 for(EntryId=1; EntryId<4 ; EntryId++)
9022 setKey(dev,
9023 EntryId ,
9024 EntryId,
9025 priv->ieee80211->group_key_type,
9026 MacAddr,
9028 NULL);
9032 if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
9033 setKey(dev,
9036 priv->ieee80211->group_key_type,
9037 CAM_CONST_ADDR[0],
9039 NULL);
9042 //////////////////////////////////////////////////////////////
9043 // This function is used to fix Tx/Rx stop bug temporarily.
9044 // This function will do "system reset" to NIC when Tx or Rx is stuck.
9045 // The method checking Tx/Rx stuck of this function is supported by FW,
9046 // which reports Tx and Rx counter to register 0x128 and 0x130.
9047 //////////////////////////////////////////////////////////////
9048 void
9049 rtl819x_ifsilentreset(struct net_device *dev)
9051 //OCTET_STRING asocpdu;
9052 struct r8192_priv *priv = ieee80211_priv(dev);
9053 u8 reset_times = 0;
9054 int reset_status = 0;
9055 struct ieee80211_device *ieee = priv->ieee80211;
9058 // 2007.07.20. If we need to check CCK stop, please uncomment this line.
9059 //bStuck = Adapter->HalFunc.CheckHWStopHandler(Adapter);
9061 if(priv->ResetProgress==RESET_TYPE_NORESET)
9063 RESET_START:
9065 RT_TRACE(COMP_RESET,"=========>Reset progress!! \n");
9067 // Set the variable for reset.
9068 priv->ResetProgress = RESET_TYPE_SILENT;
9069 // rtl8192_close(dev);
9070 #if 1
9071 down(&priv->wx_sem);
9072 if(priv->up == 0)
9074 RT_TRACE(COMP_ERR,"%s():the driver is not up! return\n",__FUNCTION__);
9075 up(&priv->wx_sem);
9076 return ;
9078 priv->up = 0;
9079 RT_TRACE(COMP_RESET,"%s():======>start to down the driver\n",__FUNCTION__);
9080 // if(!netif_queue_stopped(dev))
9081 // netif_stop_queue(dev);
9083 rtl8192_rtx_disable(dev);
9084 rtl8192_cancel_deferred_work(priv);
9085 deinit_hal_dm(dev);
9086 del_timer_sync(&priv->watch_dog_timer);
9088 ieee->sync_scan_hurryup = 1;
9089 if(ieee->state == IEEE80211_LINKED)
9091 down(&ieee->wx_sem);
9092 printk("ieee->state is IEEE80211_LINKED\n");
9093 ieee80211_stop_send_beacons(priv->ieee80211);
9094 del_timer_sync(&ieee->associate_timer);
9095 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
9096 cancel_delayed_work(&ieee->associate_retry_wq);
9097 #endif
9098 ieee80211_stop_scan(ieee);
9099 netif_carrier_off(dev);
9100 up(&ieee->wx_sem);
9102 else{
9103 printk("ieee->state is NOT LINKED\n");
9104 ieee80211_softmac_stop_protocol(priv->ieee80211); }
9105 up(&priv->wx_sem);
9106 RT_TRACE(COMP_RESET,"%s():<==========down process is finished\n",__FUNCTION__);
9107 //rtl8192_irq_disable(dev);
9108 RT_TRACE(COMP_RESET,"%s():===========>start to up the driver\n",__FUNCTION__);
9109 reset_status = _rtl8192_up(dev);
9111 RT_TRACE(COMP_RESET,"%s():<===========up process is finished\n",__FUNCTION__);
9112 if(reset_status == -EAGAIN)
9114 if(reset_times < 3)
9116 reset_times++;
9117 goto RESET_START;
9119 else
9121 RT_TRACE(COMP_ERR," ERR!!! %s(): Reset Failed!!\n", __FUNCTION__);
9124 #endif
9125 ieee->is_silent_reset = 1;
9126 #if 1
9127 EnableHWSecurityConfig8192(dev);
9128 #if 1
9129 if(ieee->state == IEEE80211_LINKED && ieee->iw_mode == IW_MODE_INFRA)
9131 ieee->set_chan(ieee->dev, ieee->current_network.channel);
9133 #if 1
9134 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
9135 queue_work(ieee->wq, &ieee->associate_complete_wq);
9136 #else
9137 schedule_task(&ieee->associate_complete_wq);
9138 #endif
9139 #endif
9142 else if(ieee->state == IEEE80211_LINKED && ieee->iw_mode == IW_MODE_ADHOC)
9144 ieee->set_chan(ieee->dev, ieee->current_network.channel);
9145 ieee->link_change(ieee->dev);
9147 // notify_wx_assoc_event(ieee);
9149 ieee80211_start_send_beacons(ieee);
9151 if (ieee->data_hard_resume)
9152 ieee->data_hard_resume(ieee->dev);
9153 netif_carrier_on(ieee->dev);
9155 #endif
9157 CamRestoreAllEntry(dev);
9159 priv->ResetProgress = RESET_TYPE_NORESET;
9160 priv->reset_count++;
9162 priv->bForcedSilentReset =false;
9163 priv->bResetInProgress = false;
9165 // For test --> force write UFWP.
9166 write_nic_byte(dev, UFWP, 1);
9167 RT_TRACE(COMP_RESET, "Reset finished!! ====>[%d]\n", priv->reset_count);
9168 #endif
9172 void CAM_read_entry(
9173 struct net_device *dev,
9174 u32 iIndex
9177 u32 target_command=0;
9178 u32 target_content=0;
9179 u8 entry_i=0;
9180 u32 ulStatus;
9181 s32 i=100;
9182 // printk("=======>start read CAM\n");
9183 for(entry_i=0;entry_i<CAM_CONTENT_COUNT;entry_i++)
9185 // polling bit, and No Write enable, and address
9186 target_command= entry_i+CAM_CONTENT_COUNT*iIndex;
9187 target_command= target_command | BIT31;
9189 //Check polling bit is clear
9190 // mdelay(1);
9191 #if 1
9192 while((i--)>=0)
9194 ulStatus = read_nic_dword(dev, RWCAM);
9195 if(ulStatus & BIT31){
9196 continue;
9198 else{
9199 break;
9202 #endif
9203 write_nic_dword(dev, RWCAM, target_command);
9204 RT_TRACE(COMP_SEC,"CAM_read_entry(): WRITE A0: %x \n",target_command);
9205 // printk("CAM_read_entry(): WRITE A0: %lx \n",target_command);
9206 target_content = read_nic_dword(dev, RCAMO);
9207 RT_TRACE(COMP_SEC, "CAM_read_entry(): WRITE A8: %x \n",target_content);
9208 // printk("CAM_read_entry(): WRITE A8: %lx \n",target_content);
9210 printk("\n");
9213 void rtl819x_update_rxcounts(
9214 struct r8192_priv *priv,
9215 u32* TotalRxBcnNum,
9216 u32* TotalRxDataNum
9219 u16 SlotIndex;
9220 u8 i;
9222 *TotalRxBcnNum = 0;
9223 *TotalRxDataNum = 0;
9225 SlotIndex = (priv->ieee80211->LinkDetectInfo.SlotIndex++)%(priv->ieee80211->LinkDetectInfo.SlotNum);
9226 priv->ieee80211->LinkDetectInfo.RxBcnNum[SlotIndex] = priv->ieee80211->LinkDetectInfo.NumRecvBcnInPeriod;
9227 priv->ieee80211->LinkDetectInfo.RxDataNum[SlotIndex] = priv->ieee80211->LinkDetectInfo.NumRecvDataInPeriod;
9228 for( i=0; i<priv->ieee80211->LinkDetectInfo.SlotNum; i++ ){
9229 *TotalRxBcnNum += priv->ieee80211->LinkDetectInfo.RxBcnNum[i];
9230 *TotalRxDataNum += priv->ieee80211->LinkDetectInfo.RxDataNum[i];
9235 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
9236 extern void rtl819x_watchdog_wqcallback(struct work_struct *work)
9238 struct delayed_work *dwork = container_of(work,struct delayed_work,work);
9239 struct r8192_priv *priv = container_of(dwork,struct r8192_priv,watch_dog_wq);
9240 struct net_device *dev = priv->ieee80211->dev;
9241 #else
9242 extern void rtl819x_watchdog_wqcallback(struct net_device *dev)
9244 struct r8192_priv *priv = ieee80211_priv(dev);
9245 #endif
9246 struct ieee80211_device* ieee = priv->ieee80211;
9247 RESET_TYPE ResetType = RESET_TYPE_NORESET;
9248 static u8 check_reset_cnt=0;
9249 bool bBusyTraffic = false;
9251 if(!priv->up)
9252 return;
9253 hal_dm_watchdog(dev);
9255 {//to get busy traffic condition
9256 if(ieee->state == IEEE80211_LINKED)
9258 //windows mod 666 to 100.
9259 //if( ieee->LinkDetectInfo.NumRxOkInPeriod> 666 ||
9260 // ieee->LinkDetectInfo.NumTxOkInPeriod> 666 ) {
9261 if( ieee->LinkDetectInfo.NumRxOkInPeriod> 100 ||
9262 ieee->LinkDetectInfo.NumTxOkInPeriod> 100 ) {
9263 bBusyTraffic = true;
9265 ieee->LinkDetectInfo.NumRxOkInPeriod = 0;
9266 ieee->LinkDetectInfo.NumTxOkInPeriod = 0;
9267 ieee->LinkDetectInfo.bBusyTraffic = bBusyTraffic;
9270 //added by amy for AP roaming
9272 if(priv->ieee80211->state == IEEE80211_LINKED && priv->ieee80211->iw_mode == IW_MODE_INFRA)
9274 u32 TotalRxBcnNum = 0;
9275 u32 TotalRxDataNum = 0;
9277 rtl819x_update_rxcounts(priv, &TotalRxBcnNum, &TotalRxDataNum);
9278 if((TotalRxBcnNum+TotalRxDataNum) == 0)
9280 #ifdef TODO
9281 if(rfState == eRfOff)
9282 RT_TRACE(COMP_ERR,"========>%s()\n",__FUNCTION__);
9283 #endif
9284 printk("===>%s(): AP is power off,connect another one\n",__FUNCTION__);
9285 // Dot11d_Reset(dev);
9286 priv->ieee80211->state = IEEE80211_ASSOCIATING;
9287 notify_wx_assoc_event(priv->ieee80211);
9288 RemovePeerTS(priv->ieee80211,priv->ieee80211->current_network.bssid);
9289 ieee->is_roaming = true;
9290 priv->ieee80211->link_change(dev);
9291 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
9292 queue_work(priv->ieee80211->wq, &priv->ieee80211->associate_procedure_wq);
9293 #else
9294 schedule_task(&priv->ieee80211->associate_procedure_wq);
9295 #endif
9299 priv->ieee80211->LinkDetectInfo.NumRecvBcnInPeriod=0;
9300 priv->ieee80211->LinkDetectInfo.NumRecvDataInPeriod=0;
9302 // CAM_read_entry(dev,4);
9303 //check if reset the driver
9304 if(check_reset_cnt++ >= 3 && !ieee->is_roaming)
9306 ResetType = rtl819x_ifcheck_resetornot(dev);
9307 check_reset_cnt = 3;
9308 //DbgPrint("Start to check silent reset\n");
9310 // RT_TRACE(COMP_RESET,"%s():priv->force_reset is %d,priv->ResetProgress is %d, priv->bForcedSilentReset is %d,priv->bDisableNormalResetCheck is %d,ResetType is %d\n",__FUNCTION__,priv->force_reset,priv->ResetProgress,priv->bForcedSilentReset,priv->bDisableNormalResetCheck,ResetType);
9311 #if 1
9312 if( (priv->force_reset) || (priv->ResetProgress==RESET_TYPE_NORESET &&
9313 (priv->bForcedSilentReset ||
9314 (!priv->bDisableNormalResetCheck && ResetType==RESET_TYPE_SILENT)))) // This is control by OID set in Pomelo
9316 RT_TRACE(COMP_RESET,"%s():priv->force_reset is %d,priv->ResetProgress is %d, priv->bForcedSilentReset is %d,priv->bDisableNormalResetCheck is %d,ResetType is %d\n",__FUNCTION__,priv->force_reset,priv->ResetProgress,priv->bForcedSilentReset,priv->bDisableNormalResetCheck,ResetType);
9317 rtl819x_ifsilentreset(dev);
9319 #endif
9320 priv->force_reset = false;
9321 priv->bForcedSilentReset = false;
9322 priv->bResetInProgress = false;
9323 RT_TRACE(COMP_TRACE, " <==RtUsbCheckForHangWorkItemCallback()\n");
9327 void watch_dog_timer_callback(unsigned long data)
9329 struct r8192_priv *priv = ieee80211_priv((struct net_device *) data);
9330 //printk("===============>watch_dog timer\n");
9331 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
9332 queue_delayed_work(priv->priv_wq,&priv->watch_dog_wq, 0);
9333 #else
9334 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
9335 schedule_task(&priv->watch_dog_wq);
9336 #else
9337 queue_work(priv->priv_wq,&priv->watch_dog_wq);
9338 #endif
9339 #endif
9340 mod_timer(&priv->watch_dog_timer, jiffies + MSECS(IEEE80211_WATCH_DOG_TIME));
9341 #if 0
9342 priv->watch_dog_timer.expires = jiffies + MSECS(IEEE80211_WATCH_DOG_TIME);
9343 add_timer(&priv->watch_dog_timer);
9344 #endif
9346 int _rtl8192_up(struct net_device *dev)
9348 struct r8192_priv *priv = ieee80211_priv(dev);
9349 //int i;
9350 int init_status = 0;
9351 priv->up=1;
9352 priv->ieee80211->ieee_up=1;
9353 RT_TRACE(COMP_INIT, "Bringing up iface");
9354 init_status = priv->ops->rtl819x_adapter_start(dev);
9355 if(!init_status)
9357 RT_TRACE(COMP_ERR,"ERR!!! %s(): initialization is failed!\n", __FUNCTION__);
9358 priv->up=priv->ieee80211->ieee_up = 0;
9359 return -EAGAIN;
9361 RT_TRACE(COMP_INIT, "start adapter finished\n");
9362 rtl8192_rx_enable(dev);
9363 // rtl8192_tx_enable(dev);
9364 if(priv->ieee80211->state != IEEE80211_LINKED)
9365 ieee80211_softmac_start_protocol(priv->ieee80211);
9366 ieee80211_reset_queue(priv->ieee80211);
9367 watch_dog_timer_callback((unsigned long) dev);
9368 if(!netif_queue_stopped(dev))
9369 netif_start_queue(dev);
9370 else
9371 netif_wake_queue(dev);
9374 * Make sure that drop_unencrypted is initialized as "0"
9375 * No packets will be sent in non-security mode if we had set drop_unencrypted.
9376 * ex, After kill wpa_supplicant process, make the driver up again.
9377 * drop_unencrypted remains as "1", which is set by wpa_supplicant. 2008/12/04.john
9379 priv->ieee80211->drop_unencrypted = 0;
9381 return 0;
9385 int rtl8192_open(struct net_device *dev)
9387 struct r8192_priv *priv = ieee80211_priv(dev);
9388 int ret;
9389 down(&priv->wx_sem);
9390 ret = rtl8192_up(dev);
9391 up(&priv->wx_sem);
9392 return ret;
9397 int rtl8192_up(struct net_device *dev)
9399 struct r8192_priv *priv = ieee80211_priv(dev);
9401 if (priv->up == 1) return -1;
9403 return _rtl8192_up(dev);
9407 int rtl8192_close(struct net_device *dev)
9409 struct r8192_priv *priv = ieee80211_priv(dev);
9410 int ret;
9412 down(&priv->wx_sem);
9414 ret = rtl8192_down(dev);
9416 up(&priv->wx_sem);
9418 return ret;
9422 int rtl8192_down(struct net_device *dev)
9424 struct r8192_priv *priv = ieee80211_priv(dev);
9425 int i;
9427 if (priv->up == 0) return -1;
9429 priv->up=0;
9430 priv->ieee80211->ieee_up = 0;
9431 RT_TRACE(COMP_DOWN, "==========>%s()\n", __FUNCTION__);
9432 /* FIXME */
9433 if (!netif_queue_stopped(dev))
9434 netif_stop_queue(dev);
9436 rtl8192_rtx_disable(dev);
9437 //rtl8192_irq_disable(dev);
9439 /* Tx related queue release */
9440 for(i = 0; i < MAX_QUEUE_SIZE; i++) {
9441 skb_queue_purge(&priv->ieee80211->skb_waitQ [i]);
9443 for(i = 0; i < MAX_QUEUE_SIZE; i++) {
9444 skb_queue_purge(&priv->ieee80211->skb_aggQ [i]);
9447 for(i = 0; i < MAX_QUEUE_SIZE; i++) {
9448 skb_queue_purge(&priv->ieee80211->skb_drv_aggQ [i]);
9451 //as cancel_delayed_work will del work->timer, so if work is not definedas struct delayed_work, it will corrupt
9452 // flush_scheduled_work();
9453 rtl8192_cancel_deferred_work(priv);
9454 deinit_hal_dm(dev);
9455 del_timer_sync(&priv->watch_dog_timer);
9458 ieee80211_softmac_stop_protocol(priv->ieee80211);
9459 memset(&priv->ieee80211->current_network, 0 , offsetof(struct ieee80211_network, list));
9460 RT_TRACE(COMP_DOWN, "<==========%s()\n", __FUNCTION__);
9462 return 0;
9466 void rtl8192_commit(struct net_device *dev)
9468 struct r8192_priv *priv = ieee80211_priv(dev);
9469 int reset_status = 0;
9470 //u8 reset_times = 0;
9471 if (priv->up == 0) return ;
9472 priv->up = 0;
9474 rtl8192_cancel_deferred_work(priv);
9475 del_timer_sync(&priv->watch_dog_timer);
9476 //cancel_delayed_work(&priv->SwChnlWorkItem);
9478 ieee80211_softmac_stop_protocol(priv->ieee80211);
9480 //rtl8192_irq_disable(dev);
9481 rtl8192_rtx_disable(dev);
9482 reset_status = _rtl8192_up(dev);
9487 void rtl8192_restart(struct net_device *dev)
9489 struct r8192_priv *priv = ieee80211_priv(dev);
9491 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
9492 void rtl8192_restart(struct work_struct *work)
9494 struct r8192_priv *priv = container_of(work, struct r8192_priv, reset_wq);
9495 struct net_device *dev = priv->ieee80211->dev;
9496 #else
9497 void rtl8192_restart(struct net_device *dev)
9500 struct r8192_priv *priv = ieee80211_priv(dev);
9501 #endif
9503 down(&priv->wx_sem);
9505 rtl8192_commit(dev);
9507 up(&priv->wx_sem);
9510 static void r8192_set_multicast(struct net_device *dev)
9512 struct r8192_priv *priv = ieee80211_priv(dev);
9513 short promisc;
9515 //down(&priv->wx_sem);
9517 /* FIXME FIXME */
9519 promisc = (dev->flags & IFF_PROMISC) ? 1:0;
9521 if (promisc != priv->promisc)
9522 // rtl8192_commit(dev);
9524 priv->promisc = promisc;
9526 //schedule_work(&priv->reset_wq);
9527 //up(&priv->wx_sem);
9531 int r8192_set_mac_adr(struct net_device *dev, void *mac)
9533 struct r8192_priv *priv = ieee80211_priv(dev);
9534 struct sockaddr *addr = mac;
9536 down(&priv->wx_sem);
9538 memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
9540 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
9541 schedule_work(&priv->reset_wq);
9542 #else
9543 schedule_task(&priv->reset_wq);
9544 #endif
9545 up(&priv->wx_sem);
9547 return 0;
9550 /* based on ipw2200 driver */
9551 int rtl8192_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
9553 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
9554 struct iwreq *wrq = (struct iwreq *)rq;
9555 int ret=-1;
9556 struct ieee80211_device *ieee = priv->ieee80211;
9557 u32 key[4];
9558 u8 broadcast_addr[6] = {0xff,0xff,0xff,0xff,0xff,0xff};
9559 u8 zero_addr[6] = {0};
9560 struct iw_point *p = &wrq->u.data;
9561 struct ieee_param *ipw = NULL;//(struct ieee_param *)wrq->u.data.pointer;
9563 down(&priv->wx_sem);
9566 if (p->length < sizeof(struct ieee_param) || !p->pointer){
9567 ret = -EINVAL;
9568 goto out;
9571 ipw = (struct ieee_param *)kmalloc(p->length, GFP_KERNEL);
9572 if (ipw == NULL){
9573 ret = -ENOMEM;
9574 goto out;
9576 if (copy_from_user(ipw, p->pointer, p->length)) {
9577 kfree(ipw);
9578 ret = -EFAULT;
9579 goto out;
9582 switch (cmd) {
9583 case RTL_IOCTL_WPA_SUPPLICANT:
9584 //parse here for HW security
9585 if (ipw->cmd == IEEE_CMD_SET_ENCRYPTION)
9587 if (ipw->u.crypt.set_tx)
9589 if (strcmp(ipw->u.crypt.alg, "CCMP") == 0)
9590 ieee->pairwise_key_type = KEY_TYPE_CCMP;
9591 else if (strcmp(ipw->u.crypt.alg, "TKIP") == 0)
9592 ieee->pairwise_key_type = KEY_TYPE_TKIP;
9593 else if (strcmp(ipw->u.crypt.alg, "WEP") == 0)
9595 if (ipw->u.crypt.key_len == 13)
9596 ieee->pairwise_key_type = KEY_TYPE_WEP104;
9597 else if (ipw->u.crypt.key_len == 5)
9598 ieee->pairwise_key_type = KEY_TYPE_WEP40;
9600 else
9601 ieee->pairwise_key_type = KEY_TYPE_NA;
9603 if (ieee->pairwise_key_type)
9605 // 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
9606 if (memcmp(ieee->ap_mac_addr, zero_addr, 6) == 0)
9607 ieee->iw_mode = IW_MODE_ADHOC;
9608 memcpy((u8*)key, ipw->u.crypt.key, 16);
9609 EnableHWSecurityConfig8192(dev);
9610 //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!
9611 //added by WB.
9612 setKey(dev, 4, ipw->u.crypt.idx, ieee->pairwise_key_type, (u8*)ieee->ap_mac_addr, 0, key);
9613 if (ieee->iw_mode == IW_MODE_ADHOC)
9614 setKey(dev, ipw->u.crypt.idx, ipw->u.crypt.idx, ieee->pairwise_key_type, (u8*)ieee->ap_mac_addr, 0, key);
9617 else //if (ipw->u.crypt.idx) //group key use idx > 0
9619 memcpy((u8*)key, ipw->u.crypt.key, 16);
9620 if (strcmp(ipw->u.crypt.alg, "CCMP") == 0)
9621 ieee->group_key_type= KEY_TYPE_CCMP;
9622 else if (strcmp(ipw->u.crypt.alg, "TKIP") == 0)
9623 ieee->group_key_type = KEY_TYPE_TKIP;
9624 else if (strcmp(ipw->u.crypt.alg, "WEP") == 0)
9626 if (ipw->u.crypt.key_len == 13)
9627 ieee->group_key_type = KEY_TYPE_WEP104;
9628 else if (ipw->u.crypt.key_len == 5)
9629 ieee->group_key_type = KEY_TYPE_WEP40;
9631 else
9632 ieee->group_key_type = KEY_TYPE_NA;
9634 if (ieee->group_key_type)
9636 setKey( dev,
9637 ipw->u.crypt.idx,
9638 ipw->u.crypt.idx, //KeyIndex
9639 ieee->group_key_type, //KeyType
9640 broadcast_addr, //MacAddr
9641 0, //DefaultKey
9642 key); //KeyContent
9646 #ifdef JOHN_HWSEC_DEBUG
9647 //john's test 0711
9648 printk("@@ wrq->u pointer = ");
9649 for(i=0;i<wrq->u.data.length;i++){
9650 if(i%10==0) printk("\n");
9651 printk( "%8x|", ((u32*)wrq->u.data.pointer)[i] );
9653 printk("\n");
9654 #endif /*JOHN_HWSEC_DEBUG*/
9655 ret = ieee80211_wpa_supplicant_ioctl(priv->ieee80211, &wrq->u.data);
9656 break;
9658 default:
9659 ret = -EOPNOTSUPP;
9660 break;
9662 kfree(ipw);
9663 ipw = NULL;
9664 out:
9665 up(&priv->wx_sem);
9666 return ret;
9669 #ifdef RTL8192SU
9670 u8 rtl8192SU_HwRateToMRate(bool bIsHT, u8 rate,bool bFirstAMPDU)
9673 u8 ret_rate = 0x02;
9675 if( bFirstAMPDU )
9677 if(!bIsHT)
9679 switch(rate)
9682 case DESC92S_RATE1M: ret_rate = MGN_1M; break;
9683 case DESC92S_RATE2M: ret_rate = MGN_2M; break;
9684 case DESC92S_RATE5_5M: ret_rate = MGN_5_5M; break;
9685 case DESC92S_RATE11M: ret_rate = MGN_11M; break;
9686 case DESC92S_RATE6M: ret_rate = MGN_6M; break;
9687 case DESC92S_RATE9M: ret_rate = MGN_9M; break;
9688 case DESC92S_RATE12M: ret_rate = MGN_12M; break;
9689 case DESC92S_RATE18M: ret_rate = MGN_18M; break;
9690 case DESC92S_RATE24M: ret_rate = MGN_24M; break;
9691 case DESC92S_RATE36M: ret_rate = MGN_36M; break;
9692 case DESC92S_RATE48M: ret_rate = MGN_48M; break;
9693 case DESC92S_RATE54M: ret_rate = MGN_54M; break;
9695 default:
9696 RT_TRACE(COMP_RECV, "HwRateToMRate90(): Non supported Rate [%x], bIsHT = %d!!!\n", rate, bIsHT);
9697 break;
9700 else
9702 switch(rate)
9705 case DESC92S_RATEMCS0: ret_rate = MGN_MCS0; break;
9706 case DESC92S_RATEMCS1: ret_rate = MGN_MCS1; break;
9707 case DESC92S_RATEMCS2: ret_rate = MGN_MCS2; break;
9708 case DESC92S_RATEMCS3: ret_rate = MGN_MCS3; break;
9709 case DESC92S_RATEMCS4: ret_rate = MGN_MCS4; break;
9710 case DESC92S_RATEMCS5: ret_rate = MGN_MCS5; break;
9711 case DESC92S_RATEMCS6: ret_rate = MGN_MCS6; break;
9712 case DESC92S_RATEMCS7: ret_rate = MGN_MCS7; break;
9713 case DESC92S_RATEMCS8: ret_rate = MGN_MCS8; break;
9714 case DESC92S_RATEMCS9: ret_rate = MGN_MCS9; break;
9715 case DESC92S_RATEMCS10: ret_rate = MGN_MCS10; break;
9716 case DESC92S_RATEMCS11: ret_rate = MGN_MCS11; break;
9717 case DESC92S_RATEMCS12: ret_rate = MGN_MCS12; break;
9718 case DESC92S_RATEMCS13: ret_rate = MGN_MCS13; break;
9719 case DESC92S_RATEMCS14: ret_rate = MGN_MCS14; break;
9720 case DESC92S_RATEMCS15: ret_rate = MGN_MCS15; break;
9721 case DESC92S_RATEMCS32: ret_rate = (0x80|0x20); break;
9723 default:
9724 RT_TRACE(COMP_RECV, "HwRateToMRate92S(): Non supported Rate [%x], bIsHT = %d!!!\n",rate, bIsHT );
9725 break;
9730 else
9732 switch(rate)
9735 case DESC92S_RATE1M: ret_rate = MGN_1M; break;
9736 case DESC92S_RATE2M: ret_rate = MGN_2M; break;
9737 case DESC92S_RATE5_5M: ret_rate = MGN_5_5M; break;
9738 case DESC92S_RATE11M: ret_rate = MGN_11M; break;
9739 case DESC92S_RATE6M: ret_rate = MGN_6M; break;
9740 case DESC92S_RATE9M: ret_rate = MGN_9M; break;
9741 case DESC92S_RATE12M: ret_rate = MGN_12M; break;
9742 case DESC92S_RATE18M: ret_rate = MGN_18M; break;
9743 case DESC92S_RATE24M: ret_rate = MGN_24M; break;
9744 case DESC92S_RATE36M: ret_rate = MGN_36M; break;
9745 case DESC92S_RATE48M: ret_rate = MGN_48M; break;
9746 case DESC92S_RATE54M: ret_rate = MGN_54M; break;
9747 case DESC92S_RATEMCS0: ret_rate = MGN_MCS0; break;
9748 case DESC92S_RATEMCS1: ret_rate = MGN_MCS1; break;
9749 case DESC92S_RATEMCS2: ret_rate = MGN_MCS2; break;
9750 case DESC92S_RATEMCS3: ret_rate = MGN_MCS3; break;
9751 case DESC92S_RATEMCS4: ret_rate = MGN_MCS4; break;
9752 case DESC92S_RATEMCS5: ret_rate = MGN_MCS5; break;
9753 case DESC92S_RATEMCS6: ret_rate = MGN_MCS6; break;
9754 case DESC92S_RATEMCS7: ret_rate = MGN_MCS7; break;
9755 case DESC92S_RATEMCS8: ret_rate = MGN_MCS8; break;
9756 case DESC92S_RATEMCS9: ret_rate = MGN_MCS9; break;
9757 case DESC92S_RATEMCS10: ret_rate = MGN_MCS10; break;
9758 case DESC92S_RATEMCS11: ret_rate = MGN_MCS11; break;
9759 case DESC92S_RATEMCS12: ret_rate = MGN_MCS12; break;
9760 case DESC92S_RATEMCS13: ret_rate = MGN_MCS13; break;
9761 case DESC92S_RATEMCS14: ret_rate = MGN_MCS14; break;
9762 case DESC92S_RATEMCS15: ret_rate = MGN_MCS15; break;
9763 case DESC92S_RATEMCS32: ret_rate = (0x80|0x20); break;
9765 default:
9766 RT_TRACE(COMP_RECV, "HwRateToMRate92S(): Non supported Rate [%x], bIsHT = %d!!!\n",rate, bIsHT );
9767 break;
9770 return ret_rate;
9772 #endif
9774 u8 HwRateToMRate90(bool bIsHT, u8 rate)
9776 u8 ret_rate = 0xff;
9778 if(!bIsHT) {
9779 switch(rate) {
9780 case DESC90_RATE1M: ret_rate = MGN_1M; break;
9781 case DESC90_RATE2M: ret_rate = MGN_2M; break;
9782 case DESC90_RATE5_5M: ret_rate = MGN_5_5M; break;
9783 case DESC90_RATE11M: ret_rate = MGN_11M; break;
9784 case DESC90_RATE6M: ret_rate = MGN_6M; break;
9785 case DESC90_RATE9M: ret_rate = MGN_9M; break;
9786 case DESC90_RATE12M: ret_rate = MGN_12M; break;
9787 case DESC90_RATE18M: ret_rate = MGN_18M; break;
9788 case DESC90_RATE24M: ret_rate = MGN_24M; break;
9789 case DESC90_RATE36M: ret_rate = MGN_36M; break;
9790 case DESC90_RATE48M: ret_rate = MGN_48M; break;
9791 case DESC90_RATE54M: ret_rate = MGN_54M; break;
9793 default:
9794 ret_rate = 0xff;
9795 RT_TRACE(COMP_RECV, "HwRateToMRate90(): Non supported Rate [%x], bIsHT = %d!!!\n", rate, bIsHT);
9796 break;
9799 } else {
9800 switch(rate) {
9801 case DESC90_RATEMCS0: ret_rate = MGN_MCS0; break;
9802 case DESC90_RATEMCS1: ret_rate = MGN_MCS1; break;
9803 case DESC90_RATEMCS2: ret_rate = MGN_MCS2; break;
9804 case DESC90_RATEMCS3: ret_rate = MGN_MCS3; break;
9805 case DESC90_RATEMCS4: ret_rate = MGN_MCS4; break;
9806 case DESC90_RATEMCS5: ret_rate = MGN_MCS5; break;
9807 case DESC90_RATEMCS6: ret_rate = MGN_MCS6; break;
9808 case DESC90_RATEMCS7: ret_rate = MGN_MCS7; break;
9809 case DESC90_RATEMCS8: ret_rate = MGN_MCS8; break;
9810 case DESC90_RATEMCS9: ret_rate = MGN_MCS9; break;
9811 case DESC90_RATEMCS10: ret_rate = MGN_MCS10; break;
9812 case DESC90_RATEMCS11: ret_rate = MGN_MCS11; break;
9813 case DESC90_RATEMCS12: ret_rate = MGN_MCS12; break;
9814 case DESC90_RATEMCS13: ret_rate = MGN_MCS13; break;
9815 case DESC90_RATEMCS14: ret_rate = MGN_MCS14; break;
9816 case DESC90_RATEMCS15: ret_rate = MGN_MCS15; break;
9817 case DESC90_RATEMCS32: ret_rate = (0x80|0x20); break;
9819 default:
9820 ret_rate = 0xff;
9821 RT_TRACE(COMP_RECV, "HwRateToMRate90(): Non supported Rate [%x], bIsHT = %d!!!\n",rate, bIsHT);
9822 break;
9826 return ret_rate;
9830 * Function: UpdateRxPktTimeStamp
9831 * Overview: Recored down the TSF time stamp when receiving a packet
9833 * Input:
9834 * PADAPTER Adapter
9835 * PRT_RFD pRfd,
9837 * Output:
9838 * PRT_RFD pRfd
9839 * (pRfd->Status.TimeStampHigh is updated)
9840 * (pRfd->Status.TimeStampLow is updated)
9841 * Return:
9842 * None
9844 void UpdateRxPktTimeStamp8190 (struct net_device *dev, struct ieee80211_rx_stats *stats)
9846 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
9848 if(stats->bIsAMPDU && !stats->bFirstMPDU) {
9849 stats->mac_time[0] = priv->LastRxDescTSFLow;
9850 stats->mac_time[1] = priv->LastRxDescTSFHigh;
9851 } else {
9852 priv->LastRxDescTSFLow = stats->mac_time[0];
9853 priv->LastRxDescTSFHigh = stats->mac_time[1];
9857 //by amy 080606
9859 long rtl819x_translate_todbm(u8 signal_strength_index )// 0-100 index.
9861 long signal_power; // in dBm.
9863 // Translate to dBm (x=0.5y-95).
9864 signal_power = (long)((signal_strength_index + 1) >> 1);
9865 signal_power -= 95;
9867 return signal_power;
9871 /* 2008/01/22 MH We can not delcare RSSI/EVM total value of sliding window to
9872 be a local static. Otherwise, it may increase when we return from S3/S4. The
9873 value will be kept in memory or disk. We must delcare the value in adapter
9874 and it will be reinitialized when return from S3/S4. */
9875 void rtl8192_process_phyinfo(struct r8192_priv * priv,u8* buffer, struct ieee80211_rx_stats * pprevious_stats, struct ieee80211_rx_stats * pcurrent_stats)
9877 bool bcheck = false;
9878 u8 rfpath;
9879 u32 nspatial_stream, tmp_val;
9880 //u8 i;
9881 static u32 slide_rssi_index=0, slide_rssi_statistics=0;
9882 static u32 slide_evm_index=0, slide_evm_statistics=0;
9883 static u32 last_rssi=0, last_evm=0;
9885 static u32 slide_beacon_adc_pwdb_index=0, slide_beacon_adc_pwdb_statistics=0;
9886 static u32 last_beacon_adc_pwdb=0;
9888 struct ieee80211_hdr_3addr *hdr;
9889 u16 sc ;
9890 unsigned int frag,seq;
9891 hdr = (struct ieee80211_hdr_3addr *)buffer;
9892 sc = le16_to_cpu(hdr->seq_ctl);
9893 frag = WLAN_GET_SEQ_FRAG(sc);
9894 seq = WLAN_GET_SEQ_SEQ(sc);
9895 //cosa add 04292008 to record the sequence number
9896 pcurrent_stats->Seq_Num = seq;
9898 // Check whether we should take the previous packet into accounting
9900 if(!pprevious_stats->bIsAMPDU)
9902 // if previous packet is not aggregated packet
9903 bcheck = true;
9904 }else
9906 #if 0
9907 // if previous packet is aggregated packet, and current packet
9908 // (1) is not AMPDU
9909 // (2) is the first packet of one AMPDU
9910 // that means the previous packet is the last one aggregated packet
9911 if( !pcurrent_stats->bIsAMPDU || pcurrent_stats->bFirstMPDU)
9912 bcheck = true;
9913 #endif
9917 if(slide_rssi_statistics++ >= PHY_RSSI_SLID_WIN_MAX)
9919 slide_rssi_statistics = PHY_RSSI_SLID_WIN_MAX;
9920 last_rssi = priv->stats.slide_signal_strength[slide_rssi_index];
9921 priv->stats.slide_rssi_total -= last_rssi;
9923 priv->stats.slide_rssi_total += pprevious_stats->SignalStrength;
9925 priv->stats.slide_signal_strength[slide_rssi_index++] = pprevious_stats->SignalStrength;
9926 if(slide_rssi_index >= PHY_RSSI_SLID_WIN_MAX)
9927 slide_rssi_index = 0;
9929 // <1> Showed on UI for user, in dbm
9930 tmp_val = priv->stats.slide_rssi_total/slide_rssi_statistics;
9931 priv->stats.signal_strength = rtl819x_translate_todbm((u8)tmp_val);
9932 pcurrent_stats->rssi = priv->stats.signal_strength;
9934 // If the previous packet does not match the criteria, neglect it
9936 if(!pprevious_stats->bPacketMatchBSSID)
9938 if(!pprevious_stats->bToSelfBA)
9939 return;
9942 if(!bcheck)
9943 return;
9946 //rtl8190_process_cck_rxpathsel(priv,pprevious_stats);//only rtl8190 supported
9949 // Check RSSI
9951 priv->stats.num_process_phyinfo++;
9953 /* record the general signal strength to the sliding window. */
9956 // <2> Showed on UI for engineering
9957 // hardware does not provide rssi information for each rf path in CCK
9958 if(!pprevious_stats->bIsCCK && (pprevious_stats->bPacketToSelf || pprevious_stats->bToSelfBA))
9960 for (rfpath = RF90_PATH_A; rfpath < priv->NumTotalRFPath; rfpath++)
9962 if (!rtl8192_phy_CheckIsLegalRFPath(priv->ieee80211->dev, rfpath))
9963 continue;
9965 //Fixed by Jacken 2008-03-20
9966 if(priv->stats.rx_rssi_percentage[rfpath] == 0)
9968 priv->stats.rx_rssi_percentage[rfpath] = pprevious_stats->RxMIMOSignalStrength[rfpath];
9969 //DbgPrint("MIMO RSSI initialize \n");
9971 if(pprevious_stats->RxMIMOSignalStrength[rfpath] > priv->stats.rx_rssi_percentage[rfpath])
9973 priv->stats.rx_rssi_percentage[rfpath] =
9974 ( (priv->stats.rx_rssi_percentage[rfpath]*(Rx_Smooth_Factor-1)) +
9975 (pprevious_stats->RxMIMOSignalStrength[rfpath])) /(Rx_Smooth_Factor);
9976 priv->stats.rx_rssi_percentage[rfpath] = priv->stats.rx_rssi_percentage[rfpath] + 1;
9978 else
9980 priv->stats.rx_rssi_percentage[rfpath] =
9981 ( (priv->stats.rx_rssi_percentage[rfpath]*(Rx_Smooth_Factor-1)) +
9982 (pprevious_stats->RxMIMOSignalStrength[rfpath])) /(Rx_Smooth_Factor);
9984 RT_TRACE(COMP_DBG,"priv->stats.rx_rssi_percentage[rfPath] = %d \n" ,priv->stats.rx_rssi_percentage[rfpath] );
9990 // Check PWDB.
9992 RT_TRACE(COMP_RXDESC, "Smooth %s PWDB = %d\n",
9993 pprevious_stats->bIsCCK? "CCK": "OFDM",
9994 pprevious_stats->RxPWDBAll);
9996 if(pprevious_stats->bPacketBeacon)
9998 /* record the beacon pwdb to the sliding window. */
9999 if(slide_beacon_adc_pwdb_statistics++ >= PHY_Beacon_RSSI_SLID_WIN_MAX)
10001 slide_beacon_adc_pwdb_statistics = PHY_Beacon_RSSI_SLID_WIN_MAX;
10002 last_beacon_adc_pwdb = priv->stats.Slide_Beacon_pwdb[slide_beacon_adc_pwdb_index];
10003 priv->stats.Slide_Beacon_Total -= last_beacon_adc_pwdb;
10004 //DbgPrint("slide_beacon_adc_pwdb_index = %d, last_beacon_adc_pwdb = %d, Adapter->RxStats.Slide_Beacon_Total = %d\n",
10005 // slide_beacon_adc_pwdb_index, last_beacon_adc_pwdb, Adapter->RxStats.Slide_Beacon_Total);
10007 priv->stats.Slide_Beacon_Total += pprevious_stats->RxPWDBAll;
10008 priv->stats.Slide_Beacon_pwdb[slide_beacon_adc_pwdb_index] = pprevious_stats->RxPWDBAll;
10009 //DbgPrint("slide_beacon_adc_pwdb_index = %d, pPreviousRfd->Status.RxPWDBAll = %d\n", slide_beacon_adc_pwdb_index, pPreviousRfd->Status.RxPWDBAll);
10010 slide_beacon_adc_pwdb_index++;
10011 if(slide_beacon_adc_pwdb_index >= PHY_Beacon_RSSI_SLID_WIN_MAX)
10012 slide_beacon_adc_pwdb_index = 0;
10013 pprevious_stats->RxPWDBAll = priv->stats.Slide_Beacon_Total/slide_beacon_adc_pwdb_statistics;
10014 if(pprevious_stats->RxPWDBAll >= 3)
10015 pprevious_stats->RxPWDBAll -= 3;
10018 RT_TRACE(COMP_RXDESC, "Smooth %s PWDB = %d\n",
10019 pprevious_stats->bIsCCK? "CCK": "OFDM",
10020 pprevious_stats->RxPWDBAll);
10023 if(pprevious_stats->bPacketToSelf || pprevious_stats->bPacketBeacon || pprevious_stats->bToSelfBA)
10025 if(priv->undecorated_smoothed_pwdb < 0) // initialize
10027 priv->undecorated_smoothed_pwdb = pprevious_stats->RxPWDBAll;
10028 //DbgPrint("First pwdb initialize \n");
10030 #if 1
10031 if(pprevious_stats->RxPWDBAll > (u32)priv->undecorated_smoothed_pwdb)
10033 priv->undecorated_smoothed_pwdb =
10034 ( ((priv->undecorated_smoothed_pwdb)*(Rx_Smooth_Factor-1)) +
10035 (pprevious_stats->RxPWDBAll)) /(Rx_Smooth_Factor);
10036 priv->undecorated_smoothed_pwdb = priv->undecorated_smoothed_pwdb + 1;
10038 else
10040 priv->undecorated_smoothed_pwdb =
10041 ( ((priv->undecorated_smoothed_pwdb)*(Rx_Smooth_Factor-1)) +
10042 (pprevious_stats->RxPWDBAll)) /(Rx_Smooth_Factor);
10044 #else
10045 //Fixed by Jacken 2008-03-20
10046 if(pPreviousRfd->Status.RxPWDBAll > (u32)pHalData->UndecoratedSmoothedPWDB)
10048 pHalData->UndecoratedSmoothedPWDB =
10049 ( ((pHalData->UndecoratedSmoothedPWDB)* 5) + (pPreviousRfd->Status.RxPWDBAll)) / 6;
10050 pHalData->UndecoratedSmoothedPWDB = pHalData->UndecoratedSmoothedPWDB + 1;
10052 else
10054 pHalData->UndecoratedSmoothedPWDB =
10055 ( ((pHalData->UndecoratedSmoothedPWDB)* 5) + (pPreviousRfd->Status.RxPWDBAll)) / 6;
10057 #endif
10062 // Check EVM
10064 /* record the general EVM to the sliding window. */
10065 if(pprevious_stats->SignalQuality == 0)
10068 else
10070 if(pprevious_stats->bPacketToSelf || pprevious_stats->bPacketBeacon || pprevious_stats->bToSelfBA){
10071 if(slide_evm_statistics++ >= PHY_RSSI_SLID_WIN_MAX){
10072 slide_evm_statistics = PHY_RSSI_SLID_WIN_MAX;
10073 last_evm = priv->stats.slide_evm[slide_evm_index];
10074 priv->stats.slide_evm_total -= last_evm;
10077 priv->stats.slide_evm_total += pprevious_stats->SignalQuality;
10079 priv->stats.slide_evm[slide_evm_index++] = pprevious_stats->SignalQuality;
10080 if(slide_evm_index >= PHY_RSSI_SLID_WIN_MAX)
10081 slide_evm_index = 0;
10083 // <1> Showed on UI for user, in percentage.
10084 tmp_val = priv->stats.slide_evm_total/slide_evm_statistics;
10085 priv->stats.signal_quality = tmp_val;
10086 //cosa add 10/11/2007, Showed on UI for user in Windows Vista, for Link quality.
10087 priv->stats.last_signal_strength_inpercent = tmp_val;
10090 // <2> Showed on UI for engineering
10091 if(pprevious_stats->bPacketToSelf || pprevious_stats->bPacketBeacon || pprevious_stats->bToSelfBA)
10093 for(nspatial_stream = 0; nspatial_stream<2 ; nspatial_stream++) // 2 spatial stream
10095 if(pprevious_stats->RxMIMOSignalQuality[nspatial_stream] != -1)
10097 if(priv->stats.rx_evm_percentage[nspatial_stream] == 0) // initialize
10099 priv->stats.rx_evm_percentage[nspatial_stream] = pprevious_stats->RxMIMOSignalQuality[nspatial_stream];
10101 priv->stats.rx_evm_percentage[nspatial_stream] =
10102 ( (priv->stats.rx_evm_percentage[nspatial_stream]* (Rx_Smooth_Factor-1)) +
10103 (pprevious_stats->RxMIMOSignalQuality[nspatial_stream]* 1)) / (Rx_Smooth_Factor);
10112 /*-----------------------------------------------------------------------------
10113 * Function: rtl819x_query_rxpwrpercentage()
10115 * Overview:
10117 * Input: char antpower
10119 * Output: NONE
10121 * Return: 0-100 percentage
10123 * Revised History:
10124 * When Who Remark
10125 * 05/26/2008 amy Create Version 0 porting from windows code.
10127 *---------------------------------------------------------------------------*/
10128 static u8 rtl819x_query_rxpwrpercentage(
10129 char antpower
10132 if ((antpower <= -100) || (antpower >= 20))
10134 return 0;
10136 else if (antpower >= 0)
10138 return 100;
10140 else
10142 return (100+antpower);
10145 } /* QueryRxPwrPercentage */
10147 static u8
10148 rtl819x_evm_dbtopercentage(
10149 char value
10152 char ret_val;
10154 ret_val = value;
10156 if(ret_val >= 0)
10157 ret_val = 0;
10158 if(ret_val <= -33)
10159 ret_val = -33;
10160 ret_val = 0 - ret_val;
10161 ret_val*=3;
10162 if(ret_val == 99)
10163 ret_val = 100;
10164 return(ret_val);
10167 // Description:
10168 // We want good-looking for signal strength/quality
10169 // 2007/7/19 01:09, by cosa.
10171 long
10172 rtl819x_signal_scale_mapping(
10173 long currsig
10176 long retsig;
10178 // Step 1. Scale mapping.
10179 if(currsig >= 61 && currsig <= 100)
10181 retsig = 90 + ((currsig - 60) / 4);
10183 else if(currsig >= 41 && currsig <= 60)
10185 retsig = 78 + ((currsig - 40) / 2);
10187 else if(currsig >= 31 && currsig <= 40)
10189 retsig = 66 + (currsig - 30);
10191 else if(currsig >= 21 && currsig <= 30)
10193 retsig = 54 + (currsig - 20);
10195 else if(currsig >= 5 && currsig <= 20)
10197 retsig = 42 + (((currsig - 5) * 2) / 3);
10199 else if(currsig == 4)
10201 retsig = 36;
10203 else if(currsig == 3)
10205 retsig = 27;
10207 else if(currsig == 2)
10209 retsig = 18;
10211 else if(currsig == 1)
10213 retsig = 9;
10215 else
10217 retsig = currsig;
10220 return retsig;
10223 #ifdef RTL8192SU
10224 /*-----------------------------------------------------------------------------
10225 * Function: QueryRxPhyStatus8192S()
10227 * Overview:
10229 * Input: NONE
10231 * Output: NONE
10233 * Return: NONE
10235 * Revised History:
10236 * When Who Remark
10237 * 06/01/2007 MHC Create Version 0.
10238 * 06/05/2007 MHC Accordign to HW's new data sheet, we add CCK and OFDM
10239 * descriptor definition.
10240 * 07/04/2007 MHC According to Jerry and Bryant's document. We read
10241 * ir_isolation and ext_lna for RF's init value and use
10242 * to compensate RSSI after receiving packets.
10243 * 09/10/2008 MHC Modify name and PHY status field for 92SE.
10244 * 09/19/2008 MHC Add CCK/OFDM SS/SQ for 92S series.
10246 *---------------------------------------------------------------------------*/
10247 static void rtl8192SU_query_rxphystatus(
10248 struct r8192_priv * priv,
10249 struct ieee80211_rx_stats * pstats,
10250 rx_desc_819x_usb *pDesc,
10251 rx_drvinfo_819x_usb * pdrvinfo,
10252 struct ieee80211_rx_stats * precord_stats,
10253 bool bpacket_match_bssid,
10254 bool bpacket_toself,
10255 bool bPacketBeacon,
10256 bool bToSelfBA
10259 //PRT_RFD_STATUS pRtRfdStatus = &(pRfd->Status);
10260 //PHY_STS_CCK_8192S_T *pCck_buf;
10261 phy_sts_cck_819xusb_t * pcck_buf;
10262 phy_ofdm_rx_status_rxsc_sgien_exintfflag* prxsc;
10263 //u8 *prxpkt;
10264 //u8 i, max_spatial_stream, tmp_rxsnr, tmp_rxevm, rxsc_sgien_exflg;
10265 u8 i, max_spatial_stream, rxsc_sgien_exflg;
10266 char rx_pwr[4], rx_pwr_all=0;
10267 //long rx_avg_pwr = 0;
10268 //char rx_snrX, rx_evmX;
10269 u8 evm, pwdb_all;
10270 u32 RSSI, total_rssi=0;//, total_evm=0;
10271 // long signal_strength_index = 0;
10272 u8 is_cck_rate=0;
10273 u8 rf_rx_num = 0;
10277 priv->stats.numqry_phystatus++;
10279 is_cck_rate = rx_hal_is_cck_rate(pDesc);
10281 // Record it for next packet processing
10282 memset(precord_stats, 0, sizeof(struct ieee80211_rx_stats));
10283 pstats->bPacketMatchBSSID = precord_stats->bPacketMatchBSSID = bpacket_match_bssid;
10284 pstats->bPacketToSelf = precord_stats->bPacketToSelf = bpacket_toself;
10285 pstats->bIsCCK = precord_stats->bIsCCK = is_cck_rate;//RX_HAL_IS_CCK_RATE(pDrvInfo);
10286 pstats->bPacketBeacon = precord_stats->bPacketBeacon = bPacketBeacon;
10287 pstats->bToSelfBA = precord_stats->bToSelfBA = bToSelfBA;
10289 #ifndef RTL8192SU
10290 phy_sts_ofdm_819xusb_t* pofdm_buf = NULL;
10291 prxpkt = (u8*)pdrvinfo;
10293 /* Move pointer to the 16th bytes. Phy status start address. */
10294 prxpkt += sizeof(rx_drvinfo_819x_usb);
10296 /* Initial the cck and ofdm buffer pointer */
10297 pcck_buf = (phy_sts_cck_819xusb_t *)prxpkt;
10298 pofdm_buf = (phy_sts_ofdm_819xusb_t *)prxpkt;
10299 #endif
10301 pstats->RxMIMOSignalQuality[0] = -1;
10302 pstats->RxMIMOSignalQuality[1] = -1;
10303 precord_stats->RxMIMOSignalQuality[0] = -1;
10304 precord_stats->RxMIMOSignalQuality[1] = -1;
10306 if(is_cck_rate)
10308 u8 report;//, tmp_pwdb;
10309 //char cck_adc_pwdb[4];
10311 // CCK Driver info Structure is not the same as OFDM packet.
10312 pcck_buf = (phy_sts_cck_819xusb_t *)pdrvinfo;
10315 // (1)Hardware does not provide RSSI for CCK
10319 // (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive)
10322 priv->stats.numqry_phystatusCCK++;
10324 if(!priv->bCckHighPower)
10326 report = pcck_buf->cck_agc_rpt & 0xc0;
10327 report = report>>6;
10328 switch(report)
10330 //Fixed by Jacken from Bryant 2008-03-20
10331 //Original value is -38 , -26 , -14 , -2
10332 //Fixed value is -35 , -23 , -11 , 6
10333 case 0x3:
10334 rx_pwr_all = -35 - (pcck_buf->cck_agc_rpt & 0x3e);
10335 break;
10336 case 0x2:
10337 rx_pwr_all = -23 - (pcck_buf->cck_agc_rpt & 0x3e);
10338 break;
10339 case 0x1:
10340 rx_pwr_all = -11 - (pcck_buf->cck_agc_rpt & 0x3e);
10341 break;
10342 case 0x0:
10343 rx_pwr_all = 8 - (pcck_buf->cck_agc_rpt & 0x3e);//6->8
10344 break;
10347 else
10349 report = pdrvinfo->cfosho[0] & 0x60;
10350 report = report>>5;
10351 switch(report)
10353 case 0x3:
10354 rx_pwr_all = -35 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1) ;
10355 break;
10356 case 0x2:
10357 rx_pwr_all = -23 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1);
10358 break;
10359 case 0x1:
10360 rx_pwr_all = -11 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1) ;
10361 break;
10362 case 0x0:
10363 rx_pwr_all = -8 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1) ;//6->-8
10364 break;
10368 pwdb_all = rtl819x_query_rxpwrpercentage(rx_pwr_all);//check it
10369 pstats->RxPWDBAll = precord_stats->RxPWDBAll = pwdb_all;
10370 //pstats->RecvSignalPower = pwdb_all;
10371 pstats->RecvSignalPower = rx_pwr_all;
10374 // (3) Get Signal Quality (EVM)
10376 //if(bpacket_match_bssid)
10378 u8 sq;
10380 if(pstats->RxPWDBAll > 40)
10382 sq = 100;
10383 }else
10385 sq = pcck_buf->sq_rpt;
10387 if(pcck_buf->sq_rpt > 64)
10388 sq = 0;
10389 else if (pcck_buf->sq_rpt < 20)
10390 sq = 100;
10391 else
10392 sq = ((64-sq) * 100) / 44;
10394 pstats->SignalQuality = precord_stats->SignalQuality = sq;
10395 pstats->RxMIMOSignalQuality[0] = precord_stats->RxMIMOSignalQuality[0] = sq;
10396 pstats->RxMIMOSignalQuality[1] = precord_stats->RxMIMOSignalQuality[1] = -1;
10399 else
10401 priv->stats.numqry_phystatusHT++;
10403 // 2008/09/19 MH For 92S debug, RX RF path always enable!!
10404 priv->brfpath_rxenable[0] = priv->brfpath_rxenable[1] = TRUE;
10407 // (1)Get RSSI for HT rate
10409 //for(i=RF90_PATH_A; i<priv->NumTotalRFPath; i++)
10410 for(i=RF90_PATH_A; i<RF90_PATH_MAX; i++)
10412 // 2008/01/30 MH we will judge RF RX path now.
10413 if (priv->brfpath_rxenable[i])
10414 rf_rx_num++;
10415 //else
10416 // continue;
10418 //if (!rtl8192_phy_CheckIsLegalRFPath(priv->ieee80211->dev, i))
10419 // continue;
10421 //Fixed by Jacken from Bryant 2008-03-20
10422 //Original value is 106
10423 //rx_pwr[i] = ((pofdm_buf->trsw_gain_X[i]&0x3F)*2) - 106;
10424 rx_pwr[i] = ((pdrvinfo->gain_trsw[i]&0x3F)*2) - 110;
10426 /* Translate DBM to percentage. */
10427 RSSI = rtl819x_query_rxpwrpercentage(rx_pwr[i]); //check ok
10428 total_rssi += RSSI;
10429 RT_TRACE(COMP_RF, "RF-%d RXPWR=%x RSSI=%d\n", i, rx_pwr[i], RSSI);
10431 //Get Rx snr value in DB
10432 //tmp_rxsnr = pofdm_buf->rxsnr_X[i];
10433 //rx_snrX = (char)(tmp_rxsnr);
10434 //rx_snrX /= 2;
10435 //priv->stats.rxSNRdB[i] = (long)rx_snrX;
10436 priv->stats.rxSNRdB[i] = (long)(pdrvinfo->rxsnr[i]/2);
10438 /* Translate DBM to percentage. */
10439 //RSSI = rtl819x_query_rxpwrpercentage(rx_pwr[i]);
10440 //total_rssi += RSSI;
10442 /* Record Signal Strength for next packet */
10443 //if(bpacket_match_bssid)
10445 pstats->RxMIMOSignalStrength[i] =(u8) RSSI;
10446 precord_stats->RxMIMOSignalStrength[i] =(u8) RSSI;
10452 // (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive)
10454 //Fixed by Jacken from Bryant 2008-03-20
10455 //Original value is 106
10456 //rx_pwr_all = (((pofdm_buf->pwdb_all ) >> 1 )& 0x7f) -106;
10457 rx_pwr_all = (((pdrvinfo->pwdb_all ) >> 1 )& 0x7f) -106;
10458 pwdb_all = rtl819x_query_rxpwrpercentage(rx_pwr_all);
10460 pstats->RxPWDBAll = precord_stats->RxPWDBAll = pwdb_all;
10461 pstats->RxPower = precord_stats->RxPower = rx_pwr_all;
10462 pstats->RecvSignalPower = rx_pwr_all;
10465 // (3)EVM of HT rate
10467 //if(pdrvinfo->RxHT && pdrvinfo->RxRate>=DESC90_RATEMCS8 &&
10468 // pdrvinfo->RxRate<=DESC90_RATEMCS15)
10469 if(pDesc->RxHT && pDesc->RxMCS>=DESC92S_RATEMCS8 &&
10470 pDesc->RxMCS<=DESC92S_RATEMCS15)
10471 max_spatial_stream = 2; //both spatial stream make sense
10472 else
10473 max_spatial_stream = 1; //only spatial stream 1 makes sense
10475 for(i=0; i<max_spatial_stream; i++)
10477 //tmp_rxevm = pofdm_buf->rxevm_X[i];
10478 //rx_evmX = (char)(tmp_rxevm);
10480 // Do not use shift operation like "rx_evmX >>= 1" because the compilor of free build environment
10481 // fill most significant bit to "zero" when doing shifting operation which may change a negative
10482 // value to positive one, then the dbm value (which is supposed to be negative) is not correct anymore.
10483 //rx_evmX /= 2; //dbm
10485 //evm = rtl819x_evm_dbtopercentage(rx_evmX);
10486 evm = rtl819x_evm_dbtopercentage( (pdrvinfo->rxevm[i] /*/ 2*/)); //dbm
10487 RT_TRACE(COMP_RF, "RXRATE=%x RXEVM=%x EVM=%s%d\n", pDesc->RxMCS, pdrvinfo->rxevm[i], "%", evm);
10488 #if 0
10489 EVM = SignalScaleMapping(EVM);//make it good looking, from 0~100//=====>from here
10490 #endif
10492 //if(bpacket_match_bssid)
10494 if(i==0) // Fill value in RFD, Get the first spatial stream only
10495 pstats->SignalQuality = precord_stats->SignalQuality = (u8)(evm & 0xff);
10496 pstats->RxMIMOSignalQuality[i] = precord_stats->RxMIMOSignalQuality[i] = (u8)(evm & 0xff);
10501 /* record rx statistics for debug */
10502 //rxsc_sgien_exflg = pofdm_buf->rxsc_sgien_exflg;
10503 prxsc = (phy_ofdm_rx_status_rxsc_sgien_exintfflag *)&rxsc_sgien_exflg;
10504 //if(pdrvinfo->BW) //40M channel
10505 if(pDesc->BW) //40M channel
10506 priv->stats.received_bwtype[1+pdrvinfo->rxsc]++;
10507 else //20M channel
10508 priv->stats.received_bwtype[0]++;
10511 //UI BSS List signal strength(in percentage), make it good looking, from 0~100.
10512 //It is assigned to the BSS List in GetValueFromBeaconOrProbeRsp().
10513 if(is_cck_rate)
10515 pstats->SignalStrength = precord_stats->SignalStrength = (u8)(rtl819x_signal_scale_mapping((long)pwdb_all));//PWDB_ALL;//check ok
10518 else
10520 //pRfd->Status.SignalStrength = pRecordRfd->Status.SignalStrength = (u8)(SignalScaleMapping(total_rssi/=RF90_PATH_MAX));//(u8)(total_rssi/=RF90_PATH_MAX);
10521 // We can judge RX path number now.
10522 if (rf_rx_num != 0)
10523 pstats->SignalStrength = precord_stats->SignalStrength = (u8)(rtl819x_signal_scale_mapping((long)(total_rssi/=rf_rx_num)));
10525 }/* QueryRxPhyStatus8192S */
10526 #else
10527 static void rtl8192_query_rxphystatus(
10528 struct r8192_priv * priv,
10529 struct ieee80211_rx_stats * pstats,
10530 rx_drvinfo_819x_usb * pdrvinfo,
10531 struct ieee80211_rx_stats * precord_stats,
10532 bool bpacket_match_bssid,
10533 bool bpacket_toself,
10534 bool bPacketBeacon,
10535 bool bToSelfBA
10538 //PRT_RFD_STATUS pRtRfdStatus = &(pRfd->Status);
10539 phy_sts_ofdm_819xusb_t* pofdm_buf;
10540 phy_sts_cck_819xusb_t * pcck_buf;
10541 phy_ofdm_rx_status_rxsc_sgien_exintfflag* prxsc;
10542 u8 *prxpkt;
10543 u8 i, max_spatial_stream, tmp_rxsnr, tmp_rxevm, rxsc_sgien_exflg;
10544 char rx_pwr[4], rx_pwr_all=0;
10545 //long rx_avg_pwr = 0;
10546 char rx_snrX, rx_evmX;
10547 u8 evm, pwdb_all;
10548 u32 RSSI, total_rssi=0;//, total_evm=0;
10549 // long signal_strength_index = 0;
10550 u8 is_cck_rate=0;
10551 u8 rf_rx_num = 0;
10554 priv->stats.numqry_phystatus++;
10556 is_cck_rate = rx_hal_is_cck_rate(pdrvinfo);
10558 // Record it for next packet processing
10559 memset(precord_stats, 0, sizeof(struct ieee80211_rx_stats));
10560 pstats->bPacketMatchBSSID = precord_stats->bPacketMatchBSSID = bpacket_match_bssid;
10561 pstats->bPacketToSelf = precord_stats->bPacketToSelf = bpacket_toself;
10562 pstats->bIsCCK = precord_stats->bIsCCK = is_cck_rate;//RX_HAL_IS_CCK_RATE(pDrvInfo);
10563 pstats->bPacketBeacon = precord_stats->bPacketBeacon = bPacketBeacon;
10564 pstats->bToSelfBA = precord_stats->bToSelfBA = bToSelfBA;
10566 prxpkt = (u8*)pdrvinfo;
10568 /* Move pointer to the 16th bytes. Phy status start address. */
10569 prxpkt += sizeof(rx_drvinfo_819x_usb);
10571 /* Initial the cck and ofdm buffer pointer */
10572 pcck_buf = (phy_sts_cck_819xusb_t *)prxpkt;
10573 pofdm_buf = (phy_sts_ofdm_819xusb_t *)prxpkt;
10575 pstats->RxMIMOSignalQuality[0] = -1;
10576 pstats->RxMIMOSignalQuality[1] = -1;
10577 precord_stats->RxMIMOSignalQuality[0] = -1;
10578 precord_stats->RxMIMOSignalQuality[1] = -1;
10580 if(is_cck_rate)
10583 // (1)Hardware does not provide RSSI for CCK
10587 // (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive)
10589 u8 report;//, cck_agc_rpt;
10591 priv->stats.numqry_phystatusCCK++;
10593 if(!priv->bCckHighPower)
10595 report = pcck_buf->cck_agc_rpt & 0xc0;
10596 report = report>>6;
10597 switch(report)
10599 //Fixed by Jacken from Bryant 2008-03-20
10600 //Original value is -38 , -26 , -14 , -2
10601 //Fixed value is -35 , -23 , -11 , 6
10602 case 0x3:
10603 rx_pwr_all = -35 - (pcck_buf->cck_agc_rpt & 0x3e);
10604 break;
10605 case 0x2:
10606 rx_pwr_all = -23 - (pcck_buf->cck_agc_rpt & 0x3e);
10607 break;
10608 case 0x1:
10609 rx_pwr_all = -11 - (pcck_buf->cck_agc_rpt & 0x3e);
10610 break;
10611 case 0x0:
10612 rx_pwr_all = 6 - (pcck_buf->cck_agc_rpt & 0x3e);
10613 break;
10616 else
10618 report = pcck_buf->cck_agc_rpt & 0x60;
10619 report = report>>5;
10620 switch(report)
10622 case 0x3:
10623 rx_pwr_all = -35 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1) ;
10624 break;
10625 case 0x2:
10626 rx_pwr_all = -23 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1);
10627 break;
10628 case 0x1:
10629 rx_pwr_all = -11 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1) ;
10630 break;
10631 case 0x0:
10632 rx_pwr_all = 6 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1) ;
10633 break;
10637 pwdb_all = rtl819x_query_rxpwrpercentage(rx_pwr_all);
10638 pstats->RxPWDBAll = precord_stats->RxPWDBAll = pwdb_all;
10639 pstats->RecvSignalPower = pwdb_all;
10642 // (3) Get Signal Quality (EVM)
10644 //if(bpacket_match_bssid)
10646 u8 sq;
10648 if(pstats->RxPWDBAll > 40)
10650 sq = 100;
10651 }else
10653 sq = pcck_buf->sq_rpt;
10655 if(pcck_buf->sq_rpt > 64)
10656 sq = 0;
10657 else if (pcck_buf->sq_rpt < 20)
10658 sq = 100;
10659 else
10660 sq = ((64-sq) * 100) / 44;
10662 pstats->SignalQuality = precord_stats->SignalQuality = sq;
10663 pstats->RxMIMOSignalQuality[0] = precord_stats->RxMIMOSignalQuality[0] = sq;
10664 pstats->RxMIMOSignalQuality[1] = precord_stats->RxMIMOSignalQuality[1] = -1;
10667 else
10669 priv->stats.numqry_phystatusHT++;
10671 // (1)Get RSSI for HT rate
10673 for(i=RF90_PATH_A; i<priv->NumTotalRFPath; i++)
10675 // 2008/01/30 MH we will judge RF RX path now.
10676 if (priv->brfpath_rxenable[i])
10677 rf_rx_num++;
10678 else
10679 continue;
10681 if (!rtl8192_phy_CheckIsLegalRFPath(priv->ieee80211->dev, i))
10682 continue;
10684 //Fixed by Jacken from Bryant 2008-03-20
10685 //Original value is 106
10686 rx_pwr[i] = ((pofdm_buf->trsw_gain_X[i]&0x3F)*2) - 106;
10688 //Get Rx snr value in DB
10689 tmp_rxsnr = pofdm_buf->rxsnr_X[i];
10690 rx_snrX = (char)(tmp_rxsnr);
10691 //rx_snrX >>= 1;;
10692 rx_snrX /= 2;
10693 priv->stats.rxSNRdB[i] = (long)rx_snrX;
10695 /* Translate DBM to percentage. */
10696 RSSI = rtl819x_query_rxpwrpercentage(rx_pwr[i]);
10697 total_rssi += RSSI;
10699 /* Record Signal Strength for next packet */
10700 //if(bpacket_match_bssid)
10702 pstats->RxMIMOSignalStrength[i] =(u8) RSSI;
10703 precord_stats->RxMIMOSignalStrength[i] =(u8) RSSI;
10709 // (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive)
10711 //Fixed by Jacken from Bryant 2008-03-20
10712 //Original value is 106
10713 rx_pwr_all = (((pofdm_buf->pwdb_all ) >> 1 )& 0x7f) -106;
10714 pwdb_all = rtl819x_query_rxpwrpercentage(rx_pwr_all);
10716 pstats->RxPWDBAll = precord_stats->RxPWDBAll = pwdb_all;
10717 pstats->RxPower = precord_stats->RxPower = rx_pwr_all;
10720 // (3)EVM of HT rate
10722 if(pdrvinfo->RxHT && pdrvinfo->RxRate>=DESC90_RATEMCS8 &&
10723 pdrvinfo->RxRate<=DESC90_RATEMCS15)
10724 max_spatial_stream = 2; //both spatial stream make sense
10725 else
10726 max_spatial_stream = 1; //only spatial stream 1 makes sense
10728 for(i=0; i<max_spatial_stream; i++)
10730 tmp_rxevm = pofdm_buf->rxevm_X[i];
10731 rx_evmX = (char)(tmp_rxevm);
10733 // Do not use shift operation like "rx_evmX >>= 1" because the compilor of free build environment
10734 // fill most significant bit to "zero" when doing shifting operation which may change a negative
10735 // value to positive one, then the dbm value (which is supposed to be negative) is not correct anymore.
10736 rx_evmX /= 2; //dbm
10738 evm = rtl819x_evm_dbtopercentage(rx_evmX);
10739 #if 0
10740 EVM = SignalScaleMapping(EVM);//make it good looking, from 0~100
10741 #endif
10742 //if(bpacket_match_bssid)
10744 if(i==0) // Fill value in RFD, Get the first spatial stream only
10745 pstats->SignalQuality = precord_stats->SignalQuality = (u8)(evm & 0xff);
10746 pstats->RxMIMOSignalQuality[i] = precord_stats->RxMIMOSignalQuality[i] = (u8)(evm & 0xff);
10751 /* record rx statistics for debug */
10752 rxsc_sgien_exflg = pofdm_buf->rxsc_sgien_exflg;
10753 prxsc = (phy_ofdm_rx_status_rxsc_sgien_exintfflag *)&rxsc_sgien_exflg;
10754 if(pdrvinfo->BW) //40M channel
10755 priv->stats.received_bwtype[1+prxsc->rxsc]++;
10756 else //20M channel
10757 priv->stats.received_bwtype[0]++;
10760 //UI BSS List signal strength(in percentage), make it good looking, from 0~100.
10761 //It is assigned to the BSS List in GetValueFromBeaconOrProbeRsp().
10762 if(is_cck_rate)
10764 pstats->SignalStrength = precord_stats->SignalStrength = (u8)(rtl819x_signal_scale_mapping((long)pwdb_all));//PWDB_ALL;
10767 else
10769 //pRfd->Status.SignalStrength = pRecordRfd->Status.SignalStrength = (u8)(SignalScaleMapping(total_rssi/=RF90_PATH_MAX));//(u8)(total_rssi/=RF90_PATH_MAX);
10770 // We can judge RX path number now.
10771 if (rf_rx_num != 0)
10772 pstats->SignalStrength = precord_stats->SignalStrength = (u8)(rtl819x_signal_scale_mapping((long)(total_rssi/=rf_rx_num)));
10774 } /* QueryRxPhyStatus8190Pci */
10775 #endif
10777 void
10778 rtl8192_record_rxdesc_forlateruse(
10779 struct ieee80211_rx_stats * psrc_stats,
10780 struct ieee80211_rx_stats * ptarget_stats
10783 ptarget_stats->bIsAMPDU = psrc_stats->bIsAMPDU;
10784 ptarget_stats->bFirstMPDU = psrc_stats->bFirstMPDU;
10785 ptarget_stats->Seq_Num = psrc_stats->Seq_Num;
10788 #ifdef RTL8192SU
10789 static void rtl8192SU_query_rxphystatus(
10790 struct r8192_priv * priv,
10791 struct ieee80211_rx_stats * pstats,
10792 rx_desc_819x_usb *pDesc,
10793 rx_drvinfo_819x_usb * pdrvinfo,
10794 struct ieee80211_rx_stats * precord_stats,
10795 bool bpacket_match_bssid,
10796 bool bpacket_toself,
10797 bool bPacketBeacon,
10798 bool bToSelfBA
10800 void rtl8192SU_TranslateRxSignalStuff(struct sk_buff *skb,
10801 struct ieee80211_rx_stats * pstats,
10802 rx_desc_819x_usb *pDesc,
10803 rx_drvinfo_819x_usb *pdrvinfo)
10805 // TODO: We must only check packet for current MAC address. Not finish
10806 rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
10807 struct net_device *dev=info->dev;
10808 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
10809 bool bpacket_match_bssid, bpacket_toself;
10810 bool bPacketBeacon=FALSE, bToSelfBA=FALSE;
10811 static struct ieee80211_rx_stats previous_stats;
10812 struct ieee80211_hdr_3addr *hdr;//by amy
10813 u16 fc,type;
10815 // Get Signal Quality for only RX data queue (but not command queue)
10817 u8* tmp_buf;
10818 //u16 tmp_buf_len = 0;
10819 u8 *praddr;
10821 /* Get MAC frame start address. */
10822 tmp_buf = (u8*)skb->data;// + get_rxpacket_shiftbytes_819xusb(pstats);
10824 hdr = (struct ieee80211_hdr_3addr *)tmp_buf;
10825 fc = le16_to_cpu(hdr->frame_ctl);
10826 type = WLAN_FC_GET_TYPE(fc);
10827 praddr = hdr->addr1;
10829 /* Check if the received packet is acceptabe. */
10830 bpacket_match_bssid = ((IEEE80211_FTYPE_CTL != type) &&
10831 (eqMacAddr(priv->ieee80211->current_network.bssid, (fc & IEEE80211_FCTL_TODS)? hdr->addr1 : (fc & IEEE80211_FCTL_FROMDS )? hdr->addr2 : hdr->addr3))
10832 && (!pstats->bHwError) && (!pstats->bCRC)&& (!pstats->bICV));
10833 bpacket_toself = bpacket_match_bssid & (eqMacAddr(praddr, priv->ieee80211->dev->dev_addr));
10835 #if 1//cosa
10836 if(WLAN_FC_GET_FRAMETYPE(fc)== IEEE80211_STYPE_BEACON)
10838 bPacketBeacon = true;
10839 //DbgPrint("Beacon 2, MatchBSSID = %d, ToSelf = %d \n", bPacketMatchBSSID, bPacketToSelf);
10841 if(WLAN_FC_GET_FRAMETYPE(fc) == IEEE80211_STYPE_BLOCKACK)
10843 if((eqMacAddr(praddr,dev->dev_addr)))
10844 bToSelfBA = true;
10845 //DbgPrint("BlockAck, MatchBSSID = %d, ToSelf = %d \n", bPacketMatchBSSID, bPacketToSelf);
10848 #endif
10851 if(bpacket_match_bssid)
10853 priv->stats.numpacket_matchbssid++;
10855 if(bpacket_toself){
10856 priv->stats.numpacket_toself++;
10859 // Process PHY information for previous packet (RSSI/PWDB/EVM)
10861 // Because phy information is contained in the last packet of AMPDU only, so driver
10862 // should process phy information of previous packet
10863 rtl8192_process_phyinfo(priv, tmp_buf, &previous_stats, pstats);
10864 rtl8192SU_query_rxphystatus(priv, pstats, pDesc, pdrvinfo, &previous_stats, bpacket_match_bssid,bpacket_toself,bPacketBeacon,bToSelfBA);
10865 rtl8192_record_rxdesc_forlateruse(pstats, &previous_stats);
10868 #else
10869 void TranslateRxSignalStuff819xUsb(struct sk_buff *skb,
10870 struct ieee80211_rx_stats * pstats,
10871 rx_drvinfo_819x_usb *pdrvinfo)
10873 // TODO: We must only check packet for current MAC address. Not finish
10874 rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
10875 struct net_device *dev=info->dev;
10876 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
10877 bool bpacket_match_bssid, bpacket_toself;
10878 bool bPacketBeacon=FALSE, bToSelfBA=FALSE;
10879 static struct ieee80211_rx_stats previous_stats;
10880 struct ieee80211_hdr_3addr *hdr;//by amy
10881 u16 fc,type;
10883 // Get Signal Quality for only RX data queue (but not command queue)
10885 u8* tmp_buf;
10886 //u16 tmp_buf_len = 0;
10887 u8 *praddr;
10889 /* Get MAC frame start address. */
10890 tmp_buf = (u8*)skb->data;// + get_rxpacket_shiftbytes_819xusb(pstats);
10892 hdr = (struct ieee80211_hdr_3addr *)tmp_buf;
10893 fc = le16_to_cpu(hdr->frame_ctl);
10894 type = WLAN_FC_GET_TYPE(fc);
10895 praddr = hdr->addr1;
10897 /* Check if the received packet is acceptabe. */
10898 bpacket_match_bssid = ((IEEE80211_FTYPE_CTL != type) &&
10899 (eqMacAddr(priv->ieee80211->current_network.bssid, (fc & IEEE80211_FCTL_TODS)? hdr->addr1 : (fc & IEEE80211_FCTL_FROMDS )? hdr->addr2 : hdr->addr3))
10900 && (!pstats->bHwError) && (!pstats->bCRC)&& (!pstats->bICV));
10901 bpacket_toself = bpacket_match_bssid & (eqMacAddr(praddr, priv->ieee80211->dev->dev_addr));
10903 #if 1//cosa
10904 if(WLAN_FC_GET_FRAMETYPE(fc)== IEEE80211_STYPE_BEACON)
10906 bPacketBeacon = true;
10907 //DbgPrint("Beacon 2, MatchBSSID = %d, ToSelf = %d \n", bPacketMatchBSSID, bPacketToSelf);
10909 if(WLAN_FC_GET_FRAMETYPE(fc) == IEEE80211_STYPE_BLOCKACK)
10911 if((eqMacAddr(praddr,dev->dev_addr)))
10912 bToSelfBA = true;
10913 //DbgPrint("BlockAck, MatchBSSID = %d, ToSelf = %d \n", bPacketMatchBSSID, bPacketToSelf);
10916 #endif
10919 if(bpacket_match_bssid)
10921 priv->stats.numpacket_matchbssid++;
10923 if(bpacket_toself){
10924 priv->stats.numpacket_toself++;
10927 // Process PHY information for previous packet (RSSI/PWDB/EVM)
10929 // Because phy information is contained in the last packet of AMPDU only, so driver
10930 // should process phy information of previous packet
10931 rtl8192_process_phyinfo(priv, tmp_buf, &previous_stats, pstats);
10932 rtl8192_query_rxphystatus(priv, pstats, pdrvinfo, &previous_stats, bpacket_match_bssid,bpacket_toself,bPacketBeacon,bToSelfBA);
10933 rtl8192_record_rxdesc_forlateruse(pstats, &previous_stats);
10936 #endif
10939 * Function: UpdateReceivedRateHistogramStatistics
10940 * Overview: Recored down the received data rate
10942 * Input:
10943 * struct net_device *dev
10944 * struct ieee80211_rx_stats *stats
10946 * Output:
10948 * (priv->stats.ReceivedRateHistogram[] is updated)
10949 * Return:
10950 * None
10952 void
10953 UpdateReceivedRateHistogramStatistics8190(
10954 struct net_device *dev,
10955 struct ieee80211_rx_stats *stats
10958 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
10959 u32 rcvType=1; //0: Total, 1:OK, 2:CRC, 3:ICV
10960 u32 rateIndex;
10961 u32 preamble_guardinterval; //1: short preamble/GI, 0: long preamble/GI
10964 if(stats->bCRC)
10965 rcvType = 2;
10966 else if(stats->bICV)
10967 rcvType = 3;
10969 if(stats->bShortPreamble)
10970 preamble_guardinterval = 1;// short
10971 else
10972 preamble_guardinterval = 0;// long
10974 switch(stats->rate)
10977 // CCK rate
10979 case MGN_1M: rateIndex = 0; break;
10980 case MGN_2M: rateIndex = 1; break;
10981 case MGN_5_5M: rateIndex = 2; break;
10982 case MGN_11M: rateIndex = 3; break;
10984 // Legacy OFDM rate
10986 case MGN_6M: rateIndex = 4; break;
10987 case MGN_9M: rateIndex = 5; break;
10988 case MGN_12M: rateIndex = 6; break;
10989 case MGN_18M: rateIndex = 7; break;
10990 case MGN_24M: rateIndex = 8; break;
10991 case MGN_36M: rateIndex = 9; break;
10992 case MGN_48M: rateIndex = 10; break;
10993 case MGN_54M: rateIndex = 11; break;
10995 // 11n High throughput rate
10997 case MGN_MCS0: rateIndex = 12; break;
10998 case MGN_MCS1: rateIndex = 13; break;
10999 case MGN_MCS2: rateIndex = 14; break;
11000 case MGN_MCS3: rateIndex = 15; break;
11001 case MGN_MCS4: rateIndex = 16; break;
11002 case MGN_MCS5: rateIndex = 17; break;
11003 case MGN_MCS6: rateIndex = 18; break;
11004 case MGN_MCS7: rateIndex = 19; break;
11005 case MGN_MCS8: rateIndex = 20; break;
11006 case MGN_MCS9: rateIndex = 21; break;
11007 case MGN_MCS10: rateIndex = 22; break;
11008 case MGN_MCS11: rateIndex = 23; break;
11009 case MGN_MCS12: rateIndex = 24; break;
11010 case MGN_MCS13: rateIndex = 25; break;
11011 case MGN_MCS14: rateIndex = 26; break;
11012 case MGN_MCS15: rateIndex = 27; break;
11013 default: rateIndex = 28; break;
11015 priv->stats.received_preamble_GI[preamble_guardinterval][rateIndex]++;
11016 priv->stats.received_rate_histogram[0][rateIndex]++; //total
11017 priv->stats.received_rate_histogram[rcvType][rateIndex]++;
11020 #ifdef RTL8192SU
11021 void rtl8192SU_query_rxdesc_status(struct sk_buff *skb, struct ieee80211_rx_stats *stats, bool bIsRxAggrSubframe)
11023 rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
11024 struct net_device *dev=info->dev;
11025 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
11026 //rx_desc_819x_usb *desc = (rx_desc_819x_usb *)skb->data;
11027 rx_drvinfo_819x_usb *driver_info = NULL;
11029 //PRT_RFD_STATUS pRtRfdStatus = &pRfd->Status;
11030 //PHAL_DATA_8192SUSB pHalData = GET_HAL_DATA(Adapter);
11031 //pu1Byte pDesc = (pu1Byte)pDescIn;
11032 //PRX_DRIVER_INFO_8192S pDrvInfo;
11034 #ifdef USB_RX_AGGREGATION_SUPPORT//FIXLZM
11035 //if (bIsRxAggrSubframe)
11036 rx_desc_819x_usb_aggr_subframe *desc = (rx_desc_819x_usb_aggr_subframe *)skb->data;
11037 else
11038 #endif
11039 rx_desc_819x_usb *desc = (rx_desc_819x_usb *)skb->data;
11041 if(0)
11043 int m = 0;
11044 printk("========================");
11045 for(m=0; m<skb->len; m++){
11046 if((m%32) == 0)
11047 printk("\n");
11048 printk("%2x ",((u8*)skb->data)[m]);
11050 printk("\n========================\n");
11056 //Get Rx Descriptor Raw Information
11058 stats->Length = desc->Length ;
11059 stats->RxDrvInfoSize = desc->RxDrvInfoSize*RX_DRV_INFO_SIZE_UNIT;
11060 stats->RxBufShift = (desc->Shift)&0x03;
11061 stats->bICV = desc->ICV;
11062 stats->bCRC = desc->CRC32;
11063 stats->bHwError = stats->bCRC|stats->bICV;
11064 stats->Decrypted = !desc->SWDec;//RTL8190 set this bit to indicate that Hw does not decrypt packet
11065 stats->bIsAMPDU = (desc->AMSDU==1);
11066 stats->bFirstMPDU = (desc->PAGGR==1) && (desc->FAGGR==1);
11067 stats->bShortPreamble = desc->SPLCP;
11068 stats->RxIs40MHzPacket = (desc->BW==1);
11069 stats->TimeStampLow = desc->TSFL;
11071 if((desc->FAGGR==1) || (desc->PAGGR==1))
11072 {// Rx A-MPDU
11073 RT_TRACE(COMP_RXDESC, "FirstAGGR = %d, PartAggr = %d\n", desc->FAGGR, desc->PAGGR);
11075 //YJ,test,090310
11076 if(stats->bHwError)
11078 if(stats->bICV)
11079 printk("%s: Receive ICV error!!!!!!!!!!!!!!!!!!!!!!\n", __FUNCTION__);
11080 if(stats->bCRC)
11081 printk("%s: Receive CRC error!!!!!!!!!!!!!!!!!!!!!!\n", __FUNCTION__);
11084 if(IS_UNDER_11N_AES_MODE(priv->ieee80211))
11086 // Always received ICV error packets in AES mode.
11087 // This fixed HW later MIC write bug.
11088 if(stats->bICV && !stats->bCRC)
11090 stats->bICV = FALSE;
11091 stats->bHwError = FALSE;
11095 // Transform HwRate to MRate
11096 if(!stats->bHwError)
11097 //stats->DataRate = HwRateToMRate(
11098 // (BOOLEAN)GET_RX_DESC_RXHT(pDesc),
11099 // (u1Byte)GET_RX_DESC_RXMCS(pDesc),
11100 // (BOOLEAN)GET_RX_DESC_PAGGR(pDesc));
11101 stats->rate = rtl8192SU_HwRateToMRate(desc->RxHT, desc->RxMCS, desc->PAGGR);
11102 else
11103 stats->rate = MGN_1M;
11106 // Collect Rx rate/AMPDU/TSFL
11108 //UpdateRxdRateHistogramStatistics8192S(Adapter, pRfd);
11109 //UpdateRxAMPDUHistogramStatistics8192S(Adapter, pRfd);
11110 //UpdateRxPktTimeStamp8192S(Adapter, pRfd);
11111 UpdateReceivedRateHistogramStatistics8190(dev, stats);
11112 //UpdateRxAMPDUHistogramStatistics8192S(dev, stats); //FIXLZM
11113 UpdateRxPktTimeStamp8190(dev, stats);
11116 // Get PHY Status and RSVD parts.
11117 // <Roger_Notes> It only appears on last aggregated packet.
11119 if (desc->PHYStatus)
11121 //driver_info = (rx_drvinfo_819x_usb *)(skb->data + RX_DESC_SIZE + stats->RxBufShift);
11122 driver_info = (rx_drvinfo_819x_usb *)(skb->data + sizeof(rx_desc_819x_usb) + \
11123 stats->RxBufShift);
11124 if(0)
11126 int m = 0;
11127 printk("========================\n");
11128 printk("RX_DESC_SIZE:%d, RxBufShift:%d, RxDrvInfoSize:%d\n",
11129 RX_DESC_SIZE, stats->RxBufShift, stats->RxDrvInfoSize);
11130 for(m=0; m<32; m++){
11131 printk("%2x ",((u8*)driver_info)[m]);
11133 printk("\n========================\n");
11139 //YJ,add,090107
11140 skb_pull(skb, sizeof(rx_desc_819x_usb));
11141 //YJ,add,090107,end
11144 // Get Total offset of MPDU Frame Body
11146 if((stats->RxBufShift + stats->RxDrvInfoSize) > 0)
11148 stats->bShift = 1;
11149 //YJ,add,090107
11150 skb_pull(skb, stats->RxBufShift + stats->RxDrvInfoSize);
11151 //YJ,add,090107,end
11155 // Get PHY Status and RSVD parts.
11156 // <Roger_Notes> It only appears on last aggregated packet.
11158 if (desc->PHYStatus)
11160 rtl8192SU_TranslateRxSignalStuff(skb, stats, desc, driver_info);
11163 #else
11164 void query_rxdesc_status(struct sk_buff *skb, struct ieee80211_rx_stats *stats, bool bIsRxAggrSubframe)
11166 rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
11167 struct net_device *dev=info->dev;
11168 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
11169 //rx_desc_819x_usb *desc = (rx_desc_819x_usb *)skb->data;
11170 rx_drvinfo_819x_usb *driver_info = NULL;
11173 //Get Rx Descriptor Information
11175 #ifdef USB_RX_AGGREGATION_SUPPORT
11176 if (bIsRxAggrSubframe)
11178 rx_desc_819x_usb_aggr_subframe *desc = (rx_desc_819x_usb_aggr_subframe *)skb->data;
11179 stats->Length = desc->Length ;
11180 stats->RxDrvInfoSize = desc->RxDrvInfoSize;
11181 stats->RxBufShift = 0; //RxBufShift = 2 in RxDesc, but usb didn't shift bytes in fact.
11182 stats->bICV = desc->ICV;
11183 stats->bCRC = desc->CRC32;
11184 stats->bHwError = stats->bCRC|stats->bICV;
11185 stats->Decrypted = !desc->SWDec;//RTL8190 set this bit to indicate that Hw does not decrypt packet
11186 } else
11187 #endif
11189 rx_desc_819x_usb *desc = (rx_desc_819x_usb *)skb->data;
11191 stats->Length = desc->Length;
11192 stats->RxDrvInfoSize = desc->RxDrvInfoSize;
11193 stats->RxBufShift = 0;//desc->Shift&0x03;
11194 stats->bICV = desc->ICV;
11195 stats->bCRC = desc->CRC32;
11196 stats->bHwError = stats->bCRC|stats->bICV;
11197 //RTL8190 set this bit to indicate that Hw does not decrypt packet
11198 stats->Decrypted = !desc->SWDec;
11201 if((priv->ieee80211->pHTInfo->bCurrentHTSupport == true) && (priv->ieee80211->pairwise_key_type == KEY_TYPE_CCMP))
11203 stats->bHwError = false;
11205 else
11207 stats->bHwError = stats->bCRC|stats->bICV;
11210 if(stats->Length < 24 || stats->Length > MAX_8192U_RX_SIZE)
11211 stats->bHwError |= 1;
11213 //Get Driver Info
11215 // TODO: Need to verify it on FGPA platform
11216 //Driver info are written to the RxBuffer following rx desc
11217 if (stats->RxDrvInfoSize != 0) {
11218 driver_info = (rx_drvinfo_819x_usb *)(skb->data + sizeof(rx_desc_819x_usb) + \
11219 stats->RxBufShift);
11220 /* unit: 0.5M */
11221 /* TODO */
11222 if(!stats->bHwError){
11223 u8 ret_rate;
11224 ret_rate = HwRateToMRate90(driver_info->RxHT, driver_info->RxRate);
11225 if(ret_rate == 0xff)
11227 // Abnormal Case: Receive CRC OK packet with Rx descriptor indicating non supported rate.
11228 // Special Error Handling here, 2008.05.16, by Emily
11230 stats->bHwError = 1;
11231 stats->rate = MGN_1M; //Set 1M rate by default
11232 }else
11234 stats->rate = ret_rate;
11237 else
11238 stats->rate = 0x02;
11240 stats->bShortPreamble = driver_info->SPLCP;
11243 UpdateReceivedRateHistogramStatistics8190(dev, stats);
11245 stats->bIsAMPDU = (driver_info->PartAggr==1);
11246 stats->bFirstMPDU = (driver_info->PartAggr==1) && (driver_info->FirstAGGR==1);
11247 #if 0
11248 // TODO: it is debug only. It should be disabled in released driver. 2007.1.12 by Joseph
11249 UpdateRxAMPDUHistogramStatistics8190(Adapter, pRfd);
11250 #endif
11251 stats->TimeStampLow = driver_info->TSFL;
11252 // xiong mask it, 070514
11253 //pRfd->Status.TimeStampHigh = PlatformEFIORead4Byte(Adapter, TSFR+4);
11254 // stats->TimeStampHigh = read_nic_dword(dev, TSFR+4);
11256 UpdateRxPktTimeStamp8190(dev, stats);
11259 // Rx A-MPDU
11261 if(driver_info->FirstAGGR==1 || driver_info->PartAggr == 1)
11262 RT_TRACE(COMP_RXDESC, "driver_info->FirstAGGR = %d, driver_info->PartAggr = %d\n",
11263 driver_info->FirstAGGR, driver_info->PartAggr);
11267 skb_pull(skb,sizeof(rx_desc_819x_usb));
11269 // Get Total offset of MPDU Frame Body
11271 if((stats->RxBufShift + stats->RxDrvInfoSize) > 0) {
11272 stats->bShift = 1;
11273 skb_pull(skb,stats->RxBufShift + stats->RxDrvInfoSize);
11276 #ifdef USB_RX_AGGREGATION_SUPPORT
11277 /* for the rx aggregated sub frame, the redundant space truelly contained in the packet */
11278 if(bIsRxAggrSubframe) {
11279 skb_pull(skb, 8);
11281 #endif
11282 /* for debug 2008.5.29 */
11283 #if 0
11285 int i;
11286 printk("\n>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
11287 for(i = 0; i < skb->len; i++) {
11288 if(i % 10 == 0) printk("\n");
11289 printk("%02x ", skb->data[i]);
11291 printk("\n<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
11293 #endif
11295 //added by vivi, for MP, 20080108
11296 stats->RxIs40MHzPacket = driver_info->BW;
11297 if(stats->RxDrvInfoSize != 0)
11298 TranslateRxSignalStuff819xUsb(skb, stats, driver_info);
11301 #endif
11303 #ifdef RTL8192SU
11304 #if 0
11305 /*-----------------------------------------------------------------------------
11306 * Function: UpdateRxAMPDUHistogramStatistics8192S
11308 * Overview: Recored down the received A-MPDU aggregation size and pkt number
11310 * Input: Adapter
11312 * Output: Adapter
11313 * (Adapter->RxStats.RxAMPDUSizeHistogram[] is updated)
11314 * (Adapter->RxStats.RxAMPDUNumHistogram[] is updated)
11316 * Return: NONE
11318 * Revised History:
11319 * When Who Remark
11320 * 09/18/2008 MHC Create Version 0.
11322 *---------------------------------------------------------------------------*/
11323 static void
11324 UpdateRxAMPDUHistogramStatistics8192S(
11325 struct net_device *dev,
11326 struct ieee80211_rx_stats *stats
11329 //HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
11330 u8 size_index;
11331 u8 num_index;
11332 u16 update_size = 0;
11333 u8 update_num = 0;
11335 if(stats->bIsAMPDU)
11337 if(stats->bFirstMPDU)
11339 if(stats->nRxAMPDU_Size!=0 && stats->nRxAMPDU_AggrNum!=0)
11341 update_size = stats->nRxAMPDU_Size;
11342 update_num = stats->nRxAMPDU_AggrNum;
11344 stats->nRxAMPDU_Size = stats->Length;
11345 stats->nRxAMPDU_AggrNum = 1;
11347 else
11349 stats->nRxAMPDU_Size += stats->Length;
11350 stats->nRxAMPDU_AggrNum++;
11353 else
11355 if(stats->nRxAMPDU_Size!=0 && stats->nRxAMPDU_AggrNum!=0)
11357 update_size = stats->nRxAMPDU_Size;
11358 update_num = stats->nRxAMPDU_AggrNum;
11360 stats->nRxAMPDU_Size = 0;
11361 stats->nRxAMPDU_AggrNum = 0;
11364 if(update_size!=0 && update_num!= 0)
11366 if(update_size < 4096)
11367 size_index = 0;
11368 else if(update_size < 8192)
11369 size_index = 1;
11370 else if(update_size < 16384)
11371 size_index = 2;
11372 else if(update_size < 32768)
11373 size_index = 3;
11374 else if(update_size < 65536)
11375 size_index = 4;
11376 else
11378 RT_TRACE(COMP_RXDESC,
11379 ("UpdateRxAMPDUHistogramStatistics8192S(): A-MPDU too large\n");
11382 Adapter->RxStats.RxAMPDUSizeHistogram[size_index]++;
11384 if(update_num < 5)
11385 num_index = 0;
11386 else if(update_num < 10)
11387 num_index = 1;
11388 else if(update_num < 20)
11389 num_index = 2;
11390 else if(update_num < 40)
11391 num_index = 3;
11392 else
11393 num_index = 4;
11395 Adapter->RxStats.RxAMPDUNumHistogram[num_index]++;
11397 } // UpdateRxAMPDUHistogramStatistics8192S
11398 #endif
11400 #endif
11403 #ifdef RTL8192SU
11405 // Description:
11406 // The strarting address of wireless lan header will shift 1 or 2 or 3 or "more" bytes for the following reason :
11407 // (1) QoS control : shift 2 bytes
11408 // (2) Mesh Network : shift 1 or 3 bytes
11409 // (3) RxDriverInfo occupies the front parts of Rx Packets buffer(shift units is in 8Bytes)
11411 // It is because Lextra CPU used by 8186 or 865x series assert exception if the statrting address
11412 // of IP header is not double word alignment.
11413 // This features is supported in 818xb and 8190 only, but not 818x.
11415 // parameter: PRT_RFD, Pointer of Reeceive frame descriptor which is initialized according to
11416 // Rx Descriptor
11417 // return value: unsigned int, number of total shifted bytes
11419 // Notes: 2008/06/28, created by Roger
11421 u32 GetRxPacketShiftBytes8192SU(struct ieee80211_rx_stats *Status, bool bIsRxAggrSubframe)
11423 //PRT_RFD_STATUS pRtRfdStatus = &pRfd->Status;
11425 return (sizeof(rx_desc_819x_usb) + Status->RxDrvInfoSize + Status->RxBufShift);
11428 void rtl8192SU_rx_nomal(struct sk_buff* skb)
11430 rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
11431 struct net_device *dev=info->dev;
11432 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
11433 struct ieee80211_rx_stats stats = {
11434 .signal = 0,
11435 .noise = -98,
11436 .rate = 0,
11437 // .mac_time = jiffies,
11438 .freq = IEEE80211_24GHZ_BAND,
11440 u32 rx_pkt_len = 0;
11441 struct ieee80211_hdr_1addr *ieee80211_hdr = NULL;
11442 bool unicast_packet = false;
11444 #ifdef USB_RX_AGGREGATION_SUPPORT
11445 struct sk_buff *agg_skb = NULL;
11446 u32 TotalLength = 0;//Total packet length for all aggregated packets.
11447 u32 TempDWord = 0;
11448 u32 PacketLength = 0;// Per-packet length include size of RxDesc.
11449 u32 PacketOccupiedLendth = 0;
11450 u8 TempByte = 0;
11451 u32 PacketShiftBytes = 0;
11452 rx_desc_819x_usb_aggr_subframe *RxDescr = NULL;
11453 u8 PaddingBytes = 0;
11454 //add just for testing
11455 u8 testing;
11457 u8 TotalAggPkt = 0;
11458 PRT_HIGH_THROUGHPUT pHTInfo =priv-> ieee80211->pHTInfo;
11459 u16 RxPageSize = pHTInfo->UsbRxPageSize;
11461 stats->nTotalAggPkt = 0;
11462 //stats->bIsRxAggrSubframe = FALSE;
11464 #endif
11465 //printk("**********skb->len = %d\n", skb->len);
11466 /* 20 is for ps-poll */
11467 if((skb->len >=(20 + sizeof(rx_desc_819x_usb))) && (skb->len < RX_URB_SIZE)) {
11469 /* first packet should not contain Rx aggregation header */
11470 rtl8192SU_query_rxdesc_status(skb, &stats, false);
11471 /* TODO */
11473 /* hardware related info */
11474 #ifdef USB_RX_AGGREGATION_SUPPORT
11475 TotalAggPkt = stats->nTotalAggPkt;
11476 PacketLength = stats->Length + GetRxPacketShiftBytes8192SU(&stats, false);
11478 agg_skb = skb;
11479 skb = dev_alloc_skb(PacketLength);
11480 memcpy(skb_put(skb,PacketLength),agg_skb->data,PacketLength);
11481 #endif
11482 priv->stats.rxoktotal++; //YJ,test,090108
11484 /* Process the MPDU recevied */
11485 skb_trim(skb, skb->len - 4/*sCrcLng*/);//FIXLZM
11487 rx_pkt_len = skb->len;
11488 ieee80211_hdr = (struct ieee80211_hdr_1addr *)skb->data;
11489 unicast_packet = false;
11490 if(is_broadcast_ether_addr(ieee80211_hdr->addr1)) {
11491 //TODO
11492 }else if(is_multicast_ether_addr(ieee80211_hdr->addr1)){
11493 //TODO
11494 }else {
11495 /* unicast packet */
11496 unicast_packet = true;
11499 if(!ieee80211_rx(priv->ieee80211,skb, &stats)) {
11500 dev_kfree_skb_any(skb);
11501 } else {
11502 // priv->stats.rxoktotal++; //YJ,test,090108
11503 if(unicast_packet) {
11504 priv->stats.rxbytesunicast += rx_pkt_len;
11508 //up is firs pkt, follow is next and next
11509 #ifdef USB_RX_AGGREGATION_SUPPORT
11511 // The following operations are for processing Rx aggregated packets.
11513 if(TotalAggPkt>0)
11514 TotalAggPkt--;
11516 while ( TotalAggPkt>0 )
11517 {// More aggregated packets need to process.
11519 u8 tmpCRC = 0, tmpICV = 0;
11521 //Page size must align to multiple of 128-Bytes.
11522 if((PacketLength%RxPageSize) != 0)
11523 //PacketLength = ((PacketLength/RxPageSize)+1)*RxPageSize;
11524 PacketLength = ((PacketLength>>7)+1)*RxPageSize; // RxPageSize is 128bytes as default.
11526 // Current total packet occupied length in this buffer.
11527 PacketOccupiedLendth += PacketLength;
11529 #if (defined (RTL8192SU_FPGA_2MAC_VERIFICATION)||defined (RTL8192SU_ASIC_VERIFICATION))
11530 //if(PacketOccupiedLendth>pContext->BufLenUsed)
11531 if(PacketOccupiedLendth>skb->len)
11533 RT_TRACE(COMP_RECV, "(1)HalUsbInMpduComplete8192SUsb(): pRtRfdStatus->Length(%#x)!!\n", stats->Length);
11534 RT_TRACE(COMP_RECV, "(1)HalUsbInMpduComplete8192SUsb(): Invalid PacketOccupiedLendth(%#x)!!, BufLenUsed(%#x)\n", PacketOccupiedLendth, stats->BufLenUsed);
11535 break;
11537 #endif
11539 skb_pull(agg_skb, PacketLength);
11542 // Process the MPDU recevied.
11544 //RT_TRACE(COMP_RECV,"%s:aggred pkt,total_len = %d\n",__FUNCTION__,agg_skb->len);
11545 RxDescr = (rx_desc_819x_usb_aggr_subframe *)(agg_skb->data);
11547 #if 0//92SU del
11548 tmpCRC = RxDescr->CRC32;
11549 tmpICV = RxDescr->ICV;
11550 memcpy(agg_skb->data, &agg_skb->data[44], 2);
11551 RxDescr->CRC32 = tmpCRC;
11552 RxDescr->ICV = tmpICV;
11553 #endif
11554 memset(&stats, 0, sizeof(struct ieee80211_rx_stats));
11555 stats.signal = 0;
11556 stats.noise = -98;
11557 stats.rate = 0;
11558 stats.freq = IEEE80211_24GHZ_BAND;
11560 rtl8192SU_query_rxdesc_status(agg_skb, &stats, true);
11561 //PacketLength = stats.Length;
11562 PacketLength = stats.Length + GetRxPacketShiftBytes8192SU(&stats, true);
11564 #if (defined (RTL8192SU_FPGA_2MAC_VERIFICATION)||defined (RTL8192SU_ASIC_VERIFICATION))
11565 if((PacketOccupiedLendth+PacketLength)>skb->len)
11567 RT_TRACE(COMP_RECV, "(2)HalUsbInMpduComplete8192SUsb(): Invalid PacketOccupiedLendth(%#x)+PacketLength(%#x)!!, BufLenUsed(%#x)\n",
11568 PacketOccupiedLendth, PacketLength, pContext->BufLenUsed);
11569 break;
11571 #endif
11573 if(PacketLength > agg_skb->len) {
11574 break;
11577 /* Process the MPDU recevied */
11578 skb = dev_alloc_skb(PacketLength);
11579 memcpy(skb_put(skb,PacketLength),agg_skb->data, PacketLength);
11580 skb_trim(skb, skb->len - 4/*sCrcLng*/);
11582 rx_pkt_len = skb->len;
11583 ieee80211_hdr = (struct ieee80211_hdr_1addr *)skb->data;
11584 unicast_packet = false;
11585 if(is_broadcast_ether_addr(ieee80211_hdr->addr1)) {
11586 //TODO
11587 }else if(is_multicast_ether_addr(ieee80211_hdr->addr1)){
11588 //TODO
11589 }else {
11590 /* unicast packet */
11591 unicast_packet = true;
11593 if(!ieee80211_rx(priv->ieee80211,skb, &stats)) {
11594 dev_kfree_skb_any(skb);
11595 } else {
11596 priv->stats.rxoktotal++;
11597 if(unicast_packet) {
11598 priv->stats.rxbytesunicast += rx_pkt_len;
11602 TotalAggPkt--;
11604 skb_pull(agg_skb, TempDWord);
11607 dev_kfree_skb(agg_skb);
11608 #endif
11610 else
11612 priv->stats.rxurberr++;
11613 printk("actual_length:%d\n", skb->len);
11614 dev_kfree_skb_any(skb);
11618 #else
11619 u32 GetRxPacketShiftBytes819xUsb(struct ieee80211_rx_stats *Status, bool bIsRxAggrSubframe)
11621 #ifdef USB_RX_AGGREGATION_SUPPORT
11622 if (bIsRxAggrSubframe)
11623 return (sizeof(rx_desc_819x_usb) + Status->RxDrvInfoSize
11624 + Status->RxBufShift + 8);
11625 else
11626 #endif
11627 return (sizeof(rx_desc_819x_usb) + Status->RxDrvInfoSize
11628 + Status->RxBufShift);
11631 void rtl8192_rx_nomal(struct sk_buff* skb)
11633 rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
11634 struct net_device *dev=info->dev;
11635 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
11636 struct ieee80211_rx_stats stats = {
11637 .signal = 0,
11638 .noise = -98,
11639 .rate = 0,
11640 // .mac_time = jiffies,
11641 .freq = IEEE80211_24GHZ_BAND,
11643 u32 rx_pkt_len = 0;
11644 struct ieee80211_hdr_1addr *ieee80211_hdr = NULL;
11645 bool unicast_packet = false;
11646 #ifdef USB_RX_AGGREGATION_SUPPORT
11647 struct sk_buff *agg_skb = NULL;
11648 u32 TotalLength = 0;
11649 u32 TempDWord = 0;
11650 u32 PacketLength = 0;
11651 u32 PacketOccupiedLendth = 0;
11652 u8 TempByte = 0;
11653 u32 PacketShiftBytes = 0;
11654 rx_desc_819x_usb_aggr_subframe *RxDescr = NULL;
11655 u8 PaddingBytes = 0;
11656 //add just for testing
11657 u8 testing;
11659 #endif
11661 /* 20 is for ps-poll */
11662 if((skb->len >=(20 + sizeof(rx_desc_819x_usb))) && (skb->len < RX_URB_SIZE)) {
11663 #ifdef USB_RX_AGGREGATION_SUPPORT
11664 TempByte = *(skb->data + sizeof(rx_desc_819x_usb));
11665 #endif
11666 /* first packet should not contain Rx aggregation header */
11667 query_rxdesc_status(skb, &stats, false);
11668 /* TODO */
11669 /* hardware related info */
11670 #ifdef USB_RX_AGGREGATION_SUPPORT
11671 if (TempByte & BIT0) {
11672 agg_skb = skb;
11673 //TotalLength = agg_skb->len - 4; /*sCrcLng*/
11674 TotalLength = stats.Length - 4; /*sCrcLng*/
11675 //RT_TRACE(COMP_RECV, "%s:first aggregated packet!Length=%d\n",__FUNCTION__,TotalLength);
11676 /* though the head pointer has passed this position */
11677 TempDWord = *(u32 *)(agg_skb->data - 4);
11678 PacketLength = (u16)(TempDWord & 0x3FFF); /*sCrcLng*/
11679 skb = dev_alloc_skb(PacketLength);
11680 memcpy(skb_put(skb,PacketLength),agg_skb->data,PacketLength);
11681 PacketShiftBytes = GetRxPacketShiftBytes819xUsb(&stats, false);
11683 #endif
11684 /* Process the MPDU recevied */
11685 skb_trim(skb, skb->len - 4/*sCrcLng*/);
11687 rx_pkt_len = skb->len;
11688 ieee80211_hdr = (struct ieee80211_hdr_1addr *)skb->data;
11689 unicast_packet = false;
11690 if(is_broadcast_ether_addr(ieee80211_hdr->addr1)) {
11691 //TODO
11692 }else if(is_multicast_ether_addr(ieee80211_hdr->addr1)){
11693 //TODO
11694 }else {
11695 /* unicast packet */
11696 unicast_packet = true;
11699 if(!ieee80211_rx(priv->ieee80211,skb, &stats)) {
11700 dev_kfree_skb_any(skb);
11701 } else {
11702 priv->stats.rxoktotal++;
11703 if(unicast_packet) {
11704 priv->stats.rxbytesunicast += rx_pkt_len;
11707 #ifdef USB_RX_AGGREGATION_SUPPORT
11708 testing = 1;
11709 // (PipeIndex == 0) && (TempByte & BIT0) => TotalLength > 0.
11710 if (TotalLength > 0) {
11711 PacketOccupiedLendth = PacketLength + (PacketShiftBytes + 8);
11712 if ((PacketOccupiedLendth & 0xFF) != 0)
11713 PacketOccupiedLendth = (PacketOccupiedLendth & 0xFFFFFF00) + 256;
11714 PacketOccupiedLendth -= 8;
11715 TempDWord = PacketOccupiedLendth - PacketShiftBytes; /*- PacketLength */
11716 if (agg_skb->len > TempDWord)
11717 skb_pull(agg_skb, TempDWord);
11718 else
11719 agg_skb->len = 0;
11721 while (agg_skb->len>=GetRxPacketShiftBytes819xUsb(&stats, true)) {
11722 u8 tmpCRC = 0, tmpICV = 0;
11723 //RT_TRACE(COMP_RECV,"%s:aggred pkt,total_len = %d\n",__FUNCTION__,agg_skb->len);
11724 RxDescr = (rx_desc_819x_usb_aggr_subframe *)(agg_skb->data);
11725 tmpCRC = RxDescr->CRC32;
11726 tmpICV = RxDescr->ICV;
11727 memcpy(agg_skb->data, &agg_skb->data[44], 2);
11728 RxDescr->CRC32 = tmpCRC;
11729 RxDescr->ICV = tmpICV;
11731 memset(&stats, 0, sizeof(struct ieee80211_rx_stats));
11732 stats.signal = 0;
11733 stats.noise = -98;
11734 stats.rate = 0;
11735 stats.freq = IEEE80211_24GHZ_BAND;
11736 query_rxdesc_status(agg_skb, &stats, true);
11737 PacketLength = stats.Length;
11739 if(PacketLength > agg_skb->len) {
11740 break;
11742 /* Process the MPDU recevied */
11743 skb = dev_alloc_skb(PacketLength);
11744 memcpy(skb_put(skb,PacketLength),agg_skb->data, PacketLength);
11745 skb_trim(skb, skb->len - 4/*sCrcLng*/);
11747 rx_pkt_len = skb->len;
11748 ieee80211_hdr = (struct ieee80211_hdr_1addr *)skb->data;
11749 unicast_packet = false;
11750 if(is_broadcast_ether_addr(ieee80211_hdr->addr1)) {
11751 //TODO
11752 }else if(is_multicast_ether_addr(ieee80211_hdr->addr1)){
11753 //TODO
11754 }else {
11755 /* unicast packet */
11756 unicast_packet = true;
11758 if(!ieee80211_rx(priv->ieee80211,skb, &stats)) {
11759 dev_kfree_skb_any(skb);
11760 } else {
11761 priv->stats.rxoktotal++;
11762 if(unicast_packet) {
11763 priv->stats.rxbytesunicast += rx_pkt_len;
11766 /* should trim the packet which has been copied to target skb */
11767 skb_pull(agg_skb, PacketLength);
11768 PacketShiftBytes = GetRxPacketShiftBytes819xUsb(&stats, true);
11769 PacketOccupiedLendth = PacketLength + PacketShiftBytes;
11770 if ((PacketOccupiedLendth & 0xFF) != 0) {
11771 PaddingBytes = 256 - (PacketOccupiedLendth & 0xFF);
11772 if (agg_skb->len > PaddingBytes)
11773 skb_pull(agg_skb, PaddingBytes);
11774 else
11775 agg_skb->len = 0;
11778 dev_kfree_skb(agg_skb);
11780 #endif
11781 } else {
11782 priv->stats.rxurberr++;
11783 printk("actual_length:%d\n", skb->len);
11784 dev_kfree_skb_any(skb);
11789 #endif
11791 void
11792 rtl819xusb_process_received_packet(
11793 struct net_device *dev,
11794 struct ieee80211_rx_stats *pstats
11797 // bool bfreerfd=false, bqueued=false;
11798 u8* frame;
11799 u16 frame_len=0;
11800 struct r8192_priv *priv = ieee80211_priv(dev);
11801 // u8 index = 0;
11802 // u8 TID = 0;
11803 //u16 seqnum = 0;
11804 //PRX_TS_RECORD pts = NULL;
11806 // Get shifted bytes of Starting address of 802.11 header. 2006.09.28, by Emily
11807 //porting by amy 080508
11808 pstats->virtual_address += get_rxpacket_shiftbytes_819xusb(pstats);
11809 frame = pstats->virtual_address;
11810 frame_len = pstats->packetlength;
11811 #ifdef TODO // by amy about HCT
11812 if(!Adapter->bInHctTest)
11813 CountRxErrStatistics(Adapter, pRfd);
11814 #endif
11816 #ifdef ENABLE_PS //by amy for adding ps function in future
11817 RT_RF_POWER_STATE rtState;
11818 // When RF is off, we should not count the packet for hw/sw synchronize
11819 // reason, ie. there may be a duration while sw switch is changed and hw
11820 // switch is being changed. 2006.12.04, by shien chang.
11821 Adapter->HalFunc.GetHwRegHandler(Adapter, HW_VAR_RF_STATE, (u8* )(&rtState));
11822 if (rtState == eRfOff)
11824 return;
11826 #endif
11827 priv->stats.rxframgment++;
11830 #ifdef TODO
11831 RmMonitorSignalStrength(Adapter, pRfd);
11832 #endif
11833 /* 2007/01/16 MH Add RX command packet handle here. */
11834 /* 2007/03/01 MH We have to release RFD and return if rx pkt is cmd pkt. */
11835 if (rtl819xusb_rx_command_packet(dev, pstats))
11837 return;
11840 #ifdef SW_CRC_CHECK
11841 SwCrcCheck();
11842 #endif
11847 void query_rx_cmdpkt_desc_status(struct sk_buff *skb, struct ieee80211_rx_stats *stats)
11849 // rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
11850 // struct net_device *dev=info->dev;
11851 // struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
11852 rx_desc_819x_usb *desc = (rx_desc_819x_usb *)skb->data;
11853 // rx_drvinfo_819x_usb *driver_info;
11856 //Get Rx Descriptor Information
11858 stats->virtual_address = (u8*)skb->data;
11859 stats->Length = desc->Length;
11860 stats->RxDrvInfoSize = 0;
11861 stats->RxBufShift = 0;
11862 stats->packetlength = stats->Length-scrclng;
11863 stats->fraglength = stats->packetlength;
11864 stats->fragoffset = 0;
11865 stats->ntotalfrag = 1;
11868 #ifdef RTL8192SU
11869 void rtl8192SU_rx_cmd(struct sk_buff *skb)
11871 struct rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
11872 struct net_device *dev = info->dev;
11874 /* TODO */
11875 struct ieee80211_rx_stats stats = {
11876 .signal = 0,
11877 .noise = -98,
11878 .rate = 0,
11879 // .mac_time = jiffies,
11880 .freq = IEEE80211_24GHZ_BAND,
11884 // Check buffer length to determine if this is a valid MPDU.
11886 if( (skb->len >= sizeof(rx_desc_819x_usb)) && (skb->len <= RX_URB_SIZE) )//&&
11887 //(pHalData->SwChnlInProgress == FALSE))
11890 // Collection information in Rx descriptor.
11892 #if 0
11893 pRxDesc = pContext->Buffer;
11895 pRfd->Buffer.VirtualAddress = pContext->Buffer; // 061109, rcnjko, for multi-platform consideration..
11897 pRtRfdStatus->Length = (u2Byte)GET_RX_DESC_PKT_LEN(pRxDesc);
11898 pRtRfdStatus->RxDrvInfoSize = 0;
11899 pRtRfdStatus->RxBufShift = 0;
11901 pRfd->PacketLength = pRfd->Status.Length - sCrcLng;
11902 pRfd->FragLength = pRfd->PacketLength;
11903 pRfd->FragOffset = 0;
11904 pRfd->nTotalFrag = 1;
11905 pRfd->queue_id = PipeIndex;
11906 #endif
11907 query_rx_cmdpkt_desc_status(skb,&stats);
11908 // this is to be done by amy 080508 prfd->queue_id = 1;
11911 // Process the MPDU recevied.
11913 rtl819xusb_process_received_packet(dev,&stats);
11915 dev_kfree_skb_any(skb);
11917 else
11919 //RTInsertTailListWithCnt(&pAdapter->RfdIdleQueue, &pRfd->List, &pAdapter->NumIdleRfd);
11920 //RT_ASSERT(pAdapter->NumIdleRfd <= pAdapter->NumRfd, ("HalUsbInCommandComplete8192SUsb(): Adapter->NumIdleRfd(%d)\n", pAdapter->NumIdleRfd));
11921 //RT_TRACE(COMP_RECV, DBG_LOUD, ("HalUsbInCommandComplete8192SUsb(): NOT enough Resources!! BufLenUsed(%d), NumIdleRfd(%d)\n",
11922 //pContext->BufLenUsed, pAdapter->NumIdleRfd));
11926 // Reuse USB_IN_CONTEXT since we had finished processing the
11927 // buffer in USB_IN_CONTEXT.
11929 //HalUsbReturnInContext(pAdapter, pContext);
11932 // Issue another bulk IN transfer.
11934 //HalUsbInMpdu(pAdapter, PipeIndex);
11936 RT_TRACE(COMP_RECV, "<--- HalUsbInCommandComplete8192SUsb()\n");
11939 #else
11940 void rtl8192_rx_cmd(struct sk_buff *skb)
11942 struct rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
11943 struct net_device *dev = info->dev;
11944 //int ret;
11945 // struct urb *rx_urb = info->urb;
11946 /* TODO */
11947 struct ieee80211_rx_stats stats = {
11948 .signal = 0,
11949 .noise = -98,
11950 .rate = 0,
11951 // .mac_time = jiffies,
11952 .freq = IEEE80211_24GHZ_BAND,
11955 if((skb->len >=(20 + sizeof(rx_desc_819x_usb))) && (skb->len < RX_URB_SIZE))
11958 query_rx_cmdpkt_desc_status(skb,&stats);
11959 // this is to be done by amy 080508 prfd->queue_id = 1;
11963 // Process the command packet received.
11966 rtl819xusb_process_received_packet(dev,&stats);
11968 dev_kfree_skb_any(skb);
11970 else
11974 #if 0
11975 desc = (u32*)(skb->data);
11976 cmd = (desc[0] >> 30) & 0x03;
11978 if(cmd == 0x00) {//beacon interrupt
11979 //send beacon packet
11980 skb = ieee80211_get_beacon(priv->ieee80211);
11982 if(!skb){
11983 DMESG("not enought memory for allocating beacon");
11984 return;
11986 skb->cb[0] = BEACON_PRIORITY;
11987 skb->cb[1] = 0;
11988 skb->cb[2] = ieeerate2rtlrate(priv->ieee80211->basic_rate);
11989 ret = rtl8192_tx(dev, skb);
11991 if( ret != 0 ){
11992 printk(KERN_ALERT "tx beacon packet error : %d !\n", ret);
11994 dev_kfree_skb_any(skb);
11995 } else {//0x00
11996 //{ log the device information
11997 // At present, It is not implemented just now.
12000 #endif
12002 #endif
12004 void rtl8192_irq_rx_tasklet(struct r8192_priv *priv)
12006 struct sk_buff *skb;
12007 struct rtl8192_rx_info *info;
12009 while (NULL != (skb = skb_dequeue(&priv->skb_queue))) {
12010 info = (struct rtl8192_rx_info *)skb->cb;
12011 switch (info->out_pipe) {
12012 /* Nomal packet pipe */
12013 case 3:
12014 //RT_TRACE(COMP_RECV, "normal in-pipe index(%d)\n",info->out_pipe);
12015 priv->IrpPendingCount--;
12016 priv->ops->rtl819x_rx_nomal(skb);
12017 break;
12019 /* Command packet pipe */
12020 case 9:
12021 RT_TRACE(COMP_RECV, "command in-pipe index(%d)\n",\
12022 info->out_pipe);
12023 priv->ops->rtl819x_rx_cmd(skb);
12024 break;
12026 default: /* should never get here! */
12027 RT_TRACE(COMP_ERR, "Unknown in-pipe index(%d)\n",\
12028 info->out_pipe);
12029 dev_kfree_skb(skb);
12030 break;
12038 /****************************************************************************
12039 ---------------------------- USB_STUFF---------------------------
12040 *****************************************************************************/
12041 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
12042 //LZM Merge from windows HalUsbSetQueuePipeMapping8192SUsb 090319
12043 static void HalUsbSetQueuePipeMapping8192SUsb(struct usb_interface *intf, struct net_device *dev)
12045 struct r8192_priv *priv = ieee80211_priv(dev);
12046 struct usb_host_interface *iface_desc;
12047 struct usb_endpoint_descriptor *endpoint;
12048 u8 i = 0;
12050 priv->ep_in_num = 0;
12051 priv->ep_out_num = 0;
12052 memset(priv->RtOutPipes,0,16);
12053 memset(priv->RtInPipes,0,16);
12055 #ifndef USE_ONE_PIPE
12056 iface_desc = intf->cur_altsetting;
12057 priv->ep_num = iface_desc->desc.bNumEndpoints;
12059 for (i = 0; i < priv->ep_num; ++i) {
12060 endpoint = &iface_desc->endpoint[i].desc;
12061 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,23)
12062 if (usb_endpoint_is_bulk_in(endpoint)) {
12063 priv->RtInPipes[priv->ep_in_num] = usb_endpoint_num(endpoint);
12064 priv->ep_in_num ++;
12065 //printk("in_endpoint_idx = %d\n", usb_endpoint_num(endpoint));
12066 } else if (usb_endpoint_is_bulk_out(endpoint)) {
12067 priv->RtOutPipes[priv->ep_out_num] = usb_endpoint_num(endpoint);
12068 priv->ep_out_num ++;
12069 //printk("out_endpoint_idx = %d\n", usb_endpoint_num(endpoint));
12071 #else
12072 if ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) &&
12073 ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_BULK)) {
12074 /* we found a bulk in endpoint */
12075 priv->RtInPipes[priv->ep_in_num] = (endpoint->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
12076 priv->ep_in_num ++;
12077 } else if (((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT) &&
12078 ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_BULK)) {
12079 /* We found bulk out endpoint */
12080 priv->RtOutPipes[priv->ep_out_num] = endpoint->bEndpointAddress;
12081 priv->ep_out_num ++;
12083 #endif
12086 memset(priv->txqueue_to_outpipemap,0,9);
12087 if (priv->ep_num == 6) {
12088 // BK, BE, VI, VO, HCCA, TXCMD, MGNT, HIGH, BEACON
12089 u8 queuetopipe[] = {3, 2, 1, 0, 4, 4, 4, 4, 4};
12091 memcpy(priv->txqueue_to_outpipemap,queuetopipe,9);
12092 } else if (priv->ep_num == 4) {
12093 // BK, BE, VI, VO, HCCA, TXCMD, MGNT, HIGH, BEACON
12094 u8 queuetopipe[] = {1, 1, 0, 0, 2, 2, 2, 2, 2};
12096 memcpy(priv->txqueue_to_outpipemap,queuetopipe,9);
12097 } else if (priv->ep_num > 9) {
12098 // BK, BE, VI, VO, HCCA, TXCMD, MGNT, HIGH, BEACON
12099 u8 queuetopipe[] = {3, 2, 1, 0, 4, 8, 7, 6, 5};
12101 memcpy(priv->txqueue_to_outpipemap,queuetopipe,9);
12102 } else {//use sigle pipe
12103 // BK, BE, VI, VO, HCCA, TXCMD, MGNT, HIGH, BEACON
12104 u8 queuetopipe[] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
12105 memcpy(priv->txqueue_to_outpipemap,queuetopipe,9);
12108 printk("==>ep_num:%d, in_ep_num:%d, out_ep_num:%d\n", priv->ep_num, priv->ep_in_num, priv->ep_out_num);
12110 printk("==>RtInPipes:");
12111 for(i=0; i < priv->ep_in_num; i++)
12112 printk("%d ", priv->RtInPipes[i]);
12113 printk("\n");
12115 printk("==>RtOutPipes:");
12116 for(i=0; i < priv->ep_out_num; i++)
12117 printk("%d ", priv->RtOutPipes[i]);
12118 printk("\n");
12120 printk("==>txqueue_to_outpipemap for BK, BE, VI, VO, HCCA, TXCMD, MGNT, HIGH, BEACON:\n");
12121 for(i=0; i < 9; i++)
12122 printk("%d ", priv->txqueue_to_outpipemap[i]);
12123 printk("\n");
12124 #else
12126 memset(priv->txqueue_to_outpipemap,0,9);
12127 memset(priv->RtOutPipes,4,16);//all use endpoint 4 for out
12129 #endif
12131 return;
12133 #endif
12135 static const struct net_device_ops rtl8192_netdev_ops = {
12136 .ndo_open = rtl8192_open,
12137 .ndo_stop = rtl8192_close,
12138 .ndo_get_stats = rtl8192_stats,
12139 .ndo_tx_timeout = tx_timeout,
12140 .ndo_do_ioctl = rtl8192_ioctl,
12141 .ndo_set_multicast_list = r8192_set_multicast,
12142 .ndo_set_mac_address = r8192_set_mac_adr,
12143 .ndo_validate_addr = eth_validate_addr,
12144 .ndo_change_mtu = eth_change_mtu,
12145 .ndo_start_xmit = rtl8192_ieee80211_xmit,
12148 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
12149 static int __devinit rtl8192_usb_probe(struct usb_interface *intf,
12150 const struct usb_device_id *id)
12151 #else
12152 static void * __devinit rtl8192_usb_probe(struct usb_device *udev,
12153 unsigned int ifnum,
12154 const struct usb_device_id *id)
12155 #endif
12157 // unsigned long ioaddr = 0;
12158 struct net_device *dev = NULL;
12159 struct r8192_priv *priv= NULL;
12160 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
12161 struct usb_device *udev = interface_to_usbdev(intf);
12162 #endif
12163 RT_TRACE(COMP_INIT, "Oops: i'm coming\n");
12165 dev = alloc_ieee80211(sizeof(struct r8192_priv));
12167 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
12168 SET_MODULE_OWNER(dev);
12169 #endif
12171 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
12172 usb_set_intfdata(intf, dev);
12173 SET_NETDEV_DEV(dev, &intf->dev);
12174 #endif
12175 priv = ieee80211_priv(dev);
12176 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
12177 priv->ieee80211 = netdev_priv(dev);
12178 #else
12179 priv->ieee80211 = (struct net_device *)dev->priv;
12180 #endif
12181 priv->udev=udev;
12183 #ifdef RTL8192SU
12184 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
12185 HalUsbSetQueuePipeMapping8192SUsb(intf, dev);
12186 #else//use one pipe
12188 memset(priv->txqueue_to_outpipemap,0,9);
12189 memset(priv->RtOutPipes,4,16);//all use endpoint 4 for out
12191 #endif
12192 #endif
12194 #ifdef RTL8192SU
12195 //printk("===============>NIC 8192SU\n");
12196 priv->ops = &rtl8192su_ops;
12197 #else
12198 //printk("===============>NIC 8192U\n");
12199 priv->ops = &rtl8192u_ops;
12200 #endif
12202 dev->netdev_ops = &rtl8192_netdev_ops;
12204 //DMESG("Oops: i'm coming\n");
12205 #if WIRELESS_EXT >= 12
12206 #if WIRELESS_EXT < 17
12207 dev->get_wireless_stats = r8192_get_wireless_stats;
12208 #endif
12209 dev->wireless_handlers = (struct iw_handler_def *) &r8192_wx_handlers_def;
12210 #endif
12211 dev->type=ARPHRD_ETHER;
12213 dev->watchdog_timeo = HZ*3; //modified by john, 0805
12215 if (dev_alloc_name(dev, ifname) < 0){
12216 RT_TRACE(COMP_INIT, "Oops: devname already taken! Trying wlan%%d...\n");
12217 ifname = "wlan%d";
12218 dev_alloc_name(dev, ifname);
12221 RT_TRACE(COMP_INIT, "Driver probe completed1\n");
12222 #if 1
12223 if(rtl8192_init(dev)!=0){
12224 RT_TRACE(COMP_ERR, "Initialization failed");
12225 goto fail;
12227 #endif
12228 netif_carrier_off(dev);
12229 netif_stop_queue(dev);
12231 register_netdev(dev);
12232 RT_TRACE(COMP_INIT, "dev name=======> %s\n",dev->name);
12233 rtl8192_proc_init_one(dev);
12236 RT_TRACE(COMP_INIT, "Driver probe completed\n");
12237 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
12238 return dev;
12239 #else
12240 return 0;
12241 #endif
12244 fail:
12245 free_ieee80211(dev);
12247 RT_TRACE(COMP_ERR, "wlan driver load failed\n");
12248 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
12249 return NULL;
12250 #else
12251 return -ENODEV;
12252 #endif
12256 //detach all the work and timer structure declared or inititialize in r8192U_init function.
12257 void rtl8192_cancel_deferred_work(struct r8192_priv* priv)
12259 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
12260 cancel_work_sync(&priv->reset_wq);
12261 cancel_work_sync(&priv->qos_activate);
12262 cancel_delayed_work(&priv->watch_dog_wq);
12263 cancel_delayed_work(&priv->update_beacon_wq);
12264 cancel_delayed_work(&priv->ieee80211->hw_wakeup_wq);
12265 cancel_delayed_work(&priv->ieee80211->hw_sleep_wq);
12266 //cancel_work_sync(&priv->SetBWModeWorkItem);
12267 //cancel_work_sync(&priv->SwChnlWorkItem);
12268 #else
12269 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
12270 cancel_delayed_work(&priv->reset_wq);
12271 cancel_delayed_work(&priv->qos_activate);
12272 cancel_delayed_work(&priv->watch_dog_wq);
12273 cancel_delayed_work(&priv->update_beacon_wq);
12274 cancel_delayed_work(&priv->ieee80211->hw_wakeup_wq);
12275 cancel_delayed_work(&priv->ieee80211->hw_sleep_wq);
12277 //cancel_delayed_work(&priv->SetBWModeWorkItem);
12278 //cancel_delayed_work(&priv->SwChnlWorkItem);
12279 #endif
12280 #endif
12285 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
12286 static void __devexit rtl8192_usb_disconnect(struct usb_interface *intf)
12287 #else
12288 static void __devexit rtl8192_usb_disconnect(struct usb_device *udev, void *ptr)
12289 #endif
12291 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
12292 struct net_device *dev = usb_get_intfdata(intf);
12293 #else
12294 struct net_device *dev = (struct net_device *)ptr;
12295 #endif
12297 struct r8192_priv *priv = ieee80211_priv(dev);
12298 if(dev){
12300 unregister_netdev(dev);
12302 RT_TRACE(COMP_DOWN, "=============>wlan driver to be removed\n");
12303 rtl8192_proc_remove_one(dev);
12305 rtl8192_down(dev);
12306 if (priv->pFirmware)
12308 vfree(priv->pFirmware);
12309 priv->pFirmware = NULL;
12311 // priv->rf_close(dev);
12312 // rtl8192_SetRFPowerState(dev, eRfOff);
12313 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
12314 destroy_workqueue(priv->priv_wq);
12315 #endif
12316 //rtl8192_irq_disable(dev);
12317 //rtl8192_reset(dev);
12318 mdelay(10);
12321 free_ieee80211(dev);
12322 RT_TRACE(COMP_DOWN, "wlan driver removed\n");
12325 static int __init rtl8192_usb_module_init(void)
12327 printk(KERN_INFO "\nLinux kernel driver for RTL8192 based WLAN cards\n");
12328 printk(KERN_INFO "Copyright (c) 2007-2008, Realsil Wlan\n");
12329 RT_TRACE(COMP_INIT, "Initializing module");
12330 RT_TRACE(COMP_INIT, "Wireless extensions version %d", WIRELESS_EXT);
12331 rtl8192_proc_module_init();
12332 return usb_register(&rtl8192_usb_driver);
12336 static void __exit rtl8192_usb_module_exit(void)
12338 usb_deregister(&rtl8192_usb_driver);
12340 RT_TRACE(COMP_DOWN, "Exiting");
12341 rtl8192_proc_module_remove();
12345 void rtl8192_try_wake_queue(struct net_device *dev, int pri)
12347 unsigned long flags;
12348 short enough_desc;
12349 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
12351 spin_lock_irqsave(&priv->tx_lock,flags);
12352 enough_desc = check_nic_enough_desc(dev,pri);
12353 spin_unlock_irqrestore(&priv->tx_lock,flags);
12355 if(enough_desc)
12356 ieee80211_wake_queue(priv->ieee80211);
12359 #if 0
12360 void DisableHWSecurityConfig8192SUsb(struct net_device *dev)
12362 u8 SECR_value = 0x0;
12363 write_nic_byte(dev, SECR, SECR_value);//SECR_value | SCR_UseDK );
12365 #endif
12367 void EnableHWSecurityConfig8192(struct net_device *dev)
12369 u8 SECR_value = 0x0;
12370 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
12371 struct ieee80211_device* ieee = priv->ieee80211;
12373 SECR_value = SCR_TxEncEnable | SCR_RxDecEnable;
12374 #if 1
12375 if (((KEY_TYPE_WEP40 == ieee->pairwise_key_type) || (KEY_TYPE_WEP104 == ieee->pairwise_key_type)) && (priv->ieee80211->auth_mode != 2))
12377 SECR_value |= SCR_RxUseDK;
12378 SECR_value |= SCR_TxUseDK;
12380 else if ((ieee->iw_mode == IW_MODE_ADHOC) && (ieee->pairwise_key_type & (KEY_TYPE_CCMP | KEY_TYPE_TKIP)))
12382 SECR_value |= SCR_RxUseDK;
12383 SECR_value |= SCR_TxUseDK;
12385 #endif
12386 //add HWSec active enable here.
12387 //default using hwsec. when peer AP is in N mode only and pairwise_key_type is none_aes(which HT_IOT_ACT_PURE_N_MODE indicates it), use software security. when peer AP is in b,g,n mode mixed and pairwise_key_type is none_aes, use g mode hw security. WB on 2008.7.4
12389 ieee->hwsec_active = 1;
12391 if ((ieee->pHTInfo->IOTAction&HT_IOT_ACT_PURE_N_MODE) || !hwwep)//!ieee->hwsec_support) //add hwsec_support flag to totol control hw_sec on/off
12393 ieee->hwsec_active = 0;
12394 SECR_value &= ~SCR_RxDecEnable;
12397 RT_TRACE(COMP_SEC,"%s:, hwsec:%d, pairwise_key:%d, SECR_value:%x\n", __FUNCTION__, \
12398 ieee->hwsec_active, ieee->pairwise_key_type, SECR_value);
12400 write_nic_byte(dev, SECR, SECR_value);//SECR_value | SCR_UseDK );
12405 void setKey( struct net_device *dev,
12406 u8 EntryNo,
12407 u8 KeyIndex,
12408 u16 KeyType,
12409 u8 *MacAddr,
12410 u8 DefaultKey,
12411 u32 *KeyContent )
12413 u32 TargetCommand = 0;
12414 u32 TargetContent = 0;
12415 u16 usConfig = 0;
12416 u8 i;
12417 if (EntryNo >= TOTAL_CAM_ENTRY)
12418 RT_TRACE(COMP_ERR, "cam entry exceeds in setKey()\n");
12420 RT_TRACE(COMP_SEC, "====>to setKey(), dev:%p, EntryNo:%d, KeyIndex:%d, KeyType:%d, MacAddr"MAC_FMT"\n", dev,EntryNo, KeyIndex, KeyType, MAC_ARG(MacAddr));
12422 if (DefaultKey)
12423 usConfig |= BIT15 | (KeyType<<2);
12424 else
12425 usConfig |= BIT15 | (KeyType<<2) | KeyIndex;
12426 // usConfig |= BIT15 | (KeyType<<2) | (DefaultKey<<5) | KeyIndex;
12429 for(i=0 ; i<CAM_CONTENT_COUNT; i++){
12430 TargetCommand = i+CAM_CONTENT_COUNT*EntryNo;
12431 TargetCommand |= BIT31|BIT16;
12433 if(i==0){//MAC|Config
12434 TargetContent = (u32)(*(MacAddr+0)) << 16|
12435 (u32)(*(MacAddr+1)) << 24|
12436 (u32)usConfig;
12438 write_nic_dword(dev, WCAMI, TargetContent);
12439 write_nic_dword(dev, RWCAM, TargetCommand);
12440 // printk("setkey cam =%8x\n", read_cam(dev, i+6*EntryNo));
12442 else if(i==1){//MAC
12443 TargetContent = (u32)(*(MacAddr+2)) |
12444 (u32)(*(MacAddr+3)) << 8|
12445 (u32)(*(MacAddr+4)) << 16|
12446 (u32)(*(MacAddr+5)) << 24;
12447 write_nic_dword(dev, WCAMI, TargetContent);
12448 write_nic_dword(dev, RWCAM, TargetCommand);
12450 else {
12451 //Key Material
12452 if(KeyContent !=NULL){
12453 write_nic_dword(dev, WCAMI, (u32)(*(KeyContent+i-2)) );
12454 write_nic_dword(dev, RWCAM, TargetCommand);
12461 /***************************************************************************
12462 ------------------- module init / exit stubs ----------------
12463 ****************************************************************************/
12464 module_init(rtl8192_usb_module_init);
12465 module_exit(rtl8192_usb_module_exit);