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>
28 #undef RX_DONT_PASS_UL
30 #undef DEBUG_RX_VERBOSE
36 #undef DEBUG_TX_FILLDESC
41 #undef DEBUG_REGISTERS
43 #undef DEBUG_IRQ_TASKLET
47 //#define CONFIG_RTL8192_IO_MAP
48 #include <linux/vmalloc.h>
49 #include <linux/slab.h>
50 #include <asm/uaccess.h>
51 #include "r8192E_hw.h"
53 #include "r8190_rtl8256.h" /* RTL8225 Radio frontend */
54 #include "r8180_93cx6.h" /* Card EEPROM */
55 #include "r8192E_wx.h"
56 #include "r819xE_phy.h" //added by WB 4.30.2008
57 #include "r819xE_phyreg.h"
58 #include "r819xE_cmdpkt.h"
59 #include "r8192E_dm.h"
66 #include "ieee80211/dot11d.h"
69 //set here to open your trace code. //WB
70 u32 rt_global_debug_component
=
88 // COMP_POWER_TRACKING |
90 COMP_ERR
; //always open err flags on
92 static DEFINE_PCI_DEVICE_TABLE(rtl8192_pci_id_tbl
) = {
96 { PCI_DEVICE(0x10ec, 0x8190) },
98 { PCI_DEVICE(0x07aa, 0x0045) },
99 { PCI_DEVICE(0x07aa, 0x0046) },
102 { PCI_DEVICE(0x10ec, 0x8192) },
105 { PCI_DEVICE(0x07aa, 0x0044) },
106 { PCI_DEVICE(0x07aa, 0x0047) },
111 static char ifname
[IFNAMSIZ
] = "wlan%d";
112 static int hwwep
= 1; //default use hw. set 0 to use software security
113 static int channels
= 0x3fff;
115 MODULE_LICENSE("GPL");
116 MODULE_VERSION("V 1.1");
117 MODULE_DEVICE_TABLE(pci
, rtl8192_pci_id_tbl
);
118 //MODULE_AUTHOR("Andrea Merello <andreamrl@tiscali.it>");
119 MODULE_DESCRIPTION("Linux driver for Realtek RTL819x WiFi cards");
122 module_param_string(ifname
, ifname
, sizeof(ifname
), S_IRUGO
|S_IWUSR
);
123 module_param(hwwep
,int, S_IRUGO
|S_IWUSR
);
124 module_param(channels
,int, S_IRUGO
|S_IWUSR
);
126 MODULE_PARM_DESC(ifname
," Net interface name, wlan%d=default");
127 MODULE_PARM_DESC(hwwep
," Try to use hardware WEP support. Still broken and not available on all cards");
128 MODULE_PARM_DESC(channels
," Channel bitmask for specific locales. NYI");
130 static int __devinit
rtl8192_pci_probe(struct pci_dev
*pdev
,
131 const struct pci_device_id
*id
);
132 static void __devexit
rtl8192_pci_disconnect(struct pci_dev
*pdev
);
134 static struct pci_driver rtl8192_pci_driver
= {
135 .name
= RTL819xE_MODULE_NAME
, /* Driver name */
136 .id_table
= rtl8192_pci_id_tbl
, /* PCI_ID table */
137 .probe
= rtl8192_pci_probe
, /* probe fn */
138 .remove
= __devexit_p(rtl8192_pci_disconnect
), /* remove fn */
140 .suspend
= rtl8192E_suspend
, /* PM suspend fn */
141 .resume
= rtl8192E_resume
, /* PM resume fn */
143 .suspend
= NULL
, /* PM suspend fn */
144 .resume
= NULL
, /* PM resume fn */
148 static void rtl8192_start_beacon(struct net_device
*dev
);
149 static void rtl8192_stop_beacon(struct net_device
*dev
);
150 static void rtl819x_watchdog_wqcallback(struct work_struct
*work
);
151 static void rtl8192_irq_rx_tasklet(struct r8192_priv
*priv
);
152 static void rtl8192_irq_tx_tasklet(struct r8192_priv
*priv
);
153 static void rtl8192_prepare_beacon(struct r8192_priv
*priv
);
154 static irqreturn_t
rtl8192_interrupt(int irq
, void *netdev
);
155 static void rtl819xE_tx_cmd(struct net_device
*dev
, struct sk_buff
*skb
);
156 static void rtl8192_update_ratr_table(struct net_device
* dev
);
157 static void rtl8192_restart(struct work_struct
*work
);
158 static void watch_dog_timer_callback(unsigned long data
);
159 static int _rtl8192_up(struct net_device
*dev
);
160 static void rtl8192_cancel_deferred_work(struct r8192_priv
* priv
);
164 typedef struct _CHANNEL_LIST
168 }CHANNEL_LIST
, *PCHANNEL_LIST
;
170 static const CHANNEL_LIST ChannelPlan
[] = {
171 {{1,2,3,4,5,6,7,8,9,10,11,36,40,44,48,52,56,60,64,149,153,157,161,165},24}, //FCC
172 {{1,2,3,4,5,6,7,8,9,10,11},11}, //IC
173 {{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48,52,56,60,64},21}, //ETSI
174 {{1,2,3,4,5,6,7,8,9,10,11,12,13},13}, //Spain. Change to ETSI.
175 {{1,2,3,4,5,6,7,8,9,10,11,12,13},13}, //France. Change to ETSI.
176 {{1,2,3,4,5,6,7,8,9,10,11,12,13,14,36,40,44,48,52,56,60,64},22}, //MKK //MKK
177 {{1,2,3,4,5,6,7,8,9,10,11,12,13,14,36,40,44,48,52,56,60,64},22},//MKK1
178 {{1,2,3,4,5,6,7,8,9,10,11,12,13},13}, //Israel.
179 {{1,2,3,4,5,6,7,8,9,10,11,12,13,14,36,40,44,48,52,56,60,64},22}, // For 11a , TELEC
180 {{1,2,3,4,5,6,7,8,9,10,11,12,13,14,36,40,44,48,52,56,60,64}, 22}, //MIC
181 {{1,2,3,4,5,6,7,8,9,10,11,12,13,14},14} //For Global Domain. 1-11:active scan, 12-14 passive scan. //+YJ, 080626
184 static void rtl819x_set_channel_map(u8 channel_plan
, struct r8192_priv
* priv
)
186 int i
, max_chan
=-1, min_chan
=-1;
187 struct ieee80211_device
* ieee
= priv
->ieee80211
;
188 switch (channel_plan
)
190 case COUNTRY_CODE_FCC
:
191 case COUNTRY_CODE_IC
:
192 case COUNTRY_CODE_ETSI
:
193 case COUNTRY_CODE_SPAIN
:
194 case COUNTRY_CODE_FRANCE
:
195 case COUNTRY_CODE_MKK
:
196 case COUNTRY_CODE_MKK1
:
197 case COUNTRY_CODE_ISRAEL
:
198 case COUNTRY_CODE_TELEC
:
199 case COUNTRY_CODE_MIC
:
202 ieee
->bGlobalDomain
= false;
203 //acturally 8225 & 8256 rf chip only support B,G,24N mode
204 if ((priv
->rf_chip
== RF_8225
) || (priv
->rf_chip
== RF_8256
))
211 RT_TRACE(COMP_ERR
, "unknown rf chip, can't set channel map in function:%s()\n", __FUNCTION__
);
213 if (ChannelPlan
[channel_plan
].Len
!= 0){
214 // Clear old channel map
215 memset(GET_DOT11D_INFO(ieee
)->channel_map
, 0, sizeof(GET_DOT11D_INFO(ieee
)->channel_map
));
216 // Set new channel map
217 for (i
=0;i
<ChannelPlan
[channel_plan
].Len
;i
++)
219 if (ChannelPlan
[channel_plan
].Channel
[i
] < min_chan
|| ChannelPlan
[channel_plan
].Channel
[i
] > max_chan
)
221 GET_DOT11D_INFO(ieee
)->channel_map
[ChannelPlan
[channel_plan
].Channel
[i
]] = 1;
226 case COUNTRY_CODE_GLOBAL_DOMAIN
:
228 GET_DOT11D_INFO(ieee
)->bEnabled
= 0; //this flag enabled to follow 11d country IE setting, otherwise, it shall follow global domain setting
230 ieee
->bGlobalDomain
= true;
239 static inline bool rx_hal_is_cck_rate(prx_fwinfo_819x_pci pdrvinfo
)
241 return (pdrvinfo
->RxRate
== DESC90_RATE1M
||
242 pdrvinfo
->RxRate
== DESC90_RATE2M
||
243 pdrvinfo
->RxRate
== DESC90_RATE5_5M
||
244 pdrvinfo
->RxRate
== DESC90_RATE11M
) &&
248 void CamResetAllEntry(struct net_device
*dev
)
250 write_nic_dword(dev
, RWCAM
, BIT31
|BIT30
);
254 void write_cam(struct net_device
*dev
, u8 addr
, u32 data
)
256 write_nic_dword(dev
, WCAMI
, data
);
257 write_nic_dword(dev
, RWCAM
, BIT31
|BIT16
|(addr
&0xff) );
259 u32
read_cam(struct net_device
*dev
, u8 addr
)
261 write_nic_dword(dev
, RWCAM
, 0x80000000|(addr
&0xff) );
262 return read_nic_dword(dev
, 0xa8);
265 #ifdef CONFIG_RTL8180_IO_MAP
267 u8
read_nic_byte(struct net_device
*dev
, int x
)
269 return 0xff&inb(dev
->base_addr
+x
);
272 u32
read_nic_dword(struct net_device
*dev
, int x
)
274 return inl(dev
->base_addr
+x
);
277 u16
read_nic_word(struct net_device
*dev
, int x
)
279 return inw(dev
->base_addr
+x
);
282 void write_nic_byte(struct net_device
*dev
, int x
,u8 y
)
284 outb(y
&0xff,dev
->base_addr
+x
);
287 void write_nic_word(struct net_device
*dev
, int x
,u16 y
)
289 outw(y
,dev
->base_addr
+x
);
292 void write_nic_dword(struct net_device
*dev
, int x
,u32 y
)
294 outl(y
,dev
->base_addr
+x
);
297 #else /* RTL_IO_MAP */
299 u8
read_nic_byte(struct net_device
*dev
, int x
)
301 return 0xff&readb((u8
*)dev
->mem_start
+x
);
304 u32
read_nic_dword(struct net_device
*dev
, int x
)
306 return readl((u8
*)dev
->mem_start
+x
);
309 u16
read_nic_word(struct net_device
*dev
, int x
)
311 return readw((u8
*)dev
->mem_start
+x
);
314 void write_nic_byte(struct net_device
*dev
, int x
,u8 y
)
316 writeb(y
,(u8
*)dev
->mem_start
+x
);
320 void write_nic_dword(struct net_device
*dev
, int x
,u32 y
)
322 writel(y
,(u8
*)dev
->mem_start
+x
);
326 void write_nic_word(struct net_device
*dev
, int x
,u16 y
)
328 writew(y
,(u8
*)dev
->mem_start
+x
);
332 #endif /* RTL_IO_MAP */
334 u8
rtl8192e_ap_sec_type(struct ieee80211_device
*ieee
)
336 static const u8 ccmp_ie
[4] = {0x00,0x50,0xf2,0x04};
337 static const u8 ccmp_rsn_ie
[4] = {0x00, 0x0f, 0xac, 0x04};
338 int wpa_ie_len
= ieee
->wpa_ie_len
;
339 struct ieee80211_crypt_data
* crypt
;
342 crypt
= ieee
->crypt
[ieee
->tx_keyidx
];
344 encrypt
= (ieee
->current_network
.capability
& WLAN_CAPABILITY_PRIVACY
) ||
345 (ieee
->host_encrypt
&& crypt
&& crypt
->ops
&&
346 (0 == strcmp(crypt
->ops
->name
,"WEP")));
349 if(encrypt
&& (wpa_ie_len
== 0)) {
350 // wep encryption, no N mode setting */
352 } else if((wpa_ie_len
!= 0)) {
353 // parse pairwise key type */
354 if (((ieee
->wpa_ie
[0] == 0xdd) && (!memcmp(&(ieee
->wpa_ie
[14]),ccmp_ie
,4))) ||
355 ((ieee
->wpa_ie
[0] == 0x30) && (!memcmp(&ieee
->wpa_ie
[10],ccmp_rsn_ie
, 4))))
365 rtl8192e_SetHwReg(struct net_device
*dev
,u8 variable
,u8
* val
)
367 struct r8192_priv
* priv
= ieee80211_priv(dev
);
373 write_nic_dword(dev
, BSSIDR
, ((u32
*)(val
))[0]);
374 write_nic_word(dev
, BSSIDR
+2, ((u16
*)(val
+2))[0]);
377 case HW_VAR_MEDIA_STATUS
:
379 RT_OP_MODE OpMode
= *((RT_OP_MODE
*)(val
));
380 u8 btMsr
= read_nic_byte(dev
, MSR
);
386 case RT_OP_MODE_INFRASTRUCTURE
:
390 case RT_OP_MODE_IBSS
:
403 write_nic_byte(dev
, MSR
, btMsr
);
407 case HW_VAR_CHECK_BSSID
:
411 Type
= ((u8
*)(val
))[0];
412 RegRCR
= read_nic_dword(dev
,RCR
);
413 priv
->ReceiveConfig
= RegRCR
;
416 RegRCR
|= (RCR_CBSSID
);
417 else if (Type
== false)
418 RegRCR
&= (~RCR_CBSSID
);
420 write_nic_dword(dev
, RCR
,RegRCR
);
421 priv
->ReceiveConfig
= RegRCR
;
426 case HW_VAR_SLOT_TIME
:
428 priv
->slot_time
= val
[0];
429 write_nic_byte(dev
, SLOT_TIME
, val
[0]);
434 case HW_VAR_ACK_PREAMBLE
:
437 priv
->short_preamble
= (bool)(*(u8
*)val
);
438 regTmp
= priv
->basic_rate
;
439 if (priv
->short_preamble
)
440 regTmp
|= BRSR_AckShortPmb
;
441 write_nic_dword(dev
, RRSR
, regTmp
);
446 write_nic_dword(dev
, CPU_GEN
, ((u32
*)(val
))[0]);
455 static struct proc_dir_entry
*rtl8192_proc
= NULL
;
457 static int proc_get_stats_ap(char *page
, char **start
,
458 off_t offset
, int count
,
459 int *eof
, void *data
)
461 struct net_device
*dev
= data
;
462 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
463 struct ieee80211_device
*ieee
= priv
->ieee80211
;
464 struct ieee80211_network
*target
;
467 list_for_each_entry(target
, &ieee
->network_list
, list
) {
469 len
+= snprintf(page
+ len
, count
- len
,
470 "%s ", target
->ssid
);
472 if(target
->wpa_ie_len
>0 || target
->rsn_ie_len
>0){
473 len
+= snprintf(page
+ len
, count
- len
,
477 len
+= snprintf(page
+ len
, count
- len
,
487 static int proc_get_registers(char *page
, char **start
,
488 off_t offset
, int count
,
489 int *eof
, void *data
)
491 struct net_device
*dev
= data
;
496 /* This dump the current register page */
497 len
+= snprintf(page
+ len
, count
- len
,
498 "\n####################page 0##################\n ");
502 len
+= snprintf(page
+ len
, count
- len
,
505 for(i
=0;i
<16 && n
<=max
;i
++,n
++)
506 len
+= snprintf(page
+ len
, count
- len
,
507 "%2x ",read_nic_byte(dev
,n
));
509 len
+= snprintf(page
+ len
, count
- len
,"\n");
510 len
+= snprintf(page
+ len
, count
- len
,
511 "\n####################page 1##################\n ");
514 len
+= snprintf(page
+ len
, count
- len
,
517 for(i
=0;i
<16 && n
<=max
;i
++,n
++)
518 len
+= snprintf(page
+ len
, count
- len
,
519 "%2x ",read_nic_byte(dev
,0x100|n
));
522 len
+= snprintf(page
+ len
, count
- len
,
523 "\n####################page 3##################\n ");
526 len
+= snprintf(page
+ len
, count
- len
,
529 for(i
=0;i
<16 && n
<=max
;i
++,n
++)
530 len
+= snprintf(page
+ len
, count
- len
,
531 "%2x ",read_nic_byte(dev
,0x300|n
));
539 static int proc_get_stats_tx(char *page
, char **start
,
540 off_t offset
, int count
,
541 int *eof
, void *data
)
543 struct net_device
*dev
= data
;
544 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
548 len
+= snprintf(page
+ len
, count
- len
,
549 "TX VI priority ok int: %lu\n"
550 // "TX VI priority error int: %lu\n"
551 "TX VO priority ok int: %lu\n"
552 // "TX VO priority error int: %lu\n"
553 "TX BE priority ok int: %lu\n"
554 // "TX BE priority error int: %lu\n"
555 "TX BK priority ok int: %lu\n"
556 // "TX BK priority error int: %lu\n"
557 "TX MANAGE priority ok int: %lu\n"
558 // "TX MANAGE priority error int: %lu\n"
559 "TX BEACON priority ok int: %lu\n"
560 "TX BEACON priority error int: %lu\n"
561 "TX CMDPKT priority ok int: %lu\n"
562 // "TX high priority ok int: %lu\n"
563 // "TX high priority failed error int: %lu\n"
564 // "TX queue resume: %lu\n"
565 "TX queue stopped?: %d\n"
566 "TX fifo overflow: %lu\n"
567 // "TX beacon: %lu\n"
568 // "TX VI queue: %d\n"
569 // "TX VO queue: %d\n"
570 // "TX BE queue: %d\n"
571 // "TX BK queue: %d\n"
572 // "TX HW queue: %d\n"
573 // "TX VI dropped: %lu\n"
574 // "TX VO dropped: %lu\n"
575 // "TX BE dropped: %lu\n"
576 // "TX BK dropped: %lu\n"
577 "TX total data packets %lu\n"
578 "TX total data bytes :%lu\n",
579 // "TX beacon aborted: %lu\n",
580 priv
->stats
.txviokint
,
581 // priv->stats.txvierr,
582 priv
->stats
.txvookint
,
583 // priv->stats.txvoerr,
584 priv
->stats
.txbeokint
,
585 // priv->stats.txbeerr,
586 priv
->stats
.txbkokint
,
587 // priv->stats.txbkerr,
588 priv
->stats
.txmanageokint
,
589 // priv->stats.txmanageerr,
590 priv
->stats
.txbeaconokint
,
591 priv
->stats
.txbeaconerr
,
592 priv
->stats
.txcmdpktokint
,
593 // priv->stats.txhpokint,
594 // priv->stats.txhperr,
595 // priv->stats.txresumed,
596 netif_queue_stopped(dev
),
597 priv
->stats
.txoverflow
,
598 // priv->stats.txbeacon,
599 // read_nic_byte(dev, TXFIFOCOUNT),
600 // priv->stats.txvidrop,
601 // priv->stats.txvodrop,
602 priv
->ieee80211
->stats
.tx_packets
,
603 priv
->ieee80211
->stats
.tx_bytes
606 // priv->stats.txbedrop,
607 // priv->stats.txbkdrop
608 // priv->stats.txdatapkt
609 // priv->stats.txbeaconerr
618 static int proc_get_stats_rx(char *page
, char **start
,
619 off_t offset
, int count
,
620 int *eof
, void *data
)
622 struct net_device
*dev
= data
;
623 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
627 len
+= snprintf(page
+ len
, count
- len
,
630 "RX rx overflow error: %lu\n"
631 "RX invalid urb error: %lu\n",
634 priv
->stats
.rxoverflow
,
635 priv
->stats
.rxurberr
);
641 static void rtl8192_proc_module_init(void)
643 RT_TRACE(COMP_INIT
, "Initializing proc filesystem");
644 rtl8192_proc
=create_proc_entry(RTL819xE_MODULE_NAME
, S_IFDIR
, init_net
.proc_net
);
648 static void rtl8192_proc_module_remove(void)
650 remove_proc_entry(RTL819xE_MODULE_NAME
, init_net
.proc_net
);
654 static void rtl8192_proc_remove_one(struct net_device
*dev
)
656 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
658 printk("dev name=======> %s\n",dev
->name
);
661 // remove_proc_entry("stats-hw", priv->dir_dev);
662 remove_proc_entry("stats-tx", priv
->dir_dev
);
663 remove_proc_entry("stats-rx", priv
->dir_dev
);
664 // remove_proc_entry("stats-ieee", priv->dir_dev);
665 remove_proc_entry("stats-ap", priv
->dir_dev
);
666 remove_proc_entry("registers", priv
->dir_dev
);
667 // remove_proc_entry("cck-registers",priv->dir_dev);
668 // remove_proc_entry("ofdm-registers",priv->dir_dev);
669 //remove_proc_entry(dev->name, rtl8192_proc);
670 remove_proc_entry("wlan0", rtl8192_proc
);
671 priv
->dir_dev
= NULL
;
676 static void rtl8192_proc_init_one(struct net_device
*dev
)
678 struct proc_dir_entry
*e
;
679 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
680 priv
->dir_dev
= create_proc_entry(dev
->name
,
681 S_IFDIR
| S_IRUGO
| S_IXUGO
,
683 if (!priv
->dir_dev
) {
684 RT_TRACE(COMP_ERR
, "Unable to initialize /proc/net/rtl8192/%s\n",
688 e
= create_proc_read_entry("stats-rx", S_IFREG
| S_IRUGO
,
689 priv
->dir_dev
, proc_get_stats_rx
, dev
);
692 RT_TRACE(COMP_ERR
,"Unable to initialize "
693 "/proc/net/rtl8192/%s/stats-rx\n",
698 e
= create_proc_read_entry("stats-tx", S_IFREG
| S_IRUGO
,
699 priv
->dir_dev
, proc_get_stats_tx
, dev
);
702 RT_TRACE(COMP_ERR
, "Unable to initialize "
703 "/proc/net/rtl8192/%s/stats-tx\n",
707 e
= create_proc_read_entry("stats-ap", S_IFREG
| S_IRUGO
,
708 priv
->dir_dev
, proc_get_stats_ap
, dev
);
711 RT_TRACE(COMP_ERR
, "Unable to initialize "
712 "/proc/net/rtl8192/%s/stats-ap\n",
716 e
= create_proc_read_entry("registers", S_IFREG
| S_IRUGO
,
717 priv
->dir_dev
, proc_get_registers
, dev
);
719 RT_TRACE(COMP_ERR
, "Unable to initialize "
720 "/proc/net/rtl8192/%s/registers\n",
725 short check_nic_enough_desc(struct net_device
*dev
, int prio
)
727 struct r8192_priv
*priv
= ieee80211_priv(dev
);
728 struct rtl8192_tx_ring
*ring
= &priv
->tx_ring
[prio
];
730 /* for now we reserve two free descriptor as a safety boundary
731 * between the tail and the head
733 return (ring
->entries
- skb_queue_len(&ring
->queue
) >= 2);
736 static void tx_timeout(struct net_device
*dev
)
738 struct r8192_priv
*priv
= ieee80211_priv(dev
);
740 schedule_work(&priv
->reset_wq
);
744 static void rtl8192_irq_enable(struct net_device
*dev
)
746 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
747 priv
->irq_enabled
= 1;
748 write_nic_dword(dev
,INTA_MASK
, priv
->irq_mask
);
751 void rtl8192_irq_disable(struct net_device
*dev
)
753 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
755 write_nic_dword(dev
,INTA_MASK
,0);
756 priv
->irq_enabled
= 0;
759 void rtl8192_update_msr(struct net_device
*dev
)
761 struct r8192_priv
*priv
= ieee80211_priv(dev
);
764 msr
= read_nic_byte(dev
, MSR
);
765 msr
&= ~ MSR_LINK_MASK
;
767 /* do not change in link_state != WLAN_LINK_ASSOCIATED.
768 * msr must be updated if the state is ASSOCIATING.
769 * this is intentional and make sense for ad-hoc and
770 * master (see the create BSS/IBSS func)
772 if (priv
->ieee80211
->state
== IEEE80211_LINKED
){
774 if (priv
->ieee80211
->iw_mode
== IW_MODE_INFRA
)
775 msr
|= (MSR_LINK_MANAGED
<<MSR_LINK_SHIFT
);
776 else if (priv
->ieee80211
->iw_mode
== IW_MODE_ADHOC
)
777 msr
|= (MSR_LINK_ADHOC
<<MSR_LINK_SHIFT
);
778 else if (priv
->ieee80211
->iw_mode
== IW_MODE_MASTER
)
779 msr
|= (MSR_LINK_MASTER
<<MSR_LINK_SHIFT
);
782 msr
|= (MSR_LINK_NONE
<<MSR_LINK_SHIFT
);
784 write_nic_byte(dev
, MSR
, msr
);
787 void rtl8192_set_chan(struct net_device
*dev
,short ch
)
789 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
793 /* need to implement rf set channel here WB */
795 if (priv
->rf_set_chan
)
796 priv
->rf_set_chan(dev
, priv
->chan
);
799 void rtl8192_rx_enable(struct net_device
*dev
)
801 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
803 write_nic_dword(dev
, RDQDA
,priv
->rx_ring_dma
);
806 /* the TX_DESC_BASE setting is according to the following queue index
815 * BEACON_QUEUE ===> 8
817 static const u32 TX_DESC_BASE
[] = {BKQDA
, BEQDA
, VIQDA
, VOQDA
, HCCAQDA
, CQDA
, MQDA
, HQDA
, BQDA
};
818 void rtl8192_tx_enable(struct net_device
*dev
)
820 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
823 for (i
= 0; i
< MAX_TX_QUEUE_COUNT
; i
++)
824 write_nic_dword(dev
, TX_DESC_BASE
[i
], priv
->tx_ring
[i
].dma
);
826 ieee80211_reset_queue(priv
->ieee80211
);
830 static void rtl8192_free_rx_ring(struct net_device
*dev
)
832 struct r8192_priv
*priv
= ieee80211_priv(dev
);
835 for (i
= 0; i
< priv
->rxringcount
; i
++) {
836 struct sk_buff
*skb
= priv
->rx_buf
[i
];
840 pci_unmap_single(priv
->pdev
,
841 *((dma_addr_t
*)skb
->cb
),
842 priv
->rxbuffersize
, PCI_DMA_FROMDEVICE
);
846 pci_free_consistent(priv
->pdev
, sizeof(*priv
->rx_ring
) * priv
->rxringcount
,
847 priv
->rx_ring
, priv
->rx_ring_dma
);
848 priv
->rx_ring
= NULL
;
851 static void rtl8192_free_tx_ring(struct net_device
*dev
, unsigned int prio
)
853 struct r8192_priv
*priv
= ieee80211_priv(dev
);
854 struct rtl8192_tx_ring
*ring
= &priv
->tx_ring
[prio
];
856 while (skb_queue_len(&ring
->queue
)) {
857 tx_desc_819x_pci
*entry
= &ring
->desc
[ring
->idx
];
858 struct sk_buff
*skb
= __skb_dequeue(&ring
->queue
);
860 pci_unmap_single(priv
->pdev
, le32_to_cpu(entry
->TxBuffAddr
),
861 skb
->len
, PCI_DMA_TODEVICE
);
863 ring
->idx
= (ring
->idx
+ 1) % ring
->entries
;
866 pci_free_consistent(priv
->pdev
, sizeof(*ring
->desc
)*ring
->entries
,
867 ring
->desc
, ring
->dma
);
871 void PHY_SetRtl8192eRfOff(struct net_device
* dev
)
873 //disable RF-Chip A/B
874 rtl8192_setBBreg(dev
, rFPGA0_XA_RFInterfaceOE
, BIT4
, 0x0);
875 //analog to digital off, for power save
876 rtl8192_setBBreg(dev
, rFPGA0_AnalogParameter4
, 0x300, 0x0);
877 //digital to analog off, for power save
878 rtl8192_setBBreg(dev
, rFPGA0_AnalogParameter1
, 0x18, 0x0);
880 rtl8192_setBBreg(dev
, rOFDM0_TRxPathEnable
, 0xf, 0x0);
882 rtl8192_setBBreg(dev
, rOFDM1_TRxPathEnable
, 0xf, 0x0);
883 //analog to digital part2 off, for power save
884 rtl8192_setBBreg(dev
, rFPGA0_AnalogParameter1
, 0x60, 0x0);
885 rtl8192_setBBreg(dev
, rFPGA0_AnalogParameter1
, 0x4, 0x0);
886 // Analog parameter!!Change bias and Lbus control.
887 write_nic_byte(dev
, ANAPAR_FOR_8192PciE
, 0x07);
891 void rtl8192_halt_adapter(struct net_device
*dev
, bool reset
)
893 struct r8192_priv
*priv
= ieee80211_priv(dev
);
898 OpMode
= RT_OP_MODE_NO_LINK
;
899 priv
->ieee80211
->SetHwRegHandler(dev
, HW_VAR_MEDIA_STATUS
, &OpMode
);
901 if (!priv
->ieee80211
->bSupportRemoteWakeUp
) {
903 * disable tx/rx. In 8185 we write 0x10 (Reset bit),
904 * but here we make reference to WMAC and wirte 0x0
906 write_nic_byte(dev
, CMDR
, 0);
915 priv
->bHwRfOffAction
= 2;
919 * Call MgntActSet_RF_State instead to
920 * prevent RF config race condition.
922 if (!priv
->ieee80211
->bSupportRemoteWakeUp
) {
923 PHY_SetRtl8192eRfOff(dev
);
924 ulRegRead
= read_nic_dword(dev
,CPU_GEN
);
925 ulRegRead
|= CPU_GEN_SYSTEM_RESET
;
926 write_nic_dword(dev
,CPU_GEN
, ulRegRead
);
929 write_nic_dword(dev
, WFCRC0
, 0xffffffff);
930 write_nic_dword(dev
, WFCRC1
, 0xffffffff);
931 write_nic_dword(dev
, WFCRC2
, 0xffffffff);
933 /* Write PMR register */
934 write_nic_byte(dev
, PMR
, 0x5);
935 /* Disable tx, enanble rx */
936 write_nic_byte(dev
, MacBlkCtrl
, 0xa);
940 for(i
= 0; i
< MAX_QUEUE_SIZE
; i
++) {
941 skb_queue_purge(&priv
->ieee80211
->skb_waitQ
[i
]);
943 for(i
= 0; i
< MAX_QUEUE_SIZE
; i
++) {
944 skb_queue_purge(&priv
->ieee80211
->skb_aggQ
[i
]);
947 skb_queue_purge(&priv
->skb_queue
);
950 static const u16 rtl_rate
[] = {10,20,55,110,60,90,120,180,240,360,480,540};
951 inline u16
rtl8192_rate2rate(short rate
)
953 if (rate
>11) return 0;
954 return rtl_rate
[rate
];
957 static void rtl8192_data_hard_stop(struct net_device
*dev
)
961 static void rtl8192_data_hard_resume(struct net_device
*dev
)
966 * this function TX data frames when the ieee80211 stack requires this.
967 * It checks also if we need to stop the ieee tx queue, eventually do it
969 static void rtl8192_hard_data_xmit(struct sk_buff
*skb
, struct net_device
*dev
, int rate
)
971 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
973 cb_desc
*tcb_desc
= (cb_desc
*)(skb
->cb
+ MAX_DEV_ADDR_SIZE
);
974 u8 queue_index
= tcb_desc
->queue_index
;
976 /* shall not be referred by command packet */
977 BUG_ON(queue_index
== TXCMD_QUEUE
);
979 if (priv
->bHwRadioOff
|| (!priv
->up
))
985 memcpy(skb
->cb
, &dev
, sizeof(dev
));
987 skb_push(skb
, priv
->ieee80211
->tx_headroom
);
988 ret
= rtl8192_tx(dev
, skb
);
993 if (queue_index
!= MGNT_QUEUE
) {
994 priv
->ieee80211
->stats
.tx_bytes
+= (skb
->len
- priv
->ieee80211
->tx_headroom
);
995 priv
->ieee80211
->stats
.tx_packets
++;
1000 * This is a rough attempt to TX a frame
1001 * This is called by the ieee 80211 stack to TX management frames.
1002 * If the ring is full packet are dropped (for data frame the queue
1003 * is stopped before this can happen).
1005 static int rtl8192_hard_start_xmit(struct sk_buff
*skb
,struct net_device
*dev
)
1007 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
1009 cb_desc
*tcb_desc
= (cb_desc
*)(skb
->cb
+ MAX_DEV_ADDR_SIZE
);
1010 u8 queue_index
= tcb_desc
->queue_index
;
1012 if (queue_index
!= TXCMD_QUEUE
) {
1013 if (priv
->bHwRadioOff
|| (!priv
->up
))
1020 memcpy(skb
->cb
, &dev
, sizeof(dev
));
1021 if (queue_index
== TXCMD_QUEUE
) {
1022 rtl819xE_tx_cmd(dev
, skb
);
1026 tcb_desc
->RATRIndex
= 7;
1027 tcb_desc
->bTxDisableRateFallBack
= 1;
1028 tcb_desc
->bTxUseDriverAssingedRate
= 1;
1029 tcb_desc
->bTxEnableFwCalcDur
= 1;
1030 skb_push(skb
, priv
->ieee80211
->tx_headroom
);
1031 ret
= rtl8192_tx(dev
, skb
);
1041 static void rtl8192_tx_isr(struct net_device
*dev
, int prio
)
1043 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
1044 struct rtl8192_tx_ring
*ring
= &priv
->tx_ring
[prio
];
1046 while (skb_queue_len(&ring
->queue
)) {
1047 tx_desc_819x_pci
*entry
= &ring
->desc
[ring
->idx
];
1048 struct sk_buff
*skb
;
1051 * beacon packet will only use the first descriptor defaultly,
1052 * and the OWN may not be cleared by the hardware
1054 if (prio
!= BEACON_QUEUE
) {
1057 ring
->idx
= (ring
->idx
+ 1) % ring
->entries
;
1060 skb
= __skb_dequeue(&ring
->queue
);
1061 pci_unmap_single(priv
->pdev
, le32_to_cpu(entry
->TxBuffAddr
),
1062 skb
->len
, PCI_DMA_TODEVICE
);
1066 if (prio
== MGNT_QUEUE
) {
1067 if (priv
->ieee80211
->ack_tx_to_ieee
) {
1068 if (rtl8192_is_tx_queue_empty(dev
)) {
1069 priv
->ieee80211
->ack_tx_to_ieee
= 0;
1070 ieee80211_ps_tx_ack(priv
->ieee80211
, 1);
1075 if (prio
!= BEACON_QUEUE
) {
1076 /* try to deal with the pending packets */
1077 tasklet_schedule(&priv
->irq_tx_tasklet
);
1081 static void rtl8192_stop_beacon(struct net_device
*dev
)
1085 static void rtl8192_config_rate(struct net_device
* dev
, u16
* rate_config
)
1087 struct r8192_priv
*priv
= ieee80211_priv(dev
);
1088 struct ieee80211_network
*net
;
1089 u8 i
=0, basic_rate
= 0;
1090 net
= & priv
->ieee80211
->current_network
;
1092 for (i
=0; i
<net
->rates_len
; i
++)
1094 basic_rate
= net
->rates
[i
]&0x7f;
1097 case MGN_1M
: *rate_config
|= RRSR_1M
; break;
1098 case MGN_2M
: *rate_config
|= RRSR_2M
; break;
1099 case MGN_5_5M
: *rate_config
|= RRSR_5_5M
; break;
1100 case MGN_11M
: *rate_config
|= RRSR_11M
; break;
1101 case MGN_6M
: *rate_config
|= RRSR_6M
; break;
1102 case MGN_9M
: *rate_config
|= RRSR_9M
; break;
1103 case MGN_12M
: *rate_config
|= RRSR_12M
; break;
1104 case MGN_18M
: *rate_config
|= RRSR_18M
; break;
1105 case MGN_24M
: *rate_config
|= RRSR_24M
; break;
1106 case MGN_36M
: *rate_config
|= RRSR_36M
; break;
1107 case MGN_48M
: *rate_config
|= RRSR_48M
; break;
1108 case MGN_54M
: *rate_config
|= RRSR_54M
; break;
1111 for (i
=0; i
<net
->rates_ex_len
; i
++)
1113 basic_rate
= net
->rates_ex
[i
]&0x7f;
1116 case MGN_1M
: *rate_config
|= RRSR_1M
; break;
1117 case MGN_2M
: *rate_config
|= RRSR_2M
; break;
1118 case MGN_5_5M
: *rate_config
|= RRSR_5_5M
; break;
1119 case MGN_11M
: *rate_config
|= RRSR_11M
; break;
1120 case MGN_6M
: *rate_config
|= RRSR_6M
; break;
1121 case MGN_9M
: *rate_config
|= RRSR_9M
; break;
1122 case MGN_12M
: *rate_config
|= RRSR_12M
; break;
1123 case MGN_18M
: *rate_config
|= RRSR_18M
; break;
1124 case MGN_24M
: *rate_config
|= RRSR_24M
; break;
1125 case MGN_36M
: *rate_config
|= RRSR_36M
; break;
1126 case MGN_48M
: *rate_config
|= RRSR_48M
; break;
1127 case MGN_54M
: *rate_config
|= RRSR_54M
; break;
1133 #define SHORT_SLOT_TIME 9
1134 #define NON_SHORT_SLOT_TIME 20
1136 static void rtl8192_update_cap(struct net_device
* dev
, u16 cap
)
1139 struct r8192_priv
*priv
= ieee80211_priv(dev
);
1140 struct ieee80211_network
*net
= &priv
->ieee80211
->current_network
;
1141 priv
->short_preamble
= cap
& WLAN_CAPABILITY_SHORT_PREAMBLE
;
1142 tmp
= priv
->basic_rate
;
1143 if (priv
->short_preamble
)
1144 tmp
|= BRSR_AckShortPmb
;
1145 write_nic_dword(dev
, RRSR
, tmp
);
1147 if (net
->mode
& (IEEE_G
|IEEE_N_24G
))
1150 if ((cap
& WLAN_CAPABILITY_SHORT_SLOT
)&&(!priv
->ieee80211
->pHTInfo
->bCurrentRT2RTLongSlotTime
))
1152 slot_time
= SHORT_SLOT_TIME
;
1154 else //long slot time
1155 slot_time
= NON_SHORT_SLOT_TIME
;
1156 priv
->slot_time
= slot_time
;
1157 write_nic_byte(dev
, SLOT_TIME
, slot_time
);
1162 static void rtl8192_net_update(struct net_device
*dev
)
1164 struct r8192_priv
*priv
= ieee80211_priv(dev
);
1165 struct ieee80211_network
*net
;
1166 u16 BcnTimeCfg
= 0, BcnCW
= 6, BcnIFS
= 0xf;
1167 u16 rate_config
= 0;
1168 net
= &priv
->ieee80211
->current_network
;
1170 /* update Basic rate: RR, BRSR */
1171 rtl8192_config_rate(dev
, &rate_config
);
1174 * Select RRSR (in Legacy-OFDM and CCK)
1175 * For 8190, we select only 24M, 12M, 6M, 11M, 5.5M,
1176 * 2M, and 1M from the Basic rate.
1177 * We do not use other rates.
1179 priv
->basic_rate
= rate_config
&= 0x15f;
1182 write_nic_dword(dev
, BSSIDR
, ((u32
*)net
->bssid
)[0]);
1183 write_nic_word(dev
, BSSIDR
+4, ((u16
*)net
->bssid
)[2]);
1185 if (priv
->ieee80211
->iw_mode
== IW_MODE_ADHOC
)
1187 write_nic_word(dev
, ATIMWND
, 2);
1188 write_nic_word(dev
, BCN_DMATIME
, 256);
1189 write_nic_word(dev
, BCN_INTERVAL
, net
->beacon_interval
);
1191 * BIT15 of BCN_DRV_EARLY_INT will indicate
1192 * whether software beacon or hw beacon is applied.
1194 write_nic_word(dev
, BCN_DRV_EARLY_INT
, 10);
1195 write_nic_byte(dev
, BCN_ERR_THRESH
, 100);
1197 BcnTimeCfg
|= (BcnCW
<<BCN_TCFG_CW_SHIFT
);
1198 /* TODO: BcnIFS may required to be changed on ASIC */
1199 BcnTimeCfg
|= BcnIFS
<<BCN_TCFG_IFS
;
1200 write_nic_word(dev
, BCN_TCFG
, BcnTimeCfg
);
1204 void rtl819xE_tx_cmd(struct net_device
*dev
, struct sk_buff
*skb
)
1206 struct r8192_priv
*priv
= ieee80211_priv(dev
);
1207 struct rtl8192_tx_ring
*ring
;
1208 tx_desc_819x_pci
*entry
;
1212 unsigned long flags
;
1214 ring
= &priv
->tx_ring
[TXCMD_QUEUE
];
1215 mapping
= pci_map_single(priv
->pdev
, skb
->data
, skb
->len
, PCI_DMA_TODEVICE
);
1217 spin_lock_irqsave(&priv
->irq_th_lock
,flags
);
1218 idx
= (ring
->idx
+ skb_queue_len(&ring
->queue
)) % ring
->entries
;
1219 entry
= &ring
->desc
[idx
];
1221 tcb_desc
= (cb_desc
*)(skb
->cb
+ MAX_DEV_ADDR_SIZE
);
1223 entry
->LINIP
= tcb_desc
->bLastIniPkt
;
1224 entry
->FirstSeg
= 1;//first segment
1225 entry
->LastSeg
= 1; //last segment
1226 if(tcb_desc
->bCmdOrInit
== DESC_PACKET_TYPE_INIT
) {
1227 entry
->CmdInit
= DESC_PACKET_TYPE_INIT
;
1229 entry
->CmdInit
= DESC_PACKET_TYPE_NORMAL
;
1230 entry
->Offset
= sizeof(TX_FWINFO_8190PCI
) + 8;
1231 entry
->PktSize
= (u16
)(tcb_desc
->pkt_size
+ entry
->Offset
);
1232 entry
->QueueSelect
= QSLT_CMD
;
1233 entry
->TxFWInfoSize
= 0x08;
1234 entry
->RATid
= (u8
)DESC_PACKET_TYPE_INIT
;
1236 entry
->TxBufferSize
= skb
->len
;
1237 entry
->TxBuffAddr
= cpu_to_le32(mapping
);
1240 __skb_queue_tail(&ring
->queue
, skb
);
1241 spin_unlock_irqrestore(&priv
->irq_th_lock
,flags
);
1243 write_nic_byte(dev
, TPPoll
, TPPoll_CQ
);
1249 * Mapping Software/Hardware descriptor queue id to "Queue Select Field"
1250 * in TxFwInfo data structure
1252 static u8
MapHwQueueToFirmwareQueue(u8 QueueID
)
1258 QueueSelect
= QSLT_BE
;
1262 QueueSelect
= QSLT_BK
;
1266 QueueSelect
= QSLT_VO
;
1270 QueueSelect
= QSLT_VI
;
1274 QueueSelect
= QSLT_MGNT
;
1278 QueueSelect
= QSLT_BEACON
;
1282 QueueSelect
= QSLT_CMD
;
1287 RT_TRACE(COMP_ERR
, "Impossible Queue Selection: %d\n", QueueID
);
1293 static u8
MRateToHwRate8190Pci(u8 rate
)
1295 u8 ret
= DESC90_RATE1M
;
1298 case MGN_1M
: ret
= DESC90_RATE1M
; break;
1299 case MGN_2M
: ret
= DESC90_RATE2M
; break;
1300 case MGN_5_5M
: ret
= DESC90_RATE5_5M
; break;
1301 case MGN_11M
: ret
= DESC90_RATE11M
; break;
1302 case MGN_6M
: ret
= DESC90_RATE6M
; break;
1303 case MGN_9M
: ret
= DESC90_RATE9M
; break;
1304 case MGN_12M
: ret
= DESC90_RATE12M
; break;
1305 case MGN_18M
: ret
= DESC90_RATE18M
; break;
1306 case MGN_24M
: ret
= DESC90_RATE24M
; break;
1307 case MGN_36M
: ret
= DESC90_RATE36M
; break;
1308 case MGN_48M
: ret
= DESC90_RATE48M
; break;
1309 case MGN_54M
: ret
= DESC90_RATE54M
; break;
1311 // HT rate since here
1312 case MGN_MCS0
: ret
= DESC90_RATEMCS0
; break;
1313 case MGN_MCS1
: ret
= DESC90_RATEMCS1
; break;
1314 case MGN_MCS2
: ret
= DESC90_RATEMCS2
; break;
1315 case MGN_MCS3
: ret
= DESC90_RATEMCS3
; break;
1316 case MGN_MCS4
: ret
= DESC90_RATEMCS4
; break;
1317 case MGN_MCS5
: ret
= DESC90_RATEMCS5
; break;
1318 case MGN_MCS6
: ret
= DESC90_RATEMCS6
; break;
1319 case MGN_MCS7
: ret
= DESC90_RATEMCS7
; break;
1320 case MGN_MCS8
: ret
= DESC90_RATEMCS8
; break;
1321 case MGN_MCS9
: ret
= DESC90_RATEMCS9
; break;
1322 case MGN_MCS10
: ret
= DESC90_RATEMCS10
; break;
1323 case MGN_MCS11
: ret
= DESC90_RATEMCS11
; break;
1324 case MGN_MCS12
: ret
= DESC90_RATEMCS12
; break;
1325 case MGN_MCS13
: ret
= DESC90_RATEMCS13
; break;
1326 case MGN_MCS14
: ret
= DESC90_RATEMCS14
; break;
1327 case MGN_MCS15
: ret
= DESC90_RATEMCS15
; break;
1328 case (0x80|0x20): ret
= DESC90_RATEMCS32
; break;
1336 static u8
QueryIsShort(u8 TxHT
, u8 TxRate
, cb_desc
*tcb_desc
)
1340 tmp_Short
= (TxHT
==1)?((tcb_desc
->bUseShortGI
)?1:0):((tcb_desc
->bUseShortPreamble
)?1:0);
1342 if(TxHT
==1 && TxRate
!= DESC90_RATEMCS15
)
1349 * The tx procedure is just as following,
1350 * skb->cb will contain all the following information,
1351 * priority, morefrag, rate, &dev.
1353 short rtl8192_tx(struct net_device
*dev
, struct sk_buff
* skb
)
1355 struct r8192_priv
*priv
= ieee80211_priv(dev
);
1356 struct rtl8192_tx_ring
*ring
;
1357 unsigned long flags
;
1358 cb_desc
*tcb_desc
= (cb_desc
*)(skb
->cb
+ MAX_DEV_ADDR_SIZE
);
1359 tx_desc_819x_pci
*pdesc
= NULL
;
1360 TX_FWINFO_8190PCI
*pTxFwInfo
= NULL
;
1362 bool multi_addr
= false, broad_addr
= false, uni_addr
= false;
1363 u8
*pda_addr
= NULL
;
1366 if (priv
->bdisable_nic
) {
1367 RT_TRACE(COMP_ERR
, "Nic is disabled! Can't tx packet len=%d qidx=%d!!!\n",
1368 skb
->len
, tcb_desc
->queue_index
);
1373 priv
->ieee80211
->bAwakePktSent
= true;
1376 mapping
= pci_map_single(priv
->pdev
, skb
->data
, skb
->len
, PCI_DMA_TODEVICE
);
1378 /* collect the tx packets statitcs */
1379 pda_addr
= ((u8
*)skb
->data
) + sizeof(TX_FWINFO_8190PCI
);
1380 if (is_multicast_ether_addr(pda_addr
))
1382 else if (is_broadcast_ether_addr(pda_addr
))
1388 priv
->stats
.txbytesunicast
+= (u8
)(skb
->len
) - sizeof(TX_FWINFO_8190PCI
);
1389 else if (multi_addr
)
1390 priv
->stats
.txbytesmulticast
+= (u8
)(skb
->len
) - sizeof(TX_FWINFO_8190PCI
);
1392 priv
->stats
.txbytesbroadcast
+= (u8
)(skb
->len
) - sizeof(TX_FWINFO_8190PCI
);
1394 /* fill tx firmware */
1395 pTxFwInfo
= (PTX_FWINFO_8190PCI
)skb
->data
;
1396 memset(pTxFwInfo
, 0, sizeof(TX_FWINFO_8190PCI
));
1397 pTxFwInfo
->TxHT
= (tcb_desc
->data_rate
&0x80) ? 1 : 0;
1398 pTxFwInfo
->TxRate
= MRateToHwRate8190Pci((u8
)tcb_desc
->data_rate
);
1399 pTxFwInfo
->EnableCPUDur
= tcb_desc
->bTxEnableFwCalcDur
;
1400 pTxFwInfo
->Short
= QueryIsShort(pTxFwInfo
->TxHT
, pTxFwInfo
->TxRate
, tcb_desc
);
1402 /* Aggregation related */
1403 if (tcb_desc
->bAMPDUEnable
) {
1404 pTxFwInfo
->AllowAggregation
= 1;
1405 pTxFwInfo
->RxMF
= tcb_desc
->ampdu_factor
;
1406 pTxFwInfo
->RxAMD
= tcb_desc
->ampdu_density
;
1408 pTxFwInfo
->AllowAggregation
= 0;
1409 pTxFwInfo
->RxMF
= 0;
1410 pTxFwInfo
->RxAMD
= 0;
1413 /* Protection mode related */
1414 pTxFwInfo
->RtsEnable
= (tcb_desc
->bRTSEnable
) ? 1 : 0;
1415 pTxFwInfo
->CtsEnable
= (tcb_desc
->bCTSEnable
) ? 1 : 0;
1416 pTxFwInfo
->RtsSTBC
= (tcb_desc
->bRTSSTBC
) ? 1 : 0;
1417 pTxFwInfo
->RtsHT
= (tcb_desc
->rts_rate
&0x80) ? 1 : 0;
1418 pTxFwInfo
->RtsRate
= MRateToHwRate8190Pci((u8
)tcb_desc
->rts_rate
);
1419 pTxFwInfo
->RtsBandwidth
= 0;
1420 pTxFwInfo
->RtsSubcarrier
= tcb_desc
->RTSSC
;
1421 pTxFwInfo
->RtsShort
= (pTxFwInfo
->RtsHT
== 0) ? (tcb_desc
->bRTSUseShortPreamble
? 1 : 0) : (tcb_desc
->bRTSUseShortGI
? 1 : 0);
1423 /* Set Bandwidth and sub-channel settings. */
1424 if (priv
->CurrentChannelBW
== HT_CHANNEL_WIDTH_20_40
) {
1425 if (tcb_desc
->bPacketBW
) {
1426 pTxFwInfo
->TxBandwidth
= 1;
1428 pTxFwInfo
->TxSubCarrier
= 3;
1430 /* use duplicated mode */
1431 pTxFwInfo
->TxSubCarrier
= 0;
1434 pTxFwInfo
->TxBandwidth
= 0;
1435 pTxFwInfo
->TxSubCarrier
= priv
->nCur40MhzPrimeSC
;
1438 pTxFwInfo
->TxBandwidth
= 0;
1439 pTxFwInfo
->TxSubCarrier
= 0;
1442 spin_lock_irqsave(&priv
->irq_th_lock
, flags
);
1443 ring
= &priv
->tx_ring
[tcb_desc
->queue_index
];
1444 if (tcb_desc
->queue_index
!= BEACON_QUEUE
)
1445 idx
= (ring
->idx
+ skb_queue_len(&ring
->queue
)) % ring
->entries
;
1449 pdesc
= &ring
->desc
[idx
];
1450 if ((pdesc
->OWN
== 1) && (tcb_desc
->queue_index
!= BEACON_QUEUE
)) {
1451 RT_TRACE(COMP_ERR
, "No more TX desc@%d, ring->idx = %d,idx = %d,%x",
1452 tcb_desc
->queue_index
, ring
->idx
, idx
, skb
->len
);
1453 spin_unlock_irqrestore(&priv
->irq_th_lock
, flags
);
1457 /* fill tx descriptor */
1458 memset(pdesc
, 0, 12);
1463 pdesc
->Offset
= sizeof(TX_FWINFO_8190PCI
) + 8; /* We must add 8!! */
1464 pdesc
->PktSize
= (u16
)skb
->len
-sizeof(TX_FWINFO_8190PCI
);
1467 pdesc
->SecCAMID
= 0;
1468 pdesc
->RATid
= tcb_desc
->RATRIndex
;
1471 pdesc
->SecType
= 0x0;
1472 if (tcb_desc
->bHwSec
) {
1473 switch (priv
->ieee80211
->pairwise_key_type
) {
1474 case KEY_TYPE_WEP40
:
1475 case KEY_TYPE_WEP104
:
1476 pdesc
->SecType
= 0x1;
1480 pdesc
->SecType
= 0x2;
1484 pdesc
->SecType
= 0x3;
1488 pdesc
->SecType
= 0x0;
1497 pdesc
->QueueSelect
= MapHwQueueToFirmwareQueue(tcb_desc
->queue_index
);
1498 pdesc
->TxFWInfoSize
= sizeof(TX_FWINFO_8190PCI
);
1500 pdesc
->DISFB
= tcb_desc
->bTxDisableRateFallBack
;
1501 pdesc
->USERATE
= tcb_desc
->bTxUseDriverAssingedRate
;
1503 pdesc
->FirstSeg
= 1;
1505 pdesc
->TxBufferSize
= skb
->len
;
1507 pdesc
->TxBuffAddr
= cpu_to_le32(mapping
);
1508 __skb_queue_tail(&ring
->queue
, skb
);
1510 spin_unlock_irqrestore(&priv
->irq_th_lock
, flags
);
1511 dev
->trans_start
= jiffies
;
1512 write_nic_word(dev
, TPPoll
, 0x01<<tcb_desc
->queue_index
);
1516 static short rtl8192_alloc_rx_desc_ring(struct net_device
*dev
)
1518 struct r8192_priv
*priv
= ieee80211_priv(dev
);
1519 rx_desc_819x_pci
*entry
= NULL
;
1522 priv
->rx_ring
= pci_alloc_consistent(priv
->pdev
,
1523 sizeof(*priv
->rx_ring
) * priv
->rxringcount
, &priv
->rx_ring_dma
);
1525 if (!priv
->rx_ring
|| (unsigned long)priv
->rx_ring
& 0xFF) {
1526 RT_TRACE(COMP_ERR
,"Cannot allocate RX ring\n");
1530 memset(priv
->rx_ring
, 0, sizeof(*priv
->rx_ring
) * priv
->rxringcount
);
1533 for (i
= 0; i
< priv
->rxringcount
; i
++) {
1534 struct sk_buff
*skb
= dev_alloc_skb(priv
->rxbuffersize
);
1535 dma_addr_t
*mapping
;
1536 entry
= &priv
->rx_ring
[i
];
1539 priv
->rx_buf
[i
] = skb
;
1540 mapping
= (dma_addr_t
*)skb
->cb
;
1541 *mapping
= pci_map_single(priv
->pdev
, skb_tail_pointer(skb
),
1542 priv
->rxbuffersize
, PCI_DMA_FROMDEVICE
);
1544 entry
->BufferAddress
= cpu_to_le32(*mapping
);
1546 entry
->Length
= priv
->rxbuffersize
;
1554 static int rtl8192_alloc_tx_desc_ring(struct net_device
*dev
,
1555 unsigned int prio
, unsigned int entries
)
1557 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
1558 tx_desc_819x_pci
*ring
;
1562 ring
= pci_alloc_consistent(priv
->pdev
, sizeof(*ring
) * entries
, &dma
);
1563 if (!ring
|| (unsigned long)ring
& 0xFF) {
1564 RT_TRACE(COMP_ERR
, "Cannot allocate TX ring (prio = %d)\n", prio
);
1568 memset(ring
, 0, sizeof(*ring
)*entries
);
1569 priv
->tx_ring
[prio
].desc
= ring
;
1570 priv
->tx_ring
[prio
].dma
= dma
;
1571 priv
->tx_ring
[prio
].idx
= 0;
1572 priv
->tx_ring
[prio
].entries
= entries
;
1573 skb_queue_head_init(&priv
->tx_ring
[prio
].queue
);
1575 for (i
= 0; i
< entries
; i
++)
1576 ring
[i
].NextDescAddress
=
1577 cpu_to_le32((u32
)dma
+ ((i
+ 1) % entries
) * sizeof(*ring
));
1582 static short rtl8192_pci_initdescring(struct net_device
*dev
)
1586 struct r8192_priv
*priv
= ieee80211_priv(dev
);
1588 ret
= rtl8192_alloc_rx_desc_ring(dev
);
1592 /* general process for other queue */
1593 for (i
= 0; i
< MAX_TX_QUEUE_COUNT
; i
++) {
1594 ret
= rtl8192_alloc_tx_desc_ring(dev
, i
, priv
->txringcount
);
1596 goto err_free_rings
;
1602 rtl8192_free_rx_ring(dev
);
1603 for (i
= 0; i
< MAX_TX_QUEUE_COUNT
; i
++)
1604 if (priv
->tx_ring
[i
].desc
)
1605 rtl8192_free_tx_ring(dev
, i
);
1609 static void rtl8192_pci_resetdescring(struct net_device
*dev
)
1611 struct r8192_priv
*priv
= ieee80211_priv(dev
);
1614 /* force the rx_idx to the first one */
1616 rx_desc_819x_pci
*entry
= NULL
;
1617 for (i
= 0; i
< priv
->rxringcount
; i
++) {
1618 entry
= &priv
->rx_ring
[i
];
1624 /* after reset, release previous pending packet, and force the
1625 * tx idx to the first one */
1626 for (i
= 0; i
< MAX_TX_QUEUE_COUNT
; i
++) {
1627 if (priv
->tx_ring
[i
].desc
) {
1628 struct rtl8192_tx_ring
*ring
= &priv
->tx_ring
[i
];
1630 while (skb_queue_len(&ring
->queue
)) {
1631 tx_desc_819x_pci
*entry
= &ring
->desc
[ring
->idx
];
1632 struct sk_buff
*skb
= __skb_dequeue(&ring
->queue
);
1634 pci_unmap_single(priv
->pdev
, le32_to_cpu(entry
->TxBuffAddr
),
1635 skb
->len
, PCI_DMA_TODEVICE
);
1637 ring
->idx
= (ring
->idx
+ 1) % ring
->entries
;
1644 static void rtl8192_link_change(struct net_device
*dev
)
1646 struct r8192_priv
*priv
= ieee80211_priv(dev
);
1647 struct ieee80211_device
* ieee
= priv
->ieee80211
;
1648 //write_nic_word(dev, BCN_INTR_ITV, net->beacon_interval);
1649 if (ieee
->state
== IEEE80211_LINKED
)
1651 rtl8192_net_update(dev
);
1652 rtl8192_update_ratr_table(dev
);
1654 //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
1655 if ((KEY_TYPE_WEP40
== ieee
->pairwise_key_type
) || (KEY_TYPE_WEP104
== ieee
->pairwise_key_type
))
1656 EnableHWSecurityConfig8192(dev
);
1661 write_nic_byte(dev
, 0x173, 0);
1663 /*update timing params*/
1664 //rtl8192_set_chan(dev, priv->chan);
1666 rtl8192_update_msr(dev
);
1668 // 2007/10/16 MH MAC Will update TSF according to all received beacon, so we have
1669 // // To set CBSSID bit when link with any AP or STA.
1670 if (ieee
->iw_mode
== IW_MODE_INFRA
|| ieee
->iw_mode
== IW_MODE_ADHOC
)
1673 reg
= read_nic_dword(dev
, RCR
);
1674 if (priv
->ieee80211
->state
== IEEE80211_LINKED
)
1675 priv
->ReceiveConfig
= reg
|= RCR_CBSSID
;
1677 priv
->ReceiveConfig
= reg
&= ~RCR_CBSSID
;
1678 write_nic_dword(dev
, RCR
, reg
);
1683 static const struct ieee80211_qos_parameters def_qos_parameters
= {
1684 {3,3,3,3},/* cw_min */
1685 {7,7,7,7},/* cw_max */
1686 {2,2,2,2},/* aifs */
1687 {0,0,0,0},/* flags */
1688 {0,0,0,0} /* tx_op_limit */
1691 static void rtl8192_update_beacon(struct work_struct
* work
)
1693 struct r8192_priv
*priv
= container_of(work
, struct r8192_priv
, update_beacon_wq
.work
);
1694 struct net_device
*dev
= priv
->ieee80211
->dev
;
1695 struct ieee80211_device
* ieee
= priv
->ieee80211
;
1696 struct ieee80211_network
* net
= &ieee
->current_network
;
1698 if (ieee
->pHTInfo
->bCurrentHTSupport
)
1699 HTUpdateSelfAndPeerSetting(ieee
, net
);
1700 ieee
->pHTInfo
->bCurrentRT2RTLongSlotTime
= net
->bssht
.bdRT2RTLongSlotTime
;
1701 rtl8192_update_cap(dev
, net
->capability
);
1705 * background support to run QoS activate functionality
1707 static const int WDCAPARA_ADD
[] = {EDCAPARA_BE
,EDCAPARA_BK
,EDCAPARA_VI
,EDCAPARA_VO
};
1708 static void rtl8192_qos_activate(struct work_struct
* work
)
1710 struct r8192_priv
*priv
= container_of(work
, struct r8192_priv
, qos_activate
);
1711 struct net_device
*dev
= priv
->ieee80211
->dev
;
1712 struct ieee80211_qos_parameters
*qos_parameters
= &priv
->ieee80211
->current_network
.qos_data
.parameters
;
1713 u8 mode
= priv
->ieee80211
->current_network
.mode
;
1718 mutex_lock(&priv
->mutex
);
1719 if(priv
->ieee80211
->state
!= IEEE80211_LINKED
)
1721 RT_TRACE(COMP_QOS
,"qos active process with associate response received\n");
1722 /* It better set slot time at first */
1723 /* For we just support b/g mode at present, let the slot time at 9/20 selection */
1724 /* update the ac parameter to related registers */
1725 for(i
= 0; i
< QOS_QUEUE_NUM
; i
++) {
1726 //Mode G/A: slotTimeTimer = 9; Mode B: 20
1727 u1bAIFS
= qos_parameters
->aifs
[i
] * ((mode
&(IEEE_G
|IEEE_N_24G
)) ?9:20) + aSifsTime
;
1728 u4bAcParam
= ((((u32
)(qos_parameters
->tx_op_limit
[i
]))<< AC_PARAM_TXOP_LIMIT_OFFSET
)|
1729 (((u32
)(qos_parameters
->cw_max
[i
]))<< AC_PARAM_ECW_MAX_OFFSET
)|
1730 (((u32
)(qos_parameters
->cw_min
[i
]))<< AC_PARAM_ECW_MIN_OFFSET
)|
1731 ((u32
)u1bAIFS
<< AC_PARAM_AIFS_OFFSET
));
1732 //printk("===>u4bAcParam:%x, ", u4bAcParam);
1733 write_nic_dword(dev
, WDCAPARA_ADD
[i
], u4bAcParam
);
1734 //write_nic_dword(dev, WDCAPARA_ADD[i], 0x005e4332);
1738 mutex_unlock(&priv
->mutex
);
1741 static int rtl8192_qos_handle_probe_response(struct r8192_priv
*priv
,
1743 struct ieee80211_network
*network
)
1746 u32 size
= sizeof(struct ieee80211_qos_parameters
);
1748 if(priv
->ieee80211
->state
!=IEEE80211_LINKED
)
1751 if ((priv
->ieee80211
->iw_mode
!= IW_MODE_INFRA
))
1754 if (network
->flags
& NETWORK_HAS_QOS_MASK
) {
1755 if (active_network
&&
1756 (network
->flags
& NETWORK_HAS_QOS_PARAMETERS
))
1757 network
->qos_data
.active
= network
->qos_data
.supported
;
1759 if ((network
->qos_data
.active
== 1) && (active_network
== 1) &&
1760 (network
->flags
& NETWORK_HAS_QOS_PARAMETERS
) &&
1761 (network
->qos_data
.old_param_count
!=
1762 network
->qos_data
.param_count
)) {
1763 network
->qos_data
.old_param_count
=
1764 network
->qos_data
.param_count
;
1765 queue_work(priv
->priv_wq
, &priv
->qos_activate
);
1766 RT_TRACE (COMP_QOS
, "QoS parameters change call "
1770 memcpy(&priv
->ieee80211
->current_network
.qos_data
.parameters
,
1771 &def_qos_parameters
, size
);
1773 if ((network
->qos_data
.active
== 1) && (active_network
== 1)) {
1774 queue_work(priv
->priv_wq
, &priv
->qos_activate
);
1775 RT_TRACE(COMP_QOS
, "QoS was disabled call qos_activate \n");
1777 network
->qos_data
.active
= 0;
1778 network
->qos_data
.supported
= 0;
1784 /* handle manage frame frame beacon and probe response */
1785 static int rtl8192_handle_beacon(struct net_device
* dev
,
1786 struct ieee80211_beacon
* beacon
,
1787 struct ieee80211_network
* network
)
1789 struct r8192_priv
*priv
= ieee80211_priv(dev
);
1791 rtl8192_qos_handle_probe_response(priv
,1,network
);
1793 queue_delayed_work(priv
->priv_wq
, &priv
->update_beacon_wq
, 0);
1799 * handling the beaconing responses. if we get different QoS setting
1800 * off the network from the associated setting, adjust the QoS setting
1802 static int rtl8192_qos_association_resp(struct r8192_priv
*priv
,
1803 struct ieee80211_network
*network
)
1806 unsigned long flags
;
1807 u32 size
= sizeof(struct ieee80211_qos_parameters
);
1808 int set_qos_param
= 0;
1810 if ((priv
== NULL
) || (network
== NULL
))
1813 if (priv
->ieee80211
->state
!= IEEE80211_LINKED
)
1816 if ((priv
->ieee80211
->iw_mode
!= IW_MODE_INFRA
))
1819 spin_lock_irqsave(&priv
->ieee80211
->lock
, flags
);
1820 if (network
->flags
& NETWORK_HAS_QOS_PARAMETERS
) {
1821 memcpy(&priv
->ieee80211
->current_network
.qos_data
.parameters
,
1822 &network
->qos_data
.parameters
,
1823 sizeof(struct ieee80211_qos_parameters
));
1824 priv
->ieee80211
->current_network
.qos_data
.active
= 1;
1826 /* update qos parameter for current network */
1827 priv
->ieee80211
->current_network
.qos_data
.old_param_count
=
1828 priv
->ieee80211
->current_network
.qos_data
.param_count
;
1829 priv
->ieee80211
->current_network
.qos_data
.param_count
=
1830 network
->qos_data
.param_count
;
1833 memcpy(&priv
->ieee80211
->current_network
.qos_data
.parameters
,
1834 &def_qos_parameters
, size
);
1835 priv
->ieee80211
->current_network
.qos_data
.active
= 0;
1836 priv
->ieee80211
->current_network
.qos_data
.supported
= 0;
1840 spin_unlock_irqrestore(&priv
->ieee80211
->lock
, flags
);
1842 RT_TRACE(COMP_QOS
, "%s: network->flags = %d,%d\n", __FUNCTION__
,
1843 network
->flags
, priv
->ieee80211
->current_network
.qos_data
.active
);
1844 if (set_qos_param
== 1)
1845 queue_work(priv
->priv_wq
, &priv
->qos_activate
);
1851 static int rtl8192_handle_assoc_response(struct net_device
*dev
,
1852 struct ieee80211_assoc_response_frame
*resp
,
1853 struct ieee80211_network
*network
)
1855 struct r8192_priv
*priv
= ieee80211_priv(dev
);
1856 rtl8192_qos_association_resp(priv
, network
);
1861 /* updateRATRTabel for MCS only. Basic rate is not implemented. */
1862 static void rtl8192_update_ratr_table(struct net_device
* dev
)
1864 struct r8192_priv
* priv
= ieee80211_priv(dev
);
1865 struct ieee80211_device
* ieee
= priv
->ieee80211
;
1866 u8
* pMcsRate
= ieee
->dot11HTOperationalRateSet
;
1870 rtl8192_config_rate(dev
, (u16
*)(&ratr_value
));
1871 ratr_value
|= (*(u16
*)(pMcsRate
)) << 12;
1876 ratr_value
&= 0x00000FF0;
1879 ratr_value
&= 0x0000000F;
1882 ratr_value
&= 0x00000FF7;
1886 if (ieee
->pHTInfo
->PeerMimoPs
== 0) //MIMO_PS_STATIC
1887 ratr_value
&= 0x0007F007;
1889 if (priv
->rf_type
== RF_1T2R
)
1890 ratr_value
&= 0x000FF007;
1892 ratr_value
&= 0x0F81F007;
1898 ratr_value
&= 0x0FFFFFFF;
1899 if(ieee
->pHTInfo
->bCurTxBW40MHz
&& ieee
->pHTInfo
->bCurShortGI40MHz
){
1900 ratr_value
|= 0x80000000;
1901 }else if(!ieee
->pHTInfo
->bCurTxBW40MHz
&& ieee
->pHTInfo
->bCurShortGI20MHz
){
1902 ratr_value
|= 0x80000000;
1904 write_nic_dword(dev
, RATR0
+rate_index
*4, ratr_value
);
1905 write_nic_byte(dev
, UFWP
, 1);
1908 static bool GetNmodeSupportBySecCfg8190Pci(struct net_device
*dev
)
1910 struct r8192_priv
*priv
= ieee80211_priv(dev
);
1911 struct ieee80211_device
*ieee
= priv
->ieee80211
;
1913 return !(ieee
->rtllib_ap_sec_type
&&
1914 (ieee
->rtllib_ap_sec_type(ieee
)&(SEC_ALG_WEP
|SEC_ALG_TKIP
)));
1917 static void rtl8192_refresh_supportrate(struct r8192_priv
* priv
)
1919 struct ieee80211_device
* ieee
= priv
->ieee80211
;
1920 //we donot consider set support rate for ABG mode, only HT MCS rate is set here.
1921 if (ieee
->mode
== WIRELESS_MODE_N_24G
|| ieee
->mode
== WIRELESS_MODE_N_5G
)
1923 memcpy(ieee
->Regdot11HTOperationalRateSet
, ieee
->RegHTSuppRateSet
, 16);
1926 memset(ieee
->Regdot11HTOperationalRateSet
, 0, 16);
1929 static u8
rtl8192_getSupportedWireleeMode(struct net_device
*dev
)
1931 struct r8192_priv
*priv
= ieee80211_priv(dev
);
1933 switch(priv
->rf_chip
)
1938 ret
= (WIRELESS_MODE_N_24G
|WIRELESS_MODE_G
|WIRELESS_MODE_B
);
1941 ret
= (WIRELESS_MODE_A
|WIRELESS_MODE_N_5G
);
1944 ret
= WIRELESS_MODE_B
;
1950 static void rtl8192_SetWirelessMode(struct net_device
* dev
, u8 wireless_mode
)
1952 struct r8192_priv
*priv
= ieee80211_priv(dev
);
1953 u8 bSupportMode
= rtl8192_getSupportedWireleeMode(dev
);
1955 if ((wireless_mode
== WIRELESS_MODE_AUTO
) || ((wireless_mode
&bSupportMode
)==0))
1957 if(bSupportMode
& WIRELESS_MODE_N_24G
)
1959 wireless_mode
= WIRELESS_MODE_N_24G
;
1961 else if(bSupportMode
& WIRELESS_MODE_N_5G
)
1963 wireless_mode
= WIRELESS_MODE_N_5G
;
1965 else if((bSupportMode
& WIRELESS_MODE_A
))
1967 wireless_mode
= WIRELESS_MODE_A
;
1969 else if((bSupportMode
& WIRELESS_MODE_G
))
1971 wireless_mode
= WIRELESS_MODE_G
;
1973 else if((bSupportMode
& WIRELESS_MODE_B
))
1975 wireless_mode
= WIRELESS_MODE_B
;
1978 RT_TRACE(COMP_ERR
, "%s(), No valid wireless mode supported, SupportedWirelessMode(%x)!!!\n", __FUNCTION__
,bSupportMode
);
1979 wireless_mode
= WIRELESS_MODE_B
;
1982 priv
->ieee80211
->mode
= wireless_mode
;
1984 if ((wireless_mode
== WIRELESS_MODE_N_24G
) || (wireless_mode
== WIRELESS_MODE_N_5G
))
1985 priv
->ieee80211
->pHTInfo
->bEnableHT
= 1;
1987 priv
->ieee80211
->pHTInfo
->bEnableHT
= 0;
1988 RT_TRACE(COMP_INIT
, "Current Wireless Mode is %x\n", wireless_mode
);
1989 rtl8192_refresh_supportrate(priv
);
1992 static bool GetHalfNmodeSupportByAPs819xPci(struct net_device
* dev
)
1994 struct r8192_priv
* priv
= ieee80211_priv(dev
);
1995 struct ieee80211_device
* ieee
= priv
->ieee80211
;
1997 return ieee
->bHalfWirelessN24GMode
;
2000 short rtl8192_is_tx_queue_empty(struct net_device
*dev
)
2003 struct r8192_priv
*priv
= ieee80211_priv(dev
);
2004 for (i
=0; i
<=MGNT_QUEUE
; i
++)
2006 if ((i
== TXCMD_QUEUE
) || (i
== HCCA_QUEUE
) )
2008 if (skb_queue_len(&(&priv
->tx_ring
[i
])->queue
) > 0){
2009 printk("===>tx queue is not empty:%d, %d\n", i
, skb_queue_len(&(&priv
->tx_ring
[i
])->queue
));
2016 static void rtl8192_hw_sleep_down(struct net_device
*dev
)
2018 struct r8192_priv
*priv
= ieee80211_priv(dev
);
2019 unsigned long flags
= 0;
2021 spin_lock_irqsave(&priv
->rf_ps_lock
,flags
);
2022 if (priv
->RFChangeInProgress
) {
2023 spin_unlock_irqrestore(&priv
->rf_ps_lock
,flags
);
2024 RT_TRACE(COMP_RF
, "rtl8192_hw_sleep_down(): RF Change in progress! \n");
2025 printk("rtl8192_hw_sleep_down(): RF Change in progress!\n");
2028 spin_unlock_irqrestore(&priv
->rf_ps_lock
,flags
);
2030 MgntActSet_RF_State(dev
, eRfSleep
, RF_CHANGE_BY_PS
);
2033 static void rtl8192_hw_sleep_wq (struct work_struct
*work
)
2035 struct delayed_work
*dwork
= container_of(work
,struct delayed_work
,work
);
2036 struct ieee80211_device
*ieee
= container_of(dwork
,struct ieee80211_device
,hw_sleep_wq
);
2037 struct net_device
*dev
= ieee
->dev
;
2039 rtl8192_hw_sleep_down(dev
);
2042 static void rtl8192_hw_wakeup(struct net_device
* dev
)
2044 struct r8192_priv
*priv
= ieee80211_priv(dev
);
2045 unsigned long flags
= 0;
2047 spin_lock_irqsave(&priv
->rf_ps_lock
,flags
);
2048 if (priv
->RFChangeInProgress
) {
2049 spin_unlock_irqrestore(&priv
->rf_ps_lock
,flags
);
2050 RT_TRACE(COMP_RF
, "rtl8192_hw_wakeup(): RF Change in progress! \n");
2051 printk("rtl8192_hw_wakeup(): RF Change in progress! schedule wake up task again\n");
2052 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
2055 spin_unlock_irqrestore(&priv
->rf_ps_lock
,flags
);
2057 MgntActSet_RF_State(dev
, eRfOn
, RF_CHANGE_BY_PS
);
2060 void rtl8192_hw_wakeup_wq (struct work_struct
*work
)
2062 struct delayed_work
*dwork
= container_of(work
,struct delayed_work
,work
);
2063 struct ieee80211_device
*ieee
= container_of(dwork
,struct ieee80211_device
,hw_wakeup_wq
);
2064 struct net_device
*dev
= ieee
->dev
;
2065 rtl8192_hw_wakeup(dev
);
2069 #define MIN_SLEEP_TIME 50
2070 #define MAX_SLEEP_TIME 10000
2071 static void rtl8192_hw_to_sleep(struct net_device
*dev
, u32 th
, u32 tl
)
2073 struct r8192_priv
*priv
= ieee80211_priv(dev
);
2076 unsigned long flags
;
2078 spin_lock_irqsave(&priv
->ps_lock
,flags
);
2080 // Writing HW register with 0 equals to disable
2081 // the timer, that is not really what we want
2083 tl
-= MSECS(8+16+7);
2085 // If the interval in witch we are requested to sleep is too
2086 // short then give up and remain awake
2087 // when we sleep after send null frame, the timer will be too short to sleep.
2089 if(((tl
>=rb
)&& (tl
-rb
) <= MSECS(MIN_SLEEP_TIME
))
2090 ||((rb
>tl
)&& (rb
-tl
) < MSECS(MIN_SLEEP_TIME
))) {
2091 spin_unlock_irqrestore(&priv
->ps_lock
,flags
);
2092 printk("too short to sleep::%x, %x, %lx\n",tl
, rb
, MSECS(MIN_SLEEP_TIME
));
2096 if(((tl
> rb
) && ((tl
-rb
) > MSECS(MAX_SLEEP_TIME
)))||
2097 ((tl
< rb
) && (tl
>MSECS(69)) && ((rb
-tl
) > MSECS(MAX_SLEEP_TIME
)))||
2098 ((tl
<rb
)&&(tl
<MSECS(69))&&((tl
+0xffffffff-rb
)>MSECS(MAX_SLEEP_TIME
)))) {
2099 printk("========>too long to sleep:%x, %x, %lx\n", tl
, rb
, MSECS(MAX_SLEEP_TIME
));
2100 spin_unlock_irqrestore(&priv
->ps_lock
,flags
);
2104 u32 tmp
= (tl
>rb
)?(tl
-rb
):(rb
-tl
);
2105 queue_delayed_work(priv
->ieee80211
->wq
,
2106 &priv
->ieee80211
->hw_wakeup_wq
,tmp
);
2107 //PowerSave not supported when kernel version less 2.6.20
2109 queue_delayed_work(priv
->ieee80211
->wq
,
2110 (void *)&priv
->ieee80211
->hw_sleep_wq
,0);
2111 spin_unlock_irqrestore(&priv
->ps_lock
,flags
);
2115 static void rtl8192_init_priv_variable(struct net_device
* dev
)
2117 struct r8192_priv
*priv
= ieee80211_priv(dev
);
2119 PRT_POWER_SAVE_CONTROL pPSC
= (PRT_POWER_SAVE_CONTROL
)(&(priv
->ieee80211
->PowerSaveControl
));
2121 // Default Halt the NIC if RF is OFF.
2122 pPSC
->RegRfPsLevel
|= RT_RF_OFF_LEVL_HALT_NIC
;
2123 pPSC
->RegRfPsLevel
|= RT_RF_OFF_LEVL_CLK_REQ
;
2124 pPSC
->RegRfPsLevel
|= RT_RF_OFF_LEVL_ASPM
;
2125 pPSC
->RegRfPsLevel
|= RT_RF_LPS_LEVEL_ASPM
;
2126 pPSC
->bLeisurePs
= true;
2127 pPSC
->RegMaxLPSAwakeIntvl
= 5;
2128 priv
->bHwRadioOff
= false;
2130 priv
->being_init_adapter
= false;
2131 priv
->txringcount
= 64;//32;
2132 priv
->rxbuffersize
= 9100;//2048;//1024;
2133 priv
->rxringcount
= MAX_RX_COUNT
;//64;
2134 priv
->irq_enabled
=0;
2135 priv
->card_8192
= NIC_8192E
;
2136 priv
->rx_skb_complete
= 1;
2137 priv
->chan
= 1; //set to channel 1
2138 priv
->RegWirelessMode
= WIRELESS_MODE_AUTO
;
2139 priv
->RegChannelPlan
= 0xf;
2140 priv
->nrxAMPDU_size
= 0;
2141 priv
->nrxAMPDU_aggr_num
= 0;
2142 priv
->last_rxdesc_tsf_high
= 0;
2143 priv
->last_rxdesc_tsf_low
= 0;
2144 priv
->ieee80211
->mode
= WIRELESS_MODE_AUTO
; //SET AUTO
2145 priv
->ieee80211
->iw_mode
= IW_MODE_INFRA
;
2146 priv
->ieee80211
->ieee_up
=0;
2147 priv
->retry_rts
= DEFAULT_RETRY_RTS
;
2148 priv
->retry_data
= DEFAULT_RETRY_DATA
;
2149 priv
->ieee80211
->rts
= DEFAULT_RTS_THRESHOLD
;
2150 priv
->ieee80211
->rate
= 110; //11 mbps
2151 priv
->ieee80211
->short_slot
= 1;
2152 priv
->promisc
= (dev
->flags
& IFF_PROMISC
) ? 1:0;
2153 priv
->bcck_in_ch14
= false;
2154 priv
->bfsync_processing
= false;
2155 priv
->CCKPresentAttentuation
= 0;
2156 priv
->rfa_txpowertrackingindex
= 0;
2157 priv
->rfc_txpowertrackingindex
= 0;
2159 //added by amy for silent reset
2160 priv
->ResetProgress
= RESET_TYPE_NORESET
;
2161 priv
->bForcedSilentReset
= 0;
2162 priv
->bDisableNormalResetCheck
= false;
2163 priv
->force_reset
= false;
2164 //added by amy for power save
2165 priv
->ieee80211
->RfOffReason
= 0;
2166 priv
->RFChangeInProgress
= false;
2167 priv
->bHwRfOffAction
= 0;
2168 priv
->SetRFPowerStateInProgress
= false;
2169 priv
->ieee80211
->PowerSaveControl
.bInactivePs
= true;
2170 priv
->ieee80211
->PowerSaveControl
.bIPSModeBackup
= false;
2172 priv
->txpower_checkcnt
= 0;
2173 priv
->thermal_readback_index
=0;
2174 priv
->txpower_tracking_callback_cnt
= 0;
2175 priv
->ccktxpower_adjustcnt_ch14
= 0;
2176 priv
->ccktxpower_adjustcnt_not_ch14
= 0;
2178 priv
->ieee80211
->current_network
.beacon_interval
= DEFAULT_BEACONINTERVAL
;
2179 priv
->ieee80211
->iw_mode
= IW_MODE_INFRA
;
2180 priv
->ieee80211
->softmac_features
= IEEE_SOFTMAC_SCAN
|
2181 IEEE_SOFTMAC_ASSOCIATE
| IEEE_SOFTMAC_PROBERQ
|
2182 IEEE_SOFTMAC_PROBERS
| IEEE_SOFTMAC_TX_QUEUE
;/* |
2183 IEEE_SOFTMAC_BEACONS;*///added by amy
080604 //| //IEEE_SOFTMAC_SINGLE_QUEUE;
2185 priv
->ieee80211
->active_scan
= 1;
2186 priv
->ieee80211
->modulation
= IEEE80211_CCK_MODULATION
| IEEE80211_OFDM_MODULATION
;
2187 priv
->ieee80211
->host_encrypt
= 1;
2188 priv
->ieee80211
->host_decrypt
= 1;
2189 //priv->ieee80211->start_send_beacons = NULL;//rtl819xusb_beacon_tx;//-by amy 080604
2190 //priv->ieee80211->stop_send_beacons = NULL;//rtl8192_beacon_stop;//-by amy 080604
2191 priv
->ieee80211
->start_send_beacons
= rtl8192_start_beacon
;//+by david 081107
2192 priv
->ieee80211
->stop_send_beacons
= rtl8192_stop_beacon
;//+by david 081107
2193 priv
->ieee80211
->softmac_hard_start_xmit
= rtl8192_hard_start_xmit
;
2194 priv
->ieee80211
->set_chan
= rtl8192_set_chan
;
2195 priv
->ieee80211
->link_change
= rtl8192_link_change
;
2196 priv
->ieee80211
->softmac_data_hard_start_xmit
= rtl8192_hard_data_xmit
;
2197 priv
->ieee80211
->data_hard_stop
= rtl8192_data_hard_stop
;
2198 priv
->ieee80211
->data_hard_resume
= rtl8192_data_hard_resume
;
2199 priv
->ieee80211
->init_wmmparam_flag
= 0;
2200 priv
->ieee80211
->fts
= DEFAULT_FRAG_THRESHOLD
;
2201 priv
->ieee80211
->check_nic_enough_desc
= check_nic_enough_desc
;
2202 priv
->ieee80211
->tx_headroom
= sizeof(TX_FWINFO_8190PCI
);
2203 priv
->ieee80211
->qos_support
= 1;
2204 priv
->ieee80211
->dot11PowerSaveMode
= 0;
2206 // priv->ieee80211->SwChnlByTimerHandler = rtl8192_phy_SwChnl;
2207 priv
->ieee80211
->SetBWModeHandler
= rtl8192_SetBWMode
;
2208 priv
->ieee80211
->handle_assoc_response
= rtl8192_handle_assoc_response
;
2209 priv
->ieee80211
->handle_beacon
= rtl8192_handle_beacon
;
2211 priv
->ieee80211
->sta_wake_up
= rtl8192_hw_wakeup
;
2212 // priv->ieee80211->ps_request_tx_ack = rtl8192_rq_tx_ack;
2213 priv
->ieee80211
->enter_sleep_state
= rtl8192_hw_to_sleep
;
2214 priv
->ieee80211
->ps_is_queue_empty
= rtl8192_is_tx_queue_empty
;
2216 priv
->ieee80211
->GetNmodeSupportBySecCfg
= GetNmodeSupportBySecCfg8190Pci
;
2217 priv
->ieee80211
->SetWirelessMode
= rtl8192_SetWirelessMode
;
2218 priv
->ieee80211
->GetHalfNmodeSupportByAPsHandler
= GetHalfNmodeSupportByAPs819xPci
;
2221 priv
->ieee80211
->InitialGainHandler
= InitialGain819xPci
;
2224 priv
->ieee80211
->ieee80211_ips_leave_wq
= ieee80211_ips_leave_wq
;
2225 priv
->ieee80211
->ieee80211_ips_leave
= ieee80211_ips_leave
;
2228 priv
->ieee80211
->LeisurePSLeave
= LeisurePSLeave
;
2231 priv
->ieee80211
->SetHwRegHandler
= rtl8192e_SetHwReg
;
2232 priv
->ieee80211
->rtllib_ap_sec_type
= rtl8192e_ap_sec_type
;
2234 priv
->ShortRetryLimit
= 0x30;
2235 priv
->LongRetryLimit
= 0x30;
2237 priv
->ReceiveConfig
= RCR_ADD3
|
2238 RCR_AMF
| RCR_ADF
| //accept management/data
2239 RCR_AICV
| //accept control frame for SW AP needs PS-poll, 2005.07.07, by rcnjko.
2240 RCR_AB
| RCR_AM
| RCR_APM
| //accept BC/MC/UC
2241 RCR_AAP
| ((u32
)7<<RCR_MXDMA_OFFSET
) |
2242 ((u32
)7 << RCR_FIFO_OFFSET
) | RCR_ONLYERLPKT
;
2244 priv
->irq_mask
= (u32
)(IMR_ROK
| IMR_VODOK
| IMR_VIDOK
| IMR_BEDOK
| IMR_BKDOK
|
2245 IMR_HCCADOK
| IMR_MGNTDOK
| IMR_COMDOK
| IMR_HIGHDOK
|
2246 IMR_BDOK
| IMR_RXCMDOK
| IMR_TIMEOUT0
| IMR_RDU
| IMR_RXFOVW
|
2247 IMR_TXFOVW
| IMR_BcnInt
| IMR_TBDOK
| IMR_TBDER
);
2249 priv
->pFirmware
= vzalloc(sizeof(rt_firmware
));
2251 /* rx related queue */
2252 skb_queue_head_init(&priv
->skb_queue
);
2254 /* Tx related queue */
2255 for(i
= 0; i
< MAX_QUEUE_SIZE
; i
++) {
2256 skb_queue_head_init(&priv
->ieee80211
->skb_waitQ
[i
]);
2258 for(i
= 0; i
< MAX_QUEUE_SIZE
; i
++) {
2259 skb_queue_head_init(&priv
->ieee80211
->skb_aggQ
[i
]);
2261 priv
->rf_set_chan
= rtl8192_phy_SwChnl
;
2264 static void rtl8192_init_priv_lock(struct r8192_priv
* priv
)
2266 spin_lock_init(&priv
->tx_lock
);
2267 spin_lock_init(&priv
->irq_th_lock
);
2268 spin_lock_init(&priv
->rf_ps_lock
);
2269 spin_lock_init(&priv
->ps_lock
);
2270 sema_init(&priv
->wx_sem
,1);
2271 sema_init(&priv
->rf_sem
,1);
2272 mutex_init(&priv
->mutex
);
2275 /* init tasklet and wait_queue here */
2276 #define DRV_NAME "wlan0"
2277 static void rtl8192_init_priv_task(struct net_device
* dev
)
2279 struct r8192_priv
*priv
= ieee80211_priv(dev
);
2281 #ifdef PF_SYNCTHREAD
2282 priv
->priv_wq
= create_workqueue(DRV_NAME
,0);
2284 priv
->priv_wq
= create_workqueue(DRV_NAME
);
2288 INIT_WORK(&priv
->ieee80211
->ips_leave_wq
, (void*)IPSLeave_wq
);
2291 // INIT_WORK(&priv->reset_wq, (void(*)(void*)) rtl8192_restart);
2292 INIT_WORK(&priv
->reset_wq
, rtl8192_restart
);
2293 // INIT_DELAYED_WORK(&priv->watch_dog_wq, hal_dm_watchdog);
2294 INIT_DELAYED_WORK(&priv
->watch_dog_wq
, rtl819x_watchdog_wqcallback
);
2295 INIT_DELAYED_WORK(&priv
->txpower_tracking_wq
, dm_txpower_trackingcallback
);
2296 INIT_DELAYED_WORK(&priv
->rfpath_check_wq
, dm_rf_pathcheck_workitemcallback
);
2297 INIT_DELAYED_WORK(&priv
->update_beacon_wq
, rtl8192_update_beacon
);
2298 //INIT_WORK(&priv->SwChnlWorkItem, rtl8192_SwChnl_WorkItem);
2299 //INIT_WORK(&priv->SetBWModeWorkItem, rtl8192_SetBWModeWorkItem);
2300 INIT_WORK(&priv
->qos_activate
, rtl8192_qos_activate
);
2301 INIT_DELAYED_WORK(&priv
->ieee80211
->hw_wakeup_wq
,(void*) rtl8192_hw_wakeup_wq
);
2302 INIT_DELAYED_WORK(&priv
->ieee80211
->hw_sleep_wq
,(void*) rtl8192_hw_sleep_wq
);
2304 tasklet_init(&priv
->irq_rx_tasklet
,
2305 (void(*)(unsigned long))rtl8192_irq_rx_tasklet
,
2306 (unsigned long)priv
);
2307 tasklet_init(&priv
->irq_tx_tasklet
,
2308 (void(*)(unsigned long))rtl8192_irq_tx_tasklet
,
2309 (unsigned long)priv
);
2310 tasklet_init(&priv
->irq_prepare_beacon_tasklet
,
2311 (void(*)(unsigned long))rtl8192_prepare_beacon
,
2312 (unsigned long)priv
);
2315 static void rtl8192_get_eeprom_size(struct net_device
* dev
)
2318 struct r8192_priv
*priv
= ieee80211_priv(dev
);
2319 RT_TRACE(COMP_INIT
, "===========>%s()\n", __FUNCTION__
);
2320 curCR
= read_nic_dword(dev
, EPROM_CMD
);
2321 RT_TRACE(COMP_INIT
, "read from Reg Cmd9346CR(%x):%x\n", EPROM_CMD
, curCR
);
2322 //whether need I consider BIT5?
2323 priv
->epromtype
= (curCR
& EPROM_CMD_9356SEL
) ? EPROM_93c56
: EPROM_93c46
;
2324 RT_TRACE(COMP_INIT
, "<===========%s(), epromtype:%d\n", __FUNCTION__
, priv
->epromtype
);
2328 * used to swap endian. as ntohl & htonl are not
2329 * neccessary to swap endian, so use this instead.
2331 static inline u16
endian_swap(u16
* data
)
2334 *data
= (tmp
>> 8) | (tmp
<< 8);
2339 * Adapter->EEPROMAddressSize should be set before this function call.
2340 * EEPROM address size can be got through GetEEPROMSize8185()
2342 static void rtl8192_read_eeprom_info(struct net_device
* dev
)
2344 struct r8192_priv
*priv
= ieee80211_priv(dev
);
2348 u8 ICVer8192
, ICVer8256
;
2350 u16 i
,usValue
, IC_Version
;
2354 u8 EepromTxPower
[100];
2356 u8 bMac_Tmp_Addr
[6] = {0x00, 0xe0, 0x4c, 0x00, 0x00, 0x01};
2357 RT_TRACE(COMP_INIT
, "====> rtl8192_read_eeprom_info\n");
2360 // TODO: I don't know if we need to apply EF function to EEPROM read function
2362 //2 Read EEPROM ID to make sure autoload is success
2363 EEPROMId
= eprom_read(dev
, 0);
2364 if( EEPROMId
!= RTL8190_EEPROM_ID
)
2366 RT_TRACE(COMP_ERR
, "EEPROM ID is invalid:%x, %x\n", EEPROMId
, RTL8190_EEPROM_ID
);
2367 priv
->AutoloadFailFlag
=true;
2371 priv
->AutoloadFailFlag
=false;
2375 // Assign Chip Version ID
2377 // Read IC Version && Channel Plan
2378 if(!priv
->AutoloadFailFlag
)
2381 priv
->eeprom_vid
= eprom_read(dev
, (EEPROM_VID
>> 1));
2382 priv
->eeprom_did
= eprom_read(dev
, (EEPROM_DID
>> 1));
2384 usValue
= eprom_read(dev
, (u16
)(EEPROM_Customer_ID
>>1)) >> 8 ;
2385 priv
->eeprom_CustomerID
= (u8
)( usValue
& 0xff);
2386 usValue
= eprom_read(dev
, (EEPROM_ICVersion_ChannelPlan
>>1));
2387 priv
->eeprom_ChannelPlan
= usValue
&0xff;
2388 IC_Version
= ((usValue
&0xff00)>>8);
2391 priv
->card_8192_version
= (VERSION_8190
)(IC_Version
);
2394 ICVer8192
= (IC_Version
&0xf); //bit0~3; 1:A cut, 2:B cut, 3:C cut...
2395 ICVer8256
= ((IC_Version
&0xf0)>>4);//bit4~6, bit7 reserved for other RF chip; 1:A cut, 2:B cut, 3:C cut...
2396 RT_TRACE(COMP_INIT
, "\nICVer8192 = 0x%x\n", ICVer8192
);
2397 RT_TRACE(COMP_INIT
, "\nICVer8256 = 0x%x\n", ICVer8256
);
2398 if(ICVer8192
== 0x2) //B-cut
2400 if(ICVer8256
== 0x5) //E-cut
2401 priv
->card_8192_version
= VERSION_8190_BE
;
2405 switch(priv
->card_8192_version
)
2407 case VERSION_8190_BD
:
2408 case VERSION_8190_BE
:
2411 priv
->card_8192_version
= VERSION_8190_BD
;
2414 RT_TRACE(COMP_INIT
, "\nIC Version = 0x%x\n", priv
->card_8192_version
);
2418 priv
->card_8192_version
= VERSION_8190_BD
;
2419 priv
->eeprom_vid
= 0;
2420 priv
->eeprom_did
= 0;
2421 priv
->eeprom_CustomerID
= 0;
2422 priv
->eeprom_ChannelPlan
= 0;
2423 RT_TRACE(COMP_INIT
, "\nIC Version = 0x%x\n", 0xff);
2426 RT_TRACE(COMP_INIT
, "EEPROM VID = 0x%4x\n", priv
->eeprom_vid
);
2427 RT_TRACE(COMP_INIT
, "EEPROM DID = 0x%4x\n", priv
->eeprom_did
);
2428 RT_TRACE(COMP_INIT
,"EEPROM Customer ID: 0x%2x\n", priv
->eeprom_CustomerID
);
2430 //2 Read Permanent MAC address
2431 if(!priv
->AutoloadFailFlag
)
2433 for(i
= 0; i
< 6; i
+= 2)
2435 usValue
= eprom_read(dev
, (u16
) ((EEPROM_NODE_ADDRESS_BYTE_0
+i
)>>1));
2436 *(u16
*)(&dev
->dev_addr
[i
]) = usValue
;
2439 // when auto load failed, the last address byte set to be a random one.
2440 // added by david woo.2007/11/7
2441 memcpy(dev
->dev_addr
, bMac_Tmp_Addr
, 6);
2444 RT_TRACE(COMP_INIT
, "Permanent Address = %pM\n", dev
->dev_addr
);
2446 //2 TX Power Check EEPROM Fail or not
2447 if(priv
->card_8192_version
> VERSION_8190_BD
) {
2448 priv
->bTXPowerDataReadFromEEPORM
= true;
2450 priv
->bTXPowerDataReadFromEEPORM
= false;
2453 // 2007/11/15 MH 8190PCI Default=2T4R, 8192PCIE default=1T2R
2454 priv
->rf_type
= RTL819X_DEFAULT_RF_TYPE
;
2456 if(priv
->card_8192_version
> VERSION_8190_BD
)
2458 // Read RF-indication and Tx Power gain index diff of legacy to HT OFDM rate.
2459 if(!priv
->AutoloadFailFlag
)
2461 tempval
= (eprom_read(dev
, (EEPROM_RFInd_PowerDiff
>>1))) & 0xff;
2462 priv
->EEPROMLegacyHTTxPowerDiff
= tempval
& 0xf; // bit[3:0]
2464 if (tempval
&0x80) //RF-indication, bit[7]
2465 priv
->rf_type
= RF_1T2R
;
2467 priv
->rf_type
= RF_2T4R
;
2471 priv
->EEPROMLegacyHTTxPowerDiff
= EEPROM_Default_LegacyHTTxPowerDiff
;
2473 RT_TRACE(COMP_INIT
, "EEPROMLegacyHTTxPowerDiff = %d\n",
2474 priv
->EEPROMLegacyHTTxPowerDiff
);
2476 // Read ThermalMeter from EEPROM
2477 if(!priv
->AutoloadFailFlag
)
2479 priv
->EEPROMThermalMeter
= (u8
)(((eprom_read(dev
, (EEPROM_ThermalMeter
>>1))) & 0xff00)>>8);
2483 priv
->EEPROMThermalMeter
= EEPROM_Default_ThermalMeter
;
2485 RT_TRACE(COMP_INIT
, "ThermalMeter = %d\n", priv
->EEPROMThermalMeter
);
2486 //vivi, for tx power track
2487 priv
->TSSI_13dBm
= priv
->EEPROMThermalMeter
*100;
2489 if(priv
->epromtype
== EPROM_93c46
)
2491 // Read antenna tx power offset of B/C/D to A and CrystalCap from EEPROM
2492 if(!priv
->AutoloadFailFlag
)
2494 usValue
= eprom_read(dev
, (EEPROM_TxPwDiff_CrystalCap
>>1));
2495 priv
->EEPROMAntPwDiff
= (usValue
&0x0fff);
2496 priv
->EEPROMCrystalCap
= (u8
)((usValue
&0xf000)>>12);
2500 priv
->EEPROMAntPwDiff
= EEPROM_Default_AntTxPowerDiff
;
2501 priv
->EEPROMCrystalCap
= EEPROM_Default_TxPwDiff_CrystalCap
;
2503 RT_TRACE(COMP_INIT
, "EEPROMAntPwDiff = %d\n", priv
->EEPROMAntPwDiff
);
2504 RT_TRACE(COMP_INIT
, "EEPROMCrystalCap = %d\n", priv
->EEPROMCrystalCap
);
2507 // Get per-channel Tx Power Level
2509 for(i
=0; i
<14; i
+=2)
2511 if(!priv
->AutoloadFailFlag
)
2513 usValue
= eprom_read(dev
, (u16
) ((EEPROM_TxPwIndex_CCK
+i
)>>1) );
2517 usValue
= EEPROM_Default_TxPower
;
2519 *((u16
*)(&priv
->EEPROMTxPowerLevelCCK
[i
])) = usValue
;
2520 RT_TRACE(COMP_INIT
,"CCK Tx Power Level, Index %d = 0x%02x\n", i
, priv
->EEPROMTxPowerLevelCCK
[i
]);
2521 RT_TRACE(COMP_INIT
, "CCK Tx Power Level, Index %d = 0x%02x\n", i
+1, priv
->EEPROMTxPowerLevelCCK
[i
+1]);
2523 for(i
=0; i
<14; i
+=2)
2525 if(!priv
->AutoloadFailFlag
)
2527 usValue
= eprom_read(dev
, (u16
) ((EEPROM_TxPwIndex_OFDM_24G
+i
)>>1) );
2531 usValue
= EEPROM_Default_TxPower
;
2533 *((u16
*)(&priv
->EEPROMTxPowerLevelOFDM24G
[i
])) = usValue
;
2534 RT_TRACE(COMP_INIT
, "OFDM 2.4G Tx Power Level, Index %d = 0x%02x\n", i
, priv
->EEPROMTxPowerLevelOFDM24G
[i
]);
2535 RT_TRACE(COMP_INIT
, "OFDM 2.4G Tx Power Level, Index %d = 0x%02x\n", i
+1, priv
->EEPROMTxPowerLevelOFDM24G
[i
+1]);
2538 else if(priv
->epromtype
== EPROM_93c56
)
2541 // Read CrystalCap from EEPROM
2542 if(!priv
->AutoloadFailFlag
)
2544 priv
->EEPROMAntPwDiff
= EEPROM_Default_AntTxPowerDiff
;
2545 priv
->EEPROMCrystalCap
= (u8
)(((eprom_read(dev
, (EEPROM_C56_CrystalCap
>>1))) & 0xf000)>>12);
2549 priv
->EEPROMAntPwDiff
= EEPROM_Default_AntTxPowerDiff
;
2550 priv
->EEPROMCrystalCap
= EEPROM_Default_TxPwDiff_CrystalCap
;
2552 RT_TRACE(COMP_INIT
,"EEPROMAntPwDiff = %d\n", priv
->EEPROMAntPwDiff
);
2553 RT_TRACE(COMP_INIT
, "EEPROMCrystalCap = %d\n", priv
->EEPROMCrystalCap
);
2555 // Get Tx Power Level by Channel
2556 if(!priv
->AutoloadFailFlag
)
2558 // Read Tx power of Channel 1 ~ 14 from EEPROM.
2559 for(i
= 0; i
< 12; i
+=2)
2562 offset
= EEPROM_C56_RfA_CCK_Chnl1_TxPwIndex
+ i
;
2564 offset
= EEPROM_C56_RfC_CCK_Chnl1_TxPwIndex
+ i
- 6;
2565 usValue
= eprom_read(dev
, (offset
>>1));
2566 *((u16
*)(&EepromTxPower
[i
])) = usValue
;
2569 for(i
= 0; i
< 12; i
++)
2572 priv
->EEPROMRfACCKChnl1TxPwLevel
[i
] = EepromTxPower
[i
];
2573 else if ((i
>=3 )&&(i
<= 5))
2574 priv
->EEPROMRfAOfdmChnlTxPwLevel
[i
-3] = EepromTxPower
[i
];
2575 else if ((i
>=6 )&&(i
<= 8))
2576 priv
->EEPROMRfCCCKChnl1TxPwLevel
[i
-6] = EepromTxPower
[i
];
2578 priv
->EEPROMRfCOfdmChnlTxPwLevel
[i
-9] = EepromTxPower
[i
];
2583 priv
->EEPROMRfACCKChnl1TxPwLevel
[0] = EEPROM_Default_TxPowerLevel
;
2584 priv
->EEPROMRfACCKChnl1TxPwLevel
[1] = EEPROM_Default_TxPowerLevel
;
2585 priv
->EEPROMRfACCKChnl1TxPwLevel
[2] = EEPROM_Default_TxPowerLevel
;
2587 priv
->EEPROMRfAOfdmChnlTxPwLevel
[0] = EEPROM_Default_TxPowerLevel
;
2588 priv
->EEPROMRfAOfdmChnlTxPwLevel
[1] = EEPROM_Default_TxPowerLevel
;
2589 priv
->EEPROMRfAOfdmChnlTxPwLevel
[2] = EEPROM_Default_TxPowerLevel
;
2591 priv
->EEPROMRfCCCKChnl1TxPwLevel
[0] = EEPROM_Default_TxPowerLevel
;
2592 priv
->EEPROMRfCCCKChnl1TxPwLevel
[1] = EEPROM_Default_TxPowerLevel
;
2593 priv
->EEPROMRfCCCKChnl1TxPwLevel
[2] = EEPROM_Default_TxPowerLevel
;
2595 priv
->EEPROMRfCOfdmChnlTxPwLevel
[0] = EEPROM_Default_TxPowerLevel
;
2596 priv
->EEPROMRfCOfdmChnlTxPwLevel
[1] = EEPROM_Default_TxPowerLevel
;
2597 priv
->EEPROMRfCOfdmChnlTxPwLevel
[2] = EEPROM_Default_TxPowerLevel
;
2599 RT_TRACE(COMP_INIT
, "priv->EEPROMRfACCKChnl1TxPwLevel[0] = 0x%x\n", priv
->EEPROMRfACCKChnl1TxPwLevel
[0]);
2600 RT_TRACE(COMP_INIT
, "priv->EEPROMRfACCKChnl1TxPwLevel[1] = 0x%x\n", priv
->EEPROMRfACCKChnl1TxPwLevel
[1]);
2601 RT_TRACE(COMP_INIT
, "priv->EEPROMRfACCKChnl1TxPwLevel[2] = 0x%x\n", priv
->EEPROMRfACCKChnl1TxPwLevel
[2]);
2602 RT_TRACE(COMP_INIT
, "priv->EEPROMRfAOfdmChnlTxPwLevel[0] = 0x%x\n", priv
->EEPROMRfAOfdmChnlTxPwLevel
[0]);
2603 RT_TRACE(COMP_INIT
, "priv->EEPROMRfAOfdmChnlTxPwLevel[1] = 0x%x\n", priv
->EEPROMRfAOfdmChnlTxPwLevel
[1]);
2604 RT_TRACE(COMP_INIT
, "priv->EEPROMRfAOfdmChnlTxPwLevel[2] = 0x%x\n", priv
->EEPROMRfAOfdmChnlTxPwLevel
[2]);
2605 RT_TRACE(COMP_INIT
, "priv->EEPROMRfCCCKChnl1TxPwLevel[0] = 0x%x\n", priv
->EEPROMRfCCCKChnl1TxPwLevel
[0]);
2606 RT_TRACE(COMP_INIT
, "priv->EEPROMRfCCCKChnl1TxPwLevel[1] = 0x%x\n", priv
->EEPROMRfCCCKChnl1TxPwLevel
[1]);
2607 RT_TRACE(COMP_INIT
, "priv->EEPROMRfCCCKChnl1TxPwLevel[2] = 0x%x\n", priv
->EEPROMRfCCCKChnl1TxPwLevel
[2]);
2608 RT_TRACE(COMP_INIT
, "priv->EEPROMRfCOfdmChnlTxPwLevel[0] = 0x%x\n", priv
->EEPROMRfCOfdmChnlTxPwLevel
[0]);
2609 RT_TRACE(COMP_INIT
, "priv->EEPROMRfCOfdmChnlTxPwLevel[1] = 0x%x\n", priv
->EEPROMRfCOfdmChnlTxPwLevel
[1]);
2610 RT_TRACE(COMP_INIT
, "priv->EEPROMRfCOfdmChnlTxPwLevel[2] = 0x%x\n", priv
->EEPROMRfCOfdmChnlTxPwLevel
[2]);
2615 // Update HAL variables.
2617 if(priv
->epromtype
== EPROM_93c46
)
2621 priv
->TxPowerLevelCCK
[i
] = priv
->EEPROMTxPowerLevelCCK
[i
];
2622 priv
->TxPowerLevelOFDM24G
[i
] = priv
->EEPROMTxPowerLevelOFDM24G
[i
];
2624 priv
->LegacyHTTxPowerDiff
= priv
->EEPROMLegacyHTTxPowerDiff
;
2625 // Antenna B gain offset to antenna A, bit0~3
2626 priv
->AntennaTxPwDiff
[0] = (priv
->EEPROMAntPwDiff
& 0xf);
2627 // Antenna C gain offset to antenna A, bit4~7
2628 priv
->AntennaTxPwDiff
[1] = ((priv
->EEPROMAntPwDiff
& 0xf0)>>4);
2629 // Antenna D gain offset to antenna A, bit8~11
2630 priv
->AntennaTxPwDiff
[2] = ((priv
->EEPROMAntPwDiff
& 0xf00)>>8);
2631 // CrystalCap, bit12~15
2632 priv
->CrystalCap
= priv
->EEPROMCrystalCap
;
2633 // ThermalMeter, bit0~3 for RFIC1, bit4~7 for RFIC2
2634 priv
->ThermalMeter
[0] = (priv
->EEPROMThermalMeter
& 0xf);
2635 priv
->ThermalMeter
[1] = ((priv
->EEPROMThermalMeter
& 0xf0)>>4);
2637 else if(priv
->epromtype
== EPROM_93c56
)
2639 //char cck_pwr_diff_a=0, cck_pwr_diff_c=0;
2641 //cck_pwr_diff_a = pHalData->EEPROMRfACCKChnl7TxPwLevel - pHalData->EEPROMRfAOfdmChnlTxPwLevel[1];
2642 //cck_pwr_diff_c = pHalData->EEPROMRfCCCKChnl7TxPwLevel - pHalData->EEPROMRfCOfdmChnlTxPwLevel[1];
2643 for(i
=0; i
<3; i
++) // channel 1~3 use the same Tx Power Level.
2645 priv
->TxPowerLevelCCK_A
[i
] = priv
->EEPROMRfACCKChnl1TxPwLevel
[0];
2646 priv
->TxPowerLevelOFDM24G_A
[i
] = priv
->EEPROMRfAOfdmChnlTxPwLevel
[0];
2647 priv
->TxPowerLevelCCK_C
[i
] = priv
->EEPROMRfCCCKChnl1TxPwLevel
[0];
2648 priv
->TxPowerLevelOFDM24G_C
[i
] = priv
->EEPROMRfCOfdmChnlTxPwLevel
[0];
2650 for(i
=3; i
<9; i
++) // channel 4~9 use the same Tx Power Level
2652 priv
->TxPowerLevelCCK_A
[i
] = priv
->EEPROMRfACCKChnl1TxPwLevel
[1];
2653 priv
->TxPowerLevelOFDM24G_A
[i
] = priv
->EEPROMRfAOfdmChnlTxPwLevel
[1];
2654 priv
->TxPowerLevelCCK_C
[i
] = priv
->EEPROMRfCCCKChnl1TxPwLevel
[1];
2655 priv
->TxPowerLevelOFDM24G_C
[i
] = priv
->EEPROMRfCOfdmChnlTxPwLevel
[1];
2657 for(i
=9; i
<14; i
++) // channel 10~14 use the same Tx Power Level
2659 priv
->TxPowerLevelCCK_A
[i
] = priv
->EEPROMRfACCKChnl1TxPwLevel
[2];
2660 priv
->TxPowerLevelOFDM24G_A
[i
] = priv
->EEPROMRfAOfdmChnlTxPwLevel
[2];
2661 priv
->TxPowerLevelCCK_C
[i
] = priv
->EEPROMRfCCCKChnl1TxPwLevel
[2];
2662 priv
->TxPowerLevelOFDM24G_C
[i
] = priv
->EEPROMRfCOfdmChnlTxPwLevel
[2];
2665 RT_TRACE(COMP_INIT
, "priv->TxPowerLevelCCK_A[%d] = 0x%x\n", i
, priv
->TxPowerLevelCCK_A
[i
]);
2667 RT_TRACE(COMP_INIT
,"priv->TxPowerLevelOFDM24G_A[%d] = 0x%x\n", i
, priv
->TxPowerLevelOFDM24G_A
[i
]);
2669 RT_TRACE(COMP_INIT
, "priv->TxPowerLevelCCK_C[%d] = 0x%x\n", i
, priv
->TxPowerLevelCCK_C
[i
]);
2671 RT_TRACE(COMP_INIT
, "priv->TxPowerLevelOFDM24G_C[%d] = 0x%x\n", i
, priv
->TxPowerLevelOFDM24G_C
[i
]);
2672 priv
->LegacyHTTxPowerDiff
= priv
->EEPROMLegacyHTTxPowerDiff
;
2673 priv
->AntennaTxPwDiff
[0] = 0;
2674 priv
->AntennaTxPwDiff
[1] = 0;
2675 priv
->AntennaTxPwDiff
[2] = 0;
2676 priv
->CrystalCap
= priv
->EEPROMCrystalCap
;
2677 // ThermalMeter, bit0~3 for RFIC1, bit4~7 for RFIC2
2678 priv
->ThermalMeter
[0] = (priv
->EEPROMThermalMeter
& 0xf);
2679 priv
->ThermalMeter
[1] = ((priv
->EEPROMThermalMeter
& 0xf0)>>4);
2683 if(priv
->rf_type
== RF_1T2R
)
2685 RT_TRACE(COMP_INIT
, "\n1T2R config\n");
2687 else if (priv
->rf_type
== RF_2T4R
)
2689 RT_TRACE(COMP_INIT
, "\n2T4R config\n");
2692 // 2008/01/16 MH We can only know RF type in the function. So we have to init
2693 // DIG RATR table again.
2694 init_rate_adaptive(dev
);
2696 //1 Make a copy for following variables and we can change them if we want
2698 priv
->rf_chip
= RF_8256
;
2700 if(priv
->RegChannelPlan
== 0xf)
2702 priv
->ChannelPlan
= priv
->eeprom_ChannelPlan
;
2706 priv
->ChannelPlan
= priv
->RegChannelPlan
;
2710 // Used PID and DID to Set CustomerID
2712 if( priv
->eeprom_vid
== 0x1186 && priv
->eeprom_did
== 0x3304 )
2714 priv
->CustomerID
= RT_CID_DLINK
;
2717 switch(priv
->eeprom_CustomerID
)
2719 case EEPROM_CID_DEFAULT
:
2720 priv
->CustomerID
= RT_CID_DEFAULT
;
2722 case EEPROM_CID_CAMEO
:
2723 priv
->CustomerID
= RT_CID_819x_CAMEO
;
2725 case EEPROM_CID_RUNTOP
:
2726 priv
->CustomerID
= RT_CID_819x_RUNTOP
;
2728 case EEPROM_CID_NetCore
:
2729 priv
->CustomerID
= RT_CID_819x_Netcore
;
2731 case EEPROM_CID_TOSHIBA
: // Merge by Jacken, 2008/01/31
2732 priv
->CustomerID
= RT_CID_TOSHIBA
;
2733 if(priv
->eeprom_ChannelPlan
&0x80)
2734 priv
->ChannelPlan
= priv
->eeprom_ChannelPlan
&0x7f;
2736 priv
->ChannelPlan
= 0x0;
2737 RT_TRACE(COMP_INIT
, "Toshiba ChannelPlan = 0x%x\n",
2740 case EEPROM_CID_Nettronix
:
2741 priv
->CustomerID
= RT_CID_Nettronix
;
2743 case EEPROM_CID_Pronet
:
2744 priv
->CustomerID
= RT_CID_PRONET
;
2746 case EEPROM_CID_DLINK
:
2747 priv
->CustomerID
= RT_CID_DLINK
;
2750 case EEPROM_CID_WHQL
:
2751 //Adapter->bInHctTest = TRUE;//do not supported
2753 //priv->bSupportTurboMode = FALSE;
2754 //priv->bAutoTurboBy8186 = FALSE;
2756 //pMgntInfo->PowerSaveControl.bInactivePs = FALSE;
2757 //pMgntInfo->PowerSaveControl.bIPSModeBackup = FALSE;
2758 //pMgntInfo->PowerSaveControl.bLeisurePs = FALSE;
2762 // value from RegCustomerID
2766 //Avoid the channel plan array overflow, by Bruce, 2007-08-27.
2767 if(priv
->ChannelPlan
> CHANNEL_PLAN_LEN
- 1)
2768 priv
->ChannelPlan
= 0; //FCC
2770 switch(priv
->CustomerID
)
2772 case RT_CID_DEFAULT
:
2774 priv
->LedStrategy
= HW_LED
;
2777 priv
->LedStrategy
= SW_LED_MODE1
;
2782 case RT_CID_819x_CAMEO
:
2783 priv
->LedStrategy
= SW_LED_MODE2
;
2786 case RT_CID_819x_RUNTOP
:
2787 priv
->LedStrategy
= SW_LED_MODE3
;
2790 case RT_CID_819x_Netcore
:
2791 priv
->LedStrategy
= SW_LED_MODE4
;
2794 case RT_CID_Nettronix
:
2795 priv
->LedStrategy
= SW_LED_MODE5
;
2799 priv
->LedStrategy
= SW_LED_MODE6
;
2802 case RT_CID_TOSHIBA
: //Modify by Jacken 2008/01/31
2808 priv
->LedStrategy
= HW_LED
;
2811 priv
->LedStrategy
= SW_LED_MODE1
;
2818 if( priv
->eeprom_vid
== 0x1186 && priv
->eeprom_did
== 0x3304)
2819 priv
->ieee80211
->bSupportRemoteWakeUp
= true;
2821 priv
->ieee80211
->bSupportRemoteWakeUp
= false;
2824 RT_TRACE(COMP_INIT
, "RegChannelPlan(%d)\n", priv
->RegChannelPlan
);
2825 RT_TRACE(COMP_INIT
, "ChannelPlan = %d \n", priv
->ChannelPlan
);
2826 RT_TRACE(COMP_INIT
, "LedStrategy = %d \n", priv
->LedStrategy
);
2827 RT_TRACE(COMP_TRACE
, "<==== ReadAdapterInfo\n");
2833 static short rtl8192_get_channel_map(struct net_device
* dev
)
2835 struct r8192_priv
*priv
= ieee80211_priv(dev
);
2836 #ifdef ENABLE_DOT11D
2837 if(priv
->ChannelPlan
> COUNTRY_CODE_GLOBAL_DOMAIN
){
2838 printk("rtl8180_init:Error channel plan! Set to default.\n");
2839 priv
->ChannelPlan
= 0;
2841 RT_TRACE(COMP_INIT
, "Channel plan is %d\n",priv
->ChannelPlan
);
2843 rtl819x_set_channel_map(priv
->ChannelPlan
, priv
);
2846 //Set Default Channel Plan
2848 DMESG("No channels, aborting");
2852 priv
->ChannelPlan
= 0;//hikaru
2853 // set channels 1..14 allowed in given locale
2854 for (i
=1; i
<=14; i
++) {
2855 (priv
->ieee80211
->channel_map
)[i
] = (u8
)(ch
& 0x01);
2862 static short rtl8192_init(struct net_device
*dev
)
2864 struct r8192_priv
*priv
= ieee80211_priv(dev
);
2865 memset(&(priv
->stats
),0,sizeof(struct Stats
));
2866 rtl8192_init_priv_variable(dev
);
2867 rtl8192_init_priv_lock(priv
);
2868 rtl8192_init_priv_task(dev
);
2869 rtl8192_get_eeprom_size(dev
);
2870 rtl8192_read_eeprom_info(dev
);
2871 rtl8192_get_channel_map(dev
);
2873 init_timer(&priv
->watch_dog_timer
);
2874 priv
->watch_dog_timer
.data
= (unsigned long)dev
;
2875 priv
->watch_dog_timer
.function
= watch_dog_timer_callback
;
2876 if (request_irq(dev
->irq
, rtl8192_interrupt
, IRQF_SHARED
, dev
->name
, dev
)) {
2877 printk("Error allocating IRQ %d",dev
->irq
);
2881 printk("IRQ %d",dev
->irq
);
2883 if(rtl8192_pci_initdescring(dev
)!=0){
2884 printk("Endopoints initialization failed");
2888 //rtl8192_rx_enable(dev);
2889 //rtl8192_adapter_start(dev);
2894 * Actually only set RRSR, RATR and BW_OPMODE registers
2895 * not to do all the hw config as its name says
2896 * This part need to modified according to the rate set we filtered
2898 static void rtl8192_hwconfig(struct net_device
* dev
)
2900 u32 regRATR
= 0, regRRSR
= 0;
2901 u8 regBwOpMode
= 0, regTmp
= 0;
2902 struct r8192_priv
*priv
= ieee80211_priv(dev
);
2904 // Set RRSR, RATR, and BW_OPMODE registers
2906 switch(priv
->ieee80211
->mode
)
2908 case WIRELESS_MODE_B
:
2909 regBwOpMode
= BW_OPMODE_20MHZ
;
2910 regRATR
= RATE_ALL_CCK
;
2911 regRRSR
= RATE_ALL_CCK
;
2913 case WIRELESS_MODE_A
:
2914 regBwOpMode
= BW_OPMODE_5G
|BW_OPMODE_20MHZ
;
2915 regRATR
= RATE_ALL_OFDM_AG
;
2916 regRRSR
= RATE_ALL_OFDM_AG
;
2918 case WIRELESS_MODE_G
:
2919 regBwOpMode
= BW_OPMODE_20MHZ
;
2920 regRATR
= RATE_ALL_CCK
| RATE_ALL_OFDM_AG
;
2921 regRRSR
= RATE_ALL_CCK
| RATE_ALL_OFDM_AG
;
2923 case WIRELESS_MODE_AUTO
:
2924 case WIRELESS_MODE_N_24G
:
2925 // It support CCK rate by default.
2926 // CCK rate will be filtered out only when associated AP does not support it.
2927 regBwOpMode
= BW_OPMODE_20MHZ
;
2928 regRATR
= RATE_ALL_CCK
| RATE_ALL_OFDM_AG
| RATE_ALL_OFDM_1SS
| RATE_ALL_OFDM_2SS
;
2929 regRRSR
= RATE_ALL_CCK
| RATE_ALL_OFDM_AG
;
2931 case WIRELESS_MODE_N_5G
:
2932 regBwOpMode
= BW_OPMODE_5G
;
2933 regRATR
= RATE_ALL_OFDM_AG
| RATE_ALL_OFDM_1SS
| RATE_ALL_OFDM_2SS
;
2934 regRRSR
= RATE_ALL_OFDM_AG
;
2938 write_nic_byte(dev
, BW_OPMODE
, regBwOpMode
);
2941 ratr_value
= regRATR
;
2942 if (priv
->rf_type
== RF_1T2R
)
2944 ratr_value
&= ~(RATE_ALL_OFDM_2SS
);
2946 write_nic_dword(dev
, RATR0
, ratr_value
);
2947 write_nic_byte(dev
, UFWP
, 1);
2949 regTmp
= read_nic_byte(dev
, 0x313);
2950 regRRSR
= ((regTmp
) << 24) | (regRRSR
& 0x00ffffff);
2951 write_nic_dword(dev
, RRSR
, regRRSR
);
2954 // Set Retry Limit here
2956 write_nic_word(dev
, RETRY_LIMIT
,
2957 priv
->ShortRetryLimit
<< RETRY_LIMIT_SHORT_SHIFT
|
2958 priv
->LongRetryLimit
<< RETRY_LIMIT_LONG_SHIFT
);
2959 // Set Contention Window here
2963 // Set Tx Antenna including Feedback control
2965 // Set Auto Rate fallback control
2971 static RT_STATUS
rtl8192_adapter_start(struct net_device
*dev
)
2973 struct r8192_priv
*priv
= ieee80211_priv(dev
);
2974 // struct ieee80211_device *ieee = priv->ieee80211;
2976 RT_STATUS rtStatus
= RT_STATUS_SUCCESS
;
2980 u8 ICVersion
,SwitchingRegulatorOutput
;
2982 bool bfirmwareok
= true;
2986 u32 tmpRegA
, tmpRegC
, TempCCk
;
2989 RT_TRACE(COMP_INIT
, "====>%s()\n", __FUNCTION__
);
2990 priv
->being_init_adapter
= true;
2991 rtl8192_pci_resetdescring(dev
);
2992 // 2007/11/02 MH Before initalizing RF. We can not use FW to do RF-R/W.
2993 priv
->Rf_Mode
= RF_OP_By_SW_3wire
;
2996 if(priv
->ResetProgress
== RESET_TYPE_NORESET
)
2998 write_nic_byte(dev
, ANAPAR
, 0x37);
2999 // Accordign to designer's explain, LBUS active will never > 10ms. We delay 10ms
3000 // Joseph increae the time to prevent firmware download fail
3004 //PlatformSleepUs(10000);
3005 // For any kind of InitializeAdapter process, we shall use system now!!
3006 priv
->pFirmware
->firmware_status
= FW_STATUS_0_INIT
;
3009 //3 //Config CPUReset Register
3011 //3 Firmware Reset Or Not
3012 ulRegRead
= read_nic_dword(dev
, CPU_GEN
);
3013 if(priv
->pFirmware
->firmware_status
== FW_STATUS_0_INIT
)
3014 { //called from MPInitialized. do nothing
3015 ulRegRead
|= CPU_GEN_SYSTEM_RESET
;
3016 }else if(priv
->pFirmware
->firmware_status
== FW_STATUS_5_READY
)
3017 ulRegRead
|= CPU_GEN_FIRMWARE_RESET
; // Called from MPReset
3019 RT_TRACE(COMP_ERR
, "ERROR in %s(): undefined firmware state(%d)\n", __FUNCTION__
, priv
->pFirmware
->firmware_status
);
3022 //2008.06.03, for WOL 90 hw bug
3023 ulRegRead
&= (~(CPU_GEN_GPIO_UART
));
3026 write_nic_dword(dev
, CPU_GEN
, ulRegRead
);
3032 //3 //Fix the issue of E-cut high temperature issue
3035 ICVersion
= read_nic_byte(dev
, IC_VERRSION
);
3036 if(ICVersion
>= 0x4) //E-cut only
3038 // HW SD suggest that we should not wirte this register too often, so driver
3039 // should readback this register. This register will be modified only when
3041 SwitchingRegulatorOutput
= read_nic_byte(dev
, SWREGULATOR
);
3042 if(SwitchingRegulatorOutput
!= 0xb8)
3044 write_nic_byte(dev
, SWREGULATOR
, 0xa8);
3046 write_nic_byte(dev
, SWREGULATOR
, 0xb8);
3053 //3// Initialize BB before MAC
3055 RT_TRACE(COMP_INIT
, "BB Config Start!\n");
3056 rtStatus
= rtl8192_BBConfig(dev
);
3057 if(rtStatus
!= RT_STATUS_SUCCESS
)
3059 RT_TRACE(COMP_ERR
, "BB Config failed\n");
3062 RT_TRACE(COMP_INIT
,"BB Config Finished!\n");
3064 //3//Set Loopback mode or Normal mode
3066 //2006.12.13 by emily. Note!We should not merge these two CPU_GEN register writings
3067 // because setting of System_Reset bit reset MAC to default transmission mode.
3068 //Loopback mode or not
3069 priv
->LoopbackMode
= RTL819X_NO_LOOPBACK
;
3070 //priv->LoopbackMode = RTL819X_MAC_LOOPBACK;
3071 if(priv
->ResetProgress
== RESET_TYPE_NORESET
)
3073 ulRegRead
= read_nic_dword(dev
, CPU_GEN
);
3074 if(priv
->LoopbackMode
== RTL819X_NO_LOOPBACK
)
3076 ulRegRead
= ((ulRegRead
& CPU_GEN_NO_LOOPBACK_MSK
) | CPU_GEN_NO_LOOPBACK_SET
);
3078 else if (priv
->LoopbackMode
== RTL819X_MAC_LOOPBACK
)
3080 ulRegRead
|= CPU_CCK_LOOPBACK
;
3084 RT_TRACE(COMP_ERR
,"Serious error: wrong loopback mode setting\n");
3087 //2008.06.03, for WOL
3088 //ulRegRead &= (~(CPU_GEN_GPIO_UART));
3089 write_nic_dword(dev
, CPU_GEN
, ulRegRead
);
3091 // 2006.11.29. After reset cpu, we sholud wait for a second, otherwise, it may fail to write registers. Emily
3094 //3Set Hardware(Do nothing now)
3095 rtl8192_hwconfig(dev
);
3096 //2=======================================================
3097 // Common Setting for all of the FPGA platform. (part 1)
3098 //2=======================================================
3099 // If there is changes, please make sure it applies to all of the FPGA version
3101 write_nic_byte(dev
, CMDR
, CR_RE
|CR_TE
);
3105 write_nic_byte(dev
, PCIF
, ((MXDMA2_NoLimit
<<MXDMA2_RX_SHIFT
) |
3106 (MXDMA2_NoLimit
<<MXDMA2_TX_SHIFT
) |
3110 write_nic_byte(dev
, PCIF
, ((MXDMA2_NoLimit
<<MXDMA2_RX_SHIFT
) |
3111 (MXDMA2_NoLimit
<<MXDMA2_TX_SHIFT
) ));
3115 write_nic_dword(dev
, MAC0
, ((u32
*)dev
->dev_addr
)[0]);
3116 write_nic_word(dev
, MAC4
, ((u16
*)(dev
->dev_addr
+ 4))[0]);
3118 write_nic_dword(dev
, RCR
, priv
->ReceiveConfig
);
3120 //3 Initialize Number of Reserved Pages in Firmware Queue
3122 if(priv
->bInHctTest
)
3124 PlatformEFIOWrite4Byte(Adapter
, RQPN1
, NUM_OF_PAGE_IN_FW_QUEUE_BK_DTM
<< RSVD_FW_QUEUE_PAGE_BK_SHIFT
|
3125 NUM_OF_PAGE_IN_FW_QUEUE_BE_DTM
<< RSVD_FW_QUEUE_PAGE_BE_SHIFT
|
3126 NUM_OF_PAGE_IN_FW_QUEUE_VI_DTM
<< RSVD_FW_QUEUE_PAGE_VI_SHIFT
|
3127 NUM_OF_PAGE_IN_FW_QUEUE_VO_DTM
<<RSVD_FW_QUEUE_PAGE_VO_SHIFT
);
3128 PlatformEFIOWrite4Byte(Adapter
, RQPN2
, NUM_OF_PAGE_IN_FW_QUEUE_MGNT
<< RSVD_FW_QUEUE_PAGE_MGNT_SHIFT
);
3129 PlatformEFIOWrite4Byte(Adapter
, RQPN3
, APPLIED_RESERVED_QUEUE_IN_FW
|
3130 NUM_OF_PAGE_IN_FW_QUEUE_BCN
<<RSVD_FW_QUEUE_PAGE_BCN_SHIFT
|
3131 NUM_OF_PAGE_IN_FW_QUEUE_PUB_DTM
<<RSVD_FW_QUEUE_PAGE_PUB_SHIFT
);
3136 write_nic_dword(dev
, RQPN1
, NUM_OF_PAGE_IN_FW_QUEUE_BK
<< RSVD_FW_QUEUE_PAGE_BK_SHIFT
|
3137 NUM_OF_PAGE_IN_FW_QUEUE_BE
<< RSVD_FW_QUEUE_PAGE_BE_SHIFT
|
3138 NUM_OF_PAGE_IN_FW_QUEUE_VI
<< RSVD_FW_QUEUE_PAGE_VI_SHIFT
|
3139 NUM_OF_PAGE_IN_FW_QUEUE_VO
<<RSVD_FW_QUEUE_PAGE_VO_SHIFT
);
3140 write_nic_dword(dev
, RQPN2
, NUM_OF_PAGE_IN_FW_QUEUE_MGNT
<< RSVD_FW_QUEUE_PAGE_MGNT_SHIFT
);
3141 write_nic_dword(dev
, RQPN3
, APPLIED_RESERVED_QUEUE_IN_FW
|
3142 NUM_OF_PAGE_IN_FW_QUEUE_BCN
<<RSVD_FW_QUEUE_PAGE_BCN_SHIFT
|
3143 NUM_OF_PAGE_IN_FW_QUEUE_PUB
<<RSVD_FW_QUEUE_PAGE_PUB_SHIFT
);
3146 rtl8192_tx_enable(dev
);
3147 rtl8192_rx_enable(dev
);
3148 //3Set Response Rate Setting Register
3149 // CCK rate is supported by default.
3150 // CCK rate will be filtered out only when associated AP does not support it.
3151 ulRegRead
= (0xFFF00000 & read_nic_dword(dev
, RRSR
)) | RATE_ALL_OFDM_AG
| RATE_ALL_CCK
;
3152 write_nic_dword(dev
, RRSR
, ulRegRead
);
3153 write_nic_dword(dev
, RATR0
+4*7, (RATE_ALL_OFDM_AG
| RATE_ALL_CCK
));
3156 // TODO: (it value is only for FPGA version). need to be changed!!2006.12.18, by Emily
3157 write_nic_byte(dev
, ACK_TIMEOUT
, 0x30);
3159 //rtl8192_actset_wirelessmode(dev,priv->RegWirelessMode);
3160 if(priv
->ResetProgress
== RESET_TYPE_NORESET
)
3161 rtl8192_SetWirelessMode(dev
, priv
->ieee80211
->mode
);
3162 //-----------------------------------------------------------------------------
3163 // Set up security related. 070106, by rcnjko:
3164 // 1. Clear all H/W keys.
3165 // 2. Enable H/W encryption/decryption.
3166 //-----------------------------------------------------------------------------
3167 CamResetAllEntry(dev
);
3169 u8 SECR_value
= 0x0;
3170 SECR_value
|= SCR_TxEncEnable
;
3171 SECR_value
|= SCR_RxDecEnable
;
3172 SECR_value
|= SCR_NoSKMC
;
3173 write_nic_byte(dev
, SECR
, SECR_value
);
3176 write_nic_word(dev
, ATIMWND
, 2);
3177 write_nic_word(dev
, BCN_INTERVAL
, 100);
3178 for (i
=0; i
<QOS_QUEUE_NUM
; i
++)
3179 write_nic_dword(dev
, WDCAPARA_ADD
[i
], 0x005e4332);
3181 // Switching regulator controller: This is set temporarily.
3182 // It's not sure if this can be removed in the future.
3183 // PJ advised to leave it by default.
3185 write_nic_byte(dev
, 0xbe, 0xc0);
3187 //2=======================================================
3188 // Set PHY related configuration defined in MAC register bank
3189 //2=======================================================
3190 rtl8192_phy_configmac(dev
);
3192 if (priv
->card_8192_version
> (u8
) VERSION_8190_BD
) {
3193 rtl8192_phy_getTxPower(dev
);
3194 rtl8192_phy_setTxPower(dev
, priv
->chan
);
3198 tmpvalue
= read_nic_byte(dev
, IC_VERRSION
);
3199 priv
->IC_Cut
= tmpvalue
;
3200 RT_TRACE(COMP_INIT
, "priv->IC_Cut = 0x%x\n", priv
->IC_Cut
);
3201 if(priv
->IC_Cut
>= IC_VersionCut_D
)
3203 //pHalData->bDcut = TRUE;
3204 if(priv
->IC_Cut
== IC_VersionCut_D
)
3205 RT_TRACE(COMP_INIT
, "D-cut\n");
3206 if(priv
->IC_Cut
== IC_VersionCut_E
)
3208 RT_TRACE(COMP_INIT
, "E-cut\n");
3209 // HW SD suggest that we should not wirte this register too often, so driver
3210 // should readback this register. This register will be modified only when
3216 //pHalData->bDcut = FALSE;
3217 RT_TRACE(COMP_INIT
, "Before C-cut\n");
3222 RT_TRACE(COMP_INIT
, "Load Firmware!\n");
3223 bfirmwareok
= init_firmware(dev
);
3224 if(bfirmwareok
!= true) {
3225 rtStatus
= RT_STATUS_FAILURE
;
3228 RT_TRACE(COMP_INIT
, "Load Firmware finished!\n");
3231 if(priv
->ResetProgress
== RESET_TYPE_NORESET
)
3233 RT_TRACE(COMP_INIT
, "RF Config Started!\n");
3234 rtStatus
= rtl8192_phy_RFConfig(dev
);
3235 if(rtStatus
!= RT_STATUS_SUCCESS
)
3237 RT_TRACE(COMP_ERR
, "RF Config failed\n");
3240 RT_TRACE(COMP_INIT
, "RF Config Finished!\n");
3242 rtl8192_phy_updateInitGain(dev
);
3244 /*---- Set CCK and OFDM Block "ON"----*/
3245 rtl8192_setBBreg(dev
, rFPGA0_RFMOD
, bCCKEn
, 0x1);
3246 rtl8192_setBBreg(dev
, rFPGA0_RFMOD
, bOFDMEn
, 0x1);
3250 write_nic_byte(dev
, 0x87, 0x0);
3253 //2008.06.03, for WOL
3254 ucRegRead
= read_nic_byte(dev
, GPE
);
3256 write_nic_byte(dev
, GPE
, ucRegRead
);
3258 ucRegRead
= read_nic_byte(dev
, GPO
);
3260 write_nic_byte(dev
, GPO
, ucRegRead
);
3263 //2=======================================================
3265 //2=======================================================
3269 if(priv
->ieee80211
->RfOffReason
> RF_CHANGE_BY_PS
)
3270 { // H/W or S/W RF OFF before sleep.
3271 RT_TRACE((COMP_INIT
|COMP_RF
|COMP_POWER
), "%s(): Turn off RF for RfOffReason(%d) ----------\n", __FUNCTION__
,priv
->ieee80211
->RfOffReason
);
3272 MgntActSet_RF_State(dev
, eRfOff
, priv
->ieee80211
->RfOffReason
);
3274 else if(priv
->ieee80211
->RfOffReason
>= RF_CHANGE_BY_IPS
)
3275 { // H/W or S/W RF OFF before sleep.
3276 RT_TRACE((COMP_INIT
|COMP_RF
|COMP_POWER
), "%s(): Turn off RF for RfOffReason(%d) ----------\n", __FUNCTION__
,priv
->ieee80211
->RfOffReason
);
3277 MgntActSet_RF_State(dev
, eRfOff
, priv
->ieee80211
->RfOffReason
);
3281 RT_TRACE((COMP_INIT
|COMP_RF
|COMP_POWER
), "%s(): RF-ON \n",__FUNCTION__
);
3282 priv
->ieee80211
->eRFPowerState
= eRfOn
;
3283 priv
->ieee80211
->RfOffReason
= 0;
3284 //DrvIFIndicateCurrentPhyStatus(Adapter);
3286 //Adapter->HalFunc.LedControlHandler(Adapter, LED_CTL_POWER_ON);
3289 // If inactive power mode is enabled, disable rf while in disconnected state.
3290 // But we should still tell upper layer we are in rf on state.
3291 // 2007.07.16, by shien chang.
3293 //if(!Adapter->bInHctTest)
3294 //IPSEnter(Adapter);
3301 // We can force firmware to do RF-R/W
3302 if(priv
->ieee80211
->FwRWRF
)
3303 priv
->Rf_Mode
= RF_OP_By_FW
;
3305 priv
->Rf_Mode
= RF_OP_By_SW_3wire
;
3307 priv
->Rf_Mode
= RF_OP_By_SW_3wire
;
3311 if(priv
->ResetProgress
== RESET_TYPE_NORESET
)
3313 dm_initialize_txpower_tracking(dev
);
3315 tmpRegA
= rtl8192_QueryBBReg(dev
,rOFDM0_XATxIQImbalance
,bMaskDWord
);
3316 tmpRegC
= rtl8192_QueryBBReg(dev
,rOFDM0_XCTxIQImbalance
,bMaskDWord
);
3318 if(priv
->rf_type
== RF_2T4R
){
3319 for(i
= 0; i
<TxBBGainTableLength
; i
++)
3321 if(tmpRegA
== priv
->txbbgain_table
[i
].txbbgain_value
)
3323 priv
->rfa_txpowertrackingindex
= (u8
)i
;
3324 priv
->rfa_txpowertrackingindex_real
= (u8
)i
;
3325 priv
->rfa_txpowertracking_default
= priv
->rfa_txpowertrackingindex
;
3330 for(i
= 0; i
<TxBBGainTableLength
; i
++)
3332 if(tmpRegC
== priv
->txbbgain_table
[i
].txbbgain_value
)
3334 priv
->rfc_txpowertrackingindex
= (u8
)i
;
3335 priv
->rfc_txpowertrackingindex_real
= (u8
)i
;
3336 priv
->rfc_txpowertracking_default
= priv
->rfc_txpowertrackingindex
;
3340 TempCCk
= rtl8192_QueryBBReg(dev
, rCCK0_TxFilter1
, bMaskByte2
);
3342 for(i
=0 ; i
<CCKTxBBGainTableLength
; i
++)
3344 if(TempCCk
== priv
->cck_txbbgain_table
[i
].ccktxbb_valuearray
[0])
3346 priv
->CCKPresentAttentuation_20Mdefault
=(u8
) i
;
3350 priv
->CCKPresentAttentuation_40Mdefault
= 0;
3351 priv
->CCKPresentAttentuation_difference
= 0;
3352 priv
->CCKPresentAttentuation
= priv
->CCKPresentAttentuation_20Mdefault
;
3353 RT_TRACE(COMP_POWER_TRACKING
, "priv->rfa_txpowertrackingindex_initial = %d\n", priv
->rfa_txpowertrackingindex
);
3354 RT_TRACE(COMP_POWER_TRACKING
, "priv->rfa_txpowertrackingindex_real__initial = %d\n", priv
->rfa_txpowertrackingindex_real
);
3355 RT_TRACE(COMP_POWER_TRACKING
, "priv->rfc_txpowertrackingindex_initial = %d\n", priv
->rfc_txpowertrackingindex
);
3356 RT_TRACE(COMP_POWER_TRACKING
, "priv->rfc_txpowertrackingindex_real_initial = %d\n", priv
->rfc_txpowertrackingindex_real
);
3357 RT_TRACE(COMP_POWER_TRACKING
, "priv->CCKPresentAttentuation_difference_initial = %d\n", priv
->CCKPresentAttentuation_difference
);
3358 RT_TRACE(COMP_POWER_TRACKING
, "priv->CCKPresentAttentuation_initial = %d\n", priv
->CCKPresentAttentuation
);
3362 if(priv
->ResetProgress
== RESET_TYPE_NORESET
)
3364 dm_initialize_txpower_tracking(dev
);
3366 if(priv
->IC_Cut
>= IC_VersionCut_D
)
3368 tmpRegA
= rtl8192_QueryBBReg(dev
,rOFDM0_XATxIQImbalance
,bMaskDWord
);
3369 tmpRegC
= rtl8192_QueryBBReg(dev
,rOFDM0_XCTxIQImbalance
,bMaskDWord
);
3370 for(i
= 0; i
<TxBBGainTableLength
; i
++)
3372 if(tmpRegA
== priv
->txbbgain_table
[i
].txbbgain_value
)
3374 priv
->rfa_txpowertrackingindex
= (u8
)i
;
3375 priv
->rfa_txpowertrackingindex_real
= (u8
)i
;
3376 priv
->rfa_txpowertracking_default
= priv
->rfa_txpowertrackingindex
;
3381 TempCCk
= rtl8192_QueryBBReg(dev
, rCCK0_TxFilter1
, bMaskByte2
);
3383 for(i
=0 ; i
<CCKTxBBGainTableLength
; i
++)
3385 if(TempCCk
== priv
->cck_txbbgain_table
[i
].ccktxbb_valuearray
[0])
3387 priv
->CCKPresentAttentuation_20Mdefault
=(u8
) i
;
3391 priv
->CCKPresentAttentuation_40Mdefault
= 0;
3392 priv
->CCKPresentAttentuation_difference
= 0;
3393 priv
->CCKPresentAttentuation
= priv
->CCKPresentAttentuation_20Mdefault
;
3394 RT_TRACE(COMP_POWER_TRACKING
, "priv->rfa_txpowertrackingindex_initial = %d\n", priv
->rfa_txpowertrackingindex
);
3395 RT_TRACE(COMP_POWER_TRACKING
, "priv->rfa_txpowertrackingindex_real__initial = %d\n", priv
->rfa_txpowertrackingindex_real
);
3396 RT_TRACE(COMP_POWER_TRACKING
, "priv->CCKPresentAttentuation_difference_initial = %d\n", priv
->CCKPresentAttentuation_difference
);
3397 RT_TRACE(COMP_POWER_TRACKING
, "priv->CCKPresentAttentuation_initial = %d\n", priv
->CCKPresentAttentuation
);
3398 priv
->btxpower_tracking
= FALSE
;//TEMPLY DISABLE
3403 rtl8192_irq_enable(dev
);
3404 priv
->being_init_adapter
= false;
3409 static void rtl8192_prepare_beacon(struct r8192_priv
*priv
)
3411 struct sk_buff
*skb
;
3412 //unsigned long flags;
3415 skb
= ieee80211_get_beacon(priv
->ieee80211
);
3416 tcb_desc
= (cb_desc
*)(skb
->cb
+ 8);
3417 //spin_lock_irqsave(&priv->tx_lock,flags);
3418 /* prepare misc info for the beacon xmit */
3419 tcb_desc
->queue_index
= BEACON_QUEUE
;
3420 /* IBSS does not support HT yet, use 1M defaultly */
3421 tcb_desc
->data_rate
= 2;
3422 tcb_desc
->RATRIndex
= 7;
3423 tcb_desc
->bTxDisableRateFallBack
= 1;
3424 tcb_desc
->bTxUseDriverAssingedRate
= 1;
3426 skb_push(skb
, priv
->ieee80211
->tx_headroom
);
3428 rtl8192_tx(priv
->ieee80211
->dev
,skb
);
3430 //spin_unlock_irqrestore (&priv->tx_lock, flags);
3435 * configure registers for beacon tx and enables it via
3436 * rtl8192_beacon_tx_enable(). rtl8192_beacon_tx_disable() might
3437 * be used to stop beacon transmission
3439 static void rtl8192_start_beacon(struct net_device
*dev
)
3441 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
3442 struct ieee80211_network
*net
= &priv
->ieee80211
->current_network
;
3447 DMESG("Enabling beacon TX");
3448 //rtl8192_prepare_beacon(dev);
3449 rtl8192_irq_disable(dev
);
3450 //rtl8192_beacon_tx_enable(dev);
3453 write_nic_word(dev
, ATIMWND
, 2);
3455 /* Beacon interval (in unit of TU) */
3456 write_nic_word(dev
, BCN_INTERVAL
, net
->beacon_interval
);
3459 * DrvErlyInt (in unit of TU).
3460 * (Time to send interrupt to notify driver to c
3461 * hange beacon content)
3463 write_nic_word(dev
, BCN_DRV_EARLY_INT
, 10);
3466 * BcnDMATIM(in unit of us).
3467 * Indicates the time before TBTT to perform beacon queue DMA
3469 write_nic_word(dev
, BCN_DMATIME
, 256);
3472 * Force beacon frame transmission even after receiving
3473 * beacon frame from other ad hoc STA
3475 write_nic_byte(dev
, BCN_ERR_THRESH
, 100);
3477 /* Set CW and IFS */
3478 BcnTimeCfg
|= BcnCW
<<BCN_TCFG_CW_SHIFT
;
3479 BcnTimeCfg
|= BcnIFS
<<BCN_TCFG_IFS
;
3480 write_nic_word(dev
, BCN_TCFG
, BcnTimeCfg
);
3483 /* enable the interrupt for ad-hoc process */
3484 rtl8192_irq_enable(dev
);
3487 static bool HalTxCheckStuck8190Pci(struct net_device
*dev
)
3489 u16 RegTxCounter
= read_nic_word(dev
, 0x128);
3490 struct r8192_priv
*priv
= ieee80211_priv(dev
);
3491 bool bStuck
= FALSE
;
3492 RT_TRACE(COMP_RESET
,"%s():RegTxCounter is %d,TxCounter is %d\n",__FUNCTION__
,RegTxCounter
,priv
->TxCounter
);
3493 if(priv
->TxCounter
==RegTxCounter
)
3496 priv
->TxCounter
= RegTxCounter
;
3502 * Assumption: RT_TX_SPINLOCK is acquired.
3505 TxCheckStuck(struct net_device
*dev
)
3507 struct r8192_priv
*priv
= ieee80211_priv(dev
);
3508 u8 ResetThreshold
= NIC_SEND_HANG_THRESHOLD_POWERSAVE
;
3509 bool bCheckFwTxCnt
= false;
3512 // Decide Stuch threshold according to current power save mode
3514 switch (priv
->ieee80211
->dot11PowerSaveMode
)
3516 // The threshold value may required to be adjusted .
3517 case eActive
: // Active/Continuous access.
3518 ResetThreshold
= NIC_SEND_HANG_THRESHOLD_NORMAL
;
3520 case eMaxPs
: // Max power save mode.
3521 ResetThreshold
= NIC_SEND_HANG_THRESHOLD_POWERSAVE
;
3523 case eFastPs
: // Fast power save mode.
3524 ResetThreshold
= NIC_SEND_HANG_THRESHOLD_POWERSAVE
;
3531 if(HalTxCheckStuck8190Pci(dev
))
3533 RT_TRACE(COMP_RESET
, "TxCheckStuck(): Fw indicates no Tx condition! \n");
3534 return RESET_TYPE_SILENT
;
3538 return RESET_TYPE_NORESET
;
3542 static bool HalRxCheckStuck8190Pci(struct net_device
*dev
)
3544 struct r8192_priv
*priv
= ieee80211_priv(dev
);
3545 u16 RegRxCounter
= read_nic_word(dev
, 0x130);
3546 bool bStuck
= FALSE
;
3547 static u8 rx_chk_cnt
= 0;
3548 RT_TRACE(COMP_RESET
,"%s(): RegRxCounter is %d,RxCounter is %d\n",__FUNCTION__
,RegRxCounter
,priv
->RxCounter
);
3549 // If rssi is small, we should check rx for long time because of bad rx.
3550 // or maybe it will continuous silent reset every 2 seconds.
3552 if(priv
->undecorated_smoothed_pwdb
>= (RateAdaptiveTH_High
+5))
3554 rx_chk_cnt
= 0; //high rssi, check rx stuck right now.
3556 else if(priv
->undecorated_smoothed_pwdb
< (RateAdaptiveTH_High
+5) &&
3557 ((priv
->CurrentChannelBW
!=HT_CHANNEL_WIDTH_20
&&priv
->undecorated_smoothed_pwdb
>=RateAdaptiveTH_Low_40M
) ||
3558 (priv
->CurrentChannelBW
==HT_CHANNEL_WIDTH_20
&&priv
->undecorated_smoothed_pwdb
>=RateAdaptiveTH_Low_20M
)) )
3570 else if(((priv
->CurrentChannelBW
!=HT_CHANNEL_WIDTH_20
&&priv
->undecorated_smoothed_pwdb
<RateAdaptiveTH_Low_40M
) ||
3571 (priv
->CurrentChannelBW
==HT_CHANNEL_WIDTH_20
&&priv
->undecorated_smoothed_pwdb
<RateAdaptiveTH_Low_20M
)) &&
3572 priv
->undecorated_smoothed_pwdb
>= VeryLowRSSI
)
3576 //DbgPrint("RSSI < %d && RSSI >= %d, no check this time \n", RateAdaptiveTH_Low, VeryLowRSSI);
3582 //DbgPrint("RSSI < %d && RSSI >= %d, check this time \n", RateAdaptiveTH_Low, VeryLowRSSI);
3589 //DbgPrint("RSSI <= %d, no check this time \n", VeryLowRSSI);
3595 //DbgPrint("RSSI <= %d, check this time \n", VeryLowRSSI);
3598 if(priv
->RxCounter
==RegRxCounter
)
3601 priv
->RxCounter
= RegRxCounter
;
3606 static RESET_TYPE
RxCheckStuck(struct net_device
*dev
)
3609 if(HalRxCheckStuck8190Pci(dev
))
3611 RT_TRACE(COMP_RESET
, "RxStuck Condition\n");
3612 return RESET_TYPE_SILENT
;
3615 return RESET_TYPE_NORESET
;
3619 rtl819x_ifcheck_resetornot(struct net_device
*dev
)
3621 struct r8192_priv
*priv
= ieee80211_priv(dev
);
3622 RESET_TYPE TxResetType
= RESET_TYPE_NORESET
;
3623 RESET_TYPE RxResetType
= RESET_TYPE_NORESET
;
3624 RT_RF_POWER_STATE rfState
;
3626 rfState
= priv
->ieee80211
->eRFPowerState
;
3628 TxResetType
= TxCheckStuck(dev
);
3630 if( rfState
!= eRfOff
&&
3631 /*ADAPTER_TEST_STATUS_FLAG(Adapter, ADAPTER_STATUS_FW_DOWNLOAD_FAILURE)) &&*/
3632 (priv
->ieee80211
->iw_mode
!= IW_MODE_ADHOC
))
3634 // If driver is in the status of firmware download failure , driver skips RF initialization and RF is
3635 // in turned off state. Driver should check whether Rx stuck and do silent reset. And
3636 // if driver is in firmware download failure status, driver should initialize RF in the following
3637 // silent reset procedure Emily, 2008.01.21
3639 // Driver should not check RX stuck in IBSS mode because it is required to
3640 // set Check BSSID in order to send beacon, however, if check BSSID is
3641 // set, STA cannot hear any packet a all. Emily, 2008.04.12
3642 RxResetType
= RxCheckStuck(dev
);
3646 RT_TRACE(COMP_RESET
,"%s(): TxResetType is %d, RxResetType is %d\n",__FUNCTION__
,TxResetType
,RxResetType
);
3647 if(TxResetType
==RESET_TYPE_NORMAL
|| RxResetType
==RESET_TYPE_NORMAL
)
3648 return RESET_TYPE_NORMAL
;
3649 else if(TxResetType
==RESET_TYPE_SILENT
|| RxResetType
==RESET_TYPE_SILENT
)
3650 return RESET_TYPE_SILENT
;
3652 return RESET_TYPE_NORESET
;
3657 static void CamRestoreAllEntry(struct net_device
*dev
)
3660 struct r8192_priv
*priv
= ieee80211_priv(dev
);
3661 const u8
* MacAddr
= priv
->ieee80211
->current_network
.bssid
;
3663 static const u8 CAM_CONST_ADDR
[4][6] = {
3664 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
3665 {0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
3666 {0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
3667 {0x00, 0x00, 0x00, 0x00, 0x00, 0x03}};
3668 static const u8 CAM_CONST_BROAD
[] =
3669 {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
3671 RT_TRACE(COMP_SEC
, "CamRestoreAllEntry: \n");
3674 if ((priv
->ieee80211
->pairwise_key_type
== KEY_TYPE_WEP40
)||
3675 (priv
->ieee80211
->pairwise_key_type
== KEY_TYPE_WEP104
))
3678 for(EntryId
=0; EntryId
<4; EntryId
++)
3681 MacAddr
= CAM_CONST_ADDR
[EntryId
];
3685 priv
->ieee80211
->pairwise_key_type
,
3693 else if(priv
->ieee80211
->pairwise_key_type
== KEY_TYPE_TKIP
)
3697 if(priv
->ieee80211
->iw_mode
== IW_MODE_ADHOC
)
3701 priv
->ieee80211
->pairwise_key_type
,
3709 priv
->ieee80211
->pairwise_key_type
,
3715 else if(priv
->ieee80211
->pairwise_key_type
== KEY_TYPE_CCMP
)
3719 if(priv
->ieee80211
->iw_mode
== IW_MODE_ADHOC
)
3723 priv
->ieee80211
->pairwise_key_type
,
3731 priv
->ieee80211
->pairwise_key_type
,
3740 if(priv
->ieee80211
->group_key_type
== KEY_TYPE_TKIP
)
3742 MacAddr
= CAM_CONST_BROAD
;
3743 for(EntryId
=1 ; EntryId
<4 ; EntryId
++)
3749 priv
->ieee80211
->group_key_type
,
3755 if(priv
->ieee80211
->iw_mode
== IW_MODE_ADHOC
)
3759 priv
->ieee80211
->group_key_type
,
3764 else if(priv
->ieee80211
->group_key_type
== KEY_TYPE_CCMP
)
3766 MacAddr
= CAM_CONST_BROAD
;
3767 for(EntryId
=1; EntryId
<4 ; EntryId
++)
3773 priv
->ieee80211
->group_key_type
,
3780 if(priv
->ieee80211
->iw_mode
== IW_MODE_ADHOC
)
3784 priv
->ieee80211
->group_key_type
,
3792 * This function is used to fix Tx/Rx stop bug temporarily.
3793 * This function will do "system reset" to NIC when Tx or Rx is stuck.
3794 * The method checking Tx/Rx stuck of this function is supported by FW,
3795 * which reports Tx and Rx counter to register 0x128 and 0x130.
3797 static void rtl819x_ifsilentreset(struct net_device
*dev
)
3799 struct r8192_priv
*priv
= ieee80211_priv(dev
);
3801 int reset_status
= 0;
3802 struct ieee80211_device
*ieee
= priv
->ieee80211
;
3807 // 2007.07.20. If we need to check CCK stop, please uncomment this line.
3808 //bStuck = Adapter->HalFunc.CheckHWStopHandler(Adapter);
3810 if(priv
->ResetProgress
==RESET_TYPE_NORESET
)
3814 //LZM for PS-Poll AID issue. 090429
3815 if(priv
->ieee80211
->state
== IEEE80211_LINKED
)
3816 LeisurePSLeave(dev
);
3819 RT_TRACE(COMP_RESET
,"=========>Reset progress!! \n");
3821 // Set the variable for reset.
3822 priv
->ResetProgress
= RESET_TYPE_SILENT
;
3823 // rtl8192_close(dev);
3825 down(&priv
->wx_sem
);
3828 RT_TRACE(COMP_ERR
,"%s():the driver is not up! return\n",__FUNCTION__
);
3833 RT_TRACE(COMP_RESET
,"%s():======>start to down the driver\n",__FUNCTION__
);
3834 if(!netif_queue_stopped(dev
))
3835 netif_stop_queue(dev
);
3837 dm_backup_dynamic_mechanism_state(dev
);
3839 rtl8192_irq_disable(dev
);
3840 rtl8192_cancel_deferred_work(priv
);
3842 del_timer_sync(&priv
->watch_dog_timer
);
3843 ieee
->sync_scan_hurryup
= 1;
3844 if(ieee
->state
== IEEE80211_LINKED
)
3846 down(&ieee
->wx_sem
);
3847 printk("ieee->state is IEEE80211_LINKED\n");
3848 ieee80211_stop_send_beacons(priv
->ieee80211
);
3849 del_timer_sync(&ieee
->associate_timer
);
3850 cancel_delayed_work(&ieee
->associate_retry_wq
);
3851 ieee80211_stop_scan(ieee
);
3855 printk("ieee->state is NOT LINKED\n");
3856 ieee80211_softmac_stop_protocol(priv
->ieee80211
,true);
3858 rtl8192_halt_adapter(dev
, true);
3860 RT_TRACE(COMP_RESET
,"%s():<==========down process is finished\n",__FUNCTION__
);
3861 RT_TRACE(COMP_RESET
,"%s():===========>start to up the driver\n",__FUNCTION__
);
3862 reset_status
= _rtl8192_up(dev
);
3864 RT_TRACE(COMP_RESET
,"%s():<===========up process is finished\n",__FUNCTION__
);
3865 if(reset_status
== -1)
3874 RT_TRACE(COMP_ERR
," ERR!!! %s(): Reset Failed!!\n",__FUNCTION__
);
3878 ieee
->is_silent_reset
= 1;
3880 EnableHWSecurityConfig8192(dev
);
3882 if(ieee
->state
== IEEE80211_LINKED
&& ieee
->iw_mode
== IW_MODE_INFRA
)
3884 ieee
->set_chan(ieee
->dev
, ieee
->current_network
.channel
);
3887 queue_work(ieee
->wq
, &ieee
->associate_complete_wq
);
3891 else if(ieee
->state
== IEEE80211_LINKED
&& ieee
->iw_mode
== IW_MODE_ADHOC
)
3893 ieee
->set_chan(ieee
->dev
, ieee
->current_network
.channel
);
3894 ieee
->link_change(ieee
->dev
);
3896 // notify_wx_assoc_event(ieee);
3898 ieee80211_start_send_beacons(ieee
);
3900 if (ieee
->data_hard_resume
)
3901 ieee
->data_hard_resume(ieee
->dev
);
3902 netif_carrier_on(ieee
->dev
);
3906 CamRestoreAllEntry(dev
);
3908 // Restore the previous setting for all dynamic mechanism
3909 dm_restore_dynamic_mechanism_state(dev
);
3911 priv
->ResetProgress
= RESET_TYPE_NORESET
;
3912 priv
->reset_count
++;
3914 priv
->bForcedSilentReset
=false;
3915 priv
->bResetInProgress
= false;
3917 // For test --> force write UFWP.
3918 write_nic_byte(dev
, UFWP
, 1);
3919 RT_TRACE(COMP_RESET
, "Reset finished!! ====>[%d]\n", priv
->reset_count
);
3925 void InactivePsWorkItemCallback(struct net_device
*dev
)
3927 struct r8192_priv
*priv
= ieee80211_priv(dev
);
3928 PRT_POWER_SAVE_CONTROL pPSC
= (PRT_POWER_SAVE_CONTROL
)(&(priv
->ieee80211
->PowerSaveControl
));
3930 RT_TRACE(COMP_POWER
, "InactivePsWorkItemCallback() ---------> \n");
3932 // This flag "bSwRfProcessing", indicates the status of IPS procedure, should be set if the IPS workitem
3933 // is really scheduled.
3934 // The old code, sets this flag before scheduling the IPS workitem and however, at the same time the
3935 // previous IPS workitem did not end yet, fails to schedule the current workitem. Thus, bSwRfProcessing
3936 // blocks the IPS procedure of switching RF.
3937 // By Bruce, 2007-12-25.
3939 pPSC
->bSwRfProcessing
= TRUE
;
3941 RT_TRACE(COMP_RF
, "InactivePsWorkItemCallback(): Set RF to %s.\n",
3942 pPSC
->eInactivePowerState
== eRfOff
?"OFF":"ON");
3945 MgntActSet_RF_State(dev
, pPSC
->eInactivePowerState
, RF_CHANGE_BY_IPS
);
3948 // To solve CAM values miss in RF OFF, rewrite CAM values after RF ON. By Bruce, 2007-09-20.
3950 pPSC
->bSwRfProcessing
= FALSE
;
3951 RT_TRACE(COMP_POWER
, "InactivePsWorkItemCallback() <--------- \n");
3955 /* Change current and default preamble mode. */
3956 bool MgntActSet_802_11_PowerSaveMode(struct net_device
*dev
, u8 rtPsMode
)
3958 struct r8192_priv
*priv
= ieee80211_priv(dev
);
3960 // Currently, we do not change power save mode on IBSS mode.
3961 if(priv
->ieee80211
->iw_mode
== IW_MODE_ADHOC
)
3967 // <RJ_NOTE> If we make HW to fill up the PwrMgt bit for us,
3968 // some AP will not response to our mgnt frames with PwrMgt bit set,
3969 // e.g. cannot associate the AP.
3970 // So I commented out it. 2005.02.16, by rcnjko.
3972 // // Change device's power save mode.
3973 // Adapter->HalFunc.SetPSModeHandler( Adapter, rtPsMode );
3975 // Update power save mode configured.
3976 //RT_TRACE(COMP_LPS,"%s(): set ieee->ps = %x\n",__FUNCTION__,rtPsMode);
3977 if(!priv
->ps_force
) {
3978 priv
->ieee80211
->ps
= rtPsMode
;
3981 // Awake immediately
3982 if(priv
->ieee80211
->sta_sleep
!= 0 && rtPsMode
== IEEE80211_PS_DISABLED
)
3984 unsigned long flags
;
3986 //PlatformSetTimer(Adapter, &(pMgntInfo->AwakeTimer), 0);
3987 // Notify the AP we awke.
3988 rtl8192_hw_wakeup(dev
);
3989 priv
->ieee80211
->sta_sleep
= 0;
3991 spin_lock_irqsave(&(priv
->ieee80211
->mgmt_tx_lock
), flags
);
3992 printk("LPS leave: notify AP we are awaked ++++++++++ SendNullFunctionData\n");
3993 ieee80211_sta_ps_send_null_frame(priv
->ieee80211
, 0);
3994 spin_unlock_irqrestore(&(priv
->ieee80211
->mgmt_tx_lock
), flags
);
4000 /* Enter the leisure power save mode. */
4001 void LeisurePSEnter(struct net_device
*dev
)
4003 struct r8192_priv
*priv
= ieee80211_priv(dev
);
4004 PRT_POWER_SAVE_CONTROL pPSC
= (PRT_POWER_SAVE_CONTROL
)(&(priv
->ieee80211
->PowerSaveControl
));
4006 //RT_TRACE(COMP_PS, "LeisurePSEnter()...\n");
4007 //RT_TRACE(COMP_PS, "pPSC->bLeisurePs = %d, ieee->ps = %d,pPSC->LpsIdleCount is %d,RT_CHECK_FOR_HANG_PERIOD is %d\n",
4008 // pPSC->bLeisurePs, priv->ieee80211->ps,pPSC->LpsIdleCount,RT_CHECK_FOR_HANG_PERIOD);
4010 if(!((priv
->ieee80211
->iw_mode
== IW_MODE_INFRA
) &&
4011 (priv
->ieee80211
->state
== IEEE80211_LINKED
)) ||
4012 (priv
->ieee80211
->iw_mode
== IW_MODE_ADHOC
) ||
4013 (priv
->ieee80211
->iw_mode
== IW_MODE_MASTER
))
4016 if (pPSC
->bLeisurePs
)
4018 // Idle for a while if we connect to AP a while ago.
4019 if(pPSC
->LpsIdleCount
>= RT_CHECK_FOR_HANG_PERIOD
) // 4 Sec
4022 if(priv
->ieee80211
->ps
== IEEE80211_PS_DISABLED
)
4025 //RT_TRACE(COMP_LPS, "LeisurePSEnter(): Enter 802.11 power save mode...\n");
4026 MgntActSet_802_11_PowerSaveMode(dev
, IEEE80211_PS_MBCAST
|IEEE80211_PS_UNICAST
);
4031 pPSC
->LpsIdleCount
++;
4036 /* Leave leisure power save mode. */
4037 void LeisurePSLeave(struct net_device
*dev
)
4039 struct r8192_priv
*priv
= ieee80211_priv(dev
);
4040 PRT_POWER_SAVE_CONTROL pPSC
= (PRT_POWER_SAVE_CONTROL
)(&(priv
->ieee80211
->PowerSaveControl
));
4042 if (pPSC
->bLeisurePs
)
4044 if(priv
->ieee80211
->ps
!= IEEE80211_PS_DISABLED
)
4046 // move to lps_wakecomplete()
4047 //RT_TRACE(COMP_LPS, "LeisurePSLeave(): Busy Traffic , Leave 802.11 power save..\n");
4048 MgntActSet_802_11_PowerSaveMode(dev
, IEEE80211_PS_DISABLED
);
4056 /* Enter the inactive power save mode. RF will be off */
4058 IPSEnter(struct net_device
*dev
)
4060 struct r8192_priv
*priv
= ieee80211_priv(dev
);
4061 PRT_POWER_SAVE_CONTROL pPSC
= (PRT_POWER_SAVE_CONTROL
)(&(priv
->ieee80211
->PowerSaveControl
));
4062 RT_RF_POWER_STATE rtState
;
4064 if (pPSC
->bInactivePs
)
4066 rtState
= priv
->ieee80211
->eRFPowerState
;
4068 // Added by Bruce, 2007-12-25.
4069 // Do not enter IPS in the following conditions:
4070 // (1) RF is already OFF or Sleep
4071 // (2) bSwRfProcessing (indicates the IPS is still under going)
4072 // (3) Connectted (only disconnected can trigger IPS)
4073 // (4) IBSS (send Beacon)
4074 // (5) AP mode (send Beacon)
4076 if (rtState
== eRfOn
&& !pPSC
->bSwRfProcessing
4077 && (priv
->ieee80211
->state
!= IEEE80211_LINKED
) )
4079 RT_TRACE(COMP_RF
,"IPSEnter(): Turn off RF.\n");
4080 //printk("IPSEnter(): Turn off RF.\n");
4081 pPSC
->eInactivePowerState
= eRfOff
;
4082 // queue_work(priv->priv_wq,&(pPSC->InactivePsWorkItem));
4083 InactivePsWorkItemCallback(dev
);
4090 // Leave the inactive power save mode, RF will be on.
4091 // 2007.08.17, by shien chang.
4094 IPSLeave(struct net_device
*dev
)
4096 struct r8192_priv
*priv
= ieee80211_priv(dev
);
4097 PRT_POWER_SAVE_CONTROL pPSC
= (PRT_POWER_SAVE_CONTROL
)(&(priv
->ieee80211
->PowerSaveControl
));
4098 RT_RF_POWER_STATE rtState
;
4100 if (pPSC
->bInactivePs
)
4102 rtState
= priv
->ieee80211
->eRFPowerState
;
4103 if (rtState
!= eRfOn
&& !pPSC
->bSwRfProcessing
&& priv
->ieee80211
->RfOffReason
<= RF_CHANGE_BY_IPS
)
4105 RT_TRACE(COMP_POWER
, "IPSLeave(): Turn on RF.\n");
4106 //printk("IPSLeave(): Turn on RF.\n");
4107 pPSC
->eInactivePowerState
= eRfOn
;
4108 // queue_work(priv->priv_wq,&(pPSC->InactivePsWorkItem));
4109 InactivePsWorkItemCallback(dev
);
4114 void IPSLeave_wq(void *data
)
4116 struct ieee80211_device
*ieee
= container_of(data
,struct ieee80211_device
,ips_leave_wq
);
4117 struct net_device
*dev
= ieee
->dev
;
4119 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
4120 down(&priv
->ieee80211
->ips_sem
);
4122 up(&priv
->ieee80211
->ips_sem
);
4125 void ieee80211_ips_leave_wq(struct net_device
*dev
)
4127 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
4128 RT_RF_POWER_STATE rtState
;
4129 rtState
= priv
->ieee80211
->eRFPowerState
;
4131 if(priv
->ieee80211
->PowerSaveControl
.bInactivePs
){
4132 if(rtState
== eRfOff
){
4133 if(priv
->ieee80211
->RfOffReason
> RF_CHANGE_BY_IPS
)
4135 RT_TRACE(COMP_ERR
, "%s(): RF is OFF.\n",__FUNCTION__
);
4139 printk("=========>%s(): IPSLeave\n",__FUNCTION__
);
4140 queue_work(priv
->ieee80211
->wq
,&priv
->ieee80211
->ips_leave_wq
);
4145 //added by amy 090331 end
4146 void ieee80211_ips_leave(struct net_device
*dev
)
4148 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
4149 down(&priv
->ieee80211
->ips_sem
);
4151 up(&priv
->ieee80211
->ips_sem
);
4155 static void rtl819x_update_rxcounts(
4156 struct r8192_priv
*priv
,
4165 *TotalRxDataNum
= 0;
4167 SlotIndex
= (priv
->ieee80211
->LinkDetectInfo
.SlotIndex
++)%(priv
->ieee80211
->LinkDetectInfo
.SlotNum
);
4168 priv
->ieee80211
->LinkDetectInfo
.RxBcnNum
[SlotIndex
] = priv
->ieee80211
->LinkDetectInfo
.NumRecvBcnInPeriod
;
4169 priv
->ieee80211
->LinkDetectInfo
.RxDataNum
[SlotIndex
] = priv
->ieee80211
->LinkDetectInfo
.NumRecvDataInPeriod
;
4170 for( i
=0; i
<priv
->ieee80211
->LinkDetectInfo
.SlotNum
; i
++ ){
4171 *TotalRxBcnNum
+= priv
->ieee80211
->LinkDetectInfo
.RxBcnNum
[i
];
4172 *TotalRxDataNum
+= priv
->ieee80211
->LinkDetectInfo
.RxDataNum
[i
];
4177 static void rtl819x_watchdog_wqcallback(struct work_struct
*work
)
4179 struct delayed_work
*dwork
= container_of(work
,struct delayed_work
,work
);
4180 struct r8192_priv
*priv
= container_of(dwork
,struct r8192_priv
,watch_dog_wq
);
4181 struct net_device
*dev
= priv
->ieee80211
->dev
;
4182 struct ieee80211_device
* ieee
= priv
->ieee80211
;
4183 RESET_TYPE ResetType
= RESET_TYPE_NORESET
;
4184 static u8 check_reset_cnt
=0;
4185 unsigned long flags
;
4186 bool bBusyTraffic
= false;
4187 static u8 last_time
= 0;
4188 bool bEnterPS
= false;
4190 if ((!priv
->up
) || priv
->bHwRadioOff
)
4195 hal_dm_watchdog(dev
);
4197 // printk("watch_dog ENABLE_IPS\n");
4198 if(ieee
->actscanning
== false){
4199 //printk("%d,%d,%d,%d\n", ieee->eRFPowerState, ieee->is_set_key, ieee->proto_stoppping, ieee->wx_set_enc);
4200 if((ieee
->iw_mode
== IW_MODE_INFRA
) && (ieee
->state
== IEEE80211_NOLINK
) &&
4201 (ieee
->eRFPowerState
== eRfOn
)&&!ieee
->is_set_key
&&
4202 (!ieee
->proto_stoppping
) && !ieee
->wx_set_enc
){
4203 if(ieee
->PowerSaveControl
.ReturnPoint
== IPS_CALLBACK_NONE
){
4204 //printk("====================>haha:IPSEnter()\n");
4206 //ieee80211_stop_scan(priv->ieee80211);
4211 {//to get busy traffic condition
4212 if(ieee
->state
== IEEE80211_LINKED
)
4214 if( ieee
->LinkDetectInfo
.NumRxOkInPeriod
> 100 ||
4215 ieee
->LinkDetectInfo
.NumTxOkInPeriod
> 100 ) {
4216 bBusyTraffic
= true;
4220 //added by amy for Leisure PS
4221 if( ((ieee
->LinkDetectInfo
.NumRxUnicastOkInPeriod
+ ieee
->LinkDetectInfo
.NumTxOkInPeriod
) > 8 ) ||
4222 (ieee
->LinkDetectInfo
.NumRxUnicastOkInPeriod
> 2) )
4224 //printk("ieee->LinkDetectInfo.NumRxUnicastOkInPeriod is %d,ieee->LinkDetectInfo.NumTxOkInPeriod is %d\n",
4225 // ieee->LinkDetectInfo.NumRxUnicastOkInPeriod,ieee->LinkDetectInfo.NumTxOkInPeriod);
4233 //printk("***bEnterPS = %d\n", bEnterPS);
4234 // LeisurePS only work in infra mode.
4237 LeisurePSEnter(dev
);
4241 LeisurePSLeave(dev
);
4249 //RT_TRACE(COMP_LPS,"====>no link LPS leave\n");
4250 LeisurePSLeave(dev
);
4254 ieee
->LinkDetectInfo
.NumRxOkInPeriod
= 0;
4255 ieee
->LinkDetectInfo
.NumTxOkInPeriod
= 0;
4256 ieee
->LinkDetectInfo
.NumRxUnicastOkInPeriod
= 0;
4257 ieee
->LinkDetectInfo
.bBusyTraffic
= bBusyTraffic
;
4261 //added by amy for AP roaming
4264 if(ieee
->state
== IEEE80211_LINKED
&& ieee
->iw_mode
== IW_MODE_INFRA
)
4266 u32 TotalRxBcnNum
= 0;
4267 u32 TotalRxDataNum
= 0;
4269 rtl819x_update_rxcounts(priv
, &TotalRxBcnNum
, &TotalRxDataNum
);
4270 if((TotalRxBcnNum
+TotalRxDataNum
) == 0)
4272 if( ieee
->eRFPowerState
== eRfOff
)
4273 RT_TRACE(COMP_ERR
,"========>%s()\n",__FUNCTION__
);
4274 printk("===>%s(): AP is power off,connect another one\n",__FUNCTION__
);
4275 // Dot11d_Reset(dev);
4276 ieee
->state
= IEEE80211_ASSOCIATING
;
4277 notify_wx_assoc_event(priv
->ieee80211
);
4278 RemovePeerTS(priv
->ieee80211
,priv
->ieee80211
->current_network
.bssid
);
4279 ieee
->is_roaming
= true;
4280 ieee
->is_set_key
= false;
4281 ieee
->link_change(dev
);
4282 queue_work(ieee
->wq
, &ieee
->associate_procedure_wq
);
4285 ieee
->LinkDetectInfo
.NumRecvBcnInPeriod
=0;
4286 ieee
->LinkDetectInfo
.NumRecvDataInPeriod
=0;
4289 //check if reset the driver
4290 spin_lock_irqsave(&priv
->tx_lock
,flags
);
4291 if(check_reset_cnt
++ >= 3 && !ieee
->is_roaming
&& (last_time
!= 1))
4293 ResetType
= rtl819x_ifcheck_resetornot(dev
);
4294 check_reset_cnt
= 3;
4295 //DbgPrint("Start to check silent reset\n");
4297 spin_unlock_irqrestore(&priv
->tx_lock
,flags
);
4298 if(!priv
->bDisableNormalResetCheck
&& ResetType
== RESET_TYPE_NORMAL
)
4300 priv
->ResetProgress
= RESET_TYPE_NORMAL
;
4301 RT_TRACE(COMP_RESET
,"%s(): NOMAL RESET\n",__FUNCTION__
);
4304 /* disable silent reset temply 2008.9.11*/
4306 if( ((priv
->force_reset
) || (!priv
->bDisableNormalResetCheck
&& ResetType
==RESET_TYPE_SILENT
))) // This is control by OID set in Pomelo
4309 rtl819x_ifsilentreset(dev
);
4314 priv
->force_reset
= false;
4315 priv
->bForcedSilentReset
= false;
4316 priv
->bResetInProgress
= false;
4317 RT_TRACE(COMP_TRACE
, " <==RtUsbCheckForHangWorkItemCallback()\n");
4321 void watch_dog_timer_callback(unsigned long data
)
4323 struct r8192_priv
*priv
= ieee80211_priv((struct net_device
*) data
);
4324 queue_delayed_work(priv
->priv_wq
,&priv
->watch_dog_wq
,0);
4325 mod_timer(&priv
->watch_dog_timer
, jiffies
+ MSECS(IEEE80211_WATCH_DOG_TIME
));
4329 static int _rtl8192_up(struct net_device
*dev
)
4331 struct r8192_priv
*priv
= ieee80211_priv(dev
);
4333 RT_STATUS init_status
= RT_STATUS_SUCCESS
;
4335 priv
->ieee80211
->ieee_up
=1;
4336 priv
->bdisable_nic
= false; //YJ,add,091111
4337 RT_TRACE(COMP_INIT
, "Bringing up iface");
4339 init_status
= rtl8192_adapter_start(dev
);
4340 if(init_status
!= RT_STATUS_SUCCESS
)
4342 RT_TRACE(COMP_ERR
,"ERR!!! %s(): initialization is failed!\n",__FUNCTION__
);
4345 RT_TRACE(COMP_INIT
, "start adapter finished\n");
4347 if(priv
->ieee80211
->eRFPowerState
!=eRfOn
)
4348 MgntActSet_RF_State(dev
, eRfOn
, priv
->ieee80211
->RfOffReason
);
4350 if(priv
->ieee80211
->state
!= IEEE80211_LINKED
)
4351 ieee80211_softmac_start_protocol(priv
->ieee80211
);
4352 ieee80211_reset_queue(priv
->ieee80211
);
4353 watch_dog_timer_callback((unsigned long) dev
);
4354 if(!netif_queue_stopped(dev
))
4355 netif_start_queue(dev
);
4357 netif_wake_queue(dev
);
4363 static int rtl8192_open(struct net_device
*dev
)
4365 struct r8192_priv
*priv
= ieee80211_priv(dev
);
4368 down(&priv
->wx_sem
);
4369 ret
= rtl8192_up(dev
);
4376 int rtl8192_up(struct net_device
*dev
)
4378 struct r8192_priv
*priv
= ieee80211_priv(dev
);
4380 if (priv
->up
== 1) return -1;
4382 return _rtl8192_up(dev
);
4386 static int rtl8192_close(struct net_device
*dev
)
4388 struct r8192_priv
*priv
= ieee80211_priv(dev
);
4391 down(&priv
->wx_sem
);
4393 ret
= rtl8192_down(dev
);
4401 int rtl8192_down(struct net_device
*dev
)
4403 struct r8192_priv
*priv
= ieee80211_priv(dev
);
4405 if (priv
->up
== 0) return -1;
4408 //LZM for PS-Poll AID issue. 090429
4409 if(priv
->ieee80211
->state
== IEEE80211_LINKED
)
4410 LeisurePSLeave(dev
);
4414 priv
->ieee80211
->ieee_up
= 0;
4415 RT_TRACE(COMP_DOWN
, "==========>%s()\n", __FUNCTION__
);
4417 if (!netif_queue_stopped(dev
))
4418 netif_stop_queue(dev
);
4420 rtl8192_irq_disable(dev
);
4421 rtl8192_cancel_deferred_work(priv
);
4423 del_timer_sync(&priv
->watch_dog_timer
);
4425 ieee80211_softmac_stop_protocol(priv
->ieee80211
,true);
4427 rtl8192_halt_adapter(dev
,false);
4428 memset(&priv
->ieee80211
->current_network
, 0 , offsetof(struct ieee80211_network
, list
));
4430 RT_TRACE(COMP_DOWN
, "<==========%s()\n", __FUNCTION__
);
4436 void rtl8192_commit(struct net_device
*dev
)
4438 struct r8192_priv
*priv
= ieee80211_priv(dev
);
4440 if (priv
->up
== 0) return ;
4443 ieee80211_softmac_stop_protocol(priv
->ieee80211
,true);
4445 rtl8192_irq_disable(dev
);
4446 rtl8192_halt_adapter(dev
,true);
4450 static void rtl8192_restart(struct work_struct
*work
)
4452 struct r8192_priv
*priv
= container_of(work
, struct r8192_priv
, reset_wq
);
4453 struct net_device
*dev
= priv
->ieee80211
->dev
;
4455 down(&priv
->wx_sem
);
4457 rtl8192_commit(dev
);
4462 static void r8192_set_multicast(struct net_device
*dev
)
4464 struct r8192_priv
*priv
= ieee80211_priv(dev
);
4467 //down(&priv->wx_sem);
4471 promisc
= (dev
->flags
& IFF_PROMISC
) ? 1:0;
4473 if (promisc
!= priv
->promisc
) {
4475 // rtl8192_commit(dev);
4478 priv
->promisc
= promisc
;
4480 //schedule_work(&priv->reset_wq);
4481 //up(&priv->wx_sem);
4485 static int r8192_set_mac_adr(struct net_device
*dev
, void *mac
)
4487 struct r8192_priv
*priv
= ieee80211_priv(dev
);
4488 struct sockaddr
*addr
= mac
;
4490 down(&priv
->wx_sem
);
4492 memcpy(dev
->dev_addr
, addr
->sa_data
, ETH_ALEN
);
4494 schedule_work(&priv
->reset_wq
);
4500 /* based on ipw2200 driver */
4501 static int rtl8192_ioctl(struct net_device
*dev
, struct ifreq
*rq
, int cmd
)
4503 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
4504 struct iwreq
*wrq
= (struct iwreq
*)rq
;
4506 struct ieee80211_device
*ieee
= priv
->ieee80211
;
4508 u8 broadcast_addr
[6] = {0xff,0xff,0xff,0xff,0xff,0xff};
4509 struct iw_point
*p
= &wrq
->u
.data
;
4510 struct ieee_param
*ipw
= NULL
;//(struct ieee_param *)wrq->u.data.pointer;
4512 down(&priv
->wx_sem
);
4515 if (p
->length
< sizeof(struct ieee_param
) || !p
->pointer
){
4520 ipw
= kmalloc(p
->length
, GFP_KERNEL
);
4525 if (copy_from_user(ipw
, p
->pointer
, p
->length
)) {
4532 case RTL_IOCTL_WPA_SUPPLICANT
:
4533 //parse here for HW security
4534 if (ipw
->cmd
== IEEE_CMD_SET_ENCRYPTION
)
4536 if (ipw
->u
.crypt
.set_tx
)
4538 if (strcmp(ipw
->u
.crypt
.alg
, "CCMP") == 0)
4539 ieee
->pairwise_key_type
= KEY_TYPE_CCMP
;
4540 else if (strcmp(ipw
->u
.crypt
.alg
, "TKIP") == 0)
4541 ieee
->pairwise_key_type
= KEY_TYPE_TKIP
;
4542 else if (strcmp(ipw
->u
.crypt
.alg
, "WEP") == 0)
4544 if (ipw
->u
.crypt
.key_len
== 13)
4545 ieee
->pairwise_key_type
= KEY_TYPE_WEP104
;
4546 else if (ipw
->u
.crypt
.key_len
== 5)
4547 ieee
->pairwise_key_type
= KEY_TYPE_WEP40
;
4550 ieee
->pairwise_key_type
= KEY_TYPE_NA
;
4552 if (ieee
->pairwise_key_type
)
4554 memcpy((u8
*)key
, ipw
->u
.crypt
.key
, 16);
4555 EnableHWSecurityConfig8192(dev
);
4556 //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!
4558 setKey(dev
, 4, ipw
->u
.crypt
.idx
, ieee
->pairwise_key_type
, (u8
*)ieee
->ap_mac_addr
, 0, key
);
4559 if (ieee
->auth_mode
!= 2) //LEAP WEP will never set this.
4560 setKey(dev
, ipw
->u
.crypt
.idx
, ipw
->u
.crypt
.idx
, ieee
->pairwise_key_type
, (u8
*)ieee
->ap_mac_addr
, 0, key
);
4562 if ((ieee
->pairwise_key_type
== KEY_TYPE_CCMP
) && ieee
->pHTInfo
->bCurrentHTSupport
){
4563 write_nic_byte(dev
, 0x173, 1); //fix aes bug
4567 else //if (ipw->u.crypt.idx) //group key use idx > 0
4569 memcpy((u8
*)key
, ipw
->u
.crypt
.key
, 16);
4570 if (strcmp(ipw
->u
.crypt
.alg
, "CCMP") == 0)
4571 ieee
->group_key_type
= KEY_TYPE_CCMP
;
4572 else if (strcmp(ipw
->u
.crypt
.alg
, "TKIP") == 0)
4573 ieee
->group_key_type
= KEY_TYPE_TKIP
;
4574 else if (strcmp(ipw
->u
.crypt
.alg
, "WEP") == 0)
4576 if (ipw
->u
.crypt
.key_len
== 13)
4577 ieee
->group_key_type
= KEY_TYPE_WEP104
;
4578 else if (ipw
->u
.crypt
.key_len
== 5)
4579 ieee
->group_key_type
= KEY_TYPE_WEP40
;
4582 ieee
->group_key_type
= KEY_TYPE_NA
;
4584 if (ieee
->group_key_type
)
4588 ipw
->u
.crypt
.idx
, //KeyIndex
4589 ieee
->group_key_type
, //KeyType
4590 broadcast_addr
, //MacAddr
4596 ret
= ieee80211_wpa_supplicant_ioctl(priv
->ieee80211
, &wrq
->u
.data
);
4611 static u8
HwRateToMRate90(bool bIsHT
, u8 rate
)
4617 case DESC90_RATE1M
: ret_rate
= MGN_1M
; break;
4618 case DESC90_RATE2M
: ret_rate
= MGN_2M
; break;
4619 case DESC90_RATE5_5M
: ret_rate
= MGN_5_5M
; break;
4620 case DESC90_RATE11M
: ret_rate
= MGN_11M
; break;
4621 case DESC90_RATE6M
: ret_rate
= MGN_6M
; break;
4622 case DESC90_RATE9M
: ret_rate
= MGN_9M
; break;
4623 case DESC90_RATE12M
: ret_rate
= MGN_12M
; break;
4624 case DESC90_RATE18M
: ret_rate
= MGN_18M
; break;
4625 case DESC90_RATE24M
: ret_rate
= MGN_24M
; break;
4626 case DESC90_RATE36M
: ret_rate
= MGN_36M
; break;
4627 case DESC90_RATE48M
: ret_rate
= MGN_48M
; break;
4628 case DESC90_RATE54M
: ret_rate
= MGN_54M
; break;
4631 RT_TRACE(COMP_RECV
, "HwRateToMRate90(): Non supported Rate [%x], bIsHT = %d!!!\n", rate
, bIsHT
);
4637 case DESC90_RATEMCS0
: ret_rate
= MGN_MCS0
; break;
4638 case DESC90_RATEMCS1
: ret_rate
= MGN_MCS1
; break;
4639 case DESC90_RATEMCS2
: ret_rate
= MGN_MCS2
; break;
4640 case DESC90_RATEMCS3
: ret_rate
= MGN_MCS3
; break;
4641 case DESC90_RATEMCS4
: ret_rate
= MGN_MCS4
; break;
4642 case DESC90_RATEMCS5
: ret_rate
= MGN_MCS5
; break;
4643 case DESC90_RATEMCS6
: ret_rate
= MGN_MCS6
; break;
4644 case DESC90_RATEMCS7
: ret_rate
= MGN_MCS7
; break;
4645 case DESC90_RATEMCS8
: ret_rate
= MGN_MCS8
; break;
4646 case DESC90_RATEMCS9
: ret_rate
= MGN_MCS9
; break;
4647 case DESC90_RATEMCS10
: ret_rate
= MGN_MCS10
; break;
4648 case DESC90_RATEMCS11
: ret_rate
= MGN_MCS11
; break;
4649 case DESC90_RATEMCS12
: ret_rate
= MGN_MCS12
; break;
4650 case DESC90_RATEMCS13
: ret_rate
= MGN_MCS13
; break;
4651 case DESC90_RATEMCS14
: ret_rate
= MGN_MCS14
; break;
4652 case DESC90_RATEMCS15
: ret_rate
= MGN_MCS15
; break;
4653 case DESC90_RATEMCS32
: ret_rate
= (0x80|0x20); break;
4656 RT_TRACE(COMP_RECV
, "HwRateToMRate90(): Non supported Rate [%x], bIsHT = %d!!!\n",rate
, bIsHT
);
4664 /* Record the TSF time stamp when receiving a packet */
4665 static void UpdateRxPktTimeStamp8190 (struct net_device
*dev
, struct ieee80211_rx_stats
*stats
)
4667 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
4669 if(stats
->bIsAMPDU
&& !stats
->bFirstMPDU
) {
4670 stats
->mac_time
[0] = priv
->LastRxDescTSFLow
;
4671 stats
->mac_time
[1] = priv
->LastRxDescTSFHigh
;
4673 priv
->LastRxDescTSFLow
= stats
->mac_time
[0];
4674 priv
->LastRxDescTSFHigh
= stats
->mac_time
[1];
4678 static long rtl819x_translate_todbm(u8 signal_strength_index
)// 0-100 index.
4680 long signal_power
; // in dBm.
4682 // Translate to dBm (x=0.5y-95).
4683 signal_power
= (long)((signal_strength_index
+ 1) >> 1);
4686 return signal_power
;
4690 * Update Rx signal related information in the packet reeived
4691 * to RxStats. User application can query RxStats to realize
4692 * current Rx signal status.
4694 * In normal operation, user only care about the information of the BSS
4695 * and we shall invoke this function if the packet received is from the BSS.
4698 rtl819x_update_rxsignalstatistics8190pci(
4699 struct r8192_priv
* priv
,
4700 struct ieee80211_rx_stats
* pprevious_stats
4705 //2 <ToDo> Update Rx Statistics (such as signal strength and signal quality).
4708 if(priv
->stats
.recv_signal_power
== 0)
4709 priv
->stats
.recv_signal_power
= pprevious_stats
->RecvSignalPower
;
4711 // To avoid the past result restricting the statistics sensitivity, weight the current power (5/6) to speed up the
4712 // reaction of smoothed Signal Power.
4713 if(pprevious_stats
->RecvSignalPower
> priv
->stats
.recv_signal_power
)
4715 else if(pprevious_stats
->RecvSignalPower
< priv
->stats
.recv_signal_power
)
4718 // We need more correct power of received packets and the "SignalStrength" of RxStats have been beautified or translated,
4719 // so we record the correct power in Dbm here. By Bruce, 2008-03-07.
4721 priv
->stats
.recv_signal_power
= (priv
->stats
.recv_signal_power
* 5 + pprevious_stats
->RecvSignalPower
+ weighting
) / 6;
4725 rtl8190_process_cck_rxpathsel(
4726 struct r8192_priv
* priv
,
4727 struct ieee80211_rx_stats
* pprevious_stats
4730 #ifdef RTL8190P //Only 90P 2T4R need to check
4731 char last_cck_adc_pwdb
[4]={0,0,0,0};
4733 //cosa add for Rx path selection
4734 if(priv
->rf_type
== RF_2T4R
&& DM_RxPathSelTable
.Enable
)
4736 if(pprevious_stats
->bIsCCK
&&
4737 (pprevious_stats
->bPacketToSelf
||pprevious_stats
->bPacketBeacon
))
4739 /* record the cck adc_pwdb to the sliding window. */
4740 if(priv
->stats
.cck_adc_pwdb
.TotalNum
++ >= PHY_RSSI_SLID_WIN_MAX
)
4742 priv
->stats
.cck_adc_pwdb
.TotalNum
= PHY_RSSI_SLID_WIN_MAX
;
4743 for(i
=RF90_PATH_A
; i
<RF90_PATH_MAX
; i
++)
4745 last_cck_adc_pwdb
[i
] = priv
->stats
.cck_adc_pwdb
.elements
[i
][priv
->stats
.cck_adc_pwdb
.index
];
4746 priv
->stats
.cck_adc_pwdb
.TotalVal
[i
] -= last_cck_adc_pwdb
[i
];
4749 for(i
=RF90_PATH_A
; i
<RF90_PATH_MAX
; i
++)
4751 priv
->stats
.cck_adc_pwdb
.TotalVal
[i
] += pprevious_stats
->cck_adc_pwdb
[i
];
4752 priv
->stats
.cck_adc_pwdb
.elements
[i
][priv
->stats
.cck_adc_pwdb
.index
] = pprevious_stats
->cck_adc_pwdb
[i
];
4754 priv
->stats
.cck_adc_pwdb
.index
++;
4755 if(priv
->stats
.cck_adc_pwdb
.index
>= PHY_RSSI_SLID_WIN_MAX
)
4756 priv
->stats
.cck_adc_pwdb
.index
= 0;
4758 for(i
=RF90_PATH_A
; i
<RF90_PATH_MAX
; i
++)
4760 DM_RxPathSelTable
.cck_pwdb_sta
[i
] = priv
->stats
.cck_adc_pwdb
.TotalVal
[i
]/priv
->stats
.cck_adc_pwdb
.TotalNum
;
4763 for(i
=RF90_PATH_A
; i
<RF90_PATH_MAX
; i
++)
4765 if(pprevious_stats
->cck_adc_pwdb
[i
] > (char)priv
->undecorated_smoothed_cck_adc_pwdb
[i
])
4767 priv
->undecorated_smoothed_cck_adc_pwdb
[i
] =
4768 ( (priv
->undecorated_smoothed_cck_adc_pwdb
[i
]*(Rx_Smooth_Factor
-1)) +
4769 (pprevious_stats
->cck_adc_pwdb
[i
])) /(Rx_Smooth_Factor
);
4770 priv
->undecorated_smoothed_cck_adc_pwdb
[i
] = priv
->undecorated_smoothed_cck_adc_pwdb
[i
] + 1;
4774 priv
->undecorated_smoothed_cck_adc_pwdb
[i
] =
4775 ( (priv
->undecorated_smoothed_cck_adc_pwdb
[i
]*(Rx_Smooth_Factor
-1)) +
4776 (pprevious_stats
->cck_adc_pwdb
[i
])) /(Rx_Smooth_Factor
);
4785 /* 2008/01/22 MH We can not delcare RSSI/EVM total value of sliding window to
4786 be a local static. Otherwise, it may increase when we return from S3/S4. The
4787 value will be kept in memory or disk. We must delcare the value in adapter
4788 and it will be reinitialized when return from S3/S4. */
4789 static void rtl8192_process_phyinfo(struct r8192_priv
* priv
, u8
* buffer
,struct ieee80211_rx_stats
* pprevious_stats
, struct ieee80211_rx_stats
* pcurrent_stats
)
4791 bool bcheck
= false;
4793 u32 nspatial_stream
, tmp_val
;
4795 static u32 slide_rssi_index
=0, slide_rssi_statistics
=0;
4796 static u32 slide_evm_index
=0, slide_evm_statistics
=0;
4797 static u32 last_rssi
=0, last_evm
=0;
4798 //cosa add for rx path selection
4799 // static long slide_cck_adc_pwdb_index=0, slide_cck_adc_pwdb_statistics=0;
4800 // static char last_cck_adc_pwdb[4]={0,0,0,0};
4801 //cosa add for beacon rssi smoothing
4802 static u32 slide_beacon_adc_pwdb_index
=0, slide_beacon_adc_pwdb_statistics
=0;
4803 static u32 last_beacon_adc_pwdb
=0;
4805 struct ieee80211_hdr_3addr
*hdr
;
4807 unsigned int frag
,seq
;
4808 hdr
= (struct ieee80211_hdr_3addr
*)buffer
;
4809 sc
= le16_to_cpu(hdr
->seq_ctl
);
4810 frag
= WLAN_GET_SEQ_FRAG(sc
);
4811 seq
= WLAN_GET_SEQ_SEQ(sc
);
4812 //cosa add 04292008 to record the sequence number
4813 pcurrent_stats
->Seq_Num
= seq
;
4815 // Check whether we should take the previous packet into accounting
4817 if(!pprevious_stats
->bIsAMPDU
)
4819 // if previous packet is not aggregated packet
4823 if(slide_rssi_statistics
++ >= PHY_RSSI_SLID_WIN_MAX
)
4825 slide_rssi_statistics
= PHY_RSSI_SLID_WIN_MAX
;
4826 last_rssi
= priv
->stats
.slide_signal_strength
[slide_rssi_index
];
4827 priv
->stats
.slide_rssi_total
-= last_rssi
;
4829 priv
->stats
.slide_rssi_total
+= pprevious_stats
->SignalStrength
;
4831 priv
->stats
.slide_signal_strength
[slide_rssi_index
++] = pprevious_stats
->SignalStrength
;
4832 if(slide_rssi_index
>= PHY_RSSI_SLID_WIN_MAX
)
4833 slide_rssi_index
= 0;
4835 // <1> Showed on UI for user, in dbm
4836 tmp_val
= priv
->stats
.slide_rssi_total
/slide_rssi_statistics
;
4837 priv
->stats
.signal_strength
= rtl819x_translate_todbm((u8
)tmp_val
);
4838 pcurrent_stats
->rssi
= priv
->stats
.signal_strength
;
4840 // If the previous packet does not match the criteria, neglect it
4842 if(!pprevious_stats
->bPacketMatchBSSID
)
4844 if(!pprevious_stats
->bToSelfBA
)
4851 rtl8190_process_cck_rxpathsel(priv
,pprevious_stats
);
4856 priv
->stats
.num_process_phyinfo
++;
4858 // <2> Showed on UI for engineering
4859 // hardware does not provide rssi information for each rf path in CCK
4860 if(!pprevious_stats
->bIsCCK
&& pprevious_stats
->bPacketToSelf
)
4862 for (rfpath
= RF90_PATH_A
; rfpath
< RF90_PATH_C
; rfpath
++)
4864 if (!rtl8192_phy_CheckIsLegalRFPath(priv
->ieee80211
->dev
, rfpath
))
4866 RT_TRACE(COMP_DBG
,"Jacken -> pPreviousstats->RxMIMOSignalStrength[rfpath] = %d \n" ,pprevious_stats
->RxMIMOSignalStrength
[rfpath
] );
4867 //Fixed by Jacken 2008-03-20
4868 if(priv
->stats
.rx_rssi_percentage
[rfpath
] == 0)
4870 priv
->stats
.rx_rssi_percentage
[rfpath
] = pprevious_stats
->RxMIMOSignalStrength
[rfpath
];
4871 //DbgPrint("MIMO RSSI initialize \n");
4873 if(pprevious_stats
->RxMIMOSignalStrength
[rfpath
] > priv
->stats
.rx_rssi_percentage
[rfpath
])
4875 priv
->stats
.rx_rssi_percentage
[rfpath
] =
4876 ( (priv
->stats
.rx_rssi_percentage
[rfpath
]*(Rx_Smooth_Factor
-1)) +
4877 (pprevious_stats
->RxMIMOSignalStrength
[rfpath
])) /(Rx_Smooth_Factor
);
4878 priv
->stats
.rx_rssi_percentage
[rfpath
] = priv
->stats
.rx_rssi_percentage
[rfpath
] + 1;
4882 priv
->stats
.rx_rssi_percentage
[rfpath
] =
4883 ( (priv
->stats
.rx_rssi_percentage
[rfpath
]*(Rx_Smooth_Factor
-1)) +
4884 (pprevious_stats
->RxMIMOSignalStrength
[rfpath
])) /(Rx_Smooth_Factor
);
4886 RT_TRACE(COMP_DBG
,"Jacken -> priv->RxStats.RxRSSIPercentage[rfPath] = %d \n" ,priv
->stats
.rx_rssi_percentage
[rfpath
] );
4894 //cosa add for beacon rssi smoothing by average.
4895 if(pprevious_stats
->bPacketBeacon
)
4897 /* record the beacon pwdb to the sliding window. */
4898 if(slide_beacon_adc_pwdb_statistics
++ >= PHY_Beacon_RSSI_SLID_WIN_MAX
)
4900 slide_beacon_adc_pwdb_statistics
= PHY_Beacon_RSSI_SLID_WIN_MAX
;
4901 last_beacon_adc_pwdb
= priv
->stats
.Slide_Beacon_pwdb
[slide_beacon_adc_pwdb_index
];
4902 priv
->stats
.Slide_Beacon_Total
-= last_beacon_adc_pwdb
;
4903 //DbgPrint("slide_beacon_adc_pwdb_index = %d, last_beacon_adc_pwdb = %d, Adapter->RxStats.Slide_Beacon_Total = %d\n",
4904 // slide_beacon_adc_pwdb_index, last_beacon_adc_pwdb, Adapter->RxStats.Slide_Beacon_Total);
4906 priv
->stats
.Slide_Beacon_Total
+= pprevious_stats
->RxPWDBAll
;
4907 priv
->stats
.Slide_Beacon_pwdb
[slide_beacon_adc_pwdb_index
] = pprevious_stats
->RxPWDBAll
;
4908 //DbgPrint("slide_beacon_adc_pwdb_index = %d, pPreviousRfd->Status.RxPWDBAll = %d\n", slide_beacon_adc_pwdb_index, pPreviousRfd->Status.RxPWDBAll);
4909 slide_beacon_adc_pwdb_index
++;
4910 if(slide_beacon_adc_pwdb_index
>= PHY_Beacon_RSSI_SLID_WIN_MAX
)
4911 slide_beacon_adc_pwdb_index
= 0;
4912 pprevious_stats
->RxPWDBAll
= priv
->stats
.Slide_Beacon_Total
/slide_beacon_adc_pwdb_statistics
;
4913 if(pprevious_stats
->RxPWDBAll
>= 3)
4914 pprevious_stats
->RxPWDBAll
-= 3;
4917 RT_TRACE(COMP_RXDESC
, "Smooth %s PWDB = %d\n",
4918 pprevious_stats
->bIsCCK
? "CCK": "OFDM",
4919 pprevious_stats
->RxPWDBAll
);
4921 if(pprevious_stats
->bPacketToSelf
|| pprevious_stats
->bPacketBeacon
|| pprevious_stats
->bToSelfBA
)
4923 if(priv
->undecorated_smoothed_pwdb
< 0) // initialize
4925 priv
->undecorated_smoothed_pwdb
= pprevious_stats
->RxPWDBAll
;
4926 //DbgPrint("First pwdb initialize \n");
4929 if(pprevious_stats
->RxPWDBAll
> (u32
)priv
->undecorated_smoothed_pwdb
)
4931 priv
->undecorated_smoothed_pwdb
=
4932 ( ((priv
->undecorated_smoothed_pwdb
)*(Rx_Smooth_Factor
-1)) +
4933 (pprevious_stats
->RxPWDBAll
)) /(Rx_Smooth_Factor
);
4934 priv
->undecorated_smoothed_pwdb
= priv
->undecorated_smoothed_pwdb
+ 1;
4938 priv
->undecorated_smoothed_pwdb
=
4939 ( ((priv
->undecorated_smoothed_pwdb
)*(Rx_Smooth_Factor
-1)) +
4940 (pprevious_stats
->RxPWDBAll
)) /(Rx_Smooth_Factor
);
4943 //Fixed by Jacken 2008-03-20
4944 if(pPreviousRfd
->Status
.RxPWDBAll
> (u32
)pHalData
->UndecoratedSmoothedPWDB
)
4946 pHalData
->UndecoratedSmoothedPWDB
=
4947 ( ((pHalData
->UndecoratedSmoothedPWDB
)* 5) + (pPreviousRfd
->Status
.RxPWDBAll
)) / 6;
4948 pHalData
->UndecoratedSmoothedPWDB
= pHalData
->UndecoratedSmoothedPWDB
+ 1;
4952 pHalData
->UndecoratedSmoothedPWDB
=
4953 ( ((pHalData
->UndecoratedSmoothedPWDB
)* 5) + (pPreviousRfd
->Status
.RxPWDBAll
)) / 6;
4956 rtl819x_update_rxsignalstatistics8190pci(priv
,pprevious_stats
);
4962 /* record the general EVM to the sliding window. */
4963 if(pprevious_stats
->SignalQuality
== 0)
4968 if(pprevious_stats
->bPacketToSelf
|| pprevious_stats
->bPacketBeacon
|| pprevious_stats
->bToSelfBA
){
4969 if(slide_evm_statistics
++ >= PHY_RSSI_SLID_WIN_MAX
){
4970 slide_evm_statistics
= PHY_RSSI_SLID_WIN_MAX
;
4971 last_evm
= priv
->stats
.slide_evm
[slide_evm_index
];
4972 priv
->stats
.slide_evm_total
-= last_evm
;
4975 priv
->stats
.slide_evm_total
+= pprevious_stats
->SignalQuality
;
4977 priv
->stats
.slide_evm
[slide_evm_index
++] = pprevious_stats
->SignalQuality
;
4978 if(slide_evm_index
>= PHY_RSSI_SLID_WIN_MAX
)
4979 slide_evm_index
= 0;
4981 // <1> Showed on UI for user, in percentage.
4982 tmp_val
= priv
->stats
.slide_evm_total
/slide_evm_statistics
;
4983 priv
->stats
.signal_quality
= tmp_val
;
4984 //cosa add 10/11/2007, Showed on UI for user in Windows Vista, for Link quality.
4985 priv
->stats
.last_signal_strength_inpercent
= tmp_val
;
4988 // <2> Showed on UI for engineering
4989 if(pprevious_stats
->bPacketToSelf
|| pprevious_stats
->bPacketBeacon
|| pprevious_stats
->bToSelfBA
)
4991 for(nspatial_stream
= 0; nspatial_stream
<2 ; nspatial_stream
++) // 2 spatial stream
4993 if(pprevious_stats
->RxMIMOSignalQuality
[nspatial_stream
] != -1)
4995 if(priv
->stats
.rx_evm_percentage
[nspatial_stream
] == 0) // initialize
4997 priv
->stats
.rx_evm_percentage
[nspatial_stream
] = pprevious_stats
->RxMIMOSignalQuality
[nspatial_stream
];
4999 priv
->stats
.rx_evm_percentage
[nspatial_stream
] =
5000 ( (priv
->stats
.rx_evm_percentage
[nspatial_stream
]* (Rx_Smooth_Factor
-1)) +
5001 (pprevious_stats
->RxMIMOSignalQuality
[nspatial_stream
]* 1)) / (Rx_Smooth_Factor
);
5009 static u8
rtl819x_query_rxpwrpercentage(
5013 if ((antpower
<= -100) || (antpower
>= 20))
5017 else if (antpower
>= 0)
5023 return (100+antpower
);
5029 rtl819x_evm_dbtopercentage(
5041 ret_val
= 0 - ret_val
;
5048 /* We want good-looking for signal strength/quality */
5049 static long rtl819x_signal_scale_mapping(long currsig
)
5053 // Step 1. Scale mapping.
5054 if(currsig
>= 61 && currsig
<= 100)
5056 retsig
= 90 + ((currsig
- 60) / 4);
5058 else if(currsig
>= 41 && currsig
<= 60)
5060 retsig
= 78 + ((currsig
- 40) / 2);
5062 else if(currsig
>= 31 && currsig
<= 40)
5064 retsig
= 66 + (currsig
- 30);
5066 else if(currsig
>= 21 && currsig
<= 30)
5068 retsig
= 54 + (currsig
- 20);
5070 else if(currsig
>= 5 && currsig
<= 20)
5072 retsig
= 42 + (((currsig
- 5) * 2) / 3);
5074 else if(currsig
== 4)
5078 else if(currsig
== 3)
5082 else if(currsig
== 2)
5086 else if(currsig
== 1)
5098 static void rtl8192_query_rxphystatus(
5099 struct r8192_priv
* priv
,
5100 struct ieee80211_rx_stats
* pstats
,
5101 prx_desc_819x_pci pdesc
,
5102 prx_fwinfo_819x_pci pdrvinfo
,
5103 struct ieee80211_rx_stats
* precord_stats
,
5104 bool bpacket_match_bssid
,
5105 bool bpacket_toself
,
5110 //PRT_RFD_STATUS pRtRfdStatus = &(pRfd->Status);
5111 phy_sts_ofdm_819xpci_t
* pofdm_buf
;
5112 phy_sts_cck_819xpci_t
* pcck_buf
;
5113 phy_ofdm_rx_status_rxsc_sgien_exintfflag
* prxsc
;
5115 u8 i
,max_spatial_stream
, tmp_rxsnr
, tmp_rxevm
, rxsc_sgien_exflg
;
5116 char rx_pwr
[4], rx_pwr_all
=0;
5117 //long rx_avg_pwr = 0;
5118 char rx_snrX
, rx_evmX
;
5120 u32 RSSI
, total_rssi
=0;//, total_evm=0;
5121 // long signal_strength_index = 0;
5125 /* 2007/07/04 MH For OFDM RSSI. For high power or not. */
5126 static u8 check_reg824
= 0;
5127 static u32 reg824_bit9
= 0;
5129 priv
->stats
.numqry_phystatus
++;
5131 is_cck_rate
= rx_hal_is_cck_rate(pdrvinfo
);
5133 // Record it for next packet processing
5134 memset(precord_stats
, 0, sizeof(struct ieee80211_rx_stats
));
5135 pstats
->bPacketMatchBSSID
= precord_stats
->bPacketMatchBSSID
= bpacket_match_bssid
;
5136 pstats
->bPacketToSelf
= precord_stats
->bPacketToSelf
= bpacket_toself
;
5137 pstats
->bIsCCK
= precord_stats
->bIsCCK
= is_cck_rate
;//RX_HAL_IS_CCK_RATE(pDrvInfo);
5138 pstats
->bPacketBeacon
= precord_stats
->bPacketBeacon
= bPacketBeacon
;
5139 pstats
->bToSelfBA
= precord_stats
->bToSelfBA
= bToSelfBA
;
5140 /*2007.08.30 requested by SD3 Jerry */
5141 if(check_reg824
== 0)
5143 reg824_bit9
= rtl8192_QueryBBReg(priv
->ieee80211
->dev
, rFPGA0_XA_HSSIParameter2
, 0x200);
5148 prxpkt
= (u8
*)pdrvinfo
;
5150 /* Move pointer to the 16th bytes. Phy status start address. */
5151 prxpkt
+= sizeof(rx_fwinfo_819x_pci
);
5153 /* Initial the cck and ofdm buffer pointer */
5154 pcck_buf
= (phy_sts_cck_819xpci_t
*)prxpkt
;
5155 pofdm_buf
= (phy_sts_ofdm_819xpci_t
*)prxpkt
;
5157 pstats
->RxMIMOSignalQuality
[0] = -1;
5158 pstats
->RxMIMOSignalQuality
[1] = -1;
5159 precord_stats
->RxMIMOSignalQuality
[0] = -1;
5160 precord_stats
->RxMIMOSignalQuality
[1] = -1;
5165 // (1)Hardware does not provide RSSI for CCK
5169 // (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive)
5171 u8 report
;//, cck_agc_rpt;
5174 char cck_adc_pwdb
[4];
5176 priv
->stats
.numqry_phystatusCCK
++;
5178 #ifdef RTL8190P //Only 90P 2T4R need to check
5179 if(priv
->rf_type
== RF_2T4R
&& DM_RxPathSelTable
.Enable
&& bpacket_match_bssid
)
5181 for(i
=RF90_PATH_A
; i
<RF90_PATH_MAX
; i
++)
5183 tmp_pwdb
= pcck_buf
->adc_pwdb_X
[i
];
5184 cck_adc_pwdb
[i
] = (char)tmp_pwdb
;
5185 cck_adc_pwdb
[i
] /= 2;
5186 pstats
->cck_adc_pwdb
[i
] = precord_stats
->cck_adc_pwdb
[i
] = cck_adc_pwdb
[i
];
5187 //DbgPrint("RF-%d tmp_pwdb = 0x%x, cck_adc_pwdb = %d", i, tmp_pwdb, cck_adc_pwdb[i]);
5194 report
= pcck_buf
->cck_agc_rpt
& 0xc0;
5198 //Fixed by Jacken from Bryant 2008-03-20
5199 //Original value is -38 , -26 , -14 , -2
5200 //Fixed value is -35 , -23 , -11 , 6
5202 rx_pwr_all
= -35 - (pcck_buf
->cck_agc_rpt
& 0x3e);
5205 rx_pwr_all
= -23 - (pcck_buf
->cck_agc_rpt
& 0x3e);
5208 rx_pwr_all
= -11 - (pcck_buf
->cck_agc_rpt
& 0x3e);
5211 rx_pwr_all
= 8 - (pcck_buf
->cck_agc_rpt
& 0x3e);
5217 report
= pcck_buf
->cck_agc_rpt
& 0x60;
5222 rx_pwr_all
= -35 - ((pcck_buf
->cck_agc_rpt
& 0x1f)<<1) ;
5225 rx_pwr_all
= -23 - ((pcck_buf
->cck_agc_rpt
& 0x1f)<<1);
5228 rx_pwr_all
= -11 - ((pcck_buf
->cck_agc_rpt
& 0x1f)<<1) ;
5231 rx_pwr_all
= -8 - ((pcck_buf
->cck_agc_rpt
& 0x1f)<<1) ;
5236 pwdb_all
= rtl819x_query_rxpwrpercentage(rx_pwr_all
);
5237 pstats
->RxPWDBAll
= precord_stats
->RxPWDBAll
= pwdb_all
;
5238 pstats
->RecvSignalPower
= rx_pwr_all
;
5241 // (3) Get Signal Quality (EVM)
5243 if(bpacket_match_bssid
)
5247 if(pstats
->RxPWDBAll
> 40)
5252 sq
= pcck_buf
->sq_rpt
;
5254 if(pcck_buf
->sq_rpt
> 64)
5256 else if (pcck_buf
->sq_rpt
< 20)
5259 sq
= ((64-sq
) * 100) / 44;
5261 pstats
->SignalQuality
= precord_stats
->SignalQuality
= sq
;
5262 pstats
->RxMIMOSignalQuality
[0] = precord_stats
->RxMIMOSignalQuality
[0] = sq
;
5263 pstats
->RxMIMOSignalQuality
[1] = precord_stats
->RxMIMOSignalQuality
[1] = -1;
5268 priv
->stats
.numqry_phystatusHT
++;
5270 // (1)Get RSSI for HT rate
5272 for(i
=RF90_PATH_A
; i
<RF90_PATH_MAX
; i
++)
5274 // 2008/01/30 MH we will judge RF RX path now.
5275 if (priv
->brfpath_rxenable
[i
])
5280 //Fixed by Jacken from Bryant 2008-03-20
5281 //Original value is 106
5282 #ifdef RTL8190P //Modify by Jacken 2008/03/31
5283 rx_pwr
[i
] = ((pofdm_buf
->trsw_gain_X
[i
]&0x3F)*2) - 106;
5285 rx_pwr
[i
] = ((pofdm_buf
->trsw_gain_X
[i
]&0x3F)*2) - 110;
5288 //Get Rx snr value in DB
5289 tmp_rxsnr
= pofdm_buf
->rxsnr_X
[i
];
5290 rx_snrX
= (char)(tmp_rxsnr
);
5292 priv
->stats
.rxSNRdB
[i
] = (long)rx_snrX
;
5294 /* Translate DBM to percentage. */
5295 RSSI
= rtl819x_query_rxpwrpercentage(rx_pwr
[i
]);
5296 if (priv
->brfpath_rxenable
[i
])
5299 /* Record Signal Strength for next packet */
5300 if(bpacket_match_bssid
)
5302 pstats
->RxMIMOSignalStrength
[i
] =(u8
) RSSI
;
5303 precord_stats
->RxMIMOSignalStrength
[i
] =(u8
) RSSI
;
5309 // (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive)
5311 //Fixed by Jacken from Bryant 2008-03-20
5312 //Original value is 106
5313 rx_pwr_all
= (((pofdm_buf
->pwdb_all
) >> 1 )& 0x7f) -106;
5314 pwdb_all
= rtl819x_query_rxpwrpercentage(rx_pwr_all
);
5316 pstats
->RxPWDBAll
= precord_stats
->RxPWDBAll
= pwdb_all
;
5317 pstats
->RxPower
= precord_stats
->RxPower
= rx_pwr_all
;
5318 pstats
->RecvSignalPower
= rx_pwr_all
;
5320 // (3)EVM of HT rate
5322 if(pdrvinfo
->RxHT
&& pdrvinfo
->RxRate
>=DESC90_RATEMCS8
&&
5323 pdrvinfo
->RxRate
<=DESC90_RATEMCS15
)
5324 max_spatial_stream
= 2; //both spatial stream make sense
5326 max_spatial_stream
= 1; //only spatial stream 1 makes sense
5328 for(i
=0; i
<max_spatial_stream
; i
++)
5330 tmp_rxevm
= pofdm_buf
->rxevm_X
[i
];
5331 rx_evmX
= (char)(tmp_rxevm
);
5333 // Do not use shift operation like "rx_evmX >>= 1" because the compilor of free build environment
5334 // fill most significant bit to "zero" when doing shifting operation which may change a negative
5335 // value to positive one, then the dbm value (which is supposed to be negative) is not correct anymore.
5338 evm
= rtl819x_evm_dbtopercentage(rx_evmX
);
5339 if(bpacket_match_bssid
)
5341 if(i
==0) // Fill value in RFD, Get the first spatial stream only
5342 pstats
->SignalQuality
= precord_stats
->SignalQuality
= (u8
)(evm
& 0xff);
5343 pstats
->RxMIMOSignalQuality
[i
] = precord_stats
->RxMIMOSignalQuality
[i
] = (u8
)(evm
& 0xff);
5348 /* record rx statistics for debug */
5349 rxsc_sgien_exflg
= pofdm_buf
->rxsc_sgien_exflg
;
5350 prxsc
= (phy_ofdm_rx_status_rxsc_sgien_exintfflag
*)&rxsc_sgien_exflg
;
5351 if(pdrvinfo
->BW
) //40M channel
5352 priv
->stats
.received_bwtype
[1+prxsc
->rxsc
]++;
5354 priv
->stats
.received_bwtype
[0]++;
5357 //UI BSS List signal strength(in percentage), make it good looking, from 0~100.
5358 //It is assigned to the BSS List in GetValueFromBeaconOrProbeRsp().
5361 pstats
->SignalStrength
= precord_stats
->SignalStrength
= (u8
)(rtl819x_signal_scale_mapping((long)pwdb_all
));//PWDB_ALL;
5366 //pRfd->Status.SignalStrength = pRecordRfd->Status.SignalStrength = (u1Byte)(SignalScaleMapping(total_rssi/=RF90_PATH_MAX));//(u1Byte)(total_rssi/=RF90_PATH_MAX);
5367 // We can judge RX path number now.
5369 pstats
->SignalStrength
= precord_stats
->SignalStrength
= (u8
)(rtl819x_signal_scale_mapping((long)(total_rssi
/=rf_rx_num
)));
5374 rtl8192_record_rxdesc_forlateruse(
5375 struct ieee80211_rx_stats
* psrc_stats
,
5376 struct ieee80211_rx_stats
* ptarget_stats
5379 ptarget_stats
->bIsAMPDU
= psrc_stats
->bIsAMPDU
;
5380 ptarget_stats
->bFirstMPDU
= psrc_stats
->bFirstMPDU
;
5381 //ptarget_stats->Seq_Num = psrc_stats->Seq_Num;
5386 static void TranslateRxSignalStuff819xpci(struct net_device
*dev
,
5387 struct sk_buff
*skb
,
5388 struct ieee80211_rx_stats
* pstats
,
5389 prx_desc_819x_pci pdesc
,
5390 prx_fwinfo_819x_pci pdrvinfo
)
5392 // TODO: We must only check packet for current MAC address. Not finish
5393 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
5394 bool bpacket_match_bssid
, bpacket_toself
;
5395 bool bPacketBeacon
=false, bToSelfBA
=false;
5396 static struct ieee80211_rx_stats previous_stats
;
5397 struct ieee80211_hdr_3addr
*hdr
;
5400 // Get Signal Quality for only RX data queue (but not command queue)
5405 /* Get MAC frame start address. */
5406 tmp_buf
= skb
->data
;
5408 hdr
= (struct ieee80211_hdr_3addr
*)tmp_buf
;
5409 fc
= le16_to_cpu(hdr
->frame_ctl
);
5410 type
= WLAN_FC_GET_TYPE(fc
);
5411 praddr
= hdr
->addr1
;
5413 /* Check if the received packet is acceptabe. */
5414 bpacket_match_bssid
= ((IEEE80211_FTYPE_CTL
!= type
) &&
5415 (!compare_ether_addr(priv
->ieee80211
->current_network
.bssid
, (fc
& IEEE80211_FCTL_TODS
)? hdr
->addr1
: (fc
& IEEE80211_FCTL_FROMDS
)? hdr
->addr2
: hdr
->addr3
))
5416 && (!pstats
->bHwError
) && (!pstats
->bCRC
)&& (!pstats
->bICV
));
5417 bpacket_toself
= bpacket_match_bssid
& (!compare_ether_addr(praddr
, priv
->ieee80211
->dev
->dev_addr
));
5419 if(WLAN_FC_GET_FRAMETYPE(fc
)== IEEE80211_STYPE_BEACON
)
5421 bPacketBeacon
= true;
5422 //DbgPrint("Beacon 2, MatchBSSID = %d, ToSelf = %d \n", bPacketMatchBSSID, bPacketToSelf);
5424 if(WLAN_FC_GET_FRAMETYPE(fc
) == IEEE80211_STYPE_BLOCKACK
)
5426 if((!compare_ether_addr(praddr
,dev
->dev_addr
)))
5428 //DbgPrint("BlockAck, MatchBSSID = %d, ToSelf = %d \n", bPacketMatchBSSID, bPacketToSelf);
5432 if(bpacket_match_bssid
)
5434 priv
->stats
.numpacket_matchbssid
++;
5437 priv
->stats
.numpacket_toself
++;
5440 // Process PHY information for previous packet (RSSI/PWDB/EVM)
5442 // Because phy information is contained in the last packet of AMPDU only, so driver
5443 // should process phy information of previous packet
5444 rtl8192_process_phyinfo(priv
, tmp_buf
,&previous_stats
, pstats
);
5445 rtl8192_query_rxphystatus(priv
, pstats
, pdesc
, pdrvinfo
, &previous_stats
, bpacket_match_bssid
,
5446 bpacket_toself
,bPacketBeacon
, bToSelfBA
);
5447 rtl8192_record_rxdesc_forlateruse(pstats
, &previous_stats
);
5452 static void rtl8192_tx_resume(struct net_device
*dev
)
5454 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
5455 struct ieee80211_device
*ieee
= priv
->ieee80211
;
5456 struct sk_buff
*skb
;
5459 for(queue_index
= BK_QUEUE
; queue_index
< TXCMD_QUEUE
;queue_index
++) {
5460 while((!skb_queue_empty(&ieee
->skb_waitQ
[queue_index
]))&&
5461 (priv
->ieee80211
->check_nic_enough_desc(dev
,queue_index
) > 0)) {
5462 /* 1. dequeue the packet from the wait queue */
5463 skb
= skb_dequeue(&ieee
->skb_waitQ
[queue_index
]);
5464 /* 2. tx the packet directly */
5465 ieee
->softmac_data_hard_start_xmit(skb
,dev
,0/* rate useless now*/);
5470 static void rtl8192_irq_tx_tasklet(struct r8192_priv
*priv
)
5472 rtl8192_tx_resume(priv
->ieee80211
->dev
);
5475 /* Record the received data rate */
5476 static void UpdateReceivedRateHistogramStatistics8190(
5477 struct net_device
*dev
,
5478 struct ieee80211_rx_stats
* pstats
5481 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
5482 u32 rcvType
=1; //0: Total, 1:OK, 2:CRC, 3:ICV
5484 u32 preamble_guardinterval
; //1: short preamble/GI, 0: long preamble/GI
5488 else if(pstats
->bICV
)
5491 if(pstats
->bShortPreamble
)
5492 preamble_guardinterval
= 1;// short
5494 preamble_guardinterval
= 0;// long
5496 switch(pstats
->rate
)
5501 case MGN_1M
: rateIndex
= 0; break;
5502 case MGN_2M
: rateIndex
= 1; break;
5503 case MGN_5_5M
: rateIndex
= 2; break;
5504 case MGN_11M
: rateIndex
= 3; break;
5508 case MGN_6M
: rateIndex
= 4; break;
5509 case MGN_9M
: rateIndex
= 5; break;
5510 case MGN_12M
: rateIndex
= 6; break;
5511 case MGN_18M
: rateIndex
= 7; break;
5512 case MGN_24M
: rateIndex
= 8; break;
5513 case MGN_36M
: rateIndex
= 9; break;
5514 case MGN_48M
: rateIndex
= 10; break;
5515 case MGN_54M
: rateIndex
= 11; break;
5517 // 11n High throughput rate
5519 case MGN_MCS0
: rateIndex
= 12; break;
5520 case MGN_MCS1
: rateIndex
= 13; break;
5521 case MGN_MCS2
: rateIndex
= 14; break;
5522 case MGN_MCS3
: rateIndex
= 15; break;
5523 case MGN_MCS4
: rateIndex
= 16; break;
5524 case MGN_MCS5
: rateIndex
= 17; break;
5525 case MGN_MCS6
: rateIndex
= 18; break;
5526 case MGN_MCS7
: rateIndex
= 19; break;
5527 case MGN_MCS8
: rateIndex
= 20; break;
5528 case MGN_MCS9
: rateIndex
= 21; break;
5529 case MGN_MCS10
: rateIndex
= 22; break;
5530 case MGN_MCS11
: rateIndex
= 23; break;
5531 case MGN_MCS12
: rateIndex
= 24; break;
5532 case MGN_MCS13
: rateIndex
= 25; break;
5533 case MGN_MCS14
: rateIndex
= 26; break;
5534 case MGN_MCS15
: rateIndex
= 27; break;
5535 default: rateIndex
= 28; break;
5537 priv
->stats
.received_preamble_GI
[preamble_guardinterval
][rateIndex
]++;
5538 priv
->stats
.received_rate_histogram
[0][rateIndex
]++; //total
5539 priv
->stats
.received_rate_histogram
[rcvType
][rateIndex
]++;
5542 static void rtl8192_rx(struct net_device
*dev
)
5544 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
5545 struct ieee80211_hdr_1addr
*ieee80211_hdr
= NULL
;
5546 bool unicast_packet
= false;
5547 struct ieee80211_rx_stats stats
= {
5551 .freq
= IEEE80211_24GHZ_BAND
,
5553 unsigned int count
= priv
->rxringcount
;
5555 stats
.nic_type
= NIC_8192E
;
5558 rx_desc_819x_pci
*pdesc
= &priv
->rx_ring
[priv
->rx_idx
];//rx descriptor
5559 struct sk_buff
*skb
= priv
->rx_buf
[priv
->rx_idx
];//rx pkt
5562 /* wait data to be filled by hardware */
5565 stats
.bICV
= pdesc
->ICV
;
5566 stats
.bCRC
= pdesc
->CRC32
;
5567 stats
.bHwError
= pdesc
->CRC32
| pdesc
->ICV
;
5569 stats
.Length
= pdesc
->Length
;
5570 if(stats
.Length
< 24)
5571 stats
.bHwError
|= 1;
5573 if(stats
.bHwError
) {
5574 stats
.bShift
= false;
5577 if (pdesc
->Length
<500)
5578 priv
->stats
.rxcrcerrmin
++;
5579 else if (pdesc
->Length
>1000)
5580 priv
->stats
.rxcrcerrmax
++;
5582 priv
->stats
.rxcrcerrmid
++;
5586 prx_fwinfo_819x_pci pDrvInfo
= NULL
;
5587 struct sk_buff
*new_skb
= dev_alloc_skb(priv
->rxbuffersize
);
5589 if (unlikely(!new_skb
)) {
5593 stats
.RxDrvInfoSize
= pdesc
->RxDrvInfoSize
;
5594 stats
.RxBufShift
= ((pdesc
->Shift
)&0x03);
5595 stats
.Decrypted
= !pdesc
->SWDec
;
5597 pci_dma_sync_single_for_cpu(priv
->pdev
,
5598 *((dma_addr_t
*)skb
->cb
),
5600 PCI_DMA_FROMDEVICE
);
5601 skb_put(skb
, pdesc
->Length
);
5602 pDrvInfo
= (rx_fwinfo_819x_pci
*)(skb
->data
+ stats
.RxBufShift
);
5603 skb_reserve(skb
, stats
.RxDrvInfoSize
+ stats
.RxBufShift
);
5605 stats
.rate
= HwRateToMRate90((bool)pDrvInfo
->RxHT
, (u8
)pDrvInfo
->RxRate
);
5606 stats
.bShortPreamble
= pDrvInfo
->SPLCP
;
5608 /* it is debug only. It should be disabled in released driver.
5609 * 2007.1.11 by Emily
5611 UpdateReceivedRateHistogramStatistics8190(dev
, &stats
);
5613 stats
.bIsAMPDU
= (pDrvInfo
->PartAggr
==1);
5614 stats
.bFirstMPDU
= (pDrvInfo
->PartAggr
==1) && (pDrvInfo
->FirstAGGR
==1);
5616 stats
.TimeStampLow
= pDrvInfo
->TSFL
;
5617 stats
.TimeStampHigh
= read_nic_dword(dev
, TSFR
+4);
5619 UpdateRxPktTimeStamp8190(dev
, &stats
);
5622 // Get Total offset of MPDU Frame Body
5624 if((stats
.RxBufShift
+ stats
.RxDrvInfoSize
) > 0)
5627 stats
.RxIs40MHzPacket
= pDrvInfo
->BW
;
5630 TranslateRxSignalStuff819xpci(dev
,skb
, &stats
, pdesc
, pDrvInfo
);
5633 if(pDrvInfo
->FirstAGGR
==1 || pDrvInfo
->PartAggr
== 1)
5634 RT_TRACE(COMP_RXDESC
, "pDrvInfo->FirstAGGR = %d, pDrvInfo->PartAggr = %d\n",
5635 pDrvInfo
->FirstAGGR
, pDrvInfo
->PartAggr
);
5636 skb_trim(skb
, skb
->len
- 4/*sCrcLng*/);
5637 /* rx packets statistics */
5638 ieee80211_hdr
= (struct ieee80211_hdr_1addr
*)skb
->data
;
5639 unicast_packet
= false;
5641 if(is_broadcast_ether_addr(ieee80211_hdr
->addr1
)) {
5643 }else if(is_multicast_ether_addr(ieee80211_hdr
->addr1
)){
5646 /* unicast packet */
5647 unicast_packet
= true;
5650 stats
.packetlength
= stats
.Length
-4;
5651 stats
.fraglength
= stats
.packetlength
;
5652 stats
.fragoffset
= 0;
5653 stats
.ntotalfrag
= 1;
5655 if(!ieee80211_rtl_rx(priv
->ieee80211
, skb
, &stats
)){
5656 dev_kfree_skb_any(skb
);
5659 if(unicast_packet
) {
5660 priv
->stats
.rxbytesunicast
+= skb
->len
;
5664 pci_unmap_single(priv
->pdev
, *((dma_addr_t
*) skb
->cb
),
5665 priv
->rxbuffersize
, PCI_DMA_FROMDEVICE
);
5668 priv
->rx_buf
[priv
->rx_idx
] = skb
;
5669 *((dma_addr_t
*) skb
->cb
) = pci_map_single(priv
->pdev
, skb_tail_pointer(skb
), priv
->rxbuffersize
, PCI_DMA_FROMDEVICE
);
5674 pdesc
->BufferAddress
= cpu_to_le32(*((dma_addr_t
*)skb
->cb
));
5676 pdesc
->Length
= priv
->rxbuffersize
;
5677 if (priv
->rx_idx
== priv
->rxringcount
-1)
5679 priv
->rx_idx
= (priv
->rx_idx
+ 1) % priv
->rxringcount
;
5684 static void rtl8192_irq_rx_tasklet(struct r8192_priv
*priv
)
5686 rtl8192_rx(priv
->ieee80211
->dev
);
5688 write_nic_dword(priv
->ieee80211
->dev
, INTA_MASK
,read_nic_dword(priv
->ieee80211
->dev
, INTA_MASK
) | IMR_RDU
);
5691 static const struct net_device_ops rtl8192_netdev_ops
= {
5692 .ndo_open
= rtl8192_open
,
5693 .ndo_stop
= rtl8192_close
,
5694 .ndo_tx_timeout
= tx_timeout
,
5695 .ndo_do_ioctl
= rtl8192_ioctl
,
5696 .ndo_set_multicast_list
= r8192_set_multicast
,
5697 .ndo_set_mac_address
= r8192_set_mac_adr
,
5698 .ndo_start_xmit
= ieee80211_rtl_xmit
,
5701 static int __devinit
rtl8192_pci_probe(struct pci_dev
*pdev
,
5702 const struct pci_device_id
*id
)
5704 unsigned long ioaddr
= 0;
5705 struct net_device
*dev
= NULL
;
5706 struct r8192_priv
*priv
= NULL
;
5710 #ifdef CONFIG_RTL8192_IO_MAP
5711 unsigned long pio_start
, pio_len
, pio_flags
;
5713 unsigned long pmem_start
, pmem_len
, pmem_flags
;
5714 #endif //end #ifdef RTL_IO_MAP
5716 RT_TRACE(COMP_INIT
,"Configuring chip resources");
5718 if( pci_enable_device (pdev
) ){
5719 RT_TRACE(COMP_ERR
,"Failed to enable PCI device");
5723 pci_set_master(pdev
);
5724 //pci_set_wmi(pdev);
5725 pci_set_dma_mask(pdev
, 0xffffff00ULL
);
5726 pci_set_consistent_dma_mask(pdev
,0xffffff00ULL
);
5727 dev
= alloc_ieee80211(sizeof(struct r8192_priv
));
5733 pci_set_drvdata(pdev
, dev
);
5734 SET_NETDEV_DEV(dev
, &pdev
->dev
);
5735 priv
= ieee80211_priv(dev
);
5736 priv
->ieee80211
= netdev_priv(dev
);
5738 if((pdev
->subsystem_vendor
== PCI_VENDOR_ID_DLINK
)&&(pdev
->subsystem_device
== 0x3304)){
5739 priv
->ieee80211
->bSupportRemoteWakeUp
= 1;
5742 priv
->ieee80211
->bSupportRemoteWakeUp
= 0;
5745 #ifdef CONFIG_RTL8192_IO_MAP
5747 pio_start
= (unsigned long)pci_resource_start (pdev
, 0);
5748 pio_len
= (unsigned long)pci_resource_len (pdev
, 0);
5749 pio_flags
= (unsigned long)pci_resource_flags (pdev
, 0);
5751 if (!(pio_flags
& IORESOURCE_IO
)) {
5752 RT_TRACE(COMP_ERR
,"region #0 not a PIO resource, aborting");
5756 //DMESG("IO space @ 0x%08lx", pio_start );
5757 if( ! request_region( pio_start
, pio_len
, RTL819xE_MODULE_NAME
) ){
5758 RT_TRACE(COMP_ERR
,"request_region failed!");
5763 dev
->base_addr
= ioaddr
; // device I/O address
5767 pmem_start
= pci_resource_start(pdev
, 1);
5768 pmem_len
= pci_resource_len(pdev
, 1);
5769 pmem_flags
= pci_resource_flags (pdev
, 1);
5771 if (!(pmem_flags
& IORESOURCE_MEM
)) {
5772 RT_TRACE(COMP_ERR
,"region #1 not a MMIO resource, aborting");
5776 //DMESG("Memory mapped space @ 0x%08lx ", pmem_start);
5777 if( ! request_mem_region(pmem_start
, pmem_len
, RTL819xE_MODULE_NAME
)) {
5778 RT_TRACE(COMP_ERR
,"request_mem_region failed!");
5783 ioaddr
= (unsigned long)ioremap_nocache( pmem_start
, pmem_len
);
5784 if( ioaddr
== (unsigned long)NULL
){
5785 RT_TRACE(COMP_ERR
,"ioremap failed!");
5786 // release_mem_region( pmem_start, pmem_len );
5790 dev
->mem_start
= ioaddr
; // shared mem start
5791 dev
->mem_end
= ioaddr
+ pci_resource_len(pdev
, 0); // shared mem end
5793 #endif //end #ifdef RTL_IO_MAP
5795 /* We disable the RETRY_TIMEOUT register (0x41) to keep
5796 * PCI Tx retries from interfering with C3 CPU state */
5797 pci_write_config_byte(pdev
, 0x41, 0x00);
5800 pci_read_config_byte(pdev
, 0x05, &unit
);
5801 pci_write_config_byte(pdev
, 0x05, unit
& (~0x04));
5803 dev
->irq
= pdev
->irq
;
5806 dev
->netdev_ops
= &rtl8192_netdev_ops
;
5808 //DMESG("Oops: i'm coming\n");
5809 #if WIRELESS_EXT >= 12
5810 #if WIRELESS_EXT < 17
5811 dev
->get_wireless_stats
= r8192_get_wireless_stats
;
5813 dev
->wireless_handlers
= (struct iw_handler_def
*) &r8192_wx_handlers_def
;
5815 //dev->get_wireless_stats = r8192_get_wireless_stats;
5816 dev
->type
=ARPHRD_ETHER
;
5818 dev
->watchdog_timeo
= HZ
*3; //modified by john, 0805
5820 if (dev_alloc_name(dev
, ifname
) < 0){
5821 RT_TRACE(COMP_INIT
, "Oops: devname already taken! Trying wlan%%d...\n");
5822 strcpy(ifname
, "wlan%d");
5823 dev_alloc_name(dev
, ifname
);
5826 RT_TRACE(COMP_INIT
, "Driver probe completed1\n");
5827 if(rtl8192_init(dev
)!=0){
5828 RT_TRACE(COMP_ERR
, "Initialization failed");
5832 netif_carrier_off(dev
);
5833 netif_stop_queue(dev
);
5835 register_netdev(dev
);
5836 RT_TRACE(COMP_INIT
, "dev name=======> %s\n",dev
->name
);
5837 rtl8192_proc_init_one(dev
);
5840 RT_TRACE(COMP_INIT
, "Driver probe completed\n");
5845 #ifdef CONFIG_RTL8180_IO_MAP
5847 if( dev
->base_addr
!= 0 ){
5849 release_region(dev
->base_addr
,
5850 pci_resource_len(pdev
, 0) );
5853 if( dev
->mem_start
!= (unsigned long)NULL
){
5854 iounmap( (void *)dev
->mem_start
);
5855 release_mem_region( pci_resource_start(pdev
, 1),
5856 pci_resource_len(pdev
, 1) );
5858 #endif //end #ifdef RTL_IO_MAP
5864 free_irq(dev
->irq
, dev
);
5867 free_ieee80211(dev
);
5871 pci_disable_device(pdev
);
5873 DMESG("wlan driver load failed\n");
5874 pci_set_drvdata(pdev
, NULL
);
5879 /* detach all the work and timer structure declared or inititialized
5880 * in r8192_init function.
5882 static void rtl8192_cancel_deferred_work(struct r8192_priv
* priv
)
5884 /* call cancel_work_sync instead of cancel_delayed_work if and only if Linux_version_code
5885 * is or is newer than 2.6.20 and work structure is defined to be struct work_struct.
5886 * Otherwise call cancel_delayed_work is enough.
5887 * FIXME (2.6.20 should 2.6.22, work_struct should not cancel)
5889 cancel_delayed_work(&priv
->watch_dog_wq
);
5890 cancel_delayed_work(&priv
->update_beacon_wq
);
5891 cancel_delayed_work(&priv
->ieee80211
->hw_wakeup_wq
);
5892 cancel_delayed_work(&priv
->ieee80211
->hw_sleep_wq
);
5894 cancel_delayed_work(&priv
->gpio_change_rf_wq
);
5896 cancel_work_sync(&priv
->reset_wq
);
5897 cancel_work_sync(&priv
->qos_activate
);
5898 //cancel_work_sync(&priv->SetBWModeWorkItem);
5899 //cancel_work_sync(&priv->SwChnlWorkItem);
5904 static void __devexit
rtl8192_pci_disconnect(struct pci_dev
*pdev
)
5906 struct net_device
*dev
= pci_get_drvdata(pdev
);
5907 struct r8192_priv
*priv
;
5911 unregister_netdev(dev
);
5913 priv
=ieee80211_priv(dev
);
5915 rtl8192_proc_remove_one(dev
);
5918 if (priv
->pFirmware
)
5920 vfree(priv
->pFirmware
);
5921 priv
->pFirmware
= NULL
;
5923 // priv->rf_close(dev);
5924 // rtl8192_usb_deleteendpoints(dev);
5925 destroy_workqueue(priv
->priv_wq
);
5926 /* redundant with rtl8192_down */
5927 // rtl8192_irq_disable(dev);
5928 // rtl8192_reset(dev);
5932 /* free tx/rx rings */
5933 rtl8192_free_rx_ring(dev
);
5934 for (i
= 0; i
< MAX_TX_QUEUE_COUNT
; i
++) {
5935 rtl8192_free_tx_ring(dev
, i
);
5940 printk("Freeing irq %d\n",dev
->irq
);
5941 free_irq(dev
->irq
, dev
);
5946 #ifdef CONFIG_RTL8180_IO_MAP
5948 if( dev
->base_addr
!= 0 ){
5950 release_region(dev
->base_addr
,
5951 pci_resource_len(pdev
, 0) );
5954 if( dev
->mem_start
!= (unsigned long)NULL
){
5955 iounmap( (void *)dev
->mem_start
);
5956 release_mem_region( pci_resource_start(pdev
, 1),
5957 pci_resource_len(pdev
, 1) );
5959 #endif /*end #ifdef RTL_IO_MAP*/
5960 free_ieee80211(dev
);
5964 pci_disable_device(pdev
);
5965 RT_TRACE(COMP_DOWN
, "wlan driver removed\n");
5968 extern int ieee80211_rtl_init(void);
5969 extern void ieee80211_rtl_exit(void);
5971 static int __init
rtl8192_pci_module_init(void)
5975 retval
= ieee80211_rtl_init();
5979 printk(KERN_INFO
"\nLinux kernel driver for RTL8192 based WLAN cards\n");
5980 printk(KERN_INFO
"Copyright (c) 2007-2008, Realsil Wlan\n");
5981 RT_TRACE(COMP_INIT
, "Initializing module");
5982 RT_TRACE(COMP_INIT
, "Wireless extensions version %d", WIRELESS_EXT
);
5983 rtl8192_proc_module_init();
5984 if(0!=pci_register_driver(&rtl8192_pci_driver
))
5986 DMESG("No device found");
5987 /*pci_unregister_driver (&rtl8192_pci_driver);*/
5994 static void __exit
rtl8192_pci_module_exit(void)
5996 pci_unregister_driver(&rtl8192_pci_driver
);
5998 RT_TRACE(COMP_DOWN
, "Exiting");
5999 rtl8192_proc_module_remove();
6000 ieee80211_rtl_exit();
6003 static irqreturn_t
rtl8192_interrupt(int irq
, void *netdev
)
6005 struct net_device
*dev
= (struct net_device
*) netdev
;
6006 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
6007 unsigned long flags
;
6009 irqreturn_t ret
= IRQ_HANDLED
;
6011 spin_lock_irqsave(&priv
->irq_th_lock
, flags
);
6013 /* We should return IRQ_NONE, but for now let me keep this */
6014 if (priv
->irq_enabled
== 0)
6019 inta
= read_nic_dword(dev
, ISR
); /* & priv->IntrMask; */
6020 write_nic_dword(dev
, ISR
, inta
); /* reset int situation */
6022 priv
->stats
.shints
++;
6025 * most probably we can safely return IRQ_NONE,
6026 * but for now is better to avoid problems
6031 if (inta
== 0xffff) {
6038 if (!netif_running(dev
))
6041 if (inta
& IMR_TBDOK
) {
6042 RT_TRACE(COMP_INTR
, "beacon ok interrupt!\n");
6043 rtl8192_tx_isr(dev
, BEACON_QUEUE
);
6044 priv
->stats
.txbeaconokint
++;
6047 if (inta
& IMR_TBDER
) {
6048 RT_TRACE(COMP_INTR
, "beacon ok interrupt!\n");
6049 rtl8192_tx_isr(dev
, BEACON_QUEUE
);
6050 priv
->stats
.txbeaconerr
++;
6053 if (inta
& IMR_MGNTDOK
) {
6054 RT_TRACE(COMP_INTR
, "Manage ok interrupt!\n");
6055 priv
->stats
.txmanageokint
++;
6056 rtl8192_tx_isr(dev
,MGNT_QUEUE
);
6059 if (inta
& IMR_COMDOK
)
6061 priv
->stats
.txcmdpktokint
++;
6062 rtl8192_tx_isr(dev
, TXCMD_QUEUE
);
6065 if (inta
& IMR_ROK
) {
6066 priv
->stats
.rxint
++;
6067 tasklet_schedule(&priv
->irq_rx_tasklet
);
6070 if (inta
& IMR_BcnInt
) {
6071 RT_TRACE(COMP_INTR
, "prepare beacon for interrupt!\n");
6072 tasklet_schedule(&priv
->irq_prepare_beacon_tasklet
);
6075 if (inta
& IMR_RDU
) {
6076 RT_TRACE(COMP_INTR
, "rx descriptor unavailable!\n");
6077 priv
->stats
.rxrdu
++;
6078 /* reset int situation */
6079 write_nic_dword(dev
, INTA_MASK
, read_nic_dword(dev
, INTA_MASK
) & ~IMR_RDU
);
6080 tasklet_schedule(&priv
->irq_rx_tasklet
);
6083 if (inta
& IMR_RXFOVW
) {
6084 RT_TRACE(COMP_INTR
, "rx overflow !\n");
6085 priv
->stats
.rxoverflow
++;
6086 tasklet_schedule(&priv
->irq_rx_tasklet
);
6089 if (inta
& IMR_TXFOVW
)
6090 priv
->stats
.txoverflow
++;
6092 if (inta
& IMR_BKDOK
) {
6093 RT_TRACE(COMP_INTR
, "BK Tx OK interrupt!\n");
6094 priv
->stats
.txbkokint
++;
6095 priv
->ieee80211
->LinkDetectInfo
.NumTxOkInPeriod
++;
6096 rtl8192_tx_isr(dev
, BK_QUEUE
);
6099 if (inta
& IMR_BEDOK
) {
6100 RT_TRACE(COMP_INTR
, "BE TX OK interrupt!\n");
6101 priv
->stats
.txbeokint
++;
6102 priv
->ieee80211
->LinkDetectInfo
.NumTxOkInPeriod
++;
6103 rtl8192_tx_isr(dev
, BE_QUEUE
);
6106 if (inta
& IMR_VIDOK
) {
6107 RT_TRACE(COMP_INTR
, "VI TX OK interrupt!\n");
6108 priv
->stats
.txviokint
++;
6109 priv
->ieee80211
->LinkDetectInfo
.NumTxOkInPeriod
++;
6110 rtl8192_tx_isr(dev
, VI_QUEUE
);
6113 if (inta
& IMR_VODOK
) {
6114 priv
->stats
.txvookint
++;
6115 priv
->ieee80211
->LinkDetectInfo
.NumTxOkInPeriod
++;
6116 rtl8192_tx_isr(dev
, VO_QUEUE
);
6120 spin_unlock_irqrestore(&priv
->irq_th_lock
, flags
);
6125 void EnableHWSecurityConfig8192(struct net_device
*dev
)
6127 u8 SECR_value
= 0x0;
6128 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
6129 struct ieee80211_device
* ieee
= priv
->ieee80211
;
6131 SECR_value
= SCR_TxEncEnable
| SCR_RxDecEnable
;
6133 if (((KEY_TYPE_WEP40
== ieee
->pairwise_key_type
) || (KEY_TYPE_WEP104
== ieee
->pairwise_key_type
)) && (priv
->ieee80211
->auth_mode
!= 2))
6135 SECR_value
|= SCR_RxUseDK
;
6136 SECR_value
|= SCR_TxUseDK
;
6138 else if ((ieee
->iw_mode
== IW_MODE_ADHOC
) && (ieee
->pairwise_key_type
& (KEY_TYPE_CCMP
| KEY_TYPE_TKIP
)))
6140 SECR_value
|= SCR_RxUseDK
;
6141 SECR_value
|= SCR_TxUseDK
;
6146 //add HWSec active enable here.
6147 //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
6148 ieee
->hwsec_active
= 1;
6150 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
6152 ieee
->hwsec_active
= 0;
6153 SECR_value
&= ~SCR_RxDecEnable
;
6156 RT_TRACE(COMP_SEC
,"%s:, hwsec:%d, pairwise_key:%d, SECR_value:%x\n", __FUNCTION__
,
6157 ieee
->hwsec_active
, ieee
->pairwise_key_type
, SECR_value
);
6159 write_nic_byte(dev
, SECR
, SECR_value
);//SECR_value | SCR_UseDK );
6163 #define TOTAL_CAM_ENTRY 32
6164 //#define CAM_CONTENT_COUNT 8
6165 void setKey( struct net_device
*dev
,
6173 u32 TargetCommand
= 0;
6174 u32 TargetContent
= 0;
6178 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
6179 RT_RF_POWER_STATE rtState
;
6180 rtState
= priv
->ieee80211
->eRFPowerState
;
6181 if(priv
->ieee80211
->PowerSaveControl
.bInactivePs
){
6182 if(rtState
== eRfOff
){
6183 if(priv
->ieee80211
->RfOffReason
> RF_CHANGE_BY_IPS
)
6185 RT_TRACE(COMP_ERR
, "%s(): RF is OFF.\n",__FUNCTION__
);
6186 //up(&priv->wx_sem);
6190 down(&priv
->ieee80211
->ips_sem
);
6192 up(&priv
->ieee80211
->ips_sem
);
6196 priv
->ieee80211
->is_set_key
= true;
6198 if (EntryNo
>= TOTAL_CAM_ENTRY
)
6199 RT_TRACE(COMP_ERR
, "cam entry exceeds in setKey()\n");
6201 RT_TRACE(COMP_SEC
, "====>to setKey(), dev:%p, EntryNo:%d, KeyIndex:%d, KeyType:%d, MacAddr%pM\n", dev
,EntryNo
, KeyIndex
, KeyType
, MacAddr
);
6204 usConfig
|= BIT15
| (KeyType
<<2);
6206 usConfig
|= BIT15
| (KeyType
<<2) | KeyIndex
;
6207 // usConfig |= BIT15 | (KeyType<<2) | (DefaultKey<<5) | KeyIndex;
6210 for(i
=0 ; i
<CAM_CONTENT_COUNT
; i
++){
6211 TargetCommand
= i
+CAM_CONTENT_COUNT
*EntryNo
;
6212 TargetCommand
|= BIT31
|BIT16
;
6214 if(i
==0){//MAC|Config
6215 TargetContent
= (u32
)(*(MacAddr
+0)) << 16|
6216 (u32
)(*(MacAddr
+1)) << 24|
6219 write_nic_dword(dev
, WCAMI
, TargetContent
);
6220 write_nic_dword(dev
, RWCAM
, TargetCommand
);
6221 // printk("setkey cam =%8x\n", read_cam(dev, i+6*EntryNo));
6224 TargetContent
= (u32
)(*(MacAddr
+2)) |
6225 (u32
)(*(MacAddr
+3)) << 8|
6226 (u32
)(*(MacAddr
+4)) << 16|
6227 (u32
)(*(MacAddr
+5)) << 24;
6228 write_nic_dword(dev
, WCAMI
, TargetContent
);
6229 write_nic_dword(dev
, RWCAM
, TargetCommand
);
6231 else { //Key Material
6232 if(KeyContent
!= NULL
)
6234 write_nic_dword(dev
, WCAMI
, (u32
)(*(KeyContent
+i
-2)) );
6235 write_nic_dword(dev
, RWCAM
, TargetCommand
);
6239 RT_TRACE(COMP_SEC
,"=========>after set key, usconfig:%x\n", usConfig
);
6242 bool NicIFEnableNIC(struct net_device
* dev
)
6244 RT_STATUS init_status
= RT_STATUS_SUCCESS
;
6245 struct r8192_priv
* priv
= ieee80211_priv(dev
);
6246 PRT_POWER_SAVE_CONTROL pPSC
= (PRT_POWER_SAVE_CONTROL
)(&(priv
->ieee80211
->PowerSaveControl
));
6250 RT_TRACE(COMP_ERR
, "ERR!!! %s(): Driver is already down!\n",__FUNCTION__
);
6251 priv
->bdisable_nic
= false; //YJ,add,091111
6254 // <1> Reset memory: descriptor, buffer,..
6255 //NicIFResetMemory(Adapter);
6257 // <2> Enable Adapter
6258 //priv->bfirst_init = true;
6259 init_status
= rtl8192_adapter_start(dev
);
6260 if (init_status
!= RT_STATUS_SUCCESS
) {
6261 RT_TRACE(COMP_ERR
,"ERR!!! %s(): initialization is failed!\n",__FUNCTION__
);
6262 priv
->bdisable_nic
= false; //YJ,add,091111
6265 //printk("start adapter finished\n");
6266 RT_CLEAR_PS_LEVEL(pPSC
, RT_RF_OFF_LEVL_HALT_NIC
);
6267 //priv->bfirst_init = false;
6269 // <3> Enable Interrupt
6270 rtl8192_irq_enable(dev
);
6271 priv
->bdisable_nic
= false;
6273 return (init_status
== RT_STATUS_SUCCESS
);
6276 bool NicIFDisableNIC(struct net_device
* dev
)
6279 struct r8192_priv
* priv
= ieee80211_priv(dev
);
6281 // <1> Disable Interrupt
6283 priv
->bdisable_nic
= true; //YJ,move,091109
6284 tmp_state
= priv
->ieee80211
->state
;
6286 ieee80211_softmac_stop_protocol(priv
->ieee80211
, false);
6288 priv
->ieee80211
->state
= tmp_state
;
6289 rtl8192_cancel_deferred_work(priv
);
6290 rtl8192_irq_disable(dev
);
6291 // <2> Stop all timer
6293 // <3> Disable Adapter
6294 rtl8192_halt_adapter(dev
, false);
6295 // priv->bdisable_nic = true;
6300 module_init(rtl8192_pci_module_init
);
6301 module_exit(rtl8192_pci_module_exit
);