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