r8192U_core.c revision f61fb9356d20977258bb59a8d9f1857d2c58ac98
1/******************************************************************************
2 * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
3 * Linux device driver for RTL8192U
4 *
5 * Based on the r8187 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#ifndef CONFIG_FORCE_HARD_FLOAT
28double __floatsidf (int i) { return i; }
29unsigned int __fixunsdfsi (double d) { return d; }
30double __adddf3(double a, double b) { return a+b; }
31double __addsf3(float a, float b) { return a+b; }
32double __subdf3(double a, double b) { return a-b; }
33double __extendsfdf2(float a) {return a;}
34#endif
35
36#undef LOOP_TEST
37#undef DUMP_RX
38#undef DUMP_TX
39#undef DEBUG_TX_DESC2
40#undef RX_DONT_PASS_UL
41#undef DEBUG_EPROM
42#undef DEBUG_RX_VERBOSE
43#undef DUMMY_RX
44#undef DEBUG_ZERO_RX
45#undef DEBUG_RX_SKB
46#undef DEBUG_TX_FRAG
47#undef DEBUG_RX_FRAG
48#undef DEBUG_TX_FILLDESC
49#undef DEBUG_TX
50#undef DEBUG_IRQ
51#undef DEBUG_RX
52#undef DEBUG_RXALLOC
53#undef DEBUG_REGISTERS
54#undef DEBUG_RING
55#undef DEBUG_IRQ_TASKLET
56#undef DEBUG_TX_ALLOC
57#undef DEBUG_TX_DESC
58
59#define CONFIG_RTL8192_IO_MAP
60
61#include <asm/uaccess.h>
62#include "r8192U_hw.h"
63#include "r8192U.h"
64#include "r8190_rtl8256.h" /* RTL8225 Radio frontend */
65#include "r8180_93cx6.h"   /* Card EEPROM */
66#include "r8192U_wx.h"
67#include "r819xU_phy.h" //added by WB 4.30.2008
68#include "r819xU_phyreg.h"
69#include "r819xU_cmdpkt.h"
70#include "r8192U_dm.h"
71//#include "r8192xU_phyreg.h"
72#include <linux/usb.h>
73// FIXME: check if 2.6.7 is ok
74#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,7))
75#define usb_kill_urb usb_unlink_urb
76#endif
77
78#ifdef CONFIG_RTL8192_PM
79#include "r8192_pm.h"
80#endif
81
82#ifdef ENABLE_DOT11D
83#include "dot11d.h"
84#endif
85//set here to open your trace code. //WB
86u32 rt_global_debug_component = \
87			//	COMP_INIT    	|
88//				COMP_DBG	|
89			//	COMP_EPROM   	|
90//				COMP_PHY	|
91			//	COMP_RF		|
92//				COMP_FIRMWARE	|
93//				COMP_CH		|
94			//	COMP_POWER_TRACKING |
95//				COMP_RATE	|
96			//	COMP_TXAGC	|
97		//		COMP_TRACE	|
98				COMP_DOWN	|
99		//		COMP_RECV	|
100                //              COMP_SWBW	|
101				COMP_SEC	|
102	//			COMP_RESET	|
103		//		COMP_SEND	|
104			//	COMP_EVENTS	|
105				COMP_ERR ; //always open err flags on
106
107#define TOTAL_CAM_ENTRY 32
108#define CAM_CONTENT_COUNT 8
109
110static struct usb_device_id rtl8192_usb_id_tbl[] = {
111	/* Realtek */
112	{USB_DEVICE(0x0bda, 0x8192)},
113	{USB_DEVICE(0x0bda, 0x8709)},
114	/* Corega */
115	{USB_DEVICE(0x07aa, 0x0043)},
116	/* Belkin */
117	{USB_DEVICE(0x050d, 0x805E)},
118	/* Sitecom */
119	{USB_DEVICE(0x0df6, 0x0031)},
120	/* EnGenius */
121	{USB_DEVICE(0x1740, 0x9201)},
122	/* Dlink */
123	{USB_DEVICE(0x2001, 0x3301)},
124	/* Zinwell */
125	{USB_DEVICE(0x5a57, 0x0290)},
126	{}
127};
128
129MODULE_LICENSE("GPL");
130#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
131MODULE_VERSION("V 1.1");
132#endif
133MODULE_DEVICE_TABLE(usb, rtl8192_usb_id_tbl);
134MODULE_DESCRIPTION("Linux driver for Realtek RTL8192 USB WiFi cards");
135
136static char* ifname = "wlan%d";
137#if 0
138static int hwseqnum = 0;
139static int hwwep = 0;
140#endif
141static int hwwep = 1;  //default use hw. set 0 to use software security
142static int channels = 0x3fff;
143
144
145
146#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 9)
147module_param(ifname, charp, S_IRUGO|S_IWUSR );
148//module_param(hwseqnum,int, S_IRUGO|S_IWUSR);
149module_param(hwwep,int, S_IRUGO|S_IWUSR);
150module_param(channels,int, S_IRUGO|S_IWUSR);
151#else
152MODULE_PARM(ifname, "s");
153//MODULE_PARM(hwseqnum,"i");
154MODULE_PARM(hwwep,"i");
155MODULE_PARM(channels,"i");
156#endif
157
158MODULE_PARM_DESC(ifname," Net interface name, wlan%d=default");
159//MODULE_PARM_DESC(hwseqnum," Try to use hardware 802.11 header sequence numbers. Zero=default");
160MODULE_PARM_DESC(hwwep," Try to use hardware security support. ");
161MODULE_PARM_DESC(channels," Channel bitmask for specific locales. NYI");
162
163#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
164static int __devinit rtl8192_usb_probe(struct usb_interface *intf,
165			 const struct usb_device_id *id);
166static void __devexit rtl8192_usb_disconnect(struct usb_interface *intf);
167#else
168static void *__devinit rtl8192_usb_probe(struct usb_device *udev,unsigned int ifnum,
169			 const struct usb_device_id *id);
170static void __devexit rtl8192_usb_disconnect(struct usb_device *udev, void *ptr);
171#endif
172
173
174static struct usb_driver rtl8192_usb_driver = {
175#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 15)
176	.owner		= THIS_MODULE,
177#endif
178	.name		= RTL819xU_MODULE_NAME,	          /* Driver name   */
179	.id_table	= rtl8192_usb_id_tbl,	          /* PCI_ID table  */
180	.probe		= rtl8192_usb_probe,	          /* probe fn      */
181	.disconnect	= rtl8192_usb_disconnect,	  /* remove fn     */
182#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0)
183#ifdef CONFIG_RTL8192_PM
184	.suspend	= rtl8192_suspend,	          /* PM suspend fn */
185	.resume		= rtl8192_resume,                 /* PM resume fn  */
186#else
187	.suspend	= NULL,			          /* PM suspend fn */
188	.resume      	= NULL,			          /* PM resume fn  */
189#endif
190#endif
191};
192
193#ifdef ENABLE_DOT11D
194
195typedef struct _CHANNEL_LIST
196{
197	u8	Channel[32];
198	u8	Len;
199}CHANNEL_LIST, *PCHANNEL_LIST;
200
201static CHANNEL_LIST ChannelPlan[] = {
202	{{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
203	{{1,2,3,4,5,6,7,8,9,10,11},11},                    				//IC
204	{{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48,52,56,60,64},21},  	//ETSI
205	{{1,2,3,4,5,6,7,8,9,10,11,12,13},13},    //Spain. Change to ETSI.
206	{{1,2,3,4,5,6,7,8,9,10,11,12,13},13},  	//France. Change to ETSI.
207	{{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
208	{{1,2,3,4,5,6,7,8,9,10,11,12,13,14,36,40,44,48,52,56,60,64},22},//MKK1
209	{{1,2,3,4,5,6,7,8,9,10,11,12,13},13},	//Israel.
210	{{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
211	{{1,2,3,4,5,6,7,8,9,10,11,12,13,14,36,40,44,48,52,56,60,64}, 22},    //MIC
212	{{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
213};
214
215static void rtl819x_set_channel_map(u8 channel_plan, struct r8192_priv* priv)
216{
217	int i, max_chan=-1, min_chan=-1;
218	struct ieee80211_device* ieee = priv->ieee80211;
219	switch (channel_plan)
220	{
221		case COUNTRY_CODE_FCC:
222		case COUNTRY_CODE_IC:
223		case COUNTRY_CODE_ETSI:
224		case COUNTRY_CODE_SPAIN:
225		case COUNTRY_CODE_FRANCE:
226		case COUNTRY_CODE_MKK:
227		case COUNTRY_CODE_MKK1:
228		case COUNTRY_CODE_ISRAEL:
229		case COUNTRY_CODE_TELEC:
230		case COUNTRY_CODE_MIC:
231		{
232			Dot11d_Init(ieee);
233			ieee->bGlobalDomain = false;
234			//acturally 8225 & 8256 rf chip only support B,G,24N mode
235			if ((priv->rf_chip == RF_8225) || (priv->rf_chip == RF_8256))
236			{
237				min_chan = 1;
238				max_chan = 14;
239			}
240			else
241			{
242				RT_TRACE(COMP_ERR, "unknown rf chip, can't set channel map in function:%s()\n", __FUNCTION__);
243			}
244			if (ChannelPlan[channel_plan].Len != 0){
245				// Clear old channel map
246				memset(GET_DOT11D_INFO(ieee)->channel_map, 0, sizeof(GET_DOT11D_INFO(ieee)->channel_map));
247				// Set new channel map
248				for (i=0;i<ChannelPlan[channel_plan].Len;i++)
249				{
250					if (ChannelPlan[channel_plan].Channel[i] < min_chan || ChannelPlan[channel_plan].Channel[i] > max_chan)
251					break;
252					GET_DOT11D_INFO(ieee)->channel_map[ChannelPlan[channel_plan].Channel[i]] = 1;
253				}
254			}
255			break;
256		}
257		case COUNTRY_CODE_GLOBAL_DOMAIN:
258		{
259			GET_DOT11D_INFO(ieee)->bEnabled = 0;//this flag enabled to follow 11d country IE setting, otherwise, it shall follow global domain settings.
260			Dot11d_Reset(ieee);
261			ieee->bGlobalDomain = true;
262			break;
263		}
264		default:
265			break;
266	}
267	return;
268}
269#endif
270
271#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 )
272
273#define 	rx_hal_is_cck_rate(_pdrvinfo)\
274			(_pdrvinfo->RxRate == DESC90_RATE1M ||\
275			_pdrvinfo->RxRate == DESC90_RATE2M ||\
276			_pdrvinfo->RxRate == DESC90_RATE5_5M ||\
277			_pdrvinfo->RxRate == DESC90_RATE11M) &&\
278			!_pdrvinfo->RxHT\
279
280
281void CamResetAllEntry(struct net_device *dev)
282{
283#if 1
284	u32 ulcommand = 0;
285        //2004/02/11  In static WEP, OID_ADD_KEY or OID_ADD_WEP are set before STA associate to AP.
286        // However, ResetKey is called on OID_802_11_INFRASTRUCTURE_MODE and MlmeAssociateRequest
287        // In this condition, Cam can not be reset because upper layer will not set this static key again.
288        //if(Adapter->EncAlgorithm == WEP_Encryption)
289        //      return;
290//debug
291        //DbgPrint("========================================\n");
292        //DbgPrint("                            Call ResetAllEntry                                              \n");
293        //DbgPrint("========================================\n\n");
294	ulcommand |= BIT31|BIT30;
295	write_nic_dword(dev, RWCAM, ulcommand);
296#else
297        for(ucIndex=0;ucIndex<TOTAL_CAM_ENTRY;ucIndex++)
298                CAM_mark_invalid(dev, ucIndex);
299        for(ucIndex=0;ucIndex<TOTAL_CAM_ENTRY;ucIndex++)
300                CAM_empty_entry(dev, ucIndex);
301#endif
302
303}
304
305
306void write_cam(struct net_device *dev, u8 addr, u32 data)
307{
308        write_nic_dword(dev, WCAMI, data);
309        write_nic_dword(dev, RWCAM, BIT31|BIT16|(addr&0xff) );
310}
311
312u32 read_cam(struct net_device *dev, u8 addr)
313{
314        write_nic_dword(dev, RWCAM, 0x80000000|(addr&0xff) );
315        return read_nic_dword(dev, 0xa8);
316}
317
318void write_nic_byte_E(struct net_device *dev, int indx, u8 data)
319{
320	int status;
321	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
322	struct usb_device *udev = priv->udev;
323
324	status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
325			       RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
326			       indx|0xfe00, 0, &data, 1, HZ / 2);
327
328	if (status < 0)
329	{
330		printk("write_nic_byte_E TimeOut! status:%d\n", status);
331	}
332}
333
334u8 read_nic_byte_E(struct net_device *dev, int indx)
335{
336	int status;
337	u8 data;
338	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
339	struct usb_device *udev = priv->udev;
340
341	status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
342			       RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
343			       indx|0xfe00, 0, &data, 1, HZ / 2);
344
345        if (status < 0)
346        {
347                printk("read_nic_byte_E TimeOut! status:%d\n", status);
348        }
349
350	return data;
351}
352//as 92U has extend page from 4 to 16, so modify functions below.
353void write_nic_byte(struct net_device *dev, int indx, u8 data)
354{
355	int status;
356
357	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
358	struct usb_device *udev = priv->udev;
359
360	status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
361			       RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
362			       (indx&0xff)|0xff00, (indx>>8)&0x0f, &data, 1, HZ / 2);
363
364        if (status < 0)
365        {
366                printk("write_nic_byte TimeOut! status:%d\n", status);
367        }
368
369
370}
371
372
373void write_nic_word(struct net_device *dev, int indx, u16 data)
374{
375
376	int status;
377
378	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
379	struct usb_device *udev = priv->udev;
380
381	status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
382			       RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
383			       (indx&0xff)|0xff00, (indx>>8)&0x0f, &data, 2, HZ / 2);
384
385        if (status < 0)
386        {
387                printk("write_nic_word TimeOut! status:%d\n", status);
388        }
389
390}
391
392
393void write_nic_dword(struct net_device *dev, int indx, u32 data)
394{
395
396	int status;
397
398	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
399	struct usb_device *udev = priv->udev;
400
401	status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
402			       RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
403			       (indx&0xff)|0xff00, (indx>>8)&0x0f, &data, 4, HZ / 2);
404
405
406        if (status < 0)
407        {
408                printk("write_nic_dword TimeOut! status:%d\n", status);
409        }
410
411}
412
413
414
415u8 read_nic_byte(struct net_device *dev, int indx)
416{
417	u8 data;
418	int status;
419	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
420	struct usb_device *udev = priv->udev;
421
422	status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
423			       RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
424			       (indx&0xff)|0xff00, (indx>>8)&0x0f, &data, 1, HZ / 2);
425
426        if (status < 0)
427        {
428                printk("read_nic_byte TimeOut! status:%d\n", status);
429        }
430
431	return data;
432}
433
434
435
436u16 read_nic_word(struct net_device *dev, int indx)
437{
438	u16 data;
439	int status;
440	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
441	struct usb_device *udev = priv->udev;
442
443	status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
444			       RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
445			       (indx&0xff)|0xff00, (indx>>8)&0x0f, &data, 2, HZ / 2);
446
447        if (status < 0)
448        {
449                printk("read_nic_word TimeOut! status:%d\n", status);
450        }
451
452
453	return data;
454}
455
456u16 read_nic_word_E(struct net_device *dev, int indx)
457{
458	u16 data;
459	int status;
460	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
461	struct usb_device *udev = priv->udev;
462
463	status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
464			       RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
465			       indx|0xfe00, 0, &data, 2, HZ / 2);
466
467        if (status < 0)
468        {
469                printk("read_nic_word TimeOut! status:%d\n", status);
470        }
471
472
473	return data;
474}
475
476u32 read_nic_dword(struct net_device *dev, int indx)
477{
478	u32 data;
479	int status;
480//	int result;
481
482	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
483	struct usb_device *udev = priv->udev;
484
485	status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
486			       RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
487			       (indx&0xff)|0xff00, (indx>>8)&0x0f, &data, 4, HZ / 2);
488//	if(0 != result) {
489//	  printk(KERN_WARNING "read size of data = %d\, date = %d\n", result, data);
490//	}
491
492        if (status < 0)
493        {
494                printk("read_nic_dword TimeOut! status:%d\n", status);
495        }
496
497
498
499	return data;
500}
501
502
503//u8 read_phy_cck(struct net_device *dev, u8 adr);
504//u8 read_phy_ofdm(struct net_device *dev, u8 adr);
505/* this might still called in what was the PHY rtl8185/rtl8192 common code
506 * plans are to possibilty turn it again in one common code...
507 */
508inline void force_pci_posting(struct net_device *dev)
509{
510}
511
512
513static struct net_device_stats *rtl8192_stats(struct net_device *dev);
514void rtl8192_commit(struct net_device *dev);
515//void rtl8192_restart(struct net_device *dev);
516#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
517void rtl8192_restart(struct work_struct *work);
518//void rtl8192_rq_tx_ack(struct work_struct *work);
519#else
520 void rtl8192_restart(struct net_device *dev);
521// //void rtl8192_rq_tx_ack(struct net_device *dev);
522 #endif
523
524void watch_dog_timer_callback(unsigned long data);
525
526/****************************************************************************
527   -----------------------------PROCFS STUFF-------------------------
528*****************************************************************************/
529
530static struct proc_dir_entry *rtl8192_proc = NULL;
531
532
533
534static int proc_get_stats_ap(char *page, char **start,
535			  off_t offset, int count,
536			  int *eof, void *data)
537{
538	struct net_device *dev = data;
539	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
540	struct ieee80211_device *ieee = priv->ieee80211;
541	struct ieee80211_network *target;
542
543	int len = 0;
544
545        list_for_each_entry(target, &ieee->network_list, list) {
546
547		len += snprintf(page + len, count - len,
548                "%s ", target->ssid);
549
550		if(target->wpa_ie_len>0 || target->rsn_ie_len>0){
551	                len += snprintf(page + len, count - len,
552        	        "WPA\n");
553		}
554		else{
555                        len += snprintf(page + len, count - len,
556                        "non_WPA\n");
557                }
558
559        }
560
561	*eof = 1;
562	return len;
563}
564
565static int proc_get_registers(char *page, char **start,
566			  off_t offset, int count,
567			  int *eof, void *data)
568{
569	struct net_device *dev = data;
570//	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
571
572	int len = 0;
573	int i,n;
574
575	int max=0xff;
576
577	/* This dump the current register page */
578len += snprintf(page + len, count - len,
579                        "\n####################page 0##################\n ");
580
581	for(n=0;n<=max;)
582	{
583		//printk( "\nD: %2x> ", n);
584		len += snprintf(page + len, count - len,
585			"\nD:  %2x > ",n);
586
587		for(i=0;i<16 && n<=max;i++,n++)
588		len += snprintf(page + len, count - len,
589			"%2x ",read_nic_byte(dev,0x000|n));
590
591		//	printk("%2x ",read_nic_byte(dev,n));
592	}
593#if 1
594len += snprintf(page + len, count - len,
595                        "\n####################page 1##################\n ");
596        for(n=0;n<=max;)
597        {
598                //printk( "\nD: %2x> ", n);
599                len += snprintf(page + len, count - len,
600                        "\nD:  %2x > ",n);
601
602                for(i=0;i<16 && n<=max;i++,n++)
603                len += snprintf(page + len, count - len,
604                        "%2x ",read_nic_byte(dev,0x100|n));
605
606                //      printk("%2x ",read_nic_byte(dev,n));
607        }
608len += snprintf(page + len, count - len,
609                        "\n####################page 3##################\n ");
610        for(n=0;n<=max;)
611        {
612                //printk( "\nD: %2x> ", n);
613                len += snprintf(page + len, count - len,
614                        "\nD:  %2x > ",n);
615
616                for(i=0;i<16 && n<=max;i++,n++)
617                len += snprintf(page + len, count - len,
618                        "%2x ",read_nic_byte(dev,0x300|n));
619
620                //      printk("%2x ",read_nic_byte(dev,n));
621        }
622
623#endif
624
625	len += snprintf(page + len, count - len,"\n");
626	*eof = 1;
627	return len;
628
629}
630
631
632#if 0
633static int proc_get_cck_reg(char *page, char **start,
634			  off_t offset, int count,
635			  int *eof, void *data)
636{
637	struct net_device *dev = data;
638//	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
639
640	int len = 0;
641	int i,n;
642
643	int max = 0x5F;
644
645	/* This dump the current register page */
646	for(n=0;n<=max;)
647	{
648		//printk( "\nD: %2x> ", n);
649		len += snprintf(page + len, count - len,
650			"\nD:  %2x > ",n);
651
652		for(i=0;i<16 && n<=max;i++,n++)
653		len += snprintf(page + len, count - len,
654			"%2x ",read_phy_cck(dev,n));
655
656		//	printk("%2x ",read_nic_byte(dev,n));
657	}
658	len += snprintf(page + len, count - len,"\n");
659
660
661	*eof = 1;
662	return len;
663}
664
665#endif
666
667#if 0
668static int proc_get_ofdm_reg(char *page, char **start,
669			  off_t offset, int count,
670			  int *eof, void *data)
671{
672	struct net_device *dev = data;
673//	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
674
675	int len = 0;
676	int i,n;
677
678	//int max=0xff;
679	int max = 0x40;
680
681	/* This dump the current register page */
682	for(n=0;n<=max;)
683	{
684		//printk( "\nD: %2x> ", n);
685		len += snprintf(page + len, count - len,
686			"\nD:  %2x > ",n);
687
688		for(i=0;i<16 && n<=max;i++,n++)
689		len += snprintf(page + len, count - len,
690			"%2x ",read_phy_ofdm(dev,n));
691
692		//	printk("%2x ",read_nic_byte(dev,n));
693	}
694	len += snprintf(page + len, count - len,"\n");
695
696
697
698	*eof = 1;
699	return len;
700}
701
702#endif
703
704#if 0
705static int proc_get_stats_hw(char *page, char **start,
706			  off_t offset, int count,
707			  int *eof, void *data)
708{
709	struct net_device *dev = data;
710	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
711
712	int len = 0;
713
714	len += snprintf(page + len, count - len,
715		"NIC int: %lu\n"
716		"Total int: %lu\n",
717		priv->stats.ints,
718		priv->stats.shints);
719
720	*eof = 1;
721	return len;
722}
723#endif
724
725static int proc_get_stats_tx(char *page, char **start,
726			  off_t offset, int count,
727			  int *eof, void *data)
728{
729	struct net_device *dev = data;
730	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
731
732	int len = 0;
733
734	len += snprintf(page + len, count - len,
735		"TX VI priority ok int: %lu\n"
736		"TX VI priority error int: %lu\n"
737		"TX VO priority ok int: %lu\n"
738		"TX VO priority error int: %lu\n"
739		"TX BE priority ok int: %lu\n"
740		"TX BE priority error int: %lu\n"
741		"TX BK priority ok int: %lu\n"
742		"TX BK priority error int: %lu\n"
743		"TX MANAGE priority ok int: %lu\n"
744		"TX MANAGE priority error int: %lu\n"
745		"TX BEACON priority ok int: %lu\n"
746		"TX BEACON priority error int: %lu\n"
747//		"TX high priority ok int: %lu\n"
748//		"TX high priority failed error int: %lu\n"
749		"TX queue resume: %lu\n"
750		"TX queue stopped?: %d\n"
751		"TX fifo overflow: %lu\n"
752//		"TX beacon: %lu\n"
753		"TX VI queue: %d\n"
754		"TX VO queue: %d\n"
755		"TX BE queue: %d\n"
756		"TX BK queue: %d\n"
757//		"TX HW queue: %d\n"
758		"TX VI dropped: %lu\n"
759		"TX VO dropped: %lu\n"
760		"TX BE dropped: %lu\n"
761		"TX BK dropped: %lu\n"
762		"TX total data packets %lu\n",
763//		"TX beacon aborted: %lu\n",
764		priv->stats.txviokint,
765		priv->stats.txvierr,
766		priv->stats.txvookint,
767		priv->stats.txvoerr,
768		priv->stats.txbeokint,
769		priv->stats.txbeerr,
770		priv->stats.txbkokint,
771		priv->stats.txbkerr,
772		priv->stats.txmanageokint,
773		priv->stats.txmanageerr,
774		priv->stats.txbeaconokint,
775		priv->stats.txbeaconerr,
776//		priv->stats.txhpokint,
777//		priv->stats.txhperr,
778		priv->stats.txresumed,
779		netif_queue_stopped(dev),
780		priv->stats.txoverflow,
781//		priv->stats.txbeacon,
782		atomic_read(&(priv->tx_pending[VI_PRIORITY])),
783		atomic_read(&(priv->tx_pending[VO_PRIORITY])),
784		atomic_read(&(priv->tx_pending[BE_PRIORITY])),
785		atomic_read(&(priv->tx_pending[BK_PRIORITY])),
786//		read_nic_byte(dev, TXFIFOCOUNT),
787		priv->stats.txvidrop,
788		priv->stats.txvodrop,
789		priv->stats.txbedrop,
790		priv->stats.txbkdrop,
791		priv->stats.txdatapkt
792//		priv->stats.txbeaconerr
793		);
794
795	*eof = 1;
796	return len;
797}
798
799
800
801static int proc_get_stats_rx(char *page, char **start,
802			  off_t offset, int count,
803			  int *eof, void *data)
804{
805	struct net_device *dev = data;
806	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
807
808	int len = 0;
809
810	len += snprintf(page + len, count - len,
811		"RX packets: %lu\n"
812		"RX urb status error: %lu\n"
813		"RX invalid urb error: %lu\n",
814		priv->stats.rxoktotal,
815		priv->stats.rxstaterr,
816		priv->stats.rxurberr);
817
818	*eof = 1;
819	return len;
820}
821#if 0
822#if WIRELESS_EXT >= 12 && WIRELESS_EXT < 17
823
824static struct iw_statistics *r8192_get_wireless_stats(struct net_device *dev)
825{
826       struct r8192_priv *priv = ieee80211_priv(dev);
827
828       return &priv->wstats;
829}
830#endif
831#endif
832void rtl8192_proc_module_init(void)
833{
834	RT_TRACE(COMP_INIT, "Initializing proc filesystem");
835#if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24))
836	rtl8192_proc=create_proc_entry(RTL819xU_MODULE_NAME, S_IFDIR, proc_net);
837#else
838	rtl8192_proc=create_proc_entry(RTL819xU_MODULE_NAME, S_IFDIR, init_net.proc_net);
839#endif
840}
841
842
843void rtl8192_proc_module_remove(void)
844{
845#if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24))
846	remove_proc_entry(RTL819xU_MODULE_NAME, proc_net);
847#else
848	remove_proc_entry(RTL819xU_MODULE_NAME, init_net.proc_net);
849#endif
850}
851
852
853void rtl8192_proc_remove_one(struct net_device *dev)
854{
855	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
856
857
858	if (priv->dir_dev) {
859	//	remove_proc_entry("stats-hw", priv->dir_dev);
860		remove_proc_entry("stats-tx", priv->dir_dev);
861		remove_proc_entry("stats-rx", priv->dir_dev);
862	//	remove_proc_entry("stats-ieee", priv->dir_dev);
863		remove_proc_entry("stats-ap", priv->dir_dev);
864		remove_proc_entry("registers", priv->dir_dev);
865	//	remove_proc_entry("cck-registers",priv->dir_dev);
866	//	remove_proc_entry("ofdm-registers",priv->dir_dev);
867		//remove_proc_entry(dev->name, rtl8192_proc);
868		remove_proc_entry("wlan0", rtl8192_proc);
869		priv->dir_dev = NULL;
870	}
871}
872
873
874void rtl8192_proc_init_one(struct net_device *dev)
875{
876	struct proc_dir_entry *e;
877	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
878	priv->dir_dev = create_proc_entry(dev->name,
879					  S_IFDIR | S_IRUGO | S_IXUGO,
880					  rtl8192_proc);
881	if (!priv->dir_dev) {
882		RT_TRACE(COMP_ERR, "Unable to initialize /proc/net/rtl8192/%s\n",
883		      dev->name);
884		return;
885	}
886	#if 0
887	e = create_proc_read_entry("stats-hw", S_IFREG | S_IRUGO,
888				   priv->dir_dev, proc_get_stats_hw, dev);
889
890	if (!e) {
891		DMESGE("Unable to initialize "
892		      "/proc/net/rtl8192/%s/stats-hw\n",
893		      dev->name);
894	}
895	#endif
896	e = create_proc_read_entry("stats-rx", S_IFREG | S_IRUGO,
897				   priv->dir_dev, proc_get_stats_rx, dev);
898
899	if (!e) {
900		RT_TRACE(COMP_ERR,"Unable to initialize "
901		      "/proc/net/rtl8192/%s/stats-rx\n",
902		      dev->name);
903	}
904
905
906	e = create_proc_read_entry("stats-tx", S_IFREG | S_IRUGO,
907				   priv->dir_dev, proc_get_stats_tx, dev);
908
909	if (!e) {
910		RT_TRACE(COMP_ERR, "Unable to initialize "
911		      "/proc/net/rtl8192/%s/stats-tx\n",
912		      dev->name);
913	}
914	#if 0
915	e = create_proc_read_entry("stats-ieee", S_IFREG | S_IRUGO,
916				   priv->dir_dev, proc_get_stats_ieee, dev);
917
918	if (!e) {
919		DMESGE("Unable to initialize "
920		      "/proc/net/rtl8192/%s/stats-ieee\n",
921		      dev->name);
922	}
923
924	#endif
925
926	e = create_proc_read_entry("stats-ap", S_IFREG | S_IRUGO,
927				   priv->dir_dev, proc_get_stats_ap, dev);
928
929	if (!e) {
930		RT_TRACE(COMP_ERR, "Unable to initialize "
931		      "/proc/net/rtl8192/%s/stats-ap\n",
932		      dev->name);
933	}
934
935	e = create_proc_read_entry("registers", S_IFREG | S_IRUGO,
936				   priv->dir_dev, proc_get_registers, dev);
937	if (!e) {
938		RT_TRACE(COMP_ERR, "Unable to initialize "
939		      "/proc/net/rtl8192/%s/registers\n",
940		      dev->name);
941	}
942#if 0
943	e = create_proc_read_entry("cck-registers", S_IFREG | S_IRUGO,
944				   priv->dir_dev, proc_get_cck_reg, dev);
945	if (!e) {
946		RT_TRACE(COMP_ERR, "Unable to initialize "
947		      "/proc/net/rtl8192/%s/cck-registers\n",
948		      dev->name);
949	}
950
951	e = create_proc_read_entry("ofdm-registers", S_IFREG | S_IRUGO,
952				   priv->dir_dev, proc_get_ofdm_reg, dev);
953	if (!e) {
954		RT_TRACE(COMP_ERR, "Unable to initialize "
955		      "/proc/net/rtl8192/%s/ofdm-registers\n",
956		      dev->name);
957	}
958#endif
959}
960/****************************************************************************
961   -----------------------------MISC STUFF-------------------------
962*****************************************************************************/
963
964/* this is only for debugging */
965void print_buffer(u32 *buffer, int len)
966{
967	int i;
968	u8 *buf =(u8*)buffer;
969
970	printk("ASCII BUFFER DUMP (len: %x):\n",len);
971
972	for(i=0;i<len;i++)
973		printk("%c",buf[i]);
974
975	printk("\nBINARY BUFFER DUMP (len: %x):\n",len);
976
977	for(i=0;i<len;i++)
978		printk("%x",buf[i]);
979
980	printk("\n");
981}
982
983//short check_nic_enough_desc(struct net_device *dev, priority_t priority)
984short check_nic_enough_desc(struct net_device *dev,int queue_index)
985{
986	struct r8192_priv *priv = ieee80211_priv(dev);
987	int used = atomic_read(&priv->tx_pending[queue_index]);
988
989	return (used < MAX_TX_URB);
990}
991
992void tx_timeout(struct net_device *dev)
993{
994	struct r8192_priv *priv = ieee80211_priv(dev);
995	//rtl8192_commit(dev);
996
997#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
998	schedule_work(&priv->reset_wq);
999#else
1000	schedule_task(&priv->reset_wq);
1001#endif
1002	//DMESG("TXTIMEOUT");
1003}
1004
1005
1006/* this is only for debug */
1007void dump_eprom(struct net_device *dev)
1008{
1009	int i;
1010	for(i=0; i<63; i++)
1011		RT_TRACE(COMP_EPROM, "EEPROM addr %x : %x", i, eprom_read(dev,i));
1012}
1013
1014/* this is only for debug */
1015void rtl8192_dump_reg(struct net_device *dev)
1016{
1017	int i;
1018	int n;
1019	int max=0x1ff;
1020
1021	RT_TRACE(COMP_PHY, "Dumping NIC register map");
1022
1023	for(n=0;n<=max;)
1024	{
1025		printk( "\nD: %2x> ", n);
1026		for(i=0;i<16 && n<=max;i++,n++)
1027			printk("%2x ",read_nic_byte(dev,n));
1028	}
1029	printk("\n");
1030}
1031
1032/****************************************************************************
1033      ------------------------------HW STUFF---------------------------
1034*****************************************************************************/
1035
1036#if 0
1037void rtl8192_irq_enable(struct net_device *dev)
1038{
1039	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1040	//priv->irq_enabled = 1;
1041/*
1042	write_nic_word(dev,INTA_MASK,INTA_RXOK | INTA_RXDESCERR | INTA_RXOVERFLOW |\
1043	INTA_TXOVERFLOW | INTA_HIPRIORITYDESCERR | INTA_HIPRIORITYDESCOK |\
1044	INTA_NORMPRIORITYDESCERR | INTA_NORMPRIORITYDESCOK |\
1045	INTA_LOWPRIORITYDESCERR | INTA_LOWPRIORITYDESCOK | INTA_TIMEOUT);
1046*/
1047	write_nic_word(dev,INTA_MASK, priv->irq_mask);
1048}
1049
1050
1051void rtl8192_irq_disable(struct net_device *dev)
1052{
1053//	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1054
1055	write_nic_word(dev,INTA_MASK,0);
1056	force_pci_posting(dev);
1057//	priv->irq_enabled = 0;
1058}
1059#endif
1060
1061void rtl8192_set_mode(struct net_device *dev,int mode)
1062{
1063	u8 ecmd;
1064	ecmd=read_nic_byte(dev, EPROM_CMD);
1065	ecmd=ecmd &~ EPROM_CMD_OPERATING_MODE_MASK;
1066	ecmd=ecmd | (mode<<EPROM_CMD_OPERATING_MODE_SHIFT);
1067	ecmd=ecmd &~ (1<<EPROM_CS_SHIFT);
1068	ecmd=ecmd &~ (1<<EPROM_CK_SHIFT);
1069	write_nic_byte(dev, EPROM_CMD, ecmd);
1070}
1071
1072
1073void rtl8192_update_msr(struct net_device *dev)
1074{
1075	struct r8192_priv *priv = ieee80211_priv(dev);
1076	u8 msr;
1077
1078	msr  = read_nic_byte(dev, MSR);
1079	msr &= ~ MSR_LINK_MASK;
1080
1081	/* do not change in link_state != WLAN_LINK_ASSOCIATED.
1082	 * msr must be updated if the state is ASSOCIATING.
1083	 * this is intentional and make sense for ad-hoc and
1084	 * master (see the create BSS/IBSS func)
1085	 */
1086	if (priv->ieee80211->state == IEEE80211_LINKED){
1087
1088		if (priv->ieee80211->iw_mode == IW_MODE_INFRA)
1089			msr |= (MSR_LINK_MANAGED<<MSR_LINK_SHIFT);
1090		else if (priv->ieee80211->iw_mode == IW_MODE_ADHOC)
1091			msr |= (MSR_LINK_ADHOC<<MSR_LINK_SHIFT);
1092		else if (priv->ieee80211->iw_mode == IW_MODE_MASTER)
1093			msr |= (MSR_LINK_MASTER<<MSR_LINK_SHIFT);
1094
1095	}else
1096		msr |= (MSR_LINK_NONE<<MSR_LINK_SHIFT);
1097
1098	write_nic_byte(dev, MSR, msr);
1099}
1100
1101void rtl8192_set_chan(struct net_device *dev,short ch)
1102{
1103	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1104//	u32 tx;
1105	RT_TRACE(COMP_CH, "=====>%s()====ch:%d\n", __FUNCTION__, ch);
1106	priv->chan=ch;
1107	#if 0
1108	if(priv->ieee80211->iw_mode == IW_MODE_ADHOC ||
1109		priv->ieee80211->iw_mode == IW_MODE_MASTER){
1110
1111			priv->ieee80211->link_state = WLAN_LINK_ASSOCIATED;
1112			priv->ieee80211->master_chan = ch;
1113			rtl8192_update_beacon_ch(dev);
1114		}
1115	#endif
1116
1117	/* this hack should avoid frame TX during channel setting*/
1118
1119
1120//	tx = read_nic_dword(dev,TX_CONF);
1121//	tx &= ~TX_LOOPBACK_MASK;
1122
1123#ifndef LOOP_TEST
1124//	write_nic_dword(dev,TX_CONF, tx |( TX_LOOPBACK_MAC<<TX_LOOPBACK_SHIFT));
1125
1126	//need to implement rf set channel here WB
1127
1128	if (priv->rf_set_chan)
1129	priv->rf_set_chan(dev,priv->chan);
1130	mdelay(10);
1131//	write_nic_dword(dev,TX_CONF,tx | (TX_LOOPBACK_NONE<<TX_LOOPBACK_SHIFT));
1132#endif
1133}
1134
1135#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
1136static void rtl8192_rx_isr(struct urb *urb, struct pt_regs *regs);
1137#else
1138static void rtl8192_rx_isr(struct urb *urb);
1139#endif
1140//static void rtl8192_rx_isr(struct urb *rx_urb);
1141
1142u32 get_rxpacket_shiftbytes_819xusb(struct ieee80211_rx_stats *pstats)
1143{
1144
1145#ifdef USB_RX_AGGREGATION_SUPPORT
1146	if (pstats->bisrxaggrsubframe)
1147		return (sizeof(rx_desc_819x_usb) + pstats->RxDrvInfoSize
1148			+ pstats->RxBufShift + 8);
1149	else
1150#endif
1151		return (sizeof(rx_desc_819x_usb) + pstats->RxDrvInfoSize
1152				+ pstats->RxBufShift);
1153
1154}
1155static int rtl8192_rx_initiate(struct net_device*dev)
1156{
1157        struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1158        struct urb *entry;
1159        struct sk_buff *skb;
1160        struct rtl8192_rx_info *info;
1161
1162	/* nomal packet rx procedure */
1163        while (skb_queue_len(&priv->rx_queue) < MAX_RX_URB) {
1164                skb = __dev_alloc_skb(RX_URB_SIZE, GFP_KERNEL);
1165                if (!skb)
1166                        break;
1167#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
1168	        entry = usb_alloc_urb(0, GFP_KERNEL);
1169#else
1170	        entry = usb_alloc_urb(0);
1171#endif
1172                if (!entry) {
1173                        kfree_skb(skb);
1174                        break;
1175                }
1176//		printk("nomal packet IN request!\n");
1177                usb_fill_bulk_urb(entry, priv->udev,
1178                                  usb_rcvbulkpipe(priv->udev, 3), skb_tail_pointer(skb),
1179                                  RX_URB_SIZE, rtl8192_rx_isr, skb);
1180                info = (struct rtl8192_rx_info *) skb->cb;
1181                info->urb = entry;
1182                info->dev = dev;
1183		info->out_pipe = 3; //denote rx normal packet queue
1184                skb_queue_tail(&priv->rx_queue, skb);
1185                usb_submit_urb(entry, GFP_KERNEL);
1186        }
1187
1188	/* command packet rx procedure */
1189        while (skb_queue_len(&priv->rx_queue) < MAX_RX_URB + 3) {
1190//		printk("command packet IN request!\n");
1191                skb = __dev_alloc_skb(RX_URB_SIZE ,GFP_KERNEL);
1192                if (!skb)
1193                        break;
1194#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
1195                entry = usb_alloc_urb(0, GFP_KERNEL);
1196#else
1197                entry = usb_alloc_urb(0);
1198#endif
1199                if (!entry) {
1200                        kfree_skb(skb);
1201                        break;
1202                }
1203                usb_fill_bulk_urb(entry, priv->udev,
1204                                  usb_rcvbulkpipe(priv->udev, 9), skb_tail_pointer(skb),
1205                                  RX_URB_SIZE, rtl8192_rx_isr, skb);
1206                info = (struct rtl8192_rx_info *) skb->cb;
1207                info->urb = entry;
1208                info->dev = dev;
1209		   info->out_pipe = 9; //denote rx cmd packet queue
1210                skb_queue_tail(&priv->rx_queue, skb);
1211		usb_submit_urb(entry, GFP_KERNEL);
1212        }
1213
1214        return 0;
1215}
1216
1217void rtl8192_set_rxconf(struct net_device *dev)
1218{
1219	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1220	u32 rxconf;
1221
1222	rxconf=read_nic_dword(dev,RCR);
1223	rxconf = rxconf &~ MAC_FILTER_MASK;
1224	rxconf = rxconf | RCR_AMF;
1225	rxconf = rxconf | RCR_ADF;
1226	rxconf = rxconf | RCR_AB;
1227	rxconf = rxconf | RCR_AM;
1228	//rxconf = rxconf | RCR_ACF;
1229
1230	if (dev->flags & IFF_PROMISC) {DMESG ("NIC in promisc mode");}
1231
1232	if(priv->ieee80211->iw_mode == IW_MODE_MONITOR || \
1233	   dev->flags & IFF_PROMISC){
1234		rxconf = rxconf | RCR_AAP;
1235	} /*else if(priv->ieee80211->iw_mode == IW_MODE_MASTER){
1236		rxconf = rxconf | (1<<ACCEPT_ALLMAC_FRAME_SHIFT);
1237		rxconf = rxconf | (1<<RX_CHECK_BSSID_SHIFT);
1238	}*/else{
1239		rxconf = rxconf | RCR_APM;
1240		rxconf = rxconf | RCR_CBSSID;
1241	}
1242
1243
1244	if(priv->ieee80211->iw_mode == IW_MODE_MONITOR){
1245		rxconf = rxconf | RCR_AICV;
1246		rxconf = rxconf | RCR_APWRMGT;
1247	}
1248
1249	if( priv->crcmon == 1 && priv->ieee80211->iw_mode == IW_MODE_MONITOR)
1250		rxconf = rxconf | RCR_ACRC32;
1251
1252
1253	rxconf = rxconf &~ RX_FIFO_THRESHOLD_MASK;
1254	rxconf = rxconf | (RX_FIFO_THRESHOLD_NONE<<RX_FIFO_THRESHOLD_SHIFT);
1255	rxconf = rxconf &~ MAX_RX_DMA_MASK;
1256	rxconf = rxconf | ((u32)7<<RCR_MXDMA_OFFSET);
1257
1258//	rxconf = rxconf | (1<<RX_AUTORESETPHY_SHIFT);
1259	rxconf = rxconf | RCR_ONLYERLPKT;
1260
1261//	rxconf = rxconf &~ RCR_CS_MASK;
1262//	rxconf = rxconf | (1<<RCR_CS_SHIFT);
1263
1264	write_nic_dword(dev, RCR, rxconf);
1265
1266	#ifdef DEBUG_RX
1267	DMESG("rxconf: %x %x",rxconf ,read_nic_dword(dev,RCR));
1268	#endif
1269}
1270//wait to be removed
1271void rtl8192_rx_enable(struct net_device *dev)
1272{
1273	//u8 cmd;
1274
1275	//struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1276
1277	rtl8192_rx_initiate(dev);
1278
1279//	rtl8192_set_rxconf(dev);
1280#if 0
1281	if(NIC_8187 == priv->card_8187) {
1282		cmd=read_nic_byte(dev,CMD);
1283		write_nic_byte(dev,CMD,cmd | (1<<CMD_RX_ENABLE_SHIFT));
1284	}
1285	else {
1286		//write_nic_dword(dev, RX_CONF, priv->ReceiveConfig);
1287	}
1288#endif
1289}
1290
1291
1292void rtl8192_tx_enable(struct net_device *dev)
1293{
1294#if 0
1295	u8 cmd;
1296	u8 byte;
1297	u32 txconf;
1298	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1299	//test loopback
1300	//	priv->TransmitConfig |= (TX_LOOPBACK_BASEBAND<<TX_LOOPBACK_SHIFT);
1301	if(NIC_8187B == priv->card_8187){
1302		write_nic_dword(dev, TX_CONF, priv->TransmitConfig);
1303		byte = read_nic_byte(dev, MSR);
1304		byte |= MSR_LINK_ENEDCA;
1305		write_nic_byte(dev, MSR, byte);
1306	} else {
1307		byte = read_nic_byte(dev,CW_CONF);
1308		byte &= ~(1<<CW_CONF_PERPACKET_CW_SHIFT);
1309		byte &= ~(1<<CW_CONF_PERPACKET_RETRY_SHIFT);
1310		write_nic_byte(dev, CW_CONF, byte);
1311
1312		byte = read_nic_byte(dev, TX_AGC_CTL);
1313		byte &= ~(1<<TX_AGC_CTL_PERPACKET_GAIN_SHIFT);
1314		byte &= ~(1<<TX_AGC_CTL_PERPACKET_ANTSEL_SHIFT);
1315		byte &= ~(1<<TX_AGC_CTL_FEEDBACK_ANT);
1316		write_nic_byte(dev, TX_AGC_CTL, byte);
1317
1318		txconf= read_nic_dword(dev,TX_CONF);
1319
1320
1321		txconf = txconf &~ TX_LOOPBACK_MASK;
1322
1323#ifndef LOOP_TEST
1324		txconf = txconf | (TX_LOOPBACK_NONE<<TX_LOOPBACK_SHIFT);
1325#else
1326		txconf = txconf | (TX_LOOPBACK_BASEBAND<<TX_LOOPBACK_SHIFT);
1327#endif
1328		txconf = txconf &~ TCR_SRL_MASK;
1329		txconf = txconf &~ TCR_LRL_MASK;
1330
1331		txconf = txconf | (priv->retry_data<<TX_LRLRETRY_SHIFT); // long
1332		txconf = txconf | (priv->retry_rts<<TX_SRLRETRY_SHIFT); // short
1333
1334		txconf = txconf &~ (1<<TX_NOCRC_SHIFT);
1335
1336		txconf = txconf &~ TCR_MXDMA_MASK;
1337		txconf = txconf | (TCR_MXDMA_2048<<TCR_MXDMA_SHIFT);
1338
1339		txconf = txconf | TCR_DISReqQsize;
1340		txconf = txconf | TCR_DISCW;
1341		txconf = txconf &~ TCR_SWPLCPLEN;
1342
1343		txconf=txconf | (1<<TX_NOICV_SHIFT);
1344
1345		write_nic_dword(dev,TX_CONF,txconf);
1346
1347#ifdef DEBUG_TX
1348		DMESG("txconf: %x %x",txconf,read_nic_dword(dev,TX_CONF));
1349#endif
1350
1351		cmd=read_nic_byte(dev,CMD);
1352		write_nic_byte(dev,CMD,cmd | (1<<CMD_TX_ENABLE_SHIFT));
1353	}
1354#endif
1355}
1356
1357#if 0
1358void rtl8192_beacon_tx_enable(struct net_device *dev)
1359{
1360	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1361	priv->dma_poll_mask &=~(1<<TX_DMA_STOP_BEACON_SHIFT);
1362	rtl8192_set_mode(dev,EPROM_CMD_CONFIG);
1363	write_nic_byte(dev,TX_DMA_POLLING,priv->dma_poll_mask);
1364	rtl8192_set_mode(dev,EPROM_CMD_NORMAL);
1365}
1366
1367
1368void rtl8192_
1369_disable(struct net_device *dev)
1370{
1371	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1372	priv->dma_poll_mask |= (1<<TX_DMA_STOP_BEACON_SHIFT);
1373	rtl8192_set_mode(dev,EPROM_CMD_CONFIG);
1374	write_nic_byte(dev,TX_DMA_POLLING,priv->dma_poll_mask);
1375	rtl8192_set_mode(dev,EPROM_CMD_NORMAL);
1376}
1377
1378#endif
1379
1380
1381void rtl8192_rtx_disable(struct net_device *dev)
1382{
1383	u8 cmd;
1384	struct r8192_priv *priv = ieee80211_priv(dev);
1385	struct sk_buff *skb;
1386	struct rtl8192_rx_info *info;
1387
1388	cmd=read_nic_byte(dev,CMDR);
1389	write_nic_byte(dev, CMDR, cmd &~ \
1390		(CR_TE|CR_RE));
1391	force_pci_posting(dev);
1392	mdelay(10);
1393
1394	while ((skb = __skb_dequeue(&priv->rx_queue))) {
1395		info = (struct rtl8192_rx_info *) skb->cb;
1396		if (!info->urb)
1397			continue;
1398
1399		usb_kill_urb(info->urb);
1400		kfree_skb(skb);
1401	}
1402
1403	if (skb_queue_len(&priv->skb_queue)) {
1404		printk(KERN_WARNING "skb_queue not empty\n");
1405	}
1406
1407	skb_queue_purge(&priv->skb_queue);
1408	return;
1409}
1410
1411
1412int alloc_tx_beacon_desc_ring(struct net_device *dev, int count)
1413{
1414	#if 0
1415	int i;
1416	u32 *tmp;
1417	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1418
1419	priv->txbeaconring = (u32*)pci_alloc_consistent(priv->pdev,
1420					  sizeof(u32)*8*count,
1421					  &priv->txbeaconringdma);
1422	if (!priv->txbeaconring) return -1;
1423	for (tmp=priv->txbeaconring,i=0;i<count;i++){
1424		*tmp = *tmp &~ (1<<31); // descriptor empty, owned by the drv
1425		/*
1426		*(tmp+2) = (u32)dma_tmp;
1427		*(tmp+3) = bufsize;
1428		*/
1429		if(i+1<count)
1430			*(tmp+4) = (u32)priv->txbeaconringdma+((i+1)*8*4);
1431		else
1432			*(tmp+4) = (u32)priv->txbeaconringdma;
1433
1434		tmp=tmp+8;
1435	}
1436	#endif
1437	return 0;
1438}
1439
1440#if 0
1441void rtl8192_reset(struct net_device *dev)
1442{
1443
1444	//struct r8192_priv *priv = ieee80211_priv(dev);
1445	//u8 cr;
1446
1447
1448	/* make sure the analog power is on before
1449	 * reset, otherwise reset may fail
1450	 */
1451#if 0
1452	if(NIC_8187 == priv->card_8187) {
1453		rtl8192_set_anaparam(dev, RTL8225_ANAPARAM_ON);
1454		rtl8185_set_anaparam2(dev, RTL8225_ANAPARAM2_ON);
1455		rtl8192_irq_disable(dev);
1456		mdelay(200);
1457		write_nic_byte_E(dev,0x18,0x10);
1458		write_nic_byte_E(dev,0x18,0x11);
1459		write_nic_byte_E(dev,0x18,0x00);
1460		mdelay(200);
1461	}
1462#endif
1463	printk("=====>reset?\n");
1464#if 0
1465	cr=read_nic_byte(dev,CMD);
1466	cr = cr & 2;
1467	cr = cr | (1<<CMD_RST_SHIFT);
1468	write_nic_byte(dev,CMD,cr);
1469
1470	force_pci_posting(dev);
1471
1472	mdelay(200);
1473
1474	if(read_nic_byte(dev,CMD) & (1<<CMD_RST_SHIFT))
1475		RT_TRACE(COMP_ERR, "Card reset timeout!\n");
1476	else
1477		RT_TRACE(COMP_DOWN, "Card successfully reset\n");
1478#endif
1479#if 0
1480	if(NIC_8187 == priv->card_8187) {
1481
1482		printk("This is RTL8187 Reset procedure\n");
1483		rtl8192_set_mode(dev,EPROM_CMD_LOAD);
1484		force_pci_posting(dev);
1485		mdelay(200);
1486
1487		/* after the eeprom load cycle, make sure we have
1488		 * correct anaparams
1489		 */
1490		rtl8192_set_anaparam(dev, RTL8225_ANAPARAM_ON);
1491		rtl8185_set_anaparam2(dev, RTL8225_ANAPARAM2_ON);
1492	}
1493	else
1494#endif
1495		printk("This is RTL8187B Reset procedure\n");
1496
1497}
1498#endif
1499inline u16 ieeerate2rtlrate(int rate)
1500{
1501	switch(rate){
1502	case 10:
1503	return 0;
1504	case 20:
1505	return 1;
1506	case 55:
1507	return 2;
1508	case 110:
1509	return 3;
1510	case 60:
1511	return 4;
1512	case 90:
1513	return 5;
1514	case 120:
1515	return 6;
1516	case 180:
1517	return 7;
1518	case 240:
1519	return 8;
1520	case 360:
1521	return 9;
1522	case 480:
1523	return 10;
1524	case 540:
1525	return 11;
1526	default:
1527	return 3;
1528
1529	}
1530}
1531static u16 rtl_rate[] = {10,20,55,110,60,90,120,180,240,360,480,540};
1532inline u16 rtl8192_rate2rate(short rate)
1533{
1534	if (rate >11) return 0;
1535	return rtl_rate[rate];
1536}
1537
1538
1539/* The protype of rx_isr has changed since one verion of Linux Kernel */
1540#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
1541static void rtl8192_rx_isr(struct urb *urb, struct pt_regs *regs)
1542#else
1543static void rtl8192_rx_isr(struct urb *urb)
1544#endif
1545{
1546        struct sk_buff *skb = (struct sk_buff *) urb->context;
1547        struct rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
1548        struct net_device *dev = info->dev;
1549	struct r8192_priv *priv = ieee80211_priv(dev);
1550	int out_pipe = info->out_pipe;
1551	int err;
1552	if(!priv->up)
1553		return;
1554        if (unlikely(urb->status)) {
1555                info->urb = NULL;
1556                priv->stats.rxstaterr++;
1557                priv->ieee80211->stats.rx_errors++;
1558                usb_free_urb(urb);
1559	//	printk("%s():rx status err\n",__FUNCTION__);
1560                return;
1561        }
1562#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,14)
1563        skb_unlink(skb, &priv->rx_queue);
1564#else
1565        __skb_unlink(skb,&priv->rx_queue);
1566#endif
1567        skb_put(skb, urb->actual_length);
1568
1569	skb_queue_tail(&priv->skb_queue, skb);
1570	tasklet_schedule(&priv->irq_rx_tasklet);
1571
1572        skb = dev_alloc_skb(RX_URB_SIZE);
1573        if (unlikely(!skb)) {
1574                usb_free_urb(urb);
1575		printk("%s():can,t alloc skb\n",__FUNCTION__);
1576                /* TODO check rx queue length and refill *somewhere* */
1577                return;
1578        }
1579
1580	usb_fill_bulk_urb(urb, priv->udev,
1581			usb_rcvbulkpipe(priv->udev, out_pipe), skb_tail_pointer(skb),
1582			RX_URB_SIZE, rtl8192_rx_isr, skb);
1583
1584        info = (struct rtl8192_rx_info *) skb->cb;
1585        info->urb = urb;
1586        info->dev = dev;
1587	info->out_pipe = out_pipe;
1588
1589        urb->transfer_buffer = skb_tail_pointer(skb);
1590        urb->context = skb;
1591        skb_queue_tail(&priv->rx_queue, skb);
1592        err = usb_submit_urb(urb, GFP_ATOMIC);
1593	if(err && err != EPERM)
1594		printk("can not submit rxurb, err is %x,URB status is %x\n",err,urb->status);
1595}
1596
1597u32
1598rtl819xusb_rx_command_packet(
1599	struct net_device *dev,
1600	struct ieee80211_rx_stats *pstats
1601	)
1602{
1603	u32	status;
1604
1605	//RT_TRACE(COMP_RECV, DBG_TRACE, ("---> RxCommandPacketHandle819xUsb()\n"));
1606
1607	status = cmpk_message_handle_rx(dev, pstats);
1608	if (status)
1609	{
1610		DMESG("rxcommandpackethandle819xusb: It is a command packet\n");
1611	}
1612	else
1613	{
1614		//RT_TRACE(COMP_RECV, DBG_TRACE, ("RxCommandPacketHandle819xUsb: It is not a command packet\n"));
1615	}
1616
1617	//RT_TRACE(COMP_RECV, DBG_TRACE, ("<--- RxCommandPacketHandle819xUsb()\n"));
1618	return status;
1619}
1620
1621#if 0
1622void rtl8192_tx_queues_stop(struct net_device *dev)
1623{
1624	//struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1625	u8 dma_poll_mask = (1<<TX_DMA_STOP_LOWPRIORITY_SHIFT);
1626	dma_poll_mask |= (1<<TX_DMA_STOP_HIPRIORITY_SHIFT);
1627	dma_poll_mask |= (1<<TX_DMA_STOP_NORMPRIORITY_SHIFT);
1628	dma_poll_mask |= (1<<TX_DMA_STOP_BEACON_SHIFT);
1629
1630	rtl8192_set_mode(dev,EPROM_CMD_CONFIG);
1631	write_nic_byte(dev,TX_DMA_POLLING,dma_poll_mask);
1632	rtl8192_set_mode(dev,EPROM_CMD_NORMAL);
1633}
1634#endif
1635
1636void rtl8192_data_hard_stop(struct net_device *dev)
1637{
1638	//FIXME !!
1639	#if 0
1640	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1641	priv->dma_poll_mask |= (1<<TX_DMA_STOP_LOWPRIORITY_SHIFT);
1642	rtl8192_set_mode(dev,EPROM_CMD_CONFIG);
1643	write_nic_byte(dev,TX_DMA_POLLING,priv->dma_poll_mask);
1644	rtl8192_set_mode(dev,EPROM_CMD_NORMAL);
1645	#endif
1646}
1647
1648
1649void rtl8192_data_hard_resume(struct net_device *dev)
1650{
1651	// FIXME !!
1652	#if 0
1653	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1654	priv->dma_poll_mask &= ~(1<<TX_DMA_STOP_LOWPRIORITY_SHIFT);
1655	rtl8192_set_mode(dev,EPROM_CMD_CONFIG);
1656	write_nic_byte(dev,TX_DMA_POLLING,priv->dma_poll_mask);
1657	rtl8192_set_mode(dev,EPROM_CMD_NORMAL);
1658	#endif
1659}
1660
1661/* this function TX data frames when the ieee80211 stack requires this.
1662 * It checks also if we need to stop the ieee tx queue, eventually do it
1663 */
1664void rtl8192_hard_data_xmit(struct sk_buff *skb, struct net_device *dev, int rate)
1665{
1666	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1667	int ret;
1668	unsigned long flags;
1669	cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1670	u8 queue_index = tcb_desc->queue_index;
1671
1672	/* shall not be referred by command packet */
1673	assert(queue_index != TXCMD_QUEUE);
1674
1675	spin_lock_irqsave(&priv->tx_lock,flags);
1676
1677        memcpy((unsigned char *)(skb->cb),&dev,sizeof(dev));
1678//	tcb_desc->RATRIndex = 7;
1679//	tcb_desc->bTxDisableRateFallBack = 1;
1680//	tcb_desc->bTxUseDriverAssingedRate = 1;
1681	tcb_desc->bTxEnableFwCalcDur = 1;
1682	skb_push(skb, priv->ieee80211->tx_headroom);
1683	ret = rtl8192_tx(dev, skb);
1684
1685	//priv->ieee80211->stats.tx_bytes+=(skb->len - priv->ieee80211->tx_headroom);
1686	//priv->ieee80211->stats.tx_packets++;
1687
1688	spin_unlock_irqrestore(&priv->tx_lock,flags);
1689
1690//	return ret;
1691	return;
1692}
1693
1694/* This is a rough attempt to TX a frame
1695 * This is called by the ieee 80211 stack to TX management frames.
1696 * If the ring is full packet are dropped (for data frame the queue
1697 * is stopped before this can happen).
1698 */
1699int rtl8192_hard_start_xmit(struct sk_buff *skb,struct net_device *dev)
1700{
1701	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1702	int ret;
1703	unsigned long flags;
1704        cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1705        u8 queue_index = tcb_desc->queue_index;
1706
1707
1708	spin_lock_irqsave(&priv->tx_lock,flags);
1709
1710        memcpy((unsigned char *)(skb->cb),&dev,sizeof(dev));
1711	if(queue_index == TXCMD_QUEUE) {
1712		skb_push(skb, USB_HWDESC_HEADER_LEN);
1713		rtl819xU_tx_cmd(dev, skb);
1714		ret = 1;
1715	        spin_unlock_irqrestore(&priv->tx_lock,flags);
1716		return ret;
1717	} else {
1718		skb_push(skb, priv->ieee80211->tx_headroom);
1719		ret = rtl8192_tx(dev, skb);
1720	}
1721
1722	spin_unlock_irqrestore(&priv->tx_lock,flags);
1723
1724	return ret;
1725}
1726
1727
1728void rtl8192_try_wake_queue(struct net_device *dev, int pri);
1729
1730#ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
1731u16 DrvAggr_PaddingAdd(struct net_device *dev, struct sk_buff *skb)
1732{
1733	u16     PaddingNum =  256 - ((skb->len + TX_PACKET_DRVAGGR_SUBFRAME_SHIFT_BYTES) % 256);
1734	return  (PaddingNum&0xff);
1735}
1736
1737u8 MRateToHwRate8190Pci(u8 rate);
1738u8 QueryIsShort(u8 TxHT, u8 TxRate, cb_desc *tcb_desc);
1739u8 MapHwQueueToFirmwareQueue(u8 QueueID);
1740struct sk_buff *DrvAggr_Aggregation(struct net_device *dev, struct ieee80211_drv_agg_txb *pSendList)
1741{
1742#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
1743	struct ieee80211_device *ieee = netdev_priv(dev);
1744#else
1745	struct ieee80211_device *ieee = (struct ieee80211_device *)dev->priv;
1746#endif
1747	struct r8192_priv *priv = ieee80211_priv(dev);
1748	cb_desc 	*tcb_desc = NULL;
1749	u8 		i;
1750	u32		TotalLength;
1751	struct sk_buff	*skb;
1752	struct sk_buff  *agg_skb;
1753	tx_desc_819x_usb_aggr_subframe *tx_agg_desc = NULL;
1754	tx_fwinfo_819x_usb	       *tx_fwinfo = NULL;
1755
1756	//
1757	// Local variable initialization.
1758	//
1759	/* first skb initialization */
1760	skb = pSendList->tx_agg_frames[0];
1761	TotalLength = skb->len;
1762
1763	/* Get the total aggregation length including the padding space and
1764	 * sub frame header.
1765	 */
1766	for(i = 1; i < pSendList->nr_drv_agg_frames; i++) {
1767		TotalLength += DrvAggr_PaddingAdd(dev, skb);
1768		skb = pSendList->tx_agg_frames[i];
1769		TotalLength += (skb->len + TX_PACKET_DRVAGGR_SUBFRAME_SHIFT_BYTES);
1770	}
1771
1772	/* allocate skb to contain the aggregated packets */
1773	agg_skb = dev_alloc_skb(TotalLength + ieee->tx_headroom);
1774	memset(agg_skb->data, 0, agg_skb->len);
1775	skb_reserve(agg_skb, ieee->tx_headroom);
1776
1777//	RT_DEBUG_DATA(COMP_SEND, skb->cb, sizeof(skb->cb));
1778	/* reserve info for first subframe Tx descriptor to be set in the tx function */
1779	skb = pSendList->tx_agg_frames[0];
1780	tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1781	tcb_desc->drv_agg_enable = 1;
1782	tcb_desc->pkt_size = skb->len;
1783 	tcb_desc->DrvAggrNum = pSendList->nr_drv_agg_frames;
1784	printk("DrvAggNum = %d\n", tcb_desc->DrvAggrNum);
1785//	RT_DEBUG_DATA(COMP_SEND, skb->cb, sizeof(skb->cb));
1786//	printk("========>skb->data ======> \n");
1787//	RT_DEBUG_DATA(COMP_SEND, skb->data, skb->len);
1788	memcpy(agg_skb->cb, skb->cb, sizeof(skb->cb));
1789	memcpy(skb_put(agg_skb,skb->len),skb->data,skb->len);
1790
1791	for(i = 1; i < pSendList->nr_drv_agg_frames; i++) {
1792		/* push the next sub frame to be 256 byte aline */
1793		skb_put(agg_skb,DrvAggr_PaddingAdd(dev,skb));
1794
1795		/* Subframe drv Tx descriptor and firmware info setting */
1796		skb = pSendList->tx_agg_frames[i];
1797		tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1798		tx_agg_desc = (tx_desc_819x_usb_aggr_subframe *)agg_skb->tail;
1799		tx_fwinfo = (tx_fwinfo_819x_usb *)(agg_skb->tail + sizeof(tx_desc_819x_usb_aggr_subframe));
1800
1801		memset(tx_fwinfo,0,sizeof(tx_fwinfo_819x_usb));
1802		/* DWORD 0 */
1803		tx_fwinfo->TxHT = (tcb_desc->data_rate&0x80)?1:0;
1804		tx_fwinfo->TxRate = MRateToHwRate8190Pci(tcb_desc->data_rate);
1805		tx_fwinfo->EnableCPUDur = tcb_desc->bTxEnableFwCalcDur;
1806		tx_fwinfo->Short = QueryIsShort(tx_fwinfo->TxHT, tx_fwinfo->TxRate, tcb_desc);
1807		if(tcb_desc->bAMPDUEnable) {//AMPDU enabled
1808			tx_fwinfo->AllowAggregation = 1;
1809			/* DWORD 1 */
1810			tx_fwinfo->RxMF = tcb_desc->ampdu_factor;
1811			tx_fwinfo->RxAMD = tcb_desc->ampdu_density&0x07;//ampdudensity
1812		} else {
1813			tx_fwinfo->AllowAggregation = 0;
1814			/* DWORD 1 */
1815			tx_fwinfo->RxMF = 0;
1816			tx_fwinfo->RxAMD = 0;
1817		}
1818
1819		/* Protection mode related */
1820		tx_fwinfo->RtsEnable = (tcb_desc->bRTSEnable)?1:0;
1821		tx_fwinfo->CtsEnable = (tcb_desc->bCTSEnable)?1:0;
1822		tx_fwinfo->RtsSTBC = (tcb_desc->bRTSSTBC)?1:0;
1823		tx_fwinfo->RtsHT = (tcb_desc->rts_rate&0x80)?1:0;
1824		tx_fwinfo->RtsRate =  MRateToHwRate8190Pci((u8)tcb_desc->rts_rate);
1825		tx_fwinfo->RtsSubcarrier = (tx_fwinfo->RtsHT==0)?(tcb_desc->RTSSC):0;
1826		tx_fwinfo->RtsBandwidth = (tx_fwinfo->RtsHT==1)?((tcb_desc->bRTSBW)?1:0):0;
1827		tx_fwinfo->RtsShort = (tx_fwinfo->RtsHT==0)?(tcb_desc->bRTSUseShortPreamble?1:0):\
1828				      (tcb_desc->bRTSUseShortGI?1:0);
1829
1830		/* Set Bandwidth and sub-channel settings. */
1831		if(priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20_40)
1832		{
1833			if(tcb_desc->bPacketBW) {
1834				tx_fwinfo->TxBandwidth = 1;
1835				tx_fwinfo->TxSubCarrier = 0;    //By SD3's Jerry suggestion, use duplicated mode
1836			} else {
1837				tx_fwinfo->TxBandwidth = 0;
1838				tx_fwinfo->TxSubCarrier = priv->nCur40MhzPrimeSC;
1839			}
1840		} else {
1841			tx_fwinfo->TxBandwidth = 0;
1842			tx_fwinfo->TxSubCarrier = 0;
1843		}
1844
1845		/* Fill Tx descriptor */
1846		memset(tx_agg_desc, 0, sizeof(tx_desc_819x_usb_aggr_subframe));
1847		/* DWORD 0 */
1848		//tx_agg_desc->LINIP = 0;
1849		//tx_agg_desc->CmdInit = 1;
1850		tx_agg_desc->Offset =  sizeof(tx_fwinfo_819x_usb) + 8;
1851		/* already raw data, need not to substract header length */
1852		tx_agg_desc->PktSize = skb->len & 0xffff;
1853
1854		/*DWORD 1*/
1855		tx_agg_desc->SecCAMID= 0;
1856		tx_agg_desc->RATid = tcb_desc->RATRIndex;
1857#if 0
1858		/* Fill security related */
1859		if( pTcb->bEncrypt && !Adapter->MgntInfo.SecurityInfo.SWTxEncryptFlag)
1860		{
1861			EncAlg = SecGetEncryptionOverhead(
1862					Adapter,
1863					&EncryptionMPDUHeadOverhead,
1864					&EncryptionMPDUTailOverhead,
1865					NULL,
1866					NULL,
1867					FALSE,
1868					FALSE);
1869			//2004/07/22, kcwu, EncryptionMPDUHeadOverhead has been added in previous code
1870			//MPDUOverhead = EncryptionMPDUHeadOverhead + EncryptionMPDUTailOverhead;
1871			MPDUOverhead = EncryptionMPDUTailOverhead;
1872			tx_agg_desc->NoEnc = 0;
1873			RT_TRACE(COMP_SEC, DBG_LOUD, ("******We in the loop SecCAMID is %d SecDescAssign is %d The Sec is %d********\n",tx_agg_desc->SecCAMID,tx_agg_desc->SecDescAssign,EncAlg));
1874			//CamDumpAll(Adapter);
1875		}
1876		else
1877#endif
1878		{
1879			//MPDUOverhead = 0;
1880			tx_agg_desc->NoEnc = 1;
1881		}
1882#if 0
1883		switch(EncAlg){
1884			case NO_Encryption:
1885				tx_agg_desc->SecType = 0x0;
1886				break;
1887			case WEP40_Encryption:
1888			case WEP104_Encryption:
1889				tx_agg_desc->SecType = 0x1;
1890				break;
1891			case TKIP_Encryption:
1892				tx_agg_desc->SecType = 0x2;
1893				break;
1894			case AESCCMP_Encryption:
1895				tx_agg_desc->SecType = 0x3;
1896				break;
1897			default:
1898				tx_agg_desc->SecType = 0x0;
1899				break;
1900		}
1901#else
1902		tx_agg_desc->SecType = 0x0;
1903#endif
1904
1905		if (tcb_desc->bHwSec) {
1906			switch (priv->ieee80211->pairwise_key_type)
1907			{
1908				case KEY_TYPE_WEP40:
1909				case KEY_TYPE_WEP104:
1910					tx_agg_desc->SecType = 0x1;
1911					tx_agg_desc->NoEnc = 0;
1912					break;
1913				case KEY_TYPE_TKIP:
1914					tx_agg_desc->SecType = 0x2;
1915					tx_agg_desc->NoEnc = 0;
1916					break;
1917				case KEY_TYPE_CCMP:
1918					tx_agg_desc->SecType = 0x3;
1919					tx_agg_desc->NoEnc = 0;
1920					break;
1921				case KEY_TYPE_NA:
1922					tx_agg_desc->SecType = 0x0;
1923					tx_agg_desc->NoEnc = 1;
1924					break;
1925			}
1926		}
1927
1928		tx_agg_desc->QueueSelect = MapHwQueueToFirmwareQueue(tcb_desc->queue_index);
1929		tx_agg_desc->TxFWInfoSize =  sizeof(tx_fwinfo_819x_usb);
1930
1931		tx_agg_desc->DISFB = tcb_desc->bTxDisableRateFallBack;
1932		tx_agg_desc->USERATE = tcb_desc->bTxUseDriverAssingedRate;
1933
1934		tx_agg_desc->OWN = 1;
1935
1936		//DWORD 2
1937		/* According windows driver, it seems that there no need to fill this field */
1938		//tx_agg_desc->TxBufferSize= (u32)(skb->len - USB_HWDESC_HEADER_LEN);
1939
1940		/* to fill next packet */
1941		skb_put(agg_skb,TX_PACKET_DRVAGGR_SUBFRAME_SHIFT_BYTES);
1942		memcpy(skb_put(agg_skb,skb->len),skb->data,skb->len);
1943	}
1944
1945	for(i = 0; i < pSendList->nr_drv_agg_frames; i++) {
1946		dev_kfree_skb_any(pSendList->tx_agg_frames[i]);
1947	}
1948
1949	return agg_skb;
1950}
1951
1952/* NOTE:
1953	This function return a list of PTCB which is proper to be aggregate with the input TCB.
1954	If no proper TCB is found to do aggregation, SendList will only contain the input TCB.
1955*/
1956u8 DrvAggr_GetAggregatibleList(struct net_device *dev, struct sk_buff *skb,
1957		struct ieee80211_drv_agg_txb *pSendList)
1958{
1959#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
1960	struct ieee80211_device *ieee = netdev_priv(dev);
1961#else
1962	struct ieee80211_device *ieee = (struct ieee80211_device *)dev->priv;
1963#endif
1964	PRT_HIGH_THROUGHPUT	pHTInfo = ieee->pHTInfo;
1965	u16		nMaxAggrNum = pHTInfo->UsbTxAggrNum;
1966	cb_desc 	*tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1967	u8		QueueID = tcb_desc->queue_index;
1968
1969	do {
1970		pSendList->tx_agg_frames[pSendList->nr_drv_agg_frames++] = skb;
1971		if(pSendList->nr_drv_agg_frames >= nMaxAggrNum) {
1972			break;
1973		}
1974
1975	} while((skb = skb_dequeue(&ieee->skb_drv_aggQ[QueueID])));
1976
1977	RT_TRACE(COMP_AMSDU, "DrvAggr_GetAggregatibleList, nAggrTcbNum = %d \n", pSendList->nr_drv_agg_frames);
1978	return pSendList->nr_drv_agg_frames;
1979}
1980#endif
1981
1982#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
1983static void rtl8192_tx_isr(struct urb *tx_urb, struct pt_regs *reg)
1984#else
1985static void rtl8192_tx_isr(struct urb *tx_urb)
1986#endif
1987{
1988	struct sk_buff *skb = (struct sk_buff*)tx_urb->context;
1989	struct net_device *dev = NULL;
1990	struct r8192_priv *priv = NULL;
1991	cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1992	u8  queue_index = tcb_desc->queue_index;
1993//	bool bToSend0Byte;
1994//	u16 BufLen = skb->len;
1995
1996	memcpy(&dev,(struct net_device*)(skb->cb),sizeof(struct net_device*));
1997	priv = ieee80211_priv(dev);
1998
1999	if(tcb_desc->queue_index != TXCMD_QUEUE) {
2000		if(tx_urb->status == 0) {
2001			dev->trans_start = jiffies;
2002			// As act as station mode, destion shall be  unicast address.
2003			//priv->ieee80211->stats.tx_bytes+=(skb->len - priv->ieee80211->tx_headroom);
2004			//priv->ieee80211->stats.tx_packets++;
2005			priv->stats.txoktotal++;
2006			priv->ieee80211->LinkDetectInfo.NumTxOkInPeriod++;
2007			priv->stats.txbytesunicast += (skb->len - priv->ieee80211->tx_headroom);
2008		} else {
2009			priv->ieee80211->stats.tx_errors++;
2010			//priv->stats.txmanageerr++;
2011			/* TODO */
2012		}
2013	}
2014
2015	/* free skb and tx_urb */
2016	if(skb != NULL) {
2017		dev_kfree_skb_any(skb);
2018		usb_free_urb(tx_urb);
2019		atomic_dec(&priv->tx_pending[queue_index]);
2020	}
2021
2022#if 0  //we need to send zero byte packet just after 512 byte(64 byte)packet is transmitted, or we will halt. It will greatly reduced available page in FW, and ruin our throughput. WB 2008.08.27
2023	if(BufLen > 0 && ((BufLen % 512 == 0)||(BufLen % 64 == 0))) {
2024		bToSend0Byte = true;
2025	}
2026
2027	bToSend0Byte = false;
2028	//
2029	// Note that, we at most handle 1 MPDU to send here, either
2030	// fragment or MPDU in wait queue.
2031	//
2032	if(!bToSend0Byte)
2033#endif
2034	{
2035		//
2036		// Handle HW Beacon:
2037		// We had transfer our beacon frame to host controler at this moment.
2038		//
2039#if 0
2040		if(tcb_desc->tx_queue == BEACON_QUEUE)
2041		{
2042			priv->bSendingBeacon = FALSE;
2043		}
2044#endif
2045		//
2046		// Caution:
2047		// Handling the wait queue of command packets.
2048		// For Tx command packets, we must not do TCB fragment because it is not handled right now.
2049		// We must cut the packets to match the size of TX_CMD_PKT before we send it.
2050		//
2051
2052		/* Handle MPDU in wait queue. */
2053		if(queue_index != BEACON_QUEUE) {
2054			/* Don't send data frame during scanning.*/
2055			if((skb_queue_len(&priv->ieee80211->skb_waitQ[queue_index]) != 0)&&\
2056					(!(priv->ieee80211->queue_stop))) {
2057				if(NULL != (skb = skb_dequeue(&(priv->ieee80211->skb_waitQ[queue_index]))))
2058					priv->ieee80211->softmac_hard_start_xmit(skb, dev);
2059
2060				return; //modified by david to avoid further processing AMSDU
2061			}
2062#ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
2063			else if ((skb_queue_len(&priv->ieee80211->skb_drv_aggQ[queue_index])!= 0)&&\
2064 				(!(priv->ieee80211->queue_stop))) {
2065				// Tx Driver Aggregation process
2066				/* The driver will aggregation the packets according to the following stets
2067				 * 1. check whether there's tx irq available, for it's a completion return
2068				 *    function, it should contain enough tx irq;
2069				 * 2. check pakcet type;
2070				 * 3. intialize sendlist, check whether the to-be send packet no greater than 1
2071				 * 4. aggregation the packets, and fill firmware info and tx desc to it, etc.
2072				 * 5. check whehter the packet could be sent, otherwise just insert to wait head
2073				 * */
2074				skb = skb_dequeue(&priv->ieee80211->skb_drv_aggQ[queue_index]);
2075				if(!check_nic_enough_desc(dev, queue_index)) {
2076					skb_queue_head(&(priv->ieee80211->skb_drv_aggQ[queue_index]), skb);
2077					return;
2078				}
2079
2080				{
2081					/*TODO*/
2082					/*
2083					u8* pHeader = skb->data;
2084
2085					if(IsMgntQosData(pHeader) ||
2086				            IsMgntQData_Ack(pHeader) ||
2087					    IsMgntQData_Poll(pHeader) ||
2088					    IsMgntQData_Poll_Ack(pHeader)
2089					  )
2090					*/
2091					{
2092						struct ieee80211_drv_agg_txb SendList;
2093
2094						memset(&SendList, 0, sizeof(struct ieee80211_drv_agg_txb));
2095						if(DrvAggr_GetAggregatibleList(dev, skb, &SendList) > 1) {
2096							skb = DrvAggr_Aggregation(dev, &SendList);
2097
2098#if 0
2099						printk("=============>to send aggregated packet!\n");
2100						RT_DEBUG_DATA(COMP_SEND, skb->cb, sizeof(skb->cb));
2101						printk("\n=================skb->len = %d\n", skb->len);
2102						RT_DEBUG_DATA(COMP_SEND, skb->data, skb->len);
2103#endif
2104						}
2105					}
2106					priv->ieee80211->softmac_hard_start_xmit(skb, dev);
2107				}
2108			}
2109#endif
2110		}
2111	}
2112
2113#if 0
2114	else
2115	{
2116		RT_TRACE( COMP_SEND,"HalUsbOutComplete(%d): bToSend0Byte.\n", PipeIndex);
2117
2118		//
2119		// In this case, we don't return skb now.
2120		// It will be returned when the 0-byte request completed.
2121		//
2122
2123		//
2124		// Bulk out an 0-byte padding transfer.
2125		//
2126		HalUsbOut0Byte(pAdapter, PipeIndex, skb);
2127	}
2128
2129#endif
2130}
2131
2132void rtl8192_beacon_stop(struct net_device *dev)
2133{
2134	u8 msr, msrm, msr2;
2135	struct r8192_priv *priv = ieee80211_priv(dev);
2136
2137	msr  = read_nic_byte(dev, MSR);
2138	msrm = msr & MSR_LINK_MASK;
2139	msr2 = msr & ~MSR_LINK_MASK;
2140
2141	if(NIC_8192U == priv->card_8192) {
2142		usb_kill_urb(priv->rx_urb[MAX_RX_URB]);
2143	}
2144	if ((msrm == (MSR_LINK_ADHOC<<MSR_LINK_SHIFT) ||
2145		(msrm == (MSR_LINK_MASTER<<MSR_LINK_SHIFT)))){
2146		write_nic_byte(dev, MSR, msr2 | MSR_LINK_NONE);
2147		write_nic_byte(dev, MSR, msr);
2148	}
2149}
2150
2151void rtl8192_config_rate(struct net_device* dev, u16* rate_config)
2152{
2153	 struct r8192_priv *priv = ieee80211_priv(dev);
2154	 struct ieee80211_network *net;
2155	 u8 i=0, basic_rate = 0;
2156	 net = & priv->ieee80211->current_network;
2157
2158	 for (i=0; i<net->rates_len; i++)
2159	 {
2160		 basic_rate = net->rates[i]&0x7f;
2161		 switch(basic_rate)
2162		 {
2163			 case MGN_1M:	*rate_config |= RRSR_1M;	break;
2164			 case MGN_2M:	*rate_config |= RRSR_2M;	break;
2165			 case MGN_5_5M:	*rate_config |= RRSR_5_5M;	break;
2166			 case MGN_11M:	*rate_config |= RRSR_11M;	break;
2167			 case MGN_6M:	*rate_config |= RRSR_6M;	break;
2168			 case MGN_9M:	*rate_config |= RRSR_9M;	break;
2169			 case MGN_12M:	*rate_config |= RRSR_12M;	break;
2170			 case MGN_18M:	*rate_config |= RRSR_18M;	break;
2171			 case MGN_24M:	*rate_config |= RRSR_24M;	break;
2172			 case MGN_36M:	*rate_config |= RRSR_36M;	break;
2173			 case MGN_48M:	*rate_config |= RRSR_48M;	break;
2174			 case MGN_54M:	*rate_config |= RRSR_54M;	break;
2175		 }
2176	 }
2177	 for (i=0; i<net->rates_ex_len; i++)
2178	 {
2179		 basic_rate = net->rates_ex[i]&0x7f;
2180		 switch(basic_rate)
2181		 {
2182			 case MGN_1M:	*rate_config |= RRSR_1M;	break;
2183			 case MGN_2M:	*rate_config |= RRSR_2M;	break;
2184			 case MGN_5_5M:	*rate_config |= RRSR_5_5M;	break;
2185			 case MGN_11M:	*rate_config |= RRSR_11M;	break;
2186			 case MGN_6M:	*rate_config |= RRSR_6M;	break;
2187			 case MGN_9M:	*rate_config |= RRSR_9M;	break;
2188			 case MGN_12M:	*rate_config |= RRSR_12M;	break;
2189			 case MGN_18M:	*rate_config |= RRSR_18M;	break;
2190			 case MGN_24M:	*rate_config |= RRSR_24M;	break;
2191			 case MGN_36M:	*rate_config |= RRSR_36M;	break;
2192			 case MGN_48M:	*rate_config |= RRSR_48M;	break;
2193			 case MGN_54M:	*rate_config |= RRSR_54M;	break;
2194		 }
2195	 }
2196}
2197
2198
2199#define SHORT_SLOT_TIME 9
2200#define NON_SHORT_SLOT_TIME 20
2201
2202void rtl8192_update_cap(struct net_device* dev, u16 cap)
2203{
2204	u32 tmp = 0;
2205	struct r8192_priv *priv = ieee80211_priv(dev);
2206	struct ieee80211_network *net = &priv->ieee80211->current_network;
2207	priv->short_preamble = cap & WLAN_CAPABILITY_SHORT_PREAMBLE;
2208	tmp = priv->basic_rate;
2209	if (priv->short_preamble)
2210		tmp |= BRSR_AckShortPmb;
2211	write_nic_dword(dev, RRSR, tmp);
2212
2213	if (net->mode & (IEEE_G|IEEE_N_24G))
2214	{
2215		u8 slot_time = 0;
2216		if ((cap & WLAN_CAPABILITY_SHORT_SLOT)&&(!priv->ieee80211->pHTInfo->bCurrentRT2RTLongSlotTime))
2217		{//short slot time
2218			slot_time = SHORT_SLOT_TIME;
2219		}
2220		else //long slot time
2221			slot_time = NON_SHORT_SLOT_TIME;
2222		priv->slot_time = slot_time;
2223		write_nic_byte(dev, SLOT_TIME, slot_time);
2224	}
2225
2226}
2227void rtl8192_net_update(struct net_device *dev)
2228{
2229
2230	struct r8192_priv *priv = ieee80211_priv(dev);
2231	struct ieee80211_network *net;
2232	u16 BcnTimeCfg = 0, BcnCW = 6, BcnIFS = 0xf;
2233	u16 rate_config = 0;
2234	net = & priv->ieee80211->current_network;
2235
2236	rtl8192_config_rate(dev, &rate_config);
2237	priv->basic_rate = rate_config &= 0x15f;
2238
2239	write_nic_dword(dev,BSSIDR,((u32*)net->bssid)[0]);
2240	write_nic_word(dev,BSSIDR+4,((u16*)net->bssid)[2]);
2241	//for(i=0;i<ETH_ALEN;i++)
2242	//	write_nic_byte(dev,BSSID+i,net->bssid[i]);
2243
2244	rtl8192_update_msr(dev);
2245//	rtl8192_update_cap(dev, net->capability);
2246	if (priv->ieee80211->iw_mode == IW_MODE_ADHOC)
2247	{
2248	write_nic_word(dev, ATIMWND, 2);
2249	write_nic_word(dev, BCN_DMATIME, 1023);
2250	write_nic_word(dev, BCN_INTERVAL, net->beacon_interval);
2251//	write_nic_word(dev, BcnIntTime, 100);
2252	write_nic_word(dev, BCN_DRV_EARLY_INT, 1);
2253	write_nic_byte(dev, BCN_ERR_THRESH, 100);
2254		BcnTimeCfg |= (BcnCW<<BCN_TCFG_CW_SHIFT);
2255	// TODO: BcnIFS may required to be changed on ASIC
2256	 	BcnTimeCfg |= BcnIFS<<BCN_TCFG_IFS;
2257
2258	write_nic_word(dev, BCN_TCFG, BcnTimeCfg);
2259	}
2260
2261
2262
2263}
2264
2265//temporary hw beacon is not used any more.
2266//open it when necessary
2267#if 1
2268void rtl819xusb_beacon_tx(struct net_device *dev,u16  tx_rate)
2269{
2270
2271#if 0
2272	struct r8192_priv *priv = ieee80211_priv(dev);
2273	struct sk_buff *skb;
2274	int i = 0;
2275	//u8 cr;
2276
2277	rtl8192_net_update(dev);
2278
2279	skb = ieee80211_get_beacon(priv->ieee80211);
2280		if(!skb){
2281			DMESG("not enought memory for allocating beacon");
2282			return;
2283		}
2284
2285
2286		write_nic_byte(dev, BQREQ, read_nic_byte(dev, BQREQ) | (1<<7));
2287
2288		i=0;
2289		//while(!read_nic_byte(dev,BQREQ & (1<<7)))
2290		while( (read_nic_byte(dev, BQREQ) & (1<<7)) == 0 )
2291		{
2292			msleep_interruptible_rtl(HZ/2);
2293			if(i++ > 10){
2294				DMESGW("get stuck to wait HW beacon to be ready");
2295				return ;
2296			}
2297		}
2298	skb->cb[0] = NORM_PRIORITY;
2299	skb->cb[1] = 0; //morefragment = 0
2300	skb->cb[2] = ieeerate2rtlrate(tx_rate);
2301
2302	rtl8192_tx(dev,skb);
2303
2304#endif
2305}
2306#endif
2307inline u8 rtl8192_IsWirelessBMode(u16 rate)
2308{
2309	if( ((rate <= 110) && (rate != 60) && (rate != 90)) || (rate == 220) )
2310		return 1;
2311	else return 0;
2312}
2313
2314u16 N_DBPSOfRate(u16 DataRate);
2315
2316u16 ComputeTxTime(
2317	u16		FrameLength,
2318	u16		DataRate,
2319	u8		bManagementFrame,
2320	u8		bShortPreamble
2321)
2322{
2323	u16	FrameTime;
2324	u16	N_DBPS;
2325	u16	Ceiling;
2326
2327	if( rtl8192_IsWirelessBMode(DataRate) )
2328	{
2329		if( bManagementFrame || !bShortPreamble || DataRate == 10 )
2330		{	// long preamble
2331			FrameTime = (u16)(144+48+(FrameLength*8/(DataRate/10)));
2332		}
2333		else
2334		{	// Short preamble
2335			FrameTime = (u16)(72+24+(FrameLength*8/(DataRate/10)));
2336		}
2337		if( ( FrameLength*8 % (DataRate/10) ) != 0 ) //Get the Ceilling
2338				FrameTime ++;
2339	} else {	//802.11g DSSS-OFDM PLCP length field calculation.
2340		N_DBPS = N_DBPSOfRate(DataRate);
2341		Ceiling = (16 + 8*FrameLength + 6) / N_DBPS
2342				+ (((16 + 8*FrameLength + 6) % N_DBPS) ? 1 : 0);
2343		FrameTime = (u16)(16 + 4 + 4*Ceiling + 6);
2344	}
2345	return FrameTime;
2346}
2347
2348u16 N_DBPSOfRate(u16 DataRate)
2349{
2350	 u16 N_DBPS = 24;
2351
2352	 switch(DataRate)
2353	 {
2354	 case 60:
2355	  N_DBPS = 24;
2356	  break;
2357
2358	 case 90:
2359	  N_DBPS = 36;
2360	  break;
2361
2362	 case 120:
2363	  N_DBPS = 48;
2364	  break;
2365
2366	 case 180:
2367	  N_DBPS = 72;
2368	  break;
2369
2370	 case 240:
2371	  N_DBPS = 96;
2372	  break;
2373
2374	 case 360:
2375	  N_DBPS = 144;
2376	  break;
2377
2378	 case 480:
2379	  N_DBPS = 192;
2380	  break;
2381
2382	 case 540:
2383	  N_DBPS = 216;
2384	  break;
2385
2386	 default:
2387	  break;
2388	 }
2389
2390	 return N_DBPS;
2391}
2392
2393void rtl819xU_cmd_isr(struct urb *tx_cmd_urb, struct pt_regs *regs)
2394{
2395#if 0
2396	struct net_device *dev = (struct net_device*)tx_cmd_urb->context;
2397	struct r8192_priv *priv = ieee80211_priv(dev);
2398	int		   last_init_packet = 0;
2399	u8		   *ptr_cmd_buf;
2400	u16		    cmd_buf_len;
2401
2402	if(tx_cmd_urb->status != 0) {
2403		priv->pFirmware.firmware_seg_index = 0; //only begin transter, should it can be set to 1
2404	}
2405
2406	/* Free the urb and the corresponding buf for common Tx cmd packet, or
2407	 * last segment of each firmware img.
2408	 */
2409	if((priv->pFirmware.firmware_seg_index == 0) ||(priv->pFirmware.firmware_seg_index == priv->pFirmware.firmware_seg_maxnum)) {
2410		priv->pFirmware.firmware_seg_index = 0;//only begin transter, should it can be set to 1
2411	} else {
2412		/* prepare for last transfer */
2413		/* update some infomation for */
2414		/* last segment of the firmware img need indicate to device */
2415		priv->pFirmware.firmware_seg_index++;
2416		if(priv->pFirmware.firmware_seg_index == priv->pFirmware.firmware_seg_maxnum) {
2417			last_init_packet = 1;
2418		}
2419
2420		cmd_buf_len = priv->pFirmware.firmware_seg_container[priv->pFirmware.firmware_seg_index-1].seg_size;
2421		ptr_cmd_buf = priv->pFfirmware.firmware_seg_container[priv->pFfirmware.firmware_seg_index-1].seg_ptr;
2422		rtl819xU_tx_cmd(dev, ptr_cmd_buf, cmd_buf_len, last_init_packet, DESC_PACKET_TYPE_INIT);
2423	}
2424
2425	kfree(tx_cmd_urb->transfer_buffer);
2426#endif
2427	usb_free_urb(tx_cmd_urb);
2428}
2429
2430unsigned int txqueue2outpipe(struct r8192_priv* priv,unsigned int tx_queue) {
2431
2432	if(tx_queue >= 9)
2433	{
2434		RT_TRACE(COMP_ERR,"%s():Unknown queue ID!!!\n",__FUNCTION__);
2435		return 0x04;
2436	}
2437	return priv->txqueue_to_outpipemap[tx_queue];
2438}
2439
2440short rtl819xU_tx_cmd(struct net_device *dev, struct sk_buff *skb)
2441{
2442	struct r8192_priv *priv = ieee80211_priv(dev);
2443	//u8			*tx;
2444	int			status;
2445	struct urb		*tx_urb;
2446	//int			urb_buf_len;
2447	unsigned int 		idx_pipe;
2448	tx_desc_cmd_819x_usb *pdesc = (tx_desc_cmd_819x_usb *)skb->data;
2449	cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
2450	u8 queue_index = tcb_desc->queue_index;
2451
2452	//printk("\n %s::queue_index = %d\n",__FUNCTION__, queue_index);
2453	atomic_inc(&priv->tx_pending[queue_index]);
2454#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
2455	tx_urb = usb_alloc_urb(0,GFP_ATOMIC);
2456#else
2457	tx_urb = usb_alloc_urb(0);
2458#endif
2459	if(!tx_urb){
2460		dev_kfree_skb(skb);
2461		return -ENOMEM;
2462	}
2463
2464	memset(pdesc, 0, USB_HWDESC_HEADER_LEN);
2465	/* Tx descriptor ought to be set according to the skb->cb */
2466	pdesc->FirstSeg = 1;//bFirstSeg;
2467	pdesc->LastSeg = 1;//bLastSeg;
2468	pdesc->CmdInit = tcb_desc->bCmdOrInit;
2469	pdesc->TxBufferSize = tcb_desc->txbuf_size;
2470	pdesc->OWN = 1;
2471	pdesc->LINIP = tcb_desc->bLastIniPkt;
2472
2473	//----------------------------------------------------------------------------
2474	// Fill up USB_OUT_CONTEXT.
2475	//----------------------------------------------------------------------------
2476	// Get index to out pipe from specified QueueID.
2477#ifndef USE_ONE_PIPE
2478	idx_pipe = txqueue2outpipe(priv,queue_index);
2479#else
2480	idx_pipe = 0x04;
2481#endif
2482#ifdef JOHN_DUMP_TXDESC
2483	int i;
2484	printk("<Tx descriptor>--rate %x---",rate);
2485	for (i = 0; i < 8; i++)
2486		printk("%8x ", tx[i]);
2487	printk("\n");
2488#endif
2489	usb_fill_bulk_urb(tx_urb,priv->udev, usb_sndbulkpipe(priv->udev,idx_pipe), \
2490			skb->data, skb->len, rtl8192_tx_isr, skb);
2491
2492#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
2493	status = usb_submit_urb(tx_urb, GFP_ATOMIC);
2494#else
2495	status = usb_submit_urb(tx_urb);
2496#endif
2497
2498	if (!status){
2499		return 0;
2500	}else{
2501		DMESGE("Error TX CMD URB, error %d",
2502				status);
2503		return -1;
2504	}
2505}
2506
2507/*
2508 * Mapping Software/Hardware descriptor queue id to "Queue Select Field"
2509 * in TxFwInfo data structure
2510 * 2006.10.30 by Emily
2511 *
2512 * \param QUEUEID       Software Queue
2513*/
2514u8 MapHwQueueToFirmwareQueue(u8 QueueID)
2515{
2516	u8 QueueSelect = 0x0;       //defualt set to
2517
2518	switch(QueueID) {
2519		case BE_QUEUE:
2520			QueueSelect = QSLT_BE;  //or QSelect = pTcb->priority;
2521			break;
2522
2523		case BK_QUEUE:
2524			QueueSelect = QSLT_BK;  //or QSelect = pTcb->priority;
2525			break;
2526
2527		case VO_QUEUE:
2528			QueueSelect = QSLT_VO;  //or QSelect = pTcb->priority;
2529			break;
2530
2531		case VI_QUEUE:
2532			QueueSelect = QSLT_VI;  //or QSelect = pTcb->priority;
2533			break;
2534		case MGNT_QUEUE:
2535			QueueSelect = QSLT_MGNT;
2536			break;
2537
2538		case BEACON_QUEUE:
2539			QueueSelect = QSLT_BEACON;
2540			break;
2541
2542			// TODO: 2006.10.30 mark other queue selection until we verify it is OK
2543			// TODO: Remove Assertions
2544//#if (RTL819X_FPGA_VER & RTL819X_FPGA_GUANGAN_070502)
2545		case TXCMD_QUEUE:
2546			QueueSelect = QSLT_CMD;
2547			break;
2548//#endif
2549		case HIGH_QUEUE:
2550			QueueSelect = QSLT_HIGH;
2551			break;
2552
2553		default:
2554			RT_TRACE(COMP_ERR, "TransmitTCB(): Impossible Queue Selection: %d \n", QueueID);
2555			break;
2556	}
2557	return QueueSelect;
2558}
2559
2560u8 MRateToHwRate8190Pci(u8 rate)
2561{
2562	u8  ret = DESC90_RATE1M;
2563
2564	switch(rate) {
2565		case MGN_1M:    ret = DESC90_RATE1M;    break;
2566		case MGN_2M:    ret = DESC90_RATE2M;    break;
2567		case MGN_5_5M:  ret = DESC90_RATE5_5M;  break;
2568		case MGN_11M:   ret = DESC90_RATE11M;   break;
2569		case MGN_6M:    ret = DESC90_RATE6M;    break;
2570		case MGN_9M:    ret = DESC90_RATE9M;    break;
2571		case MGN_12M:   ret = DESC90_RATE12M;   break;
2572		case MGN_18M:   ret = DESC90_RATE18M;   break;
2573		case MGN_24M:   ret = DESC90_RATE24M;   break;
2574		case MGN_36M:   ret = DESC90_RATE36M;   break;
2575		case MGN_48M:   ret = DESC90_RATE48M;   break;
2576		case MGN_54M:   ret = DESC90_RATE54M;   break;
2577
2578		// HT rate since here
2579		case MGN_MCS0:  ret = DESC90_RATEMCS0;  break;
2580		case MGN_MCS1:  ret = DESC90_RATEMCS1;  break;
2581		case MGN_MCS2:  ret = DESC90_RATEMCS2;  break;
2582		case MGN_MCS3:  ret = DESC90_RATEMCS3;  break;
2583		case MGN_MCS4:  ret = DESC90_RATEMCS4;  break;
2584		case MGN_MCS5:  ret = DESC90_RATEMCS5;  break;
2585		case MGN_MCS6:  ret = DESC90_RATEMCS6;  break;
2586		case MGN_MCS7:  ret = DESC90_RATEMCS7;  break;
2587		case MGN_MCS8:  ret = DESC90_RATEMCS8;  break;
2588		case MGN_MCS9:  ret = DESC90_RATEMCS9;  break;
2589		case MGN_MCS10: ret = DESC90_RATEMCS10; break;
2590		case MGN_MCS11: ret = DESC90_RATEMCS11; break;
2591		case MGN_MCS12: ret = DESC90_RATEMCS12; break;
2592		case MGN_MCS13: ret = DESC90_RATEMCS13; break;
2593		case MGN_MCS14: ret = DESC90_RATEMCS14; break;
2594		case MGN_MCS15: ret = DESC90_RATEMCS15; break;
2595		case (0x80|0x20): ret = DESC90_RATEMCS32; break;
2596
2597		default:       break;
2598	}
2599	return ret;
2600}
2601
2602
2603u8 QueryIsShort(u8 TxHT, u8 TxRate, cb_desc *tcb_desc)
2604{
2605	u8   tmp_Short;
2606
2607	tmp_Short = (TxHT==1)?((tcb_desc->bUseShortGI)?1:0):((tcb_desc->bUseShortPreamble)?1:0);
2608
2609	if(TxHT==1 && TxRate != DESC90_RATEMCS15)
2610		tmp_Short = 0;
2611
2612	return tmp_Short;
2613}
2614
2615#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
2616static void tx_zero_isr(struct urb *tx_urb, struct pt_regs *reg)
2617#else
2618static void tx_zero_isr(struct urb *tx_urb)
2619#endif
2620{
2621	return;
2622}
2623
2624/*
2625 * The tx procedure is just as following,
2626 * skb->cb will contain all the following information,
2627 * priority, morefrag, rate, &dev.
2628 * */
2629short rtl8192_tx(struct net_device *dev, struct sk_buff* skb)
2630{
2631	struct r8192_priv *priv = ieee80211_priv(dev);
2632	cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
2633	tx_desc_819x_usb *tx_desc = (tx_desc_819x_usb *)skb->data;
2634	tx_fwinfo_819x_usb *tx_fwinfo = (tx_fwinfo_819x_usb *)(skb->data + USB_HWDESC_HEADER_LEN);
2635	struct usb_device *udev = priv->udev;
2636	int pend;
2637	int status;
2638	struct urb *tx_urb = NULL, *tx_urb_zero = NULL;
2639	//int urb_len;
2640	unsigned int idx_pipe;
2641//	RT_DEBUG_DATA(COMP_SEND, tcb_desc, sizeof(cb_desc));
2642#if 0
2643	/* Added by Annie for filling Len_Adjust field. 2005-12-14. */
2644        RT_ENC_ALG  EncAlg = NO_Encryption;
2645#endif
2646//	printk("=============> %s\n", __FUNCTION__);
2647	pend = atomic_read(&priv->tx_pending[tcb_desc->queue_index]);
2648	/* we are locked here so the two atomic_read and inc are executed
2649	 * without interleaves
2650	 * !!! For debug purpose
2651	 */
2652	if( pend > MAX_TX_URB){
2653#if 0
2654		switch (tcb_desc->queue_index) {
2655			case VO_PRIORITY:
2656				priv->stats.txvodrop++;
2657				break;
2658			case VI_PRIORITY:
2659				priv->stats.txvidrop++;
2660				break;
2661			case BE_PRIORITY:
2662				priv->stats.txbedrop++;
2663				break;
2664			default://BK_PRIORITY
2665				priv->stats.txbkdrop++;
2666				break;
2667		}
2668#endif
2669		printk("To discard skb packet!\n");
2670		dev_kfree_skb_any(skb);
2671		return -1;
2672	}
2673
2674#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
2675	tx_urb = usb_alloc_urb(0,GFP_ATOMIC);
2676#else
2677	tx_urb = usb_alloc_urb(0);
2678#endif
2679	if(!tx_urb){
2680		dev_kfree_skb_any(skb);
2681		return -ENOMEM;
2682	}
2683
2684	/* Fill Tx firmware info */
2685	memset(tx_fwinfo,0,sizeof(tx_fwinfo_819x_usb));
2686	/* DWORD 0 */
2687	tx_fwinfo->TxHT = (tcb_desc->data_rate&0x80)?1:0;
2688	tx_fwinfo->TxRate = MRateToHwRate8190Pci(tcb_desc->data_rate);
2689	tx_fwinfo->EnableCPUDur = tcb_desc->bTxEnableFwCalcDur;
2690	tx_fwinfo->Short = QueryIsShort(tx_fwinfo->TxHT, tx_fwinfo->TxRate, tcb_desc);
2691	if(tcb_desc->bAMPDUEnable) {//AMPDU enabled
2692		tx_fwinfo->AllowAggregation = 1;
2693		/* DWORD 1 */
2694		tx_fwinfo->RxMF = tcb_desc->ampdu_factor;
2695		tx_fwinfo->RxAMD = tcb_desc->ampdu_density&0x07;//ampdudensity
2696	} else {
2697		tx_fwinfo->AllowAggregation = 0;
2698		/* DWORD 1 */
2699		tx_fwinfo->RxMF = 0;
2700		tx_fwinfo->RxAMD = 0;
2701	}
2702
2703	/* Protection mode related */
2704	tx_fwinfo->RtsEnable = (tcb_desc->bRTSEnable)?1:0;
2705	tx_fwinfo->CtsEnable = (tcb_desc->bCTSEnable)?1:0;
2706	tx_fwinfo->RtsSTBC = (tcb_desc->bRTSSTBC)?1:0;
2707	tx_fwinfo->RtsHT = (tcb_desc->rts_rate&0x80)?1:0;
2708	tx_fwinfo->RtsRate =  MRateToHwRate8190Pci((u8)tcb_desc->rts_rate);
2709	tx_fwinfo->RtsSubcarrier = (tx_fwinfo->RtsHT==0)?(tcb_desc->RTSSC):0;
2710	tx_fwinfo->RtsBandwidth = (tx_fwinfo->RtsHT==1)?((tcb_desc->bRTSBW)?1:0):0;
2711	tx_fwinfo->RtsShort = (tx_fwinfo->RtsHT==0)?(tcb_desc->bRTSUseShortPreamble?1:0):\
2712				(tcb_desc->bRTSUseShortGI?1:0);
2713
2714	/* Set Bandwidth and sub-channel settings. */
2715	if(priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20_40)
2716	{
2717		if(tcb_desc->bPacketBW) {
2718			tx_fwinfo->TxBandwidth = 1;
2719			tx_fwinfo->TxSubCarrier = 0;    //By SD3's Jerry suggestion, use duplicated mode
2720		} else {
2721			tx_fwinfo->TxBandwidth = 0;
2722			tx_fwinfo->TxSubCarrier = priv->nCur40MhzPrimeSC;
2723		}
2724	} else {
2725		tx_fwinfo->TxBandwidth = 0;
2726		tx_fwinfo->TxSubCarrier = 0;
2727	}
2728
2729#ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
2730	if (tcb_desc->drv_agg_enable)
2731	{
2732		tx_fwinfo->Tx_INFO_RSVD = (tcb_desc->DrvAggrNum & 0x1f) << 1;
2733	}
2734#endif
2735	/* Fill Tx descriptor */
2736	memset(tx_desc, 0, sizeof(tx_desc_819x_usb));
2737	/* DWORD 0 */
2738        tx_desc->LINIP = 0;
2739        tx_desc->CmdInit = 1;
2740        tx_desc->Offset =  sizeof(tx_fwinfo_819x_usb) + 8;
2741
2742#ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
2743	if (tcb_desc->drv_agg_enable) {
2744		tx_desc->PktSize = tcb_desc->pkt_size;
2745	} else
2746#endif
2747	{
2748		tx_desc->PktSize = (skb->len - TX_PACKET_SHIFT_BYTES) & 0xffff;
2749	}
2750
2751	/*DWORD 1*/
2752	tx_desc->SecCAMID= 0;
2753	tx_desc->RATid = tcb_desc->RATRIndex;
2754#if 0
2755	/* Fill security related */
2756	if( pTcb->bEncrypt && !Adapter->MgntInfo.SecurityInfo.SWTxEncryptFlag)
2757	{
2758		EncAlg = SecGetEncryptionOverhead(
2759				Adapter,
2760				&EncryptionMPDUHeadOverhead,
2761				&EncryptionMPDUTailOverhead,
2762				NULL,
2763				NULL,
2764				FALSE,
2765				FALSE);
2766		//2004/07/22, kcwu, EncryptionMPDUHeadOverhead has been added in previous code
2767		//MPDUOverhead = EncryptionMPDUHeadOverhead + EncryptionMPDUTailOverhead;
2768		MPDUOverhead = EncryptionMPDUTailOverhead;
2769		tx_desc->NoEnc = 0;
2770		RT_TRACE(COMP_SEC, DBG_LOUD, ("******We in the loop SecCAMID is %d SecDescAssign is %d The Sec is %d********\n",tx_desc->SecCAMID,tx_desc->SecDescAssign,EncAlg));
2771		//CamDumpAll(Adapter);
2772	}
2773	else
2774#endif
2775	{
2776		//MPDUOverhead = 0;
2777		tx_desc->NoEnc = 1;
2778	}
2779#if 0
2780	switch(EncAlg){
2781		case NO_Encryption:
2782			tx_desc->SecType = 0x0;
2783			break;
2784		case WEP40_Encryption:
2785		case WEP104_Encryption:
2786			tx_desc->SecType = 0x1;
2787			break;
2788		case TKIP_Encryption:
2789			tx_desc->SecType = 0x2;
2790			break;
2791		case AESCCMP_Encryption:
2792			tx_desc->SecType = 0x3;
2793			break;
2794		default:
2795			tx_desc->SecType = 0x0;
2796			break;
2797	}
2798#else
2799	tx_desc->SecType = 0x0;
2800#endif
2801		if (tcb_desc->bHwSec)
2802			{
2803				switch (priv->ieee80211->pairwise_key_type)
2804				{
2805					case KEY_TYPE_WEP40:
2806					case KEY_TYPE_WEP104:
2807						 tx_desc->SecType = 0x1;
2808						 tx_desc->NoEnc = 0;
2809						 break;
2810					case KEY_TYPE_TKIP:
2811						 tx_desc->SecType = 0x2;
2812						 tx_desc->NoEnc = 0;
2813						 break;
2814					case KEY_TYPE_CCMP:
2815						 tx_desc->SecType = 0x3;
2816						 tx_desc->NoEnc = 0;
2817						 break;
2818					case KEY_TYPE_NA:
2819						 tx_desc->SecType = 0x0;
2820						 tx_desc->NoEnc = 1;
2821						 break;
2822				}
2823			}
2824
2825	tx_desc->QueueSelect = MapHwQueueToFirmwareQueue(tcb_desc->queue_index);
2826	tx_desc->TxFWInfoSize =  sizeof(tx_fwinfo_819x_usb);
2827
2828	tx_desc->DISFB = tcb_desc->bTxDisableRateFallBack;
2829	tx_desc->USERATE = tcb_desc->bTxUseDriverAssingedRate;
2830
2831        /* Fill fields that are required to be initialized in all of the descriptors */
2832        //DWORD 0
2833#if 0
2834        tx_desc->FirstSeg = (tcb_desc->bFirstSeg)? 1:0;
2835        tx_desc->LastSeg = (tcb_desc->bLastSeg)?1:0;
2836#else
2837        tx_desc->FirstSeg = 1;
2838        tx_desc->LastSeg = 1;
2839#endif
2840        tx_desc->OWN = 1;
2841
2842#ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
2843	if (tcb_desc->drv_agg_enable) {
2844		tx_desc->TxBufferSize = tcb_desc->pkt_size + sizeof(tx_fwinfo_819x_usb);
2845	} else
2846#endif
2847	{
2848		//DWORD 2
2849		tx_desc->TxBufferSize = (u32)(skb->len - USB_HWDESC_HEADER_LEN);
2850	}
2851	/* Get index to out pipe from specified QueueID */
2852#ifndef USE_ONE_PIPE
2853	idx_pipe = txqueue2outpipe(priv,tcb_desc->queue_index);
2854#else
2855	idx_pipe = 0x5;
2856#endif
2857
2858	//RT_DEBUG_DATA(COMP_SEND,tx_fwinfo,sizeof(tx_fwinfo_819x_usb));
2859	//RT_DEBUG_DATA(COMP_SEND,tx_desc,sizeof(tx_desc_819x_usb));
2860
2861	/* To submit bulk urb */
2862	usb_fill_bulk_urb(tx_urb,udev,
2863			usb_sndbulkpipe(udev,idx_pipe), skb->data,
2864			skb->len, rtl8192_tx_isr, skb);
2865
2866#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
2867	status = usb_submit_urb(tx_urb, GFP_ATOMIC);
2868#else
2869	status = usb_submit_urb(tx_urb);
2870#endif
2871	if (!status){
2872//we need to send 0 byte packet whenever 512N bytes/64N(HIGN SPEED/NORMAL SPEED) bytes packet has been transmitted. Otherwise, it will be halt to wait for another packet. WB. 2008.08.27
2873		bool bSend0Byte = false;
2874		u8 zero = 0;
2875		if(udev->speed == USB_SPEED_HIGH)
2876		{
2877			if (skb->len > 0 && skb->len % 512 == 0)
2878				bSend0Byte = true;
2879		}
2880		else
2881		{
2882			if (skb->len > 0 && skb->len % 64 == 0)
2883				bSend0Byte = true;
2884		}
2885		if (bSend0Byte)
2886		{
2887#if 1
2888#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
2889			tx_urb_zero = usb_alloc_urb(0,GFP_ATOMIC);
2890#else
2891			tx_urb_zero = usb_alloc_urb(0);
2892#endif
2893			if(!tx_urb_zero){
2894				RT_TRACE(COMP_ERR, "can't alloc urb for zero byte\n");
2895				return -ENOMEM;
2896			}
2897			usb_fill_bulk_urb(tx_urb_zero,udev,
2898					usb_sndbulkpipe(udev,idx_pipe), &zero,
2899					0, tx_zero_isr, dev);
2900#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
2901			status = usb_submit_urb(tx_urb_zero, GFP_ATOMIC);
2902#else
2903			status = usb_submit_urb(tx_urb_zero);
2904#endif
2905			if (status){
2906			RT_TRACE(COMP_ERR, "Error TX URB for zero byte %d, error %d", atomic_read(&priv->tx_pending[tcb_desc->queue_index]), status);
2907			return -1;
2908			}
2909#endif
2910		}
2911		dev->trans_start = jiffies;
2912		atomic_inc(&priv->tx_pending[tcb_desc->queue_index]);
2913		return 0;
2914	}else{
2915		RT_TRACE(COMP_ERR, "Error TX URB %d, error %d", atomic_read(&priv->tx_pending[tcb_desc->queue_index]),
2916				status);
2917		return -1;
2918	}
2919}
2920
2921short rtl8192_usb_initendpoints(struct net_device *dev)
2922{
2923	struct r8192_priv *priv = ieee80211_priv(dev);
2924
2925	priv->rx_urb = (struct urb**) kmalloc (sizeof(struct urb*) * (MAX_RX_URB+1), GFP_KERNEL);
2926
2927#ifndef JACKSON_NEW_RX
2928	for(i=0;i<(MAX_RX_URB+1);i++){
2929
2930#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
2931		priv->rx_urb[i] = usb_alloc_urb(0,GFP_KERNEL);
2932#else
2933		priv->rx_urb[i] = usb_alloc_urb(0);
2934#endif
2935
2936		priv->rx_urb[i]->transfer_buffer = kmalloc(RX_URB_SIZE, GFP_KERNEL);
2937
2938		priv->rx_urb[i]->transfer_buffer_length = RX_URB_SIZE;
2939	}
2940#endif
2941
2942#ifdef THOMAS_BEACON
2943{
2944	long align = 0;
2945	void *oldaddr, *newaddr;
2946
2947	priv->rx_urb[16] = usb_alloc_urb(0, GFP_KERNEL);
2948	priv->oldaddr = kmalloc(16, GFP_KERNEL);
2949	oldaddr = priv->oldaddr;
2950	align = ((long)oldaddr) & 3;
2951	if (align) {
2952		newaddr = oldaddr + 4 - align;
2953		priv->rx_urb[16]->transfer_buffer_length = 16 - 4 + align;
2954	} else {
2955		newaddr = oldaddr;
2956		priv->rx_urb[16]->transfer_buffer_length = 16;
2957	}
2958	priv->rx_urb[16]->transfer_buffer = newaddr;
2959}
2960#endif
2961
2962        memset(priv->rx_urb, 0, sizeof(struct urb*) * MAX_RX_URB);
2963        priv->pp_rxskb = (struct sk_buff **)kmalloc(sizeof(struct sk_buff *) * MAX_RX_URB, GFP_KERNEL);
2964        if (priv->pp_rxskb == NULL)
2965                goto destroy;
2966
2967        memset(priv->pp_rxskb, 0, sizeof(struct sk_buff*) * MAX_RX_URB);
2968
2969        goto _middle;
2970
2971
2972destroy:
2973        if (priv->pp_rxskb) {
2974                kfree(priv->pp_rxskb);
2975        }
2976        if (priv->rx_urb) {
2977                kfree(priv->rx_urb);
2978        }
2979
2980        priv->pp_rxskb = NULL;
2981	priv->rx_urb = NULL;
2982
2983        DMESGE("Endpoint Alloc Failure");
2984        return -ENOMEM;
2985
2986
2987_middle:
2988
2989	printk("End of initendpoints\n");
2990	return 0;
2991
2992}
2993#ifdef THOMAS_BEACON
2994void rtl8192_usb_deleteendpoints(struct net_device *dev)
2995{
2996	int i;
2997	struct r8192_priv *priv = ieee80211_priv(dev);
2998
2999	if(priv->rx_urb){
3000		for(i=0;i<(MAX_RX_URB+1);i++){
3001			usb_kill_urb(priv->rx_urb[i]);
3002			usb_free_urb(priv->rx_urb[i]);
3003		}
3004		kfree(priv->rx_urb);
3005		priv->rx_urb = NULL;
3006	}
3007	if(priv->oldaddr){
3008		kfree(priv->oldaddr);
3009		priv->oldaddr = NULL;
3010	}
3011        if (priv->pp_rxskb) {
3012                kfree(priv->pp_rxskb);
3013                priv->pp_rxskb = 0;
3014	}
3015}
3016#else
3017void rtl8192_usb_deleteendpoints(struct net_device *dev)
3018{
3019	int i;
3020	struct r8192_priv *priv = ieee80211_priv(dev);
3021
3022#ifndef JACKSON_NEW_RX
3023
3024	if(priv->rx_urb){
3025		for(i=0;i<(MAX_RX_URB+1);i++){
3026			usb_kill_urb(priv->rx_urb[i]);
3027			kfree(priv->rx_urb[i]->transfer_buffer);
3028			usb_free_urb(priv->rx_urb[i]);
3029		}
3030		kfree(priv->rx_urb);
3031		priv->rx_urb = NULL;
3032
3033	}
3034#else
3035	if(priv->rx_urb){
3036                kfree(priv->rx_urb);
3037                priv->rx_urb = NULL;
3038        }
3039	if(priv->oldaddr){
3040		kfree(priv->oldaddr);
3041		priv->oldaddr = NULL;
3042	}
3043        if (priv->pp_rxskb) {
3044                kfree(priv->pp_rxskb);
3045                priv->pp_rxskb = 0;
3046
3047        }
3048
3049#endif
3050}
3051#endif
3052
3053#if 0
3054void rtl8192_set_rate(struct net_device *dev)
3055{
3056	int i;
3057	u16 word;
3058	int basic_rate,min_rr_rate,max_rr_rate;
3059
3060//	struct r8192_priv *priv = ieee80211_priv(dev);
3061
3062	//if (ieee80211_is_54g(priv->ieee80211->current_network) &&
3063//		priv->ieee80211->state == IEEE80211_LINKED){
3064	basic_rate = ieeerate2rtlrate(240);
3065	min_rr_rate = ieeerate2rtlrate(60);
3066	max_rr_rate = ieeerate2rtlrate(240);
3067
3068//
3069//	}else{
3070//		basic_rate = ieeerate2rtlrate(20);
3071//		min_rr_rate = ieeerate2rtlrate(10);
3072//		max_rr_rate = ieeerate2rtlrate(110);
3073//	}
3074
3075	write_nic_byte(dev, RESP_RATE,
3076			max_rr_rate<<MAX_RESP_RATE_SHIFT| min_rr_rate<<MIN_RESP_RATE_SHIFT);
3077
3078	//word  = read_nic_word(dev, BRSR);
3079	word  = read_nic_word(dev, BRSR_8187);
3080	word &= ~BRSR_MBR_8185;
3081
3082
3083	for(i=0;i<=basic_rate;i++)
3084		word |= (1<<i);
3085
3086	//write_nic_word(dev, BRSR, word);
3087	write_nic_word(dev, BRSR_8187, word);
3088	//DMESG("RR:%x BRSR: %x", read_nic_byte(dev,RESP_RATE), read_nic_word(dev,BRSR));
3089}
3090#endif
3091extern void rtl8192_update_ratr_table(struct net_device* dev);
3092void rtl8192_link_change(struct net_device *dev)
3093{
3094//	int i;
3095
3096	struct r8192_priv *priv = ieee80211_priv(dev);
3097	struct ieee80211_device* ieee = priv->ieee80211;
3098	//write_nic_word(dev, BCN_INTR_ITV, net->beacon_interval);
3099	if (ieee->state == IEEE80211_LINKED)
3100	{
3101		rtl8192_net_update(dev);
3102		rtl8192_update_ratr_table(dev);
3103#if 1
3104		//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
3105		if ((KEY_TYPE_WEP40 == ieee->pairwise_key_type) || (KEY_TYPE_WEP104 == ieee->pairwise_key_type))
3106		EnableHWSecurityConfig8192(dev);
3107#endif
3108	}
3109	/*update timing params*/
3110//	RT_TRACE(COMP_CH, "========>%s(), chan:%d\n", __FUNCTION__, priv->chan);
3111//	rtl8192_set_chan(dev, priv->chan);
3112	 if (ieee->iw_mode == IW_MODE_INFRA || ieee->iw_mode == IW_MODE_ADHOC)
3113        {
3114                u32 reg = 0;
3115                reg = read_nic_dword(dev, RCR);
3116                if (priv->ieee80211->state == IEEE80211_LINKED)
3117                        priv->ReceiveConfig = reg |= RCR_CBSSID;
3118                else
3119                        priv->ReceiveConfig = reg &= ~RCR_CBSSID;
3120                write_nic_dword(dev, RCR, reg);
3121        }
3122
3123//	rtl8192_set_rxconf(dev);
3124}
3125
3126static struct ieee80211_qos_parameters def_qos_parameters = {
3127        {3,3,3,3},/* cw_min */
3128        {7,7,7,7},/* cw_max */
3129        {2,2,2,2},/* aifs */
3130        {0,0,0,0},/* flags */
3131        {0,0,0,0} /* tx_op_limit */
3132};
3133
3134
3135#if LINUX_VERSION_CODE >=KERNEL_VERSION(2,6,20)
3136void rtl8192_update_beacon(struct work_struct * work)
3137{
3138        struct r8192_priv *priv = container_of(work, struct r8192_priv, update_beacon_wq.work);
3139        struct net_device *dev = priv->ieee80211->dev;
3140#else
3141void rtl8192_update_beacon(struct net_device *dev)
3142{
3143        struct r8192_priv *priv = ieee80211_priv(dev);
3144#endif
3145 	struct ieee80211_device* ieee = priv->ieee80211;
3146	struct ieee80211_network* net = &ieee->current_network;
3147
3148	if (ieee->pHTInfo->bCurrentHTSupport)
3149		HTUpdateSelfAndPeerSetting(ieee, net);
3150	ieee->pHTInfo->bCurrentRT2RTLongSlotTime = net->bssht.bdRT2RTLongSlotTime;
3151	rtl8192_update_cap(dev, net->capability);
3152}
3153/*
3154* background support to run QoS activate functionality
3155*/
3156int WDCAPARA_ADD[] = {EDCAPARA_BE,EDCAPARA_BK,EDCAPARA_VI,EDCAPARA_VO};
3157#if LINUX_VERSION_CODE >=KERNEL_VERSION(2,6,20)
3158void rtl8192_qos_activate(struct work_struct * work)
3159{
3160        struct r8192_priv *priv = container_of(work, struct r8192_priv, qos_activate);
3161        struct net_device *dev = priv->ieee80211->dev;
3162#else
3163void rtl8192_qos_activate(struct net_device *dev)
3164{
3165        struct r8192_priv *priv = ieee80211_priv(dev);
3166#endif
3167        struct ieee80211_qos_parameters *qos_parameters = &priv->ieee80211->current_network.qos_data.parameters;
3168        u8 mode = priv->ieee80211->current_network.mode;
3169        //u32 size = sizeof(struct ieee80211_qos_parameters);
3170	u8  u1bAIFS;
3171	u32 u4bAcParam;
3172        int i;
3173
3174        if (priv == NULL)
3175                return;
3176
3177#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16))
3178	down(&priv->mutex);
3179#else
3180       mutex_lock(&priv->mutex);
3181#endif
3182        if(priv->ieee80211->state != IEEE80211_LINKED)
3183		goto success;
3184	RT_TRACE(COMP_QOS,"qos active process with associate response received\n");
3185	/* It better set slot time at first */
3186	/* For we just support b/g mode at present, let the slot time at 9/20 selection */
3187	/* update the ac parameter to related registers */
3188	for(i = 0; i <  QOS_QUEUE_NUM; i++) {
3189		//Mode G/A: slotTimeTimer = 9; Mode B: 20
3190		u1bAIFS = qos_parameters->aifs[i] * ((mode&(IEEE_G|IEEE_N_24G)) ?9:20) + aSifsTime;
3191		u4bAcParam = ((((u32)(qos_parameters->tx_op_limit[i]))<< AC_PARAM_TXOP_LIMIT_OFFSET)|
3192				(((u32)(qos_parameters->cw_max[i]))<< AC_PARAM_ECW_MAX_OFFSET)|
3193				(((u32)(qos_parameters->cw_min[i]))<< AC_PARAM_ECW_MIN_OFFSET)|
3194				((u32)u1bAIFS << AC_PARAM_AIFS_OFFSET));
3195
3196		write_nic_dword(dev, WDCAPARA_ADD[i], u4bAcParam);
3197		//write_nic_dword(dev, WDCAPARA_ADD[i], 0x005e4332);
3198	}
3199
3200success:
3201#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16))
3202	up(&priv->mutex);
3203#else
3204       mutex_unlock(&priv->mutex);
3205#endif
3206}
3207
3208static int rtl8192_qos_handle_probe_response(struct r8192_priv *priv,
3209		int active_network,
3210		struct ieee80211_network *network)
3211{
3212	int ret = 0;
3213	u32 size = sizeof(struct ieee80211_qos_parameters);
3214
3215	if(priv->ieee80211->state !=IEEE80211_LINKED)
3216                return ret;
3217
3218        if ((priv->ieee80211->iw_mode != IW_MODE_INFRA))
3219                return ret;
3220
3221	if (network->flags & NETWORK_HAS_QOS_MASK) {
3222		if (active_network &&
3223				(network->flags & NETWORK_HAS_QOS_PARAMETERS))
3224			network->qos_data.active = network->qos_data.supported;
3225
3226		if ((network->qos_data.active == 1) && (active_network == 1) &&
3227				(network->flags & NETWORK_HAS_QOS_PARAMETERS) &&
3228				(network->qos_data.old_param_count !=
3229				 network->qos_data.param_count)) {
3230			network->qos_data.old_param_count =
3231				network->qos_data.param_count;
3232#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
3233			queue_work(priv->priv_wq, &priv->qos_activate);
3234#else
3235			schedule_task(&priv->qos_activate);
3236#endif
3237			RT_TRACE (COMP_QOS, "QoS parameters change call "
3238					"qos_activate\n");
3239		}
3240	} else {
3241		memcpy(&priv->ieee80211->current_network.qos_data.parameters,\
3242		       &def_qos_parameters, size);
3243
3244		if ((network->qos_data.active == 1) && (active_network == 1)) {
3245#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
3246			queue_work(priv->priv_wq, &priv->qos_activate);
3247#else
3248			schedule_task(&priv->qos_activate);
3249#endif
3250			RT_TRACE(COMP_QOS, "QoS was disabled call qos_activate \n");
3251		}
3252		network->qos_data.active = 0;
3253		network->qos_data.supported = 0;
3254	}
3255
3256	return 0;
3257}
3258
3259/* handle manage frame frame beacon and probe response */
3260static int rtl8192_handle_beacon(struct net_device * dev,
3261                              struct ieee80211_beacon * beacon,
3262                              struct ieee80211_network * network)
3263{
3264	struct r8192_priv *priv = ieee80211_priv(dev);
3265
3266	rtl8192_qos_handle_probe_response(priv,1,network);
3267#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
3268	queue_delayed_work(priv->priv_wq, &priv->update_beacon_wq, 0);
3269#else
3270#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
3271	schedule_task(&priv->update_beacon_wq);
3272#else
3273	queue_work(priv->priv_wq, &priv->update_beacon_wq);
3274#endif
3275
3276#endif
3277	return 0;
3278
3279}
3280
3281/*
3282* handling the beaconing responses. if we get different QoS setting
3283* off the network from the associated setting, adjust the QoS
3284* setting
3285*/
3286static int rtl8192_qos_association_resp(struct r8192_priv *priv,
3287                                    struct ieee80211_network *network)
3288{
3289        int ret = 0;
3290        unsigned long flags;
3291        u32 size = sizeof(struct ieee80211_qos_parameters);
3292        int set_qos_param = 0;
3293
3294        if ((priv == NULL) || (network == NULL))
3295                return ret;
3296
3297	if(priv->ieee80211->state !=IEEE80211_LINKED)
3298                return ret;
3299
3300        if ((priv->ieee80211->iw_mode != IW_MODE_INFRA))
3301                return ret;
3302
3303        spin_lock_irqsave(&priv->ieee80211->lock, flags);
3304	if(network->flags & NETWORK_HAS_QOS_PARAMETERS) {
3305		memcpy(&priv->ieee80211->current_network.qos_data.parameters,\
3306			 &network->qos_data.parameters,\
3307			sizeof(struct ieee80211_qos_parameters));
3308		priv->ieee80211->current_network.qos_data.active = 1;
3309#if 0
3310		if((priv->ieee80211->current_network.qos_data.param_count != \
3311					network->qos_data.param_count))
3312#endif
3313		 {
3314                        set_qos_param = 1;
3315			/* update qos parameter for current network */
3316			priv->ieee80211->current_network.qos_data.old_param_count = \
3317				 priv->ieee80211->current_network.qos_data.param_count;
3318			priv->ieee80211->current_network.qos_data.param_count = \
3319			     	 network->qos_data.param_count;
3320		}
3321        } else {
3322		memcpy(&priv->ieee80211->current_network.qos_data.parameters,\
3323		       &def_qos_parameters, size);
3324		priv->ieee80211->current_network.qos_data.active = 0;
3325		priv->ieee80211->current_network.qos_data.supported = 0;
3326                set_qos_param = 1;
3327        }
3328
3329        spin_unlock_irqrestore(&priv->ieee80211->lock, flags);
3330
3331	RT_TRACE(COMP_QOS, "%s: network->flags = %d,%d\n",__FUNCTION__,network->flags ,priv->ieee80211->current_network.qos_data.active);
3332	if (set_qos_param == 1)
3333#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
3334		queue_work(priv->priv_wq, &priv->qos_activate);
3335#else
3336		schedule_task(&priv->qos_activate);
3337#endif
3338
3339
3340        return ret;
3341}
3342
3343
3344static int rtl8192_handle_assoc_response(struct net_device *dev,
3345                                     struct ieee80211_assoc_response_frame *resp,
3346                                     struct ieee80211_network *network)
3347{
3348        struct r8192_priv *priv = ieee80211_priv(dev);
3349        rtl8192_qos_association_resp(priv, network);
3350        return 0;
3351}
3352
3353
3354void rtl8192_update_ratr_table(struct net_device* dev)
3355	//	POCTET_STRING	posLegacyRate,
3356	//	u8*			pMcsRate)
3357	//	PRT_WLAN_STA	pEntry)
3358{
3359	struct r8192_priv* priv = ieee80211_priv(dev);
3360	struct ieee80211_device* ieee = priv->ieee80211;
3361	u8* pMcsRate = ieee->dot11HTOperationalRateSet;
3362	//struct ieee80211_network *net = &ieee->current_network;
3363	u32 ratr_value = 0;
3364	u8 rate_index = 0;
3365	rtl8192_config_rate(dev, (u16*)(&ratr_value));
3366	ratr_value |= (*(u16*)(pMcsRate)) << 12;
3367//	switch (net->mode)
3368	switch (ieee->mode)
3369	{
3370		case IEEE_A:
3371			ratr_value &= 0x00000FF0;
3372			break;
3373		case IEEE_B:
3374			ratr_value &= 0x0000000F;
3375			break;
3376		case IEEE_G:
3377			ratr_value &= 0x00000FF7;
3378			break;
3379		case IEEE_N_24G:
3380		case IEEE_N_5G:
3381			if (ieee->pHTInfo->PeerMimoPs == 0) //MIMO_PS_STATIC
3382				ratr_value &= 0x0007F007;
3383			else{
3384				if (priv->rf_type == RF_1T2R)
3385					ratr_value &= 0x000FF007;
3386				else
3387					ratr_value &= 0x0F81F007;
3388			}
3389			break;
3390		default:
3391			break;
3392	}
3393	ratr_value &= 0x0FFFFFFF;
3394	if(ieee->pHTInfo->bCurTxBW40MHz && ieee->pHTInfo->bCurShortGI40MHz){
3395		ratr_value |= 0x80000000;
3396	}else if(!ieee->pHTInfo->bCurTxBW40MHz && ieee->pHTInfo->bCurShortGI20MHz){
3397		ratr_value |= 0x80000000;
3398	}
3399	write_nic_dword(dev, RATR0+rate_index*4, ratr_value);
3400	write_nic_byte(dev, UFWP, 1);
3401}
3402
3403static u8 ccmp_ie[4] = {0x00,0x50,0xf2,0x04};
3404static u8 ccmp_rsn_ie[4] = {0x00, 0x0f, 0xac, 0x04};
3405bool GetNmodeSupportBySecCfg8192(struct net_device*dev)
3406{
3407#if 1
3408	struct r8192_priv* priv = ieee80211_priv(dev);
3409	struct ieee80211_device* ieee = priv->ieee80211;
3410	struct ieee80211_network * network = &ieee->current_network;
3411        int wpa_ie_len= ieee->wpa_ie_len;
3412        struct ieee80211_crypt_data* crypt;
3413        int encrypt;
3414
3415        crypt = ieee->crypt[ieee->tx_keyidx];
3416	//we use connecting AP's capability instead of only security config on our driver to distinguish whether it should use N mode or G mode
3417        encrypt = (network->capability & WLAN_CAPABILITY_PRIVACY) || (ieee->host_encrypt && crypt && crypt->ops && (0 == strcmp(crypt->ops->name,"WEP")));
3418
3419	/* simply judge  */
3420	if(encrypt && (wpa_ie_len == 0)) {
3421		/* wep encryption, no N mode setting */
3422		return false;
3423//	} else if((wpa_ie_len != 0)&&(memcmp(&(ieee->wpa_ie[14]),ccmp_ie,4))) {
3424	} else if((wpa_ie_len != 0)) {
3425		/* parse pairwise key type */
3426		//if((pairwisekey = WEP40)||(pairwisekey = WEP104)||(pairwisekey = TKIP))
3427		if (((ieee->wpa_ie[0] == 0xdd) && (!memcmp(&(ieee->wpa_ie[14]),ccmp_ie,4))) || ((ieee->wpa_ie[0] == 0x30) && (!memcmp(&ieee->wpa_ie[10],ccmp_rsn_ie, 4))))
3428			return true;
3429		else
3430			return false;
3431	} else {
3432		return true;
3433	}
3434
3435#if 0
3436        //In here we discuss with SD4 David. He think we still can send TKIP in broadcast group key in MCS rate.
3437        //We can't force in G mode if Pairwie key is AES and group key is TKIP
3438        if((pSecInfo->GroupEncAlgorithm == WEP104_Encryption) || (pSecInfo->GroupEncAlgorithm == WEP40_Encryption)  ||
3439           (pSecInfo->PairwiseEncAlgorithm == WEP104_Encryption) ||
3440           (pSecInfo->PairwiseEncAlgorithm == WEP40_Encryption) || (pSecInfo->PairwiseEncAlgorithm == TKIP_Encryption))
3441        {
3442                return  false;
3443        }
3444        else
3445                return true;
3446#endif
3447	return true;
3448#endif
3449}
3450
3451bool GetHalfNmodeSupportByAPs819xUsb(struct net_device* dev)
3452{
3453	bool			Reval;
3454	struct r8192_priv* priv = ieee80211_priv(dev);
3455	struct ieee80211_device* ieee = priv->ieee80211;
3456
3457	if(ieee->bHalfWirelessN24GMode == true)
3458		Reval = true;
3459	else
3460		Reval =  false;
3461
3462	return Reval;
3463}
3464
3465void rtl8192_refresh_supportrate(struct r8192_priv* priv)
3466{
3467	struct ieee80211_device* ieee = priv->ieee80211;
3468	//we donot consider set support rate for ABG mode, only HT MCS rate is set here.
3469	if (ieee->mode == WIRELESS_MODE_N_24G || ieee->mode == WIRELESS_MODE_N_5G)
3470	{
3471		memcpy(ieee->Regdot11HTOperationalRateSet, ieee->RegHTSuppRateSet, 16);
3472		//RT_DEBUG_DATA(COMP_INIT, ieee->RegHTSuppRateSet, 16);
3473		//RT_DEBUG_DATA(COMP_INIT, ieee->Regdot11HTOperationalRateSet, 16);
3474	}
3475	else
3476		memset(ieee->Regdot11HTOperationalRateSet, 0, 16);
3477	return;
3478}
3479
3480u8 rtl8192_getSupportedWireleeMode(struct net_device*dev)
3481{
3482	struct r8192_priv *priv = ieee80211_priv(dev);
3483	u8 ret = 0;
3484	switch(priv->rf_chip)
3485	{
3486		case RF_8225:
3487		case RF_8256:
3488		case RF_PSEUDO_11N:
3489			ret = (WIRELESS_MODE_N_24G|WIRELESS_MODE_G|WIRELESS_MODE_B);
3490			break;
3491		case RF_8258:
3492			ret = (WIRELESS_MODE_A|WIRELESS_MODE_N_5G);
3493			break;
3494		default:
3495			ret = WIRELESS_MODE_B;
3496			break;
3497	}
3498	return ret;
3499}
3500void rtl8192_SetWirelessMode(struct net_device* dev, u8 wireless_mode)
3501{
3502	struct r8192_priv *priv = ieee80211_priv(dev);
3503	u8 bSupportMode = rtl8192_getSupportedWireleeMode(dev);
3504
3505#if 1
3506	if ((wireless_mode == WIRELESS_MODE_AUTO) || ((wireless_mode&bSupportMode)==0))
3507	{
3508		if(bSupportMode & WIRELESS_MODE_N_24G)
3509		{
3510			wireless_mode = WIRELESS_MODE_N_24G;
3511		}
3512		else if(bSupportMode & WIRELESS_MODE_N_5G)
3513		{
3514			wireless_mode = WIRELESS_MODE_N_5G;
3515		}
3516		else if((bSupportMode & WIRELESS_MODE_A))
3517		{
3518			wireless_mode = WIRELESS_MODE_A;
3519		}
3520		else if((bSupportMode & WIRELESS_MODE_G))
3521		{
3522			wireless_mode = WIRELESS_MODE_G;
3523		}
3524		else if((bSupportMode & WIRELESS_MODE_B))
3525		{
3526			wireless_mode = WIRELESS_MODE_B;
3527		}
3528		else{
3529			RT_TRACE(COMP_ERR, "%s(), No valid wireless mode supported, SupportedWirelessMode(%x)!!!\n", __FUNCTION__,bSupportMode);
3530			wireless_mode = WIRELESS_MODE_B;
3531		}
3532	}
3533#ifdef TO_DO_LIST //// TODO: this function doesn't work well at this time, we shoud wait for FPGA
3534	ActUpdateChannelAccessSetting( pAdapter, pHalData->CurrentWirelessMode, &pAdapter->MgntInfo.Info8185.ChannelAccessSetting );
3535#endif
3536	priv->ieee80211->mode = wireless_mode;
3537
3538	if ((wireless_mode == WIRELESS_MODE_N_24G) ||  (wireless_mode == WIRELESS_MODE_N_5G))
3539		priv->ieee80211->pHTInfo->bEnableHT = 1;
3540	else
3541		priv->ieee80211->pHTInfo->bEnableHT = 0;
3542	RT_TRACE(COMP_INIT, "Current Wireless Mode is %x\n", wireless_mode);
3543	rtl8192_refresh_supportrate(priv);
3544#endif
3545
3546}
3547//init priv variables here. only non_zero value should be initialized here.
3548static void rtl8192_init_priv_variable(struct net_device* dev)
3549{
3550	struct r8192_priv *priv = ieee80211_priv(dev);
3551	u8 i;
3552	priv->card_8192 = NIC_8192U;
3553	priv->chan = 1; //set to channel 1
3554	priv->ieee80211->mode = WIRELESS_MODE_AUTO; //SET AUTO
3555	priv->ieee80211->iw_mode = IW_MODE_INFRA;
3556	priv->ieee80211->ieee_up=0;
3557	priv->retry_rts = DEFAULT_RETRY_RTS;
3558	priv->retry_data = DEFAULT_RETRY_DATA;
3559	priv->ieee80211->rts = DEFAULT_RTS_THRESHOLD;
3560	priv->ieee80211->rate = 110; //11 mbps
3561	priv->ieee80211->short_slot = 1;
3562	priv->promisc = (dev->flags & IFF_PROMISC) ? 1:0;
3563	priv->CckPwEnl = 6;
3564	//for silent reset
3565	priv->IrpPendingCount = 1;
3566	priv->ResetProgress = RESET_TYPE_NORESET;
3567	priv->bForcedSilentReset = 0;
3568	priv->bDisableNormalResetCheck = false;
3569	priv->force_reset = false;
3570
3571	priv->ieee80211->FwRWRF = 0; 	//we don't use FW read/write RF until stable firmware is available.
3572	priv->ieee80211->current_network.beacon_interval = DEFAULT_BEACONINTERVAL;
3573	priv->ieee80211->iw_mode = IW_MODE_INFRA;
3574	priv->ieee80211->softmac_features  = IEEE_SOFTMAC_SCAN |
3575		IEEE_SOFTMAC_ASSOCIATE | IEEE_SOFTMAC_PROBERQ |
3576		IEEE_SOFTMAC_PROBERS | IEEE_SOFTMAC_TX_QUEUE |
3577		IEEE_SOFTMAC_BEACONS;//added by amy 080604 //|  //IEEE_SOFTMAC_SINGLE_QUEUE;
3578
3579	priv->ieee80211->active_scan = 1;
3580	priv->ieee80211->modulation = IEEE80211_CCK_MODULATION | IEEE80211_OFDM_MODULATION;
3581	priv->ieee80211->host_encrypt = 1;
3582	priv->ieee80211->host_decrypt = 1;
3583	priv->ieee80211->start_send_beacons = NULL;//rtl819xusb_beacon_tx;//-by amy 080604
3584	priv->ieee80211->stop_send_beacons = NULL;//rtl8192_beacon_stop;//-by amy 080604
3585	priv->ieee80211->softmac_hard_start_xmit = rtl8192_hard_start_xmit;
3586	priv->ieee80211->set_chan = rtl8192_set_chan;
3587	priv->ieee80211->link_change = rtl8192_link_change;
3588	priv->ieee80211->softmac_data_hard_start_xmit = rtl8192_hard_data_xmit;
3589	priv->ieee80211->data_hard_stop = rtl8192_data_hard_stop;
3590	priv->ieee80211->data_hard_resume = rtl8192_data_hard_resume;
3591	priv->ieee80211->init_wmmparam_flag = 0;
3592	priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD;
3593	priv->ieee80211->check_nic_enough_desc = check_nic_enough_desc;
3594	priv->ieee80211->tx_headroom = TX_PACKET_SHIFT_BYTES;
3595	priv->ieee80211->qos_support = 1;
3596
3597	//added by WB
3598//	priv->ieee80211->SwChnlByTimerHandler = rtl8192_phy_SwChnl;
3599	priv->ieee80211->SetBWModeHandler = rtl8192_SetBWMode;
3600	priv->ieee80211->handle_assoc_response = rtl8192_handle_assoc_response;
3601	priv->ieee80211->handle_beacon = rtl8192_handle_beacon;
3602	//added by david
3603	priv->ieee80211->GetNmodeSupportBySecCfg = GetNmodeSupportBySecCfg8192;
3604	priv->ieee80211->GetHalfNmodeSupportByAPsHandler = GetHalfNmodeSupportByAPs819xUsb;
3605	priv->ieee80211->SetWirelessMode = rtl8192_SetWirelessMode;
3606	//added by amy
3607	priv->ieee80211->InitialGainHandler = InitialGain819xUsb;
3608	priv->card_type = USB;
3609#ifdef TO_DO_LIST
3610	if(Adapter->bInHctTest)
3611  	{
3612		pHalData->ShortRetryLimit = 7;
3613		pHalData->LongRetryLimit = 7;
3614  	}
3615#endif
3616	{
3617		priv->ShortRetryLimit = 0x30;
3618		priv->LongRetryLimit = 0x30;
3619	}
3620	priv->EarlyRxThreshold = 7;
3621	priv->enable_gpio0 = 0;
3622	priv->TransmitConfig =
3623	//	TCR_DurProcMode |	//for RTL8185B, duration setting by HW
3624	//?	TCR_DISReqQsize |
3625                (TCR_MXDMA_2048<<TCR_MXDMA_OFFSET)|  // Max DMA Burst Size per Tx DMA Burst, 7: reservied.
3626		(priv->ShortRetryLimit<<TCR_SRL_OFFSET)|	// Short retry limit
3627		(priv->LongRetryLimit<<TCR_LRL_OFFSET) |	// Long retry limit
3628		(false ? TCR_SAT: 0);	// FALSE: HW provies PLCP length and LENGEXT, TURE: SW proiveds them
3629#ifdef TO_DO_LIST
3630	if(Adapter->bInHctTest)
3631		pHalData->ReceiveConfig	=	pHalData->CSMethod |
3632						RCR_AMF | RCR_ADF |	//RCR_AAP | 	//accept management/data
3633						//guangan200710
3634						RCR_ACF |	//accept control frame for SW AP needs PS-poll, 2005.07.07, by rcnjko.
3635						RCR_AB | RCR_AM | RCR_APM |		//accept BC/MC/UC
3636						RCR_AICV | RCR_ACRC32 | 		//accept ICV/CRC error packet
3637						((u32)7<<RCR_MXDMA_OFFSET) | // Max DMA Burst Size per Rx DMA Burst, 7: unlimited.
3638						(pHalData->EarlyRxThreshold<<RCR_FIFO_OFFSET) | // Rx FIFO Threshold, 7: No Rx threshold.
3639						(pHalData->EarlyRxThreshold == 7 ? RCR_OnlyErlPkt:0);
3640	else
3641
3642#endif
3643	priv->ReceiveConfig	=
3644		RCR_AMF | RCR_ADF |		//accept management/data
3645		RCR_ACF |			//accept control frame for SW AP needs PS-poll, 2005.07.07, by rcnjko.
3646		RCR_AB | RCR_AM | RCR_APM |	//accept BC/MC/UC
3647		//RCR_AICV | RCR_ACRC32 | 	//accept ICV/CRC error packet
3648		((u32)7<<RCR_MXDMA_OFFSET)| // Max DMA Burst Size per Rx DMA Burst, 7: unlimited.
3649		(priv->EarlyRxThreshold<<RX_FIFO_THRESHOLD_SHIFT) | // Rx FIFO Threshold, 7: No Rx threshold.
3650		(priv->EarlyRxThreshold == 7 ? RCR_ONLYERLPKT:0);
3651
3652	priv->AcmControl = 0;
3653	priv->pFirmware = (rt_firmware*)kmalloc(sizeof(rt_firmware), GFP_KERNEL);
3654	if (priv->pFirmware)
3655	memset(priv->pFirmware, 0, sizeof(rt_firmware));
3656
3657	/* rx related queue */
3658        skb_queue_head_init(&priv->rx_queue);
3659	skb_queue_head_init(&priv->skb_queue);
3660
3661	/* Tx related queue */
3662	for(i = 0; i < MAX_QUEUE_SIZE; i++) {
3663		skb_queue_head_init(&priv->ieee80211->skb_waitQ [i]);
3664	}
3665	for(i = 0; i < MAX_QUEUE_SIZE; i++) {
3666		skb_queue_head_init(&priv->ieee80211->skb_aggQ [i]);
3667	}
3668	for(i = 0; i < MAX_QUEUE_SIZE; i++) {
3669		skb_queue_head_init(&priv->ieee80211->skb_drv_aggQ [i]);
3670	}
3671	priv->rf_set_chan = rtl8192_phy_SwChnl;
3672}
3673
3674//init lock here
3675static void rtl8192_init_priv_lock(struct r8192_priv* priv)
3676{
3677	spin_lock_init(&priv->tx_lock);
3678	spin_lock_init(&priv->irq_lock);//added by thomas
3679	//spin_lock_init(&priv->rf_lock);
3680	sema_init(&priv->wx_sem,1);
3681	sema_init(&priv->rf_sem,1);
3682#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16))
3683	sema_init(&priv->mutex, 1);
3684#else
3685	mutex_init(&priv->mutex);
3686#endif
3687}
3688
3689#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
3690extern  void    rtl819x_watchdog_wqcallback(struct work_struct *work);
3691#else
3692extern  void    rtl819x_watchdog_wqcallback(struct net_device *dev);
3693#endif
3694
3695void rtl8192_irq_rx_tasklet(struct r8192_priv *priv);
3696//init tasklet and wait_queue here. only 2.6 above kernel is considered
3697#define DRV_NAME "wlan0"
3698static void rtl8192_init_priv_task(struct net_device* dev)
3699{
3700	struct r8192_priv *priv = ieee80211_priv(dev);
3701
3702#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
3703#ifdef PF_SYNCTHREAD
3704	priv->priv_wq = create_workqueue(DRV_NAME,0);
3705#else
3706	priv->priv_wq = create_workqueue(DRV_NAME);
3707#endif
3708#endif
3709
3710#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
3711	INIT_WORK(&priv->reset_wq, rtl8192_restart);
3712
3713	//INIT_DELAYED_WORK(&priv->watch_dog_wq, hal_dm_watchdog);
3714	INIT_DELAYED_WORK(&priv->watch_dog_wq, rtl819x_watchdog_wqcallback);
3715	INIT_DELAYED_WORK(&priv->txpower_tracking_wq,  dm_txpower_trackingcallback);
3716//	INIT_DELAYED_WORK(&priv->gpio_change_rf_wq,  dm_gpio_change_rf_callback);
3717	INIT_DELAYED_WORK(&priv->rfpath_check_wq,  dm_rf_pathcheck_workitemcallback);
3718	INIT_DELAYED_WORK(&priv->update_beacon_wq, rtl8192_update_beacon);
3719	INIT_DELAYED_WORK(&priv->initialgain_operate_wq, InitialGainOperateWorkItemCallBack);
3720	//INIT_WORK(&priv->SwChnlWorkItem,  rtl8192_SwChnl_WorkItem);
3721	//INIT_WORK(&priv->SetBWModeWorkItem,  rtl8192_SetBWModeWorkItem);
3722	INIT_WORK(&priv->qos_activate, rtl8192_qos_activate);
3723#else
3724#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
3725	tq_init(&priv->reset_wq, (void*)rtl8192_restart, dev);
3726	tq_init(&priv->watch_dog_wq, (void*)rtl819x_watchdog_wqcallback, dev);
3727	tq_init(&priv->txpower_tracking_wq, (void*)dm_txpower_trackingcallback, dev);
3728	tq_init(&priv->rfpath_check_wq, (void*)dm_rf_pathcheck_workitemcallback, dev);
3729	tq_init(&priv->update_beacon_wq, (void*)rtl8192_update_beacon, dev);
3730	//tq_init(&priv->SwChnlWorkItem, (void*) rtl8192_SwChnl_WorkItem, dev);
3731	//tq_init(&priv->SetBWModeWorkItem, (void*)rtl8192_SetBWModeWorkItem, dev);
3732	tq_init(&priv->qos_activate, (void *)rtl8192_qos_activate, dev);
3733#else
3734	INIT_WORK(&priv->reset_wq,(void(*)(void*)) rtl8192_restart,dev);
3735	//INIT_WORK(&priv->watch_dog_wq, (void(*)(void*)) hal_dm_watchdog,dev);
3736	INIT_WORK(&priv->watch_dog_wq, (void(*)(void*)) rtl819x_watchdog_wqcallback,dev);
3737	INIT_WORK(&priv->txpower_tracking_wq, (void(*)(void*)) dm_txpower_trackingcallback,dev);
3738//	INIT_WORK(&priv->gpio_change_rf_wq, (void(*)(void*)) dm_gpio_change_rf_callback,dev);
3739	INIT_WORK(&priv->rfpath_check_wq, (void(*)(void*)) dm_rf_pathcheck_workitemcallback,dev);
3740	INIT_WORK(&priv->update_beacon_wq, (void(*)(void*))rtl8192_update_beacon,dev);
3741	INIT_WORK(&priv->initialgain_operate_wq, (void(*)(void*))InitialGainOperateWorkItemCallBack,dev);
3742	//INIT_WORK(&priv->SwChnlWorkItem, (void(*)(void*)) rtl8192_SwChnl_WorkItem, dev);
3743	//INIT_WORK(&priv->SetBWModeWorkItem, (void(*)(void*)) rtl8192_SetBWModeWorkItem, dev);
3744	INIT_WORK(&priv->qos_activate, (void(*)(void *))rtl8192_qos_activate, dev);
3745#endif
3746#endif
3747
3748	tasklet_init(&priv->irq_rx_tasklet,
3749	     (void(*)(unsigned long))rtl8192_irq_rx_tasklet,
3750	     (unsigned long)priv);
3751}
3752
3753static void rtl8192_get_eeprom_size(struct net_device* dev)
3754{
3755	u16 curCR = 0;
3756	struct r8192_priv *priv = ieee80211_priv(dev);
3757	RT_TRACE(COMP_EPROM, "===========>%s()\n", __FUNCTION__);
3758	curCR = read_nic_word_E(dev,EPROM_CMD);
3759	RT_TRACE(COMP_EPROM, "read from Reg EPROM_CMD(%x):%x\n", EPROM_CMD, curCR);
3760	//whether need I consider BIT5?
3761	priv->epromtype = (curCR & Cmd9346CR_9356SEL) ? EPROM_93c56 : EPROM_93c46;
3762	RT_TRACE(COMP_EPROM, "<===========%s(), epromtype:%d\n", __FUNCTION__, priv->epromtype);
3763}
3764
3765//used to swap endian. as ntohl & htonl are not neccessary to swap endian, so use this instead.
3766static inline u16 endian_swap(u16* data)
3767{
3768	u16 tmp = *data;
3769	*data = (tmp >> 8) | (tmp << 8);
3770	return *data;
3771}
3772static void rtl8192_read_eeprom_info(struct net_device* dev)
3773{
3774	u16 wEPROM_ID = 0;
3775	u8 bMac_Tmp_Addr[6] = {0x00, 0xe0, 0x4c, 0x00, 0x00, 0x02};
3776	u8 bLoad_From_EEPOM = false;
3777	struct r8192_priv *priv = ieee80211_priv(dev);
3778	u16 tmpValue = 0;
3779	RT_TRACE(COMP_EPROM, "===========>%s()\n", __FUNCTION__);
3780	wEPROM_ID = eprom_read(dev, 0); //first read EEPROM ID out;
3781	RT_TRACE(COMP_EPROM, "EEPROM ID is 0x%x\n", wEPROM_ID);
3782
3783	if (wEPROM_ID != RTL8190_EEPROM_ID)
3784	{
3785		RT_TRACE(COMP_ERR, "EEPROM ID is invalid(is 0x%x(should be 0x%x)\n", wEPROM_ID, RTL8190_EEPROM_ID);
3786	}
3787	else
3788		bLoad_From_EEPOM = true;
3789
3790	if (bLoad_From_EEPOM)
3791	{
3792		tmpValue = eprom_read(dev, (EEPROM_VID>>1));
3793		priv->eeprom_vid = endian_swap(&tmpValue);
3794		priv->eeprom_pid = eprom_read(dev, (EEPROM_PID>>1));
3795		tmpValue = eprom_read(dev, (EEPROM_ChannelPlan>>1));
3796		priv->eeprom_ChannelPlan =((tmpValue&0xff00)>>8);
3797		priv->btxpowerdata_readfromEEPORM = true;
3798		priv->eeprom_CustomerID = eprom_read(dev, (EEPROM_Customer_ID>>1)) >>8;
3799	}
3800	else
3801	{
3802		priv->eeprom_vid = 0;
3803		priv->eeprom_pid = 0;
3804		priv->card_8192_version = VERSION_819xU_B;
3805		priv->eeprom_ChannelPlan = 0;
3806		priv->eeprom_CustomerID = 0;
3807	}
3808	RT_TRACE(COMP_EPROM, "vid:0x%4x, pid:0x%4x, CustomID:0x%2x, ChanPlan:0x%x\n", priv->eeprom_vid, priv->eeprom_pid, priv->eeprom_CustomerID, priv->eeprom_ChannelPlan);
3809	//set channelplan from eeprom
3810	priv->ChannelPlan = priv->eeprom_ChannelPlan;
3811	if (bLoad_From_EEPOM)
3812	{
3813		int i;
3814		for (i=0; i<6; i+=2)
3815		{
3816			u16 tmp = 0;
3817			tmp = eprom_read(dev, (u16)((EEPROM_NODE_ADDRESS_BYTE_0 + i)>>1));
3818			*(u16*)(&dev->dev_addr[i]) = tmp;
3819		}
3820	}
3821	else
3822	{
3823		memcpy(dev->dev_addr, bMac_Tmp_Addr, 6);
3824		//should I set IDR0 here?
3825	}
3826	RT_TRACE(COMP_EPROM, "MAC addr:"MAC_FMT"\n", MAC_ARG(dev->dev_addr));
3827	priv->rf_type = RTL819X_DEFAULT_RF_TYPE; //default 1T2R
3828	priv->rf_chip = RF_8256;
3829
3830	if (priv->card_8192_version == (u8)VERSION_819xU_A)
3831	{
3832		//read Tx power gain offset of legacy OFDM to HT rate
3833		if (bLoad_From_EEPOM)
3834			priv->EEPROMTxPowerDiff = (eprom_read(dev, (EEPROM_TxPowerDiff>>1))&0xff00) >> 8;
3835		else
3836			priv->EEPROMTxPowerDiff = EEPROM_Default_TxPower;
3837		RT_TRACE(COMP_EPROM, "TxPowerDiff:%d\n", priv->EEPROMTxPowerDiff);
3838		//read ThermalMeter from EEPROM
3839		if (bLoad_From_EEPOM)
3840			priv->EEPROMThermalMeter = (u8)(eprom_read(dev, (EEPROM_ThermalMeter>>1))&0x00ff);
3841		else
3842			priv->EEPROMThermalMeter = EEPROM_Default_ThermalMeter;
3843		RT_TRACE(COMP_EPROM, "ThermalMeter:%d\n", priv->EEPROMThermalMeter);
3844		//vivi, for tx power track
3845		priv->TSSI_13dBm = priv->EEPROMThermalMeter *100;
3846		//read antenna tx power offset of B/C/D to A from EEPROM
3847		if (bLoad_From_EEPOM)
3848			priv->EEPROMPwDiff = (eprom_read(dev, (EEPROM_PwDiff>>1))&0x0f00)>>8;
3849		else
3850			priv->EEPROMPwDiff = EEPROM_Default_PwDiff;
3851		RT_TRACE(COMP_EPROM, "TxPwDiff:%d\n", priv->EEPROMPwDiff);
3852		// Read CrystalCap from EEPROM
3853		if (bLoad_From_EEPOM)
3854			priv->EEPROMCrystalCap = (eprom_read(dev, (EEPROM_CrystalCap>>1))&0x0f);
3855		else
3856			priv->EEPROMCrystalCap = EEPROM_Default_CrystalCap;
3857		RT_TRACE(COMP_EPROM, "CrystalCap = %d\n", priv->EEPROMCrystalCap);
3858		//get per-channel Tx power level
3859		if (bLoad_From_EEPOM)
3860			priv->EEPROM_Def_Ver = (eprom_read(dev, (EEPROM_TxPwIndex_Ver>>1))&0xff00)>>8;
3861		else
3862			priv->EEPROM_Def_Ver = 1;
3863		RT_TRACE(COMP_EPROM, "EEPROM_DEF_VER:%d\n", priv->EEPROM_Def_Ver);
3864		if (priv->EEPROM_Def_Ver == 0) //old eeprom definition
3865		{
3866			int i;
3867			if (bLoad_From_EEPOM)
3868				priv->EEPROMTxPowerLevelCCK = (eprom_read(dev, (EEPROM_TxPwIndex_CCK>>1))&0xff) >> 8;
3869			else
3870				priv->EEPROMTxPowerLevelCCK = 0x10;
3871			RT_TRACE(COMP_EPROM, "CCK Tx Power Levl: 0x%02x\n", priv->EEPROMTxPowerLevelCCK);
3872			for (i=0; i<3; i++)
3873			{
3874				if (bLoad_From_EEPOM)
3875				{
3876					tmpValue = eprom_read(dev, (EEPROM_TxPwIndex_OFDM_24G+i)>>1);
3877					if (((EEPROM_TxPwIndex_OFDM_24G+i) % 2) == 0)
3878						tmpValue = tmpValue & 0x00ff;
3879					else
3880						tmpValue = (tmpValue & 0xff00) >> 8;
3881				}
3882				else
3883					tmpValue = 0x10;
3884				priv->EEPROMTxPowerLevelOFDM24G[i] = (u8) tmpValue;
3885				RT_TRACE(COMP_EPROM, "OFDM 2.4G Tx Power Level, Index %d = 0x%02x\n", i, priv->EEPROMTxPowerLevelCCK);
3886			}
3887		}//end if EEPROM_DEF_VER == 0
3888		else if (priv->EEPROM_Def_Ver == 1)
3889		{
3890			if (bLoad_From_EEPOM)
3891			{
3892				tmpValue = eprom_read(dev, (EEPROM_TxPwIndex_CCK_V1>>1));
3893				tmpValue = (tmpValue & 0xff00) >> 8;
3894			}
3895			else
3896				tmpValue = 0x10;
3897			priv->EEPROMTxPowerLevelCCK_V1[0] = (u8)tmpValue;
3898
3899			if (bLoad_From_EEPOM)
3900				tmpValue = eprom_read(dev, (EEPROM_TxPwIndex_CCK_V1 + 2)>>1);
3901			else
3902				tmpValue = 0x1010;
3903			*((u16*)(&priv->EEPROMTxPowerLevelCCK_V1[1])) = tmpValue;
3904			if (bLoad_From_EEPOM)
3905				tmpValue = eprom_read(dev, (EEPROM_TxPwIndex_OFDM_24G_V1>>1));
3906			else
3907				tmpValue = 0x1010;
3908			*((u16*)(&priv->EEPROMTxPowerLevelOFDM24G[0])) = tmpValue;
3909			if (bLoad_From_EEPOM)
3910				tmpValue = eprom_read(dev, (EEPROM_TxPwIndex_OFDM_24G_V1+2)>>1);
3911			else
3912				tmpValue = 0x10;
3913			priv->EEPROMTxPowerLevelOFDM24G[2] = (u8)tmpValue;
3914		}//endif EEPROM_Def_Ver == 1
3915
3916		//update HAL variables
3917		//
3918		{
3919			int i;
3920			for (i=0; i<14; i++)
3921			{
3922				if (i<=3)
3923					priv->TxPowerLevelOFDM24G[i] = priv->EEPROMTxPowerLevelOFDM24G[0];
3924				else if (i>=4 && i<=9)
3925					priv->TxPowerLevelOFDM24G[i] = priv->EEPROMTxPowerLevelOFDM24G[1];
3926				else
3927					priv->TxPowerLevelOFDM24G[i] = priv->EEPROMTxPowerLevelOFDM24G[2];
3928			}
3929
3930			for (i=0; i<14; i++)
3931			{
3932				if (priv->EEPROM_Def_Ver == 0)
3933				{
3934					if (i<=3)
3935						priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelOFDM24G[0] + (priv->EEPROMTxPowerLevelCCK - priv->EEPROMTxPowerLevelOFDM24G[1]);
3936					else if (i>=4 && i<=9)
3937						priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelCCK;
3938					else
3939						priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelOFDM24G[2] + (priv->EEPROMTxPowerLevelCCK - priv->EEPROMTxPowerLevelOFDM24G[1]);
3940				}
3941				else if (priv->EEPROM_Def_Ver == 1)
3942				{
3943					if (i<=3)
3944						priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelCCK_V1[0];
3945					else if (i>=4 && i<=9)
3946						priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelCCK_V1[1];
3947					else
3948						priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelCCK_V1[2];
3949				}
3950			}
3951		}//end update HAL variables
3952		priv->TxPowerDiff = priv->EEPROMPwDiff;
3953// Antenna B gain offset to antenna A, bit0~3
3954		priv->AntennaTxPwDiff[0] = (priv->EEPROMTxPowerDiff & 0xf);
3955		// Antenna C gain offset to antenna A, bit4~7
3956		priv->AntennaTxPwDiff[1] = ((priv->EEPROMTxPowerDiff & 0xf0)>>4);
3957		// CrystalCap, bit12~15
3958		priv->CrystalCap = priv->EEPROMCrystalCap;
3959		// ThermalMeter, bit0~3 for RFIC1, bit4~7 for RFIC2
3960		// 92U does not enable TX power tracking.
3961		priv->ThermalMeter[0] = priv->EEPROMThermalMeter;
3962	}//end if VersionID == VERSION_819xU_A
3963
3964//added by vivi, for dlink led, 20080416
3965	switch(priv->eeprom_CustomerID)
3966	{
3967		case EEPROM_CID_RUNTOP:
3968			priv->CustomerID = RT_CID_819x_RUNTOP;
3969			break;
3970
3971		case EEPROM_CID_DLINK:
3972			priv->CustomerID = RT_CID_DLINK;
3973			break;
3974
3975		default:
3976			priv->CustomerID = RT_CID_DEFAULT;
3977			break;
3978
3979	}
3980
3981	switch(priv->CustomerID)
3982	{
3983		case RT_CID_819x_RUNTOP:
3984			priv->LedStrategy = SW_LED_MODE2;
3985			break;
3986
3987 		case RT_CID_DLINK:
3988			priv->LedStrategy = SW_LED_MODE4;
3989			break;
3990
3991		default:
3992			priv->LedStrategy = SW_LED_MODE0;
3993			break;
3994
3995	}
3996
3997
3998	if(priv->rf_type == RF_1T2R)
3999	{
4000		RT_TRACE(COMP_EPROM, "\n1T2R config\n");
4001	}
4002	else
4003	{
4004		RT_TRACE(COMP_EPROM, "\n2T4R config\n");
4005	}
4006
4007	// 2008/01/16 MH We can only know RF type in the function. So we have to init
4008	// DIG RATR table again.
4009	init_rate_adaptive(dev);
4010	//we need init DIG RATR table here again.
4011
4012	RT_TRACE(COMP_EPROM, "<===========%s()\n", __FUNCTION__);
4013	return;
4014}
4015
4016short rtl8192_get_channel_map(struct net_device * dev)
4017{
4018	struct r8192_priv *priv = ieee80211_priv(dev);
4019#ifdef ENABLE_DOT11D
4020	if(priv->ChannelPlan > COUNTRY_CODE_GLOBAL_DOMAIN){
4021		printk("rtl8180_init:Error channel plan! Set to default.\n");
4022		priv->ChannelPlan= 0;
4023	}
4024	RT_TRACE(COMP_INIT, "Channel plan is %d\n",priv->ChannelPlan);
4025
4026	rtl819x_set_channel_map(priv->ChannelPlan, priv);
4027#else
4028	int ch,i;
4029	//Set Default Channel Plan
4030	if(!channels){
4031		DMESG("No channels, aborting");
4032		return -1;
4033	}
4034	ch=channels;
4035	priv->ChannelPlan= 0;//hikaru
4036	 // set channels 1..14 allowed in given locale
4037	for (i=1; i<=14; i++) {
4038		(priv->ieee80211->channel_map)[i] = (u8)(ch & 0x01);
4039		ch >>= 1;
4040	}
4041#endif
4042	return 0;
4043}
4044
4045short rtl8192_init(struct net_device *dev)
4046{
4047
4048	struct r8192_priv *priv = ieee80211_priv(dev);
4049
4050	memset(&(priv->stats),0,sizeof(struct Stats));
4051	memset(priv->txqueue_to_outpipemap,0,9);
4052#ifdef PIPE12
4053	{
4054		int i=0;
4055		u8 queuetopipe[]={3,2,1,0,4,8,7,6,5};
4056		memcpy(priv->txqueue_to_outpipemap,queuetopipe,9);
4057/*		for(i=0;i<9;i++)
4058			printk("%d ",priv->txqueue_to_outpipemap[i]);
4059		printk("\n");*/
4060	}
4061#else
4062	{
4063		u8 queuetopipe[]={3,2,1,0,4,4,0,4,4};
4064		memcpy(priv->txqueue_to_outpipemap,queuetopipe,9);
4065/*		for(i=0;i<9;i++)
4066			printk("%d ",priv->txqueue_to_outpipemap[i]);
4067		printk("\n");*/
4068	}
4069#endif
4070	rtl8192_init_priv_variable(dev);
4071	rtl8192_init_priv_lock(priv);
4072	rtl8192_init_priv_task(dev);
4073	rtl8192_get_eeprom_size(dev);
4074	rtl8192_read_eeprom_info(dev);
4075	rtl8192_get_channel_map(dev);
4076	init_hal_dm(dev);
4077	init_timer(&priv->watch_dog_timer);
4078	priv->watch_dog_timer.data = (unsigned long)dev;
4079	priv->watch_dog_timer.function = watch_dog_timer_callback;
4080	if(rtl8192_usb_initendpoints(dev)!=0){
4081		DMESG("Endopoints initialization failed");
4082		return -ENOMEM;
4083	}
4084
4085	//rtl8192_adapter_start(dev);
4086#ifdef DEBUG_EPROM
4087	dump_eprom(dev);
4088#endif
4089	return 0;
4090}
4091
4092/******************************************************************************
4093 *function:  This function actually only set RRSR, RATR and BW_OPMODE registers
4094 *	     not to do all the hw config as its name says
4095 *   input:  net_device dev
4096 *  output:  none
4097 *  return:  none
4098 *  notice:  This part need to modified according to the rate set we filtered
4099 * ****************************************************************************/
4100void rtl8192_hwconfig(struct net_device* dev)
4101{
4102	u32 regRATR = 0, regRRSR = 0;
4103	u8 regBwOpMode = 0, regTmp = 0;
4104	struct r8192_priv *priv = ieee80211_priv(dev);
4105
4106// Set RRSR, RATR, and BW_OPMODE registers
4107	//
4108	switch(priv->ieee80211->mode)
4109	{
4110	case WIRELESS_MODE_B:
4111		regBwOpMode = BW_OPMODE_20MHZ;
4112		regRATR = RATE_ALL_CCK;
4113		regRRSR = RATE_ALL_CCK;
4114		break;
4115	case WIRELESS_MODE_A:
4116		regBwOpMode = BW_OPMODE_5G |BW_OPMODE_20MHZ;
4117		regRATR = RATE_ALL_OFDM_AG;
4118		regRRSR = RATE_ALL_OFDM_AG;
4119		break;
4120	case WIRELESS_MODE_G:
4121		regBwOpMode = BW_OPMODE_20MHZ;
4122		regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
4123		regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
4124		break;
4125	case WIRELESS_MODE_AUTO:
4126#ifdef TO_DO_LIST
4127		if (Adapter->bInHctTest)
4128		{
4129		    regBwOpMode = BW_OPMODE_20MHZ;
4130		    regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
4131		    regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
4132		}
4133		else
4134#endif
4135		{
4136		    regBwOpMode = BW_OPMODE_20MHZ;
4137		    regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
4138		    regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
4139		}
4140		break;
4141	case WIRELESS_MODE_N_24G:
4142		// It support CCK rate by default.
4143		// CCK rate will be filtered out only when associated AP does not support it.
4144		regBwOpMode = BW_OPMODE_20MHZ;
4145			regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
4146			regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
4147		break;
4148	case WIRELESS_MODE_N_5G:
4149		regBwOpMode = BW_OPMODE_5G;
4150		regRATR = RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
4151		regRRSR = RATE_ALL_OFDM_AG;
4152		break;
4153	}
4154
4155	write_nic_byte(dev, BW_OPMODE, regBwOpMode);
4156	{
4157		u32 ratr_value = 0;
4158		ratr_value = regRATR;
4159		if (priv->rf_type == RF_1T2R)
4160		{
4161			ratr_value &= ~(RATE_ALL_OFDM_2SS);
4162		}
4163		write_nic_dword(dev, RATR0, ratr_value);
4164		write_nic_byte(dev, UFWP, 1);
4165	}
4166	regTmp = read_nic_byte(dev, 0x313);
4167	regRRSR = ((regTmp) << 24) | (regRRSR & 0x00ffffff);
4168	write_nic_dword(dev, RRSR, regRRSR);
4169
4170	//
4171	// Set Retry Limit here
4172	//
4173	write_nic_word(dev, RETRY_LIMIT,
4174			priv->ShortRetryLimit << RETRY_LIMIT_SHORT_SHIFT | \
4175			priv->LongRetryLimit << RETRY_LIMIT_LONG_SHIFT);
4176	// Set Contention Window here
4177
4178	// Set Tx AGC
4179
4180	// Set Tx Antenna including Feedback control
4181
4182	// Set Auto Rate fallback control
4183
4184
4185}
4186
4187
4188//InitializeAdapter and PhyCfg
4189bool rtl8192_adapter_start(struct net_device *dev)
4190{
4191	struct r8192_priv *priv = ieee80211_priv(dev);
4192	u32 dwRegRead = 0;
4193	bool init_status = true;
4194	RT_TRACE(COMP_INIT, "====>%s()\n", __FUNCTION__);
4195	priv->Rf_Mode = RF_OP_By_SW_3wire;
4196	//for ASIC power on sequence
4197	write_nic_byte_E(dev, 0x5f, 0x80);
4198	mdelay(50);
4199	write_nic_byte_E(dev, 0x5f, 0xf0);
4200	write_nic_byte_E(dev, 0x5d, 0x00);
4201	write_nic_byte_E(dev, 0x5e, 0x80);
4202	write_nic_byte(dev, 0x17, 0x37);
4203	mdelay(10);
4204//#ifdef TO_DO_LIST
4205	priv->pFirmware->firmware_status = FW_STATUS_0_INIT;
4206	//config CPUReset Register
4207	//Firmware Reset or not?
4208	dwRegRead = read_nic_dword(dev, CPU_GEN);
4209	if (priv->pFirmware->firmware_status == FW_STATUS_0_INIT)
4210		dwRegRead |= CPU_GEN_SYSTEM_RESET; //do nothing here?
4211	else if (priv->pFirmware->firmware_status == FW_STATUS_5_READY)
4212		dwRegRead |= CPU_GEN_FIRMWARE_RESET;
4213	else
4214		RT_TRACE(COMP_ERR, "ERROR in %s(): undefined firmware state(%d)\n", __FUNCTION__,   priv->pFirmware->firmware_status);
4215
4216	write_nic_dword(dev, CPU_GEN, dwRegRead);
4217	//mdelay(30);
4218	//config BB.
4219	rtl8192_BBConfig(dev);
4220
4221#if 1
4222	//Loopback mode or not
4223	priv->LoopbackMode = RTL819xU_NO_LOOPBACK;
4224//	priv->LoopbackMode = RTL819xU_MAC_LOOPBACK;
4225
4226	dwRegRead = read_nic_dword(dev, CPU_GEN);
4227	if (priv->LoopbackMode == RTL819xU_NO_LOOPBACK)
4228		dwRegRead = ((dwRegRead & CPU_GEN_NO_LOOPBACK_MSK) | CPU_GEN_NO_LOOPBACK_SET);
4229	else if (priv->LoopbackMode == RTL819xU_MAC_LOOPBACK)
4230		dwRegRead |= CPU_CCK_LOOPBACK;
4231	else
4232		RT_TRACE(COMP_ERR, "Serious error in %s(): wrong loopback mode setting(%d)\n", __FUNCTION__,  priv->LoopbackMode);
4233
4234	write_nic_dword(dev, CPU_GEN, dwRegRead);
4235
4236	//after reset cpu, we need wait for a seconds to write in register.
4237	udelay(500);
4238
4239	//xiong add for new bitfile:usb suspend reset pin set to 1. //do we need?
4240	write_nic_byte_E(dev, 0x5f, (read_nic_byte_E(dev, 0x5f)|0x20));
4241
4242	//Set Hardware
4243	rtl8192_hwconfig(dev);
4244
4245	//turn on Tx/Rx
4246	write_nic_byte(dev, CMDR, CR_RE|CR_TE);
4247
4248	//set IDR0 here
4249	write_nic_dword(dev, MAC0, ((u32*)dev->dev_addr)[0]);
4250	write_nic_word(dev, MAC4, ((u16*)(dev->dev_addr + 4))[0]);
4251
4252	//set RCR
4253	write_nic_dword(dev, RCR, priv->ReceiveConfig);
4254
4255	//Initialize Number of Reserved Pages in Firmware Queue
4256	write_nic_dword(dev, RQPN1,  NUM_OF_PAGE_IN_FW_QUEUE_BK << RSVD_FW_QUEUE_PAGE_BK_SHIFT |\
4257						NUM_OF_PAGE_IN_FW_QUEUE_BE << RSVD_FW_QUEUE_PAGE_BE_SHIFT | \
4258						NUM_OF_PAGE_IN_FW_QUEUE_VI << RSVD_FW_QUEUE_PAGE_VI_SHIFT | \
4259						NUM_OF_PAGE_IN_FW_QUEUE_VO <<RSVD_FW_QUEUE_PAGE_VO_SHIFT);
4260	write_nic_dword(dev, RQPN2, NUM_OF_PAGE_IN_FW_QUEUE_MGNT << RSVD_FW_QUEUE_PAGE_MGNT_SHIFT |\
4261						NUM_OF_PAGE_IN_FW_QUEUE_CMD << RSVD_FW_QUEUE_PAGE_CMD_SHIFT);
4262	write_nic_dword(dev, RQPN3, APPLIED_RESERVED_QUEUE_IN_FW| \
4263						NUM_OF_PAGE_IN_FW_QUEUE_BCN<<RSVD_FW_QUEUE_PAGE_BCN_SHIFT
4264//						| NUM_OF_PAGE_IN_FW_QUEUE_PUB<<RSVD_FW_QUEUE_PAGE_PUB_SHIFT
4265						);
4266	write_nic_dword(dev, RATR0+4*7, (RATE_ALL_OFDM_AG | RATE_ALL_CCK));
4267
4268	//Set AckTimeout
4269	// TODO: (it value is only for FPGA version). need to be changed!!2006.12.18, by Emily
4270	write_nic_byte(dev, ACK_TIMEOUT, 0x30);
4271
4272//	RT_TRACE(COMP_INIT, "%s():priv->ResetProgress is %d\n", __FUNCTION__,priv->ResetProgress);
4273	if(priv->ResetProgress == RESET_TYPE_NORESET)
4274	rtl8192_SetWirelessMode(dev, priv->ieee80211->mode);
4275	if(priv->ResetProgress == RESET_TYPE_NORESET){
4276	CamResetAllEntry(dev);
4277	{
4278		u8 SECR_value = 0x0;
4279		SECR_value |= SCR_TxEncEnable;
4280		SECR_value |= SCR_RxDecEnable;
4281		SECR_value |= SCR_NoSKMC;
4282		write_nic_byte(dev, SECR, SECR_value);
4283	}
4284	}
4285
4286	//Beacon related
4287	write_nic_word(dev, ATIMWND, 2);
4288	write_nic_word(dev, BCN_INTERVAL, 100);
4289
4290	{
4291#define DEFAULT_EDCA 0x005e4332
4292		int i;
4293		for (i=0; i<QOS_QUEUE_NUM; i++)
4294		write_nic_dword(dev, WDCAPARA_ADD[i], DEFAULT_EDCA);
4295	}
4296#ifdef USB_RX_AGGREGATION_SUPPORT
4297	//3 For usb rx firmware aggregation control
4298	if(priv->ResetProgress == RESET_TYPE_NORESET)
4299	{
4300		u32 ulValue;
4301		PRT_HIGH_THROUGHPUT	pHTInfo = priv->ieee80211->pHTInfo;
4302		ulValue = (pHTInfo->UsbRxFwAggrEn<<24) | (pHTInfo->UsbRxFwAggrPageNum<<16) |
4303					(pHTInfo->UsbRxFwAggrPacketNum<<8) | (pHTInfo->UsbRxFwAggrTimeout);
4304		/*
4305		 * If usb rx firmware aggregation is enabled,
4306		 * when anyone of three threshold conditions above is reached,
4307		 * firmware will send aggregated packet to driver.
4308		 */
4309		write_nic_dword(dev, 0x1a8, ulValue);
4310		priv->bCurrentRxAggrEnable = true;
4311	}
4312#endif
4313
4314	rtl8192_phy_configmac(dev);
4315
4316	if (priv->card_8192_version == (u8) VERSION_819xU_A)
4317	{
4318		rtl8192_phy_getTxPower(dev);
4319		rtl8192_phy_setTxPower(dev, priv->chan);
4320	}
4321
4322	//Firmware download
4323	init_status = init_firmware(dev);
4324	if(!init_status)
4325	{
4326		RT_TRACE(COMP_ERR,"ERR!!! %s(): Firmware download is failed\n", __FUNCTION__);
4327		return init_status;
4328	}
4329	RT_TRACE(COMP_INIT, "%s():after firmware download\n", __FUNCTION__);
4330	//
4331#ifdef TO_DO_LIST
4332if(Adapter->ResetProgress == RESET_TYPE_NORESET)
4333	{
4334		if(pMgntInfo->RegRfOff == TRUE)
4335		{ // User disable RF via registry.
4336			RT_TRACE((COMP_INIT|COMP_RF), DBG_LOUD, ("InitializeAdapter819xUsb(): Turn off RF for RegRfOff ----------\n"));
4337			MgntActSet_RF_State(Adapter, eRfOff, RF_CHANGE_BY_SW);
4338			// Those action will be discard in MgntActSet_RF_State because off the same state
4339			for(eRFPath = 0; eRFPath <pHalData->NumTotalRFPath; eRFPath++)
4340				PHY_SetRFReg(Adapter, (RF90_RADIO_PATH_E)eRFPath, 0x4, 0xC00, 0x0);
4341		}
4342		else if(pMgntInfo->RfOffReason > RF_CHANGE_BY_PS)
4343		{ // H/W or S/W RF OFF before sleep.
4344			RT_TRACE((COMP_INIT|COMP_RF), DBG_LOUD, ("InitializeAdapter819xUsb(): Turn off RF for RfOffReason(%d) ----------\n", pMgntInfo->RfOffReason));
4345			MgntActSet_RF_State(Adapter, eRfOff, pMgntInfo->RfOffReason);
4346		}
4347		else
4348		{
4349			pHalData->eRFPowerState = eRfOn;
4350			pMgntInfo->RfOffReason = 0;
4351			RT_TRACE((COMP_INIT|COMP_RF), DBG_LOUD, ("InitializeAdapter819xUsb(): RF is on ----------\n"));
4352		}
4353	}
4354	else
4355	{
4356		if(pHalData->eRFPowerState == eRfOff)
4357		{
4358			MgntActSet_RF_State(Adapter, eRfOff, pMgntInfo->RfOffReason);
4359			// Those action will be discard in MgntActSet_RF_State because off the same state
4360			for(eRFPath = 0; eRFPath <pHalData->NumTotalRFPath; eRFPath++)
4361				PHY_SetRFReg(Adapter, (RF90_RADIO_PATH_E)eRFPath, 0x4, 0xC00, 0x0);
4362		}
4363	}
4364#endif
4365	//config RF.
4366	if(priv->ResetProgress == RESET_TYPE_NORESET){
4367	rtl8192_phy_RFConfig(dev);
4368	RT_TRACE(COMP_INIT, "%s():after phy RF config\n", __FUNCTION__);
4369	}
4370
4371
4372	if(priv->ieee80211->FwRWRF)
4373		// We can force firmware to do RF-R/W
4374		priv->Rf_Mode = RF_OP_By_FW;
4375	else
4376		priv->Rf_Mode = RF_OP_By_SW_3wire;
4377
4378
4379	rtl8192_phy_updateInitGain(dev);
4380	/*--set CCK and OFDM Block "ON"--*/
4381	rtl8192_setBBreg(dev, rFPGA0_RFMOD, bCCKEn, 0x1);
4382	rtl8192_setBBreg(dev, rFPGA0_RFMOD, bOFDMEn, 0x1);
4383
4384	if(priv->ResetProgress == RESET_TYPE_NORESET)
4385	{
4386		//if D or C cut
4387		u8 tmpvalue = read_nic_byte(dev, 0x301);
4388		if(tmpvalue ==0x03)
4389		{
4390			priv->bDcut = TRUE;
4391			RT_TRACE(COMP_POWER_TRACKING, "D-cut\n");
4392		}
4393		else
4394		{
4395			priv->bDcut = FALSE;
4396			RT_TRACE(COMP_POWER_TRACKING, "C-cut\n");
4397		}
4398		dm_initialize_txpower_tracking(dev);
4399
4400		if(priv->bDcut == TRUE)
4401		{
4402			u32 i, TempCCk;
4403			u32 tmpRegA= rtl8192_QueryBBReg(dev,rOFDM0_XATxIQImbalance,bMaskDWord);
4404		//	u32 tmpRegC= rtl8192_QueryBBReg(dev,rOFDM0_XCTxIQImbalance,bMaskDWord);
4405			for(i = 0; i<TxBBGainTableLength; i++)
4406			{
4407				if(tmpRegA == priv->txbbgain_table[i].txbbgain_value)
4408				{
4409					priv->rfa_txpowertrackingindex= (u8)i;
4410					priv->rfa_txpowertrackingindex_real= (u8)i;
4411					priv->rfa_txpowertracking_default= priv->rfa_txpowertrackingindex;
4412					break;
4413				}
4414			}
4415
4416			TempCCk = rtl8192_QueryBBReg(dev, rCCK0_TxFilter1, bMaskByte2);
4417
4418			for(i=0 ; i<CCKTxBBGainTableLength ; i++)
4419			{
4420
4421				if(TempCCk == priv->cck_txbbgain_table[i].ccktxbb_valuearray[0])
4422				{
4423					priv->cck_present_attentuation_20Mdefault=(u8) i;
4424					break;
4425				}
4426			}
4427			priv->cck_present_attentuation_40Mdefault= 0;
4428			priv->cck_present_attentuation_difference= 0;
4429			priv->cck_present_attentuation = priv->cck_present_attentuation_20Mdefault;
4430
4431	//		pMgntInfo->bTXPowerTracking = FALSE;//TEMPLY DISABLE
4432		}
4433	}
4434	write_nic_byte(dev, 0x87, 0x0);
4435
4436
4437#endif
4438	return init_status;
4439}
4440
4441/* this configures registers for beacon tx and enables it via
4442 * rtl8192_beacon_tx_enable(). rtl8192_beacon_tx_disable() might
4443 * be used to stop beacon transmission
4444 */
4445#if 0
4446void rtl8192_start_tx_beacon(struct net_device *dev)
4447{
4448	int i;
4449	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
4450	u16 word;
4451	DMESG("Enabling beacon TX");
4452	//write_nic_byte(dev, TX_CONF,0xe6);// TX_CONF
4453	//rtl8192_init_beacon(dev);
4454	//set_nic_txring(dev);
4455//	rtl8192_prepare_beacon(dev);
4456	rtl8192_irq_disable(dev);
4457//	rtl8192_beacon_tx_enable(dev);
4458	rtl8192_set_mode(dev,EPROM_CMD_CONFIG);
4459	//write_nic_byte(dev,0x9d,0x20); //DMA Poll
4460	//write_nic_word(dev,0x7a,0);
4461	//write_nic_word(dev,0x7a,0x8000);
4462
4463
4464	word  = read_nic_word(dev, BcnItv);
4465	word &= ~BcnItv_BcnItv; // clear Bcn_Itv
4466	write_nic_word(dev, BcnItv, word);
4467
4468	write_nic_word(dev, AtimWnd,
4469		       read_nic_word(dev, AtimWnd) &~ AtimWnd_AtimWnd);
4470
4471	word  = read_nic_word(dev, BCN_INTR_ITV);
4472	word &= ~BCN_INTR_ITV_MASK;
4473
4474	//word |= priv->ieee80211->beacon_interval *
4475	//	((priv->txbeaconcount > 1)?(priv->txbeaconcount-1):1);
4476	// FIXME:FIXME check if correct ^^ worked with 0x3e8;
4477
4478	write_nic_word(dev, BCN_INTR_ITV, word);
4479
4480	//write_nic_word(dev,0x2e,0xe002);
4481	//write_nic_dword(dev,0x30,0xb8c7832e);
4482	for(i=0; i<ETH_ALEN; i++)
4483		write_nic_byte(dev, BSSID+i, priv->ieee80211->beacon_cell_ssid[i]);
4484
4485//	rtl8192_update_msr(dev);
4486
4487
4488	//write_nic_byte(dev,CONFIG4,3); /* !!!!!!!!!! */
4489
4490	rtl8192_set_mode(dev, EPROM_CMD_NORMAL);
4491
4492	rtl8192_irq_enable(dev);
4493
4494	/* VV !!!!!!!!!! VV*/
4495	/*
4496	rtl8192_set_mode(dev,EPROM_CMD_CONFIG);
4497	write_nic_byte(dev,0x9d,0x00);
4498	rtl8192_set_mode(dev,EPROM_CMD_NORMAL);
4499*/
4500}
4501#endif
4502/***************************************************************************
4503    -------------------------------NET STUFF---------------------------
4504***************************************************************************/
4505
4506static struct net_device_stats *rtl8192_stats(struct net_device *dev)
4507{
4508	struct r8192_priv *priv = ieee80211_priv(dev);
4509
4510	return &priv->ieee80211->stats;
4511}
4512
4513bool
4514HalTxCheckStuck819xUsb(
4515	struct net_device *dev
4516	)
4517{
4518	struct r8192_priv *priv = ieee80211_priv(dev);
4519	u16 		RegTxCounter = read_nic_word(dev, 0x128);
4520	bool		bStuck = FALSE;
4521	RT_TRACE(COMP_RESET,"%s():RegTxCounter is %d,TxCounter is %d\n",__FUNCTION__,RegTxCounter,priv->TxCounter);
4522	if(priv->TxCounter==RegTxCounter)
4523		bStuck = TRUE;
4524
4525	priv->TxCounter = RegTxCounter;
4526
4527	return bStuck;
4528}
4529
4530/*
4531*	<Assumption: RT_TX_SPINLOCK is acquired.>
4532*	First added: 2006.11.19 by emily
4533*/
4534RESET_TYPE
4535TxCheckStuck(struct net_device *dev)
4536{
4537	struct r8192_priv *priv = ieee80211_priv(dev);
4538	u8			QueueID;
4539//	PRT_TCB			pTcb;
4540//	u8			ResetThreshold;
4541	bool			bCheckFwTxCnt = false;
4542	//unsigned long flags;
4543
4544	//
4545	// Decide Stuch threshold according to current power save mode
4546	//
4547
4548//     RT_TRACE(COMP_RESET, " ==> TxCheckStuck()\n");
4549//	     PlatformAcquireSpinLock(Adapter, RT_TX_SPINLOCK);
4550//	     spin_lock_irqsave(&priv->ieee80211->lock,flags);
4551	     for (QueueID = 0; QueueID<=BEACON_QUEUE;QueueID ++)
4552	     {
4553	     		if(QueueID == TXCMD_QUEUE)
4554		         continue;
4555#if 1
4556#ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
4557			if((skb_queue_len(&priv->ieee80211->skb_waitQ[QueueID]) == 0) && (skb_queue_len(&priv->ieee80211->skb_aggQ[QueueID]) == 0) && (skb_queue_len(&priv->ieee80211->skb_drv_aggQ[QueueID]) == 0))
4558#else
4559		     	if((skb_queue_len(&priv->ieee80211->skb_waitQ[QueueID]) == 0)  && (skb_queue_len(&priv->ieee80211->skb_aggQ[QueueID]) == 0))
4560#endif
4561			 	continue;
4562#endif
4563
4564	             bCheckFwTxCnt = true;
4565	     }
4566//	     PlatformReleaseSpinLock(Adapter, RT_TX_SPINLOCK);
4567//	spin_unlock_irqrestore(&priv->ieee80211->lock,flags);
4568//	RT_TRACE(COMP_RESET,"bCheckFwTxCnt is %d\n",bCheckFwTxCnt);
4569#if 1
4570	if(bCheckFwTxCnt)
4571	{
4572		if(HalTxCheckStuck819xUsb(dev))
4573		{
4574			RT_TRACE(COMP_RESET, "TxCheckStuck(): Fw indicates no Tx condition! \n");
4575			return RESET_TYPE_SILENT;
4576		}
4577	}
4578#endif
4579	return RESET_TYPE_NORESET;
4580}
4581
4582bool
4583HalRxCheckStuck819xUsb(struct net_device *dev)
4584{
4585	u16 	RegRxCounter = read_nic_word(dev, 0x130);
4586	struct r8192_priv *priv = ieee80211_priv(dev);
4587	bool bStuck = FALSE;
4588	static u8	rx_chk_cnt = 0;
4589	RT_TRACE(COMP_RESET,"%s(): RegRxCounter is %d,RxCounter is %d\n",__FUNCTION__,RegRxCounter,priv->RxCounter);
4590	// If rssi is small, we should check rx for long time because of bad rx.
4591	// or maybe it will continuous silent reset every 2 seconds.
4592	rx_chk_cnt++;
4593	if(priv->undecorated_smoothed_pwdb >= (RateAdaptiveTH_High+5))
4594	{
4595		rx_chk_cnt = 0;	//high rssi, check rx stuck right now.
4596	}
4597	else if(priv->undecorated_smoothed_pwdb < (RateAdaptiveTH_High+5) &&
4598		((priv->CurrentChannelBW!=HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb>=RateAdaptiveTH_Low_40M) ||
4599		(priv->CurrentChannelBW==HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb>=RateAdaptiveTH_Low_20M)) )
4600	{
4601		if(rx_chk_cnt < 2)
4602		{
4603			return bStuck;
4604		}
4605		else
4606		{
4607			rx_chk_cnt = 0;
4608		}
4609	}
4610	else if(((priv->CurrentChannelBW!=HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb<RateAdaptiveTH_Low_40M) ||
4611		(priv->CurrentChannelBW==HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb<RateAdaptiveTH_Low_20M)) &&
4612		priv->undecorated_smoothed_pwdb >= VeryLowRSSI)
4613	{
4614		if(rx_chk_cnt < 4)
4615		{
4616			//DbgPrint("RSSI < %d && RSSI >= %d, no check this time \n", RateAdaptiveTH_Low, VeryLowRSSI);
4617			return bStuck;
4618		}
4619		else
4620		{
4621			rx_chk_cnt = 0;
4622			//DbgPrint("RSSI < %d && RSSI >= %d, check this time \n", RateAdaptiveTH_Low, VeryLowRSSI);
4623		}
4624	}
4625	else
4626	{
4627		if(rx_chk_cnt < 8)
4628		{
4629			//DbgPrint("RSSI <= %d, no check this time \n", VeryLowRSSI);
4630			return bStuck;
4631		}
4632		else
4633		{
4634			rx_chk_cnt = 0;
4635			//DbgPrint("RSSI <= %d, check this time \n", VeryLowRSSI);
4636		}
4637	}
4638
4639	if(priv->RxCounter==RegRxCounter)
4640		bStuck = TRUE;
4641
4642	priv->RxCounter = RegRxCounter;
4643
4644	return bStuck;
4645}
4646
4647RESET_TYPE
4648RxCheckStuck(struct net_device *dev)
4649{
4650	struct r8192_priv *priv = ieee80211_priv(dev);
4651	//int                     i;
4652	bool        bRxCheck = FALSE;
4653
4654//       RT_TRACE(COMP_RESET," ==> RxCheckStuck()\n");
4655	//PlatformAcquireSpinLock(Adapter, RT_RX_SPINLOCK);
4656
4657	 if(priv->IrpPendingCount > 1)
4658	 	bRxCheck = TRUE;
4659       //PlatformReleaseSpinLock(Adapter, RT_RX_SPINLOCK);
4660
4661//       RT_TRACE(COMP_RESET,"bRxCheck is %d \n",bRxCheck);
4662	if(bRxCheck)
4663	{
4664		if(HalRxCheckStuck819xUsb(dev))
4665		{
4666			RT_TRACE(COMP_RESET, "RxStuck Condition\n");
4667			return RESET_TYPE_SILENT;
4668		}
4669	}
4670	return RESET_TYPE_NORESET;
4671}
4672
4673
4674/**
4675*	This function is called by Checkforhang to check whether we should ask OS to reset driver
4676*
4677*	\param pAdapter	The adapter context for this miniport
4678*
4679*	Note:NIC with USB interface sholud not call this function because we cannot scan descriptor
4680*	to judge whether there is tx stuck.
4681*	Note: This function may be required to be rewrite for Vista OS.
4682*	<<<Assumption: Tx spinlock has been acquired >>>
4683*
4684*	8185 and 8185b does not implement this function. This is added by Emily at 2006.11.24
4685*/
4686RESET_TYPE
4687rtl819x_ifcheck_resetornot(struct net_device *dev)
4688{
4689	struct r8192_priv *priv = ieee80211_priv(dev);
4690	RESET_TYPE	TxResetType = RESET_TYPE_NORESET;
4691	RESET_TYPE	RxResetType = RESET_TYPE_NORESET;
4692	RT_RF_POWER_STATE 	rfState;
4693
4694	rfState = priv->ieee80211->eRFPowerState;
4695
4696	TxResetType = TxCheckStuck(dev);
4697#if 1
4698	if( rfState != eRfOff ||
4699		/*ADAPTER_TEST_STATUS_FLAG(Adapter, ADAPTER_STATUS_FW_DOWNLOAD_FAILURE)) &&*/
4700		(priv->ieee80211->iw_mode != IW_MODE_ADHOC))
4701	{
4702		// If driver is in the status of firmware download failure , driver skips RF initialization and RF is
4703		// in turned off state. Driver should check whether Rx stuck and do silent reset. And
4704		// if driver is in firmware download failure status, driver should initialize RF in the following
4705		// silent reset procedure Emily, 2008.01.21
4706
4707		// Driver should not check RX stuck in IBSS mode because it is required to
4708		// set Check BSSID in order to send beacon, however, if check BSSID is
4709		// set, STA cannot hear any packet a all. Emily, 2008.04.12
4710		RxResetType = RxCheckStuck(dev);
4711	}
4712#endif
4713	if(TxResetType==RESET_TYPE_NORMAL || RxResetType==RESET_TYPE_NORMAL)
4714		return RESET_TYPE_NORMAL;
4715	else if(TxResetType==RESET_TYPE_SILENT || RxResetType==RESET_TYPE_SILENT){
4716		RT_TRACE(COMP_RESET,"%s():silent reset\n",__FUNCTION__);
4717		return RESET_TYPE_SILENT;
4718	}
4719	else
4720		return RESET_TYPE_NORESET;
4721
4722}
4723
4724void rtl8192_cancel_deferred_work(struct r8192_priv* priv);
4725int _rtl8192_up(struct net_device *dev);
4726int rtl8192_close(struct net_device *dev);
4727
4728
4729
4730void
4731CamRestoreAllEntry(	struct net_device *dev)
4732{
4733	u8 EntryId = 0;
4734	struct r8192_priv *priv = ieee80211_priv(dev);
4735	u8*	MacAddr = priv->ieee80211->current_network.bssid;
4736
4737	static u8	CAM_CONST_ADDR[4][6] = {
4738		{0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
4739		{0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
4740		{0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
4741		{0x00, 0x00, 0x00, 0x00, 0x00, 0x03}};
4742	static u8	CAM_CONST_BROAD[] =
4743		{0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
4744
4745	RT_TRACE(COMP_SEC, "CamRestoreAllEntry: \n");
4746
4747
4748	if ((priv->ieee80211->pairwise_key_type == KEY_TYPE_WEP40)||
4749	    (priv->ieee80211->pairwise_key_type == KEY_TYPE_WEP104))
4750	{
4751
4752		for(EntryId=0; EntryId<4; EntryId++)
4753		{
4754			{
4755				MacAddr = CAM_CONST_ADDR[EntryId];
4756				setKey(dev,
4757						EntryId ,
4758						EntryId,
4759						priv->ieee80211->pairwise_key_type,
4760						MacAddr,
4761						0,
4762						NULL);
4763			}
4764		}
4765
4766	}
4767	else if(priv->ieee80211->pairwise_key_type == KEY_TYPE_TKIP)
4768	{
4769
4770		{
4771			if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
4772				setKey(dev,
4773						4,
4774						0,
4775						priv->ieee80211->pairwise_key_type,
4776						(u8*)dev->dev_addr,
4777						0,
4778						NULL);
4779			else
4780				setKey(dev,
4781						4,
4782						0,
4783						priv->ieee80211->pairwise_key_type,
4784						MacAddr,
4785						0,
4786						NULL);
4787		}
4788	}
4789	else if(priv->ieee80211->pairwise_key_type == KEY_TYPE_CCMP)
4790	{
4791
4792		{
4793			if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
4794				setKey(dev,
4795						4,
4796						0,
4797						priv->ieee80211->pairwise_key_type,
4798						(u8*)dev->dev_addr,
4799						0,
4800						NULL);
4801			else
4802				setKey(dev,
4803						4,
4804						0,
4805						priv->ieee80211->pairwise_key_type,
4806						MacAddr,
4807						0,
4808						NULL);
4809		}
4810	}
4811
4812
4813
4814	if(priv->ieee80211->group_key_type == KEY_TYPE_TKIP)
4815	{
4816		MacAddr = CAM_CONST_BROAD;
4817		for(EntryId=1 ; EntryId<4 ; EntryId++)
4818		{
4819			{
4820				setKey(dev,
4821						EntryId,
4822						EntryId,
4823						priv->ieee80211->group_key_type,
4824						MacAddr,
4825						0,
4826						NULL);
4827			}
4828		}
4829		if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
4830				setKey(dev,
4831						0,
4832						0,
4833						priv->ieee80211->group_key_type,
4834						CAM_CONST_ADDR[0],
4835						0,
4836						NULL);
4837	}
4838	else if(priv->ieee80211->group_key_type == KEY_TYPE_CCMP)
4839	{
4840		MacAddr = CAM_CONST_BROAD;
4841		for(EntryId=1; EntryId<4 ; EntryId++)
4842		{
4843			{
4844				setKey(dev,
4845						EntryId ,
4846						EntryId,
4847						priv->ieee80211->group_key_type,
4848						MacAddr,
4849						0,
4850						NULL);
4851			}
4852		}
4853
4854		if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
4855				setKey(dev,
4856						0 ,
4857						0,
4858						priv->ieee80211->group_key_type,
4859						CAM_CONST_ADDR[0],
4860						0,
4861						NULL);
4862	}
4863}
4864//////////////////////////////////////////////////////////////
4865// This function is used to fix Tx/Rx stop bug temporarily.
4866// This function will do "system reset" to NIC when Tx or Rx is stuck.
4867// The method checking Tx/Rx stuck of this function is supported by FW,
4868// which reports Tx and Rx counter to register 0x128 and 0x130.
4869//////////////////////////////////////////////////////////////
4870void
4871rtl819x_ifsilentreset(struct net_device *dev)
4872{
4873	//OCTET_STRING asocpdu;
4874	struct r8192_priv *priv = ieee80211_priv(dev);
4875	u8	reset_times = 0;
4876	int reset_status = 0;
4877	struct ieee80211_device *ieee = priv->ieee80211;
4878
4879
4880	// 2007.07.20. If we need to check CCK stop, please uncomment this line.
4881	//bStuck = Adapter->HalFunc.CheckHWStopHandler(Adapter);
4882
4883	if(priv->ResetProgress==RESET_TYPE_NORESET)
4884	{
4885RESET_START:
4886
4887		RT_TRACE(COMP_RESET,"=========>Reset progress!! \n");
4888
4889		// Set the variable for reset.
4890		priv->ResetProgress = RESET_TYPE_SILENT;
4891//		rtl8192_close(dev);
4892#if 1
4893		down(&priv->wx_sem);
4894		if(priv->up == 0)
4895		{
4896			RT_TRACE(COMP_ERR,"%s():the driver is not up! return\n",__FUNCTION__);
4897			up(&priv->wx_sem);
4898			return ;
4899		}
4900		priv->up = 0;
4901		RT_TRACE(COMP_RESET,"%s():======>start to down the driver\n",__FUNCTION__);
4902//		if(!netif_queue_stopped(dev))
4903//			netif_stop_queue(dev);
4904
4905		rtl8192_rtx_disable(dev);
4906		rtl8192_cancel_deferred_work(priv);
4907		deinit_hal_dm(dev);
4908		del_timer_sync(&priv->watch_dog_timer);
4909
4910		ieee->sync_scan_hurryup = 1;
4911		if(ieee->state == IEEE80211_LINKED)
4912		{
4913			down(&ieee->wx_sem);
4914			printk("ieee->state is IEEE80211_LINKED\n");
4915			ieee80211_stop_send_beacons(priv->ieee80211);
4916			del_timer_sync(&ieee->associate_timer);
4917			#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
4918			cancel_delayed_work(&ieee->associate_retry_wq);
4919			#endif
4920			ieee80211_stop_scan(ieee);
4921			netif_carrier_off(dev);
4922			up(&ieee->wx_sem);
4923		}
4924		else{
4925			printk("ieee->state is NOT LINKED\n");
4926			ieee80211_softmac_stop_protocol(priv->ieee80211);			}
4927		up(&priv->wx_sem);
4928		RT_TRACE(COMP_RESET,"%s():<==========down process is finished\n",__FUNCTION__);
4929	//rtl8192_irq_disable(dev);
4930		RT_TRACE(COMP_RESET,"%s():===========>start to up the driver\n",__FUNCTION__);
4931		reset_status = _rtl8192_up(dev);
4932
4933		RT_TRACE(COMP_RESET,"%s():<===========up process is finished\n",__FUNCTION__);
4934		if(reset_status == -EAGAIN)
4935		{
4936			if(reset_times < 3)
4937			{
4938				reset_times++;
4939				goto RESET_START;
4940			}
4941			else
4942			{
4943				RT_TRACE(COMP_ERR," ERR!!! %s():  Reset Failed!!\n", __FUNCTION__);
4944			}
4945		}
4946#endif
4947		ieee->is_silent_reset = 1;
4948#if 1
4949		EnableHWSecurityConfig8192(dev);
4950#if 1
4951		if(ieee->state == IEEE80211_LINKED && ieee->iw_mode == IW_MODE_INFRA)
4952		{
4953			ieee->set_chan(ieee->dev, ieee->current_network.channel);
4954
4955#if 1
4956#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
4957			queue_work(ieee->wq, &ieee->associate_complete_wq);
4958#else
4959			schedule_task(&ieee->associate_complete_wq);
4960#endif
4961#endif
4962
4963		}
4964		else if(ieee->state == IEEE80211_LINKED && ieee->iw_mode == IW_MODE_ADHOC)
4965		{
4966			ieee->set_chan(ieee->dev, ieee->current_network.channel);
4967			ieee->link_change(ieee->dev);
4968
4969		//	notify_wx_assoc_event(ieee);
4970
4971			ieee80211_start_send_beacons(ieee);
4972
4973			if (ieee->data_hard_resume)
4974				ieee->data_hard_resume(ieee->dev);
4975			netif_carrier_on(ieee->dev);
4976		}
4977#endif
4978
4979		CamRestoreAllEntry(dev);
4980
4981		priv->ResetProgress = RESET_TYPE_NORESET;
4982		priv->reset_count++;
4983
4984		priv->bForcedSilentReset =false;
4985		priv->bResetInProgress = false;
4986
4987		// For test --> force write UFWP.
4988		write_nic_byte(dev, UFWP, 1);
4989		RT_TRACE(COMP_RESET, "Reset finished!! ====>[%d]\n", priv->reset_count);
4990#endif
4991	}
4992}
4993
4994void CAM_read_entry(
4995	struct net_device *dev,
4996	u32	 		iIndex
4997)
4998{
4999 	u32 target_command=0;
5000	 u32 target_content=0;
5001	 u8 entry_i=0;
5002	 u32 ulStatus;
5003	s32 i=100;
5004//	printk("=======>start read CAM\n");
5005 	for(entry_i=0;entry_i<CAM_CONTENT_COUNT;entry_i++)
5006 	{
5007   	// polling bit, and No Write enable, and address
5008		target_command= entry_i+CAM_CONTENT_COUNT*iIndex;
5009		target_command= target_command | BIT31;
5010
5011	//Check polling bit is clear
5012//	mdelay(1);
5013#if 1
5014		while((i--)>=0)
5015		{
5016			ulStatus = read_nic_dword(dev, RWCAM);
5017			if(ulStatus & BIT31){
5018				continue;
5019			}
5020			else{
5021				break;
5022			}
5023		}
5024#endif
5025  		write_nic_dword(dev, RWCAM, target_command);
5026   	 	RT_TRACE(COMP_SEC,"CAM_read_entry(): WRITE A0: %x \n",target_command);
5027   	 //	printk("CAM_read_entry(): WRITE A0: %lx \n",target_command);
5028  	 	target_content = read_nic_dword(dev, RCAMO);
5029  	 	RT_TRACE(COMP_SEC, "CAM_read_entry(): WRITE A8: %x \n",target_content);
5030  	 //	printk("CAM_read_entry(): WRITE A8: %lx \n",target_content);
5031 	}
5032	printk("\n");
5033}
5034
5035void rtl819x_update_rxcounts(
5036	struct r8192_priv *priv,
5037	u32* TotalRxBcnNum,
5038	u32* TotalRxDataNum
5039)
5040{
5041	u16 			SlotIndex;
5042	u8			i;
5043
5044	*TotalRxBcnNum = 0;
5045	*TotalRxDataNum = 0;
5046
5047	SlotIndex = (priv->ieee80211->LinkDetectInfo.SlotIndex++)%(priv->ieee80211->LinkDetectInfo.SlotNum);
5048	priv->ieee80211->LinkDetectInfo.RxBcnNum[SlotIndex] = priv->ieee80211->LinkDetectInfo.NumRecvBcnInPeriod;
5049	priv->ieee80211->LinkDetectInfo.RxDataNum[SlotIndex] = priv->ieee80211->LinkDetectInfo.NumRecvDataInPeriod;
5050	for( i=0; i<priv->ieee80211->LinkDetectInfo.SlotNum; i++ ){
5051		*TotalRxBcnNum += priv->ieee80211->LinkDetectInfo.RxBcnNum[i];
5052		*TotalRxDataNum += priv->ieee80211->LinkDetectInfo.RxDataNum[i];
5053	}
5054}
5055
5056
5057#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
5058extern	void	rtl819x_watchdog_wqcallback(struct work_struct *work)
5059{
5060	struct delayed_work *dwork = container_of(work,struct delayed_work,work);
5061       struct r8192_priv *priv = container_of(dwork,struct r8192_priv,watch_dog_wq);
5062       struct net_device *dev = priv->ieee80211->dev;
5063#else
5064extern	void	rtl819x_watchdog_wqcallback(struct net_device *dev)
5065{
5066	struct r8192_priv *priv = ieee80211_priv(dev);
5067#endif
5068	struct ieee80211_device* ieee = priv->ieee80211;
5069	RESET_TYPE	ResetType = RESET_TYPE_NORESET;
5070      	static u8	check_reset_cnt=0;
5071	bool bBusyTraffic = false;
5072
5073	if(!priv->up)
5074		return;
5075	hal_dm_watchdog(dev);
5076
5077	{//to get busy traffic condition
5078		if(ieee->state == IEEE80211_LINKED)
5079		{
5080			if(	ieee->LinkDetectInfo.NumRxOkInPeriod> 666 ||
5081				ieee->LinkDetectInfo.NumTxOkInPeriod> 666 ) {
5082				bBusyTraffic = true;
5083			}
5084			ieee->LinkDetectInfo.NumRxOkInPeriod = 0;
5085			ieee->LinkDetectInfo.NumTxOkInPeriod = 0;
5086			ieee->LinkDetectInfo.bBusyTraffic = bBusyTraffic;
5087		}
5088	}
5089	//added by amy for AP roaming
5090	{
5091		if(priv->ieee80211->state == IEEE80211_LINKED && priv->ieee80211->iw_mode == IW_MODE_INFRA)
5092		{
5093			u32	TotalRxBcnNum = 0;
5094			u32	TotalRxDataNum = 0;
5095
5096			rtl819x_update_rxcounts(priv, &TotalRxBcnNum, &TotalRxDataNum);
5097			if((TotalRxBcnNum+TotalRxDataNum) == 0)
5098			{
5099				#ifdef TODO
5100				if(rfState == eRfOff)
5101					RT_TRACE(COMP_ERR,"========>%s()\n",__FUNCTION__);
5102				#endif
5103				printk("===>%s(): AP is power off,connect another one\n",__FUNCTION__);
5104			//	Dot11d_Reset(dev);
5105				priv->ieee80211->state = IEEE80211_ASSOCIATING;
5106				notify_wx_assoc_event(priv->ieee80211);
5107				RemovePeerTS(priv->ieee80211,priv->ieee80211->current_network.bssid);
5108				priv->ieee80211->link_change(dev);
5109#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
5110                                queue_work(priv->ieee80211->wq, &priv->ieee80211->associate_procedure_wq);
5111#else
5112                                schedule_task(&priv->ieee80211->associate_procedure_wq);
5113#endif
5114
5115			}
5116		}
5117		priv->ieee80211->LinkDetectInfo.NumRecvBcnInPeriod=0;
5118		priv->ieee80211->LinkDetectInfo.NumRecvDataInPeriod=0;
5119	}
5120//	CAM_read_entry(dev,4);
5121	//check if reset the driver
5122	if(check_reset_cnt++ >= 3)
5123	{
5124    		ResetType = rtl819x_ifcheck_resetornot(dev);
5125		check_reset_cnt = 3;
5126		//DbgPrint("Start to check silent reset\n");
5127	}
5128	//	RT_TRACE(COMP_RESET,"%s():priv->force_reset is %d,priv->ResetProgress is %d, priv->bForcedSilentReset is %d,priv->bDisableNormalResetCheck is %d,ResetType is %d\n",__FUNCTION__,priv->force_reset,priv->ResetProgress,priv->bForcedSilentReset,priv->bDisableNormalResetCheck,ResetType);
5129#if 1
5130	if( (priv->force_reset) || (priv->ResetProgress==RESET_TYPE_NORESET &&
5131		(priv->bForcedSilentReset ||
5132		(!priv->bDisableNormalResetCheck && ResetType==RESET_TYPE_SILENT)))) // This is control by OID set in Pomelo
5133	{
5134		RT_TRACE(COMP_RESET,"%s():priv->force_reset is %d,priv->ResetProgress is %d, priv->bForcedSilentReset is %d,priv->bDisableNormalResetCheck is %d,ResetType is %d\n",__FUNCTION__,priv->force_reset,priv->ResetProgress,priv->bForcedSilentReset,priv->bDisableNormalResetCheck,ResetType);
5135		rtl819x_ifsilentreset(dev);
5136	}
5137#endif
5138	priv->force_reset = false;
5139	priv->bForcedSilentReset = false;
5140	priv->bResetInProgress = false;
5141	RT_TRACE(COMP_TRACE, " <==RtUsbCheckForHangWorkItemCallback()\n");
5142
5143}
5144
5145void watch_dog_timer_callback(unsigned long data)
5146{
5147	struct r8192_priv *priv = ieee80211_priv((struct net_device *) data);
5148	//printk("===============>watch_dog  timer\n");
5149#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
5150	queue_delayed_work(priv->priv_wq,&priv->watch_dog_wq, 0);
5151#else
5152#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
5153	schedule_task(&priv->watch_dog_wq);
5154#else
5155	queue_work(priv->priv_wq,&priv->watch_dog_wq);
5156#endif
5157#endif
5158	mod_timer(&priv->watch_dog_timer, jiffies + MSECS(IEEE80211_WATCH_DOG_TIME));
5159#if 0
5160	priv->watch_dog_timer.expires = jiffies + MSECS(IEEE80211_WATCH_DOG_TIME);
5161	add_timer(&priv->watch_dog_timer);
5162#endif
5163}
5164int _rtl8192_up(struct net_device *dev)
5165{
5166	struct r8192_priv *priv = ieee80211_priv(dev);
5167	//int i;
5168	int init_status = 0;
5169	priv->up=1;
5170	priv->ieee80211->ieee_up=1;
5171	RT_TRACE(COMP_INIT, "Bringing up iface");
5172	init_status = rtl8192_adapter_start(dev);
5173	if(!init_status)
5174	{
5175		RT_TRACE(COMP_ERR,"ERR!!! %s(): initialization is failed!\n", __FUNCTION__);
5176		priv->up=priv->ieee80211->ieee_up = 0;
5177		return -EAGAIN;
5178	}
5179	RT_TRACE(COMP_INIT, "start adapter finished\n");
5180	rtl8192_rx_enable(dev);
5181//	rtl8192_tx_enable(dev);
5182	if(priv->ieee80211->state != IEEE80211_LINKED)
5183	ieee80211_softmac_start_protocol(priv->ieee80211);
5184	ieee80211_reset_queue(priv->ieee80211);
5185	watch_dog_timer_callback((unsigned long) dev);
5186	if(!netif_queue_stopped(dev))
5187		netif_start_queue(dev);
5188	else
5189		netif_wake_queue(dev);
5190
5191	return 0;
5192}
5193
5194
5195int rtl8192_open(struct net_device *dev)
5196{
5197	struct r8192_priv *priv = ieee80211_priv(dev);
5198	int ret;
5199	down(&priv->wx_sem);
5200	ret = rtl8192_up(dev);
5201	up(&priv->wx_sem);
5202	return ret;
5203
5204}
5205
5206
5207int rtl8192_up(struct net_device *dev)
5208{
5209	struct r8192_priv *priv = ieee80211_priv(dev);
5210
5211	if (priv->up == 1) return -1;
5212
5213	return _rtl8192_up(dev);
5214}
5215
5216
5217int rtl8192_close(struct net_device *dev)
5218{
5219	struct r8192_priv *priv = ieee80211_priv(dev);
5220	int ret;
5221
5222	down(&priv->wx_sem);
5223
5224	ret = rtl8192_down(dev);
5225
5226	up(&priv->wx_sem);
5227
5228	return ret;
5229
5230}
5231
5232int rtl8192_down(struct net_device *dev)
5233{
5234	struct r8192_priv *priv = ieee80211_priv(dev);
5235	int i;
5236
5237	if (priv->up == 0) return -1;
5238
5239	priv->up=0;
5240	priv->ieee80211->ieee_up = 0;
5241	RT_TRACE(COMP_DOWN, "==========>%s()\n", __FUNCTION__);
5242/* FIXME */
5243	if (!netif_queue_stopped(dev))
5244		netif_stop_queue(dev);
5245
5246	rtl8192_rtx_disable(dev);
5247	//rtl8192_irq_disable(dev);
5248
5249 /* Tx related queue release */
5250        for(i = 0; i < MAX_QUEUE_SIZE; i++) {
5251                skb_queue_purge(&priv->ieee80211->skb_waitQ [i]);
5252        }
5253        for(i = 0; i < MAX_QUEUE_SIZE; i++) {
5254                skb_queue_purge(&priv->ieee80211->skb_aggQ [i]);
5255        }
5256
5257        for(i = 0; i < MAX_QUEUE_SIZE; i++) {
5258                skb_queue_purge(&priv->ieee80211->skb_drv_aggQ [i]);
5259        }
5260
5261        //as cancel_delayed_work will del work->timer, so if work is not definedas struct delayed_work, it will corrupt
5262//	flush_scheduled_work();
5263	rtl8192_cancel_deferred_work(priv);
5264	deinit_hal_dm(dev);
5265	del_timer_sync(&priv->watch_dog_timer);
5266
5267
5268	ieee80211_softmac_stop_protocol(priv->ieee80211);
5269	memset(&priv->ieee80211->current_network, 0 , offsetof(struct ieee80211_network, list));
5270	RT_TRACE(COMP_DOWN, "<==========%s()\n", __FUNCTION__);
5271
5272		return 0;
5273}
5274
5275
5276void rtl8192_commit(struct net_device *dev)
5277{
5278	struct r8192_priv *priv = ieee80211_priv(dev);
5279	int reset_status = 0;
5280	//u8 reset_times = 0;
5281	if (priv->up == 0) return ;
5282	priv->up = 0;
5283
5284	rtl8192_cancel_deferred_work(priv);
5285	del_timer_sync(&priv->watch_dog_timer);
5286	//cancel_delayed_work(&priv->SwChnlWorkItem);
5287
5288	ieee80211_softmac_stop_protocol(priv->ieee80211);
5289
5290	//rtl8192_irq_disable(dev);
5291	rtl8192_rtx_disable(dev);
5292	reset_status = _rtl8192_up(dev);
5293
5294}
5295
5296/*
5297void rtl8192_restart(struct net_device *dev)
5298{
5299	struct r8192_priv *priv = ieee80211_priv(dev);
5300*/
5301#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
5302void rtl8192_restart(struct work_struct *work)
5303{
5304        struct r8192_priv *priv = container_of(work, struct r8192_priv, reset_wq);
5305        struct net_device *dev = priv->ieee80211->dev;
5306#else
5307void rtl8192_restart(struct net_device *dev)
5308{
5309
5310        struct r8192_priv *priv = ieee80211_priv(dev);
5311#endif
5312
5313	down(&priv->wx_sem);
5314
5315	rtl8192_commit(dev);
5316
5317	up(&priv->wx_sem);
5318}
5319
5320static void r8192_set_multicast(struct net_device *dev)
5321{
5322	struct r8192_priv *priv = ieee80211_priv(dev);
5323	short promisc;
5324
5325	//down(&priv->wx_sem);
5326
5327	/* FIXME FIXME */
5328
5329	promisc = (dev->flags & IFF_PROMISC) ? 1:0;
5330
5331	if (promisc != priv->promisc)
5332	//	rtl8192_commit(dev);
5333
5334	priv->promisc = promisc;
5335
5336	//schedule_work(&priv->reset_wq);
5337	//up(&priv->wx_sem);
5338}
5339
5340
5341int r8192_set_mac_adr(struct net_device *dev, void *mac)
5342{
5343	struct r8192_priv *priv = ieee80211_priv(dev);
5344	struct sockaddr *addr = mac;
5345
5346	down(&priv->wx_sem);
5347
5348	memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
5349
5350#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
5351	schedule_work(&priv->reset_wq);
5352#else
5353	schedule_task(&priv->reset_wq);
5354#endif
5355	up(&priv->wx_sem);
5356
5357	return 0;
5358}
5359
5360/* based on ipw2200 driver */
5361int rtl8192_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
5362{
5363	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
5364	struct iwreq *wrq = (struct iwreq *)rq;
5365	int ret=-1;
5366	struct ieee80211_device *ieee = priv->ieee80211;
5367	u32 key[4];
5368	u8 broadcast_addr[6] = {0xff,0xff,0xff,0xff,0xff,0xff};
5369	struct iw_point *p = &wrq->u.data;
5370	struct ieee_param *ipw = NULL;//(struct ieee_param *)wrq->u.data.pointer;
5371
5372	down(&priv->wx_sem);
5373
5374
5375     if (p->length < sizeof(struct ieee_param) || !p->pointer){
5376             ret = -EINVAL;
5377             goto out;
5378	}
5379
5380     ipw = (struct ieee_param *)kmalloc(p->length, GFP_KERNEL);
5381     if (ipw == NULL){
5382             ret = -ENOMEM;
5383             goto out;
5384     }
5385     if (copy_from_user(ipw, p->pointer, p->length)) {
5386		kfree(ipw);
5387            ret = -EFAULT;
5388            goto out;
5389	}
5390
5391	switch (cmd) {
5392	    case RTL_IOCTL_WPA_SUPPLICANT:
5393	//parse here for HW security
5394			if (ipw->cmd == IEEE_CMD_SET_ENCRYPTION)
5395			{
5396				if (ipw->u.crypt.set_tx)
5397				{
5398					if (strcmp(ipw->u.crypt.alg, "CCMP") == 0)
5399						ieee->pairwise_key_type = KEY_TYPE_CCMP;
5400					else if (strcmp(ipw->u.crypt.alg, "TKIP") == 0)
5401						ieee->pairwise_key_type = KEY_TYPE_TKIP;
5402					else if (strcmp(ipw->u.crypt.alg, "WEP") == 0)
5403					{
5404						if (ipw->u.crypt.key_len == 13)
5405							ieee->pairwise_key_type = KEY_TYPE_WEP104;
5406						else if (ipw->u.crypt.key_len == 5)
5407							ieee->pairwise_key_type = KEY_TYPE_WEP40;
5408					}
5409					else
5410						ieee->pairwise_key_type = KEY_TYPE_NA;
5411
5412					if (ieee->pairwise_key_type)
5413					{
5414						memcpy((u8*)key, ipw->u.crypt.key, 16);
5415						EnableHWSecurityConfig8192(dev);
5416					//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!
5417					//added by WB.
5418						setKey(dev, 4, ipw->u.crypt.idx, ieee->pairwise_key_type, (u8*)ieee->ap_mac_addr, 0, key);
5419						if (ieee->auth_mode != 2)
5420						setKey(dev, ipw->u.crypt.idx, ipw->u.crypt.idx, ieee->pairwise_key_type, (u8*)ieee->ap_mac_addr, 0, key);
5421					}
5422				}
5423				else //if (ipw->u.crypt.idx) //group key use idx > 0
5424				{
5425					memcpy((u8*)key, ipw->u.crypt.key, 16);
5426					if (strcmp(ipw->u.crypt.alg, "CCMP") == 0)
5427						ieee->group_key_type= KEY_TYPE_CCMP;
5428					else if (strcmp(ipw->u.crypt.alg, "TKIP") == 0)
5429						ieee->group_key_type = KEY_TYPE_TKIP;
5430					else if (strcmp(ipw->u.crypt.alg, "WEP") == 0)
5431					{
5432						if (ipw->u.crypt.key_len == 13)
5433							ieee->group_key_type = KEY_TYPE_WEP104;
5434						else if (ipw->u.crypt.key_len == 5)
5435							ieee->group_key_type = KEY_TYPE_WEP40;
5436					}
5437					else
5438						ieee->group_key_type = KEY_TYPE_NA;
5439
5440					if (ieee->group_key_type)
5441					{
5442							setKey(	dev,
5443								ipw->u.crypt.idx,
5444								ipw->u.crypt.idx,		//KeyIndex
5445						     		ieee->group_key_type,	//KeyType
5446						            	broadcast_addr,	//MacAddr
5447								0,		//DefaultKey
5448							      	key);		//KeyContent
5449					}
5450				}
5451			}
5452#ifdef JOHN_HWSEC_DEBUG
5453		//john's test 0711
5454		printk("@@ wrq->u pointer = ");
5455		for(i=0;i<wrq->u.data.length;i++){
5456			if(i%10==0) printk("\n");
5457			printk( "%8x|", ((u32*)wrq->u.data.pointer)[i] );
5458		}
5459		printk("\n");
5460#endif /*JOHN_HWSEC_DEBUG*/
5461		ret = ieee80211_wpa_supplicant_ioctl(priv->ieee80211, &wrq->u.data);
5462		break;
5463
5464	    default:
5465		ret = -EOPNOTSUPP;
5466		break;
5467	}
5468	kfree(ipw);
5469        ipw = NULL;
5470out:
5471	up(&priv->wx_sem);
5472	return ret;
5473}
5474
5475u8 HwRateToMRate90(bool bIsHT, u8 rate)
5476{
5477	u8  ret_rate = 0xff;
5478
5479	if(!bIsHT) {
5480		switch(rate) {
5481			case DESC90_RATE1M:   ret_rate = MGN_1M;         break;
5482			case DESC90_RATE2M:   ret_rate = MGN_2M;         break;
5483			case DESC90_RATE5_5M: ret_rate = MGN_5_5M;       break;
5484			case DESC90_RATE11M:  ret_rate = MGN_11M;        break;
5485			case DESC90_RATE6M:   ret_rate = MGN_6M;         break;
5486			case DESC90_RATE9M:   ret_rate = MGN_9M;         break;
5487			case DESC90_RATE12M:  ret_rate = MGN_12M;        break;
5488			case DESC90_RATE18M:  ret_rate = MGN_18M;        break;
5489			case DESC90_RATE24M:  ret_rate = MGN_24M;        break;
5490			case DESC90_RATE36M:  ret_rate = MGN_36M;        break;
5491			case DESC90_RATE48M:  ret_rate = MGN_48M;        break;
5492			case DESC90_RATE54M:  ret_rate = MGN_54M;        break;
5493
5494			default:
5495				ret_rate = 0xff;
5496				RT_TRACE(COMP_RECV, "HwRateToMRate90(): Non supported Rate [%x], bIsHT = %d!!!\n", rate, bIsHT);
5497				break;
5498		}
5499
5500	} else {
5501		switch(rate) {
5502			case DESC90_RATEMCS0:   ret_rate = MGN_MCS0;    break;
5503			case DESC90_RATEMCS1:   ret_rate = MGN_MCS1;    break;
5504			case DESC90_RATEMCS2:   ret_rate = MGN_MCS2;    break;
5505			case DESC90_RATEMCS3:   ret_rate = MGN_MCS3;    break;
5506			case DESC90_RATEMCS4:   ret_rate = MGN_MCS4;    break;
5507			case DESC90_RATEMCS5:   ret_rate = MGN_MCS5;    break;
5508			case DESC90_RATEMCS6:   ret_rate = MGN_MCS6;    break;
5509			case DESC90_RATEMCS7:   ret_rate = MGN_MCS7;    break;
5510			case DESC90_RATEMCS8:   ret_rate = MGN_MCS8;    break;
5511			case DESC90_RATEMCS9:   ret_rate = MGN_MCS9;    break;
5512			case DESC90_RATEMCS10:  ret_rate = MGN_MCS10;   break;
5513			case DESC90_RATEMCS11:  ret_rate = MGN_MCS11;   break;
5514			case DESC90_RATEMCS12:  ret_rate = MGN_MCS12;   break;
5515			case DESC90_RATEMCS13:  ret_rate = MGN_MCS13;   break;
5516			case DESC90_RATEMCS14:  ret_rate = MGN_MCS14;   break;
5517			case DESC90_RATEMCS15:  ret_rate = MGN_MCS15;   break;
5518			case DESC90_RATEMCS32:  ret_rate = (0x80|0x20); break;
5519
5520			default:
5521				ret_rate = 0xff;
5522				RT_TRACE(COMP_RECV, "HwRateToMRate90(): Non supported Rate [%x], bIsHT = %d!!!\n",rate, bIsHT);
5523				break;
5524		}
5525	}
5526
5527	return ret_rate;
5528}
5529
5530/**
5531 * Function:     UpdateRxPktTimeStamp
5532 * Overview:     Recored down the TSF time stamp when receiving a packet
5533 *
5534 * Input:
5535 *       PADAPTER        Adapter
5536 *       PRT_RFD         pRfd,
5537 *
5538 * Output:
5539 *       PRT_RFD         pRfd
5540 *                               (pRfd->Status.TimeStampHigh is updated)
5541 *                               (pRfd->Status.TimeStampLow is updated)
5542 * Return:
5543 *               None
5544 */
5545void UpdateRxPktTimeStamp8190 (struct net_device *dev, struct ieee80211_rx_stats *stats)
5546{
5547	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
5548
5549	if(stats->bIsAMPDU && !stats->bFirstMPDU) {
5550		stats->mac_time[0] = priv->LastRxDescTSFLow;
5551		stats->mac_time[1] = priv->LastRxDescTSFHigh;
5552	} else {
5553		priv->LastRxDescTSFLow = stats->mac_time[0];
5554		priv->LastRxDescTSFHigh = stats->mac_time[1];
5555	}
5556}
5557
5558//by amy 080606
5559
5560long rtl819x_translate_todbm(u8 signal_strength_index	)// 0-100 index.
5561{
5562	long	signal_power; // in dBm.
5563
5564	// Translate to dBm (x=0.5y-95).
5565	signal_power = (long)((signal_strength_index + 1) >> 1);
5566	signal_power -= 95;
5567
5568	return signal_power;
5569}
5570
5571
5572/* 2008/01/22 MH We can not delcare RSSI/EVM total value of sliding window to
5573    be a local static. Otherwise, it may increase when we return from S3/S4. The
5574    value will be kept in memory or disk. We must delcare the value in adapter
5575    and it will be reinitialized when return from S3/S4. */
5576void rtl8192_process_phyinfo(struct r8192_priv * priv,u8* buffer, struct ieee80211_rx_stats * pprevious_stats, struct ieee80211_rx_stats * pcurrent_stats)
5577{
5578	bool bcheck = false;
5579	u8	rfpath;
5580	u32	nspatial_stream, tmp_val;
5581	//u8	i;
5582	static u32 slide_rssi_index=0, slide_rssi_statistics=0;
5583	static u32 slide_evm_index=0, slide_evm_statistics=0;
5584	static u32 last_rssi=0, last_evm=0;
5585
5586	static u32 slide_beacon_adc_pwdb_index=0, slide_beacon_adc_pwdb_statistics=0;
5587	static u32 last_beacon_adc_pwdb=0;
5588
5589	struct ieee80211_hdr_3addr *hdr;
5590	u16 sc ;
5591	unsigned int frag,seq;
5592	hdr = (struct ieee80211_hdr_3addr *)buffer;
5593	sc = le16_to_cpu(hdr->seq_ctl);
5594	frag = WLAN_GET_SEQ_FRAG(sc);
5595	seq = WLAN_GET_SEQ_SEQ(sc);
5596	//cosa add 04292008 to record the sequence number
5597	pcurrent_stats->Seq_Num = seq;
5598	//
5599	// Check whether we should take the previous packet into accounting
5600	//
5601	if(!pprevious_stats->bIsAMPDU)
5602	{
5603		// if previous packet is not aggregated packet
5604		bcheck = true;
5605	}else
5606	{
5607	#if 0
5608		// if previous packet is aggregated packet, and current packet
5609		//  (1) is not AMPDU
5610		//  (2) is the first packet of one AMPDU
5611		// that means the previous packet is the last one aggregated packet
5612		if( !pcurrent_stats->bIsAMPDU || pcurrent_stats->bFirstMPDU)
5613			bcheck = true;
5614	#endif
5615	}
5616
5617
5618	if(slide_rssi_statistics++ >= PHY_RSSI_SLID_WIN_MAX)
5619	{
5620		slide_rssi_statistics = PHY_RSSI_SLID_WIN_MAX;
5621		last_rssi = priv->stats.slide_signal_strength[slide_rssi_index];
5622		priv->stats.slide_rssi_total -= last_rssi;
5623	}
5624	priv->stats.slide_rssi_total += pprevious_stats->SignalStrength;
5625
5626	priv->stats.slide_signal_strength[slide_rssi_index++] = pprevious_stats->SignalStrength;
5627	if(slide_rssi_index >= PHY_RSSI_SLID_WIN_MAX)
5628		slide_rssi_index = 0;
5629
5630	// <1> Showed on UI for user, in dbm
5631	tmp_val = priv->stats.slide_rssi_total/slide_rssi_statistics;
5632	priv->stats.signal_strength = rtl819x_translate_todbm((u8)tmp_val);
5633	pcurrent_stats->rssi = priv->stats.signal_strength;
5634	//
5635	// If the previous packet does not match the criteria, neglect it
5636	//
5637	if(!pprevious_stats->bPacketMatchBSSID)
5638	{
5639		if(!pprevious_stats->bToSelfBA)
5640			return;
5641	}
5642
5643	if(!bcheck)
5644		return;
5645
5646
5647	//rtl8190_process_cck_rxpathsel(priv,pprevious_stats);//only rtl8190 supported
5648
5649	//
5650	// Check RSSI
5651	//
5652	priv->stats.num_process_phyinfo++;
5653
5654	/* record the general signal strength to the sliding window. */
5655
5656
5657	// <2> Showed on UI for engineering
5658	// hardware does not provide rssi information for each rf path in CCK
5659	if(!pprevious_stats->bIsCCK && (pprevious_stats->bPacketToSelf || pprevious_stats->bToSelfBA))
5660	{
5661		for (rfpath = RF90_PATH_A; rfpath < priv->NumTotalRFPath; rfpath++)
5662		{
5663                     if (!rtl8192_phy_CheckIsLegalRFPath(priv->ieee80211->dev, rfpath))
5664			         continue;
5665
5666			//Fixed by Jacken 2008-03-20
5667			if(priv->stats.rx_rssi_percentage[rfpath] == 0)
5668			{
5669				priv->stats.rx_rssi_percentage[rfpath] = pprevious_stats->RxMIMOSignalStrength[rfpath];
5670				//DbgPrint("MIMO RSSI initialize \n");
5671			}
5672			if(pprevious_stats->RxMIMOSignalStrength[rfpath]  > priv->stats.rx_rssi_percentage[rfpath])
5673			{
5674				priv->stats.rx_rssi_percentage[rfpath] =
5675					( (priv->stats.rx_rssi_percentage[rfpath]*(Rx_Smooth_Factor-1)) +
5676					(pprevious_stats->RxMIMOSignalStrength[rfpath])) /(Rx_Smooth_Factor);
5677				priv->stats.rx_rssi_percentage[rfpath] = priv->stats.rx_rssi_percentage[rfpath]  + 1;
5678			}
5679			else
5680			{
5681				priv->stats.rx_rssi_percentage[rfpath] =
5682					( (priv->stats.rx_rssi_percentage[rfpath]*(Rx_Smooth_Factor-1)) +
5683					(pprevious_stats->RxMIMOSignalStrength[rfpath])) /(Rx_Smooth_Factor);
5684			}
5685			RT_TRACE(COMP_DBG,"priv->stats.rx_rssi_percentage[rfPath]  = %d \n" ,priv->stats.rx_rssi_percentage[rfpath] );
5686		}
5687	}
5688
5689
5690	//
5691	// Check PWDB.
5692	//
5693	RT_TRACE(COMP_RXDESC, "Smooth %s PWDB = %d\n",
5694				pprevious_stats->bIsCCK? "CCK": "OFDM",
5695				pprevious_stats->RxPWDBAll);
5696
5697	if(pprevious_stats->bPacketBeacon)
5698	{
5699/* record the beacon pwdb to the sliding window. */
5700		if(slide_beacon_adc_pwdb_statistics++ >= PHY_Beacon_RSSI_SLID_WIN_MAX)
5701		{
5702			slide_beacon_adc_pwdb_statistics = PHY_Beacon_RSSI_SLID_WIN_MAX;
5703			last_beacon_adc_pwdb = priv->stats.Slide_Beacon_pwdb[slide_beacon_adc_pwdb_index];
5704			priv->stats.Slide_Beacon_Total -= last_beacon_adc_pwdb;
5705			//DbgPrint("slide_beacon_adc_pwdb_index = %d, last_beacon_adc_pwdb = %d, Adapter->RxStats.Slide_Beacon_Total = %d\n",
5706			//	slide_beacon_adc_pwdb_index, last_beacon_adc_pwdb, Adapter->RxStats.Slide_Beacon_Total);
5707		}
5708		priv->stats.Slide_Beacon_Total += pprevious_stats->RxPWDBAll;
5709		priv->stats.Slide_Beacon_pwdb[slide_beacon_adc_pwdb_index] = pprevious_stats->RxPWDBAll;
5710		//DbgPrint("slide_beacon_adc_pwdb_index = %d, pPreviousRfd->Status.RxPWDBAll = %d\n", slide_beacon_adc_pwdb_index, pPreviousRfd->Status.RxPWDBAll);
5711		slide_beacon_adc_pwdb_index++;
5712		if(slide_beacon_adc_pwdb_index >= PHY_Beacon_RSSI_SLID_WIN_MAX)
5713			slide_beacon_adc_pwdb_index = 0;
5714		pprevious_stats->RxPWDBAll = priv->stats.Slide_Beacon_Total/slide_beacon_adc_pwdb_statistics;
5715		if(pprevious_stats->RxPWDBAll >= 3)
5716			pprevious_stats->RxPWDBAll -= 3;
5717	}
5718
5719	RT_TRACE(COMP_RXDESC, "Smooth %s PWDB = %d\n",
5720				pprevious_stats->bIsCCK? "CCK": "OFDM",
5721				pprevious_stats->RxPWDBAll);
5722
5723
5724	if(pprevious_stats->bPacketToSelf || pprevious_stats->bPacketBeacon || pprevious_stats->bToSelfBA)
5725	{
5726		if(priv->undecorated_smoothed_pwdb < 0)	// initialize
5727		{
5728			priv->undecorated_smoothed_pwdb = pprevious_stats->RxPWDBAll;
5729			//DbgPrint("First pwdb initialize \n");
5730		}
5731#if 1
5732		if(pprevious_stats->RxPWDBAll > (u32)priv->undecorated_smoothed_pwdb)
5733		{
5734			priv->undecorated_smoothed_pwdb =
5735					( ((priv->undecorated_smoothed_pwdb)*(Rx_Smooth_Factor-1)) +
5736					(pprevious_stats->RxPWDBAll)) /(Rx_Smooth_Factor);
5737			priv->undecorated_smoothed_pwdb = priv->undecorated_smoothed_pwdb + 1;
5738		}
5739		else
5740		{
5741			priv->undecorated_smoothed_pwdb =
5742					( ((priv->undecorated_smoothed_pwdb)*(Rx_Smooth_Factor-1)) +
5743					(pprevious_stats->RxPWDBAll)) /(Rx_Smooth_Factor);
5744		}
5745#else
5746		//Fixed by Jacken 2008-03-20
5747		if(pPreviousRfd->Status.RxPWDBAll > (u32)pHalData->UndecoratedSmoothedPWDB)
5748		{
5749			pHalData->UndecoratedSmoothedPWDB =
5750					( ((pHalData->UndecoratedSmoothedPWDB)* 5) + (pPreviousRfd->Status.RxPWDBAll)) / 6;
5751			pHalData->UndecoratedSmoothedPWDB = pHalData->UndecoratedSmoothedPWDB + 1;
5752		}
5753		else
5754		{
5755			pHalData->UndecoratedSmoothedPWDB =
5756					( ((pHalData->UndecoratedSmoothedPWDB)* 5) + (pPreviousRfd->Status.RxPWDBAll)) / 6;
5757		}
5758#endif
5759
5760	}
5761
5762	//
5763	// Check EVM
5764	//
5765	/* record the general EVM to the sliding window. */
5766	if(pprevious_stats->SignalQuality == 0)
5767	{
5768	}
5769	else
5770	{
5771		if(pprevious_stats->bPacketToSelf || pprevious_stats->bPacketBeacon || pprevious_stats->bToSelfBA){
5772			if(slide_evm_statistics++ >= PHY_RSSI_SLID_WIN_MAX){
5773				slide_evm_statistics = PHY_RSSI_SLID_WIN_MAX;
5774				last_evm = priv->stats.slide_evm[slide_evm_index];
5775				priv->stats.slide_evm_total -= last_evm;
5776			}
5777
5778			priv->stats.slide_evm_total += pprevious_stats->SignalQuality;
5779
5780			priv->stats.slide_evm[slide_evm_index++] = pprevious_stats->SignalQuality;
5781			if(slide_evm_index >= PHY_RSSI_SLID_WIN_MAX)
5782				slide_evm_index = 0;
5783
5784			// <1> Showed on UI for user, in percentage.
5785			tmp_val = priv->stats.slide_evm_total/slide_evm_statistics;
5786			priv->stats.signal_quality = tmp_val;
5787			//cosa add 10/11/2007, Showed on UI for user in Windows Vista, for Link quality.
5788			priv->stats.last_signal_strength_inpercent = tmp_val;
5789		}
5790
5791		// <2> Showed on UI for engineering
5792		if(pprevious_stats->bPacketToSelf || pprevious_stats->bPacketBeacon || pprevious_stats->bToSelfBA)
5793		{
5794			for(nspatial_stream = 0; nspatial_stream<2 ; nspatial_stream++) // 2 spatial stream
5795			{
5796				if(pprevious_stats->RxMIMOSignalQuality[nspatial_stream] != -1)
5797				{
5798					if(priv->stats.rx_evm_percentage[nspatial_stream] == 0)	// initialize
5799					{
5800						priv->stats.rx_evm_percentage[nspatial_stream] = pprevious_stats->RxMIMOSignalQuality[nspatial_stream];
5801					}
5802					priv->stats.rx_evm_percentage[nspatial_stream] =
5803						( (priv->stats.rx_evm_percentage[nspatial_stream]* (Rx_Smooth_Factor-1)) +
5804						(pprevious_stats->RxMIMOSignalQuality[nspatial_stream]* 1)) / (Rx_Smooth_Factor);
5805				}
5806			}
5807		}
5808	}
5809
5810
5811}
5812
5813/*-----------------------------------------------------------------------------
5814 * Function:	rtl819x_query_rxpwrpercentage()
5815 *
5816 * Overview:
5817 *
5818 * Input:		char		antpower
5819 *
5820 * Output:		NONE
5821 *
5822 * Return:		0-100 percentage
5823 *
5824 * Revised History:
5825 *	When		Who		Remark
5826 *	05/26/2008	amy		Create Version 0 porting from windows code.
5827 *
5828 *---------------------------------------------------------------------------*/
5829static u8 rtl819x_query_rxpwrpercentage(
5830	char		antpower
5831	)
5832{
5833	if ((antpower <= -100) || (antpower >= 20))
5834	{
5835		return	0;
5836	}
5837	else if (antpower >= 0)
5838	{
5839		return	100;
5840	}
5841	else
5842	{
5843		return	(100+antpower);
5844	}
5845
5846}	/* QueryRxPwrPercentage */
5847
5848static u8
5849rtl819x_evm_dbtopercentage(
5850    char value
5851    )
5852{
5853    char ret_val;
5854
5855    ret_val = value;
5856
5857    if(ret_val >= 0)
5858        ret_val = 0;
5859    if(ret_val <= -33)
5860        ret_val = -33;
5861    ret_val = 0 - ret_val;
5862    ret_val*=3;
5863	if(ret_val == 99)
5864		ret_val = 100;
5865    return(ret_val);
5866}
5867//
5868//	Description:
5869// 	We want good-looking for signal strength/quality
5870//	2007/7/19 01:09, by cosa.
5871//
5872long
5873rtl819x_signal_scale_mapping(
5874	long currsig
5875	)
5876{
5877	long retsig;
5878
5879	// Step 1. Scale mapping.
5880	if(currsig >= 61 && currsig <= 100)
5881	{
5882		retsig = 90 + ((currsig - 60) / 4);
5883	}
5884	else if(currsig >= 41 && currsig <= 60)
5885	{
5886		retsig = 78 + ((currsig - 40) / 2);
5887	}
5888	else if(currsig >= 31 && currsig <= 40)
5889	{
5890		retsig = 66 + (currsig - 30);
5891	}
5892	else if(currsig >= 21 && currsig <= 30)
5893	{
5894		retsig = 54 + (currsig - 20);
5895	}
5896	else if(currsig >= 5 && currsig <= 20)
5897	{
5898		retsig = 42 + (((currsig - 5) * 2) / 3);
5899	}
5900	else if(currsig == 4)
5901	{
5902		retsig = 36;
5903	}
5904	else if(currsig == 3)
5905	{
5906		retsig = 27;
5907	}
5908	else if(currsig == 2)
5909	{
5910		retsig = 18;
5911	}
5912	else if(currsig == 1)
5913	{
5914		retsig = 9;
5915	}
5916	else
5917	{
5918		retsig = currsig;
5919	}
5920
5921	return retsig;
5922}
5923
5924static void rtl8192_query_rxphystatus(
5925	struct r8192_priv * priv,
5926	struct ieee80211_rx_stats * pstats,
5927	rx_drvinfo_819x_usb  * pdrvinfo,
5928	struct ieee80211_rx_stats * precord_stats,
5929	bool bpacket_match_bssid,
5930	bool bpacket_toself,
5931	bool bPacketBeacon,
5932	bool bToSelfBA
5933	)
5934{
5935	//PRT_RFD_STATUS		pRtRfdStatus = &(pRfd->Status);
5936	phy_sts_ofdm_819xusb_t*	pofdm_buf;
5937	phy_sts_cck_819xusb_t	*	pcck_buf;
5938	phy_ofdm_rx_status_rxsc_sgien_exintfflag* prxsc;
5939	u8				*prxpkt;
5940	u8				i, max_spatial_stream, tmp_rxsnr, tmp_rxevm, rxsc_sgien_exflg;
5941	char				rx_pwr[4], rx_pwr_all=0;
5942	//long				rx_avg_pwr = 0;
5943	char				rx_snrX, rx_evmX;
5944	u8				evm, pwdb_all;
5945	u32				RSSI, total_rssi=0;//, total_evm=0;
5946//	long				signal_strength_index = 0;
5947	u8				is_cck_rate=0;
5948	u8				rf_rx_num = 0;
5949
5950
5951	priv->stats.numqry_phystatus++;
5952
5953	is_cck_rate = rx_hal_is_cck_rate(pdrvinfo);
5954
5955	// Record it for next packet processing
5956	memset(precord_stats, 0, sizeof(struct ieee80211_rx_stats));
5957	pstats->bPacketMatchBSSID = precord_stats->bPacketMatchBSSID = bpacket_match_bssid;
5958	pstats->bPacketToSelf = precord_stats->bPacketToSelf = bpacket_toself;
5959	pstats->bIsCCK = precord_stats->bIsCCK = is_cck_rate;//RX_HAL_IS_CCK_RATE(pDrvInfo);
5960	pstats->bPacketBeacon = precord_stats->bPacketBeacon = bPacketBeacon;
5961	pstats->bToSelfBA = precord_stats->bToSelfBA = bToSelfBA;
5962
5963	prxpkt = (u8*)pdrvinfo;
5964
5965	/* Move pointer to the 16th bytes. Phy status start address. */
5966	prxpkt += sizeof(rx_drvinfo_819x_usb);
5967
5968	/* Initial the cck and ofdm buffer pointer */
5969	pcck_buf = (phy_sts_cck_819xusb_t *)prxpkt;
5970	pofdm_buf = (phy_sts_ofdm_819xusb_t *)prxpkt;
5971
5972	pstats->RxMIMOSignalQuality[0] = -1;
5973	pstats->RxMIMOSignalQuality[1] = -1;
5974	precord_stats->RxMIMOSignalQuality[0] = -1;
5975	precord_stats->RxMIMOSignalQuality[1] = -1;
5976
5977	if(is_cck_rate)
5978	{
5979		//
5980		// (1)Hardware does not provide RSSI for CCK
5981		//
5982
5983		//
5984		// (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive)
5985		//
5986		u8 report;//, cck_agc_rpt;
5987
5988		priv->stats.numqry_phystatusCCK++;
5989
5990		if(!priv->bCckHighPower)
5991		{
5992			report = pcck_buf->cck_agc_rpt & 0xc0;
5993			report = report>>6;
5994			switch(report)
5995			{
5996				//Fixed by Jacken from Bryant 2008-03-20
5997				//Original value is -38 , -26 , -14 , -2
5998				//Fixed value is -35 , -23 , -11 , 6
5999				case 0x3:
6000					rx_pwr_all = -35 - (pcck_buf->cck_agc_rpt & 0x3e);
6001					break;
6002				case 0x2:
6003					rx_pwr_all = -23 - (pcck_buf->cck_agc_rpt & 0x3e);
6004					break;
6005				case 0x1:
6006					rx_pwr_all = -11 - (pcck_buf->cck_agc_rpt & 0x3e);
6007					break;
6008				case 0x0:
6009					rx_pwr_all = 6 - (pcck_buf->cck_agc_rpt & 0x3e);
6010					break;
6011			}
6012		}
6013		else
6014		{
6015			report = pcck_buf->cck_agc_rpt & 0x60;
6016			report = report>>5;
6017			switch(report)
6018			{
6019				case 0x3:
6020					rx_pwr_all = -35 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1) ;
6021					break;
6022				case 0x2:
6023					rx_pwr_all = -23 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1);
6024					break;
6025				case 0x1:
6026					rx_pwr_all = -11 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1) ;
6027					break;
6028				case 0x0:
6029					rx_pwr_all = 6 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1) ;
6030					break;
6031			}
6032		}
6033
6034		pwdb_all = rtl819x_query_rxpwrpercentage(rx_pwr_all);
6035		pstats->RxPWDBAll = precord_stats->RxPWDBAll = pwdb_all;
6036		pstats->RecvSignalPower = pwdb_all;
6037
6038		//
6039		// (3) Get Signal Quality (EVM)
6040		//
6041		//if(bpacket_match_bssid)
6042		{
6043			u8	sq;
6044
6045			if(pstats->RxPWDBAll > 40)
6046			{
6047				sq = 100;
6048			}else
6049			{
6050				sq = pcck_buf->sq_rpt;
6051
6052				if(pcck_buf->sq_rpt > 64)
6053					sq = 0;
6054				else if (pcck_buf->sq_rpt < 20)
6055					sq = 100;
6056				else
6057					sq = ((64-sq) * 100) / 44;
6058			}
6059			pstats->SignalQuality = precord_stats->SignalQuality = sq;
6060			pstats->RxMIMOSignalQuality[0] = precord_stats->RxMIMOSignalQuality[0] = sq;
6061			pstats->RxMIMOSignalQuality[1] = precord_stats->RxMIMOSignalQuality[1] = -1;
6062		}
6063	}
6064	else
6065	{
6066		priv->stats.numqry_phystatusHT++;
6067		//
6068		// (1)Get RSSI for HT rate
6069		//
6070		for(i=RF90_PATH_A; i<priv->NumTotalRFPath; i++)
6071		{
6072			// 2008/01/30 MH we will judge RF RX path now.
6073			if (priv->brfpath_rxenable[i])
6074				rf_rx_num++;
6075			else
6076				continue;
6077
6078		if (!rtl8192_phy_CheckIsLegalRFPath(priv->ieee80211->dev, i))
6079				continue;
6080
6081			//Fixed by Jacken from Bryant 2008-03-20
6082			//Original value is 106
6083			rx_pwr[i] = ((pofdm_buf->trsw_gain_X[i]&0x3F)*2) - 106;
6084
6085			//Get Rx snr value in DB
6086			tmp_rxsnr =	pofdm_buf->rxsnr_X[i];
6087			rx_snrX = (char)(tmp_rxsnr);
6088			//rx_snrX >>= 1;;
6089			rx_snrX /= 2;
6090			priv->stats.rxSNRdB[i] = (long)rx_snrX;
6091
6092			/* Translate DBM to percentage. */
6093			RSSI = rtl819x_query_rxpwrpercentage(rx_pwr[i]);
6094			total_rssi += RSSI;
6095
6096			/* Record Signal Strength for next packet */
6097			//if(bpacket_match_bssid)
6098			{
6099				pstats->RxMIMOSignalStrength[i] =(u8) RSSI;
6100				precord_stats->RxMIMOSignalStrength[i] =(u8) RSSI;
6101			}
6102		}
6103
6104
6105		//
6106		// (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive)
6107		//
6108		//Fixed by Jacken from Bryant 2008-03-20
6109		//Original value is 106
6110		rx_pwr_all = (((pofdm_buf->pwdb_all ) >> 1 )& 0x7f) -106;
6111		pwdb_all = rtl819x_query_rxpwrpercentage(rx_pwr_all);
6112
6113		pstats->RxPWDBAll = precord_stats->RxPWDBAll = pwdb_all;
6114		pstats->RxPower = precord_stats->RxPower =  rx_pwr_all;
6115
6116		//
6117		// (3)EVM of HT rate
6118		//
6119		if(pdrvinfo->RxHT && pdrvinfo->RxRate>=DESC90_RATEMCS8 &&
6120		 	pdrvinfo->RxRate<=DESC90_RATEMCS15)
6121			max_spatial_stream = 2; //both spatial stream make sense
6122		else
6123			max_spatial_stream = 1; //only spatial stream 1 makes sense
6124
6125		for(i=0; i<max_spatial_stream; i++)
6126		{
6127			tmp_rxevm =	pofdm_buf->rxevm_X[i];
6128			rx_evmX = (char)(tmp_rxevm);
6129
6130			// Do not use shift operation like "rx_evmX >>= 1" because the compilor of free build environment
6131			// fill most significant bit to "zero" when doing shifting operation which may change a negative
6132			// value to positive one, then the dbm value (which is supposed to be negative)  is not correct anymore.
6133			rx_evmX /= 2;	//dbm
6134
6135			evm = rtl819x_evm_dbtopercentage(rx_evmX);
6136#if 0
6137			EVM = SignalScaleMapping(EVM);//make it good looking, from 0~100
6138#endif
6139			//if(bpacket_match_bssid)
6140			{
6141				if(i==0) // Fill value in RFD, Get the first spatial stream only
6142					pstats->SignalQuality = precord_stats->SignalQuality = (u8)(evm & 0xff);
6143				pstats->RxMIMOSignalQuality[i] = precord_stats->RxMIMOSignalQuality[i] = (u8)(evm & 0xff);
6144			}
6145		}
6146
6147
6148		/* record rx statistics for debug */
6149		rxsc_sgien_exflg = pofdm_buf->rxsc_sgien_exflg;
6150		prxsc =	(phy_ofdm_rx_status_rxsc_sgien_exintfflag *)&rxsc_sgien_exflg;
6151		if(pdrvinfo->BW)	//40M channel
6152			priv->stats.received_bwtype[1+prxsc->rxsc]++;
6153		else				//20M channel
6154			priv->stats.received_bwtype[0]++;
6155	}
6156
6157	//UI BSS List signal strength(in percentage), make it good looking, from 0~100.
6158	//It is assigned to the BSS List in GetValueFromBeaconOrProbeRsp().
6159	if(is_cck_rate)
6160	{
6161		pstats->SignalStrength = precord_stats->SignalStrength = (u8)(rtl819x_signal_scale_mapping((long)pwdb_all));//PWDB_ALL;
6162
6163	}
6164	else
6165	{
6166		//pRfd->Status.SignalStrength = pRecordRfd->Status.SignalStrength = (u8)(SignalScaleMapping(total_rssi/=RF90_PATH_MAX));//(u8)(total_rssi/=RF90_PATH_MAX);
6167		// We can judge RX path number now.
6168		if (rf_rx_num != 0)
6169			pstats->SignalStrength = precord_stats->SignalStrength = (u8)(rtl819x_signal_scale_mapping((long)(total_rssi/=rf_rx_num)));
6170	}
6171}	/* QueryRxPhyStatus8190Pci */
6172
6173void
6174rtl8192_record_rxdesc_forlateruse(
6175	struct ieee80211_rx_stats *	psrc_stats,
6176	struct ieee80211_rx_stats *	ptarget_stats
6177)
6178{
6179	ptarget_stats->bIsAMPDU = psrc_stats->bIsAMPDU;
6180	ptarget_stats->bFirstMPDU = psrc_stats->bFirstMPDU;
6181	ptarget_stats->Seq_Num = psrc_stats->Seq_Num;
6182}
6183
6184
6185void TranslateRxSignalStuff819xUsb(struct sk_buff *skb,
6186				   struct ieee80211_rx_stats * pstats,
6187                                   rx_drvinfo_819x_usb  *pdrvinfo)
6188{
6189	// TODO: We must only check packet for current MAC address. Not finish
6190	rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
6191	struct net_device *dev=info->dev;
6192	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
6193	bool bpacket_match_bssid, bpacket_toself;
6194	bool bPacketBeacon=FALSE, bToSelfBA=FALSE;
6195	static struct ieee80211_rx_stats  previous_stats;
6196	struct ieee80211_hdr_3addr *hdr;//by amy
6197       u16 fc,type;
6198
6199	// Get Signal Quality for only RX data queue (but not command queue)
6200
6201	u8* tmp_buf;
6202	//u16 tmp_buf_len = 0;
6203	u8  *praddr;
6204
6205	/* Get MAC frame start address. */
6206	tmp_buf = (u8*)skb->data;// + get_rxpacket_shiftbytes_819xusb(pstats);
6207
6208	hdr = (struct ieee80211_hdr_3addr *)tmp_buf;
6209	fc = le16_to_cpu(hdr->frame_ctl);
6210	type = WLAN_FC_GET_TYPE(fc);
6211	praddr = hdr->addr1;
6212
6213	/* Check if the received packet is acceptabe. */
6214	bpacket_match_bssid = ((IEEE80211_FTYPE_CTL != type) &&
6215                                			(eqMacAddr(priv->ieee80211->current_network.bssid,  (fc & IEEE80211_FCTL_TODS)? hdr->addr1 : (fc & IEEE80211_FCTL_FROMDS )? hdr->addr2 : hdr->addr3))
6216                                				 && (!pstats->bHwError) && (!pstats->bCRC)&& (!pstats->bICV));
6217	bpacket_toself =  bpacket_match_bssid & (eqMacAddr(praddr, priv->ieee80211->dev->dev_addr));
6218
6219#if 1//cosa
6220		if(WLAN_FC_GET_FRAMETYPE(fc)== IEEE80211_STYPE_BEACON)
6221		{
6222			bPacketBeacon = true;
6223			//DbgPrint("Beacon 2, MatchBSSID = %d, ToSelf = %d \n", bPacketMatchBSSID, bPacketToSelf);
6224		}
6225		if(WLAN_FC_GET_FRAMETYPE(fc) == IEEE80211_STYPE_BLOCKACK)
6226		{
6227			if((eqMacAddr(praddr,dev->dev_addr)))
6228				bToSelfBA = true;
6229				//DbgPrint("BlockAck, MatchBSSID = %d, ToSelf = %d \n", bPacketMatchBSSID, bPacketToSelf);
6230		}
6231
6232#endif
6233
6234
6235	if(bpacket_match_bssid)
6236	{
6237		priv->stats.numpacket_matchbssid++;
6238	}
6239	if(bpacket_toself){
6240		priv->stats.numpacket_toself++;
6241	}
6242	//
6243	// Process PHY information for previous packet (RSSI/PWDB/EVM)
6244	//
6245	// Because phy information is contained in the last packet of AMPDU only, so driver
6246	// should process phy information of previous packet
6247	rtl8192_process_phyinfo(priv, tmp_buf, &previous_stats, pstats);
6248	rtl8192_query_rxphystatus(priv, pstats, pdrvinfo, &previous_stats, bpacket_match_bssid,bpacket_toself,bPacketBeacon,bToSelfBA);
6249	rtl8192_record_rxdesc_forlateruse(pstats, &previous_stats);
6250
6251}
6252
6253/**
6254* Function:	UpdateReceivedRateHistogramStatistics
6255* Overview:	Recored down the received data rate
6256*
6257* Input:
6258* 	struct net_device *dev
6259*	struct ieee80211_rx_stats *stats
6260*
6261* Output:
6262*
6263*			(priv->stats.ReceivedRateHistogram[] is updated)
6264* Return:
6265*		None
6266*/
6267void
6268UpdateReceivedRateHistogramStatistics8190(
6269	struct net_device *dev,
6270	struct ieee80211_rx_stats *stats
6271	)
6272{
6273	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
6274    	u32 rcvType=1;   //0: Total, 1:OK, 2:CRC, 3:ICV
6275    	u32 rateIndex;
6276    	u32 preamble_guardinterval;  //1: short preamble/GI, 0: long preamble/GI
6277
6278
6279    	if(stats->bCRC)
6280       	rcvType = 2;
6281   	else if(stats->bICV)
6282       	rcvType = 3;
6283
6284   	if(stats->bShortPreamble)
6285       	preamble_guardinterval = 1;// short
6286    	else
6287       	preamble_guardinterval = 0;// long
6288
6289	switch(stats->rate)
6290	{
6291		//
6292		// CCK rate
6293		//
6294		case MGN_1M:    rateIndex = 0;  break;
6295		case MGN_2M:    rateIndex = 1;  break;
6296		case MGN_5_5M:  rateIndex = 2;  break;
6297		case MGN_11M:   rateIndex = 3;  break;
6298		//
6299		// Legacy OFDM rate
6300		//
6301		case MGN_6M:    rateIndex = 4;  break;
6302		case MGN_9M:    rateIndex = 5;  break;
6303		case MGN_12M:   rateIndex = 6;  break;
6304		case MGN_18M:   rateIndex = 7;  break;
6305		case MGN_24M:   rateIndex = 8;  break;
6306		case MGN_36M:   rateIndex = 9;  break;
6307		case MGN_48M:   rateIndex = 10; break;
6308		case MGN_54M:   rateIndex = 11; break;
6309		//
6310		// 11n High throughput rate
6311		//
6312		case MGN_MCS0:  rateIndex = 12; break;
6313		case MGN_MCS1:  rateIndex = 13; break;
6314		case MGN_MCS2:  rateIndex = 14; break;
6315		case MGN_MCS3:  rateIndex = 15; break;
6316		case MGN_MCS4:  rateIndex = 16; break;
6317		case MGN_MCS5:  rateIndex = 17; break;
6318		case MGN_MCS6:  rateIndex = 18; break;
6319		case MGN_MCS7:  rateIndex = 19; break;
6320		case MGN_MCS8:  rateIndex = 20; break;
6321		case MGN_MCS9:  rateIndex = 21; break;
6322		case MGN_MCS10: rateIndex = 22; break;
6323		case MGN_MCS11: rateIndex = 23; break;
6324		case MGN_MCS12: rateIndex = 24; break;
6325		case MGN_MCS13: rateIndex = 25; break;
6326		case MGN_MCS14: rateIndex = 26; break;
6327		case MGN_MCS15: rateIndex = 27; break;
6328		default:        rateIndex = 28; break;
6329	}
6330    priv->stats.received_preamble_GI[preamble_guardinterval][rateIndex]++;
6331    priv->stats.received_rate_histogram[0][rateIndex]++; //total
6332    priv->stats.received_rate_histogram[rcvType][rateIndex]++;
6333}
6334
6335
6336void query_rxdesc_status(struct sk_buff *skb, struct ieee80211_rx_stats *stats, bool bIsRxAggrSubframe)
6337{
6338	rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
6339	struct net_device *dev=info->dev;
6340	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
6341	//rx_desc_819x_usb *desc = (rx_desc_819x_usb *)skb->data;
6342	rx_drvinfo_819x_usb  *driver_info = NULL;
6343
6344	//
6345	//Get Rx Descriptor Information
6346	//
6347#ifdef USB_RX_AGGREGATION_SUPPORT
6348	if (bIsRxAggrSubframe)
6349	{
6350		rx_desc_819x_usb_aggr_subframe *desc = (rx_desc_819x_usb_aggr_subframe *)skb->data;
6351		stats->Length = desc->Length ;
6352		stats->RxDrvInfoSize = desc->RxDrvInfoSize;
6353		stats->RxBufShift = 0; //RxBufShift = 2 in RxDesc, but usb didn't shift bytes in fact.
6354		stats->bICV = desc->ICV;
6355		stats->bCRC = desc->CRC32;
6356		stats->bHwError = stats->bCRC|stats->bICV;
6357		stats->Decrypted = !desc->SWDec;//RTL8190 set this bit to indicate that Hw does not decrypt packet
6358	} else
6359#endif
6360	{
6361		rx_desc_819x_usb *desc = (rx_desc_819x_usb *)skb->data;
6362
6363		stats->Length = desc->Length;
6364		stats->RxDrvInfoSize = desc->RxDrvInfoSize;
6365		stats->RxBufShift = 0;//desc->Shift&0x03;
6366		stats->bICV = desc->ICV;
6367		stats->bCRC = desc->CRC32;
6368		stats->bHwError = stats->bCRC|stats->bICV;
6369		//RTL8190 set this bit to indicate that Hw does not decrypt packet
6370		stats->Decrypted = !desc->SWDec;
6371	}
6372
6373	if((priv->ieee80211->pHTInfo->bCurrentHTSupport == true) && (priv->ieee80211->pairwise_key_type == KEY_TYPE_CCMP))
6374	{
6375		stats->bHwError = false;
6376	}
6377	else
6378	{
6379		stats->bHwError = stats->bCRC|stats->bICV;
6380	}
6381
6382	if(stats->Length < 24 || stats->Length > MAX_8192U_RX_SIZE)
6383		stats->bHwError |= 1;
6384	//
6385	//Get Driver Info
6386	//
6387	// TODO: Need to verify it on FGPA platform
6388	//Driver info are written to the RxBuffer following rx desc
6389	if (stats->RxDrvInfoSize != 0) {
6390		driver_info = (rx_drvinfo_819x_usb *)(skb->data + sizeof(rx_desc_819x_usb) + \
6391				stats->RxBufShift);
6392		/* unit: 0.5M */
6393		/* TODO */
6394		if(!stats->bHwError){
6395			u8	ret_rate;
6396			ret_rate = HwRateToMRate90(driver_info->RxHT, driver_info->RxRate);
6397			if(ret_rate == 0xff)
6398			{
6399				// Abnormal Case: Receive CRC OK packet with Rx descriptor indicating non supported rate.
6400				// Special Error Handling here, 2008.05.16, by Emily
6401
6402				stats->bHwError = 1;
6403				stats->rate = MGN_1M;	//Set 1M rate by default
6404			}else
6405			{
6406				stats->rate = ret_rate;
6407			}
6408		}
6409		else
6410			stats->rate = 0x02;
6411
6412		stats->bShortPreamble = driver_info->SPLCP;
6413
6414
6415		UpdateReceivedRateHistogramStatistics8190(dev, stats);
6416
6417		stats->bIsAMPDU = (driver_info->PartAggr==1);
6418		stats->bFirstMPDU = (driver_info->PartAggr==1) && (driver_info->FirstAGGR==1);
6419#if 0
6420		// TODO: it is debug only. It should be disabled in released driver. 2007.1.12 by Joseph
6421		UpdateRxAMPDUHistogramStatistics8190(Adapter, pRfd);
6422#endif
6423		stats->TimeStampLow = driver_info->TSFL;
6424		// xiong mask it, 070514
6425		//pRfd->Status.TimeStampHigh = PlatformEFIORead4Byte(Adapter, TSFR+4);
6426		// stats->TimeStampHigh = read_nic_dword(dev,  TSFR+4);
6427
6428		UpdateRxPktTimeStamp8190(dev, stats);
6429
6430		//
6431		// Rx A-MPDU
6432		//
6433		if(driver_info->FirstAGGR==1 || driver_info->PartAggr == 1)
6434			RT_TRACE(COMP_RXDESC, "driver_info->FirstAGGR = %d, driver_info->PartAggr = %d\n",
6435					driver_info->FirstAGGR, driver_info->PartAggr);
6436
6437	}
6438
6439	skb_pull(skb,sizeof(rx_desc_819x_usb));
6440	//
6441	// Get Total offset of MPDU Frame Body
6442	//
6443	if((stats->RxBufShift + stats->RxDrvInfoSize) > 0) {
6444		stats->bShift = 1;
6445		skb_pull(skb,stats->RxBufShift + stats->RxDrvInfoSize);
6446	}
6447
6448#ifdef USB_RX_AGGREGATION_SUPPORT
6449	/* for the rx aggregated sub frame, the redundant space truelly contained in the packet */
6450	if(bIsRxAggrSubframe) {
6451		skb_pull(skb, 8);
6452	}
6453#endif
6454	/* for debug 2008.5.29 */
6455#if 0
6456	{
6457		int i;
6458		printk("\n>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
6459		for(i = 0; i < skb->len; i++) {
6460			if(i % 10 == 0) printk("\n");
6461			printk("%02x ", skb->data[i]);
6462		}
6463		printk("\n<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
6464	}
6465#endif
6466
6467	//added by vivi, for MP, 20080108
6468	stats->RxIs40MHzPacket = driver_info->BW;
6469	if(stats->RxDrvInfoSize != 0)
6470		TranslateRxSignalStuff819xUsb(skb, stats, driver_info);
6471
6472}
6473
6474u32 GetRxPacketShiftBytes819xUsb(struct ieee80211_rx_stats  *Status, bool bIsRxAggrSubframe)
6475{
6476#ifdef USB_RX_AGGREGATION_SUPPORT
6477	if (bIsRxAggrSubframe)
6478		return (sizeof(rx_desc_819x_usb) + Status->RxDrvInfoSize
6479			+ Status->RxBufShift + 8);
6480	else
6481#endif
6482		return (sizeof(rx_desc_819x_usb) + Status->RxDrvInfoSize
6483				+ Status->RxBufShift);
6484}
6485
6486void rtl8192_rx_nomal(struct sk_buff* skb)
6487{
6488	rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
6489	struct net_device *dev=info->dev;
6490	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
6491	struct ieee80211_rx_stats stats = {
6492		.signal = 0,
6493		.noise = -98,
6494		.rate = 0,
6495		//      .mac_time = jiffies,
6496		.freq = IEEE80211_24GHZ_BAND,
6497	};
6498	u32 rx_pkt_len = 0;
6499	struct ieee80211_hdr_1addr *ieee80211_hdr = NULL;
6500	bool unicast_packet = false;
6501#ifdef USB_RX_AGGREGATION_SUPPORT
6502	struct sk_buff *agg_skb = NULL;
6503	u32  TotalLength = 0;
6504	u32  TempDWord = 0;
6505	u32  PacketLength = 0;
6506	u32  PacketOccupiedLendth = 0;
6507	u8   TempByte = 0;
6508	u32  PacketShiftBytes = 0;
6509	rx_desc_819x_usb_aggr_subframe *RxDescr = NULL;
6510	u8  PaddingBytes = 0;
6511	//add just for testing
6512	u8   testing;
6513
6514#endif
6515
6516	/* 20 is for ps-poll */
6517	if((skb->len >=(20 + sizeof(rx_desc_819x_usb))) && (skb->len < RX_URB_SIZE)) {
6518#ifdef USB_RX_AGGREGATION_SUPPORT
6519		TempByte = *(skb->data + sizeof(rx_desc_819x_usb));
6520#endif
6521		/* first packet should not contain Rx aggregation header */
6522		query_rxdesc_status(skb, &stats, false);
6523		/* TODO */
6524		/* hardware related info */
6525#ifdef USB_RX_AGGREGATION_SUPPORT
6526		if (TempByte & BIT0) {
6527			agg_skb = skb;
6528			//TotalLength = agg_skb->len - 4; /*sCrcLng*/
6529			TotalLength = stats.Length - 4; /*sCrcLng*/
6530			//RT_TRACE(COMP_RECV, "%s:first aggregated packet!Length=%d\n",__FUNCTION__,TotalLength);
6531			/* though the head pointer has passed this position  */
6532			TempDWord = *(u32 *)(agg_skb->data - 4);
6533			PacketLength = (u16)(TempDWord & 0x3FFF); /*sCrcLng*/
6534			skb = dev_alloc_skb(PacketLength);
6535			memcpy(skb_put(skb,PacketLength),agg_skb->data,PacketLength);
6536			PacketShiftBytes = GetRxPacketShiftBytes819xUsb(&stats, false);
6537		}
6538#endif
6539		/* Process the MPDU recevied */
6540		skb_trim(skb, skb->len - 4/*sCrcLng*/);
6541
6542		rx_pkt_len = skb->len;
6543		ieee80211_hdr = (struct ieee80211_hdr_1addr *)skb->data;
6544		unicast_packet = false;
6545		if(is_broadcast_ether_addr(ieee80211_hdr->addr1)) {
6546			//TODO
6547		}else if(is_multicast_ether_addr(ieee80211_hdr->addr1)){
6548			//TODO
6549		}else {
6550			/* unicast packet */
6551			unicast_packet = true;
6552		}
6553
6554		if(!ieee80211_rx(priv->ieee80211,skb, &stats)) {
6555			dev_kfree_skb_any(skb);
6556		} else {
6557			priv->stats.rxoktotal++;
6558			if(unicast_packet) {
6559				priv->stats.rxbytesunicast += rx_pkt_len;
6560			}
6561		}
6562#ifdef USB_RX_AGGREGATION_SUPPORT
6563		testing = 1;
6564		// (PipeIndex == 0) && (TempByte & BIT0) => TotalLength > 0.
6565		if (TotalLength > 0) {
6566			PacketOccupiedLendth = PacketLength + (PacketShiftBytes + 8);
6567			if ((PacketOccupiedLendth & 0xFF) != 0)
6568				PacketOccupiedLendth = (PacketOccupiedLendth & 0xFFFFFF00) + 256;
6569			PacketOccupiedLendth -= 8;
6570			TempDWord = PacketOccupiedLendth - PacketShiftBytes; /*- PacketLength */
6571			if (agg_skb->len > TempDWord)
6572				skb_pull(agg_skb, TempDWord);
6573			else
6574				agg_skb->len = 0;
6575
6576			while (agg_skb->len>=GetRxPacketShiftBytes819xUsb(&stats, true)) {
6577				u8 tmpCRC = 0, tmpICV = 0;
6578				//RT_TRACE(COMP_RECV,"%s:aggred pkt,total_len = %d\n",__FUNCTION__,agg_skb->len);
6579				RxDescr = (rx_desc_819x_usb_aggr_subframe *)(agg_skb->data);
6580				tmpCRC = RxDescr->CRC32;
6581				tmpICV = RxDescr->ICV;
6582				memcpy(agg_skb->data, &agg_skb->data[44], 2);
6583				RxDescr->CRC32 = tmpCRC;
6584				RxDescr->ICV = tmpICV;
6585
6586				memset(&stats, 0, sizeof(struct ieee80211_rx_stats));
6587				stats.signal = 0;
6588				stats.noise = -98;
6589				stats.rate = 0;
6590				stats.freq = IEEE80211_24GHZ_BAND;
6591				query_rxdesc_status(agg_skb, &stats, true);
6592				PacketLength = stats.Length;
6593
6594				if(PacketLength > agg_skb->len) {
6595					break;
6596				}
6597				/* Process the MPDU recevied */
6598				skb = dev_alloc_skb(PacketLength);
6599				memcpy(skb_put(skb,PacketLength),agg_skb->data, PacketLength);
6600				skb_trim(skb, skb->len - 4/*sCrcLng*/);
6601
6602				rx_pkt_len = skb->len;
6603				ieee80211_hdr = (struct ieee80211_hdr_1addr *)skb->data;
6604				unicast_packet = false;
6605				if(is_broadcast_ether_addr(ieee80211_hdr->addr1)) {
6606					//TODO
6607				}else if(is_multicast_ether_addr(ieee80211_hdr->addr1)){
6608					//TODO
6609				}else {
6610					/* unicast packet */
6611					unicast_packet = true;
6612				}
6613				if(!ieee80211_rx(priv->ieee80211,skb, &stats)) {
6614					dev_kfree_skb_any(skb);
6615				} else {
6616					priv->stats.rxoktotal++;
6617					if(unicast_packet) {
6618						priv->stats.rxbytesunicast += rx_pkt_len;
6619					}
6620				}
6621				/* should trim the packet which has been copied to target skb */
6622				skb_pull(agg_skb, PacketLength);
6623				PacketShiftBytes = GetRxPacketShiftBytes819xUsb(&stats, true);
6624				PacketOccupiedLendth = PacketLength + PacketShiftBytes;
6625				if ((PacketOccupiedLendth & 0xFF) != 0) {
6626					PaddingBytes = 256 - (PacketOccupiedLendth & 0xFF);
6627					if (agg_skb->len > PaddingBytes)
6628						skb_pull(agg_skb, PaddingBytes);
6629					else
6630						agg_skb->len = 0;
6631				}
6632			}
6633			dev_kfree_skb(agg_skb);
6634		}
6635#endif
6636	} else {
6637		priv->stats.rxurberr++;
6638		printk("actual_length:%d\n", skb->len);
6639		dev_kfree_skb_any(skb);
6640	}
6641
6642}
6643
6644void
6645rtl819xusb_process_received_packet(
6646	struct net_device *dev,
6647	struct ieee80211_rx_stats *pstats
6648	)
6649{
6650//	bool bfreerfd=false, bqueued=false;
6651	u8* 	frame;
6652	u16     frame_len=0;
6653	struct r8192_priv *priv = ieee80211_priv(dev);
6654//	u8			index = 0;
6655//	u8			TID = 0;
6656	//u16			seqnum = 0;
6657	//PRX_TS_RECORD	pts = NULL;
6658
6659	// Get shifted bytes of Starting address of 802.11 header. 2006.09.28, by Emily
6660	//porting by amy 080508
6661	pstats->virtual_address += get_rxpacket_shiftbytes_819xusb(pstats);
6662	frame = pstats->virtual_address;
6663	frame_len = pstats->packetlength;
6664#ifdef TODO	// by amy about HCT
6665	if(!Adapter->bInHctTest)
6666		CountRxErrStatistics(Adapter, pRfd);
6667#endif
6668	{
6669	#ifdef ENABLE_PS  //by amy for adding ps function in future
6670		RT_RF_POWER_STATE rtState;
6671		// When RF is off, we should not count the packet for hw/sw synchronize
6672		// reason, ie. there may be a duration while sw switch is changed and hw
6673		// switch is being changed. 2006.12.04, by shien chang.
6674		Adapter->HalFunc.GetHwRegHandler(Adapter, HW_VAR_RF_STATE, (u8* )(&rtState));
6675		if (rtState == eRfOff)
6676		{
6677			return;
6678		}
6679	#endif
6680	priv->stats.rxframgment++;
6681
6682	}
6683#ifdef TODO
6684	RmMonitorSignalStrength(Adapter, pRfd);
6685#endif
6686	/* 2007/01/16 MH Add RX command packet handle here. */
6687	/* 2007/03/01 MH We have to release RFD and return if rx pkt is cmd pkt. */
6688	if (rtl819xusb_rx_command_packet(dev, pstats))
6689	{
6690		return;
6691	}
6692
6693#ifdef SW_CRC_CHECK
6694	SwCrcCheck();
6695#endif
6696
6697
6698}
6699
6700void query_rx_cmdpkt_desc_status(struct sk_buff *skb, struct ieee80211_rx_stats *stats)
6701{
6702//	rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
6703//	struct net_device *dev=info->dev;
6704//	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
6705	rx_desc_819x_usb *desc = (rx_desc_819x_usb *)skb->data;
6706//	rx_drvinfo_819x_usb  *driver_info;
6707
6708	//
6709	//Get Rx Descriptor Information
6710	//
6711	stats->virtual_address = (u8*)skb->data;
6712	stats->Length = desc->Length;
6713	stats->RxDrvInfoSize = 0;
6714	stats->RxBufShift = 0;
6715	stats->packetlength = stats->Length-scrclng;
6716	stats->fraglength = stats->packetlength;
6717	stats->fragoffset = 0;
6718	stats->ntotalfrag = 1;
6719}
6720
6721
6722void rtl8192_rx_cmd(struct sk_buff *skb)
6723{
6724	struct rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
6725	struct net_device *dev = info->dev;
6726	//int ret;
6727//	struct urb *rx_urb = info->urb;
6728	/* TODO */
6729	struct ieee80211_rx_stats stats = {
6730		.signal = 0,
6731		.noise = -98,
6732		.rate = 0,
6733		//      .mac_time = jiffies,
6734		.freq = IEEE80211_24GHZ_BAND,
6735	};
6736
6737	if((skb->len >=(20 + sizeof(rx_desc_819x_usb))) && (skb->len < RX_URB_SIZE))
6738	{
6739
6740		query_rx_cmdpkt_desc_status(skb,&stats);
6741		// this is to be done by amy 080508     prfd->queue_id = 1;
6742
6743
6744		//
6745		//  Process the command packet received.
6746		//
6747
6748		rtl819xusb_process_received_packet(dev,&stats);
6749
6750		dev_kfree_skb_any(skb);
6751	}
6752	else
6753		;
6754
6755
6756#if 0
6757	desc = (u32*)(skb->data);
6758	cmd = (desc[0] >> 30) & 0x03;
6759
6760	if(cmd == 0x00) {//beacon interrupt
6761		//send beacon packet
6762		skb = ieee80211_get_beacon(priv->ieee80211);
6763
6764		if(!skb){
6765			DMESG("not enought memory for allocating beacon");
6766			return;
6767		}
6768		skb->cb[0] = BEACON_PRIORITY;
6769		skb->cb[1] = 0;
6770		skb->cb[2] = ieeerate2rtlrate(priv->ieee80211->basic_rate);
6771		ret = rtl8192_tx(dev, skb);
6772
6773		if( ret != 0 ){
6774			printk(KERN_ALERT "tx beacon packet error : %d !\n", ret);
6775		}
6776		dev_kfree_skb_any(skb);
6777	} else {//0x00
6778		//{ log the device information
6779		// At present, It is not implemented just now.
6780		//}
6781	}
6782#endif
6783}
6784
6785void rtl8192_irq_rx_tasklet(struct r8192_priv *priv)
6786{
6787        struct sk_buff *skb;
6788	struct rtl8192_rx_info *info;
6789
6790        while (NULL != (skb = skb_dequeue(&priv->skb_queue))) {
6791		info = (struct rtl8192_rx_info *)skb->cb;
6792                switch (info->out_pipe) {
6793		/* Nomal packet pipe */
6794			case 3:
6795				//RT_TRACE(COMP_RECV, "normal in-pipe index(%d)\n",info->out_pipe);
6796				priv->IrpPendingCount--;
6797				rtl8192_rx_nomal(skb);
6798				break;
6799
6800				/* Command packet pipe */
6801			case 9:
6802				RT_TRACE(COMP_RECV, "command in-pipe index(%d)\n",\
6803						info->out_pipe);
6804
6805				rtl8192_rx_cmd(skb);
6806				break;
6807
6808			default: /* should never get here! */
6809				RT_TRACE(COMP_ERR, "Unknown in-pipe index(%d)\n",\
6810						info->out_pipe);
6811				dev_kfree_skb(skb);
6812				break;
6813
6814		}
6815        }
6816}
6817
6818static const struct net_device_ops rtl8192_netdev_ops = {
6819	.ndo_open               = rtl8192_open,
6820	.ndo_stop               = rtl8192_close,
6821	.ndo_get_stats          = rtl8192_stats,
6822	.ndo_tx_timeout         = tx_timeout,
6823	.ndo_do_ioctl           = rtl8192_ioctl,
6824	.ndo_set_multicast_list = r8192_set_multicast,
6825	.ndo_set_mac_address    = r8192_set_mac_adr,
6826	.ndo_validate_addr      = eth_validate_addr,
6827	.ndo_change_mtu         = eth_change_mtu,
6828	.ndo_start_xmit         = ieee80211_xmit,
6829};
6830
6831
6832/****************************************************************************
6833     ---------------------------- USB_STUFF---------------------------
6834*****************************************************************************/
6835
6836#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
6837static int __devinit rtl8192_usb_probe(struct usb_interface *intf,
6838			 const struct usb_device_id *id)
6839#else
6840static void * __devinit rtl8192_usb_probe(struct usb_device *udev,
6841			                unsigned int ifnum,
6842			          const struct usb_device_id *id)
6843#endif
6844{
6845//	unsigned long ioaddr = 0;
6846	struct net_device *dev = NULL;
6847	struct r8192_priv *priv= NULL;
6848#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
6849	struct usb_device *udev = interface_to_usbdev(intf);
6850#endif
6851        RT_TRACE(COMP_INIT, "Oops: i'm coming\n");
6852
6853	dev = alloc_ieee80211(sizeof(struct r8192_priv));
6854
6855#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
6856	SET_MODULE_OWNER(dev);
6857#endif
6858
6859#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
6860	usb_set_intfdata(intf, dev);
6861	SET_NETDEV_DEV(dev, &intf->dev);
6862#endif
6863	priv = ieee80211_priv(dev);
6864#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
6865	priv->ieee80211 = netdev_priv(dev);
6866#else
6867	priv->ieee80211 = (struct net_device *)dev->priv;
6868#endif
6869	priv->udev=udev;
6870
6871        dev->netdev_ops = &rtl8192_netdev_ops;
6872
6873         //DMESG("Oops: i'm coming\n");
6874#if WIRELESS_EXT >= 12
6875#if WIRELESS_EXT < 17
6876        dev->get_wireless_stats = r8192_get_wireless_stats;
6877#endif
6878        dev->wireless_handlers = (struct iw_handler_def *) &r8192_wx_handlers_def;
6879#endif
6880	dev->type=ARPHRD_ETHER;
6881
6882	dev->watchdog_timeo = HZ*3;	//modified by john, 0805
6883
6884	if (dev_alloc_name(dev, ifname) < 0){
6885                RT_TRACE(COMP_INIT, "Oops: devname already taken! Trying wlan%%d...\n");
6886		ifname = "wlan%d";
6887		dev_alloc_name(dev, ifname);
6888        }
6889
6890	RT_TRACE(COMP_INIT, "Driver probe completed1\n");
6891#if 1
6892	if(rtl8192_init(dev)!=0){
6893		RT_TRACE(COMP_ERR, "Initialization failed");
6894		goto fail;
6895	}
6896#endif
6897	netif_carrier_off(dev);
6898	netif_stop_queue(dev);
6899
6900	register_netdev(dev);
6901	RT_TRACE(COMP_INIT, "dev name=======> %s\n",dev->name);
6902	rtl8192_proc_init_one(dev);
6903
6904
6905	RT_TRACE(COMP_INIT, "Driver probe completed\n");
6906#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
6907	return dev;
6908#else
6909	return 0;
6910#endif
6911
6912
6913fail:
6914	free_ieee80211(dev);
6915
6916	RT_TRACE(COMP_ERR, "wlan driver load failed\n");
6917#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
6918	return NULL;
6919#else
6920	return -ENODEV;
6921#endif
6922
6923}
6924
6925//detach all the work and timer structure declared or inititialize in r8192U_init function.
6926void rtl8192_cancel_deferred_work(struct r8192_priv* priv)
6927{
6928
6929#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
6930	cancel_work_sync(&priv->reset_wq);
6931	cancel_delayed_work(&priv->watch_dog_wq);
6932	cancel_delayed_work(&priv->update_beacon_wq);
6933	cancel_work_sync(&priv->qos_activate);
6934	//cancel_work_sync(&priv->SetBWModeWorkItem);
6935	//cancel_work_sync(&priv->SwChnlWorkItem);
6936#else
6937#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
6938//	cancel_delayed_work(&priv->reset_wq);
6939	cancel_delayed_work(&priv->watch_dog_wq);
6940	cancel_delayed_work(&priv->update_beacon_wq);
6941//	cancel_delayed_work(&priv->qos_activate);
6942	//cancel_delayed_work(&priv->SetBWModeWorkItem);
6943	//cancel_delayed_work(&priv->SwChnlWorkItem);
6944#endif
6945#endif
6946
6947}
6948
6949
6950#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
6951static void __devexit rtl8192_usb_disconnect(struct usb_interface *intf)
6952#else
6953static void __devexit rtl8192_usb_disconnect(struct usb_device *udev, void *ptr)
6954#endif
6955{
6956#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
6957	struct net_device *dev = usb_get_intfdata(intf);
6958#else
6959	struct net_device *dev = (struct net_device *)ptr;
6960#endif
6961
6962	struct r8192_priv *priv = ieee80211_priv(dev);
6963 	if(dev){
6964
6965		unregister_netdev(dev);
6966
6967		RT_TRACE(COMP_DOWN, "=============>wlan driver to be removed\n");
6968		rtl8192_proc_remove_one(dev);
6969
6970			rtl8192_down(dev);
6971		if (priv->pFirmware)
6972		{
6973			kfree(priv->pFirmware);
6974			priv->pFirmware = NULL;
6975		}
6976	//	priv->rf_close(dev);
6977//		rtl8192_SetRFPowerState(dev, eRfOff);
6978		rtl8192_usb_deleteendpoints(dev);
6979#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
6980		destroy_workqueue(priv->priv_wq);
6981#endif
6982		//rtl8192_irq_disable(dev);
6983		//rtl8192_reset(dev);
6984		mdelay(10);
6985
6986	}
6987	free_ieee80211(dev);
6988	RT_TRACE(COMP_DOWN, "wlan driver removed\n");
6989}
6990
6991/* fun with the built-in ieee80211 stack... */
6992extern int ieee80211_debug_init(void);
6993extern void ieee80211_debug_exit(void);
6994extern int ieee80211_crypto_init(void);
6995extern void ieee80211_crypto_deinit(void);
6996extern int ieee80211_crypto_tkip_init(void);
6997extern void ieee80211_crypto_tkip_exit(void);
6998extern int ieee80211_crypto_ccmp_init(void);
6999extern void ieee80211_crypto_ccmp_exit(void);
7000extern int ieee80211_crypto_wep_init(void);
7001extern void ieee80211_crypto_wep_exit(void);
7002
7003static int __init rtl8192_usb_module_init(void)
7004{
7005        int ret;
7006
7007#ifdef CONFIG_IEEE80211_DEBUG
7008        ret = ieee80211_debug_init();
7009        if (ret) {
7010                printk(KERN_ERR "ieee80211_debug_init() failed %d\n", ret);
7011                return ret;
7012        }
7013#endif
7014        ret = ieee80211_crypto_init();
7015        if (ret) {
7016                printk(KERN_ERR "ieee80211_crypto_init() failed %d\n", ret);
7017                return ret;
7018        }
7019
7020        ret = ieee80211_crypto_tkip_init();
7021        if (ret) {
7022                printk(KERN_ERR "ieee80211_crypto_tkip_init() failed %d\n",
7023                        ret);
7024                return ret;
7025        }
7026
7027        ret = ieee80211_crypto_ccmp_init();
7028        if (ret) {
7029                printk(KERN_ERR "ieee80211_crypto_ccmp_init() failed %d\n",
7030                        ret);
7031                return ret;
7032        }
7033
7034        ret = ieee80211_crypto_wep_init();
7035        if (ret) {
7036                printk(KERN_ERR "ieee80211_crypto_wep_init() failed %d\n", ret);
7037                return ret;
7038        }
7039
7040	printk(KERN_INFO "\nLinux kernel driver for RTL8192 based WLAN cards\n");
7041	printk(KERN_INFO "Copyright (c) 2007-2008, Realsil Wlan\n");
7042	RT_TRACE(COMP_INIT, "Initializing module");
7043	RT_TRACE(COMP_INIT, "Wireless extensions version %d", WIRELESS_EXT);
7044	rtl8192_proc_module_init();
7045	return usb_register(&rtl8192_usb_driver);
7046}
7047
7048
7049static void __exit rtl8192_usb_module_exit(void)
7050{
7051	usb_deregister(&rtl8192_usb_driver);
7052
7053	RT_TRACE(COMP_DOWN, "Exiting");
7054//	rtl8192_proc_module_remove();
7055}
7056
7057
7058void rtl8192_try_wake_queue(struct net_device *dev, int pri)
7059{
7060	unsigned long flags;
7061	short enough_desc;
7062	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
7063
7064	spin_lock_irqsave(&priv->tx_lock,flags);
7065	enough_desc = check_nic_enough_desc(dev,pri);
7066        spin_unlock_irqrestore(&priv->tx_lock,flags);
7067
7068	if(enough_desc)
7069		ieee80211_wake_queue(priv->ieee80211);
7070}
7071
7072void EnableHWSecurityConfig8192(struct net_device *dev)
7073{
7074        u8 SECR_value = 0x0;
7075	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
7076	 struct ieee80211_device* ieee = priv->ieee80211;
7077	SECR_value = SCR_TxEncEnable | SCR_RxDecEnable;
7078#if 1
7079	if (((KEY_TYPE_WEP40 == ieee->pairwise_key_type) || (KEY_TYPE_WEP104 == ieee->pairwise_key_type)) && (priv->ieee80211->auth_mode != 2))
7080	{
7081		SECR_value |= SCR_RxUseDK;
7082		SECR_value |= SCR_TxUseDK;
7083	}
7084	else if ((ieee->iw_mode == IW_MODE_ADHOC) && (ieee->pairwise_key_type & (KEY_TYPE_CCMP | KEY_TYPE_TKIP)))
7085	{
7086		SECR_value |= SCR_RxUseDK;
7087		SECR_value |= SCR_TxUseDK;
7088	}
7089#endif
7090        //add HWSec active enable here.
7091//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
7092
7093	ieee->hwsec_active = 1;
7094
7095	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
7096	{
7097		ieee->hwsec_active = 0;
7098		SECR_value &= ~SCR_RxDecEnable;
7099	}
7100	RT_TRACE(COMP_SEC,"%s:, hwsec:%d, pairwise_key:%d, SECR_value:%x\n", __FUNCTION__, \
7101			ieee->hwsec_active, ieee->pairwise_key_type, SECR_value);
7102	{
7103                write_nic_byte(dev, SECR,  SECR_value);//SECR_value |  SCR_UseDK );
7104        }
7105}
7106
7107
7108void setKey(	struct net_device *dev,
7109		u8 EntryNo,
7110		u8 KeyIndex,
7111		u16 KeyType,
7112		u8 *MacAddr,
7113		u8 DefaultKey,
7114		u32 *KeyContent )
7115{
7116	u32 TargetCommand = 0;
7117	u32 TargetContent = 0;
7118	u16 usConfig = 0;
7119	u8 i;
7120	if (EntryNo >= TOTAL_CAM_ENTRY)
7121		RT_TRACE(COMP_ERR, "cam entry exceeds in setKey()\n");
7122
7123	RT_TRACE(COMP_SEC, "====>to setKey(), dev:%p, EntryNo:%d, KeyIndex:%d, KeyType:%d, MacAddr"MAC_FMT"\n", dev,EntryNo, KeyIndex, KeyType, MAC_ARG(MacAddr));
7124
7125	if (DefaultKey)
7126		usConfig |= BIT15 | (KeyType<<2);
7127	else
7128		usConfig |= BIT15 | (KeyType<<2) | KeyIndex;
7129//	usConfig |= BIT15 | (KeyType<<2) | (DefaultKey<<5) | KeyIndex;
7130
7131
7132	for(i=0 ; i<CAM_CONTENT_COUNT; i++){
7133		TargetCommand  = i+CAM_CONTENT_COUNT*EntryNo;
7134		TargetCommand |= BIT31|BIT16;
7135
7136		if(i==0){//MAC|Config
7137			TargetContent = (u32)(*(MacAddr+0)) << 16|
7138					(u32)(*(MacAddr+1)) << 24|
7139					(u32)usConfig;
7140
7141			write_nic_dword(dev, WCAMI, TargetContent);
7142			write_nic_dword(dev, RWCAM, TargetCommand);
7143	//		printk("setkey cam =%8x\n", read_cam(dev, i+6*EntryNo));
7144		}
7145		else if(i==1){//MAC
7146                        TargetContent = (u32)(*(MacAddr+2)) 	 |
7147                                        (u32)(*(MacAddr+3)) <<  8|
7148                                        (u32)(*(MacAddr+4)) << 16|
7149                                        (u32)(*(MacAddr+5)) << 24;
7150			write_nic_dword(dev, WCAMI, TargetContent);
7151			write_nic_dword(dev, RWCAM, TargetCommand);
7152		}
7153		else {
7154			//Key Material
7155			if(KeyContent !=NULL){
7156			write_nic_dword(dev, WCAMI, (u32)(*(KeyContent+i-2)) );
7157			write_nic_dword(dev, RWCAM, TargetCommand);
7158		}
7159	}
7160	}
7161
7162}
7163
7164/***************************************************************************
7165     ------------------- module init / exit stubs ----------------
7166****************************************************************************/
7167module_init(rtl8192_usb_module_init);
7168module_exit(rtl8192_usb_module_exit);
7169