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