staging: rtl8192u Fix a typo.
[linux-2.6-block.git] / drivers / staging / rtl8192u / r8192U_core.c
CommitLineData
8fc8598e
JC
1/******************************************************************************
2 * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
3 * Linux device driver for RTL8192U
4 *
5 * Based on the r8187 driver, which is:
6 * Copyright 2004-2005 Andrea Merello <andreamrl@tiscali.it>, et al.
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of version 2 of the GNU General Public License as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along with
17 * this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 *
20 * The full GNU General Public License is included in this distribution in the
21 * file called LICENSE.
22 *
23 * Contact Information:
24 * Jerry chuang <wlanfae@realtek.com>
25 */
26
27#ifndef CONFIG_FORCE_HARD_FLOAT
28double __floatsidf (int i) { return i; }
29unsigned int __fixunsdfsi (double d) { return d; }
30double __adddf3(double a, double b) { return a+b; }
31double __addsf3(float a, float b) { return a+b; }
32double __subdf3(double a, double b) { return a-b; }
33double __extendsfdf2(float a) {return a;}
34#endif
35
36#undef LOOP_TEST
37#undef DUMP_RX
38#undef DUMP_TX
39#undef DEBUG_TX_DESC2
40#undef RX_DONT_PASS_UL
41#undef DEBUG_EPROM
42#undef DEBUG_RX_VERBOSE
43#undef DUMMY_RX
44#undef DEBUG_ZERO_RX
45#undef DEBUG_RX_SKB
46#undef DEBUG_TX_FRAG
47#undef DEBUG_RX_FRAG
48#undef DEBUG_TX_FILLDESC
49#undef DEBUG_TX
50#undef DEBUG_IRQ
51#undef DEBUG_RX
52#undef DEBUG_RXALLOC
53#undef DEBUG_REGISTERS
54#undef DEBUG_RING
55#undef DEBUG_IRQ_TASKLET
56#undef DEBUG_TX_ALLOC
57#undef DEBUG_TX_DESC
58
59#define CONFIG_RTL8192_IO_MAP
60
61#include <asm/uaccess.h>
62#include "r8192U_hw.h"
63#include "r8192U.h"
64#include "r8190_rtl8256.h" /* RTL8225 Radio frontend */
65#include "r8180_93cx6.h" /* Card EEPROM */
66#include "r8192U_wx.h"
67#include "r819xU_phy.h" //added by WB 4.30.2008
68#include "r819xU_phyreg.h"
69#include "r819xU_cmdpkt.h"
70#include "r8192U_dm.h"
71//#include "r8192xU_phyreg.h"
72#include <linux/usb.h>
5a0e3ad6 73#include <linux/slab.h>
8fc8598e 74// FIXME: check if 2.6.7 is ok
8fc8598e
JC
75
76#ifdef CONFIG_RTL8192_PM
77#include "r8192_pm.h"
78#endif
79
8fc8598e 80#include "dot11d.h"
8fc8598e
JC
81//set here to open your trace code. //WB
82u32 rt_global_debug_component = \
83 // COMP_INIT |
84// COMP_DBG |
85 // COMP_EPROM |
86// COMP_PHY |
87 // COMP_RF |
88// COMP_FIRMWARE |
89// COMP_CH |
90 // COMP_POWER_TRACKING |
91// COMP_RATE |
92 // COMP_TXAGC |
93 // COMP_TRACE |
94 COMP_DOWN |
95 // COMP_RECV |
e406322b 96 // COMP_SWBW |
8fc8598e
JC
97 COMP_SEC |
98 // COMP_RESET |
99 // COMP_SEND |
100 // COMP_EVENTS |
101 COMP_ERR ; //always open err flags on
102
103#define TOTAL_CAM_ENTRY 32
104#define CAM_CONTENT_COUNT 8
105
a457732b 106static const struct usb_device_id rtl8192_usb_id_tbl[] = {
8fc8598e 107 /* Realtek */
8fc8598e
JC
108 {USB_DEVICE(0x0bda, 0x8709)},
109 /* Corega */
110 {USB_DEVICE(0x07aa, 0x0043)},
111 /* Belkin */
112 {USB_DEVICE(0x050d, 0x805E)},
113 /* Sitecom */
114 {USB_DEVICE(0x0df6, 0x0031)},
115 /* EnGenius */
116 {USB_DEVICE(0x1740, 0x9201)},
117 /* Dlink */
118 {USB_DEVICE(0x2001, 0x3301)},
119 /* Zinwell */
120 {USB_DEVICE(0x5a57, 0x0290)},
e10ac155
BH
121 /* LG */
122 {USB_DEVICE(0x043e, 0x7a01)},
8fc8598e
JC
123 {}
124};
125
126MODULE_LICENSE("GPL");
8fc8598e 127MODULE_VERSION("V 1.1");
8fc8598e
JC
128MODULE_DEVICE_TABLE(usb, rtl8192_usb_id_tbl);
129MODULE_DESCRIPTION("Linux driver for Realtek RTL8192 USB WiFi cards");
130
131static char* ifname = "wlan%d";
8fc8598e
JC
132static int hwwep = 1; //default use hw. set 0 to use software security
133static int channels = 0x3fff;
134
135
136
8fc8598e
JC
137module_param(ifname, charp, S_IRUGO|S_IWUSR );
138//module_param(hwseqnum,int, S_IRUGO|S_IWUSR);
139module_param(hwwep,int, S_IRUGO|S_IWUSR);
140module_param(channels,int, S_IRUGO|S_IWUSR);
8fc8598e
JC
141
142MODULE_PARM_DESC(ifname," Net interface name, wlan%d=default");
143//MODULE_PARM_DESC(hwseqnum," Try to use hardware 802.11 header sequence numbers. Zero=default");
144MODULE_PARM_DESC(hwwep," Try to use hardware security support. ");
145MODULE_PARM_DESC(channels," Channel bitmask for specific locales. NYI");
146
8fc8598e
JC
147static int __devinit rtl8192_usb_probe(struct usb_interface *intf,
148 const struct usb_device_id *id);
149static void __devexit rtl8192_usb_disconnect(struct usb_interface *intf);
8fc8598e
JC
150
151
152static struct usb_driver rtl8192_usb_driver = {
e406322b
MCC
153 .name = RTL819xU_MODULE_NAME, /* Driver name */
154 .id_table = rtl8192_usb_id_tbl, /* PCI_ID table */
155 .probe = rtl8192_usb_probe, /* probe fn */
8fc8598e 156 .disconnect = rtl8192_usb_disconnect, /* remove fn */
8fc8598e 157#ifdef CONFIG_RTL8192_PM
e406322b 158 .suspend = rtl8192_suspend, /* PM suspend fn */
8fc8598e
JC
159 .resume = rtl8192_resume, /* PM resume fn */
160#else
e406322b
MCC
161 .suspend = NULL, /* PM suspend fn */
162 .resume = NULL, /* PM resume fn */
8fc8598e 163#endif
8fc8598e
JC
164};
165
8fc8598e
JC
166
167typedef struct _CHANNEL_LIST
168{
169 u8 Channel[32];
170 u8 Len;
171}CHANNEL_LIST, *PCHANNEL_LIST;
172
173static CHANNEL_LIST ChannelPlan[] = {
174 {{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
175 {{1,2,3,4,5,6,7,8,9,10,11},11}, //IC
176 {{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48,52,56,60,64},21}, //ETSI
177 {{1,2,3,4,5,6,7,8,9,10,11,12,13},13}, //Spain. Change to ETSI.
178 {{1,2,3,4,5,6,7,8,9,10,11,12,13},13}, //France. Change to ETSI.
179 {{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
180 {{1,2,3,4,5,6,7,8,9,10,11,12,13,14,36,40,44,48,52,56,60,64},22},//MKK1
181 {{1,2,3,4,5,6,7,8,9,10,11,12,13},13}, //Israel.
182 {{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
183 {{1,2,3,4,5,6,7,8,9,10,11,12,13,14,36,40,44,48,52,56,60,64}, 22}, //MIC
184 {{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
185};
186
187static void rtl819x_set_channel_map(u8 channel_plan, struct r8192_priv* priv)
188{
189 int i, max_chan=-1, min_chan=-1;
190 struct ieee80211_device* ieee = priv->ieee80211;
191 switch (channel_plan)
192 {
193 case COUNTRY_CODE_FCC:
194 case COUNTRY_CODE_IC:
195 case COUNTRY_CODE_ETSI:
196 case COUNTRY_CODE_SPAIN:
197 case COUNTRY_CODE_FRANCE:
198 case COUNTRY_CODE_MKK:
199 case COUNTRY_CODE_MKK1:
200 case COUNTRY_CODE_ISRAEL:
201 case COUNTRY_CODE_TELEC:
202 case COUNTRY_CODE_MIC:
203 {
204 Dot11d_Init(ieee);
205 ieee->bGlobalDomain = false;
589b3d06 206 //actually 8225 & 8256 rf chip only support B,G,24N mode
8fc8598e
JC
207 if ((priv->rf_chip == RF_8225) || (priv->rf_chip == RF_8256))
208 {
209 min_chan = 1;
210 max_chan = 14;
211 }
212 else
213 {
214 RT_TRACE(COMP_ERR, "unknown rf chip, can't set channel map in function:%s()\n", __FUNCTION__);
215 }
216 if (ChannelPlan[channel_plan].Len != 0){
217 // Clear old channel map
218 memset(GET_DOT11D_INFO(ieee)->channel_map, 0, sizeof(GET_DOT11D_INFO(ieee)->channel_map));
219 // Set new channel map
220 for (i=0;i<ChannelPlan[channel_plan].Len;i++)
221 {
222 if (ChannelPlan[channel_plan].Channel[i] < min_chan || ChannelPlan[channel_plan].Channel[i] > max_chan)
223 break;
224 GET_DOT11D_INFO(ieee)->channel_map[ChannelPlan[channel_plan].Channel[i]] = 1;
225 }
226 }
227 break;
228 }
229 case COUNTRY_CODE_GLOBAL_DOMAIN:
230 {
231 GET_DOT11D_INFO(ieee)->bEnabled = 0;//this flag enabled to follow 11d country IE setting, otherwise, it shall follow global domain settings.
232 Dot11d_Reset(ieee);
233 ieee->bGlobalDomain = true;
234 break;
235 }
236 default:
237 break;
238 }
239 return;
240}
8fc8598e 241
8fc8598e
JC
242
243#define rx_hal_is_cck_rate(_pdrvinfo)\
244 (_pdrvinfo->RxRate == DESC90_RATE1M ||\
245 _pdrvinfo->RxRate == DESC90_RATE2M ||\
246 _pdrvinfo->RxRate == DESC90_RATE5_5M ||\
247 _pdrvinfo->RxRate == DESC90_RATE11M) &&\
248 !_pdrvinfo->RxHT\
249
250
251void CamResetAllEntry(struct net_device *dev)
252{
8fc8598e 253 u32 ulcommand = 0;
e406322b
MCC
254 //2004/02/11 In static WEP, OID_ADD_KEY or OID_ADD_WEP are set before STA associate to AP.
255 // However, ResetKey is called on OID_802_11_INFRASTRUCTURE_MODE and MlmeAssociateRequest
256 // In this condition, Cam can not be reset because upper layer will not set this static key again.
257 //if(Adapter->EncAlgorithm == WEP_Encryption)
258 // return;
8fc8598e 259//debug
e406322b
MCC
260 //DbgPrint("========================================\n");
261 //DbgPrint(" Call ResetAllEntry \n");
262 //DbgPrint("========================================\n\n");
8fc8598e
JC
263 ulcommand |= BIT31|BIT30;
264 write_nic_dword(dev, RWCAM, ulcommand);
8fc8598e
JC
265
266}
267
268
269void write_cam(struct net_device *dev, u8 addr, u32 data)
270{
e406322b
MCC
271 write_nic_dword(dev, WCAMI, data);
272 write_nic_dword(dev, RWCAM, BIT31|BIT16|(addr&0xff) );
8fc8598e
JC
273}
274
275u32 read_cam(struct net_device *dev, u8 addr)
276{
e406322b
MCC
277 write_nic_dword(dev, RWCAM, 0x80000000|(addr&0xff) );
278 return read_nic_dword(dev, 0xa8);
8fc8598e
JC
279}
280
281void write_nic_byte_E(struct net_device *dev, int indx, u8 data)
282{
283 int status;
284 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
285 struct usb_device *udev = priv->udev;
286
287 status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
288 RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
289 indx|0xfe00, 0, &data, 1, HZ / 2);
290
291 if (status < 0)
292 {
293 printk("write_nic_byte_E TimeOut! status:%d\n", status);
294 }
295}
296
297u8 read_nic_byte_E(struct net_device *dev, int indx)
298{
299 int status;
300 u8 data;
301 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
302 struct usb_device *udev = priv->udev;
303
304 status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
305 RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
306 indx|0xfe00, 0, &data, 1, HZ / 2);
307
e406322b
MCC
308 if (status < 0)
309 {
310 printk("read_nic_byte_E TimeOut! status:%d\n", status);
311 }
8fc8598e
JC
312
313 return data;
314}
315//as 92U has extend page from 4 to 16, so modify functions below.
316void write_nic_byte(struct net_device *dev, int indx, u8 data)
317{
318 int status;
319
320 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
321 struct usb_device *udev = priv->udev;
322
323 status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
324 RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
325 (indx&0xff)|0xff00, (indx>>8)&0x0f, &data, 1, HZ / 2);
326
e406322b
MCC
327 if (status < 0)
328 {
329 printk("write_nic_byte TimeOut! status:%d\n", status);
330 }
8fc8598e
JC
331
332
333}
334
335
336void write_nic_word(struct net_device *dev, int indx, u16 data)
337{
338
339 int status;
340
341 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
342 struct usb_device *udev = priv->udev;
343
344 status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
345 RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
346 (indx&0xff)|0xff00, (indx>>8)&0x0f, &data, 2, HZ / 2);
347
e406322b
MCC
348 if (status < 0)
349 {
350 printk("write_nic_word TimeOut! status:%d\n", status);
351 }
8fc8598e
JC
352
353}
354
355
356void write_nic_dword(struct net_device *dev, int indx, u32 data)
357{
358
359 int status;
360
361 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
362 struct usb_device *udev = priv->udev;
363
364 status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
365 RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
366 (indx&0xff)|0xff00, (indx>>8)&0x0f, &data, 4, HZ / 2);
367
368
e406322b
MCC
369 if (status < 0)
370 {
371 printk("write_nic_dword TimeOut! status:%d\n", status);
372 }
8fc8598e
JC
373
374}
375
376
377
378u8 read_nic_byte(struct net_device *dev, int indx)
379{
380 u8 data;
381 int status;
382 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
383 struct usb_device *udev = priv->udev;
384
385 status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
386 RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
387 (indx&0xff)|0xff00, (indx>>8)&0x0f, &data, 1, HZ / 2);
388
e406322b
MCC
389 if (status < 0)
390 {
391 printk("read_nic_byte TimeOut! status:%d\n", status);
392 }
8fc8598e
JC
393
394 return data;
395}
396
397
398
399u16 read_nic_word(struct net_device *dev, int indx)
400{
401 u16 data;
402 int status;
403 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
404 struct usb_device *udev = priv->udev;
405
406 status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
616f58f6
MG
407 RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
408 (indx&0xff)|0xff00, (indx>>8)&0x0f,
409 &data, 2, HZ / 2);
8fc8598e 410
e406322b 411 if (status < 0)
e406322b 412 printk("read_nic_word TimeOut! status:%d\n", status);
8fc8598e
JC
413
414 return data;
415}
416
417u16 read_nic_word_E(struct net_device *dev, int indx)
418{
419 u16 data;
420 int status;
421 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
422 struct usb_device *udev = priv->udev;
423
424 status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
425 RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
616f58f6 426 indx|0xfe00, 0, &data, 2, HZ / 2);
8fc8598e 427
e406322b 428 if (status < 0)
e406322b 429 printk("read_nic_word TimeOut! status:%d\n", status);
8fc8598e
JC
430
431 return data;
432}
433
434u32 read_nic_dword(struct net_device *dev, int indx)
435{
436 u32 data;
437 int status;
616f58f6 438 /* int result; */
8fc8598e
JC
439
440 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
441 struct usb_device *udev = priv->udev;
442
443 status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
616f58f6
MG
444 RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
445 (indx&0xff)|0xff00, (indx>>8)&0x0f,
446 &data, 4, HZ / 2);
447 /* if(0 != result) {
448 * printk(KERN_WARNING "read size of data = %d\, date = %d\n",
449 * result, data);
450 * }
451 */
8fc8598e 452
e406322b 453 if (status < 0)
e406322b 454 printk("read_nic_dword TimeOut! status:%d\n", status);
8fc8598e
JC
455
456 return data;
457}
458
616f58f6
MG
459/* u8 read_phy_cck(struct net_device *dev, u8 adr); */
460/* u8 read_phy_ofdm(struct net_device *dev, u8 adr); */
8fc8598e 461/* this might still called in what was the PHY rtl8185/rtl8192 common code
25985edc 462 * plans are to possibility turn it again in one common code...
8fc8598e
JC
463 */
464inline void force_pci_posting(struct net_device *dev)
465{
466}
467
8fc8598e
JC
468static struct net_device_stats *rtl8192_stats(struct net_device *dev);
469void rtl8192_commit(struct net_device *dev);
616f58f6 470/* void rtl8192_restart(struct net_device *dev); */
8fc8598e 471void rtl8192_restart(struct work_struct *work);
616f58f6 472/* void rtl8192_rq_tx_ack(struct work_struct *work); */
8fc8598e
JC
473void watch_dog_timer_callback(unsigned long data);
474
475/****************************************************************************
616f58f6
MG
476 * -----------------------------PROCFS STUFF-------------------------
477*****************************************************************************
478 */
8fc8598e 479
616f58f6 480static struct proc_dir_entry *rtl8192_proc;
8fc8598e 481
616f58f6
MG
482static int proc_get_stats_ap(char *page, char **start, off_t offset, int count,
483 int *eof, void *data)
8fc8598e
JC
484{
485 struct net_device *dev = data;
486 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
487 struct ieee80211_device *ieee = priv->ieee80211;
488 struct ieee80211_network *target;
489
490 int len = 0;
491
e406322b 492 list_for_each_entry(target, &ieee->network_list, list) {
8fc8598e 493
616f58f6 494 len += snprintf(page + len, count - len, "%s ", target->ssid);
8fc8598e 495
616f58f6
MG
496 if (target->wpa_ie_len > 0 || target->rsn_ie_len > 0)
497 len += snprintf(page + len, count - len, "WPA\n");
498 else
499 len += snprintf(page + len, count - len, "non_WPA\n");
e406322b 500 }
8fc8598e
JC
501
502 *eof = 1;
503 return len;
504}
505
506static int proc_get_registers(char *page, char **start,
507 off_t offset, int count,
508 int *eof, void *data)
509{
510 struct net_device *dev = data;
511// struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
512
513 int len = 0;
514 int i,n;
515
516 int max=0xff;
517
518 /* This dump the current register page */
519len += snprintf(page + len, count - len,
e406322b 520 "\n####################page 0##################\n ");
8fc8598e
JC
521
522 for(n=0;n<=max;)
523 {
524 //printk( "\nD: %2x> ", n);
525 len += snprintf(page + len, count - len,
526 "\nD: %2x > ",n);
527
528 for(i=0;i<16 && n<=max;i++,n++)
529 len += snprintf(page + len, count - len,
530 "%2x ",read_nic_byte(dev,0x000|n));
531
532 // printk("%2x ",read_nic_byte(dev,n));
533 }
8fc8598e 534len += snprintf(page + len, count - len,
e406322b
MCC
535 "\n####################page 1##################\n ");
536 for(n=0;n<=max;)
537 {
538 //printk( "\nD: %2x> ", n);
539 len += snprintf(page + len, count - len,
540 "\nD: %2x > ",n);
8fc8598e 541
e406322b
MCC
542 for(i=0;i<16 && n<=max;i++,n++)
543 len += snprintf(page + len, count - len,
544 "%2x ",read_nic_byte(dev,0x100|n));
8fc8598e 545
e406322b
MCC
546 // printk("%2x ",read_nic_byte(dev,n));
547 }
8fc8598e 548len += snprintf(page + len, count - len,
e406322b
MCC
549 "\n####################page 3##################\n ");
550 for(n=0;n<=max;)
551 {
552 //printk( "\nD: %2x> ", n);
553 len += snprintf(page + len, count - len,
554 "\nD: %2x > ",n);
8fc8598e 555
e406322b
MCC
556 for(i=0;i<16 && n<=max;i++,n++)
557 len += snprintf(page + len, count - len,
558 "%2x ",read_nic_byte(dev,0x300|n));
8fc8598e 559
e406322b
MCC
560 // printk("%2x ",read_nic_byte(dev,n));
561 }
8fc8598e 562
8fc8598e
JC
563
564 len += snprintf(page + len, count - len,"\n");
565 *eof = 1;
566 return len;
567
568}
569
570
8fc8598e 571
8fc8598e 572
8fc8598e
JC
573
574static int proc_get_stats_tx(char *page, char **start,
575 off_t offset, int count,
576 int *eof, void *data)
577{
578 struct net_device *dev = data;
579 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
580
581 int len = 0;
582
583 len += snprintf(page + len, count - len,
584 "TX VI priority ok int: %lu\n"
585 "TX VI priority error int: %lu\n"
586 "TX VO priority ok int: %lu\n"
587 "TX VO priority error int: %lu\n"
588 "TX BE priority ok int: %lu\n"
589 "TX BE priority error int: %lu\n"
590 "TX BK priority ok int: %lu\n"
591 "TX BK priority error int: %lu\n"
592 "TX MANAGE priority ok int: %lu\n"
593 "TX MANAGE priority error int: %lu\n"
594 "TX BEACON priority ok int: %lu\n"
595 "TX BEACON priority error int: %lu\n"
596// "TX high priority ok int: %lu\n"
597// "TX high priority failed error int: %lu\n"
598 "TX queue resume: %lu\n"
599 "TX queue stopped?: %d\n"
600 "TX fifo overflow: %lu\n"
601// "TX beacon: %lu\n"
602 "TX VI queue: %d\n"
603 "TX VO queue: %d\n"
604 "TX BE queue: %d\n"
605 "TX BK queue: %d\n"
606// "TX HW queue: %d\n"
607 "TX VI dropped: %lu\n"
608 "TX VO dropped: %lu\n"
609 "TX BE dropped: %lu\n"
610 "TX BK dropped: %lu\n"
611 "TX total data packets %lu\n",
612// "TX beacon aborted: %lu\n",
613 priv->stats.txviokint,
614 priv->stats.txvierr,
615 priv->stats.txvookint,
616 priv->stats.txvoerr,
617 priv->stats.txbeokint,
618 priv->stats.txbeerr,
619 priv->stats.txbkokint,
620 priv->stats.txbkerr,
621 priv->stats.txmanageokint,
622 priv->stats.txmanageerr,
623 priv->stats.txbeaconokint,
624 priv->stats.txbeaconerr,
625// priv->stats.txhpokint,
626// priv->stats.txhperr,
627 priv->stats.txresumed,
628 netif_queue_stopped(dev),
629 priv->stats.txoverflow,
630// priv->stats.txbeacon,
631 atomic_read(&(priv->tx_pending[VI_PRIORITY])),
632 atomic_read(&(priv->tx_pending[VO_PRIORITY])),
633 atomic_read(&(priv->tx_pending[BE_PRIORITY])),
634 atomic_read(&(priv->tx_pending[BK_PRIORITY])),
635// read_nic_byte(dev, TXFIFOCOUNT),
636 priv->stats.txvidrop,
637 priv->stats.txvodrop,
638 priv->stats.txbedrop,
639 priv->stats.txbkdrop,
640 priv->stats.txdatapkt
641// priv->stats.txbeaconerr
642 );
643
644 *eof = 1;
645 return len;
646}
647
648
649
650static int proc_get_stats_rx(char *page, char **start,
651 off_t offset, int count,
652 int *eof, void *data)
653{
654 struct net_device *dev = data;
655 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
656
657 int len = 0;
658
659 len += snprintf(page + len, count - len,
660 "RX packets: %lu\n"
661 "RX urb status error: %lu\n"
662 "RX invalid urb error: %lu\n",
663 priv->stats.rxoktotal,
664 priv->stats.rxstaterr,
665 priv->stats.rxurberr);
666
667 *eof = 1;
668 return len;
669}
8fc8598e
JC
670void rtl8192_proc_module_init(void)
671{
672 RT_TRACE(COMP_INIT, "Initializing proc filesystem");
e55d92b9 673 rtl8192_proc = proc_mkdir(RTL819xU_MODULE_NAME, init_net.proc_net);
8fc8598e
JC
674}
675
676
677void rtl8192_proc_module_remove(void)
678{
8fc8598e 679 remove_proc_entry(RTL819xU_MODULE_NAME, init_net.proc_net);
8fc8598e
JC
680}
681
682
683void rtl8192_proc_remove_one(struct net_device *dev)
684{
685 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
686
687
688 if (priv->dir_dev) {
689 // remove_proc_entry("stats-hw", priv->dir_dev);
690 remove_proc_entry("stats-tx", priv->dir_dev);
691 remove_proc_entry("stats-rx", priv->dir_dev);
692 // remove_proc_entry("stats-ieee", priv->dir_dev);
693 remove_proc_entry("stats-ap", priv->dir_dev);
694 remove_proc_entry("registers", priv->dir_dev);
695 // remove_proc_entry("cck-registers",priv->dir_dev);
696 // remove_proc_entry("ofdm-registers",priv->dir_dev);
697 //remove_proc_entry(dev->name, rtl8192_proc);
698 remove_proc_entry("wlan0", rtl8192_proc);
699 priv->dir_dev = NULL;
700 }
701}
702
703
704void rtl8192_proc_init_one(struct net_device *dev)
705{
706 struct proc_dir_entry *e;
707 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
e55d92b9 708 priv->dir_dev = proc_mkdir(dev->name, rtl8192_proc);
8fc8598e
JC
709 if (!priv->dir_dev) {
710 RT_TRACE(COMP_ERR, "Unable to initialize /proc/net/rtl8192/%s\n",
711 dev->name);
712 return;
713 }
8fc8598e
JC
714 e = create_proc_read_entry("stats-rx", S_IFREG | S_IRUGO,
715 priv->dir_dev, proc_get_stats_rx, dev);
716
717 if (!e) {
718 RT_TRACE(COMP_ERR,"Unable to initialize "
719 "/proc/net/rtl8192/%s/stats-rx\n",
720 dev->name);
721 }
722
723
724 e = create_proc_read_entry("stats-tx", S_IFREG | S_IRUGO,
725 priv->dir_dev, proc_get_stats_tx, dev);
726
727 if (!e) {
728 RT_TRACE(COMP_ERR, "Unable to initialize "
729 "/proc/net/rtl8192/%s/stats-tx\n",
730 dev->name);
731 }
8fc8598e
JC
732
733 e = create_proc_read_entry("stats-ap", S_IFREG | S_IRUGO,
734 priv->dir_dev, proc_get_stats_ap, dev);
735
736 if (!e) {
737 RT_TRACE(COMP_ERR, "Unable to initialize "
738 "/proc/net/rtl8192/%s/stats-ap\n",
739 dev->name);
740 }
741
742 e = create_proc_read_entry("registers", S_IFREG | S_IRUGO,
743 priv->dir_dev, proc_get_registers, dev);
744 if (!e) {
745 RT_TRACE(COMP_ERR, "Unable to initialize "
746 "/proc/net/rtl8192/%s/registers\n",
747 dev->name);
748 }
8fc8598e
JC
749}
750/****************************************************************************
751 -----------------------------MISC STUFF-------------------------
752*****************************************************************************/
753
754/* this is only for debugging */
755void print_buffer(u32 *buffer, int len)
756{
757 int i;
758 u8 *buf =(u8*)buffer;
759
760 printk("ASCII BUFFER DUMP (len: %x):\n",len);
761
762 for(i=0;i<len;i++)
763 printk("%c",buf[i]);
764
765 printk("\nBINARY BUFFER DUMP (len: %x):\n",len);
766
767 for(i=0;i<len;i++)
768 printk("%x",buf[i]);
769
770 printk("\n");
771}
772
773//short check_nic_enough_desc(struct net_device *dev, priority_t priority)
774short check_nic_enough_desc(struct net_device *dev,int queue_index)
775{
776 struct r8192_priv *priv = ieee80211_priv(dev);
777 int used = atomic_read(&priv->tx_pending[queue_index]);
778
779 return (used < MAX_TX_URB);
780}
781
782void tx_timeout(struct net_device *dev)
783{
784 struct r8192_priv *priv = ieee80211_priv(dev);
785 //rtl8192_commit(dev);
786
8fc8598e 787 schedule_work(&priv->reset_wq);
8fc8598e
JC
788 //DMESG("TXTIMEOUT");
789}
790
791
792/* this is only for debug */
793void dump_eprom(struct net_device *dev)
794{
795 int i;
796 for(i=0; i<63; i++)
797 RT_TRACE(COMP_EPROM, "EEPROM addr %x : %x", i, eprom_read(dev,i));
798}
799
800/* this is only for debug */
801void rtl8192_dump_reg(struct net_device *dev)
802{
803 int i;
804 int n;
805 int max=0x1ff;
806
807 RT_TRACE(COMP_PHY, "Dumping NIC register map");
808
809 for(n=0;n<=max;)
810 {
811 printk( "\nD: %2x> ", n);
812 for(i=0;i<16 && n<=max;i++,n++)
813 printk("%2x ",read_nic_byte(dev,n));
814 }
815 printk("\n");
816}
817
818/****************************************************************************
819 ------------------------------HW STUFF---------------------------
820*****************************************************************************/
821
8fc8598e
JC
822
823void rtl8192_set_mode(struct net_device *dev,int mode)
824{
825 u8 ecmd;
826 ecmd=read_nic_byte(dev, EPROM_CMD);
827 ecmd=ecmd &~ EPROM_CMD_OPERATING_MODE_MASK;
828 ecmd=ecmd | (mode<<EPROM_CMD_OPERATING_MODE_SHIFT);
829 ecmd=ecmd &~ (1<<EPROM_CS_SHIFT);
830 ecmd=ecmd &~ (1<<EPROM_CK_SHIFT);
831 write_nic_byte(dev, EPROM_CMD, ecmd);
832}
833
834
835void rtl8192_update_msr(struct net_device *dev)
836{
837 struct r8192_priv *priv = ieee80211_priv(dev);
838 u8 msr;
839
840 msr = read_nic_byte(dev, MSR);
841 msr &= ~ MSR_LINK_MASK;
842
843 /* do not change in link_state != WLAN_LINK_ASSOCIATED.
844 * msr must be updated if the state is ASSOCIATING.
845 * this is intentional and make sense for ad-hoc and
846 * master (see the create BSS/IBSS func)
847 */
848 if (priv->ieee80211->state == IEEE80211_LINKED){
849
850 if (priv->ieee80211->iw_mode == IW_MODE_INFRA)
851 msr |= (MSR_LINK_MANAGED<<MSR_LINK_SHIFT);
852 else if (priv->ieee80211->iw_mode == IW_MODE_ADHOC)
853 msr |= (MSR_LINK_ADHOC<<MSR_LINK_SHIFT);
854 else if (priv->ieee80211->iw_mode == IW_MODE_MASTER)
855 msr |= (MSR_LINK_MASTER<<MSR_LINK_SHIFT);
856
857 }else
858 msr |= (MSR_LINK_NONE<<MSR_LINK_SHIFT);
859
860 write_nic_byte(dev, MSR, msr);
861}
862
863void rtl8192_set_chan(struct net_device *dev,short ch)
864{
865 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
866// u32 tx;
867 RT_TRACE(COMP_CH, "=====>%s()====ch:%d\n", __FUNCTION__, ch);
868 priv->chan=ch;
8fc8598e
JC
869
870 /* this hack should avoid frame TX during channel setting*/
871
872
873// tx = read_nic_dword(dev,TX_CONF);
874// tx &= ~TX_LOOPBACK_MASK;
875
876#ifndef LOOP_TEST
877// write_nic_dword(dev,TX_CONF, tx |( TX_LOOPBACK_MAC<<TX_LOOPBACK_SHIFT));
878
879 //need to implement rf set channel here WB
880
881 if (priv->rf_set_chan)
882 priv->rf_set_chan(dev,priv->chan);
883 mdelay(10);
884// write_nic_dword(dev,TX_CONF,tx | (TX_LOOPBACK_NONE<<TX_LOOPBACK_SHIFT));
885#endif
886}
887
8fc8598e 888static void rtl8192_rx_isr(struct urb *urb);
8fc8598e
JC
889//static void rtl8192_rx_isr(struct urb *rx_urb);
890
891u32 get_rxpacket_shiftbytes_819xusb(struct ieee80211_rx_stats *pstats)
892{
893
894#ifdef USB_RX_AGGREGATION_SUPPORT
895 if (pstats->bisrxaggrsubframe)
896 return (sizeof(rx_desc_819x_usb) + pstats->RxDrvInfoSize
897 + pstats->RxBufShift + 8);
898 else
899#endif
900 return (sizeof(rx_desc_819x_usb) + pstats->RxDrvInfoSize
901 + pstats->RxBufShift);
902
903}
904static int rtl8192_rx_initiate(struct net_device*dev)
905{
e406322b
MCC
906 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
907 struct urb *entry;
908 struct sk_buff *skb;
909 struct rtl8192_rx_info *info;
8fc8598e
JC
910
911 /* nomal packet rx procedure */
e406322b
MCC
912 while (skb_queue_len(&priv->rx_queue) < MAX_RX_URB) {
913 skb = __dev_alloc_skb(RX_URB_SIZE, GFP_KERNEL);
914 if (!skb)
915 break;
e406322b 916 entry = usb_alloc_urb(0, GFP_KERNEL);
e406322b
MCC
917 if (!entry) {
918 kfree_skb(skb);
919 break;
920 }
8fc8598e 921// printk("nomal packet IN request!\n");
e406322b
MCC
922 usb_fill_bulk_urb(entry, priv->udev,
923 usb_rcvbulkpipe(priv->udev, 3), skb_tail_pointer(skb),
924 RX_URB_SIZE, rtl8192_rx_isr, skb);
925 info = (struct rtl8192_rx_info *) skb->cb;
926 info->urb = entry;
927 info->dev = dev;
8fc8598e 928 info->out_pipe = 3; //denote rx normal packet queue
e406322b
MCC
929 skb_queue_tail(&priv->rx_queue, skb);
930 usb_submit_urb(entry, GFP_KERNEL);
931 }
8fc8598e
JC
932
933 /* command packet rx procedure */
e406322b 934 while (skb_queue_len(&priv->rx_queue) < MAX_RX_URB + 3) {
8fc8598e 935// printk("command packet IN request!\n");
e406322b
MCC
936 skb = __dev_alloc_skb(RX_URB_SIZE ,GFP_KERNEL);
937 if (!skb)
938 break;
e406322b 939 entry = usb_alloc_urb(0, GFP_KERNEL);
e406322b
MCC
940 if (!entry) {
941 kfree_skb(skb);
942 break;
943 }
944 usb_fill_bulk_urb(entry, priv->udev,
945 usb_rcvbulkpipe(priv->udev, 9), skb_tail_pointer(skb),
946 RX_URB_SIZE, rtl8192_rx_isr, skb);
947 info = (struct rtl8192_rx_info *) skb->cb;
948 info->urb = entry;
949 info->dev = dev;
8fc8598e 950 info->out_pipe = 9; //denote rx cmd packet queue
e406322b 951 skb_queue_tail(&priv->rx_queue, skb);
8fc8598e 952 usb_submit_urb(entry, GFP_KERNEL);
e406322b 953 }
8fc8598e 954
e406322b 955 return 0;
8fc8598e
JC
956}
957
958void rtl8192_set_rxconf(struct net_device *dev)
959{
960 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
961 u32 rxconf;
962
963 rxconf=read_nic_dword(dev,RCR);
964 rxconf = rxconf &~ MAC_FILTER_MASK;
965 rxconf = rxconf | RCR_AMF;
966 rxconf = rxconf | RCR_ADF;
967 rxconf = rxconf | RCR_AB;
968 rxconf = rxconf | RCR_AM;
969 //rxconf = rxconf | RCR_ACF;
970
971 if (dev->flags & IFF_PROMISC) {DMESG ("NIC in promisc mode");}
972
973 if(priv->ieee80211->iw_mode == IW_MODE_MONITOR || \
974 dev->flags & IFF_PROMISC){
975 rxconf = rxconf | RCR_AAP;
976 } /*else if(priv->ieee80211->iw_mode == IW_MODE_MASTER){
977 rxconf = rxconf | (1<<ACCEPT_ALLMAC_FRAME_SHIFT);
978 rxconf = rxconf | (1<<RX_CHECK_BSSID_SHIFT);
979 }*/else{
980 rxconf = rxconf | RCR_APM;
981 rxconf = rxconf | RCR_CBSSID;
982 }
983
984
985 if(priv->ieee80211->iw_mode == IW_MODE_MONITOR){
986 rxconf = rxconf | RCR_AICV;
987 rxconf = rxconf | RCR_APWRMGT;
988 }
989
990 if( priv->crcmon == 1 && priv->ieee80211->iw_mode == IW_MODE_MONITOR)
991 rxconf = rxconf | RCR_ACRC32;
992
993
994 rxconf = rxconf &~ RX_FIFO_THRESHOLD_MASK;
995 rxconf = rxconf | (RX_FIFO_THRESHOLD_NONE<<RX_FIFO_THRESHOLD_SHIFT);
996 rxconf = rxconf &~ MAX_RX_DMA_MASK;
997 rxconf = rxconf | ((u32)7<<RCR_MXDMA_OFFSET);
998
999// rxconf = rxconf | (1<<RX_AUTORESETPHY_SHIFT);
1000 rxconf = rxconf | RCR_ONLYERLPKT;
1001
1002// rxconf = rxconf &~ RCR_CS_MASK;
1003// rxconf = rxconf | (1<<RCR_CS_SHIFT);
1004
1005 write_nic_dword(dev, RCR, rxconf);
1006
1007 #ifdef DEBUG_RX
1008 DMESG("rxconf: %x %x",rxconf ,read_nic_dword(dev,RCR));
1009 #endif
1010}
1011//wait to be removed
1012void rtl8192_rx_enable(struct net_device *dev)
1013{
1014 //u8 cmd;
1015
1016 //struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1017
1018 rtl8192_rx_initiate(dev);
1019
1020// rtl8192_set_rxconf(dev);
8fc8598e
JC
1021}
1022
1023
1024void rtl8192_tx_enable(struct net_device *dev)
1025{
8fc8598e
JC
1026}
1027
1028
8fc8598e
JC
1029
1030void rtl8192_rtx_disable(struct net_device *dev)
1031{
1032 u8 cmd;
1033 struct r8192_priv *priv = ieee80211_priv(dev);
1034 struct sk_buff *skb;
1035 struct rtl8192_rx_info *info;
1036
1037 cmd=read_nic_byte(dev,CMDR);
1038 write_nic_byte(dev, CMDR, cmd &~ \
1039 (CR_TE|CR_RE));
1040 force_pci_posting(dev);
1041 mdelay(10);
1042
1043 while ((skb = __skb_dequeue(&priv->rx_queue))) {
1044 info = (struct rtl8192_rx_info *) skb->cb;
1045 if (!info->urb)
1046 continue;
1047
1048 usb_kill_urb(info->urb);
1049 kfree_skb(skb);
1050 }
1051
1052 if (skb_queue_len(&priv->skb_queue)) {
1053 printk(KERN_WARNING "skb_queue not empty\n");
1054 }
1055
1056 skb_queue_purge(&priv->skb_queue);
1057 return;
1058}
1059
1060
1061int alloc_tx_beacon_desc_ring(struct net_device *dev, int count)
1062{
8fc8598e
JC
1063 return 0;
1064}
1065
8fc8598e
JC
1066inline u16 ieeerate2rtlrate(int rate)
1067{
1068 switch(rate){
1069 case 10:
1070 return 0;
1071 case 20:
1072 return 1;
1073 case 55:
1074 return 2;
1075 case 110:
1076 return 3;
1077 case 60:
1078 return 4;
1079 case 90:
1080 return 5;
1081 case 120:
1082 return 6;
1083 case 180:
1084 return 7;
1085 case 240:
1086 return 8;
1087 case 360:
1088 return 9;
1089 case 480:
1090 return 10;
1091 case 540:
1092 return 11;
1093 default:
1094 return 3;
1095
1096 }
1097}
1098static u16 rtl_rate[] = {10,20,55,110,60,90,120,180,240,360,480,540};
1099inline u16 rtl8192_rate2rate(short rate)
1100{
1101 if (rate >11) return 0;
1102 return rtl_rate[rate];
1103}
1104
1105
589b3d06 1106/* The prototype of rx_isr has changed since one version of Linux Kernel */
8fc8598e 1107static void rtl8192_rx_isr(struct urb *urb)
8fc8598e 1108{
e406322b
MCC
1109 struct sk_buff *skb = (struct sk_buff *) urb->context;
1110 struct rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
1111 struct net_device *dev = info->dev;
8fc8598e
JC
1112 struct r8192_priv *priv = ieee80211_priv(dev);
1113 int out_pipe = info->out_pipe;
1114 int err;
1115 if(!priv->up)
1116 return;
e406322b
MCC
1117 if (unlikely(urb->status)) {
1118 info->urb = NULL;
1119 priv->stats.rxstaterr++;
1120 priv->ieee80211->stats.rx_errors++;
1121 usb_free_urb(urb);
8fc8598e 1122 // printk("%s():rx status err\n",__FUNCTION__);
e406322b
MCC
1123 return;
1124 }
e406322b 1125 skb_unlink(skb, &priv->rx_queue);
e406322b 1126 skb_put(skb, urb->actual_length);
8fc8598e
JC
1127
1128 skb_queue_tail(&priv->skb_queue, skb);
1129 tasklet_schedule(&priv->irq_rx_tasklet);
1130
e406322b
MCC
1131 skb = dev_alloc_skb(RX_URB_SIZE);
1132 if (unlikely(!skb)) {
1133 usb_free_urb(urb);
8fc8598e 1134 printk("%s():can,t alloc skb\n",__FUNCTION__);
e406322b
MCC
1135 /* TODO check rx queue length and refill *somewhere* */
1136 return;
1137 }
8fc8598e
JC
1138
1139 usb_fill_bulk_urb(urb, priv->udev,
f61fb935 1140 usb_rcvbulkpipe(priv->udev, out_pipe), skb_tail_pointer(skb),
8fc8598e
JC
1141 RX_URB_SIZE, rtl8192_rx_isr, skb);
1142
e406322b
MCC
1143 info = (struct rtl8192_rx_info *) skb->cb;
1144 info->urb = urb;
1145 info->dev = dev;
8fc8598e
JC
1146 info->out_pipe = out_pipe;
1147
e406322b
MCC
1148 urb->transfer_buffer = skb_tail_pointer(skb);
1149 urb->context = skb;
1150 skb_queue_tail(&priv->rx_queue, skb);
1151 err = usb_submit_urb(urb, GFP_ATOMIC);
8fc8598e
JC
1152 if(err && err != EPERM)
1153 printk("can not submit rxurb, err is %x,URB status is %x\n",err,urb->status);
1154}
1155
1156u32
1157rtl819xusb_rx_command_packet(
1158 struct net_device *dev,
1159 struct ieee80211_rx_stats *pstats
1160 )
1161{
1162 u32 status;
1163
1164 //RT_TRACE(COMP_RECV, DBG_TRACE, ("---> RxCommandPacketHandle819xUsb()\n"));
1165
1166 status = cmpk_message_handle_rx(dev, pstats);
1167 if (status)
1168 {
1169 DMESG("rxcommandpackethandle819xusb: It is a command packet\n");
1170 }
1171 else
1172 {
1173 //RT_TRACE(COMP_RECV, DBG_TRACE, ("RxCommandPacketHandle819xUsb: It is not a command packet\n"));
1174 }
1175
1176 //RT_TRACE(COMP_RECV, DBG_TRACE, ("<--- RxCommandPacketHandle819xUsb()\n"));
1177 return status;
1178}
1179
8fc8598e
JC
1180
1181void rtl8192_data_hard_stop(struct net_device *dev)
1182{
1183 //FIXME !!
8fc8598e
JC
1184}
1185
1186
1187void rtl8192_data_hard_resume(struct net_device *dev)
1188{
1189 // FIXME !!
8fc8598e
JC
1190}
1191
1192/* this function TX data frames when the ieee80211 stack requires this.
1193 * It checks also if we need to stop the ieee tx queue, eventually do it
1194 */
1195void rtl8192_hard_data_xmit(struct sk_buff *skb, struct net_device *dev, int rate)
1196{
1197 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1198 int ret;
1199 unsigned long flags;
1200 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1201 u8 queue_index = tcb_desc->queue_index;
1202
1203 /* shall not be referred by command packet */
1204 assert(queue_index != TXCMD_QUEUE);
1205
1206 spin_lock_irqsave(&priv->tx_lock,flags);
1207
e406322b 1208 memcpy((unsigned char *)(skb->cb),&dev,sizeof(dev));
8fc8598e
JC
1209// tcb_desc->RATRIndex = 7;
1210// tcb_desc->bTxDisableRateFallBack = 1;
1211// tcb_desc->bTxUseDriverAssingedRate = 1;
1212 tcb_desc->bTxEnableFwCalcDur = 1;
1213 skb_push(skb, priv->ieee80211->tx_headroom);
1214 ret = rtl8192_tx(dev, skb);
1215
1216 //priv->ieee80211->stats.tx_bytes+=(skb->len - priv->ieee80211->tx_headroom);
1217 //priv->ieee80211->stats.tx_packets++;
1218
1219 spin_unlock_irqrestore(&priv->tx_lock,flags);
1220
1221// return ret;
1222 return;
1223}
1224
1225/* This is a rough attempt to TX a frame
1226 * This is called by the ieee 80211 stack to TX management frames.
1227 * If the ring is full packet are dropped (for data frame the queue
1228 * is stopped before this can happen).
1229 */
1230int rtl8192_hard_start_xmit(struct sk_buff *skb,struct net_device *dev)
1231{
1232 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1233 int ret;
1234 unsigned long flags;
e406322b
MCC
1235 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1236 u8 queue_index = tcb_desc->queue_index;
8fc8598e
JC
1237
1238
1239 spin_lock_irqsave(&priv->tx_lock,flags);
1240
e406322b 1241 memcpy((unsigned char *)(skb->cb),&dev,sizeof(dev));
8fc8598e
JC
1242 if(queue_index == TXCMD_QUEUE) {
1243 skb_push(skb, USB_HWDESC_HEADER_LEN);
1244 rtl819xU_tx_cmd(dev, skb);
1245 ret = 1;
e406322b 1246 spin_unlock_irqrestore(&priv->tx_lock,flags);
8fc8598e
JC
1247 return ret;
1248 } else {
1249 skb_push(skb, priv->ieee80211->tx_headroom);
1250 ret = rtl8192_tx(dev, skb);
1251 }
1252
1253 spin_unlock_irqrestore(&priv->tx_lock,flags);
1254
1255 return ret;
1256}
1257
1258
1259void rtl8192_try_wake_queue(struct net_device *dev, int pri);
1260
1261#ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
1262u16 DrvAggr_PaddingAdd(struct net_device *dev, struct sk_buff *skb)
1263{
1264 u16 PaddingNum = 256 - ((skb->len + TX_PACKET_DRVAGGR_SUBFRAME_SHIFT_BYTES) % 256);
1265 return (PaddingNum&0xff);
1266}
1267
1268u8 MRateToHwRate8190Pci(u8 rate);
1269u8 QueryIsShort(u8 TxHT, u8 TxRate, cb_desc *tcb_desc);
1270u8 MapHwQueueToFirmwareQueue(u8 QueueID);
1271struct sk_buff *DrvAggr_Aggregation(struct net_device *dev, struct ieee80211_drv_agg_txb *pSendList)
1272{
8fc8598e 1273 struct ieee80211_device *ieee = netdev_priv(dev);
8fc8598e
JC
1274 struct r8192_priv *priv = ieee80211_priv(dev);
1275 cb_desc *tcb_desc = NULL;
1276 u8 i;
1277 u32 TotalLength;
1278 struct sk_buff *skb;
1279 struct sk_buff *agg_skb;
1280 tx_desc_819x_usb_aggr_subframe *tx_agg_desc = NULL;
1281 tx_fwinfo_819x_usb *tx_fwinfo = NULL;
1282
1283 //
1284 // Local variable initialization.
1285 //
1286 /* first skb initialization */
1287 skb = pSendList->tx_agg_frames[0];
1288 TotalLength = skb->len;
1289
1290 /* Get the total aggregation length including the padding space and
1291 * sub frame header.
1292 */
1293 for(i = 1; i < pSendList->nr_drv_agg_frames; i++) {
1294 TotalLength += DrvAggr_PaddingAdd(dev, skb);
1295 skb = pSendList->tx_agg_frames[i];
1296 TotalLength += (skb->len + TX_PACKET_DRVAGGR_SUBFRAME_SHIFT_BYTES);
1297 }
1298
1299 /* allocate skb to contain the aggregated packets */
1300 agg_skb = dev_alloc_skb(TotalLength + ieee->tx_headroom);
1301 memset(agg_skb->data, 0, agg_skb->len);
1302 skb_reserve(agg_skb, ieee->tx_headroom);
1303
1304// RT_DEBUG_DATA(COMP_SEND, skb->cb, sizeof(skb->cb));
1305 /* reserve info for first subframe Tx descriptor to be set in the tx function */
1306 skb = pSendList->tx_agg_frames[0];
1307 tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1308 tcb_desc->drv_agg_enable = 1;
1309 tcb_desc->pkt_size = skb->len;
e406322b 1310 tcb_desc->DrvAggrNum = pSendList->nr_drv_agg_frames;
8fc8598e
JC
1311 printk("DrvAggNum = %d\n", tcb_desc->DrvAggrNum);
1312// RT_DEBUG_DATA(COMP_SEND, skb->cb, sizeof(skb->cb));
1313// printk("========>skb->data ======> \n");
1314// RT_DEBUG_DATA(COMP_SEND, skb->data, skb->len);
1315 memcpy(agg_skb->cb, skb->cb, sizeof(skb->cb));
1316 memcpy(skb_put(agg_skb,skb->len),skb->data,skb->len);
1317
1318 for(i = 1; i < pSendList->nr_drv_agg_frames; i++) {
1319 /* push the next sub frame to be 256 byte aline */
1320 skb_put(agg_skb,DrvAggr_PaddingAdd(dev,skb));
1321
1322 /* Subframe drv Tx descriptor and firmware info setting */
1323 skb = pSendList->tx_agg_frames[i];
1324 tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1325 tx_agg_desc = (tx_desc_819x_usb_aggr_subframe *)agg_skb->tail;
1326 tx_fwinfo = (tx_fwinfo_819x_usb *)(agg_skb->tail + sizeof(tx_desc_819x_usb_aggr_subframe));
1327
1328 memset(tx_fwinfo,0,sizeof(tx_fwinfo_819x_usb));
1329 /* DWORD 0 */
1330 tx_fwinfo->TxHT = (tcb_desc->data_rate&0x80)?1:0;
1331 tx_fwinfo->TxRate = MRateToHwRate8190Pci(tcb_desc->data_rate);
1332 tx_fwinfo->EnableCPUDur = tcb_desc->bTxEnableFwCalcDur;
1333 tx_fwinfo->Short = QueryIsShort(tx_fwinfo->TxHT, tx_fwinfo->TxRate, tcb_desc);
1334 if(tcb_desc->bAMPDUEnable) {//AMPDU enabled
1335 tx_fwinfo->AllowAggregation = 1;
1336 /* DWORD 1 */
1337 tx_fwinfo->RxMF = tcb_desc->ampdu_factor;
1338 tx_fwinfo->RxAMD = tcb_desc->ampdu_density&0x07;//ampdudensity
1339 } else {
1340 tx_fwinfo->AllowAggregation = 0;
1341 /* DWORD 1 */
1342 tx_fwinfo->RxMF = 0;
1343 tx_fwinfo->RxAMD = 0;
1344 }
1345
1346 /* Protection mode related */
1347 tx_fwinfo->RtsEnable = (tcb_desc->bRTSEnable)?1:0;
1348 tx_fwinfo->CtsEnable = (tcb_desc->bCTSEnable)?1:0;
1349 tx_fwinfo->RtsSTBC = (tcb_desc->bRTSSTBC)?1:0;
1350 tx_fwinfo->RtsHT = (tcb_desc->rts_rate&0x80)?1:0;
1351 tx_fwinfo->RtsRate = MRateToHwRate8190Pci((u8)tcb_desc->rts_rate);
1352 tx_fwinfo->RtsSubcarrier = (tx_fwinfo->RtsHT==0)?(tcb_desc->RTSSC):0;
1353 tx_fwinfo->RtsBandwidth = (tx_fwinfo->RtsHT==1)?((tcb_desc->bRTSBW)?1:0):0;
1354 tx_fwinfo->RtsShort = (tx_fwinfo->RtsHT==0)?(tcb_desc->bRTSUseShortPreamble?1:0):\
1355 (tcb_desc->bRTSUseShortGI?1:0);
1356
1357 /* Set Bandwidth and sub-channel settings. */
1358 if(priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20_40)
1359 {
1360 if(tcb_desc->bPacketBW) {
1361 tx_fwinfo->TxBandwidth = 1;
1362 tx_fwinfo->TxSubCarrier = 0; //By SD3's Jerry suggestion, use duplicated mode
1363 } else {
1364 tx_fwinfo->TxBandwidth = 0;
1365 tx_fwinfo->TxSubCarrier = priv->nCur40MhzPrimeSC;
1366 }
1367 } else {
1368 tx_fwinfo->TxBandwidth = 0;
1369 tx_fwinfo->TxSubCarrier = 0;
1370 }
1371
1372 /* Fill Tx descriptor */
1373 memset(tx_agg_desc, 0, sizeof(tx_desc_819x_usb_aggr_subframe));
1374 /* DWORD 0 */
1375 //tx_agg_desc->LINIP = 0;
1376 //tx_agg_desc->CmdInit = 1;
1377 tx_agg_desc->Offset = sizeof(tx_fwinfo_819x_usb) + 8;
25985edc 1378 /* already raw data, need not to subtract header length */
8fc8598e
JC
1379 tx_agg_desc->PktSize = skb->len & 0xffff;
1380
1381 /*DWORD 1*/
1382 tx_agg_desc->SecCAMID= 0;
1383 tx_agg_desc->RATid = tcb_desc->RATRIndex;
8fc8598e
JC
1384 {
1385 //MPDUOverhead = 0;
1386 tx_agg_desc->NoEnc = 1;
1387 }
8fc8598e 1388 tx_agg_desc->SecType = 0x0;
8fc8598e
JC
1389
1390 if (tcb_desc->bHwSec) {
1391 switch (priv->ieee80211->pairwise_key_type)
1392 {
1393 case KEY_TYPE_WEP40:
1394 case KEY_TYPE_WEP104:
1395 tx_agg_desc->SecType = 0x1;
1396 tx_agg_desc->NoEnc = 0;
1397 break;
1398 case KEY_TYPE_TKIP:
1399 tx_agg_desc->SecType = 0x2;
1400 tx_agg_desc->NoEnc = 0;
1401 break;
1402 case KEY_TYPE_CCMP:
1403 tx_agg_desc->SecType = 0x3;
1404 tx_agg_desc->NoEnc = 0;
1405 break;
1406 case KEY_TYPE_NA:
1407 tx_agg_desc->SecType = 0x0;
1408 tx_agg_desc->NoEnc = 1;
1409 break;
1410 }
1411 }
1412
1413 tx_agg_desc->QueueSelect = MapHwQueueToFirmwareQueue(tcb_desc->queue_index);
1414 tx_agg_desc->TxFWInfoSize = sizeof(tx_fwinfo_819x_usb);
1415
1416 tx_agg_desc->DISFB = tcb_desc->bTxDisableRateFallBack;
1417 tx_agg_desc->USERATE = tcb_desc->bTxUseDriverAssingedRate;
1418
1419 tx_agg_desc->OWN = 1;
1420
1421 //DWORD 2
1422 /* According windows driver, it seems that there no need to fill this field */
1423 //tx_agg_desc->TxBufferSize= (u32)(skb->len - USB_HWDESC_HEADER_LEN);
1424
1425 /* to fill next packet */
1426 skb_put(agg_skb,TX_PACKET_DRVAGGR_SUBFRAME_SHIFT_BYTES);
1427 memcpy(skb_put(agg_skb,skb->len),skb->data,skb->len);
1428 }
1429
1430 for(i = 0; i < pSendList->nr_drv_agg_frames; i++) {
1431 dev_kfree_skb_any(pSendList->tx_agg_frames[i]);
1432 }
1433
1434 return agg_skb;
1435}
1436
1437/* NOTE:
1438 This function return a list of PTCB which is proper to be aggregate with the input TCB.
1439 If no proper TCB is found to do aggregation, SendList will only contain the input TCB.
1440*/
1441u8 DrvAggr_GetAggregatibleList(struct net_device *dev, struct sk_buff *skb,
1442 struct ieee80211_drv_agg_txb *pSendList)
1443{
8fc8598e 1444 struct ieee80211_device *ieee = netdev_priv(dev);
8fc8598e
JC
1445 PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
1446 u16 nMaxAggrNum = pHTInfo->UsbTxAggrNum;
1447 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1448 u8 QueueID = tcb_desc->queue_index;
1449
1450 do {
1451 pSendList->tx_agg_frames[pSendList->nr_drv_agg_frames++] = skb;
1452 if(pSendList->nr_drv_agg_frames >= nMaxAggrNum) {
1453 break;
1454 }
1455
1456 } while((skb = skb_dequeue(&ieee->skb_drv_aggQ[QueueID])));
1457
1458 RT_TRACE(COMP_AMSDU, "DrvAggr_GetAggregatibleList, nAggrTcbNum = %d \n", pSendList->nr_drv_agg_frames);
1459 return pSendList->nr_drv_agg_frames;
1460}
1461#endif
1462
8fc8598e 1463static void rtl8192_tx_isr(struct urb *tx_urb)
8fc8598e
JC
1464{
1465 struct sk_buff *skb = (struct sk_buff*)tx_urb->context;
1466 struct net_device *dev = NULL;
1467 struct r8192_priv *priv = NULL;
1468 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1469 u8 queue_index = tcb_desc->queue_index;
1470// bool bToSend0Byte;
1471// u16 BufLen = skb->len;
1472
1473 memcpy(&dev,(struct net_device*)(skb->cb),sizeof(struct net_device*));
1474 priv = ieee80211_priv(dev);
1475
1476 if(tcb_desc->queue_index != TXCMD_QUEUE) {
1477 if(tx_urb->status == 0) {
1478 dev->trans_start = jiffies;
589b3d06 1479 // As act as station mode, destination shall be unicast address.
8fc8598e
JC
1480 //priv->ieee80211->stats.tx_bytes+=(skb->len - priv->ieee80211->tx_headroom);
1481 //priv->ieee80211->stats.tx_packets++;
1482 priv->stats.txoktotal++;
1483 priv->ieee80211->LinkDetectInfo.NumTxOkInPeriod++;
1484 priv->stats.txbytesunicast += (skb->len - priv->ieee80211->tx_headroom);
1485 } else {
1486 priv->ieee80211->stats.tx_errors++;
1487 //priv->stats.txmanageerr++;
1488 /* TODO */
1489 }
1490 }
1491
1492 /* free skb and tx_urb */
1493 if(skb != NULL) {
1494 dev_kfree_skb_any(skb);
1495 usb_free_urb(tx_urb);
1496 atomic_dec(&priv->tx_pending[queue_index]);
1497 }
1498
8fc8598e
JC
1499 {
1500 //
1501 // Handle HW Beacon:
af02b584 1502 // We had transfer our beacon frame to host controller at this moment.
8fc8598e 1503 //
8fc8598e
JC
1504 //
1505 // Caution:
1506 // Handling the wait queue of command packets.
1507 // For Tx command packets, we must not do TCB fragment because it is not handled right now.
1508 // We must cut the packets to match the size of TX_CMD_PKT before we send it.
1509 //
1510
1511 /* Handle MPDU in wait queue. */
1512 if(queue_index != BEACON_QUEUE) {
1513 /* Don't send data frame during scanning.*/
1514 if((skb_queue_len(&priv->ieee80211->skb_waitQ[queue_index]) != 0)&&\
1515 (!(priv->ieee80211->queue_stop))) {
1516 if(NULL != (skb = skb_dequeue(&(priv->ieee80211->skb_waitQ[queue_index]))))
1517 priv->ieee80211->softmac_hard_start_xmit(skb, dev);
1518
1519 return; //modified by david to avoid further processing AMSDU
1520 }
1521#ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
1522 else if ((skb_queue_len(&priv->ieee80211->skb_drv_aggQ[queue_index])!= 0)&&\
e406322b 1523 (!(priv->ieee80211->queue_stop))) {
8fc8598e 1524 // Tx Driver Aggregation process
589b3d06 1525 /* The driver will aggregation the packets according to the following stats
8fc8598e
JC
1526 * 1. check whether there's tx irq available, for it's a completion return
1527 * function, it should contain enough tx irq;
589b3d06 1528 * 2. check packet type;
9b0131cb 1529 * 3. initialize sendlist, check whether the to-be send packet no greater than 1
589b3d06
JM
1530 * 4. aggregates the packets, and fill firmware info and tx desc to it, etc.
1531 * 5. check whether the packet could be sent, otherwise just insert to wait head
8fc8598e
JC
1532 * */
1533 skb = skb_dequeue(&priv->ieee80211->skb_drv_aggQ[queue_index]);
1534 if(!check_nic_enough_desc(dev, queue_index)) {
1535 skb_queue_head(&(priv->ieee80211->skb_drv_aggQ[queue_index]), skb);
1536 return;
1537 }
1538
1539 {
1540 /*TODO*/
1541 /*
1542 u8* pHeader = skb->data;
1543
1544 if(IsMgntQosData(pHeader) ||
e406322b 1545 IsMgntQData_Ack(pHeader) ||
8fc8598e
JC
1546 IsMgntQData_Poll(pHeader) ||
1547 IsMgntQData_Poll_Ack(pHeader)
1548 )
1549 */
1550 {
1551 struct ieee80211_drv_agg_txb SendList;
1552
1553 memset(&SendList, 0, sizeof(struct ieee80211_drv_agg_txb));
1554 if(DrvAggr_GetAggregatibleList(dev, skb, &SendList) > 1) {
1555 skb = DrvAggr_Aggregation(dev, &SendList);
1556
8fc8598e
JC
1557 }
1558 }
1559 priv->ieee80211->softmac_hard_start_xmit(skb, dev);
1560 }
1561 }
1562#endif
1563 }
1564 }
1565
8fc8598e
JC
1566}
1567
1568void rtl8192_beacon_stop(struct net_device *dev)
1569{
1570 u8 msr, msrm, msr2;
1571 struct r8192_priv *priv = ieee80211_priv(dev);
1572
1573 msr = read_nic_byte(dev, MSR);
1574 msrm = msr & MSR_LINK_MASK;
1575 msr2 = msr & ~MSR_LINK_MASK;
1576
1577 if(NIC_8192U == priv->card_8192) {
1578 usb_kill_urb(priv->rx_urb[MAX_RX_URB]);
1579 }
1580 if ((msrm == (MSR_LINK_ADHOC<<MSR_LINK_SHIFT) ||
1581 (msrm == (MSR_LINK_MASTER<<MSR_LINK_SHIFT)))){
1582 write_nic_byte(dev, MSR, msr2 | MSR_LINK_NONE);
1583 write_nic_byte(dev, MSR, msr);
1584 }
1585}
1586
1587void rtl8192_config_rate(struct net_device* dev, u16* rate_config)
1588{
1589 struct r8192_priv *priv = ieee80211_priv(dev);
1590 struct ieee80211_network *net;
1591 u8 i=0, basic_rate = 0;
1592 net = & priv->ieee80211->current_network;
1593
1594 for (i=0; i<net->rates_len; i++)
1595 {
1596 basic_rate = net->rates[i]&0x7f;
1597 switch(basic_rate)
1598 {
1599 case MGN_1M: *rate_config |= RRSR_1M; break;
1600 case MGN_2M: *rate_config |= RRSR_2M; break;
1601 case MGN_5_5M: *rate_config |= RRSR_5_5M; break;
1602 case MGN_11M: *rate_config |= RRSR_11M; break;
1603 case MGN_6M: *rate_config |= RRSR_6M; break;
1604 case MGN_9M: *rate_config |= RRSR_9M; break;
1605 case MGN_12M: *rate_config |= RRSR_12M; break;
1606 case MGN_18M: *rate_config |= RRSR_18M; break;
1607 case MGN_24M: *rate_config |= RRSR_24M; break;
1608 case MGN_36M: *rate_config |= RRSR_36M; break;
1609 case MGN_48M: *rate_config |= RRSR_48M; break;
1610 case MGN_54M: *rate_config |= RRSR_54M; break;
1611 }
1612 }
1613 for (i=0; i<net->rates_ex_len; i++)
1614 {
1615 basic_rate = net->rates_ex[i]&0x7f;
1616 switch(basic_rate)
1617 {
1618 case MGN_1M: *rate_config |= RRSR_1M; break;
1619 case MGN_2M: *rate_config |= RRSR_2M; break;
1620 case MGN_5_5M: *rate_config |= RRSR_5_5M; break;
1621 case MGN_11M: *rate_config |= RRSR_11M; break;
1622 case MGN_6M: *rate_config |= RRSR_6M; break;
1623 case MGN_9M: *rate_config |= RRSR_9M; break;
1624 case MGN_12M: *rate_config |= RRSR_12M; break;
1625 case MGN_18M: *rate_config |= RRSR_18M; break;
1626 case MGN_24M: *rate_config |= RRSR_24M; break;
1627 case MGN_36M: *rate_config |= RRSR_36M; break;
1628 case MGN_48M: *rate_config |= RRSR_48M; break;
1629 case MGN_54M: *rate_config |= RRSR_54M; break;
1630 }
1631 }
1632}
1633
1634
1635#define SHORT_SLOT_TIME 9
1636#define NON_SHORT_SLOT_TIME 20
1637
1638void rtl8192_update_cap(struct net_device* dev, u16 cap)
1639{
1640 u32 tmp = 0;
1641 struct r8192_priv *priv = ieee80211_priv(dev);
1642 struct ieee80211_network *net = &priv->ieee80211->current_network;
1643 priv->short_preamble = cap & WLAN_CAPABILITY_SHORT_PREAMBLE;
1644 tmp = priv->basic_rate;
1645 if (priv->short_preamble)
1646 tmp |= BRSR_AckShortPmb;
1647 write_nic_dword(dev, RRSR, tmp);
1648
1649 if (net->mode & (IEEE_G|IEEE_N_24G))
1650 {
1651 u8 slot_time = 0;
1652 if ((cap & WLAN_CAPABILITY_SHORT_SLOT)&&(!priv->ieee80211->pHTInfo->bCurrentRT2RTLongSlotTime))
1653 {//short slot time
1654 slot_time = SHORT_SLOT_TIME;
1655 }
1656 else //long slot time
1657 slot_time = NON_SHORT_SLOT_TIME;
1658 priv->slot_time = slot_time;
1659 write_nic_byte(dev, SLOT_TIME, slot_time);
1660 }
1661
1662}
1663void rtl8192_net_update(struct net_device *dev)
1664{
1665
1666 struct r8192_priv *priv = ieee80211_priv(dev);
1667 struct ieee80211_network *net;
1668 u16 BcnTimeCfg = 0, BcnCW = 6, BcnIFS = 0xf;
1669 u16 rate_config = 0;
1670 net = & priv->ieee80211->current_network;
1671
1672 rtl8192_config_rate(dev, &rate_config);
1673 priv->basic_rate = rate_config &= 0x15f;
1674
1675 write_nic_dword(dev,BSSIDR,((u32*)net->bssid)[0]);
1676 write_nic_word(dev,BSSIDR+4,((u16*)net->bssid)[2]);
1677 //for(i=0;i<ETH_ALEN;i++)
1678 // write_nic_byte(dev,BSSID+i,net->bssid[i]);
1679
1680 rtl8192_update_msr(dev);
1681// rtl8192_update_cap(dev, net->capability);
1682 if (priv->ieee80211->iw_mode == IW_MODE_ADHOC)
1683 {
1684 write_nic_word(dev, ATIMWND, 2);
1685 write_nic_word(dev, BCN_DMATIME, 1023);
1686 write_nic_word(dev, BCN_INTERVAL, net->beacon_interval);
1687// write_nic_word(dev, BcnIntTime, 100);
1688 write_nic_word(dev, BCN_DRV_EARLY_INT, 1);
1689 write_nic_byte(dev, BCN_ERR_THRESH, 100);
1690 BcnTimeCfg |= (BcnCW<<BCN_TCFG_CW_SHIFT);
1691 // TODO: BcnIFS may required to be changed on ASIC
e406322b 1692 BcnTimeCfg |= BcnIFS<<BCN_TCFG_IFS;
8fc8598e
JC
1693
1694 write_nic_word(dev, BCN_TCFG, BcnTimeCfg);
1695 }
1696
1697
1698
1699}
1700
1701//temporary hw beacon is not used any more.
1702//open it when necessary
8fc8598e
JC
1703void rtl819xusb_beacon_tx(struct net_device *dev,u16 tx_rate)
1704{
1705
8fc8598e 1706}
8fc8598e
JC
1707inline u8 rtl8192_IsWirelessBMode(u16 rate)
1708{
1709 if( ((rate <= 110) && (rate != 60) && (rate != 90)) || (rate == 220) )
1710 return 1;
1711 else return 0;
1712}
1713
1714u16 N_DBPSOfRate(u16 DataRate);
1715
1716u16 ComputeTxTime(
1717 u16 FrameLength,
1718 u16 DataRate,
1719 u8 bManagementFrame,
1720 u8 bShortPreamble
1721)
1722{
1723 u16 FrameTime;
1724 u16 N_DBPS;
1725 u16 Ceiling;
1726
1727 if( rtl8192_IsWirelessBMode(DataRate) )
1728 {
1729 if( bManagementFrame || !bShortPreamble || DataRate == 10 )
1730 { // long preamble
1731 FrameTime = (u16)(144+48+(FrameLength*8/(DataRate/10)));
1732 }
1733 else
1734 { // Short preamble
1735 FrameTime = (u16)(72+24+(FrameLength*8/(DataRate/10)));
1736 }
1737 if( ( FrameLength*8 % (DataRate/10) ) != 0 ) //Get the Ceilling
1738 FrameTime ++;
1739 } else { //802.11g DSSS-OFDM PLCP length field calculation.
1740 N_DBPS = N_DBPSOfRate(DataRate);
1741 Ceiling = (16 + 8*FrameLength + 6) / N_DBPS
1742 + (((16 + 8*FrameLength + 6) % N_DBPS) ? 1 : 0);
1743 FrameTime = (u16)(16 + 4 + 4*Ceiling + 6);
1744 }
1745 return FrameTime;
1746}
1747
1748u16 N_DBPSOfRate(u16 DataRate)
1749{
1750 u16 N_DBPS = 24;
1751
1752 switch(DataRate)
1753 {
1754 case 60:
1755 N_DBPS = 24;
1756 break;
1757
1758 case 90:
1759 N_DBPS = 36;
1760 break;
1761
1762 case 120:
1763 N_DBPS = 48;
1764 break;
1765
1766 case 180:
1767 N_DBPS = 72;
1768 break;
1769
1770 case 240:
1771 N_DBPS = 96;
1772 break;
1773
1774 case 360:
1775 N_DBPS = 144;
1776 break;
1777
1778 case 480:
1779 N_DBPS = 192;
1780 break;
1781
1782 case 540:
1783 N_DBPS = 216;
1784 break;
1785
1786 default:
1787 break;
1788 }
1789
1790 return N_DBPS;
1791}
1792
1793void rtl819xU_cmd_isr(struct urb *tx_cmd_urb, struct pt_regs *regs)
1794{
8fc8598e
JC
1795 usb_free_urb(tx_cmd_urb);
1796}
1797
1798unsigned int txqueue2outpipe(struct r8192_priv* priv,unsigned int tx_queue) {
1799
1800 if(tx_queue >= 9)
1801 {
1802 RT_TRACE(COMP_ERR,"%s():Unknown queue ID!!!\n",__FUNCTION__);
1803 return 0x04;
1804 }
1805 return priv->txqueue_to_outpipemap[tx_queue];
1806}
1807
1808short rtl819xU_tx_cmd(struct net_device *dev, struct sk_buff *skb)
1809{
1810 struct r8192_priv *priv = ieee80211_priv(dev);
1811 //u8 *tx;
1812 int status;
1813 struct urb *tx_urb;
1814 //int urb_buf_len;
1815 unsigned int idx_pipe;
1816 tx_desc_cmd_819x_usb *pdesc = (tx_desc_cmd_819x_usb *)skb->data;
1817 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1818 u8 queue_index = tcb_desc->queue_index;
1819
1820 //printk("\n %s::queue_index = %d\n",__FUNCTION__, queue_index);
1821 atomic_inc(&priv->tx_pending[queue_index]);
8fc8598e 1822 tx_urb = usb_alloc_urb(0,GFP_ATOMIC);
8fc8598e
JC
1823 if(!tx_urb){
1824 dev_kfree_skb(skb);
1825 return -ENOMEM;
1826 }
1827
1828 memset(pdesc, 0, USB_HWDESC_HEADER_LEN);
1829 /* Tx descriptor ought to be set according to the skb->cb */
1830 pdesc->FirstSeg = 1;//bFirstSeg;
1831 pdesc->LastSeg = 1;//bLastSeg;
1832 pdesc->CmdInit = tcb_desc->bCmdOrInit;
1833 pdesc->TxBufferSize = tcb_desc->txbuf_size;
1834 pdesc->OWN = 1;
1835 pdesc->LINIP = tcb_desc->bLastIniPkt;
1836
1837 //----------------------------------------------------------------------------
1838 // Fill up USB_OUT_CONTEXT.
1839 //----------------------------------------------------------------------------
1840 // Get index to out pipe from specified QueueID.
1841#ifndef USE_ONE_PIPE
1842 idx_pipe = txqueue2outpipe(priv,queue_index);
1843#else
1844 idx_pipe = 0x04;
1845#endif
1846#ifdef JOHN_DUMP_TXDESC
1847 int i;
1848 printk("<Tx descriptor>--rate %x---",rate);
1849 for (i = 0; i < 8; i++)
1850 printk("%8x ", tx[i]);
1851 printk("\n");
1852#endif
1853 usb_fill_bulk_urb(tx_urb,priv->udev, usb_sndbulkpipe(priv->udev,idx_pipe), \
1854 skb->data, skb->len, rtl8192_tx_isr, skb);
1855
8fc8598e 1856 status = usb_submit_urb(tx_urb, GFP_ATOMIC);
8fc8598e
JC
1857
1858 if (!status){
1859 return 0;
1860 }else{
1861 DMESGE("Error TX CMD URB, error %d",
1862 status);
1863 return -1;
1864 }
1865}
1866
1867/*
1868 * Mapping Software/Hardware descriptor queue id to "Queue Select Field"
1869 * in TxFwInfo data structure
1870 * 2006.10.30 by Emily
1871 *
1872 * \param QUEUEID Software Queue
1873*/
1874u8 MapHwQueueToFirmwareQueue(u8 QueueID)
1875{
1876 u8 QueueSelect = 0x0; //defualt set to
1877
1878 switch(QueueID) {
1879 case BE_QUEUE:
1880 QueueSelect = QSLT_BE; //or QSelect = pTcb->priority;
1881 break;
1882
1883 case BK_QUEUE:
1884 QueueSelect = QSLT_BK; //or QSelect = pTcb->priority;
1885 break;
1886
1887 case VO_QUEUE:
1888 QueueSelect = QSLT_VO; //or QSelect = pTcb->priority;
1889 break;
1890
1891 case VI_QUEUE:
1892 QueueSelect = QSLT_VI; //or QSelect = pTcb->priority;
1893 break;
1894 case MGNT_QUEUE:
1895 QueueSelect = QSLT_MGNT;
1896 break;
1897
1898 case BEACON_QUEUE:
1899 QueueSelect = QSLT_BEACON;
1900 break;
1901
1902 // TODO: 2006.10.30 mark other queue selection until we verify it is OK
1903 // TODO: Remove Assertions
1904//#if (RTL819X_FPGA_VER & RTL819X_FPGA_GUANGAN_070502)
1905 case TXCMD_QUEUE:
1906 QueueSelect = QSLT_CMD;
1907 break;
1908//#endif
1909 case HIGH_QUEUE:
1910 QueueSelect = QSLT_HIGH;
1911 break;
1912
1913 default:
1914 RT_TRACE(COMP_ERR, "TransmitTCB(): Impossible Queue Selection: %d \n", QueueID);
1915 break;
1916 }
1917 return QueueSelect;
1918}
1919
1920u8 MRateToHwRate8190Pci(u8 rate)
1921{
1922 u8 ret = DESC90_RATE1M;
1923
1924 switch(rate) {
1925 case MGN_1M: ret = DESC90_RATE1M; break;
1926 case MGN_2M: ret = DESC90_RATE2M; break;
1927 case MGN_5_5M: ret = DESC90_RATE5_5M; break;
1928 case MGN_11M: ret = DESC90_RATE11M; break;
1929 case MGN_6M: ret = DESC90_RATE6M; break;
1930 case MGN_9M: ret = DESC90_RATE9M; break;
1931 case MGN_12M: ret = DESC90_RATE12M; break;
1932 case MGN_18M: ret = DESC90_RATE18M; break;
1933 case MGN_24M: ret = DESC90_RATE24M; break;
1934 case MGN_36M: ret = DESC90_RATE36M; break;
1935 case MGN_48M: ret = DESC90_RATE48M; break;
1936 case MGN_54M: ret = DESC90_RATE54M; break;
1937
1938 // HT rate since here
1939 case MGN_MCS0: ret = DESC90_RATEMCS0; break;
1940 case MGN_MCS1: ret = DESC90_RATEMCS1; break;
1941 case MGN_MCS2: ret = DESC90_RATEMCS2; break;
1942 case MGN_MCS3: ret = DESC90_RATEMCS3; break;
1943 case MGN_MCS4: ret = DESC90_RATEMCS4; break;
1944 case MGN_MCS5: ret = DESC90_RATEMCS5; break;
1945 case MGN_MCS6: ret = DESC90_RATEMCS6; break;
1946 case MGN_MCS7: ret = DESC90_RATEMCS7; break;
1947 case MGN_MCS8: ret = DESC90_RATEMCS8; break;
1948 case MGN_MCS9: ret = DESC90_RATEMCS9; break;
1949 case MGN_MCS10: ret = DESC90_RATEMCS10; break;
1950 case MGN_MCS11: ret = DESC90_RATEMCS11; break;
1951 case MGN_MCS12: ret = DESC90_RATEMCS12; break;
1952 case MGN_MCS13: ret = DESC90_RATEMCS13; break;
1953 case MGN_MCS14: ret = DESC90_RATEMCS14; break;
1954 case MGN_MCS15: ret = DESC90_RATEMCS15; break;
1955 case (0x80|0x20): ret = DESC90_RATEMCS32; break;
1956
1957 default: break;
1958 }
1959 return ret;
1960}
1961
1962
1963u8 QueryIsShort(u8 TxHT, u8 TxRate, cb_desc *tcb_desc)
1964{
1965 u8 tmp_Short;
1966
1967 tmp_Short = (TxHT==1)?((tcb_desc->bUseShortGI)?1:0):((tcb_desc->bUseShortPreamble)?1:0);
1968
1969 if(TxHT==1 && TxRate != DESC90_RATEMCS15)
1970 tmp_Short = 0;
1971
1972 return tmp_Short;
1973}
1974
8fc8598e 1975static void tx_zero_isr(struct urb *tx_urb)
8fc8598e
JC
1976{
1977 return;
1978}
1979
1980/*
1981 * The tx procedure is just as following,
1982 * skb->cb will contain all the following information,
1983 * priority, morefrag, rate, &dev.
1984 * */
1985short rtl8192_tx(struct net_device *dev, struct sk_buff* skb)
1986{
1987 struct r8192_priv *priv = ieee80211_priv(dev);
1988 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1989 tx_desc_819x_usb *tx_desc = (tx_desc_819x_usb *)skb->data;
1990 tx_fwinfo_819x_usb *tx_fwinfo = (tx_fwinfo_819x_usb *)(skb->data + USB_HWDESC_HEADER_LEN);
1991 struct usb_device *udev = priv->udev;
1992 int pend;
1993 int status;
1994 struct urb *tx_urb = NULL, *tx_urb_zero = NULL;
1995 //int urb_len;
1996 unsigned int idx_pipe;
1997// RT_DEBUG_DATA(COMP_SEND, tcb_desc, sizeof(cb_desc));
8fc8598e
JC
1998// printk("=============> %s\n", __FUNCTION__);
1999 pend = atomic_read(&priv->tx_pending[tcb_desc->queue_index]);
2000 /* we are locked here so the two atomic_read and inc are executed
2001 * without interleaves
2002 * !!! For debug purpose
2003 */
2004 if( pend > MAX_TX_URB){
8fc8598e
JC
2005 printk("To discard skb packet!\n");
2006 dev_kfree_skb_any(skb);
2007 return -1;
2008 }
2009
8fc8598e 2010 tx_urb = usb_alloc_urb(0,GFP_ATOMIC);
8fc8598e
JC
2011 if(!tx_urb){
2012 dev_kfree_skb_any(skb);
2013 return -ENOMEM;
2014 }
2015
2016 /* Fill Tx firmware info */
2017 memset(tx_fwinfo,0,sizeof(tx_fwinfo_819x_usb));
2018 /* DWORD 0 */
2019 tx_fwinfo->TxHT = (tcb_desc->data_rate&0x80)?1:0;
2020 tx_fwinfo->TxRate = MRateToHwRate8190Pci(tcb_desc->data_rate);
2021 tx_fwinfo->EnableCPUDur = tcb_desc->bTxEnableFwCalcDur;
2022 tx_fwinfo->Short = QueryIsShort(tx_fwinfo->TxHT, tx_fwinfo->TxRate, tcb_desc);
2023 if(tcb_desc->bAMPDUEnable) {//AMPDU enabled
2024 tx_fwinfo->AllowAggregation = 1;
2025 /* DWORD 1 */
2026 tx_fwinfo->RxMF = tcb_desc->ampdu_factor;
2027 tx_fwinfo->RxAMD = tcb_desc->ampdu_density&0x07;//ampdudensity
2028 } else {
2029 tx_fwinfo->AllowAggregation = 0;
2030 /* DWORD 1 */
2031 tx_fwinfo->RxMF = 0;
2032 tx_fwinfo->RxAMD = 0;
2033 }
2034
2035 /* Protection mode related */
2036 tx_fwinfo->RtsEnable = (tcb_desc->bRTSEnable)?1:0;
2037 tx_fwinfo->CtsEnable = (tcb_desc->bCTSEnable)?1:0;
2038 tx_fwinfo->RtsSTBC = (tcb_desc->bRTSSTBC)?1:0;
2039 tx_fwinfo->RtsHT = (tcb_desc->rts_rate&0x80)?1:0;
2040 tx_fwinfo->RtsRate = MRateToHwRate8190Pci((u8)tcb_desc->rts_rate);
2041 tx_fwinfo->RtsSubcarrier = (tx_fwinfo->RtsHT==0)?(tcb_desc->RTSSC):0;
2042 tx_fwinfo->RtsBandwidth = (tx_fwinfo->RtsHT==1)?((tcb_desc->bRTSBW)?1:0):0;
2043 tx_fwinfo->RtsShort = (tx_fwinfo->RtsHT==0)?(tcb_desc->bRTSUseShortPreamble?1:0):\
2044 (tcb_desc->bRTSUseShortGI?1:0);
2045
2046 /* Set Bandwidth and sub-channel settings. */
2047 if(priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20_40)
2048 {
2049 if(tcb_desc->bPacketBW) {
2050 tx_fwinfo->TxBandwidth = 1;
2051 tx_fwinfo->TxSubCarrier = 0; //By SD3's Jerry suggestion, use duplicated mode
2052 } else {
2053 tx_fwinfo->TxBandwidth = 0;
2054 tx_fwinfo->TxSubCarrier = priv->nCur40MhzPrimeSC;
2055 }
2056 } else {
2057 tx_fwinfo->TxBandwidth = 0;
2058 tx_fwinfo->TxSubCarrier = 0;
2059 }
2060
2061#ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
2062 if (tcb_desc->drv_agg_enable)
2063 {
2064 tx_fwinfo->Tx_INFO_RSVD = (tcb_desc->DrvAggrNum & 0x1f) << 1;
2065 }
2066#endif
2067 /* Fill Tx descriptor */
2068 memset(tx_desc, 0, sizeof(tx_desc_819x_usb));
2069 /* DWORD 0 */
e406322b
MCC
2070 tx_desc->LINIP = 0;
2071 tx_desc->CmdInit = 1;
2072 tx_desc->Offset = sizeof(tx_fwinfo_819x_usb) + 8;
8fc8598e
JC
2073
2074#ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
2075 if (tcb_desc->drv_agg_enable) {
2076 tx_desc->PktSize = tcb_desc->pkt_size;
2077 } else
2078#endif
2079 {
2080 tx_desc->PktSize = (skb->len - TX_PACKET_SHIFT_BYTES) & 0xffff;
2081 }
2082
2083 /*DWORD 1*/
2084 tx_desc->SecCAMID= 0;
2085 tx_desc->RATid = tcb_desc->RATRIndex;
8fc8598e
JC
2086 {
2087 //MPDUOverhead = 0;
2088 tx_desc->NoEnc = 1;
2089 }
8fc8598e 2090 tx_desc->SecType = 0x0;
8fc8598e
JC
2091 if (tcb_desc->bHwSec)
2092 {
2093 switch (priv->ieee80211->pairwise_key_type)
2094 {
2095 case KEY_TYPE_WEP40:
2096 case KEY_TYPE_WEP104:
2097 tx_desc->SecType = 0x1;
2098 tx_desc->NoEnc = 0;
2099 break;
2100 case KEY_TYPE_TKIP:
2101 tx_desc->SecType = 0x2;
2102 tx_desc->NoEnc = 0;
2103 break;
2104 case KEY_TYPE_CCMP:
2105 tx_desc->SecType = 0x3;
2106 tx_desc->NoEnc = 0;
2107 break;
2108 case KEY_TYPE_NA:
2109 tx_desc->SecType = 0x0;
2110 tx_desc->NoEnc = 1;
2111 break;
2112 }
2113 }
2114
2115 tx_desc->QueueSelect = MapHwQueueToFirmwareQueue(tcb_desc->queue_index);
2116 tx_desc->TxFWInfoSize = sizeof(tx_fwinfo_819x_usb);
2117
2118 tx_desc->DISFB = tcb_desc->bTxDisableRateFallBack;
2119 tx_desc->USERATE = tcb_desc->bTxUseDriverAssingedRate;
2120
e406322b
MCC
2121 /* Fill fields that are required to be initialized in all of the descriptors */
2122 //DWORD 0
e406322b
MCC
2123 tx_desc->FirstSeg = 1;
2124 tx_desc->LastSeg = 1;
e406322b 2125 tx_desc->OWN = 1;
8fc8598e
JC
2126
2127#ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
2128 if (tcb_desc->drv_agg_enable) {
2129 tx_desc->TxBufferSize = tcb_desc->pkt_size + sizeof(tx_fwinfo_819x_usb);
2130 } else
2131#endif
2132 {
2133 //DWORD 2
2134 tx_desc->TxBufferSize = (u32)(skb->len - USB_HWDESC_HEADER_LEN);
2135 }
2136 /* Get index to out pipe from specified QueueID */
2137#ifndef USE_ONE_PIPE
2138 idx_pipe = txqueue2outpipe(priv,tcb_desc->queue_index);
2139#else
2140 idx_pipe = 0x5;
2141#endif
2142
2143 //RT_DEBUG_DATA(COMP_SEND,tx_fwinfo,sizeof(tx_fwinfo_819x_usb));
2144 //RT_DEBUG_DATA(COMP_SEND,tx_desc,sizeof(tx_desc_819x_usb));
2145
2146 /* To submit bulk urb */
2147 usb_fill_bulk_urb(tx_urb,udev,
2148 usb_sndbulkpipe(udev,idx_pipe), skb->data,
2149 skb->len, rtl8192_tx_isr, skb);
2150
8fc8598e 2151 status = usb_submit_urb(tx_urb, GFP_ATOMIC);
8fc8598e
JC
2152 if (!status){
2153//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
2154 bool bSend0Byte = false;
2155 u8 zero = 0;
2156 if(udev->speed == USB_SPEED_HIGH)
2157 {
2158 if (skb->len > 0 && skb->len % 512 == 0)
2159 bSend0Byte = true;
2160 }
2161 else
2162 {
2163 if (skb->len > 0 && skb->len % 64 == 0)
2164 bSend0Byte = true;
2165 }
2166 if (bSend0Byte)
2167 {
8fc8598e 2168 tx_urb_zero = usb_alloc_urb(0,GFP_ATOMIC);
8fc8598e
JC
2169 if(!tx_urb_zero){
2170 RT_TRACE(COMP_ERR, "can't alloc urb for zero byte\n");
2171 return -ENOMEM;
2172 }
2173 usb_fill_bulk_urb(tx_urb_zero,udev,
2174 usb_sndbulkpipe(udev,idx_pipe), &zero,
2175 0, tx_zero_isr, dev);
8fc8598e 2176 status = usb_submit_urb(tx_urb_zero, GFP_ATOMIC);
8fc8598e
JC
2177 if (status){
2178 RT_TRACE(COMP_ERR, "Error TX URB for zero byte %d, error %d", atomic_read(&priv->tx_pending[tcb_desc->queue_index]), status);
2179 return -1;
2180 }
8fc8598e
JC
2181 }
2182 dev->trans_start = jiffies;
2183 atomic_inc(&priv->tx_pending[tcb_desc->queue_index]);
2184 return 0;
2185 }else{
2186 RT_TRACE(COMP_ERR, "Error TX URB %d, error %d", atomic_read(&priv->tx_pending[tcb_desc->queue_index]),
2187 status);
2188 return -1;
2189 }
2190}
2191
2192short rtl8192_usb_initendpoints(struct net_device *dev)
2193{
2194 struct r8192_priv *priv = ieee80211_priv(dev);
2195
32414878
JL
2196 priv->rx_urb = kmalloc(sizeof(struct urb *) * (MAX_RX_URB+1),
2197 GFP_KERNEL);
b8345175
DC
2198 if (priv->rx_urb == NULL)
2199 return -ENOMEM;
8fc8598e
JC
2200
2201#ifndef JACKSON_NEW_RX
2202 for(i=0;i<(MAX_RX_URB+1);i++){
2203
8fc8598e 2204 priv->rx_urb[i] = usb_alloc_urb(0,GFP_KERNEL);
8fc8598e
JC
2205
2206 priv->rx_urb[i]->transfer_buffer = kmalloc(RX_URB_SIZE, GFP_KERNEL);
2207
2208 priv->rx_urb[i]->transfer_buffer_length = RX_URB_SIZE;
2209 }
2210#endif
2211
2212#ifdef THOMAS_BEACON
2213{
f61fb935
MCC
2214 long align = 0;
2215 void *oldaddr, *newaddr;
2216
8fc8598e 2217 priv->rx_urb[16] = usb_alloc_urb(0, GFP_KERNEL);
8fc8598e 2218 priv->oldaddr = kmalloc(16, GFP_KERNEL);
f61fb935
MCC
2219 oldaddr = priv->oldaddr;
2220 align = ((long)oldaddr) & 3;
2221 if (align) {
8fc8598e 2222 newaddr = oldaddr + 4 - align;
f61fb935
MCC
2223 priv->rx_urb[16]->transfer_buffer_length = 16 - 4 + align;
2224 } else {
8fc8598e
JC
2225 newaddr = oldaddr;
2226 priv->rx_urb[16]->transfer_buffer_length = 16;
2227 }
f61fb935 2228 priv->rx_urb[16]->transfer_buffer = newaddr;
8fc8598e
JC
2229}
2230#endif
2231
e406322b 2232 memset(priv->rx_urb, 0, sizeof(struct urb*) * MAX_RX_URB);
7a6cb0d5 2233 priv->pp_rxskb = kcalloc(MAX_RX_URB, sizeof(struct sk_buff *),
32414878 2234 GFP_KERNEL);
e406322b
MCC
2235 if (priv->pp_rxskb == NULL)
2236 goto destroy;
8fc8598e 2237
e406322b 2238 goto _middle;
8fc8598e
JC
2239
2240
2241destroy:
e72714fb
IM
2242 kfree(priv->pp_rxskb);
2243 kfree(priv->rx_urb);
8fc8598e 2244
e406322b 2245 priv->pp_rxskb = NULL;
8fc8598e
JC
2246 priv->rx_urb = NULL;
2247
e406322b
MCC
2248 DMESGE("Endpoint Alloc Failure");
2249 return -ENOMEM;
8fc8598e
JC
2250
2251
2252_middle:
2253
2254 printk("End of initendpoints\n");
2255 return 0;
2256
2257}
2258#ifdef THOMAS_BEACON
2259void rtl8192_usb_deleteendpoints(struct net_device *dev)
2260{
2261 int i;
2262 struct r8192_priv *priv = ieee80211_priv(dev);
2263
2264 if(priv->rx_urb){
2265 for(i=0;i<(MAX_RX_URB+1);i++){
2266 usb_kill_urb(priv->rx_urb[i]);
2267 usb_free_urb(priv->rx_urb[i]);
2268 }
2269 kfree(priv->rx_urb);
2270 priv->rx_urb = NULL;
2271 }
e72714fb
IM
2272 kfree(priv->oldaddr);
2273 priv->oldaddr = NULL;
e406322b
MCC
2274 if (priv->pp_rxskb) {
2275 kfree(priv->pp_rxskb);
2276 priv->pp_rxskb = 0;
8fc8598e
JC
2277 }
2278}
2279#else
2280void rtl8192_usb_deleteendpoints(struct net_device *dev)
2281{
2282 int i;
2283 struct r8192_priv *priv = ieee80211_priv(dev);
2284
2285#ifndef JACKSON_NEW_RX
2286
2287 if(priv->rx_urb){
2288 for(i=0;i<(MAX_RX_URB+1);i++){
2289 usb_kill_urb(priv->rx_urb[i]);
2290 kfree(priv->rx_urb[i]->transfer_buffer);
2291 usb_free_urb(priv->rx_urb[i]);
2292 }
2293 kfree(priv->rx_urb);
2294 priv->rx_urb = NULL;
2295
2296 }
2297#else
e72714fb
IM
2298 kfree(priv->rx_urb);
2299 priv->rx_urb = NULL;
2300 kfree(priv->oldaddr);
2301 priv->oldaddr = NULL;
e406322b
MCC
2302 if (priv->pp_rxskb) {
2303 kfree(priv->pp_rxskb);
2304 priv->pp_rxskb = 0;
8fc8598e 2305
e406322b 2306 }
8fc8598e
JC
2307
2308#endif
2309}
2310#endif
2311
8fc8598e
JC
2312extern void rtl8192_update_ratr_table(struct net_device* dev);
2313void rtl8192_link_change(struct net_device *dev)
2314{
2315// int i;
2316
2317 struct r8192_priv *priv = ieee80211_priv(dev);
2318 struct ieee80211_device* ieee = priv->ieee80211;
2319 //write_nic_word(dev, BCN_INTR_ITV, net->beacon_interval);
2320 if (ieee->state == IEEE80211_LINKED)
2321 {
2322 rtl8192_net_update(dev);
2323 rtl8192_update_ratr_table(dev);
8fc8598e
JC
2324 //add this as in pure N mode, wep encryption will use software way, but there is no chance to set this as wep will not set group key in wext. WB.2008.07.08
2325 if ((KEY_TYPE_WEP40 == ieee->pairwise_key_type) || (KEY_TYPE_WEP104 == ieee->pairwise_key_type))
2326 EnableHWSecurityConfig8192(dev);
8fc8598e
JC
2327 }
2328 /*update timing params*/
2329// RT_TRACE(COMP_CH, "========>%s(), chan:%d\n", __FUNCTION__, priv->chan);
2330// rtl8192_set_chan(dev, priv->chan);
2331 if (ieee->iw_mode == IW_MODE_INFRA || ieee->iw_mode == IW_MODE_ADHOC)
2332 {
2333 u32 reg = 0;
2334 reg = read_nic_dword(dev, RCR);
2335 if (priv->ieee80211->state == IEEE80211_LINKED)
2336 priv->ReceiveConfig = reg |= RCR_CBSSID;
2337 else
2338 priv->ReceiveConfig = reg &= ~RCR_CBSSID;
2339 write_nic_dword(dev, RCR, reg);
2340 }
2341
2342// rtl8192_set_rxconf(dev);
2343}
2344
2345static struct ieee80211_qos_parameters def_qos_parameters = {
2346 {3,3,3,3},/* cw_min */
2347 {7,7,7,7},/* cw_max */
2348 {2,2,2,2},/* aifs */
2349 {0,0,0,0},/* flags */
2350 {0,0,0,0} /* tx_op_limit */
2351};
2352
2353
8fc8598e
JC
2354void rtl8192_update_beacon(struct work_struct * work)
2355{
2356 struct r8192_priv *priv = container_of(work, struct r8192_priv, update_beacon_wq.work);
2357 struct net_device *dev = priv->ieee80211->dev;
8fc8598e
JC
2358 struct ieee80211_device* ieee = priv->ieee80211;
2359 struct ieee80211_network* net = &ieee->current_network;
2360
2361 if (ieee->pHTInfo->bCurrentHTSupport)
2362 HTUpdateSelfAndPeerSetting(ieee, net);
2363 ieee->pHTInfo->bCurrentRT2RTLongSlotTime = net->bssht.bdRT2RTLongSlotTime;
2364 rtl8192_update_cap(dev, net->capability);
2365}
2366/*
2367* background support to run QoS activate functionality
2368*/
2369int WDCAPARA_ADD[] = {EDCAPARA_BE,EDCAPARA_BK,EDCAPARA_VI,EDCAPARA_VO};
8fc8598e
JC
2370void rtl8192_qos_activate(struct work_struct * work)
2371{
e406322b
MCC
2372 struct r8192_priv *priv = container_of(work, struct r8192_priv, qos_activate);
2373 struct net_device *dev = priv->ieee80211->dev;
e406322b
MCC
2374 struct ieee80211_qos_parameters *qos_parameters = &priv->ieee80211->current_network.qos_data.parameters;
2375 u8 mode = priv->ieee80211->current_network.mode;
2376 //u32 size = sizeof(struct ieee80211_qos_parameters);
8fc8598e
JC
2377 u8 u1bAIFS;
2378 u32 u4bAcParam;
e406322b 2379 int i;
8fc8598e 2380
e406322b
MCC
2381 if (priv == NULL)
2382 return;
8fc8598e 2383
8fc8598e 2384 mutex_lock(&priv->mutex);
e406322b 2385 if(priv->ieee80211->state != IEEE80211_LINKED)
8fc8598e
JC
2386 goto success;
2387 RT_TRACE(COMP_QOS,"qos active process with associate response received\n");
2388 /* It better set slot time at first */
2389 /* For we just support b/g mode at present, let the slot time at 9/20 selection */
2390 /* update the ac parameter to related registers */
2391 for(i = 0; i < QOS_QUEUE_NUM; i++) {
2392 //Mode G/A: slotTimeTimer = 9; Mode B: 20
2393 u1bAIFS = qos_parameters->aifs[i] * ((mode&(IEEE_G|IEEE_N_24G)) ?9:20) + aSifsTime;
2394 u4bAcParam = ((((u32)(qos_parameters->tx_op_limit[i]))<< AC_PARAM_TXOP_LIMIT_OFFSET)|
2395 (((u32)(qos_parameters->cw_max[i]))<< AC_PARAM_ECW_MAX_OFFSET)|
2396 (((u32)(qos_parameters->cw_min[i]))<< AC_PARAM_ECW_MIN_OFFSET)|
2397 ((u32)u1bAIFS << AC_PARAM_AIFS_OFFSET));
2398
2399 write_nic_dword(dev, WDCAPARA_ADD[i], u4bAcParam);
2400 //write_nic_dword(dev, WDCAPARA_ADD[i], 0x005e4332);
2401 }
2402
2403success:
8fc8598e 2404 mutex_unlock(&priv->mutex);
8fc8598e
JC
2405}
2406
2407static int rtl8192_qos_handle_probe_response(struct r8192_priv *priv,
2408 int active_network,
2409 struct ieee80211_network *network)
2410{
2411 int ret = 0;
2412 u32 size = sizeof(struct ieee80211_qos_parameters);
2413
2414 if(priv->ieee80211->state !=IEEE80211_LINKED)
e406322b 2415 return ret;
8fc8598e 2416
e406322b
MCC
2417 if ((priv->ieee80211->iw_mode != IW_MODE_INFRA))
2418 return ret;
8fc8598e
JC
2419
2420 if (network->flags & NETWORK_HAS_QOS_MASK) {
2421 if (active_network &&
2422 (network->flags & NETWORK_HAS_QOS_PARAMETERS))
2423 network->qos_data.active = network->qos_data.supported;
2424
2425 if ((network->qos_data.active == 1) && (active_network == 1) &&
2426 (network->flags & NETWORK_HAS_QOS_PARAMETERS) &&
2427 (network->qos_data.old_param_count !=
2428 network->qos_data.param_count)) {
2429 network->qos_data.old_param_count =
2430 network->qos_data.param_count;
8fc8598e 2431 queue_work(priv->priv_wq, &priv->qos_activate);
8fc8598e
JC
2432 RT_TRACE (COMP_QOS, "QoS parameters change call "
2433 "qos_activate\n");
2434 }
2435 } else {
2436 memcpy(&priv->ieee80211->current_network.qos_data.parameters,\
2437 &def_qos_parameters, size);
2438
2439 if ((network->qos_data.active == 1) && (active_network == 1)) {
8fc8598e 2440 queue_work(priv->priv_wq, &priv->qos_activate);
8fc8598e
JC
2441 RT_TRACE(COMP_QOS, "QoS was disabled call qos_activate \n");
2442 }
2443 network->qos_data.active = 0;
2444 network->qos_data.supported = 0;
2445 }
2446
2447 return 0;
2448}
2449
589b3d06 2450/* handle and manage frame from beacon and probe response */
8fc8598e 2451static int rtl8192_handle_beacon(struct net_device * dev,
e406322b
MCC
2452 struct ieee80211_beacon * beacon,
2453 struct ieee80211_network * network)
8fc8598e
JC
2454{
2455 struct r8192_priv *priv = ieee80211_priv(dev);
2456
2457 rtl8192_qos_handle_probe_response(priv,1,network);
8fc8598e 2458 queue_delayed_work(priv->priv_wq, &priv->update_beacon_wq, 0);
8fc8598e
JC
2459 return 0;
2460
2461}
2462
2463/*
2464* handling the beaconing responses. if we get different QoS setting
2465* off the network from the associated setting, adjust the QoS
2466* setting
2467*/
2468static int rtl8192_qos_association_resp(struct r8192_priv *priv,
e406322b 2469 struct ieee80211_network *network)
8fc8598e 2470{
e406322b
MCC
2471 int ret = 0;
2472 unsigned long flags;
2473 u32 size = sizeof(struct ieee80211_qos_parameters);
2474 int set_qos_param = 0;
8fc8598e 2475
e406322b
MCC
2476 if ((priv == NULL) || (network == NULL))
2477 return ret;
8fc8598e
JC
2478
2479 if(priv->ieee80211->state !=IEEE80211_LINKED)
e406322b 2480 return ret;
8fc8598e 2481
e406322b
MCC
2482 if ((priv->ieee80211->iw_mode != IW_MODE_INFRA))
2483 return ret;
8fc8598e 2484
e406322b 2485 spin_lock_irqsave(&priv->ieee80211->lock, flags);
8fc8598e
JC
2486 if(network->flags & NETWORK_HAS_QOS_PARAMETERS) {
2487 memcpy(&priv->ieee80211->current_network.qos_data.parameters,\
2488 &network->qos_data.parameters,\
2489 sizeof(struct ieee80211_qos_parameters));
2490 priv->ieee80211->current_network.qos_data.active = 1;
8fc8598e 2491 {
e406322b 2492 set_qos_param = 1;
8fc8598e
JC
2493 /* update qos parameter for current network */
2494 priv->ieee80211->current_network.qos_data.old_param_count = \
2495 priv->ieee80211->current_network.qos_data.param_count;
2496 priv->ieee80211->current_network.qos_data.param_count = \
e406322b 2497 network->qos_data.param_count;
8fc8598e 2498 }
e406322b 2499 } else {
8fc8598e
JC
2500 memcpy(&priv->ieee80211->current_network.qos_data.parameters,\
2501 &def_qos_parameters, size);
2502 priv->ieee80211->current_network.qos_data.active = 0;
2503 priv->ieee80211->current_network.qos_data.supported = 0;
e406322b
MCC
2504 set_qos_param = 1;
2505 }
8fc8598e 2506
e406322b 2507 spin_unlock_irqrestore(&priv->ieee80211->lock, flags);
8fc8598e
JC
2508
2509 RT_TRACE(COMP_QOS, "%s: network->flags = %d,%d\n",__FUNCTION__,network->flags ,priv->ieee80211->current_network.qos_data.active);
2510 if (set_qos_param == 1)
8fc8598e 2511 queue_work(priv->priv_wq, &priv->qos_activate);
8fc8598e
JC
2512
2513
e406322b 2514 return ret;
8fc8598e
JC
2515}
2516
2517
2518static int rtl8192_handle_assoc_response(struct net_device *dev,
e406322b
MCC
2519 struct ieee80211_assoc_response_frame *resp,
2520 struct ieee80211_network *network)
8fc8598e 2521{
e406322b
MCC
2522 struct r8192_priv *priv = ieee80211_priv(dev);
2523 rtl8192_qos_association_resp(priv, network);
2524 return 0;
8fc8598e
JC
2525}
2526
2527
2528void rtl8192_update_ratr_table(struct net_device* dev)
2529 // POCTET_STRING posLegacyRate,
2530 // u8* pMcsRate)
2531 // PRT_WLAN_STA pEntry)
2532{
2533 struct r8192_priv* priv = ieee80211_priv(dev);
2534 struct ieee80211_device* ieee = priv->ieee80211;
2535 u8* pMcsRate = ieee->dot11HTOperationalRateSet;
2536 //struct ieee80211_network *net = &ieee->current_network;
2537 u32 ratr_value = 0;
2538 u8 rate_index = 0;
2539 rtl8192_config_rate(dev, (u16*)(&ratr_value));
2540 ratr_value |= (*(u16*)(pMcsRate)) << 12;
2541// switch (net->mode)
2542 switch (ieee->mode)
2543 {
2544 case IEEE_A:
2545 ratr_value &= 0x00000FF0;
2546 break;
2547 case IEEE_B:
2548 ratr_value &= 0x0000000F;
2549 break;
2550 case IEEE_G:
2551 ratr_value &= 0x00000FF7;
2552 break;
2553 case IEEE_N_24G:
2554 case IEEE_N_5G:
2555 if (ieee->pHTInfo->PeerMimoPs == 0) //MIMO_PS_STATIC
2556 ratr_value &= 0x0007F007;
2557 else{
2558 if (priv->rf_type == RF_1T2R)
2559 ratr_value &= 0x000FF007;
2560 else
2561 ratr_value &= 0x0F81F007;
2562 }
2563 break;
2564 default:
2565 break;
2566 }
2567 ratr_value &= 0x0FFFFFFF;
2568 if(ieee->pHTInfo->bCurTxBW40MHz && ieee->pHTInfo->bCurShortGI40MHz){
2569 ratr_value |= 0x80000000;
2570 }else if(!ieee->pHTInfo->bCurTxBW40MHz && ieee->pHTInfo->bCurShortGI20MHz){
2571 ratr_value |= 0x80000000;
2572 }
2573 write_nic_dword(dev, RATR0+rate_index*4, ratr_value);
2574 write_nic_byte(dev, UFWP, 1);
2575}
2576
2577static u8 ccmp_ie[4] = {0x00,0x50,0xf2,0x04};
2578static u8 ccmp_rsn_ie[4] = {0x00, 0x0f, 0xac, 0x04};
2579bool GetNmodeSupportBySecCfg8192(struct net_device*dev)
2580{
8fc8598e
JC
2581 struct r8192_priv* priv = ieee80211_priv(dev);
2582 struct ieee80211_device* ieee = priv->ieee80211;
2583 struct ieee80211_network * network = &ieee->current_network;
e406322b
MCC
2584 int wpa_ie_len= ieee->wpa_ie_len;
2585 struct ieee80211_crypt_data* crypt;
2586 int encrypt;
8fc8598e 2587
e406322b 2588 crypt = ieee->crypt[ieee->tx_keyidx];
8fc8598e 2589 //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
e406322b 2590 encrypt = (network->capability & WLAN_CAPABILITY_PRIVACY) || (ieee->host_encrypt && crypt && crypt->ops && (0 == strcmp(crypt->ops->name,"WEP")));
8fc8598e
JC
2591
2592 /* simply judge */
2593 if(encrypt && (wpa_ie_len == 0)) {
2594 /* wep encryption, no N mode setting */
2595 return false;
2596// } else if((wpa_ie_len != 0)&&(memcmp(&(ieee->wpa_ie[14]),ccmp_ie,4))) {
2597 } else if((wpa_ie_len != 0)) {
2598 /* parse pairwise key type */
2599 //if((pairwisekey = WEP40)||(pairwisekey = WEP104)||(pairwisekey = TKIP))
2600 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))))
2601 return true;
2602 else
2603 return false;
2604 } else {
2605 return true;
2606 }
2607
8fc8598e 2608 return true;
8fc8598e
JC
2609}
2610
2611bool GetHalfNmodeSupportByAPs819xUsb(struct net_device* dev)
2612{
2613 bool Reval;
2614 struct r8192_priv* priv = ieee80211_priv(dev);
2615 struct ieee80211_device* ieee = priv->ieee80211;
2616
2617 if(ieee->bHalfWirelessN24GMode == true)
2618 Reval = true;
2619 else
2620 Reval = false;
2621
2622 return Reval;
2623}
2624
2625void rtl8192_refresh_supportrate(struct r8192_priv* priv)
2626{
2627 struct ieee80211_device* ieee = priv->ieee80211;
589b3d06 2628 //we do not consider set support rate for ABG mode, only HT MCS rate is set here.
8fc8598e
JC
2629 if (ieee->mode == WIRELESS_MODE_N_24G || ieee->mode == WIRELESS_MODE_N_5G)
2630 {
2631 memcpy(ieee->Regdot11HTOperationalRateSet, ieee->RegHTSuppRateSet, 16);
2632 //RT_DEBUG_DATA(COMP_INIT, ieee->RegHTSuppRateSet, 16);
2633 //RT_DEBUG_DATA(COMP_INIT, ieee->Regdot11HTOperationalRateSet, 16);
2634 }
2635 else
2636 memset(ieee->Regdot11HTOperationalRateSet, 0, 16);
2637 return;
2638}
2639
2640u8 rtl8192_getSupportedWireleeMode(struct net_device*dev)
2641{
2642 struct r8192_priv *priv = ieee80211_priv(dev);
2643 u8 ret = 0;
2644 switch(priv->rf_chip)
2645 {
2646 case RF_8225:
2647 case RF_8256:
2648 case RF_PSEUDO_11N:
2649 ret = (WIRELESS_MODE_N_24G|WIRELESS_MODE_G|WIRELESS_MODE_B);
2650 break;
2651 case RF_8258:
2652 ret = (WIRELESS_MODE_A|WIRELESS_MODE_N_5G);
2653 break;
2654 default:
2655 ret = WIRELESS_MODE_B;
2656 break;
2657 }
2658 return ret;
2659}
2660void rtl8192_SetWirelessMode(struct net_device* dev, u8 wireless_mode)
2661{
2662 struct r8192_priv *priv = ieee80211_priv(dev);
2663 u8 bSupportMode = rtl8192_getSupportedWireleeMode(dev);
2664
8fc8598e
JC
2665 if ((wireless_mode == WIRELESS_MODE_AUTO) || ((wireless_mode&bSupportMode)==0))
2666 {
2667 if(bSupportMode & WIRELESS_MODE_N_24G)
2668 {
2669 wireless_mode = WIRELESS_MODE_N_24G;
2670 }
2671 else if(bSupportMode & WIRELESS_MODE_N_5G)
2672 {
2673 wireless_mode = WIRELESS_MODE_N_5G;
2674 }
2675 else if((bSupportMode & WIRELESS_MODE_A))
2676 {
2677 wireless_mode = WIRELESS_MODE_A;
2678 }
2679 else if((bSupportMode & WIRELESS_MODE_G))
2680 {
2681 wireless_mode = WIRELESS_MODE_G;
2682 }
2683 else if((bSupportMode & WIRELESS_MODE_B))
2684 {
2685 wireless_mode = WIRELESS_MODE_B;
2686 }
2687 else{
2688 RT_TRACE(COMP_ERR, "%s(), No valid wireless mode supported, SupportedWirelessMode(%x)!!!\n", __FUNCTION__,bSupportMode);
2689 wireless_mode = WIRELESS_MODE_B;
2690 }
2691 }
39cfb97b 2692#ifdef TO_DO_LIST //// TODO: this function doesn't work well at this time, we should wait for FPGA
8fc8598e
JC
2693 ActUpdateChannelAccessSetting( pAdapter, pHalData->CurrentWirelessMode, &pAdapter->MgntInfo.Info8185.ChannelAccessSetting );
2694#endif
2695 priv->ieee80211->mode = wireless_mode;
2696
2697 if ((wireless_mode == WIRELESS_MODE_N_24G) || (wireless_mode == WIRELESS_MODE_N_5G))
2698 priv->ieee80211->pHTInfo->bEnableHT = 1;
2699 else
2700 priv->ieee80211->pHTInfo->bEnableHT = 0;
2701 RT_TRACE(COMP_INIT, "Current Wireless Mode is %x\n", wireless_mode);
2702 rtl8192_refresh_supportrate(priv);
8fc8598e
JC
2703
2704}
2705//init priv variables here. only non_zero value should be initialized here.
2706static void rtl8192_init_priv_variable(struct net_device* dev)
2707{
2708 struct r8192_priv *priv = ieee80211_priv(dev);
2709 u8 i;
2710 priv->card_8192 = NIC_8192U;
2711 priv->chan = 1; //set to channel 1
2712 priv->ieee80211->mode = WIRELESS_MODE_AUTO; //SET AUTO
2713 priv->ieee80211->iw_mode = IW_MODE_INFRA;
2714 priv->ieee80211->ieee_up=0;
2715 priv->retry_rts = DEFAULT_RETRY_RTS;
2716 priv->retry_data = DEFAULT_RETRY_DATA;
2717 priv->ieee80211->rts = DEFAULT_RTS_THRESHOLD;
2718 priv->ieee80211->rate = 110; //11 mbps
2719 priv->ieee80211->short_slot = 1;
2720 priv->promisc = (dev->flags & IFF_PROMISC) ? 1:0;
2721 priv->CckPwEnl = 6;
2722 //for silent reset
2723 priv->IrpPendingCount = 1;
2724 priv->ResetProgress = RESET_TYPE_NORESET;
2725 priv->bForcedSilentReset = 0;
2726 priv->bDisableNormalResetCheck = false;
2727 priv->force_reset = false;
2728
2729 priv->ieee80211->FwRWRF = 0; //we don't use FW read/write RF until stable firmware is available.
2730 priv->ieee80211->current_network.beacon_interval = DEFAULT_BEACONINTERVAL;
2731 priv->ieee80211->iw_mode = IW_MODE_INFRA;
2732 priv->ieee80211->softmac_features = IEEE_SOFTMAC_SCAN |
2733 IEEE_SOFTMAC_ASSOCIATE | IEEE_SOFTMAC_PROBERQ |
2734 IEEE_SOFTMAC_PROBERS | IEEE_SOFTMAC_TX_QUEUE |
2735 IEEE_SOFTMAC_BEACONS;//added by amy 080604 //| //IEEE_SOFTMAC_SINGLE_QUEUE;
2736
2737 priv->ieee80211->active_scan = 1;
2738 priv->ieee80211->modulation = IEEE80211_CCK_MODULATION | IEEE80211_OFDM_MODULATION;
2739 priv->ieee80211->host_encrypt = 1;
2740 priv->ieee80211->host_decrypt = 1;
2741 priv->ieee80211->start_send_beacons = NULL;//rtl819xusb_beacon_tx;//-by amy 080604
2742 priv->ieee80211->stop_send_beacons = NULL;//rtl8192_beacon_stop;//-by amy 080604
2743 priv->ieee80211->softmac_hard_start_xmit = rtl8192_hard_start_xmit;
2744 priv->ieee80211->set_chan = rtl8192_set_chan;
2745 priv->ieee80211->link_change = rtl8192_link_change;
2746 priv->ieee80211->softmac_data_hard_start_xmit = rtl8192_hard_data_xmit;
2747 priv->ieee80211->data_hard_stop = rtl8192_data_hard_stop;
2748 priv->ieee80211->data_hard_resume = rtl8192_data_hard_resume;
2749 priv->ieee80211->init_wmmparam_flag = 0;
2750 priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD;
2751 priv->ieee80211->check_nic_enough_desc = check_nic_enough_desc;
2752 priv->ieee80211->tx_headroom = TX_PACKET_SHIFT_BYTES;
2753 priv->ieee80211->qos_support = 1;
2754
2755 //added by WB
2756// priv->ieee80211->SwChnlByTimerHandler = rtl8192_phy_SwChnl;
2757 priv->ieee80211->SetBWModeHandler = rtl8192_SetBWMode;
2758 priv->ieee80211->handle_assoc_response = rtl8192_handle_assoc_response;
2759 priv->ieee80211->handle_beacon = rtl8192_handle_beacon;
2760 //added by david
2761 priv->ieee80211->GetNmodeSupportBySecCfg = GetNmodeSupportBySecCfg8192;
2762 priv->ieee80211->GetHalfNmodeSupportByAPsHandler = GetHalfNmodeSupportByAPs819xUsb;
2763 priv->ieee80211->SetWirelessMode = rtl8192_SetWirelessMode;
2764 //added by amy
2765 priv->ieee80211->InitialGainHandler = InitialGain819xUsb;
2766 priv->card_type = USB;
2767#ifdef TO_DO_LIST
2768 if(Adapter->bInHctTest)
e406322b 2769 {
8fc8598e
JC
2770 pHalData->ShortRetryLimit = 7;
2771 pHalData->LongRetryLimit = 7;
e406322b 2772 }
8fc8598e
JC
2773#endif
2774 {
2775 priv->ShortRetryLimit = 0x30;
2776 priv->LongRetryLimit = 0x30;
2777 }
2778 priv->EarlyRxThreshold = 7;
2779 priv->enable_gpio0 = 0;
2780 priv->TransmitConfig =
2781 // TCR_DurProcMode | //for RTL8185B, duration setting by HW
2782 //? TCR_DISReqQsize |
589b3d06 2783 (TCR_MXDMA_2048<<TCR_MXDMA_OFFSET)| // Max DMA Burst Size per Tx DMA Burst, 7: reserved.
8fc8598e
JC
2784 (priv->ShortRetryLimit<<TCR_SRL_OFFSET)| // Short retry limit
2785 (priv->LongRetryLimit<<TCR_LRL_OFFSET) | // Long retry limit
589b3d06 2786 (false ? TCR_SAT: 0); // FALSE: HW provides PLCP length and LENGEXT, TURE: SW provides them
8fc8598e
JC
2787#ifdef TO_DO_LIST
2788 if(Adapter->bInHctTest)
2789 pHalData->ReceiveConfig = pHalData->CSMethod |
2790 RCR_AMF | RCR_ADF | //RCR_AAP | //accept management/data
2791 //guangan200710
2792 RCR_ACF | //accept control frame for SW AP needs PS-poll, 2005.07.07, by rcnjko.
2793 RCR_AB | RCR_AM | RCR_APM | //accept BC/MC/UC
2794 RCR_AICV | RCR_ACRC32 | //accept ICV/CRC error packet
2795 ((u32)7<<RCR_MXDMA_OFFSET) | // Max DMA Burst Size per Rx DMA Burst, 7: unlimited.
2796 (pHalData->EarlyRxThreshold<<RCR_FIFO_OFFSET) | // Rx FIFO Threshold, 7: No Rx threshold.
2797 (pHalData->EarlyRxThreshold == 7 ? RCR_OnlyErlPkt:0);
2798 else
2799
2800#endif
2801 priv->ReceiveConfig =
2802 RCR_AMF | RCR_ADF | //accept management/data
2803 RCR_ACF | //accept control frame for SW AP needs PS-poll, 2005.07.07, by rcnjko.
2804 RCR_AB | RCR_AM | RCR_APM | //accept BC/MC/UC
2805 //RCR_AICV | RCR_ACRC32 | //accept ICV/CRC error packet
2806 ((u32)7<<RCR_MXDMA_OFFSET)| // Max DMA Burst Size per Rx DMA Burst, 7: unlimited.
2807 (priv->EarlyRxThreshold<<RX_FIFO_THRESHOLD_SHIFT) | // Rx FIFO Threshold, 7: No Rx threshold.
2808 (priv->EarlyRxThreshold == 7 ? RCR_ONLYERLPKT:0);
2809
2810 priv->AcmControl = 0;
32414878 2811 priv->pFirmware = kmalloc(sizeof(rt_firmware), GFP_KERNEL);
8fc8598e
JC
2812 if (priv->pFirmware)
2813 memset(priv->pFirmware, 0, sizeof(rt_firmware));
2814
2815 /* rx related queue */
e406322b 2816 skb_queue_head_init(&priv->rx_queue);
8fc8598e
JC
2817 skb_queue_head_init(&priv->skb_queue);
2818
2819 /* Tx related queue */
2820 for(i = 0; i < MAX_QUEUE_SIZE; i++) {
2821 skb_queue_head_init(&priv->ieee80211->skb_waitQ [i]);
2822 }
2823 for(i = 0; i < MAX_QUEUE_SIZE; i++) {
2824 skb_queue_head_init(&priv->ieee80211->skb_aggQ [i]);
2825 }
2826 for(i = 0; i < MAX_QUEUE_SIZE; i++) {
2827 skb_queue_head_init(&priv->ieee80211->skb_drv_aggQ [i]);
2828 }
2829 priv->rf_set_chan = rtl8192_phy_SwChnl;
2830}
2831
2832//init lock here
2833static void rtl8192_init_priv_lock(struct r8192_priv* priv)
2834{
2835 spin_lock_init(&priv->tx_lock);
2836 spin_lock_init(&priv->irq_lock);//added by thomas
2837 //spin_lock_init(&priv->rf_lock);
2838 sema_init(&priv->wx_sem,1);
2839 sema_init(&priv->rf_sem,1);
8fc8598e 2840 mutex_init(&priv->mutex);
8fc8598e
JC
2841}
2842
8fc8598e 2843extern void rtl819x_watchdog_wqcallback(struct work_struct *work);
8fc8598e
JC
2844
2845void rtl8192_irq_rx_tasklet(struct r8192_priv *priv);
2846//init tasklet and wait_queue here. only 2.6 above kernel is considered
2847#define DRV_NAME "wlan0"
2848static void rtl8192_init_priv_task(struct net_device* dev)
2849{
2850 struct r8192_priv *priv = ieee80211_priv(dev);
2851
8fc8598e 2852 priv->priv_wq = create_workqueue(DRV_NAME);
8fc8598e 2853
8fc8598e
JC
2854 INIT_WORK(&priv->reset_wq, rtl8192_restart);
2855
2856 //INIT_DELAYED_WORK(&priv->watch_dog_wq, hal_dm_watchdog);
2857 INIT_DELAYED_WORK(&priv->watch_dog_wq, rtl819x_watchdog_wqcallback);
2858 INIT_DELAYED_WORK(&priv->txpower_tracking_wq, dm_txpower_trackingcallback);
2859// INIT_DELAYED_WORK(&priv->gpio_change_rf_wq, dm_gpio_change_rf_callback);
2860 INIT_DELAYED_WORK(&priv->rfpath_check_wq, dm_rf_pathcheck_workitemcallback);
2861 INIT_DELAYED_WORK(&priv->update_beacon_wq, rtl8192_update_beacon);
2862 INIT_DELAYED_WORK(&priv->initialgain_operate_wq, InitialGainOperateWorkItemCallBack);
2863 //INIT_WORK(&priv->SwChnlWorkItem, rtl8192_SwChnl_WorkItem);
2864 //INIT_WORK(&priv->SetBWModeWorkItem, rtl8192_SetBWModeWorkItem);
2865 INIT_WORK(&priv->qos_activate, rtl8192_qos_activate);
8fc8598e
JC
2866
2867 tasklet_init(&priv->irq_rx_tasklet,
2868 (void(*)(unsigned long))rtl8192_irq_rx_tasklet,
2869 (unsigned long)priv);
2870}
2871
2872static void rtl8192_get_eeprom_size(struct net_device* dev)
2873{
2874 u16 curCR = 0;
2875 struct r8192_priv *priv = ieee80211_priv(dev);
2876 RT_TRACE(COMP_EPROM, "===========>%s()\n", __FUNCTION__);
2877 curCR = read_nic_word_E(dev,EPROM_CMD);
2878 RT_TRACE(COMP_EPROM, "read from Reg EPROM_CMD(%x):%x\n", EPROM_CMD, curCR);
2879 //whether need I consider BIT5?
2880 priv->epromtype = (curCR & Cmd9346CR_9356SEL) ? EPROM_93c56 : EPROM_93c46;
2881 RT_TRACE(COMP_EPROM, "<===========%s(), epromtype:%d\n", __FUNCTION__, priv->epromtype);
2882}
2883
25985edc 2884//used to swap endian. as ntohl & htonl are not necessary to swap endian, so use this instead.
8fc8598e
JC
2885static inline u16 endian_swap(u16* data)
2886{
2887 u16 tmp = *data;
2888 *data = (tmp >> 8) | (tmp << 8);
2889 return *data;
2890}
2891static void rtl8192_read_eeprom_info(struct net_device* dev)
2892{
2893 u16 wEPROM_ID = 0;
2894 u8 bMac_Tmp_Addr[6] = {0x00, 0xe0, 0x4c, 0x00, 0x00, 0x02};
2895 u8 bLoad_From_EEPOM = false;
2896 struct r8192_priv *priv = ieee80211_priv(dev);
2897 u16 tmpValue = 0;
2898 RT_TRACE(COMP_EPROM, "===========>%s()\n", __FUNCTION__);
2899 wEPROM_ID = eprom_read(dev, 0); //first read EEPROM ID out;
2900 RT_TRACE(COMP_EPROM, "EEPROM ID is 0x%x\n", wEPROM_ID);
2901
2902 if (wEPROM_ID != RTL8190_EEPROM_ID)
2903 {
2904 RT_TRACE(COMP_ERR, "EEPROM ID is invalid(is 0x%x(should be 0x%x)\n", wEPROM_ID, RTL8190_EEPROM_ID);
2905 }
2906 else
2907 bLoad_From_EEPOM = true;
2908
2909 if (bLoad_From_EEPOM)
2910 {
2911 tmpValue = eprom_read(dev, (EEPROM_VID>>1));
2912 priv->eeprom_vid = endian_swap(&tmpValue);
2913 priv->eeprom_pid = eprom_read(dev, (EEPROM_PID>>1));
2914 tmpValue = eprom_read(dev, (EEPROM_ChannelPlan>>1));
2915 priv->eeprom_ChannelPlan =((tmpValue&0xff00)>>8);
2916 priv->btxpowerdata_readfromEEPORM = true;
2917 priv->eeprom_CustomerID = eprom_read(dev, (EEPROM_Customer_ID>>1)) >>8;
2918 }
2919 else
2920 {
2921 priv->eeprom_vid = 0;
2922 priv->eeprom_pid = 0;
2923 priv->card_8192_version = VERSION_819xU_B;
2924 priv->eeprom_ChannelPlan = 0;
2925 priv->eeprom_CustomerID = 0;
2926 }
2927 RT_TRACE(COMP_EPROM, "vid:0x%4x, pid:0x%4x, CustomID:0x%2x, ChanPlan:0x%x\n", priv->eeprom_vid, priv->eeprom_pid, priv->eeprom_CustomerID, priv->eeprom_ChannelPlan);
2928 //set channelplan from eeprom
2929 priv->ChannelPlan = priv->eeprom_ChannelPlan;
2930 if (bLoad_From_EEPOM)
2931 {
2932 int i;
2933 for (i=0; i<6; i+=2)
2934 {
2935 u16 tmp = 0;
2936 tmp = eprom_read(dev, (u16)((EEPROM_NODE_ADDRESS_BYTE_0 + i)>>1));
2937 *(u16*)(&dev->dev_addr[i]) = tmp;
2938 }
2939 }
2940 else
2941 {
2942 memcpy(dev->dev_addr, bMac_Tmp_Addr, 6);
2943 //should I set IDR0 here?
2944 }
0ee9f67c 2945 RT_TRACE(COMP_EPROM, "MAC addr:%pM\n", dev->dev_addr);
8fc8598e
JC
2946 priv->rf_type = RTL819X_DEFAULT_RF_TYPE; //default 1T2R
2947 priv->rf_chip = RF_8256;
2948
2949 if (priv->card_8192_version == (u8)VERSION_819xU_A)
2950 {
2951 //read Tx power gain offset of legacy OFDM to HT rate
2952 if (bLoad_From_EEPOM)
2953 priv->EEPROMTxPowerDiff = (eprom_read(dev, (EEPROM_TxPowerDiff>>1))&0xff00) >> 8;
2954 else
2955 priv->EEPROMTxPowerDiff = EEPROM_Default_TxPower;
2956 RT_TRACE(COMP_EPROM, "TxPowerDiff:%d\n", priv->EEPROMTxPowerDiff);
2957 //read ThermalMeter from EEPROM
2958 if (bLoad_From_EEPOM)
2959 priv->EEPROMThermalMeter = (u8)(eprom_read(dev, (EEPROM_ThermalMeter>>1))&0x00ff);
2960 else
2961 priv->EEPROMThermalMeter = EEPROM_Default_ThermalMeter;
2962 RT_TRACE(COMP_EPROM, "ThermalMeter:%d\n", priv->EEPROMThermalMeter);
2963 //vivi, for tx power track
2964 priv->TSSI_13dBm = priv->EEPROMThermalMeter *100;
2965 //read antenna tx power offset of B/C/D to A from EEPROM
2966 if (bLoad_From_EEPOM)
2967 priv->EEPROMPwDiff = (eprom_read(dev, (EEPROM_PwDiff>>1))&0x0f00)>>8;
2968 else
2969 priv->EEPROMPwDiff = EEPROM_Default_PwDiff;
2970 RT_TRACE(COMP_EPROM, "TxPwDiff:%d\n", priv->EEPROMPwDiff);
2971 // Read CrystalCap from EEPROM
2972 if (bLoad_From_EEPOM)
2973 priv->EEPROMCrystalCap = (eprom_read(dev, (EEPROM_CrystalCap>>1))&0x0f);
2974 else
2975 priv->EEPROMCrystalCap = EEPROM_Default_CrystalCap;
2976 RT_TRACE(COMP_EPROM, "CrystalCap = %d\n", priv->EEPROMCrystalCap);
2977 //get per-channel Tx power level
2978 if (bLoad_From_EEPOM)
2979 priv->EEPROM_Def_Ver = (eprom_read(dev, (EEPROM_TxPwIndex_Ver>>1))&0xff00)>>8;
2980 else
2981 priv->EEPROM_Def_Ver = 1;
2982 RT_TRACE(COMP_EPROM, "EEPROM_DEF_VER:%d\n", priv->EEPROM_Def_Ver);
2983 if (priv->EEPROM_Def_Ver == 0) //old eeprom definition
2984 {
2985 int i;
2986 if (bLoad_From_EEPOM)
2987 priv->EEPROMTxPowerLevelCCK = (eprom_read(dev, (EEPROM_TxPwIndex_CCK>>1))&0xff) >> 8;
2988 else
2989 priv->EEPROMTxPowerLevelCCK = 0x10;
2990 RT_TRACE(COMP_EPROM, "CCK Tx Power Levl: 0x%02x\n", priv->EEPROMTxPowerLevelCCK);
2991 for (i=0; i<3; i++)
2992 {
2993 if (bLoad_From_EEPOM)
2994 {
2995 tmpValue = eprom_read(dev, (EEPROM_TxPwIndex_OFDM_24G+i)>>1);
2996 if (((EEPROM_TxPwIndex_OFDM_24G+i) % 2) == 0)
2997 tmpValue = tmpValue & 0x00ff;
2998 else
2999 tmpValue = (tmpValue & 0xff00) >> 8;
3000 }
3001 else
3002 tmpValue = 0x10;
3003 priv->EEPROMTxPowerLevelOFDM24G[i] = (u8) tmpValue;
3004 RT_TRACE(COMP_EPROM, "OFDM 2.4G Tx Power Level, Index %d = 0x%02x\n", i, priv->EEPROMTxPowerLevelCCK);
3005 }
3006 }//end if EEPROM_DEF_VER == 0
3007 else if (priv->EEPROM_Def_Ver == 1)
3008 {
3009 if (bLoad_From_EEPOM)
3010 {
3011 tmpValue = eprom_read(dev, (EEPROM_TxPwIndex_CCK_V1>>1));
3012 tmpValue = (tmpValue & 0xff00) >> 8;
3013 }
3014 else
3015 tmpValue = 0x10;
3016 priv->EEPROMTxPowerLevelCCK_V1[0] = (u8)tmpValue;
3017
3018 if (bLoad_From_EEPOM)
3019 tmpValue = eprom_read(dev, (EEPROM_TxPwIndex_CCK_V1 + 2)>>1);
3020 else
3021 tmpValue = 0x1010;
3022 *((u16*)(&priv->EEPROMTxPowerLevelCCK_V1[1])) = tmpValue;
3023 if (bLoad_From_EEPOM)
3024 tmpValue = eprom_read(dev, (EEPROM_TxPwIndex_OFDM_24G_V1>>1));
3025 else
3026 tmpValue = 0x1010;
3027 *((u16*)(&priv->EEPROMTxPowerLevelOFDM24G[0])) = tmpValue;
3028 if (bLoad_From_EEPOM)
3029 tmpValue = eprom_read(dev, (EEPROM_TxPwIndex_OFDM_24G_V1+2)>>1);
3030 else
3031 tmpValue = 0x10;
3032 priv->EEPROMTxPowerLevelOFDM24G[2] = (u8)tmpValue;
3033 }//endif EEPROM_Def_Ver == 1
3034
3035 //update HAL variables
3036 //
3037 {
3038 int i;
3039 for (i=0; i<14; i++)
3040 {
3041 if (i<=3)
3042 priv->TxPowerLevelOFDM24G[i] = priv->EEPROMTxPowerLevelOFDM24G[0];
3043 else if (i>=4 && i<=9)
3044 priv->TxPowerLevelOFDM24G[i] = priv->EEPROMTxPowerLevelOFDM24G[1];
3045 else
3046 priv->TxPowerLevelOFDM24G[i] = priv->EEPROMTxPowerLevelOFDM24G[2];
3047 }
3048
3049 for (i=0; i<14; i++)
3050 {
3051 if (priv->EEPROM_Def_Ver == 0)
3052 {
3053 if (i<=3)
3054 priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelOFDM24G[0] + (priv->EEPROMTxPowerLevelCCK - priv->EEPROMTxPowerLevelOFDM24G[1]);
3055 else if (i>=4 && i<=9)
3056 priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelCCK;
3057 else
3058 priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelOFDM24G[2] + (priv->EEPROMTxPowerLevelCCK - priv->EEPROMTxPowerLevelOFDM24G[1]);
3059 }
3060 else if (priv->EEPROM_Def_Ver == 1)
3061 {
3062 if (i<=3)
3063 priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelCCK_V1[0];
3064 else if (i>=4 && i<=9)
3065 priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelCCK_V1[1];
3066 else
3067 priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelCCK_V1[2];
3068 }
3069 }
3070 }//end update HAL variables
3071 priv->TxPowerDiff = priv->EEPROMPwDiff;
3072// Antenna B gain offset to antenna A, bit0~3
3073 priv->AntennaTxPwDiff[0] = (priv->EEPROMTxPowerDiff & 0xf);
3074 // Antenna C gain offset to antenna A, bit4~7
3075 priv->AntennaTxPwDiff[1] = ((priv->EEPROMTxPowerDiff & 0xf0)>>4);
3076 // CrystalCap, bit12~15
3077 priv->CrystalCap = priv->EEPROMCrystalCap;
3078 // ThermalMeter, bit0~3 for RFIC1, bit4~7 for RFIC2
3079 // 92U does not enable TX power tracking.
3080 priv->ThermalMeter[0] = priv->EEPROMThermalMeter;
3081 }//end if VersionID == VERSION_819xU_A
3082
3083//added by vivi, for dlink led, 20080416
3084 switch(priv->eeprom_CustomerID)
3085 {
3086 case EEPROM_CID_RUNTOP:
3087 priv->CustomerID = RT_CID_819x_RUNTOP;
3088 break;
3089
3090 case EEPROM_CID_DLINK:
3091 priv->CustomerID = RT_CID_DLINK;
3092 break;
3093
3094 default:
3095 priv->CustomerID = RT_CID_DEFAULT;
3096 break;
3097
3098 }
3099
3100 switch(priv->CustomerID)
3101 {
3102 case RT_CID_819x_RUNTOP:
3103 priv->LedStrategy = SW_LED_MODE2;
3104 break;
3105
e406322b 3106 case RT_CID_DLINK:
8fc8598e
JC
3107 priv->LedStrategy = SW_LED_MODE4;
3108 break;
3109
3110 default:
3111 priv->LedStrategy = SW_LED_MODE0;
3112 break;
3113
3114 }
3115
3116
3117 if(priv->rf_type == RF_1T2R)
3118 {
3119 RT_TRACE(COMP_EPROM, "\n1T2R config\n");
3120 }
3121 else
3122 {
3123 RT_TRACE(COMP_EPROM, "\n2T4R config\n");
3124 }
3125
3126 // 2008/01/16 MH We can only know RF type in the function. So we have to init
3127 // DIG RATR table again.
3128 init_rate_adaptive(dev);
3129 //we need init DIG RATR table here again.
3130
3131 RT_TRACE(COMP_EPROM, "<===========%s()\n", __FUNCTION__);
3132 return;
3133}
3134
3135short rtl8192_get_channel_map(struct net_device * dev)
3136{
3137 struct r8192_priv *priv = ieee80211_priv(dev);
8fc8598e
JC
3138 if(priv->ChannelPlan > COUNTRY_CODE_GLOBAL_DOMAIN){
3139 printk("rtl8180_init:Error channel plan! Set to default.\n");
3140 priv->ChannelPlan= 0;
3141 }
3142 RT_TRACE(COMP_INIT, "Channel plan is %d\n",priv->ChannelPlan);
3143
3144 rtl819x_set_channel_map(priv->ChannelPlan, priv);
8fc8598e
JC
3145 return 0;
3146}
3147
3148short rtl8192_init(struct net_device *dev)
3149{
3150
3151 struct r8192_priv *priv = ieee80211_priv(dev);
3152
3153 memset(&(priv->stats),0,sizeof(struct Stats));
3154 memset(priv->txqueue_to_outpipemap,0,9);
3155#ifdef PIPE12
3156 {
3157 int i=0;
3158 u8 queuetopipe[]={3,2,1,0,4,8,7,6,5};
3159 memcpy(priv->txqueue_to_outpipemap,queuetopipe,9);
3160/* for(i=0;i<9;i++)
3161 printk("%d ",priv->txqueue_to_outpipemap[i]);
3162 printk("\n");*/
3163 }
3164#else
3165 {
3166 u8 queuetopipe[]={3,2,1,0,4,4,0,4,4};
3167 memcpy(priv->txqueue_to_outpipemap,queuetopipe,9);
3168/* for(i=0;i<9;i++)
3169 printk("%d ",priv->txqueue_to_outpipemap[i]);
3170 printk("\n");*/
3171 }
3172#endif
3173 rtl8192_init_priv_variable(dev);
3174 rtl8192_init_priv_lock(priv);
3175 rtl8192_init_priv_task(dev);
3176 rtl8192_get_eeprom_size(dev);
3177 rtl8192_read_eeprom_info(dev);
3178 rtl8192_get_channel_map(dev);
3179 init_hal_dm(dev);
3180 init_timer(&priv->watch_dog_timer);
3181 priv->watch_dog_timer.data = (unsigned long)dev;
3182 priv->watch_dog_timer.function = watch_dog_timer_callback;
3183 if(rtl8192_usb_initendpoints(dev)!=0){
3184 DMESG("Endopoints initialization failed");
3185 return -ENOMEM;
3186 }
3187
3188 //rtl8192_adapter_start(dev);
3189#ifdef DEBUG_EPROM
3190 dump_eprom(dev);
3191#endif
3192 return 0;
3193}
3194
3195/******************************************************************************
3196 *function: This function actually only set RRSR, RATR and BW_OPMODE registers
3197 * not to do all the hw config as its name says
3198 * input: net_device dev
3199 * output: none
3200 * return: none
3201 * notice: This part need to modified according to the rate set we filtered
3202 * ****************************************************************************/
3203void rtl8192_hwconfig(struct net_device* dev)
3204{
3205 u32 regRATR = 0, regRRSR = 0;
3206 u8 regBwOpMode = 0, regTmp = 0;
3207 struct r8192_priv *priv = ieee80211_priv(dev);
3208
3209// Set RRSR, RATR, and BW_OPMODE registers
3210 //
3211 switch(priv->ieee80211->mode)
3212 {
3213 case WIRELESS_MODE_B:
3214 regBwOpMode = BW_OPMODE_20MHZ;
3215 regRATR = RATE_ALL_CCK;
3216 regRRSR = RATE_ALL_CCK;
3217 break;
3218 case WIRELESS_MODE_A:
3219 regBwOpMode = BW_OPMODE_5G |BW_OPMODE_20MHZ;
3220 regRATR = RATE_ALL_OFDM_AG;
3221 regRRSR = RATE_ALL_OFDM_AG;
3222 break;
3223 case WIRELESS_MODE_G:
3224 regBwOpMode = BW_OPMODE_20MHZ;
3225 regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
3226 regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
3227 break;
3228 case WIRELESS_MODE_AUTO:
3229#ifdef TO_DO_LIST
3230 if (Adapter->bInHctTest)
3231 {
3232 regBwOpMode = BW_OPMODE_20MHZ;
3233 regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
3234 regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
3235 }
3236 else
3237#endif
3238 {
3239 regBwOpMode = BW_OPMODE_20MHZ;
3240 regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
3241 regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
3242 }
3243 break;
3244 case WIRELESS_MODE_N_24G:
3245 // It support CCK rate by default.
3246 // CCK rate will be filtered out only when associated AP does not support it.
3247 regBwOpMode = BW_OPMODE_20MHZ;
3248 regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
3249 regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
3250 break;
3251 case WIRELESS_MODE_N_5G:
3252 regBwOpMode = BW_OPMODE_5G;
3253 regRATR = RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
3254 regRRSR = RATE_ALL_OFDM_AG;
3255 break;
3256 }
3257
3258 write_nic_byte(dev, BW_OPMODE, regBwOpMode);
3259 {
3260 u32 ratr_value = 0;
3261 ratr_value = regRATR;
3262 if (priv->rf_type == RF_1T2R)
3263 {
3264 ratr_value &= ~(RATE_ALL_OFDM_2SS);
3265 }
3266 write_nic_dword(dev, RATR0, ratr_value);
3267 write_nic_byte(dev, UFWP, 1);
3268 }
3269 regTmp = read_nic_byte(dev, 0x313);
3270 regRRSR = ((regTmp) << 24) | (regRRSR & 0x00ffffff);
3271 write_nic_dword(dev, RRSR, regRRSR);
3272
3273 //
3274 // Set Retry Limit here
3275 //
3276 write_nic_word(dev, RETRY_LIMIT,
3277 priv->ShortRetryLimit << RETRY_LIMIT_SHORT_SHIFT | \
3278 priv->LongRetryLimit << RETRY_LIMIT_LONG_SHIFT);
3279 // Set Contention Window here
3280
3281 // Set Tx AGC
3282
3283 // Set Tx Antenna including Feedback control
3284
3285 // Set Auto Rate fallback control
3286
3287
3288}
3289
3290
3291//InitializeAdapter and PhyCfg
3292bool rtl8192_adapter_start(struct net_device *dev)
3293{
3294 struct r8192_priv *priv = ieee80211_priv(dev);
3295 u32 dwRegRead = 0;
3296 bool init_status = true;
3297 RT_TRACE(COMP_INIT, "====>%s()\n", __FUNCTION__);
3298 priv->Rf_Mode = RF_OP_By_SW_3wire;
3299 //for ASIC power on sequence
3300 write_nic_byte_E(dev, 0x5f, 0x80);
3301 mdelay(50);
3302 write_nic_byte_E(dev, 0x5f, 0xf0);
3303 write_nic_byte_E(dev, 0x5d, 0x00);
3304 write_nic_byte_E(dev, 0x5e, 0x80);
3305 write_nic_byte(dev, 0x17, 0x37);
3306 mdelay(10);
3307//#ifdef TO_DO_LIST
3308 priv->pFirmware->firmware_status = FW_STATUS_0_INIT;
3309 //config CPUReset Register
3310 //Firmware Reset or not?
3311 dwRegRead = read_nic_dword(dev, CPU_GEN);
3312 if (priv->pFirmware->firmware_status == FW_STATUS_0_INIT)
3313 dwRegRead |= CPU_GEN_SYSTEM_RESET; //do nothing here?
3314 else if (priv->pFirmware->firmware_status == FW_STATUS_5_READY)
3315 dwRegRead |= CPU_GEN_FIRMWARE_RESET;
3316 else
3317 RT_TRACE(COMP_ERR, "ERROR in %s(): undefined firmware state(%d)\n", __FUNCTION__, priv->pFirmware->firmware_status);
3318
3319 write_nic_dword(dev, CPU_GEN, dwRegRead);
3320 //mdelay(30);
3321 //config BB.
3322 rtl8192_BBConfig(dev);
3323
8fc8598e
JC
3324 //Loopback mode or not
3325 priv->LoopbackMode = RTL819xU_NO_LOOPBACK;
3326// priv->LoopbackMode = RTL819xU_MAC_LOOPBACK;
3327
3328 dwRegRead = read_nic_dword(dev, CPU_GEN);
3329 if (priv->LoopbackMode == RTL819xU_NO_LOOPBACK)
3330 dwRegRead = ((dwRegRead & CPU_GEN_NO_LOOPBACK_MSK) | CPU_GEN_NO_LOOPBACK_SET);
3331 else if (priv->LoopbackMode == RTL819xU_MAC_LOOPBACK)
3332 dwRegRead |= CPU_CCK_LOOPBACK;
3333 else
3334 RT_TRACE(COMP_ERR, "Serious error in %s(): wrong loopback mode setting(%d)\n", __FUNCTION__, priv->LoopbackMode);
3335
3336 write_nic_dword(dev, CPU_GEN, dwRegRead);
3337
3338 //after reset cpu, we need wait for a seconds to write in register.
3339 udelay(500);
3340
3341 //xiong add for new bitfile:usb suspend reset pin set to 1. //do we need?
3342 write_nic_byte_E(dev, 0x5f, (read_nic_byte_E(dev, 0x5f)|0x20));
3343
3344 //Set Hardware
3345 rtl8192_hwconfig(dev);
3346
3347 //turn on Tx/Rx
3348 write_nic_byte(dev, CMDR, CR_RE|CR_TE);
3349
3350 //set IDR0 here
3351 write_nic_dword(dev, MAC0, ((u32*)dev->dev_addr)[0]);
3352 write_nic_word(dev, MAC4, ((u16*)(dev->dev_addr + 4))[0]);
3353
3354 //set RCR
3355 write_nic_dword(dev, RCR, priv->ReceiveConfig);
3356
3357 //Initialize Number of Reserved Pages in Firmware Queue
3358 write_nic_dword(dev, RQPN1, NUM_OF_PAGE_IN_FW_QUEUE_BK << RSVD_FW_QUEUE_PAGE_BK_SHIFT |\
3359 NUM_OF_PAGE_IN_FW_QUEUE_BE << RSVD_FW_QUEUE_PAGE_BE_SHIFT | \
3360 NUM_OF_PAGE_IN_FW_QUEUE_VI << RSVD_FW_QUEUE_PAGE_VI_SHIFT | \
3361 NUM_OF_PAGE_IN_FW_QUEUE_VO <<RSVD_FW_QUEUE_PAGE_VO_SHIFT);
3362 write_nic_dword(dev, RQPN2, NUM_OF_PAGE_IN_FW_QUEUE_MGNT << RSVD_FW_QUEUE_PAGE_MGNT_SHIFT |\
3363 NUM_OF_PAGE_IN_FW_QUEUE_CMD << RSVD_FW_QUEUE_PAGE_CMD_SHIFT);
3364 write_nic_dword(dev, RQPN3, APPLIED_RESERVED_QUEUE_IN_FW| \
3365 NUM_OF_PAGE_IN_FW_QUEUE_BCN<<RSVD_FW_QUEUE_PAGE_BCN_SHIFT
3366// | NUM_OF_PAGE_IN_FW_QUEUE_PUB<<RSVD_FW_QUEUE_PAGE_PUB_SHIFT
3367 );
3368 write_nic_dword(dev, RATR0+4*7, (RATE_ALL_OFDM_AG | RATE_ALL_CCK));
3369
3370 //Set AckTimeout
3371 // TODO: (it value is only for FPGA version). need to be changed!!2006.12.18, by Emily
3372 write_nic_byte(dev, ACK_TIMEOUT, 0x30);
3373
3374// RT_TRACE(COMP_INIT, "%s():priv->ResetProgress is %d\n", __FUNCTION__,priv->ResetProgress);
3375 if(priv->ResetProgress == RESET_TYPE_NORESET)
3376 rtl8192_SetWirelessMode(dev, priv->ieee80211->mode);
3377 if(priv->ResetProgress == RESET_TYPE_NORESET){
3378 CamResetAllEntry(dev);
3379 {
3380 u8 SECR_value = 0x0;
3381 SECR_value |= SCR_TxEncEnable;
3382 SECR_value |= SCR_RxDecEnable;
3383 SECR_value |= SCR_NoSKMC;
3384 write_nic_byte(dev, SECR, SECR_value);
3385 }
3386 }
3387
3388 //Beacon related
3389 write_nic_word(dev, ATIMWND, 2);
3390 write_nic_word(dev, BCN_INTERVAL, 100);
3391
3392 {
3393#define DEFAULT_EDCA 0x005e4332
3394 int i;
3395 for (i=0; i<QOS_QUEUE_NUM; i++)
3396 write_nic_dword(dev, WDCAPARA_ADD[i], DEFAULT_EDCA);
3397 }
3398#ifdef USB_RX_AGGREGATION_SUPPORT
3399 //3 For usb rx firmware aggregation control
3400 if(priv->ResetProgress == RESET_TYPE_NORESET)
3401 {
3402 u32 ulValue;
3403 PRT_HIGH_THROUGHPUT pHTInfo = priv->ieee80211->pHTInfo;
3404 ulValue = (pHTInfo->UsbRxFwAggrEn<<24) | (pHTInfo->UsbRxFwAggrPageNum<<16) |
3405 (pHTInfo->UsbRxFwAggrPacketNum<<8) | (pHTInfo->UsbRxFwAggrTimeout);
3406 /*
3407 * If usb rx firmware aggregation is enabled,
3408 * when anyone of three threshold conditions above is reached,
3409 * firmware will send aggregated packet to driver.
3410 */
3411 write_nic_dword(dev, 0x1a8, ulValue);
3412 priv->bCurrentRxAggrEnable = true;
3413 }
3414#endif
3415
3416 rtl8192_phy_configmac(dev);
3417
3418 if (priv->card_8192_version == (u8) VERSION_819xU_A)
3419 {
3420 rtl8192_phy_getTxPower(dev);
3421 rtl8192_phy_setTxPower(dev, priv->chan);
3422 }
3423
3424 //Firmware download
3425 init_status = init_firmware(dev);
3426 if(!init_status)
3427 {
3428 RT_TRACE(COMP_ERR,"ERR!!! %s(): Firmware download is failed\n", __FUNCTION__);
3429 return init_status;
3430 }
3431 RT_TRACE(COMP_INIT, "%s():after firmware download\n", __FUNCTION__);
3432 //
3433#ifdef TO_DO_LIST
3434if(Adapter->ResetProgress == RESET_TYPE_NORESET)
3435 {
3436 if(pMgntInfo->RegRfOff == TRUE)
3437 { // User disable RF via registry.
3438 RT_TRACE((COMP_INIT|COMP_RF), DBG_LOUD, ("InitializeAdapter819xUsb(): Turn off RF for RegRfOff ----------\n"));
3439 MgntActSet_RF_State(Adapter, eRfOff, RF_CHANGE_BY_SW);
589b3d06 3440 // Those action will be discard in MgntActSet_RF_State because of the same state
8fc8598e
JC
3441 for(eRFPath = 0; eRFPath <pHalData->NumTotalRFPath; eRFPath++)
3442 PHY_SetRFReg(Adapter, (RF90_RADIO_PATH_E)eRFPath, 0x4, 0xC00, 0x0);
3443 }
3444 else if(pMgntInfo->RfOffReason > RF_CHANGE_BY_PS)
3445 { // H/W or S/W RF OFF before sleep.
3446 RT_TRACE((COMP_INIT|COMP_RF), DBG_LOUD, ("InitializeAdapter819xUsb(): Turn off RF for RfOffReason(%d) ----------\n", pMgntInfo->RfOffReason));
3447 MgntActSet_RF_State(Adapter, eRfOff, pMgntInfo->RfOffReason);
3448 }
3449 else
3450 {
3451 pHalData->eRFPowerState = eRfOn;
3452 pMgntInfo->RfOffReason = 0;
3453 RT_TRACE((COMP_INIT|COMP_RF), DBG_LOUD, ("InitializeAdapter819xUsb(): RF is on ----------\n"));
3454 }
3455 }
3456 else
3457 {
3458 if(pHalData->eRFPowerState == eRfOff)
3459 {
3460 MgntActSet_RF_State(Adapter, eRfOff, pMgntInfo->RfOffReason);
589b3d06 3461 // Those action will be discard in MgntActSet_RF_State because of the same state
8fc8598e
JC
3462 for(eRFPath = 0; eRFPath <pHalData->NumTotalRFPath; eRFPath++)
3463 PHY_SetRFReg(Adapter, (RF90_RADIO_PATH_E)eRFPath, 0x4, 0xC00, 0x0);
3464 }
3465 }
3466#endif
3467 //config RF.
3468 if(priv->ResetProgress == RESET_TYPE_NORESET){
3469 rtl8192_phy_RFConfig(dev);
3470 RT_TRACE(COMP_INIT, "%s():after phy RF config\n", __FUNCTION__);
3471 }
3472
3473
3474 if(priv->ieee80211->FwRWRF)
3475 // We can force firmware to do RF-R/W
3476 priv->Rf_Mode = RF_OP_By_FW;
3477 else
3478 priv->Rf_Mode = RF_OP_By_SW_3wire;
3479
3480
3481 rtl8192_phy_updateInitGain(dev);
3482 /*--set CCK and OFDM Block "ON"--*/
3483 rtl8192_setBBreg(dev, rFPGA0_RFMOD, bCCKEn, 0x1);
3484 rtl8192_setBBreg(dev, rFPGA0_RFMOD, bOFDMEn, 0x1);
3485
3486 if(priv->ResetProgress == RESET_TYPE_NORESET)
3487 {
3488 //if D or C cut
3489 u8 tmpvalue = read_nic_byte(dev, 0x301);
3490 if(tmpvalue ==0x03)
3491 {
3492 priv->bDcut = TRUE;
3493 RT_TRACE(COMP_POWER_TRACKING, "D-cut\n");
3494 }
3495 else
3496 {
3497 priv->bDcut = FALSE;
3498 RT_TRACE(COMP_POWER_TRACKING, "C-cut\n");
3499 }
3500 dm_initialize_txpower_tracking(dev);
3501
3502 if(priv->bDcut == TRUE)
3503 {
3504 u32 i, TempCCk;
3505 u32 tmpRegA= rtl8192_QueryBBReg(dev,rOFDM0_XATxIQImbalance,bMaskDWord);
3506 // u32 tmpRegC= rtl8192_QueryBBReg(dev,rOFDM0_XCTxIQImbalance,bMaskDWord);
3507 for(i = 0; i<TxBBGainTableLength; i++)
3508 {
3509 if(tmpRegA == priv->txbbgain_table[i].txbbgain_value)
3510 {
3511 priv->rfa_txpowertrackingindex= (u8)i;
3512 priv->rfa_txpowertrackingindex_real= (u8)i;
3513 priv->rfa_txpowertracking_default= priv->rfa_txpowertrackingindex;
3514 break;
3515 }
3516 }
3517
3518 TempCCk = rtl8192_QueryBBReg(dev, rCCK0_TxFilter1, bMaskByte2);
3519
3520 for(i=0 ; i<CCKTxBBGainTableLength ; i++)
3521 {
3522
3523 if(TempCCk == priv->cck_txbbgain_table[i].ccktxbb_valuearray[0])
3524 {
3525 priv->cck_present_attentuation_20Mdefault=(u8) i;
3526 break;
3527 }
3528 }
3529 priv->cck_present_attentuation_40Mdefault= 0;
3530 priv->cck_present_attentuation_difference= 0;
3531 priv->cck_present_attentuation = priv->cck_present_attentuation_20Mdefault;
3532
3533 // pMgntInfo->bTXPowerTracking = FALSE;//TEMPLY DISABLE
3534 }
3535 }
3536 write_nic_byte(dev, 0x87, 0x0);
3537
3538
8fc8598e
JC
3539 return init_status;
3540}
3541
3542/* this configures registers for beacon tx and enables it via
3543 * rtl8192_beacon_tx_enable(). rtl8192_beacon_tx_disable() might
3544 * be used to stop beacon transmission
3545 */
8fc8598e
JC
3546/***************************************************************************
3547 -------------------------------NET STUFF---------------------------
3548***************************************************************************/
3549
3550static struct net_device_stats *rtl8192_stats(struct net_device *dev)
3551{
3552 struct r8192_priv *priv = ieee80211_priv(dev);
3553
3554 return &priv->ieee80211->stats;
3555}
3556
3557bool
3558HalTxCheckStuck819xUsb(
3559 struct net_device *dev
3560 )
3561{
3562 struct r8192_priv *priv = ieee80211_priv(dev);
3563 u16 RegTxCounter = read_nic_word(dev, 0x128);
3564 bool bStuck = FALSE;
3565 RT_TRACE(COMP_RESET,"%s():RegTxCounter is %d,TxCounter is %d\n",__FUNCTION__,RegTxCounter,priv->TxCounter);
3566 if(priv->TxCounter==RegTxCounter)
3567 bStuck = TRUE;
3568
3569 priv->TxCounter = RegTxCounter;
3570
3571 return bStuck;
3572}
3573
3574/*
3575* <Assumption: RT_TX_SPINLOCK is acquired.>
3576* First added: 2006.11.19 by emily
3577*/
3578RESET_TYPE
3579TxCheckStuck(struct net_device *dev)
3580{
3581 struct r8192_priv *priv = ieee80211_priv(dev);
3582 u8 QueueID;
3583// PRT_TCB pTcb;
3584// u8 ResetThreshold;
3585 bool bCheckFwTxCnt = false;
3586 //unsigned long flags;
3587
3588 //
589b3d06 3589 // Decide such threshold according to current power save mode
8fc8598e
JC
3590 //
3591
3592// RT_TRACE(COMP_RESET, " ==> TxCheckStuck()\n");
3593// PlatformAcquireSpinLock(Adapter, RT_TX_SPINLOCK);
3594// spin_lock_irqsave(&priv->ieee80211->lock,flags);
3595 for (QueueID = 0; QueueID<=BEACON_QUEUE;QueueID ++)
3596 {
3597 if(QueueID == TXCMD_QUEUE)
3598 continue;
8fc8598e
JC
3599#ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
3600 if((skb_queue_len(&priv->ieee80211->skb_waitQ[QueueID]) == 0) && (skb_queue_len(&priv->ieee80211->skb_aggQ[QueueID]) == 0) && (skb_queue_len(&priv->ieee80211->skb_drv_aggQ[QueueID]) == 0))
3601#else
3602 if((skb_queue_len(&priv->ieee80211->skb_waitQ[QueueID]) == 0) && (skb_queue_len(&priv->ieee80211->skb_aggQ[QueueID]) == 0))
3603#endif
3604 continue;
8fc8598e
JC
3605
3606 bCheckFwTxCnt = true;
3607 }
3608// PlatformReleaseSpinLock(Adapter, RT_TX_SPINLOCK);
3609// spin_unlock_irqrestore(&priv->ieee80211->lock,flags);
3610// RT_TRACE(COMP_RESET,"bCheckFwTxCnt is %d\n",bCheckFwTxCnt);
8fc8598e
JC
3611 if(bCheckFwTxCnt)
3612 {
3613 if(HalTxCheckStuck819xUsb(dev))
3614 {
3615 RT_TRACE(COMP_RESET, "TxCheckStuck(): Fw indicates no Tx condition! \n");
3616 return RESET_TYPE_SILENT;
3617 }
3618 }
8fc8598e
JC
3619 return RESET_TYPE_NORESET;
3620}
3621
3622bool
3623HalRxCheckStuck819xUsb(struct net_device *dev)
3624{
3625 u16 RegRxCounter = read_nic_word(dev, 0x130);
3626 struct r8192_priv *priv = ieee80211_priv(dev);
3627 bool bStuck = FALSE;
3628 static u8 rx_chk_cnt = 0;
3629 RT_TRACE(COMP_RESET,"%s(): RegRxCounter is %d,RxCounter is %d\n",__FUNCTION__,RegRxCounter,priv->RxCounter);
3630 // If rssi is small, we should check rx for long time because of bad rx.
3631 // or maybe it will continuous silent reset every 2 seconds.
3632 rx_chk_cnt++;
3633 if(priv->undecorated_smoothed_pwdb >= (RateAdaptiveTH_High+5))
3634 {
3635 rx_chk_cnt = 0; //high rssi, check rx stuck right now.
3636 }
3637 else if(priv->undecorated_smoothed_pwdb < (RateAdaptiveTH_High+5) &&
3638 ((priv->CurrentChannelBW!=HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb>=RateAdaptiveTH_Low_40M) ||
3639 (priv->CurrentChannelBW==HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb>=RateAdaptiveTH_Low_20M)) )
3640 {
3641 if(rx_chk_cnt < 2)
3642 {
3643 return bStuck;
3644 }
3645 else
3646 {
3647 rx_chk_cnt = 0;
3648 }
3649 }
3650 else if(((priv->CurrentChannelBW!=HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb<RateAdaptiveTH_Low_40M) ||
3651 (priv->CurrentChannelBW==HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb<RateAdaptiveTH_Low_20M)) &&
3652 priv->undecorated_smoothed_pwdb >= VeryLowRSSI)
3653 {
3654 if(rx_chk_cnt < 4)
3655 {
3656 //DbgPrint("RSSI < %d && RSSI >= %d, no check this time \n", RateAdaptiveTH_Low, VeryLowRSSI);
3657 return bStuck;
3658 }
3659 else
3660 {
3661 rx_chk_cnt = 0;
3662 //DbgPrint("RSSI < %d && RSSI >= %d, check this time \n", RateAdaptiveTH_Low, VeryLowRSSI);
3663 }
3664 }
3665 else
3666 {
3667 if(rx_chk_cnt < 8)
3668 {
3669 //DbgPrint("RSSI <= %d, no check this time \n", VeryLowRSSI);
3670 return bStuck;
3671 }
3672 else
3673 {
3674 rx_chk_cnt = 0;
3675 //DbgPrint("RSSI <= %d, check this time \n", VeryLowRSSI);
3676 }
3677 }
3678
3679 if(priv->RxCounter==RegRxCounter)
3680 bStuck = TRUE;
3681
3682 priv->RxCounter = RegRxCounter;
3683
3684 return bStuck;
3685}
3686
3687RESET_TYPE
3688RxCheckStuck(struct net_device *dev)
3689{
3690 struct r8192_priv *priv = ieee80211_priv(dev);
3691 //int i;
3692 bool bRxCheck = FALSE;
3693
3694// RT_TRACE(COMP_RESET," ==> RxCheckStuck()\n");
3695 //PlatformAcquireSpinLock(Adapter, RT_RX_SPINLOCK);
3696
3697 if(priv->IrpPendingCount > 1)
e406322b 3698 bRxCheck = TRUE;
8fc8598e
JC
3699 //PlatformReleaseSpinLock(Adapter, RT_RX_SPINLOCK);
3700
3701// RT_TRACE(COMP_RESET,"bRxCheck is %d \n",bRxCheck);
3702 if(bRxCheck)
3703 {
3704 if(HalRxCheckStuck819xUsb(dev))
3705 {
3706 RT_TRACE(COMP_RESET, "RxStuck Condition\n");
3707 return RESET_TYPE_SILENT;
3708 }
3709 }
3710 return RESET_TYPE_NORESET;
3711}
3712
3713
3714/**
3715* This function is called by Checkforhang to check whether we should ask OS to reset driver
3716*
3717* \param pAdapter The adapter context for this miniport
3718*
3719* Note:NIC with USB interface sholud not call this function because we cannot scan descriptor
3720* to judge whether there is tx stuck.
3721* Note: This function may be required to be rewrite for Vista OS.
3722* <<<Assumption: Tx spinlock has been acquired >>>
3723*
3724* 8185 and 8185b does not implement this function. This is added by Emily at 2006.11.24
3725*/
3726RESET_TYPE
3727rtl819x_ifcheck_resetornot(struct net_device *dev)
3728{
3729 struct r8192_priv *priv = ieee80211_priv(dev);
3730 RESET_TYPE TxResetType = RESET_TYPE_NORESET;
3731 RESET_TYPE RxResetType = RESET_TYPE_NORESET;
3732 RT_RF_POWER_STATE rfState;
3733
3734 rfState = priv->ieee80211->eRFPowerState;
3735
3736 TxResetType = TxCheckStuck(dev);
8fc8598e
JC
3737 if( rfState != eRfOff ||
3738 /*ADAPTER_TEST_STATUS_FLAG(Adapter, ADAPTER_STATUS_FW_DOWNLOAD_FAILURE)) &&*/
3739 (priv->ieee80211->iw_mode != IW_MODE_ADHOC))
3740 {
3741 // If driver is in the status of firmware download failure , driver skips RF initialization and RF is
3742 // in turned off state. Driver should check whether Rx stuck and do silent reset. And
3743 // if driver is in firmware download failure status, driver should initialize RF in the following
3744 // silent reset procedure Emily, 2008.01.21
3745
3746 // Driver should not check RX stuck in IBSS mode because it is required to
3747 // set Check BSSID in order to send beacon, however, if check BSSID is
589b3d06 3748 // set, STA cannot hear any packet at all. Emily, 2008.04.12
8fc8598e
JC
3749 RxResetType = RxCheckStuck(dev);
3750 }
8fc8598e
JC
3751 if(TxResetType==RESET_TYPE_NORMAL || RxResetType==RESET_TYPE_NORMAL)
3752 return RESET_TYPE_NORMAL;
3753 else if(TxResetType==RESET_TYPE_SILENT || RxResetType==RESET_TYPE_SILENT){
3754 RT_TRACE(COMP_RESET,"%s():silent reset\n",__FUNCTION__);
3755 return RESET_TYPE_SILENT;
3756 }
3757 else
3758 return RESET_TYPE_NORESET;
3759
3760}
3761
3762void rtl8192_cancel_deferred_work(struct r8192_priv* priv);
3763int _rtl8192_up(struct net_device *dev);
3764int rtl8192_close(struct net_device *dev);
3765
3766
3767
3768void
3769CamRestoreAllEntry( struct net_device *dev)
3770{
3771 u8 EntryId = 0;
3772 struct r8192_priv *priv = ieee80211_priv(dev);
3773 u8* MacAddr = priv->ieee80211->current_network.bssid;
3774
3775 static u8 CAM_CONST_ADDR[4][6] = {
3776 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
3777 {0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
3778 {0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
3779 {0x00, 0x00, 0x00, 0x00, 0x00, 0x03}};
3780 static u8 CAM_CONST_BROAD[] =
3781 {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
3782
3783 RT_TRACE(COMP_SEC, "CamRestoreAllEntry: \n");
3784
3785
3786 if ((priv->ieee80211->pairwise_key_type == KEY_TYPE_WEP40)||
3787 (priv->ieee80211->pairwise_key_type == KEY_TYPE_WEP104))
3788 {
3789
3790 for(EntryId=0; EntryId<4; EntryId++)
3791 {
3792 {
3793 MacAddr = CAM_CONST_ADDR[EntryId];
3794 setKey(dev,
3795 EntryId ,
3796 EntryId,
3797 priv->ieee80211->pairwise_key_type,
3798 MacAddr,
3799 0,
3800 NULL);
3801 }
3802 }
3803
3804 }
3805 else if(priv->ieee80211->pairwise_key_type == KEY_TYPE_TKIP)
3806 {
3807
3808 {
3809 if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
3810 setKey(dev,
3811 4,
3812 0,
3813 priv->ieee80211->pairwise_key_type,
3814 (u8*)dev->dev_addr,
3815 0,
3816 NULL);
3817 else
3818 setKey(dev,
3819 4,
3820 0,
3821 priv->ieee80211->pairwise_key_type,
3822 MacAddr,
3823 0,
3824 NULL);
3825 }
3826 }
3827 else if(priv->ieee80211->pairwise_key_type == KEY_TYPE_CCMP)
3828 {
3829
3830 {
3831 if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
3832 setKey(dev,
3833 4,
3834 0,
3835 priv->ieee80211->pairwise_key_type,
3836 (u8*)dev->dev_addr,
3837 0,
3838 NULL);
3839 else
3840 setKey(dev,
3841 4,
3842 0,
3843 priv->ieee80211->pairwise_key_type,
3844 MacAddr,
3845 0,
3846 NULL);
3847 }
3848 }
3849
3850
3851
3852 if(priv->ieee80211->group_key_type == KEY_TYPE_TKIP)
3853 {
3854 MacAddr = CAM_CONST_BROAD;
3855 for(EntryId=1 ; EntryId<4 ; EntryId++)
3856 {
3857 {
3858 setKey(dev,
3859 EntryId,
3860 EntryId,
3861 priv->ieee80211->group_key_type,
3862 MacAddr,
3863 0,
3864 NULL);
3865 }
3866 }
3867 if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
3868 setKey(dev,
3869 0,
3870 0,
3871 priv->ieee80211->group_key_type,
3872 CAM_CONST_ADDR[0],
3873 0,
3874 NULL);
3875 }
3876 else if(priv->ieee80211->group_key_type == KEY_TYPE_CCMP)
3877 {
3878 MacAddr = CAM_CONST_BROAD;
3879 for(EntryId=1; EntryId<4 ; EntryId++)
3880 {
3881 {
3882 setKey(dev,
3883 EntryId ,
3884 EntryId,
3885 priv->ieee80211->group_key_type,
3886 MacAddr,
3887 0,
3888 NULL);
3889 }
3890 }
3891
3892 if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
3893 setKey(dev,
3894 0 ,
3895 0,
3896 priv->ieee80211->group_key_type,
3897 CAM_CONST_ADDR[0],
3898 0,
3899 NULL);
3900 }
3901}
3902//////////////////////////////////////////////////////////////
3903// This function is used to fix Tx/Rx stop bug temporarily.
3904// This function will do "system reset" to NIC when Tx or Rx is stuck.
3905// The method checking Tx/Rx stuck of this function is supported by FW,
3906// which reports Tx and Rx counter to register 0x128 and 0x130.
3907//////////////////////////////////////////////////////////////
3908void
3909rtl819x_ifsilentreset(struct net_device *dev)
3910{
3911 //OCTET_STRING asocpdu;
3912 struct r8192_priv *priv = ieee80211_priv(dev);
3913 u8 reset_times = 0;
3914 int reset_status = 0;
3915 struct ieee80211_device *ieee = priv->ieee80211;
3916
3917
3918 // 2007.07.20. If we need to check CCK stop, please uncomment this line.
3919 //bStuck = Adapter->HalFunc.CheckHWStopHandler(Adapter);
3920
3921 if(priv->ResetProgress==RESET_TYPE_NORESET)
3922 {
3923RESET_START:
3924
3925 RT_TRACE(COMP_RESET,"=========>Reset progress!! \n");
3926
3927 // Set the variable for reset.
3928 priv->ResetProgress = RESET_TYPE_SILENT;
3929// rtl8192_close(dev);
8fc8598e
JC
3930 down(&priv->wx_sem);
3931 if(priv->up == 0)
3932 {
3933 RT_TRACE(COMP_ERR,"%s():the driver is not up! return\n",__FUNCTION__);
3934 up(&priv->wx_sem);
3935 return ;
3936 }
3937 priv->up = 0;
3938 RT_TRACE(COMP_RESET,"%s():======>start to down the driver\n",__FUNCTION__);
3939// if(!netif_queue_stopped(dev))
3940// netif_stop_queue(dev);
3941
3942 rtl8192_rtx_disable(dev);
3943 rtl8192_cancel_deferred_work(priv);
3944 deinit_hal_dm(dev);
3945 del_timer_sync(&priv->watch_dog_timer);
3946
3947 ieee->sync_scan_hurryup = 1;
3948 if(ieee->state == IEEE80211_LINKED)
3949 {
3950 down(&ieee->wx_sem);
3951 printk("ieee->state is IEEE80211_LINKED\n");
3952 ieee80211_stop_send_beacons(priv->ieee80211);
3953 del_timer_sync(&ieee->associate_timer);
8fc8598e 3954 cancel_delayed_work(&ieee->associate_retry_wq);
8fc8598e
JC
3955 ieee80211_stop_scan(ieee);
3956 netif_carrier_off(dev);
3957 up(&ieee->wx_sem);
3958 }
3959 else{
3960 printk("ieee->state is NOT LINKED\n");
3961 ieee80211_softmac_stop_protocol(priv->ieee80211); }
3962 up(&priv->wx_sem);
3963 RT_TRACE(COMP_RESET,"%s():<==========down process is finished\n",__FUNCTION__);
3964 //rtl8192_irq_disable(dev);
589b3d06 3965 RT_TRACE(COMP_RESET,"%s():===========>start up the driver\n",__FUNCTION__);
8fc8598e
JC
3966 reset_status = _rtl8192_up(dev);
3967
3968 RT_TRACE(COMP_RESET,"%s():<===========up process is finished\n",__FUNCTION__);
3969 if(reset_status == -EAGAIN)
3970 {
3971 if(reset_times < 3)
3972 {
3973 reset_times++;
3974 goto RESET_START;
3975 }
3976 else
3977 {
3978 RT_TRACE(COMP_ERR," ERR!!! %s(): Reset Failed!!\n", __FUNCTION__);
3979 }
3980 }
8fc8598e 3981 ieee->is_silent_reset = 1;
8fc8598e 3982 EnableHWSecurityConfig8192(dev);
8fc8598e
JC
3983 if(ieee->state == IEEE80211_LINKED && ieee->iw_mode == IW_MODE_INFRA)
3984 {
3985 ieee->set_chan(ieee->dev, ieee->current_network.channel);
3986
8fc8598e 3987 queue_work(ieee->wq, &ieee->associate_complete_wq);
8fc8598e
JC
3988
3989 }
3990 else if(ieee->state == IEEE80211_LINKED && ieee->iw_mode == IW_MODE_ADHOC)
3991 {
3992 ieee->set_chan(ieee->dev, ieee->current_network.channel);
3993 ieee->link_change(ieee->dev);
3994
3995 // notify_wx_assoc_event(ieee);
3996
3997 ieee80211_start_send_beacons(ieee);
3998
3999 if (ieee->data_hard_resume)
4000 ieee->data_hard_resume(ieee->dev);
4001 netif_carrier_on(ieee->dev);
4002 }
8fc8598e
JC
4003
4004 CamRestoreAllEntry(dev);
4005
4006 priv->ResetProgress = RESET_TYPE_NORESET;
4007 priv->reset_count++;
4008
4009 priv->bForcedSilentReset =false;
4010 priv->bResetInProgress = false;
4011
4012 // For test --> force write UFWP.
4013 write_nic_byte(dev, UFWP, 1);
4014 RT_TRACE(COMP_RESET, "Reset finished!! ====>[%d]\n", priv->reset_count);
8fc8598e
JC
4015 }
4016}
4017
4018void CAM_read_entry(
4019 struct net_device *dev,
4020 u32 iIndex
4021)
4022{
4023 u32 target_command=0;
4024 u32 target_content=0;
4025 u8 entry_i=0;
4026 u32 ulStatus;
4027 s32 i=100;
4028// printk("=======>start read CAM\n");
4029 for(entry_i=0;entry_i<CAM_CONTENT_COUNT;entry_i++)
4030 {
4031 // polling bit, and No Write enable, and address
4032 target_command= entry_i+CAM_CONTENT_COUNT*iIndex;
4033 target_command= target_command | BIT31;
4034
4035 //Check polling bit is clear
4036// mdelay(1);
8fc8598e
JC
4037 while((i--)>=0)
4038 {
4039 ulStatus = read_nic_dword(dev, RWCAM);
4040 if(ulStatus & BIT31){
4041 continue;
4042 }
4043 else{
4044 break;
4045 }
4046 }
e406322b
MCC
4047 write_nic_dword(dev, RWCAM, target_command);
4048 RT_TRACE(COMP_SEC,"CAM_read_entry(): WRITE A0: %x \n",target_command);
4049 // printk("CAM_read_entry(): WRITE A0: %lx \n",target_command);
4050 target_content = read_nic_dword(dev, RCAMO);
4051 RT_TRACE(COMP_SEC, "CAM_read_entry(): WRITE A8: %x \n",target_content);
4052 // printk("CAM_read_entry(): WRITE A8: %lx \n",target_content);
4053 }
8fc8598e
JC
4054 printk("\n");
4055}
4056
4057void rtl819x_update_rxcounts(
4058 struct r8192_priv *priv,
4059 u32* TotalRxBcnNum,
4060 u32* TotalRxDataNum
4061)
4062{
4063 u16 SlotIndex;
4064 u8 i;
4065
4066 *TotalRxBcnNum = 0;
4067 *TotalRxDataNum = 0;
4068
4069 SlotIndex = (priv->ieee80211->LinkDetectInfo.SlotIndex++)%(priv->ieee80211->LinkDetectInfo.SlotNum);
4070 priv->ieee80211->LinkDetectInfo.RxBcnNum[SlotIndex] = priv->ieee80211->LinkDetectInfo.NumRecvBcnInPeriod;
4071 priv->ieee80211->LinkDetectInfo.RxDataNum[SlotIndex] = priv->ieee80211->LinkDetectInfo.NumRecvDataInPeriod;
4072 for( i=0; i<priv->ieee80211->LinkDetectInfo.SlotNum; i++ ){
4073 *TotalRxBcnNum += priv->ieee80211->LinkDetectInfo.RxBcnNum[i];
4074 *TotalRxDataNum += priv->ieee80211->LinkDetectInfo.RxDataNum[i];
4075 }
4076}
4077
4078
8fc8598e
JC
4079extern void rtl819x_watchdog_wqcallback(struct work_struct *work)
4080{
4081 struct delayed_work *dwork = container_of(work,struct delayed_work,work);
4082 struct r8192_priv *priv = container_of(dwork,struct r8192_priv,watch_dog_wq);
4083 struct net_device *dev = priv->ieee80211->dev;
8fc8598e
JC
4084 struct ieee80211_device* ieee = priv->ieee80211;
4085 RESET_TYPE ResetType = RESET_TYPE_NORESET;
e406322b 4086 static u8 check_reset_cnt=0;
8fc8598e
JC
4087 bool bBusyTraffic = false;
4088
4089 if(!priv->up)
4090 return;
4091 hal_dm_watchdog(dev);
4092
4093 {//to get busy traffic condition
4094 if(ieee->state == IEEE80211_LINKED)
4095 {
4096 if( ieee->LinkDetectInfo.NumRxOkInPeriod> 666 ||
4097 ieee->LinkDetectInfo.NumTxOkInPeriod> 666 ) {
4098 bBusyTraffic = true;
4099 }
4100 ieee->LinkDetectInfo.NumRxOkInPeriod = 0;
4101 ieee->LinkDetectInfo.NumTxOkInPeriod = 0;
4102 ieee->LinkDetectInfo.bBusyTraffic = bBusyTraffic;
4103 }
4104 }
4105 //added by amy for AP roaming
4106 {
4107 if(priv->ieee80211->state == IEEE80211_LINKED && priv->ieee80211->iw_mode == IW_MODE_INFRA)
4108 {
4109 u32 TotalRxBcnNum = 0;
4110 u32 TotalRxDataNum = 0;
4111
4112 rtl819x_update_rxcounts(priv, &TotalRxBcnNum, &TotalRxDataNum);
4113 if((TotalRxBcnNum+TotalRxDataNum) == 0)
4114 {
4115 #ifdef TODO
4116 if(rfState == eRfOff)
4117 RT_TRACE(COMP_ERR,"========>%s()\n",__FUNCTION__);
4118 #endif
4119 printk("===>%s(): AP is power off,connect another one\n",__FUNCTION__);
4120 // Dot11d_Reset(dev);
4121 priv->ieee80211->state = IEEE80211_ASSOCIATING;
4122 notify_wx_assoc_event(priv->ieee80211);
4123 RemovePeerTS(priv->ieee80211,priv->ieee80211->current_network.bssid);
4124 priv->ieee80211->link_change(dev);
8fc8598e 4125 queue_work(priv->ieee80211->wq, &priv->ieee80211->associate_procedure_wq);
8fc8598e
JC
4126
4127 }
4128 }
4129 priv->ieee80211->LinkDetectInfo.NumRecvBcnInPeriod=0;
4130 priv->ieee80211->LinkDetectInfo.NumRecvDataInPeriod=0;
4131 }
4132// CAM_read_entry(dev,4);
4133 //check if reset the driver
4134 if(check_reset_cnt++ >= 3)
4135 {
4136 ResetType = rtl819x_ifcheck_resetornot(dev);
4137 check_reset_cnt = 3;
4138 //DbgPrint("Start to check silent reset\n");
4139 }
4140 // 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);
8fc8598e
JC
4141 if( (priv->force_reset) || (priv->ResetProgress==RESET_TYPE_NORESET &&
4142 (priv->bForcedSilentReset ||
4143 (!priv->bDisableNormalResetCheck && ResetType==RESET_TYPE_SILENT)))) // This is control by OID set in Pomelo
4144 {
4145 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);
4146 rtl819x_ifsilentreset(dev);
4147 }
8fc8598e
JC
4148 priv->force_reset = false;
4149 priv->bForcedSilentReset = false;
4150 priv->bResetInProgress = false;
4151 RT_TRACE(COMP_TRACE, " <==RtUsbCheckForHangWorkItemCallback()\n");
4152
4153}
4154
4155void watch_dog_timer_callback(unsigned long data)
4156{
4157 struct r8192_priv *priv = ieee80211_priv((struct net_device *) data);
589b3d06 4158 //printk("===============>watch_dog timer\n");
8fc8598e 4159 queue_delayed_work(priv->priv_wq,&priv->watch_dog_wq, 0);
8fc8598e 4160 mod_timer(&priv->watch_dog_timer, jiffies + MSECS(IEEE80211_WATCH_DOG_TIME));
8fc8598e
JC
4161}
4162int _rtl8192_up(struct net_device *dev)
4163{
4164 struct r8192_priv *priv = ieee80211_priv(dev);
4165 //int i;
4166 int init_status = 0;
4167 priv->up=1;
4168 priv->ieee80211->ieee_up=1;
4169 RT_TRACE(COMP_INIT, "Bringing up iface");
4170 init_status = rtl8192_adapter_start(dev);
4171 if(!init_status)
4172 {
589b3d06 4173 RT_TRACE(COMP_ERR,"ERR!!! %s(): initialization failed!\n", __FUNCTION__);
8fc8598e
JC
4174 priv->up=priv->ieee80211->ieee_up = 0;
4175 return -EAGAIN;
4176 }
4177 RT_TRACE(COMP_INIT, "start adapter finished\n");
4178 rtl8192_rx_enable(dev);
4179// rtl8192_tx_enable(dev);
4180 if(priv->ieee80211->state != IEEE80211_LINKED)
4181 ieee80211_softmac_start_protocol(priv->ieee80211);
4182 ieee80211_reset_queue(priv->ieee80211);
4183 watch_dog_timer_callback((unsigned long) dev);
4184 if(!netif_queue_stopped(dev))
4185 netif_start_queue(dev);
4186 else
4187 netif_wake_queue(dev);
4188
4189 return 0;
4190}
4191
4192
4193int rtl8192_open(struct net_device *dev)
4194{
4195 struct r8192_priv *priv = ieee80211_priv(dev);
4196 int ret;
4197 down(&priv->wx_sem);
4198 ret = rtl8192_up(dev);
4199 up(&priv->wx_sem);
4200 return ret;
4201
4202}
4203
4204
4205int rtl8192_up(struct net_device *dev)
4206{
4207 struct r8192_priv *priv = ieee80211_priv(dev);
4208
4209 if (priv->up == 1) return -1;
4210
4211 return _rtl8192_up(dev);
4212}
4213
4214
4215int rtl8192_close(struct net_device *dev)
4216{
4217 struct r8192_priv *priv = ieee80211_priv(dev);
4218 int ret;
4219
4220 down(&priv->wx_sem);
4221
4222 ret = rtl8192_down(dev);
4223
4224 up(&priv->wx_sem);
4225
4226 return ret;
4227
4228}
4229
4230int rtl8192_down(struct net_device *dev)
4231{
4232 struct r8192_priv *priv = ieee80211_priv(dev);
4233 int i;
4234
4235 if (priv->up == 0) return -1;
4236
4237 priv->up=0;
4238 priv->ieee80211->ieee_up = 0;
4239 RT_TRACE(COMP_DOWN, "==========>%s()\n", __FUNCTION__);
4240/* FIXME */
4241 if (!netif_queue_stopped(dev))
4242 netif_stop_queue(dev);
4243
4244 rtl8192_rtx_disable(dev);
4245 //rtl8192_irq_disable(dev);
4246
4247 /* Tx related queue release */
e406322b
MCC
4248 for(i = 0; i < MAX_QUEUE_SIZE; i++) {
4249 skb_queue_purge(&priv->ieee80211->skb_waitQ [i]);
4250 }
4251 for(i = 0; i < MAX_QUEUE_SIZE; i++) {
4252 skb_queue_purge(&priv->ieee80211->skb_aggQ [i]);
4253 }
8fc8598e 4254
e406322b
MCC
4255 for(i = 0; i < MAX_QUEUE_SIZE; i++) {
4256 skb_queue_purge(&priv->ieee80211->skb_drv_aggQ [i]);
4257 }
8fc8598e 4258
589b3d06 4259 //as cancel_delayed_work will del work->timer, so if work is not defined as struct delayed_work, it will corrupt
8fc8598e
JC
4260// flush_scheduled_work();
4261 rtl8192_cancel_deferred_work(priv);
4262 deinit_hal_dm(dev);
4263 del_timer_sync(&priv->watch_dog_timer);
4264
4265
4266 ieee80211_softmac_stop_protocol(priv->ieee80211);
4267 memset(&priv->ieee80211->current_network, 0 , offsetof(struct ieee80211_network, list));
4268 RT_TRACE(COMP_DOWN, "<==========%s()\n", __FUNCTION__);
4269
4270 return 0;
4271}
4272
4273
4274void rtl8192_commit(struct net_device *dev)
4275{
4276 struct r8192_priv *priv = ieee80211_priv(dev);
4277 int reset_status = 0;
4278 //u8 reset_times = 0;
4279 if (priv->up == 0) return ;
4280 priv->up = 0;
4281
4282 rtl8192_cancel_deferred_work(priv);
4283 del_timer_sync(&priv->watch_dog_timer);
4284 //cancel_delayed_work(&priv->SwChnlWorkItem);
4285
4286 ieee80211_softmac_stop_protocol(priv->ieee80211);
4287
4288 //rtl8192_irq_disable(dev);
4289 rtl8192_rtx_disable(dev);
4290 reset_status = _rtl8192_up(dev);
4291
4292}
4293
4294/*
4295void rtl8192_restart(struct net_device *dev)
4296{
4297 struct r8192_priv *priv = ieee80211_priv(dev);
4298*/
8fc8598e
JC
4299void rtl8192_restart(struct work_struct *work)
4300{
e406322b
MCC
4301 struct r8192_priv *priv = container_of(work, struct r8192_priv, reset_wq);
4302 struct net_device *dev = priv->ieee80211->dev;
8fc8598e
JC
4303
4304 down(&priv->wx_sem);
4305
4306 rtl8192_commit(dev);
4307
4308 up(&priv->wx_sem);
4309}
4310
4311static void r8192_set_multicast(struct net_device *dev)
4312{
4313 struct r8192_priv *priv = ieee80211_priv(dev);
4314 short promisc;
4315
4316 //down(&priv->wx_sem);
4317
4318 /* FIXME FIXME */
4319
4320 promisc = (dev->flags & IFF_PROMISC) ? 1:0;
4321
4322 if (promisc != priv->promisc)
4323 // rtl8192_commit(dev);
4324
4325 priv->promisc = promisc;
4326
4327 //schedule_work(&priv->reset_wq);
4328 //up(&priv->wx_sem);
4329}
4330
4331
4332int r8192_set_mac_adr(struct net_device *dev, void *mac)
4333{
4334 struct r8192_priv *priv = ieee80211_priv(dev);
4335 struct sockaddr *addr = mac;
4336
4337 down(&priv->wx_sem);
4338
4339 memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
4340
8fc8598e 4341 schedule_work(&priv->reset_wq);
8fc8598e
JC
4342 up(&priv->wx_sem);
4343
4344 return 0;
4345}
4346
4347/* based on ipw2200 driver */
4348int rtl8192_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
4349{
4350 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
4351 struct iwreq *wrq = (struct iwreq *)rq;
4352 int ret=-1;
4353 struct ieee80211_device *ieee = priv->ieee80211;
4354 u32 key[4];
4355 u8 broadcast_addr[6] = {0xff,0xff,0xff,0xff,0xff,0xff};
4356 struct iw_point *p = &wrq->u.data;
4357 struct ieee_param *ipw = NULL;//(struct ieee_param *)wrq->u.data.pointer;
4358
4359 down(&priv->wx_sem);
4360
4361
4362 if (p->length < sizeof(struct ieee_param) || !p->pointer){
e406322b
MCC
4363 ret = -EINVAL;
4364 goto out;
8fc8598e
JC
4365 }
4366
32414878 4367 ipw = kmalloc(p->length, GFP_KERNEL);
8fc8598e 4368 if (ipw == NULL){
e406322b
MCC
4369 ret = -ENOMEM;
4370 goto out;
8fc8598e
JC
4371 }
4372 if (copy_from_user(ipw, p->pointer, p->length)) {
4373 kfree(ipw);
e406322b
MCC
4374 ret = -EFAULT;
4375 goto out;
8fc8598e
JC
4376 }
4377
4378 switch (cmd) {
4379 case RTL_IOCTL_WPA_SUPPLICANT:
4380 //parse here for HW security
4381 if (ipw->cmd == IEEE_CMD_SET_ENCRYPTION)
4382 {
4383 if (ipw->u.crypt.set_tx)
4384 {
4385 if (strcmp(ipw->u.crypt.alg, "CCMP") == 0)
4386 ieee->pairwise_key_type = KEY_TYPE_CCMP;
4387 else if (strcmp(ipw->u.crypt.alg, "TKIP") == 0)
4388 ieee->pairwise_key_type = KEY_TYPE_TKIP;
4389 else if (strcmp(ipw->u.crypt.alg, "WEP") == 0)
4390 {
4391 if (ipw->u.crypt.key_len == 13)
4392 ieee->pairwise_key_type = KEY_TYPE_WEP104;
4393 else if (ipw->u.crypt.key_len == 5)
4394 ieee->pairwise_key_type = KEY_TYPE_WEP40;
4395 }
4396 else
4397 ieee->pairwise_key_type = KEY_TYPE_NA;
4398
4399 if (ieee->pairwise_key_type)
4400 {
4401 memcpy((u8*)key, ipw->u.crypt.key, 16);
4402 EnableHWSecurityConfig8192(dev);
4403 //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!
4404 //added by WB.
4405 setKey(dev, 4, ipw->u.crypt.idx, ieee->pairwise_key_type, (u8*)ieee->ap_mac_addr, 0, key);
4406 if (ieee->auth_mode != 2)
4407 setKey(dev, ipw->u.crypt.idx, ipw->u.crypt.idx, ieee->pairwise_key_type, (u8*)ieee->ap_mac_addr, 0, key);
4408 }
4409 }
4410 else //if (ipw->u.crypt.idx) //group key use idx > 0
4411 {
4412 memcpy((u8*)key, ipw->u.crypt.key, 16);
4413 if (strcmp(ipw->u.crypt.alg, "CCMP") == 0)
4414 ieee->group_key_type= KEY_TYPE_CCMP;
4415 else if (strcmp(ipw->u.crypt.alg, "TKIP") == 0)
4416 ieee->group_key_type = KEY_TYPE_TKIP;
4417 else if (strcmp(ipw->u.crypt.alg, "WEP") == 0)
4418 {
4419 if (ipw->u.crypt.key_len == 13)
4420 ieee->group_key_type = KEY_TYPE_WEP104;
4421 else if (ipw->u.crypt.key_len == 5)
4422 ieee->group_key_type = KEY_TYPE_WEP40;
4423 }
4424 else
4425 ieee->group_key_type = KEY_TYPE_NA;
4426
4427 if (ieee->group_key_type)
4428 {
4429 setKey( dev,
4430 ipw->u.crypt.idx,
4431 ipw->u.crypt.idx, //KeyIndex
4432 ieee->group_key_type, //KeyType
4433 broadcast_addr, //MacAddr
4434 0, //DefaultKey
4435 key); //KeyContent
4436 }
4437 }
4438 }
4439#ifdef JOHN_HWSEC_DEBUG
4440 //john's test 0711
4441 printk("@@ wrq->u pointer = ");
4442 for(i=0;i<wrq->u.data.length;i++){
4443 if(i%10==0) printk("\n");
4444 printk( "%8x|", ((u32*)wrq->u.data.pointer)[i] );
4445 }
4446 printk("\n");
4447#endif /*JOHN_HWSEC_DEBUG*/
4448 ret = ieee80211_wpa_supplicant_ioctl(priv->ieee80211, &wrq->u.data);
4449 break;
4450
4451 default:
4452 ret = -EOPNOTSUPP;
4453 break;
4454 }
4455 kfree(ipw);
e406322b 4456 ipw = NULL;
8fc8598e
JC
4457out:
4458 up(&priv->wx_sem);
4459 return ret;
4460}
4461
4462u8 HwRateToMRate90(bool bIsHT, u8 rate)
4463{
4464 u8 ret_rate = 0xff;
4465
4466 if(!bIsHT) {
4467 switch(rate) {
4468 case DESC90_RATE1M: ret_rate = MGN_1M; break;
4469 case DESC90_RATE2M: ret_rate = MGN_2M; break;
4470 case DESC90_RATE5_5M: ret_rate = MGN_5_5M; break;
4471 case DESC90_RATE11M: ret_rate = MGN_11M; break;
4472 case DESC90_RATE6M: ret_rate = MGN_6M; break;
4473 case DESC90_RATE9M: ret_rate = MGN_9M; break;
4474 case DESC90_RATE12M: ret_rate = MGN_12M; break;
4475 case DESC90_RATE18M: ret_rate = MGN_18M; break;
4476 case DESC90_RATE24M: ret_rate = MGN_24M; break;
4477 case DESC90_RATE36M: ret_rate = MGN_36M; break;
4478 case DESC90_RATE48M: ret_rate = MGN_48M; break;
4479 case DESC90_RATE54M: ret_rate = MGN_54M; break;
4480
4481 default:
4482 ret_rate = 0xff;
4483 RT_TRACE(COMP_RECV, "HwRateToMRate90(): Non supported Rate [%x], bIsHT = %d!!!\n", rate, bIsHT);
4484 break;
4485 }
4486
4487 } else {
4488 switch(rate) {
4489 case DESC90_RATEMCS0: ret_rate = MGN_MCS0; break;
4490 case DESC90_RATEMCS1: ret_rate = MGN_MCS1; break;
4491 case DESC90_RATEMCS2: ret_rate = MGN_MCS2; break;
4492 case DESC90_RATEMCS3: ret_rate = MGN_MCS3; break;
4493 case DESC90_RATEMCS4: ret_rate = MGN_MCS4; break;
4494 case DESC90_RATEMCS5: ret_rate = MGN_MCS5; break;
4495 case DESC90_RATEMCS6: ret_rate = MGN_MCS6; break;
4496 case DESC90_RATEMCS7: ret_rate = MGN_MCS7; break;
4497 case DESC90_RATEMCS8: ret_rate = MGN_MCS8; break;
4498 case DESC90_RATEMCS9: ret_rate = MGN_MCS9; break;
4499 case DESC90_RATEMCS10: ret_rate = MGN_MCS10; break;
4500 case DESC90_RATEMCS11: ret_rate = MGN_MCS11; break;
4501 case DESC90_RATEMCS12: ret_rate = MGN_MCS12; break;
4502 case DESC90_RATEMCS13: ret_rate = MGN_MCS13; break;
4503 case DESC90_RATEMCS14: ret_rate = MGN_MCS14; break;
4504 case DESC90_RATEMCS15: ret_rate = MGN_MCS15; break;
4505 case DESC90_RATEMCS32: ret_rate = (0x80|0x20); break;
4506
4507 default:
4508 ret_rate = 0xff;
4509 RT_TRACE(COMP_RECV, "HwRateToMRate90(): Non supported Rate [%x], bIsHT = %d!!!\n",rate, bIsHT);
4510 break;
4511 }
4512 }
4513
4514 return ret_rate;
4515}
4516
4517/**
4518 * Function: UpdateRxPktTimeStamp
589b3d06 4519 * Overview: Record down the TSF time stamp when receiving a packet
8fc8598e
JC
4520 *
4521 * Input:
4522 * PADAPTER Adapter
4523 * PRT_RFD pRfd,
4524 *
4525 * Output:
4526 * PRT_RFD pRfd
4527 * (pRfd->Status.TimeStampHigh is updated)
4528 * (pRfd->Status.TimeStampLow is updated)
4529 * Return:
4530 * None
4531 */
4532void UpdateRxPktTimeStamp8190 (struct net_device *dev, struct ieee80211_rx_stats *stats)
4533{
4534 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
4535
4536 if(stats->bIsAMPDU && !stats->bFirstMPDU) {
4537 stats->mac_time[0] = priv->LastRxDescTSFLow;
4538 stats->mac_time[1] = priv->LastRxDescTSFHigh;
4539 } else {
4540 priv->LastRxDescTSFLow = stats->mac_time[0];
4541 priv->LastRxDescTSFHigh = stats->mac_time[1];
4542 }
4543}
4544
4545//by amy 080606
4546
4547long rtl819x_translate_todbm(u8 signal_strength_index )// 0-100 index.
4548{
4549 long signal_power; // in dBm.
4550
4551 // Translate to dBm (x=0.5y-95).
4552 signal_power = (long)((signal_strength_index + 1) >> 1);
4553 signal_power -= 95;
4554
4555 return signal_power;
4556}
4557
4558
589b3d06 4559/* 2008/01/22 MH We can not declare RSSI/EVM total value of sliding window to
8fc8598e 4560 be a local static. Otherwise, it may increase when we return from S3/S4. The
589b3d06 4561 value will be kept in memory or disk. We must declare the value in adapter
8fc8598e
JC
4562 and it will be reinitialized when return from S3/S4. */
4563void rtl8192_process_phyinfo(struct r8192_priv * priv,u8* buffer, struct ieee80211_rx_stats * pprevious_stats, struct ieee80211_rx_stats * pcurrent_stats)
4564{
4565 bool bcheck = false;
4566 u8 rfpath;
4567 u32 nspatial_stream, tmp_val;
4568 //u8 i;
4569 static u32 slide_rssi_index=0, slide_rssi_statistics=0;
4570 static u32 slide_evm_index=0, slide_evm_statistics=0;
4571 static u32 last_rssi=0, last_evm=0;
4572
4573 static u32 slide_beacon_adc_pwdb_index=0, slide_beacon_adc_pwdb_statistics=0;
4574 static u32 last_beacon_adc_pwdb=0;
4575
4576 struct ieee80211_hdr_3addr *hdr;
4577 u16 sc ;
4578 unsigned int frag,seq;
4579 hdr = (struct ieee80211_hdr_3addr *)buffer;
4580 sc = le16_to_cpu(hdr->seq_ctl);
4581 frag = WLAN_GET_SEQ_FRAG(sc);
4582 seq = WLAN_GET_SEQ_SEQ(sc);
4583 //cosa add 04292008 to record the sequence number
4584 pcurrent_stats->Seq_Num = seq;
4585 //
4586 // Check whether we should take the previous packet into accounting
4587 //
4588 if(!pprevious_stats->bIsAMPDU)
4589 {
4590 // if previous packet is not aggregated packet
4591 bcheck = true;
4592 }else
4593 {
8fc8598e
JC
4594 }
4595
4596
4597 if(slide_rssi_statistics++ >= PHY_RSSI_SLID_WIN_MAX)
4598 {
4599 slide_rssi_statistics = PHY_RSSI_SLID_WIN_MAX;
4600 last_rssi = priv->stats.slide_signal_strength[slide_rssi_index];
4601 priv->stats.slide_rssi_total -= last_rssi;
4602 }
4603 priv->stats.slide_rssi_total += pprevious_stats->SignalStrength;
4604
4605 priv->stats.slide_signal_strength[slide_rssi_index++] = pprevious_stats->SignalStrength;
4606 if(slide_rssi_index >= PHY_RSSI_SLID_WIN_MAX)
4607 slide_rssi_index = 0;
4608
4609 // <1> Showed on UI for user, in dbm
4610 tmp_val = priv->stats.slide_rssi_total/slide_rssi_statistics;
4611 priv->stats.signal_strength = rtl819x_translate_todbm((u8)tmp_val);
4612 pcurrent_stats->rssi = priv->stats.signal_strength;
4613 //
4614 // If the previous packet does not match the criteria, neglect it
4615 //
4616 if(!pprevious_stats->bPacketMatchBSSID)
4617 {
4618 if(!pprevious_stats->bToSelfBA)
4619 return;
4620 }
4621
4622 if(!bcheck)
4623 return;
4624
4625
4626 //rtl8190_process_cck_rxpathsel(priv,pprevious_stats);//only rtl8190 supported
4627
4628 //
4629 // Check RSSI
4630 //
4631 priv->stats.num_process_phyinfo++;
4632
4633 /* record the general signal strength to the sliding window. */
4634
4635
4636 // <2> Showed on UI for engineering
4637 // hardware does not provide rssi information for each rf path in CCK
4638 if(!pprevious_stats->bIsCCK && (pprevious_stats->bPacketToSelf || pprevious_stats->bToSelfBA))
4639 {
4640 for (rfpath = RF90_PATH_A; rfpath < priv->NumTotalRFPath; rfpath++)
4641 {
e406322b
MCC
4642 if (!rtl8192_phy_CheckIsLegalRFPath(priv->ieee80211->dev, rfpath))
4643 continue;
8fc8598e
JC
4644
4645 //Fixed by Jacken 2008-03-20
4646 if(priv->stats.rx_rssi_percentage[rfpath] == 0)
4647 {
4648 priv->stats.rx_rssi_percentage[rfpath] = pprevious_stats->RxMIMOSignalStrength[rfpath];
4649 //DbgPrint("MIMO RSSI initialize \n");
4650 }
4651 if(pprevious_stats->RxMIMOSignalStrength[rfpath] > priv->stats.rx_rssi_percentage[rfpath])
4652 {
4653 priv->stats.rx_rssi_percentage[rfpath] =
4654 ( (priv->stats.rx_rssi_percentage[rfpath]*(Rx_Smooth_Factor-1)) +
4655 (pprevious_stats->RxMIMOSignalStrength[rfpath])) /(Rx_Smooth_Factor);
4656 priv->stats.rx_rssi_percentage[rfpath] = priv->stats.rx_rssi_percentage[rfpath] + 1;
4657 }
4658 else
4659 {
4660 priv->stats.rx_rssi_percentage[rfpath] =
4661 ( (priv->stats.rx_rssi_percentage[rfpath]*(Rx_Smooth_Factor-1)) +
4662 (pprevious_stats->RxMIMOSignalStrength[rfpath])) /(Rx_Smooth_Factor);
4663 }
4664 RT_TRACE(COMP_DBG,"priv->stats.rx_rssi_percentage[rfPath] = %d \n" ,priv->stats.rx_rssi_percentage[rfpath] );
4665 }
4666 }
4667
4668
4669 //
4670 // Check PWDB.
4671 //
4672 RT_TRACE(COMP_RXDESC, "Smooth %s PWDB = %d\n",
4673 pprevious_stats->bIsCCK? "CCK": "OFDM",
4674 pprevious_stats->RxPWDBAll);
4675
4676 if(pprevious_stats->bPacketBeacon)
4677 {
4678/* record the beacon pwdb to the sliding window. */
4679 if(slide_beacon_adc_pwdb_statistics++ >= PHY_Beacon_RSSI_SLID_WIN_MAX)
4680 {
4681 slide_beacon_adc_pwdb_statistics = PHY_Beacon_RSSI_SLID_WIN_MAX;
4682 last_beacon_adc_pwdb = priv->stats.Slide_Beacon_pwdb[slide_beacon_adc_pwdb_index];
4683 priv->stats.Slide_Beacon_Total -= last_beacon_adc_pwdb;
4684 //DbgPrint("slide_beacon_adc_pwdb_index = %d, last_beacon_adc_pwdb = %d, Adapter->RxStats.Slide_Beacon_Total = %d\n",
4685 // slide_beacon_adc_pwdb_index, last_beacon_adc_pwdb, Adapter->RxStats.Slide_Beacon_Total);
4686 }
4687 priv->stats.Slide_Beacon_Total += pprevious_stats->RxPWDBAll;
4688 priv->stats.Slide_Beacon_pwdb[slide_beacon_adc_pwdb_index] = pprevious_stats->RxPWDBAll;
4689 //DbgPrint("slide_beacon_adc_pwdb_index = %d, pPreviousRfd->Status.RxPWDBAll = %d\n", slide_beacon_adc_pwdb_index, pPreviousRfd->Status.RxPWDBAll);
4690 slide_beacon_adc_pwdb_index++;
4691 if(slide_beacon_adc_pwdb_index >= PHY_Beacon_RSSI_SLID_WIN_MAX)
4692 slide_beacon_adc_pwdb_index = 0;
4693 pprevious_stats->RxPWDBAll = priv->stats.Slide_Beacon_Total/slide_beacon_adc_pwdb_statistics;
4694 if(pprevious_stats->RxPWDBAll >= 3)
4695 pprevious_stats->RxPWDBAll -= 3;
4696 }
4697
4698 RT_TRACE(COMP_RXDESC, "Smooth %s PWDB = %d\n",
4699 pprevious_stats->bIsCCK? "CCK": "OFDM",
4700 pprevious_stats->RxPWDBAll);
4701
4702
4703 if(pprevious_stats->bPacketToSelf || pprevious_stats->bPacketBeacon || pprevious_stats->bToSelfBA)
4704 {
4705 if(priv->undecorated_smoothed_pwdb < 0) // initialize
4706 {
4707 priv->undecorated_smoothed_pwdb = pprevious_stats->RxPWDBAll;
4708 //DbgPrint("First pwdb initialize \n");
4709 }
8fc8598e
JC
4710 if(pprevious_stats->RxPWDBAll > (u32)priv->undecorated_smoothed_pwdb)
4711 {
4712 priv->undecorated_smoothed_pwdb =
4713 ( ((priv->undecorated_smoothed_pwdb)*(Rx_Smooth_Factor-1)) +
4714 (pprevious_stats->RxPWDBAll)) /(Rx_Smooth_Factor);
4715 priv->undecorated_smoothed_pwdb = priv->undecorated_smoothed_pwdb + 1;
4716 }
4717 else
4718 {
4719 priv->undecorated_smoothed_pwdb =
4720 ( ((priv->undecorated_smoothed_pwdb)*(Rx_Smooth_Factor-1)) +
4721 (pprevious_stats->RxPWDBAll)) /(Rx_Smooth_Factor);
4722 }
8fc8598e
JC
4723
4724 }
4725
4726 //
4727 // Check EVM
4728 //
4729 /* record the general EVM to the sliding window. */
4730 if(pprevious_stats->SignalQuality == 0)
4731 {
4732 }
4733 else
4734 {
4735 if(pprevious_stats->bPacketToSelf || pprevious_stats->bPacketBeacon || pprevious_stats->bToSelfBA){
4736 if(slide_evm_statistics++ >= PHY_RSSI_SLID_WIN_MAX){
4737 slide_evm_statistics = PHY_RSSI_SLID_WIN_MAX;
4738 last_evm = priv->stats.slide_evm[slide_evm_index];
4739 priv->stats.slide_evm_total -= last_evm;
4740 }
4741
4742 priv->stats.slide_evm_total += pprevious_stats->SignalQuality;
4743
4744 priv->stats.slide_evm[slide_evm_index++] = pprevious_stats->SignalQuality;
4745 if(slide_evm_index >= PHY_RSSI_SLID_WIN_MAX)
4746 slide_evm_index = 0;
4747
4748 // <1> Showed on UI for user, in percentage.
4749 tmp_val = priv->stats.slide_evm_total/slide_evm_statistics;
4750 priv->stats.signal_quality = tmp_val;
4751 //cosa add 10/11/2007, Showed on UI for user in Windows Vista, for Link quality.
4752 priv->stats.last_signal_strength_inpercent = tmp_val;
4753 }
4754
4755 // <2> Showed on UI for engineering
4756 if(pprevious_stats->bPacketToSelf || pprevious_stats->bPacketBeacon || pprevious_stats->bToSelfBA)
4757 {
4758 for(nspatial_stream = 0; nspatial_stream<2 ; nspatial_stream++) // 2 spatial stream
4759 {
4760 if(pprevious_stats->RxMIMOSignalQuality[nspatial_stream] != -1)
4761 {
4762 if(priv->stats.rx_evm_percentage[nspatial_stream] == 0) // initialize
4763 {
4764 priv->stats.rx_evm_percentage[nspatial_stream] = pprevious_stats->RxMIMOSignalQuality[nspatial_stream];
4765 }
4766 priv->stats.rx_evm_percentage[nspatial_stream] =
4767 ( (priv->stats.rx_evm_percentage[nspatial_stream]* (Rx_Smooth_Factor-1)) +
4768 (pprevious_stats->RxMIMOSignalQuality[nspatial_stream]* 1)) / (Rx_Smooth_Factor);
4769 }
4770 }
4771 }
4772 }
4773
4774
4775}
4776
4777/*-----------------------------------------------------------------------------
4778 * Function: rtl819x_query_rxpwrpercentage()
4779 *
4780 * Overview:
4781 *
4782 * Input: char antpower
4783 *
4784 * Output: NONE
4785 *
4786 * Return: 0-100 percentage
4787 *
4788 * Revised History:
4789 * When Who Remark
4790 * 05/26/2008 amy Create Version 0 porting from windows code.
4791 *
4792 *---------------------------------------------------------------------------*/
4793static u8 rtl819x_query_rxpwrpercentage(
4794 char antpower
4795 )
4796{
4797 if ((antpower <= -100) || (antpower >= 20))
4798 {
4799 return 0;
4800 }
4801 else if (antpower >= 0)
4802 {
4803 return 100;
4804 }
4805 else
4806 {
4807 return (100+antpower);
4808 }
4809
4810} /* QueryRxPwrPercentage */
4811
4812static u8
4813rtl819x_evm_dbtopercentage(
4814 char value
4815 )
4816{
4817 char ret_val;
4818
4819 ret_val = value;
4820
4821 if(ret_val >= 0)
4822 ret_val = 0;
4823 if(ret_val <= -33)
4824 ret_val = -33;
4825 ret_val = 0 - ret_val;
4826 ret_val*=3;
4827 if(ret_val == 99)
4828 ret_val = 100;
4829 return(ret_val);
4830}
4831//
4832// Description:
4833// We want good-looking for signal strength/quality
4834// 2007/7/19 01:09, by cosa.
4835//
4836long
4837rtl819x_signal_scale_mapping(
4838 long currsig
4839 )
4840{
4841 long retsig;
4842
4843 // Step 1. Scale mapping.
4844 if(currsig >= 61 && currsig <= 100)
4845 {
4846 retsig = 90 + ((currsig - 60) / 4);
4847 }
4848 else if(currsig >= 41 && currsig <= 60)
4849 {
4850 retsig = 78 + ((currsig - 40) / 2);
4851 }
4852 else if(currsig >= 31 && currsig <= 40)
4853 {
4854 retsig = 66 + (currsig - 30);
4855 }
4856 else if(currsig >= 21 && currsig <= 30)
4857 {
4858 retsig = 54 + (currsig - 20);
4859 }
4860 else if(currsig >= 5 && currsig <= 20)
4861 {
4862 retsig = 42 + (((currsig - 5) * 2) / 3);
4863 }
4864 else if(currsig == 4)
4865 {
4866 retsig = 36;
4867 }
4868 else if(currsig == 3)
4869 {
4870 retsig = 27;
4871 }
4872 else if(currsig == 2)
4873 {
4874 retsig = 18;
4875 }
4876 else if(currsig == 1)
4877 {
4878 retsig = 9;
4879 }
4880 else
4881 {
4882 retsig = currsig;
4883 }
4884
4885 return retsig;
4886}
4887
4888static void rtl8192_query_rxphystatus(
4889 struct r8192_priv * priv,
4890 struct ieee80211_rx_stats * pstats,
4891 rx_drvinfo_819x_usb * pdrvinfo,
4892 struct ieee80211_rx_stats * precord_stats,
4893 bool bpacket_match_bssid,
4894 bool bpacket_toself,
4895 bool bPacketBeacon,
4896 bool bToSelfBA
4897 )
4898{
4899 //PRT_RFD_STATUS pRtRfdStatus = &(pRfd->Status);
4900 phy_sts_ofdm_819xusb_t* pofdm_buf;
4901 phy_sts_cck_819xusb_t * pcck_buf;
4902 phy_ofdm_rx_status_rxsc_sgien_exintfflag* prxsc;
4903 u8 *prxpkt;
4904 u8 i, max_spatial_stream, tmp_rxsnr, tmp_rxevm, rxsc_sgien_exflg;
4905 char rx_pwr[4], rx_pwr_all=0;
4906 //long rx_avg_pwr = 0;
4907 char rx_snrX, rx_evmX;
4908 u8 evm, pwdb_all;
4909 u32 RSSI, total_rssi=0;//, total_evm=0;
4910// long signal_strength_index = 0;
4911 u8 is_cck_rate=0;
4912 u8 rf_rx_num = 0;
4913
4914
4915 priv->stats.numqry_phystatus++;
4916
4917 is_cck_rate = rx_hal_is_cck_rate(pdrvinfo);
4918
4919 // Record it for next packet processing
4920 memset(precord_stats, 0, sizeof(struct ieee80211_rx_stats));
4921 pstats->bPacketMatchBSSID = precord_stats->bPacketMatchBSSID = bpacket_match_bssid;
4922 pstats->bPacketToSelf = precord_stats->bPacketToSelf = bpacket_toself;
4923 pstats->bIsCCK = precord_stats->bIsCCK = is_cck_rate;//RX_HAL_IS_CCK_RATE(pDrvInfo);
4924 pstats->bPacketBeacon = precord_stats->bPacketBeacon = bPacketBeacon;
4925 pstats->bToSelfBA = precord_stats->bToSelfBA = bToSelfBA;
4926
4927 prxpkt = (u8*)pdrvinfo;
4928
4929 /* Move pointer to the 16th bytes. Phy status start address. */
4930 prxpkt += sizeof(rx_drvinfo_819x_usb);
4931
4932 /* Initial the cck and ofdm buffer pointer */
4933 pcck_buf = (phy_sts_cck_819xusb_t *)prxpkt;
4934 pofdm_buf = (phy_sts_ofdm_819xusb_t *)prxpkt;
4935
4936 pstats->RxMIMOSignalQuality[0] = -1;
4937 pstats->RxMIMOSignalQuality[1] = -1;
4938 precord_stats->RxMIMOSignalQuality[0] = -1;
4939 precord_stats->RxMIMOSignalQuality[1] = -1;
4940
4941 if(is_cck_rate)
4942 {
4943 //
4944 // (1)Hardware does not provide RSSI for CCK
4945 //
4946
4947 //
4948 // (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive)
4949 //
4950 u8 report;//, cck_agc_rpt;
4951
4952 priv->stats.numqry_phystatusCCK++;
4953
4954 if(!priv->bCckHighPower)
4955 {
4956 report = pcck_buf->cck_agc_rpt & 0xc0;
4957 report = report>>6;
4958 switch(report)
4959 {
4960 //Fixed by Jacken from Bryant 2008-03-20
4961 //Original value is -38 , -26 , -14 , -2
4962 //Fixed value is -35 , -23 , -11 , 6
4963 case 0x3:
4964 rx_pwr_all = -35 - (pcck_buf->cck_agc_rpt & 0x3e);
4965 break;
4966 case 0x2:
4967 rx_pwr_all = -23 - (pcck_buf->cck_agc_rpt & 0x3e);
4968 break;
4969 case 0x1:
4970 rx_pwr_all = -11 - (pcck_buf->cck_agc_rpt & 0x3e);
4971 break;
4972 case 0x0:
4973 rx_pwr_all = 6 - (pcck_buf->cck_agc_rpt & 0x3e);
4974 break;
4975 }
4976 }
4977 else
4978 {
4979 report = pcck_buf->cck_agc_rpt & 0x60;
4980 report = report>>5;
4981 switch(report)
4982 {
4983 case 0x3:
4984 rx_pwr_all = -35 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1) ;
4985 break;
4986 case 0x2:
4987 rx_pwr_all = -23 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1);
4988 break;
4989 case 0x1:
4990 rx_pwr_all = -11 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1) ;
4991 break;
4992 case 0x0:
4993 rx_pwr_all = 6 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1) ;
4994 break;
4995 }
4996 }
4997
4998 pwdb_all = rtl819x_query_rxpwrpercentage(rx_pwr_all);
4999 pstats->RxPWDBAll = precord_stats->RxPWDBAll = pwdb_all;
5000 pstats->RecvSignalPower = pwdb_all;
5001
5002 //
5003 // (3) Get Signal Quality (EVM)
5004 //
5005 //if(bpacket_match_bssid)
5006 {
5007 u8 sq;
5008
5009 if(pstats->RxPWDBAll > 40)
5010 {
5011 sq = 100;
5012 }else
5013 {
5014 sq = pcck_buf->sq_rpt;
5015
5016 if(pcck_buf->sq_rpt > 64)
5017 sq = 0;
5018 else if (pcck_buf->sq_rpt < 20)
5019 sq = 100;
5020 else
5021 sq = ((64-sq) * 100) / 44;
5022 }
5023 pstats->SignalQuality = precord_stats->SignalQuality = sq;
5024 pstats->RxMIMOSignalQuality[0] = precord_stats->RxMIMOSignalQuality[0] = sq;
5025 pstats->RxMIMOSignalQuality[1] = precord_stats->RxMIMOSignalQuality[1] = -1;
5026 }
5027 }
5028 else
5029 {
5030 priv->stats.numqry_phystatusHT++;
5031 //
5032 // (1)Get RSSI for HT rate
5033 //
5034 for(i=RF90_PATH_A; i<priv->NumTotalRFPath; i++)
5035 {
5036 // 2008/01/30 MH we will judge RF RX path now.
5037 if (priv->brfpath_rxenable[i])
5038 rf_rx_num++;
5039 else
5040 continue;
5041
5042 if (!rtl8192_phy_CheckIsLegalRFPath(priv->ieee80211->dev, i))
5043 continue;
5044
5045 //Fixed by Jacken from Bryant 2008-03-20
5046 //Original value is 106
5047 rx_pwr[i] = ((pofdm_buf->trsw_gain_X[i]&0x3F)*2) - 106;
5048
5049 //Get Rx snr value in DB
5050 tmp_rxsnr = pofdm_buf->rxsnr_X[i];
5051 rx_snrX = (char)(tmp_rxsnr);
859171ca 5052 //rx_snrX >>= 1;
8fc8598e
JC
5053 rx_snrX /= 2;
5054 priv->stats.rxSNRdB[i] = (long)rx_snrX;
5055
5056 /* Translate DBM to percentage. */
5057 RSSI = rtl819x_query_rxpwrpercentage(rx_pwr[i]);
5058 total_rssi += RSSI;
5059
5060 /* Record Signal Strength for next packet */
5061 //if(bpacket_match_bssid)
5062 {
5063 pstats->RxMIMOSignalStrength[i] =(u8) RSSI;
5064 precord_stats->RxMIMOSignalStrength[i] =(u8) RSSI;
5065 }
5066 }
5067
5068
5069 //
5070 // (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive)
5071 //
5072 //Fixed by Jacken from Bryant 2008-03-20
5073 //Original value is 106
5074 rx_pwr_all = (((pofdm_buf->pwdb_all ) >> 1 )& 0x7f) -106;
5075 pwdb_all = rtl819x_query_rxpwrpercentage(rx_pwr_all);
5076
5077 pstats->RxPWDBAll = precord_stats->RxPWDBAll = pwdb_all;
5078 pstats->RxPower = precord_stats->RxPower = rx_pwr_all;
5079
5080 //
5081 // (3)EVM of HT rate
5082 //
5083 if(pdrvinfo->RxHT && pdrvinfo->RxRate>=DESC90_RATEMCS8 &&
e406322b 5084 pdrvinfo->RxRate<=DESC90_RATEMCS15)
8fc8598e
JC
5085 max_spatial_stream = 2; //both spatial stream make sense
5086 else
5087 max_spatial_stream = 1; //only spatial stream 1 makes sense
5088
5089 for(i=0; i<max_spatial_stream; i++)
5090 {
5091 tmp_rxevm = pofdm_buf->rxevm_X[i];
5092 rx_evmX = (char)(tmp_rxevm);
5093
589b3d06 5094 // Do not use shift operation like "rx_evmX >>= 1" because the compiler of free build environment
8fc8598e
JC
5095 // fill most significant bit to "zero" when doing shifting operation which may change a negative
5096 // value to positive one, then the dbm value (which is supposed to be negative) is not correct anymore.
5097 rx_evmX /= 2; //dbm
5098
5099 evm = rtl819x_evm_dbtopercentage(rx_evmX);
8fc8598e
JC
5100 //if(bpacket_match_bssid)
5101 {
5102 if(i==0) // Fill value in RFD, Get the first spatial stream only
5103 pstats->SignalQuality = precord_stats->SignalQuality = (u8)(evm & 0xff);
5104 pstats->RxMIMOSignalQuality[i] = precord_stats->RxMIMOSignalQuality[i] = (u8)(evm & 0xff);
5105 }
5106 }
5107
5108
5109 /* record rx statistics for debug */
5110 rxsc_sgien_exflg = pofdm_buf->rxsc_sgien_exflg;
5111 prxsc = (phy_ofdm_rx_status_rxsc_sgien_exintfflag *)&rxsc_sgien_exflg;
5112 if(pdrvinfo->BW) //40M channel
5113 priv->stats.received_bwtype[1+prxsc->rxsc]++;
5114 else //20M channel
5115 priv->stats.received_bwtype[0]++;
5116 }
5117
5118 //UI BSS List signal strength(in percentage), make it good looking, from 0~100.
5119 //It is assigned to the BSS List in GetValueFromBeaconOrProbeRsp().
5120 if(is_cck_rate)
5121 {
5122 pstats->SignalStrength = precord_stats->SignalStrength = (u8)(rtl819x_signal_scale_mapping((long)pwdb_all));//PWDB_ALL;
5123
5124 }
5125 else
5126 {
5127 //pRfd->Status.SignalStrength = pRecordRfd->Status.SignalStrength = (u8)(SignalScaleMapping(total_rssi/=RF90_PATH_MAX));//(u8)(total_rssi/=RF90_PATH_MAX);
5128 // We can judge RX path number now.
5129 if (rf_rx_num != 0)
5130 pstats->SignalStrength = precord_stats->SignalStrength = (u8)(rtl819x_signal_scale_mapping((long)(total_rssi/=rf_rx_num)));
5131 }
5132} /* QueryRxPhyStatus8190Pci */
5133
5134void
5135rtl8192_record_rxdesc_forlateruse(
5136 struct ieee80211_rx_stats * psrc_stats,
5137 struct ieee80211_rx_stats * ptarget_stats
5138)
5139{
5140 ptarget_stats->bIsAMPDU = psrc_stats->bIsAMPDU;
5141 ptarget_stats->bFirstMPDU = psrc_stats->bFirstMPDU;
5142 ptarget_stats->Seq_Num = psrc_stats->Seq_Num;
5143}
5144
5145
5146void TranslateRxSignalStuff819xUsb(struct sk_buff *skb,
5147 struct ieee80211_rx_stats * pstats,
e406322b 5148 rx_drvinfo_819x_usb *pdrvinfo)
8fc8598e
JC
5149{
5150 // TODO: We must only check packet for current MAC address. Not finish
5151 rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
5152 struct net_device *dev=info->dev;
5153 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
5154 bool bpacket_match_bssid, bpacket_toself;
5155 bool bPacketBeacon=FALSE, bToSelfBA=FALSE;
5156 static struct ieee80211_rx_stats previous_stats;
5157 struct ieee80211_hdr_3addr *hdr;//by amy
5158 u16 fc,type;
5159
5160 // Get Signal Quality for only RX data queue (but not command queue)
5161
5162 u8* tmp_buf;
5163 //u16 tmp_buf_len = 0;
5164 u8 *praddr;
5165
5166 /* Get MAC frame start address. */
5167 tmp_buf = (u8*)skb->data;// + get_rxpacket_shiftbytes_819xusb(pstats);
5168
5169 hdr = (struct ieee80211_hdr_3addr *)tmp_buf;
5170 fc = le16_to_cpu(hdr->frame_ctl);
5171 type = WLAN_FC_GET_TYPE(fc);
5172 praddr = hdr->addr1;
5173
589b3d06 5174 /* Check if the received packet is acceptable. */
8fc8598e 5175 bpacket_match_bssid = ((IEEE80211_FTYPE_CTL != type) &&
e406322b
MCC
5176 (eqMacAddr(priv->ieee80211->current_network.bssid, (fc & IEEE80211_FCTL_TODS)? hdr->addr1 : (fc & IEEE80211_FCTL_FROMDS )? hdr->addr2 : hdr->addr3))
5177 && (!pstats->bHwError) && (!pstats->bCRC)&& (!pstats->bICV));
8fc8598e
JC
5178 bpacket_toself = bpacket_match_bssid & (eqMacAddr(praddr, priv->ieee80211->dev->dev_addr));
5179
8fc8598e
JC
5180 if(WLAN_FC_GET_FRAMETYPE(fc)== IEEE80211_STYPE_BEACON)
5181 {
5182 bPacketBeacon = true;
5183 //DbgPrint("Beacon 2, MatchBSSID = %d, ToSelf = %d \n", bPacketMatchBSSID, bPacketToSelf);
5184 }
5185 if(WLAN_FC_GET_FRAMETYPE(fc) == IEEE80211_STYPE_BLOCKACK)
5186 {
5187 if((eqMacAddr(praddr,dev->dev_addr)))
5188 bToSelfBA = true;
5189 //DbgPrint("BlockAck, MatchBSSID = %d, ToSelf = %d \n", bPacketMatchBSSID, bPacketToSelf);
5190 }
5191
8fc8598e
JC
5192
5193
5194 if(bpacket_match_bssid)
5195 {
5196 priv->stats.numpacket_matchbssid++;
5197 }
5198 if(bpacket_toself){
5199 priv->stats.numpacket_toself++;
5200 }
5201 //
5202 // Process PHY information for previous packet (RSSI/PWDB/EVM)
5203 //
5204 // Because phy information is contained in the last packet of AMPDU only, so driver
5205 // should process phy information of previous packet
5206 rtl8192_process_phyinfo(priv, tmp_buf, &previous_stats, pstats);
5207 rtl8192_query_rxphystatus(priv, pstats, pdrvinfo, &previous_stats, bpacket_match_bssid,bpacket_toself,bPacketBeacon,bToSelfBA);
5208 rtl8192_record_rxdesc_forlateruse(pstats, &previous_stats);
5209
5210}
5211
5212/**
5213* Function: UpdateReceivedRateHistogramStatistics
589b3d06 5214* Overview: Record down the received data rate
8fc8598e
JC
5215*
5216* Input:
5217* struct net_device *dev
5218* struct ieee80211_rx_stats *stats
5219*
5220* Output:
5221*
5222* (priv->stats.ReceivedRateHistogram[] is updated)
5223* Return:
5224* None
5225*/
5226void
5227UpdateReceivedRateHistogramStatistics8190(
5228 struct net_device *dev,
5229 struct ieee80211_rx_stats *stats
5230 )
5231{
5232 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
e406322b
MCC
5233 u32 rcvType=1; //0: Total, 1:OK, 2:CRC, 3:ICV
5234 u32 rateIndex;
5235 u32 preamble_guardinterval; //1: short preamble/GI, 0: long preamble/GI
8fc8598e
JC
5236
5237
e406322b
MCC
5238 if(stats->bCRC)
5239 rcvType = 2;
5240 else if(stats->bICV)
5241 rcvType = 3;
8fc8598e 5242
e406322b
MCC
5243 if(stats->bShortPreamble)
5244 preamble_guardinterval = 1;// short
5245 else
5246 preamble_guardinterval = 0;// long
8fc8598e
JC
5247
5248 switch(stats->rate)
5249 {
5250 //
5251 // CCK rate
5252 //
5253 case MGN_1M: rateIndex = 0; break;
5254 case MGN_2M: rateIndex = 1; break;
5255 case MGN_5_5M: rateIndex = 2; break;
5256 case MGN_11M: rateIndex = 3; break;
5257 //
5258 // Legacy OFDM rate
5259 //
5260 case MGN_6M: rateIndex = 4; break;
5261 case MGN_9M: rateIndex = 5; break;
5262 case MGN_12M: rateIndex = 6; break;
5263 case MGN_18M: rateIndex = 7; break;
5264 case MGN_24M: rateIndex = 8; break;
5265 case MGN_36M: rateIndex = 9; break;
5266 case MGN_48M: rateIndex = 10; break;
5267 case MGN_54M: rateIndex = 11; break;
5268 //
5269 // 11n High throughput rate
5270 //
5271 case MGN_MCS0: rateIndex = 12; break;
5272 case MGN_MCS1: rateIndex = 13; break;
5273 case MGN_MCS2: rateIndex = 14; break;
5274 case MGN_MCS3: rateIndex = 15; break;
5275 case MGN_MCS4: rateIndex = 16; break;
5276 case MGN_MCS5: rateIndex = 17; break;
5277 case MGN_MCS6: rateIndex = 18; break;
5278 case MGN_MCS7: rateIndex = 19; break;
5279 case MGN_MCS8: rateIndex = 20; break;
5280 case MGN_MCS9: rateIndex = 21; break;
5281 case MGN_MCS10: rateIndex = 22; break;
5282 case MGN_MCS11: rateIndex = 23; break;
5283 case MGN_MCS12: rateIndex = 24; break;
5284 case MGN_MCS13: rateIndex = 25; break;
5285 case MGN_MCS14: rateIndex = 26; break;
5286 case MGN_MCS15: rateIndex = 27; break;
5287 default: rateIndex = 28; break;
5288 }
5289 priv->stats.received_preamble_GI[preamble_guardinterval][rateIndex]++;
5290 priv->stats.received_rate_histogram[0][rateIndex]++; //total
5291 priv->stats.received_rate_histogram[rcvType][rateIndex]++;
5292}
5293
5294
5295void query_rxdesc_status(struct sk_buff *skb, struct ieee80211_rx_stats *stats, bool bIsRxAggrSubframe)
5296{
5297 rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
5298 struct net_device *dev=info->dev;
5299 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
5300 //rx_desc_819x_usb *desc = (rx_desc_819x_usb *)skb->data;
5301 rx_drvinfo_819x_usb *driver_info = NULL;
5302
5303 //
5304 //Get Rx Descriptor Information
5305 //
5306#ifdef USB_RX_AGGREGATION_SUPPORT
5307 if (bIsRxAggrSubframe)
5308 {
5309 rx_desc_819x_usb_aggr_subframe *desc = (rx_desc_819x_usb_aggr_subframe *)skb->data;
5310 stats->Length = desc->Length ;
5311 stats->RxDrvInfoSize = desc->RxDrvInfoSize;
5312 stats->RxBufShift = 0; //RxBufShift = 2 in RxDesc, but usb didn't shift bytes in fact.
5313 stats->bICV = desc->ICV;
5314 stats->bCRC = desc->CRC32;
5315 stats->bHwError = stats->bCRC|stats->bICV;
5316 stats->Decrypted = !desc->SWDec;//RTL8190 set this bit to indicate that Hw does not decrypt packet
5317 } else
5318#endif
5319 {
5320 rx_desc_819x_usb *desc = (rx_desc_819x_usb *)skb->data;
5321
5322 stats->Length = desc->Length;
5323 stats->RxDrvInfoSize = desc->RxDrvInfoSize;
5324 stats->RxBufShift = 0;//desc->Shift&0x03;
5325 stats->bICV = desc->ICV;
5326 stats->bCRC = desc->CRC32;
5327 stats->bHwError = stats->bCRC|stats->bICV;
5328 //RTL8190 set this bit to indicate that Hw does not decrypt packet
5329 stats->Decrypted = !desc->SWDec;
5330 }
5331
5332 if((priv->ieee80211->pHTInfo->bCurrentHTSupport == true) && (priv->ieee80211->pairwise_key_type == KEY_TYPE_CCMP))
5333 {
5334 stats->bHwError = false;
5335 }
5336 else
5337 {
5338 stats->bHwError = stats->bCRC|stats->bICV;
5339 }
5340
5341 if(stats->Length < 24 || stats->Length > MAX_8192U_RX_SIZE)
5342 stats->bHwError |= 1;
5343 //
5344 //Get Driver Info
5345 //
5346 // TODO: Need to verify it on FGPA platform
5347 //Driver info are written to the RxBuffer following rx desc
5348 if (stats->RxDrvInfoSize != 0) {
5349 driver_info = (rx_drvinfo_819x_usb *)(skb->data + sizeof(rx_desc_819x_usb) + \
5350 stats->RxBufShift);
5351 /* unit: 0.5M */
5352 /* TODO */
5353 if(!stats->bHwError){
5354 u8 ret_rate;
5355 ret_rate = HwRateToMRate90(driver_info->RxHT, driver_info->RxRate);
5356 if(ret_rate == 0xff)
5357 {
5358 // Abnormal Case: Receive CRC OK packet with Rx descriptor indicating non supported rate.
5359 // Special Error Handling here, 2008.05.16, by Emily
5360
5361 stats->bHwError = 1;
5362 stats->rate = MGN_1M; //Set 1M rate by default
5363 }else
5364 {
5365 stats->rate = ret_rate;
5366 }
5367 }
5368 else
5369 stats->rate = 0x02;
5370
5371 stats->bShortPreamble = driver_info->SPLCP;
5372
5373
5374 UpdateReceivedRateHistogramStatistics8190(dev, stats);
5375
5376 stats->bIsAMPDU = (driver_info->PartAggr==1);
5377 stats->bFirstMPDU = (driver_info->PartAggr==1) && (driver_info->FirstAGGR==1);
8fc8598e
JC
5378 stats->TimeStampLow = driver_info->TSFL;
5379 // xiong mask it, 070514
5380 //pRfd->Status.TimeStampHigh = PlatformEFIORead4Byte(Adapter, TSFR+4);
5381 // stats->TimeStampHigh = read_nic_dword(dev, TSFR+4);
5382
5383 UpdateRxPktTimeStamp8190(dev, stats);
5384
5385 //
5386 // Rx A-MPDU
5387 //
5388 if(driver_info->FirstAGGR==1 || driver_info->PartAggr == 1)
5389 RT_TRACE(COMP_RXDESC, "driver_info->FirstAGGR = %d, driver_info->PartAggr = %d\n",
5390 driver_info->FirstAGGR, driver_info->PartAggr);
5391
5392 }
5393
5394 skb_pull(skb,sizeof(rx_desc_819x_usb));
5395 //
5396 // Get Total offset of MPDU Frame Body
5397 //
5398 if((stats->RxBufShift + stats->RxDrvInfoSize) > 0) {
5399 stats->bShift = 1;
5400 skb_pull(skb,stats->RxBufShift + stats->RxDrvInfoSize);
5401 }
5402
5403#ifdef USB_RX_AGGREGATION_SUPPORT
589b3d06 5404 /* for the rx aggregated sub frame, the redundant space truly contained in the packet */
8fc8598e
JC
5405 if(bIsRxAggrSubframe) {
5406 skb_pull(skb, 8);
5407 }
5408#endif
5409 /* for debug 2008.5.29 */
8fc8598e
JC
5410
5411 //added by vivi, for MP, 20080108
5412 stats->RxIs40MHzPacket = driver_info->BW;
5413 if(stats->RxDrvInfoSize != 0)
5414 TranslateRxSignalStuff819xUsb(skb, stats, driver_info);
5415
5416}
5417
5418u32 GetRxPacketShiftBytes819xUsb(struct ieee80211_rx_stats *Status, bool bIsRxAggrSubframe)
5419{
5420#ifdef USB_RX_AGGREGATION_SUPPORT
5421 if (bIsRxAggrSubframe)
5422 return (sizeof(rx_desc_819x_usb) + Status->RxDrvInfoSize
5423 + Status->RxBufShift + 8);
5424 else
5425#endif
5426 return (sizeof(rx_desc_819x_usb) + Status->RxDrvInfoSize
5427 + Status->RxBufShift);
5428}
5429
5430void rtl8192_rx_nomal(struct sk_buff* skb)
5431{
5432 rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
5433 struct net_device *dev=info->dev;
5434 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
5435 struct ieee80211_rx_stats stats = {
5436 .signal = 0,
5437 .noise = -98,
5438 .rate = 0,
5439 // .mac_time = jiffies,
5440 .freq = IEEE80211_24GHZ_BAND,
5441 };
5442 u32 rx_pkt_len = 0;
5443 struct ieee80211_hdr_1addr *ieee80211_hdr = NULL;
5444 bool unicast_packet = false;
5445#ifdef USB_RX_AGGREGATION_SUPPORT
5446 struct sk_buff *agg_skb = NULL;
5447 u32 TotalLength = 0;
5448 u32 TempDWord = 0;
5449 u32 PacketLength = 0;
5450 u32 PacketOccupiedLendth = 0;
5451 u8 TempByte = 0;
5452 u32 PacketShiftBytes = 0;
5453 rx_desc_819x_usb_aggr_subframe *RxDescr = NULL;
5454 u8 PaddingBytes = 0;
5455 //add just for testing
5456 u8 testing;
5457
5458#endif
5459
5460 /* 20 is for ps-poll */
5461 if((skb->len >=(20 + sizeof(rx_desc_819x_usb))) && (skb->len < RX_URB_SIZE)) {
5462#ifdef USB_RX_AGGREGATION_SUPPORT
5463 TempByte = *(skb->data + sizeof(rx_desc_819x_usb));
5464#endif
5465 /* first packet should not contain Rx aggregation header */
5466 query_rxdesc_status(skb, &stats, false);
5467 /* TODO */
5468 /* hardware related info */
5469#ifdef USB_RX_AGGREGATION_SUPPORT
5470 if (TempByte & BIT0) {
5471 agg_skb = skb;
5472 //TotalLength = agg_skb->len - 4; /*sCrcLng*/
5473 TotalLength = stats.Length - 4; /*sCrcLng*/
5474 //RT_TRACE(COMP_RECV, "%s:first aggregated packet!Length=%d\n",__FUNCTION__,TotalLength);
5475 /* though the head pointer has passed this position */
5476 TempDWord = *(u32 *)(agg_skb->data - 4);
5477 PacketLength = (u16)(TempDWord & 0x3FFF); /*sCrcLng*/
5478 skb = dev_alloc_skb(PacketLength);
5479 memcpy(skb_put(skb,PacketLength),agg_skb->data,PacketLength);
5480 PacketShiftBytes = GetRxPacketShiftBytes819xUsb(&stats, false);
5481 }
5482#endif
589b3d06 5483 /* Process the MPDU received */
8fc8598e
JC
5484 skb_trim(skb, skb->len - 4/*sCrcLng*/);
5485
5486 rx_pkt_len = skb->len;
5487 ieee80211_hdr = (struct ieee80211_hdr_1addr *)skb->data;
5488 unicast_packet = false;
5489 if(is_broadcast_ether_addr(ieee80211_hdr->addr1)) {
5490 //TODO
5491 }else if(is_multicast_ether_addr(ieee80211_hdr->addr1)){
5492 //TODO
5493 }else {
5494 /* unicast packet */
5495 unicast_packet = true;
5496 }
5497
5498 if(!ieee80211_rx(priv->ieee80211,skb, &stats)) {
5499 dev_kfree_skb_any(skb);
5500 } else {
5501 priv->stats.rxoktotal++;
5502 if(unicast_packet) {
5503 priv->stats.rxbytesunicast += rx_pkt_len;
5504 }
5505 }
5506#ifdef USB_RX_AGGREGATION_SUPPORT
5507 testing = 1;
5508 // (PipeIndex == 0) && (TempByte & BIT0) => TotalLength > 0.
5509 if (TotalLength > 0) {
5510 PacketOccupiedLendth = PacketLength + (PacketShiftBytes + 8);
5511 if ((PacketOccupiedLendth & 0xFF) != 0)
5512 PacketOccupiedLendth = (PacketOccupiedLendth & 0xFFFFFF00) + 256;
5513 PacketOccupiedLendth -= 8;
5514 TempDWord = PacketOccupiedLendth - PacketShiftBytes; /*- PacketLength */
5515 if (agg_skb->len > TempDWord)
5516 skb_pull(agg_skb, TempDWord);
5517 else
5518 agg_skb->len = 0;
5519
5520 while (agg_skb->len>=GetRxPacketShiftBytes819xUsb(&stats, true)) {
5521 u8 tmpCRC = 0, tmpICV = 0;
5522 //RT_TRACE(COMP_RECV,"%s:aggred pkt,total_len = %d\n",__FUNCTION__,agg_skb->len);
5523 RxDescr = (rx_desc_819x_usb_aggr_subframe *)(agg_skb->data);
5524 tmpCRC = RxDescr->CRC32;
5525 tmpICV = RxDescr->ICV;
5526 memcpy(agg_skb->data, &agg_skb->data[44], 2);
5527 RxDescr->CRC32 = tmpCRC;
5528 RxDescr->ICV = tmpICV;
5529
5530 memset(&stats, 0, sizeof(struct ieee80211_rx_stats));
5531 stats.signal = 0;
5532 stats.noise = -98;
5533 stats.rate = 0;
5534 stats.freq = IEEE80211_24GHZ_BAND;
5535 query_rxdesc_status(agg_skb, &stats, true);
5536 PacketLength = stats.Length;
5537
5538 if(PacketLength > agg_skb->len) {
5539 break;
5540 }
589b3d06 5541 /* Process the MPDU received */
8fc8598e
JC
5542 skb = dev_alloc_skb(PacketLength);
5543 memcpy(skb_put(skb,PacketLength),agg_skb->data, PacketLength);
5544 skb_trim(skb, skb->len - 4/*sCrcLng*/);
5545
5546 rx_pkt_len = skb->len;
5547 ieee80211_hdr = (struct ieee80211_hdr_1addr *)skb->data;
5548 unicast_packet = false;
5549 if(is_broadcast_ether_addr(ieee80211_hdr->addr1)) {
5550 //TODO
5551 }else if(is_multicast_ether_addr(ieee80211_hdr->addr1)){
5552 //TODO
5553 }else {
5554 /* unicast packet */
5555 unicast_packet = true;
5556 }
5557 if(!ieee80211_rx(priv->ieee80211,skb, &stats)) {
5558 dev_kfree_skb_any(skb);
5559 } else {
5560 priv->stats.rxoktotal++;
5561 if(unicast_packet) {
5562 priv->stats.rxbytesunicast += rx_pkt_len;
5563 }
5564 }
5565 /* should trim the packet which has been copied to target skb */
5566 skb_pull(agg_skb, PacketLength);
5567 PacketShiftBytes = GetRxPacketShiftBytes819xUsb(&stats, true);
5568 PacketOccupiedLendth = PacketLength + PacketShiftBytes;
5569 if ((PacketOccupiedLendth & 0xFF) != 0) {
5570 PaddingBytes = 256 - (PacketOccupiedLendth & 0xFF);
5571 if (agg_skb->len > PaddingBytes)
5572 skb_pull(agg_skb, PaddingBytes);
5573 else
5574 agg_skb->len = 0;
5575 }
5576 }
5577 dev_kfree_skb(agg_skb);
5578 }
5579#endif
5580 } else {
5581 priv->stats.rxurberr++;
5582 printk("actual_length:%d\n", skb->len);
5583 dev_kfree_skb_any(skb);
5584 }
5585
5586}
5587
5588void
5589rtl819xusb_process_received_packet(
5590 struct net_device *dev,
5591 struct ieee80211_rx_stats *pstats
5592 )
5593{
5594// bool bfreerfd=false, bqueued=false;
5595 u8* frame;
5596 u16 frame_len=0;
5597 struct r8192_priv *priv = ieee80211_priv(dev);
5598// u8 index = 0;
5599// u8 TID = 0;
5600 //u16 seqnum = 0;
5601 //PRX_TS_RECORD pts = NULL;
5602
5603 // Get shifted bytes of Starting address of 802.11 header. 2006.09.28, by Emily
5604 //porting by amy 080508
5605 pstats->virtual_address += get_rxpacket_shiftbytes_819xusb(pstats);
5606 frame = pstats->virtual_address;
5607 frame_len = pstats->packetlength;
5608#ifdef TODO // by amy about HCT
5609 if(!Adapter->bInHctTest)
5610 CountRxErrStatistics(Adapter, pRfd);
5611#endif
5612 {
5613 #ifdef ENABLE_PS //by amy for adding ps function in future
5614 RT_RF_POWER_STATE rtState;
5615 // When RF is off, we should not count the packet for hw/sw synchronize
5616 // reason, ie. there may be a duration while sw switch is changed and hw
5617 // switch is being changed. 2006.12.04, by shien chang.
5618 Adapter->HalFunc.GetHwRegHandler(Adapter, HW_VAR_RF_STATE, (u8* )(&rtState));
5619 if (rtState == eRfOff)
5620 {
5621 return;
5622 }
5623 #endif
5624 priv->stats.rxframgment++;
5625
5626 }
5627#ifdef TODO
5628 RmMonitorSignalStrength(Adapter, pRfd);
5629#endif
5630 /* 2007/01/16 MH Add RX command packet handle here. */
5631 /* 2007/03/01 MH We have to release RFD and return if rx pkt is cmd pkt. */
5632 if (rtl819xusb_rx_command_packet(dev, pstats))
5633 {
5634 return;
5635 }
5636
5637#ifdef SW_CRC_CHECK
5638 SwCrcCheck();
5639#endif
5640
5641
5642}
5643
5644void query_rx_cmdpkt_desc_status(struct sk_buff *skb, struct ieee80211_rx_stats *stats)
5645{
5646// rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
5647// struct net_device *dev=info->dev;
5648// struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
5649 rx_desc_819x_usb *desc = (rx_desc_819x_usb *)skb->data;
5650// rx_drvinfo_819x_usb *driver_info;
5651
5652 //
5653 //Get Rx Descriptor Information
5654 //
5655 stats->virtual_address = (u8*)skb->data;
5656 stats->Length = desc->Length;
5657 stats->RxDrvInfoSize = 0;
5658 stats->RxBufShift = 0;
5659 stats->packetlength = stats->Length-scrclng;
5660 stats->fraglength = stats->packetlength;
5661 stats->fragoffset = 0;
5662 stats->ntotalfrag = 1;
5663}
5664
5665
5666void rtl8192_rx_cmd(struct sk_buff *skb)
5667{
5668 struct rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
5669 struct net_device *dev = info->dev;
5670 //int ret;
5671// struct urb *rx_urb = info->urb;
5672 /* TODO */
5673 struct ieee80211_rx_stats stats = {
5674 .signal = 0,
5675 .noise = -98,
5676 .rate = 0,
5677 // .mac_time = jiffies,
5678 .freq = IEEE80211_24GHZ_BAND,
5679 };
5680
5681 if((skb->len >=(20 + sizeof(rx_desc_819x_usb))) && (skb->len < RX_URB_SIZE))
5682 {
5683
5684 query_rx_cmdpkt_desc_status(skb,&stats);
5685 // this is to be done by amy 080508 prfd->queue_id = 1;
5686
5687
5688 //
5689 // Process the command packet received.
5690 //
5691
5692 rtl819xusb_process_received_packet(dev,&stats);
5693
5694 dev_kfree_skb_any(skb);
5695 }
5696 else
5697 ;
5698
5699
8fc8598e
JC
5700}
5701
5702void rtl8192_irq_rx_tasklet(struct r8192_priv *priv)
5703{
e406322b 5704 struct sk_buff *skb;
8fc8598e
JC
5705 struct rtl8192_rx_info *info;
5706
e406322b 5707 while (NULL != (skb = skb_dequeue(&priv->skb_queue))) {
8fc8598e 5708 info = (struct rtl8192_rx_info *)skb->cb;
e406322b 5709 switch (info->out_pipe) {
8fc8598e
JC
5710 /* Nomal packet pipe */
5711 case 3:
5712 //RT_TRACE(COMP_RECV, "normal in-pipe index(%d)\n",info->out_pipe);
5713 priv->IrpPendingCount--;
5714 rtl8192_rx_nomal(skb);
5715 break;
5716
5717 /* Command packet pipe */
5718 case 9:
5719 RT_TRACE(COMP_RECV, "command in-pipe index(%d)\n",\
5720 info->out_pipe);
5721
5722 rtl8192_rx_cmd(skb);
5723 break;
5724
5725 default: /* should never get here! */
5726 RT_TRACE(COMP_ERR, "Unknown in-pipe index(%d)\n",\
5727 info->out_pipe);
5728 dev_kfree_skb(skb);
5729 break;
5730
5731 }
e406322b 5732 }
8fc8598e
JC
5733}
5734
f61fb935
MCC
5735static const struct net_device_ops rtl8192_netdev_ops = {
5736 .ndo_open = rtl8192_open,
5737 .ndo_stop = rtl8192_close,
5738 .ndo_get_stats = rtl8192_stats,
5739 .ndo_tx_timeout = tx_timeout,
5740 .ndo_do_ioctl = rtl8192_ioctl,
afc4b13d 5741 .ndo_set_rx_mode = r8192_set_multicast,
f61fb935
MCC
5742 .ndo_set_mac_address = r8192_set_mac_adr,
5743 .ndo_validate_addr = eth_validate_addr,
5744 .ndo_change_mtu = eth_change_mtu,
5745 .ndo_start_xmit = ieee80211_xmit,
5746};
8fc8598e
JC
5747
5748
5749/****************************************************************************
5750 ---------------------------- USB_STUFF---------------------------
5751*****************************************************************************/
5752
8fc8598e
JC
5753static int __devinit rtl8192_usb_probe(struct usb_interface *intf,
5754 const struct usb_device_id *id)
8fc8598e
JC
5755{
5756// unsigned long ioaddr = 0;
5757 struct net_device *dev = NULL;
5758 struct r8192_priv *priv= NULL;
8fc8598e 5759 struct usb_device *udev = interface_to_usbdev(intf);
2fac6c29 5760 int ret;
e406322b 5761 RT_TRACE(COMP_INIT, "Oops: i'm coming\n");
8fc8598e
JC
5762
5763 dev = alloc_ieee80211(sizeof(struct r8192_priv));
2fac6c29
VK
5764 if (dev == NULL)
5765 return -ENOMEM;
8fc8598e 5766
8fc8598e
JC
5767 usb_set_intfdata(intf, dev);
5768 SET_NETDEV_DEV(dev, &intf->dev);
8fc8598e 5769 priv = ieee80211_priv(dev);
8fc8598e 5770 priv->ieee80211 = netdev_priv(dev);
8fc8598e
JC
5771 priv->udev=udev;
5772
e406322b 5773 dev->netdev_ops = &rtl8192_netdev_ops;
8fc8598e 5774
e406322b 5775 //DMESG("Oops: i'm coming\n");
8fc8598e
JC
5776#if WIRELESS_EXT >= 12
5777#if WIRELESS_EXT < 17
e406322b 5778 dev->get_wireless_stats = r8192_get_wireless_stats;
8fc8598e 5779#endif
e406322b 5780 dev->wireless_handlers = (struct iw_handler_def *) &r8192_wx_handlers_def;
8fc8598e
JC
5781#endif
5782 dev->type=ARPHRD_ETHER;
5783
5784 dev->watchdog_timeo = HZ*3; //modified by john, 0805
5785
5786 if (dev_alloc_name(dev, ifname) < 0){
e406322b 5787 RT_TRACE(COMP_INIT, "Oops: devname already taken! Trying wlan%%d...\n");
8fc8598e
JC
5788 ifname = "wlan%d";
5789 dev_alloc_name(dev, ifname);
e406322b 5790 }
8fc8598e
JC
5791
5792 RT_TRACE(COMP_INIT, "Driver probe completed1\n");
8fc8598e
JC
5793 if(rtl8192_init(dev)!=0){
5794 RT_TRACE(COMP_ERR, "Initialization failed");
2fac6c29 5795 ret = -ENODEV;
8fc8598e
JC
5796 goto fail;
5797 }
8fc8598e
JC
5798 netif_carrier_off(dev);
5799 netif_stop_queue(dev);
5800
2fac6c29
VK
5801 ret = register_netdev(dev);
5802 if (ret)
5803 goto fail2;
5804
8fc8598e
JC
5805 RT_TRACE(COMP_INIT, "dev name=======> %s\n",dev->name);
5806 rtl8192_proc_init_one(dev);
5807
5808
5809 RT_TRACE(COMP_INIT, "Driver probe completed\n");
8fc8598e 5810 return 0;
8fc8598e 5811
2fac6c29
VK
5812fail2:
5813 rtl8192_down(dev);
e72714fb
IM
5814 kfree(priv->pFirmware);
5815 priv->pFirmware = NULL;
2fac6c29
VK
5816 rtl8192_usb_deleteendpoints(dev);
5817 destroy_workqueue(priv->priv_wq);
5818 mdelay(10);
8fc8598e
JC
5819fail:
5820 free_ieee80211(dev);
5821
5822 RT_TRACE(COMP_ERR, "wlan driver load failed\n");
2fac6c29 5823 return ret;
8fc8598e
JC
5824}
5825
5826//detach all the work and timer structure declared or inititialize in r8192U_init function.
5827void rtl8192_cancel_deferred_work(struct r8192_priv* priv)
5828{
5829
8fc8598e
JC
5830 cancel_work_sync(&priv->reset_wq);
5831 cancel_delayed_work(&priv->watch_dog_wq);
5832 cancel_delayed_work(&priv->update_beacon_wq);
5833 cancel_work_sync(&priv->qos_activate);
5834 //cancel_work_sync(&priv->SetBWModeWorkItem);
5835 //cancel_work_sync(&priv->SwChnlWorkItem);
8fc8598e
JC
5836
5837}
5838
5839
8fc8598e 5840static void __devexit rtl8192_usb_disconnect(struct usb_interface *intf)
8fc8598e 5841{
8fc8598e 5842 struct net_device *dev = usb_get_intfdata(intf);
8fc8598e
JC
5843
5844 struct r8192_priv *priv = ieee80211_priv(dev);
e406322b 5845 if(dev){
8fc8598e
JC
5846
5847 unregister_netdev(dev);
5848
5849 RT_TRACE(COMP_DOWN, "=============>wlan driver to be removed\n");
5850 rtl8192_proc_remove_one(dev);
5851
5852 rtl8192_down(dev);
e72714fb
IM
5853 kfree(priv->pFirmware);
5854 priv->pFirmware = NULL;
8fc8598e
JC
5855 // priv->rf_close(dev);
5856// rtl8192_SetRFPowerState(dev, eRfOff);
5857 rtl8192_usb_deleteendpoints(dev);
8fc8598e 5858 destroy_workqueue(priv->priv_wq);
8fc8598e
JC
5859 //rtl8192_irq_disable(dev);
5860 //rtl8192_reset(dev);
5861 mdelay(10);
5862
5863 }
5864 free_ieee80211(dev);
5865 RT_TRACE(COMP_DOWN, "wlan driver removed\n");
5866}
5867
f61fb935
MCC
5868/* fun with the built-in ieee80211 stack... */
5869extern int ieee80211_debug_init(void);
5870extern void ieee80211_debug_exit(void);
5871extern int ieee80211_crypto_init(void);
5872extern void ieee80211_crypto_deinit(void);
5873extern int ieee80211_crypto_tkip_init(void);
5874extern void ieee80211_crypto_tkip_exit(void);
5875extern int ieee80211_crypto_ccmp_init(void);
5876extern void ieee80211_crypto_ccmp_exit(void);
5877extern int ieee80211_crypto_wep_init(void);
5878extern void ieee80211_crypto_wep_exit(void);
8fc8598e
JC
5879
5880static int __init rtl8192_usb_module_init(void)
5881{
e406322b 5882 int ret;
f61fb935
MCC
5883
5884#ifdef CONFIG_IEEE80211_DEBUG
e406322b
MCC
5885 ret = ieee80211_debug_init();
5886 if (ret) {
5887 printk(KERN_ERR "ieee80211_debug_init() failed %d\n", ret);
5888 return ret;
5889 }
f61fb935 5890#endif
e406322b
MCC
5891 ret = ieee80211_crypto_init();
5892 if (ret) {
5893 printk(KERN_ERR "ieee80211_crypto_init() failed %d\n", ret);
5894 return ret;
5895 }
f61fb935 5896
e406322b
MCC
5897 ret = ieee80211_crypto_tkip_init();
5898 if (ret) {
5899 printk(KERN_ERR "ieee80211_crypto_tkip_init() failed %d\n",
5900 ret);
5901 return ret;
5902 }
f61fb935 5903
e406322b
MCC
5904 ret = ieee80211_crypto_ccmp_init();
5905 if (ret) {
5906 printk(KERN_ERR "ieee80211_crypto_ccmp_init() failed %d\n",
5907 ret);
5908 return ret;
5909 }
f61fb935 5910
e406322b
MCC
5911 ret = ieee80211_crypto_wep_init();
5912 if (ret) {
5913 printk(KERN_ERR "ieee80211_crypto_wep_init() failed %d\n", ret);
5914 return ret;
5915 }
f61fb935 5916
8fc8598e
JC
5917 printk(KERN_INFO "\nLinux kernel driver for RTL8192 based WLAN cards\n");
5918 printk(KERN_INFO "Copyright (c) 2007-2008, Realsil Wlan\n");
5919 RT_TRACE(COMP_INIT, "Initializing module");
5920 RT_TRACE(COMP_INIT, "Wireless extensions version %d", WIRELESS_EXT);
5921 rtl8192_proc_module_init();
5922 return usb_register(&rtl8192_usb_driver);
5923}
5924
5925
5926static void __exit rtl8192_usb_module_exit(void)
5927{
5928 usb_deregister(&rtl8192_usb_driver);
5929
5930 RT_TRACE(COMP_DOWN, "Exiting");
5931// rtl8192_proc_module_remove();
5932}
5933
5934
5935void rtl8192_try_wake_queue(struct net_device *dev, int pri)
5936{
5937 unsigned long flags;
5938 short enough_desc;
5939 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
5940
5941 spin_lock_irqsave(&priv->tx_lock,flags);
5942 enough_desc = check_nic_enough_desc(dev,pri);
e406322b 5943 spin_unlock_irqrestore(&priv->tx_lock,flags);
8fc8598e
JC
5944
5945 if(enough_desc)
5946 ieee80211_wake_queue(priv->ieee80211);
5947}
5948
5949void EnableHWSecurityConfig8192(struct net_device *dev)
5950{
e406322b 5951 u8 SECR_value = 0x0;
8fc8598e
JC
5952 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
5953 struct ieee80211_device* ieee = priv->ieee80211;
5954 SECR_value = SCR_TxEncEnable | SCR_RxDecEnable;
8fc8598e
JC
5955 if (((KEY_TYPE_WEP40 == ieee->pairwise_key_type) || (KEY_TYPE_WEP104 == ieee->pairwise_key_type)) && (priv->ieee80211->auth_mode != 2))
5956 {
5957 SECR_value |= SCR_RxUseDK;
5958 SECR_value |= SCR_TxUseDK;
5959 }
5960 else if ((ieee->iw_mode == IW_MODE_ADHOC) && (ieee->pairwise_key_type & (KEY_TYPE_CCMP | KEY_TYPE_TKIP)))
5961 {
5962 SECR_value |= SCR_RxUseDK;
5963 SECR_value |= SCR_TxUseDK;
5964 }
e406322b 5965 //add HWSec active enable here.
8fc8598e
JC
5966//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
5967
5968 ieee->hwsec_active = 1;
5969
5970 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
5971 {
5972 ieee->hwsec_active = 0;
5973 SECR_value &= ~SCR_RxDecEnable;
5974 }
5975 RT_TRACE(COMP_SEC,"%s:, hwsec:%d, pairwise_key:%d, SECR_value:%x\n", __FUNCTION__, \
5976 ieee->hwsec_active, ieee->pairwise_key_type, SECR_value);
5977 {
e406322b
MCC
5978 write_nic_byte(dev, SECR, SECR_value);//SECR_value | SCR_UseDK );
5979 }
8fc8598e
JC
5980}
5981
5982
5983void setKey( struct net_device *dev,
5984 u8 EntryNo,
5985 u8 KeyIndex,
5986 u16 KeyType,
5987 u8 *MacAddr,
5988 u8 DefaultKey,
5989 u32 *KeyContent )
5990{
5991 u32 TargetCommand = 0;
5992 u32 TargetContent = 0;
5993 u16 usConfig = 0;
5994 u8 i;
5995 if (EntryNo >= TOTAL_CAM_ENTRY)
5996 RT_TRACE(COMP_ERR, "cam entry exceeds in setKey()\n");
5997
0ee9f67c 5998 RT_TRACE(COMP_SEC, "====>to setKey(), dev:%p, EntryNo:%d, KeyIndex:%d, KeyType:%d, MacAddr%pM\n", dev,EntryNo, KeyIndex, KeyType, MacAddr);
8fc8598e
JC
5999
6000 if (DefaultKey)
6001 usConfig |= BIT15 | (KeyType<<2);
6002 else
6003 usConfig |= BIT15 | (KeyType<<2) | KeyIndex;
6004// usConfig |= BIT15 | (KeyType<<2) | (DefaultKey<<5) | KeyIndex;
6005
6006
6007 for(i=0 ; i<CAM_CONTENT_COUNT; i++){
6008 TargetCommand = i+CAM_CONTENT_COUNT*EntryNo;
6009 TargetCommand |= BIT31|BIT16;
6010
6011 if(i==0){//MAC|Config
6012 TargetContent = (u32)(*(MacAddr+0)) << 16|
6013 (u32)(*(MacAddr+1)) << 24|
6014 (u32)usConfig;
6015
6016 write_nic_dword(dev, WCAMI, TargetContent);
6017 write_nic_dword(dev, RWCAM, TargetCommand);
6018 // printk("setkey cam =%8x\n", read_cam(dev, i+6*EntryNo));
6019 }
6020 else if(i==1){//MAC
e406322b
MCC
6021 TargetContent = (u32)(*(MacAddr+2)) |
6022 (u32)(*(MacAddr+3)) << 8|
6023 (u32)(*(MacAddr+4)) << 16|
6024 (u32)(*(MacAddr+5)) << 24;
8fc8598e
JC
6025 write_nic_dword(dev, WCAMI, TargetContent);
6026 write_nic_dword(dev, RWCAM, TargetCommand);
6027 }
6028 else {
6029 //Key Material
6030 if(KeyContent !=NULL){
6031 write_nic_dword(dev, WCAMI, (u32)(*(KeyContent+i-2)) );
6032 write_nic_dword(dev, RWCAM, TargetCommand);
6033 }
6034 }
6035 }
6036
6037}
6038
6039/***************************************************************************
6040 ------------------- module init / exit stubs ----------------
6041****************************************************************************/
6042module_init(rtl8192_usb_module_init);
6043module_exit(rtl8192_usb_module_exit);