Staging: rt2870: remove dead CONFIG_AP_SUPPORT code
[safe/jmp/linux-2.6] / drivers / staging / rt2870 / sta_ioctl.c
1 /*
2  *************************************************************************
3  * Ralink Tech Inc.
4  * 5F., No.36, Taiyuan St., Jhubei City,
5  * Hsinchu County 302,
6  * Taiwan, R.O.C.
7  *
8  * (c) Copyright 2002-2007, Ralink Technology, Inc.
9  *
10  * This program is free software; you can redistribute it and/or modify  *
11  * it under the terms of the GNU General Public License as published by  *
12  * the Free Software Foundation; either version 2 of the License, or     *
13  * (at your option) any later version.                                   *
14  *                                                                       *
15  * This program is distributed in the hope that it will be useful,       *
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
18  * GNU General Public License for more details.                          *
19  *                                                                       *
20  * You should have received a copy of the GNU General Public License     *
21  * along with this program; if not, write to the                         *
22  * Free Software Foundation, Inc.,                                       *
23  * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
24  *                                                                       *
25  *************************************************************************
26
27     Module Name:
28     sta_ioctl.c
29
30     Abstract:
31     IOCTL related subroutines
32
33     Revision History:
34     Who         When          What
35     --------    ----------    ----------------------------------------------
36     Rory Chen   01-03-2003    created
37         Rory Chen   02-14-2005    modify to support RT61
38 */
39
40 #include        "rt_config.h"
41
42 #ifdef DBG
43 extern ULONG    RTDebugLevel;
44 #endif
45
46 #define NR_WEP_KEYS                             4
47 #define WEP_SMALL_KEY_LEN                       (40/8)
48 #define WEP_LARGE_KEY_LEN                       (104/8)
49
50 #define GROUP_KEY_NO                4
51
52 extern UCHAR    CipherWpa2Template[];
53 extern UCHAR    CipherWpaPskTkip[];
54 extern UCHAR    CipherWpaPskTkipLen;
55
56 typedef struct PACKED _RT_VERSION_INFO{
57     UCHAR       DriverVersionW;
58     UCHAR       DriverVersionX;
59     UCHAR       DriverVersionY;
60     UCHAR       DriverVersionZ;
61     UINT        DriverBuildYear;
62     UINT        DriverBuildMonth;
63     UINT        DriverBuildDay;
64 } RT_VERSION_INFO, *PRT_VERSION_INFO;
65
66 struct iw_priv_args privtab[] = {
67 { RTPRIV_IOCTL_SET,
68   IW_PRIV_TYPE_CHAR | 1024, 0,
69   "set"},
70
71 { RTPRIV_IOCTL_SHOW, 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK,
72   ""},
73 { RTPRIV_IOCTL_SHOW, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK,
74   ""},
75 /* --- sub-ioctls definitions --- */
76     { SHOW_CONN_STATUS,
77           0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "connStatus" },
78         { SHOW_DRVIER_VERION,
79           0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "driverVer" },
80     { SHOW_BA_INFO,
81           0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "bainfo" },
82         { SHOW_DESC_INFO,
83           0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "descinfo" },
84     { RAIO_OFF,
85           0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "radio_off" },
86         { RAIO_ON,
87           0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "radio_on" },
88         { SHOW_CFG_VALUE,
89           IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "show" },
90         { SHOW_ADHOC_ENTRY_INFO,
91           0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "adhocEntry" },
92
93 /* --- sub-ioctls relations --- */
94
95 #ifdef DBG
96 { RTPRIV_IOCTL_BBP,
97   IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK,
98   "bbp"},
99 { RTPRIV_IOCTL_MAC,
100   IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | 1024,
101   "mac"},
102 { RTPRIV_IOCTL_E2P,
103   IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | 1024,
104   "e2p"},
105 #endif  /* DBG */
106
107 { RTPRIV_IOCTL_STATISTICS,
108   0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK,
109   "stat"},
110 { RTPRIV_IOCTL_GSITESURVEY,
111   0, IW_PRIV_TYPE_CHAR | 1024,
112   "get_site_survey"},
113 };
114
115 INT Set_SSID_Proc(
116     IN  PRTMP_ADAPTER   pAdapter,
117     IN  PUCHAR          arg);
118
119 #ifdef WMM_SUPPORT
120 INT     Set_WmmCapable_Proc(
121         IN      PRTMP_ADAPTER   pAd,
122         IN      PUCHAR                  arg);
123 #endif
124
125 INT Set_NetworkType_Proc(
126     IN  PRTMP_ADAPTER   pAdapter,
127     IN  PUCHAR          arg);
128
129 INT Set_AuthMode_Proc(
130     IN  PRTMP_ADAPTER   pAdapter,
131     IN  PUCHAR          arg);
132
133 INT Set_EncrypType_Proc(
134     IN  PRTMP_ADAPTER   pAdapter,
135     IN  PUCHAR          arg);
136
137 INT Set_DefaultKeyID_Proc(
138     IN  PRTMP_ADAPTER   pAdapter,
139     IN  PUCHAR          arg);
140
141 INT Set_Key1_Proc(
142     IN  PRTMP_ADAPTER   pAdapter,
143     IN  PUCHAR          arg);
144
145 INT Set_Key2_Proc(
146     IN  PRTMP_ADAPTER   pAdapter,
147     IN  PUCHAR          arg);
148
149 INT Set_Key3_Proc(
150     IN  PRTMP_ADAPTER   pAdapter,
151     IN  PUCHAR          arg);
152
153 INT Set_Key4_Proc(
154     IN  PRTMP_ADAPTER   pAdapter,
155     IN  PUCHAR          arg);
156
157 INT Set_WPAPSK_Proc(
158     IN  PRTMP_ADAPTER   pAdapter,
159     IN  PUCHAR          arg);
160
161
162 INT Set_PSMode_Proc(
163     IN  PRTMP_ADAPTER   pAdapter,
164     IN  PUCHAR          arg);
165
166 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         (iw_handler) rt_ioctl_setparam, /* + 0x02 */
3016 #ifdef DBG
3017         (iw_handler) rt_private_ioctl_bbp, /* + 0x03 */
3018 #else
3019         (iw_handler) NULL, /* + 0x03 */
3020 #endif
3021         (iw_handler) NULL, /* + 0x04 */
3022         (iw_handler) NULL, /* + 0x05 */
3023         (iw_handler) NULL, /* + 0x06 */
3024         (iw_handler) NULL, /* + 0x07 */
3025         (iw_handler) NULL, /* + 0x08 */
3026         (iw_handler) rt_private_get_statistics, /* + 0x09 */
3027         (iw_handler) NULL, /* + 0x0A */
3028         (iw_handler) NULL, /* + 0x0B */
3029         (iw_handler) NULL, /* + 0x0C */
3030         (iw_handler) NULL, /* + 0x0D */
3031         (iw_handler) NULL, /* + 0x0E */
3032         (iw_handler) NULL, /* + 0x0F */
3033         (iw_handler) NULL, /* + 0x10 */
3034         (iw_handler) rt_private_show, /* + 0x11 */
3035     (iw_handler) NULL, /* + 0x12 */
3036         (iw_handler) NULL, /* + 0x13 */
3037         (iw_handler) NULL, /* + 0x15 */
3038         (iw_handler) NULL, /* + 0x17 */
3039         (iw_handler) NULL, /* + 0x18 */
3040 };
3041
3042 const struct iw_handler_def rt28xx_iw_handler_def =
3043 {
3044 #define N(a)    (sizeof (a) / sizeof (a[0]))
3045         .standard       = (iw_handler *) rt_handler,
3046         .num_standard   = sizeof(rt_handler) / sizeof(iw_handler),
3047         .private        = (iw_handler *) rt_priv_handlers,
3048         .num_private            = N(rt_priv_handlers),
3049         .private_args   = (struct iw_priv_args *) privtab,
3050         .num_private_args       = N(privtab),
3051 #if IW_HANDLER_VERSION >= 7
3052     .get_wireless_stats = rt28xx_get_wireless_stats,
3053 #endif
3054 };
3055
3056 INT RTMPSetInformation(
3057     IN  PRTMP_ADAPTER pAdapter,
3058     IN  OUT struct ifreq    *rq,
3059     IN  INT                 cmd)
3060 {
3061     struct iwreq                        *wrq = (struct iwreq *) rq;
3062     NDIS_802_11_SSID                    Ssid;
3063     NDIS_802_11_MAC_ADDRESS             Bssid;
3064     RT_802_11_PHY_MODE                  PhyMode;
3065     RT_802_11_STA_CONFIG                StaConfig;
3066     NDIS_802_11_RATES                   aryRates;
3067     RT_802_11_PREAMBLE                  Preamble;
3068     NDIS_802_11_WEP_STATUS              WepStatus;
3069     NDIS_802_11_AUTHENTICATION_MODE     AuthMode = Ndis802_11AuthModeMax;
3070     NDIS_802_11_NETWORK_INFRASTRUCTURE  BssType;
3071     NDIS_802_11_RTS_THRESHOLD           RtsThresh;
3072     NDIS_802_11_FRAGMENTATION_THRESHOLD FragThresh;
3073     NDIS_802_11_POWER_MODE              PowerMode;
3074     PNDIS_802_11_KEY                    pKey = NULL;
3075     PNDIS_802_11_WEP                            pWepKey =NULL;
3076     PNDIS_802_11_REMOVE_KEY             pRemoveKey = NULL;
3077     NDIS_802_11_CONFIGURATION           Config, *pConfig = NULL;
3078     NDIS_802_11_NETWORK_TYPE            NetType;
3079     ULONG                               Now;
3080     UINT                                KeyIdx = 0;
3081     INT                                 Status = NDIS_STATUS_SUCCESS, MaxPhyMode = PHY_11G;
3082     ULONG                               PowerTemp;
3083     BOOLEAN                             RadioState;
3084     BOOLEAN                             StateMachineTouched = FALSE;
3085         OID_SET_HT_PHYMODE                                      HT_PhyMode;     //11n ,kathy
3086     PNDIS_802_11_PMKID                  pPmkId = NULL;
3087     BOOLEAN                                             IEEE8021xState = FALSE;
3088     BOOLEAN                                             IEEE8021x_required_keys = FALSE;
3089     UCHAR                               wpa_supplicant_enable = 0;
3090
3091         MaxPhyMode = PHY_11N_5G;
3092
3093         DBGPRINT(RT_DEBUG_TRACE, ("-->RTMPSetInformation(),     0x%08x\n", cmd&0x7FFF));
3094     switch(cmd & 0x7FFF) {
3095         case RT_OID_802_11_COUNTRY_REGION:
3096             if (wrq->u.data.length < sizeof(UCHAR))
3097                 Status = -EINVAL;
3098                         // Only avaliable when EEPROM not programming
3099             else if (!(pAdapter->CommonCfg.CountryRegion & 0x80) && !(pAdapter->CommonCfg.CountryRegionForABand & 0x80))
3100             {
3101                 ULONG   Country;
3102                 UCHAR   TmpPhy;
3103
3104                                 Status = copy_from_user(&Country, wrq->u.data.pointer, wrq->u.data.length);
3105                                 pAdapter->CommonCfg.CountryRegion = (UCHAR)(Country & 0x000000FF);
3106                                 pAdapter->CommonCfg.CountryRegionForABand = (UCHAR)((Country >> 8) & 0x000000FF);
3107                 TmpPhy = pAdapter->CommonCfg.PhyMode;
3108                                 pAdapter->CommonCfg.PhyMode = 0xff;
3109                                 // Build all corresponding channel information
3110                                 RTMPSetPhyMode(pAdapter, TmpPhy);
3111                                 SetCommonHT(pAdapter);
3112                                 DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_COUNTRY_REGION (A:%d  B/G:%d)\n", pAdapter->CommonCfg.CountryRegionForABand,
3113                                     pAdapter->CommonCfg.CountryRegion));
3114             }
3115             break;
3116         case OID_802_11_BSSID_LIST_SCAN:
3117             Now = jiffies;
3118                         DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_BSSID_LIST_SCAN, TxCnt = %d \n", pAdapter->RalinkCounters.LastOneSecTotalTxCount));
3119
3120             if (MONITOR_ON(pAdapter))
3121             {
3122                 DBGPRINT(RT_DEBUG_TRACE, ("!!! Driver is in Monitor Mode now !!!\n"));
3123                 break;
3124             }
3125
3126                         //Benson add 20080527, when radio off, sta don't need to scan
3127                         if (RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_RADIO_OFF))
3128                                 break;
3129
3130                         if (RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
3131                         {
3132                 DBGPRINT(RT_DEBUG_TRACE, ("!!! Driver is scanning now !!!\n"));
3133                                 pAdapter->StaCfg.bScanReqIsFromWebUI = TRUE;
3134                                 Status = NDIS_STATUS_SUCCESS;
3135                 break;
3136             }
3137
3138                         if (pAdapter->RalinkCounters.LastOneSecTotalTxCount > 100)
3139             {
3140                 DBGPRINT(RT_DEBUG_TRACE, ("!!! Link UP, ignore this set::OID_802_11_BSSID_LIST_SCAN\n"));
3141                                 Status = NDIS_STATUS_SUCCESS;
3142                                 pAdapter->StaCfg.ScanCnt = 99;          // Prevent auto scan triggered by this OID
3143                                 break;
3144             }
3145
3146             if ((OPSTATUS_TEST_FLAG(pAdapter, fOP_STATUS_MEDIA_STATE_CONNECTED)) &&
3147                                 ((pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPA) ||
3148                                 (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
3149                                 (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) ||
3150                                 (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)) &&
3151                 (pAdapter->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED))
3152             {
3153                 DBGPRINT(RT_DEBUG_TRACE, ("!!! Link UP, Port Not Secured! ignore this set::OID_802_11_BSSID_LIST_SCAN\n"));
3154                                 Status = NDIS_STATUS_SUCCESS;
3155                                 pAdapter->StaCfg.ScanCnt = 99;          // Prevent auto scan triggered by this OID
3156                                 break;
3157             }
3158
3159
3160             if (pAdapter->Mlme.CntlMachine.CurrState != CNTL_IDLE)
3161             {
3162                 RT28XX_MLME_RESET_STATE_MACHINE(pAdapter);
3163                 DBGPRINT(RT_DEBUG_TRACE, ("!!! MLME busy, reset MLME state machine !!!\n"));
3164             }
3165
3166             // tell CNTL state machine to call NdisMSetInformationComplete() after completing
3167             // this request, because this request is initiated by NDIS.
3168             pAdapter->MlmeAux.CurrReqIsFromNdis = FALSE;
3169             // Reset allowed scan retries
3170             pAdapter->StaCfg.ScanCnt = 0;
3171             pAdapter->StaCfg.LastScanTime = Now;
3172
3173                         pAdapter->StaCfg.bScanReqIsFromWebUI = TRUE;
3174             RTMP_SET_FLAG(pAdapter, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
3175             MlmeEnqueue(pAdapter,
3176                         MLME_CNTL_STATE_MACHINE,
3177                         OID_802_11_BSSID_LIST_SCAN,
3178                         0,
3179                         NULL);
3180
3181             Status = NDIS_STATUS_SUCCESS;
3182             StateMachineTouched = TRUE;
3183             break;
3184         case OID_802_11_SSID:
3185             if (wrq->u.data.length != sizeof(NDIS_802_11_SSID))
3186                 Status = -EINVAL;
3187             else
3188             {
3189                 PCHAR pSsidString = NULL;
3190                 Status = copy_from_user(&Ssid, wrq->u.data.pointer, wrq->u.data.length);
3191
3192                                 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_SSID (Len=%d,Ssid=%s)\n", Ssid.SsidLength, Ssid.Ssid));
3193                 if (Ssid.SsidLength > MAX_LEN_OF_SSID)
3194                     Status = -EINVAL;
3195                 else
3196                 {
3197                         if (Ssid.SsidLength == 0)
3198                         {
3199                                 Set_SSID_Proc(pAdapter, "");
3200                         }
3201                                         else
3202                         {
3203                                 pSsidString = (CHAR *) kmalloc(MAX_LEN_OF_SSID+1, MEM_ALLOC_FLAG);
3204                                                 if (pSsidString)
3205                                                 {
3206                                                         NdisZeroMemory(pSsidString, MAX_LEN_OF_SSID+1);
3207                                                         NdisMoveMemory(pSsidString, Ssid.Ssid, Ssid.SsidLength);
3208                                         Set_SSID_Proc(pAdapter, pSsidString);
3209                                                         kfree(pSsidString);
3210                                                 }
3211                                                 else
3212                                                         Status = -ENOMEM;
3213                         }
3214                 }
3215             }
3216             break;
3217         case OID_802_11_BSSID:
3218             if (wrq->u.data.length != sizeof(NDIS_802_11_MAC_ADDRESS))
3219                 Status  = -EINVAL;
3220             else
3221             {
3222                 Status = copy_from_user(&Bssid, wrq->u.data.pointer, wrq->u.data.length);
3223
3224                 // tell CNTL state machine to call NdisMSetInformationComplete() after completing
3225                 // this request, because this request is initiated by NDIS.
3226                 pAdapter->MlmeAux.CurrReqIsFromNdis = FALSE;
3227
3228                                 // Prevent to connect AP again in STAMlmePeriodicExec
3229                                 pAdapter->MlmeAux.AutoReconnectSsidLen= 32;
3230
3231                 // Reset allowed scan retries
3232                                 pAdapter->StaCfg.ScanCnt = 0;
3233
3234                 if (pAdapter->Mlme.CntlMachine.CurrState != CNTL_IDLE)
3235                 {
3236                     RT28XX_MLME_RESET_STATE_MACHINE(pAdapter);
3237                     DBGPRINT(RT_DEBUG_TRACE, ("!!! MLME busy, reset MLME state machine !!!\n"));
3238                 }
3239                 MlmeEnqueue(pAdapter,
3240                             MLME_CNTL_STATE_MACHINE,
3241                             OID_802_11_BSSID,
3242                             sizeof(NDIS_802_11_MAC_ADDRESS),
3243                             (VOID *)&Bssid);
3244                 Status = NDIS_STATUS_SUCCESS;
3245                 StateMachineTouched = TRUE;
3246
3247                 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_BSSID %02x:%02x:%02x:%02x:%02x:%02x\n",
3248                                         Bssid[0], Bssid[1], Bssid[2], Bssid[3], Bssid[4], Bssid[5]));
3249             }
3250             break;
3251         case RT_OID_802_11_RADIO:
3252             if (wrq->u.data.length != sizeof(BOOLEAN))
3253                 Status  = -EINVAL;
3254             else
3255             {
3256                 Status = copy_from_user(&RadioState, wrq->u.data.pointer, wrq->u.data.length);
3257                 DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_RADIO (=%d)\n", RadioState));
3258                 if (pAdapter->StaCfg.bSwRadio != RadioState)
3259                 {
3260                     pAdapter->StaCfg.bSwRadio = RadioState;
3261                     if (pAdapter->StaCfg.bRadio != (pAdapter->StaCfg.bHwRadio && pAdapter->StaCfg.bSwRadio))
3262                     {
3263                         pAdapter->StaCfg.bRadio = (pAdapter->StaCfg.bHwRadio && pAdapter->StaCfg.bSwRadio);
3264                         if (pAdapter->StaCfg.bRadio == TRUE)
3265                         {
3266                             MlmeRadioOn(pAdapter);
3267                             // Update extra information
3268                                                         pAdapter->ExtraInfo = EXTRA_INFO_CLEAR;
3269                         }
3270                         else
3271                         {
3272                             MlmeRadioOff(pAdapter);
3273                             // Update extra information
3274                                                         pAdapter->ExtraInfo = SW_RADIO_OFF;
3275                         }
3276                     }
3277                 }
3278             }
3279             break;
3280         case RT_OID_802_11_PHY_MODE:
3281             if (wrq->u.data.length != sizeof(RT_802_11_PHY_MODE))
3282                 Status  = -EINVAL;
3283             else
3284             {
3285                 Status = copy_from_user(&PhyMode, wrq->u.data.pointer, wrq->u.data.length);
3286                                 if (PhyMode <= MaxPhyMode)
3287                                 {
3288                         RTMPSetPhyMode(pAdapter, PhyMode);
3289                                         SetCommonHT(pAdapter);
3290                                 }
3291                 DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_PHY_MODE (=%d)\n", PhyMode));
3292             }
3293             break;
3294         case RT_OID_802_11_STA_CONFIG:
3295             if (wrq->u.data.length != sizeof(RT_802_11_STA_CONFIG))
3296                 Status  = -EINVAL;
3297             else
3298             {
3299                 Status = copy_from_user(&StaConfig, wrq->u.data.pointer, wrq->u.data.length);
3300                 pAdapter->CommonCfg.bEnableTxBurst = StaConfig.EnableTxBurst;
3301                 pAdapter->CommonCfg.UseBGProtection = StaConfig.UseBGProtection;
3302                 pAdapter->CommonCfg.bUseShortSlotTime = 1; // 2003-10-30 always SHORT SLOT capable
3303                 if ((pAdapter->CommonCfg.PhyMode != StaConfig.AdhocMode) &&
3304                                         (StaConfig.AdhocMode <= MaxPhyMode))
3305                 {
3306                     // allow dynamic change of "USE OFDM rate or not" in ADHOC mode
3307                     // if setting changed, need to reset current TX rate as well as BEACON frame format
3308                     if (pAdapter->StaCfg.BssType == BSS_ADHOC)
3309                     {
3310                                                 pAdapter->CommonCfg.PhyMode = StaConfig.AdhocMode;
3311                         RTMPSetPhyMode(pAdapter, PhyMode);
3312                         MlmeUpdateTxRates(pAdapter, FALSE, 0);
3313                         MakeIbssBeacon(pAdapter);           // re-build BEACON frame
3314                         AsicEnableIbssSync(pAdapter);   // copy to on-chip memory
3315                     }
3316                 }
3317                 DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_SET_STA_CONFIG (Burst=%d, Protection=%ld,ShortSlot=%d\n",
3318                                         pAdapter->CommonCfg.bEnableTxBurst,
3319                                         pAdapter->CommonCfg.UseBGProtection,
3320                                         pAdapter->CommonCfg.bUseShortSlotTime));
3321             }
3322             break;
3323         case OID_802_11_DESIRED_RATES:
3324             if (wrq->u.data.length != sizeof(NDIS_802_11_RATES))
3325                 Status  = -EINVAL;
3326             else
3327             {
3328                 Status = copy_from_user(&aryRates, wrq->u.data.pointer, wrq->u.data.length);
3329                 NdisZeroMemory(pAdapter->CommonCfg.DesireRate, MAX_LEN_OF_SUPPORTED_RATES);
3330                 NdisMoveMemory(pAdapter->CommonCfg.DesireRate, &aryRates, sizeof(NDIS_802_11_RATES));
3331                 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_DESIRED_RATES (%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x)\n",
3332                     pAdapter->CommonCfg.DesireRate[0],pAdapter->CommonCfg.DesireRate[1],
3333                     pAdapter->CommonCfg.DesireRate[2],pAdapter->CommonCfg.DesireRate[3],
3334                     pAdapter->CommonCfg.DesireRate[4],pAdapter->CommonCfg.DesireRate[5],
3335                     pAdapter->CommonCfg.DesireRate[6],pAdapter->CommonCfg.DesireRate[7] ));
3336                 // Changing DesiredRate may affect the MAX TX rate we used to TX frames out
3337                 MlmeUpdateTxRates(pAdapter, FALSE, 0);
3338             }
3339             break;
3340         case RT_OID_802_11_PREAMBLE:
3341             if (wrq->u.data.length != sizeof(RT_802_11_PREAMBLE))
3342                 Status  = -EINVAL;
3343             else
3344             {
3345                 Status = copy_from_user(&Preamble, wrq->u.data.pointer, wrq->u.data.length);
3346                 if (Preamble == Rt802_11PreambleShort)
3347                 {
3348                     pAdapter->CommonCfg.TxPreamble = Preamble;
3349                     MlmeSetTxPreamble(pAdapter, Rt802_11PreambleShort);
3350                 }
3351                 else if ((Preamble == Rt802_11PreambleLong) || (Preamble == Rt802_11PreambleAuto))
3352                 {
3353                     // if user wants AUTO, initialize to LONG here, then change according to AP's
3354                     // capability upon association.
3355                     pAdapter->CommonCfg.TxPreamble = Preamble;
3356                     MlmeSetTxPreamble(pAdapter, Rt802_11PreambleLong);
3357                 }
3358                 else
3359                 {
3360                     Status = -EINVAL;
3361                     break;
3362                 }
3363                 DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_PREAMBLE (=%d)\n", Preamble));
3364             }
3365             break;
3366         case OID_802_11_WEP_STATUS:
3367             if (wrq->u.data.length != sizeof(NDIS_802_11_WEP_STATUS))
3368                 Status  = -EINVAL;
3369             else
3370             {
3371                 Status = copy_from_user(&WepStatus, wrq->u.data.pointer, wrq->u.data.length);
3372                 // Since TKIP, AES, WEP are all supported. It should not have any invalid setting
3373                 if (WepStatus <= Ndis802_11Encryption3KeyAbsent)
3374                 {
3375                     if (pAdapter->StaCfg.WepStatus != WepStatus)
3376                     {
3377                         // Config has changed
3378                         pAdapter->bConfigChanged = TRUE;
3379                     }
3380                     pAdapter->StaCfg.WepStatus     = WepStatus;
3381                     pAdapter->StaCfg.OrigWepStatus = WepStatus;
3382                     pAdapter->StaCfg.PairCipher    = WepStatus;
3383                         pAdapter->StaCfg.GroupCipher   = WepStatus;
3384                 }
3385                 else
3386                 {
3387                     Status  = -EINVAL;
3388                     break;
3389                 }
3390                 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_WEP_STATUS (=%d)\n",WepStatus));
3391             }
3392             break;
3393         case OID_802_11_AUTHENTICATION_MODE:
3394             if (wrq->u.data.length != sizeof(NDIS_802_11_AUTHENTICATION_MODE))
3395                 Status  = -EINVAL;
3396             else
3397             {
3398                 Status = copy_from_user(&AuthMode, wrq->u.data.pointer, wrq->u.data.length);
3399                 if (AuthMode > Ndis802_11AuthModeMax)
3400                 {
3401                     Status  = -EINVAL;
3402                     break;
3403                 }
3404                 else
3405                 {
3406                     if (pAdapter->StaCfg.AuthMode != AuthMode)
3407                     {
3408                         // Config has changed
3409                         pAdapter->bConfigChanged = TRUE;
3410                     }
3411                     pAdapter->StaCfg.AuthMode = AuthMode;
3412                 }
3413                 pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
3414                 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_AUTHENTICATION_MODE (=%d) \n",pAdapter->StaCfg.AuthMode));
3415             }
3416             break;
3417         case OID_802_11_INFRASTRUCTURE_MODE:
3418             if (wrq->u.data.length != sizeof(NDIS_802_11_NETWORK_INFRASTRUCTURE))
3419                 Status  = -EINVAL;
3420             else
3421             {
3422                 Status = copy_from_user(&BssType, wrq->u.data.pointer, wrq->u.data.length);
3423
3424                                 if (BssType == Ndis802_11IBSS)
3425                                         Set_NetworkType_Proc(pAdapter, "Adhoc");
3426                                 else if (BssType == Ndis802_11Infrastructure)
3427                                         Set_NetworkType_Proc(pAdapter, "Infra");
3428                                 else if (BssType == Ndis802_11Monitor)
3429                                         Set_NetworkType_Proc(pAdapter, "Monitor");
3430                                 else
3431                                 {
3432                                         Status  = -EINVAL;
3433                                         DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_INFRASTRUCTURE_MODE (unknown)\n"));
3434                                 }
3435                         }
3436                         break;
3437          case OID_802_11_REMOVE_WEP:
3438             DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_REMOVE_WEP\n"));
3439             if (wrq->u.data.length != sizeof(NDIS_802_11_KEY_INDEX))
3440             {
3441                                 Status = -EINVAL;
3442             }
3443             else
3444             {
3445                                 KeyIdx = *(NDIS_802_11_KEY_INDEX *) wrq->u.data.pointer;
3446
3447                                 if (KeyIdx & 0x80000000)
3448                                 {
3449                                         // Should never set default bit when remove key
3450                                         Status = -EINVAL;
3451                                 }
3452                                 else
3453                                 {
3454                                         KeyIdx = KeyIdx & 0x0fffffff;
3455                                         if (KeyIdx >= 4){
3456                                                 Status = -EINVAL;
3457                                         }
3458                                         else
3459                                         {
3460                                                 pAdapter->SharedKey[BSS0][KeyIdx].KeyLen = 0;
3461                                                 pAdapter->SharedKey[BSS0][KeyIdx].CipherAlg = CIPHER_NONE;
3462                                                 AsicRemoveSharedKeyEntry(pAdapter, 0, (UCHAR)KeyIdx);
3463                                         }
3464                                 }
3465             }
3466             break;
3467         case RT_OID_802_11_RESET_COUNTERS:
3468             NdisZeroMemory(&pAdapter->WlanCounters, sizeof(COUNTER_802_11));
3469             NdisZeroMemory(&pAdapter->Counters8023, sizeof(COUNTER_802_3));
3470             NdisZeroMemory(&pAdapter->RalinkCounters, sizeof(COUNTER_RALINK));
3471             pAdapter->Counters8023.RxNoBuffer   = 0;
3472                         pAdapter->Counters8023.GoodReceives = 0;
3473                         pAdapter->Counters8023.RxNoBuffer   = 0;
3474 #ifdef RT2870
3475                         pAdapter->BulkOutComplete       = 0;
3476                         pAdapter->BulkOutCompleteOther= 0;
3477                         pAdapter->BulkOutCompleteCancel = 0;
3478                         pAdapter->BulkOutReq = 0;
3479                         pAdapter->BulkInReq= 0;
3480                         pAdapter->BulkInComplete = 0;
3481                         pAdapter->BulkInCompleteFail = 0;
3482 #endif // RT2870 //
3483             DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_RESET_COUNTERS \n"));
3484             break;
3485         case OID_802_11_RTS_THRESHOLD:
3486             if (wrq->u.data.length != sizeof(NDIS_802_11_RTS_THRESHOLD))
3487                 Status  = -EINVAL;
3488             else
3489             {
3490                 Status = copy_from_user(&RtsThresh, wrq->u.data.pointer, wrq->u.data.length);
3491                 if (RtsThresh > MAX_RTS_THRESHOLD)
3492                     Status  = -EINVAL;
3493                 else
3494                     pAdapter->CommonCfg.RtsThreshold = (USHORT)RtsThresh;
3495             }
3496             DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_RTS_THRESHOLD (=%ld)\n",RtsThresh));
3497             break;
3498         case OID_802_11_FRAGMENTATION_THRESHOLD:
3499             if (wrq->u.data.length != sizeof(NDIS_802_11_FRAGMENTATION_THRESHOLD))
3500                 Status  = -EINVAL;
3501             else
3502             {
3503                 Status = copy_from_user(&FragThresh, wrq->u.data.pointer, wrq->u.data.length);
3504                 pAdapter->CommonCfg.bUseZeroToDisableFragment = FALSE;
3505                 if (FragThresh > MAX_FRAG_THRESHOLD || FragThresh < MIN_FRAG_THRESHOLD)
3506                 {
3507                     if (FragThresh == 0)
3508                     {
3509                         pAdapter->CommonCfg.FragmentThreshold = MAX_FRAG_THRESHOLD;
3510                         pAdapter->CommonCfg.bUseZeroToDisableFragment = TRUE;
3511                     }
3512                     else
3513                         Status  = -EINVAL;
3514                 }
3515                 else
3516                     pAdapter->CommonCfg.FragmentThreshold = (USHORT)FragThresh;
3517             }
3518             DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_FRAGMENTATION_THRESHOLD (=%ld) \n",FragThresh));
3519             break;
3520         case OID_802_11_POWER_MODE:
3521             if (wrq->u.data.length != sizeof(NDIS_802_11_POWER_MODE))
3522                 Status = -EINVAL;
3523             else
3524             {
3525                 Status = copy_from_user(&PowerMode, wrq->u.data.pointer, wrq->u.data.length);
3526                 if (PowerMode == Ndis802_11PowerModeCAM)
3527                         Set_PSMode_Proc(pAdapter, "CAM");
3528                 else if (PowerMode == Ndis802_11PowerModeMAX_PSP)
3529                         Set_PSMode_Proc(pAdapter, "Max_PSP");
3530                 else if (PowerMode == Ndis802_11PowerModeFast_PSP)
3531                                         Set_PSMode_Proc(pAdapter, "Fast_PSP");
3532                 else if (PowerMode == Ndis802_11PowerModeLegacy_PSP)
3533                                         Set_PSMode_Proc(pAdapter, "Legacy_PSP");
3534                 else
3535                     Status = -EINVAL;
3536             }
3537             DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_POWER_MODE (=%d)\n",PowerMode));
3538             break;
3539          case RT_OID_802_11_TX_POWER_LEVEL_1:
3540                         if (wrq->u.data.length  < sizeof(ULONG))
3541                                 Status = -EINVAL;
3542                         else
3543                         {
3544                                 Status = copy_from_user(&PowerTemp, wrq->u.data.pointer, wrq->u.data.length);
3545                                 if (PowerTemp > 100)
3546                                         PowerTemp = 0xffffffff;  // AUTO
3547                                 pAdapter->CommonCfg.TxPowerDefault = PowerTemp; //keep current setting.
3548                                         pAdapter->CommonCfg.TxPowerPercentage = pAdapter->CommonCfg.TxPowerDefault;
3549                 DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_TX_POWER_LEVEL_1 (=%ld)\n", pAdapter->CommonCfg.TxPowerPercentage));
3550                         }
3551                 break;
3552                 case OID_802_11_NETWORK_TYPE_IN_USE:
3553                         if (wrq->u.data.length != sizeof(NDIS_802_11_NETWORK_TYPE))
3554                                 Status = -EINVAL;
3555                         else
3556                         {
3557                                 Status = copy_from_user(&NetType, wrq->u.data.pointer, wrq->u.data.length);
3558
3559                                 if (NetType == Ndis802_11DS)
3560                                         RTMPSetPhyMode(pAdapter, PHY_11B);
3561                                 else if (NetType == Ndis802_11OFDM24)
3562                                         RTMPSetPhyMode(pAdapter, PHY_11BG_MIXED);
3563                                 else if (NetType == Ndis802_11OFDM5)
3564                                         RTMPSetPhyMode(pAdapter, PHY_11A);
3565                                 else
3566                                         Status = -EINVAL;
3567
3568                                 if (Status == NDIS_STATUS_SUCCESS)
3569                                         SetCommonHT(pAdapter);
3570
3571                 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_NETWORK_TYPE_IN_USE (=%d)\n",NetType));
3572                     }
3573                         break;
3574         // For WPA PSK PMK key
3575         case RT_OID_802_11_ADD_WPA:
3576             pKey = kmalloc(wrq->u.data.length, MEM_ALLOC_FLAG);
3577             if(pKey == NULL)
3578             {
3579                 Status = -ENOMEM;
3580                 break;
3581             }
3582
3583             Status = copy_from_user(pKey, wrq->u.data.pointer, wrq->u.data.length);
3584             if (pKey->Length != wrq->u.data.length)
3585             {
3586                 Status  = -EINVAL;
3587                 DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_ADD_WPA, Failed!!\n"));
3588             }
3589             else
3590             {
3591                 if ((pAdapter->StaCfg.AuthMode != Ndis802_11AuthModeWPAPSK) &&
3592                                     (pAdapter->StaCfg.AuthMode != Ndis802_11AuthModeWPA2PSK) &&
3593                                     (pAdapter->StaCfg.AuthMode != Ndis802_11AuthModeWPANone) )
3594                 {
3595                     Status = -EOPNOTSUPP;
3596                     DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_ADD_WPA, Failed!! [AuthMode != WPAPSK/WPA2PSK/WPANONE]\n"));
3597                 }
3598                 else if ((pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
3599                                                  (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK) ||
3600                                                  (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPANone) )     // Only for WPA PSK mode
3601                                 {
3602                     NdisMoveMemory(pAdapter->StaCfg.PMK, &pKey->KeyMaterial, pKey->KeyLength);
3603                     // Use RaConfig as PSK agent.
3604                     // Start STA supplicant state machine
3605                     if (pAdapter->StaCfg.AuthMode != Ndis802_11AuthModeWPANone)
3606                         pAdapter->StaCfg.WpaState = SS_START;
3607
3608                     DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_ADD_WPA (id=0x%x, Len=%d-byte)\n", pKey->KeyIndex, pKey->KeyLength));
3609                 }
3610                 else
3611                 {
3612                     pAdapter->StaCfg.WpaState = SS_NOTUSE;
3613                     DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_ADD_WPA (id=0x%x, Len=%d-byte)\n", pKey->KeyIndex, pKey->KeyLength));
3614                 }
3615             }
3616             kfree(pKey);
3617             break;
3618         case OID_802_11_REMOVE_KEY:
3619             pRemoveKey = kmalloc(wrq->u.data.length, MEM_ALLOC_FLAG);
3620             if(pRemoveKey == NULL)
3621             {
3622                 Status = -ENOMEM;
3623                 break;
3624             }
3625
3626             Status = copy_from_user(pRemoveKey, wrq->u.data.pointer, wrq->u.data.length);
3627             if (pRemoveKey->Length != wrq->u.data.length)
3628             {
3629                 Status  = -EINVAL;
3630                 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_REMOVE_KEY, Failed!!\n"));
3631             }
3632             else
3633             {
3634                 if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
3635                 {
3636                     RTMPWPARemoveKeyProc(pAdapter, pRemoveKey);
3637                     DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_REMOVE_KEY, Remove WPA Key!!\n"));
3638                 }
3639                 else
3640                 {
3641                     KeyIdx = pRemoveKey->KeyIndex;
3642
3643                     if (KeyIdx & 0x80000000)
3644                     {
3645                         // Should never set default bit when remove key
3646                         Status  = -EINVAL;
3647                         DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_REMOVE_KEY, Failed!!(Should never set default bit when remove key)\n"));
3648                     }
3649                     else
3650                     {
3651                         KeyIdx = KeyIdx & 0x0fffffff;
3652                         if (KeyIdx > 3)
3653                         {
3654                             Status  = -EINVAL;
3655                             DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_REMOVE_KEY, Failed!!(KeyId[%d] out of range)\n", KeyIdx));
3656                         }
3657                         else
3658                         {
3659                             pAdapter->SharedKey[BSS0][KeyIdx].KeyLen = 0;
3660                             pAdapter->SharedKey[BSS0][KeyIdx].CipherAlg = CIPHER_NONE;
3661                             AsicRemoveSharedKeyEntry(pAdapter, 0, (UCHAR)KeyIdx);
3662                             DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_REMOVE_KEY (id=0x%x, Len=%d-byte)\n", pRemoveKey->KeyIndex, pRemoveKey->Length));
3663                         }
3664                     }
3665                 }
3666             }
3667             kfree(pRemoveKey);
3668             break;
3669         // New for WPA
3670         case OID_802_11_ADD_KEY:
3671             pKey = kmalloc(wrq->u.data.length, MEM_ALLOC_FLAG);
3672             if(pKey == NULL)
3673             {
3674                 Status = -ENOMEM;
3675                 break;
3676             }
3677             Status = copy_from_user(pKey, wrq->u.data.pointer, wrq->u.data.length);
3678             if (pKey->Length != wrq->u.data.length)
3679             {
3680                 Status  = -EINVAL;
3681                 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_ADD_KEY, Failed!!\n"));
3682             }
3683             else
3684             {
3685                 RTMPAddKey(pAdapter, pKey);
3686                 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_ADD_KEY (id=0x%x, Len=%d-byte)\n", pKey->KeyIndex, pKey->KeyLength));
3687             }
3688             kfree(pKey);
3689             break;
3690         case OID_802_11_CONFIGURATION:
3691             if (wrq->u.data.length != sizeof(NDIS_802_11_CONFIGURATION))
3692                 Status  = -EINVAL;
3693             else
3694             {
3695                 Status = copy_from_user(&Config, wrq->u.data.pointer, wrq->u.data.length);
3696                 pConfig = &Config;
3697
3698                 if ((pConfig->BeaconPeriod >= 20) && (pConfig->BeaconPeriod <=400))
3699                      pAdapter->CommonCfg.BeaconPeriod = (USHORT) pConfig->BeaconPeriod;
3700
3701                 pAdapter->StaActive.AtimWin = (USHORT) pConfig->ATIMWindow;
3702                 MAP_KHZ_TO_CHANNEL_ID(pConfig->DSConfig, pAdapter->CommonCfg.Channel);
3703                 //
3704                                 // Save the channel on MlmeAux for CntlOidRTBssidProc used.
3705                                 //
3706                                 pAdapter->MlmeAux.Channel = pAdapter->CommonCfg.Channel;
3707
3708                 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_CONFIGURATION (BeacnPeriod=%ld,AtimW=%ld,Ch=%d)\n",
3709                     pConfig->BeaconPeriod, pConfig->ATIMWindow, pAdapter->CommonCfg.Channel));
3710                 // Config has changed
3711                 pAdapter->bConfigChanged = TRUE;
3712             }
3713             break;
3714                 case RT_OID_802_11_SET_HT_PHYMODE:
3715                         if (wrq->u.data.length  != sizeof(OID_SET_HT_PHYMODE))
3716                                 Status = -EINVAL;
3717                         else
3718                         {
3719                             POID_SET_HT_PHYMODE pHTPhyMode = &HT_PhyMode;
3720
3721                                 Status = copy_from_user(&HT_PhyMode, wrq->u.data.pointer, wrq->u.data.length);
3722                                 DBGPRINT(RT_DEBUG_TRACE, ("Set::pHTPhyMode      (PhyMode = %d,TransmitNo = %d, HtMode = %d,     ExtOffset =     %d , MCS = %d, BW =     %d,     STBC = %d, SHORTGI = %d) \n",
3723                                 pHTPhyMode->PhyMode, pHTPhyMode->TransmitNo,pHTPhyMode->HtMode,pHTPhyMode->ExtOffset,
3724                                 pHTPhyMode->MCS, pHTPhyMode->BW, pHTPhyMode->STBC,      pHTPhyMode->SHORTGI));
3725                                 if (pAdapter->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
3726                                         RTMPSetHT(pAdapter,     pHTPhyMode);
3727                         }
3728                         DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_SET_HT_PHYMODE(MCS=%d,BW=%d,SGI=%d,STBC=%d)\n",
3729                                 pAdapter->StaCfg.HTPhyMode.field.MCS, pAdapter->StaCfg.HTPhyMode.field.BW, pAdapter->StaCfg.HTPhyMode.field.ShortGI,
3730                                 pAdapter->StaCfg.HTPhyMode.field.STBC));
3731                         break;
3732                 case RT_OID_802_11_SET_APSD_SETTING:
3733                         if (wrq->u.data.length != sizeof(ULONG))
3734                                 Status = -EINVAL;
3735                         else
3736                         {
3737                                 ULONG apsd ;
3738                                 Status = copy_from_user(&apsd, wrq->u.data.pointer,     wrq->u.data.length);
3739
3740                                 /*-------------------------------------------------------------------
3741                                 |B31~B7 |       B6~B5    |       B4      |       B3      |      B2       |      B1       |         B0           |
3742                                 ---------------------------------------------------------------------
3743                                 | Rsvd  | Max SP Len | AC_VO | AC_VI | AC_BK | AC_BE | APSD     Capable |
3744                                 ---------------------------------------------------------------------*/
3745                                 pAdapter->CommonCfg.bAPSDCapable = (apsd & 0x00000001) ? TRUE : FALSE;
3746                                 pAdapter->CommonCfg.bAPSDAC_BE = ((apsd & 0x00000002) >> 1)     ? TRUE : FALSE;
3747                                 pAdapter->CommonCfg.bAPSDAC_BK = ((apsd & 0x00000004) >> 2)     ? TRUE : FALSE;
3748                                 pAdapter->CommonCfg.bAPSDAC_VI = ((apsd & 0x00000008) >> 3)     ? TRUE : FALSE;
3749                                 pAdapter->CommonCfg.bAPSDAC_VO = ((apsd & 0x00000010) >> 4)     ? TRUE : FALSE;
3750                                 pAdapter->CommonCfg.MaxSPLength = (UCHAR)((apsd & 0x00000060) >> 5);
3751
3752                                 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,
3753                                         pAdapter->CommonCfg.bAPSDAC_BE, pAdapter->CommonCfg.bAPSDAC_BK, pAdapter->CommonCfg.bAPSDAC_VI, pAdapter->CommonCfg.bAPSDAC_VO, pAdapter->CommonCfg.MaxSPLength));
3754                         }
3755                         break;
3756
3757                 case RT_OID_802_11_SET_APSD_PSM:
3758                         if (wrq->u.data.length  != sizeof(ULONG))
3759                                 Status = -EINVAL;
3760                         else
3761                         {
3762                                 // Driver needs to notify AP when PSM changes
3763                                 Status = copy_from_user(&pAdapter->CommonCfg.bAPSDForcePowerSave, wrq->u.data.pointer, wrq->u.data.length);
3764                                 if (pAdapter->CommonCfg.bAPSDForcePowerSave     != pAdapter->StaCfg.Psm)
3765                                 {
3766                                         MlmeSetPsmBit(pAdapter, pAdapter->CommonCfg.bAPSDForcePowerSave);
3767                                         RTMPSendNullFrame(pAdapter,     pAdapter->CommonCfg.TxRate,     TRUE);
3768                                 }
3769                                 DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_SET_APSD_PSM (bAPSDForcePowerSave:%d)\n", pAdapter->CommonCfg.bAPSDForcePowerSave));
3770                         }
3771                         break;
3772
3773                 case RT_OID_802_11_SET_WMM:
3774                         if (wrq->u.data.length  != sizeof(BOOLEAN))
3775                                 Status = -EINVAL;
3776                         else
3777                         {
3778                                 Status = copy_from_user(&pAdapter->CommonCfg.bWmmCapable, wrq->u.data.pointer, wrq->u.data.length);
3779                                 DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_SET_WMM (=%d)     \n", pAdapter->CommonCfg.bWmmCapable));
3780                         }
3781                         break;
3782
3783                 case OID_802_11_DISASSOCIATE:
3784                         //
3785                         // Set NdisRadioStateOff to     TRUE, instead of called MlmeRadioOff.
3786                         // Later on, NDIS_802_11_BSSID_LIST_EX->NumberOfItems should be 0
3787                         // when query OID_802_11_BSSID_LIST.
3788                         //
3789                         // TRUE:  NumberOfItems will set to     0.
3790                         // FALSE: NumberOfItems no change.
3791                         //
3792                         pAdapter->CommonCfg.NdisRadioStateOff = TRUE;
3793                         // Set to immediately send the media disconnect event
3794                         pAdapter->MlmeAux.CurrReqIsFromNdis     = TRUE;
3795                         DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_DISASSOCIATE \n"));
3796
3797                         if (INFRA_ON(pAdapter))
3798                         {
3799                                 if (pAdapter->Mlme.CntlMachine.CurrState !=     CNTL_IDLE)
3800                                 {
3801                                         RT28XX_MLME_RESET_STATE_MACHINE(pAdapter);
3802                                         DBGPRINT(RT_DEBUG_TRACE, ("!!! MLME     busy, reset     MLME state machine !!!\n"));
3803                                 }
3804
3805                                 MlmeEnqueue(pAdapter,
3806                                         MLME_CNTL_STATE_MACHINE,
3807                                         OID_802_11_DISASSOCIATE,
3808                                         0,
3809                                         NULL);
3810
3811                                 StateMachineTouched     = TRUE;
3812                         }
3813                         break;
3814                 case RT_OID_802_11_SET_IMME_BA_CAP:
3815                                 if (wrq->u.data.length != sizeof(OID_BACAP_STRUC))
3816                                         Status = -EINVAL;
3817                                 else
3818                                 {
3819                                         OID_BACAP_STRUC Orde ;
3820                                         Status = copy_from_user(&Orde, wrq->u.data.pointer, wrq->u.data.length);
3821                                         if (Orde.Policy > BA_NOTUSE)
3822                                         {
3823                                                 Status = NDIS_STATUS_INVALID_DATA;
3824                                         }
3825                                         else if (Orde.Policy == BA_NOTUSE)
3826                                         {
3827                                                 pAdapter->CommonCfg.BACapability.field.Policy = BA_NOTUSE;
3828                                                 pAdapter->CommonCfg.BACapability.field.MpduDensity = Orde.MpduDensity;
3829                                                 pAdapter->CommonCfg.DesiredHtPhy.MpduDensity = Orde.MpduDensity;
3830                                                 pAdapter->CommonCfg.DesiredHtPhy.AmsduEnable = Orde.AmsduEnable;
3831                                                 pAdapter->CommonCfg.DesiredHtPhy.AmsduSize= Orde.AmsduSize;
3832                                                 pAdapter->CommonCfg.DesiredHtPhy.MimoPs= Orde.MMPSmode;
3833                                                 pAdapter->CommonCfg.BACapability.field.MMPSmode = Orde.MMPSmode;
3834                                                 // UPdata to HT IE
3835                                                 pAdapter->CommonCfg.HtCapability.HtCapInfo.MimoPs = Orde.MMPSmode;
3836                                                 pAdapter->CommonCfg.HtCapability.HtCapInfo.AMsduSize = Orde.AmsduSize;
3837                                                 pAdapter->CommonCfg.HtCapability.HtCapParm.MpduDensity = Orde.MpduDensity;
3838                                         }
3839                                         else
3840                                         {
3841                         pAdapter->CommonCfg.BACapability.field.AutoBA = Orde.AutoBA;
3842                                                 pAdapter->CommonCfg.BACapability.field.Policy = IMMED_BA; // we only support immediate BA.
3843                                                 pAdapter->CommonCfg.BACapability.field.MpduDensity = Orde.MpduDensity;
3844                                                 pAdapter->CommonCfg.DesiredHtPhy.MpduDensity = Orde.MpduDensity;
3845                                                 pAdapter->CommonCfg.DesiredHtPhy.AmsduEnable = Orde.AmsduEnable;
3846                                                 pAdapter->CommonCfg.DesiredHtPhy.AmsduSize= Orde.AmsduSize;
3847                                                 pAdapter->CommonCfg.DesiredHtPhy.MimoPs = Orde.MMPSmode;
3848                                                 pAdapter->CommonCfg.BACapability.field.MMPSmode = Orde.MMPSmode;
3849
3850                                                 // UPdata to HT IE
3851                                                 pAdapter->CommonCfg.HtCapability.HtCapInfo.MimoPs = Orde.MMPSmode;
3852                                                 pAdapter->CommonCfg.HtCapability.HtCapInfo.AMsduSize = Orde.AmsduSize;
3853                                                 pAdapter->CommonCfg.HtCapability.HtCapParm.MpduDensity = Orde.MpduDensity;
3854
3855                                                 if (pAdapter->CommonCfg.BACapability.field.RxBAWinLimit > MAX_RX_REORDERBUF)
3856                                                         pAdapter->CommonCfg.BACapability.field.RxBAWinLimit = MAX_RX_REORDERBUF;
3857
3858                                         }
3859
3860                                         pAdapter->CommonCfg.REGBACapability.word = pAdapter->CommonCfg.BACapability.word;
3861                                         DBGPRINT(RT_DEBUG_TRACE, ("Set::(Orde.AutoBA = %d) (Policy=%d)(ReBAWinLimit=%d)(TxBAWinLimit=%d)(AutoMode=%d)\n",Orde.AutoBA, pAdapter->CommonCfg.BACapability.field.Policy,
3862                                                 pAdapter->CommonCfg.BACapability.field.RxBAWinLimit,pAdapter->CommonCfg.BACapability.field.TxBAWinLimit, pAdapter->CommonCfg.BACapability.field.AutoBA));
3863                                         DBGPRINT(RT_DEBUG_TRACE, ("Set::(MimoPs = %d)(AmsduEnable = %d) (AmsduSize=%d)(MpduDensity=%d)\n",pAdapter->CommonCfg.DesiredHtPhy.MimoPs, pAdapter->CommonCfg.DesiredHtPhy.AmsduEnable,
3864                                                 pAdapter->CommonCfg.DesiredHtPhy.AmsduSize, pAdapter->CommonCfg.DesiredHtPhy.MpduDensity));
3865                                 }
3866
3867                                 break;
3868                 case RT_OID_802_11_ADD_IMME_BA:
3869                         DBGPRINT(RT_DEBUG_TRACE, (" Set :: RT_OID_802_11_ADD_IMME_BA \n"));
3870                         if (wrq->u.data.length != sizeof(OID_ADD_BA_ENTRY))
3871                                         Status = -EINVAL;
3872                         else
3873                         {
3874                                 UCHAR                   index;
3875                                 OID_ADD_BA_ENTRY    BA;
3876                                 MAC_TABLE_ENTRY     *pEntry;
3877
3878                                 Status = copy_from_user(&BA, wrq->u.data.pointer, wrq->u.data.length);
3879                                 if (BA.TID > 15)
3880                                 {
3881                                         Status = NDIS_STATUS_INVALID_DATA;
3882                                         break;
3883                                 }
3884                                 else
3885                                 {
3886                                         //BATableInsertEntry
3887                                         //As ad-hoc mode, BA pair is not limited to only BSSID. so add via OID.
3888                                         index = BA.TID;
3889                                         // in ad hoc mode, when adding BA pair, we should insert this entry into MACEntry too
3890                                         pEntry = MacTableLookup(pAdapter, BA.MACAddr);
3891                                         if (!pEntry)
3892                                         {
3893                                                 DBGPRINT(RT_DEBUG_TRACE, ("RT_OID_802_11_ADD_IMME_BA. break on no connection.----:%x:%x\n", BA.MACAddr[4], BA.MACAddr[5]));
3894                                                 break;
3895                                         }
3896                                         if (BA.IsRecipient == FALSE)
3897                                         {
3898                                             if (pEntry->bIAmBadAtheros == TRUE)
3899                                                         pAdapter->CommonCfg.BACapability.field.RxBAWinLimit = 0x10;
3900
3901                                                 BAOriSessionSetUp(pAdapter, pEntry, index, 0, 100, TRUE);
3902                                         }
3903                                         else
3904                                         {
3905                                                 //BATableInsertEntry(pAdapter, pEntry->Aid, BA.MACAddr, 0, 0xffff, BA.TID, BA.nMSDU, BA.IsRecipient);
3906                                         }
3907
3908                                         DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_ADD_IMME_BA. Rec = %d. Mac = %x:%x:%x:%x:%x:%x . \n",
3909                                                 BA.IsRecipient, BA.MACAddr[0], BA.MACAddr[1], BA.MACAddr[2], BA.MACAddr[2]
3910                                                 , BA.MACAddr[4], BA.MACAddr[5]));
3911                                 }
3912                         }
3913                         break;
3914
3915                 case RT_OID_802_11_TEAR_IMME_BA:
3916                         DBGPRINT(RT_DEBUG_TRACE, ("Set :: RT_OID_802_11_TEAR_IMME_BA \n"));
3917                         if (wrq->u.data.length != sizeof(OID_ADD_BA_ENTRY))
3918                                         Status = -EINVAL;
3919                         else
3920                         {
3921                                 POID_ADD_BA_ENTRY       pBA;
3922                                 MAC_TABLE_ENTRY *pEntry;
3923
3924                                 pBA = kmalloc(wrq->u.data.length, MEM_ALLOC_FLAG);
3925
3926                                 if (pBA == NULL)
3927                                 {
3928                                         DBGPRINT(RT_DEBUG_TRACE, ("Set :: RT_OID_802_11_TEAR_IMME_BA kmalloc() can't allocate enough memory\n"));
3929                                         Status = NDIS_STATUS_FAILURE;
3930                                 }
3931                                 else
3932                                 {
3933                                         Status = copy_from_user(pBA, wrq->u.data.pointer, wrq->u.data.length);
3934                                         DBGPRINT(RT_DEBUG_TRACE, ("Set :: RT_OID_802_11_TEAR_IMME_BA(TID=%d, bAllTid=%d)\n", pBA->TID, pBA->bAllTid));
3935
3936                                         if (!pBA->bAllTid && (pBA->TID > NUM_OF_TID))
3937                                         {
3938                                                 Status = NDIS_STATUS_INVALID_DATA;
3939                                                 break;
3940                                         }
3941
3942                                         if (pBA->IsRecipient == FALSE)
3943                                         {
3944                                                 pEntry = MacTableLookup(pAdapter, pBA->MACAddr);
3945                                                 DBGPRINT(RT_DEBUG_TRACE, (" pBA->IsRecipient == FALSE\n"));
3946                                                 if (pEntry)
3947                                                 {
3948                                                         DBGPRINT(RT_DEBUG_TRACE, (" pBA->pEntry\n"));
3949                                                         BAOriSessionTearDown(pAdapter, pEntry->Aid, pBA->TID, FALSE, TRUE);
3950                                                 }
3951                                                 else
3952                                                         DBGPRINT(RT_DEBUG_TRACE, ("Set :: Not found pEntry \n"));
3953                                         }
3954                                         else
3955                                         {
3956                                                 pEntry = MacTableLookup(pAdapter, pBA->MACAddr);
3957                                                 if (pEntry)
3958                                                 {
3959                                                         BARecSessionTearDown( pAdapter, (UCHAR)pEntry->Aid, pBA->TID, TRUE);
3960                                                 }
3961                                                 else
3962                                                         DBGPRINT(RT_DEBUG_TRACE, ("Set :: Not found pEntry \n"));
3963                                         }
3964                                         kfree(pBA);
3965                                 }
3966             }
3967             break;
3968         // For WPA_SUPPLICANT to set static wep key
3969         case OID_802_11_ADD_WEP:
3970             pWepKey = kmalloc(wrq->u.data.length, MEM_ALLOC_FLAG);
3971
3972             if(pWepKey == NULL)
3973             {
3974                 Status = -ENOMEM;
3975                                 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_ADD_WEP, Failed!!\n"));
3976                 break;
3977             }
3978             Status = copy_from_user(pWepKey, wrq->u.data.pointer, wrq->u.data.length);
3979             if (Status)
3980             {
3981                 Status  = -EINVAL;
3982                 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_ADD_WEP, Failed (length mismatch)!!\n"));
3983             }
3984             else
3985             {
3986                         KeyIdx = pWepKey->KeyIndex & 0x0fffffff;
3987                 // KeyIdx must be 0 ~ 3
3988                 if (KeyIdx > 4)
3989                         {
3990                     Status  = -EINVAL;
3991                     DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_ADD_WEP, Failed (KeyIdx must be smaller than 4)!!\n"));
3992                 }
3993                 else
3994                 {
3995                     UCHAR CipherAlg = 0;
3996                     PUCHAR Key;
3997
3998                     // set key material and key length
3999                     NdisZeroMemory(pAdapter->SharedKey[BSS0][KeyIdx].Key, 16);
4000                     pAdapter->SharedKey[BSS0][KeyIdx].KeyLen = (UCHAR) pWepKey->KeyLength;
4001                     NdisMoveMemory(pAdapter->SharedKey[BSS0][KeyIdx].Key, &pWepKey->KeyMaterial, pWepKey->KeyLength);
4002
4003                     switch(pWepKey->KeyLength)
4004                     {
4005                         case 5:
4006                             CipherAlg = CIPHER_WEP64;
4007                             break;
4008                         case 13:
4009                             CipherAlg = CIPHER_WEP128;
4010                             break;
4011                         default:
4012                             DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_ADD_WEP, only support CIPHER_WEP64(len:5) & CIPHER_WEP128(len:13)!!\n"));
4013                             Status = -EINVAL;
4014                             break;
4015                     }
4016                     pAdapter->SharedKey[BSS0][KeyIdx].CipherAlg = CipherAlg;
4017
4018                     // Default key for tx (shared key)
4019                     if (pWepKey->KeyIndex & 0x80000000)
4020                     {
4021                         // set key material and key length
4022                         NdisZeroMemory(pAdapter->StaCfg.DesireSharedKey[KeyIdx].Key, 16);
4023                         pAdapter->StaCfg.DesireSharedKey[KeyIdx].KeyLen = (UCHAR) pWepKey->KeyLength;
4024                         NdisMoveMemory(pAdapter->StaCfg.DesireSharedKey[KeyIdx].Key, &pWepKey->KeyMaterial, pWepKey->KeyLength);
4025                         pAdapter->StaCfg.DesireSharedKeyId = KeyIdx;
4026                         pAdapter->StaCfg.DesireSharedKey[KeyIdx].CipherAlg = CipherAlg;
4027                         pAdapter->StaCfg.DefaultKeyId = (UCHAR) KeyIdx;
4028                     }
4029
4030                                         if ((pAdapter->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE) &&
4031                                                 (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA))
4032                                         {
4033                                                 Key = pWepKey->KeyMaterial;
4034
4035                                                 // Set Group key material to Asic
4036                                         AsicAddSharedKeyEntry(pAdapter, BSS0, KeyIdx, CipherAlg, Key, NULL, NULL);
4037
4038                                                 // Update WCID attribute table and IVEIV table for this group key table
4039                                                 RTMPAddWcidAttributeEntry(pAdapter, BSS0, KeyIdx, CipherAlg, NULL);
4040
4041                                                 STA_PORT_SECURED(pAdapter);
4042
4043                                         // Indicate Connected for GUI
4044                                         pAdapter->IndicateMediaState = NdisMediaStateConnected;
4045                                         }
4046                     else if (pAdapter->StaCfg.PortSecured == WPA_802_1X_PORT_SECURED)
4047                     {
4048                         Key = pAdapter->SharedKey[BSS0][KeyIdx].Key;
4049
4050                         // Set key material and cipherAlg to Asic
4051                                         AsicAddSharedKeyEntry(pAdapter, BSS0, KeyIdx, CipherAlg, Key, NULL, NULL);
4052
4053                         if (pWepKey->KeyIndex & 0x80000000)
4054                         {
4055                             PMAC_TABLE_ENTRY pEntry = &pAdapter->MacTab.Content[BSSID_WCID];
4056                             // Assign group key info
4057                                                 RTMPAddWcidAttributeEntry(pAdapter, BSS0, KeyIdx, CipherAlg, NULL);
4058                                                 // Assign pairwise key info
4059                                                 RTMPAddWcidAttributeEntry(pAdapter, BSS0, KeyIdx, CipherAlg, pEntry);
4060                         }
4061                     }
4062                                         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"));
4063                                 }
4064             }
4065             kfree(pWepKey);
4066             break;
4067             case OID_SET_COUNTERMEASURES:
4068             if (wrq->u.data.length != sizeof(int))
4069                 Status  = -EINVAL;
4070             else
4071             {
4072                 int enabled = 0;
4073                 Status = copy_from_user(&enabled, wrq->u.data.pointer, wrq->u.data.length);
4074                 if (enabled == 1)
4075                     pAdapter->StaCfg.bBlockAssoc = TRUE;
4076                 else
4077                     // WPA MIC error should block association attempt for 60 seconds
4078                     pAdapter->StaCfg.bBlockAssoc = FALSE;
4079                 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_SET_COUNTERMEASURES bBlockAssoc=%s\n", pAdapter->StaCfg.bBlockAssoc ? "TRUE":"FALSE"));
4080             }
4081                 break;
4082         case RT_OID_WPA_SUPPLICANT_SUPPORT:
4083                         if (wrq->u.data.length != sizeof(UCHAR))
4084                 Status  = -EINVAL;
4085             else
4086             {
4087                 Status = copy_from_user(&wpa_supplicant_enable, wrq->u.data.pointer, wrq->u.data.length);
4088                         pAdapter->StaCfg.WpaSupplicantUP = wpa_supplicant_enable;
4089                         DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_WPA_SUPPLICANT_SUPPORT (=%d)\n", pAdapter->StaCfg.WpaSupplicantUP));
4090                         }
4091             break;
4092         case OID_802_11_DEAUTHENTICATION:
4093             if (wrq->u.data.length != sizeof(MLME_DEAUTH_REQ_STRUCT))
4094                 Status  = -EINVAL;
4095             else
4096             {
4097                 MLME_DEAUTH_REQ_STRUCT      *pInfo;
4098                                 MLME_QUEUE_ELEM *MsgElem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG);
4099
4100                 pInfo = (MLME_DEAUTH_REQ_STRUCT *) MsgElem->Msg;
4101                 Status = copy_from_user(pInfo, wrq->u.data.pointer, wrq->u.data.length);
4102                 MlmeDeauthReqAction(pAdapter, MsgElem);
4103                                 kfree(MsgElem);
4104
4105                 if (INFRA_ON(pAdapter))
4106                 {
4107                     LinkDown(pAdapter, FALSE);
4108                     pAdapter->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
4109                 }
4110                 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_DEAUTHENTICATION (Reason=%d)\n", pInfo->Reason));
4111             }
4112             break;
4113         case OID_802_11_DROP_UNENCRYPTED:
4114             if (wrq->u.data.length != sizeof(int))
4115                 Status  = -EINVAL;
4116             else
4117             {
4118                 int enabled = 0;
4119                 Status = copy_from_user(&enabled, wrq->u.data.pointer, wrq->u.data.length);
4120                 if (enabled == 1)
4121                     pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
4122                 else
4123                     pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
4124                                 NdisAcquireSpinLock(&pAdapter->MacTabLock);
4125                                 pAdapter->MacTab.Content[BSSID_WCID].PortSecured = pAdapter->StaCfg.PortSecured;
4126                                 NdisReleaseSpinLock(&pAdapter->MacTabLock);
4127                 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_DROP_UNENCRYPTED (=%d)\n", enabled));
4128             }
4129             break;
4130         case OID_802_11_SET_IEEE8021X:
4131             if (wrq->u.data.length != sizeof(BOOLEAN))
4132                 Status  = -EINVAL;
4133             else
4134             {
4135                 Status = copy_from_user(&IEEE8021xState, wrq->u.data.pointer, wrq->u.data.length);
4136                         pAdapter->StaCfg.IEEE8021X = IEEE8021xState;
4137                 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_SET_IEEE8021X (=%d)\n", IEEE8021xState));
4138             }
4139             break;
4140         case OID_802_11_SET_IEEE8021X_REQUIRE_KEY:
4141                         if (wrq->u.data.length != sizeof(BOOLEAN))
4142                                  Status  = -EINVAL;
4143             else
4144             {
4145                 Status = copy_from_user(&IEEE8021x_required_keys, wrq->u.data.pointer, wrq->u.data.length);
4146                                 pAdapter->StaCfg.IEEE8021x_required_keys = IEEE8021x_required_keys;
4147                                 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_SET_IEEE8021X_REQUIRE_KEY (%d)\n", IEEE8021x_required_keys));
4148                         }
4149                         break;
4150         case OID_802_11_PMKID:
4151                 pPmkId = kmalloc(wrq->u.data.length, MEM_ALLOC_FLAG);
4152
4153                 if(pPmkId == NULL) {
4154                 Status = -ENOMEM;
4155                 break;
4156             }
4157             Status = copy_from_user(pPmkId, wrq->u.data.pointer, wrq->u.data.length);
4158
4159                 // check the PMKID information
4160                 if (pPmkId->BSSIDInfoCount == 0)
4161                 NdisZeroMemory(pAdapter->StaCfg.SavedPMK, sizeof(BSSID_INFO)*PMKID_NO);
4162                 else
4163                 {
4164                         PBSSID_INFO     pBssIdInfo;
4165                         UINT            BssIdx;
4166                         UINT            CachedIdx;
4167
4168                         for (BssIdx = 0; BssIdx < pPmkId->BSSIDInfoCount; BssIdx++)
4169                         {
4170                                 // point to the indexed BSSID_INFO structure
4171                                 pBssIdInfo = (PBSSID_INFO) ((PUCHAR) pPmkId + 2 * sizeof(UINT) + BssIdx * sizeof(BSSID_INFO));
4172                                 // Find the entry in the saved data base.
4173                                 for (CachedIdx = 0; CachedIdx < pAdapter->StaCfg.SavedPMKNum; CachedIdx++)
4174                                 {
4175                                         // compare the BSSID
4176                                         if (NdisEqualMemory(pBssIdInfo->BSSID, pAdapter->StaCfg.SavedPMK[CachedIdx].BSSID, sizeof(NDIS_802_11_MAC_ADDRESS)))
4177                                                 break;
4178                                 }
4179
4180                                 // Found, replace it
4181                                 if (CachedIdx < PMKID_NO)
4182                                 {
4183                                         DBGPRINT(RT_DEBUG_OFF, ("Update OID_802_11_PMKID, idx = %d\n", CachedIdx));
4184                                         NdisMoveMemory(&pAdapter->StaCfg.SavedPMK[CachedIdx], pBssIdInfo, sizeof(BSSID_INFO));
4185                                         pAdapter->StaCfg.SavedPMKNum++;
4186                                 }
4187                                 // Not found, replace the last one
4188                                 else
4189                                 {
4190                                         // Randomly replace one
4191                                         CachedIdx = (pBssIdInfo->BSSID[5] % PMKID_NO);
4192                                         DBGPRINT(RT_DEBUG_OFF, ("Update OID_802_11_PMKID, idx = %d\n", CachedIdx));
4193                                         NdisMoveMemory(&pAdapter->StaCfg.SavedPMK[CachedIdx], pBssIdInfo, sizeof(BSSID_INFO));
4194                                 }
4195                         }
4196                         }
4197                         if(pPmkId)
4198                                 kfree(pPmkId);
4199                 break;
4200         default:
4201             DBGPRINT(RT_DEBUG_TRACE, ("Set::unknown IOCTL's subcmd = 0x%08x\n", cmd));
4202             Status = -EOPNOTSUPP;
4203             break;
4204     }
4205
4206
4207     return Status;
4208 }
4209
4210 INT RTMPQueryInformation(
4211     IN  PRTMP_ADAPTER pAdapter,
4212     IN  OUT struct ifreq    *rq,
4213     IN  INT                 cmd)
4214 {
4215     struct iwreq                        *wrq = (struct iwreq *) rq;
4216     NDIS_802_11_BSSID_LIST_EX           *pBssidList = NULL;
4217     PNDIS_WLAN_BSSID_EX                 pBss;
4218     NDIS_802_11_SSID                    Ssid;
4219     NDIS_802_11_CONFIGURATION           *pConfiguration = NULL;
4220     RT_802_11_LINK_STATUS               *pLinkStatus = NULL;
4221     RT_802_11_STA_CONFIG                *pStaConfig = NULL;
4222     NDIS_802_11_STATISTICS              *pStatistics = NULL;
4223     NDIS_802_11_RTS_THRESHOLD           RtsThresh;
4224     NDIS_802_11_FRAGMENTATION_THRESHOLD FragThresh;
4225     NDIS_802_11_POWER_MODE              PowerMode;
4226     NDIS_802_11_NETWORK_INFRASTRUCTURE  BssType;
4227     RT_802_11_PREAMBLE                  PreamType;
4228     NDIS_802_11_AUTHENTICATION_MODE     AuthMode;
4229     NDIS_802_11_WEP_STATUS              WepStatus;
4230     NDIS_MEDIA_STATE                    MediaState;
4231     ULONG                               BssBufSize, ulInfo=0, NetworkTypeList[4], apsd = 0;
4232     USHORT                              BssLen = 0;
4233     PUCHAR                              pBuf = NULL, pPtr;
4234     INT                                 Status = NDIS_STATUS_SUCCESS;
4235     UINT                                we_version_compiled;
4236     UCHAR                               i, Padding = 0;
4237     BOOLEAN                             RadioState;
4238         UCHAR   driverVersion[8];
4239     OID_SET_HT_PHYMODE                          *pHTPhyMode = NULL;
4240
4241     switch(cmd)
4242     {
4243         case RT_OID_DEVICE_NAME:
4244             wrq->u.data.length = sizeof(STA_NIC_DEVICE_NAME);
4245             Status = copy_to_user(wrq->u.data.pointer, STA_NIC_DEVICE_NAME, wrq->u.data.length);
4246             break;
4247         case RT_OID_VERSION_INFO:
4248                         DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_VERSION_INFO \n"));
4249                         wrq->u.data.length = 8*sizeof(UCHAR);
4250                         sprintf(&driverVersion[0], "%s", STA_DRIVER_VERSION);
4251                         driverVersion[7] = '\0';
4252                         if (copy_to_user(wrq->u.data.pointer, &driverVersion, wrq->u.data.length))
4253             {
4254                                 Status = -EFAULT;
4255             }
4256             break;
4257         case OID_802_11_BSSID_LIST:
4258             if (RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
4259             {
4260                 /*
4261                  * Still scanning, indicate the caller should try again.
4262                  */
4263                 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_BSSID_LIST (Still scanning)\n"));
4264                                 return -EAGAIN;
4265             }
4266             DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_BSSID_LIST (%d BSS returned)\n",pAdapter->ScanTab.BssNr));
4267                         pAdapter->StaCfg.bScanReqIsFromWebUI = FALSE;
4268             // Claculate total buffer size required
4269             BssBufSize = sizeof(ULONG);
4270
4271             for (i = 0; i < pAdapter->ScanTab.BssNr; i++)
4272             {
4273                 // Align pointer to 4 bytes boundary.
4274                 //Padding = 4 - (pAdapter->ScanTab.BssEntry[i].VarIELen & 0x0003);
4275                 //if (Padding == 4)
4276                 //    Padding = 0;
4277                 BssBufSize += (sizeof(NDIS_WLAN_BSSID_EX) - 1 + sizeof(NDIS_802_11_FIXED_IEs) + pAdapter->ScanTab.BssEntry[i].VarIELen + Padding);
4278             }
4279
4280             // For safety issue, we add 256 bytes just in case
4281             BssBufSize += 256;
4282             // Allocate the same size as passed from higher layer
4283             pBuf = kmalloc(BssBufSize, MEM_ALLOC_FLAG);
4284             if(pBuf == NULL)
4285             {
4286                 Status = -ENOMEM;
4287                 break;
4288             }
4289             // Init 802_11_BSSID_LIST_EX structure
4290             NdisZeroMemory(pBuf, BssBufSize);
4291             pBssidList = (PNDIS_802_11_BSSID_LIST_EX) pBuf;
4292             pBssidList->NumberOfItems = pAdapter->ScanTab.BssNr;
4293
4294             // Calculate total buffer length
4295             BssLen = 4; // Consist of NumberOfItems
4296             // Point to start of NDIS_WLAN_BSSID_EX
4297             // pPtr = pBuf + sizeof(ULONG);
4298             pPtr = (PUCHAR) &pBssidList->Bssid[0];
4299             for (i = 0; i < pAdapter->ScanTab.BssNr; i++)
4300             {
4301                 pBss = (PNDIS_WLAN_BSSID_EX) pPtr;
4302                 NdisMoveMemory(&pBss->MacAddress, &pAdapter->ScanTab.BssEntry[i].Bssid, MAC_ADDR_LEN);
4303                 if ((pAdapter->ScanTab.BssEntry[i].Hidden == 1) && (pAdapter->StaCfg.bShowHiddenSSID == FALSE))
4304                 {
4305                     //
4306                                         // We must return this SSID during 4way handshaking, otherwise Aegis will failed to parse WPA infomation
4307                                         // and then failed to send EAPOl farame.
4308                                         //
4309                                         if ((pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA) && (pAdapter->StaCfg.PortSecured != WPA_802_1X_PORT_SECURED))
4310                                         {
4311                                                 pBss->Ssid.SsidLength = pAdapter->ScanTab.BssEntry[i].SsidLen;
4312                                                 NdisMoveMemory(pBss->Ssid.Ssid, pAdapter->ScanTab.BssEntry[i].Ssid, pAdapter->ScanTab.BssEntry[i].SsidLen);
4313                                         }
4314                                         else
4315                         pBss->Ssid.SsidLength = 0;
4316                 }
4317                 else
4318                 {
4319                     pBss->Ssid.SsidLength = pAdapter->ScanTab.BssEntry[i].SsidLen;
4320                     NdisMoveMemory(pBss->Ssid.Ssid, pAdapter->ScanTab.BssEntry[i].Ssid, pAdapter->ScanTab.BssEntry[i].SsidLen);
4321                 }
4322                 pBss->Privacy = pAdapter->ScanTab.BssEntry[i].Privacy;
4323                 pBss->Rssi = pAdapter->ScanTab.BssEntry[i].Rssi - pAdapter->BbpRssiToDbmDelta;
4324                 pBss->NetworkTypeInUse = NetworkTypeInUseSanity(&pAdapter->ScanTab.BssEntry[i]);
4325                 pBss->Configuration.Length = sizeof(NDIS_802_11_CONFIGURATION);
4326                 pBss->Configuration.BeaconPeriod = pAdapter->ScanTab.BssEntry[i].BeaconPeriod;
4327                 pBss->Configuration.ATIMWindow = pAdapter->ScanTab.BssEntry[i].AtimWin;
4328
4329                 MAP_CHANNEL_ID_TO_KHZ(pAdapter->ScanTab.BssEntry[i].Channel, pBss->Configuration.DSConfig);
4330
4331                 if (pAdapter->ScanTab.BssEntry[i].BssType == BSS_INFRA)
4332                     pBss->InfrastructureMode = Ndis802_11Infrastructure;
4333                 else
4334                     pBss->InfrastructureMode = Ndis802_11IBSS;
4335
4336                 NdisMoveMemory(pBss->SupportedRates, pAdapter->ScanTab.BssEntry[i].SupRate, pAdapter->ScanTab.BssEntry[i].SupRateLen);
4337                 NdisMoveMemory(pBss->SupportedRates + pAdapter->ScanTab.BssEntry[i].SupRateLen,
4338                                pAdapter->ScanTab.BssEntry[i].ExtRate,
4339                                pAdapter->ScanTab.BssEntry[i].ExtRateLen);
4340
4341                 if (pAdapter->ScanTab.BssEntry[i].VarIELen == 0)
4342                 {
4343                     pBss->IELength = sizeof(NDIS_802_11_FIXED_IEs);
4344                     NdisMoveMemory(pBss->IEs, &pAdapter->ScanTab.BssEntry[i].FixIEs, sizeof(NDIS_802_11_FIXED_IEs));
4345                     pPtr = pPtr + sizeof(NDIS_WLAN_BSSID_EX) - 1 + sizeof(NDIS_802_11_FIXED_IEs);
4346                 }
4347                 else
4348                 {
4349                     pBss->IELength = (ULONG)(sizeof(NDIS_802_11_FIXED_IEs) + pAdapter->ScanTab.BssEntry[i].VarIELen);
4350                     pPtr = pPtr + sizeof(NDIS_WLAN_BSSID_EX) - 1 + sizeof(NDIS_802_11_FIXED_IEs);
4351                     NdisMoveMemory(pBss->IEs, &pAdapter->ScanTab.BssEntry[i].FixIEs, sizeof(NDIS_802_11_FIXED_IEs));
4352                     NdisMoveMemory(pBss->IEs + sizeof(NDIS_802_11_FIXED_IEs), pAdapter->ScanTab.BssEntry[i].VarIEs, pAdapter->ScanTab.BssEntry[i].VarIELen);
4353                     pPtr += pAdapter->ScanTab.BssEntry[i].VarIELen;
4354                 }
4355                 pBss->Length = (ULONG)(sizeof(NDIS_WLAN_BSSID_EX) - 1 + sizeof(NDIS_802_11_FIXED_IEs) + pAdapter->ScanTab.BssEntry[i].VarIELen + Padding);
4356
4357 #if WIRELESS_EXT < 17
4358                 if ((BssLen + pBss->Length) < wrq->u.data.length)
4359                 BssLen += pBss->Length;
4360                 else
4361                 {
4362                     pBssidList->NumberOfItems = i;
4363                     break;
4364                 }
4365 #else
4366                 BssLen += pBss->Length;
4367 #endif
4368             }
4369
4370 #if WIRELESS_EXT < 17
4371             wrq->u.data.length = BssLen;
4372 #else
4373             if (BssLen > wrq->u.data.length)
4374             {
4375                 kfree(pBssidList);
4376                 return -E2BIG;
4377             }
4378             else
4379                 wrq->u.data.length = BssLen;
4380 #endif
4381             Status = copy_to_user(wrq->u.data.pointer, pBssidList, BssLen);
4382             kfree(pBssidList);
4383             break;
4384         case OID_802_3_CURRENT_ADDRESS:
4385             wrq->u.data.length = MAC_ADDR_LEN;
4386             Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CurrentAddress, wrq->u.data.length);
4387             break;
4388         case OID_GEN_MEDIA_CONNECT_STATUS:
4389             if (pAdapter->IndicateMediaState == NdisMediaStateConnected)
4390                 MediaState = NdisMediaStateConnected;
4391             else
4392                 MediaState = NdisMediaStateDisconnected;
4393
4394             wrq->u.data.length = sizeof(NDIS_MEDIA_STATE);
4395             Status = copy_to_user(wrq->u.data.pointer, &MediaState, wrq->u.data.length);
4396             break;
4397         case OID_802_11_BSSID:
4398             if (INFRA_ON(pAdapter) || ADHOC_ON(pAdapter))
4399             {
4400                 Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.Bssid, sizeof(NDIS_802_11_MAC_ADDRESS));
4401
4402             }
4403             else
4404             {
4405                 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_BSSID(=EMPTY)\n"));
4406                 Status = -ENOTCONN;
4407             }
4408             break;
4409         case OID_802_11_SSID:
4410                         NdisZeroMemory(&Ssid, sizeof(NDIS_802_11_SSID));
4411                         NdisZeroMemory(Ssid.Ssid, MAX_LEN_OF_SSID);
4412             Ssid.SsidLength = pAdapter->CommonCfg.SsidLen;
4413                         memcpy(Ssid.Ssid, pAdapter->CommonCfg.Ssid,     Ssid.SsidLength);
4414             wrq->u.data.length = sizeof(NDIS_802_11_SSID);
4415             Status = copy_to_user(wrq->u.data.pointer, &Ssid, wrq->u.data.length);
4416             DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_SSID (Len=%d, ssid=%s)\n", Ssid.SsidLength,Ssid.Ssid));
4417             break;
4418         case RT_OID_802_11_QUERY_LINK_STATUS:
4419             pLinkStatus = (RT_802_11_LINK_STATUS *) kmalloc(sizeof(RT_802_11_LINK_STATUS), MEM_ALLOC_FLAG);
4420             if (pLinkStatus)
4421             {
4422                 pLinkStatus->CurrTxRate = RateIdTo500Kbps[pAdapter->CommonCfg.TxRate];   // unit : 500 kbps
4423                 pLinkStatus->ChannelQuality = pAdapter->Mlme.ChannelQuality;
4424                 pLinkStatus->RxByteCount = pAdapter->RalinkCounters.ReceivedByteCount;
4425                 pLinkStatus->TxByteCount = pAdapter->RalinkCounters.TransmittedByteCount;
4426                         pLinkStatus->CentralChannel = pAdapter->CommonCfg.CentralChannel;
4427                 wrq->u.data.length = sizeof(RT_802_11_LINK_STATUS);
4428                 Status = copy_to_user(wrq->u.data.pointer, pLinkStatus, wrq->u.data.length);
4429                 kfree(pLinkStatus);
4430                 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_LINK_STATUS\n"));
4431             }
4432             else
4433             {
4434                 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_LINK_STATUS(kmalloc failed)\n"));
4435                 Status = -EFAULT;
4436             }
4437             break;
4438         case OID_802_11_CONFIGURATION:
4439             pConfiguration = (NDIS_802_11_CONFIGURATION *) kmalloc(sizeof(NDIS_802_11_CONFIGURATION), MEM_ALLOC_FLAG);
4440             if (pConfiguration)
4441             {
4442                 pConfiguration->Length = sizeof(NDIS_802_11_CONFIGURATION);
4443                 pConfiguration->BeaconPeriod = pAdapter->CommonCfg.BeaconPeriod;
4444                 pConfiguration->ATIMWindow = pAdapter->StaActive.AtimWin;
4445                 MAP_CHANNEL_ID_TO_KHZ(pAdapter->CommonCfg.Channel, pConfiguration->DSConfig);
4446                 wrq->u.data.length = sizeof(NDIS_802_11_CONFIGURATION);
4447                 Status = copy_to_user(wrq->u.data.pointer, pConfiguration, wrq->u.data.length);
4448                 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_CONFIGURATION(BeaconPeriod=%ld,AtimW=%ld,Channel=%d) \n",
4449                                         pConfiguration->BeaconPeriod, pConfiguration->ATIMWindow, pAdapter->CommonCfg.Channel));
4450                                 kfree(pConfiguration);
4451             }
4452             else
4453             {
4454                 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_CONFIGURATION(kmalloc failed)\n"));
4455                 Status = -EFAULT;
4456             }
4457             break;
4458                 case RT_OID_802_11_SNR_0:
4459                         if ((pAdapter->StaCfg.LastSNR0 > 0))
4460                         {
4461                                 ulInfo = ((0xeb - pAdapter->StaCfg.LastSNR0) * 3) /     16 ;
4462                                 wrq->u.data.length = sizeof(ulInfo);
4463                                 Status = copy_to_user(wrq->u.data.pointer, &ulInfo,     wrq->u.data.length);
4464                                 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_SNR_0(0x=%lx)\n", ulInfo));
4465                         }
4466             else
4467                             Status = -EFAULT;
4468                         break;
4469                 case RT_OID_802_11_SNR_1:
4470                         if ((pAdapter->Antenna.field.RxPath     > 1) &&
4471                 (pAdapter->StaCfg.LastSNR1 > 0))
4472                         {
4473                                 ulInfo = ((0xeb - pAdapter->StaCfg.LastSNR1) * 3) /     16 ;
4474                                 wrq->u.data.length = sizeof(ulInfo);
4475                                 Status = copy_to_user(wrq->u.data.pointer, &ulInfo,     wrq->u.data.length);
4476                                 DBGPRINT(RT_DEBUG_TRACE,("Query::RT_OID_802_11_SNR_1(0x=%lx)\n",ulInfo));
4477                         }
4478                         else
4479                                 Status = -EFAULT;
4480             DBGPRINT(RT_DEBUG_TRACE,("Query::RT_OID_802_11_SNR_1(pAdapter->StaCfg.LastSNR1=%d)\n",pAdapter->StaCfg.LastSNR1));
4481                         break;
4482         case OID_802_11_RSSI_TRIGGER:
4483             ulInfo = pAdapter->StaCfg.RssiSample.LastRssi0 - pAdapter->BbpRssiToDbmDelta;
4484             wrq->u.data.length = sizeof(ulInfo);
4485             Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
4486             DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_RSSI_TRIGGER(=%ld)\n", ulInfo));
4487             break;
4488                 case OID_802_11_RSSI:
4489         case RT_OID_802_11_RSSI:
4490                         ulInfo = pAdapter->StaCfg.RssiSample.LastRssi0;
4491                         wrq->u.data.length = sizeof(ulInfo);
4492                         Status = copy_to_user(wrq->u.data.pointer, &ulInfo,     wrq->u.data.length);
4493                         break;
4494                 case RT_OID_802_11_RSSI_1:
4495             ulInfo = pAdapter->StaCfg.RssiSample.LastRssi1;
4496                         wrq->u.data.length = sizeof(ulInfo);
4497                         Status = copy_to_user(wrq->u.data.pointer, &ulInfo,     wrq->u.data.length);
4498                         break;
4499         case RT_OID_802_11_RSSI_2:
4500             ulInfo = pAdapter->StaCfg.RssiSample.LastRssi2;
4501                         wrq->u.data.length = sizeof(ulInfo);
4502                         Status = copy_to_user(wrq->u.data.pointer, &ulInfo,     wrq->u.data.length);
4503                         break;
4504         case OID_802_11_STATISTICS:
4505             pStatistics = (NDIS_802_11_STATISTICS *) kmalloc(sizeof(NDIS_802_11_STATISTICS), MEM_ALLOC_FLAG);
4506             if (pStatistics)
4507             {
4508                 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_STATISTICS \n"));
4509                 // add the most up-to-date h/w raw counters into software counters
4510                             NICUpdateRawCounters(pAdapter);
4511
4512                 // Sanity check for calculation of sucessful count
4513                 if (pAdapter->WlanCounters.TransmittedFragmentCount.QuadPart < pAdapter->WlanCounters.RetryCount.QuadPart)
4514                     pAdapter->WlanCounters.TransmittedFragmentCount.QuadPart = pAdapter->WlanCounters.RetryCount.QuadPart;
4515
4516                 pStatistics->TransmittedFragmentCount.QuadPart = pAdapter->WlanCounters.TransmittedFragmentCount.QuadPart;
4517                 pStatistics->MulticastTransmittedFrameCount.QuadPart = pAdapter->WlanCounters.MulticastTransmittedFrameCount.QuadPart;
4518                 pStatistics->FailedCount.QuadPart = pAdapter->WlanCounters.FailedCount.QuadPart;
4519                 pStatistics->RetryCount.QuadPart = pAdapter->WlanCounters.RetryCount.QuadPart;
4520                 pStatistics->MultipleRetryCount.QuadPart = pAdapter->WlanCounters.MultipleRetryCount.QuadPart;
4521                 pStatistics->RTSSuccessCount.QuadPart = pAdapter->WlanCounters.RTSSuccessCount.QuadPart;
4522                 pStatistics->RTSFailureCount.QuadPart = pAdapter->WlanCounters.RTSFailureCount.QuadPart;
4523                 pStatistics->ACKFailureCount.QuadPart = pAdapter->WlanCounters.ACKFailureCount.QuadPart;
4524                 pStatistics->FrameDuplicateCount.QuadPart = pAdapter->WlanCounters.FrameDuplicateCount.QuadPart;
4525                 pStatistics->ReceivedFragmentCount.QuadPart = pAdapter->WlanCounters.ReceivedFragmentCount.QuadPart;
4526                 pStatistics->MulticastReceivedFrameCount.QuadPart = pAdapter->WlanCounters.MulticastReceivedFrameCount.QuadPart;
4527 #ifdef DBG
4528                 pStatistics->FCSErrorCount = pAdapter->RalinkCounters.RealFcsErrCount;
4529 #else
4530                 pStatistics->FCSErrorCount.QuadPart = pAdapter->WlanCounters.FCSErrorCount.QuadPart;
4531                 pStatistics->FrameDuplicateCount.u.LowPart = pAdapter->WlanCounters.FrameDuplicateCount.u.LowPart / 100;
4532 #endif
4533                 wrq->u.data.length = sizeof(NDIS_802_11_STATISTICS);
4534                 Status = copy_to_user(wrq->u.data.pointer, pStatistics, wrq->u.data.length);
4535                 kfree(pStatistics);
4536             }
4537             else
4538             {
4539                 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_STATISTICS(kmalloc failed)\n"));
4540                 Status = -EFAULT;
4541             }
4542             break;
4543         case OID_GEN_RCV_OK:
4544             ulInfo = pAdapter->Counters8023.GoodReceives;
4545             wrq->u.data.length = sizeof(ulInfo);
4546             Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
4547             break;
4548         case OID_GEN_RCV_NO_BUFFER:
4549             ulInfo = pAdapter->Counters8023.RxNoBuffer;
4550             wrq->u.data.length = sizeof(ulInfo);
4551             Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
4552             break;
4553         case RT_OID_802_11_PHY_MODE:
4554             ulInfo = (ULONG)pAdapter->CommonCfg.PhyMode;
4555             wrq->u.data.length = sizeof(ulInfo);
4556             Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
4557             DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_PHY_MODE (=%ld)\n", ulInfo));
4558             break;
4559         case RT_OID_802_11_STA_CONFIG:
4560             pStaConfig = (RT_802_11_STA_CONFIG *) kmalloc(sizeof(RT_802_11_STA_CONFIG), MEM_ALLOC_FLAG);
4561             if (pStaConfig)
4562             {
4563                 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_STA_CONFIG\n"));
4564                 pStaConfig->EnableTxBurst = pAdapter->CommonCfg.bEnableTxBurst;
4565                 pStaConfig->EnableTurboRate = 0;
4566                 pStaConfig->UseBGProtection = pAdapter->CommonCfg.UseBGProtection;
4567                 pStaConfig->UseShortSlotTime = pAdapter->CommonCfg.bUseShortSlotTime;
4568                 //pStaConfig->AdhocMode = pAdapter->StaCfg.AdhocMode;
4569                 pStaConfig->HwRadioStatus = (pAdapter->StaCfg.bHwRadio == TRUE) ? 1 : 0;
4570                 pStaConfig->Rsv1 = 0;
4571                 pStaConfig->SystemErrorBitmap = pAdapter->SystemErrorBitmap;
4572                 wrq->u.data.length = sizeof(RT_802_11_STA_CONFIG);
4573                 Status = copy_to_user(wrq->u.data.pointer, pStaConfig, wrq->u.data.length);
4574                 kfree(pStaConfig);
4575             }
4576             else
4577             {
4578                 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_STA_CONFIG(kmalloc failed)\n"));
4579                 Status = -EFAULT;
4580             }
4581             break;
4582         case OID_802_11_RTS_THRESHOLD:
4583             RtsThresh = pAdapter->CommonCfg.RtsThreshold;
4584             wrq->u.data.length = sizeof(RtsThresh);
4585             Status = copy_to_user(wrq->u.data.pointer, &RtsThresh, wrq->u.data.length);
4586             DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_RTS_THRESHOLD(=%ld)\n", RtsThresh));
4587             break;
4588         case OID_802_11_FRAGMENTATION_THRESHOLD:
4589             FragThresh = pAdapter->CommonCfg.FragmentThreshold;
4590             if (pAdapter->CommonCfg.bUseZeroToDisableFragment == TRUE)
4591                 FragThresh = 0;
4592             wrq->u.data.length = sizeof(FragThresh);
4593             Status = copy_to_user(wrq->u.data.pointer, &FragThresh, wrq->u.data.length);
4594             DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_FRAGMENTATION_THRESHOLD(=%ld)\n", FragThresh));
4595             break;
4596         case OID_802_11_POWER_MODE:
4597             PowerMode = pAdapter->StaCfg.WindowsPowerMode;
4598             wrq->u.data.length = sizeof(PowerMode);
4599             Status = copy_to_user(wrq->u.data.pointer, &PowerMode, wrq->u.data.length);
4600             DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_POWER_MODE(=%d)\n", PowerMode));
4601             break;
4602         case RT_OID_802_11_RADIO:
4603             RadioState = (BOOLEAN) pAdapter->StaCfg.bSwRadio;
4604             wrq->u.data.length = sizeof(RadioState);
4605             Status = copy_to_user(wrq->u.data.pointer, &RadioState, wrq->u.data.length);
4606             DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_RADIO (=%d)\n", RadioState));
4607             break;
4608         case OID_802_11_INFRASTRUCTURE_MODE:
4609             if (pAdapter->StaCfg.BssType == BSS_ADHOC)
4610                 BssType = Ndis802_11IBSS;
4611             else if (pAdapter->StaCfg.BssType == BSS_INFRA)
4612                 BssType = Ndis802_11Infrastructure;
4613             else if (pAdapter->StaCfg.BssType == BSS_MONITOR)
4614                 BssType = Ndis802_11Monitor;
4615             else
4616                 BssType = Ndis802_11AutoUnknown;
4617
4618             wrq->u.data.length = sizeof(BssType);
4619             Status = copy_to_user(wrq->u.data.pointer, &BssType, wrq->u.data.length);
4620             DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_INFRASTRUCTURE_MODE(=%d)\n", BssType));
4621             break;
4622         case RT_OID_802_11_PREAMBLE:
4623             PreamType = pAdapter->CommonCfg.TxPreamble;
4624             wrq->u.data.length = sizeof(PreamType);
4625             Status = copy_to_user(wrq->u.data.pointer, &PreamType, wrq->u.data.length);
4626             DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_PREAMBLE(=%d)\n", PreamType));
4627             break;
4628         case OID_802_11_AUTHENTICATION_MODE:
4629             AuthMode = pAdapter->StaCfg.AuthMode;
4630             wrq->u.data.length = sizeof(AuthMode);
4631             Status = copy_to_user(wrq->u.data.pointer, &AuthMode, wrq->u.data.length);
4632             DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_AUTHENTICATION_MODE(=%d)\n", AuthMode));
4633             break;
4634         case OID_802_11_WEP_STATUS:
4635             WepStatus = pAdapter->StaCfg.WepStatus;
4636             wrq->u.data.length = sizeof(WepStatus);
4637             Status = copy_to_user(wrq->u.data.pointer, &WepStatus, wrq->u.data.length);
4638             DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_WEP_STATUS(=%d)\n", WepStatus));
4639             break;
4640         case OID_802_11_TX_POWER_LEVEL:
4641                         wrq->u.data.length = sizeof(ULONG);
4642                         Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.TxPower, wrq->u.data.length);
4643                         DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_TX_POWER_LEVEL %x\n",pAdapter->CommonCfg.TxPower));
4644                         break;
4645         case RT_OID_802_11_TX_POWER_LEVEL_1:
4646             wrq->u.data.length = sizeof(ULONG);
4647             Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.TxPowerPercentage, wrq->u.data.length);
4648                         DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_TX_POWER_LEVEL_1 (=%ld)\n", pAdapter->CommonCfg.TxPowerPercentage));
4649                         break;
4650         case OID_802_11_NETWORK_TYPES_SUPPORTED:
4651                         if ((pAdapter->RfIcType == RFIC_2850) || (pAdapter->RfIcType == RFIC_2750))
4652                         {
4653                                 NetworkTypeList[0] = 3;                 // NumberOfItems = 3
4654                                 NetworkTypeList[1] = Ndis802_11DS;      // NetworkType[1] = 11b
4655                                 NetworkTypeList[2] = Ndis802_11OFDM24;  // NetworkType[2] = 11g
4656                                 NetworkTypeList[3] = Ndis802_11OFDM5;   // NetworkType[3] = 11a
4657                 wrq->u.data.length = 16;
4658                                 Status = copy_to_user(wrq->u.data.pointer, &NetworkTypeList[0], wrq->u.data.length);
4659                         }
4660                         else
4661                         {
4662                                 NetworkTypeList[0] = 2;                 // NumberOfItems = 2
4663                                 NetworkTypeList[1] = Ndis802_11DS;      // NetworkType[1] = 11b
4664                                 NetworkTypeList[2] = Ndis802_11OFDM24;  // NetworkType[2] = 11g
4665                             wrq->u.data.length = 12;
4666                                 Status = copy_to_user(wrq->u.data.pointer, &NetworkTypeList[0], wrq->u.data.length);
4667                         }
4668                         DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_NETWORK_TYPES_SUPPORTED\n"));
4669                                 break;
4670             case OID_802_11_NETWORK_TYPE_IN_USE:
4671             wrq->u.data.length = sizeof(ULONG);
4672                         if (pAdapter->CommonCfg.PhyMode == PHY_11A)
4673                                 ulInfo = Ndis802_11OFDM5;
4674                         else if ((pAdapter->CommonCfg.PhyMode == PHY_11BG_MIXED) || (pAdapter->CommonCfg.PhyMode == PHY_11G))
4675                                 ulInfo = Ndis802_11OFDM24;
4676                         else
4677                                 ulInfo = Ndis802_11DS;
4678             Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
4679                         break;
4680         case RT_OID_802_11_QUERY_LAST_RX_RATE:
4681             ulInfo = (ULONG)pAdapter->LastRxRate;
4682             wrq->u.data.length = sizeof(ulInfo);
4683                         Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
4684                         DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_LAST_RX_RATE (=%ld)\n", ulInfo));
4685                         break;
4686                 case RT_OID_802_11_QUERY_LAST_TX_RATE:
4687                         //ulInfo = (ULONG)pAdapter->LastTxRate;
4688                         ulInfo = (ULONG)pAdapter->MacTab.Content[BSSID_WCID].HTPhyMode.word;
4689                         wrq->u.data.length = sizeof(ulInfo);
4690                         Status = copy_to_user(wrq->u.data.pointer, &ulInfo,     wrq->u.data.length);
4691                         DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_LAST_TX_RATE (=%lx)\n", ulInfo));
4692                         break;
4693         case RT_OID_802_11_QUERY_EEPROM_VERSION:
4694             wrq->u.data.length = sizeof(ULONG);
4695             Status = copy_to_user(wrq->u.data.pointer, &pAdapter->EepromVersion, wrq->u.data.length);
4696             break;
4697         case RT_OID_802_11_QUERY_FIRMWARE_VERSION:
4698             wrq->u.data.length = sizeof(ULONG);
4699             Status = copy_to_user(wrq->u.data.pointer, &pAdapter->FirmwareVersion, wrq->u.data.length);
4700                         break;
4701             case RT_OID_802_11_QUERY_NOISE_LEVEL:
4702                         wrq->u.data.length = sizeof(UCHAR);
4703                         Status = copy_to_user(wrq->u.data.pointer, &pAdapter->BbpWriteLatch[66], wrq->u.data.length);
4704                         DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_NOISE_LEVEL (=%d)\n", pAdapter->BbpWriteLatch[66]));
4705                         break;
4706             case RT_OID_802_11_EXTRA_INFO:
4707                         wrq->u.data.length = sizeof(ULONG);
4708                         Status = copy_to_user(wrq->u.data.pointer, &pAdapter->ExtraInfo, wrq->u.data.length);
4709                 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_EXTRA_INFO (=%ld)\n", pAdapter->ExtraInfo));
4710                 break;
4711             case RT_OID_WE_VERSION_COMPILED:
4712                 wrq->u.data.length = sizeof(UINT);
4713                 we_version_compiled = WIRELESS_EXT;
4714                 Status = copy_to_user(wrq->u.data.pointer, &we_version_compiled, wrq->u.data.length);
4715                 break;
4716                 case RT_OID_802_11_QUERY_APSD_SETTING:
4717                         apsd = (pAdapter->CommonCfg.bAPSDCapable | (pAdapter->CommonCfg.bAPSDAC_BE << 1) | (pAdapter->CommonCfg.bAPSDAC_BK << 2)
4718                                 | (pAdapter->CommonCfg.bAPSDAC_VI << 3) | (pAdapter->CommonCfg.bAPSDAC_VO << 4) | (pAdapter->CommonCfg.MaxSPLength << 5));
4719
4720                         wrq->u.data.length = sizeof(ULONG);
4721                         Status = copy_to_user(wrq->u.data.pointer, &apsd, wrq->u.data.length);
4722                         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",
4723                                 apsd,pAdapter->CommonCfg.bAPSDCapable,pAdapter->CommonCfg.bAPSDAC_BE,pAdapter->CommonCfg.bAPSDAC_BK,pAdapter->CommonCfg.bAPSDAC_VI,pAdapter->CommonCfg.bAPSDAC_VO,pAdapter->CommonCfg.MaxSPLength));
4724                         break;
4725                 case RT_OID_802_11_QUERY_APSD_PSM:
4726                         wrq->u.data.length = sizeof(ULONG);
4727                         Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.bAPSDForcePowerSave, wrq->u.data.length);
4728                         DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_APSD_PSM (=%d)\n", pAdapter->CommonCfg.bAPSDForcePowerSave));
4729                         break;
4730                 case RT_OID_802_11_QUERY_WMM:
4731                         wrq->u.data.length = sizeof(BOOLEAN);
4732                         Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.bWmmCapable, wrq->u.data.length);
4733                         DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_WMM (=%d)\n",     pAdapter->CommonCfg.bWmmCapable));
4734                         break;
4735         case RT_OID_NEW_DRIVER:
4736             {
4737                 UCHAR enabled = 1;
4738                 wrq->u.data.length = sizeof(UCHAR);
4739                 Status = copy_to_user(wrq->u.data.pointer, &enabled, wrq->u.data.length);
4740                 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_NEW_DRIVER (=%d)\n", enabled));
4741             }
4742                 break;
4743         case RT_OID_WPA_SUPPLICANT_SUPPORT:
4744                 wrq->u.data.length = sizeof(UCHAR);
4745                 Status = copy_to_user(wrq->u.data.pointer, &pAdapter->StaCfg.WpaSupplicantUP, wrq->u.data.length);
4746             DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_WPA_SUPPLICANT_SUPPORT (=%d)\n", pAdapter->StaCfg.WpaSupplicantUP));
4747                 break;
4748         case RT_OID_DRIVER_DEVICE_NAME:
4749             DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_DRIVER_DEVICE_NAME \n"));
4750                         wrq->u.data.length = 16;
4751                         if (copy_to_user(wrq->u.data.pointer, pAdapter->StaCfg.dev_name, wrq->u.data.length))
4752                         {
4753                                 Status = -EFAULT;
4754                         }
4755             break;
4756         case RT_OID_802_11_QUERY_HT_PHYMODE:
4757             pHTPhyMode = (OID_SET_HT_PHYMODE *) kmalloc(sizeof(OID_SET_HT_PHYMODE), MEM_ALLOC_FLAG);
4758             if (pHTPhyMode)
4759             {
4760                 pHTPhyMode->PhyMode = pAdapter->CommonCfg.PhyMode;
4761                         pHTPhyMode->HtMode = (UCHAR)pAdapter->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE;
4762                         pHTPhyMode->BW = (UCHAR)pAdapter->MacTab.Content[BSSID_WCID].HTPhyMode.field.BW;
4763                         pHTPhyMode->MCS= (UCHAR)pAdapter->MacTab.Content[BSSID_WCID].HTPhyMode.field.MCS;
4764                         pHTPhyMode->SHORTGI= (UCHAR)pAdapter->MacTab.Content[BSSID_WCID].HTPhyMode.field.ShortGI;
4765                         pHTPhyMode->STBC= (UCHAR)pAdapter->MacTab.Content[BSSID_WCID].HTPhyMode.field.STBC;
4766
4767                         pHTPhyMode->ExtOffset = ((pAdapter->CommonCfg.CentralChannel < pAdapter->CommonCfg.Channel) ? (EXTCHA_BELOW) : (EXTCHA_ABOVE));
4768                 wrq->u.data.length = sizeof(OID_SET_HT_PHYMODE);
4769                 if (copy_to_user(wrq->u.data.pointer, pHTPhyMode, wrq->u.data.length))
4770                         {
4771                                 Status = -EFAULT;
4772                         }
4773                         DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_HT_PHYMODE (PhyMode = %d, MCS =%d, BW = %d, STBC = %d, ExtOffset=%d)\n",
4774                                 pHTPhyMode->HtMode, pHTPhyMode->MCS, pHTPhyMode->BW, pHTPhyMode->STBC, pHTPhyMode->ExtOffset));
4775                         DBGPRINT(RT_DEBUG_TRACE, (" MlmeUpdateTxRates (.word = %x )\n", pAdapter->MacTab.Content[BSSID_WCID].HTPhyMode.word));
4776             }
4777             else
4778             {
4779                 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_STA_CONFIG(kmalloc failed)\n"));
4780                 Status = -EFAULT;
4781             }
4782             break;
4783         case RT_OID_802_11_COUNTRY_REGION:
4784             DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_COUNTRY_REGION \n"));
4785                         wrq->u.data.length = sizeof(ulInfo);
4786             ulInfo = pAdapter->CommonCfg.CountryRegionForABand;
4787             ulInfo = (ulInfo << 8)|(pAdapter->CommonCfg.CountryRegion);
4788                         if (copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length))
4789             {
4790                                 Status = -EFAULT;
4791             }
4792             break;
4793         case RT_OID_802_11_QUERY_DAT_HT_PHYMODE:
4794             pHTPhyMode = (OID_SET_HT_PHYMODE *) kmalloc(sizeof(OID_SET_HT_PHYMODE), MEM_ALLOC_FLAG);
4795             if (pHTPhyMode)
4796             {
4797                 pHTPhyMode->PhyMode = pAdapter->CommonCfg.PhyMode;
4798                         pHTPhyMode->HtMode = (UCHAR)pAdapter->CommonCfg.RegTransmitSetting.field.HTMODE;
4799                         pHTPhyMode->BW = (UCHAR)pAdapter->CommonCfg.RegTransmitSetting.field.BW;
4800                         pHTPhyMode->MCS= (UCHAR)pAdapter->StaCfg.DesiredTransmitSetting.field.MCS;
4801                         pHTPhyMode->SHORTGI= (UCHAR)pAdapter->CommonCfg.RegTransmitSetting.field.ShortGI;
4802                         pHTPhyMode->STBC= (UCHAR)pAdapter->CommonCfg.RegTransmitSetting.field.STBC;
4803
4804                 wrq->u.data.length = sizeof(OID_SET_HT_PHYMODE);
4805                 if (copy_to_user(wrq->u.data.pointer, pHTPhyMode, wrq->u.data.length))
4806                         {
4807                                 Status = -EFAULT;
4808                         }
4809                         DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_HT_PHYMODE (PhyMode = %d, MCS =%d, BW = %d, STBC = %d, ExtOffset=%d)\n",
4810                                 pHTPhyMode->HtMode, pHTPhyMode->MCS, pHTPhyMode->BW, pHTPhyMode->STBC, pHTPhyMode->ExtOffset));
4811                         DBGPRINT(RT_DEBUG_TRACE, (" MlmeUpdateTxRates (.word = %x )\n", pAdapter->MacTab.Content[BSSID_WCID].HTPhyMode.word));
4812             }
4813             else
4814             {
4815                 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_STA_CONFIG(kmalloc failed)\n"));
4816                 Status = -EFAULT;
4817             }
4818             break;
4819         case RT_OID_QUERY_MULTIPLE_CARD_SUPPORT:
4820                         wrq->u.data.length = sizeof(UCHAR);
4821             i = 0;
4822                         if (copy_to_user(wrq->u.data.pointer, &i, wrq->u.data.length))
4823             {
4824                                 Status = -EFAULT;
4825             }
4826             DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_QUERY_MULTIPLE_CARD_SUPPORT(=%d) \n", i));
4827             break;
4828
4829                 case OID_802_11_BUILD_CHANNEL_EX:
4830                         {
4831                                 UCHAR value;
4832                                 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_BUILD_CHANNEL_EX \n"));
4833                                 wrq->u.data.length = sizeof(UCHAR);
4834                                 DBGPRINT(RT_DEBUG_TRACE, ("Doesn't support EXT_BUILD_CHANNEL_LIST.\n"));
4835                                 value = 0;
4836                                 Status = copy_to_user(wrq->u.data.pointer, &value, 1);
4837                                 DBGPRINT(RT_DEBUG_TRACE, ("Status=%d\n", Status));
4838                         }
4839                         break;
4840
4841                 case OID_802_11_GET_CH_LIST:
4842                         {
4843                                 PRT_CHANNEL_LIST_INFO pChListBuf;
4844
4845                                 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_GET_CH_LIST \n"));
4846                                 if (pAdapter->ChannelListNum == 0)
4847                                 {
4848                                         wrq->u.data.length = 0;
4849                                         break;
4850                                 }
4851
4852                                 pChListBuf = (RT_CHANNEL_LIST_INFO *) kmalloc(sizeof(RT_CHANNEL_LIST_INFO), MEM_ALLOC_FLAG);
4853                                 if (pChListBuf == NULL)
4854                                 {
4855                                         wrq->u.data.length = 0;
4856                                         break;
4857                                 }
4858
4859                                 pChListBuf->ChannelListNum = pAdapter->ChannelListNum;
4860                                 for (i = 0; i < pChListBuf->ChannelListNum; i++)
4861                                         pChListBuf->ChannelList[i] = pAdapter->ChannelList[i].Channel;
4862
4863                                 wrq->u.data.length = sizeof(RT_CHANNEL_LIST_INFO);
4864                                 Status = copy_to_user(wrq->u.data.pointer, pChListBuf, sizeof(RT_CHANNEL_LIST_INFO));
4865                                 DBGPRINT(RT_DEBUG_TRACE, ("Status=%d\n", Status));
4866
4867                                 if (pChListBuf)
4868                                         kfree(pChListBuf);
4869                         }
4870                         break;
4871
4872                 case OID_802_11_GET_COUNTRY_CODE:
4873                         DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_GET_COUNTRY_CODE \n"));
4874                         wrq->u.data.length = 2;
4875                         Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.CountryCode, 2);
4876                         DBGPRINT(RT_DEBUG_TRACE, ("Status=%d\n", Status));
4877                         break;
4878
4879                 case OID_802_11_GET_CHANNEL_GEOGRAPHY:
4880                         DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_GET_CHANNEL_GEOGRAPHY \n"));
4881                         wrq->u.data.length = 1;
4882                         Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.Geography, 1);
4883                         DBGPRINT(RT_DEBUG_TRACE, ("Status=%d\n", Status));
4884                         break;
4885
4886         default:
4887             DBGPRINT(RT_DEBUG_TRACE, ("Query::unknown IOCTL's subcmd = 0x%08x\n", cmd));
4888             Status = -EOPNOTSUPP;
4889             break;
4890     }
4891     return Status;
4892 }
4893
4894 INT rt28xx_sta_ioctl(
4895         IN      struct net_device       *net_dev,
4896         IN      OUT     struct ifreq    *rq,
4897         IN      INT                                     cmd)
4898 {
4899         POS_COOKIE                      pObj;
4900         VIRTUAL_ADAPTER         *pVirtualAd = NULL;
4901         RTMP_ADAPTER        *pAd = NULL;
4902         struct iwreq        *wrq = (struct iwreq *) rq;
4903         BOOLEAN                         StateMachineTouched = FALSE;
4904         INT                                     Status = NDIS_STATUS_SUCCESS;
4905         USHORT                          subcmd;
4906
4907         if (net_dev->priv_flags == INT_MAIN)
4908         {
4909                 pAd = net_dev->ml_priv;
4910         }
4911         else
4912         {
4913                 pVirtualAd = net_dev->ml_priv;
4914                 pAd = pVirtualAd->RtmpDev->ml_priv;
4915         }
4916         pObj = (POS_COOKIE) pAd->OS_Cookie;
4917
4918         if (pAd == NULL)
4919         {
4920                 /* if 1st open fail, pAd will be free;
4921                    So the net_dev->ml_priv will be NULL in 2rd open */
4922                 return -ENETDOWN;
4923         }
4924
4925     //check if the interface is down
4926     if(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE))
4927     {
4928         {
4929             DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
4930                     return -ENETDOWN;
4931         }
4932     }
4933
4934         {       // determine this ioctl command is comming from which interface.
4935                 pObj->ioctl_if_type = INT_MAIN;
4936                 pObj->ioctl_if = MAIN_MBSSID;
4937         }
4938
4939         switch(cmd)
4940         {
4941         case SIOCGIFHWADDR:
4942                         DBGPRINT(RT_DEBUG_TRACE, ("IOCTL::SIOCGIFHWADDR\n"));
4943                         memcpy(wrq->u.name, pAd->CurrentAddress, ETH_ALEN);
4944                         break;
4945                 case SIOCGIWNAME:
4946         {
4947                 char *name=&wrq->u.name[0];
4948                 rt_ioctl_giwname(net_dev, NULL, name, NULL);
4949                         break;
4950                 }
4951                 case SIOCGIWESSID:  //Get ESSID
4952         {
4953                 struct iw_point *essid=&wrq->u.essid;
4954                 rt_ioctl_giwessid(net_dev, NULL, essid, essid->pointer);
4955                         break;
4956                 }
4957                 case SIOCSIWESSID:  //Set ESSID
4958         {
4959                 struct iw_point *essid=&wrq->u.essid;
4960                 rt_ioctl_siwessid(net_dev, NULL, essid, essid->pointer);
4961                         break;
4962                 }
4963                 case SIOCSIWNWID:   // set network id (the cell)
4964                 case SIOCGIWNWID:   // get network id
4965                         Status = -EOPNOTSUPP;
4966                         break;
4967                 case SIOCSIWFREQ:   //set channel/frequency (Hz)
4968         {
4969                 struct iw_freq *freq=&wrq->u.freq;
4970                 rt_ioctl_siwfreq(net_dev, NULL, freq, NULL);
4971                         break;
4972                 }
4973                 case SIOCGIWFREQ:   // get channel/frequency (Hz)
4974         {
4975                 struct iw_freq *freq=&wrq->u.freq;
4976                 rt_ioctl_giwfreq(net_dev, NULL, freq, NULL);
4977                         break;
4978                 }
4979                 case SIOCSIWNICKN: //set node name/nickname
4980         {
4981                 struct iw_point *data=&wrq->u.data;
4982                 rt_ioctl_siwnickn(net_dev, NULL, data, NULL);
4983                         break;
4984                 }
4985                 case SIOCGIWNICKN: //get node name/nickname
4986         {
4987                 struct iw_point *data=&wrq->u.data;
4988                 rt_ioctl_giwnickn(net_dev, NULL, data, NULL);
4989                         break;
4990                 }
4991                 case SIOCGIWRATE:   //get default bit rate (bps)
4992                     rt_ioctl_giwrate(net_dev, NULL, &wrq->u, NULL);
4993             break;
4994             case SIOCSIWRATE:  //set default bit rate (bps)
4995                 rt_ioctl_siwrate(net_dev, NULL, &wrq->u, NULL);
4996             break;
4997         case SIOCGIWRTS:  // get RTS/CTS threshold (bytes)
4998         {
4999                 struct iw_param *rts=&wrq->u.rts;
5000                 rt_ioctl_giwrts(net_dev, NULL, rts, NULL);
5001                         break;
5002                 }
5003         case SIOCSIWRTS:  //set RTS/CTS threshold (bytes)
5004         {
5005                 struct iw_param *rts=&wrq->u.rts;
5006                 rt_ioctl_siwrts(net_dev, NULL, rts, NULL);
5007                         break;
5008                 }
5009         case SIOCGIWFRAG:  //get fragmentation thr (bytes)
5010         {
5011                 struct iw_param *frag=&wrq->u.frag;
5012                 rt_ioctl_giwfrag(net_dev, NULL, frag, NULL);
5013                         break;
5014                 }
5015         case SIOCSIWFRAG:  //set fragmentation thr (bytes)
5016         {
5017                 struct iw_param *frag=&wrq->u.frag;
5018                 rt_ioctl_siwfrag(net_dev, NULL, frag, NULL);
5019                         break;
5020                 }
5021         case SIOCGIWENCODE:  //get encoding token & mode
5022         {
5023                 struct iw_point *erq=&wrq->u.encoding;
5024                 if(erq->pointer)
5025                         rt_ioctl_giwencode(net_dev, NULL, erq, erq->pointer);
5026                         break;
5027                 }
5028         case SIOCSIWENCODE:  //set encoding token & mode
5029         {
5030                 struct iw_point *erq=&wrq->u.encoding;
5031                 if(erq->pointer)
5032                         rt_ioctl_siwencode(net_dev, NULL, erq, erq->pointer);
5033                         break;
5034                 }
5035                 case SIOCGIWAP:     //get access point MAC addresses
5036         {
5037                 struct sockaddr *ap_addr=&wrq->u.ap_addr;
5038                 rt_ioctl_giwap(net_dev, NULL, ap_addr, ap_addr->sa_data);
5039                         break;
5040                 }
5041             case SIOCSIWAP:  //set access point MAC addresses
5042         {
5043                 struct sockaddr *ap_addr=&wrq->u.ap_addr;
5044                 rt_ioctl_siwap(net_dev, NULL, ap_addr, ap_addr->sa_data);
5045                         break;
5046                 }
5047                 case SIOCGIWMODE:   //get operation mode
5048         {
5049                 __u32 *mode=&wrq->u.mode;
5050                 rt_ioctl_giwmode(net_dev, NULL, mode, NULL);
5051                         break;
5052                 }
5053                 case SIOCSIWMODE:   //set operation mode
5054         {
5055                 __u32 *mode=&wrq->u.mode;
5056                 rt_ioctl_siwmode(net_dev, NULL, mode, NULL);
5057                         break;
5058                 }
5059                 case SIOCGIWSENS:   //get sensitivity (dBm)
5060                 case SIOCSIWSENS:       //set sensitivity (dBm)
5061                 case SIOCGIWPOWER:  //get Power Management settings
5062                 case SIOCSIWPOWER:  //set Power Management settings
5063                 case SIOCGIWTXPOW:  //get transmit power (dBm)
5064                 case SIOCSIWTXPOW:  //set transmit power (dBm)
5065                 case SIOCGIWRANGE:      //Get range of parameters
5066                 case SIOCGIWRETRY:      //get retry limits and lifetime
5067                 case SIOCSIWRETRY:      //set retry limits and lifetime
5068                         Status = -EOPNOTSUPP;
5069                         break;
5070                 case RT_PRIV_IOCTL:
5071                         subcmd = wrq->u.data.flags;
5072                         if( subcmd & OID_GET_SET_TOGGLE)
5073                                 Status = RTMPSetInformation(pAd, rq, subcmd);
5074                         else
5075                                 Status = RTMPQueryInformation(pAd, rq, subcmd);
5076                         break;
5077                 case SIOCGIWPRIV:
5078                         if (wrq->u.data.pointer)
5079                         {
5080                                 if ( access_ok(VERIFY_WRITE, wrq->u.data.pointer, sizeof(privtab)) != TRUE)
5081                                         break;
5082                                 wrq->u.data.length = sizeof(privtab) / sizeof(privtab[0]);
5083                                 if (copy_to_user(wrq->u.data.pointer, privtab, sizeof(privtab)))
5084                                         Status = -EFAULT;
5085                         }
5086                         break;
5087                 case RTPRIV_IOCTL_SET:
5088                         if(access_ok(VERIFY_READ, wrq->u.data.pointer, wrq->u.data.length) != TRUE)
5089                                 break;
5090                         rt_ioctl_setparam(net_dev, NULL, NULL, wrq->u.data.pointer);
5091                         break;
5092                 case RTPRIV_IOCTL_GSITESURVEY:
5093                         RTMPIoctlGetSiteSurvey(pAd, wrq);
5094                     break;
5095 #ifdef DBG
5096                 case RTPRIV_IOCTL_MAC:
5097                         RTMPIoctlMAC(pAd, wrq);
5098                         break;
5099                 case RTPRIV_IOCTL_E2P:
5100                         RTMPIoctlE2PROM(pAd, wrq);
5101                         break;
5102 #endif // DBG //
5103         case SIOCETHTOOL:
5104                 break;
5105                 default:
5106                         DBGPRINT(RT_DEBUG_ERROR, ("IOCTL::unknown IOCTL's cmd = 0x%08x\n", cmd));
5107                         Status = -EOPNOTSUPP;
5108                         break;
5109         }
5110
5111     if(StateMachineTouched) // Upper layer sent a MLME-related operations
5112         RT28XX_MLME_HANDLER(pAd);
5113
5114         return Status;
5115 }
5116
5117 /*
5118     ==========================================================================
5119     Description:
5120         Set SSID
5121     Return:
5122         TRUE if all parameters are OK, FALSE otherwise
5123     ==========================================================================
5124 */
5125 INT Set_SSID_Proc(
5126     IN  PRTMP_ADAPTER   pAdapter,
5127     IN  PUCHAR          arg)
5128 {
5129     NDIS_802_11_SSID                    Ssid, *pSsid=NULL;
5130     BOOLEAN                             StateMachineTouched = FALSE;
5131     int                                 success = TRUE;
5132
5133     if( strlen(arg) <= MAX_LEN_OF_SSID)
5134     {
5135         NdisZeroMemory(&Ssid, sizeof(NDIS_802_11_SSID));
5136         if (strlen(arg) != 0)
5137         {
5138             NdisMoveMemory(Ssid.Ssid, arg, strlen(arg));
5139             Ssid.SsidLength = strlen(arg);
5140         }
5141         else   //ANY ssid
5142         {
5143             Ssid.SsidLength = 0;
5144                     memcpy(Ssid.Ssid, "", 0);
5145                         pAdapter->StaCfg.BssType = BSS_INFRA;
5146                         pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
5147                 pAdapter->StaCfg.WepStatus  = Ndis802_11EncryptionDisabled;
5148                 }
5149         pSsid = &Ssid;
5150
5151         if (pAdapter->Mlme.CntlMachine.CurrState != CNTL_IDLE)
5152         {
5153             RT28XX_MLME_RESET_STATE_MACHINE(pAdapter);
5154             DBGPRINT(RT_DEBUG_TRACE, ("!!! MLME busy, reset MLME state machine !!!\n"));
5155         }
5156
5157         pAdapter->MlmeAux.CurrReqIsFromNdis = TRUE;
5158         pAdapter->StaCfg.bScanReqIsFromWebUI = FALSE;
5159                 pAdapter->bConfigChanged = TRUE;
5160
5161         MlmeEnqueue(pAdapter,
5162                     MLME_CNTL_STATE_MACHINE,
5163                     OID_802_11_SSID,
5164                     sizeof(NDIS_802_11_SSID),
5165                     (VOID *)pSsid);
5166
5167         StateMachineTouched = TRUE;
5168         DBGPRINT(RT_DEBUG_TRACE, ("Set_SSID_Proc::(Len=%d,Ssid=%s)\n", Ssid.SsidLength, Ssid.Ssid));
5169     }
5170     else
5171         success = FALSE;
5172
5173     if (StateMachineTouched) // Upper layer sent a MLME-related operations
5174         RT28XX_MLME_HANDLER(pAdapter);
5175
5176     return success;
5177 }
5178
5179 #ifdef WMM_SUPPORT
5180 /*
5181     ==========================================================================
5182     Description:
5183         Set WmmCapable Enable or Disable
5184     Return:
5185         TRUE if all parameters are OK, FALSE otherwise
5186     ==========================================================================
5187 */
5188 INT     Set_WmmCapable_Proc(
5189         IN      PRTMP_ADAPTER   pAd,
5190         IN      PUCHAR                  arg)
5191 {
5192         BOOLEAN bWmmCapable;
5193
5194         bWmmCapable = simple_strtol(arg, 0, 10);
5195
5196         if ((bWmmCapable == 1)
5197 #ifdef RT2870
5198                 && (pAd->NumberOfPipes >= 5)
5199 #endif // RT2870 //
5200                 )
5201                 pAd->CommonCfg.bWmmCapable = TRUE;
5202         else if (bWmmCapable == 0)
5203                 pAd->CommonCfg.bWmmCapable = FALSE;
5204         else
5205                 return FALSE;  //Invalid argument
5206
5207         DBGPRINT(RT_DEBUG_TRACE, ("Set_WmmCapable_Proc::(bWmmCapable=%d)\n",
5208                 pAd->CommonCfg.bWmmCapable));
5209
5210         return TRUE;
5211 }
5212 #endif // WMM_SUPPORT //
5213
5214 /*
5215     ==========================================================================
5216     Description:
5217         Set Network Type(Infrastructure/Adhoc mode)
5218     Return:
5219         TRUE if all parameters are OK, FALSE otherwise
5220     ==========================================================================
5221 */
5222 INT Set_NetworkType_Proc(
5223     IN  PRTMP_ADAPTER   pAdapter,
5224     IN  PUCHAR          arg)
5225 {
5226     UINT32      Value = 0;
5227
5228     if (strcmp(arg, "Adhoc") == 0)
5229         {
5230                 if (pAdapter->StaCfg.BssType != BSS_ADHOC)
5231                 {
5232                         // Config has changed
5233                         pAdapter->bConfigChanged = TRUE;
5234             if (MONITOR_ON(pAdapter))
5235             {
5236                 RTMP_IO_WRITE32(pAdapter, RX_FILTR_CFG, STANORMAL);
5237                 RTMP_IO_READ32(pAdapter, MAC_SYS_CTRL, &Value);
5238                                 Value &= (~0x80);
5239                                 RTMP_IO_WRITE32(pAdapter, MAC_SYS_CTRL, Value);
5240                 OPSTATUS_CLEAR_FLAG(pAdapter, fOP_STATUS_MEDIA_STATE_CONNECTED);
5241                 pAdapter->StaCfg.bAutoReconnect = TRUE;
5242                 LinkDown(pAdapter, FALSE);
5243             }
5244                         if (INFRA_ON(pAdapter))
5245                         {
5246                                 //BOOLEAN Cancelled;
5247                                 // Set the AutoReconnectSsid to prevent it reconnect to old SSID
5248                                 // Since calling this indicate user don't want to connect to that SSID anymore.
5249                                 pAdapter->MlmeAux.AutoReconnectSsidLen= 32;
5250                                 NdisZeroMemory(pAdapter->MlmeAux.AutoReconnectSsid, pAdapter->MlmeAux.AutoReconnectSsidLen);
5251
5252                                 LinkDown(pAdapter, FALSE);
5253
5254                                 DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event BB!\n"));
5255                         }
5256                 }
5257                 pAdapter->StaCfg.BssType = BSS_ADHOC;
5258         pAdapter->net_dev->type = pAdapter->StaCfg.OriDevType;
5259                 DBGPRINT(RT_DEBUG_TRACE, ("===>Set_NetworkType_Proc::(AD-HOC)\n"));
5260         }
5261     else if (strcmp(arg, "Infra") == 0)
5262         {
5263                 if (pAdapter->StaCfg.BssType != BSS_INFRA)
5264                 {
5265                         // Config has changed
5266                         pAdapter->bConfigChanged = TRUE;
5267             if (MONITOR_ON(pAdapter))
5268             {
5269                 RTMP_IO_WRITE32(pAdapter, RX_FILTR_CFG, STANORMAL);
5270                 RTMP_IO_READ32(pAdapter, MAC_SYS_CTRL, &Value);
5271                                 Value &= (~0x80);
5272                                 RTMP_IO_WRITE32(pAdapter, MAC_SYS_CTRL, Value);
5273                 OPSTATUS_CLEAR_FLAG(pAdapter, fOP_STATUS_MEDIA_STATE_CONNECTED);
5274                 pAdapter->StaCfg.bAutoReconnect = TRUE;
5275                 LinkDown(pAdapter, FALSE);
5276             }
5277                         if (ADHOC_ON(pAdapter))
5278                         {
5279                                 // Set the AutoReconnectSsid to prevent it reconnect to old SSID
5280                                 // Since calling this indicate user don't want to connect to that SSID anymore.
5281                                 pAdapter->MlmeAux.AutoReconnectSsidLen= 32;
5282                                 NdisZeroMemory(pAdapter->MlmeAux.AutoReconnectSsid, pAdapter->MlmeAux.AutoReconnectSsidLen);
5283
5284                                 LinkDown(pAdapter, FALSE);
5285                         }
5286                 }
5287                 pAdapter->StaCfg.BssType = BSS_INFRA;
5288         pAdapter->net_dev->type = pAdapter->StaCfg.OriDevType;
5289                 DBGPRINT(RT_DEBUG_TRACE, ("===>Set_NetworkType_Proc::(INFRA)\n"));
5290
5291         pAdapter->StaCfg.BssType = BSS_INFRA;
5292         }
5293     else if (strcmp(arg, "Monitor") == 0)
5294     {
5295                 UCHAR   bbpValue = 0;
5296                 BCN_TIME_CFG_STRUC csr;
5297                 OPSTATUS_CLEAR_FLAG(pAdapter, fOP_STATUS_INFRA_ON);
5298         OPSTATUS_CLEAR_FLAG(pAdapter, fOP_STATUS_ADHOC_ON);
5299                 OPSTATUS_SET_FLAG(pAdapter, fOP_STATUS_MEDIA_STATE_CONNECTED);
5300                 // disable all periodic state machine
5301                 pAdapter->StaCfg.bAutoReconnect = FALSE;
5302                 // reset all mlme state machine
5303                 RT28XX_MLME_RESET_STATE_MACHINE(pAdapter);
5304                 DBGPRINT(RT_DEBUG_TRACE, ("fOP_STATUS_MEDIA_STATE_CONNECTED \n"));
5305         if (pAdapter->CommonCfg.CentralChannel == 0)
5306         {
5307             if (pAdapter->CommonCfg.PhyMode == PHY_11AN_MIXED)
5308                 pAdapter->CommonCfg.CentralChannel = 36;
5309             else
5310                 pAdapter->CommonCfg.CentralChannel = 6;
5311         }
5312         else
5313             N_ChannelCheck(pAdapter);
5314
5315         if (pAdapter->CommonCfg.PhyMode >= PHY_11ABGN_MIXED &&
5316             pAdapter->CommonCfg.RegTransmitSetting.field.BW == BW_40 &&
5317             pAdapter->CommonCfg.RegTransmitSetting.field.EXTCHA == EXTCHA_ABOVE)
5318                 {
5319                         // 40MHz ,control channel at lower
5320                         RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R4, &bbpValue);
5321                         bbpValue &= (~0x18);
5322                         bbpValue |= 0x10;
5323                         RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R4, bbpValue);
5324                         pAdapter->CommonCfg.BBPCurrentBW = BW_40;
5325                         //  RX : control channel at lower
5326                         RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R3, &bbpValue);
5327                         bbpValue &= (~0x20);
5328                         RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R3, bbpValue);
5329
5330                         RTMP_IO_READ32(pAdapter, TX_BAND_CFG, &Value);
5331                         Value &= 0xfffffffe;
5332                         RTMP_IO_WRITE32(pAdapter, TX_BAND_CFG, Value);
5333                         pAdapter->CommonCfg.CentralChannel = pAdapter->CommonCfg.Channel + 2;
5334             AsicSwitchChannel(pAdapter, pAdapter->CommonCfg.CentralChannel, FALSE);
5335                     AsicLockChannel(pAdapter, pAdapter->CommonCfg.CentralChannel);
5336             DBGPRINT(RT_DEBUG_TRACE, ("BW_40 ,control_channel(%d), CentralChannel(%d) \n",
5337                                        pAdapter->CommonCfg.Channel,
5338                                        pAdapter->CommonCfg.CentralChannel));
5339                 }
5340                 else if (pAdapter->CommonCfg.PhyMode >= PHY_11ABGN_MIXED &&
5341                  pAdapter->CommonCfg.RegTransmitSetting.field.BW == BW_40 &&
5342                  pAdapter->CommonCfg.RegTransmitSetting.field.EXTCHA == EXTCHA_BELOW)
5343                 {
5344                         // 40MHz ,control channel at upper
5345                         RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R4, &bbpValue);
5346                         bbpValue &= (~0x18);
5347                         bbpValue |= 0x10;
5348                         RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R4, bbpValue);
5349                         pAdapter->CommonCfg.BBPCurrentBW = BW_40;
5350                         RTMP_IO_READ32(pAdapter, TX_BAND_CFG, &Value);
5351                         Value |= 0x1;
5352                         RTMP_IO_WRITE32(pAdapter, TX_BAND_CFG, Value);
5353
5354                         RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R3, &bbpValue);
5355                         bbpValue |= (0x20);
5356                         RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R3, bbpValue);
5357                         pAdapter->CommonCfg.CentralChannel = pAdapter->CommonCfg.Channel - 2;
5358             AsicSwitchChannel(pAdapter, pAdapter->CommonCfg.CentralChannel, FALSE);
5359                     AsicLockChannel(pAdapter, pAdapter->CommonCfg.CentralChannel);
5360             DBGPRINT(RT_DEBUG_TRACE, ("BW_40 ,control_channel(%d), CentralChannel(%d) \n",
5361                                        pAdapter->CommonCfg.Channel,
5362                                        pAdapter->CommonCfg.CentralChannel));
5363                 }
5364                 else
5365                 {
5366                         // 20MHz
5367                         RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R4, &bbpValue);
5368                         bbpValue &= (~0x18);
5369                         RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R4, bbpValue);
5370                         pAdapter->CommonCfg.BBPCurrentBW = BW_20;
5371                         AsicSwitchChannel(pAdapter, pAdapter->CommonCfg.Channel, FALSE);
5372                         AsicLockChannel(pAdapter, pAdapter->CommonCfg.Channel);
5373                         DBGPRINT(RT_DEBUG_TRACE, ("BW_20, Channel(%d)\n", pAdapter->CommonCfg.Channel));
5374                 }
5375                 // Enable Rx with promiscuous reception
5376                 RTMP_IO_WRITE32(pAdapter, RX_FILTR_CFG, 0x3);
5377                 // ASIC supporsts sniffer function with replacing RSSI with timestamp.
5378                 //RTMP_IO_READ32(pAdapter, MAC_SYS_CTRL, &Value);
5379                 //Value |= (0x80);
5380                 //RTMP_IO_WRITE32(pAdapter, MAC_SYS_CTRL, Value);
5381                 // disable sync
5382                 RTMP_IO_READ32(pAdapter, BCN_TIME_CFG, &csr.word);
5383                 csr.field.bBeaconGen = 0;
5384                 csr.field.bTBTTEnable = 0;
5385                 csr.field.TsfSyncMode = 0;
5386                 RTMP_IO_WRITE32(pAdapter, BCN_TIME_CFG, csr.word);
5387
5388                 pAdapter->StaCfg.BssType = BSS_MONITOR;
5389         pAdapter->net_dev->type = ARPHRD_IEEE80211_PRISM; //ARPHRD_IEEE80211; // IEEE80211
5390                 DBGPRINT(RT_DEBUG_TRACE, ("===>Set_NetworkType_Proc::(MONITOR)\n"));
5391     }
5392
5393     // Reset Ralink supplicant to not use, it will be set to start when UI set PMK key
5394     pAdapter->StaCfg.WpaState = SS_NOTUSE;
5395
5396     DBGPRINT(RT_DEBUG_TRACE, ("Set_NetworkType_Proc::(NetworkType=%d)\n", pAdapter->StaCfg.BssType));
5397
5398     return TRUE;
5399 }
5400
5401 /*
5402     ==========================================================================
5403     Description:
5404         Set Authentication mode
5405     Return:
5406         TRUE if all parameters are OK, FALSE otherwise
5407     ==========================================================================
5408 */
5409 INT Set_AuthMode_Proc(
5410     IN  PRTMP_ADAPTER   pAdapter,
5411     IN  PUCHAR          arg)
5412 {
5413     if ((strcmp(arg, "WEPAUTO") == 0) || (strcmp(arg, "wepauto") == 0))
5414         pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeAutoSwitch;
5415     else if ((strcmp(arg, "OPEN") == 0) || (strcmp(arg, "open") == 0))
5416         pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
5417     else if ((strcmp(arg, "SHARED") == 0) || (strcmp(arg, "shared") == 0))
5418         pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeShared;
5419     else if ((strcmp(arg, "WPAPSK") == 0) || (strcmp(arg, "wpapsk") == 0))
5420         pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPAPSK;
5421     else if ((strcmp(arg, "WPANONE") == 0) || (strcmp(arg, "wpanone") == 0))
5422         pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPANone;
5423     else if ((strcmp(arg, "WPA2PSK") == 0) || (strcmp(arg, "wpa2psk") == 0))
5424         pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPA2PSK;
5425     else if ((strcmp(arg, "WPA") == 0) || (strcmp(arg, "wpa") == 0))
5426         pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPA;
5427     else if ((strcmp(arg, "WPA2") == 0) || (strcmp(arg, "wpa2") == 0))
5428         pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPA2;
5429     else
5430         return FALSE;
5431
5432     pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
5433
5434     DBGPRINT(RT_DEBUG_TRACE, ("Set_AuthMode_Proc::(AuthMode=%d)\n", pAdapter->StaCfg.AuthMode));
5435
5436     return TRUE;
5437 }
5438
5439 /*
5440     ==========================================================================
5441     Description:
5442         Set Encryption Type
5443     Return:
5444         TRUE if all parameters are OK, FALSE otherwise
5445     ==========================================================================
5446 */
5447 INT Set_EncrypType_Proc(
5448     IN  PRTMP_ADAPTER   pAdapter,
5449     IN  PUCHAR          arg)
5450 {
5451     if ((strcmp(arg, "NONE") == 0) || (strcmp(arg, "none") == 0))
5452     {
5453         if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
5454             return TRUE;    // do nothing
5455
5456         pAdapter->StaCfg.WepStatus     = Ndis802_11WEPDisabled;
5457         pAdapter->StaCfg.PairCipher    = Ndis802_11WEPDisabled;
5458             pAdapter->StaCfg.GroupCipher   = Ndis802_11WEPDisabled;
5459     }
5460     else if ((strcmp(arg, "WEP") == 0) || (strcmp(arg, "wep") == 0))
5461     {
5462         if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
5463             return TRUE;    // do nothing
5464
5465         pAdapter->StaCfg.WepStatus     = Ndis802_11WEPEnabled;
5466         pAdapter->StaCfg.PairCipher    = Ndis802_11WEPEnabled;
5467             pAdapter->StaCfg.GroupCipher   = Ndis802_11WEPEnabled;
5468     }
5469     else if ((strcmp(arg, "TKIP") == 0) || (strcmp(arg, "tkip") == 0))
5470     {
5471         if (pAdapter->StaCfg.AuthMode < Ndis802_11AuthModeWPA)
5472             return TRUE;    // do nothing
5473
5474         pAdapter->StaCfg.WepStatus     = Ndis802_11Encryption2Enabled;
5475         pAdapter->StaCfg.PairCipher    = Ndis802_11Encryption2Enabled;
5476             pAdapter->StaCfg.GroupCipher   = Ndis802_11Encryption2Enabled;
5477     }
5478     else if ((strcmp(arg, "AES") == 0) || (strcmp(arg, "aes") == 0))
5479     {
5480         if (pAdapter->StaCfg.AuthMode < Ndis802_11AuthModeWPA)
5481             return TRUE;    // do nothing
5482
5483         pAdapter->StaCfg.WepStatus     = Ndis802_11Encryption3Enabled;
5484         pAdapter->StaCfg.PairCipher    = Ndis802_11Encryption3Enabled;
5485             pAdapter->StaCfg.GroupCipher   = Ndis802_11Encryption3Enabled;
5486     }
5487     else
5488         return FALSE;
5489
5490     pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
5491
5492     DBGPRINT(RT_DEBUG_TRACE, ("Set_EncrypType_Proc::(EncrypType=%d)\n", pAdapter->StaCfg.WepStatus));
5493
5494     return TRUE;
5495 }
5496
5497 /*
5498     ==========================================================================
5499     Description:
5500         Set Default Key ID
5501     Return:
5502         TRUE if all parameters are OK, FALSE otherwise
5503     ==========================================================================
5504 */
5505 INT Set_DefaultKeyID_Proc(
5506     IN  PRTMP_ADAPTER   pAdapter,
5507     IN  PUCHAR          arg)
5508 {
5509     ULONG                               KeyIdx;
5510
5511     KeyIdx = simple_strtol(arg, 0, 10);
5512     if((KeyIdx >= 1 ) && (KeyIdx <= 4))
5513         pAdapter->StaCfg.DefaultKeyId = (UCHAR) (KeyIdx - 1 );
5514     else
5515         return FALSE;  //Invalid argument
5516
5517     DBGPRINT(RT_DEBUG_TRACE, ("Set_DefaultKeyID_Proc::(DefaultKeyID=%d)\n", pAdapter->StaCfg.DefaultKeyId));
5518
5519     return TRUE;
5520 }
5521
5522 /*
5523     ==========================================================================
5524     Description:
5525         Set WEP KEY1
5526     Return:
5527         TRUE if all parameters are OK, FALSE otherwise
5528     ==========================================================================
5529 */
5530 INT Set_Key1_Proc(
5531     IN  PRTMP_ADAPTER   pAdapter,
5532     IN  PUCHAR          arg)
5533 {
5534     int                                 KeyLen;
5535     int                                 i;
5536     UCHAR                               CipherAlg=CIPHER_WEP64;
5537
5538     if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
5539         return TRUE;    // do nothing
5540
5541     KeyLen = strlen(arg);
5542
5543     switch (KeyLen)
5544     {
5545         case 5: //wep 40 Ascii type
5546             pAdapter->SharedKey[BSS0][0].KeyLen = KeyLen;
5547             memcpy(pAdapter->SharedKey[BSS0][0].Key, arg, KeyLen);
5548             CipherAlg = CIPHER_WEP64;
5549             DBGPRINT(RT_DEBUG_TRACE, ("Set_Key1_Proc::(Key1=%s and type=%s)\n", arg, "Ascii"));
5550             break;
5551         case 10: //wep 40 Hex type
5552             for(i=0; i < KeyLen; i++)
5553             {
5554                 if( !isxdigit(*(arg+i)) )
5555                     return FALSE;  //Not Hex value;
5556             }
5557             pAdapter->SharedKey[BSS0][0].KeyLen = KeyLen / 2 ;
5558             AtoH(arg, pAdapter->SharedKey[BSS0][0].Key, KeyLen / 2);
5559             CipherAlg = CIPHER_WEP64;
5560             DBGPRINT(RT_DEBUG_TRACE, ("Set_Key1_Proc::(Key1=%s and type=%s)\n", arg, "Hex"));
5561             break;
5562         case 13: //wep 104 Ascii type
5563             pAdapter->SharedKey[BSS0][0].KeyLen = KeyLen;
5564             memcpy(pAdapter->SharedKey[BSS0][0].Key, arg, KeyLen);
5565             CipherAlg = CIPHER_WEP128;
5566             DBGPRINT(RT_DEBUG_TRACE, ("Set_Key1_Proc::(Key1=%s and type=%s)\n", arg, "Ascii"));
5567             break;
5568         case 26: //wep 104 Hex type
5569             for(i=0; i < KeyLen; i++)
5570             {
5571                 if( !isxdigit(*(arg+i)) )
5572                     return FALSE;  //Not Hex value;
5573             }
5574             pAdapter->SharedKey[BSS0][0].KeyLen = KeyLen / 2 ;
5575             AtoH(arg, pAdapter->SharedKey[BSS0][0].Key, KeyLen / 2);
5576             CipherAlg = CIPHER_WEP128;
5577             DBGPRINT(RT_DEBUG_TRACE, ("Set_Key1_Proc::(Key1=%s and type=%s)\n", arg, "Hex"));
5578             break;
5579         default: //Invalid argument
5580             DBGPRINT(RT_DEBUG_TRACE, ("Set_Key1_Proc::Invalid argument (=%s)\n", arg));
5581             return FALSE;
5582     }
5583
5584     pAdapter->SharedKey[BSS0][0].CipherAlg = CipherAlg;
5585
5586     // Set keys (into ASIC)
5587     if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
5588         ;   // not support
5589     else    // Old WEP stuff
5590     {
5591         AsicAddSharedKeyEntry(pAdapter,
5592                               0,
5593                               0,
5594                               pAdapter->SharedKey[BSS0][0].CipherAlg,
5595                               pAdapter->SharedKey[BSS0][0].Key,
5596                               NULL,
5597                               NULL);
5598     }
5599
5600     return TRUE;
5601 }
5602 /*
5603     ==========================================================================
5604
5605     Description:
5606         Set WEP KEY2
5607     Return:
5608         TRUE if all parameters are OK, FALSE otherwise
5609     ==========================================================================
5610 */
5611 INT Set_Key2_Proc(
5612     IN  PRTMP_ADAPTER   pAdapter,
5613     IN  PUCHAR          arg)
5614 {
5615     int                                 KeyLen;
5616     int                                 i;
5617     UCHAR                               CipherAlg=CIPHER_WEP64;
5618
5619     if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
5620         return TRUE;    // do nothing
5621
5622     KeyLen = strlen(arg);
5623
5624     switch (KeyLen)
5625     {
5626         case 5: //wep 40 Ascii type
5627             pAdapter->SharedKey[BSS0][1].KeyLen = KeyLen;
5628             memcpy(pAdapter->SharedKey[BSS0][1].Key, arg, KeyLen);
5629             CipherAlg = CIPHER_WEP64;
5630             DBGPRINT(RT_DEBUG_TRACE, ("Set_Key2_Proc::(Key2=%s and type=%s)\n", arg, "Ascii"));
5631             break;
5632         case 10: //wep 40 Hex type
5633             for(i=0; i < KeyLen; i++)
5634             {
5635                 if( !isxdigit(*(arg+i)) )
5636                     return FALSE;  //Not Hex value;
5637             }
5638             pAdapter->SharedKey[BSS0][1].KeyLen = KeyLen / 2 ;
5639             AtoH(arg, pAdapter->SharedKey[BSS0][1].Key, KeyLen / 2);
5640             CipherAlg = CIPHER_WEP64;
5641             DBGPRINT(RT_DEBUG_TRACE, ("Set_Key2_Proc::(Key2=%s and type=%s)\n", arg, "Hex"));
5642             break;
5643         case 13: //wep 104 Ascii type
5644             pAdapter->SharedKey[BSS0][1].KeyLen = KeyLen;
5645             memcpy(pAdapter->SharedKey[BSS0][1].Key, arg, KeyLen);
5646             CipherAlg = CIPHER_WEP128;
5647             DBGPRINT(RT_DEBUG_TRACE, ("Set_Key2_Proc::(Key2=%s and type=%s)\n", arg, "Ascii"));
5648             break;
5649         case 26: //wep 104 Hex type
5650             for(i=0; i < KeyLen; i++)
5651             {
5652                 if( !isxdigit(*(arg+i)) )
5653                     return FALSE;  //Not Hex value;
5654             }
5655             pAdapter->SharedKey[BSS0][1].KeyLen = KeyLen / 2 ;
5656             AtoH(arg, pAdapter->SharedKey[BSS0][1].Key, KeyLen / 2);
5657             CipherAlg = CIPHER_WEP128;
5658             DBGPRINT(RT_DEBUG_TRACE, ("Set_Key2_Proc::(Key2=%s and type=%s)\n", arg, "Hex"));
5659             break;
5660         default: //Invalid argument
5661             DBGPRINT(RT_DEBUG_TRACE, ("Set_Key2_Proc::Invalid argument (=%s)\n", arg));
5662             return FALSE;
5663     }
5664     pAdapter->SharedKey[BSS0][1].CipherAlg = CipherAlg;
5665
5666     // Set keys (into ASIC)
5667     if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
5668         ;   // not support
5669     else    // Old WEP stuff
5670     {
5671         AsicAddSharedKeyEntry(pAdapter,
5672                               0,
5673                               1,
5674                               pAdapter->SharedKey[BSS0][1].CipherAlg,
5675                               pAdapter->SharedKey[BSS0][1].Key,
5676                               NULL,
5677                               NULL);
5678     }
5679
5680     return TRUE;
5681 }
5682 /*
5683     ==========================================================================
5684     Description:
5685         Set WEP KEY3
5686     Return:
5687         TRUE if all parameters are OK, FALSE otherwise
5688     ==========================================================================
5689 */
5690 INT Set_Key3_Proc(
5691     IN  PRTMP_ADAPTER   pAdapter,
5692     IN  PUCHAR          arg)
5693 {
5694     int                                 KeyLen;
5695     int                                 i;
5696     UCHAR                               CipherAlg=CIPHER_WEP64;
5697
5698     if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
5699         return TRUE;    // do nothing
5700
5701     KeyLen = strlen(arg);
5702
5703     switch (KeyLen)
5704     {
5705         case 5: //wep 40 Ascii type
5706             pAdapter->SharedKey[BSS0][2].KeyLen = KeyLen;
5707             memcpy(pAdapter->SharedKey[BSS0][2].Key, arg, KeyLen);
5708             CipherAlg = CIPHER_WEP64;
5709             DBGPRINT(RT_DEBUG_TRACE, ("Set_Key3_Proc::(Key3=%s and type=Ascii)\n", arg));
5710             break;
5711         case 10: //wep 40 Hex type
5712             for(i=0; i < KeyLen; i++)
5713             {
5714                 if( !isxdigit(*(arg+i)) )
5715                     return FALSE;  //Not Hex value;
5716             }
5717             pAdapter->SharedKey[BSS0][2].KeyLen = KeyLen / 2 ;
5718             AtoH(arg, pAdapter->SharedKey[BSS0][2].Key, KeyLen / 2);
5719             CipherAlg = CIPHER_WEP64;
5720             DBGPRINT(RT_DEBUG_TRACE, ("Set_Key3_Proc::(Key3=%s and type=Hex)\n", arg));
5721             break;
5722         case 13: //wep 104 Ascii type
5723             pAdapter->SharedKey[BSS0][2].KeyLen = KeyLen;
5724             memcpy(pAdapter->SharedKey[BSS0][2].Key, arg, KeyLen);
5725             CipherAlg = CIPHER_WEP128;
5726             DBGPRINT(RT_DEBUG_TRACE, ("Set_Key3_Proc::(Key3=%s and type=Ascii)\n", arg));
5727             break;
5728         case 26: //wep 104 Hex type
5729             for(i=0; i < KeyLen; i++)
5730             {
5731                 if( !isxdigit(*(arg+i)) )
5732                     return FALSE;  //Not Hex value;
5733             }
5734             pAdapter->SharedKey[BSS0][2].KeyLen = KeyLen / 2 ;
5735             AtoH(arg, pAdapter->SharedKey[BSS0][2].Key, KeyLen / 2);
5736             CipherAlg = CIPHER_WEP128;
5737             DBGPRINT(RT_DEBUG_TRACE, ("Set_Key3_Proc::(Key3=%s and type=Hex)\n", arg));
5738             break;
5739         default: //Invalid argument
5740             DBGPRINT(RT_DEBUG_TRACE, ("Set_Key3_Proc::Invalid argument (=%s)\n", arg));
5741             return FALSE;
5742     }
5743     pAdapter->SharedKey[BSS0][2].CipherAlg = CipherAlg;
5744
5745     // Set keys (into ASIC)
5746     if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
5747         ;   // not support
5748     else    // Old WEP stuff
5749     {
5750         AsicAddSharedKeyEntry(pAdapter,
5751                               0,
5752                               2,
5753                               pAdapter->SharedKey[BSS0][2].CipherAlg,
5754                               pAdapter->SharedKey[BSS0][2].Key,
5755                               NULL,
5756                               NULL);
5757     }
5758
5759     return TRUE;
5760 }
5761 /*
5762     ==========================================================================
5763     Description:
5764         Set WEP KEY4
5765     Return:
5766         TRUE if all parameters are OK, FALSE otherwise
5767     ==========================================================================
5768 */
5769 INT Set_Key4_Proc(
5770     IN  PRTMP_ADAPTER   pAdapter,
5771     IN  PUCHAR          arg)
5772 {
5773     int                                 KeyLen;
5774     int                                 i;
5775     UCHAR                               CipherAlg=CIPHER_WEP64;
5776
5777     if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
5778         return TRUE;    // do nothing
5779
5780     KeyLen = strlen(arg);
5781
5782     switch (KeyLen)
5783     {
5784         case 5: //wep 40 Ascii type
5785             pAdapter->SharedKey[BSS0][3].KeyLen = KeyLen;
5786             memcpy(pAdapter->SharedKey[BSS0][3].Key, arg, KeyLen);
5787             CipherAlg = CIPHER_WEP64;
5788             DBGPRINT(RT_DEBUG_TRACE, ("Set_Key4_Proc::(Key4=%s and type=%s)\n", arg, "Ascii"));
5789             break;
5790         case 10: //wep 40 Hex type
5791             for(i=0; i < KeyLen; i++)
5792             {
5793                 if( !isxdigit(*(arg+i)) )
5794                     return FALSE;  //Not Hex value;
5795             }
5796             pAdapter->SharedKey[BSS0][3].KeyLen = KeyLen / 2 ;
5797             AtoH(arg, pAdapter->SharedKey[BSS0][3].Key, KeyLen / 2);
5798             CipherAlg = CIPHER_WEP64;
5799             DBGPRINT(RT_DEBUG_TRACE, ("Set_Key4_Proc::(Key4=%s and type=%s)\n", arg, "Hex"));
5800             break;
5801         case 13: //wep 104 Ascii type
5802             pAdapter->SharedKey[BSS0][3].KeyLen = KeyLen;
5803             memcpy(pAdapter->SharedKey[BSS0][3].Key, arg, KeyLen);
5804             CipherAlg = CIPHER_WEP128;
5805             DBGPRINT(RT_DEBUG_TRACE, ("Set_Key4_Proc::(Key4=%s and type=%s)\n", arg, "Ascii"));
5806             break;
5807         case 26: //wep 104 Hex type
5808             for(i=0; i < KeyLen; i++)
5809             {
5810                 if( !isxdigit(*(arg+i)) )
5811                     return FALSE;  //Not Hex value;
5812             }
5813             pAdapter->SharedKey[BSS0][3].KeyLen = KeyLen / 2 ;
5814             AtoH(arg, pAdapter->SharedKey[BSS0][3].Key, KeyLen / 2);
5815             CipherAlg = CIPHER_WEP128;
5816             DBGPRINT(RT_DEBUG_TRACE, ("Set_Key4_Proc::(Key4=%s and type=%s)\n", arg, "Hex"));
5817             break;
5818         default: //Invalid argument
5819             DBGPRINT(RT_DEBUG_TRACE, ("Set_Key4_Proc::Invalid argument (=%s)\n", arg));
5820             return FALSE;
5821     }
5822     pAdapter->SharedKey[BSS0][3].CipherAlg = CipherAlg;
5823
5824     // Set keys (into ASIC)
5825     if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
5826         ;   // not support
5827     else    // Old WEP stuff
5828     {
5829         AsicAddSharedKeyEntry(pAdapter,
5830                               0,
5831                               3,
5832                               pAdapter->SharedKey[BSS0][3].CipherAlg,
5833                               pAdapter->SharedKey[BSS0][3].Key,
5834                               NULL,
5835                               NULL);
5836     }
5837
5838     return TRUE;
5839 }
5840
5841 /*
5842     ==========================================================================
5843     Description:
5844         Set WPA PSK key
5845     Return:
5846         TRUE if all parameters are OK, FALSE otherwise
5847     ==========================================================================
5848 */
5849 INT Set_WPAPSK_Proc(
5850     IN  PRTMP_ADAPTER   pAdapter,
5851     IN  PUCHAR          arg)
5852 {
5853     UCHAR                   keyMaterial[40];
5854
5855     if ((pAdapter->StaCfg.AuthMode != Ndis802_11AuthModeWPAPSK) &&
5856         (pAdapter->StaCfg.AuthMode != Ndis802_11AuthModeWPA2PSK) &&
5857             (pAdapter->StaCfg.AuthMode != Ndis802_11AuthModeWPANone)
5858                 )
5859         return TRUE;    // do nothing
5860
5861     DBGPRINT(RT_DEBUG_TRACE, ("Set_WPAPSK_Proc::(WPAPSK=%s)\n", arg));
5862
5863     NdisZeroMemory(keyMaterial, 40);
5864
5865     if ((strlen(arg) < 8) || (strlen(arg) > 64))
5866     {
5867         DBGPRINT(RT_DEBUG_TRACE, ("Set failed!!(WPAPSK=%s), WPAPSK key-string required 8 ~ 64 characters \n", arg));
5868         return FALSE;
5869     }
5870
5871     if (strlen(arg) == 64)
5872     {
5873         AtoH(arg, keyMaterial, 32);
5874         NdisMoveMemory(pAdapter->StaCfg.PMK, keyMaterial, 32);
5875
5876     }
5877     else
5878     {
5879         PasswordHash((char *)arg, pAdapter->MlmeAux.Ssid, pAdapter->MlmeAux.SsidLen, keyMaterial);
5880         NdisMoveMemory(pAdapter->StaCfg.PMK, keyMaterial, 32);
5881     }
5882
5883
5884
5885     if(pAdapter->StaCfg.BssType == BSS_ADHOC &&
5886        pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
5887     {
5888          pAdapter->StaCfg.WpaState = SS_NOTUSE;
5889     }
5890     else
5891     {
5892         // Start STA supplicant state machine
5893         pAdapter->StaCfg.WpaState = SS_START;
5894     }
5895
5896     return TRUE;
5897 }
5898
5899 /*
5900     ==========================================================================
5901     Description:
5902         Set Power Saving mode
5903     Return:
5904         TRUE if all parameters are OK, FALSE otherwise
5905     ==========================================================================
5906 */
5907 INT Set_PSMode_Proc(
5908     IN  PRTMP_ADAPTER   pAdapter,
5909     IN  PUCHAR          arg)
5910 {
5911     if (pAdapter->StaCfg.BssType == BSS_INFRA)
5912     {
5913         if ((strcmp(arg, "Max_PSP") == 0) ||
5914                         (strcmp(arg, "max_psp") == 0) ||
5915                         (strcmp(arg, "MAX_PSP") == 0))
5916         {
5917             // do NOT turn on PSM bit here, wait until MlmeCheckForPsmChange()
5918             // to exclude certain situations.
5919             if (pAdapter->StaCfg.bWindowsACCAMEnable == FALSE)
5920                 pAdapter->StaCfg.WindowsPowerMode = Ndis802_11PowerModeMAX_PSP;
5921             pAdapter->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeMAX_PSP;
5922             OPSTATUS_SET_FLAG(pAdapter, fOP_STATUS_RECEIVE_DTIM);
5923             pAdapter->StaCfg.DefaultListenCount = 5;
5924
5925         }
5926         else if ((strcmp(arg, "Fast_PSP") == 0) ||
5927                                  (strcmp(arg, "fast_psp") == 0) ||
5928                  (strcmp(arg, "FAST_PSP") == 0))
5929         {
5930             // do NOT turn on PSM bit here, wait until MlmeCheckForPsmChange()
5931             // to exclude certain situations.
5932             OPSTATUS_SET_FLAG(pAdapter, fOP_STATUS_RECEIVE_DTIM);
5933             if (pAdapter->StaCfg.bWindowsACCAMEnable == FALSE)
5934                 pAdapter->StaCfg.WindowsPowerMode = Ndis802_11PowerModeFast_PSP;
5935             pAdapter->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeFast_PSP;
5936             pAdapter->StaCfg.DefaultListenCount = 3;
5937         }
5938         else if ((strcmp(arg, "Legacy_PSP") == 0) ||
5939                  (strcmp(arg, "legacy_psp") == 0) ||
5940                  (strcmp(arg, "LEGACY_PSP") == 0))
5941         {
5942             // do NOT turn on PSM bit here, wait until MlmeCheckForPsmChange()
5943             // to exclude certain situations.
5944             OPSTATUS_SET_FLAG(pAdapter, fOP_STATUS_RECEIVE_DTIM);
5945             if (pAdapter->StaCfg.bWindowsACCAMEnable == FALSE)
5946                 pAdapter->StaCfg.WindowsPowerMode = Ndis802_11PowerModeLegacy_PSP;
5947             pAdapter->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeLegacy_PSP;
5948             pAdapter->StaCfg.DefaultListenCount = 3;
5949         }
5950         else
5951         {
5952             //Default Ndis802_11PowerModeCAM
5953             // clear PSM bit immediately
5954             MlmeSetPsmBit(pAdapter, PWR_ACTIVE);
5955             OPSTATUS_SET_FLAG(pAdapter, fOP_STATUS_RECEIVE_DTIM);
5956             if (pAdapter->StaCfg.bWindowsACCAMEnable == FALSE)
5957                 pAdapter->StaCfg.WindowsPowerMode = Ndis802_11PowerModeCAM;
5958             pAdapter->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeCAM;
5959         }
5960
5961         DBGPRINT(RT_DEBUG_TRACE, ("Set_PSMode_Proc::(PSMode=%ld)\n", pAdapter->StaCfg.WindowsPowerMode));
5962     }
5963     else
5964         return FALSE;
5965
5966
5967     return TRUE;
5968 }
5969
5970 /*
5971     ==========================================================================
5972     Description:
5973         Set WpaSupport flag.
5974     Value:
5975         0: Driver ignore wpa_supplicant.
5976         1: wpa_supplicant initiates scanning and AP selection.
5977         2: driver takes care of scanning, AP selection, and IEEE 802.11 association parameters.
5978     Return:
5979         TRUE if all parameters are OK, FALSE otherwise
5980     ==========================================================================
5981 */
5982 INT Set_Wpa_Support(
5983     IN  PRTMP_ADAPTER   pAd,
5984         IN      PUCHAR                  arg)
5985 {
5986
5987     if ( simple_strtol(arg, 0, 10) == 0)
5988         pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_DISABLE;
5989     else if ( simple_strtol(arg, 0, 10) == 1)
5990         pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_ENABLE;
5991     else if ( simple_strtol(arg, 0, 10) == 2)
5992         pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_ENABLE_WITH_WEB_UI;
5993     else
5994         pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_DISABLE;
5995
5996     DBGPRINT(RT_DEBUG_TRACE, ("Set_Wpa_Support::(WpaSupplicantUP=%d)\n", pAd->StaCfg.WpaSupplicantUP));
5997
5998     return TRUE;
5999 }
6000
6001 #ifdef DBG
6002 /*
6003     ==========================================================================
6004     Description:
6005         Read / Write MAC
6006     Arguments:
6007         pAdapter                    Pointer to our adapter
6008         wrq                         Pointer to the ioctl argument
6009
6010     Return Value:
6011         None
6012
6013     Note:
6014         Usage:
6015                1.) iwpriv ra0 mac 0        ==> read MAC where Addr=0x0
6016                2.) iwpriv ra0 mac 0=12     ==> write MAC where Addr=0x0, value=12
6017     ==========================================================================
6018 */
6019 VOID RTMPIoctlMAC(
6020         IN      PRTMP_ADAPTER   pAdapter,
6021         IN      struct iwreq    *wrq)
6022 {
6023         CHAR                            *this_char;
6024         CHAR                            *value;
6025         INT                                     j = 0, k = 0;
6026         CHAR                            msg[1024];
6027         CHAR                            arg[255];
6028         ULONG                           macAddr = 0;
6029         UCHAR                           temp[16], temp2[16];
6030         UINT32                          macValue = 0;
6031         INT                                     Status;
6032
6033
6034         memset(msg, 0x00, 1024);
6035         if (wrq->u.data.length > 1) //No parameters.
6036         {
6037             Status = copy_from_user(arg, wrq->u.data.pointer, (wrq->u.data.length > 255) ? 255 : wrq->u.data.length);
6038                 sprintf(msg, "\n");
6039
6040                 //Parsing Read or Write
6041             this_char = arg;
6042                 if (!*this_char)
6043                         goto next;
6044
6045                 if ((value = rtstrchr(this_char, '=')) != NULL)
6046                         *value++ = 0;
6047
6048                 if (!value || !*value)
6049                 { //Read
6050                         // Sanity check
6051                         if(strlen(this_char) > 4)
6052                                 goto next;
6053
6054                         j = strlen(this_char);
6055                         while(j-- > 0)
6056                         {
6057                                 if(this_char[j] > 'f' || this_char[j] < '0')
6058                                         return;
6059                         }
6060
6061                         // Mac Addr
6062                         k = j = strlen(this_char);
6063                         while(j-- > 0)
6064                         {
6065                                 this_char[4-k+j] = this_char[j];
6066                         }
6067
6068                         while(k < 4)
6069                                 this_char[3-k++]='0';
6070                         this_char[4]='\0';
6071
6072                         if(strlen(this_char) == 4)
6073                         {
6074                                 AtoH(this_char, temp, 2);
6075                                 macAddr = *temp*256 + temp[1];
6076                                 if (macAddr < 0xFFFF)
6077                                 {
6078                                         RTMP_IO_READ32(pAdapter, macAddr, &macValue);
6079                                         DBGPRINT(RT_DEBUG_TRACE, ("MacAddr=%lx, MacValue=%x\n", macAddr, macValue));
6080                                         sprintf(msg+strlen(msg), "[0x%08lX]:%08X  ", macAddr , macValue);
6081                                 }
6082                                 else
6083                                 {//Invalid parametes, so default printk all bbp
6084                                         goto next;
6085                                 }
6086                         }
6087                 }
6088                 else
6089                 { //Write
6090                         memcpy(&temp2, value, strlen(value));
6091                         temp2[strlen(value)] = '\0';
6092
6093                         // Sanity check
6094                         if((strlen(this_char) > 4) || strlen(temp2) > 8)
6095                                 goto next;
6096
6097                         j = strlen(this_char);
6098                         while(j-- > 0)
6099                         {
6100                                 if(this_char[j] > 'f' || this_char[j] < '0')
6101                                         return;
6102                         }
6103
6104                         j = strlen(temp2);
6105                         while(j-- > 0)
6106                         {
6107                                 if(temp2[j] > 'f' || temp2[j] < '0')
6108                                         return;
6109                         }
6110
6111                         //MAC Addr
6112                         k = j = strlen(this_char);
6113                         while(j-- > 0)
6114                         {
6115                                 this_char[4-k+j] = this_char[j];
6116                         }
6117
6118                         while(k < 4)
6119                                 this_char[3-k++]='0';
6120                         this_char[4]='\0';
6121
6122                         //MAC value
6123                         k = j = strlen(temp2);
6124                         while(j-- > 0)
6125                         {
6126                                 temp2[8-k+j] = temp2[j];
6127                         }
6128
6129                         while(k < 8)
6130                                 temp2[7-k++]='0';
6131                         temp2[8]='\0';
6132
6133                         {
6134                                 AtoH(this_char, temp, 2);
6135                                 macAddr = *temp*256 + temp[1];
6136
6137                                 AtoH(temp2, temp, 4);
6138                                 macValue = *temp*256*256*256 + temp[1]*256*256 + temp[2]*256 + temp[3];
6139
6140                                 // debug mode
6141                                 if (macAddr == (HW_DEBUG_SETTING_BASE + 4))
6142                                 {
6143                                         // 0x2bf4: byte0 non-zero: enable R17 tuning, 0: disable R17 tuning
6144                     if (macValue & 0x000000ff)
6145                     {
6146                         pAdapter->BbpTuning.bEnable = TRUE;
6147                         DBGPRINT(RT_DEBUG_TRACE,("turn on R17 tuning\n"));
6148                     }
6149                     else
6150                     {
6151                         UCHAR R66;
6152                         pAdapter->BbpTuning.bEnable = FALSE;
6153                         R66 = 0x26 + GET_LNA_GAIN(pAdapter);
6154                                                 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R66, (0x26 + GET_LNA_GAIN(pAdapter)));
6155                         DBGPRINT(RT_DEBUG_TRACE,("turn off R17 tuning, restore to 0x%02x\n", R66));
6156                     }
6157                                         return;
6158                                 }
6159
6160                                 DBGPRINT(RT_DEBUG_TRACE, ("MacAddr=%02lx, MacValue=0x%x\n", macAddr, macValue));
6161
6162                                 RTMP_IO_WRITE32(pAdapter, macAddr, macValue);
6163                                 sprintf(msg+strlen(msg), "[0x%08lX]:%08X  ", macAddr, macValue);
6164                         }
6165                 }
6166         }
6167 next:
6168         if(strlen(msg) == 1)
6169                 sprintf(msg+strlen(msg), "===>Error command format!");
6170
6171         // Copy the information into the user buffer
6172         wrq->u.data.length = strlen(msg);
6173         Status = copy_to_user(wrq->u.data.pointer, msg, wrq->u.data.length);
6174
6175         DBGPRINT(RT_DEBUG_TRACE, ("<==RTMPIoctlMAC\n\n"));
6176 }
6177
6178 /*
6179     ==========================================================================
6180     Description:
6181         Read / Write E2PROM
6182     Arguments:
6183         pAdapter                    Pointer to our adapter
6184         wrq                         Pointer to the ioctl argument
6185
6186     Return Value:
6187         None
6188
6189     Note:
6190         Usage:
6191                1.) iwpriv ra0 e2p 0             ==> read E2PROM where Addr=0x0
6192                2.) iwpriv ra0 e2p 0=1234    ==> write E2PROM where Addr=0x0, value=1234
6193     ==========================================================================
6194 */
6195 VOID RTMPIoctlE2PROM(
6196         IN      PRTMP_ADAPTER   pAdapter,
6197         IN      struct iwreq    *wrq)
6198 {
6199         CHAR                            *this_char;
6200         CHAR                            *value;
6201         INT                                     j = 0, k = 0;
6202         CHAR                            msg[1024];
6203         CHAR                            arg[255];
6204         USHORT                          eepAddr = 0;
6205         UCHAR                           temp[16], temp2[16];
6206         USHORT                          eepValue;
6207         int                                     Status;
6208
6209
6210         memset(msg, 0x00, 1024);
6211         if (wrq->u.data.length > 1) //No parameters.
6212         {
6213             Status = copy_from_user(arg, wrq->u.data.pointer, (wrq->u.data.length > 255) ? 255 : wrq->u.data.length);
6214                 sprintf(msg, "\n");
6215
6216             //Parsing Read or Write
6217                 this_char = arg;
6218
6219
6220                 if (!*this_char)
6221                         goto next;
6222
6223                 if ((value = rtstrchr(this_char, '=')) != NULL)
6224                         *value++ = 0;
6225
6226                 if (!value || !*value)
6227                 { //Read
6228
6229                         // Sanity check
6230                         if(strlen(this_char) > 4)
6231                                 goto next;
6232
6233                         j = strlen(this_char);
6234                         while(j-- > 0)
6235                         {
6236                                 if(this_char[j] > 'f' || this_char[j] < '0')
6237                                         return;
6238                         }
6239
6240                         // E2PROM addr
6241                         k = j = strlen(this_char);
6242                         while(j-- > 0)
6243                         {
6244                                 this_char[4-k+j] = this_char[j];
6245                         }
6246
6247                         while(k < 4)
6248                                 this_char[3-k++]='0';
6249                         this_char[4]='\0';
6250
6251                         if(strlen(this_char) == 4)
6252                         {
6253                                 AtoH(this_char, temp, 2);
6254                                 eepAddr = *temp*256 + temp[1];
6255                                 if (eepAddr < 0xFFFF)
6256                                 {
6257                                         RT28xx_EEPROM_READ16(pAdapter, eepAddr, eepValue);
6258                                         sprintf(msg+strlen(msg), "[0x%04X]:0x%04X  ", eepAddr , eepValue);
6259                                 }
6260                                 else
6261                                 {//Invalid parametes, so default printk all bbp
6262                                         goto next;
6263                                 }
6264                         }
6265                 }
6266                 else
6267                 { //Write
6268                         memcpy(&temp2, value, strlen(value));
6269                         temp2[strlen(value)] = '\0';
6270
6271                         // Sanity check
6272                         if((strlen(this_char) > 4) || strlen(temp2) > 8)
6273                                 goto next;
6274
6275                         j = strlen(this_char);
6276                         while(j-- > 0)
6277                         {
6278                                 if(this_char[j] > 'f' || this_char[j] < '0')
6279                                         return;
6280                         }
6281                         j = strlen(temp2);
6282                         while(j-- > 0)
6283                         {
6284                                 if(temp2[j] > 'f' || temp2[j] < '0')
6285                                         return;
6286                         }
6287
6288                         //MAC Addr
6289                         k = j = strlen(this_char);
6290                         while(j-- > 0)
6291                         {
6292                                 this_char[4-k+j] = this_char[j];
6293                         }
6294
6295                         while(k < 4)
6296                                 this_char[3-k++]='0';
6297                         this_char[4]='\0';
6298
6299                         //MAC value
6300                         k = j = strlen(temp2);
6301                         while(j-- > 0)
6302                         {
6303                                 temp2[4-k+j] = temp2[j];
6304                         }
6305
6306                         while(k < 4)
6307                                 temp2[3-k++]='0';
6308                         temp2[4]='\0';
6309
6310                         AtoH(this_char, temp, 2);
6311                         eepAddr = *temp*256 + temp[1];
6312
6313                         AtoH(temp2, temp, 2);
6314                         eepValue = *temp*256 + temp[1];
6315
6316                         RT28xx_EEPROM_WRITE16(pAdapter, eepAddr, eepValue);
6317                         sprintf(msg+strlen(msg), "[0x%02X]:%02X  ", eepAddr, eepValue);
6318                 }
6319         }
6320 next:
6321         if(strlen(msg) == 1)
6322                 sprintf(msg+strlen(msg), "===>Error command format!");
6323
6324
6325         // Copy the information into the user buffer
6326         wrq->u.data.length = strlen(msg);
6327         Status = copy_to_user(wrq->u.data.pointer, msg, wrq->u.data.length);
6328
6329         DBGPRINT(RT_DEBUG_TRACE, ("<==RTMPIoctlE2PROM\n"));
6330 }
6331 #endif // DBG //
6332
6333
6334
6335
6336 INT Set_TGnWifiTest_Proc(
6337     IN  PRTMP_ADAPTER   pAd,
6338     IN  PUCHAR          arg)
6339 {
6340     if (simple_strtol(arg, 0, 10) == 0)
6341         pAd->StaCfg.bTGnWifiTest = FALSE;
6342     else
6343         pAd->StaCfg.bTGnWifiTest = TRUE;
6344
6345     DBGPRINT(RT_DEBUG_TRACE, ("IF Set_TGnWifiTest_Proc::(bTGnWifiTest=%d)\n", pAd->StaCfg.bTGnWifiTest));
6346         return TRUE;
6347 }
6348
6349 INT Set_LongRetryLimit_Proc(
6350         IN      PRTMP_ADAPTER   pAdapter,
6351         IN      PUCHAR                  arg)
6352 {
6353         TX_RTY_CFG_STRUC        tx_rty_cfg;
6354         UCHAR                           LongRetryLimit = (UCHAR)simple_strtol(arg, 0, 10);
6355
6356         RTMP_IO_READ32(pAdapter, TX_RTY_CFG, &tx_rty_cfg.word);
6357         tx_rty_cfg.field.LongRtyLimit = LongRetryLimit;
6358         RTMP_IO_WRITE32(pAdapter, TX_RTY_CFG, tx_rty_cfg.word);
6359         DBGPRINT(RT_DEBUG_TRACE, ("IF Set_LongRetryLimit_Proc::(tx_rty_cfg=0x%x)\n", tx_rty_cfg.word));
6360         return TRUE;
6361 }
6362
6363 INT Set_ShortRetryLimit_Proc(
6364         IN      PRTMP_ADAPTER   pAdapter,
6365         IN      PUCHAR                  arg)
6366 {
6367         TX_RTY_CFG_STRUC        tx_rty_cfg;
6368         UCHAR                           ShortRetryLimit = (UCHAR)simple_strtol(arg, 0, 10);
6369
6370         RTMP_IO_READ32(pAdapter, TX_RTY_CFG, &tx_rty_cfg.word);
6371         tx_rty_cfg.field.ShortRtyLimit = ShortRetryLimit;
6372         RTMP_IO_WRITE32(pAdapter, TX_RTY_CFG, tx_rty_cfg.word);
6373         DBGPRINT(RT_DEBUG_TRACE, ("IF Set_ShortRetryLimit_Proc::(tx_rty_cfg=0x%x)\n", tx_rty_cfg.word));
6374         return TRUE;
6375 }
6376
6377 INT     Show_Adhoc_MacTable_Proc(
6378         IN      PRTMP_ADAPTER   pAd,
6379         IN      PCHAR                   extra)
6380 {
6381         INT i;
6382
6383         sprintf(extra, "\n");
6384
6385         sprintf(extra + strlen(extra), "HT Operating Mode : %d\n", pAd->CommonCfg.AddHTInfo.AddHtInfo2.OperaionMode);
6386
6387         sprintf(extra + strlen(extra), "\n%-19s%-4s%-4s%-7s%-7s%-7s%-10s%-6s%-6s%-6s%-6s\n",
6388                         "MAC", "AID", "BSS", "RSSI0", "RSSI1", "RSSI2", "PhMd", "BW", "MCS", "SGI", "STBC");
6389
6390         for (i=1; i<MAX_LEN_OF_MAC_TABLE; i++)
6391         {
6392                 PMAC_TABLE_ENTRY pEntry = &pAd->MacTab.Content[i];
6393
6394                 if (strlen(extra) > (IW_PRIV_SIZE_MASK - 30))
6395                     break;
6396                 if ((pEntry->ValidAsCLI || pEntry->ValidAsApCli) && (pEntry->Sst == SST_ASSOC))
6397                 {
6398                         sprintf(extra + strlen(extra), "%02X:%02X:%02X:%02X:%02X:%02X  ",
6399                                 pEntry->Addr[0], pEntry->Addr[1], pEntry->Addr[2],
6400                                 pEntry->Addr[3], pEntry->Addr[4], pEntry->Addr[5]);
6401                         sprintf(extra + strlen(extra), "%-4d", (int)pEntry->Aid);
6402                         sprintf(extra + strlen(extra), "%-4d", (int)pEntry->apidx);
6403                         sprintf(extra + strlen(extra), "%-7d", pEntry->RssiSample.AvgRssi0);
6404                         sprintf(extra + strlen(extra), "%-7d", pEntry->RssiSample.AvgRssi1);
6405                         sprintf(extra + strlen(extra), "%-7d", pEntry->RssiSample.AvgRssi2);
6406                         sprintf(extra + strlen(extra), "%-10s", GetPhyMode(pEntry->HTPhyMode.field.MODE));
6407                         sprintf(extra + strlen(extra), "%-6s", GetBW(pEntry->HTPhyMode.field.BW));
6408                         sprintf(extra + strlen(extra), "%-6d", pEntry->HTPhyMode.field.MCS);
6409                         sprintf(extra + strlen(extra), "%-6d", pEntry->HTPhyMode.field.ShortGI);
6410                         sprintf(extra + strlen(extra), "%-6d", pEntry->HTPhyMode.field.STBC);
6411                         sprintf(extra + strlen(extra), "%-10d, %d, %d%%\n", pEntry->DebugFIFOCount, pEntry->DebugTxCount,
6412                                                 (pEntry->DebugTxCount) ? ((pEntry->DebugTxCount-pEntry->DebugFIFOCount)*100/pEntry->DebugTxCount) : 0);
6413                         sprintf(extra, "%s\n", extra);
6414                 }
6415         }
6416
6417         return TRUE;
6418 }
6419
6420