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