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