1 /******************************************************************************
2 * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
3 * Linux device driver for RTL8190P / RTL8192E
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.
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
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
20 * The full GNU General Public License is included in this distribution in the
21 * file called LICENSE.
23 * Contact Information:
24 * Jerry chuang <wlanfae@realtek.com>
29 #undef RX_DONT_PASS_UL
31 #undef DEBUG_RX_VERBOSE
37 #undef DEBUG_TX_FILLDESC
42 #undef DEBUG_REGISTERS
44 #undef DEBUG_IRQ_TASKLET
48 //#define CONFIG_RTL8192_IO_MAP
49 #include <linux/vmalloc.h>
50 #include <linux/slab.h>
51 #include <asm/uaccess.h>
52 #include "r8192E_hw.h"
54 #include "r8190_rtl8256.h" /* RTL8225 Radio frontend */
55 #include "r8180_93cx6.h" /* Card EEPROM */
56 #include "r8192E_wx.h"
57 #include "r819xE_phy.h" //added by WB 4.30.2008
58 #include "r819xE_phyreg.h"
59 #include "r819xE_cmdpkt.h"
60 #include "r8192E_dm.h"
61 //#include "r8192xU_phyreg.h"
62 //#include <linux/usb.h>
63 // FIXME: check if 2.6.7 is ok
70 #include "ieee80211/dot11d.h"
73 //set here to open your trace code. //WB
74 u32 rt_global_debug_component
= \
92 // COMP_POWER_TRACKING |
94 COMP_ERR
; //always open err flags on
96 static const struct pci_device_id rtl8192_pci_id_tbl
[] __devinitdata
= {
100 { PCI_DEVICE(0x10ec, 0x8190) },
102 { PCI_DEVICE(0x07aa, 0x0045) },
103 { PCI_DEVICE(0x07aa, 0x0046) },
106 { PCI_DEVICE(0x10ec, 0x8192) },
109 { PCI_DEVICE(0x07aa, 0x0044) },
110 { PCI_DEVICE(0x07aa, 0x0047) },
115 static char* ifname
= "wlan%d";
116 static int hwwep
= 1; //default use hw. set 0 to use software security
117 static int channels
= 0x3fff;
119 MODULE_LICENSE("GPL");
120 MODULE_VERSION("V 1.1");
121 MODULE_DEVICE_TABLE(pci
, rtl8192_pci_id_tbl
);
122 //MODULE_AUTHOR("Andrea Merello <andreamrl@tiscali.it>");
123 MODULE_DESCRIPTION("Linux driver for Realtek RTL819x WiFi cards");
126 module_param(ifname
, charp
, S_IRUGO
|S_IWUSR
);
127 //module_param(hwseqnum,int, S_IRUGO|S_IWUSR);
128 module_param(hwwep
,int, S_IRUGO
|S_IWUSR
);
129 module_param(channels
,int, S_IRUGO
|S_IWUSR
);
131 MODULE_PARM_DESC(ifname
," Net interface name, wlan%d=default");
132 //MODULE_PARM_DESC(hwseqnum," Try to use hardware 802.11 header sequence numbers. Zero=default");
133 MODULE_PARM_DESC(hwwep
," Try to use hardware WEP support. Still broken and not available on all cards");
134 MODULE_PARM_DESC(channels
," Channel bitmask for specific locales. NYI");
136 static int __devinit
rtl8192_pci_probe(struct pci_dev
*pdev
,
137 const struct pci_device_id
*id
);
138 static void __devexit
rtl8192_pci_disconnect(struct pci_dev
*pdev
);
140 static struct pci_driver rtl8192_pci_driver
= {
141 .name
= RTL819xE_MODULE_NAME
, /* Driver name */
142 .id_table
= rtl8192_pci_id_tbl
, /* PCI_ID table */
143 .probe
= rtl8192_pci_probe
, /* probe fn */
144 .remove
= __devexit_p(rtl8192_pci_disconnect
), /* remove fn */
146 .suspend
= rtl8192E_suspend
, /* PM suspend fn */
147 .resume
= rtl8192E_resume
, /* PM resume fn */
149 .suspend
= NULL
, /* PM suspend fn */
150 .resume
= NULL
, /* PM resume fn */
154 static void rtl8192_start_beacon(struct net_device
*dev
);
155 static void rtl8192_stop_beacon(struct net_device
*dev
);
156 static void rtl819x_watchdog_wqcallback(struct work_struct
*work
);
157 static void rtl8192_irq_rx_tasklet(struct r8192_priv
*priv
);
158 static void rtl8192_irq_tx_tasklet(struct r8192_priv
*priv
);
159 static void rtl8192_prepare_beacon(struct r8192_priv
*priv
);
160 static irqreturn_t
rtl8192_interrupt(int irq
, void *netdev
);
161 static void rtl8192_try_wake_queue(struct net_device
*dev
, int pri
);
162 static void rtl819xE_tx_cmd(struct net_device
*dev
, struct sk_buff
*skb
);
166 typedef struct _CHANNEL_LIST
170 }CHANNEL_LIST
, *PCHANNEL_LIST
;
172 static const CHANNEL_LIST ChannelPlan
[] = {
173 {{1,2,3,4,5,6,7,8,9,10,11,36,40,44,48,52,56,60,64,149,153,157,161,165},24}, //FCC
174 {{1,2,3,4,5,6,7,8,9,10,11},11}, //IC
175 {{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48,52,56,60,64},21}, //ETSI
176 {{1,2,3,4,5,6,7,8,9,10,11,12,13},13}, //Spain. Change to ETSI.
177 {{1,2,3,4,5,6,7,8,9,10,11,12,13},13}, //France. Change to ETSI.
178 {{1,2,3,4,5,6,7,8,9,10,11,12,13,14,36,40,44,48,52,56,60,64},22}, //MKK //MKK
179 {{1,2,3,4,5,6,7,8,9,10,11,12,13,14,36,40,44,48,52,56,60,64},22},//MKK1
180 {{1,2,3,4,5,6,7,8,9,10,11,12,13},13}, //Israel.
181 {{1,2,3,4,5,6,7,8,9,10,11,12,13,14,36,40,44,48,52,56,60,64},22}, // For 11a , TELEC
182 {{1,2,3,4,5,6,7,8,9,10,11,12,13,14,36,40,44,48,52,56,60,64}, 22}, //MIC
183 {{1,2,3,4,5,6,7,8,9,10,11,12,13,14},14} //For Global Domain. 1-11:active scan, 12-14 passive scan. //+YJ, 080626
186 static void rtl819x_set_channel_map(u8 channel_plan
, struct r8192_priv
* priv
)
188 int i
, max_chan
=-1, min_chan
=-1;
189 struct ieee80211_device
* ieee
= priv
->ieee80211
;
190 switch (channel_plan
)
192 case COUNTRY_CODE_FCC
:
193 case COUNTRY_CODE_IC
:
194 case COUNTRY_CODE_ETSI
:
195 case COUNTRY_CODE_SPAIN
:
196 case COUNTRY_CODE_FRANCE
:
197 case COUNTRY_CODE_MKK
:
198 case COUNTRY_CODE_MKK1
:
199 case COUNTRY_CODE_ISRAEL
:
200 case COUNTRY_CODE_TELEC
:
201 case COUNTRY_CODE_MIC
:
204 ieee
->bGlobalDomain
= false;
205 //acturally 8225 & 8256 rf chip only support B,G,24N mode
206 if ((priv
->rf_chip
== RF_8225
) || (priv
->rf_chip
== RF_8256
))
213 RT_TRACE(COMP_ERR
, "unknown rf chip, can't set channel map in function:%s()\n", __FUNCTION__
);
215 if (ChannelPlan
[channel_plan
].Len
!= 0){
216 // Clear old channel map
217 memset(GET_DOT11D_INFO(ieee
)->channel_map
, 0, sizeof(GET_DOT11D_INFO(ieee
)->channel_map
));
218 // Set new channel map
219 for (i
=0;i
<ChannelPlan
[channel_plan
].Len
;i
++)
221 if (ChannelPlan
[channel_plan
].Channel
[i
] < min_chan
|| ChannelPlan
[channel_plan
].Channel
[i
] > max_chan
)
223 GET_DOT11D_INFO(ieee
)->channel_map
[ChannelPlan
[channel_plan
].Channel
[i
]] = 1;
228 case COUNTRY_CODE_GLOBAL_DOMAIN
:
230 GET_DOT11D_INFO(ieee
)->bEnabled
= 0; //this flag enabled to follow 11d country IE setting, otherwise, it shall follow global domain setting
232 ieee
->bGlobalDomain
= true;
242 #define eqMacAddr(a,b) ( ((a)[0]==(b)[0] && (a)[1]==(b)[1] && (a)[2]==(b)[2] && (a)[3]==(b)[3] && (a)[4]==(b)[4] && (a)[5]==(b)[5]) ? 1:0 )
243 /* 2007/07/25 MH Defien temp tx fw info. */
244 static TX_FWINFO_T Tmp_TxFwInfo
;
247 #define rx_hal_is_cck_rate(_pdrvinfo)\
248 (_pdrvinfo->RxRate == DESC90_RATE1M ||\
249 _pdrvinfo->RxRate == DESC90_RATE2M ||\
250 _pdrvinfo->RxRate == DESC90_RATE5_5M ||\
251 _pdrvinfo->RxRate == DESC90_RATE11M) &&\
255 void CamResetAllEntry(struct net_device *dev)
261 ulcommand
|= BIT31
|BIT30
;
262 write_nic_dword(dev
, RWCAM
, ulcommand
);
264 for(ucIndex
=0;ucIndex
<TOTAL_CAM_ENTRY
;ucIndex
++)
265 CAM_mark_invalid(dev
, ucIndex
);
266 for(ucIndex
=0;ucIndex
<TOTAL_CAM_ENTRY
;ucIndex
++)
267 CAM_empty_entry(dev
, ucIndex
);
272 void write_cam(struct net_device
*dev
, u8 addr
, u32 data
)
274 write_nic_dword(dev
, WCAMI
, data
);
275 write_nic_dword(dev
, RWCAM
, BIT31
|BIT16
|(addr
&0xff) );
277 u32
read_cam(struct net_device
*dev
, u8 addr
)
279 write_nic_dword(dev
, RWCAM
, 0x80000000|(addr
&0xff) );
280 return read_nic_dword(dev
, 0xa8);
283 ////////////////////////////////////////////////////////////
284 #ifdef CONFIG_RTL8180_IO_MAP
286 u8
read_nic_byte(struct net_device
*dev
, int x
)
288 return 0xff&inb(dev
->base_addr
+x
);
291 u32
read_nic_dword(struct net_device
*dev
, int x
)
293 return inl(dev
->base_addr
+x
);
296 u16
read_nic_word(struct net_device
*dev
, int x
)
298 return inw(dev
->base_addr
+x
);
301 void write_nic_byte(struct net_device
*dev
, int x
,u8 y
)
303 outb(y
&0xff,dev
->base_addr
+x
);
306 void write_nic_word(struct net_device
*dev
, int x
,u16 y
)
308 outw(y
,dev
->base_addr
+x
);
311 void write_nic_dword(struct net_device
*dev
, int x
,u32 y
)
313 outl(y
,dev
->base_addr
+x
);
316 #else /* RTL_IO_MAP */
318 u8
read_nic_byte(struct net_device
*dev
, int x
)
320 return 0xff&readb((u8
*)dev
->mem_start
+x
);
323 u32
read_nic_dword(struct net_device
*dev
, int x
)
325 return readl((u8
*)dev
->mem_start
+x
);
328 u16
read_nic_word(struct net_device
*dev
, int x
)
330 return readw((u8
*)dev
->mem_start
+x
);
333 void write_nic_byte(struct net_device
*dev
, int x
,u8 y
)
335 writeb(y
,(u8
*)dev
->mem_start
+x
);
339 void write_nic_dword(struct net_device
*dev
, int x
,u32 y
)
341 writel(y
,(u8
*)dev
->mem_start
+x
);
345 void write_nic_word(struct net_device
*dev
, int x
,u16 y
)
347 writew(y
,(u8
*)dev
->mem_start
+x
);
351 #endif /* RTL_IO_MAP */
353 u8
rtl8192e_ap_sec_type(struct ieee80211_device
*ieee
)
355 //struct r8192_priv* priv = ieee80211_priv(dev);
356 //struct ieee80211_device *ieee = priv->ieee80211;
358 static const u8 ccmp_ie
[4] = {0x00,0x50,0xf2,0x04};
359 static const u8 ccmp_rsn_ie
[4] = {0x00, 0x0f, 0xac, 0x04};
360 int wpa_ie_len
= ieee
->wpa_ie_len
;
361 struct ieee80211_crypt_data
* crypt
;
364 crypt
= ieee
->crypt
[ieee
->tx_keyidx
];
366 encrypt
= (ieee
->current_network
.capability
& WLAN_CAPABILITY_PRIVACY
) ||\
367 (ieee
->host_encrypt
&& crypt
&& crypt
->ops
&& \
368 (0 == strcmp(crypt
->ops
->name
,"WEP")));
371 if(encrypt
&& (wpa_ie_len
== 0)) {
372 // wep encryption, no N mode setting */
374 } else if((wpa_ie_len
!= 0)) {
375 // parse pairwise key type */
376 if (((ieee
->wpa_ie
[0] == 0xdd) && (!memcmp(&(ieee
->wpa_ie
[14]),ccmp_ie
,4))) ||
377 ((ieee
->wpa_ie
[0] == 0x30) && (!memcmp(&ieee
->wpa_ie
[10],ccmp_rsn_ie
, 4))))
387 rtl8192e_SetHwReg(struct net_device
*dev
,u8 variable
,u8
* val
)
389 struct r8192_priv
* priv
= ieee80211_priv(dev
);
395 write_nic_dword(dev
, BSSIDR
, ((u32
*)(val
))[0]);
396 write_nic_word(dev
, BSSIDR
+2, ((u16
*)(val
+2))[0]);
399 case HW_VAR_MEDIA_STATUS
:
401 RT_OP_MODE OpMode
= *((RT_OP_MODE
*)(val
));
402 //LED_CTL_MODE LedAction = LED_CTL_NO_LINK;
403 u8 btMsr
= read_nic_byte(dev
, MSR
);
409 case RT_OP_MODE_INFRASTRUCTURE
:
411 //LedAction = LED_CTL_LINK;
414 case RT_OP_MODE_IBSS
:
416 // led link set separate
421 //LedAction = LED_CTL_LINK;
429 write_nic_byte(dev
, MSR
, btMsr
);
431 //priv->ieee80211->LedControlHandler(dev, LedAction);
435 case HW_VAR_CECHK_BSSID
:
439 Type
= ((u8
*)(val
))[0];
440 //priv->ieee80211->GetHwRegHandler(dev, HW_VAR_RCR, (u8*)(&RegRCR));
441 RegRCR
= read_nic_dword(dev
,RCR
);
442 priv
->ReceiveConfig
= RegRCR
;
445 RegRCR
|= (RCR_CBSSID
);
446 else if (Type
== false)
447 RegRCR
&= (~RCR_CBSSID
);
449 //priv->ieee80211->SetHwRegHandler( dev, HW_VAR_RCR, (u8*)(&RegRCR) );
450 write_nic_dword(dev
, RCR
,RegRCR
);
451 priv
->ReceiveConfig
= RegRCR
;
456 case HW_VAR_SLOT_TIME
:
458 //PSTA_QOS pStaQos = Adapter->MgntInfo.pStaQos;
461 priv
->slot_time
= val
[0];
462 write_nic_byte(dev
, SLOT_TIME
, val
[0]);
467 case HW_VAR_ACK_PREAMBLE
:
470 priv
->short_preamble
= (bool)(*(u8
*)val
);
471 regTmp
= priv
->basic_rate
;
472 if (priv
->short_preamble
)
473 regTmp
|= BRSR_AckShortPmb
;
474 write_nic_dword(dev
, RRSR
, regTmp
);
479 write_nic_dword(dev
, CPU_GEN
, ((u32
*)(val
))[0]);
489 ///////////////////////////////////////////////////////////
491 //u8 read_phy_cck(struct net_device *dev, u8 adr);
492 //u8 read_phy_ofdm(struct net_device *dev, u8 adr);
493 /* this might still called in what was the PHY rtl8185/rtl8192 common code
494 * plans are to possibilty turn it again in one common code...
496 void force_pci_posting(struct net_device
*dev
)
502 //static struct net_device_stats *rtl8192_stats(struct net_device *dev);
503 //void rtl8192_restart(struct net_device *dev);
504 void rtl8192_restart(struct work_struct
*work
);
505 //void rtl8192_rq_tx_ack(struct work_struct *work);
507 void watch_dog_timer_callback(unsigned long data
);
508 /****************************************************************************
509 -----------------------------PROCFS STUFF-------------------------
510 *****************************************************************************/
512 static struct proc_dir_entry
*rtl8192_proc
= NULL
;
516 static int proc_get_stats_ap(char *page
, char **start
,
517 off_t offset
, int count
,
518 int *eof
, void *data
)
520 struct net_device
*dev
= data
;
521 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
522 struct ieee80211_device
*ieee
= priv
->ieee80211
;
523 struct ieee80211_network
*target
;
527 list_for_each_entry(target
, &ieee
->network_list
, list
) {
529 len
+= snprintf(page
+ len
, count
- len
,
530 "%s ", target
->ssid
);
532 if(target
->wpa_ie_len
>0 || target
->rsn_ie_len
>0){
533 len
+= snprintf(page
+ len
, count
- len
,
537 len
+= snprintf(page
+ len
, count
- len
,
547 static int proc_get_registers(char *page
, char **start
,
548 off_t offset
, int count
,
549 int *eof
, void *data
)
551 struct net_device
*dev
= data
;
552 // struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
559 /* This dump the current register page */
560 len
+= snprintf(page
+ len
, count
- len
,
561 "\n####################page 0##################\n ");
565 //printk( "\nD: %2x> ", n);
566 len
+= snprintf(page
+ len
, count
- len
,
569 for(i
=0;i
<16 && n
<=max
;i
++,n
++)
570 len
+= snprintf(page
+ len
, count
- len
,
571 "%2x ",read_nic_byte(dev
,n
));
573 // printk("%2x ",read_nic_byte(dev,n));
575 len
+= snprintf(page
+ len
, count
- len
,"\n");
576 len
+= snprintf(page
+ len
, count
- len
,
577 "\n####################page 1##################\n ");
580 //printk( "\nD: %2x> ", n);
581 len
+= snprintf(page
+ len
, count
- len
,
584 for(i
=0;i
<16 && n
<=max
;i
++,n
++)
585 len
+= snprintf(page
+ len
, count
- len
,
586 "%2x ",read_nic_byte(dev
,0x100|n
));
588 // printk("%2x ",read_nic_byte(dev,n));
591 len
+= snprintf(page
+ len
, count
- len
,
592 "\n####################page 3##################\n ");
595 //printk( "\nD: %2x> ", n);
596 len
+= snprintf(page
+ len
, count
- len
,
599 for(i
=0;i
<16 && n
<=max
;i
++,n
++)
600 len
+= snprintf(page
+ len
, count
- len
,
601 "%2x ",read_nic_byte(dev
,0x300|n
));
603 // printk("%2x ",read_nic_byte(dev,n));
614 static int proc_get_stats_tx(char *page
, char **start
,
615 off_t offset
, int count
,
616 int *eof
, void *data
)
618 struct net_device
*dev
= data
;
619 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
623 len
+= snprintf(page
+ len
, count
- len
,
624 "TX VI priority ok int: %lu\n"
625 // "TX VI priority error int: %lu\n"
626 "TX VO priority ok int: %lu\n"
627 // "TX VO priority error int: %lu\n"
628 "TX BE priority ok int: %lu\n"
629 // "TX BE priority error int: %lu\n"
630 "TX BK priority ok int: %lu\n"
631 // "TX BK priority error int: %lu\n"
632 "TX MANAGE priority ok int: %lu\n"
633 // "TX MANAGE priority error int: %lu\n"
634 "TX BEACON priority ok int: %lu\n"
635 "TX BEACON priority error int: %lu\n"
636 "TX CMDPKT priority ok int: %lu\n"
637 // "TX high priority ok int: %lu\n"
638 // "TX high priority failed error int: %lu\n"
639 // "TX queue resume: %lu\n"
640 "TX queue stopped?: %d\n"
641 "TX fifo overflow: %lu\n"
642 // "TX beacon: %lu\n"
643 // "TX VI queue: %d\n"
644 // "TX VO queue: %d\n"
645 // "TX BE queue: %d\n"
646 // "TX BK queue: %d\n"
647 // "TX HW queue: %d\n"
648 // "TX VI dropped: %lu\n"
649 // "TX VO dropped: %lu\n"
650 // "TX BE dropped: %lu\n"
651 // "TX BK dropped: %lu\n"
652 "TX total data packets %lu\n"
653 "TX total data bytes :%lu\n",
654 // "TX beacon aborted: %lu\n",
655 priv
->stats
.txviokint
,
656 // priv->stats.txvierr,
657 priv
->stats
.txvookint
,
658 // priv->stats.txvoerr,
659 priv
->stats
.txbeokint
,
660 // priv->stats.txbeerr,
661 priv
->stats
.txbkokint
,
662 // priv->stats.txbkerr,
663 priv
->stats
.txmanageokint
,
664 // priv->stats.txmanageerr,
665 priv
->stats
.txbeaconokint
,
666 priv
->stats
.txbeaconerr
,
667 priv
->stats
.txcmdpktokint
,
668 // priv->stats.txhpokint,
669 // priv->stats.txhperr,
670 // priv->stats.txresumed,
671 netif_queue_stopped(dev
),
672 priv
->stats
.txoverflow
,
673 // priv->stats.txbeacon,
674 // atomic_read(&(priv->tx_pending[VI_QUEUE])),
675 // atomic_read(&(priv->tx_pending[VO_QUEUE])),
676 // atomic_read(&(priv->tx_pending[BE_QUEUE])),
677 // atomic_read(&(priv->tx_pending[BK_QUEUE])),
678 // read_nic_byte(dev, TXFIFOCOUNT),
679 // priv->stats.txvidrop,
680 // priv->stats.txvodrop,
681 priv
->ieee80211
->stats
.tx_packets
,
682 priv
->ieee80211
->stats
.tx_bytes
685 // priv->stats.txbedrop,
686 // priv->stats.txbkdrop
687 // priv->stats.txdatapkt
688 // priv->stats.txbeaconerr
697 static int proc_get_stats_rx(char *page
, char **start
,
698 off_t offset
, int count
,
699 int *eof
, void *data
)
701 struct net_device
*dev
= data
;
702 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
706 len
+= snprintf(page
+ len
, count
- len
,
709 "RX rx overflow error: %lu\n"
710 "RX invalid urb error: %lu\n",
713 priv
->stats
.rxoverflow
,
714 priv
->stats
.rxurberr
);
720 static void rtl8192_proc_module_init(void)
722 RT_TRACE(COMP_INIT
, "Initializing proc filesystem");
723 rtl8192_proc
=create_proc_entry(RTL819xE_MODULE_NAME
, S_IFDIR
, init_net
.proc_net
);
727 static void rtl8192_proc_module_remove(void)
729 remove_proc_entry(RTL819xE_MODULE_NAME
, init_net
.proc_net
);
733 static void rtl8192_proc_remove_one(struct net_device
*dev
)
735 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
737 printk("dev name=======> %s\n",dev
->name
);
740 // remove_proc_entry("stats-hw", priv->dir_dev);
741 remove_proc_entry("stats-tx", priv
->dir_dev
);
742 remove_proc_entry("stats-rx", priv
->dir_dev
);
743 // remove_proc_entry("stats-ieee", priv->dir_dev);
744 remove_proc_entry("stats-ap", priv
->dir_dev
);
745 remove_proc_entry("registers", priv
->dir_dev
);
746 // remove_proc_entry("cck-registers",priv->dir_dev);
747 // remove_proc_entry("ofdm-registers",priv->dir_dev);
748 //remove_proc_entry(dev->name, rtl8192_proc);
749 remove_proc_entry("wlan0", rtl8192_proc
);
750 priv
->dir_dev
= NULL
;
755 static void rtl8192_proc_init_one(struct net_device
*dev
)
757 struct proc_dir_entry
*e
;
758 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
759 priv
->dir_dev
= create_proc_entry(dev
->name
,
760 S_IFDIR
| S_IRUGO
| S_IXUGO
,
762 if (!priv
->dir_dev
) {
763 RT_TRACE(COMP_ERR
, "Unable to initialize /proc/net/rtl8192/%s\n",
767 e
= create_proc_read_entry("stats-rx", S_IFREG
| S_IRUGO
,
768 priv
->dir_dev
, proc_get_stats_rx
, dev
);
771 RT_TRACE(COMP_ERR
,"Unable to initialize "
772 "/proc/net/rtl8192/%s/stats-rx\n",
777 e
= create_proc_read_entry("stats-tx", S_IFREG
| S_IRUGO
,
778 priv
->dir_dev
, proc_get_stats_tx
, dev
);
781 RT_TRACE(COMP_ERR
, "Unable to initialize "
782 "/proc/net/rtl8192/%s/stats-tx\n",
786 e
= create_proc_read_entry("stats-ap", S_IFREG
| S_IRUGO
,
787 priv
->dir_dev
, proc_get_stats_ap
, dev
);
790 RT_TRACE(COMP_ERR
, "Unable to initialize "
791 "/proc/net/rtl8192/%s/stats-ap\n",
795 e
= create_proc_read_entry("registers", S_IFREG
| S_IRUGO
,
796 priv
->dir_dev
, proc_get_registers
, dev
);
798 RT_TRACE(COMP_ERR
, "Unable to initialize "
799 "/proc/net/rtl8192/%s/registers\n",
803 /****************************************************************************
804 -----------------------------MISC STUFF-------------------------
805 *****************************************************************************/
807 short check_nic_enough_desc(struct net_device
*dev
, int prio
)
809 struct r8192_priv
*priv
= ieee80211_priv(dev
);
810 struct rtl8192_tx_ring
*ring
= &priv
->tx_ring
[prio
];
812 /* for now we reserve two free descriptor as a safety boundary
813 * between the tail and the head
815 if (ring
->entries
- skb_queue_len(&ring
->queue
) >= 2) {
822 static void tx_timeout(struct net_device
*dev
)
824 struct r8192_priv
*priv
= ieee80211_priv(dev
);
825 //rtl8192_commit(dev);
827 schedule_work(&priv
->reset_wq
);
832 /****************************************************************************
833 ------------------------------HW STUFF---------------------------
834 *****************************************************************************/
837 static void rtl8192_irq_enable(struct net_device
*dev
)
839 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
840 priv
->irq_enabled
= 1;
841 write_nic_dword(dev
,INTA_MASK
, priv
->irq_mask
);
845 void rtl8192_irq_disable(struct net_device
*dev
)
847 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
849 write_nic_dword(dev
,INTA_MASK
,0);
850 force_pci_posting(dev
);
851 priv
->irq_enabled
= 0;
856 static void rtl8192_set_mode(struct net_device
*dev
,int mode
)
859 ecmd
=read_nic_byte(dev
, EPROM_CMD
);
860 ecmd
=ecmd
&~ EPROM_CMD_OPERATING_MODE_MASK
;
861 ecmd
=ecmd
| (mode
<<EPROM_CMD_OPERATING_MODE_SHIFT
);
862 ecmd
=ecmd
&~ (1<<EPROM_CS_SHIFT
);
863 ecmd
=ecmd
&~ (1<<EPROM_CK_SHIFT
);
864 write_nic_byte(dev
, EPROM_CMD
, ecmd
);
868 void rtl8192_update_msr(struct net_device
*dev
)
870 struct r8192_priv
*priv
= ieee80211_priv(dev
);
873 msr
= read_nic_byte(dev
, MSR
);
874 msr
&= ~ MSR_LINK_MASK
;
876 /* do not change in link_state != WLAN_LINK_ASSOCIATED.
877 * msr must be updated if the state is ASSOCIATING.
878 * this is intentional and make sense for ad-hoc and
879 * master (see the create BSS/IBSS func)
881 if (priv
->ieee80211
->state
== IEEE80211_LINKED
){
883 if (priv
->ieee80211
->iw_mode
== IW_MODE_INFRA
)
884 msr
|= (MSR_LINK_MANAGED
<<MSR_LINK_SHIFT
);
885 else if (priv
->ieee80211
->iw_mode
== IW_MODE_ADHOC
)
886 msr
|= (MSR_LINK_ADHOC
<<MSR_LINK_SHIFT
);
887 else if (priv
->ieee80211
->iw_mode
== IW_MODE_MASTER
)
888 msr
|= (MSR_LINK_MASTER
<<MSR_LINK_SHIFT
);
891 msr
|= (MSR_LINK_NONE
<<MSR_LINK_SHIFT
);
893 write_nic_byte(dev
, MSR
, msr
);
896 void rtl8192_set_chan(struct net_device
*dev
,short ch
)
898 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
899 RT_TRACE(COMP_RF
, "=====>%s()====ch:%d\n", __FUNCTION__
, ch
);
902 if(priv
->ieee80211
->iw_mode
== IW_MODE_ADHOC
||
903 priv
->ieee80211
->iw_mode
== IW_MODE_MASTER
){
905 priv
->ieee80211
->link_state
= WLAN_LINK_ASSOCIATED
;
906 priv
->ieee80211
->master_chan
= ch
;
907 rtl8192_update_beacon_ch(dev
);
911 /* this hack should avoid frame TX during channel setting*/
914 // tx = read_nic_dword(dev,TX_CONF);
915 // tx &= ~TX_LOOPBACK_MASK;
919 // write_nic_dword(dev,TX_CONF, tx |( TX_LOOPBACK_MAC<<TX_LOOPBACK_SHIFT));
921 //need to implement rf set channel here WB
923 if (priv
->rf_set_chan
)
924 priv
->rf_set_chan(dev
,priv
->chan
);
926 // write_nic_dword(dev,TX_CONF,tx | (TX_LOOPBACK_NONE<<TX_LOOPBACK_SHIFT));
930 void rtl8192_rx_enable(struct net_device
*dev
)
932 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
933 write_nic_dword(dev
, RDQDA
,priv
->rx_ring_dma
);
936 /* the TX_DESC_BASE setting is according to the following queue index
945 * BEACON_QUEUE ===> 8
947 static const u32 TX_DESC_BASE
[] = {BKQDA
, BEQDA
, VIQDA
, VOQDA
, HCCAQDA
, CQDA
, MQDA
, HQDA
, BQDA
};
948 void rtl8192_tx_enable(struct net_device
*dev
)
950 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
952 for (i
= 0; i
< MAX_TX_QUEUE_COUNT
; i
++)
953 write_nic_dword(dev
, TX_DESC_BASE
[i
], priv
->tx_ring
[i
].dma
);
955 ieee80211_reset_queue(priv
->ieee80211
);
959 static void rtl8192_free_rx_ring(struct net_device
*dev
)
961 struct r8192_priv
*priv
= ieee80211_priv(dev
);
964 for (i
= 0; i
< priv
->rxringcount
; i
++) {
965 struct sk_buff
*skb
= priv
->rx_buf
[i
];
969 pci_unmap_single(priv
->pdev
,
970 *((dma_addr_t
*)skb
->cb
),
971 priv
->rxbuffersize
, PCI_DMA_FROMDEVICE
);
975 pci_free_consistent(priv
->pdev
, sizeof(*priv
->rx_ring
) * priv
->rxringcount
,
976 priv
->rx_ring
, priv
->rx_ring_dma
);
977 priv
->rx_ring
= NULL
;
980 static void rtl8192_free_tx_ring(struct net_device
*dev
, unsigned int prio
)
982 struct r8192_priv
*priv
= ieee80211_priv(dev
);
983 struct rtl8192_tx_ring
*ring
= &priv
->tx_ring
[prio
];
985 while (skb_queue_len(&ring
->queue
)) {
986 tx_desc_819x_pci
*entry
= &ring
->desc
[ring
->idx
];
987 struct sk_buff
*skb
= __skb_dequeue(&ring
->queue
);
989 pci_unmap_single(priv
->pdev
, le32_to_cpu(entry
->TxBuffAddr
),
990 skb
->len
, PCI_DMA_TODEVICE
);
992 ring
->idx
= (ring
->idx
+ 1) % ring
->entries
;
995 pci_free_consistent(priv
->pdev
, sizeof(*ring
->desc
)*ring
->entries
,
996 ring
->desc
, ring
->dma
);
1001 static void rtl8192_beacon_disable(struct net_device
*dev
)
1003 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
1006 reg
= read_nic_dword(priv
->ieee80211
->dev
,INTA_MASK
);
1008 /* disable Beacon realted interrupt signal */
1009 reg
&= ~(IMR_BcnInt
| IMR_BcnInt
| IMR_TBDOK
| IMR_TBDER
);
1010 write_nic_dword(priv
->ieee80211
->dev
, INTA_MASK
, reg
);
1014 void PHY_SetRtl8192eRfOff(struct net_device
* dev
)
1016 //struct r8192_priv *priv = ieee80211_priv(dev);
1018 //disable RF-Chip A/B
1019 rtl8192_setBBreg(dev
, rFPGA0_XA_RFInterfaceOE
, BIT4
, 0x0);
1020 //analog to digital off, for power save
1021 rtl8192_setBBreg(dev
, rFPGA0_AnalogParameter4
, 0x300, 0x0);
1022 //digital to analog off, for power save
1023 rtl8192_setBBreg(dev
, rFPGA0_AnalogParameter1
, 0x18, 0x0);
1025 rtl8192_setBBreg(dev
, rOFDM0_TRxPathEnable
, 0xf, 0x0);
1027 rtl8192_setBBreg(dev
, rOFDM1_TRxPathEnable
, 0xf, 0x0);
1028 //analog to digital part2 off, for power save
1029 rtl8192_setBBreg(dev
, rFPGA0_AnalogParameter1
, 0x60, 0x0);
1030 rtl8192_setBBreg(dev
, rFPGA0_AnalogParameter1
, 0x4, 0x0);
1031 // Analog parameter!!Change bias and Lbus control.
1032 write_nic_byte(dev
, ANAPAR_FOR_8192PciE
, 0x07);
1036 void rtl8192_halt_adapter(struct net_device
*dev
, bool reset
)
1039 struct r8192_priv
*priv
= ieee80211_priv(dev
);
1045 OpMode
= RT_OP_MODE_NO_LINK
;
1046 priv
->ieee80211
->SetHwRegHandler(dev
, HW_VAR_MEDIA_STATUS
, &OpMode
);
1049 if(!priv
->ieee80211
->bSupportRemoteWakeUp
)
1051 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
1052 //priv->ieee80211->SetHwRegHandler(dev, HW_VAR_COMMAND, &u1bTmp ); // Using HW_VAR_COMMAND instead of writing CMDR directly. Rewrited by Annie, 2006-04-07.
1053 write_nic_byte(dev
, CMDR
, u1bTmp
);
1056 cmd
=read_nic_byte(dev
,CMDR
);
1057 write_nic_byte(dev
, CMDR
, cmd
&~ (CR_TE
|CR_RE
));
1064 //PlatformStallExecution(150000);
1068 priv
->bHwRfOffAction
= 2;
1072 // Call MgntActSet_RF_State instead to prevent RF config race condition.
1073 // By Bruce, 2008-01-17.
1075 if(!priv
->ieee80211
->bSupportRemoteWakeUp
)
1077 //MgntActSet_RF_State(Adapter, eRfOff, RF_CHANGE_BY_INIT);
1078 //MgntActSet_RF_State(Adapter, eRfOff, Adapter->MgntInfo.RfOffReason);
1079 //if(Adapter->HardwareType == HARDWARE_TYPE_RTL8190P)
1081 PHY_SetRtl8192eRfOff(dev
);
1083 // 2006.11.30. System reset bit
1084 //priv->ieee80211->GetHwRegHandler(dev, HW_VAR_CPU_RST, (u32*)(&ulRegRead) );
1085 ulRegRead
= read_nic_dword(dev
,CPU_GEN
);
1086 ulRegRead
|=CPU_GEN_SYSTEM_RESET
;
1087 //priv->ieee80211->SetHwRegHandler(dev, HW_VAR_CPU_RST, &ulRegRead);
1088 write_nic_dword(dev
,CPU_GEN
, ulRegRead
);
1092 //2008.06.03 for WOL
1093 write_nic_dword(dev
, WFCRC0
, 0xffffffff);
1094 write_nic_dword(dev
, WFCRC1
, 0xffffffff);
1095 write_nic_dword(dev
, WFCRC2
, 0xffffffff);
1097 //Write PMR register
1098 write_nic_byte(dev
, PMR
, 0x5);
1099 //Disable tx, enanble rx
1100 write_nic_byte(dev
, MacBlkCtrl
, 0xa);
1104 for(i
= 0; i
< MAX_QUEUE_SIZE
; i
++) {
1105 skb_queue_purge(&priv
->ieee80211
->skb_waitQ
[i
]);
1107 for(i
= 0; i
< MAX_QUEUE_SIZE
; i
++) {
1108 skb_queue_purge(&priv
->ieee80211
->skb_aggQ
[i
]);
1111 skb_queue_purge(&priv
->skb_queue
);
1116 static void rtl8192_reset(struct net_device
*dev
)
1118 rtl8192_irq_disable(dev
);
1119 printk("This is RTL819xP Reset procedure\n");
1123 static const u16 rtl_rate
[] = {10,20,55,110,60,90,120,180,240,360,480,540};
1124 inline u16
rtl8192_rate2rate(short rate
)
1126 if (rate
>11) return 0;
1127 return rtl_rate
[rate
];
1133 static void rtl8192_data_hard_stop(struct net_device
*dev
)
1137 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
1138 priv
->dma_poll_mask
|= (1<<TX_DMA_STOP_LOWPRIORITY_SHIFT
);
1139 rtl8192_set_mode(dev
,EPROM_CMD_CONFIG
);
1140 write_nic_byte(dev
,TX_DMA_POLLING
,priv
->dma_poll_mask
);
1141 rtl8192_set_mode(dev
,EPROM_CMD_NORMAL
);
1146 static void rtl8192_data_hard_resume(struct net_device
*dev
)
1150 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
1151 priv
->dma_poll_mask
&= ~(1<<TX_DMA_STOP_LOWPRIORITY_SHIFT
);
1152 rtl8192_set_mode(dev
,EPROM_CMD_CONFIG
);
1153 write_nic_byte(dev
,TX_DMA_POLLING
,priv
->dma_poll_mask
);
1154 rtl8192_set_mode(dev
,EPROM_CMD_NORMAL
);
1158 /* this function TX data frames when the ieee80211 stack requires this.
1159 * It checks also if we need to stop the ieee tx queue, eventually do it
1161 static void rtl8192_hard_data_xmit(struct sk_buff
*skb
, struct net_device
*dev
, int rate
)
1163 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
1165 //unsigned long flags;
1166 cb_desc
*tcb_desc
= (cb_desc
*)(skb
->cb
+ MAX_DEV_ADDR_SIZE
);
1167 u8 queue_index
= tcb_desc
->queue_index
;
1168 /* shall not be referred by command packet */
1169 assert(queue_index
!= TXCMD_QUEUE
);
1171 if((priv
->bHwRadioOff
== true)||(!priv
->up
))
1177 //spin_lock_irqsave(&priv->tx_lock,flags);
1179 memcpy((unsigned char *)(skb
->cb
),&dev
,sizeof(dev
));
1181 tcb_desc
->RATRIndex
= 7;
1182 tcb_desc
->bTxDisableRateFallBack
= 1;
1183 tcb_desc
->bTxUseDriverAssingedRate
= 1;
1184 tcb_desc
->bTxEnableFwCalcDur
= 1;
1186 skb_push(skb
, priv
->ieee80211
->tx_headroom
);
1187 ret
= rtl8192_tx(dev
, skb
);
1193 if(queue_index
!=MGNT_QUEUE
) {
1194 priv
->ieee80211
->stats
.tx_bytes
+=(skb
->len
- priv
->ieee80211
->tx_headroom
);
1195 priv
->ieee80211
->stats
.tx_packets
++;
1198 //spin_unlock_irqrestore(&priv->tx_lock,flags);
1204 /* This is a rough attempt to TX a frame
1205 * This is called by the ieee 80211 stack to TX management frames.
1206 * If the ring is full packet are dropped (for data frame the queue
1207 * is stopped before this can happen).
1209 static int rtl8192_hard_start_xmit(struct sk_buff
*skb
,struct net_device
*dev
)
1211 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
1215 //unsigned long flags;
1216 cb_desc
*tcb_desc
= (cb_desc
*)(skb
->cb
+ MAX_DEV_ADDR_SIZE
);
1217 u8 queue_index
= tcb_desc
->queue_index
;
1219 if(queue_index
!= TXCMD_QUEUE
){
1220 if((priv
->bHwRadioOff
== true)||(!priv
->up
))
1227 //spin_lock_irqsave(&priv->tx_lock,flags);
1229 memcpy((unsigned char *)(skb
->cb
),&dev
,sizeof(dev
));
1230 if(queue_index
== TXCMD_QUEUE
) {
1231 // skb_push(skb, USB_HWDESC_HEADER_LEN);
1232 rtl819xE_tx_cmd(dev
, skb
);
1234 //spin_unlock_irqrestore(&priv->tx_lock,flags);
1237 // RT_TRACE(COMP_SEND, "To send management packet\n");
1238 tcb_desc
->RATRIndex
= 7;
1239 tcb_desc
->bTxDisableRateFallBack
= 1;
1240 tcb_desc
->bTxUseDriverAssingedRate
= 1;
1241 tcb_desc
->bTxEnableFwCalcDur
= 1;
1242 skb_push(skb
, priv
->ieee80211
->tx_headroom
);
1243 ret
= rtl8192_tx(dev
, skb
);
1249 // priv->ieee80211->stats.tx_bytes+=skb->len;
1250 // priv->ieee80211->stats.tx_packets++;
1252 //spin_unlock_irqrestore(&priv->tx_lock,flags);
1259 static void rtl8192_tx_isr(struct net_device
*dev
, int prio
)
1261 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
1263 struct rtl8192_tx_ring
*ring
= &priv
->tx_ring
[prio
];
1265 while (skb_queue_len(&ring
->queue
)) {
1266 tx_desc_819x_pci
*entry
= &ring
->desc
[ring
->idx
];
1267 struct sk_buff
*skb
;
1269 /* beacon packet will only use the first descriptor defaultly,
1270 * and the OWN may not be cleared by the hardware
1272 if(prio
!= BEACON_QUEUE
) {
1275 ring
->idx
= (ring
->idx
+ 1) % ring
->entries
;
1278 skb
= __skb_dequeue(&ring
->queue
);
1279 pci_unmap_single(priv
->pdev
, le32_to_cpu(entry
->TxBuffAddr
),
1280 skb
->len
, PCI_DMA_TODEVICE
);
1284 if (prio
== MGNT_QUEUE
){
1285 if (priv
->ieee80211
->ack_tx_to_ieee
){
1286 if (rtl8192_is_tx_queue_empty(dev
)){
1287 priv
->ieee80211
->ack_tx_to_ieee
= 0;
1288 ieee80211_ps_tx_ack(priv
->ieee80211
, 1);
1293 if(prio
!= BEACON_QUEUE
) {
1294 /* try to deal with the pending packets */
1295 tasklet_schedule(&priv
->irq_tx_tasklet
);
1300 static void rtl8192_stop_beacon(struct net_device
*dev
)
1302 //rtl8192_beacon_disable(dev);
1305 static void rtl8192_config_rate(struct net_device
* dev
, u16
* rate_config
)
1307 struct r8192_priv
*priv
= ieee80211_priv(dev
);
1308 struct ieee80211_network
*net
;
1309 u8 i
=0, basic_rate
= 0;
1310 net
= & priv
->ieee80211
->current_network
;
1312 for (i
=0; i
<net
->rates_len
; i
++)
1314 basic_rate
= net
->rates
[i
]&0x7f;
1317 case MGN_1M
: *rate_config
|= RRSR_1M
; break;
1318 case MGN_2M
: *rate_config
|= RRSR_2M
; break;
1319 case MGN_5_5M
: *rate_config
|= RRSR_5_5M
; break;
1320 case MGN_11M
: *rate_config
|= RRSR_11M
; break;
1321 case MGN_6M
: *rate_config
|= RRSR_6M
; break;
1322 case MGN_9M
: *rate_config
|= RRSR_9M
; break;
1323 case MGN_12M
: *rate_config
|= RRSR_12M
; break;
1324 case MGN_18M
: *rate_config
|= RRSR_18M
; break;
1325 case MGN_24M
: *rate_config
|= RRSR_24M
; break;
1326 case MGN_36M
: *rate_config
|= RRSR_36M
; break;
1327 case MGN_48M
: *rate_config
|= RRSR_48M
; break;
1328 case MGN_54M
: *rate_config
|= RRSR_54M
; break;
1331 for (i
=0; i
<net
->rates_ex_len
; i
++)
1333 basic_rate
= net
->rates_ex
[i
]&0x7f;
1336 case MGN_1M
: *rate_config
|= RRSR_1M
; break;
1337 case MGN_2M
: *rate_config
|= RRSR_2M
; break;
1338 case MGN_5_5M
: *rate_config
|= RRSR_5_5M
; break;
1339 case MGN_11M
: *rate_config
|= RRSR_11M
; break;
1340 case MGN_6M
: *rate_config
|= RRSR_6M
; break;
1341 case MGN_9M
: *rate_config
|= RRSR_9M
; break;
1342 case MGN_12M
: *rate_config
|= RRSR_12M
; break;
1343 case MGN_18M
: *rate_config
|= RRSR_18M
; break;
1344 case MGN_24M
: *rate_config
|= RRSR_24M
; break;
1345 case MGN_36M
: *rate_config
|= RRSR_36M
; break;
1346 case MGN_48M
: *rate_config
|= RRSR_48M
; break;
1347 case MGN_54M
: *rate_config
|= RRSR_54M
; break;
1353 #define SHORT_SLOT_TIME 9
1354 #define NON_SHORT_SLOT_TIME 20
1356 static void rtl8192_update_cap(struct net_device
* dev
, u16 cap
)
1359 struct r8192_priv
*priv
= ieee80211_priv(dev
);
1360 struct ieee80211_network
*net
= &priv
->ieee80211
->current_network
;
1361 priv
->short_preamble
= cap
& WLAN_CAPABILITY_SHORT_PREAMBLE
;
1362 tmp
= priv
->basic_rate
;
1363 if (priv
->short_preamble
)
1364 tmp
|= BRSR_AckShortPmb
;
1365 write_nic_dword(dev
, RRSR
, tmp
);
1367 if (net
->mode
& (IEEE_G
|IEEE_N_24G
))
1370 if ((cap
& WLAN_CAPABILITY_SHORT_SLOT
)&&(!priv
->ieee80211
->pHTInfo
->bCurrentRT2RTLongSlotTime
))
1372 slot_time
= SHORT_SLOT_TIME
;
1374 else //long slot time
1375 slot_time
= NON_SHORT_SLOT_TIME
;
1376 priv
->slot_time
= slot_time
;
1377 write_nic_byte(dev
, SLOT_TIME
, slot_time
);
1382 static void rtl8192_net_update(struct net_device
*dev
)
1385 struct r8192_priv
*priv
= ieee80211_priv(dev
);
1386 struct ieee80211_network
*net
;
1387 u16 BcnTimeCfg
= 0, BcnCW
= 6, BcnIFS
= 0xf;
1388 u16 rate_config
= 0;
1389 net
= &priv
->ieee80211
->current_network
;
1390 //update Basic rate: RR, BRSR
1391 rtl8192_config_rate(dev
, &rate_config
);
1392 // 2007.01.16, by Emily
1393 // Select RRSR (in Legacy-OFDM and CCK)
1394 // For 8190, we select only 24M, 12M, 6M, 11M, 5.5M, 2M, and 1M from the Basic rate.
1395 // We do not use other rates.
1396 priv
->basic_rate
= rate_config
&= 0x15f;
1398 write_nic_dword(dev
,BSSIDR
,((u32
*)net
->bssid
)[0]);
1399 write_nic_word(dev
,BSSIDR
+4,((u16
*)net
->bssid
)[2]);
1402 rtl8192_update_msr(dev
);
1406 // rtl8192_update_cap(dev, net->capability);
1407 if (priv
->ieee80211
->iw_mode
== IW_MODE_ADHOC
)
1409 write_nic_word(dev
, ATIMWND
, 2);
1410 write_nic_word(dev
, BCN_DMATIME
, 256);
1411 write_nic_word(dev
, BCN_INTERVAL
, net
->beacon_interval
);
1412 // write_nic_word(dev, BcnIntTime, 100);
1413 //BIT15 of BCN_DRV_EARLY_INT will indicate whether software beacon or hw beacon is applied.
1414 write_nic_word(dev
, BCN_DRV_EARLY_INT
, 10);
1415 write_nic_byte(dev
, BCN_ERR_THRESH
, 100);
1417 BcnTimeCfg
|= (BcnCW
<<BCN_TCFG_CW_SHIFT
);
1418 // TODO: BcnIFS may required to be changed on ASIC
1419 BcnTimeCfg
|= BcnIFS
<<BCN_TCFG_IFS
;
1421 write_nic_word(dev
, BCN_TCFG
, BcnTimeCfg
);
1427 void rtl819xE_tx_cmd(struct net_device
*dev
, struct sk_buff
*skb
)
1429 struct r8192_priv
*priv
= ieee80211_priv(dev
);
1430 struct rtl8192_tx_ring
*ring
;
1431 tx_desc_819x_pci
*entry
;
1435 unsigned long flags
;
1437 ring
= &priv
->tx_ring
[TXCMD_QUEUE
];
1438 mapping
= pci_map_single(priv
->pdev
, skb
->data
, skb
->len
, PCI_DMA_TODEVICE
);
1440 spin_lock_irqsave(&priv
->irq_th_lock
,flags
);
1441 idx
= (ring
->idx
+ skb_queue_len(&ring
->queue
)) % ring
->entries
;
1442 entry
= &ring
->desc
[idx
];
1444 tcb_desc
= (cb_desc
*)(skb
->cb
+ MAX_DEV_ADDR_SIZE
);
1446 entry
->LINIP
= tcb_desc
->bLastIniPkt
;
1447 entry
->FirstSeg
= 1;//first segment
1448 entry
->LastSeg
= 1; //last segment
1449 if(tcb_desc
->bCmdOrInit
== DESC_PACKET_TYPE_INIT
) {
1450 entry
->CmdInit
= DESC_PACKET_TYPE_INIT
;
1452 entry
->CmdInit
= DESC_PACKET_TYPE_NORMAL
;
1453 entry
->Offset
= sizeof(TX_FWINFO_8190PCI
) + 8;
1454 entry
->PktSize
= (u16
)(tcb_desc
->pkt_size
+ entry
->Offset
);
1455 entry
->QueueSelect
= QSLT_CMD
;
1456 entry
->TxFWInfoSize
= 0x08;
1457 entry
->RATid
= (u8
)DESC_PACKET_TYPE_INIT
;
1459 entry
->TxBufferSize
= skb
->len
;
1460 entry
->TxBuffAddr
= cpu_to_le32(mapping
);
1463 #ifdef JOHN_DUMP_TXDESC
1465 tx_desc_819x_pci
*entry1
= &ring
->desc
[0];
1466 unsigned int *ptr
= (unsigned int *)entry1
;
1467 printk("<Tx descriptor>:\n");
1468 for (i
= 0; i
< 8; i
++)
1469 printk("%8x ", ptr
[i
]);
1473 __skb_queue_tail(&ring
->queue
, skb
);
1474 spin_unlock_irqrestore(&priv
->irq_th_lock
,flags
);
1476 write_nic_byte(dev
, TPPoll
, TPPoll_CQ
);
1482 * Mapping Software/Hardware descriptor queue id to "Queue Select Field"
1483 * in TxFwInfo data structure
1484 * 2006.10.30 by Emily
1486 * \param QUEUEID Software Queue
1488 static u8
MapHwQueueToFirmwareQueue(u8 QueueID
)
1490 u8 QueueSelect
= 0x0; //defualt set to
1494 QueueSelect
= QSLT_BE
; //or QSelect = pTcb->priority;
1498 QueueSelect
= QSLT_BK
; //or QSelect = pTcb->priority;
1502 QueueSelect
= QSLT_VO
; //or QSelect = pTcb->priority;
1506 QueueSelect
= QSLT_VI
; //or QSelect = pTcb->priority;
1509 QueueSelect
= QSLT_MGNT
;
1513 QueueSelect
= QSLT_BEACON
;
1516 // TODO: 2006.10.30 mark other queue selection until we verify it is OK
1517 // TODO: Remove Assertions
1518 //#if (RTL819X_FPGA_VER & RTL819X_FPGA_GUANGAN_070502)
1520 QueueSelect
= QSLT_CMD
;
1524 //QueueSelect = QSLT_HIGH;
1528 RT_TRACE(COMP_ERR
, "TransmitTCB(): Impossible Queue Selection: %d \n", QueueID
);
1534 static u8
MRateToHwRate8190Pci(u8 rate
)
1536 u8 ret
= DESC90_RATE1M
;
1539 case MGN_1M
: ret
= DESC90_RATE1M
; break;
1540 case MGN_2M
: ret
= DESC90_RATE2M
; break;
1541 case MGN_5_5M
: ret
= DESC90_RATE5_5M
; break;
1542 case MGN_11M
: ret
= DESC90_RATE11M
; break;
1543 case MGN_6M
: ret
= DESC90_RATE6M
; break;
1544 case MGN_9M
: ret
= DESC90_RATE9M
; break;
1545 case MGN_12M
: ret
= DESC90_RATE12M
; break;
1546 case MGN_18M
: ret
= DESC90_RATE18M
; break;
1547 case MGN_24M
: ret
= DESC90_RATE24M
; break;
1548 case MGN_36M
: ret
= DESC90_RATE36M
; break;
1549 case MGN_48M
: ret
= DESC90_RATE48M
; break;
1550 case MGN_54M
: ret
= DESC90_RATE54M
; break;
1552 // HT rate since here
1553 case MGN_MCS0
: ret
= DESC90_RATEMCS0
; break;
1554 case MGN_MCS1
: ret
= DESC90_RATEMCS1
; break;
1555 case MGN_MCS2
: ret
= DESC90_RATEMCS2
; break;
1556 case MGN_MCS3
: ret
= DESC90_RATEMCS3
; break;
1557 case MGN_MCS4
: ret
= DESC90_RATEMCS4
; break;
1558 case MGN_MCS5
: ret
= DESC90_RATEMCS5
; break;
1559 case MGN_MCS6
: ret
= DESC90_RATEMCS6
; break;
1560 case MGN_MCS7
: ret
= DESC90_RATEMCS7
; break;
1561 case MGN_MCS8
: ret
= DESC90_RATEMCS8
; break;
1562 case MGN_MCS9
: ret
= DESC90_RATEMCS9
; break;
1563 case MGN_MCS10
: ret
= DESC90_RATEMCS10
; break;
1564 case MGN_MCS11
: ret
= DESC90_RATEMCS11
; break;
1565 case MGN_MCS12
: ret
= DESC90_RATEMCS12
; break;
1566 case MGN_MCS13
: ret
= DESC90_RATEMCS13
; break;
1567 case MGN_MCS14
: ret
= DESC90_RATEMCS14
; break;
1568 case MGN_MCS15
: ret
= DESC90_RATEMCS15
; break;
1569 case (0x80|0x20): ret
= DESC90_RATEMCS32
; break;
1577 static u8
QueryIsShort(u8 TxHT
, u8 TxRate
, cb_desc
*tcb_desc
)
1581 tmp_Short
= (TxHT
==1)?((tcb_desc
->bUseShortGI
)?1:0):((tcb_desc
->bUseShortPreamble
)?1:0);
1583 if(TxHT
==1 && TxRate
!= DESC90_RATEMCS15
)
1590 * The tx procedure is just as following,
1591 * skb->cb will contain all the following information,
1592 * priority, morefrag, rate, &dev.
1594 short rtl8192_tx(struct net_device
*dev
, struct sk_buff
* skb
)
1596 struct r8192_priv
*priv
= ieee80211_priv(dev
);
1597 struct rtl8192_tx_ring
*ring
;
1598 unsigned long flags
;
1599 cb_desc
*tcb_desc
= (cb_desc
*)(skb
->cb
+ MAX_DEV_ADDR_SIZE
);
1600 tx_desc_819x_pci
*pdesc
= NULL
;
1601 TX_FWINFO_8190PCI
*pTxFwInfo
= NULL
;
1603 bool multi_addr
=false,broad_addr
=false,uni_addr
=false;
1604 u8
* pda_addr
= NULL
;
1607 if(priv
->bdisable_nic
){
1608 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
);
1613 priv
->ieee80211
->bAwakePktSent
= true;
1616 mapping
= pci_map_single(priv
->pdev
, skb
->data
, skb
->len
, PCI_DMA_TODEVICE
);
1617 /* collect the tx packets statitcs */
1618 pda_addr
= ((u8
*)skb
->data
) + sizeof(TX_FWINFO_8190PCI
);
1619 if(is_multicast_ether_addr(pda_addr
))
1621 else if(is_broadcast_ether_addr(pda_addr
))
1627 priv
->stats
.txbytesunicast
+= (u8
)(skb
->len
) - sizeof(TX_FWINFO_8190PCI
);
1629 priv
->stats
.txbytesmulticast
+=(u8
)(skb
->len
) - sizeof(TX_FWINFO_8190PCI
);
1631 priv
->stats
.txbytesbroadcast
+= (u8
)(skb
->len
) - sizeof(TX_FWINFO_8190PCI
);
1633 /* fill tx firmware */
1634 pTxFwInfo
= (PTX_FWINFO_8190PCI
)skb
->data
;
1635 memset(pTxFwInfo
,0,sizeof(TX_FWINFO_8190PCI
));
1636 pTxFwInfo
->TxHT
= (tcb_desc
->data_rate
&0x80)?1:0;
1637 pTxFwInfo
->TxRate
= MRateToHwRate8190Pci((u8
)tcb_desc
->data_rate
);
1638 pTxFwInfo
->EnableCPUDur
= tcb_desc
->bTxEnableFwCalcDur
;
1639 pTxFwInfo
->Short
= QueryIsShort(pTxFwInfo
->TxHT
, pTxFwInfo
->TxRate
, tcb_desc
);
1641 /* Aggregation related */
1642 if(tcb_desc
->bAMPDUEnable
) {
1643 pTxFwInfo
->AllowAggregation
= 1;
1644 pTxFwInfo
->RxMF
= tcb_desc
->ampdu_factor
;
1645 pTxFwInfo
->RxAMD
= tcb_desc
->ampdu_density
;
1647 pTxFwInfo
->AllowAggregation
= 0;
1648 pTxFwInfo
->RxMF
= 0;
1649 pTxFwInfo
->RxAMD
= 0;
1653 // Protection mode related
1655 pTxFwInfo
->RtsEnable
= (tcb_desc
->bRTSEnable
)?1:0;
1656 pTxFwInfo
->CtsEnable
= (tcb_desc
->bCTSEnable
)?1:0;
1657 pTxFwInfo
->RtsSTBC
= (tcb_desc
->bRTSSTBC
)?1:0;
1658 pTxFwInfo
->RtsHT
= (tcb_desc
->rts_rate
&0x80)?1:0;
1659 pTxFwInfo
->RtsRate
= MRateToHwRate8190Pci((u8
)tcb_desc
->rts_rate
);
1660 pTxFwInfo
->RtsBandwidth
= 0;
1661 pTxFwInfo
->RtsSubcarrier
= tcb_desc
->RTSSC
;
1662 pTxFwInfo
->RtsShort
= (pTxFwInfo
->RtsHT
==0)?(tcb_desc
->bRTSUseShortPreamble
?1:0):(tcb_desc
->bRTSUseShortGI
?1:0);
1664 // Set Bandwidth and sub-channel settings.
1666 if(priv
->CurrentChannelBW
== HT_CHANNEL_WIDTH_20_40
)
1668 if(tcb_desc
->bPacketBW
)
1670 pTxFwInfo
->TxBandwidth
= 1;
1672 pTxFwInfo
->TxSubCarrier
= 3;
1674 pTxFwInfo
->TxSubCarrier
= 0; //By SD3's Jerry suggestion, use duplicated mode, cosa 04012008
1679 pTxFwInfo
->TxBandwidth
= 0;
1680 pTxFwInfo
->TxSubCarrier
= priv
->nCur40MhzPrimeSC
;
1683 pTxFwInfo
->TxBandwidth
= 0;
1684 pTxFwInfo
->TxSubCarrier
= 0;
1689 /* 2007/07/25 MH Copy current TX FW info.*/
1690 memcpy((void*)(&Tmp_TxFwInfo
), (void*)(pTxFwInfo
), sizeof(TX_FWINFO_8190PCI
));
1691 printk("&&&&&&&&&&&&&&&&&&&&&&====>print out fwinf\n");
1692 printk("===>enable fwcacl:%d\n", Tmp_TxFwInfo
.EnableCPUDur
);
1693 printk("===>RTS STBC:%d\n", Tmp_TxFwInfo
.RtsSTBC
);
1694 printk("===>RTS Subcarrier:%d\n", Tmp_TxFwInfo
.RtsSubcarrier
);
1695 printk("===>Allow Aggregation:%d\n", Tmp_TxFwInfo
.AllowAggregation
);
1696 printk("===>TX HT bit:%d\n", Tmp_TxFwInfo
.TxHT
);
1697 printk("===>Tx rate:%d\n", Tmp_TxFwInfo
.TxRate
);
1698 printk("===>Received AMPDU Density:%d\n", Tmp_TxFwInfo
.RxAMD
);
1699 printk("===>Received MPDU Factor:%d\n", Tmp_TxFwInfo
.RxMF
);
1700 printk("===>TxBandwidth:%d\n", Tmp_TxFwInfo
.TxBandwidth
);
1701 printk("===>TxSubCarrier:%d\n", Tmp_TxFwInfo
.TxSubCarrier
);
1703 printk("<=====**********************out of print\n");
1706 spin_lock_irqsave(&priv
->irq_th_lock
,flags
);
1707 ring
= &priv
->tx_ring
[tcb_desc
->queue_index
];
1708 if (tcb_desc
->queue_index
!= BEACON_QUEUE
) {
1709 idx
= (ring
->idx
+ skb_queue_len(&ring
->queue
)) % ring
->entries
;
1714 pdesc
= &ring
->desc
[idx
];
1715 if((pdesc
->OWN
== 1) && (tcb_desc
->queue_index
!= BEACON_QUEUE
)) {
1716 RT_TRACE(COMP_ERR
,"No more TX desc@%d, ring->idx = %d,idx = %d,%x", \
1717 tcb_desc
->queue_index
,ring
->idx
, idx
,skb
->len
);
1718 spin_unlock_irqrestore(&priv
->irq_th_lock
,flags
);
1722 /* fill tx descriptor */
1723 memset((u8
*)pdesc
,0,12);
1727 pdesc
->Offset
= sizeof(TX_FWINFO_8190PCI
) + 8; //We must add 8!! Emily
1728 pdesc
->PktSize
= (u16
)skb
->len
-sizeof(TX_FWINFO_8190PCI
);
1732 pdesc
->RATid
= tcb_desc
->RATRIndex
;
1736 pdesc
->SecType
= 0x0;
1737 if (tcb_desc
->bHwSec
) {
1738 switch (priv
->ieee80211
->pairwise_key_type
) {
1739 case KEY_TYPE_WEP40
:
1740 case KEY_TYPE_WEP104
:
1741 pdesc
->SecType
= 0x1;
1745 pdesc
->SecType
= 0x2;
1749 pdesc
->SecType
= 0x3;
1753 pdesc
->SecType
= 0x0;
1764 pdesc
->QueueSelect
= MapHwQueueToFirmwareQueue(tcb_desc
->queue_index
);
1765 pdesc
->TxFWInfoSize
= sizeof(TX_FWINFO_8190PCI
);
1767 pdesc
->DISFB
= tcb_desc
->bTxDisableRateFallBack
;
1768 pdesc
->USERATE
= tcb_desc
->bTxUseDriverAssingedRate
;
1772 pdesc
->TxBufferSize
= skb
->len
;
1774 pdesc
->TxBuffAddr
= cpu_to_le32(mapping
);
1775 __skb_queue_tail(&ring
->queue
, skb
);
1777 spin_unlock_irqrestore(&priv
->irq_th_lock
,flags
);
1778 dev
->trans_start
= jiffies
;
1779 write_nic_word(dev
,TPPoll
,0x01<<tcb_desc
->queue_index
);
1783 static short rtl8192_alloc_rx_desc_ring(struct net_device
*dev
)
1785 struct r8192_priv
*priv
= ieee80211_priv(dev
);
1786 rx_desc_819x_pci
*entry
= NULL
;
1789 priv
->rx_ring
= pci_alloc_consistent(priv
->pdev
,
1790 sizeof(*priv
->rx_ring
) * priv
->rxringcount
, &priv
->rx_ring_dma
);
1792 if (!priv
->rx_ring
|| (unsigned long)priv
->rx_ring
& 0xFF) {
1793 RT_TRACE(COMP_ERR
,"Cannot allocate RX ring\n");
1797 memset(priv
->rx_ring
, 0, sizeof(*priv
->rx_ring
) * priv
->rxringcount
);
1800 for (i
= 0; i
< priv
->rxringcount
; i
++) {
1801 struct sk_buff
*skb
= dev_alloc_skb(priv
->rxbuffersize
);
1802 dma_addr_t
*mapping
;
1803 entry
= &priv
->rx_ring
[i
];
1806 priv
->rx_buf
[i
] = skb
;
1807 mapping
= (dma_addr_t
*)skb
->cb
;
1808 *mapping
= pci_map_single(priv
->pdev
, skb_tail_pointer(skb
),
1809 priv
->rxbuffersize
, PCI_DMA_FROMDEVICE
);
1811 entry
->BufferAddress
= cpu_to_le32(*mapping
);
1813 entry
->Length
= priv
->rxbuffersize
;
1821 static int rtl8192_alloc_tx_desc_ring(struct net_device
*dev
,
1822 unsigned int prio
, unsigned int entries
)
1824 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
1825 tx_desc_819x_pci
*ring
;
1829 ring
= pci_alloc_consistent(priv
->pdev
, sizeof(*ring
) * entries
, &dma
);
1830 if (!ring
|| (unsigned long)ring
& 0xFF) {
1831 RT_TRACE(COMP_ERR
, "Cannot allocate TX ring (prio = %d)\n", prio
);
1835 memset(ring
, 0, sizeof(*ring
)*entries
);
1836 priv
->tx_ring
[prio
].desc
= ring
;
1837 priv
->tx_ring
[prio
].dma
= dma
;
1838 priv
->tx_ring
[prio
].idx
= 0;
1839 priv
->tx_ring
[prio
].entries
= entries
;
1840 skb_queue_head_init(&priv
->tx_ring
[prio
].queue
);
1842 for (i
= 0; i
< entries
; i
++)
1843 ring
[i
].NextDescAddress
=
1844 cpu_to_le32((u32
)dma
+ ((i
+ 1) % entries
) * sizeof(*ring
));
1850 static short rtl8192_pci_initdescring(struct net_device
*dev
)
1854 struct r8192_priv
*priv
= ieee80211_priv(dev
);
1856 ret
= rtl8192_alloc_rx_desc_ring(dev
);
1862 /* general process for other queue */
1863 for (i
= 0; i
< MAX_TX_QUEUE_COUNT
; i
++) {
1864 ret
= rtl8192_alloc_tx_desc_ring(dev
, i
, priv
->txringcount
);
1866 goto err_free_rings
;
1870 /* specific process for hardware beacon process */
1871 ret
= rtl8192_alloc_tx_desc_ring(dev
, MAX_TX_QUEUE_COUNT
- 1, 2);
1873 goto err_free_rings
;
1879 rtl8192_free_rx_ring(dev
);
1880 for (i
= 0; i
< MAX_TX_QUEUE_COUNT
; i
++)
1881 if (priv
->tx_ring
[i
].desc
)
1882 rtl8192_free_tx_ring(dev
, i
);
1886 static void rtl8192_pci_resetdescring(struct net_device
*dev
)
1888 struct r8192_priv
*priv
= ieee80211_priv(dev
);
1891 /* force the rx_idx to the first one */
1893 rx_desc_819x_pci
*entry
= NULL
;
1894 for (i
= 0; i
< priv
->rxringcount
; i
++) {
1895 entry
= &priv
->rx_ring
[i
];
1901 /* after reset, release previous pending packet, and force the
1902 * tx idx to the first one */
1903 for (i
= 0; i
< MAX_TX_QUEUE_COUNT
; i
++) {
1904 if (priv
->tx_ring
[i
].desc
) {
1905 struct rtl8192_tx_ring
*ring
= &priv
->tx_ring
[i
];
1907 while (skb_queue_len(&ring
->queue
)) {
1908 tx_desc_819x_pci
*entry
= &ring
->desc
[ring
->idx
];
1909 struct sk_buff
*skb
= __skb_dequeue(&ring
->queue
);
1911 pci_unmap_single(priv
->pdev
, le32_to_cpu(entry
->TxBuffAddr
),
1912 skb
->len
, PCI_DMA_TODEVICE
);
1914 ring
->idx
= (ring
->idx
+ 1) % ring
->entries
;
1922 extern void rtl8192_update_ratr_table(struct net_device
* dev
);
1923 static void rtl8192_link_change(struct net_device
*dev
)
1927 struct r8192_priv
*priv
= ieee80211_priv(dev
);
1928 struct ieee80211_device
* ieee
= priv
->ieee80211
;
1929 //write_nic_word(dev, BCN_INTR_ITV, net->beacon_interval);
1930 if (ieee
->state
== IEEE80211_LINKED
)
1932 rtl8192_net_update(dev
);
1933 rtl8192_update_ratr_table(dev
);
1935 //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
1936 if ((KEY_TYPE_WEP40
== ieee
->pairwise_key_type
) || (KEY_TYPE_WEP104
== ieee
->pairwise_key_type
))
1937 EnableHWSecurityConfig8192(dev
);
1942 write_nic_byte(dev
, 0x173, 0);
1944 /*update timing params*/
1945 //rtl8192_set_chan(dev, priv->chan);
1947 rtl8192_update_msr(dev
);
1949 // 2007/10/16 MH MAC Will update TSF according to all received beacon, so we have
1950 // // To set CBSSID bit when link with any AP or STA.
1951 if (ieee
->iw_mode
== IW_MODE_INFRA
|| ieee
->iw_mode
== IW_MODE_ADHOC
)
1954 reg
= read_nic_dword(dev
, RCR
);
1955 if (priv
->ieee80211
->state
== IEEE80211_LINKED
)
1956 priv
->ReceiveConfig
= reg
|= RCR_CBSSID
;
1958 priv
->ReceiveConfig
= reg
&= ~RCR_CBSSID
;
1959 write_nic_dword(dev
, RCR
, reg
);
1965 static struct ieee80211_qos_parameters def_qos_parameters
= {
1966 {3,3,3,3},/* cw_min */
1967 {7,7,7,7},/* cw_max */
1968 {2,2,2,2},/* aifs */
1969 {0,0,0,0},/* flags */
1970 {0,0,0,0} /* tx_op_limit */
1973 static void rtl8192_update_beacon(struct work_struct
* work
)
1975 struct r8192_priv
*priv
= container_of(work
, struct r8192_priv
, update_beacon_wq
.work
);
1976 struct net_device
*dev
= priv
->ieee80211
->dev
;
1977 struct ieee80211_device
* ieee
= priv
->ieee80211
;
1978 struct ieee80211_network
* net
= &ieee
->current_network
;
1980 if (ieee
->pHTInfo
->bCurrentHTSupport
)
1981 HTUpdateSelfAndPeerSetting(ieee
, net
);
1982 ieee
->pHTInfo
->bCurrentRT2RTLongSlotTime
= net
->bssht
.bdRT2RTLongSlotTime
;
1983 rtl8192_update_cap(dev
, net
->capability
);
1986 * background support to run QoS activate functionality
1988 static const int WDCAPARA_ADD
[] = {EDCAPARA_BE
,EDCAPARA_BK
,EDCAPARA_VI
,EDCAPARA_VO
};
1989 static void rtl8192_qos_activate(struct work_struct
* work
)
1991 struct r8192_priv
*priv
= container_of(work
, struct r8192_priv
, qos_activate
);
1992 struct net_device
*dev
= priv
->ieee80211
->dev
;
1993 struct ieee80211_qos_parameters
*qos_parameters
= &priv
->ieee80211
->current_network
.qos_data
.parameters
;
1994 u8 mode
= priv
->ieee80211
->current_network
.mode
;
1995 // u32 size = sizeof(struct ieee80211_qos_parameters);
2000 mutex_lock(&priv
->mutex
);
2001 if(priv
->ieee80211
->state
!= IEEE80211_LINKED
)
2003 RT_TRACE(COMP_QOS
,"qos active process with associate response received\n");
2004 /* It better set slot time at first */
2005 /* For we just support b/g mode at present, let the slot time at 9/20 selection */
2006 /* update the ac parameter to related registers */
2007 for(i
= 0; i
< QOS_QUEUE_NUM
; i
++) {
2008 //Mode G/A: slotTimeTimer = 9; Mode B: 20
2009 u1bAIFS
= qos_parameters
->aifs
[i
] * ((mode
&(IEEE_G
|IEEE_N_24G
)) ?9:20) + aSifsTime
;
2010 u4bAcParam
= ((((u32
)(qos_parameters
->tx_op_limit
[i
]))<< AC_PARAM_TXOP_LIMIT_OFFSET
)|
2011 (((u32
)(qos_parameters
->cw_max
[i
]))<< AC_PARAM_ECW_MAX_OFFSET
)|
2012 (((u32
)(qos_parameters
->cw_min
[i
]))<< AC_PARAM_ECW_MIN_OFFSET
)|
2013 ((u32
)u1bAIFS
<< AC_PARAM_AIFS_OFFSET
));
2014 //printk("===>u4bAcParam:%x, ", u4bAcParam);
2015 write_nic_dword(dev
, WDCAPARA_ADD
[i
], u4bAcParam
);
2016 //write_nic_dword(dev, WDCAPARA_ADD[i], 0x005e4332);
2020 mutex_unlock(&priv
->mutex
);
2023 static int rtl8192_qos_handle_probe_response(struct r8192_priv
*priv
,
2025 struct ieee80211_network
*network
)
2028 u32 size
= sizeof(struct ieee80211_qos_parameters
);
2030 if(priv
->ieee80211
->state
!=IEEE80211_LINKED
)
2033 if ((priv
->ieee80211
->iw_mode
!= IW_MODE_INFRA
))
2036 if (network
->flags
& NETWORK_HAS_QOS_MASK
) {
2037 if (active_network
&&
2038 (network
->flags
& NETWORK_HAS_QOS_PARAMETERS
))
2039 network
->qos_data
.active
= network
->qos_data
.supported
;
2041 if ((network
->qos_data
.active
== 1) && (active_network
== 1) &&
2042 (network
->flags
& NETWORK_HAS_QOS_PARAMETERS
) &&
2043 (network
->qos_data
.old_param_count
!=
2044 network
->qos_data
.param_count
)) {
2045 network
->qos_data
.old_param_count
=
2046 network
->qos_data
.param_count
;
2047 queue_work(priv
->priv_wq
, &priv
->qos_activate
);
2048 RT_TRACE (COMP_QOS
, "QoS parameters change call "
2052 memcpy(&priv
->ieee80211
->current_network
.qos_data
.parameters
,\
2053 &def_qos_parameters
, size
);
2055 if ((network
->qos_data
.active
== 1) && (active_network
== 1)) {
2056 queue_work(priv
->priv_wq
, &priv
->qos_activate
);
2057 RT_TRACE(COMP_QOS
, "QoS was disabled call qos_activate \n");
2059 network
->qos_data
.active
= 0;
2060 network
->qos_data
.supported
= 0;
2066 /* handle manage frame frame beacon and probe response */
2067 static int rtl8192_handle_beacon(struct net_device
* dev
,
2068 struct ieee80211_beacon
* beacon
,
2069 struct ieee80211_network
* network
)
2071 struct r8192_priv
*priv
= ieee80211_priv(dev
);
2073 rtl8192_qos_handle_probe_response(priv
,1,network
);
2075 queue_delayed_work(priv
->priv_wq
, &priv
->update_beacon_wq
, 0);
2081 * handling the beaconing responses. if we get different QoS setting
2082 * off the network from the associated setting, adjust the QoS
2085 static int rtl8192_qos_association_resp(struct r8192_priv
*priv
,
2086 struct ieee80211_network
*network
)
2089 unsigned long flags
;
2090 u32 size
= sizeof(struct ieee80211_qos_parameters
);
2091 int set_qos_param
= 0;
2093 if ((priv
== NULL
) || (network
== NULL
))
2096 if(priv
->ieee80211
->state
!=IEEE80211_LINKED
)
2099 if ((priv
->ieee80211
->iw_mode
!= IW_MODE_INFRA
))
2102 spin_lock_irqsave(&priv
->ieee80211
->lock
, flags
);
2103 if(network
->flags
& NETWORK_HAS_QOS_PARAMETERS
) {
2104 memcpy(&priv
->ieee80211
->current_network
.qos_data
.parameters
,\
2105 &network
->qos_data
.parameters
,\
2106 sizeof(struct ieee80211_qos_parameters
));
2107 priv
->ieee80211
->current_network
.qos_data
.active
= 1;
2109 if((priv
->ieee80211
->current_network
.qos_data
.param_count
!= \
2110 network
->qos_data
.param_count
))
2114 /* update qos parameter for current network */
2115 priv
->ieee80211
->current_network
.qos_data
.old_param_count
= \
2116 priv
->ieee80211
->current_network
.qos_data
.param_count
;
2117 priv
->ieee80211
->current_network
.qos_data
.param_count
= \
2118 network
->qos_data
.param_count
;
2121 memcpy(&priv
->ieee80211
->current_network
.qos_data
.parameters
,\
2122 &def_qos_parameters
, size
);
2123 priv
->ieee80211
->current_network
.qos_data
.active
= 0;
2124 priv
->ieee80211
->current_network
.qos_data
.supported
= 0;
2128 spin_unlock_irqrestore(&priv
->ieee80211
->lock
, flags
);
2130 RT_TRACE(COMP_QOS
, "%s: network->flags = %d,%d\n",__FUNCTION__
,network
->flags
,priv
->ieee80211
->current_network
.qos_data
.active
);
2131 if (set_qos_param
== 1)
2132 queue_work(priv
->priv_wq
, &priv
->qos_activate
);
2138 static int rtl8192_handle_assoc_response(struct net_device
*dev
,
2139 struct ieee80211_assoc_response_frame
*resp
,
2140 struct ieee80211_network
*network
)
2142 struct r8192_priv
*priv
= ieee80211_priv(dev
);
2143 rtl8192_qos_association_resp(priv
, network
);
2148 //updateRATRTabel for MCS only. Basic rate is not implement.
2149 void rtl8192_update_ratr_table(struct net_device
* dev
)
2150 // POCTET_STRING posLegacyRate,
2152 // PRT_WLAN_STA pEntry)
2154 struct r8192_priv
* priv
= ieee80211_priv(dev
);
2155 struct ieee80211_device
* ieee
= priv
->ieee80211
;
2156 u8
* pMcsRate
= ieee
->dot11HTOperationalRateSet
;
2157 //struct ieee80211_network *net = &ieee->current_network;
2161 rtl8192_config_rate(dev
, (u16
*)(&ratr_value
));
2162 ratr_value
|= (*(u16
*)(pMcsRate
)) << 12;
2163 // switch (net->mode)
2167 ratr_value
&= 0x00000FF0;
2170 ratr_value
&= 0x0000000F;
2173 ratr_value
&= 0x00000FF7;
2177 if (ieee
->pHTInfo
->PeerMimoPs
== 0) //MIMO_PS_STATIC
2178 ratr_value
&= 0x0007F007;
2180 if (priv
->rf_type
== RF_1T2R
)
2181 ratr_value
&= 0x000FF007;
2183 ratr_value
&= 0x0F81F007;
2189 ratr_value
&= 0x0FFFFFFF;
2190 if(ieee
->pHTInfo
->bCurTxBW40MHz
&& ieee
->pHTInfo
->bCurShortGI40MHz
){
2191 ratr_value
|= 0x80000000;
2192 }else if(!ieee
->pHTInfo
->bCurTxBW40MHz
&& ieee
->pHTInfo
->bCurShortGI20MHz
){
2193 ratr_value
|= 0x80000000;
2195 write_nic_dword(dev
, RATR0
+rate_index
*4, ratr_value
);
2196 write_nic_byte(dev
, UFWP
, 1);
2200 static u8 ccmp_ie
[4] = {0x00,0x50,0xf2,0x04};
2201 static u8 ccmp_rsn_ie
[4] = {0x00, 0x0f, 0xac, 0x04};
2204 static bool GetNmodeSupportBySecCfg8190Pci(struct net_device
*dev
)
2208 struct r8192_priv
*priv
= ieee80211_priv(dev
);
2209 struct ieee80211_device
*ieee
= priv
->ieee80211
;
2210 if (ieee
->rtllib_ap_sec_type
&&
2211 (ieee
->rtllib_ap_sec_type(ieee
)&(SEC_ALG_WEP
|SEC_ALG_TKIP
))) {
2217 struct r8192_priv
* priv
= ieee80211_priv(dev
);
2218 struct ieee80211_device
* ieee
= priv
->ieee80211
;
2219 int wpa_ie_len
= ieee
->wpa_ie_len
;
2220 struct ieee80211_crypt_data
* crypt
;
2223 crypt
= ieee
->crypt
[ieee
->tx_keyidx
];
2224 encrypt
= (ieee
->current_network
.capability
& WLAN_CAPABILITY_PRIVACY
) || (ieee
->host_encrypt
&& crypt
&& crypt
->ops
&& (0 == strcmp(crypt
->ops
->name
,"WEP")));
2227 if(encrypt
&& (wpa_ie_len
== 0)) {
2228 /* wep encryption, no N mode setting */
2230 // } else if((wpa_ie_len != 0)&&(memcmp(&(ieee->wpa_ie[14]),ccmp_ie,4))) {
2231 } else if((wpa_ie_len
!= 0)) {
2232 /* parse pairwise key type */
2233 //if((pairwisekey = WEP40)||(pairwisekey = WEP104)||(pairwisekey = TKIP))
2234 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))))
2239 //RT_TRACE(COMP_ERR,"In %s The GroupEncAlgorithm is [4]\n",__FUNCTION__ );
2247 static void rtl8192_refresh_supportrate(struct r8192_priv
* priv
)
2249 struct ieee80211_device
* ieee
= priv
->ieee80211
;
2250 //we donot consider set support rate for ABG mode, only HT MCS rate is set here.
2251 if (ieee
->mode
== WIRELESS_MODE_N_24G
|| ieee
->mode
== WIRELESS_MODE_N_5G
)
2253 memcpy(ieee
->Regdot11HTOperationalRateSet
, ieee
->RegHTSuppRateSet
, 16);
2254 //RT_DEBUG_DATA(COMP_INIT, ieee->RegHTSuppRateSet, 16);
2255 //RT_DEBUG_DATA(COMP_INIT, ieee->Regdot11HTOperationalRateSet, 16);
2258 memset(ieee
->Regdot11HTOperationalRateSet
, 0, 16);
2262 static u8
rtl8192_getSupportedWireleeMode(struct net_device
*dev
)
2264 struct r8192_priv
*priv
= ieee80211_priv(dev
);
2266 switch(priv
->rf_chip
)
2271 ret
= (WIRELESS_MODE_N_24G
|WIRELESS_MODE_G
|WIRELESS_MODE_B
);
2274 ret
= (WIRELESS_MODE_A
|WIRELESS_MODE_N_5G
);
2277 ret
= WIRELESS_MODE_B
;
2283 static void rtl8192_SetWirelessMode(struct net_device
* dev
, u8 wireless_mode
)
2285 struct r8192_priv
*priv
= ieee80211_priv(dev
);
2286 u8 bSupportMode
= rtl8192_getSupportedWireleeMode(dev
);
2289 if ((wireless_mode
== WIRELESS_MODE_AUTO
) || ((wireless_mode
&bSupportMode
)==0))
2291 if(bSupportMode
& WIRELESS_MODE_N_24G
)
2293 wireless_mode
= WIRELESS_MODE_N_24G
;
2295 else if(bSupportMode
& WIRELESS_MODE_N_5G
)
2297 wireless_mode
= WIRELESS_MODE_N_5G
;
2299 else if((bSupportMode
& WIRELESS_MODE_A
))
2301 wireless_mode
= WIRELESS_MODE_A
;
2303 else if((bSupportMode
& WIRELESS_MODE_G
))
2305 wireless_mode
= WIRELESS_MODE_G
;
2307 else if((bSupportMode
& WIRELESS_MODE_B
))
2309 wireless_mode
= WIRELESS_MODE_B
;
2312 RT_TRACE(COMP_ERR
, "%s(), No valid wireless mode supported, SupportedWirelessMode(%x)!!!\n", __FUNCTION__
,bSupportMode
);
2313 wireless_mode
= WIRELESS_MODE_B
;
2316 #ifdef TO_DO_LIST //// TODO: this function doesn't work well at this time, we should wait for FPGA
2317 ActUpdateChannelAccessSetting( pAdapter
, pHalData
->CurrentWirelessMode
, &pAdapter
->MgntInfo
.Info8185
.ChannelAccessSetting
);
2319 priv
->ieee80211
->mode
= wireless_mode
;
2321 if ((wireless_mode
== WIRELESS_MODE_N_24G
) || (wireless_mode
== WIRELESS_MODE_N_5G
))
2322 priv
->ieee80211
->pHTInfo
->bEnableHT
= 1;
2324 priv
->ieee80211
->pHTInfo
->bEnableHT
= 0;
2325 RT_TRACE(COMP_INIT
, "Current Wireless Mode is %x\n", wireless_mode
);
2326 rtl8192_refresh_supportrate(priv
);
2330 //init priv variables here
2332 static bool GetHalfNmodeSupportByAPs819xPci(struct net_device
* dev
)
2335 struct r8192_priv
* priv
= ieee80211_priv(dev
);
2336 struct ieee80211_device
* ieee
= priv
->ieee80211
;
2338 if(ieee
->bHalfWirelessN24GMode
== true)
2346 short rtl8192_is_tx_queue_empty(struct net_device
*dev
)
2349 struct r8192_priv
*priv
= ieee80211_priv(dev
);
2350 for (i
=0; i
<=MGNT_QUEUE
; i
++)
2352 if ((i
== TXCMD_QUEUE
) || (i
== HCCA_QUEUE
) )
2354 if (skb_queue_len(&(&priv
->tx_ring
[i
])->queue
) > 0){
2355 printk("===>tx queue is not empty:%d, %d\n", i
, skb_queue_len(&(&priv
->tx_ring
[i
])->queue
));
2361 static void rtl8192_hw_sleep_down(struct net_device
*dev
)
2363 struct r8192_priv
*priv
= ieee80211_priv(dev
);
2364 unsigned long flags
= 0;
2366 spin_lock_irqsave(&priv
->rf_ps_lock
,flags
);
2367 if (priv
->RFChangeInProgress
) {
2368 spin_unlock_irqrestore(&priv
->rf_ps_lock
,flags
);
2369 RT_TRACE(COMP_RF
, "rtl8192_hw_sleep_down(): RF Change in progress! \n");
2370 printk("rtl8192_hw_sleep_down(): RF Change in progress!\n");
2373 spin_unlock_irqrestore(&priv
->rf_ps_lock
,flags
);
2374 //RT_TRACE(COMP_PS, "%s()============>come to sleep down\n", __FUNCTION__);
2376 MgntActSet_RF_State(dev
, eRfSleep
, RF_CHANGE_BY_PS
);
2378 static void rtl8192_hw_sleep_wq (struct work_struct
*work
)
2380 // struct r8180_priv *priv = container_of(work, struct r8180_priv, watch_dog_wq);
2381 // struct ieee80211_device * ieee = (struct ieee80211_device*)
2382 // container_of(work, struct ieee80211_device, watch_dog_wq);
2383 struct delayed_work
*dwork
= container_of(work
,struct delayed_work
,work
);
2384 struct ieee80211_device
*ieee
= container_of(dwork
,struct ieee80211_device
,hw_sleep_wq
);
2385 struct net_device
*dev
= ieee
->dev
;
2387 rtl8192_hw_sleep_down(dev
);
2390 static void rtl8192_hw_wakeup(struct net_device
* dev
)
2392 struct r8192_priv
*priv
= ieee80211_priv(dev
);
2393 unsigned long flags
= 0;
2395 spin_lock_irqsave(&priv
->rf_ps_lock
,flags
);
2396 if (priv
->RFChangeInProgress
) {
2397 spin_unlock_irqrestore(&priv
->rf_ps_lock
,flags
);
2398 RT_TRACE(COMP_RF
, "rtl8192_hw_wakeup(): RF Change in progress! \n");
2399 printk("rtl8192_hw_wakeup(): RF Change in progress! schedule wake up task again\n");
2400 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
2403 spin_unlock_irqrestore(&priv
->rf_ps_lock
,flags
);
2405 //RT_TRACE(COMP_PS, "%s()============>come to wake up\n", __FUNCTION__);
2406 MgntActSet_RF_State(dev
, eRfOn
, RF_CHANGE_BY_PS
);
2409 void rtl8192_hw_wakeup_wq (struct work_struct
*work
)
2411 // struct r8180_priv *priv = container_of(work, struct r8180_priv, watch_dog_wq);
2412 // struct ieee80211_device * ieee = (struct ieee80211_device*)
2413 // container_of(work, struct ieee80211_device, watch_dog_wq);
2414 struct delayed_work
*dwork
= container_of(work
,struct delayed_work
,work
);
2415 struct ieee80211_device
*ieee
= container_of(dwork
,struct ieee80211_device
,hw_wakeup_wq
);
2416 struct net_device
*dev
= ieee
->dev
;
2417 rtl8192_hw_wakeup(dev
);
2421 #define MIN_SLEEP_TIME 50
2422 #define MAX_SLEEP_TIME 10000
2423 static void rtl8192_hw_to_sleep(struct net_device
*dev
, u32 th
, u32 tl
)
2425 struct r8192_priv
*priv
= ieee80211_priv(dev
);
2428 unsigned long flags
;
2430 spin_lock_irqsave(&priv
->ps_lock
,flags
);
2432 // Writing HW register with 0 equals to disable
2433 // the timer, that is not really what we want
2435 tl
-= MSECS(8+16+7);
2437 // If the interval in witch we are requested to sleep is too
2438 // short then give up and remain awake
2439 // when we sleep after send null frame, the timer will be too short to sleep.
2441 if(((tl
>=rb
)&& (tl
-rb
) <= MSECS(MIN_SLEEP_TIME
))
2442 ||((rb
>tl
)&& (rb
-tl
) < MSECS(MIN_SLEEP_TIME
))) {
2443 spin_unlock_irqrestore(&priv
->ps_lock
,flags
);
2444 printk("too short to sleep::%x, %x, %lx\n",tl
, rb
, MSECS(MIN_SLEEP_TIME
));
2448 if(((tl
> rb
) && ((tl
-rb
) > MSECS(MAX_SLEEP_TIME
)))||
2449 ((tl
< rb
) && (tl
>MSECS(69)) && ((rb
-tl
) > MSECS(MAX_SLEEP_TIME
)))||
2450 ((tl
<rb
)&&(tl
<MSECS(69))&&((tl
+0xffffffff-rb
)>MSECS(MAX_SLEEP_TIME
)))) {
2451 printk("========>too long to sleep:%x, %x, %lx\n", tl
, rb
, MSECS(MAX_SLEEP_TIME
));
2452 spin_unlock_irqrestore(&priv
->ps_lock
,flags
);
2456 u32 tmp
= (tl
>rb
)?(tl
-rb
):(rb
-tl
);
2457 queue_delayed_work(priv
->ieee80211
->wq
,
2458 &priv
->ieee80211
->hw_wakeup_wq
,tmp
);
2459 //PowerSave not supported when kernel version less 2.6.20
2461 queue_delayed_work(priv
->ieee80211
->wq
,
2462 (void *)&priv
->ieee80211
->hw_sleep_wq
,0);
2463 spin_unlock_irqrestore(&priv
->ps_lock
,flags
);
2466 static void rtl8192_init_priv_variable(struct net_device
* dev
)
2468 struct r8192_priv
*priv
= ieee80211_priv(dev
);
2470 PRT_POWER_SAVE_CONTROL pPSC
= (PRT_POWER_SAVE_CONTROL
)(&(priv
->ieee80211
->PowerSaveControl
));
2472 // Default Halt the NIC if RF is OFF.
2473 pPSC
->RegRfPsLevel
|= RT_RF_OFF_LEVL_HALT_NIC
;
2474 pPSC
->RegRfPsLevel
|= RT_RF_OFF_LEVL_CLK_REQ
;
2475 pPSC
->RegRfPsLevel
|= RT_RF_OFF_LEVL_ASPM
;
2476 pPSC
->RegRfPsLevel
|= RT_RF_LPS_LEVEL_ASPM
;
2477 pPSC
->bLeisurePs
= true;
2478 pPSC
->RegMaxLPSAwakeIntvl
= 5;
2479 priv
->bHwRadioOff
= false;
2481 priv
->being_init_adapter
= false;
2482 priv
->txbuffsize
= 1600;//1024;
2483 priv
->txfwbuffersize
= 4096;
2484 priv
->txringcount
= 64;//32;
2485 //priv->txbeaconcount = priv->txringcount;
2486 priv
->txbeaconcount
= 2;
2487 priv
->rxbuffersize
= 9100;//2048;//1024;
2488 priv
->rxringcount
= MAX_RX_COUNT
;//64;
2489 priv
->irq_enabled
=0;
2490 priv
->card_8192
= NIC_8192E
;
2491 priv
->rx_skb_complete
= 1;
2492 priv
->chan
= 1; //set to channel 1
2493 priv
->RegWirelessMode
= WIRELESS_MODE_AUTO
;
2494 priv
->RegChannelPlan
= 0xf;
2495 priv
->nrxAMPDU_size
= 0;
2496 priv
->nrxAMPDU_aggr_num
= 0;
2497 priv
->last_rxdesc_tsf_high
= 0;
2498 priv
->last_rxdesc_tsf_low
= 0;
2499 priv
->ieee80211
->mode
= WIRELESS_MODE_AUTO
; //SET AUTO
2500 priv
->ieee80211
->iw_mode
= IW_MODE_INFRA
;
2501 priv
->ieee80211
->ieee_up
=0;
2502 priv
->retry_rts
= DEFAULT_RETRY_RTS
;
2503 priv
->retry_data
= DEFAULT_RETRY_DATA
;
2504 priv
->ieee80211
->rts
= DEFAULT_RTS_THRESHOLD
;
2505 priv
->ieee80211
->rate
= 110; //11 mbps
2506 priv
->ieee80211
->short_slot
= 1;
2507 priv
->promisc
= (dev
->flags
& IFF_PROMISC
) ? 1:0;
2508 priv
->bcck_in_ch14
= false;
2509 priv
->bfsync_processing
= false;
2510 priv
->CCKPresentAttentuation
= 0;
2511 priv
->rfa_txpowertrackingindex
= 0;
2512 priv
->rfc_txpowertrackingindex
= 0;
2514 priv
->ScanDelay
= 50;//for Scan TODO
2515 //added by amy for silent reset
2516 priv
->ResetProgress
= RESET_TYPE_NORESET
;
2517 priv
->bForcedSilentReset
= 0;
2518 priv
->bDisableNormalResetCheck
= false;
2519 priv
->force_reset
= false;
2520 //added by amy for power save
2522 priv
->ieee80211
->RfOffReason
= 0;
2523 priv
->RFChangeInProgress
= false;
2524 priv
->bHwRfOffAction
= 0;
2525 priv
->SetRFPowerStateInProgress
= false;
2526 priv
->ieee80211
->PowerSaveControl
.bInactivePs
= true;
2527 priv
->ieee80211
->PowerSaveControl
.bIPSModeBackup
= false;
2529 priv
->txpower_checkcnt
= 0;
2530 priv
->thermal_readback_index
=0;
2531 priv
->txpower_tracking_callback_cnt
= 0;
2532 priv
->ccktxpower_adjustcnt_ch14
= 0;
2533 priv
->ccktxpower_adjustcnt_not_ch14
= 0;
2535 priv
->ieee80211
->current_network
.beacon_interval
= DEFAULT_BEACONINTERVAL
;
2536 priv
->ieee80211
->iw_mode
= IW_MODE_INFRA
;
2537 priv
->ieee80211
->softmac_features
= IEEE_SOFTMAC_SCAN
|
2538 IEEE_SOFTMAC_ASSOCIATE
| IEEE_SOFTMAC_PROBERQ
|
2539 IEEE_SOFTMAC_PROBERS
| IEEE_SOFTMAC_TX_QUEUE
;/* |
2540 IEEE_SOFTMAC_BEACONS;*///added by amy
080604 //| //IEEE_SOFTMAC_SINGLE_QUEUE;
2542 priv
->ieee80211
->active_scan
= 1;
2543 priv
->ieee80211
->modulation
= IEEE80211_CCK_MODULATION
| IEEE80211_OFDM_MODULATION
;
2544 priv
->ieee80211
->host_encrypt
= 1;
2545 priv
->ieee80211
->host_decrypt
= 1;
2546 //priv->ieee80211->start_send_beacons = NULL;//rtl819xusb_beacon_tx;//-by amy 080604
2547 //priv->ieee80211->stop_send_beacons = NULL;//rtl8192_beacon_stop;//-by amy 080604
2548 priv
->ieee80211
->start_send_beacons
= rtl8192_start_beacon
;//+by david 081107
2549 priv
->ieee80211
->stop_send_beacons
= rtl8192_stop_beacon
;//+by david 081107
2550 priv
->ieee80211
->softmac_hard_start_xmit
= rtl8192_hard_start_xmit
;
2551 priv
->ieee80211
->set_chan
= rtl8192_set_chan
;
2552 priv
->ieee80211
->link_change
= rtl8192_link_change
;
2553 priv
->ieee80211
->softmac_data_hard_start_xmit
= rtl8192_hard_data_xmit
;
2554 priv
->ieee80211
->data_hard_stop
= rtl8192_data_hard_stop
;
2555 priv
->ieee80211
->data_hard_resume
= rtl8192_data_hard_resume
;
2556 priv
->ieee80211
->init_wmmparam_flag
= 0;
2557 priv
->ieee80211
->fts
= DEFAULT_FRAG_THRESHOLD
;
2558 priv
->ieee80211
->check_nic_enough_desc
= check_nic_enough_desc
;
2559 priv
->ieee80211
->tx_headroom
= sizeof(TX_FWINFO_8190PCI
);
2560 priv
->ieee80211
->qos_support
= 1;
2561 priv
->ieee80211
->dot11PowerSaveMode
= 0;
2563 // priv->ieee80211->SwChnlByTimerHandler = rtl8192_phy_SwChnl;
2564 priv
->ieee80211
->SetBWModeHandler
= rtl8192_SetBWMode
;
2565 priv
->ieee80211
->handle_assoc_response
= rtl8192_handle_assoc_response
;
2566 priv
->ieee80211
->handle_beacon
= rtl8192_handle_beacon
;
2568 priv
->ieee80211
->sta_wake_up
= rtl8192_hw_wakeup
;
2569 // priv->ieee80211->ps_request_tx_ack = rtl8192_rq_tx_ack;
2570 priv
->ieee80211
->enter_sleep_state
= rtl8192_hw_to_sleep
;
2571 priv
->ieee80211
->ps_is_queue_empty
= rtl8192_is_tx_queue_empty
;
2573 priv
->ieee80211
->GetNmodeSupportBySecCfg
= GetNmodeSupportBySecCfg8190Pci
;
2574 priv
->ieee80211
->SetWirelessMode
= rtl8192_SetWirelessMode
;
2575 priv
->ieee80211
->GetHalfNmodeSupportByAPsHandler
= GetHalfNmodeSupportByAPs819xPci
;
2578 priv
->ieee80211
->InitialGainHandler
= InitialGain819xPci
;
2581 priv
->ieee80211
->ieee80211_ips_leave_wq
= ieee80211_ips_leave_wq
;
2582 priv
->ieee80211
->ieee80211_ips_leave
= ieee80211_ips_leave
;
2585 priv
->ieee80211
->LeisurePSLeave
= LeisurePSLeave
;
2588 priv
->ieee80211
->SetHwRegHandler
= rtl8192e_SetHwReg
;
2589 priv
->ieee80211
->rtllib_ap_sec_type
= rtl8192e_ap_sec_type
;
2591 priv
->card_type
= USB
;
2593 priv
->ShortRetryLimit
= 0x30;
2594 priv
->LongRetryLimit
= 0x30;
2596 priv
->EarlyRxThreshold
= 7;
2597 priv
->enable_gpio0
= 0;
2599 priv
->TransmitConfig
= 0;
2601 priv
->ReceiveConfig
= RCR_ADD3
|
2602 RCR_AMF
| RCR_ADF
| //accept management/data
2603 RCR_AICV
| //accept control frame for SW AP needs PS-poll, 2005.07.07, by rcnjko.
2604 RCR_AB
| RCR_AM
| RCR_APM
| //accept BC/MC/UC
2605 RCR_AAP
| ((u32
)7<<RCR_MXDMA_OFFSET
) |
2606 ((u32
)7 << RCR_FIFO_OFFSET
) | RCR_ONLYERLPKT
;
2608 priv
->irq_mask
= (u32
)(IMR_ROK
| IMR_VODOK
| IMR_VIDOK
| IMR_BEDOK
| IMR_BKDOK
|\
2609 IMR_HCCADOK
| IMR_MGNTDOK
| IMR_COMDOK
| IMR_HIGHDOK
|\
2610 IMR_BDOK
| IMR_RXCMDOK
| IMR_TIMEOUT0
| IMR_RDU
| IMR_RXFOVW
|\
2611 IMR_TXFOVW
| IMR_BcnInt
| IMR_TBDOK
| IMR_TBDER
);
2613 priv
->AcmControl
= 0;
2614 priv
->pFirmware
= (rt_firmware
*)vmalloc(sizeof(rt_firmware
));
2615 if (priv
->pFirmware
)
2616 memset(priv
->pFirmware
, 0, sizeof(rt_firmware
));
2618 /* rx related queue */
2619 skb_queue_head_init(&priv
->rx_queue
);
2620 skb_queue_head_init(&priv
->skb_queue
);
2622 /* Tx related queue */
2623 for(i
= 0; i
< MAX_QUEUE_SIZE
; i
++) {
2624 skb_queue_head_init(&priv
->ieee80211
->skb_waitQ
[i
]);
2626 for(i
= 0; i
< MAX_QUEUE_SIZE
; i
++) {
2627 skb_queue_head_init(&priv
->ieee80211
->skb_aggQ
[i
]);
2629 priv
->rf_set_chan
= rtl8192_phy_SwChnl
;
2633 static void rtl8192_init_priv_lock(struct r8192_priv
* priv
)
2635 spin_lock_init(&priv
->tx_lock
);
2636 spin_lock_init(&priv
->irq_lock
);//added by thomas
2637 spin_lock_init(&priv
->irq_th_lock
);
2638 spin_lock_init(&priv
->rf_ps_lock
);
2639 spin_lock_init(&priv
->ps_lock
);
2640 //spin_lock_init(&priv->rf_lock);
2641 sema_init(&priv
->wx_sem
,1);
2642 sema_init(&priv
->rf_sem
,1);
2643 mutex_init(&priv
->mutex
);
2646 //init tasklet and wait_queue here. only 2.6 above kernel is considered
2647 #define DRV_NAME "wlan0"
2648 static void rtl8192_init_priv_task(struct net_device
* dev
)
2650 struct r8192_priv
*priv
= ieee80211_priv(dev
);
2652 #ifdef PF_SYNCTHREAD
2653 priv
->priv_wq
= create_workqueue(DRV_NAME
,0);
2655 priv
->priv_wq
= create_workqueue(DRV_NAME
);
2659 INIT_WORK(&priv
->ieee80211
->ips_leave_wq
, (void*)IPSLeave_wq
);
2662 // INIT_WORK(&priv->reset_wq, (void(*)(void*)) rtl8192_restart);
2663 INIT_WORK(&priv
->reset_wq
, rtl8192_restart
);
2664 // INIT_DELAYED_WORK(&priv->watch_dog_wq, hal_dm_watchdog);
2665 INIT_DELAYED_WORK(&priv
->watch_dog_wq
, rtl819x_watchdog_wqcallback
);
2666 INIT_DELAYED_WORK(&priv
->txpower_tracking_wq
, dm_txpower_trackingcallback
);
2667 INIT_DELAYED_WORK(&priv
->rfpath_check_wq
, dm_rf_pathcheck_workitemcallback
);
2668 INIT_DELAYED_WORK(&priv
->update_beacon_wq
, rtl8192_update_beacon
);
2669 //INIT_WORK(&priv->SwChnlWorkItem, rtl8192_SwChnl_WorkItem);
2670 //INIT_WORK(&priv->SetBWModeWorkItem, rtl8192_SetBWModeWorkItem);
2671 INIT_WORK(&priv
->qos_activate
, rtl8192_qos_activate
);
2672 INIT_DELAYED_WORK(&priv
->ieee80211
->hw_wakeup_wq
,(void*) rtl8192_hw_wakeup_wq
);
2673 INIT_DELAYED_WORK(&priv
->ieee80211
->hw_sleep_wq
,(void*) rtl8192_hw_sleep_wq
);
2675 tasklet_init(&priv
->irq_rx_tasklet
,
2676 (void(*)(unsigned long))rtl8192_irq_rx_tasklet
,
2677 (unsigned long)priv
);
2678 tasklet_init(&priv
->irq_tx_tasklet
,
2679 (void(*)(unsigned long))rtl8192_irq_tx_tasklet
,
2680 (unsigned long)priv
);
2681 tasklet_init(&priv
->irq_prepare_beacon_tasklet
,
2682 (void(*)(unsigned long))rtl8192_prepare_beacon
,
2683 (unsigned long)priv
);
2686 static void rtl8192_get_eeprom_size(struct net_device
* dev
)
2689 struct r8192_priv
*priv
= ieee80211_priv(dev
);
2690 RT_TRACE(COMP_INIT
, "===========>%s()\n", __FUNCTION__
);
2691 curCR
= read_nic_dword(dev
, EPROM_CMD
);
2692 RT_TRACE(COMP_INIT
, "read from Reg Cmd9346CR(%x):%x\n", EPROM_CMD
, curCR
);
2693 //whether need I consider BIT5?
2694 priv
->epromtype
= (curCR
& EPROM_CMD_9356SEL
) ? EPROM_93c56
: EPROM_93c46
;
2695 RT_TRACE(COMP_INIT
, "<===========%s(), epromtype:%d\n", __FUNCTION__
, priv
->epromtype
);
2698 //used to swap endian. as ntohl & htonl are not neccessary to swap endian, so use this instead.
2699 static inline u16
endian_swap(u16
* data
)
2702 *data
= (tmp
>> 8) | (tmp
<< 8);
2707 * Note: Adapter->EEPROMAddressSize should be set before this function call.
2708 * EEPROM address size can be got through GetEEPROMSize8185()
2710 static void rtl8192_read_eeprom_info(struct net_device
* dev
)
2712 struct r8192_priv
*priv
= ieee80211_priv(dev
);
2716 u8 ICVer8192
, ICVer8256
;
2718 u16 i
,usValue
, IC_Version
;
2721 u8 offset
;//, tmpAFR;
2722 u8 EepromTxPower
[100];
2724 u8 bMac_Tmp_Addr
[6] = {0x00, 0xe0, 0x4c, 0x00, 0x00, 0x01};
2725 RT_TRACE(COMP_INIT
, "====> rtl8192_read_eeprom_info\n");
2728 // TODO: I don't know if we need to apply EF function to EEPROM read function
2730 //2 Read EEPROM ID to make sure autoload is success
2731 EEPROMId
= eprom_read(dev
, 0);
2732 if( EEPROMId
!= RTL8190_EEPROM_ID
)
2734 RT_TRACE(COMP_ERR
, "EEPROM ID is invalid:%x, %x\n", EEPROMId
, RTL8190_EEPROM_ID
);
2735 priv
->AutoloadFailFlag
=true;
2739 priv
->AutoloadFailFlag
=false;
2743 // Assign Chip Version ID
2745 // Read IC Version && Channel Plan
2746 if(!priv
->AutoloadFailFlag
)
2749 priv
->eeprom_vid
= eprom_read(dev
, (EEPROM_VID
>> 1));
2750 priv
->eeprom_did
= eprom_read(dev
, (EEPROM_DID
>> 1));
2752 usValue
= eprom_read(dev
, (u16
)(EEPROM_Customer_ID
>>1)) >> 8 ;
2753 priv
->eeprom_CustomerID
= (u8
)( usValue
& 0xff);
2754 usValue
= eprom_read(dev
, (EEPROM_ICVersion_ChannelPlan
>>1));
2755 priv
->eeprom_ChannelPlan
= usValue
&0xff;
2756 IC_Version
= ((usValue
&0xff00)>>8);
2759 priv
->card_8192_version
= (VERSION_8190
)(IC_Version
);
2762 ICVer8192
= (IC_Version
&0xf); //bit0~3; 1:A cut, 2:B cut, 3:C cut...
2763 ICVer8256
= ((IC_Version
&0xf0)>>4);//bit4~6, bit7 reserved for other RF chip; 1:A cut, 2:B cut, 3:C cut...
2764 RT_TRACE(COMP_INIT
, "\nICVer8192 = 0x%x\n", ICVer8192
);
2765 RT_TRACE(COMP_INIT
, "\nICVer8256 = 0x%x\n", ICVer8256
);
2766 if(ICVer8192
== 0x2) //B-cut
2768 if(ICVer8256
== 0x5) //E-cut
2769 priv
->card_8192_version
= VERSION_8190_BE
;
2773 switch(priv
->card_8192_version
)
2775 case VERSION_8190_BD
:
2776 case VERSION_8190_BE
:
2779 priv
->card_8192_version
= VERSION_8190_BD
;
2782 RT_TRACE(COMP_INIT
, "\nIC Version = 0x%x\n", priv
->card_8192_version
);
2786 priv
->card_8192_version
= VERSION_8190_BD
;
2787 priv
->eeprom_vid
= 0;
2788 priv
->eeprom_did
= 0;
2789 priv
->eeprom_CustomerID
= 0;
2790 priv
->eeprom_ChannelPlan
= 0;
2791 RT_TRACE(COMP_INIT
, "\nIC Version = 0x%x\n", 0xff);
2794 RT_TRACE(COMP_INIT
, "EEPROM VID = 0x%4x\n", priv
->eeprom_vid
);
2795 RT_TRACE(COMP_INIT
, "EEPROM DID = 0x%4x\n", priv
->eeprom_did
);
2796 RT_TRACE(COMP_INIT
,"EEPROM Customer ID: 0x%2x\n", priv
->eeprom_CustomerID
);
2798 //2 Read Permanent MAC address
2799 if(!priv
->AutoloadFailFlag
)
2801 for(i
= 0; i
< 6; i
+= 2)
2803 usValue
= eprom_read(dev
, (u16
) ((EEPROM_NODE_ADDRESS_BYTE_0
+i
)>>1));
2804 *(u16
*)(&dev
->dev_addr
[i
]) = usValue
;
2807 // when auto load failed, the last address byte set to be a random one.
2808 // added by david woo.2007/11/7
2809 memcpy(dev
->dev_addr
, bMac_Tmp_Addr
, 6);
2812 RT_TRACE(COMP_INIT
, "Permanent Address = %pM\n", dev
->dev_addr
);
2814 //2 TX Power Check EEPROM Fail or not
2815 if(priv
->card_8192_version
> VERSION_8190_BD
) {
2816 priv
->bTXPowerDataReadFromEEPORM
= true;
2818 priv
->bTXPowerDataReadFromEEPORM
= false;
2821 // 2007/11/15 MH 8190PCI Default=2T4R, 8192PCIE default=1T2R
2822 priv
->rf_type
= RTL819X_DEFAULT_RF_TYPE
;
2824 if(priv
->card_8192_version
> VERSION_8190_BD
)
2826 // Read RF-indication and Tx Power gain index diff of legacy to HT OFDM rate.
2827 if(!priv
->AutoloadFailFlag
)
2829 tempval
= (eprom_read(dev
, (EEPROM_RFInd_PowerDiff
>>1))) & 0xff;
2830 priv
->EEPROMLegacyHTTxPowerDiff
= tempval
& 0xf; // bit[3:0]
2832 if (tempval
&0x80) //RF-indication, bit[7]
2833 priv
->rf_type
= RF_1T2R
;
2835 priv
->rf_type
= RF_2T4R
;
2839 priv
->EEPROMLegacyHTTxPowerDiff
= EEPROM_Default_LegacyHTTxPowerDiff
;
2841 RT_TRACE(COMP_INIT
, "EEPROMLegacyHTTxPowerDiff = %d\n",
2842 priv
->EEPROMLegacyHTTxPowerDiff
);
2844 // Read ThermalMeter from EEPROM
2845 if(!priv
->AutoloadFailFlag
)
2847 priv
->EEPROMThermalMeter
= (u8
)(((eprom_read(dev
, (EEPROM_ThermalMeter
>>1))) & 0xff00)>>8);
2851 priv
->EEPROMThermalMeter
= EEPROM_Default_ThermalMeter
;
2853 RT_TRACE(COMP_INIT
, "ThermalMeter = %d\n", priv
->EEPROMThermalMeter
);
2854 //vivi, for tx power track
2855 priv
->TSSI_13dBm
= priv
->EEPROMThermalMeter
*100;
2857 if(priv
->epromtype
== EPROM_93c46
)
2859 // Read antenna tx power offset of B/C/D to A and CrystalCap from EEPROM
2860 if(!priv
->AutoloadFailFlag
)
2862 usValue
= eprom_read(dev
, (EEPROM_TxPwDiff_CrystalCap
>>1));
2863 priv
->EEPROMAntPwDiff
= (usValue
&0x0fff);
2864 priv
->EEPROMCrystalCap
= (u8
)((usValue
&0xf000)>>12);
2868 priv
->EEPROMAntPwDiff
= EEPROM_Default_AntTxPowerDiff
;
2869 priv
->EEPROMCrystalCap
= EEPROM_Default_TxPwDiff_CrystalCap
;
2871 RT_TRACE(COMP_INIT
, "EEPROMAntPwDiff = %d\n", priv
->EEPROMAntPwDiff
);
2872 RT_TRACE(COMP_INIT
, "EEPROMCrystalCap = %d\n", priv
->EEPROMCrystalCap
);
2875 // Get per-channel Tx Power Level
2877 for(i
=0; i
<14; i
+=2)
2879 if(!priv
->AutoloadFailFlag
)
2881 usValue
= eprom_read(dev
, (u16
) ((EEPROM_TxPwIndex_CCK
+i
)>>1) );
2885 usValue
= EEPROM_Default_TxPower
;
2887 *((u16
*)(&priv
->EEPROMTxPowerLevelCCK
[i
])) = usValue
;
2888 RT_TRACE(COMP_INIT
,"CCK Tx Power Level, Index %d = 0x%02x\n", i
, priv
->EEPROMTxPowerLevelCCK
[i
]);
2889 RT_TRACE(COMP_INIT
, "CCK Tx Power Level, Index %d = 0x%02x\n", i
+1, priv
->EEPROMTxPowerLevelCCK
[i
+1]);
2891 for(i
=0; i
<14; i
+=2)
2893 if(!priv
->AutoloadFailFlag
)
2895 usValue
= eprom_read(dev
, (u16
) ((EEPROM_TxPwIndex_OFDM_24G
+i
)>>1) );
2899 usValue
= EEPROM_Default_TxPower
;
2901 *((u16
*)(&priv
->EEPROMTxPowerLevelOFDM24G
[i
])) = usValue
;
2902 RT_TRACE(COMP_INIT
, "OFDM 2.4G Tx Power Level, Index %d = 0x%02x\n", i
, priv
->EEPROMTxPowerLevelOFDM24G
[i
]);
2903 RT_TRACE(COMP_INIT
, "OFDM 2.4G Tx Power Level, Index %d = 0x%02x\n", i
+1, priv
->EEPROMTxPowerLevelOFDM24G
[i
+1]);
2906 else if(priv
->epromtype
== EPROM_93c56
)
2909 // Read CrystalCap from EEPROM
2910 if(!priv
->AutoloadFailFlag
)
2912 priv
->EEPROMAntPwDiff
= EEPROM_Default_AntTxPowerDiff
;
2913 priv
->EEPROMCrystalCap
= (u8
)(((eprom_read(dev
, (EEPROM_C56_CrystalCap
>>1))) & 0xf000)>>12);
2917 priv
->EEPROMAntPwDiff
= EEPROM_Default_AntTxPowerDiff
;
2918 priv
->EEPROMCrystalCap
= EEPROM_Default_TxPwDiff_CrystalCap
;
2920 RT_TRACE(COMP_INIT
,"EEPROMAntPwDiff = %d\n", priv
->EEPROMAntPwDiff
);
2921 RT_TRACE(COMP_INIT
, "EEPROMCrystalCap = %d\n", priv
->EEPROMCrystalCap
);
2923 // Get Tx Power Level by Channel
2924 if(!priv
->AutoloadFailFlag
)
2926 // Read Tx power of Channel 1 ~ 14 from EEPROM.
2927 for(i
= 0; i
< 12; i
+=2)
2930 offset
= EEPROM_C56_RfA_CCK_Chnl1_TxPwIndex
+ i
;
2932 offset
= EEPROM_C56_RfC_CCK_Chnl1_TxPwIndex
+ i
- 6;
2933 usValue
= eprom_read(dev
, (offset
>>1));
2934 *((u16
*)(&EepromTxPower
[i
])) = usValue
;
2937 for(i
= 0; i
< 12; i
++)
2940 priv
->EEPROMRfACCKChnl1TxPwLevel
[i
] = EepromTxPower
[i
];
2941 else if ((i
>=3 )&&(i
<= 5))
2942 priv
->EEPROMRfAOfdmChnlTxPwLevel
[i
-3] = EepromTxPower
[i
];
2943 else if ((i
>=6 )&&(i
<= 8))
2944 priv
->EEPROMRfCCCKChnl1TxPwLevel
[i
-6] = EepromTxPower
[i
];
2946 priv
->EEPROMRfCOfdmChnlTxPwLevel
[i
-9] = EepromTxPower
[i
];
2951 priv
->EEPROMRfACCKChnl1TxPwLevel
[0] = EEPROM_Default_TxPowerLevel
;
2952 priv
->EEPROMRfACCKChnl1TxPwLevel
[1] = EEPROM_Default_TxPowerLevel
;
2953 priv
->EEPROMRfACCKChnl1TxPwLevel
[2] = EEPROM_Default_TxPowerLevel
;
2955 priv
->EEPROMRfAOfdmChnlTxPwLevel
[0] = EEPROM_Default_TxPowerLevel
;
2956 priv
->EEPROMRfAOfdmChnlTxPwLevel
[1] = EEPROM_Default_TxPowerLevel
;
2957 priv
->EEPROMRfAOfdmChnlTxPwLevel
[2] = EEPROM_Default_TxPowerLevel
;
2959 priv
->EEPROMRfCCCKChnl1TxPwLevel
[0] = EEPROM_Default_TxPowerLevel
;
2960 priv
->EEPROMRfCCCKChnl1TxPwLevel
[1] = EEPROM_Default_TxPowerLevel
;
2961 priv
->EEPROMRfCCCKChnl1TxPwLevel
[2] = EEPROM_Default_TxPowerLevel
;
2963 priv
->EEPROMRfCOfdmChnlTxPwLevel
[0] = EEPROM_Default_TxPowerLevel
;
2964 priv
->EEPROMRfCOfdmChnlTxPwLevel
[1] = EEPROM_Default_TxPowerLevel
;
2965 priv
->EEPROMRfCOfdmChnlTxPwLevel
[2] = EEPROM_Default_TxPowerLevel
;
2967 RT_TRACE(COMP_INIT
, "priv->EEPROMRfACCKChnl1TxPwLevel[0] = 0x%x\n", priv
->EEPROMRfACCKChnl1TxPwLevel
[0]);
2968 RT_TRACE(COMP_INIT
, "priv->EEPROMRfACCKChnl1TxPwLevel[1] = 0x%x\n", priv
->EEPROMRfACCKChnl1TxPwLevel
[1]);
2969 RT_TRACE(COMP_INIT
, "priv->EEPROMRfACCKChnl1TxPwLevel[2] = 0x%x\n", priv
->EEPROMRfACCKChnl1TxPwLevel
[2]);
2970 RT_TRACE(COMP_INIT
, "priv->EEPROMRfAOfdmChnlTxPwLevel[0] = 0x%x\n", priv
->EEPROMRfAOfdmChnlTxPwLevel
[0]);
2971 RT_TRACE(COMP_INIT
, "priv->EEPROMRfAOfdmChnlTxPwLevel[1] = 0x%x\n", priv
->EEPROMRfAOfdmChnlTxPwLevel
[1]);
2972 RT_TRACE(COMP_INIT
, "priv->EEPROMRfAOfdmChnlTxPwLevel[2] = 0x%x\n", priv
->EEPROMRfAOfdmChnlTxPwLevel
[2]);
2973 RT_TRACE(COMP_INIT
, "priv->EEPROMRfCCCKChnl1TxPwLevel[0] = 0x%x\n", priv
->EEPROMRfCCCKChnl1TxPwLevel
[0]);
2974 RT_TRACE(COMP_INIT
, "priv->EEPROMRfCCCKChnl1TxPwLevel[1] = 0x%x\n", priv
->EEPROMRfCCCKChnl1TxPwLevel
[1]);
2975 RT_TRACE(COMP_INIT
, "priv->EEPROMRfCCCKChnl1TxPwLevel[2] = 0x%x\n", priv
->EEPROMRfCCCKChnl1TxPwLevel
[2]);
2976 RT_TRACE(COMP_INIT
, "priv->EEPROMRfCOfdmChnlTxPwLevel[0] = 0x%x\n", priv
->EEPROMRfCOfdmChnlTxPwLevel
[0]);
2977 RT_TRACE(COMP_INIT
, "priv->EEPROMRfCOfdmChnlTxPwLevel[1] = 0x%x\n", priv
->EEPROMRfCOfdmChnlTxPwLevel
[1]);
2978 RT_TRACE(COMP_INIT
, "priv->EEPROMRfCOfdmChnlTxPwLevel[2] = 0x%x\n", priv
->EEPROMRfCOfdmChnlTxPwLevel
[2]);
2983 // Update HAL variables.
2985 if(priv
->epromtype
== EPROM_93c46
)
2989 priv
->TxPowerLevelCCK
[i
] = priv
->EEPROMTxPowerLevelCCK
[i
];
2990 priv
->TxPowerLevelOFDM24G
[i
] = priv
->EEPROMTxPowerLevelOFDM24G
[i
];
2992 priv
->LegacyHTTxPowerDiff
= priv
->EEPROMLegacyHTTxPowerDiff
;
2993 // Antenna B gain offset to antenna A, bit0~3
2994 priv
->AntennaTxPwDiff
[0] = (priv
->EEPROMAntPwDiff
& 0xf);
2995 // Antenna C gain offset to antenna A, bit4~7
2996 priv
->AntennaTxPwDiff
[1] = ((priv
->EEPROMAntPwDiff
& 0xf0)>>4);
2997 // Antenna D gain offset to antenna A, bit8~11
2998 priv
->AntennaTxPwDiff
[2] = ((priv
->EEPROMAntPwDiff
& 0xf00)>>8);
2999 // CrystalCap, bit12~15
3000 priv
->CrystalCap
= priv
->EEPROMCrystalCap
;
3001 // ThermalMeter, bit0~3 for RFIC1, bit4~7 for RFIC2
3002 priv
->ThermalMeter
[0] = (priv
->EEPROMThermalMeter
& 0xf);
3003 priv
->ThermalMeter
[1] = ((priv
->EEPROMThermalMeter
& 0xf0)>>4);
3005 else if(priv
->epromtype
== EPROM_93c56
)
3007 //char cck_pwr_diff_a=0, cck_pwr_diff_c=0;
3009 //cck_pwr_diff_a = pHalData->EEPROMRfACCKChnl7TxPwLevel - pHalData->EEPROMRfAOfdmChnlTxPwLevel[1];
3010 //cck_pwr_diff_c = pHalData->EEPROMRfCCCKChnl7TxPwLevel - pHalData->EEPROMRfCOfdmChnlTxPwLevel[1];
3011 for(i
=0; i
<3; i
++) // channel 1~3 use the same Tx Power Level.
3013 priv
->TxPowerLevelCCK_A
[i
] = priv
->EEPROMRfACCKChnl1TxPwLevel
[0];
3014 priv
->TxPowerLevelOFDM24G_A
[i
] = priv
->EEPROMRfAOfdmChnlTxPwLevel
[0];
3015 priv
->TxPowerLevelCCK_C
[i
] = priv
->EEPROMRfCCCKChnl1TxPwLevel
[0];
3016 priv
->TxPowerLevelOFDM24G_C
[i
] = priv
->EEPROMRfCOfdmChnlTxPwLevel
[0];
3018 for(i
=3; i
<9; i
++) // channel 4~9 use the same Tx Power Level
3020 priv
->TxPowerLevelCCK_A
[i
] = priv
->EEPROMRfACCKChnl1TxPwLevel
[1];
3021 priv
->TxPowerLevelOFDM24G_A
[i
] = priv
->EEPROMRfAOfdmChnlTxPwLevel
[1];
3022 priv
->TxPowerLevelCCK_C
[i
] = priv
->EEPROMRfCCCKChnl1TxPwLevel
[1];
3023 priv
->TxPowerLevelOFDM24G_C
[i
] = priv
->EEPROMRfCOfdmChnlTxPwLevel
[1];
3025 for(i
=9; i
<14; i
++) // channel 10~14 use the same Tx Power Level
3027 priv
->TxPowerLevelCCK_A
[i
] = priv
->EEPROMRfACCKChnl1TxPwLevel
[2];
3028 priv
->TxPowerLevelOFDM24G_A
[i
] = priv
->EEPROMRfAOfdmChnlTxPwLevel
[2];
3029 priv
->TxPowerLevelCCK_C
[i
] = priv
->EEPROMRfCCCKChnl1TxPwLevel
[2];
3030 priv
->TxPowerLevelOFDM24G_C
[i
] = priv
->EEPROMRfCOfdmChnlTxPwLevel
[2];
3033 RT_TRACE(COMP_INIT
, "priv->TxPowerLevelCCK_A[%d] = 0x%x\n", i
, priv
->TxPowerLevelCCK_A
[i
]);
3035 RT_TRACE(COMP_INIT
,"priv->TxPowerLevelOFDM24G_A[%d] = 0x%x\n", i
, priv
->TxPowerLevelOFDM24G_A
[i
]);
3037 RT_TRACE(COMP_INIT
, "priv->TxPowerLevelCCK_C[%d] = 0x%x\n", i
, priv
->TxPowerLevelCCK_C
[i
]);
3039 RT_TRACE(COMP_INIT
, "priv->TxPowerLevelOFDM24G_C[%d] = 0x%x\n", i
, priv
->TxPowerLevelOFDM24G_C
[i
]);
3040 priv
->LegacyHTTxPowerDiff
= priv
->EEPROMLegacyHTTxPowerDiff
;
3041 priv
->AntennaTxPwDiff
[0] = 0;
3042 priv
->AntennaTxPwDiff
[1] = 0;
3043 priv
->AntennaTxPwDiff
[2] = 0;
3044 priv
->CrystalCap
= priv
->EEPROMCrystalCap
;
3045 // ThermalMeter, bit0~3 for RFIC1, bit4~7 for RFIC2
3046 priv
->ThermalMeter
[0] = (priv
->EEPROMThermalMeter
& 0xf);
3047 priv
->ThermalMeter
[1] = ((priv
->EEPROMThermalMeter
& 0xf0)>>4);
3051 if(priv
->rf_type
== RF_1T2R
)
3053 RT_TRACE(COMP_INIT
, "\n1T2R config\n");
3055 else if (priv
->rf_type
== RF_2T4R
)
3057 RT_TRACE(COMP_INIT
, "\n2T4R config\n");
3060 // 2008/01/16 MH We can only know RF type in the function. So we have to init
3061 // DIG RATR table again.
3062 init_rate_adaptive(dev
);
3064 //1 Make a copy for following variables and we can change them if we want
3066 priv
->rf_chip
= RF_8256
;
3068 if(priv
->RegChannelPlan
== 0xf)
3070 priv
->ChannelPlan
= priv
->eeprom_ChannelPlan
;
3074 priv
->ChannelPlan
= priv
->RegChannelPlan
;
3078 // Used PID and DID to Set CustomerID
3080 if( priv
->eeprom_vid
== 0x1186 && priv
->eeprom_did
== 0x3304 )
3082 priv
->CustomerID
= RT_CID_DLINK
;
3085 switch(priv
->eeprom_CustomerID
)
3087 case EEPROM_CID_DEFAULT
:
3088 priv
->CustomerID
= RT_CID_DEFAULT
;
3090 case EEPROM_CID_CAMEO
:
3091 priv
->CustomerID
= RT_CID_819x_CAMEO
;
3093 case EEPROM_CID_RUNTOP
:
3094 priv
->CustomerID
= RT_CID_819x_RUNTOP
;
3096 case EEPROM_CID_NetCore
:
3097 priv
->CustomerID
= RT_CID_819x_Netcore
;
3099 case EEPROM_CID_TOSHIBA
: // Merge by Jacken, 2008/01/31
3100 priv
->CustomerID
= RT_CID_TOSHIBA
;
3101 if(priv
->eeprom_ChannelPlan
&0x80)
3102 priv
->ChannelPlan
= priv
->eeprom_ChannelPlan
&0x7f;
3104 priv
->ChannelPlan
= 0x0;
3105 RT_TRACE(COMP_INIT
, "Toshiba ChannelPlan = 0x%x\n",
3108 case EEPROM_CID_Nettronix
:
3109 priv
->ScanDelay
= 100; //cosa add for scan
3110 priv
->CustomerID
= RT_CID_Nettronix
;
3112 case EEPROM_CID_Pronet
:
3113 priv
->CustomerID
= RT_CID_PRONET
;
3115 case EEPROM_CID_DLINK
:
3116 priv
->CustomerID
= RT_CID_DLINK
;
3119 case EEPROM_CID_WHQL
:
3120 //Adapter->bInHctTest = TRUE;//do not supported
3122 //priv->bSupportTurboMode = FALSE;
3123 //priv->bAutoTurboBy8186 = FALSE;
3125 //pMgntInfo->PowerSaveControl.bInactivePs = FALSE;
3126 //pMgntInfo->PowerSaveControl.bIPSModeBackup = FALSE;
3127 //pMgntInfo->PowerSaveControl.bLeisurePs = FALSE;
3131 // value from RegCustomerID
3135 //Avoid the channel plan array overflow, by Bruce, 2007-08-27.
3136 if(priv
->ChannelPlan
> CHANNEL_PLAN_LEN
- 1)
3137 priv
->ChannelPlan
= 0; //FCC
3139 switch(priv
->CustomerID
)
3141 case RT_CID_DEFAULT
:
3143 priv
->LedStrategy
= HW_LED
;
3146 priv
->LedStrategy
= SW_LED_MODE1
;
3151 case RT_CID_819x_CAMEO
:
3152 priv
->LedStrategy
= SW_LED_MODE2
;
3155 case RT_CID_819x_RUNTOP
:
3156 priv
->LedStrategy
= SW_LED_MODE3
;
3159 case RT_CID_819x_Netcore
:
3160 priv
->LedStrategy
= SW_LED_MODE4
;
3163 case RT_CID_Nettronix
:
3164 priv
->LedStrategy
= SW_LED_MODE5
;
3168 priv
->LedStrategy
= SW_LED_MODE6
;
3171 case RT_CID_TOSHIBA
: //Modify by Jacken 2008/01/31
3177 priv
->LedStrategy
= HW_LED
;
3180 priv
->LedStrategy
= SW_LED_MODE1
;
3187 if( priv
->eeprom_vid
== 0x1186 && priv
->eeprom_did
== 0x3304)
3188 priv
->ieee80211
->bSupportRemoteWakeUp
= true;
3190 priv
->ieee80211
->bSupportRemoteWakeUp
= false;
3193 RT_TRACE(COMP_INIT
, "RegChannelPlan(%d)\n", priv
->RegChannelPlan
);
3194 RT_TRACE(COMP_INIT
, "ChannelPlan = %d \n", priv
->ChannelPlan
);
3195 RT_TRACE(COMP_INIT
, "LedStrategy = %d \n", priv
->LedStrategy
);
3196 RT_TRACE(COMP_TRACE
, "<==== ReadAdapterInfo\n");
3202 static short rtl8192_get_channel_map(struct net_device
* dev
)
3204 struct r8192_priv
*priv
= ieee80211_priv(dev
);
3205 #ifdef ENABLE_DOT11D
3206 if(priv
->ChannelPlan
> COUNTRY_CODE_GLOBAL_DOMAIN
){
3207 printk("rtl8180_init:Error channel plan! Set to default.\n");
3208 priv
->ChannelPlan
= 0;
3210 RT_TRACE(COMP_INIT
, "Channel plan is %d\n",priv
->ChannelPlan
);
3212 rtl819x_set_channel_map(priv
->ChannelPlan
, priv
);
3215 //Set Default Channel Plan
3217 DMESG("No channels, aborting");
3221 priv
->ChannelPlan
= 0;//hikaru
3222 // set channels 1..14 allowed in given locale
3223 for (i
=1; i
<=14; i
++) {
3224 (priv
->ieee80211
->channel_map
)[i
] = (u8
)(ch
& 0x01);
3231 static short rtl8192_init(struct net_device
*dev
)
3233 struct r8192_priv
*priv
= ieee80211_priv(dev
);
3234 memset(&(priv
->stats
),0,sizeof(struct Stats
));
3235 rtl8192_init_priv_variable(dev
);
3236 rtl8192_init_priv_lock(priv
);
3237 rtl8192_init_priv_task(dev
);
3238 rtl8192_get_eeprom_size(dev
);
3239 rtl8192_read_eeprom_info(dev
);
3240 rtl8192_get_channel_map(dev
);
3242 init_timer(&priv
->watch_dog_timer
);
3243 priv
->watch_dog_timer
.data
= (unsigned long)dev
;
3244 priv
->watch_dog_timer
.function
= watch_dog_timer_callback
;
3245 #if defined(IRQF_SHARED)
3246 if(request_irq(dev
->irq
, (void*)rtl8192_interrupt
, IRQF_SHARED
, dev
->name
, dev
)){
3248 if(request_irq(dev
->irq
, (void *)rtl8192_interrupt
, SA_SHIRQ
, dev
->name
, dev
)){
3250 printk("Error allocating IRQ %d",dev
->irq
);
3254 printk("IRQ %d",dev
->irq
);
3256 if(rtl8192_pci_initdescring(dev
)!=0){
3257 printk("Endopoints initialization failed");
3261 //rtl8192_rx_enable(dev);
3262 //rtl8192_adapter_start(dev);
3266 /******************************************************************************
3267 *function: This function actually only set RRSR, RATR and BW_OPMODE registers
3268 * not to do all the hw config as its name says
3269 * input: net_device dev
3272 * notice: This part need to modified according to the rate set we filtered
3273 * ****************************************************************************/
3274 static void rtl8192_hwconfig(struct net_device
* dev
)
3276 u32 regRATR
= 0, regRRSR
= 0;
3277 u8 regBwOpMode
= 0, regTmp
= 0;
3278 struct r8192_priv
*priv
= ieee80211_priv(dev
);
3280 // Set RRSR, RATR, and BW_OPMODE registers
3282 switch(priv
->ieee80211
->mode
)
3284 case WIRELESS_MODE_B
:
3285 regBwOpMode
= BW_OPMODE_20MHZ
;
3286 regRATR
= RATE_ALL_CCK
;
3287 regRRSR
= RATE_ALL_CCK
;
3289 case WIRELESS_MODE_A
:
3290 regBwOpMode
= BW_OPMODE_5G
|BW_OPMODE_20MHZ
;
3291 regRATR
= RATE_ALL_OFDM_AG
;
3292 regRRSR
= RATE_ALL_OFDM_AG
;
3294 case WIRELESS_MODE_G
:
3295 regBwOpMode
= BW_OPMODE_20MHZ
;
3296 regRATR
= RATE_ALL_CCK
| RATE_ALL_OFDM_AG
;
3297 regRRSR
= RATE_ALL_CCK
| RATE_ALL_OFDM_AG
;
3299 case WIRELESS_MODE_AUTO
:
3300 case WIRELESS_MODE_N_24G
:
3301 // It support CCK rate by default.
3302 // CCK rate will be filtered out only when associated AP does not support it.
3303 regBwOpMode
= BW_OPMODE_20MHZ
;
3304 regRATR
= RATE_ALL_CCK
| RATE_ALL_OFDM_AG
| RATE_ALL_OFDM_1SS
| RATE_ALL_OFDM_2SS
;
3305 regRRSR
= RATE_ALL_CCK
| RATE_ALL_OFDM_AG
;
3307 case WIRELESS_MODE_N_5G
:
3308 regBwOpMode
= BW_OPMODE_5G
;
3309 regRATR
= RATE_ALL_OFDM_AG
| RATE_ALL_OFDM_1SS
| RATE_ALL_OFDM_2SS
;
3310 regRRSR
= RATE_ALL_OFDM_AG
;
3314 write_nic_byte(dev
, BW_OPMODE
, regBwOpMode
);
3317 ratr_value
= regRATR
;
3318 if (priv
->rf_type
== RF_1T2R
)
3320 ratr_value
&= ~(RATE_ALL_OFDM_2SS
);
3322 write_nic_dword(dev
, RATR0
, ratr_value
);
3323 write_nic_byte(dev
, UFWP
, 1);
3325 regTmp
= read_nic_byte(dev
, 0x313);
3326 regRRSR
= ((regTmp
) << 24) | (regRRSR
& 0x00ffffff);
3327 write_nic_dword(dev
, RRSR
, regRRSR
);
3330 // Set Retry Limit here
3332 write_nic_word(dev
, RETRY_LIMIT
,
3333 priv
->ShortRetryLimit
<< RETRY_LIMIT_SHORT_SHIFT
| \
3334 priv
->LongRetryLimit
<< RETRY_LIMIT_LONG_SHIFT
);
3335 // Set Contention Window here
3339 // Set Tx Antenna including Feedback control
3341 // Set Auto Rate fallback control
3347 static RT_STATUS
rtl8192_adapter_start(struct net_device
*dev
)
3349 struct r8192_priv
*priv
= ieee80211_priv(dev
);
3350 // struct ieee80211_device *ieee = priv->ieee80211;
3352 RT_STATUS rtStatus
= RT_STATUS_SUCCESS
;
3353 // static char szMACPHYRegFile[] = RTL819X_PHY_MACPHY_REG;
3354 // static char szMACPHYRegPGFile[] = RTL819X_PHY_MACPHY_REG_PG;
3358 u8 ICVersion
,SwitchingRegulatorOutput
;
3360 bool bfirmwareok
= true;
3364 u32 tmpRegA
, tmpRegC
, TempCCk
;
3366 // u32 dwRegRead = 0;
3368 RT_TRACE(COMP_INIT
, "====>%s()\n", __FUNCTION__
);
3369 priv
->being_init_adapter
= true;
3370 rtl8192_pci_resetdescring(dev
);
3371 // 2007/11/02 MH Before initalizing RF. We can not use FW to do RF-R/W.
3372 priv
->Rf_Mode
= RF_OP_By_SW_3wire
;
3375 if(priv
->ResetProgress
== RESET_TYPE_NORESET
)
3377 write_nic_byte(dev
, ANAPAR
, 0x37);
3378 // Accordign to designer's explain, LBUS active will never > 10ms. We delay 10ms
3379 // Joseph increae the time to prevent firmware download fail
3383 //PlatformSleepUs(10000);
3384 // For any kind of InitializeAdapter process, we shall use system now!!
3385 priv
->pFirmware
->firmware_status
= FW_STATUS_0_INIT
;
3387 // Set to eRfoff in order not to count receive count.
3388 if(priv
->RegRfOff
== TRUE
)
3389 priv
->ieee80211
->eRFPowerState
= eRfOff
;
3392 //3 //Config CPUReset Register
3394 //3 Firmware Reset Or Not
3395 ulRegRead
= read_nic_dword(dev
, CPU_GEN
);
3396 if(priv
->pFirmware
->firmware_status
== FW_STATUS_0_INIT
)
3397 { //called from MPInitialized. do nothing
3398 ulRegRead
|= CPU_GEN_SYSTEM_RESET
;
3399 }else if(priv
->pFirmware
->firmware_status
== FW_STATUS_5_READY
)
3400 ulRegRead
|= CPU_GEN_FIRMWARE_RESET
; // Called from MPReset
3402 RT_TRACE(COMP_ERR
, "ERROR in %s(): undefined firmware state(%d)\n", __FUNCTION__
, priv
->pFirmware
->firmware_status
);
3405 //2008.06.03, for WOL 90 hw bug
3406 ulRegRead
&= (~(CPU_GEN_GPIO_UART
));
3409 write_nic_dword(dev
, CPU_GEN
, ulRegRead
);
3415 //3 //Fix the issue of E-cut high temperature issue
3418 ICVersion
= read_nic_byte(dev
, IC_VERRSION
);
3419 if(ICVersion
>= 0x4) //E-cut only
3421 // HW SD suggest that we should not wirte this register too often, so driver
3422 // should readback this register. This register will be modified only when
3424 SwitchingRegulatorOutput
= read_nic_byte(dev
, SWREGULATOR
);
3425 if(SwitchingRegulatorOutput
!= 0xb8)
3427 write_nic_byte(dev
, SWREGULATOR
, 0xa8);
3429 write_nic_byte(dev
, SWREGULATOR
, 0xb8);
3436 //3// Initialize BB before MAC
3438 RT_TRACE(COMP_INIT
, "BB Config Start!\n");
3439 rtStatus
= rtl8192_BBConfig(dev
);
3440 if(rtStatus
!= RT_STATUS_SUCCESS
)
3442 RT_TRACE(COMP_ERR
, "BB Config failed\n");
3445 RT_TRACE(COMP_INIT
,"BB Config Finished!\n");
3447 //3//Set Loopback mode or Normal mode
3449 //2006.12.13 by emily. Note!We should not merge these two CPU_GEN register writings
3450 // because setting of System_Reset bit reset MAC to default transmission mode.
3451 //Loopback mode or not
3452 priv
->LoopbackMode
= RTL819X_NO_LOOPBACK
;
3453 //priv->LoopbackMode = RTL819X_MAC_LOOPBACK;
3454 if(priv
->ResetProgress
== RESET_TYPE_NORESET
)
3456 ulRegRead
= read_nic_dword(dev
, CPU_GEN
);
3457 if(priv
->LoopbackMode
== RTL819X_NO_LOOPBACK
)
3459 ulRegRead
= ((ulRegRead
& CPU_GEN_NO_LOOPBACK_MSK
) | CPU_GEN_NO_LOOPBACK_SET
);
3461 else if (priv
->LoopbackMode
== RTL819X_MAC_LOOPBACK
)
3463 ulRegRead
|= CPU_CCK_LOOPBACK
;
3467 RT_TRACE(COMP_ERR
,"Serious error: wrong loopback mode setting\n");
3470 //2008.06.03, for WOL
3471 //ulRegRead &= (~(CPU_GEN_GPIO_UART));
3472 write_nic_dword(dev
, CPU_GEN
, ulRegRead
);
3474 // 2006.11.29. After reset cpu, we sholud wait for a second, otherwise, it may fail to write registers. Emily
3477 //3Set Hardware(Do nothing now)
3478 rtl8192_hwconfig(dev
);
3479 //2=======================================================
3480 // Common Setting for all of the FPGA platform. (part 1)
3481 //2=======================================================
3482 // If there is changes, please make sure it applies to all of the FPGA version
3484 write_nic_byte(dev
, CMDR
, CR_RE
|CR_TE
);
3488 write_nic_byte(dev
, PCIF
, ((MXDMA2_NoLimit
<<MXDMA2_RX_SHIFT
) | \
3489 (MXDMA2_NoLimit
<<MXDMA2_TX_SHIFT
) | \
3493 write_nic_byte(dev
, PCIF
, ((MXDMA2_NoLimit
<<MXDMA2_RX_SHIFT
) |\
3494 (MXDMA2_NoLimit
<<MXDMA2_TX_SHIFT
) ));
3498 write_nic_dword(dev
, MAC0
, ((u32
*)dev
->dev_addr
)[0]);
3499 write_nic_word(dev
, MAC4
, ((u16
*)(dev
->dev_addr
+ 4))[0]);
3501 write_nic_dword(dev
, RCR
, priv
->ReceiveConfig
);
3503 //3 Initialize Number of Reserved Pages in Firmware Queue
3505 if(priv
->bInHctTest
)
3507 PlatformEFIOWrite4Byte(Adapter
, RQPN1
, NUM_OF_PAGE_IN_FW_QUEUE_BK_DTM
<< RSVD_FW_QUEUE_PAGE_BK_SHIFT
|\
3508 NUM_OF_PAGE_IN_FW_QUEUE_BE_DTM
<< RSVD_FW_QUEUE_PAGE_BE_SHIFT
| \
3509 NUM_OF_PAGE_IN_FW_QUEUE_VI_DTM
<< RSVD_FW_QUEUE_PAGE_VI_SHIFT
| \
3510 NUM_OF_PAGE_IN_FW_QUEUE_VO_DTM
<<RSVD_FW_QUEUE_PAGE_VO_SHIFT
);
3511 PlatformEFIOWrite4Byte(Adapter
, RQPN2
, NUM_OF_PAGE_IN_FW_QUEUE_MGNT
<< RSVD_FW_QUEUE_PAGE_MGNT_SHIFT
);
3512 PlatformEFIOWrite4Byte(Adapter
, RQPN3
, APPLIED_RESERVED_QUEUE_IN_FW
| \
3513 NUM_OF_PAGE_IN_FW_QUEUE_BCN
<<RSVD_FW_QUEUE_PAGE_BCN_SHIFT
|\
3514 NUM_OF_PAGE_IN_FW_QUEUE_PUB_DTM
<<RSVD_FW_QUEUE_PAGE_PUB_SHIFT
);
3519 write_nic_dword(dev
, RQPN1
, NUM_OF_PAGE_IN_FW_QUEUE_BK
<< RSVD_FW_QUEUE_PAGE_BK_SHIFT
|\
3520 NUM_OF_PAGE_IN_FW_QUEUE_BE
<< RSVD_FW_QUEUE_PAGE_BE_SHIFT
| \
3521 NUM_OF_PAGE_IN_FW_QUEUE_VI
<< RSVD_FW_QUEUE_PAGE_VI_SHIFT
| \
3522 NUM_OF_PAGE_IN_FW_QUEUE_VO
<<RSVD_FW_QUEUE_PAGE_VO_SHIFT
);
3523 write_nic_dword(dev
, RQPN2
, NUM_OF_PAGE_IN_FW_QUEUE_MGNT
<< RSVD_FW_QUEUE_PAGE_MGNT_SHIFT
);
3524 write_nic_dword(dev
, RQPN3
, APPLIED_RESERVED_QUEUE_IN_FW
| \
3525 NUM_OF_PAGE_IN_FW_QUEUE_BCN
<<RSVD_FW_QUEUE_PAGE_BCN_SHIFT
|\
3526 NUM_OF_PAGE_IN_FW_QUEUE_PUB
<<RSVD_FW_QUEUE_PAGE_PUB_SHIFT
);
3529 rtl8192_tx_enable(dev
);
3530 rtl8192_rx_enable(dev
);
3531 //3Set Response Rate Setting Register
3532 // CCK rate is supported by default.
3533 // CCK rate will be filtered out only when associated AP does not support it.
3534 ulRegRead
= (0xFFF00000 & read_nic_dword(dev
, RRSR
)) | RATE_ALL_OFDM_AG
| RATE_ALL_CCK
;
3535 write_nic_dword(dev
, RRSR
, ulRegRead
);
3536 write_nic_dword(dev
, RATR0
+4*7, (RATE_ALL_OFDM_AG
| RATE_ALL_CCK
));
3539 // TODO: (it value is only for FPGA version). need to be changed!!2006.12.18, by Emily
3540 write_nic_byte(dev
, ACK_TIMEOUT
, 0x30);
3542 //rtl8192_actset_wirelessmode(dev,priv->RegWirelessMode);
3543 if(priv
->ResetProgress
== RESET_TYPE_NORESET
)
3544 rtl8192_SetWirelessMode(dev
, priv
->ieee80211
->mode
);
3545 //-----------------------------------------------------------------------------
3546 // Set up security related. 070106, by rcnjko:
3547 // 1. Clear all H/W keys.
3548 // 2. Enable H/W encryption/decryption.
3549 //-----------------------------------------------------------------------------
3550 CamResetAllEntry(dev
);
3552 u8 SECR_value
= 0x0;
3553 SECR_value
|= SCR_TxEncEnable
;
3554 SECR_value
|= SCR_RxDecEnable
;
3555 SECR_value
|= SCR_NoSKMC
;
3556 write_nic_byte(dev
, SECR
, SECR_value
);
3559 write_nic_word(dev
, ATIMWND
, 2);
3560 write_nic_word(dev
, BCN_INTERVAL
, 100);
3561 for (i
=0; i
<QOS_QUEUE_NUM
; i
++)
3562 write_nic_dword(dev
, WDCAPARA_ADD
[i
], 0x005e4332);
3564 // Switching regulator controller: This is set temporarily.
3565 // It's not sure if this can be removed in the future.
3566 // PJ advised to leave it by default.
3568 write_nic_byte(dev
, 0xbe, 0xc0);
3570 //2=======================================================
3571 // Set PHY related configuration defined in MAC register bank
3572 //2=======================================================
3573 rtl8192_phy_configmac(dev
);
3575 if (priv
->card_8192_version
> (u8
) VERSION_8190_BD
) {
3576 rtl8192_phy_getTxPower(dev
);
3577 rtl8192_phy_setTxPower(dev
, priv
->chan
);
3581 tmpvalue
= read_nic_byte(dev
, IC_VERRSION
);
3582 priv
->IC_Cut
= tmpvalue
;
3583 RT_TRACE(COMP_INIT
, "priv->IC_Cut = 0x%x\n", priv
->IC_Cut
);
3584 if(priv
->IC_Cut
>= IC_VersionCut_D
)
3586 //pHalData->bDcut = TRUE;
3587 if(priv
->IC_Cut
== IC_VersionCut_D
)
3588 RT_TRACE(COMP_INIT
, "D-cut\n");
3589 if(priv
->IC_Cut
== IC_VersionCut_E
)
3591 RT_TRACE(COMP_INIT
, "E-cut\n");
3592 // HW SD suggest that we should not wirte this register too often, so driver
3593 // should readback this register. This register will be modified only when
3599 //pHalData->bDcut = FALSE;
3600 RT_TRACE(COMP_INIT
, "Before C-cut\n");
3605 RT_TRACE(COMP_INIT
, "Load Firmware!\n");
3606 bfirmwareok
= init_firmware(dev
);
3607 if(bfirmwareok
!= true) {
3608 rtStatus
= RT_STATUS_FAILURE
;
3611 RT_TRACE(COMP_INIT
, "Load Firmware finished!\n");
3614 if(priv
->ResetProgress
== RESET_TYPE_NORESET
)
3616 RT_TRACE(COMP_INIT
, "RF Config Started!\n");
3617 rtStatus
= rtl8192_phy_RFConfig(dev
);
3618 if(rtStatus
!= RT_STATUS_SUCCESS
)
3620 RT_TRACE(COMP_ERR
, "RF Config failed\n");
3623 RT_TRACE(COMP_INIT
, "RF Config Finished!\n");
3625 rtl8192_phy_updateInitGain(dev
);
3627 /*---- Set CCK and OFDM Block "ON"----*/
3628 rtl8192_setBBreg(dev
, rFPGA0_RFMOD
, bCCKEn
, 0x1);
3629 rtl8192_setBBreg(dev
, rFPGA0_RFMOD
, bOFDMEn
, 0x1);
3633 write_nic_byte(dev
, 0x87, 0x0);
3636 //2008.06.03, for WOL
3637 ucRegRead
= read_nic_byte(dev
, GPE
);
3639 write_nic_byte(dev
, GPE
, ucRegRead
);
3641 ucRegRead
= read_nic_byte(dev
, GPO
);
3643 write_nic_byte(dev
, GPO
, ucRegRead
);
3646 //2=======================================================
3648 //2=======================================================
3652 if(priv
->RegRfOff
== TRUE
)
3653 { // User disable RF via registry.
3654 RT_TRACE((COMP_INIT
|COMP_RF
|COMP_POWER
), "%s(): Turn off RF for RegRfOff ----------\n",__FUNCTION__
);
3655 MgntActSet_RF_State(dev
, eRfOff
, RF_CHANGE_BY_SW
);
3656 #if 0//cosa, ask SD3 willis and he doesn't know what is this for
3657 // Those action will be discard in MgntActSet_RF_State because off the same state
3658 for(eRFPath
= 0; eRFPath
<pHalData
->NumTotalRFPath
; eRFPath
++)
3659 PHY_SetRFReg(Adapter
, (RF90_RADIO_PATH_E
)eRFPath
, 0x4, 0xC00, 0x0);
3662 else if(priv
->ieee80211
->RfOffReason
> RF_CHANGE_BY_PS
)
3663 { // H/W or S/W RF OFF before sleep.
3664 RT_TRACE((COMP_INIT
|COMP_RF
|COMP_POWER
), "%s(): Turn off RF for RfOffReason(%d) ----------\n", __FUNCTION__
,priv
->ieee80211
->RfOffReason
);
3665 MgntActSet_RF_State(dev
, eRfOff
, priv
->ieee80211
->RfOffReason
);
3667 else if(priv
->ieee80211
->RfOffReason
>= RF_CHANGE_BY_IPS
)
3668 { // H/W or S/W RF OFF before sleep.
3669 RT_TRACE((COMP_INIT
|COMP_RF
|COMP_POWER
), "%s(): Turn off RF for RfOffReason(%d) ----------\n", __FUNCTION__
,priv
->ieee80211
->RfOffReason
);
3670 MgntActSet_RF_State(dev
, eRfOff
, priv
->ieee80211
->RfOffReason
);
3674 RT_TRACE((COMP_INIT
|COMP_RF
|COMP_POWER
), "%s(): RF-ON \n",__FUNCTION__
);
3675 priv
->ieee80211
->eRFPowerState
= eRfOn
;
3676 priv
->ieee80211
->RfOffReason
= 0;
3677 //DrvIFIndicateCurrentPhyStatus(Adapter);
3679 //Adapter->HalFunc.LedControlHandler(Adapter, LED_CTL_POWER_ON);
3682 // If inactive power mode is enabled, disable rf while in disconnected state.
3683 // But we should still tell upper layer we are in rf on state.
3684 // 2007.07.16, by shien chang.
3686 //if(!Adapter->bInHctTest)
3687 //IPSEnter(Adapter);
3694 // We can force firmware to do RF-R/W
3695 if(priv
->ieee80211
->FwRWRF
)
3696 priv
->Rf_Mode
= RF_OP_By_FW
;
3698 priv
->Rf_Mode
= RF_OP_By_SW_3wire
;
3700 priv
->Rf_Mode
= RF_OP_By_SW_3wire
;
3704 if(priv
->ResetProgress
== RESET_TYPE_NORESET
)
3706 dm_initialize_txpower_tracking(dev
);
3708 tmpRegA
= rtl8192_QueryBBReg(dev
,rOFDM0_XATxIQImbalance
,bMaskDWord
);
3709 tmpRegC
= rtl8192_QueryBBReg(dev
,rOFDM0_XCTxIQImbalance
,bMaskDWord
);
3711 if(priv
->rf_type
== RF_2T4R
){
3712 for(i
= 0; i
<TxBBGainTableLength
; i
++)
3714 if(tmpRegA
== priv
->txbbgain_table
[i
].txbbgain_value
)
3716 priv
->rfa_txpowertrackingindex
= (u8
)i
;
3717 priv
->rfa_txpowertrackingindex_real
= (u8
)i
;
3718 priv
->rfa_txpowertracking_default
= priv
->rfa_txpowertrackingindex
;
3723 for(i
= 0; i
<TxBBGainTableLength
; i
++)
3725 if(tmpRegC
== priv
->txbbgain_table
[i
].txbbgain_value
)
3727 priv
->rfc_txpowertrackingindex
= (u8
)i
;
3728 priv
->rfc_txpowertrackingindex_real
= (u8
)i
;
3729 priv
->rfc_txpowertracking_default
= priv
->rfc_txpowertrackingindex
;
3733 TempCCk
= rtl8192_QueryBBReg(dev
, rCCK0_TxFilter1
, bMaskByte2
);
3735 for(i
=0 ; i
<CCKTxBBGainTableLength
; i
++)
3737 if(TempCCk
== priv
->cck_txbbgain_table
[i
].ccktxbb_valuearray
[0])
3739 priv
->CCKPresentAttentuation_20Mdefault
=(u8
) i
;
3743 priv
->CCKPresentAttentuation_40Mdefault
= 0;
3744 priv
->CCKPresentAttentuation_difference
= 0;
3745 priv
->CCKPresentAttentuation
= priv
->CCKPresentAttentuation_20Mdefault
;
3746 RT_TRACE(COMP_POWER_TRACKING
, "priv->rfa_txpowertrackingindex_initial = %d\n", priv
->rfa_txpowertrackingindex
);
3747 RT_TRACE(COMP_POWER_TRACKING
, "priv->rfa_txpowertrackingindex_real__initial = %d\n", priv
->rfa_txpowertrackingindex_real
);
3748 RT_TRACE(COMP_POWER_TRACKING
, "priv->rfc_txpowertrackingindex_initial = %d\n", priv
->rfc_txpowertrackingindex
);
3749 RT_TRACE(COMP_POWER_TRACKING
, "priv->rfc_txpowertrackingindex_real_initial = %d\n", priv
->rfc_txpowertrackingindex_real
);
3750 RT_TRACE(COMP_POWER_TRACKING
, "priv->CCKPresentAttentuation_difference_initial = %d\n", priv
->CCKPresentAttentuation_difference
);
3751 RT_TRACE(COMP_POWER_TRACKING
, "priv->CCKPresentAttentuation_initial = %d\n", priv
->CCKPresentAttentuation
);
3755 if(priv
->ResetProgress
== RESET_TYPE_NORESET
)
3757 dm_initialize_txpower_tracking(dev
);
3759 if(priv
->IC_Cut
>= IC_VersionCut_D
)
3761 tmpRegA
= rtl8192_QueryBBReg(dev
,rOFDM0_XATxIQImbalance
,bMaskDWord
);
3762 tmpRegC
= rtl8192_QueryBBReg(dev
,rOFDM0_XCTxIQImbalance
,bMaskDWord
);
3763 for(i
= 0; i
<TxBBGainTableLength
; i
++)
3765 if(tmpRegA
== priv
->txbbgain_table
[i
].txbbgain_value
)
3767 priv
->rfa_txpowertrackingindex
= (u8
)i
;
3768 priv
->rfa_txpowertrackingindex_real
= (u8
)i
;
3769 priv
->rfa_txpowertracking_default
= priv
->rfa_txpowertrackingindex
;
3774 TempCCk
= rtl8192_QueryBBReg(dev
, rCCK0_TxFilter1
, bMaskByte2
);
3776 for(i
=0 ; i
<CCKTxBBGainTableLength
; i
++)
3778 if(TempCCk
== priv
->cck_txbbgain_table
[i
].ccktxbb_valuearray
[0])
3780 priv
->CCKPresentAttentuation_20Mdefault
=(u8
) i
;
3784 priv
->CCKPresentAttentuation_40Mdefault
= 0;
3785 priv
->CCKPresentAttentuation_difference
= 0;
3786 priv
->CCKPresentAttentuation
= priv
->CCKPresentAttentuation_20Mdefault
;
3787 RT_TRACE(COMP_POWER_TRACKING
, "priv->rfa_txpowertrackingindex_initial = %d\n", priv
->rfa_txpowertrackingindex
);
3788 RT_TRACE(COMP_POWER_TRACKING
, "priv->rfa_txpowertrackingindex_real__initial = %d\n", priv
->rfa_txpowertrackingindex_real
);
3789 RT_TRACE(COMP_POWER_TRACKING
, "priv->CCKPresentAttentuation_difference_initial = %d\n", priv
->CCKPresentAttentuation_difference
);
3790 RT_TRACE(COMP_POWER_TRACKING
, "priv->CCKPresentAttentuation_initial = %d\n", priv
->CCKPresentAttentuation
);
3791 priv
->btxpower_tracking
= FALSE
;//TEMPLY DISABLE
3796 rtl8192_irq_enable(dev
);
3797 priv
->being_init_adapter
= false;
3802 static void rtl8192_prepare_beacon(struct r8192_priv
*priv
)
3804 struct sk_buff
*skb
;
3805 //unsigned long flags;
3808 skb
= ieee80211_get_beacon(priv
->ieee80211
);
3809 tcb_desc
= (cb_desc
*)(skb
->cb
+ 8);
3810 //printk("===========> %s\n", __FUNCTION__);
3811 //spin_lock_irqsave(&priv->tx_lock,flags);
3812 /* prepare misc info for the beacon xmit */
3813 tcb_desc
->queue_index
= BEACON_QUEUE
;
3814 /* IBSS does not support HT yet, use 1M defaultly */
3815 tcb_desc
->data_rate
= 2;
3816 tcb_desc
->RATRIndex
= 7;
3817 tcb_desc
->bTxDisableRateFallBack
= 1;
3818 tcb_desc
->bTxUseDriverAssingedRate
= 1;
3820 skb_push(skb
, priv
->ieee80211
->tx_headroom
);
3822 rtl8192_tx(priv
->ieee80211
->dev
,skb
);
3824 //spin_unlock_irqrestore (&priv->tx_lock, flags);
3828 /* this configures registers for beacon tx and enables it via
3829 * rtl8192_beacon_tx_enable(). rtl8192_beacon_tx_disable() might
3830 * be used to stop beacon transmission
3832 static void rtl8192_start_beacon(struct net_device
*dev
)
3834 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
3835 struct ieee80211_network
*net
= &priv
->ieee80211
->current_network
;
3840 DMESG("Enabling beacon TX");
3841 //rtl8192_prepare_beacon(dev);
3842 rtl8192_irq_disable(dev
);
3843 //rtl8192_beacon_tx_enable(dev);
3846 write_nic_word(dev
, ATIMWND
, 2);
3848 /* Beacon interval (in unit of TU) */
3849 write_nic_word(dev
, BCN_INTERVAL
, net
->beacon_interval
);
3852 * DrvErlyInt (in unit of TU).
3853 * (Time to send interrupt to notify driver to c
3854 * hange beacon content)
3856 write_nic_word(dev
, BCN_DRV_EARLY_INT
, 10);
3859 * BcnDMATIM(in unit of us).
3860 * Indicates the time before TBTT to perform beacon queue DMA
3862 write_nic_word(dev
, BCN_DMATIME
, 256);
3865 * Force beacon frame transmission even after receiving
3866 * beacon frame from other ad hoc STA
3868 write_nic_byte(dev
, BCN_ERR_THRESH
, 100);
3870 /* Set CW and IFS */
3871 BcnTimeCfg
|= BcnCW
<<BCN_TCFG_CW_SHIFT
;
3872 BcnTimeCfg
|= BcnIFS
<<BCN_TCFG_IFS
;
3873 write_nic_word(dev
, BCN_TCFG
, BcnTimeCfg
);
3876 /* enable the interrupt for ad-hoc process */
3877 rtl8192_irq_enable(dev
);
3879 /***************************************************************************
3880 -------------------------------NET STUFF---------------------------
3881 ***************************************************************************/
3885 static bool HalTxCheckStuck8190Pci(struct net_device
*dev
)
3887 u16 RegTxCounter
= read_nic_word(dev
, 0x128);
3888 struct r8192_priv
*priv
= ieee80211_priv(dev
);
3889 bool bStuck
= FALSE
;
3890 RT_TRACE(COMP_RESET
,"%s():RegTxCounter is %d,TxCounter is %d\n",__FUNCTION__
,RegTxCounter
,priv
->TxCounter
);
3891 if(priv
->TxCounter
==RegTxCounter
)
3894 priv
->TxCounter
= RegTxCounter
;
3900 * <Assumption: RT_TX_SPINLOCK is acquired.>
3901 * First added: 2006.11.19 by emily
3904 TxCheckStuck(struct net_device
*dev
)
3906 struct r8192_priv
*priv
= ieee80211_priv(dev
);
3908 ptx_ring head
=NULL
,tail
=NULL
,txring
= NULL
;
3909 u8 ResetThreshold
= NIC_SEND_HANG_THRESHOLD_POWERSAVE
;
3910 bool bCheckFwTxCnt
= false;
3911 //unsigned long flags;
3914 // Decide Stuch threshold according to current power save mode
3916 //printk("++++++++++++>%s()\n",__FUNCTION__);
3917 switch (priv
->ieee80211
->dot11PowerSaveMode
)
3919 // The threshold value may required to be adjusted .
3920 case eActive
: // Active/Continuous access.
3921 ResetThreshold
= NIC_SEND_HANG_THRESHOLD_NORMAL
;
3923 case eMaxPs
: // Max power save mode.
3924 ResetThreshold
= NIC_SEND_HANG_THRESHOLD_POWERSAVE
;
3926 case eFastPs
: // Fast power save mode.
3927 ResetThreshold
= NIC_SEND_HANG_THRESHOLD_POWERSAVE
;
3932 // Check whether specific tcb has been queued for a specific time
3934 for(QueueID
= 0; QueueID
< MAX_TX_QUEUE
; QueueID
++)
3938 if(QueueID
== TXCMD_QUEUE
)
3943 tail
=priv
->txmapringtail
;
3944 head
=priv
->txmapringhead
;
3948 tail
=priv
->txbkpringtail
;
3949 head
=priv
->txbkpringhead
;
3953 tail
=priv
->txbepringtail
;
3954 head
=priv
->txbepringhead
;
3958 tail
=priv
->txvipringtail
;
3959 head
=priv
->txvipringhead
;
3963 tail
=priv
->txvopringtail
;
3964 head
=priv
->txvopringhead
;
3979 RT_TRACE(COMP_ERR
,"%s():txring is NULL , BUG!\n",__FUNCTION__
);
3982 txring
->nStuckCount
++;
3983 bCheckFwTxCnt
= TRUE
;
3989 if(HalTxCheckStuck8190Pci(dev
))
3991 RT_TRACE(COMP_RESET
, "TxCheckStuck(): Fw indicates no Tx condition! \n");
3992 return RESET_TYPE_SILENT
;
3996 return RESET_TYPE_NORESET
;
4000 static bool HalRxCheckStuck8190Pci(struct net_device
*dev
)
4002 struct r8192_priv
*priv
= ieee80211_priv(dev
);
4003 u16 RegRxCounter
= read_nic_word(dev
, 0x130);
4004 bool bStuck
= FALSE
;
4005 static u8 rx_chk_cnt
= 0;
4006 RT_TRACE(COMP_RESET
,"%s(): RegRxCounter is %d,RxCounter is %d\n",__FUNCTION__
,RegRxCounter
,priv
->RxCounter
);
4007 // If rssi is small, we should check rx for long time because of bad rx.
4008 // or maybe it will continuous silent reset every 2 seconds.
4010 if(priv
->undecorated_smoothed_pwdb
>= (RateAdaptiveTH_High
+5))
4012 rx_chk_cnt
= 0; //high rssi, check rx stuck right now.
4014 else if(priv
->undecorated_smoothed_pwdb
< (RateAdaptiveTH_High
+5) &&
4015 ((priv
->CurrentChannelBW
!=HT_CHANNEL_WIDTH_20
&&priv
->undecorated_smoothed_pwdb
>=RateAdaptiveTH_Low_40M
) ||
4016 (priv
->CurrentChannelBW
==HT_CHANNEL_WIDTH_20
&&priv
->undecorated_smoothed_pwdb
>=RateAdaptiveTH_Low_20M
)) )
4028 else if(((priv
->CurrentChannelBW
!=HT_CHANNEL_WIDTH_20
&&priv
->undecorated_smoothed_pwdb
<RateAdaptiveTH_Low_40M
) ||
4029 (priv
->CurrentChannelBW
==HT_CHANNEL_WIDTH_20
&&priv
->undecorated_smoothed_pwdb
<RateAdaptiveTH_Low_20M
)) &&
4030 priv
->undecorated_smoothed_pwdb
>= VeryLowRSSI
)
4034 //DbgPrint("RSSI < %d && RSSI >= %d, no check this time \n", RateAdaptiveTH_Low, VeryLowRSSI);
4040 //DbgPrint("RSSI < %d && RSSI >= %d, check this time \n", RateAdaptiveTH_Low, VeryLowRSSI);
4047 //DbgPrint("RSSI <= %d, no check this time \n", VeryLowRSSI);
4053 //DbgPrint("RSSI <= %d, check this time \n", VeryLowRSSI);
4056 if(priv
->RxCounter
==RegRxCounter
)
4059 priv
->RxCounter
= RegRxCounter
;
4064 static RESET_TYPE
RxCheckStuck(struct net_device
*dev
)
4067 if(HalRxCheckStuck8190Pci(dev
))
4069 RT_TRACE(COMP_RESET
, "RxStuck Condition\n");
4070 return RESET_TYPE_SILENT
;
4073 return RESET_TYPE_NORESET
;
4077 rtl819x_ifcheck_resetornot(struct net_device
*dev
)
4079 struct r8192_priv
*priv
= ieee80211_priv(dev
);
4080 RESET_TYPE TxResetType
= RESET_TYPE_NORESET
;
4081 RESET_TYPE RxResetType
= RESET_TYPE_NORESET
;
4082 RT_RF_POWER_STATE rfState
;
4084 rfState
= priv
->ieee80211
->eRFPowerState
;
4086 TxResetType
= TxCheckStuck(dev
);
4088 if( rfState
!= eRfOff
&&
4089 /*ADAPTER_TEST_STATUS_FLAG(Adapter, ADAPTER_STATUS_FW_DOWNLOAD_FAILURE)) &&*/
4090 (priv
->ieee80211
->iw_mode
!= IW_MODE_ADHOC
))
4092 // If driver is in the status of firmware download failure , driver skips RF initialization and RF is
4093 // in turned off state. Driver should check whether Rx stuck and do silent reset. And
4094 // if driver is in firmware download failure status, driver should initialize RF in the following
4095 // silent reset procedure Emily, 2008.01.21
4097 // Driver should not check RX stuck in IBSS mode because it is required to
4098 // set Check BSSID in order to send beacon, however, if check BSSID is
4099 // set, STA cannot hear any packet a all. Emily, 2008.04.12
4100 RxResetType
= RxCheckStuck(dev
);
4104 RT_TRACE(COMP_RESET
,"%s(): TxResetType is %d, RxResetType is %d\n",__FUNCTION__
,TxResetType
,RxResetType
);
4105 if(TxResetType
==RESET_TYPE_NORMAL
|| RxResetType
==RESET_TYPE_NORMAL
)
4106 return RESET_TYPE_NORMAL
;
4107 else if(TxResetType
==RESET_TYPE_SILENT
|| RxResetType
==RESET_TYPE_SILENT
)
4108 return RESET_TYPE_SILENT
;
4110 return RESET_TYPE_NORESET
;
4115 static void CamRestoreAllEntry(struct net_device
*dev
)
4118 struct r8192_priv
*priv
= ieee80211_priv(dev
);
4119 const u8
* MacAddr
= priv
->ieee80211
->current_network
.bssid
;
4121 static const u8 CAM_CONST_ADDR
[4][6] = {
4122 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
4123 {0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
4124 {0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
4125 {0x00, 0x00, 0x00, 0x00, 0x00, 0x03}};
4126 static const u8 CAM_CONST_BROAD
[] =
4127 {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
4129 RT_TRACE(COMP_SEC
, "CamRestoreAllEntry: \n");
4132 if ((priv
->ieee80211
->pairwise_key_type
== KEY_TYPE_WEP40
)||
4133 (priv
->ieee80211
->pairwise_key_type
== KEY_TYPE_WEP104
))
4136 for(EntryId
=0; EntryId
<4; EntryId
++)
4139 MacAddr
= CAM_CONST_ADDR
[EntryId
];
4143 priv
->ieee80211
->pairwise_key_type
,
4151 else if(priv
->ieee80211
->pairwise_key_type
== KEY_TYPE_TKIP
)
4155 if(priv
->ieee80211
->iw_mode
== IW_MODE_ADHOC
)
4159 priv
->ieee80211
->pairwise_key_type
,
4167 priv
->ieee80211
->pairwise_key_type
,
4173 else if(priv
->ieee80211
->pairwise_key_type
== KEY_TYPE_CCMP
)
4177 if(priv
->ieee80211
->iw_mode
== IW_MODE_ADHOC
)
4181 priv
->ieee80211
->pairwise_key_type
,
4189 priv
->ieee80211
->pairwise_key_type
,
4198 if(priv
->ieee80211
->group_key_type
== KEY_TYPE_TKIP
)
4200 MacAddr
= CAM_CONST_BROAD
;
4201 for(EntryId
=1 ; EntryId
<4 ; EntryId
++)
4207 priv
->ieee80211
->group_key_type
,
4213 if(priv
->ieee80211
->iw_mode
== IW_MODE_ADHOC
)
4217 priv
->ieee80211
->group_key_type
,
4222 else if(priv
->ieee80211
->group_key_type
== KEY_TYPE_CCMP
)
4224 MacAddr
= CAM_CONST_BROAD
;
4225 for(EntryId
=1; EntryId
<4 ; EntryId
++)
4231 priv
->ieee80211
->group_key_type
,
4238 if(priv
->ieee80211
->iw_mode
== IW_MODE_ADHOC
)
4242 priv
->ieee80211
->group_key_type
,
4249 void rtl8192_cancel_deferred_work(struct r8192_priv
* priv
);
4250 int _rtl8192_up(struct net_device
*dev
);
4253 * This function is used to fix Tx/Rx stop bug temporarily.
4254 * This function will do "system reset" to NIC when Tx or Rx is stuck.
4255 * The method checking Tx/Rx stuck of this function is supported by FW,
4256 * which reports Tx and Rx counter to register 0x128 and 0x130.
4258 static void rtl819x_ifsilentreset(struct net_device
*dev
)
4260 struct r8192_priv
*priv
= ieee80211_priv(dev
);
4262 int reset_status
= 0;
4263 struct ieee80211_device
*ieee
= priv
->ieee80211
;
4268 // 2007.07.20. If we need to check CCK stop, please uncomment this line.
4269 //bStuck = Adapter->HalFunc.CheckHWStopHandler(Adapter);
4271 if(priv
->ResetProgress
==RESET_TYPE_NORESET
)
4275 //LZM for PS-Poll AID issue. 090429
4276 if(priv
->ieee80211
->state
== IEEE80211_LINKED
)
4277 LeisurePSLeave(dev
);
4280 RT_TRACE(COMP_RESET
,"=========>Reset progress!! \n");
4282 // Set the variable for reset.
4283 priv
->ResetProgress
= RESET_TYPE_SILENT
;
4284 // rtl8192_close(dev);
4286 down(&priv
->wx_sem
);
4289 RT_TRACE(COMP_ERR
,"%s():the driver is not up! return\n",__FUNCTION__
);
4294 RT_TRACE(COMP_RESET
,"%s():======>start to down the driver\n",__FUNCTION__
);
4295 if(!netif_queue_stopped(dev
))
4296 netif_stop_queue(dev
);
4298 dm_backup_dynamic_mechanism_state(dev
);
4300 rtl8192_irq_disable(dev
);
4301 rtl8192_cancel_deferred_work(priv
);
4303 del_timer_sync(&priv
->watch_dog_timer
);
4304 ieee
->sync_scan_hurryup
= 1;
4305 if(ieee
->state
== IEEE80211_LINKED
)
4307 down(&ieee
->wx_sem
);
4308 printk("ieee->state is IEEE80211_LINKED\n");
4309 ieee80211_stop_send_beacons(priv
->ieee80211
);
4310 del_timer_sync(&ieee
->associate_timer
);
4311 cancel_delayed_work(&ieee
->associate_retry_wq
);
4312 ieee80211_stop_scan(ieee
);
4316 printk("ieee->state is NOT LINKED\n");
4317 ieee80211_softmac_stop_protocol(priv
->ieee80211
,true);
4319 rtl8192_halt_adapter(dev
, true);
4321 RT_TRACE(COMP_RESET
,"%s():<==========down process is finished\n",__FUNCTION__
);
4322 RT_TRACE(COMP_RESET
,"%s():===========>start to up the driver\n",__FUNCTION__
);
4323 reset_status
= _rtl8192_up(dev
);
4325 RT_TRACE(COMP_RESET
,"%s():<===========up process is finished\n",__FUNCTION__
);
4326 if(reset_status
== -1)
4335 RT_TRACE(COMP_ERR
," ERR!!! %s(): Reset Failed!!\n",__FUNCTION__
);
4339 ieee
->is_silent_reset
= 1;
4341 EnableHWSecurityConfig8192(dev
);
4343 if(ieee
->state
== IEEE80211_LINKED
&& ieee
->iw_mode
== IW_MODE_INFRA
)
4345 ieee
->set_chan(ieee
->dev
, ieee
->current_network
.channel
);
4348 queue_work(ieee
->wq
, &ieee
->associate_complete_wq
);
4352 else if(ieee
->state
== IEEE80211_LINKED
&& ieee
->iw_mode
== IW_MODE_ADHOC
)
4354 ieee
->set_chan(ieee
->dev
, ieee
->current_network
.channel
);
4355 ieee
->link_change(ieee
->dev
);
4357 // notify_wx_assoc_event(ieee);
4359 ieee80211_start_send_beacons(ieee
);
4361 if (ieee
->data_hard_resume
)
4362 ieee
->data_hard_resume(ieee
->dev
);
4363 netif_carrier_on(ieee
->dev
);
4367 CamRestoreAllEntry(dev
);
4369 // Restore the previous setting for all dynamic mechanism
4370 dm_restore_dynamic_mechanism_state(dev
);
4372 priv
->ResetProgress
= RESET_TYPE_NORESET
;
4373 priv
->reset_count
++;
4375 priv
->bForcedSilentReset
=false;
4376 priv
->bResetInProgress
= false;
4378 // For test --> force write UFWP.
4379 write_nic_byte(dev
, UFWP
, 1);
4380 RT_TRACE(COMP_RESET
, "Reset finished!! ====>[%d]\n", priv
->reset_count
);
4386 void InactivePsWorkItemCallback(struct net_device
*dev
)
4388 struct r8192_priv
*priv
= ieee80211_priv(dev
);
4389 PRT_POWER_SAVE_CONTROL pPSC
= (PRT_POWER_SAVE_CONTROL
)(&(priv
->ieee80211
->PowerSaveControl
));
4392 RT_TRACE(COMP_POWER
, "InactivePsWorkItemCallback() ---------> \n");
4394 // This flag "bSwRfProcessing", indicates the status of IPS procedure, should be set if the IPS workitem
4395 // is really scheduled.
4396 // The old code, sets this flag before scheduling the IPS workitem and however, at the same time the
4397 // previous IPS workitem did not end yet, fails to schedule the current workitem. Thus, bSwRfProcessing
4398 // blocks the IPS procedure of switching RF.
4399 // By Bruce, 2007-12-25.
4401 pPSC
->bSwRfProcessing
= TRUE
;
4403 RT_TRACE(COMP_RF
, "InactivePsWorkItemCallback(): Set RF to %s.\n", \
4404 pPSC
->eInactivePowerState
== eRfOff
?"OFF":"ON");
4407 MgntActSet_RF_State(dev
, pPSC
->eInactivePowerState
, RF_CHANGE_BY_IPS
);
4410 // To solve CAM values miss in RF OFF, rewrite CAM values after RF ON. By Bruce, 2007-09-20.
4412 pPSC
->bSwRfProcessing
= FALSE
;
4413 RT_TRACE(COMP_POWER
, "InactivePsWorkItemCallback() <--------- \n");
4418 // Change current and default preamble mode.
4419 // 2005.01.06, by rcnjko.
4421 bool MgntActSet_802_11_PowerSaveMode(struct net_device
*dev
, u8 rtPsMode
)
4423 struct r8192_priv
*priv
= ieee80211_priv(dev
);
4424 //PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->ieee80211->PowerSaveControl));
4425 //u8 RpwmVal, FwPwrMode;
4427 // Currently, we do not change power save mode on IBSS mode.
4428 if(priv
->ieee80211
->iw_mode
== IW_MODE_ADHOC
)
4434 // <RJ_NOTE> If we make HW to fill up the PwrMgt bit for us,
4435 // some AP will not response to our mgnt frames with PwrMgt bit set,
4436 // e.g. cannot associate the AP.
4437 // So I commented out it. 2005.02.16, by rcnjko.
4439 // // Change device's power save mode.
4440 // Adapter->HalFunc.SetPSModeHandler( Adapter, rtPsMode );
4442 // Update power save mode configured.
4443 //RT_TRACE(COMP_LPS,"%s(): set ieee->ps = %x\n",__FUNCTION__,rtPsMode);
4444 if(!priv
->ps_force
) {
4445 priv
->ieee80211
->ps
= rtPsMode
;
4448 // Awake immediately
4449 if(priv
->ieee80211
->sta_sleep
!= 0 && rtPsMode
== IEEE80211_PS_DISABLED
)
4451 unsigned long flags
;
4453 //PlatformSetTimer(Adapter, &(pMgntInfo->AwakeTimer), 0);
4454 // Notify the AP we awke.
4455 rtl8192_hw_wakeup(dev
);
4456 priv
->ieee80211
->sta_sleep
= 0;
4458 spin_lock_irqsave(&(priv
->ieee80211
->mgmt_tx_lock
), flags
);
4459 printk("LPS leave: notify AP we are awaked ++++++++++ SendNullFunctionData\n");
4460 ieee80211_sta_ps_send_null_frame(priv
->ieee80211
, 0);
4461 spin_unlock_irqrestore(&(priv
->ieee80211
->mgmt_tx_lock
), flags
);
4467 //================================================================================
4468 // Leisure Power Save in linked state.
4469 //================================================================================
4473 // Enter the leisure power save mode.
4475 void LeisurePSEnter(struct net_device
*dev
)
4477 struct r8192_priv
*priv
= ieee80211_priv(dev
);
4478 PRT_POWER_SAVE_CONTROL pPSC
= (PRT_POWER_SAVE_CONTROL
)(&(priv
->ieee80211
->PowerSaveControl
));
4480 //RT_TRACE(COMP_PS, "LeisurePSEnter()...\n");
4481 //RT_TRACE(COMP_PS, "pPSC->bLeisurePs = %d, ieee->ps = %d,pPSC->LpsIdleCount is %d,RT_CHECK_FOR_HANG_PERIOD is %d\n",
4482 // pPSC->bLeisurePs, priv->ieee80211->ps,pPSC->LpsIdleCount,RT_CHECK_FOR_HANG_PERIOD);
4484 if(!((priv
->ieee80211
->iw_mode
== IW_MODE_INFRA
) &&
4485 (priv
->ieee80211
->state
== IEEE80211_LINKED
)) ||
4486 (priv
->ieee80211
->iw_mode
== IW_MODE_ADHOC
) ||
4487 (priv
->ieee80211
->iw_mode
== IW_MODE_MASTER
))
4490 if (pPSC
->bLeisurePs
)
4492 // Idle for a while if we connect to AP a while ago.
4493 if(pPSC
->LpsIdleCount
>= RT_CHECK_FOR_HANG_PERIOD
) // 4 Sec
4496 if(priv
->ieee80211
->ps
== IEEE80211_PS_DISABLED
)
4499 //RT_TRACE(COMP_LPS, "LeisurePSEnter(): Enter 802.11 power save mode...\n");
4500 MgntActSet_802_11_PowerSaveMode(dev
, IEEE80211_PS_MBCAST
|IEEE80211_PS_UNICAST
);
4505 pPSC
->LpsIdleCount
++;
4512 // Leave the leisure power save mode.
4514 void LeisurePSLeave(struct net_device
*dev
)
4516 struct r8192_priv
*priv
= ieee80211_priv(dev
);
4517 PRT_POWER_SAVE_CONTROL pPSC
= (PRT_POWER_SAVE_CONTROL
)(&(priv
->ieee80211
->PowerSaveControl
));
4520 //RT_TRACE(COMP_PS, "LeisurePSLeave()...\n");
4521 //RT_TRACE(COMP_PS, "pPSC->bLeisurePs = %d, ieee->ps = %d\n",
4522 // pPSC->bLeisurePs, priv->ieee80211->ps);
4524 if (pPSC
->bLeisurePs
)
4526 if(priv
->ieee80211
->ps
!= IEEE80211_PS_DISABLED
)
4528 // move to lps_wakecomplete()
4529 //RT_TRACE(COMP_LPS, "LeisurePSLeave(): Busy Traffic , Leave 802.11 power save..\n");
4530 MgntActSet_802_11_PowerSaveMode(dev
, IEEE80211_PS_DISABLED
);
4540 // Enter the inactive power save mode. RF will be off
4541 // 2007.08.17, by shien chang.
4544 IPSEnter(struct net_device
*dev
)
4546 struct r8192_priv
*priv
= ieee80211_priv(dev
);
4547 PRT_POWER_SAVE_CONTROL pPSC
= (PRT_POWER_SAVE_CONTROL
)(&(priv
->ieee80211
->PowerSaveControl
));
4548 RT_RF_POWER_STATE rtState
;
4550 if (pPSC
->bInactivePs
)
4552 rtState
= priv
->ieee80211
->eRFPowerState
;
4554 // Added by Bruce, 2007-12-25.
4555 // Do not enter IPS in the following conditions:
4556 // (1) RF is already OFF or Sleep
4557 // (2) bSwRfProcessing (indicates the IPS is still under going)
4558 // (3) Connectted (only disconnected can trigger IPS)
4559 // (4) IBSS (send Beacon)
4560 // (5) AP mode (send Beacon)
4562 if (rtState
== eRfOn
&& !pPSC
->bSwRfProcessing
4563 && (priv
->ieee80211
->state
!= IEEE80211_LINKED
) )
4565 RT_TRACE(COMP_RF
,"IPSEnter(): Turn off RF.\n");
4566 //printk("IPSEnter(): Turn off RF.\n");
4567 pPSC
->eInactivePowerState
= eRfOff
;
4568 // queue_work(priv->priv_wq,&(pPSC->InactivePsWorkItem));
4569 InactivePsWorkItemCallback(dev
);
4576 // Leave the inactive power save mode, RF will be on.
4577 // 2007.08.17, by shien chang.
4580 IPSLeave(struct net_device
*dev
)
4582 struct r8192_priv
*priv
= ieee80211_priv(dev
);
4583 PRT_POWER_SAVE_CONTROL pPSC
= (PRT_POWER_SAVE_CONTROL
)(&(priv
->ieee80211
->PowerSaveControl
));
4584 RT_RF_POWER_STATE rtState
;
4586 if (pPSC
->bInactivePs
)
4588 rtState
= priv
->ieee80211
->eRFPowerState
;
4589 if (rtState
!= eRfOn
&& !pPSC
->bSwRfProcessing
&& priv
->ieee80211
->RfOffReason
<= RF_CHANGE_BY_IPS
)
4591 RT_TRACE(COMP_POWER
, "IPSLeave(): Turn on RF.\n");
4592 //printk("IPSLeave(): Turn on RF.\n");
4593 pPSC
->eInactivePowerState
= eRfOn
;
4594 // queue_work(priv->priv_wq,&(pPSC->InactivePsWorkItem));
4595 InactivePsWorkItemCallback(dev
);
4600 void IPSLeave_wq(void *data
)
4602 struct ieee80211_device
*ieee
= container_of(data
,struct ieee80211_device
,ips_leave_wq
);
4603 struct net_device
*dev
= ieee
->dev
;
4605 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
4606 down(&priv
->ieee80211
->ips_sem
);
4608 up(&priv
->ieee80211
->ips_sem
);
4611 void ieee80211_ips_leave_wq(struct net_device
*dev
)
4613 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
4614 RT_RF_POWER_STATE rtState
;
4615 rtState
= priv
->ieee80211
->eRFPowerState
;
4617 if(priv
->ieee80211
->PowerSaveControl
.bInactivePs
){
4618 if(rtState
== eRfOff
){
4619 if(priv
->ieee80211
->RfOffReason
> RF_CHANGE_BY_IPS
)
4621 RT_TRACE(COMP_ERR
, "%s(): RF is OFF.\n",__FUNCTION__
);
4625 printk("=========>%s(): IPSLeave\n",__FUNCTION__
);
4626 queue_work(priv
->ieee80211
->wq
,&priv
->ieee80211
->ips_leave_wq
);
4631 //added by amy 090331 end
4632 void ieee80211_ips_leave(struct net_device
*dev
)
4634 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
4635 down(&priv
->ieee80211
->ips_sem
);
4637 up(&priv
->ieee80211
->ips_sem
);
4641 static void rtl819x_update_rxcounts(
4642 struct r8192_priv
*priv
,
4651 *TotalRxDataNum
= 0;
4653 SlotIndex
= (priv
->ieee80211
->LinkDetectInfo
.SlotIndex
++)%(priv
->ieee80211
->LinkDetectInfo
.SlotNum
);
4654 priv
->ieee80211
->LinkDetectInfo
.RxBcnNum
[SlotIndex
] = priv
->ieee80211
->LinkDetectInfo
.NumRecvBcnInPeriod
;
4655 priv
->ieee80211
->LinkDetectInfo
.RxDataNum
[SlotIndex
] = priv
->ieee80211
->LinkDetectInfo
.NumRecvDataInPeriod
;
4656 for( i
=0; i
<priv
->ieee80211
->LinkDetectInfo
.SlotNum
; i
++ ){
4657 *TotalRxBcnNum
+= priv
->ieee80211
->LinkDetectInfo
.RxBcnNum
[i
];
4658 *TotalRxDataNum
+= priv
->ieee80211
->LinkDetectInfo
.RxDataNum
[i
];
4663 static void rtl819x_watchdog_wqcallback(struct work_struct
*work
)
4665 struct delayed_work
*dwork
= container_of(work
,struct delayed_work
,work
);
4666 struct r8192_priv
*priv
= container_of(dwork
,struct r8192_priv
,watch_dog_wq
);
4667 struct net_device
*dev
= priv
->ieee80211
->dev
;
4668 struct ieee80211_device
* ieee
= priv
->ieee80211
;
4669 RESET_TYPE ResetType
= RESET_TYPE_NORESET
;
4670 static u8 check_reset_cnt
=0;
4671 unsigned long flags
;
4672 bool bBusyTraffic
= false;
4673 static u8 last_time
= 0;
4674 bool bEnterPS
= false;
4676 if((!priv
->up
) || (priv
->bHwRadioOff
== true))
4681 hal_dm_watchdog(dev
);
4683 // printk("watch_dog ENABLE_IPS\n");
4684 if(ieee
->actscanning
== false){
4685 //printk("%d,%d,%d,%d\n", ieee->eRFPowerState, ieee->is_set_key, ieee->proto_stoppping, ieee->wx_set_enc);
4686 if((ieee
->iw_mode
== IW_MODE_INFRA
) && (ieee
->state
== IEEE80211_NOLINK
) &&\
4687 (ieee
->eRFPowerState
== eRfOn
)&&!ieee
->is_set_key
&&\
4688 (!ieee
->proto_stoppping
) && !ieee
->wx_set_enc
){
4689 if(ieee
->PowerSaveControl
.ReturnPoint
== IPS_CALLBACK_NONE
){
4690 //printk("====================>haha:IPSEnter()\n");
4692 //ieee80211_stop_scan(priv->ieee80211);
4697 {//to get busy traffic condition
4698 if(ieee
->state
== IEEE80211_LINKED
)
4700 if( ieee
->LinkDetectInfo
.NumRxOkInPeriod
> 100 ||
4701 ieee
->LinkDetectInfo
.NumTxOkInPeriod
> 100 ) {
4702 bBusyTraffic
= true;
4706 //added by amy for Leisure PS
4707 if( ((ieee
->LinkDetectInfo
.NumRxUnicastOkInPeriod
+ ieee
->LinkDetectInfo
.NumTxOkInPeriod
) > 8 ) ||
4708 (ieee
->LinkDetectInfo
.NumRxUnicastOkInPeriod
> 2) )
4710 //printk("ieee->LinkDetectInfo.NumRxUnicastOkInPeriod is %d,ieee->LinkDetectInfo.NumTxOkInPeriod is %d\n",
4711 // ieee->LinkDetectInfo.NumRxUnicastOkInPeriod,ieee->LinkDetectInfo.NumTxOkInPeriod);
4719 //printk("***bEnterPS = %d\n", bEnterPS);
4720 // LeisurePS only work in infra mode.
4723 LeisurePSEnter(dev
);
4727 LeisurePSLeave(dev
);
4735 //RT_TRACE(COMP_LPS,"====>no link LPS leave\n");
4736 LeisurePSLeave(dev
);
4740 ieee
->LinkDetectInfo
.NumRxOkInPeriod
= 0;
4741 ieee
->LinkDetectInfo
.NumTxOkInPeriod
= 0;
4742 ieee
->LinkDetectInfo
.NumRxUnicastOkInPeriod
= 0;
4743 ieee
->LinkDetectInfo
.bBusyTraffic
= bBusyTraffic
;
4747 //added by amy for AP roaming
4750 if(ieee
->state
== IEEE80211_LINKED
&& ieee
->iw_mode
== IW_MODE_INFRA
)
4752 u32 TotalRxBcnNum
= 0;
4753 u32 TotalRxDataNum
= 0;
4755 rtl819x_update_rxcounts(priv
, &TotalRxBcnNum
, &TotalRxDataNum
);
4756 if((TotalRxBcnNum
+TotalRxDataNum
) == 0)
4758 if( ieee
->eRFPowerState
== eRfOff
)
4759 RT_TRACE(COMP_ERR
,"========>%s()\n",__FUNCTION__
);
4760 printk("===>%s(): AP is power off,connect another one\n",__FUNCTION__
);
4761 // Dot11d_Reset(dev);
4762 ieee
->state
= IEEE80211_ASSOCIATING
;
4763 notify_wx_assoc_event(priv
->ieee80211
);
4764 RemovePeerTS(priv
->ieee80211
,priv
->ieee80211
->current_network
.bssid
);
4765 ieee
->is_roaming
= true;
4766 ieee
->is_set_key
= false;
4767 ieee
->link_change(dev
);
4768 queue_work(ieee
->wq
, &ieee
->associate_procedure_wq
);
4771 ieee
->LinkDetectInfo
.NumRecvBcnInPeriod
=0;
4772 ieee
->LinkDetectInfo
.NumRecvDataInPeriod
=0;
4775 //check if reset the driver
4776 spin_lock_irqsave(&priv
->tx_lock
,flags
);
4777 if(check_reset_cnt
++ >= 3 && !ieee
->is_roaming
&& (last_time
!= 1))
4779 ResetType
= rtl819x_ifcheck_resetornot(dev
);
4780 check_reset_cnt
= 3;
4781 //DbgPrint("Start to check silent reset\n");
4783 spin_unlock_irqrestore(&priv
->tx_lock
,flags
);
4784 if(!priv
->bDisableNormalResetCheck
&& ResetType
== RESET_TYPE_NORMAL
)
4786 priv
->ResetProgress
= RESET_TYPE_NORMAL
;
4787 RT_TRACE(COMP_RESET
,"%s(): NOMAL RESET\n",__FUNCTION__
);
4790 /* disable silent reset temply 2008.9.11*/
4792 if( ((priv
->force_reset
) || (!priv
->bDisableNormalResetCheck
&& ResetType
==RESET_TYPE_SILENT
))) // This is control by OID set in Pomelo
4795 rtl819x_ifsilentreset(dev
);
4800 priv
->force_reset
= false;
4801 priv
->bForcedSilentReset
= false;
4802 priv
->bResetInProgress
= false;
4803 RT_TRACE(COMP_TRACE
, " <==RtUsbCheckForHangWorkItemCallback()\n");
4807 void watch_dog_timer_callback(unsigned long data
)
4809 struct r8192_priv
*priv
= ieee80211_priv((struct net_device
*) data
);
4810 queue_delayed_work(priv
->priv_wq
,&priv
->watch_dog_wq
,0);
4811 mod_timer(&priv
->watch_dog_timer
, jiffies
+ MSECS(IEEE80211_WATCH_DOG_TIME
));
4814 int _rtl8192_up(struct net_device
*dev
)
4816 struct r8192_priv
*priv
= ieee80211_priv(dev
);
4818 RT_STATUS init_status
= RT_STATUS_SUCCESS
;
4820 priv
->ieee80211
->ieee_up
=1;
4821 priv
->bdisable_nic
= false; //YJ,add,091111
4822 RT_TRACE(COMP_INIT
, "Bringing up iface");
4824 init_status
= rtl8192_adapter_start(dev
);
4825 if(init_status
!= RT_STATUS_SUCCESS
)
4827 RT_TRACE(COMP_ERR
,"ERR!!! %s(): initialization is failed!\n",__FUNCTION__
);
4830 RT_TRACE(COMP_INIT
, "start adapter finished\n");
4832 if(priv
->ieee80211
->eRFPowerState
!=eRfOn
)
4833 MgntActSet_RF_State(dev
, eRfOn
, priv
->ieee80211
->RfOffReason
);
4835 if(priv
->ieee80211
->state
!= IEEE80211_LINKED
)
4836 ieee80211_softmac_start_protocol(priv
->ieee80211
);
4837 ieee80211_reset_queue(priv
->ieee80211
);
4838 watch_dog_timer_callback((unsigned long) dev
);
4839 if(!netif_queue_stopped(dev
))
4840 netif_start_queue(dev
);
4842 netif_wake_queue(dev
);
4848 static int rtl8192_open(struct net_device
*dev
)
4850 struct r8192_priv
*priv
= ieee80211_priv(dev
);
4853 down(&priv
->wx_sem
);
4854 ret
= rtl8192_up(dev
);
4861 int rtl8192_up(struct net_device
*dev
)
4863 struct r8192_priv
*priv
= ieee80211_priv(dev
);
4865 if (priv
->up
== 1) return -1;
4867 return _rtl8192_up(dev
);
4871 static int rtl8192_close(struct net_device
*dev
)
4873 struct r8192_priv
*priv
= ieee80211_priv(dev
);
4876 down(&priv
->wx_sem
);
4878 ret
= rtl8192_down(dev
);
4886 int rtl8192_down(struct net_device
*dev
)
4888 struct r8192_priv
*priv
= ieee80211_priv(dev
);
4894 if (priv
->up
== 0) return -1;
4897 //LZM for PS-Poll AID issue. 090429
4898 if(priv
->ieee80211
->state
== IEEE80211_LINKED
)
4899 LeisurePSLeave(dev
);
4903 priv
->ieee80211
->ieee_up
= 0;
4904 RT_TRACE(COMP_DOWN
, "==========>%s()\n", __FUNCTION__
);
4906 if (!netif_queue_stopped(dev
))
4907 netif_stop_queue(dev
);
4909 rtl8192_irq_disable(dev
);
4911 if(!priv
->ieee80211
->bSupportRemoteWakeUp
) {
4912 MgntActSet_RF_State(dev
, eRfOff
, RF_CHANGE_BY_INIT
);
4913 // 2006.11.30. System reset bit
4914 ulRegRead
= read_nic_dword(dev
, CPU_GEN
);
4915 ulRegRead
|=CPU_GEN_SYSTEM_RESET
;
4916 write_nic_dword(dev
, CPU_GEN
, ulRegRead
);
4918 //2008.06.03 for WOL
4919 write_nic_dword(dev
, WFCRC0
, 0xffffffff);
4920 write_nic_dword(dev
, WFCRC1
, 0xffffffff);
4921 write_nic_dword(dev
, WFCRC2
, 0xffffffff);
4924 ucRegRead
= read_nic_byte(dev
, GPO
);
4926 write_nic_byte(dev
, GPO
, ucRegRead
);
4928 //Write PMR register
4929 write_nic_byte(dev
, PMR
, 0x5);
4930 //Disable tx, enanble rx
4931 write_nic_byte(dev
, MacBlkCtrl
, 0xa);
4934 // flush_scheduled_work();
4935 rtl8192_cancel_deferred_work(priv
);
4937 del_timer_sync(&priv
->watch_dog_timer
);
4939 ieee80211_softmac_stop_protocol(priv
->ieee80211
,true);
4941 rtl8192_halt_adapter(dev
,false);
4942 memset(&priv
->ieee80211
->current_network
, 0 , offsetof(struct ieee80211_network
, list
));
4944 RT_TRACE(COMP_DOWN
, "<==========%s()\n", __FUNCTION__
);
4950 void rtl8192_commit(struct net_device
*dev
)
4952 struct r8192_priv
*priv
= ieee80211_priv(dev
);
4954 if (priv
->up
== 0) return ;
4957 ieee80211_softmac_stop_protocol(priv
->ieee80211
,true);
4959 rtl8192_irq_disable(dev
);
4960 rtl8192_halt_adapter(dev
,true);
4964 void rtl8192_restart(struct work_struct
*work
)
4966 struct r8192_priv
*priv
= container_of(work
, struct r8192_priv
, reset_wq
);
4967 struct net_device
*dev
= priv
->ieee80211
->dev
;
4969 down(&priv
->wx_sem
);
4971 rtl8192_commit(dev
);
4976 static void r8192_set_multicast(struct net_device
*dev
)
4978 struct r8192_priv
*priv
= ieee80211_priv(dev
);
4981 //down(&priv->wx_sem);
4985 promisc
= (dev
->flags
& IFF_PROMISC
) ? 1:0;
4987 if (promisc
!= priv
->promisc
) {
4989 // rtl8192_commit(dev);
4992 priv
->promisc
= promisc
;
4994 //schedule_work(&priv->reset_wq);
4995 //up(&priv->wx_sem);
4999 static int r8192_set_mac_adr(struct net_device
*dev
, void *mac
)
5001 struct r8192_priv
*priv
= ieee80211_priv(dev
);
5002 struct sockaddr
*addr
= mac
;
5004 down(&priv
->wx_sem
);
5006 memcpy(dev
->dev_addr
, addr
->sa_data
, ETH_ALEN
);
5008 schedule_work(&priv
->reset_wq
);
5014 /* based on ipw2200 driver */
5015 static int rtl8192_ioctl(struct net_device
*dev
, struct ifreq
*rq
, int cmd
)
5017 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
5018 struct iwreq
*wrq
= (struct iwreq
*)rq
;
5020 struct ieee80211_device
*ieee
= priv
->ieee80211
;
5022 u8 broadcast_addr
[6] = {0xff,0xff,0xff,0xff,0xff,0xff};
5023 struct iw_point
*p
= &wrq
->u
.data
;
5024 struct ieee_param
*ipw
= NULL
;//(struct ieee_param *)wrq->u.data.pointer;
5026 down(&priv
->wx_sem
);
5029 if (p
->length
< sizeof(struct ieee_param
) || !p
->pointer
){
5034 ipw
= kmalloc(p
->length
, GFP_KERNEL
);
5039 if (copy_from_user(ipw
, p
->pointer
, p
->length
)) {
5046 case RTL_IOCTL_WPA_SUPPLICANT
:
5047 //parse here for HW security
5048 if (ipw
->cmd
== IEEE_CMD_SET_ENCRYPTION
)
5050 if (ipw
->u
.crypt
.set_tx
)
5052 if (strcmp(ipw
->u
.crypt
.alg
, "CCMP") == 0)
5053 ieee
->pairwise_key_type
= KEY_TYPE_CCMP
;
5054 else if (strcmp(ipw
->u
.crypt
.alg
, "TKIP") == 0)
5055 ieee
->pairwise_key_type
= KEY_TYPE_TKIP
;
5056 else if (strcmp(ipw
->u
.crypt
.alg
, "WEP") == 0)
5058 if (ipw
->u
.crypt
.key_len
== 13)
5059 ieee
->pairwise_key_type
= KEY_TYPE_WEP104
;
5060 else if (ipw
->u
.crypt
.key_len
== 5)
5061 ieee
->pairwise_key_type
= KEY_TYPE_WEP40
;
5064 ieee
->pairwise_key_type
= KEY_TYPE_NA
;
5066 if (ieee
->pairwise_key_type
)
5068 memcpy((u8
*)key
, ipw
->u
.crypt
.key
, 16);
5069 EnableHWSecurityConfig8192(dev
);
5070 //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!
5072 setKey(dev
, 4, ipw
->u
.crypt
.idx
, ieee
->pairwise_key_type
, (u8
*)ieee
->ap_mac_addr
, 0, key
);
5073 if (ieee
->auth_mode
!= 2) //LEAP WEP will never set this.
5074 setKey(dev
, ipw
->u
.crypt
.idx
, ipw
->u
.crypt
.idx
, ieee
->pairwise_key_type
, (u8
*)ieee
->ap_mac_addr
, 0, key
);
5076 if ((ieee
->pairwise_key_type
== KEY_TYPE_CCMP
) && ieee
->pHTInfo
->bCurrentHTSupport
){
5077 write_nic_byte(dev
, 0x173, 1); //fix aes bug
5081 else //if (ipw->u.crypt.idx) //group key use idx > 0
5083 memcpy((u8
*)key
, ipw
->u
.crypt
.key
, 16);
5084 if (strcmp(ipw
->u
.crypt
.alg
, "CCMP") == 0)
5085 ieee
->group_key_type
= KEY_TYPE_CCMP
;
5086 else if (strcmp(ipw
->u
.crypt
.alg
, "TKIP") == 0)
5087 ieee
->group_key_type
= KEY_TYPE_TKIP
;
5088 else if (strcmp(ipw
->u
.crypt
.alg
, "WEP") == 0)
5090 if (ipw
->u
.crypt
.key_len
== 13)
5091 ieee
->group_key_type
= KEY_TYPE_WEP104
;
5092 else if (ipw
->u
.crypt
.key_len
== 5)
5093 ieee
->group_key_type
= KEY_TYPE_WEP40
;
5096 ieee
->group_key_type
= KEY_TYPE_NA
;
5098 if (ieee
->group_key_type
)
5102 ipw
->u
.crypt
.idx
, //KeyIndex
5103 ieee
->group_key_type
, //KeyType
5104 broadcast_addr
, //MacAddr
5114 printk("@@ wrq->u pointer = ");
5115 for(i
=0;i
<wrq
->u
.data
.length
;i
++){
5116 if(i
%10==0) printk("\n");
5117 printk( "%8x|", ((u32
*)wrq
->u
.data
.pointer
)[i
] );
5121 #endif /*JOHN_DEBUG*/
5122 ret
= ieee80211_wpa_supplicant_ioctl(priv
->ieee80211
, &wrq
->u
.data
);
5137 static u8
HwRateToMRate90(bool bIsHT
, u8 rate
)
5143 case DESC90_RATE1M
: ret_rate
= MGN_1M
; break;
5144 case DESC90_RATE2M
: ret_rate
= MGN_2M
; break;
5145 case DESC90_RATE5_5M
: ret_rate
= MGN_5_5M
; break;
5146 case DESC90_RATE11M
: ret_rate
= MGN_11M
; break;
5147 case DESC90_RATE6M
: ret_rate
= MGN_6M
; break;
5148 case DESC90_RATE9M
: ret_rate
= MGN_9M
; break;
5149 case DESC90_RATE12M
: ret_rate
= MGN_12M
; break;
5150 case DESC90_RATE18M
: ret_rate
= MGN_18M
; break;
5151 case DESC90_RATE24M
: ret_rate
= MGN_24M
; break;
5152 case DESC90_RATE36M
: ret_rate
= MGN_36M
; break;
5153 case DESC90_RATE48M
: ret_rate
= MGN_48M
; break;
5154 case DESC90_RATE54M
: ret_rate
= MGN_54M
; break;
5157 RT_TRACE(COMP_RECV
, "HwRateToMRate90(): Non supported Rate [%x], bIsHT = %d!!!\n", rate
, bIsHT
);
5163 case DESC90_RATEMCS0
: ret_rate
= MGN_MCS0
; break;
5164 case DESC90_RATEMCS1
: ret_rate
= MGN_MCS1
; break;
5165 case DESC90_RATEMCS2
: ret_rate
= MGN_MCS2
; break;
5166 case DESC90_RATEMCS3
: ret_rate
= MGN_MCS3
; break;
5167 case DESC90_RATEMCS4
: ret_rate
= MGN_MCS4
; break;
5168 case DESC90_RATEMCS5
: ret_rate
= MGN_MCS5
; break;
5169 case DESC90_RATEMCS6
: ret_rate
= MGN_MCS6
; break;
5170 case DESC90_RATEMCS7
: ret_rate
= MGN_MCS7
; break;
5171 case DESC90_RATEMCS8
: ret_rate
= MGN_MCS8
; break;
5172 case DESC90_RATEMCS9
: ret_rate
= MGN_MCS9
; break;
5173 case DESC90_RATEMCS10
: ret_rate
= MGN_MCS10
; break;
5174 case DESC90_RATEMCS11
: ret_rate
= MGN_MCS11
; break;
5175 case DESC90_RATEMCS12
: ret_rate
= MGN_MCS12
; break;
5176 case DESC90_RATEMCS13
: ret_rate
= MGN_MCS13
; break;
5177 case DESC90_RATEMCS14
: ret_rate
= MGN_MCS14
; break;
5178 case DESC90_RATEMCS15
: ret_rate
= MGN_MCS15
; break;
5179 case DESC90_RATEMCS32
: ret_rate
= (0x80|0x20); break;
5182 RT_TRACE(COMP_RECV
, "HwRateToMRate90(): Non supported Rate [%x], bIsHT = %d!!!\n",rate
, bIsHT
);
5191 * Function: UpdateRxPktTimeStamp
5192 * Overview: Recored down the TSF time stamp when receiving a packet
5200 * (pRfd->Status.TimeStampHigh is updated)
5201 * (pRfd->Status.TimeStampLow is updated)
5205 static void UpdateRxPktTimeStamp8190 (struct net_device
*dev
, struct ieee80211_rx_stats
*stats
)
5207 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
5209 if(stats
->bIsAMPDU
&& !stats
->bFirstMPDU
) {
5210 stats
->mac_time
[0] = priv
->LastRxDescTSFLow
;
5211 stats
->mac_time
[1] = priv
->LastRxDescTSFHigh
;
5213 priv
->LastRxDescTSFLow
= stats
->mac_time
[0];
5214 priv
->LastRxDescTSFHigh
= stats
->mac_time
[1];
5218 static long rtl819x_translate_todbm(u8 signal_strength_index
)// 0-100 index.
5220 long signal_power
; // in dBm.
5222 // Translate to dBm (x=0.5y-95).
5223 signal_power
= (long)((signal_strength_index
+ 1) >> 1);
5226 return signal_power
;
5231 // Update Rx signal related information in the packet reeived
5232 // to RxStats. User application can query RxStats to realize
5233 // current Rx signal status.
5236 // In normal operation, user only care about the information of the BSS
5237 // and we shall invoke this function if the packet received is from the BSS.
5240 rtl819x_update_rxsignalstatistics8190pci(
5241 struct r8192_priv
* priv
,
5242 struct ieee80211_rx_stats
* pprevious_stats
5247 //2 <ToDo> Update Rx Statistics (such as signal strength and signal quality).
5250 if(priv
->stats
.recv_signal_power
== 0)
5251 priv
->stats
.recv_signal_power
= pprevious_stats
->RecvSignalPower
;
5253 // To avoid the past result restricting the statistics sensitivity, weight the current power (5/6) to speed up the
5254 // reaction of smoothed Signal Power.
5255 if(pprevious_stats
->RecvSignalPower
> priv
->stats
.recv_signal_power
)
5257 else if(pprevious_stats
->RecvSignalPower
< priv
->stats
.recv_signal_power
)
5260 // We need more correct power of received packets and the "SignalStrength" of RxStats have been beautified or translated,
5261 // so we record the correct power in Dbm here. By Bruce, 2008-03-07.
5263 priv
->stats
.recv_signal_power
= (priv
->stats
.recv_signal_power
* 5 + pprevious_stats
->RecvSignalPower
+ weighting
) / 6;
5267 rtl8190_process_cck_rxpathsel(
5268 struct r8192_priv
* priv
,
5269 struct ieee80211_rx_stats
* pprevious_stats
5272 #ifdef RTL8190P //Only 90P 2T4R need to check
5273 char last_cck_adc_pwdb
[4]={0,0,0,0};
5275 //cosa add for Rx path selection
5276 if(priv
->rf_type
== RF_2T4R
&& DM_RxPathSelTable
.Enable
)
5278 if(pprevious_stats
->bIsCCK
&&
5279 (pprevious_stats
->bPacketToSelf
||pprevious_stats
->bPacketBeacon
))
5281 /* record the cck adc_pwdb to the sliding window. */
5282 if(priv
->stats
.cck_adc_pwdb
.TotalNum
++ >= PHY_RSSI_SLID_WIN_MAX
)
5284 priv
->stats
.cck_adc_pwdb
.TotalNum
= PHY_RSSI_SLID_WIN_MAX
;
5285 for(i
=RF90_PATH_A
; i
<RF90_PATH_MAX
; i
++)
5287 last_cck_adc_pwdb
[i
] = priv
->stats
.cck_adc_pwdb
.elements
[i
][priv
->stats
.cck_adc_pwdb
.index
];
5288 priv
->stats
.cck_adc_pwdb
.TotalVal
[i
] -= last_cck_adc_pwdb
[i
];
5291 for(i
=RF90_PATH_A
; i
<RF90_PATH_MAX
; i
++)
5293 priv
->stats
.cck_adc_pwdb
.TotalVal
[i
] += pprevious_stats
->cck_adc_pwdb
[i
];
5294 priv
->stats
.cck_adc_pwdb
.elements
[i
][priv
->stats
.cck_adc_pwdb
.index
] = pprevious_stats
->cck_adc_pwdb
[i
];
5296 priv
->stats
.cck_adc_pwdb
.index
++;
5297 if(priv
->stats
.cck_adc_pwdb
.index
>= PHY_RSSI_SLID_WIN_MAX
)
5298 priv
->stats
.cck_adc_pwdb
.index
= 0;
5300 for(i
=RF90_PATH_A
; i
<RF90_PATH_MAX
; i
++)
5302 DM_RxPathSelTable
.cck_pwdb_sta
[i
] = priv
->stats
.cck_adc_pwdb
.TotalVal
[i
]/priv
->stats
.cck_adc_pwdb
.TotalNum
;
5305 for(i
=RF90_PATH_A
; i
<RF90_PATH_MAX
; i
++)
5307 if(pprevious_stats
->cck_adc_pwdb
[i
] > (char)priv
->undecorated_smoothed_cck_adc_pwdb
[i
])
5309 priv
->undecorated_smoothed_cck_adc_pwdb
[i
] =
5310 ( (priv
->undecorated_smoothed_cck_adc_pwdb
[i
]*(Rx_Smooth_Factor
-1)) +
5311 (pprevious_stats
->cck_adc_pwdb
[i
])) /(Rx_Smooth_Factor
);
5312 priv
->undecorated_smoothed_cck_adc_pwdb
[i
] = priv
->undecorated_smoothed_cck_adc_pwdb
[i
] + 1;
5316 priv
->undecorated_smoothed_cck_adc_pwdb
[i
] =
5317 ( (priv
->undecorated_smoothed_cck_adc_pwdb
[i
]*(Rx_Smooth_Factor
-1)) +
5318 (pprevious_stats
->cck_adc_pwdb
[i
])) /(Rx_Smooth_Factor
);
5327 /* 2008/01/22 MH We can not delcare RSSI/EVM total value of sliding window to
5328 be a local static. Otherwise, it may increase when we return from S3/S4. The
5329 value will be kept in memory or disk. We must delcare the value in adapter
5330 and it will be reinitialized when return from S3/S4. */
5331 static void rtl8192_process_phyinfo(struct r8192_priv
* priv
, u8
* buffer
,struct ieee80211_rx_stats
* pprevious_stats
, struct ieee80211_rx_stats
* pcurrent_stats
)
5333 bool bcheck
= false;
5335 u32 nspatial_stream
, tmp_val
;
5337 static u32 slide_rssi_index
=0, slide_rssi_statistics
=0;
5338 static u32 slide_evm_index
=0, slide_evm_statistics
=0;
5339 static u32 last_rssi
=0, last_evm
=0;
5340 //cosa add for rx path selection
5341 // static long slide_cck_adc_pwdb_index=0, slide_cck_adc_pwdb_statistics=0;
5342 // static char last_cck_adc_pwdb[4]={0,0,0,0};
5343 //cosa add for beacon rssi smoothing
5344 static u32 slide_beacon_adc_pwdb_index
=0, slide_beacon_adc_pwdb_statistics
=0;
5345 static u32 last_beacon_adc_pwdb
=0;
5347 struct ieee80211_hdr_3addr
*hdr
;
5349 unsigned int frag
,seq
;
5350 hdr
= (struct ieee80211_hdr_3addr
*)buffer
;
5351 sc
= le16_to_cpu(hdr
->seq_ctl
);
5352 frag
= WLAN_GET_SEQ_FRAG(sc
);
5353 seq
= WLAN_GET_SEQ_SEQ(sc
);
5354 //cosa add 04292008 to record the sequence number
5355 pcurrent_stats
->Seq_Num
= seq
;
5357 // Check whether we should take the previous packet into accounting
5359 if(!pprevious_stats
->bIsAMPDU
)
5361 // if previous packet is not aggregated packet
5365 //remve for that we don't use AMPDU to calculate PWDB,because the reported PWDB of some AP is fault.
5367 // if previous packet is aggregated packet, and current packet
5369 // (2) is the first packet of one AMPDU
5370 // that means the previous packet is the last one aggregated packet
5371 if( !pcurrent_stats
->bIsAMPDU
|| pcurrent_stats
->bFirstMPDU
)
5376 if(slide_rssi_statistics
++ >= PHY_RSSI_SLID_WIN_MAX
)
5378 slide_rssi_statistics
= PHY_RSSI_SLID_WIN_MAX
;
5379 last_rssi
= priv
->stats
.slide_signal_strength
[slide_rssi_index
];
5380 priv
->stats
.slide_rssi_total
-= last_rssi
;
5382 priv
->stats
.slide_rssi_total
+= pprevious_stats
->SignalStrength
;
5384 priv
->stats
.slide_signal_strength
[slide_rssi_index
++] = pprevious_stats
->SignalStrength
;
5385 if(slide_rssi_index
>= PHY_RSSI_SLID_WIN_MAX
)
5386 slide_rssi_index
= 0;
5388 // <1> Showed on UI for user, in dbm
5389 tmp_val
= priv
->stats
.slide_rssi_total
/slide_rssi_statistics
;
5390 priv
->stats
.signal_strength
= rtl819x_translate_todbm((u8
)tmp_val
);
5391 pcurrent_stats
->rssi
= priv
->stats
.signal_strength
;
5393 // If the previous packet does not match the criteria, neglect it
5395 if(!pprevious_stats
->bPacketMatchBSSID
)
5397 if(!pprevious_stats
->bToSelfBA
)
5404 rtl8190_process_cck_rxpathsel(priv
,pprevious_stats
);
5409 priv
->stats
.num_process_phyinfo
++;
5411 /* record the general signal strength to the sliding window. */
5412 if(slide_rssi_statistics
++ >= PHY_RSSI_SLID_WIN_MAX
)
5414 slide_rssi_statistics
= PHY_RSSI_SLID_WIN_MAX
;
5415 last_rssi
= priv
->stats
.slide_signal_strength
[slide_rssi_index
];
5416 priv
->stats
.slide_rssi_total
-= last_rssi
;
5418 priv
->stats
.slide_rssi_total
+= pprevious_stats
->SignalStrength
;
5420 priv
->stats
.slide_signal_strength
[slide_rssi_index
++] = pprevious_stats
->SignalStrength
;
5421 if(slide_rssi_index
>= PHY_RSSI_SLID_WIN_MAX
)
5422 slide_rssi_index
= 0;
5424 // <1> Showed on UI for user, in dbm
5425 tmp_val
= priv
->stats
.slide_rssi_total
/slide_rssi_statistics
;
5426 priv
->stats
.signal_strength
= rtl819x_translate_todbm((u8
)tmp_val
);
5429 // <2> Showed on UI for engineering
5430 // hardware does not provide rssi information for each rf path in CCK
5431 if(!pprevious_stats
->bIsCCK
&& pprevious_stats
->bPacketToSelf
)
5433 for (rfpath
= RF90_PATH_A
; rfpath
< RF90_PATH_C
; rfpath
++)
5435 if (!rtl8192_phy_CheckIsLegalRFPath(priv
->ieee80211
->dev
, rfpath
))
5437 RT_TRACE(COMP_DBG
,"Jacken -> pPreviousstats->RxMIMOSignalStrength[rfpath] = %d \n" ,pprevious_stats
->RxMIMOSignalStrength
[rfpath
] );
5438 //Fixed by Jacken 2008-03-20
5439 if(priv
->stats
.rx_rssi_percentage
[rfpath
] == 0)
5441 priv
->stats
.rx_rssi_percentage
[rfpath
] = pprevious_stats
->RxMIMOSignalStrength
[rfpath
];
5442 //DbgPrint("MIMO RSSI initialize \n");
5444 if(pprevious_stats
->RxMIMOSignalStrength
[rfpath
] > priv
->stats
.rx_rssi_percentage
[rfpath
])
5446 priv
->stats
.rx_rssi_percentage
[rfpath
] =
5447 ( (priv
->stats
.rx_rssi_percentage
[rfpath
]*(Rx_Smooth_Factor
-1)) +
5448 (pprevious_stats
->RxMIMOSignalStrength
[rfpath
])) /(Rx_Smooth_Factor
);
5449 priv
->stats
.rx_rssi_percentage
[rfpath
] = priv
->stats
.rx_rssi_percentage
[rfpath
] + 1;
5453 priv
->stats
.rx_rssi_percentage
[rfpath
] =
5454 ( (priv
->stats
.rx_rssi_percentage
[rfpath
]*(Rx_Smooth_Factor
-1)) +
5455 (pprevious_stats
->RxMIMOSignalStrength
[rfpath
])) /(Rx_Smooth_Factor
);
5457 RT_TRACE(COMP_DBG
,"Jacken -> priv->RxStats.RxRSSIPercentage[rfPath] = %d \n" ,priv
->stats
.rx_rssi_percentage
[rfpath
] );
5465 //cosa add for beacon rssi smoothing by average.
5466 if(pprevious_stats
->bPacketBeacon
)
5468 /* record the beacon pwdb to the sliding window. */
5469 if(slide_beacon_adc_pwdb_statistics
++ >= PHY_Beacon_RSSI_SLID_WIN_MAX
)
5471 slide_beacon_adc_pwdb_statistics
= PHY_Beacon_RSSI_SLID_WIN_MAX
;
5472 last_beacon_adc_pwdb
= priv
->stats
.Slide_Beacon_pwdb
[slide_beacon_adc_pwdb_index
];
5473 priv
->stats
.Slide_Beacon_Total
-= last_beacon_adc_pwdb
;
5474 //DbgPrint("slide_beacon_adc_pwdb_index = %d, last_beacon_adc_pwdb = %d, Adapter->RxStats.Slide_Beacon_Total = %d\n",
5475 // slide_beacon_adc_pwdb_index, last_beacon_adc_pwdb, Adapter->RxStats.Slide_Beacon_Total);
5477 priv
->stats
.Slide_Beacon_Total
+= pprevious_stats
->RxPWDBAll
;
5478 priv
->stats
.Slide_Beacon_pwdb
[slide_beacon_adc_pwdb_index
] = pprevious_stats
->RxPWDBAll
;
5479 //DbgPrint("slide_beacon_adc_pwdb_index = %d, pPreviousRfd->Status.RxPWDBAll = %d\n", slide_beacon_adc_pwdb_index, pPreviousRfd->Status.RxPWDBAll);
5480 slide_beacon_adc_pwdb_index
++;
5481 if(slide_beacon_adc_pwdb_index
>= PHY_Beacon_RSSI_SLID_WIN_MAX
)
5482 slide_beacon_adc_pwdb_index
= 0;
5483 pprevious_stats
->RxPWDBAll
= priv
->stats
.Slide_Beacon_Total
/slide_beacon_adc_pwdb_statistics
;
5484 if(pprevious_stats
->RxPWDBAll
>= 3)
5485 pprevious_stats
->RxPWDBAll
-= 3;
5488 RT_TRACE(COMP_RXDESC
, "Smooth %s PWDB = %d\n",
5489 pprevious_stats
->bIsCCK
? "CCK": "OFDM",
5490 pprevious_stats
->RxPWDBAll
);
5492 if(pprevious_stats
->bPacketToSelf
|| pprevious_stats
->bPacketBeacon
|| pprevious_stats
->bToSelfBA
)
5494 if(priv
->undecorated_smoothed_pwdb
< 0) // initialize
5496 priv
->undecorated_smoothed_pwdb
= pprevious_stats
->RxPWDBAll
;
5497 //DbgPrint("First pwdb initialize \n");
5500 if(pprevious_stats
->RxPWDBAll
> (u32
)priv
->undecorated_smoothed_pwdb
)
5502 priv
->undecorated_smoothed_pwdb
=
5503 ( ((priv
->undecorated_smoothed_pwdb
)*(Rx_Smooth_Factor
-1)) +
5504 (pprevious_stats
->RxPWDBAll
)) /(Rx_Smooth_Factor
);
5505 priv
->undecorated_smoothed_pwdb
= priv
->undecorated_smoothed_pwdb
+ 1;
5509 priv
->undecorated_smoothed_pwdb
=
5510 ( ((priv
->undecorated_smoothed_pwdb
)*(Rx_Smooth_Factor
-1)) +
5511 (pprevious_stats
->RxPWDBAll
)) /(Rx_Smooth_Factor
);
5514 //Fixed by Jacken 2008-03-20
5515 if(pPreviousRfd
->Status
.RxPWDBAll
> (u32
)pHalData
->UndecoratedSmoothedPWDB
)
5517 pHalData
->UndecoratedSmoothedPWDB
=
5518 ( ((pHalData
->UndecoratedSmoothedPWDB
)* 5) + (pPreviousRfd
->Status
.RxPWDBAll
)) / 6;
5519 pHalData
->UndecoratedSmoothedPWDB
= pHalData
->UndecoratedSmoothedPWDB
+ 1;
5523 pHalData
->UndecoratedSmoothedPWDB
=
5524 ( ((pHalData
->UndecoratedSmoothedPWDB
)* 5) + (pPreviousRfd
->Status
.RxPWDBAll
)) / 6;
5527 rtl819x_update_rxsignalstatistics8190pci(priv
,pprevious_stats
);
5533 /* record the general EVM to the sliding window. */
5534 if(pprevious_stats
->SignalQuality
== 0)
5539 if(pprevious_stats
->bPacketToSelf
|| pprevious_stats
->bPacketBeacon
|| pprevious_stats
->bToSelfBA
){
5540 if(slide_evm_statistics
++ >= PHY_RSSI_SLID_WIN_MAX
){
5541 slide_evm_statistics
= PHY_RSSI_SLID_WIN_MAX
;
5542 last_evm
= priv
->stats
.slide_evm
[slide_evm_index
];
5543 priv
->stats
.slide_evm_total
-= last_evm
;
5546 priv
->stats
.slide_evm_total
+= pprevious_stats
->SignalQuality
;
5548 priv
->stats
.slide_evm
[slide_evm_index
++] = pprevious_stats
->SignalQuality
;
5549 if(slide_evm_index
>= PHY_RSSI_SLID_WIN_MAX
)
5550 slide_evm_index
= 0;
5552 // <1> Showed on UI for user, in percentage.
5553 tmp_val
= priv
->stats
.slide_evm_total
/slide_evm_statistics
;
5554 priv
->stats
.signal_quality
= tmp_val
;
5555 //cosa add 10/11/2007, Showed on UI for user in Windows Vista, for Link quality.
5556 priv
->stats
.last_signal_strength_inpercent
= tmp_val
;
5559 // <2> Showed on UI for engineering
5560 if(pprevious_stats
->bPacketToSelf
|| pprevious_stats
->bPacketBeacon
|| pprevious_stats
->bToSelfBA
)
5562 for(nspatial_stream
= 0; nspatial_stream
<2 ; nspatial_stream
++) // 2 spatial stream
5564 if(pprevious_stats
->RxMIMOSignalQuality
[nspatial_stream
] != -1)
5566 if(priv
->stats
.rx_evm_percentage
[nspatial_stream
] == 0) // initialize
5568 priv
->stats
.rx_evm_percentage
[nspatial_stream
] = pprevious_stats
->RxMIMOSignalQuality
[nspatial_stream
];
5570 priv
->stats
.rx_evm_percentage
[nspatial_stream
] =
5571 ( (priv
->stats
.rx_evm_percentage
[nspatial_stream
]* (Rx_Smooth_Factor
-1)) +
5572 (pprevious_stats
->RxMIMOSignalQuality
[nspatial_stream
]* 1)) / (Rx_Smooth_Factor
);
5580 /*-----------------------------------------------------------------------------
5581 * Function: rtl819x_query_rxpwrpercentage()
5585 * Input: char antpower
5589 * Return: 0-100 percentage
5593 * 05/26/2008 amy Create Version 0 porting from windows code.
5595 *---------------------------------------------------------------------------*/
5596 static u8
rtl819x_query_rxpwrpercentage(
5600 if ((antpower
<= -100) || (antpower
>= 20))
5604 else if (antpower
>= 0)
5610 return (100+antpower
);
5613 } /* QueryRxPwrPercentage */
5616 rtl819x_evm_dbtopercentage(
5628 ret_val
= 0 - ret_val
;
5637 // We want good-looking for signal strength/quality
5638 // 2007/7/19 01:09, by cosa.
5640 static long rtl819x_signal_scale_mapping(long currsig
)
5644 // Step 1. Scale mapping.
5645 if(currsig
>= 61 && currsig
<= 100)
5647 retsig
= 90 + ((currsig
- 60) / 4);
5649 else if(currsig
>= 41 && currsig
<= 60)
5651 retsig
= 78 + ((currsig
- 40) / 2);
5653 else if(currsig
>= 31 && currsig
<= 40)
5655 retsig
= 66 + (currsig
- 30);
5657 else if(currsig
>= 21 && currsig
<= 30)
5659 retsig
= 54 + (currsig
- 20);
5661 else if(currsig
>= 5 && currsig
<= 20)
5663 retsig
= 42 + (((currsig
- 5) * 2) / 3);
5665 else if(currsig
== 4)
5669 else if(currsig
== 3)
5673 else if(currsig
== 2)
5677 else if(currsig
== 1)
5689 static void rtl8192_query_rxphystatus(
5690 struct r8192_priv
* priv
,
5691 struct ieee80211_rx_stats
* pstats
,
5692 prx_desc_819x_pci pdesc
,
5693 prx_fwinfo_819x_pci pdrvinfo
,
5694 struct ieee80211_rx_stats
* precord_stats
,
5695 bool bpacket_match_bssid
,
5696 bool bpacket_toself
,
5701 //PRT_RFD_STATUS pRtRfdStatus = &(pRfd->Status);
5702 phy_sts_ofdm_819xpci_t
* pofdm_buf
;
5703 phy_sts_cck_819xpci_t
* pcck_buf
;
5704 phy_ofdm_rx_status_rxsc_sgien_exintfflag
* prxsc
;
5706 u8 i
,max_spatial_stream
, tmp_rxsnr
, tmp_rxevm
, rxsc_sgien_exflg
;
5707 char rx_pwr
[4], rx_pwr_all
=0;
5708 //long rx_avg_pwr = 0;
5709 char rx_snrX
, rx_evmX
;
5711 u32 RSSI
, total_rssi
=0;//, total_evm=0;
5712 // long signal_strength_index = 0;
5716 /* 2007/07/04 MH For OFDM RSSI. For high power or not. */
5717 static u8 check_reg824
= 0;
5718 static u32 reg824_bit9
= 0;
5720 priv
->stats
.numqry_phystatus
++;
5722 is_cck_rate
= rx_hal_is_cck_rate(pdrvinfo
);
5724 // Record it for next packet processing
5725 memset(precord_stats
, 0, sizeof(struct ieee80211_rx_stats
));
5726 pstats
->bPacketMatchBSSID
= precord_stats
->bPacketMatchBSSID
= bpacket_match_bssid
;
5727 pstats
->bPacketToSelf
= precord_stats
->bPacketToSelf
= bpacket_toself
;
5728 pstats
->bIsCCK
= precord_stats
->bIsCCK
= is_cck_rate
;//RX_HAL_IS_CCK_RATE(pDrvInfo);
5729 pstats
->bPacketBeacon
= precord_stats
->bPacketBeacon
= bPacketBeacon
;
5730 pstats
->bToSelfBA
= precord_stats
->bToSelfBA
= bToSelfBA
;
5731 /*2007.08.30 requested by SD3 Jerry */
5732 if(check_reg824
== 0)
5734 reg824_bit9
= rtl8192_QueryBBReg(priv
->ieee80211
->dev
, rFPGA0_XA_HSSIParameter2
, 0x200);
5739 prxpkt
= (u8
*)pdrvinfo
;
5741 /* Move pointer to the 16th bytes. Phy status start address. */
5742 prxpkt
+= sizeof(rx_fwinfo_819x_pci
);
5744 /* Initial the cck and ofdm buffer pointer */
5745 pcck_buf
= (phy_sts_cck_819xpci_t
*)prxpkt
;
5746 pofdm_buf
= (phy_sts_ofdm_819xpci_t
*)prxpkt
;
5748 pstats
->RxMIMOSignalQuality
[0] = -1;
5749 pstats
->RxMIMOSignalQuality
[1] = -1;
5750 precord_stats
->RxMIMOSignalQuality
[0] = -1;
5751 precord_stats
->RxMIMOSignalQuality
[1] = -1;
5756 // (1)Hardware does not provide RSSI for CCK
5760 // (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive)
5762 u8 report
;//, cck_agc_rpt;
5765 char cck_adc_pwdb
[4];
5767 priv
->stats
.numqry_phystatusCCK
++;
5769 #ifdef RTL8190P //Only 90P 2T4R need to check
5770 if(priv
->rf_type
== RF_2T4R
&& DM_RxPathSelTable
.Enable
&& bpacket_match_bssid
)
5772 for(i
=RF90_PATH_A
; i
<RF90_PATH_MAX
; i
++)
5774 tmp_pwdb
= pcck_buf
->adc_pwdb_X
[i
];
5775 cck_adc_pwdb
[i
] = (char)tmp_pwdb
;
5776 cck_adc_pwdb
[i
] /= 2;
5777 pstats
->cck_adc_pwdb
[i
] = precord_stats
->cck_adc_pwdb
[i
] = cck_adc_pwdb
[i
];
5778 //DbgPrint("RF-%d tmp_pwdb = 0x%x, cck_adc_pwdb = %d", i, tmp_pwdb, cck_adc_pwdb[i]);
5785 report
= pcck_buf
->cck_agc_rpt
& 0xc0;
5789 //Fixed by Jacken from Bryant 2008-03-20
5790 //Original value is -38 , -26 , -14 , -2
5791 //Fixed value is -35 , -23 , -11 , 6
5793 rx_pwr_all
= -35 - (pcck_buf
->cck_agc_rpt
& 0x3e);
5796 rx_pwr_all
= -23 - (pcck_buf
->cck_agc_rpt
& 0x3e);
5799 rx_pwr_all
= -11 - (pcck_buf
->cck_agc_rpt
& 0x3e);
5802 rx_pwr_all
= 8 - (pcck_buf
->cck_agc_rpt
& 0x3e);
5808 report
= pcck_buf
->cck_agc_rpt
& 0x60;
5813 rx_pwr_all
= -35 - ((pcck_buf
->cck_agc_rpt
& 0x1f)<<1) ;
5816 rx_pwr_all
= -23 - ((pcck_buf
->cck_agc_rpt
& 0x1f)<<1);
5819 rx_pwr_all
= -11 - ((pcck_buf
->cck_agc_rpt
& 0x1f)<<1) ;
5822 rx_pwr_all
= -8 - ((pcck_buf
->cck_agc_rpt
& 0x1f)<<1) ;
5827 pwdb_all
= rtl819x_query_rxpwrpercentage(rx_pwr_all
);
5828 pstats
->RxPWDBAll
= precord_stats
->RxPWDBAll
= pwdb_all
;
5829 pstats
->RecvSignalPower
= rx_pwr_all
;
5832 // (3) Get Signal Quality (EVM)
5834 if(bpacket_match_bssid
)
5838 if(pstats
->RxPWDBAll
> 40)
5843 sq
= pcck_buf
->sq_rpt
;
5845 if(pcck_buf
->sq_rpt
> 64)
5847 else if (pcck_buf
->sq_rpt
< 20)
5850 sq
= ((64-sq
) * 100) / 44;
5852 pstats
->SignalQuality
= precord_stats
->SignalQuality
= sq
;
5853 pstats
->RxMIMOSignalQuality
[0] = precord_stats
->RxMIMOSignalQuality
[0] = sq
;
5854 pstats
->RxMIMOSignalQuality
[1] = precord_stats
->RxMIMOSignalQuality
[1] = -1;
5859 priv
->stats
.numqry_phystatusHT
++;
5861 // (1)Get RSSI for HT rate
5863 for(i
=RF90_PATH_A
; i
<RF90_PATH_MAX
; i
++)
5865 // 2008/01/30 MH we will judge RF RX path now.
5866 if (priv
->brfpath_rxenable
[i
])
5871 //Fixed by Jacken from Bryant 2008-03-20
5872 //Original value is 106
5873 #ifdef RTL8190P //Modify by Jacken 2008/03/31
5874 rx_pwr
[i
] = ((pofdm_buf
->trsw_gain_X
[i
]&0x3F)*2) - 106;
5876 rx_pwr
[i
] = ((pofdm_buf
->trsw_gain_X
[i
]&0x3F)*2) - 110;
5879 //Get Rx snr value in DB
5880 tmp_rxsnr
= pofdm_buf
->rxsnr_X
[i
];
5881 rx_snrX
= (char)(tmp_rxsnr
);
5883 priv
->stats
.rxSNRdB
[i
] = (long)rx_snrX
;
5885 /* Translate DBM to percentage. */
5886 RSSI
= rtl819x_query_rxpwrpercentage(rx_pwr
[i
]);
5887 if (priv
->brfpath_rxenable
[i
])
5890 /* Record Signal Strength for next packet */
5891 if(bpacket_match_bssid
)
5893 pstats
->RxMIMOSignalStrength
[i
] =(u8
) RSSI
;
5894 precord_stats
->RxMIMOSignalStrength
[i
] =(u8
) RSSI
;
5900 // (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive)
5902 //Fixed by Jacken from Bryant 2008-03-20
5903 //Original value is 106
5904 rx_pwr_all
= (((pofdm_buf
->pwdb_all
) >> 1 )& 0x7f) -106;
5905 pwdb_all
= rtl819x_query_rxpwrpercentage(rx_pwr_all
);
5907 pstats
->RxPWDBAll
= precord_stats
->RxPWDBAll
= pwdb_all
;
5908 pstats
->RxPower
= precord_stats
->RxPower
= rx_pwr_all
;
5909 pstats
->RecvSignalPower
= rx_pwr_all
;
5911 // (3)EVM of HT rate
5913 if(pdrvinfo
->RxHT
&& pdrvinfo
->RxRate
>=DESC90_RATEMCS8
&&
5914 pdrvinfo
->RxRate
<=DESC90_RATEMCS15
)
5915 max_spatial_stream
= 2; //both spatial stream make sense
5917 max_spatial_stream
= 1; //only spatial stream 1 makes sense
5919 for(i
=0; i
<max_spatial_stream
; i
++)
5921 tmp_rxevm
= pofdm_buf
->rxevm_X
[i
];
5922 rx_evmX
= (char)(tmp_rxevm
);
5924 // Do not use shift operation like "rx_evmX >>= 1" because the compilor of free build environment
5925 // fill most significant bit to "zero" when doing shifting operation which may change a negative
5926 // value to positive one, then the dbm value (which is supposed to be negative) is not correct anymore.
5929 evm
= rtl819x_evm_dbtopercentage(rx_evmX
);
5931 EVM
= SignalScaleMapping(EVM
);//make it good looking, from 0~100
5933 if(bpacket_match_bssid
)
5935 if(i
==0) // Fill value in RFD, Get the first spatial stream only
5936 pstats
->SignalQuality
= precord_stats
->SignalQuality
= (u8
)(evm
& 0xff);
5937 pstats
->RxMIMOSignalQuality
[i
] = precord_stats
->RxMIMOSignalQuality
[i
] = (u8
)(evm
& 0xff);
5942 /* record rx statistics for debug */
5943 rxsc_sgien_exflg
= pofdm_buf
->rxsc_sgien_exflg
;
5944 prxsc
= (phy_ofdm_rx_status_rxsc_sgien_exintfflag
*)&rxsc_sgien_exflg
;
5945 if(pdrvinfo
->BW
) //40M channel
5946 priv
->stats
.received_bwtype
[1+prxsc
->rxsc
]++;
5948 priv
->stats
.received_bwtype
[0]++;
5951 //UI BSS List signal strength(in percentage), make it good looking, from 0~100.
5952 //It is assigned to the BSS List in GetValueFromBeaconOrProbeRsp().
5955 pstats
->SignalStrength
= precord_stats
->SignalStrength
= (u8
)(rtl819x_signal_scale_mapping((long)pwdb_all
));//PWDB_ALL;
5960 //pRfd->Status.SignalStrength = pRecordRfd->Status.SignalStrength = (u1Byte)(SignalScaleMapping(total_rssi/=RF90_PATH_MAX));//(u1Byte)(total_rssi/=RF90_PATH_MAX);
5961 // We can judge RX path number now.
5963 pstats
->SignalStrength
= precord_stats
->SignalStrength
= (u8
)(rtl819x_signal_scale_mapping((long)(total_rssi
/=rf_rx_num
)));
5965 } /* QueryRxPhyStatus8190Pci */
5968 rtl8192_record_rxdesc_forlateruse(
5969 struct ieee80211_rx_stats
* psrc_stats
,
5970 struct ieee80211_rx_stats
* ptarget_stats
5973 ptarget_stats
->bIsAMPDU
= psrc_stats
->bIsAMPDU
;
5974 ptarget_stats
->bFirstMPDU
= psrc_stats
->bFirstMPDU
;
5975 //ptarget_stats->Seq_Num = psrc_stats->Seq_Num;
5980 static void TranslateRxSignalStuff819xpci(struct net_device
*dev
,
5981 struct sk_buff
*skb
,
5982 struct ieee80211_rx_stats
* pstats
,
5983 prx_desc_819x_pci pdesc
,
5984 prx_fwinfo_819x_pci pdrvinfo
)
5986 // TODO: We must only check packet for current MAC address. Not finish
5987 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
5988 bool bpacket_match_bssid
, bpacket_toself
;
5989 bool bPacketBeacon
=false, bToSelfBA
=false;
5990 static struct ieee80211_rx_stats previous_stats
;
5991 struct ieee80211_hdr_3addr
*hdr
;
5994 // Get Signal Quality for only RX data queue (but not command queue)
5999 /* Get MAC frame start address. */
6000 tmp_buf
= skb
->data
;
6002 hdr
= (struct ieee80211_hdr_3addr
*)tmp_buf
;
6003 fc
= le16_to_cpu(hdr
->frame_ctl
);
6004 type
= WLAN_FC_GET_TYPE(fc
);
6005 praddr
= hdr
->addr1
;
6007 /* Check if the received packet is acceptabe. */
6008 bpacket_match_bssid
= ((IEEE80211_FTYPE_CTL
!= type
) &&
6009 (eqMacAddr(priv
->ieee80211
->current_network
.bssid
, (fc
& IEEE80211_FCTL_TODS
)? hdr
->addr1
: (fc
& IEEE80211_FCTL_FROMDS
)? hdr
->addr2
: hdr
->addr3
))
6010 && (!pstats
->bHwError
) && (!pstats
->bCRC
)&& (!pstats
->bICV
));
6011 bpacket_toself
= bpacket_match_bssid
& (eqMacAddr(praddr
, priv
->ieee80211
->dev
->dev_addr
));
6013 if(WLAN_FC_GET_FRAMETYPE(fc
)== IEEE80211_STYPE_BEACON
)
6015 bPacketBeacon
= true;
6016 //DbgPrint("Beacon 2, MatchBSSID = %d, ToSelf = %d \n", bPacketMatchBSSID, bPacketToSelf);
6018 if(WLAN_FC_GET_FRAMETYPE(fc
) == IEEE80211_STYPE_BLOCKACK
)
6020 if((eqMacAddr(praddr
,dev
->dev_addr
)))
6022 //DbgPrint("BlockAck, MatchBSSID = %d, ToSelf = %d \n", bPacketMatchBSSID, bPacketToSelf);
6026 if(bpacket_match_bssid
)
6028 priv
->stats
.numpacket_matchbssid
++;
6031 priv
->stats
.numpacket_toself
++;
6034 // Process PHY information for previous packet (RSSI/PWDB/EVM)
6036 // Because phy information is contained in the last packet of AMPDU only, so driver
6037 // should process phy information of previous packet
6038 rtl8192_process_phyinfo(priv
, tmp_buf
,&previous_stats
, pstats
);
6039 rtl8192_query_rxphystatus(priv
, pstats
, pdesc
, pdrvinfo
, &previous_stats
, bpacket_match_bssid
,
6040 bpacket_toself
,bPacketBeacon
, bToSelfBA
);
6041 rtl8192_record_rxdesc_forlateruse(pstats
, &previous_stats
);
6046 static void rtl8192_tx_resume(struct net_device
*dev
)
6048 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
6049 struct ieee80211_device
*ieee
= priv
->ieee80211
;
6050 struct sk_buff
*skb
;
6053 for(queue_index
= BK_QUEUE
; queue_index
< TXCMD_QUEUE
;queue_index
++) {
6054 while((!skb_queue_empty(&ieee
->skb_waitQ
[queue_index
]))&&
6055 (priv
->ieee80211
->check_nic_enough_desc(dev
,queue_index
) > 0)) {
6056 /* 1. dequeue the packet from the wait queue */
6057 skb
= skb_dequeue(&ieee
->skb_waitQ
[queue_index
]);
6058 /* 2. tx the packet directly */
6059 ieee
->softmac_data_hard_start_xmit(skb
,dev
,0/* rate useless now*/);
6061 if(queue_index
!=MGNT_QUEUE
) {
6062 ieee
->stats
.tx_packets
++;
6063 ieee
->stats
.tx_bytes
+= skb
->len
;
6070 static void rtl8192_irq_tx_tasklet(struct r8192_priv
*priv
)
6072 rtl8192_tx_resume(priv
->ieee80211
->dev
);
6076 * Function: UpdateReceivedRateHistogramStatistics
6077 * Overview: Recored down the received data rate
6085 * (Adapter->RxStats.ReceivedRateHistogram[] is updated)
6089 static void UpdateReceivedRateHistogramStatistics8190(
6090 struct net_device
*dev
,
6091 struct ieee80211_rx_stats
* pstats
6094 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
6095 u32 rcvType
=1; //0: Total, 1:OK, 2:CRC, 3:ICV
6097 u32 preamble_guardinterval
; //1: short preamble/GI, 0: long preamble/GI
6099 /* 2007/03/09 MH We will not update rate of packet from rx cmd queue. */
6101 if (pRfd
->queue_id
== CMPK_RX_QUEUE_ID
)
6106 else if(pstats
->bICV
)
6109 if(pstats
->bShortPreamble
)
6110 preamble_guardinterval
= 1;// short
6112 preamble_guardinterval
= 0;// long
6114 switch(pstats
->rate
)
6119 case MGN_1M
: rateIndex
= 0; break;
6120 case MGN_2M
: rateIndex
= 1; break;
6121 case MGN_5_5M
: rateIndex
= 2; break;
6122 case MGN_11M
: rateIndex
= 3; break;
6126 case MGN_6M
: rateIndex
= 4; break;
6127 case MGN_9M
: rateIndex
= 5; break;
6128 case MGN_12M
: rateIndex
= 6; break;
6129 case MGN_18M
: rateIndex
= 7; break;
6130 case MGN_24M
: rateIndex
= 8; break;
6131 case MGN_36M
: rateIndex
= 9; break;
6132 case MGN_48M
: rateIndex
= 10; break;
6133 case MGN_54M
: rateIndex
= 11; break;
6135 // 11n High throughput rate
6137 case MGN_MCS0
: rateIndex
= 12; break;
6138 case MGN_MCS1
: rateIndex
= 13; break;
6139 case MGN_MCS2
: rateIndex
= 14; break;
6140 case MGN_MCS3
: rateIndex
= 15; break;
6141 case MGN_MCS4
: rateIndex
= 16; break;
6142 case MGN_MCS5
: rateIndex
= 17; break;
6143 case MGN_MCS6
: rateIndex
= 18; break;
6144 case MGN_MCS7
: rateIndex
= 19; break;
6145 case MGN_MCS8
: rateIndex
= 20; break;
6146 case MGN_MCS9
: rateIndex
= 21; break;
6147 case MGN_MCS10
: rateIndex
= 22; break;
6148 case MGN_MCS11
: rateIndex
= 23; break;
6149 case MGN_MCS12
: rateIndex
= 24; break;
6150 case MGN_MCS13
: rateIndex
= 25; break;
6151 case MGN_MCS14
: rateIndex
= 26; break;
6152 case MGN_MCS15
: rateIndex
= 27; break;
6153 default: rateIndex
= 28; break;
6155 priv
->stats
.received_preamble_GI
[preamble_guardinterval
][rateIndex
]++;
6156 priv
->stats
.received_rate_histogram
[0][rateIndex
]++; //total
6157 priv
->stats
.received_rate_histogram
[rcvType
][rateIndex
]++;
6160 static void rtl8192_rx(struct net_device
*dev
)
6162 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
6163 struct ieee80211_hdr_1addr
*ieee80211_hdr
= NULL
;
6164 bool unicast_packet
= false;
6165 struct ieee80211_rx_stats stats
= {
6169 .freq
= IEEE80211_24GHZ_BAND
,
6171 unsigned int count
= priv
->rxringcount
;
6173 stats
.nic_type
= NIC_8192E
;
6176 rx_desc_819x_pci
*pdesc
= &priv
->rx_ring
[priv
->rx_idx
];//rx descriptor
6177 struct sk_buff
*skb
= priv
->rx_buf
[priv
->rx_idx
];//rx pkt
6180 /* wait data to be filled by hardware */
6183 stats
.bICV
= pdesc
->ICV
;
6184 stats
.bCRC
= pdesc
->CRC32
;
6185 stats
.bHwError
= pdesc
->CRC32
| pdesc
->ICV
;
6187 stats
.Length
= pdesc
->Length
;
6188 if(stats
.Length
< 24)
6189 stats
.bHwError
|= 1;
6191 if(stats
.bHwError
) {
6192 stats
.bShift
= false;
6195 if (pdesc
->Length
<500)
6196 priv
->stats
.rxcrcerrmin
++;
6197 else if (pdesc
->Length
>1000)
6198 priv
->stats
.rxcrcerrmax
++;
6200 priv
->stats
.rxcrcerrmid
++;
6204 prx_fwinfo_819x_pci pDrvInfo
= NULL
;
6205 struct sk_buff
*new_skb
= dev_alloc_skb(priv
->rxbuffersize
);
6207 if (unlikely(!new_skb
)) {
6211 stats
.RxDrvInfoSize
= pdesc
->RxDrvInfoSize
;
6212 stats
.RxBufShift
= ((pdesc
->Shift
)&0x03);
6213 stats
.Decrypted
= !pdesc
->SWDec
;
6215 pci_dma_sync_single_for_cpu(priv
->pdev
,
6216 *((dma_addr_t
*)skb
->cb
),
6218 PCI_DMA_FROMDEVICE
);
6219 skb_put(skb
, pdesc
->Length
);
6220 pDrvInfo
= (rx_fwinfo_819x_pci
*)(skb
->data
+ stats
.RxBufShift
);
6221 skb_reserve(skb
, stats
.RxDrvInfoSize
+ stats
.RxBufShift
);
6223 stats
.rate
= HwRateToMRate90((bool)pDrvInfo
->RxHT
, (u8
)pDrvInfo
->RxRate
);
6224 stats
.bShortPreamble
= pDrvInfo
->SPLCP
;
6226 /* it is debug only. It should be disabled in released driver.
6227 * 2007.1.11 by Emily
6229 UpdateReceivedRateHistogramStatistics8190(dev
, &stats
);
6231 stats
.bIsAMPDU
= (pDrvInfo
->PartAggr
==1);
6232 stats
.bFirstMPDU
= (pDrvInfo
->PartAggr
==1) && (pDrvInfo
->FirstAGGR
==1);
6234 stats
.TimeStampLow
= pDrvInfo
->TSFL
;
6235 stats
.TimeStampHigh
= read_nic_dword(dev
, TSFR
+4);
6237 UpdateRxPktTimeStamp8190(dev
, &stats
);
6240 // Get Total offset of MPDU Frame Body
6242 if((stats
.RxBufShift
+ stats
.RxDrvInfoSize
) > 0)
6245 stats
.RxIs40MHzPacket
= pDrvInfo
->BW
;
6248 TranslateRxSignalStuff819xpci(dev
,skb
, &stats
, pdesc
, pDrvInfo
);
6251 if(pDrvInfo
->FirstAGGR
==1 || pDrvInfo
->PartAggr
== 1)
6252 RT_TRACE(COMP_RXDESC
, "pDrvInfo->FirstAGGR = %d, pDrvInfo->PartAggr = %d\n",
6253 pDrvInfo
->FirstAGGR
, pDrvInfo
->PartAggr
);
6254 skb_trim(skb
, skb
->len
- 4/*sCrcLng*/);
6255 /* rx packets statistics */
6256 ieee80211_hdr
= (struct ieee80211_hdr_1addr
*)skb
->data
;
6257 unicast_packet
= false;
6259 if(is_broadcast_ether_addr(ieee80211_hdr
->addr1
)) {
6261 }else if(is_multicast_ether_addr(ieee80211_hdr
->addr1
)){
6264 /* unicast packet */
6265 unicast_packet
= true;
6268 stats
.packetlength
= stats
.Length
-4;
6269 stats
.fraglength
= stats
.packetlength
;
6270 stats
.fragoffset
= 0;
6271 stats
.ntotalfrag
= 1;
6273 if(!ieee80211_rtl_rx(priv
->ieee80211
, skb
, &stats
)){
6274 dev_kfree_skb_any(skb
);
6277 if(unicast_packet
) {
6278 priv
->stats
.rxbytesunicast
+= skb
->len
;
6283 priv
->rx_buf
[priv
->rx_idx
] = skb
;
6284 *((dma_addr_t
*) skb
->cb
) = pci_map_single(priv
->pdev
, skb_tail_pointer(skb
), priv
->rxbuffersize
, PCI_DMA_FROMDEVICE
);
6289 pdesc
->BufferAddress
= cpu_to_le32(*((dma_addr_t
*)skb
->cb
));
6291 pdesc
->Length
= priv
->rxbuffersize
;
6292 if (priv
->rx_idx
== priv
->rxringcount
-1)
6294 priv
->rx_idx
= (priv
->rx_idx
+ 1) % priv
->rxringcount
;
6299 static void rtl8192_irq_rx_tasklet(struct r8192_priv
*priv
)
6301 rtl8192_rx(priv
->ieee80211
->dev
);
6303 write_nic_dword(priv
->ieee80211
->dev
, INTA_MASK
,read_nic_dword(priv
->ieee80211
->dev
, INTA_MASK
) | IMR_RDU
);
6306 static const struct net_device_ops rtl8192_netdev_ops
= {
6307 .ndo_open
= rtl8192_open
,
6308 .ndo_stop
= rtl8192_close
,
6309 /* .ndo_get_stats = rtl8192_stats, */
6310 .ndo_tx_timeout
= tx_timeout
,
6311 .ndo_do_ioctl
= rtl8192_ioctl
,
6312 .ndo_set_multicast_list
= r8192_set_multicast
,
6313 .ndo_set_mac_address
= r8192_set_mac_adr
,
6314 .ndo_start_xmit
= ieee80211_rtl_xmit
,
6317 /****************************************************************************
6318 ---------------------------- PCI_STUFF---------------------------
6319 *****************************************************************************/
6321 static int __devinit
rtl8192_pci_probe(struct pci_dev
*pdev
,
6322 const struct pci_device_id
*id
)
6324 unsigned long ioaddr
= 0;
6325 struct net_device
*dev
= NULL
;
6326 struct r8192_priv
*priv
= NULL
;
6329 #ifdef CONFIG_RTL8192_IO_MAP
6330 unsigned long pio_start
, pio_len
, pio_flags
;
6332 unsigned long pmem_start
, pmem_len
, pmem_flags
;
6333 #endif //end #ifdef RTL_IO_MAP
6335 RT_TRACE(COMP_INIT
,"Configuring chip resources");
6337 if( pci_enable_device (pdev
) ){
6338 RT_TRACE(COMP_ERR
,"Failed to enable PCI device");
6342 pci_set_master(pdev
);
6343 //pci_set_wmi(pdev);
6344 pci_set_dma_mask(pdev
, 0xffffff00ULL
);
6345 pci_set_consistent_dma_mask(pdev
,0xffffff00ULL
);
6346 dev
= alloc_ieee80211(sizeof(struct r8192_priv
));
6350 pci_set_drvdata(pdev
, dev
);
6351 SET_NETDEV_DEV(dev
, &pdev
->dev
);
6352 priv
= ieee80211_priv(dev
);
6353 priv
->ieee80211
= netdev_priv(dev
);
6355 if((pdev
->subsystem_vendor
== PCI_VENDOR_ID_DLINK
)&&(pdev
->subsystem_device
== 0x3304)){
6356 priv
->ieee80211
->bSupportRemoteWakeUp
= 1;
6359 priv
->ieee80211
->bSupportRemoteWakeUp
= 0;
6362 #ifdef CONFIG_RTL8192_IO_MAP
6364 pio_start
= (unsigned long)pci_resource_start (pdev
, 0);
6365 pio_len
= (unsigned long)pci_resource_len (pdev
, 0);
6366 pio_flags
= (unsigned long)pci_resource_flags (pdev
, 0);
6368 if (!(pio_flags
& IORESOURCE_IO
)) {
6369 RT_TRACE(COMP_ERR
,"region #0 not a PIO resource, aborting");
6373 //DMESG("IO space @ 0x%08lx", pio_start );
6374 if( ! request_region( pio_start
, pio_len
, RTL819xE_MODULE_NAME
) ){
6375 RT_TRACE(COMP_ERR
,"request_region failed!");
6380 dev
->base_addr
= ioaddr
; // device I/O address
6384 pmem_start
= pci_resource_start(pdev
, 1);
6385 pmem_len
= pci_resource_len(pdev
, 1);
6386 pmem_flags
= pci_resource_flags (pdev
, 1);
6388 if (!(pmem_flags
& IORESOURCE_MEM
)) {
6389 RT_TRACE(COMP_ERR
,"region #1 not a MMIO resource, aborting");
6393 //DMESG("Memory mapped space @ 0x%08lx ", pmem_start);
6394 if( ! request_mem_region(pmem_start
, pmem_len
, RTL819xE_MODULE_NAME
)) {
6395 RT_TRACE(COMP_ERR
,"request_mem_region failed!");
6400 ioaddr
= (unsigned long)ioremap_nocache( pmem_start
, pmem_len
);
6401 if( ioaddr
== (unsigned long)NULL
){
6402 RT_TRACE(COMP_ERR
,"ioremap failed!");
6403 // release_mem_region( pmem_start, pmem_len );
6407 dev
->mem_start
= ioaddr
; // shared mem start
6408 dev
->mem_end
= ioaddr
+ pci_resource_len(pdev
, 0); // shared mem end
6410 #endif //end #ifdef RTL_IO_MAP
6412 /* We disable the RETRY_TIMEOUT register (0x41) to keep
6413 * PCI Tx retries from interfering with C3 CPU state */
6414 pci_write_config_byte(pdev
, 0x41, 0x00);
6417 pci_read_config_byte(pdev
, 0x05, &unit
);
6418 pci_write_config_byte(pdev
, 0x05, unit
& (~0x04));
6420 dev
->irq
= pdev
->irq
;
6423 dev
->netdev_ops
= &rtl8192_netdev_ops
;
6425 dev
->open
= rtl8192_open
;
6426 dev
->stop
= rtl8192_close
;
6427 //dev->hard_start_xmit = rtl8192_8023_hard_start_xmit;
6428 dev
->tx_timeout
= tx_timeout
;
6429 //dev->wireless_handlers = &r8192_wx_handlers_def;
6430 dev
->do_ioctl
= rtl8192_ioctl
;
6431 dev
->set_multicast_list
= r8192_set_multicast
;
6432 dev
->set_mac_address
= r8192_set_mac_adr
;
6435 //DMESG("Oops: i'm coming\n");
6436 #if WIRELESS_EXT >= 12
6437 #if WIRELESS_EXT < 17
6438 dev
->get_wireless_stats
= r8192_get_wireless_stats
;
6440 dev
->wireless_handlers
= (struct iw_handler_def
*) &r8192_wx_handlers_def
;
6442 //dev->get_wireless_stats = r8192_get_wireless_stats;
6443 dev
->type
=ARPHRD_ETHER
;
6445 dev
->watchdog_timeo
= HZ
*3; //modified by john, 0805
6447 if (dev_alloc_name(dev
, ifname
) < 0){
6448 RT_TRACE(COMP_INIT
, "Oops: devname already taken! Trying wlan%%d...\n");
6450 dev_alloc_name(dev
, ifname
);
6453 RT_TRACE(COMP_INIT
, "Driver probe completed1\n");
6454 if(rtl8192_init(dev
)!=0){
6455 RT_TRACE(COMP_ERR
, "Initialization failed");
6459 netif_carrier_off(dev
);
6460 netif_stop_queue(dev
);
6462 register_netdev(dev
);
6463 RT_TRACE(COMP_INIT
, "dev name=======> %s\n",dev
->name
);
6464 rtl8192_proc_init_one(dev
);
6467 RT_TRACE(COMP_INIT
, "Driver probe completed\n");
6472 #ifdef CONFIG_RTL8180_IO_MAP
6474 if( dev
->base_addr
!= 0 ){
6476 release_region(dev
->base_addr
,
6477 pci_resource_len(pdev
, 0) );
6480 if( dev
->mem_start
!= (unsigned long)NULL
){
6481 iounmap( (void *)dev
->mem_start
);
6482 release_mem_region( pci_resource_start(pdev
, 1),
6483 pci_resource_len(pdev
, 1) );
6485 #endif //end #ifdef RTL_IO_MAP
6491 free_irq(dev
->irq
, dev
);
6494 free_ieee80211(dev
);
6497 pci_disable_device(pdev
);
6499 DMESG("wlan driver load failed\n");
6500 pci_set_drvdata(pdev
, NULL
);
6505 /* detach all the work and timer structure declared or inititialized
6506 * in r8192_init function.
6508 void rtl8192_cancel_deferred_work(struct r8192_priv
* priv
)
6510 /* call cancel_work_sync instead of cancel_delayed_work if and only if Linux_version_code
6511 * is or is newer than 2.6.20 and work structure is defined to be struct work_struct.
6512 * Otherwise call cancel_delayed_work is enough.
6513 * FIXME (2.6.20 should 2.6.22, work_struct should not cancel)
6515 cancel_delayed_work(&priv
->watch_dog_wq
);
6516 cancel_delayed_work(&priv
->update_beacon_wq
);
6517 cancel_delayed_work(&priv
->ieee80211
->hw_wakeup_wq
);
6518 cancel_delayed_work(&priv
->ieee80211
->hw_sleep_wq
);
6520 cancel_delayed_work(&priv
->gpio_change_rf_wq
);
6522 cancel_work_sync(&priv
->reset_wq
);
6523 cancel_work_sync(&priv
->qos_activate
);
6524 //cancel_work_sync(&priv->SetBWModeWorkItem);
6525 //cancel_work_sync(&priv->SwChnlWorkItem);
6530 static void __devexit
rtl8192_pci_disconnect(struct pci_dev
*pdev
)
6532 struct net_device
*dev
= pci_get_drvdata(pdev
);
6533 struct r8192_priv
*priv
;
6537 unregister_netdev(dev
);
6539 priv
=ieee80211_priv(dev
);
6541 rtl8192_proc_remove_one(dev
);
6544 if (priv
->pFirmware
)
6546 vfree(priv
->pFirmware
);
6547 priv
->pFirmware
= NULL
;
6549 // priv->rf_close(dev);
6550 // rtl8192_usb_deleteendpoints(dev);
6551 destroy_workqueue(priv
->priv_wq
);
6552 /* redundant with rtl8192_down */
6553 // rtl8192_irq_disable(dev);
6554 // rtl8192_reset(dev);
6558 /* free tx/rx rings */
6559 rtl8192_free_rx_ring(dev
);
6560 for (i
= 0; i
< MAX_TX_QUEUE_COUNT
; i
++) {
6561 rtl8192_free_tx_ring(dev
, i
);
6566 printk("Freeing irq %d\n",dev
->irq
);
6567 free_irq(dev
->irq
, dev
);
6574 // free_beacon_desc_ring(dev,priv->txbeaconcount);
6576 #ifdef CONFIG_RTL8180_IO_MAP
6578 if( dev
->base_addr
!= 0 ){
6580 release_region(dev
->base_addr
,
6581 pci_resource_len(pdev
, 0) );
6584 if( dev
->mem_start
!= (unsigned long)NULL
){
6585 iounmap( (void *)dev
->mem_start
);
6586 release_mem_region( pci_resource_start(pdev
, 1),
6587 pci_resource_len(pdev
, 1) );
6589 #endif /*end #ifdef RTL_IO_MAP*/
6590 free_ieee80211(dev
);
6594 pci_disable_device(pdev
);
6595 RT_TRACE(COMP_DOWN
, "wlan driver removed\n");
6598 extern int ieee80211_rtl_init(void);
6599 extern void ieee80211_rtl_exit(void);
6601 static int __init
rtl8192_pci_module_init(void)
6605 retval
= ieee80211_rtl_init();
6609 printk(KERN_INFO
"\nLinux kernel driver for RTL8192 based WLAN cards\n");
6610 printk(KERN_INFO
"Copyright (c) 2007-2008, Realsil Wlan\n");
6611 RT_TRACE(COMP_INIT
, "Initializing module");
6612 RT_TRACE(COMP_INIT
, "Wireless extensions version %d", WIRELESS_EXT
);
6613 rtl8192_proc_module_init();
6614 if(0!=pci_register_driver(&rtl8192_pci_driver
))
6616 DMESG("No device found");
6617 /*pci_unregister_driver (&rtl8192_pci_driver);*/
6624 static void __exit
rtl8192_pci_module_exit(void)
6626 pci_unregister_driver(&rtl8192_pci_driver
);
6628 RT_TRACE(COMP_DOWN
, "Exiting");
6629 rtl8192_proc_module_remove();
6630 ieee80211_rtl_exit();
6633 //warning message WB
6634 static irqreturn_t
rtl8192_interrupt(int irq
, void *netdev
)
6636 struct net_device
*dev
= (struct net_device
*) netdev
;
6637 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
6638 unsigned long flags
;
6640 /* We should return IRQ_NONE, but for now let me keep this */
6641 if(priv
->irq_enabled
== 0){
6645 spin_lock_irqsave(&priv
->irq_th_lock
,flags
);
6649 inta
= read_nic_dword(dev
, ISR
);// & priv->IntrMask;
6650 write_nic_dword(dev
,ISR
,inta
); // reset int situation
6652 priv
->stats
.shints
++;
6653 //DMESG("Enter interrupt, ISR value = 0x%08x", inta);
6655 spin_unlock_irqrestore(&priv
->irq_th_lock
,flags
);
6658 most probably we can safely return IRQ_NONE,
6659 but for now is better to avoid problems
6665 spin_unlock_irqrestore(&priv
->irq_th_lock
,flags
);
6671 DMESG("NIC irq %x",inta
);
6673 //priv->irqpending = inta;
6676 if(!netif_running(dev
)) {
6677 spin_unlock_irqrestore(&priv
->irq_th_lock
,flags
);
6681 if(inta
& IMR_TIMEOUT0
){
6682 // write_nic_dword(dev, TimerInt, 0);
6683 //DMESG("=================>waking up");
6684 // rtl8180_hw_wakeup(dev);
6687 if(inta
& IMR_TBDOK
){
6688 RT_TRACE(COMP_INTR
, "beacon ok interrupt!\n");
6689 rtl8192_tx_isr(dev
, BEACON_QUEUE
);
6690 priv
->stats
.txbeaconokint
++;
6693 if(inta
& IMR_TBDER
){
6694 RT_TRACE(COMP_INTR
, "beacon ok interrupt!\n");
6695 rtl8192_tx_isr(dev
, BEACON_QUEUE
);
6696 priv
->stats
.txbeaconerr
++;
6699 if(inta
& IMR_MGNTDOK
) {
6700 RT_TRACE(COMP_INTR
, "Manage ok interrupt!\n");
6701 priv
->stats
.txmanageokint
++;
6702 rtl8192_tx_isr(dev
,MGNT_QUEUE
);
6706 if(inta
& IMR_COMDOK
)
6708 priv
->stats
.txcmdpktokint
++;
6709 rtl8192_tx_isr(dev
,TXCMD_QUEUE
);
6714 DMESG("Frame arrived !");
6716 priv
->stats
.rxint
++;
6717 tasklet_schedule(&priv
->irq_rx_tasklet
);
6720 if(inta
& IMR_BcnInt
) {
6721 RT_TRACE(COMP_INTR
, "prepare beacon for interrupt!\n");
6722 tasklet_schedule(&priv
->irq_prepare_beacon_tasklet
);
6726 RT_TRACE(COMP_INTR
, "rx descriptor unavailable!\n");
6727 priv
->stats
.rxrdu
++;
6728 /* reset int situation */
6729 write_nic_dword(dev
,INTA_MASK
,read_nic_dword(dev
, INTA_MASK
) & ~IMR_RDU
);
6730 tasklet_schedule(&priv
->irq_rx_tasklet
);
6733 if(inta
& IMR_RXFOVW
){
6734 RT_TRACE(COMP_INTR
, "rx overflow !\n");
6735 priv
->stats
.rxoverflow
++;
6736 tasklet_schedule(&priv
->irq_rx_tasklet
);
6739 if(inta
& IMR_TXFOVW
) priv
->stats
.txoverflow
++;
6741 if(inta
& IMR_BKDOK
){
6742 RT_TRACE(COMP_INTR
, "BK Tx OK interrupt!\n");
6743 priv
->stats
.txbkokint
++;
6744 priv
->ieee80211
->LinkDetectInfo
.NumTxOkInPeriod
++;
6745 rtl8192_tx_isr(dev
,BK_QUEUE
);
6746 rtl8192_try_wake_queue(dev
, BK_QUEUE
);
6749 if(inta
& IMR_BEDOK
){
6750 RT_TRACE(COMP_INTR
, "BE TX OK interrupt!\n");
6751 priv
->stats
.txbeokint
++;
6752 priv
->ieee80211
->LinkDetectInfo
.NumTxOkInPeriod
++;
6753 rtl8192_tx_isr(dev
,BE_QUEUE
);
6754 rtl8192_try_wake_queue(dev
, BE_QUEUE
);
6757 if(inta
& IMR_VIDOK
){
6758 RT_TRACE(COMP_INTR
, "VI TX OK interrupt!\n");
6759 priv
->stats
.txviokint
++;
6760 priv
->ieee80211
->LinkDetectInfo
.NumTxOkInPeriod
++;
6761 rtl8192_tx_isr(dev
,VI_QUEUE
);
6762 rtl8192_try_wake_queue(dev
, VI_QUEUE
);
6765 if(inta
& IMR_VODOK
){
6766 priv
->stats
.txvookint
++;
6767 priv
->ieee80211
->LinkDetectInfo
.NumTxOkInPeriod
++;
6768 rtl8192_tx_isr(dev
,VO_QUEUE
);
6769 rtl8192_try_wake_queue(dev
, VO_QUEUE
);
6772 force_pci_posting(dev
);
6773 spin_unlock_irqrestore(&priv
->irq_th_lock
,flags
);
6778 static void rtl8192_try_wake_queue(struct net_device
*dev
, int pri
)
6781 unsigned long flags
;
6783 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
6785 spin_lock_irqsave(&priv
->tx_lock
,flags
);
6786 enough_desc
= check_nic_enough_desc(dev
,pri
);
6787 spin_unlock_irqrestore(&priv
->tx_lock
,flags
);
6790 ieee80211_rtl_wake_queue(priv
->ieee80211
);
6795 void EnableHWSecurityConfig8192(struct net_device
*dev
)
6797 u8 SECR_value
= 0x0;
6798 // struct ieee80211_device* ieee1 = container_of(&dev, struct ieee80211_device, dev);
6799 //printk("==>ieee1:%p, dev:%p\n", ieee1, dev);
6800 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
6801 struct ieee80211_device
* ieee
= priv
->ieee80211
;
6802 //printk("==>ieee:%p, dev:%p\n", ieee, dev);
6803 SECR_value
= SCR_TxEncEnable
| SCR_RxDecEnable
;
6805 if (((KEY_TYPE_WEP40
== ieee
->pairwise_key_type
) || (KEY_TYPE_WEP104
== ieee
->pairwise_key_type
)) && (priv
->ieee80211
->auth_mode
!= 2))
6807 SECR_value
|= SCR_RxUseDK
;
6808 SECR_value
|= SCR_TxUseDK
;
6810 else if ((ieee
->iw_mode
== IW_MODE_ADHOC
) && (ieee
->pairwise_key_type
& (KEY_TYPE_CCMP
| KEY_TYPE_TKIP
)))
6812 SECR_value
|= SCR_RxUseDK
;
6813 SECR_value
|= SCR_TxUseDK
;
6818 //add HWSec active enable here.
6819 //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
6820 ieee
->hwsec_active
= 1;
6822 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
6824 ieee
->hwsec_active
= 0;
6825 SECR_value
&= ~SCR_RxDecEnable
;
6828 RT_TRACE(COMP_SEC
,"%s:, hwsec:%d, pairwise_key:%d, SECR_value:%x\n", __FUNCTION__
, \
6829 ieee
->hwsec_active
, ieee
->pairwise_key_type
, SECR_value
);
6831 write_nic_byte(dev
, SECR
, SECR_value
);//SECR_value | SCR_UseDK );
6835 #define TOTAL_CAM_ENTRY 32
6836 //#define CAM_CONTENT_COUNT 8
6837 void setKey( struct net_device
*dev
,
6845 u32 TargetCommand
= 0;
6846 u32 TargetContent
= 0;
6850 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
6851 RT_RF_POWER_STATE rtState
;
6852 rtState
= priv
->ieee80211
->eRFPowerState
;
6853 if(priv
->ieee80211
->PowerSaveControl
.bInactivePs
){
6854 if(rtState
== eRfOff
){
6855 if(priv
->ieee80211
->RfOffReason
> RF_CHANGE_BY_IPS
)
6857 RT_TRACE(COMP_ERR
, "%s(): RF is OFF.\n",__FUNCTION__
);
6858 //up(&priv->wx_sem);
6862 down(&priv
->ieee80211
->ips_sem
);
6864 up(&priv
->ieee80211
->ips_sem
);
6868 priv
->ieee80211
->is_set_key
= true;
6870 if (EntryNo
>= TOTAL_CAM_ENTRY
)
6871 RT_TRACE(COMP_ERR
, "cam entry exceeds in setKey()\n");
6873 RT_TRACE(COMP_SEC
, "====>to setKey(), dev:%p, EntryNo:%d, KeyIndex:%d, KeyType:%d, MacAddr%pM\n", dev
,EntryNo
, KeyIndex
, KeyType
, MacAddr
);
6876 usConfig
|= BIT15
| (KeyType
<<2);
6878 usConfig
|= BIT15
| (KeyType
<<2) | KeyIndex
;
6879 // usConfig |= BIT15 | (KeyType<<2) | (DefaultKey<<5) | KeyIndex;
6882 for(i
=0 ; i
<CAM_CONTENT_COUNT
; i
++){
6883 TargetCommand
= i
+CAM_CONTENT_COUNT
*EntryNo
;
6884 TargetCommand
|= BIT31
|BIT16
;
6886 if(i
==0){//MAC|Config
6887 TargetContent
= (u32
)(*(MacAddr
+0)) << 16|
6888 (u32
)(*(MacAddr
+1)) << 24|
6891 write_nic_dword(dev
, WCAMI
, TargetContent
);
6892 write_nic_dword(dev
, RWCAM
, TargetCommand
);
6893 // printk("setkey cam =%8x\n", read_cam(dev, i+6*EntryNo));
6896 TargetContent
= (u32
)(*(MacAddr
+2)) |
6897 (u32
)(*(MacAddr
+3)) << 8|
6898 (u32
)(*(MacAddr
+4)) << 16|
6899 (u32
)(*(MacAddr
+5)) << 24;
6900 write_nic_dword(dev
, WCAMI
, TargetContent
);
6901 write_nic_dword(dev
, RWCAM
, TargetCommand
);
6903 else { //Key Material
6904 if(KeyContent
!= NULL
)
6906 write_nic_dword(dev
, WCAMI
, (u32
)(*(KeyContent
+i
-2)) );
6907 write_nic_dword(dev
, RWCAM
, TargetCommand
);
6911 RT_TRACE(COMP_SEC
,"=========>after set key, usconfig:%x\n", usConfig
);
6913 // This function seems not ready! WB
6914 void CamPrintDbgReg(struct net_device
* dev
)
6916 unsigned long rvalue
;
6917 unsigned char ucValue
;
6918 write_nic_dword(dev
, DCAM
, 0x80000000);
6920 rvalue
= read_nic_dword(dev
, DCAM
); //delay_ms(40);
6921 RT_TRACE(COMP_SEC
, " TX CAM=%8lX ",rvalue
);
6922 if((rvalue
& 0x40000000) != 0x4000000)
6923 RT_TRACE(COMP_SEC
, "-->TX Key Not Found ");
6925 write_nic_dword(dev
, DCAM
, 0x00000000); //delay_ms(40);
6926 rvalue
= read_nic_dword(dev
, DCAM
); //delay_ms(40);
6927 RT_TRACE(COMP_SEC
, "RX CAM=%8lX ",rvalue
);
6928 if((rvalue
& 0x40000000) != 0x4000000)
6929 RT_TRACE(COMP_SEC
, "-->CAM Key Not Found ");
6930 ucValue
= read_nic_byte(dev
, SECR
);
6931 RT_TRACE(COMP_SEC
, "WPA_Config=%x \n",ucValue
);
6934 bool NicIFEnableNIC(struct net_device
* dev
)
6936 RT_STATUS init_status
= RT_STATUS_SUCCESS
;
6937 struct r8192_priv
* priv
= ieee80211_priv(dev
);
6938 PRT_POWER_SAVE_CONTROL pPSC
= (PRT_POWER_SAVE_CONTROL
)(&(priv
->ieee80211
->PowerSaveControl
));
6942 RT_TRACE(COMP_ERR
, "ERR!!! %s(): Driver is already down!\n",__FUNCTION__
);
6943 priv
->bdisable_nic
= false; //YJ,add,091111
6946 // <1> Reset memory: descriptor, buffer,..
6947 //NicIFResetMemory(Adapter);
6949 // <2> Enable Adapter
6950 //printk("===========>%s()\n",__FUNCTION__);
6951 //priv->bfirst_init = true;
6952 init_status
= rtl8192_adapter_start(dev
);
6953 if (init_status
!= RT_STATUS_SUCCESS
) {
6954 RT_TRACE(COMP_ERR
,"ERR!!! %s(): initialization is failed!\n",__FUNCTION__
);
6955 priv
->bdisable_nic
= false; //YJ,add,091111
6958 //printk("start adapter finished\n");
6959 RT_CLEAR_PS_LEVEL(pPSC
, RT_RF_OFF_LEVL_HALT_NIC
);
6960 //priv->bfirst_init = false;
6962 // <3> Enable Interrupt
6963 rtl8192_irq_enable(dev
);
6964 priv
->bdisable_nic
= false;
6965 //RT_TRACE(COMP_PS,"<===========%s()\n",__FUNCTION__);
6966 return (init_status
== RT_STATUS_SUCCESS
) ? true:false;
6968 bool NicIFDisableNIC(struct net_device
* dev
)
6971 struct r8192_priv
* priv
= ieee80211_priv(dev
);
6973 // <1> Disable Interrupt
6974 //RT_TRACE(COMP_PS, "=========>%s()\n",__FUNCTION__);
6975 priv
->bdisable_nic
= true; //YJ,move,091109
6976 tmp_state
= priv
->ieee80211
->state
;
6978 ieee80211_softmac_stop_protocol(priv
->ieee80211
, false);
6980 priv
->ieee80211
->state
= tmp_state
;
6981 rtl8192_cancel_deferred_work(priv
);
6982 rtl8192_irq_disable(dev
);
6983 // <2> Stop all timer
6985 // <3> Disable Adapter
6986 rtl8192_halt_adapter(dev
, false);
6987 // priv->bdisable_nic = true;
6988 //RT_TRACE(COMP_PS, "<=========%s()\n",__FUNCTION__);
6994 /***************************************************************************
6995 ------------------- module init / exit stubs ----------------
6996 ****************************************************************************/
6997 module_init(rtl8192_pci_module_init
);
6998 module_exit(rtl8192_pci_module_exit
);