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