• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify  *
11 * it under the terms of the GNU General Public License as published by  *
12 * the Free Software Foundation; either version 2 of the License, or     *
13 * (at your option) any later version.                                   *
14 *                                                                       *
15 * This program is distributed in the hope that it will be useful,       *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
18 * GNU General Public License for more details.                          *
19 *                                                                       *
20 * You should have received a copy of the GNU General Public License     *
21 * along with this program; if not, write to the                         *
22 * Free Software Foundation, Inc.,                                       *
23 * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
24 *                                                                       *
25 *************************************************************************
26
27    Module Name:
28    sta_ioctl.c
29
30    Abstract:
31    IOCTL related subroutines
32
33    Revision History:
34    Who         When          What
35    --------    ----------    ----------------------------------------------
36    Rory Chen   01-03-2003    created
37	Rory Chen   02-14-2005    modify to support RT61
38*/
39
40#include	"rt_config.h"
41
42#ifdef DBG
43extern ULONG    RTDebugLevel;
44#endif
45
46#define NR_WEP_KEYS 				4
47#define WEP_SMALL_KEY_LEN 			(40/8)
48#define WEP_LARGE_KEY_LEN 			(104/8)
49
50#define GROUP_KEY_NO                4
51
52#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
53#define IWE_STREAM_ADD_EVENT(_A, _B, _C, _D, _E)		iwe_stream_add_event(_A, _B, _C, _D, _E)
54#define IWE_STREAM_ADD_POINT(_A, _B, _C, _D, _E)		iwe_stream_add_point(_A, _B, _C, _D, _E)
55#define IWE_STREAM_ADD_VALUE(_A, _B, _C, _D, _E, _F)	iwe_stream_add_value(_A, _B, _C, _D, _E, _F)
56#else
57#define IWE_STREAM_ADD_EVENT(_A, _B, _C, _D, _E)		iwe_stream_add_event(_B, _C, _D, _E)
58#define IWE_STREAM_ADD_POINT(_A, _B, _C, _D, _E)		iwe_stream_add_point(_B, _C, _D, _E)
59#define IWE_STREAM_ADD_VALUE(_A, _B, _C, _D, _E, _F)	iwe_stream_add_value(_B, _C, _D, _E, _F)
60#endif
61
62extern UCHAR    CipherWpa2Template[];
63extern UCHAR    CipherWpaPskTkip[];
64extern UCHAR    CipherWpaPskTkipLen;
65
66typedef struct PACKED _RT_VERSION_INFO{
67    UCHAR       DriverVersionW;
68    UCHAR       DriverVersionX;
69    UCHAR       DriverVersionY;
70    UCHAR       DriverVersionZ;
71    UINT        DriverBuildYear;
72    UINT        DriverBuildMonth;
73    UINT        DriverBuildDay;
74} RT_VERSION_INFO, *PRT_VERSION_INFO;
75
76struct iw_priv_args privtab[] = {
77{ RTPRIV_IOCTL_SET,
78  IW_PRIV_TYPE_CHAR | 1024, 0,
79  "set"},
80
81{ RTPRIV_IOCTL_SHOW, 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK,
82  ""},
83{ RTPRIV_IOCTL_SHOW, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK,
84  ""},
85/* --- sub-ioctls definitions --- */
86    { SHOW_CONN_STATUS,
87	  0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "connStatus" },
88	{ SHOW_DRVIER_VERION,
89	  0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "driverVer" },
90    { SHOW_BA_INFO,
91	  0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "bainfo" },
92	{ SHOW_DESC_INFO,
93	  0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "descinfo" },
94    { RAIO_OFF,
95	  0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "radio_off" },
96	{ RAIO_ON,
97	  0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "radio_on" },
98#ifdef QOS_DLS_SUPPORT
99	{ SHOW_DLS_ENTRY_INFO,
100	  0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "dlsentryinfo" },
101#endif // QOS_DLS_SUPPORT //
102	{ SHOW_CFG_VALUE,
103	  IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "show" },
104	{ SHOW_ADHOC_ENTRY_INFO,
105	  0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "adhocEntry" },
106
107/* --- sub-ioctls relations --- */
108
109#ifdef DBG
110{ RTPRIV_IOCTL_BBP,
111  IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK,
112  "bbp"},
113{ RTPRIV_IOCTL_MAC,
114  IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | 1024,
115  "mac"},
116{ RTPRIV_IOCTL_E2P,
117  IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | 1024,
118  "e2p"},
119#endif  /* DBG */
120
121{ RTPRIV_IOCTL_STATISTICS,
122  0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK,
123  "stat"},
124{ RTPRIV_IOCTL_GSITESURVEY,
125  0, IW_PRIV_TYPE_CHAR | 1024,
126  "get_site_survey"},
127};
128
129INT Set_SSID_Proc(
130    IN  PRTMP_ADAPTER   pAdapter,
131    IN  PUCHAR          arg);
132
133#ifdef WMM_SUPPORT
134INT	Set_WmmCapable_Proc(
135	IN	PRTMP_ADAPTER	pAd,
136	IN	PUCHAR			arg);
137#endif
138
139INT Set_NetworkType_Proc(
140    IN  PRTMP_ADAPTER   pAdapter,
141    IN  PUCHAR          arg);
142
143INT Set_AuthMode_Proc(
144    IN  PRTMP_ADAPTER   pAdapter,
145    IN  PUCHAR          arg);
146
147INT Set_EncrypType_Proc(
148    IN  PRTMP_ADAPTER   pAdapter,
149    IN  PUCHAR          arg);
150
151INT Set_DefaultKeyID_Proc(
152    IN  PRTMP_ADAPTER   pAdapter,
153    IN  PUCHAR          arg);
154
155INT Set_Key1_Proc(
156    IN  PRTMP_ADAPTER   pAdapter,
157    IN  PUCHAR          arg);
158
159INT Set_Key2_Proc(
160    IN  PRTMP_ADAPTER   pAdapter,
161    IN  PUCHAR          arg);
162
163INT Set_Key3_Proc(
164    IN  PRTMP_ADAPTER   pAdapter,
165    IN  PUCHAR          arg);
166
167INT Set_Key4_Proc(
168    IN  PRTMP_ADAPTER   pAdapter,
169    IN  PUCHAR          arg);
170
171INT Set_WPAPSK_Proc(
172    IN  PRTMP_ADAPTER   pAdapter,
173    IN  PUCHAR          arg);
174
175
176INT Set_PSMode_Proc(
177    IN  PRTMP_ADAPTER   pAdapter,
178    IN  PUCHAR          arg);
179
180#ifdef WPA_SUPPLICANT_SUPPORT
181INT Set_Wpa_Support(
182    IN	PRTMP_ADAPTER	pAd,
183	IN	PUCHAR			arg);
184#endif // WPA_SUPPLICANT_SUPPORT //
185
186#ifdef DBG
187VOID RTMPIoctlBBP(
188	IN	PRTMP_ADAPTER	pAdapter,
189	IN	struct iwreq	*wrq);
190
191VOID RTMPIoctlMAC(
192	IN	PRTMP_ADAPTER	pAdapter,
193	IN	struct iwreq	*wrq);
194
195VOID RTMPIoctlE2PROM(
196    IN  PRTMP_ADAPTER   pAdapter,
197    IN  struct iwreq    *wrq);
198#endif // DBG //
199
200
201NDIS_STATUS RTMPWPANoneAddKeyProc(
202    IN  PRTMP_ADAPTER   pAd,
203    IN	PVOID			pBuf);
204
205INT Set_FragTest_Proc(
206    IN  PRTMP_ADAPTER   pAdapter,
207    IN  PUCHAR          arg);
208
209#ifdef DOT11_N_SUPPORT
210INT Set_TGnWifiTest_Proc(
211    IN  PRTMP_ADAPTER   pAd,
212    IN  PUCHAR          arg);
213#endif // DOT11_N_SUPPORT //
214
215INT Set_LongRetryLimit_Proc(
216	IN	PRTMP_ADAPTER	pAdapter,
217	IN	PUCHAR			arg);
218
219INT Set_ShortRetryLimit_Proc(
220	IN	PRTMP_ADAPTER	pAdapter,
221	IN	PUCHAR			arg);
222
223#ifdef EXT_BUILD_CHANNEL_LIST
224INT Set_Ieee80211dClientMode_Proc(
225    IN  PRTMP_ADAPTER   pAdapter,
226    IN  PUCHAR          arg);
227#endif // EXT_BUILD_CHANNEL_LIST //
228
229#ifdef CARRIER_DETECTION_SUPPORT
230INT Set_CarrierDetect_Proc(
231    IN  PRTMP_ADAPTER   pAd,
232    IN  PUCHAR          arg);
233#endif // CARRIER_DETECTION_SUPPORT //
234
235INT	Show_Adhoc_MacTable_Proc(
236	IN	PRTMP_ADAPTER	pAd,
237	IN	PCHAR			extra);
238
239static struct {
240	CHAR *name;
241	INT (*set_proc)(PRTMP_ADAPTER pAdapter, PUCHAR arg);
242} *PRTMP_PRIVATE_SET_PROC, RTMP_PRIVATE_SUPPORT_PROC[] = {
243	{"DriverVersion",				Set_DriverVersion_Proc},
244	{"CountryRegion",				Set_CountryRegion_Proc},
245	{"CountryRegionABand",			Set_CountryRegionABand_Proc},
246	{"SSID",						Set_SSID_Proc},
247	{"WirelessMode",				Set_WirelessMode_Proc},
248	{"TxBurst",					Set_TxBurst_Proc},
249	{"TxPreamble",				Set_TxPreamble_Proc},
250	{"TxPower",					Set_TxPower_Proc},
251	{"Channel",					Set_Channel_Proc},
252	{"BGProtection",				Set_BGProtection_Proc},
253	{"RTSThreshold",				Set_RTSThreshold_Proc},
254	{"FragThreshold",				Set_FragThreshold_Proc},
255#ifdef DOT11_N_SUPPORT
256	{"HtBw",		                Set_HtBw_Proc},
257	{"HtMcs",		                Set_HtMcs_Proc},
258	{"HtGi",		                Set_HtGi_Proc},
259	{"HtOpMode",		            Set_HtOpMode_Proc},
260	{"HtExtcha",		            Set_HtExtcha_Proc},
261	{"HtMpduDensity",		        Set_HtMpduDensity_Proc},
262	{"HtBaWinSize",		        	Set_HtBaWinSize_Proc},
263	{"HtRdg",		        		Set_HtRdg_Proc},
264	{"HtAmsdu",		        		Set_HtAmsdu_Proc},
265	{"HtAutoBa",		        	Set_HtAutoBa_Proc},
266	{"HtBaDecline",					Set_BADecline_Proc},
267	{"HtProtect",		        	Set_HtProtect_Proc},
268	{"HtMimoPs",		        	Set_HtMimoPs_Proc},
269#endif // DOT11_N_SUPPORT //
270
271#ifdef AGGREGATION_SUPPORT
272	{"PktAggregate",				Set_PktAggregate_Proc},
273#endif
274
275#ifdef WMM_SUPPORT
276	{"WmmCapable",					Set_WmmCapable_Proc},
277#endif
278	{"IEEE80211H",					Set_IEEE80211H_Proc},
279    {"NetworkType",                 Set_NetworkType_Proc},
280	{"AuthMode",					Set_AuthMode_Proc},
281	{"EncrypType",					Set_EncrypType_Proc},
282	{"DefaultKeyID",				Set_DefaultKeyID_Proc},
283	{"Key1",						Set_Key1_Proc},
284	{"Key2",						Set_Key2_Proc},
285	{"Key3",						Set_Key3_Proc},
286	{"Key4",						Set_Key4_Proc},
287	{"WPAPSK",						Set_WPAPSK_Proc},
288	{"ResetCounter",				Set_ResetStatCounter_Proc},
289	{"PSMode",                      Set_PSMode_Proc},
290#ifdef DBG
291	{"Debug",						Set_Debug_Proc},
292#endif
293
294#ifdef RALINK_ATE
295	{"ATE",							Set_ATE_Proc},
296	{"ATEDA",						Set_ATE_DA_Proc},
297	{"ATESA",						Set_ATE_SA_Proc},
298	{"ATEBSSID",					Set_ATE_BSSID_Proc},
299	{"ATECHANNEL",					Set_ATE_CHANNEL_Proc},
300	{"ATETXPOW0",					Set_ATE_TX_POWER0_Proc},
301	{"ATETXPOW1",					Set_ATE_TX_POWER1_Proc},
302	{"ATETXANT",					Set_ATE_TX_Antenna_Proc},
303	{"ATERXANT",					Set_ATE_RX_Antenna_Proc},
304	{"ATETXFREQOFFSET",				Set_ATE_TX_FREQOFFSET_Proc},
305	{"ATETXBW",						Set_ATE_TX_BW_Proc},
306	{"ATETXLEN",					Set_ATE_TX_LENGTH_Proc},
307	{"ATETXCNT",					Set_ATE_TX_COUNT_Proc},
308	{"ATETXMCS",					Set_ATE_TX_MCS_Proc},
309	{"ATETXMODE",					Set_ATE_TX_MODE_Proc},
310	{"ATETXGI",						Set_ATE_TX_GI_Proc},
311	{"ATERXFER",					Set_ATE_RX_FER_Proc},
312	{"ATERRF",						Set_ATE_Read_RF_Proc},
313	{"ATEWRF1",						Set_ATE_Write_RF1_Proc},
314	{"ATEWRF2",						Set_ATE_Write_RF2_Proc},
315	{"ATEWRF3",						Set_ATE_Write_RF3_Proc},
316	{"ATEWRF4",						Set_ATE_Write_RF4_Proc},
317	{"ATELDE2P",				    Set_ATE_Load_E2P_Proc},
318	{"ATERE2P",						Set_ATE_Read_E2P_Proc},
319	{"ATESHOW",						Set_ATE_Show_Proc},
320	{"ATEHELP",						Set_ATE_Help_Proc},
321
322#ifdef RALINK_28xx_QA
323	{"TxStop",						Set_TxStop_Proc},
324	{"RxStop",						Set_RxStop_Proc},
325#endif // RALINK_28xx_QA //
326#endif // RALINK_ATE //
327
328#ifdef WPA_SUPPLICANT_SUPPORT
329    {"WpaSupport",                  Set_Wpa_Support},
330#endif // WPA_SUPPLICANT_SUPPORT //
331
332
333
334	{"FixedTxMode",                 Set_FixedTxMode_Proc},
335#ifdef CONFIG_APSTA_MIXED_SUPPORT
336	{"OpMode",						Set_OpMode_Proc},
337#endif // CONFIG_APSTA_MIXED_SUPPORT //
338#ifdef DOT11_N_SUPPORT
339    {"TGnWifiTest",                 Set_TGnWifiTest_Proc},
340    {"ForceGF",		        		Set_ForceGF_Proc},
341#endif // DOT11_N_SUPPORT //
342#ifdef QOS_DLS_SUPPORT
343	{"DlsAddEntry",					Set_DlsAddEntry_Proc},
344	{"DlsTearDownEntry",			Set_DlsTearDownEntry_Proc},
345#endif // QOS_DLS_SUPPORT //
346	{"LongRetry",	        		Set_LongRetryLimit_Proc},
347	{"ShortRetry",	        		Set_ShortRetryLimit_Proc},
348#ifdef EXT_BUILD_CHANNEL_LIST
349	{"11dClientMode",				Set_Ieee80211dClientMode_Proc},
350#endif // EXT_BUILD_CHANNEL_LIST //
351#ifdef CARRIER_DETECTION_SUPPORT
352	{"CarrierDetect",				Set_CarrierDetect_Proc},
353#endif // CARRIER_DETECTION_SUPPORT //
354
355	{NULL,}
356};
357
358
359VOID RTMPAddKey(
360	IN	PRTMP_ADAPTER	    pAd,
361	IN	PNDIS_802_11_KEY    pKey)
362{
363	ULONG				KeyIdx;
364	MAC_TABLE_ENTRY  	*pEntry;
365
366    DBGPRINT(RT_DEBUG_TRACE, ("RTMPAddKey ------>\n"));
367
368	if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
369	{
370		if (pKey->KeyIndex & 0x80000000)
371		{
372		    if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
373            {
374                NdisZeroMemory(pAd->StaCfg.PMK, 32);
375                NdisMoveMemory(pAd->StaCfg.PMK, pKey->KeyMaterial, pKey->KeyLength);
376                goto end;
377            }
378		    // Update PTK
379		    NdisZeroMemory(&pAd->SharedKey[BSS0][0], sizeof(CIPHER_KEY));
380            pAd->SharedKey[BSS0][0].KeyLen = LEN_TKIP_EK;
381            NdisMoveMemory(pAd->SharedKey[BSS0][0].Key, pKey->KeyMaterial, LEN_TKIP_EK);
382#ifdef WPA_SUPPLICANT_SUPPORT
383            if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
384            {
385                NdisMoveMemory(pAd->SharedKey[BSS0][0].RxMic, pKey->KeyMaterial + LEN_TKIP_EK, LEN_TKIP_TXMICK);
386                NdisMoveMemory(pAd->SharedKey[BSS0][0].TxMic, pKey->KeyMaterial + LEN_TKIP_EK + LEN_TKIP_TXMICK, LEN_TKIP_RXMICK);
387            }
388            else
389#endif // WPA_SUPPLICANT_SUPPORT //
390            {
391            	NdisMoveMemory(pAd->SharedKey[BSS0][0].TxMic, pKey->KeyMaterial + LEN_TKIP_EK, LEN_TKIP_TXMICK);
392                NdisMoveMemory(pAd->SharedKey[BSS0][0].RxMic, pKey->KeyMaterial + LEN_TKIP_EK + LEN_TKIP_TXMICK, LEN_TKIP_RXMICK);
393            }
394
395            // Decide its ChiperAlg
396        	if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
397        		pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_TKIP;
398        	else if (pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled)
399        		pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES;
400        	else
401        		pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_NONE;
402
403            // Update these related information to MAC_TABLE_ENTRY
404        	pEntry = &pAd->MacTab.Content[BSSID_WCID];
405            NdisMoveMemory(pEntry->PairwiseKey.Key, pAd->SharedKey[BSS0][0].Key, LEN_TKIP_EK);
406        	NdisMoveMemory(pEntry->PairwiseKey.RxMic, pAd->SharedKey[BSS0][0].RxMic, LEN_TKIP_RXMICK);
407        	NdisMoveMemory(pEntry->PairwiseKey.TxMic, pAd->SharedKey[BSS0][0].TxMic, LEN_TKIP_TXMICK);
408        	pEntry->PairwiseKey.CipherAlg = pAd->SharedKey[BSS0][0].CipherAlg;
409
410        	// Update pairwise key information to ASIC Shared Key Table
411        	AsicAddSharedKeyEntry(pAd,
412        						  BSS0,
413        						  0,
414        						  pAd->SharedKey[BSS0][0].CipherAlg,
415        						  pAd->SharedKey[BSS0][0].Key,
416        						  pAd->SharedKey[BSS0][0].TxMic,
417        						  pAd->SharedKey[BSS0][0].RxMic);
418
419        	// Update ASIC WCID attribute table and IVEIV table
420        	RTMPAddWcidAttributeEntry(pAd,
421        							  BSS0,
422        							  0,
423        							  pAd->SharedKey[BSS0][0].CipherAlg,
424        							  pEntry);
425
426            if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA2)
427            {
428                // set 802.1x port control
429	            //pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
430				STA_PORT_SECURED(pAd);
431
432                // Indicate Connected for GUI
433                pAd->IndicateMediaState = NdisMediaStateConnected;
434            }
435		}
436        else
437        {
438            // Update GTK
439            pAd->StaCfg.DefaultKeyId = (pKey->KeyIndex & 0xFF);
440            NdisZeroMemory(&pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId], sizeof(CIPHER_KEY));
441            pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].KeyLen = LEN_TKIP_EK;
442            NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].Key, pKey->KeyMaterial, LEN_TKIP_EK);
443#ifdef WPA_SUPPLICANT_SUPPORT
444            if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption2Enabled)
445            {
446                NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].RxMic, pKey->KeyMaterial + LEN_TKIP_EK, LEN_TKIP_TXMICK);
447                NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].TxMic, pKey->KeyMaterial + LEN_TKIP_EK + LEN_TKIP_TXMICK, LEN_TKIP_RXMICK);
448            }
449            else
450#endif // WPA_SUPPLICANT_SUPPORT //
451            {
452            	NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].TxMic, pKey->KeyMaterial + LEN_TKIP_EK, LEN_TKIP_TXMICK);
453                NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].RxMic, pKey->KeyMaterial + LEN_TKIP_EK + LEN_TKIP_TXMICK, LEN_TKIP_RXMICK);
454            }
455
456            // Update Shared Key CipherAlg
457    		pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_NONE;
458    		if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption2Enabled)
459    			pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_TKIP;
460    		else if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption3Enabled)
461    			pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_AES;
462
463            // Update group key information to ASIC Shared Key Table
464        	AsicAddSharedKeyEntry(pAd,
465        						  BSS0,
466        						  pAd->StaCfg.DefaultKeyId,
467        						  pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg,
468        						  pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].Key,
469        						  pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].TxMic,
470        						  pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].RxMic);
471
472        	// Update ASIC WCID attribute table and IVEIV table
473        	RTMPAddWcidAttributeEntry(pAd,
474        							  BSS0,
475        							  pAd->StaCfg.DefaultKeyId,
476        							  pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg,
477        							  NULL);
478
479            // set 802.1x port control
480	        //pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
481			STA_PORT_SECURED(pAd);
482
483            // Indicate Connected for GUI
484            pAd->IndicateMediaState = NdisMediaStateConnected;
485        }
486	}
487	else	// dynamic WEP from wpa_supplicant
488	{
489		UCHAR	CipherAlg;
490    	PUCHAR	Key;
491
492		if(pKey->KeyLength == 32)
493			goto end;
494
495		KeyIdx = pKey->KeyIndex & 0x0fffffff;
496
497		if (KeyIdx < 4)
498		{
499			// it is a default shared key, for Pairwise key setting
500			if (pKey->KeyIndex & 0x80000000)
501			{
502				pEntry = MacTableLookup(pAd, pKey->BSSID);
503
504				if (pEntry)
505				{
506					DBGPRINT(RT_DEBUG_TRACE, ("RTMPAddKey: Set Pair-wise Key\n"));
507
508					// set key material and key length
509 					pEntry->PairwiseKey.KeyLen = (UCHAR)pKey->KeyLength;
510					NdisMoveMemory(pEntry->PairwiseKey.Key, &pKey->KeyMaterial, pKey->KeyLength);
511
512					// set Cipher type
513					if (pKey->KeyLength == 5)
514						pEntry->PairwiseKey.CipherAlg = CIPHER_WEP64;
515					else
516						pEntry->PairwiseKey.CipherAlg = CIPHER_WEP128;
517
518					// Add Pair-wise key to Asic
519					AsicAddPairwiseKeyEntry(
520						pAd,
521						pEntry->Addr,
522						(UCHAR)pEntry->Aid,
523                		&pEntry->PairwiseKey);
524
525					// update WCID attribute table and IVEIV table for this entry
526					RTMPAddWcidAttributeEntry(
527						pAd,
528						BSS0,
529						KeyIdx, // The value may be not zero
530						pEntry->PairwiseKey.CipherAlg,
531						pEntry);
532
533				}
534			}
535			else
536            {
537				// Default key for tx (shared key)
538				pAd->StaCfg.DefaultKeyId = (UCHAR) KeyIdx;
539
540				// set key material and key length
541				pAd->SharedKey[BSS0][KeyIdx].KeyLen = (UCHAR) pKey->KeyLength;
542				NdisMoveMemory(pAd->SharedKey[BSS0][KeyIdx].Key, &pKey->KeyMaterial, pKey->KeyLength);
543
544				// Set Ciper type
545				if (pKey->KeyLength == 5)
546					pAd->SharedKey[BSS0][KeyIdx].CipherAlg = CIPHER_WEP64;
547				else
548					pAd->SharedKey[BSS0][KeyIdx].CipherAlg = CIPHER_WEP128;
549
550    			CipherAlg = pAd->SharedKey[BSS0][KeyIdx].CipherAlg;
551    			Key = pAd->SharedKey[BSS0][KeyIdx].Key;
552
553				// Set Group key material to Asic
554    			AsicAddSharedKeyEntry(pAd, BSS0, KeyIdx, CipherAlg, Key, NULL, NULL);
555
556				// Update WCID attribute table and IVEIV table for this group key table
557				RTMPAddWcidAttributeEntry(pAd, BSS0, KeyIdx, CipherAlg, NULL);
558
559			}
560		}
561	}
562end:
563	return;
564}
565
566char * rtstrchr(const char * s, int c)
567{
568    for(; *s != (char) c; ++s)
569        if (*s == '\0')
570            return NULL;
571    return (char *) s;
572}
573
574/*
575This is required for LinEX2004/kernel2.6.7 to provide iwlist scanning function
576*/
577
578int
579rt_ioctl_giwname(struct net_device *dev,
580		   struct iw_request_info *info,
581		   char *name, char *extra)
582{
583//	PRTMP_ADAPTER pAdapter = (PRTMP_ADAPTER) dev->priv;
584
585#ifdef RT2870
586	strncpy(name, "RT2870 Wireless", IFNAMSIZ);
587#endif // RT2870 //
588	return 0;
589}
590
591int rt_ioctl_siwfreq(struct net_device *dev,
592			struct iw_request_info *info,
593			struct iw_freq *freq, char *extra)
594{
595	PRTMP_ADAPTER pAdapter = (PRTMP_ADAPTER) dev->priv;
596	int 	chan = -1;
597
598    //check if the interface is down
599    if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
600    {
601        DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
602        return -ENETDOWN;
603    }
604
605
606	if (freq->e > 1)
607		return -EINVAL;
608
609	if((freq->e == 0) && (freq->m <= 1000))
610		chan = freq->m;	// Setting by channel number
611	else
612		MAP_KHZ_TO_CHANNEL_ID( (freq->m /100) , chan); // Setting by frequency - search the table , like 2.412G, 2.422G,
613
614    if (ChannelSanity(pAdapter, chan) == TRUE)
615    {
616	pAdapter->CommonCfg.Channel = chan;
617	DBGPRINT(RT_DEBUG_ERROR, ("==>rt_ioctl_siwfreq::SIOCSIWFREQ[cmd=0x%x] (Channel=%d)\n", SIOCSIWFREQ, pAdapter->CommonCfg.Channel));
618    }
619    else
620        return -EINVAL;
621
622	return 0;
623}
624int rt_ioctl_giwfreq(struct net_device *dev,
625		   struct iw_request_info *info,
626		   struct iw_freq *freq, char *extra)
627{
628    VIRTUAL_ADAPTER *pVirtualAd = NULL;
629	PRTMP_ADAPTER pAdapter = NULL;
630	UCHAR ch;
631	ULONG	m;
632
633	if (dev->priv_flags == INT_MAIN)
634	{
635		pAdapter = dev->priv;
636	}
637	else
638	{
639		pVirtualAd = dev->priv;
640		if (pVirtualAd && pVirtualAd->RtmpDev)
641			pAdapter = pVirtualAd->RtmpDev->priv;
642	}
643
644	if (pAdapter == NULL)
645	{
646		/* if 1st open fail, pAd will be free;
647		   So the net_dev->priv will be NULL in 2rd open */
648		return -ENETDOWN;
649	}
650
651		ch = pAdapter->CommonCfg.Channel;
652
653	DBGPRINT(RT_DEBUG_TRACE,("==>rt_ioctl_giwfreq  %d\n", ch));
654
655    MAP_CHANNEL_ID_TO_KHZ(ch, m);
656	freq->m = m * 100;
657	freq->e = 1;
658	return 0;
659}
660
661int rt_ioctl_siwmode(struct net_device *dev,
662		   struct iw_request_info *info,
663		   __u32 *mode, char *extra)
664{
665	PRTMP_ADAPTER pAdapter = (PRTMP_ADAPTER) dev->priv;
666
667	//check if the interface is down
668    if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
669    {
670    	DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
671       	return -ENETDOWN;
672    }
673
674	switch (*mode)
675	{
676		case IW_MODE_ADHOC:
677			Set_NetworkType_Proc(pAdapter, "Adhoc");
678			break;
679		case IW_MODE_INFRA:
680			Set_NetworkType_Proc(pAdapter, "Infra");
681			break;
682#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,4,20))
683        case IW_MODE_MONITOR:
684			Set_NetworkType_Proc(pAdapter, "Monitor");
685			break;
686#endif
687		default:
688			DBGPRINT(RT_DEBUG_TRACE, ("===>rt_ioctl_siwmode::SIOCSIWMODE (unknown %d)\n", *mode));
689			return -EINVAL;
690	}
691
692	// Reset Ralink supplicant to not use, it will be set to start when UI set PMK key
693	pAdapter->StaCfg.WpaState = SS_NOTUSE;
694
695	return 0;
696}
697
698int rt_ioctl_giwmode(struct net_device *dev,
699		   struct iw_request_info *info,
700		   __u32 *mode, char *extra)
701{
702	PRTMP_ADAPTER 	pAdapter = NULL;
703	VIRTUAL_ADAPTER *pVirtualAd = NULL;
704
705	if (dev->priv_flags == INT_MAIN)
706	{
707		pAdapter = dev->priv;
708	}
709	else
710	{
711		pVirtualAd = dev->priv;
712		if (pVirtualAd && pVirtualAd->RtmpDev)
713			pAdapter = pVirtualAd->RtmpDev->priv;
714	}
715
716	if (pAdapter == NULL)
717	{
718		/* if 1st open fail, pAd will be free;
719		   So the net_dev->priv will be NULL in 2rd open */
720		return -ENETDOWN;
721	}
722
723	if (ADHOC_ON(pAdapter))
724		*mode = IW_MODE_ADHOC;
725    else if (INFRA_ON(pAdapter))
726		*mode = IW_MODE_INFRA;
727#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,4,20))
728    else if (MONITOR_ON(pAdapter))
729    {
730        *mode = IW_MODE_MONITOR;
731    }
732#endif
733    else
734        *mode = IW_MODE_AUTO;
735
736	DBGPRINT(RT_DEBUG_TRACE, ("==>rt_ioctl_giwmode(mode=%d)\n", *mode));
737	return 0;
738}
739
740int rt_ioctl_siwsens(struct net_device *dev,
741		   struct iw_request_info *info,
742		   char *name, char *extra)
743{
744	PRTMP_ADAPTER pAdapter = (PRTMP_ADAPTER) dev->priv;
745
746	//check if the interface is down
747    	if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
748    	{
749        	DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
750        	return -ENETDOWN;
751    	}
752
753	return 0;
754}
755
756int rt_ioctl_giwsens(struct net_device *dev,
757		   struct iw_request_info *info,
758		   char *name, char *extra)
759{
760	return 0;
761}
762
763int rt_ioctl_giwrange(struct net_device *dev,
764		   struct iw_request_info *info,
765		   struct iw_point *data, char *extra)
766{
767	PRTMP_ADAPTER 	pAdapter = NULL;
768	VIRTUAL_ADAPTER *pVirtualAd = NULL;
769	struct iw_range *range = (struct iw_range *) extra;
770	u16 val;
771	int i;
772
773	if (dev->priv_flags == INT_MAIN)
774	{
775		pAdapter = dev->priv;
776	}
777	else
778	{
779		pVirtualAd = dev->priv;
780		if (pVirtualAd && pVirtualAd->RtmpDev)
781			pAdapter = pVirtualAd->RtmpDev->priv;
782	}
783
784	if (pAdapter == NULL)
785	{
786		/* if 1st open fail, pAd will be free;
787		   So the net_dev->priv will be NULL in 2rd open */
788		return -ENETDOWN;
789	}
790
791	DBGPRINT(RT_DEBUG_TRACE ,("===>rt_ioctl_giwrange\n"));
792	data->length = sizeof(struct iw_range);
793	memset(range, 0, sizeof(struct iw_range));
794
795	range->txpower_capa = IW_TXPOW_DBM;
796
797	if (INFRA_ON(pAdapter)||ADHOC_ON(pAdapter))
798	{
799		range->min_pmp = 1 * 1024;
800		range->max_pmp = 65535 * 1024;
801		range->min_pmt = 1 * 1024;
802		range->max_pmt = 1000 * 1024;
803		range->pmp_flags = IW_POWER_PERIOD;
804		range->pmt_flags = IW_POWER_TIMEOUT;
805		range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT |
806			IW_POWER_UNICAST_R | IW_POWER_ALL_R;
807	}
808
809	range->we_version_compiled = WIRELESS_EXT;
810	range->we_version_source = 14;
811
812	range->retry_capa = IW_RETRY_LIMIT;
813	range->retry_flags = IW_RETRY_LIMIT;
814	range->min_retry = 0;
815	range->max_retry = 255;
816
817	range->num_channels =  pAdapter->ChannelListNum;
818
819	val = 0;
820	for (i = 1; i <= range->num_channels; i++)
821	{
822		u32 m;
823		range->freq[val].i = pAdapter->ChannelList[i-1].Channel;
824		MAP_CHANNEL_ID_TO_KHZ(pAdapter->ChannelList[i-1].Channel, m);
825		range->freq[val].m = m * 100; /* HZ */
826
827		range->freq[val].e = 1;
828		val++;
829		if (val == IW_MAX_FREQUENCIES)
830			break;
831	}
832	range->num_frequency = val;
833
834	range->max_qual.qual = 100; /* what is correct max? This was not
835					* documented exactly. At least
836					* 69 has been observed. */
837	range->max_qual.level = 0; /* dB */
838	range->max_qual.noise = 0; /* dB */
839
840	/* What would be suitable values for "average/typical" qual? */
841	range->avg_qual.qual = 20;
842	range->avg_qual.level = -60;
843	range->avg_qual.noise = -95;
844	range->sensitivity = 3;
845
846	range->max_encoding_tokens = NR_WEP_KEYS;
847	range->num_encoding_sizes = 2;
848	range->encoding_size[0] = 5;
849	range->encoding_size[1] = 13;
850
851	range->min_rts = 0;
852	range->max_rts = 2347;
853	range->min_frag = 256;
854	range->max_frag = 2346;
855
856#if WIRELESS_EXT > 17
857	/* IW_ENC_CAPA_* bit field */
858	range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
859					IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
860#endif
861
862	return 0;
863}
864
865int rt_ioctl_siwap(struct net_device *dev,
866		      struct iw_request_info *info,
867		      struct sockaddr *ap_addr, char *extra)
868{
869	PRTMP_ADAPTER pAdapter = (PRTMP_ADAPTER) dev->priv;
870    NDIS_802_11_MAC_ADDRESS Bssid;
871
872	//check if the interface is down
873	if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
874	{
875       	DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
876       	return -ENETDOWN;
877    }
878
879	if (pAdapter->Mlme.CntlMachine.CurrState != CNTL_IDLE)
880    {
881        RT28XX_MLME_RESET_STATE_MACHINE(pAdapter);
882        DBGPRINT(RT_DEBUG_TRACE, ("!!! MLME busy, reset MLME state machine !!!\n"));
883    }
884
885    // tell CNTL state machine to call NdisMSetInformationComplete() after completing
886    // this request, because this request is initiated by NDIS.
887    pAdapter->MlmeAux.CurrReqIsFromNdis = FALSE;
888	// Prevent to connect AP again in STAMlmePeriodicExec
889	pAdapter->MlmeAux.AutoReconnectSsidLen= 32;
890
891    memset(Bssid, 0, MAC_ADDR_LEN);
892    memcpy(Bssid, ap_addr->sa_data, MAC_ADDR_LEN);
893    MlmeEnqueue(pAdapter,
894                MLME_CNTL_STATE_MACHINE,
895                OID_802_11_BSSID,
896                sizeof(NDIS_802_11_MAC_ADDRESS),
897                (VOID *)&Bssid);
898
899    DBGPRINT(RT_DEBUG_TRACE, ("IOCTL::SIOCSIWAP %02x:%02x:%02x:%02x:%02x:%02x\n",
900        Bssid[0], Bssid[1], Bssid[2], Bssid[3], Bssid[4], Bssid[5]));
901
902	return 0;
903}
904
905int rt_ioctl_giwap(struct net_device *dev,
906		      struct iw_request_info *info,
907		      struct sockaddr *ap_addr, char *extra)
908{
909	PRTMP_ADAPTER 	pAdapter = NULL;
910	VIRTUAL_ADAPTER *pVirtualAd = NULL;
911
912	if (dev->priv_flags == INT_MAIN)
913	{
914		pAdapter = dev->priv;
915	}
916	else
917	{
918		pVirtualAd = dev->priv;
919		if (pVirtualAd && pVirtualAd->RtmpDev)
920			pAdapter = pVirtualAd->RtmpDev->priv;
921	}
922
923	if (pAdapter == NULL)
924	{
925		/* if 1st open fail, pAd will be free;
926		   So the net_dev->priv will be NULL in 2rd open */
927		return -ENETDOWN;
928	}
929
930	if (INFRA_ON(pAdapter) || ADHOC_ON(pAdapter))
931	{
932		ap_addr->sa_family = ARPHRD_ETHER;
933		memcpy(ap_addr->sa_data, &pAdapter->CommonCfg.Bssid, ETH_ALEN);
934	}
935#ifdef WPA_SUPPLICANT_SUPPORT
936    // Add for RT2870
937    else if (pAdapter->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE)
938    {
939        ap_addr->sa_family = ARPHRD_ETHER;
940        memcpy(ap_addr->sa_data, &pAdapter->MlmeAux.Bssid, ETH_ALEN);
941    }
942#endif // WPA_SUPPLICANT_SUPPORT //
943	else
944	{
945		DBGPRINT(RT_DEBUG_TRACE, ("IOCTL::SIOCGIWAP(=EMPTY)\n"));
946		return -ENOTCONN;
947	}
948
949	return 0;
950}
951
952/*
953 * Units are in db above the noise floor. That means the
954 * rssi values reported in the tx/rx descriptors in the
955 * driver are the SNR expressed in db.
956 *
957 * If you assume that the noise floor is -95, which is an
958 * excellent assumption 99.5 % of the time, then you can
959 * derive the absolute signal level (i.e. -95 + rssi).
960 * There are some other slight factors to take into account
961 * depending on whether the rssi measurement is from 11b,
962 * 11g, or 11a.   These differences are at most 2db and
963 * can be documented.
964 *
965 * NB: various calculations are based on the orinoco/wavelan
966 *     drivers for compatibility
967 */
968static void set_quality(PRTMP_ADAPTER pAdapter,
969                        struct iw_quality *iq,
970                        signed char rssi)
971{
972	__u8 ChannelQuality;
973
974	// Normalize Rssi
975	if (rssi >= -50)
976		ChannelQuality = 100;
977	else if (rssi >= -80) // between -50 ~ -80dbm
978		ChannelQuality = (__u8)(24 + ((rssi + 80) * 26)/10);
979	else if (rssi >= -90)   // between -80 ~ -90dbm
980        ChannelQuality = (__u8)((rssi + 90) * 26)/10;
981	else
982		ChannelQuality = 0;
983
984    iq->qual = (__u8)ChannelQuality;
985
986    iq->level = (__u8)(rssi);
987    iq->noise = (pAdapter->BbpWriteLatch[66] > pAdapter->BbpTuning.FalseCcaUpperThreshold) ? ((__u8)pAdapter->BbpTuning.FalseCcaUpperThreshold) : ((__u8) pAdapter->BbpWriteLatch[66]); 	// noise level (dBm)
988    iq->noise += 256 - 143;
989    iq->updated = pAdapter->iw_stats.qual.updated;
990}
991
992int rt_ioctl_iwaplist(struct net_device *dev,
993			struct iw_request_info *info,
994			struct iw_point *data, char *extra)
995{
996 	PRTMP_ADAPTER pAdapter = (PRTMP_ADAPTER) dev->priv;
997
998	struct sockaddr addr[IW_MAX_AP];
999	struct iw_quality qual[IW_MAX_AP];
1000	int i;
1001
1002   	//check if the interface is down
1003    if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
1004    {
1005       	DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
1006		data->length = 0;
1007		return 0;
1008        //return -ENETDOWN;
1009	}
1010
1011	for (i = 0; i <IW_MAX_AP ; i++)
1012	{
1013		if (i >=  pAdapter->ScanTab.BssNr)
1014			break;
1015		addr[i].sa_family = ARPHRD_ETHER;
1016			memcpy(addr[i].sa_data, &pAdapter->ScanTab.BssEntry[i].Bssid, MAC_ADDR_LEN);
1017		set_quality(pAdapter, &qual[i], pAdapter->ScanTab.BssEntry[i].Rssi);
1018	}
1019	data->length = i;
1020	memcpy(extra, &addr, i*sizeof(addr[0]));
1021	data->flags = 1;		/* signal quality present (sort of) */
1022	memcpy(extra + i*sizeof(addr[0]), &qual, i*sizeof(qual[i]));
1023
1024	return 0;
1025}
1026
1027#ifdef SIOCGIWSCAN
1028int rt_ioctl_siwscan(struct net_device *dev,
1029			struct iw_request_info *info,
1030			struct iw_point *data, char *extra)
1031{
1032	PRTMP_ADAPTER pAdapter = (PRTMP_ADAPTER) dev->priv;
1033
1034	ULONG								Now;
1035	int Status = NDIS_STATUS_SUCCESS;
1036
1037	//check if the interface is down
1038	if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
1039	{
1040		DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
1041		return -ENETDOWN;
1042	}
1043
1044	if (MONITOR_ON(pAdapter))
1045    {
1046        DBGPRINT(RT_DEBUG_TRACE, ("!!! Driver is in Monitor Mode now !!!\n"));
1047        return -EINVAL;
1048    }
1049
1050
1051#ifdef WPA_SUPPLICANT_SUPPORT
1052	if (pAdapter->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_ENABLE)
1053	{
1054		pAdapter->StaCfg.WpaSupplicantScanCount++;
1055	}
1056#endif // WPA_SUPPLICANT_SUPPORT //
1057
1058    pAdapter->StaCfg.bScanReqIsFromWebUI = TRUE;
1059	if (RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
1060		return 0;
1061	do{
1062		Now = jiffies;
1063
1064#ifdef WPA_SUPPLICANT_SUPPORT
1065		if ((pAdapter->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_ENABLE) &&
1066			(pAdapter->StaCfg.WpaSupplicantScanCount > 3))
1067		{
1068			DBGPRINT(RT_DEBUG_TRACE, ("!!! WpaSupplicantScanCount > 3\n"));
1069			Status = NDIS_STATUS_SUCCESS;
1070			break;
1071		}
1072#endif // WPA_SUPPLICANT_SUPPORT //
1073
1074		if ((OPSTATUS_TEST_FLAG(pAdapter, fOP_STATUS_MEDIA_STATE_CONNECTED)) &&
1075			((pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPA) ||
1076			(pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK)) &&
1077			(pAdapter->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED))
1078		{
1079			DBGPRINT(RT_DEBUG_TRACE, ("!!! Link UP, Port Not Secured! ignore this set::OID_802_11_BSSID_LIST_SCAN\n"));
1080			Status = NDIS_STATUS_SUCCESS;
1081			break;
1082		}
1083
1084		if (pAdapter->Mlme.CntlMachine.CurrState != CNTL_IDLE)
1085		{
1086			RT28XX_MLME_RESET_STATE_MACHINE(pAdapter);
1087			DBGPRINT(RT_DEBUG_TRACE, ("!!! MLME busy, reset MLME state machine !!!\n"));
1088		}
1089
1090		// tell CNTL state machine to call NdisMSetInformationComplete() after completing
1091		// this request, because this request is initiated by NDIS.
1092		pAdapter->MlmeAux.CurrReqIsFromNdis = FALSE;
1093		// Reset allowed scan retries
1094		pAdapter->StaCfg.ScanCnt = 0;
1095		pAdapter->StaCfg.LastScanTime = Now;
1096
1097		MlmeEnqueue(pAdapter,
1098			MLME_CNTL_STATE_MACHINE,
1099			OID_802_11_BSSID_LIST_SCAN,
1100			0,
1101			NULL);
1102
1103		Status = NDIS_STATUS_SUCCESS;
1104		RT28XX_MLME_HANDLER(pAdapter);
1105	}while(0);
1106	return 0;
1107}
1108
1109int rt_ioctl_giwscan(struct net_device *dev,
1110			struct iw_request_info *info,
1111			struct iw_point *data, char *extra)
1112{
1113
1114	PRTMP_ADAPTER pAdapter = (PRTMP_ADAPTER) dev->priv;
1115	int i=0;
1116	char *current_ev = extra, *previous_ev = extra;
1117	char *end_buf;
1118	char *current_val, custom[MAX_CUSTOM_LEN] = {0};
1119#ifndef IWEVGENIE
1120	char idx;
1121#endif // IWEVGENIE //
1122	struct iw_event iwe;
1123
1124	if (RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
1125    {
1126		/*
1127		 * Still scanning, indicate the caller should try again.
1128		 */
1129		return -EAGAIN;
1130	}
1131
1132
1133#ifdef WPA_SUPPLICANT_SUPPORT
1134	if (pAdapter->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_ENABLE)
1135	{
1136		pAdapter->StaCfg.WpaSupplicantScanCount = 0;
1137	}
1138#endif // WPA_SUPPLICANT_SUPPORT //
1139
1140	if (pAdapter->ScanTab.BssNr == 0)
1141	{
1142		data->length = 0;
1143		return 0;
1144	}
1145
1146#if WIRELESS_EXT >= 17
1147    if (data->length > 0)
1148        end_buf = extra + data->length;
1149    else
1150        end_buf = extra + IW_SCAN_MAX_DATA;
1151#else
1152    end_buf = extra + IW_SCAN_MAX_DATA;
1153#endif
1154
1155	for (i = 0; i < pAdapter->ScanTab.BssNr; i++)
1156	{
1157		if (current_ev >= end_buf)
1158        {
1159#if WIRELESS_EXT >= 17
1160            return -E2BIG;
1161#else
1162			break;
1163#endif
1164        }
1165
1166		//MAC address
1167		//================================
1168		memset(&iwe, 0, sizeof(iwe));
1169		iwe.cmd = SIOCGIWAP;
1170		iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
1171				memcpy(iwe.u.ap_addr.sa_data, &pAdapter->ScanTab.BssEntry[i].Bssid, ETH_ALEN);
1172
1173        previous_ev = current_ev;
1174		current_ev = IWE_STREAM_ADD_EVENT(info, current_ev,end_buf, &iwe, IW_EV_ADDR_LEN);
1175        if (current_ev == previous_ev)
1176#if WIRELESS_EXT >= 17
1177            return -E2BIG;
1178#else
1179			break;
1180#endif
1181
1182		//ESSID
1183		//================================
1184		memset(&iwe, 0, sizeof(iwe));
1185		iwe.cmd = SIOCGIWESSID;
1186		iwe.u.data.length = pAdapter->ScanTab.BssEntry[i].SsidLen;
1187		iwe.u.data.flags = 1;
1188
1189        previous_ev = current_ev;
1190		current_ev = IWE_STREAM_ADD_POINT(info, current_ev,end_buf, &iwe, pAdapter->ScanTab.BssEntry[i].Ssid);
1191        if (current_ev == previous_ev)
1192#if WIRELESS_EXT >= 17
1193            return -E2BIG;
1194#else
1195			break;
1196#endif
1197
1198		//Network Type
1199		//================================
1200		memset(&iwe, 0, sizeof(iwe));
1201		iwe.cmd = SIOCGIWMODE;
1202		if (pAdapter->ScanTab.BssEntry[i].BssType == Ndis802_11IBSS)
1203		{
1204			iwe.u.mode = IW_MODE_ADHOC;
1205		}
1206		else if (pAdapter->ScanTab.BssEntry[i].BssType == Ndis802_11Infrastructure)
1207		{
1208			iwe.u.mode = IW_MODE_INFRA;
1209		}
1210		else
1211		{
1212			iwe.u.mode = IW_MODE_AUTO;
1213		}
1214		iwe.len = IW_EV_UINT_LEN;
1215
1216        previous_ev = current_ev;
1217		current_ev = IWE_STREAM_ADD_EVENT(info, current_ev, end_buf, &iwe,  IW_EV_UINT_LEN);
1218        if (current_ev == previous_ev)
1219#if WIRELESS_EXT >= 17
1220            return -E2BIG;
1221#else
1222			break;
1223#endif
1224
1225		//Channel and Frequency
1226		//================================
1227		memset(&iwe, 0, sizeof(iwe));
1228		iwe.cmd = SIOCGIWFREQ;
1229		if (INFRA_ON(pAdapter) || ADHOC_ON(pAdapter))
1230			iwe.u.freq.m = pAdapter->ScanTab.BssEntry[i].Channel;
1231		else
1232			iwe.u.freq.m = pAdapter->ScanTab.BssEntry[i].Channel;
1233		iwe.u.freq.e = 0;
1234		iwe.u.freq.i = 0;
1235
1236		previous_ev = current_ev;
1237		current_ev = IWE_STREAM_ADD_EVENT(info, current_ev,end_buf, &iwe, IW_EV_FREQ_LEN);
1238        if (current_ev == previous_ev)
1239#if WIRELESS_EXT >= 17
1240            return -E2BIG;
1241#else
1242			break;
1243#endif
1244
1245        //Add quality statistics
1246        //================================
1247        memset(&iwe, 0, sizeof(iwe));
1248    	iwe.cmd = IWEVQUAL;
1249    	iwe.u.qual.level = 0;
1250    	iwe.u.qual.noise = 0;
1251        set_quality(pAdapter, &iwe.u.qual, pAdapter->ScanTab.BssEntry[i].Rssi);
1252    	current_ev = IWE_STREAM_ADD_EVENT(info, current_ev, end_buf, &iwe, IW_EV_QUAL_LEN);
1253        if (current_ev == previous_ev)
1254#if WIRELESS_EXT >= 17
1255            return -E2BIG;
1256#else
1257			break;
1258#endif
1259
1260		//Encyption key
1261		//================================
1262		memset(&iwe, 0, sizeof(iwe));
1263		iwe.cmd = SIOCGIWENCODE;
1264		if (CAP_IS_PRIVACY_ON (pAdapter->ScanTab.BssEntry[i].CapabilityInfo ))
1265			iwe.u.data.flags =IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
1266		else
1267			iwe.u.data.flags = IW_ENCODE_DISABLED;
1268
1269        previous_ev = current_ev;
1270        current_ev = IWE_STREAM_ADD_POINT(info, current_ev, end_buf,&iwe, (char *)pAdapter->SharedKey[BSS0][(iwe.u.data.flags & IW_ENCODE_INDEX)-1].Key);
1271        if (current_ev == previous_ev)
1272#if WIRELESS_EXT >= 17
1273            return -E2BIG;
1274#else
1275			break;
1276#endif
1277
1278		//Bit Rate
1279		//================================
1280		if (pAdapter->ScanTab.BssEntry[i].SupRateLen)
1281        {
1282            UCHAR tmpRate = pAdapter->ScanTab.BssEntry[i].SupRate[pAdapter->ScanTab.BssEntry[i].SupRateLen-1];
1283			memset(&iwe, 0, sizeof(iwe));
1284			iwe.cmd = SIOCGIWRATE;
1285    		current_val = current_ev + IW_EV_LCP_LEN;
1286            if (tmpRate == 0x82)
1287                iwe.u.bitrate.value =  1 * 1000000;
1288            else if (tmpRate == 0x84)
1289                iwe.u.bitrate.value =  2 * 1000000;
1290            else if (tmpRate == 0x8B)
1291                iwe.u.bitrate.value =  5.5 * 1000000;
1292            else if (tmpRate == 0x96)
1293                iwe.u.bitrate.value =  11 * 1000000;
1294            else
1295    		    iwe.u.bitrate.value =  (tmpRate/2) * 1000000;
1296
1297			iwe.u.bitrate.disabled = 0;
1298			current_val = IWE_STREAM_ADD_VALUE(info, current_ev,
1299				current_val, end_buf, &iwe,
1300    			IW_EV_PARAM_LEN);
1301
1302        	if((current_val-current_ev)>IW_EV_LCP_LEN)
1303            	current_ev = current_val;
1304        	else
1305#if WIRELESS_EXT >= 17
1306                return -E2BIG;
1307#else
1308			    break;
1309#endif
1310        }
1311
1312#ifdef IWEVGENIE
1313		//WPA IE
1314		if (pAdapter->ScanTab.BssEntry[i].WpaIE.IELen > 0)
1315		{
1316			memset(&iwe, 0, sizeof(iwe));
1317			memset(&custom[0], 0, MAX_CUSTOM_LEN);
1318			memcpy(custom, &(pAdapter->ScanTab.BssEntry[i].WpaIE.IE[0]),
1319						   pAdapter->ScanTab.BssEntry[i].WpaIE.IELen);
1320			iwe.cmd = IWEVGENIE;
1321			iwe.u.data.length = pAdapter->ScanTab.BssEntry[i].WpaIE.IELen;
1322			current_ev = IWE_STREAM_ADD_POINT(info, current_ev, end_buf, &iwe, custom);
1323			if (current_ev == previous_ev)
1324#if WIRELESS_EXT >= 17
1325                return -E2BIG;
1326#else
1327			    break;
1328#endif
1329		}
1330
1331		//WPA2 IE
1332        if (pAdapter->ScanTab.BssEntry[i].RsnIE.IELen > 0)
1333        {
1334        	memset(&iwe, 0, sizeof(iwe));
1335			memset(&custom[0], 0, MAX_CUSTOM_LEN);
1336			memcpy(custom, &(pAdapter->ScanTab.BssEntry[i].RsnIE.IE[0]),
1337						   pAdapter->ScanTab.BssEntry[i].RsnIE.IELen);
1338			iwe.cmd = IWEVGENIE;
1339			iwe.u.data.length = pAdapter->ScanTab.BssEntry[i].RsnIE.IELen;
1340			current_ev = IWE_STREAM_ADD_POINT(info, current_ev, end_buf, &iwe, custom);
1341			if (current_ev == previous_ev)
1342#if WIRELESS_EXT >= 17
1343                return -E2BIG;
1344#else
1345			    break;
1346#endif
1347        }
1348#else
1349        //WPA IE
1350		//================================
1351        if (pAdapter->ScanTab.BssEntry[i].WpaIE.IELen > 0)
1352        {
1353    		NdisZeroMemory(&iwe, sizeof(iwe));
1354			memset(&custom[0], 0, MAX_CUSTOM_LEN);
1355    		iwe.cmd = IWEVCUSTOM;
1356            iwe.u.data.length = (pAdapter->ScanTab.BssEntry[i].WpaIE.IELen * 2) + 7;
1357            NdisMoveMemory(custom, "wpa_ie=", 7);
1358            for (idx = 0; idx < pAdapter->ScanTab.BssEntry[i].WpaIE.IELen; idx++)
1359                sprintf(custom, "%s%02x", custom, pAdapter->ScanTab.BssEntry[i].WpaIE.IE[idx]);
1360            previous_ev = current_ev;
1361    		current_ev = IWE_STREAM_ADD_POINT(info, current_ev, end_buf, &iwe,  custom);
1362            if (current_ev == previous_ev)
1363#if WIRELESS_EXT >= 17
1364                return -E2BIG;
1365#else
1366			    break;
1367#endif
1368        }
1369
1370        //WPA2 IE
1371        if (pAdapter->ScanTab.BssEntry[i].RsnIE.IELen > 0)
1372        {
1373    		NdisZeroMemory(&iwe, sizeof(iwe));
1374			memset(&custom[0], 0, MAX_CUSTOM_LEN);
1375    		iwe.cmd = IWEVCUSTOM;
1376            iwe.u.data.length = (pAdapter->ScanTab.BssEntry[i].RsnIE.IELen * 2) + 7;
1377            NdisMoveMemory(custom, "rsn_ie=", 7);
1378			for (idx = 0; idx < pAdapter->ScanTab.BssEntry[i].RsnIE.IELen; idx++)
1379                sprintf(custom, "%s%02x", custom, pAdapter->ScanTab.BssEntry[i].RsnIE.IE[idx]);
1380            previous_ev = current_ev;
1381    		current_ev = IWE_STREAM_ADD_POINT(info, current_ev, end_buf, &iwe,  custom);
1382            if (current_ev == previous_ev)
1383#if WIRELESS_EXT >= 17
1384                return -E2BIG;
1385#else
1386			    break;
1387#endif
1388        }
1389#endif // IWEVGENIE //
1390	}
1391
1392	data->length = current_ev - extra;
1393    pAdapter->StaCfg.bScanReqIsFromWebUI = FALSE;
1394	DBGPRINT(RT_DEBUG_ERROR ,("===>rt_ioctl_giwscan. %d(%d) BSS returned, data->length = %d\n",i , pAdapter->ScanTab.BssNr, data->length));
1395	return 0;
1396}
1397#endif
1398
1399int rt_ioctl_siwessid(struct net_device *dev,
1400			 struct iw_request_info *info,
1401			 struct iw_point *data, char *essid)
1402{
1403	PRTMP_ADAPTER pAdapter = (PRTMP_ADAPTER) dev->priv;
1404
1405	//check if the interface is down
1406    if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
1407    {
1408       	DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
1409       	return -ENETDOWN;
1410    }
1411
1412	if (data->flags)
1413	{
1414		PCHAR	pSsidString = NULL;
1415
1416		// Includes null character.
1417		if (data->length > (IW_ESSID_MAX_SIZE + 1))
1418			return -E2BIG;
1419
1420		pSsidString = (CHAR *) kmalloc(MAX_LEN_OF_SSID+1, MEM_ALLOC_FLAG);
1421		if (pSsidString)
1422		{
1423			NdisZeroMemory(pSsidString, MAX_LEN_OF_SSID+1);
1424			NdisMoveMemory(pSsidString, essid, data->length);
1425			if (Set_SSID_Proc(pAdapter, pSsidString) == FALSE)
1426				return -EINVAL;
1427		}
1428		else
1429			return -ENOMEM;
1430	}
1431	else
1432	{
1433		// ANY ssid
1434		if (Set_SSID_Proc(pAdapter, "") == FALSE)
1435			return -EINVAL;
1436    }
1437	return 0;
1438}
1439
1440int rt_ioctl_giwessid(struct net_device *dev,
1441			 struct iw_request_info *info,
1442			 struct iw_point *data, char *essid)
1443{
1444	PRTMP_ADAPTER 	pAdapter = NULL;
1445	VIRTUAL_ADAPTER *pVirtualAd = NULL;
1446
1447	if (dev->priv_flags == INT_MAIN)
1448	{
1449		pAdapter = dev->priv;
1450	}
1451	else
1452	{
1453		pVirtualAd = dev->priv;
1454		if (pVirtualAd && pVirtualAd->RtmpDev)
1455			pAdapter = pVirtualAd->RtmpDev->priv;
1456	}
1457
1458	if (pAdapter == NULL)
1459	{
1460		/* if 1st open fail, pAd will be free;
1461		   So the net_dev->priv will be NULL in 2rd open */
1462		return -ENETDOWN;
1463	}
1464
1465	data->flags = 1;
1466    if (MONITOR_ON(pAdapter))
1467    {
1468        data->length  = 0;
1469        return 0;
1470    }
1471
1472	if (OPSTATUS_TEST_FLAG(pAdapter, fOP_STATUS_MEDIA_STATE_CONNECTED))
1473	{
1474		DBGPRINT(RT_DEBUG_TRACE ,("MediaState is connected\n"));
1475		data->length = pAdapter->CommonCfg.SsidLen;
1476		memcpy(essid, pAdapter->CommonCfg.Ssid, pAdapter->CommonCfg.SsidLen);
1477	}
1478#ifdef RT2870
1479#ifdef WPA_SUPPLICANT_SUPPORT
1480    // Add for RT2870
1481    else if (pAdapter->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE)
1482    {
1483        data->length = pAdapter->CommonCfg.SsidLen;
1484		memcpy(essid, pAdapter->CommonCfg.Ssid, pAdapter->CommonCfg.SsidLen);
1485	}
1486#endif // WPA_SUPPLICANT_SUPPORT //
1487#endif // RT2870 //
1488	else
1489	{//the ANY ssid was specified
1490		data->length  = 0;
1491		DBGPRINT(RT_DEBUG_TRACE ,("MediaState is not connected, ess\n"));
1492	}
1493
1494	return 0;
1495
1496}
1497
1498int rt_ioctl_siwnickn(struct net_device *dev,
1499			 struct iw_request_info *info,
1500			 struct iw_point *data, char *nickname)
1501{
1502	PRTMP_ADAPTER pAdapter = (PRTMP_ADAPTER) dev->priv;
1503
1504    //check if the interface is down
1505    if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
1506    {
1507        DBGPRINT(RT_DEBUG_TRACE ,("INFO::Network is down!\n"));
1508        return -ENETDOWN;
1509    }
1510
1511	if (data->length > IW_ESSID_MAX_SIZE)
1512		return -EINVAL;
1513
1514	memset(pAdapter->nickname, 0, IW_ESSID_MAX_SIZE + 1);
1515	memcpy(pAdapter->nickname, nickname, data->length);
1516
1517
1518	return 0;
1519}
1520
1521int rt_ioctl_giwnickn(struct net_device *dev,
1522			 struct iw_request_info *info,
1523			 struct iw_point *data, char *nickname)
1524{
1525	PRTMP_ADAPTER 	pAdapter = NULL;
1526	VIRTUAL_ADAPTER *pVirtualAd = NULL;
1527
1528	if (dev->priv_flags == INT_MAIN)
1529	{
1530		pAdapter = dev->priv;
1531	}
1532	else
1533	{
1534		pVirtualAd = dev->priv;
1535		if (pVirtualAd && pVirtualAd->RtmpDev)
1536			pAdapter = pVirtualAd->RtmpDev->priv;
1537	}
1538
1539	if (pAdapter == NULL)
1540	{
1541		/* if 1st open fail, pAd will be free;
1542		   So the net_dev->priv will be NULL in 2rd open */
1543		return -ENETDOWN;
1544	}
1545
1546	if (data->length > strlen(pAdapter->nickname) + 1)
1547		data->length = strlen(pAdapter->nickname) + 1;
1548	if (data->length > 0) {
1549		memcpy(nickname, pAdapter->nickname, data->length-1);
1550		nickname[data->length-1] = '\0';
1551	}
1552	return 0;
1553}
1554
1555int rt_ioctl_siwrts(struct net_device *dev,
1556		       struct iw_request_info *info,
1557		       struct iw_param *rts, char *extra)
1558{
1559	PRTMP_ADAPTER pAdapter = (PRTMP_ADAPTER) dev->priv;
1560	u16 val;
1561
1562    //check if the interface is down
1563    if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
1564    {
1565        DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
1566        return -ENETDOWN;
1567    }
1568
1569	if (rts->disabled)
1570		val = MAX_RTS_THRESHOLD;
1571	else if (rts->value < 0 || rts->value > MAX_RTS_THRESHOLD)
1572		return -EINVAL;
1573	else if (rts->value == 0)
1574	    val = MAX_RTS_THRESHOLD;
1575	else
1576		val = rts->value;
1577
1578	if (val != pAdapter->CommonCfg.RtsThreshold)
1579		pAdapter->CommonCfg.RtsThreshold = val;
1580
1581	return 0;
1582}
1583
1584int rt_ioctl_giwrts(struct net_device *dev,
1585		       struct iw_request_info *info,
1586		       struct iw_param *rts, char *extra)
1587{
1588	PRTMP_ADAPTER 	pAdapter = NULL;
1589	VIRTUAL_ADAPTER *pVirtualAd = NULL;
1590
1591	if (dev->priv_flags == INT_MAIN)
1592	{
1593		pAdapter = dev->priv;
1594	}
1595	else
1596	{
1597		pVirtualAd = dev->priv;
1598		if (pVirtualAd && pVirtualAd->RtmpDev)
1599			pAdapter = pVirtualAd->RtmpDev->priv;
1600	}
1601
1602	if (pAdapter == NULL)
1603	{
1604		/* if 1st open fail, pAd will be free;
1605		   So the net_dev->priv will be NULL in 2rd open */
1606		return -ENETDOWN;
1607	}
1608
1609	//check if the interface is down
1610	if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
1611	{
1612  		DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
1613    	return -ENETDOWN;
1614	}
1615
1616	rts->value = pAdapter->CommonCfg.RtsThreshold;
1617	rts->disabled = (rts->value == MAX_RTS_THRESHOLD);
1618	rts->fixed = 1;
1619
1620	return 0;
1621}
1622
1623int rt_ioctl_siwfrag(struct net_device *dev,
1624			struct iw_request_info *info,
1625			struct iw_param *frag, char *extra)
1626{
1627	PRTMP_ADAPTER pAdapter = (PRTMP_ADAPTER) dev->priv;
1628	u16 val;
1629
1630	//check if the interface is down
1631    	if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
1632    	{
1633      		DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
1634        	return -ENETDOWN;
1635    	}
1636
1637	if (frag->disabled)
1638		val = MAX_FRAG_THRESHOLD;
1639	else if (frag->value >= MIN_FRAG_THRESHOLD || frag->value <= MAX_FRAG_THRESHOLD)
1640        val = __cpu_to_le16(frag->value & ~0x1); /* even numbers only */
1641	else if (frag->value == 0)
1642	    val = MAX_FRAG_THRESHOLD;
1643	else
1644		return -EINVAL;
1645
1646	pAdapter->CommonCfg.FragmentThreshold = val;
1647	return 0;
1648}
1649
1650int rt_ioctl_giwfrag(struct net_device *dev,
1651			struct iw_request_info *info,
1652			struct iw_param *frag, char *extra)
1653{
1654	PRTMP_ADAPTER 	pAdapter = NULL;
1655	VIRTUAL_ADAPTER *pVirtualAd = NULL;
1656
1657	if (dev->priv_flags == INT_MAIN)
1658	{
1659		pAdapter = dev->priv;
1660	}
1661	else
1662	{
1663		pVirtualAd = dev->priv;
1664		if (pVirtualAd && pVirtualAd->RtmpDev)
1665			pAdapter = pVirtualAd->RtmpDev->priv;
1666	}
1667
1668	if (pAdapter == NULL)
1669	{
1670		/* if 1st open fail, pAd will be free;
1671		   So the net_dev->priv will be NULL in 2rd open */
1672		return -ENETDOWN;
1673	}
1674
1675	//check if the interface is down
1676	if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
1677	{
1678  		DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
1679    	return -ENETDOWN;
1680	}
1681
1682	frag->value = pAdapter->CommonCfg.FragmentThreshold;
1683	frag->disabled = (frag->value == MAX_FRAG_THRESHOLD);
1684	frag->fixed = 1;
1685
1686	return 0;
1687}
1688
1689#define MAX_WEP_KEY_SIZE 13
1690#define MIN_WEP_KEY_SIZE 5
1691int rt_ioctl_siwencode(struct net_device *dev,
1692			  struct iw_request_info *info,
1693			  struct iw_point *erq, char *extra)
1694{
1695	PRTMP_ADAPTER pAdapter = (PRTMP_ADAPTER) dev->priv;
1696
1697	//check if the interface is down
1698    	if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
1699    	{
1700      		DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
1701        	return -ENETDOWN;
1702    	}
1703
1704	if ((erq->length == 0) &&
1705        (erq->flags & IW_ENCODE_DISABLED))
1706	{
1707		pAdapter->StaCfg.PairCipher = Ndis802_11WEPDisabled;
1708		pAdapter->StaCfg.GroupCipher = Ndis802_11WEPDisabled;
1709		pAdapter->StaCfg.WepStatus = Ndis802_11WEPDisabled;
1710        pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
1711        pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
1712        goto done;
1713	}
1714	else if ((erq->length == 0) &&
1715             (erq->flags & IW_ENCODE_RESTRICTED || erq->flags & IW_ENCODE_OPEN))
1716	{
1717	    //pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
1718		STA_PORT_SECURED(pAdapter);
1719		pAdapter->StaCfg.PairCipher = Ndis802_11WEPEnabled;
1720		pAdapter->StaCfg.GroupCipher = Ndis802_11WEPEnabled;
1721		pAdapter->StaCfg.WepStatus = Ndis802_11WEPEnabled;
1722        pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
1723		if (erq->flags & IW_ENCODE_RESTRICTED)
1724			pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeShared;
1725    	else
1726			pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
1727        goto done;
1728	}
1729
1730    if (erq->length > 0)
1731	{
1732		int keyIdx = (erq->flags & IW_ENCODE_INDEX) - 1;
1733		/* Check the size of the key */
1734		if (erq->length > MAX_WEP_KEY_SIZE) {
1735			return -EINVAL;
1736		}
1737		/* Check key index */
1738		if ((keyIdx < 0) || (keyIdx >= NR_WEP_KEYS))
1739        {
1740            DBGPRINT(RT_DEBUG_TRACE ,("==>rt_ioctl_siwencode::Wrong keyIdx=%d! Using default key instead (%d)\n",
1741                                        keyIdx, pAdapter->StaCfg.DefaultKeyId));
1742
1743            //Using default key
1744			keyIdx = pAdapter->StaCfg.DefaultKeyId;
1745        }
1746
1747        NdisZeroMemory(pAdapter->SharedKey[BSS0][keyIdx].Key,  16);
1748
1749		if (erq->length == MAX_WEP_KEY_SIZE)
1750        {
1751			pAdapter->SharedKey[BSS0][keyIdx].KeyLen = MAX_WEP_KEY_SIZE;
1752            pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = CIPHER_WEP128;
1753		}
1754		else if (erq->length == MIN_WEP_KEY_SIZE)
1755        {
1756            pAdapter->SharedKey[BSS0][keyIdx].KeyLen = MIN_WEP_KEY_SIZE;
1757            pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = CIPHER_WEP64;
1758		}
1759		else
1760			/* Disable the key */
1761			pAdapter->SharedKey[BSS0][keyIdx].KeyLen = 0;
1762
1763		/* Check if the key is not marked as invalid */
1764		if(!(erq->flags & IW_ENCODE_NOKEY)) {
1765			/* Copy the key in the driver */
1766			NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].Key, extra, erq->length);
1767        }
1768	}
1769    else
1770			{
1771		/* Do we want to just set the transmit key index ? */
1772		int index = (erq->flags & IW_ENCODE_INDEX) - 1;
1773		if ((index >= 0) && (index < 4))
1774        {
1775			pAdapter->StaCfg.DefaultKeyId = index;
1776            }
1777        else
1778			/* Don't complain if only change the mode */
1779			if(!erq->flags & IW_ENCODE_MODE) {
1780				return -EINVAL;
1781		}
1782	}
1783
1784done:
1785    DBGPRINT(RT_DEBUG_TRACE ,("==>rt_ioctl_siwencode::erq->flags=%x\n",erq->flags));
1786	DBGPRINT(RT_DEBUG_TRACE ,("==>rt_ioctl_siwencode::AuthMode=%x\n",pAdapter->StaCfg.AuthMode));
1787	DBGPRINT(RT_DEBUG_TRACE ,("==>rt_ioctl_siwencode::DefaultKeyId=%x, KeyLen = %d\n",pAdapter->StaCfg.DefaultKeyId , pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].KeyLen));
1788	DBGPRINT(RT_DEBUG_TRACE ,("==>rt_ioctl_siwencode::WepStatus=%x\n",pAdapter->StaCfg.WepStatus));
1789	return 0;
1790}
1791
1792int
1793rt_ioctl_giwencode(struct net_device *dev,
1794			  struct iw_request_info *info,
1795			  struct iw_point *erq, char *key)
1796{
1797	int kid;
1798	PRTMP_ADAPTER 	pAdapter = NULL;
1799	VIRTUAL_ADAPTER *pVirtualAd = NULL;
1800
1801	if (dev->priv_flags == INT_MAIN)
1802	{
1803		pAdapter = dev->priv;
1804	}
1805	else
1806	{
1807		pVirtualAd = dev->priv;
1808		if (pVirtualAd && pVirtualAd->RtmpDev)
1809			pAdapter = pVirtualAd->RtmpDev->priv;
1810	}
1811
1812	if (pAdapter == NULL)
1813	{
1814		/* if 1st open fail, pAd will be free;
1815		   So the net_dev->priv will be NULL in 2rd open */
1816		return -ENETDOWN;
1817	}
1818
1819	//check if the interface is down
1820	if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
1821	{
1822  		DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
1823    	return -ENETDOWN;
1824	}
1825
1826	kid = erq->flags & IW_ENCODE_INDEX;
1827	DBGPRINT(RT_DEBUG_TRACE, ("===>rt_ioctl_giwencode %d\n", erq->flags & IW_ENCODE_INDEX));
1828
1829	if (pAdapter->StaCfg.WepStatus == Ndis802_11WEPDisabled)
1830	{
1831		erq->length = 0;
1832		erq->flags = IW_ENCODE_DISABLED;
1833	}
1834	else if ((kid > 0) && (kid <=4))
1835	{
1836		// copy wep key
1837		erq->flags = kid ;			/* NB: base 1 */
1838		if (erq->length > pAdapter->SharedKey[BSS0][kid-1].KeyLen)
1839			erq->length = pAdapter->SharedKey[BSS0][kid-1].KeyLen;
1840		memcpy(key, pAdapter->SharedKey[BSS0][kid-1].Key, erq->length);
1841		//if ((kid == pAdapter->PortCfg.DefaultKeyId))
1842		//erq->flags |= IW_ENCODE_ENABLED;	/* XXX */
1843		if (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeShared)
1844			erq->flags |= IW_ENCODE_RESTRICTED;		/* XXX */
1845		else
1846			erq->flags |= IW_ENCODE_OPEN;		/* XXX */
1847
1848	}
1849	else if (kid == 0)
1850	{
1851		if (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeShared)
1852			erq->flags |= IW_ENCODE_RESTRICTED;		/* XXX */
1853		else
1854			erq->flags |= IW_ENCODE_OPEN;		/* XXX */
1855		erq->length = pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].KeyLen;
1856		memcpy(key, pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].Key, erq->length);
1857		// copy default key ID
1858		if (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeShared)
1859			erq->flags |= IW_ENCODE_RESTRICTED;		/* XXX */
1860		else
1861			erq->flags |= IW_ENCODE_OPEN;		/* XXX */
1862		erq->flags = pAdapter->StaCfg.DefaultKeyId + 1;			/* NB: base 1 */
1863		erq->flags |= IW_ENCODE_ENABLED;	/* XXX */
1864	}
1865
1866	return 0;
1867
1868}
1869
1870static int
1871rt_ioctl_setparam(struct net_device *dev, struct iw_request_info *info,
1872			 void *w, char *extra)
1873{
1874    VIRTUAL_ADAPTER	*pVirtualAd = NULL;
1875	PRTMP_ADAPTER pAdapter;
1876	POS_COOKIE pObj;
1877	char *this_char = extra;
1878	char *value;
1879	int  Status=0;
1880
1881	if (dev->priv_flags == INT_MAIN)
1882	{
1883		pAdapter = dev->priv;
1884	}
1885	else
1886	{
1887		pVirtualAd = dev->priv;
1888		pAdapter = pVirtualAd->RtmpDev->priv;
1889	}
1890	pObj = (POS_COOKIE) pAdapter->OS_Cookie;
1891
1892	if (pAdapter == NULL)
1893	{
1894		/* if 1st open fail, pAd will be free;
1895		   So the net_dev->priv will be NULL in 2rd open */
1896		return -ENETDOWN;
1897	}
1898
1899	{
1900		pObj->ioctl_if_type = INT_MAIN;
1901        pObj->ioctl_if = MAIN_MBSSID;
1902	}
1903
1904	//check if the interface is down
1905    	if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
1906    	{
1907      		DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
1908			return -ENETDOWN;
1909    	}
1910
1911	if (!*this_char)
1912		return -EINVAL;
1913
1914	if ((value = rtstrchr(this_char, '=')) != NULL)
1915	    *value++ = 0;
1916
1917	if (!value)
1918	    return -EINVAL;
1919
1920	// reject setting nothing besides ANY ssid(ssidLen=0)
1921    if (!*value && (strcmp(this_char, "SSID") != 0))
1922        return -EINVAL;
1923
1924	for (PRTMP_PRIVATE_SET_PROC = RTMP_PRIVATE_SUPPORT_PROC; PRTMP_PRIVATE_SET_PROC->name; PRTMP_PRIVATE_SET_PROC++)
1925	{
1926	    if (strcmp(this_char, PRTMP_PRIVATE_SET_PROC->name) == 0)
1927	    {
1928	        if(!PRTMP_PRIVATE_SET_PROC->set_proc(pAdapter, value))
1929	        {	//FALSE:Set private failed then return Invalid argument
1930			    Status = -EINVAL;
1931	        }
1932		    break;	//Exit for loop.
1933	    }
1934	}
1935
1936	if(PRTMP_PRIVATE_SET_PROC->name == NULL)
1937	{  //Not found argument
1938	    Status = -EINVAL;
1939	    DBGPRINT(RT_DEBUG_TRACE, ("===>rt_ioctl_setparam:: (iwpriv) Not Support Set Command [%s=%s]\n", this_char, value));
1940	}
1941
1942    return Status;
1943}
1944
1945
1946static int
1947rt_private_get_statistics(struct net_device *dev, struct iw_request_info *info,
1948		struct iw_point *wrq, char *extra)
1949{
1950	INT				Status = 0;
1951    PRTMP_ADAPTER   pAd = (PRTMP_ADAPTER) dev->priv;
1952
1953    if (extra == NULL)
1954    {
1955        wrq->length = 0;
1956        return -EIO;
1957    }
1958
1959    memset(extra, 0x00, IW_PRIV_SIZE_MASK);
1960    sprintf(extra, "\n\n");
1961
1962#ifdef RALINK_ATE
1963	if (ATE_ON(pAd))
1964	{
1965	    sprintf(extra+strlen(extra), "Tx success                      = %ld\n", (ULONG)pAd->ate.TxDoneCount);
1966	    //sprintf(extra+strlen(extra), "Tx success without retry        = %ld\n", (ULONG)pAd->ate.TxDoneCount);
1967	}
1968	else
1969#endif // RALINK_ATE //
1970	{
1971    sprintf(extra+strlen(extra), "Tx success                      = %ld\n", (ULONG)pAd->WlanCounters.TransmittedFragmentCount.QuadPart);
1972    sprintf(extra+strlen(extra), "Tx success without retry        = %ld\n", (ULONG)pAd->WlanCounters.TransmittedFragmentCount.QuadPart - (ULONG)pAd->WlanCounters.RetryCount.QuadPart);
1973	}
1974    sprintf(extra+strlen(extra), "Tx success after retry          = %ld\n", (ULONG)pAd->WlanCounters.RetryCount.QuadPart);
1975    sprintf(extra+strlen(extra), "Tx fail to Rcv ACK after retry  = %ld\n", (ULONG)pAd->WlanCounters.FailedCount.QuadPart);
1976    sprintf(extra+strlen(extra), "RTS Success Rcv CTS             = %ld\n", (ULONG)pAd->WlanCounters.RTSSuccessCount.QuadPart);
1977    sprintf(extra+strlen(extra), "RTS Fail Rcv CTS                = %ld\n", (ULONG)pAd->WlanCounters.RTSFailureCount.QuadPart);
1978
1979    sprintf(extra+strlen(extra), "Rx success                      = %ld\n", (ULONG)pAd->WlanCounters.ReceivedFragmentCount.QuadPart);
1980    sprintf(extra+strlen(extra), "Rx with CRC                     = %ld\n", (ULONG)pAd->WlanCounters.FCSErrorCount.QuadPart);
1981    sprintf(extra+strlen(extra), "Rx drop due to out of resource  = %ld\n", (ULONG)pAd->Counters8023.RxNoBuffer);
1982    sprintf(extra+strlen(extra), "Rx duplicate frame              = %ld\n", (ULONG)pAd->WlanCounters.FrameDuplicateCount.QuadPart);
1983
1984    sprintf(extra+strlen(extra), "False CCA (one second)          = %ld\n", (ULONG)pAd->RalinkCounters.OneSecFalseCCACnt);
1985#ifdef RALINK_ATE
1986	if (ATE_ON(pAd))
1987	{
1988		if (pAd->ate.RxAntennaSel == 0)
1989		{
1990    		sprintf(extra+strlen(extra), "RSSI-A                          = %ld\n", (LONG)(pAd->ate.LastRssi0 - pAd->BbpRssiToDbmDelta));
1991			sprintf(extra+strlen(extra), "RSSI-B (if available)           = %ld\n", (LONG)(pAd->ate.LastRssi1 - pAd->BbpRssiToDbmDelta));
1992			sprintf(extra+strlen(extra), "RSSI-C (if available)           = %ld\n\n", (LONG)(pAd->ate.LastRssi2 - pAd->BbpRssiToDbmDelta));
1993		}
1994		else
1995		{
1996    		sprintf(extra+strlen(extra), "RSSI                            = %ld\n", (LONG)(pAd->ate.LastRssi0 - pAd->BbpRssiToDbmDelta));
1997		}
1998	}
1999	else
2000#endif // RALINK_ATE //
2001	{
2002    	sprintf(extra+strlen(extra), "RSSI-A                          = %ld\n", (LONG)(pAd->StaCfg.RssiSample.LastRssi0 - pAd->BbpRssiToDbmDelta));
2003        sprintf(extra+strlen(extra), "RSSI-B (if available)           = %ld\n", (LONG)(pAd->StaCfg.RssiSample.LastRssi1 - pAd->BbpRssiToDbmDelta));
2004        sprintf(extra+strlen(extra), "RSSI-C (if available)           = %ld\n\n", (LONG)(pAd->StaCfg.RssiSample.LastRssi2 - pAd->BbpRssiToDbmDelta));
2005	}
2006#ifdef WPA_SUPPLICANT_SUPPORT
2007    sprintf(extra+strlen(extra), "WpaSupplicantUP                 = %d\n\n", pAd->StaCfg.WpaSupplicantUP);
2008#endif // WPA_SUPPLICANT_SUPPORT //
2009
2010
2011    wrq->length = strlen(extra) + 1; // 1: size of '\0'
2012    DBGPRINT(RT_DEBUG_TRACE, ("<== rt_private_get_statistics, wrq->length = %d\n", wrq->length));
2013
2014    return Status;
2015}
2016
2017#ifdef DOT11_N_SUPPORT
2018void	getBaInfo(
2019	IN	PRTMP_ADAPTER	pAd,
2020	IN	PUCHAR			pOutBuf)
2021{
2022	INT i, j;
2023	BA_ORI_ENTRY *pOriBAEntry;
2024	BA_REC_ENTRY *pRecBAEntry;
2025
2026	for (i=0; i<MAX_LEN_OF_MAC_TABLE; i++)
2027	{
2028		PMAC_TABLE_ENTRY pEntry = &pAd->MacTab.Content[i];
2029		if (((pEntry->ValidAsCLI || pEntry->ValidAsApCli) && (pEntry->Sst == SST_ASSOC))
2030			|| (pEntry->ValidAsWDS) || (pEntry->ValidAsMesh))
2031		{
2032			sprintf(pOutBuf, "%s\n%02X:%02X:%02X:%02X:%02X:%02X (Aid = %d) (AP) -\n",
2033                pOutBuf,
2034				pEntry->Addr[0], pEntry->Addr[1], pEntry->Addr[2],
2035				pEntry->Addr[3], pEntry->Addr[4], pEntry->Addr[5], pEntry->Aid);
2036
2037			sprintf(pOutBuf, "%s[Recipient]\n", pOutBuf);
2038			for (j=0; j < NUM_OF_TID; j++)
2039			{
2040				if (pEntry->BARecWcidArray[j] != 0)
2041				{
2042					pRecBAEntry =&pAd->BATable.BARecEntry[pEntry->BARecWcidArray[j]];
2043					sprintf(pOutBuf, "%sTID=%d, BAWinSize=%d, LastIndSeq=%d, ReorderingPkts=%d\n", pOutBuf, j, pRecBAEntry->BAWinSize, pRecBAEntry->LastIndSeq, pRecBAEntry->list.qlen);
2044				}
2045			}
2046			sprintf(pOutBuf, "%s\n", pOutBuf);
2047
2048			sprintf(pOutBuf, "%s[Originator]\n", pOutBuf);
2049			for (j=0; j < NUM_OF_TID; j++)
2050			{
2051				if (pEntry->BAOriWcidArray[j] != 0)
2052				{
2053					pOriBAEntry =&pAd->BATable.BAOriEntry[pEntry->BAOriWcidArray[j]];
2054					sprintf(pOutBuf, "%sTID=%d, BAWinSize=%d, StartSeq=%d, CurTxSeq=%d\n", pOutBuf, j, pOriBAEntry->BAWinSize, pOriBAEntry->Sequence, pEntry->TxSeq[j]);
2055				}
2056			}
2057			sprintf(pOutBuf, "%s\n\n", pOutBuf);
2058		}
2059        if (strlen(pOutBuf) > (IW_PRIV_SIZE_MASK - 30))
2060                break;
2061	}
2062
2063	return;
2064}
2065#endif // DOT11_N_SUPPORT //
2066
2067static int
2068rt_private_show(struct net_device *dev, struct iw_request_info *info,
2069		struct iw_point *wrq, char *extra)
2070{
2071    INT				Status = 0;
2072    VIRTUAL_ADAPTER	*pVirtualAd = NULL;
2073    PRTMP_ADAPTER   pAd;
2074	POS_COOKIE		pObj;
2075    u32             subcmd = wrq->flags;
2076
2077	if (dev->priv_flags == INT_MAIN)
2078		pAd = dev->priv;
2079	else
2080	{
2081		pVirtualAd = dev->priv;
2082		pAd = pVirtualAd->RtmpDev->priv;
2083	}
2084	pObj = (POS_COOKIE) pAd->OS_Cookie;
2085
2086	if (pAd == NULL)
2087	{
2088		/* if 1st open fail, pAd will be free;
2089		   So the net_dev->priv will be NULL in 2rd open */
2090		return -ENETDOWN;
2091	}
2092
2093    if (extra == NULL)
2094    {
2095        wrq->length = 0;
2096        return -EIO;
2097    }
2098    memset(extra, 0x00, IW_PRIV_SIZE_MASK);
2099
2100	{
2101		pObj->ioctl_if_type = INT_MAIN;
2102        pObj->ioctl_if = MAIN_MBSSID;
2103	}
2104
2105    switch(subcmd)
2106    {
2107
2108        case SHOW_CONN_STATUS:
2109            if (MONITOR_ON(pAd))
2110            {
2111#ifdef DOT11_N_SUPPORT
2112                if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED &&
2113                    pAd->CommonCfg.RegTransmitSetting.field.BW)
2114                    sprintf(extra, "Monitor Mode(CentralChannel %d)\n", pAd->CommonCfg.CentralChannel);
2115                else
2116#endif // DOT11_N_SUPPORT //
2117                    sprintf(extra, "Monitor Mode(Channel %d)\n", pAd->CommonCfg.Channel);
2118            }
2119            else
2120            {
2121                if (pAd->IndicateMediaState == NdisMediaStateConnected)
2122            	{
2123            	    if (INFRA_ON(pAd))
2124                    {
2125                    sprintf(extra, "Connected(AP: %s[%02X:%02X:%02X:%02X:%02X:%02X])\n",
2126                                    pAd->CommonCfg.Ssid,
2127                                    pAd->CommonCfg.Bssid[0],
2128                                    pAd->CommonCfg.Bssid[1],
2129                                    pAd->CommonCfg.Bssid[2],
2130                                    pAd->CommonCfg.Bssid[3],
2131                                    pAd->CommonCfg.Bssid[4],
2132                                    pAd->CommonCfg.Bssid[5]);
2133            		DBGPRINT(RT_DEBUG_TRACE ,("Ssid=%s ,Ssidlen = %d\n",pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen));
2134            	}
2135                    else if (ADHOC_ON(pAd))
2136                        sprintf(extra, "Connected\n");
2137            	}
2138            	else
2139            	{
2140            	    sprintf(extra, "Disconnected\n");
2141            		DBGPRINT(RT_DEBUG_TRACE ,("ConnStatus is not connected\n"));
2142            	}
2143            }
2144            wrq->length = strlen(extra) + 1; // 1: size of '\0'
2145            break;
2146        case SHOW_DRVIER_VERION:
2147            sprintf(extra, "Driver version-%s, %s %s\n", STA_DRIVER_VERSION, __DATE__, __TIME__ );
2148            wrq->length = strlen(extra) + 1; // 1: size of '\0'
2149            break;
2150#ifdef DOT11_N_SUPPORT
2151        case SHOW_BA_INFO:
2152            getBaInfo(pAd, extra);
2153            wrq->length = strlen(extra) + 1; // 1: size of '\0'
2154            break;
2155#endif // DOT11_N_SUPPORT //
2156		case SHOW_DESC_INFO:
2157			{
2158				Show_DescInfo_Proc(pAd, NULL);
2159				wrq->length = 0; // 1: size of '\0'
2160			}
2161			break;
2162        case RAIO_OFF:
2163            if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
2164            {
2165                sprintf(extra, "Scanning\n");
2166                wrq->length = strlen(extra) + 1; // 1: size of '\0'
2167                break;
2168            }
2169            pAd->StaCfg.bSwRadio = FALSE;
2170            if (pAd->StaCfg.bRadio != (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio))
2171            {
2172                pAd->StaCfg.bRadio = (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio);
2173                if (pAd->StaCfg.bRadio == FALSE)
2174                {
2175                    MlmeRadioOff(pAd);
2176                    // Update extra information
2177					pAd->ExtraInfo = SW_RADIO_OFF;
2178                }
2179            }
2180            sprintf(extra, "Radio Off\n");
2181            wrq->length = strlen(extra) + 1; // 1: size of '\0'
2182            break;
2183        case RAIO_ON:
2184            if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
2185            {
2186                sprintf(extra, "Scanning\n");
2187                wrq->length = strlen(extra) + 1; // 1: size of '\0'
2188                break;
2189            }
2190            pAd->StaCfg.bSwRadio = TRUE;
2191            //if (pAd->StaCfg.bRadio != (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio))
2192            {
2193                pAd->StaCfg.bRadio = (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio);
2194                if (pAd->StaCfg.bRadio == TRUE)
2195                {
2196                    MlmeRadioOn(pAd);
2197                    // Update extra information
2198					pAd->ExtraInfo = EXTRA_INFO_CLEAR;
2199                }
2200            }
2201            sprintf(extra, "Radio On\n");
2202            wrq->length = strlen(extra) + 1; // 1: size of '\0'
2203            break;
2204
2205
2206#ifdef QOS_DLS_SUPPORT
2207		case SHOW_DLS_ENTRY_INFO:
2208			{
2209				Set_DlsEntryInfo_Display_Proc(pAd, NULL);
2210				wrq->length = 0; // 1: size of '\0'
2211			}
2212			break;
2213#endif // QOS_DLS_SUPPORT //
2214
2215		case SHOW_CFG_VALUE:
2216			{
2217				Status = RTMPShowCfgValue(pAd, wrq->pointer, extra);
2218				if (Status == 0)
2219					wrq->length = strlen(extra) + 1; // 1: size of '\0'
2220			}
2221			break;
2222		case SHOW_ADHOC_ENTRY_INFO:
2223			Show_Adhoc_MacTable_Proc(pAd, extra);
2224			wrq->length = strlen(extra) + 1; // 1: size of '\0'
2225			break;
2226        default:
2227            DBGPRINT(RT_DEBUG_TRACE, ("%s - unknow subcmd = %d\n", __func__, subcmd));
2228            break;
2229    }
2230
2231    return Status;
2232}
2233
2234#ifdef SIOCSIWMLME
2235int rt_ioctl_siwmlme(struct net_device *dev,
2236			   struct iw_request_info *info,
2237			   union iwreq_data *wrqu,
2238			   char *extra)
2239{
2240	PRTMP_ADAPTER   pAd = (PRTMP_ADAPTER) dev->priv;
2241	struct iw_mlme *pMlme = (struct iw_mlme *)wrqu->data.pointer;
2242	MLME_QUEUE_ELEM				MsgElem;
2243	MLME_DISASSOC_REQ_STRUCT	DisAssocReq;
2244	MLME_DEAUTH_REQ_STRUCT      DeAuthReq;
2245
2246	DBGPRINT(RT_DEBUG_TRACE, ("====> %s\n", __func__));
2247
2248	if (pMlme == NULL)
2249		return -EINVAL;
2250
2251	switch(pMlme->cmd)
2252	{
2253#ifdef IW_MLME_DEAUTH
2254		case IW_MLME_DEAUTH:
2255			DBGPRINT(RT_DEBUG_TRACE, ("====> %s - IW_MLME_DEAUTH\n", __func__));
2256			COPY_MAC_ADDR(DeAuthReq.Addr, pAd->CommonCfg.Bssid);
2257			DeAuthReq.Reason = pMlme->reason_code;
2258			MsgElem.MsgLen = sizeof(MLME_DEAUTH_REQ_STRUCT);
2259			NdisMoveMemory(MsgElem.Msg, &DeAuthReq, sizeof(MLME_DEAUTH_REQ_STRUCT));
2260			MlmeDeauthReqAction(pAd, &MsgElem);
2261			if (INFRA_ON(pAd))
2262			{
2263			    LinkDown(pAd, FALSE);
2264			    pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
2265			}
2266			break;
2267#endif // IW_MLME_DEAUTH //
2268#ifdef IW_MLME_DISASSOC
2269		case IW_MLME_DISASSOC:
2270			DBGPRINT(RT_DEBUG_TRACE, ("====> %s - IW_MLME_DISASSOC\n", __func__));
2271			COPY_MAC_ADDR(DisAssocReq.Addr, pAd->CommonCfg.Bssid);
2272			DisAssocReq.Reason =  pMlme->reason_code;
2273
2274			MsgElem.Machine = ASSOC_STATE_MACHINE;
2275			MsgElem.MsgType = MT2_MLME_DISASSOC_REQ;
2276			MsgElem.MsgLen = sizeof(MLME_DISASSOC_REQ_STRUCT);
2277			NdisMoveMemory(MsgElem.Msg, &DisAssocReq, sizeof(MLME_DISASSOC_REQ_STRUCT));
2278
2279			pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_DISASSOC;
2280			MlmeDisassocReqAction(pAd, &MsgElem);
2281			break;
2282#endif // IW_MLME_DISASSOC //
2283		default:
2284			DBGPRINT(RT_DEBUG_TRACE, ("====> %s - Unknow Command\n", __func__));
2285			break;
2286	}
2287
2288	return 0;
2289}
2290#endif // SIOCSIWMLME //
2291
2292#if WIRELESS_EXT > 17
2293int rt_ioctl_siwauth(struct net_device *dev,
2294			  struct iw_request_info *info,
2295			  union iwreq_data *wrqu, char *extra)
2296{
2297	PRTMP_ADAPTER   pAdapter = (PRTMP_ADAPTER) dev->priv;
2298	struct iw_param *param = &wrqu->param;
2299
2300    //check if the interface is down
2301	if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
2302	{
2303  		DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
2304    	return -ENETDOWN;
2305	}
2306	switch (param->flags & IW_AUTH_INDEX) {
2307    	case IW_AUTH_WPA_VERSION:
2308            if (param->value == IW_AUTH_WPA_VERSION_WPA)
2309            {
2310                pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPAPSK;
2311				if (pAdapter->StaCfg.BssType == BSS_ADHOC)
2312					pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPANone;
2313            }
2314            else if (param->value == IW_AUTH_WPA_VERSION_WPA2)
2315                pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPA2PSK;
2316
2317            DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_WPA_VERSION - param->value = %d!\n", __func__, param->value));
2318            break;
2319    	case IW_AUTH_CIPHER_PAIRWISE:
2320            if (param->value == IW_AUTH_CIPHER_NONE)
2321            {
2322                pAdapter->StaCfg.WepStatus = Ndis802_11WEPDisabled;
2323                pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
2324                pAdapter->StaCfg.PairCipher = Ndis802_11WEPDisabled;
2325            }
2326            else if (param->value == IW_AUTH_CIPHER_WEP40 ||
2327                     param->value == IW_AUTH_CIPHER_WEP104)
2328            {
2329                pAdapter->StaCfg.WepStatus = Ndis802_11WEPEnabled;
2330                pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
2331                pAdapter->StaCfg.PairCipher = Ndis802_11WEPEnabled;
2332#ifdef WPA_SUPPLICANT_SUPPORT
2333                pAdapter->StaCfg.IEEE8021X = FALSE;
2334#endif // WPA_SUPPLICANT_SUPPORT //
2335            }
2336            else if (param->value == IW_AUTH_CIPHER_TKIP)
2337            {
2338                pAdapter->StaCfg.WepStatus = Ndis802_11Encryption2Enabled;
2339                pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
2340                pAdapter->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
2341            }
2342            else if (param->value == IW_AUTH_CIPHER_CCMP)
2343            {
2344                pAdapter->StaCfg.WepStatus = Ndis802_11Encryption3Enabled;
2345                pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
2346                pAdapter->StaCfg.PairCipher = Ndis802_11Encryption3Enabled;
2347            }
2348            DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_CIPHER_PAIRWISE - param->value = %d!\n", __func__, param->value));
2349            break;
2350    	case IW_AUTH_CIPHER_GROUP:
2351            if (param->value == IW_AUTH_CIPHER_NONE)
2352            {
2353                pAdapter->StaCfg.GroupCipher = Ndis802_11WEPDisabled;
2354            }
2355            else if (param->value == IW_AUTH_CIPHER_WEP40 ||
2356                     param->value == IW_AUTH_CIPHER_WEP104)
2357            {
2358                pAdapter->StaCfg.GroupCipher = Ndis802_11WEPEnabled;
2359            }
2360            else if (param->value == IW_AUTH_CIPHER_TKIP)
2361            {
2362                pAdapter->StaCfg.GroupCipher = Ndis802_11Encryption2Enabled;
2363            }
2364            else if (param->value == IW_AUTH_CIPHER_CCMP)
2365            {
2366                pAdapter->StaCfg.GroupCipher = Ndis802_11Encryption3Enabled;
2367            }
2368            DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_CIPHER_GROUP - param->value = %d!\n", __func__, param->value));
2369            break;
2370    	case IW_AUTH_KEY_MGMT:
2371            if (param->value == IW_AUTH_KEY_MGMT_802_1X)
2372            {
2373                if (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK)
2374                {
2375                    pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPA;
2376#ifdef WPA_SUPPLICANT_SUPPORT
2377                    pAdapter->StaCfg.IEEE8021X = FALSE;
2378#endif // WPA_SUPPLICANT_SUPPORT //
2379                }
2380                else if (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)
2381                {
2382                    pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPA2;
2383#ifdef WPA_SUPPLICANT_SUPPORT
2384                    pAdapter->StaCfg.IEEE8021X = FALSE;
2385#endif // WPA_SUPPLICANT_SUPPORT //
2386                }
2387#ifdef WPA_SUPPLICANT_SUPPORT
2388                else
2389                    // WEP 1x
2390                    pAdapter->StaCfg.IEEE8021X = TRUE;
2391#endif // WPA_SUPPLICANT_SUPPORT //
2392            }
2393            else if (param->value == 0)
2394            {
2395                //pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
2396				STA_PORT_SECURED(pAdapter);
2397            }
2398            DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_KEY_MGMT - param->value = %d!\n", __func__, param->value));
2399            break;
2400    	case IW_AUTH_RX_UNENCRYPTED_EAPOL:
2401            break;
2402    	case IW_AUTH_PRIVACY_INVOKED:
2403            /*if (param->value == 0)
2404			{
2405                pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
2406                pAdapter->StaCfg.WepStatus = Ndis802_11WEPDisabled;
2407                pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
2408                pAdapter->StaCfg.PairCipher = Ndis802_11WEPDisabled;
2409        	    pAdapter->StaCfg.GroupCipher = Ndis802_11WEPDisabled;
2410            }*/
2411            DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_PRIVACY_INVOKED - param->value = %d!\n", __func__, param->value));
2412    		break;
2413    	case IW_AUTH_DROP_UNENCRYPTED:
2414            if (param->value != 0)
2415                pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
2416			else
2417			{
2418                //pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
2419				STA_PORT_SECURED(pAdapter);
2420			}
2421            DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_WPA_VERSION - param->value = %d!\n", __func__, param->value));
2422    		break;
2423    	case IW_AUTH_80211_AUTH_ALG:
2424			if (param->value & IW_AUTH_ALG_SHARED_KEY)
2425            {
2426				pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeShared;
2427			}
2428            else if (param->value & IW_AUTH_ALG_OPEN_SYSTEM)
2429            {
2430				pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
2431			}
2432            else
2433				return -EINVAL;
2434            DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_80211_AUTH_ALG - param->value = %d!\n", __func__, param->value));
2435			break;
2436    	case IW_AUTH_WPA_ENABLED:
2437    		DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_WPA_ENABLED - Driver supports WPA!(param->value = %d)\n", __func__, param->value));
2438    		break;
2439    	default:
2440    		return -EOPNOTSUPP;
2441}
2442
2443	return 0;
2444}
2445
2446int rt_ioctl_giwauth(struct net_device *dev,
2447			       struct iw_request_info *info,
2448			       union iwreq_data *wrqu, char *extra)
2449{
2450	PRTMP_ADAPTER   pAdapter = (PRTMP_ADAPTER) dev->priv;
2451	struct iw_param *param = &wrqu->param;
2452
2453    //check if the interface is down
2454	if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
2455    {
2456  		DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
2457    	return -ENETDOWN;
2458    }
2459
2460	switch (param->flags & IW_AUTH_INDEX) {
2461	case IW_AUTH_DROP_UNENCRYPTED:
2462        param->value = (pAdapter->StaCfg.WepStatus == Ndis802_11WEPDisabled) ? 0 : 1;
2463		break;
2464
2465	case IW_AUTH_80211_AUTH_ALG:
2466        param->value = (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeShared) ? IW_AUTH_ALG_SHARED_KEY : IW_AUTH_ALG_OPEN_SYSTEM;
2467		break;
2468
2469	case IW_AUTH_WPA_ENABLED:
2470		param->value = (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA) ? 1 : 0;
2471		break;
2472
2473	default:
2474		return -EOPNOTSUPP;
2475	}
2476    DBGPRINT(RT_DEBUG_TRACE, ("rt_ioctl_giwauth::param->value = %d!\n", param->value));
2477	return 0;
2478}
2479
2480void fnSetCipherKey(
2481    IN  PRTMP_ADAPTER   pAdapter,
2482    IN  INT             keyIdx,
2483    IN  UCHAR           CipherAlg,
2484    IN  BOOLEAN         bGTK,
2485    IN  struct iw_encode_ext *ext)
2486{
2487    NdisZeroMemory(&pAdapter->SharedKey[BSS0][keyIdx], sizeof(CIPHER_KEY));
2488    pAdapter->SharedKey[BSS0][keyIdx].KeyLen = LEN_TKIP_EK;
2489    NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].Key, ext->key, LEN_TKIP_EK);
2490    NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].TxMic, ext->key + LEN_TKIP_EK, LEN_TKIP_TXMICK);
2491    NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].RxMic, ext->key + LEN_TKIP_EK + LEN_TKIP_TXMICK, LEN_TKIP_RXMICK);
2492    pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = CipherAlg;
2493
2494    // Update group key information to ASIC Shared Key Table
2495	AsicAddSharedKeyEntry(pAdapter,
2496						  BSS0,
2497						  keyIdx,
2498						  pAdapter->SharedKey[BSS0][keyIdx].CipherAlg,
2499						  pAdapter->SharedKey[BSS0][keyIdx].Key,
2500						  pAdapter->SharedKey[BSS0][keyIdx].TxMic,
2501						  pAdapter->SharedKey[BSS0][keyIdx].RxMic);
2502
2503    if (bGTK)
2504        // Update ASIC WCID attribute table and IVEIV table
2505    	RTMPAddWcidAttributeEntry(pAdapter,
2506    							  BSS0,
2507    							  keyIdx,
2508    							  pAdapter->SharedKey[BSS0][keyIdx].CipherAlg,
2509    							  NULL);
2510    else
2511        // Update ASIC WCID attribute table and IVEIV table
2512    	RTMPAddWcidAttributeEntry(pAdapter,
2513    							  BSS0,
2514    							  keyIdx,
2515    							  pAdapter->SharedKey[BSS0][keyIdx].CipherAlg,
2516    							  &pAdapter->MacTab.Content[BSSID_WCID]);
2517}
2518
2519int rt_ioctl_siwencodeext(struct net_device *dev,
2520			   struct iw_request_info *info,
2521			   union iwreq_data *wrqu,
2522			   char *extra)
2523			{
2524    PRTMP_ADAPTER   pAdapter = (PRTMP_ADAPTER) dev->priv;
2525	struct iw_point *encoding = &wrqu->encoding;
2526	struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
2527    int keyIdx, alg = ext->alg;
2528
2529    //check if the interface is down
2530	if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
2531	{
2532  		DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
2533    	return -ENETDOWN;
2534	}
2535
2536    if (encoding->flags & IW_ENCODE_DISABLED)
2537	{
2538        keyIdx = (encoding->flags & IW_ENCODE_INDEX) - 1;
2539        // set BSSID wcid entry of the Pair-wise Key table as no-security mode
2540	    AsicRemovePairwiseKeyEntry(pAdapter, BSS0, BSSID_WCID);
2541        pAdapter->SharedKey[BSS0][keyIdx].KeyLen = 0;
2542		pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = CIPHER_NONE;
2543		AsicRemoveSharedKeyEntry(pAdapter, 0, (UCHAR)keyIdx);
2544        NdisZeroMemory(&pAdapter->SharedKey[BSS0][keyIdx], sizeof(CIPHER_KEY));
2545        DBGPRINT(RT_DEBUG_TRACE, ("%s::Remove all keys!(encoding->flags = %x)\n", __func__, encoding->flags));
2546    }
2547					else
2548    {
2549        // Get Key Index and convet to our own defined key index
2550    	keyIdx = (encoding->flags & IW_ENCODE_INDEX) - 1;
2551    	if((keyIdx < 0) || (keyIdx >= NR_WEP_KEYS))
2552    		return -EINVAL;
2553
2554        if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
2555        {
2556            pAdapter->StaCfg.DefaultKeyId = keyIdx;
2557            DBGPRINT(RT_DEBUG_TRACE, ("%s::DefaultKeyId = %d\n", __func__, pAdapter->StaCfg.DefaultKeyId));
2558        }
2559
2560        switch (alg) {
2561    		case IW_ENCODE_ALG_NONE:
2562                DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_ENCODE_ALG_NONE\n", __func__));
2563    			break;
2564    		case IW_ENCODE_ALG_WEP:
2565                DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_ENCODE_ALG_WEP - ext->key_len = %d, keyIdx = %d\n", __func__, ext->key_len, keyIdx));
2566    			if (ext->key_len == MAX_WEP_KEY_SIZE)
2567                {
2568        			pAdapter->SharedKey[BSS0][keyIdx].KeyLen = MAX_WEP_KEY_SIZE;
2569                    pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = CIPHER_WEP128;
2570				}
2571        		else if (ext->key_len == MIN_WEP_KEY_SIZE)
2572                {
2573                    pAdapter->SharedKey[BSS0][keyIdx].KeyLen = MIN_WEP_KEY_SIZE;
2574                    pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = CIPHER_WEP64;
2575			}
2576        		else
2577                    return -EINVAL;
2578
2579                NdisZeroMemory(pAdapter->SharedKey[BSS0][keyIdx].Key,  16);
2580			    NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].Key, ext->key, ext->key_len);
2581    			break;
2582            case IW_ENCODE_ALG_TKIP:
2583                DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_ENCODE_ALG_TKIP - keyIdx = %d, ext->key_len = %d\n", __func__, keyIdx, ext->key_len));
2584                if (ext->key_len == 32)
2585                {
2586                    if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
2587                    {
2588                        fnSetCipherKey(pAdapter, keyIdx, CIPHER_TKIP, FALSE, ext);
2589                        if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA2)
2590                        {
2591                            //pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
2592                            STA_PORT_SECURED(pAdapter);
2593                        }
2594		}
2595                    else if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY)
2596                    {
2597                        fnSetCipherKey(pAdapter, keyIdx, CIPHER_TKIP, TRUE, ext);
2598
2599                        // set 802.1x port control
2600            	        //pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
2601            	        STA_PORT_SECURED(pAdapter);
2602                    }
2603                }
2604                else
2605                    return -EINVAL;
2606                break;
2607            case IW_ENCODE_ALG_CCMP:
2608                if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
2609		{
2610                    fnSetCipherKey(pAdapter, keyIdx, CIPHER_AES, FALSE, ext);
2611                    if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA2)
2612                    	//pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
2613                    	STA_PORT_SECURED(pAdapter);
2614                }
2615                else if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY)
2616                {
2617                    fnSetCipherKey(pAdapter, keyIdx, CIPHER_AES, TRUE, ext);
2618
2619                    // set 802.1x port control
2620        	        //pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
2621        	        STA_PORT_SECURED(pAdapter);
2622                }
2623                break;
2624    		default:
2625    			return -EINVAL;
2626		}
2627    }
2628
2629    return 0;
2630}
2631
2632int
2633rt_ioctl_giwencodeext(struct net_device *dev,
2634			  struct iw_request_info *info,
2635			  union iwreq_data *wrqu, char *extra)
2636{
2637	PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) dev->priv;
2638	PCHAR pKey = NULL;
2639	struct iw_point *encoding = &wrqu->encoding;
2640	struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
2641	int idx, max_key_len;
2642
2643	DBGPRINT(RT_DEBUG_TRACE ,("===> rt_ioctl_giwencodeext\n"));
2644
2645	max_key_len = encoding->length - sizeof(*ext);
2646	if (max_key_len < 0)
2647		return -EINVAL;
2648
2649	idx = encoding->flags & IW_ENCODE_INDEX;
2650	if (idx)
2651	{
2652		if (idx < 1 || idx > 4)
2653			return -EINVAL;
2654		idx--;
2655
2656		if ((pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) ||
2657			(pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled))
2658		{
2659			if (idx != pAd->StaCfg.DefaultKeyId)
2660			{
2661				ext->key_len = 0;
2662				return 0;
2663			}
2664		}
2665	}
2666	else
2667		idx = pAd->StaCfg.DefaultKeyId;
2668
2669	encoding->flags = idx + 1;
2670	memset(ext, 0, sizeof(*ext));
2671
2672	ext->key_len = 0;
2673	switch(pAd->StaCfg.WepStatus) {
2674		case Ndis802_11WEPDisabled:
2675			ext->alg = IW_ENCODE_ALG_NONE;
2676			encoding->flags |= IW_ENCODE_DISABLED;
2677			break;
2678		case Ndis802_11WEPEnabled:
2679			ext->alg = IW_ENCODE_ALG_WEP;
2680			if (pAd->SharedKey[BSS0][idx].KeyLen > max_key_len)
2681				return -E2BIG;
2682			else
2683			{
2684				ext->key_len = pAd->SharedKey[BSS0][idx].KeyLen;
2685				pKey = &(pAd->SharedKey[BSS0][idx].Key[0]);
2686			}
2687			break;
2688		case Ndis802_11Encryption2Enabled:
2689		case Ndis802_11Encryption3Enabled:
2690			if (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled)
2691				ext->alg = IW_ENCODE_ALG_TKIP;
2692			else
2693				ext->alg = IW_ENCODE_ALG_CCMP;
2694
2695			if (max_key_len < 32)
2696				return -E2BIG;
2697			else
2698			{
2699				ext->key_len = 32;
2700				pKey = &pAd->StaCfg.PMK[0];
2701			}
2702			break;
2703		default:
2704			return -EINVAL;
2705	}
2706
2707	if (ext->key_len && pKey)
2708	{
2709		encoding->flags |= IW_ENCODE_ENABLED;
2710		memcpy(ext->key, pKey, ext->key_len);
2711	}
2712
2713	return 0;
2714}
2715
2716#ifdef SIOCSIWGENIE
2717int rt_ioctl_siwgenie(struct net_device *dev,
2718			  struct iw_request_info *info,
2719			  union iwreq_data *wrqu, char *extra)
2720{
2721	PRTMP_ADAPTER   pAd = (PRTMP_ADAPTER) dev->priv;
2722
2723	if (wrqu->data.length > MAX_LEN_OF_RSNIE ||
2724	    (wrqu->data.length && extra == NULL))
2725		return -EINVAL;
2726
2727	if (wrqu->data.length)
2728	{
2729		pAd->StaCfg.RSNIE_Len = wrqu->data.length;
2730		NdisMoveMemory(&pAd->StaCfg.RSN_IE[0], extra, pAd->StaCfg.RSNIE_Len);
2731	}
2732	else
2733	{
2734		pAd->StaCfg.RSNIE_Len = 0;
2735		NdisZeroMemory(&pAd->StaCfg.RSN_IE[0], MAX_LEN_OF_RSNIE);
2736	}
2737
2738	return 0;
2739}
2740#endif // SIOCSIWGENIE //
2741
2742int rt_ioctl_giwgenie(struct net_device *dev,
2743			       struct iw_request_info *info,
2744			       union iwreq_data *wrqu, char *extra)
2745{
2746	PRTMP_ADAPTER   pAd = (PRTMP_ADAPTER) dev->priv;
2747
2748	if ((pAd->StaCfg.RSNIE_Len == 0) ||
2749		(pAd->StaCfg.AuthMode < Ndis802_11AuthModeWPA))
2750	{
2751		wrqu->data.length = 0;
2752		return 0;
2753	}
2754
2755#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
2756#ifdef SIOCSIWGENIE
2757	if (pAd->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_ENABLE)
2758	{
2759	if (wrqu->data.length < pAd->StaCfg.RSNIE_Len)
2760		return -E2BIG;
2761
2762	wrqu->data.length = pAd->StaCfg.RSNIE_Len;
2763	memcpy(extra, &pAd->StaCfg.RSN_IE[0], pAd->StaCfg.RSNIE_Len);
2764	}
2765	else
2766#endif // SIOCSIWGENIE //
2767#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
2768	{
2769		UCHAR RSNIe = IE_WPA;
2770
2771		if (wrqu->data.length < (pAd->StaCfg.RSNIE_Len + 2)) // ID, Len
2772			return -E2BIG;
2773		wrqu->data.length = pAd->StaCfg.RSNIE_Len + 2;
2774
2775		if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK) ||
2776            (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2))
2777			RSNIe = IE_RSN;
2778
2779		extra[0] = (char)RSNIe;
2780		extra[1] = pAd->StaCfg.RSNIE_Len;
2781		memcpy(extra+2, &pAd->StaCfg.RSN_IE[0], pAd->StaCfg.RSNIE_Len);
2782	}
2783
2784	return 0;
2785}
2786
2787int rt_ioctl_siwpmksa(struct net_device *dev,
2788			   struct iw_request_info *info,
2789			   union iwreq_data *wrqu,
2790			   char *extra)
2791{
2792	PRTMP_ADAPTER   pAd = (PRTMP_ADAPTER) dev->priv;
2793	struct iw_pmksa *pPmksa = (struct iw_pmksa *)wrqu->data.pointer;
2794	INT	CachedIdx = 0, idx = 0;
2795
2796	if (pPmksa == NULL)
2797		return -EINVAL;
2798
2799	DBGPRINT(RT_DEBUG_TRACE ,("===> rt_ioctl_siwpmksa\n"));
2800	switch(pPmksa->cmd)
2801	{
2802		case IW_PMKSA_FLUSH:
2803			NdisZeroMemory(pAd->StaCfg.SavedPMK, sizeof(BSSID_INFO)*PMKID_NO);
2804			DBGPRINT(RT_DEBUG_TRACE ,("rt_ioctl_siwpmksa - IW_PMKSA_FLUSH\n"));
2805			break;
2806		case IW_PMKSA_REMOVE:
2807			for (CachedIdx = 0; CachedIdx < pAd->StaCfg.SavedPMKNum; CachedIdx++)
2808			{
2809		        // compare the BSSID
2810		        if (NdisEqualMemory(pPmksa->bssid.sa_data, pAd->StaCfg.SavedPMK[CachedIdx].BSSID, MAC_ADDR_LEN))
2811		        {
2812		        	NdisZeroMemory(pAd->StaCfg.SavedPMK[CachedIdx].BSSID, MAC_ADDR_LEN);
2813					NdisZeroMemory(pAd->StaCfg.SavedPMK[CachedIdx].PMKID, 16);
2814					for (idx = CachedIdx; idx < (pAd->StaCfg.SavedPMKNum - 1); idx++)
2815					{
2816						NdisMoveMemory(&pAd->StaCfg.SavedPMK[idx].BSSID[0], &pAd->StaCfg.SavedPMK[idx+1].BSSID[0], MAC_ADDR_LEN);
2817						NdisMoveMemory(&pAd->StaCfg.SavedPMK[idx].PMKID[0], &pAd->StaCfg.SavedPMK[idx+1].PMKID[0], 16);
2818					}
2819					pAd->StaCfg.SavedPMKNum--;
2820			        break;
2821		        }
2822	        }
2823
2824			DBGPRINT(RT_DEBUG_TRACE ,("rt_ioctl_siwpmksa - IW_PMKSA_REMOVE\n"));
2825			break;
2826		case IW_PMKSA_ADD:
2827			for (CachedIdx = 0; CachedIdx < pAd->StaCfg.SavedPMKNum; CachedIdx++)
2828			{
2829		        // compare the BSSID
2830		        if (NdisEqualMemory(pPmksa->bssid.sa_data, pAd->StaCfg.SavedPMK[CachedIdx].BSSID, MAC_ADDR_LEN))
2831			        break;
2832	        }
2833
2834	        // Found, replace it
2835	        if (CachedIdx < PMKID_NO)
2836	        {
2837		        DBGPRINT(RT_DEBUG_OFF, ("Update PMKID, idx = %d\n", CachedIdx));
2838		        NdisMoveMemory(&pAd->StaCfg.SavedPMK[CachedIdx].BSSID[0], pPmksa->bssid.sa_data, MAC_ADDR_LEN);
2839				NdisMoveMemory(&pAd->StaCfg.SavedPMK[CachedIdx].PMKID[0], pPmksa->pmkid, 16);
2840		        pAd->StaCfg.SavedPMKNum++;
2841	        }
2842	        // Not found, replace the last one
2843	        else
2844	        {
2845		        // Randomly replace one
2846		        CachedIdx = (pPmksa->bssid.sa_data[5] % PMKID_NO);
2847		        DBGPRINT(RT_DEBUG_OFF, ("Update PMKID, idx = %d\n", CachedIdx));
2848		        NdisMoveMemory(&pAd->StaCfg.SavedPMK[CachedIdx].BSSID[0], pPmksa->bssid.sa_data, MAC_ADDR_LEN);
2849				NdisMoveMemory(&pAd->StaCfg.SavedPMK[CachedIdx].PMKID[0], pPmksa->pmkid, 16);
2850	        }
2851
2852			DBGPRINT(RT_DEBUG_TRACE ,("rt_ioctl_siwpmksa - IW_PMKSA_ADD\n"));
2853			break;
2854		default:
2855			DBGPRINT(RT_DEBUG_TRACE ,("rt_ioctl_siwpmksa - Unknow Command!!\n"));
2856			break;
2857	}
2858
2859	return 0;
2860}
2861#endif // #if WIRELESS_EXT > 17
2862
2863#ifdef DBG
2864static int
2865rt_private_ioctl_bbp(struct net_device *dev, struct iw_request_info *info,
2866		struct iw_point *wrq, char *extra)
2867			{
2868	CHAR				*this_char;
2869	CHAR				*value = NULL;
2870	UCHAR				regBBP = 0;
2871//	CHAR				arg[255]={0};
2872	UINT32				bbpId;
2873	UINT32				bbpValue;
2874	BOOLEAN				bIsPrintAllBBP = FALSE;
2875	INT					Status = 0;
2876    PRTMP_ADAPTER       pAdapter = (PRTMP_ADAPTER) dev->priv;
2877
2878
2879	memset(extra, 0x00, IW_PRIV_SIZE_MASK);
2880
2881	if (wrq->length > 1) //No parameters.
2882				{
2883		sprintf(extra, "\n");
2884
2885		//Parsing Read or Write
2886		this_char = wrq->pointer;
2887		DBGPRINT(RT_DEBUG_TRACE, ("this_char=%s\n", this_char));
2888		if (!*this_char)
2889			goto next;
2890
2891		if ((value = rtstrchr(this_char, '=')) != NULL)
2892			*value++ = 0;
2893
2894		if (!value || !*value)
2895		{ //Read
2896			DBGPRINT(RT_DEBUG_TRACE, ("this_char=%s, value=%s\n", this_char, value));
2897			if (sscanf(this_char, "%d", &(bbpId)) == 1)
2898			{
2899				if (bbpId <= 136)
2900				{
2901#ifdef RALINK_ATE
2902					if (ATE_ON(pAdapter))
2903					{
2904						ATE_BBP_IO_READ8_BY_REG_ID(pAdapter, bbpId, &regBBP);
2905					}
2906					else
2907#endif // RALINK_ATE //
2908					{
2909					RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, bbpId, &regBBP);
2910					}
2911					sprintf(extra+strlen(extra), "R%02d[0x%02X]:%02X\n", bbpId, bbpId*2, regBBP);
2912                    wrq->length = strlen(extra) + 1; // 1: size of '\0'
2913					DBGPRINT(RT_DEBUG_TRACE, ("msg=%s\n", extra));
2914				}
2915				else
2916				{//Invalid parametes, so default printk all bbp
2917					bIsPrintAllBBP = TRUE;
2918					goto next;
2919				}
2920			}
2921			else
2922			{ //Invalid parametes, so default printk all bbp
2923				bIsPrintAllBBP = TRUE;
2924				goto next;
2925			}
2926		}
2927		else
2928		{ //Write
2929			if ((sscanf(this_char, "%d", &(bbpId)) == 1) && (sscanf(value, "%x", &(bbpValue)) == 1))
2930			{
2931				if (bbpId <= 136)
2932				{
2933#ifdef RALINK_ATE
2934					if (ATE_ON(pAdapter))
2935					{
2936						ATE_BBP_IO_WRITE8_BY_REG_ID(pAdapter, bbpId, bbpValue);
2937						//Read it back for showing
2938						ATE_BBP_IO_READ8_BY_REG_ID(pAdapter, bbpId, &regBBP);
2939					}
2940					else
2941#endif // RALINK_ATE //
2942					{
2943					    RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, bbpId, bbpValue);
2944    					//Read it back for showing
2945    					RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, bbpId, &regBBP);
2946			}
2947					sprintf(extra+strlen(extra), "R%02d[0x%02X]:%02X\n", bbpId, bbpId*2, regBBP);
2948                    wrq->length = strlen(extra) + 1; // 1: size of '\0'
2949					DBGPRINT(RT_DEBUG_TRACE, ("msg=%s\n", extra));
2950				}
2951				else
2952				{//Invalid parametes, so default printk all bbp
2953					bIsPrintAllBBP = TRUE;
2954					goto next;
2955				}
2956			}
2957			else
2958			{ //Invalid parametes, so default printk all bbp
2959				bIsPrintAllBBP = TRUE;
2960				goto next;
2961			}
2962		}
2963		}
2964	else
2965		bIsPrintAllBBP = TRUE;
2966
2967next:
2968	if (bIsPrintAllBBP)
2969	{
2970		memset(extra, 0x00, IW_PRIV_SIZE_MASK);
2971		sprintf(extra, "\n");
2972		for (bbpId = 0; bbpId <= 136; bbpId++)
2973		{
2974		    if (strlen(extra) >= (IW_PRIV_SIZE_MASK - 10))
2975                break;
2976#ifdef RALINK_ATE
2977			if (ATE_ON(pAdapter))
2978			{
2979				ATE_BBP_IO_READ8_BY_REG_ID(pAdapter, bbpId, &regBBP);
2980			}
2981			else
2982#endif // RALINK_ATE //
2983			RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, bbpId, &regBBP);
2984			sprintf(extra+strlen(extra), "R%02d[0x%02X]:%02X    ", bbpId, bbpId*2, regBBP);
2985			if (bbpId%5 == 4)
2986				sprintf(extra+strlen(extra), "\n");
2987		}
2988
2989        wrq->length = strlen(extra) + 1; // 1: size of '\0'
2990        DBGPRINT(RT_DEBUG_TRACE, ("wrq->length = %d\n", wrq->length));
2991	}
2992
2993	DBGPRINT(RT_DEBUG_TRACE, ("<==rt_private_ioctl_bbp\n\n"));
2994
2995    return Status;
2996}
2997#endif // DBG //
2998
2999int rt_ioctl_siwrate(struct net_device *dev,
3000			struct iw_request_info *info,
3001			union iwreq_data *wrqu, char *extra)
3002{
3003    PRTMP_ADAPTER   pAd = (PRTMP_ADAPTER) dev->priv;
3004    UINT32          rate = wrqu->bitrate.value, fixed = wrqu->bitrate.fixed;
3005
3006    //check if the interface is down
3007	if(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE))
3008	{
3009  		DBGPRINT(RT_DEBUG_TRACE, ("rt_ioctl_siwrate::Network is down!\n"));
3010    	return -ENETDOWN;
3011	}
3012
3013    DBGPRINT(RT_DEBUG_TRACE, ("rt_ioctl_siwrate::(rate = %d, fixed = %d)\n", rate, fixed));
3014    /* rate = -1 => auto rate
3015       rate = X, fixed = 1 => (fixed rate X)
3016    */
3017    if (rate == -1)
3018    {
3019		//Auto Rate
3020		pAd->StaCfg.DesiredTransmitSetting.field.MCS = MCS_AUTO;
3021		pAd->StaCfg.bAutoTxRateSwitch = TRUE;
3022		if ((pAd->CommonCfg.PhyMode <= PHY_11G) ||
3023		    (pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE <= MODE_OFDM))
3024			RTMPSetDesiredRates(pAd, -1);
3025
3026#ifdef DOT11_N_SUPPORT
3027		SetCommonHT(pAd);
3028#endif // DOT11_N_SUPPORT //
3029    }
3030    else
3031    {
3032        if (fixed)
3033        {
3034        	pAd->StaCfg.bAutoTxRateSwitch = FALSE;
3035            if ((pAd->CommonCfg.PhyMode <= PHY_11G) ||
3036                (pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE <= MODE_OFDM))
3037                RTMPSetDesiredRates(pAd, rate);
3038            else
3039            {
3040                pAd->StaCfg.DesiredTransmitSetting.field.MCS = MCS_AUTO;
3041#ifdef DOT11_N_SUPPORT
3042                SetCommonHT(pAd);
3043#endif // DOT11_N_SUPPORT //
3044            }
3045            DBGPRINT(RT_DEBUG_TRACE, ("rt_ioctl_siwrate::(HtMcs=%d)\n",pAd->StaCfg.DesiredTransmitSetting.field.MCS));
3046        }
3047        else
3048        {
3049            // TODO: rate = X, fixed = 0 => (rates <= X)
3050            return -EOPNOTSUPP;
3051        }
3052    }
3053
3054    return 0;
3055}
3056
3057int rt_ioctl_giwrate(struct net_device *dev,
3058			       struct iw_request_info *info,
3059			       union iwreq_data *wrqu, char *extra)
3060{
3061    PRTMP_ADAPTER   pAd = (PRTMP_ADAPTER) dev->priv;
3062    int rate_index = 0, rate_count = 0;
3063    HTTRANSMIT_SETTING ht_setting;
3064    __s32 ralinkrate[] =
3065	{2,  4,   11,  22, // CCK
3066	12, 18,   24,  36, 48, 72, 96, 108, // OFDM
3067	13, 26,   39,  52,  78, 104, 117, 130, 26,  52,  78, 104, 156, 208, 234, 260, // 20MHz, 800ns GI, MCS: 0 ~ 15
3068	39, 78,  117, 156, 234, 312, 351, 390,										  // 20MHz, 800ns GI, MCS: 16 ~ 23
3069	27, 54,   81, 108, 162, 216, 243, 270, 54, 108, 162, 216, 324, 432, 486, 540, // 40MHz, 800ns GI, MCS: 0 ~ 15
3070	81, 162, 243, 324, 486, 648, 729, 810,										  // 40MHz, 800ns GI, MCS: 16 ~ 23
3071	14, 29,   43,  57,  87, 115, 130, 144, 29, 59,   87, 115, 173, 230, 260, 288, // 20MHz, 400ns GI, MCS: 0 ~ 15
3072	43, 87,  130, 173, 260, 317, 390, 433,										  // 20MHz, 400ns GI, MCS: 16 ~ 23
3073	30, 60,   90, 120, 180, 240, 270, 300, 60, 120, 180, 240, 360, 480, 540, 600, // 40MHz, 400ns GI, MCS: 0 ~ 15
3074	90, 180, 270, 360, 540, 720, 810, 900};										  // 40MHz, 400ns GI, MCS: 16 ~ 23
3075
3076    rate_count = sizeof(ralinkrate)/sizeof(__s32);
3077    //check if the interface is down
3078	if(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE))
3079	{
3080  		DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
3081    	return -ENETDOWN;
3082	}
3083
3084    if ((pAd->StaCfg.bAutoTxRateSwitch == FALSE) &&
3085        (INFRA_ON(pAd)) &&
3086        ((pAd->CommonCfg.PhyMode <= PHY_11G) || (pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE <= MODE_OFDM)))
3087        ht_setting.word = pAd->StaCfg.HTPhyMode.word;
3088    else
3089        ht_setting.word = pAd->MacTab.Content[BSSID_WCID].HTPhyMode.word;
3090
3091#ifdef DOT11_N_SUPPORT
3092    if (ht_setting.field.MODE >= MODE_HTMIX)
3093    {
3094//    	rate_index = 12 + ((UCHAR)ht_setting.field.BW *16) + ((UCHAR)ht_setting.field.ShortGI *32) + ((UCHAR)ht_setting.field.MCS);
3095    	rate_index = 12 + ((UCHAR)ht_setting.field.BW *24) + ((UCHAR)ht_setting.field.ShortGI *48) + ((UCHAR)ht_setting.field.MCS);
3096    }
3097    else
3098#endif // DOT11_N_SUPPORT //
3099    if (ht_setting.field.MODE == MODE_OFDM)
3100    	rate_index = (UCHAR)(ht_setting.field.MCS) + 4;
3101    else if (ht_setting.field.MODE == MODE_CCK)
3102    	rate_index = (UCHAR)(ht_setting.field.MCS);
3103
3104    if (rate_index < 0)
3105        rate_index = 0;
3106
3107    if (rate_index > rate_count)
3108        rate_index = rate_count;
3109
3110    wrqu->bitrate.value = ralinkrate[rate_index] * 500000;
3111    wrqu->bitrate.disabled = 0;
3112
3113    return 0;
3114}
3115
3116static const iw_handler rt_handler[] =
3117{
3118	(iw_handler) NULL,			            /* SIOCSIWCOMMIT */
3119	(iw_handler) rt_ioctl_giwname,			/* SIOCGIWNAME   */
3120	(iw_handler) NULL,			            /* SIOCSIWNWID   */
3121	(iw_handler) NULL,			            /* SIOCGIWNWID   */
3122	(iw_handler) rt_ioctl_siwfreq,		    /* SIOCSIWFREQ   */
3123	(iw_handler) rt_ioctl_giwfreq,		    /* SIOCGIWFREQ   */
3124	(iw_handler) rt_ioctl_siwmode,		    /* SIOCSIWMODE   */
3125	(iw_handler) rt_ioctl_giwmode,		    /* SIOCGIWMODE   */
3126	(iw_handler) NULL,		                /* SIOCSIWSENS   */
3127	(iw_handler) NULL,		                /* SIOCGIWSENS   */
3128	(iw_handler) NULL /* not used */,		/* SIOCSIWRANGE  */
3129	(iw_handler) rt_ioctl_giwrange,		    /* SIOCGIWRANGE  */
3130	(iw_handler) NULL /* not used */,		/* SIOCSIWPRIV   */
3131	(iw_handler) NULL /* kernel code */,    /* SIOCGIWPRIV   */
3132	(iw_handler) NULL /* not used */,		/* SIOCSIWSTATS  */
3133	(iw_handler) rt28xx_get_wireless_stats /* kernel code */,    /* SIOCGIWSTATS  */
3134	(iw_handler) NULL,		                /* SIOCSIWSPY    */
3135	(iw_handler) NULL,		                /* SIOCGIWSPY    */
3136	(iw_handler) NULL,				        /* SIOCSIWTHRSPY */
3137	(iw_handler) NULL,				        /* SIOCGIWTHRSPY */
3138	(iw_handler) rt_ioctl_siwap,            /* SIOCSIWAP     */
3139	(iw_handler) rt_ioctl_giwap,		    /* SIOCGIWAP     */
3140#ifdef SIOCSIWMLME
3141	(iw_handler) rt_ioctl_siwmlme,	        /* SIOCSIWMLME   */
3142#else
3143	(iw_handler) NULL,				        /* SIOCSIWMLME */
3144#endif // SIOCSIWMLME //
3145	(iw_handler) rt_ioctl_iwaplist,		    /* SIOCGIWAPLIST */
3146#ifdef SIOCGIWSCAN
3147	(iw_handler) rt_ioctl_siwscan,		    /* SIOCSIWSCAN   */
3148	(iw_handler) rt_ioctl_giwscan,		    /* SIOCGIWSCAN   */
3149#else
3150	(iw_handler) NULL,				        /* SIOCSIWSCAN   */
3151	(iw_handler) NULL,				        /* SIOCGIWSCAN   */
3152#endif /* SIOCGIWSCAN */
3153	(iw_handler) rt_ioctl_siwessid,		    /* SIOCSIWESSID  */
3154	(iw_handler) rt_ioctl_giwessid,		    /* SIOCGIWESSID  */
3155	(iw_handler) rt_ioctl_siwnickn,		    /* SIOCSIWNICKN  */
3156	(iw_handler) rt_ioctl_giwnickn,		    /* SIOCGIWNICKN  */
3157	(iw_handler) NULL,				        /* -- hole --    */
3158	(iw_handler) NULL,				        /* -- hole --    */
3159	(iw_handler) rt_ioctl_siwrate,          /* SIOCSIWRATE   */
3160	(iw_handler) rt_ioctl_giwrate,          /* SIOCGIWRATE   */
3161	(iw_handler) rt_ioctl_siwrts,		    /* SIOCSIWRTS    */
3162	(iw_handler) rt_ioctl_giwrts,		    /* SIOCGIWRTS    */
3163	(iw_handler) rt_ioctl_siwfrag,		    /* SIOCSIWFRAG   */
3164	(iw_handler) rt_ioctl_giwfrag,		    /* SIOCGIWFRAG   */
3165	(iw_handler) NULL,		                /* SIOCSIWTXPOW  */
3166	(iw_handler) NULL,		                /* SIOCGIWTXPOW  */
3167	(iw_handler) NULL,		                /* SIOCSIWRETRY  */
3168	(iw_handler) NULL,		                /* SIOCGIWRETRY  */
3169	(iw_handler) rt_ioctl_siwencode,		/* SIOCSIWENCODE */
3170	(iw_handler) rt_ioctl_giwencode,		/* SIOCGIWENCODE */
3171	(iw_handler) NULL,		                /* SIOCSIWPOWER  */
3172	(iw_handler) NULL,		                /* SIOCGIWPOWER  */
3173	(iw_handler) NULL,						/* -- hole -- */
3174	(iw_handler) NULL,						/* -- hole -- */
3175#if WIRELESS_EXT > 17
3176    (iw_handler) rt_ioctl_siwgenie,         /* SIOCSIWGENIE  */
3177	(iw_handler) rt_ioctl_giwgenie,         /* SIOCGIWGENIE  */
3178	(iw_handler) rt_ioctl_siwauth,		    /* SIOCSIWAUTH   */
3179	(iw_handler) rt_ioctl_giwauth,		    /* SIOCGIWAUTH   */
3180	(iw_handler) rt_ioctl_siwencodeext,	    /* SIOCSIWENCODEEXT */
3181	(iw_handler) rt_ioctl_giwencodeext,		/* SIOCGIWENCODEEXT */
3182	(iw_handler) rt_ioctl_siwpmksa,         /* SIOCSIWPMKSA  */
3183#endif
3184};
3185
3186static const iw_handler rt_priv_handlers[] = {
3187	(iw_handler) NULL, /* + 0x00 */
3188	(iw_handler) NULL, /* + 0x01 */
3189#ifndef CONFIG_AP_SUPPORT
3190	(iw_handler) rt_ioctl_setparam, /* + 0x02 */
3191#else
3192	(iw_handler) NULL, /* + 0x02 */
3193#endif // CONFIG_AP_SUPPORT //
3194#ifdef DBG
3195	(iw_handler) rt_private_ioctl_bbp, /* + 0x03 */
3196#else
3197	(iw_handler) NULL, /* + 0x03 */
3198#endif
3199	(iw_handler) NULL, /* + 0x04 */
3200	(iw_handler) NULL, /* + 0x05 */
3201	(iw_handler) NULL, /* + 0x06 */
3202	(iw_handler) NULL, /* + 0x07 */
3203	(iw_handler) NULL, /* + 0x08 */
3204	(iw_handler) rt_private_get_statistics, /* + 0x09 */
3205	(iw_handler) NULL, /* + 0x0A */
3206	(iw_handler) NULL, /* + 0x0B */
3207	(iw_handler) NULL, /* + 0x0C */
3208	(iw_handler) NULL, /* + 0x0D */
3209	(iw_handler) NULL, /* + 0x0E */
3210	(iw_handler) NULL, /* + 0x0F */
3211	(iw_handler) NULL, /* + 0x10 */
3212	(iw_handler) rt_private_show, /* + 0x11 */
3213    (iw_handler) NULL, /* + 0x12 */
3214	(iw_handler) NULL, /* + 0x13 */
3215	(iw_handler) NULL, /* + 0x15 */
3216	(iw_handler) NULL, /* + 0x17 */
3217	(iw_handler) NULL, /* + 0x18 */
3218};
3219
3220const struct iw_handler_def rt28xx_iw_handler_def =
3221{
3222#define	N(a)	(sizeof (a) / sizeof (a[0]))
3223	.standard	= (iw_handler *) rt_handler,
3224	.num_standard	= sizeof(rt_handler) / sizeof(iw_handler),
3225	.private	= (iw_handler *) rt_priv_handlers,
3226	.num_private		= N(rt_priv_handlers),
3227	.private_args	= (struct iw_priv_args *) privtab,
3228	.num_private_args	= N(privtab),
3229#if IW_HANDLER_VERSION >= 7
3230    .get_wireless_stats = rt28xx_get_wireless_stats,
3231#endif
3232};
3233
3234INT RTMPSetInformation(
3235    IN  PRTMP_ADAPTER pAdapter,
3236    IN  OUT struct ifreq    *rq,
3237    IN  INT                 cmd)
3238{
3239    struct iwreq                        *wrq = (struct iwreq *) rq;
3240    NDIS_802_11_SSID                    Ssid;
3241    NDIS_802_11_MAC_ADDRESS             Bssid;
3242    RT_802_11_PHY_MODE                  PhyMode;
3243    RT_802_11_STA_CONFIG                StaConfig;
3244    NDIS_802_11_RATES                   aryRates;
3245    RT_802_11_PREAMBLE                  Preamble;
3246    NDIS_802_11_WEP_STATUS              WepStatus;
3247    NDIS_802_11_AUTHENTICATION_MODE     AuthMode = Ndis802_11AuthModeMax;
3248    NDIS_802_11_NETWORK_INFRASTRUCTURE  BssType;
3249    NDIS_802_11_RTS_THRESHOLD           RtsThresh;
3250    NDIS_802_11_FRAGMENTATION_THRESHOLD FragThresh;
3251    NDIS_802_11_POWER_MODE              PowerMode;
3252    PNDIS_802_11_KEY                    pKey = NULL;
3253    PNDIS_802_11_WEP			        pWepKey =NULL;
3254    PNDIS_802_11_REMOVE_KEY             pRemoveKey = NULL;
3255    NDIS_802_11_CONFIGURATION           Config, *pConfig = NULL;
3256    NDIS_802_11_NETWORK_TYPE            NetType;
3257    ULONG                               Now;
3258    UINT                                KeyIdx = 0;
3259    INT                                 Status = NDIS_STATUS_SUCCESS, MaxPhyMode = PHY_11G;
3260    ULONG                               PowerTemp;
3261    BOOLEAN                             RadioState;
3262    BOOLEAN                             StateMachineTouched = FALSE;
3263#ifdef DOT11_N_SUPPORT
3264	OID_SET_HT_PHYMODE					HT_PhyMode;	//11n ,kathy
3265#endif // DOT11_N_SUPPORT //
3266#ifdef WPA_SUPPLICANT_SUPPORT
3267    PNDIS_802_11_PMKID                  pPmkId = NULL;
3268    BOOLEAN				                IEEE8021xState = FALSE;
3269    BOOLEAN				                IEEE8021x_required_keys = FALSE;
3270    UCHAR                               wpa_supplicant_enable = 0;
3271#endif // WPA_SUPPLICANT_SUPPORT //
3272
3273#ifdef SNMP_SUPPORT
3274	TX_RTY_CFG_STRUC			tx_rty_cfg;
3275	ULONG						ShortRetryLimit, LongRetryLimit;
3276	UCHAR						ctmp;
3277#endif // SNMP_SUPPORT //
3278
3279
3280
3281#ifdef DOT11_N_SUPPORT
3282	MaxPhyMode = PHY_11N_5G;
3283#endif // DOT11_N_SUPPORT //
3284
3285
3286	DBGPRINT(RT_DEBUG_TRACE, ("-->RTMPSetInformation(),	0x%08x\n", cmd&0x7FFF));
3287    switch(cmd & 0x7FFF) {
3288        case RT_OID_802_11_COUNTRY_REGION:
3289            if (wrq->u.data.length < sizeof(UCHAR))
3290                Status = -EINVAL;
3291			// Only avaliable when EEPROM not programming
3292            else if (!(pAdapter->CommonCfg.CountryRegion & 0x80) && !(pAdapter->CommonCfg.CountryRegionForABand & 0x80))
3293            {
3294                ULONG   Country;
3295                UCHAR	TmpPhy;
3296
3297				Status = copy_from_user(&Country, wrq->u.data.pointer, wrq->u.data.length);
3298				pAdapter->CommonCfg.CountryRegion = (UCHAR)(Country & 0x000000FF);
3299				pAdapter->CommonCfg.CountryRegionForABand = (UCHAR)((Country >> 8) & 0x000000FF);
3300                TmpPhy = pAdapter->CommonCfg.PhyMode;
3301				pAdapter->CommonCfg.PhyMode = 0xff;
3302				// Build all corresponding channel information
3303				RTMPSetPhyMode(pAdapter, TmpPhy);
3304#ifdef DOT11_N_SUPPORT
3305				SetCommonHT(pAdapter);
3306#endif // DOT11_N_SUPPORT //
3307				DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_COUNTRY_REGION (A:%d  B/G:%d)\n", pAdapter->CommonCfg.CountryRegionForABand,
3308				    pAdapter->CommonCfg.CountryRegion));
3309            }
3310            break;
3311        case OID_802_11_BSSID_LIST_SCAN:
3312 #ifdef RALINK_ATE
3313			if (ATE_ON(pAdapter))
3314			{
3315				DBGPRINT(RT_DEBUG_TRACE, ("The driver is in ATE mode now\n"));
3316				break;
3317			}
3318#endif // RALINK_ATE //
3319            Now = jiffies;
3320			DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_BSSID_LIST_SCAN, TxCnt = %d \n", pAdapter->RalinkCounters.LastOneSecTotalTxCount));
3321
3322            if (MONITOR_ON(pAdapter))
3323            {
3324                DBGPRINT(RT_DEBUG_TRACE, ("!!! Driver is in Monitor Mode now !!!\n"));
3325                break;
3326            }
3327
3328			//Benson add 20080527, when radio off, sta don't need to scan
3329			if (RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_RADIO_OFF))
3330				break;
3331
3332			if (RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
3333			{
3334                DBGPRINT(RT_DEBUG_TRACE, ("!!! Driver is scanning now !!!\n"));
3335				pAdapter->StaCfg.bScanReqIsFromWebUI = TRUE;
3336				Status = NDIS_STATUS_SUCCESS;
3337                break;
3338            }
3339
3340			if (pAdapter->RalinkCounters.LastOneSecTotalTxCount > 100)
3341            {
3342                DBGPRINT(RT_DEBUG_TRACE, ("!!! Link UP, ignore this set::OID_802_11_BSSID_LIST_SCAN\n"));
3343				Status = NDIS_STATUS_SUCCESS;
3344				pAdapter->StaCfg.ScanCnt = 99;		// Prevent auto scan triggered by this OID
3345				break;
3346            }
3347
3348            if ((OPSTATUS_TEST_FLAG(pAdapter, fOP_STATUS_MEDIA_STATE_CONNECTED)) &&
3349				((pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPA) ||
3350				(pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
3351				(pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) ||
3352				(pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)) &&
3353                (pAdapter->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED))
3354            {
3355                DBGPRINT(RT_DEBUG_TRACE, ("!!! Link UP, Port Not Secured! ignore this set::OID_802_11_BSSID_LIST_SCAN\n"));
3356				Status = NDIS_STATUS_SUCCESS;
3357				pAdapter->StaCfg.ScanCnt = 99;		// Prevent auto scan triggered by this OID
3358				break;
3359            }
3360
3361
3362            if (pAdapter->Mlme.CntlMachine.CurrState != CNTL_IDLE)
3363            {
3364                RT28XX_MLME_RESET_STATE_MACHINE(pAdapter);
3365                DBGPRINT(RT_DEBUG_TRACE, ("!!! MLME busy, reset MLME state machine !!!\n"));
3366            }
3367
3368            // tell CNTL state machine to call NdisMSetInformationComplete() after completing
3369            // this request, because this request is initiated by NDIS.
3370            pAdapter->MlmeAux.CurrReqIsFromNdis = FALSE;
3371            // Reset allowed scan retries
3372            pAdapter->StaCfg.ScanCnt = 0;
3373            pAdapter->StaCfg.LastScanTime = Now;
3374
3375			pAdapter->StaCfg.bScanReqIsFromWebUI = TRUE;
3376            RTMP_SET_FLAG(pAdapter, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
3377            MlmeEnqueue(pAdapter,
3378                        MLME_CNTL_STATE_MACHINE,
3379                        OID_802_11_BSSID_LIST_SCAN,
3380                        0,
3381                        NULL);
3382
3383            Status = NDIS_STATUS_SUCCESS;
3384            StateMachineTouched = TRUE;
3385            break;
3386        case OID_802_11_SSID:
3387            if (wrq->u.data.length != sizeof(NDIS_802_11_SSID))
3388                Status = -EINVAL;
3389            else
3390            {
3391            	PCHAR pSsidString = NULL;
3392                Status = copy_from_user(&Ssid, wrq->u.data.pointer, wrq->u.data.length);
3393
3394				DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_SSID (Len=%d,Ssid=%s)\n", Ssid.SsidLength, Ssid.Ssid));
3395                if (Ssid.SsidLength > MAX_LEN_OF_SSID)
3396                    Status = -EINVAL;
3397                else
3398                {
3399                	if (Ssid.SsidLength == 0)
3400                	{
3401                		Set_SSID_Proc(pAdapter, "");
3402                	}
3403					else
3404                	{
3405	                	pSsidString = (CHAR *) kmalloc(MAX_LEN_OF_SSID+1, MEM_ALLOC_FLAG);
3406						if (pSsidString)
3407						{
3408							NdisZeroMemory(pSsidString, MAX_LEN_OF_SSID+1);
3409							NdisMoveMemory(pSsidString, Ssid.Ssid, Ssid.SsidLength);
3410	                		Set_SSID_Proc(pAdapter, pSsidString);
3411							kfree(pSsidString);
3412						}
3413						else
3414							Status = -ENOMEM;
3415                	}
3416                }
3417            }
3418            break;
3419        case OID_802_11_BSSID:
3420#ifdef RALINK_ATE
3421			if (ATE_ON(pAdapter))
3422			{
3423				DBGPRINT(RT_DEBUG_TRACE, ("The driver is in ATE mode now\n"));
3424				break;
3425			}
3426#endif // RALINK_ATE //
3427            if (wrq->u.data.length != sizeof(NDIS_802_11_MAC_ADDRESS))
3428                Status  = -EINVAL;
3429            else
3430            {
3431                Status = copy_from_user(&Bssid, wrq->u.data.pointer, wrq->u.data.length);
3432
3433                // tell CNTL state machine to call NdisMSetInformationComplete() after completing
3434                // this request, because this request is initiated by NDIS.
3435                pAdapter->MlmeAux.CurrReqIsFromNdis = FALSE;
3436
3437				// Prevent to connect AP again in STAMlmePeriodicExec
3438				pAdapter->MlmeAux.AutoReconnectSsidLen= 32;
3439
3440                // Reset allowed scan retries
3441				pAdapter->StaCfg.ScanCnt = 0;
3442
3443                if (pAdapter->Mlme.CntlMachine.CurrState != CNTL_IDLE)
3444                {
3445                    RT28XX_MLME_RESET_STATE_MACHINE(pAdapter);
3446                    DBGPRINT(RT_DEBUG_TRACE, ("!!! MLME busy, reset MLME state machine !!!\n"));
3447                }
3448                MlmeEnqueue(pAdapter,
3449                            MLME_CNTL_STATE_MACHINE,
3450                            OID_802_11_BSSID,
3451                            sizeof(NDIS_802_11_MAC_ADDRESS),
3452                            (VOID *)&Bssid);
3453                Status = NDIS_STATUS_SUCCESS;
3454                StateMachineTouched = TRUE;
3455
3456                DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_BSSID %02x:%02x:%02x:%02x:%02x:%02x\n",
3457                                        Bssid[0], Bssid[1], Bssid[2], Bssid[3], Bssid[4], Bssid[5]));
3458            }
3459            break;
3460        case RT_OID_802_11_RADIO:
3461            if (wrq->u.data.length != sizeof(BOOLEAN))
3462                Status  = -EINVAL;
3463            else
3464            {
3465                Status = copy_from_user(&RadioState, wrq->u.data.pointer, wrq->u.data.length);
3466                DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_RADIO (=%d)\n", RadioState));
3467                if (pAdapter->StaCfg.bSwRadio != RadioState)
3468                {
3469                    pAdapter->StaCfg.bSwRadio = RadioState;
3470                    if (pAdapter->StaCfg.bRadio != (pAdapter->StaCfg.bHwRadio && pAdapter->StaCfg.bSwRadio))
3471                    {
3472                        pAdapter->StaCfg.bRadio = (pAdapter->StaCfg.bHwRadio && pAdapter->StaCfg.bSwRadio);
3473                        if (pAdapter->StaCfg.bRadio == TRUE)
3474                        {
3475                            MlmeRadioOn(pAdapter);
3476                            // Update extra information
3477							pAdapter->ExtraInfo = EXTRA_INFO_CLEAR;
3478                        }
3479                        else
3480                        {
3481                            MlmeRadioOff(pAdapter);
3482                            // Update extra information
3483							pAdapter->ExtraInfo = SW_RADIO_OFF;
3484                        }
3485                    }
3486                }
3487            }
3488            break;
3489        case RT_OID_802_11_PHY_MODE:
3490            if (wrq->u.data.length != sizeof(RT_802_11_PHY_MODE))
3491                Status  = -EINVAL;
3492            else
3493            {
3494                Status = copy_from_user(&PhyMode, wrq->u.data.pointer, wrq->u.data.length);
3495				if (PhyMode <= MaxPhyMode)
3496				{
3497                	RTMPSetPhyMode(pAdapter, PhyMode);
3498#ifdef DOT11_N_SUPPORT
3499					SetCommonHT(pAdapter);
3500#endif // DOT11_N_SUPPORT //
3501				}
3502                DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_PHY_MODE (=%d)\n", PhyMode));
3503            }
3504            break;
3505        case RT_OID_802_11_STA_CONFIG:
3506            if (wrq->u.data.length != sizeof(RT_802_11_STA_CONFIG))
3507                Status  = -EINVAL;
3508            else
3509            {
3510                Status = copy_from_user(&StaConfig, wrq->u.data.pointer, wrq->u.data.length);
3511                pAdapter->CommonCfg.bEnableTxBurst = StaConfig.EnableTxBurst;
3512                pAdapter->CommonCfg.UseBGProtection = StaConfig.UseBGProtection;
3513                pAdapter->CommonCfg.bUseShortSlotTime = 1; // 2003-10-30 always SHORT SLOT capable
3514                if ((pAdapter->CommonCfg.PhyMode != StaConfig.AdhocMode) &&
3515					(StaConfig.AdhocMode <= MaxPhyMode))
3516                {
3517                    // allow dynamic change of "USE OFDM rate or not" in ADHOC mode
3518                    // if setting changed, need to reset current TX rate as well as BEACON frame format
3519                    if (pAdapter->StaCfg.BssType == BSS_ADHOC)
3520                    {
3521						pAdapter->CommonCfg.PhyMode = StaConfig.AdhocMode;
3522                    	RTMPSetPhyMode(pAdapter, PhyMode);
3523                        MlmeUpdateTxRates(pAdapter, FALSE, 0);
3524                        MakeIbssBeacon(pAdapter);           // re-build BEACON frame
3525                        AsicEnableIbssSync(pAdapter);   // copy to on-chip memory
3526                    }
3527                }
3528                DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_SET_STA_CONFIG (Burst=%d, Protection=%ld,ShortSlot=%d\n",
3529                                        pAdapter->CommonCfg.bEnableTxBurst,
3530                                        pAdapter->CommonCfg.UseBGProtection,
3531                                        pAdapter->CommonCfg.bUseShortSlotTime));
3532            }
3533            break;
3534        case OID_802_11_DESIRED_RATES:
3535            if (wrq->u.data.length != sizeof(NDIS_802_11_RATES))
3536                Status  = -EINVAL;
3537            else
3538            {
3539                Status = copy_from_user(&aryRates, wrq->u.data.pointer, wrq->u.data.length);
3540                NdisZeroMemory(pAdapter->CommonCfg.DesireRate, MAX_LEN_OF_SUPPORTED_RATES);
3541                NdisMoveMemory(pAdapter->CommonCfg.DesireRate, &aryRates, sizeof(NDIS_802_11_RATES));
3542                DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_DESIRED_RATES (%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x)\n",
3543                    pAdapter->CommonCfg.DesireRate[0],pAdapter->CommonCfg.DesireRate[1],
3544                    pAdapter->CommonCfg.DesireRate[2],pAdapter->CommonCfg.DesireRate[3],
3545                    pAdapter->CommonCfg.DesireRate[4],pAdapter->CommonCfg.DesireRate[5],
3546                    pAdapter->CommonCfg.DesireRate[6],pAdapter->CommonCfg.DesireRate[7] ));
3547                // Changing DesiredRate may affect the MAX TX rate we used to TX frames out
3548                MlmeUpdateTxRates(pAdapter, FALSE, 0);
3549            }
3550            break;
3551        case RT_OID_802_11_PREAMBLE:
3552            if (wrq->u.data.length != sizeof(RT_802_11_PREAMBLE))
3553                Status  = -EINVAL;
3554            else
3555            {
3556                Status = copy_from_user(&Preamble, wrq->u.data.pointer, wrq->u.data.length);
3557                if (Preamble == Rt802_11PreambleShort)
3558                {
3559                    pAdapter->CommonCfg.TxPreamble = Preamble;
3560                    MlmeSetTxPreamble(pAdapter, Rt802_11PreambleShort);
3561                }
3562                else if ((Preamble == Rt802_11PreambleLong) || (Preamble == Rt802_11PreambleAuto))
3563                {
3564                    // if user wants AUTO, initialize to LONG here, then change according to AP's
3565                    // capability upon association.
3566                    pAdapter->CommonCfg.TxPreamble = Preamble;
3567                    MlmeSetTxPreamble(pAdapter, Rt802_11PreambleLong);
3568                }
3569                else
3570                {
3571                    Status = -EINVAL;
3572                    break;
3573                }
3574                DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_PREAMBLE (=%d)\n", Preamble));
3575            }
3576            break;
3577        case OID_802_11_WEP_STATUS:
3578            if (wrq->u.data.length != sizeof(NDIS_802_11_WEP_STATUS))
3579                Status  = -EINVAL;
3580            else
3581            {
3582                Status = copy_from_user(&WepStatus, wrq->u.data.pointer, wrq->u.data.length);
3583                // Since TKIP, AES, WEP are all supported. It should not have any invalid setting
3584                if (WepStatus <= Ndis802_11Encryption3KeyAbsent)
3585                {
3586                    if (pAdapter->StaCfg.WepStatus != WepStatus)
3587                    {
3588                        // Config has changed
3589                        pAdapter->bConfigChanged = TRUE;
3590                    }
3591                    pAdapter->StaCfg.WepStatus     = WepStatus;
3592                    pAdapter->StaCfg.OrigWepStatus = WepStatus;
3593                    pAdapter->StaCfg.PairCipher    = WepStatus;
3594                	pAdapter->StaCfg.GroupCipher   = WepStatus;
3595                }
3596                else
3597                {
3598                    Status  = -EINVAL;
3599                    break;
3600                }
3601                DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_WEP_STATUS (=%d)\n",WepStatus));
3602            }
3603            break;
3604        case OID_802_11_AUTHENTICATION_MODE:
3605            if (wrq->u.data.length != sizeof(NDIS_802_11_AUTHENTICATION_MODE))
3606                Status  = -EINVAL;
3607            else
3608            {
3609                Status = copy_from_user(&AuthMode, wrq->u.data.pointer, wrq->u.data.length);
3610                if (AuthMode > Ndis802_11AuthModeMax)
3611                {
3612                    Status  = -EINVAL;
3613                    break;
3614                }
3615                else
3616                {
3617                    if (pAdapter->StaCfg.AuthMode != AuthMode)
3618                    {
3619                        // Config has changed
3620                        pAdapter->bConfigChanged = TRUE;
3621                    }
3622                    pAdapter->StaCfg.AuthMode = AuthMode;
3623                }
3624                pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
3625                DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_AUTHENTICATION_MODE (=%d) \n",pAdapter->StaCfg.AuthMode));
3626            }
3627            break;
3628        case OID_802_11_INFRASTRUCTURE_MODE:
3629            if (wrq->u.data.length != sizeof(NDIS_802_11_NETWORK_INFRASTRUCTURE))
3630                Status  = -EINVAL;
3631            else
3632            {
3633                Status = copy_from_user(&BssType, wrq->u.data.pointer, wrq->u.data.length);
3634
3635				if (BssType == Ndis802_11IBSS)
3636					Set_NetworkType_Proc(pAdapter, "Adhoc");
3637				else if (BssType == Ndis802_11Infrastructure)
3638					Set_NetworkType_Proc(pAdapter, "Infra");
3639				else if (BssType == Ndis802_11Monitor)
3640					Set_NetworkType_Proc(pAdapter, "Monitor");
3641				else
3642				{
3643					Status  = -EINVAL;
3644					DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_INFRASTRUCTURE_MODE (unknown)\n"));
3645				}
3646			}
3647			break;
3648	 case OID_802_11_REMOVE_WEP:
3649            DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_REMOVE_WEP\n"));
3650            if (wrq->u.data.length != sizeof(NDIS_802_11_KEY_INDEX))
3651            {
3652				Status = -EINVAL;
3653            }
3654            else
3655            {
3656				KeyIdx = *(NDIS_802_11_KEY_INDEX *) wrq->u.data.pointer;
3657
3658				if (KeyIdx & 0x80000000)
3659				{
3660					// Should never set default bit when remove key
3661					Status = -EINVAL;
3662				}
3663				else
3664				{
3665					KeyIdx = KeyIdx & 0x0fffffff;
3666					if (KeyIdx >= 4){
3667						Status = -EINVAL;
3668					}
3669					else
3670					{
3671						pAdapter->SharedKey[BSS0][KeyIdx].KeyLen = 0;
3672						pAdapter->SharedKey[BSS0][KeyIdx].CipherAlg = CIPHER_NONE;
3673						AsicRemoveSharedKeyEntry(pAdapter, 0, (UCHAR)KeyIdx);
3674					}
3675				}
3676            }
3677            break;
3678        case RT_OID_802_11_RESET_COUNTERS:
3679            NdisZeroMemory(&pAdapter->WlanCounters, sizeof(COUNTER_802_11));
3680            NdisZeroMemory(&pAdapter->Counters8023, sizeof(COUNTER_802_3));
3681            NdisZeroMemory(&pAdapter->RalinkCounters, sizeof(COUNTER_RALINK));
3682            pAdapter->Counters8023.RxNoBuffer   = 0;
3683			pAdapter->Counters8023.GoodReceives = 0;
3684			pAdapter->Counters8023.RxNoBuffer   = 0;
3685#ifdef RT2870
3686			pAdapter->BulkOutComplete	= 0;
3687			pAdapter->BulkOutCompleteOther= 0;
3688			pAdapter->BulkOutCompleteCancel = 0;
3689			pAdapter->BulkOutReq = 0;
3690			pAdapter->BulkInReq= 0;
3691			pAdapter->BulkInComplete = 0;
3692			pAdapter->BulkInCompleteFail = 0;
3693#endif // RT2870 //
3694            DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_RESET_COUNTERS \n"));
3695            break;
3696        case OID_802_11_RTS_THRESHOLD:
3697            if (wrq->u.data.length != sizeof(NDIS_802_11_RTS_THRESHOLD))
3698                Status  = -EINVAL;
3699            else
3700            {
3701                Status = copy_from_user(&RtsThresh, wrq->u.data.pointer, wrq->u.data.length);
3702                if (RtsThresh > MAX_RTS_THRESHOLD)
3703                    Status  = -EINVAL;
3704                else
3705                    pAdapter->CommonCfg.RtsThreshold = (USHORT)RtsThresh;
3706            }
3707            DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_RTS_THRESHOLD (=%ld)\n",RtsThresh));
3708            break;
3709        case OID_802_11_FRAGMENTATION_THRESHOLD:
3710            if (wrq->u.data.length != sizeof(NDIS_802_11_FRAGMENTATION_THRESHOLD))
3711                Status  = -EINVAL;
3712            else
3713            {
3714                Status = copy_from_user(&FragThresh, wrq->u.data.pointer, wrq->u.data.length);
3715                pAdapter->CommonCfg.bUseZeroToDisableFragment = FALSE;
3716                if (FragThresh > MAX_FRAG_THRESHOLD || FragThresh < MIN_FRAG_THRESHOLD)
3717                {
3718                    if (FragThresh == 0)
3719                    {
3720                        pAdapter->CommonCfg.FragmentThreshold = MAX_FRAG_THRESHOLD;
3721                        pAdapter->CommonCfg.bUseZeroToDisableFragment = TRUE;
3722                    }
3723                    else
3724                        Status  = -EINVAL;
3725                }
3726                else
3727                    pAdapter->CommonCfg.FragmentThreshold = (USHORT)FragThresh;
3728            }
3729            DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_FRAGMENTATION_THRESHOLD (=%ld) \n",FragThresh));
3730            break;
3731        case OID_802_11_POWER_MODE:
3732            if (wrq->u.data.length != sizeof(NDIS_802_11_POWER_MODE))
3733                Status = -EINVAL;
3734            else
3735            {
3736                Status = copy_from_user(&PowerMode, wrq->u.data.pointer, wrq->u.data.length);
3737                if (PowerMode == Ndis802_11PowerModeCAM)
3738                	Set_PSMode_Proc(pAdapter, "CAM");
3739                else if (PowerMode == Ndis802_11PowerModeMAX_PSP)
3740                	Set_PSMode_Proc(pAdapter, "Max_PSP");
3741                else if (PowerMode == Ndis802_11PowerModeFast_PSP)
3742					Set_PSMode_Proc(pAdapter, "Fast_PSP");
3743                else if (PowerMode == Ndis802_11PowerModeLegacy_PSP)
3744					Set_PSMode_Proc(pAdapter, "Legacy_PSP");
3745                else
3746                    Status = -EINVAL;
3747            }
3748            DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_POWER_MODE (=%d)\n",PowerMode));
3749            break;
3750         case RT_OID_802_11_TX_POWER_LEVEL_1:
3751			if (wrq->u.data.length  < sizeof(ULONG))
3752				Status = -EINVAL;
3753			else
3754			{
3755				Status = copy_from_user(&PowerTemp, wrq->u.data.pointer, wrq->u.data.length);
3756				if (PowerTemp > 100)
3757					PowerTemp = 0xffffffff;  // AUTO
3758				pAdapter->CommonCfg.TxPowerDefault = PowerTemp; //keep current setting.
3759					pAdapter->CommonCfg.TxPowerPercentage = pAdapter->CommonCfg.TxPowerDefault;
3760                DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_TX_POWER_LEVEL_1 (=%ld)\n", pAdapter->CommonCfg.TxPowerPercentage));
3761			}
3762	        break;
3763		case OID_802_11_NETWORK_TYPE_IN_USE:
3764			if (wrq->u.data.length != sizeof(NDIS_802_11_NETWORK_TYPE))
3765				Status = -EINVAL;
3766			else
3767			{
3768				Status = copy_from_user(&NetType, wrq->u.data.pointer, wrq->u.data.length);
3769
3770				if (NetType == Ndis802_11DS)
3771					RTMPSetPhyMode(pAdapter, PHY_11B);
3772				else if (NetType == Ndis802_11OFDM24)
3773					RTMPSetPhyMode(pAdapter, PHY_11BG_MIXED);
3774				else if (NetType == Ndis802_11OFDM5)
3775					RTMPSetPhyMode(pAdapter, PHY_11A);
3776				else
3777					Status = -EINVAL;
3778#ifdef DOT11_N_SUPPORT
3779				if (Status == NDIS_STATUS_SUCCESS)
3780					SetCommonHT(pAdapter);
3781#endif // DOT11_N_SUPPORT //
3782                DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_NETWORK_TYPE_IN_USE (=%d)\n",NetType));
3783		    }
3784			break;
3785        // For WPA PSK PMK key
3786        case RT_OID_802_11_ADD_WPA:
3787            pKey = kmalloc(wrq->u.data.length, MEM_ALLOC_FLAG);
3788            if(pKey == NULL)
3789            {
3790                Status = -ENOMEM;
3791                break;
3792            }
3793
3794            Status = copy_from_user(pKey, wrq->u.data.pointer, wrq->u.data.length);
3795            if (pKey->Length != wrq->u.data.length)
3796            {
3797                Status  = -EINVAL;
3798                DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_ADD_WPA, Failed!!\n"));
3799            }
3800            else
3801            {
3802                if ((pAdapter->StaCfg.AuthMode != Ndis802_11AuthModeWPAPSK) &&
3803				    (pAdapter->StaCfg.AuthMode != Ndis802_11AuthModeWPA2PSK) &&
3804				    (pAdapter->StaCfg.AuthMode != Ndis802_11AuthModeWPANone) )
3805                {
3806                    Status = -EOPNOTSUPP;
3807                    DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_ADD_WPA, Failed!! [AuthMode != WPAPSK/WPA2PSK/WPANONE]\n"));
3808                }
3809                else if ((pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
3810						 (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK) ||
3811						 (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPANone) )     // Only for WPA PSK mode
3812				{
3813                    NdisMoveMemory(pAdapter->StaCfg.PMK, &pKey->KeyMaterial, pKey->KeyLength);
3814                    // Use RaConfig as PSK agent.
3815                    // Start STA supplicant state machine
3816                    if (pAdapter->StaCfg.AuthMode != Ndis802_11AuthModeWPANone)
3817                        pAdapter->StaCfg.WpaState = SS_START;
3818
3819                    DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_ADD_WPA (id=0x%x, Len=%d-byte)\n", pKey->KeyIndex, pKey->KeyLength));
3820                }
3821                else
3822                {
3823                    pAdapter->StaCfg.WpaState = SS_NOTUSE;
3824                    DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_ADD_WPA (id=0x%x, Len=%d-byte)\n", pKey->KeyIndex, pKey->KeyLength));
3825                }
3826            }
3827            kfree(pKey);
3828            break;
3829        case OID_802_11_REMOVE_KEY:
3830            pRemoveKey = kmalloc(wrq->u.data.length, MEM_ALLOC_FLAG);
3831            if(pRemoveKey == NULL)
3832            {
3833                Status = -ENOMEM;
3834                break;
3835            }
3836
3837            Status = copy_from_user(pRemoveKey, wrq->u.data.pointer, wrq->u.data.length);
3838            if (pRemoveKey->Length != wrq->u.data.length)
3839            {
3840                Status  = -EINVAL;
3841                DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_REMOVE_KEY, Failed!!\n"));
3842            }
3843            else
3844            {
3845                if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
3846                {
3847                    RTMPWPARemoveKeyProc(pAdapter, pRemoveKey);
3848                    DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_REMOVE_KEY, Remove WPA Key!!\n"));
3849                }
3850                else
3851                {
3852                    KeyIdx = pRemoveKey->KeyIndex;
3853
3854                    if (KeyIdx & 0x80000000)
3855                    {
3856                        // Should never set default bit when remove key
3857                        Status  = -EINVAL;
3858                        DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_REMOVE_KEY, Failed!!(Should never set default bit when remove key)\n"));
3859                    }
3860                    else
3861                    {
3862                        KeyIdx = KeyIdx & 0x0fffffff;
3863                        if (KeyIdx > 3)
3864                        {
3865                            Status  = -EINVAL;
3866                            DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_REMOVE_KEY, Failed!!(KeyId[%d] out of range)\n", KeyIdx));
3867                        }
3868                        else
3869                        {
3870                            pAdapter->SharedKey[BSS0][KeyIdx].KeyLen = 0;
3871                            pAdapter->SharedKey[BSS0][KeyIdx].CipherAlg = CIPHER_NONE;
3872                            AsicRemoveSharedKeyEntry(pAdapter, 0, (UCHAR)KeyIdx);
3873                            DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_REMOVE_KEY (id=0x%x, Len=%d-byte)\n", pRemoveKey->KeyIndex, pRemoveKey->Length));
3874                        }
3875                    }
3876                }
3877            }
3878            kfree(pRemoveKey);
3879            break;
3880        // New for WPA
3881        case OID_802_11_ADD_KEY:
3882            pKey = kmalloc(wrq->u.data.length, MEM_ALLOC_FLAG);
3883            if(pKey == NULL)
3884            {
3885                Status = -ENOMEM;
3886                break;
3887            }
3888            Status = copy_from_user(pKey, wrq->u.data.pointer, wrq->u.data.length);
3889            if (pKey->Length != wrq->u.data.length)
3890            {
3891                Status  = -EINVAL;
3892                DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_ADD_KEY, Failed!!\n"));
3893            }
3894            else
3895            {
3896                RTMPAddKey(pAdapter, pKey);
3897                DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_ADD_KEY (id=0x%x, Len=%d-byte)\n", pKey->KeyIndex, pKey->KeyLength));
3898            }
3899            kfree(pKey);
3900            break;
3901        case OID_802_11_CONFIGURATION:
3902            if (wrq->u.data.length != sizeof(NDIS_802_11_CONFIGURATION))
3903                Status  = -EINVAL;
3904            else
3905            {
3906                Status = copy_from_user(&Config, wrq->u.data.pointer, wrq->u.data.length);
3907                pConfig = &Config;
3908
3909                if ((pConfig->BeaconPeriod >= 20) && (pConfig->BeaconPeriod <=400))
3910                     pAdapter->CommonCfg.BeaconPeriod = (USHORT) pConfig->BeaconPeriod;
3911
3912                pAdapter->StaActive.AtimWin = (USHORT) pConfig->ATIMWindow;
3913                MAP_KHZ_TO_CHANNEL_ID(pConfig->DSConfig, pAdapter->CommonCfg.Channel);
3914                //
3915				// Save the channel on MlmeAux for CntlOidRTBssidProc used.
3916				//
3917				pAdapter->MlmeAux.Channel = pAdapter->CommonCfg.Channel;
3918
3919                DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_CONFIGURATION (BeacnPeriod=%ld,AtimW=%ld,Ch=%d)\n",
3920                    pConfig->BeaconPeriod, pConfig->ATIMWindow, pAdapter->CommonCfg.Channel));
3921                // Config has changed
3922                pAdapter->bConfigChanged = TRUE;
3923            }
3924            break;
3925#ifdef DOT11_N_SUPPORT
3926		case RT_OID_802_11_SET_HT_PHYMODE:
3927			if (wrq->u.data.length	!= sizeof(OID_SET_HT_PHYMODE))
3928				Status = -EINVAL;
3929			else
3930			{
3931			    POID_SET_HT_PHYMODE	pHTPhyMode = &HT_PhyMode;
3932
3933				Status = copy_from_user(&HT_PhyMode, wrq->u.data.pointer, wrq->u.data.length);
3934				DBGPRINT(RT_DEBUG_TRACE, ("Set::pHTPhyMode	(PhyMode = %d,TransmitNo = %d, HtMode =	%d,	ExtOffset =	%d , MCS = %d, BW =	%d,	STBC = %d, SHORTGI = %d) \n",
3935				pHTPhyMode->PhyMode, pHTPhyMode->TransmitNo,pHTPhyMode->HtMode,pHTPhyMode->ExtOffset,
3936				pHTPhyMode->MCS, pHTPhyMode->BW, pHTPhyMode->STBC,	pHTPhyMode->SHORTGI));
3937				if (pAdapter->CommonCfg.PhyMode	>= PHY_11ABGN_MIXED)
3938					RTMPSetHT(pAdapter,	pHTPhyMode);
3939			}
3940			DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_SET_HT_PHYMODE(MCS=%d,BW=%d,SGI=%d,STBC=%d)\n",
3941				pAdapter->StaCfg.HTPhyMode.field.MCS, pAdapter->StaCfg.HTPhyMode.field.BW, pAdapter->StaCfg.HTPhyMode.field.ShortGI,
3942				pAdapter->StaCfg.HTPhyMode.field.STBC));
3943			break;
3944#endif // DOT11_N_SUPPORT //
3945		case RT_OID_802_11_SET_APSD_SETTING:
3946			if (wrq->u.data.length != sizeof(ULONG))
3947				Status = -EINVAL;
3948			else
3949			{
3950				ULONG apsd ;
3951				Status = copy_from_user(&apsd, wrq->u.data.pointer,	wrq->u.data.length);
3952
3953				/*-------------------------------------------------------------------
3954				|B31~B7	|	B6~B5	 |	 B4	 |	 B3	 |	B2	 |	B1	 |	   B0		|
3955				---------------------------------------------------------------------
3956				| Rsvd	| Max SP Len | AC_VO | AC_VI | AC_BK | AC_BE | APSD	Capable	|
3957				---------------------------------------------------------------------*/
3958				pAdapter->CommonCfg.bAPSDCapable = (apsd & 0x00000001) ? TRUE :	FALSE;
3959				pAdapter->CommonCfg.bAPSDAC_BE = ((apsd	& 0x00000002) >> 1)	? TRUE : FALSE;
3960				pAdapter->CommonCfg.bAPSDAC_BK = ((apsd	& 0x00000004) >> 2)	? TRUE : FALSE;
3961				pAdapter->CommonCfg.bAPSDAC_VI = ((apsd	& 0x00000008) >> 3)	? TRUE : FALSE;
3962				pAdapter->CommonCfg.bAPSDAC_VO = ((apsd	& 0x00000010) >> 4)	? TRUE : FALSE;
3963				pAdapter->CommonCfg.MaxSPLength	= (UCHAR)((apsd	& 0x00000060) >> 5);
3964
3965				DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_SET_APSD_SETTING (apsd=0x%lx, APSDCap=%d, [BE,BK,VI,VO]=[%d/%d/%d/%d],	MaxSPLen=%d)\n", apsd, pAdapter->CommonCfg.bAPSDCapable,
3966					pAdapter->CommonCfg.bAPSDAC_BE,	pAdapter->CommonCfg.bAPSDAC_BK,	pAdapter->CommonCfg.bAPSDAC_VI,	pAdapter->CommonCfg.bAPSDAC_VO,	pAdapter->CommonCfg.MaxSPLength));
3967			}
3968			break;
3969
3970		case RT_OID_802_11_SET_APSD_PSM:
3971			if (wrq->u.data.length	!= sizeof(ULONG))
3972				Status = -EINVAL;
3973			else
3974			{
3975				// Driver needs	to notify AP when PSM changes
3976				Status = copy_from_user(&pAdapter->CommonCfg.bAPSDForcePowerSave, wrq->u.data.pointer, wrq->u.data.length);
3977				if (pAdapter->CommonCfg.bAPSDForcePowerSave	!= pAdapter->StaCfg.Psm)
3978				{
3979					MlmeSetPsmBit(pAdapter,	pAdapter->CommonCfg.bAPSDForcePowerSave);
3980					RTMPSendNullFrame(pAdapter,	pAdapter->CommonCfg.TxRate,	TRUE);
3981				}
3982				DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_SET_APSD_PSM (bAPSDForcePowerSave:%d)\n",	pAdapter->CommonCfg.bAPSDForcePowerSave));
3983			}
3984			break;
3985#ifdef QOS_DLS_SUPPORT
3986		case RT_OID_802_11_SET_DLS:
3987			if (wrq->u.data.length != sizeof(ULONG))
3988				Status = -EINVAL;
3989			else
3990			{
3991				BOOLEAN	oldvalue = pAdapter->CommonCfg.bDLSCapable;
3992				Status = copy_from_user(&pAdapter->CommonCfg.bDLSCapable, wrq->u.data.pointer, wrq->u.data.length);
3993				if (oldvalue &&	!pAdapter->CommonCfg.bDLSCapable)
3994				{
3995					int	i;
3996					// tear	down local dls table entry
3997					for	(i=0; i<MAX_NUM_OF_INIT_DLS_ENTRY; i++)
3998					{
3999						if (pAdapter->StaCfg.DLSEntry[i].Valid && (pAdapter->StaCfg.DLSEntry[i].Status == DLS_FINISH))
4000						{
4001							pAdapter->StaCfg.DLSEntry[i].Status	= DLS_NONE;
4002							pAdapter->StaCfg.DLSEntry[i].Valid	= FALSE;
4003							RTMPSendDLSTearDownFrame(pAdapter, pAdapter->StaCfg.DLSEntry[i].MacAddr);
4004						}
4005					}
4006
4007					// tear	down peer dls table	entry
4008					for	(i=MAX_NUM_OF_INIT_DLS_ENTRY; i<MAX_NUM_OF_DLS_ENTRY; i++)
4009					{
4010						if (pAdapter->StaCfg.DLSEntry[i].Valid && (pAdapter->StaCfg.DLSEntry[i].Status == DLS_FINISH))
4011						{
4012							pAdapter->StaCfg.DLSEntry[i].Status	= DLS_NONE;
4013							pAdapter->StaCfg.DLSEntry[i].Valid	= FALSE;
4014							RTMPSendDLSTearDownFrame(pAdapter, pAdapter->StaCfg.DLSEntry[i].MacAddr);
4015						}
4016					}
4017				}
4018
4019				DBGPRINT(RT_DEBUG_TRACE,("Set::RT_OID_802_11_SET_DLS (=%d)\n", pAdapter->CommonCfg.bDLSCapable));
4020			}
4021			break;
4022
4023		case RT_OID_802_11_SET_DLS_PARAM:
4024			if (wrq->u.data.length	!= sizeof(RT_802_11_DLS_UI))
4025				Status = -EINVAL;
4026			else
4027			{
4028				RT_802_11_DLS	Dls;
4029
4030				NdisZeroMemory(&Dls, sizeof(RT_802_11_DLS));
4031				RTMPMoveMemory(&Dls, wrq->u.data.pointer, sizeof(RT_802_11_DLS_UI));
4032				MlmeEnqueue(pAdapter,
4033							MLME_CNTL_STATE_MACHINE,
4034							RT_OID_802_11_SET_DLS_PARAM,
4035							sizeof(RT_802_11_DLS),
4036							&Dls);
4037				DBGPRINT(RT_DEBUG_TRACE,("Set::RT_OID_802_11_SET_DLS_PARAM \n"));
4038			}
4039			break;
4040#endif // QOS_DLS_SUPPORT //
4041		case RT_OID_802_11_SET_WMM:
4042			if (wrq->u.data.length	!= sizeof(BOOLEAN))
4043				Status = -EINVAL;
4044			else
4045			{
4046				Status = copy_from_user(&pAdapter->CommonCfg.bWmmCapable, wrq->u.data.pointer, wrq->u.data.length);
4047				DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_SET_WMM (=%d)	\n", pAdapter->CommonCfg.bWmmCapable));
4048			}
4049			break;
4050
4051		case OID_802_11_DISASSOCIATE:
4052#ifdef RALINK_ATE
4053			if (ATE_ON(pAdapter))
4054			{
4055				DBGPRINT(RT_DEBUG_TRACE, ("The driver is in ATE mode now\n"));
4056				break;
4057			}
4058#endif // RALINK_ATE //
4059			//
4060			// Set NdisRadioStateOff to	TRUE, instead of called	MlmeRadioOff.
4061			// Later on, NDIS_802_11_BSSID_LIST_EX->NumberOfItems should be	0
4062			// when	query OID_802_11_BSSID_LIST.
4063			//
4064			// TRUE:  NumberOfItems	will set to	0.
4065			// FALSE: NumberOfItems	no change.
4066			//
4067			pAdapter->CommonCfg.NdisRadioStateOff =	TRUE;
4068			// Set to immediately send the media disconnect	event
4069			pAdapter->MlmeAux.CurrReqIsFromNdis	= TRUE;
4070			DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_DISASSOCIATE	\n"));
4071
4072			if (INFRA_ON(pAdapter))
4073			{
4074				if (pAdapter->Mlme.CntlMachine.CurrState !=	CNTL_IDLE)
4075				{
4076					RT28XX_MLME_RESET_STATE_MACHINE(pAdapter);
4077					DBGPRINT(RT_DEBUG_TRACE, ("!!! MLME	busy, reset	MLME state machine !!!\n"));
4078				}
4079
4080				MlmeEnqueue(pAdapter,
4081					MLME_CNTL_STATE_MACHINE,
4082					OID_802_11_DISASSOCIATE,
4083					0,
4084					NULL);
4085
4086				StateMachineTouched	= TRUE;
4087			}
4088			break;
4089
4090#ifdef DOT11_N_SUPPORT
4091		case RT_OID_802_11_SET_IMME_BA_CAP:
4092				if (wrq->u.data.length != sizeof(OID_BACAP_STRUC))
4093					Status = -EINVAL;
4094				else
4095				{
4096					OID_BACAP_STRUC Orde ;
4097					Status = copy_from_user(&Orde, wrq->u.data.pointer, wrq->u.data.length);
4098					if (Orde.Policy > BA_NOTUSE)
4099					{
4100						Status = NDIS_STATUS_INVALID_DATA;
4101					}
4102					else if (Orde.Policy == BA_NOTUSE)
4103					{
4104						pAdapter->CommonCfg.BACapability.field.Policy = BA_NOTUSE;
4105						pAdapter->CommonCfg.BACapability.field.MpduDensity = Orde.MpduDensity;
4106						pAdapter->CommonCfg.DesiredHtPhy.MpduDensity = Orde.MpduDensity;
4107						pAdapter->CommonCfg.DesiredHtPhy.AmsduEnable = Orde.AmsduEnable;
4108						pAdapter->CommonCfg.DesiredHtPhy.AmsduSize= Orde.AmsduSize;
4109						pAdapter->CommonCfg.DesiredHtPhy.MimoPs= Orde.MMPSmode;
4110						pAdapter->CommonCfg.BACapability.field.MMPSmode = Orde.MMPSmode;
4111						// UPdata to HT IE
4112						pAdapter->CommonCfg.HtCapability.HtCapInfo.MimoPs = Orde.MMPSmode;
4113						pAdapter->CommonCfg.HtCapability.HtCapInfo.AMsduSize = Orde.AmsduSize;
4114						pAdapter->CommonCfg.HtCapability.HtCapParm.MpduDensity = Orde.MpduDensity;
4115					}
4116					else
4117					{
4118                        pAdapter->CommonCfg.BACapability.field.AutoBA = Orde.AutoBA;
4119						pAdapter->CommonCfg.BACapability.field.Policy = IMMED_BA; // we only support immediate BA.
4120						pAdapter->CommonCfg.BACapability.field.MpduDensity = Orde.MpduDensity;
4121						pAdapter->CommonCfg.DesiredHtPhy.MpduDensity = Orde.MpduDensity;
4122						pAdapter->CommonCfg.DesiredHtPhy.AmsduEnable = Orde.AmsduEnable;
4123						pAdapter->CommonCfg.DesiredHtPhy.AmsduSize= Orde.AmsduSize;
4124						pAdapter->CommonCfg.DesiredHtPhy.MimoPs = Orde.MMPSmode;
4125						pAdapter->CommonCfg.BACapability.field.MMPSmode = Orde.MMPSmode;
4126
4127						// UPdata to HT IE
4128						pAdapter->CommonCfg.HtCapability.HtCapInfo.MimoPs = Orde.MMPSmode;
4129						pAdapter->CommonCfg.HtCapability.HtCapInfo.AMsduSize = Orde.AmsduSize;
4130						pAdapter->CommonCfg.HtCapability.HtCapParm.MpduDensity = Orde.MpduDensity;
4131
4132						if (pAdapter->CommonCfg.BACapability.field.RxBAWinLimit > MAX_RX_REORDERBUF)
4133							pAdapter->CommonCfg.BACapability.field.RxBAWinLimit = MAX_RX_REORDERBUF;
4134
4135					}
4136
4137					pAdapter->CommonCfg.REGBACapability.word = pAdapter->CommonCfg.BACapability.word;
4138					DBGPRINT(RT_DEBUG_TRACE, ("Set::(Orde.AutoBA = %d) (Policy=%d)(ReBAWinLimit=%d)(TxBAWinLimit=%d)(AutoMode=%d)\n",Orde.AutoBA, pAdapter->CommonCfg.BACapability.field.Policy,
4139						pAdapter->CommonCfg.BACapability.field.RxBAWinLimit,pAdapter->CommonCfg.BACapability.field.TxBAWinLimit, pAdapter->CommonCfg.BACapability.field.AutoBA));
4140					DBGPRINT(RT_DEBUG_TRACE, ("Set::(MimoPs = %d)(AmsduEnable = %d) (AmsduSize=%d)(MpduDensity=%d)\n",pAdapter->CommonCfg.DesiredHtPhy.MimoPs, pAdapter->CommonCfg.DesiredHtPhy.AmsduEnable,
4141						pAdapter->CommonCfg.DesiredHtPhy.AmsduSize, pAdapter->CommonCfg.DesiredHtPhy.MpduDensity));
4142				}
4143
4144				break;
4145		case RT_OID_802_11_ADD_IMME_BA:
4146			DBGPRINT(RT_DEBUG_TRACE, (" Set :: RT_OID_802_11_ADD_IMME_BA \n"));
4147			if (wrq->u.data.length != sizeof(OID_ADD_BA_ENTRY))
4148					Status = -EINVAL;
4149			else
4150			{
4151				UCHAR		        index;
4152				OID_ADD_BA_ENTRY    BA;
4153				MAC_TABLE_ENTRY     *pEntry;
4154
4155				Status = copy_from_user(&BA, wrq->u.data.pointer, wrq->u.data.length);
4156				if (BA.TID > 15)
4157				{
4158					Status = NDIS_STATUS_INVALID_DATA;
4159					break;
4160				}
4161				else
4162				{
4163					//BATableInsertEntry
4164					//As ad-hoc mode, BA pair is not limited to only BSSID. so add via OID.
4165					index = BA.TID;
4166					// in ad hoc mode, when adding BA pair, we should insert this entry into MACEntry too
4167					pEntry = MacTableLookup(pAdapter, BA.MACAddr);
4168					if (!pEntry)
4169					{
4170						DBGPRINT(RT_DEBUG_TRACE, ("RT_OID_802_11_ADD_IMME_BA. break on no connection.----:%x:%x\n", BA.MACAddr[4], BA.MACAddr[5]));
4171						break;
4172					}
4173					if (BA.IsRecipient == FALSE)
4174					{
4175					    if (pEntry->bIAmBadAtheros == TRUE)
4176							pAdapter->CommonCfg.BACapability.field.RxBAWinLimit = 0x10;
4177
4178						BAOriSessionSetUp(pAdapter, pEntry, index, 0, 100, TRUE);
4179					}
4180					else
4181					{
4182						//BATableInsertEntry(pAdapter, pEntry->Aid, BA.MACAddr, 0, 0xffff, BA.TID, BA.nMSDU, BA.IsRecipient);
4183					}
4184
4185					DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_ADD_IMME_BA. Rec = %d. Mac = %x:%x:%x:%x:%x:%x . \n",
4186						BA.IsRecipient, BA.MACAddr[0], BA.MACAddr[1], BA.MACAddr[2], BA.MACAddr[2]
4187						, BA.MACAddr[4], BA.MACAddr[5]));
4188				}
4189			}
4190			break;
4191
4192		case RT_OID_802_11_TEAR_IMME_BA:
4193			DBGPRINT(RT_DEBUG_TRACE, ("Set :: RT_OID_802_11_TEAR_IMME_BA \n"));
4194			if (wrq->u.data.length != sizeof(OID_ADD_BA_ENTRY))
4195					Status = -EINVAL;
4196			else
4197			{
4198				POID_ADD_BA_ENTRY	pBA;
4199				MAC_TABLE_ENTRY *pEntry;
4200
4201				pBA = kmalloc(wrq->u.data.length, MEM_ALLOC_FLAG);
4202
4203				if (pBA == NULL)
4204				{
4205					DBGPRINT(RT_DEBUG_TRACE, ("Set :: RT_OID_802_11_TEAR_IMME_BA kmalloc() can't allocate enough memory\n"));
4206					Status = NDIS_STATUS_FAILURE;
4207				}
4208				else
4209				{
4210					Status = copy_from_user(pBA, wrq->u.data.pointer, wrq->u.data.length);
4211					DBGPRINT(RT_DEBUG_TRACE, ("Set :: RT_OID_802_11_TEAR_IMME_BA(TID=%d, bAllTid=%d)\n", pBA->TID, pBA->bAllTid));
4212
4213					if (!pBA->bAllTid && (pBA->TID > NUM_OF_TID))
4214					{
4215						Status = NDIS_STATUS_INVALID_DATA;
4216						break;
4217					}
4218
4219					if (pBA->IsRecipient == FALSE)
4220					{
4221						pEntry = MacTableLookup(pAdapter, pBA->MACAddr);
4222						DBGPRINT(RT_DEBUG_TRACE, (" pBA->IsRecipient == FALSE\n"));
4223						if (pEntry)
4224						{
4225							DBGPRINT(RT_DEBUG_TRACE, (" pBA->pEntry\n"));
4226							BAOriSessionTearDown(pAdapter, pEntry->Aid, pBA->TID, FALSE, TRUE);
4227						}
4228						else
4229							DBGPRINT(RT_DEBUG_TRACE, ("Set :: Not found pEntry \n"));
4230					}
4231					else
4232					{
4233						pEntry = MacTableLookup(pAdapter, pBA->MACAddr);
4234						if (pEntry)
4235						{
4236							BARecSessionTearDown( pAdapter, (UCHAR)pEntry->Aid, pBA->TID, TRUE);
4237						}
4238						else
4239							DBGPRINT(RT_DEBUG_TRACE, ("Set :: Not found pEntry \n"));
4240					}
4241					kfree(pBA);
4242				}
4243            }
4244            break;
4245#endif // DOT11_N_SUPPORT //
4246
4247        // For WPA_SUPPLICANT to set static wep key
4248    	case OID_802_11_ADD_WEP:
4249    	    pWepKey = kmalloc(wrq->u.data.length, MEM_ALLOC_FLAG);
4250
4251    	    if(pWepKey == NULL)
4252            {
4253                Status = -ENOMEM;
4254				DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_ADD_WEP, Failed!!\n"));
4255                break;
4256            }
4257            Status = copy_from_user(pWepKey, wrq->u.data.pointer, wrq->u.data.length);
4258            if (Status)
4259            {
4260                Status  = -EINVAL;
4261                DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_ADD_WEP, Failed (length mismatch)!!\n"));
4262            }
4263            else
4264            {
4265		        KeyIdx = pWepKey->KeyIndex & 0x0fffffff;
4266                // KeyIdx must be 0 ~ 3
4267                if (KeyIdx > 4)
4268    			{
4269                    Status  = -EINVAL;
4270                    DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_ADD_WEP, Failed (KeyIdx must be smaller than 4)!!\n"));
4271                }
4272                else
4273                {
4274                    UCHAR CipherAlg = 0;
4275                    PUCHAR Key;
4276
4277                    // set key material and key length
4278                    NdisZeroMemory(pAdapter->SharedKey[BSS0][KeyIdx].Key, 16);
4279                    pAdapter->SharedKey[BSS0][KeyIdx].KeyLen = (UCHAR) pWepKey->KeyLength;
4280                    NdisMoveMemory(pAdapter->SharedKey[BSS0][KeyIdx].Key, &pWepKey->KeyMaterial, pWepKey->KeyLength);
4281
4282                    switch(pWepKey->KeyLength)
4283                    {
4284                        case 5:
4285                            CipherAlg = CIPHER_WEP64;
4286                            break;
4287                        case 13:
4288                            CipherAlg = CIPHER_WEP128;
4289                            break;
4290                        default:
4291                            DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_ADD_WEP, only support CIPHER_WEP64(len:5) & CIPHER_WEP128(len:13)!!\n"));
4292                            Status = -EINVAL;
4293                            break;
4294                    }
4295                    pAdapter->SharedKey[BSS0][KeyIdx].CipherAlg = CipherAlg;
4296
4297                    // Default key for tx (shared key)
4298                    if (pWepKey->KeyIndex & 0x80000000)
4299                    {
4300#ifdef WPA_SUPPLICANT_SUPPORT
4301                        // set key material and key length
4302                        NdisZeroMemory(pAdapter->StaCfg.DesireSharedKey[KeyIdx].Key, 16);
4303                        pAdapter->StaCfg.DesireSharedKey[KeyIdx].KeyLen = (UCHAR) pWepKey->KeyLength;
4304                        NdisMoveMemory(pAdapter->StaCfg.DesireSharedKey[KeyIdx].Key, &pWepKey->KeyMaterial, pWepKey->KeyLength);
4305                        pAdapter->StaCfg.DesireSharedKeyId = KeyIdx;
4306                        pAdapter->StaCfg.DesireSharedKey[KeyIdx].CipherAlg = CipherAlg;
4307#endif // WPA_SUPPLICANT_SUPPORT //
4308                        pAdapter->StaCfg.DefaultKeyId = (UCHAR) KeyIdx;
4309                    }
4310
4311#ifdef WPA_SUPPLICANT_SUPPORT
4312                    if (pAdapter->StaCfg.PortSecured == WPA_802_1X_PORT_SECURED)
4313#endif // WPA_SUPPLICANT_SUPPORT
4314                    {
4315                        Key = pAdapter->SharedKey[BSS0][KeyIdx].Key;
4316
4317                        // Set key material and cipherAlg to Asic
4318        				AsicAddSharedKeyEntry(pAdapter, BSS0, KeyIdx, CipherAlg, Key, NULL, NULL);
4319
4320                        if (pWepKey->KeyIndex & 0x80000000)
4321                        {
4322                            PMAC_TABLE_ENTRY pEntry = &pAdapter->MacTab.Content[BSSID_WCID];
4323                            // Assign group key info
4324    						RTMPAddWcidAttributeEntry(pAdapter, BSS0, KeyIdx, CipherAlg, NULL);
4325    						// Assign pairwise key info
4326    						RTMPAddWcidAttributeEntry(pAdapter, BSS0, KeyIdx, CipherAlg, pEntry);
4327                        }
4328                    }
4329					DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_ADD_WEP (id=0x%x, Len=%d-byte), %s\n", pWepKey->KeyIndex, pWepKey->KeyLength, (pAdapter->StaCfg.PortSecured == WPA_802_1X_PORT_SECURED) ? "Port Secured":"Port NOT Secured"));
4330				}
4331            }
4332            kfree(pWepKey);
4333            break;
4334#ifdef WPA_SUPPLICANT_SUPPORT
4335	    case OID_SET_COUNTERMEASURES:
4336            if (wrq->u.data.length != sizeof(int))
4337                Status  = -EINVAL;
4338            else
4339            {
4340                int enabled = 0;
4341                Status = copy_from_user(&enabled, wrq->u.data.pointer, wrq->u.data.length);
4342                if (enabled == 1)
4343                    pAdapter->StaCfg.bBlockAssoc = TRUE;
4344                else
4345                    // WPA MIC error should block association attempt for 60 seconds
4346                    pAdapter->StaCfg.bBlockAssoc = FALSE;
4347                DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_SET_COUNTERMEASURES bBlockAssoc=%s\n", pAdapter->StaCfg.bBlockAssoc ? "TRUE":"FALSE"));
4348            }
4349	        break;
4350        case RT_OID_WPA_SUPPLICANT_SUPPORT:
4351			if (wrq->u.data.length != sizeof(UCHAR))
4352                Status  = -EINVAL;
4353            else
4354            {
4355                Status = copy_from_user(&wpa_supplicant_enable, wrq->u.data.pointer, wrq->u.data.length);
4356    			pAdapter->StaCfg.WpaSupplicantUP = wpa_supplicant_enable;
4357    			DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_WPA_SUPPLICANT_SUPPORT (=%d)\n", pAdapter->StaCfg.WpaSupplicantUP));
4358			}
4359            break;
4360        case OID_802_11_DEAUTHENTICATION:
4361            if (wrq->u.data.length != sizeof(MLME_DEAUTH_REQ_STRUCT))
4362                Status  = -EINVAL;
4363            else
4364            {
4365                MLME_DEAUTH_REQ_STRUCT      *pInfo;
4366				MLME_QUEUE_ELEM *MsgElem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG);
4367
4368                pInfo = (MLME_DEAUTH_REQ_STRUCT *) MsgElem->Msg;
4369                Status = copy_from_user(pInfo, wrq->u.data.pointer, wrq->u.data.length);
4370                MlmeDeauthReqAction(pAdapter, MsgElem);
4371				kfree(MsgElem);
4372
4373                if (INFRA_ON(pAdapter))
4374                {
4375                    LinkDown(pAdapter, FALSE);
4376                    pAdapter->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
4377                }
4378                DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_DEAUTHENTICATION (Reason=%d)\n", pInfo->Reason));
4379            }
4380            break;
4381        case OID_802_11_DROP_UNENCRYPTED:
4382            if (wrq->u.data.length != sizeof(int))
4383                Status  = -EINVAL;
4384            else
4385            {
4386                int enabled = 0;
4387                Status = copy_from_user(&enabled, wrq->u.data.pointer, wrq->u.data.length);
4388                if (enabled == 1)
4389                    pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
4390                else
4391                    pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
4392				NdisAcquireSpinLock(&pAdapter->MacTabLock);
4393				pAdapter->MacTab.Content[BSSID_WCID].PortSecured = pAdapter->StaCfg.PortSecured;
4394				NdisReleaseSpinLock(&pAdapter->MacTabLock);
4395                DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_DROP_UNENCRYPTED (=%d)\n", enabled));
4396            }
4397            break;
4398        case OID_802_11_SET_IEEE8021X:
4399            if (wrq->u.data.length != sizeof(BOOLEAN))
4400                Status  = -EINVAL;
4401            else
4402            {
4403                Status = copy_from_user(&IEEE8021xState, wrq->u.data.pointer, wrq->u.data.length);
4404		        pAdapter->StaCfg.IEEE8021X = IEEE8021xState;
4405                DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_SET_IEEE8021X (=%d)\n", IEEE8021xState));
4406            }
4407            break;
4408        case OID_802_11_SET_IEEE8021X_REQUIRE_KEY:
4409			if (wrq->u.data.length != sizeof(BOOLEAN))
4410				 Status  = -EINVAL;
4411            else
4412            {
4413                Status = copy_from_user(&IEEE8021x_required_keys, wrq->u.data.pointer, wrq->u.data.length);
4414				pAdapter->StaCfg.IEEE8021x_required_keys = IEEE8021x_required_keys;
4415				DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_SET_IEEE8021X_REQUIRE_KEY (%d)\n", IEEE8021x_required_keys));
4416			}
4417			break;
4418        case OID_802_11_PMKID:
4419	        pPmkId = kmalloc(wrq->u.data.length, MEM_ALLOC_FLAG);
4420
4421	        if(pPmkId == NULL) {
4422                Status = -ENOMEM;
4423                break;
4424            }
4425            Status = copy_from_user(pPmkId, wrq->u.data.pointer, wrq->u.data.length);
4426
4427	        // check the PMKID information
4428	        if (pPmkId->BSSIDInfoCount == 0)
4429                NdisZeroMemory(pAdapter->StaCfg.SavedPMK, sizeof(BSSID_INFO)*PMKID_NO);
4430	        else
4431	        {
4432		        PBSSID_INFO	pBssIdInfo;
4433		        UINT		BssIdx;
4434		        UINT		CachedIdx;
4435
4436		        for (BssIdx = 0; BssIdx < pPmkId->BSSIDInfoCount; BssIdx++)
4437		        {
4438			        // point to the indexed BSSID_INFO structure
4439			        pBssIdInfo = (PBSSID_INFO) ((PUCHAR) pPmkId + 2 * sizeof(UINT) + BssIdx * sizeof(BSSID_INFO));
4440			        // Find the entry in the saved data base.
4441			        for (CachedIdx = 0; CachedIdx < pAdapter->StaCfg.SavedPMKNum; CachedIdx++)
4442			        {
4443				        // compare the BSSID
4444				        if (NdisEqualMemory(pBssIdInfo->BSSID, pAdapter->StaCfg.SavedPMK[CachedIdx].BSSID, sizeof(NDIS_802_11_MAC_ADDRESS)))
4445					        break;
4446			        }
4447
4448			        // Found, replace it
4449			        if (CachedIdx < PMKID_NO)
4450			        {
4451				        DBGPRINT(RT_DEBUG_OFF, ("Update OID_802_11_PMKID, idx = %d\n", CachedIdx));
4452				        NdisMoveMemory(&pAdapter->StaCfg.SavedPMK[CachedIdx], pBssIdInfo, sizeof(BSSID_INFO));
4453				        pAdapter->StaCfg.SavedPMKNum++;
4454			        }
4455			        // Not found, replace the last one
4456			        else
4457			        {
4458				        // Randomly replace one
4459				        CachedIdx = (pBssIdInfo->BSSID[5] % PMKID_NO);
4460				        DBGPRINT(RT_DEBUG_OFF, ("Update OID_802_11_PMKID, idx = %d\n", CachedIdx));
4461				        NdisMoveMemory(&pAdapter->StaCfg.SavedPMK[CachedIdx], pBssIdInfo, sizeof(BSSID_INFO));
4462			        }
4463		        }
4464			}
4465			if(pPmkId)
4466				kfree(pPmkId);
4467	        break;
4468#endif // WPA_SUPPLICANT_SUPPORT //
4469
4470
4471
4472#ifdef SNMP_SUPPORT
4473		case OID_802_11_SHORTRETRYLIMIT:
4474			if (wrq->u.data.length != sizeof(ULONG))
4475				Status = -EINVAL;
4476			else
4477			{
4478				Status = copy_from_user(&ShortRetryLimit, wrq->u.data.pointer, wrq->u.data.length);
4479				RTMP_IO_READ32(pAdapter, TX_RTY_CFG, &tx_rty_cfg.word);
4480				tx_rty_cfg.field.ShortRtyLimit = ShortRetryLimit;
4481				RTMP_IO_WRITE32(pAdapter, TX_RTY_CFG, tx_rty_cfg.word);
4482				DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_SHORTRETRYLIMIT (tx_rty_cfg.field.ShortRetryLimit=%d, ShortRetryLimit=%ld)\n", tx_rty_cfg.field.ShortRtyLimit, ShortRetryLimit));
4483			}
4484			break;
4485
4486		case OID_802_11_LONGRETRYLIMIT:
4487			DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_LONGRETRYLIMIT \n"));
4488			if (wrq->u.data.length != sizeof(ULONG))
4489				Status = -EINVAL;
4490			else
4491			{
4492				Status = copy_from_user(&LongRetryLimit, wrq->u.data.pointer, wrq->u.data.length);
4493				RTMP_IO_READ32(pAdapter, TX_RTY_CFG, &tx_rty_cfg.word);
4494				tx_rty_cfg.field.LongRtyLimit = LongRetryLimit;
4495				RTMP_IO_WRITE32(pAdapter, TX_RTY_CFG, tx_rty_cfg.word);
4496				DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_LONGRETRYLIMIT (tx_rty_cfg.field.LongRetryLimit= %d,LongRetryLimit=%ld)\n", tx_rty_cfg.field.LongRtyLimit, LongRetryLimit));
4497			}
4498			break;
4499
4500		case OID_802_11_WEPDEFAULTKEYVALUE:
4501			DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_WEPDEFAULTKEYVALUE\n"));
4502			pKey = kmalloc(wrq->u.data.length, GFP_KERNEL);
4503			Status = copy_from_user(pKey, wrq->u.data.pointer, wrq->u.data.length);
4504			//pKey = &WepKey;
4505
4506			if ( pKey->Length != wrq->u.data.length)
4507			{
4508				Status = -EINVAL;
4509				DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_WEPDEFAULTKEYVALUE, Failed!!\n"));
4510			}
4511			KeyIdx = pKey->KeyIndex & 0x0fffffff;
4512			DBGPRINT(RT_DEBUG_TRACE,("pKey->KeyIndex =%d, pKey->KeyLength=%d\n", pKey->KeyIndex, pKey->KeyLength));
4513
4514			// it is a shared key
4515			if (KeyIdx > 4)
4516				Status = -EINVAL;
4517			else
4518			{
4519				pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].KeyLen = (UCHAR) pKey->KeyLength;
4520				NdisMoveMemory(&pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].Key, &pKey->KeyMaterial, pKey->KeyLength);
4521				if (pKey->KeyIndex & 0x80000000)
4522				{
4523					// Default key for tx (shared key)
4524					pAdapter->StaCfg.DefaultKeyId = (UCHAR) KeyIdx;
4525				}
4526				//RestartAPIsRequired = TRUE;
4527			}
4528			break;
4529
4530
4531		case OID_802_11_WEPDEFAULTKEYID:
4532			DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_WEPDEFAULTKEYID \n"));
4533
4534			if (wrq->u.data.length != sizeof(UCHAR))
4535				Status = -EINVAL;
4536			else
4537				Status = copy_from_user(&pAdapter->StaCfg.DefaultKeyId, wrq->u.data.pointer, wrq->u.data.length);
4538
4539			break;
4540
4541
4542		case OID_802_11_CURRENTCHANNEL:
4543			DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_CURRENTCHANNEL \n"));
4544			if (wrq->u.data.length != sizeof(UCHAR))
4545				Status = -EINVAL;
4546			else
4547			{
4548				Status = copy_from_user(&ctmp, wrq->u.data.pointer, wrq->u.data.length);
4549				sprintf(&ctmp,"%d", ctmp);
4550				Set_Channel_Proc(pAdapter, &ctmp);
4551			}
4552			break;
4553#endif
4554
4555
4556
4557        default:
4558            DBGPRINT(RT_DEBUG_TRACE, ("Set::unknown IOCTL's subcmd = 0x%08x\n", cmd));
4559            Status = -EOPNOTSUPP;
4560            break;
4561    }
4562
4563
4564    return Status;
4565}
4566
4567INT RTMPQueryInformation(
4568    IN  PRTMP_ADAPTER pAdapter,
4569    IN  OUT struct ifreq    *rq,
4570    IN  INT                 cmd)
4571{
4572    struct iwreq                        *wrq = (struct iwreq *) rq;
4573    NDIS_802_11_BSSID_LIST_EX           *pBssidList = NULL;
4574    PNDIS_WLAN_BSSID_EX                 pBss;
4575    NDIS_802_11_SSID                    Ssid;
4576    NDIS_802_11_CONFIGURATION           *pConfiguration = NULL;
4577    RT_802_11_LINK_STATUS               *pLinkStatus = NULL;
4578    RT_802_11_STA_CONFIG                *pStaConfig = NULL;
4579    NDIS_802_11_STATISTICS              *pStatistics = NULL;
4580    NDIS_802_11_RTS_THRESHOLD           RtsThresh;
4581    NDIS_802_11_FRAGMENTATION_THRESHOLD FragThresh;
4582    NDIS_802_11_POWER_MODE              PowerMode;
4583    NDIS_802_11_NETWORK_INFRASTRUCTURE  BssType;
4584    RT_802_11_PREAMBLE                  PreamType;
4585    NDIS_802_11_AUTHENTICATION_MODE     AuthMode;
4586    NDIS_802_11_WEP_STATUS              WepStatus;
4587    NDIS_MEDIA_STATE                    MediaState;
4588    ULONG                               BssBufSize, ulInfo=0, NetworkTypeList[4], apsd = 0;
4589    USHORT                              BssLen = 0;
4590    PUCHAR                              pBuf = NULL, pPtr;
4591    INT                                 Status = NDIS_STATUS_SUCCESS;
4592    UINT                                we_version_compiled;
4593    UCHAR                               i, Padding = 0;
4594    BOOLEAN                             RadioState;
4595	UCHAR	driverVersion[8];
4596    OID_SET_HT_PHYMODE			        *pHTPhyMode = NULL;
4597
4598
4599#ifdef SNMP_SUPPORT
4600	//for snmp, kathy
4601	DefaultKeyIdxValue			*pKeyIdxValue;
4602	INT							valueLen;
4603	TX_RTY_CFG_STRUC			tx_rty_cfg;
4604	ULONG						ShortRetryLimit, LongRetryLimit;
4605	UCHAR						tmp[64];
4606#endif //SNMP
4607
4608    switch(cmd)
4609    {
4610        case RT_OID_DEVICE_NAME:
4611            wrq->u.data.length = sizeof(STA_NIC_DEVICE_NAME);
4612            Status = copy_to_user(wrq->u.data.pointer, STA_NIC_DEVICE_NAME, wrq->u.data.length);
4613            break;
4614        case RT_OID_VERSION_INFO:
4615			DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_VERSION_INFO \n"));
4616			wrq->u.data.length = 8*sizeof(UCHAR);
4617			sprintf(&driverVersion[0], "%s", STA_DRIVER_VERSION);
4618			driverVersion[7] = '\0';
4619			if (copy_to_user(wrq->u.data.pointer, &driverVersion, wrq->u.data.length))
4620            {
4621				Status = -EFAULT;
4622            }
4623            break;
4624#ifdef RALINK_ATE
4625		case RT_QUERY_ATE_TXDONE_COUNT:
4626			DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_QUERY_ATE_TXDONE_COUNT \n"));
4627			wrq->u.data.length = sizeof(UINT32);
4628			if (copy_to_user(wrq->u.data.pointer, &pAdapter->ate.TxDoneCount, wrq->u.data.length))
4629			{
4630				Status = -EFAULT;
4631			}
4632			break;
4633#endif // RALINK_ATE //
4634        case OID_802_11_BSSID_LIST:
4635            if (RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
4636            {
4637            	/*
4638            	 * Still scanning, indicate the caller should try again.
4639            	 */
4640            	DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_BSSID_LIST (Still scanning)\n"));
4641				return -EAGAIN;
4642            }
4643            DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_BSSID_LIST (%d BSS returned)\n",pAdapter->ScanTab.BssNr));
4644			pAdapter->StaCfg.bScanReqIsFromWebUI = FALSE;
4645            // Claculate total buffer size required
4646            BssBufSize = sizeof(ULONG);
4647
4648            for (i = 0; i < pAdapter->ScanTab.BssNr; i++)
4649            {
4650                // Align pointer to 4 bytes boundary.
4651                //Padding = 4 - (pAdapter->ScanTab.BssEntry[i].VarIELen & 0x0003);
4652                //if (Padding == 4)
4653                //    Padding = 0;
4654                BssBufSize += (sizeof(NDIS_WLAN_BSSID_EX) - 1 + sizeof(NDIS_802_11_FIXED_IEs) + pAdapter->ScanTab.BssEntry[i].VarIELen + Padding);
4655            }
4656
4657            // For safety issue, we add 256 bytes just in case
4658            BssBufSize += 256;
4659            // Allocate the same size as passed from higher layer
4660            pBuf = kmalloc(BssBufSize, MEM_ALLOC_FLAG);
4661            if(pBuf == NULL)
4662            {
4663                Status = -ENOMEM;
4664                break;
4665            }
4666            // Init 802_11_BSSID_LIST_EX structure
4667            NdisZeroMemory(pBuf, BssBufSize);
4668            pBssidList = (PNDIS_802_11_BSSID_LIST_EX) pBuf;
4669            pBssidList->NumberOfItems = pAdapter->ScanTab.BssNr;
4670
4671            // Calculate total buffer length
4672            BssLen = 4; // Consist of NumberOfItems
4673            // Point to start of NDIS_WLAN_BSSID_EX
4674            // pPtr = pBuf + sizeof(ULONG);
4675            pPtr = (PUCHAR) &pBssidList->Bssid[0];
4676            for (i = 0; i < pAdapter->ScanTab.BssNr; i++)
4677            {
4678                pBss = (PNDIS_WLAN_BSSID_EX) pPtr;
4679                NdisMoveMemory(&pBss->MacAddress, &pAdapter->ScanTab.BssEntry[i].Bssid, MAC_ADDR_LEN);
4680                if ((pAdapter->ScanTab.BssEntry[i].Hidden == 1) && (pAdapter->StaCfg.bShowHiddenSSID == FALSE))
4681                {
4682                    //
4683					// We must return this SSID during 4way handshaking, otherwise Aegis will failed to parse WPA infomation
4684					// and then failed to send EAPOl farame.
4685					//
4686					if ((pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA) && (pAdapter->StaCfg.PortSecured != WPA_802_1X_PORT_SECURED))
4687					{
4688						pBss->Ssid.SsidLength = pAdapter->ScanTab.BssEntry[i].SsidLen;
4689						NdisMoveMemory(pBss->Ssid.Ssid, pAdapter->ScanTab.BssEntry[i].Ssid, pAdapter->ScanTab.BssEntry[i].SsidLen);
4690					}
4691					else
4692                    	pBss->Ssid.SsidLength = 0;
4693                }
4694                else
4695                {
4696                    pBss->Ssid.SsidLength = pAdapter->ScanTab.BssEntry[i].SsidLen;
4697                    NdisMoveMemory(pBss->Ssid.Ssid, pAdapter->ScanTab.BssEntry[i].Ssid, pAdapter->ScanTab.BssEntry[i].SsidLen);
4698                }
4699                pBss->Privacy = pAdapter->ScanTab.BssEntry[i].Privacy;
4700                pBss->Rssi = pAdapter->ScanTab.BssEntry[i].Rssi - pAdapter->BbpRssiToDbmDelta;
4701                pBss->NetworkTypeInUse = NetworkTypeInUseSanity(&pAdapter->ScanTab.BssEntry[i]);
4702                pBss->Configuration.Length = sizeof(NDIS_802_11_CONFIGURATION);
4703                pBss->Configuration.BeaconPeriod = pAdapter->ScanTab.BssEntry[i].BeaconPeriod;
4704                pBss->Configuration.ATIMWindow = pAdapter->ScanTab.BssEntry[i].AtimWin;
4705
4706                MAP_CHANNEL_ID_TO_KHZ(pAdapter->ScanTab.BssEntry[i].Channel, pBss->Configuration.DSConfig);
4707
4708                if (pAdapter->ScanTab.BssEntry[i].BssType == BSS_INFRA)
4709                    pBss->InfrastructureMode = Ndis802_11Infrastructure;
4710                else
4711                    pBss->InfrastructureMode = Ndis802_11IBSS;
4712
4713                NdisMoveMemory(pBss->SupportedRates, pAdapter->ScanTab.BssEntry[i].SupRate, pAdapter->ScanTab.BssEntry[i].SupRateLen);
4714                NdisMoveMemory(pBss->SupportedRates + pAdapter->ScanTab.BssEntry[i].SupRateLen,
4715                               pAdapter->ScanTab.BssEntry[i].ExtRate,
4716                               pAdapter->ScanTab.BssEntry[i].ExtRateLen);
4717
4718                if (pAdapter->ScanTab.BssEntry[i].VarIELen == 0)
4719                {
4720                    pBss->IELength = sizeof(NDIS_802_11_FIXED_IEs);
4721                    NdisMoveMemory(pBss->IEs, &pAdapter->ScanTab.BssEntry[i].FixIEs, sizeof(NDIS_802_11_FIXED_IEs));
4722                    pPtr = pPtr + sizeof(NDIS_WLAN_BSSID_EX) - 1 + sizeof(NDIS_802_11_FIXED_IEs);
4723                }
4724                else
4725                {
4726                    pBss->IELength = (ULONG)(sizeof(NDIS_802_11_FIXED_IEs) + pAdapter->ScanTab.BssEntry[i].VarIELen);
4727                    pPtr = pPtr + sizeof(NDIS_WLAN_BSSID_EX) - 1 + sizeof(NDIS_802_11_FIXED_IEs);
4728                    NdisMoveMemory(pBss->IEs, &pAdapter->ScanTab.BssEntry[i].FixIEs, sizeof(NDIS_802_11_FIXED_IEs));
4729                    NdisMoveMemory(pBss->IEs + sizeof(NDIS_802_11_FIXED_IEs), pAdapter->ScanTab.BssEntry[i].VarIEs, pAdapter->ScanTab.BssEntry[i].VarIELen);
4730                    pPtr += pAdapter->ScanTab.BssEntry[i].VarIELen;
4731                }
4732                pBss->Length = (ULONG)(sizeof(NDIS_WLAN_BSSID_EX) - 1 + sizeof(NDIS_802_11_FIXED_IEs) + pAdapter->ScanTab.BssEntry[i].VarIELen + Padding);
4733
4734#if WIRELESS_EXT < 17
4735                if ((BssLen + pBss->Length) < wrq->u.data.length)
4736                BssLen += pBss->Length;
4737                else
4738                {
4739                    pBssidList->NumberOfItems = i;
4740                    break;
4741                }
4742#else
4743                BssLen += pBss->Length;
4744#endif
4745            }
4746
4747#if WIRELESS_EXT < 17
4748            wrq->u.data.length = BssLen;
4749#else
4750            if (BssLen > wrq->u.data.length)
4751            {
4752                kfree(pBssidList);
4753                return -E2BIG;
4754            }
4755            else
4756                wrq->u.data.length = BssLen;
4757#endif
4758            Status = copy_to_user(wrq->u.data.pointer, pBssidList, BssLen);
4759            kfree(pBssidList);
4760            break;
4761        case OID_802_3_CURRENT_ADDRESS:
4762            wrq->u.data.length = MAC_ADDR_LEN;
4763            Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CurrentAddress, wrq->u.data.length);
4764            break;
4765        case OID_GEN_MEDIA_CONNECT_STATUS:
4766            if (pAdapter->IndicateMediaState == NdisMediaStateConnected)
4767                MediaState = NdisMediaStateConnected;
4768            else
4769                MediaState = NdisMediaStateDisconnected;
4770
4771            wrq->u.data.length = sizeof(NDIS_MEDIA_STATE);
4772            Status = copy_to_user(wrq->u.data.pointer, &MediaState, wrq->u.data.length);
4773            break;
4774        case OID_802_11_BSSID:
4775#ifdef RALINK_ATE
4776			if (ATE_ON(pAdapter))
4777			{
4778				DBGPRINT(RT_DEBUG_TRACE, ("The driver is in ATE mode now\n"));
4779				Status = NDIS_STATUS_RESOURCES;
4780				break;
4781			}
4782#endif // RALINK_ATE //
4783            if (INFRA_ON(pAdapter) || ADHOC_ON(pAdapter))
4784            {
4785                Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.Bssid, sizeof(NDIS_802_11_MAC_ADDRESS));
4786
4787            }
4788            else
4789            {
4790                DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_BSSID(=EMPTY)\n"));
4791                Status = -ENOTCONN;
4792            }
4793            break;
4794        case OID_802_11_SSID:
4795			NdisZeroMemory(&Ssid, sizeof(NDIS_802_11_SSID));
4796			NdisZeroMemory(Ssid.Ssid, MAX_LEN_OF_SSID);
4797            Ssid.SsidLength = pAdapter->CommonCfg.SsidLen;
4798			memcpy(Ssid.Ssid, pAdapter->CommonCfg.Ssid,	Ssid.SsidLength);
4799            wrq->u.data.length = sizeof(NDIS_802_11_SSID);
4800            Status = copy_to_user(wrq->u.data.pointer, &Ssid, wrq->u.data.length);
4801            DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_SSID (Len=%d, ssid=%s)\n", Ssid.SsidLength,Ssid.Ssid));
4802            break;
4803        case RT_OID_802_11_QUERY_LINK_STATUS:
4804            pLinkStatus = (RT_802_11_LINK_STATUS *) kmalloc(sizeof(RT_802_11_LINK_STATUS), MEM_ALLOC_FLAG);
4805            if (pLinkStatus)
4806            {
4807                pLinkStatus->CurrTxRate = RateIdTo500Kbps[pAdapter->CommonCfg.TxRate];   // unit : 500 kbps
4808                pLinkStatus->ChannelQuality = pAdapter->Mlme.ChannelQuality;
4809                pLinkStatus->RxByteCount = pAdapter->RalinkCounters.ReceivedByteCount;
4810                pLinkStatus->TxByteCount = pAdapter->RalinkCounters.TransmittedByteCount;
4811        		pLinkStatus->CentralChannel = pAdapter->CommonCfg.CentralChannel;
4812                wrq->u.data.length = sizeof(RT_802_11_LINK_STATUS);
4813                Status = copy_to_user(wrq->u.data.pointer, pLinkStatus, wrq->u.data.length);
4814                kfree(pLinkStatus);
4815                DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_LINK_STATUS\n"));
4816            }
4817            else
4818            {
4819                DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_LINK_STATUS(kmalloc failed)\n"));
4820                Status = -EFAULT;
4821            }
4822            break;
4823        case OID_802_11_CONFIGURATION:
4824            pConfiguration = (NDIS_802_11_CONFIGURATION *) kmalloc(sizeof(NDIS_802_11_CONFIGURATION), MEM_ALLOC_FLAG);
4825            if (pConfiguration)
4826            {
4827                pConfiguration->Length = sizeof(NDIS_802_11_CONFIGURATION);
4828                pConfiguration->BeaconPeriod = pAdapter->CommonCfg.BeaconPeriod;
4829                pConfiguration->ATIMWindow = pAdapter->StaActive.AtimWin;
4830                MAP_CHANNEL_ID_TO_KHZ(pAdapter->CommonCfg.Channel, pConfiguration->DSConfig);
4831                wrq->u.data.length = sizeof(NDIS_802_11_CONFIGURATION);
4832                Status = copy_to_user(wrq->u.data.pointer, pConfiguration, wrq->u.data.length);
4833                DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_CONFIGURATION(BeaconPeriod=%ld,AtimW=%ld,Channel=%d) \n",
4834                                        pConfiguration->BeaconPeriod, pConfiguration->ATIMWindow, pAdapter->CommonCfg.Channel));
4835				kfree(pConfiguration);
4836            }
4837            else
4838            {
4839                DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_CONFIGURATION(kmalloc failed)\n"));
4840                Status = -EFAULT;
4841            }
4842            break;
4843		case RT_OID_802_11_SNR_0:
4844			if ((pAdapter->StaCfg.LastSNR0 > 0))
4845			{
4846				ulInfo = ((0xeb	- pAdapter->StaCfg.LastSNR0) * 3) /	16 ;
4847				wrq->u.data.length = sizeof(ulInfo);
4848				Status = copy_to_user(wrq->u.data.pointer, &ulInfo,	wrq->u.data.length);
4849				DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_SNR_0(0x=%lx)\n", ulInfo));
4850			}
4851            else
4852			    Status = -EFAULT;
4853			break;
4854		case RT_OID_802_11_SNR_1:
4855			if ((pAdapter->Antenna.field.RxPath	> 1) &&
4856                (pAdapter->StaCfg.LastSNR1 > 0))
4857			{
4858				ulInfo = ((0xeb	- pAdapter->StaCfg.LastSNR1) * 3) /	16 ;
4859				wrq->u.data.length = sizeof(ulInfo);
4860				Status = copy_to_user(wrq->u.data.pointer, &ulInfo,	wrq->u.data.length);
4861				DBGPRINT(RT_DEBUG_TRACE,("Query::RT_OID_802_11_SNR_1(0x=%lx)\n",ulInfo));
4862			}
4863			else
4864				Status = -EFAULT;
4865            DBGPRINT(RT_DEBUG_TRACE,("Query::RT_OID_802_11_SNR_1(pAdapter->StaCfg.LastSNR1=%d)\n",pAdapter->StaCfg.LastSNR1));
4866			break;
4867        case OID_802_11_RSSI_TRIGGER:
4868            ulInfo = pAdapter->StaCfg.RssiSample.LastRssi0 - pAdapter->BbpRssiToDbmDelta;
4869            wrq->u.data.length = sizeof(ulInfo);
4870            Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
4871            DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_RSSI_TRIGGER(=%ld)\n", ulInfo));
4872            break;
4873		case OID_802_11_RSSI:
4874        case RT_OID_802_11_RSSI:
4875			ulInfo = pAdapter->StaCfg.RssiSample.LastRssi0;
4876			wrq->u.data.length = sizeof(ulInfo);
4877			Status = copy_to_user(wrq->u.data.pointer, &ulInfo,	wrq->u.data.length);
4878			break;
4879		case RT_OID_802_11_RSSI_1:
4880            ulInfo = pAdapter->StaCfg.RssiSample.LastRssi1;
4881			wrq->u.data.length = sizeof(ulInfo);
4882			Status = copy_to_user(wrq->u.data.pointer, &ulInfo,	wrq->u.data.length);
4883			break;
4884        case RT_OID_802_11_RSSI_2:
4885            ulInfo = pAdapter->StaCfg.RssiSample.LastRssi2;
4886			wrq->u.data.length = sizeof(ulInfo);
4887			Status = copy_to_user(wrq->u.data.pointer, &ulInfo,	wrq->u.data.length);
4888			break;
4889        case OID_802_11_STATISTICS:
4890            pStatistics = (NDIS_802_11_STATISTICS *) kmalloc(sizeof(NDIS_802_11_STATISTICS), MEM_ALLOC_FLAG);
4891            if (pStatistics)
4892            {
4893                DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_STATISTICS \n"));
4894                // add the most up-to-date h/w raw counters into software counters
4895			    NICUpdateRawCounters(pAdapter);
4896
4897                // Sanity check for calculation of sucessful count
4898                if (pAdapter->WlanCounters.TransmittedFragmentCount.QuadPart < pAdapter->WlanCounters.RetryCount.QuadPart)
4899                    pAdapter->WlanCounters.TransmittedFragmentCount.QuadPart = pAdapter->WlanCounters.RetryCount.QuadPart;
4900
4901                pStatistics->TransmittedFragmentCount.QuadPart = pAdapter->WlanCounters.TransmittedFragmentCount.QuadPart;
4902                pStatistics->MulticastTransmittedFrameCount.QuadPart = pAdapter->WlanCounters.MulticastTransmittedFrameCount.QuadPart;
4903                pStatistics->FailedCount.QuadPart = pAdapter->WlanCounters.FailedCount.QuadPart;
4904                pStatistics->RetryCount.QuadPart = pAdapter->WlanCounters.RetryCount.QuadPart;
4905                pStatistics->MultipleRetryCount.QuadPart = pAdapter->WlanCounters.MultipleRetryCount.QuadPart;
4906                pStatistics->RTSSuccessCount.QuadPart = pAdapter->WlanCounters.RTSSuccessCount.QuadPart;
4907                pStatistics->RTSFailureCount.QuadPart = pAdapter->WlanCounters.RTSFailureCount.QuadPart;
4908                pStatistics->ACKFailureCount.QuadPart = pAdapter->WlanCounters.ACKFailureCount.QuadPart;
4909                pStatistics->FrameDuplicateCount.QuadPart = pAdapter->WlanCounters.FrameDuplicateCount.QuadPart;
4910                pStatistics->ReceivedFragmentCount.QuadPart = pAdapter->WlanCounters.ReceivedFragmentCount.QuadPart;
4911                pStatistics->MulticastReceivedFrameCount.QuadPart = pAdapter->WlanCounters.MulticastReceivedFrameCount.QuadPart;
4912#ifdef DBG
4913                pStatistics->FCSErrorCount = pAdapter->RalinkCounters.RealFcsErrCount;
4914#else
4915                pStatistics->FCSErrorCount.QuadPart = pAdapter->WlanCounters.FCSErrorCount.QuadPart;
4916                pStatistics->FrameDuplicateCount.u.LowPart = pAdapter->WlanCounters.FrameDuplicateCount.u.LowPart / 100;
4917#endif
4918                wrq->u.data.length = sizeof(NDIS_802_11_STATISTICS);
4919                Status = copy_to_user(wrq->u.data.pointer, pStatistics, wrq->u.data.length);
4920                kfree(pStatistics);
4921            }
4922            else
4923            {
4924                DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_STATISTICS(kmalloc failed)\n"));
4925                Status = -EFAULT;
4926            }
4927            break;
4928        case OID_GEN_RCV_OK:
4929            ulInfo = pAdapter->Counters8023.GoodReceives;
4930            wrq->u.data.length = sizeof(ulInfo);
4931            Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
4932            break;
4933        case OID_GEN_RCV_NO_BUFFER:
4934            ulInfo = pAdapter->Counters8023.RxNoBuffer;
4935            wrq->u.data.length = sizeof(ulInfo);
4936            Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
4937            break;
4938        case RT_OID_802_11_PHY_MODE:
4939            ulInfo = (ULONG)pAdapter->CommonCfg.PhyMode;
4940            wrq->u.data.length = sizeof(ulInfo);
4941            Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
4942            DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_PHY_MODE (=%ld)\n", ulInfo));
4943            break;
4944        case RT_OID_802_11_STA_CONFIG:
4945            pStaConfig = (RT_802_11_STA_CONFIG *) kmalloc(sizeof(RT_802_11_STA_CONFIG), MEM_ALLOC_FLAG);
4946            if (pStaConfig)
4947            {
4948                DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_STA_CONFIG\n"));
4949                pStaConfig->EnableTxBurst = pAdapter->CommonCfg.bEnableTxBurst;
4950                pStaConfig->EnableTurboRate = 0;
4951                pStaConfig->UseBGProtection = pAdapter->CommonCfg.UseBGProtection;
4952                pStaConfig->UseShortSlotTime = pAdapter->CommonCfg.bUseShortSlotTime;
4953                //pStaConfig->AdhocMode = pAdapter->StaCfg.AdhocMode;
4954                pStaConfig->HwRadioStatus = (pAdapter->StaCfg.bHwRadio == TRUE) ? 1 : 0;
4955                pStaConfig->Rsv1 = 0;
4956                pStaConfig->SystemErrorBitmap = pAdapter->SystemErrorBitmap;
4957                wrq->u.data.length = sizeof(RT_802_11_STA_CONFIG);
4958                Status = copy_to_user(wrq->u.data.pointer, pStaConfig, wrq->u.data.length);
4959                kfree(pStaConfig);
4960            }
4961            else
4962            {
4963                DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_STA_CONFIG(kmalloc failed)\n"));
4964                Status = -EFAULT;
4965            }
4966            break;
4967        case OID_802_11_RTS_THRESHOLD:
4968            RtsThresh = pAdapter->CommonCfg.RtsThreshold;
4969            wrq->u.data.length = sizeof(RtsThresh);
4970            Status = copy_to_user(wrq->u.data.pointer, &RtsThresh, wrq->u.data.length);
4971            DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_RTS_THRESHOLD(=%ld)\n", RtsThresh));
4972            break;
4973        case OID_802_11_FRAGMENTATION_THRESHOLD:
4974            FragThresh = pAdapter->CommonCfg.FragmentThreshold;
4975            if (pAdapter->CommonCfg.bUseZeroToDisableFragment == TRUE)
4976                FragThresh = 0;
4977            wrq->u.data.length = sizeof(FragThresh);
4978            Status = copy_to_user(wrq->u.data.pointer, &FragThresh, wrq->u.data.length);
4979            DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_FRAGMENTATION_THRESHOLD(=%ld)\n", FragThresh));
4980            break;
4981        case OID_802_11_POWER_MODE:
4982            PowerMode = pAdapter->StaCfg.WindowsPowerMode;
4983            wrq->u.data.length = sizeof(PowerMode);
4984            Status = copy_to_user(wrq->u.data.pointer, &PowerMode, wrq->u.data.length);
4985            DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_POWER_MODE(=%d)\n", PowerMode));
4986            break;
4987        case RT_OID_802_11_RADIO:
4988            RadioState = (BOOLEAN) pAdapter->StaCfg.bSwRadio;
4989            wrq->u.data.length = sizeof(RadioState);
4990            Status = copy_to_user(wrq->u.data.pointer, &RadioState, wrq->u.data.length);
4991            DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_RADIO (=%d)\n", RadioState));
4992            break;
4993        case OID_802_11_INFRASTRUCTURE_MODE:
4994            if (pAdapter->StaCfg.BssType == BSS_ADHOC)
4995                BssType = Ndis802_11IBSS;
4996            else if (pAdapter->StaCfg.BssType == BSS_INFRA)
4997                BssType = Ndis802_11Infrastructure;
4998            else if (pAdapter->StaCfg.BssType == BSS_MONITOR)
4999                BssType = Ndis802_11Monitor;
5000            else
5001                BssType = Ndis802_11AutoUnknown;
5002
5003            wrq->u.data.length = sizeof(BssType);
5004            Status = copy_to_user(wrq->u.data.pointer, &BssType, wrq->u.data.length);
5005            DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_INFRASTRUCTURE_MODE(=%d)\n", BssType));
5006            break;
5007        case RT_OID_802_11_PREAMBLE:
5008            PreamType = pAdapter->CommonCfg.TxPreamble;
5009            wrq->u.data.length = sizeof(PreamType);
5010            Status = copy_to_user(wrq->u.data.pointer, &PreamType, wrq->u.data.length);
5011            DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_PREAMBLE(=%d)\n", PreamType));
5012            break;
5013        case OID_802_11_AUTHENTICATION_MODE:
5014            AuthMode = pAdapter->StaCfg.AuthMode;
5015            wrq->u.data.length = sizeof(AuthMode);
5016            Status = copy_to_user(wrq->u.data.pointer, &AuthMode, wrq->u.data.length);
5017            DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_AUTHENTICATION_MODE(=%d)\n", AuthMode));
5018            break;
5019        case OID_802_11_WEP_STATUS:
5020            WepStatus = pAdapter->StaCfg.WepStatus;
5021            wrq->u.data.length = sizeof(WepStatus);
5022            Status = copy_to_user(wrq->u.data.pointer, &WepStatus, wrq->u.data.length);
5023            DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_WEP_STATUS(=%d)\n", WepStatus));
5024            break;
5025        case OID_802_11_TX_POWER_LEVEL:
5026			wrq->u.data.length = sizeof(ULONG);
5027			Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.TxPower, wrq->u.data.length);
5028			DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_TX_POWER_LEVEL %x\n",pAdapter->CommonCfg.TxPower));
5029			break;
5030        case RT_OID_802_11_TX_POWER_LEVEL_1:
5031            wrq->u.data.length = sizeof(ULONG);
5032            Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.TxPowerPercentage, wrq->u.data.length);
5033			DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_TX_POWER_LEVEL_1 (=%ld)\n", pAdapter->CommonCfg.TxPowerPercentage));
5034			break;
5035        case OID_802_11_NETWORK_TYPES_SUPPORTED:
5036			if ((pAdapter->RfIcType	== RFIC_2850) || (pAdapter->RfIcType ==	RFIC_2750))
5037			{
5038				NetworkTypeList[0] = 3;                 // NumberOfItems = 3
5039				NetworkTypeList[1] = Ndis802_11DS;      // NetworkType[1] = 11b
5040				NetworkTypeList[2] = Ndis802_11OFDM24;  // NetworkType[2] = 11g
5041				NetworkTypeList[3] = Ndis802_11OFDM5;   // NetworkType[3] = 11a
5042                wrq->u.data.length = 16;
5043				Status = copy_to_user(wrq->u.data.pointer, &NetworkTypeList[0], wrq->u.data.length);
5044			}
5045			else
5046			{
5047				NetworkTypeList[0] = 2;                 // NumberOfItems = 2
5048				NetworkTypeList[1] = Ndis802_11DS;      // NetworkType[1] = 11b
5049				NetworkTypeList[2] = Ndis802_11OFDM24;  // NetworkType[2] = 11g
5050			    wrq->u.data.length = 12;
5051				Status = copy_to_user(wrq->u.data.pointer, &NetworkTypeList[0], wrq->u.data.length);
5052			}
5053			DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_NETWORK_TYPES_SUPPORTED\n"));
5054				break;
5055	    case OID_802_11_NETWORK_TYPE_IN_USE:
5056            wrq->u.data.length = sizeof(ULONG);
5057			if (pAdapter->CommonCfg.PhyMode == PHY_11A)
5058				ulInfo = Ndis802_11OFDM5;
5059			else if ((pAdapter->CommonCfg.PhyMode == PHY_11BG_MIXED) || (pAdapter->CommonCfg.PhyMode == PHY_11G))
5060				ulInfo = Ndis802_11OFDM24;
5061			else
5062				ulInfo = Ndis802_11DS;
5063            Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
5064			break;
5065        case RT_OID_802_11_QUERY_LAST_RX_RATE:
5066            ulInfo = (ULONG)pAdapter->LastRxRate;
5067            wrq->u.data.length = sizeof(ulInfo);
5068			Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
5069			DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_LAST_RX_RATE (=%ld)\n", ulInfo));
5070			break;
5071		case RT_OID_802_11_QUERY_LAST_TX_RATE:
5072			//ulInfo = (ULONG)pAdapter->LastTxRate;
5073			ulInfo = (ULONG)pAdapter->MacTab.Content[BSSID_WCID].HTPhyMode.word;
5074			wrq->u.data.length = sizeof(ulInfo);
5075			Status = copy_to_user(wrq->u.data.pointer, &ulInfo,	wrq->u.data.length);
5076			DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_LAST_TX_RATE (=%lx)\n", ulInfo));
5077			break;
5078        case RT_OID_802_11_QUERY_EEPROM_VERSION:
5079            wrq->u.data.length = sizeof(ULONG);
5080            Status = copy_to_user(wrq->u.data.pointer, &pAdapter->EepromVersion, wrq->u.data.length);
5081            break;
5082        case RT_OID_802_11_QUERY_FIRMWARE_VERSION:
5083            wrq->u.data.length = sizeof(ULONG);
5084            Status = copy_to_user(wrq->u.data.pointer, &pAdapter->FirmwareVersion, wrq->u.data.length);
5085			break;
5086	    case RT_OID_802_11_QUERY_NOISE_LEVEL:
5087			wrq->u.data.length = sizeof(UCHAR);
5088			Status = copy_to_user(wrq->u.data.pointer, &pAdapter->BbpWriteLatch[66], wrq->u.data.length);
5089			DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_NOISE_LEVEL (=%d)\n", pAdapter->BbpWriteLatch[66]));
5090			break;
5091	    case RT_OID_802_11_EXTRA_INFO:
5092			wrq->u.data.length = sizeof(ULONG);
5093			Status = copy_to_user(wrq->u.data.pointer, &pAdapter->ExtraInfo, wrq->u.data.length);
5094	        DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_EXTRA_INFO (=%ld)\n", pAdapter->ExtraInfo));
5095	        break;
5096	    case RT_OID_WE_VERSION_COMPILED:
5097	        wrq->u.data.length = sizeof(UINT);
5098	        we_version_compiled = WIRELESS_EXT;
5099	        Status = copy_to_user(wrq->u.data.pointer, &we_version_compiled, wrq->u.data.length);
5100	        break;
5101		case RT_OID_802_11_QUERY_APSD_SETTING:
5102			apsd = (pAdapter->CommonCfg.bAPSDCapable | (pAdapter->CommonCfg.bAPSDAC_BE << 1) | (pAdapter->CommonCfg.bAPSDAC_BK << 2)
5103				| (pAdapter->CommonCfg.bAPSDAC_VI << 3)	| (pAdapter->CommonCfg.bAPSDAC_VO << 4)	| (pAdapter->CommonCfg.MaxSPLength << 5));
5104
5105			wrq->u.data.length = sizeof(ULONG);
5106			Status = copy_to_user(wrq->u.data.pointer, &apsd, wrq->u.data.length);
5107			DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_APSD_SETTING (=0x%lx,APSDCap=%d,AC_BE=%d,AC_BK=%d,AC_VI=%d,AC_VO=%d,MAXSPLen=%d)\n",
5108				apsd,pAdapter->CommonCfg.bAPSDCapable,pAdapter->CommonCfg.bAPSDAC_BE,pAdapter->CommonCfg.bAPSDAC_BK,pAdapter->CommonCfg.bAPSDAC_VI,pAdapter->CommonCfg.bAPSDAC_VO,pAdapter->CommonCfg.MaxSPLength));
5109			break;
5110		case RT_OID_802_11_QUERY_APSD_PSM:
5111			wrq->u.data.length = sizeof(ULONG);
5112			Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.bAPSDForcePowerSave, wrq->u.data.length);
5113			DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_APSD_PSM (=%d)\n", pAdapter->CommonCfg.bAPSDForcePowerSave));
5114			break;
5115		case RT_OID_802_11_QUERY_WMM:
5116			wrq->u.data.length = sizeof(BOOLEAN);
5117			Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.bWmmCapable, wrq->u.data.length);
5118			DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_WMM (=%d)\n",	pAdapter->CommonCfg.bWmmCapable));
5119			break;
5120#ifdef WPA_SUPPLICANT_SUPPORT
5121        case RT_OID_NEW_DRIVER:
5122            {
5123                UCHAR enabled = 1;
5124    	        wrq->u.data.length = sizeof(UCHAR);
5125    	        Status = copy_to_user(wrq->u.data.pointer, &enabled, wrq->u.data.length);
5126                DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_NEW_DRIVER (=%d)\n", enabled));
5127            }
5128	        break;
5129        case RT_OID_WPA_SUPPLICANT_SUPPORT:
5130	        wrq->u.data.length = sizeof(UCHAR);
5131	        Status = copy_to_user(wrq->u.data.pointer, &pAdapter->StaCfg.WpaSupplicantUP, wrq->u.data.length);
5132            DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_WPA_SUPPLICANT_SUPPORT (=%d)\n", pAdapter->StaCfg.WpaSupplicantUP));
5133	        break;
5134#endif // WPA_SUPPLICANT_SUPPORT //
5135
5136        case RT_OID_DRIVER_DEVICE_NAME:
5137            DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_DRIVER_DEVICE_NAME \n"));
5138			wrq->u.data.length = 16;
5139			if (copy_to_user(wrq->u.data.pointer, pAdapter->StaCfg.dev_name, wrq->u.data.length))
5140			{
5141				Status = -EFAULT;
5142			}
5143            break;
5144        case RT_OID_802_11_QUERY_HT_PHYMODE:
5145            pHTPhyMode = (OID_SET_HT_PHYMODE *) kmalloc(sizeof(OID_SET_HT_PHYMODE), MEM_ALLOC_FLAG);
5146            if (pHTPhyMode)
5147            {
5148                pHTPhyMode->PhyMode = pAdapter->CommonCfg.PhyMode;
5149    			pHTPhyMode->HtMode = (UCHAR)pAdapter->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE;
5150    			pHTPhyMode->BW = (UCHAR)pAdapter->MacTab.Content[BSSID_WCID].HTPhyMode.field.BW;
5151    			pHTPhyMode->MCS= (UCHAR)pAdapter->MacTab.Content[BSSID_WCID].HTPhyMode.field.MCS;
5152    			pHTPhyMode->SHORTGI= (UCHAR)pAdapter->MacTab.Content[BSSID_WCID].HTPhyMode.field.ShortGI;
5153    			pHTPhyMode->STBC= (UCHAR)pAdapter->MacTab.Content[BSSID_WCID].HTPhyMode.field.STBC;
5154
5155    			pHTPhyMode->ExtOffset = ((pAdapter->CommonCfg.CentralChannel < pAdapter->CommonCfg.Channel) ? (EXTCHA_BELOW) : (EXTCHA_ABOVE));
5156                wrq->u.data.length = sizeof(OID_SET_HT_PHYMODE);
5157                if (copy_to_user(wrq->u.data.pointer, pHTPhyMode, wrq->u.data.length))
5158    			{
5159    				Status = -EFAULT;
5160    			}
5161    			DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_HT_PHYMODE (PhyMode = %d, MCS =%d, BW = %d, STBC = %d, ExtOffset=%d)\n",
5162    				pHTPhyMode->HtMode, pHTPhyMode->MCS, pHTPhyMode->BW, pHTPhyMode->STBC, pHTPhyMode->ExtOffset));
5163    			DBGPRINT(RT_DEBUG_TRACE, (" MlmeUpdateTxRates (.word = %x )\n", pAdapter->MacTab.Content[BSSID_WCID].HTPhyMode.word));
5164            }
5165            else
5166            {
5167                DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_STA_CONFIG(kmalloc failed)\n"));
5168                Status = -EFAULT;
5169            }
5170            break;
5171        case RT_OID_802_11_COUNTRY_REGION:
5172            DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_COUNTRY_REGION \n"));
5173			wrq->u.data.length = sizeof(ulInfo);
5174            ulInfo = pAdapter->CommonCfg.CountryRegionForABand;
5175            ulInfo = (ulInfo << 8)|(pAdapter->CommonCfg.CountryRegion);
5176			if (copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length))
5177            {
5178				Status = -EFAULT;
5179            }
5180            break;
5181        case RT_OID_802_11_QUERY_DAT_HT_PHYMODE:
5182            pHTPhyMode = (OID_SET_HT_PHYMODE *) kmalloc(sizeof(OID_SET_HT_PHYMODE), MEM_ALLOC_FLAG);
5183            if (pHTPhyMode)
5184            {
5185                pHTPhyMode->PhyMode = pAdapter->CommonCfg.PhyMode;
5186    			pHTPhyMode->HtMode = (UCHAR)pAdapter->CommonCfg.RegTransmitSetting.field.HTMODE;
5187    			pHTPhyMode->BW = (UCHAR)pAdapter->CommonCfg.RegTransmitSetting.field.BW;
5188    			pHTPhyMode->MCS= (UCHAR)pAdapter->StaCfg.DesiredTransmitSetting.field.MCS;
5189    			pHTPhyMode->SHORTGI= (UCHAR)pAdapter->CommonCfg.RegTransmitSetting.field.ShortGI;
5190    			pHTPhyMode->STBC= (UCHAR)pAdapter->CommonCfg.RegTransmitSetting.field.STBC;
5191
5192                wrq->u.data.length = sizeof(OID_SET_HT_PHYMODE);
5193                if (copy_to_user(wrq->u.data.pointer, pHTPhyMode, wrq->u.data.length))
5194    			{
5195    				Status = -EFAULT;
5196    			}
5197    			DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_HT_PHYMODE (PhyMode = %d, MCS =%d, BW = %d, STBC = %d, ExtOffset=%d)\n",
5198    				pHTPhyMode->HtMode, pHTPhyMode->MCS, pHTPhyMode->BW, pHTPhyMode->STBC, pHTPhyMode->ExtOffset));
5199    			DBGPRINT(RT_DEBUG_TRACE, (" MlmeUpdateTxRates (.word = %x )\n", pAdapter->MacTab.Content[BSSID_WCID].HTPhyMode.word));
5200            }
5201            else
5202            {
5203                DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_STA_CONFIG(kmalloc failed)\n"));
5204                Status = -EFAULT;
5205            }
5206            break;
5207        case RT_OID_QUERY_MULTIPLE_CARD_SUPPORT:
5208			wrq->u.data.length = sizeof(UCHAR);
5209            i = 0;
5210#ifdef MULTIPLE_CARD_SUPPORT
5211            i = 1;
5212#endif // MULTIPLE_CARD_SUPPORT //
5213			if (copy_to_user(wrq->u.data.pointer, &i, wrq->u.data.length))
5214            {
5215				Status = -EFAULT;
5216            }
5217            DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_QUERY_MULTIPLE_CARD_SUPPORT(=%d) \n", i));
5218            break;
5219#ifdef SNMP_SUPPORT
5220		case RT_OID_802_11_MAC_ADDRESS:
5221            wrq->u.data.length = MAC_ADDR_LEN;
5222            Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CurrentAddress, wrq->u.data.length);
5223			break;
5224
5225		case RT_OID_802_11_MANUFACTUREROUI:
5226			DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_MANUFACTUREROUI \n"));
5227			wrq->u.data.length = ManufacturerOUI_LEN;
5228			Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CurrentAddress, wrq->u.data.length);
5229			break;
5230
5231		case RT_OID_802_11_MANUFACTURERNAME:
5232			DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_MANUFACTURERNAME \n"));
5233			wrq->u.data.length = strlen(ManufacturerNAME);
5234			Status = copy_to_user(wrq->u.data.pointer, ManufacturerNAME, wrq->u.data.length);
5235			break;
5236
5237		case RT_OID_802_11_RESOURCETYPEIDNAME:
5238			DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_RESOURCETYPEIDNAME \n"));
5239			wrq->u.data.length = strlen(ResourceTypeIdName);
5240			Status = copy_to_user(wrq->u.data.pointer, ResourceTypeIdName, wrq->u.data.length);
5241			break;
5242
5243		case RT_OID_802_11_PRIVACYOPTIONIMPLEMENTED:
5244			DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_PRIVACYOPTIONIMPLEMENTED \n"));
5245			ulInfo = 1; // 1 is support wep else 2 is not support.
5246			wrq->u.data.length = sizeof(ulInfo);
5247			Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
5248			break;
5249
5250		case RT_OID_802_11_POWERMANAGEMENTMODE:
5251			DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_POWERMANAGEMENTMODE \n"));
5252			if (pAdapter->StaCfg.Psm == PSMP_ACTION)
5253				ulInfo = 1; // 1 is power active else 2 is power save.
5254			else
5255				ulInfo = 2;
5256
5257			wrq->u.data.length = sizeof(ulInfo);
5258			Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
5259			break;
5260
5261		case OID_802_11_WEPDEFAULTKEYVALUE:
5262			DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_WEPDEFAULTKEYVALUE \n"));
5263			//KeyIdxValue.KeyIdx = pAd->PortCfg.MBSSID[pAd->IoctlIF].DefaultKeyId;
5264			pKeyIdxValue = wrq->u.data.pointer;
5265			DBGPRINT(RT_DEBUG_TRACE,("KeyIdxValue.KeyIdx = %d, \n",pKeyIdxValue->KeyIdx));
5266			valueLen = pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].KeyLen;
5267			NdisMoveMemory(pKeyIdxValue->Value,
5268						   &pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].Key,
5269						   valueLen);
5270			pKeyIdxValue->Value[valueLen]='\0';
5271
5272			wrq->u.data.length = sizeof(DefaultKeyIdxValue);
5273
5274			Status = copy_to_user(wrq->u.data.pointer, pKeyIdxValue, wrq->u.data.length);
5275			DBGPRINT(RT_DEBUG_TRACE,("DefaultKeyId = %d, total len = %d, str len=%d, KeyValue= %02x %02x %02x %02x \n", pAdapter->StaCfg.DefaultKeyId, wrq->u.data.length, pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].KeyLen,
5276			pAdapter->SharedKey[BSS0][0].Key[0],
5277			pAdapter->SharedKey[BSS0][1].Key[0],
5278			pAdapter->SharedKey[BSS0][2].Key[0],
5279			pAdapter->SharedKey[BSS0][3].Key[0]));
5280			break;
5281
5282		case OID_802_11_WEPDEFAULTKEYID:
5283			DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_WEPDEFAULTKEYID \n"));
5284			wrq->u.data.length = sizeof(UCHAR);
5285			Status = copy_to_user(wrq->u.data.pointer, &pAdapter->StaCfg.DefaultKeyId, wrq->u.data.length);
5286			DBGPRINT(RT_DEBUG_TRACE, ("DefaultKeyId =%d \n", pAdapter->StaCfg.DefaultKeyId));
5287			break;
5288
5289		case RT_OID_802_11_WEPKEYMAPPINGLENGTH:
5290			DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_WEPKEYMAPPINGLENGTH \n"));
5291			wrq->u.data.length = sizeof(UCHAR);
5292			Status = copy_to_user(wrq->u.data.pointer,
5293									&pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].KeyLen,
5294									wrq->u.data.length);
5295			break;
5296
5297		case OID_802_11_SHORTRETRYLIMIT:
5298			DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_SHORTRETRYLIMIT \n"));
5299			wrq->u.data.length = sizeof(ULONG);
5300			RTMP_IO_READ32(pAdapter, TX_RTY_CFG, &tx_rty_cfg.word);
5301			ShortRetryLimit = tx_rty_cfg.field.ShortRtyLimit;
5302			DBGPRINT(RT_DEBUG_TRACE, ("ShortRetryLimit =%ld,  tx_rty_cfg.field.ShortRetryLimit=%d\n", ShortRetryLimit, tx_rty_cfg.field.ShortRtyLimit));
5303			Status = copy_to_user(wrq->u.data.pointer, &ShortRetryLimit, wrq->u.data.length);
5304			break;
5305
5306		case OID_802_11_LONGRETRYLIMIT:
5307			DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_LONGRETRYLIMIT \n"));
5308			wrq->u.data.length = sizeof(ULONG);
5309			RTMP_IO_READ32(pAdapter, TX_RTY_CFG, &tx_rty_cfg.word);
5310			LongRetryLimit = tx_rty_cfg.field.LongRtyLimit;
5311			DBGPRINT(RT_DEBUG_TRACE, ("LongRetryLimit =%ld,  tx_rty_cfg.field.LongRtyLimit=%d\n", LongRetryLimit, tx_rty_cfg.field.LongRtyLimit));
5312			Status = copy_to_user(wrq->u.data.pointer, &LongRetryLimit, wrq->u.data.length);
5313			break;
5314
5315		case RT_OID_802_11_PRODUCTID:
5316			DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_PRODUCTID \n"));
5317
5318#ifdef RT2870
5319			sprintf(tmp, "%04x %04x\n", ((POS_COOKIE)pAdapter->OS_Cookie)->pUsb_Dev->descriptor.idVendor ,((POS_COOKIE)pAdapter->OS_Cookie)->pUsb_Dev->descriptor.idProduct);
5320
5321#endif // RT2870 //
5322			wrq->u.data.length = strlen(tmp);
5323			Status = copy_to_user(wrq->u.data.pointer, tmp, wrq->u.data.length);
5324			break;
5325
5326		case RT_OID_802_11_MANUFACTUREID:
5327			DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_MANUFACTUREID \n"));
5328			wrq->u.data.length = strlen(ManufacturerNAME);
5329			Status = copy_to_user(wrq->u.data.pointer, ManufacturerNAME, wrq->u.data.length);
5330			break;
5331
5332		case OID_802_11_CURRENTCHANNEL:
5333			DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_CURRENTCHANNEL \n"));
5334			wrq->u.data.length = sizeof(UCHAR);
5335			DBGPRINT(RT_DEBUG_TRACE, ("sizeof UCHAR=%d, channel=%d \n", sizeof(UCHAR), pAdapter->CommonCfg.Channel));
5336			Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.Channel, wrq->u.data.length);
5337			DBGPRINT(RT_DEBUG_TRACE, ("Status=%d\n", Status));
5338			break;
5339#endif //SNMP_SUPPORT
5340
5341		case OID_802_11_BUILD_CHANNEL_EX:
5342			{
5343				UCHAR value;
5344				DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_BUILD_CHANNEL_EX \n"));
5345				wrq->u.data.length = sizeof(UCHAR);
5346#ifdef EXT_BUILD_CHANNEL_LIST
5347				DBGPRINT(RT_DEBUG_TRACE, ("Support EXT_BUILD_CHANNEL_LIST.\n"));
5348				value = 1;
5349#else
5350				DBGPRINT(RT_DEBUG_TRACE, ("Doesn't support EXT_BUILD_CHANNEL_LIST.\n"));
5351				value = 0;
5352#endif // EXT_BUILD_CHANNEL_LIST //
5353				Status = copy_to_user(wrq->u.data.pointer, &value, 1);
5354				DBGPRINT(RT_DEBUG_TRACE, ("Status=%d\n", Status));
5355			}
5356			break;
5357
5358		case OID_802_11_GET_CH_LIST:
5359			{
5360				PRT_CHANNEL_LIST_INFO pChListBuf;
5361
5362				DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_GET_CH_LIST \n"));
5363				if (pAdapter->ChannelListNum == 0)
5364				{
5365					wrq->u.data.length = 0;
5366					break;
5367				}
5368
5369				pChListBuf = (RT_CHANNEL_LIST_INFO *) kmalloc(sizeof(RT_CHANNEL_LIST_INFO), MEM_ALLOC_FLAG);
5370				if (pChListBuf == NULL)
5371				{
5372					wrq->u.data.length = 0;
5373					break;
5374				}
5375
5376				pChListBuf->ChannelListNum = pAdapter->ChannelListNum;
5377				for (i = 0; i < pChListBuf->ChannelListNum; i++)
5378					pChListBuf->ChannelList[i] = pAdapter->ChannelList[i].Channel;
5379
5380				wrq->u.data.length = sizeof(RT_CHANNEL_LIST_INFO);
5381				Status = copy_to_user(wrq->u.data.pointer, pChListBuf, sizeof(RT_CHANNEL_LIST_INFO));
5382				DBGPRINT(RT_DEBUG_TRACE, ("Status=%d\n", Status));
5383
5384				if (pChListBuf)
5385					kfree(pChListBuf);
5386			}
5387			break;
5388
5389		case OID_802_11_GET_COUNTRY_CODE:
5390			DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_GET_COUNTRY_CODE \n"));
5391			wrq->u.data.length = 2;
5392			Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.CountryCode, 2);
5393			DBGPRINT(RT_DEBUG_TRACE, ("Status=%d\n", Status));
5394			break;
5395
5396		case OID_802_11_GET_CHANNEL_GEOGRAPHY:
5397			DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_GET_CHANNEL_GEOGRAPHY \n"));
5398			wrq->u.data.length = 1;
5399			Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.Geography, 1);
5400			DBGPRINT(RT_DEBUG_TRACE, ("Status=%d\n", Status));
5401			break;
5402
5403
5404#ifdef QOS_DLS_SUPPORT
5405		case RT_OID_802_11_QUERY_DLS:
5406			wrq->u.data.length = sizeof(BOOLEAN);
5407			Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.bDLSCapable, wrq->u.data.length);
5408			DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_DLS(=%d)\n", pAdapter->CommonCfg.bDLSCapable));
5409			break;
5410
5411		case RT_OID_802_11_QUERY_DLS_PARAM:
5412			{
5413				PRT_802_11_DLS_INFO	pDlsInfo = kmalloc(sizeof(RT_802_11_DLS_INFO), GFP_ATOMIC);
5414				if (pDlsInfo == NULL)
5415					break;
5416
5417				for (i=0; i<MAX_NUM_OF_DLS_ENTRY; i++)
5418				{
5419					RTMPMoveMemory(&pDlsInfo->Entry[i], &pAdapter->StaCfg.DLSEntry[i], sizeof(RT_802_11_DLS_UI));
5420				}
5421
5422				pDlsInfo->num = MAX_NUM_OF_DLS_ENTRY;
5423				wrq->u.data.length = sizeof(RT_802_11_DLS_INFO);
5424				Status = copy_to_user(wrq->u.data.pointer, pDlsInfo, wrq->u.data.length);
5425				DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_DLS_PARAM\n"));
5426
5427				if (pDlsInfo)
5428					kfree(pDlsInfo);
5429			}
5430			break;
5431#endif // QOS_DLS_SUPPORT //
5432        default:
5433            DBGPRINT(RT_DEBUG_TRACE, ("Query::unknown IOCTL's subcmd = 0x%08x\n", cmd));
5434            Status = -EOPNOTSUPP;
5435            break;
5436    }
5437    return Status;
5438}
5439
5440INT rt28xx_sta_ioctl(
5441	IN	struct net_device	*net_dev,
5442	IN	OUT	struct ifreq	*rq,
5443	IN	INT					cmd)
5444{
5445	POS_COOKIE			pObj;
5446	VIRTUAL_ADAPTER		*pVirtualAd = NULL;
5447	RTMP_ADAPTER        *pAd = NULL;
5448	struct iwreq        *wrq = (struct iwreq *) rq;
5449	BOOLEAN				StateMachineTouched = FALSE;
5450	INT					Status = NDIS_STATUS_SUCCESS;
5451	USHORT				subcmd;
5452
5453	if (net_dev->priv_flags == INT_MAIN)
5454	{
5455		pAd = net_dev->priv;
5456	}
5457	else
5458	{
5459		pVirtualAd = net_dev->priv;
5460		pAd = pVirtualAd->RtmpDev->priv;
5461	}
5462	pObj = (POS_COOKIE) pAd->OS_Cookie;
5463
5464	if (pAd == NULL)
5465	{
5466		/* if 1st open fail, pAd will be free;
5467		   So the net_dev->priv will be NULL in 2rd open */
5468		return -ENETDOWN;
5469	}
5470
5471    //check if the interface is down
5472    if(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE))
5473    {
5474#ifdef CONFIG_APSTA_MIXED_SUPPORT
5475	    if (wrq->u.data.pointer == NULL)
5476	    {
5477		    return Status;
5478	    }
5479
5480	    if (strstr(wrq->u.data.pointer, "OpMode") == NULL)
5481#endif // CONFIG_APSTA_MIXED_SUPPORT //
5482        {
5483            DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
5484		    return -ENETDOWN;
5485        }
5486    }
5487
5488	{	// determine this ioctl command is comming from which interface.
5489		pObj->ioctl_if_type = INT_MAIN;
5490		pObj->ioctl_if = MAIN_MBSSID;
5491	}
5492
5493	switch(cmd)
5494	{
5495#ifdef RALINK_ATE
5496#ifdef RALINK_28xx_QA
5497		case RTPRIV_IOCTL_ATE:
5498			{
5499				RtmpDoAte(pAd, wrq);
5500			}
5501			break;
5502#endif // RALINK_28xx_QA //
5503#endif // RALINK_ATE //
5504        case SIOCGIFHWADDR:
5505			DBGPRINT(RT_DEBUG_TRACE, ("IOCTL::SIOCGIFHWADDR\n"));
5506			memcpy(wrq->u.name, pAd->CurrentAddress, ETH_ALEN);
5507			break;
5508		case SIOCGIWNAME:
5509        {
5510        	char *name=&wrq->u.name[0];
5511        	rt_ioctl_giwname(net_dev, NULL, name, NULL);
5512			break;
5513		}
5514		case SIOCGIWESSID:  //Get ESSID
5515        {
5516        	struct iw_point *essid=&wrq->u.essid;
5517        	rt_ioctl_giwessid(net_dev, NULL, essid, essid->pointer);
5518			break;
5519		}
5520		case SIOCSIWESSID:  //Set ESSID
5521        {
5522        	struct iw_point	*essid=&wrq->u.essid;
5523        	rt_ioctl_siwessid(net_dev, NULL, essid, essid->pointer);
5524			break;
5525		}
5526		case SIOCSIWNWID:   // set network id (the cell)
5527		case SIOCGIWNWID:   // get network id
5528			Status = -EOPNOTSUPP;
5529			break;
5530		case SIOCSIWFREQ:   //set channel/frequency (Hz)
5531        {
5532        	struct iw_freq *freq=&wrq->u.freq;
5533        	rt_ioctl_siwfreq(net_dev, NULL, freq, NULL);
5534			break;
5535		}
5536		case SIOCGIWFREQ:   // get channel/frequency (Hz)
5537        {
5538        	struct iw_freq *freq=&wrq->u.freq;
5539        	rt_ioctl_giwfreq(net_dev, NULL, freq, NULL);
5540			break;
5541		}
5542		case SIOCSIWNICKN: //set node name/nickname
5543        {
5544        	struct iw_point *data=&wrq->u.data;
5545        	rt_ioctl_siwnickn(net_dev, NULL, data, NULL);
5546			break;
5547		}
5548		case SIOCGIWNICKN: //get node name/nickname
5549        {
5550        	struct iw_point *data=&wrq->u.data;
5551        	rt_ioctl_giwnickn(net_dev, NULL, data, NULL);
5552			break;
5553		}
5554		case SIOCGIWRATE:   //get default bit rate (bps)
5555		    rt_ioctl_giwrate(net_dev, NULL, &wrq->u, NULL);
5556            break;
5557	    case SIOCSIWRATE:  //set default bit rate (bps)
5558	        rt_ioctl_siwrate(net_dev, NULL, &wrq->u, NULL);
5559            break;
5560        case SIOCGIWRTS:  // get RTS/CTS threshold (bytes)
5561        {
5562        	struct iw_param *rts=&wrq->u.rts;
5563        	rt_ioctl_giwrts(net_dev, NULL, rts, NULL);
5564			break;
5565		}
5566        case SIOCSIWRTS:  //set RTS/CTS threshold (bytes)
5567        {
5568        	struct iw_param *rts=&wrq->u.rts;
5569        	rt_ioctl_siwrts(net_dev, NULL, rts, NULL);
5570			break;
5571		}
5572        case SIOCGIWFRAG:  //get fragmentation thr (bytes)
5573        {
5574        	struct iw_param *frag=&wrq->u.frag;
5575        	rt_ioctl_giwfrag(net_dev, NULL, frag, NULL);
5576			break;
5577		}
5578        case SIOCSIWFRAG:  //set fragmentation thr (bytes)
5579        {
5580        	struct iw_param *frag=&wrq->u.frag;
5581        	rt_ioctl_siwfrag(net_dev, NULL, frag, NULL);
5582			break;
5583		}
5584        case SIOCGIWENCODE:  //get encoding token & mode
5585        {
5586        	struct iw_point *erq=&wrq->u.encoding;
5587        	if(erq->pointer)
5588        		rt_ioctl_giwencode(net_dev, NULL, erq, erq->pointer);
5589			break;
5590		}
5591        case SIOCSIWENCODE:  //set encoding token & mode
5592        {
5593        	struct iw_point *erq=&wrq->u.encoding;
5594        	if(erq->pointer)
5595        		rt_ioctl_siwencode(net_dev, NULL, erq, erq->pointer);
5596			break;
5597		}
5598		case SIOCGIWAP:     //get access point MAC addresses
5599        {
5600        	struct sockaddr *ap_addr=&wrq->u.ap_addr;
5601        	rt_ioctl_giwap(net_dev, NULL, ap_addr, ap_addr->sa_data);
5602			break;
5603		}
5604	    case SIOCSIWAP:  //set access point MAC addresses
5605        {
5606        	struct sockaddr *ap_addr=&wrq->u.ap_addr;
5607        	rt_ioctl_siwap(net_dev, NULL, ap_addr, ap_addr->sa_data);
5608			break;
5609		}
5610		case SIOCGIWMODE:   //get operation mode
5611        {
5612        	__u32 *mode=&wrq->u.mode;
5613        	rt_ioctl_giwmode(net_dev, NULL, mode, NULL);
5614			break;
5615		}
5616		case SIOCSIWMODE:   //set operation mode
5617        {
5618        	__u32 *mode=&wrq->u.mode;
5619        	rt_ioctl_siwmode(net_dev, NULL, mode, NULL);
5620			break;
5621		}
5622		case SIOCGIWSENS:   //get sensitivity (dBm)
5623		case SIOCSIWSENS:	//set sensitivity (dBm)
5624		case SIOCGIWPOWER:  //get Power Management settings
5625		case SIOCSIWPOWER:  //set Power Management settings
5626		case SIOCGIWTXPOW:  //get transmit power (dBm)
5627		case SIOCSIWTXPOW:  //set transmit power (dBm)
5628		case SIOCGIWRANGE:	//Get range of parameters
5629		case SIOCGIWRETRY:	//get retry limits and lifetime
5630		case SIOCSIWRETRY:	//set retry limits and lifetime
5631			Status = -EOPNOTSUPP;
5632			break;
5633		case RT_PRIV_IOCTL:
5634			subcmd = wrq->u.data.flags;
5635			if( subcmd & OID_GET_SET_TOGGLE)
5636				Status = RTMPSetInformation(pAd, rq, subcmd);
5637			else
5638				Status = RTMPQueryInformation(pAd, rq, subcmd);
5639			break;
5640		case SIOCGIWPRIV:
5641			if (wrq->u.data.pointer)
5642			{
5643				if ( access_ok(VERIFY_WRITE, wrq->u.data.pointer, sizeof(privtab)) != TRUE)
5644					break;
5645				wrq->u.data.length = sizeof(privtab) / sizeof(privtab[0]);
5646				if (copy_to_user(wrq->u.data.pointer, privtab, sizeof(privtab)))
5647					Status = -EFAULT;
5648			}
5649			break;
5650		case RTPRIV_IOCTL_SET:
5651			if(access_ok(VERIFY_READ, wrq->u.data.pointer, wrq->u.data.length) != TRUE)
5652				break;
5653			rt_ioctl_setparam(net_dev, NULL, NULL, wrq->u.data.pointer);
5654			break;
5655		case RTPRIV_IOCTL_GSITESURVEY:
5656			RTMPIoctlGetSiteSurvey(pAd, wrq);
5657		    break;
5658#ifdef DBG
5659		case RTPRIV_IOCTL_MAC:
5660			RTMPIoctlMAC(pAd, wrq);
5661			break;
5662		case RTPRIV_IOCTL_E2P:
5663			RTMPIoctlE2PROM(pAd, wrq);
5664			break;
5665#endif // DBG //
5666        case SIOCETHTOOL:
5667                break;
5668		default:
5669			DBGPRINT(RT_DEBUG_ERROR, ("IOCTL::unknown IOCTL's cmd = 0x%08x\n", cmd));
5670			Status = -EOPNOTSUPP;
5671			break;
5672	}
5673
5674    if(StateMachineTouched) // Upper layer sent a MLME-related operations
5675    	RT28XX_MLME_HANDLER(pAd);
5676
5677	return Status;
5678}
5679
5680/*
5681    ==========================================================================
5682    Description:
5683        Set SSID
5684    Return:
5685        TRUE if all parameters are OK, FALSE otherwise
5686    ==========================================================================
5687*/
5688INT Set_SSID_Proc(
5689    IN  PRTMP_ADAPTER   pAdapter,
5690    IN  PUCHAR          arg)
5691{
5692    NDIS_802_11_SSID                    Ssid, *pSsid=NULL;
5693    BOOLEAN                             StateMachineTouched = FALSE;
5694    int                                 success = TRUE;
5695
5696    if( strlen(arg) <= MAX_LEN_OF_SSID)
5697    {
5698        NdisZeroMemory(&Ssid, sizeof(NDIS_802_11_SSID));
5699        if (strlen(arg) != 0)
5700        {
5701            NdisMoveMemory(Ssid.Ssid, arg, strlen(arg));
5702            Ssid.SsidLength = strlen(arg);
5703        }
5704        else   //ANY ssid
5705        {
5706            Ssid.SsidLength = 0;
5707		    memcpy(Ssid.Ssid, "", 0);
5708			pAdapter->StaCfg.BssType = BSS_INFRA;
5709			pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
5710	        pAdapter->StaCfg.WepStatus  = Ndis802_11EncryptionDisabled;
5711		}
5712        pSsid = &Ssid;
5713
5714        if (pAdapter->Mlme.CntlMachine.CurrState != CNTL_IDLE)
5715        {
5716            RT28XX_MLME_RESET_STATE_MACHINE(pAdapter);
5717            DBGPRINT(RT_DEBUG_TRACE, ("!!! MLME busy, reset MLME state machine !!!\n"));
5718        }
5719
5720        pAdapter->MlmeAux.CurrReqIsFromNdis = TRUE;
5721        pAdapter->StaCfg.bScanReqIsFromWebUI = FALSE;
5722		pAdapter->bConfigChanged = TRUE;
5723
5724        MlmeEnqueue(pAdapter,
5725                    MLME_CNTL_STATE_MACHINE,
5726                    OID_802_11_SSID,
5727                    sizeof(NDIS_802_11_SSID),
5728                    (VOID *)pSsid);
5729
5730        StateMachineTouched = TRUE;
5731        DBGPRINT(RT_DEBUG_TRACE, ("Set_SSID_Proc::(Len=%d,Ssid=%s)\n", Ssid.SsidLength, Ssid.Ssid));
5732    }
5733    else
5734        success = FALSE;
5735
5736    if (StateMachineTouched) // Upper layer sent a MLME-related operations
5737    	RT28XX_MLME_HANDLER(pAdapter);
5738
5739    return success;
5740}
5741
5742#ifdef WMM_SUPPORT
5743/*
5744    ==========================================================================
5745    Description:
5746        Set WmmCapable Enable or Disable
5747    Return:
5748        TRUE if all parameters are OK, FALSE otherwise
5749    ==========================================================================
5750*/
5751INT	Set_WmmCapable_Proc(
5752	IN	PRTMP_ADAPTER	pAd,
5753	IN	PUCHAR			arg)
5754{
5755	BOOLEAN	bWmmCapable;
5756
5757	bWmmCapable = simple_strtol(arg, 0, 10);
5758
5759	if ((bWmmCapable == 1)
5760#ifdef RT2870
5761		&& (pAd->NumberOfPipes >= 5)
5762#endif // RT2870 //
5763		)
5764		pAd->CommonCfg.bWmmCapable = TRUE;
5765	else if (bWmmCapable == 0)
5766		pAd->CommonCfg.bWmmCapable = FALSE;
5767	else
5768		return FALSE;  //Invalid argument
5769
5770	DBGPRINT(RT_DEBUG_TRACE, ("Set_WmmCapable_Proc::(bWmmCapable=%d)\n",
5771		pAd->CommonCfg.bWmmCapable));
5772
5773	return TRUE;
5774}
5775#endif // WMM_SUPPORT //
5776
5777/*
5778    ==========================================================================
5779    Description:
5780        Set Network Type(Infrastructure/Adhoc mode)
5781    Return:
5782        TRUE if all parameters are OK, FALSE otherwise
5783    ==========================================================================
5784*/
5785INT Set_NetworkType_Proc(
5786    IN  PRTMP_ADAPTER   pAdapter,
5787    IN  PUCHAR          arg)
5788{
5789    UINT32	Value = 0;
5790
5791    if (strcmp(arg, "Adhoc") == 0)
5792	{
5793		if (pAdapter->StaCfg.BssType != BSS_ADHOC)
5794		{
5795			// Config has changed
5796			pAdapter->bConfigChanged = TRUE;
5797            if (MONITOR_ON(pAdapter))
5798            {
5799                RTMP_IO_WRITE32(pAdapter, RX_FILTR_CFG, STANORMAL);
5800                RTMP_IO_READ32(pAdapter, MAC_SYS_CTRL, &Value);
5801				Value &= (~0x80);
5802				RTMP_IO_WRITE32(pAdapter, MAC_SYS_CTRL, Value);
5803                OPSTATUS_CLEAR_FLAG(pAdapter, fOP_STATUS_MEDIA_STATE_CONNECTED);
5804                pAdapter->StaCfg.bAutoReconnect = TRUE;
5805                LinkDown(pAdapter, FALSE);
5806            }
5807			if (INFRA_ON(pAdapter))
5808			{
5809				//BOOLEAN Cancelled;
5810				// Set the AutoReconnectSsid to prevent it reconnect to old SSID
5811				// Since calling this indicate user don't want to connect to that SSID anymore.
5812				pAdapter->MlmeAux.AutoReconnectSsidLen= 32;
5813				NdisZeroMemory(pAdapter->MlmeAux.AutoReconnectSsid, pAdapter->MlmeAux.AutoReconnectSsidLen);
5814
5815				LinkDown(pAdapter, FALSE);
5816
5817				DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event BB!\n"));
5818			}
5819		}
5820		pAdapter->StaCfg.BssType = BSS_ADHOC;
5821        pAdapter->net_dev->type = pAdapter->StaCfg.OriDevType;
5822		DBGPRINT(RT_DEBUG_TRACE, ("===>Set_NetworkType_Proc::(AD-HOC)\n"));
5823	}
5824    else if (strcmp(arg, "Infra") == 0)
5825	{
5826		if (pAdapter->StaCfg.BssType != BSS_INFRA)
5827		{
5828			// Config has changed
5829			pAdapter->bConfigChanged = TRUE;
5830            if (MONITOR_ON(pAdapter))
5831            {
5832                RTMP_IO_WRITE32(pAdapter, RX_FILTR_CFG, STANORMAL);
5833                RTMP_IO_READ32(pAdapter, MAC_SYS_CTRL, &Value);
5834				Value &= (~0x80);
5835				RTMP_IO_WRITE32(pAdapter, MAC_SYS_CTRL, Value);
5836                OPSTATUS_CLEAR_FLAG(pAdapter, fOP_STATUS_MEDIA_STATE_CONNECTED);
5837                pAdapter->StaCfg.bAutoReconnect = TRUE;
5838                LinkDown(pAdapter, FALSE);
5839            }
5840			if (ADHOC_ON(pAdapter))
5841			{
5842				// Set the AutoReconnectSsid to prevent it reconnect to old SSID
5843				// Since calling this indicate user don't want to connect to that SSID anymore.
5844				pAdapter->MlmeAux.AutoReconnectSsidLen= 32;
5845				NdisZeroMemory(pAdapter->MlmeAux.AutoReconnectSsid, pAdapter->MlmeAux.AutoReconnectSsidLen);
5846
5847				LinkDown(pAdapter, FALSE);
5848			}
5849		}
5850		pAdapter->StaCfg.BssType = BSS_INFRA;
5851        pAdapter->net_dev->type = pAdapter->StaCfg.OriDevType;
5852		DBGPRINT(RT_DEBUG_TRACE, ("===>Set_NetworkType_Proc::(INFRA)\n"));
5853
5854        pAdapter->StaCfg.BssType = BSS_INFRA;
5855	}
5856    else if (strcmp(arg, "Monitor") == 0)
5857    {
5858		UCHAR	bbpValue = 0;
5859		BCN_TIME_CFG_STRUC csr;
5860		OPSTATUS_CLEAR_FLAG(pAdapter, fOP_STATUS_INFRA_ON);
5861        OPSTATUS_CLEAR_FLAG(pAdapter, fOP_STATUS_ADHOC_ON);
5862		OPSTATUS_SET_FLAG(pAdapter, fOP_STATUS_MEDIA_STATE_CONNECTED);
5863		// disable all periodic state machine
5864		pAdapter->StaCfg.bAutoReconnect = FALSE;
5865		// reset all mlme state machine
5866		RT28XX_MLME_RESET_STATE_MACHINE(pAdapter);
5867		DBGPRINT(RT_DEBUG_TRACE, ("fOP_STATUS_MEDIA_STATE_CONNECTED \n"));
5868        if (pAdapter->CommonCfg.CentralChannel == 0)
5869        {
5870#ifdef DOT11_N_SUPPORT
5871            if (pAdapter->CommonCfg.PhyMode == PHY_11AN_MIXED)
5872                pAdapter->CommonCfg.CentralChannel = 36;
5873            else
5874#endif // DOT11_N_SUPPORT //
5875                pAdapter->CommonCfg.CentralChannel = 6;
5876        }
5877#ifdef DOT11_N_SUPPORT
5878        else
5879            N_ChannelCheck(pAdapter);
5880#endif // DOT11_N_SUPPORT //
5881
5882#ifdef DOT11_N_SUPPORT
5883	if (pAdapter->CommonCfg.PhyMode >= PHY_11ABGN_MIXED &&
5884            pAdapter->CommonCfg.RegTransmitSetting.field.BW == BW_40 &&
5885            pAdapter->CommonCfg.RegTransmitSetting.field.EXTCHA == EXTCHA_ABOVE)
5886		{
5887			// 40MHz ,control channel at lower
5888			RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R4, &bbpValue);
5889			bbpValue &= (~0x18);
5890			bbpValue |= 0x10;
5891			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R4, bbpValue);
5892			pAdapter->CommonCfg.BBPCurrentBW = BW_40;
5893			//  RX : control channel at lower
5894			RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R3, &bbpValue);
5895			bbpValue &= (~0x20);
5896			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R3, bbpValue);
5897
5898			RTMP_IO_READ32(pAdapter, TX_BAND_CFG, &Value);
5899			Value &= 0xfffffffe;
5900			RTMP_IO_WRITE32(pAdapter, TX_BAND_CFG, Value);
5901			pAdapter->CommonCfg.CentralChannel = pAdapter->CommonCfg.Channel + 2;
5902            AsicSwitchChannel(pAdapter, pAdapter->CommonCfg.CentralChannel, FALSE);
5903		    AsicLockChannel(pAdapter, pAdapter->CommonCfg.CentralChannel);
5904            DBGPRINT(RT_DEBUG_TRACE, ("BW_40 ,control_channel(%d), CentralChannel(%d) \n",
5905                                       pAdapter->CommonCfg.Channel,
5906                                       pAdapter->CommonCfg.CentralChannel));
5907		}
5908		else if (pAdapter->CommonCfg.PhyMode >= PHY_11ABGN_MIXED &&
5909                 pAdapter->CommonCfg.RegTransmitSetting.field.BW == BW_40 &&
5910                 pAdapter->CommonCfg.RegTransmitSetting.field.EXTCHA == EXTCHA_BELOW)
5911		{
5912			// 40MHz ,control channel at upper
5913			RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R4, &bbpValue);
5914			bbpValue &= (~0x18);
5915			bbpValue |= 0x10;
5916			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R4, bbpValue);
5917			pAdapter->CommonCfg.BBPCurrentBW = BW_40;
5918			RTMP_IO_READ32(pAdapter, TX_BAND_CFG, &Value);
5919			Value |= 0x1;
5920			RTMP_IO_WRITE32(pAdapter, TX_BAND_CFG, Value);
5921
5922			RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R3, &bbpValue);
5923			bbpValue |= (0x20);
5924			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R3, bbpValue);
5925			pAdapter->CommonCfg.CentralChannel = pAdapter->CommonCfg.Channel - 2;
5926            AsicSwitchChannel(pAdapter, pAdapter->CommonCfg.CentralChannel, FALSE);
5927		    AsicLockChannel(pAdapter, pAdapter->CommonCfg.CentralChannel);
5928            DBGPRINT(RT_DEBUG_TRACE, ("BW_40 ,control_channel(%d), CentralChannel(%d) \n",
5929                                       pAdapter->CommonCfg.Channel,
5930                                       pAdapter->CommonCfg.CentralChannel));
5931		}
5932		else
5933#endif // DOT11_N_SUPPORT //
5934		{
5935			// 20MHz
5936			RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R4, &bbpValue);
5937			bbpValue &= (~0x18);
5938			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R4, bbpValue);
5939			pAdapter->CommonCfg.BBPCurrentBW = BW_20;
5940			AsicSwitchChannel(pAdapter, pAdapter->CommonCfg.Channel, FALSE);
5941			AsicLockChannel(pAdapter, pAdapter->CommonCfg.Channel);
5942			DBGPRINT(RT_DEBUG_TRACE, ("BW_20, Channel(%d)\n", pAdapter->CommonCfg.Channel));
5943		}
5944		// Enable Rx with promiscuous reception
5945		RTMP_IO_WRITE32(pAdapter, RX_FILTR_CFG, 0x3);
5946		// ASIC supporsts sniffer function with replacing RSSI with timestamp.
5947		//RTMP_IO_READ32(pAdapter, MAC_SYS_CTRL, &Value);
5948		//Value |= (0x80);
5949		//RTMP_IO_WRITE32(pAdapter, MAC_SYS_CTRL, Value);
5950		// disable sync
5951		RTMP_IO_READ32(pAdapter, BCN_TIME_CFG, &csr.word);
5952		csr.field.bBeaconGen = 0;
5953		csr.field.bTBTTEnable = 0;
5954		csr.field.TsfSyncMode = 0;
5955		RTMP_IO_WRITE32(pAdapter, BCN_TIME_CFG, csr.word);
5956
5957		pAdapter->StaCfg.BssType = BSS_MONITOR;
5958        pAdapter->net_dev->type = ARPHRD_IEEE80211_PRISM; //ARPHRD_IEEE80211; // IEEE80211
5959		DBGPRINT(RT_DEBUG_TRACE, ("===>Set_NetworkType_Proc::(MONITOR)\n"));
5960    }
5961
5962    // Reset Ralink supplicant to not use, it will be set to start when UI set PMK key
5963    pAdapter->StaCfg.WpaState = SS_NOTUSE;
5964
5965    DBGPRINT(RT_DEBUG_TRACE, ("Set_NetworkType_Proc::(NetworkType=%d)\n", pAdapter->StaCfg.BssType));
5966
5967    return TRUE;
5968}
5969
5970/*
5971    ==========================================================================
5972    Description:
5973        Set Authentication mode
5974    Return:
5975        TRUE if all parameters are OK, FALSE otherwise
5976    ==========================================================================
5977*/
5978INT Set_AuthMode_Proc(
5979    IN  PRTMP_ADAPTER   pAdapter,
5980    IN  PUCHAR          arg)
5981{
5982    if ((strcmp(arg, "WEPAUTO") == 0) || (strcmp(arg, "wepauto") == 0))
5983        pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeAutoSwitch;
5984    else if ((strcmp(arg, "OPEN") == 0) || (strcmp(arg, "open") == 0))
5985        pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
5986    else if ((strcmp(arg, "SHARED") == 0) || (strcmp(arg, "shared") == 0))
5987        pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeShared;
5988    else if ((strcmp(arg, "WPAPSK") == 0) || (strcmp(arg, "wpapsk") == 0))
5989        pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPAPSK;
5990    else if ((strcmp(arg, "WPANONE") == 0) || (strcmp(arg, "wpanone") == 0))
5991        pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPANone;
5992    else if ((strcmp(arg, "WPA2PSK") == 0) || (strcmp(arg, "wpa2psk") == 0))
5993        pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPA2PSK;
5994#ifdef WPA_SUPPLICANT_SUPPORT
5995    else if ((strcmp(arg, "WPA") == 0) || (strcmp(arg, "wpa") == 0))
5996        pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPA;
5997    else if ((strcmp(arg, "WPA2") == 0) || (strcmp(arg, "wpa2") == 0))
5998        pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPA2;
5999#endif // WPA_SUPPLICANT_SUPPORT //
6000    else
6001        return FALSE;
6002
6003    pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
6004
6005    DBGPRINT(RT_DEBUG_TRACE, ("Set_AuthMode_Proc::(AuthMode=%d)\n", pAdapter->StaCfg.AuthMode));
6006
6007    return TRUE;
6008}
6009
6010/*
6011    ==========================================================================
6012    Description:
6013        Set Encryption Type
6014    Return:
6015        TRUE if all parameters are OK, FALSE otherwise
6016    ==========================================================================
6017*/
6018INT Set_EncrypType_Proc(
6019    IN  PRTMP_ADAPTER   pAdapter,
6020    IN  PUCHAR          arg)
6021{
6022    if ((strcmp(arg, "NONE") == 0) || (strcmp(arg, "none") == 0))
6023    {
6024        if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
6025            return TRUE;    // do nothing
6026
6027        pAdapter->StaCfg.WepStatus     = Ndis802_11WEPDisabled;
6028        pAdapter->StaCfg.PairCipher    = Ndis802_11WEPDisabled;
6029	    pAdapter->StaCfg.GroupCipher   = Ndis802_11WEPDisabled;
6030    }
6031    else if ((strcmp(arg, "WEP") == 0) || (strcmp(arg, "wep") == 0))
6032    {
6033        if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
6034            return TRUE;    // do nothing
6035
6036        pAdapter->StaCfg.WepStatus     = Ndis802_11WEPEnabled;
6037        pAdapter->StaCfg.PairCipher    = Ndis802_11WEPEnabled;
6038	    pAdapter->StaCfg.GroupCipher   = Ndis802_11WEPEnabled;
6039    }
6040    else if ((strcmp(arg, "TKIP") == 0) || (strcmp(arg, "tkip") == 0))
6041    {
6042        if (pAdapter->StaCfg.AuthMode < Ndis802_11AuthModeWPA)
6043            return TRUE;    // do nothing
6044
6045        pAdapter->StaCfg.WepStatus     = Ndis802_11Encryption2Enabled;
6046        pAdapter->StaCfg.PairCipher    = Ndis802_11Encryption2Enabled;
6047	    pAdapter->StaCfg.GroupCipher   = Ndis802_11Encryption2Enabled;
6048    }
6049    else if ((strcmp(arg, "AES") == 0) || (strcmp(arg, "aes") == 0))
6050    {
6051        if (pAdapter->StaCfg.AuthMode < Ndis802_11AuthModeWPA)
6052            return TRUE;    // do nothing
6053
6054        pAdapter->StaCfg.WepStatus     = Ndis802_11Encryption3Enabled;
6055        pAdapter->StaCfg.PairCipher    = Ndis802_11Encryption3Enabled;
6056	    pAdapter->StaCfg.GroupCipher   = Ndis802_11Encryption3Enabled;
6057    }
6058    else
6059        return FALSE;
6060
6061    pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
6062
6063    DBGPRINT(RT_DEBUG_TRACE, ("Set_EncrypType_Proc::(EncrypType=%d)\n", pAdapter->StaCfg.WepStatus));
6064
6065    return TRUE;
6066}
6067
6068/*
6069    ==========================================================================
6070    Description:
6071        Set Default Key ID
6072    Return:
6073        TRUE if all parameters are OK, FALSE otherwise
6074    ==========================================================================
6075*/
6076INT Set_DefaultKeyID_Proc(
6077    IN  PRTMP_ADAPTER   pAdapter,
6078    IN  PUCHAR          arg)
6079{
6080    ULONG                               KeyIdx;
6081
6082    KeyIdx = simple_strtol(arg, 0, 10);
6083    if((KeyIdx >= 1 ) && (KeyIdx <= 4))
6084        pAdapter->StaCfg.DefaultKeyId = (UCHAR) (KeyIdx - 1 );
6085    else
6086        return FALSE;  //Invalid argument
6087
6088    DBGPRINT(RT_DEBUG_TRACE, ("Set_DefaultKeyID_Proc::(DefaultKeyID=%d)\n", pAdapter->StaCfg.DefaultKeyId));
6089
6090    return TRUE;
6091}
6092
6093/*
6094    ==========================================================================
6095    Description:
6096        Set WEP KEY1
6097    Return:
6098        TRUE if all parameters are OK, FALSE otherwise
6099    ==========================================================================
6100*/
6101INT Set_Key1_Proc(
6102    IN  PRTMP_ADAPTER   pAdapter,
6103    IN  PUCHAR          arg)
6104{
6105    int                                 KeyLen;
6106    int                                 i;
6107    UCHAR                               CipherAlg=CIPHER_WEP64;
6108
6109    if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
6110        return TRUE;    // do nothing
6111
6112    KeyLen = strlen(arg);
6113
6114    switch (KeyLen)
6115    {
6116        case 5: //wep 40 Ascii type
6117            pAdapter->SharedKey[BSS0][0].KeyLen = KeyLen;
6118            memcpy(pAdapter->SharedKey[BSS0][0].Key, arg, KeyLen);
6119            CipherAlg = CIPHER_WEP64;
6120            DBGPRINT(RT_DEBUG_TRACE, ("Set_Key1_Proc::(Key1=%s and type=%s)\n", arg, "Ascii"));
6121            break;
6122        case 10: //wep 40 Hex type
6123            for(i=0; i < KeyLen; i++)
6124            {
6125                if( !isxdigit(*(arg+i)) )
6126                    return FALSE;  //Not Hex value;
6127            }
6128            pAdapter->SharedKey[BSS0][0].KeyLen = KeyLen / 2 ;
6129            AtoH(arg, pAdapter->SharedKey[BSS0][0].Key, KeyLen / 2);
6130            CipherAlg = CIPHER_WEP64;
6131            DBGPRINT(RT_DEBUG_TRACE, ("Set_Key1_Proc::(Key1=%s and type=%s)\n", arg, "Hex"));
6132            break;
6133        case 13: //wep 104 Ascii type
6134            pAdapter->SharedKey[BSS0][0].KeyLen = KeyLen;
6135            memcpy(pAdapter->SharedKey[BSS0][0].Key, arg, KeyLen);
6136            CipherAlg = CIPHER_WEP128;
6137            DBGPRINT(RT_DEBUG_TRACE, ("Set_Key1_Proc::(Key1=%s and type=%s)\n", arg, "Ascii"));
6138            break;
6139        case 26: //wep 104 Hex type
6140            for(i=0; i < KeyLen; i++)
6141            {
6142                if( !isxdigit(*(arg+i)) )
6143                    return FALSE;  //Not Hex value;
6144            }
6145            pAdapter->SharedKey[BSS0][0].KeyLen = KeyLen / 2 ;
6146            AtoH(arg, pAdapter->SharedKey[BSS0][0].Key, KeyLen / 2);
6147            CipherAlg = CIPHER_WEP128;
6148            DBGPRINT(RT_DEBUG_TRACE, ("Set_Key1_Proc::(Key1=%s and type=%s)\n", arg, "Hex"));
6149            break;
6150        default: //Invalid argument
6151            DBGPRINT(RT_DEBUG_TRACE, ("Set_Key1_Proc::Invalid argument (=%s)\n", arg));
6152            return FALSE;
6153    }
6154
6155    pAdapter->SharedKey[BSS0][0].CipherAlg = CipherAlg;
6156
6157    // Set keys (into ASIC)
6158    if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
6159        ;   // not support
6160    else    // Old WEP stuff
6161    {
6162        AsicAddSharedKeyEntry(pAdapter,
6163                              0,
6164                              0,
6165                              pAdapter->SharedKey[BSS0][0].CipherAlg,
6166                              pAdapter->SharedKey[BSS0][0].Key,
6167                              NULL,
6168                              NULL);
6169    }
6170
6171    return TRUE;
6172}
6173/*
6174    ==========================================================================
6175
6176    Description:
6177        Set WEP KEY2
6178    Return:
6179        TRUE if all parameters are OK, FALSE otherwise
6180    ==========================================================================
6181*/
6182INT Set_Key2_Proc(
6183    IN  PRTMP_ADAPTER   pAdapter,
6184    IN  PUCHAR          arg)
6185{
6186    int                                 KeyLen;
6187    int                                 i;
6188    UCHAR                               CipherAlg=CIPHER_WEP64;
6189
6190    if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
6191        return TRUE;    // do nothing
6192
6193    KeyLen = strlen(arg);
6194
6195    switch (KeyLen)
6196    {
6197        case 5: //wep 40 Ascii type
6198            pAdapter->SharedKey[BSS0][1].KeyLen = KeyLen;
6199            memcpy(pAdapter->SharedKey[BSS0][1].Key, arg, KeyLen);
6200            CipherAlg = CIPHER_WEP64;
6201            DBGPRINT(RT_DEBUG_TRACE, ("Set_Key2_Proc::(Key2=%s and type=%s)\n", arg, "Ascii"));
6202            break;
6203        case 10: //wep 40 Hex type
6204            for(i=0; i < KeyLen; i++)
6205            {
6206                if( !isxdigit(*(arg+i)) )
6207                    return FALSE;  //Not Hex value;
6208            }
6209            pAdapter->SharedKey[BSS0][1].KeyLen = KeyLen / 2 ;
6210            AtoH(arg, pAdapter->SharedKey[BSS0][1].Key, KeyLen / 2);
6211            CipherAlg = CIPHER_WEP64;
6212            DBGPRINT(RT_DEBUG_TRACE, ("Set_Key2_Proc::(Key2=%s and type=%s)\n", arg, "Hex"));
6213            break;
6214        case 13: //wep 104 Ascii type
6215            pAdapter->SharedKey[BSS0][1].KeyLen = KeyLen;
6216            memcpy(pAdapter->SharedKey[BSS0][1].Key, arg, KeyLen);
6217            CipherAlg = CIPHER_WEP128;
6218            DBGPRINT(RT_DEBUG_TRACE, ("Set_Key2_Proc::(Key2=%s and type=%s)\n", arg, "Ascii"));
6219            break;
6220        case 26: //wep 104 Hex type
6221            for(i=0; i < KeyLen; i++)
6222            {
6223                if( !isxdigit(*(arg+i)) )
6224                    return FALSE;  //Not Hex value;
6225            }
6226            pAdapter->SharedKey[BSS0][1].KeyLen = KeyLen / 2 ;
6227            AtoH(arg, pAdapter->SharedKey[BSS0][1].Key, KeyLen / 2);
6228            CipherAlg = CIPHER_WEP128;
6229            DBGPRINT(RT_DEBUG_TRACE, ("Set_Key2_Proc::(Key2=%s and type=%s)\n", arg, "Hex"));
6230            break;
6231        default: //Invalid argument
6232            DBGPRINT(RT_DEBUG_TRACE, ("Set_Key2_Proc::Invalid argument (=%s)\n", arg));
6233            return FALSE;
6234    }
6235    pAdapter->SharedKey[BSS0][1].CipherAlg = CipherAlg;
6236
6237    // Set keys (into ASIC)
6238    if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
6239        ;   // not support
6240    else    // Old WEP stuff
6241    {
6242        AsicAddSharedKeyEntry(pAdapter,
6243                              0,
6244                              1,
6245                              pAdapter->SharedKey[BSS0][1].CipherAlg,
6246                              pAdapter->SharedKey[BSS0][1].Key,
6247                              NULL,
6248                              NULL);
6249    }
6250
6251    return TRUE;
6252}
6253/*
6254    ==========================================================================
6255    Description:
6256        Set WEP KEY3
6257    Return:
6258        TRUE if all parameters are OK, FALSE otherwise
6259    ==========================================================================
6260*/
6261INT Set_Key3_Proc(
6262    IN  PRTMP_ADAPTER   pAdapter,
6263    IN  PUCHAR          arg)
6264{
6265    int                                 KeyLen;
6266    int                                 i;
6267    UCHAR                               CipherAlg=CIPHER_WEP64;
6268
6269    if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
6270        return TRUE;    // do nothing
6271
6272    KeyLen = strlen(arg);
6273
6274    switch (KeyLen)
6275    {
6276        case 5: //wep 40 Ascii type
6277            pAdapter->SharedKey[BSS0][2].KeyLen = KeyLen;
6278            memcpy(pAdapter->SharedKey[BSS0][2].Key, arg, KeyLen);
6279            CipherAlg = CIPHER_WEP64;
6280            DBGPRINT(RT_DEBUG_TRACE, ("Set_Key3_Proc::(Key3=%s and type=Ascii)\n", arg));
6281            break;
6282        case 10: //wep 40 Hex type
6283            for(i=0; i < KeyLen; i++)
6284            {
6285                if( !isxdigit(*(arg+i)) )
6286                    return FALSE;  //Not Hex value;
6287            }
6288            pAdapter->SharedKey[BSS0][2].KeyLen = KeyLen / 2 ;
6289            AtoH(arg, pAdapter->SharedKey[BSS0][2].Key, KeyLen / 2);
6290            CipherAlg = CIPHER_WEP64;
6291            DBGPRINT(RT_DEBUG_TRACE, ("Set_Key3_Proc::(Key3=%s and type=Hex)\n", arg));
6292            break;
6293        case 13: //wep 104 Ascii type
6294            pAdapter->SharedKey[BSS0][2].KeyLen = KeyLen;
6295            memcpy(pAdapter->SharedKey[BSS0][2].Key, arg, KeyLen);
6296            CipherAlg = CIPHER_WEP128;
6297            DBGPRINT(RT_DEBUG_TRACE, ("Set_Key3_Proc::(Key3=%s and type=Ascii)\n", arg));
6298            break;
6299        case 26: //wep 104 Hex type
6300            for(i=0; i < KeyLen; i++)
6301            {
6302                if( !isxdigit(*(arg+i)) )
6303                    return FALSE;  //Not Hex value;
6304            }
6305            pAdapter->SharedKey[BSS0][2].KeyLen = KeyLen / 2 ;
6306            AtoH(arg, pAdapter->SharedKey[BSS0][2].Key, KeyLen / 2);
6307            CipherAlg = CIPHER_WEP128;
6308            DBGPRINT(RT_DEBUG_TRACE, ("Set_Key3_Proc::(Key3=%s and type=Hex)\n", arg));
6309            break;
6310        default: //Invalid argument
6311            DBGPRINT(RT_DEBUG_TRACE, ("Set_Key3_Proc::Invalid argument (=%s)\n", arg));
6312            return FALSE;
6313    }
6314    pAdapter->SharedKey[BSS0][2].CipherAlg = CipherAlg;
6315
6316    // Set keys (into ASIC)
6317    if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
6318        ;   // not support
6319    else    // Old WEP stuff
6320    {
6321        AsicAddSharedKeyEntry(pAdapter,
6322                              0,
6323                              2,
6324                              pAdapter->SharedKey[BSS0][2].CipherAlg,
6325                              pAdapter->SharedKey[BSS0][2].Key,
6326                              NULL,
6327                              NULL);
6328    }
6329
6330    return TRUE;
6331}
6332/*
6333    ==========================================================================
6334    Description:
6335        Set WEP KEY4
6336    Return:
6337        TRUE if all parameters are OK, FALSE otherwise
6338    ==========================================================================
6339*/
6340INT Set_Key4_Proc(
6341    IN  PRTMP_ADAPTER   pAdapter,
6342    IN  PUCHAR          arg)
6343{
6344    int                                 KeyLen;
6345    int                                 i;
6346    UCHAR                               CipherAlg=CIPHER_WEP64;
6347
6348    if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
6349        return TRUE;    // do nothing
6350
6351    KeyLen = strlen(arg);
6352
6353    switch (KeyLen)
6354    {
6355        case 5: //wep 40 Ascii type
6356            pAdapter->SharedKey[BSS0][3].KeyLen = KeyLen;
6357            memcpy(pAdapter->SharedKey[BSS0][3].Key, arg, KeyLen);
6358            CipherAlg = CIPHER_WEP64;
6359            DBGPRINT(RT_DEBUG_TRACE, ("Set_Key4_Proc::(Key4=%s and type=%s)\n", arg, "Ascii"));
6360            break;
6361        case 10: //wep 40 Hex type
6362            for(i=0; i < KeyLen; i++)
6363            {
6364                if( !isxdigit(*(arg+i)) )
6365                    return FALSE;  //Not Hex value;
6366            }
6367            pAdapter->SharedKey[BSS0][3].KeyLen = KeyLen / 2 ;
6368            AtoH(arg, pAdapter->SharedKey[BSS0][3].Key, KeyLen / 2);
6369            CipherAlg = CIPHER_WEP64;
6370            DBGPRINT(RT_DEBUG_TRACE, ("Set_Key4_Proc::(Key4=%s and type=%s)\n", arg, "Hex"));
6371            break;
6372        case 13: //wep 104 Ascii type
6373            pAdapter->SharedKey[BSS0][3].KeyLen = KeyLen;
6374            memcpy(pAdapter->SharedKey[BSS0][3].Key, arg, KeyLen);
6375            CipherAlg = CIPHER_WEP128;
6376            DBGPRINT(RT_DEBUG_TRACE, ("Set_Key4_Proc::(Key4=%s and type=%s)\n", arg, "Ascii"));
6377            break;
6378        case 26: //wep 104 Hex type
6379            for(i=0; i < KeyLen; i++)
6380            {
6381                if( !isxdigit(*(arg+i)) )
6382                    return FALSE;  //Not Hex value;
6383            }
6384            pAdapter->SharedKey[BSS0][3].KeyLen = KeyLen / 2 ;
6385            AtoH(arg, pAdapter->SharedKey[BSS0][3].Key, KeyLen / 2);
6386            CipherAlg = CIPHER_WEP128;
6387            DBGPRINT(RT_DEBUG_TRACE, ("Set_Key4_Proc::(Key4=%s and type=%s)\n", arg, "Hex"));
6388            break;
6389        default: //Invalid argument
6390            DBGPRINT(RT_DEBUG_TRACE, ("Set_Key4_Proc::Invalid argument (=%s)\n", arg));
6391            return FALSE;
6392    }
6393    pAdapter->SharedKey[BSS0][3].CipherAlg = CipherAlg;
6394
6395    // Set keys (into ASIC)
6396    if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
6397        ;   // not support
6398    else    // Old WEP stuff
6399    {
6400        AsicAddSharedKeyEntry(pAdapter,
6401                              0,
6402                              3,
6403                              pAdapter->SharedKey[BSS0][3].CipherAlg,
6404                              pAdapter->SharedKey[BSS0][3].Key,
6405                              NULL,
6406                              NULL);
6407    }
6408
6409    return TRUE;
6410}
6411
6412/*
6413    ==========================================================================
6414    Description:
6415        Set WPA PSK key
6416    Return:
6417        TRUE if all parameters are OK, FALSE otherwise
6418    ==========================================================================
6419*/
6420INT Set_WPAPSK_Proc(
6421    IN  PRTMP_ADAPTER   pAdapter,
6422    IN  PUCHAR          arg)
6423{
6424    UCHAR                   keyMaterial[40];
6425
6426    if ((pAdapter->StaCfg.AuthMode != Ndis802_11AuthModeWPAPSK) &&
6427        (pAdapter->StaCfg.AuthMode != Ndis802_11AuthModeWPA2PSK) &&
6428	    (pAdapter->StaCfg.AuthMode != Ndis802_11AuthModeWPANone)
6429		)
6430        return TRUE;    // do nothing
6431
6432    DBGPRINT(RT_DEBUG_TRACE, ("Set_WPAPSK_Proc::(WPAPSK=%s)\n", arg));
6433
6434    NdisZeroMemory(keyMaterial, 40);
6435
6436    if ((strlen(arg) < 8) || (strlen(arg) > 64))
6437    {
6438        DBGPRINT(RT_DEBUG_TRACE, ("Set failed!!(WPAPSK=%s), WPAPSK key-string required 8 ~ 64 characters \n", arg));
6439        return FALSE;
6440    }
6441
6442    if (strlen(arg) == 64)
6443    {
6444        AtoH(arg, keyMaterial, 32);
6445        NdisMoveMemory(pAdapter->StaCfg.PMK, keyMaterial, 32);
6446
6447    }
6448    else
6449    {
6450        PasswordHash((char *)arg, pAdapter->MlmeAux.Ssid, pAdapter->MlmeAux.SsidLen, keyMaterial);
6451        NdisMoveMemory(pAdapter->StaCfg.PMK, keyMaterial, 32);
6452    }
6453
6454
6455
6456    if(pAdapter->StaCfg.BssType == BSS_ADHOC &&
6457       pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
6458    {
6459         pAdapter->StaCfg.WpaState = SS_NOTUSE;
6460    }
6461    else
6462    {
6463        // Start STA supplicant state machine
6464        pAdapter->StaCfg.WpaState = SS_START;
6465    }
6466
6467    return TRUE;
6468}
6469
6470/*
6471    ==========================================================================
6472    Description:
6473        Set Power Saving mode
6474    Return:
6475        TRUE if all parameters are OK, FALSE otherwise
6476    ==========================================================================
6477*/
6478INT Set_PSMode_Proc(
6479    IN  PRTMP_ADAPTER   pAdapter,
6480    IN  PUCHAR          arg)
6481{
6482    if (pAdapter->StaCfg.BssType == BSS_INFRA)
6483    {
6484        if ((strcmp(arg, "Max_PSP") == 0) ||
6485			(strcmp(arg, "max_psp") == 0) ||
6486			(strcmp(arg, "MAX_PSP") == 0))
6487        {
6488            // do NOT turn on PSM bit here, wait until MlmeCheckForPsmChange()
6489            // to exclude certain situations.
6490            if (pAdapter->StaCfg.bWindowsACCAMEnable == FALSE)
6491                pAdapter->StaCfg.WindowsPowerMode = Ndis802_11PowerModeMAX_PSP;
6492            pAdapter->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeMAX_PSP;
6493            OPSTATUS_SET_FLAG(pAdapter, fOP_STATUS_RECEIVE_DTIM);
6494            pAdapter->StaCfg.DefaultListenCount = 5;
6495
6496        }
6497        else if ((strcmp(arg, "Fast_PSP") == 0) ||
6498				 (strcmp(arg, "fast_psp") == 0) ||
6499                 (strcmp(arg, "FAST_PSP") == 0))
6500        {
6501            // do NOT turn on PSM bit here, wait until MlmeCheckForPsmChange()
6502            // to exclude certain situations.
6503            OPSTATUS_SET_FLAG(pAdapter, fOP_STATUS_RECEIVE_DTIM);
6504            if (pAdapter->StaCfg.bWindowsACCAMEnable == FALSE)
6505                pAdapter->StaCfg.WindowsPowerMode = Ndis802_11PowerModeFast_PSP;
6506            pAdapter->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeFast_PSP;
6507            pAdapter->StaCfg.DefaultListenCount = 3;
6508        }
6509        else if ((strcmp(arg, "Legacy_PSP") == 0) ||
6510                 (strcmp(arg, "legacy_psp") == 0) ||
6511                 (strcmp(arg, "LEGACY_PSP") == 0))
6512        {
6513            // do NOT turn on PSM bit here, wait until MlmeCheckForPsmChange()
6514            // to exclude certain situations.
6515            OPSTATUS_SET_FLAG(pAdapter, fOP_STATUS_RECEIVE_DTIM);
6516            if (pAdapter->StaCfg.bWindowsACCAMEnable == FALSE)
6517                pAdapter->StaCfg.WindowsPowerMode = Ndis802_11PowerModeLegacy_PSP;
6518            pAdapter->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeLegacy_PSP;
6519            pAdapter->StaCfg.DefaultListenCount = 3;
6520        }
6521        else
6522        {
6523            //Default Ndis802_11PowerModeCAM
6524            // clear PSM bit immediately
6525            MlmeSetPsmBit(pAdapter, PWR_ACTIVE);
6526            OPSTATUS_SET_FLAG(pAdapter, fOP_STATUS_RECEIVE_DTIM);
6527            if (pAdapter->StaCfg.bWindowsACCAMEnable == FALSE)
6528                pAdapter->StaCfg.WindowsPowerMode = Ndis802_11PowerModeCAM;
6529            pAdapter->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeCAM;
6530        }
6531
6532        DBGPRINT(RT_DEBUG_TRACE, ("Set_PSMode_Proc::(PSMode=%ld)\n", pAdapter->StaCfg.WindowsPowerMode));
6533    }
6534    else
6535        return FALSE;
6536
6537
6538    return TRUE;
6539}
6540
6541#ifdef WPA_SUPPLICANT_SUPPORT
6542/*
6543    ==========================================================================
6544    Description:
6545        Set WpaSupport flag.
6546    Value:
6547        0: Driver ignore wpa_supplicant.
6548        1: wpa_supplicant initiates scanning and AP selection.
6549        2: driver takes care of scanning, AP selection, and IEEE 802.11 association parameters.
6550    Return:
6551        TRUE if all parameters are OK, FALSE otherwise
6552    ==========================================================================
6553*/
6554INT Set_Wpa_Support(
6555    IN	PRTMP_ADAPTER	pAd,
6556	IN	PUCHAR			arg)
6557{
6558
6559    if ( simple_strtol(arg, 0, 10) == 0)
6560        pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_DISABLE;
6561    else if ( simple_strtol(arg, 0, 10) == 1)
6562        pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_ENABLE;
6563    else if ( simple_strtol(arg, 0, 10) == 2)
6564        pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_ENABLE_WITH_WEB_UI;
6565    else
6566        pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_DISABLE;
6567
6568    DBGPRINT(RT_DEBUG_TRACE, ("Set_Wpa_Support::(WpaSupplicantUP=%d)\n", pAd->StaCfg.WpaSupplicantUP));
6569
6570    return TRUE;
6571}
6572#endif // WPA_SUPPLICANT_SUPPORT //
6573
6574#ifdef DBG
6575/*
6576    ==========================================================================
6577    Description:
6578        Read / Write MAC
6579    Arguments:
6580        pAdapter                    Pointer to our adapter
6581        wrq                         Pointer to the ioctl argument
6582
6583    Return Value:
6584        None
6585
6586    Note:
6587        Usage:
6588               1.) iwpriv ra0 mac 0        ==> read MAC where Addr=0x0
6589               2.) iwpriv ra0 mac 0=12     ==> write MAC where Addr=0x0, value=12
6590    ==========================================================================
6591*/
6592VOID RTMPIoctlMAC(
6593	IN	PRTMP_ADAPTER	pAdapter,
6594	IN	struct iwreq	*wrq)
6595{
6596	CHAR				*this_char;
6597	CHAR				*value;
6598	INT					j = 0, k = 0;
6599	CHAR				msg[1024];
6600	CHAR				arg[255];
6601	ULONG				macAddr = 0;
6602	UCHAR				temp[16], temp2[16];
6603	UINT32				macValue = 0;
6604	INT					Status;
6605
6606
6607	memset(msg, 0x00, 1024);
6608	if (wrq->u.data.length > 1) //No parameters.
6609	{
6610	    Status = copy_from_user(arg, wrq->u.data.pointer, (wrq->u.data.length > 255) ? 255 : wrq->u.data.length);
6611		sprintf(msg, "\n");
6612
6613		//Parsing Read or Write
6614	    this_char = arg;
6615		if (!*this_char)
6616			goto next;
6617
6618		if ((value = rtstrchr(this_char, '=')) != NULL)
6619			*value++ = 0;
6620
6621		if (!value || !*value)
6622		{ //Read
6623			// Sanity check
6624			if(strlen(this_char) > 4)
6625				goto next;
6626
6627			j = strlen(this_char);
6628			while(j-- > 0)
6629			{
6630				if(this_char[j] > 'f' || this_char[j] < '0')
6631					return;
6632			}
6633
6634			// Mac Addr
6635			k = j = strlen(this_char);
6636			while(j-- > 0)
6637			{
6638				this_char[4-k+j] = this_char[j];
6639			}
6640
6641			while(k < 4)
6642				this_char[3-k++]='0';
6643			this_char[4]='\0';
6644
6645			if(strlen(this_char) == 4)
6646			{
6647				AtoH(this_char, temp, 2);
6648				macAddr = *temp*256 + temp[1];
6649				if (macAddr < 0xFFFF)
6650				{
6651					RTMP_IO_READ32(pAdapter, macAddr, &macValue);
6652					DBGPRINT(RT_DEBUG_TRACE, ("MacAddr=%lx, MacValue=%x\n", macAddr, macValue));
6653					sprintf(msg+strlen(msg), "[0x%08lX]:%08X  ", macAddr , macValue);
6654				}
6655				else
6656				{//Invalid parametes, so default printk all bbp
6657					goto next;
6658				}
6659			}
6660		}
6661		else
6662		{ //Write
6663			memcpy(&temp2, value, strlen(value));
6664			temp2[strlen(value)] = '\0';
6665
6666			// Sanity check
6667			if((strlen(this_char) > 4) || strlen(temp2) > 8)
6668				goto next;
6669
6670			j = strlen(this_char);
6671			while(j-- > 0)
6672			{
6673				if(this_char[j] > 'f' || this_char[j] < '0')
6674					return;
6675			}
6676
6677			j = strlen(temp2);
6678			while(j-- > 0)
6679			{
6680				if(temp2[j] > 'f' || temp2[j] < '0')
6681					return;
6682			}
6683
6684			//MAC Addr
6685			k = j = strlen(this_char);
6686			while(j-- > 0)
6687			{
6688				this_char[4-k+j] = this_char[j];
6689			}
6690
6691			while(k < 4)
6692				this_char[3-k++]='0';
6693			this_char[4]='\0';
6694
6695			//MAC value
6696			k = j = strlen(temp2);
6697			while(j-- > 0)
6698			{
6699				temp2[8-k+j] = temp2[j];
6700			}
6701
6702			while(k < 8)
6703				temp2[7-k++]='0';
6704			temp2[8]='\0';
6705
6706			{
6707				AtoH(this_char, temp, 2);
6708				macAddr = *temp*256 + temp[1];
6709
6710				AtoH(temp2, temp, 4);
6711				macValue = *temp*256*256*256 + temp[1]*256*256 + temp[2]*256 + temp[3];
6712
6713				// debug mode
6714				if (macAddr == (HW_DEBUG_SETTING_BASE + 4))
6715				{
6716					// 0x2bf4: byte0 non-zero: enable R17 tuning, 0: disable R17 tuning
6717                    if (macValue & 0x000000ff)
6718                    {
6719                        pAdapter->BbpTuning.bEnable = TRUE;
6720                        DBGPRINT(RT_DEBUG_TRACE,("turn on R17 tuning\n"));
6721                    }
6722                    else
6723                    {
6724                        UCHAR R66;
6725                        pAdapter->BbpTuning.bEnable = FALSE;
6726                        R66 = 0x26 + GET_LNA_GAIN(pAdapter);
6727#ifdef RALINK_ATE
6728						if (ATE_ON(pAdapter))
6729						{
6730							ATE_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R66, (0x26 + GET_LNA_GAIN(pAdapter)));
6731						}
6732						else
6733#endif // RALINK_ATE //
6734						RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R66, (0x26 + GET_LNA_GAIN(pAdapter)));
6735                        DBGPRINT(RT_DEBUG_TRACE,("turn off R17 tuning, restore to 0x%02x\n", R66));
6736                    }
6737					return;
6738				}
6739
6740				DBGPRINT(RT_DEBUG_TRACE, ("MacAddr=%02lx, MacValue=0x%x\n", macAddr, macValue));
6741
6742				RTMP_IO_WRITE32(pAdapter, macAddr, macValue);
6743				sprintf(msg+strlen(msg), "[0x%08lX]:%08X  ", macAddr, macValue);
6744			}
6745		}
6746	}
6747next:
6748	if(strlen(msg) == 1)
6749		sprintf(msg+strlen(msg), "===>Error command format!");
6750
6751	// Copy the information into the user buffer
6752	wrq->u.data.length = strlen(msg);
6753	Status = copy_to_user(wrq->u.data.pointer, msg, wrq->u.data.length);
6754
6755	DBGPRINT(RT_DEBUG_TRACE, ("<==RTMPIoctlMAC\n\n"));
6756}
6757
6758/*
6759    ==========================================================================
6760    Description:
6761        Read / Write E2PROM
6762    Arguments:
6763        pAdapter                    Pointer to our adapter
6764        wrq                         Pointer to the ioctl argument
6765
6766    Return Value:
6767        None
6768
6769    Note:
6770        Usage:
6771               1.) iwpriv ra0 e2p 0     	==> read E2PROM where Addr=0x0
6772               2.) iwpriv ra0 e2p 0=1234    ==> write E2PROM where Addr=0x0, value=1234
6773    ==========================================================================
6774*/
6775VOID RTMPIoctlE2PROM(
6776	IN	PRTMP_ADAPTER	pAdapter,
6777	IN	struct iwreq	*wrq)
6778{
6779	CHAR				*this_char;
6780	CHAR				*value;
6781	INT					j = 0, k = 0;
6782	CHAR				msg[1024];
6783	CHAR				arg[255];
6784	USHORT				eepAddr = 0;
6785	UCHAR				temp[16], temp2[16];
6786	USHORT				eepValue;
6787	int					Status;
6788
6789
6790	memset(msg, 0x00, 1024);
6791	if (wrq->u.data.length > 1) //No parameters.
6792	{
6793	    Status = copy_from_user(arg, wrq->u.data.pointer, (wrq->u.data.length > 255) ? 255 : wrq->u.data.length);
6794		sprintf(msg, "\n");
6795
6796	    //Parsing Read or Write
6797		this_char = arg;
6798
6799
6800		if (!*this_char)
6801			goto next;
6802
6803		if ((value = rtstrchr(this_char, '=')) != NULL)
6804			*value++ = 0;
6805
6806		if (!value || !*value)
6807		{ //Read
6808
6809			// Sanity check
6810			if(strlen(this_char) > 4)
6811				goto next;
6812
6813			j = strlen(this_char);
6814			while(j-- > 0)
6815			{
6816				if(this_char[j] > 'f' || this_char[j] < '0')
6817					return;
6818			}
6819
6820			// E2PROM addr
6821			k = j = strlen(this_char);
6822			while(j-- > 0)
6823			{
6824				this_char[4-k+j] = this_char[j];
6825			}
6826
6827			while(k < 4)
6828				this_char[3-k++]='0';
6829			this_char[4]='\0';
6830
6831			if(strlen(this_char) == 4)
6832			{
6833				AtoH(this_char, temp, 2);
6834				eepAddr = *temp*256 + temp[1];
6835				if (eepAddr < 0xFFFF)
6836				{
6837					RT28xx_EEPROM_READ16(pAdapter, eepAddr, eepValue);
6838					sprintf(msg+strlen(msg), "[0x%04X]:0x%04X  ", eepAddr , eepValue);
6839				}
6840				else
6841				{//Invalid parametes, so default printk all bbp
6842					goto next;
6843				}
6844			}
6845		}
6846		else
6847		{ //Write
6848			memcpy(&temp2, value, strlen(value));
6849			temp2[strlen(value)] = '\0';
6850
6851			// Sanity check
6852			if((strlen(this_char) > 4) || strlen(temp2) > 8)
6853				goto next;
6854
6855			j = strlen(this_char);
6856			while(j-- > 0)
6857			{
6858				if(this_char[j] > 'f' || this_char[j] < '0')
6859					return;
6860			}
6861			j = strlen(temp2);
6862			while(j-- > 0)
6863			{
6864				if(temp2[j] > 'f' || temp2[j] < '0')
6865					return;
6866			}
6867
6868			//MAC Addr
6869			k = j = strlen(this_char);
6870			while(j-- > 0)
6871			{
6872				this_char[4-k+j] = this_char[j];
6873			}
6874
6875			while(k < 4)
6876				this_char[3-k++]='0';
6877			this_char[4]='\0';
6878
6879			//MAC value
6880			k = j = strlen(temp2);
6881			while(j-- > 0)
6882			{
6883				temp2[4-k+j] = temp2[j];
6884			}
6885
6886			while(k < 4)
6887				temp2[3-k++]='0';
6888			temp2[4]='\0';
6889
6890			AtoH(this_char, temp, 2);
6891			eepAddr = *temp*256 + temp[1];
6892
6893			AtoH(temp2, temp, 2);
6894			eepValue = *temp*256 + temp[1];
6895
6896			RT28xx_EEPROM_WRITE16(pAdapter, eepAddr, eepValue);
6897			sprintf(msg+strlen(msg), "[0x%02X]:%02X  ", eepAddr, eepValue);
6898		}
6899	}
6900next:
6901	if(strlen(msg) == 1)
6902		sprintf(msg+strlen(msg), "===>Error command format!");
6903
6904
6905	// Copy the information into the user buffer
6906	wrq->u.data.length = strlen(msg);
6907	Status = copy_to_user(wrq->u.data.pointer, msg, wrq->u.data.length);
6908
6909	DBGPRINT(RT_DEBUG_TRACE, ("<==RTMPIoctlE2PROM\n"));
6910}
6911#endif // DBG //
6912
6913
6914
6915
6916INT Set_TGnWifiTest_Proc(
6917    IN  PRTMP_ADAPTER   pAd,
6918    IN  PUCHAR          arg)
6919{
6920    if (simple_strtol(arg, 0, 10) == 0)
6921        pAd->StaCfg.bTGnWifiTest = FALSE;
6922    else
6923        pAd->StaCfg.bTGnWifiTest = TRUE;
6924
6925    DBGPRINT(RT_DEBUG_TRACE, ("IF Set_TGnWifiTest_Proc::(bTGnWifiTest=%d)\n", pAd->StaCfg.bTGnWifiTest));
6926	return TRUE;
6927}
6928
6929INT Set_LongRetryLimit_Proc(
6930	IN	PRTMP_ADAPTER	pAdapter,
6931	IN	PUCHAR			arg)
6932{
6933	TX_RTY_CFG_STRUC	tx_rty_cfg;
6934	UCHAR				LongRetryLimit = (UCHAR)simple_strtol(arg, 0, 10);
6935
6936	RTMP_IO_READ32(pAdapter, TX_RTY_CFG, &tx_rty_cfg.word);
6937	tx_rty_cfg.field.LongRtyLimit = LongRetryLimit;
6938	RTMP_IO_WRITE32(pAdapter, TX_RTY_CFG, tx_rty_cfg.word);
6939	DBGPRINT(RT_DEBUG_TRACE, ("IF Set_LongRetryLimit_Proc::(tx_rty_cfg=0x%x)\n", tx_rty_cfg.word));
6940	return TRUE;
6941}
6942
6943INT Set_ShortRetryLimit_Proc(
6944	IN	PRTMP_ADAPTER	pAdapter,
6945	IN	PUCHAR			arg)
6946{
6947	TX_RTY_CFG_STRUC	tx_rty_cfg;
6948	UCHAR				ShortRetryLimit = (UCHAR)simple_strtol(arg, 0, 10);
6949
6950	RTMP_IO_READ32(pAdapter, TX_RTY_CFG, &tx_rty_cfg.word);
6951	tx_rty_cfg.field.ShortRtyLimit = ShortRetryLimit;
6952	RTMP_IO_WRITE32(pAdapter, TX_RTY_CFG, tx_rty_cfg.word);
6953	DBGPRINT(RT_DEBUG_TRACE, ("IF Set_ShortRetryLimit_Proc::(tx_rty_cfg=0x%x)\n", tx_rty_cfg.word));
6954	return TRUE;
6955}
6956
6957#ifdef EXT_BUILD_CHANNEL_LIST
6958INT Set_Ieee80211dClientMode_Proc(
6959    IN  PRTMP_ADAPTER   pAdapter,
6960    IN  PUCHAR          arg)
6961{
6962    if (simple_strtol(arg, 0, 10) == 0)
6963        pAdapter->StaCfg.IEEE80211dClientMode = Rt802_11_D_None;
6964    else if (simple_strtol(arg, 0, 10) == 1)
6965        pAdapter->StaCfg.IEEE80211dClientMode = Rt802_11_D_Flexible;
6966    else if (simple_strtol(arg, 0, 10) == 2)
6967        pAdapter->StaCfg.IEEE80211dClientMode = Rt802_11_D_Strict;
6968    else
6969        return FALSE;
6970
6971    DBGPRINT(RT_DEBUG_TRACE, ("Set_Ieee802dMode_Proc::(IEEEE0211dMode=%d)\n", pAdapter->StaCfg.IEEE80211dClientMode));
6972    return TRUE;
6973}
6974#endif // EXT_BUILD_CHANNEL_LIST //
6975
6976#ifdef CARRIER_DETECTION_SUPPORT
6977INT Set_CarrierDetect_Proc(
6978    IN  PRTMP_ADAPTER   pAd,
6979    IN  PUCHAR          arg)
6980{
6981    if (simple_strtol(arg, 0, 10) == 0)
6982        pAd->CommonCfg.CarrierDetect.Enable = FALSE;
6983    else
6984        pAd->CommonCfg.CarrierDetect.Enable = TRUE;
6985
6986    DBGPRINT(RT_DEBUG_TRACE, ("IF Set_CarrierDetect_Proc::(CarrierDetect.Enable=%d)\n", pAd->CommonCfg.CarrierDetect.Enable));
6987	return TRUE;
6988}
6989#endif // CARRIER_DETECTION_SUPPORT //
6990
6991
6992INT	Show_Adhoc_MacTable_Proc(
6993	IN	PRTMP_ADAPTER	pAd,
6994	IN	PCHAR			extra)
6995{
6996	INT i;
6997
6998	sprintf(extra, "\n");
6999
7000#ifdef DOT11_N_SUPPORT
7001	sprintf(extra, "%sHT Operating Mode : %d\n", extra, pAd->CommonCfg.AddHTInfo.AddHtInfo2.OperaionMode);
7002#endif // DOT11_N_SUPPORT //
7003
7004	sprintf(extra, "%s\n%-19s%-4s%-4s%-7s%-7s%-7s%-10s%-6s%-6s%-6s%-6s\n", extra,
7005			"MAC", "AID", "BSS", "RSSI0", "RSSI1", "RSSI2", "PhMd", "BW", "MCS", "SGI", "STBC");
7006
7007	for (i=1; i<MAX_LEN_OF_MAC_TABLE; i++)
7008	{
7009		PMAC_TABLE_ENTRY pEntry = &pAd->MacTab.Content[i];
7010
7011		if (strlen(extra) > (IW_PRIV_SIZE_MASK - 30))
7012		    break;
7013		if ((pEntry->ValidAsCLI || pEntry->ValidAsApCli) && (pEntry->Sst == SST_ASSOC))
7014		{
7015			sprintf(extra, "%s%02X:%02X:%02X:%02X:%02X:%02X  ", extra,
7016				pEntry->Addr[0], pEntry->Addr[1], pEntry->Addr[2],
7017				pEntry->Addr[3], pEntry->Addr[4], pEntry->Addr[5]);
7018			sprintf(extra, "%s%-4d", extra, (int)pEntry->Aid);
7019			sprintf(extra, "%s%-4d", extra, (int)pEntry->apidx);
7020			sprintf(extra, "%s%-7d", extra, pEntry->RssiSample.AvgRssi0);
7021			sprintf(extra, "%s%-7d", extra, pEntry->RssiSample.AvgRssi1);
7022			sprintf(extra, "%s%-7d", extra, pEntry->RssiSample.AvgRssi2);
7023			sprintf(extra, "%s%-10s", extra, GetPhyMode(pEntry->HTPhyMode.field.MODE));
7024			sprintf(extra, "%s%-6s", extra, GetBW(pEntry->HTPhyMode.field.BW));
7025			sprintf(extra, "%s%-6d", extra, pEntry->HTPhyMode.field.MCS);
7026			sprintf(extra, "%s%-6d", extra, pEntry->HTPhyMode.field.ShortGI);
7027			sprintf(extra, "%s%-6d", extra, pEntry->HTPhyMode.field.STBC);
7028			sprintf(extra, "%s%-10d, %d, %d%%\n", extra, pEntry->DebugFIFOCount, pEntry->DebugTxCount,
7029						(pEntry->DebugTxCount) ? ((pEntry->DebugTxCount-pEntry->DebugFIFOCount)*100/pEntry->DebugTxCount) : 0);
7030			sprintf(extra, "%s\n", extra);
7031		}
7032	}
7033
7034	return TRUE;
7035}
7036
7037
7038