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