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