1 /******************************************************************************
2 * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
3 * Linux device driver for RTL8190P / RTL8192E
5 * Based on the r8180 driver, which is:
6 * Copyright 2004-2005 Andrea Merello <andreamrl@tiscali.it>, et al.
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of version 2 of the GNU General Public License as
9 * published by the Free Software Foundation.
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 * You should have received a copy of the GNU General Public License along with
17 * this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
20 * The full GNU General Public License is included in this distribution in the
21 * file called LICENSE.
23 * Contact Information:
24 * Jerry chuang <wlanfae@realtek.com>
29 #undef RX_DONT_PASS_UL
31 #undef DEBUG_RX_VERBOSE
37 #undef DEBUG_TX_FILLDESC
42 #undef DEBUG_REGISTERS
44 #undef DEBUG_IRQ_TASKLET
48 //#define CONFIG_RTL8192_IO_MAP
49 #include <linux/vmalloc.h>
50 #include <linux/slab.h>
51 #include <asm/uaccess.h>
52 #include "r8192E_hw.h"
54 #include "r8190_rtl8256.h" /* RTL8225 Radio frontend */
55 #include "r8180_93cx6.h" /* Card EEPROM */
56 #include "r8192E_wx.h"
57 #include "r819xE_phy.h" //added by WB 4.30.2008
58 #include "r819xE_phyreg.h"
59 #include "r819xE_cmdpkt.h"
60 #include "r8192E_dm.h"
61 //#include "r8192xU_phyreg.h"
62 //#include <linux/usb.h>
63 // FIXME: check if 2.6.7 is ok
70 #include "ieee80211/dot11d.h"
73 //set here to open your trace code. //WB
74 u32 rt_global_debug_component
=
92 // COMP_POWER_TRACKING |
94 COMP_ERR
; //always open err flags on
96 static const struct pci_device_id rtl8192_pci_id_tbl
[] __devinitdata
= {
100 { PCI_DEVICE(0x10ec, 0x8190) },
102 { PCI_DEVICE(0x07aa, 0x0045) },
103 { PCI_DEVICE(0x07aa, 0x0046) },
106 { PCI_DEVICE(0x10ec, 0x8192) },
109 { PCI_DEVICE(0x07aa, 0x0044) },
110 { PCI_DEVICE(0x07aa, 0x0047) },
115 static char ifname
[IFNAMSIZ
] = "wlan%d";
116 static int hwwep
= 1; //default use hw. set 0 to use software security
117 static int channels
= 0x3fff;
119 MODULE_LICENSE("GPL");
120 MODULE_VERSION("V 1.1");
121 MODULE_DEVICE_TABLE(pci
, rtl8192_pci_id_tbl
);
122 //MODULE_AUTHOR("Andrea Merello <andreamrl@tiscali.it>");
123 MODULE_DESCRIPTION("Linux driver for Realtek RTL819x WiFi cards");
126 module_param_string(ifname
, ifname
, sizeof(ifname
), S_IRUGO
|S_IWUSR
);
127 //module_param(hwseqnum,int, S_IRUGO|S_IWUSR);
128 module_param(hwwep
,int, S_IRUGO
|S_IWUSR
);
129 module_param(channels
,int, S_IRUGO
|S_IWUSR
);
131 MODULE_PARM_DESC(ifname
," Net interface name, wlan%d=default");
132 //MODULE_PARM_DESC(hwseqnum," Try to use hardware 802.11 header sequence numbers. Zero=default");
133 MODULE_PARM_DESC(hwwep
," Try to use hardware WEP support. Still broken and not available on all cards");
134 MODULE_PARM_DESC(channels
," Channel bitmask for specific locales. NYI");
136 static int __devinit
rtl8192_pci_probe(struct pci_dev
*pdev
,
137 const struct pci_device_id
*id
);
138 static void __devexit
rtl8192_pci_disconnect(struct pci_dev
*pdev
);
140 static struct pci_driver rtl8192_pci_driver
= {
141 .name
= RTL819xE_MODULE_NAME
, /* Driver name */
142 .id_table
= rtl8192_pci_id_tbl
, /* PCI_ID table */
143 .probe
= rtl8192_pci_probe
, /* probe fn */
144 .remove
= __devexit_p(rtl8192_pci_disconnect
), /* remove fn */
146 .suspend
= rtl8192E_suspend
, /* PM suspend fn */
147 .resume
= rtl8192E_resume
, /* PM resume fn */
149 .suspend
= NULL
, /* PM suspend fn */
150 .resume
= NULL
, /* PM resume fn */
154 static void rtl8192_start_beacon(struct net_device
*dev
);
155 static void rtl8192_stop_beacon(struct net_device
*dev
);
156 static void rtl819x_watchdog_wqcallback(struct work_struct
*work
);
157 static void rtl8192_irq_rx_tasklet(struct r8192_priv
*priv
);
158 static void rtl8192_irq_tx_tasklet(struct r8192_priv
*priv
);
159 static void rtl8192_prepare_beacon(struct r8192_priv
*priv
);
160 static irqreturn_t
rtl8192_interrupt(int irq
, void *netdev
);
161 static void rtl8192_try_wake_queue(struct net_device
*dev
, int pri
);
162 static void rtl819xE_tx_cmd(struct net_device
*dev
, struct sk_buff
*skb
);
166 typedef struct _CHANNEL_LIST
170 }CHANNEL_LIST
, *PCHANNEL_LIST
;
172 static const CHANNEL_LIST ChannelPlan
[] = {
173 {{1,2,3,4,5,6,7,8,9,10,11,36,40,44,48,52,56,60,64,149,153,157,161,165},24}, //FCC
174 {{1,2,3,4,5,6,7,8,9,10,11},11}, //IC
175 {{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48,52,56,60,64},21}, //ETSI
176 {{1,2,3,4,5,6,7,8,9,10,11,12,13},13}, //Spain. Change to ETSI.
177 {{1,2,3,4,5,6,7,8,9,10,11,12,13},13}, //France. Change to ETSI.
178 {{1,2,3,4,5,6,7,8,9,10,11,12,13,14,36,40,44,48,52,56,60,64},22}, //MKK //MKK
179 {{1,2,3,4,5,6,7,8,9,10,11,12,13,14,36,40,44,48,52,56,60,64},22},//MKK1
180 {{1,2,3,4,5,6,7,8,9,10,11,12,13},13}, //Israel.
181 {{1,2,3,4,5,6,7,8,9,10,11,12,13,14,36,40,44,48,52,56,60,64},22}, // For 11a , TELEC
182 {{1,2,3,4,5,6,7,8,9,10,11,12,13,14,36,40,44,48,52,56,60,64}, 22}, //MIC
183 {{1,2,3,4,5,6,7,8,9,10,11,12,13,14},14} //For Global Domain. 1-11:active scan, 12-14 passive scan. //+YJ, 080626
186 static void rtl819x_set_channel_map(u8 channel_plan
, struct r8192_priv
* priv
)
188 int i
, max_chan
=-1, min_chan
=-1;
189 struct ieee80211_device
* ieee
= priv
->ieee80211
;
190 switch (channel_plan
)
192 case COUNTRY_CODE_FCC
:
193 case COUNTRY_CODE_IC
:
194 case COUNTRY_CODE_ETSI
:
195 case COUNTRY_CODE_SPAIN
:
196 case COUNTRY_CODE_FRANCE
:
197 case COUNTRY_CODE_MKK
:
198 case COUNTRY_CODE_MKK1
:
199 case COUNTRY_CODE_ISRAEL
:
200 case COUNTRY_CODE_TELEC
:
201 case COUNTRY_CODE_MIC
:
204 ieee
->bGlobalDomain
= false;
205 //acturally 8225 & 8256 rf chip only support B,G,24N mode
206 if ((priv
->rf_chip
== RF_8225
) || (priv
->rf_chip
== RF_8256
))
213 RT_TRACE(COMP_ERR
, "unknown rf chip, can't set channel map in function:%s()\n", __FUNCTION__
);
215 if (ChannelPlan
[channel_plan
].Len
!= 0){
216 // Clear old channel map
217 memset(GET_DOT11D_INFO(ieee
)->channel_map
, 0, sizeof(GET_DOT11D_INFO(ieee
)->channel_map
));
218 // Set new channel map
219 for (i
=0;i
<ChannelPlan
[channel_plan
].Len
;i
++)
221 if (ChannelPlan
[channel_plan
].Channel
[i
] < min_chan
|| ChannelPlan
[channel_plan
].Channel
[i
] > max_chan
)
223 GET_DOT11D_INFO(ieee
)->channel_map
[ChannelPlan
[channel_plan
].Channel
[i
]] = 1;
228 case COUNTRY_CODE_GLOBAL_DOMAIN
:
230 GET_DOT11D_INFO(ieee
)->bEnabled
= 0; //this flag enabled to follow 11d country IE setting, otherwise, it shall follow global domain setting
232 ieee
->bGlobalDomain
= true;
242 #define eqMacAddr(a,b) ( ((a)[0]==(b)[0] && (a)[1]==(b)[1] && (a)[2]==(b)[2] && (a)[3]==(b)[3] && (a)[4]==(b)[4] && (a)[5]==(b)[5]) ? 1:0 )
243 /* 2007/07/25 MH Defien temp tx fw info. */
244 static TX_FWINFO_T Tmp_TxFwInfo
;
247 #define rx_hal_is_cck_rate(_pdrvinfo)\
248 (_pdrvinfo->RxRate == DESC90_RATE1M ||\
249 _pdrvinfo->RxRate == DESC90_RATE2M ||\
250 _pdrvinfo->RxRate == DESC90_RATE5_5M ||\
251 _pdrvinfo->RxRate == DESC90_RATE11M) &&\
255 void CamResetAllEntry(struct net_device *dev)
261 ulcommand
|= BIT31
|BIT30
;
262 write_nic_dword(dev
, RWCAM
, ulcommand
);
264 for(ucIndex
=0;ucIndex
<TOTAL_CAM_ENTRY
;ucIndex
++)
265 CAM_mark_invalid(dev
, ucIndex
);
266 for(ucIndex
=0;ucIndex
<TOTAL_CAM_ENTRY
;ucIndex
++)
267 CAM_empty_entry(dev
, ucIndex
);
272 void write_cam(struct net_device
*dev
, u8 addr
, u32 data
)
274 write_nic_dword(dev
, WCAMI
, data
);
275 write_nic_dword(dev
, RWCAM
, BIT31
|BIT16
|(addr
&0xff) );
277 u32
read_cam(struct net_device
*dev
, u8 addr
)
279 write_nic_dword(dev
, RWCAM
, 0x80000000|(addr
&0xff) );
280 return read_nic_dword(dev
, 0xa8);
283 ////////////////////////////////////////////////////////////
284 #ifdef CONFIG_RTL8180_IO_MAP
286 u8
read_nic_byte(struct net_device
*dev
, int x
)
288 return 0xff&inb(dev
->base_addr
+x
);
291 u32
read_nic_dword(struct net_device
*dev
, int x
)
293 return inl(dev
->base_addr
+x
);
296 u16
read_nic_word(struct net_device
*dev
, int x
)
298 return inw(dev
->base_addr
+x
);
301 void write_nic_byte(struct net_device
*dev
, int x
,u8 y
)
303 outb(y
&0xff,dev
->base_addr
+x
);
306 void write_nic_word(struct net_device
*dev
, int x
,u16 y
)
308 outw(y
,dev
->base_addr
+x
);
311 void write_nic_dword(struct net_device
*dev
, int x
,u32 y
)
313 outl(y
,dev
->base_addr
+x
);
316 #else /* RTL_IO_MAP */
318 u8
read_nic_byte(struct net_device
*dev
, int x
)
320 return 0xff&readb((u8
*)dev
->mem_start
+x
);
323 u32
read_nic_dword(struct net_device
*dev
, int x
)
325 return readl((u8
*)dev
->mem_start
+x
);
328 u16
read_nic_word(struct net_device
*dev
, int x
)
330 return readw((u8
*)dev
->mem_start
+x
);
333 void write_nic_byte(struct net_device
*dev
, int x
,u8 y
)
335 writeb(y
,(u8
*)dev
->mem_start
+x
);
339 void write_nic_dword(struct net_device
*dev
, int x
,u32 y
)
341 writel(y
,(u8
*)dev
->mem_start
+x
);
345 void write_nic_word(struct net_device
*dev
, int x
,u16 y
)
347 writew(y
,(u8
*)dev
->mem_start
+x
);
351 #endif /* RTL_IO_MAP */
353 u8
rtl8192e_ap_sec_type(struct ieee80211_device
*ieee
)
355 //struct r8192_priv* priv = ieee80211_priv(dev);
356 //struct ieee80211_device *ieee = priv->ieee80211;
358 static const u8 ccmp_ie
[4] = {0x00,0x50,0xf2,0x04};
359 static const u8 ccmp_rsn_ie
[4] = {0x00, 0x0f, 0xac, 0x04};
360 int wpa_ie_len
= ieee
->wpa_ie_len
;
361 struct ieee80211_crypt_data
* crypt
;
364 crypt
= ieee
->crypt
[ieee
->tx_keyidx
];
366 encrypt
= (ieee
->current_network
.capability
& WLAN_CAPABILITY_PRIVACY
) ||
367 (ieee
->host_encrypt
&& crypt
&& crypt
->ops
&&
368 (0 == strcmp(crypt
->ops
->name
,"WEP")));
371 if(encrypt
&& (wpa_ie_len
== 0)) {
372 // wep encryption, no N mode setting */
374 } else if((wpa_ie_len
!= 0)) {
375 // parse pairwise key type */
376 if (((ieee
->wpa_ie
[0] == 0xdd) && (!memcmp(&(ieee
->wpa_ie
[14]),ccmp_ie
,4))) ||
377 ((ieee
->wpa_ie
[0] == 0x30) && (!memcmp(&ieee
->wpa_ie
[10],ccmp_rsn_ie
, 4))))
387 rtl8192e_SetHwReg(struct net_device
*dev
,u8 variable
,u8
* val
)
389 struct r8192_priv
* priv
= ieee80211_priv(dev
);
395 write_nic_dword(dev
, BSSIDR
, ((u32
*)(val
))[0]);
396 write_nic_word(dev
, BSSIDR
+2, ((u16
*)(val
+2))[0]);
399 case HW_VAR_MEDIA_STATUS
:
401 RT_OP_MODE OpMode
= *((RT_OP_MODE
*)(val
));
402 //LED_CTL_MODE LedAction = LED_CTL_NO_LINK;
403 u8 btMsr
= read_nic_byte(dev
, MSR
);
409 case RT_OP_MODE_INFRASTRUCTURE
:
411 //LedAction = LED_CTL_LINK;
414 case RT_OP_MODE_IBSS
:
416 // led link set separate
421 //LedAction = LED_CTL_LINK;
429 write_nic_byte(dev
, MSR
, btMsr
);
431 //priv->ieee80211->LedControlHandler(dev, LedAction);
435 case HW_VAR_CECHK_BSSID
:
439 Type
= ((u8
*)(val
))[0];
440 //priv->ieee80211->GetHwRegHandler(dev, HW_VAR_RCR, (u8*)(&RegRCR));
441 RegRCR
= read_nic_dword(dev
,RCR
);
442 priv
->ReceiveConfig
= RegRCR
;
445 RegRCR
|= (RCR_CBSSID
);
446 else if (Type
== false)
447 RegRCR
&= (~RCR_CBSSID
);
449 //priv->ieee80211->SetHwRegHandler( dev, HW_VAR_RCR, (u8*)(&RegRCR) );
450 write_nic_dword(dev
, RCR
,RegRCR
);
451 priv
->ReceiveConfig
= RegRCR
;
456 case HW_VAR_SLOT_TIME
:
458 //PSTA_QOS pStaQos = Adapter->MgntInfo.pStaQos;
461 priv
->slot_time
= val
[0];
462 write_nic_byte(dev
, SLOT_TIME
, val
[0]);
467 case HW_VAR_ACK_PREAMBLE
:
470 priv
->short_preamble
= (bool)(*(u8
*)val
);
471 regTmp
= priv
->basic_rate
;
472 if (priv
->short_preamble
)
473 regTmp
|= BRSR_AckShortPmb
;
474 write_nic_dword(dev
, RRSR
, regTmp
);
479 write_nic_dword(dev
, CPU_GEN
, ((u32
*)(val
))[0]);
489 ///////////////////////////////////////////////////////////
491 //u8 read_phy_cck(struct net_device *dev, u8 adr);
492 //u8 read_phy_ofdm(struct net_device *dev, u8 adr);
493 /* this might still called in what was the PHY rtl8185/rtl8192 common code
494 * plans are to possibilty turn it again in one common code...
496 void force_pci_posting(struct net_device
*dev
)
502 //static struct net_device_stats *rtl8192_stats(struct net_device *dev);
503 //void rtl8192_restart(struct net_device *dev);
504 void rtl8192_restart(struct work_struct
*work
);
505 //void rtl8192_rq_tx_ack(struct work_struct *work);
507 void watch_dog_timer_callback(unsigned long data
);
508 /****************************************************************************
509 -----------------------------PROCFS STUFF-------------------------
510 *****************************************************************************/
512 static struct proc_dir_entry
*rtl8192_proc
= NULL
;
516 static int proc_get_stats_ap(char *page
, char **start
,
517 off_t offset
, int count
,
518 int *eof
, void *data
)
520 struct net_device
*dev
= data
;
521 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
522 struct ieee80211_device
*ieee
= priv
->ieee80211
;
523 struct ieee80211_network
*target
;
527 list_for_each_entry(target
, &ieee
->network_list
, list
) {
529 len
+= snprintf(page
+ len
, count
- len
,
530 "%s ", target
->ssid
);
532 if(target
->wpa_ie_len
>0 || target
->rsn_ie_len
>0){
533 len
+= snprintf(page
+ len
, count
- len
,
537 len
+= snprintf(page
+ len
, count
- len
,
547 static int proc_get_registers(char *page
, char **start
,
548 off_t offset
, int count
,
549 int *eof
, void *data
)
551 struct net_device
*dev
= data
;
552 // struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
559 /* This dump the current register page */
560 len
+= snprintf(page
+ len
, count
- len
,
561 "\n####################page 0##################\n ");
565 //printk( "\nD: %2x> ", n);
566 len
+= snprintf(page
+ len
, count
- len
,
569 for(i
=0;i
<16 && n
<=max
;i
++,n
++)
570 len
+= snprintf(page
+ len
, count
- len
,
571 "%2x ",read_nic_byte(dev
,n
));
573 // printk("%2x ",read_nic_byte(dev,n));
575 len
+= snprintf(page
+ len
, count
- len
,"\n");
576 len
+= snprintf(page
+ len
, count
- len
,
577 "\n####################page 1##################\n ");
580 //printk( "\nD: %2x> ", n);
581 len
+= snprintf(page
+ len
, count
- len
,
584 for(i
=0;i
<16 && n
<=max
;i
++,n
++)
585 len
+= snprintf(page
+ len
, count
- len
,
586 "%2x ",read_nic_byte(dev
,0x100|n
));
588 // printk("%2x ",read_nic_byte(dev,n));
591 len
+= snprintf(page
+ len
, count
- len
,
592 "\n####################page 3##################\n ");
595 //printk( "\nD: %2x> ", n);
596 len
+= snprintf(page
+ len
, count
- len
,
599 for(i
=0;i
<16 && n
<=max
;i
++,n
++)
600 len
+= snprintf(page
+ len
, count
- len
,
601 "%2x ",read_nic_byte(dev
,0x300|n
));
603 // printk("%2x ",read_nic_byte(dev,n));
614 static int proc_get_stats_tx(char *page
, char **start
,
615 off_t offset
, int count
,
616 int *eof
, void *data
)
618 struct net_device
*dev
= data
;
619 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
623 len
+= snprintf(page
+ len
, count
- len
,
624 "TX VI priority ok int: %lu\n"
625 // "TX VI priority error int: %lu\n"
626 "TX VO priority ok int: %lu\n"
627 // "TX VO priority error int: %lu\n"
628 "TX BE priority ok int: %lu\n"
629 // "TX BE priority error int: %lu\n"
630 "TX BK priority ok int: %lu\n"
631 // "TX BK priority error int: %lu\n"
632 "TX MANAGE priority ok int: %lu\n"
633 // "TX MANAGE priority error int: %lu\n"
634 "TX BEACON priority ok int: %lu\n"
635 "TX BEACON priority error int: %lu\n"
636 "TX CMDPKT priority ok int: %lu\n"
637 // "TX high priority ok int: %lu\n"
638 // "TX high priority failed error int: %lu\n"
639 // "TX queue resume: %lu\n"
640 "TX queue stopped?: %d\n"
641 "TX fifo overflow: %lu\n"
642 // "TX beacon: %lu\n"
643 // "TX VI queue: %d\n"
644 // "TX VO queue: %d\n"
645 // "TX BE queue: %d\n"
646 // "TX BK queue: %d\n"
647 // "TX HW queue: %d\n"
648 // "TX VI dropped: %lu\n"
649 // "TX VO dropped: %lu\n"
650 // "TX BE dropped: %lu\n"
651 // "TX BK dropped: %lu\n"
652 "TX total data packets %lu\n"
653 "TX total data bytes :%lu\n",
654 // "TX beacon aborted: %lu\n",
655 priv
->stats
.txviokint
,
656 // priv->stats.txvierr,
657 priv
->stats
.txvookint
,
658 // priv->stats.txvoerr,
659 priv
->stats
.txbeokint
,
660 // priv->stats.txbeerr,
661 priv
->stats
.txbkokint
,
662 // priv->stats.txbkerr,
663 priv
->stats
.txmanageokint
,
664 // priv->stats.txmanageerr,
665 priv
->stats
.txbeaconokint
,
666 priv
->stats
.txbeaconerr
,
667 priv
->stats
.txcmdpktokint
,
668 // priv->stats.txhpokint,
669 // priv->stats.txhperr,
670 // priv->stats.txresumed,
671 netif_queue_stopped(dev
),
672 priv
->stats
.txoverflow
,
673 // priv->stats.txbeacon,
674 // atomic_read(&(priv->tx_pending[VI_QUEUE])),
675 // atomic_read(&(priv->tx_pending[VO_QUEUE])),
676 // atomic_read(&(priv->tx_pending[BE_QUEUE])),
677 // atomic_read(&(priv->tx_pending[BK_QUEUE])),
678 // read_nic_byte(dev, TXFIFOCOUNT),
679 // priv->stats.txvidrop,
680 // priv->stats.txvodrop,
681 priv
->ieee80211
->stats
.tx_packets
,
682 priv
->ieee80211
->stats
.tx_bytes
685 // priv->stats.txbedrop,
686 // priv->stats.txbkdrop
687 // priv->stats.txdatapkt
688 // priv->stats.txbeaconerr
697 static int proc_get_stats_rx(char *page
, char **start
,
698 off_t offset
, int count
,
699 int *eof
, void *data
)
701 struct net_device
*dev
= data
;
702 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
706 len
+= snprintf(page
+ len
, count
- len
,
709 "RX rx overflow error: %lu\n"
710 "RX invalid urb error: %lu\n",
713 priv
->stats
.rxoverflow
,
714 priv
->stats
.rxurberr
);
720 static void rtl8192_proc_module_init(void)
722 RT_TRACE(COMP_INIT
, "Initializing proc filesystem");
723 rtl8192_proc
=create_proc_entry(RTL819xE_MODULE_NAME
, S_IFDIR
, init_net
.proc_net
);
727 static void rtl8192_proc_module_remove(void)
729 remove_proc_entry(RTL819xE_MODULE_NAME
, init_net
.proc_net
);
733 static void rtl8192_proc_remove_one(struct net_device
*dev
)
735 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
737 printk("dev name=======> %s\n",dev
->name
);
740 // remove_proc_entry("stats-hw", priv->dir_dev);
741 remove_proc_entry("stats-tx", priv
->dir_dev
);
742 remove_proc_entry("stats-rx", priv
->dir_dev
);
743 // remove_proc_entry("stats-ieee", priv->dir_dev);
744 remove_proc_entry("stats-ap", priv
->dir_dev
);
745 remove_proc_entry("registers", priv
->dir_dev
);
746 // remove_proc_entry("cck-registers",priv->dir_dev);
747 // remove_proc_entry("ofdm-registers",priv->dir_dev);
748 //remove_proc_entry(dev->name, rtl8192_proc);
749 remove_proc_entry("wlan0", rtl8192_proc
);
750 priv
->dir_dev
= NULL
;
755 static void rtl8192_proc_init_one(struct net_device
*dev
)
757 struct proc_dir_entry
*e
;
758 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
759 priv
->dir_dev
= create_proc_entry(dev
->name
,
760 S_IFDIR
| S_IRUGO
| S_IXUGO
,
762 if (!priv
->dir_dev
) {
763 RT_TRACE(COMP_ERR
, "Unable to initialize /proc/net/rtl8192/%s\n",
767 e
= create_proc_read_entry("stats-rx", S_IFREG
| S_IRUGO
,
768 priv
->dir_dev
, proc_get_stats_rx
, dev
);
771 RT_TRACE(COMP_ERR
,"Unable to initialize "
772 "/proc/net/rtl8192/%s/stats-rx\n",
777 e
= create_proc_read_entry("stats-tx", S_IFREG
| S_IRUGO
,
778 priv
->dir_dev
, proc_get_stats_tx
, dev
);
781 RT_TRACE(COMP_ERR
, "Unable to initialize "
782 "/proc/net/rtl8192/%s/stats-tx\n",
786 e
= create_proc_read_entry("stats-ap", S_IFREG
| S_IRUGO
,
787 priv
->dir_dev
, proc_get_stats_ap
, dev
);
790 RT_TRACE(COMP_ERR
, "Unable to initialize "
791 "/proc/net/rtl8192/%s/stats-ap\n",
795 e
= create_proc_read_entry("registers", S_IFREG
| S_IRUGO
,
796 priv
->dir_dev
, proc_get_registers
, dev
);
798 RT_TRACE(COMP_ERR
, "Unable to initialize "
799 "/proc/net/rtl8192/%s/registers\n",
803 /****************************************************************************
804 -----------------------------MISC STUFF-------------------------
805 *****************************************************************************/
807 short check_nic_enough_desc(struct net_device
*dev
, int prio
)
809 struct r8192_priv
*priv
= ieee80211_priv(dev
);
810 struct rtl8192_tx_ring
*ring
= &priv
->tx_ring
[prio
];
812 /* for now we reserve two free descriptor as a safety boundary
813 * between the tail and the head
815 return (ring
->entries
- skb_queue_len(&ring
->queue
) >= 2);
818 static void tx_timeout(struct net_device
*dev
)
820 struct r8192_priv
*priv
= ieee80211_priv(dev
);
821 //rtl8192_commit(dev);
823 schedule_work(&priv
->reset_wq
);
828 /****************************************************************************
829 ------------------------------HW STUFF---------------------------
830 *****************************************************************************/
833 static void rtl8192_irq_enable(struct net_device
*dev
)
835 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
836 priv
->irq_enabled
= 1;
837 write_nic_dword(dev
,INTA_MASK
, priv
->irq_mask
);
841 void rtl8192_irq_disable(struct net_device
*dev
)
843 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
845 write_nic_dword(dev
,INTA_MASK
,0);
846 force_pci_posting(dev
);
847 priv
->irq_enabled
= 0;
852 static void rtl8192_set_mode(struct net_device
*dev
,int mode
)
855 ecmd
=read_nic_byte(dev
, EPROM_CMD
);
856 ecmd
=ecmd
&~ EPROM_CMD_OPERATING_MODE_MASK
;
857 ecmd
=ecmd
| (mode
<<EPROM_CMD_OPERATING_MODE_SHIFT
);
858 ecmd
=ecmd
&~ (1<<EPROM_CS_SHIFT
);
859 ecmd
=ecmd
&~ (1<<EPROM_CK_SHIFT
);
860 write_nic_byte(dev
, EPROM_CMD
, ecmd
);
864 void rtl8192_update_msr(struct net_device
*dev
)
866 struct r8192_priv
*priv
= ieee80211_priv(dev
);
869 msr
= read_nic_byte(dev
, MSR
);
870 msr
&= ~ MSR_LINK_MASK
;
872 /* do not change in link_state != WLAN_LINK_ASSOCIATED.
873 * msr must be updated if the state is ASSOCIATING.
874 * this is intentional and make sense for ad-hoc and
875 * master (see the create BSS/IBSS func)
877 if (priv
->ieee80211
->state
== IEEE80211_LINKED
){
879 if (priv
->ieee80211
->iw_mode
== IW_MODE_INFRA
)
880 msr
|= (MSR_LINK_MANAGED
<<MSR_LINK_SHIFT
);
881 else if (priv
->ieee80211
->iw_mode
== IW_MODE_ADHOC
)
882 msr
|= (MSR_LINK_ADHOC
<<MSR_LINK_SHIFT
);
883 else if (priv
->ieee80211
->iw_mode
== IW_MODE_MASTER
)
884 msr
|= (MSR_LINK_MASTER
<<MSR_LINK_SHIFT
);
887 msr
|= (MSR_LINK_NONE
<<MSR_LINK_SHIFT
);
889 write_nic_byte(dev
, MSR
, msr
);
892 void rtl8192_set_chan(struct net_device
*dev
,short ch
)
894 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
895 RT_TRACE(COMP_RF
, "=====>%s()====ch:%d\n", __FUNCTION__
, ch
);
898 if(priv
->ieee80211
->iw_mode
== IW_MODE_ADHOC
||
899 priv
->ieee80211
->iw_mode
== IW_MODE_MASTER
){
901 priv
->ieee80211
->link_state
= WLAN_LINK_ASSOCIATED
;
902 priv
->ieee80211
->master_chan
= ch
;
903 rtl8192_update_beacon_ch(dev
);
907 /* this hack should avoid frame TX during channel setting*/
910 // tx = read_nic_dword(dev,TX_CONF);
911 // tx &= ~TX_LOOPBACK_MASK;
915 // write_nic_dword(dev,TX_CONF, tx |( TX_LOOPBACK_MAC<<TX_LOOPBACK_SHIFT));
917 //need to implement rf set channel here WB
919 if (priv
->rf_set_chan
)
920 priv
->rf_set_chan(dev
,priv
->chan
);
922 // write_nic_dword(dev,TX_CONF,tx | (TX_LOOPBACK_NONE<<TX_LOOPBACK_SHIFT));
926 void rtl8192_rx_enable(struct net_device
*dev
)
928 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
929 write_nic_dword(dev
, RDQDA
,priv
->rx_ring_dma
);
932 /* the TX_DESC_BASE setting is according to the following queue index
941 * BEACON_QUEUE ===> 8
943 static const u32 TX_DESC_BASE
[] = {BKQDA
, BEQDA
, VIQDA
, VOQDA
, HCCAQDA
, CQDA
, MQDA
, HQDA
, BQDA
};
944 void rtl8192_tx_enable(struct net_device
*dev
)
946 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
948 for (i
= 0; i
< MAX_TX_QUEUE_COUNT
; i
++)
949 write_nic_dword(dev
, TX_DESC_BASE
[i
], priv
->tx_ring
[i
].dma
);
951 ieee80211_reset_queue(priv
->ieee80211
);
955 static void rtl8192_free_rx_ring(struct net_device
*dev
)
957 struct r8192_priv
*priv
= ieee80211_priv(dev
);
960 for (i
= 0; i
< priv
->rxringcount
; i
++) {
961 struct sk_buff
*skb
= priv
->rx_buf
[i
];
965 pci_unmap_single(priv
->pdev
,
966 *((dma_addr_t
*)skb
->cb
),
967 priv
->rxbuffersize
, PCI_DMA_FROMDEVICE
);
971 pci_free_consistent(priv
->pdev
, sizeof(*priv
->rx_ring
) * priv
->rxringcount
,
972 priv
->rx_ring
, priv
->rx_ring_dma
);
973 priv
->rx_ring
= NULL
;
976 static void rtl8192_free_tx_ring(struct net_device
*dev
, unsigned int prio
)
978 struct r8192_priv
*priv
= ieee80211_priv(dev
);
979 struct rtl8192_tx_ring
*ring
= &priv
->tx_ring
[prio
];
981 while (skb_queue_len(&ring
->queue
)) {
982 tx_desc_819x_pci
*entry
= &ring
->desc
[ring
->idx
];
983 struct sk_buff
*skb
= __skb_dequeue(&ring
->queue
);
985 pci_unmap_single(priv
->pdev
, le32_to_cpu(entry
->TxBuffAddr
),
986 skb
->len
, PCI_DMA_TODEVICE
);
988 ring
->idx
= (ring
->idx
+ 1) % ring
->entries
;
991 pci_free_consistent(priv
->pdev
, sizeof(*ring
->desc
)*ring
->entries
,
992 ring
->desc
, ring
->dma
);
997 static void rtl8192_beacon_disable(struct net_device
*dev
)
999 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
1002 reg
= read_nic_dword(priv
->ieee80211
->dev
,INTA_MASK
);
1004 /* disable Beacon realted interrupt signal */
1005 reg
&= ~(IMR_BcnInt
| IMR_BcnInt
| IMR_TBDOK
| IMR_TBDER
);
1006 write_nic_dword(priv
->ieee80211
->dev
, INTA_MASK
, reg
);
1010 void PHY_SetRtl8192eRfOff(struct net_device
* dev
)
1012 //struct r8192_priv *priv = ieee80211_priv(dev);
1014 //disable RF-Chip A/B
1015 rtl8192_setBBreg(dev
, rFPGA0_XA_RFInterfaceOE
, BIT4
, 0x0);
1016 //analog to digital off, for power save
1017 rtl8192_setBBreg(dev
, rFPGA0_AnalogParameter4
, 0x300, 0x0);
1018 //digital to analog off, for power save
1019 rtl8192_setBBreg(dev
, rFPGA0_AnalogParameter1
, 0x18, 0x0);
1021 rtl8192_setBBreg(dev
, rOFDM0_TRxPathEnable
, 0xf, 0x0);
1023 rtl8192_setBBreg(dev
, rOFDM1_TRxPathEnable
, 0xf, 0x0);
1024 //analog to digital part2 off, for power save
1025 rtl8192_setBBreg(dev
, rFPGA0_AnalogParameter1
, 0x60, 0x0);
1026 rtl8192_setBBreg(dev
, rFPGA0_AnalogParameter1
, 0x4, 0x0);
1027 // Analog parameter!!Change bias and Lbus control.
1028 write_nic_byte(dev
, ANAPAR_FOR_8192PciE
, 0x07);
1032 void rtl8192_halt_adapter(struct net_device
*dev
, bool reset
)
1035 struct r8192_priv
*priv
= ieee80211_priv(dev
);
1041 OpMode
= RT_OP_MODE_NO_LINK
;
1042 priv
->ieee80211
->SetHwRegHandler(dev
, HW_VAR_MEDIA_STATUS
, &OpMode
);
1045 if(!priv
->ieee80211
->bSupportRemoteWakeUp
)
1047 u1bTmp
= 0x0; // disable tx/rx. In 8185 we write 0x10 (Reset bit), but here we make reference to WMAC and wirte 0x0. 2006.11.21 Emily
1048 //priv->ieee80211->SetHwRegHandler(dev, HW_VAR_COMMAND, &u1bTmp ); // Using HW_VAR_COMMAND instead of writing CMDR directly. Rewrited by Annie, 2006-04-07.
1049 write_nic_byte(dev
, CMDR
, u1bTmp
);
1052 cmd
=read_nic_byte(dev
,CMDR
);
1053 write_nic_byte(dev
, CMDR
, cmd
&~ (CR_TE
|CR_RE
));
1060 //PlatformStallExecution(150000);
1064 priv
->bHwRfOffAction
= 2;
1068 // Call MgntActSet_RF_State instead to prevent RF config race condition.
1069 // By Bruce, 2008-01-17.
1071 if(!priv
->ieee80211
->bSupportRemoteWakeUp
)
1073 //MgntActSet_RF_State(Adapter, eRfOff, RF_CHANGE_BY_INIT);
1074 //MgntActSet_RF_State(Adapter, eRfOff, Adapter->MgntInfo.RfOffReason);
1075 //if(Adapter->HardwareType == HARDWARE_TYPE_RTL8190P)
1077 PHY_SetRtl8192eRfOff(dev
);
1079 // 2006.11.30. System reset bit
1080 //priv->ieee80211->GetHwRegHandler(dev, HW_VAR_CPU_RST, (u32*)(&ulRegRead) );
1081 ulRegRead
= read_nic_dword(dev
,CPU_GEN
);
1082 ulRegRead
|=CPU_GEN_SYSTEM_RESET
;
1083 //priv->ieee80211->SetHwRegHandler(dev, HW_VAR_CPU_RST, &ulRegRead);
1084 write_nic_dword(dev
,CPU_GEN
, ulRegRead
);
1088 //2008.06.03 for WOL
1089 write_nic_dword(dev
, WFCRC0
, 0xffffffff);
1090 write_nic_dword(dev
, WFCRC1
, 0xffffffff);
1091 write_nic_dword(dev
, WFCRC2
, 0xffffffff);
1093 //Write PMR register
1094 write_nic_byte(dev
, PMR
, 0x5);
1095 //Disable tx, enanble rx
1096 write_nic_byte(dev
, MacBlkCtrl
, 0xa);
1100 for(i
= 0; i
< MAX_QUEUE_SIZE
; i
++) {
1101 skb_queue_purge(&priv
->ieee80211
->skb_waitQ
[i
]);
1103 for(i
= 0; i
< MAX_QUEUE_SIZE
; i
++) {
1104 skb_queue_purge(&priv
->ieee80211
->skb_aggQ
[i
]);
1107 skb_queue_purge(&priv
->skb_queue
);
1112 static void rtl8192_reset(struct net_device
*dev
)
1114 rtl8192_irq_disable(dev
);
1115 printk("This is RTL819xP Reset procedure\n");
1119 static const u16 rtl_rate
[] = {10,20,55,110,60,90,120,180,240,360,480,540};
1120 inline u16
rtl8192_rate2rate(short rate
)
1122 if (rate
>11) return 0;
1123 return rtl_rate
[rate
];
1129 static void rtl8192_data_hard_stop(struct net_device
*dev
)
1133 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
1134 priv
->dma_poll_mask
|= (1<<TX_DMA_STOP_LOWPRIORITY_SHIFT
);
1135 rtl8192_set_mode(dev
,EPROM_CMD_CONFIG
);
1136 write_nic_byte(dev
,TX_DMA_POLLING
,priv
->dma_poll_mask
);
1137 rtl8192_set_mode(dev
,EPROM_CMD_NORMAL
);
1142 static void rtl8192_data_hard_resume(struct net_device
*dev
)
1146 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
1147 priv
->dma_poll_mask
&= ~(1<<TX_DMA_STOP_LOWPRIORITY_SHIFT
);
1148 rtl8192_set_mode(dev
,EPROM_CMD_CONFIG
);
1149 write_nic_byte(dev
,TX_DMA_POLLING
,priv
->dma_poll_mask
);
1150 rtl8192_set_mode(dev
,EPROM_CMD_NORMAL
);
1154 /* this function TX data frames when the ieee80211 stack requires this.
1155 * It checks also if we need to stop the ieee tx queue, eventually do it
1157 static void rtl8192_hard_data_xmit(struct sk_buff
*skb
, struct net_device
*dev
, int rate
)
1159 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
1161 //unsigned long flags;
1162 cb_desc
*tcb_desc
= (cb_desc
*)(skb
->cb
+ MAX_DEV_ADDR_SIZE
);
1163 u8 queue_index
= tcb_desc
->queue_index
;
1164 /* shall not be referred by command packet */
1165 assert(queue_index
!= TXCMD_QUEUE
);
1167 if((priv
->bHwRadioOff
== true)||(!priv
->up
))
1173 //spin_lock_irqsave(&priv->tx_lock,flags);
1175 memcpy((unsigned char *)(skb
->cb
),&dev
,sizeof(dev
));
1177 tcb_desc
->RATRIndex
= 7;
1178 tcb_desc
->bTxDisableRateFallBack
= 1;
1179 tcb_desc
->bTxUseDriverAssingedRate
= 1;
1180 tcb_desc
->bTxEnableFwCalcDur
= 1;
1182 skb_push(skb
, priv
->ieee80211
->tx_headroom
);
1183 ret
= rtl8192_tx(dev
, skb
);
1189 if(queue_index
!=MGNT_QUEUE
) {
1190 priv
->ieee80211
->stats
.tx_bytes
+=(skb
->len
- priv
->ieee80211
->tx_headroom
);
1191 priv
->ieee80211
->stats
.tx_packets
++;
1194 //spin_unlock_irqrestore(&priv->tx_lock,flags);
1199 /* This is a rough attempt to TX a frame
1200 * This is called by the ieee 80211 stack to TX management frames.
1201 * If the ring is full packet are dropped (for data frame the queue
1202 * is stopped before this can happen).
1204 static int rtl8192_hard_start_xmit(struct sk_buff
*skb
,struct net_device
*dev
)
1206 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
1210 //unsigned long flags;
1211 cb_desc
*tcb_desc
= (cb_desc
*)(skb
->cb
+ MAX_DEV_ADDR_SIZE
);
1212 u8 queue_index
= tcb_desc
->queue_index
;
1214 if(queue_index
!= TXCMD_QUEUE
){
1215 if((priv
->bHwRadioOff
== true)||(!priv
->up
))
1222 //spin_lock_irqsave(&priv->tx_lock,flags);
1224 memcpy((unsigned char *)(skb
->cb
),&dev
,sizeof(dev
));
1225 if(queue_index
== TXCMD_QUEUE
) {
1226 // skb_push(skb, USB_HWDESC_HEADER_LEN);
1227 rtl819xE_tx_cmd(dev
, skb
);
1229 //spin_unlock_irqrestore(&priv->tx_lock,flags);
1232 // RT_TRACE(COMP_SEND, "To send management packet\n");
1233 tcb_desc
->RATRIndex
= 7;
1234 tcb_desc
->bTxDisableRateFallBack
= 1;
1235 tcb_desc
->bTxUseDriverAssingedRate
= 1;
1236 tcb_desc
->bTxEnableFwCalcDur
= 1;
1237 skb_push(skb
, priv
->ieee80211
->tx_headroom
);
1238 ret
= rtl8192_tx(dev
, skb
);
1244 // priv->ieee80211->stats.tx_bytes+=skb->len;
1245 // priv->ieee80211->stats.tx_packets++;
1247 //spin_unlock_irqrestore(&priv->tx_lock,flags);
1254 static void rtl8192_tx_isr(struct net_device
*dev
, int prio
)
1256 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
1258 struct rtl8192_tx_ring
*ring
= &priv
->tx_ring
[prio
];
1260 while (skb_queue_len(&ring
->queue
)) {
1261 tx_desc_819x_pci
*entry
= &ring
->desc
[ring
->idx
];
1262 struct sk_buff
*skb
;
1264 /* beacon packet will only use the first descriptor defaultly,
1265 * and the OWN may not be cleared by the hardware
1267 if(prio
!= BEACON_QUEUE
) {
1270 ring
->idx
= (ring
->idx
+ 1) % ring
->entries
;
1273 skb
= __skb_dequeue(&ring
->queue
);
1274 pci_unmap_single(priv
->pdev
, le32_to_cpu(entry
->TxBuffAddr
),
1275 skb
->len
, PCI_DMA_TODEVICE
);
1279 if (prio
== MGNT_QUEUE
){
1280 if (priv
->ieee80211
->ack_tx_to_ieee
){
1281 if (rtl8192_is_tx_queue_empty(dev
)){
1282 priv
->ieee80211
->ack_tx_to_ieee
= 0;
1283 ieee80211_ps_tx_ack(priv
->ieee80211
, 1);
1288 if(prio
!= BEACON_QUEUE
) {
1289 /* try to deal with the pending packets */
1290 tasklet_schedule(&priv
->irq_tx_tasklet
);
1295 static void rtl8192_stop_beacon(struct net_device
*dev
)
1297 //rtl8192_beacon_disable(dev);
1300 static void rtl8192_config_rate(struct net_device
* dev
, u16
* rate_config
)
1302 struct r8192_priv
*priv
= ieee80211_priv(dev
);
1303 struct ieee80211_network
*net
;
1304 u8 i
=0, basic_rate
= 0;
1305 net
= & priv
->ieee80211
->current_network
;
1307 for (i
=0; i
<net
->rates_len
; i
++)
1309 basic_rate
= net
->rates
[i
]&0x7f;
1312 case MGN_1M
: *rate_config
|= RRSR_1M
; break;
1313 case MGN_2M
: *rate_config
|= RRSR_2M
; break;
1314 case MGN_5_5M
: *rate_config
|= RRSR_5_5M
; break;
1315 case MGN_11M
: *rate_config
|= RRSR_11M
; break;
1316 case MGN_6M
: *rate_config
|= RRSR_6M
; break;
1317 case MGN_9M
: *rate_config
|= RRSR_9M
; break;
1318 case MGN_12M
: *rate_config
|= RRSR_12M
; break;
1319 case MGN_18M
: *rate_config
|= RRSR_18M
; break;
1320 case MGN_24M
: *rate_config
|= RRSR_24M
; break;
1321 case MGN_36M
: *rate_config
|= RRSR_36M
; break;
1322 case MGN_48M
: *rate_config
|= RRSR_48M
; break;
1323 case MGN_54M
: *rate_config
|= RRSR_54M
; break;
1326 for (i
=0; i
<net
->rates_ex_len
; i
++)
1328 basic_rate
= net
->rates_ex
[i
]&0x7f;
1331 case MGN_1M
: *rate_config
|= RRSR_1M
; break;
1332 case MGN_2M
: *rate_config
|= RRSR_2M
; break;
1333 case MGN_5_5M
: *rate_config
|= RRSR_5_5M
; break;
1334 case MGN_11M
: *rate_config
|= RRSR_11M
; break;
1335 case MGN_6M
: *rate_config
|= RRSR_6M
; break;
1336 case MGN_9M
: *rate_config
|= RRSR_9M
; break;
1337 case MGN_12M
: *rate_config
|= RRSR_12M
; break;
1338 case MGN_18M
: *rate_config
|= RRSR_18M
; break;
1339 case MGN_24M
: *rate_config
|= RRSR_24M
; break;
1340 case MGN_36M
: *rate_config
|= RRSR_36M
; break;
1341 case MGN_48M
: *rate_config
|= RRSR_48M
; break;
1342 case MGN_54M
: *rate_config
|= RRSR_54M
; break;
1348 #define SHORT_SLOT_TIME 9
1349 #define NON_SHORT_SLOT_TIME 20
1351 static void rtl8192_update_cap(struct net_device
* dev
, u16 cap
)
1354 struct r8192_priv
*priv
= ieee80211_priv(dev
);
1355 struct ieee80211_network
*net
= &priv
->ieee80211
->current_network
;
1356 priv
->short_preamble
= cap
& WLAN_CAPABILITY_SHORT_PREAMBLE
;
1357 tmp
= priv
->basic_rate
;
1358 if (priv
->short_preamble
)
1359 tmp
|= BRSR_AckShortPmb
;
1360 write_nic_dword(dev
, RRSR
, tmp
);
1362 if (net
->mode
& (IEEE_G
|IEEE_N_24G
))
1365 if ((cap
& WLAN_CAPABILITY_SHORT_SLOT
)&&(!priv
->ieee80211
->pHTInfo
->bCurrentRT2RTLongSlotTime
))
1367 slot_time
= SHORT_SLOT_TIME
;
1369 else //long slot time
1370 slot_time
= NON_SHORT_SLOT_TIME
;
1371 priv
->slot_time
= slot_time
;
1372 write_nic_byte(dev
, SLOT_TIME
, slot_time
);
1377 static void rtl8192_net_update(struct net_device
*dev
)
1380 struct r8192_priv
*priv
= ieee80211_priv(dev
);
1381 struct ieee80211_network
*net
;
1382 u16 BcnTimeCfg
= 0, BcnCW
= 6, BcnIFS
= 0xf;
1383 u16 rate_config
= 0;
1384 net
= &priv
->ieee80211
->current_network
;
1385 //update Basic rate: RR, BRSR
1386 rtl8192_config_rate(dev
, &rate_config
);
1387 // 2007.01.16, by Emily
1388 // Select RRSR (in Legacy-OFDM and CCK)
1389 // For 8190, we select only 24M, 12M, 6M, 11M, 5.5M, 2M, and 1M from the Basic rate.
1390 // We do not use other rates.
1391 priv
->basic_rate
= rate_config
&= 0x15f;
1393 write_nic_dword(dev
,BSSIDR
,((u32
*)net
->bssid
)[0]);
1394 write_nic_word(dev
,BSSIDR
+4,((u16
*)net
->bssid
)[2]);
1397 rtl8192_update_msr(dev
);
1401 // rtl8192_update_cap(dev, net->capability);
1402 if (priv
->ieee80211
->iw_mode
== IW_MODE_ADHOC
)
1404 write_nic_word(dev
, ATIMWND
, 2);
1405 write_nic_word(dev
, BCN_DMATIME
, 256);
1406 write_nic_word(dev
, BCN_INTERVAL
, net
->beacon_interval
);
1407 // write_nic_word(dev, BcnIntTime, 100);
1408 //BIT15 of BCN_DRV_EARLY_INT will indicate whether software beacon or hw beacon is applied.
1409 write_nic_word(dev
, BCN_DRV_EARLY_INT
, 10);
1410 write_nic_byte(dev
, BCN_ERR_THRESH
, 100);
1412 BcnTimeCfg
|= (BcnCW
<<BCN_TCFG_CW_SHIFT
);
1413 // TODO: BcnIFS may required to be changed on ASIC
1414 BcnTimeCfg
|= BcnIFS
<<BCN_TCFG_IFS
;
1416 write_nic_word(dev
, BCN_TCFG
, BcnTimeCfg
);
1422 void rtl819xE_tx_cmd(struct net_device
*dev
, struct sk_buff
*skb
)
1424 struct r8192_priv
*priv
= ieee80211_priv(dev
);
1425 struct rtl8192_tx_ring
*ring
;
1426 tx_desc_819x_pci
*entry
;
1430 unsigned long flags
;
1432 ring
= &priv
->tx_ring
[TXCMD_QUEUE
];
1433 mapping
= pci_map_single(priv
->pdev
, skb
->data
, skb
->len
, PCI_DMA_TODEVICE
);
1435 spin_lock_irqsave(&priv
->irq_th_lock
,flags
);
1436 idx
= (ring
->idx
+ skb_queue_len(&ring
->queue
)) % ring
->entries
;
1437 entry
= &ring
->desc
[idx
];
1439 tcb_desc
= (cb_desc
*)(skb
->cb
+ MAX_DEV_ADDR_SIZE
);
1441 entry
->LINIP
= tcb_desc
->bLastIniPkt
;
1442 entry
->FirstSeg
= 1;//first segment
1443 entry
->LastSeg
= 1; //last segment
1444 if(tcb_desc
->bCmdOrInit
== DESC_PACKET_TYPE_INIT
) {
1445 entry
->CmdInit
= DESC_PACKET_TYPE_INIT
;
1447 entry
->CmdInit
= DESC_PACKET_TYPE_NORMAL
;
1448 entry
->Offset
= sizeof(TX_FWINFO_8190PCI
) + 8;
1449 entry
->PktSize
= (u16
)(tcb_desc
->pkt_size
+ entry
->Offset
);
1450 entry
->QueueSelect
= QSLT_CMD
;
1451 entry
->TxFWInfoSize
= 0x08;
1452 entry
->RATid
= (u8
)DESC_PACKET_TYPE_INIT
;
1454 entry
->TxBufferSize
= skb
->len
;
1455 entry
->TxBuffAddr
= cpu_to_le32(mapping
);
1458 #ifdef JOHN_DUMP_TXDESC
1460 tx_desc_819x_pci
*entry1
= &ring
->desc
[0];
1461 unsigned int *ptr
= (unsigned int *)entry1
;
1462 printk("<Tx descriptor>:\n");
1463 for (i
= 0; i
< 8; i
++)
1464 printk("%8x ", ptr
[i
]);
1468 __skb_queue_tail(&ring
->queue
, skb
);
1469 spin_unlock_irqrestore(&priv
->irq_th_lock
,flags
);
1471 write_nic_byte(dev
, TPPoll
, TPPoll_CQ
);
1477 * Mapping Software/Hardware descriptor queue id to "Queue Select Field"
1478 * in TxFwInfo data structure
1479 * 2006.10.30 by Emily
1481 * \param QUEUEID Software Queue
1483 static u8
MapHwQueueToFirmwareQueue(u8 QueueID
)
1485 u8 QueueSelect
= 0x0; //defualt set to
1489 QueueSelect
= QSLT_BE
; //or QSelect = pTcb->priority;
1493 QueueSelect
= QSLT_BK
; //or QSelect = pTcb->priority;
1497 QueueSelect
= QSLT_VO
; //or QSelect = pTcb->priority;
1501 QueueSelect
= QSLT_VI
; //or QSelect = pTcb->priority;
1504 QueueSelect
= QSLT_MGNT
;
1508 QueueSelect
= QSLT_BEACON
;
1511 // TODO: 2006.10.30 mark other queue selection until we verify it is OK
1512 // TODO: Remove Assertions
1513 //#if (RTL819X_FPGA_VER & RTL819X_FPGA_GUANGAN_070502)
1515 QueueSelect
= QSLT_CMD
;
1519 //QueueSelect = QSLT_HIGH;
1523 RT_TRACE(COMP_ERR
, "TransmitTCB(): Impossible Queue Selection: %d \n", QueueID
);
1529 static u8
MRateToHwRate8190Pci(u8 rate
)
1531 u8 ret
= DESC90_RATE1M
;
1534 case MGN_1M
: ret
= DESC90_RATE1M
; break;
1535 case MGN_2M
: ret
= DESC90_RATE2M
; break;
1536 case MGN_5_5M
: ret
= DESC90_RATE5_5M
; break;
1537 case MGN_11M
: ret
= DESC90_RATE11M
; break;
1538 case MGN_6M
: ret
= DESC90_RATE6M
; break;
1539 case MGN_9M
: ret
= DESC90_RATE9M
; break;
1540 case MGN_12M
: ret
= DESC90_RATE12M
; break;
1541 case MGN_18M
: ret
= DESC90_RATE18M
; break;
1542 case MGN_24M
: ret
= DESC90_RATE24M
; break;
1543 case MGN_36M
: ret
= DESC90_RATE36M
; break;
1544 case MGN_48M
: ret
= DESC90_RATE48M
; break;
1545 case MGN_54M
: ret
= DESC90_RATE54M
; break;
1547 // HT rate since here
1548 case MGN_MCS0
: ret
= DESC90_RATEMCS0
; break;
1549 case MGN_MCS1
: ret
= DESC90_RATEMCS1
; break;
1550 case MGN_MCS2
: ret
= DESC90_RATEMCS2
; break;
1551 case MGN_MCS3
: ret
= DESC90_RATEMCS3
; break;
1552 case MGN_MCS4
: ret
= DESC90_RATEMCS4
; break;
1553 case MGN_MCS5
: ret
= DESC90_RATEMCS5
; break;
1554 case MGN_MCS6
: ret
= DESC90_RATEMCS6
; break;
1555 case MGN_MCS7
: ret
= DESC90_RATEMCS7
; break;
1556 case MGN_MCS8
: ret
= DESC90_RATEMCS8
; break;
1557 case MGN_MCS9
: ret
= DESC90_RATEMCS9
; break;
1558 case MGN_MCS10
: ret
= DESC90_RATEMCS10
; break;
1559 case MGN_MCS11
: ret
= DESC90_RATEMCS11
; break;
1560 case MGN_MCS12
: ret
= DESC90_RATEMCS12
; break;
1561 case MGN_MCS13
: ret
= DESC90_RATEMCS13
; break;
1562 case MGN_MCS14
: ret
= DESC90_RATEMCS14
; break;
1563 case MGN_MCS15
: ret
= DESC90_RATEMCS15
; break;
1564 case (0x80|0x20): ret
= DESC90_RATEMCS32
; break;
1572 static u8
QueryIsShort(u8 TxHT
, u8 TxRate
, cb_desc
*tcb_desc
)
1576 tmp_Short
= (TxHT
==1)?((tcb_desc
->bUseShortGI
)?1:0):((tcb_desc
->bUseShortPreamble
)?1:0);
1578 if(TxHT
==1 && TxRate
!= DESC90_RATEMCS15
)
1585 * The tx procedure is just as following,
1586 * skb->cb will contain all the following information,
1587 * priority, morefrag, rate, &dev.
1589 short rtl8192_tx(struct net_device
*dev
, struct sk_buff
* skb
)
1591 struct r8192_priv
*priv
= ieee80211_priv(dev
);
1592 struct rtl8192_tx_ring
*ring
;
1593 unsigned long flags
;
1594 cb_desc
*tcb_desc
= (cb_desc
*)(skb
->cb
+ MAX_DEV_ADDR_SIZE
);
1595 tx_desc_819x_pci
*pdesc
= NULL
;
1596 TX_FWINFO_8190PCI
*pTxFwInfo
= NULL
;
1598 bool multi_addr
=false,broad_addr
=false,uni_addr
=false;
1599 u8
* pda_addr
= NULL
;
1602 if(priv
->bdisable_nic
){
1603 RT_TRACE(COMP_ERR
,"%s: ERR!! Nic is disabled! Can't tx packet len=%d qidx=%d!!!\n", __FUNCTION__
, skb
->len
, tcb_desc
->queue_index
);
1608 priv
->ieee80211
->bAwakePktSent
= true;
1611 mapping
= pci_map_single(priv
->pdev
, skb
->data
, skb
->len
, PCI_DMA_TODEVICE
);
1612 /* collect the tx packets statitcs */
1613 pda_addr
= ((u8
*)skb
->data
) + sizeof(TX_FWINFO_8190PCI
);
1614 if(is_multicast_ether_addr(pda_addr
))
1616 else if(is_broadcast_ether_addr(pda_addr
))
1622 priv
->stats
.txbytesunicast
+= (u8
)(skb
->len
) - sizeof(TX_FWINFO_8190PCI
);
1624 priv
->stats
.txbytesmulticast
+=(u8
)(skb
->len
) - sizeof(TX_FWINFO_8190PCI
);
1626 priv
->stats
.txbytesbroadcast
+= (u8
)(skb
->len
) - sizeof(TX_FWINFO_8190PCI
);
1628 /* fill tx firmware */
1629 pTxFwInfo
= (PTX_FWINFO_8190PCI
)skb
->data
;
1630 memset(pTxFwInfo
,0,sizeof(TX_FWINFO_8190PCI
));
1631 pTxFwInfo
->TxHT
= (tcb_desc
->data_rate
&0x80)?1:0;
1632 pTxFwInfo
->TxRate
= MRateToHwRate8190Pci((u8
)tcb_desc
->data_rate
);
1633 pTxFwInfo
->EnableCPUDur
= tcb_desc
->bTxEnableFwCalcDur
;
1634 pTxFwInfo
->Short
= QueryIsShort(pTxFwInfo
->TxHT
, pTxFwInfo
->TxRate
, tcb_desc
);
1636 /* Aggregation related */
1637 if(tcb_desc
->bAMPDUEnable
) {
1638 pTxFwInfo
->AllowAggregation
= 1;
1639 pTxFwInfo
->RxMF
= tcb_desc
->ampdu_factor
;
1640 pTxFwInfo
->RxAMD
= tcb_desc
->ampdu_density
;
1642 pTxFwInfo
->AllowAggregation
= 0;
1643 pTxFwInfo
->RxMF
= 0;
1644 pTxFwInfo
->RxAMD
= 0;
1648 // Protection mode related
1650 pTxFwInfo
->RtsEnable
= (tcb_desc
->bRTSEnable
)?1:0;
1651 pTxFwInfo
->CtsEnable
= (tcb_desc
->bCTSEnable
)?1:0;
1652 pTxFwInfo
->RtsSTBC
= (tcb_desc
->bRTSSTBC
)?1:0;
1653 pTxFwInfo
->RtsHT
= (tcb_desc
->rts_rate
&0x80)?1:0;
1654 pTxFwInfo
->RtsRate
= MRateToHwRate8190Pci((u8
)tcb_desc
->rts_rate
);
1655 pTxFwInfo
->RtsBandwidth
= 0;
1656 pTxFwInfo
->RtsSubcarrier
= tcb_desc
->RTSSC
;
1657 pTxFwInfo
->RtsShort
= (pTxFwInfo
->RtsHT
==0)?(tcb_desc
->bRTSUseShortPreamble
?1:0):(tcb_desc
->bRTSUseShortGI
?1:0);
1659 // Set Bandwidth and sub-channel settings.
1661 if(priv
->CurrentChannelBW
== HT_CHANNEL_WIDTH_20_40
)
1663 if(tcb_desc
->bPacketBW
)
1665 pTxFwInfo
->TxBandwidth
= 1;
1667 pTxFwInfo
->TxSubCarrier
= 3;
1669 pTxFwInfo
->TxSubCarrier
= 0; //By SD3's Jerry suggestion, use duplicated mode, cosa 04012008
1674 pTxFwInfo
->TxBandwidth
= 0;
1675 pTxFwInfo
->TxSubCarrier
= priv
->nCur40MhzPrimeSC
;
1678 pTxFwInfo
->TxBandwidth
= 0;
1679 pTxFwInfo
->TxSubCarrier
= 0;
1684 /* 2007/07/25 MH Copy current TX FW info.*/
1685 memcpy((void*)(&Tmp_TxFwInfo
), (void*)(pTxFwInfo
), sizeof(TX_FWINFO_8190PCI
));
1686 printk("&&&&&&&&&&&&&&&&&&&&&&====>print out fwinf\n");
1687 printk("===>enable fwcacl:%d\n", Tmp_TxFwInfo
.EnableCPUDur
);
1688 printk("===>RTS STBC:%d\n", Tmp_TxFwInfo
.RtsSTBC
);
1689 printk("===>RTS Subcarrier:%d\n", Tmp_TxFwInfo
.RtsSubcarrier
);
1690 printk("===>Allow Aggregation:%d\n", Tmp_TxFwInfo
.AllowAggregation
);
1691 printk("===>TX HT bit:%d\n", Tmp_TxFwInfo
.TxHT
);
1692 printk("===>Tx rate:%d\n", Tmp_TxFwInfo
.TxRate
);
1693 printk("===>Received AMPDU Density:%d\n", Tmp_TxFwInfo
.RxAMD
);
1694 printk("===>Received MPDU Factor:%d\n", Tmp_TxFwInfo
.RxMF
);
1695 printk("===>TxBandwidth:%d\n", Tmp_TxFwInfo
.TxBandwidth
);
1696 printk("===>TxSubCarrier:%d\n", Tmp_TxFwInfo
.TxSubCarrier
);
1698 printk("<=====**********************out of print\n");
1701 spin_lock_irqsave(&priv
->irq_th_lock
,flags
);
1702 ring
= &priv
->tx_ring
[tcb_desc
->queue_index
];
1703 if (tcb_desc
->queue_index
!= BEACON_QUEUE
) {
1704 idx
= (ring
->idx
+ skb_queue_len(&ring
->queue
)) % ring
->entries
;
1709 pdesc
= &ring
->desc
[idx
];
1710 if((pdesc
->OWN
== 1) && (tcb_desc
->queue_index
!= BEACON_QUEUE
)) {
1711 RT_TRACE(COMP_ERR
,"No more TX desc@%d, ring->idx = %d,idx = %d,%x",
1712 tcb_desc
->queue_index
,ring
->idx
, idx
,skb
->len
);
1713 spin_unlock_irqrestore(&priv
->irq_th_lock
,flags
);
1717 /* fill tx descriptor */
1718 memset((u8
*)pdesc
,0,12);
1722 pdesc
->Offset
= sizeof(TX_FWINFO_8190PCI
) + 8; //We must add 8!! Emily
1723 pdesc
->PktSize
= (u16
)skb
->len
-sizeof(TX_FWINFO_8190PCI
);
1727 pdesc
->RATid
= tcb_desc
->RATRIndex
;
1731 pdesc
->SecType
= 0x0;
1732 if (tcb_desc
->bHwSec
) {
1733 switch (priv
->ieee80211
->pairwise_key_type
) {
1734 case KEY_TYPE_WEP40
:
1735 case KEY_TYPE_WEP104
:
1736 pdesc
->SecType
= 0x1;
1740 pdesc
->SecType
= 0x2;
1744 pdesc
->SecType
= 0x3;
1748 pdesc
->SecType
= 0x0;
1759 pdesc
->QueueSelect
= MapHwQueueToFirmwareQueue(tcb_desc
->queue_index
);
1760 pdesc
->TxFWInfoSize
= sizeof(TX_FWINFO_8190PCI
);
1762 pdesc
->DISFB
= tcb_desc
->bTxDisableRateFallBack
;
1763 pdesc
->USERATE
= tcb_desc
->bTxUseDriverAssingedRate
;
1767 pdesc
->TxBufferSize
= skb
->len
;
1769 pdesc
->TxBuffAddr
= cpu_to_le32(mapping
);
1770 __skb_queue_tail(&ring
->queue
, skb
);
1772 spin_unlock_irqrestore(&priv
->irq_th_lock
,flags
);
1773 dev
->trans_start
= jiffies
;
1774 write_nic_word(dev
,TPPoll
,0x01<<tcb_desc
->queue_index
);
1778 static short rtl8192_alloc_rx_desc_ring(struct net_device
*dev
)
1780 struct r8192_priv
*priv
= ieee80211_priv(dev
);
1781 rx_desc_819x_pci
*entry
= NULL
;
1784 priv
->rx_ring
= pci_alloc_consistent(priv
->pdev
,
1785 sizeof(*priv
->rx_ring
) * priv
->rxringcount
, &priv
->rx_ring_dma
);
1787 if (!priv
->rx_ring
|| (unsigned long)priv
->rx_ring
& 0xFF) {
1788 RT_TRACE(COMP_ERR
,"Cannot allocate RX ring\n");
1792 memset(priv
->rx_ring
, 0, sizeof(*priv
->rx_ring
) * priv
->rxringcount
);
1795 for (i
= 0; i
< priv
->rxringcount
; i
++) {
1796 struct sk_buff
*skb
= dev_alloc_skb(priv
->rxbuffersize
);
1797 dma_addr_t
*mapping
;
1798 entry
= &priv
->rx_ring
[i
];
1801 priv
->rx_buf
[i
] = skb
;
1802 mapping
= (dma_addr_t
*)skb
->cb
;
1803 *mapping
= pci_map_single(priv
->pdev
, skb_tail_pointer(skb
),
1804 priv
->rxbuffersize
, PCI_DMA_FROMDEVICE
);
1806 entry
->BufferAddress
= cpu_to_le32(*mapping
);
1808 entry
->Length
= priv
->rxbuffersize
;
1816 static int rtl8192_alloc_tx_desc_ring(struct net_device
*dev
,
1817 unsigned int prio
, unsigned int entries
)
1819 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
1820 tx_desc_819x_pci
*ring
;
1824 ring
= pci_alloc_consistent(priv
->pdev
, sizeof(*ring
) * entries
, &dma
);
1825 if (!ring
|| (unsigned long)ring
& 0xFF) {
1826 RT_TRACE(COMP_ERR
, "Cannot allocate TX ring (prio = %d)\n", prio
);
1830 memset(ring
, 0, sizeof(*ring
)*entries
);
1831 priv
->tx_ring
[prio
].desc
= ring
;
1832 priv
->tx_ring
[prio
].dma
= dma
;
1833 priv
->tx_ring
[prio
].idx
= 0;
1834 priv
->tx_ring
[prio
].entries
= entries
;
1835 skb_queue_head_init(&priv
->tx_ring
[prio
].queue
);
1837 for (i
= 0; i
< entries
; i
++)
1838 ring
[i
].NextDescAddress
=
1839 cpu_to_le32((u32
)dma
+ ((i
+ 1) % entries
) * sizeof(*ring
));
1845 static short rtl8192_pci_initdescring(struct net_device
*dev
)
1849 struct r8192_priv
*priv
= ieee80211_priv(dev
);
1851 ret
= rtl8192_alloc_rx_desc_ring(dev
);
1857 /* general process for other queue */
1858 for (i
= 0; i
< MAX_TX_QUEUE_COUNT
; i
++) {
1859 ret
= rtl8192_alloc_tx_desc_ring(dev
, i
, priv
->txringcount
);
1861 goto err_free_rings
;
1865 /* specific process for hardware beacon process */
1866 ret
= rtl8192_alloc_tx_desc_ring(dev
, MAX_TX_QUEUE_COUNT
- 1, 2);
1868 goto err_free_rings
;
1874 rtl8192_free_rx_ring(dev
);
1875 for (i
= 0; i
< MAX_TX_QUEUE_COUNT
; i
++)
1876 if (priv
->tx_ring
[i
].desc
)
1877 rtl8192_free_tx_ring(dev
, i
);
1881 static void rtl8192_pci_resetdescring(struct net_device
*dev
)
1883 struct r8192_priv
*priv
= ieee80211_priv(dev
);
1886 /* force the rx_idx to the first one */
1888 rx_desc_819x_pci
*entry
= NULL
;
1889 for (i
= 0; i
< priv
->rxringcount
; i
++) {
1890 entry
= &priv
->rx_ring
[i
];
1896 /* after reset, release previous pending packet, and force the
1897 * tx idx to the first one */
1898 for (i
= 0; i
< MAX_TX_QUEUE_COUNT
; i
++) {
1899 if (priv
->tx_ring
[i
].desc
) {
1900 struct rtl8192_tx_ring
*ring
= &priv
->tx_ring
[i
];
1902 while (skb_queue_len(&ring
->queue
)) {
1903 tx_desc_819x_pci
*entry
= &ring
->desc
[ring
->idx
];
1904 struct sk_buff
*skb
= __skb_dequeue(&ring
->queue
);
1906 pci_unmap_single(priv
->pdev
, le32_to_cpu(entry
->TxBuffAddr
),
1907 skb
->len
, PCI_DMA_TODEVICE
);
1909 ring
->idx
= (ring
->idx
+ 1) % ring
->entries
;
1917 extern void rtl8192_update_ratr_table(struct net_device
* dev
);
1918 static void rtl8192_link_change(struct net_device
*dev
)
1922 struct r8192_priv
*priv
= ieee80211_priv(dev
);
1923 struct ieee80211_device
* ieee
= priv
->ieee80211
;
1924 //write_nic_word(dev, BCN_INTR_ITV, net->beacon_interval);
1925 if (ieee
->state
== IEEE80211_LINKED
)
1927 rtl8192_net_update(dev
);
1928 rtl8192_update_ratr_table(dev
);
1930 //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
1931 if ((KEY_TYPE_WEP40
== ieee
->pairwise_key_type
) || (KEY_TYPE_WEP104
== ieee
->pairwise_key_type
))
1932 EnableHWSecurityConfig8192(dev
);
1937 write_nic_byte(dev
, 0x173, 0);
1939 /*update timing params*/
1940 //rtl8192_set_chan(dev, priv->chan);
1942 rtl8192_update_msr(dev
);
1944 // 2007/10/16 MH MAC Will update TSF according to all received beacon, so we have
1945 // // To set CBSSID bit when link with any AP or STA.
1946 if (ieee
->iw_mode
== IW_MODE_INFRA
|| ieee
->iw_mode
== IW_MODE_ADHOC
)
1949 reg
= read_nic_dword(dev
, RCR
);
1950 if (priv
->ieee80211
->state
== IEEE80211_LINKED
)
1951 priv
->ReceiveConfig
= reg
|= RCR_CBSSID
;
1953 priv
->ReceiveConfig
= reg
&= ~RCR_CBSSID
;
1954 write_nic_dword(dev
, RCR
, reg
);
1960 static struct ieee80211_qos_parameters def_qos_parameters
= {
1961 {3,3,3,3},/* cw_min */
1962 {7,7,7,7},/* cw_max */
1963 {2,2,2,2},/* aifs */
1964 {0,0,0,0},/* flags */
1965 {0,0,0,0} /* tx_op_limit */
1968 static void rtl8192_update_beacon(struct work_struct
* work
)
1970 struct r8192_priv
*priv
= container_of(work
, struct r8192_priv
, update_beacon_wq
.work
);
1971 struct net_device
*dev
= priv
->ieee80211
->dev
;
1972 struct ieee80211_device
* ieee
= priv
->ieee80211
;
1973 struct ieee80211_network
* net
= &ieee
->current_network
;
1975 if (ieee
->pHTInfo
->bCurrentHTSupport
)
1976 HTUpdateSelfAndPeerSetting(ieee
, net
);
1977 ieee
->pHTInfo
->bCurrentRT2RTLongSlotTime
= net
->bssht
.bdRT2RTLongSlotTime
;
1978 rtl8192_update_cap(dev
, net
->capability
);
1981 * background support to run QoS activate functionality
1983 static const int WDCAPARA_ADD
[] = {EDCAPARA_BE
,EDCAPARA_BK
,EDCAPARA_VI
,EDCAPARA_VO
};
1984 static void rtl8192_qos_activate(struct work_struct
* work
)
1986 struct r8192_priv
*priv
= container_of(work
, struct r8192_priv
, qos_activate
);
1987 struct net_device
*dev
= priv
->ieee80211
->dev
;
1988 struct ieee80211_qos_parameters
*qos_parameters
= &priv
->ieee80211
->current_network
.qos_data
.parameters
;
1989 u8 mode
= priv
->ieee80211
->current_network
.mode
;
1990 // u32 size = sizeof(struct ieee80211_qos_parameters);
1995 mutex_lock(&priv
->mutex
);
1996 if(priv
->ieee80211
->state
!= IEEE80211_LINKED
)
1998 RT_TRACE(COMP_QOS
,"qos active process with associate response received\n");
1999 /* It better set slot time at first */
2000 /* For we just support b/g mode at present, let the slot time at 9/20 selection */
2001 /* update the ac parameter to related registers */
2002 for(i
= 0; i
< QOS_QUEUE_NUM
; i
++) {
2003 //Mode G/A: slotTimeTimer = 9; Mode B: 20
2004 u1bAIFS
= qos_parameters
->aifs
[i
] * ((mode
&(IEEE_G
|IEEE_N_24G
)) ?9:20) + aSifsTime
;
2005 u4bAcParam
= ((((u32
)(qos_parameters
->tx_op_limit
[i
]))<< AC_PARAM_TXOP_LIMIT_OFFSET
)|
2006 (((u32
)(qos_parameters
->cw_max
[i
]))<< AC_PARAM_ECW_MAX_OFFSET
)|
2007 (((u32
)(qos_parameters
->cw_min
[i
]))<< AC_PARAM_ECW_MIN_OFFSET
)|
2008 ((u32
)u1bAIFS
<< AC_PARAM_AIFS_OFFSET
));
2009 //printk("===>u4bAcParam:%x, ", u4bAcParam);
2010 write_nic_dword(dev
, WDCAPARA_ADD
[i
], u4bAcParam
);
2011 //write_nic_dword(dev, WDCAPARA_ADD[i], 0x005e4332);
2015 mutex_unlock(&priv
->mutex
);
2018 static int rtl8192_qos_handle_probe_response(struct r8192_priv
*priv
,
2020 struct ieee80211_network
*network
)
2023 u32 size
= sizeof(struct ieee80211_qos_parameters
);
2025 if(priv
->ieee80211
->state
!=IEEE80211_LINKED
)
2028 if ((priv
->ieee80211
->iw_mode
!= IW_MODE_INFRA
))
2031 if (network
->flags
& NETWORK_HAS_QOS_MASK
) {
2032 if (active_network
&&
2033 (network
->flags
& NETWORK_HAS_QOS_PARAMETERS
))
2034 network
->qos_data
.active
= network
->qos_data
.supported
;
2036 if ((network
->qos_data
.active
== 1) && (active_network
== 1) &&
2037 (network
->flags
& NETWORK_HAS_QOS_PARAMETERS
) &&
2038 (network
->qos_data
.old_param_count
!=
2039 network
->qos_data
.param_count
)) {
2040 network
->qos_data
.old_param_count
=
2041 network
->qos_data
.param_count
;
2042 queue_work(priv
->priv_wq
, &priv
->qos_activate
);
2043 RT_TRACE (COMP_QOS
, "QoS parameters change call "
2047 memcpy(&priv
->ieee80211
->current_network
.qos_data
.parameters
,
2048 &def_qos_parameters
, size
);
2050 if ((network
->qos_data
.active
== 1) && (active_network
== 1)) {
2051 queue_work(priv
->priv_wq
, &priv
->qos_activate
);
2052 RT_TRACE(COMP_QOS
, "QoS was disabled call qos_activate \n");
2054 network
->qos_data
.active
= 0;
2055 network
->qos_data
.supported
= 0;
2061 /* handle manage frame frame beacon and probe response */
2062 static int rtl8192_handle_beacon(struct net_device
* dev
,
2063 struct ieee80211_beacon
* beacon
,
2064 struct ieee80211_network
* network
)
2066 struct r8192_priv
*priv
= ieee80211_priv(dev
);
2068 rtl8192_qos_handle_probe_response(priv
,1,network
);
2070 queue_delayed_work(priv
->priv_wq
, &priv
->update_beacon_wq
, 0);
2076 * handling the beaconing responses. if we get different QoS setting
2077 * off the network from the associated setting, adjust the QoS
2080 static int rtl8192_qos_association_resp(struct r8192_priv
*priv
,
2081 struct ieee80211_network
*network
)
2084 unsigned long flags
;
2085 u32 size
= sizeof(struct ieee80211_qos_parameters
);
2086 int set_qos_param
= 0;
2088 if ((priv
== NULL
) || (network
== NULL
))
2091 if(priv
->ieee80211
->state
!=IEEE80211_LINKED
)
2094 if ((priv
->ieee80211
->iw_mode
!= IW_MODE_INFRA
))
2097 spin_lock_irqsave(&priv
->ieee80211
->lock
, flags
);
2098 if(network
->flags
& NETWORK_HAS_QOS_PARAMETERS
) {
2099 memcpy(&priv
->ieee80211
->current_network
.qos_data
.parameters
,
2100 &network
->qos_data
.parameters
,
2101 sizeof(struct ieee80211_qos_parameters
));
2102 priv
->ieee80211
->current_network
.qos_data
.active
= 1;
2104 if((priv
->ieee80211
->current_network
.qos_data
.param_count
!=
2105 network
->qos_data
.param_count
))
2109 /* update qos parameter for current network */
2110 priv
->ieee80211
->current_network
.qos_data
.old_param_count
=
2111 priv
->ieee80211
->current_network
.qos_data
.param_count
;
2112 priv
->ieee80211
->current_network
.qos_data
.param_count
=
2113 network
->qos_data
.param_count
;
2116 memcpy(&priv
->ieee80211
->current_network
.qos_data
.parameters
,
2117 &def_qos_parameters
, size
);
2118 priv
->ieee80211
->current_network
.qos_data
.active
= 0;
2119 priv
->ieee80211
->current_network
.qos_data
.supported
= 0;
2123 spin_unlock_irqrestore(&priv
->ieee80211
->lock
, flags
);
2125 RT_TRACE(COMP_QOS
, "%s: network->flags = %d,%d\n",__FUNCTION__
,network
->flags
,priv
->ieee80211
->current_network
.qos_data
.active
);
2126 if (set_qos_param
== 1)
2127 queue_work(priv
->priv_wq
, &priv
->qos_activate
);
2133 static int rtl8192_handle_assoc_response(struct net_device
*dev
,
2134 struct ieee80211_assoc_response_frame
*resp
,
2135 struct ieee80211_network
*network
)
2137 struct r8192_priv
*priv
= ieee80211_priv(dev
);
2138 rtl8192_qos_association_resp(priv
, network
);
2143 //updateRATRTabel for MCS only. Basic rate is not implement.
2144 void rtl8192_update_ratr_table(struct net_device
* dev
)
2145 // POCTET_STRING posLegacyRate,
2147 // PRT_WLAN_STA pEntry)
2149 struct r8192_priv
* priv
= ieee80211_priv(dev
);
2150 struct ieee80211_device
* ieee
= priv
->ieee80211
;
2151 u8
* pMcsRate
= ieee
->dot11HTOperationalRateSet
;
2152 //struct ieee80211_network *net = &ieee->current_network;
2156 rtl8192_config_rate(dev
, (u16
*)(&ratr_value
));
2157 ratr_value
|= (*(u16
*)(pMcsRate
)) << 12;
2158 // switch (net->mode)
2162 ratr_value
&= 0x00000FF0;
2165 ratr_value
&= 0x0000000F;
2168 ratr_value
&= 0x00000FF7;
2172 if (ieee
->pHTInfo
->PeerMimoPs
== 0) //MIMO_PS_STATIC
2173 ratr_value
&= 0x0007F007;
2175 if (priv
->rf_type
== RF_1T2R
)
2176 ratr_value
&= 0x000FF007;
2178 ratr_value
&= 0x0F81F007;
2184 ratr_value
&= 0x0FFFFFFF;
2185 if(ieee
->pHTInfo
->bCurTxBW40MHz
&& ieee
->pHTInfo
->bCurShortGI40MHz
){
2186 ratr_value
|= 0x80000000;
2187 }else if(!ieee
->pHTInfo
->bCurTxBW40MHz
&& ieee
->pHTInfo
->bCurShortGI20MHz
){
2188 ratr_value
|= 0x80000000;
2190 write_nic_dword(dev
, RATR0
+rate_index
*4, ratr_value
);
2191 write_nic_byte(dev
, UFWP
, 1);
2195 static u8 ccmp_ie
[4] = {0x00,0x50,0xf2,0x04};
2196 static u8 ccmp_rsn_ie
[4] = {0x00, 0x0f, 0xac, 0x04};
2199 static bool GetNmodeSupportBySecCfg8190Pci(struct net_device
*dev
)
2203 struct r8192_priv
*priv
= ieee80211_priv(dev
);
2204 struct ieee80211_device
*ieee
= priv
->ieee80211
;
2205 return !(ieee
->rtllib_ap_sec_type
&&
2206 (ieee
->rtllib_ap_sec_type(ieee
)&(SEC_ALG_WEP
|SEC_ALG_TKIP
)));
2208 struct r8192_priv
* priv
= ieee80211_priv(dev
);
2209 struct ieee80211_device
* ieee
= priv
->ieee80211
;
2210 int wpa_ie_len
= ieee
->wpa_ie_len
;
2211 struct ieee80211_crypt_data
* crypt
;
2214 crypt
= ieee
->crypt
[ieee
->tx_keyidx
];
2215 encrypt
= (ieee
->current_network
.capability
& WLAN_CAPABILITY_PRIVACY
) || (ieee
->host_encrypt
&& crypt
&& crypt
->ops
&& (0 == strcmp(crypt
->ops
->name
,"WEP")));
2218 if(encrypt
&& (wpa_ie_len
== 0)) {
2219 /* wep encryption, no N mode setting */
2221 // } else if((wpa_ie_len != 0)&&(memcmp(&(ieee->wpa_ie[14]),ccmp_ie,4))) {
2222 } else if((wpa_ie_len
!= 0)) {
2223 /* parse pairwise key type */
2224 //if((pairwisekey = WEP40)||(pairwisekey = WEP104)||(pairwisekey = TKIP))
2225 if (((ieee
->wpa_ie
[0] == 0xdd) && (!memcmp(&(ieee
->wpa_ie
[14]),ccmp_ie
,4))) || ((ieee
->wpa_ie
[0] == 0x30) && (!memcmp(&ieee
->wpa_ie
[10],ccmp_rsn_ie
, 4))))
2230 //RT_TRACE(COMP_ERR,"In %s The GroupEncAlgorithm is [4]\n",__FUNCTION__ );
2238 static void rtl8192_refresh_supportrate(struct r8192_priv
* priv
)
2240 struct ieee80211_device
* ieee
= priv
->ieee80211
;
2241 //we donot consider set support rate for ABG mode, only HT MCS rate is set here.
2242 if (ieee
->mode
== WIRELESS_MODE_N_24G
|| ieee
->mode
== WIRELESS_MODE_N_5G
)
2244 memcpy(ieee
->Regdot11HTOperationalRateSet
, ieee
->RegHTSuppRateSet
, 16);
2245 //RT_DEBUG_DATA(COMP_INIT, ieee->RegHTSuppRateSet, 16);
2246 //RT_DEBUG_DATA(COMP_INIT, ieee->Regdot11HTOperationalRateSet, 16);
2249 memset(ieee
->Regdot11HTOperationalRateSet
, 0, 16);
2252 static u8
rtl8192_getSupportedWireleeMode(struct net_device
*dev
)
2254 struct r8192_priv
*priv
= ieee80211_priv(dev
);
2256 switch(priv
->rf_chip
)
2261 ret
= (WIRELESS_MODE_N_24G
|WIRELESS_MODE_G
|WIRELESS_MODE_B
);
2264 ret
= (WIRELESS_MODE_A
|WIRELESS_MODE_N_5G
);
2267 ret
= WIRELESS_MODE_B
;
2273 static void rtl8192_SetWirelessMode(struct net_device
* dev
, u8 wireless_mode
)
2275 struct r8192_priv
*priv
= ieee80211_priv(dev
);
2276 u8 bSupportMode
= rtl8192_getSupportedWireleeMode(dev
);
2279 if ((wireless_mode
== WIRELESS_MODE_AUTO
) || ((wireless_mode
&bSupportMode
)==0))
2281 if(bSupportMode
& WIRELESS_MODE_N_24G
)
2283 wireless_mode
= WIRELESS_MODE_N_24G
;
2285 else if(bSupportMode
& WIRELESS_MODE_N_5G
)
2287 wireless_mode
= WIRELESS_MODE_N_5G
;
2289 else if((bSupportMode
& WIRELESS_MODE_A
))
2291 wireless_mode
= WIRELESS_MODE_A
;
2293 else if((bSupportMode
& WIRELESS_MODE_G
))
2295 wireless_mode
= WIRELESS_MODE_G
;
2297 else if((bSupportMode
& WIRELESS_MODE_B
))
2299 wireless_mode
= WIRELESS_MODE_B
;
2302 RT_TRACE(COMP_ERR
, "%s(), No valid wireless mode supported, SupportedWirelessMode(%x)!!!\n", __FUNCTION__
,bSupportMode
);
2303 wireless_mode
= WIRELESS_MODE_B
;
2306 #ifdef TO_DO_LIST //// TODO: this function doesn't work well at this time, we should wait for FPGA
2307 ActUpdateChannelAccessSetting( pAdapter
, pHalData
->CurrentWirelessMode
, &pAdapter
->MgntInfo
.Info8185
.ChannelAccessSetting
);
2309 priv
->ieee80211
->mode
= wireless_mode
;
2311 if ((wireless_mode
== WIRELESS_MODE_N_24G
) || (wireless_mode
== WIRELESS_MODE_N_5G
))
2312 priv
->ieee80211
->pHTInfo
->bEnableHT
= 1;
2314 priv
->ieee80211
->pHTInfo
->bEnableHT
= 0;
2315 RT_TRACE(COMP_INIT
, "Current Wireless Mode is %x\n", wireless_mode
);
2316 rtl8192_refresh_supportrate(priv
);
2320 //init priv variables here
2322 static bool GetHalfNmodeSupportByAPs819xPci(struct net_device
* dev
)
2324 struct r8192_priv
* priv
= ieee80211_priv(dev
);
2325 struct ieee80211_device
* ieee
= priv
->ieee80211
;
2327 return ieee
->bHalfWirelessN24GMode
;
2330 short rtl8192_is_tx_queue_empty(struct net_device
*dev
)
2333 struct r8192_priv
*priv
= ieee80211_priv(dev
);
2334 for (i
=0; i
<=MGNT_QUEUE
; i
++)
2336 if ((i
== TXCMD_QUEUE
) || (i
== HCCA_QUEUE
) )
2338 if (skb_queue_len(&(&priv
->tx_ring
[i
])->queue
) > 0){
2339 printk("===>tx queue is not empty:%d, %d\n", i
, skb_queue_len(&(&priv
->tx_ring
[i
])->queue
));
2345 static void rtl8192_hw_sleep_down(struct net_device
*dev
)
2347 struct r8192_priv
*priv
= ieee80211_priv(dev
);
2348 unsigned long flags
= 0;
2350 spin_lock_irqsave(&priv
->rf_ps_lock
,flags
);
2351 if (priv
->RFChangeInProgress
) {
2352 spin_unlock_irqrestore(&priv
->rf_ps_lock
,flags
);
2353 RT_TRACE(COMP_RF
, "rtl8192_hw_sleep_down(): RF Change in progress! \n");
2354 printk("rtl8192_hw_sleep_down(): RF Change in progress!\n");
2357 spin_unlock_irqrestore(&priv
->rf_ps_lock
,flags
);
2358 //RT_TRACE(COMP_PS, "%s()============>come to sleep down\n", __FUNCTION__);
2360 MgntActSet_RF_State(dev
, eRfSleep
, RF_CHANGE_BY_PS
);
2362 static void rtl8192_hw_sleep_wq (struct work_struct
*work
)
2364 // struct r8180_priv *priv = container_of(work, struct r8180_priv, watch_dog_wq);
2365 // struct ieee80211_device * ieee = (struct ieee80211_device*)
2366 // container_of(work, struct ieee80211_device, watch_dog_wq);
2367 struct delayed_work
*dwork
= container_of(work
,struct delayed_work
,work
);
2368 struct ieee80211_device
*ieee
= container_of(dwork
,struct ieee80211_device
,hw_sleep_wq
);
2369 struct net_device
*dev
= ieee
->dev
;
2371 rtl8192_hw_sleep_down(dev
);
2374 static void rtl8192_hw_wakeup(struct net_device
* dev
)
2376 struct r8192_priv
*priv
= ieee80211_priv(dev
);
2377 unsigned long flags
= 0;
2379 spin_lock_irqsave(&priv
->rf_ps_lock
,flags
);
2380 if (priv
->RFChangeInProgress
) {
2381 spin_unlock_irqrestore(&priv
->rf_ps_lock
,flags
);
2382 RT_TRACE(COMP_RF
, "rtl8192_hw_wakeup(): RF Change in progress! \n");
2383 printk("rtl8192_hw_wakeup(): RF Change in progress! schedule wake up task again\n");
2384 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
2387 spin_unlock_irqrestore(&priv
->rf_ps_lock
,flags
);
2389 //RT_TRACE(COMP_PS, "%s()============>come to wake up\n", __FUNCTION__);
2390 MgntActSet_RF_State(dev
, eRfOn
, RF_CHANGE_BY_PS
);
2393 void rtl8192_hw_wakeup_wq (struct work_struct
*work
)
2395 // struct r8180_priv *priv = container_of(work, struct r8180_priv, watch_dog_wq);
2396 // struct ieee80211_device * ieee = (struct ieee80211_device*)
2397 // container_of(work, struct ieee80211_device, watch_dog_wq);
2398 struct delayed_work
*dwork
= container_of(work
,struct delayed_work
,work
);
2399 struct ieee80211_device
*ieee
= container_of(dwork
,struct ieee80211_device
,hw_wakeup_wq
);
2400 struct net_device
*dev
= ieee
->dev
;
2401 rtl8192_hw_wakeup(dev
);
2405 #define MIN_SLEEP_TIME 50
2406 #define MAX_SLEEP_TIME 10000
2407 static void rtl8192_hw_to_sleep(struct net_device
*dev
, u32 th
, u32 tl
)
2409 struct r8192_priv
*priv
= ieee80211_priv(dev
);
2412 unsigned long flags
;
2414 spin_lock_irqsave(&priv
->ps_lock
,flags
);
2416 // Writing HW register with 0 equals to disable
2417 // the timer, that is not really what we want
2419 tl
-= MSECS(8+16+7);
2421 // If the interval in witch we are requested to sleep is too
2422 // short then give up and remain awake
2423 // when we sleep after send null frame, the timer will be too short to sleep.
2425 if(((tl
>=rb
)&& (tl
-rb
) <= MSECS(MIN_SLEEP_TIME
))
2426 ||((rb
>tl
)&& (rb
-tl
) < MSECS(MIN_SLEEP_TIME
))) {
2427 spin_unlock_irqrestore(&priv
->ps_lock
,flags
);
2428 printk("too short to sleep::%x, %x, %lx\n",tl
, rb
, MSECS(MIN_SLEEP_TIME
));
2432 if(((tl
> rb
) && ((tl
-rb
) > MSECS(MAX_SLEEP_TIME
)))||
2433 ((tl
< rb
) && (tl
>MSECS(69)) && ((rb
-tl
) > MSECS(MAX_SLEEP_TIME
)))||
2434 ((tl
<rb
)&&(tl
<MSECS(69))&&((tl
+0xffffffff-rb
)>MSECS(MAX_SLEEP_TIME
)))) {
2435 printk("========>too long to sleep:%x, %x, %lx\n", tl
, rb
, MSECS(MAX_SLEEP_TIME
));
2436 spin_unlock_irqrestore(&priv
->ps_lock
,flags
);
2440 u32 tmp
= (tl
>rb
)?(tl
-rb
):(rb
-tl
);
2441 queue_delayed_work(priv
->ieee80211
->wq
,
2442 &priv
->ieee80211
->hw_wakeup_wq
,tmp
);
2443 //PowerSave not supported when kernel version less 2.6.20
2445 queue_delayed_work(priv
->ieee80211
->wq
,
2446 (void *)&priv
->ieee80211
->hw_sleep_wq
,0);
2447 spin_unlock_irqrestore(&priv
->ps_lock
,flags
);
2450 static void rtl8192_init_priv_variable(struct net_device
* dev
)
2452 struct r8192_priv
*priv
= ieee80211_priv(dev
);
2454 PRT_POWER_SAVE_CONTROL pPSC
= (PRT_POWER_SAVE_CONTROL
)(&(priv
->ieee80211
->PowerSaveControl
));
2456 // Default Halt the NIC if RF is OFF.
2457 pPSC
->RegRfPsLevel
|= RT_RF_OFF_LEVL_HALT_NIC
;
2458 pPSC
->RegRfPsLevel
|= RT_RF_OFF_LEVL_CLK_REQ
;
2459 pPSC
->RegRfPsLevel
|= RT_RF_OFF_LEVL_ASPM
;
2460 pPSC
->RegRfPsLevel
|= RT_RF_LPS_LEVEL_ASPM
;
2461 pPSC
->bLeisurePs
= true;
2462 pPSC
->RegMaxLPSAwakeIntvl
= 5;
2463 priv
->bHwRadioOff
= false;
2465 priv
->being_init_adapter
= false;
2466 priv
->txbuffsize
= 1600;//1024;
2467 priv
->txfwbuffersize
= 4096;
2468 priv
->txringcount
= 64;//32;
2469 //priv->txbeaconcount = priv->txringcount;
2470 priv
->txbeaconcount
= 2;
2471 priv
->rxbuffersize
= 9100;//2048;//1024;
2472 priv
->rxringcount
= MAX_RX_COUNT
;//64;
2473 priv
->irq_enabled
=0;
2474 priv
->card_8192
= NIC_8192E
;
2475 priv
->rx_skb_complete
= 1;
2476 priv
->chan
= 1; //set to channel 1
2477 priv
->RegWirelessMode
= WIRELESS_MODE_AUTO
;
2478 priv
->RegChannelPlan
= 0xf;
2479 priv
->nrxAMPDU_size
= 0;
2480 priv
->nrxAMPDU_aggr_num
= 0;
2481 priv
->last_rxdesc_tsf_high
= 0;
2482 priv
->last_rxdesc_tsf_low
= 0;
2483 priv
->ieee80211
->mode
= WIRELESS_MODE_AUTO
; //SET AUTO
2484 priv
->ieee80211
->iw_mode
= IW_MODE_INFRA
;
2485 priv
->ieee80211
->ieee_up
=0;
2486 priv
->retry_rts
= DEFAULT_RETRY_RTS
;
2487 priv
->retry_data
= DEFAULT_RETRY_DATA
;
2488 priv
->ieee80211
->rts
= DEFAULT_RTS_THRESHOLD
;
2489 priv
->ieee80211
->rate
= 110; //11 mbps
2490 priv
->ieee80211
->short_slot
= 1;
2491 priv
->promisc
= (dev
->flags
& IFF_PROMISC
) ? 1:0;
2492 priv
->bcck_in_ch14
= false;
2493 priv
->bfsync_processing
= false;
2494 priv
->CCKPresentAttentuation
= 0;
2495 priv
->rfa_txpowertrackingindex
= 0;
2496 priv
->rfc_txpowertrackingindex
= 0;
2498 priv
->ScanDelay
= 50;//for Scan TODO
2499 //added by amy for silent reset
2500 priv
->ResetProgress
= RESET_TYPE_NORESET
;
2501 priv
->bForcedSilentReset
= 0;
2502 priv
->bDisableNormalResetCheck
= false;
2503 priv
->force_reset
= false;
2504 //added by amy for power save
2506 priv
->ieee80211
->RfOffReason
= 0;
2507 priv
->RFChangeInProgress
= false;
2508 priv
->bHwRfOffAction
= 0;
2509 priv
->SetRFPowerStateInProgress
= false;
2510 priv
->ieee80211
->PowerSaveControl
.bInactivePs
= true;
2511 priv
->ieee80211
->PowerSaveControl
.bIPSModeBackup
= false;
2513 priv
->txpower_checkcnt
= 0;
2514 priv
->thermal_readback_index
=0;
2515 priv
->txpower_tracking_callback_cnt
= 0;
2516 priv
->ccktxpower_adjustcnt_ch14
= 0;
2517 priv
->ccktxpower_adjustcnt_not_ch14
= 0;
2519 priv
->ieee80211
->current_network
.beacon_interval
= DEFAULT_BEACONINTERVAL
;
2520 priv
->ieee80211
->iw_mode
= IW_MODE_INFRA
;
2521 priv
->ieee80211
->softmac_features
= IEEE_SOFTMAC_SCAN
|
2522 IEEE_SOFTMAC_ASSOCIATE
| IEEE_SOFTMAC_PROBERQ
|
2523 IEEE_SOFTMAC_PROBERS
| IEEE_SOFTMAC_TX_QUEUE
;/* |
2524 IEEE_SOFTMAC_BEACONS;*///added by amy
080604 //| //IEEE_SOFTMAC_SINGLE_QUEUE;
2526 priv
->ieee80211
->active_scan
= 1;
2527 priv
->ieee80211
->modulation
= IEEE80211_CCK_MODULATION
| IEEE80211_OFDM_MODULATION
;
2528 priv
->ieee80211
->host_encrypt
= 1;
2529 priv
->ieee80211
->host_decrypt
= 1;
2530 //priv->ieee80211->start_send_beacons = NULL;//rtl819xusb_beacon_tx;//-by amy 080604
2531 //priv->ieee80211->stop_send_beacons = NULL;//rtl8192_beacon_stop;//-by amy 080604
2532 priv
->ieee80211
->start_send_beacons
= rtl8192_start_beacon
;//+by david 081107
2533 priv
->ieee80211
->stop_send_beacons
= rtl8192_stop_beacon
;//+by david 081107
2534 priv
->ieee80211
->softmac_hard_start_xmit
= rtl8192_hard_start_xmit
;
2535 priv
->ieee80211
->set_chan
= rtl8192_set_chan
;
2536 priv
->ieee80211
->link_change
= rtl8192_link_change
;
2537 priv
->ieee80211
->softmac_data_hard_start_xmit
= rtl8192_hard_data_xmit
;
2538 priv
->ieee80211
->data_hard_stop
= rtl8192_data_hard_stop
;
2539 priv
->ieee80211
->data_hard_resume
= rtl8192_data_hard_resume
;
2540 priv
->ieee80211
->init_wmmparam_flag
= 0;
2541 priv
->ieee80211
->fts
= DEFAULT_FRAG_THRESHOLD
;
2542 priv
->ieee80211
->check_nic_enough_desc
= check_nic_enough_desc
;
2543 priv
->ieee80211
->tx_headroom
= sizeof(TX_FWINFO_8190PCI
);
2544 priv
->ieee80211
->qos_support
= 1;
2545 priv
->ieee80211
->dot11PowerSaveMode
= 0;
2547 // priv->ieee80211->SwChnlByTimerHandler = rtl8192_phy_SwChnl;
2548 priv
->ieee80211
->SetBWModeHandler
= rtl8192_SetBWMode
;
2549 priv
->ieee80211
->handle_assoc_response
= rtl8192_handle_assoc_response
;
2550 priv
->ieee80211
->handle_beacon
= rtl8192_handle_beacon
;
2552 priv
->ieee80211
->sta_wake_up
= rtl8192_hw_wakeup
;
2553 // priv->ieee80211->ps_request_tx_ack = rtl8192_rq_tx_ack;
2554 priv
->ieee80211
->enter_sleep_state
= rtl8192_hw_to_sleep
;
2555 priv
->ieee80211
->ps_is_queue_empty
= rtl8192_is_tx_queue_empty
;
2557 priv
->ieee80211
->GetNmodeSupportBySecCfg
= GetNmodeSupportBySecCfg8190Pci
;
2558 priv
->ieee80211
->SetWirelessMode
= rtl8192_SetWirelessMode
;
2559 priv
->ieee80211
->GetHalfNmodeSupportByAPsHandler
= GetHalfNmodeSupportByAPs819xPci
;
2562 priv
->ieee80211
->InitialGainHandler
= InitialGain819xPci
;
2565 priv
->ieee80211
->ieee80211_ips_leave_wq
= ieee80211_ips_leave_wq
;
2566 priv
->ieee80211
->ieee80211_ips_leave
= ieee80211_ips_leave
;
2569 priv
->ieee80211
->LeisurePSLeave
= LeisurePSLeave
;
2572 priv
->ieee80211
->SetHwRegHandler
= rtl8192e_SetHwReg
;
2573 priv
->ieee80211
->rtllib_ap_sec_type
= rtl8192e_ap_sec_type
;
2575 priv
->card_type
= USB
;
2577 priv
->ShortRetryLimit
= 0x30;
2578 priv
->LongRetryLimit
= 0x30;
2580 priv
->EarlyRxThreshold
= 7;
2581 priv
->enable_gpio0
= 0;
2583 priv
->TransmitConfig
= 0;
2585 priv
->ReceiveConfig
= RCR_ADD3
|
2586 RCR_AMF
| RCR_ADF
| //accept management/data
2587 RCR_AICV
| //accept control frame for SW AP needs PS-poll, 2005.07.07, by rcnjko.
2588 RCR_AB
| RCR_AM
| RCR_APM
| //accept BC/MC/UC
2589 RCR_AAP
| ((u32
)7<<RCR_MXDMA_OFFSET
) |
2590 ((u32
)7 << RCR_FIFO_OFFSET
) | RCR_ONLYERLPKT
;
2592 priv
->irq_mask
= (u32
)(IMR_ROK
| IMR_VODOK
| IMR_VIDOK
| IMR_BEDOK
| IMR_BKDOK
|
2593 IMR_HCCADOK
| IMR_MGNTDOK
| IMR_COMDOK
| IMR_HIGHDOK
|
2594 IMR_BDOK
| IMR_RXCMDOK
| IMR_TIMEOUT0
| IMR_RDU
| IMR_RXFOVW
|
2595 IMR_TXFOVW
| IMR_BcnInt
| IMR_TBDOK
| IMR_TBDER
);
2597 priv
->AcmControl
= 0;
2598 priv
->pFirmware
= (rt_firmware
*)vmalloc(sizeof(rt_firmware
));
2599 if (priv
->pFirmware
)
2600 memset(priv
->pFirmware
, 0, sizeof(rt_firmware
));
2602 /* rx related queue */
2603 skb_queue_head_init(&priv
->rx_queue
);
2604 skb_queue_head_init(&priv
->skb_queue
);
2606 /* Tx related queue */
2607 for(i
= 0; i
< MAX_QUEUE_SIZE
; i
++) {
2608 skb_queue_head_init(&priv
->ieee80211
->skb_waitQ
[i
]);
2610 for(i
= 0; i
< MAX_QUEUE_SIZE
; i
++) {
2611 skb_queue_head_init(&priv
->ieee80211
->skb_aggQ
[i
]);
2613 priv
->rf_set_chan
= rtl8192_phy_SwChnl
;
2617 static void rtl8192_init_priv_lock(struct r8192_priv
* priv
)
2619 spin_lock_init(&priv
->tx_lock
);
2620 spin_lock_init(&priv
->irq_lock
);//added by thomas
2621 spin_lock_init(&priv
->irq_th_lock
);
2622 spin_lock_init(&priv
->rf_ps_lock
);
2623 spin_lock_init(&priv
->ps_lock
);
2624 //spin_lock_init(&priv->rf_lock);
2625 sema_init(&priv
->wx_sem
,1);
2626 sema_init(&priv
->rf_sem
,1);
2627 mutex_init(&priv
->mutex
);
2630 //init tasklet and wait_queue here. only 2.6 above kernel is considered
2631 #define DRV_NAME "wlan0"
2632 static void rtl8192_init_priv_task(struct net_device
* dev
)
2634 struct r8192_priv
*priv
= ieee80211_priv(dev
);
2636 #ifdef PF_SYNCTHREAD
2637 priv
->priv_wq
= create_workqueue(DRV_NAME
,0);
2639 priv
->priv_wq
= create_workqueue(DRV_NAME
);
2643 INIT_WORK(&priv
->ieee80211
->ips_leave_wq
, (void*)IPSLeave_wq
);
2646 // INIT_WORK(&priv->reset_wq, (void(*)(void*)) rtl8192_restart);
2647 INIT_WORK(&priv
->reset_wq
, rtl8192_restart
);
2648 // INIT_DELAYED_WORK(&priv->watch_dog_wq, hal_dm_watchdog);
2649 INIT_DELAYED_WORK(&priv
->watch_dog_wq
, rtl819x_watchdog_wqcallback
);
2650 INIT_DELAYED_WORK(&priv
->txpower_tracking_wq
, dm_txpower_trackingcallback
);
2651 INIT_DELAYED_WORK(&priv
->rfpath_check_wq
, dm_rf_pathcheck_workitemcallback
);
2652 INIT_DELAYED_WORK(&priv
->update_beacon_wq
, rtl8192_update_beacon
);
2653 //INIT_WORK(&priv->SwChnlWorkItem, rtl8192_SwChnl_WorkItem);
2654 //INIT_WORK(&priv->SetBWModeWorkItem, rtl8192_SetBWModeWorkItem);
2655 INIT_WORK(&priv
->qos_activate
, rtl8192_qos_activate
);
2656 INIT_DELAYED_WORK(&priv
->ieee80211
->hw_wakeup_wq
,(void*) rtl8192_hw_wakeup_wq
);
2657 INIT_DELAYED_WORK(&priv
->ieee80211
->hw_sleep_wq
,(void*) rtl8192_hw_sleep_wq
);
2659 tasklet_init(&priv
->irq_rx_tasklet
,
2660 (void(*)(unsigned long))rtl8192_irq_rx_tasklet
,
2661 (unsigned long)priv
);
2662 tasklet_init(&priv
->irq_tx_tasklet
,
2663 (void(*)(unsigned long))rtl8192_irq_tx_tasklet
,
2664 (unsigned long)priv
);
2665 tasklet_init(&priv
->irq_prepare_beacon_tasklet
,
2666 (void(*)(unsigned long))rtl8192_prepare_beacon
,
2667 (unsigned long)priv
);
2670 static void rtl8192_get_eeprom_size(struct net_device
* dev
)
2673 struct r8192_priv
*priv
= ieee80211_priv(dev
);
2674 RT_TRACE(COMP_INIT
, "===========>%s()\n", __FUNCTION__
);
2675 curCR
= read_nic_dword(dev
, EPROM_CMD
);
2676 RT_TRACE(COMP_INIT
, "read from Reg Cmd9346CR(%x):%x\n", EPROM_CMD
, curCR
);
2677 //whether need I consider BIT5?
2678 priv
->epromtype
= (curCR
& EPROM_CMD_9356SEL
) ? EPROM_93c56
: EPROM_93c46
;
2679 RT_TRACE(COMP_INIT
, "<===========%s(), epromtype:%d\n", __FUNCTION__
, priv
->epromtype
);
2682 //used to swap endian. as ntohl & htonl are not neccessary to swap endian, so use this instead.
2683 static inline u16
endian_swap(u16
* data
)
2686 *data
= (tmp
>> 8) | (tmp
<< 8);
2691 * Note: Adapter->EEPROMAddressSize should be set before this function call.
2692 * EEPROM address size can be got through GetEEPROMSize8185()
2694 static void rtl8192_read_eeprom_info(struct net_device
* dev
)
2696 struct r8192_priv
*priv
= ieee80211_priv(dev
);
2700 u8 ICVer8192
, ICVer8256
;
2702 u16 i
,usValue
, IC_Version
;
2705 u8 offset
;//, tmpAFR;
2706 u8 EepromTxPower
[100];
2708 u8 bMac_Tmp_Addr
[6] = {0x00, 0xe0, 0x4c, 0x00, 0x00, 0x01};
2709 RT_TRACE(COMP_INIT
, "====> rtl8192_read_eeprom_info\n");
2712 // TODO: I don't know if we need to apply EF function to EEPROM read function
2714 //2 Read EEPROM ID to make sure autoload is success
2715 EEPROMId
= eprom_read(dev
, 0);
2716 if( EEPROMId
!= RTL8190_EEPROM_ID
)
2718 RT_TRACE(COMP_ERR
, "EEPROM ID is invalid:%x, %x\n", EEPROMId
, RTL8190_EEPROM_ID
);
2719 priv
->AutoloadFailFlag
=true;
2723 priv
->AutoloadFailFlag
=false;
2727 // Assign Chip Version ID
2729 // Read IC Version && Channel Plan
2730 if(!priv
->AutoloadFailFlag
)
2733 priv
->eeprom_vid
= eprom_read(dev
, (EEPROM_VID
>> 1));
2734 priv
->eeprom_did
= eprom_read(dev
, (EEPROM_DID
>> 1));
2736 usValue
= eprom_read(dev
, (u16
)(EEPROM_Customer_ID
>>1)) >> 8 ;
2737 priv
->eeprom_CustomerID
= (u8
)( usValue
& 0xff);
2738 usValue
= eprom_read(dev
, (EEPROM_ICVersion_ChannelPlan
>>1));
2739 priv
->eeprom_ChannelPlan
= usValue
&0xff;
2740 IC_Version
= ((usValue
&0xff00)>>8);
2743 priv
->card_8192_version
= (VERSION_8190
)(IC_Version
);
2746 ICVer8192
= (IC_Version
&0xf); //bit0~3; 1:A cut, 2:B cut, 3:C cut...
2747 ICVer8256
= ((IC_Version
&0xf0)>>4);//bit4~6, bit7 reserved for other RF chip; 1:A cut, 2:B cut, 3:C cut...
2748 RT_TRACE(COMP_INIT
, "\nICVer8192 = 0x%x\n", ICVer8192
);
2749 RT_TRACE(COMP_INIT
, "\nICVer8256 = 0x%x\n", ICVer8256
);
2750 if(ICVer8192
== 0x2) //B-cut
2752 if(ICVer8256
== 0x5) //E-cut
2753 priv
->card_8192_version
= VERSION_8190_BE
;
2757 switch(priv
->card_8192_version
)
2759 case VERSION_8190_BD
:
2760 case VERSION_8190_BE
:
2763 priv
->card_8192_version
= VERSION_8190_BD
;
2766 RT_TRACE(COMP_INIT
, "\nIC Version = 0x%x\n", priv
->card_8192_version
);
2770 priv
->card_8192_version
= VERSION_8190_BD
;
2771 priv
->eeprom_vid
= 0;
2772 priv
->eeprom_did
= 0;
2773 priv
->eeprom_CustomerID
= 0;
2774 priv
->eeprom_ChannelPlan
= 0;
2775 RT_TRACE(COMP_INIT
, "\nIC Version = 0x%x\n", 0xff);
2778 RT_TRACE(COMP_INIT
, "EEPROM VID = 0x%4x\n", priv
->eeprom_vid
);
2779 RT_TRACE(COMP_INIT
, "EEPROM DID = 0x%4x\n", priv
->eeprom_did
);
2780 RT_TRACE(COMP_INIT
,"EEPROM Customer ID: 0x%2x\n", priv
->eeprom_CustomerID
);
2782 //2 Read Permanent MAC address
2783 if(!priv
->AutoloadFailFlag
)
2785 for(i
= 0; i
< 6; i
+= 2)
2787 usValue
= eprom_read(dev
, (u16
) ((EEPROM_NODE_ADDRESS_BYTE_0
+i
)>>1));
2788 *(u16
*)(&dev
->dev_addr
[i
]) = usValue
;
2791 // when auto load failed, the last address byte set to be a random one.
2792 // added by david woo.2007/11/7
2793 memcpy(dev
->dev_addr
, bMac_Tmp_Addr
, 6);
2796 RT_TRACE(COMP_INIT
, "Permanent Address = %pM\n", dev
->dev_addr
);
2798 //2 TX Power Check EEPROM Fail or not
2799 if(priv
->card_8192_version
> VERSION_8190_BD
) {
2800 priv
->bTXPowerDataReadFromEEPORM
= true;
2802 priv
->bTXPowerDataReadFromEEPORM
= false;
2805 // 2007/11/15 MH 8190PCI Default=2T4R, 8192PCIE default=1T2R
2806 priv
->rf_type
= RTL819X_DEFAULT_RF_TYPE
;
2808 if(priv
->card_8192_version
> VERSION_8190_BD
)
2810 // Read RF-indication and Tx Power gain index diff of legacy to HT OFDM rate.
2811 if(!priv
->AutoloadFailFlag
)
2813 tempval
= (eprom_read(dev
, (EEPROM_RFInd_PowerDiff
>>1))) & 0xff;
2814 priv
->EEPROMLegacyHTTxPowerDiff
= tempval
& 0xf; // bit[3:0]
2816 if (tempval
&0x80) //RF-indication, bit[7]
2817 priv
->rf_type
= RF_1T2R
;
2819 priv
->rf_type
= RF_2T4R
;
2823 priv
->EEPROMLegacyHTTxPowerDiff
= EEPROM_Default_LegacyHTTxPowerDiff
;
2825 RT_TRACE(COMP_INIT
, "EEPROMLegacyHTTxPowerDiff = %d\n",
2826 priv
->EEPROMLegacyHTTxPowerDiff
);
2828 // Read ThermalMeter from EEPROM
2829 if(!priv
->AutoloadFailFlag
)
2831 priv
->EEPROMThermalMeter
= (u8
)(((eprom_read(dev
, (EEPROM_ThermalMeter
>>1))) & 0xff00)>>8);
2835 priv
->EEPROMThermalMeter
= EEPROM_Default_ThermalMeter
;
2837 RT_TRACE(COMP_INIT
, "ThermalMeter = %d\n", priv
->EEPROMThermalMeter
);
2838 //vivi, for tx power track
2839 priv
->TSSI_13dBm
= priv
->EEPROMThermalMeter
*100;
2841 if(priv
->epromtype
== EPROM_93c46
)
2843 // Read antenna tx power offset of B/C/D to A and CrystalCap from EEPROM
2844 if(!priv
->AutoloadFailFlag
)
2846 usValue
= eprom_read(dev
, (EEPROM_TxPwDiff_CrystalCap
>>1));
2847 priv
->EEPROMAntPwDiff
= (usValue
&0x0fff);
2848 priv
->EEPROMCrystalCap
= (u8
)((usValue
&0xf000)>>12);
2852 priv
->EEPROMAntPwDiff
= EEPROM_Default_AntTxPowerDiff
;
2853 priv
->EEPROMCrystalCap
= EEPROM_Default_TxPwDiff_CrystalCap
;
2855 RT_TRACE(COMP_INIT
, "EEPROMAntPwDiff = %d\n", priv
->EEPROMAntPwDiff
);
2856 RT_TRACE(COMP_INIT
, "EEPROMCrystalCap = %d\n", priv
->EEPROMCrystalCap
);
2859 // Get per-channel Tx Power Level
2861 for(i
=0; i
<14; i
+=2)
2863 if(!priv
->AutoloadFailFlag
)
2865 usValue
= eprom_read(dev
, (u16
) ((EEPROM_TxPwIndex_CCK
+i
)>>1) );
2869 usValue
= EEPROM_Default_TxPower
;
2871 *((u16
*)(&priv
->EEPROMTxPowerLevelCCK
[i
])) = usValue
;
2872 RT_TRACE(COMP_INIT
,"CCK Tx Power Level, Index %d = 0x%02x\n", i
, priv
->EEPROMTxPowerLevelCCK
[i
]);
2873 RT_TRACE(COMP_INIT
, "CCK Tx Power Level, Index %d = 0x%02x\n", i
+1, priv
->EEPROMTxPowerLevelCCK
[i
+1]);
2875 for(i
=0; i
<14; i
+=2)
2877 if(!priv
->AutoloadFailFlag
)
2879 usValue
= eprom_read(dev
, (u16
) ((EEPROM_TxPwIndex_OFDM_24G
+i
)>>1) );
2883 usValue
= EEPROM_Default_TxPower
;
2885 *((u16
*)(&priv
->EEPROMTxPowerLevelOFDM24G
[i
])) = usValue
;
2886 RT_TRACE(COMP_INIT
, "OFDM 2.4G Tx Power Level, Index %d = 0x%02x\n", i
, priv
->EEPROMTxPowerLevelOFDM24G
[i
]);
2887 RT_TRACE(COMP_INIT
, "OFDM 2.4G Tx Power Level, Index %d = 0x%02x\n", i
+1, priv
->EEPROMTxPowerLevelOFDM24G
[i
+1]);
2890 else if(priv
->epromtype
== EPROM_93c56
)
2893 // Read CrystalCap from EEPROM
2894 if(!priv
->AutoloadFailFlag
)
2896 priv
->EEPROMAntPwDiff
= EEPROM_Default_AntTxPowerDiff
;
2897 priv
->EEPROMCrystalCap
= (u8
)(((eprom_read(dev
, (EEPROM_C56_CrystalCap
>>1))) & 0xf000)>>12);
2901 priv
->EEPROMAntPwDiff
= EEPROM_Default_AntTxPowerDiff
;
2902 priv
->EEPROMCrystalCap
= EEPROM_Default_TxPwDiff_CrystalCap
;
2904 RT_TRACE(COMP_INIT
,"EEPROMAntPwDiff = %d\n", priv
->EEPROMAntPwDiff
);
2905 RT_TRACE(COMP_INIT
, "EEPROMCrystalCap = %d\n", priv
->EEPROMCrystalCap
);
2907 // Get Tx Power Level by Channel
2908 if(!priv
->AutoloadFailFlag
)
2910 // Read Tx power of Channel 1 ~ 14 from EEPROM.
2911 for(i
= 0; i
< 12; i
+=2)
2914 offset
= EEPROM_C56_RfA_CCK_Chnl1_TxPwIndex
+ i
;
2916 offset
= EEPROM_C56_RfC_CCK_Chnl1_TxPwIndex
+ i
- 6;
2917 usValue
= eprom_read(dev
, (offset
>>1));
2918 *((u16
*)(&EepromTxPower
[i
])) = usValue
;
2921 for(i
= 0; i
< 12; i
++)
2924 priv
->EEPROMRfACCKChnl1TxPwLevel
[i
] = EepromTxPower
[i
];
2925 else if ((i
>=3 )&&(i
<= 5))
2926 priv
->EEPROMRfAOfdmChnlTxPwLevel
[i
-3] = EepromTxPower
[i
];
2927 else if ((i
>=6 )&&(i
<= 8))
2928 priv
->EEPROMRfCCCKChnl1TxPwLevel
[i
-6] = EepromTxPower
[i
];
2930 priv
->EEPROMRfCOfdmChnlTxPwLevel
[i
-9] = EepromTxPower
[i
];
2935 priv
->EEPROMRfACCKChnl1TxPwLevel
[0] = EEPROM_Default_TxPowerLevel
;
2936 priv
->EEPROMRfACCKChnl1TxPwLevel
[1] = EEPROM_Default_TxPowerLevel
;
2937 priv
->EEPROMRfACCKChnl1TxPwLevel
[2] = EEPROM_Default_TxPowerLevel
;
2939 priv
->EEPROMRfAOfdmChnlTxPwLevel
[0] = EEPROM_Default_TxPowerLevel
;
2940 priv
->EEPROMRfAOfdmChnlTxPwLevel
[1] = EEPROM_Default_TxPowerLevel
;
2941 priv
->EEPROMRfAOfdmChnlTxPwLevel
[2] = EEPROM_Default_TxPowerLevel
;
2943 priv
->EEPROMRfCCCKChnl1TxPwLevel
[0] = EEPROM_Default_TxPowerLevel
;
2944 priv
->EEPROMRfCCCKChnl1TxPwLevel
[1] = EEPROM_Default_TxPowerLevel
;
2945 priv
->EEPROMRfCCCKChnl1TxPwLevel
[2] = EEPROM_Default_TxPowerLevel
;
2947 priv
->EEPROMRfCOfdmChnlTxPwLevel
[0] = EEPROM_Default_TxPowerLevel
;
2948 priv
->EEPROMRfCOfdmChnlTxPwLevel
[1] = EEPROM_Default_TxPowerLevel
;
2949 priv
->EEPROMRfCOfdmChnlTxPwLevel
[2] = EEPROM_Default_TxPowerLevel
;
2951 RT_TRACE(COMP_INIT
, "priv->EEPROMRfACCKChnl1TxPwLevel[0] = 0x%x\n", priv
->EEPROMRfACCKChnl1TxPwLevel
[0]);
2952 RT_TRACE(COMP_INIT
, "priv->EEPROMRfACCKChnl1TxPwLevel[1] = 0x%x\n", priv
->EEPROMRfACCKChnl1TxPwLevel
[1]);
2953 RT_TRACE(COMP_INIT
, "priv->EEPROMRfACCKChnl1TxPwLevel[2] = 0x%x\n", priv
->EEPROMRfACCKChnl1TxPwLevel
[2]);
2954 RT_TRACE(COMP_INIT
, "priv->EEPROMRfAOfdmChnlTxPwLevel[0] = 0x%x\n", priv
->EEPROMRfAOfdmChnlTxPwLevel
[0]);
2955 RT_TRACE(COMP_INIT
, "priv->EEPROMRfAOfdmChnlTxPwLevel[1] = 0x%x\n", priv
->EEPROMRfAOfdmChnlTxPwLevel
[1]);
2956 RT_TRACE(COMP_INIT
, "priv->EEPROMRfAOfdmChnlTxPwLevel[2] = 0x%x\n", priv
->EEPROMRfAOfdmChnlTxPwLevel
[2]);
2957 RT_TRACE(COMP_INIT
, "priv->EEPROMRfCCCKChnl1TxPwLevel[0] = 0x%x\n", priv
->EEPROMRfCCCKChnl1TxPwLevel
[0]);
2958 RT_TRACE(COMP_INIT
, "priv->EEPROMRfCCCKChnl1TxPwLevel[1] = 0x%x\n", priv
->EEPROMRfCCCKChnl1TxPwLevel
[1]);
2959 RT_TRACE(COMP_INIT
, "priv->EEPROMRfCCCKChnl1TxPwLevel[2] = 0x%x\n", priv
->EEPROMRfCCCKChnl1TxPwLevel
[2]);
2960 RT_TRACE(COMP_INIT
, "priv->EEPROMRfCOfdmChnlTxPwLevel[0] = 0x%x\n", priv
->EEPROMRfCOfdmChnlTxPwLevel
[0]);
2961 RT_TRACE(COMP_INIT
, "priv->EEPROMRfCOfdmChnlTxPwLevel[1] = 0x%x\n", priv
->EEPROMRfCOfdmChnlTxPwLevel
[1]);
2962 RT_TRACE(COMP_INIT
, "priv->EEPROMRfCOfdmChnlTxPwLevel[2] = 0x%x\n", priv
->EEPROMRfCOfdmChnlTxPwLevel
[2]);
2967 // Update HAL variables.
2969 if(priv
->epromtype
== EPROM_93c46
)
2973 priv
->TxPowerLevelCCK
[i
] = priv
->EEPROMTxPowerLevelCCK
[i
];
2974 priv
->TxPowerLevelOFDM24G
[i
] = priv
->EEPROMTxPowerLevelOFDM24G
[i
];
2976 priv
->LegacyHTTxPowerDiff
= priv
->EEPROMLegacyHTTxPowerDiff
;
2977 // Antenna B gain offset to antenna A, bit0~3
2978 priv
->AntennaTxPwDiff
[0] = (priv
->EEPROMAntPwDiff
& 0xf);
2979 // Antenna C gain offset to antenna A, bit4~7
2980 priv
->AntennaTxPwDiff
[1] = ((priv
->EEPROMAntPwDiff
& 0xf0)>>4);
2981 // Antenna D gain offset to antenna A, bit8~11
2982 priv
->AntennaTxPwDiff
[2] = ((priv
->EEPROMAntPwDiff
& 0xf00)>>8);
2983 // CrystalCap, bit12~15
2984 priv
->CrystalCap
= priv
->EEPROMCrystalCap
;
2985 // ThermalMeter, bit0~3 for RFIC1, bit4~7 for RFIC2
2986 priv
->ThermalMeter
[0] = (priv
->EEPROMThermalMeter
& 0xf);
2987 priv
->ThermalMeter
[1] = ((priv
->EEPROMThermalMeter
& 0xf0)>>4);
2989 else if(priv
->epromtype
== EPROM_93c56
)
2991 //char cck_pwr_diff_a=0, cck_pwr_diff_c=0;
2993 //cck_pwr_diff_a = pHalData->EEPROMRfACCKChnl7TxPwLevel - pHalData->EEPROMRfAOfdmChnlTxPwLevel[1];
2994 //cck_pwr_diff_c = pHalData->EEPROMRfCCCKChnl7TxPwLevel - pHalData->EEPROMRfCOfdmChnlTxPwLevel[1];
2995 for(i
=0; i
<3; i
++) // channel 1~3 use the same Tx Power Level.
2997 priv
->TxPowerLevelCCK_A
[i
] = priv
->EEPROMRfACCKChnl1TxPwLevel
[0];
2998 priv
->TxPowerLevelOFDM24G_A
[i
] = priv
->EEPROMRfAOfdmChnlTxPwLevel
[0];
2999 priv
->TxPowerLevelCCK_C
[i
] = priv
->EEPROMRfCCCKChnl1TxPwLevel
[0];
3000 priv
->TxPowerLevelOFDM24G_C
[i
] = priv
->EEPROMRfCOfdmChnlTxPwLevel
[0];
3002 for(i
=3; i
<9; i
++) // channel 4~9 use the same Tx Power Level
3004 priv
->TxPowerLevelCCK_A
[i
] = priv
->EEPROMRfACCKChnl1TxPwLevel
[1];
3005 priv
->TxPowerLevelOFDM24G_A
[i
] = priv
->EEPROMRfAOfdmChnlTxPwLevel
[1];
3006 priv
->TxPowerLevelCCK_C
[i
] = priv
->EEPROMRfCCCKChnl1TxPwLevel
[1];
3007 priv
->TxPowerLevelOFDM24G_C
[i
] = priv
->EEPROMRfCOfdmChnlTxPwLevel
[1];
3009 for(i
=9; i
<14; i
++) // channel 10~14 use the same Tx Power Level
3011 priv
->TxPowerLevelCCK_A
[i
] = priv
->EEPROMRfACCKChnl1TxPwLevel
[2];
3012 priv
->TxPowerLevelOFDM24G_A
[i
] = priv
->EEPROMRfAOfdmChnlTxPwLevel
[2];
3013 priv
->TxPowerLevelCCK_C
[i
] = priv
->EEPROMRfCCCKChnl1TxPwLevel
[2];
3014 priv
->TxPowerLevelOFDM24G_C
[i
] = priv
->EEPROMRfCOfdmChnlTxPwLevel
[2];
3017 RT_TRACE(COMP_INIT
, "priv->TxPowerLevelCCK_A[%d] = 0x%x\n", i
, priv
->TxPowerLevelCCK_A
[i
]);
3019 RT_TRACE(COMP_INIT
,"priv->TxPowerLevelOFDM24G_A[%d] = 0x%x\n", i
, priv
->TxPowerLevelOFDM24G_A
[i
]);
3021 RT_TRACE(COMP_INIT
, "priv->TxPowerLevelCCK_C[%d] = 0x%x\n", i
, priv
->TxPowerLevelCCK_C
[i
]);
3023 RT_TRACE(COMP_INIT
, "priv->TxPowerLevelOFDM24G_C[%d] = 0x%x\n", i
, priv
->TxPowerLevelOFDM24G_C
[i
]);
3024 priv
->LegacyHTTxPowerDiff
= priv
->EEPROMLegacyHTTxPowerDiff
;
3025 priv
->AntennaTxPwDiff
[0] = 0;
3026 priv
->AntennaTxPwDiff
[1] = 0;
3027 priv
->AntennaTxPwDiff
[2] = 0;
3028 priv
->CrystalCap
= priv
->EEPROMCrystalCap
;
3029 // ThermalMeter, bit0~3 for RFIC1, bit4~7 for RFIC2
3030 priv
->ThermalMeter
[0] = (priv
->EEPROMThermalMeter
& 0xf);
3031 priv
->ThermalMeter
[1] = ((priv
->EEPROMThermalMeter
& 0xf0)>>4);
3035 if(priv
->rf_type
== RF_1T2R
)
3037 RT_TRACE(COMP_INIT
, "\n1T2R config\n");
3039 else if (priv
->rf_type
== RF_2T4R
)
3041 RT_TRACE(COMP_INIT
, "\n2T4R config\n");
3044 // 2008/01/16 MH We can only know RF type in the function. So we have to init
3045 // DIG RATR table again.
3046 init_rate_adaptive(dev
);
3048 //1 Make a copy for following variables and we can change them if we want
3050 priv
->rf_chip
= RF_8256
;
3052 if(priv
->RegChannelPlan
== 0xf)
3054 priv
->ChannelPlan
= priv
->eeprom_ChannelPlan
;
3058 priv
->ChannelPlan
= priv
->RegChannelPlan
;
3062 // Used PID and DID to Set CustomerID
3064 if( priv
->eeprom_vid
== 0x1186 && priv
->eeprom_did
== 0x3304 )
3066 priv
->CustomerID
= RT_CID_DLINK
;
3069 switch(priv
->eeprom_CustomerID
)
3071 case EEPROM_CID_DEFAULT
:
3072 priv
->CustomerID
= RT_CID_DEFAULT
;
3074 case EEPROM_CID_CAMEO
:
3075 priv
->CustomerID
= RT_CID_819x_CAMEO
;
3077 case EEPROM_CID_RUNTOP
:
3078 priv
->CustomerID
= RT_CID_819x_RUNTOP
;
3080 case EEPROM_CID_NetCore
:
3081 priv
->CustomerID
= RT_CID_819x_Netcore
;
3083 case EEPROM_CID_TOSHIBA
: // Merge by Jacken, 2008/01/31
3084 priv
->CustomerID
= RT_CID_TOSHIBA
;
3085 if(priv
->eeprom_ChannelPlan
&0x80)
3086 priv
->ChannelPlan
= priv
->eeprom_ChannelPlan
&0x7f;
3088 priv
->ChannelPlan
= 0x0;
3089 RT_TRACE(COMP_INIT
, "Toshiba ChannelPlan = 0x%x\n",
3092 case EEPROM_CID_Nettronix
:
3093 priv
->ScanDelay
= 100; //cosa add for scan
3094 priv
->CustomerID
= RT_CID_Nettronix
;
3096 case EEPROM_CID_Pronet
:
3097 priv
->CustomerID
= RT_CID_PRONET
;
3099 case EEPROM_CID_DLINK
:
3100 priv
->CustomerID
= RT_CID_DLINK
;
3103 case EEPROM_CID_WHQL
:
3104 //Adapter->bInHctTest = TRUE;//do not supported
3106 //priv->bSupportTurboMode = FALSE;
3107 //priv->bAutoTurboBy8186 = FALSE;
3109 //pMgntInfo->PowerSaveControl.bInactivePs = FALSE;
3110 //pMgntInfo->PowerSaveControl.bIPSModeBackup = FALSE;
3111 //pMgntInfo->PowerSaveControl.bLeisurePs = FALSE;
3115 // value from RegCustomerID
3119 //Avoid the channel plan array overflow, by Bruce, 2007-08-27.
3120 if(priv
->ChannelPlan
> CHANNEL_PLAN_LEN
- 1)
3121 priv
->ChannelPlan
= 0; //FCC
3123 switch(priv
->CustomerID
)
3125 case RT_CID_DEFAULT
:
3127 priv
->LedStrategy
= HW_LED
;
3130 priv
->LedStrategy
= SW_LED_MODE1
;
3135 case RT_CID_819x_CAMEO
:
3136 priv
->LedStrategy
= SW_LED_MODE2
;
3139 case RT_CID_819x_RUNTOP
:
3140 priv
->LedStrategy
= SW_LED_MODE3
;
3143 case RT_CID_819x_Netcore
:
3144 priv
->LedStrategy
= SW_LED_MODE4
;
3147 case RT_CID_Nettronix
:
3148 priv
->LedStrategy
= SW_LED_MODE5
;
3152 priv
->LedStrategy
= SW_LED_MODE6
;
3155 case RT_CID_TOSHIBA
: //Modify by Jacken 2008/01/31
3161 priv
->LedStrategy
= HW_LED
;
3164 priv
->LedStrategy
= SW_LED_MODE1
;
3171 if( priv
->eeprom_vid
== 0x1186 && priv
->eeprom_did
== 0x3304)
3172 priv
->ieee80211
->bSupportRemoteWakeUp
= true;
3174 priv
->ieee80211
->bSupportRemoteWakeUp
= false;
3177 RT_TRACE(COMP_INIT
, "RegChannelPlan(%d)\n", priv
->RegChannelPlan
);
3178 RT_TRACE(COMP_INIT
, "ChannelPlan = %d \n", priv
->ChannelPlan
);
3179 RT_TRACE(COMP_INIT
, "LedStrategy = %d \n", priv
->LedStrategy
);
3180 RT_TRACE(COMP_TRACE
, "<==== ReadAdapterInfo\n");
3186 static short rtl8192_get_channel_map(struct net_device
* dev
)
3188 struct r8192_priv
*priv
= ieee80211_priv(dev
);
3189 #ifdef ENABLE_DOT11D
3190 if(priv
->ChannelPlan
> COUNTRY_CODE_GLOBAL_DOMAIN
){
3191 printk("rtl8180_init:Error channel plan! Set to default.\n");
3192 priv
->ChannelPlan
= 0;
3194 RT_TRACE(COMP_INIT
, "Channel plan is %d\n",priv
->ChannelPlan
);
3196 rtl819x_set_channel_map(priv
->ChannelPlan
, priv
);
3199 //Set Default Channel Plan
3201 DMESG("No channels, aborting");
3205 priv
->ChannelPlan
= 0;//hikaru
3206 // set channels 1..14 allowed in given locale
3207 for (i
=1; i
<=14; i
++) {
3208 (priv
->ieee80211
->channel_map
)[i
] = (u8
)(ch
& 0x01);
3215 static short rtl8192_init(struct net_device
*dev
)
3217 struct r8192_priv
*priv
= ieee80211_priv(dev
);
3218 memset(&(priv
->stats
),0,sizeof(struct Stats
));
3219 rtl8192_init_priv_variable(dev
);
3220 rtl8192_init_priv_lock(priv
);
3221 rtl8192_init_priv_task(dev
);
3222 rtl8192_get_eeprom_size(dev
);
3223 rtl8192_read_eeprom_info(dev
);
3224 rtl8192_get_channel_map(dev
);
3226 init_timer(&priv
->watch_dog_timer
);
3227 priv
->watch_dog_timer
.data
= (unsigned long)dev
;
3228 priv
->watch_dog_timer
.function
= watch_dog_timer_callback
;
3229 #if defined(IRQF_SHARED)
3230 if(request_irq(dev
->irq
, (void*)rtl8192_interrupt
, IRQF_SHARED
, dev
->name
, dev
)){
3232 if(request_irq(dev
->irq
, (void *)rtl8192_interrupt
, SA_SHIRQ
, dev
->name
, dev
)){
3234 printk("Error allocating IRQ %d",dev
->irq
);
3238 printk("IRQ %d",dev
->irq
);
3240 if(rtl8192_pci_initdescring(dev
)!=0){
3241 printk("Endopoints initialization failed");
3245 //rtl8192_rx_enable(dev);
3246 //rtl8192_adapter_start(dev);
3250 /******************************************************************************
3251 *function: This function actually only set RRSR, RATR and BW_OPMODE registers
3252 * not to do all the hw config as its name says
3253 * input: net_device dev
3256 * notice: This part need to modified according to the rate set we filtered
3257 * ****************************************************************************/
3258 static void rtl8192_hwconfig(struct net_device
* dev
)
3260 u32 regRATR
= 0, regRRSR
= 0;
3261 u8 regBwOpMode
= 0, regTmp
= 0;
3262 struct r8192_priv
*priv
= ieee80211_priv(dev
);
3264 // Set RRSR, RATR, and BW_OPMODE registers
3266 switch(priv
->ieee80211
->mode
)
3268 case WIRELESS_MODE_B
:
3269 regBwOpMode
= BW_OPMODE_20MHZ
;
3270 regRATR
= RATE_ALL_CCK
;
3271 regRRSR
= RATE_ALL_CCK
;
3273 case WIRELESS_MODE_A
:
3274 regBwOpMode
= BW_OPMODE_5G
|BW_OPMODE_20MHZ
;
3275 regRATR
= RATE_ALL_OFDM_AG
;
3276 regRRSR
= RATE_ALL_OFDM_AG
;
3278 case WIRELESS_MODE_G
:
3279 regBwOpMode
= BW_OPMODE_20MHZ
;
3280 regRATR
= RATE_ALL_CCK
| RATE_ALL_OFDM_AG
;
3281 regRRSR
= RATE_ALL_CCK
| RATE_ALL_OFDM_AG
;
3283 case WIRELESS_MODE_AUTO
:
3284 case WIRELESS_MODE_N_24G
:
3285 // It support CCK rate by default.
3286 // CCK rate will be filtered out only when associated AP does not support it.
3287 regBwOpMode
= BW_OPMODE_20MHZ
;
3288 regRATR
= RATE_ALL_CCK
| RATE_ALL_OFDM_AG
| RATE_ALL_OFDM_1SS
| RATE_ALL_OFDM_2SS
;
3289 regRRSR
= RATE_ALL_CCK
| RATE_ALL_OFDM_AG
;
3291 case WIRELESS_MODE_N_5G
:
3292 regBwOpMode
= BW_OPMODE_5G
;
3293 regRATR
= RATE_ALL_OFDM_AG
| RATE_ALL_OFDM_1SS
| RATE_ALL_OFDM_2SS
;
3294 regRRSR
= RATE_ALL_OFDM_AG
;
3298 write_nic_byte(dev
, BW_OPMODE
, regBwOpMode
);
3301 ratr_value
= regRATR
;
3302 if (priv
->rf_type
== RF_1T2R
)
3304 ratr_value
&= ~(RATE_ALL_OFDM_2SS
);
3306 write_nic_dword(dev
, RATR0
, ratr_value
);
3307 write_nic_byte(dev
, UFWP
, 1);
3309 regTmp
= read_nic_byte(dev
, 0x313);
3310 regRRSR
= ((regTmp
) << 24) | (regRRSR
& 0x00ffffff);
3311 write_nic_dword(dev
, RRSR
, regRRSR
);
3314 // Set Retry Limit here
3316 write_nic_word(dev
, RETRY_LIMIT
,
3317 priv
->ShortRetryLimit
<< RETRY_LIMIT_SHORT_SHIFT
|
3318 priv
->LongRetryLimit
<< RETRY_LIMIT_LONG_SHIFT
);
3319 // Set Contention Window here
3323 // Set Tx Antenna including Feedback control
3325 // Set Auto Rate fallback control
3331 static RT_STATUS
rtl8192_adapter_start(struct net_device
*dev
)
3333 struct r8192_priv
*priv
= ieee80211_priv(dev
);
3334 // struct ieee80211_device *ieee = priv->ieee80211;
3336 RT_STATUS rtStatus
= RT_STATUS_SUCCESS
;
3337 // static char szMACPHYRegFile[] = RTL819X_PHY_MACPHY_REG;
3338 // static char szMACPHYRegPGFile[] = RTL819X_PHY_MACPHY_REG_PG;
3342 u8 ICVersion
,SwitchingRegulatorOutput
;
3344 bool bfirmwareok
= true;
3348 u32 tmpRegA
, tmpRegC
, TempCCk
;
3350 // u32 dwRegRead = 0;
3352 RT_TRACE(COMP_INIT
, "====>%s()\n", __FUNCTION__
);
3353 priv
->being_init_adapter
= true;
3354 rtl8192_pci_resetdescring(dev
);
3355 // 2007/11/02 MH Before initalizing RF. We can not use FW to do RF-R/W.
3356 priv
->Rf_Mode
= RF_OP_By_SW_3wire
;
3359 if(priv
->ResetProgress
== RESET_TYPE_NORESET
)
3361 write_nic_byte(dev
, ANAPAR
, 0x37);
3362 // Accordign to designer's explain, LBUS active will never > 10ms. We delay 10ms
3363 // Joseph increae the time to prevent firmware download fail
3367 //PlatformSleepUs(10000);
3368 // For any kind of InitializeAdapter process, we shall use system now!!
3369 priv
->pFirmware
->firmware_status
= FW_STATUS_0_INIT
;
3371 // Set to eRfoff in order not to count receive count.
3372 if(priv
->RegRfOff
== TRUE
)
3373 priv
->ieee80211
->eRFPowerState
= eRfOff
;
3376 //3 //Config CPUReset Register
3378 //3 Firmware Reset Or Not
3379 ulRegRead
= read_nic_dword(dev
, CPU_GEN
);
3380 if(priv
->pFirmware
->firmware_status
== FW_STATUS_0_INIT
)
3381 { //called from MPInitialized. do nothing
3382 ulRegRead
|= CPU_GEN_SYSTEM_RESET
;
3383 }else if(priv
->pFirmware
->firmware_status
== FW_STATUS_5_READY
)
3384 ulRegRead
|= CPU_GEN_FIRMWARE_RESET
; // Called from MPReset
3386 RT_TRACE(COMP_ERR
, "ERROR in %s(): undefined firmware state(%d)\n", __FUNCTION__
, priv
->pFirmware
->firmware_status
);
3389 //2008.06.03, for WOL 90 hw bug
3390 ulRegRead
&= (~(CPU_GEN_GPIO_UART
));
3393 write_nic_dword(dev
, CPU_GEN
, ulRegRead
);
3399 //3 //Fix the issue of E-cut high temperature issue
3402 ICVersion
= read_nic_byte(dev
, IC_VERRSION
);
3403 if(ICVersion
>= 0x4) //E-cut only
3405 // HW SD suggest that we should not wirte this register too often, so driver
3406 // should readback this register. This register will be modified only when
3408 SwitchingRegulatorOutput
= read_nic_byte(dev
, SWREGULATOR
);
3409 if(SwitchingRegulatorOutput
!= 0xb8)
3411 write_nic_byte(dev
, SWREGULATOR
, 0xa8);
3413 write_nic_byte(dev
, SWREGULATOR
, 0xb8);
3420 //3// Initialize BB before MAC
3422 RT_TRACE(COMP_INIT
, "BB Config Start!\n");
3423 rtStatus
= rtl8192_BBConfig(dev
);
3424 if(rtStatus
!= RT_STATUS_SUCCESS
)
3426 RT_TRACE(COMP_ERR
, "BB Config failed\n");
3429 RT_TRACE(COMP_INIT
,"BB Config Finished!\n");
3431 //3//Set Loopback mode or Normal mode
3433 //2006.12.13 by emily. Note!We should not merge these two CPU_GEN register writings
3434 // because setting of System_Reset bit reset MAC to default transmission mode.
3435 //Loopback mode or not
3436 priv
->LoopbackMode
= RTL819X_NO_LOOPBACK
;
3437 //priv->LoopbackMode = RTL819X_MAC_LOOPBACK;
3438 if(priv
->ResetProgress
== RESET_TYPE_NORESET
)
3440 ulRegRead
= read_nic_dword(dev
, CPU_GEN
);
3441 if(priv
->LoopbackMode
== RTL819X_NO_LOOPBACK
)
3443 ulRegRead
= ((ulRegRead
& CPU_GEN_NO_LOOPBACK_MSK
) | CPU_GEN_NO_LOOPBACK_SET
);
3445 else if (priv
->LoopbackMode
== RTL819X_MAC_LOOPBACK
)
3447 ulRegRead
|= CPU_CCK_LOOPBACK
;
3451 RT_TRACE(COMP_ERR
,"Serious error: wrong loopback mode setting\n");
3454 //2008.06.03, for WOL
3455 //ulRegRead &= (~(CPU_GEN_GPIO_UART));
3456 write_nic_dword(dev
, CPU_GEN
, ulRegRead
);
3458 // 2006.11.29. After reset cpu, we sholud wait for a second, otherwise, it may fail to write registers. Emily
3461 //3Set Hardware(Do nothing now)
3462 rtl8192_hwconfig(dev
);
3463 //2=======================================================
3464 // Common Setting for all of the FPGA platform. (part 1)
3465 //2=======================================================
3466 // If there is changes, please make sure it applies to all of the FPGA version
3468 write_nic_byte(dev
, CMDR
, CR_RE
|CR_TE
);
3472 write_nic_byte(dev
, PCIF
, ((MXDMA2_NoLimit
<<MXDMA2_RX_SHIFT
) |
3473 (MXDMA2_NoLimit
<<MXDMA2_TX_SHIFT
) |
3477 write_nic_byte(dev
, PCIF
, ((MXDMA2_NoLimit
<<MXDMA2_RX_SHIFT
) |
3478 (MXDMA2_NoLimit
<<MXDMA2_TX_SHIFT
) ));
3482 write_nic_dword(dev
, MAC0
, ((u32
*)dev
->dev_addr
)[0]);
3483 write_nic_word(dev
, MAC4
, ((u16
*)(dev
->dev_addr
+ 4))[0]);
3485 write_nic_dword(dev
, RCR
, priv
->ReceiveConfig
);
3487 //3 Initialize Number of Reserved Pages in Firmware Queue
3489 if(priv
->bInHctTest
)
3491 PlatformEFIOWrite4Byte(Adapter
, RQPN1
, NUM_OF_PAGE_IN_FW_QUEUE_BK_DTM
<< RSVD_FW_QUEUE_PAGE_BK_SHIFT
|
3492 NUM_OF_PAGE_IN_FW_QUEUE_BE_DTM
<< RSVD_FW_QUEUE_PAGE_BE_SHIFT
|
3493 NUM_OF_PAGE_IN_FW_QUEUE_VI_DTM
<< RSVD_FW_QUEUE_PAGE_VI_SHIFT
|
3494 NUM_OF_PAGE_IN_FW_QUEUE_VO_DTM
<<RSVD_FW_QUEUE_PAGE_VO_SHIFT
);
3495 PlatformEFIOWrite4Byte(Adapter
, RQPN2
, NUM_OF_PAGE_IN_FW_QUEUE_MGNT
<< RSVD_FW_QUEUE_PAGE_MGNT_SHIFT
);
3496 PlatformEFIOWrite4Byte(Adapter
, RQPN3
, APPLIED_RESERVED_QUEUE_IN_FW
|
3497 NUM_OF_PAGE_IN_FW_QUEUE_BCN
<<RSVD_FW_QUEUE_PAGE_BCN_SHIFT
|
3498 NUM_OF_PAGE_IN_FW_QUEUE_PUB_DTM
<<RSVD_FW_QUEUE_PAGE_PUB_SHIFT
);
3503 write_nic_dword(dev
, RQPN1
, NUM_OF_PAGE_IN_FW_QUEUE_BK
<< RSVD_FW_QUEUE_PAGE_BK_SHIFT
|
3504 NUM_OF_PAGE_IN_FW_QUEUE_BE
<< RSVD_FW_QUEUE_PAGE_BE_SHIFT
|
3505 NUM_OF_PAGE_IN_FW_QUEUE_VI
<< RSVD_FW_QUEUE_PAGE_VI_SHIFT
|
3506 NUM_OF_PAGE_IN_FW_QUEUE_VO
<<RSVD_FW_QUEUE_PAGE_VO_SHIFT
);
3507 write_nic_dword(dev
, RQPN2
, NUM_OF_PAGE_IN_FW_QUEUE_MGNT
<< RSVD_FW_QUEUE_PAGE_MGNT_SHIFT
);
3508 write_nic_dword(dev
, RQPN3
, APPLIED_RESERVED_QUEUE_IN_FW
|
3509 NUM_OF_PAGE_IN_FW_QUEUE_BCN
<<RSVD_FW_QUEUE_PAGE_BCN_SHIFT
|
3510 NUM_OF_PAGE_IN_FW_QUEUE_PUB
<<RSVD_FW_QUEUE_PAGE_PUB_SHIFT
);
3513 rtl8192_tx_enable(dev
);
3514 rtl8192_rx_enable(dev
);
3515 //3Set Response Rate Setting Register
3516 // CCK rate is supported by default.
3517 // CCK rate will be filtered out only when associated AP does not support it.
3518 ulRegRead
= (0xFFF00000 & read_nic_dword(dev
, RRSR
)) | RATE_ALL_OFDM_AG
| RATE_ALL_CCK
;
3519 write_nic_dword(dev
, RRSR
, ulRegRead
);
3520 write_nic_dword(dev
, RATR0
+4*7, (RATE_ALL_OFDM_AG
| RATE_ALL_CCK
));
3523 // TODO: (it value is only for FPGA version). need to be changed!!2006.12.18, by Emily
3524 write_nic_byte(dev
, ACK_TIMEOUT
, 0x30);
3526 //rtl8192_actset_wirelessmode(dev,priv->RegWirelessMode);
3527 if(priv
->ResetProgress
== RESET_TYPE_NORESET
)
3528 rtl8192_SetWirelessMode(dev
, priv
->ieee80211
->mode
);
3529 //-----------------------------------------------------------------------------
3530 // Set up security related. 070106, by rcnjko:
3531 // 1. Clear all H/W keys.
3532 // 2. Enable H/W encryption/decryption.
3533 //-----------------------------------------------------------------------------
3534 CamResetAllEntry(dev
);
3536 u8 SECR_value
= 0x0;
3537 SECR_value
|= SCR_TxEncEnable
;
3538 SECR_value
|= SCR_RxDecEnable
;
3539 SECR_value
|= SCR_NoSKMC
;
3540 write_nic_byte(dev
, SECR
, SECR_value
);
3543 write_nic_word(dev
, ATIMWND
, 2);
3544 write_nic_word(dev
, BCN_INTERVAL
, 100);
3545 for (i
=0; i
<QOS_QUEUE_NUM
; i
++)
3546 write_nic_dword(dev
, WDCAPARA_ADD
[i
], 0x005e4332);
3548 // Switching regulator controller: This is set temporarily.
3549 // It's not sure if this can be removed in the future.
3550 // PJ advised to leave it by default.
3552 write_nic_byte(dev
, 0xbe, 0xc0);
3554 //2=======================================================
3555 // Set PHY related configuration defined in MAC register bank
3556 //2=======================================================
3557 rtl8192_phy_configmac(dev
);
3559 if (priv
->card_8192_version
> (u8
) VERSION_8190_BD
) {
3560 rtl8192_phy_getTxPower(dev
);
3561 rtl8192_phy_setTxPower(dev
, priv
->chan
);
3565 tmpvalue
= read_nic_byte(dev
, IC_VERRSION
);
3566 priv
->IC_Cut
= tmpvalue
;
3567 RT_TRACE(COMP_INIT
, "priv->IC_Cut = 0x%x\n", priv
->IC_Cut
);
3568 if(priv
->IC_Cut
>= IC_VersionCut_D
)
3570 //pHalData->bDcut = TRUE;
3571 if(priv
->IC_Cut
== IC_VersionCut_D
)
3572 RT_TRACE(COMP_INIT
, "D-cut\n");
3573 if(priv
->IC_Cut
== IC_VersionCut_E
)
3575 RT_TRACE(COMP_INIT
, "E-cut\n");
3576 // HW SD suggest that we should not wirte this register too often, so driver
3577 // should readback this register. This register will be modified only when
3583 //pHalData->bDcut = FALSE;
3584 RT_TRACE(COMP_INIT
, "Before C-cut\n");
3589 RT_TRACE(COMP_INIT
, "Load Firmware!\n");
3590 bfirmwareok
= init_firmware(dev
);
3591 if(bfirmwareok
!= true) {
3592 rtStatus
= RT_STATUS_FAILURE
;
3595 RT_TRACE(COMP_INIT
, "Load Firmware finished!\n");
3598 if(priv
->ResetProgress
== RESET_TYPE_NORESET
)
3600 RT_TRACE(COMP_INIT
, "RF Config Started!\n");
3601 rtStatus
= rtl8192_phy_RFConfig(dev
);
3602 if(rtStatus
!= RT_STATUS_SUCCESS
)
3604 RT_TRACE(COMP_ERR
, "RF Config failed\n");
3607 RT_TRACE(COMP_INIT
, "RF Config Finished!\n");
3609 rtl8192_phy_updateInitGain(dev
);
3611 /*---- Set CCK and OFDM Block "ON"----*/
3612 rtl8192_setBBreg(dev
, rFPGA0_RFMOD
, bCCKEn
, 0x1);
3613 rtl8192_setBBreg(dev
, rFPGA0_RFMOD
, bOFDMEn
, 0x1);
3617 write_nic_byte(dev
, 0x87, 0x0);
3620 //2008.06.03, for WOL
3621 ucRegRead
= read_nic_byte(dev
, GPE
);
3623 write_nic_byte(dev
, GPE
, ucRegRead
);
3625 ucRegRead
= read_nic_byte(dev
, GPO
);
3627 write_nic_byte(dev
, GPO
, ucRegRead
);
3630 //2=======================================================
3632 //2=======================================================
3636 if(priv
->RegRfOff
== TRUE
)
3637 { // User disable RF via registry.
3638 RT_TRACE((COMP_INIT
|COMP_RF
|COMP_POWER
), "%s(): Turn off RF for RegRfOff ----------\n",__FUNCTION__
);
3639 MgntActSet_RF_State(dev
, eRfOff
, RF_CHANGE_BY_SW
);
3640 #if 0//cosa, ask SD3 willis and he doesn't know what is this for
3641 // Those action will be discard in MgntActSet_RF_State because off the same state
3642 for(eRFPath
= 0; eRFPath
<pHalData
->NumTotalRFPath
; eRFPath
++)
3643 PHY_SetRFReg(Adapter
, (RF90_RADIO_PATH_E
)eRFPath
, 0x4, 0xC00, 0x0);
3646 else if(priv
->ieee80211
->RfOffReason
> RF_CHANGE_BY_PS
)
3647 { // H/W or S/W RF OFF before sleep.
3648 RT_TRACE((COMP_INIT
|COMP_RF
|COMP_POWER
), "%s(): Turn off RF for RfOffReason(%d) ----------\n", __FUNCTION__
,priv
->ieee80211
->RfOffReason
);
3649 MgntActSet_RF_State(dev
, eRfOff
, priv
->ieee80211
->RfOffReason
);
3651 else if(priv
->ieee80211
->RfOffReason
>= RF_CHANGE_BY_IPS
)
3652 { // H/W or S/W RF OFF before sleep.
3653 RT_TRACE((COMP_INIT
|COMP_RF
|COMP_POWER
), "%s(): Turn off RF for RfOffReason(%d) ----------\n", __FUNCTION__
,priv
->ieee80211
->RfOffReason
);
3654 MgntActSet_RF_State(dev
, eRfOff
, priv
->ieee80211
->RfOffReason
);
3658 RT_TRACE((COMP_INIT
|COMP_RF
|COMP_POWER
), "%s(): RF-ON \n",__FUNCTION__
);
3659 priv
->ieee80211
->eRFPowerState
= eRfOn
;
3660 priv
->ieee80211
->RfOffReason
= 0;
3661 //DrvIFIndicateCurrentPhyStatus(Adapter);
3663 //Adapter->HalFunc.LedControlHandler(Adapter, LED_CTL_POWER_ON);
3666 // If inactive power mode is enabled, disable rf while in disconnected state.
3667 // But we should still tell upper layer we are in rf on state.
3668 // 2007.07.16, by shien chang.
3670 //if(!Adapter->bInHctTest)
3671 //IPSEnter(Adapter);
3678 // We can force firmware to do RF-R/W
3679 if(priv
->ieee80211
->FwRWRF
)
3680 priv
->Rf_Mode
= RF_OP_By_FW
;
3682 priv
->Rf_Mode
= RF_OP_By_SW_3wire
;
3684 priv
->Rf_Mode
= RF_OP_By_SW_3wire
;
3688 if(priv
->ResetProgress
== RESET_TYPE_NORESET
)
3690 dm_initialize_txpower_tracking(dev
);
3692 tmpRegA
= rtl8192_QueryBBReg(dev
,rOFDM0_XATxIQImbalance
,bMaskDWord
);
3693 tmpRegC
= rtl8192_QueryBBReg(dev
,rOFDM0_XCTxIQImbalance
,bMaskDWord
);
3695 if(priv
->rf_type
== RF_2T4R
){
3696 for(i
= 0; i
<TxBBGainTableLength
; i
++)
3698 if(tmpRegA
== priv
->txbbgain_table
[i
].txbbgain_value
)
3700 priv
->rfa_txpowertrackingindex
= (u8
)i
;
3701 priv
->rfa_txpowertrackingindex_real
= (u8
)i
;
3702 priv
->rfa_txpowertracking_default
= priv
->rfa_txpowertrackingindex
;
3707 for(i
= 0; i
<TxBBGainTableLength
; i
++)
3709 if(tmpRegC
== priv
->txbbgain_table
[i
].txbbgain_value
)
3711 priv
->rfc_txpowertrackingindex
= (u8
)i
;
3712 priv
->rfc_txpowertrackingindex_real
= (u8
)i
;
3713 priv
->rfc_txpowertracking_default
= priv
->rfc_txpowertrackingindex
;
3717 TempCCk
= rtl8192_QueryBBReg(dev
, rCCK0_TxFilter1
, bMaskByte2
);
3719 for(i
=0 ; i
<CCKTxBBGainTableLength
; i
++)
3721 if(TempCCk
== priv
->cck_txbbgain_table
[i
].ccktxbb_valuearray
[0])
3723 priv
->CCKPresentAttentuation_20Mdefault
=(u8
) i
;
3727 priv
->CCKPresentAttentuation_40Mdefault
= 0;
3728 priv
->CCKPresentAttentuation_difference
= 0;
3729 priv
->CCKPresentAttentuation
= priv
->CCKPresentAttentuation_20Mdefault
;
3730 RT_TRACE(COMP_POWER_TRACKING
, "priv->rfa_txpowertrackingindex_initial = %d\n", priv
->rfa_txpowertrackingindex
);
3731 RT_TRACE(COMP_POWER_TRACKING
, "priv->rfa_txpowertrackingindex_real__initial = %d\n", priv
->rfa_txpowertrackingindex_real
);
3732 RT_TRACE(COMP_POWER_TRACKING
, "priv->rfc_txpowertrackingindex_initial = %d\n", priv
->rfc_txpowertrackingindex
);
3733 RT_TRACE(COMP_POWER_TRACKING
, "priv->rfc_txpowertrackingindex_real_initial = %d\n", priv
->rfc_txpowertrackingindex_real
);
3734 RT_TRACE(COMP_POWER_TRACKING
, "priv->CCKPresentAttentuation_difference_initial = %d\n", priv
->CCKPresentAttentuation_difference
);
3735 RT_TRACE(COMP_POWER_TRACKING
, "priv->CCKPresentAttentuation_initial = %d\n", priv
->CCKPresentAttentuation
);
3739 if(priv
->ResetProgress
== RESET_TYPE_NORESET
)
3741 dm_initialize_txpower_tracking(dev
);
3743 if(priv
->IC_Cut
>= IC_VersionCut_D
)
3745 tmpRegA
= rtl8192_QueryBBReg(dev
,rOFDM0_XATxIQImbalance
,bMaskDWord
);
3746 tmpRegC
= rtl8192_QueryBBReg(dev
,rOFDM0_XCTxIQImbalance
,bMaskDWord
);
3747 for(i
= 0; i
<TxBBGainTableLength
; i
++)
3749 if(tmpRegA
== priv
->txbbgain_table
[i
].txbbgain_value
)
3751 priv
->rfa_txpowertrackingindex
= (u8
)i
;
3752 priv
->rfa_txpowertrackingindex_real
= (u8
)i
;
3753 priv
->rfa_txpowertracking_default
= priv
->rfa_txpowertrackingindex
;
3758 TempCCk
= rtl8192_QueryBBReg(dev
, rCCK0_TxFilter1
, bMaskByte2
);
3760 for(i
=0 ; i
<CCKTxBBGainTableLength
; i
++)
3762 if(TempCCk
== priv
->cck_txbbgain_table
[i
].ccktxbb_valuearray
[0])
3764 priv
->CCKPresentAttentuation_20Mdefault
=(u8
) i
;
3768 priv
->CCKPresentAttentuation_40Mdefault
= 0;
3769 priv
->CCKPresentAttentuation_difference
= 0;
3770 priv
->CCKPresentAttentuation
= priv
->CCKPresentAttentuation_20Mdefault
;
3771 RT_TRACE(COMP_POWER_TRACKING
, "priv->rfa_txpowertrackingindex_initial = %d\n", priv
->rfa_txpowertrackingindex
);
3772 RT_TRACE(COMP_POWER_TRACKING
, "priv->rfa_txpowertrackingindex_real__initial = %d\n", priv
->rfa_txpowertrackingindex_real
);
3773 RT_TRACE(COMP_POWER_TRACKING
, "priv->CCKPresentAttentuation_difference_initial = %d\n", priv
->CCKPresentAttentuation_difference
);
3774 RT_TRACE(COMP_POWER_TRACKING
, "priv->CCKPresentAttentuation_initial = %d\n", priv
->CCKPresentAttentuation
);
3775 priv
->btxpower_tracking
= FALSE
;//TEMPLY DISABLE
3780 rtl8192_irq_enable(dev
);
3781 priv
->being_init_adapter
= false;
3786 static void rtl8192_prepare_beacon(struct r8192_priv
*priv
)
3788 struct sk_buff
*skb
;
3789 //unsigned long flags;
3792 skb
= ieee80211_get_beacon(priv
->ieee80211
);
3793 tcb_desc
= (cb_desc
*)(skb
->cb
+ 8);
3794 //printk("===========> %s\n", __FUNCTION__);
3795 //spin_lock_irqsave(&priv->tx_lock,flags);
3796 /* prepare misc info for the beacon xmit */
3797 tcb_desc
->queue_index
= BEACON_QUEUE
;
3798 /* IBSS does not support HT yet, use 1M defaultly */
3799 tcb_desc
->data_rate
= 2;
3800 tcb_desc
->RATRIndex
= 7;
3801 tcb_desc
->bTxDisableRateFallBack
= 1;
3802 tcb_desc
->bTxUseDriverAssingedRate
= 1;
3804 skb_push(skb
, priv
->ieee80211
->tx_headroom
);
3806 rtl8192_tx(priv
->ieee80211
->dev
,skb
);
3808 //spin_unlock_irqrestore (&priv->tx_lock, flags);
3812 /* this configures registers for beacon tx and enables it via
3813 * rtl8192_beacon_tx_enable(). rtl8192_beacon_tx_disable() might
3814 * be used to stop beacon transmission
3816 static void rtl8192_start_beacon(struct net_device
*dev
)
3818 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
3819 struct ieee80211_network
*net
= &priv
->ieee80211
->current_network
;
3824 DMESG("Enabling beacon TX");
3825 //rtl8192_prepare_beacon(dev);
3826 rtl8192_irq_disable(dev
);
3827 //rtl8192_beacon_tx_enable(dev);
3830 write_nic_word(dev
, ATIMWND
, 2);
3832 /* Beacon interval (in unit of TU) */
3833 write_nic_word(dev
, BCN_INTERVAL
, net
->beacon_interval
);
3836 * DrvErlyInt (in unit of TU).
3837 * (Time to send interrupt to notify driver to c
3838 * hange beacon content)
3840 write_nic_word(dev
, BCN_DRV_EARLY_INT
, 10);
3843 * BcnDMATIM(in unit of us).
3844 * Indicates the time before TBTT to perform beacon queue DMA
3846 write_nic_word(dev
, BCN_DMATIME
, 256);
3849 * Force beacon frame transmission even after receiving
3850 * beacon frame from other ad hoc STA
3852 write_nic_byte(dev
, BCN_ERR_THRESH
, 100);
3854 /* Set CW and IFS */
3855 BcnTimeCfg
|= BcnCW
<<BCN_TCFG_CW_SHIFT
;
3856 BcnTimeCfg
|= BcnIFS
<<BCN_TCFG_IFS
;
3857 write_nic_word(dev
, BCN_TCFG
, BcnTimeCfg
);
3860 /* enable the interrupt for ad-hoc process */
3861 rtl8192_irq_enable(dev
);
3863 /***************************************************************************
3864 -------------------------------NET STUFF---------------------------
3865 ***************************************************************************/
3869 static bool HalTxCheckStuck8190Pci(struct net_device
*dev
)
3871 u16 RegTxCounter
= read_nic_word(dev
, 0x128);
3872 struct r8192_priv
*priv
= ieee80211_priv(dev
);
3873 bool bStuck
= FALSE
;
3874 RT_TRACE(COMP_RESET
,"%s():RegTxCounter is %d,TxCounter is %d\n",__FUNCTION__
,RegTxCounter
,priv
->TxCounter
);
3875 if(priv
->TxCounter
==RegTxCounter
)
3878 priv
->TxCounter
= RegTxCounter
;
3884 * <Assumption: RT_TX_SPINLOCK is acquired.>
3885 * First added: 2006.11.19 by emily
3888 TxCheckStuck(struct net_device
*dev
)
3890 struct r8192_priv
*priv
= ieee80211_priv(dev
);
3892 ptx_ring head
=NULL
,tail
=NULL
,txring
= NULL
;
3893 u8 ResetThreshold
= NIC_SEND_HANG_THRESHOLD_POWERSAVE
;
3894 bool bCheckFwTxCnt
= false;
3895 //unsigned long flags;
3898 // Decide Stuch threshold according to current power save mode
3900 //printk("++++++++++++>%s()\n",__FUNCTION__);
3901 switch (priv
->ieee80211
->dot11PowerSaveMode
)
3903 // The threshold value may required to be adjusted .
3904 case eActive
: // Active/Continuous access.
3905 ResetThreshold
= NIC_SEND_HANG_THRESHOLD_NORMAL
;
3907 case eMaxPs
: // Max power save mode.
3908 ResetThreshold
= NIC_SEND_HANG_THRESHOLD_POWERSAVE
;
3910 case eFastPs
: // Fast power save mode.
3911 ResetThreshold
= NIC_SEND_HANG_THRESHOLD_POWERSAVE
;
3916 // Check whether specific tcb has been queued for a specific time
3918 for(QueueID
= 0; QueueID
< MAX_TX_QUEUE
; QueueID
++)
3922 if(QueueID
== TXCMD_QUEUE
)
3927 tail
=priv
->txmapringtail
;
3928 head
=priv
->txmapringhead
;
3932 tail
=priv
->txbkpringtail
;
3933 head
=priv
->txbkpringhead
;
3937 tail
=priv
->txbepringtail
;
3938 head
=priv
->txbepringhead
;
3942 tail
=priv
->txvipringtail
;
3943 head
=priv
->txvipringhead
;
3947 tail
=priv
->txvopringtail
;
3948 head
=priv
->txvopringhead
;
3963 RT_TRACE(COMP_ERR
,"%s():txring is NULL , BUG!\n",__FUNCTION__
);
3966 txring
->nStuckCount
++;
3967 bCheckFwTxCnt
= TRUE
;
3973 if(HalTxCheckStuck8190Pci(dev
))
3975 RT_TRACE(COMP_RESET
, "TxCheckStuck(): Fw indicates no Tx condition! \n");
3976 return RESET_TYPE_SILENT
;
3980 return RESET_TYPE_NORESET
;
3984 static bool HalRxCheckStuck8190Pci(struct net_device
*dev
)
3986 struct r8192_priv
*priv
= ieee80211_priv(dev
);
3987 u16 RegRxCounter
= read_nic_word(dev
, 0x130);
3988 bool bStuck
= FALSE
;
3989 static u8 rx_chk_cnt
= 0;
3990 RT_TRACE(COMP_RESET
,"%s(): RegRxCounter is %d,RxCounter is %d\n",__FUNCTION__
,RegRxCounter
,priv
->RxCounter
);
3991 // If rssi is small, we should check rx for long time because of bad rx.
3992 // or maybe it will continuous silent reset every 2 seconds.
3994 if(priv
->undecorated_smoothed_pwdb
>= (RateAdaptiveTH_High
+5))
3996 rx_chk_cnt
= 0; //high rssi, check rx stuck right now.
3998 else if(priv
->undecorated_smoothed_pwdb
< (RateAdaptiveTH_High
+5) &&
3999 ((priv
->CurrentChannelBW
!=HT_CHANNEL_WIDTH_20
&&priv
->undecorated_smoothed_pwdb
>=RateAdaptiveTH_Low_40M
) ||
4000 (priv
->CurrentChannelBW
==HT_CHANNEL_WIDTH_20
&&priv
->undecorated_smoothed_pwdb
>=RateAdaptiveTH_Low_20M
)) )
4012 else if(((priv
->CurrentChannelBW
!=HT_CHANNEL_WIDTH_20
&&priv
->undecorated_smoothed_pwdb
<RateAdaptiveTH_Low_40M
) ||
4013 (priv
->CurrentChannelBW
==HT_CHANNEL_WIDTH_20
&&priv
->undecorated_smoothed_pwdb
<RateAdaptiveTH_Low_20M
)) &&
4014 priv
->undecorated_smoothed_pwdb
>= VeryLowRSSI
)
4018 //DbgPrint("RSSI < %d && RSSI >= %d, no check this time \n", RateAdaptiveTH_Low, VeryLowRSSI);
4024 //DbgPrint("RSSI < %d && RSSI >= %d, check this time \n", RateAdaptiveTH_Low, VeryLowRSSI);
4031 //DbgPrint("RSSI <= %d, no check this time \n", VeryLowRSSI);
4037 //DbgPrint("RSSI <= %d, check this time \n", VeryLowRSSI);
4040 if(priv
->RxCounter
==RegRxCounter
)
4043 priv
->RxCounter
= RegRxCounter
;
4048 static RESET_TYPE
RxCheckStuck(struct net_device
*dev
)
4051 if(HalRxCheckStuck8190Pci(dev
))
4053 RT_TRACE(COMP_RESET
, "RxStuck Condition\n");
4054 return RESET_TYPE_SILENT
;
4057 return RESET_TYPE_NORESET
;
4061 rtl819x_ifcheck_resetornot(struct net_device
*dev
)
4063 struct r8192_priv
*priv
= ieee80211_priv(dev
);
4064 RESET_TYPE TxResetType
= RESET_TYPE_NORESET
;
4065 RESET_TYPE RxResetType
= RESET_TYPE_NORESET
;
4066 RT_RF_POWER_STATE rfState
;
4068 rfState
= priv
->ieee80211
->eRFPowerState
;
4070 TxResetType
= TxCheckStuck(dev
);
4072 if( rfState
!= eRfOff
&&
4073 /*ADAPTER_TEST_STATUS_FLAG(Adapter, ADAPTER_STATUS_FW_DOWNLOAD_FAILURE)) &&*/
4074 (priv
->ieee80211
->iw_mode
!= IW_MODE_ADHOC
))
4076 // If driver is in the status of firmware download failure , driver skips RF initialization and RF is
4077 // in turned off state. Driver should check whether Rx stuck and do silent reset. And
4078 // if driver is in firmware download failure status, driver should initialize RF in the following
4079 // silent reset procedure Emily, 2008.01.21
4081 // Driver should not check RX stuck in IBSS mode because it is required to
4082 // set Check BSSID in order to send beacon, however, if check BSSID is
4083 // set, STA cannot hear any packet a all. Emily, 2008.04.12
4084 RxResetType
= RxCheckStuck(dev
);
4088 RT_TRACE(COMP_RESET
,"%s(): TxResetType is %d, RxResetType is %d\n",__FUNCTION__
,TxResetType
,RxResetType
);
4089 if(TxResetType
==RESET_TYPE_NORMAL
|| RxResetType
==RESET_TYPE_NORMAL
)
4090 return RESET_TYPE_NORMAL
;
4091 else if(TxResetType
==RESET_TYPE_SILENT
|| RxResetType
==RESET_TYPE_SILENT
)
4092 return RESET_TYPE_SILENT
;
4094 return RESET_TYPE_NORESET
;
4099 static void CamRestoreAllEntry(struct net_device
*dev
)
4102 struct r8192_priv
*priv
= ieee80211_priv(dev
);
4103 const u8
* MacAddr
= priv
->ieee80211
->current_network
.bssid
;
4105 static const u8 CAM_CONST_ADDR
[4][6] = {
4106 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
4107 {0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
4108 {0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
4109 {0x00, 0x00, 0x00, 0x00, 0x00, 0x03}};
4110 static const u8 CAM_CONST_BROAD
[] =
4111 {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
4113 RT_TRACE(COMP_SEC
, "CamRestoreAllEntry: \n");
4116 if ((priv
->ieee80211
->pairwise_key_type
== KEY_TYPE_WEP40
)||
4117 (priv
->ieee80211
->pairwise_key_type
== KEY_TYPE_WEP104
))
4120 for(EntryId
=0; EntryId
<4; EntryId
++)
4123 MacAddr
= CAM_CONST_ADDR
[EntryId
];
4127 priv
->ieee80211
->pairwise_key_type
,
4135 else if(priv
->ieee80211
->pairwise_key_type
== KEY_TYPE_TKIP
)
4139 if(priv
->ieee80211
->iw_mode
== IW_MODE_ADHOC
)
4143 priv
->ieee80211
->pairwise_key_type
,
4151 priv
->ieee80211
->pairwise_key_type
,
4157 else if(priv
->ieee80211
->pairwise_key_type
== KEY_TYPE_CCMP
)
4161 if(priv
->ieee80211
->iw_mode
== IW_MODE_ADHOC
)
4165 priv
->ieee80211
->pairwise_key_type
,
4173 priv
->ieee80211
->pairwise_key_type
,
4182 if(priv
->ieee80211
->group_key_type
== KEY_TYPE_TKIP
)
4184 MacAddr
= CAM_CONST_BROAD
;
4185 for(EntryId
=1 ; EntryId
<4 ; EntryId
++)
4191 priv
->ieee80211
->group_key_type
,
4197 if(priv
->ieee80211
->iw_mode
== IW_MODE_ADHOC
)
4201 priv
->ieee80211
->group_key_type
,
4206 else if(priv
->ieee80211
->group_key_type
== KEY_TYPE_CCMP
)
4208 MacAddr
= CAM_CONST_BROAD
;
4209 for(EntryId
=1; EntryId
<4 ; EntryId
++)
4215 priv
->ieee80211
->group_key_type
,
4222 if(priv
->ieee80211
->iw_mode
== IW_MODE_ADHOC
)
4226 priv
->ieee80211
->group_key_type
,
4233 void rtl8192_cancel_deferred_work(struct r8192_priv
* priv
);
4234 int _rtl8192_up(struct net_device
*dev
);
4237 * This function is used to fix Tx/Rx stop bug temporarily.
4238 * This function will do "system reset" to NIC when Tx or Rx is stuck.
4239 * The method checking Tx/Rx stuck of this function is supported by FW,
4240 * which reports Tx and Rx counter to register 0x128 and 0x130.
4242 static void rtl819x_ifsilentreset(struct net_device
*dev
)
4244 struct r8192_priv
*priv
= ieee80211_priv(dev
);
4246 int reset_status
= 0;
4247 struct ieee80211_device
*ieee
= priv
->ieee80211
;
4252 // 2007.07.20. If we need to check CCK stop, please uncomment this line.
4253 //bStuck = Adapter->HalFunc.CheckHWStopHandler(Adapter);
4255 if(priv
->ResetProgress
==RESET_TYPE_NORESET
)
4259 //LZM for PS-Poll AID issue. 090429
4260 if(priv
->ieee80211
->state
== IEEE80211_LINKED
)
4261 LeisurePSLeave(dev
);
4264 RT_TRACE(COMP_RESET
,"=========>Reset progress!! \n");
4266 // Set the variable for reset.
4267 priv
->ResetProgress
= RESET_TYPE_SILENT
;
4268 // rtl8192_close(dev);
4270 down(&priv
->wx_sem
);
4273 RT_TRACE(COMP_ERR
,"%s():the driver is not up! return\n",__FUNCTION__
);
4278 RT_TRACE(COMP_RESET
,"%s():======>start to down the driver\n",__FUNCTION__
);
4279 if(!netif_queue_stopped(dev
))
4280 netif_stop_queue(dev
);
4282 dm_backup_dynamic_mechanism_state(dev
);
4284 rtl8192_irq_disable(dev
);
4285 rtl8192_cancel_deferred_work(priv
);
4287 del_timer_sync(&priv
->watch_dog_timer
);
4288 ieee
->sync_scan_hurryup
= 1;
4289 if(ieee
->state
== IEEE80211_LINKED
)
4291 down(&ieee
->wx_sem
);
4292 printk("ieee->state is IEEE80211_LINKED\n");
4293 ieee80211_stop_send_beacons(priv
->ieee80211
);
4294 del_timer_sync(&ieee
->associate_timer
);
4295 cancel_delayed_work(&ieee
->associate_retry_wq
);
4296 ieee80211_stop_scan(ieee
);
4300 printk("ieee->state is NOT LINKED\n");
4301 ieee80211_softmac_stop_protocol(priv
->ieee80211
,true);
4303 rtl8192_halt_adapter(dev
, true);
4305 RT_TRACE(COMP_RESET
,"%s():<==========down process is finished\n",__FUNCTION__
);
4306 RT_TRACE(COMP_RESET
,"%s():===========>start to up the driver\n",__FUNCTION__
);
4307 reset_status
= _rtl8192_up(dev
);
4309 RT_TRACE(COMP_RESET
,"%s():<===========up process is finished\n",__FUNCTION__
);
4310 if(reset_status
== -1)
4319 RT_TRACE(COMP_ERR
," ERR!!! %s(): Reset Failed!!\n",__FUNCTION__
);
4323 ieee
->is_silent_reset
= 1;
4325 EnableHWSecurityConfig8192(dev
);
4327 if(ieee
->state
== IEEE80211_LINKED
&& ieee
->iw_mode
== IW_MODE_INFRA
)
4329 ieee
->set_chan(ieee
->dev
, ieee
->current_network
.channel
);
4332 queue_work(ieee
->wq
, &ieee
->associate_complete_wq
);
4336 else if(ieee
->state
== IEEE80211_LINKED
&& ieee
->iw_mode
== IW_MODE_ADHOC
)
4338 ieee
->set_chan(ieee
->dev
, ieee
->current_network
.channel
);
4339 ieee
->link_change(ieee
->dev
);
4341 // notify_wx_assoc_event(ieee);
4343 ieee80211_start_send_beacons(ieee
);
4345 if (ieee
->data_hard_resume
)
4346 ieee
->data_hard_resume(ieee
->dev
);
4347 netif_carrier_on(ieee
->dev
);
4351 CamRestoreAllEntry(dev
);
4353 // Restore the previous setting for all dynamic mechanism
4354 dm_restore_dynamic_mechanism_state(dev
);
4356 priv
->ResetProgress
= RESET_TYPE_NORESET
;
4357 priv
->reset_count
++;
4359 priv
->bForcedSilentReset
=false;
4360 priv
->bResetInProgress
= false;
4362 // For test --> force write UFWP.
4363 write_nic_byte(dev
, UFWP
, 1);
4364 RT_TRACE(COMP_RESET
, "Reset finished!! ====>[%d]\n", priv
->reset_count
);
4370 void InactivePsWorkItemCallback(struct net_device
*dev
)
4372 struct r8192_priv
*priv
= ieee80211_priv(dev
);
4373 PRT_POWER_SAVE_CONTROL pPSC
= (PRT_POWER_SAVE_CONTROL
)(&(priv
->ieee80211
->PowerSaveControl
));
4376 RT_TRACE(COMP_POWER
, "InactivePsWorkItemCallback() ---------> \n");
4378 // This flag "bSwRfProcessing", indicates the status of IPS procedure, should be set if the IPS workitem
4379 // is really scheduled.
4380 // The old code, sets this flag before scheduling the IPS workitem and however, at the same time the
4381 // previous IPS workitem did not end yet, fails to schedule the current workitem. Thus, bSwRfProcessing
4382 // blocks the IPS procedure of switching RF.
4383 // By Bruce, 2007-12-25.
4385 pPSC
->bSwRfProcessing
= TRUE
;
4387 RT_TRACE(COMP_RF
, "InactivePsWorkItemCallback(): Set RF to %s.\n",
4388 pPSC
->eInactivePowerState
== eRfOff
?"OFF":"ON");
4391 MgntActSet_RF_State(dev
, pPSC
->eInactivePowerState
, RF_CHANGE_BY_IPS
);
4394 // To solve CAM values miss in RF OFF, rewrite CAM values after RF ON. By Bruce, 2007-09-20.
4396 pPSC
->bSwRfProcessing
= FALSE
;
4397 RT_TRACE(COMP_POWER
, "InactivePsWorkItemCallback() <--------- \n");
4402 // Change current and default preamble mode.
4403 // 2005.01.06, by rcnjko.
4405 bool MgntActSet_802_11_PowerSaveMode(struct net_device
*dev
, u8 rtPsMode
)
4407 struct r8192_priv
*priv
= ieee80211_priv(dev
);
4408 //PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->ieee80211->PowerSaveControl));
4409 //u8 RpwmVal, FwPwrMode;
4411 // Currently, we do not change power save mode on IBSS mode.
4412 if(priv
->ieee80211
->iw_mode
== IW_MODE_ADHOC
)
4418 // <RJ_NOTE> If we make HW to fill up the PwrMgt bit for us,
4419 // some AP will not response to our mgnt frames with PwrMgt bit set,
4420 // e.g. cannot associate the AP.
4421 // So I commented out it. 2005.02.16, by rcnjko.
4423 // // Change device's power save mode.
4424 // Adapter->HalFunc.SetPSModeHandler( Adapter, rtPsMode );
4426 // Update power save mode configured.
4427 //RT_TRACE(COMP_LPS,"%s(): set ieee->ps = %x\n",__FUNCTION__,rtPsMode);
4428 if(!priv
->ps_force
) {
4429 priv
->ieee80211
->ps
= rtPsMode
;
4432 // Awake immediately
4433 if(priv
->ieee80211
->sta_sleep
!= 0 && rtPsMode
== IEEE80211_PS_DISABLED
)
4435 unsigned long flags
;
4437 //PlatformSetTimer(Adapter, &(pMgntInfo->AwakeTimer), 0);
4438 // Notify the AP we awke.
4439 rtl8192_hw_wakeup(dev
);
4440 priv
->ieee80211
->sta_sleep
= 0;
4442 spin_lock_irqsave(&(priv
->ieee80211
->mgmt_tx_lock
), flags
);
4443 printk("LPS leave: notify AP we are awaked ++++++++++ SendNullFunctionData\n");
4444 ieee80211_sta_ps_send_null_frame(priv
->ieee80211
, 0);
4445 spin_unlock_irqrestore(&(priv
->ieee80211
->mgmt_tx_lock
), flags
);
4451 //================================================================================
4452 // Leisure Power Save in linked state.
4453 //================================================================================
4457 // Enter the leisure power save mode.
4459 void LeisurePSEnter(struct net_device
*dev
)
4461 struct r8192_priv
*priv
= ieee80211_priv(dev
);
4462 PRT_POWER_SAVE_CONTROL pPSC
= (PRT_POWER_SAVE_CONTROL
)(&(priv
->ieee80211
->PowerSaveControl
));
4464 //RT_TRACE(COMP_PS, "LeisurePSEnter()...\n");
4465 //RT_TRACE(COMP_PS, "pPSC->bLeisurePs = %d, ieee->ps = %d,pPSC->LpsIdleCount is %d,RT_CHECK_FOR_HANG_PERIOD is %d\n",
4466 // pPSC->bLeisurePs, priv->ieee80211->ps,pPSC->LpsIdleCount,RT_CHECK_FOR_HANG_PERIOD);
4468 if(!((priv
->ieee80211
->iw_mode
== IW_MODE_INFRA
) &&
4469 (priv
->ieee80211
->state
== IEEE80211_LINKED
)) ||
4470 (priv
->ieee80211
->iw_mode
== IW_MODE_ADHOC
) ||
4471 (priv
->ieee80211
->iw_mode
== IW_MODE_MASTER
))
4474 if (pPSC
->bLeisurePs
)
4476 // Idle for a while if we connect to AP a while ago.
4477 if(pPSC
->LpsIdleCount
>= RT_CHECK_FOR_HANG_PERIOD
) // 4 Sec
4480 if(priv
->ieee80211
->ps
== IEEE80211_PS_DISABLED
)
4483 //RT_TRACE(COMP_LPS, "LeisurePSEnter(): Enter 802.11 power save mode...\n");
4484 MgntActSet_802_11_PowerSaveMode(dev
, IEEE80211_PS_MBCAST
|IEEE80211_PS_UNICAST
);
4489 pPSC
->LpsIdleCount
++;
4496 // Leave the leisure power save mode.
4498 void LeisurePSLeave(struct net_device
*dev
)
4500 struct r8192_priv
*priv
= ieee80211_priv(dev
);
4501 PRT_POWER_SAVE_CONTROL pPSC
= (PRT_POWER_SAVE_CONTROL
)(&(priv
->ieee80211
->PowerSaveControl
));
4504 //RT_TRACE(COMP_PS, "LeisurePSLeave()...\n");
4505 //RT_TRACE(COMP_PS, "pPSC->bLeisurePs = %d, ieee->ps = %d\n",
4506 // pPSC->bLeisurePs, priv->ieee80211->ps);
4508 if (pPSC
->bLeisurePs
)
4510 if(priv
->ieee80211
->ps
!= IEEE80211_PS_DISABLED
)
4512 // move to lps_wakecomplete()
4513 //RT_TRACE(COMP_LPS, "LeisurePSLeave(): Busy Traffic , Leave 802.11 power save..\n");
4514 MgntActSet_802_11_PowerSaveMode(dev
, IEEE80211_PS_DISABLED
);
4524 // Enter the inactive power save mode. RF will be off
4525 // 2007.08.17, by shien chang.
4528 IPSEnter(struct net_device
*dev
)
4530 struct r8192_priv
*priv
= ieee80211_priv(dev
);
4531 PRT_POWER_SAVE_CONTROL pPSC
= (PRT_POWER_SAVE_CONTROL
)(&(priv
->ieee80211
->PowerSaveControl
));
4532 RT_RF_POWER_STATE rtState
;
4534 if (pPSC
->bInactivePs
)
4536 rtState
= priv
->ieee80211
->eRFPowerState
;
4538 // Added by Bruce, 2007-12-25.
4539 // Do not enter IPS in the following conditions:
4540 // (1) RF is already OFF or Sleep
4541 // (2) bSwRfProcessing (indicates the IPS is still under going)
4542 // (3) Connectted (only disconnected can trigger IPS)
4543 // (4) IBSS (send Beacon)
4544 // (5) AP mode (send Beacon)
4546 if (rtState
== eRfOn
&& !pPSC
->bSwRfProcessing
4547 && (priv
->ieee80211
->state
!= IEEE80211_LINKED
) )
4549 RT_TRACE(COMP_RF
,"IPSEnter(): Turn off RF.\n");
4550 //printk("IPSEnter(): Turn off RF.\n");
4551 pPSC
->eInactivePowerState
= eRfOff
;
4552 // queue_work(priv->priv_wq,&(pPSC->InactivePsWorkItem));
4553 InactivePsWorkItemCallback(dev
);
4560 // Leave the inactive power save mode, RF will be on.
4561 // 2007.08.17, by shien chang.
4564 IPSLeave(struct net_device
*dev
)
4566 struct r8192_priv
*priv
= ieee80211_priv(dev
);
4567 PRT_POWER_SAVE_CONTROL pPSC
= (PRT_POWER_SAVE_CONTROL
)(&(priv
->ieee80211
->PowerSaveControl
));
4568 RT_RF_POWER_STATE rtState
;
4570 if (pPSC
->bInactivePs
)
4572 rtState
= priv
->ieee80211
->eRFPowerState
;
4573 if (rtState
!= eRfOn
&& !pPSC
->bSwRfProcessing
&& priv
->ieee80211
->RfOffReason
<= RF_CHANGE_BY_IPS
)
4575 RT_TRACE(COMP_POWER
, "IPSLeave(): Turn on RF.\n");
4576 //printk("IPSLeave(): Turn on RF.\n");
4577 pPSC
->eInactivePowerState
= eRfOn
;
4578 // queue_work(priv->priv_wq,&(pPSC->InactivePsWorkItem));
4579 InactivePsWorkItemCallback(dev
);
4584 void IPSLeave_wq(void *data
)
4586 struct ieee80211_device
*ieee
= container_of(data
,struct ieee80211_device
,ips_leave_wq
);
4587 struct net_device
*dev
= ieee
->dev
;
4589 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
4590 down(&priv
->ieee80211
->ips_sem
);
4592 up(&priv
->ieee80211
->ips_sem
);
4595 void ieee80211_ips_leave_wq(struct net_device
*dev
)
4597 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
4598 RT_RF_POWER_STATE rtState
;
4599 rtState
= priv
->ieee80211
->eRFPowerState
;
4601 if(priv
->ieee80211
->PowerSaveControl
.bInactivePs
){
4602 if(rtState
== eRfOff
){
4603 if(priv
->ieee80211
->RfOffReason
> RF_CHANGE_BY_IPS
)
4605 RT_TRACE(COMP_ERR
, "%s(): RF is OFF.\n",__FUNCTION__
);
4609 printk("=========>%s(): IPSLeave\n",__FUNCTION__
);
4610 queue_work(priv
->ieee80211
->wq
,&priv
->ieee80211
->ips_leave_wq
);
4615 //added by amy 090331 end
4616 void ieee80211_ips_leave(struct net_device
*dev
)
4618 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
4619 down(&priv
->ieee80211
->ips_sem
);
4621 up(&priv
->ieee80211
->ips_sem
);
4625 static void rtl819x_update_rxcounts(
4626 struct r8192_priv
*priv
,
4635 *TotalRxDataNum
= 0;
4637 SlotIndex
= (priv
->ieee80211
->LinkDetectInfo
.SlotIndex
++)%(priv
->ieee80211
->LinkDetectInfo
.SlotNum
);
4638 priv
->ieee80211
->LinkDetectInfo
.RxBcnNum
[SlotIndex
] = priv
->ieee80211
->LinkDetectInfo
.NumRecvBcnInPeriod
;
4639 priv
->ieee80211
->LinkDetectInfo
.RxDataNum
[SlotIndex
] = priv
->ieee80211
->LinkDetectInfo
.NumRecvDataInPeriod
;
4640 for( i
=0; i
<priv
->ieee80211
->LinkDetectInfo
.SlotNum
; i
++ ){
4641 *TotalRxBcnNum
+= priv
->ieee80211
->LinkDetectInfo
.RxBcnNum
[i
];
4642 *TotalRxDataNum
+= priv
->ieee80211
->LinkDetectInfo
.RxDataNum
[i
];
4647 static void rtl819x_watchdog_wqcallback(struct work_struct
*work
)
4649 struct delayed_work
*dwork
= container_of(work
,struct delayed_work
,work
);
4650 struct r8192_priv
*priv
= container_of(dwork
,struct r8192_priv
,watch_dog_wq
);
4651 struct net_device
*dev
= priv
->ieee80211
->dev
;
4652 struct ieee80211_device
* ieee
= priv
->ieee80211
;
4653 RESET_TYPE ResetType
= RESET_TYPE_NORESET
;
4654 static u8 check_reset_cnt
=0;
4655 unsigned long flags
;
4656 bool bBusyTraffic
= false;
4657 static u8 last_time
= 0;
4658 bool bEnterPS
= false;
4660 if((!priv
->up
) || (priv
->bHwRadioOff
== true))
4665 hal_dm_watchdog(dev
);
4667 // printk("watch_dog ENABLE_IPS\n");
4668 if(ieee
->actscanning
== false){
4669 //printk("%d,%d,%d,%d\n", ieee->eRFPowerState, ieee->is_set_key, ieee->proto_stoppping, ieee->wx_set_enc);
4670 if((ieee
->iw_mode
== IW_MODE_INFRA
) && (ieee
->state
== IEEE80211_NOLINK
) &&
4671 (ieee
->eRFPowerState
== eRfOn
)&&!ieee
->is_set_key
&&
4672 (!ieee
->proto_stoppping
) && !ieee
->wx_set_enc
){
4673 if(ieee
->PowerSaveControl
.ReturnPoint
== IPS_CALLBACK_NONE
){
4674 //printk("====================>haha:IPSEnter()\n");
4676 //ieee80211_stop_scan(priv->ieee80211);
4681 {//to get busy traffic condition
4682 if(ieee
->state
== IEEE80211_LINKED
)
4684 if( ieee
->LinkDetectInfo
.NumRxOkInPeriod
> 100 ||
4685 ieee
->LinkDetectInfo
.NumTxOkInPeriod
> 100 ) {
4686 bBusyTraffic
= true;
4690 //added by amy for Leisure PS
4691 if( ((ieee
->LinkDetectInfo
.NumRxUnicastOkInPeriod
+ ieee
->LinkDetectInfo
.NumTxOkInPeriod
) > 8 ) ||
4692 (ieee
->LinkDetectInfo
.NumRxUnicastOkInPeriod
> 2) )
4694 //printk("ieee->LinkDetectInfo.NumRxUnicastOkInPeriod is %d,ieee->LinkDetectInfo.NumTxOkInPeriod is %d\n",
4695 // ieee->LinkDetectInfo.NumRxUnicastOkInPeriod,ieee->LinkDetectInfo.NumTxOkInPeriod);
4703 //printk("***bEnterPS = %d\n", bEnterPS);
4704 // LeisurePS only work in infra mode.
4707 LeisurePSEnter(dev
);
4711 LeisurePSLeave(dev
);
4719 //RT_TRACE(COMP_LPS,"====>no link LPS leave\n");
4720 LeisurePSLeave(dev
);
4724 ieee
->LinkDetectInfo
.NumRxOkInPeriod
= 0;
4725 ieee
->LinkDetectInfo
.NumTxOkInPeriod
= 0;
4726 ieee
->LinkDetectInfo
.NumRxUnicastOkInPeriod
= 0;
4727 ieee
->LinkDetectInfo
.bBusyTraffic
= bBusyTraffic
;
4731 //added by amy for AP roaming
4734 if(ieee
->state
== IEEE80211_LINKED
&& ieee
->iw_mode
== IW_MODE_INFRA
)
4736 u32 TotalRxBcnNum
= 0;
4737 u32 TotalRxDataNum
= 0;
4739 rtl819x_update_rxcounts(priv
, &TotalRxBcnNum
, &TotalRxDataNum
);
4740 if((TotalRxBcnNum
+TotalRxDataNum
) == 0)
4742 if( ieee
->eRFPowerState
== eRfOff
)
4743 RT_TRACE(COMP_ERR
,"========>%s()\n",__FUNCTION__
);
4744 printk("===>%s(): AP is power off,connect another one\n",__FUNCTION__
);
4745 // Dot11d_Reset(dev);
4746 ieee
->state
= IEEE80211_ASSOCIATING
;
4747 notify_wx_assoc_event(priv
->ieee80211
);
4748 RemovePeerTS(priv
->ieee80211
,priv
->ieee80211
->current_network
.bssid
);
4749 ieee
->is_roaming
= true;
4750 ieee
->is_set_key
= false;
4751 ieee
->link_change(dev
);
4752 queue_work(ieee
->wq
, &ieee
->associate_procedure_wq
);
4755 ieee
->LinkDetectInfo
.NumRecvBcnInPeriod
=0;
4756 ieee
->LinkDetectInfo
.NumRecvDataInPeriod
=0;
4759 //check if reset the driver
4760 spin_lock_irqsave(&priv
->tx_lock
,flags
);
4761 if(check_reset_cnt
++ >= 3 && !ieee
->is_roaming
&& (last_time
!= 1))
4763 ResetType
= rtl819x_ifcheck_resetornot(dev
);
4764 check_reset_cnt
= 3;
4765 //DbgPrint("Start to check silent reset\n");
4767 spin_unlock_irqrestore(&priv
->tx_lock
,flags
);
4768 if(!priv
->bDisableNormalResetCheck
&& ResetType
== RESET_TYPE_NORMAL
)
4770 priv
->ResetProgress
= RESET_TYPE_NORMAL
;
4771 RT_TRACE(COMP_RESET
,"%s(): NOMAL RESET\n",__FUNCTION__
);
4774 /* disable silent reset temply 2008.9.11*/
4776 if( ((priv
->force_reset
) || (!priv
->bDisableNormalResetCheck
&& ResetType
==RESET_TYPE_SILENT
))) // This is control by OID set in Pomelo
4779 rtl819x_ifsilentreset(dev
);
4784 priv
->force_reset
= false;
4785 priv
->bForcedSilentReset
= false;
4786 priv
->bResetInProgress
= false;
4787 RT_TRACE(COMP_TRACE
, " <==RtUsbCheckForHangWorkItemCallback()\n");
4791 void watch_dog_timer_callback(unsigned long data
)
4793 struct r8192_priv
*priv
= ieee80211_priv((struct net_device
*) data
);
4794 queue_delayed_work(priv
->priv_wq
,&priv
->watch_dog_wq
,0);
4795 mod_timer(&priv
->watch_dog_timer
, jiffies
+ MSECS(IEEE80211_WATCH_DOG_TIME
));
4798 int _rtl8192_up(struct net_device
*dev
)
4800 struct r8192_priv
*priv
= ieee80211_priv(dev
);
4802 RT_STATUS init_status
= RT_STATUS_SUCCESS
;
4804 priv
->ieee80211
->ieee_up
=1;
4805 priv
->bdisable_nic
= false; //YJ,add,091111
4806 RT_TRACE(COMP_INIT
, "Bringing up iface");
4808 init_status
= rtl8192_adapter_start(dev
);
4809 if(init_status
!= RT_STATUS_SUCCESS
)
4811 RT_TRACE(COMP_ERR
,"ERR!!! %s(): initialization is failed!\n",__FUNCTION__
);
4814 RT_TRACE(COMP_INIT
, "start adapter finished\n");
4816 if(priv
->ieee80211
->eRFPowerState
!=eRfOn
)
4817 MgntActSet_RF_State(dev
, eRfOn
, priv
->ieee80211
->RfOffReason
);
4819 if(priv
->ieee80211
->state
!= IEEE80211_LINKED
)
4820 ieee80211_softmac_start_protocol(priv
->ieee80211
);
4821 ieee80211_reset_queue(priv
->ieee80211
);
4822 watch_dog_timer_callback((unsigned long) dev
);
4823 if(!netif_queue_stopped(dev
))
4824 netif_start_queue(dev
);
4826 netif_wake_queue(dev
);
4832 static int rtl8192_open(struct net_device
*dev
)
4834 struct r8192_priv
*priv
= ieee80211_priv(dev
);
4837 down(&priv
->wx_sem
);
4838 ret
= rtl8192_up(dev
);
4845 int rtl8192_up(struct net_device
*dev
)
4847 struct r8192_priv
*priv
= ieee80211_priv(dev
);
4849 if (priv
->up
== 1) return -1;
4851 return _rtl8192_up(dev
);
4855 static int rtl8192_close(struct net_device
*dev
)
4857 struct r8192_priv
*priv
= ieee80211_priv(dev
);
4860 down(&priv
->wx_sem
);
4862 ret
= rtl8192_down(dev
);
4870 int rtl8192_down(struct net_device
*dev
)
4872 struct r8192_priv
*priv
= ieee80211_priv(dev
);
4878 if (priv
->up
== 0) return -1;
4881 //LZM for PS-Poll AID issue. 090429
4882 if(priv
->ieee80211
->state
== IEEE80211_LINKED
)
4883 LeisurePSLeave(dev
);
4887 priv
->ieee80211
->ieee_up
= 0;
4888 RT_TRACE(COMP_DOWN
, "==========>%s()\n", __FUNCTION__
);
4890 if (!netif_queue_stopped(dev
))
4891 netif_stop_queue(dev
);
4893 rtl8192_irq_disable(dev
);
4895 if(!priv
->ieee80211
->bSupportRemoteWakeUp
) {
4896 MgntActSet_RF_State(dev
, eRfOff
, RF_CHANGE_BY_INIT
);
4897 // 2006.11.30. System reset bit
4898 ulRegRead
= read_nic_dword(dev
, CPU_GEN
);
4899 ulRegRead
|=CPU_GEN_SYSTEM_RESET
;
4900 write_nic_dword(dev
, CPU_GEN
, ulRegRead
);
4902 //2008.06.03 for WOL
4903 write_nic_dword(dev
, WFCRC0
, 0xffffffff);
4904 write_nic_dword(dev
, WFCRC1
, 0xffffffff);
4905 write_nic_dword(dev
, WFCRC2
, 0xffffffff);
4908 ucRegRead
= read_nic_byte(dev
, GPO
);
4910 write_nic_byte(dev
, GPO
, ucRegRead
);
4912 //Write PMR register
4913 write_nic_byte(dev
, PMR
, 0x5);
4914 //Disable tx, enanble rx
4915 write_nic_byte(dev
, MacBlkCtrl
, 0xa);
4918 // flush_scheduled_work();
4919 rtl8192_cancel_deferred_work(priv
);
4921 del_timer_sync(&priv
->watch_dog_timer
);
4923 ieee80211_softmac_stop_protocol(priv
->ieee80211
,true);
4925 rtl8192_halt_adapter(dev
,false);
4926 memset(&priv
->ieee80211
->current_network
, 0 , offsetof(struct ieee80211_network
, list
));
4928 RT_TRACE(COMP_DOWN
, "<==========%s()\n", __FUNCTION__
);
4934 void rtl8192_commit(struct net_device
*dev
)
4936 struct r8192_priv
*priv
= ieee80211_priv(dev
);
4938 if (priv
->up
== 0) return ;
4941 ieee80211_softmac_stop_protocol(priv
->ieee80211
,true);
4943 rtl8192_irq_disable(dev
);
4944 rtl8192_halt_adapter(dev
,true);
4948 void rtl8192_restart(struct work_struct
*work
)
4950 struct r8192_priv
*priv
= container_of(work
, struct r8192_priv
, reset_wq
);
4951 struct net_device
*dev
= priv
->ieee80211
->dev
;
4953 down(&priv
->wx_sem
);
4955 rtl8192_commit(dev
);
4960 static void r8192_set_multicast(struct net_device
*dev
)
4962 struct r8192_priv
*priv
= ieee80211_priv(dev
);
4965 //down(&priv->wx_sem);
4969 promisc
= (dev
->flags
& IFF_PROMISC
) ? 1:0;
4971 if (promisc
!= priv
->promisc
) {
4973 // rtl8192_commit(dev);
4976 priv
->promisc
= promisc
;
4978 //schedule_work(&priv->reset_wq);
4979 //up(&priv->wx_sem);
4983 static int r8192_set_mac_adr(struct net_device
*dev
, void *mac
)
4985 struct r8192_priv
*priv
= ieee80211_priv(dev
);
4986 struct sockaddr
*addr
= mac
;
4988 down(&priv
->wx_sem
);
4990 memcpy(dev
->dev_addr
, addr
->sa_data
, ETH_ALEN
);
4992 schedule_work(&priv
->reset_wq
);
4998 /* based on ipw2200 driver */
4999 static int rtl8192_ioctl(struct net_device
*dev
, struct ifreq
*rq
, int cmd
)
5001 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
5002 struct iwreq
*wrq
= (struct iwreq
*)rq
;
5004 struct ieee80211_device
*ieee
= priv
->ieee80211
;
5006 u8 broadcast_addr
[6] = {0xff,0xff,0xff,0xff,0xff,0xff};
5007 struct iw_point
*p
= &wrq
->u
.data
;
5008 struct ieee_param
*ipw
= NULL
;//(struct ieee_param *)wrq->u.data.pointer;
5010 down(&priv
->wx_sem
);
5013 if (p
->length
< sizeof(struct ieee_param
) || !p
->pointer
){
5018 ipw
= kmalloc(p
->length
, GFP_KERNEL
);
5023 if (copy_from_user(ipw
, p
->pointer
, p
->length
)) {
5030 case RTL_IOCTL_WPA_SUPPLICANT
:
5031 //parse here for HW security
5032 if (ipw
->cmd
== IEEE_CMD_SET_ENCRYPTION
)
5034 if (ipw
->u
.crypt
.set_tx
)
5036 if (strcmp(ipw
->u
.crypt
.alg
, "CCMP") == 0)
5037 ieee
->pairwise_key_type
= KEY_TYPE_CCMP
;
5038 else if (strcmp(ipw
->u
.crypt
.alg
, "TKIP") == 0)
5039 ieee
->pairwise_key_type
= KEY_TYPE_TKIP
;
5040 else if (strcmp(ipw
->u
.crypt
.alg
, "WEP") == 0)
5042 if (ipw
->u
.crypt
.key_len
== 13)
5043 ieee
->pairwise_key_type
= KEY_TYPE_WEP104
;
5044 else if (ipw
->u
.crypt
.key_len
== 5)
5045 ieee
->pairwise_key_type
= KEY_TYPE_WEP40
;
5048 ieee
->pairwise_key_type
= KEY_TYPE_NA
;
5050 if (ieee
->pairwise_key_type
)
5052 memcpy((u8
*)key
, ipw
->u
.crypt
.key
, 16);
5053 EnableHWSecurityConfig8192(dev
);
5054 //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!
5056 setKey(dev
, 4, ipw
->u
.crypt
.idx
, ieee
->pairwise_key_type
, (u8
*)ieee
->ap_mac_addr
, 0, key
);
5057 if (ieee
->auth_mode
!= 2) //LEAP WEP will never set this.
5058 setKey(dev
, ipw
->u
.crypt
.idx
, ipw
->u
.crypt
.idx
, ieee
->pairwise_key_type
, (u8
*)ieee
->ap_mac_addr
, 0, key
);
5060 if ((ieee
->pairwise_key_type
== KEY_TYPE_CCMP
) && ieee
->pHTInfo
->bCurrentHTSupport
){
5061 write_nic_byte(dev
, 0x173, 1); //fix aes bug
5065 else //if (ipw->u.crypt.idx) //group key use idx > 0
5067 memcpy((u8
*)key
, ipw
->u
.crypt
.key
, 16);
5068 if (strcmp(ipw
->u
.crypt
.alg
, "CCMP") == 0)
5069 ieee
->group_key_type
= KEY_TYPE_CCMP
;
5070 else if (strcmp(ipw
->u
.crypt
.alg
, "TKIP") == 0)
5071 ieee
->group_key_type
= KEY_TYPE_TKIP
;
5072 else if (strcmp(ipw
->u
.crypt
.alg
, "WEP") == 0)
5074 if (ipw
->u
.crypt
.key_len
== 13)
5075 ieee
->group_key_type
= KEY_TYPE_WEP104
;
5076 else if (ipw
->u
.crypt
.key_len
== 5)
5077 ieee
->group_key_type
= KEY_TYPE_WEP40
;
5080 ieee
->group_key_type
= KEY_TYPE_NA
;
5082 if (ieee
->group_key_type
)
5086 ipw
->u
.crypt
.idx
, //KeyIndex
5087 ieee
->group_key_type
, //KeyType
5088 broadcast_addr
, //MacAddr
5098 printk("@@ wrq->u pointer = ");
5099 for(i
=0;i
<wrq
->u
.data
.length
;i
++){
5100 if(i
%10==0) printk("\n");
5101 printk( "%8x|", ((u32
*)wrq
->u
.data
.pointer
)[i
] );
5105 #endif /*JOHN_DEBUG*/
5106 ret
= ieee80211_wpa_supplicant_ioctl(priv
->ieee80211
, &wrq
->u
.data
);
5121 static u8
HwRateToMRate90(bool bIsHT
, u8 rate
)
5127 case DESC90_RATE1M
: ret_rate
= MGN_1M
; break;
5128 case DESC90_RATE2M
: ret_rate
= MGN_2M
; break;
5129 case DESC90_RATE5_5M
: ret_rate
= MGN_5_5M
; break;
5130 case DESC90_RATE11M
: ret_rate
= MGN_11M
; break;
5131 case DESC90_RATE6M
: ret_rate
= MGN_6M
; break;
5132 case DESC90_RATE9M
: ret_rate
= MGN_9M
; break;
5133 case DESC90_RATE12M
: ret_rate
= MGN_12M
; break;
5134 case DESC90_RATE18M
: ret_rate
= MGN_18M
; break;
5135 case DESC90_RATE24M
: ret_rate
= MGN_24M
; break;
5136 case DESC90_RATE36M
: ret_rate
= MGN_36M
; break;
5137 case DESC90_RATE48M
: ret_rate
= MGN_48M
; break;
5138 case DESC90_RATE54M
: ret_rate
= MGN_54M
; break;
5141 RT_TRACE(COMP_RECV
, "HwRateToMRate90(): Non supported Rate [%x], bIsHT = %d!!!\n", rate
, bIsHT
);
5147 case DESC90_RATEMCS0
: ret_rate
= MGN_MCS0
; break;
5148 case DESC90_RATEMCS1
: ret_rate
= MGN_MCS1
; break;
5149 case DESC90_RATEMCS2
: ret_rate
= MGN_MCS2
; break;
5150 case DESC90_RATEMCS3
: ret_rate
= MGN_MCS3
; break;
5151 case DESC90_RATEMCS4
: ret_rate
= MGN_MCS4
; break;
5152 case DESC90_RATEMCS5
: ret_rate
= MGN_MCS5
; break;
5153 case DESC90_RATEMCS6
: ret_rate
= MGN_MCS6
; break;
5154 case DESC90_RATEMCS7
: ret_rate
= MGN_MCS7
; break;
5155 case DESC90_RATEMCS8
: ret_rate
= MGN_MCS8
; break;
5156 case DESC90_RATEMCS9
: ret_rate
= MGN_MCS9
; break;
5157 case DESC90_RATEMCS10
: ret_rate
= MGN_MCS10
; break;
5158 case DESC90_RATEMCS11
: ret_rate
= MGN_MCS11
; break;
5159 case DESC90_RATEMCS12
: ret_rate
= MGN_MCS12
; break;
5160 case DESC90_RATEMCS13
: ret_rate
= MGN_MCS13
; break;
5161 case DESC90_RATEMCS14
: ret_rate
= MGN_MCS14
; break;
5162 case DESC90_RATEMCS15
: ret_rate
= MGN_MCS15
; break;
5163 case DESC90_RATEMCS32
: ret_rate
= (0x80|0x20); break;
5166 RT_TRACE(COMP_RECV
, "HwRateToMRate90(): Non supported Rate [%x], bIsHT = %d!!!\n",rate
, bIsHT
);
5175 * Function: UpdateRxPktTimeStamp
5176 * Overview: Recored down the TSF time stamp when receiving a packet
5184 * (pRfd->Status.TimeStampHigh is updated)
5185 * (pRfd->Status.TimeStampLow is updated)
5189 static void UpdateRxPktTimeStamp8190 (struct net_device
*dev
, struct ieee80211_rx_stats
*stats
)
5191 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
5193 if(stats
->bIsAMPDU
&& !stats
->bFirstMPDU
) {
5194 stats
->mac_time
[0] = priv
->LastRxDescTSFLow
;
5195 stats
->mac_time
[1] = priv
->LastRxDescTSFHigh
;
5197 priv
->LastRxDescTSFLow
= stats
->mac_time
[0];
5198 priv
->LastRxDescTSFHigh
= stats
->mac_time
[1];
5202 static long rtl819x_translate_todbm(u8 signal_strength_index
)// 0-100 index.
5204 long signal_power
; // in dBm.
5206 // Translate to dBm (x=0.5y-95).
5207 signal_power
= (long)((signal_strength_index
+ 1) >> 1);
5210 return signal_power
;
5215 // Update Rx signal related information in the packet reeived
5216 // to RxStats. User application can query RxStats to realize
5217 // current Rx signal status.
5220 // In normal operation, user only care about the information of the BSS
5221 // and we shall invoke this function if the packet received is from the BSS.
5224 rtl819x_update_rxsignalstatistics8190pci(
5225 struct r8192_priv
* priv
,
5226 struct ieee80211_rx_stats
* pprevious_stats
5231 //2 <ToDo> Update Rx Statistics (such as signal strength and signal quality).
5234 if(priv
->stats
.recv_signal_power
== 0)
5235 priv
->stats
.recv_signal_power
= pprevious_stats
->RecvSignalPower
;
5237 // To avoid the past result restricting the statistics sensitivity, weight the current power (5/6) to speed up the
5238 // reaction of smoothed Signal Power.
5239 if(pprevious_stats
->RecvSignalPower
> priv
->stats
.recv_signal_power
)
5241 else if(pprevious_stats
->RecvSignalPower
< priv
->stats
.recv_signal_power
)
5244 // We need more correct power of received packets and the "SignalStrength" of RxStats have been beautified or translated,
5245 // so we record the correct power in Dbm here. By Bruce, 2008-03-07.
5247 priv
->stats
.recv_signal_power
= (priv
->stats
.recv_signal_power
* 5 + pprevious_stats
->RecvSignalPower
+ weighting
) / 6;
5251 rtl8190_process_cck_rxpathsel(
5252 struct r8192_priv
* priv
,
5253 struct ieee80211_rx_stats
* pprevious_stats
5256 #ifdef RTL8190P //Only 90P 2T4R need to check
5257 char last_cck_adc_pwdb
[4]={0,0,0,0};
5259 //cosa add for Rx path selection
5260 if(priv
->rf_type
== RF_2T4R
&& DM_RxPathSelTable
.Enable
)
5262 if(pprevious_stats
->bIsCCK
&&
5263 (pprevious_stats
->bPacketToSelf
||pprevious_stats
->bPacketBeacon
))
5265 /* record the cck adc_pwdb to the sliding window. */
5266 if(priv
->stats
.cck_adc_pwdb
.TotalNum
++ >= PHY_RSSI_SLID_WIN_MAX
)
5268 priv
->stats
.cck_adc_pwdb
.TotalNum
= PHY_RSSI_SLID_WIN_MAX
;
5269 for(i
=RF90_PATH_A
; i
<RF90_PATH_MAX
; i
++)
5271 last_cck_adc_pwdb
[i
] = priv
->stats
.cck_adc_pwdb
.elements
[i
][priv
->stats
.cck_adc_pwdb
.index
];
5272 priv
->stats
.cck_adc_pwdb
.TotalVal
[i
] -= last_cck_adc_pwdb
[i
];
5275 for(i
=RF90_PATH_A
; i
<RF90_PATH_MAX
; i
++)
5277 priv
->stats
.cck_adc_pwdb
.TotalVal
[i
] += pprevious_stats
->cck_adc_pwdb
[i
];
5278 priv
->stats
.cck_adc_pwdb
.elements
[i
][priv
->stats
.cck_adc_pwdb
.index
] = pprevious_stats
->cck_adc_pwdb
[i
];
5280 priv
->stats
.cck_adc_pwdb
.index
++;
5281 if(priv
->stats
.cck_adc_pwdb
.index
>= PHY_RSSI_SLID_WIN_MAX
)
5282 priv
->stats
.cck_adc_pwdb
.index
= 0;
5284 for(i
=RF90_PATH_A
; i
<RF90_PATH_MAX
; i
++)
5286 DM_RxPathSelTable
.cck_pwdb_sta
[i
] = priv
->stats
.cck_adc_pwdb
.TotalVal
[i
]/priv
->stats
.cck_adc_pwdb
.TotalNum
;
5289 for(i
=RF90_PATH_A
; i
<RF90_PATH_MAX
; i
++)
5291 if(pprevious_stats
->cck_adc_pwdb
[i
] > (char)priv
->undecorated_smoothed_cck_adc_pwdb
[i
])
5293 priv
->undecorated_smoothed_cck_adc_pwdb
[i
] =
5294 ( (priv
->undecorated_smoothed_cck_adc_pwdb
[i
]*(Rx_Smooth_Factor
-1)) +
5295 (pprevious_stats
->cck_adc_pwdb
[i
])) /(Rx_Smooth_Factor
);
5296 priv
->undecorated_smoothed_cck_adc_pwdb
[i
] = priv
->undecorated_smoothed_cck_adc_pwdb
[i
] + 1;
5300 priv
->undecorated_smoothed_cck_adc_pwdb
[i
] =
5301 ( (priv
->undecorated_smoothed_cck_adc_pwdb
[i
]*(Rx_Smooth_Factor
-1)) +
5302 (pprevious_stats
->cck_adc_pwdb
[i
])) /(Rx_Smooth_Factor
);
5311 /* 2008/01/22 MH We can not delcare RSSI/EVM total value of sliding window to
5312 be a local static. Otherwise, it may increase when we return from S3/S4. The
5313 value will be kept in memory or disk. We must delcare the value in adapter
5314 and it will be reinitialized when return from S3/S4. */
5315 static void rtl8192_process_phyinfo(struct r8192_priv
* priv
, u8
* buffer
,struct ieee80211_rx_stats
* pprevious_stats
, struct ieee80211_rx_stats
* pcurrent_stats
)
5317 bool bcheck
= false;
5319 u32 nspatial_stream
, tmp_val
;
5321 static u32 slide_rssi_index
=0, slide_rssi_statistics
=0;
5322 static u32 slide_evm_index
=0, slide_evm_statistics
=0;
5323 static u32 last_rssi
=0, last_evm
=0;
5324 //cosa add for rx path selection
5325 // static long slide_cck_adc_pwdb_index=0, slide_cck_adc_pwdb_statistics=0;
5326 // static char last_cck_adc_pwdb[4]={0,0,0,0};
5327 //cosa add for beacon rssi smoothing
5328 static u32 slide_beacon_adc_pwdb_index
=0, slide_beacon_adc_pwdb_statistics
=0;
5329 static u32 last_beacon_adc_pwdb
=0;
5331 struct ieee80211_hdr_3addr
*hdr
;
5333 unsigned int frag
,seq
;
5334 hdr
= (struct ieee80211_hdr_3addr
*)buffer
;
5335 sc
= le16_to_cpu(hdr
->seq_ctl
);
5336 frag
= WLAN_GET_SEQ_FRAG(sc
);
5337 seq
= WLAN_GET_SEQ_SEQ(sc
);
5338 //cosa add 04292008 to record the sequence number
5339 pcurrent_stats
->Seq_Num
= seq
;
5341 // Check whether we should take the previous packet into accounting
5343 if(!pprevious_stats
->bIsAMPDU
)
5345 // if previous packet is not aggregated packet
5349 //remve for that we don't use AMPDU to calculate PWDB,because the reported PWDB of some AP is fault.
5351 // if previous packet is aggregated packet, and current packet
5353 // (2) is the first packet of one AMPDU
5354 // that means the previous packet is the last one aggregated packet
5355 if( !pcurrent_stats
->bIsAMPDU
|| pcurrent_stats
->bFirstMPDU
)
5360 if(slide_rssi_statistics
++ >= PHY_RSSI_SLID_WIN_MAX
)
5362 slide_rssi_statistics
= PHY_RSSI_SLID_WIN_MAX
;
5363 last_rssi
= priv
->stats
.slide_signal_strength
[slide_rssi_index
];
5364 priv
->stats
.slide_rssi_total
-= last_rssi
;
5366 priv
->stats
.slide_rssi_total
+= pprevious_stats
->SignalStrength
;
5368 priv
->stats
.slide_signal_strength
[slide_rssi_index
++] = pprevious_stats
->SignalStrength
;
5369 if(slide_rssi_index
>= PHY_RSSI_SLID_WIN_MAX
)
5370 slide_rssi_index
= 0;
5372 // <1> Showed on UI for user, in dbm
5373 tmp_val
= priv
->stats
.slide_rssi_total
/slide_rssi_statistics
;
5374 priv
->stats
.signal_strength
= rtl819x_translate_todbm((u8
)tmp_val
);
5375 pcurrent_stats
->rssi
= priv
->stats
.signal_strength
;
5377 // If the previous packet does not match the criteria, neglect it
5379 if(!pprevious_stats
->bPacketMatchBSSID
)
5381 if(!pprevious_stats
->bToSelfBA
)
5388 rtl8190_process_cck_rxpathsel(priv
,pprevious_stats
);
5393 priv
->stats
.num_process_phyinfo
++;
5395 /* record the general signal strength to the sliding window. */
5396 if(slide_rssi_statistics
++ >= PHY_RSSI_SLID_WIN_MAX
)
5398 slide_rssi_statistics
= PHY_RSSI_SLID_WIN_MAX
;
5399 last_rssi
= priv
->stats
.slide_signal_strength
[slide_rssi_index
];
5400 priv
->stats
.slide_rssi_total
-= last_rssi
;
5402 priv
->stats
.slide_rssi_total
+= pprevious_stats
->SignalStrength
;
5404 priv
->stats
.slide_signal_strength
[slide_rssi_index
++] = pprevious_stats
->SignalStrength
;
5405 if(slide_rssi_index
>= PHY_RSSI_SLID_WIN_MAX
)
5406 slide_rssi_index
= 0;
5408 // <1> Showed on UI for user, in dbm
5409 tmp_val
= priv
->stats
.slide_rssi_total
/slide_rssi_statistics
;
5410 priv
->stats
.signal_strength
= rtl819x_translate_todbm((u8
)tmp_val
);
5413 // <2> Showed on UI for engineering
5414 // hardware does not provide rssi information for each rf path in CCK
5415 if(!pprevious_stats
->bIsCCK
&& pprevious_stats
->bPacketToSelf
)
5417 for (rfpath
= RF90_PATH_A
; rfpath
< RF90_PATH_C
; rfpath
++)
5419 if (!rtl8192_phy_CheckIsLegalRFPath(priv
->ieee80211
->dev
, rfpath
))
5421 RT_TRACE(COMP_DBG
,"Jacken -> pPreviousstats->RxMIMOSignalStrength[rfpath] = %d \n" ,pprevious_stats
->RxMIMOSignalStrength
[rfpath
] );
5422 //Fixed by Jacken 2008-03-20
5423 if(priv
->stats
.rx_rssi_percentage
[rfpath
] == 0)
5425 priv
->stats
.rx_rssi_percentage
[rfpath
] = pprevious_stats
->RxMIMOSignalStrength
[rfpath
];
5426 //DbgPrint("MIMO RSSI initialize \n");
5428 if(pprevious_stats
->RxMIMOSignalStrength
[rfpath
] > priv
->stats
.rx_rssi_percentage
[rfpath
])
5430 priv
->stats
.rx_rssi_percentage
[rfpath
] =
5431 ( (priv
->stats
.rx_rssi_percentage
[rfpath
]*(Rx_Smooth_Factor
-1)) +
5432 (pprevious_stats
->RxMIMOSignalStrength
[rfpath
])) /(Rx_Smooth_Factor
);
5433 priv
->stats
.rx_rssi_percentage
[rfpath
] = priv
->stats
.rx_rssi_percentage
[rfpath
] + 1;
5437 priv
->stats
.rx_rssi_percentage
[rfpath
] =
5438 ( (priv
->stats
.rx_rssi_percentage
[rfpath
]*(Rx_Smooth_Factor
-1)) +
5439 (pprevious_stats
->RxMIMOSignalStrength
[rfpath
])) /(Rx_Smooth_Factor
);
5441 RT_TRACE(COMP_DBG
,"Jacken -> priv->RxStats.RxRSSIPercentage[rfPath] = %d \n" ,priv
->stats
.rx_rssi_percentage
[rfpath
] );
5449 //cosa add for beacon rssi smoothing by average.
5450 if(pprevious_stats
->bPacketBeacon
)
5452 /* record the beacon pwdb to the sliding window. */
5453 if(slide_beacon_adc_pwdb_statistics
++ >= PHY_Beacon_RSSI_SLID_WIN_MAX
)
5455 slide_beacon_adc_pwdb_statistics
= PHY_Beacon_RSSI_SLID_WIN_MAX
;
5456 last_beacon_adc_pwdb
= priv
->stats
.Slide_Beacon_pwdb
[slide_beacon_adc_pwdb_index
];
5457 priv
->stats
.Slide_Beacon_Total
-= last_beacon_adc_pwdb
;
5458 //DbgPrint("slide_beacon_adc_pwdb_index = %d, last_beacon_adc_pwdb = %d, Adapter->RxStats.Slide_Beacon_Total = %d\n",
5459 // slide_beacon_adc_pwdb_index, last_beacon_adc_pwdb, Adapter->RxStats.Slide_Beacon_Total);
5461 priv
->stats
.Slide_Beacon_Total
+= pprevious_stats
->RxPWDBAll
;
5462 priv
->stats
.Slide_Beacon_pwdb
[slide_beacon_adc_pwdb_index
] = pprevious_stats
->RxPWDBAll
;
5463 //DbgPrint("slide_beacon_adc_pwdb_index = %d, pPreviousRfd->Status.RxPWDBAll = %d\n", slide_beacon_adc_pwdb_index, pPreviousRfd->Status.RxPWDBAll);
5464 slide_beacon_adc_pwdb_index
++;
5465 if(slide_beacon_adc_pwdb_index
>= PHY_Beacon_RSSI_SLID_WIN_MAX
)
5466 slide_beacon_adc_pwdb_index
= 0;
5467 pprevious_stats
->RxPWDBAll
= priv
->stats
.Slide_Beacon_Total
/slide_beacon_adc_pwdb_statistics
;
5468 if(pprevious_stats
->RxPWDBAll
>= 3)
5469 pprevious_stats
->RxPWDBAll
-= 3;
5472 RT_TRACE(COMP_RXDESC
, "Smooth %s PWDB = %d\n",
5473 pprevious_stats
->bIsCCK
? "CCK": "OFDM",
5474 pprevious_stats
->RxPWDBAll
);
5476 if(pprevious_stats
->bPacketToSelf
|| pprevious_stats
->bPacketBeacon
|| pprevious_stats
->bToSelfBA
)
5478 if(priv
->undecorated_smoothed_pwdb
< 0) // initialize
5480 priv
->undecorated_smoothed_pwdb
= pprevious_stats
->RxPWDBAll
;
5481 //DbgPrint("First pwdb initialize \n");
5484 if(pprevious_stats
->RxPWDBAll
> (u32
)priv
->undecorated_smoothed_pwdb
)
5486 priv
->undecorated_smoothed_pwdb
=
5487 ( ((priv
->undecorated_smoothed_pwdb
)*(Rx_Smooth_Factor
-1)) +
5488 (pprevious_stats
->RxPWDBAll
)) /(Rx_Smooth_Factor
);
5489 priv
->undecorated_smoothed_pwdb
= priv
->undecorated_smoothed_pwdb
+ 1;
5493 priv
->undecorated_smoothed_pwdb
=
5494 ( ((priv
->undecorated_smoothed_pwdb
)*(Rx_Smooth_Factor
-1)) +
5495 (pprevious_stats
->RxPWDBAll
)) /(Rx_Smooth_Factor
);
5498 //Fixed by Jacken 2008-03-20
5499 if(pPreviousRfd
->Status
.RxPWDBAll
> (u32
)pHalData
->UndecoratedSmoothedPWDB
)
5501 pHalData
->UndecoratedSmoothedPWDB
=
5502 ( ((pHalData
->UndecoratedSmoothedPWDB
)* 5) + (pPreviousRfd
->Status
.RxPWDBAll
)) / 6;
5503 pHalData
->UndecoratedSmoothedPWDB
= pHalData
->UndecoratedSmoothedPWDB
+ 1;
5507 pHalData
->UndecoratedSmoothedPWDB
=
5508 ( ((pHalData
->UndecoratedSmoothedPWDB
)* 5) + (pPreviousRfd
->Status
.RxPWDBAll
)) / 6;
5511 rtl819x_update_rxsignalstatistics8190pci(priv
,pprevious_stats
);
5517 /* record the general EVM to the sliding window. */
5518 if(pprevious_stats
->SignalQuality
== 0)
5523 if(pprevious_stats
->bPacketToSelf
|| pprevious_stats
->bPacketBeacon
|| pprevious_stats
->bToSelfBA
){
5524 if(slide_evm_statistics
++ >= PHY_RSSI_SLID_WIN_MAX
){
5525 slide_evm_statistics
= PHY_RSSI_SLID_WIN_MAX
;
5526 last_evm
= priv
->stats
.slide_evm
[slide_evm_index
];
5527 priv
->stats
.slide_evm_total
-= last_evm
;
5530 priv
->stats
.slide_evm_total
+= pprevious_stats
->SignalQuality
;
5532 priv
->stats
.slide_evm
[slide_evm_index
++] = pprevious_stats
->SignalQuality
;
5533 if(slide_evm_index
>= PHY_RSSI_SLID_WIN_MAX
)
5534 slide_evm_index
= 0;
5536 // <1> Showed on UI for user, in percentage.
5537 tmp_val
= priv
->stats
.slide_evm_total
/slide_evm_statistics
;
5538 priv
->stats
.signal_quality
= tmp_val
;
5539 //cosa add 10/11/2007, Showed on UI for user in Windows Vista, for Link quality.
5540 priv
->stats
.last_signal_strength_inpercent
= tmp_val
;
5543 // <2> Showed on UI for engineering
5544 if(pprevious_stats
->bPacketToSelf
|| pprevious_stats
->bPacketBeacon
|| pprevious_stats
->bToSelfBA
)
5546 for(nspatial_stream
= 0; nspatial_stream
<2 ; nspatial_stream
++) // 2 spatial stream
5548 if(pprevious_stats
->RxMIMOSignalQuality
[nspatial_stream
] != -1)
5550 if(priv
->stats
.rx_evm_percentage
[nspatial_stream
] == 0) // initialize
5552 priv
->stats
.rx_evm_percentage
[nspatial_stream
] = pprevious_stats
->RxMIMOSignalQuality
[nspatial_stream
];
5554 priv
->stats
.rx_evm_percentage
[nspatial_stream
] =
5555 ( (priv
->stats
.rx_evm_percentage
[nspatial_stream
]* (Rx_Smooth_Factor
-1)) +
5556 (pprevious_stats
->RxMIMOSignalQuality
[nspatial_stream
]* 1)) / (Rx_Smooth_Factor
);
5564 /*-----------------------------------------------------------------------------
5565 * Function: rtl819x_query_rxpwrpercentage()
5569 * Input: char antpower
5573 * Return: 0-100 percentage
5577 * 05/26/2008 amy Create Version 0 porting from windows code.
5579 *---------------------------------------------------------------------------*/
5580 static u8
rtl819x_query_rxpwrpercentage(
5584 if ((antpower
<= -100) || (antpower
>= 20))
5588 else if (antpower
>= 0)
5594 return (100+antpower
);
5597 } /* QueryRxPwrPercentage */
5600 rtl819x_evm_dbtopercentage(
5612 ret_val
= 0 - ret_val
;
5621 // We want good-looking for signal strength/quality
5622 // 2007/7/19 01:09, by cosa.
5624 static long rtl819x_signal_scale_mapping(long currsig
)
5628 // Step 1. Scale mapping.
5629 if(currsig
>= 61 && currsig
<= 100)
5631 retsig
= 90 + ((currsig
- 60) / 4);
5633 else if(currsig
>= 41 && currsig
<= 60)
5635 retsig
= 78 + ((currsig
- 40) / 2);
5637 else if(currsig
>= 31 && currsig
<= 40)
5639 retsig
= 66 + (currsig
- 30);
5641 else if(currsig
>= 21 && currsig
<= 30)
5643 retsig
= 54 + (currsig
- 20);
5645 else if(currsig
>= 5 && currsig
<= 20)
5647 retsig
= 42 + (((currsig
- 5) * 2) / 3);
5649 else if(currsig
== 4)
5653 else if(currsig
== 3)
5657 else if(currsig
== 2)
5661 else if(currsig
== 1)
5673 static void rtl8192_query_rxphystatus(
5674 struct r8192_priv
* priv
,
5675 struct ieee80211_rx_stats
* pstats
,
5676 prx_desc_819x_pci pdesc
,
5677 prx_fwinfo_819x_pci pdrvinfo
,
5678 struct ieee80211_rx_stats
* precord_stats
,
5679 bool bpacket_match_bssid
,
5680 bool bpacket_toself
,
5685 //PRT_RFD_STATUS pRtRfdStatus = &(pRfd->Status);
5686 phy_sts_ofdm_819xpci_t
* pofdm_buf
;
5687 phy_sts_cck_819xpci_t
* pcck_buf
;
5688 phy_ofdm_rx_status_rxsc_sgien_exintfflag
* prxsc
;
5690 u8 i
,max_spatial_stream
, tmp_rxsnr
, tmp_rxevm
, rxsc_sgien_exflg
;
5691 char rx_pwr
[4], rx_pwr_all
=0;
5692 //long rx_avg_pwr = 0;
5693 char rx_snrX
, rx_evmX
;
5695 u32 RSSI
, total_rssi
=0;//, total_evm=0;
5696 // long signal_strength_index = 0;
5700 /* 2007/07/04 MH For OFDM RSSI. For high power or not. */
5701 static u8 check_reg824
= 0;
5702 static u32 reg824_bit9
= 0;
5704 priv
->stats
.numqry_phystatus
++;
5706 is_cck_rate
= rx_hal_is_cck_rate(pdrvinfo
);
5708 // Record it for next packet processing
5709 memset(precord_stats
, 0, sizeof(struct ieee80211_rx_stats
));
5710 pstats
->bPacketMatchBSSID
= precord_stats
->bPacketMatchBSSID
= bpacket_match_bssid
;
5711 pstats
->bPacketToSelf
= precord_stats
->bPacketToSelf
= bpacket_toself
;
5712 pstats
->bIsCCK
= precord_stats
->bIsCCK
= is_cck_rate
;//RX_HAL_IS_CCK_RATE(pDrvInfo);
5713 pstats
->bPacketBeacon
= precord_stats
->bPacketBeacon
= bPacketBeacon
;
5714 pstats
->bToSelfBA
= precord_stats
->bToSelfBA
= bToSelfBA
;
5715 /*2007.08.30 requested by SD3 Jerry */
5716 if(check_reg824
== 0)
5718 reg824_bit9
= rtl8192_QueryBBReg(priv
->ieee80211
->dev
, rFPGA0_XA_HSSIParameter2
, 0x200);
5723 prxpkt
= (u8
*)pdrvinfo
;
5725 /* Move pointer to the 16th bytes. Phy status start address. */
5726 prxpkt
+= sizeof(rx_fwinfo_819x_pci
);
5728 /* Initial the cck and ofdm buffer pointer */
5729 pcck_buf
= (phy_sts_cck_819xpci_t
*)prxpkt
;
5730 pofdm_buf
= (phy_sts_ofdm_819xpci_t
*)prxpkt
;
5732 pstats
->RxMIMOSignalQuality
[0] = -1;
5733 pstats
->RxMIMOSignalQuality
[1] = -1;
5734 precord_stats
->RxMIMOSignalQuality
[0] = -1;
5735 precord_stats
->RxMIMOSignalQuality
[1] = -1;
5740 // (1)Hardware does not provide RSSI for CCK
5744 // (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive)
5746 u8 report
;//, cck_agc_rpt;
5749 char cck_adc_pwdb
[4];
5751 priv
->stats
.numqry_phystatusCCK
++;
5753 #ifdef RTL8190P //Only 90P 2T4R need to check
5754 if(priv
->rf_type
== RF_2T4R
&& DM_RxPathSelTable
.Enable
&& bpacket_match_bssid
)
5756 for(i
=RF90_PATH_A
; i
<RF90_PATH_MAX
; i
++)
5758 tmp_pwdb
= pcck_buf
->adc_pwdb_X
[i
];
5759 cck_adc_pwdb
[i
] = (char)tmp_pwdb
;
5760 cck_adc_pwdb
[i
] /= 2;
5761 pstats
->cck_adc_pwdb
[i
] = precord_stats
->cck_adc_pwdb
[i
] = cck_adc_pwdb
[i
];
5762 //DbgPrint("RF-%d tmp_pwdb = 0x%x, cck_adc_pwdb = %d", i, tmp_pwdb, cck_adc_pwdb[i]);
5769 report
= pcck_buf
->cck_agc_rpt
& 0xc0;
5773 //Fixed by Jacken from Bryant 2008-03-20
5774 //Original value is -38 , -26 , -14 , -2
5775 //Fixed value is -35 , -23 , -11 , 6
5777 rx_pwr_all
= -35 - (pcck_buf
->cck_agc_rpt
& 0x3e);
5780 rx_pwr_all
= -23 - (pcck_buf
->cck_agc_rpt
& 0x3e);
5783 rx_pwr_all
= -11 - (pcck_buf
->cck_agc_rpt
& 0x3e);
5786 rx_pwr_all
= 8 - (pcck_buf
->cck_agc_rpt
& 0x3e);
5792 report
= pcck_buf
->cck_agc_rpt
& 0x60;
5797 rx_pwr_all
= -35 - ((pcck_buf
->cck_agc_rpt
& 0x1f)<<1) ;
5800 rx_pwr_all
= -23 - ((pcck_buf
->cck_agc_rpt
& 0x1f)<<1);
5803 rx_pwr_all
= -11 - ((pcck_buf
->cck_agc_rpt
& 0x1f)<<1) ;
5806 rx_pwr_all
= -8 - ((pcck_buf
->cck_agc_rpt
& 0x1f)<<1) ;
5811 pwdb_all
= rtl819x_query_rxpwrpercentage(rx_pwr_all
);
5812 pstats
->RxPWDBAll
= precord_stats
->RxPWDBAll
= pwdb_all
;
5813 pstats
->RecvSignalPower
= rx_pwr_all
;
5816 // (3) Get Signal Quality (EVM)
5818 if(bpacket_match_bssid
)
5822 if(pstats
->RxPWDBAll
> 40)
5827 sq
= pcck_buf
->sq_rpt
;
5829 if(pcck_buf
->sq_rpt
> 64)
5831 else if (pcck_buf
->sq_rpt
< 20)
5834 sq
= ((64-sq
) * 100) / 44;
5836 pstats
->SignalQuality
= precord_stats
->SignalQuality
= sq
;
5837 pstats
->RxMIMOSignalQuality
[0] = precord_stats
->RxMIMOSignalQuality
[0] = sq
;
5838 pstats
->RxMIMOSignalQuality
[1] = precord_stats
->RxMIMOSignalQuality
[1] = -1;
5843 priv
->stats
.numqry_phystatusHT
++;
5845 // (1)Get RSSI for HT rate
5847 for(i
=RF90_PATH_A
; i
<RF90_PATH_MAX
; i
++)
5849 // 2008/01/30 MH we will judge RF RX path now.
5850 if (priv
->brfpath_rxenable
[i
])
5855 //Fixed by Jacken from Bryant 2008-03-20
5856 //Original value is 106
5857 #ifdef RTL8190P //Modify by Jacken 2008/03/31
5858 rx_pwr
[i
] = ((pofdm_buf
->trsw_gain_X
[i
]&0x3F)*2) - 106;
5860 rx_pwr
[i
] = ((pofdm_buf
->trsw_gain_X
[i
]&0x3F)*2) - 110;
5863 //Get Rx snr value in DB
5864 tmp_rxsnr
= pofdm_buf
->rxsnr_X
[i
];
5865 rx_snrX
= (char)(tmp_rxsnr
);
5867 priv
->stats
.rxSNRdB
[i
] = (long)rx_snrX
;
5869 /* Translate DBM to percentage. */
5870 RSSI
= rtl819x_query_rxpwrpercentage(rx_pwr
[i
]);
5871 if (priv
->brfpath_rxenable
[i
])
5874 /* Record Signal Strength for next packet */
5875 if(bpacket_match_bssid
)
5877 pstats
->RxMIMOSignalStrength
[i
] =(u8
) RSSI
;
5878 precord_stats
->RxMIMOSignalStrength
[i
] =(u8
) RSSI
;
5884 // (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive)
5886 //Fixed by Jacken from Bryant 2008-03-20
5887 //Original value is 106
5888 rx_pwr_all
= (((pofdm_buf
->pwdb_all
) >> 1 )& 0x7f) -106;
5889 pwdb_all
= rtl819x_query_rxpwrpercentage(rx_pwr_all
);
5891 pstats
->RxPWDBAll
= precord_stats
->RxPWDBAll
= pwdb_all
;
5892 pstats
->RxPower
= precord_stats
->RxPower
= rx_pwr_all
;
5893 pstats
->RecvSignalPower
= rx_pwr_all
;
5895 // (3)EVM of HT rate
5897 if(pdrvinfo
->RxHT
&& pdrvinfo
->RxRate
>=DESC90_RATEMCS8
&&
5898 pdrvinfo
->RxRate
<=DESC90_RATEMCS15
)
5899 max_spatial_stream
= 2; //both spatial stream make sense
5901 max_spatial_stream
= 1; //only spatial stream 1 makes sense
5903 for(i
=0; i
<max_spatial_stream
; i
++)
5905 tmp_rxevm
= pofdm_buf
->rxevm_X
[i
];
5906 rx_evmX
= (char)(tmp_rxevm
);
5908 // Do not use shift operation like "rx_evmX >>= 1" because the compilor of free build environment
5909 // fill most significant bit to "zero" when doing shifting operation which may change a negative
5910 // value to positive one, then the dbm value (which is supposed to be negative) is not correct anymore.
5913 evm
= rtl819x_evm_dbtopercentage(rx_evmX
);
5915 EVM
= SignalScaleMapping(EVM
);//make it good looking, from 0~100
5917 if(bpacket_match_bssid
)
5919 if(i
==0) // Fill value in RFD, Get the first spatial stream only
5920 pstats
->SignalQuality
= precord_stats
->SignalQuality
= (u8
)(evm
& 0xff);
5921 pstats
->RxMIMOSignalQuality
[i
] = precord_stats
->RxMIMOSignalQuality
[i
] = (u8
)(evm
& 0xff);
5926 /* record rx statistics for debug */
5927 rxsc_sgien_exflg
= pofdm_buf
->rxsc_sgien_exflg
;
5928 prxsc
= (phy_ofdm_rx_status_rxsc_sgien_exintfflag
*)&rxsc_sgien_exflg
;
5929 if(pdrvinfo
->BW
) //40M channel
5930 priv
->stats
.received_bwtype
[1+prxsc
->rxsc
]++;
5932 priv
->stats
.received_bwtype
[0]++;
5935 //UI BSS List signal strength(in percentage), make it good looking, from 0~100.
5936 //It is assigned to the BSS List in GetValueFromBeaconOrProbeRsp().
5939 pstats
->SignalStrength
= precord_stats
->SignalStrength
= (u8
)(rtl819x_signal_scale_mapping((long)pwdb_all
));//PWDB_ALL;
5944 //pRfd->Status.SignalStrength = pRecordRfd->Status.SignalStrength = (u1Byte)(SignalScaleMapping(total_rssi/=RF90_PATH_MAX));//(u1Byte)(total_rssi/=RF90_PATH_MAX);
5945 // We can judge RX path number now.
5947 pstats
->SignalStrength
= precord_stats
->SignalStrength
= (u8
)(rtl819x_signal_scale_mapping((long)(total_rssi
/=rf_rx_num
)));
5949 } /* QueryRxPhyStatus8190Pci */
5952 rtl8192_record_rxdesc_forlateruse(
5953 struct ieee80211_rx_stats
* psrc_stats
,
5954 struct ieee80211_rx_stats
* ptarget_stats
5957 ptarget_stats
->bIsAMPDU
= psrc_stats
->bIsAMPDU
;
5958 ptarget_stats
->bFirstMPDU
= psrc_stats
->bFirstMPDU
;
5959 //ptarget_stats->Seq_Num = psrc_stats->Seq_Num;
5964 static void TranslateRxSignalStuff819xpci(struct net_device
*dev
,
5965 struct sk_buff
*skb
,
5966 struct ieee80211_rx_stats
* pstats
,
5967 prx_desc_819x_pci pdesc
,
5968 prx_fwinfo_819x_pci pdrvinfo
)
5970 // TODO: We must only check packet for current MAC address. Not finish
5971 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
5972 bool bpacket_match_bssid
, bpacket_toself
;
5973 bool bPacketBeacon
=false, bToSelfBA
=false;
5974 static struct ieee80211_rx_stats previous_stats
;
5975 struct ieee80211_hdr_3addr
*hdr
;
5978 // Get Signal Quality for only RX data queue (but not command queue)
5983 /* Get MAC frame start address. */
5984 tmp_buf
= skb
->data
;
5986 hdr
= (struct ieee80211_hdr_3addr
*)tmp_buf
;
5987 fc
= le16_to_cpu(hdr
->frame_ctl
);
5988 type
= WLAN_FC_GET_TYPE(fc
);
5989 praddr
= hdr
->addr1
;
5991 /* Check if the received packet is acceptabe. */
5992 bpacket_match_bssid
= ((IEEE80211_FTYPE_CTL
!= type
) &&
5993 (eqMacAddr(priv
->ieee80211
->current_network
.bssid
, (fc
& IEEE80211_FCTL_TODS
)? hdr
->addr1
: (fc
& IEEE80211_FCTL_FROMDS
)? hdr
->addr2
: hdr
->addr3
))
5994 && (!pstats
->bHwError
) && (!pstats
->bCRC
)&& (!pstats
->bICV
));
5995 bpacket_toself
= bpacket_match_bssid
& (eqMacAddr(praddr
, priv
->ieee80211
->dev
->dev_addr
));
5997 if(WLAN_FC_GET_FRAMETYPE(fc
)== IEEE80211_STYPE_BEACON
)
5999 bPacketBeacon
= true;
6000 //DbgPrint("Beacon 2, MatchBSSID = %d, ToSelf = %d \n", bPacketMatchBSSID, bPacketToSelf);
6002 if(WLAN_FC_GET_FRAMETYPE(fc
) == IEEE80211_STYPE_BLOCKACK
)
6004 if((eqMacAddr(praddr
,dev
->dev_addr
)))
6006 //DbgPrint("BlockAck, MatchBSSID = %d, ToSelf = %d \n", bPacketMatchBSSID, bPacketToSelf);
6010 if(bpacket_match_bssid
)
6012 priv
->stats
.numpacket_matchbssid
++;
6015 priv
->stats
.numpacket_toself
++;
6018 // Process PHY information for previous packet (RSSI/PWDB/EVM)
6020 // Because phy information is contained in the last packet of AMPDU only, so driver
6021 // should process phy information of previous packet
6022 rtl8192_process_phyinfo(priv
, tmp_buf
,&previous_stats
, pstats
);
6023 rtl8192_query_rxphystatus(priv
, pstats
, pdesc
, pdrvinfo
, &previous_stats
, bpacket_match_bssid
,
6024 bpacket_toself
,bPacketBeacon
, bToSelfBA
);
6025 rtl8192_record_rxdesc_forlateruse(pstats
, &previous_stats
);
6030 static void rtl8192_tx_resume(struct net_device
*dev
)
6032 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
6033 struct ieee80211_device
*ieee
= priv
->ieee80211
;
6034 struct sk_buff
*skb
;
6037 for(queue_index
= BK_QUEUE
; queue_index
< TXCMD_QUEUE
;queue_index
++) {
6038 while((!skb_queue_empty(&ieee
->skb_waitQ
[queue_index
]))&&
6039 (priv
->ieee80211
->check_nic_enough_desc(dev
,queue_index
) > 0)) {
6040 /* 1. dequeue the packet from the wait queue */
6041 skb
= skb_dequeue(&ieee
->skb_waitQ
[queue_index
]);
6042 /* 2. tx the packet directly */
6043 ieee
->softmac_data_hard_start_xmit(skb
,dev
,0/* rate useless now*/);
6045 if(queue_index
!=MGNT_QUEUE
) {
6046 ieee
->stats
.tx_packets
++;
6047 ieee
->stats
.tx_bytes
+= skb
->len
;
6054 static void rtl8192_irq_tx_tasklet(struct r8192_priv
*priv
)
6056 rtl8192_tx_resume(priv
->ieee80211
->dev
);
6060 * Function: UpdateReceivedRateHistogramStatistics
6061 * Overview: Recored down the received data rate
6069 * (Adapter->RxStats.ReceivedRateHistogram[] is updated)
6073 static void UpdateReceivedRateHistogramStatistics8190(
6074 struct net_device
*dev
,
6075 struct ieee80211_rx_stats
* pstats
6078 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
6079 u32 rcvType
=1; //0: Total, 1:OK, 2:CRC, 3:ICV
6081 u32 preamble_guardinterval
; //1: short preamble/GI, 0: long preamble/GI
6083 /* 2007/03/09 MH We will not update rate of packet from rx cmd queue. */
6085 if (pRfd
->queue_id
== CMPK_RX_QUEUE_ID
)
6090 else if(pstats
->bICV
)
6093 if(pstats
->bShortPreamble
)
6094 preamble_guardinterval
= 1;// short
6096 preamble_guardinterval
= 0;// long
6098 switch(pstats
->rate
)
6103 case MGN_1M
: rateIndex
= 0; break;
6104 case MGN_2M
: rateIndex
= 1; break;
6105 case MGN_5_5M
: rateIndex
= 2; break;
6106 case MGN_11M
: rateIndex
= 3; break;
6110 case MGN_6M
: rateIndex
= 4; break;
6111 case MGN_9M
: rateIndex
= 5; break;
6112 case MGN_12M
: rateIndex
= 6; break;
6113 case MGN_18M
: rateIndex
= 7; break;
6114 case MGN_24M
: rateIndex
= 8; break;
6115 case MGN_36M
: rateIndex
= 9; break;
6116 case MGN_48M
: rateIndex
= 10; break;
6117 case MGN_54M
: rateIndex
= 11; break;
6119 // 11n High throughput rate
6121 case MGN_MCS0
: rateIndex
= 12; break;
6122 case MGN_MCS1
: rateIndex
= 13; break;
6123 case MGN_MCS2
: rateIndex
= 14; break;
6124 case MGN_MCS3
: rateIndex
= 15; break;
6125 case MGN_MCS4
: rateIndex
= 16; break;
6126 case MGN_MCS5
: rateIndex
= 17; break;
6127 case MGN_MCS6
: rateIndex
= 18; break;
6128 case MGN_MCS7
: rateIndex
= 19; break;
6129 case MGN_MCS8
: rateIndex
= 20; break;
6130 case MGN_MCS9
: rateIndex
= 21; break;
6131 case MGN_MCS10
: rateIndex
= 22; break;
6132 case MGN_MCS11
: rateIndex
= 23; break;
6133 case MGN_MCS12
: rateIndex
= 24; break;
6134 case MGN_MCS13
: rateIndex
= 25; break;
6135 case MGN_MCS14
: rateIndex
= 26; break;
6136 case MGN_MCS15
: rateIndex
= 27; break;
6137 default: rateIndex
= 28; break;
6139 priv
->stats
.received_preamble_GI
[preamble_guardinterval
][rateIndex
]++;
6140 priv
->stats
.received_rate_histogram
[0][rateIndex
]++; //total
6141 priv
->stats
.received_rate_histogram
[rcvType
][rateIndex
]++;
6144 static void rtl8192_rx(struct net_device
*dev
)
6146 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
6147 struct ieee80211_hdr_1addr
*ieee80211_hdr
= NULL
;
6148 bool unicast_packet
= false;
6149 struct ieee80211_rx_stats stats
= {
6153 .freq
= IEEE80211_24GHZ_BAND
,
6155 unsigned int count
= priv
->rxringcount
;
6157 stats
.nic_type
= NIC_8192E
;
6160 rx_desc_819x_pci
*pdesc
= &priv
->rx_ring
[priv
->rx_idx
];//rx descriptor
6161 struct sk_buff
*skb
= priv
->rx_buf
[priv
->rx_idx
];//rx pkt
6164 /* wait data to be filled by hardware */
6167 stats
.bICV
= pdesc
->ICV
;
6168 stats
.bCRC
= pdesc
->CRC32
;
6169 stats
.bHwError
= pdesc
->CRC32
| pdesc
->ICV
;
6171 stats
.Length
= pdesc
->Length
;
6172 if(stats
.Length
< 24)
6173 stats
.bHwError
|= 1;
6175 if(stats
.bHwError
) {
6176 stats
.bShift
= false;
6179 if (pdesc
->Length
<500)
6180 priv
->stats
.rxcrcerrmin
++;
6181 else if (pdesc
->Length
>1000)
6182 priv
->stats
.rxcrcerrmax
++;
6184 priv
->stats
.rxcrcerrmid
++;
6188 prx_fwinfo_819x_pci pDrvInfo
= NULL
;
6189 struct sk_buff
*new_skb
= dev_alloc_skb(priv
->rxbuffersize
);
6191 if (unlikely(!new_skb
)) {
6195 stats
.RxDrvInfoSize
= pdesc
->RxDrvInfoSize
;
6196 stats
.RxBufShift
= ((pdesc
->Shift
)&0x03);
6197 stats
.Decrypted
= !pdesc
->SWDec
;
6199 pci_dma_sync_single_for_cpu(priv
->pdev
,
6200 *((dma_addr_t
*)skb
->cb
),
6202 PCI_DMA_FROMDEVICE
);
6203 skb_put(skb
, pdesc
->Length
);
6204 pDrvInfo
= (rx_fwinfo_819x_pci
*)(skb
->data
+ stats
.RxBufShift
);
6205 skb_reserve(skb
, stats
.RxDrvInfoSize
+ stats
.RxBufShift
);
6207 stats
.rate
= HwRateToMRate90((bool)pDrvInfo
->RxHT
, (u8
)pDrvInfo
->RxRate
);
6208 stats
.bShortPreamble
= pDrvInfo
->SPLCP
;
6210 /* it is debug only. It should be disabled in released driver.
6211 * 2007.1.11 by Emily
6213 UpdateReceivedRateHistogramStatistics8190(dev
, &stats
);
6215 stats
.bIsAMPDU
= (pDrvInfo
->PartAggr
==1);
6216 stats
.bFirstMPDU
= (pDrvInfo
->PartAggr
==1) && (pDrvInfo
->FirstAGGR
==1);
6218 stats
.TimeStampLow
= pDrvInfo
->TSFL
;
6219 stats
.TimeStampHigh
= read_nic_dword(dev
, TSFR
+4);
6221 UpdateRxPktTimeStamp8190(dev
, &stats
);
6224 // Get Total offset of MPDU Frame Body
6226 if((stats
.RxBufShift
+ stats
.RxDrvInfoSize
) > 0)
6229 stats
.RxIs40MHzPacket
= pDrvInfo
->BW
;
6232 TranslateRxSignalStuff819xpci(dev
,skb
, &stats
, pdesc
, pDrvInfo
);
6235 if(pDrvInfo
->FirstAGGR
==1 || pDrvInfo
->PartAggr
== 1)
6236 RT_TRACE(COMP_RXDESC
, "pDrvInfo->FirstAGGR = %d, pDrvInfo->PartAggr = %d\n",
6237 pDrvInfo
->FirstAGGR
, pDrvInfo
->PartAggr
);
6238 skb_trim(skb
, skb
->len
- 4/*sCrcLng*/);
6239 /* rx packets statistics */
6240 ieee80211_hdr
= (struct ieee80211_hdr_1addr
*)skb
->data
;
6241 unicast_packet
= false;
6243 if(is_broadcast_ether_addr(ieee80211_hdr
->addr1
)) {
6245 }else if(is_multicast_ether_addr(ieee80211_hdr
->addr1
)){
6248 /* unicast packet */
6249 unicast_packet
= true;
6252 stats
.packetlength
= stats
.Length
-4;
6253 stats
.fraglength
= stats
.packetlength
;
6254 stats
.fragoffset
= 0;
6255 stats
.ntotalfrag
= 1;
6257 if(!ieee80211_rtl_rx(priv
->ieee80211
, skb
, &stats
)){
6258 dev_kfree_skb_any(skb
);
6261 if(unicast_packet
) {
6262 priv
->stats
.rxbytesunicast
+= skb
->len
;
6267 priv
->rx_buf
[priv
->rx_idx
] = skb
;
6268 *((dma_addr_t
*) skb
->cb
) = pci_map_single(priv
->pdev
, skb_tail_pointer(skb
), priv
->rxbuffersize
, PCI_DMA_FROMDEVICE
);
6273 pdesc
->BufferAddress
= cpu_to_le32(*((dma_addr_t
*)skb
->cb
));
6275 pdesc
->Length
= priv
->rxbuffersize
;
6276 if (priv
->rx_idx
== priv
->rxringcount
-1)
6278 priv
->rx_idx
= (priv
->rx_idx
+ 1) % priv
->rxringcount
;
6283 static void rtl8192_irq_rx_tasklet(struct r8192_priv
*priv
)
6285 rtl8192_rx(priv
->ieee80211
->dev
);
6287 write_nic_dword(priv
->ieee80211
->dev
, INTA_MASK
,read_nic_dword(priv
->ieee80211
->dev
, INTA_MASK
) | IMR_RDU
);
6290 static const struct net_device_ops rtl8192_netdev_ops
= {
6291 .ndo_open
= rtl8192_open
,
6292 .ndo_stop
= rtl8192_close
,
6293 /* .ndo_get_stats = rtl8192_stats, */
6294 .ndo_tx_timeout
= tx_timeout
,
6295 .ndo_do_ioctl
= rtl8192_ioctl
,
6296 .ndo_set_multicast_list
= r8192_set_multicast
,
6297 .ndo_set_mac_address
= r8192_set_mac_adr
,
6298 .ndo_start_xmit
= ieee80211_rtl_xmit
,
6301 /****************************************************************************
6302 ---------------------------- PCI_STUFF---------------------------
6303 *****************************************************************************/
6305 static int __devinit
rtl8192_pci_probe(struct pci_dev
*pdev
,
6306 const struct pci_device_id
*id
)
6308 unsigned long ioaddr
= 0;
6309 struct net_device
*dev
= NULL
;
6310 struct r8192_priv
*priv
= NULL
;
6314 #ifdef CONFIG_RTL8192_IO_MAP
6315 unsigned long pio_start
, pio_len
, pio_flags
;
6317 unsigned long pmem_start
, pmem_len
, pmem_flags
;
6318 #endif //end #ifdef RTL_IO_MAP
6320 RT_TRACE(COMP_INIT
,"Configuring chip resources");
6322 if( pci_enable_device (pdev
) ){
6323 RT_TRACE(COMP_ERR
,"Failed to enable PCI device");
6327 pci_set_master(pdev
);
6328 //pci_set_wmi(pdev);
6329 pci_set_dma_mask(pdev
, 0xffffff00ULL
);
6330 pci_set_consistent_dma_mask(pdev
,0xffffff00ULL
);
6331 dev
= alloc_ieee80211(sizeof(struct r8192_priv
));
6337 pci_set_drvdata(pdev
, dev
);
6338 SET_NETDEV_DEV(dev
, &pdev
->dev
);
6339 priv
= ieee80211_priv(dev
);
6340 priv
->ieee80211
= netdev_priv(dev
);
6342 if((pdev
->subsystem_vendor
== PCI_VENDOR_ID_DLINK
)&&(pdev
->subsystem_device
== 0x3304)){
6343 priv
->ieee80211
->bSupportRemoteWakeUp
= 1;
6346 priv
->ieee80211
->bSupportRemoteWakeUp
= 0;
6349 #ifdef CONFIG_RTL8192_IO_MAP
6351 pio_start
= (unsigned long)pci_resource_start (pdev
, 0);
6352 pio_len
= (unsigned long)pci_resource_len (pdev
, 0);
6353 pio_flags
= (unsigned long)pci_resource_flags (pdev
, 0);
6355 if (!(pio_flags
& IORESOURCE_IO
)) {
6356 RT_TRACE(COMP_ERR
,"region #0 not a PIO resource, aborting");
6360 //DMESG("IO space @ 0x%08lx", pio_start );
6361 if( ! request_region( pio_start
, pio_len
, RTL819xE_MODULE_NAME
) ){
6362 RT_TRACE(COMP_ERR
,"request_region failed!");
6367 dev
->base_addr
= ioaddr
; // device I/O address
6371 pmem_start
= pci_resource_start(pdev
, 1);
6372 pmem_len
= pci_resource_len(pdev
, 1);
6373 pmem_flags
= pci_resource_flags (pdev
, 1);
6375 if (!(pmem_flags
& IORESOURCE_MEM
)) {
6376 RT_TRACE(COMP_ERR
,"region #1 not a MMIO resource, aborting");
6380 //DMESG("Memory mapped space @ 0x%08lx ", pmem_start);
6381 if( ! request_mem_region(pmem_start
, pmem_len
, RTL819xE_MODULE_NAME
)) {
6382 RT_TRACE(COMP_ERR
,"request_mem_region failed!");
6387 ioaddr
= (unsigned long)ioremap_nocache( pmem_start
, pmem_len
);
6388 if( ioaddr
== (unsigned long)NULL
){
6389 RT_TRACE(COMP_ERR
,"ioremap failed!");
6390 // release_mem_region( pmem_start, pmem_len );
6394 dev
->mem_start
= ioaddr
; // shared mem start
6395 dev
->mem_end
= ioaddr
+ pci_resource_len(pdev
, 0); // shared mem end
6397 #endif //end #ifdef RTL_IO_MAP
6399 /* We disable the RETRY_TIMEOUT register (0x41) to keep
6400 * PCI Tx retries from interfering with C3 CPU state */
6401 pci_write_config_byte(pdev
, 0x41, 0x00);
6404 pci_read_config_byte(pdev
, 0x05, &unit
);
6405 pci_write_config_byte(pdev
, 0x05, unit
& (~0x04));
6407 dev
->irq
= pdev
->irq
;
6410 dev
->netdev_ops
= &rtl8192_netdev_ops
;
6412 dev
->open
= rtl8192_open
;
6413 dev
->stop
= rtl8192_close
;
6414 //dev->hard_start_xmit = rtl8192_8023_hard_start_xmit;
6415 dev
->tx_timeout
= tx_timeout
;
6416 //dev->wireless_handlers = &r8192_wx_handlers_def;
6417 dev
->do_ioctl
= rtl8192_ioctl
;
6418 dev
->set_multicast_list
= r8192_set_multicast
;
6419 dev
->set_mac_address
= r8192_set_mac_adr
;
6422 //DMESG("Oops: i'm coming\n");
6423 #if WIRELESS_EXT >= 12
6424 #if WIRELESS_EXT < 17
6425 dev
->get_wireless_stats
= r8192_get_wireless_stats
;
6427 dev
->wireless_handlers
= (struct iw_handler_def
*) &r8192_wx_handlers_def
;
6429 //dev->get_wireless_stats = r8192_get_wireless_stats;
6430 dev
->type
=ARPHRD_ETHER
;
6432 dev
->watchdog_timeo
= HZ
*3; //modified by john, 0805
6434 if (dev_alloc_name(dev
, ifname
) < 0){
6435 RT_TRACE(COMP_INIT
, "Oops: devname already taken! Trying wlan%%d...\n");
6436 strcpy(ifname
, "wlan%d");
6437 dev_alloc_name(dev
, ifname
);
6440 RT_TRACE(COMP_INIT
, "Driver probe completed1\n");
6441 if(rtl8192_init(dev
)!=0){
6442 RT_TRACE(COMP_ERR
, "Initialization failed");
6446 netif_carrier_off(dev
);
6447 netif_stop_queue(dev
);
6449 register_netdev(dev
);
6450 RT_TRACE(COMP_INIT
, "dev name=======> %s\n",dev
->name
);
6451 rtl8192_proc_init_one(dev
);
6454 RT_TRACE(COMP_INIT
, "Driver probe completed\n");
6459 #ifdef CONFIG_RTL8180_IO_MAP
6461 if( dev
->base_addr
!= 0 ){
6463 release_region(dev
->base_addr
,
6464 pci_resource_len(pdev
, 0) );
6467 if( dev
->mem_start
!= (unsigned long)NULL
){
6468 iounmap( (void *)dev
->mem_start
);
6469 release_mem_region( pci_resource_start(pdev
, 1),
6470 pci_resource_len(pdev
, 1) );
6472 #endif //end #ifdef RTL_IO_MAP
6478 free_irq(dev
->irq
, dev
);
6481 free_ieee80211(dev
);
6485 pci_disable_device(pdev
);
6487 DMESG("wlan driver load failed\n");
6488 pci_set_drvdata(pdev
, NULL
);
6493 /* detach all the work and timer structure declared or inititialized
6494 * in r8192_init function.
6496 void rtl8192_cancel_deferred_work(struct r8192_priv
* priv
)
6498 /* call cancel_work_sync instead of cancel_delayed_work if and only if Linux_version_code
6499 * is or is newer than 2.6.20 and work structure is defined to be struct work_struct.
6500 * Otherwise call cancel_delayed_work is enough.
6501 * FIXME (2.6.20 should 2.6.22, work_struct should not cancel)
6503 cancel_delayed_work(&priv
->watch_dog_wq
);
6504 cancel_delayed_work(&priv
->update_beacon_wq
);
6505 cancel_delayed_work(&priv
->ieee80211
->hw_wakeup_wq
);
6506 cancel_delayed_work(&priv
->ieee80211
->hw_sleep_wq
);
6508 cancel_delayed_work(&priv
->gpio_change_rf_wq
);
6510 cancel_work_sync(&priv
->reset_wq
);
6511 cancel_work_sync(&priv
->qos_activate
);
6512 //cancel_work_sync(&priv->SetBWModeWorkItem);
6513 //cancel_work_sync(&priv->SwChnlWorkItem);
6518 static void __devexit
rtl8192_pci_disconnect(struct pci_dev
*pdev
)
6520 struct net_device
*dev
= pci_get_drvdata(pdev
);
6521 struct r8192_priv
*priv
;
6525 unregister_netdev(dev
);
6527 priv
=ieee80211_priv(dev
);
6529 rtl8192_proc_remove_one(dev
);
6532 if (priv
->pFirmware
)
6534 vfree(priv
->pFirmware
);
6535 priv
->pFirmware
= NULL
;
6537 // priv->rf_close(dev);
6538 // rtl8192_usb_deleteendpoints(dev);
6539 destroy_workqueue(priv
->priv_wq
);
6540 /* redundant with rtl8192_down */
6541 // rtl8192_irq_disable(dev);
6542 // rtl8192_reset(dev);
6546 /* free tx/rx rings */
6547 rtl8192_free_rx_ring(dev
);
6548 for (i
= 0; i
< MAX_TX_QUEUE_COUNT
; i
++) {
6549 rtl8192_free_tx_ring(dev
, i
);
6554 printk("Freeing irq %d\n",dev
->irq
);
6555 free_irq(dev
->irq
, dev
);
6562 // free_beacon_desc_ring(dev,priv->txbeaconcount);
6564 #ifdef CONFIG_RTL8180_IO_MAP
6566 if( dev
->base_addr
!= 0 ){
6568 release_region(dev
->base_addr
,
6569 pci_resource_len(pdev
, 0) );
6572 if( dev
->mem_start
!= (unsigned long)NULL
){
6573 iounmap( (void *)dev
->mem_start
);
6574 release_mem_region( pci_resource_start(pdev
, 1),
6575 pci_resource_len(pdev
, 1) );
6577 #endif /*end #ifdef RTL_IO_MAP*/
6578 free_ieee80211(dev
);
6582 pci_disable_device(pdev
);
6583 RT_TRACE(COMP_DOWN
, "wlan driver removed\n");
6586 extern int ieee80211_rtl_init(void);
6587 extern void ieee80211_rtl_exit(void);
6589 static int __init
rtl8192_pci_module_init(void)
6593 retval
= ieee80211_rtl_init();
6597 printk(KERN_INFO
"\nLinux kernel driver for RTL8192 based WLAN cards\n");
6598 printk(KERN_INFO
"Copyright (c) 2007-2008, Realsil Wlan\n");
6599 RT_TRACE(COMP_INIT
, "Initializing module");
6600 RT_TRACE(COMP_INIT
, "Wireless extensions version %d", WIRELESS_EXT
);
6601 rtl8192_proc_module_init();
6602 if(0!=pci_register_driver(&rtl8192_pci_driver
))
6604 DMESG("No device found");
6605 /*pci_unregister_driver (&rtl8192_pci_driver);*/
6612 static void __exit
rtl8192_pci_module_exit(void)
6614 pci_unregister_driver(&rtl8192_pci_driver
);
6616 RT_TRACE(COMP_DOWN
, "Exiting");
6617 rtl8192_proc_module_remove();
6618 ieee80211_rtl_exit();
6621 //warning message WB
6622 static irqreturn_t
rtl8192_interrupt(int irq
, void *netdev
)
6624 struct net_device
*dev
= (struct net_device
*) netdev
;
6625 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
6626 unsigned long flags
;
6628 /* We should return IRQ_NONE, but for now let me keep this */
6629 if(priv
->irq_enabled
== 0){
6633 spin_lock_irqsave(&priv
->irq_th_lock
,flags
);
6637 inta
= read_nic_dword(dev
, ISR
);// & priv->IntrMask;
6638 write_nic_dword(dev
,ISR
,inta
); // reset int situation
6640 priv
->stats
.shints
++;
6641 //DMESG("Enter interrupt, ISR value = 0x%08x", inta);
6643 spin_unlock_irqrestore(&priv
->irq_th_lock
,flags
);
6646 most probably we can safely return IRQ_NONE,
6647 but for now is better to avoid problems
6653 spin_unlock_irqrestore(&priv
->irq_th_lock
,flags
);
6659 DMESG("NIC irq %x",inta
);
6661 //priv->irqpending = inta;
6664 if(!netif_running(dev
)) {
6665 spin_unlock_irqrestore(&priv
->irq_th_lock
,flags
);
6669 if(inta
& IMR_TIMEOUT0
){
6670 // write_nic_dword(dev, TimerInt, 0);
6671 //DMESG("=================>waking up");
6672 // rtl8180_hw_wakeup(dev);
6675 if(inta
& IMR_TBDOK
){
6676 RT_TRACE(COMP_INTR
, "beacon ok interrupt!\n");
6677 rtl8192_tx_isr(dev
, BEACON_QUEUE
);
6678 priv
->stats
.txbeaconokint
++;
6681 if(inta
& IMR_TBDER
){
6682 RT_TRACE(COMP_INTR
, "beacon ok interrupt!\n");
6683 rtl8192_tx_isr(dev
, BEACON_QUEUE
);
6684 priv
->stats
.txbeaconerr
++;
6687 if(inta
& IMR_MGNTDOK
) {
6688 RT_TRACE(COMP_INTR
, "Manage ok interrupt!\n");
6689 priv
->stats
.txmanageokint
++;
6690 rtl8192_tx_isr(dev
,MGNT_QUEUE
);
6694 if(inta
& IMR_COMDOK
)
6696 priv
->stats
.txcmdpktokint
++;
6697 rtl8192_tx_isr(dev
,TXCMD_QUEUE
);
6702 DMESG("Frame arrived !");
6704 priv
->stats
.rxint
++;
6705 tasklet_schedule(&priv
->irq_rx_tasklet
);
6708 if(inta
& IMR_BcnInt
) {
6709 RT_TRACE(COMP_INTR
, "prepare beacon for interrupt!\n");
6710 tasklet_schedule(&priv
->irq_prepare_beacon_tasklet
);
6714 RT_TRACE(COMP_INTR
, "rx descriptor unavailable!\n");
6715 priv
->stats
.rxrdu
++;
6716 /* reset int situation */
6717 write_nic_dword(dev
,INTA_MASK
,read_nic_dword(dev
, INTA_MASK
) & ~IMR_RDU
);
6718 tasklet_schedule(&priv
->irq_rx_tasklet
);
6721 if(inta
& IMR_RXFOVW
){
6722 RT_TRACE(COMP_INTR
, "rx overflow !\n");
6723 priv
->stats
.rxoverflow
++;
6724 tasklet_schedule(&priv
->irq_rx_tasklet
);
6727 if(inta
& IMR_TXFOVW
) priv
->stats
.txoverflow
++;
6729 if(inta
& IMR_BKDOK
){
6730 RT_TRACE(COMP_INTR
, "BK Tx OK interrupt!\n");
6731 priv
->stats
.txbkokint
++;
6732 priv
->ieee80211
->LinkDetectInfo
.NumTxOkInPeriod
++;
6733 rtl8192_tx_isr(dev
,BK_QUEUE
);
6734 rtl8192_try_wake_queue(dev
, BK_QUEUE
);
6737 if(inta
& IMR_BEDOK
){
6738 RT_TRACE(COMP_INTR
, "BE TX OK interrupt!\n");
6739 priv
->stats
.txbeokint
++;
6740 priv
->ieee80211
->LinkDetectInfo
.NumTxOkInPeriod
++;
6741 rtl8192_tx_isr(dev
,BE_QUEUE
);
6742 rtl8192_try_wake_queue(dev
, BE_QUEUE
);
6745 if(inta
& IMR_VIDOK
){
6746 RT_TRACE(COMP_INTR
, "VI TX OK interrupt!\n");
6747 priv
->stats
.txviokint
++;
6748 priv
->ieee80211
->LinkDetectInfo
.NumTxOkInPeriod
++;
6749 rtl8192_tx_isr(dev
,VI_QUEUE
);
6750 rtl8192_try_wake_queue(dev
, VI_QUEUE
);
6753 if(inta
& IMR_VODOK
){
6754 priv
->stats
.txvookint
++;
6755 priv
->ieee80211
->LinkDetectInfo
.NumTxOkInPeriod
++;
6756 rtl8192_tx_isr(dev
,VO_QUEUE
);
6757 rtl8192_try_wake_queue(dev
, VO_QUEUE
);
6760 force_pci_posting(dev
);
6761 spin_unlock_irqrestore(&priv
->irq_th_lock
,flags
);
6766 static void rtl8192_try_wake_queue(struct net_device
*dev
, int pri
)
6769 unsigned long flags
;
6771 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
6773 spin_lock_irqsave(&priv
->tx_lock
,flags
);
6774 enough_desc
= check_nic_enough_desc(dev
,pri
);
6775 spin_unlock_irqrestore(&priv
->tx_lock
,flags
);
6778 ieee80211_rtl_wake_queue(priv
->ieee80211
);
6783 void EnableHWSecurityConfig8192(struct net_device
*dev
)
6785 u8 SECR_value
= 0x0;
6786 // struct ieee80211_device* ieee1 = container_of(&dev, struct ieee80211_device, dev);
6787 //printk("==>ieee1:%p, dev:%p\n", ieee1, dev);
6788 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
6789 struct ieee80211_device
* ieee
= priv
->ieee80211
;
6790 //printk("==>ieee:%p, dev:%p\n", ieee, dev);
6791 SECR_value
= SCR_TxEncEnable
| SCR_RxDecEnable
;
6793 if (((KEY_TYPE_WEP40
== ieee
->pairwise_key_type
) || (KEY_TYPE_WEP104
== ieee
->pairwise_key_type
)) && (priv
->ieee80211
->auth_mode
!= 2))
6795 SECR_value
|= SCR_RxUseDK
;
6796 SECR_value
|= SCR_TxUseDK
;
6798 else if ((ieee
->iw_mode
== IW_MODE_ADHOC
) && (ieee
->pairwise_key_type
& (KEY_TYPE_CCMP
| KEY_TYPE_TKIP
)))
6800 SECR_value
|= SCR_RxUseDK
;
6801 SECR_value
|= SCR_TxUseDK
;
6806 //add HWSec active enable here.
6807 //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
6808 ieee
->hwsec_active
= 1;
6810 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
6812 ieee
->hwsec_active
= 0;
6813 SECR_value
&= ~SCR_RxDecEnable
;
6816 RT_TRACE(COMP_SEC
,"%s:, hwsec:%d, pairwise_key:%d, SECR_value:%x\n", __FUNCTION__
,
6817 ieee
->hwsec_active
, ieee
->pairwise_key_type
, SECR_value
);
6819 write_nic_byte(dev
, SECR
, SECR_value
);//SECR_value | SCR_UseDK );
6823 #define TOTAL_CAM_ENTRY 32
6824 //#define CAM_CONTENT_COUNT 8
6825 void setKey( struct net_device
*dev
,
6833 u32 TargetCommand
= 0;
6834 u32 TargetContent
= 0;
6838 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
6839 RT_RF_POWER_STATE rtState
;
6840 rtState
= priv
->ieee80211
->eRFPowerState
;
6841 if(priv
->ieee80211
->PowerSaveControl
.bInactivePs
){
6842 if(rtState
== eRfOff
){
6843 if(priv
->ieee80211
->RfOffReason
> RF_CHANGE_BY_IPS
)
6845 RT_TRACE(COMP_ERR
, "%s(): RF is OFF.\n",__FUNCTION__
);
6846 //up(&priv->wx_sem);
6850 down(&priv
->ieee80211
->ips_sem
);
6852 up(&priv
->ieee80211
->ips_sem
);
6856 priv
->ieee80211
->is_set_key
= true;
6858 if (EntryNo
>= TOTAL_CAM_ENTRY
)
6859 RT_TRACE(COMP_ERR
, "cam entry exceeds in setKey()\n");
6861 RT_TRACE(COMP_SEC
, "====>to setKey(), dev:%p, EntryNo:%d, KeyIndex:%d, KeyType:%d, MacAddr%pM\n", dev
,EntryNo
, KeyIndex
, KeyType
, MacAddr
);
6864 usConfig
|= BIT15
| (KeyType
<<2);
6866 usConfig
|= BIT15
| (KeyType
<<2) | KeyIndex
;
6867 // usConfig |= BIT15 | (KeyType<<2) | (DefaultKey<<5) | KeyIndex;
6870 for(i
=0 ; i
<CAM_CONTENT_COUNT
; i
++){
6871 TargetCommand
= i
+CAM_CONTENT_COUNT
*EntryNo
;
6872 TargetCommand
|= BIT31
|BIT16
;
6874 if(i
==0){//MAC|Config
6875 TargetContent
= (u32
)(*(MacAddr
+0)) << 16|
6876 (u32
)(*(MacAddr
+1)) << 24|
6879 write_nic_dword(dev
, WCAMI
, TargetContent
);
6880 write_nic_dword(dev
, RWCAM
, TargetCommand
);
6881 // printk("setkey cam =%8x\n", read_cam(dev, i+6*EntryNo));
6884 TargetContent
= (u32
)(*(MacAddr
+2)) |
6885 (u32
)(*(MacAddr
+3)) << 8|
6886 (u32
)(*(MacAddr
+4)) << 16|
6887 (u32
)(*(MacAddr
+5)) << 24;
6888 write_nic_dword(dev
, WCAMI
, TargetContent
);
6889 write_nic_dword(dev
, RWCAM
, TargetCommand
);
6891 else { //Key Material
6892 if(KeyContent
!= NULL
)
6894 write_nic_dword(dev
, WCAMI
, (u32
)(*(KeyContent
+i
-2)) );
6895 write_nic_dword(dev
, RWCAM
, TargetCommand
);
6899 RT_TRACE(COMP_SEC
,"=========>after set key, usconfig:%x\n", usConfig
);
6901 // This function seems not ready! WB
6902 void CamPrintDbgReg(struct net_device
* dev
)
6904 unsigned long rvalue
;
6905 unsigned char ucValue
;
6906 write_nic_dword(dev
, DCAM
, 0x80000000);
6908 rvalue
= read_nic_dword(dev
, DCAM
); //delay_ms(40);
6909 RT_TRACE(COMP_SEC
, " TX CAM=%8lX ",rvalue
);
6910 if((rvalue
& 0x40000000) != 0x4000000)
6911 RT_TRACE(COMP_SEC
, "-->TX Key Not Found ");
6913 write_nic_dword(dev
, DCAM
, 0x00000000); //delay_ms(40);
6914 rvalue
= read_nic_dword(dev
, DCAM
); //delay_ms(40);
6915 RT_TRACE(COMP_SEC
, "RX CAM=%8lX ",rvalue
);
6916 if((rvalue
& 0x40000000) != 0x4000000)
6917 RT_TRACE(COMP_SEC
, "-->CAM Key Not Found ");
6918 ucValue
= read_nic_byte(dev
, SECR
);
6919 RT_TRACE(COMP_SEC
, "WPA_Config=%x \n",ucValue
);
6922 bool NicIFEnableNIC(struct net_device
* dev
)
6924 RT_STATUS init_status
= RT_STATUS_SUCCESS
;
6925 struct r8192_priv
* priv
= ieee80211_priv(dev
);
6926 PRT_POWER_SAVE_CONTROL pPSC
= (PRT_POWER_SAVE_CONTROL
)(&(priv
->ieee80211
->PowerSaveControl
));
6930 RT_TRACE(COMP_ERR
, "ERR!!! %s(): Driver is already down!\n",__FUNCTION__
);
6931 priv
->bdisable_nic
= false; //YJ,add,091111
6934 // <1> Reset memory: descriptor, buffer,..
6935 //NicIFResetMemory(Adapter);
6937 // <2> Enable Adapter
6938 //printk("===========>%s()\n",__FUNCTION__);
6939 //priv->bfirst_init = true;
6940 init_status
= rtl8192_adapter_start(dev
);
6941 if (init_status
!= RT_STATUS_SUCCESS
) {
6942 RT_TRACE(COMP_ERR
,"ERR!!! %s(): initialization is failed!\n",__FUNCTION__
);
6943 priv
->bdisable_nic
= false; //YJ,add,091111
6946 //printk("start adapter finished\n");
6947 RT_CLEAR_PS_LEVEL(pPSC
, RT_RF_OFF_LEVL_HALT_NIC
);
6948 //priv->bfirst_init = false;
6950 // <3> Enable Interrupt
6951 rtl8192_irq_enable(dev
);
6952 priv
->bdisable_nic
= false;
6953 //RT_TRACE(COMP_PS,"<===========%s()\n",__FUNCTION__);
6954 return (init_status
== RT_STATUS_SUCCESS
) ? true:false;
6956 bool NicIFDisableNIC(struct net_device
* dev
)
6959 struct r8192_priv
* priv
= ieee80211_priv(dev
);
6961 // <1> Disable Interrupt
6962 //RT_TRACE(COMP_PS, "=========>%s()\n",__FUNCTION__);
6963 priv
->bdisable_nic
= true; //YJ,move,091109
6964 tmp_state
= priv
->ieee80211
->state
;
6966 ieee80211_softmac_stop_protocol(priv
->ieee80211
, false);
6968 priv
->ieee80211
->state
= tmp_state
;
6969 rtl8192_cancel_deferred_work(priv
);
6970 rtl8192_irq_disable(dev
);
6971 // <2> Stop all timer
6973 // <3> Disable Adapter
6974 rtl8192_halt_adapter(dev
, false);
6975 // priv->bdisable_nic = true;
6976 //RT_TRACE(COMP_PS, "<=========%s()\n",__FUNCTION__);
6982 /***************************************************************************
6983 ------------------- module init / exit stubs ----------------
6984 ****************************************************************************/
6985 module_init(rtl8192_pci_module_init
);
6986 module_exit(rtl8192_pci_module_exit
);