Staging: rt28x0: rt_ioctl_siwencode() fixes
[firefly-linux-kernel-4.4.55.git] / drivers / staging / rt2860 / 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 #if !defined(RT2860) && !defined(RT30xx)
91         { SHOW_ADHOC_ENTRY_INFO,
92           0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "adhocEntry" },
93 #endif
94 /* --- sub-ioctls relations --- */
95
96 { RTPRIV_IOCTL_STATISTICS,
97   0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK,
98   "stat"},
99 { RTPRIV_IOCTL_GSITESURVEY,
100   0, IW_PRIV_TYPE_CHAR | 1024,
101   "get_site_survey"},
102 };
103
104 INT Set_SSID_Proc(
105     IN  PRTMP_ADAPTER   pAdapter,
106     IN  PUCHAR          arg);
107
108 #ifdef WMM_SUPPORT
109 INT     Set_WmmCapable_Proc(
110         IN      PRTMP_ADAPTER   pAd,
111         IN      PUCHAR                  arg);
112 #endif
113
114 INT Set_NetworkType_Proc(
115     IN  PRTMP_ADAPTER   pAdapter,
116     IN  PUCHAR          arg);
117
118 INT Set_AuthMode_Proc(
119     IN  PRTMP_ADAPTER   pAdapter,
120     IN  PUCHAR          arg);
121
122 INT Set_EncrypType_Proc(
123     IN  PRTMP_ADAPTER   pAdapter,
124     IN  PUCHAR          arg);
125
126 INT Set_DefaultKeyID_Proc(
127     IN  PRTMP_ADAPTER   pAdapter,
128     IN  PUCHAR          arg);
129
130 INT Set_Key1_Proc(
131     IN  PRTMP_ADAPTER   pAdapter,
132     IN  PUCHAR          arg);
133
134 INT Set_Key2_Proc(
135     IN  PRTMP_ADAPTER   pAdapter,
136     IN  PUCHAR          arg);
137
138 INT Set_Key3_Proc(
139     IN  PRTMP_ADAPTER   pAdapter,
140     IN  PUCHAR          arg);
141
142 INT Set_Key4_Proc(
143     IN  PRTMP_ADAPTER   pAdapter,
144     IN  PUCHAR          arg);
145
146 INT Set_WPAPSK_Proc(
147     IN  PRTMP_ADAPTER   pAdapter,
148     IN  PUCHAR          arg);
149
150
151 INT Set_PSMode_Proc(
152     IN  PRTMP_ADAPTER   pAdapter,
153     IN  PUCHAR          arg);
154
155 INT Set_Wpa_Support(
156     IN  PRTMP_ADAPTER   pAd,
157         IN      PUCHAR                  arg);
158
159 NDIS_STATUS RTMPWPANoneAddKeyProc(
160     IN  PRTMP_ADAPTER   pAd,
161     IN  PVOID                   pBuf);
162
163 INT Set_FragTest_Proc(
164     IN  PRTMP_ADAPTER   pAdapter,
165     IN  PUCHAR          arg);
166
167 INT Set_TGnWifiTest_Proc(
168     IN  PRTMP_ADAPTER   pAd,
169     IN  PUCHAR          arg);
170
171 INT Set_LongRetryLimit_Proc(
172         IN      PRTMP_ADAPTER   pAdapter,
173         IN      PUCHAR                  arg);
174
175 INT Set_ShortRetryLimit_Proc(
176         IN      PRTMP_ADAPTER   pAdapter,
177         IN      PUCHAR                  arg);
178
179 #if !defined(RT2860) && !defined(RT30xx)
180 INT     Show_Adhoc_MacTable_Proc(
181         IN      PRTMP_ADAPTER   pAd,
182         IN      PCHAR                   extra);
183 #endif
184
185 static struct {
186         CHAR *name;
187         INT (*set_proc)(PRTMP_ADAPTER pAdapter, PUCHAR arg);
188 } *PRTMP_PRIVATE_SET_PROC, RTMP_PRIVATE_SUPPORT_PROC[] = {
189         {"DriverVersion",                               Set_DriverVersion_Proc},
190         {"CountryRegion",                               Set_CountryRegion_Proc},
191         {"CountryRegionABand",                  Set_CountryRegionABand_Proc},
192         {"SSID",                                                Set_SSID_Proc},
193         {"WirelessMode",                                Set_WirelessMode_Proc},
194         {"TxBurst",                                     Set_TxBurst_Proc},
195         {"TxPreamble",                          Set_TxPreamble_Proc},
196         {"TxPower",                                     Set_TxPower_Proc},
197         {"Channel",                                     Set_Channel_Proc},
198         {"BGProtection",                                Set_BGProtection_Proc},
199         {"RTSThreshold",                                Set_RTSThreshold_Proc},
200         {"FragThreshold",                               Set_FragThreshold_Proc},
201         {"HtBw",                                Set_HtBw_Proc},
202         {"HtMcs",                               Set_HtMcs_Proc},
203         {"HtGi",                                Set_HtGi_Proc},
204         {"HtOpMode",                        Set_HtOpMode_Proc},
205         {"HtExtcha",                        Set_HtExtcha_Proc},
206         {"HtMpduDensity",                       Set_HtMpduDensity_Proc},
207         {"HtBaWinSize",                         Set_HtBaWinSize_Proc},
208         {"HtRdg",                                       Set_HtRdg_Proc},
209         {"HtAmsdu",                                     Set_HtAmsdu_Proc},
210         {"HtAutoBa",                            Set_HtAutoBa_Proc},
211         {"HtBaDecline",                                 Set_BADecline_Proc},
212         {"HtProtect",                           Set_HtProtect_Proc},
213         {"HtMimoPs",                            Set_HtMimoPs_Proc},
214 #ifdef AGGREGATION_SUPPORT
215         {"PktAggregate",                                Set_PktAggregate_Proc},
216 #endif
217
218 #ifdef WMM_SUPPORT
219         {"WmmCapable",                                  Set_WmmCapable_Proc},
220 #endif
221         {"IEEE80211H",                                  Set_IEEE80211H_Proc},
222     {"NetworkType",                 Set_NetworkType_Proc},
223         {"AuthMode",                                    Set_AuthMode_Proc},
224         {"EncrypType",                                  Set_EncrypType_Proc},
225         {"DefaultKeyID",                                Set_DefaultKeyID_Proc},
226         {"Key1",                                                Set_Key1_Proc},
227         {"Key2",                                                Set_Key2_Proc},
228         {"Key3",                                                Set_Key3_Proc},
229         {"Key4",                                                Set_Key4_Proc},
230         {"WPAPSK",                                              Set_WPAPSK_Proc},
231         {"ResetCounter",                                Set_ResetStatCounter_Proc},
232         {"PSMode",                      Set_PSMode_Proc},
233 #ifdef DBG
234         {"Debug",                                               Set_Debug_Proc},
235 #endif
236     {"WpaSupport",                  Set_Wpa_Support},
237         {"FixedTxMode",                 Set_FixedTxMode_Proc},
238     {"TGnWifiTest",                 Set_TGnWifiTest_Proc},
239     {"ForceGF",                                 Set_ForceGF_Proc},
240         {"LongRetry",                           Set_LongRetryLimit_Proc},
241         {"ShortRetry",                          Set_ShortRetryLimit_Proc},
242 //2008/09/11:KH add to support efuse<--
243 #ifdef RT30xx
244         {"efuseFreeNumber",                             set_eFuseGetFreeBlockCount_Proc},
245         {"efuseDump",                                   set_eFusedump_Proc},
246         {"efuseLoadFromBin",                            set_eFuseLoadFromBin_Proc},
247 #endif // RT30xx //
248 //2008/09/11:KH add to support efuse-->
249         {NULL,}
250 };
251
252
253 VOID RTMPAddKey(
254         IN      PRTMP_ADAPTER       pAd,
255         IN      PNDIS_802_11_KEY    pKey)
256 {
257         ULONG                           KeyIdx;
258         MAC_TABLE_ENTRY         *pEntry;
259
260     DBGPRINT(RT_DEBUG_TRACE, ("RTMPAddKey ------>\n"));
261
262 #ifdef RT2860
263         RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
264         if (RTMP_TEST_PSFLAG(pAd, fRTMP_PS_SET_PCI_CLK_OFF_COMMAND))
265         {
266                 if (pAd->StaCfg.bRadio == FALSE)
267                 {
268                         RTMP_SET_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
269                         return;
270                 }
271                 DBGPRINT(RT_DEBUG_TRACE,("RTMPWPAAddKeyProc1==>\n"));
272                 RTMPPCIeLinkCtrlValueRestore(pAd, RESTORE_HALT);
273                 RTMPusecDelay(6000);
274                 pAd->bPCIclkOff = FALSE;
275         }
276 #endif
277
278         if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
279         {
280                 if (pKey->KeyIndex & 0x80000000)
281                 {
282                     if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
283             {
284                 NdisZeroMemory(pAd->StaCfg.PMK, 32);
285                 NdisMoveMemory(pAd->StaCfg.PMK, pKey->KeyMaterial, pKey->KeyLength);
286                 goto end;
287             }
288                     // Update PTK
289                     NdisZeroMemory(&pAd->SharedKey[BSS0][0], sizeof(CIPHER_KEY));
290             pAd->SharedKey[BSS0][0].KeyLen = LEN_TKIP_EK;
291             NdisMoveMemory(pAd->SharedKey[BSS0][0].Key, pKey->KeyMaterial, LEN_TKIP_EK);
292
293             if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
294             {
295                 NdisMoveMemory(pAd->SharedKey[BSS0][0].RxMic, pKey->KeyMaterial + LEN_TKIP_EK, LEN_TKIP_TXMICK);
296                 NdisMoveMemory(pAd->SharedKey[BSS0][0].TxMic, pKey->KeyMaterial + LEN_TKIP_EK + LEN_TKIP_TXMICK, LEN_TKIP_RXMICK);
297             }
298             else
299             {
300                 NdisMoveMemory(pAd->SharedKey[BSS0][0].TxMic, pKey->KeyMaterial + LEN_TKIP_EK, LEN_TKIP_TXMICK);
301                 NdisMoveMemory(pAd->SharedKey[BSS0][0].RxMic, pKey->KeyMaterial + LEN_TKIP_EK + LEN_TKIP_TXMICK, LEN_TKIP_RXMICK);
302             }
303
304             // Decide its ChiperAlg
305                 if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
306                         pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_TKIP;
307                 else if (pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled)
308                         pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES;
309                 else
310                         pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_NONE;
311
312             // Update these related information to MAC_TABLE_ENTRY
313                 pEntry = &pAd->MacTab.Content[BSSID_WCID];
314             NdisMoveMemory(pEntry->PairwiseKey.Key, pAd->SharedKey[BSS0][0].Key, LEN_TKIP_EK);
315                 NdisMoveMemory(pEntry->PairwiseKey.RxMic, pAd->SharedKey[BSS0][0].RxMic, LEN_TKIP_RXMICK);
316                 NdisMoveMemory(pEntry->PairwiseKey.TxMic, pAd->SharedKey[BSS0][0].TxMic, LEN_TKIP_TXMICK);
317                 pEntry->PairwiseKey.CipherAlg = pAd->SharedKey[BSS0][0].CipherAlg;
318
319                 // Update pairwise key information to ASIC Shared Key Table
320                 AsicAddSharedKeyEntry(pAd,
321                                                           BSS0,
322                                                           0,
323                                                           pAd->SharedKey[BSS0][0].CipherAlg,
324                                                           pAd->SharedKey[BSS0][0].Key,
325                                                           pAd->SharedKey[BSS0][0].TxMic,
326                                                           pAd->SharedKey[BSS0][0].RxMic);
327
328                 // Update ASIC WCID attribute table and IVEIV table
329                 RTMPAddWcidAttributeEntry(pAd,
330                                                                   BSS0,
331                                                                   0,
332                                                                   pAd->SharedKey[BSS0][0].CipherAlg,
333                                                                   pEntry);
334
335             if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA2)
336             {
337                 // set 802.1x port control
338                                 STA_PORT_SECURED(pAd);
339
340                 // Indicate Connected for GUI
341                 pAd->IndicateMediaState = NdisMediaStateConnected;
342             }
343                 }
344         else
345         {
346             // Update GTK
347             pAd->StaCfg.DefaultKeyId = (pKey->KeyIndex & 0xFF);
348             NdisZeroMemory(&pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId], sizeof(CIPHER_KEY));
349             pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].KeyLen = LEN_TKIP_EK;
350             NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].Key, pKey->KeyMaterial, LEN_TKIP_EK);
351
352             if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption2Enabled)
353             {
354                 NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].RxMic, pKey->KeyMaterial + LEN_TKIP_EK, LEN_TKIP_TXMICK);
355                 NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].TxMic, pKey->KeyMaterial + LEN_TKIP_EK + LEN_TKIP_TXMICK, LEN_TKIP_RXMICK);
356             }
357             else
358             {
359                 NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].TxMic, pKey->KeyMaterial + LEN_TKIP_EK, LEN_TKIP_TXMICK);
360                 NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].RxMic, pKey->KeyMaterial + LEN_TKIP_EK + LEN_TKIP_TXMICK, LEN_TKIP_RXMICK);
361             }
362
363             // Update Shared Key CipherAlg
364                 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_NONE;
365                 if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption2Enabled)
366                         pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_TKIP;
367                 else if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption3Enabled)
368                         pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_AES;
369
370             // Update group key information to ASIC Shared Key Table
371                 AsicAddSharedKeyEntry(pAd,
372                                                           BSS0,
373                                                           pAd->StaCfg.DefaultKeyId,
374                                                           pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg,
375                                                           pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].Key,
376                                                           pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].TxMic,
377                                                           pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].RxMic);
378
379                 // Update ASIC WCID attribute table and IVEIV table
380                 RTMPAddWcidAttributeEntry(pAd,
381                                                                   BSS0,
382                                                                   pAd->StaCfg.DefaultKeyId,
383                                                                   pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg,
384                                                                   NULL);
385
386             // set 802.1x port control
387                         STA_PORT_SECURED(pAd);
388
389             // Indicate Connected for GUI
390             pAd->IndicateMediaState = NdisMediaStateConnected;
391         }
392         }
393         else    // dynamic WEP from wpa_supplicant
394         {
395                 UCHAR   CipherAlg;
396         PUCHAR  Key;
397
398                 if(pKey->KeyLength == 32)
399                         goto end;
400
401                 KeyIdx = pKey->KeyIndex & 0x0fffffff;
402
403                 if (KeyIdx < 4)
404                 {
405                         // it is a default shared key, for Pairwise key setting
406                         if (pKey->KeyIndex & 0x80000000)
407                         {
408                                 pEntry = MacTableLookup(pAd, pKey->BSSID);
409
410                                 if (pEntry)
411                                 {
412                                         DBGPRINT(RT_DEBUG_TRACE, ("RTMPAddKey: Set Pair-wise Key\n"));
413
414                                         // set key material and key length
415                                         pEntry->PairwiseKey.KeyLen = (UCHAR)pKey->KeyLength;
416                                         NdisMoveMemory(pEntry->PairwiseKey.Key, &pKey->KeyMaterial, pKey->KeyLength);
417
418                                         // set Cipher type
419                                         if (pKey->KeyLength == 5)
420                                                 pEntry->PairwiseKey.CipherAlg = CIPHER_WEP64;
421                                         else
422                                                 pEntry->PairwiseKey.CipherAlg = CIPHER_WEP128;
423
424                                         // Add Pair-wise key to Asic
425                                         AsicAddPairwiseKeyEntry(
426                                                 pAd,
427                                                 pEntry->Addr,
428                                                 (UCHAR)pEntry->Aid,
429                                 &pEntry->PairwiseKey);
430
431                                         // update WCID attribute table and IVEIV table for this entry
432                                         RTMPAddWcidAttributeEntry(
433                                                 pAd,
434                                                 BSS0,
435                                                 KeyIdx, // The value may be not zero
436                                                 pEntry->PairwiseKey.CipherAlg,
437                                                 pEntry);
438
439                                 }
440                         }
441                         else
442             {
443                                 // Default key for tx (shared key)
444                                 pAd->StaCfg.DefaultKeyId = (UCHAR) KeyIdx;
445
446                                 // set key material and key length
447                                 pAd->SharedKey[BSS0][KeyIdx].KeyLen = (UCHAR) pKey->KeyLength;
448                                 NdisMoveMemory(pAd->SharedKey[BSS0][KeyIdx].Key, &pKey->KeyMaterial, pKey->KeyLength);
449
450                                 // Set Ciper type
451                                 if (pKey->KeyLength == 5)
452                                         pAd->SharedKey[BSS0][KeyIdx].CipherAlg = CIPHER_WEP64;
453                                 else
454                                         pAd->SharedKey[BSS0][KeyIdx].CipherAlg = CIPHER_WEP128;
455
456                         CipherAlg = pAd->SharedKey[BSS0][KeyIdx].CipherAlg;
457                         Key = pAd->SharedKey[BSS0][KeyIdx].Key;
458
459                                 // Set Group key material to Asic
460                         AsicAddSharedKeyEntry(pAd, BSS0, KeyIdx, CipherAlg, Key, NULL, NULL);
461
462                                 // Update WCID attribute table and IVEIV table for this group key table
463                                 RTMPAddWcidAttributeEntry(pAd, BSS0, KeyIdx, CipherAlg, NULL);
464
465                         }
466                 }
467         }
468 end:
469 #ifdef RT2860
470         RTMP_SET_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
471     DBGPRINT(RT_DEBUG_INFO, ("<------ RTMPAddKey\n"));
472 #endif
473         return;
474 }
475
476 char * rtstrchr(const char * s, int c)
477 {
478     for(; *s != (char) c; ++s)
479         if (*s == '\0')
480             return NULL;
481     return (char *) s;
482 }
483
484 /*
485 This is required for LinEX2004/kernel2.6.7 to provide iwlist scanning function
486 */
487
488 int
489 rt_ioctl_giwname(struct net_device *dev,
490                    struct iw_request_info *info,
491                    char *name, char *extra)
492 {
493 //      PRTMP_ADAPTER pAdapter = dev->ml_priv;
494         strncpy(name, RT28xx_CHIP_NAME " Wireless", IFNAMSIZ);
495         return 0;
496 }
497
498 int rt_ioctl_siwfreq(struct net_device *dev,
499                         struct iw_request_info *info,
500                         struct iw_freq *freq, char *extra)
501 {
502         PRTMP_ADAPTER pAdapter = dev->ml_priv;
503         int     chan = -1;
504
505     //check if the interface is down
506     if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
507     {
508         DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
509         return -ENETDOWN;
510     }
511
512
513         if (freq->e > 1)
514                 return -EINVAL;
515
516         if((freq->e == 0) && (freq->m <= 1000))
517                 chan = freq->m; // Setting by channel number
518         else
519                 MAP_KHZ_TO_CHANNEL_ID( (freq->m /100) , chan); // Setting by frequency - search the table , like 2.412G, 2.422G,
520
521     if (ChannelSanity(pAdapter, chan) == TRUE)
522     {
523         pAdapter->CommonCfg.Channel = chan;
524         DBGPRINT(RT_DEBUG_ERROR, ("==>rt_ioctl_siwfreq::SIOCSIWFREQ[cmd=0x%x] (Channel=%d)\n", SIOCSIWFREQ, pAdapter->CommonCfg.Channel));
525     }
526     else
527         return -EINVAL;
528
529         return 0;
530 }
531 int rt_ioctl_giwfreq(struct net_device *dev,
532                    struct iw_request_info *info,
533                    struct iw_freq *freq, char *extra)
534 {
535         PRTMP_ADAPTER pAdapter = dev->ml_priv;
536         UCHAR ch = pAdapter->CommonCfg.Channel;
537         ULONG   m;
538
539         DBGPRINT(RT_DEBUG_TRACE,("==>rt_ioctl_giwfreq  %d\n", ch));
540
541     MAP_CHANNEL_ID_TO_KHZ(ch, m);
542         freq->m = m * 100;
543         freq->e = 1;
544         return 0;
545 }
546
547 int rt_ioctl_siwmode(struct net_device *dev,
548                    struct iw_request_info *info,
549                    __u32 *mode, char *extra)
550 {
551         PRTMP_ADAPTER pAdapter = dev->ml_priv;
552
553         //check if the interface is down
554     if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
555     {
556         DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
557         return -ENETDOWN;
558     }
559
560         switch (*mode)
561         {
562                 case IW_MODE_ADHOC:
563                         Set_NetworkType_Proc(pAdapter, "Adhoc");
564                         break;
565                 case IW_MODE_INFRA:
566                         Set_NetworkType_Proc(pAdapter, "Infra");
567                         break;
568         case IW_MODE_MONITOR:
569                         Set_NetworkType_Proc(pAdapter, "Monitor");
570                         break;
571                 default:
572                         DBGPRINT(RT_DEBUG_TRACE, ("===>rt_ioctl_siwmode::SIOCSIWMODE (unknown %d)\n", *mode));
573                         return -EINVAL;
574         }
575
576         // Reset Ralink supplicant to not use, it will be set to start when UI set PMK key
577         pAdapter->StaCfg.WpaState = SS_NOTUSE;
578
579         return 0;
580 }
581
582 int rt_ioctl_giwmode(struct net_device *dev,
583                    struct iw_request_info *info,
584                    __u32 *mode, char *extra)
585 {
586         PRTMP_ADAPTER pAdapter = dev->ml_priv;
587
588         if (ADHOC_ON(pAdapter))
589                 *mode = IW_MODE_ADHOC;
590     else if (INFRA_ON(pAdapter))
591                 *mode = IW_MODE_INFRA;
592     else if (MONITOR_ON(pAdapter))
593     {
594         *mode = IW_MODE_MONITOR;
595     }
596     else
597         *mode = IW_MODE_AUTO;
598
599         DBGPRINT(RT_DEBUG_TRACE, ("==>rt_ioctl_giwmode(mode=%d)\n", *mode));
600         return 0;
601 }
602
603 int rt_ioctl_siwsens(struct net_device *dev,
604                    struct iw_request_info *info,
605                    char *name, char *extra)
606 {
607         PRTMP_ADAPTER pAdapter = dev->ml_priv;
608
609         //check if the interface is down
610         if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
611         {
612                 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
613                 return -ENETDOWN;
614         }
615
616         return 0;
617 }
618
619 int rt_ioctl_giwsens(struct net_device *dev,
620                    struct iw_request_info *info,
621                    char *name, char *extra)
622 {
623         return 0;
624 }
625
626 int rt_ioctl_giwrange(struct net_device *dev,
627                    struct iw_request_info *info,
628                    struct iw_point *data, char *extra)
629 {
630         PRTMP_ADAPTER pAdapter = dev->ml_priv;
631         struct iw_range *range = (struct iw_range *) extra;
632         u16 val;
633         int i;
634
635         DBGPRINT(RT_DEBUG_TRACE ,("===>rt_ioctl_giwrange\n"));
636         data->length = sizeof(struct iw_range);
637         memset(range, 0, sizeof(struct iw_range));
638
639         range->txpower_capa = IW_TXPOW_DBM;
640
641         if (INFRA_ON(pAdapter)||ADHOC_ON(pAdapter))
642         {
643                 range->min_pmp = 1 * 1024;
644                 range->max_pmp = 65535 * 1024;
645                 range->min_pmt = 1 * 1024;
646                 range->max_pmt = 1000 * 1024;
647                 range->pmp_flags = IW_POWER_PERIOD;
648                 range->pmt_flags = IW_POWER_TIMEOUT;
649                 range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT |
650                         IW_POWER_UNICAST_R | IW_POWER_ALL_R;
651         }
652
653         range->we_version_compiled = WIRELESS_EXT;
654         range->we_version_source = 14;
655
656         range->retry_capa = IW_RETRY_LIMIT;
657         range->retry_flags = IW_RETRY_LIMIT;
658         range->min_retry = 0;
659         range->max_retry = 255;
660
661         range->num_channels =  pAdapter->ChannelListNum;
662
663         val = 0;
664         for (i = 1; i <= range->num_channels; i++)
665         {
666                 u32 m;
667                 range->freq[val].i = pAdapter->ChannelList[i-1].Channel;
668                 MAP_CHANNEL_ID_TO_KHZ(pAdapter->ChannelList[i-1].Channel, m);
669                 range->freq[val].m = m * 100; /* HZ */
670
671                 range->freq[val].e = 1;
672                 val++;
673                 if (val == IW_MAX_FREQUENCIES)
674                         break;
675         }
676         range->num_frequency = val;
677
678         range->max_qual.qual = 100; /* what is correct max? This was not
679                                         * documented exactly. At least
680                                         * 69 has been observed. */
681         range->max_qual.level = 0; /* dB */
682         range->max_qual.noise = 0; /* dB */
683
684         /* What would be suitable values for "average/typical" qual? */
685         range->avg_qual.qual = 20;
686         range->avg_qual.level = -60;
687         range->avg_qual.noise = -95;
688         range->sensitivity = 3;
689
690         range->max_encoding_tokens = NR_WEP_KEYS;
691         range->num_encoding_sizes = 2;
692         range->encoding_size[0] = 5;
693         range->encoding_size[1] = 13;
694
695         range->min_rts = 0;
696         range->max_rts = 2347;
697         range->min_frag = 256;
698         range->max_frag = 2346;
699
700         /* IW_ENC_CAPA_* bit field */
701         range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
702                                         IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
703
704         return 0;
705 }
706
707 int rt_ioctl_siwap(struct net_device *dev,
708                       struct iw_request_info *info,
709                       struct sockaddr *ap_addr, char *extra)
710 {
711         PRTMP_ADAPTER pAdapter = dev->ml_priv;
712     NDIS_802_11_MAC_ADDRESS Bssid;
713
714         //check if the interface is down
715         if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
716         {
717         DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
718         return -ENETDOWN;
719     }
720
721         if (pAdapter->Mlme.CntlMachine.CurrState != CNTL_IDLE)
722     {
723         RT28XX_MLME_RESET_STATE_MACHINE(pAdapter);
724         DBGPRINT(RT_DEBUG_TRACE, ("!!! MLME busy, reset MLME state machine !!!\n"));
725     }
726
727     // tell CNTL state machine to call NdisMSetInformationComplete() after completing
728     // this request, because this request is initiated by NDIS.
729     pAdapter->MlmeAux.CurrReqIsFromNdis = FALSE;
730         // Prevent to connect AP again in STAMlmePeriodicExec
731         pAdapter->MlmeAux.AutoReconnectSsidLen= 32;
732
733     memset(Bssid, 0, MAC_ADDR_LEN);
734     memcpy(Bssid, ap_addr->sa_data, MAC_ADDR_LEN);
735     MlmeEnqueue(pAdapter,
736                 MLME_CNTL_STATE_MACHINE,
737                 OID_802_11_BSSID,
738                 sizeof(NDIS_802_11_MAC_ADDRESS),
739                 (VOID *)&Bssid);
740
741     DBGPRINT(RT_DEBUG_TRACE, ("IOCTL::SIOCSIWAP %02x:%02x:%02x:%02x:%02x:%02x\n",
742         Bssid[0], Bssid[1], Bssid[2], Bssid[3], Bssid[4], Bssid[5]));
743
744         return 0;
745 }
746
747 int rt_ioctl_giwap(struct net_device *dev,
748                       struct iw_request_info *info,
749                       struct sockaddr *ap_addr, char *extra)
750 {
751         PRTMP_ADAPTER pAdapter = dev->ml_priv;
752
753         if (INFRA_ON(pAdapter) || ADHOC_ON(pAdapter))
754         {
755                 ap_addr->sa_family = ARPHRD_ETHER;
756                 memcpy(ap_addr->sa_data, &pAdapter->CommonCfg.Bssid, ETH_ALEN);
757         }
758     // Add for RT2870
759     else if (pAdapter->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE)
760     {
761         ap_addr->sa_family = ARPHRD_ETHER;
762         memcpy(ap_addr->sa_data, &pAdapter->MlmeAux.Bssid, ETH_ALEN);
763     }
764         else
765         {
766                 DBGPRINT(RT_DEBUG_TRACE, ("IOCTL::SIOCGIWAP(=EMPTY)\n"));
767                 return -ENOTCONN;
768         }
769
770         return 0;
771 }
772
773 /*
774  * Units are in db above the noise floor. That means the
775  * rssi values reported in the tx/rx descriptors in the
776  * driver are the SNR expressed in db.
777  *
778  * If you assume that the noise floor is -95, which is an
779  * excellent assumption 99.5 % of the time, then you can
780  * derive the absolute signal level (i.e. -95 + rssi).
781  * There are some other slight factors to take into account
782  * depending on whether the rssi measurement is from 11b,
783  * 11g, or 11a.   These differences are at most 2db and
784  * can be documented.
785  *
786  * NB: various calculations are based on the orinoco/wavelan
787  *     drivers for compatibility
788  */
789 static void set_quality(PRTMP_ADAPTER pAdapter,
790                         struct iw_quality *iq,
791                         signed char rssi)
792 {
793         __u8 ChannelQuality;
794
795         // Normalize Rssi
796         if (rssi >= -50)
797                 ChannelQuality = 100;
798         else if (rssi >= -80) // between -50 ~ -80dbm
799                 ChannelQuality = (__u8)(24 + ((rssi + 80) * 26)/10);
800         else if (rssi >= -90)   // between -80 ~ -90dbm
801         ChannelQuality = (__u8)((rssi + 90) * 26)/10;
802         else
803                 ChannelQuality = 0;
804
805     iq->qual = (__u8)ChannelQuality;
806
807     iq->level = (__u8)(rssi);
808     iq->noise = (pAdapter->BbpWriteLatch[66] > pAdapter->BbpTuning.FalseCcaUpperThreshold) ? ((__u8)pAdapter->BbpTuning.FalseCcaUpperThreshold) : ((__u8) pAdapter->BbpWriteLatch[66]);         // noise level (dBm)
809     iq->noise += 256 - 143;
810     iq->updated = pAdapter->iw_stats.qual.updated;
811 }
812
813 int rt_ioctl_iwaplist(struct net_device *dev,
814                         struct iw_request_info *info,
815                         struct iw_point *data, char *extra)
816 {
817         PRTMP_ADAPTER pAdapter = dev->ml_priv;
818
819         struct sockaddr addr[IW_MAX_AP];
820         struct iw_quality qual[IW_MAX_AP];
821         int i;
822
823         //check if the interface is down
824     if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
825     {
826         DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
827                 data->length = 0;
828                 return 0;
829         //return -ENETDOWN;
830         }
831
832         for (i = 0; i <IW_MAX_AP ; i++)
833         {
834                 if (i >=  pAdapter->ScanTab.BssNr)
835                         break;
836                 addr[i].sa_family = ARPHRD_ETHER;
837                         memcpy(addr[i].sa_data, &pAdapter->ScanTab.BssEntry[i].Bssid, MAC_ADDR_LEN);
838                 set_quality(pAdapter, &qual[i], pAdapter->ScanTab.BssEntry[i].Rssi);
839         }
840         data->length = i;
841         memcpy(extra, &addr, i*sizeof(addr[0]));
842         data->flags = 1;                /* signal quality present (sort of) */
843         memcpy(extra + i*sizeof(addr[0]), &qual, i*sizeof(qual[i]));
844
845         return 0;
846 }
847
848 int rt_ioctl_siwscan(struct net_device *dev,
849                         struct iw_request_info *info,
850                         struct iw_point *data, char *extra)
851 {
852         PRTMP_ADAPTER pAdapter = dev->ml_priv;
853
854         ULONG                                                           Now;
855         int Status = NDIS_STATUS_SUCCESS;
856
857         //check if the interface is down
858         if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
859         {
860                 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
861                 return -ENETDOWN;
862         }
863
864         if (MONITOR_ON(pAdapter))
865     {
866         DBGPRINT(RT_DEBUG_TRACE, ("!!! Driver is in Monitor Mode now !!!\n"));
867         return -EINVAL;
868     }
869 #ifdef RT2860
870         if ((pAdapter->OpMode == OPMODE_STA) && (IDLE_ON(pAdapter))
871                 && (pAdapter->StaCfg.bRadio == TRUE)
872                 && (RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_IDLE_RADIO_OFF)))
873         {
874                 RT28xxPciAsicRadioOn(pAdapter, GUI_IDLE_POWER_SAVE);
875         }
876         // Check if still radio off.
877         else if (pAdapter->bPCIclkOff == TRUE)
878                 return 0;
879 #endif
880         if (pAdapter->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_ENABLE)
881         {
882                 pAdapter->StaCfg.WpaSupplicantScanCount++;
883         }
884
885     pAdapter->StaCfg.bScanReqIsFromWebUI = TRUE;
886         if (RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
887                 return 0;
888         do{
889                 Now = jiffies;
890
891                 if ((pAdapter->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_ENABLE) &&
892                         (pAdapter->StaCfg.WpaSupplicantScanCount > 3))
893                 {
894                         DBGPRINT(RT_DEBUG_TRACE, ("!!! WpaSupplicantScanCount > 3\n"));
895                         Status = NDIS_STATUS_SUCCESS;
896                         break;
897                 }
898
899                 if ((OPSTATUS_TEST_FLAG(pAdapter, fOP_STATUS_MEDIA_STATE_CONNECTED)) &&
900                         ((pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPA) ||
901                         (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK)) &&
902                         (pAdapter->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED))
903                 {
904                         DBGPRINT(RT_DEBUG_TRACE, ("!!! Link UP, Port Not Secured! ignore this set::OID_802_11_BSSID_LIST_SCAN\n"));
905                         Status = NDIS_STATUS_SUCCESS;
906                         break;
907                 }
908
909                 if (pAdapter->Mlme.CntlMachine.CurrState != CNTL_IDLE)
910                 {
911                         RT28XX_MLME_RESET_STATE_MACHINE(pAdapter);
912                         DBGPRINT(RT_DEBUG_TRACE, ("!!! MLME busy, reset MLME state machine !!!\n"));
913                 }
914
915                 // tell CNTL state machine to call NdisMSetInformationComplete() after completing
916                 // this request, because this request is initiated by NDIS.
917                 pAdapter->MlmeAux.CurrReqIsFromNdis = FALSE;
918                 // Reset allowed scan retries
919                 pAdapter->StaCfg.ScanCnt = 0;
920                 pAdapter->StaCfg.LastScanTime = Now;
921
922                 MlmeEnqueue(pAdapter,
923                         MLME_CNTL_STATE_MACHINE,
924                         OID_802_11_BSSID_LIST_SCAN,
925                         0,
926                         NULL);
927
928                 Status = NDIS_STATUS_SUCCESS;
929                 RT28XX_MLME_HANDLER(pAdapter);
930         }while(0);
931         return 0;
932 }
933
934 int rt_ioctl_giwscan(struct net_device *dev,
935                         struct iw_request_info *info,
936                         struct iw_point *data, char *extra)
937 {
938
939         PRTMP_ADAPTER pAdapter = dev->ml_priv;
940         int i=0;
941         char *current_ev = extra, *previous_ev = extra;
942         char *end_buf;
943         char *current_val, custom[MAX_CUSTOM_LEN] = {0};
944         struct iw_event iwe;
945
946         if (RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
947     {
948                 /*
949                  * Still scanning, indicate the caller should try again.
950                  */
951                 return -EAGAIN;
952         }
953
954         if (pAdapter->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_ENABLE)
955         {
956                 pAdapter->StaCfg.WpaSupplicantScanCount = 0;
957         }
958
959         if (pAdapter->ScanTab.BssNr == 0)
960         {
961                 data->length = 0;
962                 return 0;
963         }
964
965     if (data->length > 0)
966         end_buf = extra + data->length;
967     else
968         end_buf = extra + IW_SCAN_MAX_DATA;
969
970         for (i = 0; i < pAdapter->ScanTab.BssNr; i++)
971         {
972                 if (current_ev >= end_buf)
973                         return -E2BIG;
974
975                 //MAC address
976                 //================================
977                 memset(&iwe, 0, sizeof(iwe));
978                 iwe.cmd = SIOCGIWAP;
979                 iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
980                 memcpy(iwe.u.ap_addr.sa_data, &pAdapter->ScanTab.BssEntry[i].Bssid, ETH_ALEN);
981
982         previous_ev = current_ev;
983                 current_ev = iwe_stream_add_event(info, current_ev,end_buf, &iwe, IW_EV_ADDR_LEN);
984         if (current_ev == previous_ev)
985                 return -E2BIG;
986
987                 /*
988                 Protocol:
989                         it will show scanned AP's WirelessMode .
990                         it might be
991                                         802.11a
992                                         802.11a/n
993                                         802.11g/n
994                                         802.11b/g/n
995                                         802.11g
996                                         802.11b/g
997                 */
998                 memset(&iwe, 0, sizeof(iwe));
999                 iwe.cmd = SIOCGIWNAME;
1000
1001
1002         {
1003                 PBSS_ENTRY pBssEntry=&pAdapter->ScanTab.BssEntry[i];
1004                 BOOLEAN isGonly=FALSE;
1005                 int rateCnt=0;
1006
1007                 if (pBssEntry->Channel>14)
1008                 {
1009                         if (pBssEntry->HtCapabilityLen!=0)
1010                                 strcpy(iwe.u.name,"802.11a/n");
1011                         else
1012                                 strcpy(iwe.u.name,"802.11a");
1013                 }
1014                 else
1015                 {
1016                         /*
1017                                 if one of non B mode rate is set supported rate . it mean G only.
1018                         */
1019                         for (rateCnt=0;rateCnt<pBssEntry->SupRateLen;rateCnt++)
1020                         {
1021                                 /*
1022                                         6Mbps(140) 9Mbps(146) and >=12Mbps(152) are supported rate , it mean G only.
1023                                 */
1024                                 if (pBssEntry->SupRate[rateCnt]==140 || pBssEntry->SupRate[rateCnt]==146 || pBssEntry->SupRate[rateCnt]>=152)
1025                                         isGonly=TRUE;
1026                         }
1027
1028                         for (rateCnt=0;rateCnt<pBssEntry->ExtRateLen;rateCnt++)
1029                         {
1030                                 if (pBssEntry->ExtRate[rateCnt]==140 || pBssEntry->ExtRate[rateCnt]==146 || pBssEntry->ExtRate[rateCnt]>=152)
1031                                         isGonly=TRUE;
1032                         }
1033
1034
1035                         if (pBssEntry->HtCapabilityLen!=0)
1036                         {
1037                                 if (isGonly==TRUE)
1038                                         strcpy(iwe.u.name,"802.11g/n");
1039                                 else
1040                                         strcpy(iwe.u.name,"802.11b/g/n");
1041                         }
1042                         else
1043                         {
1044                                 if (isGonly==TRUE)
1045                                         strcpy(iwe.u.name,"802.11g");
1046                                 else
1047                                 {
1048                                         if (pBssEntry->SupRateLen==4 && pBssEntry->ExtRateLen==0)
1049                                                 strcpy(iwe.u.name,"802.11b");
1050                                         else
1051                                                 strcpy(iwe.u.name,"802.11b/g");
1052                                 }
1053                         }
1054                 }
1055         }
1056
1057                 previous_ev = current_ev;
1058                 current_ev       = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_ADDR_LEN);
1059         if (current_ev == previous_ev)
1060                 return -E2BIG;
1061
1062                 //ESSID
1063                 //================================
1064                 memset(&iwe, 0, sizeof(iwe));
1065                 iwe.cmd = SIOCGIWESSID;
1066                 iwe.u.data.length = pAdapter->ScanTab.BssEntry[i].SsidLen;
1067                 iwe.u.data.flags = 1;
1068
1069         previous_ev = current_ev;
1070                 current_ev = iwe_stream_add_point(info, current_ev,end_buf, &iwe, pAdapter->ScanTab.BssEntry[i].Ssid);
1071         if (current_ev == previous_ev)
1072                 return -E2BIG;
1073
1074                 //Network Type
1075                 //================================
1076                 memset(&iwe, 0, sizeof(iwe));
1077                 iwe.cmd = SIOCGIWMODE;
1078                 if (pAdapter->ScanTab.BssEntry[i].BssType == Ndis802_11IBSS)
1079                 {
1080                         iwe.u.mode = IW_MODE_ADHOC;
1081                 }
1082                 else if (pAdapter->ScanTab.BssEntry[i].BssType == Ndis802_11Infrastructure)
1083                 {
1084                         iwe.u.mode = IW_MODE_INFRA;
1085                 }
1086                 else
1087                 {
1088                         iwe.u.mode = IW_MODE_AUTO;
1089                 }
1090                 iwe.len = IW_EV_UINT_LEN;
1091
1092         previous_ev = current_ev;
1093                 current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe,  IW_EV_UINT_LEN);
1094         if (current_ev == previous_ev)
1095                 return -E2BIG;
1096
1097                 //Channel and Frequency
1098                 //================================
1099                 memset(&iwe, 0, sizeof(iwe));
1100                 iwe.cmd = SIOCGIWFREQ;
1101                 if (INFRA_ON(pAdapter) || ADHOC_ON(pAdapter))
1102                         iwe.u.freq.m = pAdapter->ScanTab.BssEntry[i].Channel;
1103                 else
1104                         iwe.u.freq.m = pAdapter->ScanTab.BssEntry[i].Channel;
1105                 iwe.u.freq.e = 0;
1106                 iwe.u.freq.i = 0;
1107
1108                 previous_ev = current_ev;
1109                 current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_FREQ_LEN);
1110         if (current_ev == previous_ev)
1111                 return -E2BIG;
1112
1113         //Add quality statistics
1114         //================================
1115         memset(&iwe, 0, sizeof(iwe));
1116         iwe.cmd = IWEVQUAL;
1117         iwe.u.qual.level = 0;
1118         iwe.u.qual.noise = 0;
1119         set_quality(pAdapter, &iwe.u.qual, pAdapter->ScanTab.BssEntry[i].Rssi);
1120         current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_QUAL_LEN);
1121         if (current_ev == previous_ev)
1122                 return -E2BIG;
1123
1124                 //Encyption key
1125                 //================================
1126                 memset(&iwe, 0, sizeof(iwe));
1127                 iwe.cmd = SIOCGIWENCODE;
1128                 if (CAP_IS_PRIVACY_ON (pAdapter->ScanTab.BssEntry[i].CapabilityInfo ))
1129                         iwe.u.data.flags =IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
1130                 else
1131                         iwe.u.data.flags = IW_ENCODE_DISABLED;
1132
1133         previous_ev = current_ev;
1134         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);
1135         if (current_ev == previous_ev)
1136                 return -E2BIG;
1137
1138                 //Bit Rate
1139                 //================================
1140                 if (pAdapter->ScanTab.BssEntry[i].SupRateLen)
1141         {
1142             UCHAR tmpRate = pAdapter->ScanTab.BssEntry[i].SupRate[pAdapter->ScanTab.BssEntry[i].SupRateLen-1];
1143                         memset(&iwe, 0, sizeof(iwe));
1144                         iwe.cmd = SIOCGIWRATE;
1145                 current_val = current_ev + IW_EV_LCP_LEN;
1146             if (tmpRate == 0x82)
1147                 iwe.u.bitrate.value =  1 * 1000000;
1148             else if (tmpRate == 0x84)
1149                 iwe.u.bitrate.value =  2 * 1000000;
1150             else if (tmpRate == 0x8B)
1151                 iwe.u.bitrate.value =  5.5 * 1000000;
1152             else if (tmpRate == 0x96)
1153                 iwe.u.bitrate.value =  11 * 1000000;
1154             else
1155                     iwe.u.bitrate.value =  (tmpRate/2) * 1000000;
1156
1157                         iwe.u.bitrate.disabled = 0;
1158                         current_val = iwe_stream_add_value(info, current_ev,
1159                                 current_val, end_buf, &iwe,
1160                         IW_EV_PARAM_LEN);
1161
1162                 if((current_val-current_ev)>IW_EV_LCP_LEN)
1163                 current_ev = current_val;
1164                 else
1165                         return -E2BIG;
1166         }
1167
1168                 //WPA IE
1169                 if (pAdapter->ScanTab.BssEntry[i].WpaIE.IELen > 0)
1170                 {
1171                         memset(&iwe, 0, sizeof(iwe));
1172                         memset(&custom[0], 0, MAX_CUSTOM_LEN);
1173                         memcpy(custom, &(pAdapter->ScanTab.BssEntry[i].WpaIE.IE[0]),
1174                                                    pAdapter->ScanTab.BssEntry[i].WpaIE.IELen);
1175                         iwe.cmd = IWEVGENIE;
1176                         iwe.u.data.length = pAdapter->ScanTab.BssEntry[i].WpaIE.IELen;
1177                         current_ev = iwe_stream_add_point(info, current_ev, end_buf, &iwe, custom);
1178                         if (current_ev == previous_ev)
1179                                 return -E2BIG;
1180                 }
1181
1182                 //WPA2 IE
1183         if (pAdapter->ScanTab.BssEntry[i].RsnIE.IELen > 0)
1184         {
1185                 memset(&iwe, 0, sizeof(iwe));
1186                         memset(&custom[0], 0, MAX_CUSTOM_LEN);
1187                         memcpy(custom, &(pAdapter->ScanTab.BssEntry[i].RsnIE.IE[0]),
1188                                                    pAdapter->ScanTab.BssEntry[i].RsnIE.IELen);
1189                         iwe.cmd = IWEVGENIE;
1190                         iwe.u.data.length = pAdapter->ScanTab.BssEntry[i].RsnIE.IELen;
1191                         current_ev = iwe_stream_add_point(info, current_ev, end_buf, &iwe, custom);
1192                         if (current_ev == previous_ev)
1193                                 return -E2BIG;
1194         }
1195         }
1196
1197         data->length = current_ev - extra;
1198     pAdapter->StaCfg.bScanReqIsFromWebUI = FALSE;
1199         DBGPRINT(RT_DEBUG_ERROR ,("===>rt_ioctl_giwscan. %d(%d) BSS returned, data->length = %d\n",i , pAdapter->ScanTab.BssNr, data->length));
1200         return 0;
1201 }
1202
1203 int rt_ioctl_siwessid(struct net_device *dev,
1204                          struct iw_request_info *info,
1205                          struct iw_point *data, char *essid)
1206 {
1207         PRTMP_ADAPTER pAdapter = dev->ml_priv;
1208
1209         //check if the interface is down
1210     if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
1211     {
1212         DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
1213         return -ENETDOWN;
1214     }
1215
1216         if (data->flags)
1217         {
1218                 PCHAR   pSsidString = NULL;
1219
1220                 // Includes null character.
1221                 if (data->length > (IW_ESSID_MAX_SIZE + 1))
1222                         return -E2BIG;
1223
1224                 pSsidString = (CHAR *) kmalloc(MAX_LEN_OF_SSID+1, MEM_ALLOC_FLAG);
1225                 if (pSsidString)
1226                 {
1227                         NdisZeroMemory(pSsidString, MAX_LEN_OF_SSID+1);
1228                         NdisMoveMemory(pSsidString, essid, data->length);
1229                         if (Set_SSID_Proc(pAdapter, pSsidString) == FALSE)
1230                                 return -EINVAL;
1231                 }
1232                 else
1233                         return -ENOMEM;
1234         }
1235         else
1236         {
1237                 // ANY ssid
1238                 if (Set_SSID_Proc(pAdapter, "") == FALSE)
1239                         return -EINVAL;
1240     }
1241         return 0;
1242 }
1243
1244 int rt_ioctl_giwessid(struct net_device *dev,
1245                          struct iw_request_info *info,
1246                          struct iw_point *data, char *essid)
1247 {
1248         PRTMP_ADAPTER pAdapter = dev->ml_priv;
1249
1250         data->flags = 1;
1251     if (MONITOR_ON(pAdapter))
1252     {
1253         data->length  = 0;
1254         return 0;
1255     }
1256
1257         if (OPSTATUS_TEST_FLAG(pAdapter, fOP_STATUS_MEDIA_STATE_CONNECTED))
1258         {
1259                 DBGPRINT(RT_DEBUG_TRACE ,("MediaState is connected\n"));
1260                 data->length = pAdapter->CommonCfg.SsidLen;
1261                 memcpy(essid, pAdapter->CommonCfg.Ssid, pAdapter->CommonCfg.SsidLen);
1262         }
1263 #ifdef RT2870
1264     // Add for RT2870
1265     else if (pAdapter->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE)
1266     {
1267         data->length = pAdapter->CommonCfg.SsidLen;
1268                 memcpy(essid, pAdapter->CommonCfg.Ssid, pAdapter->CommonCfg.SsidLen);
1269         }
1270 #endif // RT2870 //
1271         else
1272         {//the ANY ssid was specified
1273                 data->length  = 0;
1274                 DBGPRINT(RT_DEBUG_TRACE ,("MediaState is not connected, ess\n"));
1275         }
1276
1277         return 0;
1278
1279 }
1280
1281 int rt_ioctl_siwnickn(struct net_device *dev,
1282                          struct iw_request_info *info,
1283                          struct iw_point *data, char *nickname)
1284 {
1285         PRTMP_ADAPTER pAdapter = dev->ml_priv;
1286
1287     //check if the interface is down
1288     if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
1289     {
1290         DBGPRINT(RT_DEBUG_TRACE ,("INFO::Network is down!\n"));
1291         return -ENETDOWN;
1292     }
1293
1294         if (data->length > IW_ESSID_MAX_SIZE)
1295                 return -EINVAL;
1296
1297         memset(pAdapter->nickname, 0, IW_ESSID_MAX_SIZE + 1);
1298         memcpy(pAdapter->nickname, nickname, data->length);
1299
1300
1301         return 0;
1302 }
1303
1304 int rt_ioctl_giwnickn(struct net_device *dev,
1305                          struct iw_request_info *info,
1306                          struct iw_point *data, char *nickname)
1307 {
1308         PRTMP_ADAPTER pAdapter = dev->ml_priv;
1309
1310         if (data->length > strlen(pAdapter->nickname) + 1)
1311                 data->length = strlen(pAdapter->nickname) + 1;
1312         if (data->length > 0) {
1313                 memcpy(nickname, pAdapter->nickname, data->length-1);
1314                 nickname[data->length-1] = '\0';
1315         }
1316         return 0;
1317 }
1318
1319 int rt_ioctl_siwrts(struct net_device *dev,
1320                        struct iw_request_info *info,
1321                        struct iw_param *rts, char *extra)
1322 {
1323         PRTMP_ADAPTER pAdapter = dev->ml_priv;
1324         u16 val;
1325
1326     //check if the interface is down
1327     if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
1328     {
1329         DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
1330         return -ENETDOWN;
1331     }
1332
1333         if (rts->disabled)
1334                 val = MAX_RTS_THRESHOLD;
1335         else if (rts->value < 0 || rts->value > MAX_RTS_THRESHOLD)
1336                 return -EINVAL;
1337         else if (rts->value == 0)
1338             val = MAX_RTS_THRESHOLD;
1339         else
1340                 val = rts->value;
1341
1342         if (val != pAdapter->CommonCfg.RtsThreshold)
1343                 pAdapter->CommonCfg.RtsThreshold = val;
1344
1345         return 0;
1346 }
1347
1348 int rt_ioctl_giwrts(struct net_device *dev,
1349                        struct iw_request_info *info,
1350                        struct iw_param *rts, char *extra)
1351 {
1352         PRTMP_ADAPTER pAdapter = dev->ml_priv;
1353
1354         //check if the interface is down
1355         if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
1356         {
1357                 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
1358                 return -ENETDOWN;
1359         }
1360
1361         rts->value = pAdapter->CommonCfg.RtsThreshold;
1362         rts->disabled = (rts->value == MAX_RTS_THRESHOLD);
1363         rts->fixed = 1;
1364
1365         return 0;
1366 }
1367
1368 int rt_ioctl_siwfrag(struct net_device *dev,
1369                         struct iw_request_info *info,
1370                         struct iw_param *frag, char *extra)
1371 {
1372         PRTMP_ADAPTER pAdapter = dev->ml_priv;
1373         u16 val;
1374
1375         //check if the interface is down
1376         if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
1377         {
1378                 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
1379                 return -ENETDOWN;
1380         }
1381
1382         if (frag->disabled)
1383                 val = MAX_FRAG_THRESHOLD;
1384         else if (frag->value >= MIN_FRAG_THRESHOLD || frag->value <= MAX_FRAG_THRESHOLD)
1385         val = __cpu_to_le16(frag->value & ~0x1); /* even numbers only */
1386         else if (frag->value == 0)
1387             val = MAX_FRAG_THRESHOLD;
1388         else
1389                 return -EINVAL;
1390
1391         pAdapter->CommonCfg.FragmentThreshold = val;
1392         return 0;
1393 }
1394
1395 int rt_ioctl_giwfrag(struct net_device *dev,
1396                         struct iw_request_info *info,
1397                         struct iw_param *frag, char *extra)
1398 {
1399         PRTMP_ADAPTER pAdapter = dev->ml_priv;
1400
1401         //check if the interface is down
1402         if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
1403         {
1404                 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
1405                 return -ENETDOWN;
1406         }
1407
1408         frag->value = pAdapter->CommonCfg.FragmentThreshold;
1409         frag->disabled = (frag->value == MAX_FRAG_THRESHOLD);
1410         frag->fixed = 1;
1411
1412         return 0;
1413 }
1414
1415 #define MAX_WEP_KEY_SIZE 13
1416 #define MIN_WEP_KEY_SIZE 5
1417 int rt_ioctl_siwencode(struct net_device *dev,
1418                           struct iw_request_info *info,
1419                           struct iw_point *erq, char *extra)
1420 {
1421         PRTMP_ADAPTER pAdapter = dev->ml_priv;
1422
1423         //check if the interface is down
1424         if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
1425         {
1426                 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
1427                 return -ENETDOWN;
1428         }
1429
1430         if ((erq->length == 0) &&
1431         (erq->flags & IW_ENCODE_DISABLED))
1432         {
1433                 pAdapter->StaCfg.PairCipher = Ndis802_11WEPDisabled;
1434                 pAdapter->StaCfg.GroupCipher = Ndis802_11WEPDisabled;
1435                 pAdapter->StaCfg.WepStatus = Ndis802_11WEPDisabled;
1436         pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
1437         pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
1438         goto done;
1439         } else if (
1440                  (erq->flags & IW_ENCODE_RESTRICTED || erq->flags & IW_ENCODE_OPEN)) {
1441                 STA_PORT_SECURED(pAdapter);
1442                 pAdapter->StaCfg.PairCipher = Ndis802_11WEPEnabled;
1443                 pAdapter->StaCfg.GroupCipher = Ndis802_11WEPEnabled;
1444                 pAdapter->StaCfg.WepStatus = Ndis802_11WEPEnabled;
1445         pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
1446                 if (erq->flags & IW_ENCODE_RESTRICTED)
1447                         pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeShared;
1448         else
1449                         pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
1450         }
1451
1452     if (erq->length > 0)
1453         {
1454                 int keyIdx = (erq->flags & IW_ENCODE_INDEX) - 1;
1455                 /* Check the size of the key */
1456                 if (erq->length > MAX_WEP_KEY_SIZE) {
1457                         return -EINVAL;
1458                 }
1459                 /* Check key index */
1460                 if ((keyIdx < 0) || (keyIdx >= NR_WEP_KEYS))
1461         {
1462             DBGPRINT(RT_DEBUG_TRACE ,("==>rt_ioctl_siwencode::Wrong keyIdx=%d! Using default key instead (%d)\n",
1463                                         keyIdx, pAdapter->StaCfg.DefaultKeyId));
1464
1465             //Using default key
1466                         keyIdx = pAdapter->StaCfg.DefaultKeyId;
1467         }
1468                 else
1469                         pAdapter->StaCfg.DefaultKeyId=keyIdx;
1470
1471         NdisZeroMemory(pAdapter->SharedKey[BSS0][keyIdx].Key,  16);
1472
1473                 if (erq->length == MAX_WEP_KEY_SIZE)
1474         {
1475                         pAdapter->SharedKey[BSS0][keyIdx].KeyLen = MAX_WEP_KEY_SIZE;
1476             pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = CIPHER_WEP128;
1477                 }
1478                 else if (erq->length == MIN_WEP_KEY_SIZE)
1479         {
1480             pAdapter->SharedKey[BSS0][keyIdx].KeyLen = MIN_WEP_KEY_SIZE;
1481             pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = CIPHER_WEP64;
1482                 }
1483                 else
1484                         /* Disable the key */
1485                         pAdapter->SharedKey[BSS0][keyIdx].KeyLen = 0;
1486
1487                 /* Check if the key is not marked as invalid */
1488                 if(!(erq->flags & IW_ENCODE_NOKEY)) {
1489                         /* Copy the key in the driver */
1490                         NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].Key, extra, erq->length);
1491         }
1492         }
1493     else
1494                         {
1495                 /* Do we want to just set the transmit key index ? */
1496                 int index = (erq->flags & IW_ENCODE_INDEX) - 1;
1497                 if ((index >= 0) && (index < 4))
1498         {
1499                         pAdapter->StaCfg.DefaultKeyId = index;
1500             }
1501         else
1502                         /* Don't complain if only change the mode */
1503                         if (!(erq->flags & IW_ENCODE_MODE)) {
1504                                 return -EINVAL;
1505                 }
1506         }
1507
1508 done:
1509     DBGPRINT(RT_DEBUG_TRACE ,("==>rt_ioctl_siwencode::erq->flags=%x\n",erq->flags));
1510         DBGPRINT(RT_DEBUG_TRACE ,("==>rt_ioctl_siwencode::AuthMode=%x\n",pAdapter->StaCfg.AuthMode));
1511         DBGPRINT(RT_DEBUG_TRACE ,("==>rt_ioctl_siwencode::DefaultKeyId=%x, KeyLen = %d\n",pAdapter->StaCfg.DefaultKeyId , pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].KeyLen));
1512         DBGPRINT(RT_DEBUG_TRACE ,("==>rt_ioctl_siwencode::WepStatus=%x\n",pAdapter->StaCfg.WepStatus));
1513         return 0;
1514 }
1515
1516 int
1517 rt_ioctl_giwencode(struct net_device *dev,
1518                           struct iw_request_info *info,
1519                           struct iw_point *erq, char *key)
1520 {
1521         PRTMP_ADAPTER pAdapter = dev->ml_priv;
1522         int kid;
1523
1524         //check if the interface is down
1525         if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
1526         {
1527                 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
1528         return -ENETDOWN;
1529         }
1530
1531         kid = erq->flags & IW_ENCODE_INDEX;
1532         DBGPRINT(RT_DEBUG_TRACE, ("===>rt_ioctl_giwencode %d\n", erq->flags & IW_ENCODE_INDEX));
1533
1534         if (pAdapter->StaCfg.WepStatus == Ndis802_11WEPDisabled)
1535         {
1536                 erq->length = 0;
1537                 erq->flags = IW_ENCODE_DISABLED;
1538         }
1539         else if ((kid > 0) && (kid <=4))
1540         {
1541                 // copy wep key
1542                 erq->flags = kid ;                      /* NB: base 1 */
1543                 if (erq->length > pAdapter->SharedKey[BSS0][kid-1].KeyLen)
1544                         erq->length = pAdapter->SharedKey[BSS0][kid-1].KeyLen;
1545                 memcpy(key, pAdapter->SharedKey[BSS0][kid-1].Key, erq->length);
1546                 //if ((kid == pAdapter->PortCfg.DefaultKeyId))
1547                 //erq->flags |= IW_ENCODE_ENABLED;      /* XXX */
1548                 if (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeShared)
1549                         erq->flags |= IW_ENCODE_RESTRICTED;             /* XXX */
1550                 else
1551                         erq->flags |= IW_ENCODE_OPEN;           /* XXX */
1552
1553         }
1554         else if (kid == 0)
1555         {
1556                 if (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeShared)
1557                         erq->flags |= IW_ENCODE_RESTRICTED;             /* XXX */
1558                 else
1559                         erq->flags |= IW_ENCODE_OPEN;           /* XXX */
1560                 erq->length = pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].KeyLen;
1561                 memcpy(key, pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].Key, erq->length);
1562                 // copy default key ID
1563                 if (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeShared)
1564                         erq->flags |= IW_ENCODE_RESTRICTED;             /* XXX */
1565                 else
1566                         erq->flags |= IW_ENCODE_OPEN;           /* XXX */
1567                 erq->flags = pAdapter->StaCfg.DefaultKeyId + 1;                 /* NB: base 1 */
1568                 erq->flags |= IW_ENCODE_ENABLED;        /* XXX */
1569         }
1570
1571         return 0;
1572
1573 }
1574
1575 static int
1576 rt_ioctl_setparam(struct net_device *dev, struct iw_request_info *info,
1577                          void *w, char *extra)
1578 {
1579         PRTMP_ADAPTER pAdapter = dev->ml_priv;
1580         POS_COOKIE pObj = (POS_COOKIE)pAdapter->OS_Cookie;
1581         char *this_char = extra;
1582         char *value;
1583         int  Status=0;
1584
1585         {
1586                 pObj->ioctl_if_type = INT_MAIN;
1587         pObj->ioctl_if = MAIN_MBSSID;
1588         }
1589
1590         //check if the interface is down
1591         if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
1592         {
1593                 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
1594                         return -ENETDOWN;
1595         }
1596
1597         if (!*this_char)
1598                 return -EINVAL;
1599
1600         if ((value = rtstrchr(this_char, '=')) != NULL)
1601             *value++ = 0;
1602
1603         if (!value)
1604             return -EINVAL;
1605
1606         // reject setting nothing besides ANY ssid(ssidLen=0)
1607     if (!*value && (strcmp(this_char, "SSID") != 0))
1608         return -EINVAL;
1609
1610         for (PRTMP_PRIVATE_SET_PROC = RTMP_PRIVATE_SUPPORT_PROC; PRTMP_PRIVATE_SET_PROC->name; PRTMP_PRIVATE_SET_PROC++)
1611         {
1612             if (strcmp(this_char, PRTMP_PRIVATE_SET_PROC->name) == 0)
1613             {
1614                 if(!PRTMP_PRIVATE_SET_PROC->set_proc(pAdapter, value))
1615                 {       //FALSE:Set private failed then return Invalid argument
1616                             Status = -EINVAL;
1617                 }
1618                     break;      //Exit for loop.
1619             }
1620         }
1621
1622         if(PRTMP_PRIVATE_SET_PROC->name == NULL)
1623         {  //Not found argument
1624             Status = -EINVAL;
1625             DBGPRINT(RT_DEBUG_TRACE, ("===>rt_ioctl_setparam:: (iwpriv) Not Support Set Command [%s=%s]\n", this_char, value));
1626         }
1627
1628     return Status;
1629 }
1630
1631
1632 static int
1633 rt_private_get_statistics(struct net_device *dev, struct iw_request_info *info,
1634                 struct iw_point *wrq, char *extra)
1635 {
1636         INT                             Status = 0;
1637     PRTMP_ADAPTER   pAd = dev->ml_priv;
1638
1639     if (extra == NULL)
1640     {
1641         wrq->length = 0;
1642         return -EIO;
1643     }
1644
1645     memset(extra, 0x00, IW_PRIV_SIZE_MASK);
1646     sprintf(extra, "\n\n");
1647
1648         {
1649     sprintf(extra+strlen(extra), "Tx success                      = %ld\n", (ULONG)pAd->WlanCounters.TransmittedFragmentCount.QuadPart);
1650     sprintf(extra+strlen(extra), "Tx success without retry        = %ld\n", (ULONG)pAd->WlanCounters.TransmittedFragmentCount.QuadPart - (ULONG)pAd->WlanCounters.RetryCount.QuadPart);
1651         }
1652     sprintf(extra+strlen(extra), "Tx success after retry          = %ld\n", (ULONG)pAd->WlanCounters.RetryCount.QuadPart);
1653     sprintf(extra+strlen(extra), "Tx fail to Rcv ACK after retry  = %ld\n", (ULONG)pAd->WlanCounters.FailedCount.QuadPart);
1654     sprintf(extra+strlen(extra), "RTS Success Rcv CTS             = %ld\n", (ULONG)pAd->WlanCounters.RTSSuccessCount.QuadPart);
1655     sprintf(extra+strlen(extra), "RTS Fail Rcv CTS                = %ld\n", (ULONG)pAd->WlanCounters.RTSFailureCount.QuadPart);
1656
1657     sprintf(extra+strlen(extra), "Rx success                      = %ld\n", (ULONG)pAd->WlanCounters.ReceivedFragmentCount.QuadPart);
1658     sprintf(extra+strlen(extra), "Rx with CRC                     = %ld\n", (ULONG)pAd->WlanCounters.FCSErrorCount.QuadPart);
1659     sprintf(extra+strlen(extra), "Rx drop due to out of resource  = %ld\n", (ULONG)pAd->Counters8023.RxNoBuffer);
1660     sprintf(extra+strlen(extra), "Rx duplicate frame              = %ld\n", (ULONG)pAd->WlanCounters.FrameDuplicateCount.QuadPart);
1661
1662     sprintf(extra+strlen(extra), "False CCA (one second)          = %ld\n", (ULONG)pAd->RalinkCounters.OneSecFalseCCACnt);
1663         {
1664         sprintf(extra+strlen(extra), "RSSI-A                          = %ld\n", (LONG)(pAd->StaCfg.RssiSample.LastRssi0 - pAd->BbpRssiToDbmDelta));
1665         sprintf(extra+strlen(extra), "RSSI-B (if available)           = %ld\n", (LONG)(pAd->StaCfg.RssiSample.LastRssi1 - pAd->BbpRssiToDbmDelta));
1666         sprintf(extra+strlen(extra), "RSSI-C (if available)           = %ld\n\n", (LONG)(pAd->StaCfg.RssiSample.LastRssi2 - pAd->BbpRssiToDbmDelta));
1667         }
1668     sprintf(extra+strlen(extra), "WpaSupplicantUP                 = %d\n\n", pAd->StaCfg.WpaSupplicantUP);
1669
1670     wrq->length = strlen(extra) + 1; // 1: size of '\0'
1671     DBGPRINT(RT_DEBUG_TRACE, ("<== rt_private_get_statistics, wrq->length = %d\n", wrq->length));
1672
1673     return Status;
1674 }
1675
1676 void    getBaInfo(
1677         IN      PRTMP_ADAPTER   pAd,
1678         IN      PUCHAR                  pOutBuf)
1679 {
1680         INT i, j;
1681         BA_ORI_ENTRY *pOriBAEntry;
1682         BA_REC_ENTRY *pRecBAEntry;
1683
1684         for (i=0; i<MAX_LEN_OF_MAC_TABLE; i++)
1685         {
1686                 PMAC_TABLE_ENTRY pEntry = &pAd->MacTab.Content[i];
1687                 if (((pEntry->ValidAsCLI || pEntry->ValidAsApCli) && (pEntry->Sst == SST_ASSOC))
1688                         || (pEntry->ValidAsWDS) || (pEntry->ValidAsMesh))
1689                 {
1690                         sprintf(pOutBuf + strlen(pOutBuf), "\n%02X:%02X:%02X:%02X:%02X:%02X (Aid = %d) (AP) -\n",
1691                                 pEntry->Addr[0], pEntry->Addr[1], pEntry->Addr[2],
1692                                 pEntry->Addr[3], pEntry->Addr[4], pEntry->Addr[5], pEntry->Aid);
1693
1694                         sprintf(pOutBuf, "%s[Recipient]\n", pOutBuf);
1695                         for (j=0; j < NUM_OF_TID; j++)
1696                         {
1697                                 if (pEntry->BARecWcidArray[j] != 0)
1698                                 {
1699                                         pRecBAEntry =&pAd->BATable.BARecEntry[pEntry->BARecWcidArray[j]];
1700                                         sprintf(pOutBuf + strlen(pOutBuf), "TID=%d, BAWinSize=%d, LastIndSeq=%d, ReorderingPkts=%d\n", j, pRecBAEntry->BAWinSize, pRecBAEntry->LastIndSeq, pRecBAEntry->list.qlen);
1701                                 }
1702                         }
1703                         sprintf(pOutBuf, "%s\n", pOutBuf);
1704
1705                         sprintf(pOutBuf, "%s[Originator]\n", pOutBuf);
1706                         for (j=0; j < NUM_OF_TID; j++)
1707                         {
1708                                 if (pEntry->BAOriWcidArray[j] != 0)
1709                                 {
1710                                         pOriBAEntry =&pAd->BATable.BAOriEntry[pEntry->BAOriWcidArray[j]];
1711                                         sprintf(pOutBuf + strlen(pOutBuf), "TID=%d, BAWinSize=%d, StartSeq=%d, CurTxSeq=%d\n", j, pOriBAEntry->BAWinSize, pOriBAEntry->Sequence, pEntry->TxSeq[j]);
1712                                 }
1713                         }
1714                         sprintf(pOutBuf, "%s\n\n", pOutBuf);
1715                 }
1716         if (strlen(pOutBuf) > (IW_PRIV_SIZE_MASK - 30))
1717                 break;
1718         }
1719
1720         return;
1721 }
1722
1723 static int
1724 rt_private_show(struct net_device *dev, struct iw_request_info *info,
1725                 struct iw_point *wrq, char *extra)
1726 {
1727     INT                         Status = 0;
1728     PRTMP_ADAPTER pAd = dev->ml_priv;
1729     POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
1730     u32             subcmd = wrq->flags;
1731
1732     if (extra == NULL)
1733     {
1734         wrq->length = 0;
1735         return -EIO;
1736     }
1737     memset(extra, 0x00, IW_PRIV_SIZE_MASK);
1738
1739         {
1740                 pObj->ioctl_if_type = INT_MAIN;
1741         pObj->ioctl_if = MAIN_MBSSID;
1742         }
1743
1744     switch(subcmd)
1745     {
1746
1747         case SHOW_CONN_STATUS:
1748             if (MONITOR_ON(pAd))
1749             {
1750                 if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED &&
1751                     pAd->CommonCfg.RegTransmitSetting.field.BW)
1752                     sprintf(extra, "Monitor Mode(CentralChannel %d)\n", pAd->CommonCfg.CentralChannel);
1753                 else
1754                     sprintf(extra, "Monitor Mode(Channel %d)\n", pAd->CommonCfg.Channel);
1755             }
1756             else
1757             {
1758                 if (pAd->IndicateMediaState == NdisMediaStateConnected)
1759                 {
1760                     if (INFRA_ON(pAd))
1761                     {
1762                     sprintf(extra, "Connected(AP: %s[%02X:%02X:%02X:%02X:%02X:%02X])\n",
1763                                     pAd->CommonCfg.Ssid,
1764                                     pAd->CommonCfg.Bssid[0],
1765                                     pAd->CommonCfg.Bssid[1],
1766                                     pAd->CommonCfg.Bssid[2],
1767                                     pAd->CommonCfg.Bssid[3],
1768                                     pAd->CommonCfg.Bssid[4],
1769                                     pAd->CommonCfg.Bssid[5]);
1770                         DBGPRINT(RT_DEBUG_TRACE ,("Ssid=%s ,Ssidlen = %d\n",pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen));
1771                 }
1772                     else if (ADHOC_ON(pAd))
1773                         sprintf(extra, "Connected\n");
1774                 }
1775                 else
1776                 {
1777                     sprintf(extra, "Disconnected\n");
1778                         DBGPRINT(RT_DEBUG_TRACE ,("ConnStatus is not connected\n"));
1779                 }
1780             }
1781             wrq->length = strlen(extra) + 1; // 1: size of '\0'
1782             break;
1783         case SHOW_DRVIER_VERION:
1784             sprintf(extra, "Driver version-%s, %s %s\n", STA_DRIVER_VERSION, __DATE__, __TIME__ );
1785             wrq->length = strlen(extra) + 1; // 1: size of '\0'
1786             break;
1787         case SHOW_BA_INFO:
1788             getBaInfo(pAd, extra);
1789             wrq->length = strlen(extra) + 1; // 1: size of '\0'
1790             break;
1791                 case SHOW_DESC_INFO:
1792                         {
1793                                 Show_DescInfo_Proc(pAd, NULL);
1794                                 wrq->length = 0; // 1: size of '\0'
1795                         }
1796                         break;
1797         case RAIO_OFF:
1798             if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
1799             {
1800                 sprintf(extra, "Scanning\n");
1801                 wrq->length = strlen(extra) + 1; // 1: size of '\0'
1802                 break;
1803             }
1804             pAd->StaCfg.bSwRadio = FALSE;
1805             if (pAd->StaCfg.bRadio != (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio))
1806             {
1807                 pAd->StaCfg.bRadio = (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio);
1808                 if (pAd->StaCfg.bRadio == FALSE)
1809                 {
1810                     MlmeRadioOff(pAd);
1811                     // Update extra information
1812                                         pAd->ExtraInfo = SW_RADIO_OFF;
1813                 }
1814             }
1815             sprintf(extra, "Radio Off\n");
1816             wrq->length = strlen(extra) + 1; // 1: size of '\0'
1817             break;
1818         case RAIO_ON:
1819 #ifdef RT2870
1820             if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
1821             {
1822                 sprintf(extra, "Scanning\n");
1823                 wrq->length = strlen(extra) + 1; // 1: size of '\0'
1824                 break;
1825             }
1826 #endif
1827             pAd->StaCfg.bSwRadio = TRUE;
1828             //if (pAd->StaCfg.bRadio != (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio))
1829             {
1830                 pAd->StaCfg.bRadio = (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio);
1831                 if (pAd->StaCfg.bRadio == TRUE)
1832                 {
1833                     MlmeRadioOn(pAd);
1834                     // Update extra information
1835                                         pAd->ExtraInfo = EXTRA_INFO_CLEAR;
1836                 }
1837             }
1838             sprintf(extra, "Radio On\n");
1839             wrq->length = strlen(extra) + 1; // 1: size of '\0'
1840             break;
1841
1842                 case SHOW_CFG_VALUE:
1843                         {
1844                                 Status = RTMPShowCfgValue(pAd, wrq->pointer, extra);
1845                                 if (Status == 0)
1846                                         wrq->length = strlen(extra) + 1; // 1: size of '\0'
1847                         }
1848                         break;
1849 #if !defined(RT2860) && !defined(RT30xx)
1850                 case SHOW_ADHOC_ENTRY_INFO:
1851                         Show_Adhoc_MacTable_Proc(pAd, extra);
1852                         wrq->length = strlen(extra) + 1; // 1: size of '\0'
1853                         break;
1854 #endif
1855         default:
1856             DBGPRINT(RT_DEBUG_TRACE, ("%s - unknow subcmd = %d\n", __func__, subcmd));
1857             break;
1858     }
1859
1860     return Status;
1861 }
1862
1863 int rt_ioctl_siwmlme(struct net_device *dev,
1864                            struct iw_request_info *info,
1865                            union iwreq_data *wrqu,
1866                            char *extra)
1867 {
1868         PRTMP_ADAPTER   pAd = dev->ml_priv;
1869         struct iw_mlme *pMlme = (struct iw_mlme *)wrqu->data.pointer;
1870         MLME_QUEUE_ELEM                         MsgElem;
1871         MLME_DISASSOC_REQ_STRUCT        DisAssocReq;
1872         MLME_DEAUTH_REQ_STRUCT      DeAuthReq;
1873
1874         DBGPRINT(RT_DEBUG_TRACE, ("====> %s\n", __func__));
1875
1876         if (pMlme == NULL)
1877                 return -EINVAL;
1878
1879         switch(pMlme->cmd)
1880         {
1881 #ifdef IW_MLME_DEAUTH
1882                 case IW_MLME_DEAUTH:
1883                         DBGPRINT(RT_DEBUG_TRACE, ("====> %s - IW_MLME_DEAUTH\n", __func__));
1884                         COPY_MAC_ADDR(DeAuthReq.Addr, pAd->CommonCfg.Bssid);
1885                         DeAuthReq.Reason = pMlme->reason_code;
1886                         MsgElem.MsgLen = sizeof(MLME_DEAUTH_REQ_STRUCT);
1887                         NdisMoveMemory(MsgElem.Msg, &DeAuthReq, sizeof(MLME_DEAUTH_REQ_STRUCT));
1888                         MlmeDeauthReqAction(pAd, &MsgElem);
1889                         if (INFRA_ON(pAd))
1890                         {
1891                             LinkDown(pAd, FALSE);
1892                             pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
1893                         }
1894                         break;
1895 #endif // IW_MLME_DEAUTH //
1896 #ifdef IW_MLME_DISASSOC
1897                 case IW_MLME_DISASSOC:
1898                         DBGPRINT(RT_DEBUG_TRACE, ("====> %s - IW_MLME_DISASSOC\n", __func__));
1899                         COPY_MAC_ADDR(DisAssocReq.Addr, pAd->CommonCfg.Bssid);
1900                         DisAssocReq.Reason =  pMlme->reason_code;
1901
1902                         MsgElem.Machine = ASSOC_STATE_MACHINE;
1903                         MsgElem.MsgType = MT2_MLME_DISASSOC_REQ;
1904                         MsgElem.MsgLen = sizeof(MLME_DISASSOC_REQ_STRUCT);
1905                         NdisMoveMemory(MsgElem.Msg, &DisAssocReq, sizeof(MLME_DISASSOC_REQ_STRUCT));
1906
1907                         pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_DISASSOC;
1908                         MlmeDisassocReqAction(pAd, &MsgElem);
1909                         break;
1910 #endif // IW_MLME_DISASSOC //
1911                 default:
1912                         DBGPRINT(RT_DEBUG_TRACE, ("====> %s - Unknow Command\n", __func__));
1913                         break;
1914         }
1915
1916         return 0;
1917 }
1918
1919 int rt_ioctl_siwauth(struct net_device *dev,
1920                           struct iw_request_info *info,
1921                           union iwreq_data *wrqu, char *extra)
1922 {
1923         PRTMP_ADAPTER   pAdapter = dev->ml_priv;
1924         struct iw_param *param = &wrqu->param;
1925
1926     //check if the interface is down
1927         if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
1928         {
1929                 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
1930         return -ENETDOWN;
1931         }
1932         switch (param->flags & IW_AUTH_INDEX) {
1933         case IW_AUTH_WPA_VERSION:
1934             if (param->value == IW_AUTH_WPA_VERSION_WPA)
1935             {
1936                 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPAPSK;
1937                                 if (pAdapter->StaCfg.BssType == BSS_ADHOC)
1938                                         pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPANone;
1939             }
1940             else if (param->value == IW_AUTH_WPA_VERSION_WPA2)
1941                 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPA2PSK;
1942
1943             DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_WPA_VERSION - param->value = %d!\n", __func__, param->value));
1944             break;
1945         case IW_AUTH_CIPHER_PAIRWISE:
1946             if (param->value == IW_AUTH_CIPHER_NONE)
1947             {
1948                 pAdapter->StaCfg.WepStatus = Ndis802_11WEPDisabled;
1949                 pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
1950                 pAdapter->StaCfg.PairCipher = Ndis802_11WEPDisabled;
1951             }
1952             else if (param->value == IW_AUTH_CIPHER_WEP40 ||
1953                      param->value == IW_AUTH_CIPHER_WEP104)
1954             {
1955                 pAdapter->StaCfg.WepStatus = Ndis802_11WEPEnabled;
1956                 pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
1957                 pAdapter->StaCfg.PairCipher = Ndis802_11WEPEnabled;
1958                 pAdapter->StaCfg.IEEE8021X = FALSE;
1959             }
1960             else if (param->value == IW_AUTH_CIPHER_TKIP)
1961             {
1962                 pAdapter->StaCfg.WepStatus = Ndis802_11Encryption2Enabled;
1963                 pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
1964                 pAdapter->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
1965             }
1966             else if (param->value == IW_AUTH_CIPHER_CCMP)
1967             {
1968                 pAdapter->StaCfg.WepStatus = Ndis802_11Encryption3Enabled;
1969                 pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
1970                 pAdapter->StaCfg.PairCipher = Ndis802_11Encryption3Enabled;
1971             }
1972             DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_CIPHER_PAIRWISE - param->value = %d!\n", __func__, param->value));
1973             break;
1974         case IW_AUTH_CIPHER_GROUP:
1975             if (param->value == IW_AUTH_CIPHER_NONE)
1976             {
1977                 pAdapter->StaCfg.GroupCipher = Ndis802_11WEPDisabled;
1978             }
1979             else if (param->value == IW_AUTH_CIPHER_WEP40 ||
1980                      param->value == IW_AUTH_CIPHER_WEP104)
1981             {
1982                 pAdapter->StaCfg.GroupCipher = Ndis802_11WEPEnabled;
1983             }
1984             else if (param->value == IW_AUTH_CIPHER_TKIP)
1985             {
1986                 pAdapter->StaCfg.GroupCipher = Ndis802_11Encryption2Enabled;
1987             }
1988             else if (param->value == IW_AUTH_CIPHER_CCMP)
1989             {
1990                 pAdapter->StaCfg.GroupCipher = Ndis802_11Encryption3Enabled;
1991             }
1992             DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_CIPHER_GROUP - param->value = %d!\n", __func__, param->value));
1993             break;
1994         case IW_AUTH_KEY_MGMT:
1995             if (param->value == IW_AUTH_KEY_MGMT_802_1X)
1996             {
1997                 if (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK)
1998                 {
1999                     pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPA;
2000                     pAdapter->StaCfg.IEEE8021X = FALSE;
2001                 }
2002                 else if (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)
2003                 {
2004                     pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPA2;
2005                     pAdapter->StaCfg.IEEE8021X = FALSE;
2006                 }
2007                 else
2008                     // WEP 1x
2009                     pAdapter->StaCfg.IEEE8021X = TRUE;
2010             }
2011             else if (param->value == 0)
2012             {
2013                                 STA_PORT_SECURED(pAdapter);
2014             }
2015             DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_KEY_MGMT - param->value = %d!\n", __func__, param->value));
2016             break;
2017         case IW_AUTH_RX_UNENCRYPTED_EAPOL:
2018             break;
2019         case IW_AUTH_PRIVACY_INVOKED:
2020             DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_PRIVACY_INVOKED - param->value = %d!\n", __func__, param->value));
2021                 break;
2022         case IW_AUTH_DROP_UNENCRYPTED:
2023             if (param->value != 0)
2024                 pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
2025                         else
2026                         {
2027                                 STA_PORT_SECURED(pAdapter);
2028                         }
2029             DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_WPA_VERSION - param->value = %d!\n", __func__, param->value));
2030                 break;
2031         case IW_AUTH_80211_AUTH_ALG:
2032                         if (param->value & IW_AUTH_ALG_SHARED_KEY)
2033             {
2034                                 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeShared;
2035                         }
2036             else if (param->value & IW_AUTH_ALG_OPEN_SYSTEM)
2037             {
2038                                 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
2039                         }
2040             else
2041                                 return -EINVAL;
2042             DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_80211_AUTH_ALG - param->value = %d!\n", __func__, param->value));
2043                         break;
2044         case IW_AUTH_WPA_ENABLED:
2045                 DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_WPA_ENABLED - Driver supports WPA!(param->value = %d)\n", __func__, param->value));
2046                 break;
2047         default:
2048                 return -EOPNOTSUPP;
2049 }
2050
2051         return 0;
2052 }
2053
2054 int rt_ioctl_giwauth(struct net_device *dev,
2055                                struct iw_request_info *info,
2056                                union iwreq_data *wrqu, char *extra)
2057 {
2058         PRTMP_ADAPTER   pAdapter = dev->ml_priv;
2059         struct iw_param *param = &wrqu->param;
2060
2061     //check if the interface is down
2062         if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
2063     {
2064                 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
2065         return -ENETDOWN;
2066     }
2067
2068         switch (param->flags & IW_AUTH_INDEX) {
2069         case IW_AUTH_DROP_UNENCRYPTED:
2070         param->value = (pAdapter->StaCfg.WepStatus == Ndis802_11WEPDisabled) ? 0 : 1;
2071                 break;
2072
2073         case IW_AUTH_80211_AUTH_ALG:
2074         param->value = (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeShared) ? IW_AUTH_ALG_SHARED_KEY : IW_AUTH_ALG_OPEN_SYSTEM;
2075                 break;
2076
2077         case IW_AUTH_WPA_ENABLED:
2078                 param->value = (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA) ? 1 : 0;
2079                 break;
2080
2081         default:
2082                 return -EOPNOTSUPP;
2083         }
2084     DBGPRINT(RT_DEBUG_TRACE, ("rt_ioctl_giwauth::param->value = %d!\n", param->value));
2085         return 0;
2086 }
2087
2088 void fnSetCipherKey(
2089     IN  PRTMP_ADAPTER   pAdapter,
2090     IN  INT             keyIdx,
2091     IN  UCHAR           CipherAlg,
2092     IN  BOOLEAN         bGTK,
2093     IN  struct iw_encode_ext *ext)
2094 {
2095 #ifdef RT2860
2096         RTMP_CLEAR_PSFLAG(pAdapter, fRTMP_PS_CAN_GO_SLEEP);
2097         if (RTMP_TEST_PSFLAG(pAdapter, fRTMP_PS_SET_PCI_CLK_OFF_COMMAND))
2098         {
2099                 if (pAdapter->StaCfg.bRadio == FALSE)
2100                 {
2101                         RTMP_SET_PSFLAG(pAdapter, fRTMP_PS_CAN_GO_SLEEP);
2102                         return;
2103                 }
2104                 DBGPRINT(RT_DEBUG_TRACE,("RTMPWPAAddKeyProc1==>\n"));
2105                 RTMPPCIeLinkCtrlValueRestore(pAdapter, RESTORE_HALT);
2106                 RTMPusecDelay(6000);
2107                 pAdapter->bPCIclkOff = FALSE;
2108         }
2109 #endif
2110     NdisZeroMemory(&pAdapter->SharedKey[BSS0][keyIdx], sizeof(CIPHER_KEY));
2111     pAdapter->SharedKey[BSS0][keyIdx].KeyLen = LEN_TKIP_EK;
2112     NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].Key, ext->key, LEN_TKIP_EK);
2113     NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].TxMic, ext->key + LEN_TKIP_EK, LEN_TKIP_TXMICK);
2114     NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].RxMic, ext->key + LEN_TKIP_EK + LEN_TKIP_TXMICK, LEN_TKIP_RXMICK);
2115     pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = CipherAlg;
2116
2117     // Update group key information to ASIC Shared Key Table
2118         AsicAddSharedKeyEntry(pAdapter,
2119                                                   BSS0,
2120                                                   keyIdx,
2121                                                   pAdapter->SharedKey[BSS0][keyIdx].CipherAlg,
2122                                                   pAdapter->SharedKey[BSS0][keyIdx].Key,
2123                                                   pAdapter->SharedKey[BSS0][keyIdx].TxMic,
2124                                                   pAdapter->SharedKey[BSS0][keyIdx].RxMic);
2125
2126     if (bGTK)
2127         // Update ASIC WCID attribute table and IVEIV table
2128         RTMPAddWcidAttributeEntry(pAdapter,
2129                                                           BSS0,
2130                                                           keyIdx,
2131                                                           pAdapter->SharedKey[BSS0][keyIdx].CipherAlg,
2132                                                           NULL);
2133     else
2134         // Update ASIC WCID attribute table and IVEIV table
2135         RTMPAddWcidAttributeEntry(pAdapter,
2136                                                           BSS0,
2137                                                           keyIdx,
2138                                                           pAdapter->SharedKey[BSS0][keyIdx].CipherAlg,
2139                                                           &pAdapter->MacTab.Content[BSSID_WCID]);
2140 #ifdef RT2860
2141         RTMP_SET_PSFLAG(pAdapter, fRTMP_PS_CAN_GO_SLEEP);
2142 #endif
2143 }
2144
2145 int rt_ioctl_siwencodeext(struct net_device *dev,
2146                            struct iw_request_info *info,
2147                            union iwreq_data *wrqu,
2148                            char *extra)
2149                         {
2150     PRTMP_ADAPTER   pAdapter = dev->ml_priv;
2151         struct iw_point *encoding = &wrqu->encoding;
2152         struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
2153     int keyIdx, alg = ext->alg;
2154
2155     //check if the interface is down
2156         if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
2157         {
2158                 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
2159         return -ENETDOWN;
2160         }
2161
2162     if (encoding->flags & IW_ENCODE_DISABLED)
2163         {
2164         keyIdx = (encoding->flags & IW_ENCODE_INDEX) - 1;
2165         // set BSSID wcid entry of the Pair-wise Key table as no-security mode
2166             AsicRemovePairwiseKeyEntry(pAdapter, BSS0, BSSID_WCID);
2167         pAdapter->SharedKey[BSS0][keyIdx].KeyLen = 0;
2168                 pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = CIPHER_NONE;
2169                 AsicRemoveSharedKeyEntry(pAdapter, 0, (UCHAR)keyIdx);
2170         NdisZeroMemory(&pAdapter->SharedKey[BSS0][keyIdx], sizeof(CIPHER_KEY));
2171         DBGPRINT(RT_DEBUG_TRACE, ("%s::Remove all keys!(encoding->flags = %x)\n", __func__, encoding->flags));
2172     }
2173                                         else
2174     {
2175         // Get Key Index and convet to our own defined key index
2176         keyIdx = (encoding->flags & IW_ENCODE_INDEX) - 1;
2177         if((keyIdx < 0) || (keyIdx >= NR_WEP_KEYS))
2178                 return -EINVAL;
2179
2180         if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
2181         {
2182             pAdapter->StaCfg.DefaultKeyId = keyIdx;
2183             DBGPRINT(RT_DEBUG_TRACE, ("%s::DefaultKeyId = %d\n", __func__, pAdapter->StaCfg.DefaultKeyId));
2184         }
2185
2186         switch (alg) {
2187                 case IW_ENCODE_ALG_NONE:
2188                 DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_ENCODE_ALG_NONE\n", __func__));
2189                         break;
2190                 case IW_ENCODE_ALG_WEP:
2191                 DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_ENCODE_ALG_WEP - ext->key_len = %d, keyIdx = %d\n", __func__, ext->key_len, keyIdx));
2192                         if (ext->key_len == MAX_WEP_KEY_SIZE)
2193                 {
2194                                 pAdapter->SharedKey[BSS0][keyIdx].KeyLen = MAX_WEP_KEY_SIZE;
2195                     pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = CIPHER_WEP128;
2196                                 }
2197                         else if (ext->key_len == MIN_WEP_KEY_SIZE)
2198                 {
2199                     pAdapter->SharedKey[BSS0][keyIdx].KeyLen = MIN_WEP_KEY_SIZE;
2200                     pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = CIPHER_WEP64;
2201                         }
2202                         else
2203                     return -EINVAL;
2204
2205                 NdisZeroMemory(pAdapter->SharedKey[BSS0][keyIdx].Key,  16);
2206                             NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].Key, ext->key, ext->key_len);
2207                                 if (pAdapter->StaCfg.GroupCipher == Ndis802_11GroupWEP40Enabled ||
2208                                         pAdapter->StaCfg.GroupCipher == Ndis802_11GroupWEP104Enabled)
2209                                 {
2210                                         // Set Group key material to Asic
2211                                         AsicAddSharedKeyEntry(pAdapter, BSS0, keyIdx, pAdapter->SharedKey[BSS0][keyIdx].CipherAlg, pAdapter->SharedKey[BSS0][keyIdx].Key, NULL, NULL);
2212
2213                                         // Update WCID attribute table and IVEIV table for this group key table
2214                                         RTMPAddWcidAttributeEntry(pAdapter, BSS0, keyIdx, pAdapter->SharedKey[BSS0][keyIdx].CipherAlg, NULL);
2215
2216                                         STA_PORT_SECURED(pAdapter);
2217
2218                                 // Indicate Connected for GUI
2219                                 pAdapter->IndicateMediaState = NdisMediaStateConnected;
2220                                 }
2221                         break;
2222             case IW_ENCODE_ALG_TKIP:
2223                 DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_ENCODE_ALG_TKIP - keyIdx = %d, ext->key_len = %d\n", __func__, keyIdx, ext->key_len));
2224                 if (ext->key_len == 32)
2225                 {
2226                     if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
2227                     {
2228                         fnSetCipherKey(pAdapter, keyIdx, CIPHER_TKIP, FALSE, ext);
2229                         if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA2)
2230                         {
2231                             STA_PORT_SECURED(pAdapter);
2232                         }
2233                 }
2234                     else if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY)
2235                     {
2236                         fnSetCipherKey(pAdapter, keyIdx, CIPHER_TKIP, TRUE, ext);
2237
2238                         // set 802.1x port control
2239                         STA_PORT_SECURED(pAdapter);
2240                     }
2241                 }
2242                 else
2243                     return -EINVAL;
2244                 break;
2245             case IW_ENCODE_ALG_CCMP:
2246                 if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
2247                 {
2248                     fnSetCipherKey(pAdapter, keyIdx, CIPHER_AES, FALSE, ext);
2249                     if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA2)
2250                         STA_PORT_SECURED(pAdapter);
2251                 }
2252                 else if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY)
2253                 {
2254                     fnSetCipherKey(pAdapter, keyIdx, CIPHER_AES, TRUE, ext);
2255
2256                     // set 802.1x port control
2257                         STA_PORT_SECURED(pAdapter);
2258                 }
2259                 break;
2260                 default:
2261                         return -EINVAL;
2262                 }
2263     }
2264
2265     return 0;
2266 }
2267
2268 int
2269 rt_ioctl_giwencodeext(struct net_device *dev,
2270                           struct iw_request_info *info,
2271                           union iwreq_data *wrqu, char *extra)
2272 {
2273         PRTMP_ADAPTER pAd = dev->ml_priv;
2274         PCHAR pKey = NULL;
2275         struct iw_point *encoding = &wrqu->encoding;
2276         struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
2277         int idx, max_key_len;
2278
2279         DBGPRINT(RT_DEBUG_TRACE ,("===> rt_ioctl_giwencodeext\n"));
2280
2281         max_key_len = encoding->length - sizeof(*ext);
2282         if (max_key_len < 0)
2283                 return -EINVAL;
2284
2285         idx = encoding->flags & IW_ENCODE_INDEX;
2286         if (idx)
2287         {
2288                 if (idx < 1 || idx > 4)
2289                         return -EINVAL;
2290                 idx--;
2291
2292                 if ((pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) ||
2293                         (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled))
2294                 {
2295                         if (idx != pAd->StaCfg.DefaultKeyId)
2296                         {
2297                                 ext->key_len = 0;
2298                                 return 0;
2299                         }
2300                 }
2301         }
2302         else
2303                 idx = pAd->StaCfg.DefaultKeyId;
2304
2305         encoding->flags = idx + 1;
2306         memset(ext, 0, sizeof(*ext));
2307
2308         ext->key_len = 0;
2309         switch(pAd->StaCfg.WepStatus) {
2310                 case Ndis802_11WEPDisabled:
2311                         ext->alg = IW_ENCODE_ALG_NONE;
2312                         encoding->flags |= IW_ENCODE_DISABLED;
2313                         break;
2314                 case Ndis802_11WEPEnabled:
2315                         ext->alg = IW_ENCODE_ALG_WEP;
2316                         if (pAd->SharedKey[BSS0][idx].KeyLen > max_key_len)
2317                                 return -E2BIG;
2318                         else
2319                         {
2320                                 ext->key_len = pAd->SharedKey[BSS0][idx].KeyLen;
2321                                 pKey = &(pAd->SharedKey[BSS0][idx].Key[0]);
2322                         }
2323                         break;
2324                 case Ndis802_11Encryption2Enabled:
2325                 case Ndis802_11Encryption3Enabled:
2326                         if (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled)
2327                                 ext->alg = IW_ENCODE_ALG_TKIP;
2328                         else
2329                                 ext->alg = IW_ENCODE_ALG_CCMP;
2330
2331                         if (max_key_len < 32)
2332                                 return -E2BIG;
2333                         else
2334                         {
2335                                 ext->key_len = 32;
2336                                 pKey = &pAd->StaCfg.PMK[0];
2337                         }
2338                         break;
2339                 default:
2340                         return -EINVAL;
2341         }
2342
2343         if (ext->key_len && pKey)
2344         {
2345                 encoding->flags |= IW_ENCODE_ENABLED;
2346                 memcpy(ext->key, pKey, ext->key_len);
2347         }
2348
2349         return 0;
2350 }
2351
2352 int rt_ioctl_siwgenie(struct net_device *dev,
2353                           struct iw_request_info *info,
2354                           union iwreq_data *wrqu, char *extra)
2355 {
2356         PRTMP_ADAPTER   pAd = dev->ml_priv;
2357
2358         if (wrqu->data.length > MAX_LEN_OF_RSNIE ||
2359             (wrqu->data.length && extra == NULL))
2360                 return -EINVAL;
2361
2362         if (wrqu->data.length)
2363         {
2364                 pAd->StaCfg.RSNIE_Len = wrqu->data.length;
2365                 NdisMoveMemory(&pAd->StaCfg.RSN_IE[0], extra, pAd->StaCfg.RSNIE_Len);
2366         }
2367         else
2368         {
2369                 pAd->StaCfg.RSNIE_Len = 0;
2370                 NdisZeroMemory(&pAd->StaCfg.RSN_IE[0], MAX_LEN_OF_RSNIE);
2371         }
2372
2373         return 0;
2374 }
2375
2376 int rt_ioctl_giwgenie(struct net_device *dev,
2377                                struct iw_request_info *info,
2378                                union iwreq_data *wrqu, char *extra)
2379 {
2380         PRTMP_ADAPTER   pAd = dev->ml_priv;
2381
2382         if ((pAd->StaCfg.RSNIE_Len == 0) ||
2383                 (pAd->StaCfg.AuthMode < Ndis802_11AuthModeWPA))
2384         {
2385                 wrqu->data.length = 0;
2386                 return 0;
2387         }
2388
2389         if (pAd->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_ENABLE)
2390         {
2391         if (wrqu->data.length < pAd->StaCfg.RSNIE_Len)
2392                 return -E2BIG;
2393
2394         wrqu->data.length = pAd->StaCfg.RSNIE_Len;
2395         memcpy(extra, &pAd->StaCfg.RSN_IE[0], pAd->StaCfg.RSNIE_Len);
2396         }
2397         else
2398         {
2399                 UCHAR RSNIe = IE_WPA;
2400
2401                 if (wrqu->data.length < (pAd->StaCfg.RSNIE_Len + 2)) // ID, Len
2402                         return -E2BIG;
2403                 wrqu->data.length = pAd->StaCfg.RSNIE_Len + 2;
2404
2405                 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK) ||
2406             (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2))
2407                         RSNIe = IE_RSN;
2408
2409                 extra[0] = (char)RSNIe;
2410                 extra[1] = pAd->StaCfg.RSNIE_Len;
2411                 memcpy(extra+2, &pAd->StaCfg.RSN_IE[0], pAd->StaCfg.RSNIE_Len);
2412         }
2413
2414         return 0;
2415 }
2416
2417 int rt_ioctl_siwpmksa(struct net_device *dev,
2418                            struct iw_request_info *info,
2419                            union iwreq_data *wrqu,
2420                            char *extra)
2421 {
2422         PRTMP_ADAPTER   pAd = dev->ml_priv;
2423         struct iw_pmksa *pPmksa = (struct iw_pmksa *)wrqu->data.pointer;
2424         INT     CachedIdx = 0, idx = 0;
2425
2426         if (pPmksa == NULL)
2427                 return -EINVAL;
2428
2429         DBGPRINT(RT_DEBUG_TRACE ,("===> rt_ioctl_siwpmksa\n"));
2430         switch(pPmksa->cmd)
2431         {
2432                 case IW_PMKSA_FLUSH:
2433                         NdisZeroMemory(pAd->StaCfg.SavedPMK, sizeof(BSSID_INFO)*PMKID_NO);
2434                         DBGPRINT(RT_DEBUG_TRACE ,("rt_ioctl_siwpmksa - IW_PMKSA_FLUSH\n"));
2435                         break;
2436                 case IW_PMKSA_REMOVE:
2437                         for (CachedIdx = 0; CachedIdx < pAd->StaCfg.SavedPMKNum; CachedIdx++)
2438                         {
2439                         // compare the BSSID
2440                         if (NdisEqualMemory(pPmksa->bssid.sa_data, pAd->StaCfg.SavedPMK[CachedIdx].BSSID, MAC_ADDR_LEN))
2441                         {
2442                                 NdisZeroMemory(pAd->StaCfg.SavedPMK[CachedIdx].BSSID, MAC_ADDR_LEN);
2443                                         NdisZeroMemory(pAd->StaCfg.SavedPMK[CachedIdx].PMKID, 16);
2444                                         for (idx = CachedIdx; idx < (pAd->StaCfg.SavedPMKNum - 1); idx++)
2445                                         {
2446                                                 NdisMoveMemory(&pAd->StaCfg.SavedPMK[idx].BSSID[0], &pAd->StaCfg.SavedPMK[idx+1].BSSID[0], MAC_ADDR_LEN);
2447                                                 NdisMoveMemory(&pAd->StaCfg.SavedPMK[idx].PMKID[0], &pAd->StaCfg.SavedPMK[idx+1].PMKID[0], 16);
2448                                         }
2449                                         pAd->StaCfg.SavedPMKNum--;
2450                                 break;
2451                         }
2452                 }
2453
2454                         DBGPRINT(RT_DEBUG_TRACE ,("rt_ioctl_siwpmksa - IW_PMKSA_REMOVE\n"));
2455                         break;
2456                 case IW_PMKSA_ADD:
2457                         for (CachedIdx = 0; CachedIdx < pAd->StaCfg.SavedPMKNum; CachedIdx++)
2458                         {
2459                         // compare the BSSID
2460                         if (NdisEqualMemory(pPmksa->bssid.sa_data, pAd->StaCfg.SavedPMK[CachedIdx].BSSID, MAC_ADDR_LEN))
2461                                 break;
2462                 }
2463
2464                 // Found, replace it
2465                 if (CachedIdx < PMKID_NO)
2466                 {
2467                         DBGPRINT(RT_DEBUG_OFF, ("Update PMKID, idx = %d\n", CachedIdx));
2468                         NdisMoveMemory(&pAd->StaCfg.SavedPMK[CachedIdx].BSSID[0], pPmksa->bssid.sa_data, MAC_ADDR_LEN);
2469                                 NdisMoveMemory(&pAd->StaCfg.SavedPMK[CachedIdx].PMKID[0], pPmksa->pmkid, 16);
2470                         pAd->StaCfg.SavedPMKNum++;
2471                 }
2472                 // Not found, replace the last one
2473                 else
2474                 {
2475                         // Randomly replace one
2476                         CachedIdx = (pPmksa->bssid.sa_data[5] % PMKID_NO);
2477                         DBGPRINT(RT_DEBUG_OFF, ("Update PMKID, idx = %d\n", CachedIdx));
2478                         NdisMoveMemory(&pAd->StaCfg.SavedPMK[CachedIdx].BSSID[0], pPmksa->bssid.sa_data, MAC_ADDR_LEN);
2479                                 NdisMoveMemory(&pAd->StaCfg.SavedPMK[CachedIdx].PMKID[0], pPmksa->pmkid, 16);
2480                 }
2481
2482                         DBGPRINT(RT_DEBUG_TRACE ,("rt_ioctl_siwpmksa - IW_PMKSA_ADD\n"));
2483                         break;
2484                 default:
2485                         DBGPRINT(RT_DEBUG_TRACE ,("rt_ioctl_siwpmksa - Unknow Command!!\n"));
2486                         break;
2487         }
2488
2489         return 0;
2490 }
2491
2492 int rt_ioctl_siwrate(struct net_device *dev,
2493                         struct iw_request_info *info,
2494                         union iwreq_data *wrqu, char *extra)
2495 {
2496     PRTMP_ADAPTER   pAd = dev->ml_priv;
2497     UINT32          rate = wrqu->bitrate.value, fixed = wrqu->bitrate.fixed;
2498
2499     //check if the interface is down
2500         if(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE))
2501         {
2502                 DBGPRINT(RT_DEBUG_TRACE, ("rt_ioctl_siwrate::Network is down!\n"));
2503         return -ENETDOWN;
2504         }
2505
2506     DBGPRINT(RT_DEBUG_TRACE, ("rt_ioctl_siwrate::(rate = %d, fixed = %d)\n", rate, fixed));
2507     /* rate = -1 => auto rate
2508        rate = X, fixed = 1 => (fixed rate X)
2509     */
2510     if (rate == -1)
2511     {
2512                 //Auto Rate
2513                 pAd->StaCfg.DesiredTransmitSetting.field.MCS = MCS_AUTO;
2514                 pAd->StaCfg.bAutoTxRateSwitch = TRUE;
2515                 if ((pAd->CommonCfg.PhyMode <= PHY_11G) ||
2516                     (pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE <= MODE_OFDM))
2517                         RTMPSetDesiredRates(pAd, -1);
2518
2519                 SetCommonHT(pAd);
2520     }
2521     else
2522     {
2523         if (fixed)
2524         {
2525                 pAd->StaCfg.bAutoTxRateSwitch = FALSE;
2526             if ((pAd->CommonCfg.PhyMode <= PHY_11G) ||
2527                 (pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE <= MODE_OFDM))
2528                 RTMPSetDesiredRates(pAd, rate);
2529             else
2530             {
2531                 pAd->StaCfg.DesiredTransmitSetting.field.MCS = MCS_AUTO;
2532                 SetCommonHT(pAd);
2533             }
2534             DBGPRINT(RT_DEBUG_TRACE, ("rt_ioctl_siwrate::(HtMcs=%d)\n",pAd->StaCfg.DesiredTransmitSetting.field.MCS));
2535         }
2536         else
2537         {
2538             // TODO: rate = X, fixed = 0 => (rates <= X)
2539             return -EOPNOTSUPP;
2540         }
2541     }
2542
2543     return 0;
2544 }
2545
2546 int rt_ioctl_giwrate(struct net_device *dev,
2547                                struct iw_request_info *info,
2548                                union iwreq_data *wrqu, char *extra)
2549 {
2550     PRTMP_ADAPTER   pAd = dev->ml_priv;
2551     int rate_index = 0, rate_count = 0;
2552     HTTRANSMIT_SETTING ht_setting;
2553     __s32 ralinkrate[] =
2554         {2,  4,   11,  22, // CCK
2555         12, 18,   24,  36, 48, 72, 96, 108, // OFDM
2556         13, 26,   39,  52,  78, 104, 117, 130, 26,  52,  78, 104, 156, 208, 234, 260, // 20MHz, 800ns GI, MCS: 0 ~ 15
2557         39, 78,  117, 156, 234, 312, 351, 390,                                                                            // 20MHz, 800ns GI, MCS: 16 ~ 23
2558         27, 54,   81, 108, 162, 216, 243, 270, 54, 108, 162, 216, 324, 432, 486, 540, // 40MHz, 800ns GI, MCS: 0 ~ 15
2559         81, 162, 243, 324, 486, 648, 729, 810,                                                                            // 40MHz, 800ns GI, MCS: 16 ~ 23
2560         14, 29,   43,  57,  87, 115, 130, 144, 29, 59,   87, 115, 173, 230, 260, 288, // 20MHz, 400ns GI, MCS: 0 ~ 15
2561         43, 87,  130, 173, 260, 317, 390, 433,                                                                            // 20MHz, 400ns GI, MCS: 16 ~ 23
2562         30, 60,   90, 120, 180, 240, 270, 300, 60, 120, 180, 240, 360, 480, 540, 600, // 40MHz, 400ns GI, MCS: 0 ~ 15
2563         90, 180, 270, 360, 540, 720, 810, 900};                                                                           // 40MHz, 400ns GI, MCS: 16 ~ 23
2564
2565     rate_count = sizeof(ralinkrate)/sizeof(__s32);
2566     //check if the interface is down
2567         if(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE))
2568         {
2569                 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
2570         return -ENETDOWN;
2571         }
2572
2573     if ((pAd->StaCfg.bAutoTxRateSwitch == FALSE) &&
2574         (INFRA_ON(pAd)) &&
2575         ((pAd->CommonCfg.PhyMode <= PHY_11G) || (pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE <= MODE_OFDM)))
2576         ht_setting.word = pAd->StaCfg.HTPhyMode.word;
2577     else
2578         ht_setting.word = pAd->MacTab.Content[BSSID_WCID].HTPhyMode.word;
2579
2580     if (ht_setting.field.MODE >= MODE_HTMIX)
2581     {
2582         rate_index = 12 + ((UCHAR)ht_setting.field.BW *24) + ((UCHAR)ht_setting.field.ShortGI *48) + ((UCHAR)ht_setting.field.MCS);
2583     }
2584     else
2585     if (ht_setting.field.MODE == MODE_OFDM)
2586         rate_index = (UCHAR)(ht_setting.field.MCS) + 4;
2587     else if (ht_setting.field.MODE == MODE_CCK)
2588         rate_index = (UCHAR)(ht_setting.field.MCS);
2589
2590     if (rate_index < 0)
2591         rate_index = 0;
2592
2593     if (rate_index > rate_count)
2594         rate_index = rate_count;
2595
2596     wrqu->bitrate.value = ralinkrate[rate_index] * 500000;
2597     wrqu->bitrate.disabled = 0;
2598
2599     return 0;
2600 }
2601
2602 static const iw_handler rt_handler[] =
2603 {
2604         (iw_handler) NULL,                                  /* SIOCSIWCOMMIT */
2605         (iw_handler) rt_ioctl_giwname,                  /* SIOCGIWNAME   */
2606         (iw_handler) NULL,                                  /* SIOCSIWNWID   */
2607         (iw_handler) NULL,                                  /* SIOCGIWNWID   */
2608         (iw_handler) rt_ioctl_siwfreq,              /* SIOCSIWFREQ   */
2609         (iw_handler) rt_ioctl_giwfreq,              /* SIOCGIWFREQ   */
2610         (iw_handler) rt_ioctl_siwmode,              /* SIOCSIWMODE   */
2611         (iw_handler) rt_ioctl_giwmode,              /* SIOCGIWMODE   */
2612         (iw_handler) NULL,                              /* SIOCSIWSENS   */
2613         (iw_handler) NULL,                              /* SIOCGIWSENS   */
2614         (iw_handler) NULL /* not used */,               /* SIOCSIWRANGE  */
2615         (iw_handler) rt_ioctl_giwrange,             /* SIOCGIWRANGE  */
2616         (iw_handler) NULL /* not used */,               /* SIOCSIWPRIV   */
2617         (iw_handler) NULL /* kernel code */,    /* SIOCGIWPRIV   */
2618         (iw_handler) NULL /* not used */,               /* SIOCSIWSTATS  */
2619         (iw_handler) rt28xx_get_wireless_stats /* kernel code */,    /* SIOCGIWSTATS  */
2620         (iw_handler) NULL,                              /* SIOCSIWSPY    */
2621         (iw_handler) NULL,                              /* SIOCGIWSPY    */
2622         (iw_handler) NULL,                                      /* SIOCSIWTHRSPY */
2623         (iw_handler) NULL,                                      /* SIOCGIWTHRSPY */
2624         (iw_handler) rt_ioctl_siwap,            /* SIOCSIWAP     */
2625         (iw_handler) rt_ioctl_giwap,                /* SIOCGIWAP     */
2626         (iw_handler) rt_ioctl_siwmlme,          /* SIOCSIWMLME   */
2627         (iw_handler) rt_ioctl_iwaplist,             /* SIOCGIWAPLIST */
2628         (iw_handler) rt_ioctl_siwscan,              /* SIOCSIWSCAN   */
2629         (iw_handler) rt_ioctl_giwscan,              /* SIOCGIWSCAN   */
2630         (iw_handler) rt_ioctl_siwessid,             /* SIOCSIWESSID  */
2631         (iw_handler) rt_ioctl_giwessid,             /* SIOCGIWESSID  */
2632         (iw_handler) rt_ioctl_siwnickn,             /* SIOCSIWNICKN  */
2633         (iw_handler) rt_ioctl_giwnickn,             /* SIOCGIWNICKN  */
2634         (iw_handler) NULL,                                      /* -- hole --    */
2635         (iw_handler) NULL,                                      /* -- hole --    */
2636         (iw_handler) rt_ioctl_siwrate,          /* SIOCSIWRATE   */
2637         (iw_handler) rt_ioctl_giwrate,          /* SIOCGIWRATE   */
2638         (iw_handler) rt_ioctl_siwrts,               /* SIOCSIWRTS    */
2639         (iw_handler) rt_ioctl_giwrts,               /* SIOCGIWRTS    */
2640         (iw_handler) rt_ioctl_siwfrag,              /* SIOCSIWFRAG   */
2641         (iw_handler) rt_ioctl_giwfrag,              /* SIOCGIWFRAG   */
2642         (iw_handler) NULL,                              /* SIOCSIWTXPOW  */
2643         (iw_handler) NULL,                              /* SIOCGIWTXPOW  */
2644         (iw_handler) NULL,                              /* SIOCSIWRETRY  */
2645         (iw_handler) NULL,                              /* SIOCGIWRETRY  */
2646         (iw_handler) rt_ioctl_siwencode,                /* SIOCSIWENCODE */
2647         (iw_handler) rt_ioctl_giwencode,                /* SIOCGIWENCODE */
2648         (iw_handler) NULL,                              /* SIOCSIWPOWER  */
2649         (iw_handler) NULL,                              /* SIOCGIWPOWER  */
2650         (iw_handler) NULL,                                              /* -- hole -- */
2651         (iw_handler) NULL,                                              /* -- hole -- */
2652     (iw_handler) rt_ioctl_siwgenie,         /* SIOCSIWGENIE  */
2653         (iw_handler) rt_ioctl_giwgenie,         /* SIOCGIWGENIE  */
2654         (iw_handler) rt_ioctl_siwauth,              /* SIOCSIWAUTH   */
2655         (iw_handler) rt_ioctl_giwauth,              /* SIOCGIWAUTH   */
2656         (iw_handler) rt_ioctl_siwencodeext,         /* SIOCSIWENCODEEXT */
2657         (iw_handler) rt_ioctl_giwencodeext,             /* SIOCGIWENCODEEXT */
2658         (iw_handler) rt_ioctl_siwpmksa,         /* SIOCSIWPMKSA  */
2659 };
2660
2661 static const iw_handler rt_priv_handlers[] = {
2662         (iw_handler) NULL, /* + 0x00 */
2663         (iw_handler) NULL, /* + 0x01 */
2664         (iw_handler) rt_ioctl_setparam, /* + 0x02 */
2665         (iw_handler) NULL, /* + 0x03 */
2666         (iw_handler) NULL, /* + 0x04 */
2667         (iw_handler) NULL, /* + 0x05 */
2668         (iw_handler) NULL, /* + 0x06 */
2669         (iw_handler) NULL, /* + 0x07 */
2670         (iw_handler) NULL, /* + 0x08 */
2671         (iw_handler) rt_private_get_statistics, /* + 0x09 */
2672         (iw_handler) NULL, /* + 0x0A */
2673         (iw_handler) NULL, /* + 0x0B */
2674         (iw_handler) NULL, /* + 0x0C */
2675         (iw_handler) NULL, /* + 0x0D */
2676         (iw_handler) NULL, /* + 0x0E */
2677         (iw_handler) NULL, /* + 0x0F */
2678         (iw_handler) NULL, /* + 0x10 */
2679         (iw_handler) rt_private_show, /* + 0x11 */
2680     (iw_handler) NULL, /* + 0x12 */
2681         (iw_handler) NULL, /* + 0x13 */
2682         (iw_handler) NULL, /* + 0x15 */
2683         (iw_handler) NULL, /* + 0x17 */
2684         (iw_handler) NULL, /* + 0x18 */
2685 };
2686
2687 const struct iw_handler_def rt28xx_iw_handler_def =
2688 {
2689 #define N(a)    (sizeof (a) / sizeof (a[0]))
2690         .standard       = (iw_handler *) rt_handler,
2691         .num_standard   = sizeof(rt_handler) / sizeof(iw_handler),
2692         .private        = (iw_handler *) rt_priv_handlers,
2693         .num_private            = N(rt_priv_handlers),
2694         .private_args   = (struct iw_priv_args *) privtab,
2695         .num_private_args       = N(privtab),
2696 #if IW_HANDLER_VERSION >= 7
2697     .get_wireless_stats = rt28xx_get_wireless_stats,
2698 #endif
2699 };
2700
2701 INT rt28xx_sta_ioctl(
2702         IN      struct net_device       *net_dev,
2703         IN      OUT     struct ifreq    *rq,
2704         IN      INT                                     cmd)
2705 {
2706         RTMP_ADAPTER *pAd = net_dev->ml_priv;
2707         POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie;
2708         struct iwreq        *wrq = (struct iwreq *) rq;
2709         BOOLEAN                         StateMachineTouched = FALSE;
2710         INT                                     Status = NDIS_STATUS_SUCCESS;
2711
2712     //check if the interface is down
2713     if(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE))
2714     {
2715         {
2716             DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
2717                     return -ENETDOWN;
2718         }
2719     }
2720
2721         {       // determine this ioctl command is comming from which interface.
2722                 pObj->ioctl_if_type = INT_MAIN;
2723                 pObj->ioctl_if = MAIN_MBSSID;
2724         }
2725
2726         switch(cmd)
2727         {
2728         case SIOCGIFHWADDR:
2729                         DBGPRINT(RT_DEBUG_TRACE, ("IOCTL::SIOCGIFHWADDR\n"));
2730                         memcpy(wrq->u.name, pAd->CurrentAddress, ETH_ALEN);
2731                         break;
2732                 case SIOCGIWNAME:
2733         {
2734                 char *name=&wrq->u.name[0];
2735                 rt_ioctl_giwname(net_dev, NULL, name, NULL);
2736                         break;
2737                 }
2738                 case SIOCGIWESSID:  //Get ESSID
2739         {
2740                 struct iw_point *essid=&wrq->u.essid;
2741                 rt_ioctl_giwessid(net_dev, NULL, essid, essid->pointer);
2742                         break;
2743                 }
2744                 case SIOCSIWESSID:  //Set ESSID
2745         {
2746                 struct iw_point *essid=&wrq->u.essid;
2747                 rt_ioctl_siwessid(net_dev, NULL, essid, essid->pointer);
2748                         break;
2749                 }
2750                 case SIOCSIWNWID:   // set network id (the cell)
2751                 case SIOCGIWNWID:   // get network id
2752                         Status = -EOPNOTSUPP;
2753                         break;
2754                 case SIOCSIWFREQ:   //set channel/frequency (Hz)
2755         {
2756                 struct iw_freq *freq=&wrq->u.freq;
2757                 rt_ioctl_siwfreq(net_dev, NULL, freq, NULL);
2758                         break;
2759                 }
2760                 case SIOCGIWFREQ:   // get channel/frequency (Hz)
2761         {
2762                 struct iw_freq *freq=&wrq->u.freq;
2763                 rt_ioctl_giwfreq(net_dev, NULL, freq, NULL);
2764                         break;
2765                 }
2766                 case SIOCSIWNICKN: //set node name/nickname
2767         {
2768                 struct iw_point *data=&wrq->u.data;
2769                 rt_ioctl_siwnickn(net_dev, NULL, data, NULL);
2770                         break;
2771                 }
2772                 case SIOCGIWNICKN: //get node name/nickname
2773         {
2774                 struct iw_point *data=&wrq->u.data;
2775                 rt_ioctl_giwnickn(net_dev, NULL, data, NULL);
2776                         break;
2777                 }
2778                 case SIOCGIWRATE:   //get default bit rate (bps)
2779                     rt_ioctl_giwrate(net_dev, NULL, &wrq->u, NULL);
2780             break;
2781             case SIOCSIWRATE:  //set default bit rate (bps)
2782                 rt_ioctl_siwrate(net_dev, NULL, &wrq->u, NULL);
2783             break;
2784         case SIOCGIWRTS:  // get RTS/CTS threshold (bytes)
2785         {
2786                 struct iw_param *rts=&wrq->u.rts;
2787                 rt_ioctl_giwrts(net_dev, NULL, rts, NULL);
2788                         break;
2789                 }
2790         case SIOCSIWRTS:  //set RTS/CTS threshold (bytes)
2791         {
2792                 struct iw_param *rts=&wrq->u.rts;
2793                 rt_ioctl_siwrts(net_dev, NULL, rts, NULL);
2794                         break;
2795                 }
2796         case SIOCGIWFRAG:  //get fragmentation thr (bytes)
2797         {
2798                 struct iw_param *frag=&wrq->u.frag;
2799                 rt_ioctl_giwfrag(net_dev, NULL, frag, NULL);
2800                         break;
2801                 }
2802         case SIOCSIWFRAG:  //set fragmentation thr (bytes)
2803         {
2804                 struct iw_param *frag=&wrq->u.frag;
2805                 rt_ioctl_siwfrag(net_dev, NULL, frag, NULL);
2806                         break;
2807                 }
2808         case SIOCGIWENCODE:  //get encoding token & mode
2809         {
2810                 struct iw_point *erq=&wrq->u.encoding;
2811                 if(erq->pointer)
2812                         rt_ioctl_giwencode(net_dev, NULL, erq, erq->pointer);
2813                         break;
2814                 }
2815         case SIOCSIWENCODE:  //set encoding token & mode
2816         {
2817                 struct iw_point *erq=&wrq->u.encoding;
2818                 if(erq->pointer)
2819                         rt_ioctl_siwencode(net_dev, NULL, erq, erq->pointer);
2820                         break;
2821                 }
2822                 case SIOCGIWAP:     //get access point MAC addresses
2823         {
2824                 struct sockaddr *ap_addr=&wrq->u.ap_addr;
2825                 rt_ioctl_giwap(net_dev, NULL, ap_addr, ap_addr->sa_data);
2826                         break;
2827                 }
2828             case SIOCSIWAP:  //set access point MAC addresses
2829         {
2830                 struct sockaddr *ap_addr=&wrq->u.ap_addr;
2831                 rt_ioctl_siwap(net_dev, NULL, ap_addr, ap_addr->sa_data);
2832                         break;
2833                 }
2834                 case SIOCGIWMODE:   //get operation mode
2835         {
2836                 __u32 *mode=&wrq->u.mode;
2837                 rt_ioctl_giwmode(net_dev, NULL, mode, NULL);
2838                         break;
2839                 }
2840                 case SIOCSIWMODE:   //set operation mode
2841         {
2842                 __u32 *mode=&wrq->u.mode;
2843                 rt_ioctl_siwmode(net_dev, NULL, mode, NULL);
2844                         break;
2845                 }
2846                 case SIOCGIWSENS:   //get sensitivity (dBm)
2847                 case SIOCSIWSENS:       //set sensitivity (dBm)
2848                 case SIOCGIWPOWER:  //get Power Management settings
2849                 case SIOCSIWPOWER:  //set Power Management settings
2850                 case SIOCGIWTXPOW:  //get transmit power (dBm)
2851                 case SIOCSIWTXPOW:  //set transmit power (dBm)
2852                 case SIOCGIWRANGE:      //Get range of parameters
2853                 case SIOCGIWRETRY:      //get retry limits and lifetime
2854                 case SIOCSIWRETRY:      //set retry limits and lifetime
2855                 case RT_PRIV_IOCTL:
2856                 case RT_PRIV_IOCTL_EXT:
2857                         Status = -EOPNOTSUPP;
2858                         break;
2859                 case SIOCGIWPRIV:
2860                         if (wrq->u.data.pointer)
2861                         {
2862                                 if ( access_ok(VERIFY_WRITE, wrq->u.data.pointer, sizeof(privtab)) != TRUE)
2863                                         break;
2864                                 wrq->u.data.length = sizeof(privtab) / sizeof(privtab[0]);
2865                                 if (copy_to_user(wrq->u.data.pointer, privtab, sizeof(privtab)))
2866                                         Status = -EFAULT;
2867                         }
2868                         break;
2869                 case RTPRIV_IOCTL_SET:
2870                         if(access_ok(VERIFY_READ, wrq->u.data.pointer, wrq->u.data.length) != TRUE)
2871                                 break;
2872                         rt_ioctl_setparam(net_dev, NULL, NULL, wrq->u.data.pointer);
2873                         break;
2874                 case RTPRIV_IOCTL_GSITESURVEY:
2875                         RTMPIoctlGetSiteSurvey(pAd, wrq);
2876                     break;
2877         case SIOCETHTOOL:
2878                 break;
2879                 default:
2880                         DBGPRINT(RT_DEBUG_ERROR, ("IOCTL::unknown IOCTL's cmd = 0x%08x\n", cmd));
2881                         Status = -EOPNOTSUPP;
2882                         break;
2883         }
2884
2885     if(StateMachineTouched) // Upper layer sent a MLME-related operations
2886         RT28XX_MLME_HANDLER(pAd);
2887
2888         return Status;
2889 }
2890
2891 /*
2892     ==========================================================================
2893     Description:
2894         Set SSID
2895     Return:
2896         TRUE if all parameters are OK, FALSE otherwise
2897     ==========================================================================
2898 */
2899 INT Set_SSID_Proc(
2900     IN  PRTMP_ADAPTER   pAdapter,
2901     IN  PUCHAR          arg)
2902 {
2903     NDIS_802_11_SSID                    Ssid, *pSsid=NULL;
2904     BOOLEAN                             StateMachineTouched = FALSE;
2905     int                                 success = TRUE;
2906
2907     if( strlen(arg) <= MAX_LEN_OF_SSID)
2908     {
2909         NdisZeroMemory(&Ssid, sizeof(NDIS_802_11_SSID));
2910         if (strlen(arg) != 0)
2911         {
2912             NdisMoveMemory(Ssid.Ssid, arg, strlen(arg));
2913             Ssid.SsidLength = strlen(arg);
2914         }
2915         else   //ANY ssid
2916         {
2917             Ssid.SsidLength = 0;
2918                     memcpy(Ssid.Ssid, "", 0);
2919                         pAdapter->StaCfg.BssType = BSS_INFRA;
2920                         pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
2921                 pAdapter->StaCfg.WepStatus  = Ndis802_11EncryptionDisabled;
2922                 }
2923         pSsid = &Ssid;
2924
2925         if (pAdapter->Mlme.CntlMachine.CurrState != CNTL_IDLE)
2926         {
2927             RT28XX_MLME_RESET_STATE_MACHINE(pAdapter);
2928             DBGPRINT(RT_DEBUG_TRACE, ("!!! MLME busy, reset MLME state machine !!!\n"));
2929         }
2930
2931         pAdapter->MlmeAux.CurrReqIsFromNdis = TRUE;
2932         pAdapter->StaCfg.bScanReqIsFromWebUI = FALSE;
2933                 pAdapter->bConfigChanged = TRUE;
2934
2935         MlmeEnqueue(pAdapter,
2936                     MLME_CNTL_STATE_MACHINE,
2937                     OID_802_11_SSID,
2938                     sizeof(NDIS_802_11_SSID),
2939                     (VOID *)pSsid);
2940
2941         StateMachineTouched = TRUE;
2942         DBGPRINT(RT_DEBUG_TRACE, ("Set_SSID_Proc::(Len=%d,Ssid=%s)\n", Ssid.SsidLength, Ssid.Ssid));
2943     }
2944     else
2945         success = FALSE;
2946
2947     if (StateMachineTouched) // Upper layer sent a MLME-related operations
2948         RT28XX_MLME_HANDLER(pAdapter);
2949
2950     return success;
2951 }
2952
2953 #ifdef WMM_SUPPORT
2954 /*
2955     ==========================================================================
2956     Description:
2957         Set WmmCapable Enable or Disable
2958     Return:
2959         TRUE if all parameters are OK, FALSE otherwise
2960     ==========================================================================
2961 */
2962 INT     Set_WmmCapable_Proc(
2963         IN      PRTMP_ADAPTER   pAd,
2964         IN      PUCHAR                  arg)
2965 {
2966         BOOLEAN bWmmCapable;
2967
2968         bWmmCapable = simple_strtol(arg, 0, 10);
2969
2970         if ((bWmmCapable == 1)
2971 #ifdef RT2870
2972                 && (pAd->NumberOfPipes >= 5)
2973 #endif // RT2870 //
2974                 )
2975                 pAd->CommonCfg.bWmmCapable = TRUE;
2976         else if (bWmmCapable == 0)
2977                 pAd->CommonCfg.bWmmCapable = FALSE;
2978         else
2979                 return FALSE;  //Invalid argument
2980
2981         DBGPRINT(RT_DEBUG_TRACE, ("Set_WmmCapable_Proc::(bWmmCapable=%d)\n",
2982                 pAd->CommonCfg.bWmmCapable));
2983
2984         return TRUE;
2985 }
2986 #endif // WMM_SUPPORT //
2987
2988 /*
2989     ==========================================================================
2990     Description:
2991         Set Network Type(Infrastructure/Adhoc mode)
2992     Return:
2993         TRUE if all parameters are OK, FALSE otherwise
2994     ==========================================================================
2995 */
2996 INT Set_NetworkType_Proc(
2997     IN  PRTMP_ADAPTER   pAdapter,
2998     IN  PUCHAR          arg)
2999 {
3000     UINT32      Value = 0;
3001
3002     if (strcmp(arg, "Adhoc") == 0)
3003         {
3004                 if (pAdapter->StaCfg.BssType != BSS_ADHOC)
3005                 {
3006                         // Config has changed
3007                         pAdapter->bConfigChanged = TRUE;
3008             if (MONITOR_ON(pAdapter))
3009             {
3010                 RTMP_IO_WRITE32(pAdapter, RX_FILTR_CFG, STANORMAL);
3011                 RTMP_IO_READ32(pAdapter, MAC_SYS_CTRL, &Value);
3012                                 Value &= (~0x80);
3013                                 RTMP_IO_WRITE32(pAdapter, MAC_SYS_CTRL, Value);
3014                 OPSTATUS_CLEAR_FLAG(pAdapter, fOP_STATUS_MEDIA_STATE_CONNECTED);
3015                 pAdapter->StaCfg.bAutoReconnect = TRUE;
3016                 LinkDown(pAdapter, FALSE);
3017             }
3018                         if (INFRA_ON(pAdapter))
3019                         {
3020                                 //BOOLEAN Cancelled;
3021                                 // Set the AutoReconnectSsid to prevent it reconnect to old SSID
3022                                 // Since calling this indicate user don't want to connect to that SSID anymore.
3023                                 pAdapter->MlmeAux.AutoReconnectSsidLen= 32;
3024                                 NdisZeroMemory(pAdapter->MlmeAux.AutoReconnectSsid, pAdapter->MlmeAux.AutoReconnectSsidLen);
3025
3026                                 LinkDown(pAdapter, FALSE);
3027
3028                                 DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event BB!\n"));
3029                         }
3030                 }
3031                 pAdapter->StaCfg.BssType = BSS_ADHOC;
3032         pAdapter->net_dev->type = pAdapter->StaCfg.OriDevType;
3033                 DBGPRINT(RT_DEBUG_TRACE, ("===>Set_NetworkType_Proc::(AD-HOC)\n"));
3034         }
3035     else if (strcmp(arg, "Infra") == 0)
3036         {
3037                 if (pAdapter->StaCfg.BssType != BSS_INFRA)
3038                 {
3039                         // Config has changed
3040                         pAdapter->bConfigChanged = TRUE;
3041             if (MONITOR_ON(pAdapter))
3042             {
3043                 RTMP_IO_WRITE32(pAdapter, RX_FILTR_CFG, STANORMAL);
3044                 RTMP_IO_READ32(pAdapter, MAC_SYS_CTRL, &Value);
3045                                 Value &= (~0x80);
3046                                 RTMP_IO_WRITE32(pAdapter, MAC_SYS_CTRL, Value);
3047                 OPSTATUS_CLEAR_FLAG(pAdapter, fOP_STATUS_MEDIA_STATE_CONNECTED);
3048                 pAdapter->StaCfg.bAutoReconnect = TRUE;
3049                 LinkDown(pAdapter, FALSE);
3050             }
3051                         if (ADHOC_ON(pAdapter))
3052                         {
3053                                 // Set the AutoReconnectSsid to prevent it reconnect to old SSID
3054                                 // Since calling this indicate user don't want to connect to that SSID anymore.
3055                                 pAdapter->MlmeAux.AutoReconnectSsidLen= 32;
3056                                 NdisZeroMemory(pAdapter->MlmeAux.AutoReconnectSsid, pAdapter->MlmeAux.AutoReconnectSsidLen);
3057
3058                                 LinkDown(pAdapter, FALSE);
3059                         }
3060                 }
3061                 pAdapter->StaCfg.BssType = BSS_INFRA;
3062         pAdapter->net_dev->type = pAdapter->StaCfg.OriDevType;
3063                 DBGPRINT(RT_DEBUG_TRACE, ("===>Set_NetworkType_Proc::(INFRA)\n"));
3064
3065         pAdapter->StaCfg.BssType = BSS_INFRA;
3066         }
3067     else if (strcmp(arg, "Monitor") == 0)
3068     {
3069                 UCHAR   bbpValue = 0;
3070                 BCN_TIME_CFG_STRUC csr;
3071                 OPSTATUS_CLEAR_FLAG(pAdapter, fOP_STATUS_INFRA_ON);
3072         OPSTATUS_CLEAR_FLAG(pAdapter, fOP_STATUS_ADHOC_ON);
3073                 OPSTATUS_SET_FLAG(pAdapter, fOP_STATUS_MEDIA_STATE_CONNECTED);
3074                 // disable all periodic state machine
3075                 pAdapter->StaCfg.bAutoReconnect = FALSE;
3076                 // reset all mlme state machine
3077                 RT28XX_MLME_RESET_STATE_MACHINE(pAdapter);
3078                 DBGPRINT(RT_DEBUG_TRACE, ("fOP_STATUS_MEDIA_STATE_CONNECTED \n"));
3079         if (pAdapter->CommonCfg.CentralChannel == 0)
3080         {
3081             if (pAdapter->CommonCfg.PhyMode == PHY_11AN_MIXED)
3082                 pAdapter->CommonCfg.CentralChannel = 36;
3083             else
3084                 pAdapter->CommonCfg.CentralChannel = 6;
3085         }
3086         else
3087             N_ChannelCheck(pAdapter);
3088
3089         if (pAdapter->CommonCfg.PhyMode >= PHY_11ABGN_MIXED &&
3090             pAdapter->CommonCfg.RegTransmitSetting.field.BW == BW_40 &&
3091             pAdapter->CommonCfg.RegTransmitSetting.field.EXTCHA == EXTCHA_ABOVE)
3092                 {
3093                         // 40MHz ,control channel at lower
3094                         RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R4, &bbpValue);
3095                         bbpValue &= (~0x18);
3096                         bbpValue |= 0x10;
3097                         RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R4, bbpValue);
3098                         pAdapter->CommonCfg.BBPCurrentBW = BW_40;
3099                         //  RX : control channel at lower
3100                         RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R3, &bbpValue);
3101                         bbpValue &= (~0x20);
3102                         RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R3, bbpValue);
3103
3104                         RTMP_IO_READ32(pAdapter, TX_BAND_CFG, &Value);
3105                         Value &= 0xfffffffe;
3106                         RTMP_IO_WRITE32(pAdapter, TX_BAND_CFG, Value);
3107                         pAdapter->CommonCfg.CentralChannel = pAdapter->CommonCfg.Channel + 2;
3108             AsicSwitchChannel(pAdapter, pAdapter->CommonCfg.CentralChannel, FALSE);
3109                     AsicLockChannel(pAdapter, pAdapter->CommonCfg.CentralChannel);
3110             DBGPRINT(RT_DEBUG_TRACE, ("BW_40 ,control_channel(%d), CentralChannel(%d) \n",
3111                                        pAdapter->CommonCfg.Channel,
3112                                        pAdapter->CommonCfg.CentralChannel));
3113                 }
3114                 else if (pAdapter->CommonCfg.PhyMode >= PHY_11ABGN_MIXED &&
3115                  pAdapter->CommonCfg.RegTransmitSetting.field.BW == BW_40 &&
3116                  pAdapter->CommonCfg.RegTransmitSetting.field.EXTCHA == EXTCHA_BELOW)
3117                 {
3118                         // 40MHz ,control channel at upper
3119                         RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R4, &bbpValue);
3120                         bbpValue &= (~0x18);
3121                         bbpValue |= 0x10;
3122                         RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R4, bbpValue);
3123                         pAdapter->CommonCfg.BBPCurrentBW = BW_40;
3124                         RTMP_IO_READ32(pAdapter, TX_BAND_CFG, &Value);
3125                         Value |= 0x1;
3126                         RTMP_IO_WRITE32(pAdapter, TX_BAND_CFG, Value);
3127
3128                         RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R3, &bbpValue);
3129                         bbpValue |= (0x20);
3130                         RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R3, bbpValue);
3131                         pAdapter->CommonCfg.CentralChannel = pAdapter->CommonCfg.Channel - 2;
3132             AsicSwitchChannel(pAdapter, pAdapter->CommonCfg.CentralChannel, FALSE);
3133                     AsicLockChannel(pAdapter, pAdapter->CommonCfg.CentralChannel);
3134             DBGPRINT(RT_DEBUG_TRACE, ("BW_40 ,control_channel(%d), CentralChannel(%d) \n",
3135                                        pAdapter->CommonCfg.Channel,
3136                                        pAdapter->CommonCfg.CentralChannel));
3137                 }
3138                 else
3139                 {
3140                         // 20MHz
3141                         RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R4, &bbpValue);
3142                         bbpValue &= (~0x18);
3143                         RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R4, bbpValue);
3144                         pAdapter->CommonCfg.BBPCurrentBW = BW_20;
3145                         AsicSwitchChannel(pAdapter, pAdapter->CommonCfg.Channel, FALSE);
3146                         AsicLockChannel(pAdapter, pAdapter->CommonCfg.Channel);
3147                         DBGPRINT(RT_DEBUG_TRACE, ("BW_20, Channel(%d)\n", pAdapter->CommonCfg.Channel));
3148                 }
3149                 // Enable Rx with promiscuous reception
3150                 RTMP_IO_WRITE32(pAdapter, RX_FILTR_CFG, 0x3);
3151                 // ASIC supporsts sniffer function with replacing RSSI with timestamp.
3152                 //RTMP_IO_READ32(pAdapter, MAC_SYS_CTRL, &Value);
3153                 //Value |= (0x80);
3154                 //RTMP_IO_WRITE32(pAdapter, MAC_SYS_CTRL, Value);
3155                 // disable sync
3156                 RTMP_IO_READ32(pAdapter, BCN_TIME_CFG, &csr.word);
3157                 csr.field.bBeaconGen = 0;
3158                 csr.field.bTBTTEnable = 0;
3159                 csr.field.TsfSyncMode = 0;
3160                 RTMP_IO_WRITE32(pAdapter, BCN_TIME_CFG, csr.word);
3161
3162                 pAdapter->StaCfg.BssType = BSS_MONITOR;
3163         pAdapter->net_dev->type = ARPHRD_IEEE80211_PRISM; //ARPHRD_IEEE80211; // IEEE80211
3164                 DBGPRINT(RT_DEBUG_TRACE, ("===>Set_NetworkType_Proc::(MONITOR)\n"));
3165     }
3166
3167     // Reset Ralink supplicant to not use, it will be set to start when UI set PMK key
3168     pAdapter->StaCfg.WpaState = SS_NOTUSE;
3169
3170     DBGPRINT(RT_DEBUG_TRACE, ("Set_NetworkType_Proc::(NetworkType=%d)\n", pAdapter->StaCfg.BssType));
3171
3172     return TRUE;
3173 }
3174
3175 /*
3176     ==========================================================================
3177     Description:
3178         Set Authentication mode
3179     Return:
3180         TRUE if all parameters are OK, FALSE otherwise
3181     ==========================================================================
3182 */
3183 INT Set_AuthMode_Proc(
3184     IN  PRTMP_ADAPTER   pAdapter,
3185     IN  PUCHAR          arg)
3186 {
3187     if ((strcmp(arg, "WEPAUTO") == 0) || (strcmp(arg, "wepauto") == 0))
3188         pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeAutoSwitch;
3189     else if ((strcmp(arg, "OPEN") == 0) || (strcmp(arg, "open") == 0))
3190         pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
3191     else if ((strcmp(arg, "SHARED") == 0) || (strcmp(arg, "shared") == 0))
3192         pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeShared;
3193     else if ((strcmp(arg, "WPAPSK") == 0) || (strcmp(arg, "wpapsk") == 0))
3194         pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPAPSK;
3195     else if ((strcmp(arg, "WPANONE") == 0) || (strcmp(arg, "wpanone") == 0))
3196         pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPANone;
3197     else if ((strcmp(arg, "WPA2PSK") == 0) || (strcmp(arg, "wpa2psk") == 0))
3198         pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPA2PSK;
3199     else if ((strcmp(arg, "WPA") == 0) || (strcmp(arg, "wpa") == 0))
3200         pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPA;
3201     else if ((strcmp(arg, "WPA2") == 0) || (strcmp(arg, "wpa2") == 0))
3202         pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPA2;
3203     else
3204         return FALSE;
3205
3206     pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
3207
3208     DBGPRINT(RT_DEBUG_TRACE, ("Set_AuthMode_Proc::(AuthMode=%d)\n", pAdapter->StaCfg.AuthMode));
3209
3210     return TRUE;
3211 }
3212
3213 /*
3214     ==========================================================================
3215     Description:
3216         Set Encryption Type
3217     Return:
3218         TRUE if all parameters are OK, FALSE otherwise
3219     ==========================================================================
3220 */
3221 INT Set_EncrypType_Proc(
3222     IN  PRTMP_ADAPTER   pAdapter,
3223     IN  PUCHAR          arg)
3224 {
3225     if ((strcmp(arg, "NONE") == 0) || (strcmp(arg, "none") == 0))
3226     {
3227         if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
3228             return TRUE;    // do nothing
3229
3230         pAdapter->StaCfg.WepStatus     = Ndis802_11WEPDisabled;
3231         pAdapter->StaCfg.PairCipher    = Ndis802_11WEPDisabled;
3232             pAdapter->StaCfg.GroupCipher   = Ndis802_11WEPDisabled;
3233     }
3234     else if ((strcmp(arg, "WEP") == 0) || (strcmp(arg, "wep") == 0))
3235     {
3236         if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
3237             return TRUE;    // do nothing
3238
3239         pAdapter->StaCfg.WepStatus     = Ndis802_11WEPEnabled;
3240         pAdapter->StaCfg.PairCipher    = Ndis802_11WEPEnabled;
3241             pAdapter->StaCfg.GroupCipher   = Ndis802_11WEPEnabled;
3242     }
3243     else if ((strcmp(arg, "TKIP") == 0) || (strcmp(arg, "tkip") == 0))
3244     {
3245         if (pAdapter->StaCfg.AuthMode < Ndis802_11AuthModeWPA)
3246             return TRUE;    // do nothing
3247
3248         pAdapter->StaCfg.WepStatus     = Ndis802_11Encryption2Enabled;
3249         pAdapter->StaCfg.PairCipher    = Ndis802_11Encryption2Enabled;
3250             pAdapter->StaCfg.GroupCipher   = Ndis802_11Encryption2Enabled;
3251     }
3252     else if ((strcmp(arg, "AES") == 0) || (strcmp(arg, "aes") == 0))
3253     {
3254         if (pAdapter->StaCfg.AuthMode < Ndis802_11AuthModeWPA)
3255             return TRUE;    // do nothing
3256
3257         pAdapter->StaCfg.WepStatus     = Ndis802_11Encryption3Enabled;
3258         pAdapter->StaCfg.PairCipher    = Ndis802_11Encryption3Enabled;
3259             pAdapter->StaCfg.GroupCipher   = Ndis802_11Encryption3Enabled;
3260     }
3261     else
3262         return FALSE;
3263
3264     pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
3265
3266     DBGPRINT(RT_DEBUG_TRACE, ("Set_EncrypType_Proc::(EncrypType=%d)\n", pAdapter->StaCfg.WepStatus));
3267
3268     return TRUE;
3269 }
3270
3271 /*
3272     ==========================================================================
3273     Description:
3274         Set Default Key ID
3275     Return:
3276         TRUE if all parameters are OK, FALSE otherwise
3277     ==========================================================================
3278 */
3279 INT Set_DefaultKeyID_Proc(
3280     IN  PRTMP_ADAPTER   pAdapter,
3281     IN  PUCHAR          arg)
3282 {
3283     ULONG                               KeyIdx;
3284
3285     KeyIdx = simple_strtol(arg, 0, 10);
3286     if((KeyIdx >= 1 ) && (KeyIdx <= 4))
3287         pAdapter->StaCfg.DefaultKeyId = (UCHAR) (KeyIdx - 1 );
3288     else
3289         return FALSE;  //Invalid argument
3290
3291     DBGPRINT(RT_DEBUG_TRACE, ("Set_DefaultKeyID_Proc::(DefaultKeyID=%d)\n", pAdapter->StaCfg.DefaultKeyId));
3292
3293     return TRUE;
3294 }
3295
3296 /*
3297     ==========================================================================
3298     Description:
3299         Set WEP KEY1
3300     Return:
3301         TRUE if all parameters are OK, FALSE otherwise
3302     ==========================================================================
3303 */
3304 INT Set_Key1_Proc(
3305     IN  PRTMP_ADAPTER   pAdapter,
3306     IN  PUCHAR          arg)
3307 {
3308     int                                 KeyLen;
3309     int                                 i;
3310     UCHAR                               CipherAlg=CIPHER_WEP64;
3311
3312     if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
3313         return TRUE;    // do nothing
3314
3315     KeyLen = strlen(arg);
3316
3317     switch (KeyLen)
3318     {
3319         case 5: //wep 40 Ascii type
3320             pAdapter->SharedKey[BSS0][0].KeyLen = KeyLen;
3321             memcpy(pAdapter->SharedKey[BSS0][0].Key, arg, KeyLen);
3322             CipherAlg = CIPHER_WEP64;
3323             DBGPRINT(RT_DEBUG_TRACE, ("Set_Key1_Proc::(Key1=%s and type=%s)\n", arg, "Ascii"));
3324             break;
3325         case 10: //wep 40 Hex type
3326             for(i=0; i < KeyLen; i++)
3327             {
3328                 if( !isxdigit(*(arg+i)) )
3329                     return FALSE;  //Not Hex value;
3330             }
3331             pAdapter->SharedKey[BSS0][0].KeyLen = KeyLen / 2 ;
3332             AtoH(arg, pAdapter->SharedKey[BSS0][0].Key, KeyLen / 2);
3333             CipherAlg = CIPHER_WEP64;
3334             DBGPRINT(RT_DEBUG_TRACE, ("Set_Key1_Proc::(Key1=%s and type=%s)\n", arg, "Hex"));
3335             break;
3336         case 13: //wep 104 Ascii type
3337             pAdapter->SharedKey[BSS0][0].KeyLen = KeyLen;
3338             memcpy(pAdapter->SharedKey[BSS0][0].Key, arg, KeyLen);
3339             CipherAlg = CIPHER_WEP128;
3340             DBGPRINT(RT_DEBUG_TRACE, ("Set_Key1_Proc::(Key1=%s and type=%s)\n", arg, "Ascii"));
3341             break;
3342         case 26: //wep 104 Hex type
3343             for(i=0; i < KeyLen; i++)
3344             {
3345                 if( !isxdigit(*(arg+i)) )
3346                     return FALSE;  //Not Hex value;
3347             }
3348             pAdapter->SharedKey[BSS0][0].KeyLen = KeyLen / 2 ;
3349             AtoH(arg, pAdapter->SharedKey[BSS0][0].Key, KeyLen / 2);
3350             CipherAlg = CIPHER_WEP128;
3351             DBGPRINT(RT_DEBUG_TRACE, ("Set_Key1_Proc::(Key1=%s and type=%s)\n", arg, "Hex"));
3352             break;
3353         default: //Invalid argument
3354             DBGPRINT(RT_DEBUG_TRACE, ("Set_Key1_Proc::Invalid argument (=%s)\n", arg));
3355             return FALSE;
3356     }
3357
3358     pAdapter->SharedKey[BSS0][0].CipherAlg = CipherAlg;
3359
3360     // Set keys (into ASIC)
3361     if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
3362         ;   // not support
3363     else    // Old WEP stuff
3364     {
3365         AsicAddSharedKeyEntry(pAdapter,
3366                               0,
3367                               0,
3368                               pAdapter->SharedKey[BSS0][0].CipherAlg,
3369                               pAdapter->SharedKey[BSS0][0].Key,
3370                               NULL,
3371                               NULL);
3372     }
3373
3374     return TRUE;
3375 }
3376 /*
3377     ==========================================================================
3378
3379     Description:
3380         Set WEP KEY2
3381     Return:
3382         TRUE if all parameters are OK, FALSE otherwise
3383     ==========================================================================
3384 */
3385 INT Set_Key2_Proc(
3386     IN  PRTMP_ADAPTER   pAdapter,
3387     IN  PUCHAR          arg)
3388 {
3389     int                                 KeyLen;
3390     int                                 i;
3391     UCHAR                               CipherAlg=CIPHER_WEP64;
3392
3393     if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
3394         return TRUE;    // do nothing
3395
3396     KeyLen = strlen(arg);
3397
3398     switch (KeyLen)
3399     {
3400         case 5: //wep 40 Ascii type
3401             pAdapter->SharedKey[BSS0][1].KeyLen = KeyLen;
3402             memcpy(pAdapter->SharedKey[BSS0][1].Key, arg, KeyLen);
3403             CipherAlg = CIPHER_WEP64;
3404             DBGPRINT(RT_DEBUG_TRACE, ("Set_Key2_Proc::(Key2=%s and type=%s)\n", arg, "Ascii"));
3405             break;
3406         case 10: //wep 40 Hex type
3407             for(i=0; i < KeyLen; i++)
3408             {
3409                 if( !isxdigit(*(arg+i)) )
3410                     return FALSE;  //Not Hex value;
3411             }
3412             pAdapter->SharedKey[BSS0][1].KeyLen = KeyLen / 2 ;
3413             AtoH(arg, pAdapter->SharedKey[BSS0][1].Key, KeyLen / 2);
3414             CipherAlg = CIPHER_WEP64;
3415             DBGPRINT(RT_DEBUG_TRACE, ("Set_Key2_Proc::(Key2=%s and type=%s)\n", arg, "Hex"));
3416             break;
3417         case 13: //wep 104 Ascii type
3418             pAdapter->SharedKey[BSS0][1].KeyLen = KeyLen;
3419             memcpy(pAdapter->SharedKey[BSS0][1].Key, arg, KeyLen);
3420             CipherAlg = CIPHER_WEP128;
3421             DBGPRINT(RT_DEBUG_TRACE, ("Set_Key2_Proc::(Key2=%s and type=%s)\n", arg, "Ascii"));
3422             break;
3423         case 26: //wep 104 Hex type
3424             for(i=0; i < KeyLen; i++)
3425             {
3426                 if( !isxdigit(*(arg+i)) )
3427                     return FALSE;  //Not Hex value;
3428             }
3429             pAdapter->SharedKey[BSS0][1].KeyLen = KeyLen / 2 ;
3430             AtoH(arg, pAdapter->SharedKey[BSS0][1].Key, KeyLen / 2);
3431             CipherAlg = CIPHER_WEP128;
3432             DBGPRINT(RT_DEBUG_TRACE, ("Set_Key2_Proc::(Key2=%s and type=%s)\n", arg, "Hex"));
3433             break;
3434         default: //Invalid argument
3435             DBGPRINT(RT_DEBUG_TRACE, ("Set_Key2_Proc::Invalid argument (=%s)\n", arg));
3436             return FALSE;
3437     }
3438     pAdapter->SharedKey[BSS0][1].CipherAlg = CipherAlg;
3439
3440     // Set keys (into ASIC)
3441     if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
3442         ;   // not support
3443     else    // Old WEP stuff
3444     {
3445         AsicAddSharedKeyEntry(pAdapter,
3446                               0,
3447                               1,
3448                               pAdapter->SharedKey[BSS0][1].CipherAlg,
3449                               pAdapter->SharedKey[BSS0][1].Key,
3450                               NULL,
3451                               NULL);
3452     }
3453
3454     return TRUE;
3455 }
3456 /*
3457     ==========================================================================
3458     Description:
3459         Set WEP KEY3
3460     Return:
3461         TRUE if all parameters are OK, FALSE otherwise
3462     ==========================================================================
3463 */
3464 INT Set_Key3_Proc(
3465     IN  PRTMP_ADAPTER   pAdapter,
3466     IN  PUCHAR          arg)
3467 {
3468     int                                 KeyLen;
3469     int                                 i;
3470     UCHAR                               CipherAlg=CIPHER_WEP64;
3471
3472     if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
3473         return TRUE;    // do nothing
3474
3475     KeyLen = strlen(arg);
3476
3477     switch (KeyLen)
3478     {
3479         case 5: //wep 40 Ascii type
3480             pAdapter->SharedKey[BSS0][2].KeyLen = KeyLen;
3481             memcpy(pAdapter->SharedKey[BSS0][2].Key, arg, KeyLen);
3482             CipherAlg = CIPHER_WEP64;
3483             DBGPRINT(RT_DEBUG_TRACE, ("Set_Key3_Proc::(Key3=%s and type=Ascii)\n", arg));
3484             break;
3485         case 10: //wep 40 Hex type
3486             for(i=0; i < KeyLen; i++)
3487             {
3488                 if( !isxdigit(*(arg+i)) )
3489                     return FALSE;  //Not Hex value;
3490             }
3491             pAdapter->SharedKey[BSS0][2].KeyLen = KeyLen / 2 ;
3492             AtoH(arg, pAdapter->SharedKey[BSS0][2].Key, KeyLen / 2);
3493             CipherAlg = CIPHER_WEP64;
3494             DBGPRINT(RT_DEBUG_TRACE, ("Set_Key3_Proc::(Key3=%s and type=Hex)\n", arg));
3495             break;
3496         case 13: //wep 104 Ascii type
3497             pAdapter->SharedKey[BSS0][2].KeyLen = KeyLen;
3498             memcpy(pAdapter->SharedKey[BSS0][2].Key, arg, KeyLen);
3499             CipherAlg = CIPHER_WEP128;
3500             DBGPRINT(RT_DEBUG_TRACE, ("Set_Key3_Proc::(Key3=%s and type=Ascii)\n", arg));
3501             break;
3502         case 26: //wep 104 Hex type
3503             for(i=0; i < KeyLen; i++)
3504             {
3505                 if( !isxdigit(*(arg+i)) )
3506                     return FALSE;  //Not Hex value;
3507             }
3508             pAdapter->SharedKey[BSS0][2].KeyLen = KeyLen / 2 ;
3509             AtoH(arg, pAdapter->SharedKey[BSS0][2].Key, KeyLen / 2);
3510             CipherAlg = CIPHER_WEP128;
3511             DBGPRINT(RT_DEBUG_TRACE, ("Set_Key3_Proc::(Key3=%s and type=Hex)\n", arg));
3512             break;
3513         default: //Invalid argument
3514             DBGPRINT(RT_DEBUG_TRACE, ("Set_Key3_Proc::Invalid argument (=%s)\n", arg));
3515             return FALSE;
3516     }
3517     pAdapter->SharedKey[BSS0][2].CipherAlg = CipherAlg;
3518
3519     // Set keys (into ASIC)
3520     if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
3521         ;   // not support
3522     else    // Old WEP stuff
3523     {
3524         AsicAddSharedKeyEntry(pAdapter,
3525                               0,
3526                               2,
3527                               pAdapter->SharedKey[BSS0][2].CipherAlg,
3528                               pAdapter->SharedKey[BSS0][2].Key,
3529                               NULL,
3530                               NULL);
3531     }
3532
3533     return TRUE;
3534 }
3535 /*
3536     ==========================================================================
3537     Description:
3538         Set WEP KEY4
3539     Return:
3540         TRUE if all parameters are OK, FALSE otherwise
3541     ==========================================================================
3542 */
3543 INT Set_Key4_Proc(
3544     IN  PRTMP_ADAPTER   pAdapter,
3545     IN  PUCHAR          arg)
3546 {
3547     int                                 KeyLen;
3548     int                                 i;
3549     UCHAR                               CipherAlg=CIPHER_WEP64;
3550
3551     if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
3552         return TRUE;    // do nothing
3553
3554     KeyLen = strlen(arg);
3555
3556     switch (KeyLen)
3557     {
3558         case 5: //wep 40 Ascii type
3559             pAdapter->SharedKey[BSS0][3].KeyLen = KeyLen;
3560             memcpy(pAdapter->SharedKey[BSS0][3].Key, arg, KeyLen);
3561             CipherAlg = CIPHER_WEP64;
3562             DBGPRINT(RT_DEBUG_TRACE, ("Set_Key4_Proc::(Key4=%s and type=%s)\n", arg, "Ascii"));
3563             break;
3564         case 10: //wep 40 Hex type
3565             for(i=0; i < KeyLen; i++)
3566             {
3567                 if( !isxdigit(*(arg+i)) )
3568                     return FALSE;  //Not Hex value;
3569             }
3570             pAdapter->SharedKey[BSS0][3].KeyLen = KeyLen / 2 ;
3571             AtoH(arg, pAdapter->SharedKey[BSS0][3].Key, KeyLen / 2);
3572             CipherAlg = CIPHER_WEP64;
3573             DBGPRINT(RT_DEBUG_TRACE, ("Set_Key4_Proc::(Key4=%s and type=%s)\n", arg, "Hex"));
3574             break;
3575         case 13: //wep 104 Ascii type
3576             pAdapter->SharedKey[BSS0][3].KeyLen = KeyLen;
3577             memcpy(pAdapter->SharedKey[BSS0][3].Key, arg, KeyLen);
3578             CipherAlg = CIPHER_WEP128;
3579             DBGPRINT(RT_DEBUG_TRACE, ("Set_Key4_Proc::(Key4=%s and type=%s)\n", arg, "Ascii"));
3580             break;
3581         case 26: //wep 104 Hex type
3582             for(i=0; i < KeyLen; i++)
3583             {
3584                 if( !isxdigit(*(arg+i)) )
3585                     return FALSE;  //Not Hex value;
3586             }
3587             pAdapter->SharedKey[BSS0][3].KeyLen = KeyLen / 2 ;
3588             AtoH(arg, pAdapter->SharedKey[BSS0][3].Key, KeyLen / 2);
3589             CipherAlg = CIPHER_WEP128;
3590             DBGPRINT(RT_DEBUG_TRACE, ("Set_Key4_Proc::(Key4=%s and type=%s)\n", arg, "Hex"));
3591             break;
3592         default: //Invalid argument
3593             DBGPRINT(RT_DEBUG_TRACE, ("Set_Key4_Proc::Invalid argument (=%s)\n", arg));
3594             return FALSE;
3595     }
3596     pAdapter->SharedKey[BSS0][3].CipherAlg = CipherAlg;
3597
3598     // Set keys (into ASIC)
3599     if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
3600         ;   // not support
3601     else    // Old WEP stuff
3602     {
3603         AsicAddSharedKeyEntry(pAdapter,
3604                               0,
3605                               3,
3606                               pAdapter->SharedKey[BSS0][3].CipherAlg,
3607                               pAdapter->SharedKey[BSS0][3].Key,
3608                               NULL,
3609                               NULL);
3610     }
3611
3612     return TRUE;
3613 }
3614
3615 /*
3616     ==========================================================================
3617     Description:
3618         Set WPA PSK key
3619     Return:
3620         TRUE if all parameters are OK, FALSE otherwise
3621     ==========================================================================
3622 */
3623 INT Set_WPAPSK_Proc(
3624     IN  PRTMP_ADAPTER   pAdapter,
3625     IN  PUCHAR          arg)
3626 {
3627     UCHAR                   keyMaterial[40];
3628
3629     if ((pAdapter->StaCfg.AuthMode != Ndis802_11AuthModeWPAPSK) &&
3630         (pAdapter->StaCfg.AuthMode != Ndis802_11AuthModeWPA2PSK) &&
3631             (pAdapter->StaCfg.AuthMode != Ndis802_11AuthModeWPANone)
3632                 )
3633         return TRUE;    // do nothing
3634
3635     DBGPRINT(RT_DEBUG_TRACE, ("Set_WPAPSK_Proc::(WPAPSK=%s)\n", arg));
3636
3637     NdisZeroMemory(keyMaterial, 40);
3638
3639     if ((strlen(arg) < 8) || (strlen(arg) > 64))
3640     {
3641         DBGPRINT(RT_DEBUG_TRACE, ("Set failed!!(WPAPSK=%s), WPAPSK key-string required 8 ~ 64 characters \n", arg));
3642         return FALSE;
3643     }
3644
3645     if (strlen(arg) == 64)
3646     {
3647         AtoH(arg, keyMaterial, 32);
3648         NdisMoveMemory(pAdapter->StaCfg.PMK, keyMaterial, 32);
3649
3650     }
3651     else
3652     {
3653         PasswordHash((char *)arg, pAdapter->MlmeAux.Ssid, pAdapter->MlmeAux.SsidLen, keyMaterial);
3654         NdisMoveMemory(pAdapter->StaCfg.PMK, keyMaterial, 32);
3655     }
3656
3657
3658
3659     if(pAdapter->StaCfg.BssType == BSS_ADHOC &&
3660        pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
3661     {
3662          pAdapter->StaCfg.WpaState = SS_NOTUSE;
3663     }
3664     else
3665     {
3666         // Start STA supplicant state machine
3667         pAdapter->StaCfg.WpaState = SS_START;
3668     }
3669
3670     return TRUE;
3671 }
3672
3673 /*
3674     ==========================================================================
3675     Description:
3676         Set Power Saving mode
3677     Return:
3678         TRUE if all parameters are OK, FALSE otherwise
3679     ==========================================================================
3680 */
3681 INT Set_PSMode_Proc(
3682     IN  PRTMP_ADAPTER   pAdapter,
3683     IN  PUCHAR          arg)
3684 {
3685     if (pAdapter->StaCfg.BssType == BSS_INFRA)
3686     {
3687         if ((strcmp(arg, "Max_PSP") == 0) ||
3688                         (strcmp(arg, "max_psp") == 0) ||
3689                         (strcmp(arg, "MAX_PSP") == 0))
3690         {
3691             // do NOT turn on PSM bit here, wait until MlmeCheckForPsmChange()
3692             // to exclude certain situations.
3693             if (pAdapter->StaCfg.bWindowsACCAMEnable == FALSE)
3694                 pAdapter->StaCfg.WindowsPowerMode = Ndis802_11PowerModeMAX_PSP;
3695             pAdapter->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeMAX_PSP;
3696             OPSTATUS_SET_FLAG(pAdapter, fOP_STATUS_RECEIVE_DTIM);
3697             pAdapter->StaCfg.DefaultListenCount = 5;
3698
3699         }
3700         else if ((strcmp(arg, "Fast_PSP") == 0) ||
3701                                  (strcmp(arg, "fast_psp") == 0) ||
3702                  (strcmp(arg, "FAST_PSP") == 0))
3703         {
3704             // do NOT turn on PSM bit here, wait until MlmeCheckForPsmChange()
3705             // to exclude certain situations.
3706             OPSTATUS_SET_FLAG(pAdapter, fOP_STATUS_RECEIVE_DTIM);
3707             if (pAdapter->StaCfg.bWindowsACCAMEnable == FALSE)
3708                 pAdapter->StaCfg.WindowsPowerMode = Ndis802_11PowerModeFast_PSP;
3709             pAdapter->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeFast_PSP;
3710             pAdapter->StaCfg.DefaultListenCount = 3;
3711         }
3712         else if ((strcmp(arg, "Legacy_PSP") == 0) ||
3713                  (strcmp(arg, "legacy_psp") == 0) ||
3714                  (strcmp(arg, "LEGACY_PSP") == 0))
3715         {
3716             // do NOT turn on PSM bit here, wait until MlmeCheckForPsmChange()
3717             // to exclude certain situations.
3718             OPSTATUS_SET_FLAG(pAdapter, fOP_STATUS_RECEIVE_DTIM);
3719             if (pAdapter->StaCfg.bWindowsACCAMEnable == FALSE)
3720                 pAdapter->StaCfg.WindowsPowerMode = Ndis802_11PowerModeLegacy_PSP;
3721             pAdapter->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeLegacy_PSP;
3722             pAdapter->StaCfg.DefaultListenCount = 3;
3723         }
3724         else
3725         {
3726             //Default Ndis802_11PowerModeCAM
3727             // clear PSM bit immediately
3728             MlmeSetPsmBit(pAdapter, PWR_ACTIVE);
3729             OPSTATUS_SET_FLAG(pAdapter, fOP_STATUS_RECEIVE_DTIM);
3730             if (pAdapter->StaCfg.bWindowsACCAMEnable == FALSE)
3731                 pAdapter->StaCfg.WindowsPowerMode = Ndis802_11PowerModeCAM;
3732             pAdapter->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeCAM;
3733         }
3734
3735         DBGPRINT(RT_DEBUG_TRACE, ("Set_PSMode_Proc::(PSMode=%ld)\n", pAdapter->StaCfg.WindowsPowerMode));
3736     }
3737     else
3738         return FALSE;
3739
3740
3741     return TRUE;
3742 }
3743
3744 /*
3745     ==========================================================================
3746     Description:
3747         Set WpaSupport flag.
3748     Value:
3749         0: Driver ignore wpa_supplicant.
3750         1: wpa_supplicant initiates scanning and AP selection.
3751         2: driver takes care of scanning, AP selection, and IEEE 802.11 association parameters.
3752     Return:
3753         TRUE if all parameters are OK, FALSE otherwise
3754     ==========================================================================
3755 */
3756 INT Set_Wpa_Support(
3757     IN  PRTMP_ADAPTER   pAd,
3758         IN      PUCHAR                  arg)
3759 {
3760
3761     if ( simple_strtol(arg, 0, 10) == 0)
3762         pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_DISABLE;
3763     else if ( simple_strtol(arg, 0, 10) == 1)
3764         pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_ENABLE;
3765     else if ( simple_strtol(arg, 0, 10) == 2)
3766         pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_ENABLE_WITH_WEB_UI;
3767     else
3768         pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_DISABLE;
3769
3770     DBGPRINT(RT_DEBUG_TRACE, ("Set_Wpa_Support::(WpaSupplicantUP=%d)\n", pAd->StaCfg.WpaSupplicantUP));
3771
3772     return TRUE;
3773 }
3774
3775 INT Set_TGnWifiTest_Proc(
3776     IN  PRTMP_ADAPTER   pAd,
3777     IN  PUCHAR          arg)
3778 {
3779     if (simple_strtol(arg, 0, 10) == 0)
3780         pAd->StaCfg.bTGnWifiTest = FALSE;
3781     else
3782         pAd->StaCfg.bTGnWifiTest = TRUE;
3783
3784     DBGPRINT(RT_DEBUG_TRACE, ("IF Set_TGnWifiTest_Proc::(bTGnWifiTest=%d)\n", pAd->StaCfg.bTGnWifiTest));
3785         return TRUE;
3786 }
3787
3788 INT Set_LongRetryLimit_Proc(
3789         IN      PRTMP_ADAPTER   pAdapter,
3790         IN      PUCHAR                  arg)
3791 {
3792         TX_RTY_CFG_STRUC        tx_rty_cfg;
3793         UCHAR                           LongRetryLimit = (UCHAR)simple_strtol(arg, 0, 10);
3794
3795         RTMP_IO_READ32(pAdapter, TX_RTY_CFG, &tx_rty_cfg.word);
3796         tx_rty_cfg.field.LongRtyLimit = LongRetryLimit;
3797         RTMP_IO_WRITE32(pAdapter, TX_RTY_CFG, tx_rty_cfg.word);
3798         DBGPRINT(RT_DEBUG_TRACE, ("IF Set_LongRetryLimit_Proc::(tx_rty_cfg=0x%x)\n", tx_rty_cfg.word));
3799         return TRUE;
3800 }
3801
3802 INT Set_ShortRetryLimit_Proc(
3803         IN      PRTMP_ADAPTER   pAdapter,
3804         IN      PUCHAR                  arg)
3805 {
3806         TX_RTY_CFG_STRUC        tx_rty_cfg;
3807         UCHAR                           ShortRetryLimit = (UCHAR)simple_strtol(arg, 0, 10);
3808
3809         RTMP_IO_READ32(pAdapter, TX_RTY_CFG, &tx_rty_cfg.word);
3810         tx_rty_cfg.field.ShortRtyLimit = ShortRetryLimit;
3811         RTMP_IO_WRITE32(pAdapter, TX_RTY_CFG, tx_rty_cfg.word);
3812         DBGPRINT(RT_DEBUG_TRACE, ("IF Set_ShortRetryLimit_Proc::(tx_rty_cfg=0x%x)\n", tx_rty_cfg.word));
3813         return TRUE;
3814 }
3815
3816 #if !defined(RT2860) && !defined(RT30xx)
3817 INT     Show_Adhoc_MacTable_Proc(
3818         IN      PRTMP_ADAPTER   pAd,
3819         IN      PCHAR                   extra)
3820 {
3821         INT i;
3822
3823         sprintf(extra, "\n");
3824
3825         sprintf(extra + strlen(extra), "HT Operating Mode : %d\n", pAd->CommonCfg.AddHTInfo.AddHtInfo2.OperaionMode);
3826
3827         sprintf(extra + strlen(extra), "\n%-19s%-4s%-4s%-7s%-7s%-7s%-10s%-6s%-6s%-6s%-6s\n",
3828                         "MAC", "AID", "BSS", "RSSI0", "RSSI1", "RSSI2", "PhMd", "BW", "MCS", "SGI", "STBC");
3829
3830         for (i=1; i<MAX_LEN_OF_MAC_TABLE; i++)
3831         {
3832                 PMAC_TABLE_ENTRY pEntry = &pAd->MacTab.Content[i];
3833
3834                 if (strlen(extra) > (IW_PRIV_SIZE_MASK - 30))
3835                     break;
3836                 if ((pEntry->ValidAsCLI || pEntry->ValidAsApCli) && (pEntry->Sst == SST_ASSOC))
3837                 {
3838                         sprintf(extra + strlen(extra), "%02X:%02X:%02X:%02X:%02X:%02X  ",
3839                                 pEntry->Addr[0], pEntry->Addr[1], pEntry->Addr[2],
3840                                 pEntry->Addr[3], pEntry->Addr[4], pEntry->Addr[5]);
3841                         sprintf(extra + strlen(extra), "%-4d", (int)pEntry->Aid);
3842                         sprintf(extra + strlen(extra), "%-4d", (int)pEntry->apidx);
3843                         sprintf(extra + strlen(extra), "%-7d", pEntry->RssiSample.AvgRssi0);
3844                         sprintf(extra + strlen(extra), "%-7d", pEntry->RssiSample.AvgRssi1);
3845                         sprintf(extra + strlen(extra), "%-7d", pEntry->RssiSample.AvgRssi2);
3846                         sprintf(extra + strlen(extra), "%-10s", GetPhyMode(pEntry->HTPhyMode.field.MODE));
3847                         sprintf(extra + strlen(extra), "%-6s", GetBW(pEntry->HTPhyMode.field.BW));
3848                         sprintf(extra + strlen(extra), "%-6d", pEntry->HTPhyMode.field.MCS);
3849                         sprintf(extra + strlen(extra), "%-6d", pEntry->HTPhyMode.field.ShortGI);
3850                         sprintf(extra + strlen(extra), "%-6d", pEntry->HTPhyMode.field.STBC);
3851                         sprintf(extra + strlen(extra), "%-10d, %d, %d%%\n", pEntry->DebugFIFOCount, pEntry->DebugTxCount,
3852                                                 (pEntry->DebugTxCount) ? ((pEntry->DebugTxCount-pEntry->DebugFIFOCount)*100/pEntry->DebugTxCount) : 0);
3853                         sprintf(extra, "%s\n", extra);
3854                 }
3855         }
3856
3857         return TRUE;
3858 }
3859 #endif /* RT2870 */