staging: rtl8192e: Remove commented function rtl8192_set_mode()
[deliverable/linux.git] / drivers / staging / rtl8192e / r8192E_core.c
CommitLineData
ecdfa446
GKH
1/******************************************************************************
2 * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
3 * Linux device driver for RTL8190P / RTL8192E
4 *
5 * Based on the r8180 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
ecdfa446
GKH
27
28#undef LOOP_TEST
29#undef RX_DONT_PASS_UL
30#undef DEBUG_EPROM
31#undef DEBUG_RX_VERBOSE
32#undef DUMMY_RX
33#undef DEBUG_ZERO_RX
34#undef DEBUG_RX_SKB
35#undef DEBUG_TX_FRAG
36#undef DEBUG_RX_FRAG
37#undef DEBUG_TX_FILLDESC
38#undef DEBUG_TX
39#undef DEBUG_IRQ
40#undef DEBUG_RX
41#undef DEBUG_RXALLOC
42#undef DEBUG_REGISTERS
43#undef DEBUG_RING
44#undef DEBUG_IRQ_TASKLET
45#undef DEBUG_TX_ALLOC
46#undef DEBUG_TX_DESC
47
48//#define CONFIG_RTL8192_IO_MAP
3d14b518 49#include <linux/vmalloc.h>
5a0e3ad6 50#include <linux/slab.h>
ecdfa446
GKH
51#include <asm/uaccess.h>
52#include "r8192E_hw.h"
53#include "r8192E.h"
54#include "r8190_rtl8256.h" /* RTL8225 Radio frontend */
55#include "r8180_93cx6.h" /* Card EEPROM */
56#include "r8192E_wx.h"
57#include "r819xE_phy.h" //added by WB 4.30.2008
58#include "r819xE_phyreg.h"
59#include "r819xE_cmdpkt.h"
60#include "r8192E_dm.h"
ecdfa446 61
bebdf809 62#ifdef CONFIG_PM
ecdfa446
GKH
63#include "r8192_pm.h"
64#endif
65
66#ifdef ENABLE_DOT11D
65a43784 67#include "ieee80211/dot11d.h"
ecdfa446
GKH
68#endif
69
70//set here to open your trace code. //WB
207b58fb 71u32 rt_global_debug_component =
ecdfa446
GKH
72 // COMP_INIT |
73 // COMP_EPROM |
74 // COMP_PHY |
75 // COMP_RF |
65a43784 76// COMP_FIRMWARE |
ecdfa446
GKH
77 // COMP_TRACE |
78 // COMP_DOWN |
79 // COMP_SWBW |
80 // COMP_SEC |
81// COMP_QOS |
82// COMP_RATE |
83 // COMP_RECV |
84 // COMP_SEND |
85 // COMP_POWER |
86 // COMP_EVENTS |
87 // COMP_RESET |
88 // COMP_CMDPKT |
89 // COMP_POWER_TRACKING |
90 // COMP_INTR |
91 COMP_ERR ; //always open err flags on
cf3d3d38 92
881a975b 93static const struct pci_device_id rtl8192_pci_id_tbl[] __devinitdata = {
ecdfa446
GKH
94#ifdef RTL8190P
95 /* Realtek */
96 /* Dlink */
97 { PCI_DEVICE(0x10ec, 0x8190) },
98 /* Corega */
99 { PCI_DEVICE(0x07aa, 0x0045) },
100 { PCI_DEVICE(0x07aa, 0x0046) },
101#else
102 /* Realtek */
103 { PCI_DEVICE(0x10ec, 0x8192) },
104
105 /* Corega */
106 { PCI_DEVICE(0x07aa, 0x0044) },
107 { PCI_DEVICE(0x07aa, 0x0047) },
108#endif
109 {}
110};
111
dca41306 112static char ifname[IFNAMSIZ] = "wlan%d";
ecdfa446
GKH
113static int hwwep = 1; //default use hw. set 0 to use software security
114static int channels = 0x3fff;
115
116MODULE_LICENSE("GPL");
ecdfa446 117MODULE_VERSION("V 1.1");
ecdfa446
GKH
118MODULE_DEVICE_TABLE(pci, rtl8192_pci_id_tbl);
119//MODULE_AUTHOR("Andrea Merello <andreamrl@tiscali.it>");
120MODULE_DESCRIPTION("Linux driver for Realtek RTL819x WiFi cards");
121
ecdfa446 122
dca41306 123module_param_string(ifname, ifname, sizeof(ifname), S_IRUGO|S_IWUSR);
ecdfa446
GKH
124module_param(hwwep,int, S_IRUGO|S_IWUSR);
125module_param(channels,int, S_IRUGO|S_IWUSR);
ecdfa446
GKH
126
127MODULE_PARM_DESC(ifname," Net interface name, wlan%d=default");
ecdfa446
GKH
128MODULE_PARM_DESC(hwwep," Try to use hardware WEP support. Still broken and not available on all cards");
129MODULE_PARM_DESC(channels," Channel bitmask for specific locales. NYI");
130
131static int __devinit rtl8192_pci_probe(struct pci_dev *pdev,
132 const struct pci_device_id *id);
133static void __devexit rtl8192_pci_disconnect(struct pci_dev *pdev);
134
135static struct pci_driver rtl8192_pci_driver = {
136 .name = RTL819xE_MODULE_NAME, /* Driver name */
137 .id_table = rtl8192_pci_id_tbl, /* PCI_ID table */
138 .probe = rtl8192_pci_probe, /* probe fn */
139 .remove = __devexit_p(rtl8192_pci_disconnect), /* remove fn */
bebdf809 140#ifdef CONFIG_PM
ecdfa446
GKH
141 .suspend = rtl8192E_suspend, /* PM suspend fn */
142 .resume = rtl8192E_resume, /* PM resume fn */
143#else
144 .suspend = NULL, /* PM suspend fn */
214985a6 145 .resume = NULL, /* PM resume fn */
ecdfa446 146#endif
ecdfa446
GKH
147};
148
559fba5e
MM
149static void rtl8192_start_beacon(struct net_device *dev);
150static void rtl8192_stop_beacon(struct net_device *dev);
151static void rtl819x_watchdog_wqcallback(struct work_struct *work);
152static void rtl8192_irq_rx_tasklet(struct r8192_priv *priv);
153static void rtl8192_irq_tx_tasklet(struct r8192_priv *priv);
154static void rtl8192_prepare_beacon(struct r8192_priv *priv);
155static irqreturn_t rtl8192_interrupt(int irq, void *netdev);
156static void rtl8192_try_wake_queue(struct net_device *dev, int pri);
881a975b 157static void rtl819xE_tx_cmd(struct net_device *dev, struct sk_buff *skb);
5b3b1a7b
MM
158static void rtl8192_update_ratr_table(struct net_device* dev);
159static void rtl8192_restart(struct work_struct *work);
160static void watch_dog_timer_callback(unsigned long data);
161static int _rtl8192_up(struct net_device *dev);
162static void rtl8192_cancel_deferred_work(struct r8192_priv* priv);
559fba5e 163
ecdfa446
GKH
164#ifdef ENABLE_DOT11D
165
166typedef struct _CHANNEL_LIST
167{
168 u8 Channel[32];
169 u8 Len;
170}CHANNEL_LIST, *PCHANNEL_LIST;
171
ab2161a0 172static const CHANNEL_LIST ChannelPlan[] = {
ecdfa446
GKH
173 {{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
174 {{1,2,3,4,5,6,7,8,9,10,11},11}, //IC
175 {{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48,52,56,60,64},21}, //ETSI
176 {{1,2,3,4,5,6,7,8,9,10,11,12,13},13}, //Spain. Change to ETSI.
177 {{1,2,3,4,5,6,7,8,9,10,11,12,13},13}, //France. Change to ETSI.
178 {{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
179 {{1,2,3,4,5,6,7,8,9,10,11,12,13,14,36,40,44,48,52,56,60,64},22},//MKK1
180 {{1,2,3,4,5,6,7,8,9,10,11,12,13},13}, //Israel.
181 {{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
182 {{1,2,3,4,5,6,7,8,9,10,11,12,13,14,36,40,44,48,52,56,60,64}, 22}, //MIC
183 {{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
184};
185
186static void rtl819x_set_channel_map(u8 channel_plan, struct r8192_priv* priv)
187{
188 int i, max_chan=-1, min_chan=-1;
189 struct ieee80211_device* ieee = priv->ieee80211;
190 switch (channel_plan)
191 {
192 case COUNTRY_CODE_FCC:
193 case COUNTRY_CODE_IC:
194 case COUNTRY_CODE_ETSI:
195 case COUNTRY_CODE_SPAIN:
196 case COUNTRY_CODE_FRANCE:
197 case COUNTRY_CODE_MKK:
198 case COUNTRY_CODE_MKK1:
199 case COUNTRY_CODE_ISRAEL:
200 case COUNTRY_CODE_TELEC:
201 case COUNTRY_CODE_MIC:
202 {
203 Dot11d_Init(ieee);
204 ieee->bGlobalDomain = false;
205 //acturally 8225 & 8256 rf chip only support B,G,24N mode
206 if ((priv->rf_chip == RF_8225) || (priv->rf_chip == RF_8256))
207 {
208 min_chan = 1;
209 max_chan = 14;
210 }
211 else
212 {
213 RT_TRACE(COMP_ERR, "unknown rf chip, can't set channel map in function:%s()\n", __FUNCTION__);
214 }
215 if (ChannelPlan[channel_plan].Len != 0){
216 // Clear old channel map
217 memset(GET_DOT11D_INFO(ieee)->channel_map, 0, sizeof(GET_DOT11D_INFO(ieee)->channel_map));
218 // Set new channel map
219 for (i=0;i<ChannelPlan[channel_plan].Len;i++)
220 {
221 if (ChannelPlan[channel_plan].Channel[i] < min_chan || ChannelPlan[channel_plan].Channel[i] > max_chan)
222 break;
223 GET_DOT11D_INFO(ieee)->channel_map[ChannelPlan[channel_plan].Channel[i]] = 1;
224 }
225 }
226 break;
227 }
228 case COUNTRY_CODE_GLOBAL_DOMAIN:
229 {
230 GET_DOT11D_INFO(ieee)->bEnabled = 0; //this flag enabled to follow 11d country IE setting, otherwise, it shall follow global domain setting
231 Dot11d_Reset(ieee);
232 ieee->bGlobalDomain = true;
233 break;
234 }
235 default:
236 break;
237 }
238}
239#endif
240
241
242#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 )
243/* 2007/07/25 MH Defien temp tx fw info. */
5e1ad18a 244static TX_FWINFO_T Tmp_TxFwInfo;
ecdfa446
GKH
245
246
247#define rx_hal_is_cck_rate(_pdrvinfo)\
248 (_pdrvinfo->RxRate == DESC90_RATE1M ||\
249 _pdrvinfo->RxRate == DESC90_RATE2M ||\
250 _pdrvinfo->RxRate == DESC90_RATE5_5M ||\
251 _pdrvinfo->RxRate == DESC90_RATE11M) &&\
252 !_pdrvinfo->RxHT\
253
254
255void CamResetAllEntry(struct net_device *dev)
256{
257 //u8 ucIndex;
258 u32 ulcommand = 0;
259
260#if 1
261 ulcommand |= BIT31|BIT30;
262 write_nic_dword(dev, RWCAM, ulcommand);
263#else
264 for(ucIndex=0;ucIndex<TOTAL_CAM_ENTRY;ucIndex++)
265 CAM_mark_invalid(dev, ucIndex);
266 for(ucIndex=0;ucIndex<TOTAL_CAM_ENTRY;ucIndex++)
267 CAM_empty_entry(dev, ucIndex);
268#endif
269}
270
271
272void write_cam(struct net_device *dev, u8 addr, u32 data)
273{
274 write_nic_dword(dev, WCAMI, data);
275 write_nic_dword(dev, RWCAM, BIT31|BIT16|(addr&0xff) );
276}
277u32 read_cam(struct net_device *dev, u8 addr)
278{
279 write_nic_dword(dev, RWCAM, 0x80000000|(addr&0xff) );
280 return read_nic_dword(dev, 0xa8);
281}
282
ecdfa446
GKH
283#ifdef CONFIG_RTL8180_IO_MAP
284
285u8 read_nic_byte(struct net_device *dev, int x)
286{
287 return 0xff&inb(dev->base_addr +x);
288}
289
290u32 read_nic_dword(struct net_device *dev, int x)
291{
292 return inl(dev->base_addr +x);
293}
294
295u16 read_nic_word(struct net_device *dev, int x)
296{
297 return inw(dev->base_addr +x);
298}
299
300void write_nic_byte(struct net_device *dev, int x,u8 y)
301{
302 outb(y&0xff,dev->base_addr +x);
303}
304
305void write_nic_word(struct net_device *dev, int x,u16 y)
306{
307 outw(y,dev->base_addr +x);
308}
309
310void write_nic_dword(struct net_device *dev, int x,u32 y)
311{
312 outl(y,dev->base_addr +x);
313}
314
315#else /* RTL_IO_MAP */
316
317u8 read_nic_byte(struct net_device *dev, int x)
318{
319 return 0xff&readb((u8*)dev->mem_start +x);
320}
321
322u32 read_nic_dword(struct net_device *dev, int x)
323{
324 return readl((u8*)dev->mem_start +x);
325}
326
327u16 read_nic_word(struct net_device *dev, int x)
328{
329 return readw((u8*)dev->mem_start +x);
330}
331
332void write_nic_byte(struct net_device *dev, int x,u8 y)
333{
334 writeb(y,(u8*)dev->mem_start +x);
335 udelay(20);
336}
337
338void write_nic_dword(struct net_device *dev, int x,u32 y)
339{
340 writel(y,(u8*)dev->mem_start +x);
341 udelay(20);
342}
343
344void write_nic_word(struct net_device *dev, int x,u16 y)
345{
346 writew(y,(u8*)dev->mem_start +x);
347 udelay(20);
348}
349
350#endif /* RTL_IO_MAP */
351
65a43784 352u8 rtl8192e_ap_sec_type(struct ieee80211_device *ieee)
353{
354 //struct r8192_priv* priv = ieee80211_priv(dev);
355 //struct ieee80211_device *ieee = priv->ieee80211;
356
4a533365
MM
357 static const u8 ccmp_ie[4] = {0x00,0x50,0xf2,0x04};
358 static const u8 ccmp_rsn_ie[4] = {0x00, 0x0f, 0xac, 0x04};
65a43784 359 int wpa_ie_len= ieee->wpa_ie_len;
360 struct ieee80211_crypt_data* crypt;
361 int encrypt;
362
363 crypt = ieee->crypt[ieee->tx_keyidx];
364
207b58fb
MM
365 encrypt = (ieee->current_network.capability & WLAN_CAPABILITY_PRIVACY) ||
366 (ieee->host_encrypt && crypt && crypt->ops &&
65a43784 367 (0 == strcmp(crypt->ops->name,"WEP")));
368
369 /* simply judge */
370 if(encrypt && (wpa_ie_len == 0)) {
371 // wep encryption, no N mode setting */
372 return SEC_ALG_WEP;
373 } else if((wpa_ie_len != 0)) {
374 // parse pairwise key type */
375 if (((ieee->wpa_ie[0] == 0xdd) && (!memcmp(&(ieee->wpa_ie[14]),ccmp_ie,4))) ||
376 ((ieee->wpa_ie[0] == 0x30) && (!memcmp(&ieee->wpa_ie[10],ccmp_rsn_ie, 4))))
377 return SEC_ALG_CCMP;
378 else
379 return SEC_ALG_TKIP;
380 } else {
381 return SEC_ALG_NONE;
382 }
383}
384
385void
386rtl8192e_SetHwReg(struct net_device *dev,u8 variable,u8* val)
387{
388 struct r8192_priv* priv = ieee80211_priv(dev);
389
390 switch(variable)
391 {
392
393 case HW_VAR_BSSID:
394 write_nic_dword(dev, BSSIDR, ((u32*)(val))[0]);
395 write_nic_word(dev, BSSIDR+2, ((u16*)(val+2))[0]);
396 break;
397
398 case HW_VAR_MEDIA_STATUS:
399 {
400 RT_OP_MODE OpMode = *((RT_OP_MODE *)(val));
401 //LED_CTL_MODE LedAction = LED_CTL_NO_LINK;
402 u8 btMsr = read_nic_byte(dev, MSR);
403
404 btMsr &= 0xfc;
405
406 switch(OpMode)
407 {
408 case RT_OP_MODE_INFRASTRUCTURE:
409 btMsr |= MSR_INFRA;
410 //LedAction = LED_CTL_LINK;
411 break;
412
413 case RT_OP_MODE_IBSS:
414 btMsr |= MSR_ADHOC;
935e99fb 415 // led link set separate
65a43784 416 break;
417
418 case RT_OP_MODE_AP:
419 btMsr |= MSR_AP;
420 //LedAction = LED_CTL_LINK;
421 break;
422
423 default:
424 btMsr |= MSR_NOLINK;
425 break;
426 }
427
428 write_nic_byte(dev, MSR, btMsr);
429
430 //priv->ieee80211->LedControlHandler(dev, LedAction);
431 }
432 break;
433
434 case HW_VAR_CECHK_BSSID:
435 {
436 u32 RegRCR, Type;
437
438 Type = ((u8*)(val))[0];
439 //priv->ieee80211->GetHwRegHandler(dev, HW_VAR_RCR, (u8*)(&RegRCR));
440 RegRCR = read_nic_dword(dev,RCR);
441 priv->ReceiveConfig = RegRCR;
442
443 if (Type == true)
444 RegRCR |= (RCR_CBSSID);
445 else if (Type == false)
446 RegRCR &= (~RCR_CBSSID);
447
448 //priv->ieee80211->SetHwRegHandler( dev, HW_VAR_RCR, (u8*)(&RegRCR) );
449 write_nic_dword(dev, RCR,RegRCR);
450 priv->ReceiveConfig = RegRCR;
451
452 }
453 break;
454
455 case HW_VAR_SLOT_TIME:
456 {
457 //PSTA_QOS pStaQos = Adapter->MgntInfo.pStaQos;
458 //AC_CODING eACI;
459
460 priv->slot_time = val[0];
461 write_nic_byte(dev, SLOT_TIME, val[0]);
462
463 }
464 break;
465
466 case HW_VAR_ACK_PREAMBLE:
467 {
468 u32 regTmp = 0;
469 priv->short_preamble = (bool)(*(u8*)val );
470 regTmp = priv->basic_rate;
471 if (priv->short_preamble)
472 regTmp |= BRSR_AckShortPmb;
473 write_nic_dword(dev, RRSR, regTmp);
474 }
475 break;
476
477 case HW_VAR_CPU_RST:
478 write_nic_dword(dev, CPU_GEN, ((u32*)(val))[0]);
479 break;
480
481 default:
482 break;
483 }
484
485}
486
ecdfa446
GKH
487static struct proc_dir_entry *rtl8192_proc = NULL;
488
ecdfa446
GKH
489static int proc_get_stats_ap(char *page, char **start,
490 off_t offset, int count,
491 int *eof, void *data)
492{
493 struct net_device *dev = data;
494 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
495 struct ieee80211_device *ieee = priv->ieee80211;
496 struct ieee80211_network *target;
497
498 int len = 0;
499
500 list_for_each_entry(target, &ieee->network_list, list) {
501
502 len += snprintf(page + len, count - len,
503 "%s ", target->ssid);
504
505 if(target->wpa_ie_len>0 || target->rsn_ie_len>0){
506 len += snprintf(page + len, count - len,
507 "WPA\n");
508 }
509 else{
510 len += snprintf(page + len, count - len,
511 "non_WPA\n");
512 }
513
514 }
515
516 *eof = 1;
517 return len;
518}
519
520static int proc_get_registers(char *page, char **start,
521 off_t offset, int count,
522 int *eof, void *data)
523{
524 struct net_device *dev = data;
525// struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
526
527 int len = 0;
528 int i,n;
529
530 int max=0xff;
531
532 /* This dump the current register page */
533 len += snprintf(page + len, count - len,
534 "\n####################page 0##################\n ");
535
536 for(n=0;n<=max;)
537 {
538 //printk( "\nD: %2x> ", n);
539 len += snprintf(page + len, count - len,
540 "\nD: %2x > ",n);
541
542 for(i=0;i<16 && n<=max;i++,n++)
543 len += snprintf(page + len, count - len,
544 "%2x ",read_nic_byte(dev,n));
545
546 // printk("%2x ",read_nic_byte(dev,n));
547 }
548 len += snprintf(page + len, count - len,"\n");
549 len += snprintf(page + len, count - len,
550 "\n####################page 1##################\n ");
551 for(n=0;n<=max;)
552 {
553 //printk( "\nD: %2x> ", n);
554 len += snprintf(page + len, count - len,
555 "\nD: %2x > ",n);
556
557 for(i=0;i<16 && n<=max;i++,n++)
558 len += snprintf(page + len, count - len,
559 "%2x ",read_nic_byte(dev,0x100|n));
560
561 // printk("%2x ",read_nic_byte(dev,n));
562 }
563
564 len += snprintf(page + len, count - len,
565 "\n####################page 3##################\n ");
566 for(n=0;n<=max;)
567 {
568 //printk( "\nD: %2x> ", n);
569 len += snprintf(page + len, count - len,
570 "\nD: %2x > ",n);
571
572 for(i=0;i<16 && n<=max;i++,n++)
573 len += snprintf(page + len, count - len,
574 "%2x ",read_nic_byte(dev,0x300|n));
575
576 // printk("%2x ",read_nic_byte(dev,n));
577 }
578
579
580 *eof = 1;
581 return len;
582
583}
584
585
ecdfa446
GKH
586
587static int proc_get_stats_tx(char *page, char **start,
588 off_t offset, int count,
589 int *eof, void *data)
590{
591 struct net_device *dev = data;
592 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
593
594 int len = 0;
595
596 len += snprintf(page + len, count - len,
597 "TX VI priority ok int: %lu\n"
598// "TX VI priority error int: %lu\n"
599 "TX VO priority ok int: %lu\n"
600// "TX VO priority error int: %lu\n"
601 "TX BE priority ok int: %lu\n"
602// "TX BE priority error int: %lu\n"
603 "TX BK priority ok int: %lu\n"
604// "TX BK priority error int: %lu\n"
605 "TX MANAGE priority ok int: %lu\n"
606// "TX MANAGE priority error int: %lu\n"
607 "TX BEACON priority ok int: %lu\n"
608 "TX BEACON priority error int: %lu\n"
609 "TX CMDPKT priority ok int: %lu\n"
610// "TX high priority ok int: %lu\n"
611// "TX high priority failed error int: %lu\n"
612// "TX queue resume: %lu\n"
613 "TX queue stopped?: %d\n"
614 "TX fifo overflow: %lu\n"
615// "TX beacon: %lu\n"
616// "TX VI queue: %d\n"
617// "TX VO queue: %d\n"
618// "TX BE queue: %d\n"
619// "TX BK queue: %d\n"
620// "TX HW queue: %d\n"
621// "TX VI dropped: %lu\n"
622// "TX VO dropped: %lu\n"
623// "TX BE dropped: %lu\n"
624// "TX BK dropped: %lu\n"
625 "TX total data packets %lu\n"
626 "TX total data bytes :%lu\n",
627// "TX beacon aborted: %lu\n",
628 priv->stats.txviokint,
629// priv->stats.txvierr,
630 priv->stats.txvookint,
631// priv->stats.txvoerr,
632 priv->stats.txbeokint,
633// priv->stats.txbeerr,
634 priv->stats.txbkokint,
635// priv->stats.txbkerr,
636 priv->stats.txmanageokint,
637// priv->stats.txmanageerr,
638 priv->stats.txbeaconokint,
639 priv->stats.txbeaconerr,
640 priv->stats.txcmdpktokint,
641// priv->stats.txhpokint,
642// priv->stats.txhperr,
643// priv->stats.txresumed,
644 netif_queue_stopped(dev),
645 priv->stats.txoverflow,
646// priv->stats.txbeacon,
647// atomic_read(&(priv->tx_pending[VI_QUEUE])),
648// atomic_read(&(priv->tx_pending[VO_QUEUE])),
649// atomic_read(&(priv->tx_pending[BE_QUEUE])),
650// atomic_read(&(priv->tx_pending[BK_QUEUE])),
651// read_nic_byte(dev, TXFIFOCOUNT),
652// priv->stats.txvidrop,
653// priv->stats.txvodrop,
654 priv->ieee80211->stats.tx_packets,
655 priv->ieee80211->stats.tx_bytes
656
657
658// priv->stats.txbedrop,
659// priv->stats.txbkdrop
660 // priv->stats.txdatapkt
661// priv->stats.txbeaconerr
662 );
663
664 *eof = 1;
665 return len;
666}
667
668
669
670static int proc_get_stats_rx(char *page, char **start,
671 off_t offset, int count,
672 int *eof, void *data)
673{
674 struct net_device *dev = data;
675 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
676
677 int len = 0;
678
679 len += snprintf(page + len, count - len,
680 "RX packets: %lu\n"
681 "RX desc err: %lu\n"
682 "RX rx overflow error: %lu\n"
683 "RX invalid urb error: %lu\n",
684 priv->stats.rxint,
685 priv->stats.rxrdu,
686 priv->stats.rxoverflow,
687 priv->stats.rxurberr);
688
689 *eof = 1;
690 return len;
691}
692
5e1ad18a 693static void rtl8192_proc_module_init(void)
ecdfa446
GKH
694{
695 RT_TRACE(COMP_INIT, "Initializing proc filesystem");
ecdfa446 696 rtl8192_proc=create_proc_entry(RTL819xE_MODULE_NAME, S_IFDIR, init_net.proc_net);
ecdfa446
GKH
697}
698
699
5e1ad18a 700static void rtl8192_proc_module_remove(void)
ecdfa446 701{
ecdfa446 702 remove_proc_entry(RTL819xE_MODULE_NAME, init_net.proc_net);
ecdfa446
GKH
703}
704
705
5e1ad18a 706static void rtl8192_proc_remove_one(struct net_device *dev)
ecdfa446
GKH
707{
708 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
709
710 printk("dev name=======> %s\n",dev->name);
711
712 if (priv->dir_dev) {
713 // remove_proc_entry("stats-hw", priv->dir_dev);
714 remove_proc_entry("stats-tx", priv->dir_dev);
715 remove_proc_entry("stats-rx", priv->dir_dev);
716 // remove_proc_entry("stats-ieee", priv->dir_dev);
717 remove_proc_entry("stats-ap", priv->dir_dev);
718 remove_proc_entry("registers", priv->dir_dev);
719 // remove_proc_entry("cck-registers",priv->dir_dev);
720 // remove_proc_entry("ofdm-registers",priv->dir_dev);
721 //remove_proc_entry(dev->name, rtl8192_proc);
722 remove_proc_entry("wlan0", rtl8192_proc);
723 priv->dir_dev = NULL;
724 }
725}
726
727
5e1ad18a 728static void rtl8192_proc_init_one(struct net_device *dev)
ecdfa446
GKH
729{
730 struct proc_dir_entry *e;
731 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
732 priv->dir_dev = create_proc_entry(dev->name,
733 S_IFDIR | S_IRUGO | S_IXUGO,
734 rtl8192_proc);
735 if (!priv->dir_dev) {
736 RT_TRACE(COMP_ERR, "Unable to initialize /proc/net/rtl8192/%s\n",
737 dev->name);
738 return;
739 }
ecdfa446
GKH
740 e = create_proc_read_entry("stats-rx", S_IFREG | S_IRUGO,
741 priv->dir_dev, proc_get_stats_rx, dev);
742
743 if (!e) {
744 RT_TRACE(COMP_ERR,"Unable to initialize "
745 "/proc/net/rtl8192/%s/stats-rx\n",
746 dev->name);
747 }
748
749
750 e = create_proc_read_entry("stats-tx", S_IFREG | S_IRUGO,
751 priv->dir_dev, proc_get_stats_tx, dev);
752
753 if (!e) {
754 RT_TRACE(COMP_ERR, "Unable to initialize "
755 "/proc/net/rtl8192/%s/stats-tx\n",
756 dev->name);
757 }
ecdfa446
GKH
758
759 e = create_proc_read_entry("stats-ap", S_IFREG | S_IRUGO,
760 priv->dir_dev, proc_get_stats_ap, dev);
761
762 if (!e) {
763 RT_TRACE(COMP_ERR, "Unable to initialize "
764 "/proc/net/rtl8192/%s/stats-ap\n",
765 dev->name);
766 }
767
768 e = create_proc_read_entry("registers", S_IFREG | S_IRUGO,
769 priv->dir_dev, proc_get_registers, dev);
770 if (!e) {
771 RT_TRACE(COMP_ERR, "Unable to initialize "
772 "/proc/net/rtl8192/%s/registers\n",
773 dev->name);
774 }
ecdfa446 775}
ecdfa446 776
ecdfa446
GKH
777short check_nic_enough_desc(struct net_device *dev, int prio)
778{
779 struct r8192_priv *priv = ieee80211_priv(dev);
780 struct rtl8192_tx_ring *ring = &priv->tx_ring[prio];
781
782 /* for now we reserve two free descriptor as a safety boundary
783 * between the tail and the head
784 */
285f660c 785 return (ring->entries - skb_queue_len(&ring->queue) >= 2);
ecdfa446
GKH
786}
787
5e1ad18a 788static void tx_timeout(struct net_device *dev)
ecdfa446
GKH
789{
790 struct r8192_priv *priv = ieee80211_priv(dev);
791 //rtl8192_commit(dev);
792
ecdfa446 793 schedule_work(&priv->reset_wq);
ecdfa446
GKH
794 printk("TXTIMEOUT");
795}
796
5e1ad18a 797static void rtl8192_irq_enable(struct net_device *dev)
ecdfa446
GKH
798{
799 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
800 priv->irq_enabled = 1;
801 write_nic_dword(dev,INTA_MASK, priv->irq_mask);
802}
803
65a43784 804void rtl8192_irq_disable(struct net_device *dev)
ecdfa446
GKH
805{
806 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
807
808 write_nic_dword(dev,INTA_MASK,0);
ecdfa446
GKH
809 priv->irq_enabled = 0;
810}
811
ecdfa446
GKH
812void rtl8192_update_msr(struct net_device *dev)
813{
814 struct r8192_priv *priv = ieee80211_priv(dev);
815 u8 msr;
816
817 msr = read_nic_byte(dev, MSR);
818 msr &= ~ MSR_LINK_MASK;
819
820 /* do not change in link_state != WLAN_LINK_ASSOCIATED.
821 * msr must be updated if the state is ASSOCIATING.
822 * this is intentional and make sense for ad-hoc and
823 * master (see the create BSS/IBSS func)
824 */
825 if (priv->ieee80211->state == IEEE80211_LINKED){
826
827 if (priv->ieee80211->iw_mode == IW_MODE_INFRA)
828 msr |= (MSR_LINK_MANAGED<<MSR_LINK_SHIFT);
829 else if (priv->ieee80211->iw_mode == IW_MODE_ADHOC)
830 msr |= (MSR_LINK_ADHOC<<MSR_LINK_SHIFT);
831 else if (priv->ieee80211->iw_mode == IW_MODE_MASTER)
832 msr |= (MSR_LINK_MASTER<<MSR_LINK_SHIFT);
833
834 }else
835 msr |= (MSR_LINK_NONE<<MSR_LINK_SHIFT);
836
837 write_nic_byte(dev, MSR, msr);
838}
839
840void rtl8192_set_chan(struct net_device *dev,short ch)
841{
842 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
843 RT_TRACE(COMP_RF, "=====>%s()====ch:%d\n", __FUNCTION__, ch);
844 priv->chan=ch;
845#if 0
846 if(priv->ieee80211->iw_mode == IW_MODE_ADHOC ||
847 priv->ieee80211->iw_mode == IW_MODE_MASTER){
848
849 priv->ieee80211->link_state = WLAN_LINK_ASSOCIATED;
850 priv->ieee80211->master_chan = ch;
851 rtl8192_update_beacon_ch(dev);
852 }
853#endif
854
855 /* this hack should avoid frame TX during channel setting*/
856
857
858 // tx = read_nic_dword(dev,TX_CONF);
859 // tx &= ~TX_LOOPBACK_MASK;
860
861#ifndef LOOP_TEST
862 //TODO
863 // write_nic_dword(dev,TX_CONF, tx |( TX_LOOPBACK_MAC<<TX_LOOPBACK_SHIFT));
864
865 //need to implement rf set channel here WB
866
867 if (priv->rf_set_chan)
868 priv->rf_set_chan(dev,priv->chan);
869 // mdelay(10);
870 // write_nic_dword(dev,TX_CONF,tx | (TX_LOOPBACK_NONE<<TX_LOOPBACK_SHIFT));
871#endif
872}
873
874void rtl8192_rx_enable(struct net_device *dev)
875{
876 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
877 write_nic_dword(dev, RDQDA,priv->rx_ring_dma);
878}
879
880/* the TX_DESC_BASE setting is according to the following queue index
881 * BK_QUEUE ===> 0
882 * BE_QUEUE ===> 1
883 * VI_QUEUE ===> 2
884 * VO_QUEUE ===> 3
885 * HCCA_QUEUE ===> 4
886 * TXCMD_QUEUE ===> 5
887 * MGNT_QUEUE ===> 6
888 * HIGH_QUEUE ===> 7
889 * BEACON_QUEUE ===> 8
890 * */
881a975b 891static const u32 TX_DESC_BASE[] = {BKQDA, BEQDA, VIQDA, VOQDA, HCCAQDA, CQDA, MQDA, HQDA, BQDA};
ecdfa446
GKH
892void rtl8192_tx_enable(struct net_device *dev)
893{
894 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
895 u32 i;
896 for (i = 0; i < MAX_TX_QUEUE_COUNT; i++)
897 write_nic_dword(dev, TX_DESC_BASE[i], priv->tx_ring[i].dma);
898
899 ieee80211_reset_queue(priv->ieee80211);
900}
901
ecdfa446
GKH
902
903static void rtl8192_free_rx_ring(struct net_device *dev)
904{
905 struct r8192_priv *priv = ieee80211_priv(dev);
906 int i;
907
908 for (i = 0; i < priv->rxringcount; i++) {
909 struct sk_buff *skb = priv->rx_buf[i];
910 if (!skb)
911 continue;
912
913 pci_unmap_single(priv->pdev,
914 *((dma_addr_t *)skb->cb),
915 priv->rxbuffersize, PCI_DMA_FROMDEVICE);
916 kfree_skb(skb);
917 }
918
919 pci_free_consistent(priv->pdev, sizeof(*priv->rx_ring) * priv->rxringcount,
920 priv->rx_ring, priv->rx_ring_dma);
921 priv->rx_ring = NULL;
922}
923
924static void rtl8192_free_tx_ring(struct net_device *dev, unsigned int prio)
925{
926 struct r8192_priv *priv = ieee80211_priv(dev);
927 struct rtl8192_tx_ring *ring = &priv->tx_ring[prio];
928
929 while (skb_queue_len(&ring->queue)) {
930 tx_desc_819x_pci *entry = &ring->desc[ring->idx];
931 struct sk_buff *skb = __skb_dequeue(&ring->queue);
932
933 pci_unmap_single(priv->pdev, le32_to_cpu(entry->TxBuffAddr),
934 skb->len, PCI_DMA_TODEVICE);
935 kfree_skb(skb);
936 ring->idx = (ring->idx + 1) % ring->entries;
937 }
938
939 pci_free_consistent(priv->pdev, sizeof(*ring->desc)*ring->entries,
940 ring->desc, ring->dma);
941 ring->desc = NULL;
942}
943
16d74da0 944void PHY_SetRtl8192eRfOff(struct net_device* dev)
ecdfa446 945{
65a43784 946 //disable RF-Chip A/B
947 rtl8192_setBBreg(dev, rFPGA0_XA_RFInterfaceOE, BIT4, 0x0);
948 //analog to digital off, for power save
949 rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0x300, 0x0);
950 //digital to analog off, for power save
951 rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x18, 0x0);
952 //rx antenna off
953 rtl8192_setBBreg(dev, rOFDM0_TRxPathEnable, 0xf, 0x0);
954 //rx antenna off
955 rtl8192_setBBreg(dev, rOFDM1_TRxPathEnable, 0xf, 0x0);
956 //analog to digital part2 off, for power save
957 rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x60, 0x0);
958 rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x4, 0x0);
959 // Analog parameter!!Change bias and Lbus control.
960 write_nic_byte(dev, ANAPAR_FOR_8192PciE, 0x07);
961
962}
ecdfa446 963
65a43784 964void rtl8192_halt_adapter(struct net_device *dev, bool reset)
ecdfa446 965{
65a43784 966 //u8 cmd;
ecdfa446 967 struct r8192_priv *priv = ieee80211_priv(dev);
65a43784 968 int i;
969 u8 OpMode;
970 u8 u1bTmp;
971 u32 ulRegRead;
972
973 OpMode = RT_OP_MODE_NO_LINK;
974 priv->ieee80211->SetHwRegHandler(dev, HW_VAR_MEDIA_STATUS, &OpMode);
ecdfa446 975
65a43784 976#if 1
977 if(!priv->ieee80211->bSupportRemoteWakeUp)
978 {
979 u1bTmp = 0x0; // disable tx/rx. In 8185 we write 0x10 (Reset bit), but here we make reference to WMAC and wirte 0x0. 2006.11.21 Emily
980 //priv->ieee80211->SetHwRegHandler(dev, HW_VAR_COMMAND, &u1bTmp ); // Using HW_VAR_COMMAND instead of writing CMDR directly. Rewrited by Annie, 2006-04-07.
981 write_nic_byte(dev, CMDR, u1bTmp);
982 }
983#else
ecdfa446 984 cmd=read_nic_byte(dev,CMDR);
65a43784 985 write_nic_byte(dev, CMDR, cmd &~ (CR_TE|CR_RE));
986#endif
ecdfa446 987
65a43784 988 mdelay(20);
ecdfa446 989
65a43784 990 if(!reset)
991 {
992 //PlatformStallExecution(150000);
993 mdelay(150);
994
995#ifdef RTL8192E
996 priv->bHwRfOffAction = 2;
997#endif
998
999 //
1000 // Call MgntActSet_RF_State instead to prevent RF config race condition.
1001 // By Bruce, 2008-01-17.
1002 //
1003 if(!priv->ieee80211->bSupportRemoteWakeUp)
1004 {
1005 //MgntActSet_RF_State(Adapter, eRfOff, RF_CHANGE_BY_INIT);
1006 //MgntActSet_RF_State(Adapter, eRfOff, Adapter->MgntInfo.RfOffReason);
1007 //if(Adapter->HardwareType == HARDWARE_TYPE_RTL8190P)
1008
1009 PHY_SetRtl8192eRfOff(dev);
1010
1011 // 2006.11.30. System reset bit
1012 //priv->ieee80211->GetHwRegHandler(dev, HW_VAR_CPU_RST, (u32*)(&ulRegRead) );
1013 ulRegRead = read_nic_dword(dev,CPU_GEN);
1014 ulRegRead|=CPU_GEN_SYSTEM_RESET;
1015 //priv->ieee80211->SetHwRegHandler(dev, HW_VAR_CPU_RST, &ulRegRead);
1016 write_nic_dword(dev,CPU_GEN, ulRegRead);
1017 }
1018 else
1019 {
1020 //2008.06.03 for WOL
1021 write_nic_dword(dev, WFCRC0, 0xffffffff);
1022 write_nic_dword(dev, WFCRC1, 0xffffffff);
1023 write_nic_dword(dev, WFCRC2, 0xffffffff);
1024
1025 //Write PMR register
1026 write_nic_byte(dev, PMR, 0x5);
1027 //Disable tx, enanble rx
1028 write_nic_byte(dev, MacBlkCtrl, 0xa);
1029 }
1030 }
1031
1032 for(i = 0; i < MAX_QUEUE_SIZE; i++) {
1033 skb_queue_purge(&priv->ieee80211->skb_waitQ [i]);
1034 }
1035 for(i = 0; i < MAX_QUEUE_SIZE; i++) {
1036 skb_queue_purge(&priv->ieee80211->skb_aggQ [i]);
1037 }
ecdfa446
GKH
1038
1039 skb_queue_purge(&priv->skb_queue);
ecdfa446
GKH
1040}
1041
881a975b 1042static const u16 rtl_rate[] = {10,20,55,110,60,90,120,180,240,360,480,540};
ecdfa446
GKH
1043inline u16 rtl8192_rate2rate(short rate)
1044{
1045 if (rate >11) return 0;
1046 return rtl_rate[rate];
1047}
1048
5e1ad18a 1049static void rtl8192_data_hard_stop(struct net_device *dev)
ecdfa446 1050{
ecdfa446
GKH
1051}
1052
5e1ad18a 1053static void rtl8192_data_hard_resume(struct net_device *dev)
ecdfa446 1054{
ecdfa446
GKH
1055}
1056
214985a6
MM
1057/*
1058 * this function TX data frames when the ieee80211 stack requires this.
ecdfa446
GKH
1059 * It checks also if we need to stop the ieee tx queue, eventually do it
1060 */
5e1ad18a 1061static void rtl8192_hard_data_xmit(struct sk_buff *skb, struct net_device *dev, int rate)
ecdfa446
GKH
1062{
1063 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1064 int ret;
ecdfa446
GKH
1065 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1066 u8 queue_index = tcb_desc->queue_index;
dcf663fb 1067
ecdfa446
GKH
1068 /* shall not be referred by command packet */
1069 assert(queue_index != TXCMD_QUEUE);
1070
dcf663fb 1071 if (priv->bHwRadioOff || (!priv->up))
65a43784 1072 {
1073 kfree_skb(skb);
1074 return;
1075 }
1076
dcf663fb 1077 memcpy(skb->cb, &dev, sizeof(dev));
ecdfa446 1078
ecdfa446
GKH
1079 skb_push(skb, priv->ieee80211->tx_headroom);
1080 ret = rtl8192_tx(dev, skb);
dcf663fb 1081 if (ret != 0) {
ecdfa446 1082 kfree_skb(skb);
ecdfa446
GKH
1083 }
1084
dcf663fb
MM
1085 if (queue_index != MGNT_QUEUE) {
1086 priv->ieee80211->stats.tx_bytes += (skb->len - priv->ieee80211->tx_headroom);
1087 priv->ieee80211->stats.tx_packets++;
1088 }
ecdfa446
GKH
1089}
1090
214985a6
MM
1091/*
1092 * This is a rough attempt to TX a frame
ecdfa446
GKH
1093 * This is called by the ieee 80211 stack to TX management frames.
1094 * If the ring is full packet are dropped (for data frame the queue
1095 * is stopped before this can happen).
1096 */
5e1ad18a 1097static int rtl8192_hard_start_xmit(struct sk_buff *skb,struct net_device *dev)
ecdfa446
GKH
1098{
1099 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1100
1101
1102 int ret;
1103 //unsigned long flags;
1104 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1105 u8 queue_index = tcb_desc->queue_index;
1106
65a43784 1107 if(queue_index != TXCMD_QUEUE){
f500e256 1108 if (priv->bHwRadioOff ||(!priv->up))
65a43784 1109 {
1110 kfree_skb(skb);
1111 return 0;
1112 }
1113 }
ecdfa446
GKH
1114
1115 //spin_lock_irqsave(&priv->tx_lock,flags);
1116
1117 memcpy((unsigned char *)(skb->cb),&dev,sizeof(dev));
1118 if(queue_index == TXCMD_QUEUE) {
1119 // skb_push(skb, USB_HWDESC_HEADER_LEN);
1120 rtl819xE_tx_cmd(dev, skb);
1121 ret = 0;
1122 //spin_unlock_irqrestore(&priv->tx_lock,flags);
1123 return ret;
1124 } else {
1125 // RT_TRACE(COMP_SEND, "To send management packet\n");
1126 tcb_desc->RATRIndex = 7;
1127 tcb_desc->bTxDisableRateFallBack = 1;
1128 tcb_desc->bTxUseDriverAssingedRate = 1;
1129 tcb_desc->bTxEnableFwCalcDur = 1;
1130 skb_push(skb, priv->ieee80211->tx_headroom);
1131 ret = rtl8192_tx(dev, skb);
1132 if(ret != 0) {
1133 kfree_skb(skb);
1134 };
1135 }
1136
1137// priv->ieee80211->stats.tx_bytes+=skb->len;
1138// priv->ieee80211->stats.tx_packets++;
1139
1140 //spin_unlock_irqrestore(&priv->tx_lock,flags);
1141
1142 return ret;
1143
1144}
1145
1146
5e1ad18a 1147static void rtl8192_tx_isr(struct net_device *dev, int prio)
ecdfa446
GKH
1148{
1149 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1150
1151 struct rtl8192_tx_ring *ring = &priv->tx_ring[prio];
1152
1153 while (skb_queue_len(&ring->queue)) {
1154 tx_desc_819x_pci *entry = &ring->desc[ring->idx];
1155 struct sk_buff *skb;
1156
bbc9a991 1157 /* beacon packet will only use the first descriptor defaultly,
ecdfa446
GKH
1158 * and the OWN may not be cleared by the hardware
1159 * */
1160 if(prio != BEACON_QUEUE) {
1161 if(entry->OWN)
1162 return;
1163 ring->idx = (ring->idx + 1) % ring->entries;
1164 }
1165
1166 skb = __skb_dequeue(&ring->queue);
1167 pci_unmap_single(priv->pdev, le32_to_cpu(entry->TxBuffAddr),
1168 skb->len, PCI_DMA_TODEVICE);
1169
1170 kfree_skb(skb);
1171 }
1172 if (prio == MGNT_QUEUE){
1173 if (priv->ieee80211->ack_tx_to_ieee){
1174 if (rtl8192_is_tx_queue_empty(dev)){
1175 priv->ieee80211->ack_tx_to_ieee = 0;
1176 ieee80211_ps_tx_ack(priv->ieee80211, 1);
1177 }
1178 }
1179 }
1180
1181 if(prio != BEACON_QUEUE) {
1182 /* try to deal with the pending packets */
1183 tasklet_schedule(&priv->irq_tx_tasklet);
1184 }
1185
1186}
1187
5e1ad18a 1188static void rtl8192_stop_beacon(struct net_device *dev)
ecdfa446 1189{
ecdfa446
GKH
1190}
1191
5e1ad18a 1192static void rtl8192_config_rate(struct net_device* dev, u16* rate_config)
ecdfa446
GKH
1193{
1194 struct r8192_priv *priv = ieee80211_priv(dev);
1195 struct ieee80211_network *net;
1196 u8 i=0, basic_rate = 0;
1197 net = & priv->ieee80211->current_network;
1198
1199 for (i=0; i<net->rates_len; i++)
1200 {
1201 basic_rate = net->rates[i]&0x7f;
1202 switch(basic_rate)
1203 {
1204 case MGN_1M: *rate_config |= RRSR_1M; break;
1205 case MGN_2M: *rate_config |= RRSR_2M; break;
1206 case MGN_5_5M: *rate_config |= RRSR_5_5M; break;
1207 case MGN_11M: *rate_config |= RRSR_11M; break;
1208 case MGN_6M: *rate_config |= RRSR_6M; break;
1209 case MGN_9M: *rate_config |= RRSR_9M; break;
1210 case MGN_12M: *rate_config |= RRSR_12M; break;
1211 case MGN_18M: *rate_config |= RRSR_18M; break;
1212 case MGN_24M: *rate_config |= RRSR_24M; break;
1213 case MGN_36M: *rate_config |= RRSR_36M; break;
1214 case MGN_48M: *rate_config |= RRSR_48M; break;
1215 case MGN_54M: *rate_config |= RRSR_54M; break;
1216 }
1217 }
1218 for (i=0; i<net->rates_ex_len; i++)
1219 {
1220 basic_rate = net->rates_ex[i]&0x7f;
1221 switch(basic_rate)
1222 {
1223 case MGN_1M: *rate_config |= RRSR_1M; break;
1224 case MGN_2M: *rate_config |= RRSR_2M; break;
1225 case MGN_5_5M: *rate_config |= RRSR_5_5M; break;
1226 case MGN_11M: *rate_config |= RRSR_11M; break;
1227 case MGN_6M: *rate_config |= RRSR_6M; break;
1228 case MGN_9M: *rate_config |= RRSR_9M; break;
1229 case MGN_12M: *rate_config |= RRSR_12M; break;
1230 case MGN_18M: *rate_config |= RRSR_18M; break;
1231 case MGN_24M: *rate_config |= RRSR_24M; break;
1232 case MGN_36M: *rate_config |= RRSR_36M; break;
1233 case MGN_48M: *rate_config |= RRSR_48M; break;
1234 case MGN_54M: *rate_config |= RRSR_54M; break;
1235 }
1236 }
1237}
1238
1239
1240#define SHORT_SLOT_TIME 9
1241#define NON_SHORT_SLOT_TIME 20
1242
5e1ad18a 1243static void rtl8192_update_cap(struct net_device* dev, u16 cap)
ecdfa446
GKH
1244{
1245 u32 tmp = 0;
1246 struct r8192_priv *priv = ieee80211_priv(dev);
1247 struct ieee80211_network *net = &priv->ieee80211->current_network;
1248 priv->short_preamble = cap & WLAN_CAPABILITY_SHORT_PREAMBLE;
1249 tmp = priv->basic_rate;
1250 if (priv->short_preamble)
1251 tmp |= BRSR_AckShortPmb;
1252 write_nic_dword(dev, RRSR, tmp);
1253
1254 if (net->mode & (IEEE_G|IEEE_N_24G))
1255 {
1256 u8 slot_time = 0;
1257 if ((cap & WLAN_CAPABILITY_SHORT_SLOT)&&(!priv->ieee80211->pHTInfo->bCurrentRT2RTLongSlotTime))
1258 {//short slot time
1259 slot_time = SHORT_SLOT_TIME;
1260 }
1261 else //long slot time
1262 slot_time = NON_SHORT_SLOT_TIME;
1263 priv->slot_time = slot_time;
1264 write_nic_byte(dev, SLOT_TIME, slot_time);
1265 }
1266
1267}
5e1ad18a
GKH
1268
1269static void rtl8192_net_update(struct net_device *dev)
ecdfa446
GKH
1270{
1271
1272 struct r8192_priv *priv = ieee80211_priv(dev);
1273 struct ieee80211_network *net;
1274 u16 BcnTimeCfg = 0, BcnCW = 6, BcnIFS = 0xf;
1275 u16 rate_config = 0;
1276 net = &priv->ieee80211->current_network;
1277 //update Basic rate: RR, BRSR
1278 rtl8192_config_rate(dev, &rate_config);
1279 // 2007.01.16, by Emily
1280 // Select RRSR (in Legacy-OFDM and CCK)
1281 // For 8190, we select only 24M, 12M, 6M, 11M, 5.5M, 2M, and 1M from the Basic rate.
1282 // We do not use other rates.
1283 priv->basic_rate = rate_config &= 0x15f;
1284 //BSSID
1285 write_nic_dword(dev,BSSIDR,((u32*)net->bssid)[0]);
1286 write_nic_word(dev,BSSIDR+4,((u16*)net->bssid)[2]);
1287#if 0
1288 //MSR
1289 rtl8192_update_msr(dev);
1290#endif
1291
1292
1293// rtl8192_update_cap(dev, net->capability);
1294 if (priv->ieee80211->iw_mode == IW_MODE_ADHOC)
1295 {
1296 write_nic_word(dev, ATIMWND, 2);
1297 write_nic_word(dev, BCN_DMATIME, 256);
1298 write_nic_word(dev, BCN_INTERVAL, net->beacon_interval);
1299 // write_nic_word(dev, BcnIntTime, 100);
1300 //BIT15 of BCN_DRV_EARLY_INT will indicate whether software beacon or hw beacon is applied.
1301 write_nic_word(dev, BCN_DRV_EARLY_INT, 10);
1302 write_nic_byte(dev, BCN_ERR_THRESH, 100);
1303
1304 BcnTimeCfg |= (BcnCW<<BCN_TCFG_CW_SHIFT);
1305 // TODO: BcnIFS may required to be changed on ASIC
1306 BcnTimeCfg |= BcnIFS<<BCN_TCFG_IFS;
1307
1308 write_nic_word(dev, BCN_TCFG, BcnTimeCfg);
1309 }
1310
1311
1312}
1313
ecdfa446
GKH
1314void rtl819xE_tx_cmd(struct net_device *dev, struct sk_buff *skb)
1315{
1316 struct r8192_priv *priv = ieee80211_priv(dev);
1317 struct rtl8192_tx_ring *ring;
1318 tx_desc_819x_pci *entry;
1319 unsigned int idx;
1320 dma_addr_t mapping;
1321 cb_desc *tcb_desc;
1322 unsigned long flags;
1323
1324 ring = &priv->tx_ring[TXCMD_QUEUE];
1325 mapping = pci_map_single(priv->pdev, skb->data, skb->len, PCI_DMA_TODEVICE);
1326
1327 spin_lock_irqsave(&priv->irq_th_lock,flags);
1328 idx = (ring->idx + skb_queue_len(&ring->queue)) % ring->entries;
1329 entry = &ring->desc[idx];
1330
1331 tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1332 memset(entry,0,12);
1333 entry->LINIP = tcb_desc->bLastIniPkt;
1334 entry->FirstSeg = 1;//first segment
1335 entry->LastSeg = 1; //last segment
1336 if(tcb_desc->bCmdOrInit == DESC_PACKET_TYPE_INIT) {
1337 entry->CmdInit = DESC_PACKET_TYPE_INIT;
1338 } else {
1339 entry->CmdInit = DESC_PACKET_TYPE_NORMAL;
1340 entry->Offset = sizeof(TX_FWINFO_8190PCI) + 8;
1341 entry->PktSize = (u16)(tcb_desc->pkt_size + entry->Offset);
1342 entry->QueueSelect = QSLT_CMD;
1343 entry->TxFWInfoSize = 0x08;
1344 entry->RATid = (u8)DESC_PACKET_TYPE_INIT;
1345 }
1346 entry->TxBufferSize = skb->len;
1347 entry->TxBuffAddr = cpu_to_le32(mapping);
1348 entry->OWN = 1;
1349
1350#ifdef JOHN_DUMP_TXDESC
1351 { int i;
1352 tx_desc_819x_pci *entry1 = &ring->desc[0];
1353 unsigned int *ptr= (unsigned int *)entry1;
1354 printk("<Tx descriptor>:\n");
1355 for (i = 0; i < 8; i++)
1356 printk("%8x ", ptr[i]);
1357 printk("\n");
1358 }
1359#endif
1360 __skb_queue_tail(&ring->queue, skb);
1361 spin_unlock_irqrestore(&priv->irq_th_lock,flags);
1362
1363 write_nic_byte(dev, TPPoll, TPPoll_CQ);
1364
1365 return;
1366}
1367
1368/*
1369 * Mapping Software/Hardware descriptor queue id to "Queue Select Field"
1370 * in TxFwInfo data structure
214985a6 1371 */
5e1ad18a 1372static u8 MapHwQueueToFirmwareQueue(u8 QueueID)
ecdfa446
GKH
1373{
1374 u8 QueueSelect = 0x0; //defualt set to
1375
1376 switch(QueueID) {
1377 case BE_QUEUE:
1378 QueueSelect = QSLT_BE; //or QSelect = pTcb->priority;
1379 break;
1380
1381 case BK_QUEUE:
1382 QueueSelect = QSLT_BK; //or QSelect = pTcb->priority;
1383 break;
1384
1385 case VO_QUEUE:
1386 QueueSelect = QSLT_VO; //or QSelect = pTcb->priority;
1387 break;
1388
1389 case VI_QUEUE:
1390 QueueSelect = QSLT_VI; //or QSelect = pTcb->priority;
1391 break;
1392 case MGNT_QUEUE:
1393 QueueSelect = QSLT_MGNT;
1394 break;
1395
1396 case BEACON_QUEUE:
1397 QueueSelect = QSLT_BEACON;
1398 break;
1399
1400 // TODO: 2006.10.30 mark other queue selection until we verify it is OK
1401 // TODO: Remove Assertions
1402//#if (RTL819X_FPGA_VER & RTL819X_FPGA_GUANGAN_070502)
1403 case TXCMD_QUEUE:
1404 QueueSelect = QSLT_CMD;
1405 break;
1406//#endif
1407 case HIGH_QUEUE:
1408 //QueueSelect = QSLT_HIGH;
1409 //break;
1410
1411 default:
1412 RT_TRACE(COMP_ERR, "TransmitTCB(): Impossible Queue Selection: %d \n", QueueID);
1413 break;
1414 }
1415 return QueueSelect;
1416}
1417
5e1ad18a 1418static u8 MRateToHwRate8190Pci(u8 rate)
ecdfa446
GKH
1419{
1420 u8 ret = DESC90_RATE1M;
1421
1422 switch(rate) {
1423 case MGN_1M: ret = DESC90_RATE1M; break;
1424 case MGN_2M: ret = DESC90_RATE2M; break;
1425 case MGN_5_5M: ret = DESC90_RATE5_5M; break;
1426 case MGN_11M: ret = DESC90_RATE11M; break;
1427 case MGN_6M: ret = DESC90_RATE6M; break;
1428 case MGN_9M: ret = DESC90_RATE9M; break;
1429 case MGN_12M: ret = DESC90_RATE12M; break;
1430 case MGN_18M: ret = DESC90_RATE18M; break;
1431 case MGN_24M: ret = DESC90_RATE24M; break;
1432 case MGN_36M: ret = DESC90_RATE36M; break;
1433 case MGN_48M: ret = DESC90_RATE48M; break;
1434 case MGN_54M: ret = DESC90_RATE54M; break;
1435
1436 // HT rate since here
1437 case MGN_MCS0: ret = DESC90_RATEMCS0; break;
1438 case MGN_MCS1: ret = DESC90_RATEMCS1; break;
1439 case MGN_MCS2: ret = DESC90_RATEMCS2; break;
1440 case MGN_MCS3: ret = DESC90_RATEMCS3; break;
1441 case MGN_MCS4: ret = DESC90_RATEMCS4; break;
1442 case MGN_MCS5: ret = DESC90_RATEMCS5; break;
1443 case MGN_MCS6: ret = DESC90_RATEMCS6; break;
1444 case MGN_MCS7: ret = DESC90_RATEMCS7; break;
1445 case MGN_MCS8: ret = DESC90_RATEMCS8; break;
1446 case MGN_MCS9: ret = DESC90_RATEMCS9; break;
1447 case MGN_MCS10: ret = DESC90_RATEMCS10; break;
1448 case MGN_MCS11: ret = DESC90_RATEMCS11; break;
1449 case MGN_MCS12: ret = DESC90_RATEMCS12; break;
1450 case MGN_MCS13: ret = DESC90_RATEMCS13; break;
1451 case MGN_MCS14: ret = DESC90_RATEMCS14; break;
1452 case MGN_MCS15: ret = DESC90_RATEMCS15; break;
1453 case (0x80|0x20): ret = DESC90_RATEMCS32; break;
1454
1455 default: break;
1456 }
1457 return ret;
1458}
1459
1460
5e1ad18a 1461static u8 QueryIsShort(u8 TxHT, u8 TxRate, cb_desc *tcb_desc)
ecdfa446
GKH
1462{
1463 u8 tmp_Short;
1464
1465 tmp_Short = (TxHT==1)?((tcb_desc->bUseShortGI)?1:0):((tcb_desc->bUseShortPreamble)?1:0);
1466
1467 if(TxHT==1 && TxRate != DESC90_RATEMCS15)
1468 tmp_Short = 0;
1469
1470 return tmp_Short;
1471}
1472
1473/*
1474 * The tx procedure is just as following,
1475 * skb->cb will contain all the following information,
1476 * priority, morefrag, rate, &dev.
214985a6 1477 */
ecdfa446
GKH
1478short rtl8192_tx(struct net_device *dev, struct sk_buff* skb)
1479{
1480 struct r8192_priv *priv = ieee80211_priv(dev);
1481 struct rtl8192_tx_ring *ring;
1482 unsigned long flags;
1483 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1484 tx_desc_819x_pci *pdesc = NULL;
1485 TX_FWINFO_8190PCI *pTxFwInfo = NULL;
1486 dma_addr_t mapping;
1487 bool multi_addr=false,broad_addr=false,uni_addr=false;
1488 u8* pda_addr = NULL;
1489 int idx;
1490
65a43784 1491 if(priv->bdisable_nic){
1492 RT_TRACE(COMP_ERR,"%s: ERR!! Nic is disabled! Can't tx packet len=%d qidx=%d!!!\n", __FUNCTION__, skb->len, tcb_desc->queue_index);
1493 return skb->len;
1494 }
1495
1496#ifdef ENABLE_LPS
1497 priv->ieee80211->bAwakePktSent = true;
1498#endif
1499
ecdfa446
GKH
1500 mapping = pci_map_single(priv->pdev, skb->data, skb->len, PCI_DMA_TODEVICE);
1501 /* collect the tx packets statitcs */
1502 pda_addr = ((u8*)skb->data) + sizeof(TX_FWINFO_8190PCI);
1503 if(is_multicast_ether_addr(pda_addr))
1504 multi_addr = true;
1505 else if(is_broadcast_ether_addr(pda_addr))
1506 broad_addr = true;
1507 else
1508 uni_addr = true;
1509
1510 if(uni_addr)
1511 priv->stats.txbytesunicast += (u8)(skb->len) - sizeof(TX_FWINFO_8190PCI);
1512 else if(multi_addr)
1513 priv->stats.txbytesmulticast +=(u8)(skb->len) - sizeof(TX_FWINFO_8190PCI);
1514 else
1515 priv->stats.txbytesbroadcast += (u8)(skb->len) - sizeof(TX_FWINFO_8190PCI);
1516
1517 /* fill tx firmware */
1518 pTxFwInfo = (PTX_FWINFO_8190PCI)skb->data;
1519 memset(pTxFwInfo,0,sizeof(TX_FWINFO_8190PCI));
1520 pTxFwInfo->TxHT = (tcb_desc->data_rate&0x80)?1:0;
1521 pTxFwInfo->TxRate = MRateToHwRate8190Pci((u8)tcb_desc->data_rate);
1522 pTxFwInfo->EnableCPUDur = tcb_desc->bTxEnableFwCalcDur;
1523 pTxFwInfo->Short = QueryIsShort(pTxFwInfo->TxHT, pTxFwInfo->TxRate, tcb_desc);
1524
1525 /* Aggregation related */
1526 if(tcb_desc->bAMPDUEnable) {
1527 pTxFwInfo->AllowAggregation = 1;
1528 pTxFwInfo->RxMF = tcb_desc->ampdu_factor;
1529 pTxFwInfo->RxAMD = tcb_desc->ampdu_density;
1530 } else {
1531 pTxFwInfo->AllowAggregation = 0;
1532 pTxFwInfo->RxMF = 0;
1533 pTxFwInfo->RxAMD = 0;
1534 }
1535
1536 //
1537 // Protection mode related
1538 //
1539 pTxFwInfo->RtsEnable = (tcb_desc->bRTSEnable)?1:0;
1540 pTxFwInfo->CtsEnable = (tcb_desc->bCTSEnable)?1:0;
1541 pTxFwInfo->RtsSTBC = (tcb_desc->bRTSSTBC)?1:0;
1542 pTxFwInfo->RtsHT= (tcb_desc->rts_rate&0x80)?1:0;
1543 pTxFwInfo->RtsRate = MRateToHwRate8190Pci((u8)tcb_desc->rts_rate);
1544 pTxFwInfo->RtsBandwidth = 0;
1545 pTxFwInfo->RtsSubcarrier = tcb_desc->RTSSC;
1546 pTxFwInfo->RtsShort = (pTxFwInfo->RtsHT==0)?(tcb_desc->bRTSUseShortPreamble?1:0):(tcb_desc->bRTSUseShortGI?1:0);
1547 //
1548 // Set Bandwidth and sub-channel settings.
1549 //
1550 if(priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20_40)
1551 {
1552 if(tcb_desc->bPacketBW)
1553 {
1554 pTxFwInfo->TxBandwidth = 1;
1555#ifdef RTL8190P
1556 pTxFwInfo->TxSubCarrier = 3;
1557#else
1558 pTxFwInfo->TxSubCarrier = 0; //By SD3's Jerry suggestion, use duplicated mode, cosa 04012008
1559#endif
1560 }
1561 else
1562 {
1563 pTxFwInfo->TxBandwidth = 0;
1564 pTxFwInfo->TxSubCarrier = priv->nCur40MhzPrimeSC;
1565 }
1566 } else {
1567 pTxFwInfo->TxBandwidth = 0;
1568 pTxFwInfo->TxSubCarrier = 0;
1569 }
1570
1571 if (0)
1572 {
1573 /* 2007/07/25 MH Copy current TX FW info.*/
1574 memcpy((void*)(&Tmp_TxFwInfo), (void*)(pTxFwInfo), sizeof(TX_FWINFO_8190PCI));
1575 printk("&&&&&&&&&&&&&&&&&&&&&&====>print out fwinf\n");
1576 printk("===>enable fwcacl:%d\n", Tmp_TxFwInfo.EnableCPUDur);
1577 printk("===>RTS STBC:%d\n", Tmp_TxFwInfo.RtsSTBC);
1578 printk("===>RTS Subcarrier:%d\n", Tmp_TxFwInfo.RtsSubcarrier);
1579 printk("===>Allow Aggregation:%d\n", Tmp_TxFwInfo.AllowAggregation);
1580 printk("===>TX HT bit:%d\n", Tmp_TxFwInfo.TxHT);
1581 printk("===>Tx rate:%d\n", Tmp_TxFwInfo.TxRate);
1582 printk("===>Received AMPDU Density:%d\n", Tmp_TxFwInfo.RxAMD);
1583 printk("===>Received MPDU Factor:%d\n", Tmp_TxFwInfo.RxMF);
1584 printk("===>TxBandwidth:%d\n", Tmp_TxFwInfo.TxBandwidth);
1585 printk("===>TxSubCarrier:%d\n", Tmp_TxFwInfo.TxSubCarrier);
1586
1587 printk("<=====**********************out of print\n");
1588
1589 }
1590 spin_lock_irqsave(&priv->irq_th_lock,flags);
1591 ring = &priv->tx_ring[tcb_desc->queue_index];
1592 if (tcb_desc->queue_index != BEACON_QUEUE) {
1593 idx = (ring->idx + skb_queue_len(&ring->queue)) % ring->entries;
1594 } else {
1595 idx = 0;
1596 }
1597
1598 pdesc = &ring->desc[idx];
1599 if((pdesc->OWN == 1) && (tcb_desc->queue_index != BEACON_QUEUE)) {
207b58fb 1600 RT_TRACE(COMP_ERR,"No more TX desc@%d, ring->idx = %d,idx = %d,%x",
ecdfa446 1601 tcb_desc->queue_index,ring->idx, idx,skb->len);
65a43784 1602 spin_unlock_irqrestore(&priv->irq_th_lock,flags);
ecdfa446
GKH
1603 return skb->len;
1604 }
1605
1606 /* fill tx descriptor */
1607 memset((u8*)pdesc,0,12);
1608 /*DWORD 0*/
1609 pdesc->LINIP = 0;
1610 pdesc->CmdInit = 1;
1611 pdesc->Offset = sizeof(TX_FWINFO_8190PCI) + 8; //We must add 8!! Emily
1612 pdesc->PktSize = (u16)skb->len-sizeof(TX_FWINFO_8190PCI);
1613
1614 /*DWORD 1*/
1615 pdesc->SecCAMID= 0;
1616 pdesc->RATid = tcb_desc->RATRIndex;
1617
1618
1619 pdesc->NoEnc = 1;
1620 pdesc->SecType = 0x0;
1621 if (tcb_desc->bHwSec) {
ecdfa446
GKH
1622 switch (priv->ieee80211->pairwise_key_type) {
1623 case KEY_TYPE_WEP40:
1624 case KEY_TYPE_WEP104:
1625 pdesc->SecType = 0x1;
1626 pdesc->NoEnc = 0;
1627 break;
1628 case KEY_TYPE_TKIP:
1629 pdesc->SecType = 0x2;
1630 pdesc->NoEnc = 0;
1631 break;
1632 case KEY_TYPE_CCMP:
1633 pdesc->SecType = 0x3;
1634 pdesc->NoEnc = 0;
1635 break;
1636 case KEY_TYPE_NA:
1637 pdesc->SecType = 0x0;
1638 pdesc->NoEnc = 1;
1639 break;
1640 }
1641 }
1642
1643 //
1644 // Set Packet ID
1645 //
1646 pdesc->PktId = 0x0;
1647
1648 pdesc->QueueSelect = MapHwQueueToFirmwareQueue(tcb_desc->queue_index);
1649 pdesc->TxFWInfoSize = sizeof(TX_FWINFO_8190PCI);
1650
1651 pdesc->DISFB = tcb_desc->bTxDisableRateFallBack;
1652 pdesc->USERATE = tcb_desc->bTxUseDriverAssingedRate;
1653
1654 pdesc->FirstSeg =1;
1655 pdesc->LastSeg = 1;
1656 pdesc->TxBufferSize = skb->len;
1657
1658 pdesc->TxBuffAddr = cpu_to_le32(mapping);
1659 __skb_queue_tail(&ring->queue, skb);
1660 pdesc->OWN = 1;
1661 spin_unlock_irqrestore(&priv->irq_th_lock,flags);
1662 dev->trans_start = jiffies;
1663 write_nic_word(dev,TPPoll,0x01<<tcb_desc->queue_index);
1664 return 0;
1665}
1666
5e1ad18a 1667static short rtl8192_alloc_rx_desc_ring(struct net_device *dev)
ecdfa446
GKH
1668{
1669 struct r8192_priv *priv = ieee80211_priv(dev);
1670 rx_desc_819x_pci *entry = NULL;
1671 int i;
1672
1673 priv->rx_ring = pci_alloc_consistent(priv->pdev,
1674 sizeof(*priv->rx_ring) * priv->rxringcount, &priv->rx_ring_dma);
1675
1676 if (!priv->rx_ring || (unsigned long)priv->rx_ring & 0xFF) {
1677 RT_TRACE(COMP_ERR,"Cannot allocate RX ring\n");
1678 return -ENOMEM;
1679 }
1680
1681 memset(priv->rx_ring, 0, sizeof(*priv->rx_ring) * priv->rxringcount);
1682 priv->rx_idx = 0;
1683
1684 for (i = 0; i < priv->rxringcount; i++) {
1685 struct sk_buff *skb = dev_alloc_skb(priv->rxbuffersize);
1686 dma_addr_t *mapping;
1687 entry = &priv->rx_ring[i];
1688 if (!skb)
1689 return 0;
1690 priv->rx_buf[i] = skb;
1691 mapping = (dma_addr_t *)skb->cb;
1c7ec2e8 1692 *mapping = pci_map_single(priv->pdev, skb_tail_pointer(skb),
ecdfa446
GKH
1693 priv->rxbuffersize, PCI_DMA_FROMDEVICE);
1694
1695 entry->BufferAddress = cpu_to_le32(*mapping);
1696
1697 entry->Length = priv->rxbuffersize;
1698 entry->OWN = 1;
1699 }
1700
1701 entry->EOR = 1;
1702 return 0;
1703}
1704
1705static int rtl8192_alloc_tx_desc_ring(struct net_device *dev,
1706 unsigned int prio, unsigned int entries)
1707{
1708 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1709 tx_desc_819x_pci *ring;
1710 dma_addr_t dma;
1711 int i;
1712
1713 ring = pci_alloc_consistent(priv->pdev, sizeof(*ring) * entries, &dma);
1714 if (!ring || (unsigned long)ring & 0xFF) {
1715 RT_TRACE(COMP_ERR, "Cannot allocate TX ring (prio = %d)\n", prio);
1716 return -ENOMEM;
1717 }
1718
1719 memset(ring, 0, sizeof(*ring)*entries);
1720 priv->tx_ring[prio].desc = ring;
1721 priv->tx_ring[prio].dma = dma;
1722 priv->tx_ring[prio].idx = 0;
1723 priv->tx_ring[prio].entries = entries;
1724 skb_queue_head_init(&priv->tx_ring[prio].queue);
1725
1726 for (i = 0; i < entries; i++)
1727 ring[i].NextDescAddress =
1728 cpu_to_le32((u32)dma + ((i + 1) % entries) * sizeof(*ring));
1729
1730 return 0;
1731}
1732
1733
5e1ad18a 1734static short rtl8192_pci_initdescring(struct net_device *dev)
ecdfa446
GKH
1735{
1736 u32 ret;
1737 int i;
1738 struct r8192_priv *priv = ieee80211_priv(dev);
1739
1740 ret = rtl8192_alloc_rx_desc_ring(dev);
1741 if (ret) {
1742 return ret;
1743 }
1744
1745
1746 /* general process for other queue */
1747 for (i = 0; i < MAX_TX_QUEUE_COUNT; i++) {
d6d42dfb
JP
1748 ret = rtl8192_alloc_tx_desc_ring(dev, i, priv->txringcount);
1749 if (ret)
ecdfa446
GKH
1750 goto err_free_rings;
1751 }
1752
1753#if 0
1754 /* specific process for hardware beacon process */
d6d42dfb
JP
1755 ret = rtl8192_alloc_tx_desc_ring(dev, MAX_TX_QUEUE_COUNT - 1, 2);
1756 if (ret)
ecdfa446
GKH
1757 goto err_free_rings;
1758#endif
1759
1760 return 0;
1761
1762err_free_rings:
1763 rtl8192_free_rx_ring(dev);
1764 for (i = 0; i < MAX_TX_QUEUE_COUNT; i++)
1765 if (priv->tx_ring[i].desc)
1766 rtl8192_free_tx_ring(dev, i);
1767 return 1;
1768}
1769
5e1ad18a 1770static void rtl8192_pci_resetdescring(struct net_device *dev)
ecdfa446
GKH
1771{
1772 struct r8192_priv *priv = ieee80211_priv(dev);
1773 int i;
1774
1775 /* force the rx_idx to the first one */
1776 if(priv->rx_ring) {
1777 rx_desc_819x_pci *entry = NULL;
1778 for (i = 0; i < priv->rxringcount; i++) {
1779 entry = &priv->rx_ring[i];
1780 entry->OWN = 1;
1781 }
1782 priv->rx_idx = 0;
1783 }
1784
1785 /* after reset, release previous pending packet, and force the
1786 * tx idx to the first one */
1787 for (i = 0; i < MAX_TX_QUEUE_COUNT; i++) {
1788 if (priv->tx_ring[i].desc) {
1789 struct rtl8192_tx_ring *ring = &priv->tx_ring[i];
1790
1791 while (skb_queue_len(&ring->queue)) {
1792 tx_desc_819x_pci *entry = &ring->desc[ring->idx];
1793 struct sk_buff *skb = __skb_dequeue(&ring->queue);
1794
1795 pci_unmap_single(priv->pdev, le32_to_cpu(entry->TxBuffAddr),
1796 skb->len, PCI_DMA_TODEVICE);
1797 kfree_skb(skb);
1798 ring->idx = (ring->idx + 1) % ring->entries;
1799 }
1800 ring->idx = 0;
1801 }
1802 }
1803}
1804
5e1ad18a 1805static void rtl8192_link_change(struct net_device *dev)
ecdfa446 1806{
ecdfa446
GKH
1807 struct r8192_priv *priv = ieee80211_priv(dev);
1808 struct ieee80211_device* ieee = priv->ieee80211;
1809 //write_nic_word(dev, BCN_INTR_ITV, net->beacon_interval);
1810 if (ieee->state == IEEE80211_LINKED)
1811 {
1812 rtl8192_net_update(dev);
1813 rtl8192_update_ratr_table(dev);
1814#if 1
1815 //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
1816 if ((KEY_TYPE_WEP40 == ieee->pairwise_key_type) || (KEY_TYPE_WEP104 == ieee->pairwise_key_type))
1817 EnableHWSecurityConfig8192(dev);
1818#endif
1819 }
1820 else
1821 {
1822 write_nic_byte(dev, 0x173, 0);
1823 }
1824 /*update timing params*/
1825 //rtl8192_set_chan(dev, priv->chan);
1826 //MSR
1827 rtl8192_update_msr(dev);
1828
1829 // 2007/10/16 MH MAC Will update TSF according to all received beacon, so we have
1830 // // To set CBSSID bit when link with any AP or STA.
1831 if (ieee->iw_mode == IW_MODE_INFRA || ieee->iw_mode == IW_MODE_ADHOC)
1832 {
1833 u32 reg = 0;
1834 reg = read_nic_dword(dev, RCR);
1835 if (priv->ieee80211->state == IEEE80211_LINKED)
1836 priv->ReceiveConfig = reg |= RCR_CBSSID;
1837 else
1838 priv->ReceiveConfig = reg &= ~RCR_CBSSID;
1839 write_nic_dword(dev, RCR, reg);
1840 }
1841}
ecdfa446
GKH
1842
1843
5b3b1a7b 1844static const struct ieee80211_qos_parameters def_qos_parameters = {
ecdfa446
GKH
1845 {3,3,3,3},/* cw_min */
1846 {7,7,7,7},/* cw_max */
1847 {2,2,2,2},/* aifs */
1848 {0,0,0,0},/* flags */
1849 {0,0,0,0} /* tx_op_limit */
1850};
1851
5e1ad18a 1852static void rtl8192_update_beacon(struct work_struct * work)
ecdfa446
GKH
1853{
1854 struct r8192_priv *priv = container_of(work, struct r8192_priv, update_beacon_wq.work);
1855 struct net_device *dev = priv->ieee80211->dev;
ecdfa446
GKH
1856 struct ieee80211_device* ieee = priv->ieee80211;
1857 struct ieee80211_network* net = &ieee->current_network;
1858
1859 if (ieee->pHTInfo->bCurrentHTSupport)
1860 HTUpdateSelfAndPeerSetting(ieee, net);
1861 ieee->pHTInfo->bCurrentRT2RTLongSlotTime = net->bssht.bdRT2RTLongSlotTime;
1862 rtl8192_update_cap(dev, net->capability);
1863}
214985a6 1864
ecdfa446
GKH
1865/*
1866* background support to run QoS activate functionality
1867*/
881a975b 1868static const int WDCAPARA_ADD[] = {EDCAPARA_BE,EDCAPARA_BK,EDCAPARA_VI,EDCAPARA_VO};
5e1ad18a 1869static void rtl8192_qos_activate(struct work_struct * work)
ecdfa446
GKH
1870{
1871 struct r8192_priv *priv = container_of(work, struct r8192_priv, qos_activate);
1872 struct net_device *dev = priv->ieee80211->dev;
ecdfa446
GKH
1873 struct ieee80211_qos_parameters *qos_parameters = &priv->ieee80211->current_network.qos_data.parameters;
1874 u8 mode = priv->ieee80211->current_network.mode;
ecdfa446
GKH
1875 u8 u1bAIFS;
1876 u32 u4bAcParam;
1877 int i;
ecdfa446 1878
ecdfa446 1879 mutex_lock(&priv->mutex);
ecdfa446
GKH
1880 if(priv->ieee80211->state != IEEE80211_LINKED)
1881 goto success;
1882 RT_TRACE(COMP_QOS,"qos active process with associate response received\n");
1883 /* It better set slot time at first */
1884 /* For we just support b/g mode at present, let the slot time at 9/20 selection */
1885 /* update the ac parameter to related registers */
1886 for(i = 0; i < QOS_QUEUE_NUM; i++) {
1887 //Mode G/A: slotTimeTimer = 9; Mode B: 20
1888 u1bAIFS = qos_parameters->aifs[i] * ((mode&(IEEE_G|IEEE_N_24G)) ?9:20) + aSifsTime;
1889 u4bAcParam = ((((u32)(qos_parameters->tx_op_limit[i]))<< AC_PARAM_TXOP_LIMIT_OFFSET)|
1890 (((u32)(qos_parameters->cw_max[i]))<< AC_PARAM_ECW_MAX_OFFSET)|
1891 (((u32)(qos_parameters->cw_min[i]))<< AC_PARAM_ECW_MIN_OFFSET)|
1892 ((u32)u1bAIFS << AC_PARAM_AIFS_OFFSET));
65a43784 1893 //printk("===>u4bAcParam:%x, ", u4bAcParam);
ecdfa446
GKH
1894 write_nic_dword(dev, WDCAPARA_ADD[i], u4bAcParam);
1895 //write_nic_dword(dev, WDCAPARA_ADD[i], 0x005e4332);
1896 }
1897
1898success:
ecdfa446 1899 mutex_unlock(&priv->mutex);
ecdfa446
GKH
1900}
1901
1902static int rtl8192_qos_handle_probe_response(struct r8192_priv *priv,
1903 int active_network,
1904 struct ieee80211_network *network)
1905{
1906 int ret = 0;
1907 u32 size = sizeof(struct ieee80211_qos_parameters);
1908
1909 if(priv->ieee80211->state !=IEEE80211_LINKED)
1910 return ret;
1911
1912 if ((priv->ieee80211->iw_mode != IW_MODE_INFRA))
1913 return ret;
1914
1915 if (network->flags & NETWORK_HAS_QOS_MASK) {
1916 if (active_network &&
1917 (network->flags & NETWORK_HAS_QOS_PARAMETERS))
1918 network->qos_data.active = network->qos_data.supported;
1919
1920 if ((network->qos_data.active == 1) && (active_network == 1) &&
1921 (network->flags & NETWORK_HAS_QOS_PARAMETERS) &&
1922 (network->qos_data.old_param_count !=
1923 network->qos_data.param_count)) {
1924 network->qos_data.old_param_count =
1925 network->qos_data.param_count;
ecdfa446 1926 queue_work(priv->priv_wq, &priv->qos_activate);
ecdfa446
GKH
1927 RT_TRACE (COMP_QOS, "QoS parameters change call "
1928 "qos_activate\n");
1929 }
1930 } else {
207b58fb 1931 memcpy(&priv->ieee80211->current_network.qos_data.parameters,
ecdfa446
GKH
1932 &def_qos_parameters, size);
1933
1934 if ((network->qos_data.active == 1) && (active_network == 1)) {
ecdfa446 1935 queue_work(priv->priv_wq, &priv->qos_activate);
ecdfa446
GKH
1936 RT_TRACE(COMP_QOS, "QoS was disabled call qos_activate \n");
1937 }
1938 network->qos_data.active = 0;
1939 network->qos_data.supported = 0;
1940 }
1941
1942 return 0;
1943}
1944
1945/* handle manage frame frame beacon and probe response */
1946static int rtl8192_handle_beacon(struct net_device * dev,
1947 struct ieee80211_beacon * beacon,
1948 struct ieee80211_network * network)
1949{
1950 struct r8192_priv *priv = ieee80211_priv(dev);
1951
1952 rtl8192_qos_handle_probe_response(priv,1,network);
1953
ecdfa446 1954 queue_delayed_work(priv->priv_wq, &priv->update_beacon_wq, 0);
ecdfa446
GKH
1955 return 0;
1956
1957}
1958
1959/*
214985a6
MM
1960 * handling the beaconing responses. if we get different QoS setting
1961 * off the network from the associated setting, adjust the QoS setting
1962 */
ecdfa446
GKH
1963static int rtl8192_qos_association_resp(struct r8192_priv *priv,
1964 struct ieee80211_network *network)
1965{
1966 int ret = 0;
1967 unsigned long flags;
1968 u32 size = sizeof(struct ieee80211_qos_parameters);
1969 int set_qos_param = 0;
1970
1971 if ((priv == NULL) || (network == NULL))
1972 return ret;
1973
1974 if(priv->ieee80211->state !=IEEE80211_LINKED)
1975 return ret;
1976
1977 if ((priv->ieee80211->iw_mode != IW_MODE_INFRA))
1978 return ret;
1979
1980 spin_lock_irqsave(&priv->ieee80211->lock, flags);
1981 if(network->flags & NETWORK_HAS_QOS_PARAMETERS) {
207b58fb
MM
1982 memcpy(&priv->ieee80211->current_network.qos_data.parameters,
1983 &network->qos_data.parameters,
ecdfa446
GKH
1984 sizeof(struct ieee80211_qos_parameters));
1985 priv->ieee80211->current_network.qos_data.active = 1;
1986#if 0
207b58fb 1987 if((priv->ieee80211->current_network.qos_data.param_count !=
ecdfa446
GKH
1988 network->qos_data.param_count))
1989#endif
1990 {
1991 set_qos_param = 1;
1992 /* update qos parameter for current network */
207b58fb 1993 priv->ieee80211->current_network.qos_data.old_param_count =
ecdfa446 1994 priv->ieee80211->current_network.qos_data.param_count;
207b58fb 1995 priv->ieee80211->current_network.qos_data.param_count =
ecdfa446
GKH
1996 network->qos_data.param_count;
1997 }
1998 } else {
207b58fb 1999 memcpy(&priv->ieee80211->current_network.qos_data.parameters,
ecdfa446
GKH
2000 &def_qos_parameters, size);
2001 priv->ieee80211->current_network.qos_data.active = 0;
2002 priv->ieee80211->current_network.qos_data.supported = 0;
2003 set_qos_param = 1;
2004 }
2005
2006 spin_unlock_irqrestore(&priv->ieee80211->lock, flags);
2007
2008 RT_TRACE(COMP_QOS, "%s: network->flags = %d,%d\n",__FUNCTION__,network->flags ,priv->ieee80211->current_network.qos_data.active);
2009 if (set_qos_param == 1)
ecdfa446 2010 queue_work(priv->priv_wq, &priv->qos_activate);
ecdfa446
GKH
2011
2012 return ret;
2013}
2014
2015
2016static int rtl8192_handle_assoc_response(struct net_device *dev,
2017 struct ieee80211_assoc_response_frame *resp,
2018 struct ieee80211_network *network)
2019{
2020 struct r8192_priv *priv = ieee80211_priv(dev);
2021 rtl8192_qos_association_resp(priv, network);
2022 return 0;
2023}
2024
2025
214985a6 2026/* updateRATRTabel for MCS only. Basic rate is not implemented. */
5b3b1a7b 2027static void rtl8192_update_ratr_table(struct net_device* dev)
ecdfa446
GKH
2028{
2029 struct r8192_priv* priv = ieee80211_priv(dev);
2030 struct ieee80211_device* ieee = priv->ieee80211;
2031 u8* pMcsRate = ieee->dot11HTOperationalRateSet;
ecdfa446
GKH
2032 u32 ratr_value = 0;
2033 u8 rate_index = 0;
2034
2035 rtl8192_config_rate(dev, (u16*)(&ratr_value));
2036 ratr_value |= (*(u16*)(pMcsRate)) << 12;
16d74da0 2037
ecdfa446
GKH
2038 switch (ieee->mode)
2039 {
2040 case IEEE_A:
2041 ratr_value &= 0x00000FF0;
2042 break;
2043 case IEEE_B:
2044 ratr_value &= 0x0000000F;
2045 break;
2046 case IEEE_G:
2047 ratr_value &= 0x00000FF7;
2048 break;
2049 case IEEE_N_24G:
2050 case IEEE_N_5G:
2051 if (ieee->pHTInfo->PeerMimoPs == 0) //MIMO_PS_STATIC
2052 ratr_value &= 0x0007F007;
2053 else{
2054 if (priv->rf_type == RF_1T2R)
2055 ratr_value &= 0x000FF007;
2056 else
2057 ratr_value &= 0x0F81F007;
2058 }
2059 break;
2060 default:
2061 break;
2062 }
2063 ratr_value &= 0x0FFFFFFF;
2064 if(ieee->pHTInfo->bCurTxBW40MHz && ieee->pHTInfo->bCurShortGI40MHz){
2065 ratr_value |= 0x80000000;
2066 }else if(!ieee->pHTInfo->bCurTxBW40MHz && ieee->pHTInfo->bCurShortGI20MHz){
2067 ratr_value |= 0x80000000;
2068 }
2069 write_nic_dword(dev, RATR0+rate_index*4, ratr_value);
2070 write_nic_byte(dev, UFWP, 1);
2071}
2072
5e1ad18a 2073static bool GetNmodeSupportBySecCfg8190Pci(struct net_device*dev)
ecdfa446
GKH
2074{
2075#if 1
65a43784 2076
2077 struct r8192_priv *priv = ieee80211_priv(dev);
2078 struct ieee80211_device *ieee = priv->ieee80211;
285f660c
MM
2079 return !(ieee->rtllib_ap_sec_type &&
2080 (ieee->rtllib_ap_sec_type(ieee)&(SEC_ALG_WEP|SEC_ALG_TKIP)));
65a43784 2081#else
ecdfa446
GKH
2082 struct r8192_priv* priv = ieee80211_priv(dev);
2083 struct ieee80211_device* ieee = priv->ieee80211;
2084 int wpa_ie_len= ieee->wpa_ie_len;
2085 struct ieee80211_crypt_data* crypt;
2086 int encrypt;
2087
2088 crypt = ieee->crypt[ieee->tx_keyidx];
2089 encrypt = (ieee->current_network.capability & WLAN_CAPABILITY_PRIVACY) || (ieee->host_encrypt && crypt && crypt->ops && (0 == strcmp(crypt->ops->name,"WEP")));
2090
2091 /* simply judge */
2092 if(encrypt && (wpa_ie_len == 0)) {
2093 /* wep encryption, no N mode setting */
2094 return false;
2095// } else if((wpa_ie_len != 0)&&(memcmp(&(ieee->wpa_ie[14]),ccmp_ie,4))) {
2096 } else if((wpa_ie_len != 0)) {
2097 /* parse pairwise key type */
2098 //if((pairwisekey = WEP40)||(pairwisekey = WEP104)||(pairwisekey = TKIP))
2099 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))))
2100 return true;
2101 else
2102 return false;
2103 } else {
2104 //RT_TRACE(COMP_ERR,"In %s The GroupEncAlgorithm is [4]\n",__FUNCTION__ );
2105 return true;
2106 }
2107
ecdfa446
GKH
2108 return true;
2109#endif
2110}
2111
5e1ad18a 2112static void rtl8192_refresh_supportrate(struct r8192_priv* priv)
ecdfa446
GKH
2113{
2114 struct ieee80211_device* ieee = priv->ieee80211;
2115 //we donot consider set support rate for ABG mode, only HT MCS rate is set here.
2116 if (ieee->mode == WIRELESS_MODE_N_24G || ieee->mode == WIRELESS_MODE_N_5G)
2117 {
2118 memcpy(ieee->Regdot11HTOperationalRateSet, ieee->RegHTSuppRateSet, 16);
2119 //RT_DEBUG_DATA(COMP_INIT, ieee->RegHTSuppRateSet, 16);
2120 //RT_DEBUG_DATA(COMP_INIT, ieee->Regdot11HTOperationalRateSet, 16);
2121 }
2122 else
2123 memset(ieee->Regdot11HTOperationalRateSet, 0, 16);
ecdfa446
GKH
2124}
2125
5e1ad18a 2126static u8 rtl8192_getSupportedWireleeMode(struct net_device*dev)
ecdfa446
GKH
2127{
2128 struct r8192_priv *priv = ieee80211_priv(dev);
2129 u8 ret = 0;
2130 switch(priv->rf_chip)
2131 {
2132 case RF_8225:
2133 case RF_8256:
2134 case RF_PSEUDO_11N:
2135 ret = (WIRELESS_MODE_N_24G|WIRELESS_MODE_G|WIRELESS_MODE_B);
2136 break;
2137 case RF_8258:
2138 ret = (WIRELESS_MODE_A|WIRELESS_MODE_N_5G);
2139 break;
2140 default:
2141 ret = WIRELESS_MODE_B;
2142 break;
2143 }
2144 return ret;
2145}
5e1ad18a
GKH
2146
2147static void rtl8192_SetWirelessMode(struct net_device* dev, u8 wireless_mode)
ecdfa446
GKH
2148{
2149 struct r8192_priv *priv = ieee80211_priv(dev);
2150 u8 bSupportMode = rtl8192_getSupportedWireleeMode(dev);
2151
2152#if 1
2153 if ((wireless_mode == WIRELESS_MODE_AUTO) || ((wireless_mode&bSupportMode)==0))
2154 {
2155 if(bSupportMode & WIRELESS_MODE_N_24G)
2156 {
2157 wireless_mode = WIRELESS_MODE_N_24G;
2158 }
2159 else if(bSupportMode & WIRELESS_MODE_N_5G)
2160 {
2161 wireless_mode = WIRELESS_MODE_N_5G;
2162 }
2163 else if((bSupportMode & WIRELESS_MODE_A))
2164 {
2165 wireless_mode = WIRELESS_MODE_A;
2166 }
2167 else if((bSupportMode & WIRELESS_MODE_G))
2168 {
2169 wireless_mode = WIRELESS_MODE_G;
2170 }
2171 else if((bSupportMode & WIRELESS_MODE_B))
2172 {
2173 wireless_mode = WIRELESS_MODE_B;
2174 }
2175 else{
2176 RT_TRACE(COMP_ERR, "%s(), No valid wireless mode supported, SupportedWirelessMode(%x)!!!\n", __FUNCTION__,bSupportMode);
2177 wireless_mode = WIRELESS_MODE_B;
2178 }
2179 }
39cfb97b 2180#ifdef TO_DO_LIST //// TODO: this function doesn't work well at this time, we should wait for FPGA
ecdfa446
GKH
2181 ActUpdateChannelAccessSetting( pAdapter, pHalData->CurrentWirelessMode, &pAdapter->MgntInfo.Info8185.ChannelAccessSetting );
2182#endif
2183 priv->ieee80211->mode = wireless_mode;
2184
2185 if ((wireless_mode == WIRELESS_MODE_N_24G) || (wireless_mode == WIRELESS_MODE_N_5G))
2186 priv->ieee80211->pHTInfo->bEnableHT = 1;
2187 else
2188 priv->ieee80211->pHTInfo->bEnableHT = 0;
2189 RT_TRACE(COMP_INIT, "Current Wireless Mode is %x\n", wireless_mode);
2190 rtl8192_refresh_supportrate(priv);
2191#endif
2192
2193}
ecdfa446 2194
5e1ad18a 2195static bool GetHalfNmodeSupportByAPs819xPci(struct net_device* dev)
ecdfa446 2196{
ecdfa446
GKH
2197 struct r8192_priv* priv = ieee80211_priv(dev);
2198 struct ieee80211_device* ieee = priv->ieee80211;
2199
285f660c 2200 return ieee->bHalfWirelessN24GMode;
ecdfa446
GKH
2201}
2202
2203short rtl8192_is_tx_queue_empty(struct net_device *dev)
2204{
2205 int i=0;
2206 struct r8192_priv *priv = ieee80211_priv(dev);
2207 for (i=0; i<=MGNT_QUEUE; i++)
2208 {
2209 if ((i== TXCMD_QUEUE) || (i == HCCA_QUEUE) )
2210 continue;
2211 if (skb_queue_len(&(&priv->tx_ring[i])->queue) > 0){
2212 printk("===>tx queue is not empty:%d, %d\n", i, skb_queue_len(&(&priv->tx_ring[i])->queue));
2213 return 0;
2214 }
2215 }
2216 return 1;
2217}
16d74da0 2218
5e1ad18a 2219static void rtl8192_hw_sleep_down(struct net_device *dev)
ecdfa446 2220{
65a43784 2221 struct r8192_priv *priv = ieee80211_priv(dev);
2222 unsigned long flags = 0;
2223
2224 spin_lock_irqsave(&priv->rf_ps_lock,flags);
2225 if (priv->RFChangeInProgress) {
2226 spin_unlock_irqrestore(&priv->rf_ps_lock,flags);
2227 RT_TRACE(COMP_RF, "rtl8192_hw_sleep_down(): RF Change in progress! \n");
2228 printk("rtl8192_hw_sleep_down(): RF Change in progress!\n");
2229 return;
2230 }
2231 spin_unlock_irqrestore(&priv->rf_ps_lock,flags);
65a43784 2232
ecdfa446
GKH
2233 MgntActSet_RF_State(dev, eRfSleep, RF_CHANGE_BY_PS);
2234}
16d74da0 2235
5e1ad18a 2236static void rtl8192_hw_sleep_wq (struct work_struct *work)
ecdfa446 2237{
ecdfa446
GKH
2238 struct delayed_work *dwork = container_of(work,struct delayed_work,work);
2239 struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,hw_sleep_wq);
2240 struct net_device *dev = ieee->dev;
65a43784 2241
ecdfa446
GKH
2242 rtl8192_hw_sleep_down(dev);
2243}
65a43784 2244
5e1ad18a 2245static void rtl8192_hw_wakeup(struct net_device* dev)
ecdfa446 2246{
65a43784 2247 struct r8192_priv *priv = ieee80211_priv(dev);
2248 unsigned long flags = 0;
2249
2250 spin_lock_irqsave(&priv->rf_ps_lock,flags);
2251 if (priv->RFChangeInProgress) {
2252 spin_unlock_irqrestore(&priv->rf_ps_lock,flags);
2253 RT_TRACE(COMP_RF, "rtl8192_hw_wakeup(): RF Change in progress! \n");
2254 printk("rtl8192_hw_wakeup(): RF Change in progress! schedule wake up task again\n");
2255 queue_delayed_work(priv->ieee80211->wq,&priv->ieee80211->hw_wakeup_wq,MSECS(10));//PowerSave is not supported if kernel version is below 2.6.20
2256 return;
2257 }
2258 spin_unlock_irqrestore(&priv->rf_ps_lock,flags);
ecdfa446 2259
ecdfa446 2260 MgntActSet_RF_State(dev, eRfOn, RF_CHANGE_BY_PS);
ecdfa446 2261}
65a43784 2262
ecdfa446
GKH
2263void rtl8192_hw_wakeup_wq (struct work_struct *work)
2264{
ecdfa446
GKH
2265 struct delayed_work *dwork = container_of(work,struct delayed_work,work);
2266 struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,hw_wakeup_wq);
2267 struct net_device *dev = ieee->dev;
ecdfa446
GKH
2268 rtl8192_hw_wakeup(dev);
2269
2270}
2271
2272#define MIN_SLEEP_TIME 50
2273#define MAX_SLEEP_TIME 10000
5e1ad18a 2274static void rtl8192_hw_to_sleep(struct net_device *dev, u32 th, u32 tl)
ecdfa446 2275{
ecdfa446
GKH
2276 struct r8192_priv *priv = ieee80211_priv(dev);
2277
2278 u32 rb = jiffies;
2279 unsigned long flags;
2280
2281 spin_lock_irqsave(&priv->ps_lock,flags);
2282
65a43784 2283 // Writing HW register with 0 equals to disable
2284 // the timer, that is not really what we want
2285 //
2286 tl -= MSECS(8+16+7);
ecdfa446 2287
65a43784 2288 // If the interval in witch we are requested to sleep is too
2289 // short then give up and remain awake
2290 // when we sleep after send null frame, the timer will be too short to sleep.
2291 //
ecdfa446 2292 if(((tl>=rb)&& (tl-rb) <= MSECS(MIN_SLEEP_TIME))
65a43784 2293 ||((rb>tl)&& (rb-tl) < MSECS(MIN_SLEEP_TIME))) {
ecdfa446 2294 spin_unlock_irqrestore(&priv->ps_lock,flags);
65a43784 2295 printk("too short to sleep::%x, %x, %lx\n",tl, rb, MSECS(MIN_SLEEP_TIME));
ecdfa446
GKH
2296 return;
2297 }
2298
ecdfa446 2299 if(((tl > rb) && ((tl-rb) > MSECS(MAX_SLEEP_TIME)))||
65a43784 2300 ((tl < rb) && (tl>MSECS(69)) && ((rb-tl) > MSECS(MAX_SLEEP_TIME)))||
2301 ((tl<rb)&&(tl<MSECS(69))&&((tl+0xffffffff-rb)>MSECS(MAX_SLEEP_TIME)))) {
ecdfa446
GKH
2302 printk("========>too long to sleep:%x, %x, %lx\n", tl, rb, MSECS(MAX_SLEEP_TIME));
2303 spin_unlock_irqrestore(&priv->ps_lock,flags);
2304 return;
2305 }
65a43784 2306 {
2307 u32 tmp = (tl>rb)?(tl-rb):(rb-tl);
2308 queue_delayed_work(priv->ieee80211->wq,
2309 &priv->ieee80211->hw_wakeup_wq,tmp);
2310 //PowerSave not supported when kernel version less 2.6.20
2311 }
2312 queue_delayed_work(priv->ieee80211->wq,
2313 (void *)&priv->ieee80211->hw_sleep_wq,0);
ecdfa446 2314 spin_unlock_irqrestore(&priv->ps_lock,flags);
65a43784 2315
ecdfa446 2316}
214985a6 2317
ecdfa446
GKH
2318static void rtl8192_init_priv_variable(struct net_device* dev)
2319{
2320 struct r8192_priv *priv = ieee80211_priv(dev);
2321 u8 i;
65a43784 2322 PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->ieee80211->PowerSaveControl));
2323
2324 // Default Halt the NIC if RF is OFF.
2325 pPSC->RegRfPsLevel |= RT_RF_OFF_LEVL_HALT_NIC;
2326 pPSC->RegRfPsLevel |= RT_RF_OFF_LEVL_CLK_REQ;
2327 pPSC->RegRfPsLevel |= RT_RF_OFF_LEVL_ASPM;
2328 pPSC->RegRfPsLevel |= RT_RF_LPS_LEVEL_ASPM;
2329 pPSC->bLeisurePs = true;
2330 pPSC->RegMaxLPSAwakeIntvl = 5;
2331 priv->bHwRadioOff = false;
2332
ecdfa446
GKH
2333 priv->being_init_adapter = false;
2334 priv->txbuffsize = 1600;//1024;
2335 priv->txfwbuffersize = 4096;
2336 priv->txringcount = 64;//32;
2337 //priv->txbeaconcount = priv->txringcount;
2338 priv->txbeaconcount = 2;
2339 priv->rxbuffersize = 9100;//2048;//1024;
2340 priv->rxringcount = MAX_RX_COUNT;//64;
2341 priv->irq_enabled=0;
2342 priv->card_8192 = NIC_8192E;
2343 priv->rx_skb_complete = 1;
2344 priv->chan = 1; //set to channel 1
2345 priv->RegWirelessMode = WIRELESS_MODE_AUTO;
2346 priv->RegChannelPlan = 0xf;
2347 priv->nrxAMPDU_size = 0;
2348 priv->nrxAMPDU_aggr_num = 0;
2349 priv->last_rxdesc_tsf_high = 0;
2350 priv->last_rxdesc_tsf_low = 0;
2351 priv->ieee80211->mode = WIRELESS_MODE_AUTO; //SET AUTO
2352 priv->ieee80211->iw_mode = IW_MODE_INFRA;
2353 priv->ieee80211->ieee_up=0;
2354 priv->retry_rts = DEFAULT_RETRY_RTS;
2355 priv->retry_data = DEFAULT_RETRY_DATA;
2356 priv->ieee80211->rts = DEFAULT_RTS_THRESHOLD;
2357 priv->ieee80211->rate = 110; //11 mbps
2358 priv->ieee80211->short_slot = 1;
2359 priv->promisc = (dev->flags & IFF_PROMISC) ? 1:0;
2360 priv->bcck_in_ch14 = false;
2361 priv->bfsync_processing = false;
2362 priv->CCKPresentAttentuation = 0;
2363 priv->rfa_txpowertrackingindex = 0;
2364 priv->rfc_txpowertrackingindex = 0;
2365 priv->CckPwEnl = 6;
2366 priv->ScanDelay = 50;//for Scan TODO
2367 //added by amy for silent reset
2368 priv->ResetProgress = RESET_TYPE_NORESET;
2369 priv->bForcedSilentReset = 0;
2370 priv->bDisableNormalResetCheck = false;
2371 priv->force_reset = false;
2372 //added by amy for power save
2373 priv->RegRfOff = 0;
2374 priv->ieee80211->RfOffReason = 0;
2375 priv->RFChangeInProgress = false;
2376 priv->bHwRfOffAction = 0;
2377 priv->SetRFPowerStateInProgress = false;
2378 priv->ieee80211->PowerSaveControl.bInactivePs = true;
2379 priv->ieee80211->PowerSaveControl.bIPSModeBackup = false;
2380 //just for debug
2381 priv->txpower_checkcnt = 0;
2382 priv->thermal_readback_index =0;
2383 priv->txpower_tracking_callback_cnt = 0;
2384 priv->ccktxpower_adjustcnt_ch14 = 0;
2385 priv->ccktxpower_adjustcnt_not_ch14 = 0;
2386
2387 priv->ieee80211->current_network.beacon_interval = DEFAULT_BEACONINTERVAL;
2388 priv->ieee80211->iw_mode = IW_MODE_INFRA;
2389 priv->ieee80211->softmac_features = IEEE_SOFTMAC_SCAN |
2390 IEEE_SOFTMAC_ASSOCIATE | IEEE_SOFTMAC_PROBERQ |
2391 IEEE_SOFTMAC_PROBERS | IEEE_SOFTMAC_TX_QUEUE;/* |
2392 IEEE_SOFTMAC_BEACONS;*///added by amy 080604 //| //IEEE_SOFTMAC_SINGLE_QUEUE;
2393
2394 priv->ieee80211->active_scan = 1;
2395 priv->ieee80211->modulation = IEEE80211_CCK_MODULATION | IEEE80211_OFDM_MODULATION;
2396 priv->ieee80211->host_encrypt = 1;
2397 priv->ieee80211->host_decrypt = 1;
2398 //priv->ieee80211->start_send_beacons = NULL;//rtl819xusb_beacon_tx;//-by amy 080604
2399 //priv->ieee80211->stop_send_beacons = NULL;//rtl8192_beacon_stop;//-by amy 080604
2400 priv->ieee80211->start_send_beacons = rtl8192_start_beacon;//+by david 081107
2401 priv->ieee80211->stop_send_beacons = rtl8192_stop_beacon;//+by david 081107
2402 priv->ieee80211->softmac_hard_start_xmit = rtl8192_hard_start_xmit;
2403 priv->ieee80211->set_chan = rtl8192_set_chan;
2404 priv->ieee80211->link_change = rtl8192_link_change;
2405 priv->ieee80211->softmac_data_hard_start_xmit = rtl8192_hard_data_xmit;
2406 priv->ieee80211->data_hard_stop = rtl8192_data_hard_stop;
2407 priv->ieee80211->data_hard_resume = rtl8192_data_hard_resume;
2408 priv->ieee80211->init_wmmparam_flag = 0;
2409 priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD;
2410 priv->ieee80211->check_nic_enough_desc = check_nic_enough_desc;
2411 priv->ieee80211->tx_headroom = sizeof(TX_FWINFO_8190PCI);
2412 priv->ieee80211->qos_support = 1;
2413 priv->ieee80211->dot11PowerSaveMode = 0;
2414 //added by WB
2415// priv->ieee80211->SwChnlByTimerHandler = rtl8192_phy_SwChnl;
2416 priv->ieee80211->SetBWModeHandler = rtl8192_SetBWMode;
2417 priv->ieee80211->handle_assoc_response = rtl8192_handle_assoc_response;
2418 priv->ieee80211->handle_beacon = rtl8192_handle_beacon;
2419
2420 priv->ieee80211->sta_wake_up = rtl8192_hw_wakeup;
2421// priv->ieee80211->ps_request_tx_ack = rtl8192_rq_tx_ack;
2422 priv->ieee80211->enter_sleep_state = rtl8192_hw_to_sleep;
2423 priv->ieee80211->ps_is_queue_empty = rtl8192_is_tx_queue_empty;
2424 //added by david
2425 priv->ieee80211->GetNmodeSupportBySecCfg = GetNmodeSupportBySecCfg8190Pci;
2426 priv->ieee80211->SetWirelessMode = rtl8192_SetWirelessMode;
2427 priv->ieee80211->GetHalfNmodeSupportByAPsHandler = GetHalfNmodeSupportByAPs819xPci;
2428
2429 //added by amy
2430 priv->ieee80211->InitialGainHandler = InitialGain819xPci;
2431
65a43784 2432#ifdef ENABLE_IPS
2433 priv->ieee80211->ieee80211_ips_leave_wq = ieee80211_ips_leave_wq;
2434 priv->ieee80211->ieee80211_ips_leave = ieee80211_ips_leave;
2435#endif
2436#ifdef ENABLE_LPS
2437 priv->ieee80211->LeisurePSLeave = LeisurePSLeave;
16d74da0 2438#endif
65a43784 2439
2440 priv->ieee80211->SetHwRegHandler = rtl8192e_SetHwReg;
2441 priv->ieee80211->rtllib_ap_sec_type = rtl8192e_ap_sec_type;
2442
ecdfa446
GKH
2443 priv->card_type = USB;
2444 {
2445 priv->ShortRetryLimit = 0x30;
2446 priv->LongRetryLimit = 0x30;
2447 }
2448 priv->EarlyRxThreshold = 7;
2449 priv->enable_gpio0 = 0;
2450
2451 priv->TransmitConfig = 0;
2452
2453 priv->ReceiveConfig = RCR_ADD3 |
2454 RCR_AMF | RCR_ADF | //accept management/data
2455 RCR_AICV | //accept control frame for SW AP needs PS-poll, 2005.07.07, by rcnjko.
2456 RCR_AB | RCR_AM | RCR_APM | //accept BC/MC/UC
2457 RCR_AAP | ((u32)7<<RCR_MXDMA_OFFSET) |
2458 ((u32)7 << RCR_FIFO_OFFSET) | RCR_ONLYERLPKT;
2459
207b58fb
MM
2460 priv->irq_mask = (u32)(IMR_ROK | IMR_VODOK | IMR_VIDOK | IMR_BEDOK | IMR_BKDOK |
2461 IMR_HCCADOK | IMR_MGNTDOK | IMR_COMDOK | IMR_HIGHDOK |
2462 IMR_BDOK | IMR_RXCMDOK | IMR_TIMEOUT0 | IMR_RDU | IMR_RXFOVW |
ecdfa446
GKH
2463 IMR_TXFOVW | IMR_BcnInt | IMR_TBDOK | IMR_TBDER);
2464
2465 priv->AcmControl = 0;
2466 priv->pFirmware = (rt_firmware*)vmalloc(sizeof(rt_firmware));
2467 if (priv->pFirmware)
2468 memset(priv->pFirmware, 0, sizeof(rt_firmware));
2469
2470 /* rx related queue */
2471 skb_queue_head_init(&priv->rx_queue);
2472 skb_queue_head_init(&priv->skb_queue);
2473
2474 /* Tx related queue */
2475 for(i = 0; i < MAX_QUEUE_SIZE; i++) {
2476 skb_queue_head_init(&priv->ieee80211->skb_waitQ [i]);
2477 }
2478 for(i = 0; i < MAX_QUEUE_SIZE; i++) {
2479 skb_queue_head_init(&priv->ieee80211->skb_aggQ [i]);
2480 }
2481 priv->rf_set_chan = rtl8192_phy_SwChnl;
2482}
2483
ecdfa446
GKH
2484static void rtl8192_init_priv_lock(struct r8192_priv* priv)
2485{
2486 spin_lock_init(&priv->tx_lock);
2487 spin_lock_init(&priv->irq_lock);//added by thomas
2488 spin_lock_init(&priv->irq_th_lock);
2489 spin_lock_init(&priv->rf_ps_lock);
2490 spin_lock_init(&priv->ps_lock);
2491 //spin_lock_init(&priv->rf_lock);
2492 sema_init(&priv->wx_sem,1);
2493 sema_init(&priv->rf_sem,1);
ecdfa446 2494 mutex_init(&priv->mutex);
ecdfa446
GKH
2495}
2496
214985a6 2497/* init tasklet and wait_queue here */
ecdfa446
GKH
2498#define DRV_NAME "wlan0"
2499static void rtl8192_init_priv_task(struct net_device* dev)
2500{
2501 struct r8192_priv *priv = ieee80211_priv(dev);
2502
ecdfa446
GKH
2503#ifdef PF_SYNCTHREAD
2504 priv->priv_wq = create_workqueue(DRV_NAME,0);
2505#else
2506 priv->priv_wq = create_workqueue(DRV_NAME);
2507#endif
ecdfa446 2508
65a43784 2509#ifdef ENABLE_IPS
2510 INIT_WORK(&priv->ieee80211->ips_leave_wq, (void*)IPSLeave_wq);
2511#endif
2512
ecdfa446
GKH
2513// INIT_WORK(&priv->reset_wq, (void(*)(void*)) rtl8192_restart);
2514 INIT_WORK(&priv->reset_wq, rtl8192_restart);
2515// INIT_DELAYED_WORK(&priv->watch_dog_wq, hal_dm_watchdog);
2516 INIT_DELAYED_WORK(&priv->watch_dog_wq, rtl819x_watchdog_wqcallback);
2517 INIT_DELAYED_WORK(&priv->txpower_tracking_wq, dm_txpower_trackingcallback);
2518 INIT_DELAYED_WORK(&priv->rfpath_check_wq, dm_rf_pathcheck_workitemcallback);
2519 INIT_DELAYED_WORK(&priv->update_beacon_wq, rtl8192_update_beacon);
2520 //INIT_WORK(&priv->SwChnlWorkItem, rtl8192_SwChnl_WorkItem);
2521 //INIT_WORK(&priv->SetBWModeWorkItem, rtl8192_SetBWModeWorkItem);
2522 INIT_WORK(&priv->qos_activate, rtl8192_qos_activate);
2523 INIT_DELAYED_WORK(&priv->ieee80211->hw_wakeup_wq,(void*) rtl8192_hw_wakeup_wq);
2524 INIT_DELAYED_WORK(&priv->ieee80211->hw_sleep_wq,(void*) rtl8192_hw_sleep_wq);
2525
ecdfa446
GKH
2526 tasklet_init(&priv->irq_rx_tasklet,
2527 (void(*)(unsigned long))rtl8192_irq_rx_tasklet,
2528 (unsigned long)priv);
2529 tasklet_init(&priv->irq_tx_tasklet,
2530 (void(*)(unsigned long))rtl8192_irq_tx_tasklet,
2531 (unsigned long)priv);
2532 tasklet_init(&priv->irq_prepare_beacon_tasklet,
2533 (void(*)(unsigned long))rtl8192_prepare_beacon,
2534 (unsigned long)priv);
2535}
2536
2537static void rtl8192_get_eeprom_size(struct net_device* dev)
2538{
2539 u16 curCR = 0;
2540 struct r8192_priv *priv = ieee80211_priv(dev);
2541 RT_TRACE(COMP_INIT, "===========>%s()\n", __FUNCTION__);
2542 curCR = read_nic_dword(dev, EPROM_CMD);
2543 RT_TRACE(COMP_INIT, "read from Reg Cmd9346CR(%x):%x\n", EPROM_CMD, curCR);
2544 //whether need I consider BIT5?
2545 priv->epromtype = (curCR & EPROM_CMD_9356SEL) ? EPROM_93c56 : EPROM_93c46;
2546 RT_TRACE(COMP_INIT, "<===========%s(), epromtype:%d\n", __FUNCTION__, priv->epromtype);
2547}
2548
214985a6
MM
2549/*
2550 * used to swap endian. as ntohl & htonl are not
2551 * neccessary to swap endian, so use this instead.
2552 */
ecdfa446
GKH
2553static inline u16 endian_swap(u16* data)
2554{
2555 u16 tmp = *data;
2556 *data = (tmp >> 8) | (tmp << 8);
2557 return *data;
2558}
2559
2560/*
214985a6
MM
2561 * Adapter->EEPROMAddressSize should be set before this function call.
2562 * EEPROM address size can be got through GetEEPROMSize8185()
2563 */
ecdfa446
GKH
2564static void rtl8192_read_eeprom_info(struct net_device* dev)
2565{
2566 struct r8192_priv *priv = ieee80211_priv(dev);
2567
2568 u8 tempval;
2569#ifdef RTL8192E
2570 u8 ICVer8192, ICVer8256;
2571#endif
2572 u16 i,usValue, IC_Version;
2573 u16 EEPROMId;
2574#ifdef RTL8190P
16d74da0 2575 u8 offset;
ecdfa446
GKH
2576 u8 EepromTxPower[100];
2577#endif
2578 u8 bMac_Tmp_Addr[6] = {0x00, 0xe0, 0x4c, 0x00, 0x00, 0x01};
2579 RT_TRACE(COMP_INIT, "====> rtl8192_read_eeprom_info\n");
2580
2581
2582 // TODO: I don't know if we need to apply EF function to EEPROM read function
2583
2584 //2 Read EEPROM ID to make sure autoload is success
2585 EEPROMId = eprom_read(dev, 0);
2586 if( EEPROMId != RTL8190_EEPROM_ID )
2587 {
2588 RT_TRACE(COMP_ERR, "EEPROM ID is invalid:%x, %x\n", EEPROMId, RTL8190_EEPROM_ID);
2589 priv->AutoloadFailFlag=true;
2590 }
2591 else
2592 {
2593 priv->AutoloadFailFlag=false;
2594 }
2595
2596 //
2597 // Assign Chip Version ID
2598 //
2599 // Read IC Version && Channel Plan
2600 if(!priv->AutoloadFailFlag)
2601 {
2602 // VID, PID
2603 priv->eeprom_vid = eprom_read(dev, (EEPROM_VID >> 1));
2604 priv->eeprom_did = eprom_read(dev, (EEPROM_DID >> 1));
2605
2606 usValue = eprom_read(dev, (u16)(EEPROM_Customer_ID>>1)) >> 8 ;
2607 priv->eeprom_CustomerID = (u8)( usValue & 0xff);
2608 usValue = eprom_read(dev, (EEPROM_ICVersion_ChannelPlan>>1));
2609 priv->eeprom_ChannelPlan = usValue&0xff;
2610 IC_Version = ((usValue&0xff00)>>8);
2611
2612#ifdef RTL8190P
2613 priv->card_8192_version = (VERSION_8190)(IC_Version);
2614#else
2615 #ifdef RTL8192E
2616 ICVer8192 = (IC_Version&0xf); //bit0~3; 1:A cut, 2:B cut, 3:C cut...
2617 ICVer8256 = ((IC_Version&0xf0)>>4);//bit4~6, bit7 reserved for other RF chip; 1:A cut, 2:B cut, 3:C cut...
2618 RT_TRACE(COMP_INIT, "\nICVer8192 = 0x%x\n", ICVer8192);
2619 RT_TRACE(COMP_INIT, "\nICVer8256 = 0x%x\n", ICVer8256);
2620 if(ICVer8192 == 0x2) //B-cut
2621 {
2622 if(ICVer8256 == 0x5) //E-cut
2623 priv->card_8192_version= VERSION_8190_BE;
2624 }
2625 #endif
2626#endif
2627 switch(priv->card_8192_version)
2628 {
2629 case VERSION_8190_BD:
2630 case VERSION_8190_BE:
2631 break;
2632 default:
2633 priv->card_8192_version = VERSION_8190_BD;
2634 break;
2635 }
2636 RT_TRACE(COMP_INIT, "\nIC Version = 0x%x\n", priv->card_8192_version);
2637 }
2638 else
2639 {
2640 priv->card_8192_version = VERSION_8190_BD;
2641 priv->eeprom_vid = 0;
2642 priv->eeprom_did = 0;
2643 priv->eeprom_CustomerID = 0;
2644 priv->eeprom_ChannelPlan = 0;
2645 RT_TRACE(COMP_INIT, "\nIC Version = 0x%x\n", 0xff);
2646 }
2647
2648 RT_TRACE(COMP_INIT, "EEPROM VID = 0x%4x\n", priv->eeprom_vid);
2649 RT_TRACE(COMP_INIT, "EEPROM DID = 0x%4x\n", priv->eeprom_did);
2650 RT_TRACE(COMP_INIT,"EEPROM Customer ID: 0x%2x\n", priv->eeprom_CustomerID);
2651
2652 //2 Read Permanent MAC address
2653 if(!priv->AutoloadFailFlag)
2654 {
2655 for(i = 0; i < 6; i += 2)
2656 {
2657 usValue = eprom_read(dev, (u16) ((EEPROM_NODE_ADDRESS_BYTE_0+i)>>1));
2658 *(u16*)(&dev->dev_addr[i]) = usValue;
2659 }
2660 } else {
2661 // when auto load failed, the last address byte set to be a random one.
2662 // added by david woo.2007/11/7
2663 memcpy(dev->dev_addr, bMac_Tmp_Addr, 6);
ecdfa446
GKH
2664 }
2665
820793c3 2666 RT_TRACE(COMP_INIT, "Permanent Address = %pM\n", dev->dev_addr);
ecdfa446
GKH
2667
2668 //2 TX Power Check EEPROM Fail or not
2669 if(priv->card_8192_version > VERSION_8190_BD) {
2670 priv->bTXPowerDataReadFromEEPORM = true;
2671 } else {
2672 priv->bTXPowerDataReadFromEEPORM = false;
2673 }
2674
bbc9a991 2675 // 2007/11/15 MH 8190PCI Default=2T4R, 8192PCIE default=1T2R
ecdfa446
GKH
2676 priv->rf_type = RTL819X_DEFAULT_RF_TYPE;
2677
2678 if(priv->card_8192_version > VERSION_8190_BD)
2679 {
2680 // Read RF-indication and Tx Power gain index diff of legacy to HT OFDM rate.
2681 if(!priv->AutoloadFailFlag)
2682 {
2683 tempval = (eprom_read(dev, (EEPROM_RFInd_PowerDiff>>1))) & 0xff;
2684 priv->EEPROMLegacyHTTxPowerDiff = tempval & 0xf; // bit[3:0]
2685
2686 if (tempval&0x80) //RF-indication, bit[7]
2687 priv->rf_type = RF_1T2R;
2688 else
2689 priv->rf_type = RF_2T4R;
2690 }
2691 else
2692 {
2693 priv->EEPROMLegacyHTTxPowerDiff = EEPROM_Default_LegacyHTTxPowerDiff;
2694 }
2695 RT_TRACE(COMP_INIT, "EEPROMLegacyHTTxPowerDiff = %d\n",
2696 priv->EEPROMLegacyHTTxPowerDiff);
2697
2698 // Read ThermalMeter from EEPROM
2699 if(!priv->AutoloadFailFlag)
2700 {
2701 priv->EEPROMThermalMeter = (u8)(((eprom_read(dev, (EEPROM_ThermalMeter>>1))) & 0xff00)>>8);
2702 }
2703 else
2704 {
2705 priv->EEPROMThermalMeter = EEPROM_Default_ThermalMeter;
2706 }
2707 RT_TRACE(COMP_INIT, "ThermalMeter = %d\n", priv->EEPROMThermalMeter);
2708 //vivi, for tx power track
2709 priv->TSSI_13dBm = priv->EEPROMThermalMeter *100;
2710
2711 if(priv->epromtype == EPROM_93c46)
2712 {
2713 // Read antenna tx power offset of B/C/D to A and CrystalCap from EEPROM
2714 if(!priv->AutoloadFailFlag)
2715 {
2716 usValue = eprom_read(dev, (EEPROM_TxPwDiff_CrystalCap>>1));
2717 priv->EEPROMAntPwDiff = (usValue&0x0fff);
2718 priv->EEPROMCrystalCap = (u8)((usValue&0xf000)>>12);
2719 }
2720 else
2721 {
2722 priv->EEPROMAntPwDiff = EEPROM_Default_AntTxPowerDiff;
2723 priv->EEPROMCrystalCap = EEPROM_Default_TxPwDiff_CrystalCap;
2724 }
2725 RT_TRACE(COMP_INIT, "EEPROMAntPwDiff = %d\n", priv->EEPROMAntPwDiff);
2726 RT_TRACE(COMP_INIT, "EEPROMCrystalCap = %d\n", priv->EEPROMCrystalCap);
2727
2728 //
2729 // Get per-channel Tx Power Level
2730 //
2731 for(i=0; i<14; i+=2)
2732 {
2733 if(!priv->AutoloadFailFlag)
2734 {
2735 usValue = eprom_read(dev, (u16) ((EEPROM_TxPwIndex_CCK+i)>>1) );
2736 }
2737 else
2738 {
2739 usValue = EEPROM_Default_TxPower;
2740 }
2741 *((u16*)(&priv->EEPROMTxPowerLevelCCK[i])) = usValue;
2742 RT_TRACE(COMP_INIT,"CCK Tx Power Level, Index %d = 0x%02x\n", i, priv->EEPROMTxPowerLevelCCK[i]);
2743 RT_TRACE(COMP_INIT, "CCK Tx Power Level, Index %d = 0x%02x\n", i+1, priv->EEPROMTxPowerLevelCCK[i+1]);
2744 }
2745 for(i=0; i<14; i+=2)
2746 {
2747 if(!priv->AutoloadFailFlag)
2748 {
2749 usValue = eprom_read(dev, (u16) ((EEPROM_TxPwIndex_OFDM_24G+i)>>1) );
2750 }
2751 else
2752 {
2753 usValue = EEPROM_Default_TxPower;
2754 }
2755 *((u16*)(&priv->EEPROMTxPowerLevelOFDM24G[i])) = usValue;
2756 RT_TRACE(COMP_INIT, "OFDM 2.4G Tx Power Level, Index %d = 0x%02x\n", i, priv->EEPROMTxPowerLevelOFDM24G[i]);
2757 RT_TRACE(COMP_INIT, "OFDM 2.4G Tx Power Level, Index %d = 0x%02x\n", i+1, priv->EEPROMTxPowerLevelOFDM24G[i+1]);
2758 }
2759 }
2760 else if(priv->epromtype== EPROM_93c56)
2761 {
2762 #ifdef RTL8190P
2763 // Read CrystalCap from EEPROM
2764 if(!priv->AutoloadFailFlag)
2765 {
2766 priv->EEPROMAntPwDiff = EEPROM_Default_AntTxPowerDiff;
2767 priv->EEPROMCrystalCap = (u8)(((eprom_read(dev, (EEPROM_C56_CrystalCap>>1))) & 0xf000)>>12);
2768 }
2769 else
2770 {
2771 priv->EEPROMAntPwDiff = EEPROM_Default_AntTxPowerDiff;
2772 priv->EEPROMCrystalCap = EEPROM_Default_TxPwDiff_CrystalCap;
2773 }
2774 RT_TRACE(COMP_INIT,"EEPROMAntPwDiff = %d\n", priv->EEPROMAntPwDiff);
2775 RT_TRACE(COMP_INIT, "EEPROMCrystalCap = %d\n", priv->EEPROMCrystalCap);
2776
2777 // Get Tx Power Level by Channel
2778 if(!priv->AutoloadFailFlag)
2779 {
2780 // Read Tx power of Channel 1 ~ 14 from EEPROM.
2781 for(i = 0; i < 12; i+=2)
2782 {
2783 if (i <6)
2784 offset = EEPROM_C56_RfA_CCK_Chnl1_TxPwIndex + i;
2785 else
2786 offset = EEPROM_C56_RfC_CCK_Chnl1_TxPwIndex + i - 6;
2787 usValue = eprom_read(dev, (offset>>1));
2788 *((u16*)(&EepromTxPower[i])) = usValue;
2789 }
2790
2791 for(i = 0; i < 12; i++)
2792 {
2793 if (i <= 2)
2794 priv->EEPROMRfACCKChnl1TxPwLevel[i] = EepromTxPower[i];
2795 else if ((i >=3 )&&(i <= 5))
2796 priv->EEPROMRfAOfdmChnlTxPwLevel[i-3] = EepromTxPower[i];
2797 else if ((i >=6 )&&(i <= 8))
2798 priv->EEPROMRfCCCKChnl1TxPwLevel[i-6] = EepromTxPower[i];
2799 else
2800 priv->EEPROMRfCOfdmChnlTxPwLevel[i-9] = EepromTxPower[i];
2801 }
2802 }
2803 else
2804 {
2805 priv->EEPROMRfACCKChnl1TxPwLevel[0] = EEPROM_Default_TxPowerLevel;
2806 priv->EEPROMRfACCKChnl1TxPwLevel[1] = EEPROM_Default_TxPowerLevel;
2807 priv->EEPROMRfACCKChnl1TxPwLevel[2] = EEPROM_Default_TxPowerLevel;
2808
2809 priv->EEPROMRfAOfdmChnlTxPwLevel[0] = EEPROM_Default_TxPowerLevel;
2810 priv->EEPROMRfAOfdmChnlTxPwLevel[1] = EEPROM_Default_TxPowerLevel;
2811 priv->EEPROMRfAOfdmChnlTxPwLevel[2] = EEPROM_Default_TxPowerLevel;
2812
2813 priv->EEPROMRfCCCKChnl1TxPwLevel[0] = EEPROM_Default_TxPowerLevel;
2814 priv->EEPROMRfCCCKChnl1TxPwLevel[1] = EEPROM_Default_TxPowerLevel;
2815 priv->EEPROMRfCCCKChnl1TxPwLevel[2] = EEPROM_Default_TxPowerLevel;
2816
2817 priv->EEPROMRfCOfdmChnlTxPwLevel[0] = EEPROM_Default_TxPowerLevel;
2818 priv->EEPROMRfCOfdmChnlTxPwLevel[1] = EEPROM_Default_TxPowerLevel;
2819 priv->EEPROMRfCOfdmChnlTxPwLevel[2] = EEPROM_Default_TxPowerLevel;
2820 }
2821 RT_TRACE(COMP_INIT, "priv->EEPROMRfACCKChnl1TxPwLevel[0] = 0x%x\n", priv->EEPROMRfACCKChnl1TxPwLevel[0]);
2822 RT_TRACE(COMP_INIT, "priv->EEPROMRfACCKChnl1TxPwLevel[1] = 0x%x\n", priv->EEPROMRfACCKChnl1TxPwLevel[1]);
2823 RT_TRACE(COMP_INIT, "priv->EEPROMRfACCKChnl1TxPwLevel[2] = 0x%x\n", priv->EEPROMRfACCKChnl1TxPwLevel[2]);
2824 RT_TRACE(COMP_INIT, "priv->EEPROMRfAOfdmChnlTxPwLevel[0] = 0x%x\n", priv->EEPROMRfAOfdmChnlTxPwLevel[0]);
2825 RT_TRACE(COMP_INIT, "priv->EEPROMRfAOfdmChnlTxPwLevel[1] = 0x%x\n", priv->EEPROMRfAOfdmChnlTxPwLevel[1]);
2826 RT_TRACE(COMP_INIT, "priv->EEPROMRfAOfdmChnlTxPwLevel[2] = 0x%x\n", priv->EEPROMRfAOfdmChnlTxPwLevel[2]);
2827 RT_TRACE(COMP_INIT, "priv->EEPROMRfCCCKChnl1TxPwLevel[0] = 0x%x\n", priv->EEPROMRfCCCKChnl1TxPwLevel[0]);
2828 RT_TRACE(COMP_INIT, "priv->EEPROMRfCCCKChnl1TxPwLevel[1] = 0x%x\n", priv->EEPROMRfCCCKChnl1TxPwLevel[1]);
2829 RT_TRACE(COMP_INIT, "priv->EEPROMRfCCCKChnl1TxPwLevel[2] = 0x%x\n", priv->EEPROMRfCCCKChnl1TxPwLevel[2]);
2830 RT_TRACE(COMP_INIT, "priv->EEPROMRfCOfdmChnlTxPwLevel[0] = 0x%x\n", priv->EEPROMRfCOfdmChnlTxPwLevel[0]);
2831 RT_TRACE(COMP_INIT, "priv->EEPROMRfCOfdmChnlTxPwLevel[1] = 0x%x\n", priv->EEPROMRfCOfdmChnlTxPwLevel[1]);
2832 RT_TRACE(COMP_INIT, "priv->EEPROMRfCOfdmChnlTxPwLevel[2] = 0x%x\n", priv->EEPROMRfCOfdmChnlTxPwLevel[2]);
2833#endif
2834
2835 }
2836 //
2837 // Update HAL variables.
2838 //
2839 if(priv->epromtype == EPROM_93c46)
2840 {
2841 for(i=0; i<14; i++)
2842 {
2843 priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelCCK[i];
2844 priv->TxPowerLevelOFDM24G[i] = priv->EEPROMTxPowerLevelOFDM24G[i];
2845 }
2846 priv->LegacyHTTxPowerDiff = priv->EEPROMLegacyHTTxPowerDiff;
2847 // Antenna B gain offset to antenna A, bit0~3
2848 priv->AntennaTxPwDiff[0] = (priv->EEPROMAntPwDiff & 0xf);
2849 // Antenna C gain offset to antenna A, bit4~7
2850 priv->AntennaTxPwDiff[1] = ((priv->EEPROMAntPwDiff & 0xf0)>>4);
2851 // Antenna D gain offset to antenna A, bit8~11
2852 priv->AntennaTxPwDiff[2] = ((priv->EEPROMAntPwDiff & 0xf00)>>8);
2853 // CrystalCap, bit12~15
2854 priv->CrystalCap = priv->EEPROMCrystalCap;
2855 // ThermalMeter, bit0~3 for RFIC1, bit4~7 for RFIC2
2856 priv->ThermalMeter[0] = (priv->EEPROMThermalMeter & 0xf);
2857 priv->ThermalMeter[1] = ((priv->EEPROMThermalMeter & 0xf0)>>4);
2858 }
2859 else if(priv->epromtype == EPROM_93c56)
2860 {
2861 //char cck_pwr_diff_a=0, cck_pwr_diff_c=0;
2862
2863 //cck_pwr_diff_a = pHalData->EEPROMRfACCKChnl7TxPwLevel - pHalData->EEPROMRfAOfdmChnlTxPwLevel[1];
2864 //cck_pwr_diff_c = pHalData->EEPROMRfCCCKChnl7TxPwLevel - pHalData->EEPROMRfCOfdmChnlTxPwLevel[1];
2865 for(i=0; i<3; i++) // channel 1~3 use the same Tx Power Level.
2866 {
2867 priv->TxPowerLevelCCK_A[i] = priv->EEPROMRfACCKChnl1TxPwLevel[0];
2868 priv->TxPowerLevelOFDM24G_A[i] = priv->EEPROMRfAOfdmChnlTxPwLevel[0];
2869 priv->TxPowerLevelCCK_C[i] = priv->EEPROMRfCCCKChnl1TxPwLevel[0];
2870 priv->TxPowerLevelOFDM24G_C[i] = priv->EEPROMRfCOfdmChnlTxPwLevel[0];
2871 }
2872 for(i=3; i<9; i++) // channel 4~9 use the same Tx Power Level
2873 {
2874 priv->TxPowerLevelCCK_A[i] = priv->EEPROMRfACCKChnl1TxPwLevel[1];
2875 priv->TxPowerLevelOFDM24G_A[i] = priv->EEPROMRfAOfdmChnlTxPwLevel[1];
2876 priv->TxPowerLevelCCK_C[i] = priv->EEPROMRfCCCKChnl1TxPwLevel[1];
2877 priv->TxPowerLevelOFDM24G_C[i] = priv->EEPROMRfCOfdmChnlTxPwLevel[1];
2878 }
2879 for(i=9; i<14; i++) // channel 10~14 use the same Tx Power Level
2880 {
2881 priv->TxPowerLevelCCK_A[i] = priv->EEPROMRfACCKChnl1TxPwLevel[2];
2882 priv->TxPowerLevelOFDM24G_A[i] = priv->EEPROMRfAOfdmChnlTxPwLevel[2];
2883 priv->TxPowerLevelCCK_C[i] = priv->EEPROMRfCCCKChnl1TxPwLevel[2];
2884 priv->TxPowerLevelOFDM24G_C[i] = priv->EEPROMRfCOfdmChnlTxPwLevel[2];
2885 }
2886 for(i=0; i<14; i++)
2887 RT_TRACE(COMP_INIT, "priv->TxPowerLevelCCK_A[%d] = 0x%x\n", i, priv->TxPowerLevelCCK_A[i]);
2888 for(i=0; i<14; i++)
2889 RT_TRACE(COMP_INIT,"priv->TxPowerLevelOFDM24G_A[%d] = 0x%x\n", i, priv->TxPowerLevelOFDM24G_A[i]);
2890 for(i=0; i<14; i++)
2891 RT_TRACE(COMP_INIT, "priv->TxPowerLevelCCK_C[%d] = 0x%x\n", i, priv->TxPowerLevelCCK_C[i]);
2892 for(i=0; i<14; i++)
2893 RT_TRACE(COMP_INIT, "priv->TxPowerLevelOFDM24G_C[%d] = 0x%x\n", i, priv->TxPowerLevelOFDM24G_C[i]);
2894 priv->LegacyHTTxPowerDiff = priv->EEPROMLegacyHTTxPowerDiff;
2895 priv->AntennaTxPwDiff[0] = 0;
2896 priv->AntennaTxPwDiff[1] = 0;
2897 priv->AntennaTxPwDiff[2] = 0;
2898 priv->CrystalCap = priv->EEPROMCrystalCap;
2899 // ThermalMeter, bit0~3 for RFIC1, bit4~7 for RFIC2
2900 priv->ThermalMeter[0] = (priv->EEPROMThermalMeter & 0xf);
2901 priv->ThermalMeter[1] = ((priv->EEPROMThermalMeter & 0xf0)>>4);
2902 }
2903 }
2904
2905 if(priv->rf_type == RF_1T2R)
2906 {
2907 RT_TRACE(COMP_INIT, "\n1T2R config\n");
2908 }
2909 else if (priv->rf_type == RF_2T4R)
2910 {
2911 RT_TRACE(COMP_INIT, "\n2T4R config\n");
2912 }
2913
2914 // 2008/01/16 MH We can only know RF type in the function. So we have to init
2915 // DIG RATR table again.
2916 init_rate_adaptive(dev);
2917
2918 //1 Make a copy for following variables and we can change them if we want
2919
2920 priv->rf_chip= RF_8256;
2921
2922 if(priv->RegChannelPlan == 0xf)
2923 {
2924 priv->ChannelPlan = priv->eeprom_ChannelPlan;
2925 }
2926 else
2927 {
2928 priv->ChannelPlan = priv->RegChannelPlan;
2929 }
2930
2931 //
2932 // Used PID and DID to Set CustomerID
2933 //
2934 if( priv->eeprom_vid == 0x1186 && priv->eeprom_did == 0x3304 )
2935 {
2936 priv->CustomerID = RT_CID_DLINK;
2937 }
2938
2939 switch(priv->eeprom_CustomerID)
2940 {
2941 case EEPROM_CID_DEFAULT:
2942 priv->CustomerID = RT_CID_DEFAULT;
2943 break;
2944 case EEPROM_CID_CAMEO:
2945 priv->CustomerID = RT_CID_819x_CAMEO;
2946 break;
2947 case EEPROM_CID_RUNTOP:
2948 priv->CustomerID = RT_CID_819x_RUNTOP;
2949 break;
2950 case EEPROM_CID_NetCore:
2951 priv->CustomerID = RT_CID_819x_Netcore;
2952 break;
2953 case EEPROM_CID_TOSHIBA: // Merge by Jacken, 2008/01/31
2954 priv->CustomerID = RT_CID_TOSHIBA;
2955 if(priv->eeprom_ChannelPlan&0x80)
2956 priv->ChannelPlan = priv->eeprom_ChannelPlan&0x7f;
2957 else
2958 priv->ChannelPlan = 0x0;
2959 RT_TRACE(COMP_INIT, "Toshiba ChannelPlan = 0x%x\n",
2960 priv->ChannelPlan);
2961 break;
2962 case EEPROM_CID_Nettronix:
2963 priv->ScanDelay = 100; //cosa add for scan
2964 priv->CustomerID = RT_CID_Nettronix;
2965 break;
2966 case EEPROM_CID_Pronet:
2967 priv->CustomerID = RT_CID_PRONET;
2968 break;
2969 case EEPROM_CID_DLINK:
2970 priv->CustomerID = RT_CID_DLINK;
2971 break;
2972
2973 case EEPROM_CID_WHQL:
2974 //Adapter->bInHctTest = TRUE;//do not supported
2975
2976 //priv->bSupportTurboMode = FALSE;
2977 //priv->bAutoTurboBy8186 = FALSE;
2978
2979 //pMgntInfo->PowerSaveControl.bInactivePs = FALSE;
2980 //pMgntInfo->PowerSaveControl.bIPSModeBackup = FALSE;
2981 //pMgntInfo->PowerSaveControl.bLeisurePs = FALSE;
2982
2983 break;
2984 default:
2985 // value from RegCustomerID
2986 break;
2987 }
2988
2989 //Avoid the channel plan array overflow, by Bruce, 2007-08-27.
2990 if(priv->ChannelPlan > CHANNEL_PLAN_LEN - 1)
2991 priv->ChannelPlan = 0; //FCC
2992
2993 switch(priv->CustomerID)
2994 {
2995 case RT_CID_DEFAULT:
2996 #ifdef RTL8190P
2997 priv->LedStrategy = HW_LED;
2998 #else
2999 #ifdef RTL8192E
3000 priv->LedStrategy = SW_LED_MODE1;
3001 #endif
3002 #endif
3003 break;
3004
3005 case RT_CID_819x_CAMEO:
3006 priv->LedStrategy = SW_LED_MODE2;
3007 break;
3008
3009 case RT_CID_819x_RUNTOP:
3010 priv->LedStrategy = SW_LED_MODE3;
3011 break;
3012
3013 case RT_CID_819x_Netcore:
3014 priv->LedStrategy = SW_LED_MODE4;
3015 break;
3016
3017 case RT_CID_Nettronix:
3018 priv->LedStrategy = SW_LED_MODE5;
3019 break;
3020
3021 case RT_CID_PRONET:
3022 priv->LedStrategy = SW_LED_MODE6;
3023 break;
3024
3025 case RT_CID_TOSHIBA: //Modify by Jacken 2008/01/31
3026 // Do nothing.
3027 //break;
3028
3029 default:
3030 #ifdef RTL8190P
3031 priv->LedStrategy = HW_LED;
3032 #else
3033 #ifdef RTL8192E
3034 priv->LedStrategy = SW_LED_MODE1;
3035 #endif
3036 #endif
3037 break;
3038 }
65a43784 3039
3040
ecdfa446 3041 if( priv->eeprom_vid == 0x1186 && priv->eeprom_did == 0x3304)
65a43784 3042 priv->ieee80211->bSupportRemoteWakeUp = true;
ecdfa446 3043 else
65a43784 3044 priv->ieee80211->bSupportRemoteWakeUp = false;
3045
3046
ecdfa446
GKH
3047 RT_TRACE(COMP_INIT, "RegChannelPlan(%d)\n", priv->RegChannelPlan);
3048 RT_TRACE(COMP_INIT, "ChannelPlan = %d \n", priv->ChannelPlan);
3049 RT_TRACE(COMP_INIT, "LedStrategy = %d \n", priv->LedStrategy);
3050 RT_TRACE(COMP_TRACE, "<==== ReadAdapterInfo\n");
3051
3052 return ;
3053}
3054
3055
5e1ad18a 3056static short rtl8192_get_channel_map(struct net_device * dev)
ecdfa446
GKH
3057{
3058 struct r8192_priv *priv = ieee80211_priv(dev);
3059#ifdef ENABLE_DOT11D
3060 if(priv->ChannelPlan> COUNTRY_CODE_GLOBAL_DOMAIN){
3061 printk("rtl8180_init:Error channel plan! Set to default.\n");
3062 priv->ChannelPlan= 0;
3063 }
3064 RT_TRACE(COMP_INIT, "Channel plan is %d\n",priv->ChannelPlan);
3065
3066 rtl819x_set_channel_map(priv->ChannelPlan, priv);
3067#else
3068 int ch,i;
3069 //Set Default Channel Plan
3070 if(!channels){
3071 DMESG("No channels, aborting");
3072 return -1;
3073 }
3074 ch=channels;
3075 priv->ChannelPlan= 0;//hikaru
3076 // set channels 1..14 allowed in given locale
3077 for (i=1; i<=14; i++) {
3078 (priv->ieee80211->channel_map)[i] = (u8)(ch & 0x01);
3079 ch >>= 1;
3080 }
3081#endif
3082 return 0;
3083}
5e1ad18a
GKH
3084
3085static short rtl8192_init(struct net_device *dev)
ecdfa446
GKH
3086{
3087 struct r8192_priv *priv = ieee80211_priv(dev);
3088 memset(&(priv->stats),0,sizeof(struct Stats));
3089 rtl8192_init_priv_variable(dev);
3090 rtl8192_init_priv_lock(priv);
3091 rtl8192_init_priv_task(dev);
3092 rtl8192_get_eeprom_size(dev);
3093 rtl8192_read_eeprom_info(dev);
3094 rtl8192_get_channel_map(dev);
3095 init_hal_dm(dev);
3096 init_timer(&priv->watch_dog_timer);
3097 priv->watch_dog_timer.data = (unsigned long)dev;
3098 priv->watch_dog_timer.function = watch_dog_timer_callback;
3099#if defined(IRQF_SHARED)
3100 if(request_irq(dev->irq, (void*)rtl8192_interrupt, IRQF_SHARED, dev->name, dev)){
3101#else
3102 if(request_irq(dev->irq, (void *)rtl8192_interrupt, SA_SHIRQ, dev->name, dev)){
3103#endif
3104 printk("Error allocating IRQ %d",dev->irq);
3105 return -1;
3106 }else{
3107 priv->irq=dev->irq;
3108 printk("IRQ %d",dev->irq);
3109 }
3110 if(rtl8192_pci_initdescring(dev)!=0){
3111 printk("Endopoints initialization failed");
3112 return -1;
3113 }
3114
3115 //rtl8192_rx_enable(dev);
3116 //rtl8192_adapter_start(dev);
ecdfa446
GKH
3117 return 0;
3118}
3119
214985a6
MM
3120/*
3121 * Actually only set RRSR, RATR and BW_OPMODE registers
3122 * not to do all the hw config as its name says
3123 * This part need to modified according to the rate set we filtered
3124 */
5e1ad18a 3125static void rtl8192_hwconfig(struct net_device* dev)
ecdfa446
GKH
3126{
3127 u32 regRATR = 0, regRRSR = 0;
3128 u8 regBwOpMode = 0, regTmp = 0;
3129 struct r8192_priv *priv = ieee80211_priv(dev);
3130
3131// Set RRSR, RATR, and BW_OPMODE registers
3132 //
3133 switch(priv->ieee80211->mode)
3134 {
3135 case WIRELESS_MODE_B:
3136 regBwOpMode = BW_OPMODE_20MHZ;
3137 regRATR = RATE_ALL_CCK;
3138 regRRSR = RATE_ALL_CCK;
3139 break;
3140 case WIRELESS_MODE_A:
3141 regBwOpMode = BW_OPMODE_5G |BW_OPMODE_20MHZ;
3142 regRATR = RATE_ALL_OFDM_AG;
3143 regRRSR = RATE_ALL_OFDM_AG;
3144 break;
3145 case WIRELESS_MODE_G:
3146 regBwOpMode = BW_OPMODE_20MHZ;
3147 regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
3148 regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
3149 break;
3150 case WIRELESS_MODE_AUTO:
3151 case WIRELESS_MODE_N_24G:
3152 // It support CCK rate by default.
3153 // CCK rate will be filtered out only when associated AP does not support it.
3154 regBwOpMode = BW_OPMODE_20MHZ;
3155 regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
3156 regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
3157 break;
3158 case WIRELESS_MODE_N_5G:
3159 regBwOpMode = BW_OPMODE_5G;
3160 regRATR = RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
3161 regRRSR = RATE_ALL_OFDM_AG;
3162 break;
3163 }
3164
3165 write_nic_byte(dev, BW_OPMODE, regBwOpMode);
3166 {
3167 u32 ratr_value = 0;
3168 ratr_value = regRATR;
3169 if (priv->rf_type == RF_1T2R)
3170 {
3171 ratr_value &= ~(RATE_ALL_OFDM_2SS);
3172 }
3173 write_nic_dword(dev, RATR0, ratr_value);
3174 write_nic_byte(dev, UFWP, 1);
3175 }
3176 regTmp = read_nic_byte(dev, 0x313);
3177 regRRSR = ((regTmp) << 24) | (regRRSR & 0x00ffffff);
3178 write_nic_dword(dev, RRSR, regRRSR);
3179
3180 //
3181 // Set Retry Limit here
3182 //
3183 write_nic_word(dev, RETRY_LIMIT,
207b58fb 3184 priv->ShortRetryLimit << RETRY_LIMIT_SHORT_SHIFT |
ecdfa446
GKH
3185 priv->LongRetryLimit << RETRY_LIMIT_LONG_SHIFT);
3186 // Set Contention Window here
3187
3188 // Set Tx AGC
3189
3190 // Set Tx Antenna including Feedback control
3191
3192 // Set Auto Rate fallback control
3193
3194
3195}
3196
3197
5e1ad18a 3198static RT_STATUS rtl8192_adapter_start(struct net_device *dev)
ecdfa446
GKH
3199{
3200 struct r8192_priv *priv = ieee80211_priv(dev);
3201// struct ieee80211_device *ieee = priv->ieee80211;
3202 u32 ulRegRead;
3203 RT_STATUS rtStatus = RT_STATUS_SUCCESS;
ecdfa446
GKH
3204 //u8 eRFPath;
3205 u8 tmpvalue;
3206#ifdef RTL8192E
3207 u8 ICVersion,SwitchingRegulatorOutput;
3208#endif
3209 bool bfirmwareok = true;
3210#ifdef RTL8190P
3211 u8 ucRegRead;
3212#endif
3213 u32 tmpRegA, tmpRegC, TempCCk;
3214 int i =0;
ecdfa446
GKH
3215
3216 RT_TRACE(COMP_INIT, "====>%s()\n", __FUNCTION__);
3217 priv->being_init_adapter = true;
3218 rtl8192_pci_resetdescring(dev);
3219 // 2007/11/02 MH Before initalizing RF. We can not use FW to do RF-R/W.
3220 priv->Rf_Mode = RF_OP_By_SW_3wire;
3221#ifdef RTL8192E
3222 //dPLL on
3223 if(priv->ResetProgress == RESET_TYPE_NORESET)
3224 {
3225 write_nic_byte(dev, ANAPAR, 0x37);
3226 // Accordign to designer's explain, LBUS active will never > 10ms. We delay 10ms
3227 // Joseph increae the time to prevent firmware download fail
3228 mdelay(500);
3229 }
3230#endif
3231 //PlatformSleepUs(10000);
3232 // For any kind of InitializeAdapter process, we shall use system now!!
3233 priv->pFirmware->firmware_status = FW_STATUS_0_INIT;
3234
3235 // Set to eRfoff in order not to count receive count.
3236 if(priv->RegRfOff == TRUE)
3237 priv->ieee80211->eRFPowerState = eRfOff;
3238
3239 //
3240 //3 //Config CPUReset Register
3241 //3//
3242 //3 Firmware Reset Or Not
3243 ulRegRead = read_nic_dword(dev, CPU_GEN);
3244 if(priv->pFirmware->firmware_status == FW_STATUS_0_INIT)
3245 { //called from MPInitialized. do nothing
3246 ulRegRead |= CPU_GEN_SYSTEM_RESET;
3247 }else if(priv->pFirmware->firmware_status == FW_STATUS_5_READY)
3248 ulRegRead |= CPU_GEN_FIRMWARE_RESET; // Called from MPReset
3249 else
3250 RT_TRACE(COMP_ERR, "ERROR in %s(): undefined firmware state(%d)\n", __FUNCTION__, priv->pFirmware->firmware_status);
3251
3252#ifdef RTL8190P
3253 //2008.06.03, for WOL 90 hw bug
3254 ulRegRead &= (~(CPU_GEN_GPIO_UART));
3255#endif
3256
3257 write_nic_dword(dev, CPU_GEN, ulRegRead);
3258 //mdelay(100);
3259
3260#ifdef RTL8192E
3261
3262 //3//
3263 //3 //Fix the issue of E-cut high temperature issue
3264 //3//
3265 // TODO: E cut only
3266 ICVersion = read_nic_byte(dev, IC_VERRSION);
3267 if(ICVersion >= 0x4) //E-cut only
3268 {
3269 // HW SD suggest that we should not wirte this register too often, so driver
3270 // should readback this register. This register will be modified only when
3271 // power on reset
3272 SwitchingRegulatorOutput = read_nic_byte(dev, SWREGULATOR);
3273 if(SwitchingRegulatorOutput != 0xb8)
3274 {
3275 write_nic_byte(dev, SWREGULATOR, 0xa8);
3276 mdelay(1);
3277 write_nic_byte(dev, SWREGULATOR, 0xb8);
3278 }
3279 }
3280#endif
3281
3282
3283 //3//
3284 //3// Initialize BB before MAC
3285 //3//
ecdfa446
GKH
3286 RT_TRACE(COMP_INIT, "BB Config Start!\n");
3287 rtStatus = rtl8192_BBConfig(dev);
3288 if(rtStatus != RT_STATUS_SUCCESS)
3289 {
3290 RT_TRACE(COMP_ERR, "BB Config failed\n");
3291 return rtStatus;
3292 }
3293 RT_TRACE(COMP_INIT,"BB Config Finished!\n");
3294
ecdfa446
GKH
3295 //3//Set Loopback mode or Normal mode
3296 //3//
3297 //2006.12.13 by emily. Note!We should not merge these two CPU_GEN register writings
3298 // because setting of System_Reset bit reset MAC to default transmission mode.
3299 //Loopback mode or not
3300 priv->LoopbackMode = RTL819X_NO_LOOPBACK;
3301 //priv->LoopbackMode = RTL819X_MAC_LOOPBACK;
3302 if(priv->ResetProgress == RESET_TYPE_NORESET)
3303 {
3304 ulRegRead = read_nic_dword(dev, CPU_GEN);
3305 if(priv->LoopbackMode == RTL819X_NO_LOOPBACK)
3306 {
3307 ulRegRead = ((ulRegRead & CPU_GEN_NO_LOOPBACK_MSK) | CPU_GEN_NO_LOOPBACK_SET);
3308 }
3309 else if (priv->LoopbackMode == RTL819X_MAC_LOOPBACK )
3310 {
3311 ulRegRead |= CPU_CCK_LOOPBACK;
3312 }
3313 else
3314 {
3315 RT_TRACE(COMP_ERR,"Serious error: wrong loopback mode setting\n");
3316 }
3317
3318 //2008.06.03, for WOL
3319 //ulRegRead &= (~(CPU_GEN_GPIO_UART));
3320 write_nic_dword(dev, CPU_GEN, ulRegRead);
3321
3322 // 2006.11.29. After reset cpu, we sholud wait for a second, otherwise, it may fail to write registers. Emily
3323 udelay(500);
3324 }
3325 //3Set Hardware(Do nothing now)
3326 rtl8192_hwconfig(dev);
3327 //2=======================================================
3328 // Common Setting for all of the FPGA platform. (part 1)
3329 //2=======================================================
3330 // If there is changes, please make sure it applies to all of the FPGA version
3331 //3 Turn on Tx/Rx
3332 write_nic_byte(dev, CMDR, CR_RE|CR_TE);
3333
3334 //2Set Tx dma burst
3335#ifdef RTL8190P
207b58fb
MM
3336 write_nic_byte(dev, PCIF, ((MXDMA2_NoLimit<<MXDMA2_RX_SHIFT) |
3337 (MXDMA2_NoLimit<<MXDMA2_TX_SHIFT) |
3338 (1<<MULRW_SHIFT)));
ecdfa446
GKH
3339#else
3340 #ifdef RTL8192E
207b58fb 3341 write_nic_byte(dev, PCIF, ((MXDMA2_NoLimit<<MXDMA2_RX_SHIFT) |
ecdfa446
GKH
3342 (MXDMA2_NoLimit<<MXDMA2_TX_SHIFT) ));
3343 #endif
3344#endif
3345 //set IDR0 here
3346 write_nic_dword(dev, MAC0, ((u32*)dev->dev_addr)[0]);
3347 write_nic_word(dev, MAC4, ((u16*)(dev->dev_addr + 4))[0]);
3348 //set RCR
3349 write_nic_dword(dev, RCR, priv->ReceiveConfig);
3350
3351 //3 Initialize Number of Reserved Pages in Firmware Queue
3352 #ifdef TO_DO_LIST
3353 if(priv->bInHctTest)
3354 {
207b58fb
MM
3355 PlatformEFIOWrite4Byte(Adapter, RQPN1, NUM_OF_PAGE_IN_FW_QUEUE_BK_DTM << RSVD_FW_QUEUE_PAGE_BK_SHIFT |
3356 NUM_OF_PAGE_IN_FW_QUEUE_BE_DTM << RSVD_FW_QUEUE_PAGE_BE_SHIFT |
3357 NUM_OF_PAGE_IN_FW_QUEUE_VI_DTM << RSVD_FW_QUEUE_PAGE_VI_SHIFT |
ecdfa446
GKH
3358 NUM_OF_PAGE_IN_FW_QUEUE_VO_DTM <<RSVD_FW_QUEUE_PAGE_VO_SHIFT);
3359 PlatformEFIOWrite4Byte(Adapter, RQPN2, NUM_OF_PAGE_IN_FW_QUEUE_MGNT << RSVD_FW_QUEUE_PAGE_MGNT_SHIFT);
207b58fb
MM
3360 PlatformEFIOWrite4Byte(Adapter, RQPN3, APPLIED_RESERVED_QUEUE_IN_FW|
3361 NUM_OF_PAGE_IN_FW_QUEUE_BCN<<RSVD_FW_QUEUE_PAGE_BCN_SHIFT|
ecdfa446
GKH
3362 NUM_OF_PAGE_IN_FW_QUEUE_PUB_DTM<<RSVD_FW_QUEUE_PAGE_PUB_SHIFT);
3363 }
3364 else
3365 #endif
3366 {
207b58fb
MM
3367 write_nic_dword(dev, RQPN1, NUM_OF_PAGE_IN_FW_QUEUE_BK << RSVD_FW_QUEUE_PAGE_BK_SHIFT |
3368 NUM_OF_PAGE_IN_FW_QUEUE_BE << RSVD_FW_QUEUE_PAGE_BE_SHIFT |
3369 NUM_OF_PAGE_IN_FW_QUEUE_VI << RSVD_FW_QUEUE_PAGE_VI_SHIFT |
ecdfa446
GKH
3370 NUM_OF_PAGE_IN_FW_QUEUE_VO <<RSVD_FW_QUEUE_PAGE_VO_SHIFT);
3371 write_nic_dword(dev, RQPN2, NUM_OF_PAGE_IN_FW_QUEUE_MGNT << RSVD_FW_QUEUE_PAGE_MGNT_SHIFT);
207b58fb
MM
3372 write_nic_dword(dev, RQPN3, APPLIED_RESERVED_QUEUE_IN_FW|
3373 NUM_OF_PAGE_IN_FW_QUEUE_BCN<<RSVD_FW_QUEUE_PAGE_BCN_SHIFT|
ecdfa446
GKH
3374 NUM_OF_PAGE_IN_FW_QUEUE_PUB<<RSVD_FW_QUEUE_PAGE_PUB_SHIFT);
3375 }
3376
3377 rtl8192_tx_enable(dev);
3378 rtl8192_rx_enable(dev);
3379 //3Set Response Rate Setting Register
3380 // CCK rate is supported by default.
3381 // CCK rate will be filtered out only when associated AP does not support it.
3382 ulRegRead = (0xFFF00000 & read_nic_dword(dev, RRSR)) | RATE_ALL_OFDM_AG | RATE_ALL_CCK;
3383 write_nic_dword(dev, RRSR, ulRegRead);
3384 write_nic_dword(dev, RATR0+4*7, (RATE_ALL_OFDM_AG | RATE_ALL_CCK));
3385
3386 //2Set AckTimeout
3387 // TODO: (it value is only for FPGA version). need to be changed!!2006.12.18, by Emily
3388 write_nic_byte(dev, ACK_TIMEOUT, 0x30);
3389
3390 //rtl8192_actset_wirelessmode(dev,priv->RegWirelessMode);
3391 if(priv->ResetProgress == RESET_TYPE_NORESET)
3392 rtl8192_SetWirelessMode(dev, priv->ieee80211->mode);
3393 //-----------------------------------------------------------------------------
3394 // Set up security related. 070106, by rcnjko:
3395 // 1. Clear all H/W keys.
3396 // 2. Enable H/W encryption/decryption.
3397 //-----------------------------------------------------------------------------
3398 CamResetAllEntry(dev);
3399 {
3400 u8 SECR_value = 0x0;
3401 SECR_value |= SCR_TxEncEnable;
3402 SECR_value |= SCR_RxDecEnable;
3403 SECR_value |= SCR_NoSKMC;
3404 write_nic_byte(dev, SECR, SECR_value);
3405 }
3406 //3Beacon related
3407 write_nic_word(dev, ATIMWND, 2);
3408 write_nic_word(dev, BCN_INTERVAL, 100);
5e1ad18a 3409 for (i=0; i<QOS_QUEUE_NUM; i++)
ecdfa446 3410 write_nic_dword(dev, WDCAPARA_ADD[i], 0x005e4332);
ecdfa446
GKH
3411 //
3412 // Switching regulator controller: This is set temporarily.
3413 // It's not sure if this can be removed in the future.
3414 // PJ advised to leave it by default.
3415 //
3416 write_nic_byte(dev, 0xbe, 0xc0);
3417
3418 //2=======================================================
3419 // Set PHY related configuration defined in MAC register bank
3420 //2=======================================================
3421 rtl8192_phy_configmac(dev);
3422
3423 if (priv->card_8192_version > (u8) VERSION_8190_BD) {
3424 rtl8192_phy_getTxPower(dev);
3425 rtl8192_phy_setTxPower(dev, priv->chan);
3426 }
3427
3428 //if D or C cut
3429 tmpvalue = read_nic_byte(dev, IC_VERRSION);
3430 priv->IC_Cut = tmpvalue;
3431 RT_TRACE(COMP_INIT, "priv->IC_Cut = 0x%x\n", priv->IC_Cut);
3432 if(priv->IC_Cut >= IC_VersionCut_D)
3433 {
3434 //pHalData->bDcut = TRUE;
3435 if(priv->IC_Cut == IC_VersionCut_D)
3436 RT_TRACE(COMP_INIT, "D-cut\n");
3437 if(priv->IC_Cut == IC_VersionCut_E)
3438 {
3439 RT_TRACE(COMP_INIT, "E-cut\n");
3440 // HW SD suggest that we should not wirte this register too often, so driver
3441 // should readback this register. This register will be modified only when
3442 // power on reset
3443 }
3444 }
3445 else
3446 {
3447 //pHalData->bDcut = FALSE;
3448 RT_TRACE(COMP_INIT, "Before C-cut\n");
3449 }
3450
3451#if 1
3452 //Firmware download
3453 RT_TRACE(COMP_INIT, "Load Firmware!\n");
3454 bfirmwareok = init_firmware(dev);
3455 if(bfirmwareok != true) {
3456 rtStatus = RT_STATUS_FAILURE;
3457 return rtStatus;
3458 }
3459 RT_TRACE(COMP_INIT, "Load Firmware finished!\n");
3460#endif
3461 //RF config
3462 if(priv->ResetProgress == RESET_TYPE_NORESET)
3463 {
3464 RT_TRACE(COMP_INIT, "RF Config Started!\n");
3465 rtStatus = rtl8192_phy_RFConfig(dev);
3466 if(rtStatus != RT_STATUS_SUCCESS)
3467 {
3468 RT_TRACE(COMP_ERR, "RF Config failed\n");
3469 return rtStatus;
3470 }
3471 RT_TRACE(COMP_INIT, "RF Config Finished!\n");
3472 }
3473 rtl8192_phy_updateInitGain(dev);
3474
3475 /*---- Set CCK and OFDM Block "ON"----*/
3476 rtl8192_setBBreg(dev, rFPGA0_RFMOD, bCCKEn, 0x1);
3477 rtl8192_setBBreg(dev, rFPGA0_RFMOD, bOFDMEn, 0x1);
3478
3479#ifdef RTL8192E
3480 //Enable Led
3481 write_nic_byte(dev, 0x87, 0x0);
3482#endif
3483#ifdef RTL8190P
3484 //2008.06.03, for WOL
3485 ucRegRead = read_nic_byte(dev, GPE);
3486 ucRegRead |= BIT0;
3487 write_nic_byte(dev, GPE, ucRegRead);
3488
3489 ucRegRead = read_nic_byte(dev, GPO);
3490 ucRegRead &= ~BIT0;
3491 write_nic_byte(dev, GPO, ucRegRead);
3492#endif
3493
3494 //2=======================================================
3495 // RF Power Save
3496 //2=======================================================
3497#ifdef ENABLE_IPS
3498
3499{
3500 if(priv->RegRfOff == TRUE)
3501 { // User disable RF via registry.
3502 RT_TRACE((COMP_INIT|COMP_RF|COMP_POWER), "%s(): Turn off RF for RegRfOff ----------\n",__FUNCTION__);
3503 MgntActSet_RF_State(dev, eRfOff, RF_CHANGE_BY_SW);
3504#if 0//cosa, ask SD3 willis and he doesn't know what is this for
3505 // Those action will be discard in MgntActSet_RF_State because off the same state
3506 for(eRFPath = 0; eRFPath <pHalData->NumTotalRFPath; eRFPath++)
3507 PHY_SetRFReg(Adapter, (RF90_RADIO_PATH_E)eRFPath, 0x4, 0xC00, 0x0);
3508#endif
3509 }
3510 else if(priv->ieee80211->RfOffReason > RF_CHANGE_BY_PS)
3511 { // H/W or S/W RF OFF before sleep.
3512 RT_TRACE((COMP_INIT|COMP_RF|COMP_POWER), "%s(): Turn off RF for RfOffReason(%d) ----------\n", __FUNCTION__,priv->ieee80211->RfOffReason);
3513 MgntActSet_RF_State(dev, eRfOff, priv->ieee80211->RfOffReason);
3514 }
3515 else if(priv->ieee80211->RfOffReason >= RF_CHANGE_BY_IPS)
3516 { // H/W or S/W RF OFF before sleep.
3517 RT_TRACE((COMP_INIT|COMP_RF|COMP_POWER), "%s(): Turn off RF for RfOffReason(%d) ----------\n", __FUNCTION__,priv->ieee80211->RfOffReason);
3518 MgntActSet_RF_State(dev, eRfOff, priv->ieee80211->RfOffReason);
3519 }
3520 else
3521 {
3522 RT_TRACE((COMP_INIT|COMP_RF|COMP_POWER), "%s(): RF-ON \n",__FUNCTION__);
3523 priv->ieee80211->eRFPowerState = eRfOn;
3524 priv->ieee80211->RfOffReason = 0;
3525 //DrvIFIndicateCurrentPhyStatus(Adapter);
3526 // LED control
3527 //Adapter->HalFunc.LedControlHandler(Adapter, LED_CTL_POWER_ON);
3528
3529 //
3530 // If inactive power mode is enabled, disable rf while in disconnected state.
3531 // But we should still tell upper layer we are in rf on state.
3532 // 2007.07.16, by shien chang.
3533 //
3534 //if(!Adapter->bInHctTest)
3535 //IPSEnter(Adapter);
3536
3537 }
3538}
3539#endif
3540 if(1){
3541#ifdef RTL8192E
3542 // We can force firmware to do RF-R/W
3543 if(priv->ieee80211->FwRWRF)
3544 priv->Rf_Mode = RF_OP_By_FW;
3545 else
3546 priv->Rf_Mode = RF_OP_By_SW_3wire;
3547#else
3548 priv->Rf_Mode = RF_OP_By_SW_3wire;
3549#endif
3550 }
3551#ifdef RTL8190P
3552 if(priv->ResetProgress == RESET_TYPE_NORESET)
3553 {
3554 dm_initialize_txpower_tracking(dev);
3555
3556 tmpRegA= rtl8192_QueryBBReg(dev,rOFDM0_XATxIQImbalance,bMaskDWord);
3557 tmpRegC= rtl8192_QueryBBReg(dev,rOFDM0_XCTxIQImbalance,bMaskDWord);
3558
3559 if(priv->rf_type == RF_2T4R){
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 for(i = 0; i<TxBBGainTableLength; i++)
3572 {
3573 if(tmpRegC == priv->txbbgain_table[i].txbbgain_value)
3574 {
3575 priv->rfc_txpowertrackingindex= (u8)i;
3576 priv->rfc_txpowertrackingindex_real= (u8)i;
3577 priv->rfc_txpowertracking_default = priv->rfc_txpowertrackingindex;
3578 break;
3579 }
3580 }
3581 TempCCk = rtl8192_QueryBBReg(dev, rCCK0_TxFilter1, bMaskByte2);
3582
3583 for(i=0 ; i<CCKTxBBGainTableLength ; i++)
3584 {
3585 if(TempCCk == priv->cck_txbbgain_table[i].ccktxbb_valuearray[0])
3586 {
3587 priv->CCKPresentAttentuation_20Mdefault =(u8) i;
3588 break;
3589 }
3590 }
3591 priv->CCKPresentAttentuation_40Mdefault = 0;
3592 priv->CCKPresentAttentuation_difference = 0;
3593 priv->CCKPresentAttentuation = priv->CCKPresentAttentuation_20Mdefault;
3594 RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex_initial = %d\n", priv->rfa_txpowertrackingindex);
3595 RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex_real__initial = %d\n", priv->rfa_txpowertrackingindex_real);
3596 RT_TRACE(COMP_POWER_TRACKING, "priv->rfc_txpowertrackingindex_initial = %d\n", priv->rfc_txpowertrackingindex);
3597 RT_TRACE(COMP_POWER_TRACKING, "priv->rfc_txpowertrackingindex_real_initial = %d\n", priv->rfc_txpowertrackingindex_real);
3598 RT_TRACE(COMP_POWER_TRACKING, "priv->CCKPresentAttentuation_difference_initial = %d\n", priv->CCKPresentAttentuation_difference);
3599 RT_TRACE(COMP_POWER_TRACKING, "priv->CCKPresentAttentuation_initial = %d\n", priv->CCKPresentAttentuation);
3600 }
3601#else
3602 #ifdef RTL8192E
3603 if(priv->ResetProgress == RESET_TYPE_NORESET)
3604 {
3605 dm_initialize_txpower_tracking(dev);
3606
3607 if(priv->IC_Cut >= IC_VersionCut_D)
3608 {
3609 tmpRegA= rtl8192_QueryBBReg(dev,rOFDM0_XATxIQImbalance,bMaskDWord);
3610 tmpRegC= rtl8192_QueryBBReg(dev,rOFDM0_XCTxIQImbalance,bMaskDWord);
3611 for(i = 0; i<TxBBGainTableLength; i++)
3612 {
3613 if(tmpRegA == priv->txbbgain_table[i].txbbgain_value)
3614 {
3615 priv->rfa_txpowertrackingindex= (u8)i;
3616 priv->rfa_txpowertrackingindex_real= (u8)i;
3617 priv->rfa_txpowertracking_default = priv->rfa_txpowertrackingindex;
3618 break;
3619 }
3620 }
3621
3622 TempCCk = rtl8192_QueryBBReg(dev, rCCK0_TxFilter1, bMaskByte2);
3623
3624 for(i=0 ; i<CCKTxBBGainTableLength ; i++)
3625 {
3626 if(TempCCk == priv->cck_txbbgain_table[i].ccktxbb_valuearray[0])
3627 {
3628 priv->CCKPresentAttentuation_20Mdefault =(u8) i;
3629 break;
3630 }
3631 }
3632 priv->CCKPresentAttentuation_40Mdefault = 0;
3633 priv->CCKPresentAttentuation_difference = 0;
3634 priv->CCKPresentAttentuation = priv->CCKPresentAttentuation_20Mdefault;
3635 RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex_initial = %d\n", priv->rfa_txpowertrackingindex);
3636 RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex_real__initial = %d\n", priv->rfa_txpowertrackingindex_real);
3637 RT_TRACE(COMP_POWER_TRACKING, "priv->CCKPresentAttentuation_difference_initial = %d\n", priv->CCKPresentAttentuation_difference);
3638 RT_TRACE(COMP_POWER_TRACKING, "priv->CCKPresentAttentuation_initial = %d\n", priv->CCKPresentAttentuation);
3639 priv->btxpower_tracking = FALSE;//TEMPLY DISABLE
3640 }
3641 }
3642 #endif
3643#endif
3644 rtl8192_irq_enable(dev);
3645 priv->being_init_adapter = false;
3646 return rtStatus;
3647
3648}
3649
559fba5e 3650static void rtl8192_prepare_beacon(struct r8192_priv *priv)
ecdfa446
GKH
3651{
3652 struct sk_buff *skb;
3653 //unsigned long flags;
3654 cb_desc *tcb_desc;
3655
3656 skb = ieee80211_get_beacon(priv->ieee80211);
3657 tcb_desc = (cb_desc *)(skb->cb + 8);
ecdfa446
GKH
3658 //spin_lock_irqsave(&priv->tx_lock,flags);
3659 /* prepare misc info for the beacon xmit */
3660 tcb_desc->queue_index = BEACON_QUEUE;
bbc9a991 3661 /* IBSS does not support HT yet, use 1M defaultly */
ecdfa446
GKH
3662 tcb_desc->data_rate = 2;
3663 tcb_desc->RATRIndex = 7;
3664 tcb_desc->bTxDisableRateFallBack = 1;
3665 tcb_desc->bTxUseDriverAssingedRate = 1;
3666
3667 skb_push(skb, priv->ieee80211->tx_headroom);
3668 if(skb){
3669 rtl8192_tx(priv->ieee80211->dev,skb);
3670 }
3671 //spin_unlock_irqrestore (&priv->tx_lock, flags);
3672}
3673
ecdfa446 3674
214985a6
MM
3675/*
3676 * configure registers for beacon tx and enables it via
ecdfa446
GKH
3677 * rtl8192_beacon_tx_enable(). rtl8192_beacon_tx_disable() might
3678 * be used to stop beacon transmission
3679 */
559fba5e 3680static void rtl8192_start_beacon(struct net_device *dev)
ecdfa446
GKH
3681{
3682 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
3683 struct ieee80211_network *net = &priv->ieee80211->current_network;
3684 u16 BcnTimeCfg = 0;
3685 u16 BcnCW = 6;
3686 u16 BcnIFS = 0xf;
3687
3688 DMESG("Enabling beacon TX");
3689 //rtl8192_prepare_beacon(dev);
3690 rtl8192_irq_disable(dev);
3691 //rtl8192_beacon_tx_enable(dev);
3692
3693 /* ATIM window */
3694 write_nic_word(dev, ATIMWND, 2);
3695
3696 /* Beacon interval (in unit of TU) */
3697 write_nic_word(dev, BCN_INTERVAL, net->beacon_interval);
3698
3699 /*
3700 * DrvErlyInt (in unit of TU).
3701 * (Time to send interrupt to notify driver to c
3702 * hange beacon content)
3703 * */
3704 write_nic_word(dev, BCN_DRV_EARLY_INT, 10);
3705
3706 /*
3707 * BcnDMATIM(in unit of us).
3708 * Indicates the time before TBTT to perform beacon queue DMA
3709 * */
3710 write_nic_word(dev, BCN_DMATIME, 256);
3711
3712 /*
3713 * Force beacon frame transmission even after receiving
3714 * beacon frame from other ad hoc STA
3715 * */
3716 write_nic_byte(dev, BCN_ERR_THRESH, 100);
3717
3718 /* Set CW and IFS */
3719 BcnTimeCfg |= BcnCW<<BCN_TCFG_CW_SHIFT;
3720 BcnTimeCfg |= BcnIFS<<BCN_TCFG_IFS;
3721 write_nic_word(dev, BCN_TCFG, BcnTimeCfg);
3722
3723
3724 /* enable the interrupt for ad-hoc process */
3725 rtl8192_irq_enable(dev);
3726}
ecdfa446 3727
5e1ad18a 3728static bool HalTxCheckStuck8190Pci(struct net_device *dev)
ecdfa446
GKH
3729{
3730 u16 RegTxCounter = read_nic_word(dev, 0x128);
3731 struct r8192_priv *priv = ieee80211_priv(dev);
3732 bool bStuck = FALSE;
3733 RT_TRACE(COMP_RESET,"%s():RegTxCounter is %d,TxCounter is %d\n",__FUNCTION__,RegTxCounter,priv->TxCounter);
3734 if(priv->TxCounter==RegTxCounter)
3735 bStuck = TRUE;
3736
3737 priv->TxCounter = RegTxCounter;
3738
3739 return bStuck;
3740}
3741
3742/*
214985a6
MM
3743 * Assumption: RT_TX_SPINLOCK is acquired.
3744 */
5e1ad18a 3745static RESET_TYPE
ecdfa446
GKH
3746TxCheckStuck(struct net_device *dev)
3747{
3748 struct r8192_priv *priv = ieee80211_priv(dev);
3749 u8 QueueID;
3750 ptx_ring head=NULL,tail=NULL,txring = NULL;
3751 u8 ResetThreshold = NIC_SEND_HANG_THRESHOLD_POWERSAVE;
3752 bool bCheckFwTxCnt = false;
ecdfa446
GKH
3753
3754 //
3755 // Decide Stuch threshold according to current power save mode
3756 //
ecdfa446
GKH
3757 switch (priv->ieee80211->dot11PowerSaveMode)
3758 {
3759 // The threshold value may required to be adjusted .
3760 case eActive: // Active/Continuous access.
3761 ResetThreshold = NIC_SEND_HANG_THRESHOLD_NORMAL;
3762 break;
3763 case eMaxPs: // Max power save mode.
3764 ResetThreshold = NIC_SEND_HANG_THRESHOLD_POWERSAVE;
3765 break;
3766 case eFastPs: // Fast power save mode.
3767 ResetThreshold = NIC_SEND_HANG_THRESHOLD_POWERSAVE;
3768 break;
3769 }
3770
3771 //
3772 // Check whether specific tcb has been queued for a specific time
3773 //
3774 for(QueueID = 0; QueueID < MAX_TX_QUEUE; QueueID++)
3775 {
3776
3777
3778 if(QueueID == TXCMD_QUEUE)
3779 continue;
3780
3781 switch(QueueID) {
3782 case MGNT_QUEUE:
3783 tail=priv->txmapringtail;
3784 head=priv->txmapringhead;
3785 break;
3786
3787 case BK_QUEUE:
3788 tail=priv->txbkpringtail;
3789 head=priv->txbkpringhead;
3790 break;
3791
3792 case BE_QUEUE:
3793 tail=priv->txbepringtail;
3794 head=priv->txbepringhead;
3795 break;
3796
3797 case VI_QUEUE:
3798 tail=priv->txvipringtail;
3799 head=priv->txvipringhead;
3800 break;
3801
3802 case VO_QUEUE:
3803 tail=priv->txvopringtail;
3804 head=priv->txvopringhead;
3805 break;
3806
3807 default:
3808 tail=head=NULL;
3809 break;
3810 }
3811
3812 if(tail == head)
3813 continue;
3814 else
3815 {
3816 txring = head;
3817 if(txring == NULL)
3818 {
3819 RT_TRACE(COMP_ERR,"%s():txring is NULL , BUG!\n",__FUNCTION__);
3820 continue;
3821 }
3822 txring->nStuckCount++;
ecdfa446
GKH
3823 bCheckFwTxCnt = TRUE;
3824 }
3825 }
3826#if 1
3827 if(bCheckFwTxCnt)
3828 {
3829 if(HalTxCheckStuck8190Pci(dev))
3830 {
3831 RT_TRACE(COMP_RESET, "TxCheckStuck(): Fw indicates no Tx condition! \n");
3832 return RESET_TYPE_SILENT;
3833 }
3834 }
3835#endif
3836 return RESET_TYPE_NORESET;
3837}
3838
3839
5e1ad18a 3840static bool HalRxCheckStuck8190Pci(struct net_device *dev)
ecdfa446
GKH
3841{
3842 struct r8192_priv *priv = ieee80211_priv(dev);
3843 u16 RegRxCounter = read_nic_word(dev, 0x130);
3844 bool bStuck = FALSE;
3845 static u8 rx_chk_cnt = 0;
3846 RT_TRACE(COMP_RESET,"%s(): RegRxCounter is %d,RxCounter is %d\n",__FUNCTION__,RegRxCounter,priv->RxCounter);
3847 // If rssi is small, we should check rx for long time because of bad rx.
3848 // or maybe it will continuous silent reset every 2 seconds.
3849 rx_chk_cnt++;
3850 if(priv->undecorated_smoothed_pwdb >= (RateAdaptiveTH_High+5))
3851 {
3852 rx_chk_cnt = 0; //high rssi, check rx stuck right now.
3853 }
3854 else if(priv->undecorated_smoothed_pwdb < (RateAdaptiveTH_High+5) &&
3855 ((priv->CurrentChannelBW!=HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb>=RateAdaptiveTH_Low_40M) ||
3856 (priv->CurrentChannelBW==HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb>=RateAdaptiveTH_Low_20M)) )
3857
3858 {
3859 if(rx_chk_cnt < 2)
3860 {
3861 return bStuck;
3862 }
3863 else
3864 {
3865 rx_chk_cnt = 0;
3866 }
3867 }
3868 else if(((priv->CurrentChannelBW!=HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb<RateAdaptiveTH_Low_40M) ||
3869 (priv->CurrentChannelBW==HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb<RateAdaptiveTH_Low_20M)) &&
3870 priv->undecorated_smoothed_pwdb >= VeryLowRSSI)
3871 {
3872 if(rx_chk_cnt < 4)
3873 {
3874 //DbgPrint("RSSI < %d && RSSI >= %d, no check this time \n", RateAdaptiveTH_Low, VeryLowRSSI);
3875 return bStuck;
3876 }
3877 else
3878 {
3879 rx_chk_cnt = 0;
3880 //DbgPrint("RSSI < %d && RSSI >= %d, check this time \n", RateAdaptiveTH_Low, VeryLowRSSI);
3881 }
3882 }
3883 else
3884 {
3885 if(rx_chk_cnt < 8)
3886 {
3887 //DbgPrint("RSSI <= %d, no check this time \n", VeryLowRSSI);
3888 return bStuck;
3889 }
3890 else
3891 {
3892 rx_chk_cnt = 0;
3893 //DbgPrint("RSSI <= %d, check this time \n", VeryLowRSSI);
3894 }
3895 }
ecdfa446
GKH
3896 if(priv->RxCounter==RegRxCounter)
3897 bStuck = TRUE;
3898
3899 priv->RxCounter = RegRxCounter;
3900
3901 return bStuck;
3902}
3903
5e1ad18a 3904static RESET_TYPE RxCheckStuck(struct net_device *dev)
ecdfa446
GKH
3905{
3906
3907 if(HalRxCheckStuck8190Pci(dev))
3908 {
3909 RT_TRACE(COMP_RESET, "RxStuck Condition\n");
3910 return RESET_TYPE_SILENT;
3911 }
3912
3913 return RESET_TYPE_NORESET;
3914}
3915
5e1ad18a 3916static RESET_TYPE
ecdfa446
GKH
3917rtl819x_ifcheck_resetornot(struct net_device *dev)
3918{
3919 struct r8192_priv *priv = ieee80211_priv(dev);
3920 RESET_TYPE TxResetType = RESET_TYPE_NORESET;
3921 RESET_TYPE RxResetType = RESET_TYPE_NORESET;
3922 RT_RF_POWER_STATE rfState;
3923
3924 rfState = priv->ieee80211->eRFPowerState;
3925
3926 TxResetType = TxCheckStuck(dev);
3927#if 1
3928 if( rfState != eRfOff &&
3929 /*ADAPTER_TEST_STATUS_FLAG(Adapter, ADAPTER_STATUS_FW_DOWNLOAD_FAILURE)) &&*/
3930 (priv->ieee80211->iw_mode != IW_MODE_ADHOC))
3931 {
3932 // If driver is in the status of firmware download failure , driver skips RF initialization and RF is
3933 // in turned off state. Driver should check whether Rx stuck and do silent reset. And
3934 // if driver is in firmware download failure status, driver should initialize RF in the following
3935 // silent reset procedure Emily, 2008.01.21
3936
3937 // Driver should not check RX stuck in IBSS mode because it is required to
3938 // set Check BSSID in order to send beacon, however, if check BSSID is
3939 // set, STA cannot hear any packet a all. Emily, 2008.04.12
3940 RxResetType = RxCheckStuck(dev);
3941 }
3942#endif
3943
3944 RT_TRACE(COMP_RESET,"%s(): TxResetType is %d, RxResetType is %d\n",__FUNCTION__,TxResetType,RxResetType);
3945 if(TxResetType==RESET_TYPE_NORMAL || RxResetType==RESET_TYPE_NORMAL)
3946 return RESET_TYPE_NORMAL;
3947 else if(TxResetType==RESET_TYPE_SILENT || RxResetType==RESET_TYPE_SILENT)
3948 return RESET_TYPE_SILENT;
3949 else
3950 return RESET_TYPE_NORESET;
3951
3952}
3953
3954
5e1ad18a 3955static void CamRestoreAllEntry(struct net_device *dev)
ecdfa446
GKH
3956{
3957 u8 EntryId = 0;
3958 struct r8192_priv *priv = ieee80211_priv(dev);
881a975b 3959 const u8* MacAddr = priv->ieee80211->current_network.bssid;
ecdfa446 3960
881a975b 3961 static const u8 CAM_CONST_ADDR[4][6] = {
ecdfa446
GKH
3962 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
3963 {0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
3964 {0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
3965 {0x00, 0x00, 0x00, 0x00, 0x00, 0x03}};
881a975b 3966 static const u8 CAM_CONST_BROAD[] =
ecdfa446
GKH
3967 {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
3968
3969 RT_TRACE(COMP_SEC, "CamRestoreAllEntry: \n");
3970
3971
3972 if ((priv->ieee80211->pairwise_key_type == KEY_TYPE_WEP40)||
3973 (priv->ieee80211->pairwise_key_type == KEY_TYPE_WEP104))
3974 {
3975
3976 for(EntryId=0; EntryId<4; EntryId++)
3977 {
3978 {
3979 MacAddr = CAM_CONST_ADDR[EntryId];
3980 setKey(dev,
3981 EntryId ,
3982 EntryId,
3983 priv->ieee80211->pairwise_key_type,
3984 MacAddr,
3985 0,
3986 NULL);
3987 }
3988 }
3989
3990 }
3991 else if(priv->ieee80211->pairwise_key_type == KEY_TYPE_TKIP)
3992 {
3993
3994 {
3995 if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
3996 setKey(dev,
3997 4,
3998 0,
3999 priv->ieee80211->pairwise_key_type,
4000 (u8*)dev->dev_addr,
4001 0,
4002 NULL);
4003 else
4004 setKey(dev,
4005 4,
4006 0,
4007 priv->ieee80211->pairwise_key_type,
4008 MacAddr,
4009 0,
4010 NULL);
4011 }
4012 }
4013 else if(priv->ieee80211->pairwise_key_type == KEY_TYPE_CCMP)
4014 {
4015
4016 {
4017 if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
4018 setKey(dev,
4019 4,
4020 0,
4021 priv->ieee80211->pairwise_key_type,
4022 (u8*)dev->dev_addr,
4023 0,
4024 NULL);
4025 else
4026 setKey(dev,
4027 4,
4028 0,
4029 priv->ieee80211->pairwise_key_type,
4030 MacAddr,
4031 0,
4032 NULL);
4033 }
4034 }
4035
4036
4037
4038 if(priv->ieee80211->group_key_type == KEY_TYPE_TKIP)
4039 {
4040 MacAddr = CAM_CONST_BROAD;
4041 for(EntryId=1 ; EntryId<4 ; EntryId++)
4042 {
4043 {
4044 setKey(dev,
4045 EntryId,
4046 EntryId,
4047 priv->ieee80211->group_key_type,
4048 MacAddr,
4049 0,
4050 NULL);
4051 }
4052 }
4053 if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
4054 setKey(dev,
4055 0,
4056 0,
4057 priv->ieee80211->group_key_type,
4058 CAM_CONST_ADDR[0],
4059 0,
4060 NULL);
4061 }
4062 else if(priv->ieee80211->group_key_type == KEY_TYPE_CCMP)
4063 {
4064 MacAddr = CAM_CONST_BROAD;
4065 for(EntryId=1; EntryId<4 ; EntryId++)
4066 {
4067 {
4068 setKey(dev,
4069 EntryId ,
4070 EntryId,
4071 priv->ieee80211->group_key_type,
4072 MacAddr,
4073 0,
4074 NULL);
4075 }
4076 }
4077
4078 if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
4079 setKey(dev,
4080 0 ,
4081 0,
4082 priv->ieee80211->group_key_type,
4083 CAM_CONST_ADDR[0],
4084 0,
4085 NULL);
4086 }
4087}
4088
ecdfa446
GKH
4089/*
4090 * This function is used to fix Tx/Rx stop bug temporarily.
4091 * This function will do "system reset" to NIC when Tx or Rx is stuck.
4092 * The method checking Tx/Rx stuck of this function is supported by FW,
4093 * which reports Tx and Rx counter to register 0x128 and 0x130.
214985a6 4094 */
5e1ad18a 4095static void rtl819x_ifsilentreset(struct net_device *dev)
ecdfa446
GKH
4096{
4097 struct r8192_priv *priv = ieee80211_priv(dev);
4098 u8 reset_times = 0;
4099 int reset_status = 0;
4100 struct ieee80211_device *ieee = priv->ieee80211;
4101
4102
65a43784 4103 return;
4104
ecdfa446
GKH
4105 // 2007.07.20. If we need to check CCK stop, please uncomment this line.
4106 //bStuck = Adapter->HalFunc.CheckHWStopHandler(Adapter);
4107
4108 if(priv->ResetProgress==RESET_TYPE_NORESET)
4109 {
4110RESET_START:
65a43784 4111#ifdef ENABLE_LPS
4112 //LZM for PS-Poll AID issue. 090429
4113 if(priv->ieee80211->state == IEEE80211_LINKED)
4114 LeisurePSLeave(dev);
4115#endif
ecdfa446
GKH
4116
4117 RT_TRACE(COMP_RESET,"=========>Reset progress!! \n");
4118
4119 // Set the variable for reset.
4120 priv->ResetProgress = RESET_TYPE_SILENT;
4121// rtl8192_close(dev);
4122#if 1
4123 down(&priv->wx_sem);
4124 if(priv->up == 0)
4125 {
4126 RT_TRACE(COMP_ERR,"%s():the driver is not up! return\n",__FUNCTION__);
4127 up(&priv->wx_sem);
4128 return ;
4129 }
4130 priv->up = 0;
4131 RT_TRACE(COMP_RESET,"%s():======>start to down the driver\n",__FUNCTION__);
4132 if(!netif_queue_stopped(dev))
4133 netif_stop_queue(dev);
4134
4135 dm_backup_dynamic_mechanism_state(dev);
4136
4137 rtl8192_irq_disable(dev);
4138 rtl8192_cancel_deferred_work(priv);
4139 deinit_hal_dm(dev);
4140 del_timer_sync(&priv->watch_dog_timer);
4141 ieee->sync_scan_hurryup = 1;
4142 if(ieee->state == IEEE80211_LINKED)
4143 {
4144 down(&ieee->wx_sem);
4145 printk("ieee->state is IEEE80211_LINKED\n");
4146 ieee80211_stop_send_beacons(priv->ieee80211);
4147 del_timer_sync(&ieee->associate_timer);
ecdfa446 4148 cancel_delayed_work(&ieee->associate_retry_wq);
ecdfa446 4149 ieee80211_stop_scan(ieee);
ecdfa446
GKH
4150 up(&ieee->wx_sem);
4151 }
4152 else{
4153 printk("ieee->state is NOT LINKED\n");
65a43784 4154 ieee80211_softmac_stop_protocol(priv->ieee80211,true);
ecdfa446 4155 }
65a43784 4156 rtl8192_halt_adapter(dev, true);
ecdfa446
GKH
4157 up(&priv->wx_sem);
4158 RT_TRACE(COMP_RESET,"%s():<==========down process is finished\n",__FUNCTION__);
4159 RT_TRACE(COMP_RESET,"%s():===========>start to up the driver\n",__FUNCTION__);
4160 reset_status = _rtl8192_up(dev);
4161
4162 RT_TRACE(COMP_RESET,"%s():<===========up process is finished\n",__FUNCTION__);
4163 if(reset_status == -1)
4164 {
4165 if(reset_times < 3)
4166 {
4167 reset_times++;
4168 goto RESET_START;
4169 }
4170 else
4171 {
4172 RT_TRACE(COMP_ERR," ERR!!! %s(): Reset Failed!!\n",__FUNCTION__);
4173 }
4174 }
4175#endif
4176 ieee->is_silent_reset = 1;
4177#if 1
4178 EnableHWSecurityConfig8192(dev);
4179#if 1
4180 if(ieee->state == IEEE80211_LINKED && ieee->iw_mode == IW_MODE_INFRA)
4181 {
4182 ieee->set_chan(ieee->dev, ieee->current_network.channel);
4183
4184#if 1
ecdfa446 4185 queue_work(ieee->wq, &ieee->associate_complete_wq);
ecdfa446
GKH
4186#endif
4187
4188 }
4189 else if(ieee->state == IEEE80211_LINKED && ieee->iw_mode == IW_MODE_ADHOC)
4190 {
4191 ieee->set_chan(ieee->dev, ieee->current_network.channel);
4192 ieee->link_change(ieee->dev);
4193
4194 // notify_wx_assoc_event(ieee);
4195
4196 ieee80211_start_send_beacons(ieee);
4197
4198 if (ieee->data_hard_resume)
4199 ieee->data_hard_resume(ieee->dev);
4200 netif_carrier_on(ieee->dev);
4201 }
4202#endif
4203
4204 CamRestoreAllEntry(dev);
4205
4206 // Restore the previous setting for all dynamic mechanism
4207 dm_restore_dynamic_mechanism_state(dev);
4208
4209 priv->ResetProgress = RESET_TYPE_NORESET;
4210 priv->reset_count++;
4211
4212 priv->bForcedSilentReset =false;
4213 priv->bResetInProgress = false;
4214
4215 // For test --> force write UFWP.
4216 write_nic_byte(dev, UFWP, 1);
4217 RT_TRACE(COMP_RESET, "Reset finished!! ====>[%d]\n", priv->reset_count);
4218#endif
4219 }
4220}
4221
4222#ifdef ENABLE_IPS
4223void InactivePsWorkItemCallback(struct net_device *dev)
4224{
4225 struct r8192_priv *priv = ieee80211_priv(dev);
4226 PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->ieee80211->PowerSaveControl));
ecdfa446
GKH
4227
4228 RT_TRACE(COMP_POWER, "InactivePsWorkItemCallback() ---------> \n");
4229 //
4230 // This flag "bSwRfProcessing", indicates the status of IPS procedure, should be set if the IPS workitem
4231 // is really scheduled.
4232 // The old code, sets this flag before scheduling the IPS workitem and however, at the same time the
4233 // previous IPS workitem did not end yet, fails to schedule the current workitem. Thus, bSwRfProcessing
4234 // blocks the IPS procedure of switching RF.
4235 // By Bruce, 2007-12-25.
4236 //
4237 pPSC->bSwRfProcessing = TRUE;
4238
207b58fb 4239 RT_TRACE(COMP_RF, "InactivePsWorkItemCallback(): Set RF to %s.\n",
ecdfa446
GKH
4240 pPSC->eInactivePowerState == eRfOff?"OFF":"ON");
4241
4242
4243 MgntActSet_RF_State(dev, pPSC->eInactivePowerState, RF_CHANGE_BY_IPS);
4244
4245 //
4246 // To solve CAM values miss in RF OFF, rewrite CAM values after RF ON. By Bruce, 2007-09-20.
4247 //
ecdfa446
GKH
4248 pPSC->bSwRfProcessing = FALSE;
4249 RT_TRACE(COMP_POWER, "InactivePsWorkItemCallback() <--------- \n");
4250}
4251
65a43784 4252#ifdef ENABLE_LPS
214985a6 4253/* Change current and default preamble mode. */
65a43784 4254bool MgntActSet_802_11_PowerSaveMode(struct net_device *dev, u8 rtPsMode)
4255{
4256 struct r8192_priv *priv = ieee80211_priv(dev);
65a43784 4257
4258 // Currently, we do not change power save mode on IBSS mode.
4259 if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
4260 {
4261 return false;
4262 }
4263
4264 //
4265 // <RJ_NOTE> If we make HW to fill up the PwrMgt bit for us,
4266 // some AP will not response to our mgnt frames with PwrMgt bit set,
4267 // e.g. cannot associate the AP.
4268 // So I commented out it. 2005.02.16, by rcnjko.
4269 //
4270// // Change device's power save mode.
4271// Adapter->HalFunc.SetPSModeHandler( Adapter, rtPsMode );
4272
4273 // Update power save mode configured.
4274 //RT_TRACE(COMP_LPS,"%s(): set ieee->ps = %x\n",__FUNCTION__,rtPsMode);
4275 if(!priv->ps_force) {
4276 priv->ieee80211->ps = rtPsMode;
4277 }
4278
4279 // Awake immediately
4280 if(priv->ieee80211->sta_sleep != 0 && rtPsMode == IEEE80211_PS_DISABLED)
4281 {
4282 unsigned long flags;
4283
4284 //PlatformSetTimer(Adapter, &(pMgntInfo->AwakeTimer), 0);
4285 // Notify the AP we awke.
4286 rtl8192_hw_wakeup(dev);
4287 priv->ieee80211->sta_sleep = 0;
4288
4289 spin_lock_irqsave(&(priv->ieee80211->mgmt_tx_lock), flags);
4290 printk("LPS leave: notify AP we are awaked ++++++++++ SendNullFunctionData\n");
4291 ieee80211_sta_ps_send_null_frame(priv->ieee80211, 0);
4292 spin_unlock_irqrestore(&(priv->ieee80211->mgmt_tx_lock), flags);
4293 }
4294
4295 return true;
4296}
4297
214985a6 4298/* Enter the leisure power save mode. */
65a43784 4299void LeisurePSEnter(struct net_device *dev)
4300{
4301 struct r8192_priv *priv = ieee80211_priv(dev);
4302 PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->ieee80211->PowerSaveControl));
4303
4304 //RT_TRACE(COMP_PS, "LeisurePSEnter()...\n");
4305 //RT_TRACE(COMP_PS, "pPSC->bLeisurePs = %d, ieee->ps = %d,pPSC->LpsIdleCount is %d,RT_CHECK_FOR_HANG_PERIOD is %d\n",
4306 // pPSC->bLeisurePs, priv->ieee80211->ps,pPSC->LpsIdleCount,RT_CHECK_FOR_HANG_PERIOD);
4307
4308 if(!((priv->ieee80211->iw_mode == IW_MODE_INFRA) &&
4309 (priv->ieee80211->state == IEEE80211_LINKED)) ||
4310 (priv->ieee80211->iw_mode == IW_MODE_ADHOC) ||
4311 (priv->ieee80211->iw_mode == IW_MODE_MASTER))
4312 return;
4313
4314 if (pPSC->bLeisurePs)
4315 {
4316 // Idle for a while if we connect to AP a while ago.
4317 if(pPSC->LpsIdleCount >= RT_CHECK_FOR_HANG_PERIOD) // 4 Sec
4318 {
4319
4320 if(priv->ieee80211->ps == IEEE80211_PS_DISABLED)
4321 {
4322
4323 //RT_TRACE(COMP_LPS, "LeisurePSEnter(): Enter 802.11 power save mode...\n");
4324 MgntActSet_802_11_PowerSaveMode(dev, IEEE80211_PS_MBCAST|IEEE80211_PS_UNICAST);
4325
4326 }
4327 }
4328 else
4329 pPSC->LpsIdleCount++;
4330 }
4331}
4332
4333
214985a6 4334/* Leave leisure power save mode. */
65a43784 4335void LeisurePSLeave(struct net_device *dev)
4336{
4337 struct r8192_priv *priv = ieee80211_priv(dev);
4338 PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->ieee80211->PowerSaveControl));
4339
65a43784 4340 if (pPSC->bLeisurePs)
4341 {
4342 if(priv->ieee80211->ps != IEEE80211_PS_DISABLED)
4343 {
4344 // move to lps_wakecomplete()
4345 //RT_TRACE(COMP_LPS, "LeisurePSLeave(): Busy Traffic , Leave 802.11 power save..\n");
4346 MgntActSet_802_11_PowerSaveMode(dev, IEEE80211_PS_DISABLED);
4347
4348 }
4349 }
4350}
4351#endif
4352
4353
214985a6 4354/* Enter the inactive power save mode. RF will be off */
ecdfa446
GKH
4355void
4356IPSEnter(struct net_device *dev)
4357{
4358 struct r8192_priv *priv = ieee80211_priv(dev);
4359 PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->ieee80211->PowerSaveControl));
4360 RT_RF_POWER_STATE rtState;
4361
4362 if (pPSC->bInactivePs)
4363 {
4364 rtState = priv->ieee80211->eRFPowerState;
4365 //
4366 // Added by Bruce, 2007-12-25.
4367 // Do not enter IPS in the following conditions:
4368 // (1) RF is already OFF or Sleep
4369 // (2) bSwRfProcessing (indicates the IPS is still under going)
4370 // (3) Connectted (only disconnected can trigger IPS)
4371 // (4) IBSS (send Beacon)
4372 // (5) AP mode (send Beacon)
4373 //
4374 if (rtState == eRfOn && !pPSC->bSwRfProcessing
4375 && (priv->ieee80211->state != IEEE80211_LINKED) )
4376 {
4377 RT_TRACE(COMP_RF,"IPSEnter(): Turn off RF.\n");
65a43784 4378 //printk("IPSEnter(): Turn off RF.\n");
ecdfa446
GKH
4379 pPSC->eInactivePowerState = eRfOff;
4380// queue_work(priv->priv_wq,&(pPSC->InactivePsWorkItem));
4381 InactivePsWorkItemCallback(dev);
4382 }
4383 }
4384}
4385
4386//
4387// Description:
4388// Leave the inactive power save mode, RF will be on.
4389// 2007.08.17, by shien chang.
4390//
4391void
4392IPSLeave(struct net_device *dev)
4393{
4394 struct r8192_priv *priv = ieee80211_priv(dev);
4395 PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->ieee80211->PowerSaveControl));
4396 RT_RF_POWER_STATE rtState;
4397
4398 if (pPSC->bInactivePs)
4399 {
4400 rtState = priv->ieee80211->eRFPowerState;
4401 if (rtState != eRfOn && !pPSC->bSwRfProcessing && priv->ieee80211->RfOffReason <= RF_CHANGE_BY_IPS)
4402 {
4403 RT_TRACE(COMP_POWER, "IPSLeave(): Turn on RF.\n");
65a43784 4404 //printk("IPSLeave(): Turn on RF.\n");
ecdfa446
GKH
4405 pPSC->eInactivePowerState = eRfOn;
4406// queue_work(priv->priv_wq,&(pPSC->InactivePsWorkItem));
4407 InactivePsWorkItemCallback(dev);
4408 }
4409 }
4410}
65a43784 4411
4412void IPSLeave_wq(void *data)
4413{
4414 struct ieee80211_device *ieee = container_of(data,struct ieee80211_device,ips_leave_wq);
4415 struct net_device *dev = ieee->dev;
4416
4417 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
4418 down(&priv->ieee80211->ips_sem);
4419 IPSLeave(dev);
4420 up(&priv->ieee80211->ips_sem);
4421}
4422
4423void ieee80211_ips_leave_wq(struct net_device *dev)
4424{
4425 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
4426 RT_RF_POWER_STATE rtState;
4427 rtState = priv->ieee80211->eRFPowerState;
4428
4429 if(priv->ieee80211->PowerSaveControl.bInactivePs){
4430 if(rtState == eRfOff){
4431 if(priv->ieee80211->RfOffReason > RF_CHANGE_BY_IPS)
4432 {
4433 RT_TRACE(COMP_ERR, "%s(): RF is OFF.\n",__FUNCTION__);
4434 return;
4435 }
4436 else{
4437 printk("=========>%s(): IPSLeave\n",__FUNCTION__);
4438 queue_work(priv->ieee80211->wq,&priv->ieee80211->ips_leave_wq);
4439 }
4440 }
4441 }
4442}
4443//added by amy 090331 end
4444void ieee80211_ips_leave(struct net_device *dev)
4445{
4446 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
4447 down(&priv->ieee80211->ips_sem);
4448 IPSLeave(dev);
4449 up(&priv->ieee80211->ips_sem);
4450}
ecdfa446 4451#endif
ecdfa446 4452
5e1ad18a 4453static void rtl819x_update_rxcounts(
ecdfa446
GKH
4454 struct r8192_priv *priv,
4455 u32* TotalRxBcnNum,
4456 u32* TotalRxDataNum
4457)
4458{
4459 u16 SlotIndex;
4460 u8 i;
4461
4462 *TotalRxBcnNum = 0;
4463 *TotalRxDataNum = 0;
4464
4465 SlotIndex = (priv->ieee80211->LinkDetectInfo.SlotIndex++)%(priv->ieee80211->LinkDetectInfo.SlotNum);
4466 priv->ieee80211->LinkDetectInfo.RxBcnNum[SlotIndex] = priv->ieee80211->LinkDetectInfo.NumRecvBcnInPeriod;
4467 priv->ieee80211->LinkDetectInfo.RxDataNum[SlotIndex] = priv->ieee80211->LinkDetectInfo.NumRecvDataInPeriod;
4468 for( i=0; i<priv->ieee80211->LinkDetectInfo.SlotNum; i++ ){
4469 *TotalRxBcnNum += priv->ieee80211->LinkDetectInfo.RxBcnNum[i];
4470 *TotalRxDataNum += priv->ieee80211->LinkDetectInfo.RxDataNum[i];
4471 }
4472}
4473
4474
559fba5e 4475static void rtl819x_watchdog_wqcallback(struct work_struct *work)
ecdfa446
GKH
4476{
4477 struct delayed_work *dwork = container_of(work,struct delayed_work,work);
4478 struct r8192_priv *priv = container_of(dwork,struct r8192_priv,watch_dog_wq);
4479 struct net_device *dev = priv->ieee80211->dev;
ecdfa446
GKH
4480 struct ieee80211_device* ieee = priv->ieee80211;
4481 RESET_TYPE ResetType = RESET_TYPE_NORESET;
4482 static u8 check_reset_cnt=0;
4483 unsigned long flags;
4484 bool bBusyTraffic = false;
4485 static u8 last_time = 0;
65a43784 4486 bool bEnterPS = false;
4487
f500e256 4488 if ((!priv->up) || priv->bHwRadioOff)
65a43784 4489 return;
4490
ecdfa446
GKH
4491 if(!priv->up)
4492 return;
4493 hal_dm_watchdog(dev);
4494#ifdef ENABLE_IPS
4495// printk("watch_dog ENABLE_IPS\n");
4496 if(ieee->actscanning == false){
65a43784 4497 //printk("%d,%d,%d,%d\n", ieee->eRFPowerState, ieee->is_set_key, ieee->proto_stoppping, ieee->wx_set_enc);
207b58fb
MM
4498 if((ieee->iw_mode == IW_MODE_INFRA) && (ieee->state == IEEE80211_NOLINK) &&
4499 (ieee->eRFPowerState == eRfOn)&&!ieee->is_set_key &&
65a43784 4500 (!ieee->proto_stoppping) && !ieee->wx_set_enc){
ecdfa446 4501 if(ieee->PowerSaveControl.ReturnPoint == IPS_CALLBACK_NONE){
65a43784 4502 //printk("====================>haha:IPSEnter()\n");
ecdfa446
GKH
4503 IPSEnter(dev);
4504 //ieee80211_stop_scan(priv->ieee80211);
4505 }
4506 }
4507 }
4508#endif
4509 {//to get busy traffic condition
4510 if(ieee->state == IEEE80211_LINKED)
4511 {
65a43784 4512 if( ieee->LinkDetectInfo.NumRxOkInPeriod> 100 ||
4513 ieee->LinkDetectInfo.NumTxOkInPeriod> 100 ) {
ecdfa446
GKH
4514 bBusyTraffic = true;
4515 }
4516
65a43784 4517#ifdef ENABLE_LPS
4518 //added by amy for Leisure PS
4519 if( ((ieee->LinkDetectInfo.NumRxUnicastOkInPeriod + ieee->LinkDetectInfo.NumTxOkInPeriod) > 8 ) ||
4520 (ieee->LinkDetectInfo.NumRxUnicastOkInPeriod > 2) )
4521 {
4522 //printk("ieee->LinkDetectInfo.NumRxUnicastOkInPeriod is %d,ieee->LinkDetectInfo.NumTxOkInPeriod is %d\n",
4523 // ieee->LinkDetectInfo.NumRxUnicastOkInPeriod,ieee->LinkDetectInfo.NumTxOkInPeriod);
4524 bEnterPS= false;
4525 }
4526 else
4527 {
4528 bEnterPS= true;
4529 }
4530
4531 //printk("***bEnterPS = %d\n", bEnterPS);
4532 // LeisurePS only work in infra mode.
4533 if(bEnterPS)
4534 {
4535 LeisurePSEnter(dev);
4536 }
4537 else
4538 {
4539 LeisurePSLeave(dev);
4540 }
4541#endif
4542
4543 }
4544 else
4545 {
4546#ifdef ENABLE_LPS
4547 //RT_TRACE(COMP_LPS,"====>no link LPS leave\n");
4548 LeisurePSLeave(dev);
4549#endif
ecdfa446 4550 }
65a43784 4551
ecdfa446
GKH
4552 ieee->LinkDetectInfo.NumRxOkInPeriod = 0;
4553 ieee->LinkDetectInfo.NumTxOkInPeriod = 0;
65a43784 4554 ieee->LinkDetectInfo.NumRxUnicastOkInPeriod = 0;
ecdfa446
GKH
4555 ieee->LinkDetectInfo.bBusyTraffic = bBusyTraffic;
4556 }
4557
4558
4559 //added by amy for AP roaming
4560 if (1)
4561 {
4562 if(ieee->state == IEEE80211_LINKED && ieee->iw_mode == IW_MODE_INFRA)
4563 {
4564 u32 TotalRxBcnNum = 0;
4565 u32 TotalRxDataNum = 0;
4566
4567 rtl819x_update_rxcounts(priv, &TotalRxBcnNum, &TotalRxDataNum);
4568 if((TotalRxBcnNum+TotalRxDataNum) == 0)
4569 {
4570 if( ieee->eRFPowerState == eRfOff)
4571 RT_TRACE(COMP_ERR,"========>%s()\n",__FUNCTION__);
4572 printk("===>%s(): AP is power off,connect another one\n",__FUNCTION__);
65a43784 4573 // Dot11d_Reset(dev);
ecdfa446
GKH
4574 ieee->state = IEEE80211_ASSOCIATING;
4575 notify_wx_assoc_event(priv->ieee80211);
65a43784 4576 RemovePeerTS(priv->ieee80211,priv->ieee80211->current_network.bssid);
ecdfa446
GKH
4577 ieee->is_roaming = true;
4578 ieee->is_set_key = false;
65a43784 4579 ieee->link_change(dev);
4580 queue_work(ieee->wq, &ieee->associate_procedure_wq);
ecdfa446
GKH
4581 }
4582 }
4583 ieee->LinkDetectInfo.NumRecvBcnInPeriod=0;
4584 ieee->LinkDetectInfo.NumRecvDataInPeriod=0;
4585
4586 }
ecdfa446
GKH
4587 //check if reset the driver
4588 spin_lock_irqsave(&priv->tx_lock,flags);
4589 if(check_reset_cnt++ >= 3 && !ieee->is_roaming && (last_time != 1))
4590 {
4591 ResetType = rtl819x_ifcheck_resetornot(dev);
4592 check_reset_cnt = 3;
4593 //DbgPrint("Start to check silent reset\n");
4594 }
4595 spin_unlock_irqrestore(&priv->tx_lock,flags);
4596 if(!priv->bDisableNormalResetCheck && ResetType == RESET_TYPE_NORMAL)
4597 {
4598 priv->ResetProgress = RESET_TYPE_NORMAL;
4599 RT_TRACE(COMP_RESET,"%s(): NOMAL RESET\n",__FUNCTION__);
4600 return;
4601 }
4602 /* disable silent reset temply 2008.9.11*/
4603#if 1
4604 if( ((priv->force_reset) || (!priv->bDisableNormalResetCheck && ResetType==RESET_TYPE_SILENT))) // This is control by OID set in Pomelo
4605 {
4606 last_time = 1;
4607 rtl819x_ifsilentreset(dev);
4608 }
4609 else
4610 last_time = 0;
4611#endif
4612 priv->force_reset = false;
4613 priv->bForcedSilentReset = false;
4614 priv->bResetInProgress = false;
4615 RT_TRACE(COMP_TRACE, " <==RtUsbCheckForHangWorkItemCallback()\n");
4616
4617}
4618
4619void watch_dog_timer_callback(unsigned long data)
4620{
4621 struct r8192_priv *priv = ieee80211_priv((struct net_device *) data);
ecdfa446 4622 queue_delayed_work(priv->priv_wq,&priv->watch_dog_wq,0);
ecdfa446
GKH
4623 mod_timer(&priv->watch_dog_timer, jiffies + MSECS(IEEE80211_WATCH_DOG_TIME));
4624
4625}
5b3b1a7b
MM
4626
4627static int _rtl8192_up(struct net_device *dev)
ecdfa446
GKH
4628{
4629 struct r8192_priv *priv = ieee80211_priv(dev);
4630 //int i;
4631 RT_STATUS init_status = RT_STATUS_SUCCESS;
4632 priv->up=1;
4633 priv->ieee80211->ieee_up=1;
65a43784 4634 priv->bdisable_nic = false; //YJ,add,091111
ecdfa446
GKH
4635 RT_TRACE(COMP_INIT, "Bringing up iface");
4636
4637 init_status = rtl8192_adapter_start(dev);
4638 if(init_status != RT_STATUS_SUCCESS)
4639 {
4640 RT_TRACE(COMP_ERR,"ERR!!! %s(): initialization is failed!\n",__FUNCTION__);
4641 return -1;
4642 }
4643 RT_TRACE(COMP_INIT, "start adapter finished\n");
4644#ifdef RTL8192E
4645 if(priv->ieee80211->eRFPowerState!=eRfOn)
4646 MgntActSet_RF_State(dev, eRfOn, priv->ieee80211->RfOffReason);
4647#endif
4648 if(priv->ieee80211->state != IEEE80211_LINKED)
4649 ieee80211_softmac_start_protocol(priv->ieee80211);
4650 ieee80211_reset_queue(priv->ieee80211);
4651 watch_dog_timer_callback((unsigned long) dev);
4652 if(!netif_queue_stopped(dev))
4653 netif_start_queue(dev);
4654 else
4655 netif_wake_queue(dev);
4656
4657 return 0;
4658}
4659
4660
5e1ad18a 4661static int rtl8192_open(struct net_device *dev)
ecdfa446
GKH
4662{
4663 struct r8192_priv *priv = ieee80211_priv(dev);
4664 int ret;
4665
4666 down(&priv->wx_sem);
4667 ret = rtl8192_up(dev);
4668 up(&priv->wx_sem);
4669 return ret;
4670
4671}
4672
4673
4674int rtl8192_up(struct net_device *dev)
4675{
4676 struct r8192_priv *priv = ieee80211_priv(dev);
4677
4678 if (priv->up == 1) return -1;
4679
4680 return _rtl8192_up(dev);
4681}
4682
4683
5e1ad18a 4684static int rtl8192_close(struct net_device *dev)
ecdfa446
GKH
4685{
4686 struct r8192_priv *priv = ieee80211_priv(dev);
4687 int ret;
4688
4689 down(&priv->wx_sem);
4690
4691 ret = rtl8192_down(dev);
4692
4693 up(&priv->wx_sem);
4694
4695 return ret;
4696
4697}
4698
4699int rtl8192_down(struct net_device *dev)
4700{
4701 struct r8192_priv *priv = ieee80211_priv(dev);
16d74da0 4702
ecdfa446
GKH
4703 if (priv->up == 0) return -1;
4704
65a43784 4705#ifdef ENABLE_LPS
4706 //LZM for PS-Poll AID issue. 090429
4707 if(priv->ieee80211->state == IEEE80211_LINKED)
4708 LeisurePSLeave(dev);
4709#endif
4710
ecdfa446
GKH
4711 priv->up=0;
4712 priv->ieee80211->ieee_up = 0;
4713 RT_TRACE(COMP_DOWN, "==========>%s()\n", __FUNCTION__);
4714/* FIXME */
4715 if (!netif_queue_stopped(dev))
4716 netif_stop_queue(dev);
4717
4718 rtl8192_irq_disable(dev);
ecdfa446
GKH
4719 rtl8192_cancel_deferred_work(priv);
4720 deinit_hal_dm(dev);
4721 del_timer_sync(&priv->watch_dog_timer);
4722
65a43784 4723 ieee80211_softmac_stop_protocol(priv->ieee80211,true);
4724
4725 rtl8192_halt_adapter(dev,false);
ecdfa446
GKH
4726 memset(&priv->ieee80211->current_network, 0 , offsetof(struct ieee80211_network, list));
4727
4728 RT_TRACE(COMP_DOWN, "<==========%s()\n", __FUNCTION__);
4729
16d74da0 4730 return 0;
ecdfa446
GKH
4731}
4732
4733
4734void rtl8192_commit(struct net_device *dev)
4735{
4736 struct r8192_priv *priv = ieee80211_priv(dev);
4737
4738 if (priv->up == 0) return ;
4739
4740
65a43784 4741 ieee80211_softmac_stop_protocol(priv->ieee80211,true);
ecdfa446
GKH
4742
4743 rtl8192_irq_disable(dev);
65a43784 4744 rtl8192_halt_adapter(dev,true);
ecdfa446
GKH
4745 _rtl8192_up(dev);
4746}
4747
5b3b1a7b 4748static void rtl8192_restart(struct work_struct *work)
ecdfa446
GKH
4749{
4750 struct r8192_priv *priv = container_of(work, struct r8192_priv, reset_wq);
4751 struct net_device *dev = priv->ieee80211->dev;
ecdfa446
GKH
4752
4753 down(&priv->wx_sem);
4754
4755 rtl8192_commit(dev);
4756
4757 up(&priv->wx_sem);
4758}
4759
4760static void r8192_set_multicast(struct net_device *dev)
4761{
4762 struct r8192_priv *priv = ieee80211_priv(dev);
4763 short promisc;
4764
4765 //down(&priv->wx_sem);
4766
4767 /* FIXME FIXME */
4768
4769 promisc = (dev->flags & IFF_PROMISC) ? 1:0;
4770
4771 if (promisc != priv->promisc) {
4772 ;
4773 // rtl8192_commit(dev);
4774 }
4775
4776 priv->promisc = promisc;
4777
4778 //schedule_work(&priv->reset_wq);
4779 //up(&priv->wx_sem);
4780}
4781
4782
5e1ad18a 4783static int r8192_set_mac_adr(struct net_device *dev, void *mac)
ecdfa446
GKH
4784{
4785 struct r8192_priv *priv = ieee80211_priv(dev);
4786 struct sockaddr *addr = mac;
4787
4788 down(&priv->wx_sem);
4789
4790 memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
4791
ecdfa446 4792 schedule_work(&priv->reset_wq);
ecdfa446
GKH
4793 up(&priv->wx_sem);
4794
4795 return 0;
4796}
4797
4798/* based on ipw2200 driver */
5e1ad18a 4799static int rtl8192_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
ecdfa446
GKH
4800{
4801 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
4802 struct iwreq *wrq = (struct iwreq *)rq;
4803 int ret=-1;
4804 struct ieee80211_device *ieee = priv->ieee80211;
4805 u32 key[4];
4806 u8 broadcast_addr[6] = {0xff,0xff,0xff,0xff,0xff,0xff};
4807 struct iw_point *p = &wrq->u.data;
4808 struct ieee_param *ipw = NULL;//(struct ieee_param *)wrq->u.data.pointer;
4809
4810 down(&priv->wx_sem);
4811
4812
4813 if (p->length < sizeof(struct ieee_param) || !p->pointer){
4814 ret = -EINVAL;
4815 goto out;
4816 }
4817
32414878 4818 ipw = kmalloc(p->length, GFP_KERNEL);
ecdfa446
GKH
4819 if (ipw == NULL){
4820 ret = -ENOMEM;
4821 goto out;
4822 }
4823 if (copy_from_user(ipw, p->pointer, p->length)) {
4824 kfree(ipw);
4825 ret = -EFAULT;
4826 goto out;
4827 }
4828
4829 switch (cmd) {
4830 case RTL_IOCTL_WPA_SUPPLICANT:
4831 //parse here for HW security
4832 if (ipw->cmd == IEEE_CMD_SET_ENCRYPTION)
4833 {
4834 if (ipw->u.crypt.set_tx)
4835 {
4836 if (strcmp(ipw->u.crypt.alg, "CCMP") == 0)
4837 ieee->pairwise_key_type = KEY_TYPE_CCMP;
4838 else if (strcmp(ipw->u.crypt.alg, "TKIP") == 0)
4839 ieee->pairwise_key_type = KEY_TYPE_TKIP;
4840 else if (strcmp(ipw->u.crypt.alg, "WEP") == 0)
4841 {
4842 if (ipw->u.crypt.key_len == 13)
4843 ieee->pairwise_key_type = KEY_TYPE_WEP104;
4844 else if (ipw->u.crypt.key_len == 5)
4845 ieee->pairwise_key_type = KEY_TYPE_WEP40;
4846 }
4847 else
4848 ieee->pairwise_key_type = KEY_TYPE_NA;
4849
4850 if (ieee->pairwise_key_type)
4851 {
4852 memcpy((u8*)key, ipw->u.crypt.key, 16);
4853 EnableHWSecurityConfig8192(dev);
4854 //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!
4855 //added by WB.
4856 setKey(dev, 4, ipw->u.crypt.idx, ieee->pairwise_key_type, (u8*)ieee->ap_mac_addr, 0, key);
4857 if (ieee->auth_mode != 2) //LEAP WEP will never set this.
4858 setKey(dev, ipw->u.crypt.idx, ipw->u.crypt.idx, ieee->pairwise_key_type, (u8*)ieee->ap_mac_addr, 0, key);
4859 }
4860 if ((ieee->pairwise_key_type == KEY_TYPE_CCMP) && ieee->pHTInfo->bCurrentHTSupport){
4861 write_nic_byte(dev, 0x173, 1); //fix aes bug
4862 }
4863
4864 }
4865 else //if (ipw->u.crypt.idx) //group key use idx > 0
4866 {
4867 memcpy((u8*)key, ipw->u.crypt.key, 16);
4868 if (strcmp(ipw->u.crypt.alg, "CCMP") == 0)
4869 ieee->group_key_type= KEY_TYPE_CCMP;
4870 else if (strcmp(ipw->u.crypt.alg, "TKIP") == 0)
4871 ieee->group_key_type = KEY_TYPE_TKIP;
4872 else if (strcmp(ipw->u.crypt.alg, "WEP") == 0)
4873 {
4874 if (ipw->u.crypt.key_len == 13)
4875 ieee->group_key_type = KEY_TYPE_WEP104;
4876 else if (ipw->u.crypt.key_len == 5)
4877 ieee->group_key_type = KEY_TYPE_WEP40;
4878 }
4879 else
4880 ieee->group_key_type = KEY_TYPE_NA;
4881
4882 if (ieee->group_key_type)
4883 {
4884 setKey( dev,
4885 ipw->u.crypt.idx,
4886 ipw->u.crypt.idx, //KeyIndex
4887 ieee->group_key_type, //KeyType
4888 broadcast_addr, //MacAddr
4889 0, //DefaultKey
4890 key); //KeyContent
4891 }
4892 }
4893 }
4894#ifdef JOHN_DEBUG
4895 //john's test 0711
4896 {
4897 int i;
4898 printk("@@ wrq->u pointer = ");
4899 for(i=0;i<wrq->u.data.length;i++){
4900 if(i%10==0) printk("\n");
4901 printk( "%8x|", ((u32*)wrq->u.data.pointer)[i] );
4902 }
4903 printk("\n");
4904 }
4905#endif /*JOHN_DEBUG*/
4906 ret = ieee80211_wpa_supplicant_ioctl(priv->ieee80211, &wrq->u.data);
4907 break;
4908
4909 default:
4910 ret = -EOPNOTSUPP;
4911 break;
4912 }
4913
4914 kfree(ipw);
4915out:
4916 up(&priv->wx_sem);
4917
4918 return ret;
4919}
4920
5e1ad18a 4921static u8 HwRateToMRate90(bool bIsHT, u8 rate)
ecdfa446
GKH
4922{
4923 u8 ret_rate = 0x02;
4924
4925 if(!bIsHT) {
4926 switch(rate) {
4927 case DESC90_RATE1M: ret_rate = MGN_1M; break;
4928 case DESC90_RATE2M: ret_rate = MGN_2M; break;
4929 case DESC90_RATE5_5M: ret_rate = MGN_5_5M; break;
4930 case DESC90_RATE11M: ret_rate = MGN_11M; break;
4931 case DESC90_RATE6M: ret_rate = MGN_6M; break;
4932 case DESC90_RATE9M: ret_rate = MGN_9M; break;
4933 case DESC90_RATE12M: ret_rate = MGN_12M; break;
4934 case DESC90_RATE18M: ret_rate = MGN_18M; break;
4935 case DESC90_RATE24M: ret_rate = MGN_24M; break;
4936 case DESC90_RATE36M: ret_rate = MGN_36M; break;
4937 case DESC90_RATE48M: ret_rate = MGN_48M; break;
4938 case DESC90_RATE54M: ret_rate = MGN_54M; break;
4939
4940 default:
4941 RT_TRACE(COMP_RECV, "HwRateToMRate90(): Non supported Rate [%x], bIsHT = %d!!!\n", rate, bIsHT);
4942 break;
4943 }
4944
4945 } else {
4946 switch(rate) {
4947 case DESC90_RATEMCS0: ret_rate = MGN_MCS0; break;
4948 case DESC90_RATEMCS1: ret_rate = MGN_MCS1; break;
4949 case DESC90_RATEMCS2: ret_rate = MGN_MCS2; break;
4950 case DESC90_RATEMCS3: ret_rate = MGN_MCS3; break;
4951 case DESC90_RATEMCS4: ret_rate = MGN_MCS4; break;
4952 case DESC90_RATEMCS5: ret_rate = MGN_MCS5; break;
4953 case DESC90_RATEMCS6: ret_rate = MGN_MCS6; break;
4954 case DESC90_RATEMCS7: ret_rate = MGN_MCS7; break;
4955 case DESC90_RATEMCS8: ret_rate = MGN_MCS8; break;
4956 case DESC90_RATEMCS9: ret_rate = MGN_MCS9; break;
4957 case DESC90_RATEMCS10: ret_rate = MGN_MCS10; break;
4958 case DESC90_RATEMCS11: ret_rate = MGN_MCS11; break;
4959 case DESC90_RATEMCS12: ret_rate = MGN_MCS12; break;
4960 case DESC90_RATEMCS13: ret_rate = MGN_MCS13; break;
4961 case DESC90_RATEMCS14: ret_rate = MGN_MCS14; break;
4962 case DESC90_RATEMCS15: ret_rate = MGN_MCS15; break;
4963 case DESC90_RATEMCS32: ret_rate = (0x80|0x20); break;
4964
4965 default:
4966 RT_TRACE(COMP_RECV, "HwRateToMRate90(): Non supported Rate [%x], bIsHT = %d!!!\n",rate, bIsHT);
4967 break;
4968 }
4969 }
4970
4971 return ret_rate;
4972}
4973
214985a6 4974/* Record the TSF time stamp when receiving a packet */
5e1ad18a 4975static void UpdateRxPktTimeStamp8190 (struct net_device *dev, struct ieee80211_rx_stats *stats)
ecdfa446
GKH
4976{
4977 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
4978
4979 if(stats->bIsAMPDU && !stats->bFirstMPDU) {
4980 stats->mac_time[0] = priv->LastRxDescTSFLow;
4981 stats->mac_time[1] = priv->LastRxDescTSFHigh;
4982 } else {
4983 priv->LastRxDescTSFLow = stats->mac_time[0];
4984 priv->LastRxDescTSFHigh = stats->mac_time[1];
4985 }
4986}
4987
5e1ad18a 4988static long rtl819x_translate_todbm(u8 signal_strength_index)// 0-100 index.
ecdfa446
GKH
4989{
4990 long signal_power; // in dBm.
4991
4992 // Translate to dBm (x=0.5y-95).
4993 signal_power = (long)((signal_strength_index + 1) >> 1);
4994 signal_power -= 95;
4995
4996 return signal_power;
4997}
4998
214985a6
MM
4999/*
5000 * Update Rx signal related information in the packet reeived
5001 * to RxStats. User application can query RxStats to realize
5002 * current Rx signal status.
5003 *
5004 * In normal operation, user only care about the information of the BSS
5005 * and we shall invoke this function if the packet received is from the BSS.
5006 */
5e1ad18a 5007static void
ecdfa446
GKH
5008rtl819x_update_rxsignalstatistics8190pci(
5009 struct r8192_priv * priv,
5010 struct ieee80211_rx_stats * pprevious_stats
5011 )
5012{
5013 int weighting = 0;
5014
5015 //2 <ToDo> Update Rx Statistics (such as signal strength and signal quality).
5016
5017 // Initila state
5018 if(priv->stats.recv_signal_power == 0)
5019 priv->stats.recv_signal_power = pprevious_stats->RecvSignalPower;
5020
5021 // To avoid the past result restricting the statistics sensitivity, weight the current power (5/6) to speed up the
5022 // reaction of smoothed Signal Power.
5023 if(pprevious_stats->RecvSignalPower > priv->stats.recv_signal_power)
5024 weighting = 5;
5025 else if(pprevious_stats->RecvSignalPower < priv->stats.recv_signal_power)
5026 weighting = (-5);
5027 //
5028 // We need more correct power of received packets and the "SignalStrength" of RxStats have been beautified or translated,
5029 // so we record the correct power in Dbm here. By Bruce, 2008-03-07.
5030 //
5031 priv->stats.recv_signal_power = (priv->stats.recv_signal_power * 5 + pprevious_stats->RecvSignalPower + weighting) / 6;
5032}
5033
5e1ad18a 5034static void
ecdfa446
GKH
5035rtl8190_process_cck_rxpathsel(
5036 struct r8192_priv * priv,
5037 struct ieee80211_rx_stats * pprevious_stats
5038 )
5039{
5040#ifdef RTL8190P //Only 90P 2T4R need to check
5041 char last_cck_adc_pwdb[4]={0,0,0,0};
5042 u8 i;
5043//cosa add for Rx path selection
5044 if(priv->rf_type == RF_2T4R && DM_RxPathSelTable.Enable)
5045 {
5046 if(pprevious_stats->bIsCCK &&
5047 (pprevious_stats->bPacketToSelf ||pprevious_stats->bPacketBeacon))
5048 {
5049 /* record the cck adc_pwdb to the sliding window. */
5050 if(priv->stats.cck_adc_pwdb.TotalNum++ >= PHY_RSSI_SLID_WIN_MAX)
5051 {
5052 priv->stats.cck_adc_pwdb.TotalNum = PHY_RSSI_SLID_WIN_MAX;
5053 for(i=RF90_PATH_A; i<RF90_PATH_MAX; i++)
5054 {
5055 last_cck_adc_pwdb[i] = priv->stats.cck_adc_pwdb.elements[i][priv->stats.cck_adc_pwdb.index];
5056 priv->stats.cck_adc_pwdb.TotalVal[i] -= last_cck_adc_pwdb[i];
5057 }
5058 }
5059 for(i=RF90_PATH_A; i<RF90_PATH_MAX; i++)
5060 {
5061 priv->stats.cck_adc_pwdb.TotalVal[i] += pprevious_stats->cck_adc_pwdb[i];
5062 priv->stats.cck_adc_pwdb.elements[i][priv->stats.cck_adc_pwdb.index] = pprevious_stats->cck_adc_pwdb[i];
5063 }
5064 priv->stats.cck_adc_pwdb.index++;
5065 if(priv->stats.cck_adc_pwdb.index >= PHY_RSSI_SLID_WIN_MAX)
5066 priv->stats.cck_adc_pwdb.index = 0;
5067
5068 for(i=RF90_PATH_A; i<RF90_PATH_MAX; i++)
5069 {
5070 DM_RxPathSelTable.cck_pwdb_sta[i] = priv->stats.cck_adc_pwdb.TotalVal[i]/priv->stats.cck_adc_pwdb.TotalNum;
5071 }
5072
5073 for(i=RF90_PATH_A; i<RF90_PATH_MAX; i++)
5074 {
5075 if(pprevious_stats->cck_adc_pwdb[i] > (char)priv->undecorated_smoothed_cck_adc_pwdb[i])
5076 {
5077 priv->undecorated_smoothed_cck_adc_pwdb[i] =
5078 ( (priv->undecorated_smoothed_cck_adc_pwdb[i]*(Rx_Smooth_Factor-1)) +
5079 (pprevious_stats->cck_adc_pwdb[i])) /(Rx_Smooth_Factor);
5080 priv->undecorated_smoothed_cck_adc_pwdb[i] = priv->undecorated_smoothed_cck_adc_pwdb[i] + 1;
5081 }
5082 else
5083 {
5084 priv->undecorated_smoothed_cck_adc_pwdb[i] =
5085 ( (priv->undecorated_smoothed_cck_adc_pwdb[i]*(Rx_Smooth_Factor-1)) +
5086 (pprevious_stats->cck_adc_pwdb[i])) /(Rx_Smooth_Factor);
5087 }
5088 }
5089 }
5090 }
5091#endif
5092}
5093
5094
5095/* 2008/01/22 MH We can not delcare RSSI/EVM total value of sliding window to
5096 be a local static. Otherwise, it may increase when we return from S3/S4. The
5097 value will be kept in memory or disk. We must delcare the value in adapter
5098 and it will be reinitialized when return from S3/S4. */
5e1ad18a 5099static void rtl8192_process_phyinfo(struct r8192_priv * priv, u8* buffer,struct ieee80211_rx_stats * pprevious_stats, struct ieee80211_rx_stats * pcurrent_stats)
ecdfa446
GKH
5100{
5101 bool bcheck = false;
5102 u8 rfpath;
5103 u32 nspatial_stream, tmp_val;
5104 //u8 i;
5105 static u32 slide_rssi_index=0, slide_rssi_statistics=0;
5106 static u32 slide_evm_index=0, slide_evm_statistics=0;
5107 static u32 last_rssi=0, last_evm=0;
5108 //cosa add for rx path selection
5109// static long slide_cck_adc_pwdb_index=0, slide_cck_adc_pwdb_statistics=0;
5110// static char last_cck_adc_pwdb[4]={0,0,0,0};
5111 //cosa add for beacon rssi smoothing
5112 static u32 slide_beacon_adc_pwdb_index=0, slide_beacon_adc_pwdb_statistics=0;
5113 static u32 last_beacon_adc_pwdb=0;
5114
5115 struct ieee80211_hdr_3addr *hdr;
5116 u16 sc ;
5117 unsigned int frag,seq;
5118 hdr = (struct ieee80211_hdr_3addr *)buffer;
5119 sc = le16_to_cpu(hdr->seq_ctl);
5120 frag = WLAN_GET_SEQ_FRAG(sc);
5121 seq = WLAN_GET_SEQ_SEQ(sc);
5122 //cosa add 04292008 to record the sequence number
5123 pcurrent_stats->Seq_Num = seq;
5124 //
5125 // Check whether we should take the previous packet into accounting
5126 //
5127 if(!pprevious_stats->bIsAMPDU)
5128 {
5129 // if previous packet is not aggregated packet
5130 bcheck = true;
5131 }else
5132 {
5133//remve for that we don't use AMPDU to calculate PWDB,because the reported PWDB of some AP is fault.
5134#if 0
5135 // if previous packet is aggregated packet, and current packet
5136 // (1) is not AMPDU
5137 // (2) is the first packet of one AMPDU
5138 // that means the previous packet is the last one aggregated packet
5139 if( !pcurrent_stats->bIsAMPDU || pcurrent_stats->bFirstMPDU)
5140 bcheck = true;
5141#endif
5142 }
5143
5144 if(slide_rssi_statistics++ >= PHY_RSSI_SLID_WIN_MAX)
5145 {
5146 slide_rssi_statistics = PHY_RSSI_SLID_WIN_MAX;
5147 last_rssi = priv->stats.slide_signal_strength[slide_rssi_index];
5148 priv->stats.slide_rssi_total -= last_rssi;
5149 }
5150 priv->stats.slide_rssi_total += pprevious_stats->SignalStrength;
5151
5152 priv->stats.slide_signal_strength[slide_rssi_index++] = pprevious_stats->SignalStrength;
5153 if(slide_rssi_index >= PHY_RSSI_SLID_WIN_MAX)
5154 slide_rssi_index = 0;
5155
5156 // <1> Showed on UI for user, in dbm
5157 tmp_val = priv->stats.slide_rssi_total/slide_rssi_statistics;
5158 priv->stats.signal_strength = rtl819x_translate_todbm((u8)tmp_val);
5159 pcurrent_stats->rssi = priv->stats.signal_strength;
5160 //
5161 // If the previous packet does not match the criteria, neglect it
5162 //
5163 if(!pprevious_stats->bPacketMatchBSSID)
5164 {
5165 if(!pprevious_stats->bToSelfBA)
5166 return;
5167 }
5168
5169 if(!bcheck)
5170 return;
5171
5172 rtl8190_process_cck_rxpathsel(priv,pprevious_stats);
5173
5174 //
5175 // Check RSSI
5176 //
5177 priv->stats.num_process_phyinfo++;
5178#if 0
5179 /* record the general signal strength to the sliding window. */
5180 if(slide_rssi_statistics++ >= PHY_RSSI_SLID_WIN_MAX)
5181 {
5182 slide_rssi_statistics = PHY_RSSI_SLID_WIN_MAX;
5183 last_rssi = priv->stats.slide_signal_strength[slide_rssi_index];
5184 priv->stats.slide_rssi_total -= last_rssi;
5185 }
5186 priv->stats.slide_rssi_total += pprevious_stats->SignalStrength;
5187
5188 priv->stats.slide_signal_strength[slide_rssi_index++] = pprevious_stats->SignalStrength;
5189 if(slide_rssi_index >= PHY_RSSI_SLID_WIN_MAX)
5190 slide_rssi_index = 0;
5191
5192 // <1> Showed on UI for user, in dbm
5193 tmp_val = priv->stats.slide_rssi_total/slide_rssi_statistics;
5194 priv->stats.signal_strength = rtl819x_translate_todbm((u8)tmp_val);
5195
5196#endif
5197 // <2> Showed on UI for engineering
5198 // hardware does not provide rssi information for each rf path in CCK
5199 if(!pprevious_stats->bIsCCK && pprevious_stats->bPacketToSelf)
5200 {
5201 for (rfpath = RF90_PATH_A; rfpath < RF90_PATH_C; rfpath++)
5202 {
5203 if (!rtl8192_phy_CheckIsLegalRFPath(priv->ieee80211->dev, rfpath))
5204 continue;
5205 RT_TRACE(COMP_DBG,"Jacken -> pPreviousstats->RxMIMOSignalStrength[rfpath] = %d \n" ,pprevious_stats->RxMIMOSignalStrength[rfpath] );
5206 //Fixed by Jacken 2008-03-20
5207 if(priv->stats.rx_rssi_percentage[rfpath] == 0)
5208 {
5209 priv->stats.rx_rssi_percentage[rfpath] = pprevious_stats->RxMIMOSignalStrength[rfpath];
5210 //DbgPrint("MIMO RSSI initialize \n");
5211 }
5212 if(pprevious_stats->RxMIMOSignalStrength[rfpath] > priv->stats.rx_rssi_percentage[rfpath])
5213 {
5214 priv->stats.rx_rssi_percentage[rfpath] =
5215 ( (priv->stats.rx_rssi_percentage[rfpath]*(Rx_Smooth_Factor-1)) +
5216 (pprevious_stats->RxMIMOSignalStrength[rfpath])) /(Rx_Smooth_Factor);
5217 priv->stats.rx_rssi_percentage[rfpath] = priv->stats.rx_rssi_percentage[rfpath] + 1;
5218 }
5219 else
5220 {
5221 priv->stats.rx_rssi_percentage[rfpath] =
5222 ( (priv->stats.rx_rssi_percentage[rfpath]*(Rx_Smooth_Factor-1)) +
5223 (pprevious_stats->RxMIMOSignalStrength[rfpath])) /(Rx_Smooth_Factor);
5224 }
5225 RT_TRACE(COMP_DBG,"Jacken -> priv->RxStats.RxRSSIPercentage[rfPath] = %d \n" ,priv->stats.rx_rssi_percentage[rfpath] );
5226 }
5227 }
5228
5229
5230 //
5231 // Check PWDB.
5232 //
5233 //cosa add for beacon rssi smoothing by average.
5234 if(pprevious_stats->bPacketBeacon)
5235 {
5236 /* record the beacon pwdb to the sliding window. */
5237 if(slide_beacon_adc_pwdb_statistics++ >= PHY_Beacon_RSSI_SLID_WIN_MAX)
5238 {
5239 slide_beacon_adc_pwdb_statistics = PHY_Beacon_RSSI_SLID_WIN_MAX;
5240 last_beacon_adc_pwdb = priv->stats.Slide_Beacon_pwdb[slide_beacon_adc_pwdb_index];
5241 priv->stats.Slide_Beacon_Total -= last_beacon_adc_pwdb;
5242 //DbgPrint("slide_beacon_adc_pwdb_index = %d, last_beacon_adc_pwdb = %d, Adapter->RxStats.Slide_Beacon_Total = %d\n",
5243 // slide_beacon_adc_pwdb_index, last_beacon_adc_pwdb, Adapter->RxStats.Slide_Beacon_Total);
5244 }
5245 priv->stats.Slide_Beacon_Total += pprevious_stats->RxPWDBAll;
5246 priv->stats.Slide_Beacon_pwdb[slide_beacon_adc_pwdb_index] = pprevious_stats->RxPWDBAll;
5247 //DbgPrint("slide_beacon_adc_pwdb_index = %d, pPreviousRfd->Status.RxPWDBAll = %d\n", slide_beacon_adc_pwdb_index, pPreviousRfd->Status.RxPWDBAll);
5248 slide_beacon_adc_pwdb_index++;
5249 if(slide_beacon_adc_pwdb_index >= PHY_Beacon_RSSI_SLID_WIN_MAX)
5250 slide_beacon_adc_pwdb_index = 0;
5251 pprevious_stats->RxPWDBAll = priv->stats.Slide_Beacon_Total/slide_beacon_adc_pwdb_statistics;
5252 if(pprevious_stats->RxPWDBAll >= 3)
5253 pprevious_stats->RxPWDBAll -= 3;
5254 }
5255
5256 RT_TRACE(COMP_RXDESC, "Smooth %s PWDB = %d\n",
5257 pprevious_stats->bIsCCK? "CCK": "OFDM",
5258 pprevious_stats->RxPWDBAll);
5259
5260 if(pprevious_stats->bPacketToSelf || pprevious_stats->bPacketBeacon || pprevious_stats->bToSelfBA)
5261 {
5262 if(priv->undecorated_smoothed_pwdb < 0) // initialize
5263 {
5264 priv->undecorated_smoothed_pwdb = pprevious_stats->RxPWDBAll;
5265 //DbgPrint("First pwdb initialize \n");
5266 }
5267#if 1
5268 if(pprevious_stats->RxPWDBAll > (u32)priv->undecorated_smoothed_pwdb)
5269 {
5270 priv->undecorated_smoothed_pwdb =
5271 ( ((priv->undecorated_smoothed_pwdb)*(Rx_Smooth_Factor-1)) +
5272 (pprevious_stats->RxPWDBAll)) /(Rx_Smooth_Factor);
5273 priv->undecorated_smoothed_pwdb = priv->undecorated_smoothed_pwdb + 1;
5274 }
5275 else
5276 {
5277 priv->undecorated_smoothed_pwdb =
5278 ( ((priv->undecorated_smoothed_pwdb)*(Rx_Smooth_Factor-1)) +
5279 (pprevious_stats->RxPWDBAll)) /(Rx_Smooth_Factor);
5280 }
5281#else
5282 //Fixed by Jacken 2008-03-20
5283 if(pPreviousRfd->Status.RxPWDBAll > (u32)pHalData->UndecoratedSmoothedPWDB)
5284 {
5285 pHalData->UndecoratedSmoothedPWDB =
5286 ( ((pHalData->UndecoratedSmoothedPWDB)* 5) + (pPreviousRfd->Status.RxPWDBAll)) / 6;
5287 pHalData->UndecoratedSmoothedPWDB = pHalData->UndecoratedSmoothedPWDB + 1;
5288 }
5289 else
5290 {
5291 pHalData->UndecoratedSmoothedPWDB =
5292 ( ((pHalData->UndecoratedSmoothedPWDB)* 5) + (pPreviousRfd->Status.RxPWDBAll)) / 6;
5293 }
5294#endif
5295 rtl819x_update_rxsignalstatistics8190pci(priv,pprevious_stats);
5296 }
5297
5298 //
5299 // Check EVM
5300 //
5301 /* record the general EVM to the sliding window. */
5302 if(pprevious_stats->SignalQuality == 0)
5303 {
5304 }
5305 else
5306 {
5307 if(pprevious_stats->bPacketToSelf || pprevious_stats->bPacketBeacon || pprevious_stats->bToSelfBA){
5308 if(slide_evm_statistics++ >= PHY_RSSI_SLID_WIN_MAX){
5309 slide_evm_statistics = PHY_RSSI_SLID_WIN_MAX;
5310 last_evm = priv->stats.slide_evm[slide_evm_index];
5311 priv->stats.slide_evm_total -= last_evm;
5312 }
5313
5314 priv->stats.slide_evm_total += pprevious_stats->SignalQuality;
5315
5316 priv->stats.slide_evm[slide_evm_index++] = pprevious_stats->SignalQuality;
5317 if(slide_evm_index >= PHY_RSSI_SLID_WIN_MAX)
5318 slide_evm_index = 0;
5319
5320 // <1> Showed on UI for user, in percentage.
5321 tmp_val = priv->stats.slide_evm_total/slide_evm_statistics;
5322 priv->stats.signal_quality = tmp_val;
5323 //cosa add 10/11/2007, Showed on UI for user in Windows Vista, for Link quality.
5324 priv->stats.last_signal_strength_inpercent = tmp_val;
5325 }
5326
5327 // <2> Showed on UI for engineering
5328 if(pprevious_stats->bPacketToSelf || pprevious_stats->bPacketBeacon || pprevious_stats->bToSelfBA)
5329 {
5330 for(nspatial_stream = 0; nspatial_stream<2 ; nspatial_stream++) // 2 spatial stream
5331 {
5332 if(pprevious_stats->RxMIMOSignalQuality[nspatial_stream] != -1)
5333 {
5334 if(priv->stats.rx_evm_percentage[nspatial_stream] == 0) // initialize
5335 {
5336 priv->stats.rx_evm_percentage[nspatial_stream] = pprevious_stats->RxMIMOSignalQuality[nspatial_stream];
5337 }
5338 priv->stats.rx_evm_percentage[nspatial_stream] =
5339 ( (priv->stats.rx_evm_percentage[nspatial_stream]* (Rx_Smooth_Factor-1)) +
5340 (pprevious_stats->RxMIMOSignalQuality[nspatial_stream]* 1)) / (Rx_Smooth_Factor);
5341 }
5342 }
5343 }
5344 }
5345
5346}
5347
ecdfa446
GKH
5348static u8 rtl819x_query_rxpwrpercentage(
5349 char antpower
5350 )
5351{
5352 if ((antpower <= -100) || (antpower >= 20))
5353 {
5354 return 0;
5355 }
5356 else if (antpower >= 0)
5357 {
5358 return 100;
5359 }
5360 else
5361 {
5362 return (100+antpower);
5363 }
5364
d5abdf72 5365}
ecdfa446
GKH
5366
5367static u8
5368rtl819x_evm_dbtopercentage(
5369 char value
5370 )
5371{
5372 char ret_val;
5373
5374 ret_val = value;
5375
5376 if(ret_val >= 0)
5377 ret_val = 0;
5378 if(ret_val <= -33)
5379 ret_val = -33;
5380 ret_val = 0 - ret_val;
5381 ret_val*=3;
5382 if(ret_val == 99)
5383 ret_val = 100;
c6eae677 5384 return ret_val;
ecdfa446
GKH
5385}
5386
214985a6 5387/* We want good-looking for signal strength/quality */
5e1ad18a 5388static long rtl819x_signal_scale_mapping(long currsig)
ecdfa446
GKH
5389{
5390 long retsig;
5391
5392 // Step 1. Scale mapping.
5393 if(currsig >= 61 && currsig <= 100)
5394 {
5395 retsig = 90 + ((currsig - 60) / 4);
5396 }
5397 else if(currsig >= 41 && currsig <= 60)
5398 {
5399 retsig = 78 + ((currsig - 40) / 2);
5400 }
5401 else if(currsig >= 31 && currsig <= 40)
5402 {
5403 retsig = 66 + (currsig - 30);
5404 }
5405 else if(currsig >= 21 && currsig <= 30)
5406 {
5407 retsig = 54 + (currsig - 20);
5408 }
5409 else if(currsig >= 5 && currsig <= 20)
5410 {
5411 retsig = 42 + (((currsig - 5) * 2) / 3);
5412 }
5413 else if(currsig == 4)
5414 {
5415 retsig = 36;
5416 }
5417 else if(currsig == 3)
5418 {
5419 retsig = 27;
5420 }
5421 else if(currsig == 2)
5422 {
5423 retsig = 18;
5424 }
5425 else if(currsig == 1)
5426 {
5427 retsig = 9;
5428 }
5429 else
5430 {
5431 retsig = currsig;
5432 }
5433
5434 return retsig;
5435}
5436
5437static void rtl8192_query_rxphystatus(
5438 struct r8192_priv * priv,
5439 struct ieee80211_rx_stats * pstats,
5440 prx_desc_819x_pci pdesc,
5441 prx_fwinfo_819x_pci pdrvinfo,
5442 struct ieee80211_rx_stats * precord_stats,
5443 bool bpacket_match_bssid,
5444 bool bpacket_toself,
5445 bool bPacketBeacon,
5446 bool bToSelfBA
5447 )
5448{
5449 //PRT_RFD_STATUS pRtRfdStatus = &(pRfd->Status);
5450 phy_sts_ofdm_819xpci_t* pofdm_buf;
5451 phy_sts_cck_819xpci_t * pcck_buf;
5452 phy_ofdm_rx_status_rxsc_sgien_exintfflag* prxsc;
5453 u8 *prxpkt;
5454 u8 i,max_spatial_stream, tmp_rxsnr, tmp_rxevm, rxsc_sgien_exflg;
5455 char rx_pwr[4], rx_pwr_all=0;
5456 //long rx_avg_pwr = 0;
5457 char rx_snrX, rx_evmX;
5458 u8 evm, pwdb_all;
5459 u32 RSSI, total_rssi=0;//, total_evm=0;
5460// long signal_strength_index = 0;
5461 u8 is_cck_rate=0;
5462 u8 rf_rx_num = 0;
5463
5464 /* 2007/07/04 MH For OFDM RSSI. For high power or not. */
5465 static u8 check_reg824 = 0;
5466 static u32 reg824_bit9 = 0;
5467
5468 priv->stats.numqry_phystatus++;
5469
5470 is_cck_rate = rx_hal_is_cck_rate(pdrvinfo);
5471
5472 // Record it for next packet processing
5473 memset(precord_stats, 0, sizeof(struct ieee80211_rx_stats));
5474 pstats->bPacketMatchBSSID = precord_stats->bPacketMatchBSSID = bpacket_match_bssid;
5475 pstats->bPacketToSelf = precord_stats->bPacketToSelf = bpacket_toself;
5476 pstats->bIsCCK = precord_stats->bIsCCK = is_cck_rate;//RX_HAL_IS_CCK_RATE(pDrvInfo);
5477 pstats->bPacketBeacon = precord_stats->bPacketBeacon = bPacketBeacon;
5478 pstats->bToSelfBA = precord_stats->bToSelfBA = bToSelfBA;
5479 /*2007.08.30 requested by SD3 Jerry */
5480 if(check_reg824 == 0)
5481 {
5482 reg824_bit9 = rtl8192_QueryBBReg(priv->ieee80211->dev, rFPGA0_XA_HSSIParameter2, 0x200);
5483 check_reg824 = 1;
5484 }
5485
5486
5487 prxpkt = (u8*)pdrvinfo;
5488
5489 /* Move pointer to the 16th bytes. Phy status start address. */
5490 prxpkt += sizeof(rx_fwinfo_819x_pci);
5491
5492 /* Initial the cck and ofdm buffer pointer */
5493 pcck_buf = (phy_sts_cck_819xpci_t *)prxpkt;
5494 pofdm_buf = (phy_sts_ofdm_819xpci_t *)prxpkt;
5495
5496 pstats->RxMIMOSignalQuality[0] = -1;
5497 pstats->RxMIMOSignalQuality[1] = -1;
5498 precord_stats->RxMIMOSignalQuality[0] = -1;
5499 precord_stats->RxMIMOSignalQuality[1] = -1;
5500
5501 if(is_cck_rate)
5502 {
5503 //
5504 // (1)Hardware does not provide RSSI for CCK
5505 //
5506
5507 //
5508 // (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive)
5509 //
5510 u8 report;//, cck_agc_rpt;
5511#ifdef RTL8190P
5512 u8 tmp_pwdb;
5513 char cck_adc_pwdb[4];
5514#endif
5515 priv->stats.numqry_phystatusCCK++;
5516
5517#ifdef RTL8190P //Only 90P 2T4R need to check
5518 if(priv->rf_type == RF_2T4R && DM_RxPathSelTable.Enable && bpacket_match_bssid)
5519 {
5520 for(i=RF90_PATH_A; i<RF90_PATH_MAX; i++)
5521 {
5522 tmp_pwdb = pcck_buf->adc_pwdb_X[i];
5523 cck_adc_pwdb[i] = (char)tmp_pwdb;
5524 cck_adc_pwdb[i] /= 2;
5525 pstats->cck_adc_pwdb[i] = precord_stats->cck_adc_pwdb[i] = cck_adc_pwdb[i];
5526 //DbgPrint("RF-%d tmp_pwdb = 0x%x, cck_adc_pwdb = %d", i, tmp_pwdb, cck_adc_pwdb[i]);
5527 }
5528 }
5529#endif
5530
5531 if(!reg824_bit9)
5532 {
5533 report = pcck_buf->cck_agc_rpt & 0xc0;
5534 report = report>>6;
5535 switch(report)
5536 {
5537 //Fixed by Jacken from Bryant 2008-03-20
5538 //Original value is -38 , -26 , -14 , -2
5539 //Fixed value is -35 , -23 , -11 , 6
5540 case 0x3:
5541 rx_pwr_all = -35 - (pcck_buf->cck_agc_rpt & 0x3e);
5542 break;
5543 case 0x2:
5544 rx_pwr_all = -23 - (pcck_buf->cck_agc_rpt & 0x3e);
5545 break;
5546 case 0x1:
5547 rx_pwr_all = -11 - (pcck_buf->cck_agc_rpt & 0x3e);
5548 break;
5549 case 0x0:
5550 rx_pwr_all = 8 - (pcck_buf->cck_agc_rpt & 0x3e);
5551 break;
5552 }
5553 }
5554 else
5555 {
5556 report = pcck_buf->cck_agc_rpt & 0x60;
5557 report = report>>5;
5558 switch(report)
5559 {
5560 case 0x3:
5561 rx_pwr_all = -35 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1) ;
5562 break;
5563 case 0x2:
5564 rx_pwr_all = -23 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1);
5565 break;
5566 case 0x1:
5567 rx_pwr_all = -11 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1) ;
5568 break;
5569 case 0x0:
5570 rx_pwr_all = -8 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1) ;
5571 break;
5572 }
5573 }
5574
5575 pwdb_all = rtl819x_query_rxpwrpercentage(rx_pwr_all);
5576 pstats->RxPWDBAll = precord_stats->RxPWDBAll = pwdb_all;
5577 pstats->RecvSignalPower = rx_pwr_all;
5578
5579 //
5580 // (3) Get Signal Quality (EVM)
5581 //
5582 if(bpacket_match_bssid)
5583 {
5584 u8 sq;
5585
5586 if(pstats->RxPWDBAll > 40)
5587 {
5588 sq = 100;
5589 }else
5590 {
5591 sq = pcck_buf->sq_rpt;
5592
5593 if(pcck_buf->sq_rpt > 64)
5594 sq = 0;
5595 else if (pcck_buf->sq_rpt < 20)
5596 sq = 100;
5597 else
5598 sq = ((64-sq) * 100) / 44;
5599 }
5600 pstats->SignalQuality = precord_stats->SignalQuality = sq;
5601 pstats->RxMIMOSignalQuality[0] = precord_stats->RxMIMOSignalQuality[0] = sq;
5602 pstats->RxMIMOSignalQuality[1] = precord_stats->RxMIMOSignalQuality[1] = -1;
5603 }
5604 }
5605 else
5606 {
5607 priv->stats.numqry_phystatusHT++;
5608 //
5609 // (1)Get RSSI for HT rate
5610 //
5611 for(i=RF90_PATH_A; i<RF90_PATH_MAX; i++)
5612 {
5613 // 2008/01/30 MH we will judge RF RX path now.
5614 if (priv->brfpath_rxenable[i])
5615 rf_rx_num++;
5616 //else
5617 //continue;
5618
5619 //Fixed by Jacken from Bryant 2008-03-20
5620 //Original value is 106
5621#ifdef RTL8190P //Modify by Jacken 2008/03/31
5622 rx_pwr[i] = ((pofdm_buf->trsw_gain_X[i]&0x3F)*2) - 106;
5623#else
5624 rx_pwr[i] = ((pofdm_buf->trsw_gain_X[i]&0x3F)*2) - 110;
5625#endif
5626
5627 //Get Rx snr value in DB
5628 tmp_rxsnr = pofdm_buf->rxsnr_X[i];
5629 rx_snrX = (char)(tmp_rxsnr);
5630 rx_snrX /= 2;
5631 priv->stats.rxSNRdB[i] = (long)rx_snrX;
5632
5633 /* Translate DBM to percentage. */
5634 RSSI = rtl819x_query_rxpwrpercentage(rx_pwr[i]);
5635 if (priv->brfpath_rxenable[i])
5636 total_rssi += RSSI;
5637
5638 /* Record Signal Strength for next packet */
5639 if(bpacket_match_bssid)
5640 {
5641 pstats->RxMIMOSignalStrength[i] =(u8) RSSI;
5642 precord_stats->RxMIMOSignalStrength[i] =(u8) RSSI;
5643 }
5644 }
5645
5646
5647 //
5648 // (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive)
5649 //
5650 //Fixed by Jacken from Bryant 2008-03-20
5651 //Original value is 106
5652 rx_pwr_all = (((pofdm_buf->pwdb_all ) >> 1 )& 0x7f) -106;
5653 pwdb_all = rtl819x_query_rxpwrpercentage(rx_pwr_all);
5654
5655 pstats->RxPWDBAll = precord_stats->RxPWDBAll = pwdb_all;
5656 pstats->RxPower = precord_stats->RxPower = rx_pwr_all;
5657 pstats->RecvSignalPower = rx_pwr_all;
5658 //
5659 // (3)EVM of HT rate
5660 //
5661 if(pdrvinfo->RxHT && pdrvinfo->RxRate>=DESC90_RATEMCS8 &&
5662 pdrvinfo->RxRate<=DESC90_RATEMCS15)
5663 max_spatial_stream = 2; //both spatial stream make sense
5664 else
5665 max_spatial_stream = 1; //only spatial stream 1 makes sense
5666
5667 for(i=0; i<max_spatial_stream; i++)
5668 {
5669 tmp_rxevm = pofdm_buf->rxevm_X[i];
5670 rx_evmX = (char)(tmp_rxevm);
5671
5672 // Do not use shift operation like "rx_evmX >>= 1" because the compilor of free build environment
5673 // fill most significant bit to "zero" when doing shifting operation which may change a negative
5674 // value to positive one, then the dbm value (which is supposed to be negative) is not correct anymore.
5675 rx_evmX /= 2; //dbm
5676
5677 evm = rtl819x_evm_dbtopercentage(rx_evmX);
5678#if 0
5679 EVM = SignalScaleMapping(EVM);//make it good looking, from 0~100
5680#endif
5681 if(bpacket_match_bssid)
5682 {
5683 if(i==0) // Fill value in RFD, Get the first spatial stream only
5684 pstats->SignalQuality = precord_stats->SignalQuality = (u8)(evm & 0xff);
5685 pstats->RxMIMOSignalQuality[i] = precord_stats->RxMIMOSignalQuality[i] = (u8)(evm & 0xff);
5686 }
5687 }
5688
5689
5690 /* record rx statistics for debug */
5691 rxsc_sgien_exflg = pofdm_buf->rxsc_sgien_exflg;
5692 prxsc = (phy_ofdm_rx_status_rxsc_sgien_exintfflag *)&rxsc_sgien_exflg;
5693 if(pdrvinfo->BW) //40M channel
5694 priv->stats.received_bwtype[1+prxsc->rxsc]++;
5695 else //20M channel
5696 priv->stats.received_bwtype[0]++;
5697 }
5698
5699 //UI BSS List signal strength(in percentage), make it good looking, from 0~100.
5700 //It is assigned to the BSS List in GetValueFromBeaconOrProbeRsp().
5701 if(is_cck_rate)
5702 {
5703 pstats->SignalStrength = precord_stats->SignalStrength = (u8)(rtl819x_signal_scale_mapping((long)pwdb_all));//PWDB_ALL;
5704
5705 }
5706 else
5707 {
5708 //pRfd->Status.SignalStrength = pRecordRfd->Status.SignalStrength = (u1Byte)(SignalScaleMapping(total_rssi/=RF90_PATH_MAX));//(u1Byte)(total_rssi/=RF90_PATH_MAX);
5709 // We can judge RX path number now.
5710 if (rf_rx_num != 0)
5711 pstats->SignalStrength = precord_stats->SignalStrength = (u8)(rtl819x_signal_scale_mapping((long)(total_rssi/=rf_rx_num)));
5712 }
d5abdf72 5713}
ecdfa446 5714
5e1ad18a 5715static void
ecdfa446
GKH
5716rtl8192_record_rxdesc_forlateruse(
5717 struct ieee80211_rx_stats * psrc_stats,
5718 struct ieee80211_rx_stats * ptarget_stats
5719)
5720{
5721 ptarget_stats->bIsAMPDU = psrc_stats->bIsAMPDU;
5722 ptarget_stats->bFirstMPDU = psrc_stats->bFirstMPDU;
5723 //ptarget_stats->Seq_Num = psrc_stats->Seq_Num;
5724}
5725
5726
5727
5e1ad18a 5728static void TranslateRxSignalStuff819xpci(struct net_device *dev,
ecdfa446
GKH
5729 struct sk_buff *skb,
5730 struct ieee80211_rx_stats * pstats,
5731 prx_desc_819x_pci pdesc,
5732 prx_fwinfo_819x_pci pdrvinfo)
5733{
5734 // TODO: We must only check packet for current MAC address. Not finish
5735 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
5736 bool bpacket_match_bssid, bpacket_toself;
5737 bool bPacketBeacon=false, bToSelfBA=false;
5738 static struct ieee80211_rx_stats previous_stats;
5739 struct ieee80211_hdr_3addr *hdr;
5740 u16 fc,type;
5741
5742 // Get Signal Quality for only RX data queue (but not command queue)
5743
5744 u8* tmp_buf;
5745 u8 *praddr;
5746
5747 /* Get MAC frame start address. */
5748 tmp_buf = skb->data;
5749
5750 hdr = (struct ieee80211_hdr_3addr *)tmp_buf;
5751 fc = le16_to_cpu(hdr->frame_ctl);
5752 type = WLAN_FC_GET_TYPE(fc);
5753 praddr = hdr->addr1;
5754
5755 /* Check if the received packet is acceptabe. */
5756 bpacket_match_bssid = ((IEEE80211_FTYPE_CTL != type) &&
5757 (eqMacAddr(priv->ieee80211->current_network.bssid, (fc & IEEE80211_FCTL_TODS)? hdr->addr1 : (fc & IEEE80211_FCTL_FROMDS )? hdr->addr2 : hdr->addr3))
5758 && (!pstats->bHwError) && (!pstats->bCRC)&& (!pstats->bICV));
5759 bpacket_toself = bpacket_match_bssid & (eqMacAddr(praddr, priv->ieee80211->dev->dev_addr));
5760#if 1//cosa
5761 if(WLAN_FC_GET_FRAMETYPE(fc)== IEEE80211_STYPE_BEACON)
5762 {
5763 bPacketBeacon = true;
5764 //DbgPrint("Beacon 2, MatchBSSID = %d, ToSelf = %d \n", bPacketMatchBSSID, bPacketToSelf);
5765 }
5766 if(WLAN_FC_GET_FRAMETYPE(fc) == IEEE80211_STYPE_BLOCKACK)
5767 {
5768 if((eqMacAddr(praddr,dev->dev_addr)))
5769 bToSelfBA = true;
5770 //DbgPrint("BlockAck, MatchBSSID = %d, ToSelf = %d \n", bPacketMatchBSSID, bPacketToSelf);
5771 }
5772
5773#endif
5774 if(bpacket_match_bssid)
5775 {
5776 priv->stats.numpacket_matchbssid++;
5777 }
5778 if(bpacket_toself){
5779 priv->stats.numpacket_toself++;
5780 }
5781 //
5782 // Process PHY information for previous packet (RSSI/PWDB/EVM)
5783 //
5784 // Because phy information is contained in the last packet of AMPDU only, so driver
5785 // should process phy information of previous packet
5786 rtl8192_process_phyinfo(priv, tmp_buf,&previous_stats, pstats);
5787 rtl8192_query_rxphystatus(priv, pstats, pdesc, pdrvinfo, &previous_stats, bpacket_match_bssid,
5788 bpacket_toself ,bPacketBeacon, bToSelfBA);
5789 rtl8192_record_rxdesc_forlateruse(pstats, &previous_stats);
5790
5791}
5792
5793
5e1ad18a 5794static void rtl8192_tx_resume(struct net_device *dev)
ecdfa446
GKH
5795{
5796 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
5797 struct ieee80211_device *ieee = priv->ieee80211;
5798 struct sk_buff *skb;
5799 int queue_index;
5800
5801 for(queue_index = BK_QUEUE; queue_index < TXCMD_QUEUE;queue_index++) {
5802 while((!skb_queue_empty(&ieee->skb_waitQ[queue_index]))&&
5803 (priv->ieee80211->check_nic_enough_desc(dev,queue_index) > 0)) {
5804 /* 1. dequeue the packet from the wait queue */
5805 skb = skb_dequeue(&ieee->skb_waitQ[queue_index]);
5806 /* 2. tx the packet directly */
5807 ieee->softmac_data_hard_start_xmit(skb,dev,0/* rate useless now*/);
5808 #if 0
5809 if(queue_index!=MGNT_QUEUE) {
5810 ieee->stats.tx_packets++;
5811 ieee->stats.tx_bytes += skb->len;
5812 }
5813 #endif
5814 }
5815 }
5816}
5817
559fba5e 5818static void rtl8192_irq_tx_tasklet(struct r8192_priv *priv)
ecdfa446
GKH
5819{
5820 rtl8192_tx_resume(priv->ieee80211->dev);
5821}
5822
214985a6 5823/* Record the received data rate */
5e1ad18a 5824static void UpdateReceivedRateHistogramStatistics8190(
ecdfa446
GKH
5825 struct net_device *dev,
5826 struct ieee80211_rx_stats* pstats
5827 )
5828{
5829 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
5830 u32 rcvType=1; //0: Total, 1:OK, 2:CRC, 3:ICV
5831 u32 rateIndex;
5832 u32 preamble_guardinterval; //1: short preamble/GI, 0: long preamble/GI
5833
ecdfa446
GKH
5834 if(pstats->bCRC)
5835 rcvType = 2;
5836 else if(pstats->bICV)
5837 rcvType = 3;
5838
5839 if(pstats->bShortPreamble)
5840 preamble_guardinterval = 1;// short
5841 else
5842 preamble_guardinterval = 0;// long
5843
5844 switch(pstats->rate)
5845 {
5846 //
5847 // CCK rate
5848 //
5849 case MGN_1M: rateIndex = 0; break;
5850 case MGN_2M: rateIndex = 1; break;
5851 case MGN_5_5M: rateIndex = 2; break;
5852 case MGN_11M: rateIndex = 3; break;
5853 //
5854 // Legacy OFDM rate
5855 //
5856 case MGN_6M: rateIndex = 4; break;
5857 case MGN_9M: rateIndex = 5; break;
5858 case MGN_12M: rateIndex = 6; break;
5859 case MGN_18M: rateIndex = 7; break;
5860 case MGN_24M: rateIndex = 8; break;
5861 case MGN_36M: rateIndex = 9; break;
5862 case MGN_48M: rateIndex = 10; break;
5863 case MGN_54M: rateIndex = 11; break;
5864 //
5865 // 11n High throughput rate
5866 //
5867 case MGN_MCS0: rateIndex = 12; break;
5868 case MGN_MCS1: rateIndex = 13; break;
5869 case MGN_MCS2: rateIndex = 14; break;
5870 case MGN_MCS3: rateIndex = 15; break;
5871 case MGN_MCS4: rateIndex = 16; break;
5872 case MGN_MCS5: rateIndex = 17; break;
5873 case MGN_MCS6: rateIndex = 18; break;
5874 case MGN_MCS7: rateIndex = 19; break;
5875 case MGN_MCS8: rateIndex = 20; break;
5876 case MGN_MCS9: rateIndex = 21; break;
5877 case MGN_MCS10: rateIndex = 22; break;
5878 case MGN_MCS11: rateIndex = 23; break;
5879 case MGN_MCS12: rateIndex = 24; break;
5880 case MGN_MCS13: rateIndex = 25; break;
5881 case MGN_MCS14: rateIndex = 26; break;
5882 case MGN_MCS15: rateIndex = 27; break;
5883 default: rateIndex = 28; break;
5884 }
5885 priv->stats.received_preamble_GI[preamble_guardinterval][rateIndex]++;
5886 priv->stats.received_rate_histogram[0][rateIndex]++; //total
5887 priv->stats.received_rate_histogram[rcvType][rateIndex]++;
5888}
5889
5e1ad18a 5890static void rtl8192_rx(struct net_device *dev)
ecdfa446
GKH
5891{
5892 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
5893 struct ieee80211_hdr_1addr *ieee80211_hdr = NULL;
5894 bool unicast_packet = false;
5895 struct ieee80211_rx_stats stats = {
5896 .signal = 0,
5897 .noise = -98,
5898 .rate = 0,
5899 .freq = IEEE80211_24GHZ_BAND,
5900 };
5901 unsigned int count = priv->rxringcount;
5902
5903 stats.nic_type = NIC_8192E;
5904
5905 while (count--) {
5906 rx_desc_819x_pci *pdesc = &priv->rx_ring[priv->rx_idx];//rx descriptor
5907 struct sk_buff *skb = priv->rx_buf[priv->rx_idx];//rx pkt
5908
5909 if (pdesc->OWN){
5910 /* wait data to be filled by hardware */
5911 return;
5912 } else {
5913 stats.bICV = pdesc->ICV;
5914 stats.bCRC = pdesc->CRC32;
5915 stats.bHwError = pdesc->CRC32 | pdesc->ICV;
5916
5917 stats.Length = pdesc->Length;
5918 if(stats.Length < 24)
5919 stats.bHwError |= 1;
5920
5921 if(stats.bHwError) {
5922 stats.bShift = false;
5923
5924 if(pdesc->CRC32) {
5925 if (pdesc->Length <500)
5926 priv->stats.rxcrcerrmin++;
5927 else if (pdesc->Length >1000)
5928 priv->stats.rxcrcerrmax++;
5929 else
5930 priv->stats.rxcrcerrmid++;
5931 }
5932 goto done;
5933 } else {
5934 prx_fwinfo_819x_pci pDrvInfo = NULL;
5935 struct sk_buff *new_skb = dev_alloc_skb(priv->rxbuffersize);
5936
5937 if (unlikely(!new_skb)) {
5938 goto done;
5939 }
5940
5941 stats.RxDrvInfoSize = pdesc->RxDrvInfoSize;
5942 stats.RxBufShift = ((pdesc->Shift)&0x03);
5943 stats.Decrypted = !pdesc->SWDec;
5944
ecdfa446 5945 pci_dma_sync_single_for_cpu(priv->pdev,
ecdfa446
GKH
5946 *((dma_addr_t *)skb->cb),
5947 priv->rxbuffersize,
5948 PCI_DMA_FROMDEVICE);
5949 skb_put(skb, pdesc->Length);
5950 pDrvInfo = (rx_fwinfo_819x_pci *)(skb->data + stats.RxBufShift);
5951 skb_reserve(skb, stats.RxDrvInfoSize + stats.RxBufShift);
5952
5953 stats.rate = HwRateToMRate90((bool)pDrvInfo->RxHT, (u8)pDrvInfo->RxRate);
5954 stats.bShortPreamble = pDrvInfo->SPLCP;
5955
5956 /* it is debug only. It should be disabled in released driver.
5957 * 2007.1.11 by Emily
5958 * */
5959 UpdateReceivedRateHistogramStatistics8190(dev, &stats);
5960
5961 stats.bIsAMPDU = (pDrvInfo->PartAggr==1);
5962 stats.bFirstMPDU = (pDrvInfo->PartAggr==1) && (pDrvInfo->FirstAGGR==1);
5963
5964 stats.TimeStampLow = pDrvInfo->TSFL;
5965 stats.TimeStampHigh = read_nic_dword(dev, TSFR+4);
5966
5967 UpdateRxPktTimeStamp8190(dev, &stats);
5968
5969 //
5970 // Get Total offset of MPDU Frame Body
5971 //
5972 if((stats.RxBufShift + stats.RxDrvInfoSize) > 0)
5973 stats.bShift = 1;
5974
5975 stats.RxIs40MHzPacket = pDrvInfo->BW;
5976
5977 /* ???? */
5978 TranslateRxSignalStuff819xpci(dev,skb, &stats, pdesc, pDrvInfo);
5979
5980 /* Rx A-MPDU */
5981 if(pDrvInfo->FirstAGGR==1 || pDrvInfo->PartAggr == 1)
5982 RT_TRACE(COMP_RXDESC, "pDrvInfo->FirstAGGR = %d, pDrvInfo->PartAggr = %d\n",
5983 pDrvInfo->FirstAGGR, pDrvInfo->PartAggr);
5984 skb_trim(skb, skb->len - 4/*sCrcLng*/);
5985 /* rx packets statistics */
5986 ieee80211_hdr = (struct ieee80211_hdr_1addr *)skb->data;
5987 unicast_packet = false;
5988
5989 if(is_broadcast_ether_addr(ieee80211_hdr->addr1)) {
5990 //TODO
5991 }else if(is_multicast_ether_addr(ieee80211_hdr->addr1)){
5992 //TODO
5993 }else {
5994 /* unicast packet */
5995 unicast_packet = true;
5996 }
5997
5998 stats.packetlength = stats.Length-4;
5999 stats.fraglength = stats.packetlength;
6000 stats.fragoffset = 0;
6001 stats.ntotalfrag = 1;
6002
fb5fe277 6003 if(!ieee80211_rtl_rx(priv->ieee80211, skb, &stats)){
ecdfa446
GKH
6004 dev_kfree_skb_any(skb);
6005 } else {
6006 priv->stats.rxok++;
6007 if(unicast_packet) {
6008 priv->stats.rxbytesunicast += skb->len;
6009 }
6010 }
6011
6012 skb = new_skb;
6013 priv->rx_buf[priv->rx_idx] = skb;
1c7ec2e8 6014 *((dma_addr_t *) skb->cb) = pci_map_single(priv->pdev, skb_tail_pointer(skb), priv->rxbuffersize, PCI_DMA_FROMDEVICE);
ecdfa446
GKH
6015 }
6016
6017 }
6018done:
6019 pdesc->BufferAddress = cpu_to_le32(*((dma_addr_t *)skb->cb));
6020 pdesc->OWN = 1;
6021 pdesc->Length = priv->rxbuffersize;
6022 if (priv->rx_idx == priv->rxringcount-1)
6023 pdesc->EOR = 1;
6024 priv->rx_idx = (priv->rx_idx + 1) % priv->rxringcount;
6025 }
6026
6027}
6028
559fba5e 6029static void rtl8192_irq_rx_tasklet(struct r8192_priv *priv)
ecdfa446
GKH
6030{
6031 rtl8192_rx(priv->ieee80211->dev);
6032 /* unmask RDU */
6033 write_nic_dword(priv->ieee80211->dev, INTA_MASK,read_nic_dword(priv->ieee80211->dev, INTA_MASK) | IMR_RDU);
6034}
6035
6036static const struct net_device_ops rtl8192_netdev_ops = {
6037 .ndo_open = rtl8192_open,
6038 .ndo_stop = rtl8192_close,
ecdfa446
GKH
6039 .ndo_tx_timeout = tx_timeout,
6040 .ndo_do_ioctl = rtl8192_ioctl,
6041 .ndo_set_multicast_list = r8192_set_multicast,
6042 .ndo_set_mac_address = r8192_set_mac_adr,
fb5fe277 6043 .ndo_start_xmit = ieee80211_rtl_xmit,
ecdfa446
GKH
6044};
6045
ecdfa446
GKH
6046static int __devinit rtl8192_pci_probe(struct pci_dev *pdev,
6047 const struct pci_device_id *id)
6048{
6049 unsigned long ioaddr = 0;
6050 struct net_device *dev = NULL;
6051 struct r8192_priv *priv= NULL;
6052 u8 unit = 0;
3a8f2d3c 6053 int ret = -ENODEV;
ecdfa446
GKH
6054
6055#ifdef CONFIG_RTL8192_IO_MAP
6056 unsigned long pio_start, pio_len, pio_flags;
6057#else
6058 unsigned long pmem_start, pmem_len, pmem_flags;
6059#endif //end #ifdef RTL_IO_MAP
6060
6061 RT_TRACE(COMP_INIT,"Configuring chip resources");
6062
6063 if( pci_enable_device (pdev) ){
6064 RT_TRACE(COMP_ERR,"Failed to enable PCI device");
6065 return -EIO;
6066 }
6067
6068 pci_set_master(pdev);
6069 //pci_set_wmi(pdev);
6070 pci_set_dma_mask(pdev, 0xffffff00ULL);
ecdfa446 6071 pci_set_consistent_dma_mask(pdev,0xffffff00ULL);
ecdfa446 6072 dev = alloc_ieee80211(sizeof(struct r8192_priv));
3a8f2d3c
KV
6073 if (!dev) {
6074 ret = -ENOMEM;
6075 goto fail_free;
6076 }
ecdfa446 6077
ecdfa446 6078 pci_set_drvdata(pdev, dev);
ecdfa446 6079 SET_NETDEV_DEV(dev, &pdev->dev);
ecdfa446 6080 priv = ieee80211_priv(dev);
ecdfa446 6081 priv->ieee80211 = netdev_priv(dev);
ecdfa446 6082 priv->pdev=pdev;
ecdfa446
GKH
6083 if((pdev->subsystem_vendor == PCI_VENDOR_ID_DLINK)&&(pdev->subsystem_device == 0x3304)){
6084 priv->ieee80211->bSupportRemoteWakeUp = 1;
6085 } else
ecdfa446
GKH
6086 {
6087 priv->ieee80211->bSupportRemoteWakeUp = 0;
6088 }
6089
6090#ifdef CONFIG_RTL8192_IO_MAP
6091
6092 pio_start = (unsigned long)pci_resource_start (pdev, 0);
6093 pio_len = (unsigned long)pci_resource_len (pdev, 0);
6094 pio_flags = (unsigned long)pci_resource_flags (pdev, 0);
6095
6096 if (!(pio_flags & IORESOURCE_IO)) {
6097 RT_TRACE(COMP_ERR,"region #0 not a PIO resource, aborting");
6098 goto fail;
6099 }
6100
6101 //DMESG("IO space @ 0x%08lx", pio_start );
6102 if( ! request_region( pio_start, pio_len, RTL819xE_MODULE_NAME ) ){
6103 RT_TRACE(COMP_ERR,"request_region failed!");
6104 goto fail;
6105 }
6106
6107 ioaddr = pio_start;
6108 dev->base_addr = ioaddr; // device I/O address
6109
6110#else
6111
6112 pmem_start = pci_resource_start(pdev, 1);
6113 pmem_len = pci_resource_len(pdev, 1);
6114 pmem_flags = pci_resource_flags (pdev, 1);
6115
6116 if (!(pmem_flags & IORESOURCE_MEM)) {
6117 RT_TRACE(COMP_ERR,"region #1 not a MMIO resource, aborting");
6118 goto fail;
6119 }
6120
6121 //DMESG("Memory mapped space @ 0x%08lx ", pmem_start);
6122 if( ! request_mem_region(pmem_start, pmem_len, RTL819xE_MODULE_NAME)) {
6123 RT_TRACE(COMP_ERR,"request_mem_region failed!");
6124 goto fail;
6125 }
6126
6127
6128 ioaddr = (unsigned long)ioremap_nocache( pmem_start, pmem_len);
6129 if( ioaddr == (unsigned long)NULL ){
6130 RT_TRACE(COMP_ERR,"ioremap failed!");
6131 // release_mem_region( pmem_start, pmem_len );
6132 goto fail1;
6133 }
6134
6135 dev->mem_start = ioaddr; // shared mem start
6136 dev->mem_end = ioaddr + pci_resource_len(pdev, 0); // shared mem end
6137
6138#endif //end #ifdef RTL_IO_MAP
6139
6140 /* We disable the RETRY_TIMEOUT register (0x41) to keep
6141 * PCI Tx retries from interfering with C3 CPU state */
6142 pci_write_config_byte(pdev, 0x41, 0x00);
6143
6144
6145 pci_read_config_byte(pdev, 0x05, &unit);
6146 pci_write_config_byte(pdev, 0x05, unit & (~0x04));
6147
6148 dev->irq = pdev->irq;
6149 priv->irq = 0;
6150
6151 dev->netdev_ops = &rtl8192_netdev_ops;
6152#if 0
6153 dev->open = rtl8192_open;
6154 dev->stop = rtl8192_close;
6155 //dev->hard_start_xmit = rtl8192_8023_hard_start_xmit;
6156 dev->tx_timeout = tx_timeout;
6157 //dev->wireless_handlers = &r8192_wx_handlers_def;
6158 dev->do_ioctl = rtl8192_ioctl;
6159 dev->set_multicast_list = r8192_set_multicast;
6160 dev->set_mac_address = r8192_set_mac_adr;
6161#endif
6162
6163 //DMESG("Oops: i'm coming\n");
6164#if WIRELESS_EXT >= 12
6165#if WIRELESS_EXT < 17
6166 dev->get_wireless_stats = r8192_get_wireless_stats;
6167#endif
6168 dev->wireless_handlers = (struct iw_handler_def *) &r8192_wx_handlers_def;
6169#endif
6170 //dev->get_wireless_stats = r8192_get_wireless_stats;
6171 dev->type=ARPHRD_ETHER;
6172
6173 dev->watchdog_timeo = HZ*3; //modified by john, 0805
6174
6175 if (dev_alloc_name(dev, ifname) < 0){
6176 RT_TRACE(COMP_INIT, "Oops: devname already taken! Trying wlan%%d...\n");
dca41306 6177 strcpy(ifname, "wlan%d");
ecdfa446
GKH
6178 dev_alloc_name(dev, ifname);
6179 }
6180
6181 RT_TRACE(COMP_INIT, "Driver probe completed1\n");
6182 if(rtl8192_init(dev)!=0){
6183 RT_TRACE(COMP_ERR, "Initialization failed");
6184 goto fail;
6185 }
6186
6187 netif_carrier_off(dev);
6188 netif_stop_queue(dev);
6189
6190 register_netdev(dev);
6191 RT_TRACE(COMP_INIT, "dev name=======> %s\n",dev->name);
6192 rtl8192_proc_init_one(dev);
6193
6194
6195 RT_TRACE(COMP_INIT, "Driver probe completed\n");
ecdfa446 6196 return 0;
ecdfa446
GKH
6197
6198fail1:
6199
6200#ifdef CONFIG_RTL8180_IO_MAP
6201
6202 if( dev->base_addr != 0 ){
6203
6204 release_region(dev->base_addr,
6205 pci_resource_len(pdev, 0) );
6206 }
6207#else
6208 if( dev->mem_start != (unsigned long)NULL ){
6209 iounmap( (void *)dev->mem_start );
6210 release_mem_region( pci_resource_start(pdev, 1),
6211 pci_resource_len(pdev, 1) );
6212 }
6213#endif //end #ifdef RTL_IO_MAP
6214
6215fail:
6216 if(dev){
6217
6218 if (priv->irq) {
6219 free_irq(dev->irq, dev);
6220 dev->irq=0;
6221 }
6222 free_ieee80211(dev);
6223 }
6224
3a8f2d3c 6225fail_free:
ecdfa446
GKH
6226 pci_disable_device(pdev);
6227
6228 DMESG("wlan driver load failed\n");
6229 pci_set_drvdata(pdev, NULL);
3a8f2d3c 6230 return ret;
ecdfa446
GKH
6231
6232}
6233
6234/* detach all the work and timer structure declared or inititialized
6235 * in r8192_init function.
6236 * */
5b3b1a7b 6237static void rtl8192_cancel_deferred_work(struct r8192_priv* priv)
ecdfa446
GKH
6238{
6239 /* call cancel_work_sync instead of cancel_delayed_work if and only if Linux_version_code
6240 * is or is newer than 2.6.20 and work structure is defined to be struct work_struct.
6241 * Otherwise call cancel_delayed_work is enough.
39cfb97b 6242 * FIXME (2.6.20 should 2.6.22, work_struct should not cancel)
ecdfa446 6243 * */
ecdfa446
GKH
6244 cancel_delayed_work(&priv->watch_dog_wq);
6245 cancel_delayed_work(&priv->update_beacon_wq);
6246 cancel_delayed_work(&priv->ieee80211->hw_wakeup_wq);
6247 cancel_delayed_work(&priv->ieee80211->hw_sleep_wq);
6248#ifdef RTL8192E
6249 cancel_delayed_work(&priv->gpio_change_rf_wq);
6250#endif
ecdfa446
GKH
6251 cancel_work_sync(&priv->reset_wq);
6252 cancel_work_sync(&priv->qos_activate);
6253 //cancel_work_sync(&priv->SetBWModeWorkItem);
6254 //cancel_work_sync(&priv->SwChnlWorkItem);
ecdfa446
GKH
6255
6256}
6257
6258
6259static void __devexit rtl8192_pci_disconnect(struct pci_dev *pdev)
6260{
6261 struct net_device *dev = pci_get_drvdata(pdev);
6262 struct r8192_priv *priv ;
6263
6264 if(dev){
6265
6266 unregister_netdev(dev);
6267
6268 priv=ieee80211_priv(dev);
6269
6270 rtl8192_proc_remove_one(dev);
6271
6272 rtl8192_down(dev);
6273 if (priv->pFirmware)
6274 {
6275 vfree(priv->pFirmware);
6276 priv->pFirmware = NULL;
6277 }
6278 // priv->rf_close(dev);
6279 // rtl8192_usb_deleteendpoints(dev);
ecdfa446 6280 destroy_workqueue(priv->priv_wq);
ecdfa446
GKH
6281 /* redundant with rtl8192_down */
6282 // rtl8192_irq_disable(dev);
6283 // rtl8192_reset(dev);
6284 // mdelay(10);
6285 {
6286 u32 i;
6287 /* free tx/rx rings */
6288 rtl8192_free_rx_ring(dev);
6289 for (i = 0; i < MAX_TX_QUEUE_COUNT; i++) {
6290 rtl8192_free_tx_ring(dev, i);
6291 }
6292 }
6293 if(priv->irq){
6294
6295 printk("Freeing irq %d\n",dev->irq);
6296 free_irq(dev->irq, dev);
6297 priv->irq=0;
6298
6299 }
6300
6301
6302
6303 // free_beacon_desc_ring(dev,priv->txbeaconcount);
6304
6305#ifdef CONFIG_RTL8180_IO_MAP
6306
6307 if( dev->base_addr != 0 ){
6308
6309 release_region(dev->base_addr,
6310 pci_resource_len(pdev, 0) );
6311 }
6312#else
6313 if( dev->mem_start != (unsigned long)NULL ){
6314 iounmap( (void *)dev->mem_start );
6315 release_mem_region( pci_resource_start(pdev, 1),
6316 pci_resource_len(pdev, 1) );
6317 }
6318#endif /*end #ifdef RTL_IO_MAP*/
6319 free_ieee80211(dev);
6320
6321 }
6322
6323 pci_disable_device(pdev);
6324 RT_TRACE(COMP_DOWN, "wlan driver removed\n");
6325}
6326
fb5fe277
GK
6327extern int ieee80211_rtl_init(void);
6328extern void ieee80211_rtl_exit(void);
ecdfa446
GKH
6329
6330static int __init rtl8192_pci_module_init(void)
6331{
6332 int retval;
6333
fb5fe277 6334 retval = ieee80211_rtl_init();
ecdfa446
GKH
6335 if (retval)
6336 return retval;
6337
6338 printk(KERN_INFO "\nLinux kernel driver for RTL8192 based WLAN cards\n");
6339 printk(KERN_INFO "Copyright (c) 2007-2008, Realsil Wlan\n");
6340 RT_TRACE(COMP_INIT, "Initializing module");
6341 RT_TRACE(COMP_INIT, "Wireless extensions version %d", WIRELESS_EXT);
6342 rtl8192_proc_module_init();
ecdfa446 6343 if(0!=pci_register_driver(&rtl8192_pci_driver))
ecdfa446
GKH
6344 {
6345 DMESG("No device found");
6346 /*pci_unregister_driver (&rtl8192_pci_driver);*/
6347 return -ENODEV;
6348 }
6349 return 0;
6350}
6351
6352
6353static void __exit rtl8192_pci_module_exit(void)
6354{
6355 pci_unregister_driver(&rtl8192_pci_driver);
6356
6357 RT_TRACE(COMP_DOWN, "Exiting");
6358 rtl8192_proc_module_remove();
fb5fe277 6359 ieee80211_rtl_exit();
ecdfa446
GKH
6360}
6361
6362//warning message WB
559fba5e 6363static irqreturn_t rtl8192_interrupt(int irq, void *netdev)
ecdfa446
GKH
6364{
6365 struct net_device *dev = (struct net_device *) netdev;
6366 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
6367 unsigned long flags;
6368 u32 inta;
6369 /* We should return IRQ_NONE, but for now let me keep this */
6370 if(priv->irq_enabled == 0){
ecdfa446 6371 return IRQ_HANDLED;
ecdfa446
GKH
6372 }
6373
6374 spin_lock_irqsave(&priv->irq_th_lock,flags);
6375
6376 //ISR: 4bytes
6377
6378 inta = read_nic_dword(dev, ISR);// & priv->IntrMask;
6379 write_nic_dword(dev,ISR,inta); // reset int situation
6380
6381 priv->stats.shints++;
6382 //DMESG("Enter interrupt, ISR value = 0x%08x", inta);
6383 if(!inta){
6384 spin_unlock_irqrestore(&priv->irq_th_lock,flags);
ecdfa446 6385 return IRQ_HANDLED;
ecdfa446
GKH
6386 /*
6387 most probably we can safely return IRQ_NONE,
6388 but for now is better to avoid problems
6389 */
6390 }
6391
6392 if(inta == 0xffff){
6393 /* HW disappared */
6394 spin_unlock_irqrestore(&priv->irq_th_lock,flags);
ecdfa446 6395 return IRQ_HANDLED;
ecdfa446
GKH
6396 }
6397
6398 priv->stats.ints++;
6399#ifdef DEBUG_IRQ
6400 DMESG("NIC irq %x",inta);
6401#endif
6402 //priv->irqpending = inta;
6403
6404
6405 if(!netif_running(dev)) {
6406 spin_unlock_irqrestore(&priv->irq_th_lock,flags);
ecdfa446 6407 return IRQ_HANDLED;
ecdfa446
GKH
6408 }
6409
6410 if(inta & IMR_TIMEOUT0){
6411 // write_nic_dword(dev, TimerInt, 0);
6412 //DMESG("=================>waking up");
6413 // rtl8180_hw_wakeup(dev);
6414 }
6415
6416 if(inta & IMR_TBDOK){
6417 RT_TRACE(COMP_INTR, "beacon ok interrupt!\n");
6418 rtl8192_tx_isr(dev, BEACON_QUEUE);
6419 priv->stats.txbeaconokint++;
6420 }
6421
6422 if(inta & IMR_TBDER){
6423 RT_TRACE(COMP_INTR, "beacon ok interrupt!\n");
6424 rtl8192_tx_isr(dev, BEACON_QUEUE);
6425 priv->stats.txbeaconerr++;
6426 }
6427
6428 if(inta & IMR_MGNTDOK ) {
6429 RT_TRACE(COMP_INTR, "Manage ok interrupt!\n");
6430 priv->stats.txmanageokint++;
6431 rtl8192_tx_isr(dev,MGNT_QUEUE);
6432
6433 }
6434
6435 if(inta & IMR_COMDOK)
6436 {
6437 priv->stats.txcmdpktokint++;
6438 rtl8192_tx_isr(dev,TXCMD_QUEUE);
6439 }
6440
6441 if(inta & IMR_ROK){
6442#ifdef DEBUG_RX
6443 DMESG("Frame arrived !");
6444#endif
6445 priv->stats.rxint++;
6446 tasklet_schedule(&priv->irq_rx_tasklet);
6447 }
6448
6449 if(inta & IMR_BcnInt) {
6450 RT_TRACE(COMP_INTR, "prepare beacon for interrupt!\n");
6451 tasklet_schedule(&priv->irq_prepare_beacon_tasklet);
6452 }
6453
6454 if(inta & IMR_RDU){
6455 RT_TRACE(COMP_INTR, "rx descriptor unavailable!\n");
6456 priv->stats.rxrdu++;
6457 /* reset int situation */
6458 write_nic_dword(dev,INTA_MASK,read_nic_dword(dev, INTA_MASK) & ~IMR_RDU);
6459 tasklet_schedule(&priv->irq_rx_tasklet);
6460 }
6461
6462 if(inta & IMR_RXFOVW){
6463 RT_TRACE(COMP_INTR, "rx overflow !\n");
6464 priv->stats.rxoverflow++;
6465 tasklet_schedule(&priv->irq_rx_tasklet);
6466 }
6467
6468 if(inta & IMR_TXFOVW) priv->stats.txoverflow++;
6469
6470 if(inta & IMR_BKDOK){
6471 RT_TRACE(COMP_INTR, "BK Tx OK interrupt!\n");
6472 priv->stats.txbkokint++;
6473 priv->ieee80211->LinkDetectInfo.NumTxOkInPeriod++;
6474 rtl8192_tx_isr(dev,BK_QUEUE);
6475 rtl8192_try_wake_queue(dev, BK_QUEUE);
6476 }
6477
6478 if(inta & IMR_BEDOK){
6479 RT_TRACE(COMP_INTR, "BE TX OK interrupt!\n");
6480 priv->stats.txbeokint++;
6481 priv->ieee80211->LinkDetectInfo.NumTxOkInPeriod++;
6482 rtl8192_tx_isr(dev,BE_QUEUE);
6483 rtl8192_try_wake_queue(dev, BE_QUEUE);
6484 }
6485
6486 if(inta & IMR_VIDOK){
6487 RT_TRACE(COMP_INTR, "VI TX OK interrupt!\n");
6488 priv->stats.txviokint++;
6489 priv->ieee80211->LinkDetectInfo.NumTxOkInPeriod++;
6490 rtl8192_tx_isr(dev,VI_QUEUE);
6491 rtl8192_try_wake_queue(dev, VI_QUEUE);
6492 }
6493
6494 if(inta & IMR_VODOK){
6495 priv->stats.txvookint++;
6496 priv->ieee80211->LinkDetectInfo.NumTxOkInPeriod++;
6497 rtl8192_tx_isr(dev,VO_QUEUE);
6498 rtl8192_try_wake_queue(dev, VO_QUEUE);
6499 }
6500
ecdfa446
GKH
6501 spin_unlock_irqrestore(&priv->irq_th_lock,flags);
6502
ecdfa446 6503 return IRQ_HANDLED;
ecdfa446
GKH
6504}
6505
559fba5e 6506static void rtl8192_try_wake_queue(struct net_device *dev, int pri)
ecdfa446 6507{
ecdfa446
GKH
6508}
6509
6510
6511void EnableHWSecurityConfig8192(struct net_device *dev)
6512{
6513 u8 SECR_value = 0x0;
ecdfa446 6514 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
16d74da0
MM
6515 struct ieee80211_device* ieee = priv->ieee80211;
6516
ecdfa446
GKH
6517 SECR_value = SCR_TxEncEnable | SCR_RxDecEnable;
6518#if 1
6519 if (((KEY_TYPE_WEP40 == ieee->pairwise_key_type) || (KEY_TYPE_WEP104 == ieee->pairwise_key_type)) && (priv->ieee80211->auth_mode != 2))
6520 {
6521 SECR_value |= SCR_RxUseDK;
6522 SECR_value |= SCR_TxUseDK;
6523 }
6524 else if ((ieee->iw_mode == IW_MODE_ADHOC) && (ieee->pairwise_key_type & (KEY_TYPE_CCMP | KEY_TYPE_TKIP)))
6525 {
6526 SECR_value |= SCR_RxUseDK;
6527 SECR_value |= SCR_TxUseDK;
6528 }
6529
6530#endif
6531
6532 //add HWSec active enable here.
6533//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
6534 ieee->hwsec_active = 1;
6535
6536 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
6537 {
6538 ieee->hwsec_active = 0;
6539 SECR_value &= ~SCR_RxDecEnable;
6540 }
6541
207b58fb 6542 RT_TRACE(COMP_SEC,"%s:, hwsec:%d, pairwise_key:%d, SECR_value:%x\n", __FUNCTION__,
ecdfa446
GKH
6543 ieee->hwsec_active, ieee->pairwise_key_type, SECR_value);
6544 {
6545 write_nic_byte(dev, SECR, SECR_value);//SECR_value | SCR_UseDK );
6546 }
6547
6548}
6549#define TOTAL_CAM_ENTRY 32
6550//#define CAM_CONTENT_COUNT 8
6551void setKey( struct net_device *dev,
6552 u8 EntryNo,
6553 u8 KeyIndex,
6554 u16 KeyType,
881a975b 6555 const u8 *MacAddr,
ecdfa446
GKH
6556 u8 DefaultKey,
6557 u32 *KeyContent )
6558{
6559 u32 TargetCommand = 0;
6560 u32 TargetContent = 0;
6561 u16 usConfig = 0;
6562 u8 i;
6563#ifdef ENABLE_IPS
6564 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
6565 RT_RF_POWER_STATE rtState;
6566 rtState = priv->ieee80211->eRFPowerState;
6567 if(priv->ieee80211->PowerSaveControl.bInactivePs){
6568 if(rtState == eRfOff){
6569 if(priv->ieee80211->RfOffReason > RF_CHANGE_BY_IPS)
6570 {
6571 RT_TRACE(COMP_ERR, "%s(): RF is OFF.\n",__FUNCTION__);
65a43784 6572 //up(&priv->wx_sem);
ecdfa446
GKH
6573 return ;
6574 }
6575 else{
65a43784 6576 down(&priv->ieee80211->ips_sem);
ecdfa446 6577 IPSLeave(dev);
65a43784 6578 up(&priv->ieee80211->ips_sem);
ecdfa446
GKH
6579 }
6580 }
6581 }
6582 priv->ieee80211->is_set_key = true;
6583#endif
6584 if (EntryNo >= TOTAL_CAM_ENTRY)
6585 RT_TRACE(COMP_ERR, "cam entry exceeds in setKey()\n");
6586
0ee9f67c 6587 RT_TRACE(COMP_SEC, "====>to setKey(), dev:%p, EntryNo:%d, KeyIndex:%d, KeyType:%d, MacAddr%pM\n", dev,EntryNo, KeyIndex, KeyType, MacAddr);
ecdfa446
GKH
6588
6589 if (DefaultKey)
6590 usConfig |= BIT15 | (KeyType<<2);
6591 else
6592 usConfig |= BIT15 | (KeyType<<2) | KeyIndex;
6593// usConfig |= BIT15 | (KeyType<<2) | (DefaultKey<<5) | KeyIndex;
6594
6595
6596 for(i=0 ; i<CAM_CONTENT_COUNT; i++){
6597 TargetCommand = i+CAM_CONTENT_COUNT*EntryNo;
6598 TargetCommand |= BIT31|BIT16;
6599
6600 if(i==0){//MAC|Config
6601 TargetContent = (u32)(*(MacAddr+0)) << 16|
6602 (u32)(*(MacAddr+1)) << 24|
6603 (u32)usConfig;
6604
6605 write_nic_dword(dev, WCAMI, TargetContent);
6606 write_nic_dword(dev, RWCAM, TargetCommand);
6607 // printk("setkey cam =%8x\n", read_cam(dev, i+6*EntryNo));
6608 }
6609 else if(i==1){//MAC
6610 TargetContent = (u32)(*(MacAddr+2)) |
6611 (u32)(*(MacAddr+3)) << 8|
6612 (u32)(*(MacAddr+4)) << 16|
6613 (u32)(*(MacAddr+5)) << 24;
6614 write_nic_dword(dev, WCAMI, TargetContent);
6615 write_nic_dword(dev, RWCAM, TargetCommand);
6616 }
6617 else { //Key Material
6618 if(KeyContent != NULL)
6619 {
6620 write_nic_dword(dev, WCAMI, (u32)(*(KeyContent+i-2)) );
6621 write_nic_dword(dev, RWCAM, TargetCommand);
6622 }
6623 }
6624 }
6625 RT_TRACE(COMP_SEC,"=========>after set key, usconfig:%x\n", usConfig);
ecdfa446 6626}
ecdfa446 6627
65a43784 6628bool NicIFEnableNIC(struct net_device* dev)
6629{
6630 RT_STATUS init_status = RT_STATUS_SUCCESS;
6631 struct r8192_priv* priv = ieee80211_priv(dev);
6632 PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->ieee80211->PowerSaveControl));
6633
6634 //YJ,add,091109
6635 if (priv->up == 0){
6636 RT_TRACE(COMP_ERR, "ERR!!! %s(): Driver is already down!\n",__FUNCTION__);
6637 priv->bdisable_nic = false; //YJ,add,091111
6638 return false;
6639 }
6640 // <1> Reset memory: descriptor, buffer,..
6641 //NicIFResetMemory(Adapter);
6642
6643 // <2> Enable Adapter
65a43784 6644 //priv->bfirst_init = true;
6645 init_status = rtl8192_adapter_start(dev);
6646 if (init_status != RT_STATUS_SUCCESS) {
6647 RT_TRACE(COMP_ERR,"ERR!!! %s(): initialization is failed!\n",__FUNCTION__);
6648 priv->bdisable_nic = false; //YJ,add,091111
6649 return -1;
6650 }
6651 //printk("start adapter finished\n");
6652 RT_CLEAR_PS_LEVEL(pPSC, RT_RF_OFF_LEVL_HALT_NIC);
6653 //priv->bfirst_init = false;
6654
6655 // <3> Enable Interrupt
6656 rtl8192_irq_enable(dev);
6657 priv->bdisable_nic = false;
16d74da0 6658
c6eae677 6659 return (init_status == RT_STATUS_SUCCESS);
65a43784 6660}
214985a6 6661
65a43784 6662bool NicIFDisableNIC(struct net_device* dev)
6663{
6664 bool status = true;
6665 struct r8192_priv* priv = ieee80211_priv(dev);
6666 u8 tmp_state = 0;
6667 // <1> Disable Interrupt
16d74da0 6668
65a43784 6669 priv->bdisable_nic = true; //YJ,move,091109
6670 tmp_state = priv->ieee80211->state;
6671
6672 ieee80211_softmac_stop_protocol(priv->ieee80211, false);
6673
6674 priv->ieee80211->state = tmp_state;
6675 rtl8192_cancel_deferred_work(priv);
6676 rtl8192_irq_disable(dev);
6677 // <2> Stop all timer
6678
6679 // <3> Disable Adapter
6680 rtl8192_halt_adapter(dev, false);
6681// priv->bdisable_nic = true;
65a43784 6682
6683 return status;
6684}
6685
ecdfa446
GKH
6686module_init(rtl8192_pci_module_init);
6687module_exit(rtl8192_pci_module_exit);
This page took 0.405674 seconds and 5 git commands to generate.