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