blob: 504965a19b53f186b5a587677340b76be167afe2 [file] [log] [blame]
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001/******************************************************************************
2 * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
3 * Linux device driver for RTL8192U
4 *
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.
10 *
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.
15 *
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
19 *
20 * The full GNU General Public License is included in this distribution in the
21 * file called LICENSE.
22 *
23 * Contact Information:
24 * Jerry chuang <wlanfae@realtek.com>
25 */
26
27#ifndef CONFIG_FORCE_HARD_FLOAT
28double __floatsidf (int i) { return i; }
29unsigned int __fixunsdfsi (double d) { return d; }
30double __adddf3(double a, double b) { return a+b; }
31double __addsf3(float a, float b) { return a+b; }
32double __subdf3(double a, double b) { return a-b; }
33double __extendsfdf2(float a) {return a;}
34#endif
35
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
58
59#define CONFIG_RTL8192_IO_MAP
60
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"
67
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"
73
74#include "r819xU_cmdpkt.h"
75#include "r8192U_dm.h"
76//#include "r8192xU_phyreg.h"
77#include <linux/usb.h>
Jerry Chuang5f53d8c2009-05-21 22:16:02 -070078
79#ifdef CONFIG_RTL8192_PM
80#include "r8192U_pm.h"
81#endif
82
83#ifdef ENABLE_DOT11D
Bartlomiej Zolnierkiewicz2a7d71a2009-06-12 18:29:19 +020084#include "ieee80211/dot11d.h"
Jerry Chuang5f53d8c2009-05-21 22:16:02 -070085#endif
86
87#else
88
89#include <asm/uaccess.h>
90#include "r8192U_hw.h"
91#include "r8192U.h"
92#include "r8190_rtl8256.h" /* RTL8225 Radio frontend */
93#include "r8180_93cx6.h" /* Card EEPROM */
94#include "r8192U_wx.h"
95#include "r819xU_phy.h" //added by WB 4.30.2008
96#include "r819xU_phyreg.h"
97#include "r819xU_cmdpkt.h"
98#include "r8192U_dm.h"
99//#include "r8192xU_phyreg.h"
100#include <linux/usb.h>
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700101
102#ifdef CONFIG_RTL8192_PM
103#include "r8192U_pm.h"
104#endif
105
106#ifdef ENABLE_DOT11D
Bartlomiej Zolnierkiewicz2a7d71a2009-06-12 18:29:19 +0200107#include "ieee80211/dot11d.h"
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700108#endif
109
110#endif
111
112
113#ifdef RTL8192SU
114u32 rt_global_debug_component = \
115// COMP_TRACE |
116// COMP_DBG |
117// COMP_INIT |
118// COMP_RECV |
119// COMP_SEND |
120// COMP_IO |
121 COMP_POWER |
122// COMP_EPROM |
123 COMP_SWBW |
124 COMP_POWER_TRACKING |
125 COMP_TURBO |
126 COMP_QOS |
127// COMP_RATE |
128// COMP_RM |
129 COMP_DIG |
130// COMP_EFUSE |
131// COMP_CH |
132// COMP_TXAGC |
133 COMP_HIPWR |
134// COMP_HALDM |
135 COMP_SEC |
136 COMP_LED |
137// COMP_RF |
138// COMP_RXDESC |
139 COMP_FIRMWARE |
140 COMP_HT |
141 COMP_AMSDU |
142 COMP_SCAN |
143// COMP_CMD |
144 COMP_DOWN |
145 COMP_RESET |
146 COMP_ERR; //always open err flags on
147#else
148//set here to open your trace code. //WB
149u32 rt_global_debug_component = \
150 // COMP_INIT |
151// COMP_DBG |
152 // COMP_EPROM |
153// COMP_PHY |
154 // COMP_RF |
155// COMP_FIRMWARE |
156// COMP_CH |
157 // COMP_POWER_TRACKING |
158// COMP_RATE |
159 // COMP_TXAGC |
160 // COMP_TRACE |
161 COMP_DOWN |
162 // COMP_RECV |
163 // COMP_SWBW |
164 COMP_SEC |
165 // COMP_RESET |
166 // COMP_SEND |
167 // COMP_EVENTS |
168 COMP_ERR ; //always open err flags on
169#endif
170
171#define TOTAL_CAM_ENTRY 32
172#define CAM_CONTENT_COUNT 8
173
174static struct usb_device_id rtl8192_usb_id_tbl[] = {
175 /* Realtek */
176 {USB_DEVICE(0x0bda, 0x8192)},
177 {USB_DEVICE(0x0bda, 0x8709)},
178 /* Corega */
179 {USB_DEVICE(0x07aa, 0x0043)},
180 /* Belkin */
181 {USB_DEVICE(0x050d, 0x805E)},
182 /* Sitecom */
183 {USB_DEVICE(0x0df6, 0x0031)},
184 /* EnGenius */
185 {USB_DEVICE(0x1740, 0x9201)},
186 /* Dlink */
187 {USB_DEVICE(0x2001, 0x3301)},
188 /* Zinwell */
189 {USB_DEVICE(0x5a57, 0x0290)},
190 //92SU
191 {USB_DEVICE(0x0bda, 0x8172)},
192 {}
193};
194
195MODULE_LICENSE("GPL");
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700196MODULE_VERSION("V 1.1");
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700197MODULE_DEVICE_TABLE(usb, rtl8192_usb_id_tbl);
198MODULE_DESCRIPTION("Linux driver for Realtek RTL8192 USB WiFi cards");
199
200static char* ifname = "wlan%d";
201#if 0
202static int hwseqnum = 0;
203static int hwwep = 0;
204#endif
205static int hwwep = 1; //default use hw. set 0 to use software security
206static int channels = 0x3fff;
207
208
209
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700210module_param(ifname, charp, S_IRUGO|S_IWUSR );
211//module_param(hwseqnum,int, S_IRUGO|S_IWUSR);
212module_param(hwwep,int, S_IRUGO|S_IWUSR);
213module_param(channels,int, S_IRUGO|S_IWUSR);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700214
215MODULE_PARM_DESC(ifname," Net interface name, wlan%d=default");
216//MODULE_PARM_DESC(hwseqnum," Try to use hardware 802.11 header sequence numbers. Zero=default");
217MODULE_PARM_DESC(hwwep," Try to use hardware security support. ");
218MODULE_PARM_DESC(channels," Channel bitmask for specific locales. NYI");
219
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700220static int __devinit rtl8192_usb_probe(struct usb_interface *intf,
221 const struct usb_device_id *id);
222static void __devexit rtl8192_usb_disconnect(struct usb_interface *intf);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700223
224static struct usb_driver rtl8192_usb_driver = {
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700225 .name = RTL819xU_MODULE_NAME, /* Driver name */
226 .id_table = rtl8192_usb_id_tbl, /* PCI_ID table */
227 .probe = rtl8192_usb_probe, /* probe fn */
228 .disconnect = rtl8192_usb_disconnect, /* remove fn */
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700229#ifdef CONFIG_RTL8192_PM
230 .suspend = rtl8192U_suspend, /* PM suspend fn */
231 .resume = rtl8192U_resume, /* PM resume fn */
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700232 .reset_resume = rtl8192U_resume, /* PM reset resume fn */
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700233#else
234 .suspend = NULL, /* PM suspend fn */
235 .resume = NULL, /* PM resume fn */
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700236 .reset_resume = NULL, /* PM reset resume fn */
237#endif
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700238};
239
240
241#ifdef RTL8192SU
242static void rtl8192SU_read_eeprom_info(struct net_device *dev);
243short rtl8192SU_tx(struct net_device *dev, struct sk_buff* skb);
244void rtl8192SU_rx_nomal(struct sk_buff* skb);
245void rtl8192SU_rx_cmd(struct sk_buff *skb);
246bool rtl8192SU_adapter_start(struct net_device *dev);
247short rtl8192SU_tx_cmd(struct net_device *dev, struct sk_buff *skb);
248void rtl8192SU_link_change(struct net_device *dev);
249void InitialGain8192S(struct net_device *dev,u8 Operation);
250void rtl8192SU_query_rxdesc_status(struct sk_buff *skb, struct ieee80211_rx_stats *stats, bool bIsRxAggrSubframe);
251
252struct rtl819x_ops rtl8192su_ops = {
253 .nic_type = NIC_8192SU,
254 .rtl819x_read_eeprom_info = rtl8192SU_read_eeprom_info,
255 .rtl819x_tx = rtl8192SU_tx,
256 .rtl819x_tx_cmd = rtl8192SU_tx_cmd,
257 .rtl819x_rx_nomal = rtl8192SU_rx_nomal,
258 .rtl819x_rx_cmd = rtl8192SU_rx_cmd,
259 .rtl819x_adapter_start = rtl8192SU_adapter_start,
260 .rtl819x_link_change = rtl8192SU_link_change,
261 .rtl819x_initial_gain = InitialGain8192S,
262 .rtl819x_query_rxdesc_status = rtl8192SU_query_rxdesc_status,
263};
264#else
265static void rtl8192_read_eeprom_info(struct net_device *dev);
266short rtl8192_tx(struct net_device *dev, struct sk_buff* skb);
267void rtl8192_rx_nomal(struct sk_buff* skb);
268void rtl8192_rx_cmd(struct sk_buff *skb);
269bool rtl8192_adapter_start(struct net_device *dev);
270short rtl819xU_tx_cmd(struct net_device *dev, struct sk_buff *skb);
271void rtl8192_link_change(struct net_device *dev);
272void InitialGain819xUsb(struct net_device *dev,u8 Operation);
273void query_rxdesc_status(struct sk_buff *skb, struct ieee80211_rx_stats *stats, bool bIsRxAggrSubframe);
274
275struct rtl819x_ops rtl8192u_ops = {
276 .nic_type = NIC_8192U,
277 .rtl819x_read_eeprom_info = rtl8192_read_eeprom_info,
278 .rtl819x_tx = rtl8192_tx,
279 .rtl819x_tx_cmd = rtl819xU_tx_cmd,
280 .rtl819x_rx_nomal = rtl8192_rx_nomal,
281 .rtl819x_rx_cmd = rtl8192_rx_cmd,
282 .rtl819x_adapter_start = rtl8192_adapter_start,
283 .rtl819x_link_change = rtl8192_link_change,
284 .rtl819x_initial_gain = InitialGain819xUsb,
285 .rtl819x_query_rxdesc_status = query_rxdesc_status,
286};
287#endif
288
289#ifdef ENABLE_DOT11D
290
291typedef struct _CHANNEL_LIST
292{
293 u8 Channel[32];
294 u8 Len;
295}CHANNEL_LIST, *PCHANNEL_LIST;
296
297static CHANNEL_LIST ChannelPlan[] = {
298 {{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
299 {{1,2,3,4,5,6,7,8,9,10,11},11}, //IC
300 {{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48,52,56,60,64},21}, //ETSI
301 {{1,2,3,4,5,6,7,8,9,10,11,12,13},13}, //Spain. Change to ETSI.
302 {{1,2,3,4,5,6,7,8,9,10,11,12,13},13}, //France. Change to ETSI.
303 {{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
304 {{1,2,3,4,5,6,7,8,9,10,11,12,13,14,36,40,44,48,52,56,60,64},22},//MKK1
305 {{1,2,3,4,5,6,7,8,9,10,11,12,13},13}, //Israel.
306 {{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
307 {{1,2,3,4,5,6,7,8,9,10,11,12,13,14,36,40,44,48,52,56,60,64}, 22}, //MIC
308 {{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
309};
310
311static void rtl819x_set_channel_map(u8 channel_plan, struct r8192_priv* priv)
312{
313 int i, max_chan=-1, min_chan=-1;
314 struct ieee80211_device* ieee = priv->ieee80211;
315 switch (channel_plan)
316 {
317 case COUNTRY_CODE_FCC:
318 case COUNTRY_CODE_IC:
319 case COUNTRY_CODE_ETSI:
320 case COUNTRY_CODE_SPAIN:
321 case COUNTRY_CODE_FRANCE:
322 case COUNTRY_CODE_MKK:
323 case COUNTRY_CODE_MKK1:
324 case COUNTRY_CODE_ISRAEL:
325 case COUNTRY_CODE_TELEC:
326 case COUNTRY_CODE_MIC:
327 {
328 Dot11d_Init(ieee);
329 ieee->bGlobalDomain = false;
330 //acturally 8225 & 8256 rf chip only support B,G,24N mode
331 if ((priv->rf_chip == RF_8225) || (priv->rf_chip == RF_8256) || (priv->rf_chip == RF_6052))
332 {
333 min_chan = 1;
334 max_chan = 14;
335 }
336 else
337 {
338 RT_TRACE(COMP_ERR, "unknown rf chip, can't set channel map in function:%s()\n", __FUNCTION__);
339 }
340 if (ChannelPlan[channel_plan].Len != 0){
341 // Clear old channel map
342 memset(GET_DOT11D_INFO(ieee)->channel_map, 0, sizeof(GET_DOT11D_INFO(ieee)->channel_map));
343 // Set new channel map
344 for (i=0;i<ChannelPlan[channel_plan].Len;i++)
345 {
346 if (ChannelPlan[channel_plan].Channel[i] < min_chan || ChannelPlan[channel_plan].Channel[i] > max_chan)
347 break;
348 GET_DOT11D_INFO(ieee)->channel_map[ChannelPlan[channel_plan].Channel[i]] = 1;
349 }
350 }
351 break;
352 }
353 case COUNTRY_CODE_GLOBAL_DOMAIN:
354 {
355 GET_DOT11D_INFO(ieee)->bEnabled = 0;//this flag enabled to follow 11d country IE setting, otherwise, it shall follow global domain settings.
356 Dot11d_Reset(ieee);
357 ieee->bGlobalDomain = true;
358 break;
359 }
360 default:
361 break;
362 }
363 return;
364}
365#endif
366
367#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 )
368
369#ifdef RTL8192SU
370#define rx_hal_is_cck_rate(_pDesc)\
371 ((_pDesc->RxMCS == DESC92S_RATE1M ||\
372 _pDesc->RxMCS == DESC92S_RATE2M ||\
373 _pDesc->RxMCS == DESC92S_RATE5_5M ||\
374 _pDesc->RxMCS == DESC92S_RATE11M) &&\
375 !_pDesc->RxHT)
376
377#define tx_hal_is_cck_rate(_DataRate)\
378 ( _DataRate == MGN_1M ||\
379 _DataRate == MGN_2M ||\
380 _DataRate == MGN_5_5M ||\
381 _DataRate == MGN_11M )
382
383#else
384#define rx_hal_is_cck_rate(_pdrvinfo)\
385 ((_pdrvinfo->RxRate == DESC90_RATE1M ||\
386 _pdrvinfo->RxRate == DESC90_RATE2M ||\
387 _pdrvinfo->RxRate == DESC90_RATE5_5M ||\
388 _pdrvinfo->RxRate == DESC90_RATE11M) &&\
389 !_pdrvinfo->RxHT)
390#endif
391
392
393
394void CamResetAllEntry(struct net_device *dev)
395{
396#if 1
397 u32 ulcommand = 0;
398 //2004/02/11 In static WEP, OID_ADD_KEY or OID_ADD_WEP are set before STA associate to AP.
399 // However, ResetKey is called on OID_802_11_INFRASTRUCTURE_MODE and MlmeAssociateRequest
400 // In this condition, Cam can not be reset because upper layer will not set this static key again.
401 //if(Adapter->EncAlgorithm == WEP_Encryption)
402 // return;
403//debug
404 //DbgPrint("========================================\n");
405 //DbgPrint(" Call ResetAllEntry \n");
406 //DbgPrint("========================================\n\n");
407 ulcommand |= BIT31|BIT30;
408 write_nic_dword(dev, RWCAM, ulcommand);
409#else
410 for(ucIndex=0;ucIndex<TOTAL_CAM_ENTRY;ucIndex++)
411 CAM_mark_invalid(dev, ucIndex);
412 for(ucIndex=0;ucIndex<TOTAL_CAM_ENTRY;ucIndex++)
413 CAM_empty_entry(dev, ucIndex);
414#endif
415
416}
417
418
419void write_cam(struct net_device *dev, u8 addr, u32 data)
420{
421 write_nic_dword(dev, WCAMI, data);
422 write_nic_dword(dev, RWCAM, BIT31|BIT16|(addr&0xff) );
423}
424
425u32 read_cam(struct net_device *dev, u8 addr)
426{
427 write_nic_dword(dev, RWCAM, 0x80000000|(addr&0xff) );
428 return read_nic_dword(dev, 0xa8);
429}
430
431void write_nic_byte_E(struct net_device *dev, int indx, u8 data)
432{
433 int status;
434 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
435 struct usb_device *udev = priv->udev;
436
437 status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
438 RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
439 indx|0xfe00, 0, &data, 1, HZ / 2);
440
441 if (status < 0)
442 {
443 printk("write_nic_byte_E TimeOut! status:%d\n", status);
444 }
445}
446
447u8 read_nic_byte_E(struct net_device *dev, int indx)
448{
449 int status;
450 u8 data;
451 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
452 struct usb_device *udev = priv->udev;
453
454 status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
455 RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
456 indx|0xfe00, 0, &data, 1, HZ / 2);
457
458 if (status < 0)
459 {
460 printk("read_nic_byte_E TimeOut! status:%d\n", status);
461 }
462
463 return data;
464}
465//as 92U has extend page from 4 to 16, so modify functions below.
466void write_nic_byte(struct net_device *dev, int indx, u8 data)
467{
468 int status;
469
470 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
471 struct usb_device *udev = priv->udev;
472
473 status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
474 RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
475#ifdef RTL8192SU
476 indx, 0, &data, 1, HZ / 2);
477#else
478 (indx&0xff)|0xff00, (indx>>8)&0x0f, &data, 1, HZ / 2);
479#endif
480
481 if (status < 0)
482 {
483 printk("write_nic_byte TimeOut! status:%d\n", status);
484 }
485
486
487}
488
489
490void write_nic_word(struct net_device *dev, int indx, u16 data)
491{
492
493 int status;
494
495 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
496 struct usb_device *udev = priv->udev;
497
498 status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
499 RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
500#ifdef RTL8192SU
501 indx, 0, &data, 2, HZ / 2);
502#else
503 (indx&0xff)|0xff00, (indx>>8)&0x0f, &data, 2, HZ / 2);
504#endif
505
506 if (status < 0)
507 {
508 printk("write_nic_word TimeOut! status:%d\n", status);
509 }
510
511}
512
513
514void write_nic_dword(struct net_device *dev, int indx, u32 data)
515{
516
517 int status;
518
519 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
520 struct usb_device *udev = priv->udev;
521
522 status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
523 RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
524#ifdef RTL8192SU
525 indx, 0, &data, 4, HZ / 2);
526#else
527 (indx&0xff)|0xff00, (indx>>8)&0x0f, &data, 4, HZ / 2);
528#endif
529
530
531 if (status < 0)
532 {
533 printk("write_nic_dword TimeOut! status:%d\n", status);
534 }
535
536}
537
538
539
540u8 read_nic_byte(struct net_device *dev, int indx)
541{
542 u8 data;
543 int status;
544 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
545 struct usb_device *udev = priv->udev;
546
547 status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
548 RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
549#ifdef RTL8192SU
550 indx, 0, &data, 1, HZ / 2);
551#else
552 (indx&0xff)|0xff00, (indx>>8)&0x0f, &data, 1, HZ / 2);
553#endif
554
555 if (status < 0)
556 {
557 printk("read_nic_byte TimeOut! status:%d\n", status);
558 }
559
560 return data;
561}
562
563
564
565u16 read_nic_word(struct net_device *dev, int indx)
566{
567 u16 data;
568 int status;
569 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
570 struct usb_device *udev = priv->udev;
571
572 status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
573 RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
574#ifdef RTL8192SU
575 indx, 0, &data, 2, HZ / 2);
576#else
577 (indx&0xff)|0xff00, (indx>>8)&0x0f, &data, 2, HZ / 2);
578#endif
579
580 if (status < 0)
581 {
582 printk("read_nic_word TimeOut! status:%d\n", status);
583 }
584
585
586 return data;
587}
588
589u16 read_nic_word_E(struct net_device *dev, int indx)
590{
591 u16 data;
592 int status;
593 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
594 struct usb_device *udev = priv->udev;
595
596 status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
597 RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
598 indx|0xfe00, 0, &data, 2, HZ / 2);
599
600 if (status < 0)
601 {
602 printk("read_nic_word TimeOut! status:%d\n", status);
603 }
604
605
606 return data;
607}
608
609u32 read_nic_dword(struct net_device *dev, int indx)
610{
611 u32 data;
612 int status;
613// int result;
614
615 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
616 struct usb_device *udev = priv->udev;
617
618 status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
619 RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
620#ifdef RTL8192SU
621 indx, 0, &data, 4, HZ / 2);
622#else
623 (indx&0xff)|0xff00, (indx>>8)&0x0f, &data, 4, HZ / 2);
624#endif
625// if(0 != result) {
626// printk(KERN_WARNING "read size of data = %d\, date = %d\n", result, data);
627// }
628
629 if (status < 0)
630 {
631 printk("read_nic_dword TimeOut! status:%d\n", status);
632 if(status == -ENODEV) {
633 priv->usb_error = true;
634 }
635 }
636
637
638
639 return data;
640}
641
642
643//u8 read_phy_cck(struct net_device *dev, u8 adr);
644//u8 read_phy_ofdm(struct net_device *dev, u8 adr);
645/* this might still called in what was the PHY rtl8185/rtl8192 common code
646 * plans are to possibilty turn it again in one common code...
647 */
648inline void force_pci_posting(struct net_device *dev)
649{
650}
651
652
653static struct net_device_stats *rtl8192_stats(struct net_device *dev);
654void rtl8192_commit(struct net_device *dev);
655//void rtl8192_restart(struct net_device *dev);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700656void rtl8192_restart(struct work_struct *work);
657//void rtl8192_rq_tx_ack(struct work_struct *work);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700658
659void watch_dog_timer_callback(unsigned long data);
660
661/****************************************************************************
662 -----------------------------PROCFS STUFF-------------------------
663*****************************************************************************/
664
665static struct proc_dir_entry *rtl8192_proc = NULL;
666
667
668
669static int proc_get_stats_ap(char *page, char **start,
670 off_t offset, int count,
671 int *eof, void *data)
672{
673 struct net_device *dev = data;
674 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
675 struct ieee80211_device *ieee = priv->ieee80211;
676 struct ieee80211_network *target;
677
678 int len = 0;
679
680 list_for_each_entry(target, &ieee->network_list, list) {
681
682 len += snprintf(page + len, count - len,
683 "%s ", target->ssid);
684
685 if(target->wpa_ie_len>0 || target->rsn_ie_len>0){
686 len += snprintf(page + len, count - len,
687 "WPA\n");
688 }
689 else{
690 len += snprintf(page + len, count - len,
691 "non_WPA\n");
692 }
693
694 }
695
696 *eof = 1;
697 return len;
698}
699
700#ifdef RTL8192SU
701static int proc_get_registers(char *page, char **start,
702 off_t offset, int count,
703 int *eof, void *data)
704{
705 struct net_device *dev = data;
706// struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
707
708 int len = 0;
709 int i,n,page0,page1,page2;
710
711 int max=0xff;
712 page0 = 0x000;
713 page1 = 0x100;
714 page2 = 0x800;
715
716 /* This dump the current register page */
717 if(!IS_BB_REG_OFFSET_92S(page0)){
718 len += snprintf(page + len, count - len,
719 "\n####################page %x##################\n ", (page0>>8));
720 for(n=0;n<=max;)
721 {
722 len += snprintf(page + len, count - len,
723 "\nD: %2x > ",n);
724 for(i=0;i<16 && n<=max;i++,n++)
725 len += snprintf(page + len, count - len,
726 "%2.2x ",read_nic_byte(dev,(page0|n)));
727 }
728 }else{
729 len += snprintf(page + len, count - len,
730 "\n####################page %x##################\n ", (page0>>8));
731 for(n=0;n<=max;)
732 {
733 len += snprintf(page + len, count - len, "\nD: %2x > ",n);
734 for(i=0;i<4 && n<=max;n+=4,i++)
735 len += snprintf(page + len, count - len,
736 "%8.8x ",rtl8192_QueryBBReg(dev,(page0|n), bMaskDWord));
737 }
738 }
739 len += snprintf(page + len, count - len,"\n");
740 *eof = 1;
741 return len;
742
743}
744static int proc_get_registers_1(char *page, char **start,
745 off_t offset, int count,
746 int *eof, void *data)
747{
748 struct net_device *dev = data;
749// struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
750
751 int len = 0;
752 int i,n,page0;
753
754 int max=0xff;
755 page0 = 0x100;
756
757 /* This dump the current register page */
758 len += snprintf(page + len, count - len,
759 "\n####################page %x##################\n ", (page0>>8));
760 for(n=0;n<=max;)
761 {
762 len += snprintf(page + len, count - len,
763 "\nD: %2x > ",n);
764 for(i=0;i<16 && n<=max;i++,n++)
765 len += snprintf(page + len, count - len,
766 "%2.2x ",read_nic_byte(dev,(page0|n)));
767 }
768 len += snprintf(page + len, count - len,"\n");
769 *eof = 1;
770 return len;
771
772}
773static int proc_get_registers_2(char *page, char **start,
774 off_t offset, int count,
775 int *eof, void *data)
776{
777 struct net_device *dev = data;
778// struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
779
780 int len = 0;
781 int i,n,page0;
782
783 int max=0xff;
784 page0 = 0x200;
785
786 /* This dump the current register page */
787 len += snprintf(page + len, count - len,
788 "\n####################page %x##################\n ", (page0>>8));
789 for(n=0;n<=max;)
790 {
791 len += snprintf(page + len, count - len,
792 "\nD: %2x > ",n);
793 for(i=0;i<16 && n<=max;i++,n++)
794 len += snprintf(page + len, count - len,
795 "%2.2x ",read_nic_byte(dev,(page0|n)));
796 }
797 len += snprintf(page + len, count - len,"\n");
798 *eof = 1;
799 return len;
800
801}
802static int proc_get_registers_8(char *page, char **start,
803 off_t offset, int count,
804 int *eof, void *data)
805{
806 struct net_device *dev = data;
807
808 int len = 0;
809 int i,n,page0;
810
811 int max=0xff;
812 page0 = 0x800;
813
814 /* This dump the current register page */
815 len += snprintf(page + len, count - len,
816 "\n####################page %x##################\n ", (page0>>8));
817 for(n=0;n<=max;)
818 {
819 len += snprintf(page + len, count - len, "\nD: %2x > ",n);
820 for(i=0;i<4 && n<=max;n+=4,i++)
821 len += snprintf(page + len, count - len,
822 "%8.8x ",rtl8192_QueryBBReg(dev,(page0|n), bMaskDWord));
823 }
824 len += snprintf(page + len, count - len,"\n");
825 *eof = 1;
826 return len;
827
828 }
829static int proc_get_registers_9(char *page, char **start,
830 off_t offset, int count,
831 int *eof, void *data)
832{
833 struct net_device *dev = data;
834// struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
835
836 int len = 0;
837 int i,n,page0;
838
839 int max=0xff;
840 page0 = 0x900;
841
842 /* This dump the current register page */
843 len += snprintf(page + len, count - len,
844 "\n####################page %x##################\n ", (page0>>8));
845 for(n=0;n<=max;)
846 {
847 len += snprintf(page + len, count - len, "\nD: %2x > ",n);
848 for(i=0;i<4 && n<=max;n+=4,i++)
849 len += snprintf(page + len, count - len,
850 "%8.8x ",rtl8192_QueryBBReg(dev,(page0|n), bMaskDWord));
851 }
852 len += snprintf(page + len, count - len,"\n");
853 *eof = 1;
854 return len;
855}
856static int proc_get_registers_a(char *page, char **start,
857 off_t offset, int count,
858 int *eof, void *data)
859{
860 struct net_device *dev = data;
861// struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
862
863 int len = 0;
864 int i,n,page0;
865
866 int max=0xff;
867 page0 = 0xa00;
868
869 /* This dump the current register page */
870 len += snprintf(page + len, count - len,
871 "\n####################page %x##################\n ", (page0>>8));
872 for(n=0;n<=max;)
873 {
874 len += snprintf(page + len, count - len, "\nD: %2x > ",n);
875 for(i=0;i<4 && n<=max;n+=4,i++)
876 len += snprintf(page + len, count - len,
877 "%8.8x ",rtl8192_QueryBBReg(dev,(page0|n), bMaskDWord));
878 }
879 len += snprintf(page + len, count - len,"\n");
880 *eof = 1;
881 return len;
882}
883static int proc_get_registers_b(char *page, char **start,
884 off_t offset, int count,
885 int *eof, void *data)
886{
887 struct net_device *dev = data;
888// struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
889
890 int len = 0;
891 int i,n,page0;
892
893 int max=0xff;
894 page0 = 0xb00;
895
896 /* This dump the current register page */
897 len += snprintf(page + len, count - len,
898 "\n####################page %x##################\n ", (page0>>8));
899 for(n=0;n<=max;)
900 {
901 len += snprintf(page + len, count - len, "\nD: %2x > ",n);
902 for(i=0;i<4 && n<=max;n+=4,i++)
903 len += snprintf(page + len, count - len,
904 "%8.8x ",rtl8192_QueryBBReg(dev,(page0|n), bMaskDWord));
905 }
906 len += snprintf(page + len, count - len,"\n");
907 *eof = 1;
908 return len;
909 }
910static int proc_get_registers_c(char *page, char **start,
911 off_t offset, int count,
912 int *eof, void *data)
913{
914 struct net_device *dev = data;
915// struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
916
917 int len = 0;
918 int i,n,page0;
919
920 int max=0xff;
921 page0 = 0xc00;
922
923 /* This dump the current register page */
924 len += snprintf(page + len, count - len,
925 "\n####################page %x##################\n ", (page0>>8));
926 for(n=0;n<=max;)
927 {
928 len += snprintf(page + len, count - len, "\nD: %2x > ",n);
929 for(i=0;i<4 && n<=max;n+=4,i++)
930 len += snprintf(page + len, count - len,
931 "%8.8x ",rtl8192_QueryBBReg(dev,(page0|n), bMaskDWord));
932 }
933 len += snprintf(page + len, count - len,"\n");
934 *eof = 1;
935 return len;
936}
937static int proc_get_registers_d(char *page, char **start,
938 off_t offset, int count,
939 int *eof, void *data)
940{
941 struct net_device *dev = data;
942// struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
943
944 int len = 0;
945 int i,n,page0;
946
947 int max=0xff;
948 page0 = 0xd00;
949
950 /* This dump the current register page */
951 len += snprintf(page + len, count - len,
952 "\n####################page %x##################\n ", (page0>>8));
953 for(n=0;n<=max;)
954 {
955 len += snprintf(page + len, count - len, "\nD: %2x > ",n);
956 for(i=0;i<4 && n<=max;n+=4,i++)
957 len += snprintf(page + len, count - len,
958 "%8.8x ",rtl8192_QueryBBReg(dev,(page0|n), bMaskDWord));
959 }
960 len += snprintf(page + len, count - len,"\n");
961 *eof = 1;
962 return len;
963}
964static int proc_get_registers_e(char *page, char **start,
965 off_t offset, int count,
966 int *eof, void *data)
967{
968 struct net_device *dev = data;
969// struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
970
971 int len = 0;
972 int i,n,page0;
973
974 int max=0xff;
975 page0 = 0xe00;
976
977 /* This dump the current register page */
978 len += snprintf(page + len, count - len,
979 "\n####################page %x##################\n ", (page0>>8));
980 for(n=0;n<=max;)
981 {
982 len += snprintf(page + len, count - len, "\nD: %2x > ",n);
983 for(i=0;i<4 && n<=max;n+=4,i++)
984 len += snprintf(page + len, count - len,
985 "%8.8x ",rtl8192_QueryBBReg(dev,(page0|n), bMaskDWord));
986 }
987 len += snprintf(page + len, count - len,"\n");
988 *eof = 1;
989 return len;
990}
991#else
992static int proc_get_registers(char *page, char **start,
993 off_t offset, int count,
994 int *eof, void *data)
995{
996 struct net_device *dev = data;
997// struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
998
999 int len = 0;
1000 int i,n;
1001
1002 int max=0xff;
1003
1004 /* This dump the current register page */
1005len += snprintf(page + len, count - len,
1006 "\n####################page 0##################\n ");
1007
1008 for(n=0;n<=max;)
1009 {
1010 //printk( "\nD: %2x> ", n);
1011 len += snprintf(page + len, count - len,
1012 "\nD: %2x > ",n);
1013
1014 for(i=0;i<16 && n<=max;i++,n++)
1015 len += snprintf(page + len, count - len,
1016 "%2x ",read_nic_byte(dev,0x000|n));
1017
1018 // printk("%2x ",read_nic_byte(dev,n));
1019 }
1020#if 1
1021len += snprintf(page + len, count - len,
1022 "\n####################page 1##################\n ");
1023 for(n=0;n<=max;)
1024 {
1025 //printk( "\nD: %2x> ", n);
1026 len += snprintf(page + len, count - len,
1027 "\nD: %2x > ",n);
1028
1029 for(i=0;i<16 && n<=max;i++,n++)
1030 len += snprintf(page + len, count - len,
1031 "%2x ",read_nic_byte(dev,0x100|n));
1032
1033 // printk("%2x ",read_nic_byte(dev,n));
1034 }
1035len += snprintf(page + len, count - len,
1036 "\n####################page 3##################\n ");
1037 for(n=0;n<=max;)
1038 {
1039 //printk( "\nD: %2x> ", n);
1040 len += snprintf(page + len, count - len,
1041 "\nD: %2x > ",n);
1042
1043 for(i=0;i<16 && n<=max;i++,n++)
1044 len += snprintf(page + len, count - len,
1045 "%2x ",read_nic_byte(dev,0x300|n));
1046
1047 // printk("%2x ",read_nic_byte(dev,n));
1048 }
1049
1050#endif
1051
1052 len += snprintf(page + len, count - len,"\n");
1053 *eof = 1;
1054 return len;
1055
1056}
1057#endif
1058
1059#if 0
1060static int proc_get_cck_reg(char *page, char **start,
1061 off_t offset, int count,
1062 int *eof, void *data)
1063{
1064 struct net_device *dev = data;
1065// struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1066
1067 int len = 0;
1068 int i,n;
1069
1070 int max = 0x5F;
1071
1072 /* This dump the current register page */
1073 for(n=0;n<=max;)
1074 {
1075 //printk( "\nD: %2x> ", n);
1076 len += snprintf(page + len, count - len,
1077 "\nD: %2x > ",n);
1078
1079 for(i=0;i<16 && n<=max;i++,n++)
1080 len += snprintf(page + len, count - len,
1081 "%2x ",read_phy_cck(dev,n));
1082
1083 // printk("%2x ",read_nic_byte(dev,n));
1084 }
1085 len += snprintf(page + len, count - len,"\n");
1086
1087
1088 *eof = 1;
1089 return len;
1090}
1091
1092#endif
1093
1094#if 0
1095static int proc_get_ofdm_reg(char *page, char **start,
1096 off_t offset, int count,
1097 int *eof, void *data)
1098{
1099 struct net_device *dev = data;
1100// struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1101
1102 int len = 0;
1103 int i,n;
1104
1105 //int max=0xff;
1106 int max = 0x40;
1107
1108 /* This dump the current register page */
1109 for(n=0;n<=max;)
1110 {
1111 //printk( "\nD: %2x> ", n);
1112 len += snprintf(page + len, count - len,
1113 "\nD: %2x > ",n);
1114
1115 for(i=0;i<16 && n<=max;i++,n++)
1116 len += snprintf(page + len, count - len,
1117 "%2x ",read_phy_ofdm(dev,n));
1118
1119 // printk("%2x ",read_nic_byte(dev,n));
1120 }
1121 len += snprintf(page + len, count - len,"\n");
1122
1123
1124
1125 *eof = 1;
1126 return len;
1127}
1128
1129#endif
1130
1131#if 0
1132static int proc_get_stats_hw(char *page, char **start,
1133 off_t offset, int count,
1134 int *eof, void *data)
1135{
1136 struct net_device *dev = data;
1137 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1138
1139 int len = 0;
1140
1141 len += snprintf(page + len, count - len,
1142 "NIC int: %lu\n"
1143 "Total int: %lu\n",
1144 priv->stats.ints,
1145 priv->stats.shints);
1146
1147 *eof = 1;
1148 return len;
1149}
1150#endif
1151
1152static int proc_get_stats_tx(char *page, char **start,
1153 off_t offset, int count,
1154 int *eof, void *data)
1155{
1156 struct net_device *dev = data;
1157 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1158
1159 int len = 0;
1160
1161 len += snprintf(page + len, count - len,
1162 "TX VI priority ok int: %lu\n"
1163 "TX VI priority error int: %lu\n"
1164 "TX VO priority ok int: %lu\n"
1165 "TX VO priority error int: %lu\n"
1166 "TX BE priority ok int: %lu\n"
1167 "TX BE priority error int: %lu\n"
1168 "TX BK priority ok int: %lu\n"
1169 "TX BK priority error int: %lu\n"
1170 "TX MANAGE priority ok int: %lu\n"
1171 "TX MANAGE priority error int: %lu\n"
1172 "TX BEACON priority ok int: %lu\n"
1173 "TX BEACON priority error int: %lu\n"
1174// "TX high priority ok int: %lu\n"
1175// "TX high priority failed error int: %lu\n"
1176 "TX queue resume: %lu\n"
1177 "TX queue stopped?: %d\n"
1178 "TX fifo overflow: %lu\n"
1179// "TX beacon: %lu\n"
1180 "TX VI queue: %d\n"
1181 "TX VO queue: %d\n"
1182 "TX BE queue: %d\n"
1183 "TX BK queue: %d\n"
1184// "TX HW queue: %d\n"
1185 "TX VI dropped: %lu\n"
1186 "TX VO dropped: %lu\n"
1187 "TX BE dropped: %lu\n"
1188 "TX BK dropped: %lu\n"
1189 "TX total data packets %lu\n",
1190// "TX beacon aborted: %lu\n",
1191 priv->stats.txviokint,
1192 priv->stats.txvierr,
1193 priv->stats.txvookint,
1194 priv->stats.txvoerr,
1195 priv->stats.txbeokint,
1196 priv->stats.txbeerr,
1197 priv->stats.txbkokint,
1198 priv->stats.txbkerr,
1199 priv->stats.txmanageokint,
1200 priv->stats.txmanageerr,
1201 priv->stats.txbeaconokint,
1202 priv->stats.txbeaconerr,
1203// priv->stats.txhpokint,
1204// priv->stats.txhperr,
1205 priv->stats.txresumed,
1206 netif_queue_stopped(dev),
1207 priv->stats.txoverflow,
1208// priv->stats.txbeacon,
1209 atomic_read(&(priv->tx_pending[VI_PRIORITY])),
1210 atomic_read(&(priv->tx_pending[VO_PRIORITY])),
1211 atomic_read(&(priv->tx_pending[BE_PRIORITY])),
1212 atomic_read(&(priv->tx_pending[BK_PRIORITY])),
1213// read_nic_byte(dev, TXFIFOCOUNT),
1214 priv->stats.txvidrop,
1215 priv->stats.txvodrop,
1216 priv->stats.txbedrop,
1217 priv->stats.txbkdrop,
1218 priv->stats.txdatapkt
1219// priv->stats.txbeaconerr
1220 );
1221
1222 *eof = 1;
1223 return len;
1224}
1225
1226
1227
1228static int proc_get_stats_rx(char *page, char **start,
1229 off_t offset, int count,
1230 int *eof, void *data)
1231{
1232 struct net_device *dev = data;
1233 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1234
1235 int len = 0;
1236
1237 len += snprintf(page + len, count - len,
1238 "RX packets: %lu\n"
1239 "RX urb status error: %lu\n"
1240 "RX invalid urb error: %lu\n",
1241 priv->stats.rxoktotal,
1242 priv->stats.rxstaterr,
1243 priv->stats.rxurberr);
1244
1245 *eof = 1;
1246 return len;
1247}
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001248
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001249void rtl8192_proc_module_init(void)
1250{
1251 RT_TRACE(COMP_INIT, "Initializing proc filesystem");
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001252 rtl8192_proc=create_proc_entry(RTL819xU_MODULE_NAME, S_IFDIR, init_net.proc_net);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001253}
1254
1255
1256void rtl8192_proc_module_remove(void)
1257{
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001258 remove_proc_entry(RTL819xU_MODULE_NAME, init_net.proc_net);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001259}
1260
1261
1262void rtl8192_proc_remove_one(struct net_device *dev)
1263{
1264 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1265
1266
1267 if (priv->dir_dev) {
1268 // remove_proc_entry("stats-hw", priv->dir_dev);
1269 remove_proc_entry("stats-tx", priv->dir_dev);
1270 remove_proc_entry("stats-rx", priv->dir_dev);
1271 // remove_proc_entry("stats-ieee", priv->dir_dev);
1272 remove_proc_entry("stats-ap", priv->dir_dev);
1273 remove_proc_entry("registers", priv->dir_dev);
1274 remove_proc_entry("registers-1", priv->dir_dev);
1275 remove_proc_entry("registers-2", priv->dir_dev);
1276 remove_proc_entry("registers-8", priv->dir_dev);
1277 remove_proc_entry("registers-9", priv->dir_dev);
1278 remove_proc_entry("registers-a", priv->dir_dev);
1279 remove_proc_entry("registers-b", priv->dir_dev);
1280 remove_proc_entry("registers-c", priv->dir_dev);
1281 remove_proc_entry("registers-d", priv->dir_dev);
1282 remove_proc_entry("registers-e", priv->dir_dev);
1283 // remove_proc_entry("cck-registers",priv->dir_dev);
1284 // remove_proc_entry("ofdm-registers",priv->dir_dev);
1285 //remove_proc_entry(dev->name, rtl8192_proc);
1286 remove_proc_entry("wlan0", rtl8192_proc);
1287 priv->dir_dev = NULL;
1288 }
1289}
1290
1291
1292void rtl8192_proc_init_one(struct net_device *dev)
1293{
1294 struct proc_dir_entry *e;
1295 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1296 priv->dir_dev = create_proc_entry(dev->name,
1297 S_IFDIR | S_IRUGO | S_IXUGO,
1298 rtl8192_proc);
1299 if (!priv->dir_dev) {
1300 RT_TRACE(COMP_ERR, "Unable to initialize /proc/net/rtl8192/%s\n",
1301 dev->name);
1302 return;
1303 }
1304 #if 0
1305 e = create_proc_read_entry("stats-hw", S_IFREG | S_IRUGO,
1306 priv->dir_dev, proc_get_stats_hw, dev);
1307
1308 if (!e) {
1309 DMESGE("Unable to initialize "
1310 "/proc/net/rtl8192/%s/stats-hw\n",
1311 dev->name);
1312 }
1313 #endif
1314 e = create_proc_read_entry("stats-rx", S_IFREG | S_IRUGO,
1315 priv->dir_dev, proc_get_stats_rx, dev);
1316
1317 if (!e) {
1318 RT_TRACE(COMP_ERR,"Unable to initialize "
1319 "/proc/net/rtl8192/%s/stats-rx\n",
1320 dev->name);
1321 }
1322
1323
1324 e = create_proc_read_entry("stats-tx", S_IFREG | S_IRUGO,
1325 priv->dir_dev, proc_get_stats_tx, dev);
1326
1327 if (!e) {
1328 RT_TRACE(COMP_ERR, "Unable to initialize "
1329 "/proc/net/rtl8192/%s/stats-tx\n",
1330 dev->name);
1331 }
1332 #if 0
1333 e = create_proc_read_entry("stats-ieee", S_IFREG | S_IRUGO,
1334 priv->dir_dev, proc_get_stats_ieee, dev);
1335
1336 if (!e) {
1337 DMESGE("Unable to initialize "
1338 "/proc/net/rtl8192/%s/stats-ieee\n",
1339 dev->name);
1340 }
1341
1342 #endif
1343
1344 e = create_proc_read_entry("stats-ap", S_IFREG | S_IRUGO,
1345 priv->dir_dev, proc_get_stats_ap, dev);
1346
1347 if (!e) {
1348 RT_TRACE(COMP_ERR, "Unable to initialize "
1349 "/proc/net/rtl8192/%s/stats-ap\n",
1350 dev->name);
1351 }
1352
1353 e = create_proc_read_entry("registers", S_IFREG | S_IRUGO,
1354 priv->dir_dev, proc_get_registers, dev);
1355 if (!e) {
1356 RT_TRACE(COMP_ERR, "Unable to initialize "
1357 "/proc/net/rtl8192/%s/registers\n",
1358 dev->name);
1359 }
1360#ifdef RTL8192SU
1361 e = create_proc_read_entry("registers-1", S_IFREG | S_IRUGO,
1362 priv->dir_dev, proc_get_registers_1, dev);
1363 if (!e) {
1364 RT_TRACE(COMP_ERR, "Unable to initialize "
1365 "/proc/net/rtl8192/%s/registers-1\n",
1366 dev->name);
1367 }
1368 e = create_proc_read_entry("registers-2", S_IFREG | S_IRUGO,
1369 priv->dir_dev, proc_get_registers_2, dev);
1370 if (!e) {
1371 RT_TRACE(COMP_ERR, "Unable to initialize "
1372 "/proc/net/rtl8192/%s/registers-2\n",
1373 dev->name);
1374 }
1375 e = create_proc_read_entry("registers-8", S_IFREG | S_IRUGO,
1376 priv->dir_dev, proc_get_registers_8, dev);
1377 if (!e) {
1378 RT_TRACE(COMP_ERR, "Unable to initialize "
1379 "/proc/net/rtl8192/%s/registers-8\n",
1380 dev->name);
1381 }
1382 e = create_proc_read_entry("registers-9", S_IFREG | S_IRUGO,
1383 priv->dir_dev, proc_get_registers_9, dev);
1384 if (!e) {
1385 RT_TRACE(COMP_ERR, "Unable to initialize "
1386 "/proc/net/rtl8192/%s/registers-9\n",
1387 dev->name);
1388 }
1389 e = create_proc_read_entry("registers-a", S_IFREG | S_IRUGO,
1390 priv->dir_dev, proc_get_registers_a, dev);
1391 if (!e) {
1392 RT_TRACE(COMP_ERR, "Unable to initialize "
1393 "/proc/net/rtl8192/%s/registers-a\n",
1394 dev->name);
1395 }
1396 e = create_proc_read_entry("registers-b", S_IFREG | S_IRUGO,
1397 priv->dir_dev, proc_get_registers_b, dev);
1398 if (!e) {
1399 RT_TRACE(COMP_ERR, "Unable to initialize "
1400 "/proc/net/rtl8192/%s/registers-b\n",
1401 dev->name);
1402 }
1403 e = create_proc_read_entry("registers-c", S_IFREG | S_IRUGO,
1404 priv->dir_dev, proc_get_registers_c, dev);
1405 if (!e) {
1406 RT_TRACE(COMP_ERR, "Unable to initialize "
1407 "/proc/net/rtl8192/%s/registers-c\n",
1408 dev->name);
1409 }
1410 e = create_proc_read_entry("registers-d", S_IFREG | S_IRUGO,
1411 priv->dir_dev, proc_get_registers_d, dev);
1412 if (!e) {
1413 RT_TRACE(COMP_ERR, "Unable to initialize "
1414 "/proc/net/rtl8192/%s/registers-d\n",
1415 dev->name);
1416 }
1417 e = create_proc_read_entry("registers-e", S_IFREG | S_IRUGO,
1418 priv->dir_dev, proc_get_registers_e, dev);
1419 if (!e) {
1420 RT_TRACE(COMP_ERR, "Unable to initialize "
1421 "/proc/net/rtl8192/%s/registers-e\n",
1422 dev->name);
1423 }
1424#endif
1425#if 0
1426 e = create_proc_read_entry("cck-registers", S_IFREG | S_IRUGO,
1427 priv->dir_dev, proc_get_cck_reg, dev);
1428 if (!e) {
1429 RT_TRACE(COMP_ERR, "Unable to initialize "
1430 "/proc/net/rtl8192/%s/cck-registers\n",
1431 dev->name);
1432 }
1433
1434 e = create_proc_read_entry("ofdm-registers", S_IFREG | S_IRUGO,
1435 priv->dir_dev, proc_get_ofdm_reg, dev);
1436 if (!e) {
1437 RT_TRACE(COMP_ERR, "Unable to initialize "
1438 "/proc/net/rtl8192/%s/ofdm-registers\n",
1439 dev->name);
1440 }
1441#endif
1442}
1443/****************************************************************************
1444 -----------------------------MISC STUFF-------------------------
1445*****************************************************************************/
1446
1447/* this is only for debugging */
1448void print_buffer(u32 *buffer, int len)
1449{
1450 int i;
1451 u8 *buf =(u8*)buffer;
1452
1453 printk("ASCII BUFFER DUMP (len: %x):\n",len);
1454
1455 for(i=0;i<len;i++)
1456 printk("%c",buf[i]);
1457
1458 printk("\nBINARY BUFFER DUMP (len: %x):\n",len);
1459
1460 for(i=0;i<len;i++)
1461 printk("%x",buf[i]);
1462
1463 printk("\n");
1464}
1465
1466//short check_nic_enough_desc(struct net_device *dev, priority_t priority)
1467short check_nic_enough_desc(struct net_device *dev,int queue_index)
1468{
1469 struct r8192_priv *priv = ieee80211_priv(dev);
1470 int used = atomic_read(&priv->tx_pending[queue_index]);
1471
1472 return (used < MAX_TX_URB);
1473}
1474
1475void tx_timeout(struct net_device *dev)
1476{
1477 struct r8192_priv *priv = ieee80211_priv(dev);
1478 //rtl8192_commit(dev);
1479
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001480 schedule_work(&priv->reset_wq);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001481 //DMESG("TXTIMEOUT");
1482}
1483
1484
1485/* this is only for debug */
1486void dump_eprom(struct net_device *dev)
1487{
1488 int i;
1489 for(i=0; i<63; i++)
1490 RT_TRACE(COMP_EPROM, "EEPROM addr %x : %x", i, eprom_read(dev,i));
1491}
1492
1493/* this is only for debug */
1494void rtl8192_dump_reg(struct net_device *dev)
1495{
1496 int i;
1497 int n;
1498 int max=0x1ff;
1499
1500 RT_TRACE(COMP_PHY, "Dumping NIC register map");
1501
1502 for(n=0;n<=max;)
1503 {
1504 printk( "\nD: %2x> ", n);
1505 for(i=0;i<16 && n<=max;i++,n++)
1506 printk("%2x ",read_nic_byte(dev,n));
1507 }
1508 printk("\n");
1509}
1510
1511/****************************************************************************
1512 ------------------------------HW STUFF---------------------------
1513*****************************************************************************/
1514
1515#if 0
1516void rtl8192_irq_enable(struct net_device *dev)
1517{
1518 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1519 //priv->irq_enabled = 1;
1520/*
1521 write_nic_word(dev,INTA_MASK,INTA_RXOK | INTA_RXDESCERR | INTA_RXOVERFLOW |\
1522 INTA_TXOVERFLOW | INTA_HIPRIORITYDESCERR | INTA_HIPRIORITYDESCOK |\
1523 INTA_NORMPRIORITYDESCERR | INTA_NORMPRIORITYDESCOK |\
1524 INTA_LOWPRIORITYDESCERR | INTA_LOWPRIORITYDESCOK | INTA_TIMEOUT);
1525*/
1526 write_nic_word(dev,INTA_MASK, priv->irq_mask);
1527}
1528
1529
1530void rtl8192_irq_disable(struct net_device *dev)
1531{
1532// struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1533
1534 write_nic_word(dev,INTA_MASK,0);
1535 force_pci_posting(dev);
1536// priv->irq_enabled = 0;
1537}
1538#endif
1539
1540void rtl8192_set_mode(struct net_device *dev,int mode)
1541{
1542 u8 ecmd;
1543 ecmd=read_nic_byte(dev, EPROM_CMD);
1544 ecmd=ecmd &~ EPROM_CMD_OPERATING_MODE_MASK;
1545 ecmd=ecmd | (mode<<EPROM_CMD_OPERATING_MODE_SHIFT);
1546 ecmd=ecmd &~ (1<<EPROM_CS_SHIFT);
1547 ecmd=ecmd &~ (1<<EPROM_CK_SHIFT);
1548 write_nic_byte(dev, EPROM_CMD, ecmd);
1549}
1550
1551
1552void rtl8192_update_msr(struct net_device *dev)
1553{
1554 struct r8192_priv *priv = ieee80211_priv(dev);
1555 u8 msr;
1556
1557 msr = read_nic_byte(dev, MSR);
1558 msr &= ~ MSR_LINK_MASK;
1559
1560 /* do not change in link_state != WLAN_LINK_ASSOCIATED.
1561 * msr must be updated if the state is ASSOCIATING.
1562 * this is intentional and make sense for ad-hoc and
1563 * master (see the create BSS/IBSS func)
1564 */
1565 if (priv->ieee80211->state == IEEE80211_LINKED){
1566
1567 if (priv->ieee80211->iw_mode == IW_MODE_INFRA)
1568 msr |= (MSR_LINK_MANAGED<<MSR_LINK_SHIFT);
1569 else if (priv->ieee80211->iw_mode == IW_MODE_ADHOC)
1570 msr |= (MSR_LINK_ADHOC<<MSR_LINK_SHIFT);
1571 else if (priv->ieee80211->iw_mode == IW_MODE_MASTER)
1572 msr |= (MSR_LINK_MASTER<<MSR_LINK_SHIFT);
1573
1574 }else
1575 msr |= (MSR_LINK_NONE<<MSR_LINK_SHIFT);
1576
1577 write_nic_byte(dev, MSR, msr);
1578}
1579
1580void rtl8192_set_chan(struct net_device *dev,short ch)
1581{
1582 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1583// u32 tx;
1584 RT_TRACE(COMP_CH, "=====>%s()====ch:%d\n", __FUNCTION__, ch);
1585 //printk("=====>%s()====ch:%d\n", __FUNCTION__, ch);
1586 priv->chan=ch;
1587 #if 0
1588 if(priv->ieee80211->iw_mode == IW_MODE_ADHOC ||
1589 priv->ieee80211->iw_mode == IW_MODE_MASTER){
1590
1591 priv->ieee80211->link_state = WLAN_LINK_ASSOCIATED;
1592 priv->ieee80211->master_chan = ch;
1593 rtl8192_update_beacon_ch(dev);
1594 }
1595 #endif
1596
1597 /* this hack should avoid frame TX during channel setting*/
1598
1599
1600// tx = read_nic_dword(dev,TX_CONF);
1601// tx &= ~TX_LOOPBACK_MASK;
1602
1603#ifndef LOOP_TEST
1604// write_nic_dword(dev,TX_CONF, tx |( TX_LOOPBACK_MAC<<TX_LOOPBACK_SHIFT));
1605
1606 //need to implement rf set channel here WB
1607
1608 if (priv->rf_set_chan)
1609 priv->rf_set_chan(dev,priv->chan);
1610 mdelay(10);
1611// write_nic_dword(dev,TX_CONF,tx | (TX_LOOPBACK_NONE<<TX_LOOPBACK_SHIFT));
1612#endif
1613}
1614
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001615static void rtl8192_rx_isr(struct urb *urb);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001616
1617u32 get_rxpacket_shiftbytes_819xusb(struct ieee80211_rx_stats *pstats)
1618{
1619
1620#ifdef USB_RX_AGGREGATION_SUPPORT
1621 if (pstats->bisrxaggrsubframe)
1622 return (sizeof(rx_desc_819x_usb) + pstats->RxDrvInfoSize
1623 + pstats->RxBufShift + 8);
1624 else
1625#endif
1626 return (sizeof(rx_desc_819x_usb) + pstats->RxDrvInfoSize
1627 + pstats->RxBufShift);
1628
1629}
1630static int rtl8192_rx_initiate(struct net_device*dev)
1631{
1632 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1633 struct urb *entry;
1634 struct sk_buff *skb;
1635 struct rtl8192_rx_info *info;
1636
1637 /* nomal packet rx procedure */
1638 while (skb_queue_len(&priv->rx_queue) < MAX_RX_URB) {
1639 skb = __dev_alloc_skb(RX_URB_SIZE, GFP_KERNEL);
1640 if (!skb)
1641 break;
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001642 entry = usb_alloc_urb(0, GFP_KERNEL);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001643 if (!entry) {
1644 kfree_skb(skb);
1645 break;
1646 }
1647// printk("nomal packet IN request!\n");
1648 usb_fill_bulk_urb(entry, priv->udev,
1649 usb_rcvbulkpipe(priv->udev, 3), skb->tail,
1650 RX_URB_SIZE, rtl8192_rx_isr, skb);
1651 info = (struct rtl8192_rx_info *) skb->cb;
1652 info->urb = entry;
1653 info->dev = dev;
1654 info->out_pipe = 3; //denote rx normal packet queue
1655 skb_queue_tail(&priv->rx_queue, skb);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001656 usb_submit_urb(entry, GFP_KERNEL);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001657 }
1658
1659 /* command packet rx procedure */
1660 while (skb_queue_len(&priv->rx_queue) < MAX_RX_URB + 3) {
1661// printk("command packet IN request!\n");
1662 skb = __dev_alloc_skb(RX_URB_SIZE ,GFP_KERNEL);
1663 if (!skb)
1664 break;
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001665 entry = usb_alloc_urb(0, GFP_KERNEL);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001666 if (!entry) {
1667 kfree_skb(skb);
1668 break;
1669 }
1670 usb_fill_bulk_urb(entry, priv->udev,
1671 usb_rcvbulkpipe(priv->udev, 9), skb->tail,
1672 RX_URB_SIZE, rtl8192_rx_isr, skb);
1673 info = (struct rtl8192_rx_info *) skb->cb;
1674 info->urb = entry;
1675 info->dev = dev;
1676 info->out_pipe = 9; //denote rx cmd packet queue
1677 skb_queue_tail(&priv->rx_queue, skb);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001678 usb_submit_urb(entry, GFP_KERNEL);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001679 }
1680
1681 return 0;
1682}
1683
1684void rtl8192_set_rxconf(struct net_device *dev)
1685{
1686 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1687 u32 rxconf;
1688
1689 rxconf=read_nic_dword(dev,RCR);
1690 rxconf = rxconf &~ MAC_FILTER_MASK;
1691 rxconf = rxconf | RCR_AMF;
1692 rxconf = rxconf | RCR_ADF;
1693 rxconf = rxconf | RCR_AB;
1694 rxconf = rxconf | RCR_AM;
1695 //rxconf = rxconf | RCR_ACF;
1696
1697 if (dev->flags & IFF_PROMISC) {DMESG ("NIC in promisc mode");}
1698
1699 if(priv->ieee80211->iw_mode == IW_MODE_MONITOR || \
1700 dev->flags & IFF_PROMISC){
1701 rxconf = rxconf | RCR_AAP;
1702 } /*else if(priv->ieee80211->iw_mode == IW_MODE_MASTER){
1703 rxconf = rxconf | (1<<ACCEPT_ALLMAC_FRAME_SHIFT);
1704 rxconf = rxconf | (1<<RX_CHECK_BSSID_SHIFT);
1705 }*/else{
1706 rxconf = rxconf | RCR_APM;
1707 rxconf = rxconf | RCR_CBSSID;
1708 }
1709
1710
1711 if(priv->ieee80211->iw_mode == IW_MODE_MONITOR){
1712 rxconf = rxconf | RCR_AICV;
1713 rxconf = rxconf | RCR_APWRMGT;
1714 }
1715
1716 if( priv->crcmon == 1 && priv->ieee80211->iw_mode == IW_MODE_MONITOR)
1717 rxconf = rxconf | RCR_ACRC32;
1718
1719
1720 rxconf = rxconf &~ RX_FIFO_THRESHOLD_MASK;
1721 rxconf = rxconf | (RX_FIFO_THRESHOLD_NONE<<RX_FIFO_THRESHOLD_SHIFT);
1722 rxconf = rxconf &~ MAX_RX_DMA_MASK;
1723 rxconf = rxconf | ((u32)7<<RCR_MXDMA_OFFSET);
1724
1725// rxconf = rxconf | (1<<RX_AUTORESETPHY_SHIFT);
1726 rxconf = rxconf | RCR_ONLYERLPKT;
1727
1728// rxconf = rxconf &~ RCR_CS_MASK;
1729// rxconf = rxconf | (1<<RCR_CS_SHIFT);
1730
1731 write_nic_dword(dev, RCR, rxconf);
1732
1733 #ifdef DEBUG_RX
1734 DMESG("rxconf: %x %x",rxconf ,read_nic_dword(dev,RCR));
1735 #endif
1736}
1737//wait to be removed
1738void rtl8192_rx_enable(struct net_device *dev)
1739{
1740 //u8 cmd;
1741
1742 //struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1743
1744 rtl8192_rx_initiate(dev);
1745
1746// rtl8192_set_rxconf(dev);
1747#if 0
1748 if(NIC_8187 == priv->card_8187) {
1749 cmd=read_nic_byte(dev,CMD);
1750 write_nic_byte(dev,CMD,cmd | (1<<CMD_RX_ENABLE_SHIFT));
1751 }
1752 else {
1753 //write_nic_dword(dev, RX_CONF, priv->ReceiveConfig);
1754 }
1755#endif
1756}
1757
1758
1759void rtl8192_tx_enable(struct net_device *dev)
1760{
1761#if 0
1762 u8 cmd;
1763 u8 byte;
1764 u32 txconf;
1765 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1766 //test loopback
1767 // priv->TransmitConfig |= (TX_LOOPBACK_BASEBAND<<TX_LOOPBACK_SHIFT);
1768 if(NIC_8187B == priv->card_8187){
1769 write_nic_dword(dev, TX_CONF, priv->TransmitConfig);
1770 byte = read_nic_byte(dev, MSR);
1771 byte |= MSR_LINK_ENEDCA;
1772 write_nic_byte(dev, MSR, byte);
1773 } else {
1774 byte = read_nic_byte(dev,CW_CONF);
1775 byte &= ~(1<<CW_CONF_PERPACKET_CW_SHIFT);
1776 byte &= ~(1<<CW_CONF_PERPACKET_RETRY_SHIFT);
1777 write_nic_byte(dev, CW_CONF, byte);
1778
1779 byte = read_nic_byte(dev, TX_AGC_CTL);
1780 byte &= ~(1<<TX_AGC_CTL_PERPACKET_GAIN_SHIFT);
1781 byte &= ~(1<<TX_AGC_CTL_PERPACKET_ANTSEL_SHIFT);
1782 byte &= ~(1<<TX_AGC_CTL_FEEDBACK_ANT);
1783 write_nic_byte(dev, TX_AGC_CTL, byte);
1784
1785 txconf= read_nic_dword(dev,TX_CONF);
1786
1787
1788 txconf = txconf &~ TX_LOOPBACK_MASK;
1789
1790#ifndef LOOP_TEST
1791 txconf = txconf | (TX_LOOPBACK_NONE<<TX_LOOPBACK_SHIFT);
1792#else
1793 txconf = txconf | (TX_LOOPBACK_BASEBAND<<TX_LOOPBACK_SHIFT);
1794#endif
1795 txconf = txconf &~ TCR_SRL_MASK;
1796 txconf = txconf &~ TCR_LRL_MASK;
1797
1798 txconf = txconf | (priv->retry_data<<TX_LRLRETRY_SHIFT); // long
1799 txconf = txconf | (priv->retry_rts<<TX_SRLRETRY_SHIFT); // short
1800
1801 txconf = txconf &~ (1<<TX_NOCRC_SHIFT);
1802
1803 txconf = txconf &~ TCR_MXDMA_MASK;
1804 txconf = txconf | (TCR_MXDMA_2048<<TCR_MXDMA_SHIFT);
1805
1806 txconf = txconf | TCR_DISReqQsize;
1807 txconf = txconf | TCR_DISCW;
1808 txconf = txconf &~ TCR_SWPLCPLEN;
1809
1810 txconf=txconf | (1<<TX_NOICV_SHIFT);
1811
1812 write_nic_dword(dev,TX_CONF,txconf);
1813
1814#ifdef DEBUG_TX
1815 DMESG("txconf: %x %x",txconf,read_nic_dword(dev,TX_CONF));
1816#endif
1817
1818 cmd=read_nic_byte(dev,CMD);
1819 write_nic_byte(dev,CMD,cmd | (1<<CMD_TX_ENABLE_SHIFT));
1820 }
1821#endif
1822}
1823
1824#if 0
1825void rtl8192_beacon_tx_enable(struct net_device *dev)
1826{
1827 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1828 priv->dma_poll_mask &=~(1<<TX_DMA_STOP_BEACON_SHIFT);
1829 rtl8192_set_mode(dev,EPROM_CMD_CONFIG);
1830 write_nic_byte(dev,TX_DMA_POLLING,priv->dma_poll_mask);
1831 rtl8192_set_mode(dev,EPROM_CMD_NORMAL);
1832}
1833
1834
1835void rtl8192_
1836_disable(struct net_device *dev)
1837{
1838 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1839 priv->dma_poll_mask |= (1<<TX_DMA_STOP_BEACON_SHIFT);
1840 rtl8192_set_mode(dev,EPROM_CMD_CONFIG);
1841 write_nic_byte(dev,TX_DMA_POLLING,priv->dma_poll_mask);
1842 rtl8192_set_mode(dev,EPROM_CMD_NORMAL);
1843}
1844
1845#endif
1846
1847
1848void rtl8192_rtx_disable(struct net_device *dev)
1849{
1850 u8 cmd;
1851 struct r8192_priv *priv = ieee80211_priv(dev);
1852 struct sk_buff *skb;
1853 struct rtl8192_rx_info *info;
1854
1855 cmd=read_nic_byte(dev,CMDR);
1856 write_nic_byte(dev, CMDR, cmd &~ \
1857 (CR_TE|CR_RE));
1858 force_pci_posting(dev);
1859 mdelay(10);
1860
1861 while ((skb = __skb_dequeue(&priv->rx_queue))) {
1862 info = (struct rtl8192_rx_info *) skb->cb;
1863 if (!info->urb)
1864 continue;
1865
1866 usb_kill_urb(info->urb);
1867 kfree_skb(skb);
1868 }
1869
1870 if (skb_queue_len(&priv->skb_queue)) {
1871 printk(KERN_WARNING "skb_queue not empty\n");
1872 }
1873
1874 skb_queue_purge(&priv->skb_queue);
1875 return;
1876}
1877
1878
1879int alloc_tx_beacon_desc_ring(struct net_device *dev, int count)
1880{
1881 #if 0
1882 int i;
1883 u32 *tmp;
1884 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1885
1886 priv->txbeaconring = (u32*)pci_alloc_consistent(priv->pdev,
1887 sizeof(u32)*8*count,
1888 &priv->txbeaconringdma);
1889 if (!priv->txbeaconring) return -1;
1890 for (tmp=priv->txbeaconring,i=0;i<count;i++){
1891 *tmp = *tmp &~ (1<<31); // descriptor empty, owned by the drv
1892 /*
1893 *(tmp+2) = (u32)dma_tmp;
1894 *(tmp+3) = bufsize;
1895 */
1896 if(i+1<count)
1897 *(tmp+4) = (u32)priv->txbeaconringdma+((i+1)*8*4);
1898 else
1899 *(tmp+4) = (u32)priv->txbeaconringdma;
1900
1901 tmp=tmp+8;
1902 }
1903 #endif
1904 return 0;
1905}
1906
1907#if 0
1908void rtl8192_reset(struct net_device *dev)
1909{
1910
1911 //struct r8192_priv *priv = ieee80211_priv(dev);
1912 //u8 cr;
1913
1914
1915 /* make sure the analog power is on before
1916 * reset, otherwise reset may fail
1917 */
1918#if 0
1919 if(NIC_8187 == priv->card_8187) {
1920 rtl8192_set_anaparam(dev, RTL8225_ANAPARAM_ON);
1921 rtl8185_set_anaparam2(dev, RTL8225_ANAPARAM2_ON);
1922 rtl8192_irq_disable(dev);
1923 mdelay(200);
1924 write_nic_byte_E(dev,0x18,0x10);
1925 write_nic_byte_E(dev,0x18,0x11);
1926 write_nic_byte_E(dev,0x18,0x00);
1927 mdelay(200);
1928 }
1929#endif
1930 printk("=====>reset?\n");
1931#if 0
1932 cr=read_nic_byte(dev,CMD);
1933 cr = cr & 2;
1934 cr = cr | (1<<CMD_RST_SHIFT);
1935 write_nic_byte(dev,CMD,cr);
1936
1937 force_pci_posting(dev);
1938
1939 mdelay(200);
1940
1941 if(read_nic_byte(dev,CMD) & (1<<CMD_RST_SHIFT))
1942 RT_TRACE(COMP_ERR, "Card reset timeout!\n");
1943 else
1944 RT_TRACE(COMP_DOWN, "Card successfully reset\n");
1945#endif
1946#if 0
1947 if(NIC_8187 == priv->card_8187) {
1948
1949 printk("This is RTL8187 Reset procedure\n");
1950 rtl8192_set_mode(dev,EPROM_CMD_LOAD);
1951 force_pci_posting(dev);
1952 mdelay(200);
1953
1954 /* after the eeprom load cycle, make sure we have
1955 * correct anaparams
1956 */
1957 rtl8192_set_anaparam(dev, RTL8225_ANAPARAM_ON);
1958 rtl8185_set_anaparam2(dev, RTL8225_ANAPARAM2_ON);
1959 }
1960 else
1961#endif
1962 printk("This is RTL8187B Reset procedure\n");
1963
1964}
1965#endif
1966inline u16 ieeerate2rtlrate(int rate)
1967{
1968 switch(rate){
1969 case 10:
1970 return 0;
1971 case 20:
1972 return 1;
1973 case 55:
1974 return 2;
1975 case 110:
1976 return 3;
1977 case 60:
1978 return 4;
1979 case 90:
1980 return 5;
1981 case 120:
1982 return 6;
1983 case 180:
1984 return 7;
1985 case 240:
1986 return 8;
1987 case 360:
1988 return 9;
1989 case 480:
1990 return 10;
1991 case 540:
1992 return 11;
1993 default:
1994 return 3;
1995
1996 }
1997}
1998static u16 rtl_rate[] = {10,20,55,110,60,90,120,180,240,360,480,540};
1999inline u16 rtl8192_rate2rate(short rate)
2000{
2001 if (rate >11) return 0;
2002 return rtl_rate[rate];
2003}
2004
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002005static void rtl8192_rx_isr(struct urb *urb)
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002006{
2007 struct sk_buff *skb = (struct sk_buff *) urb->context;
2008 struct rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
2009 struct net_device *dev = info->dev;
2010 struct r8192_priv *priv = ieee80211_priv(dev);
2011 int out_pipe = info->out_pipe;
2012 int err;
2013 if(!priv->up)
2014 return;
2015 if (unlikely(urb->status)) {
2016 info->urb = NULL;
2017 priv->stats.rxstaterr++;
2018 priv->ieee80211->stats.rx_errors++;
2019 usb_free_urb(urb);
2020 // printk("%s():rx status err\n",__FUNCTION__);
2021 return;
2022 }
Bartlomiej Zolnierkiewicz1ec9e482009-06-13 18:35:04 +02002023
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002024 skb_unlink(skb, &priv->rx_queue);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002025 skb_put(skb, urb->actual_length);
2026
2027 skb_queue_tail(&priv->skb_queue, skb);
2028 tasklet_schedule(&priv->irq_rx_tasklet);
2029
2030 skb = dev_alloc_skb(RX_URB_SIZE);
2031 if (unlikely(!skb)) {
2032 usb_free_urb(urb);
2033 printk("%s():can,t alloc skb\n",__FUNCTION__);
2034 /* TODO check rx queue length and refill *somewhere* */
2035 return;
2036 }
2037
2038 usb_fill_bulk_urb(urb, priv->udev,
2039 usb_rcvbulkpipe(priv->udev, out_pipe), skb->tail,
2040 RX_URB_SIZE, rtl8192_rx_isr, skb);
2041
2042 info = (struct rtl8192_rx_info *) skb->cb;
2043 info->urb = urb;
2044 info->dev = dev;
2045 info->out_pipe = out_pipe;
2046
2047 urb->transfer_buffer = skb->tail;
2048 urb->context = skb;
2049 skb_queue_tail(&priv->rx_queue, skb);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002050 err = usb_submit_urb(urb, GFP_ATOMIC);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002051 if(err && err != EPERM)
2052 printk("can not submit rxurb, err is %x,URB status is %x\n",err,urb->status);
2053}
2054
2055u32
2056rtl819xusb_rx_command_packet(
2057 struct net_device *dev,
2058 struct ieee80211_rx_stats *pstats
2059 )
2060{
2061 u32 status;
2062
2063 //RT_TRACE(COMP_RECV, DBG_TRACE, ("---> RxCommandPacketHandle819xUsb()\n"));
2064
2065 status = cmpk_message_handle_rx(dev, pstats);
2066 if (status)
2067 {
2068 DMESG("rxcommandpackethandle819xusb: It is a command packet\n");
2069 }
2070 else
2071 {
2072 //RT_TRACE(COMP_RECV, DBG_TRACE, ("RxCommandPacketHandle819xUsb: It is not a command packet\n"));
2073 }
2074
2075 //RT_TRACE(COMP_RECV, DBG_TRACE, ("<--- RxCommandPacketHandle819xUsb()\n"));
2076 return status;
2077}
2078
2079#if 0
2080void rtl8192_tx_queues_stop(struct net_device *dev)
2081{
2082 //struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
2083 u8 dma_poll_mask = (1<<TX_DMA_STOP_LOWPRIORITY_SHIFT);
2084 dma_poll_mask |= (1<<TX_DMA_STOP_HIPRIORITY_SHIFT);
2085 dma_poll_mask |= (1<<TX_DMA_STOP_NORMPRIORITY_SHIFT);
2086 dma_poll_mask |= (1<<TX_DMA_STOP_BEACON_SHIFT);
2087
2088 rtl8192_set_mode(dev,EPROM_CMD_CONFIG);
2089 write_nic_byte(dev,TX_DMA_POLLING,dma_poll_mask);
2090 rtl8192_set_mode(dev,EPROM_CMD_NORMAL);
2091}
2092#endif
2093
2094void rtl8192_data_hard_stop(struct net_device *dev)
2095{
2096 //FIXME !!
2097 #if 0
2098 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
2099 priv->dma_poll_mask |= (1<<TX_DMA_STOP_LOWPRIORITY_SHIFT);
2100 rtl8192_set_mode(dev,EPROM_CMD_CONFIG);
2101 write_nic_byte(dev,TX_DMA_POLLING,priv->dma_poll_mask);
2102 rtl8192_set_mode(dev,EPROM_CMD_NORMAL);
2103 #endif
2104}
2105
2106
2107void rtl8192_data_hard_resume(struct net_device *dev)
2108{
2109 // FIXME !!
2110 #if 0
2111 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
2112 priv->dma_poll_mask &= ~(1<<TX_DMA_STOP_LOWPRIORITY_SHIFT);
2113 rtl8192_set_mode(dev,EPROM_CMD_CONFIG);
2114 write_nic_byte(dev,TX_DMA_POLLING,priv->dma_poll_mask);
2115 rtl8192_set_mode(dev,EPROM_CMD_NORMAL);
2116 #endif
2117}
2118
2119/* this function TX data frames when the ieee80211 stack requires this.
2120 * It checks also if we need to stop the ieee tx queue, eventually do it
2121 */
2122void rtl8192_hard_data_xmit(struct sk_buff *skb, struct net_device *dev, int rate)
2123{
2124 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
2125 int ret;
2126 unsigned long flags;
2127 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
2128 u8 queue_index = tcb_desc->queue_index;
2129
2130 /* shall not be referred by command packet */
2131 assert(queue_index != TXCMD_QUEUE);
2132
2133 spin_lock_irqsave(&priv->tx_lock,flags);
2134
2135 memcpy((unsigned char *)(skb->cb),&dev,sizeof(dev));
2136// tcb_desc->RATRIndex = 7;
2137// tcb_desc->bTxDisableRateFallBack = 1;
2138// tcb_desc->bTxUseDriverAssingedRate = 1;
2139 tcb_desc->bTxEnableFwCalcDur = 1;
2140 skb_push(skb, priv->ieee80211->tx_headroom);
2141 ret = priv->ops->rtl819x_tx(dev, skb);
2142
2143 //priv->ieee80211->stats.tx_bytes+=(skb->len - priv->ieee80211->tx_headroom);
2144 //priv->ieee80211->stats.tx_packets++;
2145
2146 spin_unlock_irqrestore(&priv->tx_lock,flags);
2147
2148// return ret;
2149 return;
2150}
2151
2152/* This is a rough attempt to TX a frame
2153 * This is called by the ieee 80211 stack to TX management frames.
2154 * If the ring is full packet are dropped (for data frame the queue
2155 * is stopped before this can happen).
2156 */
2157int rtl8192_hard_start_xmit(struct sk_buff *skb,struct net_device *dev)
2158{
2159 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
2160 int ret;
2161 unsigned long flags;
2162 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
2163 u8 queue_index = tcb_desc->queue_index;
2164
2165
2166 spin_lock_irqsave(&priv->tx_lock,flags);
2167
2168 memcpy((unsigned char *)(skb->cb),&dev,sizeof(dev));
2169 if(queue_index == TXCMD_QUEUE) {
2170 skb_push(skb, USB_HWDESC_HEADER_LEN);
2171 priv->ops->rtl819x_tx_cmd(dev, skb);
2172 ret = 1;
2173 spin_unlock_irqrestore(&priv->tx_lock,flags);
2174 return ret;
2175 } else {
2176 skb_push(skb, priv->ieee80211->tx_headroom);
2177 ret = priv->ops->rtl819x_tx(dev, skb);
2178 }
2179
2180 spin_unlock_irqrestore(&priv->tx_lock,flags);
2181
2182 return ret;
2183}
2184
2185
2186void rtl8192_try_wake_queue(struct net_device *dev, int pri);
2187
2188#ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
2189u16 DrvAggr_PaddingAdd(struct net_device *dev, struct sk_buff *skb)
2190{
2191 u16 PaddingNum = 256 - ((skb->len + TX_PACKET_DRVAGGR_SUBFRAME_SHIFT_BYTES) % 256);
2192 return (PaddingNum&0xff);
2193}
2194
2195u8 MRateToHwRate8190Pci(u8 rate);
2196u8 QueryIsShort(u8 TxHT, u8 TxRate, cb_desc *tcb_desc);
2197u8 MapHwQueueToFirmwareQueue(u8 QueueID);
2198struct sk_buff *DrvAggr_Aggregation(struct net_device *dev, struct ieee80211_drv_agg_txb *pSendList)
2199{
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002200 struct ieee80211_device *ieee = netdev_priv(dev);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002201 struct r8192_priv *priv = ieee80211_priv(dev);
2202 cb_desc *tcb_desc = NULL;
2203 u8 i;
2204 u32 TotalLength;
2205 struct sk_buff *skb;
2206 struct sk_buff *agg_skb;
2207 tx_desc_819x_usb_aggr_subframe *tx_agg_desc = NULL;
2208 tx_fwinfo_819x_usb *tx_fwinfo = NULL;
2209
2210 //
2211 // Local variable initialization.
2212 //
2213 /* first skb initialization */
2214 skb = pSendList->tx_agg_frames[0];
2215 TotalLength = skb->len;
2216
2217 /* Get the total aggregation length including the padding space and
2218 * sub frame header.
2219 */
2220 for(i = 1; i < pSendList->nr_drv_agg_frames; i++) {
2221 TotalLength += DrvAggr_PaddingAdd(dev, skb);
2222 skb = pSendList->tx_agg_frames[i];
2223 TotalLength += (skb->len + TX_PACKET_DRVAGGR_SUBFRAME_SHIFT_BYTES);
2224 }
2225
2226 /* allocate skb to contain the aggregated packets */
2227 agg_skb = dev_alloc_skb(TotalLength + ieee->tx_headroom);
2228 memset(agg_skb->data, 0, agg_skb->len);
2229 skb_reserve(agg_skb, ieee->tx_headroom);
2230
2231// RT_DEBUG_DATA(COMP_SEND, skb->cb, sizeof(skb->cb));
2232 /* reserve info for first subframe Tx descriptor to be set in the tx function */
2233 skb = pSendList->tx_agg_frames[0];
2234 tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
2235 tcb_desc->drv_agg_enable = 1;
2236 tcb_desc->pkt_size = skb->len;
2237 tcb_desc->DrvAggrNum = pSendList->nr_drv_agg_frames;
2238 printk("DrvAggNum = %d\n", tcb_desc->DrvAggrNum);
2239// RT_DEBUG_DATA(COMP_SEND, skb->cb, sizeof(skb->cb));
2240// printk("========>skb->data ======> \n");
2241// RT_DEBUG_DATA(COMP_SEND, skb->data, skb->len);
2242 memcpy(agg_skb->cb, skb->cb, sizeof(skb->cb));
2243 memcpy(skb_put(agg_skb,skb->len),skb->data,skb->len);
2244
2245 for(i = 1; i < pSendList->nr_drv_agg_frames; i++) {
2246 /* push the next sub frame to be 256 byte aline */
2247 skb_put(agg_skb,DrvAggr_PaddingAdd(dev,skb));
2248
2249 /* Subframe drv Tx descriptor and firmware info setting */
2250 skb = pSendList->tx_agg_frames[i];
2251 tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
2252 tx_agg_desc = (tx_desc_819x_usb_aggr_subframe *)agg_skb->tail;
2253 tx_fwinfo = (tx_fwinfo_819x_usb *)(agg_skb->tail + sizeof(tx_desc_819x_usb_aggr_subframe));
2254
2255 memset(tx_fwinfo,0,sizeof(tx_fwinfo_819x_usb));
2256 /* DWORD 0 */
2257 tx_fwinfo->TxHT = (tcb_desc->data_rate&0x80)?1:0;
2258 tx_fwinfo->TxRate = MRateToHwRate8190Pci(tcb_desc->data_rate);
2259 tx_fwinfo->EnableCPUDur = tcb_desc->bTxEnableFwCalcDur;
2260 tx_fwinfo->Short = QueryIsShort(tx_fwinfo->TxHT, tx_fwinfo->TxRate, tcb_desc);
2261 if(tcb_desc->bAMPDUEnable) {//AMPDU enabled
2262 tx_fwinfo->AllowAggregation = 1;
2263 /* DWORD 1 */
2264 tx_fwinfo->RxMF = tcb_desc->ampdu_factor;
2265 tx_fwinfo->RxAMD = tcb_desc->ampdu_density&0x07;//ampdudensity
2266 } else {
2267 tx_fwinfo->AllowAggregation = 0;
2268 /* DWORD 1 */
2269 tx_fwinfo->RxMF = 0;
2270 tx_fwinfo->RxAMD = 0;
2271 }
2272
2273 /* Protection mode related */
2274 tx_fwinfo->RtsEnable = (tcb_desc->bRTSEnable)?1:0;
2275 tx_fwinfo->CtsEnable = (tcb_desc->bCTSEnable)?1:0;
2276 tx_fwinfo->RtsSTBC = (tcb_desc->bRTSSTBC)?1:0;
2277 tx_fwinfo->RtsHT = (tcb_desc->rts_rate&0x80)?1:0;
2278 tx_fwinfo->RtsRate = MRateToHwRate8190Pci((u8)tcb_desc->rts_rate);
2279 tx_fwinfo->RtsSubcarrier = (tx_fwinfo->RtsHT==0)?(tcb_desc->RTSSC):0;
2280 tx_fwinfo->RtsBandwidth = (tx_fwinfo->RtsHT==1)?((tcb_desc->bRTSBW)?1:0):0;
2281 tx_fwinfo->RtsShort = (tx_fwinfo->RtsHT==0)?(tcb_desc->bRTSUseShortPreamble?1:0):\
2282 (tcb_desc->bRTSUseShortGI?1:0);
2283
2284 /* Set Bandwidth and sub-channel settings. */
2285 if(priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20_40)
2286 {
2287 if(tcb_desc->bPacketBW) {
2288 tx_fwinfo->TxBandwidth = 1;
2289 tx_fwinfo->TxSubCarrier = 0; //By SD3's Jerry suggestion, use duplicated mode
2290 } else {
2291 tx_fwinfo->TxBandwidth = 0;
2292 tx_fwinfo->TxSubCarrier = priv->nCur40MhzPrimeSC;
2293 }
2294 } else {
2295 tx_fwinfo->TxBandwidth = 0;
2296 tx_fwinfo->TxSubCarrier = 0;
2297 }
2298
2299 /* Fill Tx descriptor */
2300 memset(tx_agg_desc, 0, sizeof(tx_desc_819x_usb_aggr_subframe));
2301 /* DWORD 0 */
2302 //tx_agg_desc->LINIP = 0;
2303 //tx_agg_desc->CmdInit = 1;
2304 tx_agg_desc->Offset = sizeof(tx_fwinfo_819x_usb) + 8;
2305 /* already raw data, need not to substract header length */
2306 tx_agg_desc->PktSize = skb->len & 0xffff;
2307
2308 /*DWORD 1*/
2309 tx_agg_desc->SecCAMID= 0;
2310 tx_agg_desc->RATid = tcb_desc->RATRIndex;
2311#if 0
2312 /* Fill security related */
2313 if( pTcb->bEncrypt && !Adapter->MgntInfo.SecurityInfo.SWTxEncryptFlag)
2314 {
2315 EncAlg = SecGetEncryptionOverhead(
2316 Adapter,
2317 &EncryptionMPDUHeadOverhead,
2318 &EncryptionMPDUTailOverhead,
2319 NULL,
2320 NULL,
2321 FALSE,
2322 FALSE);
2323 //2004/07/22, kcwu, EncryptionMPDUHeadOverhead has been added in previous code
2324 //MPDUOverhead = EncryptionMPDUHeadOverhead + EncryptionMPDUTailOverhead;
2325 MPDUOverhead = EncryptionMPDUTailOverhead;
2326 tx_agg_desc->NoEnc = 0;
2327 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));
2328 //CamDumpAll(Adapter);
2329 }
2330 else
2331#endif
2332 {
2333 //MPDUOverhead = 0;
2334 tx_agg_desc->NoEnc = 1;
2335 }
2336#if 0
2337 switch(EncAlg){
2338 case NO_Encryption:
2339 tx_agg_desc->SecType = 0x0;
2340 break;
2341 case WEP40_Encryption:
2342 case WEP104_Encryption:
2343 tx_agg_desc->SecType = 0x1;
2344 break;
2345 case TKIP_Encryption:
2346 tx_agg_desc->SecType = 0x2;
2347 break;
2348 case AESCCMP_Encryption:
2349 tx_agg_desc->SecType = 0x3;
2350 break;
2351 default:
2352 tx_agg_desc->SecType = 0x0;
2353 break;
2354 }
2355#else
2356 tx_agg_desc->SecType = 0x0;
2357#endif
2358
2359 if (tcb_desc->bHwSec) {
2360 switch (priv->ieee80211->pairwise_key_type)
2361 {
2362 case KEY_TYPE_WEP40:
2363 case KEY_TYPE_WEP104:
2364 tx_agg_desc->SecType = 0x1;
2365 tx_agg_desc->NoEnc = 0;
2366 break;
2367 case KEY_TYPE_TKIP:
2368 tx_agg_desc->SecType = 0x2;
2369 tx_agg_desc->NoEnc = 0;
2370 break;
2371 case KEY_TYPE_CCMP:
2372 tx_agg_desc->SecType = 0x3;
2373 tx_agg_desc->NoEnc = 0;
2374 break;
2375 case KEY_TYPE_NA:
2376 tx_agg_desc->SecType = 0x0;
2377 tx_agg_desc->NoEnc = 1;
2378 break;
2379 }
2380 }
2381
2382 tx_agg_desc->QueueSelect = MapHwQueueToFirmwareQueue(tcb_desc->queue_index);
2383 tx_agg_desc->TxFWInfoSize = sizeof(tx_fwinfo_819x_usb);
2384
2385 tx_agg_desc->DISFB = tcb_desc->bTxDisableRateFallBack;
2386 tx_agg_desc->USERATE = tcb_desc->bTxUseDriverAssingedRate;
2387
2388 tx_agg_desc->OWN = 1;
2389
2390 //DWORD 2
2391 /* According windows driver, it seems that there no need to fill this field */
2392 //tx_agg_desc->TxBufferSize= (u32)(skb->len - USB_HWDESC_HEADER_LEN);
2393
2394 /* to fill next packet */
2395 skb_put(agg_skb,TX_PACKET_DRVAGGR_SUBFRAME_SHIFT_BYTES);
2396 memcpy(skb_put(agg_skb,skb->len),skb->data,skb->len);
2397 }
2398
2399 for(i = 0; i < pSendList->nr_drv_agg_frames; i++) {
2400 dev_kfree_skb_any(pSendList->tx_agg_frames[i]);
2401 }
2402
2403 return agg_skb;
2404}
2405
2406/* NOTE:
2407 This function return a list of PTCB which is proper to be aggregate with the input TCB.
2408 If no proper TCB is found to do aggregation, SendList will only contain the input TCB.
2409*/
2410u8 DrvAggr_GetAggregatibleList(struct net_device *dev, struct sk_buff *skb,
2411 struct ieee80211_drv_agg_txb *pSendList)
2412{
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002413 struct ieee80211_device *ieee = netdev_priv(dev);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002414 PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
2415 u16 nMaxAggrNum = pHTInfo->UsbTxAggrNum;
2416 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
2417 u8 QueueID = tcb_desc->queue_index;
2418
2419 do {
2420 pSendList->tx_agg_frames[pSendList->nr_drv_agg_frames++] = skb;
2421 if(pSendList->nr_drv_agg_frames >= nMaxAggrNum) {
2422 break;
2423 }
2424
2425 } while((skb = skb_dequeue(&ieee->skb_drv_aggQ[QueueID])));
2426
2427 RT_TRACE(COMP_AMSDU, "DrvAggr_GetAggregatibleList, nAggrTcbNum = %d \n", pSendList->nr_drv_agg_frames);
2428 return pSendList->nr_drv_agg_frames;
2429}
2430#endif
2431
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002432static void rtl8192_tx_isr(struct urb *tx_urb)
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002433{
2434 struct sk_buff *skb = (struct sk_buff*)tx_urb->context;
2435 struct net_device *dev = NULL;
2436 struct r8192_priv *priv = NULL;
2437 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
2438 u8 queue_index = tcb_desc->queue_index;
2439// bool bToSend0Byte;
2440// u16 BufLen = skb->len;
2441
2442 memcpy(&dev,(struct net_device*)(skb->cb),sizeof(struct net_device*));
2443 priv = ieee80211_priv(dev);
2444
2445 if(tcb_desc->queue_index != TXCMD_QUEUE) {
2446 if(tx_urb->status == 0) {
2447 // dev->trans_start = jiffies;
2448 // As act as station mode, destion shall be unicast address.
2449 //priv->ieee80211->stats.tx_bytes+=(skb->len - priv->ieee80211->tx_headroom);
2450 //priv->ieee80211->stats.tx_packets++;
2451 priv->stats.txoktotal++;
2452 priv->ieee80211->LinkDetectInfo.NumTxOkInPeriod++;
2453 priv->stats.txbytesunicast += (skb->len - priv->ieee80211->tx_headroom);
2454 } else {
2455 priv->ieee80211->stats.tx_errors++;
2456 //priv->stats.txmanageerr++;
2457 /* TODO */
2458 }
2459 }
2460
2461 /* free skb and tx_urb */
2462 if(skb != NULL) {
2463 dev_kfree_skb_any(skb);
2464 usb_free_urb(tx_urb);
2465 atomic_dec(&priv->tx_pending[queue_index]);
2466 }
2467
2468#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
2469 if(BufLen > 0 && ((BufLen % 512 == 0)||(BufLen % 64 == 0))) {
2470 bToSend0Byte = true;
2471 }
2472
2473 bToSend0Byte = false;
2474 //
2475 // Note that, we at most handle 1 MPDU to send here, either
2476 // fragment or MPDU in wait queue.
2477 //
2478 if(!bToSend0Byte)
2479#endif
2480 {
2481 //
2482 // Handle HW Beacon:
2483 // We had transfer our beacon frame to host controler at this moment.
2484 //
2485#if 0
2486 if(tcb_desc->tx_queue == BEACON_QUEUE)
2487 {
2488 priv->bSendingBeacon = FALSE;
2489 }
2490#endif
2491 //
2492 // Caution:
2493 // Handling the wait queue of command packets.
2494 // For Tx command packets, we must not do TCB fragment because it is not handled right now.
2495 // We must cut the packets to match the size of TX_CMD_PKT before we send it.
2496 //
2497 if (queue_index == MGNT_QUEUE){
2498 if (priv->ieee80211->ack_tx_to_ieee){
2499 if (rtl8192_is_tx_queue_empty(dev)){
2500 priv->ieee80211->ack_tx_to_ieee = 0;
2501 ieee80211_ps_tx_ack(priv->ieee80211, 1);
2502 }
2503 }
2504 }
2505 /* Handle MPDU in wait queue. */
2506 if(queue_index != BEACON_QUEUE) {
2507 /* Don't send data frame during scanning.*/
2508 if((skb_queue_len(&priv->ieee80211->skb_waitQ[queue_index]) != 0)&&\
2509 (!(priv->ieee80211->queue_stop))) {
2510 if(NULL != (skb = skb_dequeue(&(priv->ieee80211->skb_waitQ[queue_index]))))
2511 priv->ieee80211->softmac_hard_start_xmit(skb, dev);
2512
2513 return; //modified by david to avoid further processing AMSDU
2514 }
2515#ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
2516 else if ((skb_queue_len(&priv->ieee80211->skb_drv_aggQ[queue_index])!= 0)&&\
2517 (!(priv->ieee80211->queue_stop))) {
2518 // Tx Driver Aggregation process
2519 /* The driver will aggregation the packets according to the following stets
2520 * 1. check whether there's tx irq available, for it's a completion return
2521 * function, it should contain enough tx irq;
2522 * 2. check pakcet type;
2523 * 3. intialize sendlist, check whether the to-be send packet no greater than 1
2524 * 4. aggregation the packets, and fill firmware info and tx desc to it, etc.
2525 * 5. check whehter the packet could be sent, otherwise just insert to wait head
2526 * */
2527 skb = skb_dequeue(&priv->ieee80211->skb_drv_aggQ[queue_index]);
2528 if(!check_nic_enough_desc(dev, queue_index)) {
2529 skb_queue_head(&(priv->ieee80211->skb_drv_aggQ[queue_index]), skb);
2530 return;
2531 }
2532
2533 {
2534 /*TODO*/
2535 /*
2536 u8* pHeader = skb->data;
2537
2538 if(IsMgntQosData(pHeader) ||
2539 IsMgntQData_Ack(pHeader) ||
2540 IsMgntQData_Poll(pHeader) ||
2541 IsMgntQData_Poll_Ack(pHeader)
2542 )
2543 */
2544 {
2545 struct ieee80211_drv_agg_txb SendList;
2546
2547 memset(&SendList, 0, sizeof(struct ieee80211_drv_agg_txb));
2548 if(DrvAggr_GetAggregatibleList(dev, skb, &SendList) > 1) {
2549 skb = DrvAggr_Aggregation(dev, &SendList);
2550
2551#if 0
2552 printk("=============>to send aggregated packet!\n");
2553 RT_DEBUG_DATA(COMP_SEND, skb->cb, sizeof(skb->cb));
2554 printk("\n=================skb->len = %d\n", skb->len);
2555 RT_DEBUG_DATA(COMP_SEND, skb->data, skb->len);
2556#endif
2557 }
2558 }
2559 priv->ieee80211->softmac_hard_start_xmit(skb, dev);
2560 }
2561 }
2562#endif
2563 }
2564 }
2565
2566#if 0
2567 else
2568 {
2569 RT_TRACE( COMP_SEND,"HalUsbOutComplete(%d): bToSend0Byte.\n", PipeIndex);
2570
2571 //
2572 // In this case, we don't return skb now.
2573 // It will be returned when the 0-byte request completed.
2574 //
2575
2576 //
2577 // Bulk out an 0-byte padding transfer.
2578 //
2579 HalUsbOut0Byte(pAdapter, PipeIndex, skb);
2580 }
2581
2582#endif
2583}
2584
2585void rtl8192_beacon_stop(struct net_device *dev)
2586{
2587 u8 msr, msrm, msr2;
2588 struct r8192_priv *priv = ieee80211_priv(dev);
2589
2590 msr = read_nic_byte(dev, MSR);
2591 msrm = msr & MSR_LINK_MASK;
2592 msr2 = msr & ~MSR_LINK_MASK;
2593
2594 if(NIC_8192U == priv->card_8192) {
2595 usb_kill_urb(priv->rx_urb[MAX_RX_URB]);
2596 }
2597 if ((msrm == (MSR_LINK_ADHOC<<MSR_LINK_SHIFT) ||
2598 (msrm == (MSR_LINK_MASTER<<MSR_LINK_SHIFT)))){
2599 write_nic_byte(dev, MSR, msr2 | MSR_LINK_NONE);
2600 write_nic_byte(dev, MSR, msr);
2601 }
2602}
2603
2604void rtl8192_config_rate(struct net_device* dev, u16* rate_config)
2605{
2606 struct r8192_priv *priv = ieee80211_priv(dev);
2607 struct ieee80211_network *net;
2608 u8 i=0, basic_rate = 0;
2609 net = & priv->ieee80211->current_network;
2610
2611 for (i=0; i<net->rates_len; i++)
2612 {
2613 basic_rate = net->rates[i]&0x7f;
2614 switch(basic_rate)
2615 {
2616 case MGN_1M: *rate_config |= RRSR_1M; break;
2617 case MGN_2M: *rate_config |= RRSR_2M; break;
2618 case MGN_5_5M: *rate_config |= RRSR_5_5M; break;
2619 case MGN_11M: *rate_config |= RRSR_11M; break;
2620 case MGN_6M: *rate_config |= RRSR_6M; break;
2621 case MGN_9M: *rate_config |= RRSR_9M; break;
2622 case MGN_12M: *rate_config |= RRSR_12M; break;
2623 case MGN_18M: *rate_config |= RRSR_18M; break;
2624 case MGN_24M: *rate_config |= RRSR_24M; break;
2625 case MGN_36M: *rate_config |= RRSR_36M; break;
2626 case MGN_48M: *rate_config |= RRSR_48M; break;
2627 case MGN_54M: *rate_config |= RRSR_54M; break;
2628 }
2629 }
2630 for (i=0; i<net->rates_ex_len; i++)
2631 {
2632 basic_rate = net->rates_ex[i]&0x7f;
2633 switch(basic_rate)
2634 {
2635 case MGN_1M: *rate_config |= RRSR_1M; break;
2636 case MGN_2M: *rate_config |= RRSR_2M; break;
2637 case MGN_5_5M: *rate_config |= RRSR_5_5M; break;
2638 case MGN_11M: *rate_config |= RRSR_11M; break;
2639 case MGN_6M: *rate_config |= RRSR_6M; break;
2640 case MGN_9M: *rate_config |= RRSR_9M; break;
2641 case MGN_12M: *rate_config |= RRSR_12M; break;
2642 case MGN_18M: *rate_config |= RRSR_18M; break;
2643 case MGN_24M: *rate_config |= RRSR_24M; break;
2644 case MGN_36M: *rate_config |= RRSR_36M; break;
2645 case MGN_48M: *rate_config |= RRSR_48M; break;
2646 case MGN_54M: *rate_config |= RRSR_54M; break;
2647 }
2648 }
2649}
2650
2651
2652#define SHORT_SLOT_TIME 9
2653#define NON_SHORT_SLOT_TIME 20
2654
2655void rtl8192_update_cap(struct net_device* dev, u16 cap)
2656{
2657 //u32 tmp = 0;
2658 struct r8192_priv *priv = ieee80211_priv(dev);
2659 struct ieee80211_network *net = &priv->ieee80211->current_network;
2660 priv->short_preamble = cap & WLAN_CAPABILITY_SHORT_PREAMBLE;
2661
2662 //LZM MOD 090303 HW_VAR_ACK_PREAMBLE
2663#ifdef RTL8192SU
2664 if(0)
2665 {
2666 u8 tmp = 0;
2667 tmp = ((priv->nCur40MhzPrimeSC) << 5);
2668 if (priv->short_preamble)
2669 tmp |= 0x80;
2670 write_nic_byte(dev, RRSR+2, tmp);
2671 }
2672#else
2673 {
2674 u32 tmp = 0;
2675 tmp = priv->basic_rate;
2676 if (priv->short_preamble)
2677 tmp |= BRSR_AckShortPmb;
2678 write_nic_dword(dev, RRSR, tmp);
2679 }
2680#endif
2681
2682 if (net->mode & (IEEE_G|IEEE_N_24G))
2683 {
2684 u8 slot_time = 0;
2685 if ((cap & WLAN_CAPABILITY_SHORT_SLOT)&&(!priv->ieee80211->pHTInfo->bCurrentRT2RTLongSlotTime))
2686 {//short slot time
2687 slot_time = SHORT_SLOT_TIME;
2688 }
2689 else //long slot time
2690 slot_time = NON_SHORT_SLOT_TIME;
2691 priv->slot_time = slot_time;
2692 write_nic_byte(dev, SLOT_TIME, slot_time);
2693 }
2694
2695}
2696void rtl8192_net_update(struct net_device *dev)
2697{
2698
2699 struct r8192_priv *priv = ieee80211_priv(dev);
2700 struct ieee80211_network *net;
2701 u16 BcnTimeCfg = 0, BcnCW = 6, BcnIFS = 0xf;
2702 u16 rate_config = 0;
2703 net = & priv->ieee80211->current_network;
2704
2705 rtl8192_config_rate(dev, &rate_config);
2706 priv->basic_rate = rate_config &= 0x15f;
2707
2708 write_nic_dword(dev,BSSIDR,((u32*)net->bssid)[0]);
2709 write_nic_word(dev,BSSIDR+4,((u16*)net->bssid)[2]);
2710 //for(i=0;i<ETH_ALEN;i++)
2711 // write_nic_byte(dev,BSSID+i,net->bssid[i]);
2712
2713 rtl8192_update_msr(dev);
2714// rtl8192_update_cap(dev, net->capability);
2715 if (priv->ieee80211->iw_mode == IW_MODE_ADHOC)
2716 {
2717 write_nic_word(dev, ATIMWND, 2);
2718 write_nic_word(dev, BCN_DMATIME, 1023);
2719 write_nic_word(dev, BCN_INTERVAL, net->beacon_interval);
2720// write_nic_word(dev, BcnIntTime, 100);
2721 write_nic_word(dev, BCN_DRV_EARLY_INT, 1);
2722 write_nic_byte(dev, BCN_ERR_THRESH, 100);
2723 BcnTimeCfg |= (BcnCW<<BCN_TCFG_CW_SHIFT);
2724 // TODO: BcnIFS may required to be changed on ASIC
2725 BcnTimeCfg |= BcnIFS<<BCN_TCFG_IFS;
2726
2727 write_nic_word(dev, BCN_TCFG, BcnTimeCfg);
2728 }
2729
2730
2731
2732}
2733
2734//temporary hw beacon is not used any more.
2735//open it when necessary
2736#if 1
2737void rtl819xusb_beacon_tx(struct net_device *dev,u16 tx_rate)
2738{
2739
2740#if 0
2741 struct r8192_priv *priv = ieee80211_priv(dev);
2742 struct sk_buff *skb;
2743 int i = 0;
2744 //u8 cr;
2745
2746 rtl8192_net_update(dev);
2747
2748 skb = ieee80211_get_beacon(priv->ieee80211);
2749 if(!skb){
2750 DMESG("not enought memory for allocating beacon");
2751 return;
2752 }
2753
2754
2755 write_nic_byte(dev, BQREQ, read_nic_byte(dev, BQREQ) | (1<<7));
2756
2757 i=0;
2758 //while(!read_nic_byte(dev,BQREQ & (1<<7)))
2759 while( (read_nic_byte(dev, BQREQ) & (1<<7)) == 0 )
2760 {
2761 msleep_interruptible_rtl(HZ/2);
2762 if(i++ > 10){
2763 DMESGW("get stuck to wait HW beacon to be ready");
2764 return ;
2765 }
2766 }
2767 skb->cb[0] = NORM_PRIORITY;
2768 skb->cb[1] = 0; //morefragment = 0
2769 skb->cb[2] = ieeerate2rtlrate(tx_rate);
2770
2771 rtl8192_tx(dev,skb);
2772
2773#endif
2774}
2775#endif
2776inline u8 rtl8192_IsWirelessBMode(u16 rate)
2777{
2778 if( ((rate <= 110) && (rate != 60) && (rate != 90)) || (rate == 220) )
2779 return 1;
2780 else return 0;
2781}
2782
2783u16 N_DBPSOfRate(u16 DataRate);
2784
2785u16 ComputeTxTime(
2786 u16 FrameLength,
2787 u16 DataRate,
2788 u8 bManagementFrame,
2789 u8 bShortPreamble
2790)
2791{
2792 u16 FrameTime;
2793 u16 N_DBPS;
2794 u16 Ceiling;
2795
2796 if( rtl8192_IsWirelessBMode(DataRate) )
2797 {
2798 if( bManagementFrame || !bShortPreamble || DataRate == 10 )
2799 { // long preamble
2800 FrameTime = (u16)(144+48+(FrameLength*8/(DataRate/10)));
2801 }
2802 else
2803 { // Short preamble
2804 FrameTime = (u16)(72+24+(FrameLength*8/(DataRate/10)));
2805 }
2806 if( ( FrameLength*8 % (DataRate/10) ) != 0 ) //Get the Ceilling
2807 FrameTime ++;
2808 } else { //802.11g DSSS-OFDM PLCP length field calculation.
2809 N_DBPS = N_DBPSOfRate(DataRate);
2810 Ceiling = (16 + 8*FrameLength + 6) / N_DBPS
2811 + (((16 + 8*FrameLength + 6) % N_DBPS) ? 1 : 0);
2812 FrameTime = (u16)(16 + 4 + 4*Ceiling + 6);
2813 }
2814 return FrameTime;
2815}
2816
2817u16 N_DBPSOfRate(u16 DataRate)
2818{
2819 u16 N_DBPS = 24;
2820
2821 switch(DataRate)
2822 {
2823 case 60:
2824 N_DBPS = 24;
2825 break;
2826
2827 case 90:
2828 N_DBPS = 36;
2829 break;
2830
2831 case 120:
2832 N_DBPS = 48;
2833 break;
2834
2835 case 180:
2836 N_DBPS = 72;
2837 break;
2838
2839 case 240:
2840 N_DBPS = 96;
2841 break;
2842
2843 case 360:
2844 N_DBPS = 144;
2845 break;
2846
2847 case 480:
2848 N_DBPS = 192;
2849 break;
2850
2851 case 540:
2852 N_DBPS = 216;
2853 break;
2854
2855 default:
2856 break;
2857 }
2858
2859 return N_DBPS;
2860}
2861
2862void rtl819xU_cmd_isr(struct urb *tx_cmd_urb, struct pt_regs *regs)
2863{
2864#if 0
2865 struct net_device *dev = (struct net_device*)tx_cmd_urb->context;
2866 struct r8192_priv *priv = ieee80211_priv(dev);
2867 int last_init_packet = 0;
2868 u8 *ptr_cmd_buf;
2869 u16 cmd_buf_len;
2870
2871 if(tx_cmd_urb->status != 0) {
2872 priv->pFirmware.firmware_seg_index = 0; //only begin transter, should it can be set to 1
2873 }
2874
2875 /* Free the urb and the corresponding buf for common Tx cmd packet, or
2876 * last segment of each firmware img.
2877 */
2878 if((priv->pFirmware.firmware_seg_index == 0) ||(priv->pFirmware.firmware_seg_index == priv->pFirmware.firmware_seg_maxnum)) {
2879 priv->pFirmware.firmware_seg_index = 0;//only begin transter, should it can be set to 1
2880 } else {
2881 /* prepare for last transfer */
2882 /* update some infomation for */
2883 /* last segment of the firmware img need indicate to device */
2884 priv->pFirmware.firmware_seg_index++;
2885 if(priv->pFirmware.firmware_seg_index == priv->pFirmware.firmware_seg_maxnum) {
2886 last_init_packet = 1;
2887 }
2888
2889 cmd_buf_len = priv->pFirmware.firmware_seg_container[priv->pFirmware.firmware_seg_index-1].seg_size;
2890 ptr_cmd_buf = priv->pFfirmware.firmware_seg_container[priv->pFfirmware.firmware_seg_index-1].seg_ptr;
2891 rtl819xU_tx_cmd(dev, ptr_cmd_buf, cmd_buf_len, last_init_packet, DESC_PACKET_TYPE_INIT);
2892 }
2893
2894 kfree(tx_cmd_urb->transfer_buffer);
2895#endif
2896 usb_free_urb(tx_cmd_urb);
2897}
2898
2899unsigned int txqueue2outpipe(struct r8192_priv* priv,unsigned int tx_queue) {
2900
2901 if(tx_queue >= 9)
2902 {
2903 RT_TRACE(COMP_ERR,"%s():Unknown queue ID!!!\n",__FUNCTION__);
2904 return 0x04;
2905 }
2906 return priv->txqueue_to_outpipemap[tx_queue];
2907}
2908
2909#ifdef RTL8192SU
2910short rtl8192SU_tx_cmd(struct net_device *dev, struct sk_buff *skb)
2911{
2912 struct r8192_priv *priv = ieee80211_priv(dev);
2913 int status;
2914 struct urb *tx_urb;
2915 unsigned int idx_pipe;
2916 tx_desc_cmd_819x_usb *pdesc = (tx_desc_cmd_819x_usb *)skb->data;
2917 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
2918 u8 queue_index = tcb_desc->queue_index;
2919 u32 PktSize = 0;
2920
2921 //printk("\n %s::::::::::::::::::::::queue_index = %d\n",__FUNCTION__, queue_index);
2922 atomic_inc(&priv->tx_pending[queue_index]);
2923
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002924 tx_urb = usb_alloc_urb(0,GFP_ATOMIC);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002925 if(!tx_urb){
2926 dev_kfree_skb(skb);
2927 return -ENOMEM;
2928 }
2929
2930 memset(pdesc, 0, USB_HWDESC_HEADER_LEN);
2931
2932 /* Tx descriptor ought to be set according to the skb->cb */
2933 pdesc->LINIP = tcb_desc->bLastIniPkt;
2934 PktSize = (u16)(skb->len - USB_HWDESC_HEADER_LEN);
2935 pdesc->PktSize = PktSize;
2936 //printk("PKTSize = %d %x\n",pdesc->PktSize,pdesc->PktSize);
2937 //----------------------------------------------------------------------------
2938 // Fill up USB_OUT_CONTEXT.
2939 //----------------------------------------------------------------------------
2940 // Get index to out pipe from specified QueueID.
2941 idx_pipe = txqueue2outpipe(priv,queue_index);
2942 //printk("=============>%s queue_index:%d, outpipe:%d\n", __func__,queue_index,priv->RtOutPipes[idx_pipe]);
2943
2944#ifdef JOHN_DUMP_TXDESC
2945 int i;
2946 printk("Len = %d\n", skb->len);
2947 for (i = 0; i < 8; i++)
2948 printk("%2.2x ", *((u8*)skb->data+i));
2949 printk("\n");
2950#endif
2951
2952 usb_fill_bulk_urb(tx_urb,
2953 priv->udev,
2954 usb_sndbulkpipe(priv->udev,priv->RtOutPipes[idx_pipe]),
2955 skb->data,
2956 skb->len,
2957 rtl8192_tx_isr,
2958 skb);
2959
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002960 status = usb_submit_urb(tx_urb, GFP_ATOMIC);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002961 if (!status){
2962 return 0;
2963 }else{
2964 printk("Error TX CMD URB, error %d",
2965 status);
2966 return -1;
2967 }
2968}
2969#else
2970short rtl819xU_tx_cmd(struct net_device *dev, struct sk_buff *skb)
2971{
2972 struct r8192_priv *priv = ieee80211_priv(dev);
2973 //u8 *tx;
2974 int status;
2975 struct urb *tx_urb;
2976 //int urb_buf_len;
2977 unsigned int idx_pipe;
2978 tx_desc_cmd_819x_usb *pdesc = (tx_desc_cmd_819x_usb *)skb->data;
2979 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
2980 u8 queue_index = tcb_desc->queue_index;
2981
2982 //printk("\n %s::queue_index = %d\n",__FUNCTION__, queue_index);
2983 atomic_inc(&priv->tx_pending[queue_index]);
Bartlomiej Zolnierkiewicz1ec9e482009-06-13 18:35:04 +02002984
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002985 tx_urb = usb_alloc_urb(0,GFP_ATOMIC);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002986 if(!tx_urb){
2987 dev_kfree_skb(skb);
2988 return -ENOMEM;
2989 }
2990
2991 memset(pdesc, 0, USB_HWDESC_HEADER_LEN);
2992 /* Tx descriptor ought to be set according to the skb->cb */
2993 pdesc->FirstSeg = 1;//bFirstSeg;
2994 pdesc->LastSeg = 1;//bLastSeg;
2995 pdesc->CmdInit = tcb_desc->bCmdOrInit;
2996 pdesc->TxBufferSize = tcb_desc->txbuf_size;
2997 pdesc->OWN = 1;
2998 pdesc->LINIP = tcb_desc->bLastIniPkt;
2999
3000 //----------------------------------------------------------------------------
3001 // Fill up USB_OUT_CONTEXT.
3002 //----------------------------------------------------------------------------
3003 // Get index to out pipe from specified QueueID.
3004#ifndef USE_ONE_PIPE
3005 idx_pipe = txqueue2outpipe(priv,queue_index);
3006#else
3007 idx_pipe = 0x04;
3008#endif
3009#ifdef JOHN_DUMP_TXDESC
3010 int i;
3011 printk("<Tx descriptor>--rate %x---",rate);
3012 for (i = 0; i < 8; i++)
3013 printk("%8x ", tx[i]);
3014 printk("\n");
3015#endif
3016 usb_fill_bulk_urb(tx_urb,priv->udev, usb_sndbulkpipe(priv->udev,idx_pipe), \
3017 skb->data, skb->len, rtl8192_tx_isr, skb);
3018
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003019 status = usb_submit_urb(tx_urb, GFP_ATOMIC);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003020 if (!status){
3021 return 0;
3022 }else{
3023 DMESGE("Error TX CMD URB, error %d",
3024 status);
3025 return -1;
3026 }
3027}
3028#endif
3029
3030/*
3031 * Mapping Software/Hardware descriptor queue id to "Queue Select Field"
3032 * in TxFwInfo data structure
3033 * 2006.10.30 by Emily
3034 *
3035 * \param QUEUEID Software Queue
3036*/
3037u8 MapHwQueueToFirmwareQueue(u8 QueueID)
3038{
3039 u8 QueueSelect = 0x0; //defualt set to
3040
3041 switch(QueueID) {
3042 case BE_QUEUE:
3043 QueueSelect = QSLT_BE; //or QSelect = pTcb->priority;
3044 break;
3045
3046 case BK_QUEUE:
3047 QueueSelect = QSLT_BK; //or QSelect = pTcb->priority;
3048 break;
3049
3050 case VO_QUEUE:
3051 QueueSelect = QSLT_VO; //or QSelect = pTcb->priority;
3052 break;
3053
3054 case VI_QUEUE:
3055 QueueSelect = QSLT_VI; //or QSelect = pTcb->priority;
3056 break;
3057 case MGNT_QUEUE:
3058 QueueSelect = QSLT_MGNT;
3059 break;
3060
3061 case BEACON_QUEUE:
3062 QueueSelect = QSLT_BEACON;
3063 break;
3064
3065 // TODO: 2006.10.30 mark other queue selection until we verify it is OK
3066 // TODO: Remove Assertions
3067//#if (RTL819X_FPGA_VER & RTL819X_FPGA_GUANGAN_070502)
3068 case TXCMD_QUEUE:
3069 QueueSelect = QSLT_CMD;
3070 break;
3071//#endif
3072 case HIGH_QUEUE:
3073 QueueSelect = QSLT_HIGH;
3074 break;
3075
3076 default:
3077 RT_TRACE(COMP_ERR, "TransmitTCB(): Impossible Queue Selection: %d \n", QueueID);
3078 break;
3079 }
3080 return QueueSelect;
3081}
3082
3083#ifdef RTL8192SU
3084u8 MRateToHwRate8190Pci(u8 rate)
3085{
3086 u8 ret = DESC92S_RATE1M;
3087
3088 switch(rate)
3089 {
3090 // CCK and OFDM non-HT rates
3091 case MGN_1M: ret = DESC92S_RATE1M; break;
3092 case MGN_2M: ret = DESC92S_RATE2M; break;
3093 case MGN_5_5M: ret = DESC92S_RATE5_5M; break;
3094 case MGN_11M: ret = DESC92S_RATE11M; break;
3095 case MGN_6M: ret = DESC92S_RATE6M; break;
3096 case MGN_9M: ret = DESC92S_RATE9M; break;
3097 case MGN_12M: ret = DESC92S_RATE12M; break;
3098 case MGN_18M: ret = DESC92S_RATE18M; break;
3099 case MGN_24M: ret = DESC92S_RATE24M; break;
3100 case MGN_36M: ret = DESC92S_RATE36M; break;
3101 case MGN_48M: ret = DESC92S_RATE48M; break;
3102 case MGN_54M: ret = DESC92S_RATE54M; break;
3103
3104 // HT rates since here
3105 case MGN_MCS0: ret = DESC92S_RATEMCS0; break;
3106 case MGN_MCS1: ret = DESC92S_RATEMCS1; break;
3107 case MGN_MCS2: ret = DESC92S_RATEMCS2; break;
3108 case MGN_MCS3: ret = DESC92S_RATEMCS3; break;
3109 case MGN_MCS4: ret = DESC92S_RATEMCS4; break;
3110 case MGN_MCS5: ret = DESC92S_RATEMCS5; break;
3111 case MGN_MCS6: ret = DESC92S_RATEMCS6; break;
3112 case MGN_MCS7: ret = DESC92S_RATEMCS7; break;
3113 case MGN_MCS8: ret = DESC92S_RATEMCS8; break;
3114 case MGN_MCS9: ret = DESC92S_RATEMCS9; break;
3115 case MGN_MCS10: ret = DESC92S_RATEMCS10; break;
3116 case MGN_MCS11: ret = DESC92S_RATEMCS11; break;
3117 case MGN_MCS12: ret = DESC92S_RATEMCS12; break;
3118 case MGN_MCS13: ret = DESC92S_RATEMCS13; break;
3119 case MGN_MCS14: ret = DESC92S_RATEMCS14; break;
3120 case MGN_MCS15: ret = DESC92S_RATEMCS15; break;
3121
3122 // Set the highest SG rate
3123 case MGN_MCS0_SG:
3124 case MGN_MCS1_SG:
3125 case MGN_MCS2_SG:
3126 case MGN_MCS3_SG:
3127 case MGN_MCS4_SG:
3128 case MGN_MCS5_SG:
3129 case MGN_MCS6_SG:
3130 case MGN_MCS7_SG:
3131 case MGN_MCS8_SG:
3132 case MGN_MCS9_SG:
3133 case MGN_MCS10_SG:
3134 case MGN_MCS11_SG:
3135 case MGN_MCS12_SG:
3136 case MGN_MCS13_SG:
3137 case MGN_MCS14_SG:
3138 case MGN_MCS15_SG:
3139 {
3140 ret = DESC92S_RATEMCS15_SG;
3141 break;
3142 }
3143
3144 default: break;
3145 }
3146 return ret;
3147}
3148#else
3149u8 MRateToHwRate8190Pci(u8 rate)
3150{
3151 u8 ret = DESC90_RATE1M;
3152
3153 switch(rate) {
3154 case MGN_1M: ret = DESC90_RATE1M; break;
3155 case MGN_2M: ret = DESC90_RATE2M; break;
3156 case MGN_5_5M: ret = DESC90_RATE5_5M; break;
3157 case MGN_11M: ret = DESC90_RATE11M; break;
3158 case MGN_6M: ret = DESC90_RATE6M; break;
3159 case MGN_9M: ret = DESC90_RATE9M; break;
3160 case MGN_12M: ret = DESC90_RATE12M; break;
3161 case MGN_18M: ret = DESC90_RATE18M; break;
3162 case MGN_24M: ret = DESC90_RATE24M; break;
3163 case MGN_36M: ret = DESC90_RATE36M; break;
3164 case MGN_48M: ret = DESC90_RATE48M; break;
3165 case MGN_54M: ret = DESC90_RATE54M; break;
3166
3167 // HT rate since here
3168 case MGN_MCS0: ret = DESC90_RATEMCS0; break;
3169 case MGN_MCS1: ret = DESC90_RATEMCS1; break;
3170 case MGN_MCS2: ret = DESC90_RATEMCS2; break;
3171 case MGN_MCS3: ret = DESC90_RATEMCS3; break;
3172 case MGN_MCS4: ret = DESC90_RATEMCS4; break;
3173 case MGN_MCS5: ret = DESC90_RATEMCS5; break;
3174 case MGN_MCS6: ret = DESC90_RATEMCS6; break;
3175 case MGN_MCS7: ret = DESC90_RATEMCS7; break;
3176 case MGN_MCS8: ret = DESC90_RATEMCS8; break;
3177 case MGN_MCS9: ret = DESC90_RATEMCS9; break;
3178 case MGN_MCS10: ret = DESC90_RATEMCS10; break;
3179 case MGN_MCS11: ret = DESC90_RATEMCS11; break;
3180 case MGN_MCS12: ret = DESC90_RATEMCS12; break;
3181 case MGN_MCS13: ret = DESC90_RATEMCS13; break;
3182 case MGN_MCS14: ret = DESC90_RATEMCS14; break;
3183 case MGN_MCS15: ret = DESC90_RATEMCS15; break;
3184 case (0x80|0x20): ret = DESC90_RATEMCS32; break;
3185
3186 default: break;
3187 }
3188 return ret;
3189}
3190#endif
3191
3192u8 QueryIsShort(u8 TxHT, u8 TxRate, cb_desc *tcb_desc)
3193{
3194 u8 tmp_Short;
3195
3196 tmp_Short = (TxHT==1)?((tcb_desc->bUseShortGI)?1:0):((tcb_desc->bUseShortPreamble)?1:0);
3197
3198 if(TxHT==1 && TxRate != DESC90_RATEMCS15)
3199 tmp_Short = 0;
3200
3201 return tmp_Short;
3202}
3203
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003204static void tx_zero_isr(struct urb *tx_urb)
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003205{
3206 return;
3207}
3208
3209
3210#ifdef RTL8192SU
3211/*
3212 * The tx procedure is just as following, skb->cb will contain all the following
3213 *information: * priority, morefrag, rate, &dev.
3214 * */
3215 // <Note> Buffer format for 8192S Usb bulk out:
3216//
3217// --------------------------------------------------
3218// | 8192S Usb Tx Desc | 802_11_MAC_header | data |
3219// --------------------------------------------------
3220// | 32 bytes | 24 bytes |0-2318 bytes|
3221// --------------------------------------------------
3222// |<------------ BufferLen ------------------------->|
3223
3224short rtl8192SU_tx(struct net_device *dev, struct sk_buff* skb)
3225{
3226 struct r8192_priv *priv = ieee80211_priv(dev);
3227 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
3228 tx_desc_819x_usb *tx_desc = (tx_desc_819x_usb *)skb->data;
3229 //tx_fwinfo_819x_usb *tx_fwinfo = (tx_fwinfo_819x_usb *)(skb->data + USB_HWDESC_HEADER_LEN);//92su del
3230 struct usb_device *udev = priv->udev;
3231 int pend;
3232 int status;
3233 struct urb *tx_urb = NULL, *tx_urb_zero = NULL;
3234 //int urb_len;
3235 unsigned int idx_pipe;
3236 u16 MPDUOverhead = 0;
3237 //RT_DEBUG_DATA(COMP_SEND, tcb_desc, sizeof(cb_desc));
3238
3239#if 0
3240 /* Added by Annie for filling Len_Adjust field. 2005-12-14. */
3241 RT_ENC_ALG EncAlg = NO_Encryption;
3242#endif
3243
3244
3245 pend = atomic_read(&priv->tx_pending[tcb_desc->queue_index]);
3246 /* we are locked here so the two atomic_read and inc are executed
3247 * without interleaves * !!! For debug purpose */
3248 if( pend > MAX_TX_URB){
3249 switch (tcb_desc->queue_index) {
3250 case VO_PRIORITY:
3251 priv->stats.txvodrop++;
3252 break;
3253 case VI_PRIORITY:
3254 priv->stats.txvidrop++;
3255 break;
3256 case BE_PRIORITY:
3257 priv->stats.txbedrop++;
3258 break;
3259 default://BK_PRIORITY
3260 priv->stats.txbkdrop++;
3261 break;
3262 }
3263 printk("To discard skb packet!\n");
3264 dev_kfree_skb_any(skb);
3265 return -1;
3266 }
3267
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003268 tx_urb = usb_alloc_urb(0,GFP_ATOMIC);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003269 if(!tx_urb){
3270 dev_kfree_skb_any(skb);
3271 return -ENOMEM;
3272 }
3273
3274 memset(tx_desc, 0, sizeof(tx_desc_819x_usb));
3275
3276
3277#if RTL8192SU_FPGA_UNSPECIFIED_NETWORK
3278 if(IsQoSDataFrame(skb->data))
3279 {
3280 tcb_desc->bAMPDUEnable = TRUE;
3281 tx_desc->NonQos = 0;
3282 }
3283 else
3284 tcb_desc->bAMPDUEnable = FALSE;
3285
3286 tcb_desc->bPacketBW = TRUE;
3287 priv->CurrentChannelBW = HT_CHANNEL_WIDTH_20_40;
3288#endif
3289
3290#if (defined (RTL8192SU_FPGA_2MAC_VERIFICATION)||defined (RTL8192SU_ASIC_VERIFICATION))
3291 tx_desc->NonQos = (IsQoSDataFrame(skb->data)==TRUE)? 0:1;
3292#endif
3293
3294 /* Fill Tx descriptor */
3295 //memset(tx_fwinfo,0,sizeof(tx_fwinfo_819x_usb));
3296
3297 // This part can just fill to the first descriptor of the frame.
3298 /* DWORD 0 */
3299 tx_desc->TxHT = (tcb_desc->data_rate&0x80)?1:0;
3300
3301#ifdef RTL8192SU_DISABLE_CCK_RATE
3302 if(tx_hal_is_cck_rate(tcb_desc->data_rate))
3303 tcb_desc->data_rate = MGN_6M;
3304#endif
3305
3306 tx_desc->TxRate = MRateToHwRate8190Pci(tcb_desc->data_rate);
3307 //tx_desc->EnableCPUDur = tcb_desc->bTxEnableFwCalcDur;
3308 tx_desc->TxShort = QueryIsShort(tx_desc->TxHT, tx_desc->TxRate, tcb_desc);
3309
3310
3311 // Aggregation related
3312 if(tcb_desc->bAMPDUEnable) {//AMPDU enabled
3313 tx_desc->AllowAggregation = 1;
3314 /* DWORD 1 */
3315 //tx_fwinfo->RxMF = tcb_desc->ampdu_factor;
3316 //tx_fwinfo->RxAMD = tcb_desc->ampdu_density&0x07;//ampdudensity
3317 } else {
3318 tx_desc->AllowAggregation = 0;
3319 /* DWORD 1 */
3320 //tx_fwinfo->RxMF = 0;
3321 //tx_fwinfo->RxAMD = 0;
3322 }
3323
3324 //
3325 // <Roger_Notes> For AMPDU case, we must insert SSN into TX_DESC,
3326 // FW according as this SSN to do necessary packet retry.
3327 // 2008.06.06.
3328 //
3329 {
3330 u8 *pSeq;
3331 u16 Temp;
3332 //pSeq = (u8 *)(VirtualAddress+USB_HWDESC_HEADER_LEN + FRAME_OFFSET_SEQUENCE);
3333 pSeq = (u8 *)(skb->data+USB_HWDESC_HEADER_LEN + 22);
3334 Temp = pSeq[0];
3335 Temp <<= 12;
3336 Temp |= (*(u16 *)pSeq)>>4;
3337 tx_desc->Seq = Temp;
3338 }
3339
3340 /* Protection mode related */
3341 tx_desc->RTSEn = (tcb_desc->bRTSEnable)?1:0;
3342 tx_desc->CTS2Self = (tcb_desc->bCTSEnable)?1:0;
3343 tx_desc->RTSSTBC = (tcb_desc->bRTSSTBC)?1:0;
3344 tx_desc->RTSHT = (tcb_desc->rts_rate&0x80)?1:0;
3345 tx_desc->RTSRate = MRateToHwRate8190Pci((u8)tcb_desc->rts_rate);
3346 tx_desc->RTSSubcarrier = (tx_desc->RTSHT==0)?(tcb_desc->RTSSC):0;
3347 tx_desc->RTSBW = (tx_desc->RTSHT==1)?((tcb_desc->bRTSBW)?1:0):0;
3348 tx_desc->RTSShort = (tx_desc->RTSHT==0)?(tcb_desc->bRTSUseShortPreamble?1:0):\
3349 (tcb_desc->bRTSUseShortGI?1:0);
3350 //LZM 090219
3351 tx_desc->DisRTSFB = 0;
3352 tx_desc->RTSRateFBLmt = 0xf;
3353
3354 // <Roger_EXP> 2008.09.22. We disable RTS rate fallback temporarily.
3355 //tx_desc->DisRTSFB = 0x01;
3356
3357 /* Set Bandwidth and sub-channel settings. */
3358 if(priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20_40)
3359 {
3360 if(tcb_desc->bPacketBW) {
3361 tx_desc->TxBandwidth = 1;
3362 tx_desc->TxSubCarrier = 0; //By SD3's Jerry suggestion, use duplicated mode
3363 } else {
3364 tx_desc->TxBandwidth = 0;
3365 tx_desc->TxSubCarrier = priv->nCur40MhzPrimeSC;
3366 }
3367 } else {
3368 tx_desc->TxBandwidth = 0;
3369 tx_desc->TxSubCarrier = 0;
3370 }
3371
3372#ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
3373 if (tcb_desc->drv_agg_enable)
3374 {
3375 //tx_desc->Tx_INFO_RSVD = (tcb_desc->DrvAggrNum & 0x1f) << 1; //92su del
3376 }
3377#endif
3378
3379 //memset(tx_desc, 0, sizeof(tx_desc_819x_usb));
3380 /* DWORD 0 */
3381 tx_desc->LINIP = 0;
3382 //tx_desc->CmdInit = 1; //92su del
3383 tx_desc->Offset = USB_HWDESC_HEADER_LEN;
3384
3385#ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
3386 if (tcb_desc->drv_agg_enable) {
3387 tx_desc->PktSize = tcb_desc->pkt_size;//FIXLZM
3388 } else
3389#endif
3390 {
3391 tx_desc->PktSize = (skb->len - USB_HWDESC_HEADER_LEN) & 0xffff;
3392 }
3393
3394 /*DWORD 1*/
3395 //tx_desc->SecCAMID= 0;//92su del
3396 tx_desc->RaBRSRID= tcb_desc->RATRIndex;
3397//#ifdef RTL8192S_PREPARE_FOR_NORMAL_RELEASE
3398#if 0//LZM 090219
3399 tx_desc->RaBRSRID= 1;
3400#endif
3401
3402#if 0
3403 /* Fill security related */
3404 if( pTcb->bEncrypt && !Adapter->MgntInfo.SecurityInfo.SWTxEncryptFlag)
3405 {
3406 EncAlg = SecGetEncryptionOverhead(
3407 Adapter,
3408 &EncryptionMPDUHeadOverhead,
3409 &EncryptionMPDUTailOverhead,
3410 NULL,
3411 NULL,
3412 FALSE,
3413 FALSE);
3414 //2004/07/22, kcwu, EncryptionMPDUHeadOverhead has been added in previous code
3415 //MPDUOverhead = EncryptionMPDUHeadOverhead + EncryptionMPDUTailOverhead;
3416 MPDUOverhead = EncryptionMPDUTailOverhead;
3417 tx_desc->NoEnc = 0;
3418 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));
3419 //CamDumpAll(Adapter);
3420 }
3421 else
3422#endif
3423 {
3424 MPDUOverhead = 0;
3425 //tx_desc->NoEnc = 1;//92su del
3426 }
3427#if 0
3428 switch(EncAlg){
3429 case NO_Encryption:
3430 tx_desc->SecType = 0x0;
3431 break;
3432 case WEP40_Encryption:
3433 case WEP104_Encryption:
3434 tx_desc->SecType = 0x1;
3435 break;
3436 case TKIP_Encryption:
3437 tx_desc->SecType = 0x2;
3438 break;
3439 case AESCCMP_Encryption:
3440 tx_desc->SecType = 0x3;
3441 break;
3442 default:
3443 tx_desc->SecType = 0x0;
3444 break;
3445 }
3446#else
3447 tx_desc->SecType = 0x0;
3448#endif
3449 if (tcb_desc->bHwSec)
3450 {
3451 switch (priv->ieee80211->pairwise_key_type)
3452 {
3453 case KEY_TYPE_WEP40:
3454 case KEY_TYPE_WEP104:
3455 tx_desc->SecType = 0x1;
3456 //tx_desc->NoEnc = 0;//92su del
3457 break;
3458 case KEY_TYPE_TKIP:
3459 tx_desc->SecType = 0x2;
3460 //tx_desc->NoEnc = 0;//92su del
3461 break;
3462 case KEY_TYPE_CCMP:
3463 tx_desc->SecType = 0x3;
3464 //tx_desc->NoEnc = 0;//92su del
3465 break;
3466 case KEY_TYPE_NA:
3467 tx_desc->SecType = 0x0;
3468 //tx_desc->NoEnc = 1;//92su del
3469 break;
3470 default:
3471 tx_desc->SecType = 0x0;
3472 //tx_desc->NoEnc = 1;//92su del
3473 break;
3474 }
3475 }
3476
3477 //tx_desc->TxFWInfoSize = sizeof(tx_fwinfo_819x_usb);//92su del
3478
3479
3480 tx_desc->USERATE = tcb_desc->bTxUseDriverAssingedRate;
3481 tx_desc->DISFB = tcb_desc->bTxDisableRateFallBack;
3482 tx_desc->DataRateFBLmt = 0x1F;// Alwasy enable all rate fallback range
3483
3484 tx_desc->QueueSelect = MapHwQueueToFirmwareQueue(tcb_desc->queue_index);
3485
3486
3487 /* Fill fields that are required to be initialized in all of the descriptors */
3488 //DWORD 0
3489#if 0
3490 tx_desc->FirstSeg = (tcb_desc->bFirstSeg)? 1:0;
3491 tx_desc->LastSeg = (tcb_desc->bLastSeg)?1:0;
3492#else
3493 tx_desc->FirstSeg = 1;
3494 tx_desc->LastSeg = 1;
3495#endif
3496 tx_desc->OWN = 1;
3497
3498#ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
3499 if (tcb_desc->drv_agg_enable) {
3500 tx_desc->TxBufferSize = tcb_desc->pkt_size + sizeof(tx_fwinfo_819x_usb);
3501 } else
3502#endif
3503 {
3504 //DWORD 2
3505 //tx_desc->TxBufferSize = (u32)(skb->len - USB_HWDESC_HEADER_LEN);
3506 tx_desc->TxBufferSize = (u32)(skb->len);//92su mod FIXLZM
3507 }
3508
3509#if 0
3510 RT_TRACE(COMP_FPGA, DBG_LOUD, ("(1)TxFillDescriptor8192SUsb(): DataRate(%#x)\n", pTcb->DataRate));
3511 RT_TRACE(COMP_FPGA, DBG_LOUD, ("(2)TxFillDescriptor8192SUsb(): bTxUseDriverAssingedRate(%#x)\n", pTcb->bTxUseDriverAssingedRate));
3512 RT_TRACE(COMP_FPGA, DBG_LOUD, ("(3)TxFillDescriptor8192SUsb(): bAMPDUEnable(%d)\n", pTcb->bAMPDUEnable));
3513 RT_TRACE(COMP_FPGA, DBG_LOUD, ("(4)TxFillDescriptor8192SUsb(): bRTSEnable(%d)\n", pTcb->bRTSEnable));
3514 RT_TRACE(COMP_FPGA, DBG_LOUD, ("(5)TxFillDescriptor8192SUsb(): RTSRate(%#x)\n", pTcb->RTSRate));
3515 RT_TRACE(COMP_FPGA, DBG_LOUD, ("(6)TxFillDescriptor8192SUsb(): bCTSEnable(%d)\n", pTcb->bCTSEnable));
3516 RT_TRACE(COMP_FPGA, DBG_LOUD, ("(7)TxFillDescriptor8192SUsb(): bUseShortGI(%d)\n", pTcb->bUseShortGI));
3517 RT_TRACE(COMP_FPGA, DBG_LOUD, ("(8)TxFillDescriptor8192SUsb(): bPacketBW(%d)\n", pTcb->bPacketBW));
3518 RT_TRACE(COMP_FPGA, DBG_LOUD, ("(9)TxFillDescriptor8192SUsb(): CurrentChannelBW(%d)\n", pHalData->CurrentChannelBW));
3519 RT_TRACE(COMP_FPGA, DBG_LOUD, ("(10)TxFillDescriptor8192SUsb(): bTxDisableRateFallBack(%d)\n", pTcb->bTxDisableRateFallBack));
3520 RT_TRACE(COMP_FPGA, DBG_LOUD, ("(11)TxFillDescriptor8192SUsb(): RATRIndex(%d)\n", pTcb->RATRIndex));
3521#endif
3522
3523 /* Get index to out pipe from specified QueueID */
3524 idx_pipe = txqueue2outpipe(priv,tcb_desc->queue_index);
3525 //printk("=============>%s queue_index:%d, outpipe:%d\n", __func__,tcb_desc->queue_index,priv->RtOutPipes[idx_pipe]);
3526
3527 //RT_DEBUG_DATA(COMP_SEND,tx_fwinfo,sizeof(tx_fwinfo_819x_usb));
3528 //RT_DEBUG_DATA(COMP_SEND,tx_desc,sizeof(tx_desc_819x_usb));
3529
3530 /* To submit bulk urb */
3531 usb_fill_bulk_urb(tx_urb,
3532 udev,
3533 usb_sndbulkpipe(udev,priv->RtOutPipes[idx_pipe]),
3534 skb->data,
3535 skb->len, rtl8192_tx_isr, skb);
3536
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003537 status = usb_submit_urb(tx_urb, GFP_ATOMIC);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003538 if (!status){
3539//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
3540 bool bSend0Byte = false;
3541 u8 zero = 0;
3542 if(udev->speed == USB_SPEED_HIGH)
3543 {
3544 if (skb->len > 0 && skb->len % 512 == 0)
3545 bSend0Byte = true;
3546 }
3547 else
3548 {
3549 if (skb->len > 0 && skb->len % 64 == 0)
3550 bSend0Byte = true;
3551 }
3552 if (bSend0Byte)
3553 {
3554#if 1
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003555 tx_urb_zero = usb_alloc_urb(0,GFP_ATOMIC);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003556 if(!tx_urb_zero){
3557 RT_TRACE(COMP_ERR, "can't alloc urb for zero byte\n");
3558 return -ENOMEM;
3559 }
3560 usb_fill_bulk_urb(tx_urb_zero,udev,
3561 usb_sndbulkpipe(udev,idx_pipe), &zero,
3562 0, tx_zero_isr, dev);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003563 status = usb_submit_urb(tx_urb_zero, GFP_ATOMIC);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003564 if (status){
3565 RT_TRACE(COMP_ERR, "Error TX URB for zero byte %d, error %d", atomic_read(&priv->tx_pending[tcb_desc->queue_index]), status);
3566 return -1;
3567 }
3568#endif
3569 }
3570 dev->trans_start = jiffies;
3571 atomic_inc(&priv->tx_pending[tcb_desc->queue_index]);
3572 return 0;
3573 }else{
3574 RT_TRACE(COMP_ERR, "Error TX URB %d, error %d", atomic_read(&priv->tx_pending[tcb_desc->queue_index]),
3575 status);
3576 return -1;
3577 }
3578}
3579#else
3580
3581/*
3582 * The tx procedure is just as following,
3583 * skb->cb will contain all the following information,
3584 * priority, morefrag, rate, &dev.
3585 * */
3586short rtl8192_tx(struct net_device *dev, struct sk_buff* skb)
3587{
3588 struct r8192_priv *priv = ieee80211_priv(dev);
3589 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
3590 tx_desc_819x_usb *tx_desc = (tx_desc_819x_usb *)skb->data;
3591 tx_fwinfo_819x_usb *tx_fwinfo = (tx_fwinfo_819x_usb *)(skb->data + USB_HWDESC_HEADER_LEN);
3592 struct usb_device *udev = priv->udev;
3593 int pend;
3594 int status;
3595 struct urb *tx_urb = NULL, *tx_urb_zero = NULL;
3596 //int urb_len;
3597 unsigned int idx_pipe;
3598// RT_DEBUG_DATA(COMP_SEND, tcb_desc, sizeof(cb_desc));
3599#if 0
3600 /* Added by Annie for filling Len_Adjust field. 2005-12-14. */
3601 RT_ENC_ALG EncAlg = NO_Encryption;
3602#endif
3603// printk("=============> %s\n", __FUNCTION__);
3604 pend = atomic_read(&priv->tx_pending[tcb_desc->queue_index]);
3605 /* we are locked here so the two atomic_read and inc are executed
3606 * without interleaves
3607 * !!! For debug purpose
3608 */
3609 if( pend > MAX_TX_URB){
3610#if 0
3611 switch (tcb_desc->queue_index) {
3612 case VO_PRIORITY:
3613 priv->stats.txvodrop++;
3614 break;
3615 case VI_PRIORITY:
3616 priv->stats.txvidrop++;
3617 break;
3618 case BE_PRIORITY:
3619 priv->stats.txbedrop++;
3620 break;
3621 default://BK_PRIORITY
3622 priv->stats.txbkdrop++;
3623 break;
3624 }
3625#endif
3626 printk("To discard skb packet!\n");
3627 dev_kfree_skb_any(skb);
3628 return -1;
3629 }
3630
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003631 tx_urb = usb_alloc_urb(0,GFP_ATOMIC);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003632 if(!tx_urb){
3633 dev_kfree_skb_any(skb);
3634 return -ENOMEM;
3635 }
3636
3637 /* Fill Tx firmware info */
3638 memset(tx_fwinfo,0,sizeof(tx_fwinfo_819x_usb));
3639 /* DWORD 0 */
3640 tx_fwinfo->TxHT = (tcb_desc->data_rate&0x80)?1:0;
3641 tx_fwinfo->TxRate = MRateToHwRate8190Pci(tcb_desc->data_rate);
3642 tx_fwinfo->EnableCPUDur = tcb_desc->bTxEnableFwCalcDur;
3643 tx_fwinfo->Short = QueryIsShort(tx_fwinfo->TxHT, tx_fwinfo->TxRate, tcb_desc);
3644 if(tcb_desc->bAMPDUEnable) {//AMPDU enabled
3645 tx_fwinfo->AllowAggregation = 1;
3646 /* DWORD 1 */
3647 tx_fwinfo->RxMF = tcb_desc->ampdu_factor;
3648 tx_fwinfo->RxAMD = tcb_desc->ampdu_density&0x07;//ampdudensity
3649 } else {
3650 tx_fwinfo->AllowAggregation = 0;
3651 /* DWORD 1 */
3652 tx_fwinfo->RxMF = 0;
3653 tx_fwinfo->RxAMD = 0;
3654 }
3655
3656 /* Protection mode related */
3657 tx_fwinfo->RtsEnable = (tcb_desc->bRTSEnable)?1:0;
3658 tx_fwinfo->CtsEnable = (tcb_desc->bCTSEnable)?1:0;
3659 tx_fwinfo->RtsSTBC = (tcb_desc->bRTSSTBC)?1:0;
3660 tx_fwinfo->RtsHT = (tcb_desc->rts_rate&0x80)?1:0;
3661 tx_fwinfo->RtsRate = MRateToHwRate8190Pci((u8)tcb_desc->rts_rate);
3662 tx_fwinfo->RtsSubcarrier = (tx_fwinfo->RtsHT==0)?(tcb_desc->RTSSC):0;
3663 tx_fwinfo->RtsBandwidth = (tx_fwinfo->RtsHT==1)?((tcb_desc->bRTSBW)?1:0):0;
3664 tx_fwinfo->RtsShort = (tx_fwinfo->RtsHT==0)?(tcb_desc->bRTSUseShortPreamble?1:0):\
3665 (tcb_desc->bRTSUseShortGI?1:0);
3666
3667 /* Set Bandwidth and sub-channel settings. */
3668 if(priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20_40)
3669 {
3670 if(tcb_desc->bPacketBW) {
3671 tx_fwinfo->TxBandwidth = 1;
3672 tx_fwinfo->TxSubCarrier = 0; //By SD3's Jerry suggestion, use duplicated mode
3673 } else {
3674 tx_fwinfo->TxBandwidth = 0;
3675 tx_fwinfo->TxSubCarrier = priv->nCur40MhzPrimeSC;
3676 }
3677 } else {
3678 tx_fwinfo->TxBandwidth = 0;
3679 tx_fwinfo->TxSubCarrier = 0;
3680 }
3681
3682#ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
3683 if (tcb_desc->drv_agg_enable)
3684 {
3685 tx_fwinfo->Tx_INFO_RSVD = (tcb_desc->DrvAggrNum & 0x1f) << 1;
3686 }
3687#endif
3688 /* Fill Tx descriptor */
3689 memset(tx_desc, 0, sizeof(tx_desc_819x_usb));
3690 /* DWORD 0 */
3691 tx_desc->LINIP = 0;
3692 tx_desc->CmdInit = 1;
3693 tx_desc->Offset = sizeof(tx_fwinfo_819x_usb) + 8;
3694
3695#ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
3696 if (tcb_desc->drv_agg_enable) {
3697 tx_desc->PktSize = tcb_desc->pkt_size;
3698 } else
3699#endif
3700 {
3701 tx_desc->PktSize = (skb->len - TX_PACKET_SHIFT_BYTES) & 0xffff;
3702 }
3703
3704 /*DWORD 1*/
3705 tx_desc->SecCAMID= 0;
3706 tx_desc->RATid = tcb_desc->RATRIndex;
3707#if 0
3708 /* Fill security related */
3709 if( pTcb->bEncrypt && !Adapter->MgntInfo.SecurityInfo.SWTxEncryptFlag)
3710 {
3711 EncAlg = SecGetEncryptionOverhead(
3712 Adapter,
3713 &EncryptionMPDUHeadOverhead,
3714 &EncryptionMPDUTailOverhead,
3715 NULL,
3716 NULL,
3717 FALSE,
3718 FALSE);
3719 //2004/07/22, kcwu, EncryptionMPDUHeadOverhead has been added in previous code
3720 //MPDUOverhead = EncryptionMPDUHeadOverhead + EncryptionMPDUTailOverhead;
3721 MPDUOverhead = EncryptionMPDUTailOverhead;
3722 tx_desc->NoEnc = 0;
3723 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));
3724 //CamDumpAll(Adapter);
3725 }
3726 else
3727#endif
3728 {
3729 //MPDUOverhead = 0;
3730 tx_desc->NoEnc = 1;
3731 }
3732#if 0
3733 switch(EncAlg){
3734 case NO_Encryption:
3735 tx_desc->SecType = 0x0;
3736 break;
3737 case WEP40_Encryption:
3738 case WEP104_Encryption:
3739 tx_desc->SecType = 0x1;
3740 break;
3741 case TKIP_Encryption:
3742 tx_desc->SecType = 0x2;
3743 break;
3744 case AESCCMP_Encryption:
3745 tx_desc->SecType = 0x3;
3746 break;
3747 default:
3748 tx_desc->SecType = 0x0;
3749 break;
3750 }
3751#else
3752 tx_desc->SecType = 0x0;
3753#endif
3754 if (tcb_desc->bHwSec)
3755 {
3756 switch (priv->ieee80211->pairwise_key_type)
3757 {
3758 case KEY_TYPE_WEP40:
3759 case KEY_TYPE_WEP104:
3760 tx_desc->SecType = 0x1;
3761 tx_desc->NoEnc = 0;
3762 break;
3763 case KEY_TYPE_TKIP:
3764 tx_desc->SecType = 0x2;
3765 tx_desc->NoEnc = 0;
3766 break;
3767 case KEY_TYPE_CCMP:
3768 tx_desc->SecType = 0x3;
3769 tx_desc->NoEnc = 0;
3770 break;
3771 case KEY_TYPE_NA:
3772 tx_desc->SecType = 0x0;
3773 tx_desc->NoEnc = 1;
3774 break;
3775 }
3776 }
3777
3778 tx_desc->QueueSelect = MapHwQueueToFirmwareQueue(tcb_desc->queue_index);
3779 tx_desc->TxFWInfoSize = sizeof(tx_fwinfo_819x_usb);
3780
3781 tx_desc->DISFB = tcb_desc->bTxDisableRateFallBack;
3782 tx_desc->USERATE = tcb_desc->bTxUseDriverAssingedRate;
3783
3784 /* Fill fields that are required to be initialized in all of the descriptors */
3785 //DWORD 0
3786#if 0
3787 tx_desc->FirstSeg = (tcb_desc->bFirstSeg)? 1:0;
3788 tx_desc->LastSeg = (tcb_desc->bLastSeg)?1:0;
3789#else
3790 tx_desc->FirstSeg = 1;
3791 tx_desc->LastSeg = 1;
3792#endif
3793 tx_desc->OWN = 1;
3794
3795#ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
3796 if (tcb_desc->drv_agg_enable) {
3797 tx_desc->TxBufferSize = tcb_desc->pkt_size + sizeof(tx_fwinfo_819x_usb);
3798 } else
3799#endif
3800 {
3801 //DWORD 2
3802 tx_desc->TxBufferSize = (u32)(skb->len - USB_HWDESC_HEADER_LEN);
3803 }
3804 /* Get index to out pipe from specified QueueID */
3805#ifndef USE_ONE_PIPE
3806 idx_pipe = txqueue2outpipe(priv,tcb_desc->queue_index);
3807#else
3808 idx_pipe = 0x5;
3809#endif
3810
3811 //RT_DEBUG_DATA(COMP_SEND,tx_fwinfo,sizeof(tx_fwinfo_819x_usb));
3812 //RT_DEBUG_DATA(COMP_SEND,tx_desc,sizeof(tx_desc_819x_usb));
3813
3814 /* To submit bulk urb */
3815 usb_fill_bulk_urb(tx_urb,udev,
3816 usb_sndbulkpipe(udev,idx_pipe), skb->data,
3817 skb->len, rtl8192_tx_isr, skb);
3818
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003819 status = usb_submit_urb(tx_urb, GFP_ATOMIC);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003820 if (!status){
3821//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
3822 bool bSend0Byte = false;
3823 u8 zero = 0;
3824 if(udev->speed == USB_SPEED_HIGH)
3825 {
3826 if (skb->len > 0 && skb->len % 512 == 0)
3827 bSend0Byte = true;
3828 }
3829 else
3830 {
3831 if (skb->len > 0 && skb->len % 64 == 0)
3832 bSend0Byte = true;
3833 }
3834 if (bSend0Byte)
3835 {
3836#if 1
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003837 tx_urb_zero = usb_alloc_urb(0,GFP_ATOMIC);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003838 if(!tx_urb_zero){
3839 RT_TRACE(COMP_ERR, "can't alloc urb for zero byte\n");
3840 return -ENOMEM;
3841 }
3842 usb_fill_bulk_urb(tx_urb_zero,udev,
3843 usb_sndbulkpipe(udev,idx_pipe), &zero,
3844 0, tx_zero_isr, dev);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003845 status = usb_submit_urb(tx_urb_zero, GFP_ATOMIC);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003846 if (status){
3847 RT_TRACE(COMP_ERR, "Error TX URB for zero byte %d, error %d", atomic_read(&priv->tx_pending[tcb_desc->queue_index]), status);
3848 return -1;
3849 }
3850#endif
3851 }
3852 dev->trans_start = jiffies;
3853 atomic_inc(&priv->tx_pending[tcb_desc->queue_index]);
3854 return 0;
3855 }else{
3856 RT_TRACE(COMP_ERR, "Error TX URB %d, error %d", atomic_read(&priv->tx_pending[tcb_desc->queue_index]),
3857 status);
3858 return -1;
3859 }
3860}
3861#endif
3862
3863#if 0
3864void rtl8192_set_rate(struct net_device *dev)
3865{
3866 int i;
3867 u16 word;
3868 int basic_rate,min_rr_rate,max_rr_rate;
3869
3870// struct r8192_priv *priv = ieee80211_priv(dev);
3871
3872 //if (ieee80211_is_54g(priv->ieee80211->current_network) &&
3873// priv->ieee80211->state == IEEE80211_LINKED){
3874 basic_rate = ieeerate2rtlrate(240);
3875 min_rr_rate = ieeerate2rtlrate(60);
3876 max_rr_rate = ieeerate2rtlrate(240);
3877
3878//
3879// }else{
3880// basic_rate = ieeerate2rtlrate(20);
3881// min_rr_rate = ieeerate2rtlrate(10);
3882// max_rr_rate = ieeerate2rtlrate(110);
3883// }
3884
3885 write_nic_byte(dev, RESP_RATE,
3886 max_rr_rate<<MAX_RESP_RATE_SHIFT| min_rr_rate<<MIN_RESP_RATE_SHIFT);
3887
3888 //word = read_nic_word(dev, BRSR);
3889 word = read_nic_word(dev, BRSR_8187);
3890 word &= ~BRSR_MBR_8185;
3891
3892
3893 for(i=0;i<=basic_rate;i++)
3894 word |= (1<<i);
3895
3896 //write_nic_word(dev, BRSR, word);
3897 write_nic_word(dev, BRSR_8187, word);
3898 //DMESG("RR:%x BRSR: %x", read_nic_byte(dev,RESP_RATE), read_nic_word(dev,BRSR));
3899}
3900#endif
3901
3902
3903#ifdef RTL8192SU
3904void rtl8192SU_net_update(struct net_device *dev)
3905{
3906
3907 struct r8192_priv *priv = ieee80211_priv(dev);
3908 struct ieee80211_device* ieee = priv->ieee80211;
3909 struct ieee80211_network *net = &priv->ieee80211->current_network;
3910 //u16 BcnTimeCfg = 0, BcnCW = 6, BcnIFS = 0xf;
3911 u16 rate_config = 0;
3912 u32 regTmp = 0;
3913 u8 rateIndex = 0;
3914 u8 retrylimit = 0x30;
3915 u16 cap = net->capability;
3916
3917 priv->short_preamble = cap & WLAN_CAPABILITY_SHORT_PREAMBLE;
3918
3919//HW_VAR_BASIC_RATE
3920 //update Basic rate: RR, BRSR
3921 rtl8192_config_rate(dev, &rate_config); //HalSetBrateCfg
3922
3923#ifdef RTL8192SU_DISABLE_CCK_RATE
3924 priv->basic_rate = rate_config = rate_config & 0x150; // Disable CCK 11M, 5.5M, 2M, and 1M rates.
3925#else
3926 priv->basic_rate = rate_config = rate_config & 0x15f;
3927#endif
3928
3929 // Set RRSR rate table.
3930 write_nic_byte(dev, RRSR, rate_config&0xff);
3931 write_nic_byte(dev, RRSR+1, (rate_config>>8)&0xff);
3932
3933 // Set RTS initial rate
3934 while(rate_config > 0x1)
3935 {
3936 rate_config = (rate_config>> 1);
3937 rateIndex++;
3938 }
3939 write_nic_byte(dev, INIRTSMCS_SEL, rateIndex);
3940//HW_VAR_BASIC_RATE
3941
3942 //set ack preample
3943 regTmp = (priv->nCur40MhzPrimeSC) << 5;
3944 if (priv->short_preamble)
3945 regTmp |= 0x80;
3946 write_nic_byte(dev, RRSR+2, regTmp);
3947
3948 write_nic_dword(dev,BSSIDR,((u32*)net->bssid)[0]);
3949 write_nic_word(dev,BSSIDR+4,((u16*)net->bssid)[2]);
3950
3951 write_nic_word(dev, BCN_INTERVAL, net->beacon_interval);
3952 //2008.10.24 added by tynli for beacon changed.
3953 PHY_SetBeaconHwReg( dev, net->beacon_interval);
3954
3955 rtl8192_update_cap(dev, cap);
3956
3957 if (ieee->iw_mode == IW_MODE_ADHOC){
3958 retrylimit = 7;
3959 //we should enable ibss interrupt here, but disable it temporarily
3960 if (0){
3961 priv->irq_mask |= (IMR_BcnInt | IMR_BcnInt | IMR_TBDOK | IMR_TBDER);
3962 //rtl8192_irq_disable(dev);
3963 //rtl8192_irq_enable(dev);
3964 }
3965 }
3966 else{
3967 if (0){
3968 priv->irq_mask &= ~(IMR_BcnInt | IMR_BcnInt | IMR_TBDOK | IMR_TBDER);
3969 //rtl8192_irq_disable(dev);
3970 //rtl8192_irq_enable(dev);
3971 }
3972 }
3973
3974 priv->ShortRetryLimit = priv->LongRetryLimit = retrylimit;
3975
3976 write_nic_word(dev, RETRY_LIMIT,
3977 retrylimit << RETRY_LIMIT_SHORT_SHIFT | \
3978 retrylimit << RETRY_LIMIT_LONG_SHIFT);
3979}
3980
3981void rtl8192SU_update_ratr_table(struct net_device* dev)
3982{
3983 struct r8192_priv* priv = ieee80211_priv(dev);
3984 struct ieee80211_device* ieee = priv->ieee80211;
3985 u8* pMcsRate = ieee->dot11HTOperationalRateSet;
3986 //struct ieee80211_network *net = &ieee->current_network;
3987 u32 ratr_value = 0;
3988
3989 u8 rate_index = 0;
3990 int WirelessMode = ieee->mode;
3991 u8 MimoPs = ieee->pHTInfo->PeerMimoPs;
3992
3993 u8 bNMode = 0;
3994
3995 rtl8192_config_rate(dev, (u16*)(&ratr_value));
3996 ratr_value |= (*(u16*)(pMcsRate)) << 12;
3997
3998 //switch (ieee->mode)
3999 switch (WirelessMode)
4000 {
4001 case IEEE_A:
4002 ratr_value &= 0x00000FF0;
4003 break;
4004 case IEEE_B:
4005 ratr_value &= 0x0000000D;
4006 break;
4007 case IEEE_G:
4008 ratr_value &= 0x00000FF5;
4009 break;
4010 case IEEE_N_24G:
4011 case IEEE_N_5G:
4012 {
4013 bNMode = 1;
4014
4015 if (MimoPs == 0) //MIMO_PS_STATIC
4016 {
4017 ratr_value &= 0x0007F005;
4018 }
4019 else
4020 { // MCS rate only => for 11N mode.
4021 u32 ratr_mask;
4022
4023 // 1T2R or 1T1R, Spatial Stream 2 should be disabled
4024 if ( priv->rf_type == RF_1T2R ||
4025 priv->rf_type == RF_1T1R ||
4026 (ieee->pHTInfo->IOTAction & HT_IOT_ACT_DISABLE_TX_2SS) )
4027 ratr_mask = 0x000ff005;
4028 else
4029 ratr_mask = 0x0f0ff005;
4030
4031 if((ieee->pHTInfo->bCurTxBW40MHz) &&
4032 !(ieee->pHTInfo->IOTAction & HT_IOT_ACT_DISABLE_TX_40_MHZ))
4033 ratr_mask |= 0x00000010; // Set 6MBps
4034
4035 // Select rates for rate adaptive mechanism.
4036 ratr_value &= ratr_mask;
4037 }
4038 }
4039 break;
4040 default:
4041 if(0)
4042 {
4043 if(priv->rf_type == RF_1T2R) // 1T2R, Spatial Stream 2 should be disabled
4044 {
4045 ratr_value &= 0x000ff0f5;
4046 }
4047 else
4048 {
4049 ratr_value &= 0x0f0ff0f5;
4050 }
4051 }
4052 //printk("====>%s(), mode is not correct:%x\n", __FUNCTION__, ieee->mode);
4053 break;
4054 }
4055
4056#ifdef RTL8192SU_DISABLE_CCK_RATE
4057 ratr_value &= 0x0FFFFFF0;
4058#else
4059 ratr_value &= 0x0FFFFFFF;
4060#endif
4061
4062 // Get MAX MCS available.
4063 if ( (bNMode && ((ieee->pHTInfo->IOTAction & HT_IOT_ACT_DISABLE_SHORT_GI)==0)) &&
4064 ((ieee->pHTInfo->bCurBW40MHz && ieee->pHTInfo->bCurShortGI40MHz) ||
4065 (!ieee->pHTInfo->bCurBW40MHz && ieee->pHTInfo->bCurShortGI20MHz)))
4066 {
4067 u8 shortGI_rate = 0;
4068 u32 tmp_ratr_value = 0;
4069 ratr_value |= 0x10000000;//???
4070 tmp_ratr_value = (ratr_value>>12);
4071 for(shortGI_rate=15; shortGI_rate>0; shortGI_rate--)
4072 {
4073 if((1<<shortGI_rate) & tmp_ratr_value)
4074 break;
4075 }
4076 shortGI_rate = (shortGI_rate<<12)|(shortGI_rate<<8)|(shortGI_rate<<4)|(shortGI_rate);
4077 write_nic_byte(dev, SG_RATE, shortGI_rate);
4078 //printk("==>SG_RATE:%x\n", read_nic_byte(dev, SG_RATE));
4079 }
4080 write_nic_dword(dev, ARFR0+rate_index*4, ratr_value);
4081 printk("=============>ARFR0+rate_index*4:%#x\n", ratr_value);
4082
4083 //2 UFWP
4084 if (ratr_value & 0xfffff000){
4085 //printk("===>set to N mode\n");
4086 HalSetFwCmd8192S(dev, FW_CMD_RA_REFRESH_N);
4087 }
4088 else {
4089 //printk("===>set to B/G mode\n");
4090 HalSetFwCmd8192S(dev, FW_CMD_RA_REFRESH_BG);
4091 }
4092}
4093
4094void rtl8192SU_link_change(struct net_device *dev)
4095{
4096 struct r8192_priv *priv = ieee80211_priv(dev);
4097 struct ieee80211_device* ieee = priv->ieee80211;
4098 //unsigned long flags;
4099 u32 reg = 0;
4100
4101 printk("=====>%s 1\n", __func__);
4102 reg = read_nic_dword(dev, RCR);
4103
4104 if (ieee->state == IEEE80211_LINKED)
4105 {
4106
4107 rtl8192SU_net_update(dev);
4108 rtl8192SU_update_ratr_table(dev);
4109 ieee->SetFwCmdHandler(dev, FW_CMD_HIGH_PWR_ENABLE);
4110 priv->ReceiveConfig = reg |= RCR_CBSSID;
4111
4112 }else{
4113 priv->ReceiveConfig = reg &= ~RCR_CBSSID;
4114
4115 }
4116
4117 write_nic_dword(dev, RCR, reg);
4118 rtl8192_update_msr(dev);
4119
4120 printk("<=====%s 2\n", __func__);
4121}
4122#else
4123extern void rtl8192_update_ratr_table(struct net_device* dev);
4124void rtl8192_link_change(struct net_device *dev)
4125{
4126// int i;
4127
4128 struct r8192_priv *priv = ieee80211_priv(dev);
4129 struct ieee80211_device* ieee = priv->ieee80211;
4130 //write_nic_word(dev, BCN_INTR_ITV, net->beacon_interval);
4131 if (ieee->state == IEEE80211_LINKED)
4132 {
4133 rtl8192_net_update(dev);
4134 rtl8192_update_ratr_table(dev);
4135#if 1
4136 //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
4137 if ((KEY_TYPE_WEP40 == ieee->pairwise_key_type) || (KEY_TYPE_WEP104 == ieee->pairwise_key_type))
4138 EnableHWSecurityConfig8192(dev);
4139#endif
4140 }
4141 /*update timing params*/
4142// RT_TRACE(COMP_CH, "========>%s(), chan:%d\n", __FUNCTION__, priv->chan);
4143// rtl8192_set_chan(dev, priv->chan);
4144 if (ieee->iw_mode == IW_MODE_INFRA || ieee->iw_mode == IW_MODE_ADHOC)
4145 {
4146 u32 reg = 0;
4147 reg = read_nic_dword(dev, RCR);
4148 if (priv->ieee80211->state == IEEE80211_LINKED)
4149 priv->ReceiveConfig = reg |= RCR_CBSSID;
4150 else
4151 priv->ReceiveConfig = reg &= ~RCR_CBSSID;
4152 write_nic_dword(dev, RCR, reg);
4153 }
4154
4155// rtl8192_set_rxconf(dev);
4156}
4157#endif
4158
4159static struct ieee80211_qos_parameters def_qos_parameters = {
4160 {3,3,3,3},/* cw_min */
4161 {7,7,7,7},/* cw_max */
4162 {2,2,2,2},/* aifs */
4163 {0,0,0,0},/* flags */
4164 {0,0,0,0} /* tx_op_limit */
4165};
4166
4167
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07004168void rtl8192_update_beacon(struct work_struct * work)
4169{
4170 struct r8192_priv *priv = container_of(work, struct r8192_priv, update_beacon_wq.work);
4171 struct net_device *dev = priv->ieee80211->dev;
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07004172 struct ieee80211_device* ieee = priv->ieee80211;
4173 struct ieee80211_network* net = &ieee->current_network;
4174
4175 if (ieee->pHTInfo->bCurrentHTSupport)
4176 HTUpdateSelfAndPeerSetting(ieee, net);
4177 ieee->pHTInfo->bCurrentRT2RTLongSlotTime = net->bssht.bdRT2RTLongSlotTime;
4178 // Joseph test for turbo mode with AP
4179 ieee->pHTInfo->RT2RT_HT_Mode = net->bssht.RT2RT_HT_Mode;
4180 rtl8192_update_cap(dev, net->capability);
4181}
4182/*
4183* background support to run QoS activate functionality
4184*/
4185int WDCAPARA_ADD[] = {EDCAPARA_BE,EDCAPARA_BK,EDCAPARA_VI,EDCAPARA_VO};
Bartlomiej Zolnierkiewicz1ec9e482009-06-13 18:35:04 +02004186
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07004187void rtl8192_qos_activate(struct work_struct * work)
4188{
4189 struct r8192_priv *priv = container_of(work, struct r8192_priv, qos_activate);
4190 struct net_device *dev = priv->ieee80211->dev;
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07004191 struct ieee80211_qos_parameters *qos_parameters = &priv->ieee80211->current_network.qos_data.parameters;
4192 u8 mode = priv->ieee80211->current_network.mode;
4193 //u32 size = sizeof(struct ieee80211_qos_parameters);
4194 u8 u1bAIFS;
4195 u32 u4bAcParam;
4196 int i;
4197
4198 if (priv == NULL)
4199 return;
4200
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07004201 mutex_lock(&priv->mutex);
Bartlomiej Zolnierkiewicz1ec9e482009-06-13 18:35:04 +02004202
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07004203 if(priv->ieee80211->state != IEEE80211_LINKED)
4204 goto success;
4205 RT_TRACE(COMP_QOS,"qos active process with associate response received\n");
4206 /* It better set slot time at first */
4207 /* For we just support b/g mode at present, let the slot time at 9/20 selection */
4208 /* update the ac parameter to related registers */
4209 for(i = 0; i < QOS_QUEUE_NUM; i++) {
4210 //Mode G/A: slotTimeTimer = 9; Mode B: 20
4211 u1bAIFS = qos_parameters->aifs[i] * ((mode&(IEEE_G|IEEE_N_24G)) ?9:20) + aSifsTime;
4212 u4bAcParam = ((((u32)(qos_parameters->tx_op_limit[i]))<< AC_PARAM_TXOP_LIMIT_OFFSET)|
4213 (((u32)(qos_parameters->cw_max[i]))<< AC_PARAM_ECW_MAX_OFFSET)|
4214 (((u32)(qos_parameters->cw_min[i]))<< AC_PARAM_ECW_MIN_OFFSET)|
4215 ((u32)u1bAIFS << AC_PARAM_AIFS_OFFSET));
4216
4217 write_nic_dword(dev, WDCAPARA_ADD[i], u4bAcParam);
4218 //write_nic_dword(dev, WDCAPARA_ADD[i], 0x005e4322);
4219 }
4220
4221success:
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07004222 mutex_unlock(&priv->mutex);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07004223}
4224
4225static int rtl8192_qos_handle_probe_response(struct r8192_priv *priv,
4226 int active_network,
4227 struct ieee80211_network *network)
4228{
4229 int ret = 0;
4230 u32 size = sizeof(struct ieee80211_qos_parameters);
4231
4232 if(priv->ieee80211->state !=IEEE80211_LINKED)
4233 return ret;
4234
4235 if ((priv->ieee80211->iw_mode != IW_MODE_INFRA))
4236 return ret;
4237
4238 if (network->flags & NETWORK_HAS_QOS_MASK) {
4239 if (active_network &&
4240 (network->flags & NETWORK_HAS_QOS_PARAMETERS))
4241 network->qos_data.active = network->qos_data.supported;
4242
4243 if ((network->qos_data.active == 1) && (active_network == 1) &&
4244 (network->flags & NETWORK_HAS_QOS_PARAMETERS) &&
4245 (network->qos_data.old_param_count !=
4246 network->qos_data.param_count)) {
4247 network->qos_data.old_param_count =
4248 network->qos_data.param_count;
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07004249 queue_work(priv->priv_wq, &priv->qos_activate);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07004250 RT_TRACE (COMP_QOS, "QoS parameters change call "
4251 "qos_activate\n");
4252 }
4253 } else {
4254 memcpy(&priv->ieee80211->current_network.qos_data.parameters,\
4255 &def_qos_parameters, size);
4256
4257 if ((network->qos_data.active == 1) && (active_network == 1)) {
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07004258 queue_work(priv->priv_wq, &priv->qos_activate);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07004259 RT_TRACE(COMP_QOS, "QoS was disabled call qos_activate \n");
4260 }
4261 network->qos_data.active = 0;
4262 network->qos_data.supported = 0;
4263 }
4264
4265 return 0;
4266}
4267
4268/* handle manage frame frame beacon and probe response */
4269static int rtl8192_handle_beacon(struct net_device * dev,
4270 struct ieee80211_beacon * beacon,
4271 struct ieee80211_network * network)
4272{
4273 struct r8192_priv *priv = ieee80211_priv(dev);
4274
4275 rtl8192_qos_handle_probe_response(priv,1,network);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07004276 queue_delayed_work(priv->priv_wq, &priv->update_beacon_wq, 0);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07004277
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07004278 return 0;
4279
4280}
4281
4282/*
4283* handling the beaconing responses. if we get different QoS setting
4284* off the network from the associated setting, adjust the QoS
4285* setting
4286*/
4287static int rtl8192_qos_association_resp(struct r8192_priv *priv,
4288 struct ieee80211_network *network)
4289{
4290 int ret = 0;
4291 unsigned long flags;
4292 u32 size = sizeof(struct ieee80211_qos_parameters);
4293 int set_qos_param = 0;
4294
4295 if ((priv == NULL) || (network == NULL))
4296 return ret;
4297
4298 if(priv->ieee80211->state !=IEEE80211_LINKED)
4299 return ret;
4300
4301 if ((priv->ieee80211->iw_mode != IW_MODE_INFRA))
4302 return ret;
4303
4304 spin_lock_irqsave(&priv->ieee80211->lock, flags);
4305 if(network->flags & NETWORK_HAS_QOS_PARAMETERS) {
4306 memcpy(&priv->ieee80211->current_network.qos_data.parameters,\
4307 &network->qos_data.parameters,\
4308 sizeof(struct ieee80211_qos_parameters));
4309 priv->ieee80211->current_network.qos_data.active = 1;
4310#if 0
4311 if((priv->ieee80211->current_network.qos_data.param_count != \
4312 network->qos_data.param_count))
4313#endif
4314 {
4315 set_qos_param = 1;
4316 /* update qos parameter for current network */
4317 priv->ieee80211->current_network.qos_data.old_param_count = \
4318 priv->ieee80211->current_network.qos_data.param_count;
4319 priv->ieee80211->current_network.qos_data.param_count = \
4320 network->qos_data.param_count;
4321 }
4322 } else {
4323 memcpy(&priv->ieee80211->current_network.qos_data.parameters,\
4324 &def_qos_parameters, size);
4325 priv->ieee80211->current_network.qos_data.active = 0;
4326 priv->ieee80211->current_network.qos_data.supported = 0;
4327 set_qos_param = 1;
4328 }
4329
4330 spin_unlock_irqrestore(&priv->ieee80211->lock, flags);
4331
4332 RT_TRACE(COMP_QOS, "%s: network->flags = %d,%d\n",__FUNCTION__,network->flags ,priv->ieee80211->current_network.qos_data.active);
4333 if (set_qos_param == 1)
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07004334 queue_work(priv->priv_wq, &priv->qos_activate);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07004335
4336 return ret;
4337}
4338
4339
4340static int rtl8192_handle_assoc_response(struct net_device *dev,
4341 struct ieee80211_assoc_response_frame *resp,
4342 struct ieee80211_network *network)
4343{
4344 struct r8192_priv *priv = ieee80211_priv(dev);
4345 rtl8192_qos_association_resp(priv, network);
4346 return 0;
4347}
4348
4349
4350void rtl8192_update_ratr_table(struct net_device* dev)
4351 // POCTET_STRING posLegacyRate,
4352 // u8* pMcsRate)
4353 // PRT_WLAN_STA pEntry)
4354{
4355 struct r8192_priv* priv = ieee80211_priv(dev);
4356 struct ieee80211_device* ieee = priv->ieee80211;
4357 u8* pMcsRate = ieee->dot11HTOperationalRateSet;
4358 //struct ieee80211_network *net = &ieee->current_network;
4359 u32 ratr_value = 0;
4360 u8 rate_index = 0;
4361 rtl8192_config_rate(dev, (u16*)(&ratr_value));
4362 ratr_value |= (*(u16*)(pMcsRate)) << 12;
4363// switch (net->mode)
4364 switch (ieee->mode)
4365 {
4366 case IEEE_A:
4367 ratr_value &= 0x00000FF0;
4368 break;
4369 case IEEE_B:
4370 ratr_value &= 0x0000000F;
4371 break;
4372 case IEEE_G:
4373 ratr_value &= 0x00000FF7;
4374 break;
4375 case IEEE_N_24G:
4376 case IEEE_N_5G:
4377 if (ieee->pHTInfo->PeerMimoPs == 0) //MIMO_PS_STATIC
4378 ratr_value &= 0x0007F007;
4379 else{
4380 if (priv->rf_type == RF_1T2R)
4381 ratr_value &= 0x000FF007;
4382 else
4383 ratr_value &= 0x0F81F007;
4384 }
4385 break;
4386 default:
4387 break;
4388 }
4389 ratr_value &= 0x0FFFFFFF;
4390 if(ieee->pHTInfo->bCurTxBW40MHz && ieee->pHTInfo->bCurShortGI40MHz){
4391 ratr_value |= 0x80000000;
4392 }else if(!ieee->pHTInfo->bCurTxBW40MHz && ieee->pHTInfo->bCurShortGI20MHz){
4393 ratr_value |= 0x80000000;
4394 }
4395 write_nic_dword(dev, RATR0+rate_index*4, ratr_value);
4396 write_nic_byte(dev, UFWP, 1);
4397}
4398
4399static u8 ccmp_ie[4] = {0x00,0x50,0xf2,0x04};
4400static u8 ccmp_rsn_ie[4] = {0x00, 0x0f, 0xac, 0x04};
4401bool GetNmodeSupportBySecCfg8192(struct net_device*dev)
4402{
4403#if 1
4404 struct r8192_priv* priv = ieee80211_priv(dev);
4405 struct ieee80211_device* ieee = priv->ieee80211;
4406 struct ieee80211_network * network = &ieee->current_network;
4407 int wpa_ie_len= ieee->wpa_ie_len;
4408 struct ieee80211_crypt_data* crypt;
4409 int encrypt;
4410#if (defined (RTL8192SU_FPGA_2MAC_VERIFICATION)||defined (RTL8192SU_ASIC_VERIFICATION))
4411 return TRUE;
4412#endif
4413
4414 crypt = ieee->crypt[ieee->tx_keyidx];
4415 //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
4416 encrypt = (network->capability & WLAN_CAPABILITY_PRIVACY) || (ieee->host_encrypt && crypt && crypt->ops && (0 == strcmp(crypt->ops->name,"WEP")));
4417
4418 /* simply judge */
4419 if(encrypt && (wpa_ie_len == 0)) {
4420 /* wep encryption, no N mode setting */
4421 return false;
4422// } else if((wpa_ie_len != 0)&&(memcmp(&(ieee->wpa_ie[14]),ccmp_ie,4))) {
4423 } else if((wpa_ie_len != 0)) {
4424 /* parse pairwise key type */
4425 //if((pairwisekey = WEP40)||(pairwisekey = WEP104)||(pairwisekey = TKIP))
4426 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))))
4427 return true;
4428 else
4429 return false;
4430 } else {
4431 return true;
4432 }
4433
4434#if 0
4435 //In here we discuss with SD4 David. He think we still can send TKIP in broadcast group key in MCS rate.
4436 //We can't force in G mode if Pairwie key is AES and group key is TKIP
4437 if((pSecInfo->GroupEncAlgorithm == WEP104_Encryption) || (pSecInfo->GroupEncAlgorithm == WEP40_Encryption) ||
4438 (pSecInfo->PairwiseEncAlgorithm == WEP104_Encryption) ||
4439 (pSecInfo->PairwiseEncAlgorithm == WEP40_Encryption) || (pSecInfo->PairwiseEncAlgorithm == TKIP_Encryption))
4440 {
4441 return false;
4442 }
4443 else
4444 return true;
4445#endif
4446 return true;
4447#endif
4448}
4449
4450bool GetHalfNmodeSupportByAPs819xUsb(struct net_device* dev)
4451{
4452 bool Reval;
4453 struct r8192_priv* priv = ieee80211_priv(dev);
4454 struct ieee80211_device* ieee = priv->ieee80211;
4455
4456// Added by Roger, 2008.08.29.
4457#ifdef RTL8192SU
4458 return false;
4459#endif
4460
4461 if(ieee->bHalfWirelessN24GMode == true)
4462 Reval = true;
4463 else
4464 Reval = false;
4465
4466 return Reval;
4467}
4468
4469void rtl8192_refresh_supportrate(struct r8192_priv* priv)
4470{
4471 struct ieee80211_device* ieee = priv->ieee80211;
4472 //we donot consider set support rate for ABG mode, only HT MCS rate is set here.
4473 if (ieee->mode == WIRELESS_MODE_N_24G || ieee->mode == WIRELESS_MODE_N_5G)
4474 {
4475 memcpy(ieee->Regdot11HTOperationalRateSet, ieee->RegHTSuppRateSet, 16);
4476 //RT_DEBUG_DATA(COMP_INIT, ieee->RegHTSuppRateSet, 16);
4477 //RT_DEBUG_DATA(COMP_INIT, ieee->Regdot11HTOperationalRateSet, 16);
4478 }
4479 else
4480 memset(ieee->Regdot11HTOperationalRateSet, 0, 16);
4481 return;
4482}
4483
4484u8 rtl8192_getSupportedWireleeMode(struct net_device*dev)
4485{
4486 struct r8192_priv *priv = ieee80211_priv(dev);
4487 u8 ret = 0;
4488 switch(priv->rf_chip)
4489 {
4490 case RF_8225:
4491 case RF_8256:
4492 case RF_PSEUDO_11N:
4493 case RF_6052:
4494 ret = (WIRELESS_MODE_N_24G|WIRELESS_MODE_G|WIRELESS_MODE_B);
4495 break;
4496 case RF_8258:
4497 ret = (WIRELESS_MODE_A|WIRELESS_MODE_N_5G);
4498 break;
4499 default:
4500 ret = WIRELESS_MODE_B;
4501 break;
4502 }
4503 return ret;
4504}
4505void rtl8192_SetWirelessMode(struct net_device* dev, u8 wireless_mode)
4506{
4507 struct r8192_priv *priv = ieee80211_priv(dev);
4508 u8 bSupportMode = rtl8192_getSupportedWireleeMode(dev);
4509
4510#if 1
4511 if ((wireless_mode == WIRELESS_MODE_AUTO) || ((wireless_mode&bSupportMode)==0))
4512 {
4513 if(bSupportMode & WIRELESS_MODE_N_24G)
4514 {
4515 wireless_mode = WIRELESS_MODE_N_24G;
4516 }
4517 else if(bSupportMode & WIRELESS_MODE_N_5G)
4518 {
4519 wireless_mode = WIRELESS_MODE_N_5G;
4520 }
4521 else if((bSupportMode & WIRELESS_MODE_A))
4522 {
4523 wireless_mode = WIRELESS_MODE_A;
4524 }
4525 else if((bSupportMode & WIRELESS_MODE_G))
4526 {
4527 wireless_mode = WIRELESS_MODE_G;
4528 }
4529 else if((bSupportMode & WIRELESS_MODE_B))
4530 {
4531 wireless_mode = WIRELESS_MODE_B;
4532 }
4533 else{
4534 RT_TRACE(COMP_ERR, "%s(), No valid wireless mode supported, SupportedWirelessMode(%x)!!!\n", __FUNCTION__,bSupportMode);
4535 wireless_mode = WIRELESS_MODE_B;
4536 }
4537 }
4538#ifdef TO_DO_LIST //// TODO: this function doesn't work well at this time, we shoud wait for FPGA
4539 ActUpdateChannelAccessSetting( pAdapter, pHalData->CurrentWirelessMode, &pAdapter->MgntInfo.Info8185.ChannelAccessSetting );
4540#endif
4541#ifdef RTL8192SU
4542 //LZM 090306 usb crash here, mark it temp
4543 //write_nic_word(dev, SIFS_OFDM, 0x0e0e);
4544#endif
4545 priv->ieee80211->mode = wireless_mode;
4546
4547 if ((wireless_mode == WIRELESS_MODE_N_24G) || (wireless_mode == WIRELESS_MODE_N_5G))
4548 priv->ieee80211->pHTInfo->bEnableHT = 1;
4549 else
4550 priv->ieee80211->pHTInfo->bEnableHT = 0;
4551 RT_TRACE(COMP_INIT, "Current Wireless Mode is %x\n", wireless_mode);
4552 rtl8192_refresh_supportrate(priv);
4553#endif
4554
4555}
4556
4557
4558short rtl8192_is_tx_queue_empty(struct net_device *dev)
4559{
4560 int i=0;
4561 struct r8192_priv *priv = ieee80211_priv(dev);
4562 //struct ieee80211_device* ieee = priv->ieee80211;
4563 for (i=0; i<=MGNT_QUEUE; i++)
4564 {
4565 if ((i== TXCMD_QUEUE) || (i == HCCA_QUEUE) )
4566 continue;
4567 if (atomic_read(&priv->tx_pending[i]))
4568 {
4569 printk("===>tx queue is not empty:%d, %d\n", i, atomic_read(&priv->tx_pending[i]));
4570 return 0;
4571 }
4572 }
4573 return 1;
4574}
4575#if 0
4576void rtl8192_rq_tx_ack(struct net_device *dev)
4577{
4578 struct r8192_priv *priv = ieee80211_priv(dev);
4579 priv->ieee80211->ack_tx_to_ieee = 1;
4580}
4581#endif
4582void rtl8192_hw_sleep_down(struct net_device *dev)
4583{
4584 RT_TRACE(COMP_POWER, "%s()============>come to sleep down\n", __FUNCTION__);
4585#ifdef TODO
4586// MgntActSet_RF_State(dev, eRfSleep, RF_CHANGE_BY_PS);
4587#endif
4588}
Bartlomiej Zolnierkiewicz1ec9e482009-06-13 18:35:04 +02004589
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07004590void rtl8192_hw_sleep_wq (struct work_struct *work)
4591{
4592// struct r8180_priv *priv = container_of(work, struct r8180_priv, watch_dog_wq);
4593// struct ieee80211_device * ieee = (struct ieee80211_device*)
4594// container_of(work, struct ieee80211_device, watch_dog_wq);
4595 struct delayed_work *dwork = container_of(work,struct delayed_work,work);
4596 struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,hw_sleep_wq);
4597 struct net_device *dev = ieee->dev;
Bartlomiej Zolnierkiewicz1ec9e482009-06-13 18:35:04 +02004598
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07004599 //printk("=========>%s()\n", __FUNCTION__);
4600 rtl8192_hw_sleep_down(dev);
4601}
4602// printk("dev is %d\n",dev);
4603// printk("&*&(^*(&(&=========>%s()\n", __FUNCTION__);
4604void rtl8192_hw_wakeup(struct net_device* dev)
4605{
4606// u32 flags = 0;
4607
4608// spin_lock_irqsave(&priv->ps_lock,flags);
4609 RT_TRACE(COMP_POWER, "%s()============>come to wake up\n", __FUNCTION__);
4610#ifdef TODO
4611// MgntActSet_RF_State(dev, eRfSleep, RF_CHANGE_BY_PS);
4612#endif
4613 //FIXME: will we send package stored while nic is sleep?
4614// spin_unlock_irqrestore(&priv->ps_lock,flags);
4615}
Bartlomiej Zolnierkiewicz1ec9e482009-06-13 18:35:04 +02004616
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07004617void rtl8192_hw_wakeup_wq (struct work_struct *work)
4618{
4619// struct r8180_priv *priv = container_of(work, struct r8180_priv, watch_dog_wq);
4620// struct ieee80211_device * ieee = (struct ieee80211_device*)
4621// container_of(work, struct ieee80211_device, watch_dog_wq);
4622 struct delayed_work *dwork = container_of(work,struct delayed_work,work);
4623 struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,hw_wakeup_wq);
4624 struct net_device *dev = ieee->dev;
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07004625
Bartlomiej Zolnierkiewicz1ec9e482009-06-13 18:35:04 +02004626 rtl8192_hw_wakeup(dev);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07004627}
4628
4629#define MIN_SLEEP_TIME 50
4630#define MAX_SLEEP_TIME 10000
4631void rtl8192_hw_to_sleep(struct net_device *dev, u32 th, u32 tl)
4632{
4633
4634 struct r8192_priv *priv = ieee80211_priv(dev);
4635
4636 u32 rb = jiffies;
4637 unsigned long flags;
4638
4639 spin_lock_irqsave(&priv->ps_lock,flags);
4640
4641 /* Writing HW register with 0 equals to disable
4642 * the timer, that is not really what we want
4643 */
4644 tl -= MSECS(4+16+7);
4645
4646 //if(tl == 0) tl = 1;
4647
4648 /* FIXME HACK FIXME HACK */
4649// force_pci_posting(dev);
4650 //mdelay(1);
4651
4652// rb = read_nic_dword(dev, TSFTR);
4653
4654 /* If the interval in witch we are requested to sleep is too
4655 * short then give up and remain awake
4656 */
4657 if(((tl>=rb)&& (tl-rb) <= MSECS(MIN_SLEEP_TIME))
4658 ||((rb>tl)&& (rb-tl) < MSECS(MIN_SLEEP_TIME))) {
4659 spin_unlock_irqrestore(&priv->ps_lock,flags);
4660 printk("too short to sleep\n");
4661 return;
4662 }
4663
4664// write_nic_dword(dev, TimerInt, tl);
4665// rb = read_nic_dword(dev, TSFTR);
4666 {
4667 u32 tmp = (tl>rb)?(tl-rb):(rb-tl);
4668 // if (tl<rb)
4669
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07004670 queue_delayed_work(priv->ieee80211->wq, &priv->ieee80211->hw_wakeup_wq, tmp); //as tl may be less than rb
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07004671 }
4672 /* if we suspect the TimerInt is gone beyond tl
4673 * while setting it, then give up
4674 */
4675#if 1
4676 if(((tl > rb) && ((tl-rb) > MSECS(MAX_SLEEP_TIME)))||
4677 ((tl < rb) && ((rb-tl) > MSECS(MAX_SLEEP_TIME)))) {
4678 printk("========>too long to sleep:%x, %x, %lx\n", tl, rb, MSECS(MAX_SLEEP_TIME));
4679 spin_unlock_irqrestore(&priv->ps_lock,flags);
4680 return;
4681 }
4682#endif
4683// if(priv->rf_sleep)
4684// priv->rf_sleep(dev);
4685
4686 //printk("<=========%s()\n", __FUNCTION__);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07004687 queue_delayed_work(priv->ieee80211->wq, (void *)&priv->ieee80211->hw_sleep_wq,0);
Bartlomiej Zolnierkiewicz1ec9e482009-06-13 18:35:04 +02004688
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07004689 spin_unlock_irqrestore(&priv->ps_lock,flags);
4690}
4691//init priv variables here. only non_zero value should be initialized here.
4692static void rtl8192_init_priv_variable(struct net_device* dev)
4693{
4694 struct r8192_priv *priv = ieee80211_priv(dev);
4695 u8 i;
4696 priv->card_8192 = NIC_8192U;
4697 priv->chan = 1; //set to channel 1
4698 priv->ieee80211->mode = WIRELESS_MODE_AUTO; //SET AUTO
4699 priv->ieee80211->iw_mode = IW_MODE_INFRA;
4700 priv->ieee80211->ieee_up=0;
4701 priv->retry_rts = DEFAULT_RETRY_RTS;
4702 priv->retry_data = DEFAULT_RETRY_DATA;
4703 priv->ieee80211->rts = DEFAULT_RTS_THRESHOLD;
4704 priv->ieee80211->rate = 110; //11 mbps
4705 priv->ieee80211->short_slot = 1;
4706 priv->promisc = (dev->flags & IFF_PROMISC) ? 1:0;
4707 priv->CckPwEnl = 6;
4708 //for silent reset
4709 priv->IrpPendingCount = 1;
4710 priv->ResetProgress = RESET_TYPE_NORESET;
4711 priv->bForcedSilentReset = 0;
4712 priv->bDisableNormalResetCheck = false;
4713 priv->force_reset = false;
4714
4715 priv->ieee80211->FwRWRF = 0; //we don't use FW read/write RF until stable firmware is available.
4716 priv->ieee80211->current_network.beacon_interval = DEFAULT_BEACONINTERVAL;
4717 priv->ieee80211->iw_mode = IW_MODE_INFRA;
4718 priv->ieee80211->softmac_features = IEEE_SOFTMAC_SCAN |
4719 IEEE_SOFTMAC_ASSOCIATE | IEEE_SOFTMAC_PROBERQ |
4720 IEEE_SOFTMAC_PROBERS | IEEE_SOFTMAC_TX_QUEUE |
4721 IEEE_SOFTMAC_BEACONS;//added by amy 080604 //| //IEEE_SOFTMAC_SINGLE_QUEUE;
4722
4723 priv->ieee80211->active_scan = 1;
4724 priv->ieee80211->modulation = IEEE80211_CCK_MODULATION | IEEE80211_OFDM_MODULATION;
4725 priv->ieee80211->host_encrypt = 1;
4726 priv->ieee80211->host_decrypt = 1;
4727 priv->ieee80211->start_send_beacons = NULL;//rtl819xusb_beacon_tx;//-by amy 080604
4728 priv->ieee80211->stop_send_beacons = NULL;//rtl8192_beacon_stop;//-by amy 080604
4729 priv->ieee80211->softmac_hard_start_xmit = rtl8192_hard_start_xmit;
4730 priv->ieee80211->set_chan = rtl8192_set_chan;
4731 priv->ieee80211->link_change = priv->ops->rtl819x_link_change;
4732 priv->ieee80211->softmac_data_hard_start_xmit = rtl8192_hard_data_xmit;
4733 priv->ieee80211->data_hard_stop = rtl8192_data_hard_stop;
4734 priv->ieee80211->data_hard_resume = rtl8192_data_hard_resume;
4735 priv->ieee80211->init_wmmparam_flag = 0;
4736 priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD;
4737 priv->ieee80211->check_nic_enough_desc = check_nic_enough_desc;
4738 priv->ieee80211->tx_headroom = TX_PACKET_SHIFT_BYTES;
4739 priv->ieee80211->qos_support = 1;
4740
4741 //added by WB
4742// priv->ieee80211->SwChnlByTimerHandler = rtl8192_phy_SwChnl;
4743 priv->ieee80211->SetBWModeHandler = rtl8192_SetBWMode;
4744 priv->ieee80211->handle_assoc_response = rtl8192_handle_assoc_response;
4745 priv->ieee80211->handle_beacon = rtl8192_handle_beacon;
4746 //for LPS
4747 priv->ieee80211->sta_wake_up = rtl8192_hw_wakeup;
4748// priv->ieee80211->ps_request_tx_ack = rtl8192_rq_tx_ack;
4749 priv->ieee80211->enter_sleep_state = rtl8192_hw_to_sleep;
4750 priv->ieee80211->ps_is_queue_empty = rtl8192_is_tx_queue_empty;
4751 //added by david
4752 priv->ieee80211->GetNmodeSupportBySecCfg = GetNmodeSupportBySecCfg8192;
4753 priv->ieee80211->GetHalfNmodeSupportByAPsHandler = GetHalfNmodeSupportByAPs819xUsb;
4754 priv->ieee80211->SetWirelessMode = rtl8192_SetWirelessMode;
4755 //added by amy
4756 priv->ieee80211->InitialGainHandler = priv->ops->rtl819x_initial_gain;
4757 priv->card_type = USB;
4758
4759#ifdef RTL8192SU
4760//1 RTL8192SU/
4761 priv->ieee80211->current_network.beacon_interval = DEFAULT_BEACONINTERVAL;
4762 priv->ieee80211->SetFwCmdHandler = HalSetFwCmd8192S;
4763 priv->bRFSiOrPi = 0;//o=si,1=pi;
4764 //lzm add
4765 priv->bInHctTest = false;
4766
4767 priv->MidHighPwrTHR_L1 = 0x3B;
4768 priv->MidHighPwrTHR_L2 = 0x40;
4769
4770 if(priv->bInHctTest)
4771 {
4772 priv->ShortRetryLimit = HAL_RETRY_LIMIT_AP_ADHOC;
4773 priv->LongRetryLimit = HAL_RETRY_LIMIT_AP_ADHOC;
4774 }
4775 else
4776 {
4777 priv->ShortRetryLimit = HAL_RETRY_LIMIT_INFRA;
4778 priv->LongRetryLimit = HAL_RETRY_LIMIT_INFRA;
4779 }
4780
4781 priv->SetFwCmdInProgress = false; //is set FW CMD in Progress? 92S only
4782 priv->CurrentFwCmdIO = 0;
4783
4784 priv->MinSpaceCfg = 0;
4785
4786 priv->EarlyRxThreshold = 7;
4787 priv->enable_gpio0 = 0;
4788 priv->TransmitConfig =
4789 ((u32)TCR_MXDMA_2048<<TCR_MXDMA_OFFSET) | // Max DMA Burst Size per Tx DMA Burst, 7: reservied.
4790 (priv->ShortRetryLimit<<TCR_SRL_OFFSET) | // Short retry limit
4791 (priv->LongRetryLimit<<TCR_LRL_OFFSET) | // Long retry limit
4792 (false ? TCR_SAT : 0); // FALSE: HW provies PLCP length and LENGEXT, TURE: SW proiveds them
4793 if(priv->bInHctTest)
4794 priv->ReceiveConfig = //priv->CSMethod |
4795 RCR_AMF | RCR_ADF | //RCR_AAP | //accept management/data
4796 RCR_ACF |RCR_APPFCS| //accept control frame for SW AP needs PS-poll, 2005.07.07, by rcnjko.
4797 RCR_AB | RCR_AM | RCR_APM | //accept BC/MC/UC
4798 RCR_AICV | RCR_ACRC32 | //accept ICV/CRC error packet
4799 RCR_APP_PHYST_STAFF | RCR_APP_PHYST_RXFF | // Accept PHY status
4800 ((u32)7<<RCR_MXDMA_OFFSET) | // Max DMA Burst Size per Rx DMA Burst, 7: unlimited.
4801 (priv->EarlyRxThreshold<<RCR_FIFO_OFFSET) | // Rx FIFO Threshold, 7: No Rx threshold.
4802 (priv->EarlyRxThreshold == 7 ? RCR_OnlyErlPkt:0);
4803 else
4804 priv->ReceiveConfig = //priv->CSMethod |
4805 RCR_AMF | RCR_ADF | RCR_AB |
4806 RCR_AM | RCR_APM |RCR_AAP |RCR_ADD3|RCR_APP_ICV|
4807 RCR_APP_PHYST_STAFF | RCR_APP_PHYST_RXFF | // Accept PHY status
4808 RCR_APP_MIC | RCR_APPFCS;
4809
4810 // <Roger_EXP> 2008.06.16.
4811 priv->IntrMask = (u16)(IMR_ROK | IMR_VODOK | IMR_VIDOK | IMR_BEDOK | IMR_BKDOK | \
4812 IMR_HCCADOK | IMR_MGNTDOK | IMR_COMDOK | IMR_HIGHDOK | \
4813 IMR_BDOK | IMR_RXCMDOK | /*IMR_TIMEOUT0 |*/ IMR_RDU | IMR_RXFOVW | \
4814 IMR_TXFOVW | IMR_BcnInt | IMR_TBDOK | IMR_TBDER);
4815
4816//1 End
4817
4818#else
4819
4820#ifdef TO_DO_LIST
4821 if(Adapter->bInHctTest)
4822 {
4823 pHalData->ShortRetryLimit = 7;
4824 pHalData->LongRetryLimit = 7;
4825 }
4826#endif
4827 {
4828 priv->ShortRetryLimit = 0x30;
4829 priv->LongRetryLimit = 0x30;
4830 }
4831 priv->EarlyRxThreshold = 7;
4832 priv->enable_gpio0 = 0;
4833 priv->TransmitConfig =
4834 // TCR_DurProcMode | //for RTL8185B, duration setting by HW
4835 //? TCR_DISReqQsize |
4836 (TCR_MXDMA_2048<<TCR_MXDMA_OFFSET)| // Max DMA Burst Size per Tx DMA Burst, 7: reservied.
4837 (priv->ShortRetryLimit<<TCR_SRL_OFFSET)| // Short retry limit
4838 (priv->LongRetryLimit<<TCR_LRL_OFFSET) | // Long retry limit
4839 (false ? TCR_SAT: 0); // FALSE: HW provies PLCP length and LENGEXT, TURE: SW proiveds them
4840#ifdef TO_DO_LIST
4841 if(Adapter->bInHctTest)
4842 pHalData->ReceiveConfig = pHalData->CSMethod |
4843 RCR_AMF | RCR_ADF | //RCR_AAP | //accept management/data
4844 //guangan200710
4845 RCR_ACF | //accept control frame for SW AP needs PS-poll, 2005.07.07, by rcnjko.
4846 RCR_AB | RCR_AM | RCR_APM | //accept BC/MC/UC
4847 RCR_AICV | RCR_ACRC32 | //accept ICV/CRC error packet
4848 ((u32)7<<RCR_MXDMA_OFFSET) | // Max DMA Burst Size per Rx DMA Burst, 7: unlimited.
4849 (pHalData->EarlyRxThreshold<<RCR_FIFO_OFFSET) | // Rx FIFO Threshold, 7: No Rx threshold.
4850 (pHalData->EarlyRxThreshold == 7 ? RCR_OnlyErlPkt:0);
4851 else
4852
4853#endif
4854 priv->ReceiveConfig =
4855 RCR_AMF | RCR_ADF | //accept management/data
4856 RCR_ACF | //accept control frame for SW AP needs PS-poll, 2005.07.07, by rcnjko.
4857 RCR_AB | RCR_AM | RCR_APM | //accept BC/MC/UC
4858 //RCR_AICV | RCR_ACRC32 | //accept ICV/CRC error packet
4859 ((u32)7<<RCR_MXDMA_OFFSET)| // Max DMA Burst Size per Rx DMA Burst, 7: unlimited.
4860 (priv->EarlyRxThreshold<<RX_FIFO_THRESHOLD_SHIFT) | // Rx FIFO Threshold, 7: No Rx threshold.
4861 (priv->EarlyRxThreshold == 7 ? RCR_ONLYERLPKT:0);
4862#endif
4863
4864 priv->AcmControl = 0;
4865 priv->pFirmware = (rt_firmware*)vmalloc(sizeof(rt_firmware));
4866 if (priv->pFirmware)
4867 memset(priv->pFirmware, 0, sizeof(rt_firmware));
4868
4869 /* rx related queue */
4870 skb_queue_head_init(&priv->rx_queue);
4871 skb_queue_head_init(&priv->skb_queue);
4872
4873 /* Tx related queue */
4874 for(i = 0; i < MAX_QUEUE_SIZE; i++) {
4875 skb_queue_head_init(&priv->ieee80211->skb_waitQ [i]);
4876 }
4877 for(i = 0; i < MAX_QUEUE_SIZE; i++) {
4878 skb_queue_head_init(&priv->ieee80211->skb_aggQ [i]);
4879 }
4880 for(i = 0; i < MAX_QUEUE_SIZE; i++) {
4881 skb_queue_head_init(&priv->ieee80211->skb_drv_aggQ [i]);
4882 }
4883 priv->rf_set_chan = rtl8192_phy_SwChnl;
4884}
4885
4886//init lock here
4887static void rtl8192_init_priv_lock(struct r8192_priv* priv)
4888{
4889 spin_lock_init(&priv->tx_lock);
4890 spin_lock_init(&priv->irq_lock);//added by thomas
4891 //spin_lock_init(&priv->rf_lock);//use rf_sem, or will crash in some OS.
4892 sema_init(&priv->wx_sem,1);
4893 sema_init(&priv->rf_sem,1);
4894 spin_lock_init(&priv->ps_lock);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07004895 mutex_init(&priv->mutex);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07004896}
4897
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07004898extern void rtl819x_watchdog_wqcallback(struct work_struct *work);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07004899
4900void rtl8192_irq_rx_tasklet(struct r8192_priv *priv);
4901//init tasklet and wait_queue here. only 2.6 above kernel is considered
4902#define DRV_NAME "wlan0"
4903static void rtl8192_init_priv_task(struct net_device* dev)
4904{
4905 struct r8192_priv *priv = ieee80211_priv(dev);
4906
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07004907#ifdef PF_SYNCTHREAD
4908 priv->priv_wq = create_workqueue(DRV_NAME,0);
4909#else
4910 priv->priv_wq = create_workqueue(DRV_NAME);
4911#endif
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07004912
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07004913 INIT_WORK(&priv->reset_wq, rtl8192_restart);
4914
4915 //INIT_DELAYED_WORK(&priv->watch_dog_wq, hal_dm_watchdog);
4916 INIT_DELAYED_WORK(&priv->watch_dog_wq, rtl819x_watchdog_wqcallback);
4917 INIT_DELAYED_WORK(&priv->txpower_tracking_wq, dm_txpower_trackingcallback);
4918// INIT_DELAYED_WORK(&priv->gpio_change_rf_wq, dm_gpio_change_rf_callback);
4919 INIT_DELAYED_WORK(&priv->rfpath_check_wq, dm_rf_pathcheck_workitemcallback);
4920 INIT_DELAYED_WORK(&priv->update_beacon_wq, rtl8192_update_beacon);
4921 INIT_DELAYED_WORK(&priv->initialgain_operate_wq, InitialGainOperateWorkItemCallBack);
4922 //INIT_WORK(&priv->SwChnlWorkItem, rtl8192_SwChnl_WorkItem);
4923 //INIT_WORK(&priv->SetBWModeWorkItem, rtl8192_SetBWModeWorkItem);
4924 INIT_WORK(&priv->qos_activate, rtl8192_qos_activate);
4925 INIT_DELAYED_WORK(&priv->ieee80211->hw_wakeup_wq,(void*) rtl8192_hw_wakeup_wq);
4926 INIT_DELAYED_WORK(&priv->ieee80211->hw_sleep_wq,(void*) rtl8192_hw_sleep_wq);
4927
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07004928 tasklet_init(&priv->irq_rx_tasklet,
4929 (void(*)(unsigned long))rtl8192_irq_rx_tasklet,
4930 (unsigned long)priv);
4931}
4932
4933static void rtl8192_get_eeprom_size(struct net_device* dev)
4934{
4935 u16 curCR = 0;
4936 struct r8192_priv *priv = ieee80211_priv(dev);
4937 RT_TRACE(COMP_EPROM, "===========>%s()\n", __FUNCTION__);
4938 curCR = read_nic_word_E(dev,EPROM_CMD);
4939 RT_TRACE(COMP_EPROM, "read from Reg EPROM_CMD(%x):%x\n", EPROM_CMD, curCR);
4940 //whether need I consider BIT5?
4941 priv->epromtype = (curCR & Cmd9346CR_9356SEL) ? EPROM_93c56 : EPROM_93c46;
4942 RT_TRACE(COMP_EPROM, "<===========%s(), epromtype:%d\n", __FUNCTION__, priv->epromtype);
4943}
4944
4945//used to swap endian. as ntohl & htonl are not neccessary to swap endian, so use this instead.
4946static inline u16 endian_swap(u16* data)
4947{
4948 u16 tmp = *data;
4949 *data = (tmp >> 8) | (tmp << 8);
4950 return *data;
4951}
4952
4953#ifdef RTL8192SU
4954u8 rtl8192SU_UsbOptionToEndPointNumber(u8 UsbOption)
4955{
4956 u8 nEndPoint = 0;
4957 switch(UsbOption)
4958 {
4959 case 0:
4960 nEndPoint = 6;
4961 break;
4962 case 1:
4963 nEndPoint = 11;
4964 break;
4965 case 2:
4966 nEndPoint = 4;
4967 break;
4968 default:
4969 RT_TRACE(COMP_INIT, "UsbOptionToEndPointNumber(): Invalid UsbOption(%#x)\n", UsbOption);
4970 break;
4971 }
4972 return nEndPoint;
4973}
4974
4975u8 rtl8192SU_BoardTypeToRFtype(struct net_device* dev, u8 Boardtype)
4976{
4977 u8 RFtype = RF_1T2R;
4978
4979 switch(Boardtype)
4980 {
4981 case 0:
4982 RFtype = RF_1T1R;
4983 break;
4984 case 1:
4985 RFtype = RF_1T2R;
4986 break;
4987 case 2:
4988 RFtype = RF_2T2R;
4989 break;
4990 case 3:
4991 RFtype = RF_2T2R_GREEN;
4992 break;
4993 default:
4994 break;
4995 }
4996
4997 return RFtype;
4998}
4999
5000//
5001// Description:
5002// Config HW adapter information into initial value.
5003//
5004// Assumption:
5005// 1. After Auto load fail(i.e, check CR9346 fail)
5006//
5007// Created by Roger, 2008.10.21.
5008//
5009void
5010rtl8192SU_ConfigAdapterInfo8192SForAutoLoadFail(struct net_device* dev)
5011{
5012 struct r8192_priv *priv = ieee80211_priv(dev);
5013 //u16 i,usValue;
5014 //u8 sMacAddr[6] = {0x00, 0xE0, 0x4C, 0x81, 0x92, 0x00};
5015 u8 rf_path, index; // For EEPROM/EFUSE After V0.6_1117
5016 int i;
5017
5018 RT_TRACE(COMP_INIT, "====> ConfigAdapterInfo8192SForAutoLoadFail\n");
5019
5020 write_nic_byte(dev, SYS_ISO_CTRL+1, 0xE8); // Isolation signals from Loader
5021 //PlatformStallExecution(10000);
5022 mdelay(10);
5023 write_nic_byte(dev, PMC_FSM, 0x02); // Enable Loader Data Keep
5024
5025 //RT_ASSERT(priv->AutoloadFailFlag==TRUE, ("ReadAdapterInfo8192SEEPROM(): AutoloadFailFlag !=TRUE\n"));
5026
5027 // Initialize IC Version && Channel Plan
5028 priv->eeprom_vid = 0;
5029 priv->eeprom_pid = 0;
5030 priv->card_8192_version = 0;
5031 priv->eeprom_ChannelPlan = 0;
5032 priv->eeprom_CustomerID = 0;
5033 priv->eeprom_SubCustomerID = 0;
5034 priv->bIgnoreDiffRateTxPowerOffset = false;
5035
5036 RT_TRACE(COMP_INIT, "EEPROM VID = 0x%4x\n", priv->eeprom_vid);
5037 RT_TRACE(COMP_INIT, "EEPROM PID = 0x%4x\n", priv->eeprom_pid);
5038 RT_TRACE(COMP_INIT, "EEPROM Customer ID: 0x%2x\n", priv->eeprom_CustomerID);
5039 RT_TRACE(COMP_INIT, "EEPROM SubCustomer ID: 0x%2x\n", priv->eeprom_SubCustomerID);
5040 RT_TRACE(COMP_INIT, "EEPROM ChannelPlan = 0x%4x\n", priv->eeprom_ChannelPlan);
5041 RT_TRACE(COMP_INIT, "IgnoreDiffRateTxPowerOffset = %d\n", priv->bIgnoreDiffRateTxPowerOffset);
5042
5043
5044
5045 priv->EEPROMUsbOption = EEPROM_USB_Default_OPTIONAL_FUNC;
5046 RT_TRACE(COMP_INIT, "USB Option = %#x\n", priv->EEPROMUsbOption);
5047
5048 for(i=0; i<5; i++)
5049 priv->EEPROMUsbPhyParam[i] = EEPROM_USB_Default_PHY_PARAM;
5050
5051 //RT_PRINT_DATA(COMP_INIT|COMP_EFUSE, DBG_LOUD, ("EFUSE USB PHY Param: \n"), priv->EEPROMUsbPhyParam, 5);
5052
5053 {
5054 //<Roger_Notes> In this case, we random assigh MAC address here. 2008.10.15.
5055 static u8 sMacAddr[6] = {0x00, 0xE0, 0x4C, 0x81, 0x92, 0x00};
5056 u8 i;
5057
5058 //sMacAddr[5] = (u8)GetRandomNumber(1, 254);
5059
5060 for(i = 0; i < 6; i++)
5061 dev->dev_addr[i] = sMacAddr[i];
5062 }
5063 //NicIFSetMacAddress(Adapter, Adapter->PermanentAddress);
5064 write_nic_dword(dev, IDR0, ((u32*)dev->dev_addr)[0]);
5065 write_nic_word(dev, IDR4, ((u16*)(dev->dev_addr + 4))[0]);
5066
5067 RT_TRACE(COMP_INIT, "ReadAdapterInfo8192SEFuse(), Permanent Address = %02x-%02x-%02x-%02x-%02x-%02x\n",
5068 dev->dev_addr[0], dev->dev_addr[1],
5069 dev->dev_addr[2], dev->dev_addr[3],
5070 dev->dev_addr[4], dev->dev_addr[5]);
5071
5072 priv->EEPROMBoardType = EEPROM_Default_BoardType;
5073 priv->rf_type = RF_1T2R; //RF_2T2R
5074 priv->EEPROMTxPowerDiff = EEPROM_Default_PwDiff;
5075 priv->EEPROMThermalMeter = EEPROM_Default_ThermalMeter;
5076 priv->EEPROMCrystalCap = EEPROM_Default_CrystalCap;
5077 priv->EEPROMTxPwrBase = EEPROM_Default_TxPowerBase;
5078 priv->EEPROMTSSI_A = EEPROM_Default_TSSI;
5079 priv->EEPROMTSSI_B = EEPROM_Default_TSSI;
5080 priv->EEPROMTxPwrTkMode = EEPROM_Default_TxPwrTkMode;
5081
5082
5083#ifdef EEPROM_OLD_FORMAT_SUPPORT
5084 for(i=0; i<6; i++)
5085 {
5086 priv->EEPROMHT2T_TxPwr[i] = EEPROM_Default_HT2T_TxPwr;
5087 }
5088
5089 for(i=0; i<14; i++)
5090 {
5091 priv->EEPROMTxPowerLevelCCK24G[i] = (u8)(EEPROM_Default_TxPower & 0xff);
5092 priv->EEPROMTxPowerLevelOFDM24G[i] = (u8)(EEPROM_Default_TxPower & 0xff);
5093 }
5094
5095 //
5096 // Update HAL variables.
5097 //
5098 memcpy( priv->TxPowerLevelOFDM24G, priv->EEPROMTxPowerLevelOFDM24G, 14);
5099 memcpy( priv->TxPowerLevelCCK, priv->EEPROMTxPowerLevelCCK24G, 14);
5100 //RT_PRINT_DATA(COMP_INIT|COMP_EFUSE, DBG_LOUD, ("HAL CCK 2.4G TxPwr: \n"), priv->TxPowerLevelCCK, 14);
5101 //RT_PRINT_DATA(COMP_INIT|COMP_EFUSE, DBG_LOUD, ("HAL OFDM 2.4G TxPwr: \n"), priv->TxPowerLevelOFDM24G, 14);
5102#else
5103
5104 for (rf_path = 0; rf_path < 2; rf_path++)
5105 {
5106 for (i = 0; i < 3; i++)
5107 {
5108 // Read CCK RF A & B Tx power
5109 priv->RfCckChnlAreaTxPwr[rf_path][i] =
5110 priv->RfOfdmChnlAreaTxPwr1T[rf_path][i] =
5111 priv->RfOfdmChnlAreaTxPwr2T[rf_path][i] =
5112 (u8)(EEPROM_Default_TxPower & 0xff);
5113 }
5114 }
5115
5116 for (i = 0; i < 3; i++)
5117 {
5118 //RT_TRACE((COMP_EFUSE), "CCK RF-%d CHan_Area-%d = 0x%x\n", rf_path, i,
5119 //priv->RfCckChnlAreaTxPwr[rf_path][i]);
5120 //RT_TRACE((COMP_EFUSE), "OFDM-1T RF-%d CHan_Area-%d = 0x%x\n", rf_path, i,
5121 //priv->RfOfdmChnlAreaTxPwr1T[rf_path][i]);
5122 //RT_TRACE((COMP_EFUSE), "OFDM-2T RF-%d CHan_Area-%d = 0x%x\n", rf_path, i,
5123 //priv->RfOfdmChnlAreaTxPwr2T[rf_path][i]);
5124 }
5125
5126 // Assign dedicated channel tx power
5127 for(i=0; i<14; i++) // channel 1~3 use the same Tx Power Level.
5128 {
5129 if (i < 3) // Cjanel 1-3
5130 index = 0;
5131 else if (i < 9) // Channel 4-9
5132 index = 1;
5133 else // Channel 10-14
5134 index = 2;
5135
5136 // Record A & B CCK /OFDM - 1T/2T Channel area tx power
5137 priv->RfTxPwrLevelCck[rf_path][i] =
5138 priv->RfCckChnlAreaTxPwr[rf_path][index];
5139 priv->RfTxPwrLevelOfdm1T[rf_path][i] =
5140 priv->RfOfdmChnlAreaTxPwr1T[rf_path][index];
5141 priv->RfTxPwrLevelOfdm2T[rf_path][i] =
5142 priv->RfOfdmChnlAreaTxPwr2T[rf_path][index];
5143 }
5144
5145 for(i=0; i<14; i++)
5146 {
5147 //RT_TRACE((COMP_EFUSE), "Rf-%d TxPwr CH-%d CCK OFDM_1T OFDM_2T= 0x%x/0x%x/0x%x\n",
5148 //rf_path, i, priv->RfTxPwrLevelCck[0][i],
5149 //priv->RfTxPwrLevelOfdm1T[0][i] ,
5150 //priv->RfTxPwrLevelOfdm2T[0][i] );
5151 }
5152#endif
5153
5154 //
5155 // Update remained HAL variables.
5156 //
5157 priv->TSSI_13dBm = priv->EEPROMThermalMeter *100;
5158 priv->LegacyHTTxPowerDiff = priv->EEPROMTxPowerDiff;//new
5159 priv->TxPowerDiff = priv->EEPROMTxPowerDiff;
5160 //priv->AntennaTxPwDiff[0] = (priv->EEPROMTxPowerDiff & 0xf);// Antenna B gain offset to antenna A, bit0~3
5161 //priv->AntennaTxPwDiff[1] = ((priv->EEPROMTxPowerDiff & 0xf0)>>4);// Antenna C gain offset to antenna A, bit4~7
5162 priv->CrystalCap = priv->EEPROMCrystalCap; // CrystalCap, bit12~15
5163 priv->ThermalMeter[0] = priv->EEPROMThermalMeter;// ThermalMeter, bit0~3 for RFIC1, bit4~7 for RFIC2
5164 priv->LedStrategy = SW_LED_MODE0;
5165
5166 init_rate_adaptive(dev);
5167
5168 RT_TRACE(COMP_INIT, "<==== ConfigAdapterInfo8192SForAutoLoadFail\n");
5169
5170}
5171
5172#if 0
5173static void rtl8192SU_ReadAdapterInfo8192SEEPROM(struct net_device* dev)
5174{
5175 u16 EEPROMId = 0;
5176 u8 bLoad_From_EEPOM = false;
5177 struct r8192_priv *priv = ieee80211_priv(dev);
5178 u16 tmpValue = 0;
5179 u8 tmpBuffer[30];
5180 int i;
5181
5182 RT_TRACE(COMP_EPROM, "===========>%s()\n", __FUNCTION__);
5183
5184
5185 write_nic_byte(dev, SYS_ISO_CTRL+1, 0xE8); // Isolation signals from Loader
5186 udelay(10000);
5187 write_nic_byte(dev, PMC_FSM, 0x02); // Enable Loader Data Keep
5188
5189
5190 EEPROMId = eprom_read(dev, 0); //first read EEPROM ID out;
5191 RT_TRACE(COMP_EPROM, "EEPROM ID is 0x%x\n", EEPROMId);
5192
5193 if (EEPROMId != RTL8190_EEPROM_ID)
5194 {
5195 priv->AutoloadFailFlag = true;
5196 RT_TRACE(COMP_ERR, "EEPROM ID is invalid(is 0x%x(should be 0x%x)\n", EEPROMId, RTL8190_EEPROM_ID);
5197 }
5198 else
5199 {
5200 priv->AutoloadFailFlag = false;
5201 bLoad_From_EEPOM = true;
5202 }
5203
5204 if (bLoad_From_EEPOM)
5205 {
5206 tmpValue = eprom_read(dev, (EEPROM_VID>>1));
5207 priv->eeprom_vid = endian_swap(&tmpValue);
5208 priv->eeprom_pid = eprom_read(dev, (EEPROM_PID>>1));
5209
5210 // Version ID, Channel plan
5211 tmpValue = eprom_read(dev, (EEPROM_Version>>1));
5212 //pHalData->card_8192_version = (VERSION_8192S)((usValue&0x00ff));
5213 priv->eeprom_ChannelPlan =(tmpValue&0xff00)>>8;
5214 priv->bTXPowerDataReadFromEEPORM = true;
5215
5216 // Customer ID, 0x00 and 0xff are reserved for Realtek.
5217 tmpValue = eprom_read(dev, (u16)(EEPROM_CustomID>>1)) ;
5218 priv->eeprom_CustomerID = (u8)( tmpValue & 0xff);
5219 priv->eeprom_SubCustomerID = (u8)((tmpValue & 0xff00)>>8);
5220 }
5221 else
5222 {
5223 priv->eeprom_vid = 0;
5224 priv->eeprom_pid = 0;
5225 //priv->card_8192_version = VERSION_8192SU_A;
5226 priv->eeprom_ChannelPlan = 0;
5227 priv->eeprom_CustomerID = 0;
5228 priv->eeprom_SubCustomerID = 0;
5229 }
5230 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);
5231 //set channelplan from eeprom
5232 priv->ChannelPlan = priv->eeprom_ChannelPlan;// FIXLZM
5233
5234 RT_TRACE(COMP_INIT, "EEPROMId = 0x%4x\n", EEPROMId);
5235 RT_TRACE(COMP_INIT, "EEPROM VID = 0x%4x\n", priv->eeprom_vid);
5236 RT_TRACE(COMP_INIT, "EEPROM PID = 0x%4x\n", priv->eeprom_pid);
5237 //RT_TRACE(COMP_INIT, DBG_LOUD, ("EEPROM Version ID: 0x%2x\n", pHalData->VersionID));
5238 RT_TRACE(COMP_INIT, "EEPROM Customer ID: 0x%2x\n", priv->eeprom_CustomerID);
5239 RT_TRACE(COMP_INIT, "EEPROM SubCustomer ID: 0x%2x\n", priv->eeprom_SubCustomerID);
5240 RT_TRACE(COMP_INIT, "EEPROM ChannelPlan = 0x%4x\n", priv->eeprom_ChannelPlan);
5241
5242 // Read USB optional function.
5243 if(bLoad_From_EEPOM)
5244 {
5245 tmpValue = eprom_read(dev, (EEPROM_USB_OPTIONAL>>1));
5246 priv->EEPROMUsbOption = (u8)(tmpValue&0xff);
5247 }
5248 else
5249 {
5250 priv->EEPROMUsbOption = EEPROM_USB_Default_OPTIONAL_FUNC;
5251 }
5252
5253 RT_TRACE(COMP_INIT, "USB Option = %#x\n", priv->EEPROMUsbOption);
5254
5255
5256 if (bLoad_From_EEPOM)
5257 {
5258 int i;
5259 for (i=0; i<6; i+=2)
5260 {
5261 u16 tmp = 0;
5262 tmp = eprom_read(dev, (u16)((EEPROM_NODE_ADDRESS_BYTE_0 + i)>>1));
5263 *(u16*)(&dev->dev_addr[i]) = tmp;
5264 }
5265 }
5266 else
5267 {
5268 //<Roger_Notes> In this case, we random assigh MAC address here. 2008.10.15.
5269 static u8 sMacAddr[6] = {0x00, 0xE0, 0x4C, 0x81, 0x92, 0x00};
5270 u8 i;
5271
5272 //sMacAddr[5] = (u8)GetRandomNumber(1, 254);
5273
5274 for(i = 0; i < 6; i++)
5275 dev->dev_addr[i] = sMacAddr[i];
5276
5277 //memcpy(dev->dev_addr, sMacAddr, 6);
5278 //should I set IDR0 here?
5279 }
5280 write_nic_dword(dev, IDR0, ((u32*)dev->dev_addr)[0]);
5281 write_nic_word(dev, IDR4, ((u16*)(dev->dev_addr + 4))[0]);
5282 RT_TRACE(COMP_EPROM, "MAC addr:"MAC_FMT"\n", MAC_ARG(dev->dev_addr));
5283
5284 priv->rf_type = RTL819X_DEFAULT_RF_TYPE; //default 1T2R
5285#if (defined (RTL8192SU_FPGA_2MAC_VERIFICATION)||defined (RTL8192SU_ASIC_VERIFICATION))
5286 priv->rf_chip = RF_6052;
5287 priv->rf_type = RTL819X_DEFAULT_RF_TYPE;
5288 //priv->card_8192_version = VERSION_8192SU_A; //Over write for temporally experiment. 2008.10.16. By Roger.
5289#else
5290 priv->rf_chip = RF_8256;
5291#endif
5292
5293 {
5294#if 0
5295 if(bLoad_From_EEPOM)
5296 {
5297 tempval = (ReadEEprom(Adapter, (EEPROM_RFInd_PowerDiff>>1))) & 0xff;
5298 if (tempval&0x80) //RF-indication, bit[7]
5299 pHalData->RF_Type = RF_1T2R;
5300 else
5301 pHalData->RF_Type = RF_2T4R;
5302 }
5303#endif
5304
5305 priv->EEPROMTxPowerDiff = EEPROM_Default_TxPowerDiff;
5306 RT_TRACE(COMP_INIT, "TxPowerDiff = %#x\n", priv->EEPROMTxPowerDiff);
5307
5308
5309 //
5310 // Read antenna tx power offset of B/C/D to A from EEPROM
5311 // and read ThermalMeter from EEPROM
5312 //
5313 if(bLoad_From_EEPOM)
5314 {
5315 tmpValue = eprom_read(dev, (EEPROM_PwDiff>>1));
5316 priv->EEPROMPwDiff = tmpValue&0x00ff;
5317 priv->EEPROMThermalMeter = (tmpValue&0xff00)>>8;
5318 }
5319 else
5320 {
5321 priv->EEPROMPwDiff = EEPROM_Default_PwDiff;
5322 priv->EEPROMThermalMeter = EEPROM_Default_ThermalMeter;
5323 }
5324 RT_TRACE(COMP_INIT, "PwDiff = %#x\n", priv->EEPROMPwDiff);
5325 RT_TRACE(COMP_INIT, "ThermalMeter = %#x\n", priv->EEPROMThermalMeter);
5326
5327 priv->TSSI_13dBm = priv->EEPROMThermalMeter *100;
5328
5329
5330 // Read CrystalCap from EEPROM
5331 if(bLoad_From_EEPOM)
5332 {
5333 priv->EEPROMCrystalCap =(u8) (((eprom_read(dev, (EEPROM_CrystalCap>>1)))&0xf000)>>12);
5334 }
5335 else
5336 {
5337 priv->EEPROMCrystalCap = EEPROM_Default_CrystalCap;
5338 }
5339 RT_TRACE(COMP_INIT, "CrystalCap = %#x\n", priv->EEPROMCrystalCap);
5340
5341
5342 //if(pHalData->EEPROM_Def_Ver == 0) // old eeprom definition
5343 {
5344
5345 //
5346 // Get Tx Power Base.//===>
5347 //
5348 if(bLoad_From_EEPOM)
5349 {
5350 priv->EEPROMTxPwrBase =(u8) ((eprom_read(dev, (EEPROM_TxPowerBase>>1)))&0xff);
5351 }
5352 else
5353 {
5354 priv->EEPROMTxPwrBase = EEPROM_Default_TxPowerBase;
5355 }
5356
5357 RT_TRACE(COMP_INIT, "TxPwrBase = %#x\n", priv->EEPROMTxPwrBase);
5358
5359 //
5360 // Get CustomerID(Boad Type)
5361 // i.e., 0x0: RTL8188SU, 0x1: RTL8191SU, 0x2: RTL8192SU, 0x3: RTL8191GU.
5362 // Others: Reserved. Default is 0x2: RTL8192SU.
5363 //
5364 if(bLoad_From_EEPOM)
5365 {
5366 tmpValue = eprom_read(dev, (u16) (EEPROM_BoardType>>1));
5367 priv->EEPROMBoardType = (u8)(tmpValue&0xff);
5368 }
5369 else
5370 {
5371 priv->EEPROMBoardType = EEPROM_Default_BoardType;
5372 }
5373
5374 RT_TRACE(COMP_INIT, "BoardType = %#x\n", priv->EEPROMBoardType);
5375
5376#ifdef EEPROM_OLD_FORMAT_SUPPORT
5377
5378 //
5379 // Buffer TxPwIdx(i.e., from offset 0x58~0x75, total 30Bytes)
5380 //
5381 if(bLoad_From_EEPOM)
5382 {
5383 for(i = 0; i < 30; i += 2)
5384 {
5385 tmpValue = eprom_read(dev, (u16) ((EEPROM_TxPowerBase+i)>>1));
5386 *((u16 *)(&tmpBuffer[i])) = tmpValue;
5387 }
5388 }
5389
5390 //
5391 // Update CCK, OFDM Tx Power Index from above buffer.
5392 //
5393 if(bLoad_From_EEPOM)
5394 {
5395 for(i=0; i<14; i++)
5396 {
5397 priv->EEPROMTxPowerLevelCCK24G[i] = (u8)tmpBuffer[i+1];
5398 priv->EEPROMTxPowerLevelOFDM24G[i] = (u8)tmpBuffer[i+15];
5399 }
5400
5401 }
5402 else
5403 {
5404 for(i=0; i<14; i++)
5405 {
5406 priv->EEPROMTxPowerLevelCCK24G[i] = (u8)(EEPROM_Default_TxPower & 0xff);
5407 priv->EEPROMTxPowerLevelOFDM24G[i] = (u8)(EEPROM_Default_TxPower & 0xff);
5408 }
5409 }
5410
5411 for(i=0; i<14; i++)
5412 {
5413 RT_TRACE(COMP_INIT, "CCK 2.4G Tx Power Level, Index %d = 0x%02x\n", i, priv->EEPROMTxPowerLevelCCK24G[i]);
5414 RT_TRACE(COMP_INIT, "OFDM 2.4G Tx Power Level, Index %d = 0x%02x\n", i, priv->EEPROMTxPowerLevelOFDM24G[i]);
5415 }
5416#else
5417 // Please add code in the section!!!!
5418 // And merge tx power difference section.
5419#endif
5420
5421 //
5422 // Get TSSI value for each path.
5423 //
5424 if(bLoad_From_EEPOM)
5425 {
5426 tmpValue = eprom_read(dev, (u16) ((EEPROM_TSSI_A)>>1));
5427 priv->EEPROMTSSI_A = (u8)((tmpValue&0xff00)>>8);
5428 }
5429 else
5430 { // Default setting for Empty EEPROM
5431 priv->EEPROMTSSI_A = EEPROM_Default_TSSI;
5432 }
5433
5434 if(bLoad_From_EEPOM)
5435 {
5436 tmpValue = eprom_read(dev, (u16) ((EEPROM_TSSI_B)>>1));
5437 priv->EEPROMTSSI_B = (u8)(tmpValue&0xff);
5438 priv->EEPROMTxPwrTkMode = (u8)((tmpValue&0xff00)>>8);
5439 }
5440 else
5441 { // Default setting for Empty EEPROM
5442 priv->EEPROMTSSI_B = EEPROM_Default_TSSI;
5443 priv->EEPROMTxPwrTkMode = EEPROM_Default_TxPwrTkMode;
5444 }
5445
5446 RT_TRACE(COMP_INIT, "TSSI_A = %#x, TSSI_B = %#x\n", priv->EEPROMTSSI_A, priv->EEPROMTSSI_B);
5447 RT_TRACE(COMP_INIT, "TxPwrTkMod = %#x\n", priv->EEPROMTxPwrTkMode);
5448
5449#ifdef EEPROM_OLD_FORMAT_SUPPORT
5450 //
5451 // Get HT 2T Path A and B Power Index.
5452 //
5453 if(bLoad_From_EEPOM)
5454 {
5455 for(i = 0; i < 6; i += 2)
5456 {
5457 tmpValue = eprom_read(dev, (u16) ((EEPROM_HT2T_CH1_A+i)>>1));
5458 *((u16*)(&priv->EEPROMHT2T_TxPwr[i])) = tmpValue;
5459 }
5460 }
5461 else
5462 { // Default setting for Empty EEPROM
5463 for(i=0; i<6; i++)
5464 {
5465 priv->EEPROMHT2T_TxPwr[i] = EEPROM_Default_HT2T_TxPwr;
5466 }
5467 }
5468
5469 for(i=0; i<6; i++)
5470 {
5471 RT_TRACE(COMP_INIT, "EEPROMHT2T_TxPwr, Index %d = 0x%02x\n", i, priv->EEPROMHT2T_TxPwr[i]);
5472 }
5473#else
5474
5475#endif
5476 }
5477
5478#ifdef EEPROM_OLD_FORMAT_SUPPORT
5479 //
5480 // Update HAL variables.
5481 //
5482 for(i=0; i<14; i++)
5483 {
5484 priv->TxPowerLevelOFDM24G[i] = priv->EEPROMTxPowerLevelOFDM24G[i];
5485 priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelCCK24G[i];
5486 }
5487#else
5488
5489#endif
5490 priv->TxPowerDiff = priv->EEPROMPwDiff;
5491 // Antenna B gain offset to antenna A, bit0~3
5492 priv->AntennaTxPwDiff[0] = (priv->EEPROMTxPowerDiff & 0xf);
5493 // Antenna C gain offset to antenna A, bit4~7
5494 priv->AntennaTxPwDiff[1] = ((priv->EEPROMTxPowerDiff & 0xf0)>>4);
5495 // CrystalCap, bit12~15
5496 priv->CrystalCap = priv->EEPROMCrystalCap;
5497 // ThermalMeter, bit0~3 for RFIC1, bit4~7 for RFIC2
5498 // 92U does not enable TX power tracking.
5499 priv->ThermalMeter[0] = priv->EEPROMThermalMeter;
5500 }
5501
5502 priv->LedStrategy = SW_LED_MODE0;
5503
5504 if(priv->rf_type == RF_1T2R)
5505 {
5506 RT_TRACE(COMP_EPROM, "\n1T2R config\n");
5507 }
5508 else
5509 {
5510 RT_TRACE(COMP_EPROM, "\n2T4R config\n");
5511 }
5512
5513 // 2008/01/16 MH We can only know RF type in the function. So we have to init
5514 // DIG RATR table again.
5515 init_rate_adaptive(dev);
5516 //we need init DIG RATR table here again.
5517
5518 RT_TRACE(COMP_EPROM, "<===========%s()\n", __FUNCTION__);
5519 return;
5520}
5521
5522//
5523// Description:
5524// 1. Read HW adapter information by E-Fuse.
5525// 2. Refered from SD1 Richard.
5526//
5527// Assumption:
5528// 1. Boot from E-Fuse and CR9346 regiser has verified.
5529// 2. PASSIVE_LEVEL (USB interface)
5530//
5531// Created by Roger, 2008.10.21.
5532//
5533void
5534rtl8192SU_ReadAdapterInfo8192SEFuse(struct net_device* dev)
5535{
5536 struct r8192_priv *priv = ieee80211_priv(dev);
5537 u16 i,usValue;
5538 u16 EEPROMId;
5539 u8 readbyte;
5540 u8 OFDMTxPwr[14];
5541 u8 CCKTxPwr[14];
5542 u8 HT2T_TxPwr[6];
5543 u8 UsbPhyParam[5];
5544 u8 hwinfo[HWSET_MAX_SIZE_92S];
5545
5546
5547 RT_TRACE(COMP_INIT, "====> ReadAdapterInfo8192SEFuse\n");
5548
5549 //
5550 // <Roger_Notes> We set Isolation signals from Loader and reset EEPROM after system resuming
5551 // from suspend mode.
5552 // 2008.10.21.
5553 //
5554 write_nic_byte(dev, SYS_ISO_CTRL+1, 0xE8); // Isolation signals from Loader
5555 //PlatformStallExecution(10000);
5556 mdelay(10);
5557 write_nic_byte(dev, SYS_FUNC_EN+1, 0x40);
5558 write_nic_byte(dev, SYS_FUNC_EN+1, 0x50);
5559
5560 readbyte = read_nic_byte(dev, EFUSE_TEST+3);
5561 write_nic_byte(dev, EFUSE_TEST+3, (readbyte | 0x80));
5562 write_nic_byte(dev, EFUSE_TEST+3, 0x72);
5563 write_nic_byte(dev, EFUSE_CLK, 0x03);
5564
5565 //
5566 // Dump EFUSe at init time for later use
5567 //
5568 // Read EFUSE real map to shadow!!
5569 EFUSE_ShadowMapUpdate(dev);
5570
5571 memcpy(hwinfo, (void*)&priv->EfuseMap[EFUSE_INIT_MAP][0], HWSET_MAX_SIZE_92S);
5572 //RT_PRINT_DATA(COMP_INIT, DBG_LOUD, ("MAP \n"), hwinfo, HWSET_MAX_SIZE_92S);
5573
5574 //
5575 // <Roger_Notes> Event though CR9346 regiser can verify whether Autoload is success or not, but we still
5576 // double check ID codes for 92S here(e.g., due to HW GPIO polling fail issue).
5577 // 2008.10.21.
5578 //
5579 ReadEFuse(dev, 0, 2, (unsigned char*) &EEPROMId);
5580
5581 if( EEPROMId != RTL8190_EEPROM_ID )
5582 {
5583 RT_TRACE(COMP_INIT, "EEPROM ID(%#x) is invalid!!\n", EEPROMId);
5584 priv->AutoloadFailFlag=true;
5585 }
5586 else
5587 {
5588 priv->AutoloadFailFlag=false;
5589 }
5590
5591 // Read IC Version && Channel Plan
5592 if(!priv->AutoloadFailFlag)
5593 {
5594
5595 // VID, PID
5596 ReadEFuse(dev, EEPROM_VID, 2, (unsigned char*) &priv->eeprom_vid);
5597 ReadEFuse(dev, EEPROM_PID, 2, (unsigned char*) &priv->eeprom_pid);
5598
5599 // Version ID, Channel plan
5600 ReadEFuse(dev, EEPROM_Version, 2, (unsigned char*) &usValue);
5601 //pHalData->VersionID = (VERSION_8192S)(usValue&0x00ff);
5602 priv->eeprom_ChannelPlan = (usValue&0xff00>>8);
5603 priv->bTXPowerDataReadFromEEPORM = true;
5604
5605 // Customer ID, 0x00 and 0xff are reserved for Realtek.
5606 ReadEFuse(dev, EEPROM_CustomID, 2, (unsigned char*) &usValue);
5607 priv->eeprom_CustomerID = (u8)( usValue & 0xff);
5608 priv->eeprom_SubCustomerID = (u8)((usValue & 0xff00)>>8);
5609 }
5610 else
5611 {
5612 priv->eeprom_vid = 0;
5613 priv->eeprom_pid = 0;
5614 priv->eeprom_ChannelPlan = 0;
5615 priv->eeprom_CustomerID = 0;
5616 priv->eeprom_SubCustomerID = 0;
5617 }
5618
5619 RT_TRACE(COMP_INIT, "EEPROM Id = 0x%4x\n", EEPROMId);
5620 RT_TRACE(COMP_INIT, "EEPROM VID = 0x%4x\n", priv->eeprom_vid);
5621 RT_TRACE(COMP_INIT, "EEPROM PID = 0x%4x\n", priv->eeprom_pid);
5622 //RT_TRACE(COMP_INIT, DBG_LOUD, ("EEPROM Version ID: 0x%2x\n", pHalData->VersionID));
5623 RT_TRACE(COMP_INIT, "EEPROM Customer ID: 0x%2x\n", priv->eeprom_CustomerID);
5624 RT_TRACE(COMP_INIT, "EEPROM SubCustomer ID: 0x%2x\n", priv->eeprom_SubCustomerID);
5625 RT_TRACE(COMP_INIT, "EEPROM ChannelPlan = 0x%4x\n", priv->eeprom_ChannelPlan);
5626
5627
5628 // Read USB optional function.
5629 if(!priv->AutoloadFailFlag)
5630 {
5631 ReadEFuse(dev, EEPROM_USB_OPTIONAL, 1, (unsigned char*) &priv->EEPROMUsbOption);
5632 }
5633 else
5634 {
5635 priv->EEPROMUsbOption = EEPROM_USB_Default_OPTIONAL_FUNC;
5636 }
5637
5638 RT_TRACE(COMP_INIT, "USB Option = %#x\n", priv->EEPROMUsbOption);
5639
5640
5641 // Read USB PHY parameters.
5642 if(!priv->AutoloadFailFlag)
5643 {
5644 ReadEFuse(dev, EEPROM_USB_PHY_PARA1, 5, (unsigned char*)UsbPhyParam);
5645 for(i=0; i<5; i++)
5646 {
5647 priv->EEPROMUsbPhyParam[i] = UsbPhyParam[i];
5648 RT_TRACE(COMP_INIT, "USB Param = index(%d) = %#x\n", i, priv->EEPROMUsbPhyParam[i]);
5649 }
5650 }
5651 else
5652 {
5653 for(i=0; i<5; i++)
5654 {
5655 priv->EEPROMUsbPhyParam[i] = EEPROM_USB_Default_PHY_PARAM;
5656 RT_TRACE(COMP_INIT, "USB Param = index(%d) = %#x\n", i, priv->EEPROMUsbPhyParam[i]);
5657 }
5658 }
5659
5660
5661 //Read Permanent MAC address
5662 if(!priv->AutoloadFailFlag)
5663 {
5664 u8 macaddr[6] = {0x00, 0xe1, 0x86, 0x4c, 0x92, 0x00};
5665
5666 ReadEFuse(dev, EEPROM_NODE_ADDRESS_BYTE_0, 6, (unsigned char*)macaddr);
5667 for(i=0; i<6; i++)
5668 dev->dev_addr[i] = macaddr[i];
5669 }
5670 else
5671 {//Auto load fail
5672
5673 //<Roger_Notes> In this case, we random assigh MAC address here. 2008.10.15.
5674 static u8 sMacAddr[6] = {0x00, 0xE0, 0x4C, 0x81, 0x92, 0x00};
5675 u8 i;
5676
5677 //if(!Adapter->bInHctTest)
5678 //sMacAddr[5] = (u8)GetRandomNumber(1, 254);
5679
5680 for(i = 0; i < 6; i++)
5681 dev->dev_addr[i] = sMacAddr[i];
5682 }
5683
5684 //NicIFSetMacAddress(Adapter, Adapter->PermanentAddress);
5685 write_nic_dword(dev, IDR0, ((u32*)dev->dev_addr)[0]);
5686 write_nic_word(dev, IDR4, ((u16*)(dev->dev_addr + 4))[0]);
5687
5688 RT_TRACE(COMP_INIT, "ReadAdapterInfo8192SEFuse(), Permanent Address = %02x-%02x-%02x-%02x-%02x-%02x\n",
5689 dev->dev_addr[0], dev->dev_addr[1],
5690 dev->dev_addr[2], dev->dev_addr[3],
5691 dev->dev_addr[4], dev->dev_addr[5]);
5692
5693 // 2007/11/15 MH For RTL8192USB we assign as 1T2R now.
5694 priv->rf_type = RTL819X_DEFAULT_RF_TYPE; // default : 1T2R
5695
5696#if (defined (RTL8192SU_FPGA_2MAC_VERIFICATION)||defined (RTL8192SU_ASIC_VERIFICATION))
5697 priv->rf_chip = RF_6052;
5698 priv->rf_type = RTL819X_DEFAULT_RF_TYPE;
5699#else
5700 priv->rf_chip = RF_8256;
5701#endif
5702
5703 {
5704 //
5705 // Read antenna tx power offset of B/C/D to A from EEPROM
5706 // and read ThermalMeter from EEPROM
5707 //
5708 if(!priv->AutoloadFailFlag)
5709 {
5710 ReadEFuse(dev, EEPROM_PwDiff, 2, (unsigned char*) &usValue);
5711 priv->EEPROMPwDiff = usValue&0x00ff;
5712 priv->EEPROMThermalMeter = (usValue&0xff00)>>8;
5713 }
5714 else
5715 {
5716 priv->EEPROMPwDiff = EEPROM_Default_PwDiff;
5717 priv->EEPROMThermalMeter = EEPROM_Default_ThermalMeter;
5718 }
5719
5720 RT_TRACE(COMP_INIT, "PwDiff = %#x\n", priv->EEPROMPwDiff);
5721 RT_TRACE(COMP_INIT, "ThermalMeter = %#x\n", priv->EEPROMThermalMeter);
5722
5723 priv->TSSI_13dBm = priv->EEPROMThermalMeter *100;
5724
5725 //
5726 // Read Tx Power gain offset of legacy OFDM to HT rate.
5727 // Read CrystalCap from EEPROM
5728 //
5729 if(!priv->AutoloadFailFlag)
5730 {
5731 ReadEFuse(dev, EEPROM_CrystalCap, 1, (unsigned char*) &usValue);
5732 priv->EEPROMCrystalCap = (u8)((usValue&0xf0)>>4);
5733 }
5734 else
5735 {
5736 priv->EEPROMCrystalCap = EEPROM_Default_CrystalCap;
5737 }
5738
5739 RT_TRACE(COMP_INIT, "CrystalCap = %#x\n", priv->EEPROMCrystalCap);
5740
5741 priv->EEPROMTxPowerDiff = EEPROM_Default_TxPowerDiff;
5742 RT_TRACE(COMP_INIT, "TxPowerDiff = %d\n", priv->EEPROMTxPowerDiff);
5743
5744
5745 //
5746 // Get Tx Power Base.
5747 //
5748 if(!priv->AutoloadFailFlag)
5749 {
5750 ReadEFuse(dev, EEPROM_TxPowerBase, 1, (unsigned char*) &priv->EEPROMTxPwrBase );
5751 }
5752 else
5753 {
5754 priv->EEPROMTxPwrBase = EEPROM_Default_TxPowerBase;
5755 }
5756
5757 RT_TRACE(COMP_INIT, "TxPwrBase = %#x\n", priv->EEPROMTxPwrBase);
5758
5759 //
5760 // Get CustomerID(Boad Type)
5761 // i.e., 0x0: RTL8188SU, 0x1: RTL8191SU, 0x2: RTL8192SU, 0x3: RTL8191GU.
5762 // Others: Reserved. Default is 0x2: RTL8192SU.
5763 //
5764 if(!priv->AutoloadFailFlag)
5765 {
5766 ReadEFuse(dev, EEPROM_BoardType, 1, (unsigned char*) &priv->EEPROMBoardType );
5767 }
5768 else
5769 {
5770 priv->EEPROMBoardType = EEPROM_Default_BoardType;
5771 }
5772
5773 RT_TRACE(COMP_INIT, "BoardType = %#x\n", priv->EEPROMBoardType);
5774
5775 //if(pHalData->EEPROM_Def_Ver == 0)
5776 {
5777#ifdef EEPROM_OLD_FORMAT_SUPPORT
5778 //
5779 // Get CCK Tx Power Index.
5780 //
5781 if(!priv->AutoloadFailFlag)
5782 {
5783 ReadEFuse(dev, EEPROM_TxPwIndex_CCK_24G, 14, (unsigned char*)CCKTxPwr);
5784 for(i=0; i<14; i++)
5785 {
5786 RT_TRACE(COMP_INIT, "CCK 2.4G Tx Power Level, Index %d = 0x%02x\n", i, CCKTxPwr[i]);
5787 priv->EEPROMTxPowerLevelCCK24G[i] = CCKTxPwr[i];
5788 }
5789 }
5790 else
5791 { // Default setting for Empty EEPROM
5792 for(i=0; i<14; i++)
5793 priv->EEPROMTxPowerLevelCCK24G[i] = (u8)(EEPROM_Default_TxPower & 0xff);
5794 }
5795
5796 //
5797 // Get OFDM Tx Power Index.
5798 //
5799 if(!priv->AutoloadFailFlag)
5800 {
5801 ReadEFuse(dev, EEPROM_TxPwIndex_OFDM_24G, 14, (unsigned char*)OFDMTxPwr);
5802 for(i=0; i<14; i++)
5803 {
5804 RT_TRACE(COMP_INIT, "OFDM 2.4G Tx Power Level, Index %d = 0x%02x\n", i, OFDMTxPwr[i]);
5805 priv->EEPROMTxPowerLevelOFDM24G[i] = OFDMTxPwr[i];
5806 }
5807 }
5808 else
5809 { // Default setting for Empty EEPROM
5810 usValue = 0x10;
5811 for(i=0; i<14; i++)
5812 priv->EEPROMTxPowerLevelOFDM24G[i] = (u8)usValue;
5813 }
5814#else
5815 // Please add code in the section!!!!
5816 // And merge tx power difference section.
5817#endif
5818
5819 //
5820 // Get TSSI value for each path.
5821 //
5822 if(!priv->AutoloadFailFlag)
5823 {
5824 ReadEFuse(dev, EEPROM_TSSI_A, 2, (unsigned char*)&usValue);
5825 priv->EEPROMTSSI_A = (u8)(usValue&0xff);
5826 priv->EEPROMTSSI_B = (u8)((usValue&0xff00)>>8);
5827 }
5828 else
5829 { // Default setting for Empty EEPROM
5830 priv->EEPROMTSSI_A = EEPROM_Default_TSSI;
5831 priv->EEPROMTSSI_B = EEPROM_Default_TSSI;
5832 }
5833
5834 RT_TRACE(COMP_INIT, "TSSI_A = %#x, TSSI_B = %#x\n",
5835 priv->EEPROMTSSI_A, priv->EEPROMTSSI_B);
5836
5837 //
5838 // Get Tx Power tracking mode.
5839 //
5840 if(!priv->AutoloadFailFlag)
5841 {
5842 ReadEFuse(dev, EEPROM_TxPwTkMode, 1, (unsigned char*)&priv->EEPROMTxPwrTkMode);
5843 }
5844 else
5845 { // Default setting for Empty EEPROM
5846 priv->EEPROMTxPwrTkMode = EEPROM_Default_TxPwrTkMode;
5847 }
5848
5849 RT_TRACE(COMP_INIT, "TxPwrTkMod = %#x\n", priv->EEPROMTxPwrTkMode);
5850
5851
5852 // TODO: The following HT 2T Path A and B Power Index should be updated.!! Added by Roger, 2008.20.23.
5853
5854 //
5855 // Get HT 2T Path A and B Power Index.
5856 //
5857 if(!priv->AutoloadFailFlag)
5858 {
5859 ReadEFuse(dev, EEPROM_HT2T_CH1_A, 6, (unsigned char*)HT2T_TxPwr);
5860 for(i=0; i<6; i++)
5861 {
5862 priv->EEPROMHT2T_TxPwr[i] = HT2T_TxPwr[i];
5863 }
5864 }
5865 else
5866 { // Default setting for Empty EEPROM
5867 for(i=0; i<6; i++)
5868 {
5869 priv->EEPROMHT2T_TxPwr[i] = EEPROM_Default_HT2T_TxPwr;
5870 }
5871 }
5872
5873 for(i=0; i<6; i++)
5874 {
5875 RT_TRACE(COMP_INIT, "EEPROMHT2T_TxPwr, Index %d = 0x%02x\n",
5876 i, priv->EEPROMHT2T_TxPwr[i]);
5877 }
5878 }
5879
5880#ifdef EEPROM_OLD_FORMAT_SUPPORT
5881 //
5882 // Update HAL variables.
5883 //
5884 for(i=0; i<14; i++)
5885 {
5886 priv->TxPowerLevelOFDM24G[i] = priv->EEPROMTxPowerLevelOFDM24G[i];
5887 priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelCCK24G[i];
5888 }
5889#else
5890
5891#endif
5892 priv->TxPowerDiff = priv->EEPROMPwDiff;
5893 // Antenna B gain offset to antenna A, bit0~3
5894 priv->AntennaTxPwDiff[0] = (priv->EEPROMTxPowerDiff & 0xf);
5895 // Antenna C gain offset to antenna A, bit4~7
5896 priv->AntennaTxPwDiff[1] = ((priv->EEPROMTxPowerDiff & 0xf0)>>4);
5897 // CrystalCap, bit12~15
5898 priv->CrystalCap = priv->EEPROMCrystalCap;
5899 // ThermalMeter, bit0~3 for RFIC1, bit4~7 for RFIC2
5900 // 92U does not enable TX power tracking.
5901 priv->ThermalMeter[0] = priv->EEPROMThermalMeter;
5902 }
5903
5904 priv->LedStrategy = SW_LED_MODE0;
5905
5906 init_rate_adaptive(dev);
5907
5908 RT_TRACE(COMP_INIT, "<==== ReadAdapterInfo8192SEFuse\n");
5909
5910}
5911#endif
5912
5913//
5914// Description:
5915// Read HW adapter information by E-Fuse or EEPROM according CR9346 reported.
5916//
5917// Assumption:
5918// 1. CR9346 regiser has verified.
5919// 2. PASSIVE_LEVEL (USB interface)
5920//
5921// Created by Roger, 2008.10.21.
5922//
5923void
5924rtl8192SU_ReadAdapterInfo8192SUsb(struct net_device* dev)
5925{
5926 struct r8192_priv *priv = ieee80211_priv(dev);
5927 u16 i,usValue;
5928 u8 tmpU1b, tempval;
5929 u16 EEPROMId;
5930 u8 hwinfo[HWSET_MAX_SIZE_92S];
5931 u8 rf_path, index; // For EEPROM/EFUSE After V0.6_1117
5932
5933
5934 RT_TRACE(COMP_INIT, "====> ReadAdapterInfo8192SUsb\n");
5935
5936 //
5937 // <Roger_Note> The following operation are prevent Efuse leakage by turn on 2.5V.
5938 // 2008.11.25.
5939 //
5940 tmpU1b = read_nic_byte(dev, EFUSE_TEST+3);
5941 write_nic_byte(dev, EFUSE_TEST+3, tmpU1b|0x80);
5942 //PlatformStallExecution(1000);
5943 mdelay(10);
5944 write_nic_byte(dev, EFUSE_TEST+3, (tmpU1b&(~BIT7)));
5945
5946 // Retrieve Chip version.
5947 priv->card_8192_version = (VERSION_8192S)((read_nic_dword(dev, PMC_FSM)>>16)&0xF);
5948 RT_TRACE(COMP_INIT, "Chip Version ID: 0x%2x\n", priv->card_8192_version);
5949
5950 switch(priv->card_8192_version)
5951 {
5952 case 0:
5953 RT_TRACE(COMP_INIT, "Chip Version ID: VERSION_8192S_ACUT.\n");
5954 break;
5955 case 1:
5956 RT_TRACE(COMP_INIT, "Chip Version ID: VERSION_8192S_BCUT.\n");
5957 break;
5958 case 2:
5959 RT_TRACE(COMP_INIT, "Chip Version ID: VERSION_8192S_CCUT.\n");
5960 break;
5961 default:
5962 RT_TRACE(COMP_INIT, "Unknown Chip Version!!\n");
5963 priv->card_8192_version = VERSION_8192S_BCUT;
5964 break;
5965 }
5966
5967 //if (IS_BOOT_FROM_EEPROM(Adapter))
5968 if(priv->EepromOrEfuse)
5969 { // Read frin EEPROM
5970 write_nic_byte(dev, SYS_ISO_CTRL+1, 0xE8); // Isolation signals from Loader
5971 //PlatformStallExecution(10000);
5972 mdelay(10);
5973 write_nic_byte(dev, PMC_FSM, 0x02); // Enable Loader Data Keep
5974 // Read all Content from EEPROM or EFUSE.
5975 for(i = 0; i < HWSET_MAX_SIZE_92S; i += 2)
5976 {
5977 usValue = eprom_read(dev, (u16) (i>>1));
5978 *((u16*)(&hwinfo[i])) = usValue;
5979 }
5980 }
5981 else if (!(priv->EepromOrEfuse))
5982 { // Read from EFUSE
5983
5984 //
5985 // <Roger_Notes> We set Isolation signals from Loader and reset EEPROM after system resuming
5986 // from suspend mode.
5987 // 2008.10.21.
5988 //
5989 //PlatformEFIOWrite1Byte(Adapter, SYS_ISO_CTRL+1, 0xE8); // Isolation signals from Loader
5990 //PlatformStallExecution(10000);
5991 //PlatformEFIOWrite1Byte(Adapter, SYS_FUNC_EN+1, 0x40);
5992 //PlatformEFIOWrite1Byte(Adapter, SYS_FUNC_EN+1, 0x50);
5993
5994 //tmpU1b = PlatformEFIORead1Byte(Adapter, EFUSE_TEST+3);
5995 //PlatformEFIOWrite1Byte(Adapter, EFUSE_TEST+3, (tmpU1b | 0x80));
5996 //PlatformEFIOWrite1Byte(Adapter, EFUSE_TEST+3, 0x72);
5997 //PlatformEFIOWrite1Byte(Adapter, EFUSE_CLK, 0x03);
5998
5999 // Read EFUSE real map to shadow.
6000 EFUSE_ShadowMapUpdate(dev);
6001 memcpy(hwinfo, &priv->EfuseMap[EFUSE_INIT_MAP][0], HWSET_MAX_SIZE_92S);
6002 }
6003 else
6004 {
6005 RT_TRACE(COMP_INIT, "ReadAdapterInfo8192SUsb(): Invalid boot type!!\n");
6006 }
6007
6008 //YJ,test,090106
6009 //dump_buf(hwinfo,HWSET_MAX_SIZE_92S);
6010 //
6011 // <Roger_Notes> The following are EFUSE/EEPROM independent operations!!
6012 //
6013 //RT_PRINT_DATA(COMP_EFUSE, DBG_LOUD, ("MAP: \n"), hwinfo, HWSET_MAX_SIZE_92S);
6014
6015 //
6016 // <Roger_Notes> Event though CR9346 regiser can verify whether Autoload is success or not, but we still
6017 // double check ID codes for 92S here(e.g., due to HW GPIO polling fail issue).
6018 // 2008.10.21.
6019 //
6020 EEPROMId = *((u16 *)&hwinfo[0]);
6021
6022 if( EEPROMId != RTL8190_EEPROM_ID )
6023 {
6024 RT_TRACE(COMP_INIT, "ID(%#x) is invalid!!\n", EEPROMId);
6025 priv->bTXPowerDataReadFromEEPORM = FALSE;
6026 priv->AutoloadFailFlag=TRUE;
6027 }
6028 else
6029 {
6030 priv->AutoloadFailFlag=FALSE;
6031#if RTL8192SU_USE_PARAM_TXPWR
6032 priv->bTXPowerDataReadFromEEPORM = FALSE;
6033#else
6034 priv->bTXPowerDataReadFromEEPORM = TRUE;
6035#endif
6036
6037 }
6038 // Read IC Version && Channel Plan
6039 if(!priv->AutoloadFailFlag)
6040 {
6041 // VID, PID
6042 priv->eeprom_vid = *(u16 *)&hwinfo[EEPROM_VID];
6043 priv->eeprom_pid = *(u16 *)&hwinfo[EEPROM_PID];
6044 priv->bIgnoreDiffRateTxPowerOffset = false; //cosa for test
6045
6046
6047 // EEPROM Version ID, Channel plan
6048 priv->EEPROMVersion = *(u8 *)&hwinfo[EEPROM_Version];
6049 priv->eeprom_ChannelPlan = *(u8 *)&hwinfo[EEPROM_ChannelPlan];
6050
6051 // Customer ID, 0x00 and 0xff are reserved for Realtek.
6052 priv->eeprom_CustomerID = *(u8 *)&hwinfo[EEPROM_CustomID];
6053 priv->eeprom_SubCustomerID = *(u8 *)&hwinfo[EEPROM_SubCustomID];
6054 }
6055 else
6056 {
6057 //priv->eeprom_vid = 0;
6058 //priv->eeprom_pid = 0;
6059 //priv->EEPROMVersion = 0;
6060 //priv->eeprom_ChannelPlan = 0;
6061 //priv->eeprom_CustomerID = 0;
6062 //priv->eeprom_SubCustomerID = 0;
6063
6064 rtl8192SU_ConfigAdapterInfo8192SForAutoLoadFail(dev);
6065 return;
6066 }
6067
6068
6069 RT_TRACE(COMP_INIT, "EEPROM Id = 0x%4x\n", EEPROMId);
6070 RT_TRACE(COMP_INIT, "EEPROM VID = 0x%4x\n", priv->eeprom_vid);
6071 RT_TRACE(COMP_INIT, "EEPROM PID = 0x%4x\n", priv->eeprom_pid);
6072 RT_TRACE(COMP_INIT, "EEPROM Version ID: 0x%2x\n", priv->EEPROMVersion);
6073 RT_TRACE(COMP_INIT, "EEPROM Customer ID: 0x%2x\n", priv->eeprom_CustomerID);
6074 RT_TRACE(COMP_INIT, "EEPROM SubCustomer ID: 0x%2x\n", priv->eeprom_SubCustomerID);
6075 RT_TRACE(COMP_INIT, "EEPROM ChannelPlan = 0x%4x\n", priv->eeprom_ChannelPlan);
6076 RT_TRACE(COMP_INIT, "bIgnoreDiffRateTxPowerOffset = %d\n", priv->bIgnoreDiffRateTxPowerOffset);
6077
6078
6079 // Read USB optional function.
6080 if(!priv->AutoloadFailFlag)
6081 {
6082 priv->EEPROMUsbOption = *(u8 *)&hwinfo[EEPROM_USB_OPTIONAL];
6083 }
6084 else
6085 {
6086 priv->EEPROMUsbOption = EEPROM_USB_Default_OPTIONAL_FUNC;
6087 }
6088
6089
6090 priv->EEPROMUsbEndPointNumber = rtl8192SU_UsbOptionToEndPointNumber((priv->EEPROMUsbOption&EEPROM_EP_NUMBER)>>3);
6091
6092 RT_TRACE(COMP_INIT, "USB Option = %#x\n", priv->EEPROMUsbOption);
6093 RT_TRACE(COMP_INIT, "EndPoint Number = %#x\n", priv->EEPROMUsbEndPointNumber);
6094
6095#ifdef TO_DO_LIST
6096 //
6097 // Decide CustomerID according to VID/DID or EEPROM
6098 //
6099 switch(pHalData->EEPROMCustomerID)
6100 {
6101 case EEPROM_CID_ALPHA:
6102 pMgntInfo->CustomerID = RT_CID_819x_ALPHA;
6103 break;
6104
6105 case EEPROM_CID_CAMEO:
6106 pMgntInfo->CustomerID = RT_CID_819x_CAMEO;
6107 break;
6108
6109 case EEPROM_CID_SITECOM:
6110 pMgntInfo->CustomerID = RT_CID_819x_Sitecom;
6111 RT_TRACE(COMP_INIT, DBG_LOUD, ("CustomerID = 0x%4x\n", pMgntInfo->CustomerID));
6112
6113 break;
6114
6115 case EEPROM_CID_WHQL:
6116 Adapter->bInHctTest = TRUE;
6117
6118 pMgntInfo->bSupportTurboMode = FALSE;
6119 pMgntInfo->bAutoTurboBy8186 = FALSE;
6120
6121 pMgntInfo->PowerSaveControl.bInactivePs = FALSE;
6122 pMgntInfo->PowerSaveControl.bIPSModeBackup = FALSE;
6123 pMgntInfo->PowerSaveControl.bLeisurePs = FALSE;
6124 pMgntInfo->keepAliveLevel = 0;
6125 break;
6126
6127 default:
6128 pMgntInfo->CustomerID = RT_CID_DEFAULT;
6129 break;
6130
6131 }
6132
6133 //
6134 // Led mode
6135 //
6136 switch(pMgntInfo->CustomerID)
6137 {
6138 case RT_CID_DEFAULT:
6139 case RT_CID_819x_ALPHA:
6140 pHalData->LedStrategy = SW_LED_MODE1;
6141 pHalData->bRegUseLed = TRUE;
6142 pHalData->SwLed1.bLedOn = TRUE;
6143 break;
6144 case RT_CID_819x_CAMEO:
6145 pHalData->LedStrategy = SW_LED_MODE1;
6146 pHalData->bRegUseLed = TRUE;
6147 break;
6148
6149 case RT_CID_819x_Sitecom:
6150 pHalData->LedStrategy = SW_LED_MODE2;
6151 pHalData->bRegUseLed = TRUE;
6152 break;
6153
6154 default:
6155 pHalData->LedStrategy = SW_LED_MODE0;
6156 break;
6157 }
6158#endif
6159
6160 // Read USB PHY parameters.
6161 for(i=0; i<5; i++)
6162 priv->EEPROMUsbPhyParam[i] = *(u8 *)&hwinfo[EEPROM_USB_PHY_PARA1+i];
6163
6164 //RT_PRINT_DATA(COMP_EFUSE, DBG_LOUD, ("USB PHY Param: \n"), pHalData->EEPROMUsbPhyParam, 5);
6165
6166
6167 //Read Permanent MAC address
6168 for(i=0; i<6; i++)
6169 dev->dev_addr[i] = *(u8 *)&hwinfo[EEPROM_NODE_ADDRESS_BYTE_0+i];
6170
6171 //NicIFSetMacAddress(Adapter, Adapter->PermanentAddress);
6172 write_nic_dword(dev, IDR0, ((u32*)dev->dev_addr)[0]);
6173 write_nic_word(dev, IDR4, ((u16*)(dev->dev_addr + 4))[0]);
6174
6175 RT_TRACE(COMP_INIT, "ReadAdapterInfo8192SEFuse(), Permanent Address = %02x-%02x-%02x-%02x-%02x-%02x\n",
6176 dev->dev_addr[0], dev->dev_addr[1],
6177 dev->dev_addr[2], dev->dev_addr[3],
6178 dev->dev_addr[4], dev->dev_addr[5]);
6179
6180 //
6181 // Get CustomerID(Boad Type)
6182 // i.e., 0x0: RTL8188SU, 0x1: RTL8191SU, 0x2: RTL8192SU, 0x3: RTL8191GU.
6183 // Others: Reserved. Default is 0x2: RTL8192SU.
6184 //
6185 //if(!priv->AutoloadFailFlag)
6186 //{
6187 priv->EEPROMBoardType = *(u8 *)&hwinfo[EEPROM_BoardType];
6188 priv->rf_type = rtl8192SU_BoardTypeToRFtype(dev, priv->EEPROMBoardType);
6189 //}
6190 //else
6191 //{
6192 // priv->EEPROMBoardType = EEPROM_Default_BoardType;
6193 // priv->rf_type = RF_1T2R;
6194 //}
6195
6196#if (defined (RTL8192SU_FPGA_2MAC_VERIFICATION)||defined (RTL8192SU_ASIC_VERIFICATION))
6197 priv->rf_chip = RF_6052;
6198#else
6199 priv->rf_chip = RF_8256;
6200#endif
6201
6202 priv->rf_chip = RF_6052;//lzm test
6203 RT_TRACE(COMP_INIT, "BoardType = 0x%2x\n", priv->EEPROMBoardType);
6204 RT_TRACE(COMP_INIT, "RF_Type = 0x%2x\n", priv->rf_type);
6205
6206 //
6207 // Read antenna tx power offset of B/C/D to A from EEPROM
6208 // and read ThermalMeter from EEPROM
6209 //
6210 //if(!priv->AutoloadFailFlag)
6211 {
6212 priv->EEPROMTxPowerDiff = *(u8 *)&hwinfo[EEPROM_PwDiff];
6213 priv->EEPROMThermalMeter = *(u8 *)&hwinfo[EEPROM_ThermalMeter];
6214 }
6215 //else
6216 //{
6217 // priv->EEPROMTxPowerDiff = EEPROM_Default_PwDiff;
6218 // priv->EEPROMThermalMeter = EEPROM_Default_ThermalMeter;
6219 //}
6220
6221 RT_TRACE(COMP_INIT, "PwDiff = %#x\n", priv->EEPROMTxPowerDiff);
6222 RT_TRACE(COMP_INIT, "ThermalMeter = %#x\n", priv->EEPROMThermalMeter);
6223
6224 //
6225 // Read Tx Power gain offset of legacy OFDM to HT rate.
6226 // Read CrystalCap from EEPROM
6227 //
6228 //if(!priv->AutoloadFailFlag)
6229 {
6230 priv->EEPROMCrystalCap = *(u8 *)&hwinfo[EEPROM_CrystalCap];
6231 }
6232 //else
6233 //{
6234 // priv->EEPROMCrystalCap = EEPROM_Default_CrystalCap;
6235 //}
6236
6237 RT_TRACE(COMP_INIT, "CrystalCap = %#x\n", priv->EEPROMCrystalCap);
6238
6239 //
6240 // Get Tx Power Base.
6241 //
6242 //if(!priv->AutoloadFailFlag)
6243 {
6244 priv->EEPROMTxPwrBase = *(u8 *)&hwinfo[EEPROM_TxPowerBase];
6245 }
6246 //else
6247 //{
6248 // priv->EEPROMTxPwrBase = EEPROM_Default_TxPowerBase;
6249 //}
6250
6251 RT_TRACE(COMP_INIT, "TxPwrBase = %#x\n", priv->EEPROMTxPwrBase);
6252
6253
6254 //
6255 // Get TSSI value for each path.
6256 //
6257 //if(!priv->AutoloadFailFlag)
6258 {
6259 priv->EEPROMTSSI_A = *(u8 *)&hwinfo[EEPROM_TSSI_A];
6260 priv->EEPROMTSSI_B = *(u8 *)&hwinfo[EEPROM_TSSI_B];
6261 }
6262 //else
6263 //{ // Default setting for Empty EEPROM
6264 // priv->EEPROMTSSI_A = EEPROM_Default_TSSI;
6265 // priv->EEPROMTSSI_B = EEPROM_Default_TSSI;
6266 //}
6267
6268 RT_TRACE(COMP_INIT, "TSSI_A = %#x, TSSI_B = %#x\n", priv->EEPROMTSSI_A, priv->EEPROMTSSI_B);
6269
6270 //
6271 // Get Tx Power tracking mode.
6272 //
6273 //if(!priv->AutoloadFailFlag)
6274 {
6275 priv->EEPROMTxPwrTkMode = *(u8 *)&hwinfo[EEPROM_TxPwTkMode];
6276 }
6277
6278 RT_TRACE(COMP_INIT, "TxPwrTkMod = %#x\n", priv->EEPROMTxPwrTkMode);
6279
6280
6281#ifdef EEPROM_OLD_FORMAT_SUPPORT
6282
6283 //
6284 // <Roger_Notes> The following settings are EFUSE version dependence.
6285 // So we need to adjust reading offset.
6286 // 2008.11.22.
6287 //
6288 {
6289 //
6290 // Get HT 2T Path A and B Power Index.
6291 //
6292 //if(!priv->AutoloadFailFlag)
6293 {
6294 for(i=0; i<6; i++)
6295 {
6296 priv->EEPROMHT2T_TxPwr[i] = *(u8 *)&hwinfo[EEPROM_HT2T_CH1_A+i];
6297 }
6298 }
6299
6300 //RT_PRINT_DATA(COMP_EFUSE, "HT2T TxPwr: \n"), pHalData->EEPROMHT2T_TxPwr, 6);
6301
6302 //
6303 // Get CCK and OFDM Tx Power Index.
6304 //
6305 //if(!priv->AutoloadFailFlag)
6306 {
6307 for(i=0; i<14; i++)
6308 {
6309 priv->EEPROMTxPowerLevelCCK24G[i] = *(u8 *)&hwinfo[EEPROM_TxPwIndex_CCK_24G+i];
6310 priv->EEPROMTxPowerLevelOFDM24G[i] = *(u8 *)&hwinfo[EEPROM_TxPwIndex_OFDM_24G+i];
6311 }
6312 }
6313
6314 //RT_PRINT_DATA(COMP_EFUSE, DBG_LOUD, ("CCK 2.4G TxPwr: \n"), pHalData->EEPROMTxPowerLevelCCK24G, 14);
6315 //RT_PRINT_DATA(COMP_EFUSE, DBG_LOUD, ("OFDM 2.4G TxPwr: \n"), pHalData->EEPROMTxPowerLevelOFDM24G, 14);
6316
6317 //
6318 // Update HAL variables.
6319 //
6320 memcpy( priv->TxPowerLevelOFDM24G, priv->EEPROMTxPowerLevelOFDM24G, 14);
6321 memcpy( priv->TxPowerLevelCCK, priv->EEPROMTxPowerLevelCCK24G, 14);
6322 //RT_PRINT_DATA(COMP_EFUSE, DBG_LOUD, ("HAL CCK 2.4G TxPwr: \n"), pHalData->TxPowerLevelCCK, 14);
6323 //RT_PRINT_DATA(COMP_EFUSE, DBG_LOUD, ("HAL OFDM 2.4G TxPwr: \n"), pHalData->TxPowerLevelOFDM24G, 14);
6324
6325 }
6326#else // Support new version of EFUSE content, 2008.11.22.
6327 {
6328 //
6329 // Buffer TxPwIdx(i.e., from offset 0x55~0x66, total 18Bytes)
6330 // Update CCK, OFDM (1T/2T)Tx Power Index from above buffer.
6331 //
6332
6333 //
6334 // Get Tx Power Level by Channel
6335 //
6336 //if(!priv->AutoloadFailFlag)
6337 {
6338 // Read Tx power of Channel 1 ~ 14 from EFUSE.
6339 // 92S suupport RF A & B
6340 for (rf_path = 0; rf_path < 2; rf_path++)
6341 {
6342 for (i = 0; i < 3; i++)
6343 {
6344 // Read CCK RF A & B Tx power
6345 priv->RfCckChnlAreaTxPwr[rf_path][i] =
6346 hwinfo[EEPROM_TxPwIndex+rf_path*3+i];
6347
6348 // Read OFDM RF A & B Tx power for 1T
6349 priv->RfOfdmChnlAreaTxPwr1T[rf_path][i] =
6350 hwinfo[EEPROM_TxPwIndex+6+rf_path*3+i];
6351
6352 // Read OFDM RF A & B Tx power for 2T
6353 priv->RfOfdmChnlAreaTxPwr2T[rf_path][i] =
6354 hwinfo[EEPROM_TxPwIndex+12+rf_path*3+i];
6355 }
6356 }
6357
6358 }
6359//
6360 // Update Tx Power HAL variables.
6361//
6362 for (rf_path = 0; rf_path < 2; rf_path++)
6363 {
6364 for (i = 0; i < 3; i++)
6365 {
6366 RT_TRACE((COMP_INIT), "CCK RF-%d CHan_Area-%d = 0x%x\n", rf_path, i,
6367 priv->RfCckChnlAreaTxPwr[rf_path][i]);
6368 RT_TRACE((COMP_INIT), "OFDM-1T RF-%d CHan_Area-%d = 0x%x\n", rf_path, i,
6369 priv->RfOfdmChnlAreaTxPwr1T[rf_path][i]);
6370 RT_TRACE((COMP_INIT), "OFDM-2T RF-%d CHan_Area-%d = 0x%x\n", rf_path, i, priv->RfOfdmChnlAreaTxPwr2T[rf_path][i]);
6371 }
6372
6373 // Assign dedicated channel tx power
6374 for(i=0; i<14; i++) // channel 1~3 use the same Tx Power Level.
6375 {
6376 if (i < 3) // Cjanel 1-3
6377 index = 0;
6378 else if (i < 9) // Channel 4-9
6379 index = 1;
6380 else // Channel 10-14
6381 index = 2;
6382
6383 // Record A & B CCK /OFDM - 1T/2T Channel area tx power
6384 priv->RfTxPwrLevelCck[rf_path][i] =
6385 priv->RfCckChnlAreaTxPwr[rf_path][index];
6386 priv->RfTxPwrLevelOfdm1T[rf_path][i] =
6387 priv->RfOfdmChnlAreaTxPwr1T[rf_path][index];
6388 priv->RfTxPwrLevelOfdm2T[rf_path][i] =
6389 priv->RfOfdmChnlAreaTxPwr2T[rf_path][index];
6390 if (rf_path == 0)
6391 {
6392 priv->TxPowerLevelOFDM24G[i] = priv->RfTxPwrLevelOfdm1T[rf_path][i] ;
6393 priv->TxPowerLevelCCK[i] = priv->RfTxPwrLevelCck[rf_path][i];
6394 }
6395 }
6396
6397 for(i=0; i<14; i++)
6398 {
6399 RT_TRACE((COMP_INIT),
6400 "Rf-%d TxPwr CH-%d CCK OFDM_1T OFDM_2T= 0x%x/0x%x/0x%x\n",
6401 rf_path, i, priv->RfTxPwrLevelCck[rf_path][i],
6402 priv->RfTxPwrLevelOfdm1T[rf_path][i] ,
6403 priv->RfTxPwrLevelOfdm2T[rf_path][i] );
6404 }
6405 }
6406 }
6407
6408 //
6409 // 2009/02/09 Cosa add for new EEPROM format
6410 //
6411 for(i=0; i<14; i++) // channel 1~3 use the same Tx Power Level.
6412 {
6413 // Read tx power difference between HT OFDM 20/40 MHZ
6414 if (i < 3) // Cjanel 1-3
6415 index = 0;
6416 else if (i < 9) // Channel 4-9
6417 index = 1;
6418 else // Channel 10-14
6419 index = 2;
6420
6421 tempval = (*(u8 *)&hwinfo[EEPROM_TX_PWR_HT20_DIFF+index])&0xff;
6422 priv->TxPwrHt20Diff[RF90_PATH_A][i] = (tempval&0xF);
6423 priv->TxPwrHt20Diff[RF90_PATH_B][i] = ((tempval>>4)&0xF);
6424
6425 // Read OFDM<->HT tx power diff
6426 if (i < 3) // Cjanel 1-3
6427 tempval = (*(u8 *)&hwinfo[EEPROM_TX_PWR_OFDM_DIFF])&0xff;
6428 else if (i < 9) // Channel 4-9
6429 tempval = (*(u8 *)&hwinfo[EEPROM_PwDiff])&0xff;
6430 else // Channel 10-14
6431 tempval = (*(u8 *)&hwinfo[EEPROM_TX_PWR_OFDM_DIFF+1])&0xff;
6432
6433 //cosa tempval = (*(u1Byte *)&hwinfo[EEPROM_TX_PWR_OFDM_DIFF+index])&0xff;
6434 priv->TxPwrLegacyHtDiff[RF90_PATH_A][i] = (tempval&0xF);
6435 priv->TxPwrLegacyHtDiff[RF90_PATH_B][i] = ((tempval>>4)&0xF);
6436
6437 //
6438 // Read Band Edge tx power offset and check if user enable the ability
6439 //
6440 // HT 40 band edge channel
6441 tempval = (*(u8 *)&hwinfo[EEPROM_TX_PWR_BAND_EDGE])&0xff;
6442 priv->TxPwrbandEdgeHt40[RF90_PATH_A][0] = (tempval&0xF); // Band edge low channel
6443 priv->TxPwrbandEdgeHt40[RF90_PATH_A][1] = ((tempval>>4)&0xF); // Band edge high channel
6444 tempval = (*(u8 *)&hwinfo[EEPROM_TX_PWR_BAND_EDGE+1])&0xff;
6445 priv->TxPwrbandEdgeHt40[RF90_PATH_B][0] = (tempval&0xF); // Band edge low channel
6446 priv->TxPwrbandEdgeHt40[RF90_PATH_B][1] = ((tempval>>4)&0xF); // Band edge high channel
6447 // HT 20 band edge channel
6448 tempval = (*(u8 *)&hwinfo[EEPROM_TX_PWR_BAND_EDGE+2])&0xff;
6449 priv->TxPwrbandEdgeHt20[RF90_PATH_A][0] = (tempval&0xF); // Band edge low channel
6450 priv->TxPwrbandEdgeHt20[RF90_PATH_A][1] = ((tempval>>4)&0xF); // Band edge high channel
6451 tempval = (*(u8 *)&hwinfo[EEPROM_TX_PWR_BAND_EDGE+3])&0xff;
6452 priv->TxPwrbandEdgeHt20[RF90_PATH_B][0] = (tempval&0xF); // Band edge low channel
6453 priv->TxPwrbandEdgeHt20[RF90_PATH_B][1] = ((tempval>>4)&0xF); // Band edge high channel
6454 // OFDM band edge channel
6455 tempval = (*(u8 *)&hwinfo[EEPROM_TX_PWR_BAND_EDGE+4])&0xff;
6456 priv->TxPwrbandEdgeLegacyOfdm[RF90_PATH_A][0] = (tempval&0xF); // Band edge low channel
6457 priv->TxPwrbandEdgeLegacyOfdm[RF90_PATH_A][1] = ((tempval>>4)&0xF); // Band edge high channel
6458 tempval = (*(u8 *)&hwinfo[EEPROM_TX_PWR_BAND_EDGE+5])&0xff;
6459 priv->TxPwrbandEdgeLegacyOfdm[RF90_PATH_B][0] = (tempval&0xF); // Band edge low channel
6460 priv->TxPwrbandEdgeLegacyOfdm[RF90_PATH_B][1] = ((tempval>>4)&0xF); // Band edge high channel
6461
6462 priv->TxPwrbandEdgeFlag = (*(u8 *)&hwinfo[TX_PWR_BAND_EDGE_CHK]);
6463 }
6464
6465 for(i=0; i<14; i++)
6466 RT_TRACE(COMP_INIT, "RF-A Ht20 to HT40 Diff[%d] = 0x%x\n", i, priv->TxPwrHt20Diff[RF90_PATH_A][i]);
6467 for(i=0; i<14; i++)
6468 RT_TRACE(COMP_INIT, "RF-A Legacy to Ht40 Diff[%d] = 0x%x\n", i, priv->TxPwrLegacyHtDiff[RF90_PATH_A][i]);
6469 for(i=0; i<14; i++)
6470 RT_TRACE(COMP_INIT, "RF-B Ht20 to HT40 Diff[%d] = 0x%x\n", i, priv->TxPwrHt20Diff[RF90_PATH_B][i]);
6471 for(i=0; i<14; i++)
6472 RT_TRACE(COMP_INIT, "RF-B Legacy to HT40 Diff[%d] = 0x%x\n", i, priv->TxPwrLegacyHtDiff[RF90_PATH_B][i]);
6473 RT_TRACE(COMP_INIT, "RF-A HT40 band-edge low/high power diff = 0x%x/0x%x\n",
6474 priv->TxPwrbandEdgeHt40[RF90_PATH_A][0],
6475 priv->TxPwrbandEdgeHt40[RF90_PATH_A][1]);
6476 RT_TRACE((COMP_INIT&COMP_DBG), "RF-B HT40 band-edge low/high power diff = 0x%x/0x%x\n",
6477 priv->TxPwrbandEdgeHt40[RF90_PATH_B][0],
6478 priv->TxPwrbandEdgeHt40[RF90_PATH_B][1]);
6479
6480 RT_TRACE((COMP_INIT&COMP_DBG), "RF-A HT20 band-edge low/high power diff = 0x%x/0x%x\n",
6481 priv->TxPwrbandEdgeHt20[RF90_PATH_A][0],
6482 priv->TxPwrbandEdgeHt20[RF90_PATH_A][1]);
6483 RT_TRACE((COMP_INIT&COMP_DBG), "RF-B HT20 band-edge low/high power diff = 0x%x/0x%x\n",
6484 priv->TxPwrbandEdgeHt20[RF90_PATH_B][0],
6485 priv->TxPwrbandEdgeHt20[RF90_PATH_B][1]);
6486
6487 RT_TRACE((COMP_INIT&COMP_DBG), "RF-A OFDM band-edge low/high power diff = 0x%x/0x%x\n",
6488 priv->TxPwrbandEdgeLegacyOfdm[RF90_PATH_A][0],
6489 priv->TxPwrbandEdgeLegacyOfdm[RF90_PATH_A][1]);
6490 RT_TRACE((COMP_INIT&COMP_DBG), "RF-B OFDM band-edge low/high power diff = 0x%x/0x%x\n",
6491 priv->TxPwrbandEdgeLegacyOfdm[RF90_PATH_B][0],
6492 priv->TxPwrbandEdgeLegacyOfdm[RF90_PATH_B][1]);
6493 RT_TRACE((COMP_INIT&COMP_DBG), "Band-edge enable flag = %d\n", priv->TxPwrbandEdgeFlag);
6494#endif
6495
6496 //
6497 // Update remained HAL variables.
6498 //
6499 priv->TSSI_13dBm = priv->EEPROMThermalMeter *100;
6500 priv->LegacyHTTxPowerDiff = priv->EEPROMTxPowerDiff;
6501 priv->TxPowerDiff = priv->EEPROMTxPowerDiff;
6502 //priv->AntennaTxPwDiff[0] = (priv->EEPROMTxPowerDiff & 0xf);// Antenna B gain offset to antenna A, bit[3:0]
6503 //priv->AntennaTxPwDiff[1] = ((priv->EEPROMTxPowerDiff & 0xf0)>>4);// Antenna C gain offset to antenna A, bit[7:4]
6504 priv->CrystalCap = priv->EEPROMCrystalCap; // CrystalCap, bit[15:12]
6505 priv->ThermalMeter[0] = (priv->EEPROMThermalMeter&0x1f);// ThermalMeter, bit0~3 for RFIC1, bit4~7 for RFIC2
6506 priv->LedStrategy = SW_LED_MODE0;
6507
6508 init_rate_adaptive(dev);
6509
6510 RT_TRACE(COMP_INIT, "<==== ReadAdapterInfo8192SUsb\n");
6511
6512 //return RT_STATUS_SUCCESS;
6513}
6514
6515
6516//
6517// Description:
6518// Read HW adapter information by E-Fuse or EEPROM according CR9346 reported.
6519//
6520// Assumption:
6521// 1. CR9346 regiser has verified.
6522// 2. PASSIVE_LEVEL (USB interface)
6523//
6524// Created by Roger, 2008.10.21.
6525//
6526static void rtl8192SU_read_eeprom_info(struct net_device *dev)
6527{
6528 struct r8192_priv *priv = ieee80211_priv(dev);
6529 u8 tmpU1b;
6530
6531 RT_TRACE(COMP_INIT, "====> ReadAdapterInfo8192SUsb\n");
6532
6533 // Retrieve Chip version.
6534 priv->card_8192_version = (VERSION_8192S)((read_nic_dword(dev, PMC_FSM)>>16)&0xF);
6535 RT_TRACE(COMP_INIT, "Chip Version ID: 0x%2x\n", priv->card_8192_version);
6536
6537 tmpU1b = read_nic_byte(dev, EPROM_CMD);//CR9346
6538
6539 // To check system boot selection.
6540 if (tmpU1b & CmdEERPOMSEL)
6541 {
6542 RT_TRACE(COMP_INIT, "Boot from EEPROM\n");
6543 priv->EepromOrEfuse = TRUE;
6544 }
6545 else
6546 {
6547 RT_TRACE(COMP_INIT, "Boot from EFUSE\n");
6548 priv->EepromOrEfuse = FALSE;
6549 }
6550
6551 // To check autoload success or not.
6552 if (tmpU1b & CmdEEPROM_En)
6553 {
6554 RT_TRACE(COMP_INIT, "Autoload OK!!\n");
6555 priv->AutoloadFailFlag=FALSE;
6556 rtl8192SU_ReadAdapterInfo8192SUsb(dev);//eeprom or e-fuse
6557 }
6558 else
6559 { // Auto load fail.
6560 RT_TRACE(COMP_INIT, "AutoLoad Fail reported from CR9346!!\n");
6561 priv->AutoloadFailFlag=TRUE;
6562 rtl8192SU_ConfigAdapterInfo8192SForAutoLoadFail(dev);
6563
6564 //if (IS_BOOT_FROM_EFUSE(Adapter))
6565 if(!priv->EepromOrEfuse)
6566 {
6567 RT_TRACE(COMP_INIT, "Update shadow map for EFuse future use!!\n");
6568 EFUSE_ShadowMapUpdate(dev);
6569 }
6570 }
6571#ifdef TO_DO_LIST
6572 if((priv->RegChannelPlan >= RT_CHANNEL_DOMAIN_MAX) || (pHalData->EEPROMChannelPlan & EEPROM_CHANNEL_PLAN_BY_HW_MASK))
6573 {
6574 pMgntInfo->ChannelPlan = HalMapChannelPlan8192S(Adapter, (pHalData->EEPROMChannelPlan & (~(EEPROM_CHANNEL_PLAN_BY_HW_MASK))));
6575 pMgntInfo->bChnlPlanFromHW = (pHalData->EEPROMChannelPlan & EEPROM_CHANNEL_PLAN_BY_HW_MASK) ? TRUE : FALSE; // User cannot change channel plan.
6576 }
6577 else
6578 {
6579 pMgntInfo->ChannelPlan = (RT_CHANNEL_DOMAIN)pMgntInfo->RegChannelPlan;
6580 }
6581
6582 switch(pMgntInfo->ChannelPlan)
6583 {
6584 case RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN:
6585 {
6586 PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(pMgntInfo);
6587
6588 pDot11dInfo->bEnabled = TRUE;
6589 }
6590 RT_TRACE(COMP_INIT, DBG_LOUD, ("ReadAdapterInfo8187(): Enable dot11d when RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN!\n"));
6591 break;
6592 }
6593
6594 RT_TRACE(COMP_INIT, DBG_LOUD, ("RegChannelPlan(%d) EEPROMChannelPlan(%d)", pMgntInfo->RegChannelPlan, pHalData->EEPROMChannelPlan));
6595 RT_TRACE(COMP_INIT, DBG_LOUD, ("ChannelPlan = %d\n" , pMgntInfo->ChannelPlan));
6596
6597 RT_TRACE(COMP_INIT, DBG_LOUD, ("<==== ReadAdapterInfo8192S\n"));
6598#endif
6599
6600 RT_TRACE(COMP_INIT, "<==== ReadAdapterInfo8192SUsb\n");
6601
6602 //return RT_STATUS_SUCCESS;
6603}
6604#else
6605static void rtl8192_read_eeprom_info(struct net_device* dev)
6606{
6607 u16 wEPROM_ID = 0;
6608 u8 bMac_Tmp_Addr[6] = {0x00, 0xe0, 0x4c, 0x00, 0x00, 0x02};
6609 u8 bLoad_From_EEPOM = false;
6610 struct r8192_priv *priv = ieee80211_priv(dev);
6611 u16 tmpValue = 0;
6612 RT_TRACE(COMP_EPROM, "===========>%s()\n", __FUNCTION__);
6613 wEPROM_ID = eprom_read(dev, 0); //first read EEPROM ID out;
6614 RT_TRACE(COMP_EPROM, "EEPROM ID is 0x%x\n", wEPROM_ID);
6615
6616 if (wEPROM_ID != RTL8190_EEPROM_ID)
6617 {
6618 RT_TRACE(COMP_ERR, "EEPROM ID is invalid(is 0x%x(should be 0x%x)\n", wEPROM_ID, RTL8190_EEPROM_ID);
6619 }
6620 else
6621 bLoad_From_EEPOM = true;
6622
6623 if (bLoad_From_EEPOM)
6624 {
6625 tmpValue = eprom_read(dev, (EEPROM_VID>>1));
6626 priv->eeprom_vid = endian_swap(&tmpValue);
6627 priv->eeprom_pid = eprom_read(dev, (EEPROM_PID>>1));
6628 tmpValue = eprom_read(dev, (EEPROM_ChannelPlan>>1));
6629 priv->eeprom_ChannelPlan =((tmpValue&0xff00)>>8);
6630 priv->btxpowerdata_readfromEEPORM = true;
6631 priv->eeprom_CustomerID = eprom_read(dev, (EEPROM_Customer_ID>>1)) >>8;
6632 }
6633 else
6634 {
6635 priv->eeprom_vid = 0;
6636 priv->eeprom_pid = 0;
6637 priv->card_8192_version = VERSION_819xU_B;
6638 priv->eeprom_ChannelPlan = 0;
6639 priv->eeprom_CustomerID = 0;
6640 }
6641 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);
6642 //set channelplan from eeprom
6643 priv->ChannelPlan = priv->eeprom_ChannelPlan;
6644 if (bLoad_From_EEPOM)
6645 {
6646 int i;
6647 for (i=0; i<6; i+=2)
6648 {
6649 u16 tmp = 0;
6650 tmp = eprom_read(dev, (u16)((EEPROM_NODE_ADDRESS_BYTE_0 + i)>>1));
6651 *(u16*)(&dev->dev_addr[i]) = tmp;
6652 }
6653 }
6654 else
6655 {
6656 memcpy(dev->dev_addr, bMac_Tmp_Addr, 6);
6657 //should I set IDR0 here?
6658 }
6659 RT_TRACE(COMP_EPROM, "MAC addr:"MAC_FMT"\n", MAC_ARG(dev->dev_addr));
6660 priv->rf_type = RTL819X_DEFAULT_RF_TYPE; //default 1T2R
6661 priv->rf_chip = RF_8256;
6662
6663 if (priv->card_8192_version == (u8)VERSION_819xU_A)
6664 {
6665 //read Tx power gain offset of legacy OFDM to HT rate
6666 if (bLoad_From_EEPOM)
6667 priv->EEPROMTxPowerDiff = (eprom_read(dev, (EEPROM_TxPowerDiff>>1))&0xff00) >> 8;
6668 else
6669 priv->EEPROMTxPowerDiff = EEPROM_Default_TxPower;
6670 RT_TRACE(COMP_EPROM, "TxPowerDiff:%d\n", priv->EEPROMTxPowerDiff);
6671 //read ThermalMeter from EEPROM
6672 if (bLoad_From_EEPOM)
6673 priv->EEPROMThermalMeter = (u8)(eprom_read(dev, (EEPROM_ThermalMeter>>1))&0x00ff);
6674 else
6675 priv->EEPROMThermalMeter = EEPROM_Default_ThermalMeter;
6676 RT_TRACE(COMP_EPROM, "ThermalMeter:%d\n", priv->EEPROMThermalMeter);
6677 //vivi, for tx power track
6678 priv->TSSI_13dBm = priv->EEPROMThermalMeter *100;
6679 //read antenna tx power offset of B/C/D to A from EEPROM
6680 if (bLoad_From_EEPOM)
6681 priv->EEPROMPwDiff = (eprom_read(dev, (EEPROM_PwDiff>>1))&0x0f00)>>8;
6682 else
6683 priv->EEPROMPwDiff = EEPROM_Default_PwDiff;
6684 RT_TRACE(COMP_EPROM, "TxPwDiff:%d\n", priv->EEPROMPwDiff);
6685 // Read CrystalCap from EEPROM
6686 if (bLoad_From_EEPOM)
6687 priv->EEPROMCrystalCap = (eprom_read(dev, (EEPROM_CrystalCap>>1))&0x0f);
6688 else
6689 priv->EEPROMCrystalCap = EEPROM_Default_CrystalCap;
6690 RT_TRACE(COMP_EPROM, "CrystalCap = %d\n", priv->EEPROMCrystalCap);
6691 //get per-channel Tx power level
6692 if (bLoad_From_EEPOM)
6693 priv->EEPROM_Def_Ver = (eprom_read(dev, (EEPROM_TxPwIndex_Ver>>1))&0xff00)>>8;
6694 else
6695 priv->EEPROM_Def_Ver = 1;
6696 RT_TRACE(COMP_EPROM, "EEPROM_DEF_VER:%d\n", priv->EEPROM_Def_Ver);
6697 if (priv->EEPROM_Def_Ver == 0) //old eeprom definition
6698 {
6699 int i;
6700 if (bLoad_From_EEPOM)
6701 priv->EEPROMTxPowerLevelCCK = (eprom_read(dev, (EEPROM_TxPwIndex_CCK>>1))&0xff) >> 8;
6702 else
6703 priv->EEPROMTxPowerLevelCCK = 0x10;
6704 RT_TRACE(COMP_EPROM, "CCK Tx Power Levl: 0x%02x\n", priv->EEPROMTxPowerLevelCCK);
6705 for (i=0; i<3; i++)
6706 {
6707 if (bLoad_From_EEPOM)
6708 {
6709 tmpValue = eprom_read(dev, (EEPROM_TxPwIndex_OFDM_24G+i)>>1);
6710 if (((EEPROM_TxPwIndex_OFDM_24G+i) % 2) == 0)
6711 tmpValue = tmpValue & 0x00ff;
6712 else
6713 tmpValue = (tmpValue & 0xff00) >> 8;
6714 }
6715 else
6716 tmpValue = 0x10;
6717 priv->EEPROMTxPowerLevelOFDM24G[i] = (u8) tmpValue;
6718 RT_TRACE(COMP_EPROM, "OFDM 2.4G Tx Power Level, Index %d = 0x%02x\n", i, priv->EEPROMTxPowerLevelCCK);
6719 }
6720 }//end if EEPROM_DEF_VER == 0
6721 else if (priv->EEPROM_Def_Ver == 1)
6722 {
6723 if (bLoad_From_EEPOM)
6724 {
6725 tmpValue = eprom_read(dev, (EEPROM_TxPwIndex_CCK_V1>>1));
6726 tmpValue = (tmpValue & 0xff00) >> 8;
6727 }
6728 else
6729 tmpValue = 0x10;
6730 priv->EEPROMTxPowerLevelCCK_V1[0] = (u8)tmpValue;
6731
6732 if (bLoad_From_EEPOM)
6733 tmpValue = eprom_read(dev, (EEPROM_TxPwIndex_CCK_V1 + 2)>>1);
6734 else
6735 tmpValue = 0x1010;
6736 *((u16*)(&priv->EEPROMTxPowerLevelCCK_V1[1])) = tmpValue;
6737 if (bLoad_From_EEPOM)
6738 tmpValue = eprom_read(dev, (EEPROM_TxPwIndex_OFDM_24G_V1>>1));
6739 else
6740 tmpValue = 0x1010;
6741 *((u16*)(&priv->EEPROMTxPowerLevelOFDM24G[0])) = tmpValue;
6742 if (bLoad_From_EEPOM)
6743 tmpValue = eprom_read(dev, (EEPROM_TxPwIndex_OFDM_24G_V1+2)>>1);
6744 else
6745 tmpValue = 0x10;
6746 priv->EEPROMTxPowerLevelOFDM24G[2] = (u8)tmpValue;
6747 }//endif EEPROM_Def_Ver == 1
6748
6749 //update HAL variables
6750 //
6751 {
6752 int i;
6753 for (i=0; i<14; i++)
6754 {
6755 if (i<=3)
6756 priv->TxPowerLevelOFDM24G[i] = priv->EEPROMTxPowerLevelOFDM24G[0];
6757 else if (i>=4 && i<=9)
6758 priv->TxPowerLevelOFDM24G[i] = priv->EEPROMTxPowerLevelOFDM24G[1];
6759 else
6760 priv->TxPowerLevelOFDM24G[i] = priv->EEPROMTxPowerLevelOFDM24G[2];
6761 }
6762
6763 for (i=0; i<14; i++)
6764 {
6765 if (priv->EEPROM_Def_Ver == 0)
6766 {
6767 if (i<=3)
6768 priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelOFDM24G[0] + (priv->EEPROMTxPowerLevelCCK - priv->EEPROMTxPowerLevelOFDM24G[1]);
6769 else if (i>=4 && i<=9)
6770 priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelCCK;
6771 else
6772 priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelOFDM24G[2] + (priv->EEPROMTxPowerLevelCCK - priv->EEPROMTxPowerLevelOFDM24G[1]);
6773 }
6774 else if (priv->EEPROM_Def_Ver == 1)
6775 {
6776 if (i<=3)
6777 priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelCCK_V1[0];
6778 else if (i>=4 && i<=9)
6779 priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelCCK_V1[1];
6780 else
6781 priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelCCK_V1[2];
6782 }
6783 }
6784 }//end update HAL variables
6785 priv->TxPowerDiff = priv->EEPROMPwDiff;
6786// Antenna B gain offset to antenna A, bit0~3
6787 priv->AntennaTxPwDiff[0] = (priv->EEPROMTxPowerDiff & 0xf);
6788 // Antenna C gain offset to antenna A, bit4~7
6789 priv->AntennaTxPwDiff[1] = ((priv->EEPROMTxPowerDiff & 0xf0)>>4);
6790 // CrystalCap, bit12~15
6791 priv->CrystalCap = priv->EEPROMCrystalCap;
6792 // ThermalMeter, bit0~3 for RFIC1, bit4~7 for RFIC2
6793 // 92U does not enable TX power tracking.
6794 priv->ThermalMeter[0] = priv->EEPROMThermalMeter;
6795 }//end if VersionID == VERSION_819xU_A
6796
6797//added by vivi, for dlink led, 20080416
6798 switch(priv->eeprom_CustomerID)
6799 {
6800 case EEPROM_CID_RUNTOP:
6801 priv->CustomerID = RT_CID_819x_RUNTOP;
6802 break;
6803
6804 case EEPROM_CID_DLINK:
6805 priv->CustomerID = RT_CID_DLINK;
6806 break;
6807
6808 default:
6809 priv->CustomerID = RT_CID_DEFAULT;
6810 break;
6811
6812 }
6813
6814 switch(priv->CustomerID)
6815 {
6816 case RT_CID_819x_RUNTOP:
6817 priv->LedStrategy = SW_LED_MODE2;
6818 break;
6819
6820 case RT_CID_DLINK:
6821 priv->LedStrategy = SW_LED_MODE4;
6822 break;
6823
6824 default:
6825 priv->LedStrategy = SW_LED_MODE0;
6826 break;
6827
6828 }
6829
6830
6831 if(priv->rf_type == RF_1T2R)
6832 {
6833 RT_TRACE(COMP_EPROM, "\n1T2R config\n");
6834 }
6835 else
6836 {
6837 RT_TRACE(COMP_EPROM, "\n2T4R config\n");
6838 }
6839
6840 // 2008/01/16 MH We can only know RF type in the function. So we have to init
6841 // DIG RATR table again.
6842 init_rate_adaptive(dev);
6843 //we need init DIG RATR table here again.
6844
6845 RT_TRACE(COMP_EPROM, "<===========%s()\n", __FUNCTION__);
6846 return;
6847}
6848#endif
6849
6850short rtl8192_get_channel_map(struct net_device * dev)
6851{
6852 struct r8192_priv *priv = ieee80211_priv(dev);
6853#ifdef ENABLE_DOT11D
6854 if(priv->ChannelPlan > COUNTRY_CODE_GLOBAL_DOMAIN){
6855 printk("rtl8180_init:Error channel plan! Set to default.\n");
6856 priv->ChannelPlan= 0;
6857 }
6858 RT_TRACE(COMP_INIT, "Channel plan is %d\n",priv->ChannelPlan);
6859
6860 rtl819x_set_channel_map(priv->ChannelPlan, priv);
6861#else
6862 int ch,i;
6863 //Set Default Channel Plan
6864 if(!channels){
6865 DMESG("No channels, aborting");
6866 return -1;
6867 }
6868 ch=channels;
6869 priv->ChannelPlan= 0;//hikaru
6870 // set channels 1..14 allowed in given locale
6871 for (i=1; i<=14; i++) {
6872 (priv->ieee80211->channel_map)[i] = (u8)(ch & 0x01);
6873 ch >>= 1;
6874 }
6875#endif
6876 return 0;
6877}
6878
6879short rtl8192_init(struct net_device *dev)
6880{
6881
6882 struct r8192_priv *priv = ieee80211_priv(dev);
6883
6884#ifndef RTL8192SU
6885 memset(&(priv->stats),0,sizeof(struct Stats));
6886 memset(priv->txqueue_to_outpipemap,0,9);
6887#ifdef PIPE12
6888 {
6889 int i=0;
6890 u8 queuetopipe[]={3,2,1,0,4,8,7,6,5};
6891 memcpy(priv->txqueue_to_outpipemap,queuetopipe,9);
6892/* for(i=0;i<9;i++)
6893 printk("%d ",priv->txqueue_to_outpipemap[i]);
6894 printk("\n");*/
6895 }
6896#else
6897 {
6898 u8 queuetopipe[]={3,2,1,0,4,4,0,4,4};
6899 memcpy(priv->txqueue_to_outpipemap,queuetopipe,9);
6900/* for(i=0;i<9;i++)
6901 printk("%d ",priv->txqueue_to_outpipemap[i]);
6902 printk("\n");*/
6903 }
6904#endif
6905#endif
6906 rtl8192_init_priv_variable(dev);
6907 rtl8192_init_priv_lock(priv);
6908 rtl8192_init_priv_task(dev);
6909 rtl8192_get_eeprom_size(dev);
6910 priv->ops->rtl819x_read_eeprom_info(dev);
6911 rtl8192_get_channel_map(dev);
6912 init_hal_dm(dev);
6913 init_timer(&priv->watch_dog_timer);
6914 priv->watch_dog_timer.data = (unsigned long)dev;
6915 priv->watch_dog_timer.function = watch_dog_timer_callback;
6916
6917 //rtl8192_adapter_start(dev);
6918#ifdef DEBUG_EPROM
6919 dump_eprom(dev);
6920#endif
6921 return 0;
6922}
6923
6924/******************************************************************************
6925 *function: This function actually only set RRSR, RATR and BW_OPMODE registers
6926 * not to do all the hw config as its name says
6927 * input: net_device dev
6928 * output: none
6929 * return: none
6930 * notice: This part need to modified according to the rate set we filtered
6931 * ****************************************************************************/
6932void rtl8192_hwconfig(struct net_device* dev)
6933{
6934 u32 regRATR = 0, regRRSR = 0;
6935 u8 regBwOpMode = 0, regTmp = 0;
6936 struct r8192_priv *priv = ieee80211_priv(dev);
6937
6938// Set RRSR, RATR, and BW_OPMODE registers
6939 //
6940 switch(priv->ieee80211->mode)
6941 {
6942 case WIRELESS_MODE_B:
6943 regBwOpMode = BW_OPMODE_20MHZ;
6944 regRATR = RATE_ALL_CCK;
6945 regRRSR = RATE_ALL_CCK;
6946 break;
6947 case WIRELESS_MODE_A:
6948 regBwOpMode = BW_OPMODE_5G |BW_OPMODE_20MHZ;
6949 regRATR = RATE_ALL_OFDM_AG;
6950 regRRSR = RATE_ALL_OFDM_AG;
6951 break;
6952 case WIRELESS_MODE_G:
6953 regBwOpMode = BW_OPMODE_20MHZ;
6954 regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
6955 regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
6956 break;
6957 case WIRELESS_MODE_AUTO:
6958#ifdef TO_DO_LIST
6959 if (Adapter->bInHctTest)
6960 {
6961 regBwOpMode = BW_OPMODE_20MHZ;
6962 regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
6963 regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
6964 }
6965 else
6966#endif
6967 {
6968 regBwOpMode = BW_OPMODE_20MHZ;
6969 regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
6970 regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
6971 }
6972 break;
6973 case WIRELESS_MODE_N_24G:
6974 // It support CCK rate by default.
6975 // CCK rate will be filtered out only when associated AP does not support it.
6976 regBwOpMode = BW_OPMODE_20MHZ;
6977 regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
6978 regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
6979 break;
6980 case WIRELESS_MODE_N_5G:
6981 regBwOpMode = BW_OPMODE_5G;
6982 regRATR = RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
6983 regRRSR = RATE_ALL_OFDM_AG;
6984 break;
6985 }
6986
6987 write_nic_byte(dev, BW_OPMODE, regBwOpMode);
6988 {
6989 u32 ratr_value = 0;
6990 ratr_value = regRATR;
6991 if (priv->rf_type == RF_1T2R)
6992 {
6993 ratr_value &= ~(RATE_ALL_OFDM_2SS);
6994 }
6995 write_nic_dword(dev, RATR0, ratr_value);
6996 write_nic_byte(dev, UFWP, 1);
6997 }
6998 regTmp = read_nic_byte(dev, 0x313);
6999 regRRSR = ((regTmp) << 24) | (regRRSR & 0x00ffffff);
7000 write_nic_dword(dev, RRSR, regRRSR);
7001
7002 //
7003 // Set Retry Limit here
7004 //
7005 write_nic_word(dev, RETRY_LIMIT,
7006 priv->ShortRetryLimit << RETRY_LIMIT_SHORT_SHIFT | \
7007 priv->LongRetryLimit << RETRY_LIMIT_LONG_SHIFT);
7008 // Set Contention Window here
7009
7010 // Set Tx AGC
7011
7012 // Set Tx Antenna including Feedback control
7013
7014 // Set Auto Rate fallback control
7015
7016
7017}
7018
7019#ifdef RTL8192SU
7020#ifdef USB_RX_AGGREGATION_SUPPORT
7021u8 rtl8192SU_MapRxPageSizeToIdx(u16 RxPktSize )
7022{
7023 switch(RxPktSize)
7024 {
7025 case 64: return 0; break;
7026 case 128 : return 1; break;
7027 case 256: return 2; break;
7028 case 512: return 3; break;
7029 case 1024: return 4; break;
7030 default: return 0; // We use 64bytes in defult.
7031 }
7032}
7033#endif
7034
7035//
7036// Description:
7037// Initial HW relted registers.
7038//
7039// Assumption:
7040// Config RTL8192S USB MAC, we should config MAC before download FW.
7041//
7042// 2008.09.03, Added by Roger.
7043//
7044static void rtl8192SU_MacConfigBeforeFwDownloadASIC(struct net_device *dev)
7045{
7046 u8 tmpU1b;// i;
7047// u16 tmpU2b;
7048// u32 tmpU4b;
7049 u8 PollingCnt = 20;
7050
7051 RT_TRACE(COMP_INIT, "--->MacConfigBeforeFwDownloadASIC()\n");
7052
7053 //2MAC Initialization for power on sequence, Revised by Roger. 2008.09.03.
7054
7055 //
7056 //<Roger_Notes> Set control path switch to HW control and reset Digital Core, CPU Core and
7057 // MAC I/O to solve FW download fail when system from resume sate.
7058 // 2008.11.04.
7059 //
7060 tmpU1b = read_nic_byte(dev, SYS_CLKR+1);
7061 if(tmpU1b & 0x80)
7062 {
7063 tmpU1b &= 0x3f;
7064 write_nic_byte(dev, SYS_CLKR+1, tmpU1b);
7065 }
7066 // Clear FW RPWM for FW control LPS. by tynli. 2009.02.23
7067 write_nic_byte(dev, RPWM, 0x0);
7068
7069 tmpU1b = read_nic_byte(dev, SYS_FUNC_EN+1);
7070 tmpU1b &= 0x73;
7071 write_nic_byte(dev, SYS_FUNC_EN+1, tmpU1b);
7072 udelay(1000);
7073
7074 //Revised POS, suggested by SD1 Alex, 2008.09.27.
7075 write_nic_byte(dev, SPS0_CTRL+1, 0x53);
7076 write_nic_byte(dev, SPS0_CTRL, 0x57);
7077
7078 //Enable AFE Macro Block's Bandgap adn Enable AFE Macro Block's Mbias
7079 tmpU1b = read_nic_byte(dev, AFE_MISC);
7080 write_nic_byte(dev, AFE_MISC, (tmpU1b|AFE_BGEN|AFE_MBEN));
7081
7082 //Enable PLL Power (LDOA15V)
7083 tmpU1b = read_nic_byte(dev, LDOA15_CTRL);
7084 write_nic_byte(dev, LDOA15_CTRL, (tmpU1b|LDA15_EN));
7085
7086 //Enable LDOV12D block
7087 tmpU1b = read_nic_byte(dev, LDOV12D_CTRL);
7088 write_nic_byte(dev, LDOV12D_CTRL, (tmpU1b|LDV12_EN));
7089
7090 //mpU1b = read_nic_byte(Adapter, SPS1_CTRL);
7091 //write_nic_byte(dev, SPS1_CTRL, (tmpU1b|SPS1_LDEN));
7092
7093 //PlatformSleepUs(2000);
7094
7095 //Enable Switch Regulator Block
7096 //tmpU1b = read_nic_byte(Adapter, SPS1_CTRL);
7097 //write_nic_byte(dev, SPS1_CTRL, (tmpU1b|SPS1_SWEN));
7098
7099 //write_nic_dword(Adapter, SPS1_CTRL, 0x00a7b267);
7100
7101 tmpU1b = read_nic_byte(dev, SYS_ISO_CTRL+1);
7102 write_nic_byte(dev, SYS_ISO_CTRL+1, (tmpU1b|0x08));
7103
7104 //Engineer Packet CP test Enable
7105 tmpU1b = read_nic_byte(dev, SYS_FUNC_EN+1);
7106 write_nic_byte(dev, SYS_FUNC_EN+1, (tmpU1b|0x20));
7107
7108 //Support 64k IMEM, suggested by SD1 Alex.
7109 tmpU1b = read_nic_byte(dev, SYS_ISO_CTRL+1);
7110 write_nic_byte(dev, SYS_ISO_CTRL+1, (tmpU1b& 0x68));
7111
7112 //Enable AFE clock
7113 tmpU1b = read_nic_byte(dev, AFE_XTAL_CTRL+1);
7114 write_nic_byte(dev, AFE_XTAL_CTRL+1, (tmpU1b& 0xfb));
7115
7116 //Enable AFE PLL Macro Block
7117 tmpU1b = read_nic_byte(dev, AFE_PLL_CTRL);
7118 write_nic_byte(dev, AFE_PLL_CTRL, (tmpU1b|0x11));
7119
7120 //Attatch AFE PLL to MACTOP/BB/PCIe Digital
7121 tmpU1b = read_nic_byte(dev, SYS_ISO_CTRL);
7122 write_nic_byte(dev, SYS_ISO_CTRL, (tmpU1b&0xEE));
7123
7124 // Switch to 40M clock
7125 write_nic_byte(dev, SYS_CLKR, 0x00);
7126
7127 //SSC Disable
7128 tmpU1b = read_nic_byte(dev, SYS_CLKR);
7129 //write_nic_byte(dev, SYS_CLKR, (tmpU1b&0x5f));
7130 write_nic_byte(dev, SYS_CLKR, (tmpU1b|0xa0));
7131
7132 //Enable MAC clock
7133 tmpU1b = read_nic_byte(dev, SYS_CLKR+1);
7134 write_nic_byte(dev, SYS_CLKR+1, (tmpU1b|0x18));
7135
7136 //Revised POS, suggested by SD1 Alex, 2008.09.27.
7137 write_nic_byte(dev, PMC_FSM, 0x02);
7138
7139 //Enable Core digital and enable IOREG R/W
7140 tmpU1b = read_nic_byte(dev, SYS_FUNC_EN+1);
7141 write_nic_byte(dev, SYS_FUNC_EN+1, (tmpU1b|0x08));
7142
7143 //Enable REG_EN
7144 tmpU1b = read_nic_byte(dev, SYS_FUNC_EN+1);
7145 write_nic_byte(dev, SYS_FUNC_EN+1, (tmpU1b|0x80));
7146
7147 //Switch the control path to FW
7148 tmpU1b = read_nic_byte(dev, SYS_CLKR+1);
7149 write_nic_byte(dev, SYS_CLKR+1, (tmpU1b|0x80)& 0xBF);
7150
7151 write_nic_byte(dev, CMDR, 0xFC);
7152 write_nic_byte(dev, CMDR+1, 0x37);
7153
7154 //Fix the RX FIFO issue(usb error), 970410
7155 tmpU1b = read_nic_byte_E(dev, 0x5c);
7156 write_nic_byte_E(dev, 0x5c, (tmpU1b|BIT7));
7157
7158 //For power save, used this in the bit file after 970621
7159 tmpU1b = read_nic_byte(dev, SYS_CLKR);
7160 write_nic_byte(dev, SYS_CLKR, tmpU1b&(~SYS_CPU_CLKSEL));
7161
7162 // Revised for 8051 ROM code wrong operation. Added by Roger. 2008.10.16.
7163 write_nic_byte_E(dev, 0x1c, 0x80);
7164
7165 //
7166 // <Roger_EXP> To make sure that TxDMA can ready to download FW.
7167 // We should reset TxDMA if IMEM RPT was not ready.
7168 // Suggested by SD1 Alex. 2008.10.23.
7169 //
7170 do
7171 {
7172 tmpU1b = read_nic_byte(dev, TCR);
7173 if((tmpU1b & TXDMA_INIT_VALUE) == TXDMA_INIT_VALUE)
7174 break;
7175 //PlatformStallExecution(5);
7176 udelay(5);
7177 }while(PollingCnt--); // Delay 1ms
7178
7179 if(PollingCnt <= 0 )
7180 {
7181 RT_TRACE(COMP_INIT, "MacConfigBeforeFwDownloadASIC(): Polling TXDMA_INIT_VALUE timeout!! Current TCR(%#x)\n", tmpU1b);
7182 tmpU1b = read_nic_byte(dev, CMDR);
7183 write_nic_byte(dev, CMDR, tmpU1b&(~TXDMA_EN));
7184 udelay(2);
7185 write_nic_byte(dev, CMDR, tmpU1b|TXDMA_EN);// Reset TxDMA
7186 }
7187
7188
7189 RT_TRACE(COMP_INIT, "<---MacConfigBeforeFwDownloadASIC()\n");
7190}
7191#ifdef USB_RX_AGGREGATION_SUPPORT
7192void rtl8192SU_HalUsbRxAggr8192SUsb(struct net_device *dev, bool Value)
7193{
7194 struct r8192_priv *priv = ieee80211_priv((struct net_device *)dev);
7195 PRT_HIGH_THROUGHPUT pHTInfo = priv->ieee80211->pHTInfo;;
7196
7197
7198 //
7199 // <Roger_Notes> We decrease Rx page aggregated threshold in B/G mode.
7200 // 2008.10.29
7201 //
7202 if(priv->ieee80211->mode == WIRELESS_MODE_B || priv->ieee80211->mode == WIRELESS_MODE_G)
7203 {// Overwrite current settings to disable Rx Aggregation.
7204 Value = false;
7205 }
7206
7207 // Alway set Rx Aggregation to Disable if current platform is Win2K USB 1.1, by Emily
7208 //if(PLATFORM_LIMITED_RX_BUF_SIZE(Adapter))
7209 // Value = FALSE;
7210
7211 // Always set Rx Aggregation to Disable if connected AP is Realtek AP, by Joseph
7212 //if(pHTInfo->bCurrentRT2RTAggregation)
7213 // Value = FALSE;
7214
7215 // The RX aggregation may be enabled/disabled dynamically according current traffic stream.
7216 //Enable Rx aggregation if downlink traffic is busier than uplink traffic. by Guangan
7217 if(priv->bCurrentRxAggrEnable != Value)
7218 {
7219 priv->bCurrentRxAggrEnable = Value;
7220 //Adapter->HalFunc.SetHwRegHandler(Adapter, HW_VAR_USB_RX_AGGR, (pu1Byte)&pHalData->bCurrentRxAggrEnable);
7221 {
7222 //u8 Setting = ((pu1Byte)(val))[0];
7223 u8 Setting = priv->bCurrentRxAggrEnable
7224 u32 ulValue;
7225
7226 if(Setting==0)
7227 {
7228 //
7229 // <Roger_Notes> Reduce aggregated page threshold to 0x01 and set minimal threshold 0x0a.
7230 // i.e., disable Rx aggregation.
7231 //
7232 ulValue = 0x0001000a;
7233 }
7234 else
7235 {
7236 //PRT_HIGH_THROUGHPUT pHTInfo = priv->ieee80211->pHTInfo;
7237 //HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
7238
7239 if (priv->bForcedUsbRxAggr)
7240 {// Using forced settings.
7241 ulValue = priv->ForcedUsbRxAggrInfo;
7242 }
7243 else
7244 {// Using default settings.
7245
7246 ulValue = (pHTInfo->UsbRxFwAggrEn<<24) | (pHTInfo->UsbRxFwAggrPageNum<<16) |
7247 (pHTInfo->UsbRxFwAggrPacketNum<<8) | (pHTInfo->UsbRxFwAggrTimeout);
7248 }
7249 }
7250
7251 write_nic_byte(dev, RXDMA_AGG_PG_TH, (u8)((ulValue&0xff0000)>>16));
7252 write_nic_byte_E(dev, USB_RX_AGG_TIMEOUT, (u8)(ulValue&0xff));
7253
7254 priv->LastUsbRxAggrInfoSetting = ulValue;
7255
7256 RT_TRACE(COMP_HT|COMP_RECV, "Set HW_VAR_USB_RX_AGGR: ulValue(%#x)\n", ulValue);
7257 }
7258 RT_TRACE(COMP_RECV, "HalUsbRxAggr8192SUsb() : Set RxAggregation to %s\n", Value?"ON":"OFF");
7259 }
7260
7261}
7262#endif
7263
7264#ifdef USB_RX_AGGREGATION_SUPPORT
7265void rtl8192SU_HalUsbRxAggr8192SUsb(struct net_device *dev, bool Value)
7266{
7267 struct r8192_priv *priv = ieee80211_priv((struct net_device *)dev);
7268 PRT_HIGH_THROUGHPUT pHTInfo = priv->ieee80211->pHTInfo;;
7269
7270
7271 //
7272 // <Roger_Notes> We decrease Rx page aggregated threshold in B/G mode.
7273 // 2008.10.29
7274 //
7275 if((priv->ieee80211->mode & WIRELESS_MODE_B) || (priv->ieee80211->mode & WIRELESS_MODE_G))
7276 {// Overwrite current settings to disable Rx Aggregation.
7277 Value = false;
7278 }
7279
7280 // Alway set Rx Aggregation to Disable if current platform is Win2K USB 1.1, by Emily
7281 //if(PLATFORM_LIMITED_RX_BUF_SIZE(Adapter))
7282 // Value = FALSE;
7283
7284 // Always set Rx Aggregation to Disable if connected AP is Realtek AP, by Joseph
7285 //if(pHTInfo->bCurrentRT2RTAggregation)
7286 // Value = FALSE;
7287
7288 // The RX aggregation may be enabled/disabled dynamically according current traffic stream.
7289 //Enable Rx aggregation if downlink traffic is busier than uplink traffic. by Guangan
7290 if(priv->bCurrentRxAggrEnable != Value)
7291 {
7292 priv->bCurrentRxAggrEnable = Value;
7293 //Adapter->HalFunc.SetHwRegHandler(Adapter, HW_VAR_USB_RX_AGGR, (pu1Byte)&pHalData->bCurrentRxAggrEnable);
7294 {
7295 //u8 Setting = ((pu1Byte)(val))[0];
7296 u8 Setting = priv->bCurrentRxAggrEnable
7297 u32 ulValue;
7298
7299 if(Setting==0)
7300 {
7301 //
7302 // <Roger_Notes> Reduce aggregated page threshold to 0x01 and set minimal threshold 0x0a.
7303 // i.e., disable Rx aggregation.
7304 //
7305 ulValue = 0x0001000a;
7306 }
7307 else
7308 {
7309 //PRT_HIGH_THROUGHPUT pHTInfo = priv->ieee80211->pHTInfo;
7310 //HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
7311
7312 if (priv->bForcedUsbRxAggr)
7313 {// Using forced settings.
7314 ulValue = priv->ForcedUsbRxAggrInfo;
7315 }
7316 else
7317 {// Using default settings.
7318
7319 ulValue = (pHTInfo->UsbRxFwAggrEn<<24) | (pHTInfo->UsbRxFwAggrPageNum<<16) |
7320 (pHTInfo->UsbRxFwAggrPacketNum<<8) | (pHTInfo->UsbRxFwAggrTimeout);
7321 }
7322 }
7323
7324 write_nic_byte(dev, RXDMA_AGG_PG_TH, (u8)((ulValue&0xff0000)>>16));
7325 write_nic_byte_E(dev, USB_RX_AGG_TIMEOUT, (u8)(ulValue&0xff));
7326
7327 priv->LastUsbRxAggrInfoSetting = ulValue;
7328
7329 RT_TRACE(COMP_HT|COMP_RECV, "Set HW_VAR_USB_RX_AGGR: ulValue(%#x)\n", ulValue);
7330 }
7331 RT_TRACE(COMP_RECV, "HalUsbRxAggr8192SUsb() : Set RxAggregation to %s\n", Value?"ON":"OFF");
7332 }
7333
7334}
7335
7336u8 rtl8192SU_MapRxPageSizeToIdx(u16 RxPktSize )
7337{
7338 switch(RxPktSize)
7339 {
7340 case 64: return 0; break;
7341 case 128 : return 1; break;
7342 case 256: return 2; break;
7343 case 512: return 3; break;
7344 case 1024: return 4; break;
7345 default: return 0; // We use 64bytes in defult.
7346 }
7347}
7348#endif
7349
7350#if 0
7351static void rtl8192SU_SetHwRegAmpduMinSpace(struct net_device *dev, u8 MinSpaceCfg)
7352{
7353 struct r8192_priv *priv = ieee80211_priv((struct net_device *)dev);
7354 struct ieee80211_device* ieee = priv->ieee80211;
7355 u8 MinSpacingToSet;
7356 u8 SecMinSpace;
7357
7358#ifdef RTL8192S_PREPARE_FOR_NORMAL_RELEASE
7359 MinSpacingToSet = MinSpaceCfg;
7360 if(MinSpacingToSet <= 7)
7361 {
7362 switch(ieee->pairwise_key_type)
7363 {
7364 case KEY_TYPE_NA: SecMinSpace = 0; break;
7365 case KEY_TYPE_CCMP:
7366 case KEY_TYPE_WEP40:
7367 case KEY_TYPE_WEP104:
7368 case KEY_TYPE_TKIP: SecMinSpace = 6; break;
7369 default: SecMinSpace = 7; break;
7370 }
7371
7372 if(MinSpacingToSet < SecMinSpace)
7373 MinSpacingToSet = SecMinSpace;
7374 priv->MinSpaceCfg = ((priv->MinSpaceCfg&0xf8) |MinSpacingToSet);
7375 RT_TRACE(COMP_SEC, "Set AMPDU_MIN_SPACE: %x\n", priv->MinSpaceCfg);
7376 write_nic_byte(dev, AMPDU_MIN_SPACE, priv->MinSpaceCfg);
7377 }
7378
7379#else
7380 MinSpacingToSet = MinSpaceCfg;
7381 MinSpacingToSet &= 0x07; // We only care about bit[2:0]
7382 priv->MinSpaceCfg |= MinSpacingToSet;
7383 RT_TRACE(COMP_SEC, "Set AMPDU_MIN_SPACE: %x\n", priv->MinSpaceCfg);
7384 write_nic_byte(dev, AMPDU_MIN_SPACE, priv->MinSpaceCfg);//FIXLZM
7385#endif
7386}
7387#endif
7388
7389//
7390// Description:
7391// Initial HW relted registers.
7392//
7393// Assumption:
7394// 1. This function is only invoked at driver intialization once.
7395// 2. PASSIVE LEVEL.
7396//
7397// 2008.06.10, Added by Roger.
7398//
7399static void rtl8192SU_MacConfigAfterFwDownload(struct net_device *dev)
7400{
7401 struct r8192_priv *priv = ieee80211_priv((struct net_device *)dev);
7402 //PRT_HIGH_THROUGHPUT pHTInfo = priv->ieee80211->pHTInfo;
7403 //u8 tmpU1b, RxPageCfg, i;
7404 u16 tmpU2b;
7405 u8 tmpU1b;//, i;
7406
7407
7408 RT_TRACE(COMP_INIT, "--->MacConfigAfterFwDownload()\n");
7409
7410 // Enable Tx/Rx
7411 tmpU2b = (BBRSTn|BB_GLB_RSTn|SCHEDULE_EN|MACRXEN|MACTXEN|DDMA_EN|
7412 FW2HW_EN|RXDMA_EN|TXDMA_EN|HCI_RXDMA_EN|HCI_TXDMA_EN); //3
7413 //Adapter->HalFunc.SetHwRegHandler( Adapter, HW_VAR_COMMAND, &tmpU1b );
7414 write_nic_word(dev, CMDR, tmpU2b); //LZM REGISTER COM 090305
7415
7416 // Loopback mode or not
7417 priv->LoopbackMode = RTL8192SU_NO_LOOPBACK; // Set no loopback as default.
7418 if(priv->LoopbackMode == RTL8192SU_NO_LOOPBACK)
7419 tmpU1b = LBK_NORMAL;
7420 else if (priv->LoopbackMode == RTL8192SU_MAC_LOOPBACK )
7421 tmpU1b = LBK_MAC_DLB;
7422 else
7423 RT_TRACE(COMP_INIT, "Serious error: wrong loopback mode setting\n");
7424
7425 //Adapter->HalFunc.SetHwRegHandler( Adapter, HW_VAR_LBK_MODE, &tmpU1b);
7426 write_nic_byte(dev, LBKMD_SEL, tmpU1b);
7427
7428 // Set RCR
7429 write_nic_dword(dev, RCR, priv->ReceiveConfig);
7430 RT_TRACE(COMP_INIT, "MacConfigAfterFwDownload(): Current RCR settings(%#x)\n", priv->ReceiveConfig);
7431
7432
7433 // Set RQPN
7434 //
7435 // <Roger_Notes> 2008.08.18.
7436 // 6 endpoints:
7437 // (1) Page number on CMDQ is 0x03.
7438 // (2) Page number on BCNQ, HQ and MGTQ is 0.
7439 // (3) Page number on BKQ, BEQ, VIQ and VOQ are 0x07.
7440 // (4) Page number on PUBQ is 0xdd
7441 //
7442 // 11 endpoints:
7443 // (1) Page number on CMDQ is 0x00.
7444 // (2) Page number on BCNQ is 0x02, HQ and MGTQ are 0x03.
7445 // (3) Page number on BKQ, BEQ, VIQ and VOQ are 0x07.
7446 // (4) Page number on PUBQ is 0xd8
7447 //
7448 //write_nic_dword(Adapter, 0xa0, 0x07070707); //BKQ, BEQ, VIQ and VOQ
7449 //write_nic_byte(dev, 0xa4, 0x00); // HCCAQ
7450#if 0 //LZM 090219
7451#ifdef USE_SIX_USB_ENDPOINT
7452 //write_nic_dword(Adapter, 0xa5, 0x00000003); //CMDQ, MGTQ, HQ and BCNQ
7453 //write_nic_byte(dev, 0xa9, 0xdd); // PUBQ
7454 tmpU1b = read_nic_byte(dev, 0xab); // RQPN
7455 write_nic_byte(dev, 0xab, tmpU1b|BIT7|BIT6);// reduce to 6 endpoints.
7456#else
7457 write_nic_dword(dev, 0xa5, 0x02030300); //CMDQ, MGTQ, HQ and BCNQ
7458 write_nic_byte(dev, 0xa9, 0xd8); // PUBQ
7459 tmpU1b = read_nic_byte(dev, 0xab); // RQPN
7460 write_nic_byte(dev, 0xab, (tmpU1b&(~BIT6))|BIT7); // Disable reduced endpoint.
7461#endif
7462#endif
7463
7464#ifdef USB_RX_AGGREGATION_SUPPORT
7465 // Size of Tx/Rx packet buffer.
7466 tmpU1b = read_nic_byte(dev, PBP);
7467 RxPageCfg = rtl8192SU_MapRxPageSizeToIdx(priv->ieee80211->pHTInfo.UsbRxPageSize);
7468 write_nic_byte(dev, PBP, tmpU1b|RxPageCfg); // Set page size of Rx packet buffer to 128 bytes.
7469 tmpU1b = read_nic_byte(dev, RXDMA);
7470
7471 write_nic_byte(dev, RXDMA, tmpU1b|RXDMA_AGG_EN); // Rx aggregation enable.
7472 //PlatformIOWrite1Byte(Adapter, RXDMA_AGG_PG_TH, 0x14); // Set page size of RxDMA aggregation threshold, default: 20.
7473 //write_nic_byte(dev, RXDMA_AGG_PG_TH, 0x40); // By Scott's suggestion, 2008.09.30.//92su del
7474 //write_nic_byte(dev, USB_RX_AGG_TIMEOUT, RXDMA_AGG_TIMEOUT_17_4_MS); // Set aggregation time-out to 17ms/4.
7475 rtl8192SU_HalUsbRxAggr8192SUsb(dev, true);
7476#endif
7477
7478 // Fix the RX FIFO issue(USB error), Rivesed by Roger, 2008-06-14
7479 tmpU1b = read_nic_byte_E(dev, 0x5C);
7480 write_nic_byte_E(dev, 0x5C, tmpU1b|BIT7);
7481
7482 //
7483 // Revise USB PHY to solve the issue of Rx payload error, Rivesed by Roger, 2008-04-10
7484 // Suggest by SD1 Alex.
7485 //
7486 // <Roger_Notes> The following operation are ONLY for USB PHY test chip.
7487 // 2008.10.07.
7488 //
7489#if RTL8192SU_USB_PHY_TEST
7490 write_nic_byte(dev, 0x41,0xf4);
7491 write_nic_byte(dev, 0x40,0x00);
7492 write_nic_byte(dev, 0x42,0x00);
7493 write_nic_byte(dev, 0x42,0x01);
7494 write_nic_byte(dev, 0x40,0x0f);
7495 write_nic_byte(dev, 0x42,0x00);
7496 write_nic_byte(dev, 0x42,0x01);
7497#endif
7498
7499#if 0 //LZM 090219
7500 //
7501 // Suggested by SD1 Alex, 2008-06-14.
7502 //
7503 write_nic_byte(dev, TXOP_STALL_CTRL, 0x80);//NAV
7504
7505
7506 //
7507 // Set Data Auto Rate Fallback Retry Count register.
7508 //
7509 write_nic_dword(dev, DARFRC, 0x04010000);
7510 write_nic_dword(dev, DARFRC+4, 0x09070605);
7511 write_nic_dword(dev, RARFRC, 0x04010000);
7512 write_nic_dword(dev, RARFRC+4, 0x09070605);
7513
7514 // Set Data Auto Rate Fallback Reg. Added by Roger, 2008.09.22.
7515 for (i = 0; i < 8; i++)
7516#ifdef RTL8192SU_DISABLE_CCK_RATE
7517 write_nic_dword(dev, ARFR0+i*4, 0x1f0ff0f0);
7518#else
7519 write_nic_dword(dev, ARFR0+i*4, 0x1f0ffff0);
7520#endif
7521
7522 //
7523 // Set driver info, we only accept PHY status now.
7524 //
7525 //write_nic_byte(dev, RXDRVINFO_SZ, 4);
7526
7527 //
7528 // Aggregation length limit. Revised by Roger. 2008.09.22.
7529 //
7530 write_nic_dword(dev, AGGLEN_LMT_L, 0x66666666); // Long GI
7531 write_nic_byte(dev, AGGLEN_LMT_H, 0x06); // Set AMPDU length to 12Kbytes for ShortGI case.
7532
7533 //
7534 // For Min Spacing configuration.
7535 //
7536 //Adapter->HalFunc.SetHwRegHandler(Adapter, HW_VAR_AMPDU_MIN_SPACE, (u8*)(&Adapter->MgntInfo.MinSpaceCfg));
7537 rtl8192SU_SetHwRegAmpduMinSpace(dev,priv->MinSpaceCfg);
7538#endif
7539
7540 // For EFUSE init configuration.
7541 //if (IS_BOOT_FROM_EFUSE(Adapter)) // We may R/W EFUSE in EFUSE mode
7542 if (priv->bBootFromEfuse)
7543 {
7544 u8 tempval;
7545
7546 tempval = read_nic_byte(dev, SYS_ISO_CTRL+1);
7547 tempval &= 0xFE;
7548 write_nic_byte(dev, SYS_ISO_CTRL+1, tempval);
7549
7550 // Enable LDO 2.5V for write action
7551 //tempval = read_nic_byte(Adapter, EFUSE_TEST+3);
7552 //write_nic_byte(Adapter, EFUSE_TEST+3, (tempval | 0x80));
7553
7554 // Change Efuse Clock for write action
7555 //write_nic_byte(Adapter, EFUSE_CLK, 0x03);
7556
7557 // Change Program timing
7558 write_nic_byte(dev, EFUSE_CTRL+3, 0x72);
7559 //printk("!!!!!!!!!!!!!!!!!!!!!%s: write 0x33 with 0x72\n",__FUNCTION__);
7560 RT_TRACE(COMP_INIT, "EFUSE CONFIG OK\n");
7561 }
7562
7563
7564 RT_TRACE(COMP_INIT, "<---MacConfigAfterFwDownload()\n");
7565}
7566
7567void rtl8192SU_HwConfigureRTL8192SUsb(struct net_device *dev)
7568{
7569
7570 struct r8192_priv *priv = ieee80211_priv(dev);
7571 u8 regBwOpMode = 0;
7572 u32 regRATR = 0, regRRSR = 0;
7573 u8 regTmp = 0;
7574 u32 i = 0;
7575
7576 //1 This part need to modified according to the rate set we filtered!!
7577 //
7578 // Set RRSR, RATR, and BW_OPMODE registers
7579 //
7580 switch(priv->ieee80211->mode)
7581 {
7582 case WIRELESS_MODE_B:
7583 regBwOpMode = BW_OPMODE_20MHZ;
7584 regRATR = RATE_ALL_CCK;
7585 regRRSR = RATE_ALL_CCK;
7586 break;
7587 case WIRELESS_MODE_A:
7588 regBwOpMode = BW_OPMODE_5G |BW_OPMODE_20MHZ;
7589 regRATR = RATE_ALL_OFDM_AG;
7590 regRRSR = RATE_ALL_OFDM_AG;
7591 break;
7592 case WIRELESS_MODE_G:
7593 regBwOpMode = BW_OPMODE_20MHZ;
7594 regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
7595 regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
7596 break;
7597 case WIRELESS_MODE_AUTO:
7598 if (priv->bInHctTest)
7599 {
7600 regBwOpMode = BW_OPMODE_20MHZ;
7601 regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
7602 regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
7603 }
7604 else
7605 {
7606 regBwOpMode = BW_OPMODE_20MHZ;
7607 regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
7608 regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
7609 }
7610 break;
7611 case WIRELESS_MODE_N_24G:
7612 // It support CCK rate by default.
7613 // CCK rate will be filtered out only when associated AP does not support it.
7614 regBwOpMode = BW_OPMODE_20MHZ;
7615 regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
7616 regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
7617 break;
7618 case WIRELESS_MODE_N_5G:
7619 regBwOpMode = BW_OPMODE_5G;
7620 regRATR = RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
7621 regRRSR = RATE_ALL_OFDM_AG;
7622 break;
7623 }
7624
7625 //
7626 // <Roger_Notes> We disable CCK response rate until FIB CCK rate IC's back.
7627 // 2008.09.23.
7628 //
7629 regTmp = read_nic_byte(dev, INIRTSMCS_SEL);
7630#ifdef RTL8192SU_DISABLE_CCK_RATE
7631 regRRSR = ((regRRSR & 0x000ffff0)<<8) | regTmp;
7632#else
7633 regRRSR = ((regRRSR & 0x000fffff)<<8) | regTmp;
7634#endif
7635
7636 //
7637 // Update SIFS timing.
7638 //
7639 //priv->SifsTime = 0x0e0e0a0a;
7640 //Adapter->HalFunc.SetHwRegHandler( Adapter, HW_VAR_SIFS, (pu1Byte)&pHalData->SifsTime);
7641 { u8 val[4] = {0x0e, 0x0e, 0x0a, 0x0a};
7642 // SIFS for CCK Data ACK
7643 write_nic_byte(dev, SIFS_CCK, val[0]);
7644 // SIFS for CCK consecutive tx like CTS data!
7645 write_nic_byte(dev, SIFS_CCK+1, val[1]);
7646
7647 // SIFS for OFDM Data ACK
7648 write_nic_byte(dev, SIFS_OFDM, val[2]);
7649 // SIFS for OFDM consecutive tx like CTS data!
7650 write_nic_byte(dev, SIFS_OFDM+1, val[3]);
7651 }
7652
7653 write_nic_dword(dev, INIRTSMCS_SEL, regRRSR);
7654 write_nic_byte(dev, BW_OPMODE, regBwOpMode);
7655
7656 //
7657 // Suggested by SD1 Alex, 2008-06-14.
7658 //
7659 //PlatformEFIOWrite1Byte(Adapter, TXOP_STALL_CTRL, 0x80);//NAV to protect all TXOP.
7660
7661 //
7662 // Set Data Auto Rate Fallback Retry Count register.
7663 //
7664 write_nic_dword(dev, DARFRC, 0x02010000);
7665 write_nic_dword(dev, DARFRC+4, 0x06050403);
7666 write_nic_dword(dev, RARFRC, 0x02010000);
7667 write_nic_dword(dev, RARFRC+4, 0x06050403);
7668
7669 // Set Data Auto Rate Fallback Reg. Added by Roger, 2008.09.22.
7670 for (i = 0; i < 8; i++)
7671#ifdef RTL8192SU_DISABLE_CCK_RATE
7672 write_nic_dword(dev, ARFR0+i*4, 0x1f0ff0f0);
7673#else
7674 write_nic_dword(dev, ARFR0+i*4, 0x1f0ffff0);
7675#endif
7676
7677 //
7678 // Aggregation length limit. Revised by Roger. 2008.09.22.
7679 //
7680 write_nic_byte(dev, AGGLEN_LMT_H, 0x0f); // Set AMPDU length to 12Kbytes for ShortGI case.
7681 write_nic_dword(dev, AGGLEN_LMT_L, 0xddd77442); // Long GI
7682 write_nic_dword(dev, AGGLEN_LMT_L+4, 0xfffdd772);
7683
7684 // Set NAV protection length
7685 write_nic_word(dev, NAV_PROT_LEN, 0x0080);
7686
7687 // Set TXOP stall control for several queue/HI/BCN/MGT/
7688 write_nic_byte(dev, TXOP_STALL_CTRL, 0x00); // NAV Protect next packet.
7689
7690 // Set MSDU lifetime.
7691 write_nic_byte(dev, MLT, 0x8f);
7692
7693 // Set CCK/OFDM SIFS
7694 write_nic_word(dev, SIFS_CCK, 0x0a0a); // CCK SIFS shall always be 10us.
7695 write_nic_word(dev, SIFS_OFDM, 0x0e0e);
7696
7697 write_nic_byte(dev, ACK_TIMEOUT, 0x40);
7698
7699 // CF-END Threshold
7700 write_nic_byte(dev, CFEND_TH, 0xFF);
7701
7702 //
7703 // For Min Spacing configuration.
7704 //
7705 switch(priv->rf_type)
7706 {
7707 case RF_1T2R:
7708 case RF_1T1R:
7709 RT_TRACE(COMP_INIT, "Initializeadapter: RF_Type%s\n", (priv->rf_type==RF_1T1R? "(1T1R)":"(1T2R)"));
7710 priv->MinSpaceCfg = (MAX_MSS_DENSITY_1T<<3);
7711 break;
7712 case RF_2T2R:
7713 case RF_2T2R_GREEN:
7714 RT_TRACE(COMP_INIT, "Initializeadapter:RF_Type(2T2R)\n");
7715 priv->MinSpaceCfg = (MAX_MSS_DENSITY_2T<<3);
7716 break;
7717 }
7718 write_nic_byte(dev, AMPDU_MIN_SPACE, priv->MinSpaceCfg);
7719
7720 //LZM 090219
7721 //
7722 // For Min Spacing configuration.
7723 //
7724 //priv->MinSpaceCfg = 0x00;
7725 //rtl8192SU_SetHwRegAmpduMinSpace(dev, priv->MinSpaceCfg);
7726}
7727
7728#endif
7729
7730#ifdef RTL8192SU
7731// Description: Initial HW relted registers.
7732//
7733// Assumption: This function is only invoked at driver intialization once.
7734//
7735// 2008.06.10, Added by Roger.
7736bool rtl8192SU_adapter_start(struct net_device *dev)
7737{
7738 struct r8192_priv *priv = ieee80211_priv(dev);
7739 //u32 dwRegRead = 0;
7740 //bool init_status = true;
7741 //u32 ulRegRead;
7742 bool rtStatus = true;
7743 //u8 PipeIndex;
7744 //u8 eRFPath, tmpU1b;
7745 u8 fw_download_times = 1;
7746
7747
7748 RT_TRACE(COMP_INIT, "--->InitializeAdapter8192SUsb()\n");
7749
7750 //pHalData->bGPIOChangeRF = FALSE;
7751
7752
7753 //
7754 // <Roger_Notes> 2008.06.15.
7755 //
7756 // Initialization Steps on RTL8192SU:
7757 // a. MAC initialization prior to sending down firmware code.
7758 // b. Download firmware code step by step(i.e., IMEM, EMEM, DMEM).
7759 // c. MAC configuration after firmware has been download successfully.
7760 // d. Initialize BB related configurations.
7761 // e. Initialize RF related configurations.
7762 // f. Start to BulkIn transfer.
7763 //
7764
7765 //
7766 //a. MAC initialization prior to send down firmware code.
7767 //
7768start:
7769 rtl8192SU_MacConfigBeforeFwDownloadASIC(dev);
7770
7771 //
7772 //b. Download firmware code step by step(i.e., IMEM, EMEM, DMEM).
7773 //
7774 rtStatus = FirmwareDownload92S(dev);
7775 if(rtStatus != true)
7776 {
7777 if(fw_download_times == 1){
7778 RT_TRACE(COMP_INIT, "InitializeAdapter8192SUsb(): Download Firmware failed once, Download again!!\n");
7779 fw_download_times = fw_download_times + 1;
7780 goto start;
7781 }else{
7782 RT_TRACE(COMP_INIT, "InitializeAdapter8192SUsb(): Download Firmware failed twice, end!!\n");
7783 goto end;
7784 }
7785 }
7786 //
7787 //c. MAC configuration after firmware has been download successfully.
7788 //
7789 rtl8192SU_MacConfigAfterFwDownload(dev);
7790
7791#if (RTL8192S_DISABLE_FW_DM == 1)
7792 write_nic_dword(dev, WFM5, FW_DM_DISABLE);
7793#endif
7794 //priv->bLbusEnable = TRUE;
7795 //if(priv->RegRfOff == TRUE)
7796 // priv->eRFPowerState = eRfOff;
7797
7798 // Save target channel
7799 // <Roger_Notes> Current Channel will be updated again later.
7800 //priv->CurrentChannel = Channel;
7801 rtStatus = PHY_MACConfig8192S(dev);//===>ok
7802 if(rtStatus != true)
7803 {
7804 RT_TRACE(COMP_INIT, "InitializeAdapter8192SUsb(): Fail to configure MAC!!\n");
7805 goto end;
7806 }
7807 if (1){
7808 int i;
7809 for (i=0; i<4; i++)
7810 write_nic_dword(dev,WDCAPARA_ADD[i], 0x5e4322);
7811 write_nic_byte(dev,AcmHwCtrl, 0x01);
7812 }
7813
7814
7815 //
7816 //d. Initialize BB related configurations.
7817 //
7818
7819 rtStatus = PHY_BBConfig8192S(dev);//===>ok
7820 if(rtStatus != true)
7821 {
7822 RT_TRACE(COMP_INIT, "InitializeAdapter8192SUsb(): Fail to configure BB!!\n");
7823 goto end;
7824 }
7825
7826 rtl8192_setBBreg(dev, rFPGA0_AnalogParameter2, 0xff, 0x58);//===>ok
7827
7828 //
7829 // e. Initialize RF related configurations.
7830 //
7831 // 2007/11/02 MH Before initalizing RF. We can not use FW to do RF-R/W.
7832 priv->Rf_Mode = RF_OP_By_SW_3wire;
7833
7834 // For RF test only from Scott's suggestion
7835 //write_nic_byte(dev, 0x27, 0xDB);
7836 //write_nic_byte(dev, 0x1B, 0x07);
7837
7838
7839 write_nic_byte(dev, AFE_XTAL_CTRL+1, 0xDB);
7840
7841 // <Roger_Notes> The following IOs are configured for each RF modules.
7842 // Enable RF module and reset RF and SDM module. 2008.11.17.
7843 if(priv->card_8192_version == VERSION_8192S_ACUT)
7844 write_nic_byte(dev, SPS1_CTRL+3, (u8)(RF_EN|RF_RSTB|RF_SDMRSTB)); // Fix A-Cut bug.
7845 else
7846 write_nic_byte(dev, RF_CTRL, (u8)(RF_EN|RF_RSTB|RF_SDMRSTB));
7847
7848 rtStatus = PHY_RFConfig8192S(dev);//===>ok
7849 if(rtStatus != true)
7850 {
7851 RT_TRACE(COMP_INIT, "InitializeAdapter8192SUsb(): Fail to configure RF!!\n");
7852 goto end;
7853 }
7854
7855
7856 // Set CCK and OFDM Block "ON"
7857 rtl8192_setBBreg(dev, rFPGA0_RFMOD, bCCKEn, 0x1);
7858 rtl8192_setBBreg(dev, rFPGA0_RFMOD, bOFDMEn, 0x1);
7859
7860 //
7861 // Turn off Radio B while RF type is 1T1R by SD3 Wilsion's request.
7862 // Revised by Roger, 2008.12.18.
7863 //
7864 if(priv->rf_type == RF_1T1R)
7865 {
7866 // This is needed for PHY_REG after 20081219
7867 rtl8192_setBBreg(dev, rFPGA0_RFMOD, 0xff000000, 0x03);
7868 // This is needed for PHY_REG before 20081219
7869 //PHY_SetBBReg(Adapter, rOFDM0_TRxPathEnable, bMaskByte0, 0x11);
7870 }
7871
7872#if (RTL8192SU_DISABLE_IQK==0)
7873 // For 1T2R IQK only currently.
7874 if (priv->card_8192_version == VERSION_8192S_BCUT)
7875 {
7876 PHY_IQCalibrateBcut(dev);
7877 }
7878 else if (priv->card_8192_version == VERSION_8192S_ACUT)
7879 {
7880 PHY_IQCalibrate(dev);
7881 }
7882#endif
7883
7884 //LZM 090219
7885 // Set CCK and OFDM Block "ON"
7886 //rtl8192_setBBreg(dev, rFPGA0_RFMOD, bCCKEn, 0x1);
7887 //rtl8192_setBBreg(dev, rFPGA0_RFMOD, bOFDMEn, 0x1);
7888
7889
7890 //3//Get hardware version, do it in read eeprom?
7891 //GetHardwareVersion819xUsb(Adapter);
7892
7893 //3//
7894 //3 //Set Hardware
7895 //3//
7896 rtl8192SU_HwConfigureRTL8192SUsb(dev);//==>ok
7897
7898 //
7899 // <Roger_Notes> We set MAC address here if autoload was failed before,
7900 // otherwise IDR0 will NOT contain any value.
7901 //
7902 write_nic_dword(dev, IDR0, ((u32*)dev->dev_addr)[0]);
7903 write_nic_word(dev, IDR4, ((u16*)(dev->dev_addr + 4))[0]);
7904 if(!priv->bInHctTest)
7905 {
7906 if(priv->ResetProgress == RESET_TYPE_NORESET)
7907 {
7908 //RT_TRACE(COMP_MLME, DBG_LOUD, ("Initializeadapter8192SUsb():RegWirelessMode(%#x) \n", Adapter->RegWirelessMode));
7909 //Adapter->HalFunc.SetWirelessModeHandler(Adapter, Adapter->RegWirelessMode);
7910 rtl8192_SetWirelessMode(dev, priv->ieee80211->mode);//===>ok
7911 }
7912 }
7913 else
7914 {
7915 priv->ieee80211->mode = WIRELESS_MODE_G;
7916 rtl8192_SetWirelessMode(dev, WIRELESS_MODE_G);
7917 }
7918
7919 //Security related.
7920 //-----------------------------------------------------------------------------
7921 // Set up security related. 070106, by rcnjko:
7922 // 1. Clear all H/W keys.
7923 // 2. Enable H/W encryption/decryption.
7924 //-----------------------------------------------------------------------------
7925 //CamResetAllEntry(Adapter);
7926 //Adapter->HalFunc.EnableHWSecCfgHandler(Adapter);
7927
7928 //SecClearAllKeys(Adapter);
7929 CamResetAllEntry(dev);
7930 //SecInit(Adapter);
7931 {
7932 u8 SECR_value = 0x0;
7933 SECR_value |= SCR_TxEncEnable;
7934 SECR_value |= SCR_RxDecEnable;
7935 SECR_value |= SCR_NoSKMC;
7936 write_nic_byte(dev, SECR, SECR_value);
7937 }
7938
7939#if 0
7940
7941 if(pHalData->VersionID == VERSION_8192SU_A)
7942 {
7943 // cosa add for tx power level initialization.
7944 GetTxPowerOriginalOffset(Adapter);
7945 SetTxPowerLevel819xUsb(Adapter, Channel);
7946 }
7947#endif
7948
7949
7950#ifdef TO_DO_LIST
7951
7952 //PHY_UpdateInitialGain(dev);
7953
7954 if(priv->RegRfOff == true)
7955 { // User disable RF via registry.
7956 u8 eRFPath = 0;
7957
7958 RT_TRACE((COMP_INIT|COMP_RF), "InitializeAdapter8192SUsb(): Turn off RF for RegRfOff ----------\n");
7959 MgntActSet_RF_State(dev, eRfOff, RF_CHANGE_BY_SW);
7960 // Those action will be discard in MgntActSet_RF_State because off the same state
7961 for(eRFPath = 0; eRFPath <priv->NumTotalRFPath; eRFPath++)
7962 rtl8192_setBBreg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x4, 0xC00, 0x0);
7963 }
7964 else if(priv->RfOffReason > RF_CHANGE_BY_PS)
7965 { // H/W or S/W RF OFF before sleep.
7966 RT_TRACE((COMP_INIT|COMP_RF), "InitializeAdapter8192SUsb(): Turn off RF for RfOffReason(%d) ----------\n", priv->RfOffReason);
7967 MgntActSet_RF_State(dev, eRfOff, priv->RfOffReason);
7968 }
7969 else
7970 {
7971 priv->eRFPowerState = eRfOn;
7972 priv->RfOffReason = 0;
7973 RT_TRACE((COMP_INIT|COMP_RF), "InitializeAdapter8192SUsb(): RF is on ----------\n");
7974 }
7975
7976#endif
7977
7978
7979//
7980// f. Start to BulkIn transfer.
7981//
7982#ifdef TO_DO_LIST
7983
7984#ifndef UNDER_VISTA
7985 {
7986 u8 i;
7987 PlatformAcquireSpinLock(Adapter, RT_RX_SPINLOCK);
7988
7989 for(PipeIndex=0; PipeIndex < MAX_RX_QUEUE; PipeIndex++)
7990 {
7991 if (PipeIndex == 0)
7992 {
7993 for(i=0; i<32; i++)
7994 HalUsbInMpdu(Adapter, PipeIndex);
7995 }
7996 else
7997 {
7998 //HalUsbInMpdu(Adapter, PipeIndex);
7999 //HalUsbInMpdu(Adapter, PipeIndex);
8000 //HalUsbInMpdu(Adapter, PipeIndex);
8001 }
8002 }
8003 PlatformReleaseSpinLock(Adapter, RT_RX_SPINLOCK);
8004 }
8005#else
8006 // Joseph add to 819X code base for Vista USB platform.
8007 // This part may need to be add to Hal819xU code base. too.
8008 PlatformUsbEnableInPipes(Adapter);
8009#endif
8010
8011 RT_TRACE(COMP_INIT, "HighestOperaRate = %x\n", Adapter->MgntInfo.HighestOperaRate);
8012
8013 PlatformStartWorkItem( &(pHalData->RtUsbCheckForHangWorkItem) );
8014
8015 //
8016 // <Roger_EXP> The following configurations are for ASIC verification temporally.
8017 // 2008.07.10.
8018 //
8019
8020#endif
8021
8022 //
8023 // Read EEPROM TX power index and PHY_REG_PG.txt to capture correct
8024 // TX power index for different rate set.
8025 //
8026 //if(priv->card_8192_version >= VERSION_8192S_ACUT)
8027 {
8028 // Get original hw reg values
8029 PHY_GetHWRegOriginalValue(dev);
8030
8031 // Write correct tx power index//FIXLZM
8032 PHY_SetTxPowerLevel8192S(dev, priv->chan);
8033 }
8034
8035 {
8036 u8 tmpU1b = 0;
8037 // EEPROM R/W workaround
8038 tmpU1b = read_nic_byte(dev, MAC_PINMUX_CFG);
8039 write_nic_byte(dev, MAC_PINMUX_CFG, tmpU1b&(~GPIOMUX_EN));
8040 }
8041
8042//
8043//<Roger_Notes> 2008.08.19.
8044// We return status here for temporal FPGA verification, 2008.08.19.
8045
8046#ifdef RTL8192SU_FW_IQK
8047 write_nic_dword(dev, WFM5, FW_IQK_ENABLE);
8048 ChkFwCmdIoDone(dev);
8049#endif
8050
8051 //
8052 // <Roger_Notes> We enable high power mechanism after NIC initialized.
8053 // 2008.11.27.
8054 //
8055 write_nic_dword(dev, WFM5, FW_RA_RESET);
8056 ChkFwCmdIoDone(dev);
8057 write_nic_dword(dev, WFM5, FW_RA_ACTIVE);
8058 ChkFwCmdIoDone(dev);
8059 write_nic_dword(dev, WFM5, FW_RA_REFRESH);
8060 ChkFwCmdIoDone(dev);
8061 write_nic_dword(dev, WFM5, FW_BB_RESET_ENABLE);
8062
8063// <Roger_Notes> We return status here for temporal FPGA verification. 2008.05.12.
8064//
8065#if RTL8192SU_FPGA_UNSPECIFIED_NETWORK
8066 //
8067 // To send specific number of packets to verify MAC Lookback mode.
8068 //
8069 //SendRandomTxPkt(Adapter, 0); // Burst mode for verification.
8070 //rtStatus = RT_STATUS_FAILURE;
8071 rtStatus = true;
8072 goto end;
8073#endif
8074
8075// The following IO was for FPGA verification purpose. Added by Roger, 2008.09.11.
8076#if 0
8077 // 2008/08/19 MH From SD1 Jong, we must write some register for true PHY/MAC FPGA.
8078 write_nic_byte(dev, rOFDM0_XAAGCCore1, 0x30);
8079 write_nic_byte(dev, rOFDM0_XBAGCCore1, 0x30);
8080
8081 write_nic_byte(dev, rOFDM0_RxDetector1, 0x42);
8082
8083 //write_nic_dword(Adapter, RCR, 0x817FF02F);
8084
8085 write_nic_dword(Adapter, rTxAGC_Mcs15_Mcs12, 0x06060606);
8086#endif
8087end:
8088return rtStatus;
8089}
8090
8091#else
8092
8093//InitializeAdapter and PhyCfg
8094bool rtl8192_adapter_start(struct net_device *dev)
8095{
8096 struct r8192_priv *priv = ieee80211_priv(dev);
8097 u32 dwRegRead = 0;
8098 bool init_status = true;
8099 RT_TRACE(COMP_INIT, "====>%s()\n", __FUNCTION__);
8100 priv->Rf_Mode = RF_OP_By_SW_3wire;
8101 //for ASIC power on sequence
8102 write_nic_byte_E(dev, 0x5f, 0x80);
8103 mdelay(50);
8104 write_nic_byte_E(dev, 0x5f, 0xf0);
8105 write_nic_byte_E(dev, 0x5d, 0x00);
8106 write_nic_byte_E(dev, 0x5e, 0x80);
8107 write_nic_byte(dev, 0x17, 0x37);
8108 mdelay(10);
8109//#ifdef TO_DO_LIST
8110 priv->pFirmware->firmware_status = FW_STATUS_0_INIT;
8111 //config CPUReset Register
8112 //Firmware Reset or not?
8113 dwRegRead = read_nic_dword(dev, CPU_GEN);
8114 if (priv->pFirmware->firmware_status == FW_STATUS_0_INIT)
8115 dwRegRead |= CPU_GEN_SYSTEM_RESET; //do nothing here?
8116 else if (priv->pFirmware->firmware_status == FW_STATUS_5_READY)
8117 dwRegRead |= CPU_GEN_FIRMWARE_RESET;
8118 else
8119 RT_TRACE(COMP_ERR, "ERROR in %s(): undefined firmware state(%d)\n", __FUNCTION__, priv->pFirmware->firmware_status);
8120
8121 write_nic_dword(dev, CPU_GEN, dwRegRead);
8122 //mdelay(30);
8123 //config BB.
8124 rtl8192_BBConfig(dev);
8125
8126#if 1
8127 //Loopback mode or not
8128 priv->LoopbackMode = RTL819xU_NO_LOOPBACK;
8129// priv->LoopbackMode = RTL819xU_MAC_LOOPBACK;
8130
8131 dwRegRead = read_nic_dword(dev, CPU_GEN);
8132 if (priv->LoopbackMode == RTL819xU_NO_LOOPBACK)
8133 dwRegRead = ((dwRegRead & CPU_GEN_NO_LOOPBACK_MSK) | CPU_GEN_NO_LOOPBACK_SET);
8134 else if (priv->LoopbackMode == RTL819xU_MAC_LOOPBACK)
8135 dwRegRead |= CPU_CCK_LOOPBACK;
8136 else
8137 RT_TRACE(COMP_ERR, "Serious error in %s(): wrong loopback mode setting(%d)\n", __FUNCTION__, priv->LoopbackMode);
8138
8139 write_nic_dword(dev, CPU_GEN, dwRegRead);
8140
8141 //after reset cpu, we need wait for a seconds to write in register.
8142 udelay(500);
8143
8144 //xiong add for new bitfile:usb suspend reset pin set to 1. //do we need?
8145 write_nic_byte_E(dev, 0x5f, (read_nic_byte_E(dev, 0x5f)|0x20));
8146
8147 //Set Hardware
8148 rtl8192_hwconfig(dev);
8149
8150 //turn on Tx/Rx
8151 write_nic_byte(dev, CMDR, CR_RE|CR_TE);
8152
8153 //set IDR0 here
8154 write_nic_dword(dev, MAC0, ((u32*)dev->dev_addr)[0]);
8155 write_nic_word(dev, MAC4, ((u16*)(dev->dev_addr + 4))[0]);
8156
8157 //set RCR
8158 write_nic_dword(dev, RCR, priv->ReceiveConfig);
8159
8160 //Initialize Number of Reserved Pages in Firmware Queue
8161 write_nic_dword(dev, RQPN1, NUM_OF_PAGE_IN_FW_QUEUE_BK << RSVD_FW_QUEUE_PAGE_BK_SHIFT |\
8162 NUM_OF_PAGE_IN_FW_QUEUE_BE << RSVD_FW_QUEUE_PAGE_BE_SHIFT | \
8163 NUM_OF_PAGE_IN_FW_QUEUE_VI << RSVD_FW_QUEUE_PAGE_VI_SHIFT | \
8164 NUM_OF_PAGE_IN_FW_QUEUE_VO <<RSVD_FW_QUEUE_PAGE_VO_SHIFT);
8165 write_nic_dword(dev, RQPN2, NUM_OF_PAGE_IN_FW_QUEUE_MGNT << RSVD_FW_QUEUE_PAGE_MGNT_SHIFT |\
8166 NUM_OF_PAGE_IN_FW_QUEUE_CMD << RSVD_FW_QUEUE_PAGE_CMD_SHIFT);
8167 write_nic_dword(dev, RQPN3, APPLIED_RESERVED_QUEUE_IN_FW| \
8168 NUM_OF_PAGE_IN_FW_QUEUE_BCN<<RSVD_FW_QUEUE_PAGE_BCN_SHIFT
8169// | NUM_OF_PAGE_IN_FW_QUEUE_PUB<<RSVD_FW_QUEUE_PAGE_PUB_SHIFT
8170 );
8171 write_nic_dword(dev, RATR0+4*7, (RATE_ALL_OFDM_AG | RATE_ALL_CCK));
8172
8173 //Set AckTimeout
8174 // TODO: (it value is only for FPGA version). need to be changed!!2006.12.18, by Emily
8175 write_nic_byte(dev, ACK_TIMEOUT, 0x30);
8176
8177// RT_TRACE(COMP_INIT, "%s():priv->ResetProgress is %d\n", __FUNCTION__,priv->ResetProgress);
8178 if(priv->ResetProgress == RESET_TYPE_NORESET)
8179 rtl8192_SetWirelessMode(dev, priv->ieee80211->mode);
8180 if(priv->ResetProgress == RESET_TYPE_NORESET){
8181 CamResetAllEntry(dev);
8182 {
8183 u8 SECR_value = 0x0;
8184 SECR_value |= SCR_TxEncEnable;
8185 SECR_value |= SCR_RxDecEnable;
8186 SECR_value |= SCR_NoSKMC;
8187 write_nic_byte(dev, SECR, SECR_value);
8188 }
8189 }
8190
8191 //Beacon related
8192 write_nic_word(dev, ATIMWND, 2);
8193 write_nic_word(dev, BCN_INTERVAL, 100);
8194
8195 {
8196#define DEFAULT_EDCA 0x005e4332
8197 int i;
8198 for (i=0; i<QOS_QUEUE_NUM; i++)
8199 write_nic_dword(dev, WDCAPARA_ADD[i], DEFAULT_EDCA);
8200 }
8201#ifdef USB_RX_AGGREGATION_SUPPORT
8202 //3 For usb rx firmware aggregation control
8203 if(priv->ResetProgress == RESET_TYPE_NORESET)
8204 {
8205 u32 ulValue;
8206 PRT_HIGH_THROUGHPUT pHTInfo = priv->ieee80211->pHTInfo;
8207 ulValue = (pHTInfo->UsbRxFwAggrEn<<24) | (pHTInfo->UsbRxFwAggrPageNum<<16) |
8208 (pHTInfo->UsbRxFwAggrPacketNum<<8) | (pHTInfo->UsbRxFwAggrTimeout);
8209 /*
8210 * If usb rx firmware aggregation is enabled,
8211 * when anyone of three threshold conditions above is reached,
8212 * firmware will send aggregated packet to driver.
8213 */
8214 write_nic_dword(dev, 0x1a8, ulValue);
8215 priv->bCurrentRxAggrEnable = true;
8216 }
8217#endif
8218
8219 rtl8192_phy_configmac(dev);
8220
8221 if (priv->card_8192_version == (u8) VERSION_819xU_A)
8222 {
8223 rtl8192_phy_getTxPower(dev);
8224 rtl8192_phy_setTxPower(dev, priv->chan);
8225 }
8226
8227
8228 priv->usb_error = false;
8229 //Firmware download
8230 init_status = init_firmware(dev);
8231 if(!init_status)
8232 {
8233 RT_TRACE(COMP_ERR,"ERR!!! %s(): Firmware download is failed\n", __FUNCTION__);
8234 return init_status;
8235 }
8236 RT_TRACE(COMP_INIT, "%s():after firmware download\n", __FUNCTION__);
8237 //
8238#ifdef TO_DO_LIST
8239if(Adapter->ResetProgress == RESET_TYPE_NORESET)
8240 {
8241 if(pMgntInfo->RegRfOff == TRUE)
8242 { // User disable RF via registry.
8243 RT_TRACE((COMP_INIT|COMP_RF), DBG_LOUD, ("InitializeAdapter819xUsb(): Turn off RF for RegRfOff ----------\n"));
8244 MgntActSet_RF_State(Adapter, eRfOff, RF_CHANGE_BY_SW);
8245 // Those action will be discard in MgntActSet_RF_State because off the same state
8246 for(eRFPath = 0; eRFPath <pHalData->NumTotalRFPath; eRFPath++)
8247 PHY_SetRFReg(Adapter, (RF90_RADIO_PATH_E)eRFPath, 0x4, 0xC00, 0x0);
8248 }
8249 else if(pMgntInfo->RfOffReason > RF_CHANGE_BY_PS)
8250 { // H/W or S/W RF OFF before sleep.
8251 RT_TRACE((COMP_INIT|COMP_RF), DBG_LOUD, ("InitializeAdapter819xUsb(): Turn off RF for RfOffReason(%d) ----------\n", pMgntInfo->RfOffReason));
8252 MgntActSet_RF_State(Adapter, eRfOff, pMgntInfo->RfOffReason);
8253 }
8254 else
8255 {
8256 pHalData->eRFPowerState = eRfOn;
8257 pMgntInfo->RfOffReason = 0;
8258 RT_TRACE((COMP_INIT|COMP_RF), DBG_LOUD, ("InitializeAdapter819xUsb(): RF is on ----------\n"));
8259 }
8260 }
8261 else
8262 {
8263 if(pHalData->eRFPowerState == eRfOff)
8264 {
8265 MgntActSet_RF_State(Adapter, eRfOff, pMgntInfo->RfOffReason);
8266 // Those action will be discard in MgntActSet_RF_State because off the same state
8267 for(eRFPath = 0; eRFPath <pHalData->NumTotalRFPath; eRFPath++)
8268 PHY_SetRFReg(Adapter, (RF90_RADIO_PATH_E)eRFPath, 0x4, 0xC00, 0x0);
8269 }
8270 }
8271#endif
8272 //config RF.
8273 if(priv->ResetProgress == RESET_TYPE_NORESET){
8274 rtl8192_phy_RFConfig(dev);
8275 RT_TRACE(COMP_INIT, "%s():after phy RF config\n", __FUNCTION__);
8276 }
8277
8278
8279 if(priv->ieee80211->FwRWRF)
8280 // We can force firmware to do RF-R/W
8281 priv->Rf_Mode = RF_OP_By_FW;
8282 else
8283 priv->Rf_Mode = RF_OP_By_SW_3wire;
8284
8285
8286 rtl8192_phy_updateInitGain(dev);
8287 /*--set CCK and OFDM Block "ON"--*/
8288 rtl8192_setBBreg(dev, rFPGA0_RFMOD, bCCKEn, 0x1);
8289 rtl8192_setBBreg(dev, rFPGA0_RFMOD, bOFDMEn, 0x1);
8290
8291 if(priv->ResetProgress == RESET_TYPE_NORESET)
8292 {
8293 //if D or C cut
8294 u8 tmpvalue = read_nic_byte(dev, 0x301);
8295 if(tmpvalue ==0x03)
8296 {
8297 priv->bDcut = TRUE;
8298 RT_TRACE(COMP_POWER_TRACKING, "D-cut\n");
8299 }
8300 else
8301 {
8302 priv->bDcut = FALSE;
8303 RT_TRACE(COMP_POWER_TRACKING, "C-cut\n");
8304 }
8305 dm_initialize_txpower_tracking(dev);
8306
8307 if(priv->bDcut == TRUE)
8308 {
8309 u32 i, TempCCk;
8310 u32 tmpRegA= rtl8192_QueryBBReg(dev,rOFDM0_XATxIQImbalance,bMaskDWord);
8311 // u32 tmpRegC= rtl8192_QueryBBReg(dev,rOFDM0_XCTxIQImbalance,bMaskDWord);
8312 for(i = 0; i<TxBBGainTableLength; i++)
8313 {
8314 if(tmpRegA == priv->txbbgain_table[i].txbbgain_value)
8315 {
8316 priv->rfa_txpowertrackingindex= (u8)i;
8317 priv->rfa_txpowertrackingindex_real= (u8)i;
8318 priv->rfa_txpowertracking_default= priv->rfa_txpowertrackingindex;
8319 break;
8320 }
8321 }
8322
8323 TempCCk = rtl8192_QueryBBReg(dev, rCCK0_TxFilter1, bMaskByte2);
8324
8325 for(i=0 ; i<CCKTxBBGainTableLength ; i++)
8326 {
8327
8328 if(TempCCk == priv->cck_txbbgain_table[i].ccktxbb_valuearray[0])
8329 {
8330 priv->cck_present_attentuation_20Mdefault=(u8) i;
8331 break;
8332 }
8333 }
8334 priv->cck_present_attentuation_40Mdefault= 0;
8335 priv->cck_present_attentuation_difference= 0;
8336 priv->cck_present_attentuation = priv->cck_present_attentuation_20Mdefault;
8337
8338 // pMgntInfo->bTXPowerTracking = FALSE;//TEMPLY DISABLE
8339 }
8340 }
8341 write_nic_byte(dev, 0x87, 0x0);
8342
8343
8344#endif
8345 return init_status;
8346}
8347
8348#endif
8349/* this configures registers for beacon tx and enables it via
8350 * rtl8192_beacon_tx_enable(). rtl8192_beacon_tx_disable() might
8351 * be used to stop beacon transmission
8352 */
8353#if 0
8354void rtl8192_start_tx_beacon(struct net_device *dev)
8355{
8356 int i;
8357 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
8358 u16 word;
8359 DMESG("Enabling beacon TX");
8360 //write_nic_byte(dev, TX_CONF,0xe6);// TX_CONF
8361 //rtl8192_init_beacon(dev);
8362 //set_nic_txring(dev);
8363// rtl8192_prepare_beacon(dev);
8364 rtl8192_irq_disable(dev);
8365// rtl8192_beacon_tx_enable(dev);
8366 rtl8192_set_mode(dev,EPROM_CMD_CONFIG);
8367 //write_nic_byte(dev,0x9d,0x20); //DMA Poll
8368 //write_nic_word(dev,0x7a,0);
8369 //write_nic_word(dev,0x7a,0x8000);
8370
8371
8372 word = read_nic_word(dev, BcnItv);
8373 word &= ~BcnItv_BcnItv; // clear Bcn_Itv
8374 write_nic_word(dev, BcnItv, word);
8375
8376 write_nic_word(dev, AtimWnd,
8377 read_nic_word(dev, AtimWnd) &~ AtimWnd_AtimWnd);
8378
8379 word = read_nic_word(dev, BCN_INTR_ITV);
8380 word &= ~BCN_INTR_ITV_MASK;
8381
8382 //word |= priv->ieee80211->beacon_interval *
8383 // ((priv->txbeaconcount > 1)?(priv->txbeaconcount-1):1);
8384 // FIXME:FIXME check if correct ^^ worked with 0x3e8;
8385
8386 write_nic_word(dev, BCN_INTR_ITV, word);
8387
8388 //write_nic_word(dev,0x2e,0xe002);
8389 //write_nic_dword(dev,0x30,0xb8c7832e);
8390 for(i=0; i<ETH_ALEN; i++)
8391 write_nic_byte(dev, BSSID+i, priv->ieee80211->beacon_cell_ssid[i]);
8392
8393// rtl8192_update_msr(dev);
8394
8395
8396 //write_nic_byte(dev,CONFIG4,3); /* !!!!!!!!!! */
8397
8398 rtl8192_set_mode(dev, EPROM_CMD_NORMAL);
8399
8400 rtl8192_irq_enable(dev);
8401
8402 /* VV !!!!!!!!!! VV*/
8403 /*
8404 rtl8192_set_mode(dev,EPROM_CMD_CONFIG);
8405 write_nic_byte(dev,0x9d,0x00);
8406 rtl8192_set_mode(dev,EPROM_CMD_NORMAL);
8407*/
8408}
8409#endif
8410/***************************************************************************
8411 -------------------------------NET STUFF---------------------------
8412***************************************************************************/
8413
8414static struct net_device_stats *rtl8192_stats(struct net_device *dev)
8415{
8416 struct r8192_priv *priv = ieee80211_priv(dev);
8417
8418 return &priv->ieee80211->stats;
8419}
8420
8421bool
8422HalTxCheckStuck819xUsb(
8423 struct net_device *dev
8424 )
8425{
8426 struct r8192_priv *priv = ieee80211_priv(dev);
8427 u16 RegTxCounter = read_nic_word(dev, 0x128);
8428 bool bStuck = FALSE;
8429 RT_TRACE(COMP_RESET,"%s():RegTxCounter is %d,TxCounter is %d\n",__FUNCTION__,RegTxCounter,priv->TxCounter);
8430 if(priv->TxCounter==RegTxCounter)
8431 bStuck = TRUE;
8432
8433 priv->TxCounter = RegTxCounter;
8434
8435 return bStuck;
8436}
8437
8438/*
8439* <Assumption: RT_TX_SPINLOCK is acquired.>
8440* First added: 2006.11.19 by emily
8441*/
8442RESET_TYPE
8443TxCheckStuck(struct net_device *dev)
8444{
8445 struct r8192_priv *priv = ieee80211_priv(dev);
8446 u8 QueueID;
8447// PRT_TCB pTcb;
8448// u8 ResetThreshold;
8449 bool bCheckFwTxCnt = false;
8450 //unsigned long flags;
8451
8452 //
8453 // Decide Stuch threshold according to current power save mode
8454 //
8455
8456// RT_TRACE(COMP_RESET, " ==> TxCheckStuck()\n");
8457// PlatformAcquireSpinLock(Adapter, RT_TX_SPINLOCK);
8458// spin_lock_irqsave(&priv->ieee80211->lock,flags);
8459 for (QueueID = 0; QueueID<=BEACON_QUEUE;QueueID ++)
8460 {
8461 if(QueueID == TXCMD_QUEUE)
8462 continue;
8463#if 1
8464#ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
8465 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))
8466#else
8467 if((skb_queue_len(&priv->ieee80211->skb_waitQ[QueueID]) == 0) && (skb_queue_len(&priv->ieee80211->skb_aggQ[QueueID]) == 0))
8468#endif
8469 continue;
8470#endif
8471
8472 bCheckFwTxCnt = true;
8473 }
8474// PlatformReleaseSpinLock(Adapter, RT_TX_SPINLOCK);
8475// spin_unlock_irqrestore(&priv->ieee80211->lock,flags);
8476// RT_TRACE(COMP_RESET,"bCheckFwTxCnt is %d\n",bCheckFwTxCnt);
8477#if 1
8478 if(bCheckFwTxCnt)
8479 {
8480 if(HalTxCheckStuck819xUsb(dev))
8481 {
8482 RT_TRACE(COMP_RESET, "TxCheckStuck(): Fw indicates no Tx condition! \n");
8483 return RESET_TYPE_SILENT;
8484 }
8485 }
8486#endif
8487 return RESET_TYPE_NORESET;
8488}
8489
8490bool
8491HalRxCheckStuck819xUsb(struct net_device *dev)
8492{
8493 u16 RegRxCounter = read_nic_word(dev, 0x130);
8494 struct r8192_priv *priv = ieee80211_priv(dev);
8495 bool bStuck = FALSE;
8496//#ifdef RTL8192SU
8497
8498//#else
8499 static u8 rx_chk_cnt = 0;
8500 RT_TRACE(COMP_RESET,"%s(): RegRxCounter is %d,RxCounter is %d\n",__FUNCTION__,RegRxCounter,priv->RxCounter);
8501 // If rssi is small, we should check rx for long time because of bad rx.
8502 // or maybe it will continuous silent reset every 2 seconds.
8503 rx_chk_cnt++;
8504 if(priv->undecorated_smoothed_pwdb >= (RateAdaptiveTH_High+5))
8505 {
8506 rx_chk_cnt = 0; //high rssi, check rx stuck right now.
8507 }
8508 else if(priv->undecorated_smoothed_pwdb < (RateAdaptiveTH_High+5) &&
8509 ((priv->CurrentChannelBW!=HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb>=RateAdaptiveTH_Low_40M) ||
8510 (priv->CurrentChannelBW==HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb>=RateAdaptiveTH_Low_20M)) )
8511 {
8512 if(rx_chk_cnt < 2)
8513 {
8514 return bStuck;
8515 }
8516 else
8517 {
8518 rx_chk_cnt = 0;
8519 }
8520 }
8521 else if(((priv->CurrentChannelBW!=HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb<RateAdaptiveTH_Low_40M) ||
8522 (priv->CurrentChannelBW==HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb<RateAdaptiveTH_Low_20M)) &&
8523 priv->undecorated_smoothed_pwdb >= VeryLowRSSI)
8524 {
8525 if(rx_chk_cnt < 4)
8526 {
8527 //DbgPrint("RSSI < %d && RSSI >= %d, no check this time \n", RateAdaptiveTH_Low, VeryLowRSSI);
8528 return bStuck;
8529 }
8530 else
8531 {
8532 rx_chk_cnt = 0;
8533 //DbgPrint("RSSI < %d && RSSI >= %d, check this time \n", RateAdaptiveTH_Low, VeryLowRSSI);
8534 }
8535 }
8536 else
8537 {
8538 if(rx_chk_cnt < 8)
8539 {
8540 //DbgPrint("RSSI <= %d, no check this time \n", VeryLowRSSI);
8541 return bStuck;
8542 }
8543 else
8544 {
8545 rx_chk_cnt = 0;
8546 //DbgPrint("RSSI <= %d, check this time \n", VeryLowRSSI);
8547 }
8548 }
8549//#endif
8550
8551 if(priv->RxCounter==RegRxCounter)
8552 bStuck = TRUE;
8553
8554 priv->RxCounter = RegRxCounter;
8555
8556 return bStuck;
8557}
8558
8559RESET_TYPE
8560RxCheckStuck(struct net_device *dev)
8561{
8562 struct r8192_priv *priv = ieee80211_priv(dev);
8563 //int i;
8564 bool bRxCheck = FALSE;
8565
8566// RT_TRACE(COMP_RESET," ==> RxCheckStuck()\n");
8567 //PlatformAcquireSpinLock(Adapter, RT_RX_SPINLOCK);
8568
8569 if(priv->IrpPendingCount > 1)
8570 bRxCheck = TRUE;
8571 //PlatformReleaseSpinLock(Adapter, RT_RX_SPINLOCK);
8572
8573// RT_TRACE(COMP_RESET,"bRxCheck is %d \n",bRxCheck);
8574 if(bRxCheck)
8575 {
8576 if(HalRxCheckStuck819xUsb(dev))
8577 {
8578 RT_TRACE(COMP_RESET, "RxStuck Condition\n");
8579 return RESET_TYPE_SILENT;
8580 }
8581 }
8582 return RESET_TYPE_NORESET;
8583}
8584
8585
8586/**
8587* This function is called by Checkforhang to check whether we should ask OS to reset driver
8588*
8589* \param pAdapter The adapter context for this miniport
8590*
8591* Note:NIC with USB interface sholud not call this function because we cannot scan descriptor
8592* to judge whether there is tx stuck.
8593* Note: This function may be required to be rewrite for Vista OS.
8594* <<<Assumption: Tx spinlock has been acquired >>>
8595*
8596* 8185 and 8185b does not implement this function. This is added by Emily at 2006.11.24
8597*/
8598RESET_TYPE
8599rtl819x_ifcheck_resetornot(struct net_device *dev)
8600{
8601 struct r8192_priv *priv = ieee80211_priv(dev);
8602 RESET_TYPE TxResetType = RESET_TYPE_NORESET;
8603 RESET_TYPE RxResetType = RESET_TYPE_NORESET;
8604 RT_RF_POWER_STATE rfState;
8605
8606#if (defined (RTL8192SU_FPGA_2MAC_VERIFICATION)||defined (RTL8192SU_ASIC_VERIFICATION))
8607 return RESET_TYPE_NORESET;
8608#endif
8609
8610 rfState = priv->ieee80211->eRFPowerState;
8611
8612 TxResetType = TxCheckStuck(dev);
8613#if 1
8614 if( rfState != eRfOff ||
8615 /*ADAPTER_TEST_STATUS_FLAG(Adapter, ADAPTER_STATUS_FW_DOWNLOAD_FAILURE)) &&*/
8616 (priv->ieee80211->iw_mode != IW_MODE_ADHOC))
8617 {
8618 // If driver is in the status of firmware download failure , driver skips RF initialization and RF is
8619 // in turned off state. Driver should check whether Rx stuck and do silent reset. And
8620 // if driver is in firmware download failure status, driver should initialize RF in the following
8621 // silent reset procedure Emily, 2008.01.21
8622
8623 // Driver should not check RX stuck in IBSS mode because it is required to
8624 // set Check BSSID in order to send beacon, however, if check BSSID is
8625 // set, STA cannot hear any packet a all. Emily, 2008.04.12
8626 RxResetType = RxCheckStuck(dev);
8627 }
8628#endif
8629 if(TxResetType==RESET_TYPE_NORMAL || RxResetType==RESET_TYPE_NORMAL)
8630 return RESET_TYPE_NORMAL;
8631 else if(TxResetType==RESET_TYPE_SILENT || RxResetType==RESET_TYPE_SILENT){
8632 RT_TRACE(COMP_RESET,"%s():silent reset\n",__FUNCTION__);
8633 return RESET_TYPE_SILENT;
8634 }
8635 else
8636 return RESET_TYPE_NORESET;
8637
8638}
8639
8640void rtl8192_cancel_deferred_work(struct r8192_priv* priv);
8641int _rtl8192_up(struct net_device *dev);
8642int rtl8192_close(struct net_device *dev);
8643
8644
8645
8646void
8647CamRestoreAllEntry( struct net_device *dev)
8648{
8649 u8 EntryId = 0;
8650 struct r8192_priv *priv = ieee80211_priv(dev);
8651 u8* MacAddr = priv->ieee80211->current_network.bssid;
8652
8653 static u8 CAM_CONST_ADDR[4][6] = {
8654 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
8655 {0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
8656 {0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
8657 {0x00, 0x00, 0x00, 0x00, 0x00, 0x03}};
8658 static u8 CAM_CONST_BROAD[] =
8659 {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
8660
8661 RT_TRACE(COMP_SEC, "CamRestoreAllEntry: \n");
8662
8663
8664 if ((priv->ieee80211->pairwise_key_type == KEY_TYPE_WEP40)||
8665 (priv->ieee80211->pairwise_key_type == KEY_TYPE_WEP104))
8666 {
8667
8668 for(EntryId=0; EntryId<4; EntryId++)
8669 {
8670 {
8671 MacAddr = CAM_CONST_ADDR[EntryId];
8672 setKey(dev,
8673 EntryId ,
8674 EntryId,
8675 priv->ieee80211->pairwise_key_type,
8676 MacAddr,
8677 0,
8678 NULL);
8679 }
8680 }
8681
8682 }
8683 else if(priv->ieee80211->pairwise_key_type == KEY_TYPE_TKIP)
8684 {
8685
8686 {
8687 if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
8688 setKey(dev,
8689 4,
8690 0,
8691 priv->ieee80211->pairwise_key_type,
8692 (u8*)dev->dev_addr,
8693 0,
8694 NULL);
8695 else
8696 setKey(dev,
8697 4,
8698 0,
8699 priv->ieee80211->pairwise_key_type,
8700 MacAddr,
8701 0,
8702 NULL);
8703 }
8704 }
8705 else if(priv->ieee80211->pairwise_key_type == KEY_TYPE_CCMP)
8706 {
8707
8708 {
8709 if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
8710 setKey(dev,
8711 4,
8712 0,
8713 priv->ieee80211->pairwise_key_type,
8714 (u8*)dev->dev_addr,
8715 0,
8716 NULL);
8717 else
8718 setKey(dev,
8719 4,
8720 0,
8721 priv->ieee80211->pairwise_key_type,
8722 MacAddr,
8723 0,
8724 NULL);
8725 }
8726 }
8727
8728
8729
8730 if(priv->ieee80211->group_key_type == KEY_TYPE_TKIP)
8731 {
8732 MacAddr = CAM_CONST_BROAD;
8733 for(EntryId=1 ; EntryId<4 ; EntryId++)
8734 {
8735 {
8736 setKey(dev,
8737 EntryId,
8738 EntryId,
8739 priv->ieee80211->group_key_type,
8740 MacAddr,
8741 0,
8742 NULL);
8743 }
8744 }
8745 if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
8746 setKey(dev,
8747 0,
8748 0,
8749 priv->ieee80211->group_key_type,
8750 CAM_CONST_ADDR[0],
8751 0,
8752 NULL);
8753 }
8754 else if(priv->ieee80211->group_key_type == KEY_TYPE_CCMP)
8755 {
8756 MacAddr = CAM_CONST_BROAD;
8757 for(EntryId=1; EntryId<4 ; EntryId++)
8758 {
8759 {
8760 setKey(dev,
8761 EntryId ,
8762 EntryId,
8763 priv->ieee80211->group_key_type,
8764 MacAddr,
8765 0,
8766 NULL);
8767 }
8768 }
8769
8770 if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
8771 setKey(dev,
8772 0 ,
8773 0,
8774 priv->ieee80211->group_key_type,
8775 CAM_CONST_ADDR[0],
8776 0,
8777 NULL);
8778 }
8779}
8780//////////////////////////////////////////////////////////////
8781// This function is used to fix Tx/Rx stop bug temporarily.
8782// This function will do "system reset" to NIC when Tx or Rx is stuck.
8783// The method checking Tx/Rx stuck of this function is supported by FW,
8784// which reports Tx and Rx counter to register 0x128 and 0x130.
8785//////////////////////////////////////////////////////////////
8786void
8787rtl819x_ifsilentreset(struct net_device *dev)
8788{
8789 //OCTET_STRING asocpdu;
8790 struct r8192_priv *priv = ieee80211_priv(dev);
8791 u8 reset_times = 0;
8792 int reset_status = 0;
8793 struct ieee80211_device *ieee = priv->ieee80211;
8794
8795
8796 // 2007.07.20. If we need to check CCK stop, please uncomment this line.
8797 //bStuck = Adapter->HalFunc.CheckHWStopHandler(Adapter);
8798
8799 if(priv->ResetProgress==RESET_TYPE_NORESET)
8800 {
8801RESET_START:
8802
8803 RT_TRACE(COMP_RESET,"=========>Reset progress!! \n");
8804
8805 // Set the variable for reset.
8806 priv->ResetProgress = RESET_TYPE_SILENT;
8807// rtl8192_close(dev);
8808#if 1
8809 down(&priv->wx_sem);
8810 if(priv->up == 0)
8811 {
8812 RT_TRACE(COMP_ERR,"%s():the driver is not up! return\n",__FUNCTION__);
8813 up(&priv->wx_sem);
8814 return ;
8815 }
8816 priv->up = 0;
8817 RT_TRACE(COMP_RESET,"%s():======>start to down the driver\n",__FUNCTION__);
8818// if(!netif_queue_stopped(dev))
8819// netif_stop_queue(dev);
8820
8821 rtl8192_rtx_disable(dev);
8822 rtl8192_cancel_deferred_work(priv);
8823 deinit_hal_dm(dev);
8824 del_timer_sync(&priv->watch_dog_timer);
8825
8826 ieee->sync_scan_hurryup = 1;
8827 if(ieee->state == IEEE80211_LINKED)
8828 {
8829 down(&ieee->wx_sem);
8830 printk("ieee->state is IEEE80211_LINKED\n");
8831 ieee80211_stop_send_beacons(priv->ieee80211);
8832 del_timer_sync(&ieee->associate_timer);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07008833 cancel_delayed_work(&ieee->associate_retry_wq);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07008834 ieee80211_stop_scan(ieee);
8835 netif_carrier_off(dev);
8836 up(&ieee->wx_sem);
8837 }
8838 else{
8839 printk("ieee->state is NOT LINKED\n");
8840 ieee80211_softmac_stop_protocol(priv->ieee80211); }
8841 up(&priv->wx_sem);
8842 RT_TRACE(COMP_RESET,"%s():<==========down process is finished\n",__FUNCTION__);
8843 //rtl8192_irq_disable(dev);
8844 RT_TRACE(COMP_RESET,"%s():===========>start to up the driver\n",__FUNCTION__);
8845 reset_status = _rtl8192_up(dev);
8846
8847 RT_TRACE(COMP_RESET,"%s():<===========up process is finished\n",__FUNCTION__);
8848 if(reset_status == -EAGAIN)
8849 {
8850 if(reset_times < 3)
8851 {
8852 reset_times++;
8853 goto RESET_START;
8854 }
8855 else
8856 {
8857 RT_TRACE(COMP_ERR," ERR!!! %s(): Reset Failed!!\n", __FUNCTION__);
8858 }
8859 }
8860#endif
8861 ieee->is_silent_reset = 1;
8862#if 1
8863 EnableHWSecurityConfig8192(dev);
8864#if 1
8865 if(ieee->state == IEEE80211_LINKED && ieee->iw_mode == IW_MODE_INFRA)
8866 {
8867 ieee->set_chan(ieee->dev, ieee->current_network.channel);
8868
8869#if 1
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07008870 queue_work(ieee->wq, &ieee->associate_complete_wq);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07008871#endif
8872
8873 }
8874 else if(ieee->state == IEEE80211_LINKED && ieee->iw_mode == IW_MODE_ADHOC)
8875 {
8876 ieee->set_chan(ieee->dev, ieee->current_network.channel);
8877 ieee->link_change(ieee->dev);
8878
8879 // notify_wx_assoc_event(ieee);
8880
8881 ieee80211_start_send_beacons(ieee);
8882
8883 if (ieee->data_hard_resume)
8884 ieee->data_hard_resume(ieee->dev);
8885 netif_carrier_on(ieee->dev);
8886 }
8887#endif
8888
8889 CamRestoreAllEntry(dev);
8890
8891 priv->ResetProgress = RESET_TYPE_NORESET;
8892 priv->reset_count++;
8893
8894 priv->bForcedSilentReset =false;
8895 priv->bResetInProgress = false;
8896
8897 // For test --> force write UFWP.
8898 write_nic_byte(dev, UFWP, 1);
8899 RT_TRACE(COMP_RESET, "Reset finished!! ====>[%d]\n", priv->reset_count);
8900#endif
8901 }
8902}
8903
8904void CAM_read_entry(
8905 struct net_device *dev,
8906 u32 iIndex
8907)
8908{
8909 u32 target_command=0;
8910 u32 target_content=0;
8911 u8 entry_i=0;
8912 u32 ulStatus;
8913 s32 i=100;
8914// printk("=======>start read CAM\n");
8915 for(entry_i=0;entry_i<CAM_CONTENT_COUNT;entry_i++)
8916 {
8917 // polling bit, and No Write enable, and address
8918 target_command= entry_i+CAM_CONTENT_COUNT*iIndex;
8919 target_command= target_command | BIT31;
8920
8921 //Check polling bit is clear
8922// mdelay(1);
8923#if 1
8924 while((i--)>=0)
8925 {
8926 ulStatus = read_nic_dword(dev, RWCAM);
8927 if(ulStatus & BIT31){
8928 continue;
8929 }
8930 else{
8931 break;
8932 }
8933 }
8934#endif
8935 write_nic_dword(dev, RWCAM, target_command);
8936 RT_TRACE(COMP_SEC,"CAM_read_entry(): WRITE A0: %x \n",target_command);
8937 // printk("CAM_read_entry(): WRITE A0: %lx \n",target_command);
8938 target_content = read_nic_dword(dev, RCAMO);
8939 RT_TRACE(COMP_SEC, "CAM_read_entry(): WRITE A8: %x \n",target_content);
8940 // printk("CAM_read_entry(): WRITE A8: %lx \n",target_content);
8941 }
8942 printk("\n");
8943}
8944
8945void rtl819x_update_rxcounts(
8946 struct r8192_priv *priv,
8947 u32* TotalRxBcnNum,
8948 u32* TotalRxDataNum
8949)
8950{
8951 u16 SlotIndex;
8952 u8 i;
8953
8954 *TotalRxBcnNum = 0;
8955 *TotalRxDataNum = 0;
8956
8957 SlotIndex = (priv->ieee80211->LinkDetectInfo.SlotIndex++)%(priv->ieee80211->LinkDetectInfo.SlotNum);
8958 priv->ieee80211->LinkDetectInfo.RxBcnNum[SlotIndex] = priv->ieee80211->LinkDetectInfo.NumRecvBcnInPeriod;
8959 priv->ieee80211->LinkDetectInfo.RxDataNum[SlotIndex] = priv->ieee80211->LinkDetectInfo.NumRecvDataInPeriod;
8960 for( i=0; i<priv->ieee80211->LinkDetectInfo.SlotNum; i++ ){
8961 *TotalRxBcnNum += priv->ieee80211->LinkDetectInfo.RxBcnNum[i];
8962 *TotalRxDataNum += priv->ieee80211->LinkDetectInfo.RxDataNum[i];
8963 }
8964}
8965
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07008966extern void rtl819x_watchdog_wqcallback(struct work_struct *work)
8967{
8968 struct delayed_work *dwork = container_of(work,struct delayed_work,work);
8969 struct r8192_priv *priv = container_of(dwork,struct r8192_priv,watch_dog_wq);
8970 struct net_device *dev = priv->ieee80211->dev;
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07008971 struct ieee80211_device* ieee = priv->ieee80211;
8972 RESET_TYPE ResetType = RESET_TYPE_NORESET;
8973 static u8 check_reset_cnt=0;
8974 bool bBusyTraffic = false;
8975
8976 if(!priv->up)
8977 return;
8978 hal_dm_watchdog(dev);
8979
8980 {//to get busy traffic condition
8981 if(ieee->state == IEEE80211_LINKED)
8982 {
8983 //windows mod 666 to 100.
8984 //if( ieee->LinkDetectInfo.NumRxOkInPeriod> 666 ||
8985 // ieee->LinkDetectInfo.NumTxOkInPeriod> 666 ) {
8986 if( ieee->LinkDetectInfo.NumRxOkInPeriod> 100 ||
8987 ieee->LinkDetectInfo.NumTxOkInPeriod> 100 ) {
8988 bBusyTraffic = true;
8989 }
8990 ieee->LinkDetectInfo.NumRxOkInPeriod = 0;
8991 ieee->LinkDetectInfo.NumTxOkInPeriod = 0;
8992 ieee->LinkDetectInfo.bBusyTraffic = bBusyTraffic;
8993 }
8994 }
8995 //added by amy for AP roaming
8996 {
8997 if(priv->ieee80211->state == IEEE80211_LINKED && priv->ieee80211->iw_mode == IW_MODE_INFRA)
8998 {
8999 u32 TotalRxBcnNum = 0;
9000 u32 TotalRxDataNum = 0;
9001
9002 rtl819x_update_rxcounts(priv, &TotalRxBcnNum, &TotalRxDataNum);
9003 if((TotalRxBcnNum+TotalRxDataNum) == 0)
9004 {
9005 #ifdef TODO
9006 if(rfState == eRfOff)
9007 RT_TRACE(COMP_ERR,"========>%s()\n",__FUNCTION__);
9008 #endif
9009 printk("===>%s(): AP is power off,connect another one\n",__FUNCTION__);
9010 // Dot11d_Reset(dev);
9011 priv->ieee80211->state = IEEE80211_ASSOCIATING;
9012 notify_wx_assoc_event(priv->ieee80211);
9013 RemovePeerTS(priv->ieee80211,priv->ieee80211->current_network.bssid);
9014 ieee->is_roaming = true;
9015 priv->ieee80211->link_change(dev);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07009016 queue_work(priv->ieee80211->wq, &priv->ieee80211->associate_procedure_wq);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07009017 }
9018 }
9019 priv->ieee80211->LinkDetectInfo.NumRecvBcnInPeriod=0;
9020 priv->ieee80211->LinkDetectInfo.NumRecvDataInPeriod=0;
9021 }
9022// CAM_read_entry(dev,4);
9023 //check if reset the driver
9024 if(check_reset_cnt++ >= 3 && !ieee->is_roaming)
9025 {
9026 ResetType = rtl819x_ifcheck_resetornot(dev);
9027 check_reset_cnt = 3;
9028 //DbgPrint("Start to check silent reset\n");
9029 }
9030 // 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);
9031#if 1
9032 if( (priv->force_reset) || (priv->ResetProgress==RESET_TYPE_NORESET &&
9033 (priv->bForcedSilentReset ||
9034 (!priv->bDisableNormalResetCheck && ResetType==RESET_TYPE_SILENT)))) // This is control by OID set in Pomelo
9035 {
9036 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);
9037 rtl819x_ifsilentreset(dev);
9038 }
9039#endif
9040 priv->force_reset = false;
9041 priv->bForcedSilentReset = false;
9042 priv->bResetInProgress = false;
9043 RT_TRACE(COMP_TRACE, " <==RtUsbCheckForHangWorkItemCallback()\n");
9044
9045}
9046
9047void watch_dog_timer_callback(unsigned long data)
9048{
9049 struct r8192_priv *priv = ieee80211_priv((struct net_device *) data);
9050 //printk("===============>watch_dog timer\n");
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07009051 queue_delayed_work(priv->priv_wq,&priv->watch_dog_wq, 0);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07009052 mod_timer(&priv->watch_dog_timer, jiffies + MSECS(IEEE80211_WATCH_DOG_TIME));
9053#if 0
9054 priv->watch_dog_timer.expires = jiffies + MSECS(IEEE80211_WATCH_DOG_TIME);
9055 add_timer(&priv->watch_dog_timer);
9056#endif
9057}
9058int _rtl8192_up(struct net_device *dev)
9059{
9060 struct r8192_priv *priv = ieee80211_priv(dev);
9061 //int i;
9062 int init_status = 0;
9063 priv->up=1;
9064 priv->ieee80211->ieee_up=1;
9065 RT_TRACE(COMP_INIT, "Bringing up iface");
9066 init_status = priv->ops->rtl819x_adapter_start(dev);
9067 if(!init_status)
9068 {
9069 RT_TRACE(COMP_ERR,"ERR!!! %s(): initialization is failed!\n", __FUNCTION__);
9070 priv->up=priv->ieee80211->ieee_up = 0;
9071 return -EAGAIN;
9072 }
9073 RT_TRACE(COMP_INIT, "start adapter finished\n");
9074 rtl8192_rx_enable(dev);
9075// rtl8192_tx_enable(dev);
9076 if(priv->ieee80211->state != IEEE80211_LINKED)
9077 ieee80211_softmac_start_protocol(priv->ieee80211);
9078 ieee80211_reset_queue(priv->ieee80211);
9079 watch_dog_timer_callback((unsigned long) dev);
9080 if(!netif_queue_stopped(dev))
9081 netif_start_queue(dev);
9082 else
9083 netif_wake_queue(dev);
9084
9085 /*
9086 * Make sure that drop_unencrypted is initialized as "0"
9087 * No packets will be sent in non-security mode if we had set drop_unencrypted.
9088 * ex, After kill wpa_supplicant process, make the driver up again.
9089 * drop_unencrypted remains as "1", which is set by wpa_supplicant. 2008/12/04.john
9090 */
9091 priv->ieee80211->drop_unencrypted = 0;
9092
9093 return 0;
9094}
9095
9096
9097int rtl8192_open(struct net_device *dev)
9098{
9099 struct r8192_priv *priv = ieee80211_priv(dev);
9100 int ret;
9101 down(&priv->wx_sem);
9102 ret = rtl8192_up(dev);
9103 up(&priv->wx_sem);
9104 return ret;
9105
9106}
9107
9108
9109int rtl8192_up(struct net_device *dev)
9110{
9111 struct r8192_priv *priv = ieee80211_priv(dev);
9112
9113 if (priv->up == 1) return -1;
9114
9115 return _rtl8192_up(dev);
9116}
9117
9118
9119int rtl8192_close(struct net_device *dev)
9120{
9121 struct r8192_priv *priv = ieee80211_priv(dev);
9122 int ret;
9123
9124 down(&priv->wx_sem);
9125
9126 ret = rtl8192_down(dev);
9127
9128 up(&priv->wx_sem);
9129
9130 return ret;
9131
9132}
9133
9134int rtl8192_down(struct net_device *dev)
9135{
9136 struct r8192_priv *priv = ieee80211_priv(dev);
9137 int i;
9138
9139 if (priv->up == 0) return -1;
9140
9141 priv->up=0;
9142 priv->ieee80211->ieee_up = 0;
9143 RT_TRACE(COMP_DOWN, "==========>%s()\n", __FUNCTION__);
9144/* FIXME */
9145 if (!netif_queue_stopped(dev))
9146 netif_stop_queue(dev);
9147
9148 rtl8192_rtx_disable(dev);
9149 //rtl8192_irq_disable(dev);
9150
9151 /* Tx related queue release */
9152 for(i = 0; i < MAX_QUEUE_SIZE; i++) {
9153 skb_queue_purge(&priv->ieee80211->skb_waitQ [i]);
9154 }
9155 for(i = 0; i < MAX_QUEUE_SIZE; i++) {
9156 skb_queue_purge(&priv->ieee80211->skb_aggQ [i]);
9157 }
9158
9159 for(i = 0; i < MAX_QUEUE_SIZE; i++) {
9160 skb_queue_purge(&priv->ieee80211->skb_drv_aggQ [i]);
9161 }
9162
9163 //as cancel_delayed_work will del work->timer, so if work is not definedas struct delayed_work, it will corrupt
9164// flush_scheduled_work();
9165 rtl8192_cancel_deferred_work(priv);
9166 deinit_hal_dm(dev);
9167 del_timer_sync(&priv->watch_dog_timer);
9168
9169
9170 ieee80211_softmac_stop_protocol(priv->ieee80211);
9171 memset(&priv->ieee80211->current_network, 0 , offsetof(struct ieee80211_network, list));
9172 RT_TRACE(COMP_DOWN, "<==========%s()\n", __FUNCTION__);
9173
9174 return 0;
9175}
9176
9177
9178void rtl8192_commit(struct net_device *dev)
9179{
9180 struct r8192_priv *priv = ieee80211_priv(dev);
9181 int reset_status = 0;
9182 //u8 reset_times = 0;
9183 if (priv->up == 0) return ;
9184 priv->up = 0;
9185
9186 rtl8192_cancel_deferred_work(priv);
9187 del_timer_sync(&priv->watch_dog_timer);
9188 //cancel_delayed_work(&priv->SwChnlWorkItem);
9189
9190 ieee80211_softmac_stop_protocol(priv->ieee80211);
9191
9192 //rtl8192_irq_disable(dev);
9193 rtl8192_rtx_disable(dev);
9194 reset_status = _rtl8192_up(dev);
9195
9196}
9197
9198/*
9199void rtl8192_restart(struct net_device *dev)
9200{
9201 struct r8192_priv *priv = ieee80211_priv(dev);
9202*/
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07009203void rtl8192_restart(struct work_struct *work)
9204{
9205 struct r8192_priv *priv = container_of(work, struct r8192_priv, reset_wq);
9206 struct net_device *dev = priv->ieee80211->dev;
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07009207
9208 down(&priv->wx_sem);
9209
9210 rtl8192_commit(dev);
9211
9212 up(&priv->wx_sem);
9213}
9214
9215static void r8192_set_multicast(struct net_device *dev)
9216{
9217 struct r8192_priv *priv = ieee80211_priv(dev);
9218 short promisc;
9219
9220 //down(&priv->wx_sem);
9221
9222 /* FIXME FIXME */
9223
9224 promisc = (dev->flags & IFF_PROMISC) ? 1:0;
9225
9226 if (promisc != priv->promisc)
9227 // rtl8192_commit(dev);
9228
9229 priv->promisc = promisc;
9230
9231 //schedule_work(&priv->reset_wq);
9232 //up(&priv->wx_sem);
9233}
9234
9235
9236int r8192_set_mac_adr(struct net_device *dev, void *mac)
9237{
9238 struct r8192_priv *priv = ieee80211_priv(dev);
9239 struct sockaddr *addr = mac;
9240
9241 down(&priv->wx_sem);
9242
9243 memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
9244
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07009245 schedule_work(&priv->reset_wq);
Bartlomiej Zolnierkiewicz1ec9e482009-06-13 18:35:04 +02009246
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07009247 up(&priv->wx_sem);
9248
9249 return 0;
9250}
9251
9252/* based on ipw2200 driver */
9253int rtl8192_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
9254{
9255 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
9256 struct iwreq *wrq = (struct iwreq *)rq;
9257 int ret=-1;
9258 struct ieee80211_device *ieee = priv->ieee80211;
9259 u32 key[4];
9260 u8 broadcast_addr[6] = {0xff,0xff,0xff,0xff,0xff,0xff};
9261 u8 zero_addr[6] = {0};
9262 struct iw_point *p = &wrq->u.data;
9263 struct ieee_param *ipw = NULL;//(struct ieee_param *)wrq->u.data.pointer;
9264
9265 down(&priv->wx_sem);
9266
9267
9268 if (p->length < sizeof(struct ieee_param) || !p->pointer){
9269 ret = -EINVAL;
9270 goto out;
9271 }
9272
9273 ipw = (struct ieee_param *)kmalloc(p->length, GFP_KERNEL);
9274 if (ipw == NULL){
9275 ret = -ENOMEM;
9276 goto out;
9277 }
9278 if (copy_from_user(ipw, p->pointer, p->length)) {
9279 kfree(ipw);
9280 ret = -EFAULT;
9281 goto out;
9282 }
9283
9284 switch (cmd) {
9285 case RTL_IOCTL_WPA_SUPPLICANT:
9286 //parse here for HW security
9287 if (ipw->cmd == IEEE_CMD_SET_ENCRYPTION)
9288 {
9289 if (ipw->u.crypt.set_tx)
9290 {
9291 if (strcmp(ipw->u.crypt.alg, "CCMP") == 0)
9292 ieee->pairwise_key_type = KEY_TYPE_CCMP;
9293 else if (strcmp(ipw->u.crypt.alg, "TKIP") == 0)
9294 ieee->pairwise_key_type = KEY_TYPE_TKIP;
9295 else if (strcmp(ipw->u.crypt.alg, "WEP") == 0)
9296 {
9297 if (ipw->u.crypt.key_len == 13)
9298 ieee->pairwise_key_type = KEY_TYPE_WEP104;
9299 else if (ipw->u.crypt.key_len == 5)
9300 ieee->pairwise_key_type = KEY_TYPE_WEP40;
9301 }
9302 else
9303 ieee->pairwise_key_type = KEY_TYPE_NA;
9304
9305 if (ieee->pairwise_key_type)
9306 {
9307 // 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
9308 if (memcmp(ieee->ap_mac_addr, zero_addr, 6) == 0)
9309 ieee->iw_mode = IW_MODE_ADHOC;
9310 memcpy((u8*)key, ipw->u.crypt.key, 16);
9311 EnableHWSecurityConfig8192(dev);
9312 //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!
9313 //added by WB.
9314 setKey(dev, 4, ipw->u.crypt.idx, ieee->pairwise_key_type, (u8*)ieee->ap_mac_addr, 0, key);
9315 if (ieee->iw_mode == IW_MODE_ADHOC)
9316 setKey(dev, ipw->u.crypt.idx, ipw->u.crypt.idx, ieee->pairwise_key_type, (u8*)ieee->ap_mac_addr, 0, key);
9317 }
9318 }
9319 else //if (ipw->u.crypt.idx) //group key use idx > 0
9320 {
9321 memcpy((u8*)key, ipw->u.crypt.key, 16);
9322 if (strcmp(ipw->u.crypt.alg, "CCMP") == 0)
9323 ieee->group_key_type= KEY_TYPE_CCMP;
9324 else if (strcmp(ipw->u.crypt.alg, "TKIP") == 0)
9325 ieee->group_key_type = KEY_TYPE_TKIP;
9326 else if (strcmp(ipw->u.crypt.alg, "WEP") == 0)
9327 {
9328 if (ipw->u.crypt.key_len == 13)
9329 ieee->group_key_type = KEY_TYPE_WEP104;
9330 else if (ipw->u.crypt.key_len == 5)
9331 ieee->group_key_type = KEY_TYPE_WEP40;
9332 }
9333 else
9334 ieee->group_key_type = KEY_TYPE_NA;
9335
9336 if (ieee->group_key_type)
9337 {
9338 setKey( dev,
9339 ipw->u.crypt.idx,
9340 ipw->u.crypt.idx, //KeyIndex
9341 ieee->group_key_type, //KeyType
9342 broadcast_addr, //MacAddr
9343 0, //DefaultKey
9344 key); //KeyContent
9345 }
9346 }
9347 }
9348#ifdef JOHN_HWSEC_DEBUG
9349 //john's test 0711
9350 printk("@@ wrq->u pointer = ");
9351 for(i=0;i<wrq->u.data.length;i++){
9352 if(i%10==0) printk("\n");
9353 printk( "%8x|", ((u32*)wrq->u.data.pointer)[i] );
9354 }
9355 printk("\n");
9356#endif /*JOHN_HWSEC_DEBUG*/
9357 ret = ieee80211_wpa_supplicant_ioctl(priv->ieee80211, &wrq->u.data);
9358 break;
9359
9360 default:
9361 ret = -EOPNOTSUPP;
9362 break;
9363 }
9364 kfree(ipw);
9365 ipw = NULL;
9366out:
9367 up(&priv->wx_sem);
9368 return ret;
9369}
9370
9371#ifdef RTL8192SU
9372u8 rtl8192SU_HwRateToMRate(bool bIsHT, u8 rate,bool bFirstAMPDU)
9373{
9374
9375 u8 ret_rate = 0x02;
9376
9377 if( bFirstAMPDU )
9378 {
9379 if(!bIsHT)
9380 {
9381 switch(rate)
9382 {
9383
9384 case DESC92S_RATE1M: ret_rate = MGN_1M; break;
9385 case DESC92S_RATE2M: ret_rate = MGN_2M; break;
9386 case DESC92S_RATE5_5M: ret_rate = MGN_5_5M; break;
9387 case DESC92S_RATE11M: ret_rate = MGN_11M; break;
9388 case DESC92S_RATE6M: ret_rate = MGN_6M; break;
9389 case DESC92S_RATE9M: ret_rate = MGN_9M; break;
9390 case DESC92S_RATE12M: ret_rate = MGN_12M; break;
9391 case DESC92S_RATE18M: ret_rate = MGN_18M; break;
9392 case DESC92S_RATE24M: ret_rate = MGN_24M; break;
9393 case DESC92S_RATE36M: ret_rate = MGN_36M; break;
9394 case DESC92S_RATE48M: ret_rate = MGN_48M; break;
9395 case DESC92S_RATE54M: ret_rate = MGN_54M; break;
9396
9397 default:
9398 RT_TRACE(COMP_RECV, "HwRateToMRate90(): Non supported Rate [%x], bIsHT = %d!!!\n", rate, bIsHT);
9399 break;
9400 }
9401 }
9402 else
9403 {
9404 switch(rate)
9405 {
9406
9407 case DESC92S_RATEMCS0: ret_rate = MGN_MCS0; break;
9408 case DESC92S_RATEMCS1: ret_rate = MGN_MCS1; break;
9409 case DESC92S_RATEMCS2: ret_rate = MGN_MCS2; break;
9410 case DESC92S_RATEMCS3: ret_rate = MGN_MCS3; break;
9411 case DESC92S_RATEMCS4: ret_rate = MGN_MCS4; break;
9412 case DESC92S_RATEMCS5: ret_rate = MGN_MCS5; break;
9413 case DESC92S_RATEMCS6: ret_rate = MGN_MCS6; break;
9414 case DESC92S_RATEMCS7: ret_rate = MGN_MCS7; break;
9415 case DESC92S_RATEMCS8: ret_rate = MGN_MCS8; break;
9416 case DESC92S_RATEMCS9: ret_rate = MGN_MCS9; break;
9417 case DESC92S_RATEMCS10: ret_rate = MGN_MCS10; break;
9418 case DESC92S_RATEMCS11: ret_rate = MGN_MCS11; break;
9419 case DESC92S_RATEMCS12: ret_rate = MGN_MCS12; break;
9420 case DESC92S_RATEMCS13: ret_rate = MGN_MCS13; break;
9421 case DESC92S_RATEMCS14: ret_rate = MGN_MCS14; break;
9422 case DESC92S_RATEMCS15: ret_rate = MGN_MCS15; break;
9423 case DESC92S_RATEMCS32: ret_rate = (0x80|0x20); break;
9424
9425 default:
9426 RT_TRACE(COMP_RECV, "HwRateToMRate92S(): Non supported Rate [%x], bIsHT = %d!!!\n",rate, bIsHT );
9427 break;
9428 }
9429
9430 }
9431 }
9432 else
9433 {
9434 switch(rate)
9435 {
9436
9437 case DESC92S_RATE1M: ret_rate = MGN_1M; break;
9438 case DESC92S_RATE2M: ret_rate = MGN_2M; break;
9439 case DESC92S_RATE5_5M: ret_rate = MGN_5_5M; break;
9440 case DESC92S_RATE11M: ret_rate = MGN_11M; break;
9441 case DESC92S_RATE6M: ret_rate = MGN_6M; break;
9442 case DESC92S_RATE9M: ret_rate = MGN_9M; break;
9443 case DESC92S_RATE12M: ret_rate = MGN_12M; break;
9444 case DESC92S_RATE18M: ret_rate = MGN_18M; break;
9445 case DESC92S_RATE24M: ret_rate = MGN_24M; break;
9446 case DESC92S_RATE36M: ret_rate = MGN_36M; break;
9447 case DESC92S_RATE48M: ret_rate = MGN_48M; break;
9448 case DESC92S_RATE54M: ret_rate = MGN_54M; break;
9449 case DESC92S_RATEMCS0: ret_rate = MGN_MCS0; break;
9450 case DESC92S_RATEMCS1: ret_rate = MGN_MCS1; break;
9451 case DESC92S_RATEMCS2: ret_rate = MGN_MCS2; break;
9452 case DESC92S_RATEMCS3: ret_rate = MGN_MCS3; break;
9453 case DESC92S_RATEMCS4: ret_rate = MGN_MCS4; break;
9454 case DESC92S_RATEMCS5: ret_rate = MGN_MCS5; break;
9455 case DESC92S_RATEMCS6: ret_rate = MGN_MCS6; break;
9456 case DESC92S_RATEMCS7: ret_rate = MGN_MCS7; break;
9457 case DESC92S_RATEMCS8: ret_rate = MGN_MCS8; break;
9458 case DESC92S_RATEMCS9: ret_rate = MGN_MCS9; break;
9459 case DESC92S_RATEMCS10: ret_rate = MGN_MCS10; break;
9460 case DESC92S_RATEMCS11: ret_rate = MGN_MCS11; break;
9461 case DESC92S_RATEMCS12: ret_rate = MGN_MCS12; break;
9462 case DESC92S_RATEMCS13: ret_rate = MGN_MCS13; break;
9463 case DESC92S_RATEMCS14: ret_rate = MGN_MCS14; break;
9464 case DESC92S_RATEMCS15: ret_rate = MGN_MCS15; break;
9465 case DESC92S_RATEMCS32: ret_rate = (0x80|0x20); break;
9466
9467 default:
9468 RT_TRACE(COMP_RECV, "HwRateToMRate92S(): Non supported Rate [%x], bIsHT = %d!!!\n",rate, bIsHT );
9469 break;
9470 }
9471 }
9472 return ret_rate;
9473}
9474#endif
9475
9476u8 HwRateToMRate90(bool bIsHT, u8 rate)
9477{
9478 u8 ret_rate = 0xff;
9479
9480 if(!bIsHT) {
9481 switch(rate) {
9482 case DESC90_RATE1M: ret_rate = MGN_1M; break;
9483 case DESC90_RATE2M: ret_rate = MGN_2M; break;
9484 case DESC90_RATE5_5M: ret_rate = MGN_5_5M; break;
9485 case DESC90_RATE11M: ret_rate = MGN_11M; break;
9486 case DESC90_RATE6M: ret_rate = MGN_6M; break;
9487 case DESC90_RATE9M: ret_rate = MGN_9M; break;
9488 case DESC90_RATE12M: ret_rate = MGN_12M; break;
9489 case DESC90_RATE18M: ret_rate = MGN_18M; break;
9490 case DESC90_RATE24M: ret_rate = MGN_24M; break;
9491 case DESC90_RATE36M: ret_rate = MGN_36M; break;
9492 case DESC90_RATE48M: ret_rate = MGN_48M; break;
9493 case DESC90_RATE54M: ret_rate = MGN_54M; break;
9494
9495 default:
9496 ret_rate = 0xff;
9497 RT_TRACE(COMP_RECV, "HwRateToMRate90(): Non supported Rate [%x], bIsHT = %d!!!\n", rate, bIsHT);
9498 break;
9499 }
9500
9501 } else {
9502 switch(rate) {
9503 case DESC90_RATEMCS0: ret_rate = MGN_MCS0; break;
9504 case DESC90_RATEMCS1: ret_rate = MGN_MCS1; break;
9505 case DESC90_RATEMCS2: ret_rate = MGN_MCS2; break;
9506 case DESC90_RATEMCS3: ret_rate = MGN_MCS3; break;
9507 case DESC90_RATEMCS4: ret_rate = MGN_MCS4; break;
9508 case DESC90_RATEMCS5: ret_rate = MGN_MCS5; break;
9509 case DESC90_RATEMCS6: ret_rate = MGN_MCS6; break;
9510 case DESC90_RATEMCS7: ret_rate = MGN_MCS7; break;
9511 case DESC90_RATEMCS8: ret_rate = MGN_MCS8; break;
9512 case DESC90_RATEMCS9: ret_rate = MGN_MCS9; break;
9513 case DESC90_RATEMCS10: ret_rate = MGN_MCS10; break;
9514 case DESC90_RATEMCS11: ret_rate = MGN_MCS11; break;
9515 case DESC90_RATEMCS12: ret_rate = MGN_MCS12; break;
9516 case DESC90_RATEMCS13: ret_rate = MGN_MCS13; break;
9517 case DESC90_RATEMCS14: ret_rate = MGN_MCS14; break;
9518 case DESC90_RATEMCS15: ret_rate = MGN_MCS15; break;
9519 case DESC90_RATEMCS32: ret_rate = (0x80|0x20); break;
9520
9521 default:
9522 ret_rate = 0xff;
9523 RT_TRACE(COMP_RECV, "HwRateToMRate90(): Non supported Rate [%x], bIsHT = %d!!!\n",rate, bIsHT);
9524 break;
9525 }
9526 }
9527
9528 return ret_rate;
9529}
9530
9531/**
9532 * Function: UpdateRxPktTimeStamp
9533 * Overview: Recored down the TSF time stamp when receiving a packet
9534 *
9535 * Input:
9536 * PADAPTER Adapter
9537 * PRT_RFD pRfd,
9538 *
9539 * Output:
9540 * PRT_RFD pRfd
9541 * (pRfd->Status.TimeStampHigh is updated)
9542 * (pRfd->Status.TimeStampLow is updated)
9543 * Return:
9544 * None
9545 */
9546void UpdateRxPktTimeStamp8190 (struct net_device *dev, struct ieee80211_rx_stats *stats)
9547{
9548 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
9549
9550 if(stats->bIsAMPDU && !stats->bFirstMPDU) {
9551 stats->mac_time[0] = priv->LastRxDescTSFLow;
9552 stats->mac_time[1] = priv->LastRxDescTSFHigh;
9553 } else {
9554 priv->LastRxDescTSFLow = stats->mac_time[0];
9555 priv->LastRxDescTSFHigh = stats->mac_time[1];
9556 }
9557}
9558
9559//by amy 080606
9560
9561long rtl819x_translate_todbm(u8 signal_strength_index )// 0-100 index.
9562{
9563 long signal_power; // in dBm.
9564
9565 // Translate to dBm (x=0.5y-95).
9566 signal_power = (long)((signal_strength_index + 1) >> 1);
9567 signal_power -= 95;
9568
9569 return signal_power;
9570}
9571
9572
9573/* 2008/01/22 MH We can not delcare RSSI/EVM total value of sliding window to
9574 be a local static. Otherwise, it may increase when we return from S3/S4. The
9575 value will be kept in memory or disk. We must delcare the value in adapter
9576 and it will be reinitialized when return from S3/S4. */
9577void rtl8192_process_phyinfo(struct r8192_priv * priv,u8* buffer, struct ieee80211_rx_stats * pprevious_stats, struct ieee80211_rx_stats * pcurrent_stats)
9578{
9579 bool bcheck = false;
9580 u8 rfpath;
9581 u32 nspatial_stream, tmp_val;
9582 //u8 i;
9583 static u32 slide_rssi_index=0, slide_rssi_statistics=0;
9584 static u32 slide_evm_index=0, slide_evm_statistics=0;
9585 static u32 last_rssi=0, last_evm=0;
9586
9587 static u32 slide_beacon_adc_pwdb_index=0, slide_beacon_adc_pwdb_statistics=0;
9588 static u32 last_beacon_adc_pwdb=0;
9589
9590 struct ieee80211_hdr_3addr *hdr;
9591 u16 sc ;
9592 unsigned int frag,seq;
9593 hdr = (struct ieee80211_hdr_3addr *)buffer;
9594 sc = le16_to_cpu(hdr->seq_ctl);
9595 frag = WLAN_GET_SEQ_FRAG(sc);
9596 seq = WLAN_GET_SEQ_SEQ(sc);
9597 //cosa add 04292008 to record the sequence number
9598 pcurrent_stats->Seq_Num = seq;
9599 //
9600 // Check whether we should take the previous packet into accounting
9601 //
9602 if(!pprevious_stats->bIsAMPDU)
9603 {
9604 // if previous packet is not aggregated packet
9605 bcheck = true;
9606 }else
9607 {
9608 #if 0
9609 // if previous packet is aggregated packet, and current packet
9610 // (1) is not AMPDU
9611 // (2) is the first packet of one AMPDU
9612 // that means the previous packet is the last one aggregated packet
9613 if( !pcurrent_stats->bIsAMPDU || pcurrent_stats->bFirstMPDU)
9614 bcheck = true;
9615 #endif
9616 }
9617
9618
9619 if(slide_rssi_statistics++ >= PHY_RSSI_SLID_WIN_MAX)
9620 {
9621 slide_rssi_statistics = PHY_RSSI_SLID_WIN_MAX;
9622 last_rssi = priv->stats.slide_signal_strength[slide_rssi_index];
9623 priv->stats.slide_rssi_total -= last_rssi;
9624 }
9625 priv->stats.slide_rssi_total += pprevious_stats->SignalStrength;
9626
9627 priv->stats.slide_signal_strength[slide_rssi_index++] = pprevious_stats->SignalStrength;
9628 if(slide_rssi_index >= PHY_RSSI_SLID_WIN_MAX)
9629 slide_rssi_index = 0;
9630
9631 // <1> Showed on UI for user, in dbm
9632 tmp_val = priv->stats.slide_rssi_total/slide_rssi_statistics;
9633 priv->stats.signal_strength = rtl819x_translate_todbm((u8)tmp_val);
9634 pcurrent_stats->rssi = priv->stats.signal_strength;
9635 //
9636 // If the previous packet does not match the criteria, neglect it
9637 //
9638 if(!pprevious_stats->bPacketMatchBSSID)
9639 {
9640 if(!pprevious_stats->bToSelfBA)
9641 return;
9642 }
9643
9644 if(!bcheck)
9645 return;
9646
9647
9648 //rtl8190_process_cck_rxpathsel(priv,pprevious_stats);//only rtl8190 supported
9649
9650 //
9651 // Check RSSI
9652 //
9653 priv->stats.num_process_phyinfo++;
9654
9655 /* record the general signal strength to the sliding window. */
9656
9657
9658 // <2> Showed on UI for engineering
9659 // hardware does not provide rssi information for each rf path in CCK
9660 if(!pprevious_stats->bIsCCK && (pprevious_stats->bPacketToSelf || pprevious_stats->bToSelfBA))
9661 {
9662 for (rfpath = RF90_PATH_A; rfpath < priv->NumTotalRFPath; rfpath++)
9663 {
9664 if (!rtl8192_phy_CheckIsLegalRFPath(priv->ieee80211->dev, rfpath))
9665 continue;
9666
9667 //Fixed by Jacken 2008-03-20
9668 if(priv->stats.rx_rssi_percentage[rfpath] == 0)
9669 {
9670 priv->stats.rx_rssi_percentage[rfpath] = pprevious_stats->RxMIMOSignalStrength[rfpath];
9671 //DbgPrint("MIMO RSSI initialize \n");
9672 }
9673 if(pprevious_stats->RxMIMOSignalStrength[rfpath] > priv->stats.rx_rssi_percentage[rfpath])
9674 {
9675 priv->stats.rx_rssi_percentage[rfpath] =
9676 ( (priv->stats.rx_rssi_percentage[rfpath]*(Rx_Smooth_Factor-1)) +
9677 (pprevious_stats->RxMIMOSignalStrength[rfpath])) /(Rx_Smooth_Factor);
9678 priv->stats.rx_rssi_percentage[rfpath] = priv->stats.rx_rssi_percentage[rfpath] + 1;
9679 }
9680 else
9681 {
9682 priv->stats.rx_rssi_percentage[rfpath] =
9683 ( (priv->stats.rx_rssi_percentage[rfpath]*(Rx_Smooth_Factor-1)) +
9684 (pprevious_stats->RxMIMOSignalStrength[rfpath])) /(Rx_Smooth_Factor);
9685 }
9686 RT_TRACE(COMP_DBG,"priv->stats.rx_rssi_percentage[rfPath] = %d \n" ,priv->stats.rx_rssi_percentage[rfpath] );
9687 }
9688 }
9689
9690
9691 //
9692 // Check PWDB.
9693 //
9694 RT_TRACE(COMP_RXDESC, "Smooth %s PWDB = %d\n",
9695 pprevious_stats->bIsCCK? "CCK": "OFDM",
9696 pprevious_stats->RxPWDBAll);
9697
9698 if(pprevious_stats->bPacketBeacon)
9699 {
9700/* record the beacon pwdb to the sliding window. */
9701 if(slide_beacon_adc_pwdb_statistics++ >= PHY_Beacon_RSSI_SLID_WIN_MAX)
9702 {
9703 slide_beacon_adc_pwdb_statistics = PHY_Beacon_RSSI_SLID_WIN_MAX;
9704 last_beacon_adc_pwdb = priv->stats.Slide_Beacon_pwdb[slide_beacon_adc_pwdb_index];
9705 priv->stats.Slide_Beacon_Total -= last_beacon_adc_pwdb;
9706 //DbgPrint("slide_beacon_adc_pwdb_index = %d, last_beacon_adc_pwdb = %d, Adapter->RxStats.Slide_Beacon_Total = %d\n",
9707 // slide_beacon_adc_pwdb_index, last_beacon_adc_pwdb, Adapter->RxStats.Slide_Beacon_Total);
9708 }
9709 priv->stats.Slide_Beacon_Total += pprevious_stats->RxPWDBAll;
9710 priv->stats.Slide_Beacon_pwdb[slide_beacon_adc_pwdb_index] = pprevious_stats->RxPWDBAll;
9711 //DbgPrint("slide_beacon_adc_pwdb_index = %d, pPreviousRfd->Status.RxPWDBAll = %d\n", slide_beacon_adc_pwdb_index, pPreviousRfd->Status.RxPWDBAll);
9712 slide_beacon_adc_pwdb_index++;
9713 if(slide_beacon_adc_pwdb_index >= PHY_Beacon_RSSI_SLID_WIN_MAX)
9714 slide_beacon_adc_pwdb_index = 0;
9715 pprevious_stats->RxPWDBAll = priv->stats.Slide_Beacon_Total/slide_beacon_adc_pwdb_statistics;
9716 if(pprevious_stats->RxPWDBAll >= 3)
9717 pprevious_stats->RxPWDBAll -= 3;
9718 }
9719
9720 RT_TRACE(COMP_RXDESC, "Smooth %s PWDB = %d\n",
9721 pprevious_stats->bIsCCK? "CCK": "OFDM",
9722 pprevious_stats->RxPWDBAll);
9723
9724
9725 if(pprevious_stats->bPacketToSelf || pprevious_stats->bPacketBeacon || pprevious_stats->bToSelfBA)
9726 {
9727 if(priv->undecorated_smoothed_pwdb < 0) // initialize
9728 {
9729 priv->undecorated_smoothed_pwdb = pprevious_stats->RxPWDBAll;
9730 //DbgPrint("First pwdb initialize \n");
9731 }
9732#if 1
9733 if(pprevious_stats->RxPWDBAll > (u32)priv->undecorated_smoothed_pwdb)
9734 {
9735 priv->undecorated_smoothed_pwdb =
9736 ( ((priv->undecorated_smoothed_pwdb)*(Rx_Smooth_Factor-1)) +
9737 (pprevious_stats->RxPWDBAll)) /(Rx_Smooth_Factor);
9738 priv->undecorated_smoothed_pwdb = priv->undecorated_smoothed_pwdb + 1;
9739 }
9740 else
9741 {
9742 priv->undecorated_smoothed_pwdb =
9743 ( ((priv->undecorated_smoothed_pwdb)*(Rx_Smooth_Factor-1)) +
9744 (pprevious_stats->RxPWDBAll)) /(Rx_Smooth_Factor);
9745 }
9746#else
9747 //Fixed by Jacken 2008-03-20
9748 if(pPreviousRfd->Status.RxPWDBAll > (u32)pHalData->UndecoratedSmoothedPWDB)
9749 {
9750 pHalData->UndecoratedSmoothedPWDB =
9751 ( ((pHalData->UndecoratedSmoothedPWDB)* 5) + (pPreviousRfd->Status.RxPWDBAll)) / 6;
9752 pHalData->UndecoratedSmoothedPWDB = pHalData->UndecoratedSmoothedPWDB + 1;
9753 }
9754 else
9755 {
9756 pHalData->UndecoratedSmoothedPWDB =
9757 ( ((pHalData->UndecoratedSmoothedPWDB)* 5) + (pPreviousRfd->Status.RxPWDBAll)) / 6;
9758 }
9759#endif
9760
9761 }
9762
9763 //
9764 // Check EVM
9765 //
9766 /* record the general EVM to the sliding window. */
9767 if(pprevious_stats->SignalQuality == 0)
9768 {
9769 }
9770 else
9771 {
9772 if(pprevious_stats->bPacketToSelf || pprevious_stats->bPacketBeacon || pprevious_stats->bToSelfBA){
9773 if(slide_evm_statistics++ >= PHY_RSSI_SLID_WIN_MAX){
9774 slide_evm_statistics = PHY_RSSI_SLID_WIN_MAX;
9775 last_evm = priv->stats.slide_evm[slide_evm_index];
9776 priv->stats.slide_evm_total -= last_evm;
9777 }
9778
9779 priv->stats.slide_evm_total += pprevious_stats->SignalQuality;
9780
9781 priv->stats.slide_evm[slide_evm_index++] = pprevious_stats->SignalQuality;
9782 if(slide_evm_index >= PHY_RSSI_SLID_WIN_MAX)
9783 slide_evm_index = 0;
9784
9785 // <1> Showed on UI for user, in percentage.
9786 tmp_val = priv->stats.slide_evm_total/slide_evm_statistics;
9787 priv->stats.signal_quality = tmp_val;
9788 //cosa add 10/11/2007, Showed on UI for user in Windows Vista, for Link quality.
9789 priv->stats.last_signal_strength_inpercent = tmp_val;
9790 }
9791
9792 // <2> Showed on UI for engineering
9793 if(pprevious_stats->bPacketToSelf || pprevious_stats->bPacketBeacon || pprevious_stats->bToSelfBA)
9794 {
9795 for(nspatial_stream = 0; nspatial_stream<2 ; nspatial_stream++) // 2 spatial stream
9796 {
9797 if(pprevious_stats->RxMIMOSignalQuality[nspatial_stream] != -1)
9798 {
9799 if(priv->stats.rx_evm_percentage[nspatial_stream] == 0) // initialize
9800 {
9801 priv->stats.rx_evm_percentage[nspatial_stream] = pprevious_stats->RxMIMOSignalQuality[nspatial_stream];
9802 }
9803 priv->stats.rx_evm_percentage[nspatial_stream] =
9804 ( (priv->stats.rx_evm_percentage[nspatial_stream]* (Rx_Smooth_Factor-1)) +
9805 (pprevious_stats->RxMIMOSignalQuality[nspatial_stream]* 1)) / (Rx_Smooth_Factor);
9806 }
9807 }
9808 }
9809 }
9810
9811
9812}
9813
9814/*-----------------------------------------------------------------------------
9815 * Function: rtl819x_query_rxpwrpercentage()
9816 *
9817 * Overview:
9818 *
9819 * Input: char antpower
9820 *
9821 * Output: NONE
9822 *
9823 * Return: 0-100 percentage
9824 *
9825 * Revised History:
9826 * When Who Remark
9827 * 05/26/2008 amy Create Version 0 porting from windows code.
9828 *
9829 *---------------------------------------------------------------------------*/
9830static u8 rtl819x_query_rxpwrpercentage(
9831 char antpower
9832 )
9833{
9834 if ((antpower <= -100) || (antpower >= 20))
9835 {
9836 return 0;
9837 }
9838 else if (antpower >= 0)
9839 {
9840 return 100;
9841 }
9842 else
9843 {
9844 return (100+antpower);
9845 }
9846
9847} /* QueryRxPwrPercentage */
9848
9849static u8
9850rtl819x_evm_dbtopercentage(
9851 char value
9852 )
9853{
9854 char ret_val;
9855
9856 ret_val = value;
9857
9858 if(ret_val >= 0)
9859 ret_val = 0;
9860 if(ret_val <= -33)
9861 ret_val = -33;
9862 ret_val = 0 - ret_val;
9863 ret_val*=3;
9864 if(ret_val == 99)
9865 ret_val = 100;
9866 return(ret_val);
9867}
9868//
9869// Description:
9870// We want good-looking for signal strength/quality
9871// 2007/7/19 01:09, by cosa.
9872//
9873long
9874rtl819x_signal_scale_mapping(
9875 long currsig
9876 )
9877{
9878 long retsig;
9879
9880 // Step 1. Scale mapping.
9881 if(currsig >= 61 && currsig <= 100)
9882 {
9883 retsig = 90 + ((currsig - 60) / 4);
9884 }
9885 else if(currsig >= 41 && currsig <= 60)
9886 {
9887 retsig = 78 + ((currsig - 40) / 2);
9888 }
9889 else if(currsig >= 31 && currsig <= 40)
9890 {
9891 retsig = 66 + (currsig - 30);
9892 }
9893 else if(currsig >= 21 && currsig <= 30)
9894 {
9895 retsig = 54 + (currsig - 20);
9896 }
9897 else if(currsig >= 5 && currsig <= 20)
9898 {
9899 retsig = 42 + (((currsig - 5) * 2) / 3);
9900 }
9901 else if(currsig == 4)
9902 {
9903 retsig = 36;
9904 }
9905 else if(currsig == 3)
9906 {
9907 retsig = 27;
9908 }
9909 else if(currsig == 2)
9910 {
9911 retsig = 18;
9912 }
9913 else if(currsig == 1)
9914 {
9915 retsig = 9;
9916 }
9917 else
9918 {
9919 retsig = currsig;
9920 }
9921
9922 return retsig;
9923}
9924
9925#ifdef RTL8192SU
9926/*-----------------------------------------------------------------------------
9927 * Function: QueryRxPhyStatus8192S()
9928 *
9929 * Overview:
9930 *
9931 * Input: NONE
9932 *
9933 * Output: NONE
9934 *
9935 * Return: NONE
9936 *
9937 * Revised History:
9938 * When Who Remark
9939 * 06/01/2007 MHC Create Version 0.
9940 * 06/05/2007 MHC Accordign to HW's new data sheet, we add CCK and OFDM
9941 * descriptor definition.
9942 * 07/04/2007 MHC According to Jerry and Bryant's document. We read
9943 * ir_isolation and ext_lna for RF's init value and use
9944 * to compensate RSSI after receiving packets.
9945 * 09/10/2008 MHC Modify name and PHY status field for 92SE.
9946 * 09/19/2008 MHC Add CCK/OFDM SS/SQ for 92S series.
9947 *
9948 *---------------------------------------------------------------------------*/
9949static void rtl8192SU_query_rxphystatus(
9950 struct r8192_priv * priv,
9951 struct ieee80211_rx_stats * pstats,
9952 rx_desc_819x_usb *pDesc,
9953 rx_drvinfo_819x_usb * pdrvinfo,
9954 struct ieee80211_rx_stats * precord_stats,
9955 bool bpacket_match_bssid,
9956 bool bpacket_toself,
9957 bool bPacketBeacon,
9958 bool bToSelfBA
9959 )
9960{
9961 //PRT_RFD_STATUS pRtRfdStatus = &(pRfd->Status);
9962 //PHY_STS_CCK_8192S_T *pCck_buf;
9963 phy_sts_cck_819xusb_t * pcck_buf;
9964 phy_ofdm_rx_status_rxsc_sgien_exintfflag* prxsc;
9965 //u8 *prxpkt;
9966 //u8 i, max_spatial_stream, tmp_rxsnr, tmp_rxevm, rxsc_sgien_exflg;
9967 u8 i, max_spatial_stream, rxsc_sgien_exflg;
9968 char rx_pwr[4], rx_pwr_all=0;
9969 //long rx_avg_pwr = 0;
9970 //char rx_snrX, rx_evmX;
9971 u8 evm, pwdb_all;
9972 u32 RSSI, total_rssi=0;//, total_evm=0;
9973// long signal_strength_index = 0;
9974 u8 is_cck_rate=0;
9975 u8 rf_rx_num = 0;
9976
9977
9978
9979 priv->stats.numqry_phystatus++;
9980
9981 is_cck_rate = rx_hal_is_cck_rate(pDesc);
9982
9983 // Record it for next packet processing
9984 memset(precord_stats, 0, sizeof(struct ieee80211_rx_stats));
9985 pstats->bPacketMatchBSSID = precord_stats->bPacketMatchBSSID = bpacket_match_bssid;
9986 pstats->bPacketToSelf = precord_stats->bPacketToSelf = bpacket_toself;
9987 pstats->bIsCCK = precord_stats->bIsCCK = is_cck_rate;//RX_HAL_IS_CCK_RATE(pDrvInfo);
9988 pstats->bPacketBeacon = precord_stats->bPacketBeacon = bPacketBeacon;
9989 pstats->bToSelfBA = precord_stats->bToSelfBA = bToSelfBA;
9990
9991#ifndef RTL8192SU
9992 phy_sts_ofdm_819xusb_t* pofdm_buf = NULL;
9993 prxpkt = (u8*)pdrvinfo;
9994
9995 /* Move pointer to the 16th bytes. Phy status start address. */
9996 prxpkt += sizeof(rx_drvinfo_819x_usb);
9997
9998 /* Initial the cck and ofdm buffer pointer */
9999 pcck_buf = (phy_sts_cck_819xusb_t *)prxpkt;
10000 pofdm_buf = (phy_sts_ofdm_819xusb_t *)prxpkt;
10001#endif
10002
10003 pstats->RxMIMOSignalQuality[0] = -1;
10004 pstats->RxMIMOSignalQuality[1] = -1;
10005 precord_stats->RxMIMOSignalQuality[0] = -1;
10006 precord_stats->RxMIMOSignalQuality[1] = -1;
10007
10008 if(is_cck_rate)
10009 {
10010 u8 report;//, tmp_pwdb;
10011 //char cck_adc_pwdb[4];
10012
10013 // CCK Driver info Structure is not the same as OFDM packet.
10014 pcck_buf = (phy_sts_cck_819xusb_t *)pdrvinfo;
10015
10016 //
10017 // (1)Hardware does not provide RSSI for CCK
10018 //
10019
10020 //
10021 // (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive)
10022 //
10023
10024 priv->stats.numqry_phystatusCCK++;
10025
10026 if(!priv->bCckHighPower)
10027 {
10028 report = pcck_buf->cck_agc_rpt & 0xc0;
10029 report = report>>6;
10030 switch(report)
10031 {
10032 //Fixed by Jacken from Bryant 2008-03-20
10033 //Original value is -38 , -26 , -14 , -2
10034 //Fixed value is -35 , -23 , -11 , 6
10035 case 0x3:
10036 rx_pwr_all = -35 - (pcck_buf->cck_agc_rpt & 0x3e);
10037 break;
10038 case 0x2:
10039 rx_pwr_all = -23 - (pcck_buf->cck_agc_rpt & 0x3e);
10040 break;
10041 case 0x1:
10042 rx_pwr_all = -11 - (pcck_buf->cck_agc_rpt & 0x3e);
10043 break;
10044 case 0x0:
10045 rx_pwr_all = 8 - (pcck_buf->cck_agc_rpt & 0x3e);//6->8
10046 break;
10047 }
10048 }
10049 else
10050 {
10051 report = pdrvinfo->cfosho[0] & 0x60;
10052 report = report>>5;
10053 switch(report)
10054 {
10055 case 0x3:
10056 rx_pwr_all = -35 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1) ;
10057 break;
10058 case 0x2:
10059 rx_pwr_all = -23 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1);
10060 break;
10061 case 0x1:
10062 rx_pwr_all = -11 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1) ;
10063 break;
10064 case 0x0:
10065 rx_pwr_all = -8 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1) ;//6->-8
10066 break;
10067 }
10068 }
10069
10070 pwdb_all = rtl819x_query_rxpwrpercentage(rx_pwr_all);//check it
10071 pstats->RxPWDBAll = precord_stats->RxPWDBAll = pwdb_all;
10072 //pstats->RecvSignalPower = pwdb_all;
10073 pstats->RecvSignalPower = rx_pwr_all;
10074
10075 //
10076 // (3) Get Signal Quality (EVM)
10077 //
10078 //if(bpacket_match_bssid)
10079 {
10080 u8 sq;
10081
10082 if(pstats->RxPWDBAll > 40)
10083 {
10084 sq = 100;
10085 }else
10086 {
10087 sq = pcck_buf->sq_rpt;
10088
10089 if(pcck_buf->sq_rpt > 64)
10090 sq = 0;
10091 else if (pcck_buf->sq_rpt < 20)
10092 sq = 100;
10093 else
10094 sq = ((64-sq) * 100) / 44;
10095 }
10096 pstats->SignalQuality = precord_stats->SignalQuality = sq;
10097 pstats->RxMIMOSignalQuality[0] = precord_stats->RxMIMOSignalQuality[0] = sq;
10098 pstats->RxMIMOSignalQuality[1] = precord_stats->RxMIMOSignalQuality[1] = -1;
10099 }
10100 }
10101 else
10102 {
10103 priv->stats.numqry_phystatusHT++;
10104
10105 // 2008/09/19 MH For 92S debug, RX RF path always enable!!
10106 priv->brfpath_rxenable[0] = priv->brfpath_rxenable[1] = TRUE;
10107
10108 //
10109 // (1)Get RSSI for HT rate
10110 //
10111 //for(i=RF90_PATH_A; i<priv->NumTotalRFPath; i++)
10112 for(i=RF90_PATH_A; i<RF90_PATH_MAX; i++)
10113 {
10114 // 2008/01/30 MH we will judge RF RX path now.
10115 if (priv->brfpath_rxenable[i])
10116 rf_rx_num++;
10117 //else
10118 // continue;
10119
10120 //if (!rtl8192_phy_CheckIsLegalRFPath(priv->ieee80211->dev, i))
10121 // continue;
10122
10123 //Fixed by Jacken from Bryant 2008-03-20
10124 //Original value is 106
10125 //rx_pwr[i] = ((pofdm_buf->trsw_gain_X[i]&0x3F)*2) - 106;
10126 rx_pwr[i] = ((pdrvinfo->gain_trsw[i]&0x3F)*2) - 110;
10127
10128 /* Translate DBM to percentage. */
10129 RSSI = rtl819x_query_rxpwrpercentage(rx_pwr[i]); //check ok
10130 total_rssi += RSSI;
10131 RT_TRACE(COMP_RF, "RF-%d RXPWR=%x RSSI=%d\n", i, rx_pwr[i], RSSI);
10132
10133 //Get Rx snr value in DB
10134 //tmp_rxsnr = pofdm_buf->rxsnr_X[i];
10135 //rx_snrX = (char)(tmp_rxsnr);
10136 //rx_snrX /= 2;
10137 //priv->stats.rxSNRdB[i] = (long)rx_snrX;
10138 priv->stats.rxSNRdB[i] = (long)(pdrvinfo->rxsnr[i]/2);
10139
10140 /* Translate DBM to percentage. */
10141 //RSSI = rtl819x_query_rxpwrpercentage(rx_pwr[i]);
10142 //total_rssi += RSSI;
10143
10144 /* Record Signal Strength for next packet */
10145 //if(bpacket_match_bssid)
10146 {
10147 pstats->RxMIMOSignalStrength[i] =(u8) RSSI;
10148 precord_stats->RxMIMOSignalStrength[i] =(u8) RSSI;
10149 }
10150 }
10151
10152
10153 //
10154 // (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive)
10155 //
10156 //Fixed by Jacken from Bryant 2008-03-20
10157 //Original value is 106
10158 //rx_pwr_all = (((pofdm_buf->pwdb_all ) >> 1 )& 0x7f) -106;
10159 rx_pwr_all = (((pdrvinfo->pwdb_all ) >> 1 )& 0x7f) -106;
10160 pwdb_all = rtl819x_query_rxpwrpercentage(rx_pwr_all);
10161
10162 pstats->RxPWDBAll = precord_stats->RxPWDBAll = pwdb_all;
10163 pstats->RxPower = precord_stats->RxPower = rx_pwr_all;
10164 pstats->RecvSignalPower = rx_pwr_all;
10165
10166 //
10167 // (3)EVM of HT rate
10168 //
10169 //if(pdrvinfo->RxHT && pdrvinfo->RxRate>=DESC90_RATEMCS8 &&
10170 // pdrvinfo->RxRate<=DESC90_RATEMCS15)
10171 if(pDesc->RxHT && pDesc->RxMCS>=DESC92S_RATEMCS8 &&
10172 pDesc->RxMCS<=DESC92S_RATEMCS15)
10173 max_spatial_stream = 2; //both spatial stream make sense
10174 else
10175 max_spatial_stream = 1; //only spatial stream 1 makes sense
10176
10177 for(i=0; i<max_spatial_stream; i++)
10178 {
10179 //tmp_rxevm = pofdm_buf->rxevm_X[i];
10180 //rx_evmX = (char)(tmp_rxevm);
10181
10182 // Do not use shift operation like "rx_evmX >>= 1" because the compilor of free build environment
10183 // fill most significant bit to "zero" when doing shifting operation which may change a negative
10184 // value to positive one, then the dbm value (which is supposed to be negative) is not correct anymore.
10185 //rx_evmX /= 2; //dbm
10186
10187 //evm = rtl819x_evm_dbtopercentage(rx_evmX);
10188 evm = rtl819x_evm_dbtopercentage( (pdrvinfo->rxevm[i] /*/ 2*/)); //dbm
10189 RT_TRACE(COMP_RF, "RXRATE=%x RXEVM=%x EVM=%s%d\n", pDesc->RxMCS, pdrvinfo->rxevm[i], "%", evm);
10190#if 0
10191 EVM = SignalScaleMapping(EVM);//make it good looking, from 0~100//=====>from here
10192#endif
10193
10194 //if(bpacket_match_bssid)
10195 {
10196 if(i==0) // Fill value in RFD, Get the first spatial stream only
10197 pstats->SignalQuality = precord_stats->SignalQuality = (u8)(evm & 0xff);
10198 pstats->RxMIMOSignalQuality[i] = precord_stats->RxMIMOSignalQuality[i] = (u8)(evm & 0xff);
10199 }
10200 }
10201
10202
10203 /* record rx statistics for debug */
10204 //rxsc_sgien_exflg = pofdm_buf->rxsc_sgien_exflg;
10205 prxsc = (phy_ofdm_rx_status_rxsc_sgien_exintfflag *)&rxsc_sgien_exflg;
10206 //if(pdrvinfo->BW) //40M channel
10207 if(pDesc->BW) //40M channel
10208 priv->stats.received_bwtype[1+pdrvinfo->rxsc]++;
10209 else //20M channel
10210 priv->stats.received_bwtype[0]++;
10211 }
10212
10213 //UI BSS List signal strength(in percentage), make it good looking, from 0~100.
10214 //It is assigned to the BSS List in GetValueFromBeaconOrProbeRsp().
10215 if(is_cck_rate)
10216 {
10217 pstats->SignalStrength = precord_stats->SignalStrength = (u8)(rtl819x_signal_scale_mapping((long)pwdb_all));//PWDB_ALL;//check ok
10218
10219 }
10220 else
10221 {
10222 //pRfd->Status.SignalStrength = pRecordRfd->Status.SignalStrength = (u8)(SignalScaleMapping(total_rssi/=RF90_PATH_MAX));//(u8)(total_rssi/=RF90_PATH_MAX);
10223 // We can judge RX path number now.
10224 if (rf_rx_num != 0)
10225 pstats->SignalStrength = precord_stats->SignalStrength = (u8)(rtl819x_signal_scale_mapping((long)(total_rssi/=rf_rx_num)));
10226 }
10227}/* QueryRxPhyStatus8192S */
10228#else
10229static void rtl8192_query_rxphystatus(
10230 struct r8192_priv * priv,
10231 struct ieee80211_rx_stats * pstats,
10232 rx_drvinfo_819x_usb * pdrvinfo,
10233 struct ieee80211_rx_stats * precord_stats,
10234 bool bpacket_match_bssid,
10235 bool bpacket_toself,
10236 bool bPacketBeacon,
10237 bool bToSelfBA
10238 )
10239{
10240 //PRT_RFD_STATUS pRtRfdStatus = &(pRfd->Status);
10241 phy_sts_ofdm_819xusb_t* pofdm_buf;
10242 phy_sts_cck_819xusb_t * pcck_buf;
10243 phy_ofdm_rx_status_rxsc_sgien_exintfflag* prxsc;
10244 u8 *prxpkt;
10245 u8 i, max_spatial_stream, tmp_rxsnr, tmp_rxevm, rxsc_sgien_exflg;
10246 char rx_pwr[4], rx_pwr_all=0;
10247 //long rx_avg_pwr = 0;
10248 char rx_snrX, rx_evmX;
10249 u8 evm, pwdb_all;
10250 u32 RSSI, total_rssi=0;//, total_evm=0;
10251// long signal_strength_index = 0;
10252 u8 is_cck_rate=0;
10253 u8 rf_rx_num = 0;
10254
10255
10256 priv->stats.numqry_phystatus++;
10257
10258 is_cck_rate = rx_hal_is_cck_rate(pdrvinfo);
10259
10260 // Record it for next packet processing
10261 memset(precord_stats, 0, sizeof(struct ieee80211_rx_stats));
10262 pstats->bPacketMatchBSSID = precord_stats->bPacketMatchBSSID = bpacket_match_bssid;
10263 pstats->bPacketToSelf = precord_stats->bPacketToSelf = bpacket_toself;
10264 pstats->bIsCCK = precord_stats->bIsCCK = is_cck_rate;//RX_HAL_IS_CCK_RATE(pDrvInfo);
10265 pstats->bPacketBeacon = precord_stats->bPacketBeacon = bPacketBeacon;
10266 pstats->bToSelfBA = precord_stats->bToSelfBA = bToSelfBA;
10267
10268 prxpkt = (u8*)pdrvinfo;
10269
10270 /* Move pointer to the 16th bytes. Phy status start address. */
10271 prxpkt += sizeof(rx_drvinfo_819x_usb);
10272
10273 /* Initial the cck and ofdm buffer pointer */
10274 pcck_buf = (phy_sts_cck_819xusb_t *)prxpkt;
10275 pofdm_buf = (phy_sts_ofdm_819xusb_t *)prxpkt;
10276
10277 pstats->RxMIMOSignalQuality[0] = -1;
10278 pstats->RxMIMOSignalQuality[1] = -1;
10279 precord_stats->RxMIMOSignalQuality[0] = -1;
10280 precord_stats->RxMIMOSignalQuality[1] = -1;
10281
10282 if(is_cck_rate)
10283 {
10284 //
10285 // (1)Hardware does not provide RSSI for CCK
10286 //
10287
10288 //
10289 // (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive)
10290 //
10291 u8 report;//, cck_agc_rpt;
10292
10293 priv->stats.numqry_phystatusCCK++;
10294
10295 if(!priv->bCckHighPower)
10296 {
10297 report = pcck_buf->cck_agc_rpt & 0xc0;
10298 report = report>>6;
10299 switch(report)
10300 {
10301 //Fixed by Jacken from Bryant 2008-03-20
10302 //Original value is -38 , -26 , -14 , -2
10303 //Fixed value is -35 , -23 , -11 , 6
10304 case 0x3:
10305 rx_pwr_all = -35 - (pcck_buf->cck_agc_rpt & 0x3e);
10306 break;
10307 case 0x2:
10308 rx_pwr_all = -23 - (pcck_buf->cck_agc_rpt & 0x3e);
10309 break;
10310 case 0x1:
10311 rx_pwr_all = -11 - (pcck_buf->cck_agc_rpt & 0x3e);
10312 break;
10313 case 0x0:
10314 rx_pwr_all = 6 - (pcck_buf->cck_agc_rpt & 0x3e);
10315 break;
10316 }
10317 }
10318 else
10319 {
10320 report = pcck_buf->cck_agc_rpt & 0x60;
10321 report = report>>5;
10322 switch(report)
10323 {
10324 case 0x3:
10325 rx_pwr_all = -35 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1) ;
10326 break;
10327 case 0x2:
10328 rx_pwr_all = -23 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1);
10329 break;
10330 case 0x1:
10331 rx_pwr_all = -11 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1) ;
10332 break;
10333 case 0x0:
10334 rx_pwr_all = 6 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1) ;
10335 break;
10336 }
10337 }
10338
10339 pwdb_all = rtl819x_query_rxpwrpercentage(rx_pwr_all);
10340 pstats->RxPWDBAll = precord_stats->RxPWDBAll = pwdb_all;
10341 pstats->RecvSignalPower = pwdb_all;
10342
10343 //
10344 // (3) Get Signal Quality (EVM)
10345 //
10346 //if(bpacket_match_bssid)
10347 {
10348 u8 sq;
10349
10350 if(pstats->RxPWDBAll > 40)
10351 {
10352 sq = 100;
10353 }else
10354 {
10355 sq = pcck_buf->sq_rpt;
10356
10357 if(pcck_buf->sq_rpt > 64)
10358 sq = 0;
10359 else if (pcck_buf->sq_rpt < 20)
10360 sq = 100;
10361 else
10362 sq = ((64-sq) * 100) / 44;
10363 }
10364 pstats->SignalQuality = precord_stats->SignalQuality = sq;
10365 pstats->RxMIMOSignalQuality[0] = precord_stats->RxMIMOSignalQuality[0] = sq;
10366 pstats->RxMIMOSignalQuality[1] = precord_stats->RxMIMOSignalQuality[1] = -1;
10367 }
10368 }
10369 else
10370 {
10371 priv->stats.numqry_phystatusHT++;
10372 //
10373 // (1)Get RSSI for HT rate
10374 //
10375 for(i=RF90_PATH_A; i<priv->NumTotalRFPath; i++)
10376 {
10377 // 2008/01/30 MH we will judge RF RX path now.
10378 if (priv->brfpath_rxenable[i])
10379 rf_rx_num++;
10380 else
10381 continue;
10382
10383 if (!rtl8192_phy_CheckIsLegalRFPath(priv->ieee80211->dev, i))
10384 continue;
10385
10386 //Fixed by Jacken from Bryant 2008-03-20
10387 //Original value is 106
10388 rx_pwr[i] = ((pofdm_buf->trsw_gain_X[i]&0x3F)*2) - 106;
10389
10390 //Get Rx snr value in DB
10391 tmp_rxsnr = pofdm_buf->rxsnr_X[i];
10392 rx_snrX = (char)(tmp_rxsnr);
10393 //rx_snrX >>= 1;;
10394 rx_snrX /= 2;
10395 priv->stats.rxSNRdB[i] = (long)rx_snrX;
10396
10397 /* Translate DBM to percentage. */
10398 RSSI = rtl819x_query_rxpwrpercentage(rx_pwr[i]);
10399 total_rssi += RSSI;
10400
10401 /* Record Signal Strength for next packet */
10402 //if(bpacket_match_bssid)
10403 {
10404 pstats->RxMIMOSignalStrength[i] =(u8) RSSI;
10405 precord_stats->RxMIMOSignalStrength[i] =(u8) RSSI;
10406 }
10407 }
10408
10409
10410 //
10411 // (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive)
10412 //
10413 //Fixed by Jacken from Bryant 2008-03-20
10414 //Original value is 106
10415 rx_pwr_all = (((pofdm_buf->pwdb_all ) >> 1 )& 0x7f) -106;
10416 pwdb_all = rtl819x_query_rxpwrpercentage(rx_pwr_all);
10417
10418 pstats->RxPWDBAll = precord_stats->RxPWDBAll = pwdb_all;
10419 pstats->RxPower = precord_stats->RxPower = rx_pwr_all;
10420
10421 //
10422 // (3)EVM of HT rate
10423 //
10424 if(pdrvinfo->RxHT && pdrvinfo->RxRate>=DESC90_RATEMCS8 &&
10425 pdrvinfo->RxRate<=DESC90_RATEMCS15)
10426 max_spatial_stream = 2; //both spatial stream make sense
10427 else
10428 max_spatial_stream = 1; //only spatial stream 1 makes sense
10429
10430 for(i=0; i<max_spatial_stream; i++)
10431 {
10432 tmp_rxevm = pofdm_buf->rxevm_X[i];
10433 rx_evmX = (char)(tmp_rxevm);
10434
10435 // Do not use shift operation like "rx_evmX >>= 1" because the compilor of free build environment
10436 // fill most significant bit to "zero" when doing shifting operation which may change a negative
10437 // value to positive one, then the dbm value (which is supposed to be negative) is not correct anymore.
10438 rx_evmX /= 2; //dbm
10439
10440 evm = rtl819x_evm_dbtopercentage(rx_evmX);
10441#if 0
10442 EVM = SignalScaleMapping(EVM);//make it good looking, from 0~100
10443#endif
10444 //if(bpacket_match_bssid)
10445 {
10446 if(i==0) // Fill value in RFD, Get the first spatial stream only
10447 pstats->SignalQuality = precord_stats->SignalQuality = (u8)(evm & 0xff);
10448 pstats->RxMIMOSignalQuality[i] = precord_stats->RxMIMOSignalQuality[i] = (u8)(evm & 0xff);
10449 }
10450 }
10451
10452
10453 /* record rx statistics for debug */
10454 rxsc_sgien_exflg = pofdm_buf->rxsc_sgien_exflg;
10455 prxsc = (phy_ofdm_rx_status_rxsc_sgien_exintfflag *)&rxsc_sgien_exflg;
10456 if(pdrvinfo->BW) //40M channel
10457 priv->stats.received_bwtype[1+prxsc->rxsc]++;
10458 else //20M channel
10459 priv->stats.received_bwtype[0]++;
10460 }
10461
10462 //UI BSS List signal strength(in percentage), make it good looking, from 0~100.
10463 //It is assigned to the BSS List in GetValueFromBeaconOrProbeRsp().
10464 if(is_cck_rate)
10465 {
10466 pstats->SignalStrength = precord_stats->SignalStrength = (u8)(rtl819x_signal_scale_mapping((long)pwdb_all));//PWDB_ALL;
10467
10468 }
10469 else
10470 {
10471 //pRfd->Status.SignalStrength = pRecordRfd->Status.SignalStrength = (u8)(SignalScaleMapping(total_rssi/=RF90_PATH_MAX));//(u8)(total_rssi/=RF90_PATH_MAX);
10472 // We can judge RX path number now.
10473 if (rf_rx_num != 0)
10474 pstats->SignalStrength = precord_stats->SignalStrength = (u8)(rtl819x_signal_scale_mapping((long)(total_rssi/=rf_rx_num)));
10475 }
10476} /* QueryRxPhyStatus8190Pci */
10477#endif
10478
10479void
10480rtl8192_record_rxdesc_forlateruse(
10481 struct ieee80211_rx_stats * psrc_stats,
10482 struct ieee80211_rx_stats * ptarget_stats
10483)
10484{
10485 ptarget_stats->bIsAMPDU = psrc_stats->bIsAMPDU;
10486 ptarget_stats->bFirstMPDU = psrc_stats->bFirstMPDU;
10487 ptarget_stats->Seq_Num = psrc_stats->Seq_Num;
10488}
10489
10490#ifdef RTL8192SU
10491static void rtl8192SU_query_rxphystatus(
10492 struct r8192_priv * priv,
10493 struct ieee80211_rx_stats * pstats,
10494 rx_desc_819x_usb *pDesc,
10495 rx_drvinfo_819x_usb * pdrvinfo,
10496 struct ieee80211_rx_stats * precord_stats,
10497 bool bpacket_match_bssid,
10498 bool bpacket_toself,
10499 bool bPacketBeacon,
10500 bool bToSelfBA
10501 );
10502void rtl8192SU_TranslateRxSignalStuff(struct sk_buff *skb,
10503 struct ieee80211_rx_stats * pstats,
10504 rx_desc_819x_usb *pDesc,
10505 rx_drvinfo_819x_usb *pdrvinfo)
10506{
10507 // TODO: We must only check packet for current MAC address. Not finish
10508 rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
10509 struct net_device *dev=info->dev;
10510 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
10511 bool bpacket_match_bssid, bpacket_toself;
10512 bool bPacketBeacon=FALSE, bToSelfBA=FALSE;
10513 static struct ieee80211_rx_stats previous_stats;
10514 struct ieee80211_hdr_3addr *hdr;//by amy
10515 u16 fc,type;
10516
10517 // Get Signal Quality for only RX data queue (but not command queue)
10518
10519 u8* tmp_buf;
10520 //u16 tmp_buf_len = 0;
10521 u8 *praddr;
10522
10523 /* Get MAC frame start address. */
10524 tmp_buf = (u8*)skb->data;// + get_rxpacket_shiftbytes_819xusb(pstats);
10525
10526 hdr = (struct ieee80211_hdr_3addr *)tmp_buf;
10527 fc = le16_to_cpu(hdr->frame_ctl);
10528 type = WLAN_FC_GET_TYPE(fc);
10529 praddr = hdr->addr1;
10530
10531 /* Check if the received packet is acceptabe. */
10532 bpacket_match_bssid = ((IEEE80211_FTYPE_CTL != type) &&
10533 (eqMacAddr(priv->ieee80211->current_network.bssid, (fc & IEEE80211_FCTL_TODS)? hdr->addr1 : (fc & IEEE80211_FCTL_FROMDS )? hdr->addr2 : hdr->addr3))
10534 && (!pstats->bHwError) && (!pstats->bCRC)&& (!pstats->bICV));
10535 bpacket_toself = bpacket_match_bssid & (eqMacAddr(praddr, priv->ieee80211->dev->dev_addr));
10536
10537#if 1//cosa
10538 if(WLAN_FC_GET_FRAMETYPE(fc)== IEEE80211_STYPE_BEACON)
10539 {
10540 bPacketBeacon = true;
10541 //DbgPrint("Beacon 2, MatchBSSID = %d, ToSelf = %d \n", bPacketMatchBSSID, bPacketToSelf);
10542 }
10543 if(WLAN_FC_GET_FRAMETYPE(fc) == IEEE80211_STYPE_BLOCKACK)
10544 {
10545 if((eqMacAddr(praddr,dev->dev_addr)))
10546 bToSelfBA = true;
10547 //DbgPrint("BlockAck, MatchBSSID = %d, ToSelf = %d \n", bPacketMatchBSSID, bPacketToSelf);
10548 }
10549
10550#endif
10551
10552
10553 if(bpacket_match_bssid)
10554 {
10555 priv->stats.numpacket_matchbssid++;
10556 }
10557 if(bpacket_toself){
10558 priv->stats.numpacket_toself++;
10559 }
10560 //
10561 // Process PHY information for previous packet (RSSI/PWDB/EVM)
10562 //
10563 // Because phy information is contained in the last packet of AMPDU only, so driver
10564 // should process phy information of previous packet
10565 rtl8192_process_phyinfo(priv, tmp_buf, &previous_stats, pstats);
10566 rtl8192SU_query_rxphystatus(priv, pstats, pDesc, pdrvinfo, &previous_stats, bpacket_match_bssid,bpacket_toself,bPacketBeacon,bToSelfBA);
10567 rtl8192_record_rxdesc_forlateruse(pstats, &previous_stats);
10568
10569}
10570#else
10571void TranslateRxSignalStuff819xUsb(struct sk_buff *skb,
10572 struct ieee80211_rx_stats * pstats,
10573 rx_drvinfo_819x_usb *pdrvinfo)
10574{
10575 // TODO: We must only check packet for current MAC address. Not finish
10576 rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
10577 struct net_device *dev=info->dev;
10578 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
10579 bool bpacket_match_bssid, bpacket_toself;
10580 bool bPacketBeacon=FALSE, bToSelfBA=FALSE;
10581 static struct ieee80211_rx_stats previous_stats;
10582 struct ieee80211_hdr_3addr *hdr;//by amy
10583 u16 fc,type;
10584
10585 // Get Signal Quality for only RX data queue (but not command queue)
10586
10587 u8* tmp_buf;
10588 //u16 tmp_buf_len = 0;
10589 u8 *praddr;
10590
10591 /* Get MAC frame start address. */
10592 tmp_buf = (u8*)skb->data;// + get_rxpacket_shiftbytes_819xusb(pstats);
10593
10594 hdr = (struct ieee80211_hdr_3addr *)tmp_buf;
10595 fc = le16_to_cpu(hdr->frame_ctl);
10596 type = WLAN_FC_GET_TYPE(fc);
10597 praddr = hdr->addr1;
10598
10599 /* Check if the received packet is acceptabe. */
10600 bpacket_match_bssid = ((IEEE80211_FTYPE_CTL != type) &&
10601 (eqMacAddr(priv->ieee80211->current_network.bssid, (fc & IEEE80211_FCTL_TODS)? hdr->addr1 : (fc & IEEE80211_FCTL_FROMDS )? hdr->addr2 : hdr->addr3))
10602 && (!pstats->bHwError) && (!pstats->bCRC)&& (!pstats->bICV));
10603 bpacket_toself = bpacket_match_bssid & (eqMacAddr(praddr, priv->ieee80211->dev->dev_addr));
10604
10605#if 1//cosa
10606 if(WLAN_FC_GET_FRAMETYPE(fc)== IEEE80211_STYPE_BEACON)
10607 {
10608 bPacketBeacon = true;
10609 //DbgPrint("Beacon 2, MatchBSSID = %d, ToSelf = %d \n", bPacketMatchBSSID, bPacketToSelf);
10610 }
10611 if(WLAN_FC_GET_FRAMETYPE(fc) == IEEE80211_STYPE_BLOCKACK)
10612 {
10613 if((eqMacAddr(praddr,dev->dev_addr)))
10614 bToSelfBA = true;
10615 //DbgPrint("BlockAck, MatchBSSID = %d, ToSelf = %d \n", bPacketMatchBSSID, bPacketToSelf);
10616 }
10617
10618#endif
10619
10620
10621 if(bpacket_match_bssid)
10622 {
10623 priv->stats.numpacket_matchbssid++;
10624 }
10625 if(bpacket_toself){
10626 priv->stats.numpacket_toself++;
10627 }
10628 //
10629 // Process PHY information for previous packet (RSSI/PWDB/EVM)
10630 //
10631 // Because phy information is contained in the last packet of AMPDU only, so driver
10632 // should process phy information of previous packet
10633 rtl8192_process_phyinfo(priv, tmp_buf, &previous_stats, pstats);
10634 rtl8192_query_rxphystatus(priv, pstats, pdrvinfo, &previous_stats, bpacket_match_bssid,bpacket_toself,bPacketBeacon,bToSelfBA);
10635 rtl8192_record_rxdesc_forlateruse(pstats, &previous_stats);
10636
10637}
10638#endif
10639
10640/**
10641* Function: UpdateReceivedRateHistogramStatistics
10642* Overview: Recored down the received data rate
10643*
10644* Input:
10645* struct net_device *dev
10646* struct ieee80211_rx_stats *stats
10647*
10648* Output:
10649*
10650* (priv->stats.ReceivedRateHistogram[] is updated)
10651* Return:
10652* None
10653*/
10654void
10655UpdateReceivedRateHistogramStatistics8190(
10656 struct net_device *dev,
10657 struct ieee80211_rx_stats *stats
10658 )
10659{
10660 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
10661 u32 rcvType=1; //0: Total, 1:OK, 2:CRC, 3:ICV
10662 u32 rateIndex;
10663 u32 preamble_guardinterval; //1: short preamble/GI, 0: long preamble/GI
10664
10665
10666 if(stats->bCRC)
10667 rcvType = 2;
10668 else if(stats->bICV)
10669 rcvType = 3;
10670
10671 if(stats->bShortPreamble)
10672 preamble_guardinterval = 1;// short
10673 else
10674 preamble_guardinterval = 0;// long
10675
10676 switch(stats->rate)
10677 {
10678 //
10679 // CCK rate
10680 //
10681 case MGN_1M: rateIndex = 0; break;
10682 case MGN_2M: rateIndex = 1; break;
10683 case MGN_5_5M: rateIndex = 2; break;
10684 case MGN_11M: rateIndex = 3; break;
10685 //
10686 // Legacy OFDM rate
10687 //
10688 case MGN_6M: rateIndex = 4; break;
10689 case MGN_9M: rateIndex = 5; break;
10690 case MGN_12M: rateIndex = 6; break;
10691 case MGN_18M: rateIndex = 7; break;
10692 case MGN_24M: rateIndex = 8; break;
10693 case MGN_36M: rateIndex = 9; break;
10694 case MGN_48M: rateIndex = 10; break;
10695 case MGN_54M: rateIndex = 11; break;
10696 //
10697 // 11n High throughput rate
10698 //
10699 case MGN_MCS0: rateIndex = 12; break;
10700 case MGN_MCS1: rateIndex = 13; break;
10701 case MGN_MCS2: rateIndex = 14; break;
10702 case MGN_MCS3: rateIndex = 15; break;
10703 case MGN_MCS4: rateIndex = 16; break;
10704 case MGN_MCS5: rateIndex = 17; break;
10705 case MGN_MCS6: rateIndex = 18; break;
10706 case MGN_MCS7: rateIndex = 19; break;
10707 case MGN_MCS8: rateIndex = 20; break;
10708 case MGN_MCS9: rateIndex = 21; break;
10709 case MGN_MCS10: rateIndex = 22; break;
10710 case MGN_MCS11: rateIndex = 23; break;
10711 case MGN_MCS12: rateIndex = 24; break;
10712 case MGN_MCS13: rateIndex = 25; break;
10713 case MGN_MCS14: rateIndex = 26; break;
10714 case MGN_MCS15: rateIndex = 27; break;
10715 default: rateIndex = 28; break;
10716 }
10717 priv->stats.received_preamble_GI[preamble_guardinterval][rateIndex]++;
10718 priv->stats.received_rate_histogram[0][rateIndex]++; //total
10719 priv->stats.received_rate_histogram[rcvType][rateIndex]++;
10720}
10721
10722#ifdef RTL8192SU
10723void rtl8192SU_query_rxdesc_status(struct sk_buff *skb, struct ieee80211_rx_stats *stats, bool bIsRxAggrSubframe)
10724{
10725 rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
10726 struct net_device *dev=info->dev;
10727 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
10728 //rx_desc_819x_usb *desc = (rx_desc_819x_usb *)skb->data;
10729 rx_drvinfo_819x_usb *driver_info = NULL;
10730
10731 //PRT_RFD_STATUS pRtRfdStatus = &pRfd->Status;
10732 //PHAL_DATA_8192SUSB pHalData = GET_HAL_DATA(Adapter);
10733 //pu1Byte pDesc = (pu1Byte)pDescIn;
10734 //PRX_DRIVER_INFO_8192S pDrvInfo;
10735
10736#ifdef USB_RX_AGGREGATION_SUPPORT//FIXLZM
10737 //if (bIsRxAggrSubframe)
10738 rx_desc_819x_usb_aggr_subframe *desc = (rx_desc_819x_usb_aggr_subframe *)skb->data;
10739 else
10740#endif
10741 rx_desc_819x_usb *desc = (rx_desc_819x_usb *)skb->data;
10742
10743 if(0)
10744 {
10745 int m = 0;
10746 printk("========================");
10747 for(m=0; m<skb->len; m++){
10748 if((m%32) == 0)
10749 printk("\n");
10750 printk("%2x ",((u8*)skb->data)[m]);
10751 }
10752 printk("\n========================\n");
10753
10754 }
10755
10756
10757 //
10758 //Get Rx Descriptor Raw Information
10759 //
10760 stats->Length = desc->Length ;
10761 stats->RxDrvInfoSize = desc->RxDrvInfoSize*RX_DRV_INFO_SIZE_UNIT;
10762 stats->RxBufShift = (desc->Shift)&0x03;
10763 stats->bICV = desc->ICV;
10764 stats->bCRC = desc->CRC32;
10765 stats->bHwError = stats->bCRC|stats->bICV;
10766 stats->Decrypted = !desc->SWDec;//RTL8190 set this bit to indicate that Hw does not decrypt packet
10767 stats->bIsAMPDU = (desc->AMSDU==1);
10768 stats->bFirstMPDU = (desc->PAGGR==1) && (desc->FAGGR==1);
10769 stats->bShortPreamble = desc->SPLCP;
10770 stats->RxIs40MHzPacket = (desc->BW==1);
10771 stats->TimeStampLow = desc->TSFL;
10772
10773 if((desc->FAGGR==1) || (desc->PAGGR==1))
10774 {// Rx A-MPDU
10775 RT_TRACE(COMP_RXDESC, "FirstAGGR = %d, PartAggr = %d\n", desc->FAGGR, desc->PAGGR);
10776 }
10777//YJ,test,090310
10778if(stats->bHwError)
10779{
10780 if(stats->bICV)
10781 printk("%s: Receive ICV error!!!!!!!!!!!!!!!!!!!!!!\n", __FUNCTION__);
10782 if(stats->bCRC)
10783 printk("%s: Receive CRC error!!!!!!!!!!!!!!!!!!!!!!\n", __FUNCTION__);
10784}
10785
10786 if(IS_UNDER_11N_AES_MODE(priv->ieee80211))
10787 {
10788 // Always received ICV error packets in AES mode.
10789 // This fixed HW later MIC write bug.
10790 if(stats->bICV && !stats->bCRC)
10791 {
10792 stats->bICV = FALSE;
10793 stats->bHwError = FALSE;
10794 }
10795 }
10796
10797 // Transform HwRate to MRate
10798 if(!stats->bHwError)
10799 //stats->DataRate = HwRateToMRate(
10800 // (BOOLEAN)GET_RX_DESC_RXHT(pDesc),
10801 // (u1Byte)GET_RX_DESC_RXMCS(pDesc),
10802 // (BOOLEAN)GET_RX_DESC_PAGGR(pDesc));
10803 stats->rate = rtl8192SU_HwRateToMRate(desc->RxHT, desc->RxMCS, desc->PAGGR);
10804 else
10805 stats->rate = MGN_1M;
10806
10807 //
10808 // Collect Rx rate/AMPDU/TSFL
10809 //
10810 //UpdateRxdRateHistogramStatistics8192S(Adapter, pRfd);
10811 //UpdateRxAMPDUHistogramStatistics8192S(Adapter, pRfd);
10812 //UpdateRxPktTimeStamp8192S(Adapter, pRfd);
10813 UpdateReceivedRateHistogramStatistics8190(dev, stats);
10814 //UpdateRxAMPDUHistogramStatistics8192S(dev, stats); //FIXLZM
10815 UpdateRxPktTimeStamp8190(dev, stats);
10816
10817 //
10818 // Get PHY Status and RSVD parts.
10819 // <Roger_Notes> It only appears on last aggregated packet.
10820 //
10821 if (desc->PHYStatus)
10822 {
10823 //driver_info = (rx_drvinfo_819x_usb *)(skb->data + RX_DESC_SIZE + stats->RxBufShift);
10824 driver_info = (rx_drvinfo_819x_usb *)(skb->data + sizeof(rx_desc_819x_usb) + \
10825 stats->RxBufShift);
10826 if(0)
10827 {
10828 int m = 0;
10829 printk("========================\n");
10830 printk("RX_DESC_SIZE:%d, RxBufShift:%d, RxDrvInfoSize:%d\n",
10831 RX_DESC_SIZE, stats->RxBufShift, stats->RxDrvInfoSize);
10832 for(m=0; m<32; m++){
10833 printk("%2x ",((u8*)driver_info)[m]);
10834 }
10835 printk("\n========================\n");
10836
10837 }
10838
10839 }
10840
10841 //YJ,add,090107
10842 skb_pull(skb, sizeof(rx_desc_819x_usb));
10843 //YJ,add,090107,end
10844
10845 //
10846 // Get Total offset of MPDU Frame Body
10847 //
10848 if((stats->RxBufShift + stats->RxDrvInfoSize) > 0)
10849 {
10850 stats->bShift = 1;
10851 //YJ,add,090107
10852 skb_pull(skb, stats->RxBufShift + stats->RxDrvInfoSize);
10853 //YJ,add,090107,end
10854 }
10855
10856 //
10857 // Get PHY Status and RSVD parts.
10858 // <Roger_Notes> It only appears on last aggregated packet.
10859 //
10860 if (desc->PHYStatus)
10861 {
10862 rtl8192SU_TranslateRxSignalStuff(skb, stats, desc, driver_info);
10863 }
10864}
10865#else
10866void query_rxdesc_status(struct sk_buff *skb, struct ieee80211_rx_stats *stats, bool bIsRxAggrSubframe)
10867{
10868 rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
10869 struct net_device *dev=info->dev;
10870 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
10871 //rx_desc_819x_usb *desc = (rx_desc_819x_usb *)skb->data;
10872 rx_drvinfo_819x_usb *driver_info = NULL;
10873
10874 //
10875 //Get Rx Descriptor Information
10876 //
10877#ifdef USB_RX_AGGREGATION_SUPPORT
10878 if (bIsRxAggrSubframe)
10879 {
10880 rx_desc_819x_usb_aggr_subframe *desc = (rx_desc_819x_usb_aggr_subframe *)skb->data;
10881 stats->Length = desc->Length ;
10882 stats->RxDrvInfoSize = desc->RxDrvInfoSize;
10883 stats->RxBufShift = 0; //RxBufShift = 2 in RxDesc, but usb didn't shift bytes in fact.
10884 stats->bICV = desc->ICV;
10885 stats->bCRC = desc->CRC32;
10886 stats->bHwError = stats->bCRC|stats->bICV;
10887 stats->Decrypted = !desc->SWDec;//RTL8190 set this bit to indicate that Hw does not decrypt packet
10888 } else
10889#endif
10890 {
10891 rx_desc_819x_usb *desc = (rx_desc_819x_usb *)skb->data;
10892
10893 stats->Length = desc->Length;
10894 stats->RxDrvInfoSize = desc->RxDrvInfoSize;
10895 stats->RxBufShift = 0;//desc->Shift&0x03;
10896 stats->bICV = desc->ICV;
10897 stats->bCRC = desc->CRC32;
10898 stats->bHwError = stats->bCRC|stats->bICV;
10899 //RTL8190 set this bit to indicate that Hw does not decrypt packet
10900 stats->Decrypted = !desc->SWDec;
10901 }
10902
10903 if((priv->ieee80211->pHTInfo->bCurrentHTSupport == true) && (priv->ieee80211->pairwise_key_type == KEY_TYPE_CCMP))
10904 {
10905 stats->bHwError = false;
10906 }
10907 else
10908 {
10909 stats->bHwError = stats->bCRC|stats->bICV;
10910 }
10911
10912 if(stats->Length < 24 || stats->Length > MAX_8192U_RX_SIZE)
10913 stats->bHwError |= 1;
10914 //
10915 //Get Driver Info
10916 //
10917 // TODO: Need to verify it on FGPA platform
10918 //Driver info are written to the RxBuffer following rx desc
10919 if (stats->RxDrvInfoSize != 0) {
10920 driver_info = (rx_drvinfo_819x_usb *)(skb->data + sizeof(rx_desc_819x_usb) + \
10921 stats->RxBufShift);
10922 /* unit: 0.5M */
10923 /* TODO */
10924 if(!stats->bHwError){
10925 u8 ret_rate;
10926 ret_rate = HwRateToMRate90(driver_info->RxHT, driver_info->RxRate);
10927 if(ret_rate == 0xff)
10928 {
10929 // Abnormal Case: Receive CRC OK packet with Rx descriptor indicating non supported rate.
10930 // Special Error Handling here, 2008.05.16, by Emily
10931
10932 stats->bHwError = 1;
10933 stats->rate = MGN_1M; //Set 1M rate by default
10934 }else
10935 {
10936 stats->rate = ret_rate;
10937 }
10938 }
10939 else
10940 stats->rate = 0x02;
10941
10942 stats->bShortPreamble = driver_info->SPLCP;
10943
10944
10945 UpdateReceivedRateHistogramStatistics8190(dev, stats);
10946
10947 stats->bIsAMPDU = (driver_info->PartAggr==1);
10948 stats->bFirstMPDU = (driver_info->PartAggr==1) && (driver_info->FirstAGGR==1);
10949#if 0
10950 // TODO: it is debug only. It should be disabled in released driver. 2007.1.12 by Joseph
10951 UpdateRxAMPDUHistogramStatistics8190(Adapter, pRfd);
10952#endif
10953 stats->TimeStampLow = driver_info->TSFL;
10954 // xiong mask it, 070514
10955 //pRfd->Status.TimeStampHigh = PlatformEFIORead4Byte(Adapter, TSFR+4);
10956 // stats->TimeStampHigh = read_nic_dword(dev, TSFR+4);
10957
10958 UpdateRxPktTimeStamp8190(dev, stats);
10959
10960 //
10961 // Rx A-MPDU
10962 //
10963 if(driver_info->FirstAGGR==1 || driver_info->PartAggr == 1)
10964 RT_TRACE(COMP_RXDESC, "driver_info->FirstAGGR = %d, driver_info->PartAggr = %d\n",
10965 driver_info->FirstAGGR, driver_info->PartAggr);
10966
10967 }
10968
10969 skb_pull(skb,sizeof(rx_desc_819x_usb));
10970 //
10971 // Get Total offset of MPDU Frame Body
10972 //
10973 if((stats->RxBufShift + stats->RxDrvInfoSize) > 0) {
10974 stats->bShift = 1;
10975 skb_pull(skb,stats->RxBufShift + stats->RxDrvInfoSize);
10976 }
10977
10978#ifdef USB_RX_AGGREGATION_SUPPORT
10979 /* for the rx aggregated sub frame, the redundant space truelly contained in the packet */
10980 if(bIsRxAggrSubframe) {
10981 skb_pull(skb, 8);
10982 }
10983#endif
10984 /* for debug 2008.5.29 */
10985#if 0
10986 {
10987 int i;
10988 printk("\n>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
10989 for(i = 0; i < skb->len; i++) {
10990 if(i % 10 == 0) printk("\n");
10991 printk("%02x ", skb->data[i]);
10992 }
10993 printk("\n<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
10994 }
10995#endif
10996
10997 //added by vivi, for MP, 20080108
10998 stats->RxIs40MHzPacket = driver_info->BW;
10999 if(stats->RxDrvInfoSize != 0)
11000 TranslateRxSignalStuff819xUsb(skb, stats, driver_info);
11001
11002}
11003#endif
11004
11005#ifdef RTL8192SU
11006#if 0
11007/*-----------------------------------------------------------------------------
11008 * Function: UpdateRxAMPDUHistogramStatistics8192S
11009 *
11010 * Overview: Recored down the received A-MPDU aggregation size and pkt number
11011 *
11012 * Input: Adapter
11013 *
11014 * Output: Adapter
11015 * (Adapter->RxStats.RxAMPDUSizeHistogram[] is updated)
11016 * (Adapter->RxStats.RxAMPDUNumHistogram[] is updated)
11017 *
11018 * Return: NONE
11019 *
11020 * Revised History:
11021 * When Who Remark
11022 * 09/18/2008 MHC Create Version 0.
11023 *
11024 *---------------------------------------------------------------------------*/
11025static void
11026UpdateRxAMPDUHistogramStatistics8192S(
11027 struct net_device *dev,
11028 struct ieee80211_rx_stats *stats
11029 )
11030{
11031 //HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
11032 u8 size_index;
11033 u8 num_index;
11034 u16 update_size = 0;
11035 u8 update_num = 0;
11036
11037 if(stats->bIsAMPDU)
11038 {
11039 if(stats->bFirstMPDU)
11040 {
11041 if(stats->nRxAMPDU_Size!=0 && stats->nRxAMPDU_AggrNum!=0)
11042 {
11043 update_size = stats->nRxAMPDU_Size;
11044 update_num = stats->nRxAMPDU_AggrNum;
11045 }
11046 stats->nRxAMPDU_Size = stats->Length;
11047 stats->nRxAMPDU_AggrNum = 1;
11048 }
11049 else
11050 {
11051 stats->nRxAMPDU_Size += stats->Length;
11052 stats->nRxAMPDU_AggrNum++;
11053 }
11054 }
11055 else
11056 {
11057 if(stats->nRxAMPDU_Size!=0 && stats->nRxAMPDU_AggrNum!=0)
11058 {
11059 update_size = stats->nRxAMPDU_Size;
11060 update_num = stats->nRxAMPDU_AggrNum;
11061 }
11062 stats->nRxAMPDU_Size = 0;
11063 stats->nRxAMPDU_AggrNum = 0;
11064 }
11065
11066 if(update_size!=0 && update_num!= 0)
11067 {
11068 if(update_size < 4096)
11069 size_index = 0;
11070 else if(update_size < 8192)
11071 size_index = 1;
11072 else if(update_size < 16384)
11073 size_index = 2;
11074 else if(update_size < 32768)
11075 size_index = 3;
11076 else if(update_size < 65536)
11077 size_index = 4;
11078 else
11079 {
11080 RT_TRACE(COMP_RXDESC,
11081 ("UpdateRxAMPDUHistogramStatistics8192S(): A-MPDU too large\n");
11082 }
11083
11084 Adapter->RxStats.RxAMPDUSizeHistogram[size_index]++;
11085
11086 if(update_num < 5)
11087 num_index = 0;
11088 else if(update_num < 10)
11089 num_index = 1;
11090 else if(update_num < 20)
11091 num_index = 2;
11092 else if(update_num < 40)
11093 num_index = 3;
11094 else
11095 num_index = 4;
11096
11097 Adapter->RxStats.RxAMPDUNumHistogram[num_index]++;
11098 }
11099} // UpdateRxAMPDUHistogramStatistics8192S
11100#endif
11101
11102#endif
11103
11104
11105#ifdef RTL8192SU
11106//
11107// Description:
11108// The strarting address of wireless lan header will shift 1 or 2 or 3 or "more" bytes for the following reason :
11109// (1) QoS control : shift 2 bytes
11110// (2) Mesh Network : shift 1 or 3 bytes
11111// (3) RxDriverInfo occupies the front parts of Rx Packets buffer(shift units is in 8Bytes)
11112//
11113// It is because Lextra CPU used by 8186 or 865x series assert exception if the statrting address
11114// of IP header is not double word alignment.
11115// This features is supported in 818xb and 8190 only, but not 818x.
11116//
11117// parameter: PRT_RFD, Pointer of Reeceive frame descriptor which is initialized according to
11118// Rx Descriptor
11119// return value: unsigned int, number of total shifted bytes
11120//
11121// Notes: 2008/06/28, created by Roger
11122//
11123u32 GetRxPacketShiftBytes8192SU(struct ieee80211_rx_stats *Status, bool bIsRxAggrSubframe)
11124{
11125 //PRT_RFD_STATUS pRtRfdStatus = &pRfd->Status;
11126
11127 return (sizeof(rx_desc_819x_usb) + Status->RxDrvInfoSize + Status->RxBufShift);
11128}
11129
11130void rtl8192SU_rx_nomal(struct sk_buff* skb)
11131{
11132 rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
11133 struct net_device *dev=info->dev;
11134 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
11135 struct ieee80211_rx_stats stats = {
11136 .signal = 0,
11137 .noise = -98,
11138 .rate = 0,
11139 // .mac_time = jiffies,
11140 .freq = IEEE80211_24GHZ_BAND,
11141 };
11142 u32 rx_pkt_len = 0;
11143 struct ieee80211_hdr_1addr *ieee80211_hdr = NULL;
11144 bool unicast_packet = false;
11145
11146#ifdef USB_RX_AGGREGATION_SUPPORT
11147 struct sk_buff *agg_skb = NULL;
11148 u32 TotalLength = 0;//Total packet length for all aggregated packets.
11149 u32 TempDWord = 0;
11150 u32 PacketLength = 0;// Per-packet length include size of RxDesc.
11151 u32 PacketOccupiedLendth = 0;
11152 u8 TempByte = 0;
11153 u32 PacketShiftBytes = 0;
11154 rx_desc_819x_usb_aggr_subframe *RxDescr = NULL;
11155 u8 PaddingBytes = 0;
11156 //add just for testing
11157 u8 testing;
11158
11159 u8 TotalAggPkt = 0;
11160 PRT_HIGH_THROUGHPUT pHTInfo =priv-> ieee80211->pHTInfo;
11161 u16 RxPageSize = pHTInfo->UsbRxPageSize;
11162
11163 stats->nTotalAggPkt = 0;
11164 //stats->bIsRxAggrSubframe = FALSE;
11165
11166#endif
11167 //printk("**********skb->len = %d\n", skb->len);
11168 /* 20 is for ps-poll */
11169 if((skb->len >=(20 + sizeof(rx_desc_819x_usb))) && (skb->len < RX_URB_SIZE)) {
11170
11171 /* first packet should not contain Rx aggregation header */
11172 rtl8192SU_query_rxdesc_status(skb, &stats, false);
11173 /* TODO */
11174
11175 /* hardware related info */
11176#ifdef USB_RX_AGGREGATION_SUPPORT
11177 TotalAggPkt = stats->nTotalAggPkt;
11178 PacketLength = stats->Length + GetRxPacketShiftBytes8192SU(&stats, false);
11179
11180 agg_skb = skb;
11181 skb = dev_alloc_skb(PacketLength);
11182 memcpy(skb_put(skb,PacketLength),agg_skb->data,PacketLength);
11183#endif
11184 priv->stats.rxoktotal++; //YJ,test,090108
11185
11186 /* Process the MPDU recevied */
11187 skb_trim(skb, skb->len - 4/*sCrcLng*/);//FIXLZM
11188
11189 rx_pkt_len = skb->len;
11190 ieee80211_hdr = (struct ieee80211_hdr_1addr *)skb->data;
11191 unicast_packet = false;
11192 if(is_broadcast_ether_addr(ieee80211_hdr->addr1)) {
11193 //TODO
11194 }else if(is_multicast_ether_addr(ieee80211_hdr->addr1)){
11195 //TODO
11196 }else {
11197 /* unicast packet */
11198 unicast_packet = true;
11199 }
11200
11201 if(!ieee80211_rx(priv->ieee80211,skb, &stats)) {
11202 dev_kfree_skb_any(skb);
11203 } else {
11204 // priv->stats.rxoktotal++; //YJ,test,090108
11205 if(unicast_packet) {
11206 priv->stats.rxbytesunicast += rx_pkt_len;
11207 }
11208 }
11209
11210 //up is firs pkt, follow is next and next
11211#ifdef USB_RX_AGGREGATION_SUPPORT
11212 //
11213 // The following operations are for processing Rx aggregated packets.
11214 //
11215 if(TotalAggPkt>0)
11216 TotalAggPkt--;
11217
11218 while ( TotalAggPkt>0 )
11219 {// More aggregated packets need to process.
11220
11221 u8 tmpCRC = 0, tmpICV = 0;
11222
11223 //Page size must align to multiple of 128-Bytes.
11224 if((PacketLength%RxPageSize) != 0)
11225 //PacketLength = ((PacketLength/RxPageSize)+1)*RxPageSize;
11226 PacketLength = ((PacketLength>>7)+1)*RxPageSize; // RxPageSize is 128bytes as default.
11227
11228 // Current total packet occupied length in this buffer.
11229 PacketOccupiedLendth += PacketLength;
11230
11231#if (defined (RTL8192SU_FPGA_2MAC_VERIFICATION)||defined (RTL8192SU_ASIC_VERIFICATION))
11232 //if(PacketOccupiedLendth>pContext->BufLenUsed)
11233 if(PacketOccupiedLendth>skb->len)
11234 {
11235 RT_TRACE(COMP_RECV, "(1)HalUsbInMpduComplete8192SUsb(): pRtRfdStatus->Length(%#x)!!\n", stats->Length);
11236 RT_TRACE(COMP_RECV, "(1)HalUsbInMpduComplete8192SUsb(): Invalid PacketOccupiedLendth(%#x)!!, BufLenUsed(%#x)\n", PacketOccupiedLendth, stats->BufLenUsed);
11237 break;
11238 }
11239#endif
11240
11241 skb_pull(agg_skb, PacketLength);
11242
11243 //
11244 // Process the MPDU recevied.
11245 //
11246 //RT_TRACE(COMP_RECV,"%s:aggred pkt,total_len = %d\n",__FUNCTION__,agg_skb->len);
11247 RxDescr = (rx_desc_819x_usb_aggr_subframe *)(agg_skb->data);
11248
11249#if 0//92SU del
11250 tmpCRC = RxDescr->CRC32;
11251 tmpICV = RxDescr->ICV;
11252 memcpy(agg_skb->data, &agg_skb->data[44], 2);
11253 RxDescr->CRC32 = tmpCRC;
11254 RxDescr->ICV = tmpICV;
11255#endif
11256 memset(&stats, 0, sizeof(struct ieee80211_rx_stats));
11257 stats.signal = 0;
11258 stats.noise = -98;
11259 stats.rate = 0;
11260 stats.freq = IEEE80211_24GHZ_BAND;
11261
11262 rtl8192SU_query_rxdesc_status(agg_skb, &stats, true);
11263 //PacketLength = stats.Length;
11264 PacketLength = stats.Length + GetRxPacketShiftBytes8192SU(&stats, true);
11265
11266#if (defined (RTL8192SU_FPGA_2MAC_VERIFICATION)||defined (RTL8192SU_ASIC_VERIFICATION))
11267 if((PacketOccupiedLendth+PacketLength)>skb->len)
11268 {
11269 RT_TRACE(COMP_RECV, "(2)HalUsbInMpduComplete8192SUsb(): Invalid PacketOccupiedLendth(%#x)+PacketLength(%#x)!!, BufLenUsed(%#x)\n",
11270 PacketOccupiedLendth, PacketLength, pContext->BufLenUsed);
11271 break;
11272 }
11273#endif
11274
11275 if(PacketLength > agg_skb->len) {
11276 break;
11277 }
11278
11279 /* Process the MPDU recevied */
11280 skb = dev_alloc_skb(PacketLength);
11281 memcpy(skb_put(skb,PacketLength),agg_skb->data, PacketLength);
11282 skb_trim(skb, skb->len - 4/*sCrcLng*/);
11283
11284 rx_pkt_len = skb->len;
11285 ieee80211_hdr = (struct ieee80211_hdr_1addr *)skb->data;
11286 unicast_packet = false;
11287 if(is_broadcast_ether_addr(ieee80211_hdr->addr1)) {
11288 //TODO
11289 }else if(is_multicast_ether_addr(ieee80211_hdr->addr1)){
11290 //TODO
11291 }else {
11292 /* unicast packet */
11293 unicast_packet = true;
11294 }
11295 if(!ieee80211_rx(priv->ieee80211,skb, &stats)) {
11296 dev_kfree_skb_any(skb);
11297 } else {
11298 priv->stats.rxoktotal++;
11299 if(unicast_packet) {
11300 priv->stats.rxbytesunicast += rx_pkt_len;
11301 }
11302 }
11303
11304 TotalAggPkt--;
11305
11306 skb_pull(agg_skb, TempDWord);
11307 }
11308
11309 dev_kfree_skb(agg_skb);
11310#endif
11311 }
11312 else
11313 {
11314 priv->stats.rxurberr++;
11315 printk("actual_length:%d\n", skb->len);
11316 dev_kfree_skb_any(skb);
11317 }
11318
11319}
11320#else
11321u32 GetRxPacketShiftBytes819xUsb(struct ieee80211_rx_stats *Status, bool bIsRxAggrSubframe)
11322{
11323#ifdef USB_RX_AGGREGATION_SUPPORT
11324 if (bIsRxAggrSubframe)
11325 return (sizeof(rx_desc_819x_usb) + Status->RxDrvInfoSize
11326 + Status->RxBufShift + 8);
11327 else
11328#endif
11329 return (sizeof(rx_desc_819x_usb) + Status->RxDrvInfoSize
11330 + Status->RxBufShift);
11331}
11332
11333void rtl8192_rx_nomal(struct sk_buff* skb)
11334{
11335 rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
11336 struct net_device *dev=info->dev;
11337 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
11338 struct ieee80211_rx_stats stats = {
11339 .signal = 0,
11340 .noise = -98,
11341 .rate = 0,
11342 // .mac_time = jiffies,
11343 .freq = IEEE80211_24GHZ_BAND,
11344 };
11345 u32 rx_pkt_len = 0;
11346 struct ieee80211_hdr_1addr *ieee80211_hdr = NULL;
11347 bool unicast_packet = false;
11348#ifdef USB_RX_AGGREGATION_SUPPORT
11349 struct sk_buff *agg_skb = NULL;
11350 u32 TotalLength = 0;
11351 u32 TempDWord = 0;
11352 u32 PacketLength = 0;
11353 u32 PacketOccupiedLendth = 0;
11354 u8 TempByte = 0;
11355 u32 PacketShiftBytes = 0;
11356 rx_desc_819x_usb_aggr_subframe *RxDescr = NULL;
11357 u8 PaddingBytes = 0;
11358 //add just for testing
11359 u8 testing;
11360
11361#endif
11362
11363 /* 20 is for ps-poll */
11364 if((skb->len >=(20 + sizeof(rx_desc_819x_usb))) && (skb->len < RX_URB_SIZE)) {
11365#ifdef USB_RX_AGGREGATION_SUPPORT
11366 TempByte = *(skb->data + sizeof(rx_desc_819x_usb));
11367#endif
11368 /* first packet should not contain Rx aggregation header */
11369 query_rxdesc_status(skb, &stats, false);
11370 /* TODO */
11371 /* hardware related info */
11372#ifdef USB_RX_AGGREGATION_SUPPORT
11373 if (TempByte & BIT0) {
11374 agg_skb = skb;
11375 //TotalLength = agg_skb->len - 4; /*sCrcLng*/
11376 TotalLength = stats.Length - 4; /*sCrcLng*/
11377 //RT_TRACE(COMP_RECV, "%s:first aggregated packet!Length=%d\n",__FUNCTION__,TotalLength);
11378 /* though the head pointer has passed this position */
11379 TempDWord = *(u32 *)(agg_skb->data - 4);
11380 PacketLength = (u16)(TempDWord & 0x3FFF); /*sCrcLng*/
11381 skb = dev_alloc_skb(PacketLength);
11382 memcpy(skb_put(skb,PacketLength),agg_skb->data,PacketLength);
11383 PacketShiftBytes = GetRxPacketShiftBytes819xUsb(&stats, false);
11384 }
11385#endif
11386 /* Process the MPDU recevied */
11387 skb_trim(skb, skb->len - 4/*sCrcLng*/);
11388
11389 rx_pkt_len = skb->len;
11390 ieee80211_hdr = (struct ieee80211_hdr_1addr *)skb->data;
11391 unicast_packet = false;
11392 if(is_broadcast_ether_addr(ieee80211_hdr->addr1)) {
11393 //TODO
11394 }else if(is_multicast_ether_addr(ieee80211_hdr->addr1)){
11395 //TODO
11396 }else {
11397 /* unicast packet */
11398 unicast_packet = true;
11399 }
11400
11401 if(!ieee80211_rx(priv->ieee80211,skb, &stats)) {
11402 dev_kfree_skb_any(skb);
11403 } else {
11404 priv->stats.rxoktotal++;
11405 if(unicast_packet) {
11406 priv->stats.rxbytesunicast += rx_pkt_len;
11407 }
11408 }
11409#ifdef USB_RX_AGGREGATION_SUPPORT
11410 testing = 1;
11411 // (PipeIndex == 0) && (TempByte & BIT0) => TotalLength > 0.
11412 if (TotalLength > 0) {
11413 PacketOccupiedLendth = PacketLength + (PacketShiftBytes + 8);
11414 if ((PacketOccupiedLendth & 0xFF) != 0)
11415 PacketOccupiedLendth = (PacketOccupiedLendth & 0xFFFFFF00) + 256;
11416 PacketOccupiedLendth -= 8;
11417 TempDWord = PacketOccupiedLendth - PacketShiftBytes; /*- PacketLength */
11418 if (agg_skb->len > TempDWord)
11419 skb_pull(agg_skb, TempDWord);
11420 else
11421 agg_skb->len = 0;
11422
11423 while (agg_skb->len>=GetRxPacketShiftBytes819xUsb(&stats, true)) {
11424 u8 tmpCRC = 0, tmpICV = 0;
11425 //RT_TRACE(COMP_RECV,"%s:aggred pkt,total_len = %d\n",__FUNCTION__,agg_skb->len);
11426 RxDescr = (rx_desc_819x_usb_aggr_subframe *)(agg_skb->data);
11427 tmpCRC = RxDescr->CRC32;
11428 tmpICV = RxDescr->ICV;
11429 memcpy(agg_skb->data, &agg_skb->data[44], 2);
11430 RxDescr->CRC32 = tmpCRC;
11431 RxDescr->ICV = tmpICV;
11432
11433 memset(&stats, 0, sizeof(struct ieee80211_rx_stats));
11434 stats.signal = 0;
11435 stats.noise = -98;
11436 stats.rate = 0;
11437 stats.freq = IEEE80211_24GHZ_BAND;
11438 query_rxdesc_status(agg_skb, &stats, true);
11439 PacketLength = stats.Length;
11440
11441 if(PacketLength > agg_skb->len) {
11442 break;
11443 }
11444 /* Process the MPDU recevied */
11445 skb = dev_alloc_skb(PacketLength);
11446 memcpy(skb_put(skb,PacketLength),agg_skb->data, PacketLength);
11447 skb_trim(skb, skb->len - 4/*sCrcLng*/);
11448
11449 rx_pkt_len = skb->len;
11450 ieee80211_hdr = (struct ieee80211_hdr_1addr *)skb->data;
11451 unicast_packet = false;
11452 if(is_broadcast_ether_addr(ieee80211_hdr->addr1)) {
11453 //TODO
11454 }else if(is_multicast_ether_addr(ieee80211_hdr->addr1)){
11455 //TODO
11456 }else {
11457 /* unicast packet */
11458 unicast_packet = true;
11459 }
11460 if(!ieee80211_rx(priv->ieee80211,skb, &stats)) {
11461 dev_kfree_skb_any(skb);
11462 } else {
11463 priv->stats.rxoktotal++;
11464 if(unicast_packet) {
11465 priv->stats.rxbytesunicast += rx_pkt_len;
11466 }
11467 }
11468 /* should trim the packet which has been copied to target skb */
11469 skb_pull(agg_skb, PacketLength);
11470 PacketShiftBytes = GetRxPacketShiftBytes819xUsb(&stats, true);
11471 PacketOccupiedLendth = PacketLength + PacketShiftBytes;
11472 if ((PacketOccupiedLendth & 0xFF) != 0) {
11473 PaddingBytes = 256 - (PacketOccupiedLendth & 0xFF);
11474 if (agg_skb->len > PaddingBytes)
11475 skb_pull(agg_skb, PaddingBytes);
11476 else
11477 agg_skb->len = 0;
11478 }
11479 }
11480 dev_kfree_skb(agg_skb);
11481 }
11482#endif
11483 } else {
11484 priv->stats.rxurberr++;
11485 printk("actual_length:%d\n", skb->len);
11486 dev_kfree_skb_any(skb);
11487 }
11488
11489}
11490
11491#endif
11492
11493void
11494rtl819xusb_process_received_packet(
11495 struct net_device *dev,
11496 struct ieee80211_rx_stats *pstats
11497 )
11498{
11499// bool bfreerfd=false, bqueued=false;
11500 u8* frame;
11501 u16 frame_len=0;
11502 struct r8192_priv *priv = ieee80211_priv(dev);
11503// u8 index = 0;
11504// u8 TID = 0;
11505 //u16 seqnum = 0;
11506 //PRX_TS_RECORD pts = NULL;
11507
11508 // Get shifted bytes of Starting address of 802.11 header. 2006.09.28, by Emily
11509 //porting by amy 080508
11510 pstats->virtual_address += get_rxpacket_shiftbytes_819xusb(pstats);
11511 frame = pstats->virtual_address;
11512 frame_len = pstats->packetlength;
11513#ifdef TODO // by amy about HCT
11514 if(!Adapter->bInHctTest)
11515 CountRxErrStatistics(Adapter, pRfd);
11516#endif
11517 {
11518 #ifdef ENABLE_PS //by amy for adding ps function in future
11519 RT_RF_POWER_STATE rtState;
11520 // When RF is off, we should not count the packet for hw/sw synchronize
11521 // reason, ie. there may be a duration while sw switch is changed and hw
11522 // switch is being changed. 2006.12.04, by shien chang.
11523 Adapter->HalFunc.GetHwRegHandler(Adapter, HW_VAR_RF_STATE, (u8* )(&rtState));
11524 if (rtState == eRfOff)
11525 {
11526 return;
11527 }
11528 #endif
11529 priv->stats.rxframgment++;
11530
11531 }
11532#ifdef TODO
11533 RmMonitorSignalStrength(Adapter, pRfd);
11534#endif
11535 /* 2007/01/16 MH Add RX command packet handle here. */
11536 /* 2007/03/01 MH We have to release RFD and return if rx pkt is cmd pkt. */
11537 if (rtl819xusb_rx_command_packet(dev, pstats))
11538 {
11539 return;
11540 }
11541
11542#ifdef SW_CRC_CHECK
11543 SwCrcCheck();
11544#endif
11545
11546
11547}
11548
11549void query_rx_cmdpkt_desc_status(struct sk_buff *skb, struct ieee80211_rx_stats *stats)
11550{
11551// rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
11552// struct net_device *dev=info->dev;
11553// struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
11554 rx_desc_819x_usb *desc = (rx_desc_819x_usb *)skb->data;
11555// rx_drvinfo_819x_usb *driver_info;
11556
11557 //
11558 //Get Rx Descriptor Information
11559 //
11560 stats->virtual_address = (u8*)skb->data;
11561 stats->Length = desc->Length;
11562 stats->RxDrvInfoSize = 0;
11563 stats->RxBufShift = 0;
11564 stats->packetlength = stats->Length-scrclng;
11565 stats->fraglength = stats->packetlength;
11566 stats->fragoffset = 0;
11567 stats->ntotalfrag = 1;
11568}
11569
11570#ifdef RTL8192SU
11571void rtl8192SU_rx_cmd(struct sk_buff *skb)
11572{
11573 struct rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
11574 struct net_device *dev = info->dev;
11575
11576 /* TODO */
11577 struct ieee80211_rx_stats stats = {
11578 .signal = 0,
11579 .noise = -98,
11580 .rate = 0,
11581 // .mac_time = jiffies,
11582 .freq = IEEE80211_24GHZ_BAND,
11583 };
11584
11585 //
11586 // Check buffer length to determine if this is a valid MPDU.
11587 //
11588 if( (skb->len >= sizeof(rx_desc_819x_usb)) && (skb->len <= RX_URB_SIZE) )//&&
11589 //(pHalData->SwChnlInProgress == FALSE))
11590 {
11591 //
11592 // Collection information in Rx descriptor.
11593 //
11594#if 0
11595 pRxDesc = pContext->Buffer;
11596
11597 pRfd->Buffer.VirtualAddress = pContext->Buffer; // 061109, rcnjko, for multi-platform consideration..
11598
11599 pRtRfdStatus->Length = (u2Byte)GET_RX_DESC_PKT_LEN(pRxDesc);
11600 pRtRfdStatus->RxDrvInfoSize = 0;
11601 pRtRfdStatus->RxBufShift = 0;
11602
11603 pRfd->PacketLength = pRfd->Status.Length - sCrcLng;
11604 pRfd->FragLength = pRfd->PacketLength;
11605 pRfd->FragOffset = 0;
11606 pRfd->nTotalFrag = 1;
11607 pRfd->queue_id = PipeIndex;
11608#endif
11609 query_rx_cmdpkt_desc_status(skb,&stats);
11610 // this is to be done by amy 080508 prfd->queue_id = 1;
11611
11612 //
11613 // Process the MPDU recevied.
11614 //
11615 rtl819xusb_process_received_packet(dev,&stats);
11616
11617 dev_kfree_skb_any(skb);
11618 }
11619 else
11620 {
11621 //RTInsertTailListWithCnt(&pAdapter->RfdIdleQueue, &pRfd->List, &pAdapter->NumIdleRfd);
11622 //RT_ASSERT(pAdapter->NumIdleRfd <= pAdapter->NumRfd, ("HalUsbInCommandComplete8192SUsb(): Adapter->NumIdleRfd(%d)\n", pAdapter->NumIdleRfd));
11623 //RT_TRACE(COMP_RECV, DBG_LOUD, ("HalUsbInCommandComplete8192SUsb(): NOT enough Resources!! BufLenUsed(%d), NumIdleRfd(%d)\n",
11624 //pContext->BufLenUsed, pAdapter->NumIdleRfd));
11625 }
11626
11627 //
11628 // Reuse USB_IN_CONTEXT since we had finished processing the
11629 // buffer in USB_IN_CONTEXT.
11630 //
11631 //HalUsbReturnInContext(pAdapter, pContext);
11632
11633 //
11634 // Issue another bulk IN transfer.
11635 //
11636 //HalUsbInMpdu(pAdapter, PipeIndex);
11637
11638 RT_TRACE(COMP_RECV, "<--- HalUsbInCommandComplete8192SUsb()\n");
11639
11640}
11641#else
11642void rtl8192_rx_cmd(struct sk_buff *skb)
11643{
11644 struct rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
11645 struct net_device *dev = info->dev;
11646 //int ret;
11647// struct urb *rx_urb = info->urb;
11648 /* TODO */
11649 struct ieee80211_rx_stats stats = {
11650 .signal = 0,
11651 .noise = -98,
11652 .rate = 0,
11653 // .mac_time = jiffies,
11654 .freq = IEEE80211_24GHZ_BAND,
11655 };
11656
11657 if((skb->len >=(20 + sizeof(rx_desc_819x_usb))) && (skb->len < RX_URB_SIZE))
11658 {
11659
11660 query_rx_cmdpkt_desc_status(skb,&stats);
11661 // this is to be done by amy 080508 prfd->queue_id = 1;
11662
11663
11664 //
11665 // Process the command packet received.
11666 //
11667
11668 rtl819xusb_process_received_packet(dev,&stats);
11669
11670 dev_kfree_skb_any(skb);
11671 }
11672 else
11673 ;
11674
11675
11676#if 0
11677 desc = (u32*)(skb->data);
11678 cmd = (desc[0] >> 30) & 0x03;
11679
11680 if(cmd == 0x00) {//beacon interrupt
11681 //send beacon packet
11682 skb = ieee80211_get_beacon(priv->ieee80211);
11683
11684 if(!skb){
11685 DMESG("not enought memory for allocating beacon");
11686 return;
11687 }
11688 skb->cb[0] = BEACON_PRIORITY;
11689 skb->cb[1] = 0;
11690 skb->cb[2] = ieeerate2rtlrate(priv->ieee80211->basic_rate);
11691 ret = rtl8192_tx(dev, skb);
11692
11693 if( ret != 0 ){
11694 printk(KERN_ALERT "tx beacon packet error : %d !\n", ret);
11695 }
11696 dev_kfree_skb_any(skb);
11697 } else {//0x00
11698 //{ log the device information
11699 // At present, It is not implemented just now.
11700 //}
11701 }
11702#endif
11703}
11704#endif
11705
11706void rtl8192_irq_rx_tasklet(struct r8192_priv *priv)
11707{
11708 struct sk_buff *skb;
11709 struct rtl8192_rx_info *info;
11710
11711 while (NULL != (skb = skb_dequeue(&priv->skb_queue))) {
11712 info = (struct rtl8192_rx_info *)skb->cb;
11713 switch (info->out_pipe) {
11714 /* Nomal packet pipe */
11715 case 3:
11716 //RT_TRACE(COMP_RECV, "normal in-pipe index(%d)\n",info->out_pipe);
11717 priv->IrpPendingCount--;
11718 priv->ops->rtl819x_rx_nomal(skb);
11719 break;
11720
11721 /* Command packet pipe */
11722 case 9:
11723 RT_TRACE(COMP_RECV, "command in-pipe index(%d)\n",\
11724 info->out_pipe);
11725 priv->ops->rtl819x_rx_cmd(skb);
11726 break;
11727
11728 default: /* should never get here! */
11729 RT_TRACE(COMP_ERR, "Unknown in-pipe index(%d)\n",\
11730 info->out_pipe);
11731 dev_kfree_skb(skb);
11732 break;
11733
11734 }
11735 }
11736}
11737
11738
11739
11740/****************************************************************************
11741 ---------------------------- USB_STUFF---------------------------
11742*****************************************************************************/
Jerry Chuang5f53d8c2009-05-21 22:16:02 -070011743//LZM Merge from windows HalUsbSetQueuePipeMapping8192SUsb 090319
11744static void HalUsbSetQueuePipeMapping8192SUsb(struct usb_interface *intf, struct net_device *dev)
11745{
11746 struct r8192_priv *priv = ieee80211_priv(dev);
11747 struct usb_host_interface *iface_desc;
11748 struct usb_endpoint_descriptor *endpoint;
11749 u8 i = 0;
11750
11751 priv->ep_in_num = 0;
11752 priv->ep_out_num = 0;
11753 memset(priv->RtOutPipes,0,16);
11754 memset(priv->RtInPipes,0,16);
11755
11756#ifndef USE_ONE_PIPE
11757 iface_desc = intf->cur_altsetting;
11758 priv->ep_num = iface_desc->desc.bNumEndpoints;
11759
11760 for (i = 0; i < priv->ep_num; ++i) {
11761 endpoint = &iface_desc->endpoint[i].desc;
Jerry Chuang5f53d8c2009-05-21 22:16:02 -070011762 if (usb_endpoint_is_bulk_in(endpoint)) {
11763 priv->RtInPipes[priv->ep_in_num] = usb_endpoint_num(endpoint);
11764 priv->ep_in_num ++;
11765 //printk("in_endpoint_idx = %d\n", usb_endpoint_num(endpoint));
11766 } else if (usb_endpoint_is_bulk_out(endpoint)) {
11767 priv->RtOutPipes[priv->ep_out_num] = usb_endpoint_num(endpoint);
11768 priv->ep_out_num ++;
11769 //printk("out_endpoint_idx = %d\n", usb_endpoint_num(endpoint));
11770 }
Jerry Chuang5f53d8c2009-05-21 22:16:02 -070011771 }
11772 {
11773 memset(priv->txqueue_to_outpipemap,0,9);
11774 if (priv->ep_num == 6) {
11775 // BK, BE, VI, VO, HCCA, TXCMD, MGNT, HIGH, BEACON
11776 u8 queuetopipe[] = {3, 2, 1, 0, 4, 4, 4, 4, 4};
11777
11778 memcpy(priv->txqueue_to_outpipemap,queuetopipe,9);
11779 } else if (priv->ep_num == 4) {
11780 // BK, BE, VI, VO, HCCA, TXCMD, MGNT, HIGH, BEACON
11781 u8 queuetopipe[] = {1, 1, 0, 0, 2, 2, 2, 2, 2};
11782
11783 memcpy(priv->txqueue_to_outpipemap,queuetopipe,9);
11784 } else if (priv->ep_num > 9) {
11785 // BK, BE, VI, VO, HCCA, TXCMD, MGNT, HIGH, BEACON
11786 u8 queuetopipe[] = {3, 2, 1, 0, 4, 8, 7, 6, 5};
11787
11788 memcpy(priv->txqueue_to_outpipemap,queuetopipe,9);
11789 } else {//use sigle pipe
11790 // BK, BE, VI, VO, HCCA, TXCMD, MGNT, HIGH, BEACON
11791 u8 queuetopipe[] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
11792 memcpy(priv->txqueue_to_outpipemap,queuetopipe,9);
11793 }
11794 }
11795 printk("==>ep_num:%d, in_ep_num:%d, out_ep_num:%d\n", priv->ep_num, priv->ep_in_num, priv->ep_out_num);
11796
11797 printk("==>RtInPipes:");
11798 for(i=0; i < priv->ep_in_num; i++)
11799 printk("%d ", priv->RtInPipes[i]);
11800 printk("\n");
11801
11802 printk("==>RtOutPipes:");
11803 for(i=0; i < priv->ep_out_num; i++)
11804 printk("%d ", priv->RtOutPipes[i]);
11805 printk("\n");
11806
11807 printk("==>txqueue_to_outpipemap for BK, BE, VI, VO, HCCA, TXCMD, MGNT, HIGH, BEACON:\n");
11808 for(i=0; i < 9; i++)
11809 printk("%d ", priv->txqueue_to_outpipemap[i]);
11810 printk("\n");
11811#else
11812 {
11813 memset(priv->txqueue_to_outpipemap,0,9);
11814 memset(priv->RtOutPipes,4,16);//all use endpoint 4 for out
11815 }
11816#endif
11817
11818 return;
11819}
Jerry Chuang5f53d8c2009-05-21 22:16:02 -070011820
Bartlomiej Zolnierkiewicz77b92882009-06-11 20:49:07 +020011821static const struct net_device_ops rtl8192_netdev_ops = {
11822 .ndo_open = rtl8192_open,
11823 .ndo_stop = rtl8192_close,
11824 .ndo_get_stats = rtl8192_stats,
11825 .ndo_tx_timeout = tx_timeout,
11826 .ndo_do_ioctl = rtl8192_ioctl,
11827 .ndo_set_multicast_list = r8192_set_multicast,
11828 .ndo_set_mac_address = r8192_set_mac_adr,
11829 .ndo_validate_addr = eth_validate_addr,
11830 .ndo_change_mtu = eth_change_mtu,
Greg Kroah-Hartmance9c0102009-08-04 16:53:36 -070011831 .ndo_start_xmit = rtl8192_ieee80211_xmit,
Bartlomiej Zolnierkiewicz77b92882009-06-11 20:49:07 +020011832};
11833
Jerry Chuang5f53d8c2009-05-21 22:16:02 -070011834static int __devinit rtl8192_usb_probe(struct usb_interface *intf,
11835 const struct usb_device_id *id)
Jerry Chuang5f53d8c2009-05-21 22:16:02 -070011836{
11837// unsigned long ioaddr = 0;
11838 struct net_device *dev = NULL;
11839 struct r8192_priv *priv= NULL;
Jerry Chuang5f53d8c2009-05-21 22:16:02 -070011840 struct usb_device *udev = interface_to_usbdev(intf);
Bartlomiej Zolnierkiewicz1ec9e482009-06-13 18:35:04 +020011841
Jerry Chuang5f53d8c2009-05-21 22:16:02 -070011842 RT_TRACE(COMP_INIT, "Oops: i'm coming\n");
11843
11844 dev = alloc_ieee80211(sizeof(struct r8192_priv));
11845
Jerry Chuang5f53d8c2009-05-21 22:16:02 -070011846 usb_set_intfdata(intf, dev);
11847 SET_NETDEV_DEV(dev, &intf->dev);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -070011848 priv = ieee80211_priv(dev);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -070011849 priv->ieee80211 = netdev_priv(dev);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -070011850 priv->udev=udev;
11851
11852#ifdef RTL8192SU
Jerry Chuang5f53d8c2009-05-21 22:16:02 -070011853 HalUsbSetQueuePipeMapping8192SUsb(intf, dev);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -070011854#endif
11855
11856#ifdef RTL8192SU
11857 //printk("===============>NIC 8192SU\n");
11858 priv->ops = &rtl8192su_ops;
11859#else
11860 //printk("===============>NIC 8192U\n");
11861 priv->ops = &rtl8192u_ops;
11862#endif
11863
Bartlomiej Zolnierkiewicz77b92882009-06-11 20:49:07 +020011864 dev->netdev_ops = &rtl8192_netdev_ops;
Jerry Chuang5f53d8c2009-05-21 22:16:02 -070011865
11866 //DMESG("Oops: i'm coming\n");
Jerry Chuang5f53d8c2009-05-21 22:16:02 -070011867 dev->wireless_handlers = (struct iw_handler_def *) &r8192_wx_handlers_def;
Bartlomiej Zolnierkiewicz3bd709f2009-06-13 18:35:58 +020011868
Jerry Chuang5f53d8c2009-05-21 22:16:02 -070011869 dev->type=ARPHRD_ETHER;
11870
11871 dev->watchdog_timeo = HZ*3; //modified by john, 0805
11872
11873 if (dev_alloc_name(dev, ifname) < 0){
11874 RT_TRACE(COMP_INIT, "Oops: devname already taken! Trying wlan%%d...\n");
11875 ifname = "wlan%d";
11876 dev_alloc_name(dev, ifname);
11877 }
11878
11879 RT_TRACE(COMP_INIT, "Driver probe completed1\n");
11880#if 1
11881 if(rtl8192_init(dev)!=0){
11882 RT_TRACE(COMP_ERR, "Initialization failed");
11883 goto fail;
11884 }
11885#endif
11886 netif_carrier_off(dev);
11887 netif_stop_queue(dev);
11888
11889 register_netdev(dev);
11890 RT_TRACE(COMP_INIT, "dev name=======> %s\n",dev->name);
11891 rtl8192_proc_init_one(dev);
11892
11893
11894 RT_TRACE(COMP_INIT, "Driver probe completed\n");
Jerry Chuang5f53d8c2009-05-21 22:16:02 -070011895 return 0;
Jerry Chuang5f53d8c2009-05-21 22:16:02 -070011896fail:
11897 free_ieee80211(dev);
11898
11899 RT_TRACE(COMP_ERR, "wlan driver load failed\n");
Jerry Chuang5f53d8c2009-05-21 22:16:02 -070011900 return -ENODEV;
Jerry Chuang5f53d8c2009-05-21 22:16:02 -070011901}
11902
11903//detach all the work and timer structure declared or inititialize in r8192U_init function.
11904void rtl8192_cancel_deferred_work(struct r8192_priv* priv)
11905{
Jerry Chuang5f53d8c2009-05-21 22:16:02 -070011906 cancel_work_sync(&priv->reset_wq);
11907 cancel_work_sync(&priv->qos_activate);
11908 cancel_delayed_work(&priv->watch_dog_wq);
11909 cancel_delayed_work(&priv->update_beacon_wq);
11910 cancel_delayed_work(&priv->ieee80211->hw_wakeup_wq);
11911 cancel_delayed_work(&priv->ieee80211->hw_sleep_wq);
11912 //cancel_work_sync(&priv->SetBWModeWorkItem);
11913 //cancel_work_sync(&priv->SwChnlWorkItem);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -070011914}
11915
Jerry Chuang5f53d8c2009-05-21 22:16:02 -070011916static void __devexit rtl8192_usb_disconnect(struct usb_interface *intf)
Jerry Chuang5f53d8c2009-05-21 22:16:02 -070011917{
Jerry Chuang5f53d8c2009-05-21 22:16:02 -070011918 struct net_device *dev = usb_get_intfdata(intf);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -070011919 struct r8192_priv *priv = ieee80211_priv(dev);
11920 if(dev){
11921
11922 unregister_netdev(dev);
11923
11924 RT_TRACE(COMP_DOWN, "=============>wlan driver to be removed\n");
11925 rtl8192_proc_remove_one(dev);
11926
11927 rtl8192_down(dev);
11928 if (priv->pFirmware)
11929 {
11930 vfree(priv->pFirmware);
11931 priv->pFirmware = NULL;
11932 }
11933 // priv->rf_close(dev);
11934// rtl8192_SetRFPowerState(dev, eRfOff);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -070011935 destroy_workqueue(priv->priv_wq);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -070011936 //rtl8192_irq_disable(dev);
11937 //rtl8192_reset(dev);
11938 mdelay(10);
11939
11940 }
11941 free_ieee80211(dev);
11942 RT_TRACE(COMP_DOWN, "wlan driver removed\n");
11943}
11944
11945static int __init rtl8192_usb_module_init(void)
11946{
11947 printk(KERN_INFO "\nLinux kernel driver for RTL8192 based WLAN cards\n");
11948 printk(KERN_INFO "Copyright (c) 2007-2008, Realsil Wlan\n");
11949 RT_TRACE(COMP_INIT, "Initializing module");
11950 RT_TRACE(COMP_INIT, "Wireless extensions version %d", WIRELESS_EXT);
11951 rtl8192_proc_module_init();
11952 return usb_register(&rtl8192_usb_driver);
11953}
11954
11955
11956static void __exit rtl8192_usb_module_exit(void)
11957{
11958 usb_deregister(&rtl8192_usb_driver);
11959
11960 RT_TRACE(COMP_DOWN, "Exiting");
11961 rtl8192_proc_module_remove();
11962}
11963
11964
11965void rtl8192_try_wake_queue(struct net_device *dev, int pri)
11966{
11967 unsigned long flags;
11968 short enough_desc;
11969 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
11970
11971 spin_lock_irqsave(&priv->tx_lock,flags);
11972 enough_desc = check_nic_enough_desc(dev,pri);
11973 spin_unlock_irqrestore(&priv->tx_lock,flags);
11974
11975 if(enough_desc)
11976 ieee80211_wake_queue(priv->ieee80211);
11977}
11978
11979#if 0
11980void DisableHWSecurityConfig8192SUsb(struct net_device *dev)
11981{
11982 u8 SECR_value = 0x0;
11983 write_nic_byte(dev, SECR, SECR_value);//SECR_value | SCR_UseDK );
11984}
11985#endif
11986
11987void EnableHWSecurityConfig8192(struct net_device *dev)
11988{
11989 u8 SECR_value = 0x0;
11990 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
11991 struct ieee80211_device* ieee = priv->ieee80211;
11992
11993 SECR_value = SCR_TxEncEnable | SCR_RxDecEnable;
11994#if 1
11995 if (((KEY_TYPE_WEP40 == ieee->pairwise_key_type) || (KEY_TYPE_WEP104 == ieee->pairwise_key_type)) && (priv->ieee80211->auth_mode != 2))
11996 {
11997 SECR_value |= SCR_RxUseDK;
11998 SECR_value |= SCR_TxUseDK;
11999 }
12000 else if ((ieee->iw_mode == IW_MODE_ADHOC) && (ieee->pairwise_key_type & (KEY_TYPE_CCMP | KEY_TYPE_TKIP)))
12001 {
12002 SECR_value |= SCR_RxUseDK;
12003 SECR_value |= SCR_TxUseDK;
12004 }
12005#endif
12006 //add HWSec active enable here.
12007//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
12008
12009 ieee->hwsec_active = 1;
12010
12011 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
12012 {
12013 ieee->hwsec_active = 0;
12014 SECR_value &= ~SCR_RxDecEnable;
12015 }
12016
12017 RT_TRACE(COMP_SEC,"%s:, hwsec:%d, pairwise_key:%d, SECR_value:%x\n", __FUNCTION__, \
12018 ieee->hwsec_active, ieee->pairwise_key_type, SECR_value);
12019 {
12020 write_nic_byte(dev, SECR, SECR_value);//SECR_value | SCR_UseDK );
12021 }
12022}
12023
12024
12025void setKey( struct net_device *dev,
12026 u8 EntryNo,
12027 u8 KeyIndex,
12028 u16 KeyType,
12029 u8 *MacAddr,
12030 u8 DefaultKey,
12031 u32 *KeyContent )
12032{
12033 u32 TargetCommand = 0;
12034 u32 TargetContent = 0;
12035 u16 usConfig = 0;
12036 u8 i;
12037 if (EntryNo >= TOTAL_CAM_ENTRY)
12038 RT_TRACE(COMP_ERR, "cam entry exceeds in setKey()\n");
12039
12040 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));
12041
12042 if (DefaultKey)
12043 usConfig |= BIT15 | (KeyType<<2);
12044 else
12045 usConfig |= BIT15 | (KeyType<<2) | KeyIndex;
12046// usConfig |= BIT15 | (KeyType<<2) | (DefaultKey<<5) | KeyIndex;
12047
12048
12049 for(i=0 ; i<CAM_CONTENT_COUNT; i++){
12050 TargetCommand = i+CAM_CONTENT_COUNT*EntryNo;
12051 TargetCommand |= BIT31|BIT16;
12052
12053 if(i==0){//MAC|Config
12054 TargetContent = (u32)(*(MacAddr+0)) << 16|
12055 (u32)(*(MacAddr+1)) << 24|
12056 (u32)usConfig;
12057
12058 write_nic_dword(dev, WCAMI, TargetContent);
12059 write_nic_dword(dev, RWCAM, TargetCommand);
12060 // printk("setkey cam =%8x\n", read_cam(dev, i+6*EntryNo));
12061 }
12062 else if(i==1){//MAC
12063 TargetContent = (u32)(*(MacAddr+2)) |
12064 (u32)(*(MacAddr+3)) << 8|
12065 (u32)(*(MacAddr+4)) << 16|
12066 (u32)(*(MacAddr+5)) << 24;
12067 write_nic_dword(dev, WCAMI, TargetContent);
12068 write_nic_dword(dev, RWCAM, TargetCommand);
12069 }
12070 else {
12071 //Key Material
12072 if(KeyContent !=NULL){
12073 write_nic_dword(dev, WCAMI, (u32)(*(KeyContent+i-2)) );
12074 write_nic_dword(dev, RWCAM, TargetCommand);
12075 }
12076 }
12077 }
12078
12079}
12080
12081/***************************************************************************
12082 ------------------- module init / exit stubs ----------------
12083****************************************************************************/
12084module_init(rtl8192_usb_module_init);
12085module_exit(rtl8192_usb_module_exit);