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