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