Merge branch 'topic/asoc' into for-linus
[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, "%s%02x", custom, 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, "%s%02x", custom, 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, "%s\n%02X:%02X:%02X:%02X:%02X:%02X (Aid = %d) (AP) -\n",
2026                 pOutBuf,
2027                                 pEntry->Addr[0], pEntry->Addr[1], pEntry->Addr[2],
2028                                 pEntry->Addr[3], pEntry->Addr[4], pEntry->Addr[5], pEntry->Aid);
2029
2030                         sprintf(pOutBuf, "%s[Recipient]\n", pOutBuf);
2031                         for (j=0; j < NUM_OF_TID; j++)
2032                         {
2033                                 if (pEntry->BARecWcidArray[j] != 0)
2034                                 {
2035                                         pRecBAEntry =&pAd->BATable.BARecEntry[pEntry->BARecWcidArray[j]];
2036                                         sprintf(pOutBuf, "%sTID=%d, BAWinSize=%d, LastIndSeq=%d, ReorderingPkts=%d\n", pOutBuf, j, pRecBAEntry->BAWinSize, pRecBAEntry->LastIndSeq, pRecBAEntry->list.qlen);
2037                                 }
2038                         }
2039                         sprintf(pOutBuf, "%s\n", pOutBuf);
2040
2041                         sprintf(pOutBuf, "%s[Originator]\n", pOutBuf);
2042                         for (j=0; j < NUM_OF_TID; j++)
2043                         {
2044                                 if (pEntry->BAOriWcidArray[j] != 0)
2045                                 {
2046                                         pOriBAEntry =&pAd->BATable.BAOriEntry[pEntry->BAOriWcidArray[j]];
2047                                         sprintf(pOutBuf, "%sTID=%d, BAWinSize=%d, StartSeq=%d, CurTxSeq=%d\n", pOutBuf, j, pOriBAEntry->BAWinSize, pOriBAEntry->Sequence, pEntry->TxSeq[j]);
2048                                 }
2049                         }
2050                         sprintf(pOutBuf, "%s\n\n", pOutBuf);
2051                 }
2052         if (strlen(pOutBuf) > (IW_PRIV_SIZE_MASK - 30))
2053                 break;
2054         }
2055
2056         return;
2057 }
2058 #endif // DOT11_N_SUPPORT //
2059
2060 static int
2061 rt_private_show(struct net_device *dev, struct iw_request_info *info,
2062                 struct iw_point *wrq, char *extra)
2063 {
2064     INT                         Status = 0;
2065     VIRTUAL_ADAPTER     *pVirtualAd = NULL;
2066     PRTMP_ADAPTER   pAd;
2067         POS_COOKIE              pObj;
2068     u32             subcmd = wrq->flags;
2069
2070         if (dev->priv_flags == INT_MAIN)
2071                 pAd = dev->ml_priv;
2072         else
2073         {
2074                 pVirtualAd = dev->ml_priv;
2075                 pAd = pVirtualAd->RtmpDev->ml_priv;
2076         }
2077         pObj = (POS_COOKIE) pAd->OS_Cookie;
2078
2079         if (pAd == NULL)
2080         {
2081                 /* if 1st open fail, pAd will be free;
2082                    So the net_dev->ml_priv will be NULL in 2rd open */
2083                 return -ENETDOWN;
2084         }
2085
2086     if (extra == NULL)
2087     {
2088         wrq->length = 0;
2089         return -EIO;
2090     }
2091     memset(extra, 0x00, IW_PRIV_SIZE_MASK);
2092
2093         {
2094                 pObj->ioctl_if_type = INT_MAIN;
2095         pObj->ioctl_if = MAIN_MBSSID;
2096         }
2097
2098     switch(subcmd)
2099     {
2100
2101         case SHOW_CONN_STATUS:
2102             if (MONITOR_ON(pAd))
2103             {
2104 #ifdef DOT11_N_SUPPORT
2105                 if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED &&
2106                     pAd->CommonCfg.RegTransmitSetting.field.BW)
2107                     sprintf(extra, "Monitor Mode(CentralChannel %d)\n", pAd->CommonCfg.CentralChannel);
2108                 else
2109 #endif // DOT11_N_SUPPORT //
2110                     sprintf(extra, "Monitor Mode(Channel %d)\n", pAd->CommonCfg.Channel);
2111             }
2112             else
2113             {
2114                 if (pAd->IndicateMediaState == NdisMediaStateConnected)
2115                 {
2116                     if (INFRA_ON(pAd))
2117                     {
2118                     sprintf(extra, "Connected(AP: %s[%02X:%02X:%02X:%02X:%02X:%02X])\n",
2119                                     pAd->CommonCfg.Ssid,
2120                                     pAd->CommonCfg.Bssid[0],
2121                                     pAd->CommonCfg.Bssid[1],
2122                                     pAd->CommonCfg.Bssid[2],
2123                                     pAd->CommonCfg.Bssid[3],
2124                                     pAd->CommonCfg.Bssid[4],
2125                                     pAd->CommonCfg.Bssid[5]);
2126                         DBGPRINT(RT_DEBUG_TRACE ,("Ssid=%s ,Ssidlen = %d\n",pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen));
2127                 }
2128                     else if (ADHOC_ON(pAd))
2129                         sprintf(extra, "Connected\n");
2130                 }
2131                 else
2132                 {
2133                     sprintf(extra, "Disconnected\n");
2134                         DBGPRINT(RT_DEBUG_TRACE ,("ConnStatus is not connected\n"));
2135                 }
2136             }
2137             wrq->length = strlen(extra) + 1; // 1: size of '\0'
2138             break;
2139         case SHOW_DRVIER_VERION:
2140             sprintf(extra, "Driver version-%s, %s %s\n", STA_DRIVER_VERSION, __DATE__, __TIME__ );
2141             wrq->length = strlen(extra) + 1; // 1: size of '\0'
2142             break;
2143 #ifdef DOT11_N_SUPPORT
2144         case SHOW_BA_INFO:
2145             getBaInfo(pAd, extra);
2146             wrq->length = strlen(extra) + 1; // 1: size of '\0'
2147             break;
2148 #endif // DOT11_N_SUPPORT //
2149                 case SHOW_DESC_INFO:
2150                         {
2151                                 Show_DescInfo_Proc(pAd, NULL);
2152                                 wrq->length = 0; // 1: size of '\0'
2153                         }
2154                         break;
2155         case RAIO_OFF:
2156             if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
2157             {
2158                 sprintf(extra, "Scanning\n");
2159                 wrq->length = strlen(extra) + 1; // 1: size of '\0'
2160                 break;
2161             }
2162             pAd->StaCfg.bSwRadio = FALSE;
2163             if (pAd->StaCfg.bRadio != (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio))
2164             {
2165                 pAd->StaCfg.bRadio = (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio);
2166                 if (pAd->StaCfg.bRadio == FALSE)
2167                 {
2168                     MlmeRadioOff(pAd);
2169                     // Update extra information
2170                                         pAd->ExtraInfo = SW_RADIO_OFF;
2171                 }
2172             }
2173             sprintf(extra, "Radio Off\n");
2174             wrq->length = strlen(extra) + 1; // 1: size of '\0'
2175             break;
2176         case RAIO_ON:
2177             pAd->StaCfg.bSwRadio = TRUE;
2178             //if (pAd->StaCfg.bRadio != (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio))
2179             {
2180                 pAd->StaCfg.bRadio = (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio);
2181                 if (pAd->StaCfg.bRadio == TRUE)
2182                 {
2183                     MlmeRadioOn(pAd);
2184                     // Update extra information
2185                                         pAd->ExtraInfo = EXTRA_INFO_CLEAR;
2186                 }
2187             }
2188             sprintf(extra, "Radio On\n");
2189             wrq->length = strlen(extra) + 1; // 1: size of '\0'
2190             break;
2191
2192
2193 #ifdef QOS_DLS_SUPPORT
2194                 case SHOW_DLS_ENTRY_INFO:
2195                         {
2196                                 Set_DlsEntryInfo_Display_Proc(pAd, NULL);
2197                                 wrq->length = 0; // 1: size of '\0'
2198                         }
2199                         break;
2200 #endif // QOS_DLS_SUPPORT //
2201
2202                 case SHOW_CFG_VALUE:
2203                         {
2204                                 Status = RTMPShowCfgValue(pAd, wrq->pointer, extra);
2205                                 if (Status == 0)
2206                                         wrq->length = strlen(extra) + 1; // 1: size of '\0'
2207                         }
2208                         break;
2209         default:
2210             DBGPRINT(RT_DEBUG_TRACE, ("%s - unknow subcmd = %d\n", __func__, subcmd));
2211             break;
2212     }
2213
2214     return Status;
2215 }
2216
2217 #ifdef SIOCSIWMLME
2218 int rt_ioctl_siwmlme(struct net_device *dev,
2219                            struct iw_request_info *info,
2220                            union iwreq_data *wrqu,
2221                            char *extra)
2222 {
2223         PRTMP_ADAPTER   pAd = dev->ml_priv;
2224         struct iw_mlme *pMlme = (struct iw_mlme *)wrqu->data.pointer;
2225         MLME_QUEUE_ELEM                         MsgElem;
2226         MLME_DISASSOC_REQ_STRUCT        DisAssocReq;
2227         MLME_DEAUTH_REQ_STRUCT      DeAuthReq;
2228
2229         DBGPRINT(RT_DEBUG_TRACE, ("====> %s\n", __func__));
2230
2231         if (pMlme == NULL)
2232                 return -EINVAL;
2233
2234         switch(pMlme->cmd)
2235         {
2236 #ifdef IW_MLME_DEAUTH
2237                 case IW_MLME_DEAUTH:
2238                         DBGPRINT(RT_DEBUG_TRACE, ("====> %s - IW_MLME_DEAUTH\n", __func__));
2239                         COPY_MAC_ADDR(DeAuthReq.Addr, pAd->CommonCfg.Bssid);
2240                         DeAuthReq.Reason = pMlme->reason_code;
2241                         MsgElem.MsgLen = sizeof(MLME_DEAUTH_REQ_STRUCT);
2242                         NdisMoveMemory(MsgElem.Msg, &DeAuthReq, sizeof(MLME_DEAUTH_REQ_STRUCT));
2243                         MlmeDeauthReqAction(pAd, &MsgElem);
2244                         if (INFRA_ON(pAd))
2245                         {
2246                             LinkDown(pAd, FALSE);
2247                             pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
2248                         }
2249                         break;
2250 #endif // IW_MLME_DEAUTH //
2251 #ifdef IW_MLME_DISASSOC
2252                 case IW_MLME_DISASSOC:
2253                         DBGPRINT(RT_DEBUG_TRACE, ("====> %s - IW_MLME_DISASSOC\n", __func__));
2254                         COPY_MAC_ADDR(DisAssocReq.Addr, pAd->CommonCfg.Bssid);
2255                         DisAssocReq.Reason =  pMlme->reason_code;
2256
2257                         MsgElem.Machine = ASSOC_STATE_MACHINE;
2258                         MsgElem.MsgType = MT2_MLME_DISASSOC_REQ;
2259                         MsgElem.MsgLen = sizeof(MLME_DISASSOC_REQ_STRUCT);
2260                         NdisMoveMemory(MsgElem.Msg, &DisAssocReq, sizeof(MLME_DISASSOC_REQ_STRUCT));
2261
2262                         pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_DISASSOC;
2263                         MlmeDisassocReqAction(pAd, &MsgElem);
2264                         break;
2265 #endif // IW_MLME_DISASSOC //
2266                 default:
2267                         DBGPRINT(RT_DEBUG_TRACE, ("====> %s - Unknow Command\n", __func__));
2268                         break;
2269         }
2270
2271         return 0;
2272 }
2273 #endif // SIOCSIWMLME //
2274
2275 #if WIRELESS_EXT > 17
2276 int rt_ioctl_siwauth(struct net_device *dev,
2277                           struct iw_request_info *info,
2278                           union iwreq_data *wrqu, char *extra)
2279 {
2280         PRTMP_ADAPTER   pAdapter = dev->ml_priv;
2281         struct iw_param *param = &wrqu->param;
2282
2283     //check if the interface is down
2284         if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
2285         {
2286                 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
2287         return -ENETDOWN;
2288         }
2289         switch (param->flags & IW_AUTH_INDEX) {
2290         case IW_AUTH_WPA_VERSION:
2291             if (param->value == IW_AUTH_WPA_VERSION_WPA)
2292             {
2293                 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPAPSK;
2294                                 if (pAdapter->StaCfg.BssType == BSS_ADHOC)
2295                                         pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPANone;
2296             }
2297             else if (param->value == IW_AUTH_WPA_VERSION_WPA2)
2298                 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPA2PSK;
2299
2300             DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_WPA_VERSION - param->value = %d!\n", __func__, param->value));
2301             break;
2302         case IW_AUTH_CIPHER_PAIRWISE:
2303             if (param->value == IW_AUTH_CIPHER_NONE)
2304             {
2305                 pAdapter->StaCfg.WepStatus = Ndis802_11WEPDisabled;
2306                 pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
2307                 pAdapter->StaCfg.PairCipher = Ndis802_11WEPDisabled;
2308             }
2309             else if (param->value == IW_AUTH_CIPHER_WEP40 ||
2310                      param->value == IW_AUTH_CIPHER_WEP104)
2311             {
2312                 pAdapter->StaCfg.WepStatus = Ndis802_11WEPEnabled;
2313                 pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
2314                 pAdapter->StaCfg.PairCipher = Ndis802_11WEPEnabled;
2315 #ifdef WPA_SUPPLICANT_SUPPORT
2316                 pAdapter->StaCfg.IEEE8021X = FALSE;
2317 #endif // WPA_SUPPLICANT_SUPPORT //
2318             }
2319             else if (param->value == IW_AUTH_CIPHER_TKIP)
2320             {
2321                 pAdapter->StaCfg.WepStatus = Ndis802_11Encryption2Enabled;
2322                 pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
2323                 pAdapter->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
2324             }
2325             else if (param->value == IW_AUTH_CIPHER_CCMP)
2326             {
2327                 pAdapter->StaCfg.WepStatus = Ndis802_11Encryption3Enabled;
2328                 pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
2329                 pAdapter->StaCfg.PairCipher = Ndis802_11Encryption3Enabled;
2330             }
2331             DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_CIPHER_PAIRWISE - param->value = %d!\n", __func__, param->value));
2332             break;
2333         case IW_AUTH_CIPHER_GROUP:
2334             if (param->value == IW_AUTH_CIPHER_NONE)
2335             {
2336                 pAdapter->StaCfg.GroupCipher = Ndis802_11WEPDisabled;
2337             }
2338             else if (param->value == IW_AUTH_CIPHER_WEP40 ||
2339                      param->value == IW_AUTH_CIPHER_WEP104)
2340             {
2341                 pAdapter->StaCfg.GroupCipher = Ndis802_11WEPEnabled;
2342             }
2343             else if (param->value == IW_AUTH_CIPHER_TKIP)
2344             {
2345                 pAdapter->StaCfg.GroupCipher = Ndis802_11Encryption2Enabled;
2346             }
2347             else if (param->value == IW_AUTH_CIPHER_CCMP)
2348             {
2349                 pAdapter->StaCfg.GroupCipher = Ndis802_11Encryption3Enabled;
2350             }
2351             DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_CIPHER_GROUP - param->value = %d!\n", __func__, param->value));
2352             break;
2353         case IW_AUTH_KEY_MGMT:
2354             if (param->value == IW_AUTH_KEY_MGMT_802_1X)
2355             {
2356                 if (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK)
2357                 {
2358                     pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPA;
2359 #ifdef WPA_SUPPLICANT_SUPPORT
2360                     pAdapter->StaCfg.IEEE8021X = FALSE;
2361 #endif // WPA_SUPPLICANT_SUPPORT //
2362                 }
2363                 else if (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)
2364                 {
2365                     pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPA2;
2366 #ifdef WPA_SUPPLICANT_SUPPORT
2367                     pAdapter->StaCfg.IEEE8021X = FALSE;
2368 #endif // WPA_SUPPLICANT_SUPPORT //
2369                 }
2370 #ifdef WPA_SUPPLICANT_SUPPORT
2371                 else
2372                     // WEP 1x
2373                     pAdapter->StaCfg.IEEE8021X = TRUE;
2374 #endif // WPA_SUPPLICANT_SUPPORT //
2375             }
2376             else if (param->value == 0)
2377             {
2378                                 STA_PORT_SECURED(pAdapter);
2379             }
2380             DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_KEY_MGMT - param->value = %d!\n", __func__, param->value));
2381             break;
2382         case IW_AUTH_RX_UNENCRYPTED_EAPOL:
2383             break;
2384         case IW_AUTH_PRIVACY_INVOKED:
2385             DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_PRIVACY_INVOKED - param->value = %d!\n", __func__, param->value));
2386                 break;
2387         case IW_AUTH_DROP_UNENCRYPTED:
2388             if (param->value != 0)
2389                 pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
2390                         else
2391                         {
2392                                 STA_PORT_SECURED(pAdapter);
2393                         }
2394             DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_WPA_VERSION - param->value = %d!\n", __func__, param->value));
2395                 break;
2396         case IW_AUTH_80211_AUTH_ALG:
2397                         if (param->value & IW_AUTH_ALG_SHARED_KEY)
2398             {
2399                                 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeShared;
2400                         }
2401             else if (param->value & IW_AUTH_ALG_OPEN_SYSTEM)
2402             {
2403                                 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
2404                         }
2405             else
2406                                 return -EINVAL;
2407             DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_80211_AUTH_ALG - param->value = %d!\n", __func__, param->value));
2408                         break;
2409         case IW_AUTH_WPA_ENABLED:
2410                 DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_WPA_ENABLED - Driver supports WPA!(param->value = %d)\n", __func__, param->value));
2411                 break;
2412         default:
2413                 return -EOPNOTSUPP;
2414 }
2415
2416         return 0;
2417 }
2418
2419 int rt_ioctl_giwauth(struct net_device *dev,
2420                                struct iw_request_info *info,
2421                                union iwreq_data *wrqu, char *extra)
2422 {
2423         PRTMP_ADAPTER   pAdapter = dev->ml_priv;
2424         struct iw_param *param = &wrqu->param;
2425
2426     //check if the interface is down
2427         if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
2428     {
2429                 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
2430         return -ENETDOWN;
2431     }
2432
2433         switch (param->flags & IW_AUTH_INDEX) {
2434         case IW_AUTH_DROP_UNENCRYPTED:
2435         param->value = (pAdapter->StaCfg.WepStatus == Ndis802_11WEPDisabled) ? 0 : 1;
2436                 break;
2437
2438         case IW_AUTH_80211_AUTH_ALG:
2439         param->value = (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeShared) ? IW_AUTH_ALG_SHARED_KEY : IW_AUTH_ALG_OPEN_SYSTEM;
2440                 break;
2441
2442         case IW_AUTH_WPA_ENABLED:
2443                 param->value = (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA) ? 1 : 0;
2444                 break;
2445
2446         default:
2447                 return -EOPNOTSUPP;
2448         }
2449     DBGPRINT(RT_DEBUG_TRACE, ("rt_ioctl_giwauth::param->value = %d!\n", param->value));
2450         return 0;
2451 }
2452
2453 void fnSetCipherKey(
2454     IN  PRTMP_ADAPTER   pAdapter,
2455     IN  INT             keyIdx,
2456     IN  UCHAR           CipherAlg,
2457     IN  BOOLEAN         bGTK,
2458     IN  struct iw_encode_ext *ext)
2459 {
2460         RTMP_CLEAR_PSFLAG(pAdapter, fRTMP_PS_CAN_GO_SLEEP);
2461         if (RTMP_TEST_PSFLAG(pAdapter, fRTMP_PS_SET_PCI_CLK_OFF_COMMAND))
2462         {
2463                 if (pAdapter->StaCfg.bRadio == FALSE)
2464                 {
2465                         RTMP_SET_PSFLAG(pAdapter, fRTMP_PS_CAN_GO_SLEEP);
2466                         return;
2467                 }
2468                 DBGPRINT(RT_DEBUG_TRACE,("RTMPWPAAddKeyProc1==>\n"));
2469                 RTMPPCIeLinkCtrlValueRestore(pAdapter, RESTORE_HALT);
2470                 RTMPusecDelay(6000);
2471                 pAdapter->bPCIclkOff = FALSE;
2472         }
2473
2474     NdisZeroMemory(&pAdapter->SharedKey[BSS0][keyIdx], sizeof(CIPHER_KEY));
2475     pAdapter->SharedKey[BSS0][keyIdx].KeyLen = LEN_TKIP_EK;
2476     NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].Key, ext->key, LEN_TKIP_EK);
2477     NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].TxMic, ext->key + LEN_TKIP_EK, LEN_TKIP_TXMICK);
2478     NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].RxMic, ext->key + LEN_TKIP_EK + LEN_TKIP_TXMICK, LEN_TKIP_RXMICK);
2479     pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = CipherAlg;
2480
2481     // Update group key information to ASIC Shared Key Table
2482         AsicAddSharedKeyEntry(pAdapter,
2483                                                   BSS0,
2484                                                   keyIdx,
2485                                                   pAdapter->SharedKey[BSS0][keyIdx].CipherAlg,
2486                                                   pAdapter->SharedKey[BSS0][keyIdx].Key,
2487                                                   pAdapter->SharedKey[BSS0][keyIdx].TxMic,
2488                                                   pAdapter->SharedKey[BSS0][keyIdx].RxMic);
2489
2490     if (bGTK)
2491         // Update ASIC WCID attribute table and IVEIV table
2492         RTMPAddWcidAttributeEntry(pAdapter,
2493                                                           BSS0,
2494                                                           keyIdx,
2495                                                           pAdapter->SharedKey[BSS0][keyIdx].CipherAlg,
2496                                                           NULL);
2497     else
2498         // Update ASIC WCID attribute table and IVEIV table
2499         RTMPAddWcidAttributeEntry(pAdapter,
2500                                                           BSS0,
2501                                                           keyIdx,
2502                                                           pAdapter->SharedKey[BSS0][keyIdx].CipherAlg,
2503                                                           &pAdapter->MacTab.Content[BSSID_WCID]);
2504
2505         RTMP_SET_PSFLAG(pAdapter, fRTMP_PS_CAN_GO_SLEEP);
2506 }
2507
2508 int rt_ioctl_siwencodeext(struct net_device *dev,
2509                            struct iw_request_info *info,
2510                            union iwreq_data *wrqu,
2511                            char *extra)
2512                         {
2513     PRTMP_ADAPTER   pAdapter = dev->ml_priv;
2514         struct iw_point *encoding = &wrqu->encoding;
2515         struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
2516     int keyIdx, alg = ext->alg;
2517
2518     //check if the interface is down
2519         if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
2520         {
2521                 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
2522         return -ENETDOWN;
2523         }
2524
2525     if (encoding->flags & IW_ENCODE_DISABLED)
2526         {
2527         keyIdx = (encoding->flags & IW_ENCODE_INDEX) - 1;
2528         // set BSSID wcid entry of the Pair-wise Key table as no-security mode
2529             AsicRemovePairwiseKeyEntry(pAdapter, BSS0, BSSID_WCID);
2530         pAdapter->SharedKey[BSS0][keyIdx].KeyLen = 0;
2531                 pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = CIPHER_NONE;
2532                 AsicRemoveSharedKeyEntry(pAdapter, 0, (UCHAR)keyIdx);
2533         NdisZeroMemory(&pAdapter->SharedKey[BSS0][keyIdx], sizeof(CIPHER_KEY));
2534         DBGPRINT(RT_DEBUG_TRACE, ("%s::Remove all keys!(encoding->flags = %x)\n", __func__, encoding->flags));
2535     }
2536                                         else
2537     {
2538         // Get Key Index and convet to our own defined key index
2539         keyIdx = (encoding->flags & IW_ENCODE_INDEX) - 1;
2540         if((keyIdx < 0) || (keyIdx >= NR_WEP_KEYS))
2541                 return -EINVAL;
2542
2543         if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
2544         {
2545             pAdapter->StaCfg.DefaultKeyId = keyIdx;
2546             DBGPRINT(RT_DEBUG_TRACE, ("%s::DefaultKeyId = %d\n", __func__, pAdapter->StaCfg.DefaultKeyId));
2547         }
2548
2549         switch (alg) {
2550                 case IW_ENCODE_ALG_NONE:
2551                 DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_ENCODE_ALG_NONE\n", __func__));
2552                         break;
2553                 case IW_ENCODE_ALG_WEP:
2554                 DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_ENCODE_ALG_WEP - ext->key_len = %d, keyIdx = %d\n", __func__, ext->key_len, keyIdx));
2555                         if (ext->key_len == MAX_WEP_KEY_SIZE)
2556                 {
2557                                 pAdapter->SharedKey[BSS0][keyIdx].KeyLen = MAX_WEP_KEY_SIZE;
2558                     pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = CIPHER_WEP128;
2559                                 }
2560                         else if (ext->key_len == MIN_WEP_KEY_SIZE)
2561                 {
2562                     pAdapter->SharedKey[BSS0][keyIdx].KeyLen = MIN_WEP_KEY_SIZE;
2563                     pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = CIPHER_WEP64;
2564                         }
2565                         else
2566                     return -EINVAL;
2567
2568                 NdisZeroMemory(pAdapter->SharedKey[BSS0][keyIdx].Key,  16);
2569                             NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].Key, ext->key, ext->key_len);
2570
2571                                 if (pAdapter->StaCfg.GroupCipher == Ndis802_11GroupWEP40Enabled ||
2572                                         pAdapter->StaCfg.GroupCipher == Ndis802_11GroupWEP104Enabled)
2573                                 {
2574                                         // Set Group key material to Asic
2575                                         AsicAddSharedKeyEntry(pAdapter, BSS0, keyIdx, pAdapter->SharedKey[BSS0][keyIdx].CipherAlg, pAdapter->SharedKey[BSS0][keyIdx].Key, NULL, NULL);
2576
2577                                         // Update WCID attribute table and IVEIV table for this group key table
2578                                         RTMPAddWcidAttributeEntry(pAdapter, BSS0, keyIdx, pAdapter->SharedKey[BSS0][keyIdx].CipherAlg, NULL);
2579
2580                                         STA_PORT_SECURED(pAdapter);
2581
2582                                 // Indicate Connected for GUI
2583                                 pAdapter->IndicateMediaState = NdisMediaStateConnected;
2584                                 }
2585                         break;
2586             case IW_ENCODE_ALG_TKIP:
2587                 DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_ENCODE_ALG_TKIP - keyIdx = %d, ext->key_len = %d\n", __func__, keyIdx, ext->key_len));
2588                 if (ext->key_len == 32)
2589                 {
2590                     if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
2591                     {
2592                         fnSetCipherKey(pAdapter, keyIdx, CIPHER_TKIP, FALSE, ext);
2593                         if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA2)
2594                         {
2595                             STA_PORT_SECURED(pAdapter);
2596                         }
2597                 }
2598                     else if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY)
2599                     {
2600                         fnSetCipherKey(pAdapter, keyIdx, CIPHER_TKIP, TRUE, ext);
2601
2602                         // set 802.1x port control
2603                         STA_PORT_SECURED(pAdapter);
2604                     }
2605                 }
2606                 else
2607                     return -EINVAL;
2608                 break;
2609             case IW_ENCODE_ALG_CCMP:
2610                 if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
2611                 {
2612                     fnSetCipherKey(pAdapter, keyIdx, CIPHER_AES, FALSE, ext);
2613                     if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA2)
2614                         STA_PORT_SECURED(pAdapter);
2615                 }
2616                 else if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY)
2617                 {
2618                     fnSetCipherKey(pAdapter, keyIdx, CIPHER_AES, TRUE, ext);
2619
2620                     // set 802.1x port control
2621                         STA_PORT_SECURED(pAdapter);
2622                 }
2623                 break;
2624                 default:
2625                         return -EINVAL;
2626                 }
2627     }
2628
2629     return 0;
2630 }
2631
2632 int
2633 rt_ioctl_giwencodeext(struct net_device *dev,
2634                           struct iw_request_info *info,
2635                           union iwreq_data *wrqu, char *extra)
2636 {
2637         PRTMP_ADAPTER pAd = dev->ml_priv;
2638         PCHAR pKey = NULL;
2639         struct iw_point *encoding = &wrqu->encoding;
2640         struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
2641         int idx, max_key_len;
2642
2643         DBGPRINT(RT_DEBUG_TRACE ,("===> rt_ioctl_giwencodeext\n"));
2644
2645         max_key_len = encoding->length - sizeof(*ext);
2646         if (max_key_len < 0)
2647                 return -EINVAL;
2648
2649         idx = encoding->flags & IW_ENCODE_INDEX;
2650         if (idx)
2651         {
2652                 if (idx < 1 || idx > 4)
2653                         return -EINVAL;
2654                 idx--;
2655
2656                 if ((pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) ||
2657                         (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled))
2658                 {
2659                         if (idx != pAd->StaCfg.DefaultKeyId)
2660                         {
2661                                 ext->key_len = 0;
2662                                 return 0;
2663                         }
2664                 }
2665         }
2666         else
2667                 idx = pAd->StaCfg.DefaultKeyId;
2668
2669         encoding->flags = idx + 1;
2670         memset(ext, 0, sizeof(*ext));
2671
2672         ext->key_len = 0;
2673         switch(pAd->StaCfg.WepStatus) {
2674                 case Ndis802_11WEPDisabled:
2675                         ext->alg = IW_ENCODE_ALG_NONE;
2676                         encoding->flags |= IW_ENCODE_DISABLED;
2677                         break;
2678                 case Ndis802_11WEPEnabled:
2679                         ext->alg = IW_ENCODE_ALG_WEP;
2680                         if (pAd->SharedKey[BSS0][idx].KeyLen > max_key_len)
2681                                 return -E2BIG;
2682                         else
2683                         {
2684                                 ext->key_len = pAd->SharedKey[BSS0][idx].KeyLen;
2685                                 pKey = &(pAd->SharedKey[BSS0][idx].Key[0]);
2686                         }
2687                         break;
2688                 case Ndis802_11Encryption2Enabled:
2689                 case Ndis802_11Encryption3Enabled:
2690                         if (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled)
2691                                 ext->alg = IW_ENCODE_ALG_TKIP;
2692                         else
2693                                 ext->alg = IW_ENCODE_ALG_CCMP;
2694
2695                         if (max_key_len < 32)
2696                                 return -E2BIG;
2697                         else
2698                         {
2699                                 ext->key_len = 32;
2700                                 pKey = &pAd->StaCfg.PMK[0];
2701                         }
2702                         break;
2703                 default:
2704                         return -EINVAL;
2705         }
2706
2707         if (ext->key_len && pKey)
2708         {
2709                 encoding->flags |= IW_ENCODE_ENABLED;
2710                 memcpy(ext->key, pKey, ext->key_len);
2711         }
2712
2713         return 0;
2714 }
2715
2716 #ifdef SIOCSIWGENIE
2717 int rt_ioctl_siwgenie(struct net_device *dev,
2718                           struct iw_request_info *info,
2719                           union iwreq_data *wrqu, char *extra)
2720 {
2721         PRTMP_ADAPTER   pAd = dev->ml_priv;
2722
2723         if (wrqu->data.length > MAX_LEN_OF_RSNIE ||
2724             (wrqu->data.length && extra == NULL))
2725                 return -EINVAL;
2726
2727         if (wrqu->data.length)
2728         {
2729                 pAd->StaCfg.RSNIE_Len = wrqu->data.length;
2730                 NdisMoveMemory(&pAd->StaCfg.RSN_IE[0], extra, pAd->StaCfg.RSNIE_Len);
2731         }
2732         else
2733         {
2734                 pAd->StaCfg.RSNIE_Len = 0;
2735                 NdisZeroMemory(&pAd->StaCfg.RSN_IE[0], MAX_LEN_OF_RSNIE);
2736         }
2737
2738         return 0;
2739 }
2740 #endif // SIOCSIWGENIE //
2741
2742 int rt_ioctl_giwgenie(struct net_device *dev,
2743                                struct iw_request_info *info,
2744                                union iwreq_data *wrqu, char *extra)
2745 {
2746         PRTMP_ADAPTER   pAd = dev->ml_priv;
2747
2748         if ((pAd->StaCfg.RSNIE_Len == 0) ||
2749                 (pAd->StaCfg.AuthMode < Ndis802_11AuthModeWPA))
2750         {
2751                 wrqu->data.length = 0;
2752                 return 0;
2753         }
2754
2755 #ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
2756 #ifdef SIOCSIWGENIE
2757         if (pAd->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_ENABLE)
2758         {
2759         if (wrqu->data.length < pAd->StaCfg.RSNIE_Len)
2760                 return -E2BIG;
2761
2762         wrqu->data.length = pAd->StaCfg.RSNIE_Len;
2763         memcpy(extra, &pAd->StaCfg.RSN_IE[0], pAd->StaCfg.RSNIE_Len);
2764         }
2765         else
2766 #endif // SIOCSIWGENIE //
2767 #endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
2768         {
2769                 UCHAR RSNIe = IE_WPA;
2770
2771                 if (wrqu->data.length < (pAd->StaCfg.RSNIE_Len + 2)) // ID, Len
2772                         return -E2BIG;
2773                 wrqu->data.length = pAd->StaCfg.RSNIE_Len + 2;
2774
2775                 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK) ||
2776             (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2))
2777                         RSNIe = IE_RSN;
2778
2779                 extra[0] = (char)RSNIe;
2780                 extra[1] = pAd->StaCfg.RSNIE_Len;
2781                 memcpy(extra+2, &pAd->StaCfg.RSN_IE[0], pAd->StaCfg.RSNIE_Len);
2782         }
2783
2784         return 0;
2785 }
2786
2787 int rt_ioctl_siwpmksa(struct net_device *dev,
2788                            struct iw_request_info *info,
2789                            union iwreq_data *wrqu,
2790                            char *extra)
2791 {
2792         PRTMP_ADAPTER   pAd = dev->ml_priv;
2793         struct iw_pmksa *pPmksa = (struct iw_pmksa *)wrqu->data.pointer;
2794         INT     CachedIdx = 0, idx = 0;
2795
2796         if (pPmksa == NULL)
2797                 return -EINVAL;
2798
2799         DBGPRINT(RT_DEBUG_TRACE ,("===> rt_ioctl_siwpmksa\n"));
2800         switch(pPmksa->cmd)
2801         {
2802                 case IW_PMKSA_FLUSH:
2803                         NdisZeroMemory(pAd->StaCfg.SavedPMK, sizeof(BSSID_INFO)*PMKID_NO);
2804                         DBGPRINT(RT_DEBUG_TRACE ,("rt_ioctl_siwpmksa - IW_PMKSA_FLUSH\n"));
2805                         break;
2806                 case IW_PMKSA_REMOVE:
2807                         for (CachedIdx = 0; CachedIdx < pAd->StaCfg.SavedPMKNum; CachedIdx++)
2808                         {
2809                         // compare the BSSID
2810                         if (NdisEqualMemory(pPmksa->bssid.sa_data, pAd->StaCfg.SavedPMK[CachedIdx].BSSID, MAC_ADDR_LEN))
2811                         {
2812                                 NdisZeroMemory(pAd->StaCfg.SavedPMK[CachedIdx].BSSID, MAC_ADDR_LEN);
2813                                         NdisZeroMemory(pAd->StaCfg.SavedPMK[CachedIdx].PMKID, 16);
2814                                         for (idx = CachedIdx; idx < (pAd->StaCfg.SavedPMKNum - 1); idx++)
2815                                         {
2816                                                 NdisMoveMemory(&pAd->StaCfg.SavedPMK[idx].BSSID[0], &pAd->StaCfg.SavedPMK[idx+1].BSSID[0], MAC_ADDR_LEN);
2817                                                 NdisMoveMemory(&pAd->StaCfg.SavedPMK[idx].PMKID[0], &pAd->StaCfg.SavedPMK[idx+1].PMKID[0], 16);
2818                                         }
2819                                         pAd->StaCfg.SavedPMKNum--;
2820                                 break;
2821                         }
2822                 }
2823
2824                         DBGPRINT(RT_DEBUG_TRACE ,("rt_ioctl_siwpmksa - IW_PMKSA_REMOVE\n"));
2825                         break;
2826                 case IW_PMKSA_ADD:
2827                         for (CachedIdx = 0; CachedIdx < pAd->StaCfg.SavedPMKNum; CachedIdx++)
2828                         {
2829                         // compare the BSSID
2830                         if (NdisEqualMemory(pPmksa->bssid.sa_data, pAd->StaCfg.SavedPMK[CachedIdx].BSSID, MAC_ADDR_LEN))
2831                                 break;
2832                 }
2833
2834                 // Found, replace it
2835                 if (CachedIdx < PMKID_NO)
2836                 {
2837                         DBGPRINT(RT_DEBUG_OFF, ("Update PMKID, idx = %d\n", CachedIdx));
2838                         NdisMoveMemory(&pAd->StaCfg.SavedPMK[CachedIdx].BSSID[0], pPmksa->bssid.sa_data, MAC_ADDR_LEN);
2839                                 NdisMoveMemory(&pAd->StaCfg.SavedPMK[CachedIdx].PMKID[0], pPmksa->pmkid, 16);
2840                         pAd->StaCfg.SavedPMKNum++;
2841                 }
2842                 // Not found, replace the last one
2843                 else
2844                 {
2845                         // Randomly replace one
2846                         CachedIdx = (pPmksa->bssid.sa_data[5] % PMKID_NO);
2847                         DBGPRINT(RT_DEBUG_OFF, ("Update PMKID, idx = %d\n", CachedIdx));
2848                         NdisMoveMemory(&pAd->StaCfg.SavedPMK[CachedIdx].BSSID[0], pPmksa->bssid.sa_data, MAC_ADDR_LEN);
2849                                 NdisMoveMemory(&pAd->StaCfg.SavedPMK[CachedIdx].PMKID[0], pPmksa->pmkid, 16);
2850                 }
2851
2852                         DBGPRINT(RT_DEBUG_TRACE ,("rt_ioctl_siwpmksa - IW_PMKSA_ADD\n"));
2853                         break;
2854                 default:
2855                         DBGPRINT(RT_DEBUG_TRACE ,("rt_ioctl_siwpmksa - Unknow Command!!\n"));
2856                         break;
2857         }
2858
2859         return 0;
2860 }
2861 #endif // #if WIRELESS_EXT > 17
2862
2863 #ifdef DBG
2864 static int
2865 rt_private_ioctl_bbp(struct net_device *dev, struct iw_request_info *info,
2866                 struct iw_point *wrq, char *extra)
2867                         {
2868         CHAR                            *this_char;
2869         CHAR                            *value = NULL;
2870         UCHAR                           regBBP = 0;
2871         UINT32                          bbpId;
2872         UINT32                          bbpValue;
2873         BOOLEAN                         bIsPrintAllBBP = FALSE;
2874         INT                                     Status = 0;
2875     PRTMP_ADAPTER       pAdapter = dev->ml_priv;
2876
2877
2878         memset(extra, 0x00, IW_PRIV_SIZE_MASK);
2879
2880         if (wrq->length > 1) //No parameters.
2881                                 {
2882                 sprintf(extra, "\n");
2883
2884                 //Parsing Read or Write
2885                 this_char = wrq->pointer;
2886                 DBGPRINT(RT_DEBUG_TRACE, ("this_char=%s\n", this_char));
2887                 if (!*this_char)
2888                         goto next;
2889
2890                 if ((value = rtstrchr(this_char, '=')) != NULL)
2891                         *value++ = 0;
2892
2893                 if (!value || !*value)
2894                 { //Read
2895                         DBGPRINT(RT_DEBUG_TRACE, ("this_char=%s, value=%s\n", this_char, value));
2896                         if (sscanf(this_char, "%d", &(bbpId)) == 1)
2897                         {
2898                                 if (bbpId <= 136)
2899                                 {
2900 #ifdef RALINK_ATE
2901                                         if (ATE_ON(pAdapter))
2902                                         {
2903                                                 ATE_BBP_IO_READ8_BY_REG_ID(pAdapter, bbpId, &regBBP);
2904                                         }
2905                                         else
2906 #endif // RALINK_ATE //
2907                                         {
2908                                         RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, bbpId, &regBBP);
2909                                         }
2910                                         sprintf(extra+strlen(extra), "R%02d[0x%02X]:%02X\n", bbpId, bbpId*2, regBBP);
2911                     wrq->length = strlen(extra) + 1; // 1: size of '\0'
2912                                         DBGPRINT(RT_DEBUG_TRACE, ("msg=%s\n", extra));
2913                                 }
2914                                 else
2915                                 {//Invalid parametes, so default printk all bbp
2916                                         bIsPrintAllBBP = TRUE;
2917                                         goto next;
2918                                 }
2919                         }
2920                         else
2921                         { //Invalid parametes, so default printk all bbp
2922                                 bIsPrintAllBBP = TRUE;
2923                                 goto next;
2924                         }
2925                 }
2926                 else
2927                 { //Write
2928                         if ((sscanf(this_char, "%d", &(bbpId)) == 1) && (sscanf(value, "%x", &(bbpValue)) == 1))
2929                         {
2930                                 if (bbpId <= 136)
2931                                 {
2932 #ifdef RALINK_ATE
2933                                         if (ATE_ON(pAdapter))
2934                                         {
2935                                                 ATE_BBP_IO_WRITE8_BY_REG_ID(pAdapter, bbpId, bbpValue);
2936                                                 //Read it back for showing
2937                                                 ATE_BBP_IO_READ8_BY_REG_ID(pAdapter, bbpId, &regBBP);
2938                                         }
2939                                         else
2940 #endif // RALINK_ATE //
2941                                         {
2942                                             RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, bbpId, bbpValue);
2943                                         //Read it back for showing
2944                                         RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, bbpId, &regBBP);
2945                         }
2946                                         sprintf(extra+strlen(extra), "R%02d[0x%02X]:%02X\n", bbpId, bbpId*2, regBBP);
2947                     wrq->length = strlen(extra) + 1; // 1: size of '\0'
2948                                         DBGPRINT(RT_DEBUG_TRACE, ("msg=%s\n", extra));
2949                                 }
2950                                 else
2951                                 {//Invalid parametes, so default printk all bbp
2952                                         bIsPrintAllBBP = TRUE;
2953                                         goto next;
2954                                 }
2955                         }
2956                         else
2957                         { //Invalid parametes, so default printk all bbp
2958                                 bIsPrintAllBBP = TRUE;
2959                                 goto next;
2960                         }
2961                 }
2962                 }
2963         else
2964                 bIsPrintAllBBP = TRUE;
2965
2966 next:
2967         if (bIsPrintAllBBP)
2968         {
2969                 memset(extra, 0x00, IW_PRIV_SIZE_MASK);
2970                 sprintf(extra, "\n");
2971                 for (bbpId = 0; bbpId <= 136; bbpId++)
2972                 {
2973                     if (strlen(extra) >= (IW_PRIV_SIZE_MASK - 10))
2974                 break;
2975 #ifdef RALINK_ATE
2976                         if (ATE_ON(pAdapter))
2977                         {
2978                                 ATE_BBP_IO_READ8_BY_REG_ID(pAdapter, bbpId, &regBBP);
2979                         }
2980                         else
2981 #endif // RALINK_ATE //
2982                         RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, bbpId, &regBBP);
2983                         sprintf(extra+strlen(extra), "R%02d[0x%02X]:%02X    ", bbpId, bbpId*2, regBBP);
2984                         if (bbpId%5 == 4)
2985                                 sprintf(extra+strlen(extra), "\n");
2986                 }
2987
2988         wrq->length = strlen(extra) + 1; // 1: size of '\0'
2989         DBGPRINT(RT_DEBUG_TRACE, ("wrq->length = %d\n", wrq->length));
2990         }
2991
2992         DBGPRINT(RT_DEBUG_TRACE, ("<==rt_private_ioctl_bbp\n\n"));
2993
2994     return Status;
2995 }
2996 #endif // DBG //
2997
2998 int rt_ioctl_siwrate(struct net_device *dev,
2999                         struct iw_request_info *info,
3000                         union iwreq_data *wrqu, char *extra)
3001 {
3002     PRTMP_ADAPTER   pAd = dev->ml_priv;
3003     UINT32          rate = wrqu->bitrate.value, fixed = wrqu->bitrate.fixed;
3004
3005     //check if the interface is down
3006         if(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE))
3007         {
3008                 DBGPRINT(RT_DEBUG_TRACE, ("rt_ioctl_siwrate::Network is down!\n"));
3009         return -ENETDOWN;
3010         }
3011
3012     DBGPRINT(RT_DEBUG_TRACE, ("rt_ioctl_siwrate::(rate = %d, fixed = %d)\n", rate, fixed));
3013     /* rate = -1 => auto rate
3014        rate = X, fixed = 1 => (fixed rate X)
3015     */
3016     if (rate == -1)
3017     {
3018                 //Auto Rate
3019                 pAd->StaCfg.DesiredTransmitSetting.field.MCS = MCS_AUTO;
3020                 pAd->StaCfg.bAutoTxRateSwitch = TRUE;
3021                 if ((pAd->CommonCfg.PhyMode <= PHY_11G) ||
3022                     (pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE <= MODE_OFDM))
3023                         RTMPSetDesiredRates(pAd, -1);
3024
3025 #ifdef DOT11_N_SUPPORT
3026                 SetCommonHT(pAd);
3027 #endif // DOT11_N_SUPPORT //
3028     }
3029     else
3030     {
3031         if (fixed)
3032         {
3033                 pAd->StaCfg.bAutoTxRateSwitch = FALSE;
3034             if ((pAd->CommonCfg.PhyMode <= PHY_11G) ||
3035                 (pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE <= MODE_OFDM))
3036                 RTMPSetDesiredRates(pAd, rate);
3037             else
3038             {
3039                 pAd->StaCfg.DesiredTransmitSetting.field.MCS = MCS_AUTO;
3040 #ifdef DOT11_N_SUPPORT
3041                 SetCommonHT(pAd);
3042 #endif // DOT11_N_SUPPORT //
3043             }
3044             DBGPRINT(RT_DEBUG_TRACE, ("rt_ioctl_siwrate::(HtMcs=%d)\n",pAd->StaCfg.DesiredTransmitSetting.field.MCS));
3045         }
3046         else
3047         {
3048             // TODO: rate = X, fixed = 0 => (rates <= X)
3049             return -EOPNOTSUPP;
3050         }
3051     }
3052
3053     return 0;
3054 }
3055
3056 int rt_ioctl_giwrate(struct net_device *dev,
3057                                struct iw_request_info *info,
3058                                union iwreq_data *wrqu, char *extra)
3059 {
3060     PRTMP_ADAPTER   pAd = dev->ml_priv;
3061     int rate_index = 0, rate_count = 0;
3062     HTTRANSMIT_SETTING ht_setting;
3063     __s32 ralinkrate[] =
3064         {2,  4,   11,  22, // CCK
3065         12, 18,   24,  36, 48, 72, 96, 108, // OFDM
3066         13, 26,   39,  52,  78, 104, 117, 130, 26,  52,  78, 104, 156, 208, 234, 260, // 20MHz, 800ns GI, MCS: 0 ~ 15
3067         39, 78,  117, 156, 234, 312, 351, 390,                                                                            // 20MHz, 800ns GI, MCS: 16 ~ 23
3068         27, 54,   81, 108, 162, 216, 243, 270, 54, 108, 162, 216, 324, 432, 486, 540, // 40MHz, 800ns GI, MCS: 0 ~ 15
3069         81, 162, 243, 324, 486, 648, 729, 810,                                                                            // 40MHz, 800ns GI, MCS: 16 ~ 23
3070         14, 29,   43,  57,  87, 115, 130, 144, 29, 59,   87, 115, 173, 230, 260, 288, // 20MHz, 400ns GI, MCS: 0 ~ 15
3071         43, 87,  130, 173, 260, 317, 390, 433,                                                                            // 20MHz, 400ns GI, MCS: 16 ~ 23
3072         30, 60,   90, 120, 180, 240, 270, 300, 60, 120, 180, 240, 360, 480, 540, 600, // 40MHz, 400ns GI, MCS: 0 ~ 15
3073         90, 180, 270, 360, 540, 720, 810, 900};                                                                           // 40MHz, 400ns GI, MCS: 16 ~ 23
3074
3075     rate_count = sizeof(ralinkrate)/sizeof(__s32);
3076     //check if the interface is down
3077         if(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE))
3078         {
3079                 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
3080         return -ENETDOWN;
3081         }
3082
3083     if ((pAd->StaCfg.bAutoTxRateSwitch == FALSE) &&
3084         (INFRA_ON(pAd)) &&
3085         ((pAd->CommonCfg.PhyMode <= PHY_11G) || (pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE <= MODE_OFDM)))
3086         ht_setting.word = pAd->StaCfg.HTPhyMode.word;
3087     else
3088         ht_setting.word = pAd->MacTab.Content[BSSID_WCID].HTPhyMode.word;
3089
3090 #ifdef DOT11_N_SUPPORT
3091     if (ht_setting.field.MODE >= MODE_HTMIX)
3092     {
3093         rate_index = 12 + ((UCHAR)ht_setting.field.BW *24) + ((UCHAR)ht_setting.field.ShortGI *48) + ((UCHAR)ht_setting.field.MCS);
3094     }
3095     else
3096 #endif // DOT11_N_SUPPORT //
3097     if (ht_setting.field.MODE == MODE_OFDM)
3098         rate_index = (UCHAR)(ht_setting.field.MCS) + 4;
3099     else if (ht_setting.field.MODE == MODE_CCK)
3100         rate_index = (UCHAR)(ht_setting.field.MCS);
3101
3102     if (rate_index < 0)
3103         rate_index = 0;
3104
3105     if (rate_index > rate_count)
3106         rate_index = rate_count;
3107
3108     wrqu->bitrate.value = ralinkrate[rate_index] * 500000;
3109     wrqu->bitrate.disabled = 0;
3110
3111     return 0;
3112 }
3113
3114 static const iw_handler rt_handler[] =
3115 {
3116         (iw_handler) NULL,                                  /* SIOCSIWCOMMIT */
3117         (iw_handler) rt_ioctl_giwname,                  /* SIOCGIWNAME   */
3118         (iw_handler) NULL,                                  /* SIOCSIWNWID   */
3119         (iw_handler) NULL,                                  /* SIOCGIWNWID   */
3120         (iw_handler) rt_ioctl_siwfreq,              /* SIOCSIWFREQ   */
3121         (iw_handler) rt_ioctl_giwfreq,              /* SIOCGIWFREQ   */
3122         (iw_handler) rt_ioctl_siwmode,              /* SIOCSIWMODE   */
3123         (iw_handler) rt_ioctl_giwmode,              /* SIOCGIWMODE   */
3124         (iw_handler) NULL,                              /* SIOCSIWSENS   */
3125         (iw_handler) NULL,                              /* SIOCGIWSENS   */
3126         (iw_handler) NULL /* not used */,               /* SIOCSIWRANGE  */
3127         (iw_handler) rt_ioctl_giwrange,             /* SIOCGIWRANGE  */
3128         (iw_handler) NULL /* not used */,               /* SIOCSIWPRIV   */
3129         (iw_handler) NULL /* kernel code */,    /* SIOCGIWPRIV   */
3130         (iw_handler) NULL /* not used */,               /* SIOCSIWSTATS  */
3131         (iw_handler) rt28xx_get_wireless_stats /* kernel code */,    /* SIOCGIWSTATS  */
3132         (iw_handler) NULL,                              /* SIOCSIWSPY    */
3133         (iw_handler) NULL,                              /* SIOCGIWSPY    */
3134         (iw_handler) NULL,                                      /* SIOCSIWTHRSPY */
3135         (iw_handler) NULL,                                      /* SIOCGIWTHRSPY */
3136         (iw_handler) rt_ioctl_siwap,            /* SIOCSIWAP     */
3137         (iw_handler) rt_ioctl_giwap,                /* SIOCGIWAP     */
3138 #ifdef SIOCSIWMLME
3139         (iw_handler) rt_ioctl_siwmlme,          /* SIOCSIWMLME   */
3140 #else
3141         (iw_handler) NULL,                                      /* SIOCSIWMLME */
3142 #endif // SIOCSIWMLME //
3143         (iw_handler) rt_ioctl_iwaplist,             /* SIOCGIWAPLIST */
3144 #ifdef SIOCGIWSCAN
3145         (iw_handler) rt_ioctl_siwscan,              /* SIOCSIWSCAN   */
3146         (iw_handler) rt_ioctl_giwscan,              /* SIOCGIWSCAN   */
3147 #else
3148         (iw_handler) NULL,                                      /* SIOCSIWSCAN   */
3149         (iw_handler) NULL,                                      /* SIOCGIWSCAN   */
3150 #endif /* SIOCGIWSCAN */
3151         (iw_handler) rt_ioctl_siwessid,             /* SIOCSIWESSID  */
3152         (iw_handler) rt_ioctl_giwessid,             /* SIOCGIWESSID  */
3153         (iw_handler) rt_ioctl_siwnickn,             /* SIOCSIWNICKN  */
3154         (iw_handler) rt_ioctl_giwnickn,             /* SIOCGIWNICKN  */
3155         (iw_handler) NULL,                                      /* -- hole --    */
3156         (iw_handler) NULL,                                      /* -- hole --    */
3157         (iw_handler) rt_ioctl_siwrate,          /* SIOCSIWRATE   */
3158         (iw_handler) rt_ioctl_giwrate,          /* SIOCGIWRATE   */
3159         (iw_handler) rt_ioctl_siwrts,               /* SIOCSIWRTS    */
3160         (iw_handler) rt_ioctl_giwrts,               /* SIOCGIWRTS    */
3161         (iw_handler) rt_ioctl_siwfrag,              /* SIOCSIWFRAG   */
3162         (iw_handler) rt_ioctl_giwfrag,              /* SIOCGIWFRAG   */
3163         (iw_handler) NULL,                              /* SIOCSIWTXPOW  */
3164         (iw_handler) NULL,                              /* SIOCGIWTXPOW  */
3165         (iw_handler) NULL,                              /* SIOCSIWRETRY  */
3166         (iw_handler) NULL,                              /* SIOCGIWRETRY  */
3167         (iw_handler) rt_ioctl_siwencode,                /* SIOCSIWENCODE */
3168         (iw_handler) rt_ioctl_giwencode,                /* SIOCGIWENCODE */
3169         (iw_handler) NULL,                              /* SIOCSIWPOWER  */
3170         (iw_handler) NULL,                              /* SIOCGIWPOWER  */
3171         (iw_handler) NULL,                                              /* -- hole -- */
3172         (iw_handler) NULL,                                              /* -- hole -- */
3173 #if WIRELESS_EXT > 17
3174     (iw_handler) rt_ioctl_siwgenie,         /* SIOCSIWGENIE  */
3175         (iw_handler) rt_ioctl_giwgenie,         /* SIOCGIWGENIE  */
3176         (iw_handler) rt_ioctl_siwauth,              /* SIOCSIWAUTH   */
3177         (iw_handler) rt_ioctl_giwauth,              /* SIOCGIWAUTH   */
3178         (iw_handler) rt_ioctl_siwencodeext,         /* SIOCSIWENCODEEXT */
3179         (iw_handler) rt_ioctl_giwencodeext,             /* SIOCGIWENCODEEXT */
3180         (iw_handler) rt_ioctl_siwpmksa,         /* SIOCSIWPMKSA  */
3181 #endif
3182 };
3183
3184 static const iw_handler rt_priv_handlers[] = {
3185         (iw_handler) NULL, /* + 0x00 */
3186         (iw_handler) NULL, /* + 0x01 */
3187 #ifndef CONFIG_AP_SUPPORT
3188         (iw_handler) rt_ioctl_setparam, /* + 0x02 */
3189 #else
3190         (iw_handler) NULL, /* + 0x02 */
3191 #endif // CONFIG_AP_SUPPORT //
3192 #ifdef DBG
3193         (iw_handler) rt_private_ioctl_bbp, /* + 0x03 */
3194 #else
3195         (iw_handler) NULL, /* + 0x03 */
3196 #endif
3197         (iw_handler) NULL, /* + 0x04 */
3198         (iw_handler) NULL, /* + 0x05 */
3199         (iw_handler) NULL, /* + 0x06 */
3200         (iw_handler) NULL, /* + 0x07 */
3201         (iw_handler) NULL, /* + 0x08 */
3202         (iw_handler) rt_private_get_statistics, /* + 0x09 */
3203         (iw_handler) NULL, /* + 0x0A */
3204         (iw_handler) NULL, /* + 0x0B */
3205         (iw_handler) NULL, /* + 0x0C */
3206         (iw_handler) NULL, /* + 0x0D */
3207         (iw_handler) NULL, /* + 0x0E */
3208         (iw_handler) NULL, /* + 0x0F */
3209         (iw_handler) NULL, /* + 0x10 */
3210         (iw_handler) rt_private_show, /* + 0x11 */
3211     (iw_handler) NULL, /* + 0x12 */
3212         (iw_handler) NULL, /* + 0x13 */
3213         (iw_handler) NULL, /* + 0x15 */
3214         (iw_handler) NULL, /* + 0x17 */
3215         (iw_handler) NULL, /* + 0x18 */
3216 };
3217
3218 const struct iw_handler_def rt28xx_iw_handler_def =
3219 {
3220 #define N(a)    (sizeof (a) / sizeof (a[0]))
3221         .standard       = (iw_handler *) rt_handler,
3222         .num_standard   = sizeof(rt_handler) / sizeof(iw_handler),
3223         .private        = (iw_handler *) rt_priv_handlers,
3224         .num_private            = N(rt_priv_handlers),
3225         .private_args   = (struct iw_priv_args *) privtab,
3226         .num_private_args       = N(privtab),
3227 #if IW_HANDLER_VERSION >= 7
3228     .get_wireless_stats = rt28xx_get_wireless_stats,
3229 #endif
3230 };
3231
3232 INT RTMPSetInformation(
3233     IN  PRTMP_ADAPTER pAdapter,
3234     IN  OUT struct ifreq    *rq,
3235     IN  INT                 cmd)
3236 {
3237     struct iwreq                        *wrq = (struct iwreq *) rq;
3238     NDIS_802_11_SSID                    Ssid;
3239     NDIS_802_11_MAC_ADDRESS             Bssid;
3240     RT_802_11_PHY_MODE                  PhyMode;
3241     RT_802_11_STA_CONFIG                StaConfig;
3242     NDIS_802_11_RATES                   aryRates;
3243     RT_802_11_PREAMBLE                  Preamble;
3244     NDIS_802_11_WEP_STATUS              WepStatus;
3245     NDIS_802_11_AUTHENTICATION_MODE     AuthMode = Ndis802_11AuthModeMax;
3246     NDIS_802_11_NETWORK_INFRASTRUCTURE  BssType;
3247     NDIS_802_11_RTS_THRESHOLD           RtsThresh;
3248     NDIS_802_11_FRAGMENTATION_THRESHOLD FragThresh;
3249     NDIS_802_11_POWER_MODE              PowerMode;
3250     PNDIS_802_11_KEY                    pKey = NULL;
3251     PNDIS_802_11_WEP                            pWepKey =NULL;
3252     PNDIS_802_11_REMOVE_KEY             pRemoveKey = NULL;
3253     NDIS_802_11_CONFIGURATION           Config, *pConfig = NULL;
3254     NDIS_802_11_NETWORK_TYPE            NetType;
3255     ULONG                               Now;
3256     UINT                                KeyIdx = 0;
3257     INT                                 Status = NDIS_STATUS_SUCCESS, MaxPhyMode = PHY_11G;
3258     ULONG                               PowerTemp;
3259     BOOLEAN                             RadioState;
3260     BOOLEAN                             StateMachineTouched = FALSE;
3261 #ifdef DOT11_N_SUPPORT
3262         OID_SET_HT_PHYMODE                                      HT_PhyMode;     //11n ,kathy
3263 #endif // DOT11_N_SUPPORT //
3264 #ifdef WPA_SUPPLICANT_SUPPORT
3265     PNDIS_802_11_PMKID                  pPmkId = NULL;
3266     BOOLEAN                                             IEEE8021xState = FALSE;
3267     BOOLEAN                                             IEEE8021x_required_keys = FALSE;
3268     UCHAR                               wpa_supplicant_enable = 0;
3269 #endif // WPA_SUPPLICANT_SUPPORT //
3270
3271 #ifdef SNMP_SUPPORT
3272         TX_RTY_CFG_STRUC                        tx_rty_cfg;
3273         ULONG                                           ShortRetryLimit, LongRetryLimit;
3274         UCHAR                                           ctmp;
3275 #endif // SNMP_SUPPORT //
3276
3277
3278 #ifdef DOT11_N_SUPPORT
3279         MaxPhyMode = PHY_11N_5G;
3280 #endif // DOT11_N_SUPPORT //
3281
3282
3283         DBGPRINT(RT_DEBUG_TRACE, ("-->RTMPSetInformation(),     0x%08x\n", cmd&0x7FFF));
3284     switch(cmd & 0x7FFF) {
3285         case RT_OID_802_11_COUNTRY_REGION:
3286             if (wrq->u.data.length < sizeof(UCHAR))
3287                 Status = -EINVAL;
3288                         // Only avaliable when EEPROM not programming
3289             else if (!(pAdapter->CommonCfg.CountryRegion & 0x80) && !(pAdapter->CommonCfg.CountryRegionForABand & 0x80))
3290             {
3291                 ULONG   Country;
3292                 UCHAR   TmpPhy;
3293
3294                                 Status = copy_from_user(&Country, wrq->u.data.pointer, wrq->u.data.length);
3295                                 pAdapter->CommonCfg.CountryRegion = (UCHAR)(Country & 0x000000FF);
3296                                 pAdapter->CommonCfg.CountryRegionForABand = (UCHAR)((Country >> 8) & 0x000000FF);
3297                 TmpPhy = pAdapter->CommonCfg.PhyMode;
3298                                 pAdapter->CommonCfg.PhyMode = 0xff;
3299                                 // Build all corresponding channel information
3300                                 RTMPSetPhyMode(pAdapter, TmpPhy);
3301 #ifdef DOT11_N_SUPPORT
3302                                 SetCommonHT(pAdapter);
3303 #endif // DOT11_N_SUPPORT //
3304                                 DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_COUNTRY_REGION (A:%d  B/G:%d)\n", pAdapter->CommonCfg.CountryRegionForABand,
3305                                     pAdapter->CommonCfg.CountryRegion));
3306             }
3307             break;
3308         case OID_802_11_BSSID_LIST_SCAN:
3309  #ifdef RALINK_ATE
3310                         if (ATE_ON(pAdapter))
3311                         {
3312                                 DBGPRINT(RT_DEBUG_TRACE, ("The driver is in ATE mode now\n"));
3313                                 break;
3314                         }
3315 #endif // RALINK_ATE //
3316             Now = jiffies;
3317                         DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_BSSID_LIST_SCAN, TxCnt = %d \n", pAdapter->RalinkCounters.LastOneSecTotalTxCount));
3318
3319             if (MONITOR_ON(pAdapter))
3320             {
3321                 DBGPRINT(RT_DEBUG_TRACE, ("!!! Driver is in Monitor Mode now !!!\n"));
3322                 break;
3323             }
3324
3325                         //Benson add 20080527, when radio off, sta don't need to scan
3326                         if (RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_RADIO_OFF))
3327                                 break;
3328
3329                         if (RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
3330                         {
3331                 DBGPRINT(RT_DEBUG_TRACE, ("!!! Driver is scanning now !!!\n"));
3332                                 pAdapter->StaCfg.bScanReqIsFromWebUI = TRUE;
3333                                 Status = NDIS_STATUS_SUCCESS;
3334                 break;
3335             }
3336
3337                         if (pAdapter->RalinkCounters.LastOneSecTotalTxCount > 100)
3338             {
3339                 DBGPRINT(RT_DEBUG_TRACE, ("!!! Link UP, ignore this set::OID_802_11_BSSID_LIST_SCAN\n"));
3340                                 Status = NDIS_STATUS_SUCCESS;
3341                                 pAdapter->StaCfg.ScanCnt = 99;          // Prevent auto scan triggered by this OID
3342                                 break;
3343             }
3344
3345             if ((OPSTATUS_TEST_FLAG(pAdapter, fOP_STATUS_MEDIA_STATE_CONNECTED)) &&
3346                                 ((pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPA) ||
3347                                 (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
3348                                 (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) ||
3349                                 (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)) &&
3350                 (pAdapter->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED))
3351             {
3352                 DBGPRINT(RT_DEBUG_TRACE, ("!!! Link UP, Port Not Secured! ignore this set::OID_802_11_BSSID_LIST_SCAN\n"));
3353                                 Status = NDIS_STATUS_SUCCESS;
3354                                 pAdapter->StaCfg.ScanCnt = 99;          // Prevent auto scan triggered by this OID
3355                                 break;
3356             }
3357
3358
3359             if (pAdapter->Mlme.CntlMachine.CurrState != CNTL_IDLE)
3360             {
3361                 RT28XX_MLME_RESET_STATE_MACHINE(pAdapter);
3362                 DBGPRINT(RT_DEBUG_TRACE, ("!!! MLME busy, reset MLME state machine !!!\n"));
3363             }
3364
3365             // tell CNTL state machine to call NdisMSetInformationComplete() after completing
3366             // this request, because this request is initiated by NDIS.
3367             pAdapter->MlmeAux.CurrReqIsFromNdis = FALSE;
3368             // Reset allowed scan retries
3369             pAdapter->StaCfg.ScanCnt = 0;
3370             pAdapter->StaCfg.LastScanTime = Now;
3371
3372                         pAdapter->StaCfg.bScanReqIsFromWebUI = TRUE;
3373             RTMP_SET_FLAG(pAdapter, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
3374             MlmeEnqueue(pAdapter,
3375                         MLME_CNTL_STATE_MACHINE,
3376                         OID_802_11_BSSID_LIST_SCAN,
3377                         0,
3378                         NULL);
3379
3380             Status = NDIS_STATUS_SUCCESS;
3381             StateMachineTouched = TRUE;
3382             break;
3383         case OID_802_11_SSID:
3384             if (wrq->u.data.length != sizeof(NDIS_802_11_SSID))
3385                 Status = -EINVAL;
3386             else
3387             {
3388                 PCHAR pSsidString = NULL;
3389                 Status = copy_from_user(&Ssid, wrq->u.data.pointer, wrq->u.data.length);
3390
3391                                 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_SSID (Len=%d,Ssid=%s)\n", Ssid.SsidLength, Ssid.Ssid));
3392                 if (Ssid.SsidLength > MAX_LEN_OF_SSID)
3393                     Status = -EINVAL;
3394                 else
3395                 {
3396                         if (Ssid.SsidLength == 0)
3397                         {
3398                                 Set_SSID_Proc(pAdapter, "");
3399                         }
3400                                         else
3401                         {
3402                                 pSsidString = (CHAR *) kmalloc(MAX_LEN_OF_SSID+1, MEM_ALLOC_FLAG);
3403                                                 if (pSsidString)
3404                                                 {
3405                                                         NdisZeroMemory(pSsidString, MAX_LEN_OF_SSID+1);
3406                                                         NdisMoveMemory(pSsidString, Ssid.Ssid, Ssid.SsidLength);
3407                                         Set_SSID_Proc(pAdapter, pSsidString);
3408                                                         kfree(pSsidString);
3409                                                 }
3410                                                 else
3411                                                         Status = -ENOMEM;
3412                         }
3413                 }
3414             }
3415             break;
3416         case OID_802_11_BSSID:
3417 #ifdef RALINK_ATE
3418                         if (ATE_ON(pAdapter))
3419                         {
3420                                 DBGPRINT(RT_DEBUG_TRACE, ("The driver is in ATE mode now\n"));
3421                                 break;
3422                         }
3423 #endif // RALINK_ATE //
3424             if (wrq->u.data.length != sizeof(NDIS_802_11_MAC_ADDRESS))
3425                 Status  = -EINVAL;
3426             else
3427             {
3428                 Status = copy_from_user(&Bssid, wrq->u.data.pointer, wrq->u.data.length);
3429
3430                 // tell CNTL state machine to call NdisMSetInformationComplete() after completing
3431                 // this request, because this request is initiated by NDIS.
3432                 pAdapter->MlmeAux.CurrReqIsFromNdis = FALSE;
3433
3434                                 // Prevent to connect AP again in STAMlmePeriodicExec
3435                                 pAdapter->MlmeAux.AutoReconnectSsidLen= 32;
3436
3437                 // Reset allowed scan retries
3438                                 pAdapter->StaCfg.ScanCnt = 0;
3439
3440                 if (pAdapter->Mlme.CntlMachine.CurrState != CNTL_IDLE)
3441                 {
3442                     RT28XX_MLME_RESET_STATE_MACHINE(pAdapter);
3443                     DBGPRINT(RT_DEBUG_TRACE, ("!!! MLME busy, reset MLME state machine !!!\n"));
3444                 }
3445                 MlmeEnqueue(pAdapter,
3446                             MLME_CNTL_STATE_MACHINE,
3447                             OID_802_11_BSSID,
3448                             sizeof(NDIS_802_11_MAC_ADDRESS),
3449                             (VOID *)&Bssid);
3450                 Status = NDIS_STATUS_SUCCESS;
3451                 StateMachineTouched = TRUE;
3452
3453                 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_BSSID %02x:%02x:%02x:%02x:%02x:%02x\n",
3454                                         Bssid[0], Bssid[1], Bssid[2], Bssid[3], Bssid[4], Bssid[5]));
3455             }
3456             break;
3457         case RT_OID_802_11_RADIO:
3458             if (wrq->u.data.length != sizeof(BOOLEAN))
3459                 Status  = -EINVAL;
3460             else
3461             {
3462                 Status = copy_from_user(&RadioState, wrq->u.data.pointer, wrq->u.data.length);
3463                 DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_RADIO (=%d)\n", RadioState));
3464                 if (pAdapter->StaCfg.bSwRadio != RadioState)
3465                 {
3466                     pAdapter->StaCfg.bSwRadio = RadioState;
3467                     if (pAdapter->StaCfg.bRadio != (pAdapter->StaCfg.bHwRadio && pAdapter->StaCfg.bSwRadio))
3468                     {
3469                         pAdapter->StaCfg.bRadio = (pAdapter->StaCfg.bHwRadio && pAdapter->StaCfg.bSwRadio);
3470                         if (pAdapter->StaCfg.bRadio == TRUE)
3471                         {
3472                             MlmeRadioOn(pAdapter);
3473                             // Update extra information
3474                                                         pAdapter->ExtraInfo = EXTRA_INFO_CLEAR;
3475                         }
3476                         else
3477                         {
3478                             MlmeRadioOff(pAdapter);
3479                             // Update extra information
3480                                                         pAdapter->ExtraInfo = SW_RADIO_OFF;
3481                         }
3482                     }
3483                 }
3484             }
3485             break;
3486         case RT_OID_802_11_PHY_MODE:
3487             if (wrq->u.data.length != sizeof(RT_802_11_PHY_MODE))
3488                 Status  = -EINVAL;
3489             else
3490             {
3491                 Status = copy_from_user(&PhyMode, wrq->u.data.pointer, wrq->u.data.length);
3492                                 if (PhyMode <= MaxPhyMode)
3493                                 {
3494                         RTMPSetPhyMode(pAdapter, PhyMode);
3495 #ifdef DOT11_N_SUPPORT
3496                                         SetCommonHT(pAdapter);
3497 #endif // DOT11_N_SUPPORT //
3498                                 }
3499                 DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_PHY_MODE (=%d)\n", PhyMode));
3500             }
3501             break;
3502         case RT_OID_802_11_STA_CONFIG:
3503             if (wrq->u.data.length != sizeof(RT_802_11_STA_CONFIG))
3504                 Status  = -EINVAL;
3505             else
3506             {
3507                 Status = copy_from_user(&StaConfig, wrq->u.data.pointer, wrq->u.data.length);
3508                 pAdapter->CommonCfg.bEnableTxBurst = StaConfig.EnableTxBurst;
3509                 pAdapter->CommonCfg.UseBGProtection = StaConfig.UseBGProtection;
3510                 pAdapter->CommonCfg.bUseShortSlotTime = 1; // 2003-10-30 always SHORT SLOT capable
3511                 if ((pAdapter->CommonCfg.PhyMode != StaConfig.AdhocMode) &&
3512                                         (StaConfig.AdhocMode <= MaxPhyMode))
3513                 {
3514                     // allow dynamic change of "USE OFDM rate or not" in ADHOC mode
3515                     // if setting changed, need to reset current TX rate as well as BEACON frame format
3516                     if (pAdapter->StaCfg.BssType == BSS_ADHOC)
3517                     {
3518                                                 pAdapter->CommonCfg.PhyMode = StaConfig.AdhocMode;
3519                         RTMPSetPhyMode(pAdapter, PhyMode);
3520                         MlmeUpdateTxRates(pAdapter, FALSE, 0);
3521                         MakeIbssBeacon(pAdapter);           // re-build BEACON frame
3522                         AsicEnableIbssSync(pAdapter);   // copy to on-chip memory
3523                     }
3524                 }
3525                 DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_SET_STA_CONFIG (Burst=%d, Protection=%ld,ShortSlot=%d\n",
3526                                         pAdapter->CommonCfg.bEnableTxBurst,
3527                                         pAdapter->CommonCfg.UseBGProtection,
3528                                         pAdapter->CommonCfg.bUseShortSlotTime));
3529             }
3530             break;
3531         case OID_802_11_DESIRED_RATES:
3532             if (wrq->u.data.length != sizeof(NDIS_802_11_RATES))
3533                 Status  = -EINVAL;
3534             else
3535             {
3536                 Status = copy_from_user(&aryRates, wrq->u.data.pointer, wrq->u.data.length);
3537                 NdisZeroMemory(pAdapter->CommonCfg.DesireRate, MAX_LEN_OF_SUPPORTED_RATES);
3538                 NdisMoveMemory(pAdapter->CommonCfg.DesireRate, &aryRates, sizeof(NDIS_802_11_RATES));
3539                 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_DESIRED_RATES (%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x)\n",
3540                     pAdapter->CommonCfg.DesireRate[0],pAdapter->CommonCfg.DesireRate[1],
3541                     pAdapter->CommonCfg.DesireRate[2],pAdapter->CommonCfg.DesireRate[3],
3542                     pAdapter->CommonCfg.DesireRate[4],pAdapter->CommonCfg.DesireRate[5],
3543                     pAdapter->CommonCfg.DesireRate[6],pAdapter->CommonCfg.DesireRate[7] ));
3544                 // Changing DesiredRate may affect the MAX TX rate we used to TX frames out
3545                 MlmeUpdateTxRates(pAdapter, FALSE, 0);
3546             }
3547             break;
3548         case RT_OID_802_11_PREAMBLE:
3549             if (wrq->u.data.length != sizeof(RT_802_11_PREAMBLE))
3550                 Status  = -EINVAL;
3551             else
3552             {
3553                 Status = copy_from_user(&Preamble, wrq->u.data.pointer, wrq->u.data.length);
3554                 if (Preamble == Rt802_11PreambleShort)
3555                 {
3556                     pAdapter->CommonCfg.TxPreamble = Preamble;
3557                     MlmeSetTxPreamble(pAdapter, Rt802_11PreambleShort);
3558                 }
3559                 else if ((Preamble == Rt802_11PreambleLong) || (Preamble == Rt802_11PreambleAuto))
3560                 {
3561                     // if user wants AUTO, initialize to LONG here, then change according to AP's
3562                     // capability upon association.
3563                     pAdapter->CommonCfg.TxPreamble = Preamble;
3564                     MlmeSetTxPreamble(pAdapter, Rt802_11PreambleLong);
3565                 }
3566                 else
3567                 {
3568                     Status = -EINVAL;
3569                     break;
3570                 }
3571                 DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_PREAMBLE (=%d)\n", Preamble));
3572             }
3573             break;
3574         case OID_802_11_WEP_STATUS:
3575             if (wrq->u.data.length != sizeof(NDIS_802_11_WEP_STATUS))
3576                 Status  = -EINVAL;
3577             else
3578             {
3579                 Status = copy_from_user(&WepStatus, wrq->u.data.pointer, wrq->u.data.length);
3580                 // Since TKIP, AES, WEP are all supported. It should not have any invalid setting
3581                 if (WepStatus <= Ndis802_11Encryption3KeyAbsent)
3582                 {
3583                     if (pAdapter->StaCfg.WepStatus != WepStatus)
3584                     {
3585                         // Config has changed
3586                         pAdapter->bConfigChanged = TRUE;
3587                     }
3588                     pAdapter->StaCfg.WepStatus     = WepStatus;
3589                     pAdapter->StaCfg.OrigWepStatus = WepStatus;
3590                     pAdapter->StaCfg.PairCipher    = WepStatus;
3591                         pAdapter->StaCfg.GroupCipher   = WepStatus;
3592                 }
3593                 else
3594                 {
3595                     Status  = -EINVAL;
3596                     break;
3597                 }
3598                 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_WEP_STATUS (=%d)\n",WepStatus));
3599             }
3600             break;
3601         case OID_802_11_AUTHENTICATION_MODE:
3602             if (wrq->u.data.length != sizeof(NDIS_802_11_AUTHENTICATION_MODE))
3603                 Status  = -EINVAL;
3604             else
3605             {
3606                 Status = copy_from_user(&AuthMode, wrq->u.data.pointer, wrq->u.data.length);
3607                 if (AuthMode > Ndis802_11AuthModeMax)
3608                 {
3609                     Status  = -EINVAL;
3610                     break;
3611                 }
3612                 else
3613                 {
3614                     if (pAdapter->StaCfg.AuthMode != AuthMode)
3615                     {
3616                         // Config has changed
3617                         pAdapter->bConfigChanged = TRUE;
3618                     }
3619                     pAdapter->StaCfg.AuthMode = AuthMode;
3620                 }
3621                 pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
3622                 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_AUTHENTICATION_MODE (=%d) \n",pAdapter->StaCfg.AuthMode));
3623             }
3624             break;
3625         case OID_802_11_INFRASTRUCTURE_MODE:
3626             if (wrq->u.data.length != sizeof(NDIS_802_11_NETWORK_INFRASTRUCTURE))
3627                 Status  = -EINVAL;
3628             else
3629             {
3630                 Status = copy_from_user(&BssType, wrq->u.data.pointer, wrq->u.data.length);
3631
3632                                 if (BssType == Ndis802_11IBSS)
3633                                         Set_NetworkType_Proc(pAdapter, "Adhoc");
3634                                 else if (BssType == Ndis802_11Infrastructure)
3635                                         Set_NetworkType_Proc(pAdapter, "Infra");
3636                                 else if (BssType == Ndis802_11Monitor)
3637                                         Set_NetworkType_Proc(pAdapter, "Monitor");
3638                                 else
3639                                 {
3640                                         Status  = -EINVAL;
3641                                         DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_INFRASTRUCTURE_MODE (unknown)\n"));
3642                                 }
3643                         }
3644                         break;
3645          case OID_802_11_REMOVE_WEP:
3646             DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_REMOVE_WEP\n"));
3647             if (wrq->u.data.length != sizeof(NDIS_802_11_KEY_INDEX))
3648             {
3649                                 Status = -EINVAL;
3650             }
3651             else
3652             {
3653                                 KeyIdx = *(NDIS_802_11_KEY_INDEX *) wrq->u.data.pointer;
3654
3655                                 if (KeyIdx & 0x80000000)
3656                                 {
3657                                         // Should never set default bit when remove key
3658                                         Status = -EINVAL;
3659                                 }
3660                                 else
3661                                 {
3662                                         KeyIdx = KeyIdx & 0x0fffffff;
3663                                         if (KeyIdx >= 4){
3664                                                 Status = -EINVAL;
3665                                         }
3666                                         else
3667                                         {
3668                                                 pAdapter->SharedKey[BSS0][KeyIdx].KeyLen = 0;
3669                                                 pAdapter->SharedKey[BSS0][KeyIdx].CipherAlg = CIPHER_NONE;
3670                                                 AsicRemoveSharedKeyEntry(pAdapter, 0, (UCHAR)KeyIdx);
3671                                         }
3672                                 }
3673             }
3674             break;
3675         case RT_OID_802_11_RESET_COUNTERS:
3676             NdisZeroMemory(&pAdapter->WlanCounters, sizeof(COUNTER_802_11));
3677             NdisZeroMemory(&pAdapter->Counters8023, sizeof(COUNTER_802_3));
3678             NdisZeroMemory(&pAdapter->RalinkCounters, sizeof(COUNTER_RALINK));
3679             pAdapter->Counters8023.RxNoBuffer   = 0;
3680                         pAdapter->Counters8023.GoodReceives = 0;
3681                         pAdapter->Counters8023.RxNoBuffer   = 0;
3682             DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_RESET_COUNTERS \n"));
3683             break;
3684         case OID_802_11_RTS_THRESHOLD:
3685             if (wrq->u.data.length != sizeof(NDIS_802_11_RTS_THRESHOLD))
3686                 Status  = -EINVAL;
3687             else
3688             {
3689                 Status = copy_from_user(&RtsThresh, wrq->u.data.pointer, wrq->u.data.length);
3690                 if (RtsThresh > MAX_RTS_THRESHOLD)
3691                     Status  = -EINVAL;
3692                 else
3693                     pAdapter->CommonCfg.RtsThreshold = (USHORT)RtsThresh;
3694             }
3695             DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_RTS_THRESHOLD (=%ld)\n",RtsThresh));
3696             break;
3697         case OID_802_11_FRAGMENTATION_THRESHOLD:
3698             if (wrq->u.data.length != sizeof(NDIS_802_11_FRAGMENTATION_THRESHOLD))
3699                 Status  = -EINVAL;
3700             else
3701             {
3702                 Status = copy_from_user(&FragThresh, wrq->u.data.pointer, wrq->u.data.length);
3703                 pAdapter->CommonCfg.bUseZeroToDisableFragment = FALSE;
3704                 if (FragThresh > MAX_FRAG_THRESHOLD || FragThresh < MIN_FRAG_THRESHOLD)
3705                 {
3706                     if (FragThresh == 0)
3707                     {
3708                         pAdapter->CommonCfg.FragmentThreshold = MAX_FRAG_THRESHOLD;
3709                         pAdapter->CommonCfg.bUseZeroToDisableFragment = TRUE;
3710                     }
3711                     else
3712                         Status  = -EINVAL;
3713                 }
3714                 else
3715                     pAdapter->CommonCfg.FragmentThreshold = (USHORT)FragThresh;
3716             }
3717             DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_FRAGMENTATION_THRESHOLD (=%ld) \n",FragThresh));
3718             break;
3719         case OID_802_11_POWER_MODE:
3720             if (wrq->u.data.length != sizeof(NDIS_802_11_POWER_MODE))
3721                 Status = -EINVAL;
3722             else
3723             {
3724                 Status = copy_from_user(&PowerMode, wrq->u.data.pointer, wrq->u.data.length);
3725                 if (PowerMode == Ndis802_11PowerModeCAM)
3726                         Set_PSMode_Proc(pAdapter, "CAM");
3727                 else if (PowerMode == Ndis802_11PowerModeMAX_PSP)
3728                         Set_PSMode_Proc(pAdapter, "Max_PSP");
3729                 else if (PowerMode == Ndis802_11PowerModeFast_PSP)
3730                                         Set_PSMode_Proc(pAdapter, "Fast_PSP");
3731                 else if (PowerMode == Ndis802_11PowerModeLegacy_PSP)
3732                                         Set_PSMode_Proc(pAdapter, "Legacy_PSP");
3733                 else
3734                     Status = -EINVAL;
3735             }
3736             DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_POWER_MODE (=%d)\n",PowerMode));
3737             break;
3738          case RT_OID_802_11_TX_POWER_LEVEL_1:
3739                         if (wrq->u.data.length  < sizeof(ULONG))
3740                                 Status = -EINVAL;
3741                         else
3742                         {
3743                                 Status = copy_from_user(&PowerTemp, wrq->u.data.pointer, wrq->u.data.length);
3744                                 if (PowerTemp > 100)
3745                                         PowerTemp = 0xffffffff;  // AUTO
3746                                 pAdapter->CommonCfg.TxPowerDefault = PowerTemp; //keep current setting.
3747                                         pAdapter->CommonCfg.TxPowerPercentage = pAdapter->CommonCfg.TxPowerDefault;
3748                 DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_TX_POWER_LEVEL_1 (=%ld)\n", pAdapter->CommonCfg.TxPowerPercentage));
3749                         }
3750                 break;
3751                 case OID_802_11_NETWORK_TYPE_IN_USE:
3752                         if (wrq->u.data.length != sizeof(NDIS_802_11_NETWORK_TYPE))
3753                                 Status = -EINVAL;
3754                         else
3755                         {
3756                                 Status = copy_from_user(&NetType, wrq->u.data.pointer, wrq->u.data.length);
3757
3758                                 if (NetType == Ndis802_11DS)
3759                                         RTMPSetPhyMode(pAdapter, PHY_11B);
3760                                 else if (NetType == Ndis802_11OFDM24)
3761                                         RTMPSetPhyMode(pAdapter, PHY_11BG_MIXED);
3762                                 else if (NetType == Ndis802_11OFDM5)
3763                                         RTMPSetPhyMode(pAdapter, PHY_11A);
3764                                 else
3765                                         Status = -EINVAL;
3766 #ifdef DOT11_N_SUPPORT
3767                                 if (Status == NDIS_STATUS_SUCCESS)
3768                                         SetCommonHT(pAdapter);
3769 #endif // DOT11_N_SUPPORT //
3770                 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_NETWORK_TYPE_IN_USE (=%d)\n",NetType));
3771                     }
3772                         break;
3773         // For WPA PSK PMK key
3774         case RT_OID_802_11_ADD_WPA:
3775             pKey = kmalloc(wrq->u.data.length, MEM_ALLOC_FLAG);
3776             if(pKey == NULL)
3777             {
3778                 Status = -ENOMEM;
3779                 break;
3780             }
3781
3782             Status = copy_from_user(pKey, wrq->u.data.pointer, wrq->u.data.length);
3783             if (pKey->Length != wrq->u.data.length)
3784             {
3785                 Status  = -EINVAL;
3786                 DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_ADD_WPA, Failed!!\n"));
3787             }
3788             else
3789             {
3790                 if ((pAdapter->StaCfg.AuthMode != Ndis802_11AuthModeWPAPSK) &&
3791                                     (pAdapter->StaCfg.AuthMode != Ndis802_11AuthModeWPA2PSK) &&
3792                                     (pAdapter->StaCfg.AuthMode != Ndis802_11AuthModeWPANone) )
3793                 {
3794                     Status = -EOPNOTSUPP;
3795                     DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_ADD_WPA, Failed!! [AuthMode != WPAPSK/WPA2PSK/WPANONE]\n"));
3796                 }
3797                 else if ((pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
3798                                                  (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK) ||
3799                                                  (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPANone) )     // Only for WPA PSK mode
3800                                 {
3801                     NdisMoveMemory(pAdapter->StaCfg.PMK, &pKey->KeyMaterial, pKey->KeyLength);
3802                     // Use RaConfig as PSK agent.
3803                     // Start STA supplicant state machine
3804                     if (pAdapter->StaCfg.AuthMode != Ndis802_11AuthModeWPANone)
3805                         pAdapter->StaCfg.WpaState = SS_START;
3806
3807                     DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_ADD_WPA (id=0x%x, Len=%d-byte)\n", pKey->KeyIndex, pKey->KeyLength));
3808                 }
3809                 else
3810                 {
3811                     pAdapter->StaCfg.WpaState = SS_NOTUSE;
3812                     DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_ADD_WPA (id=0x%x, Len=%d-byte)\n", pKey->KeyIndex, pKey->KeyLength));
3813                 }
3814             }
3815             kfree(pKey);
3816             break;
3817         case OID_802_11_REMOVE_KEY:
3818             pRemoveKey = kmalloc(wrq->u.data.length, MEM_ALLOC_FLAG);
3819             if(pRemoveKey == NULL)
3820             {
3821                 Status = -ENOMEM;
3822                 break;
3823             }
3824
3825             Status = copy_from_user(pRemoveKey, wrq->u.data.pointer, wrq->u.data.length);
3826             if (pRemoveKey->Length != wrq->u.data.length)
3827             {
3828                 Status  = -EINVAL;
3829                 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_REMOVE_KEY, Failed!!\n"));
3830             }
3831             else
3832             {
3833                 if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
3834                 {
3835                     RTMPWPARemoveKeyProc(pAdapter, pRemoveKey);
3836                     DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_REMOVE_KEY, Remove WPA Key!!\n"));
3837                 }
3838                 else
3839                 {
3840                     KeyIdx = pRemoveKey->KeyIndex;
3841
3842                     if (KeyIdx & 0x80000000)
3843                     {
3844                         // Should never set default bit when remove key
3845                         Status  = -EINVAL;
3846                         DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_REMOVE_KEY, Failed!!(Should never set default bit when remove key)\n"));
3847                     }
3848                     else
3849                     {
3850                         KeyIdx = KeyIdx & 0x0fffffff;
3851                         if (KeyIdx > 3)
3852                         {
3853                             Status  = -EINVAL;
3854                             DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_REMOVE_KEY, Failed!!(KeyId[%d] out of range)\n", KeyIdx));
3855                         }
3856                         else
3857                         {
3858                             pAdapter->SharedKey[BSS0][KeyIdx].KeyLen = 0;
3859                             pAdapter->SharedKey[BSS0][KeyIdx].CipherAlg = CIPHER_NONE;
3860                             AsicRemoveSharedKeyEntry(pAdapter, 0, (UCHAR)KeyIdx);
3861                             DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_REMOVE_KEY (id=0x%x, Len=%d-byte)\n", pRemoveKey->KeyIndex, pRemoveKey->Length));
3862                         }
3863                     }
3864                 }
3865             }
3866             kfree(pRemoveKey);
3867             break;
3868         // New for WPA
3869         case OID_802_11_ADD_KEY:
3870             pKey = kmalloc(wrq->u.data.length, MEM_ALLOC_FLAG);
3871             if(pKey == NULL)
3872             {
3873                 Status = -ENOMEM;
3874                 break;
3875             }
3876             Status = copy_from_user(pKey, wrq->u.data.pointer, wrq->u.data.length);
3877             if (pKey->Length != wrq->u.data.length)
3878             {
3879                 Status  = -EINVAL;
3880                 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_ADD_KEY, Failed!!\n"));
3881             }
3882             else
3883             {
3884                 RTMPAddKey(pAdapter, pKey);
3885                 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_ADD_KEY (id=0x%x, Len=%d-byte)\n", pKey->KeyIndex, pKey->KeyLength));
3886             }
3887             kfree(pKey);
3888             break;
3889         case OID_802_11_CONFIGURATION:
3890             if (wrq->u.data.length != sizeof(NDIS_802_11_CONFIGURATION))
3891                 Status  = -EINVAL;
3892             else
3893             {
3894                 Status = copy_from_user(&Config, wrq->u.data.pointer, wrq->u.data.length);
3895                 pConfig = &Config;
3896
3897                 if ((pConfig->BeaconPeriod >= 20) && (pConfig->BeaconPeriod <=400))
3898                      pAdapter->CommonCfg.BeaconPeriod = (USHORT) pConfig->BeaconPeriod;
3899
3900                 pAdapter->StaActive.AtimWin = (USHORT) pConfig->ATIMWindow;
3901                 MAP_KHZ_TO_CHANNEL_ID(pConfig->DSConfig, pAdapter->CommonCfg.Channel);
3902                 //
3903                                 // Save the channel on MlmeAux for CntlOidRTBssidProc used.
3904                                 //
3905                                 pAdapter->MlmeAux.Channel = pAdapter->CommonCfg.Channel;
3906
3907                 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_CONFIGURATION (BeacnPeriod=%ld,AtimW=%ld,Ch=%d)\n",
3908                     pConfig->BeaconPeriod, pConfig->ATIMWindow, pAdapter->CommonCfg.Channel));
3909                 // Config has changed
3910                 pAdapter->bConfigChanged = TRUE;
3911             }
3912             break;
3913 #ifdef DOT11_N_SUPPORT
3914                 case RT_OID_802_11_SET_HT_PHYMODE:
3915                         if (wrq->u.data.length  != sizeof(OID_SET_HT_PHYMODE))
3916                                 Status = -EINVAL;
3917                         else
3918                         {
3919                             POID_SET_HT_PHYMODE pHTPhyMode = &HT_PhyMode;
3920
3921                                 Status = copy_from_user(&HT_PhyMode, wrq->u.data.pointer, wrq->u.data.length);
3922                                 DBGPRINT(RT_DEBUG_TRACE, ("Set::pHTPhyMode      (PhyMode = %d,TransmitNo = %d, HtMode = %d,     ExtOffset =     %d , MCS = %d, BW =     %d,     STBC = %d, SHORTGI = %d) \n",
3923                                 pHTPhyMode->PhyMode, pHTPhyMode->TransmitNo,pHTPhyMode->HtMode,pHTPhyMode->ExtOffset,
3924                                 pHTPhyMode->MCS, pHTPhyMode->BW, pHTPhyMode->STBC,      pHTPhyMode->SHORTGI));
3925                                 if (pAdapter->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
3926                                         RTMPSetHT(pAdapter,     pHTPhyMode);
3927                         }
3928                         DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_SET_HT_PHYMODE(MCS=%d,BW=%d,SGI=%d,STBC=%d)\n",
3929                                 pAdapter->StaCfg.HTPhyMode.field.MCS, pAdapter->StaCfg.HTPhyMode.field.BW, pAdapter->StaCfg.HTPhyMode.field.ShortGI,
3930                                 pAdapter->StaCfg.HTPhyMode.field.STBC));
3931                         break;
3932 #endif // DOT11_N_SUPPORT //
3933                 case RT_OID_802_11_SET_APSD_SETTING:
3934                         if (wrq->u.data.length != sizeof(ULONG))
3935                                 Status = -EINVAL;
3936                         else
3937                         {
3938                                 ULONG apsd ;
3939                                 Status = copy_from_user(&apsd, wrq->u.data.pointer,     wrq->u.data.length);
3940
3941                                 /*-------------------------------------------------------------------
3942                                 |B31~B7 |       B6~B5    |       B4      |       B3      |      B2       |      B1       |         B0           |
3943                                 ---------------------------------------------------------------------
3944                                 | Rsvd  | Max SP Len | AC_VO | AC_VI | AC_BK | AC_BE | APSD     Capable |
3945                                 ---------------------------------------------------------------------*/
3946                                 pAdapter->CommonCfg.bAPSDCapable = (apsd & 0x00000001) ? TRUE : FALSE;
3947                                 pAdapter->CommonCfg.bAPSDAC_BE = ((apsd & 0x00000002) >> 1)     ? TRUE : FALSE;
3948                                 pAdapter->CommonCfg.bAPSDAC_BK = ((apsd & 0x00000004) >> 2)     ? TRUE : FALSE;
3949                                 pAdapter->CommonCfg.bAPSDAC_VI = ((apsd & 0x00000008) >> 3)     ? TRUE : FALSE;
3950                                 pAdapter->CommonCfg.bAPSDAC_VO = ((apsd & 0x00000010) >> 4)     ? TRUE : FALSE;
3951                                 pAdapter->CommonCfg.MaxSPLength = (UCHAR)((apsd & 0x00000060) >> 5);
3952
3953                                 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,
3954                                         pAdapter->CommonCfg.bAPSDAC_BE, pAdapter->CommonCfg.bAPSDAC_BK, pAdapter->CommonCfg.bAPSDAC_VI, pAdapter->CommonCfg.bAPSDAC_VO, pAdapter->CommonCfg.MaxSPLength));
3955                         }
3956                         break;
3957
3958                 case RT_OID_802_11_SET_APSD_PSM:
3959                         if (wrq->u.data.length  != sizeof(ULONG))
3960                                 Status = -EINVAL;
3961                         else
3962                         {
3963                                 // Driver needs to notify AP when PSM changes
3964                                 Status = copy_from_user(&pAdapter->CommonCfg.bAPSDForcePowerSave, wrq->u.data.pointer, wrq->u.data.length);
3965                                 if (pAdapter->CommonCfg.bAPSDForcePowerSave     != pAdapter->StaCfg.Psm)
3966                                 {
3967                                         MlmeSetPsmBit(pAdapter, pAdapter->CommonCfg.bAPSDForcePowerSave);
3968                                         RTMPSendNullFrame(pAdapter,     pAdapter->CommonCfg.TxRate,     TRUE);
3969                                 }
3970                                 DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_SET_APSD_PSM (bAPSDForcePowerSave:%d)\n", pAdapter->CommonCfg.bAPSDForcePowerSave));
3971                         }
3972                         break;
3973 #ifdef QOS_DLS_SUPPORT
3974                 case RT_OID_802_11_SET_DLS:
3975                         if (wrq->u.data.length != sizeof(ULONG))
3976                                 Status = -EINVAL;
3977                         else
3978                         {
3979                                 BOOLEAN oldvalue = pAdapter->CommonCfg.bDLSCapable;
3980                                 Status = copy_from_user(&pAdapter->CommonCfg.bDLSCapable, wrq->u.data.pointer, wrq->u.data.length);
3981                                 if (oldvalue && !pAdapter->CommonCfg.bDLSCapable)
3982                                 {
3983                                         int     i;
3984                                         // tear down local dls table entry
3985                                         for     (i=0; i<MAX_NUM_OF_INIT_DLS_ENTRY; i++)
3986                                         {
3987                                                 if (pAdapter->StaCfg.DLSEntry[i].Valid && (pAdapter->StaCfg.DLSEntry[i].Status == DLS_FINISH))
3988                                                 {
3989                                                         pAdapter->StaCfg.DLSEntry[i].Status     = DLS_NONE;
3990                                                         pAdapter->StaCfg.DLSEntry[i].Valid      = FALSE;
3991                                                         RTMPSendDLSTearDownFrame(pAdapter, pAdapter->StaCfg.DLSEntry[i].MacAddr);
3992                                                 }
3993                                         }
3994
3995                                         // tear down peer dls table     entry
3996                                         for     (i=MAX_NUM_OF_INIT_DLS_ENTRY; i<MAX_NUM_OF_DLS_ENTRY; i++)
3997                                         {
3998                                                 if (pAdapter->StaCfg.DLSEntry[i].Valid && (pAdapter->StaCfg.DLSEntry[i].Status == DLS_FINISH))
3999                                                 {
4000                                                         pAdapter->StaCfg.DLSEntry[i].Status     = DLS_NONE;
4001                                                         pAdapter->StaCfg.DLSEntry[i].Valid      = FALSE;
4002                                                         RTMPSendDLSTearDownFrame(pAdapter, pAdapter->StaCfg.DLSEntry[i].MacAddr);
4003                                                 }
4004                                         }
4005                                 }
4006
4007                                 DBGPRINT(RT_DEBUG_TRACE,("Set::RT_OID_802_11_SET_DLS (=%d)\n", pAdapter->CommonCfg.bDLSCapable));
4008                         }
4009                         break;
4010
4011                 case RT_OID_802_11_SET_DLS_PARAM:
4012                         if (wrq->u.data.length  != sizeof(RT_802_11_DLS_UI))
4013                                 Status = -EINVAL;
4014                         else
4015                         {
4016                                 RT_802_11_DLS   Dls;
4017
4018                                 NdisZeroMemory(&Dls, sizeof(RT_802_11_DLS));
4019                                 RTMPMoveMemory(&Dls, wrq->u.data.pointer, sizeof(RT_802_11_DLS_UI));
4020                                 MlmeEnqueue(pAdapter,
4021                                                         MLME_CNTL_STATE_MACHINE,
4022                                                         RT_OID_802_11_SET_DLS_PARAM,
4023                                                         sizeof(RT_802_11_DLS),
4024                                                         &Dls);
4025                                 DBGPRINT(RT_DEBUG_TRACE,("Set::RT_OID_802_11_SET_DLS_PARAM \n"));
4026                         }
4027                         break;
4028 #endif // QOS_DLS_SUPPORT //
4029                 case RT_OID_802_11_SET_WMM:
4030                         if (wrq->u.data.length  != sizeof(BOOLEAN))
4031                                 Status = -EINVAL;
4032                         else
4033                         {
4034                                 Status = copy_from_user(&pAdapter->CommonCfg.bWmmCapable, wrq->u.data.pointer, wrq->u.data.length);
4035                                 DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_SET_WMM (=%d)     \n", pAdapter->CommonCfg.bWmmCapable));
4036                         }
4037                         break;
4038
4039                 case OID_802_11_DISASSOCIATE:
4040 #ifdef RALINK_ATE
4041                         if (ATE_ON(pAdapter))
4042                         {
4043                                 DBGPRINT(RT_DEBUG_TRACE, ("The driver is in ATE mode now\n"));
4044                                 break;
4045                         }
4046 #endif // RALINK_ATE //
4047                         //
4048                         // Set NdisRadioStateOff to     TRUE, instead of called MlmeRadioOff.
4049                         // Later on, NDIS_802_11_BSSID_LIST_EX->NumberOfItems should be 0
4050                         // when query OID_802_11_BSSID_LIST.
4051                         //
4052                         // TRUE:  NumberOfItems will set to     0.
4053                         // FALSE: NumberOfItems no change.
4054                         //
4055                         pAdapter->CommonCfg.NdisRadioStateOff = TRUE;
4056                         // Set to immediately send the media disconnect event
4057                         pAdapter->MlmeAux.CurrReqIsFromNdis     = TRUE;
4058                         DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_DISASSOCIATE \n"));
4059
4060                         if (INFRA_ON(pAdapter))
4061                         {
4062                                 if (pAdapter->Mlme.CntlMachine.CurrState !=     CNTL_IDLE)
4063                                 {
4064                                         RT28XX_MLME_RESET_STATE_MACHINE(pAdapter);
4065                                         DBGPRINT(RT_DEBUG_TRACE, ("!!! MLME     busy, reset     MLME state machine !!!\n"));
4066                                 }
4067
4068                                 MlmeEnqueue(pAdapter,
4069                                         MLME_CNTL_STATE_MACHINE,
4070                                         OID_802_11_DISASSOCIATE,
4071                                         0,
4072                                         NULL);
4073
4074                                 StateMachineTouched     = TRUE;
4075                         }
4076                         break;
4077
4078 #ifdef DOT11_N_SUPPORT
4079                 case RT_OID_802_11_SET_IMME_BA_CAP:
4080                                 if (wrq->u.data.length != sizeof(OID_BACAP_STRUC))
4081                                         Status = -EINVAL;
4082                                 else
4083                                 {
4084                                         OID_BACAP_STRUC Orde ;
4085                                         Status = copy_from_user(&Orde, wrq->u.data.pointer, wrq->u.data.length);
4086                                         if (Orde.Policy > BA_NOTUSE)
4087                                         {
4088                                                 Status = NDIS_STATUS_INVALID_DATA;
4089                                         }
4090                                         else if (Orde.Policy == BA_NOTUSE)
4091                                         {
4092                                                 pAdapter->CommonCfg.BACapability.field.Policy = BA_NOTUSE;
4093                                                 pAdapter->CommonCfg.BACapability.field.MpduDensity = Orde.MpduDensity;
4094                                                 pAdapter->CommonCfg.DesiredHtPhy.MpduDensity = Orde.MpduDensity;
4095                                                 pAdapter->CommonCfg.DesiredHtPhy.AmsduEnable = Orde.AmsduEnable;
4096                                                 pAdapter->CommonCfg.DesiredHtPhy.AmsduSize= Orde.AmsduSize;
4097                                                 pAdapter->CommonCfg.DesiredHtPhy.MimoPs= Orde.MMPSmode;
4098                                                 pAdapter->CommonCfg.BACapability.field.MMPSmode = Orde.MMPSmode;
4099                                                 // UPdata to HT IE
4100                                                 pAdapter->CommonCfg.HtCapability.HtCapInfo.MimoPs = Orde.MMPSmode;
4101                                                 pAdapter->CommonCfg.HtCapability.HtCapInfo.AMsduSize = Orde.AmsduSize;
4102                                                 pAdapter->CommonCfg.HtCapability.HtCapParm.MpduDensity = Orde.MpduDensity;
4103                                         }
4104                                         else
4105                                         {
4106                         pAdapter->CommonCfg.BACapability.field.AutoBA = Orde.AutoBA;
4107                                                 pAdapter->CommonCfg.BACapability.field.Policy = IMMED_BA; // we only support immediate BA.
4108                                                 pAdapter->CommonCfg.BACapability.field.MpduDensity = Orde.MpduDensity;
4109                                                 pAdapter->CommonCfg.DesiredHtPhy.MpduDensity = Orde.MpduDensity;
4110                                                 pAdapter->CommonCfg.DesiredHtPhy.AmsduEnable = Orde.AmsduEnable;
4111                                                 pAdapter->CommonCfg.DesiredHtPhy.AmsduSize= Orde.AmsduSize;
4112                                                 pAdapter->CommonCfg.DesiredHtPhy.MimoPs = Orde.MMPSmode;
4113                                                 pAdapter->CommonCfg.BACapability.field.MMPSmode = Orde.MMPSmode;
4114
4115                                                 // UPdata to HT IE
4116                                                 pAdapter->CommonCfg.HtCapability.HtCapInfo.MimoPs = Orde.MMPSmode;
4117                                                 pAdapter->CommonCfg.HtCapability.HtCapInfo.AMsduSize = Orde.AmsduSize;
4118                                                 pAdapter->CommonCfg.HtCapability.HtCapParm.MpduDensity = Orde.MpduDensity;
4119
4120                                                 if (pAdapter->CommonCfg.BACapability.field.RxBAWinLimit > MAX_RX_REORDERBUF)
4121                                                         pAdapter->CommonCfg.BACapability.field.RxBAWinLimit = MAX_RX_REORDERBUF;
4122
4123                                         }
4124
4125                                         pAdapter->CommonCfg.REGBACapability.word = pAdapter->CommonCfg.BACapability.word;
4126                                         DBGPRINT(RT_DEBUG_TRACE, ("Set::(Orde.AutoBA = %d) (Policy=%d)(ReBAWinLimit=%d)(TxBAWinLimit=%d)(AutoMode=%d)\n",Orde.AutoBA, pAdapter->CommonCfg.BACapability.field.Policy,
4127                                                 pAdapter->CommonCfg.BACapability.field.RxBAWinLimit,pAdapter->CommonCfg.BACapability.field.TxBAWinLimit, pAdapter->CommonCfg.BACapability.field.AutoBA));
4128                                         DBGPRINT(RT_DEBUG_TRACE, ("Set::(MimoPs = %d)(AmsduEnable = %d) (AmsduSize=%d)(MpduDensity=%d)\n",pAdapter->CommonCfg.DesiredHtPhy.MimoPs, pAdapter->CommonCfg.DesiredHtPhy.AmsduEnable,
4129                                                 pAdapter->CommonCfg.DesiredHtPhy.AmsduSize, pAdapter->CommonCfg.DesiredHtPhy.MpduDensity));
4130                                 }
4131
4132                                 break;
4133                 case RT_OID_802_11_ADD_IMME_BA:
4134                         DBGPRINT(RT_DEBUG_TRACE, (" Set :: RT_OID_802_11_ADD_IMME_BA \n"));
4135                         if (wrq->u.data.length != sizeof(OID_ADD_BA_ENTRY))
4136                                         Status = -EINVAL;
4137                         else
4138                         {
4139                                 UCHAR                   index;
4140                                 OID_ADD_BA_ENTRY    BA;
4141                                 MAC_TABLE_ENTRY     *pEntry;
4142
4143                                 Status = copy_from_user(&BA, wrq->u.data.pointer, wrq->u.data.length);
4144                                 if (BA.TID > 15)
4145                                 {
4146                                         Status = NDIS_STATUS_INVALID_DATA;
4147                                         break;
4148                                 }
4149                                 else
4150                                 {
4151                                         //BATableInsertEntry
4152                                         //As ad-hoc mode, BA pair is not limited to only BSSID. so add via OID.
4153                                         index = BA.TID;
4154                                         // in ad hoc mode, when adding BA pair, we should insert this entry into MACEntry too
4155                                         pEntry = MacTableLookup(pAdapter, BA.MACAddr);
4156                                         if (!pEntry)
4157                                         {
4158                                                 DBGPRINT(RT_DEBUG_TRACE, ("RT_OID_802_11_ADD_IMME_BA. break on no connection.----:%x:%x\n", BA.MACAddr[4], BA.MACAddr[5]));
4159                                                 break;
4160                                         }
4161                                         if (BA.IsRecipient == FALSE)
4162                                         {
4163                                             if (pEntry->bIAmBadAtheros == TRUE)
4164                                                         pAdapter->CommonCfg.BACapability.field.RxBAWinLimit = 0x10;
4165
4166                                                 BAOriSessionSetUp(pAdapter, pEntry, index, 0, 100, TRUE);
4167                                         }
4168                                         else
4169                                         {
4170                                                 //BATableInsertEntry(pAdapter, pEntry->Aid, BA.MACAddr, 0, 0xffff, BA.TID, BA.nMSDU, BA.IsRecipient);
4171                                         }
4172
4173                                         DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_ADD_IMME_BA. Rec = %d. Mac = %x:%x:%x:%x:%x:%x . \n",
4174                                                 BA.IsRecipient, BA.MACAddr[0], BA.MACAddr[1], BA.MACAddr[2], BA.MACAddr[2]
4175                                                 , BA.MACAddr[4], BA.MACAddr[5]));
4176                                 }
4177                         }
4178                         break;
4179
4180                 case RT_OID_802_11_TEAR_IMME_BA:
4181                         DBGPRINT(RT_DEBUG_TRACE, ("Set :: RT_OID_802_11_TEAR_IMME_BA \n"));
4182                         if (wrq->u.data.length != sizeof(OID_ADD_BA_ENTRY))
4183                                         Status = -EINVAL;
4184                         else
4185                         {
4186                                 POID_ADD_BA_ENTRY       pBA;
4187                                 MAC_TABLE_ENTRY *pEntry;
4188
4189                                 pBA = kmalloc(wrq->u.data.length, MEM_ALLOC_FLAG);
4190
4191                                 if (pBA == NULL)
4192                                 {
4193                                         DBGPRINT(RT_DEBUG_TRACE, ("Set :: RT_OID_802_11_TEAR_IMME_BA kmalloc() can't allocate enough memory\n"));
4194                                         Status = NDIS_STATUS_FAILURE;
4195                                 }
4196                                 else
4197                                 {
4198                                         Status = copy_from_user(pBA, wrq->u.data.pointer, wrq->u.data.length);
4199                                         DBGPRINT(RT_DEBUG_TRACE, ("Set :: RT_OID_802_11_TEAR_IMME_BA(TID=%d, bAllTid=%d)\n", pBA->TID, pBA->bAllTid));
4200
4201                                         if (!pBA->bAllTid && (pBA->TID > NUM_OF_TID))
4202                                         {
4203                                                 Status = NDIS_STATUS_INVALID_DATA;
4204                                                 break;
4205                                         }
4206
4207                                         if (pBA->IsRecipient == FALSE)
4208                                         {
4209                                                 pEntry = MacTableLookup(pAdapter, pBA->MACAddr);
4210                                                 DBGPRINT(RT_DEBUG_TRACE, (" pBA->IsRecipient == FALSE\n"));
4211                                                 if (pEntry)
4212                                                 {
4213                                                         DBGPRINT(RT_DEBUG_TRACE, (" pBA->pEntry\n"));
4214                                                         BAOriSessionTearDown(pAdapter, pEntry->Aid, pBA->TID, FALSE, TRUE);
4215                                                 }
4216                                                 else
4217                                                         DBGPRINT(RT_DEBUG_TRACE, ("Set :: Not found pEntry \n"));
4218                                         }
4219                                         else
4220                                         {
4221                                                 pEntry = MacTableLookup(pAdapter, pBA->MACAddr);
4222                                                 if (pEntry)
4223                                                 {
4224                                                         BARecSessionTearDown( pAdapter, (UCHAR)pEntry->Aid, pBA->TID, TRUE);
4225                                                 }
4226                                                 else
4227                                                         DBGPRINT(RT_DEBUG_TRACE, ("Set :: Not found pEntry \n"));
4228                                         }
4229                                         kfree(pBA);
4230                                 }
4231             }
4232             break;
4233 #endif // DOT11_N_SUPPORT //
4234
4235         // For WPA_SUPPLICANT to set static wep key
4236         case OID_802_11_ADD_WEP:
4237             pWepKey = kmalloc(wrq->u.data.length, MEM_ALLOC_FLAG);
4238
4239             if(pWepKey == NULL)
4240             {
4241                 Status = -ENOMEM;
4242                                 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_ADD_WEP, Failed!!\n"));
4243                 break;
4244             }
4245             Status = copy_from_user(pWepKey, wrq->u.data.pointer, wrq->u.data.length);
4246             if (Status)
4247             {
4248                 Status  = -EINVAL;
4249                 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_ADD_WEP, Failed (length mismatch)!!\n"));
4250             }
4251             else
4252             {
4253                         KeyIdx = pWepKey->KeyIndex & 0x0fffffff;
4254                 // KeyIdx must be 0 ~ 3
4255                 if (KeyIdx > 4)
4256                         {
4257                     Status  = -EINVAL;
4258                     DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_ADD_WEP, Failed (KeyIdx must be smaller than 4)!!\n"));
4259                 }
4260                 else
4261                 {
4262                     UCHAR CipherAlg = 0;
4263                     PUCHAR Key;
4264
4265                     // set key material and key length
4266                     NdisZeroMemory(pAdapter->SharedKey[BSS0][KeyIdx].Key, 16);
4267                     pAdapter->SharedKey[BSS0][KeyIdx].KeyLen = (UCHAR) pWepKey->KeyLength;
4268                     NdisMoveMemory(pAdapter->SharedKey[BSS0][KeyIdx].Key, &pWepKey->KeyMaterial, pWepKey->KeyLength);
4269
4270                     switch(pWepKey->KeyLength)
4271                     {
4272                         case 5:
4273                             CipherAlg = CIPHER_WEP64;
4274                             break;
4275                         case 13:
4276                             CipherAlg = CIPHER_WEP128;
4277                             break;
4278                         default:
4279                             DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_ADD_WEP, only support CIPHER_WEP64(len:5) & CIPHER_WEP128(len:13)!!\n"));
4280                             Status = -EINVAL;
4281                             break;
4282                     }
4283                     pAdapter->SharedKey[BSS0][KeyIdx].CipherAlg = CipherAlg;
4284
4285                     // Default key for tx (shared key)
4286                     if (pWepKey->KeyIndex & 0x80000000)
4287                     {
4288 #ifdef WPA_SUPPLICANT_SUPPORT
4289                         // set key material and key length
4290                         NdisZeroMemory(pAdapter->StaCfg.DesireSharedKey[KeyIdx].Key, 16);
4291                         pAdapter->StaCfg.DesireSharedKey[KeyIdx].KeyLen = (UCHAR) pWepKey->KeyLength;
4292                         NdisMoveMemory(pAdapter->StaCfg.DesireSharedKey[KeyIdx].Key, &pWepKey->KeyMaterial, pWepKey->KeyLength);
4293                         pAdapter->StaCfg.DesireSharedKeyId = KeyIdx;
4294                         pAdapter->StaCfg.DesireSharedKey[KeyIdx].CipherAlg = CipherAlg;
4295 #endif // WPA_SUPPLICANT_SUPPORT //
4296                         pAdapter->StaCfg.DefaultKeyId = (UCHAR) KeyIdx;
4297                     }
4298
4299 #ifdef WPA_SUPPLICANT_SUPPORT
4300                                         if ((pAdapter->StaCfg.WpaSupplicantUP != 0) &&
4301                                                 (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA))
4302                                         {
4303                                                 Key = pWepKey->KeyMaterial;
4304
4305                                                 // Set Group key material to Asic
4306                                         AsicAddSharedKeyEntry(pAdapter, BSS0, KeyIdx, CipherAlg, Key, NULL, NULL);
4307
4308                                                 // Update WCID attribute table and IVEIV table for this group key table
4309                                                 RTMPAddWcidAttributeEntry(pAdapter, BSS0, KeyIdx, CipherAlg, NULL);
4310
4311                                                 STA_PORT_SECURED(pAdapter);
4312
4313                                         // Indicate Connected for GUI
4314                                         pAdapter->IndicateMediaState = NdisMediaStateConnected;
4315                                         }
4316                     else if (pAdapter->StaCfg.PortSecured == WPA_802_1X_PORT_SECURED)
4317 #endif // WPA_SUPPLICANT_SUPPORT
4318                     {
4319                         Key = pAdapter->SharedKey[BSS0][KeyIdx].Key;
4320
4321                         // Set key material and cipherAlg to Asic
4322                                         AsicAddSharedKeyEntry(pAdapter, BSS0, KeyIdx, CipherAlg, Key, NULL, NULL);
4323
4324                         if (pWepKey->KeyIndex & 0x80000000)
4325                         {
4326                             PMAC_TABLE_ENTRY pEntry = &pAdapter->MacTab.Content[BSSID_WCID];
4327                             // Assign group key info
4328                                                 RTMPAddWcidAttributeEntry(pAdapter, BSS0, KeyIdx, CipherAlg, NULL);
4329                                                 // Assign pairwise key info
4330                                                 RTMPAddWcidAttributeEntry(pAdapter, BSS0, KeyIdx, CipherAlg, pEntry);
4331                         }
4332                     }
4333                                         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"));
4334                                 }
4335             }
4336             kfree(pWepKey);
4337             break;
4338 #ifdef WPA_SUPPLICANT_SUPPORT
4339             case OID_SET_COUNTERMEASURES:
4340             if (wrq->u.data.length != sizeof(int))
4341                 Status  = -EINVAL;
4342             else
4343             {
4344                 int enabled = 0;
4345                 Status = copy_from_user(&enabled, wrq->u.data.pointer, wrq->u.data.length);
4346                 if (enabled == 1)
4347                     pAdapter->StaCfg.bBlockAssoc = TRUE;
4348                 else
4349                     // WPA MIC error should block association attempt for 60 seconds
4350                     pAdapter->StaCfg.bBlockAssoc = FALSE;
4351                 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_SET_COUNTERMEASURES bBlockAssoc=%s\n", pAdapter->StaCfg.bBlockAssoc ? "TRUE":"FALSE"));
4352             }
4353                 break;
4354         case RT_OID_WPA_SUPPLICANT_SUPPORT:
4355                         if (wrq->u.data.length != sizeof(UCHAR))
4356                 Status  = -EINVAL;
4357             else
4358             {
4359                 Status = copy_from_user(&wpa_supplicant_enable, wrq->u.data.pointer, wrq->u.data.length);
4360                         pAdapter->StaCfg.WpaSupplicantUP = wpa_supplicant_enable;
4361                         DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_WPA_SUPPLICANT_SUPPORT (=%d)\n", pAdapter->StaCfg.WpaSupplicantUP));
4362                         }
4363             break;
4364         case OID_802_11_DEAUTHENTICATION:
4365             if (wrq->u.data.length != sizeof(MLME_DEAUTH_REQ_STRUCT))
4366                 Status  = -EINVAL;
4367             else
4368             {
4369                 MLME_DEAUTH_REQ_STRUCT      *pInfo;
4370                                 MLME_QUEUE_ELEM *MsgElem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG);
4371
4372                 pInfo = (MLME_DEAUTH_REQ_STRUCT *) MsgElem->Msg;
4373                 Status = copy_from_user(pInfo, wrq->u.data.pointer, wrq->u.data.length);
4374                 MlmeDeauthReqAction(pAdapter, MsgElem);
4375                                 kfree(MsgElem);
4376
4377                 if (INFRA_ON(pAdapter))
4378                 {
4379                     LinkDown(pAdapter, FALSE);
4380                     pAdapter->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
4381                 }
4382                 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_DEAUTHENTICATION (Reason=%d)\n", pInfo->Reason));
4383             }
4384             break;
4385         case OID_802_11_DROP_UNENCRYPTED:
4386             if (wrq->u.data.length != sizeof(int))
4387                 Status  = -EINVAL;
4388             else
4389             {
4390                 int enabled = 0;
4391                 Status = copy_from_user(&enabled, wrq->u.data.pointer, wrq->u.data.length);
4392                 if (enabled == 1)
4393                     pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
4394                 else
4395                     pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
4396                                 NdisAcquireSpinLock(&pAdapter->MacTabLock);
4397                                 pAdapter->MacTab.Content[BSSID_WCID].PortSecured = pAdapter->StaCfg.PortSecured;
4398                                 NdisReleaseSpinLock(&pAdapter->MacTabLock);
4399                 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_DROP_UNENCRYPTED (=%d)\n", enabled));
4400             }
4401             break;
4402         case OID_802_11_SET_IEEE8021X:
4403             if (wrq->u.data.length != sizeof(BOOLEAN))
4404                 Status  = -EINVAL;
4405             else
4406             {
4407                 Status = copy_from_user(&IEEE8021xState, wrq->u.data.pointer, wrq->u.data.length);
4408                         pAdapter->StaCfg.IEEE8021X = IEEE8021xState;
4409                 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_SET_IEEE8021X (=%d)\n", IEEE8021xState));
4410             }
4411             break;
4412         case OID_802_11_SET_IEEE8021X_REQUIRE_KEY:
4413                         if (wrq->u.data.length != sizeof(BOOLEAN))
4414                                  Status  = -EINVAL;
4415             else
4416             {
4417                 Status = copy_from_user(&IEEE8021x_required_keys, wrq->u.data.pointer, wrq->u.data.length);
4418                                 pAdapter->StaCfg.IEEE8021x_required_keys = IEEE8021x_required_keys;
4419                                 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_SET_IEEE8021X_REQUIRE_KEY (%d)\n", IEEE8021x_required_keys));
4420                         }
4421                         break;
4422         case OID_802_11_PMKID:
4423                 pPmkId = kmalloc(wrq->u.data.length, MEM_ALLOC_FLAG);
4424
4425                 if(pPmkId == NULL) {
4426                 Status = -ENOMEM;
4427                 break;
4428             }
4429             Status = copy_from_user(pPmkId, wrq->u.data.pointer, wrq->u.data.length);
4430
4431                 // check the PMKID information
4432                 if (pPmkId->BSSIDInfoCount == 0)
4433                 NdisZeroMemory(pAdapter->StaCfg.SavedPMK, sizeof(BSSID_INFO)*PMKID_NO);
4434                 else
4435                 {
4436                         PBSSID_INFO     pBssIdInfo;
4437                         UINT            BssIdx;
4438                         UINT            CachedIdx;
4439
4440                         for (BssIdx = 0; BssIdx < pPmkId->BSSIDInfoCount; BssIdx++)
4441                         {
4442                                 // point to the indexed BSSID_INFO structure
4443                                 pBssIdInfo = (PBSSID_INFO) ((PUCHAR) pPmkId + 2 * sizeof(UINT) + BssIdx * sizeof(BSSID_INFO));
4444                                 // Find the entry in the saved data base.
4445                                 for (CachedIdx = 0; CachedIdx < pAdapter->StaCfg.SavedPMKNum; CachedIdx++)
4446                                 {
4447                                         // compare the BSSID
4448                                         if (NdisEqualMemory(pBssIdInfo->BSSID, pAdapter->StaCfg.SavedPMK[CachedIdx].BSSID, sizeof(NDIS_802_11_MAC_ADDRESS)))
4449                                                 break;
4450                                 }
4451
4452                                 // Found, replace it
4453                                 if (CachedIdx < PMKID_NO)
4454                                 {
4455                                         DBGPRINT(RT_DEBUG_OFF, ("Update OID_802_11_PMKID, idx = %d\n", CachedIdx));
4456                                         NdisMoveMemory(&pAdapter->StaCfg.SavedPMK[CachedIdx], pBssIdInfo, sizeof(BSSID_INFO));
4457                                         pAdapter->StaCfg.SavedPMKNum++;
4458                                 }
4459                                 // Not found, replace the last one
4460                                 else
4461                                 {
4462                                         // Randomly replace one
4463                                         CachedIdx = (pBssIdInfo->BSSID[5] % PMKID_NO);
4464                                         DBGPRINT(RT_DEBUG_OFF, ("Update OID_802_11_PMKID, idx = %d\n", CachedIdx));
4465                                         NdisMoveMemory(&pAdapter->StaCfg.SavedPMK[CachedIdx], pBssIdInfo, sizeof(BSSID_INFO));
4466                                 }
4467                         }
4468                         }
4469                         if(pPmkId)
4470                                 kfree(pPmkId);
4471                 break;
4472 #endif // WPA_SUPPLICANT_SUPPORT //
4473
4474
4475
4476 #ifdef SNMP_SUPPORT
4477                 case OID_802_11_SHORTRETRYLIMIT:
4478                         if (wrq->u.data.length != sizeof(ULONG))
4479                                 Status = -EINVAL;
4480                         else
4481                         {
4482                                 Status = copy_from_user(&ShortRetryLimit, wrq->u.data.pointer, wrq->u.data.length);
4483                                 RTMP_IO_READ32(pAdapter, TX_RTY_CFG, &tx_rty_cfg.word);
4484                                 tx_rty_cfg.field.ShortRtyLimit = ShortRetryLimit;
4485                                 RTMP_IO_WRITE32(pAdapter, TX_RTY_CFG, tx_rty_cfg.word);
4486                                 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_SHORTRETRYLIMIT (tx_rty_cfg.field.ShortRetryLimit=%d, ShortRetryLimit=%ld)\n", tx_rty_cfg.field.ShortRtyLimit, ShortRetryLimit));
4487                         }
4488                         break;
4489
4490                 case OID_802_11_LONGRETRYLIMIT:
4491                         DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_LONGRETRYLIMIT \n"));
4492                         if (wrq->u.data.length != sizeof(ULONG))
4493                                 Status = -EINVAL;
4494                         else
4495                         {
4496                                 Status = copy_from_user(&LongRetryLimit, wrq->u.data.pointer, wrq->u.data.length);
4497                                 RTMP_IO_READ32(pAdapter, TX_RTY_CFG, &tx_rty_cfg.word);
4498                                 tx_rty_cfg.field.LongRtyLimit = LongRetryLimit;
4499                                 RTMP_IO_WRITE32(pAdapter, TX_RTY_CFG, tx_rty_cfg.word);
4500                                 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_LONGRETRYLIMIT (tx_rty_cfg.field.LongRetryLimit= %d,LongRetryLimit=%ld)\n", tx_rty_cfg.field.LongRtyLimit, LongRetryLimit));
4501                         }
4502                         break;
4503
4504                 case OID_802_11_WEPDEFAULTKEYVALUE:
4505                         DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_WEPDEFAULTKEYVALUE\n"));
4506                         pKey = kmalloc(wrq->u.data.length, GFP_KERNEL);
4507                         Status = copy_from_user(pKey, wrq->u.data.pointer, wrq->u.data.length);
4508                         //pKey = &WepKey;
4509
4510                         if ( pKey->Length != wrq->u.data.length)
4511                         {
4512                                 Status = -EINVAL;
4513                                 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_WEPDEFAULTKEYVALUE, Failed!!\n"));
4514                         }
4515                         KeyIdx = pKey->KeyIndex & 0x0fffffff;
4516                         DBGPRINT(RT_DEBUG_TRACE,("pKey->KeyIndex =%d, pKey->KeyLength=%d\n", pKey->KeyIndex, pKey->KeyLength));
4517
4518                         // it is a shared key
4519                         if (KeyIdx > 4)
4520                                 Status = -EINVAL;
4521                         else
4522                         {
4523                                 pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].KeyLen = (UCHAR) pKey->KeyLength;
4524                                 NdisMoveMemory(&pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].Key, &pKey->KeyMaterial, pKey->KeyLength);
4525                                 if (pKey->KeyIndex & 0x80000000)
4526                                 {
4527                                         // Default key for tx (shared key)
4528                                         pAdapter->StaCfg.DefaultKeyId = (UCHAR) KeyIdx;
4529                                 }
4530                                 //RestartAPIsRequired = TRUE;
4531                         }
4532                         break;
4533
4534
4535                 case OID_802_11_WEPDEFAULTKEYID:
4536                         DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_WEPDEFAULTKEYID \n"));
4537
4538                         if (wrq->u.data.length != sizeof(UCHAR))
4539                                 Status = -EINVAL;
4540                         else
4541                                 Status = copy_from_user(&pAdapter->StaCfg.DefaultKeyId, wrq->u.data.pointer, wrq->u.data.length);
4542
4543                         break;
4544
4545
4546                 case OID_802_11_CURRENTCHANNEL:
4547                         DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_CURRENTCHANNEL \n"));
4548                         if (wrq->u.data.length != sizeof(UCHAR))
4549                                 Status = -EINVAL;
4550                         else
4551                         {
4552                                 Status = copy_from_user(&ctmp, wrq->u.data.pointer, wrq->u.data.length);
4553                                 sprintf(&ctmp,"%d", ctmp);
4554                                 Set_Channel_Proc(pAdapter, &ctmp);
4555                         }
4556                         break;
4557 #endif
4558
4559
4560
4561         default:
4562             DBGPRINT(RT_DEBUG_TRACE, ("Set::unknown IOCTL's subcmd = 0x%08x\n", cmd));
4563             Status = -EOPNOTSUPP;
4564             break;
4565     }
4566
4567
4568     return Status;
4569 }
4570
4571 INT RTMPQueryInformation(
4572     IN  PRTMP_ADAPTER pAdapter,
4573     IN  OUT struct ifreq    *rq,
4574     IN  INT                 cmd)
4575 {
4576     struct iwreq                        *wrq = (struct iwreq *) rq;
4577     NDIS_802_11_BSSID_LIST_EX           *pBssidList = NULL;
4578     PNDIS_WLAN_BSSID_EX                 pBss;
4579     NDIS_802_11_SSID                    Ssid;
4580     NDIS_802_11_CONFIGURATION           *pConfiguration = NULL;
4581     RT_802_11_LINK_STATUS               *pLinkStatus = NULL;
4582     RT_802_11_STA_CONFIG                *pStaConfig = NULL;
4583     NDIS_802_11_STATISTICS              *pStatistics = NULL;
4584     NDIS_802_11_RTS_THRESHOLD           RtsThresh;
4585     NDIS_802_11_FRAGMENTATION_THRESHOLD FragThresh;
4586     NDIS_802_11_POWER_MODE              PowerMode;
4587     NDIS_802_11_NETWORK_INFRASTRUCTURE  BssType;
4588     RT_802_11_PREAMBLE                  PreamType;
4589     NDIS_802_11_AUTHENTICATION_MODE     AuthMode;
4590     NDIS_802_11_WEP_STATUS              WepStatus;
4591     NDIS_MEDIA_STATE                    MediaState;
4592     ULONG                               BssBufSize, ulInfo=0, NetworkTypeList[4], apsd = 0;
4593     USHORT                              BssLen = 0;
4594     PUCHAR                              pBuf = NULL, pPtr;
4595     INT                                 Status = NDIS_STATUS_SUCCESS;
4596     UINT                                we_version_compiled;
4597     UCHAR                               i, Padding = 0;
4598     BOOLEAN                             RadioState;
4599         UCHAR   driverVersion[8];
4600     OID_SET_HT_PHYMODE                          *pHTPhyMode = NULL;
4601
4602
4603 #ifdef SNMP_SUPPORT
4604         //for snmp, kathy
4605         DefaultKeyIdxValue                      *pKeyIdxValue;
4606         INT                                                     valueLen;
4607         TX_RTY_CFG_STRUC                        tx_rty_cfg;
4608         ULONG                                           ShortRetryLimit, LongRetryLimit;
4609         UCHAR                                           tmp[64];
4610 #endif //SNMP
4611
4612     switch(cmd)
4613     {
4614         case RT_OID_DEVICE_NAME:
4615             wrq->u.data.length = sizeof(STA_NIC_DEVICE_NAME);
4616             Status = copy_to_user(wrq->u.data.pointer, STA_NIC_DEVICE_NAME, wrq->u.data.length);
4617             break;
4618         case RT_OID_VERSION_INFO:
4619                         DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_VERSION_INFO \n"));
4620                         wrq->u.data.length = 8*sizeof(UCHAR);
4621                         sprintf(&driverVersion[0], "%s", STA_DRIVER_VERSION);
4622                         driverVersion[7] = '\0';
4623                         if (copy_to_user(wrq->u.data.pointer, &driverVersion, wrq->u.data.length))
4624             {
4625                                 Status = -EFAULT;
4626             }
4627             break;
4628 #ifdef RALINK_ATE
4629                 case RT_QUERY_ATE_TXDONE_COUNT:
4630                         DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_QUERY_ATE_TXDONE_COUNT \n"));
4631                         wrq->u.data.length = sizeof(UINT32);
4632                         if (copy_to_user(wrq->u.data.pointer, &pAdapter->ate.TxDoneCount, wrq->u.data.length))
4633                         {
4634                                 Status = -EFAULT;
4635                         }
4636                         break;
4637 #endif // RALINK_ATE //
4638         case OID_802_11_BSSID_LIST:
4639             if (RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
4640             {
4641                 /*
4642                  * Still scanning, indicate the caller should try again.
4643                  */
4644                 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_BSSID_LIST (Still scanning)\n"));
4645                                 return -EAGAIN;
4646             }
4647             DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_BSSID_LIST (%d BSS returned)\n",pAdapter->ScanTab.BssNr));
4648                         pAdapter->StaCfg.bScanReqIsFromWebUI = FALSE;
4649             // Claculate total buffer size required
4650             BssBufSize = sizeof(ULONG);
4651
4652             for (i = 0; i < pAdapter->ScanTab.BssNr; i++)
4653             {
4654                 // Align pointer to 4 bytes boundary.
4655                 //Padding = 4 - (pAdapter->ScanTab.BssEntry[i].VarIELen & 0x0003);
4656                 //if (Padding == 4)
4657                 //    Padding = 0;
4658                 BssBufSize += (sizeof(NDIS_WLAN_BSSID_EX) - 1 + sizeof(NDIS_802_11_FIXED_IEs) + pAdapter->ScanTab.BssEntry[i].VarIELen + Padding);
4659             }
4660
4661             // For safety issue, we add 256 bytes just in case
4662             BssBufSize += 256;
4663             // Allocate the same size as passed from higher layer
4664             pBuf = kmalloc(BssBufSize, MEM_ALLOC_FLAG);
4665             if(pBuf == NULL)
4666             {
4667                 Status = -ENOMEM;
4668                 break;
4669             }
4670             // Init 802_11_BSSID_LIST_EX structure
4671             NdisZeroMemory(pBuf, BssBufSize);
4672             pBssidList = (PNDIS_802_11_BSSID_LIST_EX) pBuf;
4673             pBssidList->NumberOfItems = pAdapter->ScanTab.BssNr;
4674
4675             // Calculate total buffer length
4676             BssLen = 4; // Consist of NumberOfItems
4677             // Point to start of NDIS_WLAN_BSSID_EX
4678             // pPtr = pBuf + sizeof(ULONG);
4679             pPtr = (PUCHAR) &pBssidList->Bssid[0];
4680             for (i = 0; i < pAdapter->ScanTab.BssNr; i++)
4681             {
4682                 pBss = (PNDIS_WLAN_BSSID_EX) pPtr;
4683                 NdisMoveMemory(&pBss->MacAddress, &pAdapter->ScanTab.BssEntry[i].Bssid, MAC_ADDR_LEN);
4684                 if ((pAdapter->ScanTab.BssEntry[i].Hidden == 1) && (pAdapter->StaCfg.bShowHiddenSSID == FALSE))
4685                 {
4686                     //
4687                                         // We must return this SSID during 4way handshaking, otherwise Aegis will failed to parse WPA infomation
4688                                         // and then failed to send EAPOl farame.
4689                                         //
4690                                         if ((pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA) && (pAdapter->StaCfg.PortSecured != WPA_802_1X_PORT_SECURED))
4691                                         {
4692                                                 pBss->Ssid.SsidLength = pAdapter->ScanTab.BssEntry[i].SsidLen;
4693                                                 NdisMoveMemory(pBss->Ssid.Ssid, pAdapter->ScanTab.BssEntry[i].Ssid, pAdapter->ScanTab.BssEntry[i].SsidLen);
4694                                         }
4695                                         else
4696                         pBss->Ssid.SsidLength = 0;
4697                 }
4698                 else
4699                 {
4700                     pBss->Ssid.SsidLength = pAdapter->ScanTab.BssEntry[i].SsidLen;
4701                     NdisMoveMemory(pBss->Ssid.Ssid, pAdapter->ScanTab.BssEntry[i].Ssid, pAdapter->ScanTab.BssEntry[i].SsidLen);
4702                 }
4703                 pBss->Privacy = pAdapter->ScanTab.BssEntry[i].Privacy;
4704                 pBss->Rssi = pAdapter->ScanTab.BssEntry[i].Rssi - pAdapter->BbpRssiToDbmDelta;
4705                 pBss->NetworkTypeInUse = NetworkTypeInUseSanity(&pAdapter->ScanTab.BssEntry[i]);
4706                 pBss->Configuration.Length = sizeof(NDIS_802_11_CONFIGURATION);
4707                 pBss->Configuration.BeaconPeriod = pAdapter->ScanTab.BssEntry[i].BeaconPeriod;
4708                 pBss->Configuration.ATIMWindow = pAdapter->ScanTab.BssEntry[i].AtimWin;
4709
4710                 MAP_CHANNEL_ID_TO_KHZ(pAdapter->ScanTab.BssEntry[i].Channel, pBss->Configuration.DSConfig);
4711
4712                 if (pAdapter->ScanTab.BssEntry[i].BssType == BSS_INFRA)
4713                     pBss->InfrastructureMode = Ndis802_11Infrastructure;
4714                 else
4715                     pBss->InfrastructureMode = Ndis802_11IBSS;
4716
4717                 NdisMoveMemory(pBss->SupportedRates, pAdapter->ScanTab.BssEntry[i].SupRate, pAdapter->ScanTab.BssEntry[i].SupRateLen);
4718                 NdisMoveMemory(pBss->SupportedRates + pAdapter->ScanTab.BssEntry[i].SupRateLen,
4719                                pAdapter->ScanTab.BssEntry[i].ExtRate,
4720                                pAdapter->ScanTab.BssEntry[i].ExtRateLen);
4721
4722                 if (pAdapter->ScanTab.BssEntry[i].VarIELen == 0)
4723                 {
4724                     pBss->IELength = sizeof(NDIS_802_11_FIXED_IEs);
4725                     NdisMoveMemory(pBss->IEs, &pAdapter->ScanTab.BssEntry[i].FixIEs, sizeof(NDIS_802_11_FIXED_IEs));
4726                     pPtr = pPtr + sizeof(NDIS_WLAN_BSSID_EX) - 1 + sizeof(NDIS_802_11_FIXED_IEs);
4727                 }
4728                 else
4729                 {
4730                     pBss->IELength = (ULONG)(sizeof(NDIS_802_11_FIXED_IEs) + pAdapter->ScanTab.BssEntry[i].VarIELen);
4731                     pPtr = pPtr + sizeof(NDIS_WLAN_BSSID_EX) - 1 + sizeof(NDIS_802_11_FIXED_IEs);
4732                     NdisMoveMemory(pBss->IEs, &pAdapter->ScanTab.BssEntry[i].FixIEs, sizeof(NDIS_802_11_FIXED_IEs));
4733                     NdisMoveMemory(pBss->IEs + sizeof(NDIS_802_11_FIXED_IEs), pAdapter->ScanTab.BssEntry[i].VarIEs, pAdapter->ScanTab.BssEntry[i].VarIELen);
4734                     pPtr += pAdapter->ScanTab.BssEntry[i].VarIELen;
4735                 }
4736                 pBss->Length = (ULONG)(sizeof(NDIS_WLAN_BSSID_EX) - 1 + sizeof(NDIS_802_11_FIXED_IEs) + pAdapter->ScanTab.BssEntry[i].VarIELen + Padding);
4737
4738 #if WIRELESS_EXT < 17
4739                 if ((BssLen + pBss->Length) < wrq->u.data.length)
4740                 BssLen += pBss->Length;
4741                 else
4742                 {
4743                     pBssidList->NumberOfItems = i;
4744                     break;
4745                 }
4746 #else
4747                 BssLen += pBss->Length;
4748 #endif
4749             }
4750
4751 #if WIRELESS_EXT < 17
4752             wrq->u.data.length = BssLen;
4753 #else
4754             if (BssLen > wrq->u.data.length)
4755             {
4756                 kfree(pBssidList);
4757                 return -E2BIG;
4758             }
4759             else
4760                 wrq->u.data.length = BssLen;
4761 #endif
4762             Status = copy_to_user(wrq->u.data.pointer, pBssidList, BssLen);
4763             kfree(pBssidList);
4764             break;
4765         case OID_802_3_CURRENT_ADDRESS:
4766             wrq->u.data.length = MAC_ADDR_LEN;
4767             Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CurrentAddress, wrq->u.data.length);
4768             break;
4769         case OID_GEN_MEDIA_CONNECT_STATUS:
4770             if (pAdapter->IndicateMediaState == NdisMediaStateConnected)
4771                 MediaState = NdisMediaStateConnected;
4772             else
4773                 MediaState = NdisMediaStateDisconnected;
4774
4775             wrq->u.data.length = sizeof(NDIS_MEDIA_STATE);
4776             Status = copy_to_user(wrq->u.data.pointer, &MediaState, wrq->u.data.length);
4777             break;
4778         case OID_802_11_BSSID:
4779 #ifdef RALINK_ATE
4780                         if (ATE_ON(pAdapter))
4781                         {
4782                                 DBGPRINT(RT_DEBUG_TRACE, ("The driver is in ATE mode now\n"));
4783                                 Status = NDIS_STATUS_RESOURCES;
4784                                 break;
4785                         }
4786 #endif // RALINK_ATE //
4787             if (INFRA_ON(pAdapter) || ADHOC_ON(pAdapter))
4788             {
4789                 Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.Bssid, sizeof(NDIS_802_11_MAC_ADDRESS));
4790
4791             }
4792             else
4793             {
4794                 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_BSSID(=EMPTY)\n"));
4795                 Status = -ENOTCONN;
4796             }
4797             break;
4798         case OID_802_11_SSID:
4799                         NdisZeroMemory(&Ssid, sizeof(NDIS_802_11_SSID));
4800                         NdisZeroMemory(Ssid.Ssid, MAX_LEN_OF_SSID);
4801             Ssid.SsidLength = pAdapter->CommonCfg.SsidLen;
4802                         memcpy(Ssid.Ssid, pAdapter->CommonCfg.Ssid,     Ssid.SsidLength);
4803             wrq->u.data.length = sizeof(NDIS_802_11_SSID);
4804             Status = copy_to_user(wrq->u.data.pointer, &Ssid, wrq->u.data.length);
4805             DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_SSID (Len=%d, ssid=%s)\n", Ssid.SsidLength,Ssid.Ssid));
4806             break;
4807         case RT_OID_802_11_QUERY_LINK_STATUS:
4808             pLinkStatus = (RT_802_11_LINK_STATUS *) kmalloc(sizeof(RT_802_11_LINK_STATUS), MEM_ALLOC_FLAG);
4809             if (pLinkStatus)
4810             {
4811                 pLinkStatus->CurrTxRate = RateIdTo500Kbps[pAdapter->CommonCfg.TxRate];   // unit : 500 kbps
4812                 pLinkStatus->ChannelQuality = pAdapter->Mlme.ChannelQuality;
4813                 pLinkStatus->RxByteCount = pAdapter->RalinkCounters.ReceivedByteCount;
4814                 pLinkStatus->TxByteCount = pAdapter->RalinkCounters.TransmittedByteCount;
4815                         pLinkStatus->CentralChannel = pAdapter->CommonCfg.CentralChannel;
4816                 wrq->u.data.length = sizeof(RT_802_11_LINK_STATUS);
4817                 Status = copy_to_user(wrq->u.data.pointer, pLinkStatus, wrq->u.data.length);
4818                 kfree(pLinkStatus);
4819                 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_LINK_STATUS\n"));
4820             }
4821             else
4822             {
4823                 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_LINK_STATUS(kmalloc failed)\n"));
4824                 Status = -EFAULT;
4825             }
4826             break;
4827         case OID_802_11_CONFIGURATION:
4828             pConfiguration = (NDIS_802_11_CONFIGURATION *) kmalloc(sizeof(NDIS_802_11_CONFIGURATION), MEM_ALLOC_FLAG);
4829             if (pConfiguration)
4830             {
4831                 pConfiguration->Length = sizeof(NDIS_802_11_CONFIGURATION);
4832                 pConfiguration->BeaconPeriod = pAdapter->CommonCfg.BeaconPeriod;
4833                 pConfiguration->ATIMWindow = pAdapter->StaActive.AtimWin;
4834                 MAP_CHANNEL_ID_TO_KHZ(pAdapter->CommonCfg.Channel, pConfiguration->DSConfig);
4835                 wrq->u.data.length = sizeof(NDIS_802_11_CONFIGURATION);
4836                 Status = copy_to_user(wrq->u.data.pointer, pConfiguration, wrq->u.data.length);
4837                 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_CONFIGURATION(BeaconPeriod=%ld,AtimW=%ld,Channel=%d) \n",
4838                                         pConfiguration->BeaconPeriod, pConfiguration->ATIMWindow, pAdapter->CommonCfg.Channel));
4839                                 kfree(pConfiguration);
4840             }
4841             else
4842             {
4843                 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_CONFIGURATION(kmalloc failed)\n"));
4844                 Status = -EFAULT;
4845             }
4846             break;
4847                 case RT_OID_802_11_SNR_0:
4848                         if ((pAdapter->StaCfg.LastSNR0 > 0))
4849                         {
4850                                 ulInfo = ((0xeb - pAdapter->StaCfg.LastSNR0) * 3) /     16 ;
4851                                 wrq->u.data.length = sizeof(ulInfo);
4852                                 Status = copy_to_user(wrq->u.data.pointer, &ulInfo,     wrq->u.data.length);
4853                                 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_SNR_0(0x=%lx)\n", ulInfo));
4854                         }
4855             else
4856                             Status = -EFAULT;
4857                         break;
4858                 case RT_OID_802_11_SNR_1:
4859                         if ((pAdapter->Antenna.field.RxPath     > 1) &&
4860                 (pAdapter->StaCfg.LastSNR1 > 0))
4861                         {
4862                                 ulInfo = ((0xeb - pAdapter->StaCfg.LastSNR1) * 3) /     16 ;
4863                                 wrq->u.data.length = sizeof(ulInfo);
4864                                 Status = copy_to_user(wrq->u.data.pointer, &ulInfo,     wrq->u.data.length);
4865                                 DBGPRINT(RT_DEBUG_TRACE,("Query::RT_OID_802_11_SNR_1(0x=%lx)\n",ulInfo));
4866                         }
4867                         else
4868                                 Status = -EFAULT;
4869             DBGPRINT(RT_DEBUG_TRACE,("Query::RT_OID_802_11_SNR_1(pAdapter->StaCfg.LastSNR1=%d)\n",pAdapter->StaCfg.LastSNR1));
4870                         break;
4871         case OID_802_11_RSSI_TRIGGER:
4872             ulInfo = pAdapter->StaCfg.RssiSample.LastRssi0 - pAdapter->BbpRssiToDbmDelta;
4873             wrq->u.data.length = sizeof(ulInfo);
4874             Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
4875             DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_RSSI_TRIGGER(=%ld)\n", ulInfo));
4876             break;
4877                 case OID_802_11_RSSI:
4878         case RT_OID_802_11_RSSI:
4879                         ulInfo = pAdapter->StaCfg.RssiSample.LastRssi0;
4880                         wrq->u.data.length = sizeof(ulInfo);
4881                         Status = copy_to_user(wrq->u.data.pointer, &ulInfo,     wrq->u.data.length);
4882                         break;
4883                 case RT_OID_802_11_RSSI_1:
4884             ulInfo = pAdapter->StaCfg.RssiSample.LastRssi1;
4885                         wrq->u.data.length = sizeof(ulInfo);
4886                         Status = copy_to_user(wrq->u.data.pointer, &ulInfo,     wrq->u.data.length);
4887                         break;
4888         case RT_OID_802_11_RSSI_2:
4889             ulInfo = pAdapter->StaCfg.RssiSample.LastRssi2;
4890                         wrq->u.data.length = sizeof(ulInfo);
4891                         Status = copy_to_user(wrq->u.data.pointer, &ulInfo,     wrq->u.data.length);
4892                         break;
4893         case OID_802_11_STATISTICS:
4894             pStatistics = (NDIS_802_11_STATISTICS *) kmalloc(sizeof(NDIS_802_11_STATISTICS), MEM_ALLOC_FLAG);
4895             if (pStatistics)
4896             {
4897                 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_STATISTICS \n"));
4898                 // add the most up-to-date h/w raw counters into software counters
4899                             NICUpdateRawCounters(pAdapter);
4900
4901                 // Sanity check for calculation of sucessful count
4902                 if (pAdapter->WlanCounters.TransmittedFragmentCount.QuadPart < pAdapter->WlanCounters.RetryCount.QuadPart)
4903                     pAdapter->WlanCounters.TransmittedFragmentCount.QuadPart = pAdapter->WlanCounters.RetryCount.QuadPart;
4904
4905                 pStatistics->TransmittedFragmentCount.QuadPart = pAdapter->WlanCounters.TransmittedFragmentCount.QuadPart;
4906                 pStatistics->MulticastTransmittedFrameCount.QuadPart = pAdapter->WlanCounters.MulticastTransmittedFrameCount.QuadPart;
4907                 pStatistics->FailedCount.QuadPart = pAdapter->WlanCounters.FailedCount.QuadPart;
4908                 pStatistics->RetryCount.QuadPart = pAdapter->WlanCounters.RetryCount.QuadPart;
4909                 pStatistics->MultipleRetryCount.QuadPart = pAdapter->WlanCounters.MultipleRetryCount.QuadPart;
4910                 pStatistics->RTSSuccessCount.QuadPart = pAdapter->WlanCounters.RTSSuccessCount.QuadPart;
4911                 pStatistics->RTSFailureCount.QuadPart = pAdapter->WlanCounters.RTSFailureCount.QuadPart;
4912                 pStatistics->ACKFailureCount.QuadPart = pAdapter->WlanCounters.ACKFailureCount.QuadPart;
4913                 pStatistics->FrameDuplicateCount.QuadPart = pAdapter->WlanCounters.FrameDuplicateCount.QuadPart;
4914                 pStatistics->ReceivedFragmentCount.QuadPart = pAdapter->WlanCounters.ReceivedFragmentCount.QuadPart;
4915                 pStatistics->MulticastReceivedFrameCount.QuadPart = pAdapter->WlanCounters.MulticastReceivedFrameCount.QuadPart;
4916 #ifdef DBG
4917                 pStatistics->FCSErrorCount = pAdapter->RalinkCounters.RealFcsErrCount;
4918 #else
4919                 pStatistics->FCSErrorCount.QuadPart = pAdapter->WlanCounters.FCSErrorCount.QuadPart;
4920                 pStatistics->FrameDuplicateCount.u.LowPart = pAdapter->WlanCounters.FrameDuplicateCount.u.LowPart / 100;
4921 #endif
4922                 wrq->u.data.length = sizeof(NDIS_802_11_STATISTICS);
4923                 Status = copy_to_user(wrq->u.data.pointer, pStatistics, wrq->u.data.length);
4924                 kfree(pStatistics);
4925             }
4926             else
4927             {
4928                 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_STATISTICS(kmalloc failed)\n"));
4929                 Status = -EFAULT;
4930             }
4931             break;
4932         case OID_GEN_RCV_OK:
4933             ulInfo = pAdapter->Counters8023.GoodReceives;
4934             wrq->u.data.length = sizeof(ulInfo);
4935             Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
4936             break;
4937         case OID_GEN_RCV_NO_BUFFER:
4938             ulInfo = pAdapter->Counters8023.RxNoBuffer;
4939             wrq->u.data.length = sizeof(ulInfo);
4940             Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
4941             break;
4942         case RT_OID_802_11_PHY_MODE:
4943             ulInfo = (ULONG)pAdapter->CommonCfg.PhyMode;
4944             wrq->u.data.length = sizeof(ulInfo);
4945             Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
4946             DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_PHY_MODE (=%ld)\n", ulInfo));
4947             break;
4948         case RT_OID_802_11_STA_CONFIG:
4949             pStaConfig = (RT_802_11_STA_CONFIG *) kmalloc(sizeof(RT_802_11_STA_CONFIG), MEM_ALLOC_FLAG);
4950             if (pStaConfig)
4951             {
4952                 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_STA_CONFIG\n"));
4953                 pStaConfig->EnableTxBurst = pAdapter->CommonCfg.bEnableTxBurst;
4954                 pStaConfig->EnableTurboRate = 0;
4955                 pStaConfig->UseBGProtection = pAdapter->CommonCfg.UseBGProtection;
4956                 pStaConfig->UseShortSlotTime = pAdapter->CommonCfg.bUseShortSlotTime;
4957                 //pStaConfig->AdhocMode = pAdapter->StaCfg.AdhocMode;
4958                 pStaConfig->HwRadioStatus = (pAdapter->StaCfg.bHwRadio == TRUE) ? 1 : 0;
4959                 pStaConfig->Rsv1 = 0;
4960                 pStaConfig->SystemErrorBitmap = pAdapter->SystemErrorBitmap;
4961                 wrq->u.data.length = sizeof(RT_802_11_STA_CONFIG);
4962                 Status = copy_to_user(wrq->u.data.pointer, pStaConfig, wrq->u.data.length);
4963                 kfree(pStaConfig);
4964             }
4965             else
4966             {
4967                 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_STA_CONFIG(kmalloc failed)\n"));
4968                 Status = -EFAULT;
4969             }
4970             break;
4971         case OID_802_11_RTS_THRESHOLD:
4972             RtsThresh = pAdapter->CommonCfg.RtsThreshold;
4973             wrq->u.data.length = sizeof(RtsThresh);
4974             Status = copy_to_user(wrq->u.data.pointer, &RtsThresh, wrq->u.data.length);
4975             DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_RTS_THRESHOLD(=%ld)\n", RtsThresh));
4976             break;
4977         case OID_802_11_FRAGMENTATION_THRESHOLD:
4978             FragThresh = pAdapter->CommonCfg.FragmentThreshold;
4979             if (pAdapter->CommonCfg.bUseZeroToDisableFragment == TRUE)
4980                 FragThresh = 0;
4981             wrq->u.data.length = sizeof(FragThresh);
4982             Status = copy_to_user(wrq->u.data.pointer, &FragThresh, wrq->u.data.length);
4983             DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_FRAGMENTATION_THRESHOLD(=%ld)\n", FragThresh));
4984             break;
4985         case OID_802_11_POWER_MODE:
4986             PowerMode = pAdapter->StaCfg.WindowsPowerMode;
4987             wrq->u.data.length = sizeof(PowerMode);
4988             Status = copy_to_user(wrq->u.data.pointer, &PowerMode, wrq->u.data.length);
4989             DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_POWER_MODE(=%d)\n", PowerMode));
4990             break;
4991         case RT_OID_802_11_RADIO:
4992             RadioState = (BOOLEAN) pAdapter->StaCfg.bSwRadio;
4993             wrq->u.data.length = sizeof(RadioState);
4994             Status = copy_to_user(wrq->u.data.pointer, &RadioState, wrq->u.data.length);
4995             DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_RADIO (=%d)\n", RadioState));
4996             break;
4997         case OID_802_11_INFRASTRUCTURE_MODE:
4998             if (pAdapter->StaCfg.BssType == BSS_ADHOC)
4999                 BssType = Ndis802_11IBSS;
5000             else if (pAdapter->StaCfg.BssType == BSS_INFRA)
5001                 BssType = Ndis802_11Infrastructure;
5002             else if (pAdapter->StaCfg.BssType == BSS_MONITOR)
5003                 BssType = Ndis802_11Monitor;
5004             else
5005                 BssType = Ndis802_11AutoUnknown;
5006
5007             wrq->u.data.length = sizeof(BssType);
5008             Status = copy_to_user(wrq->u.data.pointer, &BssType, wrq->u.data.length);
5009             DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_INFRASTRUCTURE_MODE(=%d)\n", BssType));
5010             break;
5011         case RT_OID_802_11_PREAMBLE:
5012             PreamType = pAdapter->CommonCfg.TxPreamble;
5013             wrq->u.data.length = sizeof(PreamType);
5014             Status = copy_to_user(wrq->u.data.pointer, &PreamType, wrq->u.data.length);
5015             DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_PREAMBLE(=%d)\n", PreamType));
5016             break;
5017         case OID_802_11_AUTHENTICATION_MODE:
5018             AuthMode = pAdapter->StaCfg.AuthMode;
5019             wrq->u.data.length = sizeof(AuthMode);
5020             Status = copy_to_user(wrq->u.data.pointer, &AuthMode, wrq->u.data.length);
5021             DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_AUTHENTICATION_MODE(=%d)\n", AuthMode));
5022             break;
5023         case OID_802_11_WEP_STATUS:
5024             WepStatus = pAdapter->StaCfg.WepStatus;
5025             wrq->u.data.length = sizeof(WepStatus);
5026             Status = copy_to_user(wrq->u.data.pointer, &WepStatus, wrq->u.data.length);
5027             DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_WEP_STATUS(=%d)\n", WepStatus));
5028             break;
5029         case OID_802_11_TX_POWER_LEVEL:
5030                         wrq->u.data.length = sizeof(ULONG);
5031                         Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.TxPower, wrq->u.data.length);
5032                         DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_TX_POWER_LEVEL %x\n",pAdapter->CommonCfg.TxPower));
5033                         break;
5034         case RT_OID_802_11_TX_POWER_LEVEL_1:
5035             wrq->u.data.length = sizeof(ULONG);
5036             Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.TxPowerPercentage, wrq->u.data.length);
5037                         DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_TX_POWER_LEVEL_1 (=%ld)\n", pAdapter->CommonCfg.TxPowerPercentage));
5038                         break;
5039         case OID_802_11_NETWORK_TYPES_SUPPORTED:
5040                         if ((pAdapter->RfIcType == RFIC_2850) || (pAdapter->RfIcType == RFIC_2750))
5041                         {
5042                                 NetworkTypeList[0] = 3;                 // NumberOfItems = 3
5043                                 NetworkTypeList[1] = Ndis802_11DS;      // NetworkType[1] = 11b
5044                                 NetworkTypeList[2] = Ndis802_11OFDM24;  // NetworkType[2] = 11g
5045                                 NetworkTypeList[3] = Ndis802_11OFDM5;   // NetworkType[3] = 11a
5046                 wrq->u.data.length = 16;
5047                                 Status = copy_to_user(wrq->u.data.pointer, &NetworkTypeList[0], wrq->u.data.length);
5048                         }
5049                         else
5050                         {
5051                                 NetworkTypeList[0] = 2;                 // NumberOfItems = 2
5052                                 NetworkTypeList[1] = Ndis802_11DS;      // NetworkType[1] = 11b
5053                                 NetworkTypeList[2] = Ndis802_11OFDM24;  // NetworkType[2] = 11g
5054                             wrq->u.data.length = 12;
5055                                 Status = copy_to_user(wrq->u.data.pointer, &NetworkTypeList[0], wrq->u.data.length);
5056                         }
5057                         DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_NETWORK_TYPES_SUPPORTED\n"));
5058                                 break;
5059             case OID_802_11_NETWORK_TYPE_IN_USE:
5060             wrq->u.data.length = sizeof(ULONG);
5061                         if (pAdapter->CommonCfg.PhyMode == PHY_11A)
5062                                 ulInfo = Ndis802_11OFDM5;
5063                         else if ((pAdapter->CommonCfg.PhyMode == PHY_11BG_MIXED) || (pAdapter->CommonCfg.PhyMode == PHY_11G))
5064                                 ulInfo = Ndis802_11OFDM24;
5065                         else
5066                                 ulInfo = Ndis802_11DS;
5067             Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
5068                         break;
5069         case RT_OID_802_11_QUERY_LAST_RX_RATE:
5070             ulInfo = (ULONG)pAdapter->LastRxRate;
5071             wrq->u.data.length = sizeof(ulInfo);
5072                         Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
5073                         DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_LAST_RX_RATE (=%ld)\n", ulInfo));
5074                         break;
5075                 case RT_OID_802_11_QUERY_LAST_TX_RATE:
5076                         //ulInfo = (ULONG)pAdapter->LastTxRate;
5077                         ulInfo = (ULONG)pAdapter->MacTab.Content[BSSID_WCID].HTPhyMode.word;
5078                         wrq->u.data.length = sizeof(ulInfo);
5079                         Status = copy_to_user(wrq->u.data.pointer, &ulInfo,     wrq->u.data.length);
5080                         DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_LAST_TX_RATE (=%lx)\n", ulInfo));
5081                         break;
5082         case RT_OID_802_11_QUERY_EEPROM_VERSION:
5083             wrq->u.data.length = sizeof(ULONG);
5084             Status = copy_to_user(wrq->u.data.pointer, &pAdapter->EepromVersion, wrq->u.data.length);
5085             break;
5086         case RT_OID_802_11_QUERY_FIRMWARE_VERSION:
5087             wrq->u.data.length = sizeof(ULONG);
5088             Status = copy_to_user(wrq->u.data.pointer, &pAdapter->FirmwareVersion, wrq->u.data.length);
5089                         break;
5090             case RT_OID_802_11_QUERY_NOISE_LEVEL:
5091                         wrq->u.data.length = sizeof(UCHAR);
5092                         Status = copy_to_user(wrq->u.data.pointer, &pAdapter->BbpWriteLatch[66], wrq->u.data.length);
5093                         DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_NOISE_LEVEL (=%d)\n", pAdapter->BbpWriteLatch[66]));
5094                         break;
5095             case RT_OID_802_11_EXTRA_INFO:
5096                         wrq->u.data.length = sizeof(ULONG);
5097                         Status = copy_to_user(wrq->u.data.pointer, &pAdapter->ExtraInfo, wrq->u.data.length);
5098                 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_EXTRA_INFO (=%ld)\n", pAdapter->ExtraInfo));
5099                 break;
5100             case RT_OID_WE_VERSION_COMPILED:
5101                 wrq->u.data.length = sizeof(UINT);
5102                 we_version_compiled = WIRELESS_EXT;
5103                 Status = copy_to_user(wrq->u.data.pointer, &we_version_compiled, wrq->u.data.length);
5104                 break;
5105                 case RT_OID_802_11_QUERY_APSD_SETTING:
5106                         apsd = (pAdapter->CommonCfg.bAPSDCapable | (pAdapter->CommonCfg.bAPSDAC_BE << 1) | (pAdapter->CommonCfg.bAPSDAC_BK << 2)
5107                                 | (pAdapter->CommonCfg.bAPSDAC_VI << 3) | (pAdapter->CommonCfg.bAPSDAC_VO << 4) | (pAdapter->CommonCfg.MaxSPLength << 5));
5108
5109                         wrq->u.data.length = sizeof(ULONG);
5110                         Status = copy_to_user(wrq->u.data.pointer, &apsd, wrq->u.data.length);
5111                         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",
5112                                 apsd,pAdapter->CommonCfg.bAPSDCapable,pAdapter->CommonCfg.bAPSDAC_BE,pAdapter->CommonCfg.bAPSDAC_BK,pAdapter->CommonCfg.bAPSDAC_VI,pAdapter->CommonCfg.bAPSDAC_VO,pAdapter->CommonCfg.MaxSPLength));
5113                         break;
5114                 case RT_OID_802_11_QUERY_APSD_PSM:
5115                         wrq->u.data.length = sizeof(ULONG);
5116                         Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.bAPSDForcePowerSave, wrq->u.data.length);
5117                         DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_APSD_PSM (=%d)\n", pAdapter->CommonCfg.bAPSDForcePowerSave));
5118                         break;
5119                 case RT_OID_802_11_QUERY_WMM:
5120                         wrq->u.data.length = sizeof(BOOLEAN);
5121                         Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.bWmmCapable, wrq->u.data.length);
5122                         DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_WMM (=%d)\n",     pAdapter->CommonCfg.bWmmCapable));
5123                         break;
5124 #ifdef WPA_SUPPLICANT_SUPPORT
5125         case RT_OID_NEW_DRIVER:
5126             {
5127                 UCHAR enabled = 1;
5128                 wrq->u.data.length = sizeof(UCHAR);
5129                 Status = copy_to_user(wrq->u.data.pointer, &enabled, wrq->u.data.length);
5130                 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_NEW_DRIVER (=%d)\n", enabled));
5131             }
5132                 break;
5133         case RT_OID_WPA_SUPPLICANT_SUPPORT:
5134                 wrq->u.data.length = sizeof(UCHAR);
5135                 Status = copy_to_user(wrq->u.data.pointer, &pAdapter->StaCfg.WpaSupplicantUP, wrq->u.data.length);
5136             DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_WPA_SUPPLICANT_SUPPORT (=%d)\n", pAdapter->StaCfg.WpaSupplicantUP));
5137                 break;
5138 #endif // WPA_SUPPLICANT_SUPPORT //
5139
5140         case RT_OID_DRIVER_DEVICE_NAME:
5141             DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_DRIVER_DEVICE_NAME \n"));
5142                         wrq->u.data.length = 16;
5143                         if (copy_to_user(wrq->u.data.pointer, pAdapter->StaCfg.dev_name, wrq->u.data.length))
5144                         {
5145                                 Status = -EFAULT;
5146                         }
5147             break;
5148         case RT_OID_802_11_QUERY_HT_PHYMODE:
5149             pHTPhyMode = (OID_SET_HT_PHYMODE *) kmalloc(sizeof(OID_SET_HT_PHYMODE), MEM_ALLOC_FLAG);
5150             if (pHTPhyMode)
5151             {
5152                 pHTPhyMode->PhyMode = pAdapter->CommonCfg.PhyMode;
5153                         pHTPhyMode->HtMode = (UCHAR)pAdapter->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE;
5154                         pHTPhyMode->BW = (UCHAR)pAdapter->MacTab.Content[BSSID_WCID].HTPhyMode.field.BW;
5155                         pHTPhyMode->MCS= (UCHAR)pAdapter->MacTab.Content[BSSID_WCID].HTPhyMode.field.MCS;
5156                         pHTPhyMode->SHORTGI= (UCHAR)pAdapter->MacTab.Content[BSSID_WCID].HTPhyMode.field.ShortGI;
5157                         pHTPhyMode->STBC= (UCHAR)pAdapter->MacTab.Content[BSSID_WCID].HTPhyMode.field.STBC;
5158
5159                         pHTPhyMode->ExtOffset = ((pAdapter->CommonCfg.CentralChannel < pAdapter->CommonCfg.Channel) ? (EXTCHA_BELOW) : (EXTCHA_ABOVE));
5160                 wrq->u.data.length = sizeof(OID_SET_HT_PHYMODE);
5161                 if (copy_to_user(wrq->u.data.pointer, pHTPhyMode, wrq->u.data.length))
5162                         {
5163                                 Status = -EFAULT;
5164                         }
5165                         DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_HT_PHYMODE (PhyMode = %d, MCS =%d, BW = %d, STBC = %d, ExtOffset=%d)\n",
5166                                 pHTPhyMode->HtMode, pHTPhyMode->MCS, pHTPhyMode->BW, pHTPhyMode->STBC, pHTPhyMode->ExtOffset));
5167                         DBGPRINT(RT_DEBUG_TRACE, (" MlmeUpdateTxRates (.word = %x )\n", pAdapter->MacTab.Content[BSSID_WCID].HTPhyMode.word));
5168             }
5169             else
5170             {
5171                 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_STA_CONFIG(kmalloc failed)\n"));
5172                 Status = -EFAULT;
5173             }
5174             break;
5175         case RT_OID_802_11_COUNTRY_REGION:
5176             DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_COUNTRY_REGION \n"));
5177                         wrq->u.data.length = sizeof(ulInfo);
5178             ulInfo = pAdapter->CommonCfg.CountryRegionForABand;
5179             ulInfo = (ulInfo << 8)|(pAdapter->CommonCfg.CountryRegion);
5180                         if (copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length))
5181             {
5182                                 Status = -EFAULT;
5183             }
5184             break;
5185         case RT_OID_802_11_QUERY_DAT_HT_PHYMODE:
5186             pHTPhyMode = (OID_SET_HT_PHYMODE *) kmalloc(sizeof(OID_SET_HT_PHYMODE), MEM_ALLOC_FLAG);
5187             if (pHTPhyMode)
5188             {
5189                 pHTPhyMode->PhyMode = pAdapter->CommonCfg.PhyMode;
5190                         pHTPhyMode->HtMode = (UCHAR)pAdapter->CommonCfg.RegTransmitSetting.field.HTMODE;
5191                         pHTPhyMode->BW = (UCHAR)pAdapter->CommonCfg.RegTransmitSetting.field.BW;
5192                         pHTPhyMode->MCS= (UCHAR)pAdapter->StaCfg.DesiredTransmitSetting.field.MCS;
5193                         pHTPhyMode->SHORTGI= (UCHAR)pAdapter->CommonCfg.RegTransmitSetting.field.ShortGI;
5194                         pHTPhyMode->STBC= (UCHAR)pAdapter->CommonCfg.RegTransmitSetting.field.STBC;
5195
5196                 wrq->u.data.length = sizeof(OID_SET_HT_PHYMODE);
5197                 if (copy_to_user(wrq->u.data.pointer, pHTPhyMode, wrq->u.data.length))
5198                         {
5199                                 Status = -EFAULT;
5200                         }
5201                         DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_HT_PHYMODE (PhyMode = %d, MCS =%d, BW = %d, STBC = %d, ExtOffset=%d)\n",
5202                                 pHTPhyMode->HtMode, pHTPhyMode->MCS, pHTPhyMode->BW, pHTPhyMode->STBC, pHTPhyMode->ExtOffset));
5203                         DBGPRINT(RT_DEBUG_TRACE, (" MlmeUpdateTxRates (.word = %x )\n", pAdapter->MacTab.Content[BSSID_WCID].HTPhyMode.word));
5204             }
5205             else
5206             {
5207                 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_STA_CONFIG(kmalloc failed)\n"));
5208                 Status = -EFAULT;
5209             }
5210             break;
5211         case RT_OID_QUERY_MULTIPLE_CARD_SUPPORT:
5212                         wrq->u.data.length = sizeof(UCHAR);
5213             i = 0;
5214 #ifdef MULTIPLE_CARD_SUPPORT
5215             i = 1;
5216 #endif // MULTIPLE_CARD_SUPPORT //
5217                         if (copy_to_user(wrq->u.data.pointer, &i, wrq->u.data.length))
5218             {
5219                                 Status = -EFAULT;
5220             }
5221             DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_QUERY_MULTIPLE_CARD_SUPPORT(=%d) \n", i));
5222             break;
5223 #ifdef SNMP_SUPPORT
5224                 case RT_OID_802_11_MAC_ADDRESS:
5225             wrq->u.data.length = MAC_ADDR_LEN;
5226             Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CurrentAddress, wrq->u.data.length);
5227                         break;
5228
5229                 case RT_OID_802_11_MANUFACTUREROUI:
5230                         DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_MANUFACTUREROUI \n"));
5231                         wrq->u.data.length = ManufacturerOUI_LEN;
5232                         Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CurrentAddress, wrq->u.data.length);
5233                         break;
5234
5235                 case RT_OID_802_11_MANUFACTURERNAME:
5236                         DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_MANUFACTURERNAME \n"));
5237                         wrq->u.data.length = strlen(ManufacturerNAME);
5238                         Status = copy_to_user(wrq->u.data.pointer, ManufacturerNAME, wrq->u.data.length);
5239                         break;
5240
5241                 case RT_OID_802_11_RESOURCETYPEIDNAME:
5242                         DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_RESOURCETYPEIDNAME \n"));
5243                         wrq->u.data.length = strlen(ResourceTypeIdName);
5244                         Status = copy_to_user(wrq->u.data.pointer, ResourceTypeIdName, wrq->u.data.length);
5245                         break;
5246
5247                 case RT_OID_802_11_PRIVACYOPTIONIMPLEMENTED:
5248                         DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_PRIVACYOPTIONIMPLEMENTED \n"));
5249                         ulInfo = 1; // 1 is support wep else 2 is not support.
5250                         wrq->u.data.length = sizeof(ulInfo);
5251                         Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
5252                         break;
5253
5254                 case RT_OID_802_11_POWERMANAGEMENTMODE:
5255                         DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_POWERMANAGEMENTMODE \n"));
5256                         if (pAdapter->StaCfg.Psm == PSMP_ACTION)
5257                                 ulInfo = 1; // 1 is power active else 2 is power save.
5258                         else
5259                                 ulInfo = 2;
5260
5261                         wrq->u.data.length = sizeof(ulInfo);
5262                         Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
5263                         break;
5264
5265                 case OID_802_11_WEPDEFAULTKEYVALUE:
5266                         DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_WEPDEFAULTKEYVALUE \n"));
5267                         //KeyIdxValue.KeyIdx = pAd->PortCfg.MBSSID[pAd->IoctlIF].DefaultKeyId;
5268                         pKeyIdxValue = wrq->u.data.pointer;
5269                         DBGPRINT(RT_DEBUG_TRACE,("KeyIdxValue.KeyIdx = %d, \n",pKeyIdxValue->KeyIdx));
5270                         valueLen = pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].KeyLen;
5271                         NdisMoveMemory(pKeyIdxValue->Value,
5272                                                    &pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].Key,
5273                                                    valueLen);
5274                         pKeyIdxValue->Value[valueLen]='\0';
5275
5276                         wrq->u.data.length = sizeof(DefaultKeyIdxValue);
5277
5278                         Status = copy_to_user(wrq->u.data.pointer, pKeyIdxValue, wrq->u.data.length);
5279                         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,
5280                         pAdapter->SharedKey[BSS0][0].Key[0],
5281                         pAdapter->SharedKey[BSS0][1].Key[0],
5282                         pAdapter->SharedKey[BSS0][2].Key[0],
5283                         pAdapter->SharedKey[BSS0][3].Key[0]));
5284                         break;
5285
5286                 case OID_802_11_WEPDEFAULTKEYID:
5287                         DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_WEPDEFAULTKEYID \n"));
5288                         wrq->u.data.length = sizeof(UCHAR);
5289                         Status = copy_to_user(wrq->u.data.pointer, &pAdapter->StaCfg.DefaultKeyId, wrq->u.data.length);
5290                         DBGPRINT(RT_DEBUG_TRACE, ("DefaultKeyId =%d \n", pAdapter->StaCfg.DefaultKeyId));
5291                         break;
5292
5293                 case RT_OID_802_11_WEPKEYMAPPINGLENGTH:
5294                         DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_WEPKEYMAPPINGLENGTH \n"));
5295                         wrq->u.data.length = sizeof(UCHAR);
5296                         Status = copy_to_user(wrq->u.data.pointer,
5297                                                                         &pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].KeyLen,
5298                                                                         wrq->u.data.length);
5299                         break;
5300
5301                 case OID_802_11_SHORTRETRYLIMIT:
5302                         DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_SHORTRETRYLIMIT \n"));
5303                         wrq->u.data.length = sizeof(ULONG);
5304                         RTMP_IO_READ32(pAdapter, TX_RTY_CFG, &tx_rty_cfg.word);
5305                         ShortRetryLimit = tx_rty_cfg.field.ShortRtyLimit;
5306                         DBGPRINT(RT_DEBUG_TRACE, ("ShortRetryLimit =%ld,  tx_rty_cfg.field.ShortRetryLimit=%d\n", ShortRetryLimit, tx_rty_cfg.field.ShortRtyLimit));
5307                         Status = copy_to_user(wrq->u.data.pointer, &ShortRetryLimit, wrq->u.data.length);
5308                         break;
5309
5310                 case OID_802_11_LONGRETRYLIMIT:
5311                         DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_LONGRETRYLIMIT \n"));
5312                         wrq->u.data.length = sizeof(ULONG);
5313                         RTMP_IO_READ32(pAdapter, TX_RTY_CFG, &tx_rty_cfg.word);
5314                         LongRetryLimit = tx_rty_cfg.field.LongRtyLimit;
5315                         DBGPRINT(RT_DEBUG_TRACE, ("LongRetryLimit =%ld,  tx_rty_cfg.field.LongRtyLimit=%d\n", LongRetryLimit, tx_rty_cfg.field.LongRtyLimit));
5316                         Status = copy_to_user(wrq->u.data.pointer, &LongRetryLimit, wrq->u.data.length);
5317                         break;
5318
5319                 case RT_OID_802_11_PRODUCTID:
5320                         DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_PRODUCTID \n"));
5321
5322                         {
5323
5324                                 USHORT  device_id;
5325                                 if (((POS_COOKIE)pAdapter->OS_Cookie)->pci_dev != NULL)
5326                                 pci_read_config_word(((POS_COOKIE)pAdapter->OS_Cookie)->pci_dev, PCI_DEVICE_ID, &device_id);
5327                                 else
5328                                         DBGPRINT(RT_DEBUG_TRACE, (" pci_dev = NULL\n"));
5329                                 sprintf(tmp, "%04x %04x\n", NIC_PCI_VENDOR_ID, device_id);
5330                         }
5331                         wrq->u.data.length = strlen(tmp);
5332                         Status = copy_to_user(wrq->u.data.pointer, tmp, wrq->u.data.length);
5333                         break;
5334
5335                 case RT_OID_802_11_MANUFACTUREID:
5336                         DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_MANUFACTUREID \n"));
5337                         wrq->u.data.length = strlen(ManufacturerNAME);
5338                         Status = copy_to_user(wrq->u.data.pointer, ManufacturerNAME, wrq->u.data.length);
5339                         break;
5340
5341                 case OID_802_11_CURRENTCHANNEL:
5342                         DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_CURRENTCHANNEL \n"));
5343                         wrq->u.data.length = sizeof(UCHAR);
5344                         DBGPRINT(RT_DEBUG_TRACE, ("sizeof UCHAR=%d, channel=%d \n", sizeof(UCHAR), pAdapter->CommonCfg.Channel));
5345                         Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.Channel, wrq->u.data.length);
5346                         DBGPRINT(RT_DEBUG_TRACE, ("Status=%d\n", Status));
5347                         break;
5348 #endif //SNMP_SUPPORT
5349
5350                 case OID_802_11_BUILD_CHANNEL_EX:
5351                         {
5352                                 UCHAR value;
5353                                 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_BUILD_CHANNEL_EX \n"));
5354                                 wrq->u.data.length = sizeof(UCHAR);
5355 #ifdef EXT_BUILD_CHANNEL_LIST
5356                                 DBGPRINT(RT_DEBUG_TRACE, ("Support EXT_BUILD_CHANNEL_LIST.\n"));
5357                                 value = 1;
5358 #else
5359                                 DBGPRINT(RT_DEBUG_TRACE, ("Doesn't support EXT_BUILD_CHANNEL_LIST.\n"));
5360                                 value = 0;
5361 #endif // EXT_BUILD_CHANNEL_LIST //
5362                                 Status = copy_to_user(wrq->u.data.pointer, &value, 1);
5363                                 DBGPRINT(RT_DEBUG_TRACE, ("Status=%d\n", Status));
5364                         }
5365                         break;
5366
5367                 case OID_802_11_GET_CH_LIST:
5368                         {
5369                                 PRT_CHANNEL_LIST_INFO pChListBuf;
5370
5371                                 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_GET_CH_LIST \n"));
5372                                 if (pAdapter->ChannelListNum == 0)
5373                                 {
5374                                         wrq->u.data.length = 0;
5375                                         break;
5376                                 }
5377
5378                                 pChListBuf = (RT_CHANNEL_LIST_INFO *) kmalloc(sizeof(RT_CHANNEL_LIST_INFO), MEM_ALLOC_FLAG);
5379                                 if (pChListBuf == NULL)
5380                                 {
5381                                         wrq->u.data.length = 0;
5382                                         break;
5383                                 }
5384
5385                                 pChListBuf->ChannelListNum = pAdapter->ChannelListNum;
5386                                 for (i = 0; i < pChListBuf->ChannelListNum; i++)
5387                                         pChListBuf->ChannelList[i] = pAdapter->ChannelList[i].Channel;
5388
5389                                 wrq->u.data.length = sizeof(RT_CHANNEL_LIST_INFO);
5390                                 Status = copy_to_user(wrq->u.data.pointer, pChListBuf, sizeof(RT_CHANNEL_LIST_INFO));
5391                                 DBGPRINT(RT_DEBUG_TRACE, ("Status=%d\n", Status));
5392
5393                                 if (pChListBuf)
5394                                         kfree(pChListBuf);
5395                         }
5396                         break;
5397
5398                 case OID_802_11_GET_COUNTRY_CODE:
5399                         DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_GET_COUNTRY_CODE \n"));
5400                         wrq->u.data.length = 2;
5401                         Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.CountryCode, 2);
5402                         DBGPRINT(RT_DEBUG_TRACE, ("Status=%d\n", Status));
5403                         break;
5404
5405                 case OID_802_11_GET_CHANNEL_GEOGRAPHY:
5406                         DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_GET_CHANNEL_GEOGRAPHY \n"));
5407                         wrq->u.data.length = 1;
5408                         Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.Geography, 1);
5409                         DBGPRINT(RT_DEBUG_TRACE, ("Status=%d\n", Status));
5410                         break;
5411
5412
5413 #ifdef QOS_DLS_SUPPORT
5414                 case RT_OID_802_11_QUERY_DLS:
5415                         wrq->u.data.length = sizeof(BOOLEAN);
5416                         Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.bDLSCapable, wrq->u.data.length);
5417                         DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_DLS(=%d)\n", pAdapter->CommonCfg.bDLSCapable));
5418                         break;
5419
5420                 case RT_OID_802_11_QUERY_DLS_PARAM:
5421                         {
5422                                 PRT_802_11_DLS_INFO     pDlsInfo = kmalloc(sizeof(RT_802_11_DLS_INFO), GFP_ATOMIC);
5423                                 if (pDlsInfo == NULL)
5424                                         break;
5425
5426                                 for (i=0; i<MAX_NUM_OF_DLS_ENTRY; i++)
5427                                 {
5428                                         RTMPMoveMemory(&pDlsInfo->Entry[i], &pAdapter->StaCfg.DLSEntry[i], sizeof(RT_802_11_DLS_UI));
5429                                 }
5430
5431                                 pDlsInfo->num = MAX_NUM_OF_DLS_ENTRY;
5432                                 wrq->u.data.length = sizeof(RT_802_11_DLS_INFO);
5433                                 Status = copy_to_user(wrq->u.data.pointer, pDlsInfo, wrq->u.data.length);
5434                                 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_DLS_PARAM\n"));
5435
5436                                 if (pDlsInfo)
5437                                         kfree(pDlsInfo);
5438                         }
5439                         break;
5440 #endif // QOS_DLS_SUPPORT //
5441         default:
5442             DBGPRINT(RT_DEBUG_TRACE, ("Query::unknown IOCTL's subcmd = 0x%08x\n", cmd));
5443             Status = -EOPNOTSUPP;
5444             break;
5445     }
5446     return Status;
5447 }
5448
5449 INT rt28xx_sta_ioctl(
5450         IN      struct net_device       *net_dev,
5451         IN      OUT     struct ifreq    *rq,
5452         IN      INT                                     cmd)
5453 {
5454         POS_COOKIE                      pObj;
5455         VIRTUAL_ADAPTER         *pVirtualAd = NULL;
5456         RTMP_ADAPTER        *pAd = NULL;
5457         struct iwreq        *wrq = (struct iwreq *) rq;
5458         BOOLEAN                         StateMachineTouched = FALSE;
5459         INT                                     Status = NDIS_STATUS_SUCCESS;
5460         USHORT                          subcmd;
5461
5462         if (net_dev->priv_flags == INT_MAIN)
5463         {
5464                 pAd = net_dev->ml_priv;
5465         }
5466         else
5467         {
5468                 pVirtualAd = net_dev->ml_priv;
5469                 pAd = pVirtualAd->RtmpDev->ml_priv;
5470         }
5471         pObj = (POS_COOKIE) pAd->OS_Cookie;
5472
5473         if (pAd == NULL)
5474         {
5475                 /* if 1st open fail, pAd will be free;
5476                    So the net_dev->ml_priv will be NULL in 2rd open */
5477                 return -ENETDOWN;
5478         }
5479
5480     //check if the interface is down
5481     if(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE))
5482     {
5483 #ifdef CONFIG_APSTA_MIXED_SUPPORT
5484             if (wrq->u.data.pointer == NULL)
5485             {
5486                     return Status;
5487             }
5488
5489             if (strstr(wrq->u.data.pointer, "OpMode") == NULL)
5490 #endif // CONFIG_APSTA_MIXED_SUPPORT //
5491         {
5492             DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
5493                     return -ENETDOWN;
5494         }
5495     }
5496
5497         {       // determine this ioctl command is comming from which interface.
5498                 pObj->ioctl_if_type = INT_MAIN;
5499                 pObj->ioctl_if = MAIN_MBSSID;
5500         }
5501
5502         switch(cmd)
5503         {
5504 #ifdef RALINK_ATE
5505 #ifdef RALINK_28xx_QA
5506                 case RTPRIV_IOCTL_ATE:
5507                         {
5508                                 RtmpDoAte(pAd, wrq);
5509                         }
5510                         break;
5511 #endif // RALINK_28xx_QA //
5512 #endif // RALINK_ATE //
5513         case SIOCGIFHWADDR:
5514                         DBGPRINT(RT_DEBUG_TRACE, ("IOCTL::SIOCGIFHWADDR\n"));
5515                         memcpy(wrq->u.name, pAd->CurrentAddress, ETH_ALEN);
5516                         break;
5517                 case SIOCGIWNAME:
5518         {
5519                 char *name=&wrq->u.name[0];
5520                 rt_ioctl_giwname(net_dev, NULL, name, NULL);
5521                         break;
5522                 }
5523                 case SIOCGIWESSID:  //Get ESSID
5524         {
5525                 struct iw_point *essid=&wrq->u.essid;
5526                 rt_ioctl_giwessid(net_dev, NULL, essid, essid->pointer);
5527                         break;
5528                 }
5529                 case SIOCSIWESSID:  //Set ESSID
5530         {
5531                 struct iw_point *essid=&wrq->u.essid;
5532                 rt_ioctl_siwessid(net_dev, NULL, essid, essid->pointer);
5533                         break;
5534                 }
5535                 case SIOCSIWNWID:   // set network id (the cell)
5536                 case SIOCGIWNWID:   // get network id
5537                         Status = -EOPNOTSUPP;
5538                         break;
5539                 case SIOCSIWFREQ:   //set channel/frequency (Hz)
5540         {
5541                 struct iw_freq *freq=&wrq->u.freq;
5542                 rt_ioctl_siwfreq(net_dev, NULL, freq, NULL);
5543                         break;
5544                 }
5545                 case SIOCGIWFREQ:   // get channel/frequency (Hz)
5546         {
5547                 struct iw_freq *freq=&wrq->u.freq;
5548                 rt_ioctl_giwfreq(net_dev, NULL, freq, NULL);
5549                         break;
5550                 }
5551                 case SIOCSIWNICKN: //set node name/nickname
5552         {
5553                 struct iw_point *data=&wrq->u.data;
5554                 rt_ioctl_siwnickn(net_dev, NULL, data, NULL);
5555                         break;
5556                 }
5557                 case SIOCGIWNICKN: //get node name/nickname
5558         {
5559                 struct iw_point *data=&wrq->u.data;
5560                 rt_ioctl_giwnickn(net_dev, NULL, data, NULL);
5561                         break;
5562                 }
5563                 case SIOCGIWRATE:   //get default bit rate (bps)
5564                     rt_ioctl_giwrate(net_dev, NULL, &wrq->u, NULL);
5565             break;
5566             case SIOCSIWRATE:  //set default bit rate (bps)
5567                 rt_ioctl_siwrate(net_dev, NULL, &wrq->u, NULL);
5568             break;
5569         case SIOCGIWRTS:  // get RTS/CTS threshold (bytes)
5570         {
5571                 struct iw_param *rts=&wrq->u.rts;
5572                 rt_ioctl_giwrts(net_dev, NULL, rts, NULL);
5573                         break;
5574                 }
5575         case SIOCSIWRTS:  //set RTS/CTS threshold (bytes)
5576         {
5577                 struct iw_param *rts=&wrq->u.rts;
5578                 rt_ioctl_siwrts(net_dev, NULL, rts, NULL);
5579                         break;
5580                 }
5581         case SIOCGIWFRAG:  //get fragmentation thr (bytes)
5582         {
5583                 struct iw_param *frag=&wrq->u.frag;
5584                 rt_ioctl_giwfrag(net_dev, NULL, frag, NULL);
5585                         break;
5586                 }
5587         case SIOCSIWFRAG:  //set fragmentation thr (bytes)
5588         {
5589                 struct iw_param *frag=&wrq->u.frag;
5590                 rt_ioctl_siwfrag(net_dev, NULL, frag, NULL);
5591                         break;
5592                 }
5593         case SIOCGIWENCODE:  //get encoding token & mode
5594         {
5595                 struct iw_point *erq=&wrq->u.encoding;
5596                 if(erq->pointer)
5597                         rt_ioctl_giwencode(net_dev, NULL, erq, erq->pointer);
5598                         break;
5599                 }
5600         case SIOCSIWENCODE:  //set encoding token & mode
5601         {
5602                 struct iw_point *erq=&wrq->u.encoding;
5603                 if(erq->pointer)
5604                         rt_ioctl_siwencode(net_dev, NULL, erq, erq->pointer);
5605                         break;
5606                 }
5607                 case SIOCGIWAP:     //get access point MAC addresses
5608         {
5609                 struct sockaddr *ap_addr=&wrq->u.ap_addr;
5610                 rt_ioctl_giwap(net_dev, NULL, ap_addr, ap_addr->sa_data);
5611                         break;
5612                 }
5613             case SIOCSIWAP:  //set access point MAC addresses
5614         {
5615                 struct sockaddr *ap_addr=&wrq->u.ap_addr;
5616                 rt_ioctl_siwap(net_dev, NULL, ap_addr, ap_addr->sa_data);
5617                         break;
5618                 }
5619                 case SIOCGIWMODE:   //get operation mode
5620         {
5621                 __u32 *mode=&wrq->u.mode;
5622                 rt_ioctl_giwmode(net_dev, NULL, mode, NULL);
5623                         break;
5624                 }
5625                 case SIOCSIWMODE:   //set operation mode
5626         {
5627                 __u32 *mode=&wrq->u.mode;
5628                 rt_ioctl_siwmode(net_dev, NULL, mode, NULL);
5629                         break;
5630                 }
5631                 case SIOCGIWSENS:   //get sensitivity (dBm)
5632                 case SIOCSIWSENS:       //set sensitivity (dBm)
5633                 case SIOCGIWPOWER:  //get Power Management settings
5634                 case SIOCSIWPOWER:  //set Power Management settings
5635                 case SIOCGIWTXPOW:  //get transmit power (dBm)
5636                 case SIOCSIWTXPOW:  //set transmit power (dBm)
5637                 case SIOCGIWRANGE:      //Get range of parameters
5638                 case SIOCGIWRETRY:      //get retry limits and lifetime
5639                 case SIOCSIWRETRY:      //set retry limits and lifetime
5640                         Status = -EOPNOTSUPP;
5641                         break;
5642                 case RT_PRIV_IOCTL:
5643                         subcmd = wrq->u.data.flags;
5644                         if( subcmd & OID_GET_SET_TOGGLE)
5645                                 Status = RTMPSetInformation(pAd, rq, subcmd);
5646                         else
5647                                 Status = RTMPQueryInformation(pAd, rq, subcmd);
5648                         break;
5649                 case SIOCGIWPRIV:
5650                         if (wrq->u.data.pointer)
5651                         {
5652                                 if ( access_ok(VERIFY_WRITE, wrq->u.data.pointer, sizeof(privtab)) != TRUE)
5653                                         break;
5654                                 wrq->u.data.length = sizeof(privtab) / sizeof(privtab[0]);
5655                                 if (copy_to_user(wrq->u.data.pointer, privtab, sizeof(privtab)))
5656                                         Status = -EFAULT;
5657                         }
5658                         break;
5659                 case RTPRIV_IOCTL_SET:
5660                         if(access_ok(VERIFY_READ, wrq->u.data.pointer, wrq->u.data.length) != TRUE)
5661                                 break;
5662                         rt_ioctl_setparam(net_dev, NULL, NULL, wrq->u.data.pointer);
5663                         break;
5664                 case RTPRIV_IOCTL_GSITESURVEY:
5665                         RTMPIoctlGetSiteSurvey(pAd, wrq);
5666                     break;
5667 #ifdef DBG
5668                 case RTPRIV_IOCTL_MAC:
5669                         RTMPIoctlMAC(pAd, wrq);
5670                         break;
5671                 case RTPRIV_IOCTL_E2P:
5672                         RTMPIoctlE2PROM(pAd, wrq);
5673                         break;
5674 #endif // DBG //
5675         case SIOCETHTOOL:
5676                 break;
5677                 default:
5678                         DBGPRINT(RT_DEBUG_ERROR, ("IOCTL::unknown IOCTL's cmd = 0x%08x\n", cmd));
5679                         Status = -EOPNOTSUPP;
5680                         break;
5681         }
5682
5683     if(StateMachineTouched) // Upper layer sent a MLME-related operations
5684         RT28XX_MLME_HANDLER(pAd);
5685
5686         return Status;
5687 }
5688
5689 /*
5690     ==========================================================================
5691     Description:
5692         Set SSID
5693     Return:
5694         TRUE if all parameters are OK, FALSE otherwise
5695     ==========================================================================
5696 */
5697 INT Set_SSID_Proc(
5698     IN  PRTMP_ADAPTER   pAdapter,
5699     IN  PUCHAR          arg)
5700 {
5701     NDIS_802_11_SSID                    Ssid, *pSsid=NULL;
5702     BOOLEAN                             StateMachineTouched = FALSE;
5703     int                                 success = TRUE;
5704
5705     if( strlen(arg) <= MAX_LEN_OF_SSID)
5706     {
5707         NdisZeroMemory(&Ssid, sizeof(NDIS_802_11_SSID));
5708         if (strlen(arg) != 0)
5709         {
5710             NdisMoveMemory(Ssid.Ssid, arg, strlen(arg));
5711             Ssid.SsidLength = strlen(arg);
5712         }
5713         else   //ANY ssid
5714         {
5715             Ssid.SsidLength = 0;
5716                     memcpy(Ssid.Ssid, "", 0);
5717                         pAdapter->StaCfg.BssType = BSS_INFRA;
5718                         pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
5719                 pAdapter->StaCfg.WepStatus  = Ndis802_11EncryptionDisabled;
5720                 }
5721         pSsid = &Ssid;
5722
5723         if (pAdapter->Mlme.CntlMachine.CurrState != CNTL_IDLE)
5724         {
5725             RT28XX_MLME_RESET_STATE_MACHINE(pAdapter);
5726             DBGPRINT(RT_DEBUG_TRACE, ("!!! MLME busy, reset MLME state machine !!!\n"));
5727         }
5728
5729         pAdapter->MlmeAux.CurrReqIsFromNdis = TRUE;
5730         pAdapter->StaCfg.bScanReqIsFromWebUI = FALSE;
5731                 pAdapter->bConfigChanged = TRUE;
5732
5733         MlmeEnqueue(pAdapter,
5734                     MLME_CNTL_STATE_MACHINE,
5735                     OID_802_11_SSID,
5736                     sizeof(NDIS_802_11_SSID),
5737                     (VOID *)pSsid);
5738
5739         StateMachineTouched = TRUE;
5740         DBGPRINT(RT_DEBUG_TRACE, ("Set_SSID_Proc::(Len=%d,Ssid=%s)\n", Ssid.SsidLength, Ssid.Ssid));
5741     }
5742     else
5743         success = FALSE;
5744
5745     if (StateMachineTouched) // Upper layer sent a MLME-related operations
5746         RT28XX_MLME_HANDLER(pAdapter);
5747
5748     return success;
5749 }
5750
5751 #ifdef WMM_SUPPORT
5752 /*
5753     ==========================================================================
5754     Description:
5755         Set WmmCapable Enable or Disable
5756     Return:
5757         TRUE if all parameters are OK, FALSE otherwise
5758     ==========================================================================
5759 */
5760 INT     Set_WmmCapable_Proc(
5761         IN      PRTMP_ADAPTER   pAd,
5762         IN      PUCHAR                  arg)
5763 {
5764         BOOLEAN bWmmCapable;
5765
5766         bWmmCapable = simple_strtol(arg, 0, 10);
5767
5768         if ((bWmmCapable == 1)
5769                 )
5770                 pAd->CommonCfg.bWmmCapable = TRUE;
5771         else if (bWmmCapable == 0)
5772                 pAd->CommonCfg.bWmmCapable = FALSE;
5773         else
5774                 return FALSE;  //Invalid argument
5775
5776         DBGPRINT(RT_DEBUG_TRACE, ("Set_WmmCapable_Proc::(bWmmCapable=%d)\n",
5777                 pAd->CommonCfg.bWmmCapable));
5778
5779         return TRUE;
5780 }
5781 #endif // WMM_SUPPORT //
5782
5783 /*
5784     ==========================================================================
5785     Description:
5786         Set Network Type(Infrastructure/Adhoc mode)
5787     Return:
5788         TRUE if all parameters are OK, FALSE otherwise
5789     ==========================================================================
5790 */
5791 INT Set_NetworkType_Proc(
5792     IN  PRTMP_ADAPTER   pAdapter,
5793     IN  PUCHAR          arg)
5794 {
5795     UINT32      Value = 0;
5796
5797     if (strcmp(arg, "Adhoc") == 0)
5798         {
5799                 if (pAdapter->StaCfg.BssType != BSS_ADHOC)
5800                 {
5801                         // Config has changed
5802                         pAdapter->bConfigChanged = TRUE;
5803             if (MONITOR_ON(pAdapter))
5804             {
5805                 RTMP_IO_WRITE32(pAdapter, RX_FILTR_CFG, STANORMAL);
5806                 RTMP_IO_READ32(pAdapter, MAC_SYS_CTRL, &Value);
5807                                 Value &= (~0x80);
5808                                 RTMP_IO_WRITE32(pAdapter, MAC_SYS_CTRL, Value);
5809                 OPSTATUS_CLEAR_FLAG(pAdapter, fOP_STATUS_MEDIA_STATE_CONNECTED);
5810                 pAdapter->StaCfg.bAutoReconnect = TRUE;
5811                 LinkDown(pAdapter, FALSE);
5812             }
5813                         if (INFRA_ON(pAdapter))
5814                         {
5815                                 //BOOLEAN Cancelled;
5816                                 // Set the AutoReconnectSsid to prevent it reconnect to old SSID
5817                                 // Since calling this indicate user don't want to connect to that SSID anymore.
5818                                 pAdapter->MlmeAux.AutoReconnectSsidLen= 32;
5819                                 NdisZeroMemory(pAdapter->MlmeAux.AutoReconnectSsid, pAdapter->MlmeAux.AutoReconnectSsidLen);
5820
5821                                 LinkDown(pAdapter, FALSE);
5822
5823                                 DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event BB!\n"));
5824                         }
5825                 }
5826                 pAdapter->StaCfg.BssType = BSS_ADHOC;
5827         pAdapter->net_dev->type = pAdapter->StaCfg.OriDevType;
5828                 DBGPRINT(RT_DEBUG_TRACE, ("===>Set_NetworkType_Proc::(AD-HOC)\n"));
5829         }
5830     else if (strcmp(arg, "Infra") == 0)
5831         {
5832                 if (pAdapter->StaCfg.BssType != BSS_INFRA)
5833                 {
5834                         // Config has changed
5835                         pAdapter->bConfigChanged = TRUE;
5836             if (MONITOR_ON(pAdapter))
5837             {
5838                 RTMP_IO_WRITE32(pAdapter, RX_FILTR_CFG, STANORMAL);
5839                 RTMP_IO_READ32(pAdapter, MAC_SYS_CTRL, &Value);
5840                                 Value &= (~0x80);
5841                                 RTMP_IO_WRITE32(pAdapter, MAC_SYS_CTRL, Value);
5842                 OPSTATUS_CLEAR_FLAG(pAdapter, fOP_STATUS_MEDIA_STATE_CONNECTED);
5843                 pAdapter->StaCfg.bAutoReconnect = TRUE;
5844                 LinkDown(pAdapter, FALSE);
5845             }
5846                         if (ADHOC_ON(pAdapter))
5847                         {
5848                                 // Set the AutoReconnectSsid to prevent it reconnect to old SSID
5849                                 // Since calling this indicate user don't want to connect to that SSID anymore.
5850                                 pAdapter->MlmeAux.AutoReconnectSsidLen= 32;
5851                                 NdisZeroMemory(pAdapter->MlmeAux.AutoReconnectSsid, pAdapter->MlmeAux.AutoReconnectSsidLen);
5852
5853                                 LinkDown(pAdapter, FALSE);
5854                         }
5855                 }
5856                 pAdapter->StaCfg.BssType = BSS_INFRA;
5857         pAdapter->net_dev->type = pAdapter->StaCfg.OriDevType;
5858                 DBGPRINT(RT_DEBUG_TRACE, ("===>Set_NetworkType_Proc::(INFRA)\n"));
5859
5860         pAdapter->StaCfg.BssType = BSS_INFRA;
5861         }
5862     else if (strcmp(arg, "Monitor") == 0)
5863     {
5864                 UCHAR   bbpValue = 0;
5865                 BCN_TIME_CFG_STRUC csr;
5866                 OPSTATUS_CLEAR_FLAG(pAdapter, fOP_STATUS_INFRA_ON);
5867         OPSTATUS_CLEAR_FLAG(pAdapter, fOP_STATUS_ADHOC_ON);
5868                 OPSTATUS_SET_FLAG(pAdapter, fOP_STATUS_MEDIA_STATE_CONNECTED);
5869                 // disable all periodic state machine
5870                 pAdapter->StaCfg.bAutoReconnect = FALSE;
5871                 // reset all mlme state machine
5872                 RT28XX_MLME_RESET_STATE_MACHINE(pAdapter);
5873                 DBGPRINT(RT_DEBUG_TRACE, ("fOP_STATUS_MEDIA_STATE_CONNECTED \n"));
5874         if (pAdapter->CommonCfg.CentralChannel == 0)
5875         {
5876 #ifdef DOT11_N_SUPPORT
5877             if (pAdapter->CommonCfg.PhyMode == PHY_11AN_MIXED)
5878                 pAdapter->CommonCfg.CentralChannel = 36;
5879             else
5880 #endif // DOT11_N_SUPPORT //
5881                 pAdapter->CommonCfg.CentralChannel = 6;
5882         }
5883 #ifdef DOT11_N_SUPPORT
5884         else
5885             N_ChannelCheck(pAdapter);
5886 #endif // DOT11_N_SUPPORT //
5887
5888 #ifdef DOT11_N_SUPPORT
5889         if (pAdapter->CommonCfg.PhyMode >= PHY_11ABGN_MIXED &&
5890             pAdapter->CommonCfg.RegTransmitSetting.field.BW == BW_40 &&
5891             pAdapter->CommonCfg.RegTransmitSetting.field.EXTCHA == EXTCHA_ABOVE)
5892                 {
5893                         // 40MHz ,control channel at lower
5894                         RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R4, &bbpValue);
5895                         bbpValue &= (~0x18);
5896                         bbpValue |= 0x10;
5897                         RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R4, bbpValue);
5898                         pAdapter->CommonCfg.BBPCurrentBW = BW_40;
5899                         //  RX : control channel at lower
5900                         RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R3, &bbpValue);
5901                         bbpValue &= (~0x20);
5902                         RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R3, bbpValue);
5903
5904                         RTMP_IO_READ32(pAdapter, TX_BAND_CFG, &Value);
5905                         Value &= 0xfffffffe;
5906                         RTMP_IO_WRITE32(pAdapter, TX_BAND_CFG, Value);
5907                         pAdapter->CommonCfg.CentralChannel = pAdapter->CommonCfg.Channel + 2;
5908             AsicSwitchChannel(pAdapter, pAdapter->CommonCfg.CentralChannel, FALSE);
5909                     AsicLockChannel(pAdapter, pAdapter->CommonCfg.CentralChannel);
5910             DBGPRINT(RT_DEBUG_TRACE, ("BW_40 ,control_channel(%d), CentralChannel(%d) \n",
5911                                        pAdapter->CommonCfg.Channel,
5912                                        pAdapter->CommonCfg.CentralChannel));
5913                 }
5914                 else if (pAdapter->CommonCfg.PhyMode >= PHY_11ABGN_MIXED &&
5915                  pAdapter->CommonCfg.RegTransmitSetting.field.BW == BW_40 &&
5916                  pAdapter->CommonCfg.RegTransmitSetting.field.EXTCHA == EXTCHA_BELOW)
5917                 {
5918                         // 40MHz ,control channel at upper
5919                         RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R4, &bbpValue);
5920                         bbpValue &= (~0x18);
5921                         bbpValue |= 0x10;
5922                         RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R4, bbpValue);
5923                         pAdapter->CommonCfg.BBPCurrentBW = BW_40;
5924                         RTMP_IO_READ32(pAdapter, TX_BAND_CFG, &Value);
5925                         Value |= 0x1;
5926                         RTMP_IO_WRITE32(pAdapter, TX_BAND_CFG, Value);
5927
5928                         RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R3, &bbpValue);
5929                         bbpValue |= (0x20);
5930                         RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R3, bbpValue);
5931                         pAdapter->CommonCfg.CentralChannel = pAdapter->CommonCfg.Channel - 2;
5932             AsicSwitchChannel(pAdapter, pAdapter->CommonCfg.CentralChannel, FALSE);
5933                     AsicLockChannel(pAdapter, pAdapter->CommonCfg.CentralChannel);
5934             DBGPRINT(RT_DEBUG_TRACE, ("BW_40 ,control_channel(%d), CentralChannel(%d) \n",
5935                                        pAdapter->CommonCfg.Channel,
5936                                        pAdapter->CommonCfg.CentralChannel));
5937                 }
5938                 else
5939 #endif // DOT11_N_SUPPORT //
5940                 {
5941                         // 20MHz
5942                         RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R4, &bbpValue);
5943                         bbpValue &= (~0x18);
5944                         RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R4, bbpValue);
5945                         pAdapter->CommonCfg.BBPCurrentBW = BW_20;
5946                         AsicSwitchChannel(pAdapter, pAdapter->CommonCfg.Channel, FALSE);
5947                         AsicLockChannel(pAdapter, pAdapter->CommonCfg.Channel);
5948                         DBGPRINT(RT_DEBUG_TRACE, ("BW_20, Channel(%d)\n", pAdapter->CommonCfg.Channel));
5949                 }
5950                 // Enable Rx with promiscuous reception
5951                 RTMP_IO_WRITE32(pAdapter, RX_FILTR_CFG, 0x3);
5952                 // ASIC supporsts sniffer function with replacing RSSI with timestamp.
5953                 //RTMP_IO_READ32(pAdapter, MAC_SYS_CTRL, &Value);
5954                 //Value |= (0x80);
5955                 //RTMP_IO_WRITE32(pAdapter, MAC_SYS_CTRL, Value);
5956                 // disable sync
5957                 RTMP_IO_READ32(pAdapter, BCN_TIME_CFG, &csr.word);
5958                 csr.field.bBeaconGen = 0;
5959                 csr.field.bTBTTEnable = 0;
5960                 csr.field.TsfSyncMode = 0;
5961                 RTMP_IO_WRITE32(pAdapter, BCN_TIME_CFG, csr.word);
5962
5963                 pAdapter->StaCfg.BssType = BSS_MONITOR;
5964         pAdapter->net_dev->type = ARPHRD_IEEE80211_PRISM; //ARPHRD_IEEE80211; // IEEE80211
5965                 DBGPRINT(RT_DEBUG_TRACE, ("===>Set_NetworkType_Proc::(MONITOR)\n"));
5966     }
5967
5968     // Reset Ralink supplicant to not use, it will be set to start when UI set PMK key
5969     pAdapter->StaCfg.WpaState = SS_NOTUSE;
5970
5971     DBGPRINT(RT_DEBUG_TRACE, ("Set_NetworkType_Proc::(NetworkType=%d)\n", pAdapter->StaCfg.BssType));
5972
5973     return TRUE;
5974 }
5975
5976 /*
5977     ==========================================================================
5978     Description:
5979         Set Authentication mode
5980     Return:
5981         TRUE if all parameters are OK, FALSE otherwise
5982     ==========================================================================
5983 */
5984 INT Set_AuthMode_Proc(
5985     IN  PRTMP_ADAPTER   pAdapter,
5986     IN  PUCHAR          arg)
5987 {
5988     if ((strcmp(arg, "WEPAUTO") == 0) || (strcmp(arg, "wepauto") == 0))
5989         pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeAutoSwitch;
5990     else if ((strcmp(arg, "OPEN") == 0) || (strcmp(arg, "open") == 0))
5991         pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
5992     else if ((strcmp(arg, "SHARED") == 0) || (strcmp(arg, "shared") == 0))
5993         pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeShared;
5994     else if ((strcmp(arg, "WPAPSK") == 0) || (strcmp(arg, "wpapsk") == 0))
5995         pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPAPSK;
5996     else if ((strcmp(arg, "WPANONE") == 0) || (strcmp(arg, "wpanone") == 0))
5997         pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPANone;
5998     else if ((strcmp(arg, "WPA2PSK") == 0) || (strcmp(arg, "wpa2psk") == 0))
5999         pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPA2PSK;
6000 #ifdef WPA_SUPPLICANT_SUPPORT
6001     else if ((strcmp(arg, "WPA") == 0) || (strcmp(arg, "wpa") == 0))
6002         pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPA;
6003     else if ((strcmp(arg, "WPA2") == 0) || (strcmp(arg, "wpa2") == 0))
6004         pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPA2;
6005 #endif // WPA_SUPPLICANT_SUPPORT //
6006     else
6007         return FALSE;
6008
6009     pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
6010
6011     DBGPRINT(RT_DEBUG_TRACE, ("Set_AuthMode_Proc::(AuthMode=%d)\n", pAdapter->StaCfg.AuthMode));
6012
6013     return TRUE;
6014 }
6015
6016 /*
6017     ==========================================================================
6018     Description:
6019         Set Encryption Type
6020     Return:
6021         TRUE if all parameters are OK, FALSE otherwise
6022     ==========================================================================
6023 */
6024 INT Set_EncrypType_Proc(
6025     IN  PRTMP_ADAPTER   pAdapter,
6026     IN  PUCHAR          arg)
6027 {
6028     if ((strcmp(arg, "NONE") == 0) || (strcmp(arg, "none") == 0))
6029     {
6030         if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
6031             return TRUE;    // do nothing
6032
6033         pAdapter->StaCfg.WepStatus     = Ndis802_11WEPDisabled;
6034         pAdapter->StaCfg.PairCipher    = Ndis802_11WEPDisabled;
6035             pAdapter->StaCfg.GroupCipher   = Ndis802_11WEPDisabled;
6036     }
6037     else if ((strcmp(arg, "WEP") == 0) || (strcmp(arg, "wep") == 0))
6038     {
6039         if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
6040             return TRUE;    // do nothing
6041
6042         pAdapter->StaCfg.WepStatus     = Ndis802_11WEPEnabled;
6043         pAdapter->StaCfg.PairCipher    = Ndis802_11WEPEnabled;
6044             pAdapter->StaCfg.GroupCipher   = Ndis802_11WEPEnabled;
6045     }
6046     else if ((strcmp(arg, "TKIP") == 0) || (strcmp(arg, "tkip") == 0))
6047     {
6048         if (pAdapter->StaCfg.AuthMode < Ndis802_11AuthModeWPA)
6049             return TRUE;    // do nothing
6050
6051         pAdapter->StaCfg.WepStatus     = Ndis802_11Encryption2Enabled;
6052         pAdapter->StaCfg.PairCipher    = Ndis802_11Encryption2Enabled;
6053             pAdapter->StaCfg.GroupCipher   = Ndis802_11Encryption2Enabled;
6054     }
6055     else if ((strcmp(arg, "AES") == 0) || (strcmp(arg, "aes") == 0))
6056     {
6057         if (pAdapter->StaCfg.AuthMode < Ndis802_11AuthModeWPA)
6058             return TRUE;    // do nothing
6059
6060         pAdapter->StaCfg.WepStatus     = Ndis802_11Encryption3Enabled;
6061         pAdapter->StaCfg.PairCipher    = Ndis802_11Encryption3Enabled;
6062             pAdapter->StaCfg.GroupCipher   = Ndis802_11Encryption3Enabled;
6063     }
6064     else
6065         return FALSE;
6066
6067     pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
6068
6069     DBGPRINT(RT_DEBUG_TRACE, ("Set_EncrypType_Proc::(EncrypType=%d)\n", pAdapter->StaCfg.WepStatus));
6070
6071     return TRUE;
6072 }
6073
6074 /*
6075     ==========================================================================
6076     Description:
6077         Set Default Key ID
6078     Return:
6079         TRUE if all parameters are OK, FALSE otherwise
6080     ==========================================================================
6081 */
6082 INT Set_DefaultKeyID_Proc(
6083     IN  PRTMP_ADAPTER   pAdapter,
6084     IN  PUCHAR          arg)
6085 {
6086     ULONG                               KeyIdx;
6087
6088     KeyIdx = simple_strtol(arg, 0, 10);
6089     if((KeyIdx >= 1 ) && (KeyIdx <= 4))
6090         pAdapter->StaCfg.DefaultKeyId = (UCHAR) (KeyIdx - 1 );
6091     else
6092         return FALSE;  //Invalid argument
6093
6094     DBGPRINT(RT_DEBUG_TRACE, ("Set_DefaultKeyID_Proc::(DefaultKeyID=%d)\n", pAdapter->StaCfg.DefaultKeyId));
6095
6096     return TRUE;
6097 }
6098
6099 /*
6100     ==========================================================================
6101     Description:
6102         Set WEP KEY1
6103     Return:
6104         TRUE if all parameters are OK, FALSE otherwise
6105     ==========================================================================
6106 */
6107 INT Set_Key1_Proc(
6108     IN  PRTMP_ADAPTER   pAdapter,
6109     IN  PUCHAR          arg)
6110 {
6111     int                                 KeyLen;
6112     int                                 i;
6113     UCHAR                               CipherAlg=CIPHER_WEP64;
6114
6115     if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
6116         return TRUE;    // do nothing
6117
6118     KeyLen = strlen(arg);
6119
6120     switch (KeyLen)
6121     {
6122         case 5: //wep 40 Ascii type
6123             pAdapter->SharedKey[BSS0][0].KeyLen = KeyLen;
6124             memcpy(pAdapter->SharedKey[BSS0][0].Key, arg, KeyLen);
6125             CipherAlg = CIPHER_WEP64;
6126             DBGPRINT(RT_DEBUG_TRACE, ("Set_Key1_Proc::(Key1=%s and type=%s)\n", arg, "Ascii"));
6127             break;
6128         case 10: //wep 40 Hex type
6129             for(i=0; i < KeyLen; i++)
6130             {
6131                 if( !isxdigit(*(arg+i)) )
6132                     return FALSE;  //Not Hex value;
6133             }
6134             pAdapter->SharedKey[BSS0][0].KeyLen = KeyLen / 2 ;
6135             AtoH(arg, pAdapter->SharedKey[BSS0][0].Key, KeyLen / 2);
6136             CipherAlg = CIPHER_WEP64;
6137             DBGPRINT(RT_DEBUG_TRACE, ("Set_Key1_Proc::(Key1=%s and type=%s)\n", arg, "Hex"));
6138             break;
6139         case 13: //wep 104 Ascii type
6140             pAdapter->SharedKey[BSS0][0].KeyLen = KeyLen;
6141             memcpy(pAdapter->SharedKey[BSS0][0].Key, arg, KeyLen);
6142             CipherAlg = CIPHER_WEP128;
6143             DBGPRINT(RT_DEBUG_TRACE, ("Set_Key1_Proc::(Key1=%s and type=%s)\n", arg, "Ascii"));
6144             break;
6145         case 26: //wep 104 Hex type
6146             for(i=0; i < KeyLen; i++)
6147             {
6148                 if( !isxdigit(*(arg+i)) )
6149                     return FALSE;  //Not Hex value;
6150             }
6151             pAdapter->SharedKey[BSS0][0].KeyLen = KeyLen / 2 ;
6152             AtoH(arg, pAdapter->SharedKey[BSS0][0].Key, KeyLen / 2);
6153             CipherAlg = CIPHER_WEP128;
6154             DBGPRINT(RT_DEBUG_TRACE, ("Set_Key1_Proc::(Key1=%s and type=%s)\n", arg, "Hex"));
6155             break;
6156         default: //Invalid argument
6157             DBGPRINT(RT_DEBUG_TRACE, ("Set_Key1_Proc::Invalid argument (=%s)\n", arg));
6158             return FALSE;
6159     }
6160
6161     pAdapter->SharedKey[BSS0][0].CipherAlg = CipherAlg;
6162
6163     // Set keys (into ASIC)
6164     if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
6165         ;   // not support
6166     else    // Old WEP stuff
6167     {
6168         AsicAddSharedKeyEntry(pAdapter,
6169                               0,
6170                               0,
6171                               pAdapter->SharedKey[BSS0][0].CipherAlg,
6172                               pAdapter->SharedKey[BSS0][0].Key,
6173                               NULL,
6174                               NULL);
6175     }
6176
6177     return TRUE;
6178 }
6179 /*
6180     ==========================================================================
6181
6182     Description:
6183         Set WEP KEY2
6184     Return:
6185         TRUE if all parameters are OK, FALSE otherwise
6186     ==========================================================================
6187 */
6188 INT Set_Key2_Proc(
6189     IN  PRTMP_ADAPTER   pAdapter,
6190     IN  PUCHAR          arg)
6191 {
6192     int                                 KeyLen;
6193     int                                 i;
6194     UCHAR                               CipherAlg=CIPHER_WEP64;
6195
6196     if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
6197         return TRUE;    // do nothing
6198
6199     KeyLen = strlen(arg);
6200
6201     switch (KeyLen)
6202     {
6203         case 5: //wep 40 Ascii type
6204             pAdapter->SharedKey[BSS0][1].KeyLen = KeyLen;
6205             memcpy(pAdapter->SharedKey[BSS0][1].Key, arg, KeyLen);
6206             CipherAlg = CIPHER_WEP64;
6207             DBGPRINT(RT_DEBUG_TRACE, ("Set_Key2_Proc::(Key2=%s and type=%s)\n", arg, "Ascii"));
6208             break;
6209         case 10: //wep 40 Hex type
6210             for(i=0; i < KeyLen; i++)
6211             {
6212                 if( !isxdigit(*(arg+i)) )
6213                     return FALSE;  //Not Hex value;
6214             }
6215             pAdapter->SharedKey[BSS0][1].KeyLen = KeyLen / 2 ;
6216             AtoH(arg, pAdapter->SharedKey[BSS0][1].Key, KeyLen / 2);
6217             CipherAlg = CIPHER_WEP64;
6218             DBGPRINT(RT_DEBUG_TRACE, ("Set_Key2_Proc::(Key2=%s and type=%s)\n", arg, "Hex"));
6219             break;
6220         case 13: //wep 104 Ascii type
6221             pAdapter->SharedKey[BSS0][1].KeyLen = KeyLen;
6222             memcpy(pAdapter->SharedKey[BSS0][1].Key, arg, KeyLen);
6223             CipherAlg = CIPHER_WEP128;
6224             DBGPRINT(RT_DEBUG_TRACE, ("Set_Key2_Proc::(Key2=%s and type=%s)\n", arg, "Ascii"));
6225             break;
6226         case 26: //wep 104 Hex type
6227             for(i=0; i < KeyLen; i++)
6228             {
6229                 if( !isxdigit(*(arg+i)) )
6230                     return FALSE;  //Not Hex value;
6231             }
6232             pAdapter->SharedKey[BSS0][1].KeyLen = KeyLen / 2 ;
6233             AtoH(arg, pAdapter->SharedKey[BSS0][1].Key, KeyLen / 2);
6234             CipherAlg = CIPHER_WEP128;
6235             DBGPRINT(RT_DEBUG_TRACE, ("Set_Key2_Proc::(Key2=%s and type=%s)\n", arg, "Hex"));
6236             break;
6237         default: //Invalid argument
6238             DBGPRINT(RT_DEBUG_TRACE, ("Set_Key2_Proc::Invalid argument (=%s)\n", arg));
6239             return FALSE;
6240     }
6241     pAdapter->SharedKey[BSS0][1].CipherAlg = CipherAlg;
6242
6243     // Set keys (into ASIC)
6244     if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
6245         ;   // not support
6246     else    // Old WEP stuff
6247     {
6248         AsicAddSharedKeyEntry(pAdapter,
6249                               0,
6250                               1,
6251                               pAdapter->SharedKey[BSS0][1].CipherAlg,
6252                               pAdapter->SharedKey[BSS0][1].Key,
6253                               NULL,
6254                               NULL);
6255     }
6256
6257     return TRUE;
6258 }
6259 /*
6260     ==========================================================================
6261     Description:
6262         Set WEP KEY3
6263     Return:
6264         TRUE if all parameters are OK, FALSE otherwise
6265     ==========================================================================
6266 */
6267 INT Set_Key3_Proc(
6268     IN  PRTMP_ADAPTER   pAdapter,
6269     IN  PUCHAR          arg)
6270 {
6271     int                                 KeyLen;
6272     int                                 i;
6273     UCHAR                               CipherAlg=CIPHER_WEP64;
6274
6275     if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
6276         return TRUE;    // do nothing
6277
6278     KeyLen = strlen(arg);
6279
6280     switch (KeyLen)
6281     {
6282         case 5: //wep 40 Ascii type
6283             pAdapter->SharedKey[BSS0][2].KeyLen = KeyLen;
6284             memcpy(pAdapter->SharedKey[BSS0][2].Key, arg, KeyLen);
6285             CipherAlg = CIPHER_WEP64;
6286             DBGPRINT(RT_DEBUG_TRACE, ("Set_Key3_Proc::(Key3=%s and type=Ascii)\n", arg));
6287             break;
6288         case 10: //wep 40 Hex type
6289             for(i=0; i < KeyLen; i++)
6290             {
6291                 if( !isxdigit(*(arg+i)) )
6292                     return FALSE;  //Not Hex value;
6293             }
6294             pAdapter->SharedKey[BSS0][2].KeyLen = KeyLen / 2 ;
6295             AtoH(arg, pAdapter->SharedKey[BSS0][2].Key, KeyLen / 2);
6296             CipherAlg = CIPHER_WEP64;
6297             DBGPRINT(RT_DEBUG_TRACE, ("Set_Key3_Proc::(Key3=%s and type=Hex)\n", arg));
6298             break;
6299         case 13: //wep 104 Ascii type
6300             pAdapter->SharedKey[BSS0][2].KeyLen = KeyLen;
6301             memcpy(pAdapter->SharedKey[BSS0][2].Key, arg, KeyLen);
6302             CipherAlg = CIPHER_WEP128;
6303             DBGPRINT(RT_DEBUG_TRACE, ("Set_Key3_Proc::(Key3=%s and type=Ascii)\n", arg));
6304             break;
6305         case 26: //wep 104 Hex type
6306             for(i=0; i < KeyLen; i++)
6307             {
6308                 if( !isxdigit(*(arg+i)) )
6309                     return FALSE;  //Not Hex value;
6310             }
6311             pAdapter->SharedKey[BSS0][2].KeyLen = KeyLen / 2 ;
6312             AtoH(arg, pAdapter->SharedKey[BSS0][2].Key, KeyLen / 2);
6313             CipherAlg = CIPHER_WEP128;
6314             DBGPRINT(RT_DEBUG_TRACE, ("Set_Key3_Proc::(Key3=%s and type=Hex)\n", arg));
6315             break;
6316         default: //Invalid argument
6317             DBGPRINT(RT_DEBUG_TRACE, ("Set_Key3_Proc::Invalid argument (=%s)\n", arg));
6318             return FALSE;
6319     }
6320     pAdapter->SharedKey[BSS0][2].CipherAlg = CipherAlg;
6321
6322     // Set keys (into ASIC)
6323     if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
6324         ;   // not support
6325     else    // Old WEP stuff
6326     {
6327         AsicAddSharedKeyEntry(pAdapter,
6328                               0,
6329                               2,
6330                               pAdapter->SharedKey[BSS0][2].CipherAlg,
6331                               pAdapter->SharedKey[BSS0][2].Key,
6332                               NULL,
6333                               NULL);
6334     }
6335
6336     return TRUE;
6337 }
6338 /*
6339     ==========================================================================
6340     Description:
6341         Set WEP KEY4
6342     Return:
6343         TRUE if all parameters are OK, FALSE otherwise
6344     ==========================================================================
6345 */
6346 INT Set_Key4_Proc(
6347     IN  PRTMP_ADAPTER   pAdapter,
6348     IN  PUCHAR          arg)
6349 {
6350     int                                 KeyLen;
6351     int                                 i;
6352     UCHAR                               CipherAlg=CIPHER_WEP64;
6353
6354     if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
6355         return TRUE;    // do nothing
6356
6357     KeyLen = strlen(arg);
6358
6359     switch (KeyLen)
6360     {
6361         case 5: //wep 40 Ascii type
6362             pAdapter->SharedKey[BSS0][3].KeyLen = KeyLen;
6363             memcpy(pAdapter->SharedKey[BSS0][3].Key, arg, KeyLen);
6364             CipherAlg = CIPHER_WEP64;
6365             DBGPRINT(RT_DEBUG_TRACE, ("Set_Key4_Proc::(Key4=%s and type=%s)\n", arg, "Ascii"));
6366             break;
6367         case 10: //wep 40 Hex type
6368             for(i=0; i < KeyLen; i++)
6369             {
6370                 if( !isxdigit(*(arg+i)) )
6371                     return FALSE;  //Not Hex value;
6372             }
6373             pAdapter->SharedKey[BSS0][3].KeyLen = KeyLen / 2 ;
6374             AtoH(arg, pAdapter->SharedKey[BSS0][3].Key, KeyLen / 2);
6375             CipherAlg = CIPHER_WEP64;
6376             DBGPRINT(RT_DEBUG_TRACE, ("Set_Key4_Proc::(Key4=%s and type=%s)\n", arg, "Hex"));
6377             break;
6378         case 13: //wep 104 Ascii type
6379             pAdapter->SharedKey[BSS0][3].KeyLen = KeyLen;
6380             memcpy(pAdapter->SharedKey[BSS0][3].Key, arg, KeyLen);
6381             CipherAlg = CIPHER_WEP128;
6382             DBGPRINT(RT_DEBUG_TRACE, ("Set_Key4_Proc::(Key4=%s and type=%s)\n", arg, "Ascii"));
6383             break;
6384         case 26: //wep 104 Hex type
6385             for(i=0; i < KeyLen; i++)
6386             {
6387                 if( !isxdigit(*(arg+i)) )
6388                     return FALSE;  //Not Hex value;
6389             }
6390             pAdapter->SharedKey[BSS0][3].KeyLen = KeyLen / 2 ;
6391             AtoH(arg, pAdapter->SharedKey[BSS0][3].Key, KeyLen / 2);
6392             CipherAlg = CIPHER_WEP128;
6393             DBGPRINT(RT_DEBUG_TRACE, ("Set_Key4_Proc::(Key4=%s and type=%s)\n", arg, "Hex"));
6394             break;
6395         default: //Invalid argument
6396             DBGPRINT(RT_DEBUG_TRACE, ("Set_Key4_Proc::Invalid argument (=%s)\n", arg));
6397             return FALSE;
6398     }
6399     pAdapter->SharedKey[BSS0][3].CipherAlg = CipherAlg;
6400
6401     // Set keys (into ASIC)
6402     if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
6403         ;   // not support
6404     else    // Old WEP stuff
6405     {
6406         AsicAddSharedKeyEntry(pAdapter,
6407                               0,
6408                               3,
6409                               pAdapter->SharedKey[BSS0][3].CipherAlg,
6410                               pAdapter->SharedKey[BSS0][3].Key,
6411                               NULL,
6412                               NULL);
6413     }
6414
6415     return TRUE;
6416 }
6417
6418 /*
6419     ==========================================================================
6420     Description:
6421         Set WPA PSK key
6422     Return:
6423         TRUE if all parameters are OK, FALSE otherwise
6424     ==========================================================================
6425 */
6426 INT Set_WPAPSK_Proc(
6427     IN  PRTMP_ADAPTER   pAdapter,
6428     IN  PUCHAR          arg)
6429 {
6430     UCHAR                   keyMaterial[40];
6431
6432     if ((pAdapter->StaCfg.AuthMode != Ndis802_11AuthModeWPAPSK) &&
6433         (pAdapter->StaCfg.AuthMode != Ndis802_11AuthModeWPA2PSK) &&
6434             (pAdapter->StaCfg.AuthMode != Ndis802_11AuthModeWPANone)
6435                 )
6436         return TRUE;    // do nothing
6437
6438     DBGPRINT(RT_DEBUG_TRACE, ("Set_WPAPSK_Proc::(WPAPSK=%s)\n", arg));
6439
6440     NdisZeroMemory(keyMaterial, 40);
6441
6442     if ((strlen(arg) < 8) || (strlen(arg) > 64))
6443     {
6444         DBGPRINT(RT_DEBUG_TRACE, ("Set failed!!(WPAPSK=%s), WPAPSK key-string required 8 ~ 64 characters \n", arg));
6445         return FALSE;
6446     }
6447
6448     if (strlen(arg) == 64)
6449     {
6450         AtoH(arg, keyMaterial, 32);
6451         NdisMoveMemory(pAdapter->StaCfg.PMK, keyMaterial, 32);
6452
6453     }
6454     else
6455     {
6456         PasswordHash((char *)arg, pAdapter->MlmeAux.Ssid, pAdapter->MlmeAux.SsidLen, keyMaterial);
6457         NdisMoveMemory(pAdapter->StaCfg.PMK, keyMaterial, 32);
6458     }
6459
6460
6461
6462     if(pAdapter->StaCfg.BssType == BSS_ADHOC &&
6463        pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
6464     {
6465          pAdapter->StaCfg.WpaState = SS_NOTUSE;
6466     }
6467     else
6468     {
6469         // Start STA supplicant state machine
6470         pAdapter->StaCfg.WpaState = SS_START;
6471     }
6472
6473     return TRUE;
6474 }
6475
6476 /*
6477     ==========================================================================
6478     Description:
6479         Set Power Saving mode
6480     Return:
6481         TRUE if all parameters are OK, FALSE otherwise
6482     ==========================================================================
6483 */
6484 INT Set_PSMode_Proc(
6485     IN  PRTMP_ADAPTER   pAdapter,
6486     IN  PUCHAR          arg)
6487 {
6488     if (pAdapter->StaCfg.BssType == BSS_INFRA)
6489     {
6490         if ((strcmp(arg, "Max_PSP") == 0) ||
6491                         (strcmp(arg, "max_psp") == 0) ||
6492                         (strcmp(arg, "MAX_PSP") == 0))
6493         {
6494             // do NOT turn on PSM bit here, wait until MlmeCheckForPsmChange()
6495             // to exclude certain situations.
6496             if (pAdapter->StaCfg.bWindowsACCAMEnable == FALSE)
6497                 pAdapter->StaCfg.WindowsPowerMode = Ndis802_11PowerModeMAX_PSP;
6498             pAdapter->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeMAX_PSP;
6499             OPSTATUS_SET_FLAG(pAdapter, fOP_STATUS_RECEIVE_DTIM);
6500             pAdapter->StaCfg.DefaultListenCount = 5;
6501
6502         }
6503         else if ((strcmp(arg, "Fast_PSP") == 0) ||
6504                                  (strcmp(arg, "fast_psp") == 0) ||
6505                  (strcmp(arg, "FAST_PSP") == 0))
6506         {
6507             // do NOT turn on PSM bit here, wait until MlmeCheckForPsmChange()
6508             // to exclude certain situations.
6509             OPSTATUS_SET_FLAG(pAdapter, fOP_STATUS_RECEIVE_DTIM);
6510             if (pAdapter->StaCfg.bWindowsACCAMEnable == FALSE)
6511                 pAdapter->StaCfg.WindowsPowerMode = Ndis802_11PowerModeFast_PSP;
6512             pAdapter->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeFast_PSP;
6513             pAdapter->StaCfg.DefaultListenCount = 3;
6514         }
6515         else if ((strcmp(arg, "Legacy_PSP") == 0) ||
6516                  (strcmp(arg, "legacy_psp") == 0) ||
6517                  (strcmp(arg, "LEGACY_PSP") == 0))
6518         {
6519             // do NOT turn on PSM bit here, wait until MlmeCheckForPsmChange()
6520             // to exclude certain situations.
6521             OPSTATUS_SET_FLAG(pAdapter, fOP_STATUS_RECEIVE_DTIM);
6522             if (pAdapter->StaCfg.bWindowsACCAMEnable == FALSE)
6523                 pAdapter->StaCfg.WindowsPowerMode = Ndis802_11PowerModeLegacy_PSP;
6524             pAdapter->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeLegacy_PSP;
6525             pAdapter->StaCfg.DefaultListenCount = 3;
6526         }
6527         else
6528         {
6529             //Default Ndis802_11PowerModeCAM
6530             // clear PSM bit immediately
6531             MlmeSetPsmBit(pAdapter, PWR_ACTIVE);
6532             OPSTATUS_SET_FLAG(pAdapter, fOP_STATUS_RECEIVE_DTIM);
6533             if (pAdapter->StaCfg.bWindowsACCAMEnable == FALSE)
6534                 pAdapter->StaCfg.WindowsPowerMode = Ndis802_11PowerModeCAM;
6535             pAdapter->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeCAM;
6536         }
6537
6538         DBGPRINT(RT_DEBUG_TRACE, ("Set_PSMode_Proc::(PSMode=%ld)\n", pAdapter->StaCfg.WindowsPowerMode));
6539     }
6540     else
6541         return FALSE;
6542
6543
6544     return TRUE;
6545 }
6546
6547 #ifdef WPA_SUPPLICANT_SUPPORT
6548 /*
6549     ==========================================================================
6550     Description:
6551         Set WpaSupport flag.
6552     Value:
6553         0: Driver ignore wpa_supplicant.
6554         1: wpa_supplicant initiates scanning and AP selection.
6555         2: driver takes care of scanning, AP selection, and IEEE 802.11 association parameters.
6556     Return:
6557         TRUE if all parameters are OK, FALSE otherwise
6558     ==========================================================================
6559 */
6560 INT Set_Wpa_Support(
6561     IN  PRTMP_ADAPTER   pAd,
6562         IN      PUCHAR                  arg)
6563 {
6564
6565     if ( simple_strtol(arg, 0, 10) == 0)
6566         pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_DISABLE;
6567     else if ( simple_strtol(arg, 0, 10) == 1)
6568         pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_ENABLE;
6569     else if ( simple_strtol(arg, 0, 10) == 2)
6570         pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_ENABLE_WITH_WEB_UI;
6571     else
6572         pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_DISABLE;
6573
6574     DBGPRINT(RT_DEBUG_TRACE, ("Set_Wpa_Support::(WpaSupplicantUP=%d)\n", pAd->StaCfg.WpaSupplicantUP));
6575
6576     return TRUE;
6577 }
6578 #endif // WPA_SUPPLICANT_SUPPORT //
6579
6580 #ifdef DBG
6581 /*
6582     ==========================================================================
6583     Description:
6584         Read / Write MAC
6585     Arguments:
6586         pAdapter                    Pointer to our adapter
6587         wrq                         Pointer to the ioctl argument
6588
6589     Return Value:
6590         None
6591
6592     Note:
6593         Usage:
6594                1.) iwpriv ra0 mac 0        ==> read MAC where Addr=0x0
6595                2.) iwpriv ra0 mac 0=12     ==> write MAC where Addr=0x0, value=12
6596     ==========================================================================
6597 */
6598 VOID RTMPIoctlMAC(
6599         IN      PRTMP_ADAPTER   pAdapter,
6600         IN      struct iwreq    *wrq)
6601 {
6602         CHAR                            *this_char;
6603         CHAR                            *value;
6604         INT                                     j = 0, k = 0;
6605         CHAR                            msg[1024];
6606         CHAR                            arg[255];
6607         ULONG                           macAddr = 0;
6608         UCHAR                           temp[16], temp2[16];
6609         UINT32                          macValue = 0;
6610         INT                                     Status;
6611
6612
6613         memset(msg, 0x00, 1024);
6614         if (wrq->u.data.length > 1) //No parameters.
6615         {
6616             Status = copy_from_user(arg, wrq->u.data.pointer, (wrq->u.data.length > 255) ? 255 : wrq->u.data.length);
6617                 sprintf(msg, "\n");
6618
6619                 //Parsing Read or Write
6620             this_char = arg;
6621                 if (!*this_char)
6622                         goto next;
6623
6624                 if ((value = rtstrchr(this_char, '=')) != NULL)
6625                         *value++ = 0;
6626
6627                 if (!value || !*value)
6628                 { //Read
6629                         // Sanity check
6630                         if(strlen(this_char) > 4)
6631                                 goto next;
6632
6633                         j = strlen(this_char);
6634                         while(j-- > 0)
6635                         {
6636                                 if(this_char[j] > 'f' || this_char[j] < '0')
6637                                         return;
6638                         }
6639
6640                         // Mac Addr
6641                         k = j = strlen(this_char);
6642                         while(j-- > 0)
6643                         {
6644                                 this_char[4-k+j] = this_char[j];
6645                         }
6646
6647                         while(k < 4)
6648                                 this_char[3-k++]='0';
6649                         this_char[4]='\0';
6650
6651                         if(strlen(this_char) == 4)
6652                         {
6653                                 AtoH(this_char, temp, 2);
6654                                 macAddr = *temp*256 + temp[1];
6655                                 if (macAddr < 0xFFFF)
6656                                 {
6657                                         RTMP_IO_READ32(pAdapter, macAddr, &macValue);
6658                                         DBGPRINT(RT_DEBUG_TRACE, ("MacAddr=%lx, MacValue=%x\n", macAddr, macValue));
6659                                         sprintf(msg+strlen(msg), "[0x%08lX]:%08X  ", macAddr , macValue);
6660                                 }
6661                                 else
6662                                 {//Invalid parametes, so default printk all bbp
6663                                         goto next;
6664                                 }
6665                         }
6666                 }
6667                 else
6668                 { //Write
6669                         memcpy(&temp2, value, strlen(value));
6670                         temp2[strlen(value)] = '\0';
6671
6672                         // Sanity check
6673                         if((strlen(this_char) > 4) || strlen(temp2) > 8)
6674                                 goto next;
6675
6676                         j = strlen(this_char);
6677                         while(j-- > 0)
6678                         {
6679                                 if(this_char[j] > 'f' || this_char[j] < '0')
6680                                         return;
6681                         }
6682
6683                         j = strlen(temp2);
6684                         while(j-- > 0)
6685                         {
6686                                 if(temp2[j] > 'f' || temp2[j] < '0')
6687                                         return;
6688                         }
6689
6690                         //MAC Addr
6691                         k = j = strlen(this_char);
6692                         while(j-- > 0)
6693                         {
6694                                 this_char[4-k+j] = this_char[j];
6695                         }
6696
6697                         while(k < 4)
6698                                 this_char[3-k++]='0';
6699                         this_char[4]='\0';
6700
6701                         //MAC value
6702                         k = j = strlen(temp2);
6703                         while(j-- > 0)
6704                         {
6705                                 temp2[8-k+j] = temp2[j];
6706                         }
6707
6708                         while(k < 8)
6709                                 temp2[7-k++]='0';
6710                         temp2[8]='\0';
6711
6712                         {
6713                                 AtoH(this_char, temp, 2);
6714                                 macAddr = *temp*256 + temp[1];
6715
6716                                 AtoH(temp2, temp, 4);
6717                                 macValue = *temp*256*256*256 + temp[1]*256*256 + temp[2]*256 + temp[3];
6718
6719                                 // debug mode
6720                                 if (macAddr == (HW_DEBUG_SETTING_BASE + 4))
6721                                 {
6722                                         // 0x2bf4: byte0 non-zero: enable R17 tuning, 0: disable R17 tuning
6723                     if (macValue & 0x000000ff)
6724                     {
6725                         pAdapter->BbpTuning.bEnable = TRUE;
6726                         DBGPRINT(RT_DEBUG_TRACE,("turn on R17 tuning\n"));
6727                     }
6728                     else
6729                     {
6730                         UCHAR R66;
6731                         pAdapter->BbpTuning.bEnable = FALSE;
6732                         R66 = 0x26 + GET_LNA_GAIN(pAdapter);
6733 #ifdef RALINK_ATE
6734                                                 if (ATE_ON(pAdapter))
6735                                                 {
6736                                                         ATE_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R66, (0x26 + GET_LNA_GAIN(pAdapter)));
6737                                                 }
6738                                                 else
6739 #endif // RALINK_ATE //
6740                                                 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R66, (0x26 + GET_LNA_GAIN(pAdapter)));
6741                         DBGPRINT(RT_DEBUG_TRACE,("turn off R17 tuning, restore to 0x%02x\n", R66));
6742                     }
6743                                         return;
6744                                 }
6745
6746                                 DBGPRINT(RT_DEBUG_TRACE, ("MacAddr=%02lx, MacValue=0x%x\n", macAddr, macValue));
6747
6748                                 RTMP_IO_WRITE32(pAdapter, macAddr, macValue);
6749                                 sprintf(msg+strlen(msg), "[0x%08lX]:%08X  ", macAddr, macValue);
6750                         }
6751                 }
6752         }
6753 next:
6754         if(strlen(msg) == 1)
6755                 sprintf(msg+strlen(msg), "===>Error command format!");
6756
6757         // Copy the information into the user buffer
6758         wrq->u.data.length = strlen(msg);
6759         Status = copy_to_user(wrq->u.data.pointer, msg, wrq->u.data.length);
6760
6761         DBGPRINT(RT_DEBUG_TRACE, ("<==RTMPIoctlMAC\n\n"));
6762 }
6763
6764 /*
6765     ==========================================================================
6766     Description:
6767         Read / Write E2PROM
6768     Arguments:
6769         pAdapter                    Pointer to our adapter
6770         wrq                         Pointer to the ioctl argument
6771
6772     Return Value:
6773         None
6774
6775     Note:
6776         Usage:
6777                1.) iwpriv ra0 e2p 0             ==> read E2PROM where Addr=0x0
6778                2.) iwpriv ra0 e2p 0=1234    ==> write E2PROM where Addr=0x0, value=1234
6779     ==========================================================================
6780 */
6781 VOID RTMPIoctlE2PROM(
6782         IN      PRTMP_ADAPTER   pAdapter,
6783         IN      struct iwreq    *wrq)
6784 {
6785         CHAR                            *this_char;
6786         CHAR                            *value;
6787         INT                                     j = 0, k = 0;
6788         CHAR                            msg[1024];
6789         CHAR                            arg[255];
6790         USHORT                          eepAddr = 0;
6791         UCHAR                           temp[16], temp2[16];
6792         USHORT                          eepValue;
6793         int                                     Status;
6794
6795
6796         memset(msg, 0x00, 1024);
6797         if (wrq->u.data.length > 1) //No parameters.
6798         {
6799             Status = copy_from_user(arg, wrq->u.data.pointer, (wrq->u.data.length > 255) ? 255 : wrq->u.data.length);
6800                 sprintf(msg, "\n");
6801
6802             //Parsing Read or Write
6803                 this_char = arg;
6804
6805
6806                 if (!*this_char)
6807                         goto next;
6808
6809                 if ((value = rtstrchr(this_char, '=')) != NULL)
6810                         *value++ = 0;
6811
6812                 if (!value || !*value)
6813                 { //Read
6814
6815                         // Sanity check
6816                         if(strlen(this_char) > 4)
6817                                 goto next;
6818
6819                         j = strlen(this_char);
6820                         while(j-- > 0)
6821                         {
6822                                 if(this_char[j] > 'f' || this_char[j] < '0')
6823                                         return;
6824                         }
6825
6826                         // E2PROM addr
6827                         k = j = strlen(this_char);
6828                         while(j-- > 0)
6829                         {
6830                                 this_char[4-k+j] = this_char[j];
6831                         }
6832
6833                         while(k < 4)
6834                                 this_char[3-k++]='0';
6835                         this_char[4]='\0';
6836
6837                         if(strlen(this_char) == 4)
6838                         {
6839                                 AtoH(this_char, temp, 2);
6840                                 eepAddr = *temp*256 + temp[1];
6841                                 if (eepAddr < 0xFFFF)
6842                                 {
6843                                         RT28xx_EEPROM_READ16(pAdapter, eepAddr, eepValue);
6844                                         sprintf(msg+strlen(msg), "[0x%04X]:0x%04X  ", eepAddr , eepValue);
6845                                 }
6846                                 else
6847                                 {//Invalid parametes, so default printk all bbp
6848                                         goto next;
6849                                 }
6850                         }
6851                 }
6852                 else
6853                 { //Write
6854                         memcpy(&temp2, value, strlen(value));
6855                         temp2[strlen(value)] = '\0';
6856
6857                         // Sanity check
6858                         if((strlen(this_char) > 4) || strlen(temp2) > 8)
6859                                 goto next;
6860
6861                         j = strlen(this_char);
6862                         while(j-- > 0)
6863                         {
6864                                 if(this_char[j] > 'f' || this_char[j] < '0')
6865                                         return;
6866                         }
6867                         j = strlen(temp2);
6868                         while(j-- > 0)
6869                         {
6870                                 if(temp2[j] > 'f' || temp2[j] < '0')
6871                                         return;
6872                         }
6873
6874                         //MAC Addr
6875                         k = j = strlen(this_char);
6876                         while(j-- > 0)
6877                         {
6878                                 this_char[4-k+j] = this_char[j];
6879                         }
6880
6881                         while(k < 4)
6882                                 this_char[3-k++]='0';
6883                         this_char[4]='\0';
6884
6885                         //MAC value
6886                         k = j = strlen(temp2);
6887                         while(j-- > 0)
6888                         {
6889                                 temp2[4-k+j] = temp2[j];
6890                         }
6891
6892                         while(k < 4)
6893                                 temp2[3-k++]='0';
6894                         temp2[4]='\0';
6895
6896                         AtoH(this_char, temp, 2);
6897                         eepAddr = *temp*256 + temp[1];
6898
6899                         AtoH(temp2, temp, 2);
6900                         eepValue = *temp*256 + temp[1];
6901
6902                         RT28xx_EEPROM_WRITE16(pAdapter, eepAddr, eepValue);
6903                         sprintf(msg+strlen(msg), "[0x%02X]:%02X  ", eepAddr, eepValue);
6904                 }
6905         }
6906 next:
6907         if(strlen(msg) == 1)
6908                 sprintf(msg+strlen(msg), "===>Error command format!");
6909
6910
6911         // Copy the information into the user buffer
6912         wrq->u.data.length = strlen(msg);
6913         Status = copy_to_user(wrq->u.data.pointer, msg, wrq->u.data.length);
6914
6915         DBGPRINT(RT_DEBUG_TRACE, ("<==RTMPIoctlE2PROM\n"));
6916 }
6917 #endif // DBG //
6918
6919
6920
6921
6922 INT Set_TGnWifiTest_Proc(
6923     IN  PRTMP_ADAPTER   pAd,
6924     IN  PUCHAR          arg)
6925 {
6926     if (simple_strtol(arg, 0, 10) == 0)
6927         pAd->StaCfg.bTGnWifiTest = FALSE;
6928     else
6929         pAd->StaCfg.bTGnWifiTest = TRUE;
6930
6931     DBGPRINT(RT_DEBUG_TRACE, ("IF Set_TGnWifiTest_Proc::(bTGnWifiTest=%d)\n", pAd->StaCfg.bTGnWifiTest));
6932         return TRUE;
6933 }
6934
6935 INT Set_LongRetryLimit_Proc(
6936         IN      PRTMP_ADAPTER   pAdapter,
6937         IN      PUCHAR                  arg)
6938 {
6939         TX_RTY_CFG_STRUC        tx_rty_cfg;
6940         UCHAR                           LongRetryLimit = (UCHAR)simple_strtol(arg, 0, 10);
6941
6942         RTMP_IO_READ32(pAdapter, TX_RTY_CFG, &tx_rty_cfg.word);
6943         tx_rty_cfg.field.LongRtyLimit = LongRetryLimit;
6944         RTMP_IO_WRITE32(pAdapter, TX_RTY_CFG, tx_rty_cfg.word);
6945         DBGPRINT(RT_DEBUG_TRACE, ("IF Set_LongRetryLimit_Proc::(tx_rty_cfg=0x%x)\n", tx_rty_cfg.word));
6946         return TRUE;
6947 }
6948
6949 INT Set_ShortRetryLimit_Proc(
6950         IN      PRTMP_ADAPTER   pAdapter,
6951         IN      PUCHAR                  arg)
6952 {
6953         TX_RTY_CFG_STRUC        tx_rty_cfg;
6954         UCHAR                           ShortRetryLimit = (UCHAR)simple_strtol(arg, 0, 10);
6955
6956         RTMP_IO_READ32(pAdapter, TX_RTY_CFG, &tx_rty_cfg.word);
6957         tx_rty_cfg.field.ShortRtyLimit = ShortRetryLimit;
6958         RTMP_IO_WRITE32(pAdapter, TX_RTY_CFG, tx_rty_cfg.word);
6959         DBGPRINT(RT_DEBUG_TRACE, ("IF Set_ShortRetryLimit_Proc::(tx_rty_cfg=0x%x)\n", tx_rty_cfg.word));
6960         return TRUE;
6961 }
6962
6963 #ifdef EXT_BUILD_CHANNEL_LIST
6964 INT Set_Ieee80211dClientMode_Proc(
6965     IN  PRTMP_ADAPTER   pAdapter,
6966     IN  PUCHAR          arg)
6967 {
6968     if (simple_strtol(arg, 0, 10) == 0)
6969         pAdapter->StaCfg.IEEE80211dClientMode = Rt802_11_D_None;
6970     else if (simple_strtol(arg, 0, 10) == 1)
6971         pAdapter->StaCfg.IEEE80211dClientMode = Rt802_11_D_Flexible;
6972     else if (simple_strtol(arg, 0, 10) == 2)
6973         pAdapter->StaCfg.IEEE80211dClientMode = Rt802_11_D_Strict;
6974     else
6975         return FALSE;
6976
6977     DBGPRINT(RT_DEBUG_TRACE, ("Set_Ieee802dMode_Proc::(IEEEE0211dMode=%d)\n", pAdapter->StaCfg.IEEE80211dClientMode));
6978     return TRUE;
6979 }
6980 #endif // EXT_BUILD_CHANNEL_LIST //
6981
6982 #ifdef CARRIER_DETECTION_SUPPORT
6983 INT Set_CarrierDetect_Proc(
6984     IN  PRTMP_ADAPTER   pAd,
6985     IN  PUCHAR          arg)
6986 {
6987     if (simple_strtol(arg, 0, 10) == 0)
6988         pAd->CommonCfg.CarrierDetect.Enable = FALSE;
6989     else
6990         pAd->CommonCfg.CarrierDetect.Enable = TRUE;
6991
6992     DBGPRINT(RT_DEBUG_TRACE, ("IF Set_CarrierDetect_Proc::(CarrierDetect.Enable=%d)\n", pAd->CommonCfg.CarrierDetect.Enable));
6993         return TRUE;
6994 }
6995 #endif // CARRIER_DETECTION_SUPPORT //
6996