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