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