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