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