blob: ea96b1159031df48c138f2e13e3999f60d9d205a [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
Jerry Chuang5f53d8c2009-05-21 22:16:02 -070061#include <asm/uaccess.h>
62#include "r8192U.h"
Jerry Chuang5f53d8c2009-05-21 22:16:02 -070063#include "r8180_93cx6.h" /* Card EEPROM */
64#include "r8192U_wx.h"
65
66#include "r8192S_rtl8225.h"
67#include "r8192S_hw.h"
68#include "r8192S_phy.h"
69#include "r8192S_phyreg.h"
70#include "r8192S_Efuse.h"
71
72#include "r819xU_cmdpkt.h"
73#include "r8192U_dm.h"
74//#include "r8192xU_phyreg.h"
75#include <linux/usb.h>
Jerry Chuang5f53d8c2009-05-21 22:16:02 -070076
Jerry Chuang5f53d8c2009-05-21 22:16:02 -070077#include "r8192U_pm.h"
Jerry Chuang5f53d8c2009-05-21 22:16:02 -070078
Bartlomiej Zolnierkiewicz2a7d71a2009-06-12 18:29:19 +020079#include "ieee80211/dot11d.h"
Jerry Chuang5f53d8c2009-05-21 22:16:02 -070080
Jerry Chuang5f53d8c2009-05-21 22:16:02 -070081
82
Jerry Chuang5f53d8c2009-05-21 22:16:02 -070083u32 rt_global_debug_component = \
84// COMP_TRACE |
85// COMP_DBG |
86// COMP_INIT |
87// COMP_RECV |
88// COMP_SEND |
89// COMP_IO |
90 COMP_POWER |
91// COMP_EPROM |
92 COMP_SWBW |
93 COMP_POWER_TRACKING |
94 COMP_TURBO |
95 COMP_QOS |
96// COMP_RATE |
97// COMP_RM |
98 COMP_DIG |
99// COMP_EFUSE |
100// COMP_CH |
101// COMP_TXAGC |
102 COMP_HIPWR |
103// COMP_HALDM |
104 COMP_SEC |
105 COMP_LED |
106// COMP_RF |
107// COMP_RXDESC |
108 COMP_FIRMWARE |
109 COMP_HT |
110 COMP_AMSDU |
111 COMP_SCAN |
112// COMP_CMD |
113 COMP_DOWN |
114 COMP_RESET |
115 COMP_ERR; //always open err flags on
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700116
117#define TOTAL_CAM_ENTRY 32
118#define CAM_CONTENT_COUNT 8
119
120static struct usb_device_id rtl8192_usb_id_tbl[] = {
121 /* Realtek */
122 {USB_DEVICE(0x0bda, 0x8192)},
123 {USB_DEVICE(0x0bda, 0x8709)},
124 /* Corega */
125 {USB_DEVICE(0x07aa, 0x0043)},
126 /* Belkin */
127 {USB_DEVICE(0x050d, 0x805E)},
128 /* Sitecom */
129 {USB_DEVICE(0x0df6, 0x0031)},
130 /* EnGenius */
131 {USB_DEVICE(0x1740, 0x9201)},
132 /* Dlink */
133 {USB_DEVICE(0x2001, 0x3301)},
134 /* Zinwell */
135 {USB_DEVICE(0x5a57, 0x0290)},
136 //92SU
137 {USB_DEVICE(0x0bda, 0x8172)},
138 {}
139};
140
141MODULE_LICENSE("GPL");
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700142MODULE_VERSION("V 1.1");
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700143MODULE_DEVICE_TABLE(usb, rtl8192_usb_id_tbl);
144MODULE_DESCRIPTION("Linux driver for Realtek RTL8192 USB WiFi cards");
145
146static char* ifname = "wlan%d";
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700147static int hwwep = 1; //default use hw. set 0 to use software security
148static int channels = 0x3fff;
149
150
151
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700152module_param(ifname, charp, S_IRUGO|S_IWUSR );
153//module_param(hwseqnum,int, S_IRUGO|S_IWUSR);
154module_param(hwwep,int, S_IRUGO|S_IWUSR);
155module_param(channels,int, S_IRUGO|S_IWUSR);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700156
157MODULE_PARM_DESC(ifname," Net interface name, wlan%d=default");
158//MODULE_PARM_DESC(hwseqnum," Try to use hardware 802.11 header sequence numbers. Zero=default");
159MODULE_PARM_DESC(hwwep," Try to use hardware security support. ");
160MODULE_PARM_DESC(channels," Channel bitmask for specific locales. NYI");
161
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700162static int __devinit rtl8192_usb_probe(struct usb_interface *intf,
163 const struct usb_device_id *id);
164static void __devexit rtl8192_usb_disconnect(struct usb_interface *intf);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700165
166static struct usb_driver rtl8192_usb_driver = {
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700167 .name = RTL819xU_MODULE_NAME, /* Driver name */
168 .id_table = rtl8192_usb_id_tbl, /* PCI_ID table */
169 .probe = rtl8192_usb_probe, /* probe fn */
170 .disconnect = rtl8192_usb_disconnect, /* remove fn */
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700171 .suspend = rtl8192U_suspend, /* PM suspend fn */
172 .resume = rtl8192U_resume, /* PM resume fn */
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700173 .reset_resume = rtl8192U_resume, /* PM reset resume fn */
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700174};
175
176
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700177static void rtl8192SU_read_eeprom_info(struct net_device *dev);
178short rtl8192SU_tx(struct net_device *dev, struct sk_buff* skb);
179void rtl8192SU_rx_nomal(struct sk_buff* skb);
180void rtl8192SU_rx_cmd(struct sk_buff *skb);
181bool rtl8192SU_adapter_start(struct net_device *dev);
182short rtl8192SU_tx_cmd(struct net_device *dev, struct sk_buff *skb);
183void rtl8192SU_link_change(struct net_device *dev);
184void InitialGain8192S(struct net_device *dev,u8 Operation);
185void rtl8192SU_query_rxdesc_status(struct sk_buff *skb, struct ieee80211_rx_stats *stats, bool bIsRxAggrSubframe);
186
187struct rtl819x_ops rtl8192su_ops = {
188 .nic_type = NIC_8192SU,
189 .rtl819x_read_eeprom_info = rtl8192SU_read_eeprom_info,
190 .rtl819x_tx = rtl8192SU_tx,
191 .rtl819x_tx_cmd = rtl8192SU_tx_cmd,
192 .rtl819x_rx_nomal = rtl8192SU_rx_nomal,
193 .rtl819x_rx_cmd = rtl8192SU_rx_cmd,
194 .rtl819x_adapter_start = rtl8192SU_adapter_start,
195 .rtl819x_link_change = rtl8192SU_link_change,
196 .rtl819x_initial_gain = InitialGain8192S,
197 .rtl819x_query_rxdesc_status = rtl8192SU_query_rxdesc_status,
198};
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700199
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700200
201typedef struct _CHANNEL_LIST
202{
203 u8 Channel[32];
204 u8 Len;
205}CHANNEL_LIST, *PCHANNEL_LIST;
206
207static CHANNEL_LIST ChannelPlan[] = {
208 {{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
209 {{1,2,3,4,5,6,7,8,9,10,11},11}, //IC
210 {{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48,52,56,60,64},21}, //ETSI
211 {{1,2,3,4,5,6,7,8,9,10,11,12,13},13}, //Spain. Change to ETSI.
212 {{1,2,3,4,5,6,7,8,9,10,11,12,13},13}, //France. Change to ETSI.
213 {{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
214 {{1,2,3,4,5,6,7,8,9,10,11,12,13,14,36,40,44,48,52,56,60,64},22},//MKK1
215 {{1,2,3,4,5,6,7,8,9,10,11,12,13},13}, //Israel.
216 {{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
217 {{1,2,3,4,5,6,7,8,9,10,11,12,13,14,36,40,44,48,52,56,60,64}, 22}, //MIC
218 {{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
219};
220
221static void rtl819x_set_channel_map(u8 channel_plan, struct r8192_priv* priv)
222{
223 int i, max_chan=-1, min_chan=-1;
224 struct ieee80211_device* ieee = priv->ieee80211;
225 switch (channel_plan)
226 {
227 case COUNTRY_CODE_FCC:
228 case COUNTRY_CODE_IC:
229 case COUNTRY_CODE_ETSI:
230 case COUNTRY_CODE_SPAIN:
231 case COUNTRY_CODE_FRANCE:
232 case COUNTRY_CODE_MKK:
233 case COUNTRY_CODE_MKK1:
234 case COUNTRY_CODE_ISRAEL:
235 case COUNTRY_CODE_TELEC:
236 case COUNTRY_CODE_MIC:
237 {
238 Dot11d_Init(ieee);
239 ieee->bGlobalDomain = false;
240 //acturally 8225 & 8256 rf chip only support B,G,24N mode
241 if ((priv->rf_chip == RF_8225) || (priv->rf_chip == RF_8256) || (priv->rf_chip == RF_6052))
242 {
243 min_chan = 1;
244 max_chan = 14;
245 }
246 else
247 {
248 RT_TRACE(COMP_ERR, "unknown rf chip, can't set channel map in function:%s()\n", __FUNCTION__);
249 }
250 if (ChannelPlan[channel_plan].Len != 0){
251 // Clear old channel map
252 memset(GET_DOT11D_INFO(ieee)->channel_map, 0, sizeof(GET_DOT11D_INFO(ieee)->channel_map));
253 // Set new channel map
254 for (i=0;i<ChannelPlan[channel_plan].Len;i++)
255 {
256 if (ChannelPlan[channel_plan].Channel[i] < min_chan || ChannelPlan[channel_plan].Channel[i] > max_chan)
257 break;
258 GET_DOT11D_INFO(ieee)->channel_map[ChannelPlan[channel_plan].Channel[i]] = 1;
259 }
260 }
261 break;
262 }
263 case COUNTRY_CODE_GLOBAL_DOMAIN:
264 {
265 GET_DOT11D_INFO(ieee)->bEnabled = 0;//this flag enabled to follow 11d country IE setting, otherwise, it shall follow global domain settings.
266 Dot11d_Reset(ieee);
267 ieee->bGlobalDomain = true;
268 break;
269 }
270 default:
271 break;
272 }
273 return;
274}
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700275
276#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 )
277
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700278#define rx_hal_is_cck_rate(_pDesc)\
279 ((_pDesc->RxMCS == DESC92S_RATE1M ||\
280 _pDesc->RxMCS == DESC92S_RATE2M ||\
281 _pDesc->RxMCS == DESC92S_RATE5_5M ||\
282 _pDesc->RxMCS == DESC92S_RATE11M) &&\
283 !_pDesc->RxHT)
284
285#define tx_hal_is_cck_rate(_DataRate)\
286 ( _DataRate == MGN_1M ||\
287 _DataRate == MGN_2M ||\
288 _DataRate == MGN_5_5M ||\
289 _DataRate == MGN_11M )
290
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700291
292
293
294void CamResetAllEntry(struct net_device *dev)
295{
296#if 1
297 u32 ulcommand = 0;
298 //2004/02/11 In static WEP, OID_ADD_KEY or OID_ADD_WEP are set before STA associate to AP.
299 // However, ResetKey is called on OID_802_11_INFRASTRUCTURE_MODE and MlmeAssociateRequest
300 // In this condition, Cam can not be reset because upper layer will not set this static key again.
301 //if(Adapter->EncAlgorithm == WEP_Encryption)
302 // return;
303//debug
304 //DbgPrint("========================================\n");
305 //DbgPrint(" Call ResetAllEntry \n");
306 //DbgPrint("========================================\n\n");
307 ulcommand |= BIT31|BIT30;
308 write_nic_dword(dev, RWCAM, ulcommand);
309#else
310 for(ucIndex=0;ucIndex<TOTAL_CAM_ENTRY;ucIndex++)
311 CAM_mark_invalid(dev, ucIndex);
312 for(ucIndex=0;ucIndex<TOTAL_CAM_ENTRY;ucIndex++)
313 CAM_empty_entry(dev, ucIndex);
314#endif
315
316}
317
318
319void write_cam(struct net_device *dev, u8 addr, u32 data)
320{
321 write_nic_dword(dev, WCAMI, data);
322 write_nic_dword(dev, RWCAM, BIT31|BIT16|(addr&0xff) );
323}
324
325u32 read_cam(struct net_device *dev, u8 addr)
326{
327 write_nic_dword(dev, RWCAM, 0x80000000|(addr&0xff) );
328 return read_nic_dword(dev, 0xa8);
329}
330
331void write_nic_byte_E(struct net_device *dev, int indx, u8 data)
332{
333 int status;
334 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
335 struct usb_device *udev = priv->udev;
336
337 status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
338 RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
339 indx|0xfe00, 0, &data, 1, HZ / 2);
340
341 if (status < 0)
342 {
343 printk("write_nic_byte_E TimeOut! status:%d\n", status);
344 }
345}
346
347u8 read_nic_byte_E(struct net_device *dev, int indx)
348{
349 int status;
350 u8 data;
351 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
352 struct usb_device *udev = priv->udev;
353
354 status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
355 RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
356 indx|0xfe00, 0, &data, 1, HZ / 2);
357
358 if (status < 0)
359 {
360 printk("read_nic_byte_E TimeOut! status:%d\n", status);
361 }
362
363 return data;
364}
365//as 92U has extend page from 4 to 16, so modify functions below.
366void write_nic_byte(struct net_device *dev, int indx, u8 data)
367{
368 int status;
369
370 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
371 struct usb_device *udev = priv->udev;
372
373 status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
374 RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700375 indx, 0, &data, 1, HZ / 2);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700376
377 if (status < 0)
378 {
379 printk("write_nic_byte TimeOut! status:%d\n", status);
380 }
381
382
383}
384
385
386void write_nic_word(struct net_device *dev, int indx, u16 data)
387{
388
389 int status;
390
391 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
392 struct usb_device *udev = priv->udev;
393
394 status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
395 RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700396 indx, 0, &data, 2, HZ / 2);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700397
398 if (status < 0)
399 {
400 printk("write_nic_word TimeOut! status:%d\n", status);
401 }
402
403}
404
405
406void write_nic_dword(struct net_device *dev, int indx, u32 data)
407{
408
409 int status;
410
411 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
412 struct usb_device *udev = priv->udev;
413
414 status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
415 RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700416 indx, 0, &data, 4, HZ / 2);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700417
418
419 if (status < 0)
420 {
421 printk("write_nic_dword TimeOut! status:%d\n", status);
422 }
423
424}
425
426
427
428u8 read_nic_byte(struct net_device *dev, int indx)
429{
430 u8 data;
431 int status;
432 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
433 struct usb_device *udev = priv->udev;
434
435 status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
436 RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700437 indx, 0, &data, 1, HZ / 2);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700438
439 if (status < 0)
440 {
441 printk("read_nic_byte TimeOut! status:%d\n", status);
442 }
443
444 return data;
445}
446
447
448
449u16 read_nic_word(struct net_device *dev, int indx)
450{
451 u16 data;
452 int status;
453 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
454 struct usb_device *udev = priv->udev;
455
456 status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
457 RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700458 indx, 0, &data, 2, HZ / 2);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700459
460 if (status < 0)
461 {
462 printk("read_nic_word TimeOut! status:%d\n", status);
463 }
464
465
466 return data;
467}
468
469u16 read_nic_word_E(struct net_device *dev, int indx)
470{
471 u16 data;
472 int status;
473 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
474 struct usb_device *udev = priv->udev;
475
476 status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
477 RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
478 indx|0xfe00, 0, &data, 2, HZ / 2);
479
480 if (status < 0)
481 {
482 printk("read_nic_word TimeOut! status:%d\n", status);
483 }
484
485
486 return data;
487}
488
489u32 read_nic_dword(struct net_device *dev, int indx)
490{
491 u32 data;
492 int status;
493// int result;
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_rcvctrlpipe(udev, 0),
499 RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700500 indx, 0, &data, 4, HZ / 2);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700501// if(0 != result) {
502// printk(KERN_WARNING "read size of data = %d\, date = %d\n", result, data);
503// }
504
505 if (status < 0)
506 {
507 printk("read_nic_dword TimeOut! status:%d\n", status);
508 if(status == -ENODEV) {
509 priv->usb_error = true;
510 }
511 }
512
513
514
515 return data;
516}
517
518
519//u8 read_phy_cck(struct net_device *dev, u8 adr);
520//u8 read_phy_ofdm(struct net_device *dev, u8 adr);
521/* this might still called in what was the PHY rtl8185/rtl8192 common code
522 * plans are to possibilty turn it again in one common code...
523 */
524inline void force_pci_posting(struct net_device *dev)
525{
526}
527
528
529static struct net_device_stats *rtl8192_stats(struct net_device *dev);
530void rtl8192_commit(struct net_device *dev);
531//void rtl8192_restart(struct net_device *dev);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700532void rtl8192_restart(struct work_struct *work);
533//void rtl8192_rq_tx_ack(struct work_struct *work);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700534
535void watch_dog_timer_callback(unsigned long data);
536
537/****************************************************************************
538 -----------------------------PROCFS STUFF-------------------------
539*****************************************************************************/
540
541static struct proc_dir_entry *rtl8192_proc = NULL;
542
543
544
545static int proc_get_stats_ap(char *page, char **start,
546 off_t offset, int count,
547 int *eof, void *data)
548{
549 struct net_device *dev = data;
550 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
551 struct ieee80211_device *ieee = priv->ieee80211;
552 struct ieee80211_network *target;
553
554 int len = 0;
555
556 list_for_each_entry(target, &ieee->network_list, list) {
557
558 len += snprintf(page + len, count - len,
559 "%s ", target->ssid);
560
561 if(target->wpa_ie_len>0 || target->rsn_ie_len>0){
562 len += snprintf(page + len, count - len,
563 "WPA\n");
564 }
565 else{
566 len += snprintf(page + len, count - len,
567 "non_WPA\n");
568 }
569
570 }
571
572 *eof = 1;
573 return len;
574}
575
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700576static int proc_get_registers(char *page, char **start,
577 off_t offset, int count,
578 int *eof, void *data)
579{
580 struct net_device *dev = data;
581// struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
582
583 int len = 0;
584 int i,n,page0,page1,page2;
585
586 int max=0xff;
587 page0 = 0x000;
588 page1 = 0x100;
589 page2 = 0x800;
590
591 /* This dump the current register page */
592 if(!IS_BB_REG_OFFSET_92S(page0)){
593 len += snprintf(page + len, count - len,
594 "\n####################page %x##################\n ", (page0>>8));
595 for(n=0;n<=max;)
596 {
597 len += snprintf(page + len, count - len,
598 "\nD: %2x > ",n);
599 for(i=0;i<16 && n<=max;i++,n++)
600 len += snprintf(page + len, count - len,
601 "%2.2x ",read_nic_byte(dev,(page0|n)));
602 }
603 }else{
604 len += snprintf(page + len, count - len,
605 "\n####################page %x##################\n ", (page0>>8));
606 for(n=0;n<=max;)
607 {
608 len += snprintf(page + len, count - len, "\nD: %2x > ",n);
609 for(i=0;i<4 && n<=max;n+=4,i++)
610 len += snprintf(page + len, count - len,
611 "%8.8x ",rtl8192_QueryBBReg(dev,(page0|n), bMaskDWord));
612 }
613 }
614 len += snprintf(page + len, count - len,"\n");
615 *eof = 1;
616 return len;
617
618}
619static int proc_get_registers_1(char *page, char **start,
620 off_t offset, int count,
621 int *eof, void *data)
622{
623 struct net_device *dev = data;
624// struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
625
626 int len = 0;
627 int i,n,page0;
628
629 int max=0xff;
630 page0 = 0x100;
631
632 /* This dump the current register page */
633 len += snprintf(page + len, count - len,
634 "\n####################page %x##################\n ", (page0>>8));
635 for(n=0;n<=max;)
636 {
637 len += snprintf(page + len, count - len,
638 "\nD: %2x > ",n);
639 for(i=0;i<16 && n<=max;i++,n++)
640 len += snprintf(page + len, count - len,
641 "%2.2x ",read_nic_byte(dev,(page0|n)));
642 }
643 len += snprintf(page + len, count - len,"\n");
644 *eof = 1;
645 return len;
646
647}
648static int proc_get_registers_2(char *page, char **start,
649 off_t offset, int count,
650 int *eof, void *data)
651{
652 struct net_device *dev = data;
653// struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
654
655 int len = 0;
656 int i,n,page0;
657
658 int max=0xff;
659 page0 = 0x200;
660
661 /* This dump the current register page */
662 len += snprintf(page + len, count - len,
663 "\n####################page %x##################\n ", (page0>>8));
664 for(n=0;n<=max;)
665 {
666 len += snprintf(page + len, count - len,
667 "\nD: %2x > ",n);
668 for(i=0;i<16 && n<=max;i++,n++)
669 len += snprintf(page + len, count - len,
670 "%2.2x ",read_nic_byte(dev,(page0|n)));
671 }
672 len += snprintf(page + len, count - len,"\n");
673 *eof = 1;
674 return len;
675
676}
677static int proc_get_registers_8(char *page, char **start,
678 off_t offset, int count,
679 int *eof, void *data)
680{
681 struct net_device *dev = data;
682
683 int len = 0;
684 int i,n,page0;
685
686 int max=0xff;
687 page0 = 0x800;
688
689 /* This dump the current register page */
690 len += snprintf(page + len, count - len,
691 "\n####################page %x##################\n ", (page0>>8));
692 for(n=0;n<=max;)
693 {
694 len += snprintf(page + len, count - len, "\nD: %2x > ",n);
695 for(i=0;i<4 && n<=max;n+=4,i++)
696 len += snprintf(page + len, count - len,
697 "%8.8x ",rtl8192_QueryBBReg(dev,(page0|n), bMaskDWord));
698 }
699 len += snprintf(page + len, count - len,"\n");
700 *eof = 1;
701 return len;
702
703 }
704static int proc_get_registers_9(char *page, char **start,
705 off_t offset, int count,
706 int *eof, void *data)
707{
708 struct net_device *dev = data;
709// struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
710
711 int len = 0;
712 int i,n,page0;
713
714 int max=0xff;
715 page0 = 0x900;
716
717 /* This dump the current register page */
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, "\nD: %2x > ",n);
723 for(i=0;i<4 && n<=max;n+=4,i++)
724 len += snprintf(page + len, count - len,
725 "%8.8x ",rtl8192_QueryBBReg(dev,(page0|n), bMaskDWord));
726 }
727 len += snprintf(page + len, count - len,"\n");
728 *eof = 1;
729 return len;
730}
731static int proc_get_registers_a(char *page, char **start,
732 off_t offset, int count,
733 int *eof, void *data)
734{
735 struct net_device *dev = data;
736// struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
737
738 int len = 0;
739 int i,n,page0;
740
741 int max=0xff;
742 page0 = 0xa00;
743
744 /* This dump the current register page */
745 len += snprintf(page + len, count - len,
746 "\n####################page %x##################\n ", (page0>>8));
747 for(n=0;n<=max;)
748 {
749 len += snprintf(page + len, count - len, "\nD: %2x > ",n);
750 for(i=0;i<4 && n<=max;n+=4,i++)
751 len += snprintf(page + len, count - len,
752 "%8.8x ",rtl8192_QueryBBReg(dev,(page0|n), bMaskDWord));
753 }
754 len += snprintf(page + len, count - len,"\n");
755 *eof = 1;
756 return len;
757}
758static int proc_get_registers_b(char *page, char **start,
759 off_t offset, int count,
760 int *eof, void *data)
761{
762 struct net_device *dev = data;
763// struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
764
765 int len = 0;
766 int i,n,page0;
767
768 int max=0xff;
769 page0 = 0xb00;
770
771 /* This dump the current register page */
772 len += snprintf(page + len, count - len,
773 "\n####################page %x##################\n ", (page0>>8));
774 for(n=0;n<=max;)
775 {
776 len += snprintf(page + len, count - len, "\nD: %2x > ",n);
777 for(i=0;i<4 && n<=max;n+=4,i++)
778 len += snprintf(page + len, count - len,
779 "%8.8x ",rtl8192_QueryBBReg(dev,(page0|n), bMaskDWord));
780 }
781 len += snprintf(page + len, count - len,"\n");
782 *eof = 1;
783 return len;
784 }
785static int proc_get_registers_c(char *page, char **start,
786 off_t offset, int count,
787 int *eof, void *data)
788{
789 struct net_device *dev = data;
790// struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
791
792 int len = 0;
793 int i,n,page0;
794
795 int max=0xff;
796 page0 = 0xc00;
797
798 /* This dump the current register page */
799 len += snprintf(page + len, count - len,
800 "\n####################page %x##################\n ", (page0>>8));
801 for(n=0;n<=max;)
802 {
803 len += snprintf(page + len, count - len, "\nD: %2x > ",n);
804 for(i=0;i<4 && n<=max;n+=4,i++)
805 len += snprintf(page + len, count - len,
806 "%8.8x ",rtl8192_QueryBBReg(dev,(page0|n), bMaskDWord));
807 }
808 len += snprintf(page + len, count - len,"\n");
809 *eof = 1;
810 return len;
811}
812static int proc_get_registers_d(char *page, char **start,
813 off_t offset, int count,
814 int *eof, void *data)
815{
816 struct net_device *dev = data;
817// struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
818
819 int len = 0;
820 int i,n,page0;
821
822 int max=0xff;
823 page0 = 0xd00;
824
825 /* This dump the current register page */
826 len += snprintf(page + len, count - len,
827 "\n####################page %x##################\n ", (page0>>8));
828 for(n=0;n<=max;)
829 {
830 len += snprintf(page + len, count - len, "\nD: %2x > ",n);
831 for(i=0;i<4 && n<=max;n+=4,i++)
832 len += snprintf(page + len, count - len,
833 "%8.8x ",rtl8192_QueryBBReg(dev,(page0|n), bMaskDWord));
834 }
835 len += snprintf(page + len, count - len,"\n");
836 *eof = 1;
837 return len;
838}
839static int proc_get_registers_e(char *page, char **start,
840 off_t offset, int count,
841 int *eof, void *data)
842{
843 struct net_device *dev = data;
844// struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
845
846 int len = 0;
847 int i,n,page0;
848
849 int max=0xff;
850 page0 = 0xe00;
851
852 /* This dump the current register page */
853 len += snprintf(page + len, count - len,
854 "\n####################page %x##################\n ", (page0>>8));
855 for(n=0;n<=max;)
856 {
857 len += snprintf(page + len, count - len, "\nD: %2x > ",n);
858 for(i=0;i<4 && n<=max;n+=4,i++)
859 len += snprintf(page + len, count - len,
860 "%8.8x ",rtl8192_QueryBBReg(dev,(page0|n), bMaskDWord));
861 }
862 len += snprintf(page + len, count - len,"\n");
863 *eof = 1;
864 return len;
865}
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700866
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700867static int proc_get_stats_tx(char *page, char **start,
868 off_t offset, int count,
869 int *eof, void *data)
870{
871 struct net_device *dev = data;
872 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
873
874 int len = 0;
875
876 len += snprintf(page + len, count - len,
877 "TX VI priority ok int: %lu\n"
878 "TX VI priority error int: %lu\n"
879 "TX VO priority ok int: %lu\n"
880 "TX VO priority error int: %lu\n"
881 "TX BE priority ok int: %lu\n"
882 "TX BE priority error int: %lu\n"
883 "TX BK priority ok int: %lu\n"
884 "TX BK priority error int: %lu\n"
885 "TX MANAGE priority ok int: %lu\n"
886 "TX MANAGE priority error int: %lu\n"
887 "TX BEACON priority ok int: %lu\n"
888 "TX BEACON priority error int: %lu\n"
889// "TX high priority ok int: %lu\n"
890// "TX high priority failed error int: %lu\n"
891 "TX queue resume: %lu\n"
892 "TX queue stopped?: %d\n"
893 "TX fifo overflow: %lu\n"
894// "TX beacon: %lu\n"
895 "TX VI queue: %d\n"
896 "TX VO queue: %d\n"
897 "TX BE queue: %d\n"
898 "TX BK queue: %d\n"
899// "TX HW queue: %d\n"
900 "TX VI dropped: %lu\n"
901 "TX VO dropped: %lu\n"
902 "TX BE dropped: %lu\n"
903 "TX BK dropped: %lu\n"
904 "TX total data packets %lu\n",
905// "TX beacon aborted: %lu\n",
906 priv->stats.txviokint,
907 priv->stats.txvierr,
908 priv->stats.txvookint,
909 priv->stats.txvoerr,
910 priv->stats.txbeokint,
911 priv->stats.txbeerr,
912 priv->stats.txbkokint,
913 priv->stats.txbkerr,
914 priv->stats.txmanageokint,
915 priv->stats.txmanageerr,
916 priv->stats.txbeaconokint,
917 priv->stats.txbeaconerr,
918// priv->stats.txhpokint,
919// priv->stats.txhperr,
920 priv->stats.txresumed,
921 netif_queue_stopped(dev),
922 priv->stats.txoverflow,
923// priv->stats.txbeacon,
924 atomic_read(&(priv->tx_pending[VI_PRIORITY])),
925 atomic_read(&(priv->tx_pending[VO_PRIORITY])),
926 atomic_read(&(priv->tx_pending[BE_PRIORITY])),
927 atomic_read(&(priv->tx_pending[BK_PRIORITY])),
928// read_nic_byte(dev, TXFIFOCOUNT),
929 priv->stats.txvidrop,
930 priv->stats.txvodrop,
931 priv->stats.txbedrop,
932 priv->stats.txbkdrop,
933 priv->stats.txdatapkt
934// priv->stats.txbeaconerr
935 );
936
937 *eof = 1;
938 return len;
939}
940
941
942
943static int proc_get_stats_rx(char *page, char **start,
944 off_t offset, int count,
945 int *eof, void *data)
946{
947 struct net_device *dev = data;
948 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
949
950 int len = 0;
951
952 len += snprintf(page + len, count - len,
953 "RX packets: %lu\n"
954 "RX urb status error: %lu\n"
955 "RX invalid urb error: %lu\n",
956 priv->stats.rxoktotal,
957 priv->stats.rxstaterr,
958 priv->stats.rxurberr);
959
960 *eof = 1;
961 return len;
962}
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700963
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700964void rtl8192_proc_module_init(void)
965{
966 RT_TRACE(COMP_INIT, "Initializing proc filesystem");
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700967 rtl8192_proc=create_proc_entry(RTL819xU_MODULE_NAME, S_IFDIR, init_net.proc_net);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700968}
969
970
971void rtl8192_proc_module_remove(void)
972{
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700973 remove_proc_entry(RTL819xU_MODULE_NAME, init_net.proc_net);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700974}
975
976
977void rtl8192_proc_remove_one(struct net_device *dev)
978{
979 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
980
981
982 if (priv->dir_dev) {
983 // remove_proc_entry("stats-hw", priv->dir_dev);
984 remove_proc_entry("stats-tx", priv->dir_dev);
985 remove_proc_entry("stats-rx", priv->dir_dev);
986 // remove_proc_entry("stats-ieee", priv->dir_dev);
987 remove_proc_entry("stats-ap", priv->dir_dev);
988 remove_proc_entry("registers", priv->dir_dev);
989 remove_proc_entry("registers-1", priv->dir_dev);
990 remove_proc_entry("registers-2", priv->dir_dev);
991 remove_proc_entry("registers-8", priv->dir_dev);
992 remove_proc_entry("registers-9", priv->dir_dev);
993 remove_proc_entry("registers-a", priv->dir_dev);
994 remove_proc_entry("registers-b", priv->dir_dev);
995 remove_proc_entry("registers-c", priv->dir_dev);
996 remove_proc_entry("registers-d", priv->dir_dev);
997 remove_proc_entry("registers-e", priv->dir_dev);
998 // remove_proc_entry("cck-registers",priv->dir_dev);
999 // remove_proc_entry("ofdm-registers",priv->dir_dev);
1000 //remove_proc_entry(dev->name, rtl8192_proc);
1001 remove_proc_entry("wlan0", rtl8192_proc);
1002 priv->dir_dev = NULL;
1003 }
1004}
1005
1006
1007void rtl8192_proc_init_one(struct net_device *dev)
1008{
1009 struct proc_dir_entry *e;
1010 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1011 priv->dir_dev = create_proc_entry(dev->name,
1012 S_IFDIR | S_IRUGO | S_IXUGO,
1013 rtl8192_proc);
1014 if (!priv->dir_dev) {
1015 RT_TRACE(COMP_ERR, "Unable to initialize /proc/net/rtl8192/%s\n",
1016 dev->name);
1017 return;
1018 }
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001019 e = create_proc_read_entry("stats-rx", S_IFREG | S_IRUGO,
1020 priv->dir_dev, proc_get_stats_rx, dev);
1021
1022 if (!e) {
1023 RT_TRACE(COMP_ERR,"Unable to initialize "
1024 "/proc/net/rtl8192/%s/stats-rx\n",
1025 dev->name);
1026 }
1027
1028
1029 e = create_proc_read_entry("stats-tx", S_IFREG | S_IRUGO,
1030 priv->dir_dev, proc_get_stats_tx, dev);
1031
1032 if (!e) {
1033 RT_TRACE(COMP_ERR, "Unable to initialize "
1034 "/proc/net/rtl8192/%s/stats-tx\n",
1035 dev->name);
1036 }
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001037
1038 e = create_proc_read_entry("stats-ap", S_IFREG | S_IRUGO,
1039 priv->dir_dev, proc_get_stats_ap, dev);
1040
1041 if (!e) {
1042 RT_TRACE(COMP_ERR, "Unable to initialize "
1043 "/proc/net/rtl8192/%s/stats-ap\n",
1044 dev->name);
1045 }
1046
1047 e = create_proc_read_entry("registers", S_IFREG | S_IRUGO,
1048 priv->dir_dev, proc_get_registers, dev);
1049 if (!e) {
1050 RT_TRACE(COMP_ERR, "Unable to initialize "
1051 "/proc/net/rtl8192/%s/registers\n",
1052 dev->name);
1053 }
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001054 e = create_proc_read_entry("registers-1", S_IFREG | S_IRUGO,
1055 priv->dir_dev, proc_get_registers_1, dev);
1056 if (!e) {
1057 RT_TRACE(COMP_ERR, "Unable to initialize "
1058 "/proc/net/rtl8192/%s/registers-1\n",
1059 dev->name);
1060 }
1061 e = create_proc_read_entry("registers-2", S_IFREG | S_IRUGO,
1062 priv->dir_dev, proc_get_registers_2, dev);
1063 if (!e) {
1064 RT_TRACE(COMP_ERR, "Unable to initialize "
1065 "/proc/net/rtl8192/%s/registers-2\n",
1066 dev->name);
1067 }
1068 e = create_proc_read_entry("registers-8", S_IFREG | S_IRUGO,
1069 priv->dir_dev, proc_get_registers_8, dev);
1070 if (!e) {
1071 RT_TRACE(COMP_ERR, "Unable to initialize "
1072 "/proc/net/rtl8192/%s/registers-8\n",
1073 dev->name);
1074 }
1075 e = create_proc_read_entry("registers-9", S_IFREG | S_IRUGO,
1076 priv->dir_dev, proc_get_registers_9, dev);
1077 if (!e) {
1078 RT_TRACE(COMP_ERR, "Unable to initialize "
1079 "/proc/net/rtl8192/%s/registers-9\n",
1080 dev->name);
1081 }
1082 e = create_proc_read_entry("registers-a", S_IFREG | S_IRUGO,
1083 priv->dir_dev, proc_get_registers_a, dev);
1084 if (!e) {
1085 RT_TRACE(COMP_ERR, "Unable to initialize "
1086 "/proc/net/rtl8192/%s/registers-a\n",
1087 dev->name);
1088 }
1089 e = create_proc_read_entry("registers-b", S_IFREG | S_IRUGO,
1090 priv->dir_dev, proc_get_registers_b, dev);
1091 if (!e) {
1092 RT_TRACE(COMP_ERR, "Unable to initialize "
1093 "/proc/net/rtl8192/%s/registers-b\n",
1094 dev->name);
1095 }
1096 e = create_proc_read_entry("registers-c", S_IFREG | S_IRUGO,
1097 priv->dir_dev, proc_get_registers_c, dev);
1098 if (!e) {
1099 RT_TRACE(COMP_ERR, "Unable to initialize "
1100 "/proc/net/rtl8192/%s/registers-c\n",
1101 dev->name);
1102 }
1103 e = create_proc_read_entry("registers-d", S_IFREG | S_IRUGO,
1104 priv->dir_dev, proc_get_registers_d, dev);
1105 if (!e) {
1106 RT_TRACE(COMP_ERR, "Unable to initialize "
1107 "/proc/net/rtl8192/%s/registers-d\n",
1108 dev->name);
1109 }
1110 e = create_proc_read_entry("registers-e", S_IFREG | S_IRUGO,
1111 priv->dir_dev, proc_get_registers_e, dev);
1112 if (!e) {
1113 RT_TRACE(COMP_ERR, "Unable to initialize "
1114 "/proc/net/rtl8192/%s/registers-e\n",
1115 dev->name);
1116 }
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001117}
1118/****************************************************************************
1119 -----------------------------MISC STUFF-------------------------
1120*****************************************************************************/
1121
1122/* this is only for debugging */
1123void print_buffer(u32 *buffer, int len)
1124{
1125 int i;
1126 u8 *buf =(u8*)buffer;
1127
1128 printk("ASCII BUFFER DUMP (len: %x):\n",len);
1129
1130 for(i=0;i<len;i++)
1131 printk("%c",buf[i]);
1132
1133 printk("\nBINARY BUFFER DUMP (len: %x):\n",len);
1134
1135 for(i=0;i<len;i++)
1136 printk("%x",buf[i]);
1137
1138 printk("\n");
1139}
1140
1141//short check_nic_enough_desc(struct net_device *dev, priority_t priority)
1142short check_nic_enough_desc(struct net_device *dev,int queue_index)
1143{
1144 struct r8192_priv *priv = ieee80211_priv(dev);
1145 int used = atomic_read(&priv->tx_pending[queue_index]);
1146
1147 return (used < MAX_TX_URB);
1148}
1149
1150void tx_timeout(struct net_device *dev)
1151{
1152 struct r8192_priv *priv = ieee80211_priv(dev);
1153 //rtl8192_commit(dev);
1154
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001155 schedule_work(&priv->reset_wq);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001156 //DMESG("TXTIMEOUT");
1157}
1158
1159
1160/* this is only for debug */
1161void dump_eprom(struct net_device *dev)
1162{
1163 int i;
1164 for(i=0; i<63; i++)
1165 RT_TRACE(COMP_EPROM, "EEPROM addr %x : %x", i, eprom_read(dev,i));
1166}
1167
1168/* this is only for debug */
1169void rtl8192_dump_reg(struct net_device *dev)
1170{
1171 int i;
1172 int n;
1173 int max=0x1ff;
1174
1175 RT_TRACE(COMP_PHY, "Dumping NIC register map");
1176
1177 for(n=0;n<=max;)
1178 {
1179 printk( "\nD: %2x> ", n);
1180 for(i=0;i<16 && n<=max;i++,n++)
1181 printk("%2x ",read_nic_byte(dev,n));
1182 }
1183 printk("\n");
1184}
1185
1186/****************************************************************************
1187 ------------------------------HW STUFF---------------------------
1188*****************************************************************************/
1189
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001190void rtl8192_set_mode(struct net_device *dev,int mode)
1191{
1192 u8 ecmd;
1193 ecmd=read_nic_byte(dev, EPROM_CMD);
1194 ecmd=ecmd &~ EPROM_CMD_OPERATING_MODE_MASK;
1195 ecmd=ecmd | (mode<<EPROM_CMD_OPERATING_MODE_SHIFT);
1196 ecmd=ecmd &~ (1<<EPROM_CS_SHIFT);
1197 ecmd=ecmd &~ (1<<EPROM_CK_SHIFT);
1198 write_nic_byte(dev, EPROM_CMD, ecmd);
1199}
1200
1201
1202void rtl8192_update_msr(struct net_device *dev)
1203{
1204 struct r8192_priv *priv = ieee80211_priv(dev);
1205 u8 msr;
1206
1207 msr = read_nic_byte(dev, MSR);
1208 msr &= ~ MSR_LINK_MASK;
1209
1210 /* do not change in link_state != WLAN_LINK_ASSOCIATED.
1211 * msr must be updated if the state is ASSOCIATING.
1212 * this is intentional and make sense for ad-hoc and
1213 * master (see the create BSS/IBSS func)
1214 */
1215 if (priv->ieee80211->state == IEEE80211_LINKED){
1216
1217 if (priv->ieee80211->iw_mode == IW_MODE_INFRA)
1218 msr |= (MSR_LINK_MANAGED<<MSR_LINK_SHIFT);
1219 else if (priv->ieee80211->iw_mode == IW_MODE_ADHOC)
1220 msr |= (MSR_LINK_ADHOC<<MSR_LINK_SHIFT);
1221 else if (priv->ieee80211->iw_mode == IW_MODE_MASTER)
1222 msr |= (MSR_LINK_MASTER<<MSR_LINK_SHIFT);
1223
1224 }else
1225 msr |= (MSR_LINK_NONE<<MSR_LINK_SHIFT);
1226
1227 write_nic_byte(dev, MSR, msr);
1228}
1229
1230void rtl8192_set_chan(struct net_device *dev,short ch)
1231{
1232 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1233// u32 tx;
1234 RT_TRACE(COMP_CH, "=====>%s()====ch:%d\n", __FUNCTION__, ch);
1235 //printk("=====>%s()====ch:%d\n", __FUNCTION__, ch);
1236 priv->chan=ch;
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001237
1238 /* this hack should avoid frame TX during channel setting*/
1239
1240
1241// tx = read_nic_dword(dev,TX_CONF);
1242// tx &= ~TX_LOOPBACK_MASK;
1243
1244#ifndef LOOP_TEST
1245// write_nic_dword(dev,TX_CONF, tx |( TX_LOOPBACK_MAC<<TX_LOOPBACK_SHIFT));
1246
1247 //need to implement rf set channel here WB
1248
1249 if (priv->rf_set_chan)
1250 priv->rf_set_chan(dev,priv->chan);
1251 mdelay(10);
1252// write_nic_dword(dev,TX_CONF,tx | (TX_LOOPBACK_NONE<<TX_LOOPBACK_SHIFT));
1253#endif
1254}
1255
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001256static void rtl8192_rx_isr(struct urb *urb);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001257
1258u32 get_rxpacket_shiftbytes_819xusb(struct ieee80211_rx_stats *pstats)
1259{
1260
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001261 return (sizeof(rx_desc_819x_usb) + pstats->RxDrvInfoSize
1262 + pstats->RxBufShift);
1263
1264}
1265static int rtl8192_rx_initiate(struct net_device*dev)
1266{
1267 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1268 struct urb *entry;
1269 struct sk_buff *skb;
1270 struct rtl8192_rx_info *info;
1271
1272 /* nomal packet rx procedure */
1273 while (skb_queue_len(&priv->rx_queue) < MAX_RX_URB) {
1274 skb = __dev_alloc_skb(RX_URB_SIZE, GFP_KERNEL);
1275 if (!skb)
1276 break;
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001277 entry = usb_alloc_urb(0, GFP_KERNEL);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001278 if (!entry) {
1279 kfree_skb(skb);
1280 break;
1281 }
1282// printk("nomal packet IN request!\n");
1283 usb_fill_bulk_urb(entry, priv->udev,
1284 usb_rcvbulkpipe(priv->udev, 3), skb->tail,
1285 RX_URB_SIZE, rtl8192_rx_isr, skb);
1286 info = (struct rtl8192_rx_info *) skb->cb;
1287 info->urb = entry;
1288 info->dev = dev;
1289 info->out_pipe = 3; //denote rx normal packet queue
1290 skb_queue_tail(&priv->rx_queue, skb);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001291 usb_submit_urb(entry, GFP_KERNEL);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001292 }
1293
1294 /* command packet rx procedure */
1295 while (skb_queue_len(&priv->rx_queue) < MAX_RX_URB + 3) {
1296// printk("command packet IN request!\n");
1297 skb = __dev_alloc_skb(RX_URB_SIZE ,GFP_KERNEL);
1298 if (!skb)
1299 break;
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001300 entry = usb_alloc_urb(0, GFP_KERNEL);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001301 if (!entry) {
1302 kfree_skb(skb);
1303 break;
1304 }
1305 usb_fill_bulk_urb(entry, priv->udev,
1306 usb_rcvbulkpipe(priv->udev, 9), skb->tail,
1307 RX_URB_SIZE, rtl8192_rx_isr, skb);
1308 info = (struct rtl8192_rx_info *) skb->cb;
1309 info->urb = entry;
1310 info->dev = dev;
1311 info->out_pipe = 9; //denote rx cmd packet queue
1312 skb_queue_tail(&priv->rx_queue, skb);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001313 usb_submit_urb(entry, GFP_KERNEL);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001314 }
1315
1316 return 0;
1317}
1318
1319void rtl8192_set_rxconf(struct net_device *dev)
1320{
1321 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1322 u32 rxconf;
1323
1324 rxconf=read_nic_dword(dev,RCR);
1325 rxconf = rxconf &~ MAC_FILTER_MASK;
1326 rxconf = rxconf | RCR_AMF;
1327 rxconf = rxconf | RCR_ADF;
1328 rxconf = rxconf | RCR_AB;
1329 rxconf = rxconf | RCR_AM;
1330 //rxconf = rxconf | RCR_ACF;
1331
1332 if (dev->flags & IFF_PROMISC) {DMESG ("NIC in promisc mode");}
1333
1334 if(priv->ieee80211->iw_mode == IW_MODE_MONITOR || \
1335 dev->flags & IFF_PROMISC){
1336 rxconf = rxconf | RCR_AAP;
1337 } /*else if(priv->ieee80211->iw_mode == IW_MODE_MASTER){
1338 rxconf = rxconf | (1<<ACCEPT_ALLMAC_FRAME_SHIFT);
1339 rxconf = rxconf | (1<<RX_CHECK_BSSID_SHIFT);
1340 }*/else{
1341 rxconf = rxconf | RCR_APM;
1342 rxconf = rxconf | RCR_CBSSID;
1343 }
1344
1345
1346 if(priv->ieee80211->iw_mode == IW_MODE_MONITOR){
1347 rxconf = rxconf | RCR_AICV;
1348 rxconf = rxconf | RCR_APWRMGT;
1349 }
1350
1351 if( priv->crcmon == 1 && priv->ieee80211->iw_mode == IW_MODE_MONITOR)
1352 rxconf = rxconf | RCR_ACRC32;
1353
1354
1355 rxconf = rxconf &~ RX_FIFO_THRESHOLD_MASK;
1356 rxconf = rxconf | (RX_FIFO_THRESHOLD_NONE<<RX_FIFO_THRESHOLD_SHIFT);
1357 rxconf = rxconf &~ MAX_RX_DMA_MASK;
1358 rxconf = rxconf | ((u32)7<<RCR_MXDMA_OFFSET);
1359
1360// rxconf = rxconf | (1<<RX_AUTORESETPHY_SHIFT);
1361 rxconf = rxconf | RCR_ONLYERLPKT;
1362
1363// rxconf = rxconf &~ RCR_CS_MASK;
1364// rxconf = rxconf | (1<<RCR_CS_SHIFT);
1365
1366 write_nic_dword(dev, RCR, rxconf);
1367
1368 #ifdef DEBUG_RX
1369 DMESG("rxconf: %x %x",rxconf ,read_nic_dword(dev,RCR));
1370 #endif
1371}
1372//wait to be removed
1373void rtl8192_rx_enable(struct net_device *dev)
1374{
1375 //u8 cmd;
1376
1377 //struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1378
1379 rtl8192_rx_initiate(dev);
1380
1381// rtl8192_set_rxconf(dev);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001382}
1383
1384
1385void rtl8192_tx_enable(struct net_device *dev)
1386{
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001387}
1388
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001389void rtl8192_rtx_disable(struct net_device *dev)
1390{
1391 u8 cmd;
1392 struct r8192_priv *priv = ieee80211_priv(dev);
1393 struct sk_buff *skb;
1394 struct rtl8192_rx_info *info;
1395
1396 cmd=read_nic_byte(dev,CMDR);
1397 write_nic_byte(dev, CMDR, cmd &~ \
1398 (CR_TE|CR_RE));
1399 force_pci_posting(dev);
1400 mdelay(10);
1401
1402 while ((skb = __skb_dequeue(&priv->rx_queue))) {
1403 info = (struct rtl8192_rx_info *) skb->cb;
1404 if (!info->urb)
1405 continue;
1406
1407 usb_kill_urb(info->urb);
1408 kfree_skb(skb);
1409 }
1410
1411 if (skb_queue_len(&priv->skb_queue)) {
1412 printk(KERN_WARNING "skb_queue not empty\n");
1413 }
1414
1415 skb_queue_purge(&priv->skb_queue);
1416 return;
1417}
1418
1419
1420int alloc_tx_beacon_desc_ring(struct net_device *dev, int count)
1421{
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001422 return 0;
1423}
1424
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001425inline u16 ieeerate2rtlrate(int rate)
1426{
1427 switch(rate){
1428 case 10:
1429 return 0;
1430 case 20:
1431 return 1;
1432 case 55:
1433 return 2;
1434 case 110:
1435 return 3;
1436 case 60:
1437 return 4;
1438 case 90:
1439 return 5;
1440 case 120:
1441 return 6;
1442 case 180:
1443 return 7;
1444 case 240:
1445 return 8;
1446 case 360:
1447 return 9;
1448 case 480:
1449 return 10;
1450 case 540:
1451 return 11;
1452 default:
1453 return 3;
1454
1455 }
1456}
1457static u16 rtl_rate[] = {10,20,55,110,60,90,120,180,240,360,480,540};
1458inline u16 rtl8192_rate2rate(short rate)
1459{
1460 if (rate >11) return 0;
1461 return rtl_rate[rate];
1462}
1463
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001464static void rtl8192_rx_isr(struct urb *urb)
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001465{
1466 struct sk_buff *skb = (struct sk_buff *) urb->context;
1467 struct rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
1468 struct net_device *dev = info->dev;
1469 struct r8192_priv *priv = ieee80211_priv(dev);
1470 int out_pipe = info->out_pipe;
1471 int err;
1472 if(!priv->up)
1473 return;
1474 if (unlikely(urb->status)) {
1475 info->urb = NULL;
1476 priv->stats.rxstaterr++;
1477 priv->ieee80211->stats.rx_errors++;
1478 usb_free_urb(urb);
1479 // printk("%s():rx status err\n",__FUNCTION__);
1480 return;
1481 }
Bartlomiej Zolnierkiewicz1ec9e482009-06-13 18:35:04 +02001482
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001483 skb_unlink(skb, &priv->rx_queue);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001484 skb_put(skb, urb->actual_length);
1485
1486 skb_queue_tail(&priv->skb_queue, skb);
1487 tasklet_schedule(&priv->irq_rx_tasklet);
1488
1489 skb = dev_alloc_skb(RX_URB_SIZE);
1490 if (unlikely(!skb)) {
1491 usb_free_urb(urb);
1492 printk("%s():can,t alloc skb\n",__FUNCTION__);
1493 /* TODO check rx queue length and refill *somewhere* */
1494 return;
1495 }
1496
1497 usb_fill_bulk_urb(urb, priv->udev,
1498 usb_rcvbulkpipe(priv->udev, out_pipe), skb->tail,
1499 RX_URB_SIZE, rtl8192_rx_isr, skb);
1500
1501 info = (struct rtl8192_rx_info *) skb->cb;
1502 info->urb = urb;
1503 info->dev = dev;
1504 info->out_pipe = out_pipe;
1505
1506 urb->transfer_buffer = skb->tail;
1507 urb->context = skb;
1508 skb_queue_tail(&priv->rx_queue, skb);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001509 err = usb_submit_urb(urb, GFP_ATOMIC);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001510 if(err && err != EPERM)
1511 printk("can not submit rxurb, err is %x,URB status is %x\n",err,urb->status);
1512}
1513
1514u32
1515rtl819xusb_rx_command_packet(
1516 struct net_device *dev,
1517 struct ieee80211_rx_stats *pstats
1518 )
1519{
1520 u32 status;
1521
1522 //RT_TRACE(COMP_RECV, DBG_TRACE, ("---> RxCommandPacketHandle819xUsb()\n"));
1523
1524 status = cmpk_message_handle_rx(dev, pstats);
1525 if (status)
1526 {
1527 DMESG("rxcommandpackethandle819xusb: It is a command packet\n");
1528 }
1529 else
1530 {
1531 //RT_TRACE(COMP_RECV, DBG_TRACE, ("RxCommandPacketHandle819xUsb: It is not a command packet\n"));
1532 }
1533
1534 //RT_TRACE(COMP_RECV, DBG_TRACE, ("<--- RxCommandPacketHandle819xUsb()\n"));
1535 return status;
1536}
1537
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001538void rtl8192_data_hard_stop(struct net_device *dev)
1539{
1540 //FIXME !!
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001541}
1542
1543
1544void rtl8192_data_hard_resume(struct net_device *dev)
1545{
1546 // FIXME !!
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001547}
1548
1549/* this function TX data frames when the ieee80211 stack requires this.
1550 * It checks also if we need to stop the ieee tx queue, eventually do it
1551 */
1552void rtl8192_hard_data_xmit(struct sk_buff *skb, struct net_device *dev, int rate)
1553{
1554 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1555 int ret;
1556 unsigned long flags;
1557 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1558 u8 queue_index = tcb_desc->queue_index;
1559
1560 /* shall not be referred by command packet */
1561 assert(queue_index != TXCMD_QUEUE);
1562
1563 spin_lock_irqsave(&priv->tx_lock,flags);
1564
1565 memcpy((unsigned char *)(skb->cb),&dev,sizeof(dev));
1566// tcb_desc->RATRIndex = 7;
1567// tcb_desc->bTxDisableRateFallBack = 1;
1568// tcb_desc->bTxUseDriverAssingedRate = 1;
1569 tcb_desc->bTxEnableFwCalcDur = 1;
1570 skb_push(skb, priv->ieee80211->tx_headroom);
1571 ret = priv->ops->rtl819x_tx(dev, skb);
1572
1573 //priv->ieee80211->stats.tx_bytes+=(skb->len - priv->ieee80211->tx_headroom);
1574 //priv->ieee80211->stats.tx_packets++;
1575
1576 spin_unlock_irqrestore(&priv->tx_lock,flags);
1577
1578// return ret;
1579 return;
1580}
1581
1582/* This is a rough attempt to TX a frame
1583 * This is called by the ieee 80211 stack to TX management frames.
1584 * If the ring is full packet are dropped (for data frame the queue
1585 * is stopped before this can happen).
1586 */
1587int rtl8192_hard_start_xmit(struct sk_buff *skb,struct net_device *dev)
1588{
1589 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1590 int ret;
1591 unsigned long flags;
1592 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1593 u8 queue_index = tcb_desc->queue_index;
1594
1595
1596 spin_lock_irqsave(&priv->tx_lock,flags);
1597
1598 memcpy((unsigned char *)(skb->cb),&dev,sizeof(dev));
1599 if(queue_index == TXCMD_QUEUE) {
1600 skb_push(skb, USB_HWDESC_HEADER_LEN);
1601 priv->ops->rtl819x_tx_cmd(dev, skb);
1602 ret = 1;
1603 spin_unlock_irqrestore(&priv->tx_lock,flags);
1604 return ret;
1605 } else {
1606 skb_push(skb, priv->ieee80211->tx_headroom);
1607 ret = priv->ops->rtl819x_tx(dev, skb);
1608 }
1609
1610 spin_unlock_irqrestore(&priv->tx_lock,flags);
1611
1612 return ret;
1613}
1614
1615
1616void rtl8192_try_wake_queue(struct net_device *dev, int pri);
1617
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001618
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001619static void rtl8192_tx_isr(struct urb *tx_urb)
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001620{
1621 struct sk_buff *skb = (struct sk_buff*)tx_urb->context;
1622 struct net_device *dev = NULL;
1623 struct r8192_priv *priv = NULL;
1624 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1625 u8 queue_index = tcb_desc->queue_index;
1626// bool bToSend0Byte;
1627// u16 BufLen = skb->len;
1628
1629 memcpy(&dev,(struct net_device*)(skb->cb),sizeof(struct net_device*));
1630 priv = ieee80211_priv(dev);
1631
1632 if(tcb_desc->queue_index != TXCMD_QUEUE) {
1633 if(tx_urb->status == 0) {
1634 // dev->trans_start = jiffies;
1635 // As act as station mode, destion shall be unicast address.
1636 //priv->ieee80211->stats.tx_bytes+=(skb->len - priv->ieee80211->tx_headroom);
1637 //priv->ieee80211->stats.tx_packets++;
1638 priv->stats.txoktotal++;
1639 priv->ieee80211->LinkDetectInfo.NumTxOkInPeriod++;
1640 priv->stats.txbytesunicast += (skb->len - priv->ieee80211->tx_headroom);
1641 } else {
1642 priv->ieee80211->stats.tx_errors++;
1643 //priv->stats.txmanageerr++;
1644 /* TODO */
1645 }
1646 }
1647
1648 /* free skb and tx_urb */
1649 if(skb != NULL) {
1650 dev_kfree_skb_any(skb);
1651 usb_free_urb(tx_urb);
1652 atomic_dec(&priv->tx_pending[queue_index]);
1653 }
1654
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001655 {
1656 //
1657 // Handle HW Beacon:
1658 // We had transfer our beacon frame to host controler at this moment.
1659 //
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001660 //
1661 // Caution:
1662 // Handling the wait queue of command packets.
1663 // For Tx command packets, we must not do TCB fragment because it is not handled right now.
1664 // We must cut the packets to match the size of TX_CMD_PKT before we send it.
1665 //
1666 if (queue_index == MGNT_QUEUE){
1667 if (priv->ieee80211->ack_tx_to_ieee){
1668 if (rtl8192_is_tx_queue_empty(dev)){
1669 priv->ieee80211->ack_tx_to_ieee = 0;
1670 ieee80211_ps_tx_ack(priv->ieee80211, 1);
1671 }
1672 }
1673 }
1674 /* Handle MPDU in wait queue. */
1675 if(queue_index != BEACON_QUEUE) {
1676 /* Don't send data frame during scanning.*/
1677 if((skb_queue_len(&priv->ieee80211->skb_waitQ[queue_index]) != 0)&&\
1678 (!(priv->ieee80211->queue_stop))) {
1679 if(NULL != (skb = skb_dequeue(&(priv->ieee80211->skb_waitQ[queue_index]))))
1680 priv->ieee80211->softmac_hard_start_xmit(skb, dev);
1681
1682 return; //modified by david to avoid further processing AMSDU
1683 }
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001684 }
1685 }
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001686}
1687
1688void rtl8192_beacon_stop(struct net_device *dev)
1689{
1690 u8 msr, msrm, msr2;
1691 struct r8192_priv *priv = ieee80211_priv(dev);
1692
1693 msr = read_nic_byte(dev, MSR);
1694 msrm = msr & MSR_LINK_MASK;
1695 msr2 = msr & ~MSR_LINK_MASK;
1696
1697 if(NIC_8192U == priv->card_8192) {
1698 usb_kill_urb(priv->rx_urb[MAX_RX_URB]);
1699 }
1700 if ((msrm == (MSR_LINK_ADHOC<<MSR_LINK_SHIFT) ||
1701 (msrm == (MSR_LINK_MASTER<<MSR_LINK_SHIFT)))){
1702 write_nic_byte(dev, MSR, msr2 | MSR_LINK_NONE);
1703 write_nic_byte(dev, MSR, msr);
1704 }
1705}
1706
1707void rtl8192_config_rate(struct net_device* dev, u16* rate_config)
1708{
1709 struct r8192_priv *priv = ieee80211_priv(dev);
1710 struct ieee80211_network *net;
1711 u8 i=0, basic_rate = 0;
1712 net = & priv->ieee80211->current_network;
1713
1714 for (i=0; i<net->rates_len; i++)
1715 {
1716 basic_rate = net->rates[i]&0x7f;
1717 switch(basic_rate)
1718 {
1719 case MGN_1M: *rate_config |= RRSR_1M; break;
1720 case MGN_2M: *rate_config |= RRSR_2M; break;
1721 case MGN_5_5M: *rate_config |= RRSR_5_5M; break;
1722 case MGN_11M: *rate_config |= RRSR_11M; break;
1723 case MGN_6M: *rate_config |= RRSR_6M; break;
1724 case MGN_9M: *rate_config |= RRSR_9M; break;
1725 case MGN_12M: *rate_config |= RRSR_12M; break;
1726 case MGN_18M: *rate_config |= RRSR_18M; break;
1727 case MGN_24M: *rate_config |= RRSR_24M; break;
1728 case MGN_36M: *rate_config |= RRSR_36M; break;
1729 case MGN_48M: *rate_config |= RRSR_48M; break;
1730 case MGN_54M: *rate_config |= RRSR_54M; break;
1731 }
1732 }
1733 for (i=0; i<net->rates_ex_len; i++)
1734 {
1735 basic_rate = net->rates_ex[i]&0x7f;
1736 switch(basic_rate)
1737 {
1738 case MGN_1M: *rate_config |= RRSR_1M; break;
1739 case MGN_2M: *rate_config |= RRSR_2M; break;
1740 case MGN_5_5M: *rate_config |= RRSR_5_5M; break;
1741 case MGN_11M: *rate_config |= RRSR_11M; break;
1742 case MGN_6M: *rate_config |= RRSR_6M; break;
1743 case MGN_9M: *rate_config |= RRSR_9M; break;
1744 case MGN_12M: *rate_config |= RRSR_12M; break;
1745 case MGN_18M: *rate_config |= RRSR_18M; break;
1746 case MGN_24M: *rate_config |= RRSR_24M; break;
1747 case MGN_36M: *rate_config |= RRSR_36M; break;
1748 case MGN_48M: *rate_config |= RRSR_48M; break;
1749 case MGN_54M: *rate_config |= RRSR_54M; break;
1750 }
1751 }
1752}
1753
1754
1755#define SHORT_SLOT_TIME 9
1756#define NON_SHORT_SLOT_TIME 20
1757
1758void rtl8192_update_cap(struct net_device* dev, u16 cap)
1759{
1760 //u32 tmp = 0;
1761 struct r8192_priv *priv = ieee80211_priv(dev);
1762 struct ieee80211_network *net = &priv->ieee80211->current_network;
1763 priv->short_preamble = cap & WLAN_CAPABILITY_SHORT_PREAMBLE;
1764
1765 //LZM MOD 090303 HW_VAR_ACK_PREAMBLE
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001766 if(0)
1767 {
1768 u8 tmp = 0;
1769 tmp = ((priv->nCur40MhzPrimeSC) << 5);
1770 if (priv->short_preamble)
1771 tmp |= 0x80;
1772 write_nic_byte(dev, RRSR+2, tmp);
1773 }
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001774
1775 if (net->mode & (IEEE_G|IEEE_N_24G))
1776 {
1777 u8 slot_time = 0;
1778 if ((cap & WLAN_CAPABILITY_SHORT_SLOT)&&(!priv->ieee80211->pHTInfo->bCurrentRT2RTLongSlotTime))
1779 {//short slot time
1780 slot_time = SHORT_SLOT_TIME;
1781 }
1782 else //long slot time
1783 slot_time = NON_SHORT_SLOT_TIME;
1784 priv->slot_time = slot_time;
1785 write_nic_byte(dev, SLOT_TIME, slot_time);
1786 }
1787
1788}
1789void rtl8192_net_update(struct net_device *dev)
1790{
1791
1792 struct r8192_priv *priv = ieee80211_priv(dev);
1793 struct ieee80211_network *net;
1794 u16 BcnTimeCfg = 0, BcnCW = 6, BcnIFS = 0xf;
1795 u16 rate_config = 0;
1796 net = & priv->ieee80211->current_network;
1797
1798 rtl8192_config_rate(dev, &rate_config);
1799 priv->basic_rate = rate_config &= 0x15f;
1800
1801 write_nic_dword(dev,BSSIDR,((u32*)net->bssid)[0]);
1802 write_nic_word(dev,BSSIDR+4,((u16*)net->bssid)[2]);
1803 //for(i=0;i<ETH_ALEN;i++)
1804 // write_nic_byte(dev,BSSID+i,net->bssid[i]);
1805
1806 rtl8192_update_msr(dev);
1807// rtl8192_update_cap(dev, net->capability);
1808 if (priv->ieee80211->iw_mode == IW_MODE_ADHOC)
1809 {
1810 write_nic_word(dev, ATIMWND, 2);
1811 write_nic_word(dev, BCN_DMATIME, 1023);
1812 write_nic_word(dev, BCN_INTERVAL, net->beacon_interval);
1813// write_nic_word(dev, BcnIntTime, 100);
1814 write_nic_word(dev, BCN_DRV_EARLY_INT, 1);
1815 write_nic_byte(dev, BCN_ERR_THRESH, 100);
1816 BcnTimeCfg |= (BcnCW<<BCN_TCFG_CW_SHIFT);
1817 // TODO: BcnIFS may required to be changed on ASIC
1818 BcnTimeCfg |= BcnIFS<<BCN_TCFG_IFS;
1819
1820 write_nic_word(dev, BCN_TCFG, BcnTimeCfg);
1821 }
1822
1823
1824
1825}
1826
1827//temporary hw beacon is not used any more.
1828//open it when necessary
1829#if 1
1830void rtl819xusb_beacon_tx(struct net_device *dev,u16 tx_rate)
1831{
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001832}
1833#endif
1834inline u8 rtl8192_IsWirelessBMode(u16 rate)
1835{
1836 if( ((rate <= 110) && (rate != 60) && (rate != 90)) || (rate == 220) )
1837 return 1;
1838 else return 0;
1839}
1840
1841u16 N_DBPSOfRate(u16 DataRate);
1842
1843u16 ComputeTxTime(
1844 u16 FrameLength,
1845 u16 DataRate,
1846 u8 bManagementFrame,
1847 u8 bShortPreamble
1848)
1849{
1850 u16 FrameTime;
1851 u16 N_DBPS;
1852 u16 Ceiling;
1853
1854 if( rtl8192_IsWirelessBMode(DataRate) )
1855 {
1856 if( bManagementFrame || !bShortPreamble || DataRate == 10 )
1857 { // long preamble
1858 FrameTime = (u16)(144+48+(FrameLength*8/(DataRate/10)));
1859 }
1860 else
1861 { // Short preamble
1862 FrameTime = (u16)(72+24+(FrameLength*8/(DataRate/10)));
1863 }
1864 if( ( FrameLength*8 % (DataRate/10) ) != 0 ) //Get the Ceilling
1865 FrameTime ++;
1866 } else { //802.11g DSSS-OFDM PLCP length field calculation.
1867 N_DBPS = N_DBPSOfRate(DataRate);
1868 Ceiling = (16 + 8*FrameLength + 6) / N_DBPS
1869 + (((16 + 8*FrameLength + 6) % N_DBPS) ? 1 : 0);
1870 FrameTime = (u16)(16 + 4 + 4*Ceiling + 6);
1871 }
1872 return FrameTime;
1873}
1874
1875u16 N_DBPSOfRate(u16 DataRate)
1876{
1877 u16 N_DBPS = 24;
1878
1879 switch(DataRate)
1880 {
1881 case 60:
1882 N_DBPS = 24;
1883 break;
1884
1885 case 90:
1886 N_DBPS = 36;
1887 break;
1888
1889 case 120:
1890 N_DBPS = 48;
1891 break;
1892
1893 case 180:
1894 N_DBPS = 72;
1895 break;
1896
1897 case 240:
1898 N_DBPS = 96;
1899 break;
1900
1901 case 360:
1902 N_DBPS = 144;
1903 break;
1904
1905 case 480:
1906 N_DBPS = 192;
1907 break;
1908
1909 case 540:
1910 N_DBPS = 216;
1911 break;
1912
1913 default:
1914 break;
1915 }
1916
1917 return N_DBPS;
1918}
1919
1920void rtl819xU_cmd_isr(struct urb *tx_cmd_urb, struct pt_regs *regs)
1921{
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001922 usb_free_urb(tx_cmd_urb);
1923}
1924
1925unsigned int txqueue2outpipe(struct r8192_priv* priv,unsigned int tx_queue) {
1926
1927 if(tx_queue >= 9)
1928 {
1929 RT_TRACE(COMP_ERR,"%s():Unknown queue ID!!!\n",__FUNCTION__);
1930 return 0x04;
1931 }
1932 return priv->txqueue_to_outpipemap[tx_queue];
1933}
1934
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001935short rtl8192SU_tx_cmd(struct net_device *dev, struct sk_buff *skb)
1936{
1937 struct r8192_priv *priv = ieee80211_priv(dev);
1938 int status;
1939 struct urb *tx_urb;
1940 unsigned int idx_pipe;
1941 tx_desc_cmd_819x_usb *pdesc = (tx_desc_cmd_819x_usb *)skb->data;
1942 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1943 u8 queue_index = tcb_desc->queue_index;
1944 u32 PktSize = 0;
1945
1946 //printk("\n %s::::::::::::::::::::::queue_index = %d\n",__FUNCTION__, queue_index);
1947 atomic_inc(&priv->tx_pending[queue_index]);
1948
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001949 tx_urb = usb_alloc_urb(0,GFP_ATOMIC);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001950 if(!tx_urb){
1951 dev_kfree_skb(skb);
1952 return -ENOMEM;
1953 }
1954
1955 memset(pdesc, 0, USB_HWDESC_HEADER_LEN);
1956
1957 /* Tx descriptor ought to be set according to the skb->cb */
1958 pdesc->LINIP = tcb_desc->bLastIniPkt;
1959 PktSize = (u16)(skb->len - USB_HWDESC_HEADER_LEN);
1960 pdesc->PktSize = PktSize;
1961 //printk("PKTSize = %d %x\n",pdesc->PktSize,pdesc->PktSize);
1962 //----------------------------------------------------------------------------
1963 // Fill up USB_OUT_CONTEXT.
1964 //----------------------------------------------------------------------------
1965 // Get index to out pipe from specified QueueID.
1966 idx_pipe = txqueue2outpipe(priv,queue_index);
1967 //printk("=============>%s queue_index:%d, outpipe:%d\n", __func__,queue_index,priv->RtOutPipes[idx_pipe]);
1968
1969#ifdef JOHN_DUMP_TXDESC
1970 int i;
1971 printk("Len = %d\n", skb->len);
1972 for (i = 0; i < 8; i++)
1973 printk("%2.2x ", *((u8*)skb->data+i));
1974 printk("\n");
1975#endif
1976
1977 usb_fill_bulk_urb(tx_urb,
1978 priv->udev,
1979 usb_sndbulkpipe(priv->udev,priv->RtOutPipes[idx_pipe]),
1980 skb->data,
1981 skb->len,
1982 rtl8192_tx_isr,
1983 skb);
1984
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001985 status = usb_submit_urb(tx_urb, GFP_ATOMIC);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001986 if (!status){
1987 return 0;
1988 }else{
1989 printk("Error TX CMD URB, error %d",
1990 status);
1991 return -1;
1992 }
1993}
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001994
1995/*
1996 * Mapping Software/Hardware descriptor queue id to "Queue Select Field"
1997 * in TxFwInfo data structure
1998 * 2006.10.30 by Emily
1999 *
2000 * \param QUEUEID Software Queue
2001*/
2002u8 MapHwQueueToFirmwareQueue(u8 QueueID)
2003{
2004 u8 QueueSelect = 0x0; //defualt set to
2005
2006 switch(QueueID) {
2007 case BE_QUEUE:
2008 QueueSelect = QSLT_BE; //or QSelect = pTcb->priority;
2009 break;
2010
2011 case BK_QUEUE:
2012 QueueSelect = QSLT_BK; //or QSelect = pTcb->priority;
2013 break;
2014
2015 case VO_QUEUE:
2016 QueueSelect = QSLT_VO; //or QSelect = pTcb->priority;
2017 break;
2018
2019 case VI_QUEUE:
2020 QueueSelect = QSLT_VI; //or QSelect = pTcb->priority;
2021 break;
2022 case MGNT_QUEUE:
2023 QueueSelect = QSLT_MGNT;
2024 break;
2025
2026 case BEACON_QUEUE:
2027 QueueSelect = QSLT_BEACON;
2028 break;
2029
2030 // TODO: 2006.10.30 mark other queue selection until we verify it is OK
2031 // TODO: Remove Assertions
2032//#if (RTL819X_FPGA_VER & RTL819X_FPGA_GUANGAN_070502)
2033 case TXCMD_QUEUE:
2034 QueueSelect = QSLT_CMD;
2035 break;
2036//#endif
2037 case HIGH_QUEUE:
2038 QueueSelect = QSLT_HIGH;
2039 break;
2040
2041 default:
2042 RT_TRACE(COMP_ERR, "TransmitTCB(): Impossible Queue Selection: %d \n", QueueID);
2043 break;
2044 }
2045 return QueueSelect;
2046}
2047
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002048u8 MRateToHwRate8190Pci(u8 rate)
2049{
2050 u8 ret = DESC92S_RATE1M;
2051
2052 switch(rate)
2053 {
2054 // CCK and OFDM non-HT rates
2055 case MGN_1M: ret = DESC92S_RATE1M; break;
2056 case MGN_2M: ret = DESC92S_RATE2M; break;
2057 case MGN_5_5M: ret = DESC92S_RATE5_5M; break;
2058 case MGN_11M: ret = DESC92S_RATE11M; break;
2059 case MGN_6M: ret = DESC92S_RATE6M; break;
2060 case MGN_9M: ret = DESC92S_RATE9M; break;
2061 case MGN_12M: ret = DESC92S_RATE12M; break;
2062 case MGN_18M: ret = DESC92S_RATE18M; break;
2063 case MGN_24M: ret = DESC92S_RATE24M; break;
2064 case MGN_36M: ret = DESC92S_RATE36M; break;
2065 case MGN_48M: ret = DESC92S_RATE48M; break;
2066 case MGN_54M: ret = DESC92S_RATE54M; break;
2067
2068 // HT rates since here
2069 case MGN_MCS0: ret = DESC92S_RATEMCS0; break;
2070 case MGN_MCS1: ret = DESC92S_RATEMCS1; break;
2071 case MGN_MCS2: ret = DESC92S_RATEMCS2; break;
2072 case MGN_MCS3: ret = DESC92S_RATEMCS3; break;
2073 case MGN_MCS4: ret = DESC92S_RATEMCS4; break;
2074 case MGN_MCS5: ret = DESC92S_RATEMCS5; break;
2075 case MGN_MCS6: ret = DESC92S_RATEMCS6; break;
2076 case MGN_MCS7: ret = DESC92S_RATEMCS7; break;
2077 case MGN_MCS8: ret = DESC92S_RATEMCS8; break;
2078 case MGN_MCS9: ret = DESC92S_RATEMCS9; break;
2079 case MGN_MCS10: ret = DESC92S_RATEMCS10; break;
2080 case MGN_MCS11: ret = DESC92S_RATEMCS11; break;
2081 case MGN_MCS12: ret = DESC92S_RATEMCS12; break;
2082 case MGN_MCS13: ret = DESC92S_RATEMCS13; break;
2083 case MGN_MCS14: ret = DESC92S_RATEMCS14; break;
2084 case MGN_MCS15: ret = DESC92S_RATEMCS15; break;
2085
2086 // Set the highest SG rate
2087 case MGN_MCS0_SG:
2088 case MGN_MCS1_SG:
2089 case MGN_MCS2_SG:
2090 case MGN_MCS3_SG:
2091 case MGN_MCS4_SG:
2092 case MGN_MCS5_SG:
2093 case MGN_MCS6_SG:
2094 case MGN_MCS7_SG:
2095 case MGN_MCS8_SG:
2096 case MGN_MCS9_SG:
2097 case MGN_MCS10_SG:
2098 case MGN_MCS11_SG:
2099 case MGN_MCS12_SG:
2100 case MGN_MCS13_SG:
2101 case MGN_MCS14_SG:
2102 case MGN_MCS15_SG:
2103 {
2104 ret = DESC92S_RATEMCS15_SG;
2105 break;
2106 }
2107
2108 default: break;
2109 }
2110 return ret;
2111}
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002112
2113u8 QueryIsShort(u8 TxHT, u8 TxRate, cb_desc *tcb_desc)
2114{
2115 u8 tmp_Short;
2116
2117 tmp_Short = (TxHT==1)?((tcb_desc->bUseShortGI)?1:0):((tcb_desc->bUseShortPreamble)?1:0);
2118
2119 if(TxHT==1 && TxRate != DESC90_RATEMCS15)
2120 tmp_Short = 0;
2121
2122 return tmp_Short;
2123}
2124
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002125static void tx_zero_isr(struct urb *tx_urb)
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002126{
2127 return;
2128}
2129
2130
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002131/*
2132 * The tx procedure is just as following, skb->cb will contain all the following
2133 *information: * priority, morefrag, rate, &dev.
2134 * */
2135 // <Note> Buffer format for 8192S Usb bulk out:
2136//
2137// --------------------------------------------------
2138// | 8192S Usb Tx Desc | 802_11_MAC_header | data |
2139// --------------------------------------------------
2140// | 32 bytes | 24 bytes |0-2318 bytes|
2141// --------------------------------------------------
2142// |<------------ BufferLen ------------------------->|
2143
2144short rtl8192SU_tx(struct net_device *dev, struct sk_buff* skb)
2145{
2146 struct r8192_priv *priv = ieee80211_priv(dev);
2147 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
2148 tx_desc_819x_usb *tx_desc = (tx_desc_819x_usb *)skb->data;
2149 //tx_fwinfo_819x_usb *tx_fwinfo = (tx_fwinfo_819x_usb *)(skb->data + USB_HWDESC_HEADER_LEN);//92su del
2150 struct usb_device *udev = priv->udev;
2151 int pend;
2152 int status;
2153 struct urb *tx_urb = NULL, *tx_urb_zero = NULL;
2154 //int urb_len;
2155 unsigned int idx_pipe;
2156 u16 MPDUOverhead = 0;
2157 //RT_DEBUG_DATA(COMP_SEND, tcb_desc, sizeof(cb_desc));
2158
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002159 pend = atomic_read(&priv->tx_pending[tcb_desc->queue_index]);
2160 /* we are locked here so the two atomic_read and inc are executed
2161 * without interleaves * !!! For debug purpose */
2162 if( pend > MAX_TX_URB){
2163 switch (tcb_desc->queue_index) {
2164 case VO_PRIORITY:
2165 priv->stats.txvodrop++;
2166 break;
2167 case VI_PRIORITY:
2168 priv->stats.txvidrop++;
2169 break;
2170 case BE_PRIORITY:
2171 priv->stats.txbedrop++;
2172 break;
2173 default://BK_PRIORITY
2174 priv->stats.txbkdrop++;
2175 break;
2176 }
2177 printk("To discard skb packet!\n");
2178 dev_kfree_skb_any(skb);
2179 return -1;
2180 }
2181
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002182 tx_urb = usb_alloc_urb(0,GFP_ATOMIC);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002183 if(!tx_urb){
2184 dev_kfree_skb_any(skb);
2185 return -ENOMEM;
2186 }
2187
2188 memset(tx_desc, 0, sizeof(tx_desc_819x_usb));
2189
2190
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002191 tx_desc->NonQos = (IsQoSDataFrame(skb->data)==TRUE)? 0:1;
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002192
2193 /* Fill Tx descriptor */
2194 //memset(tx_fwinfo,0,sizeof(tx_fwinfo_819x_usb));
2195
2196 // This part can just fill to the first descriptor of the frame.
2197 /* DWORD 0 */
2198 tx_desc->TxHT = (tcb_desc->data_rate&0x80)?1:0;
2199
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002200
2201 tx_desc->TxRate = MRateToHwRate8190Pci(tcb_desc->data_rate);
2202 //tx_desc->EnableCPUDur = tcb_desc->bTxEnableFwCalcDur;
2203 tx_desc->TxShort = QueryIsShort(tx_desc->TxHT, tx_desc->TxRate, tcb_desc);
2204
2205
2206 // Aggregation related
2207 if(tcb_desc->bAMPDUEnable) {//AMPDU enabled
2208 tx_desc->AllowAggregation = 1;
2209 /* DWORD 1 */
2210 //tx_fwinfo->RxMF = tcb_desc->ampdu_factor;
2211 //tx_fwinfo->RxAMD = tcb_desc->ampdu_density&0x07;//ampdudensity
2212 } else {
2213 tx_desc->AllowAggregation = 0;
2214 /* DWORD 1 */
2215 //tx_fwinfo->RxMF = 0;
2216 //tx_fwinfo->RxAMD = 0;
2217 }
2218
2219 //
2220 // <Roger_Notes> For AMPDU case, we must insert SSN into TX_DESC,
2221 // FW according as this SSN to do necessary packet retry.
2222 // 2008.06.06.
2223 //
2224 {
2225 u8 *pSeq;
2226 u16 Temp;
2227 //pSeq = (u8 *)(VirtualAddress+USB_HWDESC_HEADER_LEN + FRAME_OFFSET_SEQUENCE);
2228 pSeq = (u8 *)(skb->data+USB_HWDESC_HEADER_LEN + 22);
2229 Temp = pSeq[0];
2230 Temp <<= 12;
2231 Temp |= (*(u16 *)pSeq)>>4;
2232 tx_desc->Seq = Temp;
2233 }
2234
2235 /* Protection mode related */
2236 tx_desc->RTSEn = (tcb_desc->bRTSEnable)?1:0;
2237 tx_desc->CTS2Self = (tcb_desc->bCTSEnable)?1:0;
2238 tx_desc->RTSSTBC = (tcb_desc->bRTSSTBC)?1:0;
2239 tx_desc->RTSHT = (tcb_desc->rts_rate&0x80)?1:0;
2240 tx_desc->RTSRate = MRateToHwRate8190Pci((u8)tcb_desc->rts_rate);
2241 tx_desc->RTSSubcarrier = (tx_desc->RTSHT==0)?(tcb_desc->RTSSC):0;
2242 tx_desc->RTSBW = (tx_desc->RTSHT==1)?((tcb_desc->bRTSBW)?1:0):0;
2243 tx_desc->RTSShort = (tx_desc->RTSHT==0)?(tcb_desc->bRTSUseShortPreamble?1:0):\
2244 (tcb_desc->bRTSUseShortGI?1:0);
2245 //LZM 090219
2246 tx_desc->DisRTSFB = 0;
2247 tx_desc->RTSRateFBLmt = 0xf;
2248
2249 // <Roger_EXP> 2008.09.22. We disable RTS rate fallback temporarily.
2250 //tx_desc->DisRTSFB = 0x01;
2251
2252 /* Set Bandwidth and sub-channel settings. */
2253 if(priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20_40)
2254 {
2255 if(tcb_desc->bPacketBW) {
2256 tx_desc->TxBandwidth = 1;
2257 tx_desc->TxSubCarrier = 0; //By SD3's Jerry suggestion, use duplicated mode
2258 } else {
2259 tx_desc->TxBandwidth = 0;
2260 tx_desc->TxSubCarrier = priv->nCur40MhzPrimeSC;
2261 }
2262 } else {
2263 tx_desc->TxBandwidth = 0;
2264 tx_desc->TxSubCarrier = 0;
2265 }
2266
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002267
2268 //memset(tx_desc, 0, sizeof(tx_desc_819x_usb));
2269 /* DWORD 0 */
2270 tx_desc->LINIP = 0;
2271 //tx_desc->CmdInit = 1; //92su del
2272 tx_desc->Offset = USB_HWDESC_HEADER_LEN;
2273
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002274 {
2275 tx_desc->PktSize = (skb->len - USB_HWDESC_HEADER_LEN) & 0xffff;
2276 }
2277
2278 /*DWORD 1*/
2279 //tx_desc->SecCAMID= 0;//92su del
2280 tx_desc->RaBRSRID= tcb_desc->RATRIndex;
2281//#ifdef RTL8192S_PREPARE_FOR_NORMAL_RELEASE
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002282
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002283 {
2284 MPDUOverhead = 0;
2285 //tx_desc->NoEnc = 1;//92su del
2286 }
Bartlomiej Zolnierkiewicz35c1b462009-07-03 16:08:32 +02002287
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002288 tx_desc->SecType = 0x0;
Bartlomiej Zolnierkiewicz35c1b462009-07-03 16:08:32 +02002289
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002290 if (tcb_desc->bHwSec)
2291 {
2292 switch (priv->ieee80211->pairwise_key_type)
2293 {
2294 case KEY_TYPE_WEP40:
2295 case KEY_TYPE_WEP104:
2296 tx_desc->SecType = 0x1;
2297 //tx_desc->NoEnc = 0;//92su del
2298 break;
2299 case KEY_TYPE_TKIP:
2300 tx_desc->SecType = 0x2;
2301 //tx_desc->NoEnc = 0;//92su del
2302 break;
2303 case KEY_TYPE_CCMP:
2304 tx_desc->SecType = 0x3;
2305 //tx_desc->NoEnc = 0;//92su del
2306 break;
2307 case KEY_TYPE_NA:
2308 tx_desc->SecType = 0x0;
2309 //tx_desc->NoEnc = 1;//92su del
2310 break;
2311 default:
2312 tx_desc->SecType = 0x0;
2313 //tx_desc->NoEnc = 1;//92su del
2314 break;
2315 }
2316 }
2317
2318 //tx_desc->TxFWInfoSize = sizeof(tx_fwinfo_819x_usb);//92su del
2319
2320
2321 tx_desc->USERATE = tcb_desc->bTxUseDriverAssingedRate;
2322 tx_desc->DISFB = tcb_desc->bTxDisableRateFallBack;
2323 tx_desc->DataRateFBLmt = 0x1F;// Alwasy enable all rate fallback range
2324
2325 tx_desc->QueueSelect = MapHwQueueToFirmwareQueue(tcb_desc->queue_index);
2326
2327
2328 /* Fill fields that are required to be initialized in all of the descriptors */
2329 //DWORD 0
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002330 tx_desc->FirstSeg = 1;
2331 tx_desc->LastSeg = 1;
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002332 tx_desc->OWN = 1;
2333
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002334 {
2335 //DWORD 2
2336 //tx_desc->TxBufferSize = (u32)(skb->len - USB_HWDESC_HEADER_LEN);
2337 tx_desc->TxBufferSize = (u32)(skb->len);//92su mod FIXLZM
2338 }
2339
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002340 /* Get index to out pipe from specified QueueID */
2341 idx_pipe = txqueue2outpipe(priv,tcb_desc->queue_index);
2342 //printk("=============>%s queue_index:%d, outpipe:%d\n", __func__,tcb_desc->queue_index,priv->RtOutPipes[idx_pipe]);
2343
2344 //RT_DEBUG_DATA(COMP_SEND,tx_fwinfo,sizeof(tx_fwinfo_819x_usb));
2345 //RT_DEBUG_DATA(COMP_SEND,tx_desc,sizeof(tx_desc_819x_usb));
2346
2347 /* To submit bulk urb */
2348 usb_fill_bulk_urb(tx_urb,
2349 udev,
2350 usb_sndbulkpipe(udev,priv->RtOutPipes[idx_pipe]),
2351 skb->data,
2352 skb->len, rtl8192_tx_isr, skb);
2353
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002354 status = usb_submit_urb(tx_urb, GFP_ATOMIC);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002355 if (!status){
2356//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
2357 bool bSend0Byte = false;
2358 u8 zero = 0;
2359 if(udev->speed == USB_SPEED_HIGH)
2360 {
2361 if (skb->len > 0 && skb->len % 512 == 0)
2362 bSend0Byte = true;
2363 }
2364 else
2365 {
2366 if (skb->len > 0 && skb->len % 64 == 0)
2367 bSend0Byte = true;
2368 }
2369 if (bSend0Byte)
2370 {
2371#if 1
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002372 tx_urb_zero = usb_alloc_urb(0,GFP_ATOMIC);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002373 if(!tx_urb_zero){
2374 RT_TRACE(COMP_ERR, "can't alloc urb for zero byte\n");
2375 return -ENOMEM;
2376 }
2377 usb_fill_bulk_urb(tx_urb_zero,udev,
2378 usb_sndbulkpipe(udev,idx_pipe), &zero,
2379 0, tx_zero_isr, dev);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002380 status = usb_submit_urb(tx_urb_zero, GFP_ATOMIC);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002381 if (status){
2382 RT_TRACE(COMP_ERR, "Error TX URB for zero byte %d, error %d", atomic_read(&priv->tx_pending[tcb_desc->queue_index]), status);
2383 return -1;
2384 }
2385#endif
2386 }
2387 dev->trans_start = jiffies;
2388 atomic_inc(&priv->tx_pending[tcb_desc->queue_index]);
2389 return 0;
2390 }else{
2391 RT_TRACE(COMP_ERR, "Error TX URB %d, error %d", atomic_read(&priv->tx_pending[tcb_desc->queue_index]),
2392 status);
2393 return -1;
2394 }
2395}
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002396
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002397void rtl8192SU_net_update(struct net_device *dev)
2398{
2399
2400 struct r8192_priv *priv = ieee80211_priv(dev);
2401 struct ieee80211_device* ieee = priv->ieee80211;
2402 struct ieee80211_network *net = &priv->ieee80211->current_network;
2403 //u16 BcnTimeCfg = 0, BcnCW = 6, BcnIFS = 0xf;
2404 u16 rate_config = 0;
2405 u32 regTmp = 0;
2406 u8 rateIndex = 0;
2407 u8 retrylimit = 0x30;
2408 u16 cap = net->capability;
2409
2410 priv->short_preamble = cap & WLAN_CAPABILITY_SHORT_PREAMBLE;
2411
2412//HW_VAR_BASIC_RATE
2413 //update Basic rate: RR, BRSR
2414 rtl8192_config_rate(dev, &rate_config); //HalSetBrateCfg
2415
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002416 priv->basic_rate = rate_config = rate_config & 0x15f;
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002417
2418 // Set RRSR rate table.
2419 write_nic_byte(dev, RRSR, rate_config&0xff);
2420 write_nic_byte(dev, RRSR+1, (rate_config>>8)&0xff);
2421
2422 // Set RTS initial rate
2423 while(rate_config > 0x1)
2424 {
2425 rate_config = (rate_config>> 1);
2426 rateIndex++;
2427 }
2428 write_nic_byte(dev, INIRTSMCS_SEL, rateIndex);
2429//HW_VAR_BASIC_RATE
2430
2431 //set ack preample
2432 regTmp = (priv->nCur40MhzPrimeSC) << 5;
2433 if (priv->short_preamble)
2434 regTmp |= 0x80;
2435 write_nic_byte(dev, RRSR+2, regTmp);
2436
2437 write_nic_dword(dev,BSSIDR,((u32*)net->bssid)[0]);
2438 write_nic_word(dev,BSSIDR+4,((u16*)net->bssid)[2]);
2439
2440 write_nic_word(dev, BCN_INTERVAL, net->beacon_interval);
2441 //2008.10.24 added by tynli for beacon changed.
2442 PHY_SetBeaconHwReg( dev, net->beacon_interval);
2443
2444 rtl8192_update_cap(dev, cap);
2445
2446 if (ieee->iw_mode == IW_MODE_ADHOC){
2447 retrylimit = 7;
2448 //we should enable ibss interrupt here, but disable it temporarily
2449 if (0){
2450 priv->irq_mask |= (IMR_BcnInt | IMR_BcnInt | IMR_TBDOK | IMR_TBDER);
2451 //rtl8192_irq_disable(dev);
2452 //rtl8192_irq_enable(dev);
2453 }
2454 }
2455 else{
2456 if (0){
2457 priv->irq_mask &= ~(IMR_BcnInt | IMR_BcnInt | IMR_TBDOK | IMR_TBDER);
2458 //rtl8192_irq_disable(dev);
2459 //rtl8192_irq_enable(dev);
2460 }
2461 }
2462
2463 priv->ShortRetryLimit = priv->LongRetryLimit = retrylimit;
2464
2465 write_nic_word(dev, RETRY_LIMIT,
2466 retrylimit << RETRY_LIMIT_SHORT_SHIFT | \
2467 retrylimit << RETRY_LIMIT_LONG_SHIFT);
2468}
2469
2470void rtl8192SU_update_ratr_table(struct net_device* dev)
2471{
2472 struct r8192_priv* priv = ieee80211_priv(dev);
2473 struct ieee80211_device* ieee = priv->ieee80211;
2474 u8* pMcsRate = ieee->dot11HTOperationalRateSet;
2475 //struct ieee80211_network *net = &ieee->current_network;
2476 u32 ratr_value = 0;
2477
2478 u8 rate_index = 0;
2479 int WirelessMode = ieee->mode;
2480 u8 MimoPs = ieee->pHTInfo->PeerMimoPs;
2481
2482 u8 bNMode = 0;
2483
2484 rtl8192_config_rate(dev, (u16*)(&ratr_value));
2485 ratr_value |= (*(u16*)(pMcsRate)) << 12;
2486
2487 //switch (ieee->mode)
2488 switch (WirelessMode)
2489 {
2490 case IEEE_A:
2491 ratr_value &= 0x00000FF0;
2492 break;
2493 case IEEE_B:
2494 ratr_value &= 0x0000000D;
2495 break;
2496 case IEEE_G:
2497 ratr_value &= 0x00000FF5;
2498 break;
2499 case IEEE_N_24G:
2500 case IEEE_N_5G:
2501 {
2502 bNMode = 1;
2503
2504 if (MimoPs == 0) //MIMO_PS_STATIC
2505 {
2506 ratr_value &= 0x0007F005;
2507 }
2508 else
2509 { // MCS rate only => for 11N mode.
2510 u32 ratr_mask;
2511
2512 // 1T2R or 1T1R, Spatial Stream 2 should be disabled
2513 if ( priv->rf_type == RF_1T2R ||
2514 priv->rf_type == RF_1T1R ||
2515 (ieee->pHTInfo->IOTAction & HT_IOT_ACT_DISABLE_TX_2SS) )
2516 ratr_mask = 0x000ff005;
2517 else
2518 ratr_mask = 0x0f0ff005;
2519
2520 if((ieee->pHTInfo->bCurTxBW40MHz) &&
2521 !(ieee->pHTInfo->IOTAction & HT_IOT_ACT_DISABLE_TX_40_MHZ))
2522 ratr_mask |= 0x00000010; // Set 6MBps
2523
2524 // Select rates for rate adaptive mechanism.
2525 ratr_value &= ratr_mask;
2526 }
2527 }
2528 break;
2529 default:
2530 if(0)
2531 {
2532 if(priv->rf_type == RF_1T2R) // 1T2R, Spatial Stream 2 should be disabled
2533 {
2534 ratr_value &= 0x000ff0f5;
2535 }
2536 else
2537 {
2538 ratr_value &= 0x0f0ff0f5;
2539 }
2540 }
2541 //printk("====>%s(), mode is not correct:%x\n", __FUNCTION__, ieee->mode);
2542 break;
2543 }
2544
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002545 ratr_value &= 0x0FFFFFFF;
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002546
2547 // Get MAX MCS available.
2548 if ( (bNMode && ((ieee->pHTInfo->IOTAction & HT_IOT_ACT_DISABLE_SHORT_GI)==0)) &&
2549 ((ieee->pHTInfo->bCurBW40MHz && ieee->pHTInfo->bCurShortGI40MHz) ||
2550 (!ieee->pHTInfo->bCurBW40MHz && ieee->pHTInfo->bCurShortGI20MHz)))
2551 {
2552 u8 shortGI_rate = 0;
2553 u32 tmp_ratr_value = 0;
2554 ratr_value |= 0x10000000;//???
2555 tmp_ratr_value = (ratr_value>>12);
2556 for(shortGI_rate=15; shortGI_rate>0; shortGI_rate--)
2557 {
2558 if((1<<shortGI_rate) & tmp_ratr_value)
2559 break;
2560 }
2561 shortGI_rate = (shortGI_rate<<12)|(shortGI_rate<<8)|(shortGI_rate<<4)|(shortGI_rate);
2562 write_nic_byte(dev, SG_RATE, shortGI_rate);
2563 //printk("==>SG_RATE:%x\n", read_nic_byte(dev, SG_RATE));
2564 }
2565 write_nic_dword(dev, ARFR0+rate_index*4, ratr_value);
2566 printk("=============>ARFR0+rate_index*4:%#x\n", ratr_value);
2567
2568 //2 UFWP
2569 if (ratr_value & 0xfffff000){
2570 //printk("===>set to N mode\n");
2571 HalSetFwCmd8192S(dev, FW_CMD_RA_REFRESH_N);
2572 }
2573 else {
2574 //printk("===>set to B/G mode\n");
2575 HalSetFwCmd8192S(dev, FW_CMD_RA_REFRESH_BG);
2576 }
2577}
2578
2579void rtl8192SU_link_change(struct net_device *dev)
2580{
2581 struct r8192_priv *priv = ieee80211_priv(dev);
2582 struct ieee80211_device* ieee = priv->ieee80211;
2583 //unsigned long flags;
2584 u32 reg = 0;
2585
2586 printk("=====>%s 1\n", __func__);
2587 reg = read_nic_dword(dev, RCR);
2588
2589 if (ieee->state == IEEE80211_LINKED)
2590 {
2591
2592 rtl8192SU_net_update(dev);
2593 rtl8192SU_update_ratr_table(dev);
2594 ieee->SetFwCmdHandler(dev, FW_CMD_HIGH_PWR_ENABLE);
2595 priv->ReceiveConfig = reg |= RCR_CBSSID;
2596
2597 }else{
2598 priv->ReceiveConfig = reg &= ~RCR_CBSSID;
2599
2600 }
2601
2602 write_nic_dword(dev, RCR, reg);
2603 rtl8192_update_msr(dev);
2604
2605 printk("<=====%s 2\n", __func__);
2606}
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002607
2608static struct ieee80211_qos_parameters def_qos_parameters = {
2609 {3,3,3,3},/* cw_min */
2610 {7,7,7,7},/* cw_max */
2611 {2,2,2,2},/* aifs */
2612 {0,0,0,0},/* flags */
2613 {0,0,0,0} /* tx_op_limit */
2614};
2615
2616
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002617void rtl8192_update_beacon(struct work_struct * work)
2618{
2619 struct r8192_priv *priv = container_of(work, struct r8192_priv, update_beacon_wq.work);
2620 struct net_device *dev = priv->ieee80211->dev;
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002621 struct ieee80211_device* ieee = priv->ieee80211;
2622 struct ieee80211_network* net = &ieee->current_network;
2623
2624 if (ieee->pHTInfo->bCurrentHTSupport)
2625 HTUpdateSelfAndPeerSetting(ieee, net);
2626 ieee->pHTInfo->bCurrentRT2RTLongSlotTime = net->bssht.bdRT2RTLongSlotTime;
2627 // Joseph test for turbo mode with AP
2628 ieee->pHTInfo->RT2RT_HT_Mode = net->bssht.RT2RT_HT_Mode;
2629 rtl8192_update_cap(dev, net->capability);
2630}
2631/*
2632* background support to run QoS activate functionality
2633*/
2634int WDCAPARA_ADD[] = {EDCAPARA_BE,EDCAPARA_BK,EDCAPARA_VI,EDCAPARA_VO};
Bartlomiej Zolnierkiewicz1ec9e482009-06-13 18:35:04 +02002635
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002636void rtl8192_qos_activate(struct work_struct * work)
2637{
2638 struct r8192_priv *priv = container_of(work, struct r8192_priv, qos_activate);
2639 struct net_device *dev = priv->ieee80211->dev;
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002640 struct ieee80211_qos_parameters *qos_parameters = &priv->ieee80211->current_network.qos_data.parameters;
2641 u8 mode = priv->ieee80211->current_network.mode;
2642 //u32 size = sizeof(struct ieee80211_qos_parameters);
2643 u8 u1bAIFS;
2644 u32 u4bAcParam;
2645 int i;
2646
2647 if (priv == NULL)
2648 return;
2649
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002650 mutex_lock(&priv->mutex);
Bartlomiej Zolnierkiewicz1ec9e482009-06-13 18:35:04 +02002651
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002652 if(priv->ieee80211->state != IEEE80211_LINKED)
2653 goto success;
2654 RT_TRACE(COMP_QOS,"qos active process with associate response received\n");
2655 /* It better set slot time at first */
2656 /* For we just support b/g mode at present, let the slot time at 9/20 selection */
2657 /* update the ac parameter to related registers */
2658 for(i = 0; i < QOS_QUEUE_NUM; i++) {
2659 //Mode G/A: slotTimeTimer = 9; Mode B: 20
2660 u1bAIFS = qos_parameters->aifs[i] * ((mode&(IEEE_G|IEEE_N_24G)) ?9:20) + aSifsTime;
2661 u4bAcParam = ((((u32)(qos_parameters->tx_op_limit[i]))<< AC_PARAM_TXOP_LIMIT_OFFSET)|
2662 (((u32)(qos_parameters->cw_max[i]))<< AC_PARAM_ECW_MAX_OFFSET)|
2663 (((u32)(qos_parameters->cw_min[i]))<< AC_PARAM_ECW_MIN_OFFSET)|
2664 ((u32)u1bAIFS << AC_PARAM_AIFS_OFFSET));
2665
2666 write_nic_dword(dev, WDCAPARA_ADD[i], u4bAcParam);
2667 //write_nic_dword(dev, WDCAPARA_ADD[i], 0x005e4322);
2668 }
2669
2670success:
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002671 mutex_unlock(&priv->mutex);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002672}
2673
2674static int rtl8192_qos_handle_probe_response(struct r8192_priv *priv,
2675 int active_network,
2676 struct ieee80211_network *network)
2677{
2678 int ret = 0;
2679 u32 size = sizeof(struct ieee80211_qos_parameters);
2680
2681 if(priv->ieee80211->state !=IEEE80211_LINKED)
2682 return ret;
2683
2684 if ((priv->ieee80211->iw_mode != IW_MODE_INFRA))
2685 return ret;
2686
2687 if (network->flags & NETWORK_HAS_QOS_MASK) {
2688 if (active_network &&
2689 (network->flags & NETWORK_HAS_QOS_PARAMETERS))
2690 network->qos_data.active = network->qos_data.supported;
2691
2692 if ((network->qos_data.active == 1) && (active_network == 1) &&
2693 (network->flags & NETWORK_HAS_QOS_PARAMETERS) &&
2694 (network->qos_data.old_param_count !=
2695 network->qos_data.param_count)) {
2696 network->qos_data.old_param_count =
2697 network->qos_data.param_count;
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002698 queue_work(priv->priv_wq, &priv->qos_activate);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002699 RT_TRACE (COMP_QOS, "QoS parameters change call "
2700 "qos_activate\n");
2701 }
2702 } else {
2703 memcpy(&priv->ieee80211->current_network.qos_data.parameters,\
2704 &def_qos_parameters, size);
2705
2706 if ((network->qos_data.active == 1) && (active_network == 1)) {
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002707 queue_work(priv->priv_wq, &priv->qos_activate);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002708 RT_TRACE(COMP_QOS, "QoS was disabled call qos_activate \n");
2709 }
2710 network->qos_data.active = 0;
2711 network->qos_data.supported = 0;
2712 }
2713
2714 return 0;
2715}
2716
2717/* handle manage frame frame beacon and probe response */
2718static int rtl8192_handle_beacon(struct net_device * dev,
2719 struct ieee80211_beacon * beacon,
2720 struct ieee80211_network * network)
2721{
2722 struct r8192_priv *priv = ieee80211_priv(dev);
2723
2724 rtl8192_qos_handle_probe_response(priv,1,network);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002725 queue_delayed_work(priv->priv_wq, &priv->update_beacon_wq, 0);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002726
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002727 return 0;
2728
2729}
2730
2731/*
2732* handling the beaconing responses. if we get different QoS setting
2733* off the network from the associated setting, adjust the QoS
2734* setting
2735*/
2736static int rtl8192_qos_association_resp(struct r8192_priv *priv,
2737 struct ieee80211_network *network)
2738{
2739 int ret = 0;
2740 unsigned long flags;
2741 u32 size = sizeof(struct ieee80211_qos_parameters);
2742 int set_qos_param = 0;
2743
2744 if ((priv == NULL) || (network == NULL))
2745 return ret;
2746
2747 if(priv->ieee80211->state !=IEEE80211_LINKED)
2748 return ret;
2749
2750 if ((priv->ieee80211->iw_mode != IW_MODE_INFRA))
2751 return ret;
2752
2753 spin_lock_irqsave(&priv->ieee80211->lock, flags);
2754 if(network->flags & NETWORK_HAS_QOS_PARAMETERS) {
2755 memcpy(&priv->ieee80211->current_network.qos_data.parameters,\
2756 &network->qos_data.parameters,\
2757 sizeof(struct ieee80211_qos_parameters));
2758 priv->ieee80211->current_network.qos_data.active = 1;
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002759 {
2760 set_qos_param = 1;
2761 /* update qos parameter for current network */
2762 priv->ieee80211->current_network.qos_data.old_param_count = \
2763 priv->ieee80211->current_network.qos_data.param_count;
2764 priv->ieee80211->current_network.qos_data.param_count = \
2765 network->qos_data.param_count;
2766 }
2767 } else {
2768 memcpy(&priv->ieee80211->current_network.qos_data.parameters,\
2769 &def_qos_parameters, size);
2770 priv->ieee80211->current_network.qos_data.active = 0;
2771 priv->ieee80211->current_network.qos_data.supported = 0;
2772 set_qos_param = 1;
2773 }
2774
2775 spin_unlock_irqrestore(&priv->ieee80211->lock, flags);
2776
2777 RT_TRACE(COMP_QOS, "%s: network->flags = %d,%d\n",__FUNCTION__,network->flags ,priv->ieee80211->current_network.qos_data.active);
2778 if (set_qos_param == 1)
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002779 queue_work(priv->priv_wq, &priv->qos_activate);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002780
2781 return ret;
2782}
2783
2784
2785static int rtl8192_handle_assoc_response(struct net_device *dev,
2786 struct ieee80211_assoc_response_frame *resp,
2787 struct ieee80211_network *network)
2788{
2789 struct r8192_priv *priv = ieee80211_priv(dev);
2790 rtl8192_qos_association_resp(priv, network);
2791 return 0;
2792}
2793
2794
2795void rtl8192_update_ratr_table(struct net_device* dev)
2796 // POCTET_STRING posLegacyRate,
2797 // u8* pMcsRate)
2798 // PRT_WLAN_STA pEntry)
2799{
2800 struct r8192_priv* priv = ieee80211_priv(dev);
2801 struct ieee80211_device* ieee = priv->ieee80211;
2802 u8* pMcsRate = ieee->dot11HTOperationalRateSet;
2803 //struct ieee80211_network *net = &ieee->current_network;
2804 u32 ratr_value = 0;
2805 u8 rate_index = 0;
2806 rtl8192_config_rate(dev, (u16*)(&ratr_value));
2807 ratr_value |= (*(u16*)(pMcsRate)) << 12;
2808// switch (net->mode)
2809 switch (ieee->mode)
2810 {
2811 case IEEE_A:
2812 ratr_value &= 0x00000FF0;
2813 break;
2814 case IEEE_B:
2815 ratr_value &= 0x0000000F;
2816 break;
2817 case IEEE_G:
2818 ratr_value &= 0x00000FF7;
2819 break;
2820 case IEEE_N_24G:
2821 case IEEE_N_5G:
2822 if (ieee->pHTInfo->PeerMimoPs == 0) //MIMO_PS_STATIC
2823 ratr_value &= 0x0007F007;
2824 else{
2825 if (priv->rf_type == RF_1T2R)
2826 ratr_value &= 0x000FF007;
2827 else
2828 ratr_value &= 0x0F81F007;
2829 }
2830 break;
2831 default:
2832 break;
2833 }
2834 ratr_value &= 0x0FFFFFFF;
2835 if(ieee->pHTInfo->bCurTxBW40MHz && ieee->pHTInfo->bCurShortGI40MHz){
2836 ratr_value |= 0x80000000;
2837 }else if(!ieee->pHTInfo->bCurTxBW40MHz && ieee->pHTInfo->bCurShortGI20MHz){
2838 ratr_value |= 0x80000000;
2839 }
2840 write_nic_dword(dev, RATR0+rate_index*4, ratr_value);
2841 write_nic_byte(dev, UFWP, 1);
2842}
2843
2844static u8 ccmp_ie[4] = {0x00,0x50,0xf2,0x04};
2845static u8 ccmp_rsn_ie[4] = {0x00, 0x0f, 0xac, 0x04};
2846bool GetNmodeSupportBySecCfg8192(struct net_device*dev)
2847{
2848#if 1
2849 struct r8192_priv* priv = ieee80211_priv(dev);
2850 struct ieee80211_device* ieee = priv->ieee80211;
2851 struct ieee80211_network * network = &ieee->current_network;
2852 int wpa_ie_len= ieee->wpa_ie_len;
2853 struct ieee80211_crypt_data* crypt;
2854 int encrypt;
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002855 return TRUE;
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002856
2857 crypt = ieee->crypt[ieee->tx_keyidx];
2858 //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
2859 encrypt = (network->capability & WLAN_CAPABILITY_PRIVACY) || (ieee->host_encrypt && crypt && crypt->ops && (0 == strcmp(crypt->ops->name,"WEP")));
2860
2861 /* simply judge */
2862 if(encrypt && (wpa_ie_len == 0)) {
2863 /* wep encryption, no N mode setting */
2864 return false;
2865// } else if((wpa_ie_len != 0)&&(memcmp(&(ieee->wpa_ie[14]),ccmp_ie,4))) {
2866 } else if((wpa_ie_len != 0)) {
2867 /* parse pairwise key type */
2868 //if((pairwisekey = WEP40)||(pairwisekey = WEP104)||(pairwisekey = TKIP))
2869 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))))
2870 return true;
2871 else
2872 return false;
2873 } else {
2874 return true;
2875 }
2876
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002877 return true;
2878#endif
2879}
2880
2881bool GetHalfNmodeSupportByAPs819xUsb(struct net_device* dev)
2882{
2883 bool Reval;
2884 struct r8192_priv* priv = ieee80211_priv(dev);
2885 struct ieee80211_device* ieee = priv->ieee80211;
2886
2887// Added by Roger, 2008.08.29.
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002888 return false;
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002889
2890 if(ieee->bHalfWirelessN24GMode == true)
2891 Reval = true;
2892 else
2893 Reval = false;
2894
2895 return Reval;
2896}
2897
2898void rtl8192_refresh_supportrate(struct r8192_priv* priv)
2899{
2900 struct ieee80211_device* ieee = priv->ieee80211;
2901 //we donot consider set support rate for ABG mode, only HT MCS rate is set here.
2902 if (ieee->mode == WIRELESS_MODE_N_24G || ieee->mode == WIRELESS_MODE_N_5G)
2903 {
2904 memcpy(ieee->Regdot11HTOperationalRateSet, ieee->RegHTSuppRateSet, 16);
2905 //RT_DEBUG_DATA(COMP_INIT, ieee->RegHTSuppRateSet, 16);
2906 //RT_DEBUG_DATA(COMP_INIT, ieee->Regdot11HTOperationalRateSet, 16);
2907 }
2908 else
2909 memset(ieee->Regdot11HTOperationalRateSet, 0, 16);
2910 return;
2911}
2912
2913u8 rtl8192_getSupportedWireleeMode(struct net_device*dev)
2914{
2915 struct r8192_priv *priv = ieee80211_priv(dev);
2916 u8 ret = 0;
2917 switch(priv->rf_chip)
2918 {
2919 case RF_8225:
2920 case RF_8256:
2921 case RF_PSEUDO_11N:
2922 case RF_6052:
2923 ret = (WIRELESS_MODE_N_24G|WIRELESS_MODE_G|WIRELESS_MODE_B);
2924 break;
2925 case RF_8258:
2926 ret = (WIRELESS_MODE_A|WIRELESS_MODE_N_5G);
2927 break;
2928 default:
2929 ret = WIRELESS_MODE_B;
2930 break;
2931 }
2932 return ret;
2933}
2934void rtl8192_SetWirelessMode(struct net_device* dev, u8 wireless_mode)
2935{
2936 struct r8192_priv *priv = ieee80211_priv(dev);
2937 u8 bSupportMode = rtl8192_getSupportedWireleeMode(dev);
2938
2939#if 1
2940 if ((wireless_mode == WIRELESS_MODE_AUTO) || ((wireless_mode&bSupportMode)==0))
2941 {
2942 if(bSupportMode & WIRELESS_MODE_N_24G)
2943 {
2944 wireless_mode = WIRELESS_MODE_N_24G;
2945 }
2946 else if(bSupportMode & WIRELESS_MODE_N_5G)
2947 {
2948 wireless_mode = WIRELESS_MODE_N_5G;
2949 }
2950 else if((bSupportMode & WIRELESS_MODE_A))
2951 {
2952 wireless_mode = WIRELESS_MODE_A;
2953 }
2954 else if((bSupportMode & WIRELESS_MODE_G))
2955 {
2956 wireless_mode = WIRELESS_MODE_G;
2957 }
2958 else if((bSupportMode & WIRELESS_MODE_B))
2959 {
2960 wireless_mode = WIRELESS_MODE_B;
2961 }
2962 else{
2963 RT_TRACE(COMP_ERR, "%s(), No valid wireless mode supported, SupportedWirelessMode(%x)!!!\n", __FUNCTION__,bSupportMode);
2964 wireless_mode = WIRELESS_MODE_B;
2965 }
2966 }
2967#ifdef TO_DO_LIST //// TODO: this function doesn't work well at this time, we shoud wait for FPGA
2968 ActUpdateChannelAccessSetting( pAdapter, pHalData->CurrentWirelessMode, &pAdapter->MgntInfo.Info8185.ChannelAccessSetting );
2969#endif
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002970 //LZM 090306 usb crash here, mark it temp
2971 //write_nic_word(dev, SIFS_OFDM, 0x0e0e);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002972 priv->ieee80211->mode = wireless_mode;
2973
2974 if ((wireless_mode == WIRELESS_MODE_N_24G) || (wireless_mode == WIRELESS_MODE_N_5G))
2975 priv->ieee80211->pHTInfo->bEnableHT = 1;
2976 else
2977 priv->ieee80211->pHTInfo->bEnableHT = 0;
2978 RT_TRACE(COMP_INIT, "Current Wireless Mode is %x\n", wireless_mode);
2979 rtl8192_refresh_supportrate(priv);
2980#endif
2981
2982}
2983
2984
2985short rtl8192_is_tx_queue_empty(struct net_device *dev)
2986{
2987 int i=0;
2988 struct r8192_priv *priv = ieee80211_priv(dev);
2989 //struct ieee80211_device* ieee = priv->ieee80211;
2990 for (i=0; i<=MGNT_QUEUE; i++)
2991 {
2992 if ((i== TXCMD_QUEUE) || (i == HCCA_QUEUE) )
2993 continue;
2994 if (atomic_read(&priv->tx_pending[i]))
2995 {
2996 printk("===>tx queue is not empty:%d, %d\n", i, atomic_read(&priv->tx_pending[i]));
2997 return 0;
2998 }
2999 }
3000 return 1;
3001}
Bartlomiej Zolnierkiewicz35c1b462009-07-03 16:08:32 +02003002
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003003void rtl8192_hw_sleep_down(struct net_device *dev)
3004{
3005 RT_TRACE(COMP_POWER, "%s()============>come to sleep down\n", __FUNCTION__);
3006#ifdef TODO
3007// MgntActSet_RF_State(dev, eRfSleep, RF_CHANGE_BY_PS);
3008#endif
3009}
Bartlomiej Zolnierkiewicz1ec9e482009-06-13 18:35:04 +02003010
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003011void rtl8192_hw_sleep_wq (struct work_struct *work)
3012{
3013// struct r8180_priv *priv = container_of(work, struct r8180_priv, watch_dog_wq);
3014// struct ieee80211_device * ieee = (struct ieee80211_device*)
3015// container_of(work, struct ieee80211_device, watch_dog_wq);
3016 struct delayed_work *dwork = container_of(work,struct delayed_work,work);
3017 struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,hw_sleep_wq);
3018 struct net_device *dev = ieee->dev;
Bartlomiej Zolnierkiewicz1ec9e482009-06-13 18:35:04 +02003019
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003020 //printk("=========>%s()\n", __FUNCTION__);
3021 rtl8192_hw_sleep_down(dev);
3022}
3023// printk("dev is %d\n",dev);
3024// printk("&*&(^*(&(&=========>%s()\n", __FUNCTION__);
3025void rtl8192_hw_wakeup(struct net_device* dev)
3026{
3027// u32 flags = 0;
3028
3029// spin_lock_irqsave(&priv->ps_lock,flags);
3030 RT_TRACE(COMP_POWER, "%s()============>come to wake up\n", __FUNCTION__);
3031#ifdef TODO
3032// MgntActSet_RF_State(dev, eRfSleep, RF_CHANGE_BY_PS);
3033#endif
3034 //FIXME: will we send package stored while nic is sleep?
3035// spin_unlock_irqrestore(&priv->ps_lock,flags);
3036}
Bartlomiej Zolnierkiewicz1ec9e482009-06-13 18:35:04 +02003037
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003038void rtl8192_hw_wakeup_wq (struct work_struct *work)
3039{
3040// struct r8180_priv *priv = container_of(work, struct r8180_priv, watch_dog_wq);
3041// struct ieee80211_device * ieee = (struct ieee80211_device*)
3042// container_of(work, struct ieee80211_device, watch_dog_wq);
3043 struct delayed_work *dwork = container_of(work,struct delayed_work,work);
3044 struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,hw_wakeup_wq);
3045 struct net_device *dev = ieee->dev;
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003046
Bartlomiej Zolnierkiewicz1ec9e482009-06-13 18:35:04 +02003047 rtl8192_hw_wakeup(dev);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003048}
3049
3050#define MIN_SLEEP_TIME 50
3051#define MAX_SLEEP_TIME 10000
3052void rtl8192_hw_to_sleep(struct net_device *dev, u32 th, u32 tl)
3053{
3054
3055 struct r8192_priv *priv = ieee80211_priv(dev);
3056
3057 u32 rb = jiffies;
3058 unsigned long flags;
3059
3060 spin_lock_irqsave(&priv->ps_lock,flags);
3061
3062 /* Writing HW register with 0 equals to disable
3063 * the timer, that is not really what we want
3064 */
3065 tl -= MSECS(4+16+7);
3066
3067 //if(tl == 0) tl = 1;
3068
3069 /* FIXME HACK FIXME HACK */
3070// force_pci_posting(dev);
3071 //mdelay(1);
3072
3073// rb = read_nic_dword(dev, TSFTR);
3074
3075 /* If the interval in witch we are requested to sleep is too
3076 * short then give up and remain awake
3077 */
3078 if(((tl>=rb)&& (tl-rb) <= MSECS(MIN_SLEEP_TIME))
3079 ||((rb>tl)&& (rb-tl) < MSECS(MIN_SLEEP_TIME))) {
3080 spin_unlock_irqrestore(&priv->ps_lock,flags);
3081 printk("too short to sleep\n");
3082 return;
3083 }
3084
3085// write_nic_dword(dev, TimerInt, tl);
3086// rb = read_nic_dword(dev, TSFTR);
3087 {
3088 u32 tmp = (tl>rb)?(tl-rb):(rb-tl);
3089 // if (tl<rb)
3090
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003091 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 -07003092 }
3093 /* if we suspect the TimerInt is gone beyond tl
3094 * while setting it, then give up
3095 */
3096#if 1
3097 if(((tl > rb) && ((tl-rb) > MSECS(MAX_SLEEP_TIME)))||
3098 ((tl < rb) && ((rb-tl) > MSECS(MAX_SLEEP_TIME)))) {
3099 printk("========>too long to sleep:%x, %x, %lx\n", tl, rb, MSECS(MAX_SLEEP_TIME));
3100 spin_unlock_irqrestore(&priv->ps_lock,flags);
3101 return;
3102 }
3103#endif
3104// if(priv->rf_sleep)
3105// priv->rf_sleep(dev);
3106
3107 //printk("<=========%s()\n", __FUNCTION__);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003108 queue_delayed_work(priv->ieee80211->wq, (void *)&priv->ieee80211->hw_sleep_wq,0);
Bartlomiej Zolnierkiewicz1ec9e482009-06-13 18:35:04 +02003109
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003110 spin_unlock_irqrestore(&priv->ps_lock,flags);
3111}
3112//init priv variables here. only non_zero value should be initialized here.
3113static void rtl8192_init_priv_variable(struct net_device* dev)
3114{
3115 struct r8192_priv *priv = ieee80211_priv(dev);
3116 u8 i;
3117 priv->card_8192 = NIC_8192U;
3118 priv->chan = 1; //set to channel 1
3119 priv->ieee80211->mode = WIRELESS_MODE_AUTO; //SET AUTO
3120 priv->ieee80211->iw_mode = IW_MODE_INFRA;
3121 priv->ieee80211->ieee_up=0;
3122 priv->retry_rts = DEFAULT_RETRY_RTS;
3123 priv->retry_data = DEFAULT_RETRY_DATA;
3124 priv->ieee80211->rts = DEFAULT_RTS_THRESHOLD;
3125 priv->ieee80211->rate = 110; //11 mbps
3126 priv->ieee80211->short_slot = 1;
3127 priv->promisc = (dev->flags & IFF_PROMISC) ? 1:0;
3128 priv->CckPwEnl = 6;
3129 //for silent reset
3130 priv->IrpPendingCount = 1;
3131 priv->ResetProgress = RESET_TYPE_NORESET;
3132 priv->bForcedSilentReset = 0;
3133 priv->bDisableNormalResetCheck = false;
3134 priv->force_reset = false;
3135
3136 priv->ieee80211->FwRWRF = 0; //we don't use FW read/write RF until stable firmware is available.
3137 priv->ieee80211->current_network.beacon_interval = DEFAULT_BEACONINTERVAL;
3138 priv->ieee80211->iw_mode = IW_MODE_INFRA;
3139 priv->ieee80211->softmac_features = IEEE_SOFTMAC_SCAN |
3140 IEEE_SOFTMAC_ASSOCIATE | IEEE_SOFTMAC_PROBERQ |
3141 IEEE_SOFTMAC_PROBERS | IEEE_SOFTMAC_TX_QUEUE |
3142 IEEE_SOFTMAC_BEACONS;//added by amy 080604 //| //IEEE_SOFTMAC_SINGLE_QUEUE;
3143
3144 priv->ieee80211->active_scan = 1;
3145 priv->ieee80211->modulation = IEEE80211_CCK_MODULATION | IEEE80211_OFDM_MODULATION;
3146 priv->ieee80211->host_encrypt = 1;
3147 priv->ieee80211->host_decrypt = 1;
3148 priv->ieee80211->start_send_beacons = NULL;//rtl819xusb_beacon_tx;//-by amy 080604
3149 priv->ieee80211->stop_send_beacons = NULL;//rtl8192_beacon_stop;//-by amy 080604
3150 priv->ieee80211->softmac_hard_start_xmit = rtl8192_hard_start_xmit;
3151 priv->ieee80211->set_chan = rtl8192_set_chan;
3152 priv->ieee80211->link_change = priv->ops->rtl819x_link_change;
3153 priv->ieee80211->softmac_data_hard_start_xmit = rtl8192_hard_data_xmit;
3154 priv->ieee80211->data_hard_stop = rtl8192_data_hard_stop;
3155 priv->ieee80211->data_hard_resume = rtl8192_data_hard_resume;
3156 priv->ieee80211->init_wmmparam_flag = 0;
3157 priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD;
3158 priv->ieee80211->check_nic_enough_desc = check_nic_enough_desc;
3159 priv->ieee80211->tx_headroom = TX_PACKET_SHIFT_BYTES;
3160 priv->ieee80211->qos_support = 1;
3161
3162 //added by WB
3163// priv->ieee80211->SwChnlByTimerHandler = rtl8192_phy_SwChnl;
3164 priv->ieee80211->SetBWModeHandler = rtl8192_SetBWMode;
3165 priv->ieee80211->handle_assoc_response = rtl8192_handle_assoc_response;
3166 priv->ieee80211->handle_beacon = rtl8192_handle_beacon;
3167 //for LPS
3168 priv->ieee80211->sta_wake_up = rtl8192_hw_wakeup;
3169// priv->ieee80211->ps_request_tx_ack = rtl8192_rq_tx_ack;
3170 priv->ieee80211->enter_sleep_state = rtl8192_hw_to_sleep;
3171 priv->ieee80211->ps_is_queue_empty = rtl8192_is_tx_queue_empty;
3172 //added by david
3173 priv->ieee80211->GetNmodeSupportBySecCfg = GetNmodeSupportBySecCfg8192;
3174 priv->ieee80211->GetHalfNmodeSupportByAPsHandler = GetHalfNmodeSupportByAPs819xUsb;
3175 priv->ieee80211->SetWirelessMode = rtl8192_SetWirelessMode;
3176 //added by amy
3177 priv->ieee80211->InitialGainHandler = priv->ops->rtl819x_initial_gain;
3178 priv->card_type = USB;
3179
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003180//1 RTL8192SU/
3181 priv->ieee80211->current_network.beacon_interval = DEFAULT_BEACONINTERVAL;
3182 priv->ieee80211->SetFwCmdHandler = HalSetFwCmd8192S;
3183 priv->bRFSiOrPi = 0;//o=si,1=pi;
3184 //lzm add
3185 priv->bInHctTest = false;
3186
3187 priv->MidHighPwrTHR_L1 = 0x3B;
3188 priv->MidHighPwrTHR_L2 = 0x40;
3189
3190 if(priv->bInHctTest)
3191 {
3192 priv->ShortRetryLimit = HAL_RETRY_LIMIT_AP_ADHOC;
3193 priv->LongRetryLimit = HAL_RETRY_LIMIT_AP_ADHOC;
3194 }
3195 else
3196 {
3197 priv->ShortRetryLimit = HAL_RETRY_LIMIT_INFRA;
3198 priv->LongRetryLimit = HAL_RETRY_LIMIT_INFRA;
3199 }
3200
3201 priv->SetFwCmdInProgress = false; //is set FW CMD in Progress? 92S only
3202 priv->CurrentFwCmdIO = 0;
3203
3204 priv->MinSpaceCfg = 0;
3205
3206 priv->EarlyRxThreshold = 7;
3207 priv->enable_gpio0 = 0;
3208 priv->TransmitConfig =
3209 ((u32)TCR_MXDMA_2048<<TCR_MXDMA_OFFSET) | // Max DMA Burst Size per Tx DMA Burst, 7: reservied.
3210 (priv->ShortRetryLimit<<TCR_SRL_OFFSET) | // Short retry limit
3211 (priv->LongRetryLimit<<TCR_LRL_OFFSET) | // Long retry limit
3212 (false ? TCR_SAT : 0); // FALSE: HW provies PLCP length and LENGEXT, TURE: SW proiveds them
3213 if(priv->bInHctTest)
3214 priv->ReceiveConfig = //priv->CSMethod |
3215 RCR_AMF | RCR_ADF | //RCR_AAP | //accept management/data
3216 RCR_ACF |RCR_APPFCS| //accept control frame for SW AP needs PS-poll, 2005.07.07, by rcnjko.
3217 RCR_AB | RCR_AM | RCR_APM | //accept BC/MC/UC
3218 RCR_AICV | RCR_ACRC32 | //accept ICV/CRC error packet
3219 RCR_APP_PHYST_STAFF | RCR_APP_PHYST_RXFF | // Accept PHY status
3220 ((u32)7<<RCR_MXDMA_OFFSET) | // Max DMA Burst Size per Rx DMA Burst, 7: unlimited.
3221 (priv->EarlyRxThreshold<<RCR_FIFO_OFFSET) | // Rx FIFO Threshold, 7: No Rx threshold.
3222 (priv->EarlyRxThreshold == 7 ? RCR_OnlyErlPkt:0);
3223 else
3224 priv->ReceiveConfig = //priv->CSMethod |
3225 RCR_AMF | RCR_ADF | RCR_AB |
3226 RCR_AM | RCR_APM |RCR_AAP |RCR_ADD3|RCR_APP_ICV|
3227 RCR_APP_PHYST_STAFF | RCR_APP_PHYST_RXFF | // Accept PHY status
3228 RCR_APP_MIC | RCR_APPFCS;
3229
3230 // <Roger_EXP> 2008.06.16.
3231 priv->IntrMask = (u16)(IMR_ROK | IMR_VODOK | IMR_VIDOK | IMR_BEDOK | IMR_BKDOK | \
3232 IMR_HCCADOK | IMR_MGNTDOK | IMR_COMDOK | IMR_HIGHDOK | \
3233 IMR_BDOK | IMR_RXCMDOK | /*IMR_TIMEOUT0 |*/ IMR_RDU | IMR_RXFOVW | \
3234 IMR_TXFOVW | IMR_BcnInt | IMR_TBDOK | IMR_TBDER);
3235
3236//1 End
3237
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003238
3239 priv->AcmControl = 0;
3240 priv->pFirmware = (rt_firmware*)vmalloc(sizeof(rt_firmware));
3241 if (priv->pFirmware)
3242 memset(priv->pFirmware, 0, sizeof(rt_firmware));
3243
3244 /* rx related queue */
3245 skb_queue_head_init(&priv->rx_queue);
3246 skb_queue_head_init(&priv->skb_queue);
3247
3248 /* Tx related queue */
3249 for(i = 0; i < MAX_QUEUE_SIZE; i++) {
3250 skb_queue_head_init(&priv->ieee80211->skb_waitQ [i]);
3251 }
3252 for(i = 0; i < MAX_QUEUE_SIZE; i++) {
3253 skb_queue_head_init(&priv->ieee80211->skb_aggQ [i]);
3254 }
3255 for(i = 0; i < MAX_QUEUE_SIZE; i++) {
3256 skb_queue_head_init(&priv->ieee80211->skb_drv_aggQ [i]);
3257 }
3258 priv->rf_set_chan = rtl8192_phy_SwChnl;
3259}
3260
3261//init lock here
3262static void rtl8192_init_priv_lock(struct r8192_priv* priv)
3263{
3264 spin_lock_init(&priv->tx_lock);
3265 spin_lock_init(&priv->irq_lock);//added by thomas
3266 //spin_lock_init(&priv->rf_lock);//use rf_sem, or will crash in some OS.
3267 sema_init(&priv->wx_sem,1);
3268 sema_init(&priv->rf_sem,1);
3269 spin_lock_init(&priv->ps_lock);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003270 mutex_init(&priv->mutex);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003271}
3272
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003273extern void rtl819x_watchdog_wqcallback(struct work_struct *work);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003274
3275void rtl8192_irq_rx_tasklet(struct r8192_priv *priv);
3276//init tasklet and wait_queue here. only 2.6 above kernel is considered
3277#define DRV_NAME "wlan0"
3278static void rtl8192_init_priv_task(struct net_device* dev)
3279{
3280 struct r8192_priv *priv = ieee80211_priv(dev);
3281
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003282#ifdef PF_SYNCTHREAD
3283 priv->priv_wq = create_workqueue(DRV_NAME,0);
3284#else
3285 priv->priv_wq = create_workqueue(DRV_NAME);
3286#endif
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003287
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003288 INIT_WORK(&priv->reset_wq, rtl8192_restart);
3289
3290 //INIT_DELAYED_WORK(&priv->watch_dog_wq, hal_dm_watchdog);
3291 INIT_DELAYED_WORK(&priv->watch_dog_wq, rtl819x_watchdog_wqcallback);
3292 INIT_DELAYED_WORK(&priv->txpower_tracking_wq, dm_txpower_trackingcallback);
3293// INIT_DELAYED_WORK(&priv->gpio_change_rf_wq, dm_gpio_change_rf_callback);
3294 INIT_DELAYED_WORK(&priv->rfpath_check_wq, dm_rf_pathcheck_workitemcallback);
3295 INIT_DELAYED_WORK(&priv->update_beacon_wq, rtl8192_update_beacon);
3296 INIT_DELAYED_WORK(&priv->initialgain_operate_wq, InitialGainOperateWorkItemCallBack);
3297 //INIT_WORK(&priv->SwChnlWorkItem, rtl8192_SwChnl_WorkItem);
3298 //INIT_WORK(&priv->SetBWModeWorkItem, rtl8192_SetBWModeWorkItem);
3299 INIT_WORK(&priv->qos_activate, rtl8192_qos_activate);
3300 INIT_DELAYED_WORK(&priv->ieee80211->hw_wakeup_wq,(void*) rtl8192_hw_wakeup_wq);
3301 INIT_DELAYED_WORK(&priv->ieee80211->hw_sleep_wq,(void*) rtl8192_hw_sleep_wq);
3302
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003303 tasklet_init(&priv->irq_rx_tasklet,
3304 (void(*)(unsigned long))rtl8192_irq_rx_tasklet,
3305 (unsigned long)priv);
3306}
3307
3308static void rtl8192_get_eeprom_size(struct net_device* dev)
3309{
3310 u16 curCR = 0;
3311 struct r8192_priv *priv = ieee80211_priv(dev);
3312 RT_TRACE(COMP_EPROM, "===========>%s()\n", __FUNCTION__);
3313 curCR = read_nic_word_E(dev,EPROM_CMD);
3314 RT_TRACE(COMP_EPROM, "read from Reg EPROM_CMD(%x):%x\n", EPROM_CMD, curCR);
3315 //whether need I consider BIT5?
3316 priv->epromtype = (curCR & Cmd9346CR_9356SEL) ? EPROM_93c56 : EPROM_93c46;
3317 RT_TRACE(COMP_EPROM, "<===========%s(), epromtype:%d\n", __FUNCTION__, priv->epromtype);
3318}
3319
3320//used to swap endian. as ntohl & htonl are not neccessary to swap endian, so use this instead.
3321static inline u16 endian_swap(u16* data)
3322{
3323 u16 tmp = *data;
3324 *data = (tmp >> 8) | (tmp << 8);
3325 return *data;
3326}
3327
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003328u8 rtl8192SU_UsbOptionToEndPointNumber(u8 UsbOption)
3329{
3330 u8 nEndPoint = 0;
3331 switch(UsbOption)
3332 {
3333 case 0:
3334 nEndPoint = 6;
3335 break;
3336 case 1:
3337 nEndPoint = 11;
3338 break;
3339 case 2:
3340 nEndPoint = 4;
3341 break;
3342 default:
3343 RT_TRACE(COMP_INIT, "UsbOptionToEndPointNumber(): Invalid UsbOption(%#x)\n", UsbOption);
3344 break;
3345 }
3346 return nEndPoint;
3347}
3348
3349u8 rtl8192SU_BoardTypeToRFtype(struct net_device* dev, u8 Boardtype)
3350{
3351 u8 RFtype = RF_1T2R;
3352
3353 switch(Boardtype)
3354 {
3355 case 0:
3356 RFtype = RF_1T1R;
3357 break;
3358 case 1:
3359 RFtype = RF_1T2R;
3360 break;
3361 case 2:
3362 RFtype = RF_2T2R;
3363 break;
3364 case 3:
3365 RFtype = RF_2T2R_GREEN;
3366 break;
3367 default:
3368 break;
3369 }
3370
3371 return RFtype;
3372}
3373
3374//
3375// Description:
3376// Config HW adapter information into initial value.
3377//
3378// Assumption:
3379// 1. After Auto load fail(i.e, check CR9346 fail)
3380//
3381// Created by Roger, 2008.10.21.
3382//
3383void
3384rtl8192SU_ConfigAdapterInfo8192SForAutoLoadFail(struct net_device* dev)
3385{
3386 struct r8192_priv *priv = ieee80211_priv(dev);
3387 //u16 i,usValue;
3388 //u8 sMacAddr[6] = {0x00, 0xE0, 0x4C, 0x81, 0x92, 0x00};
3389 u8 rf_path, index; // For EEPROM/EFUSE After V0.6_1117
3390 int i;
3391
3392 RT_TRACE(COMP_INIT, "====> ConfigAdapterInfo8192SForAutoLoadFail\n");
3393
3394 write_nic_byte(dev, SYS_ISO_CTRL+1, 0xE8); // Isolation signals from Loader
3395 //PlatformStallExecution(10000);
3396 mdelay(10);
3397 write_nic_byte(dev, PMC_FSM, 0x02); // Enable Loader Data Keep
3398
3399 //RT_ASSERT(priv->AutoloadFailFlag==TRUE, ("ReadAdapterInfo8192SEEPROM(): AutoloadFailFlag !=TRUE\n"));
3400
3401 // Initialize IC Version && Channel Plan
3402 priv->eeprom_vid = 0;
3403 priv->eeprom_pid = 0;
3404 priv->card_8192_version = 0;
3405 priv->eeprom_ChannelPlan = 0;
3406 priv->eeprom_CustomerID = 0;
3407 priv->eeprom_SubCustomerID = 0;
3408 priv->bIgnoreDiffRateTxPowerOffset = false;
3409
3410 RT_TRACE(COMP_INIT, "EEPROM VID = 0x%4x\n", priv->eeprom_vid);
3411 RT_TRACE(COMP_INIT, "EEPROM PID = 0x%4x\n", priv->eeprom_pid);
3412 RT_TRACE(COMP_INIT, "EEPROM Customer ID: 0x%2x\n", priv->eeprom_CustomerID);
3413 RT_TRACE(COMP_INIT, "EEPROM SubCustomer ID: 0x%2x\n", priv->eeprom_SubCustomerID);
3414 RT_TRACE(COMP_INIT, "EEPROM ChannelPlan = 0x%4x\n", priv->eeprom_ChannelPlan);
3415 RT_TRACE(COMP_INIT, "IgnoreDiffRateTxPowerOffset = %d\n", priv->bIgnoreDiffRateTxPowerOffset);
3416
3417
3418
3419 priv->EEPROMUsbOption = EEPROM_USB_Default_OPTIONAL_FUNC;
3420 RT_TRACE(COMP_INIT, "USB Option = %#x\n", priv->EEPROMUsbOption);
3421
3422 for(i=0; i<5; i++)
3423 priv->EEPROMUsbPhyParam[i] = EEPROM_USB_Default_PHY_PARAM;
3424
3425 //RT_PRINT_DATA(COMP_INIT|COMP_EFUSE, DBG_LOUD, ("EFUSE USB PHY Param: \n"), priv->EEPROMUsbPhyParam, 5);
3426
3427 {
3428 //<Roger_Notes> In this case, we random assigh MAC address here. 2008.10.15.
3429 static u8 sMacAddr[6] = {0x00, 0xE0, 0x4C, 0x81, 0x92, 0x00};
3430 u8 i;
3431
3432 //sMacAddr[5] = (u8)GetRandomNumber(1, 254);
3433
3434 for(i = 0; i < 6; i++)
3435 dev->dev_addr[i] = sMacAddr[i];
3436 }
3437 //NicIFSetMacAddress(Adapter, Adapter->PermanentAddress);
3438 write_nic_dword(dev, IDR0, ((u32*)dev->dev_addr)[0]);
3439 write_nic_word(dev, IDR4, ((u16*)(dev->dev_addr + 4))[0]);
3440
3441 RT_TRACE(COMP_INIT, "ReadAdapterInfo8192SEFuse(), Permanent Address = %02x-%02x-%02x-%02x-%02x-%02x\n",
3442 dev->dev_addr[0], dev->dev_addr[1],
3443 dev->dev_addr[2], dev->dev_addr[3],
3444 dev->dev_addr[4], dev->dev_addr[5]);
3445
3446 priv->EEPROMBoardType = EEPROM_Default_BoardType;
3447 priv->rf_type = RF_1T2R; //RF_2T2R
3448 priv->EEPROMTxPowerDiff = EEPROM_Default_PwDiff;
3449 priv->EEPROMThermalMeter = EEPROM_Default_ThermalMeter;
3450 priv->EEPROMCrystalCap = EEPROM_Default_CrystalCap;
3451 priv->EEPROMTxPwrBase = EEPROM_Default_TxPowerBase;
3452 priv->EEPROMTSSI_A = EEPROM_Default_TSSI;
3453 priv->EEPROMTSSI_B = EEPROM_Default_TSSI;
3454 priv->EEPROMTxPwrTkMode = EEPROM_Default_TxPwrTkMode;
3455
3456
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003457
3458 for (rf_path = 0; rf_path < 2; rf_path++)
3459 {
3460 for (i = 0; i < 3; i++)
3461 {
3462 // Read CCK RF A & B Tx power
3463 priv->RfCckChnlAreaTxPwr[rf_path][i] =
3464 priv->RfOfdmChnlAreaTxPwr1T[rf_path][i] =
3465 priv->RfOfdmChnlAreaTxPwr2T[rf_path][i] =
3466 (u8)(EEPROM_Default_TxPower & 0xff);
3467 }
3468 }
3469
3470 for (i = 0; i < 3; i++)
3471 {
3472 //RT_TRACE((COMP_EFUSE), "CCK RF-%d CHan_Area-%d = 0x%x\n", rf_path, i,
3473 //priv->RfCckChnlAreaTxPwr[rf_path][i]);
3474 //RT_TRACE((COMP_EFUSE), "OFDM-1T RF-%d CHan_Area-%d = 0x%x\n", rf_path, i,
3475 //priv->RfOfdmChnlAreaTxPwr1T[rf_path][i]);
3476 //RT_TRACE((COMP_EFUSE), "OFDM-2T RF-%d CHan_Area-%d = 0x%x\n", rf_path, i,
3477 //priv->RfOfdmChnlAreaTxPwr2T[rf_path][i]);
3478 }
3479
3480 // Assign dedicated channel tx power
3481 for(i=0; i<14; i++) // channel 1~3 use the same Tx Power Level.
3482 {
3483 if (i < 3) // Cjanel 1-3
3484 index = 0;
3485 else if (i < 9) // Channel 4-9
3486 index = 1;
3487 else // Channel 10-14
3488 index = 2;
3489
3490 // Record A & B CCK /OFDM - 1T/2T Channel area tx power
3491 priv->RfTxPwrLevelCck[rf_path][i] =
3492 priv->RfCckChnlAreaTxPwr[rf_path][index];
3493 priv->RfTxPwrLevelOfdm1T[rf_path][i] =
3494 priv->RfOfdmChnlAreaTxPwr1T[rf_path][index];
3495 priv->RfTxPwrLevelOfdm2T[rf_path][i] =
3496 priv->RfOfdmChnlAreaTxPwr2T[rf_path][index];
3497 }
3498
3499 for(i=0; i<14; i++)
3500 {
3501 //RT_TRACE((COMP_EFUSE), "Rf-%d TxPwr CH-%d CCK OFDM_1T OFDM_2T= 0x%x/0x%x/0x%x\n",
3502 //rf_path, i, priv->RfTxPwrLevelCck[0][i],
3503 //priv->RfTxPwrLevelOfdm1T[0][i] ,
3504 //priv->RfTxPwrLevelOfdm2T[0][i] );
3505 }
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003506
3507 //
3508 // Update remained HAL variables.
3509 //
3510 priv->TSSI_13dBm = priv->EEPROMThermalMeter *100;
3511 priv->LegacyHTTxPowerDiff = priv->EEPROMTxPowerDiff;//new
3512 priv->TxPowerDiff = priv->EEPROMTxPowerDiff;
3513 //priv->AntennaTxPwDiff[0] = (priv->EEPROMTxPowerDiff & 0xf);// Antenna B gain offset to antenna A, bit0~3
3514 //priv->AntennaTxPwDiff[1] = ((priv->EEPROMTxPowerDiff & 0xf0)>>4);// Antenna C gain offset to antenna A, bit4~7
3515 priv->CrystalCap = priv->EEPROMCrystalCap; // CrystalCap, bit12~15
3516 priv->ThermalMeter[0] = priv->EEPROMThermalMeter;// ThermalMeter, bit0~3 for RFIC1, bit4~7 for RFIC2
3517 priv->LedStrategy = SW_LED_MODE0;
3518
3519 init_rate_adaptive(dev);
3520
3521 RT_TRACE(COMP_INIT, "<==== ConfigAdapterInfo8192SForAutoLoadFail\n");
3522
3523}
3524
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003525//
3526// Description:
3527// Read HW adapter information by E-Fuse or EEPROM according CR9346 reported.
3528//
3529// Assumption:
3530// 1. CR9346 regiser has verified.
3531// 2. PASSIVE_LEVEL (USB interface)
3532//
3533// Created by Roger, 2008.10.21.
3534//
3535void
3536rtl8192SU_ReadAdapterInfo8192SUsb(struct net_device* dev)
3537{
3538 struct r8192_priv *priv = ieee80211_priv(dev);
3539 u16 i,usValue;
3540 u8 tmpU1b, tempval;
3541 u16 EEPROMId;
3542 u8 hwinfo[HWSET_MAX_SIZE_92S];
3543 u8 rf_path, index; // For EEPROM/EFUSE After V0.6_1117
3544
3545
3546 RT_TRACE(COMP_INIT, "====> ReadAdapterInfo8192SUsb\n");
3547
3548 //
3549 // <Roger_Note> The following operation are prevent Efuse leakage by turn on 2.5V.
3550 // 2008.11.25.
3551 //
3552 tmpU1b = read_nic_byte(dev, EFUSE_TEST+3);
3553 write_nic_byte(dev, EFUSE_TEST+3, tmpU1b|0x80);
3554 //PlatformStallExecution(1000);
3555 mdelay(10);
3556 write_nic_byte(dev, EFUSE_TEST+3, (tmpU1b&(~BIT7)));
3557
3558 // Retrieve Chip version.
3559 priv->card_8192_version = (VERSION_8192S)((read_nic_dword(dev, PMC_FSM)>>16)&0xF);
3560 RT_TRACE(COMP_INIT, "Chip Version ID: 0x%2x\n", priv->card_8192_version);
3561
3562 switch(priv->card_8192_version)
3563 {
3564 case 0:
3565 RT_TRACE(COMP_INIT, "Chip Version ID: VERSION_8192S_ACUT.\n");
3566 break;
3567 case 1:
3568 RT_TRACE(COMP_INIT, "Chip Version ID: VERSION_8192S_BCUT.\n");
3569 break;
3570 case 2:
3571 RT_TRACE(COMP_INIT, "Chip Version ID: VERSION_8192S_CCUT.\n");
3572 break;
3573 default:
3574 RT_TRACE(COMP_INIT, "Unknown Chip Version!!\n");
3575 priv->card_8192_version = VERSION_8192S_BCUT;
3576 break;
3577 }
3578
3579 //if (IS_BOOT_FROM_EEPROM(Adapter))
3580 if(priv->EepromOrEfuse)
3581 { // Read frin EEPROM
3582 write_nic_byte(dev, SYS_ISO_CTRL+1, 0xE8); // Isolation signals from Loader
3583 //PlatformStallExecution(10000);
3584 mdelay(10);
3585 write_nic_byte(dev, PMC_FSM, 0x02); // Enable Loader Data Keep
3586 // Read all Content from EEPROM or EFUSE.
3587 for(i = 0; i < HWSET_MAX_SIZE_92S; i += 2)
3588 {
3589 usValue = eprom_read(dev, (u16) (i>>1));
3590 *((u16*)(&hwinfo[i])) = usValue;
3591 }
3592 }
3593 else if (!(priv->EepromOrEfuse))
3594 { // Read from EFUSE
3595
3596 //
3597 // <Roger_Notes> We set Isolation signals from Loader and reset EEPROM after system resuming
3598 // from suspend mode.
3599 // 2008.10.21.
3600 //
3601 //PlatformEFIOWrite1Byte(Adapter, SYS_ISO_CTRL+1, 0xE8); // Isolation signals from Loader
3602 //PlatformStallExecution(10000);
3603 //PlatformEFIOWrite1Byte(Adapter, SYS_FUNC_EN+1, 0x40);
3604 //PlatformEFIOWrite1Byte(Adapter, SYS_FUNC_EN+1, 0x50);
3605
3606 //tmpU1b = PlatformEFIORead1Byte(Adapter, EFUSE_TEST+3);
3607 //PlatformEFIOWrite1Byte(Adapter, EFUSE_TEST+3, (tmpU1b | 0x80));
3608 //PlatformEFIOWrite1Byte(Adapter, EFUSE_TEST+3, 0x72);
3609 //PlatformEFIOWrite1Byte(Adapter, EFUSE_CLK, 0x03);
3610
3611 // Read EFUSE real map to shadow.
3612 EFUSE_ShadowMapUpdate(dev);
3613 memcpy(hwinfo, &priv->EfuseMap[EFUSE_INIT_MAP][0], HWSET_MAX_SIZE_92S);
3614 }
3615 else
3616 {
3617 RT_TRACE(COMP_INIT, "ReadAdapterInfo8192SUsb(): Invalid boot type!!\n");
3618 }
3619
3620 //YJ,test,090106
3621 //dump_buf(hwinfo,HWSET_MAX_SIZE_92S);
3622 //
3623 // <Roger_Notes> The following are EFUSE/EEPROM independent operations!!
3624 //
3625 //RT_PRINT_DATA(COMP_EFUSE, DBG_LOUD, ("MAP: \n"), hwinfo, HWSET_MAX_SIZE_92S);
3626
3627 //
3628 // <Roger_Notes> Event though CR9346 regiser can verify whether Autoload is success or not, but we still
3629 // double check ID codes for 92S here(e.g., due to HW GPIO polling fail issue).
3630 // 2008.10.21.
3631 //
3632 EEPROMId = *((u16 *)&hwinfo[0]);
3633
3634 if( EEPROMId != RTL8190_EEPROM_ID )
3635 {
3636 RT_TRACE(COMP_INIT, "ID(%#x) is invalid!!\n", EEPROMId);
3637 priv->bTXPowerDataReadFromEEPORM = FALSE;
3638 priv->AutoloadFailFlag=TRUE;
3639 }
3640 else
3641 {
3642 priv->AutoloadFailFlag=FALSE;
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003643 priv->bTXPowerDataReadFromEEPORM = TRUE;
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003644 }
3645 // Read IC Version && Channel Plan
3646 if(!priv->AutoloadFailFlag)
3647 {
3648 // VID, PID
3649 priv->eeprom_vid = *(u16 *)&hwinfo[EEPROM_VID];
3650 priv->eeprom_pid = *(u16 *)&hwinfo[EEPROM_PID];
3651 priv->bIgnoreDiffRateTxPowerOffset = false; //cosa for test
3652
3653
3654 // EEPROM Version ID, Channel plan
3655 priv->EEPROMVersion = *(u8 *)&hwinfo[EEPROM_Version];
3656 priv->eeprom_ChannelPlan = *(u8 *)&hwinfo[EEPROM_ChannelPlan];
3657
3658 // Customer ID, 0x00 and 0xff are reserved for Realtek.
3659 priv->eeprom_CustomerID = *(u8 *)&hwinfo[EEPROM_CustomID];
3660 priv->eeprom_SubCustomerID = *(u8 *)&hwinfo[EEPROM_SubCustomID];
3661 }
3662 else
3663 {
3664 //priv->eeprom_vid = 0;
3665 //priv->eeprom_pid = 0;
3666 //priv->EEPROMVersion = 0;
3667 //priv->eeprom_ChannelPlan = 0;
3668 //priv->eeprom_CustomerID = 0;
3669 //priv->eeprom_SubCustomerID = 0;
3670
3671 rtl8192SU_ConfigAdapterInfo8192SForAutoLoadFail(dev);
3672 return;
3673 }
3674
3675
3676 RT_TRACE(COMP_INIT, "EEPROM Id = 0x%4x\n", EEPROMId);
3677 RT_TRACE(COMP_INIT, "EEPROM VID = 0x%4x\n", priv->eeprom_vid);
3678 RT_TRACE(COMP_INIT, "EEPROM PID = 0x%4x\n", priv->eeprom_pid);
3679 RT_TRACE(COMP_INIT, "EEPROM Version ID: 0x%2x\n", priv->EEPROMVersion);
3680 RT_TRACE(COMP_INIT, "EEPROM Customer ID: 0x%2x\n", priv->eeprom_CustomerID);
3681 RT_TRACE(COMP_INIT, "EEPROM SubCustomer ID: 0x%2x\n", priv->eeprom_SubCustomerID);
3682 RT_TRACE(COMP_INIT, "EEPROM ChannelPlan = 0x%4x\n", priv->eeprom_ChannelPlan);
3683 RT_TRACE(COMP_INIT, "bIgnoreDiffRateTxPowerOffset = %d\n", priv->bIgnoreDiffRateTxPowerOffset);
3684
3685
3686 // Read USB optional function.
3687 if(!priv->AutoloadFailFlag)
3688 {
3689 priv->EEPROMUsbOption = *(u8 *)&hwinfo[EEPROM_USB_OPTIONAL];
3690 }
3691 else
3692 {
3693 priv->EEPROMUsbOption = EEPROM_USB_Default_OPTIONAL_FUNC;
3694 }
3695
3696
3697 priv->EEPROMUsbEndPointNumber = rtl8192SU_UsbOptionToEndPointNumber((priv->EEPROMUsbOption&EEPROM_EP_NUMBER)>>3);
3698
3699 RT_TRACE(COMP_INIT, "USB Option = %#x\n", priv->EEPROMUsbOption);
3700 RT_TRACE(COMP_INIT, "EndPoint Number = %#x\n", priv->EEPROMUsbEndPointNumber);
3701
3702#ifdef TO_DO_LIST
3703 //
3704 // Decide CustomerID according to VID/DID or EEPROM
3705 //
3706 switch(pHalData->EEPROMCustomerID)
3707 {
3708 case EEPROM_CID_ALPHA:
3709 pMgntInfo->CustomerID = RT_CID_819x_ALPHA;
3710 break;
3711
3712 case EEPROM_CID_CAMEO:
3713 pMgntInfo->CustomerID = RT_CID_819x_CAMEO;
3714 break;
3715
3716 case EEPROM_CID_SITECOM:
3717 pMgntInfo->CustomerID = RT_CID_819x_Sitecom;
3718 RT_TRACE(COMP_INIT, DBG_LOUD, ("CustomerID = 0x%4x\n", pMgntInfo->CustomerID));
3719
3720 break;
3721
3722 case EEPROM_CID_WHQL:
3723 Adapter->bInHctTest = TRUE;
3724
3725 pMgntInfo->bSupportTurboMode = FALSE;
3726 pMgntInfo->bAutoTurboBy8186 = FALSE;
3727
3728 pMgntInfo->PowerSaveControl.bInactivePs = FALSE;
3729 pMgntInfo->PowerSaveControl.bIPSModeBackup = FALSE;
3730 pMgntInfo->PowerSaveControl.bLeisurePs = FALSE;
3731 pMgntInfo->keepAliveLevel = 0;
3732 break;
3733
3734 default:
3735 pMgntInfo->CustomerID = RT_CID_DEFAULT;
3736 break;
3737
3738 }
3739
3740 //
3741 // Led mode
3742 //
3743 switch(pMgntInfo->CustomerID)
3744 {
3745 case RT_CID_DEFAULT:
3746 case RT_CID_819x_ALPHA:
3747 pHalData->LedStrategy = SW_LED_MODE1;
3748 pHalData->bRegUseLed = TRUE;
3749 pHalData->SwLed1.bLedOn = TRUE;
3750 break;
3751 case RT_CID_819x_CAMEO:
3752 pHalData->LedStrategy = SW_LED_MODE1;
3753 pHalData->bRegUseLed = TRUE;
3754 break;
3755
3756 case RT_CID_819x_Sitecom:
3757 pHalData->LedStrategy = SW_LED_MODE2;
3758 pHalData->bRegUseLed = TRUE;
3759 break;
3760
3761 default:
3762 pHalData->LedStrategy = SW_LED_MODE0;
3763 break;
3764 }
3765#endif
3766
3767 // Read USB PHY parameters.
3768 for(i=0; i<5; i++)
3769 priv->EEPROMUsbPhyParam[i] = *(u8 *)&hwinfo[EEPROM_USB_PHY_PARA1+i];
3770
3771 //RT_PRINT_DATA(COMP_EFUSE, DBG_LOUD, ("USB PHY Param: \n"), pHalData->EEPROMUsbPhyParam, 5);
3772
3773
3774 //Read Permanent MAC address
3775 for(i=0; i<6; i++)
3776 dev->dev_addr[i] = *(u8 *)&hwinfo[EEPROM_NODE_ADDRESS_BYTE_0+i];
3777
3778 //NicIFSetMacAddress(Adapter, Adapter->PermanentAddress);
3779 write_nic_dword(dev, IDR0, ((u32*)dev->dev_addr)[0]);
3780 write_nic_word(dev, IDR4, ((u16*)(dev->dev_addr + 4))[0]);
3781
3782 RT_TRACE(COMP_INIT, "ReadAdapterInfo8192SEFuse(), Permanent Address = %02x-%02x-%02x-%02x-%02x-%02x\n",
3783 dev->dev_addr[0], dev->dev_addr[1],
3784 dev->dev_addr[2], dev->dev_addr[3],
3785 dev->dev_addr[4], dev->dev_addr[5]);
3786
3787 //
3788 // Get CustomerID(Boad Type)
3789 // i.e., 0x0: RTL8188SU, 0x1: RTL8191SU, 0x2: RTL8192SU, 0x3: RTL8191GU.
3790 // Others: Reserved. Default is 0x2: RTL8192SU.
3791 //
3792 //if(!priv->AutoloadFailFlag)
3793 //{
3794 priv->EEPROMBoardType = *(u8 *)&hwinfo[EEPROM_BoardType];
3795 priv->rf_type = rtl8192SU_BoardTypeToRFtype(dev, priv->EEPROMBoardType);
3796 //}
3797 //else
3798 //{
3799 // priv->EEPROMBoardType = EEPROM_Default_BoardType;
3800 // priv->rf_type = RF_1T2R;
3801 //}
3802
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003803 priv->rf_chip = RF_6052;
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003804
3805 priv->rf_chip = RF_6052;//lzm test
3806 RT_TRACE(COMP_INIT, "BoardType = 0x%2x\n", priv->EEPROMBoardType);
3807 RT_TRACE(COMP_INIT, "RF_Type = 0x%2x\n", priv->rf_type);
3808
3809 //
3810 // Read antenna tx power offset of B/C/D to A from EEPROM
3811 // and read ThermalMeter from EEPROM
3812 //
3813 //if(!priv->AutoloadFailFlag)
3814 {
3815 priv->EEPROMTxPowerDiff = *(u8 *)&hwinfo[EEPROM_PwDiff];
3816 priv->EEPROMThermalMeter = *(u8 *)&hwinfo[EEPROM_ThermalMeter];
3817 }
3818 //else
3819 //{
3820 // priv->EEPROMTxPowerDiff = EEPROM_Default_PwDiff;
3821 // priv->EEPROMThermalMeter = EEPROM_Default_ThermalMeter;
3822 //}
3823
3824 RT_TRACE(COMP_INIT, "PwDiff = %#x\n", priv->EEPROMTxPowerDiff);
3825 RT_TRACE(COMP_INIT, "ThermalMeter = %#x\n", priv->EEPROMThermalMeter);
3826
3827 //
3828 // Read Tx Power gain offset of legacy OFDM to HT rate.
3829 // Read CrystalCap from EEPROM
3830 //
3831 //if(!priv->AutoloadFailFlag)
3832 {
3833 priv->EEPROMCrystalCap = *(u8 *)&hwinfo[EEPROM_CrystalCap];
3834 }
3835 //else
3836 //{
3837 // priv->EEPROMCrystalCap = EEPROM_Default_CrystalCap;
3838 //}
3839
3840 RT_TRACE(COMP_INIT, "CrystalCap = %#x\n", priv->EEPROMCrystalCap);
3841
3842 //
3843 // Get Tx Power Base.
3844 //
3845 //if(!priv->AutoloadFailFlag)
3846 {
3847 priv->EEPROMTxPwrBase = *(u8 *)&hwinfo[EEPROM_TxPowerBase];
3848 }
3849 //else
3850 //{
3851 // priv->EEPROMTxPwrBase = EEPROM_Default_TxPowerBase;
3852 //}
3853
3854 RT_TRACE(COMP_INIT, "TxPwrBase = %#x\n", priv->EEPROMTxPwrBase);
3855
3856
3857 //
3858 // Get TSSI value for each path.
3859 //
3860 //if(!priv->AutoloadFailFlag)
3861 {
3862 priv->EEPROMTSSI_A = *(u8 *)&hwinfo[EEPROM_TSSI_A];
3863 priv->EEPROMTSSI_B = *(u8 *)&hwinfo[EEPROM_TSSI_B];
3864 }
3865 //else
3866 //{ // Default setting for Empty EEPROM
3867 // priv->EEPROMTSSI_A = EEPROM_Default_TSSI;
3868 // priv->EEPROMTSSI_B = EEPROM_Default_TSSI;
3869 //}
3870
3871 RT_TRACE(COMP_INIT, "TSSI_A = %#x, TSSI_B = %#x\n", priv->EEPROMTSSI_A, priv->EEPROMTSSI_B);
3872
3873 //
3874 // Get Tx Power tracking mode.
3875 //
3876 //if(!priv->AutoloadFailFlag)
3877 {
3878 priv->EEPROMTxPwrTkMode = *(u8 *)&hwinfo[EEPROM_TxPwTkMode];
3879 }
3880
3881 RT_TRACE(COMP_INIT, "TxPwrTkMod = %#x\n", priv->EEPROMTxPwrTkMode);
3882
3883
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003884 {
3885 //
3886 // Buffer TxPwIdx(i.e., from offset 0x55~0x66, total 18Bytes)
3887 // Update CCK, OFDM (1T/2T)Tx Power Index from above buffer.
3888 //
3889
3890 //
3891 // Get Tx Power Level by Channel
3892 //
3893 //if(!priv->AutoloadFailFlag)
3894 {
3895 // Read Tx power of Channel 1 ~ 14 from EFUSE.
3896 // 92S suupport RF A & B
3897 for (rf_path = 0; rf_path < 2; rf_path++)
3898 {
3899 for (i = 0; i < 3; i++)
3900 {
3901 // Read CCK RF A & B Tx power
3902 priv->RfCckChnlAreaTxPwr[rf_path][i] =
3903 hwinfo[EEPROM_TxPwIndex+rf_path*3+i];
3904
3905 // Read OFDM RF A & B Tx power for 1T
3906 priv->RfOfdmChnlAreaTxPwr1T[rf_path][i] =
3907 hwinfo[EEPROM_TxPwIndex+6+rf_path*3+i];
3908
3909 // Read OFDM RF A & B Tx power for 2T
3910 priv->RfOfdmChnlAreaTxPwr2T[rf_path][i] =
3911 hwinfo[EEPROM_TxPwIndex+12+rf_path*3+i];
3912 }
3913 }
3914
3915 }
3916//
3917 // Update Tx Power HAL variables.
3918//
3919 for (rf_path = 0; rf_path < 2; rf_path++)
3920 {
3921 for (i = 0; i < 3; i++)
3922 {
3923 RT_TRACE((COMP_INIT), "CCK RF-%d CHan_Area-%d = 0x%x\n", rf_path, i,
3924 priv->RfCckChnlAreaTxPwr[rf_path][i]);
3925 RT_TRACE((COMP_INIT), "OFDM-1T RF-%d CHan_Area-%d = 0x%x\n", rf_path, i,
3926 priv->RfOfdmChnlAreaTxPwr1T[rf_path][i]);
3927 RT_TRACE((COMP_INIT), "OFDM-2T RF-%d CHan_Area-%d = 0x%x\n", rf_path, i, priv->RfOfdmChnlAreaTxPwr2T[rf_path][i]);
3928 }
3929
3930 // Assign dedicated channel tx power
3931 for(i=0; i<14; i++) // channel 1~3 use the same Tx Power Level.
3932 {
3933 if (i < 3) // Cjanel 1-3
3934 index = 0;
3935 else if (i < 9) // Channel 4-9
3936 index = 1;
3937 else // Channel 10-14
3938 index = 2;
3939
3940 // Record A & B CCK /OFDM - 1T/2T Channel area tx power
3941 priv->RfTxPwrLevelCck[rf_path][i] =
3942 priv->RfCckChnlAreaTxPwr[rf_path][index];
3943 priv->RfTxPwrLevelOfdm1T[rf_path][i] =
3944 priv->RfOfdmChnlAreaTxPwr1T[rf_path][index];
3945 priv->RfTxPwrLevelOfdm2T[rf_path][i] =
3946 priv->RfOfdmChnlAreaTxPwr2T[rf_path][index];
3947 if (rf_path == 0)
3948 {
3949 priv->TxPowerLevelOFDM24G[i] = priv->RfTxPwrLevelOfdm1T[rf_path][i] ;
3950 priv->TxPowerLevelCCK[i] = priv->RfTxPwrLevelCck[rf_path][i];
3951 }
3952 }
3953
3954 for(i=0; i<14; i++)
3955 {
3956 RT_TRACE((COMP_INIT),
3957 "Rf-%d TxPwr CH-%d CCK OFDM_1T OFDM_2T= 0x%x/0x%x/0x%x\n",
3958 rf_path, i, priv->RfTxPwrLevelCck[rf_path][i],
3959 priv->RfTxPwrLevelOfdm1T[rf_path][i] ,
3960 priv->RfTxPwrLevelOfdm2T[rf_path][i] );
3961 }
3962 }
3963 }
3964
3965 //
3966 // 2009/02/09 Cosa add for new EEPROM format
3967 //
3968 for(i=0; i<14; i++) // channel 1~3 use the same Tx Power Level.
3969 {
3970 // Read tx power difference between HT OFDM 20/40 MHZ
3971 if (i < 3) // Cjanel 1-3
3972 index = 0;
3973 else if (i < 9) // Channel 4-9
3974 index = 1;
3975 else // Channel 10-14
3976 index = 2;
3977
3978 tempval = (*(u8 *)&hwinfo[EEPROM_TX_PWR_HT20_DIFF+index])&0xff;
3979 priv->TxPwrHt20Diff[RF90_PATH_A][i] = (tempval&0xF);
3980 priv->TxPwrHt20Diff[RF90_PATH_B][i] = ((tempval>>4)&0xF);
3981
3982 // Read OFDM<->HT tx power diff
3983 if (i < 3) // Cjanel 1-3
3984 tempval = (*(u8 *)&hwinfo[EEPROM_TX_PWR_OFDM_DIFF])&0xff;
3985 else if (i < 9) // Channel 4-9
3986 tempval = (*(u8 *)&hwinfo[EEPROM_PwDiff])&0xff;
3987 else // Channel 10-14
3988 tempval = (*(u8 *)&hwinfo[EEPROM_TX_PWR_OFDM_DIFF+1])&0xff;
3989
3990 //cosa tempval = (*(u1Byte *)&hwinfo[EEPROM_TX_PWR_OFDM_DIFF+index])&0xff;
3991 priv->TxPwrLegacyHtDiff[RF90_PATH_A][i] = (tempval&0xF);
3992 priv->TxPwrLegacyHtDiff[RF90_PATH_B][i] = ((tempval>>4)&0xF);
3993
3994 //
3995 // Read Band Edge tx power offset and check if user enable the ability
3996 //
3997 // HT 40 band edge channel
3998 tempval = (*(u8 *)&hwinfo[EEPROM_TX_PWR_BAND_EDGE])&0xff;
3999 priv->TxPwrbandEdgeHt40[RF90_PATH_A][0] = (tempval&0xF); // Band edge low channel
4000 priv->TxPwrbandEdgeHt40[RF90_PATH_A][1] = ((tempval>>4)&0xF); // Band edge high channel
4001 tempval = (*(u8 *)&hwinfo[EEPROM_TX_PWR_BAND_EDGE+1])&0xff;
4002 priv->TxPwrbandEdgeHt40[RF90_PATH_B][0] = (tempval&0xF); // Band edge low channel
4003 priv->TxPwrbandEdgeHt40[RF90_PATH_B][1] = ((tempval>>4)&0xF); // Band edge high channel
4004 // HT 20 band edge channel
4005 tempval = (*(u8 *)&hwinfo[EEPROM_TX_PWR_BAND_EDGE+2])&0xff;
4006 priv->TxPwrbandEdgeHt20[RF90_PATH_A][0] = (tempval&0xF); // Band edge low channel
4007 priv->TxPwrbandEdgeHt20[RF90_PATH_A][1] = ((tempval>>4)&0xF); // Band edge high channel
4008 tempval = (*(u8 *)&hwinfo[EEPROM_TX_PWR_BAND_EDGE+3])&0xff;
4009 priv->TxPwrbandEdgeHt20[RF90_PATH_B][0] = (tempval&0xF); // Band edge low channel
4010 priv->TxPwrbandEdgeHt20[RF90_PATH_B][1] = ((tempval>>4)&0xF); // Band edge high channel
4011 // OFDM band edge channel
4012 tempval = (*(u8 *)&hwinfo[EEPROM_TX_PWR_BAND_EDGE+4])&0xff;
4013 priv->TxPwrbandEdgeLegacyOfdm[RF90_PATH_A][0] = (tempval&0xF); // Band edge low channel
4014 priv->TxPwrbandEdgeLegacyOfdm[RF90_PATH_A][1] = ((tempval>>4)&0xF); // Band edge high channel
4015 tempval = (*(u8 *)&hwinfo[EEPROM_TX_PWR_BAND_EDGE+5])&0xff;
4016 priv->TxPwrbandEdgeLegacyOfdm[RF90_PATH_B][0] = (tempval&0xF); // Band edge low channel
4017 priv->TxPwrbandEdgeLegacyOfdm[RF90_PATH_B][1] = ((tempval>>4)&0xF); // Band edge high channel
4018
4019 priv->TxPwrbandEdgeFlag = (*(u8 *)&hwinfo[TX_PWR_BAND_EDGE_CHK]);
4020 }
4021
4022 for(i=0; i<14; i++)
4023 RT_TRACE(COMP_INIT, "RF-A Ht20 to HT40 Diff[%d] = 0x%x\n", i, priv->TxPwrHt20Diff[RF90_PATH_A][i]);
4024 for(i=0; i<14; i++)
4025 RT_TRACE(COMP_INIT, "RF-A Legacy to Ht40 Diff[%d] = 0x%x\n", i, priv->TxPwrLegacyHtDiff[RF90_PATH_A][i]);
4026 for(i=0; i<14; i++)
4027 RT_TRACE(COMP_INIT, "RF-B Ht20 to HT40 Diff[%d] = 0x%x\n", i, priv->TxPwrHt20Diff[RF90_PATH_B][i]);
4028 for(i=0; i<14; i++)
4029 RT_TRACE(COMP_INIT, "RF-B Legacy to HT40 Diff[%d] = 0x%x\n", i, priv->TxPwrLegacyHtDiff[RF90_PATH_B][i]);
4030 RT_TRACE(COMP_INIT, "RF-A HT40 band-edge low/high power diff = 0x%x/0x%x\n",
4031 priv->TxPwrbandEdgeHt40[RF90_PATH_A][0],
4032 priv->TxPwrbandEdgeHt40[RF90_PATH_A][1]);
4033 RT_TRACE((COMP_INIT&COMP_DBG), "RF-B HT40 band-edge low/high power diff = 0x%x/0x%x\n",
4034 priv->TxPwrbandEdgeHt40[RF90_PATH_B][0],
4035 priv->TxPwrbandEdgeHt40[RF90_PATH_B][1]);
4036
4037 RT_TRACE((COMP_INIT&COMP_DBG), "RF-A HT20 band-edge low/high power diff = 0x%x/0x%x\n",
4038 priv->TxPwrbandEdgeHt20[RF90_PATH_A][0],
4039 priv->TxPwrbandEdgeHt20[RF90_PATH_A][1]);
4040 RT_TRACE((COMP_INIT&COMP_DBG), "RF-B HT20 band-edge low/high power diff = 0x%x/0x%x\n",
4041 priv->TxPwrbandEdgeHt20[RF90_PATH_B][0],
4042 priv->TxPwrbandEdgeHt20[RF90_PATH_B][1]);
4043
4044 RT_TRACE((COMP_INIT&COMP_DBG), "RF-A OFDM band-edge low/high power diff = 0x%x/0x%x\n",
4045 priv->TxPwrbandEdgeLegacyOfdm[RF90_PATH_A][0],
4046 priv->TxPwrbandEdgeLegacyOfdm[RF90_PATH_A][1]);
4047 RT_TRACE((COMP_INIT&COMP_DBG), "RF-B OFDM band-edge low/high power diff = 0x%x/0x%x\n",
4048 priv->TxPwrbandEdgeLegacyOfdm[RF90_PATH_B][0],
4049 priv->TxPwrbandEdgeLegacyOfdm[RF90_PATH_B][1]);
4050 RT_TRACE((COMP_INIT&COMP_DBG), "Band-edge enable flag = %d\n", priv->TxPwrbandEdgeFlag);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07004051
4052 //
4053 // Update remained HAL variables.
4054 //
4055 priv->TSSI_13dBm = priv->EEPROMThermalMeter *100;
4056 priv->LegacyHTTxPowerDiff = priv->EEPROMTxPowerDiff;
4057 priv->TxPowerDiff = priv->EEPROMTxPowerDiff;
4058 //priv->AntennaTxPwDiff[0] = (priv->EEPROMTxPowerDiff & 0xf);// Antenna B gain offset to antenna A, bit[3:0]
4059 //priv->AntennaTxPwDiff[1] = ((priv->EEPROMTxPowerDiff & 0xf0)>>4);// Antenna C gain offset to antenna A, bit[7:4]
4060 priv->CrystalCap = priv->EEPROMCrystalCap; // CrystalCap, bit[15:12]
4061 priv->ThermalMeter[0] = (priv->EEPROMThermalMeter&0x1f);// ThermalMeter, bit0~3 for RFIC1, bit4~7 for RFIC2
4062 priv->LedStrategy = SW_LED_MODE0;
4063
4064 init_rate_adaptive(dev);
4065
4066 RT_TRACE(COMP_INIT, "<==== ReadAdapterInfo8192SUsb\n");
4067
4068 //return RT_STATUS_SUCCESS;
4069}
4070
4071
4072//
4073// Description:
4074// Read HW adapter information by E-Fuse or EEPROM according CR9346 reported.
4075//
4076// Assumption:
4077// 1. CR9346 regiser has verified.
4078// 2. PASSIVE_LEVEL (USB interface)
4079//
4080// Created by Roger, 2008.10.21.
4081//
4082static void rtl8192SU_read_eeprom_info(struct net_device *dev)
4083{
4084 struct r8192_priv *priv = ieee80211_priv(dev);
4085 u8 tmpU1b;
4086
4087 RT_TRACE(COMP_INIT, "====> ReadAdapterInfo8192SUsb\n");
4088
4089 // Retrieve Chip version.
4090 priv->card_8192_version = (VERSION_8192S)((read_nic_dword(dev, PMC_FSM)>>16)&0xF);
4091 RT_TRACE(COMP_INIT, "Chip Version ID: 0x%2x\n", priv->card_8192_version);
4092
4093 tmpU1b = read_nic_byte(dev, EPROM_CMD);//CR9346
4094
4095 // To check system boot selection.
4096 if (tmpU1b & CmdEERPOMSEL)
4097 {
4098 RT_TRACE(COMP_INIT, "Boot from EEPROM\n");
4099 priv->EepromOrEfuse = TRUE;
4100 }
4101 else
4102 {
4103 RT_TRACE(COMP_INIT, "Boot from EFUSE\n");
4104 priv->EepromOrEfuse = FALSE;
4105 }
4106
4107 // To check autoload success or not.
4108 if (tmpU1b & CmdEEPROM_En)
4109 {
4110 RT_TRACE(COMP_INIT, "Autoload OK!!\n");
4111 priv->AutoloadFailFlag=FALSE;
4112 rtl8192SU_ReadAdapterInfo8192SUsb(dev);//eeprom or e-fuse
4113 }
4114 else
4115 { // Auto load fail.
4116 RT_TRACE(COMP_INIT, "AutoLoad Fail reported from CR9346!!\n");
4117 priv->AutoloadFailFlag=TRUE;
4118 rtl8192SU_ConfigAdapterInfo8192SForAutoLoadFail(dev);
4119
4120 //if (IS_BOOT_FROM_EFUSE(Adapter))
4121 if(!priv->EepromOrEfuse)
4122 {
4123 RT_TRACE(COMP_INIT, "Update shadow map for EFuse future use!!\n");
4124 EFUSE_ShadowMapUpdate(dev);
4125 }
4126 }
4127#ifdef TO_DO_LIST
4128 if((priv->RegChannelPlan >= RT_CHANNEL_DOMAIN_MAX) || (pHalData->EEPROMChannelPlan & EEPROM_CHANNEL_PLAN_BY_HW_MASK))
4129 {
4130 pMgntInfo->ChannelPlan = HalMapChannelPlan8192S(Adapter, (pHalData->EEPROMChannelPlan & (~(EEPROM_CHANNEL_PLAN_BY_HW_MASK))));
4131 pMgntInfo->bChnlPlanFromHW = (pHalData->EEPROMChannelPlan & EEPROM_CHANNEL_PLAN_BY_HW_MASK) ? TRUE : FALSE; // User cannot change channel plan.
4132 }
4133 else
4134 {
4135 pMgntInfo->ChannelPlan = (RT_CHANNEL_DOMAIN)pMgntInfo->RegChannelPlan;
4136 }
4137
4138 switch(pMgntInfo->ChannelPlan)
4139 {
4140 case RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN:
4141 {
4142 PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(pMgntInfo);
4143
4144 pDot11dInfo->bEnabled = TRUE;
4145 }
4146 RT_TRACE(COMP_INIT, DBG_LOUD, ("ReadAdapterInfo8187(): Enable dot11d when RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN!\n"));
4147 break;
4148 }
4149
4150 RT_TRACE(COMP_INIT, DBG_LOUD, ("RegChannelPlan(%d) EEPROMChannelPlan(%d)", pMgntInfo->RegChannelPlan, pHalData->EEPROMChannelPlan));
4151 RT_TRACE(COMP_INIT, DBG_LOUD, ("ChannelPlan = %d\n" , pMgntInfo->ChannelPlan));
4152
4153 RT_TRACE(COMP_INIT, DBG_LOUD, ("<==== ReadAdapterInfo8192S\n"));
4154#endif
4155
4156 RT_TRACE(COMP_INIT, "<==== ReadAdapterInfo8192SUsb\n");
4157
4158 //return RT_STATUS_SUCCESS;
4159}
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07004160
4161short rtl8192_get_channel_map(struct net_device * dev)
4162{
4163 struct r8192_priv *priv = ieee80211_priv(dev);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07004164 if(priv->ChannelPlan > COUNTRY_CODE_GLOBAL_DOMAIN){
4165 printk("rtl8180_init:Error channel plan! Set to default.\n");
4166 priv->ChannelPlan= 0;
4167 }
4168 RT_TRACE(COMP_INIT, "Channel plan is %d\n",priv->ChannelPlan);
4169
4170 rtl819x_set_channel_map(priv->ChannelPlan, priv);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07004171 return 0;
4172}
4173
4174short rtl8192_init(struct net_device *dev)
4175{
4176
4177 struct r8192_priv *priv = ieee80211_priv(dev);
4178
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07004179 rtl8192_init_priv_variable(dev);
4180 rtl8192_init_priv_lock(priv);
4181 rtl8192_init_priv_task(dev);
4182 rtl8192_get_eeprom_size(dev);
4183 priv->ops->rtl819x_read_eeprom_info(dev);
4184 rtl8192_get_channel_map(dev);
4185 init_hal_dm(dev);
4186 init_timer(&priv->watch_dog_timer);
4187 priv->watch_dog_timer.data = (unsigned long)dev;
4188 priv->watch_dog_timer.function = watch_dog_timer_callback;
4189
4190 //rtl8192_adapter_start(dev);
4191#ifdef DEBUG_EPROM
4192 dump_eprom(dev);
4193#endif
4194 return 0;
4195}
4196
4197/******************************************************************************
4198 *function: This function actually only set RRSR, RATR and BW_OPMODE registers
4199 * not to do all the hw config as its name says
4200 * input: net_device dev
4201 * output: none
4202 * return: none
4203 * notice: This part need to modified according to the rate set we filtered
4204 * ****************************************************************************/
4205void rtl8192_hwconfig(struct net_device* dev)
4206{
4207 u32 regRATR = 0, regRRSR = 0;
4208 u8 regBwOpMode = 0, regTmp = 0;
4209 struct r8192_priv *priv = ieee80211_priv(dev);
4210
4211// Set RRSR, RATR, and BW_OPMODE registers
4212 //
4213 switch(priv->ieee80211->mode)
4214 {
4215 case WIRELESS_MODE_B:
4216 regBwOpMode = BW_OPMODE_20MHZ;
4217 regRATR = RATE_ALL_CCK;
4218 regRRSR = RATE_ALL_CCK;
4219 break;
4220 case WIRELESS_MODE_A:
4221 regBwOpMode = BW_OPMODE_5G |BW_OPMODE_20MHZ;
4222 regRATR = RATE_ALL_OFDM_AG;
4223 regRRSR = RATE_ALL_OFDM_AG;
4224 break;
4225 case WIRELESS_MODE_G:
4226 regBwOpMode = BW_OPMODE_20MHZ;
4227 regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
4228 regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
4229 break;
4230 case WIRELESS_MODE_AUTO:
4231#ifdef TO_DO_LIST
4232 if (Adapter->bInHctTest)
4233 {
4234 regBwOpMode = BW_OPMODE_20MHZ;
4235 regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
4236 regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
4237 }
4238 else
4239#endif
4240 {
4241 regBwOpMode = BW_OPMODE_20MHZ;
4242 regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
4243 regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
4244 }
4245 break;
4246 case WIRELESS_MODE_N_24G:
4247 // It support CCK rate by default.
4248 // CCK rate will be filtered out only when associated AP does not support it.
4249 regBwOpMode = BW_OPMODE_20MHZ;
4250 regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
4251 regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
4252 break;
4253 case WIRELESS_MODE_N_5G:
4254 regBwOpMode = BW_OPMODE_5G;
4255 regRATR = RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
4256 regRRSR = RATE_ALL_OFDM_AG;
4257 break;
4258 }
4259
4260 write_nic_byte(dev, BW_OPMODE, regBwOpMode);
4261 {
4262 u32 ratr_value = 0;
4263 ratr_value = regRATR;
4264 if (priv->rf_type == RF_1T2R)
4265 {
4266 ratr_value &= ~(RATE_ALL_OFDM_2SS);
4267 }
4268 write_nic_dword(dev, RATR0, ratr_value);
4269 write_nic_byte(dev, UFWP, 1);
4270 }
4271 regTmp = read_nic_byte(dev, 0x313);
4272 regRRSR = ((regTmp) << 24) | (regRRSR & 0x00ffffff);
4273 write_nic_dword(dev, RRSR, regRRSR);
4274
4275 //
4276 // Set Retry Limit here
4277 //
4278 write_nic_word(dev, RETRY_LIMIT,
4279 priv->ShortRetryLimit << RETRY_LIMIT_SHORT_SHIFT | \
4280 priv->LongRetryLimit << RETRY_LIMIT_LONG_SHIFT);
4281 // Set Contention Window here
4282
4283 // Set Tx AGC
4284
4285 // Set Tx Antenna including Feedback control
4286
4287 // Set Auto Rate fallback control
4288
4289
4290}
4291
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07004292
4293//
4294// Description:
4295// Initial HW relted registers.
4296//
4297// Assumption:
4298// Config RTL8192S USB MAC, we should config MAC before download FW.
4299//
4300// 2008.09.03, Added by Roger.
4301//
4302static void rtl8192SU_MacConfigBeforeFwDownloadASIC(struct net_device *dev)
4303{
4304 u8 tmpU1b;// i;
4305// u16 tmpU2b;
4306// u32 tmpU4b;
4307 u8 PollingCnt = 20;
4308
4309 RT_TRACE(COMP_INIT, "--->MacConfigBeforeFwDownloadASIC()\n");
4310
4311 //2MAC Initialization for power on sequence, Revised by Roger. 2008.09.03.
4312
4313 //
4314 //<Roger_Notes> Set control path switch to HW control and reset Digital Core, CPU Core and
4315 // MAC I/O to solve FW download fail when system from resume sate.
4316 // 2008.11.04.
4317 //
4318 tmpU1b = read_nic_byte(dev, SYS_CLKR+1);
4319 if(tmpU1b & 0x80)
4320 {
4321 tmpU1b &= 0x3f;
4322 write_nic_byte(dev, SYS_CLKR+1, tmpU1b);
4323 }
4324 // Clear FW RPWM for FW control LPS. by tynli. 2009.02.23
4325 write_nic_byte(dev, RPWM, 0x0);
4326
4327 tmpU1b = read_nic_byte(dev, SYS_FUNC_EN+1);
4328 tmpU1b &= 0x73;
4329 write_nic_byte(dev, SYS_FUNC_EN+1, tmpU1b);
4330 udelay(1000);
4331
4332 //Revised POS, suggested by SD1 Alex, 2008.09.27.
4333 write_nic_byte(dev, SPS0_CTRL+1, 0x53);
4334 write_nic_byte(dev, SPS0_CTRL, 0x57);
4335
4336 //Enable AFE Macro Block's Bandgap adn Enable AFE Macro Block's Mbias
4337 tmpU1b = read_nic_byte(dev, AFE_MISC);
4338 write_nic_byte(dev, AFE_MISC, (tmpU1b|AFE_BGEN|AFE_MBEN));
4339
4340 //Enable PLL Power (LDOA15V)
4341 tmpU1b = read_nic_byte(dev, LDOA15_CTRL);
4342 write_nic_byte(dev, LDOA15_CTRL, (tmpU1b|LDA15_EN));
4343
4344 //Enable LDOV12D block
4345 tmpU1b = read_nic_byte(dev, LDOV12D_CTRL);
4346 write_nic_byte(dev, LDOV12D_CTRL, (tmpU1b|LDV12_EN));
4347
4348 //mpU1b = read_nic_byte(Adapter, SPS1_CTRL);
4349 //write_nic_byte(dev, SPS1_CTRL, (tmpU1b|SPS1_LDEN));
4350
4351 //PlatformSleepUs(2000);
4352
4353 //Enable Switch Regulator Block
4354 //tmpU1b = read_nic_byte(Adapter, SPS1_CTRL);
4355 //write_nic_byte(dev, SPS1_CTRL, (tmpU1b|SPS1_SWEN));
4356
4357 //write_nic_dword(Adapter, SPS1_CTRL, 0x00a7b267);
4358
4359 tmpU1b = read_nic_byte(dev, SYS_ISO_CTRL+1);
4360 write_nic_byte(dev, SYS_ISO_CTRL+1, (tmpU1b|0x08));
4361
4362 //Engineer Packet CP test Enable
4363 tmpU1b = read_nic_byte(dev, SYS_FUNC_EN+1);
4364 write_nic_byte(dev, SYS_FUNC_EN+1, (tmpU1b|0x20));
4365
4366 //Support 64k IMEM, suggested by SD1 Alex.
4367 tmpU1b = read_nic_byte(dev, SYS_ISO_CTRL+1);
4368 write_nic_byte(dev, SYS_ISO_CTRL+1, (tmpU1b& 0x68));
4369
4370 //Enable AFE clock
4371 tmpU1b = read_nic_byte(dev, AFE_XTAL_CTRL+1);
4372 write_nic_byte(dev, AFE_XTAL_CTRL+1, (tmpU1b& 0xfb));
4373
4374 //Enable AFE PLL Macro Block
4375 tmpU1b = read_nic_byte(dev, AFE_PLL_CTRL);
4376 write_nic_byte(dev, AFE_PLL_CTRL, (tmpU1b|0x11));
4377
4378 //Attatch AFE PLL to MACTOP/BB/PCIe Digital
4379 tmpU1b = read_nic_byte(dev, SYS_ISO_CTRL);
4380 write_nic_byte(dev, SYS_ISO_CTRL, (tmpU1b&0xEE));
4381
4382 // Switch to 40M clock
4383 write_nic_byte(dev, SYS_CLKR, 0x00);
4384
4385 //SSC Disable
4386 tmpU1b = read_nic_byte(dev, SYS_CLKR);
4387 //write_nic_byte(dev, SYS_CLKR, (tmpU1b&0x5f));
4388 write_nic_byte(dev, SYS_CLKR, (tmpU1b|0xa0));
4389
4390 //Enable MAC clock
4391 tmpU1b = read_nic_byte(dev, SYS_CLKR+1);
4392 write_nic_byte(dev, SYS_CLKR+1, (tmpU1b|0x18));
4393
4394 //Revised POS, suggested by SD1 Alex, 2008.09.27.
4395 write_nic_byte(dev, PMC_FSM, 0x02);
4396
4397 //Enable Core digital and enable IOREG R/W
4398 tmpU1b = read_nic_byte(dev, SYS_FUNC_EN+1);
4399 write_nic_byte(dev, SYS_FUNC_EN+1, (tmpU1b|0x08));
4400
4401 //Enable REG_EN
4402 tmpU1b = read_nic_byte(dev, SYS_FUNC_EN+1);
4403 write_nic_byte(dev, SYS_FUNC_EN+1, (tmpU1b|0x80));
4404
4405 //Switch the control path to FW
4406 tmpU1b = read_nic_byte(dev, SYS_CLKR+1);
4407 write_nic_byte(dev, SYS_CLKR+1, (tmpU1b|0x80)& 0xBF);
4408
4409 write_nic_byte(dev, CMDR, 0xFC);
4410 write_nic_byte(dev, CMDR+1, 0x37);
4411
4412 //Fix the RX FIFO issue(usb error), 970410
4413 tmpU1b = read_nic_byte_E(dev, 0x5c);
4414 write_nic_byte_E(dev, 0x5c, (tmpU1b|BIT7));
4415
4416 //For power save, used this in the bit file after 970621
4417 tmpU1b = read_nic_byte(dev, SYS_CLKR);
4418 write_nic_byte(dev, SYS_CLKR, tmpU1b&(~SYS_CPU_CLKSEL));
4419
4420 // Revised for 8051 ROM code wrong operation. Added by Roger. 2008.10.16.
4421 write_nic_byte_E(dev, 0x1c, 0x80);
4422
4423 //
4424 // <Roger_EXP> To make sure that TxDMA can ready to download FW.
4425 // We should reset TxDMA if IMEM RPT was not ready.
4426 // Suggested by SD1 Alex. 2008.10.23.
4427 //
4428 do
4429 {
4430 tmpU1b = read_nic_byte(dev, TCR);
4431 if((tmpU1b & TXDMA_INIT_VALUE) == TXDMA_INIT_VALUE)
4432 break;
4433 //PlatformStallExecution(5);
4434 udelay(5);
4435 }while(PollingCnt--); // Delay 1ms
4436
4437 if(PollingCnt <= 0 )
4438 {
4439 RT_TRACE(COMP_INIT, "MacConfigBeforeFwDownloadASIC(): Polling TXDMA_INIT_VALUE timeout!! Current TCR(%#x)\n", tmpU1b);
4440 tmpU1b = read_nic_byte(dev, CMDR);
4441 write_nic_byte(dev, CMDR, tmpU1b&(~TXDMA_EN));
4442 udelay(2);
4443 write_nic_byte(dev, CMDR, tmpU1b|TXDMA_EN);// Reset TxDMA
4444 }
4445
4446
4447 RT_TRACE(COMP_INIT, "<---MacConfigBeforeFwDownloadASIC()\n");
4448}
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07004449
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07004450//
4451// Description:
4452// Initial HW relted registers.
4453//
4454// Assumption:
4455// 1. This function is only invoked at driver intialization once.
4456// 2. PASSIVE LEVEL.
4457//
4458// 2008.06.10, Added by Roger.
4459//
4460static void rtl8192SU_MacConfigAfterFwDownload(struct net_device *dev)
4461{
4462 struct r8192_priv *priv = ieee80211_priv((struct net_device *)dev);
4463 //PRT_HIGH_THROUGHPUT pHTInfo = priv->ieee80211->pHTInfo;
4464 //u8 tmpU1b, RxPageCfg, i;
4465 u16 tmpU2b;
4466 u8 tmpU1b;//, i;
4467
4468
4469 RT_TRACE(COMP_INIT, "--->MacConfigAfterFwDownload()\n");
4470
4471 // Enable Tx/Rx
4472 tmpU2b = (BBRSTn|BB_GLB_RSTn|SCHEDULE_EN|MACRXEN|MACTXEN|DDMA_EN|
4473 FW2HW_EN|RXDMA_EN|TXDMA_EN|HCI_RXDMA_EN|HCI_TXDMA_EN); //3
4474 //Adapter->HalFunc.SetHwRegHandler( Adapter, HW_VAR_COMMAND, &tmpU1b );
4475 write_nic_word(dev, CMDR, tmpU2b); //LZM REGISTER COM 090305
4476
4477 // Loopback mode or not
4478 priv->LoopbackMode = RTL8192SU_NO_LOOPBACK; // Set no loopback as default.
4479 if(priv->LoopbackMode == RTL8192SU_NO_LOOPBACK)
4480 tmpU1b = LBK_NORMAL;
4481 else if (priv->LoopbackMode == RTL8192SU_MAC_LOOPBACK )
4482 tmpU1b = LBK_MAC_DLB;
4483 else
4484 RT_TRACE(COMP_INIT, "Serious error: wrong loopback mode setting\n");
4485
4486 //Adapter->HalFunc.SetHwRegHandler( Adapter, HW_VAR_LBK_MODE, &tmpU1b);
4487 write_nic_byte(dev, LBKMD_SEL, tmpU1b);
4488
4489 // Set RCR
4490 write_nic_dword(dev, RCR, priv->ReceiveConfig);
4491 RT_TRACE(COMP_INIT, "MacConfigAfterFwDownload(): Current RCR settings(%#x)\n", priv->ReceiveConfig);
4492
4493
4494 // Set RQPN
4495 //
4496 // <Roger_Notes> 2008.08.18.
4497 // 6 endpoints:
4498 // (1) Page number on CMDQ is 0x03.
4499 // (2) Page number on BCNQ, HQ and MGTQ is 0.
4500 // (3) Page number on BKQ, BEQ, VIQ and VOQ are 0x07.
4501 // (4) Page number on PUBQ is 0xdd
4502 //
4503 // 11 endpoints:
4504 // (1) Page number on CMDQ is 0x00.
4505 // (2) Page number on BCNQ is 0x02, HQ and MGTQ are 0x03.
4506 // (3) Page number on BKQ, BEQ, VIQ and VOQ are 0x07.
4507 // (4) Page number on PUBQ is 0xd8
4508 //
4509 //write_nic_dword(Adapter, 0xa0, 0x07070707); //BKQ, BEQ, VIQ and VOQ
4510 //write_nic_byte(dev, 0xa4, 0x00); // HCCAQ
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07004511
4512 // Fix the RX FIFO issue(USB error), Rivesed by Roger, 2008-06-14
4513 tmpU1b = read_nic_byte_E(dev, 0x5C);
4514 write_nic_byte_E(dev, 0x5C, tmpU1b|BIT7);
4515
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07004516 // For EFUSE init configuration.
4517 //if (IS_BOOT_FROM_EFUSE(Adapter)) // We may R/W EFUSE in EFUSE mode
4518 if (priv->bBootFromEfuse)
4519 {
4520 u8 tempval;
4521
4522 tempval = read_nic_byte(dev, SYS_ISO_CTRL+1);
4523 tempval &= 0xFE;
4524 write_nic_byte(dev, SYS_ISO_CTRL+1, tempval);
4525
4526 // Enable LDO 2.5V for write action
4527 //tempval = read_nic_byte(Adapter, EFUSE_TEST+3);
4528 //write_nic_byte(Adapter, EFUSE_TEST+3, (tempval | 0x80));
4529
4530 // Change Efuse Clock for write action
4531 //write_nic_byte(Adapter, EFUSE_CLK, 0x03);
4532
4533 // Change Program timing
4534 write_nic_byte(dev, EFUSE_CTRL+3, 0x72);
4535 //printk("!!!!!!!!!!!!!!!!!!!!!%s: write 0x33 with 0x72\n",__FUNCTION__);
4536 RT_TRACE(COMP_INIT, "EFUSE CONFIG OK\n");
4537 }
4538
4539
4540 RT_TRACE(COMP_INIT, "<---MacConfigAfterFwDownload()\n");
4541}
4542
4543void rtl8192SU_HwConfigureRTL8192SUsb(struct net_device *dev)
4544{
4545
4546 struct r8192_priv *priv = ieee80211_priv(dev);
4547 u8 regBwOpMode = 0;
4548 u32 regRATR = 0, regRRSR = 0;
4549 u8 regTmp = 0;
4550 u32 i = 0;
4551
4552 //1 This part need to modified according to the rate set we filtered!!
4553 //
4554 // Set RRSR, RATR, and BW_OPMODE registers
4555 //
4556 switch(priv->ieee80211->mode)
4557 {
4558 case WIRELESS_MODE_B:
4559 regBwOpMode = BW_OPMODE_20MHZ;
4560 regRATR = RATE_ALL_CCK;
4561 regRRSR = RATE_ALL_CCK;
4562 break;
4563 case WIRELESS_MODE_A:
4564 regBwOpMode = BW_OPMODE_5G |BW_OPMODE_20MHZ;
4565 regRATR = RATE_ALL_OFDM_AG;
4566 regRRSR = RATE_ALL_OFDM_AG;
4567 break;
4568 case WIRELESS_MODE_G:
4569 regBwOpMode = BW_OPMODE_20MHZ;
4570 regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
4571 regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
4572 break;
4573 case WIRELESS_MODE_AUTO:
4574 if (priv->bInHctTest)
4575 {
4576 regBwOpMode = BW_OPMODE_20MHZ;
4577 regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
4578 regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
4579 }
4580 else
4581 {
4582 regBwOpMode = BW_OPMODE_20MHZ;
4583 regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
4584 regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
4585 }
4586 break;
4587 case WIRELESS_MODE_N_24G:
4588 // It support CCK rate by default.
4589 // CCK rate will be filtered out only when associated AP does not support it.
4590 regBwOpMode = BW_OPMODE_20MHZ;
4591 regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
4592 regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
4593 break;
4594 case WIRELESS_MODE_N_5G:
4595 regBwOpMode = BW_OPMODE_5G;
4596 regRATR = RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
4597 regRRSR = RATE_ALL_OFDM_AG;
4598 break;
4599 }
4600
4601 //
4602 // <Roger_Notes> We disable CCK response rate until FIB CCK rate IC's back.
4603 // 2008.09.23.
4604 //
4605 regTmp = read_nic_byte(dev, INIRTSMCS_SEL);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07004606 regRRSR = ((regRRSR & 0x000fffff)<<8) | regTmp;
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07004607
4608 //
4609 // Update SIFS timing.
4610 //
4611 //priv->SifsTime = 0x0e0e0a0a;
4612 //Adapter->HalFunc.SetHwRegHandler( Adapter, HW_VAR_SIFS, (pu1Byte)&pHalData->SifsTime);
4613 { u8 val[4] = {0x0e, 0x0e, 0x0a, 0x0a};
4614 // SIFS for CCK Data ACK
4615 write_nic_byte(dev, SIFS_CCK, val[0]);
4616 // SIFS for CCK consecutive tx like CTS data!
4617 write_nic_byte(dev, SIFS_CCK+1, val[1]);
4618
4619 // SIFS for OFDM Data ACK
4620 write_nic_byte(dev, SIFS_OFDM, val[2]);
4621 // SIFS for OFDM consecutive tx like CTS data!
4622 write_nic_byte(dev, SIFS_OFDM+1, val[3]);
4623 }
4624
4625 write_nic_dword(dev, INIRTSMCS_SEL, regRRSR);
4626 write_nic_byte(dev, BW_OPMODE, regBwOpMode);
4627
4628 //
4629 // Suggested by SD1 Alex, 2008-06-14.
4630 //
4631 //PlatformEFIOWrite1Byte(Adapter, TXOP_STALL_CTRL, 0x80);//NAV to protect all TXOP.
4632
4633 //
4634 // Set Data Auto Rate Fallback Retry Count register.
4635 //
4636 write_nic_dword(dev, DARFRC, 0x02010000);
4637 write_nic_dword(dev, DARFRC+4, 0x06050403);
4638 write_nic_dword(dev, RARFRC, 0x02010000);
4639 write_nic_dword(dev, RARFRC+4, 0x06050403);
4640
4641 // Set Data Auto Rate Fallback Reg. Added by Roger, 2008.09.22.
4642 for (i = 0; i < 8; i++)
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07004643 write_nic_dword(dev, ARFR0+i*4, 0x1f0ffff0);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07004644
4645 //
4646 // Aggregation length limit. Revised by Roger. 2008.09.22.
4647 //
4648 write_nic_byte(dev, AGGLEN_LMT_H, 0x0f); // Set AMPDU length to 12Kbytes for ShortGI case.
4649 write_nic_dword(dev, AGGLEN_LMT_L, 0xddd77442); // Long GI
4650 write_nic_dword(dev, AGGLEN_LMT_L+4, 0xfffdd772);
4651
4652 // Set NAV protection length
4653 write_nic_word(dev, NAV_PROT_LEN, 0x0080);
4654
4655 // Set TXOP stall control for several queue/HI/BCN/MGT/
4656 write_nic_byte(dev, TXOP_STALL_CTRL, 0x00); // NAV Protect next packet.
4657
4658 // Set MSDU lifetime.
4659 write_nic_byte(dev, MLT, 0x8f);
4660
4661 // Set CCK/OFDM SIFS
4662 write_nic_word(dev, SIFS_CCK, 0x0a0a); // CCK SIFS shall always be 10us.
4663 write_nic_word(dev, SIFS_OFDM, 0x0e0e);
4664
4665 write_nic_byte(dev, ACK_TIMEOUT, 0x40);
4666
4667 // CF-END Threshold
4668 write_nic_byte(dev, CFEND_TH, 0xFF);
4669
4670 //
4671 // For Min Spacing configuration.
4672 //
4673 switch(priv->rf_type)
4674 {
4675 case RF_1T2R:
4676 case RF_1T1R:
4677 RT_TRACE(COMP_INIT, "Initializeadapter: RF_Type%s\n", (priv->rf_type==RF_1T1R? "(1T1R)":"(1T2R)"));
4678 priv->MinSpaceCfg = (MAX_MSS_DENSITY_1T<<3);
4679 break;
4680 case RF_2T2R:
4681 case RF_2T2R_GREEN:
4682 RT_TRACE(COMP_INIT, "Initializeadapter:RF_Type(2T2R)\n");
4683 priv->MinSpaceCfg = (MAX_MSS_DENSITY_2T<<3);
4684 break;
4685 }
4686 write_nic_byte(dev, AMPDU_MIN_SPACE, priv->MinSpaceCfg);
4687
4688 //LZM 090219
4689 //
4690 // For Min Spacing configuration.
4691 //
4692 //priv->MinSpaceCfg = 0x00;
4693 //rtl8192SU_SetHwRegAmpduMinSpace(dev, priv->MinSpaceCfg);
4694}
4695
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07004696
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07004697// Description: Initial HW relted registers.
4698//
4699// Assumption: This function is only invoked at driver intialization once.
4700//
4701// 2008.06.10, Added by Roger.
4702bool rtl8192SU_adapter_start(struct net_device *dev)
4703{
4704 struct r8192_priv *priv = ieee80211_priv(dev);
4705 //u32 dwRegRead = 0;
4706 //bool init_status = true;
4707 //u32 ulRegRead;
4708 bool rtStatus = true;
4709 //u8 PipeIndex;
4710 //u8 eRFPath, tmpU1b;
4711 u8 fw_download_times = 1;
4712
4713
4714 RT_TRACE(COMP_INIT, "--->InitializeAdapter8192SUsb()\n");
4715
4716 //pHalData->bGPIOChangeRF = FALSE;
4717
4718
4719 //
4720 // <Roger_Notes> 2008.06.15.
4721 //
4722 // Initialization Steps on RTL8192SU:
4723 // a. MAC initialization prior to sending down firmware code.
4724 // b. Download firmware code step by step(i.e., IMEM, EMEM, DMEM).
4725 // c. MAC configuration after firmware has been download successfully.
4726 // d. Initialize BB related configurations.
4727 // e. Initialize RF related configurations.
4728 // f. Start to BulkIn transfer.
4729 //
4730
4731 //
4732 //a. MAC initialization prior to send down firmware code.
4733 //
4734start:
4735 rtl8192SU_MacConfigBeforeFwDownloadASIC(dev);
4736
4737 //
4738 //b. Download firmware code step by step(i.e., IMEM, EMEM, DMEM).
4739 //
4740 rtStatus = FirmwareDownload92S(dev);
4741 if(rtStatus != true)
4742 {
4743 if(fw_download_times == 1){
4744 RT_TRACE(COMP_INIT, "InitializeAdapter8192SUsb(): Download Firmware failed once, Download again!!\n");
4745 fw_download_times = fw_download_times + 1;
4746 goto start;
4747 }else{
4748 RT_TRACE(COMP_INIT, "InitializeAdapter8192SUsb(): Download Firmware failed twice, end!!\n");
4749 goto end;
4750 }
4751 }
4752 //
4753 //c. MAC configuration after firmware has been download successfully.
4754 //
4755 rtl8192SU_MacConfigAfterFwDownload(dev);
4756
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07004757 //priv->bLbusEnable = TRUE;
4758 //if(priv->RegRfOff == TRUE)
4759 // priv->eRFPowerState = eRfOff;
4760
4761 // Save target channel
4762 // <Roger_Notes> Current Channel will be updated again later.
4763 //priv->CurrentChannel = Channel;
4764 rtStatus = PHY_MACConfig8192S(dev);//===>ok
4765 if(rtStatus != true)
4766 {
4767 RT_TRACE(COMP_INIT, "InitializeAdapter8192SUsb(): Fail to configure MAC!!\n");
4768 goto end;
4769 }
4770 if (1){
4771 int i;
4772 for (i=0; i<4; i++)
4773 write_nic_dword(dev,WDCAPARA_ADD[i], 0x5e4322);
4774 write_nic_byte(dev,AcmHwCtrl, 0x01);
4775 }
4776
4777
4778 //
4779 //d. Initialize BB related configurations.
4780 //
4781
4782 rtStatus = PHY_BBConfig8192S(dev);//===>ok
4783 if(rtStatus != true)
4784 {
4785 RT_TRACE(COMP_INIT, "InitializeAdapter8192SUsb(): Fail to configure BB!!\n");
4786 goto end;
4787 }
4788
4789 rtl8192_setBBreg(dev, rFPGA0_AnalogParameter2, 0xff, 0x58);//===>ok
4790
4791 //
4792 // e. Initialize RF related configurations.
4793 //
4794 // 2007/11/02 MH Before initalizing RF. We can not use FW to do RF-R/W.
4795 priv->Rf_Mode = RF_OP_By_SW_3wire;
4796
4797 // For RF test only from Scott's suggestion
4798 //write_nic_byte(dev, 0x27, 0xDB);
4799 //write_nic_byte(dev, 0x1B, 0x07);
4800
4801
4802 write_nic_byte(dev, AFE_XTAL_CTRL+1, 0xDB);
4803
4804 // <Roger_Notes> The following IOs are configured for each RF modules.
4805 // Enable RF module and reset RF and SDM module. 2008.11.17.
4806 if(priv->card_8192_version == VERSION_8192S_ACUT)
4807 write_nic_byte(dev, SPS1_CTRL+3, (u8)(RF_EN|RF_RSTB|RF_SDMRSTB)); // Fix A-Cut bug.
4808 else
4809 write_nic_byte(dev, RF_CTRL, (u8)(RF_EN|RF_RSTB|RF_SDMRSTB));
4810
4811 rtStatus = PHY_RFConfig8192S(dev);//===>ok
4812 if(rtStatus != true)
4813 {
4814 RT_TRACE(COMP_INIT, "InitializeAdapter8192SUsb(): Fail to configure RF!!\n");
4815 goto end;
4816 }
4817
4818
4819 // Set CCK and OFDM Block "ON"
4820 rtl8192_setBBreg(dev, rFPGA0_RFMOD, bCCKEn, 0x1);
4821 rtl8192_setBBreg(dev, rFPGA0_RFMOD, bOFDMEn, 0x1);
4822
4823 //
4824 // Turn off Radio B while RF type is 1T1R by SD3 Wilsion's request.
4825 // Revised by Roger, 2008.12.18.
4826 //
4827 if(priv->rf_type == RF_1T1R)
4828 {
4829 // This is needed for PHY_REG after 20081219
4830 rtl8192_setBBreg(dev, rFPGA0_RFMOD, 0xff000000, 0x03);
4831 // This is needed for PHY_REG before 20081219
4832 //PHY_SetBBReg(Adapter, rOFDM0_TRxPathEnable, bMaskByte0, 0x11);
4833 }
4834
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07004835
4836 //LZM 090219
4837 // Set CCK and OFDM Block "ON"
4838 //rtl8192_setBBreg(dev, rFPGA0_RFMOD, bCCKEn, 0x1);
4839 //rtl8192_setBBreg(dev, rFPGA0_RFMOD, bOFDMEn, 0x1);
4840
4841
4842 //3//Get hardware version, do it in read eeprom?
4843 //GetHardwareVersion819xUsb(Adapter);
4844
4845 //3//
4846 //3 //Set Hardware
4847 //3//
4848 rtl8192SU_HwConfigureRTL8192SUsb(dev);//==>ok
4849
4850 //
4851 // <Roger_Notes> We set MAC address here if autoload was failed before,
4852 // otherwise IDR0 will NOT contain any value.
4853 //
4854 write_nic_dword(dev, IDR0, ((u32*)dev->dev_addr)[0]);
4855 write_nic_word(dev, IDR4, ((u16*)(dev->dev_addr + 4))[0]);
4856 if(!priv->bInHctTest)
4857 {
4858 if(priv->ResetProgress == RESET_TYPE_NORESET)
4859 {
4860 //RT_TRACE(COMP_MLME, DBG_LOUD, ("Initializeadapter8192SUsb():RegWirelessMode(%#x) \n", Adapter->RegWirelessMode));
4861 //Adapter->HalFunc.SetWirelessModeHandler(Adapter, Adapter->RegWirelessMode);
4862 rtl8192_SetWirelessMode(dev, priv->ieee80211->mode);//===>ok
4863 }
4864 }
4865 else
4866 {
4867 priv->ieee80211->mode = WIRELESS_MODE_G;
4868 rtl8192_SetWirelessMode(dev, WIRELESS_MODE_G);
4869 }
4870
4871 //Security related.
4872 //-----------------------------------------------------------------------------
4873 // Set up security related. 070106, by rcnjko:
4874 // 1. Clear all H/W keys.
4875 // 2. Enable H/W encryption/decryption.
4876 //-----------------------------------------------------------------------------
4877 //CamResetAllEntry(Adapter);
4878 //Adapter->HalFunc.EnableHWSecCfgHandler(Adapter);
4879
4880 //SecClearAllKeys(Adapter);
4881 CamResetAllEntry(dev);
4882 //SecInit(Adapter);
4883 {
4884 u8 SECR_value = 0x0;
4885 SECR_value |= SCR_TxEncEnable;
4886 SECR_value |= SCR_RxDecEnable;
4887 SECR_value |= SCR_NoSKMC;
4888 write_nic_byte(dev, SECR, SECR_value);
4889 }
4890
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07004891#ifdef TO_DO_LIST
4892
4893 //PHY_UpdateInitialGain(dev);
4894
4895 if(priv->RegRfOff == true)
4896 { // User disable RF via registry.
4897 u8 eRFPath = 0;
4898
4899 RT_TRACE((COMP_INIT|COMP_RF), "InitializeAdapter8192SUsb(): Turn off RF for RegRfOff ----------\n");
4900 MgntActSet_RF_State(dev, eRfOff, RF_CHANGE_BY_SW);
4901 // Those action will be discard in MgntActSet_RF_State because off the same state
4902 for(eRFPath = 0; eRFPath <priv->NumTotalRFPath; eRFPath++)
4903 rtl8192_setBBreg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x4, 0xC00, 0x0);
4904 }
4905 else if(priv->RfOffReason > RF_CHANGE_BY_PS)
4906 { // H/W or S/W RF OFF before sleep.
4907 RT_TRACE((COMP_INIT|COMP_RF), "InitializeAdapter8192SUsb(): Turn off RF for RfOffReason(%d) ----------\n", priv->RfOffReason);
4908 MgntActSet_RF_State(dev, eRfOff, priv->RfOffReason);
4909 }
4910 else
4911 {
4912 priv->eRFPowerState = eRfOn;
4913 priv->RfOffReason = 0;
4914 RT_TRACE((COMP_INIT|COMP_RF), "InitializeAdapter8192SUsb(): RF is on ----------\n");
4915 }
4916
4917#endif
4918
4919
4920//
4921// f. Start to BulkIn transfer.
4922//
4923#ifdef TO_DO_LIST
4924
4925#ifndef UNDER_VISTA
4926 {
4927 u8 i;
4928 PlatformAcquireSpinLock(Adapter, RT_RX_SPINLOCK);
4929
4930 for(PipeIndex=0; PipeIndex < MAX_RX_QUEUE; PipeIndex++)
4931 {
4932 if (PipeIndex == 0)
4933 {
4934 for(i=0; i<32; i++)
4935 HalUsbInMpdu(Adapter, PipeIndex);
4936 }
4937 else
4938 {
4939 //HalUsbInMpdu(Adapter, PipeIndex);
4940 //HalUsbInMpdu(Adapter, PipeIndex);
4941 //HalUsbInMpdu(Adapter, PipeIndex);
4942 }
4943 }
4944 PlatformReleaseSpinLock(Adapter, RT_RX_SPINLOCK);
4945 }
4946#else
4947 // Joseph add to 819X code base for Vista USB platform.
4948 // This part may need to be add to Hal819xU code base. too.
4949 PlatformUsbEnableInPipes(Adapter);
4950#endif
4951
4952 RT_TRACE(COMP_INIT, "HighestOperaRate = %x\n", Adapter->MgntInfo.HighestOperaRate);
4953
4954 PlatformStartWorkItem( &(pHalData->RtUsbCheckForHangWorkItem) );
4955
4956 //
4957 // <Roger_EXP> The following configurations are for ASIC verification temporally.
4958 // 2008.07.10.
4959 //
4960
4961#endif
4962
4963 //
4964 // Read EEPROM TX power index and PHY_REG_PG.txt to capture correct
4965 // TX power index for different rate set.
4966 //
4967 //if(priv->card_8192_version >= VERSION_8192S_ACUT)
4968 {
4969 // Get original hw reg values
4970 PHY_GetHWRegOriginalValue(dev);
4971
4972 // Write correct tx power index//FIXLZM
4973 PHY_SetTxPowerLevel8192S(dev, priv->chan);
4974 }
4975
4976 {
4977 u8 tmpU1b = 0;
4978 // EEPROM R/W workaround
4979 tmpU1b = read_nic_byte(dev, MAC_PINMUX_CFG);
4980 write_nic_byte(dev, MAC_PINMUX_CFG, tmpU1b&(~GPIOMUX_EN));
4981 }
4982
4983//
4984//<Roger_Notes> 2008.08.19.
4985// We return status here for temporal FPGA verification, 2008.08.19.
4986
4987#ifdef RTL8192SU_FW_IQK
4988 write_nic_dword(dev, WFM5, FW_IQK_ENABLE);
4989 ChkFwCmdIoDone(dev);
4990#endif
4991
4992 //
4993 // <Roger_Notes> We enable high power mechanism after NIC initialized.
4994 // 2008.11.27.
4995 //
4996 write_nic_dword(dev, WFM5, FW_RA_RESET);
4997 ChkFwCmdIoDone(dev);
4998 write_nic_dword(dev, WFM5, FW_RA_ACTIVE);
4999 ChkFwCmdIoDone(dev);
5000 write_nic_dword(dev, WFM5, FW_RA_REFRESH);
5001 ChkFwCmdIoDone(dev);
5002 write_nic_dword(dev, WFM5, FW_BB_RESET_ENABLE);
5003
5004// <Roger_Notes> We return status here for temporal FPGA verification. 2008.05.12.
5005//
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07005006
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07005007end:
5008return rtStatus;
5009}
5010
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07005011/***************************************************************************
5012 -------------------------------NET STUFF---------------------------
5013***************************************************************************/
5014
5015static struct net_device_stats *rtl8192_stats(struct net_device *dev)
5016{
5017 struct r8192_priv *priv = ieee80211_priv(dev);
5018
5019 return &priv->ieee80211->stats;
5020}
5021
5022bool
5023HalTxCheckStuck819xUsb(
5024 struct net_device *dev
5025 )
5026{
5027 struct r8192_priv *priv = ieee80211_priv(dev);
5028 u16 RegTxCounter = read_nic_word(dev, 0x128);
5029 bool bStuck = FALSE;
5030 RT_TRACE(COMP_RESET,"%s():RegTxCounter is %d,TxCounter is %d\n",__FUNCTION__,RegTxCounter,priv->TxCounter);
5031 if(priv->TxCounter==RegTxCounter)
5032 bStuck = TRUE;
5033
5034 priv->TxCounter = RegTxCounter;
5035
5036 return bStuck;
5037}
5038
5039/*
5040* <Assumption: RT_TX_SPINLOCK is acquired.>
5041* First added: 2006.11.19 by emily
5042*/
5043RESET_TYPE
5044TxCheckStuck(struct net_device *dev)
5045{
5046 struct r8192_priv *priv = ieee80211_priv(dev);
5047 u8 QueueID;
5048// PRT_TCB pTcb;
5049// u8 ResetThreshold;
5050 bool bCheckFwTxCnt = false;
5051 //unsigned long flags;
5052
5053 //
5054 // Decide Stuch threshold according to current power save mode
5055 //
5056
5057// RT_TRACE(COMP_RESET, " ==> TxCheckStuck()\n");
5058// PlatformAcquireSpinLock(Adapter, RT_TX_SPINLOCK);
5059// spin_lock_irqsave(&priv->ieee80211->lock,flags);
5060 for (QueueID = 0; QueueID<=BEACON_QUEUE;QueueID ++)
5061 {
5062 if(QueueID == TXCMD_QUEUE)
5063 continue;
5064#if 1
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07005065 if((skb_queue_len(&priv->ieee80211->skb_waitQ[QueueID]) == 0) && (skb_queue_len(&priv->ieee80211->skb_aggQ[QueueID]) == 0))
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07005066 continue;
5067#endif
5068
5069 bCheckFwTxCnt = true;
5070 }
5071// PlatformReleaseSpinLock(Adapter, RT_TX_SPINLOCK);
5072// spin_unlock_irqrestore(&priv->ieee80211->lock,flags);
5073// RT_TRACE(COMP_RESET,"bCheckFwTxCnt is %d\n",bCheckFwTxCnt);
5074#if 1
5075 if(bCheckFwTxCnt)
5076 {
5077 if(HalTxCheckStuck819xUsb(dev))
5078 {
5079 RT_TRACE(COMP_RESET, "TxCheckStuck(): Fw indicates no Tx condition! \n");
5080 return RESET_TYPE_SILENT;
5081 }
5082 }
5083#endif
5084 return RESET_TYPE_NORESET;
5085}
5086
5087bool
5088HalRxCheckStuck819xUsb(struct net_device *dev)
5089{
5090 u16 RegRxCounter = read_nic_word(dev, 0x130);
5091 struct r8192_priv *priv = ieee80211_priv(dev);
5092 bool bStuck = FALSE;
5093//#ifdef RTL8192SU
5094
5095//#else
5096 static u8 rx_chk_cnt = 0;
5097 RT_TRACE(COMP_RESET,"%s(): RegRxCounter is %d,RxCounter is %d\n",__FUNCTION__,RegRxCounter,priv->RxCounter);
5098 // If rssi is small, we should check rx for long time because of bad rx.
5099 // or maybe it will continuous silent reset every 2 seconds.
5100 rx_chk_cnt++;
5101 if(priv->undecorated_smoothed_pwdb >= (RateAdaptiveTH_High+5))
5102 {
5103 rx_chk_cnt = 0; //high rssi, check rx stuck right now.
5104 }
5105 else if(priv->undecorated_smoothed_pwdb < (RateAdaptiveTH_High+5) &&
5106 ((priv->CurrentChannelBW!=HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb>=RateAdaptiveTH_Low_40M) ||
5107 (priv->CurrentChannelBW==HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb>=RateAdaptiveTH_Low_20M)) )
5108 {
5109 if(rx_chk_cnt < 2)
5110 {
5111 return bStuck;
5112 }
5113 else
5114 {
5115 rx_chk_cnt = 0;
5116 }
5117 }
5118 else if(((priv->CurrentChannelBW!=HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb<RateAdaptiveTH_Low_40M) ||
5119 (priv->CurrentChannelBW==HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb<RateAdaptiveTH_Low_20M)) &&
5120 priv->undecorated_smoothed_pwdb >= VeryLowRSSI)
5121 {
5122 if(rx_chk_cnt < 4)
5123 {
5124 //DbgPrint("RSSI < %d && RSSI >= %d, no check this time \n", RateAdaptiveTH_Low, VeryLowRSSI);
5125 return bStuck;
5126 }
5127 else
5128 {
5129 rx_chk_cnt = 0;
5130 //DbgPrint("RSSI < %d && RSSI >= %d, check this time \n", RateAdaptiveTH_Low, VeryLowRSSI);
5131 }
5132 }
5133 else
5134 {
5135 if(rx_chk_cnt < 8)
5136 {
5137 //DbgPrint("RSSI <= %d, no check this time \n", VeryLowRSSI);
5138 return bStuck;
5139 }
5140 else
5141 {
5142 rx_chk_cnt = 0;
5143 //DbgPrint("RSSI <= %d, check this time \n", VeryLowRSSI);
5144 }
5145 }
5146//#endif
5147
5148 if(priv->RxCounter==RegRxCounter)
5149 bStuck = TRUE;
5150
5151 priv->RxCounter = RegRxCounter;
5152
5153 return bStuck;
5154}
5155
5156RESET_TYPE
5157RxCheckStuck(struct net_device *dev)
5158{
5159 struct r8192_priv *priv = ieee80211_priv(dev);
5160 //int i;
5161 bool bRxCheck = FALSE;
5162
5163// RT_TRACE(COMP_RESET," ==> RxCheckStuck()\n");
5164 //PlatformAcquireSpinLock(Adapter, RT_RX_SPINLOCK);
5165
5166 if(priv->IrpPendingCount > 1)
5167 bRxCheck = TRUE;
5168 //PlatformReleaseSpinLock(Adapter, RT_RX_SPINLOCK);
5169
5170// RT_TRACE(COMP_RESET,"bRxCheck is %d \n",bRxCheck);
5171 if(bRxCheck)
5172 {
5173 if(HalRxCheckStuck819xUsb(dev))
5174 {
5175 RT_TRACE(COMP_RESET, "RxStuck Condition\n");
5176 return RESET_TYPE_SILENT;
5177 }
5178 }
5179 return RESET_TYPE_NORESET;
5180}
5181
5182
5183/**
5184* This function is called by Checkforhang to check whether we should ask OS to reset driver
5185*
5186* \param pAdapter The adapter context for this miniport
5187*
5188* Note:NIC with USB interface sholud not call this function because we cannot scan descriptor
5189* to judge whether there is tx stuck.
5190* Note: This function may be required to be rewrite for Vista OS.
5191* <<<Assumption: Tx spinlock has been acquired >>>
5192*
5193* 8185 and 8185b does not implement this function. This is added by Emily at 2006.11.24
5194*/
5195RESET_TYPE
5196rtl819x_ifcheck_resetornot(struct net_device *dev)
5197{
5198 struct r8192_priv *priv = ieee80211_priv(dev);
5199 RESET_TYPE TxResetType = RESET_TYPE_NORESET;
5200 RESET_TYPE RxResetType = RESET_TYPE_NORESET;
5201 RT_RF_POWER_STATE rfState;
5202
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07005203 return RESET_TYPE_NORESET;
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07005204
5205 rfState = priv->ieee80211->eRFPowerState;
5206
5207 TxResetType = TxCheckStuck(dev);
5208#if 1
5209 if( rfState != eRfOff ||
5210 /*ADAPTER_TEST_STATUS_FLAG(Adapter, ADAPTER_STATUS_FW_DOWNLOAD_FAILURE)) &&*/
5211 (priv->ieee80211->iw_mode != IW_MODE_ADHOC))
5212 {
5213 // If driver is in the status of firmware download failure , driver skips RF initialization and RF is
5214 // in turned off state. Driver should check whether Rx stuck and do silent reset. And
5215 // if driver is in firmware download failure status, driver should initialize RF in the following
5216 // silent reset procedure Emily, 2008.01.21
5217
5218 // Driver should not check RX stuck in IBSS mode because it is required to
5219 // set Check BSSID in order to send beacon, however, if check BSSID is
5220 // set, STA cannot hear any packet a all. Emily, 2008.04.12
5221 RxResetType = RxCheckStuck(dev);
5222 }
5223#endif
5224 if(TxResetType==RESET_TYPE_NORMAL || RxResetType==RESET_TYPE_NORMAL)
5225 return RESET_TYPE_NORMAL;
5226 else if(TxResetType==RESET_TYPE_SILENT || RxResetType==RESET_TYPE_SILENT){
5227 RT_TRACE(COMP_RESET,"%s():silent reset\n",__FUNCTION__);
5228 return RESET_TYPE_SILENT;
5229 }
5230 else
5231 return RESET_TYPE_NORESET;
5232
5233}
5234
5235void rtl8192_cancel_deferred_work(struct r8192_priv* priv);
5236int _rtl8192_up(struct net_device *dev);
5237int rtl8192_close(struct net_device *dev);
5238
5239
5240
5241void
5242CamRestoreAllEntry( struct net_device *dev)
5243{
5244 u8 EntryId = 0;
5245 struct r8192_priv *priv = ieee80211_priv(dev);
5246 u8* MacAddr = priv->ieee80211->current_network.bssid;
5247
5248 static u8 CAM_CONST_ADDR[4][6] = {
5249 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
5250 {0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
5251 {0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
5252 {0x00, 0x00, 0x00, 0x00, 0x00, 0x03}};
5253 static u8 CAM_CONST_BROAD[] =
5254 {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
5255
5256 RT_TRACE(COMP_SEC, "CamRestoreAllEntry: \n");
5257
5258
5259 if ((priv->ieee80211->pairwise_key_type == KEY_TYPE_WEP40)||
5260 (priv->ieee80211->pairwise_key_type == KEY_TYPE_WEP104))
5261 {
5262
5263 for(EntryId=0; EntryId<4; EntryId++)
5264 {
5265 {
5266 MacAddr = CAM_CONST_ADDR[EntryId];
5267 setKey(dev,
5268 EntryId ,
5269 EntryId,
5270 priv->ieee80211->pairwise_key_type,
5271 MacAddr,
5272 0,
5273 NULL);
5274 }
5275 }
5276
5277 }
5278 else if(priv->ieee80211->pairwise_key_type == KEY_TYPE_TKIP)
5279 {
5280
5281 {
5282 if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
5283 setKey(dev,
5284 4,
5285 0,
5286 priv->ieee80211->pairwise_key_type,
5287 (u8*)dev->dev_addr,
5288 0,
5289 NULL);
5290 else
5291 setKey(dev,
5292 4,
5293 0,
5294 priv->ieee80211->pairwise_key_type,
5295 MacAddr,
5296 0,
5297 NULL);
5298 }
5299 }
5300 else if(priv->ieee80211->pairwise_key_type == KEY_TYPE_CCMP)
5301 {
5302
5303 {
5304 if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
5305 setKey(dev,
5306 4,
5307 0,
5308 priv->ieee80211->pairwise_key_type,
5309 (u8*)dev->dev_addr,
5310 0,
5311 NULL);
5312 else
5313 setKey(dev,
5314 4,
5315 0,
5316 priv->ieee80211->pairwise_key_type,
5317 MacAddr,
5318 0,
5319 NULL);
5320 }
5321 }
5322
5323
5324
5325 if(priv->ieee80211->group_key_type == KEY_TYPE_TKIP)
5326 {
5327 MacAddr = CAM_CONST_BROAD;
5328 for(EntryId=1 ; EntryId<4 ; EntryId++)
5329 {
5330 {
5331 setKey(dev,
5332 EntryId,
5333 EntryId,
5334 priv->ieee80211->group_key_type,
5335 MacAddr,
5336 0,
5337 NULL);
5338 }
5339 }
5340 if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
5341 setKey(dev,
5342 0,
5343 0,
5344 priv->ieee80211->group_key_type,
5345 CAM_CONST_ADDR[0],
5346 0,
5347 NULL);
5348 }
5349 else if(priv->ieee80211->group_key_type == KEY_TYPE_CCMP)
5350 {
5351 MacAddr = CAM_CONST_BROAD;
5352 for(EntryId=1; EntryId<4 ; EntryId++)
5353 {
5354 {
5355 setKey(dev,
5356 EntryId ,
5357 EntryId,
5358 priv->ieee80211->group_key_type,
5359 MacAddr,
5360 0,
5361 NULL);
5362 }
5363 }
5364
5365 if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
5366 setKey(dev,
5367 0 ,
5368 0,
5369 priv->ieee80211->group_key_type,
5370 CAM_CONST_ADDR[0],
5371 0,
5372 NULL);
5373 }
5374}
5375//////////////////////////////////////////////////////////////
5376// This function is used to fix Tx/Rx stop bug temporarily.
5377// This function will do "system reset" to NIC when Tx or Rx is stuck.
5378// The method checking Tx/Rx stuck of this function is supported by FW,
5379// which reports Tx and Rx counter to register 0x128 and 0x130.
5380//////////////////////////////////////////////////////////////
5381void
5382rtl819x_ifsilentreset(struct net_device *dev)
5383{
5384 //OCTET_STRING asocpdu;
5385 struct r8192_priv *priv = ieee80211_priv(dev);
5386 u8 reset_times = 0;
5387 int reset_status = 0;
5388 struct ieee80211_device *ieee = priv->ieee80211;
5389
5390
5391 // 2007.07.20. If we need to check CCK stop, please uncomment this line.
5392 //bStuck = Adapter->HalFunc.CheckHWStopHandler(Adapter);
5393
5394 if(priv->ResetProgress==RESET_TYPE_NORESET)
5395 {
5396RESET_START:
5397
5398 RT_TRACE(COMP_RESET,"=========>Reset progress!! \n");
5399
5400 // Set the variable for reset.
5401 priv->ResetProgress = RESET_TYPE_SILENT;
5402// rtl8192_close(dev);
5403#if 1
5404 down(&priv->wx_sem);
5405 if(priv->up == 0)
5406 {
5407 RT_TRACE(COMP_ERR,"%s():the driver is not up! return\n",__FUNCTION__);
5408 up(&priv->wx_sem);
5409 return ;
5410 }
5411 priv->up = 0;
5412 RT_TRACE(COMP_RESET,"%s():======>start to down the driver\n",__FUNCTION__);
5413// if(!netif_queue_stopped(dev))
5414// netif_stop_queue(dev);
5415
5416 rtl8192_rtx_disable(dev);
5417 rtl8192_cancel_deferred_work(priv);
5418 deinit_hal_dm(dev);
5419 del_timer_sync(&priv->watch_dog_timer);
5420
5421 ieee->sync_scan_hurryup = 1;
5422 if(ieee->state == IEEE80211_LINKED)
5423 {
5424 down(&ieee->wx_sem);
5425 printk("ieee->state is IEEE80211_LINKED\n");
5426 ieee80211_stop_send_beacons(priv->ieee80211);
5427 del_timer_sync(&ieee->associate_timer);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07005428 cancel_delayed_work(&ieee->associate_retry_wq);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07005429 ieee80211_stop_scan(ieee);
5430 netif_carrier_off(dev);
5431 up(&ieee->wx_sem);
5432 }
5433 else{
5434 printk("ieee->state is NOT LINKED\n");
5435 ieee80211_softmac_stop_protocol(priv->ieee80211); }
5436 up(&priv->wx_sem);
5437 RT_TRACE(COMP_RESET,"%s():<==========down process is finished\n",__FUNCTION__);
5438 //rtl8192_irq_disable(dev);
5439 RT_TRACE(COMP_RESET,"%s():===========>start to up the driver\n",__FUNCTION__);
5440 reset_status = _rtl8192_up(dev);
5441
5442 RT_TRACE(COMP_RESET,"%s():<===========up process is finished\n",__FUNCTION__);
5443 if(reset_status == -EAGAIN)
5444 {
5445 if(reset_times < 3)
5446 {
5447 reset_times++;
5448 goto RESET_START;
5449 }
5450 else
5451 {
5452 RT_TRACE(COMP_ERR," ERR!!! %s(): Reset Failed!!\n", __FUNCTION__);
5453 }
5454 }
5455#endif
5456 ieee->is_silent_reset = 1;
5457#if 1
5458 EnableHWSecurityConfig8192(dev);
5459#if 1
5460 if(ieee->state == IEEE80211_LINKED && ieee->iw_mode == IW_MODE_INFRA)
5461 {
5462 ieee->set_chan(ieee->dev, ieee->current_network.channel);
5463
5464#if 1
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07005465 queue_work(ieee->wq, &ieee->associate_complete_wq);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07005466#endif
5467
5468 }
5469 else if(ieee->state == IEEE80211_LINKED && ieee->iw_mode == IW_MODE_ADHOC)
5470 {
5471 ieee->set_chan(ieee->dev, ieee->current_network.channel);
5472 ieee->link_change(ieee->dev);
5473
5474 // notify_wx_assoc_event(ieee);
5475
5476 ieee80211_start_send_beacons(ieee);
5477
5478 if (ieee->data_hard_resume)
5479 ieee->data_hard_resume(ieee->dev);
5480 netif_carrier_on(ieee->dev);
5481 }
5482#endif
5483
5484 CamRestoreAllEntry(dev);
5485
5486 priv->ResetProgress = RESET_TYPE_NORESET;
5487 priv->reset_count++;
5488
5489 priv->bForcedSilentReset =false;
5490 priv->bResetInProgress = false;
5491
5492 // For test --> force write UFWP.
5493 write_nic_byte(dev, UFWP, 1);
5494 RT_TRACE(COMP_RESET, "Reset finished!! ====>[%d]\n", priv->reset_count);
5495#endif
5496 }
5497}
5498
5499void CAM_read_entry(
5500 struct net_device *dev,
5501 u32 iIndex
5502)
5503{
5504 u32 target_command=0;
5505 u32 target_content=0;
5506 u8 entry_i=0;
5507 u32 ulStatus;
5508 s32 i=100;
5509// printk("=======>start read CAM\n");
5510 for(entry_i=0;entry_i<CAM_CONTENT_COUNT;entry_i++)
5511 {
5512 // polling bit, and No Write enable, and address
5513 target_command= entry_i+CAM_CONTENT_COUNT*iIndex;
5514 target_command= target_command | BIT31;
5515
5516 //Check polling bit is clear
5517// mdelay(1);
5518#if 1
5519 while((i--)>=0)
5520 {
5521 ulStatus = read_nic_dword(dev, RWCAM);
5522 if(ulStatus & BIT31){
5523 continue;
5524 }
5525 else{
5526 break;
5527 }
5528 }
5529#endif
5530 write_nic_dword(dev, RWCAM, target_command);
5531 RT_TRACE(COMP_SEC,"CAM_read_entry(): WRITE A0: %x \n",target_command);
5532 // printk("CAM_read_entry(): WRITE A0: %lx \n",target_command);
5533 target_content = read_nic_dword(dev, RCAMO);
5534 RT_TRACE(COMP_SEC, "CAM_read_entry(): WRITE A8: %x \n",target_content);
5535 // printk("CAM_read_entry(): WRITE A8: %lx \n",target_content);
5536 }
5537 printk("\n");
5538}
5539
5540void rtl819x_update_rxcounts(
5541 struct r8192_priv *priv,
5542 u32* TotalRxBcnNum,
5543 u32* TotalRxDataNum
5544)
5545{
5546 u16 SlotIndex;
5547 u8 i;
5548
5549 *TotalRxBcnNum = 0;
5550 *TotalRxDataNum = 0;
5551
5552 SlotIndex = (priv->ieee80211->LinkDetectInfo.SlotIndex++)%(priv->ieee80211->LinkDetectInfo.SlotNum);
5553 priv->ieee80211->LinkDetectInfo.RxBcnNum[SlotIndex] = priv->ieee80211->LinkDetectInfo.NumRecvBcnInPeriod;
5554 priv->ieee80211->LinkDetectInfo.RxDataNum[SlotIndex] = priv->ieee80211->LinkDetectInfo.NumRecvDataInPeriod;
5555 for( i=0; i<priv->ieee80211->LinkDetectInfo.SlotNum; i++ ){
5556 *TotalRxBcnNum += priv->ieee80211->LinkDetectInfo.RxBcnNum[i];
5557 *TotalRxDataNum += priv->ieee80211->LinkDetectInfo.RxDataNum[i];
5558 }
5559}
5560
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07005561extern void rtl819x_watchdog_wqcallback(struct work_struct *work)
5562{
5563 struct delayed_work *dwork = container_of(work,struct delayed_work,work);
5564 struct r8192_priv *priv = container_of(dwork,struct r8192_priv,watch_dog_wq);
5565 struct net_device *dev = priv->ieee80211->dev;
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07005566 struct ieee80211_device* ieee = priv->ieee80211;
5567 RESET_TYPE ResetType = RESET_TYPE_NORESET;
5568 static u8 check_reset_cnt=0;
5569 bool bBusyTraffic = false;
5570
5571 if(!priv->up)
5572 return;
5573 hal_dm_watchdog(dev);
5574
5575 {//to get busy traffic condition
5576 if(ieee->state == IEEE80211_LINKED)
5577 {
5578 //windows mod 666 to 100.
5579 //if( ieee->LinkDetectInfo.NumRxOkInPeriod> 666 ||
5580 // ieee->LinkDetectInfo.NumTxOkInPeriod> 666 ) {
5581 if( ieee->LinkDetectInfo.NumRxOkInPeriod> 100 ||
5582 ieee->LinkDetectInfo.NumTxOkInPeriod> 100 ) {
5583 bBusyTraffic = true;
5584 }
5585 ieee->LinkDetectInfo.NumRxOkInPeriod = 0;
5586 ieee->LinkDetectInfo.NumTxOkInPeriod = 0;
5587 ieee->LinkDetectInfo.bBusyTraffic = bBusyTraffic;
5588 }
5589 }
5590 //added by amy for AP roaming
5591 {
5592 if(priv->ieee80211->state == IEEE80211_LINKED && priv->ieee80211->iw_mode == IW_MODE_INFRA)
5593 {
5594 u32 TotalRxBcnNum = 0;
5595 u32 TotalRxDataNum = 0;
5596
5597 rtl819x_update_rxcounts(priv, &TotalRxBcnNum, &TotalRxDataNum);
5598 if((TotalRxBcnNum+TotalRxDataNum) == 0)
5599 {
5600 #ifdef TODO
5601 if(rfState == eRfOff)
5602 RT_TRACE(COMP_ERR,"========>%s()\n",__FUNCTION__);
5603 #endif
5604 printk("===>%s(): AP is power off,connect another one\n",__FUNCTION__);
5605 // Dot11d_Reset(dev);
5606 priv->ieee80211->state = IEEE80211_ASSOCIATING;
5607 notify_wx_assoc_event(priv->ieee80211);
5608 RemovePeerTS(priv->ieee80211,priv->ieee80211->current_network.bssid);
5609 ieee->is_roaming = true;
5610 priv->ieee80211->link_change(dev);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07005611 queue_work(priv->ieee80211->wq, &priv->ieee80211->associate_procedure_wq);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07005612 }
5613 }
5614 priv->ieee80211->LinkDetectInfo.NumRecvBcnInPeriod=0;
5615 priv->ieee80211->LinkDetectInfo.NumRecvDataInPeriod=0;
5616 }
5617// CAM_read_entry(dev,4);
5618 //check if reset the driver
5619 if(check_reset_cnt++ >= 3 && !ieee->is_roaming)
5620 {
5621 ResetType = rtl819x_ifcheck_resetornot(dev);
5622 check_reset_cnt = 3;
5623 //DbgPrint("Start to check silent reset\n");
5624 }
5625 // 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);
5626#if 1
5627 if( (priv->force_reset) || (priv->ResetProgress==RESET_TYPE_NORESET &&
5628 (priv->bForcedSilentReset ||
5629 (!priv->bDisableNormalResetCheck && ResetType==RESET_TYPE_SILENT)))) // This is control by OID set in Pomelo
5630 {
5631 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);
5632 rtl819x_ifsilentreset(dev);
5633 }
5634#endif
5635 priv->force_reset = false;
5636 priv->bForcedSilentReset = false;
5637 priv->bResetInProgress = false;
5638 RT_TRACE(COMP_TRACE, " <==RtUsbCheckForHangWorkItemCallback()\n");
5639
5640}
5641
5642void watch_dog_timer_callback(unsigned long data)
5643{
5644 struct r8192_priv *priv = ieee80211_priv((struct net_device *) data);
5645 //printk("===============>watch_dog timer\n");
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07005646 queue_delayed_work(priv->priv_wq,&priv->watch_dog_wq, 0);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07005647 mod_timer(&priv->watch_dog_timer, jiffies + MSECS(IEEE80211_WATCH_DOG_TIME));
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07005648}
5649int _rtl8192_up(struct net_device *dev)
5650{
5651 struct r8192_priv *priv = ieee80211_priv(dev);
5652 //int i;
5653 int init_status = 0;
5654 priv->up=1;
5655 priv->ieee80211->ieee_up=1;
5656 RT_TRACE(COMP_INIT, "Bringing up iface");
5657 init_status = priv->ops->rtl819x_adapter_start(dev);
5658 if(!init_status)
5659 {
5660 RT_TRACE(COMP_ERR,"ERR!!! %s(): initialization is failed!\n", __FUNCTION__);
5661 priv->up=priv->ieee80211->ieee_up = 0;
5662 return -EAGAIN;
5663 }
5664 RT_TRACE(COMP_INIT, "start adapter finished\n");
5665 rtl8192_rx_enable(dev);
5666// rtl8192_tx_enable(dev);
5667 if(priv->ieee80211->state != IEEE80211_LINKED)
5668 ieee80211_softmac_start_protocol(priv->ieee80211);
5669 ieee80211_reset_queue(priv->ieee80211);
5670 watch_dog_timer_callback((unsigned long) dev);
5671 if(!netif_queue_stopped(dev))
5672 netif_start_queue(dev);
5673 else
5674 netif_wake_queue(dev);
5675
5676 /*
5677 * Make sure that drop_unencrypted is initialized as "0"
5678 * No packets will be sent in non-security mode if we had set drop_unencrypted.
5679 * ex, After kill wpa_supplicant process, make the driver up again.
5680 * drop_unencrypted remains as "1", which is set by wpa_supplicant. 2008/12/04.john
5681 */
5682 priv->ieee80211->drop_unencrypted = 0;
5683
5684 return 0;
5685}
5686
5687
5688int rtl8192_open(struct net_device *dev)
5689{
5690 struct r8192_priv *priv = ieee80211_priv(dev);
5691 int ret;
5692 down(&priv->wx_sem);
5693 ret = rtl8192_up(dev);
5694 up(&priv->wx_sem);
5695 return ret;
5696
5697}
5698
5699
5700int rtl8192_up(struct net_device *dev)
5701{
5702 struct r8192_priv *priv = ieee80211_priv(dev);
5703
5704 if (priv->up == 1) return -1;
5705
5706 return _rtl8192_up(dev);
5707}
5708
5709
5710int rtl8192_close(struct net_device *dev)
5711{
5712 struct r8192_priv *priv = ieee80211_priv(dev);
5713 int ret;
5714
5715 down(&priv->wx_sem);
5716
5717 ret = rtl8192_down(dev);
5718
5719 up(&priv->wx_sem);
5720
5721 return ret;
5722
5723}
5724
5725int rtl8192_down(struct net_device *dev)
5726{
5727 struct r8192_priv *priv = ieee80211_priv(dev);
5728 int i;
5729
5730 if (priv->up == 0) return -1;
5731
5732 priv->up=0;
5733 priv->ieee80211->ieee_up = 0;
5734 RT_TRACE(COMP_DOWN, "==========>%s()\n", __FUNCTION__);
5735/* FIXME */
5736 if (!netif_queue_stopped(dev))
5737 netif_stop_queue(dev);
5738
5739 rtl8192_rtx_disable(dev);
5740 //rtl8192_irq_disable(dev);
5741
5742 /* Tx related queue release */
5743 for(i = 0; i < MAX_QUEUE_SIZE; i++) {
5744 skb_queue_purge(&priv->ieee80211->skb_waitQ [i]);
5745 }
5746 for(i = 0; i < MAX_QUEUE_SIZE; i++) {
5747 skb_queue_purge(&priv->ieee80211->skb_aggQ [i]);
5748 }
5749
5750 for(i = 0; i < MAX_QUEUE_SIZE; i++) {
5751 skb_queue_purge(&priv->ieee80211->skb_drv_aggQ [i]);
5752 }
5753
5754 //as cancel_delayed_work will del work->timer, so if work is not definedas struct delayed_work, it will corrupt
5755// flush_scheduled_work();
5756 rtl8192_cancel_deferred_work(priv);
5757 deinit_hal_dm(dev);
5758 del_timer_sync(&priv->watch_dog_timer);
5759
5760
5761 ieee80211_softmac_stop_protocol(priv->ieee80211);
5762 memset(&priv->ieee80211->current_network, 0 , offsetof(struct ieee80211_network, list));
5763 RT_TRACE(COMP_DOWN, "<==========%s()\n", __FUNCTION__);
5764
5765 return 0;
5766}
5767
5768
5769void rtl8192_commit(struct net_device *dev)
5770{
5771 struct r8192_priv *priv = ieee80211_priv(dev);
5772 int reset_status = 0;
5773 //u8 reset_times = 0;
5774 if (priv->up == 0) return ;
5775 priv->up = 0;
5776
5777 rtl8192_cancel_deferred_work(priv);
5778 del_timer_sync(&priv->watch_dog_timer);
5779 //cancel_delayed_work(&priv->SwChnlWorkItem);
5780
5781 ieee80211_softmac_stop_protocol(priv->ieee80211);
5782
5783 //rtl8192_irq_disable(dev);
5784 rtl8192_rtx_disable(dev);
5785 reset_status = _rtl8192_up(dev);
5786
5787}
5788
5789/*
5790void rtl8192_restart(struct net_device *dev)
5791{
5792 struct r8192_priv *priv = ieee80211_priv(dev);
5793*/
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07005794void rtl8192_restart(struct work_struct *work)
5795{
5796 struct r8192_priv *priv = container_of(work, struct r8192_priv, reset_wq);
5797 struct net_device *dev = priv->ieee80211->dev;
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07005798
5799 down(&priv->wx_sem);
5800
5801 rtl8192_commit(dev);
5802
5803 up(&priv->wx_sem);
5804}
5805
5806static void r8192_set_multicast(struct net_device *dev)
5807{
5808 struct r8192_priv *priv = ieee80211_priv(dev);
5809 short promisc;
5810
5811 //down(&priv->wx_sem);
5812
5813 /* FIXME FIXME */
5814
5815 promisc = (dev->flags & IFF_PROMISC) ? 1:0;
5816
5817 if (promisc != priv->promisc)
5818 // rtl8192_commit(dev);
5819
5820 priv->promisc = promisc;
5821
5822 //schedule_work(&priv->reset_wq);
5823 //up(&priv->wx_sem);
5824}
5825
5826
5827int r8192_set_mac_adr(struct net_device *dev, void *mac)
5828{
5829 struct r8192_priv *priv = ieee80211_priv(dev);
5830 struct sockaddr *addr = mac;
5831
5832 down(&priv->wx_sem);
5833
5834 memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
5835
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07005836 schedule_work(&priv->reset_wq);
Bartlomiej Zolnierkiewicz1ec9e482009-06-13 18:35:04 +02005837
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07005838 up(&priv->wx_sem);
5839
5840 return 0;
5841}
5842
5843/* based on ipw2200 driver */
5844int rtl8192_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
5845{
5846 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
5847 struct iwreq *wrq = (struct iwreq *)rq;
5848 int ret=-1;
5849 struct ieee80211_device *ieee = priv->ieee80211;
5850 u32 key[4];
5851 u8 broadcast_addr[6] = {0xff,0xff,0xff,0xff,0xff,0xff};
5852 u8 zero_addr[6] = {0};
5853 struct iw_point *p = &wrq->u.data;
5854 struct ieee_param *ipw = NULL;//(struct ieee_param *)wrq->u.data.pointer;
5855
5856 down(&priv->wx_sem);
5857
5858
5859 if (p->length < sizeof(struct ieee_param) || !p->pointer){
5860 ret = -EINVAL;
5861 goto out;
5862 }
5863
5864 ipw = (struct ieee_param *)kmalloc(p->length, GFP_KERNEL);
5865 if (ipw == NULL){
5866 ret = -ENOMEM;
5867 goto out;
5868 }
5869 if (copy_from_user(ipw, p->pointer, p->length)) {
5870 kfree(ipw);
5871 ret = -EFAULT;
5872 goto out;
5873 }
5874
5875 switch (cmd) {
5876 case RTL_IOCTL_WPA_SUPPLICANT:
5877 //parse here for HW security
5878 if (ipw->cmd == IEEE_CMD_SET_ENCRYPTION)
5879 {
5880 if (ipw->u.crypt.set_tx)
5881 {
5882 if (strcmp(ipw->u.crypt.alg, "CCMP") == 0)
5883 ieee->pairwise_key_type = KEY_TYPE_CCMP;
5884 else if (strcmp(ipw->u.crypt.alg, "TKIP") == 0)
5885 ieee->pairwise_key_type = KEY_TYPE_TKIP;
5886 else if (strcmp(ipw->u.crypt.alg, "WEP") == 0)
5887 {
5888 if (ipw->u.crypt.key_len == 13)
5889 ieee->pairwise_key_type = KEY_TYPE_WEP104;
5890 else if (ipw->u.crypt.key_len == 5)
5891 ieee->pairwise_key_type = KEY_TYPE_WEP40;
5892 }
5893 else
5894 ieee->pairwise_key_type = KEY_TYPE_NA;
5895
5896 if (ieee->pairwise_key_type)
5897 {
5898 // 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
5899 if (memcmp(ieee->ap_mac_addr, zero_addr, 6) == 0)
5900 ieee->iw_mode = IW_MODE_ADHOC;
5901 memcpy((u8*)key, ipw->u.crypt.key, 16);
5902 EnableHWSecurityConfig8192(dev);
5903 //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!
5904 //added by WB.
5905 setKey(dev, 4, ipw->u.crypt.idx, ieee->pairwise_key_type, (u8*)ieee->ap_mac_addr, 0, key);
5906 if (ieee->iw_mode == IW_MODE_ADHOC)
5907 setKey(dev, ipw->u.crypt.idx, ipw->u.crypt.idx, ieee->pairwise_key_type, (u8*)ieee->ap_mac_addr, 0, key);
5908 }
5909 }
5910 else //if (ipw->u.crypt.idx) //group key use idx > 0
5911 {
5912 memcpy((u8*)key, ipw->u.crypt.key, 16);
5913 if (strcmp(ipw->u.crypt.alg, "CCMP") == 0)
5914 ieee->group_key_type= KEY_TYPE_CCMP;
5915 else if (strcmp(ipw->u.crypt.alg, "TKIP") == 0)
5916 ieee->group_key_type = KEY_TYPE_TKIP;
5917 else if (strcmp(ipw->u.crypt.alg, "WEP") == 0)
5918 {
5919 if (ipw->u.crypt.key_len == 13)
5920 ieee->group_key_type = KEY_TYPE_WEP104;
5921 else if (ipw->u.crypt.key_len == 5)
5922 ieee->group_key_type = KEY_TYPE_WEP40;
5923 }
5924 else
5925 ieee->group_key_type = KEY_TYPE_NA;
5926
5927 if (ieee->group_key_type)
5928 {
5929 setKey( dev,
5930 ipw->u.crypt.idx,
5931 ipw->u.crypt.idx, //KeyIndex
5932 ieee->group_key_type, //KeyType
5933 broadcast_addr, //MacAddr
5934 0, //DefaultKey
5935 key); //KeyContent
5936 }
5937 }
5938 }
5939#ifdef JOHN_HWSEC_DEBUG
5940 //john's test 0711
5941 printk("@@ wrq->u pointer = ");
5942 for(i=0;i<wrq->u.data.length;i++){
5943 if(i%10==0) printk("\n");
5944 printk( "%8x|", ((u32*)wrq->u.data.pointer)[i] );
5945 }
5946 printk("\n");
5947#endif /*JOHN_HWSEC_DEBUG*/
5948 ret = ieee80211_wpa_supplicant_ioctl(priv->ieee80211, &wrq->u.data);
5949 break;
5950
5951 default:
5952 ret = -EOPNOTSUPP;
5953 break;
5954 }
5955 kfree(ipw);
5956 ipw = NULL;
5957out:
5958 up(&priv->wx_sem);
5959 return ret;
5960}
5961
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07005962u8 rtl8192SU_HwRateToMRate(bool bIsHT, u8 rate,bool bFirstAMPDU)
5963{
5964
5965 u8 ret_rate = 0x02;
5966
5967 if( bFirstAMPDU )
5968 {
5969 if(!bIsHT)
5970 {
5971 switch(rate)
5972 {
5973
5974 case DESC92S_RATE1M: ret_rate = MGN_1M; break;
5975 case DESC92S_RATE2M: ret_rate = MGN_2M; break;
5976 case DESC92S_RATE5_5M: ret_rate = MGN_5_5M; break;
5977 case DESC92S_RATE11M: ret_rate = MGN_11M; break;
5978 case DESC92S_RATE6M: ret_rate = MGN_6M; break;
5979 case DESC92S_RATE9M: ret_rate = MGN_9M; break;
5980 case DESC92S_RATE12M: ret_rate = MGN_12M; break;
5981 case DESC92S_RATE18M: ret_rate = MGN_18M; break;
5982 case DESC92S_RATE24M: ret_rate = MGN_24M; break;
5983 case DESC92S_RATE36M: ret_rate = MGN_36M; break;
5984 case DESC92S_RATE48M: ret_rate = MGN_48M; break;
5985 case DESC92S_RATE54M: ret_rate = MGN_54M; break;
5986
5987 default:
5988 RT_TRACE(COMP_RECV, "HwRateToMRate90(): Non supported Rate [%x], bIsHT = %d!!!\n", rate, bIsHT);
5989 break;
5990 }
5991 }
5992 else
5993 {
5994 switch(rate)
5995 {
5996
5997 case DESC92S_RATEMCS0: ret_rate = MGN_MCS0; break;
5998 case DESC92S_RATEMCS1: ret_rate = MGN_MCS1; break;
5999 case DESC92S_RATEMCS2: ret_rate = MGN_MCS2; break;
6000 case DESC92S_RATEMCS3: ret_rate = MGN_MCS3; break;
6001 case DESC92S_RATEMCS4: ret_rate = MGN_MCS4; break;
6002 case DESC92S_RATEMCS5: ret_rate = MGN_MCS5; break;
6003 case DESC92S_RATEMCS6: ret_rate = MGN_MCS6; break;
6004 case DESC92S_RATEMCS7: ret_rate = MGN_MCS7; break;
6005 case DESC92S_RATEMCS8: ret_rate = MGN_MCS8; break;
6006 case DESC92S_RATEMCS9: ret_rate = MGN_MCS9; break;
6007 case DESC92S_RATEMCS10: ret_rate = MGN_MCS10; break;
6008 case DESC92S_RATEMCS11: ret_rate = MGN_MCS11; break;
6009 case DESC92S_RATEMCS12: ret_rate = MGN_MCS12; break;
6010 case DESC92S_RATEMCS13: ret_rate = MGN_MCS13; break;
6011 case DESC92S_RATEMCS14: ret_rate = MGN_MCS14; break;
6012 case DESC92S_RATEMCS15: ret_rate = MGN_MCS15; break;
6013 case DESC92S_RATEMCS32: ret_rate = (0x80|0x20); break;
6014
6015 default:
6016 RT_TRACE(COMP_RECV, "HwRateToMRate92S(): Non supported Rate [%x], bIsHT = %d!!!\n",rate, bIsHT );
6017 break;
6018 }
6019
6020 }
6021 }
6022 else
6023 {
6024 switch(rate)
6025 {
6026
6027 case DESC92S_RATE1M: ret_rate = MGN_1M; break;
6028 case DESC92S_RATE2M: ret_rate = MGN_2M; break;
6029 case DESC92S_RATE5_5M: ret_rate = MGN_5_5M; break;
6030 case DESC92S_RATE11M: ret_rate = MGN_11M; break;
6031 case DESC92S_RATE6M: ret_rate = MGN_6M; break;
6032 case DESC92S_RATE9M: ret_rate = MGN_9M; break;
6033 case DESC92S_RATE12M: ret_rate = MGN_12M; break;
6034 case DESC92S_RATE18M: ret_rate = MGN_18M; break;
6035 case DESC92S_RATE24M: ret_rate = MGN_24M; break;
6036 case DESC92S_RATE36M: ret_rate = MGN_36M; break;
6037 case DESC92S_RATE48M: ret_rate = MGN_48M; break;
6038 case DESC92S_RATE54M: ret_rate = MGN_54M; break;
6039 case DESC92S_RATEMCS0: ret_rate = MGN_MCS0; break;
6040 case DESC92S_RATEMCS1: ret_rate = MGN_MCS1; break;
6041 case DESC92S_RATEMCS2: ret_rate = MGN_MCS2; break;
6042 case DESC92S_RATEMCS3: ret_rate = MGN_MCS3; break;
6043 case DESC92S_RATEMCS4: ret_rate = MGN_MCS4; break;
6044 case DESC92S_RATEMCS5: ret_rate = MGN_MCS5; break;
6045 case DESC92S_RATEMCS6: ret_rate = MGN_MCS6; break;
6046 case DESC92S_RATEMCS7: ret_rate = MGN_MCS7; break;
6047 case DESC92S_RATEMCS8: ret_rate = MGN_MCS8; break;
6048 case DESC92S_RATEMCS9: ret_rate = MGN_MCS9; break;
6049 case DESC92S_RATEMCS10: ret_rate = MGN_MCS10; break;
6050 case DESC92S_RATEMCS11: ret_rate = MGN_MCS11; break;
6051 case DESC92S_RATEMCS12: ret_rate = MGN_MCS12; break;
6052 case DESC92S_RATEMCS13: ret_rate = MGN_MCS13; break;
6053 case DESC92S_RATEMCS14: ret_rate = MGN_MCS14; break;
6054 case DESC92S_RATEMCS15: ret_rate = MGN_MCS15; break;
6055 case DESC92S_RATEMCS32: ret_rate = (0x80|0x20); break;
6056
6057 default:
6058 RT_TRACE(COMP_RECV, "HwRateToMRate92S(): Non supported Rate [%x], bIsHT = %d!!!\n",rate, bIsHT );
6059 break;
6060 }
6061 }
6062 return ret_rate;
6063}
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07006064
6065u8 HwRateToMRate90(bool bIsHT, u8 rate)
6066{
6067 u8 ret_rate = 0xff;
6068
6069 if(!bIsHT) {
6070 switch(rate) {
6071 case DESC90_RATE1M: ret_rate = MGN_1M; break;
6072 case DESC90_RATE2M: ret_rate = MGN_2M; break;
6073 case DESC90_RATE5_5M: ret_rate = MGN_5_5M; break;
6074 case DESC90_RATE11M: ret_rate = MGN_11M; break;
6075 case DESC90_RATE6M: ret_rate = MGN_6M; break;
6076 case DESC90_RATE9M: ret_rate = MGN_9M; break;
6077 case DESC90_RATE12M: ret_rate = MGN_12M; break;
6078 case DESC90_RATE18M: ret_rate = MGN_18M; break;
6079 case DESC90_RATE24M: ret_rate = MGN_24M; break;
6080 case DESC90_RATE36M: ret_rate = MGN_36M; break;
6081 case DESC90_RATE48M: ret_rate = MGN_48M; break;
6082 case DESC90_RATE54M: ret_rate = MGN_54M; break;
6083
6084 default:
6085 ret_rate = 0xff;
6086 RT_TRACE(COMP_RECV, "HwRateToMRate90(): Non supported Rate [%x], bIsHT = %d!!!\n", rate, bIsHT);
6087 break;
6088 }
6089
6090 } else {
6091 switch(rate) {
6092 case DESC90_RATEMCS0: ret_rate = MGN_MCS0; break;
6093 case DESC90_RATEMCS1: ret_rate = MGN_MCS1; break;
6094 case DESC90_RATEMCS2: ret_rate = MGN_MCS2; break;
6095 case DESC90_RATEMCS3: ret_rate = MGN_MCS3; break;
6096 case DESC90_RATEMCS4: ret_rate = MGN_MCS4; break;
6097 case DESC90_RATEMCS5: ret_rate = MGN_MCS5; break;
6098 case DESC90_RATEMCS6: ret_rate = MGN_MCS6; break;
6099 case DESC90_RATEMCS7: ret_rate = MGN_MCS7; break;
6100 case DESC90_RATEMCS8: ret_rate = MGN_MCS8; break;
6101 case DESC90_RATEMCS9: ret_rate = MGN_MCS9; break;
6102 case DESC90_RATEMCS10: ret_rate = MGN_MCS10; break;
6103 case DESC90_RATEMCS11: ret_rate = MGN_MCS11; break;
6104 case DESC90_RATEMCS12: ret_rate = MGN_MCS12; break;
6105 case DESC90_RATEMCS13: ret_rate = MGN_MCS13; break;
6106 case DESC90_RATEMCS14: ret_rate = MGN_MCS14; break;
6107 case DESC90_RATEMCS15: ret_rate = MGN_MCS15; break;
6108 case DESC90_RATEMCS32: ret_rate = (0x80|0x20); break;
6109
6110 default:
6111 ret_rate = 0xff;
6112 RT_TRACE(COMP_RECV, "HwRateToMRate90(): Non supported Rate [%x], bIsHT = %d!!!\n",rate, bIsHT);
6113 break;
6114 }
6115 }
6116
6117 return ret_rate;
6118}
6119
6120/**
6121 * Function: UpdateRxPktTimeStamp
6122 * Overview: Recored down the TSF time stamp when receiving a packet
6123 *
6124 * Input:
6125 * PADAPTER Adapter
6126 * PRT_RFD pRfd,
6127 *
6128 * Output:
6129 * PRT_RFD pRfd
6130 * (pRfd->Status.TimeStampHigh is updated)
6131 * (pRfd->Status.TimeStampLow is updated)
6132 * Return:
6133 * None
6134 */
6135void UpdateRxPktTimeStamp8190 (struct net_device *dev, struct ieee80211_rx_stats *stats)
6136{
6137 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
6138
6139 if(stats->bIsAMPDU && !stats->bFirstMPDU) {
6140 stats->mac_time[0] = priv->LastRxDescTSFLow;
6141 stats->mac_time[1] = priv->LastRxDescTSFHigh;
6142 } else {
6143 priv->LastRxDescTSFLow = stats->mac_time[0];
6144 priv->LastRxDescTSFHigh = stats->mac_time[1];
6145 }
6146}
6147
6148//by amy 080606
6149
6150long rtl819x_translate_todbm(u8 signal_strength_index )// 0-100 index.
6151{
6152 long signal_power; // in dBm.
6153
6154 // Translate to dBm (x=0.5y-95).
6155 signal_power = (long)((signal_strength_index + 1) >> 1);
6156 signal_power -= 95;
6157
6158 return signal_power;
6159}
6160
6161
6162/* 2008/01/22 MH We can not delcare RSSI/EVM total value of sliding window to
6163 be a local static. Otherwise, it may increase when we return from S3/S4. The
6164 value will be kept in memory or disk. We must delcare the value in adapter
6165 and it will be reinitialized when return from S3/S4. */
6166void rtl8192_process_phyinfo(struct r8192_priv * priv,u8* buffer, struct ieee80211_rx_stats * pprevious_stats, struct ieee80211_rx_stats * pcurrent_stats)
6167{
6168 bool bcheck = false;
6169 u8 rfpath;
6170 u32 nspatial_stream, tmp_val;
6171 //u8 i;
6172 static u32 slide_rssi_index=0, slide_rssi_statistics=0;
6173 static u32 slide_evm_index=0, slide_evm_statistics=0;
6174 static u32 last_rssi=0, last_evm=0;
6175
6176 static u32 slide_beacon_adc_pwdb_index=0, slide_beacon_adc_pwdb_statistics=0;
6177 static u32 last_beacon_adc_pwdb=0;
6178
6179 struct ieee80211_hdr_3addr *hdr;
6180 u16 sc ;
6181 unsigned int frag,seq;
6182 hdr = (struct ieee80211_hdr_3addr *)buffer;
6183 sc = le16_to_cpu(hdr->seq_ctl);
6184 frag = WLAN_GET_SEQ_FRAG(sc);
6185 seq = WLAN_GET_SEQ_SEQ(sc);
6186 //cosa add 04292008 to record the sequence number
6187 pcurrent_stats->Seq_Num = seq;
6188 //
6189 // Check whether we should take the previous packet into accounting
6190 //
6191 if(!pprevious_stats->bIsAMPDU)
6192 {
6193 // if previous packet is not aggregated packet
6194 bcheck = true;
6195 }else
6196 {
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07006197 }
6198
6199
6200 if(slide_rssi_statistics++ >= PHY_RSSI_SLID_WIN_MAX)
6201 {
6202 slide_rssi_statistics = PHY_RSSI_SLID_WIN_MAX;
6203 last_rssi = priv->stats.slide_signal_strength[slide_rssi_index];
6204 priv->stats.slide_rssi_total -= last_rssi;
6205 }
6206 priv->stats.slide_rssi_total += pprevious_stats->SignalStrength;
6207
6208 priv->stats.slide_signal_strength[slide_rssi_index++] = pprevious_stats->SignalStrength;
6209 if(slide_rssi_index >= PHY_RSSI_SLID_WIN_MAX)
6210 slide_rssi_index = 0;
6211
6212 // <1> Showed on UI for user, in dbm
6213 tmp_val = priv->stats.slide_rssi_total/slide_rssi_statistics;
6214 priv->stats.signal_strength = rtl819x_translate_todbm((u8)tmp_val);
6215 pcurrent_stats->rssi = priv->stats.signal_strength;
6216 //
6217 // If the previous packet does not match the criteria, neglect it
6218 //
6219 if(!pprevious_stats->bPacketMatchBSSID)
6220 {
6221 if(!pprevious_stats->bToSelfBA)
6222 return;
6223 }
6224
6225 if(!bcheck)
6226 return;
6227
6228
6229 //rtl8190_process_cck_rxpathsel(priv,pprevious_stats);//only rtl8190 supported
6230
6231 //
6232 // Check RSSI
6233 //
6234 priv->stats.num_process_phyinfo++;
6235
6236 /* record the general signal strength to the sliding window. */
6237
6238
6239 // <2> Showed on UI for engineering
6240 // hardware does not provide rssi information for each rf path in CCK
6241 if(!pprevious_stats->bIsCCK && (pprevious_stats->bPacketToSelf || pprevious_stats->bToSelfBA))
6242 {
6243 for (rfpath = RF90_PATH_A; rfpath < priv->NumTotalRFPath; rfpath++)
6244 {
6245 if (!rtl8192_phy_CheckIsLegalRFPath(priv->ieee80211->dev, rfpath))
6246 continue;
6247
6248 //Fixed by Jacken 2008-03-20
6249 if(priv->stats.rx_rssi_percentage[rfpath] == 0)
6250 {
6251 priv->stats.rx_rssi_percentage[rfpath] = pprevious_stats->RxMIMOSignalStrength[rfpath];
6252 //DbgPrint("MIMO RSSI initialize \n");
6253 }
6254 if(pprevious_stats->RxMIMOSignalStrength[rfpath] > priv->stats.rx_rssi_percentage[rfpath])
6255 {
6256 priv->stats.rx_rssi_percentage[rfpath] =
6257 ( (priv->stats.rx_rssi_percentage[rfpath]*(Rx_Smooth_Factor-1)) +
6258 (pprevious_stats->RxMIMOSignalStrength[rfpath])) /(Rx_Smooth_Factor);
6259 priv->stats.rx_rssi_percentage[rfpath] = priv->stats.rx_rssi_percentage[rfpath] + 1;
6260 }
6261 else
6262 {
6263 priv->stats.rx_rssi_percentage[rfpath] =
6264 ( (priv->stats.rx_rssi_percentage[rfpath]*(Rx_Smooth_Factor-1)) +
6265 (pprevious_stats->RxMIMOSignalStrength[rfpath])) /(Rx_Smooth_Factor);
6266 }
6267 RT_TRACE(COMP_DBG,"priv->stats.rx_rssi_percentage[rfPath] = %d \n" ,priv->stats.rx_rssi_percentage[rfpath] );
6268 }
6269 }
6270
6271
6272 //
6273 // Check PWDB.
6274 //
6275 RT_TRACE(COMP_RXDESC, "Smooth %s PWDB = %d\n",
6276 pprevious_stats->bIsCCK? "CCK": "OFDM",
6277 pprevious_stats->RxPWDBAll);
6278
6279 if(pprevious_stats->bPacketBeacon)
6280 {
6281/* record the beacon pwdb to the sliding window. */
6282 if(slide_beacon_adc_pwdb_statistics++ >= PHY_Beacon_RSSI_SLID_WIN_MAX)
6283 {
6284 slide_beacon_adc_pwdb_statistics = PHY_Beacon_RSSI_SLID_WIN_MAX;
6285 last_beacon_adc_pwdb = priv->stats.Slide_Beacon_pwdb[slide_beacon_adc_pwdb_index];
6286 priv->stats.Slide_Beacon_Total -= last_beacon_adc_pwdb;
6287 //DbgPrint("slide_beacon_adc_pwdb_index = %d, last_beacon_adc_pwdb = %d, Adapter->RxStats.Slide_Beacon_Total = %d\n",
6288 // slide_beacon_adc_pwdb_index, last_beacon_adc_pwdb, Adapter->RxStats.Slide_Beacon_Total);
6289 }
6290 priv->stats.Slide_Beacon_Total += pprevious_stats->RxPWDBAll;
6291 priv->stats.Slide_Beacon_pwdb[slide_beacon_adc_pwdb_index] = pprevious_stats->RxPWDBAll;
6292 //DbgPrint("slide_beacon_adc_pwdb_index = %d, pPreviousRfd->Status.RxPWDBAll = %d\n", slide_beacon_adc_pwdb_index, pPreviousRfd->Status.RxPWDBAll);
6293 slide_beacon_adc_pwdb_index++;
6294 if(slide_beacon_adc_pwdb_index >= PHY_Beacon_RSSI_SLID_WIN_MAX)
6295 slide_beacon_adc_pwdb_index = 0;
6296 pprevious_stats->RxPWDBAll = priv->stats.Slide_Beacon_Total/slide_beacon_adc_pwdb_statistics;
6297 if(pprevious_stats->RxPWDBAll >= 3)
6298 pprevious_stats->RxPWDBAll -= 3;
6299 }
6300
6301 RT_TRACE(COMP_RXDESC, "Smooth %s PWDB = %d\n",
6302 pprevious_stats->bIsCCK? "CCK": "OFDM",
6303 pprevious_stats->RxPWDBAll);
6304
6305
6306 if(pprevious_stats->bPacketToSelf || pprevious_stats->bPacketBeacon || pprevious_stats->bToSelfBA)
6307 {
6308 if(priv->undecorated_smoothed_pwdb < 0) // initialize
6309 {
6310 priv->undecorated_smoothed_pwdb = pprevious_stats->RxPWDBAll;
6311 //DbgPrint("First pwdb initialize \n");
6312 }
6313#if 1
6314 if(pprevious_stats->RxPWDBAll > (u32)priv->undecorated_smoothed_pwdb)
6315 {
6316 priv->undecorated_smoothed_pwdb =
6317 ( ((priv->undecorated_smoothed_pwdb)*(Rx_Smooth_Factor-1)) +
6318 (pprevious_stats->RxPWDBAll)) /(Rx_Smooth_Factor);
6319 priv->undecorated_smoothed_pwdb = priv->undecorated_smoothed_pwdb + 1;
6320 }
6321 else
6322 {
6323 priv->undecorated_smoothed_pwdb =
6324 ( ((priv->undecorated_smoothed_pwdb)*(Rx_Smooth_Factor-1)) +
6325 (pprevious_stats->RxPWDBAll)) /(Rx_Smooth_Factor);
6326 }
6327#else
6328 //Fixed by Jacken 2008-03-20
6329 if(pPreviousRfd->Status.RxPWDBAll > (u32)pHalData->UndecoratedSmoothedPWDB)
6330 {
6331 pHalData->UndecoratedSmoothedPWDB =
6332 ( ((pHalData->UndecoratedSmoothedPWDB)* 5) + (pPreviousRfd->Status.RxPWDBAll)) / 6;
6333 pHalData->UndecoratedSmoothedPWDB = pHalData->UndecoratedSmoothedPWDB + 1;
6334 }
6335 else
6336 {
6337 pHalData->UndecoratedSmoothedPWDB =
6338 ( ((pHalData->UndecoratedSmoothedPWDB)* 5) + (pPreviousRfd->Status.RxPWDBAll)) / 6;
6339 }
6340#endif
6341
6342 }
6343
6344 //
6345 // Check EVM
6346 //
6347 /* record the general EVM to the sliding window. */
6348 if(pprevious_stats->SignalQuality == 0)
6349 {
6350 }
6351 else
6352 {
6353 if(pprevious_stats->bPacketToSelf || pprevious_stats->bPacketBeacon || pprevious_stats->bToSelfBA){
6354 if(slide_evm_statistics++ >= PHY_RSSI_SLID_WIN_MAX){
6355 slide_evm_statistics = PHY_RSSI_SLID_WIN_MAX;
6356 last_evm = priv->stats.slide_evm[slide_evm_index];
6357 priv->stats.slide_evm_total -= last_evm;
6358 }
6359
6360 priv->stats.slide_evm_total += pprevious_stats->SignalQuality;
6361
6362 priv->stats.slide_evm[slide_evm_index++] = pprevious_stats->SignalQuality;
6363 if(slide_evm_index >= PHY_RSSI_SLID_WIN_MAX)
6364 slide_evm_index = 0;
6365
6366 // <1> Showed on UI for user, in percentage.
6367 tmp_val = priv->stats.slide_evm_total/slide_evm_statistics;
6368 priv->stats.signal_quality = tmp_val;
6369 //cosa add 10/11/2007, Showed on UI for user in Windows Vista, for Link quality.
6370 priv->stats.last_signal_strength_inpercent = tmp_val;
6371 }
6372
6373 // <2> Showed on UI for engineering
6374 if(pprevious_stats->bPacketToSelf || pprevious_stats->bPacketBeacon || pprevious_stats->bToSelfBA)
6375 {
6376 for(nspatial_stream = 0; nspatial_stream<2 ; nspatial_stream++) // 2 spatial stream
6377 {
6378 if(pprevious_stats->RxMIMOSignalQuality[nspatial_stream] != -1)
6379 {
6380 if(priv->stats.rx_evm_percentage[nspatial_stream] == 0) // initialize
6381 {
6382 priv->stats.rx_evm_percentage[nspatial_stream] = pprevious_stats->RxMIMOSignalQuality[nspatial_stream];
6383 }
6384 priv->stats.rx_evm_percentage[nspatial_stream] =
6385 ( (priv->stats.rx_evm_percentage[nspatial_stream]* (Rx_Smooth_Factor-1)) +
6386 (pprevious_stats->RxMIMOSignalQuality[nspatial_stream]* 1)) / (Rx_Smooth_Factor);
6387 }
6388 }
6389 }
6390 }
6391
6392
6393}
6394
6395/*-----------------------------------------------------------------------------
6396 * Function: rtl819x_query_rxpwrpercentage()
6397 *
6398 * Overview:
6399 *
6400 * Input: char antpower
6401 *
6402 * Output: NONE
6403 *
6404 * Return: 0-100 percentage
6405 *
6406 * Revised History:
6407 * When Who Remark
6408 * 05/26/2008 amy Create Version 0 porting from windows code.
6409 *
6410 *---------------------------------------------------------------------------*/
6411static u8 rtl819x_query_rxpwrpercentage(
6412 char antpower
6413 )
6414{
6415 if ((antpower <= -100) || (antpower >= 20))
6416 {
6417 return 0;
6418 }
6419 else if (antpower >= 0)
6420 {
6421 return 100;
6422 }
6423 else
6424 {
6425 return (100+antpower);
6426 }
6427
6428} /* QueryRxPwrPercentage */
6429
6430static u8
6431rtl819x_evm_dbtopercentage(
6432 char value
6433 )
6434{
6435 char ret_val;
6436
6437 ret_val = value;
6438
6439 if(ret_val >= 0)
6440 ret_val = 0;
6441 if(ret_val <= -33)
6442 ret_val = -33;
6443 ret_val = 0 - ret_val;
6444 ret_val*=3;
6445 if(ret_val == 99)
6446 ret_val = 100;
6447 return(ret_val);
6448}
6449//
6450// Description:
6451// We want good-looking for signal strength/quality
6452// 2007/7/19 01:09, by cosa.
6453//
6454long
6455rtl819x_signal_scale_mapping(
6456 long currsig
6457 )
6458{
6459 long retsig;
6460
6461 // Step 1. Scale mapping.
6462 if(currsig >= 61 && currsig <= 100)
6463 {
6464 retsig = 90 + ((currsig - 60) / 4);
6465 }
6466 else if(currsig >= 41 && currsig <= 60)
6467 {
6468 retsig = 78 + ((currsig - 40) / 2);
6469 }
6470 else if(currsig >= 31 && currsig <= 40)
6471 {
6472 retsig = 66 + (currsig - 30);
6473 }
6474 else if(currsig >= 21 && currsig <= 30)
6475 {
6476 retsig = 54 + (currsig - 20);
6477 }
6478 else if(currsig >= 5 && currsig <= 20)
6479 {
6480 retsig = 42 + (((currsig - 5) * 2) / 3);
6481 }
6482 else if(currsig == 4)
6483 {
6484 retsig = 36;
6485 }
6486 else if(currsig == 3)
6487 {
6488 retsig = 27;
6489 }
6490 else if(currsig == 2)
6491 {
6492 retsig = 18;
6493 }
6494 else if(currsig == 1)
6495 {
6496 retsig = 9;
6497 }
6498 else
6499 {
6500 retsig = currsig;
6501 }
6502
6503 return retsig;
6504}
6505
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07006506/*-----------------------------------------------------------------------------
6507 * Function: QueryRxPhyStatus8192S()
6508 *
6509 * Overview:
6510 *
6511 * Input: NONE
6512 *
6513 * Output: NONE
6514 *
6515 * Return: NONE
6516 *
6517 * Revised History:
6518 * When Who Remark
6519 * 06/01/2007 MHC Create Version 0.
6520 * 06/05/2007 MHC Accordign to HW's new data sheet, we add CCK and OFDM
6521 * descriptor definition.
6522 * 07/04/2007 MHC According to Jerry and Bryant's document. We read
6523 * ir_isolation and ext_lna for RF's init value and use
6524 * to compensate RSSI after receiving packets.
6525 * 09/10/2008 MHC Modify name and PHY status field for 92SE.
6526 * 09/19/2008 MHC Add CCK/OFDM SS/SQ for 92S series.
6527 *
6528 *---------------------------------------------------------------------------*/
6529static void rtl8192SU_query_rxphystatus(
6530 struct r8192_priv * priv,
6531 struct ieee80211_rx_stats * pstats,
6532 rx_desc_819x_usb *pDesc,
6533 rx_drvinfo_819x_usb * pdrvinfo,
6534 struct ieee80211_rx_stats * precord_stats,
6535 bool bpacket_match_bssid,
6536 bool bpacket_toself,
6537 bool bPacketBeacon,
6538 bool bToSelfBA
6539 )
6540{
6541 //PRT_RFD_STATUS pRtRfdStatus = &(pRfd->Status);
6542 //PHY_STS_CCK_8192S_T *pCck_buf;
6543 phy_sts_cck_819xusb_t * pcck_buf;
6544 phy_ofdm_rx_status_rxsc_sgien_exintfflag* prxsc;
6545 //u8 *prxpkt;
6546 //u8 i, max_spatial_stream, tmp_rxsnr, tmp_rxevm, rxsc_sgien_exflg;
6547 u8 i, max_spatial_stream, rxsc_sgien_exflg;
6548 char rx_pwr[4], rx_pwr_all=0;
6549 //long rx_avg_pwr = 0;
6550 //char rx_snrX, rx_evmX;
6551 u8 evm, pwdb_all;
6552 u32 RSSI, total_rssi=0;//, total_evm=0;
6553// long signal_strength_index = 0;
6554 u8 is_cck_rate=0;
6555 u8 rf_rx_num = 0;
6556
6557
6558
6559 priv->stats.numqry_phystatus++;
6560
6561 is_cck_rate = rx_hal_is_cck_rate(pDesc);
6562
6563 // Record it for next packet processing
6564 memset(precord_stats, 0, sizeof(struct ieee80211_rx_stats));
6565 pstats->bPacketMatchBSSID = precord_stats->bPacketMatchBSSID = bpacket_match_bssid;
6566 pstats->bPacketToSelf = precord_stats->bPacketToSelf = bpacket_toself;
6567 pstats->bIsCCK = precord_stats->bIsCCK = is_cck_rate;//RX_HAL_IS_CCK_RATE(pDrvInfo);
6568 pstats->bPacketBeacon = precord_stats->bPacketBeacon = bPacketBeacon;
6569 pstats->bToSelfBA = precord_stats->bToSelfBA = bToSelfBA;
6570
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07006571
6572 pstats->RxMIMOSignalQuality[0] = -1;
6573 pstats->RxMIMOSignalQuality[1] = -1;
6574 precord_stats->RxMIMOSignalQuality[0] = -1;
6575 precord_stats->RxMIMOSignalQuality[1] = -1;
6576
6577 if(is_cck_rate)
6578 {
6579 u8 report;//, tmp_pwdb;
6580 //char cck_adc_pwdb[4];
6581
6582 // CCK Driver info Structure is not the same as OFDM packet.
6583 pcck_buf = (phy_sts_cck_819xusb_t *)pdrvinfo;
6584
6585 //
6586 // (1)Hardware does not provide RSSI for CCK
6587 //
6588
6589 //
6590 // (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive)
6591 //
6592
6593 priv->stats.numqry_phystatusCCK++;
6594
6595 if(!priv->bCckHighPower)
6596 {
6597 report = pcck_buf->cck_agc_rpt & 0xc0;
6598 report = report>>6;
6599 switch(report)
6600 {
6601 //Fixed by Jacken from Bryant 2008-03-20
6602 //Original value is -38 , -26 , -14 , -2
6603 //Fixed value is -35 , -23 , -11 , 6
6604 case 0x3:
6605 rx_pwr_all = -35 - (pcck_buf->cck_agc_rpt & 0x3e);
6606 break;
6607 case 0x2:
6608 rx_pwr_all = -23 - (pcck_buf->cck_agc_rpt & 0x3e);
6609 break;
6610 case 0x1:
6611 rx_pwr_all = -11 - (pcck_buf->cck_agc_rpt & 0x3e);
6612 break;
6613 case 0x0:
6614 rx_pwr_all = 8 - (pcck_buf->cck_agc_rpt & 0x3e);//6->8
6615 break;
6616 }
6617 }
6618 else
6619 {
6620 report = pdrvinfo->cfosho[0] & 0x60;
6621 report = report>>5;
6622 switch(report)
6623 {
6624 case 0x3:
6625 rx_pwr_all = -35 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1) ;
6626 break;
6627 case 0x2:
6628 rx_pwr_all = -23 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1);
6629 break;
6630 case 0x1:
6631 rx_pwr_all = -11 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1) ;
6632 break;
6633 case 0x0:
6634 rx_pwr_all = -8 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1) ;//6->-8
6635 break;
6636 }
6637 }
6638
6639 pwdb_all = rtl819x_query_rxpwrpercentage(rx_pwr_all);//check it
6640 pstats->RxPWDBAll = precord_stats->RxPWDBAll = pwdb_all;
6641 //pstats->RecvSignalPower = pwdb_all;
6642 pstats->RecvSignalPower = rx_pwr_all;
6643
6644 //
6645 // (3) Get Signal Quality (EVM)
6646 //
6647 //if(bpacket_match_bssid)
6648 {
6649 u8 sq;
6650
6651 if(pstats->RxPWDBAll > 40)
6652 {
6653 sq = 100;
6654 }else
6655 {
6656 sq = pcck_buf->sq_rpt;
6657
6658 if(pcck_buf->sq_rpt > 64)
6659 sq = 0;
6660 else if (pcck_buf->sq_rpt < 20)
6661 sq = 100;
6662 else
6663 sq = ((64-sq) * 100) / 44;
6664 }
6665 pstats->SignalQuality = precord_stats->SignalQuality = sq;
6666 pstats->RxMIMOSignalQuality[0] = precord_stats->RxMIMOSignalQuality[0] = sq;
6667 pstats->RxMIMOSignalQuality[1] = precord_stats->RxMIMOSignalQuality[1] = -1;
6668 }
6669 }
6670 else
6671 {
6672 priv->stats.numqry_phystatusHT++;
6673
6674 // 2008/09/19 MH For 92S debug, RX RF path always enable!!
6675 priv->brfpath_rxenable[0] = priv->brfpath_rxenable[1] = TRUE;
6676
6677 //
6678 // (1)Get RSSI for HT rate
6679 //
6680 //for(i=RF90_PATH_A; i<priv->NumTotalRFPath; i++)
6681 for(i=RF90_PATH_A; i<RF90_PATH_MAX; i++)
6682 {
6683 // 2008/01/30 MH we will judge RF RX path now.
6684 if (priv->brfpath_rxenable[i])
6685 rf_rx_num++;
6686 //else
6687 // continue;
6688
6689 //if (!rtl8192_phy_CheckIsLegalRFPath(priv->ieee80211->dev, i))
6690 // continue;
6691
6692 //Fixed by Jacken from Bryant 2008-03-20
6693 //Original value is 106
6694 //rx_pwr[i] = ((pofdm_buf->trsw_gain_X[i]&0x3F)*2) - 106;
6695 rx_pwr[i] = ((pdrvinfo->gain_trsw[i]&0x3F)*2) - 110;
6696
6697 /* Translate DBM to percentage. */
6698 RSSI = rtl819x_query_rxpwrpercentage(rx_pwr[i]); //check ok
6699 total_rssi += RSSI;
6700 RT_TRACE(COMP_RF, "RF-%d RXPWR=%x RSSI=%d\n", i, rx_pwr[i], RSSI);
6701
6702 //Get Rx snr value in DB
6703 //tmp_rxsnr = pofdm_buf->rxsnr_X[i];
6704 //rx_snrX = (char)(tmp_rxsnr);
6705 //rx_snrX /= 2;
6706 //priv->stats.rxSNRdB[i] = (long)rx_snrX;
6707 priv->stats.rxSNRdB[i] = (long)(pdrvinfo->rxsnr[i]/2);
6708
6709 /* Translate DBM to percentage. */
6710 //RSSI = rtl819x_query_rxpwrpercentage(rx_pwr[i]);
6711 //total_rssi += RSSI;
6712
6713 /* Record Signal Strength for next packet */
6714 //if(bpacket_match_bssid)
6715 {
6716 pstats->RxMIMOSignalStrength[i] =(u8) RSSI;
6717 precord_stats->RxMIMOSignalStrength[i] =(u8) RSSI;
6718 }
6719 }
6720
6721
6722 //
6723 // (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive)
6724 //
6725 //Fixed by Jacken from Bryant 2008-03-20
6726 //Original value is 106
6727 //rx_pwr_all = (((pofdm_buf->pwdb_all ) >> 1 )& 0x7f) -106;
6728 rx_pwr_all = (((pdrvinfo->pwdb_all ) >> 1 )& 0x7f) -106;
6729 pwdb_all = rtl819x_query_rxpwrpercentage(rx_pwr_all);
6730
6731 pstats->RxPWDBAll = precord_stats->RxPWDBAll = pwdb_all;
6732 pstats->RxPower = precord_stats->RxPower = rx_pwr_all;
6733 pstats->RecvSignalPower = rx_pwr_all;
6734
6735 //
6736 // (3)EVM of HT rate
6737 //
6738 //if(pdrvinfo->RxHT && pdrvinfo->RxRate>=DESC90_RATEMCS8 &&
6739 // pdrvinfo->RxRate<=DESC90_RATEMCS15)
6740 if(pDesc->RxHT && pDesc->RxMCS>=DESC92S_RATEMCS8 &&
6741 pDesc->RxMCS<=DESC92S_RATEMCS15)
6742 max_spatial_stream = 2; //both spatial stream make sense
6743 else
6744 max_spatial_stream = 1; //only spatial stream 1 makes sense
6745
6746 for(i=0; i<max_spatial_stream; i++)
6747 {
6748 //tmp_rxevm = pofdm_buf->rxevm_X[i];
6749 //rx_evmX = (char)(tmp_rxevm);
6750
6751 // Do not use shift operation like "rx_evmX >>= 1" because the compilor of free build environment
6752 // fill most significant bit to "zero" when doing shifting operation which may change a negative
6753 // value to positive one, then the dbm value (which is supposed to be negative) is not correct anymore.
6754 //rx_evmX /= 2; //dbm
6755
6756 //evm = rtl819x_evm_dbtopercentage(rx_evmX);
6757 evm = rtl819x_evm_dbtopercentage( (pdrvinfo->rxevm[i] /*/ 2*/)); //dbm
6758 RT_TRACE(COMP_RF, "RXRATE=%x RXEVM=%x EVM=%s%d\n", pDesc->RxMCS, pdrvinfo->rxevm[i], "%", evm);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07006759
6760 //if(bpacket_match_bssid)
6761 {
6762 if(i==0) // Fill value in RFD, Get the first spatial stream only
6763 pstats->SignalQuality = precord_stats->SignalQuality = (u8)(evm & 0xff);
6764 pstats->RxMIMOSignalQuality[i] = precord_stats->RxMIMOSignalQuality[i] = (u8)(evm & 0xff);
6765 }
6766 }
6767
6768
6769 /* record rx statistics for debug */
6770 //rxsc_sgien_exflg = pofdm_buf->rxsc_sgien_exflg;
6771 prxsc = (phy_ofdm_rx_status_rxsc_sgien_exintfflag *)&rxsc_sgien_exflg;
6772 //if(pdrvinfo->BW) //40M channel
6773 if(pDesc->BW) //40M channel
6774 priv->stats.received_bwtype[1+pdrvinfo->rxsc]++;
6775 else //20M channel
6776 priv->stats.received_bwtype[0]++;
6777 }
6778
6779 //UI BSS List signal strength(in percentage), make it good looking, from 0~100.
6780 //It is assigned to the BSS List in GetValueFromBeaconOrProbeRsp().
6781 if(is_cck_rate)
6782 {
6783 pstats->SignalStrength = precord_stats->SignalStrength = (u8)(rtl819x_signal_scale_mapping((long)pwdb_all));//PWDB_ALL;//check ok
6784
6785 }
6786 else
6787 {
6788 //pRfd->Status.SignalStrength = pRecordRfd->Status.SignalStrength = (u8)(SignalScaleMapping(total_rssi/=RF90_PATH_MAX));//(u8)(total_rssi/=RF90_PATH_MAX);
6789 // We can judge RX path number now.
6790 if (rf_rx_num != 0)
6791 pstats->SignalStrength = precord_stats->SignalStrength = (u8)(rtl819x_signal_scale_mapping((long)(total_rssi/=rf_rx_num)));
6792 }
6793}/* QueryRxPhyStatus8192S */
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07006794
6795void
6796rtl8192_record_rxdesc_forlateruse(
6797 struct ieee80211_rx_stats * psrc_stats,
6798 struct ieee80211_rx_stats * ptarget_stats
6799)
6800{
6801 ptarget_stats->bIsAMPDU = psrc_stats->bIsAMPDU;
6802 ptarget_stats->bFirstMPDU = psrc_stats->bFirstMPDU;
6803 ptarget_stats->Seq_Num = psrc_stats->Seq_Num;
6804}
6805
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07006806static void rtl8192SU_query_rxphystatus(
6807 struct r8192_priv * priv,
6808 struct ieee80211_rx_stats * pstats,
6809 rx_desc_819x_usb *pDesc,
6810 rx_drvinfo_819x_usb * pdrvinfo,
6811 struct ieee80211_rx_stats * precord_stats,
6812 bool bpacket_match_bssid,
6813 bool bpacket_toself,
6814 bool bPacketBeacon,
6815 bool bToSelfBA
6816 );
6817void rtl8192SU_TranslateRxSignalStuff(struct sk_buff *skb,
6818 struct ieee80211_rx_stats * pstats,
6819 rx_desc_819x_usb *pDesc,
6820 rx_drvinfo_819x_usb *pdrvinfo)
6821{
6822 // TODO: We must only check packet for current MAC address. Not finish
6823 rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
6824 struct net_device *dev=info->dev;
6825 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
6826 bool bpacket_match_bssid, bpacket_toself;
6827 bool bPacketBeacon=FALSE, bToSelfBA=FALSE;
6828 static struct ieee80211_rx_stats previous_stats;
6829 struct ieee80211_hdr_3addr *hdr;//by amy
6830 u16 fc,type;
6831
6832 // Get Signal Quality for only RX data queue (but not command queue)
6833
6834 u8* tmp_buf;
6835 //u16 tmp_buf_len = 0;
6836 u8 *praddr;
6837
6838 /* Get MAC frame start address. */
6839 tmp_buf = (u8*)skb->data;// + get_rxpacket_shiftbytes_819xusb(pstats);
6840
6841 hdr = (struct ieee80211_hdr_3addr *)tmp_buf;
6842 fc = le16_to_cpu(hdr->frame_ctl);
6843 type = WLAN_FC_GET_TYPE(fc);
6844 praddr = hdr->addr1;
6845
6846 /* Check if the received packet is acceptabe. */
6847 bpacket_match_bssid = ((IEEE80211_FTYPE_CTL != type) &&
6848 (eqMacAddr(priv->ieee80211->current_network.bssid, (fc & IEEE80211_FCTL_TODS)? hdr->addr1 : (fc & IEEE80211_FCTL_FROMDS )? hdr->addr2 : hdr->addr3))
6849 && (!pstats->bHwError) && (!pstats->bCRC)&& (!pstats->bICV));
6850 bpacket_toself = bpacket_match_bssid & (eqMacAddr(praddr, priv->ieee80211->dev->dev_addr));
6851
6852#if 1//cosa
6853 if(WLAN_FC_GET_FRAMETYPE(fc)== IEEE80211_STYPE_BEACON)
6854 {
6855 bPacketBeacon = true;
6856 //DbgPrint("Beacon 2, MatchBSSID = %d, ToSelf = %d \n", bPacketMatchBSSID, bPacketToSelf);
6857 }
6858 if(WLAN_FC_GET_FRAMETYPE(fc) == IEEE80211_STYPE_BLOCKACK)
6859 {
6860 if((eqMacAddr(praddr,dev->dev_addr)))
6861 bToSelfBA = true;
6862 //DbgPrint("BlockAck, MatchBSSID = %d, ToSelf = %d \n", bPacketMatchBSSID, bPacketToSelf);
6863 }
6864
6865#endif
6866
6867
6868 if(bpacket_match_bssid)
6869 {
6870 priv->stats.numpacket_matchbssid++;
6871 }
6872 if(bpacket_toself){
6873 priv->stats.numpacket_toself++;
6874 }
6875 //
6876 // Process PHY information for previous packet (RSSI/PWDB/EVM)
6877 //
6878 // Because phy information is contained in the last packet of AMPDU only, so driver
6879 // should process phy information of previous packet
6880 rtl8192_process_phyinfo(priv, tmp_buf, &previous_stats, pstats);
6881 rtl8192SU_query_rxphystatus(priv, pstats, pDesc, pdrvinfo, &previous_stats, bpacket_match_bssid,bpacket_toself,bPacketBeacon,bToSelfBA);
6882 rtl8192_record_rxdesc_forlateruse(pstats, &previous_stats);
6883
6884}
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07006885
6886/**
6887* Function: UpdateReceivedRateHistogramStatistics
6888* Overview: Recored down the received data rate
6889*
6890* Input:
6891* struct net_device *dev
6892* struct ieee80211_rx_stats *stats
6893*
6894* Output:
6895*
6896* (priv->stats.ReceivedRateHistogram[] is updated)
6897* Return:
6898* None
6899*/
6900void
6901UpdateReceivedRateHistogramStatistics8190(
6902 struct net_device *dev,
6903 struct ieee80211_rx_stats *stats
6904 )
6905{
6906 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
6907 u32 rcvType=1; //0: Total, 1:OK, 2:CRC, 3:ICV
6908 u32 rateIndex;
6909 u32 preamble_guardinterval; //1: short preamble/GI, 0: long preamble/GI
6910
6911
6912 if(stats->bCRC)
6913 rcvType = 2;
6914 else if(stats->bICV)
6915 rcvType = 3;
6916
6917 if(stats->bShortPreamble)
6918 preamble_guardinterval = 1;// short
6919 else
6920 preamble_guardinterval = 0;// long
6921
6922 switch(stats->rate)
6923 {
6924 //
6925 // CCK rate
6926 //
6927 case MGN_1M: rateIndex = 0; break;
6928 case MGN_2M: rateIndex = 1; break;
6929 case MGN_5_5M: rateIndex = 2; break;
6930 case MGN_11M: rateIndex = 3; break;
6931 //
6932 // Legacy OFDM rate
6933 //
6934 case MGN_6M: rateIndex = 4; break;
6935 case MGN_9M: rateIndex = 5; break;
6936 case MGN_12M: rateIndex = 6; break;
6937 case MGN_18M: rateIndex = 7; break;
6938 case MGN_24M: rateIndex = 8; break;
6939 case MGN_36M: rateIndex = 9; break;
6940 case MGN_48M: rateIndex = 10; break;
6941 case MGN_54M: rateIndex = 11; break;
6942 //
6943 // 11n High throughput rate
6944 //
6945 case MGN_MCS0: rateIndex = 12; break;
6946 case MGN_MCS1: rateIndex = 13; break;
6947 case MGN_MCS2: rateIndex = 14; break;
6948 case MGN_MCS3: rateIndex = 15; break;
6949 case MGN_MCS4: rateIndex = 16; break;
6950 case MGN_MCS5: rateIndex = 17; break;
6951 case MGN_MCS6: rateIndex = 18; break;
6952 case MGN_MCS7: rateIndex = 19; break;
6953 case MGN_MCS8: rateIndex = 20; break;
6954 case MGN_MCS9: rateIndex = 21; break;
6955 case MGN_MCS10: rateIndex = 22; break;
6956 case MGN_MCS11: rateIndex = 23; break;
6957 case MGN_MCS12: rateIndex = 24; break;
6958 case MGN_MCS13: rateIndex = 25; break;
6959 case MGN_MCS14: rateIndex = 26; break;
6960 case MGN_MCS15: rateIndex = 27; break;
6961 default: rateIndex = 28; break;
6962 }
6963 priv->stats.received_preamble_GI[preamble_guardinterval][rateIndex]++;
6964 priv->stats.received_rate_histogram[0][rateIndex]++; //total
6965 priv->stats.received_rate_histogram[rcvType][rateIndex]++;
6966}
6967
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07006968void rtl8192SU_query_rxdesc_status(struct sk_buff *skb, struct ieee80211_rx_stats *stats, bool bIsRxAggrSubframe)
6969{
6970 rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
6971 struct net_device *dev=info->dev;
6972 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
6973 //rx_desc_819x_usb *desc = (rx_desc_819x_usb *)skb->data;
6974 rx_drvinfo_819x_usb *driver_info = NULL;
6975
6976 //PRT_RFD_STATUS pRtRfdStatus = &pRfd->Status;
6977 //PHAL_DATA_8192SUSB pHalData = GET_HAL_DATA(Adapter);
6978 //pu1Byte pDesc = (pu1Byte)pDescIn;
6979 //PRX_DRIVER_INFO_8192S pDrvInfo;
6980
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07006981 rx_desc_819x_usb *desc = (rx_desc_819x_usb *)skb->data;
6982
6983 if(0)
6984 {
6985 int m = 0;
6986 printk("========================");
6987 for(m=0; m<skb->len; m++){
6988 if((m%32) == 0)
6989 printk("\n");
6990 printk("%2x ",((u8*)skb->data)[m]);
6991 }
6992 printk("\n========================\n");
6993
6994 }
6995
6996
6997 //
6998 //Get Rx Descriptor Raw Information
6999 //
7000 stats->Length = desc->Length ;
7001 stats->RxDrvInfoSize = desc->RxDrvInfoSize*RX_DRV_INFO_SIZE_UNIT;
7002 stats->RxBufShift = (desc->Shift)&0x03;
7003 stats->bICV = desc->ICV;
7004 stats->bCRC = desc->CRC32;
7005 stats->bHwError = stats->bCRC|stats->bICV;
7006 stats->Decrypted = !desc->SWDec;//RTL8190 set this bit to indicate that Hw does not decrypt packet
7007 stats->bIsAMPDU = (desc->AMSDU==1);
7008 stats->bFirstMPDU = (desc->PAGGR==1) && (desc->FAGGR==1);
7009 stats->bShortPreamble = desc->SPLCP;
7010 stats->RxIs40MHzPacket = (desc->BW==1);
7011 stats->TimeStampLow = desc->TSFL;
7012
7013 if((desc->FAGGR==1) || (desc->PAGGR==1))
7014 {// Rx A-MPDU
7015 RT_TRACE(COMP_RXDESC, "FirstAGGR = %d, PartAggr = %d\n", desc->FAGGR, desc->PAGGR);
7016 }
7017//YJ,test,090310
7018if(stats->bHwError)
7019{
7020 if(stats->bICV)
7021 printk("%s: Receive ICV error!!!!!!!!!!!!!!!!!!!!!!\n", __FUNCTION__);
7022 if(stats->bCRC)
7023 printk("%s: Receive CRC error!!!!!!!!!!!!!!!!!!!!!!\n", __FUNCTION__);
7024}
7025
7026 if(IS_UNDER_11N_AES_MODE(priv->ieee80211))
7027 {
7028 // Always received ICV error packets in AES mode.
7029 // This fixed HW later MIC write bug.
7030 if(stats->bICV && !stats->bCRC)
7031 {
7032 stats->bICV = FALSE;
7033 stats->bHwError = FALSE;
7034 }
7035 }
7036
7037 // Transform HwRate to MRate
7038 if(!stats->bHwError)
7039 //stats->DataRate = HwRateToMRate(
7040 // (BOOLEAN)GET_RX_DESC_RXHT(pDesc),
7041 // (u1Byte)GET_RX_DESC_RXMCS(pDesc),
7042 // (BOOLEAN)GET_RX_DESC_PAGGR(pDesc));
7043 stats->rate = rtl8192SU_HwRateToMRate(desc->RxHT, desc->RxMCS, desc->PAGGR);
7044 else
7045 stats->rate = MGN_1M;
7046
7047 //
7048 // Collect Rx rate/AMPDU/TSFL
7049 //
7050 //UpdateRxdRateHistogramStatistics8192S(Adapter, pRfd);
7051 //UpdateRxAMPDUHistogramStatistics8192S(Adapter, pRfd);
7052 //UpdateRxPktTimeStamp8192S(Adapter, pRfd);
7053 UpdateReceivedRateHistogramStatistics8190(dev, stats);
7054 //UpdateRxAMPDUHistogramStatistics8192S(dev, stats); //FIXLZM
7055 UpdateRxPktTimeStamp8190(dev, stats);
7056
7057 //
7058 // Get PHY Status and RSVD parts.
7059 // <Roger_Notes> It only appears on last aggregated packet.
7060 //
7061 if (desc->PHYStatus)
7062 {
7063 //driver_info = (rx_drvinfo_819x_usb *)(skb->data + RX_DESC_SIZE + stats->RxBufShift);
7064 driver_info = (rx_drvinfo_819x_usb *)(skb->data + sizeof(rx_desc_819x_usb) + \
7065 stats->RxBufShift);
7066 if(0)
7067 {
7068 int m = 0;
7069 printk("========================\n");
7070 printk("RX_DESC_SIZE:%d, RxBufShift:%d, RxDrvInfoSize:%d\n",
7071 RX_DESC_SIZE, stats->RxBufShift, stats->RxDrvInfoSize);
7072 for(m=0; m<32; m++){
7073 printk("%2x ",((u8*)driver_info)[m]);
7074 }
7075 printk("\n========================\n");
7076
7077 }
7078
7079 }
7080
7081 //YJ,add,090107
7082 skb_pull(skb, sizeof(rx_desc_819x_usb));
7083 //YJ,add,090107,end
7084
7085 //
7086 // Get Total offset of MPDU Frame Body
7087 //
7088 if((stats->RxBufShift + stats->RxDrvInfoSize) > 0)
7089 {
7090 stats->bShift = 1;
7091 //YJ,add,090107
7092 skb_pull(skb, stats->RxBufShift + stats->RxDrvInfoSize);
7093 //YJ,add,090107,end
7094 }
7095
7096 //
7097 // Get PHY Status and RSVD parts.
7098 // <Roger_Notes> It only appears on last aggregated packet.
7099 //
7100 if (desc->PHYStatus)
7101 {
7102 rtl8192SU_TranslateRxSignalStuff(skb, stats, desc, driver_info);
7103 }
7104}
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07007105
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07007106//
7107// Description:
7108// The strarting address of wireless lan header will shift 1 or 2 or 3 or "more" bytes for the following reason :
7109// (1) QoS control : shift 2 bytes
7110// (2) Mesh Network : shift 1 or 3 bytes
7111// (3) RxDriverInfo occupies the front parts of Rx Packets buffer(shift units is in 8Bytes)
7112//
7113// It is because Lextra CPU used by 8186 or 865x series assert exception if the statrting address
7114// of IP header is not double word alignment.
7115// This features is supported in 818xb and 8190 only, but not 818x.
7116//
7117// parameter: PRT_RFD, Pointer of Reeceive frame descriptor which is initialized according to
7118// Rx Descriptor
7119// return value: unsigned int, number of total shifted bytes
7120//
7121// Notes: 2008/06/28, created by Roger
7122//
7123u32 GetRxPacketShiftBytes8192SU(struct ieee80211_rx_stats *Status, bool bIsRxAggrSubframe)
7124{
7125 //PRT_RFD_STATUS pRtRfdStatus = &pRfd->Status;
7126
7127 return (sizeof(rx_desc_819x_usb) + Status->RxDrvInfoSize + Status->RxBufShift);
7128}
7129
7130void rtl8192SU_rx_nomal(struct sk_buff* skb)
7131{
7132 rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
7133 struct net_device *dev=info->dev;
7134 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
7135 struct ieee80211_rx_stats stats = {
7136 .signal = 0,
7137 .noise = -98,
7138 .rate = 0,
7139 // .mac_time = jiffies,
7140 .freq = IEEE80211_24GHZ_BAND,
7141 };
7142 u32 rx_pkt_len = 0;
7143 struct ieee80211_hdr_1addr *ieee80211_hdr = NULL;
7144 bool unicast_packet = false;
7145
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07007146 //printk("**********skb->len = %d\n", skb->len);
7147 /* 20 is for ps-poll */
7148 if((skb->len >=(20 + sizeof(rx_desc_819x_usb))) && (skb->len < RX_URB_SIZE)) {
7149
7150 /* first packet should not contain Rx aggregation header */
7151 rtl8192SU_query_rxdesc_status(skb, &stats, false);
7152 /* TODO */
7153
7154 /* hardware related info */
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07007155 priv->stats.rxoktotal++; //YJ,test,090108
7156
7157 /* Process the MPDU recevied */
7158 skb_trim(skb, skb->len - 4/*sCrcLng*/);//FIXLZM
7159
7160 rx_pkt_len = skb->len;
7161 ieee80211_hdr = (struct ieee80211_hdr_1addr *)skb->data;
7162 unicast_packet = false;
7163 if(is_broadcast_ether_addr(ieee80211_hdr->addr1)) {
7164 //TODO
7165 }else if(is_multicast_ether_addr(ieee80211_hdr->addr1)){
7166 //TODO
7167 }else {
7168 /* unicast packet */
7169 unicast_packet = true;
7170 }
7171
7172 if(!ieee80211_rx(priv->ieee80211,skb, &stats)) {
7173 dev_kfree_skb_any(skb);
7174 } else {
7175 // priv->stats.rxoktotal++; //YJ,test,090108
7176 if(unicast_packet) {
7177 priv->stats.rxbytesunicast += rx_pkt_len;
7178 }
7179 }
7180
7181 //up is firs pkt, follow is next and next
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07007182 }
7183 else
7184 {
7185 priv->stats.rxurberr++;
7186 printk("actual_length:%d\n", skb->len);
7187 dev_kfree_skb_any(skb);
7188 }
7189
7190}
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07007191
7192void
7193rtl819xusb_process_received_packet(
7194 struct net_device *dev,
7195 struct ieee80211_rx_stats *pstats
7196 )
7197{
7198// bool bfreerfd=false, bqueued=false;
7199 u8* frame;
7200 u16 frame_len=0;
7201 struct r8192_priv *priv = ieee80211_priv(dev);
7202// u8 index = 0;
7203// u8 TID = 0;
7204 //u16 seqnum = 0;
7205 //PRX_TS_RECORD pts = NULL;
7206
7207 // Get shifted bytes of Starting address of 802.11 header. 2006.09.28, by Emily
7208 //porting by amy 080508
7209 pstats->virtual_address += get_rxpacket_shiftbytes_819xusb(pstats);
7210 frame = pstats->virtual_address;
7211 frame_len = pstats->packetlength;
7212#ifdef TODO // by amy about HCT
7213 if(!Adapter->bInHctTest)
7214 CountRxErrStatistics(Adapter, pRfd);
7215#endif
7216 {
7217 #ifdef ENABLE_PS //by amy for adding ps function in future
7218 RT_RF_POWER_STATE rtState;
7219 // When RF is off, we should not count the packet for hw/sw synchronize
7220 // reason, ie. there may be a duration while sw switch is changed and hw
7221 // switch is being changed. 2006.12.04, by shien chang.
7222 Adapter->HalFunc.GetHwRegHandler(Adapter, HW_VAR_RF_STATE, (u8* )(&rtState));
7223 if (rtState == eRfOff)
7224 {
7225 return;
7226 }
7227 #endif
7228 priv->stats.rxframgment++;
7229
7230 }
7231#ifdef TODO
7232 RmMonitorSignalStrength(Adapter, pRfd);
7233#endif
7234 /* 2007/01/16 MH Add RX command packet handle here. */
7235 /* 2007/03/01 MH We have to release RFD and return if rx pkt is cmd pkt. */
7236 if (rtl819xusb_rx_command_packet(dev, pstats))
7237 {
7238 return;
7239 }
7240
7241#ifdef SW_CRC_CHECK
7242 SwCrcCheck();
7243#endif
7244
7245
7246}
7247
7248void query_rx_cmdpkt_desc_status(struct sk_buff *skb, struct ieee80211_rx_stats *stats)
7249{
7250// rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
7251// struct net_device *dev=info->dev;
7252// struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
7253 rx_desc_819x_usb *desc = (rx_desc_819x_usb *)skb->data;
7254// rx_drvinfo_819x_usb *driver_info;
7255
7256 //
7257 //Get Rx Descriptor Information
7258 //
7259 stats->virtual_address = (u8*)skb->data;
7260 stats->Length = desc->Length;
7261 stats->RxDrvInfoSize = 0;
7262 stats->RxBufShift = 0;
7263 stats->packetlength = stats->Length-scrclng;
7264 stats->fraglength = stats->packetlength;
7265 stats->fragoffset = 0;
7266 stats->ntotalfrag = 1;
7267}
7268
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07007269void rtl8192SU_rx_cmd(struct sk_buff *skb)
7270{
7271 struct rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
7272 struct net_device *dev = info->dev;
7273
7274 /* TODO */
7275 struct ieee80211_rx_stats stats = {
7276 .signal = 0,
7277 .noise = -98,
7278 .rate = 0,
7279 // .mac_time = jiffies,
7280 .freq = IEEE80211_24GHZ_BAND,
7281 };
7282
7283 //
7284 // Check buffer length to determine if this is a valid MPDU.
7285 //
7286 if( (skb->len >= sizeof(rx_desc_819x_usb)) && (skb->len <= RX_URB_SIZE) )//&&
7287 //(pHalData->SwChnlInProgress == FALSE))
7288 {
7289 //
7290 // Collection information in Rx descriptor.
7291 //
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07007292 query_rx_cmdpkt_desc_status(skb,&stats);
7293 // this is to be done by amy 080508 prfd->queue_id = 1;
7294
7295 //
7296 // Process the MPDU recevied.
7297 //
7298 rtl819xusb_process_received_packet(dev,&stats);
7299
7300 dev_kfree_skb_any(skb);
7301 }
7302 else
7303 {
7304 //RTInsertTailListWithCnt(&pAdapter->RfdIdleQueue, &pRfd->List, &pAdapter->NumIdleRfd);
7305 //RT_ASSERT(pAdapter->NumIdleRfd <= pAdapter->NumRfd, ("HalUsbInCommandComplete8192SUsb(): Adapter->NumIdleRfd(%d)\n", pAdapter->NumIdleRfd));
7306 //RT_TRACE(COMP_RECV, DBG_LOUD, ("HalUsbInCommandComplete8192SUsb(): NOT enough Resources!! BufLenUsed(%d), NumIdleRfd(%d)\n",
7307 //pContext->BufLenUsed, pAdapter->NumIdleRfd));
7308 }
7309
7310 //
7311 // Reuse USB_IN_CONTEXT since we had finished processing the
7312 // buffer in USB_IN_CONTEXT.
7313 //
7314 //HalUsbReturnInContext(pAdapter, pContext);
7315
7316 //
7317 // Issue another bulk IN transfer.
7318 //
7319 //HalUsbInMpdu(pAdapter, PipeIndex);
7320
7321 RT_TRACE(COMP_RECV, "<--- HalUsbInCommandComplete8192SUsb()\n");
7322
7323}
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07007324
7325void rtl8192_irq_rx_tasklet(struct r8192_priv *priv)
7326{
7327 struct sk_buff *skb;
7328 struct rtl8192_rx_info *info;
7329
7330 while (NULL != (skb = skb_dequeue(&priv->skb_queue))) {
7331 info = (struct rtl8192_rx_info *)skb->cb;
7332 switch (info->out_pipe) {
7333 /* Nomal packet pipe */
7334 case 3:
7335 //RT_TRACE(COMP_RECV, "normal in-pipe index(%d)\n",info->out_pipe);
7336 priv->IrpPendingCount--;
7337 priv->ops->rtl819x_rx_nomal(skb);
7338 break;
7339
7340 /* Command packet pipe */
7341 case 9:
7342 RT_TRACE(COMP_RECV, "command in-pipe index(%d)\n",\
7343 info->out_pipe);
7344 priv->ops->rtl819x_rx_cmd(skb);
7345 break;
7346
7347 default: /* should never get here! */
7348 RT_TRACE(COMP_ERR, "Unknown in-pipe index(%d)\n",\
7349 info->out_pipe);
7350 dev_kfree_skb(skb);
7351 break;
7352
7353 }
7354 }
7355}
7356
7357
7358
7359/****************************************************************************
7360 ---------------------------- USB_STUFF---------------------------
7361*****************************************************************************/
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07007362//LZM Merge from windows HalUsbSetQueuePipeMapping8192SUsb 090319
7363static void HalUsbSetQueuePipeMapping8192SUsb(struct usb_interface *intf, struct net_device *dev)
7364{
7365 struct r8192_priv *priv = ieee80211_priv(dev);
7366 struct usb_host_interface *iface_desc;
7367 struct usb_endpoint_descriptor *endpoint;
7368 u8 i = 0;
7369
7370 priv->ep_in_num = 0;
7371 priv->ep_out_num = 0;
7372 memset(priv->RtOutPipes,0,16);
7373 memset(priv->RtInPipes,0,16);
7374
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07007375 iface_desc = intf->cur_altsetting;
7376 priv->ep_num = iface_desc->desc.bNumEndpoints;
7377
7378 for (i = 0; i < priv->ep_num; ++i) {
7379 endpoint = &iface_desc->endpoint[i].desc;
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07007380 if (usb_endpoint_is_bulk_in(endpoint)) {
7381 priv->RtInPipes[priv->ep_in_num] = usb_endpoint_num(endpoint);
7382 priv->ep_in_num ++;
7383 //printk("in_endpoint_idx = %d\n", usb_endpoint_num(endpoint));
7384 } else if (usb_endpoint_is_bulk_out(endpoint)) {
7385 priv->RtOutPipes[priv->ep_out_num] = usb_endpoint_num(endpoint);
7386 priv->ep_out_num ++;
7387 //printk("out_endpoint_idx = %d\n", usb_endpoint_num(endpoint));
7388 }
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07007389 }
7390 {
7391 memset(priv->txqueue_to_outpipemap,0,9);
7392 if (priv->ep_num == 6) {
7393 // BK, BE, VI, VO, HCCA, TXCMD, MGNT, HIGH, BEACON
7394 u8 queuetopipe[] = {3, 2, 1, 0, 4, 4, 4, 4, 4};
7395
7396 memcpy(priv->txqueue_to_outpipemap,queuetopipe,9);
7397 } else if (priv->ep_num == 4) {
7398 // BK, BE, VI, VO, HCCA, TXCMD, MGNT, HIGH, BEACON
7399 u8 queuetopipe[] = {1, 1, 0, 0, 2, 2, 2, 2, 2};
7400
7401 memcpy(priv->txqueue_to_outpipemap,queuetopipe,9);
7402 } else if (priv->ep_num > 9) {
7403 // BK, BE, VI, VO, HCCA, TXCMD, MGNT, HIGH, BEACON
7404 u8 queuetopipe[] = {3, 2, 1, 0, 4, 8, 7, 6, 5};
7405
7406 memcpy(priv->txqueue_to_outpipemap,queuetopipe,9);
7407 } else {//use sigle pipe
7408 // BK, BE, VI, VO, HCCA, TXCMD, MGNT, HIGH, BEACON
7409 u8 queuetopipe[] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
7410 memcpy(priv->txqueue_to_outpipemap,queuetopipe,9);
7411 }
7412 }
7413 printk("==>ep_num:%d, in_ep_num:%d, out_ep_num:%d\n", priv->ep_num, priv->ep_in_num, priv->ep_out_num);
7414
7415 printk("==>RtInPipes:");
7416 for(i=0; i < priv->ep_in_num; i++)
7417 printk("%d ", priv->RtInPipes[i]);
7418 printk("\n");
7419
7420 printk("==>RtOutPipes:");
7421 for(i=0; i < priv->ep_out_num; i++)
7422 printk("%d ", priv->RtOutPipes[i]);
7423 printk("\n");
7424
7425 printk("==>txqueue_to_outpipemap for BK, BE, VI, VO, HCCA, TXCMD, MGNT, HIGH, BEACON:\n");
7426 for(i=0; i < 9; i++)
7427 printk("%d ", priv->txqueue_to_outpipemap[i]);
7428 printk("\n");
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07007429
7430 return;
7431}
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07007432
Bartlomiej Zolnierkiewicz77b92882009-06-11 20:49:07 +02007433static const struct net_device_ops rtl8192_netdev_ops = {
7434 .ndo_open = rtl8192_open,
7435 .ndo_stop = rtl8192_close,
7436 .ndo_get_stats = rtl8192_stats,
7437 .ndo_tx_timeout = tx_timeout,
7438 .ndo_do_ioctl = rtl8192_ioctl,
7439 .ndo_set_multicast_list = r8192_set_multicast,
7440 .ndo_set_mac_address = r8192_set_mac_adr,
7441 .ndo_validate_addr = eth_validate_addr,
7442 .ndo_change_mtu = eth_change_mtu,
Greg Kroah-Hartmance9c0102009-08-04 16:53:36 -07007443 .ndo_start_xmit = rtl8192_ieee80211_xmit,
Bartlomiej Zolnierkiewicz77b92882009-06-11 20:49:07 +02007444};
7445
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07007446static int __devinit rtl8192_usb_probe(struct usb_interface *intf,
7447 const struct usb_device_id *id)
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07007448{
7449// unsigned long ioaddr = 0;
7450 struct net_device *dev = NULL;
7451 struct r8192_priv *priv= NULL;
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07007452 struct usb_device *udev = interface_to_usbdev(intf);
Bartlomiej Zolnierkiewicz1ec9e482009-06-13 18:35:04 +02007453
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07007454 RT_TRACE(COMP_INIT, "Oops: i'm coming\n");
7455
7456 dev = alloc_ieee80211(sizeof(struct r8192_priv));
7457
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07007458 usb_set_intfdata(intf, dev);
7459 SET_NETDEV_DEV(dev, &intf->dev);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07007460 priv = ieee80211_priv(dev);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07007461 priv->ieee80211 = netdev_priv(dev);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07007462 priv->udev=udev;
7463
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07007464 HalUsbSetQueuePipeMapping8192SUsb(intf, dev);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07007465
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07007466 //printk("===============>NIC 8192SU\n");
7467 priv->ops = &rtl8192su_ops;
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07007468
Bartlomiej Zolnierkiewicz77b92882009-06-11 20:49:07 +02007469 dev->netdev_ops = &rtl8192_netdev_ops;
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07007470
7471 //DMESG("Oops: i'm coming\n");
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07007472 dev->wireless_handlers = (struct iw_handler_def *) &r8192_wx_handlers_def;
Bartlomiej Zolnierkiewicz3bd709f2009-06-13 18:35:58 +02007473
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07007474 dev->type=ARPHRD_ETHER;
7475
7476 dev->watchdog_timeo = HZ*3; //modified by john, 0805
7477
7478 if (dev_alloc_name(dev, ifname) < 0){
7479 RT_TRACE(COMP_INIT, "Oops: devname already taken! Trying wlan%%d...\n");
7480 ifname = "wlan%d";
7481 dev_alloc_name(dev, ifname);
7482 }
7483
7484 RT_TRACE(COMP_INIT, "Driver probe completed1\n");
7485#if 1
7486 if(rtl8192_init(dev)!=0){
7487 RT_TRACE(COMP_ERR, "Initialization failed");
7488 goto fail;
7489 }
7490#endif
7491 netif_carrier_off(dev);
7492 netif_stop_queue(dev);
7493
7494 register_netdev(dev);
7495 RT_TRACE(COMP_INIT, "dev name=======> %s\n",dev->name);
7496 rtl8192_proc_init_one(dev);
7497
7498
7499 RT_TRACE(COMP_INIT, "Driver probe completed\n");
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07007500 return 0;
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07007501fail:
7502 free_ieee80211(dev);
7503
7504 RT_TRACE(COMP_ERR, "wlan driver load failed\n");
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07007505 return -ENODEV;
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07007506}
7507
7508//detach all the work and timer structure declared or inititialize in r8192U_init function.
7509void rtl8192_cancel_deferred_work(struct r8192_priv* priv)
7510{
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07007511 cancel_work_sync(&priv->reset_wq);
7512 cancel_work_sync(&priv->qos_activate);
7513 cancel_delayed_work(&priv->watch_dog_wq);
7514 cancel_delayed_work(&priv->update_beacon_wq);
7515 cancel_delayed_work(&priv->ieee80211->hw_wakeup_wq);
7516 cancel_delayed_work(&priv->ieee80211->hw_sleep_wq);
7517 //cancel_work_sync(&priv->SetBWModeWorkItem);
7518 //cancel_work_sync(&priv->SwChnlWorkItem);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07007519}
7520
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07007521static void __devexit rtl8192_usb_disconnect(struct usb_interface *intf)
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07007522{
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07007523 struct net_device *dev = usb_get_intfdata(intf);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07007524 struct r8192_priv *priv = ieee80211_priv(dev);
7525 if(dev){
7526
7527 unregister_netdev(dev);
7528
7529 RT_TRACE(COMP_DOWN, "=============>wlan driver to be removed\n");
7530 rtl8192_proc_remove_one(dev);
7531
7532 rtl8192_down(dev);
7533 if (priv->pFirmware)
7534 {
7535 vfree(priv->pFirmware);
7536 priv->pFirmware = NULL;
7537 }
7538 // priv->rf_close(dev);
7539// rtl8192_SetRFPowerState(dev, eRfOff);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07007540 destroy_workqueue(priv->priv_wq);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07007541 //rtl8192_irq_disable(dev);
7542 //rtl8192_reset(dev);
7543 mdelay(10);
7544
7545 }
7546 free_ieee80211(dev);
7547 RT_TRACE(COMP_DOWN, "wlan driver removed\n");
7548}
7549
Bartlomiej Zolnierkiewicz5d9baea2009-07-13 20:13:49 +02007550/* fun with the built-in ieee80211 stack... */
7551extern int ieee80211_debug_init(void);
7552extern void ieee80211_debug_exit(void);
7553extern int ieee80211_crypto_init(void);
7554extern void ieee80211_crypto_deinit(void);
7555extern int ieee80211_crypto_tkip_init(void);
7556extern void ieee80211_crypto_tkip_exit(void);
7557extern int ieee80211_crypto_ccmp_init(void);
7558extern void ieee80211_crypto_ccmp_exit(void);
7559extern int ieee80211_crypto_wep_init(void);
7560extern void ieee80211_crypto_wep_exit(void);
7561
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07007562static int __init rtl8192_usb_module_init(void)
7563{
Bartlomiej Zolnierkiewicz5d9baea2009-07-13 20:13:49 +02007564 int ret;
7565
7566#ifdef CONFIG_IEEE80211_DEBUG
7567 ret = ieee80211_debug_init();
7568 if (ret) {
7569 printk(KERN_ERR "ieee80211_debug_init() failed %d\n", ret);
7570 return ret;
7571 }
7572#endif
7573 ret = ieee80211_crypto_init();
7574 if (ret) {
7575 printk(KERN_ERR "ieee80211_crypto_init() failed %d\n", ret);
7576 return ret;
7577 }
7578
7579 ret = ieee80211_crypto_tkip_init();
7580 if (ret) {
7581 printk(KERN_ERR "ieee80211_crypto_tkip_init() failed %d\n",
7582 ret);
7583 return ret;
7584 }
7585
7586 ret = ieee80211_crypto_ccmp_init();
7587 if (ret) {
7588 printk(KERN_ERR "ieee80211_crypto_ccmp_init() failed %d\n",
7589 ret);
7590 return ret;
7591 }
7592
7593 ret = ieee80211_crypto_wep_init();
7594 if (ret) {
7595 printk(KERN_ERR "ieee80211_crypto_wep_init() failed %d\n", ret);
7596 return ret;
7597 }
7598
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07007599 printk(KERN_INFO "\nLinux kernel driver for RTL8192 based WLAN cards\n");
7600 printk(KERN_INFO "Copyright (c) 2007-2008, Realsil Wlan\n");
7601 RT_TRACE(COMP_INIT, "Initializing module");
7602 RT_TRACE(COMP_INIT, "Wireless extensions version %d", WIRELESS_EXT);
7603 rtl8192_proc_module_init();
7604 return usb_register(&rtl8192_usb_driver);
7605}
7606
7607
7608static void __exit rtl8192_usb_module_exit(void)
7609{
7610 usb_deregister(&rtl8192_usb_driver);
7611
7612 RT_TRACE(COMP_DOWN, "Exiting");
7613 rtl8192_proc_module_remove();
Bartlomiej Zolnierkiewicz5d9baea2009-07-13 20:13:49 +02007614
7615 ieee80211_crypto_tkip_exit();
7616 ieee80211_crypto_ccmp_exit();
7617 ieee80211_crypto_wep_exit();
7618 ieee80211_crypto_deinit();
7619#ifdef CONFIG_IEEE80211_DEBUG
7620 ieee80211_debug_exit();
7621#endif
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07007622}
7623
7624
7625void rtl8192_try_wake_queue(struct net_device *dev, int pri)
7626{
7627 unsigned long flags;
7628 short enough_desc;
7629 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
7630
7631 spin_lock_irqsave(&priv->tx_lock,flags);
7632 enough_desc = check_nic_enough_desc(dev,pri);
7633 spin_unlock_irqrestore(&priv->tx_lock,flags);
7634
7635 if(enough_desc)
7636 ieee80211_wake_queue(priv->ieee80211);
7637}
7638
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07007639void EnableHWSecurityConfig8192(struct net_device *dev)
7640{
7641 u8 SECR_value = 0x0;
7642 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
7643 struct ieee80211_device* ieee = priv->ieee80211;
7644
7645 SECR_value = SCR_TxEncEnable | SCR_RxDecEnable;
7646#if 1
7647 if (((KEY_TYPE_WEP40 == ieee->pairwise_key_type) || (KEY_TYPE_WEP104 == ieee->pairwise_key_type)) && (priv->ieee80211->auth_mode != 2))
7648 {
7649 SECR_value |= SCR_RxUseDK;
7650 SECR_value |= SCR_TxUseDK;
7651 }
7652 else if ((ieee->iw_mode == IW_MODE_ADHOC) && (ieee->pairwise_key_type & (KEY_TYPE_CCMP | KEY_TYPE_TKIP)))
7653 {
7654 SECR_value |= SCR_RxUseDK;
7655 SECR_value |= SCR_TxUseDK;
7656 }
7657#endif
7658 //add HWSec active enable here.
7659//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
7660
7661 ieee->hwsec_active = 1;
7662
7663 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
7664 {
7665 ieee->hwsec_active = 0;
7666 SECR_value &= ~SCR_RxDecEnable;
7667 }
7668
7669 RT_TRACE(COMP_SEC,"%s:, hwsec:%d, pairwise_key:%d, SECR_value:%x\n", __FUNCTION__, \
7670 ieee->hwsec_active, ieee->pairwise_key_type, SECR_value);
7671 {
7672 write_nic_byte(dev, SECR, SECR_value);//SECR_value | SCR_UseDK );
7673 }
7674}
7675
7676
7677void setKey( struct net_device *dev,
7678 u8 EntryNo,
7679 u8 KeyIndex,
7680 u16 KeyType,
7681 u8 *MacAddr,
7682 u8 DefaultKey,
7683 u32 *KeyContent )
7684{
7685 u32 TargetCommand = 0;
7686 u32 TargetContent = 0;
7687 u16 usConfig = 0;
7688 u8 i;
7689 if (EntryNo >= TOTAL_CAM_ENTRY)
7690 RT_TRACE(COMP_ERR, "cam entry exceeds in setKey()\n");
7691
7692 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));
7693
7694 if (DefaultKey)
7695 usConfig |= BIT15 | (KeyType<<2);
7696 else
7697 usConfig |= BIT15 | (KeyType<<2) | KeyIndex;
7698// usConfig |= BIT15 | (KeyType<<2) | (DefaultKey<<5) | KeyIndex;
7699
7700
7701 for(i=0 ; i<CAM_CONTENT_COUNT; i++){
7702 TargetCommand = i+CAM_CONTENT_COUNT*EntryNo;
7703 TargetCommand |= BIT31|BIT16;
7704
7705 if(i==0){//MAC|Config
7706 TargetContent = (u32)(*(MacAddr+0)) << 16|
7707 (u32)(*(MacAddr+1)) << 24|
7708 (u32)usConfig;
7709
7710 write_nic_dword(dev, WCAMI, TargetContent);
7711 write_nic_dword(dev, RWCAM, TargetCommand);
7712 // printk("setkey cam =%8x\n", read_cam(dev, i+6*EntryNo));
7713 }
7714 else if(i==1){//MAC
7715 TargetContent = (u32)(*(MacAddr+2)) |
7716 (u32)(*(MacAddr+3)) << 8|
7717 (u32)(*(MacAddr+4)) << 16|
7718 (u32)(*(MacAddr+5)) << 24;
7719 write_nic_dword(dev, WCAMI, TargetContent);
7720 write_nic_dword(dev, RWCAM, TargetCommand);
7721 }
7722 else {
7723 //Key Material
7724 if(KeyContent !=NULL){
7725 write_nic_dword(dev, WCAMI, (u32)(*(KeyContent+i-2)) );
7726 write_nic_dword(dev, RWCAM, TargetCommand);
7727 }
7728 }
7729 }
7730
7731}
7732
7733/***************************************************************************
7734 ------------------- module init / exit stubs ----------------
7735****************************************************************************/
7736module_init(rtl8192_usb_module_init);
7737module_exit(rtl8192_usb_module_exit);