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