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 <asm/uaccess.h>
50 #include "r8192E_hw.h"
52 #include "r8190_rtl8256.h" /* RTL8225 Radio frontend */
53 #include "r8180_93cx6.h" /* Card EEPROM */
54 #include "r8192E_wx.h"
55 #include "r819xE_phy.h" //added by WB 4.30.2008
56 #include "r819xE_phyreg.h"
57 #include "r819xE_cmdpkt.h"
58 #include "r8192E_dm.h"
59 //#include "r8192xU_phyreg.h"
60 //#include <linux/usb.h>
61 // FIXME: check if 2.6.7 is ok
71 //set here to open your trace code. //WB
72 u32 rt_global_debug_component
= \
90 // COMP_POWER_TRACKING |
92 COMP_ERR
; //always open err flags on
94 #define PCI_DEVICE(vend,dev)\
95 .vendor=(vend),.device=(dev),\
96 .subvendor=PCI_ANY_ID,.subdevice=PCI_ANY_ID
98 static struct pci_device_id rtl8192_pci_id_tbl
[] __devinitdata
= {
102 { PCI_DEVICE(0x10ec, 0x8190) },
104 { PCI_DEVICE(0x07aa, 0x0045) },
105 { PCI_DEVICE(0x07aa, 0x0046) },
108 { PCI_DEVICE(0x10ec, 0x8192) },
111 { PCI_DEVICE(0x07aa, 0x0044) },
112 { PCI_DEVICE(0x07aa, 0x0047) },
117 static char* ifname
= "wlan%d";
118 static int hwwep
= 1; //default use hw. set 0 to use software security
119 static int channels
= 0x3fff;
121 MODULE_LICENSE("GPL");
122 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
123 MODULE_VERSION("V 1.1");
125 MODULE_DEVICE_TABLE(pci
, rtl8192_pci_id_tbl
);
126 //MODULE_AUTHOR("Andrea Merello <andreamrl@tiscali.it>");
127 MODULE_DESCRIPTION("Linux driver for Realtek RTL819x WiFi cards");
130 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 9)
131 module_param(ifname
, charp
, S_IRUGO
|S_IWUSR
);
132 //module_param(hwseqnum,int, S_IRUGO|S_IWUSR);
133 module_param(hwwep
,int, S_IRUGO
|S_IWUSR
);
134 module_param(channels
,int, S_IRUGO
|S_IWUSR
);
136 MODULE_PARM(ifname
, "s");
137 //MODULE_PARM(hwseqnum,"i");
138 MODULE_PARM(hwwep
,"i");
139 MODULE_PARM(channels
,"i");
142 MODULE_PARM_DESC(ifname
," Net interface name, wlan%d=default");
143 //MODULE_PARM_DESC(hwseqnum," Try to use hardware 802.11 header sequence numbers. Zero=default");
144 MODULE_PARM_DESC(hwwep
," Try to use hardware WEP support. Still broken and not available on all cards");
145 MODULE_PARM_DESC(channels
," Channel bitmask for specific locales. NYI");
147 static int __devinit
rtl8192_pci_probe(struct pci_dev
*pdev
,
148 const struct pci_device_id
*id
);
149 static void __devexit
rtl8192_pci_disconnect(struct pci_dev
*pdev
);
151 static struct pci_driver rtl8192_pci_driver
= {
152 .name
= RTL819xE_MODULE_NAME
, /* Driver name */
153 .id_table
= rtl8192_pci_id_tbl
, /* PCI_ID table */
154 .probe
= rtl8192_pci_probe
, /* probe fn */
155 .remove
= __devexit_p(rtl8192_pci_disconnect
), /* remove fn */
156 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0)
158 .suspend
= rtl8192E_suspend
, /* PM suspend fn */
159 .resume
= rtl8192E_resume
, /* PM resume fn */
161 .suspend
= NULL
, /* PM suspend fn */
162 .resume
= NULL
, /* PM resume fn */
169 typedef struct _CHANNEL_LIST
173 }CHANNEL_LIST
, *PCHANNEL_LIST
;
175 static CHANNEL_LIST ChannelPlan
[] = {
176 {{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
177 {{1,2,3,4,5,6,7,8,9,10,11},11}, //IC
178 {{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48,52,56,60,64},21}, //ETSI
179 {{1,2,3,4,5,6,7,8,9,10,11,12,13},13}, //Spain. Change to ETSI.
180 {{1,2,3,4,5,6,7,8,9,10,11,12,13},13}, //France. Change to ETSI.
181 {{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
182 {{1,2,3,4,5,6,7,8,9,10,11,12,13,14,36,40,44,48,52,56,60,64},22},//MKK1
183 {{1,2,3,4,5,6,7,8,9,10,11,12,13},13}, //Israel.
184 {{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
185 {{1,2,3,4,5,6,7,8,9,10,11,12,13,14,36,40,44,48,52,56,60,64}, 22}, //MIC
186 {{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
189 static void rtl819x_set_channel_map(u8 channel_plan
, struct r8192_priv
* priv
)
191 int i
, max_chan
=-1, min_chan
=-1;
192 struct ieee80211_device
* ieee
= priv
->ieee80211
;
193 switch (channel_plan
)
195 case COUNTRY_CODE_FCC
:
196 case COUNTRY_CODE_IC
:
197 case COUNTRY_CODE_ETSI
:
198 case COUNTRY_CODE_SPAIN
:
199 case COUNTRY_CODE_FRANCE
:
200 case COUNTRY_CODE_MKK
:
201 case COUNTRY_CODE_MKK1
:
202 case COUNTRY_CODE_ISRAEL
:
203 case COUNTRY_CODE_TELEC
:
204 case COUNTRY_CODE_MIC
:
207 ieee
->bGlobalDomain
= false;
208 //acturally 8225 & 8256 rf chip only support B,G,24N mode
209 if ((priv
->rf_chip
== RF_8225
) || (priv
->rf_chip
== RF_8256
))
216 RT_TRACE(COMP_ERR
, "unknown rf chip, can't set channel map in function:%s()\n", __FUNCTION__
);
218 if (ChannelPlan
[channel_plan
].Len
!= 0){
219 // Clear old channel map
220 memset(GET_DOT11D_INFO(ieee
)->channel_map
, 0, sizeof(GET_DOT11D_INFO(ieee
)->channel_map
));
221 // Set new channel map
222 for (i
=0;i
<ChannelPlan
[channel_plan
].Len
;i
++)
224 if (ChannelPlan
[channel_plan
].Channel
[i
] < min_chan
|| ChannelPlan
[channel_plan
].Channel
[i
] > max_chan
)
226 GET_DOT11D_INFO(ieee
)->channel_map
[ChannelPlan
[channel_plan
].Channel
[i
]] = 1;
231 case COUNTRY_CODE_GLOBAL_DOMAIN
:
233 GET_DOT11D_INFO(ieee
)->bEnabled
= 0; //this flag enabled to follow 11d country IE setting, otherwise, it shall follow global domain setting
235 ieee
->bGlobalDomain
= true;
245 #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 )
246 /* 2007/07/25 MH Defien temp tx fw info. */
247 static TX_FWINFO_T Tmp_TxFwInfo
;
250 #define rx_hal_is_cck_rate(_pdrvinfo)\
251 (_pdrvinfo->RxRate == DESC90_RATE1M ||\
252 _pdrvinfo->RxRate == DESC90_RATE2M ||\
253 _pdrvinfo->RxRate == DESC90_RATE5_5M ||\
254 _pdrvinfo->RxRate == DESC90_RATE11M) &&\
258 void CamResetAllEntry(struct net_device *dev)
264 ulcommand
|= BIT31
|BIT30
;
265 write_nic_dword(dev
, RWCAM
, ulcommand
);
267 for(ucIndex
=0;ucIndex
<TOTAL_CAM_ENTRY
;ucIndex
++)
268 CAM_mark_invalid(dev
, ucIndex
);
269 for(ucIndex
=0;ucIndex
<TOTAL_CAM_ENTRY
;ucIndex
++)
270 CAM_empty_entry(dev
, ucIndex
);
275 void write_cam(struct net_device
*dev
, u8 addr
, u32 data
)
277 write_nic_dword(dev
, WCAMI
, data
);
278 write_nic_dword(dev
, RWCAM
, BIT31
|BIT16
|(addr
&0xff) );
280 u32
read_cam(struct net_device
*dev
, u8 addr
)
282 write_nic_dword(dev
, RWCAM
, 0x80000000|(addr
&0xff) );
283 return read_nic_dword(dev
, 0xa8);
286 ////////////////////////////////////////////////////////////
287 #ifdef CONFIG_RTL8180_IO_MAP
289 u8
read_nic_byte(struct net_device
*dev
, int x
)
291 return 0xff&inb(dev
->base_addr
+x
);
294 u32
read_nic_dword(struct net_device
*dev
, int x
)
296 return inl(dev
->base_addr
+x
);
299 u16
read_nic_word(struct net_device
*dev
, int x
)
301 return inw(dev
->base_addr
+x
);
304 void write_nic_byte(struct net_device
*dev
, int x
,u8 y
)
306 outb(y
&0xff,dev
->base_addr
+x
);
309 void write_nic_word(struct net_device
*dev
, int x
,u16 y
)
311 outw(y
,dev
->base_addr
+x
);
314 void write_nic_dword(struct net_device
*dev
, int x
,u32 y
)
316 outl(y
,dev
->base_addr
+x
);
319 #else /* RTL_IO_MAP */
321 u8
read_nic_byte(struct net_device
*dev
, int x
)
323 return 0xff&readb((u8
*)dev
->mem_start
+x
);
326 u32
read_nic_dword(struct net_device
*dev
, int x
)
328 return readl((u8
*)dev
->mem_start
+x
);
331 u16
read_nic_word(struct net_device
*dev
, int x
)
333 return readw((u8
*)dev
->mem_start
+x
);
336 void write_nic_byte(struct net_device
*dev
, int x
,u8 y
)
338 writeb(y
,(u8
*)dev
->mem_start
+x
);
342 void write_nic_dword(struct net_device
*dev
, int x
,u32 y
)
344 writel(y
,(u8
*)dev
->mem_start
+x
);
348 void write_nic_word(struct net_device
*dev
, int x
,u16 y
)
350 writew(y
,(u8
*)dev
->mem_start
+x
);
354 #endif /* RTL_IO_MAP */
357 ///////////////////////////////////////////////////////////
359 //u8 read_phy_cck(struct net_device *dev, u8 adr);
360 //u8 read_phy_ofdm(struct net_device *dev, u8 adr);
361 /* this might still called in what was the PHY rtl8185/rtl8192 common code
362 * plans are to possibilty turn it again in one common code...
364 inline void force_pci_posting(struct net_device
*dev
)
370 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18)
371 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
372 void rtl8192_interrupt(int irq
, void *netdev
, struct pt_regs
*regs
);
374 irqreturn_t
rtl8192_interrupt(int irq
, void *netdev
, struct pt_regs
*regs
);
377 irqreturn_t
rtl8192_interrupt(int irq
, void *netdev
);
379 //static struct net_device_stats *rtl8192_stats(struct net_device *dev);
380 void rtl8192_commit(struct net_device
*dev
);
381 //void rtl8192_restart(struct net_device *dev);
382 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
383 void rtl8192_restart(struct work_struct
*work
);
384 //void rtl8192_rq_tx_ack(struct work_struct *work);
386 void rtl8192_restart(struct net_device
*dev
);
387 // //void rtl8192_rq_tx_ack(struct net_device *dev);
390 void watch_dog_timer_callback(unsigned long data
);
392 void IPSEnter(struct net_device
*dev
);
393 void IPSLeave(struct net_device
*dev
);
394 void InactivePsWorkItemCallback(struct net_device
*dev
);
396 /****************************************************************************
397 -----------------------------PROCFS STUFF-------------------------
398 *****************************************************************************/
400 static struct proc_dir_entry
*rtl8192_proc
= NULL
;
404 static int proc_get_stats_ap(char *page
, char **start
,
405 off_t offset
, int count
,
406 int *eof
, void *data
)
408 struct net_device
*dev
= data
;
409 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
410 struct ieee80211_device
*ieee
= priv
->ieee80211
;
411 struct ieee80211_network
*target
;
415 list_for_each_entry(target
, &ieee
->network_list
, list
) {
417 len
+= snprintf(page
+ len
, count
- len
,
418 "%s ", target
->ssid
);
420 if(target
->wpa_ie_len
>0 || target
->rsn_ie_len
>0){
421 len
+= snprintf(page
+ len
, count
- len
,
425 len
+= snprintf(page
+ len
, count
- len
,
435 static int proc_get_registers(char *page
, char **start
,
436 off_t offset
, int count
,
437 int *eof
, void *data
)
439 struct net_device
*dev
= data
;
440 // struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
447 /* This dump the current register page */
448 len
+= snprintf(page
+ len
, count
- len
,
449 "\n####################page 0##################\n ");
453 //printk( "\nD: %2x> ", n);
454 len
+= snprintf(page
+ len
, count
- len
,
457 for(i
=0;i
<16 && n
<=max
;i
++,n
++)
458 len
+= snprintf(page
+ len
, count
- len
,
459 "%2x ",read_nic_byte(dev
,n
));
461 // printk("%2x ",read_nic_byte(dev,n));
463 len
+= snprintf(page
+ len
, count
- len
,"\n");
464 len
+= snprintf(page
+ len
, count
- len
,
465 "\n####################page 1##################\n ");
468 //printk( "\nD: %2x> ", n);
469 len
+= snprintf(page
+ len
, count
- len
,
472 for(i
=0;i
<16 && n
<=max
;i
++,n
++)
473 len
+= snprintf(page
+ len
, count
- len
,
474 "%2x ",read_nic_byte(dev
,0x100|n
));
476 // printk("%2x ",read_nic_byte(dev,n));
479 len
+= snprintf(page
+ len
, count
- len
,
480 "\n####################page 3##################\n ");
483 //printk( "\nD: %2x> ", n);
484 len
+= snprintf(page
+ len
, count
- len
,
487 for(i
=0;i
<16 && n
<=max
;i
++,n
++)
488 len
+= snprintf(page
+ len
, count
- len
,
489 "%2x ",read_nic_byte(dev
,0x300|n
));
491 // printk("%2x ",read_nic_byte(dev,n));
502 static int proc_get_stats_tx(char *page
, char **start
,
503 off_t offset
, int count
,
504 int *eof
, void *data
)
506 struct net_device
*dev
= data
;
507 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
511 len
+= snprintf(page
+ len
, count
- len
,
512 "TX VI priority ok int: %lu\n"
513 // "TX VI priority error int: %lu\n"
514 "TX VO priority ok int: %lu\n"
515 // "TX VO priority error int: %lu\n"
516 "TX BE priority ok int: %lu\n"
517 // "TX BE priority error int: %lu\n"
518 "TX BK priority ok int: %lu\n"
519 // "TX BK priority error int: %lu\n"
520 "TX MANAGE priority ok int: %lu\n"
521 // "TX MANAGE priority error int: %lu\n"
522 "TX BEACON priority ok int: %lu\n"
523 "TX BEACON priority error int: %lu\n"
524 "TX CMDPKT priority ok int: %lu\n"
525 // "TX high priority ok int: %lu\n"
526 // "TX high priority failed error int: %lu\n"
527 // "TX queue resume: %lu\n"
528 "TX queue stopped?: %d\n"
529 "TX fifo overflow: %lu\n"
530 // "TX beacon: %lu\n"
531 // "TX VI queue: %d\n"
532 // "TX VO queue: %d\n"
533 // "TX BE queue: %d\n"
534 // "TX BK queue: %d\n"
535 // "TX HW queue: %d\n"
536 // "TX VI dropped: %lu\n"
537 // "TX VO dropped: %lu\n"
538 // "TX BE dropped: %lu\n"
539 // "TX BK dropped: %lu\n"
540 "TX total data packets %lu\n"
541 "TX total data bytes :%lu\n",
542 // "TX beacon aborted: %lu\n",
543 priv
->stats
.txviokint
,
544 // priv->stats.txvierr,
545 priv
->stats
.txvookint
,
546 // priv->stats.txvoerr,
547 priv
->stats
.txbeokint
,
548 // priv->stats.txbeerr,
549 priv
->stats
.txbkokint
,
550 // priv->stats.txbkerr,
551 priv
->stats
.txmanageokint
,
552 // priv->stats.txmanageerr,
553 priv
->stats
.txbeaconokint
,
554 priv
->stats
.txbeaconerr
,
555 priv
->stats
.txcmdpktokint
,
556 // priv->stats.txhpokint,
557 // priv->stats.txhperr,
558 // priv->stats.txresumed,
559 netif_queue_stopped(dev
),
560 priv
->stats
.txoverflow
,
561 // priv->stats.txbeacon,
562 // atomic_read(&(priv->tx_pending[VI_QUEUE])),
563 // atomic_read(&(priv->tx_pending[VO_QUEUE])),
564 // atomic_read(&(priv->tx_pending[BE_QUEUE])),
565 // atomic_read(&(priv->tx_pending[BK_QUEUE])),
566 // read_nic_byte(dev, TXFIFOCOUNT),
567 // priv->stats.txvidrop,
568 // priv->stats.txvodrop,
569 priv
->ieee80211
->stats
.tx_packets
,
570 priv
->ieee80211
->stats
.tx_bytes
573 // priv->stats.txbedrop,
574 // priv->stats.txbkdrop
575 // priv->stats.txdatapkt
576 // priv->stats.txbeaconerr
585 static int proc_get_stats_rx(char *page
, char **start
,
586 off_t offset
, int count
,
587 int *eof
, void *data
)
589 struct net_device
*dev
= data
;
590 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
594 len
+= snprintf(page
+ len
, count
- len
,
597 "RX rx overflow error: %lu\n"
598 "RX invalid urb error: %lu\n",
601 priv
->stats
.rxoverflow
,
602 priv
->stats
.rxurberr
);
608 static void rtl8192_proc_module_init(void)
610 RT_TRACE(COMP_INIT
, "Initializing proc filesystem");
611 #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24))
612 rtl8192_proc
=create_proc_entry(RTL819xE_MODULE_NAME
, S_IFDIR
, proc_net
);
614 rtl8192_proc
=create_proc_entry(RTL819xE_MODULE_NAME
, S_IFDIR
, init_net
.proc_net
);
619 static void rtl8192_proc_module_remove(void)
621 #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24))
622 remove_proc_entry(RTL819xE_MODULE_NAME
, proc_net
);
624 remove_proc_entry(RTL819xE_MODULE_NAME
, init_net
.proc_net
);
629 static void rtl8192_proc_remove_one(struct net_device
*dev
)
631 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
633 printk("dev name=======> %s\n",dev
->name
);
636 // remove_proc_entry("stats-hw", priv->dir_dev);
637 remove_proc_entry("stats-tx", priv
->dir_dev
);
638 remove_proc_entry("stats-rx", priv
->dir_dev
);
639 // remove_proc_entry("stats-ieee", priv->dir_dev);
640 remove_proc_entry("stats-ap", priv
->dir_dev
);
641 remove_proc_entry("registers", priv
->dir_dev
);
642 // remove_proc_entry("cck-registers",priv->dir_dev);
643 // remove_proc_entry("ofdm-registers",priv->dir_dev);
644 //remove_proc_entry(dev->name, rtl8192_proc);
645 remove_proc_entry("wlan0", rtl8192_proc
);
646 priv
->dir_dev
= NULL
;
651 static void rtl8192_proc_init_one(struct net_device
*dev
)
653 struct proc_dir_entry
*e
;
654 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
655 priv
->dir_dev
= create_proc_entry(dev
->name
,
656 S_IFDIR
| S_IRUGO
| S_IXUGO
,
658 if (!priv
->dir_dev
) {
659 RT_TRACE(COMP_ERR
, "Unable to initialize /proc/net/rtl8192/%s\n",
663 e
= create_proc_read_entry("stats-rx", S_IFREG
| S_IRUGO
,
664 priv
->dir_dev
, proc_get_stats_rx
, dev
);
667 RT_TRACE(COMP_ERR
,"Unable to initialize "
668 "/proc/net/rtl8192/%s/stats-rx\n",
673 e
= create_proc_read_entry("stats-tx", S_IFREG
| S_IRUGO
,
674 priv
->dir_dev
, proc_get_stats_tx
, dev
);
677 RT_TRACE(COMP_ERR
, "Unable to initialize "
678 "/proc/net/rtl8192/%s/stats-tx\n",
682 e
= create_proc_read_entry("stats-ap", S_IFREG
| S_IRUGO
,
683 priv
->dir_dev
, proc_get_stats_ap
, dev
);
686 RT_TRACE(COMP_ERR
, "Unable to initialize "
687 "/proc/net/rtl8192/%s/stats-ap\n",
691 e
= create_proc_read_entry("registers", S_IFREG
| S_IRUGO
,
692 priv
->dir_dev
, proc_get_registers
, dev
);
694 RT_TRACE(COMP_ERR
, "Unable to initialize "
695 "/proc/net/rtl8192/%s/registers\n",
699 /****************************************************************************
700 -----------------------------MISC STUFF-------------------------
701 *****************************************************************************/
703 short check_nic_enough_desc(struct net_device
*dev
, int prio
)
705 struct r8192_priv
*priv
= ieee80211_priv(dev
);
706 struct rtl8192_tx_ring
*ring
= &priv
->tx_ring
[prio
];
708 /* for now we reserve two free descriptor as a safety boundary
709 * between the tail and the head
711 if (ring
->entries
- skb_queue_len(&ring
->queue
) >= 2) {
718 static void tx_timeout(struct net_device
*dev
)
720 struct r8192_priv
*priv
= ieee80211_priv(dev
);
721 //rtl8192_commit(dev);
723 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
724 schedule_work(&priv
->reset_wq
);
726 schedule_task(&priv
->reset_wq
);
732 /****************************************************************************
733 ------------------------------HW STUFF---------------------------
734 *****************************************************************************/
737 static void rtl8192_irq_enable(struct net_device
*dev
)
739 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
740 priv
->irq_enabled
= 1;
741 write_nic_dword(dev
,INTA_MASK
, priv
->irq_mask
);
745 static void rtl8192_irq_disable(struct net_device
*dev
)
747 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
749 write_nic_dword(dev
,INTA_MASK
,0);
750 force_pci_posting(dev
);
751 priv
->irq_enabled
= 0;
755 static void rtl8192_set_mode(struct net_device
*dev
,int mode
)
758 ecmd
=read_nic_byte(dev
, EPROM_CMD
);
759 ecmd
=ecmd
&~ EPROM_CMD_OPERATING_MODE_MASK
;
760 ecmd
=ecmd
| (mode
<<EPROM_CMD_OPERATING_MODE_SHIFT
);
761 ecmd
=ecmd
&~ (1<<EPROM_CS_SHIFT
);
762 ecmd
=ecmd
&~ (1<<EPROM_CK_SHIFT
);
763 write_nic_byte(dev
, EPROM_CMD
, ecmd
);
767 void rtl8192_update_msr(struct net_device
*dev
)
769 struct r8192_priv
*priv
= ieee80211_priv(dev
);
772 msr
= read_nic_byte(dev
, MSR
);
773 msr
&= ~ MSR_LINK_MASK
;
775 /* do not change in link_state != WLAN_LINK_ASSOCIATED.
776 * msr must be updated if the state is ASSOCIATING.
777 * this is intentional and make sense for ad-hoc and
778 * master (see the create BSS/IBSS func)
780 if (priv
->ieee80211
->state
== IEEE80211_LINKED
){
782 if (priv
->ieee80211
->iw_mode
== IW_MODE_INFRA
)
783 msr
|= (MSR_LINK_MANAGED
<<MSR_LINK_SHIFT
);
784 else if (priv
->ieee80211
->iw_mode
== IW_MODE_ADHOC
)
785 msr
|= (MSR_LINK_ADHOC
<<MSR_LINK_SHIFT
);
786 else if (priv
->ieee80211
->iw_mode
== IW_MODE_MASTER
)
787 msr
|= (MSR_LINK_MASTER
<<MSR_LINK_SHIFT
);
790 msr
|= (MSR_LINK_NONE
<<MSR_LINK_SHIFT
);
792 write_nic_byte(dev
, MSR
, msr
);
795 void rtl8192_set_chan(struct net_device
*dev
,short ch
)
797 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
798 RT_TRACE(COMP_RF
, "=====>%s()====ch:%d\n", __FUNCTION__
, ch
);
801 if(priv
->ieee80211
->iw_mode
== IW_MODE_ADHOC
||
802 priv
->ieee80211
->iw_mode
== IW_MODE_MASTER
){
804 priv
->ieee80211
->link_state
= WLAN_LINK_ASSOCIATED
;
805 priv
->ieee80211
->master_chan
= ch
;
806 rtl8192_update_beacon_ch(dev
);
810 /* this hack should avoid frame TX during channel setting*/
813 // tx = read_nic_dword(dev,TX_CONF);
814 // tx &= ~TX_LOOPBACK_MASK;
818 // write_nic_dword(dev,TX_CONF, tx |( TX_LOOPBACK_MAC<<TX_LOOPBACK_SHIFT));
820 //need to implement rf set channel here WB
822 if (priv
->rf_set_chan
)
823 priv
->rf_set_chan(dev
,priv
->chan
);
825 // write_nic_dword(dev,TX_CONF,tx | (TX_LOOPBACK_NONE<<TX_LOOPBACK_SHIFT));
829 void rtl8192_rx_enable(struct net_device
*dev
)
831 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
832 write_nic_dword(dev
, RDQDA
,priv
->rx_ring_dma
);
835 /* the TX_DESC_BASE setting is according to the following queue index
844 * BEACON_QUEUE ===> 8
846 static u32 TX_DESC_BASE
[] = {BKQDA
, BEQDA
, VIQDA
, VOQDA
, HCCAQDA
, CQDA
, MQDA
, HQDA
, BQDA
};
847 void rtl8192_tx_enable(struct net_device
*dev
)
849 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
851 for (i
= 0; i
< MAX_TX_QUEUE_COUNT
; i
++)
852 write_nic_dword(dev
, TX_DESC_BASE
[i
], priv
->tx_ring
[i
].dma
);
854 ieee80211_reset_queue(priv
->ieee80211
);
858 static void rtl8192_free_rx_ring(struct net_device
*dev
)
860 struct r8192_priv
*priv
= ieee80211_priv(dev
);
863 for (i
= 0; i
< priv
->rxringcount
; i
++) {
864 struct sk_buff
*skb
= priv
->rx_buf
[i
];
868 pci_unmap_single(priv
->pdev
,
869 *((dma_addr_t
*)skb
->cb
),
870 priv
->rxbuffersize
, PCI_DMA_FROMDEVICE
);
874 pci_free_consistent(priv
->pdev
, sizeof(*priv
->rx_ring
) * priv
->rxringcount
,
875 priv
->rx_ring
, priv
->rx_ring_dma
);
876 priv
->rx_ring
= NULL
;
879 static void rtl8192_free_tx_ring(struct net_device
*dev
, unsigned int prio
)
881 struct r8192_priv
*priv
= ieee80211_priv(dev
);
882 struct rtl8192_tx_ring
*ring
= &priv
->tx_ring
[prio
];
884 while (skb_queue_len(&ring
->queue
)) {
885 tx_desc_819x_pci
*entry
= &ring
->desc
[ring
->idx
];
886 struct sk_buff
*skb
= __skb_dequeue(&ring
->queue
);
888 pci_unmap_single(priv
->pdev
, le32_to_cpu(entry
->TxBuffAddr
),
889 skb
->len
, PCI_DMA_TODEVICE
);
891 ring
->idx
= (ring
->idx
+ 1) % ring
->entries
;
894 pci_free_consistent(priv
->pdev
, sizeof(*ring
->desc
)*ring
->entries
,
895 ring
->desc
, ring
->dma
);
900 static void rtl8192_beacon_disable(struct net_device
*dev
)
902 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
905 reg
= read_nic_dword(priv
->ieee80211
->dev
,INTA_MASK
);
907 /* disable Beacon realted interrupt signal */
908 reg
&= ~(IMR_BcnInt
| IMR_BcnInt
| IMR_TBDOK
| IMR_TBDER
);
909 write_nic_dword(priv
->ieee80211
->dev
, INTA_MASK
, reg
);
912 void rtl8192_rtx_disable(struct net_device
*dev
)
915 struct r8192_priv
*priv
= ieee80211_priv(dev
);
918 cmd
=read_nic_byte(dev
,CMDR
);
919 // if(!priv->ieee80211->bSupportRemoteWakeUp) {
920 write_nic_byte(dev
, CMDR
, cmd
&~ \
923 force_pci_posting(dev
);
926 for(i
= 0; i
< MAX_QUEUE_SIZE
; i
++) {
927 skb_queue_purge(&priv
->ieee80211
->skb_waitQ
[i
]);
929 for(i
= 0; i
< MAX_QUEUE_SIZE
; i
++) {
930 skb_queue_purge(&priv
->ieee80211
->skb_aggQ
[i
]);
934 skb_queue_purge(&priv
->skb_queue
);
938 static void rtl8192_reset(struct net_device
*dev
)
940 rtl8192_irq_disable(dev
);
941 printk("This is RTL819xP Reset procedure\n");
944 static u16 rtl_rate
[] = {10,20,55,110,60,90,120,180,240,360,480,540};
945 inline u16
rtl8192_rate2rate(short rate
)
947 if (rate
>11) return 0;
948 return rtl_rate
[rate
];
954 static void rtl8192_data_hard_stop(struct net_device
*dev
)
958 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
959 priv
->dma_poll_mask
|= (1<<TX_DMA_STOP_LOWPRIORITY_SHIFT
);
960 rtl8192_set_mode(dev
,EPROM_CMD_CONFIG
);
961 write_nic_byte(dev
,TX_DMA_POLLING
,priv
->dma_poll_mask
);
962 rtl8192_set_mode(dev
,EPROM_CMD_NORMAL
);
967 static void rtl8192_data_hard_resume(struct net_device
*dev
)
971 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
972 priv
->dma_poll_mask
&= ~(1<<TX_DMA_STOP_LOWPRIORITY_SHIFT
);
973 rtl8192_set_mode(dev
,EPROM_CMD_CONFIG
);
974 write_nic_byte(dev
,TX_DMA_POLLING
,priv
->dma_poll_mask
);
975 rtl8192_set_mode(dev
,EPROM_CMD_NORMAL
);
979 /* this function TX data frames when the ieee80211 stack requires this.
980 * It checks also if we need to stop the ieee tx queue, eventually do it
982 static void rtl8192_hard_data_xmit(struct sk_buff
*skb
, struct net_device
*dev
, int rate
)
984 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
986 //unsigned long flags;
987 cb_desc
*tcb_desc
= (cb_desc
*)(skb
->cb
+ MAX_DEV_ADDR_SIZE
);
988 u8 queue_index
= tcb_desc
->queue_index
;
989 /* shall not be referred by command packet */
990 assert(queue_index
!= TXCMD_QUEUE
);
992 //spin_lock_irqsave(&priv->tx_lock,flags);
994 memcpy((unsigned char *)(skb
->cb
),&dev
,sizeof(dev
));
996 tcb_desc
->RATRIndex
= 7;
997 tcb_desc
->bTxDisableRateFallBack
= 1;
998 tcb_desc
->bTxUseDriverAssingedRate
= 1;
999 tcb_desc
->bTxEnableFwCalcDur
= 1;
1001 skb_push(skb
, priv
->ieee80211
->tx_headroom
);
1002 ret
= rtl8192_tx(dev
, skb
);
1008 if(queue_index
!=MGNT_QUEUE
) {
1009 priv
->ieee80211
->stats
.tx_bytes
+=(skb
->len
- priv
->ieee80211
->tx_headroom
);
1010 priv
->ieee80211
->stats
.tx_packets
++;
1013 //spin_unlock_irqrestore(&priv->tx_lock,flags);
1019 /* This is a rough attempt to TX a frame
1020 * This is called by the ieee 80211 stack to TX management frames.
1021 * If the ring is full packet are dropped (for data frame the queue
1022 * is stopped before this can happen).
1024 static int rtl8192_hard_start_xmit(struct sk_buff
*skb
,struct net_device
*dev
)
1026 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
1030 //unsigned long flags;
1031 cb_desc
*tcb_desc
= (cb_desc
*)(skb
->cb
+ MAX_DEV_ADDR_SIZE
);
1032 u8 queue_index
= tcb_desc
->queue_index
;
1035 //spin_lock_irqsave(&priv->tx_lock,flags);
1037 memcpy((unsigned char *)(skb
->cb
),&dev
,sizeof(dev
));
1038 if(queue_index
== TXCMD_QUEUE
) {
1039 // skb_push(skb, USB_HWDESC_HEADER_LEN);
1040 rtl819xE_tx_cmd(dev
, skb
);
1042 //spin_unlock_irqrestore(&priv->tx_lock,flags);
1045 // RT_TRACE(COMP_SEND, "To send management packet\n");
1046 tcb_desc
->RATRIndex
= 7;
1047 tcb_desc
->bTxDisableRateFallBack
= 1;
1048 tcb_desc
->bTxUseDriverAssingedRate
= 1;
1049 tcb_desc
->bTxEnableFwCalcDur
= 1;
1050 skb_push(skb
, priv
->ieee80211
->tx_headroom
);
1051 ret
= rtl8192_tx(dev
, skb
);
1057 // priv->ieee80211->stats.tx_bytes+=skb->len;
1058 // priv->ieee80211->stats.tx_packets++;
1060 //spin_unlock_irqrestore(&priv->tx_lock,flags);
1067 void rtl8192_try_wake_queue(struct net_device
*dev
, int pri
);
1069 static void rtl8192_tx_isr(struct net_device
*dev
, int prio
)
1071 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
1073 struct rtl8192_tx_ring
*ring
= &priv
->tx_ring
[prio
];
1075 while (skb_queue_len(&ring
->queue
)) {
1076 tx_desc_819x_pci
*entry
= &ring
->desc
[ring
->idx
];
1077 struct sk_buff
*skb
;
1079 /* beacon packet will only use the first descriptor defautly,
1080 * and the OWN may not be cleared by the hardware
1082 if(prio
!= BEACON_QUEUE
) {
1085 ring
->idx
= (ring
->idx
+ 1) % ring
->entries
;
1088 skb
= __skb_dequeue(&ring
->queue
);
1089 pci_unmap_single(priv
->pdev
, le32_to_cpu(entry
->TxBuffAddr
),
1090 skb
->len
, PCI_DMA_TODEVICE
);
1094 if (prio
== MGNT_QUEUE
){
1095 if (priv
->ieee80211
->ack_tx_to_ieee
){
1096 if (rtl8192_is_tx_queue_empty(dev
)){
1097 priv
->ieee80211
->ack_tx_to_ieee
= 0;
1098 ieee80211_ps_tx_ack(priv
->ieee80211
, 1);
1103 if(prio
!= BEACON_QUEUE
) {
1104 /* try to deal with the pending packets */
1105 tasklet_schedule(&priv
->irq_tx_tasklet
);
1110 static void rtl8192_stop_beacon(struct net_device
*dev
)
1112 //rtl8192_beacon_disable(dev);
1115 static void rtl8192_config_rate(struct net_device
* dev
, u16
* rate_config
)
1117 struct r8192_priv
*priv
= ieee80211_priv(dev
);
1118 struct ieee80211_network
*net
;
1119 u8 i
=0, basic_rate
= 0;
1120 net
= & priv
->ieee80211
->current_network
;
1122 for (i
=0; i
<net
->rates_len
; i
++)
1124 basic_rate
= net
->rates
[i
]&0x7f;
1127 case MGN_1M
: *rate_config
|= RRSR_1M
; break;
1128 case MGN_2M
: *rate_config
|= RRSR_2M
; break;
1129 case MGN_5_5M
: *rate_config
|= RRSR_5_5M
; break;
1130 case MGN_11M
: *rate_config
|= RRSR_11M
; break;
1131 case MGN_6M
: *rate_config
|= RRSR_6M
; break;
1132 case MGN_9M
: *rate_config
|= RRSR_9M
; break;
1133 case MGN_12M
: *rate_config
|= RRSR_12M
; break;
1134 case MGN_18M
: *rate_config
|= RRSR_18M
; break;
1135 case MGN_24M
: *rate_config
|= RRSR_24M
; break;
1136 case MGN_36M
: *rate_config
|= RRSR_36M
; break;
1137 case MGN_48M
: *rate_config
|= RRSR_48M
; break;
1138 case MGN_54M
: *rate_config
|= RRSR_54M
; break;
1141 for (i
=0; i
<net
->rates_ex_len
; i
++)
1143 basic_rate
= net
->rates_ex
[i
]&0x7f;
1146 case MGN_1M
: *rate_config
|= RRSR_1M
; break;
1147 case MGN_2M
: *rate_config
|= RRSR_2M
; break;
1148 case MGN_5_5M
: *rate_config
|= RRSR_5_5M
; break;
1149 case MGN_11M
: *rate_config
|= RRSR_11M
; break;
1150 case MGN_6M
: *rate_config
|= RRSR_6M
; break;
1151 case MGN_9M
: *rate_config
|= RRSR_9M
; break;
1152 case MGN_12M
: *rate_config
|= RRSR_12M
; break;
1153 case MGN_18M
: *rate_config
|= RRSR_18M
; break;
1154 case MGN_24M
: *rate_config
|= RRSR_24M
; break;
1155 case MGN_36M
: *rate_config
|= RRSR_36M
; break;
1156 case MGN_48M
: *rate_config
|= RRSR_48M
; break;
1157 case MGN_54M
: *rate_config
|= RRSR_54M
; break;
1163 #define SHORT_SLOT_TIME 9
1164 #define NON_SHORT_SLOT_TIME 20
1166 static void rtl8192_update_cap(struct net_device
* dev
, u16 cap
)
1169 struct r8192_priv
*priv
= ieee80211_priv(dev
);
1170 struct ieee80211_network
*net
= &priv
->ieee80211
->current_network
;
1171 priv
->short_preamble
= cap
& WLAN_CAPABILITY_SHORT_PREAMBLE
;
1172 tmp
= priv
->basic_rate
;
1173 if (priv
->short_preamble
)
1174 tmp
|= BRSR_AckShortPmb
;
1175 write_nic_dword(dev
, RRSR
, tmp
);
1177 if (net
->mode
& (IEEE_G
|IEEE_N_24G
))
1180 if ((cap
& WLAN_CAPABILITY_SHORT_SLOT
)&&(!priv
->ieee80211
->pHTInfo
->bCurrentRT2RTLongSlotTime
))
1182 slot_time
= SHORT_SLOT_TIME
;
1184 else //long slot time
1185 slot_time
= NON_SHORT_SLOT_TIME
;
1186 priv
->slot_time
= slot_time
;
1187 write_nic_byte(dev
, SLOT_TIME
, slot_time
);
1192 static void rtl8192_net_update(struct net_device
*dev
)
1195 struct r8192_priv
*priv
= ieee80211_priv(dev
);
1196 struct ieee80211_network
*net
;
1197 u16 BcnTimeCfg
= 0, BcnCW
= 6, BcnIFS
= 0xf;
1198 u16 rate_config
= 0;
1199 net
= &priv
->ieee80211
->current_network
;
1200 //update Basic rate: RR, BRSR
1201 rtl8192_config_rate(dev
, &rate_config
);
1202 // 2007.01.16, by Emily
1203 // Select RRSR (in Legacy-OFDM and CCK)
1204 // For 8190, we select only 24M, 12M, 6M, 11M, 5.5M, 2M, and 1M from the Basic rate.
1205 // We do not use other rates.
1206 priv
->basic_rate
= rate_config
&= 0x15f;
1208 write_nic_dword(dev
,BSSIDR
,((u32
*)net
->bssid
)[0]);
1209 write_nic_word(dev
,BSSIDR
+4,((u16
*)net
->bssid
)[2]);
1212 rtl8192_update_msr(dev
);
1216 // rtl8192_update_cap(dev, net->capability);
1217 if (priv
->ieee80211
->iw_mode
== IW_MODE_ADHOC
)
1219 write_nic_word(dev
, ATIMWND
, 2);
1220 write_nic_word(dev
, BCN_DMATIME
, 256);
1221 write_nic_word(dev
, BCN_INTERVAL
, net
->beacon_interval
);
1222 // write_nic_word(dev, BcnIntTime, 100);
1223 //BIT15 of BCN_DRV_EARLY_INT will indicate whether software beacon or hw beacon is applied.
1224 write_nic_word(dev
, BCN_DRV_EARLY_INT
, 10);
1225 write_nic_byte(dev
, BCN_ERR_THRESH
, 100);
1227 BcnTimeCfg
|= (BcnCW
<<BCN_TCFG_CW_SHIFT
);
1228 // TODO: BcnIFS may required to be changed on ASIC
1229 BcnTimeCfg
|= BcnIFS
<<BCN_TCFG_IFS
;
1231 write_nic_word(dev
, BCN_TCFG
, BcnTimeCfg
);
1237 void rtl819xE_tx_cmd(struct net_device
*dev
, struct sk_buff
*skb
)
1239 struct r8192_priv
*priv
= ieee80211_priv(dev
);
1240 struct rtl8192_tx_ring
*ring
;
1241 tx_desc_819x_pci
*entry
;
1245 unsigned long flags
;
1247 ring
= &priv
->tx_ring
[TXCMD_QUEUE
];
1248 mapping
= pci_map_single(priv
->pdev
, skb
->data
, skb
->len
, PCI_DMA_TODEVICE
);
1250 spin_lock_irqsave(&priv
->irq_th_lock
,flags
);
1251 idx
= (ring
->idx
+ skb_queue_len(&ring
->queue
)) % ring
->entries
;
1252 entry
= &ring
->desc
[idx
];
1254 tcb_desc
= (cb_desc
*)(skb
->cb
+ MAX_DEV_ADDR_SIZE
);
1256 entry
->LINIP
= tcb_desc
->bLastIniPkt
;
1257 entry
->FirstSeg
= 1;//first segment
1258 entry
->LastSeg
= 1; //last segment
1259 if(tcb_desc
->bCmdOrInit
== DESC_PACKET_TYPE_INIT
) {
1260 entry
->CmdInit
= DESC_PACKET_TYPE_INIT
;
1262 entry
->CmdInit
= DESC_PACKET_TYPE_NORMAL
;
1263 entry
->Offset
= sizeof(TX_FWINFO_8190PCI
) + 8;
1264 entry
->PktSize
= (u16
)(tcb_desc
->pkt_size
+ entry
->Offset
);
1265 entry
->QueueSelect
= QSLT_CMD
;
1266 entry
->TxFWInfoSize
= 0x08;
1267 entry
->RATid
= (u8
)DESC_PACKET_TYPE_INIT
;
1269 entry
->TxBufferSize
= skb
->len
;
1270 entry
->TxBuffAddr
= cpu_to_le32(mapping
);
1273 #ifdef JOHN_DUMP_TXDESC
1275 tx_desc_819x_pci
*entry1
= &ring
->desc
[0];
1276 unsigned int *ptr
= (unsigned int *)entry1
;
1277 printk("<Tx descriptor>:\n");
1278 for (i
= 0; i
< 8; i
++)
1279 printk("%8x ", ptr
[i
]);
1283 __skb_queue_tail(&ring
->queue
, skb
);
1284 spin_unlock_irqrestore(&priv
->irq_th_lock
,flags
);
1286 write_nic_byte(dev
, TPPoll
, TPPoll_CQ
);
1292 * Mapping Software/Hardware descriptor queue id to "Queue Select Field"
1293 * in TxFwInfo data structure
1294 * 2006.10.30 by Emily
1296 * \param QUEUEID Software Queue
1298 static u8
MapHwQueueToFirmwareQueue(u8 QueueID
)
1300 u8 QueueSelect
= 0x0; //defualt set to
1304 QueueSelect
= QSLT_BE
; //or QSelect = pTcb->priority;
1308 QueueSelect
= QSLT_BK
; //or QSelect = pTcb->priority;
1312 QueueSelect
= QSLT_VO
; //or QSelect = pTcb->priority;
1316 QueueSelect
= QSLT_VI
; //or QSelect = pTcb->priority;
1319 QueueSelect
= QSLT_MGNT
;
1323 QueueSelect
= QSLT_BEACON
;
1326 // TODO: 2006.10.30 mark other queue selection until we verify it is OK
1327 // TODO: Remove Assertions
1328 //#if (RTL819X_FPGA_VER & RTL819X_FPGA_GUANGAN_070502)
1330 QueueSelect
= QSLT_CMD
;
1334 //QueueSelect = QSLT_HIGH;
1338 RT_TRACE(COMP_ERR
, "TransmitTCB(): Impossible Queue Selection: %d \n", QueueID
);
1344 static u8
MRateToHwRate8190Pci(u8 rate
)
1346 u8 ret
= DESC90_RATE1M
;
1349 case MGN_1M
: ret
= DESC90_RATE1M
; break;
1350 case MGN_2M
: ret
= DESC90_RATE2M
; break;
1351 case MGN_5_5M
: ret
= DESC90_RATE5_5M
; break;
1352 case MGN_11M
: ret
= DESC90_RATE11M
; break;
1353 case MGN_6M
: ret
= DESC90_RATE6M
; break;
1354 case MGN_9M
: ret
= DESC90_RATE9M
; break;
1355 case MGN_12M
: ret
= DESC90_RATE12M
; break;
1356 case MGN_18M
: ret
= DESC90_RATE18M
; break;
1357 case MGN_24M
: ret
= DESC90_RATE24M
; break;
1358 case MGN_36M
: ret
= DESC90_RATE36M
; break;
1359 case MGN_48M
: ret
= DESC90_RATE48M
; break;
1360 case MGN_54M
: ret
= DESC90_RATE54M
; break;
1362 // HT rate since here
1363 case MGN_MCS0
: ret
= DESC90_RATEMCS0
; break;
1364 case MGN_MCS1
: ret
= DESC90_RATEMCS1
; break;
1365 case MGN_MCS2
: ret
= DESC90_RATEMCS2
; break;
1366 case MGN_MCS3
: ret
= DESC90_RATEMCS3
; break;
1367 case MGN_MCS4
: ret
= DESC90_RATEMCS4
; break;
1368 case MGN_MCS5
: ret
= DESC90_RATEMCS5
; break;
1369 case MGN_MCS6
: ret
= DESC90_RATEMCS6
; break;
1370 case MGN_MCS7
: ret
= DESC90_RATEMCS7
; break;
1371 case MGN_MCS8
: ret
= DESC90_RATEMCS8
; break;
1372 case MGN_MCS9
: ret
= DESC90_RATEMCS9
; break;
1373 case MGN_MCS10
: ret
= DESC90_RATEMCS10
; break;
1374 case MGN_MCS11
: ret
= DESC90_RATEMCS11
; break;
1375 case MGN_MCS12
: ret
= DESC90_RATEMCS12
; break;
1376 case MGN_MCS13
: ret
= DESC90_RATEMCS13
; break;
1377 case MGN_MCS14
: ret
= DESC90_RATEMCS14
; break;
1378 case MGN_MCS15
: ret
= DESC90_RATEMCS15
; break;
1379 case (0x80|0x20): ret
= DESC90_RATEMCS32
; break;
1387 static u8
QueryIsShort(u8 TxHT
, u8 TxRate
, cb_desc
*tcb_desc
)
1391 tmp_Short
= (TxHT
==1)?((tcb_desc
->bUseShortGI
)?1:0):((tcb_desc
->bUseShortPreamble
)?1:0);
1393 if(TxHT
==1 && TxRate
!= DESC90_RATEMCS15
)
1400 * The tx procedure is just as following,
1401 * skb->cb will contain all the following information,
1402 * priority, morefrag, rate, &dev.
1404 short rtl8192_tx(struct net_device
*dev
, struct sk_buff
* skb
)
1406 struct r8192_priv
*priv
= ieee80211_priv(dev
);
1407 struct rtl8192_tx_ring
*ring
;
1408 unsigned long flags
;
1409 cb_desc
*tcb_desc
= (cb_desc
*)(skb
->cb
+ MAX_DEV_ADDR_SIZE
);
1410 tx_desc_819x_pci
*pdesc
= NULL
;
1411 TX_FWINFO_8190PCI
*pTxFwInfo
= NULL
;
1413 bool multi_addr
=false,broad_addr
=false,uni_addr
=false;
1414 u8
* pda_addr
= NULL
;
1417 mapping
= pci_map_single(priv
->pdev
, skb
->data
, skb
->len
, PCI_DMA_TODEVICE
);
1418 /* collect the tx packets statitcs */
1419 pda_addr
= ((u8
*)skb
->data
) + sizeof(TX_FWINFO_8190PCI
);
1420 if(is_multicast_ether_addr(pda_addr
))
1422 else if(is_broadcast_ether_addr(pda_addr
))
1428 priv
->stats
.txbytesunicast
+= (u8
)(skb
->len
) - sizeof(TX_FWINFO_8190PCI
);
1430 priv
->stats
.txbytesmulticast
+=(u8
)(skb
->len
) - sizeof(TX_FWINFO_8190PCI
);
1432 priv
->stats
.txbytesbroadcast
+= (u8
)(skb
->len
) - sizeof(TX_FWINFO_8190PCI
);
1434 /* fill tx firmware */
1435 pTxFwInfo
= (PTX_FWINFO_8190PCI
)skb
->data
;
1436 memset(pTxFwInfo
,0,sizeof(TX_FWINFO_8190PCI
));
1437 pTxFwInfo
->TxHT
= (tcb_desc
->data_rate
&0x80)?1:0;
1438 pTxFwInfo
->TxRate
= MRateToHwRate8190Pci((u8
)tcb_desc
->data_rate
);
1439 pTxFwInfo
->EnableCPUDur
= tcb_desc
->bTxEnableFwCalcDur
;
1440 pTxFwInfo
->Short
= QueryIsShort(pTxFwInfo
->TxHT
, pTxFwInfo
->TxRate
, tcb_desc
);
1442 /* Aggregation related */
1443 if(tcb_desc
->bAMPDUEnable
) {
1444 pTxFwInfo
->AllowAggregation
= 1;
1445 pTxFwInfo
->RxMF
= tcb_desc
->ampdu_factor
;
1446 pTxFwInfo
->RxAMD
= tcb_desc
->ampdu_density
;
1448 pTxFwInfo
->AllowAggregation
= 0;
1449 pTxFwInfo
->RxMF
= 0;
1450 pTxFwInfo
->RxAMD
= 0;
1454 // Protection mode related
1456 pTxFwInfo
->RtsEnable
= (tcb_desc
->bRTSEnable
)?1:0;
1457 pTxFwInfo
->CtsEnable
= (tcb_desc
->bCTSEnable
)?1:0;
1458 pTxFwInfo
->RtsSTBC
= (tcb_desc
->bRTSSTBC
)?1:0;
1459 pTxFwInfo
->RtsHT
= (tcb_desc
->rts_rate
&0x80)?1:0;
1460 pTxFwInfo
->RtsRate
= MRateToHwRate8190Pci((u8
)tcb_desc
->rts_rate
);
1461 pTxFwInfo
->RtsBandwidth
= 0;
1462 pTxFwInfo
->RtsSubcarrier
= tcb_desc
->RTSSC
;
1463 pTxFwInfo
->RtsShort
= (pTxFwInfo
->RtsHT
==0)?(tcb_desc
->bRTSUseShortPreamble
?1:0):(tcb_desc
->bRTSUseShortGI
?1:0);
1465 // Set Bandwidth and sub-channel settings.
1467 if(priv
->CurrentChannelBW
== HT_CHANNEL_WIDTH_20_40
)
1469 if(tcb_desc
->bPacketBW
)
1471 pTxFwInfo
->TxBandwidth
= 1;
1473 pTxFwInfo
->TxSubCarrier
= 3;
1475 pTxFwInfo
->TxSubCarrier
= 0; //By SD3's Jerry suggestion, use duplicated mode, cosa 04012008
1480 pTxFwInfo
->TxBandwidth
= 0;
1481 pTxFwInfo
->TxSubCarrier
= priv
->nCur40MhzPrimeSC
;
1484 pTxFwInfo
->TxBandwidth
= 0;
1485 pTxFwInfo
->TxSubCarrier
= 0;
1490 /* 2007/07/25 MH Copy current TX FW info.*/
1491 memcpy((void*)(&Tmp_TxFwInfo
), (void*)(pTxFwInfo
), sizeof(TX_FWINFO_8190PCI
));
1492 printk("&&&&&&&&&&&&&&&&&&&&&&====>print out fwinf\n");
1493 printk("===>enable fwcacl:%d\n", Tmp_TxFwInfo
.EnableCPUDur
);
1494 printk("===>RTS STBC:%d\n", Tmp_TxFwInfo
.RtsSTBC
);
1495 printk("===>RTS Subcarrier:%d\n", Tmp_TxFwInfo
.RtsSubcarrier
);
1496 printk("===>Allow Aggregation:%d\n", Tmp_TxFwInfo
.AllowAggregation
);
1497 printk("===>TX HT bit:%d\n", Tmp_TxFwInfo
.TxHT
);
1498 printk("===>Tx rate:%d\n", Tmp_TxFwInfo
.TxRate
);
1499 printk("===>Received AMPDU Density:%d\n", Tmp_TxFwInfo
.RxAMD
);
1500 printk("===>Received MPDU Factor:%d\n", Tmp_TxFwInfo
.RxMF
);
1501 printk("===>TxBandwidth:%d\n", Tmp_TxFwInfo
.TxBandwidth
);
1502 printk("===>TxSubCarrier:%d\n", Tmp_TxFwInfo
.TxSubCarrier
);
1504 printk("<=====**********************out of print\n");
1507 spin_lock_irqsave(&priv
->irq_th_lock
,flags
);
1508 ring
= &priv
->tx_ring
[tcb_desc
->queue_index
];
1509 if (tcb_desc
->queue_index
!= BEACON_QUEUE
) {
1510 idx
= (ring
->idx
+ skb_queue_len(&ring
->queue
)) % ring
->entries
;
1515 pdesc
= &ring
->desc
[idx
];
1516 if((pdesc
->OWN
== 1) && (tcb_desc
->queue_index
!= BEACON_QUEUE
)) {
1517 RT_TRACE(COMP_ERR
,"No more TX desc@%d, ring->idx = %d,idx = %d,%x", \
1518 tcb_desc
->queue_index
,ring
->idx
, idx
,skb
->len
);
1522 /* fill tx descriptor */
1523 memset((u8
*)pdesc
,0,12);
1527 pdesc
->Offset
= sizeof(TX_FWINFO_8190PCI
) + 8; //We must add 8!! Emily
1528 pdesc
->PktSize
= (u16
)skb
->len
-sizeof(TX_FWINFO_8190PCI
);
1532 pdesc
->RATid
= tcb_desc
->RATRIndex
;
1536 pdesc
->SecType
= 0x0;
1537 if (tcb_desc
->bHwSec
) {
1540 printk("==>================hw sec\n");
1543 switch (priv
->ieee80211
->pairwise_key_type
) {
1544 case KEY_TYPE_WEP40
:
1545 case KEY_TYPE_WEP104
:
1546 pdesc
->SecType
= 0x1;
1550 pdesc
->SecType
= 0x2;
1554 pdesc
->SecType
= 0x3;
1558 pdesc
->SecType
= 0x0;
1569 pdesc
->QueueSelect
= MapHwQueueToFirmwareQueue(tcb_desc
->queue_index
);
1570 pdesc
->TxFWInfoSize
= sizeof(TX_FWINFO_8190PCI
);
1572 pdesc
->DISFB
= tcb_desc
->bTxDisableRateFallBack
;
1573 pdesc
->USERATE
= tcb_desc
->bTxUseDriverAssingedRate
;
1577 pdesc
->TxBufferSize
= skb
->len
;
1579 pdesc
->TxBuffAddr
= cpu_to_le32(mapping
);
1580 __skb_queue_tail(&ring
->queue
, skb
);
1582 spin_unlock_irqrestore(&priv
->irq_th_lock
,flags
);
1583 dev
->trans_start
= jiffies
;
1584 write_nic_word(dev
,TPPoll
,0x01<<tcb_desc
->queue_index
);
1588 static short rtl8192_alloc_rx_desc_ring(struct net_device
*dev
)
1590 struct r8192_priv
*priv
= ieee80211_priv(dev
);
1591 rx_desc_819x_pci
*entry
= NULL
;
1594 priv
->rx_ring
= pci_alloc_consistent(priv
->pdev
,
1595 sizeof(*priv
->rx_ring
) * priv
->rxringcount
, &priv
->rx_ring_dma
);
1597 if (!priv
->rx_ring
|| (unsigned long)priv
->rx_ring
& 0xFF) {
1598 RT_TRACE(COMP_ERR
,"Cannot allocate RX ring\n");
1602 memset(priv
->rx_ring
, 0, sizeof(*priv
->rx_ring
) * priv
->rxringcount
);
1605 for (i
= 0; i
< priv
->rxringcount
; i
++) {
1606 struct sk_buff
*skb
= dev_alloc_skb(priv
->rxbuffersize
);
1607 dma_addr_t
*mapping
;
1608 entry
= &priv
->rx_ring
[i
];
1611 priv
->rx_buf
[i
] = skb
;
1612 mapping
= (dma_addr_t
*)skb
->cb
;
1613 *mapping
= pci_map_single(priv
->pdev
, skb
->tail
,//skb_tail_pointer(skb),
1614 priv
->rxbuffersize
, PCI_DMA_FROMDEVICE
);
1616 entry
->BufferAddress
= cpu_to_le32(*mapping
);
1618 entry
->Length
= priv
->rxbuffersize
;
1626 static int rtl8192_alloc_tx_desc_ring(struct net_device
*dev
,
1627 unsigned int prio
, unsigned int entries
)
1629 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
1630 tx_desc_819x_pci
*ring
;
1634 ring
= pci_alloc_consistent(priv
->pdev
, sizeof(*ring
) * entries
, &dma
);
1635 if (!ring
|| (unsigned long)ring
& 0xFF) {
1636 RT_TRACE(COMP_ERR
, "Cannot allocate TX ring (prio = %d)\n", prio
);
1640 memset(ring
, 0, sizeof(*ring
)*entries
);
1641 priv
->tx_ring
[prio
].desc
= ring
;
1642 priv
->tx_ring
[prio
].dma
= dma
;
1643 priv
->tx_ring
[prio
].idx
= 0;
1644 priv
->tx_ring
[prio
].entries
= entries
;
1645 skb_queue_head_init(&priv
->tx_ring
[prio
].queue
);
1647 for (i
= 0; i
< entries
; i
++)
1648 ring
[i
].NextDescAddress
=
1649 cpu_to_le32((u32
)dma
+ ((i
+ 1) % entries
) * sizeof(*ring
));
1655 static short rtl8192_pci_initdescring(struct net_device
*dev
)
1659 struct r8192_priv
*priv
= ieee80211_priv(dev
);
1661 ret
= rtl8192_alloc_rx_desc_ring(dev
);
1667 /* general process for other queue */
1668 for (i
= 0; i
< MAX_TX_QUEUE_COUNT
; i
++) {
1669 if ((ret
= rtl8192_alloc_tx_desc_ring(dev
, i
, priv
->txringcount
)))
1670 goto err_free_rings
;
1674 /* specific process for hardware beacon process */
1675 if ((ret
= rtl8192_alloc_tx_desc_ring(dev
, MAX_TX_QUEUE_COUNT
- 1, 2)))
1676 goto err_free_rings
;
1682 rtl8192_free_rx_ring(dev
);
1683 for (i
= 0; i
< MAX_TX_QUEUE_COUNT
; i
++)
1684 if (priv
->tx_ring
[i
].desc
)
1685 rtl8192_free_tx_ring(dev
, i
);
1689 static void rtl8192_pci_resetdescring(struct net_device
*dev
)
1691 struct r8192_priv
*priv
= ieee80211_priv(dev
);
1694 /* force the rx_idx to the first one */
1696 rx_desc_819x_pci
*entry
= NULL
;
1697 for (i
= 0; i
< priv
->rxringcount
; i
++) {
1698 entry
= &priv
->rx_ring
[i
];
1704 /* after reset, release previous pending packet, and force the
1705 * tx idx to the first one */
1706 for (i
= 0; i
< MAX_TX_QUEUE_COUNT
; i
++) {
1707 if (priv
->tx_ring
[i
].desc
) {
1708 struct rtl8192_tx_ring
*ring
= &priv
->tx_ring
[i
];
1710 while (skb_queue_len(&ring
->queue
)) {
1711 tx_desc_819x_pci
*entry
= &ring
->desc
[ring
->idx
];
1712 struct sk_buff
*skb
= __skb_dequeue(&ring
->queue
);
1714 pci_unmap_single(priv
->pdev
, le32_to_cpu(entry
->TxBuffAddr
),
1715 skb
->len
, PCI_DMA_TODEVICE
);
1717 ring
->idx
= (ring
->idx
+ 1) % ring
->entries
;
1725 extern void rtl8192_update_ratr_table(struct net_device
* dev
);
1726 static void rtl8192_link_change(struct net_device
*dev
)
1730 struct r8192_priv
*priv
= ieee80211_priv(dev
);
1731 struct ieee80211_device
* ieee
= priv
->ieee80211
;
1732 //write_nic_word(dev, BCN_INTR_ITV, net->beacon_interval);
1733 if (ieee
->state
== IEEE80211_LINKED
)
1735 rtl8192_net_update(dev
);
1736 rtl8192_update_ratr_table(dev
);
1738 //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
1739 if ((KEY_TYPE_WEP40
== ieee
->pairwise_key_type
) || (KEY_TYPE_WEP104
== ieee
->pairwise_key_type
))
1740 EnableHWSecurityConfig8192(dev
);
1745 write_nic_byte(dev
, 0x173, 0);
1747 /*update timing params*/
1748 //rtl8192_set_chan(dev, priv->chan);
1750 rtl8192_update_msr(dev
);
1752 // 2007/10/16 MH MAC Will update TSF according to all received beacon, so we have
1753 // // To set CBSSID bit when link with any AP or STA.
1754 if (ieee
->iw_mode
== IW_MODE_INFRA
|| ieee
->iw_mode
== IW_MODE_ADHOC
)
1757 reg
= read_nic_dword(dev
, RCR
);
1758 if (priv
->ieee80211
->state
== IEEE80211_LINKED
)
1759 priv
->ReceiveConfig
= reg
|= RCR_CBSSID
;
1761 priv
->ReceiveConfig
= reg
&= ~RCR_CBSSID
;
1762 write_nic_dword(dev
, RCR
, reg
);
1768 static struct ieee80211_qos_parameters def_qos_parameters
= {
1769 {3,3,3,3},/* cw_min */
1770 {7,7,7,7},/* cw_max */
1771 {2,2,2,2},/* aifs */
1772 {0,0,0,0},/* flags */
1773 {0,0,0,0} /* tx_op_limit */
1776 #if LINUX_VERSION_CODE >=KERNEL_VERSION(2,6,20)
1777 static void rtl8192_update_beacon(struct work_struct
* work
)
1779 struct r8192_priv
*priv
= container_of(work
, struct r8192_priv
, update_beacon_wq
.work
);
1780 struct net_device
*dev
= priv
->ieee80211
->dev
;
1782 void rtl8192_update_beacon(struct net_device
*dev
)
1784 struct r8192_priv
*priv
= ieee80211_priv(dev
);
1786 struct ieee80211_device
* ieee
= priv
->ieee80211
;
1787 struct ieee80211_network
* net
= &ieee
->current_network
;
1789 if (ieee
->pHTInfo
->bCurrentHTSupport
)
1790 HTUpdateSelfAndPeerSetting(ieee
, net
);
1791 ieee
->pHTInfo
->bCurrentRT2RTLongSlotTime
= net
->bssht
.bdRT2RTLongSlotTime
;
1792 rtl8192_update_cap(dev
, net
->capability
);
1795 * background support to run QoS activate functionality
1797 static int WDCAPARA_ADD
[] = {EDCAPARA_BE
,EDCAPARA_BK
,EDCAPARA_VI
,EDCAPARA_VO
};
1798 #if LINUX_VERSION_CODE >=KERNEL_VERSION(2,6,20)
1799 static void rtl8192_qos_activate(struct work_struct
* work
)
1801 struct r8192_priv
*priv
= container_of(work
, struct r8192_priv
, qos_activate
);
1802 struct net_device
*dev
= priv
->ieee80211
->dev
;
1804 void rtl8192_qos_activate(struct net_device
*dev
)
1806 struct r8192_priv
*priv
= ieee80211_priv(dev
);
1808 struct ieee80211_qos_parameters
*qos_parameters
= &priv
->ieee80211
->current_network
.qos_data
.parameters
;
1809 u8 mode
= priv
->ieee80211
->current_network
.mode
;
1810 // u32 size = sizeof(struct ieee80211_qos_parameters);
1817 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16))
1820 mutex_lock(&priv
->mutex
);
1822 if(priv
->ieee80211
->state
!= IEEE80211_LINKED
)
1824 RT_TRACE(COMP_QOS
,"qos active process with associate response received\n");
1825 /* It better set slot time at first */
1826 /* For we just support b/g mode at present, let the slot time at 9/20 selection */
1827 /* update the ac parameter to related registers */
1828 for(i
= 0; i
< QOS_QUEUE_NUM
; i
++) {
1829 //Mode G/A: slotTimeTimer = 9; Mode B: 20
1830 u1bAIFS
= qos_parameters
->aifs
[i
] * ((mode
&(IEEE_G
|IEEE_N_24G
)) ?9:20) + aSifsTime
;
1831 u4bAcParam
= ((((u32
)(qos_parameters
->tx_op_limit
[i
]))<< AC_PARAM_TXOP_LIMIT_OFFSET
)|
1832 (((u32
)(qos_parameters
->cw_max
[i
]))<< AC_PARAM_ECW_MAX_OFFSET
)|
1833 (((u32
)(qos_parameters
->cw_min
[i
]))<< AC_PARAM_ECW_MIN_OFFSET
)|
1834 ((u32
)u1bAIFS
<< AC_PARAM_AIFS_OFFSET
));
1835 printk("===>u4bAcParam:%x, ", u4bAcParam
);
1836 write_nic_dword(dev
, WDCAPARA_ADD
[i
], u4bAcParam
);
1837 //write_nic_dword(dev, WDCAPARA_ADD[i], 0x005e4332);
1841 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16))
1844 mutex_unlock(&priv
->mutex
);
1848 static int rtl8192_qos_handle_probe_response(struct r8192_priv
*priv
,
1850 struct ieee80211_network
*network
)
1853 u32 size
= sizeof(struct ieee80211_qos_parameters
);
1855 if(priv
->ieee80211
->state
!=IEEE80211_LINKED
)
1858 if ((priv
->ieee80211
->iw_mode
!= IW_MODE_INFRA
))
1861 if (network
->flags
& NETWORK_HAS_QOS_MASK
) {
1862 if (active_network
&&
1863 (network
->flags
& NETWORK_HAS_QOS_PARAMETERS
))
1864 network
->qos_data
.active
= network
->qos_data
.supported
;
1866 if ((network
->qos_data
.active
== 1) && (active_network
== 1) &&
1867 (network
->flags
& NETWORK_HAS_QOS_PARAMETERS
) &&
1868 (network
->qos_data
.old_param_count
!=
1869 network
->qos_data
.param_count
)) {
1870 network
->qos_data
.old_param_count
=
1871 network
->qos_data
.param_count
;
1872 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
1873 queue_work(priv
->priv_wq
, &priv
->qos_activate
);
1875 schedule_task(&priv
->qos_activate
);
1877 RT_TRACE (COMP_QOS
, "QoS parameters change call "
1881 memcpy(&priv
->ieee80211
->current_network
.qos_data
.parameters
,\
1882 &def_qos_parameters
, size
);
1884 if ((network
->qos_data
.active
== 1) && (active_network
== 1)) {
1885 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
1886 queue_work(priv
->priv_wq
, &priv
->qos_activate
);
1888 schedule_task(&priv
->qos_activate
);
1890 RT_TRACE(COMP_QOS
, "QoS was disabled call qos_activate \n");
1892 network
->qos_data
.active
= 0;
1893 network
->qos_data
.supported
= 0;
1899 /* handle manage frame frame beacon and probe response */
1900 static int rtl8192_handle_beacon(struct net_device
* dev
,
1901 struct ieee80211_beacon
* beacon
,
1902 struct ieee80211_network
* network
)
1904 struct r8192_priv
*priv
= ieee80211_priv(dev
);
1906 rtl8192_qos_handle_probe_response(priv
,1,network
);
1908 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
1909 queue_delayed_work(priv
->priv_wq
, &priv
->update_beacon_wq
, 0);
1911 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
1912 schedule_task(&priv
->update_beacon_wq
);
1914 queue_work(priv
->priv_wq
, &priv
->update_beacon_wq
);
1922 * handling the beaconing responses. if we get different QoS setting
1923 * off the network from the associated setting, adjust the QoS
1926 static int rtl8192_qos_association_resp(struct r8192_priv
*priv
,
1927 struct ieee80211_network
*network
)
1930 unsigned long flags
;
1931 u32 size
= sizeof(struct ieee80211_qos_parameters
);
1932 int set_qos_param
= 0;
1934 if ((priv
== NULL
) || (network
== NULL
))
1937 if(priv
->ieee80211
->state
!=IEEE80211_LINKED
)
1940 if ((priv
->ieee80211
->iw_mode
!= IW_MODE_INFRA
))
1943 spin_lock_irqsave(&priv
->ieee80211
->lock
, flags
);
1944 if(network
->flags
& NETWORK_HAS_QOS_PARAMETERS
) {
1945 memcpy(&priv
->ieee80211
->current_network
.qos_data
.parameters
,\
1946 &network
->qos_data
.parameters
,\
1947 sizeof(struct ieee80211_qos_parameters
));
1948 priv
->ieee80211
->current_network
.qos_data
.active
= 1;
1950 if((priv
->ieee80211
->current_network
.qos_data
.param_count
!= \
1951 network
->qos_data
.param_count
))
1955 /* update qos parameter for current network */
1956 priv
->ieee80211
->current_network
.qos_data
.old_param_count
= \
1957 priv
->ieee80211
->current_network
.qos_data
.param_count
;
1958 priv
->ieee80211
->current_network
.qos_data
.param_count
= \
1959 network
->qos_data
.param_count
;
1962 memcpy(&priv
->ieee80211
->current_network
.qos_data
.parameters
,\
1963 &def_qos_parameters
, size
);
1964 priv
->ieee80211
->current_network
.qos_data
.active
= 0;
1965 priv
->ieee80211
->current_network
.qos_data
.supported
= 0;
1969 spin_unlock_irqrestore(&priv
->ieee80211
->lock
, flags
);
1971 RT_TRACE(COMP_QOS
, "%s: network->flags = %d,%d\n",__FUNCTION__
,network
->flags
,priv
->ieee80211
->current_network
.qos_data
.active
);
1972 if (set_qos_param
== 1)
1973 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
1974 queue_work(priv
->priv_wq
, &priv
->qos_activate
);
1976 schedule_task(&priv
->qos_activate
);
1984 static int rtl8192_handle_assoc_response(struct net_device
*dev
,
1985 struct ieee80211_assoc_response_frame
*resp
,
1986 struct ieee80211_network
*network
)
1988 struct r8192_priv
*priv
= ieee80211_priv(dev
);
1989 rtl8192_qos_association_resp(priv
, network
);
1994 //updateRATRTabel for MCS only. Basic rate is not implement.
1995 void rtl8192_update_ratr_table(struct net_device
* dev
)
1996 // POCTET_STRING posLegacyRate,
1998 // PRT_WLAN_STA pEntry)
2000 struct r8192_priv
* priv
= ieee80211_priv(dev
);
2001 struct ieee80211_device
* ieee
= priv
->ieee80211
;
2002 u8
* pMcsRate
= ieee
->dot11HTOperationalRateSet
;
2003 //struct ieee80211_network *net = &ieee->current_network;
2007 rtl8192_config_rate(dev
, (u16
*)(&ratr_value
));
2008 ratr_value
|= (*(u16
*)(pMcsRate
)) << 12;
2009 // switch (net->mode)
2013 ratr_value
&= 0x00000FF0;
2016 ratr_value
&= 0x0000000F;
2019 ratr_value
&= 0x00000FF7;
2023 if (ieee
->pHTInfo
->PeerMimoPs
== 0) //MIMO_PS_STATIC
2024 ratr_value
&= 0x0007F007;
2026 if (priv
->rf_type
== RF_1T2R
)
2027 ratr_value
&= 0x000FF007;
2029 ratr_value
&= 0x0F81F007;
2035 ratr_value
&= 0x0FFFFFFF;
2036 if(ieee
->pHTInfo
->bCurTxBW40MHz
&& ieee
->pHTInfo
->bCurShortGI40MHz
){
2037 ratr_value
|= 0x80000000;
2038 }else if(!ieee
->pHTInfo
->bCurTxBW40MHz
&& ieee
->pHTInfo
->bCurShortGI20MHz
){
2039 ratr_value
|= 0x80000000;
2041 write_nic_dword(dev
, RATR0
+rate_index
*4, ratr_value
);
2042 write_nic_byte(dev
, UFWP
, 1);
2045 static u8 ccmp_ie
[4] = {0x00,0x50,0xf2,0x04};
2046 static u8 ccmp_rsn_ie
[4] = {0x00, 0x0f, 0xac, 0x04};
2047 static bool GetNmodeSupportBySecCfg8190Pci(struct net_device
*dev
)
2050 struct r8192_priv
* priv
= ieee80211_priv(dev
);
2051 struct ieee80211_device
* ieee
= priv
->ieee80211
;
2052 int wpa_ie_len
= ieee
->wpa_ie_len
;
2053 struct ieee80211_crypt_data
* crypt
;
2056 crypt
= ieee
->crypt
[ieee
->tx_keyidx
];
2057 encrypt
= (ieee
->current_network
.capability
& WLAN_CAPABILITY_PRIVACY
) || (ieee
->host_encrypt
&& crypt
&& crypt
->ops
&& (0 == strcmp(crypt
->ops
->name
,"WEP")));
2060 if(encrypt
&& (wpa_ie_len
== 0)) {
2061 /* wep encryption, no N mode setting */
2063 // } else if((wpa_ie_len != 0)&&(memcmp(&(ieee->wpa_ie[14]),ccmp_ie,4))) {
2064 } else if((wpa_ie_len
!= 0)) {
2065 /* parse pairwise key type */
2066 //if((pairwisekey = WEP40)||(pairwisekey = WEP104)||(pairwisekey = TKIP))
2067 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))))
2072 //RT_TRACE(COMP_ERR,"In %s The GroupEncAlgorithm is [4]\n",__FUNCTION__ );
2077 //In here we discuss with SD4 David. He think we still can send TKIP in broadcast group key in MCS rate.
2078 //We can't force in G mode if Pairwie key is AES and group key is TKIP
2079 if((pSecInfo
->GroupEncAlgorithm
== WEP104_Encryption
) || (pSecInfo
->GroupEncAlgorithm
== WEP40_Encryption
) ||
2080 (pSecInfo
->PairwiseEncAlgorithm
== WEP104_Encryption
) ||
2081 (pSecInfo
->PairwiseEncAlgorithm
== WEP40_Encryption
) || (pSecInfo
->PairwiseEncAlgorithm
== TKIP_Encryption
))
2092 static void rtl8192_refresh_supportrate(struct r8192_priv
* priv
)
2094 struct ieee80211_device
* ieee
= priv
->ieee80211
;
2095 //we donot consider set support rate for ABG mode, only HT MCS rate is set here.
2096 if (ieee
->mode
== WIRELESS_MODE_N_24G
|| ieee
->mode
== WIRELESS_MODE_N_5G
)
2098 memcpy(ieee
->Regdot11HTOperationalRateSet
, ieee
->RegHTSuppRateSet
, 16);
2099 //RT_DEBUG_DATA(COMP_INIT, ieee->RegHTSuppRateSet, 16);
2100 //RT_DEBUG_DATA(COMP_INIT, ieee->Regdot11HTOperationalRateSet, 16);
2103 memset(ieee
->Regdot11HTOperationalRateSet
, 0, 16);
2107 static u8
rtl8192_getSupportedWireleeMode(struct net_device
*dev
)
2109 struct r8192_priv
*priv
= ieee80211_priv(dev
);
2111 switch(priv
->rf_chip
)
2116 ret
= (WIRELESS_MODE_N_24G
|WIRELESS_MODE_G
|WIRELESS_MODE_B
);
2119 ret
= (WIRELESS_MODE_A
|WIRELESS_MODE_N_5G
);
2122 ret
= WIRELESS_MODE_B
;
2128 static void rtl8192_SetWirelessMode(struct net_device
* dev
, u8 wireless_mode
)
2130 struct r8192_priv
*priv
= ieee80211_priv(dev
);
2131 u8 bSupportMode
= rtl8192_getSupportedWireleeMode(dev
);
2134 if ((wireless_mode
== WIRELESS_MODE_AUTO
) || ((wireless_mode
&bSupportMode
)==0))
2136 if(bSupportMode
& WIRELESS_MODE_N_24G
)
2138 wireless_mode
= WIRELESS_MODE_N_24G
;
2140 else if(bSupportMode
& WIRELESS_MODE_N_5G
)
2142 wireless_mode
= WIRELESS_MODE_N_5G
;
2144 else if((bSupportMode
& WIRELESS_MODE_A
))
2146 wireless_mode
= WIRELESS_MODE_A
;
2148 else if((bSupportMode
& WIRELESS_MODE_G
))
2150 wireless_mode
= WIRELESS_MODE_G
;
2152 else if((bSupportMode
& WIRELESS_MODE_B
))
2154 wireless_mode
= WIRELESS_MODE_B
;
2157 RT_TRACE(COMP_ERR
, "%s(), No valid wireless mode supported, SupportedWirelessMode(%x)!!!\n", __FUNCTION__
,bSupportMode
);
2158 wireless_mode
= WIRELESS_MODE_B
;
2161 #ifdef TO_DO_LIST //// TODO: this function doesn't work well at this time, we shoud wait for FPGA
2162 ActUpdateChannelAccessSetting( pAdapter
, pHalData
->CurrentWirelessMode
, &pAdapter
->MgntInfo
.Info8185
.ChannelAccessSetting
);
2164 priv
->ieee80211
->mode
= wireless_mode
;
2166 if ((wireless_mode
== WIRELESS_MODE_N_24G
) || (wireless_mode
== WIRELESS_MODE_N_5G
))
2167 priv
->ieee80211
->pHTInfo
->bEnableHT
= 1;
2169 priv
->ieee80211
->pHTInfo
->bEnableHT
= 0;
2170 RT_TRACE(COMP_INIT
, "Current Wireless Mode is %x\n", wireless_mode
);
2171 rtl8192_refresh_supportrate(priv
);
2175 //init priv variables here
2177 static bool GetHalfNmodeSupportByAPs819xPci(struct net_device
* dev
)
2180 struct r8192_priv
* priv
= ieee80211_priv(dev
);
2181 struct ieee80211_device
* ieee
= priv
->ieee80211
;
2183 if(ieee
->bHalfWirelessN24GMode
== true)
2191 short rtl8192_is_tx_queue_empty(struct net_device
*dev
)
2194 struct r8192_priv
*priv
= ieee80211_priv(dev
);
2195 for (i
=0; i
<=MGNT_QUEUE
; i
++)
2197 if ((i
== TXCMD_QUEUE
) || (i
== HCCA_QUEUE
) )
2199 if (skb_queue_len(&(&priv
->tx_ring
[i
])->queue
) > 0){
2200 printk("===>tx queue is not empty:%d, %d\n", i
, skb_queue_len(&(&priv
->tx_ring
[i
])->queue
));
2206 static void rtl8192_hw_sleep_down(struct net_device
*dev
)
2208 RT_TRACE(COMP_POWER
, "%s()============>come to sleep down\n", __FUNCTION__
);
2209 MgntActSet_RF_State(dev
, eRfSleep
, RF_CHANGE_BY_PS
);
2211 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
2212 static void rtl8192_hw_sleep_wq (struct work_struct
*work
)
2214 // struct r8180_priv *priv = container_of(work, struct r8180_priv, watch_dog_wq);
2215 // struct ieee80211_device * ieee = (struct ieee80211_device*)
2216 // container_of(work, struct ieee80211_device, watch_dog_wq);
2217 struct delayed_work
*dwork
= container_of(work
,struct delayed_work
,work
);
2218 struct ieee80211_device
*ieee
= container_of(dwork
,struct ieee80211_device
,hw_sleep_wq
);
2219 struct net_device
*dev
= ieee
->dev
;
2221 void rtl8192_hw_sleep_wq(struct net_device
* dev
)
2224 //printk("=========>%s()\n", __FUNCTION__);
2225 rtl8192_hw_sleep_down(dev
);
2227 // printk("dev is %d\n",dev);
2228 // printk("&*&(^*(&(&=========>%s()\n", __FUNCTION__);
2229 static void rtl8192_hw_wakeup(struct net_device
* dev
)
2233 // spin_lock_irqsave(&priv->ps_lock,flags);
2234 RT_TRACE(COMP_POWER
, "%s()============>come to wake up\n", __FUNCTION__
);
2235 MgntActSet_RF_State(dev
, eRfOn
, RF_CHANGE_BY_PS
);
2236 //FIXME: will we send package stored while nic is sleep?
2237 // spin_unlock_irqrestore(&priv->ps_lock,flags);
2239 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
2240 void rtl8192_hw_wakeup_wq (struct work_struct
*work
)
2242 // struct r8180_priv *priv = container_of(work, struct r8180_priv, watch_dog_wq);
2243 // struct ieee80211_device * ieee = (struct ieee80211_device*)
2244 // container_of(work, struct ieee80211_device, watch_dog_wq);
2245 struct delayed_work
*dwork
= container_of(work
,struct delayed_work
,work
);
2246 struct ieee80211_device
*ieee
= container_of(dwork
,struct ieee80211_device
,hw_wakeup_wq
);
2247 struct net_device
*dev
= ieee
->dev
;
2249 void rtl8192_hw_wakeup_wq(struct net_device
* dev
)
2252 rtl8192_hw_wakeup(dev
);
2256 #define MIN_SLEEP_TIME 50
2257 #define MAX_SLEEP_TIME 10000
2258 static void rtl8192_hw_to_sleep(struct net_device
*dev
, u32 th
, u32 tl
)
2261 struct r8192_priv
*priv
= ieee80211_priv(dev
);
2264 unsigned long flags
;
2266 spin_lock_irqsave(&priv
->ps_lock
,flags
);
2268 /* Writing HW register with 0 equals to disable
2269 * the timer, that is not really what we want
2271 tl
-= MSECS(4+16+7);
2273 //if(tl == 0) tl = 1;
2275 /* FIXME HACK FIXME HACK */
2276 // force_pci_posting(dev);
2279 // rb = read_nic_dword(dev, TSFTR);
2281 /* If the interval in witch we are requested to sleep is too
2282 * short then give up and remain awake
2284 if(((tl
>=rb
)&& (tl
-rb
) <= MSECS(MIN_SLEEP_TIME
))
2285 ||((rb
>tl
)&& (rb
-tl
) < MSECS(MIN_SLEEP_TIME
))) {
2286 spin_unlock_irqrestore(&priv
->ps_lock
,flags
);
2287 printk("too short to sleep\n");
2291 // write_nic_dword(dev, TimerInt, tl);
2292 // rb = read_nic_dword(dev, TSFTR);
2294 u32 tmp
= (tl
>rb
)?(tl
-rb
):(rb
-tl
);
2296 queue_delayed_work(priv
->ieee80211
->wq
, &priv
->ieee80211
->hw_wakeup_wq
, tmp
); //as tl may be less than rb
2298 /* if we suspect the TimerInt is gone beyond tl
2299 * while setting it, then give up
2302 if(((tl
> rb
) && ((tl
-rb
) > MSECS(MAX_SLEEP_TIME
)))||
2303 ((tl
< rb
) && ((rb
-tl
) > MSECS(MAX_SLEEP_TIME
)))) {
2304 printk("========>too long to sleep:%x, %x, %lx\n", tl
, rb
, MSECS(MAX_SLEEP_TIME
));
2305 spin_unlock_irqrestore(&priv
->ps_lock
,flags
);
2309 // if(priv->rf_sleep)
2310 // priv->rf_sleep(dev);
2312 //printk("<=========%s()\n", __FUNCTION__);
2313 queue_delayed_work(priv
->ieee80211
->wq
, (void *)&priv
->ieee80211
->hw_sleep_wq
,0);
2314 spin_unlock_irqrestore(&priv
->ps_lock
,flags
);
2316 static void rtl8192_init_priv_variable(struct net_device
* dev
)
2318 struct r8192_priv
*priv
= ieee80211_priv(dev
);
2320 priv
->being_init_adapter
= false;
2321 priv
->txbuffsize
= 1600;//1024;
2322 priv
->txfwbuffersize
= 4096;
2323 priv
->txringcount
= 64;//32;
2324 //priv->txbeaconcount = priv->txringcount;
2325 priv
->txbeaconcount
= 2;
2326 priv
->rxbuffersize
= 9100;//2048;//1024;
2327 priv
->rxringcount
= MAX_RX_COUNT
;//64;
2328 priv
->irq_enabled
=0;
2329 priv
->card_8192
= NIC_8192E
;
2330 priv
->rx_skb_complete
= 1;
2331 priv
->chan
= 1; //set to channel 1
2332 priv
->RegWirelessMode
= WIRELESS_MODE_AUTO
;
2333 priv
->RegChannelPlan
= 0xf;
2334 priv
->nrxAMPDU_size
= 0;
2335 priv
->nrxAMPDU_aggr_num
= 0;
2336 priv
->last_rxdesc_tsf_high
= 0;
2337 priv
->last_rxdesc_tsf_low
= 0;
2338 priv
->ieee80211
->mode
= WIRELESS_MODE_AUTO
; //SET AUTO
2339 priv
->ieee80211
->iw_mode
= IW_MODE_INFRA
;
2340 priv
->ieee80211
->ieee_up
=0;
2341 priv
->retry_rts
= DEFAULT_RETRY_RTS
;
2342 priv
->retry_data
= DEFAULT_RETRY_DATA
;
2343 priv
->ieee80211
->rts
= DEFAULT_RTS_THRESHOLD
;
2344 priv
->ieee80211
->rate
= 110; //11 mbps
2345 priv
->ieee80211
->short_slot
= 1;
2346 priv
->promisc
= (dev
->flags
& IFF_PROMISC
) ? 1:0;
2347 priv
->bcck_in_ch14
= false;
2348 priv
->bfsync_processing
= false;
2349 priv
->CCKPresentAttentuation
= 0;
2350 priv
->rfa_txpowertrackingindex
= 0;
2351 priv
->rfc_txpowertrackingindex
= 0;
2353 priv
->ScanDelay
= 50;//for Scan TODO
2354 //added by amy for silent reset
2355 priv
->ResetProgress
= RESET_TYPE_NORESET
;
2356 priv
->bForcedSilentReset
= 0;
2357 priv
->bDisableNormalResetCheck
= false;
2358 priv
->force_reset
= false;
2359 //added by amy for power save
2361 priv
->ieee80211
->RfOffReason
= 0;
2362 priv
->RFChangeInProgress
= false;
2363 priv
->bHwRfOffAction
= 0;
2364 priv
->SetRFPowerStateInProgress
= false;
2365 priv
->ieee80211
->PowerSaveControl
.bInactivePs
= true;
2366 priv
->ieee80211
->PowerSaveControl
.bIPSModeBackup
= false;
2368 priv
->txpower_checkcnt
= 0;
2369 priv
->thermal_readback_index
=0;
2370 priv
->txpower_tracking_callback_cnt
= 0;
2371 priv
->ccktxpower_adjustcnt_ch14
= 0;
2372 priv
->ccktxpower_adjustcnt_not_ch14
= 0;
2374 priv
->ieee80211
->current_network
.beacon_interval
= DEFAULT_BEACONINTERVAL
;
2375 priv
->ieee80211
->iw_mode
= IW_MODE_INFRA
;
2376 priv
->ieee80211
->softmac_features
= IEEE_SOFTMAC_SCAN
|
2377 IEEE_SOFTMAC_ASSOCIATE
| IEEE_SOFTMAC_PROBERQ
|
2378 IEEE_SOFTMAC_PROBERS
| IEEE_SOFTMAC_TX_QUEUE
;/* |
2379 IEEE_SOFTMAC_BEACONS;*///added by amy
080604 //| //IEEE_SOFTMAC_SINGLE_QUEUE;
2381 priv
->ieee80211
->active_scan
= 1;
2382 priv
->ieee80211
->modulation
= IEEE80211_CCK_MODULATION
| IEEE80211_OFDM_MODULATION
;
2383 priv
->ieee80211
->host_encrypt
= 1;
2384 priv
->ieee80211
->host_decrypt
= 1;
2385 //priv->ieee80211->start_send_beacons = NULL;//rtl819xusb_beacon_tx;//-by amy 080604
2386 //priv->ieee80211->stop_send_beacons = NULL;//rtl8192_beacon_stop;//-by amy 080604
2387 priv
->ieee80211
->start_send_beacons
= rtl8192_start_beacon
;//+by david 081107
2388 priv
->ieee80211
->stop_send_beacons
= rtl8192_stop_beacon
;//+by david 081107
2389 priv
->ieee80211
->softmac_hard_start_xmit
= rtl8192_hard_start_xmit
;
2390 priv
->ieee80211
->set_chan
= rtl8192_set_chan
;
2391 priv
->ieee80211
->link_change
= rtl8192_link_change
;
2392 priv
->ieee80211
->softmac_data_hard_start_xmit
= rtl8192_hard_data_xmit
;
2393 priv
->ieee80211
->data_hard_stop
= rtl8192_data_hard_stop
;
2394 priv
->ieee80211
->data_hard_resume
= rtl8192_data_hard_resume
;
2395 priv
->ieee80211
->init_wmmparam_flag
= 0;
2396 priv
->ieee80211
->fts
= DEFAULT_FRAG_THRESHOLD
;
2397 priv
->ieee80211
->check_nic_enough_desc
= check_nic_enough_desc
;
2398 priv
->ieee80211
->tx_headroom
= sizeof(TX_FWINFO_8190PCI
);
2399 priv
->ieee80211
->qos_support
= 1;
2400 priv
->ieee80211
->dot11PowerSaveMode
= 0;
2402 // priv->ieee80211->SwChnlByTimerHandler = rtl8192_phy_SwChnl;
2403 priv
->ieee80211
->SetBWModeHandler
= rtl8192_SetBWMode
;
2404 priv
->ieee80211
->handle_assoc_response
= rtl8192_handle_assoc_response
;
2405 priv
->ieee80211
->handle_beacon
= rtl8192_handle_beacon
;
2407 priv
->ieee80211
->sta_wake_up
= rtl8192_hw_wakeup
;
2408 // priv->ieee80211->ps_request_tx_ack = rtl8192_rq_tx_ack;
2409 priv
->ieee80211
->enter_sleep_state
= rtl8192_hw_to_sleep
;
2410 priv
->ieee80211
->ps_is_queue_empty
= rtl8192_is_tx_queue_empty
;
2412 priv
->ieee80211
->GetNmodeSupportBySecCfg
= GetNmodeSupportBySecCfg8190Pci
;
2413 priv
->ieee80211
->SetWirelessMode
= rtl8192_SetWirelessMode
;
2414 priv
->ieee80211
->GetHalfNmodeSupportByAPsHandler
= GetHalfNmodeSupportByAPs819xPci
;
2417 priv
->ieee80211
->InitialGainHandler
= InitialGain819xPci
;
2419 priv
->card_type
= USB
;
2421 priv
->ShortRetryLimit
= 0x30;
2422 priv
->LongRetryLimit
= 0x30;
2424 priv
->EarlyRxThreshold
= 7;
2425 priv
->enable_gpio0
= 0;
2427 priv
->TransmitConfig
= 0;
2429 priv
->ReceiveConfig
= RCR_ADD3
|
2430 RCR_AMF
| RCR_ADF
| //accept management/data
2431 RCR_AICV
| //accept control frame for SW AP needs PS-poll, 2005.07.07, by rcnjko.
2432 RCR_AB
| RCR_AM
| RCR_APM
| //accept BC/MC/UC
2433 RCR_AAP
| ((u32
)7<<RCR_MXDMA_OFFSET
) |
2434 ((u32
)7 << RCR_FIFO_OFFSET
) | RCR_ONLYERLPKT
;
2436 priv
->irq_mask
= (u32
)(IMR_ROK
| IMR_VODOK
| IMR_VIDOK
| IMR_BEDOK
| IMR_BKDOK
|\
2437 IMR_HCCADOK
| IMR_MGNTDOK
| IMR_COMDOK
| IMR_HIGHDOK
|\
2438 IMR_BDOK
| IMR_RXCMDOK
| IMR_TIMEOUT0
| IMR_RDU
| IMR_RXFOVW
|\
2439 IMR_TXFOVW
| IMR_BcnInt
| IMR_TBDOK
| IMR_TBDER
);
2441 priv
->AcmControl
= 0;
2442 priv
->pFirmware
= (rt_firmware
*)vmalloc(sizeof(rt_firmware
));
2443 if (priv
->pFirmware
)
2444 memset(priv
->pFirmware
, 0, sizeof(rt_firmware
));
2446 /* rx related queue */
2447 skb_queue_head_init(&priv
->rx_queue
);
2448 skb_queue_head_init(&priv
->skb_queue
);
2450 /* Tx related queue */
2451 for(i
= 0; i
< MAX_QUEUE_SIZE
; i
++) {
2452 skb_queue_head_init(&priv
->ieee80211
->skb_waitQ
[i
]);
2454 for(i
= 0; i
< MAX_QUEUE_SIZE
; i
++) {
2455 skb_queue_head_init(&priv
->ieee80211
->skb_aggQ
[i
]);
2457 priv
->rf_set_chan
= rtl8192_phy_SwChnl
;
2461 static void rtl8192_init_priv_lock(struct r8192_priv
* priv
)
2463 spin_lock_init(&priv
->tx_lock
);
2464 spin_lock_init(&priv
->irq_lock
);//added by thomas
2465 spin_lock_init(&priv
->irq_th_lock
);
2466 spin_lock_init(&priv
->rf_ps_lock
);
2467 spin_lock_init(&priv
->ps_lock
);
2468 //spin_lock_init(&priv->rf_lock);
2469 sema_init(&priv
->wx_sem
,1);
2470 sema_init(&priv
->rf_sem
,1);
2471 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16))
2472 sema_init(&priv
->mutex
, 1);
2474 mutex_init(&priv
->mutex
);
2478 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
2479 extern void rtl819x_watchdog_wqcallback(struct work_struct
*work
);
2481 extern void rtl819x_watchdog_wqcallback(struct net_device
*dev
);
2484 void rtl8192_irq_rx_tasklet(struct r8192_priv
*priv
);
2485 void rtl8192_irq_tx_tasklet(struct r8192_priv
*priv
);
2486 void rtl8192_prepare_beacon(struct r8192_priv
*priv
);
2487 //init tasklet and wait_queue here. only 2.6 above kernel is considered
2488 #define DRV_NAME "wlan0"
2489 static void rtl8192_init_priv_task(struct net_device
* dev
)
2491 struct r8192_priv
*priv
= ieee80211_priv(dev
);
2493 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
2494 #ifdef PF_SYNCTHREAD
2495 priv
->priv_wq
= create_workqueue(DRV_NAME
,0);
2497 priv
->priv_wq
= create_workqueue(DRV_NAME
);
2501 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
2502 // INIT_WORK(&priv->reset_wq, (void(*)(void*)) rtl8192_restart);
2503 INIT_WORK(&priv
->reset_wq
, rtl8192_restart
);
2504 // INIT_DELAYED_WORK(&priv->watch_dog_wq, hal_dm_watchdog);
2505 INIT_DELAYED_WORK(&priv
->watch_dog_wq
, rtl819x_watchdog_wqcallback
);
2506 INIT_DELAYED_WORK(&priv
->txpower_tracking_wq
, dm_txpower_trackingcallback
);
2507 INIT_DELAYED_WORK(&priv
->rfpath_check_wq
, dm_rf_pathcheck_workitemcallback
);
2508 INIT_DELAYED_WORK(&priv
->update_beacon_wq
, rtl8192_update_beacon
);
2509 //INIT_WORK(&priv->SwChnlWorkItem, rtl8192_SwChnl_WorkItem);
2510 //INIT_WORK(&priv->SetBWModeWorkItem, rtl8192_SetBWModeWorkItem);
2511 INIT_WORK(&priv
->qos_activate
, rtl8192_qos_activate
);
2512 INIT_DELAYED_WORK(&priv
->ieee80211
->hw_wakeup_wq
,(void*) rtl8192_hw_wakeup_wq
);
2513 INIT_DELAYED_WORK(&priv
->ieee80211
->hw_sleep_wq
,(void*) rtl8192_hw_sleep_wq
);
2516 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
2517 tq_init(&priv
->reset_wq
, (void*)rtl8192_restart
, dev
);
2518 tq_init(&priv
->watch_dog_wq
, (void*)rtl819x_watchdog_wqcallback
, dev
);
2519 tq_init(&priv
->txpower_tracking_wq
, (void*)dm_txpower_trackingcallback
, dev
);
2520 tq_init(&priv
->rfpath_check_wq
, (void*)dm_rf_pathcheck_workitemcallback
, dev
);
2521 tq_init(&priv
->update_beacon_wq
, (void*)rtl8192_update_beacon
, dev
);
2522 //tq_init(&priv->SwChnlWorkItem, (void*) rtl8192_SwChnl_WorkItem, dev);
2523 //tq_init(&priv->SetBWModeWorkItem, (void*)rtl8192_SetBWModeWorkItem, dev);
2524 tq_init(&priv
->qos_activate
, (void *)rtl8192_qos_activate
, dev
);
2525 tq_init(&priv
->ieee80211
->hw_wakeup_wq
,(void*) rtl8192_hw_wakeup_wq
, dev
);
2526 tq_init(&priv
->ieee80211
->hw_sleep_wq
,(void*) rtl8192_hw_sleep_wq
, dev
);
2529 INIT_WORK(&priv
->reset_wq
,(void(*)(void*)) rtl8192_restart
,dev
);
2530 // INIT_WORK(&priv->watch_dog_wq, (void(*)(void*)) hal_dm_watchdog,dev);
2531 INIT_WORK(&priv
->watch_dog_wq
, (void(*)(void*)) rtl819x_watchdog_wqcallback
,dev
);
2532 INIT_WORK(&priv
->txpower_tracking_wq
, (void(*)(void*)) dm_txpower_trackingcallback
,dev
);
2533 INIT_WORK(&priv
->rfpath_check_wq
, (void(*)(void*)) dm_rf_pathcheck_workitemcallback
,dev
);
2534 INIT_WORK(&priv
->update_beacon_wq
, (void(*)(void*))rtl8192_update_beacon
,dev
);
2535 //INIT_WORK(&priv->SwChnlWorkItem, (void(*)(void*)) rtl8192_SwChnl_WorkItem, dev);
2536 //INIT_WORK(&priv->SetBWModeWorkItem, (void(*)(void*)) rtl8192_SetBWModeWorkItem, dev);
2537 INIT_WORK(&priv
->qos_activate
, (void(*)(void *))rtl8192_qos_activate
, dev
);
2538 INIT_WORK(&priv
->ieee80211
->hw_wakeup_wq
,(void*) rtl8192_hw_wakeup_wq
, dev
);
2539 INIT_WORK(&priv
->ieee80211
->hw_sleep_wq
,(void*) rtl8192_hw_sleep_wq
, dev
);
2543 tasklet_init(&priv
->irq_rx_tasklet
,
2544 (void(*)(unsigned long))rtl8192_irq_rx_tasklet
,
2545 (unsigned long)priv
);
2546 tasklet_init(&priv
->irq_tx_tasklet
,
2547 (void(*)(unsigned long))rtl8192_irq_tx_tasklet
,
2548 (unsigned long)priv
);
2549 tasklet_init(&priv
->irq_prepare_beacon_tasklet
,
2550 (void(*)(unsigned long))rtl8192_prepare_beacon
,
2551 (unsigned long)priv
);
2554 static void rtl8192_get_eeprom_size(struct net_device
* dev
)
2557 struct r8192_priv
*priv
= ieee80211_priv(dev
);
2558 RT_TRACE(COMP_INIT
, "===========>%s()\n", __FUNCTION__
);
2559 curCR
= read_nic_dword(dev
, EPROM_CMD
);
2560 RT_TRACE(COMP_INIT
, "read from Reg Cmd9346CR(%x):%x\n", EPROM_CMD
, curCR
);
2561 //whether need I consider BIT5?
2562 priv
->epromtype
= (curCR
& EPROM_CMD_9356SEL
) ? EPROM_93c56
: EPROM_93c46
;
2563 RT_TRACE(COMP_INIT
, "<===========%s(), epromtype:%d\n", __FUNCTION__
, priv
->epromtype
);
2566 //used to swap endian. as ntohl & htonl are not neccessary to swap endian, so use this instead.
2567 static inline u16
endian_swap(u16
* data
)
2570 *data
= (tmp
>> 8) | (tmp
<< 8);
2575 * Note: Adapter->EEPROMAddressSize should be set before this function call.
2576 * EEPROM address size can be got through GetEEPROMSize8185()
2578 static void rtl8192_read_eeprom_info(struct net_device
* dev
)
2580 struct r8192_priv
*priv
= ieee80211_priv(dev
);
2584 u8 ICVer8192
, ICVer8256
;
2586 u16 i
,usValue
, IC_Version
;
2589 u8 offset
;//, tmpAFR;
2590 u8 EepromTxPower
[100];
2592 u8 bMac_Tmp_Addr
[6] = {0x00, 0xe0, 0x4c, 0x00, 0x00, 0x01};
2593 RT_TRACE(COMP_INIT
, "====> rtl8192_read_eeprom_info\n");
2596 // TODO: I don't know if we need to apply EF function to EEPROM read function
2598 //2 Read EEPROM ID to make sure autoload is success
2599 EEPROMId
= eprom_read(dev
, 0);
2600 if( EEPROMId
!= RTL8190_EEPROM_ID
)
2602 RT_TRACE(COMP_ERR
, "EEPROM ID is invalid:%x, %x\n", EEPROMId
, RTL8190_EEPROM_ID
);
2603 priv
->AutoloadFailFlag
=true;
2607 priv
->AutoloadFailFlag
=false;
2611 // Assign Chip Version ID
2613 // Read IC Version && Channel Plan
2614 if(!priv
->AutoloadFailFlag
)
2617 priv
->eeprom_vid
= eprom_read(dev
, (EEPROM_VID
>> 1));
2618 priv
->eeprom_did
= eprom_read(dev
, (EEPROM_DID
>> 1));
2620 usValue
= eprom_read(dev
, (u16
)(EEPROM_Customer_ID
>>1)) >> 8 ;
2621 priv
->eeprom_CustomerID
= (u8
)( usValue
& 0xff);
2622 usValue
= eprom_read(dev
, (EEPROM_ICVersion_ChannelPlan
>>1));
2623 priv
->eeprom_ChannelPlan
= usValue
&0xff;
2624 IC_Version
= ((usValue
&0xff00)>>8);
2627 priv
->card_8192_version
= (VERSION_8190
)(IC_Version
);
2630 ICVer8192
= (IC_Version
&0xf); //bit0~3; 1:A cut, 2:B cut, 3:C cut...
2631 ICVer8256
= ((IC_Version
&0xf0)>>4);//bit4~6, bit7 reserved for other RF chip; 1:A cut, 2:B cut, 3:C cut...
2632 RT_TRACE(COMP_INIT
, "\nICVer8192 = 0x%x\n", ICVer8192
);
2633 RT_TRACE(COMP_INIT
, "\nICVer8256 = 0x%x\n", ICVer8256
);
2634 if(ICVer8192
== 0x2) //B-cut
2636 if(ICVer8256
== 0x5) //E-cut
2637 priv
->card_8192_version
= VERSION_8190_BE
;
2641 switch(priv
->card_8192_version
)
2643 case VERSION_8190_BD
:
2644 case VERSION_8190_BE
:
2647 priv
->card_8192_version
= VERSION_8190_BD
;
2650 RT_TRACE(COMP_INIT
, "\nIC Version = 0x%x\n", priv
->card_8192_version
);
2654 priv
->card_8192_version
= VERSION_8190_BD
;
2655 priv
->eeprom_vid
= 0;
2656 priv
->eeprom_did
= 0;
2657 priv
->eeprom_CustomerID
= 0;
2658 priv
->eeprom_ChannelPlan
= 0;
2659 RT_TRACE(COMP_INIT
, "\nIC Version = 0x%x\n", 0xff);
2662 RT_TRACE(COMP_INIT
, "EEPROM VID = 0x%4x\n", priv
->eeprom_vid
);
2663 RT_TRACE(COMP_INIT
, "EEPROM DID = 0x%4x\n", priv
->eeprom_did
);
2664 RT_TRACE(COMP_INIT
,"EEPROM Customer ID: 0x%2x\n", priv
->eeprom_CustomerID
);
2666 //2 Read Permanent MAC address
2667 if(!priv
->AutoloadFailFlag
)
2669 for(i
= 0; i
< 6; i
+= 2)
2671 usValue
= eprom_read(dev
, (u16
) ((EEPROM_NODE_ADDRESS_BYTE_0
+i
)>>1));
2672 *(u16
*)(&dev
->dev_addr
[i
]) = usValue
;
2675 // when auto load failed, the last address byte set to be a random one.
2676 // added by david woo.2007/11/7
2677 memcpy(dev
->dev_addr
, bMac_Tmp_Addr
, 6);
2680 RT_TRACE(COMP_INIT
, "Permanent Address = %02x-%02x-%02x-%02x-%02x-%02x\n",
2681 dev
->dev_addr
[0], dev
->dev_addr
[1],
2682 dev
->dev_addr
[2], dev
->dev_addr
[3],
2683 dev
->dev_addr
[4], dev
->dev_addr
[5]);
2685 //2 TX Power Check EEPROM Fail or not
2686 if(priv
->card_8192_version
> VERSION_8190_BD
) {
2687 priv
->bTXPowerDataReadFromEEPORM
= true;
2689 priv
->bTXPowerDataReadFromEEPORM
= false;
2692 // 2007/11/15 MH 8190PCI Default=2T4R, 8192PCIE dafault=1T2R
2693 priv
->rf_type
= RTL819X_DEFAULT_RF_TYPE
;
2695 if(priv
->card_8192_version
> VERSION_8190_BD
)
2697 // Read RF-indication and Tx Power gain index diff of legacy to HT OFDM rate.
2698 if(!priv
->AutoloadFailFlag
)
2700 tempval
= (eprom_read(dev
, (EEPROM_RFInd_PowerDiff
>>1))) & 0xff;
2701 priv
->EEPROMLegacyHTTxPowerDiff
= tempval
& 0xf; // bit[3:0]
2703 if (tempval
&0x80) //RF-indication, bit[7]
2704 priv
->rf_type
= RF_1T2R
;
2706 priv
->rf_type
= RF_2T4R
;
2710 priv
->EEPROMLegacyHTTxPowerDiff
= EEPROM_Default_LegacyHTTxPowerDiff
;
2712 RT_TRACE(COMP_INIT
, "EEPROMLegacyHTTxPowerDiff = %d\n",
2713 priv
->EEPROMLegacyHTTxPowerDiff
);
2715 // Read ThermalMeter from EEPROM
2716 if(!priv
->AutoloadFailFlag
)
2718 priv
->EEPROMThermalMeter
= (u8
)(((eprom_read(dev
, (EEPROM_ThermalMeter
>>1))) & 0xff00)>>8);
2722 priv
->EEPROMThermalMeter
= EEPROM_Default_ThermalMeter
;
2724 RT_TRACE(COMP_INIT
, "ThermalMeter = %d\n", priv
->EEPROMThermalMeter
);
2725 //vivi, for tx power track
2726 priv
->TSSI_13dBm
= priv
->EEPROMThermalMeter
*100;
2728 if(priv
->epromtype
== EPROM_93c46
)
2730 // Read antenna tx power offset of B/C/D to A and CrystalCap from EEPROM
2731 if(!priv
->AutoloadFailFlag
)
2733 usValue
= eprom_read(dev
, (EEPROM_TxPwDiff_CrystalCap
>>1));
2734 priv
->EEPROMAntPwDiff
= (usValue
&0x0fff);
2735 priv
->EEPROMCrystalCap
= (u8
)((usValue
&0xf000)>>12);
2739 priv
->EEPROMAntPwDiff
= EEPROM_Default_AntTxPowerDiff
;
2740 priv
->EEPROMCrystalCap
= EEPROM_Default_TxPwDiff_CrystalCap
;
2742 RT_TRACE(COMP_INIT
, "EEPROMAntPwDiff = %d\n", priv
->EEPROMAntPwDiff
);
2743 RT_TRACE(COMP_INIT
, "EEPROMCrystalCap = %d\n", priv
->EEPROMCrystalCap
);
2746 // Get per-channel Tx Power Level
2748 for(i
=0; i
<14; i
+=2)
2750 if(!priv
->AutoloadFailFlag
)
2752 usValue
= eprom_read(dev
, (u16
) ((EEPROM_TxPwIndex_CCK
+i
)>>1) );
2756 usValue
= EEPROM_Default_TxPower
;
2758 *((u16
*)(&priv
->EEPROMTxPowerLevelCCK
[i
])) = usValue
;
2759 RT_TRACE(COMP_INIT
,"CCK Tx Power Level, Index %d = 0x%02x\n", i
, priv
->EEPROMTxPowerLevelCCK
[i
]);
2760 RT_TRACE(COMP_INIT
, "CCK Tx Power Level, Index %d = 0x%02x\n", i
+1, priv
->EEPROMTxPowerLevelCCK
[i
+1]);
2762 for(i
=0; i
<14; i
+=2)
2764 if(!priv
->AutoloadFailFlag
)
2766 usValue
= eprom_read(dev
, (u16
) ((EEPROM_TxPwIndex_OFDM_24G
+i
)>>1) );
2770 usValue
= EEPROM_Default_TxPower
;
2772 *((u16
*)(&priv
->EEPROMTxPowerLevelOFDM24G
[i
])) = usValue
;
2773 RT_TRACE(COMP_INIT
, "OFDM 2.4G Tx Power Level, Index %d = 0x%02x\n", i
, priv
->EEPROMTxPowerLevelOFDM24G
[i
]);
2774 RT_TRACE(COMP_INIT
, "OFDM 2.4G Tx Power Level, Index %d = 0x%02x\n", i
+1, priv
->EEPROMTxPowerLevelOFDM24G
[i
+1]);
2777 else if(priv
->epromtype
== EPROM_93c56
)
2780 // Read CrystalCap from EEPROM
2781 if(!priv
->AutoloadFailFlag
)
2783 priv
->EEPROMAntPwDiff
= EEPROM_Default_AntTxPowerDiff
;
2784 priv
->EEPROMCrystalCap
= (u8
)(((eprom_read(dev
, (EEPROM_C56_CrystalCap
>>1))) & 0xf000)>>12);
2788 priv
->EEPROMAntPwDiff
= EEPROM_Default_AntTxPowerDiff
;
2789 priv
->EEPROMCrystalCap
= EEPROM_Default_TxPwDiff_CrystalCap
;
2791 RT_TRACE(COMP_INIT
,"EEPROMAntPwDiff = %d\n", priv
->EEPROMAntPwDiff
);
2792 RT_TRACE(COMP_INIT
, "EEPROMCrystalCap = %d\n", priv
->EEPROMCrystalCap
);
2794 // Get Tx Power Level by Channel
2795 if(!priv
->AutoloadFailFlag
)
2797 // Read Tx power of Channel 1 ~ 14 from EEPROM.
2798 for(i
= 0; i
< 12; i
+=2)
2801 offset
= EEPROM_C56_RfA_CCK_Chnl1_TxPwIndex
+ i
;
2803 offset
= EEPROM_C56_RfC_CCK_Chnl1_TxPwIndex
+ i
- 6;
2804 usValue
= eprom_read(dev
, (offset
>>1));
2805 *((u16
*)(&EepromTxPower
[i
])) = usValue
;
2808 for(i
= 0; i
< 12; i
++)
2811 priv
->EEPROMRfACCKChnl1TxPwLevel
[i
] = EepromTxPower
[i
];
2812 else if ((i
>=3 )&&(i
<= 5))
2813 priv
->EEPROMRfAOfdmChnlTxPwLevel
[i
-3] = EepromTxPower
[i
];
2814 else if ((i
>=6 )&&(i
<= 8))
2815 priv
->EEPROMRfCCCKChnl1TxPwLevel
[i
-6] = EepromTxPower
[i
];
2817 priv
->EEPROMRfCOfdmChnlTxPwLevel
[i
-9] = EepromTxPower
[i
];
2822 priv
->EEPROMRfACCKChnl1TxPwLevel
[0] = EEPROM_Default_TxPowerLevel
;
2823 priv
->EEPROMRfACCKChnl1TxPwLevel
[1] = EEPROM_Default_TxPowerLevel
;
2824 priv
->EEPROMRfACCKChnl1TxPwLevel
[2] = EEPROM_Default_TxPowerLevel
;
2826 priv
->EEPROMRfAOfdmChnlTxPwLevel
[0] = EEPROM_Default_TxPowerLevel
;
2827 priv
->EEPROMRfAOfdmChnlTxPwLevel
[1] = EEPROM_Default_TxPowerLevel
;
2828 priv
->EEPROMRfAOfdmChnlTxPwLevel
[2] = EEPROM_Default_TxPowerLevel
;
2830 priv
->EEPROMRfCCCKChnl1TxPwLevel
[0] = EEPROM_Default_TxPowerLevel
;
2831 priv
->EEPROMRfCCCKChnl1TxPwLevel
[1] = EEPROM_Default_TxPowerLevel
;
2832 priv
->EEPROMRfCCCKChnl1TxPwLevel
[2] = EEPROM_Default_TxPowerLevel
;
2834 priv
->EEPROMRfCOfdmChnlTxPwLevel
[0] = EEPROM_Default_TxPowerLevel
;
2835 priv
->EEPROMRfCOfdmChnlTxPwLevel
[1] = EEPROM_Default_TxPowerLevel
;
2836 priv
->EEPROMRfCOfdmChnlTxPwLevel
[2] = EEPROM_Default_TxPowerLevel
;
2838 RT_TRACE(COMP_INIT
, "priv->EEPROMRfACCKChnl1TxPwLevel[0] = 0x%x\n", priv
->EEPROMRfACCKChnl1TxPwLevel
[0]);
2839 RT_TRACE(COMP_INIT
, "priv->EEPROMRfACCKChnl1TxPwLevel[1] = 0x%x\n", priv
->EEPROMRfACCKChnl1TxPwLevel
[1]);
2840 RT_TRACE(COMP_INIT
, "priv->EEPROMRfACCKChnl1TxPwLevel[2] = 0x%x\n", priv
->EEPROMRfACCKChnl1TxPwLevel
[2]);
2841 RT_TRACE(COMP_INIT
, "priv->EEPROMRfAOfdmChnlTxPwLevel[0] = 0x%x\n", priv
->EEPROMRfAOfdmChnlTxPwLevel
[0]);
2842 RT_TRACE(COMP_INIT
, "priv->EEPROMRfAOfdmChnlTxPwLevel[1] = 0x%x\n", priv
->EEPROMRfAOfdmChnlTxPwLevel
[1]);
2843 RT_TRACE(COMP_INIT
, "priv->EEPROMRfAOfdmChnlTxPwLevel[2] = 0x%x\n", priv
->EEPROMRfAOfdmChnlTxPwLevel
[2]);
2844 RT_TRACE(COMP_INIT
, "priv->EEPROMRfCCCKChnl1TxPwLevel[0] = 0x%x\n", priv
->EEPROMRfCCCKChnl1TxPwLevel
[0]);
2845 RT_TRACE(COMP_INIT
, "priv->EEPROMRfCCCKChnl1TxPwLevel[1] = 0x%x\n", priv
->EEPROMRfCCCKChnl1TxPwLevel
[1]);
2846 RT_TRACE(COMP_INIT
, "priv->EEPROMRfCCCKChnl1TxPwLevel[2] = 0x%x\n", priv
->EEPROMRfCCCKChnl1TxPwLevel
[2]);
2847 RT_TRACE(COMP_INIT
, "priv->EEPROMRfCOfdmChnlTxPwLevel[0] = 0x%x\n", priv
->EEPROMRfCOfdmChnlTxPwLevel
[0]);
2848 RT_TRACE(COMP_INIT
, "priv->EEPROMRfCOfdmChnlTxPwLevel[1] = 0x%x\n", priv
->EEPROMRfCOfdmChnlTxPwLevel
[1]);
2849 RT_TRACE(COMP_INIT
, "priv->EEPROMRfCOfdmChnlTxPwLevel[2] = 0x%x\n", priv
->EEPROMRfCOfdmChnlTxPwLevel
[2]);
2854 // Update HAL variables.
2856 if(priv
->epromtype
== EPROM_93c46
)
2860 priv
->TxPowerLevelCCK
[i
] = priv
->EEPROMTxPowerLevelCCK
[i
];
2861 priv
->TxPowerLevelOFDM24G
[i
] = priv
->EEPROMTxPowerLevelOFDM24G
[i
];
2863 priv
->LegacyHTTxPowerDiff
= priv
->EEPROMLegacyHTTxPowerDiff
;
2864 // Antenna B gain offset to antenna A, bit0~3
2865 priv
->AntennaTxPwDiff
[0] = (priv
->EEPROMAntPwDiff
& 0xf);
2866 // Antenna C gain offset to antenna A, bit4~7
2867 priv
->AntennaTxPwDiff
[1] = ((priv
->EEPROMAntPwDiff
& 0xf0)>>4);
2868 // Antenna D gain offset to antenna A, bit8~11
2869 priv
->AntennaTxPwDiff
[2] = ((priv
->EEPROMAntPwDiff
& 0xf00)>>8);
2870 // CrystalCap, bit12~15
2871 priv
->CrystalCap
= priv
->EEPROMCrystalCap
;
2872 // ThermalMeter, bit0~3 for RFIC1, bit4~7 for RFIC2
2873 priv
->ThermalMeter
[0] = (priv
->EEPROMThermalMeter
& 0xf);
2874 priv
->ThermalMeter
[1] = ((priv
->EEPROMThermalMeter
& 0xf0)>>4);
2876 else if(priv
->epromtype
== EPROM_93c56
)
2878 //char cck_pwr_diff_a=0, cck_pwr_diff_c=0;
2880 //cck_pwr_diff_a = pHalData->EEPROMRfACCKChnl7TxPwLevel - pHalData->EEPROMRfAOfdmChnlTxPwLevel[1];
2881 //cck_pwr_diff_c = pHalData->EEPROMRfCCCKChnl7TxPwLevel - pHalData->EEPROMRfCOfdmChnlTxPwLevel[1];
2882 for(i
=0; i
<3; i
++) // channel 1~3 use the same Tx Power Level.
2884 priv
->TxPowerLevelCCK_A
[i
] = priv
->EEPROMRfACCKChnl1TxPwLevel
[0];
2885 priv
->TxPowerLevelOFDM24G_A
[i
] = priv
->EEPROMRfAOfdmChnlTxPwLevel
[0];
2886 priv
->TxPowerLevelCCK_C
[i
] = priv
->EEPROMRfCCCKChnl1TxPwLevel
[0];
2887 priv
->TxPowerLevelOFDM24G_C
[i
] = priv
->EEPROMRfCOfdmChnlTxPwLevel
[0];
2889 for(i
=3; i
<9; i
++) // channel 4~9 use the same Tx Power Level
2891 priv
->TxPowerLevelCCK_A
[i
] = priv
->EEPROMRfACCKChnl1TxPwLevel
[1];
2892 priv
->TxPowerLevelOFDM24G_A
[i
] = priv
->EEPROMRfAOfdmChnlTxPwLevel
[1];
2893 priv
->TxPowerLevelCCK_C
[i
] = priv
->EEPROMRfCCCKChnl1TxPwLevel
[1];
2894 priv
->TxPowerLevelOFDM24G_C
[i
] = priv
->EEPROMRfCOfdmChnlTxPwLevel
[1];
2896 for(i
=9; i
<14; i
++) // channel 10~14 use the same Tx Power Level
2898 priv
->TxPowerLevelCCK_A
[i
] = priv
->EEPROMRfACCKChnl1TxPwLevel
[2];
2899 priv
->TxPowerLevelOFDM24G_A
[i
] = priv
->EEPROMRfAOfdmChnlTxPwLevel
[2];
2900 priv
->TxPowerLevelCCK_C
[i
] = priv
->EEPROMRfCCCKChnl1TxPwLevel
[2];
2901 priv
->TxPowerLevelOFDM24G_C
[i
] = priv
->EEPROMRfCOfdmChnlTxPwLevel
[2];
2904 RT_TRACE(COMP_INIT
, "priv->TxPowerLevelCCK_A[%d] = 0x%x\n", i
, priv
->TxPowerLevelCCK_A
[i
]);
2906 RT_TRACE(COMP_INIT
,"priv->TxPowerLevelOFDM24G_A[%d] = 0x%x\n", i
, priv
->TxPowerLevelOFDM24G_A
[i
]);
2908 RT_TRACE(COMP_INIT
, "priv->TxPowerLevelCCK_C[%d] = 0x%x\n", i
, priv
->TxPowerLevelCCK_C
[i
]);
2910 RT_TRACE(COMP_INIT
, "priv->TxPowerLevelOFDM24G_C[%d] = 0x%x\n", i
, priv
->TxPowerLevelOFDM24G_C
[i
]);
2911 priv
->LegacyHTTxPowerDiff
= priv
->EEPROMLegacyHTTxPowerDiff
;
2912 priv
->AntennaTxPwDiff
[0] = 0;
2913 priv
->AntennaTxPwDiff
[1] = 0;
2914 priv
->AntennaTxPwDiff
[2] = 0;
2915 priv
->CrystalCap
= priv
->EEPROMCrystalCap
;
2916 // ThermalMeter, bit0~3 for RFIC1, bit4~7 for RFIC2
2917 priv
->ThermalMeter
[0] = (priv
->EEPROMThermalMeter
& 0xf);
2918 priv
->ThermalMeter
[1] = ((priv
->EEPROMThermalMeter
& 0xf0)>>4);
2922 if(priv
->rf_type
== RF_1T2R
)
2924 RT_TRACE(COMP_INIT
, "\n1T2R config\n");
2926 else if (priv
->rf_type
== RF_2T4R
)
2928 RT_TRACE(COMP_INIT
, "\n2T4R config\n");
2931 // 2008/01/16 MH We can only know RF type in the function. So we have to init
2932 // DIG RATR table again.
2933 init_rate_adaptive(dev
);
2935 //1 Make a copy for following variables and we can change them if we want
2937 priv
->rf_chip
= RF_8256
;
2939 if(priv
->RegChannelPlan
== 0xf)
2941 priv
->ChannelPlan
= priv
->eeprom_ChannelPlan
;
2945 priv
->ChannelPlan
= priv
->RegChannelPlan
;
2949 // Used PID and DID to Set CustomerID
2951 if( priv
->eeprom_vid
== 0x1186 && priv
->eeprom_did
== 0x3304 )
2953 priv
->CustomerID
= RT_CID_DLINK
;
2956 switch(priv
->eeprom_CustomerID
)
2958 case EEPROM_CID_DEFAULT
:
2959 priv
->CustomerID
= RT_CID_DEFAULT
;
2961 case EEPROM_CID_CAMEO
:
2962 priv
->CustomerID
= RT_CID_819x_CAMEO
;
2964 case EEPROM_CID_RUNTOP
:
2965 priv
->CustomerID
= RT_CID_819x_RUNTOP
;
2967 case EEPROM_CID_NetCore
:
2968 priv
->CustomerID
= RT_CID_819x_Netcore
;
2970 case EEPROM_CID_TOSHIBA
: // Merge by Jacken, 2008/01/31
2971 priv
->CustomerID
= RT_CID_TOSHIBA
;
2972 if(priv
->eeprom_ChannelPlan
&0x80)
2973 priv
->ChannelPlan
= priv
->eeprom_ChannelPlan
&0x7f;
2975 priv
->ChannelPlan
= 0x0;
2976 RT_TRACE(COMP_INIT
, "Toshiba ChannelPlan = 0x%x\n",
2979 case EEPROM_CID_Nettronix
:
2980 priv
->ScanDelay
= 100; //cosa add for scan
2981 priv
->CustomerID
= RT_CID_Nettronix
;
2983 case EEPROM_CID_Pronet
:
2984 priv
->CustomerID
= RT_CID_PRONET
;
2986 case EEPROM_CID_DLINK
:
2987 priv
->CustomerID
= RT_CID_DLINK
;
2990 case EEPROM_CID_WHQL
:
2991 //Adapter->bInHctTest = TRUE;//do not supported
2993 //priv->bSupportTurboMode = FALSE;
2994 //priv->bAutoTurboBy8186 = FALSE;
2996 //pMgntInfo->PowerSaveControl.bInactivePs = FALSE;
2997 //pMgntInfo->PowerSaveControl.bIPSModeBackup = FALSE;
2998 //pMgntInfo->PowerSaveControl.bLeisurePs = FALSE;
3002 // value from RegCustomerID
3006 //Avoid the channel plan array overflow, by Bruce, 2007-08-27.
3007 if(priv
->ChannelPlan
> CHANNEL_PLAN_LEN
- 1)
3008 priv
->ChannelPlan
= 0; //FCC
3010 switch(priv
->CustomerID
)
3012 case RT_CID_DEFAULT
:
3014 priv
->LedStrategy
= HW_LED
;
3017 priv
->LedStrategy
= SW_LED_MODE1
;
3022 case RT_CID_819x_CAMEO
:
3023 priv
->LedStrategy
= SW_LED_MODE2
;
3026 case RT_CID_819x_RUNTOP
:
3027 priv
->LedStrategy
= SW_LED_MODE3
;
3030 case RT_CID_819x_Netcore
:
3031 priv
->LedStrategy
= SW_LED_MODE4
;
3034 case RT_CID_Nettronix
:
3035 priv
->LedStrategy
= SW_LED_MODE5
;
3039 priv
->LedStrategy
= SW_LED_MODE6
;
3042 case RT_CID_TOSHIBA
: //Modify by Jacken 2008/01/31
3048 priv
->LedStrategy
= HW_LED
;
3051 priv
->LedStrategy
= SW_LED_MODE1
;
3057 //2008.06.03, for WOL
3058 if( priv->eeprom_vid == 0x1186 && priv->eeprom_did == 0x3304)
3059 priv->ieee80211->bSupportRemoteWakeUp = TRUE;
3061 priv->ieee80211->bSupportRemoteWakeUp = FALSE;
3063 RT_TRACE(COMP_INIT
, "RegChannelPlan(%d)\n", priv
->RegChannelPlan
);
3064 RT_TRACE(COMP_INIT
, "ChannelPlan = %d \n", priv
->ChannelPlan
);
3065 RT_TRACE(COMP_INIT
, "LedStrategy = %d \n", priv
->LedStrategy
);
3066 RT_TRACE(COMP_TRACE
, "<==== ReadAdapterInfo\n");
3072 static short rtl8192_get_channel_map(struct net_device
* dev
)
3074 struct r8192_priv
*priv
= ieee80211_priv(dev
);
3075 #ifdef ENABLE_DOT11D
3076 if(priv
->ChannelPlan
> COUNTRY_CODE_GLOBAL_DOMAIN
){
3077 printk("rtl8180_init:Error channel plan! Set to default.\n");
3078 priv
->ChannelPlan
= 0;
3080 RT_TRACE(COMP_INIT
, "Channel plan is %d\n",priv
->ChannelPlan
);
3082 rtl819x_set_channel_map(priv
->ChannelPlan
, priv
);
3085 //Set Default Channel Plan
3087 DMESG("No channels, aborting");
3091 priv
->ChannelPlan
= 0;//hikaru
3092 // set channels 1..14 allowed in given locale
3093 for (i
=1; i
<=14; i
++) {
3094 (priv
->ieee80211
->channel_map
)[i
] = (u8
)(ch
& 0x01);
3101 static short rtl8192_init(struct net_device
*dev
)
3103 struct r8192_priv
*priv
= ieee80211_priv(dev
);
3104 memset(&(priv
->stats
),0,sizeof(struct Stats
));
3105 rtl8192_init_priv_variable(dev
);
3106 rtl8192_init_priv_lock(priv
);
3107 rtl8192_init_priv_task(dev
);
3108 rtl8192_get_eeprom_size(dev
);
3109 rtl8192_read_eeprom_info(dev
);
3110 rtl8192_get_channel_map(dev
);
3112 init_timer(&priv
->watch_dog_timer
);
3113 priv
->watch_dog_timer
.data
= (unsigned long)dev
;
3114 priv
->watch_dog_timer
.function
= watch_dog_timer_callback
;
3115 #if defined(IRQF_SHARED)
3116 if(request_irq(dev
->irq
, (void*)rtl8192_interrupt
, IRQF_SHARED
, dev
->name
, dev
)){
3118 if(request_irq(dev
->irq
, (void *)rtl8192_interrupt
, SA_SHIRQ
, dev
->name
, dev
)){
3120 printk("Error allocating IRQ %d",dev
->irq
);
3124 printk("IRQ %d",dev
->irq
);
3126 if(rtl8192_pci_initdescring(dev
)!=0){
3127 printk("Endopoints initialization failed");
3131 //rtl8192_rx_enable(dev);
3132 //rtl8192_adapter_start(dev);
3136 /******************************************************************************
3137 *function: This function actually only set RRSR, RATR and BW_OPMODE registers
3138 * not to do all the hw config as its name says
3139 * input: net_device dev
3142 * notice: This part need to modified according to the rate set we filtered
3143 * ****************************************************************************/
3144 static void rtl8192_hwconfig(struct net_device
* dev
)
3146 u32 regRATR
= 0, regRRSR
= 0;
3147 u8 regBwOpMode
= 0, regTmp
= 0;
3148 struct r8192_priv
*priv
= ieee80211_priv(dev
);
3150 // Set RRSR, RATR, and BW_OPMODE registers
3152 switch(priv
->ieee80211
->mode
)
3154 case WIRELESS_MODE_B
:
3155 regBwOpMode
= BW_OPMODE_20MHZ
;
3156 regRATR
= RATE_ALL_CCK
;
3157 regRRSR
= RATE_ALL_CCK
;
3159 case WIRELESS_MODE_A
:
3160 regBwOpMode
= BW_OPMODE_5G
|BW_OPMODE_20MHZ
;
3161 regRATR
= RATE_ALL_OFDM_AG
;
3162 regRRSR
= RATE_ALL_OFDM_AG
;
3164 case WIRELESS_MODE_G
:
3165 regBwOpMode
= BW_OPMODE_20MHZ
;
3166 regRATR
= RATE_ALL_CCK
| RATE_ALL_OFDM_AG
;
3167 regRRSR
= RATE_ALL_CCK
| RATE_ALL_OFDM_AG
;
3169 case WIRELESS_MODE_AUTO
:
3170 case WIRELESS_MODE_N_24G
:
3171 // It support CCK rate by default.
3172 // CCK rate will be filtered out only when associated AP does not support it.
3173 regBwOpMode
= BW_OPMODE_20MHZ
;
3174 regRATR
= RATE_ALL_CCK
| RATE_ALL_OFDM_AG
| RATE_ALL_OFDM_1SS
| RATE_ALL_OFDM_2SS
;
3175 regRRSR
= RATE_ALL_CCK
| RATE_ALL_OFDM_AG
;
3177 case WIRELESS_MODE_N_5G
:
3178 regBwOpMode
= BW_OPMODE_5G
;
3179 regRATR
= RATE_ALL_OFDM_AG
| RATE_ALL_OFDM_1SS
| RATE_ALL_OFDM_2SS
;
3180 regRRSR
= RATE_ALL_OFDM_AG
;
3184 write_nic_byte(dev
, BW_OPMODE
, regBwOpMode
);
3187 ratr_value
= regRATR
;
3188 if (priv
->rf_type
== RF_1T2R
)
3190 ratr_value
&= ~(RATE_ALL_OFDM_2SS
);
3192 write_nic_dword(dev
, RATR0
, ratr_value
);
3193 write_nic_byte(dev
, UFWP
, 1);
3195 regTmp
= read_nic_byte(dev
, 0x313);
3196 regRRSR
= ((regTmp
) << 24) | (regRRSR
& 0x00ffffff);
3197 write_nic_dword(dev
, RRSR
, regRRSR
);
3200 // Set Retry Limit here
3202 write_nic_word(dev
, RETRY_LIMIT
,
3203 priv
->ShortRetryLimit
<< RETRY_LIMIT_SHORT_SHIFT
| \
3204 priv
->LongRetryLimit
<< RETRY_LIMIT_LONG_SHIFT
);
3205 // Set Contention Window here
3209 // Set Tx Antenna including Feedback control
3211 // Set Auto Rate fallback control
3217 static RT_STATUS
rtl8192_adapter_start(struct net_device
*dev
)
3219 struct r8192_priv
*priv
= ieee80211_priv(dev
);
3220 // struct ieee80211_device *ieee = priv->ieee80211;
3222 RT_STATUS rtStatus
= RT_STATUS_SUCCESS
;
3223 // static char szMACPHYRegFile[] = RTL819X_PHY_MACPHY_REG;
3224 // static char szMACPHYRegPGFile[] = RTL819X_PHY_MACPHY_REG_PG;
3228 u8 ICVersion
,SwitchingRegulatorOutput
;
3230 bool bfirmwareok
= true;
3234 u32 tmpRegA
, tmpRegC
, TempCCk
;
3236 // u32 dwRegRead = 0;
3238 RT_TRACE(COMP_INIT
, "====>%s()\n", __FUNCTION__
);
3239 priv
->being_init_adapter
= true;
3240 rtl8192_pci_resetdescring(dev
);
3241 // 2007/11/02 MH Before initalizing RF. We can not use FW to do RF-R/W.
3242 priv
->Rf_Mode
= RF_OP_By_SW_3wire
;
3245 if(priv
->ResetProgress
== RESET_TYPE_NORESET
)
3247 write_nic_byte(dev
, ANAPAR
, 0x37);
3248 // Accordign to designer's explain, LBUS active will never > 10ms. We delay 10ms
3249 // Joseph increae the time to prevent firmware download fail
3253 //PlatformSleepUs(10000);
3254 // For any kind of InitializeAdapter process, we shall use system now!!
3255 priv
->pFirmware
->firmware_status
= FW_STATUS_0_INIT
;
3257 // Set to eRfoff in order not to count receive count.
3258 if(priv
->RegRfOff
== TRUE
)
3259 priv
->ieee80211
->eRFPowerState
= eRfOff
;
3262 //3 //Config CPUReset Register
3264 //3 Firmware Reset Or Not
3265 ulRegRead
= read_nic_dword(dev
, CPU_GEN
);
3266 if(priv
->pFirmware
->firmware_status
== FW_STATUS_0_INIT
)
3267 { //called from MPInitialized. do nothing
3268 ulRegRead
|= CPU_GEN_SYSTEM_RESET
;
3269 }else if(priv
->pFirmware
->firmware_status
== FW_STATUS_5_READY
)
3270 ulRegRead
|= CPU_GEN_FIRMWARE_RESET
; // Called from MPReset
3272 RT_TRACE(COMP_ERR
, "ERROR in %s(): undefined firmware state(%d)\n", __FUNCTION__
, priv
->pFirmware
->firmware_status
);
3275 //2008.06.03, for WOL 90 hw bug
3276 ulRegRead
&= (~(CPU_GEN_GPIO_UART
));
3279 write_nic_dword(dev
, CPU_GEN
, ulRegRead
);
3285 //3 //Fix the issue of E-cut high temperature issue
3288 ICVersion
= read_nic_byte(dev
, IC_VERRSION
);
3289 if(ICVersion
>= 0x4) //E-cut only
3291 // HW SD suggest that we should not wirte this register too often, so driver
3292 // should readback this register. This register will be modified only when
3294 SwitchingRegulatorOutput
= read_nic_byte(dev
, SWREGULATOR
);
3295 if(SwitchingRegulatorOutput
!= 0xb8)
3297 write_nic_byte(dev
, SWREGULATOR
, 0xa8);
3299 write_nic_byte(dev
, SWREGULATOR
, 0xb8);
3306 //3// Initialize BB before MAC
3308 RT_TRACE(COMP_INIT
, "BB Config Start!\n");
3309 rtStatus
= rtl8192_BBConfig(dev
);
3310 if(rtStatus
!= RT_STATUS_SUCCESS
)
3312 RT_TRACE(COMP_ERR
, "BB Config failed\n");
3315 RT_TRACE(COMP_INIT
,"BB Config Finished!\n");
3317 //3//Set Loopback mode or Normal mode
3319 //2006.12.13 by emily. Note!We should not merge these two CPU_GEN register writings
3320 // because setting of System_Reset bit reset MAC to default transmission mode.
3321 //Loopback mode or not
3322 priv
->LoopbackMode
= RTL819X_NO_LOOPBACK
;
3323 //priv->LoopbackMode = RTL819X_MAC_LOOPBACK;
3324 if(priv
->ResetProgress
== RESET_TYPE_NORESET
)
3326 ulRegRead
= read_nic_dword(dev
, CPU_GEN
);
3327 if(priv
->LoopbackMode
== RTL819X_NO_LOOPBACK
)
3329 ulRegRead
= ((ulRegRead
& CPU_GEN_NO_LOOPBACK_MSK
) | CPU_GEN_NO_LOOPBACK_SET
);
3331 else if (priv
->LoopbackMode
== RTL819X_MAC_LOOPBACK
)
3333 ulRegRead
|= CPU_CCK_LOOPBACK
;
3337 RT_TRACE(COMP_ERR
,"Serious error: wrong loopback mode setting\n");
3340 //2008.06.03, for WOL
3341 //ulRegRead &= (~(CPU_GEN_GPIO_UART));
3342 write_nic_dword(dev
, CPU_GEN
, ulRegRead
);
3344 // 2006.11.29. After reset cpu, we sholud wait for a second, otherwise, it may fail to write registers. Emily
3347 //3Set Hardware(Do nothing now)
3348 rtl8192_hwconfig(dev
);
3349 //2=======================================================
3350 // Common Setting for all of the FPGA platform. (part 1)
3351 //2=======================================================
3352 // If there is changes, please make sure it applies to all of the FPGA version
3354 write_nic_byte(dev
, CMDR
, CR_RE
|CR_TE
);
3358 write_nic_byte(dev
, PCIF
, ((MXDMA2_NoLimit
<<MXDMA2_RX_SHIFT
) | \
3359 (MXDMA2_NoLimit
<<MXDMA2_TX_SHIFT
) | \
3363 write_nic_byte(dev
, PCIF
, ((MXDMA2_NoLimit
<<MXDMA2_RX_SHIFT
) |\
3364 (MXDMA2_NoLimit
<<MXDMA2_TX_SHIFT
) ));
3368 write_nic_dword(dev
, MAC0
, ((u32
*)dev
->dev_addr
)[0]);
3369 write_nic_word(dev
, MAC4
, ((u16
*)(dev
->dev_addr
+ 4))[0]);
3371 write_nic_dword(dev
, RCR
, priv
->ReceiveConfig
);
3373 //3 Initialize Number of Reserved Pages in Firmware Queue
3375 if(priv
->bInHctTest
)
3377 PlatformEFIOWrite4Byte(Adapter
, RQPN1
, NUM_OF_PAGE_IN_FW_QUEUE_BK_DTM
<< RSVD_FW_QUEUE_PAGE_BK_SHIFT
|\
3378 NUM_OF_PAGE_IN_FW_QUEUE_BE_DTM
<< RSVD_FW_QUEUE_PAGE_BE_SHIFT
| \
3379 NUM_OF_PAGE_IN_FW_QUEUE_VI_DTM
<< RSVD_FW_QUEUE_PAGE_VI_SHIFT
| \
3380 NUM_OF_PAGE_IN_FW_QUEUE_VO_DTM
<<RSVD_FW_QUEUE_PAGE_VO_SHIFT
);
3381 PlatformEFIOWrite4Byte(Adapter
, RQPN2
, NUM_OF_PAGE_IN_FW_QUEUE_MGNT
<< RSVD_FW_QUEUE_PAGE_MGNT_SHIFT
);
3382 PlatformEFIOWrite4Byte(Adapter
, RQPN3
, APPLIED_RESERVED_QUEUE_IN_FW
| \
3383 NUM_OF_PAGE_IN_FW_QUEUE_BCN
<<RSVD_FW_QUEUE_PAGE_BCN_SHIFT
|\
3384 NUM_OF_PAGE_IN_FW_QUEUE_PUB_DTM
<<RSVD_FW_QUEUE_PAGE_PUB_SHIFT
);
3389 write_nic_dword(dev
, RQPN1
, NUM_OF_PAGE_IN_FW_QUEUE_BK
<< RSVD_FW_QUEUE_PAGE_BK_SHIFT
|\
3390 NUM_OF_PAGE_IN_FW_QUEUE_BE
<< RSVD_FW_QUEUE_PAGE_BE_SHIFT
| \
3391 NUM_OF_PAGE_IN_FW_QUEUE_VI
<< RSVD_FW_QUEUE_PAGE_VI_SHIFT
| \
3392 NUM_OF_PAGE_IN_FW_QUEUE_VO
<<RSVD_FW_QUEUE_PAGE_VO_SHIFT
);
3393 write_nic_dword(dev
, RQPN2
, NUM_OF_PAGE_IN_FW_QUEUE_MGNT
<< RSVD_FW_QUEUE_PAGE_MGNT_SHIFT
);
3394 write_nic_dword(dev
, RQPN3
, APPLIED_RESERVED_QUEUE_IN_FW
| \
3395 NUM_OF_PAGE_IN_FW_QUEUE_BCN
<<RSVD_FW_QUEUE_PAGE_BCN_SHIFT
|\
3396 NUM_OF_PAGE_IN_FW_QUEUE_PUB
<<RSVD_FW_QUEUE_PAGE_PUB_SHIFT
);
3399 rtl8192_tx_enable(dev
);
3400 rtl8192_rx_enable(dev
);
3401 //3Set Response Rate Setting Register
3402 // CCK rate is supported by default.
3403 // CCK rate will be filtered out only when associated AP does not support it.
3404 ulRegRead
= (0xFFF00000 & read_nic_dword(dev
, RRSR
)) | RATE_ALL_OFDM_AG
| RATE_ALL_CCK
;
3405 write_nic_dword(dev
, RRSR
, ulRegRead
);
3406 write_nic_dword(dev
, RATR0
+4*7, (RATE_ALL_OFDM_AG
| RATE_ALL_CCK
));
3409 // TODO: (it value is only for FPGA version). need to be changed!!2006.12.18, by Emily
3410 write_nic_byte(dev
, ACK_TIMEOUT
, 0x30);
3412 //rtl8192_actset_wirelessmode(dev,priv->RegWirelessMode);
3413 if(priv
->ResetProgress
== RESET_TYPE_NORESET
)
3414 rtl8192_SetWirelessMode(dev
, priv
->ieee80211
->mode
);
3415 //-----------------------------------------------------------------------------
3416 // Set up security related. 070106, by rcnjko:
3417 // 1. Clear all H/W keys.
3418 // 2. Enable H/W encryption/decryption.
3419 //-----------------------------------------------------------------------------
3420 CamResetAllEntry(dev
);
3422 u8 SECR_value
= 0x0;
3423 SECR_value
|= SCR_TxEncEnable
;
3424 SECR_value
|= SCR_RxDecEnable
;
3425 SECR_value
|= SCR_NoSKMC
;
3426 write_nic_byte(dev
, SECR
, SECR_value
);
3429 write_nic_word(dev
, ATIMWND
, 2);
3430 write_nic_word(dev
, BCN_INTERVAL
, 100);
3431 for (i
=0; i
<QOS_QUEUE_NUM
; i
++)
3432 write_nic_dword(dev
, WDCAPARA_ADD
[i
], 0x005e4332);
3434 // Switching regulator controller: This is set temporarily.
3435 // It's not sure if this can be removed in the future.
3436 // PJ advised to leave it by default.
3438 write_nic_byte(dev
, 0xbe, 0xc0);
3440 //2=======================================================
3441 // Set PHY related configuration defined in MAC register bank
3442 //2=======================================================
3443 rtl8192_phy_configmac(dev
);
3445 if (priv
->card_8192_version
> (u8
) VERSION_8190_BD
) {
3446 rtl8192_phy_getTxPower(dev
);
3447 rtl8192_phy_setTxPower(dev
, priv
->chan
);
3451 tmpvalue
= read_nic_byte(dev
, IC_VERRSION
);
3452 priv
->IC_Cut
= tmpvalue
;
3453 RT_TRACE(COMP_INIT
, "priv->IC_Cut = 0x%x\n", priv
->IC_Cut
);
3454 if(priv
->IC_Cut
>= IC_VersionCut_D
)
3456 //pHalData->bDcut = TRUE;
3457 if(priv
->IC_Cut
== IC_VersionCut_D
)
3458 RT_TRACE(COMP_INIT
, "D-cut\n");
3459 if(priv
->IC_Cut
== IC_VersionCut_E
)
3461 RT_TRACE(COMP_INIT
, "E-cut\n");
3462 // HW SD suggest that we should not wirte this register too often, so driver
3463 // should readback this register. This register will be modified only when
3469 //pHalData->bDcut = FALSE;
3470 RT_TRACE(COMP_INIT
, "Before C-cut\n");
3475 RT_TRACE(COMP_INIT
, "Load Firmware!\n");
3476 bfirmwareok
= init_firmware(dev
);
3477 if(bfirmwareok
!= true) {
3478 rtStatus
= RT_STATUS_FAILURE
;
3481 RT_TRACE(COMP_INIT
, "Load Firmware finished!\n");
3484 if(priv
->ResetProgress
== RESET_TYPE_NORESET
)
3486 RT_TRACE(COMP_INIT
, "RF Config Started!\n");
3487 rtStatus
= rtl8192_phy_RFConfig(dev
);
3488 if(rtStatus
!= RT_STATUS_SUCCESS
)
3490 RT_TRACE(COMP_ERR
, "RF Config failed\n");
3493 RT_TRACE(COMP_INIT
, "RF Config Finished!\n");
3495 rtl8192_phy_updateInitGain(dev
);
3497 /*---- Set CCK and OFDM Block "ON"----*/
3498 rtl8192_setBBreg(dev
, rFPGA0_RFMOD
, bCCKEn
, 0x1);
3499 rtl8192_setBBreg(dev
, rFPGA0_RFMOD
, bOFDMEn
, 0x1);
3503 write_nic_byte(dev
, 0x87, 0x0);
3506 //2008.06.03, for WOL
3507 ucRegRead
= read_nic_byte(dev
, GPE
);
3509 write_nic_byte(dev
, GPE
, ucRegRead
);
3511 ucRegRead
= read_nic_byte(dev
, GPO
);
3513 write_nic_byte(dev
, GPO
, ucRegRead
);
3516 //2=======================================================
3518 //2=======================================================
3522 if(priv
->RegRfOff
== TRUE
)
3523 { // User disable RF via registry.
3524 RT_TRACE((COMP_INIT
|COMP_RF
|COMP_POWER
), "%s(): Turn off RF for RegRfOff ----------\n",__FUNCTION__
);
3525 MgntActSet_RF_State(dev
, eRfOff
, RF_CHANGE_BY_SW
);
3526 #if 0//cosa, ask SD3 willis and he doesn't know what is this for
3527 // Those action will be discard in MgntActSet_RF_State because off the same state
3528 for(eRFPath
= 0; eRFPath
<pHalData
->NumTotalRFPath
; eRFPath
++)
3529 PHY_SetRFReg(Adapter
, (RF90_RADIO_PATH_E
)eRFPath
, 0x4, 0xC00, 0x0);
3532 else if(priv
->ieee80211
->RfOffReason
> RF_CHANGE_BY_PS
)
3533 { // H/W or S/W RF OFF before sleep.
3534 RT_TRACE((COMP_INIT
|COMP_RF
|COMP_POWER
), "%s(): Turn off RF for RfOffReason(%d) ----------\n", __FUNCTION__
,priv
->ieee80211
->RfOffReason
);
3535 MgntActSet_RF_State(dev
, eRfOff
, priv
->ieee80211
->RfOffReason
);
3537 else if(priv
->ieee80211
->RfOffReason
>= RF_CHANGE_BY_IPS
)
3538 { // H/W or S/W RF OFF before sleep.
3539 RT_TRACE((COMP_INIT
|COMP_RF
|COMP_POWER
), "%s(): Turn off RF for RfOffReason(%d) ----------\n", __FUNCTION__
,priv
->ieee80211
->RfOffReason
);
3540 MgntActSet_RF_State(dev
, eRfOff
, priv
->ieee80211
->RfOffReason
);
3544 RT_TRACE((COMP_INIT
|COMP_RF
|COMP_POWER
), "%s(): RF-ON \n",__FUNCTION__
);
3545 priv
->ieee80211
->eRFPowerState
= eRfOn
;
3546 priv
->ieee80211
->RfOffReason
= 0;
3547 //DrvIFIndicateCurrentPhyStatus(Adapter);
3549 //Adapter->HalFunc.LedControlHandler(Adapter, LED_CTL_POWER_ON);
3552 // If inactive power mode is enabled, disable rf while in disconnected state.
3553 // But we should still tell upper layer we are in rf on state.
3554 // 2007.07.16, by shien chang.
3556 //if(!Adapter->bInHctTest)
3557 //IPSEnter(Adapter);
3564 // We can force firmware to do RF-R/W
3565 if(priv
->ieee80211
->FwRWRF
)
3566 priv
->Rf_Mode
= RF_OP_By_FW
;
3568 priv
->Rf_Mode
= RF_OP_By_SW_3wire
;
3570 priv
->Rf_Mode
= RF_OP_By_SW_3wire
;
3574 if(priv
->ResetProgress
== RESET_TYPE_NORESET
)
3576 dm_initialize_txpower_tracking(dev
);
3578 tmpRegA
= rtl8192_QueryBBReg(dev
,rOFDM0_XATxIQImbalance
,bMaskDWord
);
3579 tmpRegC
= rtl8192_QueryBBReg(dev
,rOFDM0_XCTxIQImbalance
,bMaskDWord
);
3581 if(priv
->rf_type
== RF_2T4R
){
3582 for(i
= 0; i
<TxBBGainTableLength
; i
++)
3584 if(tmpRegA
== priv
->txbbgain_table
[i
].txbbgain_value
)
3586 priv
->rfa_txpowertrackingindex
= (u8
)i
;
3587 priv
->rfa_txpowertrackingindex_real
= (u8
)i
;
3588 priv
->rfa_txpowertracking_default
= priv
->rfa_txpowertrackingindex
;
3593 for(i
= 0; i
<TxBBGainTableLength
; i
++)
3595 if(tmpRegC
== priv
->txbbgain_table
[i
].txbbgain_value
)
3597 priv
->rfc_txpowertrackingindex
= (u8
)i
;
3598 priv
->rfc_txpowertrackingindex_real
= (u8
)i
;
3599 priv
->rfc_txpowertracking_default
= priv
->rfc_txpowertrackingindex
;
3603 TempCCk
= rtl8192_QueryBBReg(dev
, rCCK0_TxFilter1
, bMaskByte2
);
3605 for(i
=0 ; i
<CCKTxBBGainTableLength
; i
++)
3607 if(TempCCk
== priv
->cck_txbbgain_table
[i
].ccktxbb_valuearray
[0])
3609 priv
->CCKPresentAttentuation_20Mdefault
=(u8
) i
;
3613 priv
->CCKPresentAttentuation_40Mdefault
= 0;
3614 priv
->CCKPresentAttentuation_difference
= 0;
3615 priv
->CCKPresentAttentuation
= priv
->CCKPresentAttentuation_20Mdefault
;
3616 RT_TRACE(COMP_POWER_TRACKING
, "priv->rfa_txpowertrackingindex_initial = %d\n", priv
->rfa_txpowertrackingindex
);
3617 RT_TRACE(COMP_POWER_TRACKING
, "priv->rfa_txpowertrackingindex_real__initial = %d\n", priv
->rfa_txpowertrackingindex_real
);
3618 RT_TRACE(COMP_POWER_TRACKING
, "priv->rfc_txpowertrackingindex_initial = %d\n", priv
->rfc_txpowertrackingindex
);
3619 RT_TRACE(COMP_POWER_TRACKING
, "priv->rfc_txpowertrackingindex_real_initial = %d\n", priv
->rfc_txpowertrackingindex_real
);
3620 RT_TRACE(COMP_POWER_TRACKING
, "priv->CCKPresentAttentuation_difference_initial = %d\n", priv
->CCKPresentAttentuation_difference
);
3621 RT_TRACE(COMP_POWER_TRACKING
, "priv->CCKPresentAttentuation_initial = %d\n", priv
->CCKPresentAttentuation
);
3625 if(priv
->ResetProgress
== RESET_TYPE_NORESET
)
3627 dm_initialize_txpower_tracking(dev
);
3629 if(priv
->IC_Cut
>= IC_VersionCut_D
)
3631 tmpRegA
= rtl8192_QueryBBReg(dev
,rOFDM0_XATxIQImbalance
,bMaskDWord
);
3632 tmpRegC
= rtl8192_QueryBBReg(dev
,rOFDM0_XCTxIQImbalance
,bMaskDWord
);
3633 for(i
= 0; i
<TxBBGainTableLength
; i
++)
3635 if(tmpRegA
== priv
->txbbgain_table
[i
].txbbgain_value
)
3637 priv
->rfa_txpowertrackingindex
= (u8
)i
;
3638 priv
->rfa_txpowertrackingindex_real
= (u8
)i
;
3639 priv
->rfa_txpowertracking_default
= priv
->rfa_txpowertrackingindex
;
3644 TempCCk
= rtl8192_QueryBBReg(dev
, rCCK0_TxFilter1
, bMaskByte2
);
3646 for(i
=0 ; i
<CCKTxBBGainTableLength
; i
++)
3648 if(TempCCk
== priv
->cck_txbbgain_table
[i
].ccktxbb_valuearray
[0])
3650 priv
->CCKPresentAttentuation_20Mdefault
=(u8
) i
;
3654 priv
->CCKPresentAttentuation_40Mdefault
= 0;
3655 priv
->CCKPresentAttentuation_difference
= 0;
3656 priv
->CCKPresentAttentuation
= priv
->CCKPresentAttentuation_20Mdefault
;
3657 RT_TRACE(COMP_POWER_TRACKING
, "priv->rfa_txpowertrackingindex_initial = %d\n", priv
->rfa_txpowertrackingindex
);
3658 RT_TRACE(COMP_POWER_TRACKING
, "priv->rfa_txpowertrackingindex_real__initial = %d\n", priv
->rfa_txpowertrackingindex_real
);
3659 RT_TRACE(COMP_POWER_TRACKING
, "priv->CCKPresentAttentuation_difference_initial = %d\n", priv
->CCKPresentAttentuation_difference
);
3660 RT_TRACE(COMP_POWER_TRACKING
, "priv->CCKPresentAttentuation_initial = %d\n", priv
->CCKPresentAttentuation
);
3661 priv
->btxpower_tracking
= FALSE
;//TEMPLY DISABLE
3666 rtl8192_irq_enable(dev
);
3667 priv
->being_init_adapter
= false;
3672 void rtl8192_prepare_beacon(struct r8192_priv
*priv
)
3674 struct sk_buff
*skb
;
3675 //unsigned long flags;
3678 skb
= ieee80211_get_beacon(priv
->ieee80211
);
3679 tcb_desc
= (cb_desc
*)(skb
->cb
+ 8);
3680 //printk("===========> %s\n", __FUNCTION__);
3681 //spin_lock_irqsave(&priv->tx_lock,flags);
3682 /* prepare misc info for the beacon xmit */
3683 tcb_desc
->queue_index
= BEACON_QUEUE
;
3684 /* IBSS does not support HT yet, use 1M defautly */
3685 tcb_desc
->data_rate
= 2;
3686 tcb_desc
->RATRIndex
= 7;
3687 tcb_desc
->bTxDisableRateFallBack
= 1;
3688 tcb_desc
->bTxUseDriverAssingedRate
= 1;
3690 skb_push(skb
, priv
->ieee80211
->tx_headroom
);
3692 rtl8192_tx(priv
->ieee80211
->dev
,skb
);
3694 //spin_unlock_irqrestore (&priv->tx_lock, flags);
3698 /* this configures registers for beacon tx and enables it via
3699 * rtl8192_beacon_tx_enable(). rtl8192_beacon_tx_disable() might
3700 * be used to stop beacon transmission
3702 void rtl8192_start_beacon(struct net_device
*dev
)
3704 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
3705 struct ieee80211_network
*net
= &priv
->ieee80211
->current_network
;
3710 DMESG("Enabling beacon TX");
3711 //rtl8192_prepare_beacon(dev);
3712 rtl8192_irq_disable(dev
);
3713 //rtl8192_beacon_tx_enable(dev);
3716 write_nic_word(dev
, ATIMWND
, 2);
3718 /* Beacon interval (in unit of TU) */
3719 write_nic_word(dev
, BCN_INTERVAL
, net
->beacon_interval
);
3722 * DrvErlyInt (in unit of TU).
3723 * (Time to send interrupt to notify driver to c
3724 * hange beacon content)
3726 write_nic_word(dev
, BCN_DRV_EARLY_INT
, 10);
3729 * BcnDMATIM(in unit of us).
3730 * Indicates the time before TBTT to perform beacon queue DMA
3732 write_nic_word(dev
, BCN_DMATIME
, 256);
3735 * Force beacon frame transmission even after receiving
3736 * beacon frame from other ad hoc STA
3738 write_nic_byte(dev
, BCN_ERR_THRESH
, 100);
3740 /* Set CW and IFS */
3741 BcnTimeCfg
|= BcnCW
<<BCN_TCFG_CW_SHIFT
;
3742 BcnTimeCfg
|= BcnIFS
<<BCN_TCFG_IFS
;
3743 write_nic_word(dev
, BCN_TCFG
, BcnTimeCfg
);
3746 /* enable the interrupt for ad-hoc process */
3747 rtl8192_irq_enable(dev
);
3749 /***************************************************************************
3750 -------------------------------NET STUFF---------------------------
3751 ***************************************************************************/
3755 static bool HalTxCheckStuck8190Pci(struct net_device
*dev
)
3757 u16 RegTxCounter
= read_nic_word(dev
, 0x128);
3758 struct r8192_priv
*priv
= ieee80211_priv(dev
);
3759 bool bStuck
= FALSE
;
3760 RT_TRACE(COMP_RESET
,"%s():RegTxCounter is %d,TxCounter is %d\n",__FUNCTION__
,RegTxCounter
,priv
->TxCounter
);
3761 if(priv
->TxCounter
==RegTxCounter
)
3764 priv
->TxCounter
= RegTxCounter
;
3770 * <Assumption: RT_TX_SPINLOCK is acquired.>
3771 * First added: 2006.11.19 by emily
3774 TxCheckStuck(struct net_device
*dev
)
3776 struct r8192_priv
*priv
= ieee80211_priv(dev
);
3778 ptx_ring head
=NULL
,tail
=NULL
,txring
= NULL
;
3779 u8 ResetThreshold
= NIC_SEND_HANG_THRESHOLD_POWERSAVE
;
3780 bool bCheckFwTxCnt
= false;
3781 //unsigned long flags;
3784 // Decide Stuch threshold according to current power save mode
3786 //printk("++++++++++++>%s()\n",__FUNCTION__);
3787 switch (priv
->ieee80211
->dot11PowerSaveMode
)
3789 // The threshold value may required to be adjusted .
3790 case eActive
: // Active/Continuous access.
3791 ResetThreshold
= NIC_SEND_HANG_THRESHOLD_NORMAL
;
3793 case eMaxPs
: // Max power save mode.
3794 ResetThreshold
= NIC_SEND_HANG_THRESHOLD_POWERSAVE
;
3796 case eFastPs
: // Fast power save mode.
3797 ResetThreshold
= NIC_SEND_HANG_THRESHOLD_POWERSAVE
;
3802 // Check whether specific tcb has been queued for a specific time
3804 for(QueueID
= 0; QueueID
< MAX_TX_QUEUE
; QueueID
++)
3808 if(QueueID
== TXCMD_QUEUE
)
3813 tail
=priv
->txmapringtail
;
3814 head
=priv
->txmapringhead
;
3818 tail
=priv
->txbkpringtail
;
3819 head
=priv
->txbkpringhead
;
3823 tail
=priv
->txbepringtail
;
3824 head
=priv
->txbepringhead
;
3828 tail
=priv
->txvipringtail
;
3829 head
=priv
->txvipringhead
;
3833 tail
=priv
->txvopringtail
;
3834 head
=priv
->txvopringhead
;
3849 RT_TRACE(COMP_ERR
,"%s():txring is NULL , BUG!\n",__FUNCTION__
);
3852 txring
->nStuckCount
++;
3853 bCheckFwTxCnt
= TRUE
;
3859 if(HalTxCheckStuck8190Pci(dev
))
3861 RT_TRACE(COMP_RESET
, "TxCheckStuck(): Fw indicates no Tx condition! \n");
3862 return RESET_TYPE_SILENT
;
3866 return RESET_TYPE_NORESET
;
3870 static bool HalRxCheckStuck8190Pci(struct net_device
*dev
)
3872 struct r8192_priv
*priv
= ieee80211_priv(dev
);
3873 u16 RegRxCounter
= read_nic_word(dev
, 0x130);
3874 bool bStuck
= FALSE
;
3875 static u8 rx_chk_cnt
= 0;
3876 RT_TRACE(COMP_RESET
,"%s(): RegRxCounter is %d,RxCounter is %d\n",__FUNCTION__
,RegRxCounter
,priv
->RxCounter
);
3877 // If rssi is small, we should check rx for long time because of bad rx.
3878 // or maybe it will continuous silent reset every 2 seconds.
3880 if(priv
->undecorated_smoothed_pwdb
>= (RateAdaptiveTH_High
+5))
3882 rx_chk_cnt
= 0; //high rssi, check rx stuck right now.
3884 else if(priv
->undecorated_smoothed_pwdb
< (RateAdaptiveTH_High
+5) &&
3885 ((priv
->CurrentChannelBW
!=HT_CHANNEL_WIDTH_20
&&priv
->undecorated_smoothed_pwdb
>=RateAdaptiveTH_Low_40M
) ||
3886 (priv
->CurrentChannelBW
==HT_CHANNEL_WIDTH_20
&&priv
->undecorated_smoothed_pwdb
>=RateAdaptiveTH_Low_20M
)) )
3898 else if(((priv
->CurrentChannelBW
!=HT_CHANNEL_WIDTH_20
&&priv
->undecorated_smoothed_pwdb
<RateAdaptiveTH_Low_40M
) ||
3899 (priv
->CurrentChannelBW
==HT_CHANNEL_WIDTH_20
&&priv
->undecorated_smoothed_pwdb
<RateAdaptiveTH_Low_20M
)) &&
3900 priv
->undecorated_smoothed_pwdb
>= VeryLowRSSI
)
3904 //DbgPrint("RSSI < %d && RSSI >= %d, no check this time \n", RateAdaptiveTH_Low, VeryLowRSSI);
3910 //DbgPrint("RSSI < %d && RSSI >= %d, check this time \n", RateAdaptiveTH_Low, VeryLowRSSI);
3917 //DbgPrint("RSSI <= %d, no check this time \n", VeryLowRSSI);
3923 //DbgPrint("RSSI <= %d, check this time \n", VeryLowRSSI);
3926 if(priv
->RxCounter
==RegRxCounter
)
3929 priv
->RxCounter
= RegRxCounter
;
3934 static RESET_TYPE
RxCheckStuck(struct net_device
*dev
)
3937 if(HalRxCheckStuck8190Pci(dev
))
3939 RT_TRACE(COMP_RESET
, "RxStuck Condition\n");
3940 return RESET_TYPE_SILENT
;
3943 return RESET_TYPE_NORESET
;
3947 rtl819x_ifcheck_resetornot(struct net_device
*dev
)
3949 struct r8192_priv
*priv
= ieee80211_priv(dev
);
3950 RESET_TYPE TxResetType
= RESET_TYPE_NORESET
;
3951 RESET_TYPE RxResetType
= RESET_TYPE_NORESET
;
3952 RT_RF_POWER_STATE rfState
;
3954 rfState
= priv
->ieee80211
->eRFPowerState
;
3956 TxResetType
= TxCheckStuck(dev
);
3958 if( rfState
!= eRfOff
&&
3959 /*ADAPTER_TEST_STATUS_FLAG(Adapter, ADAPTER_STATUS_FW_DOWNLOAD_FAILURE)) &&*/
3960 (priv
->ieee80211
->iw_mode
!= IW_MODE_ADHOC
))
3962 // If driver is in the status of firmware download failure , driver skips RF initialization and RF is
3963 // in turned off state. Driver should check whether Rx stuck and do silent reset. And
3964 // if driver is in firmware download failure status, driver should initialize RF in the following
3965 // silent reset procedure Emily, 2008.01.21
3967 // Driver should not check RX stuck in IBSS mode because it is required to
3968 // set Check BSSID in order to send beacon, however, if check BSSID is
3969 // set, STA cannot hear any packet a all. Emily, 2008.04.12
3970 RxResetType
= RxCheckStuck(dev
);
3974 RT_TRACE(COMP_RESET
,"%s(): TxResetType is %d, RxResetType is %d\n",__FUNCTION__
,TxResetType
,RxResetType
);
3975 if(TxResetType
==RESET_TYPE_NORMAL
|| RxResetType
==RESET_TYPE_NORMAL
)
3976 return RESET_TYPE_NORMAL
;
3977 else if(TxResetType
==RESET_TYPE_SILENT
|| RxResetType
==RESET_TYPE_SILENT
)
3978 return RESET_TYPE_SILENT
;
3980 return RESET_TYPE_NORESET
;
3985 static void CamRestoreAllEntry(struct net_device
*dev
)
3988 struct r8192_priv
*priv
= ieee80211_priv(dev
);
3989 u8
* MacAddr
= priv
->ieee80211
->current_network
.bssid
;
3991 static u8 CAM_CONST_ADDR
[4][6] = {
3992 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
3993 {0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
3994 {0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
3995 {0x00, 0x00, 0x00, 0x00, 0x00, 0x03}};
3996 static u8 CAM_CONST_BROAD
[] =
3997 {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
3999 RT_TRACE(COMP_SEC
, "CamRestoreAllEntry: \n");
4002 if ((priv
->ieee80211
->pairwise_key_type
== KEY_TYPE_WEP40
)||
4003 (priv
->ieee80211
->pairwise_key_type
== KEY_TYPE_WEP104
))
4006 for(EntryId
=0; EntryId
<4; EntryId
++)
4009 MacAddr
= CAM_CONST_ADDR
[EntryId
];
4013 priv
->ieee80211
->pairwise_key_type
,
4021 else if(priv
->ieee80211
->pairwise_key_type
== KEY_TYPE_TKIP
)
4025 if(priv
->ieee80211
->iw_mode
== IW_MODE_ADHOC
)
4029 priv
->ieee80211
->pairwise_key_type
,
4037 priv
->ieee80211
->pairwise_key_type
,
4043 else if(priv
->ieee80211
->pairwise_key_type
== KEY_TYPE_CCMP
)
4047 if(priv
->ieee80211
->iw_mode
== IW_MODE_ADHOC
)
4051 priv
->ieee80211
->pairwise_key_type
,
4059 priv
->ieee80211
->pairwise_key_type
,
4068 if(priv
->ieee80211
->group_key_type
== KEY_TYPE_TKIP
)
4070 MacAddr
= CAM_CONST_BROAD
;
4071 for(EntryId
=1 ; EntryId
<4 ; EntryId
++)
4077 priv
->ieee80211
->group_key_type
,
4083 if(priv
->ieee80211
->iw_mode
== IW_MODE_ADHOC
)
4087 priv
->ieee80211
->group_key_type
,
4092 else if(priv
->ieee80211
->group_key_type
== KEY_TYPE_CCMP
)
4094 MacAddr
= CAM_CONST_BROAD
;
4095 for(EntryId
=1; EntryId
<4 ; EntryId
++)
4101 priv
->ieee80211
->group_key_type
,
4108 if(priv
->ieee80211
->iw_mode
== IW_MODE_ADHOC
)
4112 priv
->ieee80211
->group_key_type
,
4119 void rtl8192_cancel_deferred_work(struct r8192_priv
* priv
);
4120 int _rtl8192_up(struct net_device
*dev
);
4123 * This function is used to fix Tx/Rx stop bug temporarily.
4124 * This function will do "system reset" to NIC when Tx or Rx is stuck.
4125 * The method checking Tx/Rx stuck of this function is supported by FW,
4126 * which reports Tx and Rx counter to register 0x128 and 0x130.
4128 static void rtl819x_ifsilentreset(struct net_device
*dev
)
4130 struct r8192_priv
*priv
= ieee80211_priv(dev
);
4132 int reset_status
= 0;
4133 struct ieee80211_device
*ieee
= priv
->ieee80211
;
4136 // 2007.07.20. If we need to check CCK stop, please uncomment this line.
4137 //bStuck = Adapter->HalFunc.CheckHWStopHandler(Adapter);
4139 if(priv
->ResetProgress
==RESET_TYPE_NORESET
)
4143 RT_TRACE(COMP_RESET
,"=========>Reset progress!! \n");
4145 // Set the variable for reset.
4146 priv
->ResetProgress
= RESET_TYPE_SILENT
;
4147 // rtl8192_close(dev);
4149 down(&priv
->wx_sem
);
4152 RT_TRACE(COMP_ERR
,"%s():the driver is not up! return\n",__FUNCTION__
);
4157 RT_TRACE(COMP_RESET
,"%s():======>start to down the driver\n",__FUNCTION__
);
4158 if(!netif_queue_stopped(dev
))
4159 netif_stop_queue(dev
);
4161 dm_backup_dynamic_mechanism_state(dev
);
4163 rtl8192_irq_disable(dev
);
4164 rtl8192_cancel_deferred_work(priv
);
4166 del_timer_sync(&priv
->watch_dog_timer
);
4167 ieee
->sync_scan_hurryup
= 1;
4168 if(ieee
->state
== IEEE80211_LINKED
)
4170 down(&ieee
->wx_sem
);
4171 printk("ieee->state is IEEE80211_LINKED\n");
4172 ieee80211_stop_send_beacons(priv
->ieee80211
);
4173 del_timer_sync(&ieee
->associate_timer
);
4174 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
4175 cancel_delayed_work(&ieee
->associate_retry_wq
);
4177 ieee80211_stop_scan(ieee
);
4178 netif_carrier_off(dev
);
4182 printk("ieee->state is NOT LINKED\n");
4183 ieee80211_softmac_stop_protocol(priv
->ieee80211
);
4185 rtl8192_rtx_disable(dev
);
4187 RT_TRACE(COMP_RESET
,"%s():<==========down process is finished\n",__FUNCTION__
);
4188 RT_TRACE(COMP_RESET
,"%s():===========>start to up the driver\n",__FUNCTION__
);
4189 reset_status
= _rtl8192_up(dev
);
4191 RT_TRACE(COMP_RESET
,"%s():<===========up process is finished\n",__FUNCTION__
);
4192 if(reset_status
== -1)
4201 RT_TRACE(COMP_ERR
," ERR!!! %s(): Reset Failed!!\n",__FUNCTION__
);
4205 ieee
->is_silent_reset
= 1;
4207 EnableHWSecurityConfig8192(dev
);
4209 if(ieee
->state
== IEEE80211_LINKED
&& ieee
->iw_mode
== IW_MODE_INFRA
)
4211 ieee
->set_chan(ieee
->dev
, ieee
->current_network
.channel
);
4214 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
4215 queue_work(ieee
->wq
, &ieee
->associate_complete_wq
);
4217 schedule_task(&ieee
->associate_complete_wq
);
4222 else if(ieee
->state
== IEEE80211_LINKED
&& ieee
->iw_mode
== IW_MODE_ADHOC
)
4224 ieee
->set_chan(ieee
->dev
, ieee
->current_network
.channel
);
4225 ieee
->link_change(ieee
->dev
);
4227 // notify_wx_assoc_event(ieee);
4229 ieee80211_start_send_beacons(ieee
);
4231 if (ieee
->data_hard_resume
)
4232 ieee
->data_hard_resume(ieee
->dev
);
4233 netif_carrier_on(ieee
->dev
);
4237 CamRestoreAllEntry(dev
);
4239 // Restore the previous setting for all dynamic mechanism
4240 dm_restore_dynamic_mechanism_state(dev
);
4242 priv
->ResetProgress
= RESET_TYPE_NORESET
;
4243 priv
->reset_count
++;
4245 priv
->bForcedSilentReset
=false;
4246 priv
->bResetInProgress
= false;
4248 // For test --> force write UFWP.
4249 write_nic_byte(dev
, UFWP
, 1);
4250 RT_TRACE(COMP_RESET
, "Reset finished!! ====>[%d]\n", priv
->reset_count
);
4256 void InactivePsWorkItemCallback(struct net_device
*dev
)
4258 struct r8192_priv
*priv
= ieee80211_priv(dev
);
4259 PRT_POWER_SAVE_CONTROL pPSC
= (PRT_POWER_SAVE_CONTROL
)(&(priv
->ieee80211
->PowerSaveControl
));
4262 RT_TRACE(COMP_POWER
, "InactivePsWorkItemCallback() ---------> \n");
4264 // This flag "bSwRfProcessing", indicates the status of IPS procedure, should be set if the IPS workitem
4265 // is really scheduled.
4266 // The old code, sets this flag before scheduling the IPS workitem and however, at the same time the
4267 // previous IPS workitem did not end yet, fails to schedule the current workitem. Thus, bSwRfProcessing
4268 // blocks the IPS procedure of switching RF.
4269 // By Bruce, 2007-12-25.
4271 pPSC
->bSwRfProcessing
= TRUE
;
4273 RT_TRACE(COMP_RF
, "InactivePsWorkItemCallback(): Set RF to %s.\n", \
4274 pPSC
->eInactivePowerState
== eRfOff
?"OFF":"ON");
4277 MgntActSet_RF_State(dev
, pPSC
->eInactivePowerState
, RF_CHANGE_BY_IPS
);
4280 // To solve CAM values miss in RF OFF, rewrite CAM values after RF ON. By Bruce, 2007-09-20.
4282 pPSC
->bSwRfProcessing
= FALSE
;
4283 RT_TRACE(COMP_POWER
, "InactivePsWorkItemCallback() <--------- \n");
4288 // Enter the inactive power save mode. RF will be off
4289 // 2007.08.17, by shien chang.
4292 IPSEnter(struct net_device
*dev
)
4294 struct r8192_priv
*priv
= ieee80211_priv(dev
);
4295 PRT_POWER_SAVE_CONTROL pPSC
= (PRT_POWER_SAVE_CONTROL
)(&(priv
->ieee80211
->PowerSaveControl
));
4296 RT_RF_POWER_STATE rtState
;
4298 if (pPSC
->bInactivePs
)
4300 rtState
= priv
->ieee80211
->eRFPowerState
;
4302 // Added by Bruce, 2007-12-25.
4303 // Do not enter IPS in the following conditions:
4304 // (1) RF is already OFF or Sleep
4305 // (2) bSwRfProcessing (indicates the IPS is still under going)
4306 // (3) Connectted (only disconnected can trigger IPS)
4307 // (4) IBSS (send Beacon)
4308 // (5) AP mode (send Beacon)
4310 if (rtState
== eRfOn
&& !pPSC
->bSwRfProcessing
4311 && (priv
->ieee80211
->state
!= IEEE80211_LINKED
) )
4313 RT_TRACE(COMP_RF
,"IPSEnter(): Turn off RF.\n");
4314 pPSC
->eInactivePowerState
= eRfOff
;
4315 // queue_work(priv->priv_wq,&(pPSC->InactivePsWorkItem));
4316 InactivePsWorkItemCallback(dev
);
4323 // Leave the inactive power save mode, RF will be on.
4324 // 2007.08.17, by shien chang.
4327 IPSLeave(struct net_device
*dev
)
4329 struct r8192_priv
*priv
= ieee80211_priv(dev
);
4330 PRT_POWER_SAVE_CONTROL pPSC
= (PRT_POWER_SAVE_CONTROL
)(&(priv
->ieee80211
->PowerSaveControl
));
4331 RT_RF_POWER_STATE rtState
;
4333 if (pPSC
->bInactivePs
)
4335 rtState
= priv
->ieee80211
->eRFPowerState
;
4336 if (rtState
!= eRfOn
&& !pPSC
->bSwRfProcessing
&& priv
->ieee80211
->RfOffReason
<= RF_CHANGE_BY_IPS
)
4338 RT_TRACE(COMP_POWER
, "IPSLeave(): Turn on RF.\n");
4339 pPSC
->eInactivePowerState
= eRfOn
;
4340 // queue_work(priv->priv_wq,&(pPSC->InactivePsWorkItem));
4341 InactivePsWorkItemCallback(dev
);
4347 static void rtl819x_update_rxcounts(
4348 struct r8192_priv
*priv
,
4357 *TotalRxDataNum
= 0;
4359 SlotIndex
= (priv
->ieee80211
->LinkDetectInfo
.SlotIndex
++)%(priv
->ieee80211
->LinkDetectInfo
.SlotNum
);
4360 priv
->ieee80211
->LinkDetectInfo
.RxBcnNum
[SlotIndex
] = priv
->ieee80211
->LinkDetectInfo
.NumRecvBcnInPeriod
;
4361 priv
->ieee80211
->LinkDetectInfo
.RxDataNum
[SlotIndex
] = priv
->ieee80211
->LinkDetectInfo
.NumRecvDataInPeriod
;
4362 for( i
=0; i
<priv
->ieee80211
->LinkDetectInfo
.SlotNum
; i
++ ){
4363 *TotalRxBcnNum
+= priv
->ieee80211
->LinkDetectInfo
.RxBcnNum
[i
];
4364 *TotalRxDataNum
+= priv
->ieee80211
->LinkDetectInfo
.RxDataNum
[i
];
4369 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
4370 void rtl819x_watchdog_wqcallback(struct work_struct
*work
)
4372 struct delayed_work
*dwork
= container_of(work
,struct delayed_work
,work
);
4373 struct r8192_priv
*priv
= container_of(dwork
,struct r8192_priv
,watch_dog_wq
);
4374 struct net_device
*dev
= priv
->ieee80211
->dev
;
4376 extern void rtl819x_watchdog_wqcallback(struct net_device
*dev
)
4378 struct r8192_priv
*priv
= ieee80211_priv(dev
);
4380 struct ieee80211_device
* ieee
= priv
->ieee80211
;
4381 RESET_TYPE ResetType
= RESET_TYPE_NORESET
;
4382 static u8 check_reset_cnt
=0;
4383 unsigned long flags
;
4384 bool bBusyTraffic
= false;
4385 static u8 last_time
= 0;
4388 hal_dm_watchdog(dev
);
4390 // printk("watch_dog ENABLE_IPS\n");
4391 if(ieee
->actscanning
== false){
4392 if((ieee
->iw_mode
!= IW_MODE_ADHOC
) && (ieee
->state
== IEEE80211_NOLINK
) && (ieee
->beinretry
== false) && (ieee
->eRFPowerState
== eRfOn
) && !ieee
->is_set_key
){
4393 if(ieee
->PowerSaveControl
.ReturnPoint
== IPS_CALLBACK_NONE
){
4394 printk("====================>haha:IPSEnter()\n");
4396 //ieee80211_stop_scan(priv->ieee80211);
4401 {//to get busy traffic condition
4402 if(ieee
->state
== IEEE80211_LINKED
)
4404 if( ieee
->LinkDetectInfo
.NumRxOkInPeriod
> 666 ||
4405 ieee
->LinkDetectInfo
.NumTxOkInPeriod
> 666 ) {
4406 bBusyTraffic
= true;
4410 ieee
->LinkDetectInfo
.NumRxOkInPeriod
= 0;
4411 ieee
->LinkDetectInfo
.NumTxOkInPeriod
= 0;
4412 ieee
->LinkDetectInfo
.bBusyTraffic
= bBusyTraffic
;
4416 //added by amy for AP roaming
4419 if(ieee
->state
== IEEE80211_LINKED
&& ieee
->iw_mode
== IW_MODE_INFRA
)
4421 u32 TotalRxBcnNum
= 0;
4422 u32 TotalRxDataNum
= 0;
4424 rtl819x_update_rxcounts(priv
, &TotalRxBcnNum
, &TotalRxDataNum
);
4425 if((TotalRxBcnNum
+TotalRxDataNum
) == 0)
4427 if( ieee
->eRFPowerState
== eRfOff
)
4428 RT_TRACE(COMP_ERR
,"========>%s()\n",__FUNCTION__
);
4429 printk("===>%s(): AP is power off,connect another one\n",__FUNCTION__
);
4430 // Dot11d_Reset(dev);
4431 ieee
->state
= IEEE80211_ASSOCIATING
;
4432 notify_wx_assoc_event(priv
->ieee80211
);
4433 RemovePeerTS(priv
->ieee80211
,priv
->ieee80211
->current_network
.bssid
);
4434 ieee
->is_roaming
= true;
4435 ieee
->is_set_key
= false;
4436 ieee
->link_change(dev
);
4437 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
4438 queue_work(ieee
->wq
, &ieee
->associate_procedure_wq
);
4440 schedule_task(&ieee
->associate_procedure_wq
);
4444 ieee
->LinkDetectInfo
.NumRecvBcnInPeriod
=0;
4445 ieee
->LinkDetectInfo
.NumRecvDataInPeriod
=0;
4448 //check if reset the driver
4449 spin_lock_irqsave(&priv
->tx_lock
,flags
);
4450 if(check_reset_cnt
++ >= 3 && !ieee
->is_roaming
&& (last_time
!= 1))
4452 ResetType
= rtl819x_ifcheck_resetornot(dev
);
4453 check_reset_cnt
= 3;
4454 //DbgPrint("Start to check silent reset\n");
4456 spin_unlock_irqrestore(&priv
->tx_lock
,flags
);
4457 if(!priv
->bDisableNormalResetCheck
&& ResetType
== RESET_TYPE_NORMAL
)
4459 priv
->ResetProgress
= RESET_TYPE_NORMAL
;
4460 RT_TRACE(COMP_RESET
,"%s(): NOMAL RESET\n",__FUNCTION__
);
4463 /* disable silent reset temply 2008.9.11*/
4465 if( ((priv
->force_reset
) || (!priv
->bDisableNormalResetCheck
&& ResetType
==RESET_TYPE_SILENT
))) // This is control by OID set in Pomelo
4468 rtl819x_ifsilentreset(dev
);
4473 priv
->force_reset
= false;
4474 priv
->bForcedSilentReset
= false;
4475 priv
->bResetInProgress
= false;
4476 RT_TRACE(COMP_TRACE
, " <==RtUsbCheckForHangWorkItemCallback()\n");
4480 void watch_dog_timer_callback(unsigned long data
)
4482 struct r8192_priv
*priv
= ieee80211_priv((struct net_device
*) data
);
4483 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
4484 queue_delayed_work(priv
->priv_wq
,&priv
->watch_dog_wq
,0);
4486 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
4487 schedule_task(&priv
->watch_dog_wq
);
4489 queue_work(priv
->priv_wq
,&priv
->watch_dog_wq
);
4492 mod_timer(&priv
->watch_dog_timer
, jiffies
+ MSECS(IEEE80211_WATCH_DOG_TIME
));
4495 int _rtl8192_up(struct net_device
*dev
)
4497 struct r8192_priv
*priv
= ieee80211_priv(dev
);
4499 RT_STATUS init_status
= RT_STATUS_SUCCESS
;
4501 priv
->ieee80211
->ieee_up
=1;
4502 RT_TRACE(COMP_INIT
, "Bringing up iface");
4504 init_status
= rtl8192_adapter_start(dev
);
4505 if(init_status
!= RT_STATUS_SUCCESS
)
4507 RT_TRACE(COMP_ERR
,"ERR!!! %s(): initialization is failed!\n",__FUNCTION__
);
4510 RT_TRACE(COMP_INIT
, "start adapter finished\n");
4512 if(priv
->ieee80211
->eRFPowerState
!=eRfOn
)
4513 MgntActSet_RF_State(dev
, eRfOn
, priv
->ieee80211
->RfOffReason
);
4515 if(priv
->ieee80211
->state
!= IEEE80211_LINKED
)
4516 ieee80211_softmac_start_protocol(priv
->ieee80211
);
4517 ieee80211_reset_queue(priv
->ieee80211
);
4518 watch_dog_timer_callback((unsigned long) dev
);
4519 if(!netif_queue_stopped(dev
))
4520 netif_start_queue(dev
);
4522 netif_wake_queue(dev
);
4528 static int rtl8192_open(struct net_device
*dev
)
4530 struct r8192_priv
*priv
= ieee80211_priv(dev
);
4533 down(&priv
->wx_sem
);
4534 ret
= rtl8192_up(dev
);
4541 int rtl8192_up(struct net_device
*dev
)
4543 struct r8192_priv
*priv
= ieee80211_priv(dev
);
4545 if (priv
->up
== 1) return -1;
4547 return _rtl8192_up(dev
);
4551 static int rtl8192_close(struct net_device
*dev
)
4553 struct r8192_priv
*priv
= ieee80211_priv(dev
);
4556 down(&priv
->wx_sem
);
4558 ret
= rtl8192_down(dev
);
4566 int rtl8192_down(struct net_device
*dev
)
4568 struct r8192_priv
*priv
= ieee80211_priv(dev
);
4574 if (priv
->up
== 0) return -1;
4577 priv
->ieee80211
->ieee_up
= 0;
4578 RT_TRACE(COMP_DOWN
, "==========>%s()\n", __FUNCTION__
);
4580 if (!netif_queue_stopped(dev
))
4581 netif_stop_queue(dev
);
4583 rtl8192_irq_disable(dev
);
4585 if(!priv
->ieee80211
->bSupportRemoteWakeUp
) {
4586 MgntActSet_RF_State(dev
, eRfOff
, RF_CHANGE_BY_INIT
);
4587 // 2006.11.30. System reset bit
4588 ulRegRead
= read_nic_dword(dev
, CPU_GEN
);
4589 ulRegRead
|=CPU_GEN_SYSTEM_RESET
;
4590 write_nic_dword(dev
, CPU_GEN
, ulRegRead
);
4592 //2008.06.03 for WOL
4593 write_nic_dword(dev
, WFCRC0
, 0xffffffff);
4594 write_nic_dword(dev
, WFCRC1
, 0xffffffff);
4595 write_nic_dword(dev
, WFCRC2
, 0xffffffff);
4598 ucRegRead
= read_nic_byte(dev
, GPO
);
4600 write_nic_byte(dev
, GPO
, ucRegRead
);
4602 //Write PMR register
4603 write_nic_byte(dev
, PMR
, 0x5);
4604 //Disable tx, enanble rx
4605 write_nic_byte(dev
, MacBlkCtrl
, 0xa);
4608 // flush_scheduled_work();
4609 rtl8192_cancel_deferred_work(priv
);
4611 del_timer_sync(&priv
->watch_dog_timer
);
4613 ieee80211_softmac_stop_protocol(priv
->ieee80211
);
4615 MgntActSet_RF_State(dev
, eRfOff
, RF_CHANGE_BY_INIT
);
4617 rtl8192_rtx_disable(dev
);
4618 memset(&priv
->ieee80211
->current_network
, 0 , offsetof(struct ieee80211_network
, list
));
4620 RT_TRACE(COMP_DOWN
, "<==========%s()\n", __FUNCTION__
);
4626 void rtl8192_commit(struct net_device
*dev
)
4628 struct r8192_priv
*priv
= ieee80211_priv(dev
);
4630 if (priv
->up
== 0) return ;
4633 ieee80211_softmac_stop_protocol(priv
->ieee80211
);
4635 rtl8192_irq_disable(dev
);
4636 rtl8192_rtx_disable(dev
);
4640 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
4641 void rtl8192_restart(struct work_struct
*work
)
4643 struct r8192_priv
*priv
= container_of(work
, struct r8192_priv
, reset_wq
);
4644 struct net_device
*dev
= priv
->ieee80211
->dev
;
4646 void rtl8192_restart(struct net_device
*dev
)
4649 struct r8192_priv
*priv
= ieee80211_priv(dev
);
4652 down(&priv
->wx_sem
);
4654 rtl8192_commit(dev
);
4659 static void r8192_set_multicast(struct net_device
*dev
)
4661 struct r8192_priv
*priv
= ieee80211_priv(dev
);
4664 //down(&priv->wx_sem);
4668 promisc
= (dev
->flags
& IFF_PROMISC
) ? 1:0;
4670 if (promisc
!= priv
->promisc
) {
4672 // rtl8192_commit(dev);
4675 priv
->promisc
= promisc
;
4677 //schedule_work(&priv->reset_wq);
4678 //up(&priv->wx_sem);
4682 static int r8192_set_mac_adr(struct net_device
*dev
, void *mac
)
4684 struct r8192_priv
*priv
= ieee80211_priv(dev
);
4685 struct sockaddr
*addr
= mac
;
4687 down(&priv
->wx_sem
);
4689 memcpy(dev
->dev_addr
, addr
->sa_data
, ETH_ALEN
);
4691 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
4692 schedule_work(&priv
->reset_wq
);
4694 schedule_task(&priv
->reset_wq
);
4701 /* based on ipw2200 driver */
4702 static int rtl8192_ioctl(struct net_device
*dev
, struct ifreq
*rq
, int cmd
)
4704 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
4705 struct iwreq
*wrq
= (struct iwreq
*)rq
;
4707 struct ieee80211_device
*ieee
= priv
->ieee80211
;
4709 u8 broadcast_addr
[6] = {0xff,0xff,0xff,0xff,0xff,0xff};
4710 struct iw_point
*p
= &wrq
->u
.data
;
4711 struct ieee_param
*ipw
= NULL
;//(struct ieee_param *)wrq->u.data.pointer;
4713 down(&priv
->wx_sem
);
4716 if (p
->length
< sizeof(struct ieee_param
) || !p
->pointer
){
4721 ipw
= (struct ieee_param
*)kmalloc(p
->length
, GFP_KERNEL
);
4726 if (copy_from_user(ipw
, p
->pointer
, p
->length
)) {
4733 case RTL_IOCTL_WPA_SUPPLICANT
:
4734 //parse here for HW security
4735 if (ipw
->cmd
== IEEE_CMD_SET_ENCRYPTION
)
4737 if (ipw
->u
.crypt
.set_tx
)
4739 if (strcmp(ipw
->u
.crypt
.alg
, "CCMP") == 0)
4740 ieee
->pairwise_key_type
= KEY_TYPE_CCMP
;
4741 else if (strcmp(ipw
->u
.crypt
.alg
, "TKIP") == 0)
4742 ieee
->pairwise_key_type
= KEY_TYPE_TKIP
;
4743 else if (strcmp(ipw
->u
.crypt
.alg
, "WEP") == 0)
4745 if (ipw
->u
.crypt
.key_len
== 13)
4746 ieee
->pairwise_key_type
= KEY_TYPE_WEP104
;
4747 else if (ipw
->u
.crypt
.key_len
== 5)
4748 ieee
->pairwise_key_type
= KEY_TYPE_WEP40
;
4751 ieee
->pairwise_key_type
= KEY_TYPE_NA
;
4753 if (ieee
->pairwise_key_type
)
4755 memcpy((u8
*)key
, ipw
->u
.crypt
.key
, 16);
4756 EnableHWSecurityConfig8192(dev
);
4757 //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!
4759 setKey(dev
, 4, ipw
->u
.crypt
.idx
, ieee
->pairwise_key_type
, (u8
*)ieee
->ap_mac_addr
, 0, key
);
4760 if (ieee
->auth_mode
!= 2) //LEAP WEP will never set this.
4761 setKey(dev
, ipw
->u
.crypt
.idx
, ipw
->u
.crypt
.idx
, ieee
->pairwise_key_type
, (u8
*)ieee
->ap_mac_addr
, 0, key
);
4763 if ((ieee
->pairwise_key_type
== KEY_TYPE_CCMP
) && ieee
->pHTInfo
->bCurrentHTSupport
){
4764 write_nic_byte(dev
, 0x173, 1); //fix aes bug
4768 else //if (ipw->u.crypt.idx) //group key use idx > 0
4770 memcpy((u8
*)key
, ipw
->u
.crypt
.key
, 16);
4771 if (strcmp(ipw
->u
.crypt
.alg
, "CCMP") == 0)
4772 ieee
->group_key_type
= KEY_TYPE_CCMP
;
4773 else if (strcmp(ipw
->u
.crypt
.alg
, "TKIP") == 0)
4774 ieee
->group_key_type
= KEY_TYPE_TKIP
;
4775 else if (strcmp(ipw
->u
.crypt
.alg
, "WEP") == 0)
4777 if (ipw
->u
.crypt
.key_len
== 13)
4778 ieee
->group_key_type
= KEY_TYPE_WEP104
;
4779 else if (ipw
->u
.crypt
.key_len
== 5)
4780 ieee
->group_key_type
= KEY_TYPE_WEP40
;
4783 ieee
->group_key_type
= KEY_TYPE_NA
;
4785 if (ieee
->group_key_type
)
4789 ipw
->u
.crypt
.idx
, //KeyIndex
4790 ieee
->group_key_type
, //KeyType
4791 broadcast_addr
, //MacAddr
4801 printk("@@ wrq->u pointer = ");
4802 for(i
=0;i
<wrq
->u
.data
.length
;i
++){
4803 if(i
%10==0) printk("\n");
4804 printk( "%8x|", ((u32
*)wrq
->u
.data
.pointer
)[i
] );
4808 #endif /*JOHN_DEBUG*/
4809 ret
= ieee80211_wpa_supplicant_ioctl(priv
->ieee80211
, &wrq
->u
.data
);
4824 static u8
HwRateToMRate90(bool bIsHT
, u8 rate
)
4830 case DESC90_RATE1M
: ret_rate
= MGN_1M
; break;
4831 case DESC90_RATE2M
: ret_rate
= MGN_2M
; break;
4832 case DESC90_RATE5_5M
: ret_rate
= MGN_5_5M
; break;
4833 case DESC90_RATE11M
: ret_rate
= MGN_11M
; break;
4834 case DESC90_RATE6M
: ret_rate
= MGN_6M
; break;
4835 case DESC90_RATE9M
: ret_rate
= MGN_9M
; break;
4836 case DESC90_RATE12M
: ret_rate
= MGN_12M
; break;
4837 case DESC90_RATE18M
: ret_rate
= MGN_18M
; break;
4838 case DESC90_RATE24M
: ret_rate
= MGN_24M
; break;
4839 case DESC90_RATE36M
: ret_rate
= MGN_36M
; break;
4840 case DESC90_RATE48M
: ret_rate
= MGN_48M
; break;
4841 case DESC90_RATE54M
: ret_rate
= MGN_54M
; break;
4844 RT_TRACE(COMP_RECV
, "HwRateToMRate90(): Non supported Rate [%x], bIsHT = %d!!!\n", rate
, bIsHT
);
4850 case DESC90_RATEMCS0
: ret_rate
= MGN_MCS0
; break;
4851 case DESC90_RATEMCS1
: ret_rate
= MGN_MCS1
; break;
4852 case DESC90_RATEMCS2
: ret_rate
= MGN_MCS2
; break;
4853 case DESC90_RATEMCS3
: ret_rate
= MGN_MCS3
; break;
4854 case DESC90_RATEMCS4
: ret_rate
= MGN_MCS4
; break;
4855 case DESC90_RATEMCS5
: ret_rate
= MGN_MCS5
; break;
4856 case DESC90_RATEMCS6
: ret_rate
= MGN_MCS6
; break;
4857 case DESC90_RATEMCS7
: ret_rate
= MGN_MCS7
; break;
4858 case DESC90_RATEMCS8
: ret_rate
= MGN_MCS8
; break;
4859 case DESC90_RATEMCS9
: ret_rate
= MGN_MCS9
; break;
4860 case DESC90_RATEMCS10
: ret_rate
= MGN_MCS10
; break;
4861 case DESC90_RATEMCS11
: ret_rate
= MGN_MCS11
; break;
4862 case DESC90_RATEMCS12
: ret_rate
= MGN_MCS12
; break;
4863 case DESC90_RATEMCS13
: ret_rate
= MGN_MCS13
; break;
4864 case DESC90_RATEMCS14
: ret_rate
= MGN_MCS14
; break;
4865 case DESC90_RATEMCS15
: ret_rate
= MGN_MCS15
; break;
4866 case DESC90_RATEMCS32
: ret_rate
= (0x80|0x20); break;
4869 RT_TRACE(COMP_RECV
, "HwRateToMRate90(): Non supported Rate [%x], bIsHT = %d!!!\n",rate
, bIsHT
);
4878 * Function: UpdateRxPktTimeStamp
4879 * Overview: Recored down the TSF time stamp when receiving a packet
4887 * (pRfd->Status.TimeStampHigh is updated)
4888 * (pRfd->Status.TimeStampLow is updated)
4892 static void UpdateRxPktTimeStamp8190 (struct net_device
*dev
, struct ieee80211_rx_stats
*stats
)
4894 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
4896 if(stats
->bIsAMPDU
&& !stats
->bFirstMPDU
) {
4897 stats
->mac_time
[0] = priv
->LastRxDescTSFLow
;
4898 stats
->mac_time
[1] = priv
->LastRxDescTSFHigh
;
4900 priv
->LastRxDescTSFLow
= stats
->mac_time
[0];
4901 priv
->LastRxDescTSFHigh
= stats
->mac_time
[1];
4905 static long rtl819x_translate_todbm(u8 signal_strength_index
)// 0-100 index.
4907 long signal_power
; // in dBm.
4909 // Translate to dBm (x=0.5y-95).
4910 signal_power
= (long)((signal_strength_index
+ 1) >> 1);
4913 return signal_power
;
4918 // Update Rx signal related information in the packet reeived
4919 // to RxStats. User application can query RxStats to realize
4920 // current Rx signal status.
4923 // In normal operation, user only care about the information of the BSS
4924 // and we shall invoke this function if the packet received is from the BSS.
4927 rtl819x_update_rxsignalstatistics8190pci(
4928 struct r8192_priv
* priv
,
4929 struct ieee80211_rx_stats
* pprevious_stats
4934 //2 <ToDo> Update Rx Statistics (such as signal strength and signal quality).
4937 if(priv
->stats
.recv_signal_power
== 0)
4938 priv
->stats
.recv_signal_power
= pprevious_stats
->RecvSignalPower
;
4940 // To avoid the past result restricting the statistics sensitivity, weight the current power (5/6) to speed up the
4941 // reaction of smoothed Signal Power.
4942 if(pprevious_stats
->RecvSignalPower
> priv
->stats
.recv_signal_power
)
4944 else if(pprevious_stats
->RecvSignalPower
< priv
->stats
.recv_signal_power
)
4947 // We need more correct power of received packets and the "SignalStrength" of RxStats have been beautified or translated,
4948 // so we record the correct power in Dbm here. By Bruce, 2008-03-07.
4950 priv
->stats
.recv_signal_power
= (priv
->stats
.recv_signal_power
* 5 + pprevious_stats
->RecvSignalPower
+ weighting
) / 6;
4954 rtl8190_process_cck_rxpathsel(
4955 struct r8192_priv
* priv
,
4956 struct ieee80211_rx_stats
* pprevious_stats
4959 #ifdef RTL8190P //Only 90P 2T4R need to check
4960 char last_cck_adc_pwdb
[4]={0,0,0,0};
4962 //cosa add for Rx path selection
4963 if(priv
->rf_type
== RF_2T4R
&& DM_RxPathSelTable
.Enable
)
4965 if(pprevious_stats
->bIsCCK
&&
4966 (pprevious_stats
->bPacketToSelf
||pprevious_stats
->bPacketBeacon
))
4968 /* record the cck adc_pwdb to the sliding window. */
4969 if(priv
->stats
.cck_adc_pwdb
.TotalNum
++ >= PHY_RSSI_SLID_WIN_MAX
)
4971 priv
->stats
.cck_adc_pwdb
.TotalNum
= PHY_RSSI_SLID_WIN_MAX
;
4972 for(i
=RF90_PATH_A
; i
<RF90_PATH_MAX
; i
++)
4974 last_cck_adc_pwdb
[i
] = priv
->stats
.cck_adc_pwdb
.elements
[i
][priv
->stats
.cck_adc_pwdb
.index
];
4975 priv
->stats
.cck_adc_pwdb
.TotalVal
[i
] -= last_cck_adc_pwdb
[i
];
4978 for(i
=RF90_PATH_A
; i
<RF90_PATH_MAX
; i
++)
4980 priv
->stats
.cck_adc_pwdb
.TotalVal
[i
] += pprevious_stats
->cck_adc_pwdb
[i
];
4981 priv
->stats
.cck_adc_pwdb
.elements
[i
][priv
->stats
.cck_adc_pwdb
.index
] = pprevious_stats
->cck_adc_pwdb
[i
];
4983 priv
->stats
.cck_adc_pwdb
.index
++;
4984 if(priv
->stats
.cck_adc_pwdb
.index
>= PHY_RSSI_SLID_WIN_MAX
)
4985 priv
->stats
.cck_adc_pwdb
.index
= 0;
4987 for(i
=RF90_PATH_A
; i
<RF90_PATH_MAX
; i
++)
4989 DM_RxPathSelTable
.cck_pwdb_sta
[i
] = priv
->stats
.cck_adc_pwdb
.TotalVal
[i
]/priv
->stats
.cck_adc_pwdb
.TotalNum
;
4992 for(i
=RF90_PATH_A
; i
<RF90_PATH_MAX
; i
++)
4994 if(pprevious_stats
->cck_adc_pwdb
[i
] > (char)priv
->undecorated_smoothed_cck_adc_pwdb
[i
])
4996 priv
->undecorated_smoothed_cck_adc_pwdb
[i
] =
4997 ( (priv
->undecorated_smoothed_cck_adc_pwdb
[i
]*(Rx_Smooth_Factor
-1)) +
4998 (pprevious_stats
->cck_adc_pwdb
[i
])) /(Rx_Smooth_Factor
);
4999 priv
->undecorated_smoothed_cck_adc_pwdb
[i
] = priv
->undecorated_smoothed_cck_adc_pwdb
[i
] + 1;
5003 priv
->undecorated_smoothed_cck_adc_pwdb
[i
] =
5004 ( (priv
->undecorated_smoothed_cck_adc_pwdb
[i
]*(Rx_Smooth_Factor
-1)) +
5005 (pprevious_stats
->cck_adc_pwdb
[i
])) /(Rx_Smooth_Factor
);
5014 /* 2008/01/22 MH We can not delcare RSSI/EVM total value of sliding window to
5015 be a local static. Otherwise, it may increase when we return from S3/S4. The
5016 value will be kept in memory or disk. We must delcare the value in adapter
5017 and it will be reinitialized when return from S3/S4. */
5018 static void rtl8192_process_phyinfo(struct r8192_priv
* priv
, u8
* buffer
,struct ieee80211_rx_stats
* pprevious_stats
, struct ieee80211_rx_stats
* pcurrent_stats
)
5020 bool bcheck
= false;
5022 u32 nspatial_stream
, tmp_val
;
5024 static u32 slide_rssi_index
=0, slide_rssi_statistics
=0;
5025 static u32 slide_evm_index
=0, slide_evm_statistics
=0;
5026 static u32 last_rssi
=0, last_evm
=0;
5027 //cosa add for rx path selection
5028 // static long slide_cck_adc_pwdb_index=0, slide_cck_adc_pwdb_statistics=0;
5029 // static char last_cck_adc_pwdb[4]={0,0,0,0};
5030 //cosa add for beacon rssi smoothing
5031 static u32 slide_beacon_adc_pwdb_index
=0, slide_beacon_adc_pwdb_statistics
=0;
5032 static u32 last_beacon_adc_pwdb
=0;
5034 struct ieee80211_hdr_3addr
*hdr
;
5036 unsigned int frag
,seq
;
5037 hdr
= (struct ieee80211_hdr_3addr
*)buffer
;
5038 sc
= le16_to_cpu(hdr
->seq_ctl
);
5039 frag
= WLAN_GET_SEQ_FRAG(sc
);
5040 seq
= WLAN_GET_SEQ_SEQ(sc
);
5041 //cosa add 04292008 to record the sequence number
5042 pcurrent_stats
->Seq_Num
= seq
;
5044 // Check whether we should take the previous packet into accounting
5046 if(!pprevious_stats
->bIsAMPDU
)
5048 // if previous packet is not aggregated packet
5052 //remve for that we don't use AMPDU to calculate PWDB,because the reported PWDB of some AP is fault.
5054 // if previous packet is aggregated packet, and current packet
5056 // (2) is the first packet of one AMPDU
5057 // that means the previous packet is the last one aggregated packet
5058 if( !pcurrent_stats
->bIsAMPDU
|| pcurrent_stats
->bFirstMPDU
)
5063 if(slide_rssi_statistics
++ >= PHY_RSSI_SLID_WIN_MAX
)
5065 slide_rssi_statistics
= PHY_RSSI_SLID_WIN_MAX
;
5066 last_rssi
= priv
->stats
.slide_signal_strength
[slide_rssi_index
];
5067 priv
->stats
.slide_rssi_total
-= last_rssi
;
5069 priv
->stats
.slide_rssi_total
+= pprevious_stats
->SignalStrength
;
5071 priv
->stats
.slide_signal_strength
[slide_rssi_index
++] = pprevious_stats
->SignalStrength
;
5072 if(slide_rssi_index
>= PHY_RSSI_SLID_WIN_MAX
)
5073 slide_rssi_index
= 0;
5075 // <1> Showed on UI for user, in dbm
5076 tmp_val
= priv
->stats
.slide_rssi_total
/slide_rssi_statistics
;
5077 priv
->stats
.signal_strength
= rtl819x_translate_todbm((u8
)tmp_val
);
5078 pcurrent_stats
->rssi
= priv
->stats
.signal_strength
;
5080 // If the previous packet does not match the criteria, neglect it
5082 if(!pprevious_stats
->bPacketMatchBSSID
)
5084 if(!pprevious_stats
->bToSelfBA
)
5091 rtl8190_process_cck_rxpathsel(priv
,pprevious_stats
);
5096 priv
->stats
.num_process_phyinfo
++;
5098 /* record the general signal strength to the sliding window. */
5099 if(slide_rssi_statistics
++ >= PHY_RSSI_SLID_WIN_MAX
)
5101 slide_rssi_statistics
= PHY_RSSI_SLID_WIN_MAX
;
5102 last_rssi
= priv
->stats
.slide_signal_strength
[slide_rssi_index
];
5103 priv
->stats
.slide_rssi_total
-= last_rssi
;
5105 priv
->stats
.slide_rssi_total
+= pprevious_stats
->SignalStrength
;
5107 priv
->stats
.slide_signal_strength
[slide_rssi_index
++] = pprevious_stats
->SignalStrength
;
5108 if(slide_rssi_index
>= PHY_RSSI_SLID_WIN_MAX
)
5109 slide_rssi_index
= 0;
5111 // <1> Showed on UI for user, in dbm
5112 tmp_val
= priv
->stats
.slide_rssi_total
/slide_rssi_statistics
;
5113 priv
->stats
.signal_strength
= rtl819x_translate_todbm((u8
)tmp_val
);
5116 // <2> Showed on UI for engineering
5117 // hardware does not provide rssi information for each rf path in CCK
5118 if(!pprevious_stats
->bIsCCK
&& pprevious_stats
->bPacketToSelf
)
5120 for (rfpath
= RF90_PATH_A
; rfpath
< RF90_PATH_C
; rfpath
++)
5122 if (!rtl8192_phy_CheckIsLegalRFPath(priv
->ieee80211
->dev
, rfpath
))
5124 RT_TRACE(COMP_DBG
,"Jacken -> pPreviousstats->RxMIMOSignalStrength[rfpath] = %d \n" ,pprevious_stats
->RxMIMOSignalStrength
[rfpath
] );
5125 //Fixed by Jacken 2008-03-20
5126 if(priv
->stats
.rx_rssi_percentage
[rfpath
] == 0)
5128 priv
->stats
.rx_rssi_percentage
[rfpath
] = pprevious_stats
->RxMIMOSignalStrength
[rfpath
];
5129 //DbgPrint("MIMO RSSI initialize \n");
5131 if(pprevious_stats
->RxMIMOSignalStrength
[rfpath
] > priv
->stats
.rx_rssi_percentage
[rfpath
])
5133 priv
->stats
.rx_rssi_percentage
[rfpath
] =
5134 ( (priv
->stats
.rx_rssi_percentage
[rfpath
]*(Rx_Smooth_Factor
-1)) +
5135 (pprevious_stats
->RxMIMOSignalStrength
[rfpath
])) /(Rx_Smooth_Factor
);
5136 priv
->stats
.rx_rssi_percentage
[rfpath
] = priv
->stats
.rx_rssi_percentage
[rfpath
] + 1;
5140 priv
->stats
.rx_rssi_percentage
[rfpath
] =
5141 ( (priv
->stats
.rx_rssi_percentage
[rfpath
]*(Rx_Smooth_Factor
-1)) +
5142 (pprevious_stats
->RxMIMOSignalStrength
[rfpath
])) /(Rx_Smooth_Factor
);
5144 RT_TRACE(COMP_DBG
,"Jacken -> priv->RxStats.RxRSSIPercentage[rfPath] = %d \n" ,priv
->stats
.rx_rssi_percentage
[rfpath
] );
5152 //cosa add for beacon rssi smoothing by average.
5153 if(pprevious_stats
->bPacketBeacon
)
5155 /* record the beacon pwdb to the sliding window. */
5156 if(slide_beacon_adc_pwdb_statistics
++ >= PHY_Beacon_RSSI_SLID_WIN_MAX
)
5158 slide_beacon_adc_pwdb_statistics
= PHY_Beacon_RSSI_SLID_WIN_MAX
;
5159 last_beacon_adc_pwdb
= priv
->stats
.Slide_Beacon_pwdb
[slide_beacon_adc_pwdb_index
];
5160 priv
->stats
.Slide_Beacon_Total
-= last_beacon_adc_pwdb
;
5161 //DbgPrint("slide_beacon_adc_pwdb_index = %d, last_beacon_adc_pwdb = %d, Adapter->RxStats.Slide_Beacon_Total = %d\n",
5162 // slide_beacon_adc_pwdb_index, last_beacon_adc_pwdb, Adapter->RxStats.Slide_Beacon_Total);
5164 priv
->stats
.Slide_Beacon_Total
+= pprevious_stats
->RxPWDBAll
;
5165 priv
->stats
.Slide_Beacon_pwdb
[slide_beacon_adc_pwdb_index
] = pprevious_stats
->RxPWDBAll
;
5166 //DbgPrint("slide_beacon_adc_pwdb_index = %d, pPreviousRfd->Status.RxPWDBAll = %d\n", slide_beacon_adc_pwdb_index, pPreviousRfd->Status.RxPWDBAll);
5167 slide_beacon_adc_pwdb_index
++;
5168 if(slide_beacon_adc_pwdb_index
>= PHY_Beacon_RSSI_SLID_WIN_MAX
)
5169 slide_beacon_adc_pwdb_index
= 0;
5170 pprevious_stats
->RxPWDBAll
= priv
->stats
.Slide_Beacon_Total
/slide_beacon_adc_pwdb_statistics
;
5171 if(pprevious_stats
->RxPWDBAll
>= 3)
5172 pprevious_stats
->RxPWDBAll
-= 3;
5175 RT_TRACE(COMP_RXDESC
, "Smooth %s PWDB = %d\n",
5176 pprevious_stats
->bIsCCK
? "CCK": "OFDM",
5177 pprevious_stats
->RxPWDBAll
);
5179 if(pprevious_stats
->bPacketToSelf
|| pprevious_stats
->bPacketBeacon
|| pprevious_stats
->bToSelfBA
)
5181 if(priv
->undecorated_smoothed_pwdb
< 0) // initialize
5183 priv
->undecorated_smoothed_pwdb
= pprevious_stats
->RxPWDBAll
;
5184 //DbgPrint("First pwdb initialize \n");
5187 if(pprevious_stats
->RxPWDBAll
> (u32
)priv
->undecorated_smoothed_pwdb
)
5189 priv
->undecorated_smoothed_pwdb
=
5190 ( ((priv
->undecorated_smoothed_pwdb
)*(Rx_Smooth_Factor
-1)) +
5191 (pprevious_stats
->RxPWDBAll
)) /(Rx_Smooth_Factor
);
5192 priv
->undecorated_smoothed_pwdb
= priv
->undecorated_smoothed_pwdb
+ 1;
5196 priv
->undecorated_smoothed_pwdb
=
5197 ( ((priv
->undecorated_smoothed_pwdb
)*(Rx_Smooth_Factor
-1)) +
5198 (pprevious_stats
->RxPWDBAll
)) /(Rx_Smooth_Factor
);
5201 //Fixed by Jacken 2008-03-20
5202 if(pPreviousRfd
->Status
.RxPWDBAll
> (u32
)pHalData
->UndecoratedSmoothedPWDB
)
5204 pHalData
->UndecoratedSmoothedPWDB
=
5205 ( ((pHalData
->UndecoratedSmoothedPWDB
)* 5) + (pPreviousRfd
->Status
.RxPWDBAll
)) / 6;
5206 pHalData
->UndecoratedSmoothedPWDB
= pHalData
->UndecoratedSmoothedPWDB
+ 1;
5210 pHalData
->UndecoratedSmoothedPWDB
=
5211 ( ((pHalData
->UndecoratedSmoothedPWDB
)* 5) + (pPreviousRfd
->Status
.RxPWDBAll
)) / 6;
5214 rtl819x_update_rxsignalstatistics8190pci(priv
,pprevious_stats
);
5220 /* record the general EVM to the sliding window. */
5221 if(pprevious_stats
->SignalQuality
== 0)
5226 if(pprevious_stats
->bPacketToSelf
|| pprevious_stats
->bPacketBeacon
|| pprevious_stats
->bToSelfBA
){
5227 if(slide_evm_statistics
++ >= PHY_RSSI_SLID_WIN_MAX
){
5228 slide_evm_statistics
= PHY_RSSI_SLID_WIN_MAX
;
5229 last_evm
= priv
->stats
.slide_evm
[slide_evm_index
];
5230 priv
->stats
.slide_evm_total
-= last_evm
;
5233 priv
->stats
.slide_evm_total
+= pprevious_stats
->SignalQuality
;
5235 priv
->stats
.slide_evm
[slide_evm_index
++] = pprevious_stats
->SignalQuality
;
5236 if(slide_evm_index
>= PHY_RSSI_SLID_WIN_MAX
)
5237 slide_evm_index
= 0;
5239 // <1> Showed on UI for user, in percentage.
5240 tmp_val
= priv
->stats
.slide_evm_total
/slide_evm_statistics
;
5241 priv
->stats
.signal_quality
= tmp_val
;
5242 //cosa add 10/11/2007, Showed on UI for user in Windows Vista, for Link quality.
5243 priv
->stats
.last_signal_strength_inpercent
= tmp_val
;
5246 // <2> Showed on UI for engineering
5247 if(pprevious_stats
->bPacketToSelf
|| pprevious_stats
->bPacketBeacon
|| pprevious_stats
->bToSelfBA
)
5249 for(nspatial_stream
= 0; nspatial_stream
<2 ; nspatial_stream
++) // 2 spatial stream
5251 if(pprevious_stats
->RxMIMOSignalQuality
[nspatial_stream
] != -1)
5253 if(priv
->stats
.rx_evm_percentage
[nspatial_stream
] == 0) // initialize
5255 priv
->stats
.rx_evm_percentage
[nspatial_stream
] = pprevious_stats
->RxMIMOSignalQuality
[nspatial_stream
];
5257 priv
->stats
.rx_evm_percentage
[nspatial_stream
] =
5258 ( (priv
->stats
.rx_evm_percentage
[nspatial_stream
]* (Rx_Smooth_Factor
-1)) +
5259 (pprevious_stats
->RxMIMOSignalQuality
[nspatial_stream
]* 1)) / (Rx_Smooth_Factor
);
5267 /*-----------------------------------------------------------------------------
5268 * Function: rtl819x_query_rxpwrpercentage()
5272 * Input: char antpower
5276 * Return: 0-100 percentage
5280 * 05/26/2008 amy Create Version 0 porting from windows code.
5282 *---------------------------------------------------------------------------*/
5283 static u8
rtl819x_query_rxpwrpercentage(
5287 if ((antpower
<= -100) || (antpower
>= 20))
5291 else if (antpower
>= 0)
5297 return (100+antpower
);
5300 } /* QueryRxPwrPercentage */
5303 rtl819x_evm_dbtopercentage(
5315 ret_val
= 0 - ret_val
;
5324 // We want good-looking for signal strength/quality
5325 // 2007/7/19 01:09, by cosa.
5327 static long rtl819x_signal_scale_mapping(long currsig
)
5331 // Step 1. Scale mapping.
5332 if(currsig
>= 61 && currsig
<= 100)
5334 retsig
= 90 + ((currsig
- 60) / 4);
5336 else if(currsig
>= 41 && currsig
<= 60)
5338 retsig
= 78 + ((currsig
- 40) / 2);
5340 else if(currsig
>= 31 && currsig
<= 40)
5342 retsig
= 66 + (currsig
- 30);
5344 else if(currsig
>= 21 && currsig
<= 30)
5346 retsig
= 54 + (currsig
- 20);
5348 else if(currsig
>= 5 && currsig
<= 20)
5350 retsig
= 42 + (((currsig
- 5) * 2) / 3);
5352 else if(currsig
== 4)
5356 else if(currsig
== 3)
5360 else if(currsig
== 2)
5364 else if(currsig
== 1)
5376 static void rtl8192_query_rxphystatus(
5377 struct r8192_priv
* priv
,
5378 struct ieee80211_rx_stats
* pstats
,
5379 prx_desc_819x_pci pdesc
,
5380 prx_fwinfo_819x_pci pdrvinfo
,
5381 struct ieee80211_rx_stats
* precord_stats
,
5382 bool bpacket_match_bssid
,
5383 bool bpacket_toself
,
5388 //PRT_RFD_STATUS pRtRfdStatus = &(pRfd->Status);
5389 phy_sts_ofdm_819xpci_t
* pofdm_buf
;
5390 phy_sts_cck_819xpci_t
* pcck_buf
;
5391 phy_ofdm_rx_status_rxsc_sgien_exintfflag
* prxsc
;
5393 u8 i
,max_spatial_stream
, tmp_rxsnr
, tmp_rxevm
, rxsc_sgien_exflg
;
5394 char rx_pwr
[4], rx_pwr_all
=0;
5395 //long rx_avg_pwr = 0;
5396 char rx_snrX
, rx_evmX
;
5398 u32 RSSI
, total_rssi
=0;//, total_evm=0;
5399 // long signal_strength_index = 0;
5403 /* 2007/07/04 MH For OFDM RSSI. For high power or not. */
5404 static u8 check_reg824
= 0;
5405 static u32 reg824_bit9
= 0;
5407 priv
->stats
.numqry_phystatus
++;
5409 is_cck_rate
= rx_hal_is_cck_rate(pdrvinfo
);
5411 // Record it for next packet processing
5412 memset(precord_stats
, 0, sizeof(struct ieee80211_rx_stats
));
5413 pstats
->bPacketMatchBSSID
= precord_stats
->bPacketMatchBSSID
= bpacket_match_bssid
;
5414 pstats
->bPacketToSelf
= precord_stats
->bPacketToSelf
= bpacket_toself
;
5415 pstats
->bIsCCK
= precord_stats
->bIsCCK
= is_cck_rate
;//RX_HAL_IS_CCK_RATE(pDrvInfo);
5416 pstats
->bPacketBeacon
= precord_stats
->bPacketBeacon
= bPacketBeacon
;
5417 pstats
->bToSelfBA
= precord_stats
->bToSelfBA
= bToSelfBA
;
5418 /*2007.08.30 requested by SD3 Jerry */
5419 if(check_reg824
== 0)
5421 reg824_bit9
= rtl8192_QueryBBReg(priv
->ieee80211
->dev
, rFPGA0_XA_HSSIParameter2
, 0x200);
5426 prxpkt
= (u8
*)pdrvinfo
;
5428 /* Move pointer to the 16th bytes. Phy status start address. */
5429 prxpkt
+= sizeof(rx_fwinfo_819x_pci
);
5431 /* Initial the cck and ofdm buffer pointer */
5432 pcck_buf
= (phy_sts_cck_819xpci_t
*)prxpkt
;
5433 pofdm_buf
= (phy_sts_ofdm_819xpci_t
*)prxpkt
;
5435 pstats
->RxMIMOSignalQuality
[0] = -1;
5436 pstats
->RxMIMOSignalQuality
[1] = -1;
5437 precord_stats
->RxMIMOSignalQuality
[0] = -1;
5438 precord_stats
->RxMIMOSignalQuality
[1] = -1;
5443 // (1)Hardware does not provide RSSI for CCK
5447 // (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive)
5449 u8 report
;//, cck_agc_rpt;
5452 char cck_adc_pwdb
[4];
5454 priv
->stats
.numqry_phystatusCCK
++;
5456 #ifdef RTL8190P //Only 90P 2T4R need to check
5457 if(priv
->rf_type
== RF_2T4R
&& DM_RxPathSelTable
.Enable
&& bpacket_match_bssid
)
5459 for(i
=RF90_PATH_A
; i
<RF90_PATH_MAX
; i
++)
5461 tmp_pwdb
= pcck_buf
->adc_pwdb_X
[i
];
5462 cck_adc_pwdb
[i
] = (char)tmp_pwdb
;
5463 cck_adc_pwdb
[i
] /= 2;
5464 pstats
->cck_adc_pwdb
[i
] = precord_stats
->cck_adc_pwdb
[i
] = cck_adc_pwdb
[i
];
5465 //DbgPrint("RF-%d tmp_pwdb = 0x%x, cck_adc_pwdb = %d", i, tmp_pwdb, cck_adc_pwdb[i]);
5472 report
= pcck_buf
->cck_agc_rpt
& 0xc0;
5476 //Fixed by Jacken from Bryant 2008-03-20
5477 //Original value is -38 , -26 , -14 , -2
5478 //Fixed value is -35 , -23 , -11 , 6
5480 rx_pwr_all
= -35 - (pcck_buf
->cck_agc_rpt
& 0x3e);
5483 rx_pwr_all
= -23 - (pcck_buf
->cck_agc_rpt
& 0x3e);
5486 rx_pwr_all
= -11 - (pcck_buf
->cck_agc_rpt
& 0x3e);
5489 rx_pwr_all
= 8 - (pcck_buf
->cck_agc_rpt
& 0x3e);
5495 report
= pcck_buf
->cck_agc_rpt
& 0x60;
5500 rx_pwr_all
= -35 - ((pcck_buf
->cck_agc_rpt
& 0x1f)<<1) ;
5503 rx_pwr_all
= -23 - ((pcck_buf
->cck_agc_rpt
& 0x1f)<<1);
5506 rx_pwr_all
= -11 - ((pcck_buf
->cck_agc_rpt
& 0x1f)<<1) ;
5509 rx_pwr_all
= -8 - ((pcck_buf
->cck_agc_rpt
& 0x1f)<<1) ;
5514 pwdb_all
= rtl819x_query_rxpwrpercentage(rx_pwr_all
);
5515 pstats
->RxPWDBAll
= precord_stats
->RxPWDBAll
= pwdb_all
;
5516 pstats
->RecvSignalPower
= rx_pwr_all
;
5519 // (3) Get Signal Quality (EVM)
5521 if(bpacket_match_bssid
)
5525 if(pstats
->RxPWDBAll
> 40)
5530 sq
= pcck_buf
->sq_rpt
;
5532 if(pcck_buf
->sq_rpt
> 64)
5534 else if (pcck_buf
->sq_rpt
< 20)
5537 sq
= ((64-sq
) * 100) / 44;
5539 pstats
->SignalQuality
= precord_stats
->SignalQuality
= sq
;
5540 pstats
->RxMIMOSignalQuality
[0] = precord_stats
->RxMIMOSignalQuality
[0] = sq
;
5541 pstats
->RxMIMOSignalQuality
[1] = precord_stats
->RxMIMOSignalQuality
[1] = -1;
5546 priv
->stats
.numqry_phystatusHT
++;
5548 // (1)Get RSSI for HT rate
5550 for(i
=RF90_PATH_A
; i
<RF90_PATH_MAX
; i
++)
5552 // 2008/01/30 MH we will judge RF RX path now.
5553 if (priv
->brfpath_rxenable
[i
])
5558 //Fixed by Jacken from Bryant 2008-03-20
5559 //Original value is 106
5560 #ifdef RTL8190P //Modify by Jacken 2008/03/31
5561 rx_pwr
[i
] = ((pofdm_buf
->trsw_gain_X
[i
]&0x3F)*2) - 106;
5563 rx_pwr
[i
] = ((pofdm_buf
->trsw_gain_X
[i
]&0x3F)*2) - 110;
5566 //Get Rx snr value in DB
5567 tmp_rxsnr
= pofdm_buf
->rxsnr_X
[i
];
5568 rx_snrX
= (char)(tmp_rxsnr
);
5570 priv
->stats
.rxSNRdB
[i
] = (long)rx_snrX
;
5572 /* Translate DBM to percentage. */
5573 RSSI
= rtl819x_query_rxpwrpercentage(rx_pwr
[i
]);
5574 if (priv
->brfpath_rxenable
[i
])
5577 /* Record Signal Strength for next packet */
5578 if(bpacket_match_bssid
)
5580 pstats
->RxMIMOSignalStrength
[i
] =(u8
) RSSI
;
5581 precord_stats
->RxMIMOSignalStrength
[i
] =(u8
) RSSI
;
5587 // (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive)
5589 //Fixed by Jacken from Bryant 2008-03-20
5590 //Original value is 106
5591 rx_pwr_all
= (((pofdm_buf
->pwdb_all
) >> 1 )& 0x7f) -106;
5592 pwdb_all
= rtl819x_query_rxpwrpercentage(rx_pwr_all
);
5594 pstats
->RxPWDBAll
= precord_stats
->RxPWDBAll
= pwdb_all
;
5595 pstats
->RxPower
= precord_stats
->RxPower
= rx_pwr_all
;
5596 pstats
->RecvSignalPower
= rx_pwr_all
;
5598 // (3)EVM of HT rate
5600 if(pdrvinfo
->RxHT
&& pdrvinfo
->RxRate
>=DESC90_RATEMCS8
&&
5601 pdrvinfo
->RxRate
<=DESC90_RATEMCS15
)
5602 max_spatial_stream
= 2; //both spatial stream make sense
5604 max_spatial_stream
= 1; //only spatial stream 1 makes sense
5606 for(i
=0; i
<max_spatial_stream
; i
++)
5608 tmp_rxevm
= pofdm_buf
->rxevm_X
[i
];
5609 rx_evmX
= (char)(tmp_rxevm
);
5611 // Do not use shift operation like "rx_evmX >>= 1" because the compilor of free build environment
5612 // fill most significant bit to "zero" when doing shifting operation which may change a negative
5613 // value to positive one, then the dbm value (which is supposed to be negative) is not correct anymore.
5616 evm
= rtl819x_evm_dbtopercentage(rx_evmX
);
5618 EVM
= SignalScaleMapping(EVM
);//make it good looking, from 0~100
5620 if(bpacket_match_bssid
)
5622 if(i
==0) // Fill value in RFD, Get the first spatial stream only
5623 pstats
->SignalQuality
= precord_stats
->SignalQuality
= (u8
)(evm
& 0xff);
5624 pstats
->RxMIMOSignalQuality
[i
] = precord_stats
->RxMIMOSignalQuality
[i
] = (u8
)(evm
& 0xff);
5629 /* record rx statistics for debug */
5630 rxsc_sgien_exflg
= pofdm_buf
->rxsc_sgien_exflg
;
5631 prxsc
= (phy_ofdm_rx_status_rxsc_sgien_exintfflag
*)&rxsc_sgien_exflg
;
5632 if(pdrvinfo
->BW
) //40M channel
5633 priv
->stats
.received_bwtype
[1+prxsc
->rxsc
]++;
5635 priv
->stats
.received_bwtype
[0]++;
5638 //UI BSS List signal strength(in percentage), make it good looking, from 0~100.
5639 //It is assigned to the BSS List in GetValueFromBeaconOrProbeRsp().
5642 pstats
->SignalStrength
= precord_stats
->SignalStrength
= (u8
)(rtl819x_signal_scale_mapping((long)pwdb_all
));//PWDB_ALL;
5647 //pRfd->Status.SignalStrength = pRecordRfd->Status.SignalStrength = (u1Byte)(SignalScaleMapping(total_rssi/=RF90_PATH_MAX));//(u1Byte)(total_rssi/=RF90_PATH_MAX);
5648 // We can judge RX path number now.
5650 pstats
->SignalStrength
= precord_stats
->SignalStrength
= (u8
)(rtl819x_signal_scale_mapping((long)(total_rssi
/=rf_rx_num
)));
5652 } /* QueryRxPhyStatus8190Pci */
5655 rtl8192_record_rxdesc_forlateruse(
5656 struct ieee80211_rx_stats
* psrc_stats
,
5657 struct ieee80211_rx_stats
* ptarget_stats
5660 ptarget_stats
->bIsAMPDU
= psrc_stats
->bIsAMPDU
;
5661 ptarget_stats
->bFirstMPDU
= psrc_stats
->bFirstMPDU
;
5662 //ptarget_stats->Seq_Num = psrc_stats->Seq_Num;
5667 static void TranslateRxSignalStuff819xpci(struct net_device
*dev
,
5668 struct sk_buff
*skb
,
5669 struct ieee80211_rx_stats
* pstats
,
5670 prx_desc_819x_pci pdesc
,
5671 prx_fwinfo_819x_pci pdrvinfo
)
5673 // TODO: We must only check packet for current MAC address. Not finish
5674 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
5675 bool bpacket_match_bssid
, bpacket_toself
;
5676 bool bPacketBeacon
=false, bToSelfBA
=false;
5677 static struct ieee80211_rx_stats previous_stats
;
5678 struct ieee80211_hdr_3addr
*hdr
;
5681 // Get Signal Quality for only RX data queue (but not command queue)
5686 /* Get MAC frame start address. */
5687 tmp_buf
= skb
->data
;
5689 hdr
= (struct ieee80211_hdr_3addr
*)tmp_buf
;
5690 fc
= le16_to_cpu(hdr
->frame_ctl
);
5691 type
= WLAN_FC_GET_TYPE(fc
);
5692 praddr
= hdr
->addr1
;
5694 /* Check if the received packet is acceptabe. */
5695 bpacket_match_bssid
= ((IEEE80211_FTYPE_CTL
!= type
) &&
5696 (eqMacAddr(priv
->ieee80211
->current_network
.bssid
, (fc
& IEEE80211_FCTL_TODS
)? hdr
->addr1
: (fc
& IEEE80211_FCTL_FROMDS
)? hdr
->addr2
: hdr
->addr3
))
5697 && (!pstats
->bHwError
) && (!pstats
->bCRC
)&& (!pstats
->bICV
));
5698 bpacket_toself
= bpacket_match_bssid
& (eqMacAddr(praddr
, priv
->ieee80211
->dev
->dev_addr
));
5700 if(WLAN_FC_GET_FRAMETYPE(fc
)== IEEE80211_STYPE_BEACON
)
5702 bPacketBeacon
= true;
5703 //DbgPrint("Beacon 2, MatchBSSID = %d, ToSelf = %d \n", bPacketMatchBSSID, bPacketToSelf);
5705 if(WLAN_FC_GET_FRAMETYPE(fc
) == IEEE80211_STYPE_BLOCKACK
)
5707 if((eqMacAddr(praddr
,dev
->dev_addr
)))
5709 //DbgPrint("BlockAck, MatchBSSID = %d, ToSelf = %d \n", bPacketMatchBSSID, bPacketToSelf);
5713 if(bpacket_match_bssid
)
5715 priv
->stats
.numpacket_matchbssid
++;
5718 priv
->stats
.numpacket_toself
++;
5721 // Process PHY information for previous packet (RSSI/PWDB/EVM)
5723 // Because phy information is contained in the last packet of AMPDU only, so driver
5724 // should process phy information of previous packet
5725 rtl8192_process_phyinfo(priv
, tmp_buf
,&previous_stats
, pstats
);
5726 rtl8192_query_rxphystatus(priv
, pstats
, pdesc
, pdrvinfo
, &previous_stats
, bpacket_match_bssid
,
5727 bpacket_toself
,bPacketBeacon
, bToSelfBA
);
5728 rtl8192_record_rxdesc_forlateruse(pstats
, &previous_stats
);
5733 static void rtl8192_tx_resume(struct net_device
*dev
)
5735 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
5736 struct ieee80211_device
*ieee
= priv
->ieee80211
;
5737 struct sk_buff
*skb
;
5740 for(queue_index
= BK_QUEUE
; queue_index
< TXCMD_QUEUE
;queue_index
++) {
5741 while((!skb_queue_empty(&ieee
->skb_waitQ
[queue_index
]))&&
5742 (priv
->ieee80211
->check_nic_enough_desc(dev
,queue_index
) > 0)) {
5743 /* 1. dequeue the packet from the wait queue */
5744 skb
= skb_dequeue(&ieee
->skb_waitQ
[queue_index
]);
5745 /* 2. tx the packet directly */
5746 ieee
->softmac_data_hard_start_xmit(skb
,dev
,0/* rate useless now*/);
5748 if(queue_index
!=MGNT_QUEUE
) {
5749 ieee
->stats
.tx_packets
++;
5750 ieee
->stats
.tx_bytes
+= skb
->len
;
5757 void rtl8192_irq_tx_tasklet(struct r8192_priv
*priv
)
5759 rtl8192_tx_resume(priv
->ieee80211
->dev
);
5763 * Function: UpdateReceivedRateHistogramStatistics
5764 * Overview: Recored down the received data rate
5772 * (Adapter->RxStats.ReceivedRateHistogram[] is updated)
5776 static void UpdateReceivedRateHistogramStatistics8190(
5777 struct net_device
*dev
,
5778 struct ieee80211_rx_stats
* pstats
5781 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
5782 u32 rcvType
=1; //0: Total, 1:OK, 2:CRC, 3:ICV
5784 u32 preamble_guardinterval
; //1: short preamble/GI, 0: long preamble/GI
5786 /* 2007/03/09 MH We will not update rate of packet from rx cmd queue. */
5788 if (pRfd
->queue_id
== CMPK_RX_QUEUE_ID
)
5793 else if(pstats
->bICV
)
5796 if(pstats
->bShortPreamble
)
5797 preamble_guardinterval
= 1;// short
5799 preamble_guardinterval
= 0;// long
5801 switch(pstats
->rate
)
5806 case MGN_1M
: rateIndex
= 0; break;
5807 case MGN_2M
: rateIndex
= 1; break;
5808 case MGN_5_5M
: rateIndex
= 2; break;
5809 case MGN_11M
: rateIndex
= 3; break;
5813 case MGN_6M
: rateIndex
= 4; break;
5814 case MGN_9M
: rateIndex
= 5; break;
5815 case MGN_12M
: rateIndex
= 6; break;
5816 case MGN_18M
: rateIndex
= 7; break;
5817 case MGN_24M
: rateIndex
= 8; break;
5818 case MGN_36M
: rateIndex
= 9; break;
5819 case MGN_48M
: rateIndex
= 10; break;
5820 case MGN_54M
: rateIndex
= 11; break;
5822 // 11n High throughput rate
5824 case MGN_MCS0
: rateIndex
= 12; break;
5825 case MGN_MCS1
: rateIndex
= 13; break;
5826 case MGN_MCS2
: rateIndex
= 14; break;
5827 case MGN_MCS3
: rateIndex
= 15; break;
5828 case MGN_MCS4
: rateIndex
= 16; break;
5829 case MGN_MCS5
: rateIndex
= 17; break;
5830 case MGN_MCS6
: rateIndex
= 18; break;
5831 case MGN_MCS7
: rateIndex
= 19; break;
5832 case MGN_MCS8
: rateIndex
= 20; break;
5833 case MGN_MCS9
: rateIndex
= 21; break;
5834 case MGN_MCS10
: rateIndex
= 22; break;
5835 case MGN_MCS11
: rateIndex
= 23; break;
5836 case MGN_MCS12
: rateIndex
= 24; break;
5837 case MGN_MCS13
: rateIndex
= 25; break;
5838 case MGN_MCS14
: rateIndex
= 26; break;
5839 case MGN_MCS15
: rateIndex
= 27; break;
5840 default: rateIndex
= 28; break;
5842 priv
->stats
.received_preamble_GI
[preamble_guardinterval
][rateIndex
]++;
5843 priv
->stats
.received_rate_histogram
[0][rateIndex
]++; //total
5844 priv
->stats
.received_rate_histogram
[rcvType
][rateIndex
]++;
5847 static void rtl8192_rx(struct net_device
*dev
)
5849 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
5850 struct ieee80211_hdr_1addr
*ieee80211_hdr
= NULL
;
5851 bool unicast_packet
= false;
5852 struct ieee80211_rx_stats stats
= {
5856 .freq
= IEEE80211_24GHZ_BAND
,
5858 unsigned int count
= priv
->rxringcount
;
5860 stats
.nic_type
= NIC_8192E
;
5863 rx_desc_819x_pci
*pdesc
= &priv
->rx_ring
[priv
->rx_idx
];//rx descriptor
5864 struct sk_buff
*skb
= priv
->rx_buf
[priv
->rx_idx
];//rx pkt
5867 /* wait data to be filled by hardware */
5870 stats
.bICV
= pdesc
->ICV
;
5871 stats
.bCRC
= pdesc
->CRC32
;
5872 stats
.bHwError
= pdesc
->CRC32
| pdesc
->ICV
;
5874 stats
.Length
= pdesc
->Length
;
5875 if(stats
.Length
< 24)
5876 stats
.bHwError
|= 1;
5878 if(stats
.bHwError
) {
5879 stats
.bShift
= false;
5882 if (pdesc
->Length
<500)
5883 priv
->stats
.rxcrcerrmin
++;
5884 else if (pdesc
->Length
>1000)
5885 priv
->stats
.rxcrcerrmax
++;
5887 priv
->stats
.rxcrcerrmid
++;
5891 prx_fwinfo_819x_pci pDrvInfo
= NULL
;
5892 struct sk_buff
*new_skb
= dev_alloc_skb(priv
->rxbuffersize
);
5894 if (unlikely(!new_skb
)) {
5898 stats
.RxDrvInfoSize
= pdesc
->RxDrvInfoSize
;
5899 stats
.RxBufShift
= ((pdesc
->Shift
)&0x03);
5900 stats
.Decrypted
= !pdesc
->SWDec
;
5902 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
5903 pci_dma_sync_single_for_cpu(priv
->pdev
,
5905 pci_unmap_single(priv
->pdev
,
5907 *((dma_addr_t
*)skb
->cb
),
5909 PCI_DMA_FROMDEVICE
);
5910 skb_put(skb
, pdesc
->Length
);
5911 pDrvInfo
= (rx_fwinfo_819x_pci
*)(skb
->data
+ stats
.RxBufShift
);
5912 skb_reserve(skb
, stats
.RxDrvInfoSize
+ stats
.RxBufShift
);
5914 stats
.rate
= HwRateToMRate90((bool)pDrvInfo
->RxHT
, (u8
)pDrvInfo
->RxRate
);
5915 stats
.bShortPreamble
= pDrvInfo
->SPLCP
;
5917 /* it is debug only. It should be disabled in released driver.
5918 * 2007.1.11 by Emily
5920 UpdateReceivedRateHistogramStatistics8190(dev
, &stats
);
5922 stats
.bIsAMPDU
= (pDrvInfo
->PartAggr
==1);
5923 stats
.bFirstMPDU
= (pDrvInfo
->PartAggr
==1) && (pDrvInfo
->FirstAGGR
==1);
5925 stats
.TimeStampLow
= pDrvInfo
->TSFL
;
5926 stats
.TimeStampHigh
= read_nic_dword(dev
, TSFR
+4);
5928 UpdateRxPktTimeStamp8190(dev
, &stats
);
5931 // Get Total offset of MPDU Frame Body
5933 if((stats
.RxBufShift
+ stats
.RxDrvInfoSize
) > 0)
5936 stats
.RxIs40MHzPacket
= pDrvInfo
->BW
;
5939 TranslateRxSignalStuff819xpci(dev
,skb
, &stats
, pdesc
, pDrvInfo
);
5942 if(pDrvInfo
->FirstAGGR
==1 || pDrvInfo
->PartAggr
== 1)
5943 RT_TRACE(COMP_RXDESC
, "pDrvInfo->FirstAGGR = %d, pDrvInfo->PartAggr = %d\n",
5944 pDrvInfo
->FirstAGGR
, pDrvInfo
->PartAggr
);
5945 skb_trim(skb
, skb
->len
- 4/*sCrcLng*/);
5946 /* rx packets statistics */
5947 ieee80211_hdr
= (struct ieee80211_hdr_1addr
*)skb
->data
;
5948 unicast_packet
= false;
5950 if(is_broadcast_ether_addr(ieee80211_hdr
->addr1
)) {
5952 }else if(is_multicast_ether_addr(ieee80211_hdr
->addr1
)){
5955 /* unicast packet */
5956 unicast_packet
= true;
5959 stats
.packetlength
= stats
.Length
-4;
5960 stats
.fraglength
= stats
.packetlength
;
5961 stats
.fragoffset
= 0;
5962 stats
.ntotalfrag
= 1;
5964 if(!ieee80211_rx(priv
->ieee80211
, skb
, &stats
)){
5965 dev_kfree_skb_any(skb
);
5968 if(unicast_packet
) {
5969 priv
->stats
.rxbytesunicast
+= skb
->len
;
5974 priv
->rx_buf
[priv
->rx_idx
] = skb
;
5975 *((dma_addr_t
*) skb
->cb
) = pci_map_single(priv
->pdev
, skb
->tail
, priv
->rxbuffersize
, PCI_DMA_FROMDEVICE
);
5976 // *((dma_addr_t *) skb->cb) = pci_map_single(priv->pdev, skb_tail_pointer(skb), priv->rxbuffersize, PCI_DMA_FROMDEVICE);
5981 pdesc
->BufferAddress
= cpu_to_le32(*((dma_addr_t
*)skb
->cb
));
5983 pdesc
->Length
= priv
->rxbuffersize
;
5984 if (priv
->rx_idx
== priv
->rxringcount
-1)
5986 priv
->rx_idx
= (priv
->rx_idx
+ 1) % priv
->rxringcount
;
5991 void rtl8192_irq_rx_tasklet(struct r8192_priv
*priv
)
5993 rtl8192_rx(priv
->ieee80211
->dev
);
5995 write_nic_dword(priv
->ieee80211
->dev
, INTA_MASK
,read_nic_dword(priv
->ieee80211
->dev
, INTA_MASK
) | IMR_RDU
);
5998 static const struct net_device_ops rtl8192_netdev_ops
= {
5999 .ndo_open
= rtl8192_open
,
6000 .ndo_stop
= rtl8192_close
,
6001 /* .ndo_get_stats = rtl8192_stats, */
6002 .ndo_tx_timeout
= tx_timeout
,
6003 .ndo_do_ioctl
= rtl8192_ioctl
,
6004 .ndo_set_multicast_list
= r8192_set_multicast
,
6005 .ndo_set_mac_address
= r8192_set_mac_adr
,
6006 .ndo_start_xmit
= ieee80211_xmit
,
6009 /****************************************************************************
6010 ---------------------------- PCI_STUFF---------------------------
6011 *****************************************************************************/
6013 static int __devinit
rtl8192_pci_probe(struct pci_dev
*pdev
,
6014 const struct pci_device_id
*id
)
6016 unsigned long ioaddr
= 0;
6017 struct net_device
*dev
= NULL
;
6018 struct r8192_priv
*priv
= NULL
;
6021 #ifdef CONFIG_RTL8192_IO_MAP
6022 unsigned long pio_start
, pio_len
, pio_flags
;
6024 unsigned long pmem_start
, pmem_len
, pmem_flags
;
6025 #endif //end #ifdef RTL_IO_MAP
6027 RT_TRACE(COMP_INIT
,"Configuring chip resources");
6029 if( pci_enable_device (pdev
) ){
6030 RT_TRACE(COMP_ERR
,"Failed to enable PCI device");
6034 pci_set_master(pdev
);
6035 //pci_set_wmi(pdev);
6036 pci_set_dma_mask(pdev
, 0xffffff00ULL
);
6037 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
6038 pci_set_consistent_dma_mask(pdev
,0xffffff00ULL
);
6040 dev
= alloc_ieee80211(sizeof(struct r8192_priv
));
6044 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
6045 SET_MODULE_OWNER(dev
);
6048 pci_set_drvdata(pdev
, dev
);
6049 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
6050 SET_NETDEV_DEV(dev
, &pdev
->dev
);
6052 priv
= ieee80211_priv(dev
);
6053 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
6054 priv
->ieee80211
= netdev_priv(dev
);
6056 priv
->ieee80211
= (struct ieee80211_device
*)dev
->priv
;
6059 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
6060 if((pdev
->subsystem_vendor
== PCI_VENDOR_ID_DLINK
)&&(pdev
->subsystem_device
== 0x3304)){
6061 priv
->ieee80211
->bSupportRemoteWakeUp
= 1;
6065 priv
->ieee80211
->bSupportRemoteWakeUp
= 0;
6068 #ifdef CONFIG_RTL8192_IO_MAP
6070 pio_start
= (unsigned long)pci_resource_start (pdev
, 0);
6071 pio_len
= (unsigned long)pci_resource_len (pdev
, 0);
6072 pio_flags
= (unsigned long)pci_resource_flags (pdev
, 0);
6074 if (!(pio_flags
& IORESOURCE_IO
)) {
6075 RT_TRACE(COMP_ERR
,"region #0 not a PIO resource, aborting");
6079 //DMESG("IO space @ 0x%08lx", pio_start );
6080 if( ! request_region( pio_start
, pio_len
, RTL819xE_MODULE_NAME
) ){
6081 RT_TRACE(COMP_ERR
,"request_region failed!");
6086 dev
->base_addr
= ioaddr
; // device I/O address
6090 pmem_start
= pci_resource_start(pdev
, 1);
6091 pmem_len
= pci_resource_len(pdev
, 1);
6092 pmem_flags
= pci_resource_flags (pdev
, 1);
6094 if (!(pmem_flags
& IORESOURCE_MEM
)) {
6095 RT_TRACE(COMP_ERR
,"region #1 not a MMIO resource, aborting");
6099 //DMESG("Memory mapped space @ 0x%08lx ", pmem_start);
6100 if( ! request_mem_region(pmem_start
, pmem_len
, RTL819xE_MODULE_NAME
)) {
6101 RT_TRACE(COMP_ERR
,"request_mem_region failed!");
6106 ioaddr
= (unsigned long)ioremap_nocache( pmem_start
, pmem_len
);
6107 if( ioaddr
== (unsigned long)NULL
){
6108 RT_TRACE(COMP_ERR
,"ioremap failed!");
6109 // release_mem_region( pmem_start, pmem_len );
6113 dev
->mem_start
= ioaddr
; // shared mem start
6114 dev
->mem_end
= ioaddr
+ pci_resource_len(pdev
, 0); // shared mem end
6116 #endif //end #ifdef RTL_IO_MAP
6118 /* We disable the RETRY_TIMEOUT register (0x41) to keep
6119 * PCI Tx retries from interfering with C3 CPU state */
6120 pci_write_config_byte(pdev
, 0x41, 0x00);
6123 pci_read_config_byte(pdev
, 0x05, &unit
);
6124 pci_write_config_byte(pdev
, 0x05, unit
& (~0x04));
6126 dev
->irq
= pdev
->irq
;
6129 dev
->netdev_ops
= &rtl8192_netdev_ops
;
6131 dev
->open
= rtl8192_open
;
6132 dev
->stop
= rtl8192_close
;
6133 //dev->hard_start_xmit = rtl8192_8023_hard_start_xmit;
6134 dev
->tx_timeout
= tx_timeout
;
6135 //dev->wireless_handlers = &r8192_wx_handlers_def;
6136 dev
->do_ioctl
= rtl8192_ioctl
;
6137 dev
->set_multicast_list
= r8192_set_multicast
;
6138 dev
->set_mac_address
= r8192_set_mac_adr
;
6141 //DMESG("Oops: i'm coming\n");
6142 #if WIRELESS_EXT >= 12
6143 #if WIRELESS_EXT < 17
6144 dev
->get_wireless_stats
= r8192_get_wireless_stats
;
6146 dev
->wireless_handlers
= (struct iw_handler_def
*) &r8192_wx_handlers_def
;
6148 //dev->get_wireless_stats = r8192_get_wireless_stats;
6149 dev
->type
=ARPHRD_ETHER
;
6151 dev
->watchdog_timeo
= HZ
*3; //modified by john, 0805
6153 if (dev_alloc_name(dev
, ifname
) < 0){
6154 RT_TRACE(COMP_INIT
, "Oops: devname already taken! Trying wlan%%d...\n");
6156 dev_alloc_name(dev
, ifname
);
6159 RT_TRACE(COMP_INIT
, "Driver probe completed1\n");
6160 if(rtl8192_init(dev
)!=0){
6161 RT_TRACE(COMP_ERR
, "Initialization failed");
6165 netif_carrier_off(dev
);
6166 netif_stop_queue(dev
);
6168 register_netdev(dev
);
6169 RT_TRACE(COMP_INIT
, "dev name=======> %s\n",dev
->name
);
6170 rtl8192_proc_init_one(dev
);
6173 RT_TRACE(COMP_INIT
, "Driver probe completed\n");
6174 //#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
6182 #ifdef CONFIG_RTL8180_IO_MAP
6184 if( dev
->base_addr
!= 0 ){
6186 release_region(dev
->base_addr
,
6187 pci_resource_len(pdev
, 0) );
6190 if( dev
->mem_start
!= (unsigned long)NULL
){
6191 iounmap( (void *)dev
->mem_start
);
6192 release_mem_region( pci_resource_start(pdev
, 1),
6193 pci_resource_len(pdev
, 1) );
6195 #endif //end #ifdef RTL_IO_MAP
6201 free_irq(dev
->irq
, dev
);
6204 free_ieee80211(dev
);
6207 pci_disable_device(pdev
);
6209 DMESG("wlan driver load failed\n");
6210 pci_set_drvdata(pdev
, NULL
);
6215 /* detach all the work and timer structure declared or inititialized
6216 * in r8192_init function.
6218 void rtl8192_cancel_deferred_work(struct r8192_priv
* priv
)
6220 /* call cancel_work_sync instead of cancel_delayed_work if and only if Linux_version_code
6221 * is or is newer than 2.6.20 and work structure is defined to be struct work_struct.
6222 * Otherwise call cancel_delayed_work is enough.
6223 * FIXME (2.6.20 shoud 2.6.22, work_struct shoud not cancel)
6225 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
6226 cancel_delayed_work(&priv
->watch_dog_wq
);
6227 cancel_delayed_work(&priv
->update_beacon_wq
);
6228 cancel_delayed_work(&priv
->ieee80211
->hw_wakeup_wq
);
6229 cancel_delayed_work(&priv
->ieee80211
->hw_sleep_wq
);
6231 cancel_delayed_work(&priv
->gpio_change_rf_wq
);
6234 #if LINUX_VERSION_CODE >=KERNEL_VERSION(2,6,22)
6235 cancel_work_sync(&priv
->reset_wq
);
6236 cancel_work_sync(&priv
->qos_activate
);
6237 //cancel_work_sync(&priv->SetBWModeWorkItem);
6238 //cancel_work_sync(&priv->SwChnlWorkItem);
6240 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
6241 cancel_delayed_work(&priv
->reset_wq
);
6242 cancel_delayed_work(&priv
->qos_activate
);
6243 //cancel_delayed_work(&priv->SetBWModeWorkItem);
6244 //cancel_delayed_work(&priv->SwChnlWorkItem);
6251 static void __devexit
rtl8192_pci_disconnect(struct pci_dev
*pdev
)
6253 struct net_device
*dev
= pci_get_drvdata(pdev
);
6254 struct r8192_priv
*priv
;
6258 unregister_netdev(dev
);
6260 priv
=ieee80211_priv(dev
);
6262 rtl8192_proc_remove_one(dev
);
6265 if (priv
->pFirmware
)
6267 vfree(priv
->pFirmware
);
6268 priv
->pFirmware
= NULL
;
6270 // priv->rf_close(dev);
6271 // rtl8192_usb_deleteendpoints(dev);
6272 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
6273 destroy_workqueue(priv
->priv_wq
);
6275 /* redundant with rtl8192_down */
6276 // rtl8192_irq_disable(dev);
6277 // rtl8192_reset(dev);
6281 /* free tx/rx rings */
6282 rtl8192_free_rx_ring(dev
);
6283 for (i
= 0; i
< MAX_TX_QUEUE_COUNT
; i
++) {
6284 rtl8192_free_tx_ring(dev
, i
);
6289 printk("Freeing irq %d\n",dev
->irq
);
6290 free_irq(dev
->irq
, dev
);
6297 // free_beacon_desc_ring(dev,priv->txbeaconcount);
6299 #ifdef CONFIG_RTL8180_IO_MAP
6301 if( dev
->base_addr
!= 0 ){
6303 release_region(dev
->base_addr
,
6304 pci_resource_len(pdev
, 0) );
6307 if( dev
->mem_start
!= (unsigned long)NULL
){
6308 iounmap( (void *)dev
->mem_start
);
6309 release_mem_region( pci_resource_start(pdev
, 1),
6310 pci_resource_len(pdev
, 1) );
6312 #endif /*end #ifdef RTL_IO_MAP*/
6313 free_ieee80211(dev
);
6317 pci_disable_device(pdev
);
6318 RT_TRACE(COMP_DOWN
, "wlan driver removed\n");
6321 extern int ieee80211_init(void);
6322 extern void ieee80211_exit(void);
6324 static int __init
rtl8192_pci_module_init(void)
6328 retval
= ieee80211_init();
6332 printk(KERN_INFO
"\nLinux kernel driver for RTL8192 based WLAN cards\n");
6333 printk(KERN_INFO
"Copyright (c) 2007-2008, Realsil Wlan\n");
6334 RT_TRACE(COMP_INIT
, "Initializing module");
6335 RT_TRACE(COMP_INIT
, "Wireless extensions version %d", WIRELESS_EXT
);
6336 rtl8192_proc_module_init();
6337 #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22))
6338 if(0!=pci_module_init(&rtl8192_pci_driver
))
6340 if(0!=pci_register_driver(&rtl8192_pci_driver
))
6343 DMESG("No device found");
6344 /*pci_unregister_driver (&rtl8192_pci_driver);*/
6351 static void __exit
rtl8192_pci_module_exit(void)
6353 pci_unregister_driver(&rtl8192_pci_driver
);
6355 RT_TRACE(COMP_DOWN
, "Exiting");
6356 rtl8192_proc_module_remove();
6360 //warning message WB
6361 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18)
6362 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
6363 void rtl8192_interrupt(int irq
, void *netdev
, struct pt_regs
*regs
)
6365 irqreturn_t
rtl8192_interrupt(int irq
, void *netdev
, struct pt_regs
*regs
)
6368 irqreturn_t
rtl8192_interrupt(int irq
, void *netdev
)
6371 struct net_device
*dev
= (struct net_device
*) netdev
;
6372 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
6373 unsigned long flags
;
6375 /* We should return IRQ_NONE, but for now let me keep this */
6376 if(priv
->irq_enabled
== 0){
6377 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
6384 spin_lock_irqsave(&priv
->irq_th_lock
,flags
);
6388 inta
= read_nic_dword(dev
, ISR
);// & priv->IntrMask;
6389 write_nic_dword(dev
,ISR
,inta
); // reset int situation
6391 priv
->stats
.shints
++;
6392 //DMESG("Enter interrupt, ISR value = 0x%08x", inta);
6394 spin_unlock_irqrestore(&priv
->irq_th_lock
,flags
);
6395 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
6401 most probably we can safely return IRQ_NONE,
6402 but for now is better to avoid problems
6408 spin_unlock_irqrestore(&priv
->irq_th_lock
,flags
);
6409 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
6418 DMESG("NIC irq %x",inta
);
6420 //priv->irqpending = inta;
6423 if(!netif_running(dev
)) {
6424 spin_unlock_irqrestore(&priv
->irq_th_lock
,flags
);
6425 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
6432 if(inta
& IMR_TIMEOUT0
){
6433 // write_nic_dword(dev, TimerInt, 0);
6434 //DMESG("=================>waking up");
6435 // rtl8180_hw_wakeup(dev);
6438 if(inta
& IMR_TBDOK
){
6439 RT_TRACE(COMP_INTR
, "beacon ok interrupt!\n");
6440 rtl8192_tx_isr(dev
, BEACON_QUEUE
);
6441 priv
->stats
.txbeaconokint
++;
6444 if(inta
& IMR_TBDER
){
6445 RT_TRACE(COMP_INTR
, "beacon ok interrupt!\n");
6446 rtl8192_tx_isr(dev
, BEACON_QUEUE
);
6447 priv
->stats
.txbeaconerr
++;
6450 if(inta
& IMR_MGNTDOK
) {
6451 RT_TRACE(COMP_INTR
, "Manage ok interrupt!\n");
6452 priv
->stats
.txmanageokint
++;
6453 rtl8192_tx_isr(dev
,MGNT_QUEUE
);
6457 if(inta
& IMR_COMDOK
)
6459 priv
->stats
.txcmdpktokint
++;
6460 rtl8192_tx_isr(dev
,TXCMD_QUEUE
);
6465 DMESG("Frame arrived !");
6467 priv
->stats
.rxint
++;
6468 tasklet_schedule(&priv
->irq_rx_tasklet
);
6471 if(inta
& IMR_BcnInt
) {
6472 RT_TRACE(COMP_INTR
, "prepare beacon for interrupt!\n");
6473 tasklet_schedule(&priv
->irq_prepare_beacon_tasklet
);
6477 RT_TRACE(COMP_INTR
, "rx descriptor unavailable!\n");
6478 priv
->stats
.rxrdu
++;
6479 /* reset int situation */
6480 write_nic_dword(dev
,INTA_MASK
,read_nic_dword(dev
, INTA_MASK
) & ~IMR_RDU
);
6481 tasklet_schedule(&priv
->irq_rx_tasklet
);
6484 if(inta
& IMR_RXFOVW
){
6485 RT_TRACE(COMP_INTR
, "rx overflow !\n");
6486 priv
->stats
.rxoverflow
++;
6487 tasklet_schedule(&priv
->irq_rx_tasklet
);
6490 if(inta
& IMR_TXFOVW
) priv
->stats
.txoverflow
++;
6492 if(inta
& IMR_BKDOK
){
6493 RT_TRACE(COMP_INTR
, "BK Tx OK interrupt!\n");
6494 priv
->stats
.txbkokint
++;
6495 priv
->ieee80211
->LinkDetectInfo
.NumTxOkInPeriod
++;
6496 rtl8192_tx_isr(dev
,BK_QUEUE
);
6497 rtl8192_try_wake_queue(dev
, BK_QUEUE
);
6500 if(inta
& IMR_BEDOK
){
6501 RT_TRACE(COMP_INTR
, "BE TX OK interrupt!\n");
6502 priv
->stats
.txbeokint
++;
6503 priv
->ieee80211
->LinkDetectInfo
.NumTxOkInPeriod
++;
6504 rtl8192_tx_isr(dev
,BE_QUEUE
);
6505 rtl8192_try_wake_queue(dev
, BE_QUEUE
);
6508 if(inta
& IMR_VIDOK
){
6509 RT_TRACE(COMP_INTR
, "VI TX OK interrupt!\n");
6510 priv
->stats
.txviokint
++;
6511 priv
->ieee80211
->LinkDetectInfo
.NumTxOkInPeriod
++;
6512 rtl8192_tx_isr(dev
,VI_QUEUE
);
6513 rtl8192_try_wake_queue(dev
, VI_QUEUE
);
6516 if(inta
& IMR_VODOK
){
6517 priv
->stats
.txvookint
++;
6518 priv
->ieee80211
->LinkDetectInfo
.NumTxOkInPeriod
++;
6519 rtl8192_tx_isr(dev
,VO_QUEUE
);
6520 rtl8192_try_wake_queue(dev
, VO_QUEUE
);
6523 force_pci_posting(dev
);
6524 spin_unlock_irqrestore(&priv
->irq_th_lock
,flags
);
6526 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
6533 void rtl8192_try_wake_queue(struct net_device
*dev
, int pri
)
6536 unsigned long flags
;
6538 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
6540 spin_lock_irqsave(&priv
->tx_lock
,flags
);
6541 enough_desc
= check_nic_enough_desc(dev
,pri
);
6542 spin_unlock_irqrestore(&priv
->tx_lock
,flags
);
6545 ieee80211_wake_queue(priv
->ieee80211
);
6550 void EnableHWSecurityConfig8192(struct net_device
*dev
)
6552 u8 SECR_value
= 0x0;
6553 // struct ieee80211_device* ieee1 = container_of(&dev, struct ieee80211_device, dev);
6554 //printk("==>ieee1:%p, dev:%p\n", ieee1, dev);
6555 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
6556 struct ieee80211_device
* ieee
= priv
->ieee80211
;
6557 //printk("==>ieee:%p, dev:%p\n", ieee, dev);
6558 SECR_value
= SCR_TxEncEnable
| SCR_RxDecEnable
;
6560 if (((KEY_TYPE_WEP40
== ieee
->pairwise_key_type
) || (KEY_TYPE_WEP104
== ieee
->pairwise_key_type
)) && (priv
->ieee80211
->auth_mode
!= 2))
6562 SECR_value
|= SCR_RxUseDK
;
6563 SECR_value
|= SCR_TxUseDK
;
6565 else if ((ieee
->iw_mode
== IW_MODE_ADHOC
) && (ieee
->pairwise_key_type
& (KEY_TYPE_CCMP
| KEY_TYPE_TKIP
)))
6567 SECR_value
|= SCR_RxUseDK
;
6568 SECR_value
|= SCR_TxUseDK
;
6573 //add HWSec active enable here.
6574 //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
6575 ieee
->hwsec_active
= 1;
6577 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
6579 ieee
->hwsec_active
= 0;
6580 SECR_value
&= ~SCR_RxDecEnable
;
6583 RT_TRACE(COMP_SEC
,"%s:, hwsec:%d, pairwise_key:%d, SECR_value:%x\n", __FUNCTION__
, \
6584 ieee
->hwsec_active
, ieee
->pairwise_key_type
, SECR_value
);
6586 write_nic_byte(dev
, SECR
, SECR_value
);//SECR_value | SCR_UseDK );
6590 #define TOTAL_CAM_ENTRY 32
6591 //#define CAM_CONTENT_COUNT 8
6592 void setKey( struct net_device
*dev
,
6600 u32 TargetCommand
= 0;
6601 u32 TargetContent
= 0;
6605 struct r8192_priv
*priv
= (struct r8192_priv
*)ieee80211_priv(dev
);
6606 RT_RF_POWER_STATE rtState
;
6607 rtState
= priv
->ieee80211
->eRFPowerState
;
6608 if(priv
->ieee80211
->PowerSaveControl
.bInactivePs
){
6609 if(rtState
== eRfOff
){
6610 if(priv
->ieee80211
->RfOffReason
> RF_CHANGE_BY_IPS
)
6612 RT_TRACE(COMP_ERR
, "%s(): RF is OFF.\n",__FUNCTION__
);
6621 priv
->ieee80211
->is_set_key
= true;
6623 if (EntryNo
>= TOTAL_CAM_ENTRY
)
6624 RT_TRACE(COMP_ERR
, "cam entry exceeds in setKey()\n");
6626 RT_TRACE(COMP_SEC
, "====>to setKey(), dev:%p, EntryNo:%d, KeyIndex:%d, KeyType:%d, MacAddr"MAC_FMT
"\n", dev
,EntryNo
, KeyIndex
, KeyType
, MAC_ARG(MacAddr
));
6629 usConfig
|= BIT15
| (KeyType
<<2);
6631 usConfig
|= BIT15
| (KeyType
<<2) | KeyIndex
;
6632 // usConfig |= BIT15 | (KeyType<<2) | (DefaultKey<<5) | KeyIndex;
6635 for(i
=0 ; i
<CAM_CONTENT_COUNT
; i
++){
6636 TargetCommand
= i
+CAM_CONTENT_COUNT
*EntryNo
;
6637 TargetCommand
|= BIT31
|BIT16
;
6639 if(i
==0){//MAC|Config
6640 TargetContent
= (u32
)(*(MacAddr
+0)) << 16|
6641 (u32
)(*(MacAddr
+1)) << 24|
6644 write_nic_dword(dev
, WCAMI
, TargetContent
);
6645 write_nic_dword(dev
, RWCAM
, TargetCommand
);
6646 // printk("setkey cam =%8x\n", read_cam(dev, i+6*EntryNo));
6649 TargetContent
= (u32
)(*(MacAddr
+2)) |
6650 (u32
)(*(MacAddr
+3)) << 8|
6651 (u32
)(*(MacAddr
+4)) << 16|
6652 (u32
)(*(MacAddr
+5)) << 24;
6653 write_nic_dword(dev
, WCAMI
, TargetContent
);
6654 write_nic_dword(dev
, RWCAM
, TargetCommand
);
6656 else { //Key Material
6657 if(KeyContent
!= NULL
)
6659 write_nic_dword(dev
, WCAMI
, (u32
)(*(KeyContent
+i
-2)) );
6660 write_nic_dword(dev
, RWCAM
, TargetCommand
);
6664 RT_TRACE(COMP_SEC
,"=========>after set key, usconfig:%x\n", usConfig
);
6666 // This function seems not ready! WB
6667 void CamPrintDbgReg(struct net_device
* dev
)
6669 unsigned long rvalue
;
6670 unsigned char ucValue
;
6671 write_nic_dword(dev
, DCAM
, 0x80000000);
6673 rvalue
= read_nic_dword(dev
, DCAM
); //delay_ms(40);
6674 RT_TRACE(COMP_SEC
, " TX CAM=%8lX ",rvalue
);
6675 if((rvalue
& 0x40000000) != 0x4000000)
6676 RT_TRACE(COMP_SEC
, "-->TX Key Not Found ");
6678 write_nic_dword(dev
, DCAM
, 0x00000000); //delay_ms(40);
6679 rvalue
= read_nic_dword(dev
, DCAM
); //delay_ms(40);
6680 RT_TRACE(COMP_SEC
, "RX CAM=%8lX ",rvalue
);
6681 if((rvalue
& 0x40000000) != 0x4000000)
6682 RT_TRACE(COMP_SEC
, "-->CAM Key Not Found ");
6683 ucValue
= read_nic_byte(dev
, SECR
);
6684 RT_TRACE(COMP_SEC
, "WPA_Config=%x \n",ucValue
);
6688 /***************************************************************************
6689 ------------------- module init / exit stubs ----------------
6690 ****************************************************************************/
6691 module_init(rtl8192_pci_module_init
);
6692 module_exit(rtl8192_pci_module_exit
);