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