Staging: rtxx70: unify NICInitRT30xxRFRegisters()
[safe/jmp/linux-2.6] / 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 #ifdef RT30xx
985         if (current_ev == previous_ev)
986                 return -E2BIG;
987
988                 /*
989                 Protocol:
990                         it will show scanned AP's WirelessMode .
991                         it might be
992                                         802.11a
993                                         802.11a/n
994                                         802.11g/n
995                                         802.11b/g/n
996                                         802.11g
997                                         802.11b/g
998                 */
999                 memset(&iwe, 0, sizeof(iwe));
1000                 iwe.cmd = SIOCGIWNAME;
1001
1002
1003         {
1004                 PBSS_ENTRY pBssEntry=&pAdapter->ScanTab.BssEntry[i];
1005                 BOOLEAN isGonly=FALSE;
1006                 int rateCnt=0;
1007
1008                 if (pBssEntry->Channel>14)
1009                 {
1010                         if (pBssEntry->HtCapabilityLen!=0)
1011                                 strcpy(iwe.u.name,"802.11a/n");
1012                         else
1013                                 strcpy(iwe.u.name,"802.11a");
1014                 }
1015                 else
1016                 {
1017                         /*
1018                                 if one of non B mode rate is set supported rate . it mean G only.
1019                         */
1020                         for (rateCnt=0;rateCnt<pBssEntry->SupRateLen;rateCnt++)
1021                         {
1022                                 /*
1023                                         6Mbps(140) 9Mbps(146) and >=12Mbps(152) are supported rate , it mean G only.
1024                                 */
1025                                 if (pBssEntry->SupRate[rateCnt]==140 || pBssEntry->SupRate[rateCnt]==146 || pBssEntry->SupRate[rateCnt]>=152)
1026                                         isGonly=TRUE;
1027                         }
1028
1029                         for (rateCnt=0;rateCnt<pBssEntry->ExtRateLen;rateCnt++)
1030                         {
1031                                 if (pBssEntry->ExtRate[rateCnt]==140 || pBssEntry->ExtRate[rateCnt]==146 || pBssEntry->ExtRate[rateCnt]>=152)
1032                                         isGonly=TRUE;
1033                         }
1034
1035
1036                         if (pBssEntry->HtCapabilityLen!=0)
1037                         {
1038                                 if (isGonly==TRUE)
1039                                         strcpy(iwe.u.name,"802.11g/n");
1040                                 else
1041                                         strcpy(iwe.u.name,"802.11b/g/n");
1042                         }
1043                         else
1044                         {
1045                                 if (isGonly==TRUE)
1046                                         strcpy(iwe.u.name,"802.11g");
1047                                 else
1048                                 {
1049                                         if (pBssEntry->SupRateLen==4 && pBssEntry->ExtRateLen==0)
1050                                                 strcpy(iwe.u.name,"802.11b");
1051                                         else
1052                                                 strcpy(iwe.u.name,"802.11b/g");
1053                                 }
1054                         }
1055                 }
1056         }
1057
1058                 previous_ev = current_ev;
1059                 current_ev       = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_ADDR_LEN);
1060 #endif /* RT30xx */
1061         if (current_ev == previous_ev)
1062                 return -E2BIG;
1063
1064                 //ESSID
1065                 //================================
1066                 memset(&iwe, 0, sizeof(iwe));
1067                 iwe.cmd = SIOCGIWESSID;
1068                 iwe.u.data.length = pAdapter->ScanTab.BssEntry[i].SsidLen;
1069                 iwe.u.data.flags = 1;
1070
1071         previous_ev = current_ev;
1072                 current_ev = iwe_stream_add_point(info, current_ev,end_buf, &iwe, pAdapter->ScanTab.BssEntry[i].Ssid);
1073         if (current_ev == previous_ev)
1074                 return -E2BIG;
1075
1076                 //Network Type
1077                 //================================
1078                 memset(&iwe, 0, sizeof(iwe));
1079                 iwe.cmd = SIOCGIWMODE;
1080                 if (pAdapter->ScanTab.BssEntry[i].BssType == Ndis802_11IBSS)
1081                 {
1082                         iwe.u.mode = IW_MODE_ADHOC;
1083                 }
1084                 else if (pAdapter->ScanTab.BssEntry[i].BssType == Ndis802_11Infrastructure)
1085                 {
1086                         iwe.u.mode = IW_MODE_INFRA;
1087                 }
1088                 else
1089                 {
1090                         iwe.u.mode = IW_MODE_AUTO;
1091                 }
1092                 iwe.len = IW_EV_UINT_LEN;
1093
1094         previous_ev = current_ev;
1095                 current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe,  IW_EV_UINT_LEN);
1096         if (current_ev == previous_ev)
1097                 return -E2BIG;
1098
1099                 //Channel and Frequency
1100                 //================================
1101                 memset(&iwe, 0, sizeof(iwe));
1102                 iwe.cmd = SIOCGIWFREQ;
1103                 if (INFRA_ON(pAdapter) || ADHOC_ON(pAdapter))
1104                         iwe.u.freq.m = pAdapter->ScanTab.BssEntry[i].Channel;
1105                 else
1106                         iwe.u.freq.m = pAdapter->ScanTab.BssEntry[i].Channel;
1107                 iwe.u.freq.e = 0;
1108                 iwe.u.freq.i = 0;
1109
1110                 previous_ev = current_ev;
1111                 current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_FREQ_LEN);
1112         if (current_ev == previous_ev)
1113                 return -E2BIG;
1114
1115         //Add quality statistics
1116         //================================
1117         memset(&iwe, 0, sizeof(iwe));
1118         iwe.cmd = IWEVQUAL;
1119         iwe.u.qual.level = 0;
1120         iwe.u.qual.noise = 0;
1121         set_quality(pAdapter, &iwe.u.qual, pAdapter->ScanTab.BssEntry[i].Rssi);
1122         current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_QUAL_LEN);
1123         if (current_ev == previous_ev)
1124                 return -E2BIG;
1125
1126                 //Encyption key
1127                 //================================
1128                 memset(&iwe, 0, sizeof(iwe));
1129                 iwe.cmd = SIOCGIWENCODE;
1130                 if (CAP_IS_PRIVACY_ON (pAdapter->ScanTab.BssEntry[i].CapabilityInfo ))
1131                         iwe.u.data.flags =IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
1132                 else
1133                         iwe.u.data.flags = IW_ENCODE_DISABLED;
1134
1135         previous_ev = current_ev;
1136         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);
1137         if (current_ev == previous_ev)
1138                 return -E2BIG;
1139
1140                 //Bit Rate
1141                 //================================
1142                 if (pAdapter->ScanTab.BssEntry[i].SupRateLen)
1143         {
1144             UCHAR tmpRate = pAdapter->ScanTab.BssEntry[i].SupRate[pAdapter->ScanTab.BssEntry[i].SupRateLen-1];
1145                         memset(&iwe, 0, sizeof(iwe));
1146                         iwe.cmd = SIOCGIWRATE;
1147                 current_val = current_ev + IW_EV_LCP_LEN;
1148             if (tmpRate == 0x82)
1149                 iwe.u.bitrate.value =  1 * 1000000;
1150             else if (tmpRate == 0x84)
1151                 iwe.u.bitrate.value =  2 * 1000000;
1152             else if (tmpRate == 0x8B)
1153                 iwe.u.bitrate.value =  5.5 * 1000000;
1154             else if (tmpRate == 0x96)
1155                 iwe.u.bitrate.value =  11 * 1000000;
1156             else
1157                     iwe.u.bitrate.value =  (tmpRate/2) * 1000000;
1158
1159                         iwe.u.bitrate.disabled = 0;
1160                         current_val = iwe_stream_add_value(info, current_ev,
1161                                 current_val, end_buf, &iwe,
1162                         IW_EV_PARAM_LEN);
1163
1164                 if((current_val-current_ev)>IW_EV_LCP_LEN)
1165                 current_ev = current_val;
1166                 else
1167                         return -E2BIG;
1168         }
1169
1170                 //WPA IE
1171                 if (pAdapter->ScanTab.BssEntry[i].WpaIE.IELen > 0)
1172                 {
1173                         memset(&iwe, 0, sizeof(iwe));
1174                         memset(&custom[0], 0, MAX_CUSTOM_LEN);
1175                         memcpy(custom, &(pAdapter->ScanTab.BssEntry[i].WpaIE.IE[0]),
1176                                                    pAdapter->ScanTab.BssEntry[i].WpaIE.IELen);
1177                         iwe.cmd = IWEVGENIE;
1178                         iwe.u.data.length = pAdapter->ScanTab.BssEntry[i].WpaIE.IELen;
1179                         current_ev = iwe_stream_add_point(info, current_ev, end_buf, &iwe, custom);
1180                         if (current_ev == previous_ev)
1181                                 return -E2BIG;
1182                 }
1183
1184                 //WPA2 IE
1185         if (pAdapter->ScanTab.BssEntry[i].RsnIE.IELen > 0)
1186         {
1187                 memset(&iwe, 0, sizeof(iwe));
1188                         memset(&custom[0], 0, MAX_CUSTOM_LEN);
1189                         memcpy(custom, &(pAdapter->ScanTab.BssEntry[i].RsnIE.IE[0]),
1190                                                    pAdapter->ScanTab.BssEntry[i].RsnIE.IELen);
1191                         iwe.cmd = IWEVGENIE;
1192                         iwe.u.data.length = pAdapter->ScanTab.BssEntry[i].RsnIE.IELen;
1193                         current_ev = iwe_stream_add_point(info, current_ev, end_buf, &iwe, custom);
1194                         if (current_ev == previous_ev)
1195                                 return -E2BIG;
1196         }
1197         }
1198
1199         data->length = current_ev - extra;
1200     pAdapter->StaCfg.bScanReqIsFromWebUI = FALSE;
1201         DBGPRINT(RT_DEBUG_ERROR ,("===>rt_ioctl_giwscan. %d(%d) BSS returned, data->length = %d\n",i , pAdapter->ScanTab.BssNr, data->length));
1202         return 0;
1203 }
1204
1205 int rt_ioctl_siwessid(struct net_device *dev,
1206                          struct iw_request_info *info,
1207                          struct iw_point *data, char *essid)
1208 {
1209         PRTMP_ADAPTER pAdapter = dev->ml_priv;
1210
1211         //check if the interface is down
1212     if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
1213     {
1214         DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
1215         return -ENETDOWN;
1216     }
1217
1218         if (data->flags)
1219         {
1220                 PCHAR   pSsidString = NULL;
1221
1222                 // Includes null character.
1223                 if (data->length > (IW_ESSID_MAX_SIZE + 1))
1224                         return -E2BIG;
1225
1226                 pSsidString = (CHAR *) kmalloc(MAX_LEN_OF_SSID+1, MEM_ALLOC_FLAG);
1227                 if (pSsidString)
1228                 {
1229                         NdisZeroMemory(pSsidString, MAX_LEN_OF_SSID+1);
1230                         NdisMoveMemory(pSsidString, essid, data->length);
1231                         if (Set_SSID_Proc(pAdapter, pSsidString) == FALSE)
1232                                 return -EINVAL;
1233                 }
1234                 else
1235                         return -ENOMEM;
1236         }
1237         else
1238         {
1239                 // ANY ssid
1240                 if (Set_SSID_Proc(pAdapter, "") == FALSE)
1241                         return -EINVAL;
1242     }
1243         return 0;
1244 }
1245
1246 int rt_ioctl_giwessid(struct net_device *dev,
1247                          struct iw_request_info *info,
1248                          struct iw_point *data, char *essid)
1249 {
1250         PRTMP_ADAPTER pAdapter = dev->ml_priv;
1251
1252         data->flags = 1;
1253     if (MONITOR_ON(pAdapter))
1254     {
1255         data->length  = 0;
1256         return 0;
1257     }
1258
1259         if (OPSTATUS_TEST_FLAG(pAdapter, fOP_STATUS_MEDIA_STATE_CONNECTED))
1260         {
1261                 DBGPRINT(RT_DEBUG_TRACE ,("MediaState is connected\n"));
1262                 data->length = pAdapter->CommonCfg.SsidLen;
1263                 memcpy(essid, pAdapter->CommonCfg.Ssid, pAdapter->CommonCfg.SsidLen);
1264         }
1265 #ifdef RT2870
1266     // Add for RT2870
1267     else if (pAdapter->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE)
1268     {
1269         data->length = pAdapter->CommonCfg.SsidLen;
1270                 memcpy(essid, pAdapter->CommonCfg.Ssid, pAdapter->CommonCfg.SsidLen);
1271         }
1272 #endif // RT2870 //
1273         else
1274         {//the ANY ssid was specified
1275                 data->length  = 0;
1276                 DBGPRINT(RT_DEBUG_TRACE ,("MediaState is not connected, ess\n"));
1277         }
1278
1279         return 0;
1280
1281 }
1282
1283 int rt_ioctl_siwnickn(struct net_device *dev,
1284                          struct iw_request_info *info,
1285                          struct iw_point *data, char *nickname)
1286 {
1287         PRTMP_ADAPTER pAdapter = dev->ml_priv;
1288
1289     //check if the interface is down
1290     if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
1291     {
1292         DBGPRINT(RT_DEBUG_TRACE ,("INFO::Network is down!\n"));
1293         return -ENETDOWN;
1294     }
1295
1296         if (data->length > IW_ESSID_MAX_SIZE)
1297                 return -EINVAL;
1298
1299         memset(pAdapter->nickname, 0, IW_ESSID_MAX_SIZE + 1);
1300         memcpy(pAdapter->nickname, nickname, data->length);
1301
1302
1303         return 0;
1304 }
1305
1306 int rt_ioctl_giwnickn(struct net_device *dev,
1307                          struct iw_request_info *info,
1308                          struct iw_point *data, char *nickname)
1309 {
1310         PRTMP_ADAPTER pAdapter = dev->ml_priv;
1311
1312         if (data->length > strlen(pAdapter->nickname) + 1)
1313                 data->length = strlen(pAdapter->nickname) + 1;
1314         if (data->length > 0) {
1315                 memcpy(nickname, pAdapter->nickname, data->length-1);
1316                 nickname[data->length-1] = '\0';
1317         }
1318         return 0;
1319 }
1320
1321 int rt_ioctl_siwrts(struct net_device *dev,
1322                        struct iw_request_info *info,
1323                        struct iw_param *rts, char *extra)
1324 {
1325         PRTMP_ADAPTER pAdapter = dev->ml_priv;
1326         u16 val;
1327
1328     //check if the interface is down
1329     if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
1330     {
1331         DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
1332         return -ENETDOWN;
1333     }
1334
1335         if (rts->disabled)
1336                 val = MAX_RTS_THRESHOLD;
1337         else if (rts->value < 0 || rts->value > MAX_RTS_THRESHOLD)
1338                 return -EINVAL;
1339         else if (rts->value == 0)
1340             val = MAX_RTS_THRESHOLD;
1341         else
1342                 val = rts->value;
1343
1344         if (val != pAdapter->CommonCfg.RtsThreshold)
1345                 pAdapter->CommonCfg.RtsThreshold = val;
1346
1347         return 0;
1348 }
1349
1350 int rt_ioctl_giwrts(struct net_device *dev,
1351                        struct iw_request_info *info,
1352                        struct iw_param *rts, char *extra)
1353 {
1354         PRTMP_ADAPTER pAdapter = dev->ml_priv;
1355
1356         //check if the interface is down
1357         if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
1358         {
1359                 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
1360                 return -ENETDOWN;
1361         }
1362
1363         rts->value = pAdapter->CommonCfg.RtsThreshold;
1364         rts->disabled = (rts->value == MAX_RTS_THRESHOLD);
1365         rts->fixed = 1;
1366
1367         return 0;
1368 }
1369
1370 int rt_ioctl_siwfrag(struct net_device *dev,
1371                         struct iw_request_info *info,
1372                         struct iw_param *frag, char *extra)
1373 {
1374         PRTMP_ADAPTER pAdapter = dev->ml_priv;
1375         u16 val;
1376
1377         //check if the interface is down
1378         if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
1379         {
1380                 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
1381                 return -ENETDOWN;
1382         }
1383
1384         if (frag->disabled)
1385                 val = MAX_FRAG_THRESHOLD;
1386         else if (frag->value >= MIN_FRAG_THRESHOLD || frag->value <= MAX_FRAG_THRESHOLD)
1387         val = __cpu_to_le16(frag->value & ~0x1); /* even numbers only */
1388         else if (frag->value == 0)
1389             val = MAX_FRAG_THRESHOLD;
1390         else
1391                 return -EINVAL;
1392
1393         pAdapter->CommonCfg.FragmentThreshold = val;
1394         return 0;
1395 }
1396
1397 int rt_ioctl_giwfrag(struct net_device *dev,
1398                         struct iw_request_info *info,
1399                         struct iw_param *frag, char *extra)
1400 {
1401         PRTMP_ADAPTER pAdapter = dev->ml_priv;
1402
1403         //check if the interface is down
1404         if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
1405         {
1406                 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
1407                 return -ENETDOWN;
1408         }
1409
1410         frag->value = pAdapter->CommonCfg.FragmentThreshold;
1411         frag->disabled = (frag->value == MAX_FRAG_THRESHOLD);
1412         frag->fixed = 1;
1413
1414         return 0;
1415 }
1416
1417 #define MAX_WEP_KEY_SIZE 13
1418 #define MIN_WEP_KEY_SIZE 5
1419 int rt_ioctl_siwencode(struct net_device *dev,
1420                           struct iw_request_info *info,
1421                           struct iw_point *erq, char *extra)
1422 {
1423         PRTMP_ADAPTER pAdapter = dev->ml_priv;
1424
1425         //check if the interface is down
1426         if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
1427         {
1428                 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
1429                 return -ENETDOWN;
1430         }
1431
1432         if ((erq->length == 0) &&
1433         (erq->flags & IW_ENCODE_DISABLED))
1434         {
1435                 pAdapter->StaCfg.PairCipher = Ndis802_11WEPDisabled;
1436                 pAdapter->StaCfg.GroupCipher = Ndis802_11WEPDisabled;
1437                 pAdapter->StaCfg.WepStatus = Ndis802_11WEPDisabled;
1438         pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
1439         pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
1440         goto done;
1441         } else if (
1442 #ifndef RT30xx
1443                  erq->length == 0 &&
1444 #endif
1445                  (erq->flags & IW_ENCODE_RESTRICTED || erq->flags & IW_ENCODE_OPEN)) {
1446                 STA_PORT_SECURED(pAdapter);
1447                 pAdapter->StaCfg.PairCipher = Ndis802_11WEPEnabled;
1448                 pAdapter->StaCfg.GroupCipher = Ndis802_11WEPEnabled;
1449                 pAdapter->StaCfg.WepStatus = Ndis802_11WEPEnabled;
1450         pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
1451                 if (erq->flags & IW_ENCODE_RESTRICTED)
1452                         pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeShared;
1453         else
1454                         pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
1455 #ifndef RT30xx
1456         goto done;
1457 #endif
1458         }
1459
1460     if (erq->length > 0)
1461         {
1462                 int keyIdx = (erq->flags & IW_ENCODE_INDEX) - 1;
1463                 /* Check the size of the key */
1464                 if (erq->length > MAX_WEP_KEY_SIZE) {
1465                         return -EINVAL;
1466                 }
1467                 /* Check key index */
1468                 if ((keyIdx < 0) || (keyIdx >= NR_WEP_KEYS))
1469         {
1470             DBGPRINT(RT_DEBUG_TRACE ,("==>rt_ioctl_siwencode::Wrong keyIdx=%d! Using default key instead (%d)\n",
1471                                         keyIdx, pAdapter->StaCfg.DefaultKeyId));
1472
1473             //Using default key
1474                         keyIdx = pAdapter->StaCfg.DefaultKeyId;
1475         }
1476 #ifdef RT30xx
1477                 else
1478                 {
1479                         pAdapter->StaCfg.DefaultKeyId=keyIdx;
1480                 }
1481 #endif
1482
1483         NdisZeroMemory(pAdapter->SharedKey[BSS0][keyIdx].Key,  16);
1484
1485                 if (erq->length == MAX_WEP_KEY_SIZE)
1486         {
1487                         pAdapter->SharedKey[BSS0][keyIdx].KeyLen = MAX_WEP_KEY_SIZE;
1488             pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = CIPHER_WEP128;
1489                 }
1490                 else if (erq->length == MIN_WEP_KEY_SIZE)
1491         {
1492             pAdapter->SharedKey[BSS0][keyIdx].KeyLen = MIN_WEP_KEY_SIZE;
1493             pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = CIPHER_WEP64;
1494                 }
1495                 else
1496                         /* Disable the key */
1497                         pAdapter->SharedKey[BSS0][keyIdx].KeyLen = 0;
1498
1499                 /* Check if the key is not marked as invalid */
1500                 if(!(erq->flags & IW_ENCODE_NOKEY)) {
1501                         /* Copy the key in the driver */
1502                         NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].Key, extra, erq->length);
1503         }
1504         }
1505     else
1506                         {
1507                 /* Do we want to just set the transmit key index ? */
1508                 int index = (erq->flags & IW_ENCODE_INDEX) - 1;
1509                 if ((index >= 0) && (index < 4))
1510         {
1511                         pAdapter->StaCfg.DefaultKeyId = index;
1512             }
1513         else
1514                         /* Don't complain if only change the mode */
1515                         if (!(erq->flags & IW_ENCODE_MODE)) {
1516                                 return -EINVAL;
1517                 }
1518         }
1519
1520 done:
1521     DBGPRINT(RT_DEBUG_TRACE ,("==>rt_ioctl_siwencode::erq->flags=%x\n",erq->flags));
1522         DBGPRINT(RT_DEBUG_TRACE ,("==>rt_ioctl_siwencode::AuthMode=%x\n",pAdapter->StaCfg.AuthMode));
1523         DBGPRINT(RT_DEBUG_TRACE ,("==>rt_ioctl_siwencode::DefaultKeyId=%x, KeyLen = %d\n",pAdapter->StaCfg.DefaultKeyId , pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].KeyLen));
1524         DBGPRINT(RT_DEBUG_TRACE ,("==>rt_ioctl_siwencode::WepStatus=%x\n",pAdapter->StaCfg.WepStatus));
1525         return 0;
1526 }
1527
1528 int
1529 rt_ioctl_giwencode(struct net_device *dev,
1530                           struct iw_request_info *info,
1531                           struct iw_point *erq, char *key)
1532 {
1533         PRTMP_ADAPTER pAdapter = dev->ml_priv;
1534         int kid;
1535
1536         //check if the interface is down
1537         if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
1538         {
1539                 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
1540         return -ENETDOWN;
1541         }
1542
1543         kid = erq->flags & IW_ENCODE_INDEX;
1544         DBGPRINT(RT_DEBUG_TRACE, ("===>rt_ioctl_giwencode %d\n", erq->flags & IW_ENCODE_INDEX));
1545
1546         if (pAdapter->StaCfg.WepStatus == Ndis802_11WEPDisabled)
1547         {
1548                 erq->length = 0;
1549                 erq->flags = IW_ENCODE_DISABLED;
1550         }
1551         else if ((kid > 0) && (kid <=4))
1552         {
1553                 // copy wep key
1554                 erq->flags = kid ;                      /* NB: base 1 */
1555                 if (erq->length > pAdapter->SharedKey[BSS0][kid-1].KeyLen)
1556                         erq->length = pAdapter->SharedKey[BSS0][kid-1].KeyLen;
1557                 memcpy(key, pAdapter->SharedKey[BSS0][kid-1].Key, erq->length);
1558                 //if ((kid == pAdapter->PortCfg.DefaultKeyId))
1559                 //erq->flags |= IW_ENCODE_ENABLED;      /* XXX */
1560                 if (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeShared)
1561                         erq->flags |= IW_ENCODE_RESTRICTED;             /* XXX */
1562                 else
1563                         erq->flags |= IW_ENCODE_OPEN;           /* XXX */
1564
1565         }
1566         else if (kid == 0)
1567         {
1568                 if (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeShared)
1569                         erq->flags |= IW_ENCODE_RESTRICTED;             /* XXX */
1570                 else
1571                         erq->flags |= IW_ENCODE_OPEN;           /* XXX */
1572                 erq->length = pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].KeyLen;
1573                 memcpy(key, pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].Key, erq->length);
1574                 // copy default key ID
1575                 if (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeShared)
1576                         erq->flags |= IW_ENCODE_RESTRICTED;             /* XXX */
1577                 else
1578                         erq->flags |= IW_ENCODE_OPEN;           /* XXX */
1579                 erq->flags = pAdapter->StaCfg.DefaultKeyId + 1;                 /* NB: base 1 */
1580                 erq->flags |= IW_ENCODE_ENABLED;        /* XXX */
1581         }
1582
1583         return 0;
1584
1585 }
1586
1587 static int
1588 rt_ioctl_setparam(struct net_device *dev, struct iw_request_info *info,
1589                          void *w, char *extra)
1590 {
1591         PRTMP_ADAPTER pAdapter = dev->ml_priv;
1592         POS_COOKIE pObj = (POS_COOKIE)pAdapter->OS_Cookie;
1593         char *this_char = extra;
1594         char *value;
1595         int  Status=0;
1596
1597         {
1598                 pObj->ioctl_if_type = INT_MAIN;
1599         pObj->ioctl_if = MAIN_MBSSID;
1600         }
1601
1602         //check if the interface is down
1603         if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
1604         {
1605                 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
1606                         return -ENETDOWN;
1607         }
1608
1609         if (!*this_char)
1610                 return -EINVAL;
1611
1612         if ((value = rtstrchr(this_char, '=')) != NULL)
1613             *value++ = 0;
1614
1615         if (!value)
1616             return -EINVAL;
1617
1618         // reject setting nothing besides ANY ssid(ssidLen=0)
1619     if (!*value && (strcmp(this_char, "SSID") != 0))
1620         return -EINVAL;
1621
1622         for (PRTMP_PRIVATE_SET_PROC = RTMP_PRIVATE_SUPPORT_PROC; PRTMP_PRIVATE_SET_PROC->name; PRTMP_PRIVATE_SET_PROC++)
1623         {
1624             if (strcmp(this_char, PRTMP_PRIVATE_SET_PROC->name) == 0)
1625             {
1626                 if(!PRTMP_PRIVATE_SET_PROC->set_proc(pAdapter, value))
1627                 {       //FALSE:Set private failed then return Invalid argument
1628                             Status = -EINVAL;
1629                 }
1630                     break;      //Exit for loop.
1631             }
1632         }
1633
1634         if(PRTMP_PRIVATE_SET_PROC->name == NULL)
1635         {  //Not found argument
1636             Status = -EINVAL;
1637             DBGPRINT(RT_DEBUG_TRACE, ("===>rt_ioctl_setparam:: (iwpriv) Not Support Set Command [%s=%s]\n", this_char, value));
1638         }
1639
1640     return Status;
1641 }
1642
1643
1644 static int
1645 rt_private_get_statistics(struct net_device *dev, struct iw_request_info *info,
1646                 struct iw_point *wrq, char *extra)
1647 {
1648         INT                             Status = 0;
1649     PRTMP_ADAPTER   pAd = dev->ml_priv;
1650
1651     if (extra == NULL)
1652     {
1653         wrq->length = 0;
1654         return -EIO;
1655     }
1656
1657     memset(extra, 0x00, IW_PRIV_SIZE_MASK);
1658     sprintf(extra, "\n\n");
1659
1660         {
1661     sprintf(extra+strlen(extra), "Tx success                      = %ld\n", (ULONG)pAd->WlanCounters.TransmittedFragmentCount.QuadPart);
1662     sprintf(extra+strlen(extra), "Tx success without retry        = %ld\n", (ULONG)pAd->WlanCounters.TransmittedFragmentCount.QuadPart - (ULONG)pAd->WlanCounters.RetryCount.QuadPart);
1663         }
1664     sprintf(extra+strlen(extra), "Tx success after retry          = %ld\n", (ULONG)pAd->WlanCounters.RetryCount.QuadPart);
1665     sprintf(extra+strlen(extra), "Tx fail to Rcv ACK after retry  = %ld\n", (ULONG)pAd->WlanCounters.FailedCount.QuadPart);
1666     sprintf(extra+strlen(extra), "RTS Success Rcv CTS             = %ld\n", (ULONG)pAd->WlanCounters.RTSSuccessCount.QuadPart);
1667     sprintf(extra+strlen(extra), "RTS Fail Rcv CTS                = %ld\n", (ULONG)pAd->WlanCounters.RTSFailureCount.QuadPart);
1668
1669     sprintf(extra+strlen(extra), "Rx success                      = %ld\n", (ULONG)pAd->WlanCounters.ReceivedFragmentCount.QuadPart);
1670     sprintf(extra+strlen(extra), "Rx with CRC                     = %ld\n", (ULONG)pAd->WlanCounters.FCSErrorCount.QuadPart);
1671     sprintf(extra+strlen(extra), "Rx drop due to out of resource  = %ld\n", (ULONG)pAd->Counters8023.RxNoBuffer);
1672     sprintf(extra+strlen(extra), "Rx duplicate frame              = %ld\n", (ULONG)pAd->WlanCounters.FrameDuplicateCount.QuadPart);
1673
1674     sprintf(extra+strlen(extra), "False CCA (one second)          = %ld\n", (ULONG)pAd->RalinkCounters.OneSecFalseCCACnt);
1675         {
1676         sprintf(extra+strlen(extra), "RSSI-A                          = %ld\n", (LONG)(pAd->StaCfg.RssiSample.LastRssi0 - pAd->BbpRssiToDbmDelta));
1677         sprintf(extra+strlen(extra), "RSSI-B (if available)           = %ld\n", (LONG)(pAd->StaCfg.RssiSample.LastRssi1 - pAd->BbpRssiToDbmDelta));
1678         sprintf(extra+strlen(extra), "RSSI-C (if available)           = %ld\n\n", (LONG)(pAd->StaCfg.RssiSample.LastRssi2 - pAd->BbpRssiToDbmDelta));
1679         }
1680     sprintf(extra+strlen(extra), "WpaSupplicantUP                 = %d\n\n", pAd->StaCfg.WpaSupplicantUP);
1681
1682     wrq->length = strlen(extra) + 1; // 1: size of '\0'
1683     DBGPRINT(RT_DEBUG_TRACE, ("<== rt_private_get_statistics, wrq->length = %d\n", wrq->length));
1684
1685     return Status;
1686 }
1687
1688 void    getBaInfo(
1689         IN      PRTMP_ADAPTER   pAd,
1690         IN      PUCHAR                  pOutBuf)
1691 {
1692         INT i, j;
1693         BA_ORI_ENTRY *pOriBAEntry;
1694         BA_REC_ENTRY *pRecBAEntry;
1695
1696         for (i=0; i<MAX_LEN_OF_MAC_TABLE; i++)
1697         {
1698                 PMAC_TABLE_ENTRY pEntry = &pAd->MacTab.Content[i];
1699                 if (((pEntry->ValidAsCLI || pEntry->ValidAsApCli) && (pEntry->Sst == SST_ASSOC))
1700                         || (pEntry->ValidAsWDS) || (pEntry->ValidAsMesh))
1701                 {
1702                         sprintf(pOutBuf + strlen(pOutBuf), "\n%02X:%02X:%02X:%02X:%02X:%02X (Aid = %d) (AP) -\n",
1703                                 pEntry->Addr[0], pEntry->Addr[1], pEntry->Addr[2],
1704                                 pEntry->Addr[3], pEntry->Addr[4], pEntry->Addr[5], pEntry->Aid);
1705
1706                         sprintf(pOutBuf, "%s[Recipient]\n", pOutBuf);
1707                         for (j=0; j < NUM_OF_TID; j++)
1708                         {
1709                                 if (pEntry->BARecWcidArray[j] != 0)
1710                                 {
1711                                         pRecBAEntry =&pAd->BATable.BARecEntry[pEntry->BARecWcidArray[j]];
1712                                         sprintf(pOutBuf + strlen(pOutBuf), "TID=%d, BAWinSize=%d, LastIndSeq=%d, ReorderingPkts=%d\n", j, pRecBAEntry->BAWinSize, pRecBAEntry->LastIndSeq, pRecBAEntry->list.qlen);
1713                                 }
1714                         }
1715                         sprintf(pOutBuf, "%s\n", pOutBuf);
1716
1717                         sprintf(pOutBuf, "%s[Originator]\n", pOutBuf);
1718                         for (j=0; j < NUM_OF_TID; j++)
1719                         {
1720                                 if (pEntry->BAOriWcidArray[j] != 0)
1721                                 {
1722                                         pOriBAEntry =&pAd->BATable.BAOriEntry[pEntry->BAOriWcidArray[j]];
1723                                         sprintf(pOutBuf + strlen(pOutBuf), "TID=%d, BAWinSize=%d, StartSeq=%d, CurTxSeq=%d\n", j, pOriBAEntry->BAWinSize, pOriBAEntry->Sequence, pEntry->TxSeq[j]);
1724                                 }
1725                         }
1726                         sprintf(pOutBuf, "%s\n\n", pOutBuf);
1727                 }
1728         if (strlen(pOutBuf) > (IW_PRIV_SIZE_MASK - 30))
1729                 break;
1730         }
1731
1732         return;
1733 }
1734
1735 static int
1736 rt_private_show(struct net_device *dev, struct iw_request_info *info,
1737                 struct iw_point *wrq, char *extra)
1738 {
1739     INT                         Status = 0;
1740     PRTMP_ADAPTER pAd = dev->ml_priv;
1741     POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
1742     u32             subcmd = wrq->flags;
1743
1744     if (extra == NULL)
1745     {
1746         wrq->length = 0;
1747         return -EIO;
1748     }
1749     memset(extra, 0x00, IW_PRIV_SIZE_MASK);
1750
1751         {
1752                 pObj->ioctl_if_type = INT_MAIN;
1753         pObj->ioctl_if = MAIN_MBSSID;
1754         }
1755
1756     switch(subcmd)
1757     {
1758
1759         case SHOW_CONN_STATUS:
1760             if (MONITOR_ON(pAd))
1761             {
1762                 if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED &&
1763                     pAd->CommonCfg.RegTransmitSetting.field.BW)
1764                     sprintf(extra, "Monitor Mode(CentralChannel %d)\n", pAd->CommonCfg.CentralChannel);
1765                 else
1766                     sprintf(extra, "Monitor Mode(Channel %d)\n", pAd->CommonCfg.Channel);
1767             }
1768             else
1769             {
1770                 if (pAd->IndicateMediaState == NdisMediaStateConnected)
1771                 {
1772                     if (INFRA_ON(pAd))
1773                     {
1774                     sprintf(extra, "Connected(AP: %s[%02X:%02X:%02X:%02X:%02X:%02X])\n",
1775                                     pAd->CommonCfg.Ssid,
1776                                     pAd->CommonCfg.Bssid[0],
1777                                     pAd->CommonCfg.Bssid[1],
1778                                     pAd->CommonCfg.Bssid[2],
1779                                     pAd->CommonCfg.Bssid[3],
1780                                     pAd->CommonCfg.Bssid[4],
1781                                     pAd->CommonCfg.Bssid[5]);
1782                         DBGPRINT(RT_DEBUG_TRACE ,("Ssid=%s ,Ssidlen = %d\n",pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen));
1783                 }
1784                     else if (ADHOC_ON(pAd))
1785                         sprintf(extra, "Connected\n");
1786                 }
1787                 else
1788                 {
1789                     sprintf(extra, "Disconnected\n");
1790                         DBGPRINT(RT_DEBUG_TRACE ,("ConnStatus is not connected\n"));
1791                 }
1792             }
1793             wrq->length = strlen(extra) + 1; // 1: size of '\0'
1794             break;
1795         case SHOW_DRVIER_VERION:
1796             sprintf(extra, "Driver version-%s, %s %s\n", STA_DRIVER_VERSION, __DATE__, __TIME__ );
1797             wrq->length = strlen(extra) + 1; // 1: size of '\0'
1798             break;
1799         case SHOW_BA_INFO:
1800             getBaInfo(pAd, extra);
1801             wrq->length = strlen(extra) + 1; // 1: size of '\0'
1802             break;
1803                 case SHOW_DESC_INFO:
1804                         {
1805                                 Show_DescInfo_Proc(pAd, NULL);
1806                                 wrq->length = 0; // 1: size of '\0'
1807                         }
1808                         break;
1809         case RAIO_OFF:
1810             if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
1811             {
1812                 sprintf(extra, "Scanning\n");
1813                 wrq->length = strlen(extra) + 1; // 1: size of '\0'
1814                 break;
1815             }
1816             pAd->StaCfg.bSwRadio = FALSE;
1817             if (pAd->StaCfg.bRadio != (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio))
1818             {
1819                 pAd->StaCfg.bRadio = (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio);
1820                 if (pAd->StaCfg.bRadio == FALSE)
1821                 {
1822                     MlmeRadioOff(pAd);
1823                     // Update extra information
1824                                         pAd->ExtraInfo = SW_RADIO_OFF;
1825                 }
1826             }
1827             sprintf(extra, "Radio Off\n");
1828             wrq->length = strlen(extra) + 1; // 1: size of '\0'
1829             break;
1830         case RAIO_ON:
1831 #ifdef RT2870
1832             if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
1833             {
1834                 sprintf(extra, "Scanning\n");
1835                 wrq->length = strlen(extra) + 1; // 1: size of '\0'
1836                 break;
1837             }
1838 #endif
1839             pAd->StaCfg.bSwRadio = TRUE;
1840             //if (pAd->StaCfg.bRadio != (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio))
1841             {
1842                 pAd->StaCfg.bRadio = (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio);
1843                 if (pAd->StaCfg.bRadio == TRUE)
1844                 {
1845                     MlmeRadioOn(pAd);
1846                     // Update extra information
1847                                         pAd->ExtraInfo = EXTRA_INFO_CLEAR;
1848                 }
1849             }
1850             sprintf(extra, "Radio On\n");
1851             wrq->length = strlen(extra) + 1; // 1: size of '\0'
1852             break;
1853
1854                 case SHOW_CFG_VALUE:
1855                         {
1856                                 Status = RTMPShowCfgValue(pAd, wrq->pointer, extra);
1857                                 if (Status == 0)
1858                                         wrq->length = strlen(extra) + 1; // 1: size of '\0'
1859                         }
1860                         break;
1861 #if !defined(RT2860) && !defined(RT30xx)
1862                 case SHOW_ADHOC_ENTRY_INFO:
1863                         Show_Adhoc_MacTable_Proc(pAd, extra);
1864                         wrq->length = strlen(extra) + 1; // 1: size of '\0'
1865                         break;
1866 #endif
1867         default:
1868             DBGPRINT(RT_DEBUG_TRACE, ("%s - unknow subcmd = %d\n", __func__, subcmd));
1869             break;
1870     }
1871
1872     return Status;
1873 }
1874
1875 int rt_ioctl_siwmlme(struct net_device *dev,
1876                            struct iw_request_info *info,
1877                            union iwreq_data *wrqu,
1878                            char *extra)
1879 {
1880         PRTMP_ADAPTER   pAd = dev->ml_priv;
1881         struct iw_mlme *pMlme = (struct iw_mlme *)wrqu->data.pointer;
1882         MLME_QUEUE_ELEM                         MsgElem;
1883         MLME_DISASSOC_REQ_STRUCT        DisAssocReq;
1884         MLME_DEAUTH_REQ_STRUCT      DeAuthReq;
1885
1886         DBGPRINT(RT_DEBUG_TRACE, ("====> %s\n", __func__));
1887
1888         if (pMlme == NULL)
1889                 return -EINVAL;
1890
1891         switch(pMlme->cmd)
1892         {
1893 #ifdef IW_MLME_DEAUTH
1894                 case IW_MLME_DEAUTH:
1895                         DBGPRINT(RT_DEBUG_TRACE, ("====> %s - IW_MLME_DEAUTH\n", __func__));
1896                         COPY_MAC_ADDR(DeAuthReq.Addr, pAd->CommonCfg.Bssid);
1897                         DeAuthReq.Reason = pMlme->reason_code;
1898                         MsgElem.MsgLen = sizeof(MLME_DEAUTH_REQ_STRUCT);
1899                         NdisMoveMemory(MsgElem.Msg, &DeAuthReq, sizeof(MLME_DEAUTH_REQ_STRUCT));
1900                         MlmeDeauthReqAction(pAd, &MsgElem);
1901                         if (INFRA_ON(pAd))
1902                         {
1903                             LinkDown(pAd, FALSE);
1904                             pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
1905                         }
1906                         break;
1907 #endif // IW_MLME_DEAUTH //
1908 #ifdef IW_MLME_DISASSOC
1909                 case IW_MLME_DISASSOC:
1910                         DBGPRINT(RT_DEBUG_TRACE, ("====> %s - IW_MLME_DISASSOC\n", __func__));
1911                         COPY_MAC_ADDR(DisAssocReq.Addr, pAd->CommonCfg.Bssid);
1912                         DisAssocReq.Reason =  pMlme->reason_code;
1913
1914                         MsgElem.Machine = ASSOC_STATE_MACHINE;
1915                         MsgElem.MsgType = MT2_MLME_DISASSOC_REQ;
1916                         MsgElem.MsgLen = sizeof(MLME_DISASSOC_REQ_STRUCT);
1917                         NdisMoveMemory(MsgElem.Msg, &DisAssocReq, sizeof(MLME_DISASSOC_REQ_STRUCT));
1918
1919                         pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_DISASSOC;
1920                         MlmeDisassocReqAction(pAd, &MsgElem);
1921                         break;
1922 #endif // IW_MLME_DISASSOC //
1923                 default:
1924                         DBGPRINT(RT_DEBUG_TRACE, ("====> %s - Unknow Command\n", __func__));
1925                         break;
1926         }
1927
1928         return 0;
1929 }
1930
1931 int rt_ioctl_siwauth(struct net_device *dev,
1932                           struct iw_request_info *info,
1933                           union iwreq_data *wrqu, char *extra)
1934 {
1935         PRTMP_ADAPTER   pAdapter = dev->ml_priv;
1936         struct iw_param *param = &wrqu->param;
1937
1938     //check if the interface is down
1939         if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
1940         {
1941                 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
1942         return -ENETDOWN;
1943         }
1944         switch (param->flags & IW_AUTH_INDEX) {
1945         case IW_AUTH_WPA_VERSION:
1946             if (param->value == IW_AUTH_WPA_VERSION_WPA)
1947             {
1948                 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPAPSK;
1949                                 if (pAdapter->StaCfg.BssType == BSS_ADHOC)
1950                                         pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPANone;
1951             }
1952             else if (param->value == IW_AUTH_WPA_VERSION_WPA2)
1953                 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPA2PSK;
1954
1955             DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_WPA_VERSION - param->value = %d!\n", __func__, param->value));
1956             break;
1957         case IW_AUTH_CIPHER_PAIRWISE:
1958             if (param->value == IW_AUTH_CIPHER_NONE)
1959             {
1960                 pAdapter->StaCfg.WepStatus = Ndis802_11WEPDisabled;
1961                 pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
1962                 pAdapter->StaCfg.PairCipher = Ndis802_11WEPDisabled;
1963             }
1964             else if (param->value == IW_AUTH_CIPHER_WEP40 ||
1965                      param->value == IW_AUTH_CIPHER_WEP104)
1966             {
1967                 pAdapter->StaCfg.WepStatus = Ndis802_11WEPEnabled;
1968                 pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
1969                 pAdapter->StaCfg.PairCipher = Ndis802_11WEPEnabled;
1970                 pAdapter->StaCfg.IEEE8021X = FALSE;
1971             }
1972             else if (param->value == IW_AUTH_CIPHER_TKIP)
1973             {
1974                 pAdapter->StaCfg.WepStatus = Ndis802_11Encryption2Enabled;
1975                 pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
1976                 pAdapter->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
1977             }
1978             else if (param->value == IW_AUTH_CIPHER_CCMP)
1979             {
1980                 pAdapter->StaCfg.WepStatus = Ndis802_11Encryption3Enabled;
1981                 pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
1982                 pAdapter->StaCfg.PairCipher = Ndis802_11Encryption3Enabled;
1983             }
1984             DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_CIPHER_PAIRWISE - param->value = %d!\n", __func__, param->value));
1985             break;
1986         case IW_AUTH_CIPHER_GROUP:
1987             if (param->value == IW_AUTH_CIPHER_NONE)
1988             {
1989                 pAdapter->StaCfg.GroupCipher = Ndis802_11WEPDisabled;
1990             }
1991             else if (param->value == IW_AUTH_CIPHER_WEP40 ||
1992                      param->value == IW_AUTH_CIPHER_WEP104)
1993             {
1994                 pAdapter->StaCfg.GroupCipher = Ndis802_11WEPEnabled;
1995             }
1996             else if (param->value == IW_AUTH_CIPHER_TKIP)
1997             {
1998                 pAdapter->StaCfg.GroupCipher = Ndis802_11Encryption2Enabled;
1999             }
2000             else if (param->value == IW_AUTH_CIPHER_CCMP)
2001             {
2002                 pAdapter->StaCfg.GroupCipher = Ndis802_11Encryption3Enabled;
2003             }
2004             DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_CIPHER_GROUP - param->value = %d!\n", __func__, param->value));
2005             break;
2006         case IW_AUTH_KEY_MGMT:
2007             if (param->value == IW_AUTH_KEY_MGMT_802_1X)
2008             {
2009                 if (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK)
2010                 {
2011                     pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPA;
2012                     pAdapter->StaCfg.IEEE8021X = FALSE;
2013                 }
2014                 else if (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)
2015                 {
2016                     pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPA2;
2017                     pAdapter->StaCfg.IEEE8021X = FALSE;
2018                 }
2019                 else
2020                     // WEP 1x
2021                     pAdapter->StaCfg.IEEE8021X = TRUE;
2022             }
2023             else if (param->value == 0)
2024             {
2025                                 STA_PORT_SECURED(pAdapter);
2026             }
2027             DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_KEY_MGMT - param->value = %d!\n", __func__, param->value));
2028             break;
2029         case IW_AUTH_RX_UNENCRYPTED_EAPOL:
2030             break;
2031         case IW_AUTH_PRIVACY_INVOKED:
2032             DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_PRIVACY_INVOKED - param->value = %d!\n", __func__, param->value));
2033                 break;
2034         case IW_AUTH_DROP_UNENCRYPTED:
2035             if (param->value != 0)
2036                 pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
2037                         else
2038                         {
2039                                 STA_PORT_SECURED(pAdapter);
2040                         }
2041             DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_WPA_VERSION - param->value = %d!\n", __func__, param->value));
2042                 break;
2043         case IW_AUTH_80211_AUTH_ALG:
2044                         if (param->value & IW_AUTH_ALG_SHARED_KEY)
2045             {
2046                                 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeShared;
2047                         }
2048             else if (param->value & IW_AUTH_ALG_OPEN_SYSTEM)
2049             {
2050                                 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
2051                         }
2052             else
2053                                 return -EINVAL;
2054             DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_80211_AUTH_ALG - param->value = %d!\n", __func__, param->value));
2055                         break;
2056         case IW_AUTH_WPA_ENABLED:
2057                 DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_WPA_ENABLED - Driver supports WPA!(param->value = %d)\n", __func__, param->value));
2058                 break;
2059         default:
2060                 return -EOPNOTSUPP;
2061 }
2062
2063         return 0;
2064 }
2065
2066 int rt_ioctl_giwauth(struct net_device *dev,
2067                                struct iw_request_info *info,
2068                                union iwreq_data *wrqu, char *extra)
2069 {
2070         PRTMP_ADAPTER   pAdapter = dev->ml_priv;
2071         struct iw_param *param = &wrqu->param;
2072
2073     //check if the interface is down
2074         if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
2075     {
2076                 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
2077         return -ENETDOWN;
2078     }
2079
2080         switch (param->flags & IW_AUTH_INDEX) {
2081         case IW_AUTH_DROP_UNENCRYPTED:
2082         param->value = (pAdapter->StaCfg.WepStatus == Ndis802_11WEPDisabled) ? 0 : 1;
2083                 break;
2084
2085         case IW_AUTH_80211_AUTH_ALG:
2086         param->value = (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeShared) ? IW_AUTH_ALG_SHARED_KEY : IW_AUTH_ALG_OPEN_SYSTEM;
2087                 break;
2088
2089         case IW_AUTH_WPA_ENABLED:
2090                 param->value = (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA) ? 1 : 0;
2091                 break;
2092
2093         default:
2094                 return -EOPNOTSUPP;
2095         }
2096     DBGPRINT(RT_DEBUG_TRACE, ("rt_ioctl_giwauth::param->value = %d!\n", param->value));
2097         return 0;
2098 }
2099
2100 void fnSetCipherKey(
2101     IN  PRTMP_ADAPTER   pAdapter,
2102     IN  INT             keyIdx,
2103     IN  UCHAR           CipherAlg,
2104     IN  BOOLEAN         bGTK,
2105     IN  struct iw_encode_ext *ext)
2106 {
2107 #ifdef RT2860
2108         RTMP_CLEAR_PSFLAG(pAdapter, fRTMP_PS_CAN_GO_SLEEP);
2109         if (RTMP_TEST_PSFLAG(pAdapter, fRTMP_PS_SET_PCI_CLK_OFF_COMMAND))
2110         {
2111                 if (pAdapter->StaCfg.bRadio == FALSE)
2112                 {
2113                         RTMP_SET_PSFLAG(pAdapter, fRTMP_PS_CAN_GO_SLEEP);
2114                         return;
2115                 }
2116                 DBGPRINT(RT_DEBUG_TRACE,("RTMPWPAAddKeyProc1==>\n"));
2117                 RTMPPCIeLinkCtrlValueRestore(pAdapter, RESTORE_HALT);
2118                 RTMPusecDelay(6000);
2119                 pAdapter->bPCIclkOff = FALSE;
2120         }
2121 #endif
2122     NdisZeroMemory(&pAdapter->SharedKey[BSS0][keyIdx], sizeof(CIPHER_KEY));
2123     pAdapter->SharedKey[BSS0][keyIdx].KeyLen = LEN_TKIP_EK;
2124     NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].Key, ext->key, LEN_TKIP_EK);
2125     NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].TxMic, ext->key + LEN_TKIP_EK, LEN_TKIP_TXMICK);
2126     NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].RxMic, ext->key + LEN_TKIP_EK + LEN_TKIP_TXMICK, LEN_TKIP_RXMICK);
2127     pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = CipherAlg;
2128
2129     // Update group key information to ASIC Shared Key Table
2130         AsicAddSharedKeyEntry(pAdapter,
2131                                                   BSS0,
2132                                                   keyIdx,
2133                                                   pAdapter->SharedKey[BSS0][keyIdx].CipherAlg,
2134                                                   pAdapter->SharedKey[BSS0][keyIdx].Key,
2135                                                   pAdapter->SharedKey[BSS0][keyIdx].TxMic,
2136                                                   pAdapter->SharedKey[BSS0][keyIdx].RxMic);
2137
2138     if (bGTK)
2139         // Update ASIC WCID attribute table and IVEIV table
2140         RTMPAddWcidAttributeEntry(pAdapter,
2141                                                           BSS0,
2142                                                           keyIdx,
2143                                                           pAdapter->SharedKey[BSS0][keyIdx].CipherAlg,
2144                                                           NULL);
2145     else
2146         // Update ASIC WCID attribute table and IVEIV table
2147         RTMPAddWcidAttributeEntry(pAdapter,
2148                                                           BSS0,
2149                                                           keyIdx,
2150                                                           pAdapter->SharedKey[BSS0][keyIdx].CipherAlg,
2151                                                           &pAdapter->MacTab.Content[BSSID_WCID]);
2152 #ifdef RT2860
2153         RTMP_SET_PSFLAG(pAdapter, fRTMP_PS_CAN_GO_SLEEP);
2154 #endif
2155 }
2156
2157 int rt_ioctl_siwencodeext(struct net_device *dev,
2158                            struct iw_request_info *info,
2159                            union iwreq_data *wrqu,
2160                            char *extra)
2161                         {
2162     PRTMP_ADAPTER   pAdapter = dev->ml_priv;
2163         struct iw_point *encoding = &wrqu->encoding;
2164         struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
2165     int keyIdx, alg = ext->alg;
2166
2167     //check if the interface is down
2168         if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
2169         {
2170                 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
2171         return -ENETDOWN;
2172         }
2173
2174     if (encoding->flags & IW_ENCODE_DISABLED)
2175         {
2176         keyIdx = (encoding->flags & IW_ENCODE_INDEX) - 1;
2177         // set BSSID wcid entry of the Pair-wise Key table as no-security mode
2178             AsicRemovePairwiseKeyEntry(pAdapter, BSS0, BSSID_WCID);
2179         pAdapter->SharedKey[BSS0][keyIdx].KeyLen = 0;
2180                 pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = CIPHER_NONE;
2181                 AsicRemoveSharedKeyEntry(pAdapter, 0, (UCHAR)keyIdx);
2182         NdisZeroMemory(&pAdapter->SharedKey[BSS0][keyIdx], sizeof(CIPHER_KEY));
2183         DBGPRINT(RT_DEBUG_TRACE, ("%s::Remove all keys!(encoding->flags = %x)\n", __func__, encoding->flags));
2184     }
2185                                         else
2186     {
2187         // Get Key Index and convet to our own defined key index
2188         keyIdx = (encoding->flags & IW_ENCODE_INDEX) - 1;
2189         if((keyIdx < 0) || (keyIdx >= NR_WEP_KEYS))
2190                 return -EINVAL;
2191
2192         if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
2193         {
2194             pAdapter->StaCfg.DefaultKeyId = keyIdx;
2195             DBGPRINT(RT_DEBUG_TRACE, ("%s::DefaultKeyId = %d\n", __func__, pAdapter->StaCfg.DefaultKeyId));
2196         }
2197
2198         switch (alg) {
2199                 case IW_ENCODE_ALG_NONE:
2200                 DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_ENCODE_ALG_NONE\n", __func__));
2201                         break;
2202                 case IW_ENCODE_ALG_WEP:
2203                 DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_ENCODE_ALG_WEP - ext->key_len = %d, keyIdx = %d\n", __func__, ext->key_len, keyIdx));
2204                         if (ext->key_len == MAX_WEP_KEY_SIZE)
2205                 {
2206                                 pAdapter->SharedKey[BSS0][keyIdx].KeyLen = MAX_WEP_KEY_SIZE;
2207                     pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = CIPHER_WEP128;
2208                                 }
2209                         else if (ext->key_len == MIN_WEP_KEY_SIZE)
2210                 {
2211                     pAdapter->SharedKey[BSS0][keyIdx].KeyLen = MIN_WEP_KEY_SIZE;
2212                     pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = CIPHER_WEP64;
2213                         }
2214                         else
2215                     return -EINVAL;
2216
2217                 NdisZeroMemory(pAdapter->SharedKey[BSS0][keyIdx].Key,  16);
2218                             NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].Key, ext->key, ext->key_len);
2219 #ifndef RT30xx
2220                                 if (pAdapter->StaCfg.GroupCipher == Ndis802_11GroupWEP40Enabled ||
2221                                         pAdapter->StaCfg.GroupCipher == Ndis802_11GroupWEP104Enabled)
2222                                 {
2223                                         // Set Group key material to Asic
2224                                         AsicAddSharedKeyEntry(pAdapter, BSS0, keyIdx, pAdapter->SharedKey[BSS0][keyIdx].CipherAlg, pAdapter->SharedKey[BSS0][keyIdx].Key, NULL, NULL);
2225
2226                                         // Update WCID attribute table and IVEIV table for this group key table
2227                                         RTMPAddWcidAttributeEntry(pAdapter, BSS0, keyIdx, pAdapter->SharedKey[BSS0][keyIdx].CipherAlg, NULL);
2228
2229                                         STA_PORT_SECURED(pAdapter);
2230
2231                                 // Indicate Connected for GUI
2232                                 pAdapter->IndicateMediaState = NdisMediaStateConnected;
2233                                 }
2234 #endif
2235                         break;
2236             case IW_ENCODE_ALG_TKIP:
2237                 DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_ENCODE_ALG_TKIP - keyIdx = %d, ext->key_len = %d\n", __func__, keyIdx, ext->key_len));
2238                 if (ext->key_len == 32)
2239                 {
2240                     if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
2241                     {
2242                         fnSetCipherKey(pAdapter, keyIdx, CIPHER_TKIP, FALSE, ext);
2243                         if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA2)
2244                         {
2245                             STA_PORT_SECURED(pAdapter);
2246                         }
2247                 }
2248                     else if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY)
2249                     {
2250                         fnSetCipherKey(pAdapter, keyIdx, CIPHER_TKIP, TRUE, ext);
2251
2252                         // set 802.1x port control
2253                         STA_PORT_SECURED(pAdapter);
2254                     }
2255                 }
2256                 else
2257                     return -EINVAL;
2258                 break;
2259             case IW_ENCODE_ALG_CCMP:
2260                 if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
2261                 {
2262                     fnSetCipherKey(pAdapter, keyIdx, CIPHER_AES, FALSE, ext);
2263                     if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA2)
2264                         STA_PORT_SECURED(pAdapter);
2265                 }
2266                 else if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY)
2267                 {
2268                     fnSetCipherKey(pAdapter, keyIdx, CIPHER_AES, TRUE, ext);
2269
2270                     // set 802.1x port control
2271                         STA_PORT_SECURED(pAdapter);
2272                 }
2273                 break;
2274                 default:
2275                         return -EINVAL;
2276                 }
2277     }
2278
2279     return 0;
2280 }
2281
2282 int
2283 rt_ioctl_giwencodeext(struct net_device *dev,
2284                           struct iw_request_info *info,
2285                           union iwreq_data *wrqu, char *extra)
2286 {
2287         PRTMP_ADAPTER pAd = dev->ml_priv;
2288         PCHAR pKey = NULL;
2289         struct iw_point *encoding = &wrqu->encoding;
2290         struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
2291         int idx, max_key_len;
2292
2293         DBGPRINT(RT_DEBUG_TRACE ,("===> rt_ioctl_giwencodeext\n"));
2294
2295         max_key_len = encoding->length - sizeof(*ext);
2296         if (max_key_len < 0)
2297                 return -EINVAL;
2298
2299         idx = encoding->flags & IW_ENCODE_INDEX;
2300         if (idx)
2301         {
2302                 if (idx < 1 || idx > 4)
2303                         return -EINVAL;
2304                 idx--;
2305
2306                 if ((pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) ||
2307                         (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled))
2308                 {
2309                         if (idx != pAd->StaCfg.DefaultKeyId)
2310                         {
2311                                 ext->key_len = 0;
2312                                 return 0;
2313                         }
2314                 }
2315         }
2316         else
2317                 idx = pAd->StaCfg.DefaultKeyId;
2318
2319         encoding->flags = idx + 1;
2320         memset(ext, 0, sizeof(*ext));
2321
2322         ext->key_len = 0;
2323         switch(pAd->StaCfg.WepStatus) {
2324                 case Ndis802_11WEPDisabled:
2325                         ext->alg = IW_ENCODE_ALG_NONE;
2326                         encoding->flags |= IW_ENCODE_DISABLED;
2327                         break;
2328                 case Ndis802_11WEPEnabled:
2329                         ext->alg = IW_ENCODE_ALG_WEP;
2330                         if (pAd->SharedKey[BSS0][idx].KeyLen > max_key_len)
2331                                 return -E2BIG;
2332                         else
2333                         {
2334                                 ext->key_len = pAd->SharedKey[BSS0][idx].KeyLen;
2335                                 pKey = &(pAd->SharedKey[BSS0][idx].Key[0]);
2336                         }
2337                         break;
2338                 case Ndis802_11Encryption2Enabled:
2339                 case Ndis802_11Encryption3Enabled:
2340                         if (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled)
2341                                 ext->alg = IW_ENCODE_ALG_TKIP;
2342                         else
2343                                 ext->alg = IW_ENCODE_ALG_CCMP;
2344
2345                         if (max_key_len < 32)
2346                                 return -E2BIG;
2347                         else
2348                         {
2349                                 ext->key_len = 32;
2350                                 pKey = &pAd->StaCfg.PMK[0];
2351                         }
2352                         break;
2353                 default:
2354                         return -EINVAL;
2355         }
2356
2357         if (ext->key_len && pKey)
2358         {
2359                 encoding->flags |= IW_ENCODE_ENABLED;
2360                 memcpy(ext->key, pKey, ext->key_len);
2361         }
2362
2363         return 0;
2364 }
2365
2366 int rt_ioctl_siwgenie(struct net_device *dev,
2367                           struct iw_request_info *info,
2368                           union iwreq_data *wrqu, char *extra)
2369 {
2370         PRTMP_ADAPTER   pAd = dev->ml_priv;
2371
2372         if (wrqu->data.length > MAX_LEN_OF_RSNIE ||
2373             (wrqu->data.length && extra == NULL))
2374                 return -EINVAL;
2375
2376         if (wrqu->data.length)
2377         {
2378                 pAd->StaCfg.RSNIE_Len = wrqu->data.length;
2379                 NdisMoveMemory(&pAd->StaCfg.RSN_IE[0], extra, pAd->StaCfg.RSNIE_Len);
2380         }
2381         else
2382         {
2383                 pAd->StaCfg.RSNIE_Len = 0;
2384                 NdisZeroMemory(&pAd->StaCfg.RSN_IE[0], MAX_LEN_OF_RSNIE);
2385         }
2386
2387         return 0;
2388 }
2389
2390 int rt_ioctl_giwgenie(struct net_device *dev,
2391                                struct iw_request_info *info,
2392                                union iwreq_data *wrqu, char *extra)
2393 {
2394         PRTMP_ADAPTER   pAd = dev->ml_priv;
2395
2396         if ((pAd->StaCfg.RSNIE_Len == 0) ||
2397                 (pAd->StaCfg.AuthMode < Ndis802_11AuthModeWPA))
2398         {
2399                 wrqu->data.length = 0;
2400                 return 0;
2401         }
2402
2403         if (pAd->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_ENABLE)
2404         {
2405         if (wrqu->data.length < pAd->StaCfg.RSNIE_Len)
2406                 return -E2BIG;
2407
2408         wrqu->data.length = pAd->StaCfg.RSNIE_Len;
2409         memcpy(extra, &pAd->StaCfg.RSN_IE[0], pAd->StaCfg.RSNIE_Len);
2410         }
2411         else
2412         {
2413                 UCHAR RSNIe = IE_WPA;
2414
2415                 if (wrqu->data.length < (pAd->StaCfg.RSNIE_Len + 2)) // ID, Len
2416                         return -E2BIG;
2417                 wrqu->data.length = pAd->StaCfg.RSNIE_Len + 2;
2418
2419                 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK) ||
2420             (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2))
2421                         RSNIe = IE_RSN;
2422
2423                 extra[0] = (char)RSNIe;
2424                 extra[1] = pAd->StaCfg.RSNIE_Len;
2425                 memcpy(extra+2, &pAd->StaCfg.RSN_IE[0], pAd->StaCfg.RSNIE_Len);
2426         }
2427
2428         return 0;
2429 }
2430
2431 int rt_ioctl_siwpmksa(struct net_device *dev,
2432                            struct iw_request_info *info,
2433                            union iwreq_data *wrqu,
2434                            char *extra)
2435 {
2436         PRTMP_ADAPTER   pAd = dev->ml_priv;
2437         struct iw_pmksa *pPmksa = (struct iw_pmksa *)wrqu->data.pointer;
2438         INT     CachedIdx = 0, idx = 0;
2439
2440         if (pPmksa == NULL)
2441                 return -EINVAL;
2442
2443         DBGPRINT(RT_DEBUG_TRACE ,("===> rt_ioctl_siwpmksa\n"));
2444         switch(pPmksa->cmd)
2445         {
2446                 case IW_PMKSA_FLUSH:
2447                         NdisZeroMemory(pAd->StaCfg.SavedPMK, sizeof(BSSID_INFO)*PMKID_NO);
2448                         DBGPRINT(RT_DEBUG_TRACE ,("rt_ioctl_siwpmksa - IW_PMKSA_FLUSH\n"));
2449                         break;
2450                 case IW_PMKSA_REMOVE:
2451                         for (CachedIdx = 0; CachedIdx < pAd->StaCfg.SavedPMKNum; CachedIdx++)
2452                         {
2453                         // compare the BSSID
2454                         if (NdisEqualMemory(pPmksa->bssid.sa_data, pAd->StaCfg.SavedPMK[CachedIdx].BSSID, MAC_ADDR_LEN))
2455                         {
2456                                 NdisZeroMemory(pAd->StaCfg.SavedPMK[CachedIdx].BSSID, MAC_ADDR_LEN);
2457                                         NdisZeroMemory(pAd->StaCfg.SavedPMK[CachedIdx].PMKID, 16);
2458                                         for (idx = CachedIdx; idx < (pAd->StaCfg.SavedPMKNum - 1); idx++)
2459                                         {
2460                                                 NdisMoveMemory(&pAd->StaCfg.SavedPMK[idx].BSSID[0], &pAd->StaCfg.SavedPMK[idx+1].BSSID[0], MAC_ADDR_LEN);
2461                                                 NdisMoveMemory(&pAd->StaCfg.SavedPMK[idx].PMKID[0], &pAd->StaCfg.SavedPMK[idx+1].PMKID[0], 16);
2462                                         }
2463                                         pAd->StaCfg.SavedPMKNum--;
2464                                 break;
2465                         }
2466                 }
2467
2468                         DBGPRINT(RT_DEBUG_TRACE ,("rt_ioctl_siwpmksa - IW_PMKSA_REMOVE\n"));
2469                         break;
2470                 case IW_PMKSA_ADD:
2471                         for (CachedIdx = 0; CachedIdx < pAd->StaCfg.SavedPMKNum; CachedIdx++)
2472                         {
2473                         // compare the BSSID
2474                         if (NdisEqualMemory(pPmksa->bssid.sa_data, pAd->StaCfg.SavedPMK[CachedIdx].BSSID, MAC_ADDR_LEN))
2475                                 break;
2476                 }
2477
2478                 // Found, replace it
2479                 if (CachedIdx < PMKID_NO)
2480                 {
2481                         DBGPRINT(RT_DEBUG_OFF, ("Update PMKID, idx = %d\n", CachedIdx));
2482                         NdisMoveMemory(&pAd->StaCfg.SavedPMK[CachedIdx].BSSID[0], pPmksa->bssid.sa_data, MAC_ADDR_LEN);
2483                                 NdisMoveMemory(&pAd->StaCfg.SavedPMK[CachedIdx].PMKID[0], pPmksa->pmkid, 16);
2484                         pAd->StaCfg.SavedPMKNum++;
2485                 }
2486                 // Not found, replace the last one
2487                 else
2488                 {
2489                         // Randomly replace one
2490                         CachedIdx = (pPmksa->bssid.sa_data[5] % PMKID_NO);
2491                         DBGPRINT(RT_DEBUG_OFF, ("Update PMKID, idx = %d\n", CachedIdx));
2492                         NdisMoveMemory(&pAd->StaCfg.SavedPMK[CachedIdx].BSSID[0], pPmksa->bssid.sa_data, MAC_ADDR_LEN);
2493                                 NdisMoveMemory(&pAd->StaCfg.SavedPMK[CachedIdx].PMKID[0], pPmksa->pmkid, 16);
2494                 }
2495
2496                         DBGPRINT(RT_DEBUG_TRACE ,("rt_ioctl_siwpmksa - IW_PMKSA_ADD\n"));
2497                         break;
2498                 default:
2499                         DBGPRINT(RT_DEBUG_TRACE ,("rt_ioctl_siwpmksa - Unknow Command!!\n"));
2500                         break;
2501         }
2502
2503         return 0;
2504 }
2505
2506 int rt_ioctl_siwrate(struct net_device *dev,
2507                         struct iw_request_info *info,
2508                         union iwreq_data *wrqu, char *extra)
2509 {
2510     PRTMP_ADAPTER   pAd = dev->ml_priv;
2511     UINT32          rate = wrqu->bitrate.value, fixed = wrqu->bitrate.fixed;
2512
2513     //check if the interface is down
2514         if(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE))
2515         {
2516                 DBGPRINT(RT_DEBUG_TRACE, ("rt_ioctl_siwrate::Network is down!\n"));
2517         return -ENETDOWN;
2518         }
2519
2520     DBGPRINT(RT_DEBUG_TRACE, ("rt_ioctl_siwrate::(rate = %d, fixed = %d)\n", rate, fixed));
2521     /* rate = -1 => auto rate
2522        rate = X, fixed = 1 => (fixed rate X)
2523     */
2524     if (rate == -1)
2525     {
2526                 //Auto Rate
2527                 pAd->StaCfg.DesiredTransmitSetting.field.MCS = MCS_AUTO;
2528                 pAd->StaCfg.bAutoTxRateSwitch = TRUE;
2529                 if ((pAd->CommonCfg.PhyMode <= PHY_11G) ||
2530                     (pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE <= MODE_OFDM))
2531                         RTMPSetDesiredRates(pAd, -1);
2532
2533                 SetCommonHT(pAd);
2534     }
2535     else
2536     {
2537         if (fixed)
2538         {
2539                 pAd->StaCfg.bAutoTxRateSwitch = FALSE;
2540             if ((pAd->CommonCfg.PhyMode <= PHY_11G) ||
2541                 (pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE <= MODE_OFDM))
2542                 RTMPSetDesiredRates(pAd, rate);
2543             else
2544             {
2545                 pAd->StaCfg.DesiredTransmitSetting.field.MCS = MCS_AUTO;
2546                 SetCommonHT(pAd);
2547             }
2548             DBGPRINT(RT_DEBUG_TRACE, ("rt_ioctl_siwrate::(HtMcs=%d)\n",pAd->StaCfg.DesiredTransmitSetting.field.MCS));
2549         }
2550         else
2551         {
2552             // TODO: rate = X, fixed = 0 => (rates <= X)
2553             return -EOPNOTSUPP;
2554         }
2555     }
2556
2557     return 0;
2558 }
2559
2560 int rt_ioctl_giwrate(struct net_device *dev,
2561                                struct iw_request_info *info,
2562                                union iwreq_data *wrqu, char *extra)
2563 {
2564     PRTMP_ADAPTER   pAd = dev->ml_priv;
2565     int rate_index = 0, rate_count = 0;
2566     HTTRANSMIT_SETTING ht_setting;
2567     __s32 ralinkrate[] =
2568         {2,  4,   11,  22, // CCK
2569         12, 18,   24,  36, 48, 72, 96, 108, // OFDM
2570         13, 26,   39,  52,  78, 104, 117, 130, 26,  52,  78, 104, 156, 208, 234, 260, // 20MHz, 800ns GI, MCS: 0 ~ 15
2571         39, 78,  117, 156, 234, 312, 351, 390,                                                                            // 20MHz, 800ns GI, MCS: 16 ~ 23
2572         27, 54,   81, 108, 162, 216, 243, 270, 54, 108, 162, 216, 324, 432, 486, 540, // 40MHz, 800ns GI, MCS: 0 ~ 15
2573         81, 162, 243, 324, 486, 648, 729, 810,                                                                            // 40MHz, 800ns GI, MCS: 16 ~ 23
2574         14, 29,   43,  57,  87, 115, 130, 144, 29, 59,   87, 115, 173, 230, 260, 288, // 20MHz, 400ns GI, MCS: 0 ~ 15
2575         43, 87,  130, 173, 260, 317, 390, 433,                                                                            // 20MHz, 400ns GI, MCS: 16 ~ 23
2576         30, 60,   90, 120, 180, 240, 270, 300, 60, 120, 180, 240, 360, 480, 540, 600, // 40MHz, 400ns GI, MCS: 0 ~ 15
2577         90, 180, 270, 360, 540, 720, 810, 900};                                                                           // 40MHz, 400ns GI, MCS: 16 ~ 23
2578
2579     rate_count = sizeof(ralinkrate)/sizeof(__s32);
2580     //check if the interface is down
2581         if(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE))
2582         {
2583                 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
2584         return -ENETDOWN;
2585         }
2586
2587     if ((pAd->StaCfg.bAutoTxRateSwitch == FALSE) &&
2588         (INFRA_ON(pAd)) &&
2589         ((pAd->CommonCfg.PhyMode <= PHY_11G) || (pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE <= MODE_OFDM)))
2590         ht_setting.word = pAd->StaCfg.HTPhyMode.word;
2591     else
2592         ht_setting.word = pAd->MacTab.Content[BSSID_WCID].HTPhyMode.word;
2593
2594     if (ht_setting.field.MODE >= MODE_HTMIX)
2595     {
2596         rate_index = 12 + ((UCHAR)ht_setting.field.BW *24) + ((UCHAR)ht_setting.field.ShortGI *48) + ((UCHAR)ht_setting.field.MCS);
2597     }
2598     else
2599     if (ht_setting.field.MODE == MODE_OFDM)
2600         rate_index = (UCHAR)(ht_setting.field.MCS) + 4;
2601     else if (ht_setting.field.MODE == MODE_CCK)
2602         rate_index = (UCHAR)(ht_setting.field.MCS);
2603
2604     if (rate_index < 0)
2605         rate_index = 0;
2606
2607     if (rate_index > rate_count)
2608         rate_index = rate_count;
2609
2610     wrqu->bitrate.value = ralinkrate[rate_index] * 500000;
2611     wrqu->bitrate.disabled = 0;
2612
2613     return 0;
2614 }
2615
2616 static const iw_handler rt_handler[] =
2617 {
2618         (iw_handler) NULL,                                  /* SIOCSIWCOMMIT */
2619         (iw_handler) rt_ioctl_giwname,                  /* SIOCGIWNAME   */
2620         (iw_handler) NULL,                                  /* SIOCSIWNWID   */
2621         (iw_handler) NULL,                                  /* SIOCGIWNWID   */
2622         (iw_handler) rt_ioctl_siwfreq,              /* SIOCSIWFREQ   */
2623         (iw_handler) rt_ioctl_giwfreq,              /* SIOCGIWFREQ   */
2624         (iw_handler) rt_ioctl_siwmode,              /* SIOCSIWMODE   */
2625         (iw_handler) rt_ioctl_giwmode,              /* SIOCGIWMODE   */
2626         (iw_handler) NULL,                              /* SIOCSIWSENS   */
2627         (iw_handler) NULL,                              /* SIOCGIWSENS   */
2628         (iw_handler) NULL /* not used */,               /* SIOCSIWRANGE  */
2629         (iw_handler) rt_ioctl_giwrange,             /* SIOCGIWRANGE  */
2630         (iw_handler) NULL /* not used */,               /* SIOCSIWPRIV   */
2631         (iw_handler) NULL /* kernel code */,    /* SIOCGIWPRIV   */
2632         (iw_handler) NULL /* not used */,               /* SIOCSIWSTATS  */
2633         (iw_handler) rt28xx_get_wireless_stats /* kernel code */,    /* SIOCGIWSTATS  */
2634         (iw_handler) NULL,                              /* SIOCSIWSPY    */
2635         (iw_handler) NULL,                              /* SIOCGIWSPY    */
2636         (iw_handler) NULL,                                      /* SIOCSIWTHRSPY */
2637         (iw_handler) NULL,                                      /* SIOCGIWTHRSPY */
2638         (iw_handler) rt_ioctl_siwap,            /* SIOCSIWAP     */
2639         (iw_handler) rt_ioctl_giwap,                /* SIOCGIWAP     */
2640         (iw_handler) rt_ioctl_siwmlme,          /* SIOCSIWMLME   */
2641         (iw_handler) rt_ioctl_iwaplist,             /* SIOCGIWAPLIST */
2642         (iw_handler) rt_ioctl_siwscan,              /* SIOCSIWSCAN   */
2643         (iw_handler) rt_ioctl_giwscan,              /* SIOCGIWSCAN   */
2644         (iw_handler) rt_ioctl_siwessid,             /* SIOCSIWESSID  */
2645         (iw_handler) rt_ioctl_giwessid,             /* SIOCGIWESSID  */
2646         (iw_handler) rt_ioctl_siwnickn,             /* SIOCSIWNICKN  */
2647         (iw_handler) rt_ioctl_giwnickn,             /* SIOCGIWNICKN  */
2648         (iw_handler) NULL,                                      /* -- hole --    */
2649         (iw_handler) NULL,                                      /* -- hole --    */
2650         (iw_handler) rt_ioctl_siwrate,          /* SIOCSIWRATE   */
2651         (iw_handler) rt_ioctl_giwrate,          /* SIOCGIWRATE   */
2652         (iw_handler) rt_ioctl_siwrts,               /* SIOCSIWRTS    */
2653         (iw_handler) rt_ioctl_giwrts,               /* SIOCGIWRTS    */
2654         (iw_handler) rt_ioctl_siwfrag,              /* SIOCSIWFRAG   */
2655         (iw_handler) rt_ioctl_giwfrag,              /* SIOCGIWFRAG   */
2656         (iw_handler) NULL,                              /* SIOCSIWTXPOW  */
2657         (iw_handler) NULL,                              /* SIOCGIWTXPOW  */
2658         (iw_handler) NULL,                              /* SIOCSIWRETRY  */
2659         (iw_handler) NULL,                              /* SIOCGIWRETRY  */
2660         (iw_handler) rt_ioctl_siwencode,                /* SIOCSIWENCODE */
2661         (iw_handler) rt_ioctl_giwencode,                /* SIOCGIWENCODE */
2662         (iw_handler) NULL,                              /* SIOCSIWPOWER  */
2663         (iw_handler) NULL,                              /* SIOCGIWPOWER  */
2664         (iw_handler) NULL,                                              /* -- hole -- */
2665         (iw_handler) NULL,                                              /* -- hole -- */
2666     (iw_handler) rt_ioctl_siwgenie,         /* SIOCSIWGENIE  */
2667         (iw_handler) rt_ioctl_giwgenie,         /* SIOCGIWGENIE  */
2668         (iw_handler) rt_ioctl_siwauth,              /* SIOCSIWAUTH   */
2669         (iw_handler) rt_ioctl_giwauth,              /* SIOCGIWAUTH   */
2670         (iw_handler) rt_ioctl_siwencodeext,         /* SIOCSIWENCODEEXT */
2671         (iw_handler) rt_ioctl_giwencodeext,             /* SIOCGIWENCODEEXT */
2672         (iw_handler) rt_ioctl_siwpmksa,         /* SIOCSIWPMKSA  */
2673 };
2674
2675 static const iw_handler rt_priv_handlers[] = {
2676         (iw_handler) NULL, /* + 0x00 */
2677         (iw_handler) NULL, /* + 0x01 */
2678         (iw_handler) rt_ioctl_setparam, /* + 0x02 */
2679         (iw_handler) NULL, /* + 0x03 */
2680         (iw_handler) NULL, /* + 0x04 */
2681         (iw_handler) NULL, /* + 0x05 */
2682         (iw_handler) NULL, /* + 0x06 */
2683         (iw_handler) NULL, /* + 0x07 */
2684         (iw_handler) NULL, /* + 0x08 */
2685         (iw_handler) rt_private_get_statistics, /* + 0x09 */
2686         (iw_handler) NULL, /* + 0x0A */
2687         (iw_handler) NULL, /* + 0x0B */
2688         (iw_handler) NULL, /* + 0x0C */
2689         (iw_handler) NULL, /* + 0x0D */
2690         (iw_handler) NULL, /* + 0x0E */
2691         (iw_handler) NULL, /* + 0x0F */
2692         (iw_handler) NULL, /* + 0x10 */
2693         (iw_handler) rt_private_show, /* + 0x11 */
2694     (iw_handler) NULL, /* + 0x12 */
2695         (iw_handler) NULL, /* + 0x13 */
2696         (iw_handler) NULL, /* + 0x15 */
2697         (iw_handler) NULL, /* + 0x17 */
2698         (iw_handler) NULL, /* + 0x18 */
2699 };
2700
2701 const struct iw_handler_def rt28xx_iw_handler_def =
2702 {
2703 #define N(a)    (sizeof (a) / sizeof (a[0]))
2704         .standard       = (iw_handler *) rt_handler,
2705         .num_standard   = sizeof(rt_handler) / sizeof(iw_handler),
2706         .private        = (iw_handler *) rt_priv_handlers,
2707         .num_private            = N(rt_priv_handlers),
2708         .private_args   = (struct iw_priv_args *) privtab,
2709         .num_private_args       = N(privtab),
2710 #if IW_HANDLER_VERSION >= 7
2711     .get_wireless_stats = rt28xx_get_wireless_stats,
2712 #endif
2713 };
2714
2715 INT rt28xx_sta_ioctl(
2716         IN      struct net_device       *net_dev,
2717         IN      OUT     struct ifreq    *rq,
2718         IN      INT                                     cmd)
2719 {
2720         RTMP_ADAPTER *pAd = net_dev->ml_priv;
2721         POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie;
2722         struct iwreq        *wrq = (struct iwreq *) rq;
2723         BOOLEAN                         StateMachineTouched = FALSE;
2724         INT                                     Status = NDIS_STATUS_SUCCESS;
2725
2726     //check if the interface is down
2727     if(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE))
2728     {
2729         {
2730             DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
2731                     return -ENETDOWN;
2732         }
2733     }
2734
2735         {       // determine this ioctl command is comming from which interface.
2736                 pObj->ioctl_if_type = INT_MAIN;
2737                 pObj->ioctl_if = MAIN_MBSSID;
2738         }
2739
2740         switch(cmd)
2741         {
2742         case SIOCGIFHWADDR:
2743                         DBGPRINT(RT_DEBUG_TRACE, ("IOCTL::SIOCGIFHWADDR\n"));
2744                         memcpy(wrq->u.name, pAd->CurrentAddress, ETH_ALEN);
2745                         break;
2746                 case SIOCGIWNAME:
2747         {
2748                 char *name=&wrq->u.name[0];
2749                 rt_ioctl_giwname(net_dev, NULL, name, NULL);
2750                         break;
2751                 }
2752                 case SIOCGIWESSID:  //Get ESSID
2753         {
2754                 struct iw_point *essid=&wrq->u.essid;
2755                 rt_ioctl_giwessid(net_dev, NULL, essid, essid->pointer);
2756                         break;
2757                 }
2758                 case SIOCSIWESSID:  //Set ESSID
2759         {
2760                 struct iw_point *essid=&wrq->u.essid;
2761                 rt_ioctl_siwessid(net_dev, NULL, essid, essid->pointer);
2762                         break;
2763                 }
2764                 case SIOCSIWNWID:   // set network id (the cell)
2765                 case SIOCGIWNWID:   // get network id
2766                         Status = -EOPNOTSUPP;
2767                         break;
2768                 case SIOCSIWFREQ:   //set channel/frequency (Hz)
2769         {
2770                 struct iw_freq *freq=&wrq->u.freq;
2771                 rt_ioctl_siwfreq(net_dev, NULL, freq, NULL);
2772                         break;
2773                 }
2774                 case SIOCGIWFREQ:   // get channel/frequency (Hz)
2775         {
2776                 struct iw_freq *freq=&wrq->u.freq;
2777                 rt_ioctl_giwfreq(net_dev, NULL, freq, NULL);
2778                         break;
2779                 }
2780                 case SIOCSIWNICKN: //set node name/nickname
2781         {
2782                 struct iw_point *data=&wrq->u.data;
2783                 rt_ioctl_siwnickn(net_dev, NULL, data, NULL);
2784                         break;
2785                 }
2786                 case SIOCGIWNICKN: //get node name/nickname
2787         {
2788                 struct iw_point *data=&wrq->u.data;
2789                 rt_ioctl_giwnickn(net_dev, NULL, data, NULL);
2790                         break;
2791                 }
2792                 case SIOCGIWRATE:   //get default bit rate (bps)
2793                     rt_ioctl_giwrate(net_dev, NULL, &wrq->u, NULL);
2794             break;
2795             case SIOCSIWRATE:  //set default bit rate (bps)
2796                 rt_ioctl_siwrate(net_dev, NULL, &wrq->u, NULL);
2797             break;
2798         case SIOCGIWRTS:  // get RTS/CTS threshold (bytes)
2799         {
2800                 struct iw_param *rts=&wrq->u.rts;
2801                 rt_ioctl_giwrts(net_dev, NULL, rts, NULL);
2802                         break;
2803                 }
2804         case SIOCSIWRTS:  //set RTS/CTS threshold (bytes)
2805         {
2806                 struct iw_param *rts=&wrq->u.rts;
2807                 rt_ioctl_siwrts(net_dev, NULL, rts, NULL);
2808                         break;
2809                 }
2810         case SIOCGIWFRAG:  //get fragmentation thr (bytes)
2811         {
2812                 struct iw_param *frag=&wrq->u.frag;
2813                 rt_ioctl_giwfrag(net_dev, NULL, frag, NULL);
2814                         break;
2815                 }
2816         case SIOCSIWFRAG:  //set fragmentation thr (bytes)
2817         {
2818                 struct iw_param *frag=&wrq->u.frag;
2819                 rt_ioctl_siwfrag(net_dev, NULL, frag, NULL);
2820                         break;
2821                 }
2822         case SIOCGIWENCODE:  //get encoding token & mode
2823         {
2824                 struct iw_point *erq=&wrq->u.encoding;
2825                 if(erq->pointer)
2826                         rt_ioctl_giwencode(net_dev, NULL, erq, erq->pointer);
2827                         break;
2828                 }
2829         case SIOCSIWENCODE:  //set encoding token & mode
2830         {
2831                 struct iw_point *erq=&wrq->u.encoding;
2832                 if(erq->pointer)
2833                         rt_ioctl_siwencode(net_dev, NULL, erq, erq->pointer);
2834                         break;
2835                 }
2836                 case SIOCGIWAP:     //get access point MAC addresses
2837         {
2838                 struct sockaddr *ap_addr=&wrq->u.ap_addr;
2839                 rt_ioctl_giwap(net_dev, NULL, ap_addr, ap_addr->sa_data);
2840                         break;
2841                 }
2842             case SIOCSIWAP:  //set access point MAC addresses
2843         {
2844                 struct sockaddr *ap_addr=&wrq->u.ap_addr;
2845                 rt_ioctl_siwap(net_dev, NULL, ap_addr, ap_addr->sa_data);
2846                         break;
2847                 }
2848                 case SIOCGIWMODE:   //get operation mode
2849         {
2850                 __u32 *mode=&wrq->u.mode;
2851                 rt_ioctl_giwmode(net_dev, NULL, mode, NULL);
2852                         break;
2853                 }
2854                 case SIOCSIWMODE:   //set operation mode
2855         {
2856                 __u32 *mode=&wrq->u.mode;
2857                 rt_ioctl_siwmode(net_dev, NULL, mode, NULL);
2858                         break;
2859                 }
2860                 case SIOCGIWSENS:   //get sensitivity (dBm)
2861                 case SIOCSIWSENS:       //set sensitivity (dBm)
2862                 case SIOCGIWPOWER:  //get Power Management settings
2863                 case SIOCSIWPOWER:  //set Power Management settings
2864                 case SIOCGIWTXPOW:  //get transmit power (dBm)
2865                 case SIOCSIWTXPOW:  //set transmit power (dBm)
2866                 case SIOCGIWRANGE:      //Get range of parameters
2867                 case SIOCGIWRETRY:      //get retry limits and lifetime
2868                 case SIOCSIWRETRY:      //set retry limits and lifetime
2869                 case RT_PRIV_IOCTL:
2870                 case RT_PRIV_IOCTL_EXT:
2871                         Status = -EOPNOTSUPP;
2872                         break;
2873                 case SIOCGIWPRIV:
2874                         if (wrq->u.data.pointer)
2875                         {
2876                                 if ( access_ok(VERIFY_WRITE, wrq->u.data.pointer, sizeof(privtab)) != TRUE)
2877                                         break;
2878                                 wrq->u.data.length = sizeof(privtab) / sizeof(privtab[0]);
2879                                 if (copy_to_user(wrq->u.data.pointer, privtab, sizeof(privtab)))
2880                                         Status = -EFAULT;
2881                         }
2882                         break;
2883                 case RTPRIV_IOCTL_SET:
2884                         if(access_ok(VERIFY_READ, wrq->u.data.pointer, wrq->u.data.length) != TRUE)
2885                                 break;
2886                         rt_ioctl_setparam(net_dev, NULL, NULL, wrq->u.data.pointer);
2887                         break;
2888                 case RTPRIV_IOCTL_GSITESURVEY:
2889                         RTMPIoctlGetSiteSurvey(pAd, wrq);
2890                     break;
2891         case SIOCETHTOOL:
2892                 break;
2893                 default:
2894                         DBGPRINT(RT_DEBUG_ERROR, ("IOCTL::unknown IOCTL's cmd = 0x%08x\n", cmd));
2895                         Status = -EOPNOTSUPP;
2896                         break;
2897         }
2898
2899     if(StateMachineTouched) // Upper layer sent a MLME-related operations
2900         RT28XX_MLME_HANDLER(pAd);
2901
2902         return Status;
2903 }
2904
2905 /*
2906     ==========================================================================
2907     Description:
2908         Set SSID
2909     Return:
2910         TRUE if all parameters are OK, FALSE otherwise
2911     ==========================================================================
2912 */
2913 INT Set_SSID_Proc(
2914     IN  PRTMP_ADAPTER   pAdapter,
2915     IN  PUCHAR          arg)
2916 {
2917     NDIS_802_11_SSID                    Ssid, *pSsid=NULL;
2918     BOOLEAN                             StateMachineTouched = FALSE;
2919     int                                 success = TRUE;
2920
2921     if( strlen(arg) <= MAX_LEN_OF_SSID)
2922     {
2923         NdisZeroMemory(&Ssid, sizeof(NDIS_802_11_SSID));
2924         if (strlen(arg) != 0)
2925         {
2926             NdisMoveMemory(Ssid.Ssid, arg, strlen(arg));
2927             Ssid.SsidLength = strlen(arg);
2928         }
2929         else   //ANY ssid
2930         {
2931             Ssid.SsidLength = 0;
2932                     memcpy(Ssid.Ssid, "", 0);
2933                         pAdapter->StaCfg.BssType = BSS_INFRA;
2934                         pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
2935                 pAdapter->StaCfg.WepStatus  = Ndis802_11EncryptionDisabled;
2936                 }
2937         pSsid = &Ssid;
2938
2939         if (pAdapter->Mlme.CntlMachine.CurrState != CNTL_IDLE)
2940         {
2941             RT28XX_MLME_RESET_STATE_MACHINE(pAdapter);
2942             DBGPRINT(RT_DEBUG_TRACE, ("!!! MLME busy, reset MLME state machine !!!\n"));
2943         }
2944
2945         pAdapter->MlmeAux.CurrReqIsFromNdis = TRUE;
2946         pAdapter->StaCfg.bScanReqIsFromWebUI = FALSE;
2947                 pAdapter->bConfigChanged = TRUE;
2948
2949         MlmeEnqueue(pAdapter,
2950                     MLME_CNTL_STATE_MACHINE,
2951                     OID_802_11_SSID,
2952                     sizeof(NDIS_802_11_SSID),
2953                     (VOID *)pSsid);
2954
2955         StateMachineTouched = TRUE;
2956         DBGPRINT(RT_DEBUG_TRACE, ("Set_SSID_Proc::(Len=%d,Ssid=%s)\n", Ssid.SsidLength, Ssid.Ssid));
2957     }
2958     else
2959         success = FALSE;
2960
2961     if (StateMachineTouched) // Upper layer sent a MLME-related operations
2962         RT28XX_MLME_HANDLER(pAdapter);
2963
2964     return success;
2965 }
2966
2967 #ifdef WMM_SUPPORT
2968 /*
2969     ==========================================================================
2970     Description:
2971         Set WmmCapable Enable or Disable
2972     Return:
2973         TRUE if all parameters are OK, FALSE otherwise
2974     ==========================================================================
2975 */
2976 INT     Set_WmmCapable_Proc(
2977         IN      PRTMP_ADAPTER   pAd,
2978         IN      PUCHAR                  arg)
2979 {
2980         BOOLEAN bWmmCapable;
2981
2982         bWmmCapable = simple_strtol(arg, 0, 10);
2983
2984         if ((bWmmCapable == 1)
2985 #ifdef RT2870
2986                 && (pAd->NumberOfPipes >= 5)
2987 #endif // RT2870 //
2988                 )
2989                 pAd->CommonCfg.bWmmCapable = TRUE;
2990         else if (bWmmCapable == 0)
2991                 pAd->CommonCfg.bWmmCapable = FALSE;
2992         else
2993                 return FALSE;  //Invalid argument
2994
2995         DBGPRINT(RT_DEBUG_TRACE, ("Set_WmmCapable_Proc::(bWmmCapable=%d)\n",
2996                 pAd->CommonCfg.bWmmCapable));
2997
2998         return TRUE;
2999 }
3000 #endif // WMM_SUPPORT //
3001
3002 /*
3003     ==========================================================================
3004     Description:
3005         Set Network Type(Infrastructure/Adhoc mode)
3006     Return:
3007         TRUE if all parameters are OK, FALSE otherwise
3008     ==========================================================================
3009 */
3010 INT Set_NetworkType_Proc(
3011     IN  PRTMP_ADAPTER   pAdapter,
3012     IN  PUCHAR          arg)
3013 {
3014     UINT32      Value = 0;
3015
3016     if (strcmp(arg, "Adhoc") == 0)
3017         {
3018                 if (pAdapter->StaCfg.BssType != BSS_ADHOC)
3019                 {
3020                         // Config has changed
3021                         pAdapter->bConfigChanged = TRUE;
3022             if (MONITOR_ON(pAdapter))
3023             {
3024                 RTMP_IO_WRITE32(pAdapter, RX_FILTR_CFG, STANORMAL);
3025                 RTMP_IO_READ32(pAdapter, MAC_SYS_CTRL, &Value);
3026                                 Value &= (~0x80);
3027                                 RTMP_IO_WRITE32(pAdapter, MAC_SYS_CTRL, Value);
3028                 OPSTATUS_CLEAR_FLAG(pAdapter, fOP_STATUS_MEDIA_STATE_CONNECTED);
3029                 pAdapter->StaCfg.bAutoReconnect = TRUE;
3030                 LinkDown(pAdapter, FALSE);
3031             }
3032                         if (INFRA_ON(pAdapter))
3033                         {
3034                                 //BOOLEAN Cancelled;
3035                                 // Set the AutoReconnectSsid to prevent it reconnect to old SSID
3036                                 // Since calling this indicate user don't want to connect to that SSID anymore.
3037                                 pAdapter->MlmeAux.AutoReconnectSsidLen= 32;
3038                                 NdisZeroMemory(pAdapter->MlmeAux.AutoReconnectSsid, pAdapter->MlmeAux.AutoReconnectSsidLen);
3039
3040                                 LinkDown(pAdapter, FALSE);
3041
3042                                 DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event BB!\n"));
3043                         }
3044                 }
3045                 pAdapter->StaCfg.BssType = BSS_ADHOC;
3046         pAdapter->net_dev->type = pAdapter->StaCfg.OriDevType;
3047                 DBGPRINT(RT_DEBUG_TRACE, ("===>Set_NetworkType_Proc::(AD-HOC)\n"));
3048         }
3049     else if (strcmp(arg, "Infra") == 0)
3050         {
3051                 if (pAdapter->StaCfg.BssType != BSS_INFRA)
3052                 {
3053                         // Config has changed
3054                         pAdapter->bConfigChanged = TRUE;
3055             if (MONITOR_ON(pAdapter))
3056             {
3057                 RTMP_IO_WRITE32(pAdapter, RX_FILTR_CFG, STANORMAL);
3058                 RTMP_IO_READ32(pAdapter, MAC_SYS_CTRL, &Value);
3059                                 Value &= (~0x80);
3060                                 RTMP_IO_WRITE32(pAdapter, MAC_SYS_CTRL, Value);
3061                 OPSTATUS_CLEAR_FLAG(pAdapter, fOP_STATUS_MEDIA_STATE_CONNECTED);
3062                 pAdapter->StaCfg.bAutoReconnect = TRUE;
3063                 LinkDown(pAdapter, FALSE);
3064             }
3065                         if (ADHOC_ON(pAdapter))
3066                         {
3067                                 // Set the AutoReconnectSsid to prevent it reconnect to old SSID
3068                                 // Since calling this indicate user don't want to connect to that SSID anymore.
3069                                 pAdapter->MlmeAux.AutoReconnectSsidLen= 32;
3070                                 NdisZeroMemory(pAdapter->MlmeAux.AutoReconnectSsid, pAdapter->MlmeAux.AutoReconnectSsidLen);
3071
3072                                 LinkDown(pAdapter, FALSE);
3073                         }
3074                 }
3075                 pAdapter->StaCfg.BssType = BSS_INFRA;
3076         pAdapter->net_dev->type = pAdapter->StaCfg.OriDevType;
3077                 DBGPRINT(RT_DEBUG_TRACE, ("===>Set_NetworkType_Proc::(INFRA)\n"));
3078
3079         pAdapter->StaCfg.BssType = BSS_INFRA;
3080         }
3081     else if (strcmp(arg, "Monitor") == 0)
3082     {
3083                 UCHAR   bbpValue = 0;
3084                 BCN_TIME_CFG_STRUC csr;
3085                 OPSTATUS_CLEAR_FLAG(pAdapter, fOP_STATUS_INFRA_ON);
3086         OPSTATUS_CLEAR_FLAG(pAdapter, fOP_STATUS_ADHOC_ON);
3087                 OPSTATUS_SET_FLAG(pAdapter, fOP_STATUS_MEDIA_STATE_CONNECTED);
3088                 // disable all periodic state machine
3089                 pAdapter->StaCfg.bAutoReconnect = FALSE;
3090                 // reset all mlme state machine
3091                 RT28XX_MLME_RESET_STATE_MACHINE(pAdapter);
3092                 DBGPRINT(RT_DEBUG_TRACE, ("fOP_STATUS_MEDIA_STATE_CONNECTED \n"));
3093         if (pAdapter->CommonCfg.CentralChannel == 0)
3094         {
3095             if (pAdapter->CommonCfg.PhyMode == PHY_11AN_MIXED)
3096                 pAdapter->CommonCfg.CentralChannel = 36;
3097             else
3098                 pAdapter->CommonCfg.CentralChannel = 6;
3099         }
3100         else
3101             N_ChannelCheck(pAdapter);
3102
3103         if (pAdapter->CommonCfg.PhyMode >= PHY_11ABGN_MIXED &&
3104             pAdapter->CommonCfg.RegTransmitSetting.field.BW == BW_40 &&
3105             pAdapter->CommonCfg.RegTransmitSetting.field.EXTCHA == EXTCHA_ABOVE)
3106                 {
3107                         // 40MHz ,control channel at lower
3108                         RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R4, &bbpValue);
3109                         bbpValue &= (~0x18);
3110                         bbpValue |= 0x10;
3111                         RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R4, bbpValue);
3112                         pAdapter->CommonCfg.BBPCurrentBW = BW_40;
3113                         //  RX : control channel at lower
3114                         RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R3, &bbpValue);
3115                         bbpValue &= (~0x20);
3116                         RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R3, bbpValue);
3117
3118                         RTMP_IO_READ32(pAdapter, TX_BAND_CFG, &Value);
3119                         Value &= 0xfffffffe;
3120                         RTMP_IO_WRITE32(pAdapter, TX_BAND_CFG, Value);
3121                         pAdapter->CommonCfg.CentralChannel = pAdapter->CommonCfg.Channel + 2;
3122             AsicSwitchChannel(pAdapter, pAdapter->CommonCfg.CentralChannel, FALSE);
3123                     AsicLockChannel(pAdapter, pAdapter->CommonCfg.CentralChannel);
3124             DBGPRINT(RT_DEBUG_TRACE, ("BW_40 ,control_channel(%d), CentralChannel(%d) \n",
3125                                        pAdapter->CommonCfg.Channel,
3126                                        pAdapter->CommonCfg.CentralChannel));
3127                 }
3128                 else if (pAdapter->CommonCfg.PhyMode >= PHY_11ABGN_MIXED &&
3129                  pAdapter->CommonCfg.RegTransmitSetting.field.BW == BW_40 &&
3130                  pAdapter->CommonCfg.RegTransmitSetting.field.EXTCHA == EXTCHA_BELOW)
3131                 {
3132                         // 40MHz ,control channel at upper
3133                         RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R4, &bbpValue);
3134                         bbpValue &= (~0x18);
3135                         bbpValue |= 0x10;
3136                         RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R4, bbpValue);
3137                         pAdapter->CommonCfg.BBPCurrentBW = BW_40;
3138                         RTMP_IO_READ32(pAdapter, TX_BAND_CFG, &Value);
3139                         Value |= 0x1;
3140                         RTMP_IO_WRITE32(pAdapter, TX_BAND_CFG, Value);
3141
3142                         RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R3, &bbpValue);
3143                         bbpValue |= (0x20);
3144                         RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R3, bbpValue);
3145                         pAdapter->CommonCfg.CentralChannel = pAdapter->CommonCfg.Channel - 2;
3146             AsicSwitchChannel(pAdapter, pAdapter->CommonCfg.CentralChannel, FALSE);
3147                     AsicLockChannel(pAdapter, pAdapter->CommonCfg.CentralChannel);
3148             DBGPRINT(RT_DEBUG_TRACE, ("BW_40 ,control_channel(%d), CentralChannel(%d) \n",
3149                                        pAdapter->CommonCfg.Channel,
3150                                        pAdapter->CommonCfg.CentralChannel));
3151                 }
3152                 else
3153                 {
3154                         // 20MHz
3155                         RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R4, &bbpValue);
3156                         bbpValue &= (~0x18);
3157                         RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R4, bbpValue);
3158                         pAdapter->CommonCfg.BBPCurrentBW = BW_20;
3159                         AsicSwitchChannel(pAdapter, pAdapter->CommonCfg.Channel, FALSE);
3160                         AsicLockChannel(pAdapter, pAdapter->CommonCfg.Channel);
3161                         DBGPRINT(RT_DEBUG_TRACE, ("BW_20, Channel(%d)\n", pAdapter->CommonCfg.Channel));
3162                 }
3163                 // Enable Rx with promiscuous reception
3164                 RTMP_IO_WRITE32(pAdapter, RX_FILTR_CFG, 0x3);
3165                 // ASIC supporsts sniffer function with replacing RSSI with timestamp.
3166                 //RTMP_IO_READ32(pAdapter, MAC_SYS_CTRL, &Value);
3167                 //Value |= (0x80);
3168                 //RTMP_IO_WRITE32(pAdapter, MAC_SYS_CTRL, Value);
3169                 // disable sync
3170                 RTMP_IO_READ32(pAdapter, BCN_TIME_CFG, &csr.word);
3171                 csr.field.bBeaconGen = 0;
3172                 csr.field.bTBTTEnable = 0;
3173                 csr.field.TsfSyncMode = 0;
3174                 RTMP_IO_WRITE32(pAdapter, BCN_TIME_CFG, csr.word);
3175
3176                 pAdapter->StaCfg.BssType = BSS_MONITOR;
3177         pAdapter->net_dev->type = ARPHRD_IEEE80211_PRISM; //ARPHRD_IEEE80211; // IEEE80211
3178                 DBGPRINT(RT_DEBUG_TRACE, ("===>Set_NetworkType_Proc::(MONITOR)\n"));
3179     }
3180
3181     // Reset Ralink supplicant to not use, it will be set to start when UI set PMK key
3182     pAdapter->StaCfg.WpaState = SS_NOTUSE;
3183
3184     DBGPRINT(RT_DEBUG_TRACE, ("Set_NetworkType_Proc::(NetworkType=%d)\n", pAdapter->StaCfg.BssType));
3185
3186     return TRUE;
3187 }
3188
3189 /*
3190     ==========================================================================
3191     Description:
3192         Set Authentication mode
3193     Return:
3194         TRUE if all parameters are OK, FALSE otherwise
3195     ==========================================================================
3196 */
3197 INT Set_AuthMode_Proc(
3198     IN  PRTMP_ADAPTER   pAdapter,
3199     IN  PUCHAR          arg)
3200 {
3201     if ((strcmp(arg, "WEPAUTO") == 0) || (strcmp(arg, "wepauto") == 0))
3202         pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeAutoSwitch;
3203     else if ((strcmp(arg, "OPEN") == 0) || (strcmp(arg, "open") == 0))
3204         pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
3205     else if ((strcmp(arg, "SHARED") == 0) || (strcmp(arg, "shared") == 0))
3206         pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeShared;
3207     else if ((strcmp(arg, "WPAPSK") == 0) || (strcmp(arg, "wpapsk") == 0))
3208         pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPAPSK;
3209     else if ((strcmp(arg, "WPANONE") == 0) || (strcmp(arg, "wpanone") == 0))
3210         pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPANone;
3211     else if ((strcmp(arg, "WPA2PSK") == 0) || (strcmp(arg, "wpa2psk") == 0))
3212         pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPA2PSK;
3213     else if ((strcmp(arg, "WPA") == 0) || (strcmp(arg, "wpa") == 0))
3214         pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPA;
3215     else if ((strcmp(arg, "WPA2") == 0) || (strcmp(arg, "wpa2") == 0))
3216         pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPA2;
3217     else
3218         return FALSE;
3219
3220     pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
3221
3222     DBGPRINT(RT_DEBUG_TRACE, ("Set_AuthMode_Proc::(AuthMode=%d)\n", pAdapter->StaCfg.AuthMode));
3223
3224     return TRUE;
3225 }
3226
3227 /*
3228     ==========================================================================
3229     Description:
3230         Set Encryption Type
3231     Return:
3232         TRUE if all parameters are OK, FALSE otherwise
3233     ==========================================================================
3234 */
3235 INT Set_EncrypType_Proc(
3236     IN  PRTMP_ADAPTER   pAdapter,
3237     IN  PUCHAR          arg)
3238 {
3239     if ((strcmp(arg, "NONE") == 0) || (strcmp(arg, "none") == 0))
3240     {
3241         if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
3242             return TRUE;    // do nothing
3243
3244         pAdapter->StaCfg.WepStatus     = Ndis802_11WEPDisabled;
3245         pAdapter->StaCfg.PairCipher    = Ndis802_11WEPDisabled;
3246             pAdapter->StaCfg.GroupCipher   = Ndis802_11WEPDisabled;
3247     }
3248     else if ((strcmp(arg, "WEP") == 0) || (strcmp(arg, "wep") == 0))
3249     {
3250         if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
3251             return TRUE;    // do nothing
3252
3253         pAdapter->StaCfg.WepStatus     = Ndis802_11WEPEnabled;
3254         pAdapter->StaCfg.PairCipher    = Ndis802_11WEPEnabled;
3255             pAdapter->StaCfg.GroupCipher   = Ndis802_11WEPEnabled;
3256     }
3257     else if ((strcmp(arg, "TKIP") == 0) || (strcmp(arg, "tkip") == 0))
3258     {
3259         if (pAdapter->StaCfg.AuthMode < Ndis802_11AuthModeWPA)
3260             return TRUE;    // do nothing
3261
3262         pAdapter->StaCfg.WepStatus     = Ndis802_11Encryption2Enabled;
3263         pAdapter->StaCfg.PairCipher    = Ndis802_11Encryption2Enabled;
3264             pAdapter->StaCfg.GroupCipher   = Ndis802_11Encryption2Enabled;
3265     }
3266     else if ((strcmp(arg, "AES") == 0) || (strcmp(arg, "aes") == 0))
3267     {
3268         if (pAdapter->StaCfg.AuthMode < Ndis802_11AuthModeWPA)
3269             return TRUE;    // do nothing
3270
3271         pAdapter->StaCfg.WepStatus     = Ndis802_11Encryption3Enabled;
3272         pAdapter->StaCfg.PairCipher    = Ndis802_11Encryption3Enabled;
3273             pAdapter->StaCfg.GroupCipher   = Ndis802_11Encryption3Enabled;
3274     }
3275     else
3276         return FALSE;
3277
3278     pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
3279
3280     DBGPRINT(RT_DEBUG_TRACE, ("Set_EncrypType_Proc::(EncrypType=%d)\n", pAdapter->StaCfg.WepStatus));
3281
3282     return TRUE;
3283 }
3284
3285 /*
3286     ==========================================================================
3287     Description:
3288         Set Default Key ID
3289     Return:
3290         TRUE if all parameters are OK, FALSE otherwise
3291     ==========================================================================
3292 */
3293 INT Set_DefaultKeyID_Proc(
3294     IN  PRTMP_ADAPTER   pAdapter,
3295     IN  PUCHAR          arg)
3296 {
3297     ULONG                               KeyIdx;
3298
3299     KeyIdx = simple_strtol(arg, 0, 10);
3300     if((KeyIdx >= 1 ) && (KeyIdx <= 4))
3301         pAdapter->StaCfg.DefaultKeyId = (UCHAR) (KeyIdx - 1 );
3302     else
3303         return FALSE;  //Invalid argument
3304
3305     DBGPRINT(RT_DEBUG_TRACE, ("Set_DefaultKeyID_Proc::(DefaultKeyID=%d)\n", pAdapter->StaCfg.DefaultKeyId));
3306
3307     return TRUE;
3308 }
3309
3310 /*
3311     ==========================================================================
3312     Description:
3313         Set WEP KEY1
3314     Return:
3315         TRUE if all parameters are OK, FALSE otherwise
3316     ==========================================================================
3317 */
3318 INT Set_Key1_Proc(
3319     IN  PRTMP_ADAPTER   pAdapter,
3320     IN  PUCHAR          arg)
3321 {
3322     int                                 KeyLen;
3323     int                                 i;
3324     UCHAR                               CipherAlg=CIPHER_WEP64;
3325
3326     if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
3327         return TRUE;    // do nothing
3328
3329     KeyLen = strlen(arg);
3330
3331     switch (KeyLen)
3332     {
3333         case 5: //wep 40 Ascii type
3334             pAdapter->SharedKey[BSS0][0].KeyLen = KeyLen;
3335             memcpy(pAdapter->SharedKey[BSS0][0].Key, arg, KeyLen);
3336             CipherAlg = CIPHER_WEP64;
3337             DBGPRINT(RT_DEBUG_TRACE, ("Set_Key1_Proc::(Key1=%s and type=%s)\n", arg, "Ascii"));
3338             break;
3339         case 10: //wep 40 Hex type
3340             for(i=0; i < KeyLen; i++)
3341             {
3342                 if( !isxdigit(*(arg+i)) )
3343                     return FALSE;  //Not Hex value;
3344             }
3345             pAdapter->SharedKey[BSS0][0].KeyLen = KeyLen / 2 ;
3346             AtoH(arg, pAdapter->SharedKey[BSS0][0].Key, KeyLen / 2);
3347             CipherAlg = CIPHER_WEP64;
3348             DBGPRINT(RT_DEBUG_TRACE, ("Set_Key1_Proc::(Key1=%s and type=%s)\n", arg, "Hex"));
3349             break;
3350         case 13: //wep 104 Ascii type
3351             pAdapter->SharedKey[BSS0][0].KeyLen = KeyLen;
3352             memcpy(pAdapter->SharedKey[BSS0][0].Key, arg, KeyLen);
3353             CipherAlg = CIPHER_WEP128;
3354             DBGPRINT(RT_DEBUG_TRACE, ("Set_Key1_Proc::(Key1=%s and type=%s)\n", arg, "Ascii"));
3355             break;
3356         case 26: //wep 104 Hex type
3357             for(i=0; i < KeyLen; i++)
3358             {
3359                 if( !isxdigit(*(arg+i)) )
3360                     return FALSE;  //Not Hex value;
3361             }
3362             pAdapter->SharedKey[BSS0][0].KeyLen = KeyLen / 2 ;
3363             AtoH(arg, pAdapter->SharedKey[BSS0][0].Key, KeyLen / 2);
3364             CipherAlg = CIPHER_WEP128;
3365             DBGPRINT(RT_DEBUG_TRACE, ("Set_Key1_Proc::(Key1=%s and type=%s)\n", arg, "Hex"));
3366             break;
3367         default: //Invalid argument
3368             DBGPRINT(RT_DEBUG_TRACE, ("Set_Key1_Proc::Invalid argument (=%s)\n", arg));
3369             return FALSE;
3370     }
3371
3372     pAdapter->SharedKey[BSS0][0].CipherAlg = CipherAlg;
3373
3374     // Set keys (into ASIC)
3375     if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
3376         ;   // not support
3377     else    // Old WEP stuff
3378     {
3379         AsicAddSharedKeyEntry(pAdapter,
3380                               0,
3381                               0,
3382                               pAdapter->SharedKey[BSS0][0].CipherAlg,
3383                               pAdapter->SharedKey[BSS0][0].Key,
3384                               NULL,
3385                               NULL);
3386     }
3387
3388     return TRUE;
3389 }
3390 /*
3391     ==========================================================================
3392
3393     Description:
3394         Set WEP KEY2
3395     Return:
3396         TRUE if all parameters are OK, FALSE otherwise
3397     ==========================================================================
3398 */
3399 INT Set_Key2_Proc(
3400     IN  PRTMP_ADAPTER   pAdapter,
3401     IN  PUCHAR          arg)
3402 {
3403     int                                 KeyLen;
3404     int                                 i;
3405     UCHAR                               CipherAlg=CIPHER_WEP64;
3406
3407     if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
3408         return TRUE;    // do nothing
3409
3410     KeyLen = strlen(arg);
3411
3412     switch (KeyLen)
3413     {
3414         case 5: //wep 40 Ascii type
3415             pAdapter->SharedKey[BSS0][1].KeyLen = KeyLen;
3416             memcpy(pAdapter->SharedKey[BSS0][1].Key, arg, KeyLen);
3417             CipherAlg = CIPHER_WEP64;
3418             DBGPRINT(RT_DEBUG_TRACE, ("Set_Key2_Proc::(Key2=%s and type=%s)\n", arg, "Ascii"));
3419             break;
3420         case 10: //wep 40 Hex type
3421             for(i=0; i < KeyLen; i++)
3422             {
3423                 if( !isxdigit(*(arg+i)) )
3424                     return FALSE;  //Not Hex value;
3425             }
3426             pAdapter->SharedKey[BSS0][1].KeyLen = KeyLen / 2 ;
3427             AtoH(arg, pAdapter->SharedKey[BSS0][1].Key, KeyLen / 2);
3428             CipherAlg = CIPHER_WEP64;
3429             DBGPRINT(RT_DEBUG_TRACE, ("Set_Key2_Proc::(Key2=%s and type=%s)\n", arg, "Hex"));
3430             break;
3431         case 13: //wep 104 Ascii type
3432             pAdapter->SharedKey[BSS0][1].KeyLen = KeyLen;
3433             memcpy(pAdapter->SharedKey[BSS0][1].Key, arg, KeyLen);
3434             CipherAlg = CIPHER_WEP128;
3435             DBGPRINT(RT_DEBUG_TRACE, ("Set_Key2_Proc::(Key2=%s and type=%s)\n", arg, "Ascii"));
3436             break;
3437         case 26: //wep 104 Hex type
3438             for(i=0; i < KeyLen; i++)
3439             {
3440                 if( !isxdigit(*(arg+i)) )
3441                     return FALSE;  //Not Hex value;
3442             }
3443             pAdapter->SharedKey[BSS0][1].KeyLen = KeyLen / 2 ;
3444             AtoH(arg, pAdapter->SharedKey[BSS0][1].Key, KeyLen / 2);
3445             CipherAlg = CIPHER_WEP128;
3446             DBGPRINT(RT_DEBUG_TRACE, ("Set_Key2_Proc::(Key2=%s and type=%s)\n", arg, "Hex"));
3447             break;
3448         default: //Invalid argument
3449             DBGPRINT(RT_DEBUG_TRACE, ("Set_Key2_Proc::Invalid argument (=%s)\n", arg));
3450             return FALSE;
3451     }
3452     pAdapter->SharedKey[BSS0][1].CipherAlg = CipherAlg;
3453
3454     // Set keys (into ASIC)
3455     if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
3456         ;   // not support
3457     else    // Old WEP stuff
3458     {
3459         AsicAddSharedKeyEntry(pAdapter,
3460                               0,
3461                               1,
3462                               pAdapter->SharedKey[BSS0][1].CipherAlg,
3463                               pAdapter->SharedKey[BSS0][1].Key,
3464                               NULL,
3465                               NULL);
3466     }
3467
3468     return TRUE;
3469 }
3470 /*
3471     ==========================================================================
3472     Description:
3473         Set WEP KEY3
3474     Return:
3475         TRUE if all parameters are OK, FALSE otherwise
3476     ==========================================================================
3477 */
3478 INT Set_Key3_Proc(
3479     IN  PRTMP_ADAPTER   pAdapter,
3480     IN  PUCHAR          arg)
3481 {
3482     int                                 KeyLen;
3483     int                                 i;
3484     UCHAR                               CipherAlg=CIPHER_WEP64;
3485
3486     if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
3487         return TRUE;    // do nothing
3488
3489     KeyLen = strlen(arg);
3490
3491     switch (KeyLen)
3492     {
3493         case 5: //wep 40 Ascii type
3494             pAdapter->SharedKey[BSS0][2].KeyLen = KeyLen;
3495             memcpy(pAdapter->SharedKey[BSS0][2].Key, arg, KeyLen);
3496             CipherAlg = CIPHER_WEP64;
3497             DBGPRINT(RT_DEBUG_TRACE, ("Set_Key3_Proc::(Key3=%s and type=Ascii)\n", arg));
3498             break;
3499         case 10: //wep 40 Hex type
3500             for(i=0; i < KeyLen; i++)
3501             {
3502                 if( !isxdigit(*(arg+i)) )
3503                     return FALSE;  //Not Hex value;
3504             }
3505             pAdapter->SharedKey[BSS0][2].KeyLen = KeyLen / 2 ;
3506             AtoH(arg, pAdapter->SharedKey[BSS0][2].Key, KeyLen / 2);
3507             CipherAlg = CIPHER_WEP64;
3508             DBGPRINT(RT_DEBUG_TRACE, ("Set_Key3_Proc::(Key3=%s and type=Hex)\n", arg));
3509             break;
3510         case 13: //wep 104 Ascii type
3511             pAdapter->SharedKey[BSS0][2].KeyLen = KeyLen;
3512             memcpy(pAdapter->SharedKey[BSS0][2].Key, arg, KeyLen);
3513             CipherAlg = CIPHER_WEP128;
3514             DBGPRINT(RT_DEBUG_TRACE, ("Set_Key3_Proc::(Key3=%s and type=Ascii)\n", arg));
3515             break;
3516         case 26: //wep 104 Hex type
3517             for(i=0; i < KeyLen; i++)
3518             {
3519                 if( !isxdigit(*(arg+i)) )
3520                     return FALSE;  //Not Hex value;
3521             }
3522             pAdapter->SharedKey[BSS0][2].KeyLen = KeyLen / 2 ;
3523             AtoH(arg, pAdapter->SharedKey[BSS0][2].Key, KeyLen / 2);
3524             CipherAlg = CIPHER_WEP128;
3525             DBGPRINT(RT_DEBUG_TRACE, ("Set_Key3_Proc::(Key3=%s and type=Hex)\n", arg));
3526             break;
3527         default: //Invalid argument
3528             DBGPRINT(RT_DEBUG_TRACE, ("Set_Key3_Proc::Invalid argument (=%s)\n", arg));
3529             return FALSE;
3530     }
3531     pAdapter->SharedKey[BSS0][2].CipherAlg = CipherAlg;
3532
3533     // Set keys (into ASIC)
3534     if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
3535         ;   // not support
3536     else    // Old WEP stuff
3537     {
3538         AsicAddSharedKeyEntry(pAdapter,
3539                               0,
3540                               2,
3541                               pAdapter->SharedKey[BSS0][2].CipherAlg,
3542                               pAdapter->SharedKey[BSS0][2].Key,
3543                               NULL,
3544                               NULL);
3545     }
3546
3547     return TRUE;
3548 }
3549 /*
3550     ==========================================================================
3551     Description:
3552         Set WEP KEY4
3553     Return:
3554         TRUE if all parameters are OK, FALSE otherwise
3555     ==========================================================================
3556 */
3557 INT Set_Key4_Proc(
3558     IN  PRTMP_ADAPTER   pAdapter,
3559     IN  PUCHAR          arg)
3560 {
3561     int                                 KeyLen;
3562     int                                 i;
3563     UCHAR                               CipherAlg=CIPHER_WEP64;
3564
3565     if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
3566         return TRUE;    // do nothing
3567
3568     KeyLen = strlen(arg);
3569
3570     switch (KeyLen)
3571     {
3572         case 5: //wep 40 Ascii type
3573             pAdapter->SharedKey[BSS0][3].KeyLen = KeyLen;
3574             memcpy(pAdapter->SharedKey[BSS0][3].Key, arg, KeyLen);
3575             CipherAlg = CIPHER_WEP64;
3576             DBGPRINT(RT_DEBUG_TRACE, ("Set_Key4_Proc::(Key4=%s and type=%s)\n", arg, "Ascii"));
3577             break;
3578         case 10: //wep 40 Hex type
3579             for(i=0; i < KeyLen; i++)
3580             {
3581                 if( !isxdigit(*(arg+i)) )
3582                     return FALSE;  //Not Hex value;
3583             }
3584             pAdapter->SharedKey[BSS0][3].KeyLen = KeyLen / 2 ;
3585             AtoH(arg, pAdapter->SharedKey[BSS0][3].Key, KeyLen / 2);
3586             CipherAlg = CIPHER_WEP64;
3587             DBGPRINT(RT_DEBUG_TRACE, ("Set_Key4_Proc::(Key4=%s and type=%s)\n", arg, "Hex"));
3588             break;
3589         case 13: //wep 104 Ascii type
3590             pAdapter->SharedKey[BSS0][3].KeyLen = KeyLen;
3591             memcpy(pAdapter->SharedKey[BSS0][3].Key, arg, KeyLen);
3592             CipherAlg = CIPHER_WEP128;
3593             DBGPRINT(RT_DEBUG_TRACE, ("Set_Key4_Proc::(Key4=%s and type=%s)\n", arg, "Ascii"));
3594             break;
3595         case 26: //wep 104 Hex type
3596             for(i=0; i < KeyLen; i++)
3597             {
3598                 if( !isxdigit(*(arg+i)) )
3599                     return FALSE;  //Not Hex value;
3600             }
3601             pAdapter->SharedKey[BSS0][3].KeyLen = KeyLen / 2 ;
3602             AtoH(arg, pAdapter->SharedKey[BSS0][3].Key, KeyLen / 2);
3603             CipherAlg = CIPHER_WEP128;
3604             DBGPRINT(RT_DEBUG_TRACE, ("Set_Key4_Proc::(Key4=%s and type=%s)\n", arg, "Hex"));
3605             break;
3606         default: //Invalid argument
3607             DBGPRINT(RT_DEBUG_TRACE, ("Set_Key4_Proc::Invalid argument (=%s)\n", arg));
3608             return FALSE;
3609     }
3610     pAdapter->SharedKey[BSS0][3].CipherAlg = CipherAlg;
3611
3612     // Set keys (into ASIC)
3613     if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
3614         ;   // not support
3615     else    // Old WEP stuff
3616     {
3617         AsicAddSharedKeyEntry(pAdapter,
3618                               0,
3619                               3,
3620                               pAdapter->SharedKey[BSS0][3].CipherAlg,
3621                               pAdapter->SharedKey[BSS0][3].Key,
3622                               NULL,
3623                               NULL);
3624     }
3625
3626     return TRUE;
3627 }
3628
3629 /*
3630     ==========================================================================
3631     Description:
3632         Set WPA PSK key
3633     Return:
3634         TRUE if all parameters are OK, FALSE otherwise
3635     ==========================================================================
3636 */
3637 INT Set_WPAPSK_Proc(
3638     IN  PRTMP_ADAPTER   pAdapter,
3639     IN  PUCHAR          arg)
3640 {
3641     UCHAR                   keyMaterial[40];
3642
3643     if ((pAdapter->StaCfg.AuthMode != Ndis802_11AuthModeWPAPSK) &&
3644         (pAdapter->StaCfg.AuthMode != Ndis802_11AuthModeWPA2PSK) &&
3645             (pAdapter->StaCfg.AuthMode != Ndis802_11AuthModeWPANone)
3646                 )
3647         return TRUE;    // do nothing
3648
3649     DBGPRINT(RT_DEBUG_TRACE, ("Set_WPAPSK_Proc::(WPAPSK=%s)\n", arg));
3650
3651     NdisZeroMemory(keyMaterial, 40);
3652
3653     if ((strlen(arg) < 8) || (strlen(arg) > 64))
3654     {
3655         DBGPRINT(RT_DEBUG_TRACE, ("Set failed!!(WPAPSK=%s), WPAPSK key-string required 8 ~ 64 characters \n", arg));
3656         return FALSE;
3657     }
3658
3659     if (strlen(arg) == 64)
3660     {
3661         AtoH(arg, keyMaterial, 32);
3662         NdisMoveMemory(pAdapter->StaCfg.PMK, keyMaterial, 32);
3663
3664     }
3665     else
3666     {
3667         PasswordHash((char *)arg, pAdapter->MlmeAux.Ssid, pAdapter->MlmeAux.SsidLen, keyMaterial);
3668         NdisMoveMemory(pAdapter->StaCfg.PMK, keyMaterial, 32);
3669     }
3670
3671
3672
3673     if(pAdapter->StaCfg.BssType == BSS_ADHOC &&
3674        pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
3675     {
3676          pAdapter->StaCfg.WpaState = SS_NOTUSE;
3677     }
3678     else
3679     {
3680         // Start STA supplicant state machine
3681         pAdapter->StaCfg.WpaState = SS_START;
3682     }
3683
3684     return TRUE;
3685 }
3686
3687 /*
3688     ==========================================================================
3689     Description:
3690         Set Power Saving mode
3691     Return:
3692         TRUE if all parameters are OK, FALSE otherwise
3693     ==========================================================================
3694 */
3695 INT Set_PSMode_Proc(
3696     IN  PRTMP_ADAPTER   pAdapter,
3697     IN  PUCHAR          arg)
3698 {
3699     if (pAdapter->StaCfg.BssType == BSS_INFRA)
3700     {
3701         if ((strcmp(arg, "Max_PSP") == 0) ||
3702                         (strcmp(arg, "max_psp") == 0) ||
3703                         (strcmp(arg, "MAX_PSP") == 0))
3704         {
3705             // do NOT turn on PSM bit here, wait until MlmeCheckForPsmChange()
3706             // to exclude certain situations.
3707             if (pAdapter->StaCfg.bWindowsACCAMEnable == FALSE)
3708                 pAdapter->StaCfg.WindowsPowerMode = Ndis802_11PowerModeMAX_PSP;
3709             pAdapter->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeMAX_PSP;
3710             OPSTATUS_SET_FLAG(pAdapter, fOP_STATUS_RECEIVE_DTIM);
3711             pAdapter->StaCfg.DefaultListenCount = 5;
3712
3713         }
3714         else if ((strcmp(arg, "Fast_PSP") == 0) ||
3715                                  (strcmp(arg, "fast_psp") == 0) ||
3716                  (strcmp(arg, "FAST_PSP") == 0))
3717         {
3718             // do NOT turn on PSM bit here, wait until MlmeCheckForPsmChange()
3719             // to exclude certain situations.
3720             OPSTATUS_SET_FLAG(pAdapter, fOP_STATUS_RECEIVE_DTIM);
3721             if (pAdapter->StaCfg.bWindowsACCAMEnable == FALSE)
3722                 pAdapter->StaCfg.WindowsPowerMode = Ndis802_11PowerModeFast_PSP;
3723             pAdapter->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeFast_PSP;
3724             pAdapter->StaCfg.DefaultListenCount = 3;
3725         }
3726         else if ((strcmp(arg, "Legacy_PSP") == 0) ||
3727                  (strcmp(arg, "legacy_psp") == 0) ||
3728                  (strcmp(arg, "LEGACY_PSP") == 0))
3729         {
3730             // do NOT turn on PSM bit here, wait until MlmeCheckForPsmChange()
3731             // to exclude certain situations.
3732             OPSTATUS_SET_FLAG(pAdapter, fOP_STATUS_RECEIVE_DTIM);
3733             if (pAdapter->StaCfg.bWindowsACCAMEnable == FALSE)
3734                 pAdapter->StaCfg.WindowsPowerMode = Ndis802_11PowerModeLegacy_PSP;
3735             pAdapter->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeLegacy_PSP;
3736             pAdapter->StaCfg.DefaultListenCount = 3;
3737         }
3738         else
3739         {
3740             //Default Ndis802_11PowerModeCAM
3741             // clear PSM bit immediately
3742             MlmeSetPsmBit(pAdapter, PWR_ACTIVE);
3743             OPSTATUS_SET_FLAG(pAdapter, fOP_STATUS_RECEIVE_DTIM);
3744             if (pAdapter->StaCfg.bWindowsACCAMEnable == FALSE)
3745                 pAdapter->StaCfg.WindowsPowerMode = Ndis802_11PowerModeCAM;
3746             pAdapter->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeCAM;
3747         }
3748
3749         DBGPRINT(RT_DEBUG_TRACE, ("Set_PSMode_Proc::(PSMode=%ld)\n", pAdapter->StaCfg.WindowsPowerMode));
3750     }
3751     else
3752         return FALSE;
3753
3754
3755     return TRUE;
3756 }
3757
3758 /*
3759     ==========================================================================
3760     Description:
3761         Set WpaSupport flag.
3762     Value:
3763         0: Driver ignore wpa_supplicant.
3764         1: wpa_supplicant initiates scanning and AP selection.
3765         2: driver takes care of scanning, AP selection, and IEEE 802.11 association parameters.
3766     Return:
3767         TRUE if all parameters are OK, FALSE otherwise
3768     ==========================================================================
3769 */
3770 INT Set_Wpa_Support(
3771     IN  PRTMP_ADAPTER   pAd,
3772         IN      PUCHAR                  arg)
3773 {
3774
3775     if ( simple_strtol(arg, 0, 10) == 0)
3776         pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_DISABLE;
3777     else if ( simple_strtol(arg, 0, 10) == 1)
3778         pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_ENABLE;
3779     else if ( simple_strtol(arg, 0, 10) == 2)
3780         pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_ENABLE_WITH_WEB_UI;
3781     else
3782         pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_DISABLE;
3783
3784     DBGPRINT(RT_DEBUG_TRACE, ("Set_Wpa_Support::(WpaSupplicantUP=%d)\n", pAd->StaCfg.WpaSupplicantUP));
3785
3786     return TRUE;
3787 }
3788
3789 INT Set_TGnWifiTest_Proc(
3790     IN  PRTMP_ADAPTER   pAd,
3791     IN  PUCHAR          arg)
3792 {
3793     if (simple_strtol(arg, 0, 10) == 0)
3794         pAd->StaCfg.bTGnWifiTest = FALSE;
3795     else
3796         pAd->StaCfg.bTGnWifiTest = TRUE;
3797
3798     DBGPRINT(RT_DEBUG_TRACE, ("IF Set_TGnWifiTest_Proc::(bTGnWifiTest=%d)\n", pAd->StaCfg.bTGnWifiTest));
3799         return TRUE;
3800 }
3801
3802 INT Set_LongRetryLimit_Proc(
3803         IN      PRTMP_ADAPTER   pAdapter,
3804         IN      PUCHAR                  arg)
3805 {
3806         TX_RTY_CFG_STRUC        tx_rty_cfg;
3807         UCHAR                           LongRetryLimit = (UCHAR)simple_strtol(arg, 0, 10);
3808
3809         RTMP_IO_READ32(pAdapter, TX_RTY_CFG, &tx_rty_cfg.word);
3810         tx_rty_cfg.field.LongRtyLimit = LongRetryLimit;
3811         RTMP_IO_WRITE32(pAdapter, TX_RTY_CFG, tx_rty_cfg.word);
3812         DBGPRINT(RT_DEBUG_TRACE, ("IF Set_LongRetryLimit_Proc::(tx_rty_cfg=0x%x)\n", tx_rty_cfg.word));
3813         return TRUE;
3814 }
3815
3816 INT Set_ShortRetryLimit_Proc(
3817         IN      PRTMP_ADAPTER   pAdapter,
3818         IN      PUCHAR                  arg)
3819 {
3820         TX_RTY_CFG_STRUC        tx_rty_cfg;
3821         UCHAR                           ShortRetryLimit = (UCHAR)simple_strtol(arg, 0, 10);
3822
3823         RTMP_IO_READ32(pAdapter, TX_RTY_CFG, &tx_rty_cfg.word);
3824         tx_rty_cfg.field.ShortRtyLimit = ShortRetryLimit;
3825         RTMP_IO_WRITE32(pAdapter, TX_RTY_CFG, tx_rty_cfg.word);
3826         DBGPRINT(RT_DEBUG_TRACE, ("IF Set_ShortRetryLimit_Proc::(tx_rty_cfg=0x%x)\n", tx_rty_cfg.word));
3827         return TRUE;
3828 }
3829
3830 #if !defined(RT2860) && !defined(RT30xx)
3831 INT     Show_Adhoc_MacTable_Proc(
3832         IN      PRTMP_ADAPTER   pAd,
3833         IN      PCHAR                   extra)
3834 {
3835         INT i;
3836
3837         sprintf(extra, "\n");
3838
3839         sprintf(extra + strlen(extra), "HT Operating Mode : %d\n", pAd->CommonCfg.AddHTInfo.AddHtInfo2.OperaionMode);
3840
3841         sprintf(extra + strlen(extra), "\n%-19s%-4s%-4s%-7s%-7s%-7s%-10s%-6s%-6s%-6s%-6s\n",
3842                         "MAC", "AID", "BSS", "RSSI0", "RSSI1", "RSSI2", "PhMd", "BW", "MCS", "SGI", "STBC");
3843
3844         for (i=1; i<MAX_LEN_OF_MAC_TABLE; i++)
3845         {
3846                 PMAC_TABLE_ENTRY pEntry = &pAd->MacTab.Content[i];
3847
3848                 if (strlen(extra) > (IW_PRIV_SIZE_MASK - 30))
3849                     break;
3850                 if ((pEntry->ValidAsCLI || pEntry->ValidAsApCli) && (pEntry->Sst == SST_ASSOC))
3851                 {
3852                         sprintf(extra + strlen(extra), "%02X:%02X:%02X:%02X:%02X:%02X  ",
3853                                 pEntry->Addr[0], pEntry->Addr[1], pEntry->Addr[2],
3854                                 pEntry->Addr[3], pEntry->Addr[4], pEntry->Addr[5]);
3855                         sprintf(extra + strlen(extra), "%-4d", (int)pEntry->Aid);
3856                         sprintf(extra + strlen(extra), "%-4d", (int)pEntry->apidx);
3857                         sprintf(extra + strlen(extra), "%-7d", pEntry->RssiSample.AvgRssi0);
3858                         sprintf(extra + strlen(extra), "%-7d", pEntry->RssiSample.AvgRssi1);
3859                         sprintf(extra + strlen(extra), "%-7d", pEntry->RssiSample.AvgRssi2);
3860                         sprintf(extra + strlen(extra), "%-10s", GetPhyMode(pEntry->HTPhyMode.field.MODE));
3861                         sprintf(extra + strlen(extra), "%-6s", GetBW(pEntry->HTPhyMode.field.BW));
3862                         sprintf(extra + strlen(extra), "%-6d", pEntry->HTPhyMode.field.MCS);
3863                         sprintf(extra + strlen(extra), "%-6d", pEntry->HTPhyMode.field.ShortGI);
3864                         sprintf(extra + strlen(extra), "%-6d", pEntry->HTPhyMode.field.STBC);
3865                         sprintf(extra + strlen(extra), "%-10d, %d, %d%%\n", pEntry->DebugFIFOCount, pEntry->DebugTxCount,
3866                                                 (pEntry->DebugTxCount) ? ((pEntry->DebugTxCount-pEntry->DebugFIFOCount)*100/pEntry->DebugTxCount) : 0);
3867                         sprintf(extra, "%s\n", extra);
3868                 }
3869         }
3870
3871         return TRUE;
3872 }
3873 #endif /* RT2870 */