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