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