qlcnic: using too much stack
[wandboard.git] / drivers / staging / rt2860 / sta_ioctl.c
blob6b8268d3dc75a776b190694128fcbb4f43bf342e
1 /*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
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 *************************************************************************
27 Module Name:
28 sta_ioctl.c
30 Abstract:
31 IOCTL related subroutines
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
40 #include "rt_config.h"
42 #ifdef DBG
43 extern unsigned long RTDebugLevel;
44 #endif
46 #define NR_WEP_KEYS 4
47 #define WEP_SMALL_KEY_LEN (40/8)
48 #define WEP_LARGE_KEY_LEN (104/8)
50 #define GROUP_KEY_NO 4
52 extern u8 CipherWpa2Template[];
54 struct PACKED rt_version_info {
55 u8 DriverVersionW;
56 u8 DriverVersionX;
57 u8 DriverVersionY;
58 u8 DriverVersionZ;
59 u32 DriverBuildYear;
60 u32 DriverBuildMonth;
61 u32 DriverBuildDay;
64 static __s32 ralinkrate[] = { 2, 4, 11, 22, /* CCK */
65 12, 18, 24, 36, 48, 72, 96, 108, /* OFDM */
66 13, 26, 39, 52, 78, 104, 117, 130, 26, 52, 78, 104, 156, 208, 234, 260, /* 20MHz, 800ns GI, MCS: 0 ~ 15 */
67 39, 78, 117, 156, 234, 312, 351, 390, /* 20MHz, 800ns GI, MCS: 16 ~ 23 */
68 27, 54, 81, 108, 162, 216, 243, 270, 54, 108, 162, 216, 324, 432, 486, 540, /* 40MHz, 800ns GI, MCS: 0 ~ 15 */
69 81, 162, 243, 324, 486, 648, 729, 810, /* 40MHz, 800ns GI, MCS: 16 ~ 23 */
70 14, 29, 43, 57, 87, 115, 130, 144, 29, 59, 87, 115, 173, 230, 260, 288, /* 20MHz, 400ns GI, MCS: 0 ~ 15 */
71 43, 87, 130, 173, 260, 317, 390, 433, /* 20MHz, 400ns GI, MCS: 16 ~ 23 */
72 30, 60, 90, 120, 180, 240, 270, 300, 60, 120, 180, 240, 360, 480, 540, 600, /* 40MHz, 400ns GI, MCS: 0 ~ 15 */
73 90, 180, 270, 360, 540, 720, 810, 900
76 int Set_SSID_Proc(struct rt_rtmp_adapter *pAdapter, char *arg);
78 int Set_NetworkType_Proc(struct rt_rtmp_adapter *pAdapter, char *arg);
80 void RTMPAddKey(struct rt_rtmp_adapter *pAd, struct rt_ndis_802_11_key *pKey)
82 unsigned long KeyIdx;
83 struct rt_mac_table_entry *pEntry;
85 DBGPRINT(RT_DEBUG_TRACE, ("RTMPAddKey ------>\n"));
87 if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA) {
88 if (pKey->KeyIndex & 0x80000000) {
89 if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone) {
90 NdisZeroMemory(pAd->StaCfg.PMK, 32);
91 NdisMoveMemory(pAd->StaCfg.PMK,
92 pKey->KeyMaterial,
93 pKey->KeyLength);
94 goto end;
96 /* Update PTK */
97 NdisZeroMemory(&pAd->SharedKey[BSS0][0],
98 sizeof(struct rt_cipher_key));
99 pAd->SharedKey[BSS0][0].KeyLen = LEN_TKIP_EK;
100 NdisMoveMemory(pAd->SharedKey[BSS0][0].Key,
101 pKey->KeyMaterial, LEN_TKIP_EK);
103 if (pAd->StaCfg.PairCipher ==
104 Ndis802_11Encryption2Enabled) {
105 NdisMoveMemory(pAd->SharedKey[BSS0][0].RxMic,
106 pKey->KeyMaterial + LEN_TKIP_EK,
107 LEN_TKIP_TXMICK);
108 NdisMoveMemory(pAd->SharedKey[BSS0][0].TxMic,
109 pKey->KeyMaterial + LEN_TKIP_EK +
110 LEN_TKIP_TXMICK,
111 LEN_TKIP_RXMICK);
112 } else {
113 NdisMoveMemory(pAd->SharedKey[BSS0][0].TxMic,
114 pKey->KeyMaterial + LEN_TKIP_EK,
115 LEN_TKIP_TXMICK);
116 NdisMoveMemory(pAd->SharedKey[BSS0][0].RxMic,
117 pKey->KeyMaterial + LEN_TKIP_EK +
118 LEN_TKIP_TXMICK,
119 LEN_TKIP_RXMICK);
122 /* Decide its ChiperAlg */
123 if (pAd->StaCfg.PairCipher ==
124 Ndis802_11Encryption2Enabled)
125 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_TKIP;
126 else if (pAd->StaCfg.PairCipher ==
127 Ndis802_11Encryption3Enabled)
128 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES;
129 else
130 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_NONE;
132 /* Update these related information to struct rt_mac_table_entry */
133 pEntry = &pAd->MacTab.Content[BSSID_WCID];
134 NdisMoveMemory(pEntry->PairwiseKey.Key,
135 pAd->SharedKey[BSS0][0].Key,
136 LEN_TKIP_EK);
137 NdisMoveMemory(pEntry->PairwiseKey.RxMic,
138 pAd->SharedKey[BSS0][0].RxMic,
139 LEN_TKIP_RXMICK);
140 NdisMoveMemory(pEntry->PairwiseKey.TxMic,
141 pAd->SharedKey[BSS0][0].TxMic,
142 LEN_TKIP_TXMICK);
143 pEntry->PairwiseKey.CipherAlg =
144 pAd->SharedKey[BSS0][0].CipherAlg;
146 /* Update pairwise key information to ASIC Shared Key Table */
147 AsicAddSharedKeyEntry(pAd,
148 BSS0,
150 pAd->SharedKey[BSS0][0].CipherAlg,
151 pAd->SharedKey[BSS0][0].Key,
152 pAd->SharedKey[BSS0][0].TxMic,
153 pAd->SharedKey[BSS0][0].RxMic);
155 /* Update ASIC WCID attribute table and IVEIV table */
156 RTMPAddWcidAttributeEntry(pAd,
157 BSS0,
159 pAd->SharedKey[BSS0][0].
160 CipherAlg, pEntry);
162 if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA2) {
163 /* set 802.1x port control */
164 /*pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED; */
165 STA_PORT_SECURED(pAd);
167 /* Indicate Connected for GUI */
168 pAd->IndicateMediaState =
169 NdisMediaStateConnected;
171 } else {
172 /* Update GTK */
173 pAd->StaCfg.DefaultKeyId = (pKey->KeyIndex & 0xFF);
174 NdisZeroMemory(&pAd->
175 SharedKey[BSS0][pAd->StaCfg.
176 DefaultKeyId],
177 sizeof(struct rt_cipher_key));
178 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].KeyLen =
179 LEN_TKIP_EK;
180 NdisMoveMemory(pAd->
181 SharedKey[BSS0][pAd->StaCfg.
182 DefaultKeyId].Key,
183 pKey->KeyMaterial, LEN_TKIP_EK);
185 if (pAd->StaCfg.GroupCipher ==
186 Ndis802_11Encryption2Enabled) {
187 NdisMoveMemory(pAd->
188 SharedKey[BSS0][pAd->StaCfg.
189 DefaultKeyId].
190 RxMic,
191 pKey->KeyMaterial + LEN_TKIP_EK,
192 LEN_TKIP_TXMICK);
193 NdisMoveMemory(pAd->
194 SharedKey[BSS0][pAd->StaCfg.
195 DefaultKeyId].
196 TxMic,
197 pKey->KeyMaterial + LEN_TKIP_EK +
198 LEN_TKIP_TXMICK,
199 LEN_TKIP_RXMICK);
200 } else {
201 NdisMoveMemory(pAd->
202 SharedKey[BSS0][pAd->StaCfg.
203 DefaultKeyId].
204 TxMic,
205 pKey->KeyMaterial + LEN_TKIP_EK,
206 LEN_TKIP_TXMICK);
207 NdisMoveMemory(pAd->
208 SharedKey[BSS0][pAd->StaCfg.
209 DefaultKeyId].
210 RxMic,
211 pKey->KeyMaterial + LEN_TKIP_EK +
212 LEN_TKIP_TXMICK,
213 LEN_TKIP_RXMICK);
216 /* Update Shared Key CipherAlg */
217 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].
218 CipherAlg = CIPHER_NONE;
219 if (pAd->StaCfg.GroupCipher ==
220 Ndis802_11Encryption2Enabled)
221 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].
222 CipherAlg = CIPHER_TKIP;
223 else if (pAd->StaCfg.GroupCipher ==
224 Ndis802_11Encryption3Enabled)
225 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].
226 CipherAlg = CIPHER_AES;
228 /* Update group key information to ASIC Shared Key Table */
229 AsicAddSharedKeyEntry(pAd,
230 BSS0,
231 pAd->StaCfg.DefaultKeyId,
232 pAd->SharedKey[BSS0][pAd->StaCfg.
233 DefaultKeyId].
234 CipherAlg,
235 pAd->SharedKey[BSS0][pAd->StaCfg.
236 DefaultKeyId].
237 Key,
238 pAd->SharedKey[BSS0][pAd->StaCfg.
239 DefaultKeyId].
240 TxMic,
241 pAd->SharedKey[BSS0][pAd->StaCfg.
242 DefaultKeyId].
243 RxMic);
245 /* Update ASIC WCID attribute table and IVEIV table */
246 RTMPAddWcidAttributeEntry(pAd,
247 BSS0,
248 pAd->StaCfg.DefaultKeyId,
249 pAd->SharedKey[BSS0][pAd->
250 StaCfg.
251 DefaultKeyId].
252 CipherAlg, NULL);
254 /* set 802.1x port control */
255 /*pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED; */
256 STA_PORT_SECURED(pAd);
258 /* Indicate Connected for GUI */
259 pAd->IndicateMediaState = NdisMediaStateConnected;
261 } else /* dynamic WEP from wpa_supplicant */
263 u8 CipherAlg;
264 u8 *Key;
266 if (pKey->KeyLength == 32)
267 goto end;
269 KeyIdx = pKey->KeyIndex & 0x0fffffff;
271 if (KeyIdx < 4) {
272 /* it is a default shared key, for Pairwise key setting */
273 if (pKey->KeyIndex & 0x80000000) {
274 pEntry = MacTableLookup(pAd, pKey->BSSID);
276 if (pEntry) {
277 DBGPRINT(RT_DEBUG_TRACE,
278 ("RTMPAddKey: Set Pair-wise Key\n"));
280 /* set key material and key length */
281 pEntry->PairwiseKey.KeyLen =
282 (u8)pKey->KeyLength;
283 NdisMoveMemory(pEntry->PairwiseKey.Key,
284 &pKey->KeyMaterial,
285 pKey->KeyLength);
287 /* set Cipher type */
288 if (pKey->KeyLength == 5)
289 pEntry->PairwiseKey.CipherAlg =
290 CIPHER_WEP64;
291 else
292 pEntry->PairwiseKey.CipherAlg =
293 CIPHER_WEP128;
295 /* Add Pair-wise key to Asic */
296 AsicAddPairwiseKeyEntry(pAd,
297 pEntry->Addr,
298 (u8)pEntry->
299 Aid,
300 &pEntry->
301 PairwiseKey);
303 /* update WCID attribute table and IVEIV table for this entry */
304 RTMPAddWcidAttributeEntry(pAd, BSS0, KeyIdx, /* The value may be not zero */
305 pEntry->
306 PairwiseKey.
307 CipherAlg,
308 pEntry);
311 } else {
312 /* Default key for tx (shared key) */
313 pAd->StaCfg.DefaultKeyId = (u8)KeyIdx;
315 /* set key material and key length */
316 pAd->SharedKey[BSS0][KeyIdx].KeyLen =
317 (u8)pKey->KeyLength;
318 NdisMoveMemory(pAd->SharedKey[BSS0][KeyIdx].Key,
319 &pKey->KeyMaterial,
320 pKey->KeyLength);
322 /* Set Ciper type */
323 if (pKey->KeyLength == 5)
324 pAd->SharedKey[BSS0][KeyIdx].CipherAlg =
325 CIPHER_WEP64;
326 else
327 pAd->SharedKey[BSS0][KeyIdx].CipherAlg =
328 CIPHER_WEP128;
330 CipherAlg =
331 pAd->SharedKey[BSS0][KeyIdx].CipherAlg;
332 Key = pAd->SharedKey[BSS0][KeyIdx].Key;
334 /* Set Group key material to Asic */
335 AsicAddSharedKeyEntry(pAd, BSS0, KeyIdx,
336 CipherAlg, Key, NULL,
337 NULL);
339 /* Update WCID attribute table and IVEIV table for this group key table */
340 RTMPAddWcidAttributeEntry(pAd, BSS0, KeyIdx,
341 CipherAlg, NULL);
346 end:
347 return;
350 char *rtstrchr(const char *s, int c)
352 for (; *s != (char)c; ++s)
353 if (*s == '\0')
354 return NULL;
355 return (char *)s;
359 This is required for LinEX2004/kernel2.6.7 to provide iwlist scanning function
363 rt_ioctl_giwname(struct net_device *dev,
364 struct iw_request_info *info, char *name, char *extra)
366 strncpy(name, "Ralink STA", IFNAMSIZ);
367 /* RT2870 2.1.0.0 uses "RT2870 Wireless" */
368 /* RT3090 2.1.0.0 uses "RT2860 Wireless" */
369 return 0;
372 int rt_ioctl_siwfreq(struct net_device *dev,
373 struct iw_request_info *info,
374 struct iw_freq *freq, char *extra)
376 struct rt_rtmp_adapter *pAdapter = NULL;
377 int chan = -1;
379 GET_PAD_FROM_NET_DEV(pAdapter, dev);
381 /*check if the interface is down */
382 if (!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE)) {
383 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
384 return -ENETDOWN;
387 if (freq->e > 1)
388 return -EINVAL;
390 if ((freq->e == 0) && (freq->m <= 1000))
391 chan = freq->m; /* Setting by channel number */
392 else
393 MAP_KHZ_TO_CHANNEL_ID((freq->m / 100), chan); /* Setting by frequency - search the table , like 2.412G, 2.422G, */
395 if (ChannelSanity(pAdapter, chan) == TRUE) {
396 pAdapter->CommonCfg.Channel = chan;
397 DBGPRINT(RT_DEBUG_ERROR,
398 ("==>rt_ioctl_siwfreq::SIOCSIWFREQ[cmd=0x%x] (Channel=%d)\n",
399 SIOCSIWFREQ, pAdapter->CommonCfg.Channel));
400 } else
401 return -EINVAL;
403 return 0;
406 int rt_ioctl_giwfreq(struct net_device *dev,
407 struct iw_request_info *info,
408 struct iw_freq *freq, char *extra)
410 struct rt_rtmp_adapter *pAdapter = NULL;
411 u8 ch;
412 unsigned long m = 2412000;
414 GET_PAD_FROM_NET_DEV(pAdapter, dev);
416 ch = pAdapter->CommonCfg.Channel;
418 DBGPRINT(RT_DEBUG_TRACE, ("==>rt_ioctl_giwfreq %d\n", ch));
420 MAP_CHANNEL_ID_TO_KHZ(ch, m);
421 freq->m = m * 100;
422 freq->e = 1;
423 return 0;
426 int rt_ioctl_siwmode(struct net_device *dev,
427 struct iw_request_info *info, __u32 * mode, char *extra)
429 struct rt_rtmp_adapter *pAdapter = NULL;
431 GET_PAD_FROM_NET_DEV(pAdapter, dev);
433 /*check if the interface is down */
434 if (!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE)) {
435 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
436 return -ENETDOWN;
439 switch (*mode) {
440 case IW_MODE_ADHOC:
441 Set_NetworkType_Proc(pAdapter, "Adhoc");
442 break;
443 case IW_MODE_INFRA:
444 Set_NetworkType_Proc(pAdapter, "Infra");
445 break;
446 case IW_MODE_MONITOR:
447 Set_NetworkType_Proc(pAdapter, "Monitor");
448 break;
449 default:
450 DBGPRINT(RT_DEBUG_TRACE,
451 ("===>rt_ioctl_siwmode::SIOCSIWMODE (unknown %d)\n",
452 *mode));
453 return -EINVAL;
456 /* Reset Ralink supplicant to not use, it will be set to start when UI set PMK key */
457 pAdapter->StaCfg.WpaState = SS_NOTUSE;
459 return 0;
462 int rt_ioctl_giwmode(struct net_device *dev,
463 struct iw_request_info *info, __u32 * mode, char *extra)
465 struct rt_rtmp_adapter *pAdapter = NULL;
467 GET_PAD_FROM_NET_DEV(pAdapter, dev);
469 if (ADHOC_ON(pAdapter))
470 *mode = IW_MODE_ADHOC;
471 else if (INFRA_ON(pAdapter))
472 *mode = IW_MODE_INFRA;
473 else if (MONITOR_ON(pAdapter)) {
474 *mode = IW_MODE_MONITOR;
475 } else
476 *mode = IW_MODE_AUTO;
478 DBGPRINT(RT_DEBUG_TRACE, ("==>rt_ioctl_giwmode(mode=%d)\n", *mode));
479 return 0;
482 int rt_ioctl_siwsens(struct net_device *dev,
483 struct iw_request_info *info, char *name, char *extra)
485 struct rt_rtmp_adapter *pAdapter = NULL;
487 GET_PAD_FROM_NET_DEV(pAdapter, dev);
489 /*check if the interface is down */
490 if (!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE)) {
491 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
492 return -ENETDOWN;
495 return 0;
498 int rt_ioctl_giwsens(struct net_device *dev,
499 struct iw_request_info *info, char *name, char *extra)
501 return 0;
504 int rt_ioctl_giwrange(struct net_device *dev,
505 struct iw_request_info *info,
506 struct iw_point *data, char *extra)
508 struct rt_rtmp_adapter *pAdapter = NULL;
509 struct iw_range *range = (struct iw_range *)extra;
510 u16 val;
511 int i;
513 GET_PAD_FROM_NET_DEV(pAdapter, dev);
515 DBGPRINT(RT_DEBUG_TRACE, ("===>rt_ioctl_giwrange\n"));
516 data->length = sizeof(struct iw_range);
517 memset(range, 0, sizeof(struct iw_range));
519 range->txpower_capa = IW_TXPOW_DBM;
521 if (INFRA_ON(pAdapter) || ADHOC_ON(pAdapter)) {
522 range->min_pmp = 1 * 1024;
523 range->max_pmp = 65535 * 1024;
524 range->min_pmt = 1 * 1024;
525 range->max_pmt = 1000 * 1024;
526 range->pmp_flags = IW_POWER_PERIOD;
527 range->pmt_flags = IW_POWER_TIMEOUT;
528 range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT |
529 IW_POWER_UNICAST_R | IW_POWER_ALL_R;
532 range->we_version_compiled = WIRELESS_EXT;
533 range->we_version_source = 14;
535 range->retry_capa = IW_RETRY_LIMIT;
536 range->retry_flags = IW_RETRY_LIMIT;
537 range->min_retry = 0;
538 range->max_retry = 255;
540 range->num_channels = pAdapter->ChannelListNum;
542 val = 0;
543 for (i = 1; i <= range->num_channels; i++) {
544 u32 m = 2412000;
545 range->freq[val].i = pAdapter->ChannelList[i - 1].Channel;
546 MAP_CHANNEL_ID_TO_KHZ(pAdapter->ChannelList[i - 1].Channel, m);
547 range->freq[val].m = m * 100; /* OS_HZ */
549 range->freq[val].e = 1;
550 val++;
551 if (val == IW_MAX_FREQUENCIES)
552 break;
554 range->num_frequency = val;
556 range->max_qual.qual = 100; /* what is correct max? This was not
557 * documented exactly. At least
558 * 69 has been observed. */
559 range->max_qual.level = 0; /* dB */
560 range->max_qual.noise = 0; /* dB */
562 /* What would be suitable values for "average/typical" qual? */
563 range->avg_qual.qual = 20;
564 range->avg_qual.level = -60;
565 range->avg_qual.noise = -95;
566 range->sensitivity = 3;
568 range->max_encoding_tokens = NR_WEP_KEYS;
569 range->num_encoding_sizes = 2;
570 range->encoding_size[0] = 5;
571 range->encoding_size[1] = 13;
573 range->min_rts = 0;
574 range->max_rts = 2347;
575 range->min_frag = 256;
576 range->max_frag = 2346;
578 /* IW_ENC_CAPA_* bit field */
579 range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
580 IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
582 return 0;
585 int rt_ioctl_siwap(struct net_device *dev,
586 struct iw_request_info *info,
587 struct sockaddr *ap_addr, char *extra)
589 struct rt_rtmp_adapter *pAdapter = NULL;
590 NDIS_802_11_MAC_ADDRESS Bssid;
592 GET_PAD_FROM_NET_DEV(pAdapter, dev);
594 /*check if the interface is down */
595 if (!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE)) {
596 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
597 return -ENETDOWN;
600 if (pAdapter->Mlme.CntlMachine.CurrState != CNTL_IDLE) {
601 RTMP_MLME_RESET_STATE_MACHINE(pAdapter);
602 DBGPRINT(RT_DEBUG_TRACE,
603 ("MLME busy, reset MLME state machine!\n"));
605 /* tell CNTL state machine to call NdisMSetInformationComplete() after completing */
606 /* this request, because this request is initiated by NDIS. */
607 pAdapter->MlmeAux.CurrReqIsFromNdis = FALSE;
608 /* Prevent to connect AP again in STAMlmePeriodicExec */
609 pAdapter->MlmeAux.AutoReconnectSsidLen = 32;
611 memcpy(Bssid, ap_addr->sa_data, MAC_ADDR_LEN);
612 MlmeEnqueue(pAdapter,
613 MLME_CNTL_STATE_MACHINE,
614 OID_802_11_BSSID,
615 sizeof(NDIS_802_11_MAC_ADDRESS), (void *) & Bssid);
617 DBGPRINT(RT_DEBUG_TRACE,
618 ("IOCTL::SIOCSIWAP %02x:%02x:%02x:%02x:%02x:%02x\n", Bssid[0],
619 Bssid[1], Bssid[2], Bssid[3], Bssid[4], Bssid[5]));
621 return 0;
624 int rt_ioctl_giwap(struct net_device *dev,
625 struct iw_request_info *info,
626 struct sockaddr *ap_addr, char *extra)
628 struct rt_rtmp_adapter *pAdapter = NULL;
630 GET_PAD_FROM_NET_DEV(pAdapter, dev);
632 if (INFRA_ON(pAdapter) || ADHOC_ON(pAdapter)) {
633 ap_addr->sa_family = ARPHRD_ETHER;
634 memcpy(ap_addr->sa_data, &pAdapter->CommonCfg.Bssid, ETH_ALEN);
636 /* Add for RT2870 */
637 else if (pAdapter->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE) {
638 ap_addr->sa_family = ARPHRD_ETHER;
639 memcpy(ap_addr->sa_data, &pAdapter->MlmeAux.Bssid, ETH_ALEN);
640 } else {
641 DBGPRINT(RT_DEBUG_TRACE, ("IOCTL::SIOCGIWAP(=EMPTY)\n"));
642 return -ENOTCONN;
645 return 0;
649 * Units are in db above the noise floor. That means the
650 * rssi values reported in the tx/rx descriptors in the
651 * driver are the SNR expressed in db.
653 * If you assume that the noise floor is -95, which is an
654 * excellent assumption 99.5 % of the time, then you can
655 * derive the absolute signal level (i.e. -95 + rssi).
656 * There are some other slight factors to take into account
657 * depending on whether the rssi measurement is from 11b,
658 * 11g, or 11a. These differences are at most 2db and
659 * can be documented.
661 * NB: various calculations are based on the orinoco/wavelan
662 * drivers for compatibility
664 static void set_quality(struct rt_rtmp_adapter *pAdapter,
665 struct iw_quality *iq, signed char rssi)
667 __u8 ChannelQuality;
669 /* Normalize Rssi */
670 if (rssi >= -50)
671 ChannelQuality = 100;
672 else if (rssi >= -80) /* between -50 ~ -80dbm */
673 ChannelQuality = (__u8) (24 + ((rssi + 80) * 26) / 10);
674 else if (rssi >= -90) /* between -80 ~ -90dbm */
675 ChannelQuality = (__u8) ((rssi + 90) * 26) / 10;
676 else
677 ChannelQuality = 0;
679 iq->qual = (__u8) ChannelQuality;
681 iq->level = (__u8) (rssi);
682 iq->noise = (pAdapter->BbpWriteLatch[66] > pAdapter->BbpTuning.FalseCcaUpperThreshold) ? ((__u8) pAdapter->BbpTuning.FalseCcaUpperThreshold) : ((__u8) pAdapter->BbpWriteLatch[66]); /* noise level (dBm) */
683 iq->noise += 256 - 143;
684 iq->updated = pAdapter->iw_stats.qual.updated;
687 int rt_ioctl_iwaplist(struct net_device *dev,
688 struct iw_request_info *info,
689 struct iw_point *data, char *extra)
691 struct rt_rtmp_adapter *pAdapter = NULL;
693 struct sockaddr addr[IW_MAX_AP];
694 struct iw_quality qual[IW_MAX_AP];
695 int i;
697 GET_PAD_FROM_NET_DEV(pAdapter, dev);
699 /*check if the interface is down */
700 if (!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE)) {
701 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
702 data->length = 0;
703 return 0;
704 /*return -ENETDOWN; */
707 for (i = 0; i < IW_MAX_AP; i++) {
708 if (i >= pAdapter->ScanTab.BssNr)
709 break;
710 addr[i].sa_family = ARPHRD_ETHER;
711 memcpy(addr[i].sa_data, &pAdapter->ScanTab.BssEntry[i].Bssid,
712 MAC_ADDR_LEN);
713 set_quality(pAdapter, &qual[i],
714 pAdapter->ScanTab.BssEntry[i].Rssi);
716 data->length = i;
717 memcpy(extra, &addr, i * sizeof(addr[0]));
718 data->flags = 1; /* signal quality present (sort of) */
719 memcpy(extra + i * sizeof(addr[0]), &qual, i * sizeof(qual[i]));
721 return 0;
724 int rt_ioctl_siwscan(struct net_device *dev,
725 struct iw_request_info *info,
726 struct iw_point *data, char *extra)
728 struct rt_rtmp_adapter *pAdapter = NULL;
730 unsigned long Now;
731 int Status = NDIS_STATUS_SUCCESS;
733 GET_PAD_FROM_NET_DEV(pAdapter, dev);
735 /*check if the interface is down */
736 if (!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE)) {
737 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
738 return -ENETDOWN;
741 if (MONITOR_ON(pAdapter)) {
742 DBGPRINT(RT_DEBUG_TRACE,
743 ("Driver is in Monitor Mode now!\n"));
744 return -EINVAL;
747 if (pAdapter->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_ENABLE) {
748 pAdapter->StaCfg.WpaSupplicantScanCount++;
751 pAdapter->StaCfg.bScanReqIsFromWebUI = TRUE;
752 if (RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
753 return NDIS_STATUS_SUCCESS;
754 do {
755 Now = jiffies;
757 if ((pAdapter->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_ENABLE)
758 && (pAdapter->StaCfg.WpaSupplicantScanCount > 3)) {
759 DBGPRINT(RT_DEBUG_TRACE,
760 ("WpaSupplicantScanCount > 3\n"));
761 Status = NDIS_STATUS_SUCCESS;
762 break;
765 if ((OPSTATUS_TEST_FLAG
766 (pAdapter, fOP_STATUS_MEDIA_STATE_CONNECTED))
767 && ((pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPA)
768 || (pAdapter->StaCfg.AuthMode ==
769 Ndis802_11AuthModeWPAPSK))
770 && (pAdapter->StaCfg.PortSecured ==
771 WPA_802_1X_PORT_NOT_SECURED)) {
772 DBGPRINT(RT_DEBUG_TRACE,
773 ("Link UP, Port Not Secured! ignore this set::OID_802_11_BSSID_LIST_SCAN\n"));
774 Status = NDIS_STATUS_SUCCESS;
775 break;
778 if (pAdapter->Mlme.CntlMachine.CurrState != CNTL_IDLE) {
779 RTMP_MLME_RESET_STATE_MACHINE(pAdapter);
780 DBGPRINT(RT_DEBUG_TRACE,
781 ("MLME busy, reset MLME state machine!\n"));
783 /* tell CNTL state machine to call NdisMSetInformationComplete() after completing */
784 /* this request, because this request is initiated by NDIS. */
785 pAdapter->MlmeAux.CurrReqIsFromNdis = FALSE;
786 /* Reset allowed scan retries */
787 pAdapter->StaCfg.ScanCnt = 0;
788 pAdapter->StaCfg.LastScanTime = Now;
790 MlmeEnqueue(pAdapter,
791 MLME_CNTL_STATE_MACHINE,
792 OID_802_11_BSSID_LIST_SCAN, 0, NULL);
794 Status = NDIS_STATUS_SUCCESS;
795 RTMP_MLME_HANDLER(pAdapter);
796 } while (0);
797 return NDIS_STATUS_SUCCESS;
800 int rt_ioctl_giwscan(struct net_device *dev,
801 struct iw_request_info *info,
802 struct iw_point *data, char *extra)
804 struct rt_rtmp_adapter *pAdapter = NULL;
805 int i = 0;
806 char *current_ev = extra, *previous_ev = extra;
807 char *end_buf;
808 char *current_val;
809 char custom[MAX_CUSTOM_LEN] = { 0 };
810 struct iw_event iwe;
812 GET_PAD_FROM_NET_DEV(pAdapter, dev);
814 if (RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) {
816 * Still scanning, indicate the caller should try again.
818 return -EAGAIN;
821 if (pAdapter->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_ENABLE) {
822 pAdapter->StaCfg.WpaSupplicantScanCount = 0;
825 if (pAdapter->ScanTab.BssNr == 0) {
826 data->length = 0;
827 return 0;
830 if (data->length > 0)
831 end_buf = extra + data->length;
832 else
833 end_buf = extra + IW_SCAN_MAX_DATA;
835 for (i = 0; i < pAdapter->ScanTab.BssNr; i++) {
836 if (current_ev >= end_buf) {
837 return -E2BIG;
839 /*MAC address */
840 /*================================ */
841 memset(&iwe, 0, sizeof(iwe));
842 iwe.cmd = SIOCGIWAP;
843 iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
844 memcpy(iwe.u.ap_addr.sa_data,
845 &pAdapter->ScanTab.BssEntry[i].Bssid, ETH_ALEN);
847 previous_ev = current_ev;
848 current_ev =
849 iwe_stream_add_event(info, current_ev, end_buf, &iwe,
850 IW_EV_ADDR_LEN);
851 if (current_ev == previous_ev)
852 return -E2BIG;
855 Protocol:
856 it will show scanned AP's WirelessMode .
857 it might be
858 802.11a
859 802.11a/n
860 802.11g/n
861 802.11b/g/n
862 802.11g
863 802.11b/g
865 memset(&iwe, 0, sizeof(iwe));
866 iwe.cmd = SIOCGIWNAME;
869 struct rt_bss_entry *pBssEntry = &pAdapter->ScanTab.BssEntry[i];
870 BOOLEAN isGonly = FALSE;
871 int rateCnt = 0;
873 if (pBssEntry->Channel > 14) {
874 if (pBssEntry->HtCapabilityLen != 0)
875 strcpy(iwe.u.name, "802.11a/n");
876 else
877 strcpy(iwe.u.name, "802.11a");
878 } else {
880 if one of non B mode rate is set supported rate . it mean G only.
882 for (rateCnt = 0;
883 rateCnt < pBssEntry->SupRateLen;
884 rateCnt++) {
886 6Mbps(140) 9Mbps(146) and >=12Mbps(152) are supported rate , it mean G only.
888 if (pBssEntry->SupRate[rateCnt] == 140
889 || pBssEntry->SupRate[rateCnt] ==
891 || pBssEntry->SupRate[rateCnt] >=
892 152)
893 isGonly = TRUE;
896 for (rateCnt = 0;
897 rateCnt < pBssEntry->ExtRateLen;
898 rateCnt++) {
899 if (pBssEntry->ExtRate[rateCnt] == 140
900 || pBssEntry->ExtRate[rateCnt] ==
902 || pBssEntry->ExtRate[rateCnt] >=
903 152)
904 isGonly = TRUE;
907 if (pBssEntry->HtCapabilityLen != 0) {
908 if (isGonly == TRUE)
909 strcpy(iwe.u.name, "802.11g/n");
910 else
911 strcpy(iwe.u.name,
912 "802.11b/g/n");
913 } else {
914 if (isGonly == TRUE)
915 strcpy(iwe.u.name, "802.11g");
916 else {
917 if (pBssEntry->SupRateLen == 4
918 && pBssEntry->ExtRateLen ==
920 strcpy(iwe.u.name,
921 "802.11b");
922 else
923 strcpy(iwe.u.name,
924 "802.11b/g");
930 previous_ev = current_ev;
931 current_ev =
932 iwe_stream_add_event(info, current_ev, end_buf, &iwe,
933 IW_EV_ADDR_LEN);
934 if (current_ev == previous_ev)
935 return -E2BIG;
937 /*ESSID */
938 /*================================ */
939 memset(&iwe, 0, sizeof(iwe));
940 iwe.cmd = SIOCGIWESSID;
941 iwe.u.data.length = pAdapter->ScanTab.BssEntry[i].SsidLen;
942 iwe.u.data.flags = 1;
944 previous_ev = current_ev;
945 current_ev =
946 iwe_stream_add_point(info, current_ev, end_buf, &iwe,
947 (char *)pAdapter->ScanTab.
948 BssEntry[i].Ssid);
949 if (current_ev == previous_ev)
950 return -E2BIG;
952 /*Network Type */
953 /*================================ */
954 memset(&iwe, 0, sizeof(iwe));
955 iwe.cmd = SIOCGIWMODE;
956 if (pAdapter->ScanTab.BssEntry[i].BssType == Ndis802_11IBSS) {
957 iwe.u.mode = IW_MODE_ADHOC;
958 } else if (pAdapter->ScanTab.BssEntry[i].BssType ==
959 Ndis802_11Infrastructure) {
960 iwe.u.mode = IW_MODE_INFRA;
961 } else {
962 iwe.u.mode = IW_MODE_AUTO;
964 iwe.len = IW_EV_UINT_LEN;
966 previous_ev = current_ev;
967 current_ev =
968 iwe_stream_add_event(info, current_ev, end_buf, &iwe,
969 IW_EV_UINT_LEN);
970 if (current_ev == previous_ev)
971 return -E2BIG;
973 /*Channel and Frequency */
974 /*================================ */
975 memset(&iwe, 0, sizeof(iwe));
976 iwe.cmd = SIOCGIWFREQ;
977 iwe.u.freq.m = pAdapter->ScanTab.BssEntry[i].Channel;
978 iwe.u.freq.e = 0;
979 iwe.u.freq.i = 0;
981 previous_ev = current_ev;
982 current_ev =
983 iwe_stream_add_event(info, current_ev, end_buf, &iwe,
984 IW_EV_FREQ_LEN);
985 if (current_ev == previous_ev)
986 return -E2BIG;
988 /*Add quality statistics */
989 /*================================ */
990 memset(&iwe, 0, sizeof(iwe));
991 iwe.cmd = IWEVQUAL;
992 iwe.u.qual.level = 0;
993 iwe.u.qual.noise = 0;
994 set_quality(pAdapter, &iwe.u.qual,
995 pAdapter->ScanTab.BssEntry[i].Rssi);
996 current_ev =
997 iwe_stream_add_event(info, current_ev, end_buf, &iwe,
998 IW_EV_QUAL_LEN);
999 if (current_ev == previous_ev)
1000 return -E2BIG;
1002 /*Encyption key */
1003 /*================================ */
1004 memset(&iwe, 0, sizeof(iwe));
1005 iwe.cmd = SIOCGIWENCODE;
1006 if (CAP_IS_PRIVACY_ON
1007 (pAdapter->ScanTab.BssEntry[i].CapabilityInfo))
1008 iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
1009 else
1010 iwe.u.data.flags = IW_ENCODE_DISABLED;
1012 previous_ev = current_ev;
1013 current_ev =
1014 iwe_stream_add_point(info, current_ev, end_buf, &iwe,
1015 (char *)pAdapter->
1016 SharedKey[BSS0][(iwe.u.data.
1017 flags &
1018 IW_ENCODE_INDEX) -
1019 1].Key);
1020 if (current_ev == previous_ev)
1021 return -E2BIG;
1023 /*Bit Rate */
1024 /*================================ */
1025 if (pAdapter->ScanTab.BssEntry[i].SupRateLen) {
1026 u8 tmpRate =
1027 pAdapter->ScanTab.BssEntry[i].SupRate[pAdapter->
1028 ScanTab.
1029 BssEntry[i].
1030 SupRateLen -
1032 memset(&iwe, 0, sizeof(iwe));
1033 iwe.cmd = SIOCGIWRATE;
1034 current_val = current_ev + IW_EV_LCP_LEN;
1035 if (tmpRate == 0x82)
1036 iwe.u.bitrate.value = 1 * 1000000;
1037 else if (tmpRate == 0x84)
1038 iwe.u.bitrate.value = 2 * 1000000;
1039 else if (tmpRate == 0x8B)
1040 iwe.u.bitrate.value = 5.5 * 1000000;
1041 else if (tmpRate == 0x96)
1042 iwe.u.bitrate.value = 11 * 1000000;
1043 else
1044 iwe.u.bitrate.value = (tmpRate / 2) * 1000000;
1046 if (tmpRate == 0x6c
1047 && pAdapter->ScanTab.BssEntry[i].HtCapabilityLen >
1048 0) {
1049 int rate_count = ARRAY_SIZE(ralinkrate);
1050 struct rt_ht_cap_info capInfo =
1051 pAdapter->ScanTab.BssEntry[i].HtCapability.
1052 HtCapInfo;
1053 int shortGI =
1054 capInfo.ChannelWidth ? capInfo.
1055 ShortGIfor40 : capInfo.ShortGIfor20;
1056 int maxMCS =
1057 pAdapter->ScanTab.BssEntry[i].HtCapability.
1058 MCSSet[1] ? 15 : 7;
1059 int rate_index =
1060 12 + ((u8)capInfo.ChannelWidth * 24) +
1061 ((u8)shortGI * 48) + ((u8)maxMCS);
1063 if (rate_index < 0)
1064 rate_index = 0;
1065 if (rate_index >= rate_count)
1066 rate_index = rate_count - 1;
1067 iwe.u.bitrate.value =
1068 ralinkrate[rate_index] * 500000;
1071 iwe.u.bitrate.disabled = 0;
1072 current_val = iwe_stream_add_value(info, current_ev,
1073 current_val, end_buf,
1074 &iwe,
1075 IW_EV_PARAM_LEN);
1077 if ((current_val - current_ev) > IW_EV_LCP_LEN)
1078 current_ev = current_val;
1079 else
1080 return -E2BIG;
1082 /*WPA IE */
1083 if (pAdapter->ScanTab.BssEntry[i].WpaIE.IELen > 0) {
1084 memset(&iwe, 0, sizeof(iwe));
1085 memset(&custom[0], 0, MAX_CUSTOM_LEN);
1086 memcpy(custom,
1087 &(pAdapter->ScanTab.BssEntry[i].WpaIE.IE[0]),
1088 pAdapter->ScanTab.BssEntry[i].WpaIE.IELen);
1089 iwe.cmd = IWEVGENIE;
1090 iwe.u.data.length =
1091 pAdapter->ScanTab.BssEntry[i].WpaIE.IELen;
1092 current_ev =
1093 iwe_stream_add_point(info, current_ev, end_buf,
1094 &iwe, custom);
1095 if (current_ev == previous_ev)
1096 return -E2BIG;
1098 /*WPA2 IE */
1099 if (pAdapter->ScanTab.BssEntry[i].RsnIE.IELen > 0) {
1100 memset(&iwe, 0, sizeof(iwe));
1101 memset(&custom[0], 0, MAX_CUSTOM_LEN);
1102 memcpy(custom,
1103 &(pAdapter->ScanTab.BssEntry[i].RsnIE.IE[0]),
1104 pAdapter->ScanTab.BssEntry[i].RsnIE.IELen);
1105 iwe.cmd = IWEVGENIE;
1106 iwe.u.data.length =
1107 pAdapter->ScanTab.BssEntry[i].RsnIE.IELen;
1108 current_ev =
1109 iwe_stream_add_point(info, current_ev, end_buf,
1110 &iwe, custom);
1111 if (current_ev == previous_ev)
1112 return -E2BIG;
1116 data->length = current_ev - extra;
1117 pAdapter->StaCfg.bScanReqIsFromWebUI = FALSE;
1118 DBGPRINT(RT_DEBUG_ERROR,
1119 ("===>rt_ioctl_giwscan. %d(%d) BSS returned, data->length = %d\n",
1120 i, pAdapter->ScanTab.BssNr, data->length));
1121 return 0;
1124 int rt_ioctl_siwessid(struct net_device *dev,
1125 struct iw_request_info *info,
1126 struct iw_point *data, char *essid)
1128 struct rt_rtmp_adapter *pAdapter = NULL;
1130 GET_PAD_FROM_NET_DEV(pAdapter, dev);
1132 /*check if the interface is down */
1133 if (!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE)) {
1134 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
1135 return -ENETDOWN;
1138 if (data->flags) {
1139 char *pSsidString = NULL;
1141 /* Includes null character. */
1142 if (data->length > (IW_ESSID_MAX_SIZE + 1))
1143 return -E2BIG;
1145 pSsidString = kmalloc(MAX_LEN_OF_SSID + 1, MEM_ALLOC_FLAG);
1146 if (pSsidString) {
1147 NdisZeroMemory(pSsidString, MAX_LEN_OF_SSID + 1);
1148 NdisMoveMemory(pSsidString, essid, data->length);
1149 if (Set_SSID_Proc(pAdapter, pSsidString) == FALSE)
1150 return -EINVAL;
1151 } else
1152 return -ENOMEM;
1153 } else {
1154 /* ANY ssid */
1155 if (Set_SSID_Proc(pAdapter, "") == FALSE)
1156 return -EINVAL;
1158 return 0;
1161 int rt_ioctl_giwessid(struct net_device *dev,
1162 struct iw_request_info *info,
1163 struct iw_point *data, char *essid)
1165 struct rt_rtmp_adapter *pAdapter = NULL;
1167 GET_PAD_FROM_NET_DEV(pAdapter, dev);
1169 data->flags = 1;
1170 if (MONITOR_ON(pAdapter)) {
1171 data->length = 0;
1172 return 0;
1175 if (OPSTATUS_TEST_FLAG(pAdapter, fOP_STATUS_MEDIA_STATE_CONNECTED)) {
1176 DBGPRINT(RT_DEBUG_TRACE, ("MediaState is connected\n"));
1177 data->length = pAdapter->CommonCfg.SsidLen;
1178 memcpy(essid, pAdapter->CommonCfg.Ssid,
1179 pAdapter->CommonCfg.SsidLen);
1181 #ifdef RTMP_MAC_USB
1182 /* Add for RT2870 */
1183 else if (pAdapter->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE) {
1184 data->length = pAdapter->CommonCfg.SsidLen;
1185 memcpy(essid, pAdapter->CommonCfg.Ssid,
1186 pAdapter->CommonCfg.SsidLen);
1188 #endif /* RTMP_MAC_USB // */
1189 else { /*the ANY ssid was specified */
1190 data->length = 0;
1191 DBGPRINT(RT_DEBUG_TRACE,
1192 ("MediaState is not connected, ess\n"));
1195 return 0;
1199 int rt_ioctl_siwnickn(struct net_device *dev,
1200 struct iw_request_info *info,
1201 struct iw_point *data, char *nickname)
1203 struct rt_rtmp_adapter *pAdapter = NULL;
1205 GET_PAD_FROM_NET_DEV(pAdapter, dev);
1207 /*check if the interface is down */
1208 if (!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE)) {
1209 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
1210 return -ENETDOWN;
1213 if (data->length > IW_ESSID_MAX_SIZE)
1214 return -EINVAL;
1216 memset(pAdapter->nickname, 0, IW_ESSID_MAX_SIZE + 1);
1217 memcpy(pAdapter->nickname, nickname, data->length);
1219 return 0;
1222 int rt_ioctl_giwnickn(struct net_device *dev,
1223 struct iw_request_info *info,
1224 struct iw_point *data, char *nickname)
1226 struct rt_rtmp_adapter *pAdapter = NULL;
1228 GET_PAD_FROM_NET_DEV(pAdapter, dev);
1230 if (data->length > strlen((char *)pAdapter->nickname) + 1)
1231 data->length = strlen((char *)pAdapter->nickname) + 1;
1232 if (data->length > 0) {
1233 memcpy(nickname, pAdapter->nickname, data->length - 1);
1234 nickname[data->length - 1] = '\0';
1236 return 0;
1239 int rt_ioctl_siwrts(struct net_device *dev,
1240 struct iw_request_info *info,
1241 struct iw_param *rts, char *extra)
1243 struct rt_rtmp_adapter *pAdapter = NULL;
1244 u16 val;
1246 GET_PAD_FROM_NET_DEV(pAdapter, dev);
1248 /*check if the interface is down */
1249 if (!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE)) {
1250 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
1251 return -ENETDOWN;
1254 if (rts->disabled)
1255 val = MAX_RTS_THRESHOLD;
1256 else if (rts->value < 0 || rts->value > MAX_RTS_THRESHOLD)
1257 return -EINVAL;
1258 else if (rts->value == 0)
1259 val = MAX_RTS_THRESHOLD;
1260 else
1261 val = rts->value;
1263 if (val != pAdapter->CommonCfg.RtsThreshold)
1264 pAdapter->CommonCfg.RtsThreshold = val;
1266 return 0;
1269 int rt_ioctl_giwrts(struct net_device *dev,
1270 struct iw_request_info *info,
1271 struct iw_param *rts, char *extra)
1273 struct rt_rtmp_adapter *pAdapter = NULL;
1275 GET_PAD_FROM_NET_DEV(pAdapter, dev);
1277 /*check if the interface is down */
1278 if (!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE)) {
1279 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
1280 return -ENETDOWN;
1283 rts->value = pAdapter->CommonCfg.RtsThreshold;
1284 rts->disabled = (rts->value == MAX_RTS_THRESHOLD);
1285 rts->fixed = 1;
1287 return 0;
1290 int rt_ioctl_siwfrag(struct net_device *dev,
1291 struct iw_request_info *info,
1292 struct iw_param *frag, char *extra)
1294 struct rt_rtmp_adapter *pAdapter = NULL;
1295 u16 val;
1297 GET_PAD_FROM_NET_DEV(pAdapter, dev);
1299 /*check if the interface is down */
1300 if (!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE)) {
1301 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
1302 return -ENETDOWN;
1305 if (frag->disabled)
1306 val = MAX_FRAG_THRESHOLD;
1307 else if (frag->value >= MIN_FRAG_THRESHOLD
1308 && frag->value <= MAX_FRAG_THRESHOLD)
1309 val = __cpu_to_le16(frag->value & ~0x1); /* even numbers only */
1310 else if (frag->value == 0)
1311 val = MAX_FRAG_THRESHOLD;
1312 else
1313 return -EINVAL;
1315 pAdapter->CommonCfg.FragmentThreshold = val;
1316 return 0;
1319 int rt_ioctl_giwfrag(struct net_device *dev,
1320 struct iw_request_info *info,
1321 struct iw_param *frag, char *extra)
1323 struct rt_rtmp_adapter *pAdapter = NULL;
1325 GET_PAD_FROM_NET_DEV(pAdapter, dev);
1327 /*check if the interface is down */
1328 if (!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE)) {
1329 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
1330 return -ENETDOWN;
1333 frag->value = pAdapter->CommonCfg.FragmentThreshold;
1334 frag->disabled = (frag->value == MAX_FRAG_THRESHOLD);
1335 frag->fixed = 1;
1337 return 0;
1340 #define MAX_WEP_KEY_SIZE 13
1341 #define MIN_WEP_KEY_SIZE 5
1342 int rt_ioctl_siwencode(struct net_device *dev,
1343 struct iw_request_info *info,
1344 struct iw_point *erq, char *extra)
1346 struct rt_rtmp_adapter *pAdapter = NULL;
1348 GET_PAD_FROM_NET_DEV(pAdapter, dev);
1350 /*check if the interface is down */
1351 if (!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE)) {
1352 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
1353 return -ENETDOWN;
1356 if ((erq->length == 0) && (erq->flags & IW_ENCODE_DISABLED)) {
1357 pAdapter->StaCfg.PairCipher = Ndis802_11WEPDisabled;
1358 pAdapter->StaCfg.GroupCipher = Ndis802_11WEPDisabled;
1359 pAdapter->StaCfg.WepStatus = Ndis802_11WEPDisabled;
1360 pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
1361 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
1362 goto done;
1363 } else if (erq->flags & IW_ENCODE_RESTRICTED
1364 || erq->flags & IW_ENCODE_OPEN) {
1365 /*pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED; */
1366 STA_PORT_SECURED(pAdapter);
1367 pAdapter->StaCfg.PairCipher = Ndis802_11WEPEnabled;
1368 pAdapter->StaCfg.GroupCipher = Ndis802_11WEPEnabled;
1369 pAdapter->StaCfg.WepStatus = Ndis802_11WEPEnabled;
1370 pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
1371 if (erq->flags & IW_ENCODE_RESTRICTED)
1372 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeShared;
1373 else
1374 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
1377 if (erq->length > 0) {
1378 int keyIdx = (erq->flags & IW_ENCODE_INDEX) - 1;
1379 /* Check the size of the key */
1380 if (erq->length > MAX_WEP_KEY_SIZE) {
1381 return -EINVAL;
1383 /* Check key index */
1384 if ((keyIdx < 0) || (keyIdx >= NR_WEP_KEYS)) {
1385 DBGPRINT(RT_DEBUG_TRACE,
1386 ("==>rt_ioctl_siwencode::Wrong keyIdx=%d! Using default key instead (%d)\n",
1387 keyIdx, pAdapter->StaCfg.DefaultKeyId));
1389 /*Using default key */
1390 keyIdx = pAdapter->StaCfg.DefaultKeyId;
1391 } else
1392 pAdapter->StaCfg.DefaultKeyId = keyIdx;
1394 NdisZeroMemory(pAdapter->SharedKey[BSS0][keyIdx].Key, 16);
1396 if (erq->length == MAX_WEP_KEY_SIZE) {
1397 pAdapter->SharedKey[BSS0][keyIdx].KeyLen =
1398 MAX_WEP_KEY_SIZE;
1399 pAdapter->SharedKey[BSS0][keyIdx].CipherAlg =
1400 CIPHER_WEP128;
1401 } else if (erq->length == MIN_WEP_KEY_SIZE) {
1402 pAdapter->SharedKey[BSS0][keyIdx].KeyLen =
1403 MIN_WEP_KEY_SIZE;
1404 pAdapter->SharedKey[BSS0][keyIdx].CipherAlg =
1405 CIPHER_WEP64;
1406 } else
1407 /* Disable the key */
1408 pAdapter->SharedKey[BSS0][keyIdx].KeyLen = 0;
1410 /* Check if the key is not marked as invalid */
1411 if (!(erq->flags & IW_ENCODE_NOKEY)) {
1412 /* Copy the key in the driver */
1413 NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].Key,
1414 extra, erq->length);
1416 } else {
1417 /* Do we want to just set the transmit key index ? */
1418 int index = (erq->flags & IW_ENCODE_INDEX) - 1;
1419 if ((index >= 0) && (index < 4)) {
1420 pAdapter->StaCfg.DefaultKeyId = index;
1421 } else
1422 /* Don't complain if only change the mode */
1423 if (!(erq->flags & IW_ENCODE_MODE))
1424 return -EINVAL;
1427 done:
1428 DBGPRINT(RT_DEBUG_TRACE,
1429 ("==>rt_ioctl_siwencode::erq->flags=%x\n", erq->flags));
1430 DBGPRINT(RT_DEBUG_TRACE,
1431 ("==>rt_ioctl_siwencode::AuthMode=%x\n",
1432 pAdapter->StaCfg.AuthMode));
1433 DBGPRINT(RT_DEBUG_TRACE,
1434 ("==>rt_ioctl_siwencode::DefaultKeyId=%x, KeyLen = %d\n",
1435 pAdapter->StaCfg.DefaultKeyId,
1436 pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].
1437 KeyLen));
1438 DBGPRINT(RT_DEBUG_TRACE,
1439 ("==>rt_ioctl_siwencode::WepStatus=%x\n",
1440 pAdapter->StaCfg.WepStatus));
1441 return 0;
1445 rt_ioctl_giwencode(struct net_device *dev,
1446 struct iw_request_info *info,
1447 struct iw_point *erq, char *key)
1449 int kid;
1450 struct rt_rtmp_adapter *pAdapter = NULL;
1452 GET_PAD_FROM_NET_DEV(pAdapter, dev);
1454 /*check if the interface is down */
1455 if (!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE)) {
1456 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
1457 return -ENETDOWN;
1460 kid = erq->flags & IW_ENCODE_INDEX;
1461 DBGPRINT(RT_DEBUG_TRACE,
1462 ("===>rt_ioctl_giwencode %d\n", erq->flags & IW_ENCODE_INDEX));
1464 if (pAdapter->StaCfg.WepStatus == Ndis802_11WEPDisabled) {
1465 erq->length = 0;
1466 erq->flags = IW_ENCODE_DISABLED;
1467 } else if ((kid > 0) && (kid <= 4)) {
1468 /* copy wep key */
1469 erq->flags = kid; /* NB: base 1 */
1470 if (erq->length > pAdapter->SharedKey[BSS0][kid - 1].KeyLen)
1471 erq->length = pAdapter->SharedKey[BSS0][kid - 1].KeyLen;
1472 memcpy(key, pAdapter->SharedKey[BSS0][kid - 1].Key,
1473 erq->length);
1474 /*if ((kid == pAdapter->PortCfg.DefaultKeyId)) */
1475 /*erq->flags |= IW_ENCODE_ENABLED; */ /* XXX */
1476 if (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeShared)
1477 erq->flags |= IW_ENCODE_RESTRICTED; /* XXX */
1478 else
1479 erq->flags |= IW_ENCODE_OPEN; /* XXX */
1481 } else if (kid == 0) {
1482 if (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeShared)
1483 erq->flags |= IW_ENCODE_RESTRICTED; /* XXX */
1484 else
1485 erq->flags |= IW_ENCODE_OPEN; /* XXX */
1486 erq->length =
1487 pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].
1488 KeyLen;
1489 memcpy(key,
1490 pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].
1491 Key, erq->length);
1492 /* copy default key ID */
1493 if (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeShared)
1494 erq->flags |= IW_ENCODE_RESTRICTED; /* XXX */
1495 else
1496 erq->flags |= IW_ENCODE_OPEN; /* XXX */
1497 erq->flags = pAdapter->StaCfg.DefaultKeyId + 1; /* NB: base 1 */
1498 erq->flags |= IW_ENCODE_ENABLED; /* XXX */
1501 return 0;
1505 void getBaInfo(struct rt_rtmp_adapter *pAd, char *pOutBuf)
1507 int i, j;
1508 struct rt_ba_ori_entry *pOriBAEntry;
1509 struct rt_ba_rec_entry *pRecBAEntry;
1511 for (i = 0; i < MAX_LEN_OF_MAC_TABLE; i++) {
1512 struct rt_mac_table_entry *pEntry = &pAd->MacTab.Content[i];
1513 if (((pEntry->ValidAsCLI || pEntry->ValidAsApCli)
1514 && (pEntry->Sst == SST_ASSOC))
1515 || (pEntry->ValidAsWDS) || (pEntry->ValidAsMesh)) {
1516 sprintf(pOutBuf + strlen(pOutBuf),
1517 "\n%02X:%02X:%02X:%02X:%02X:%02X (Aid = %d) (AP) -\n",
1518 pEntry->Addr[0], pEntry->Addr[1],
1519 pEntry->Addr[2], pEntry->Addr[3],
1520 pEntry->Addr[4], pEntry->Addr[5], pEntry->Aid);
1522 sprintf(pOutBuf, "%s[Recipient]\n", pOutBuf);
1523 for (j = 0; j < NUM_OF_TID; j++) {
1524 if (pEntry->BARecWcidArray[j] != 0) {
1525 pRecBAEntry =
1526 &pAd->BATable.BARecEntry[pEntry->
1527 BARecWcidArray
1528 [j]];
1529 sprintf(pOutBuf + strlen(pOutBuf),
1530 "TID=%d, BAWinSize=%d, LastIndSeq=%d, ReorderingPkts=%d\n",
1531 j, pRecBAEntry->BAWinSize,
1532 pRecBAEntry->LastIndSeq,
1533 pRecBAEntry->list.qlen);
1536 sprintf(pOutBuf, "%s\n", pOutBuf);
1538 sprintf(pOutBuf, "%s[Originator]\n", pOutBuf);
1539 for (j = 0; j < NUM_OF_TID; j++) {
1540 if (pEntry->BAOriWcidArray[j] != 0) {
1541 pOriBAEntry =
1542 &pAd->BATable.BAOriEntry[pEntry->
1543 BAOriWcidArray
1544 [j]];
1545 sprintf(pOutBuf + strlen(pOutBuf),
1546 "TID=%d, BAWinSize=%d, StartSeq=%d, CurTxSeq=%d\n",
1547 j, pOriBAEntry->BAWinSize,
1548 pOriBAEntry->Sequence,
1549 pEntry->TxSeq[j]);
1552 sprintf(pOutBuf, "%s\n\n", pOutBuf);
1554 if (strlen(pOutBuf) > (IW_PRIV_SIZE_MASK - 30))
1555 break;
1558 return;
1561 int rt_ioctl_siwmlme(struct net_device *dev,
1562 struct iw_request_info *info,
1563 union iwreq_data *wrqu, char *extra)
1565 struct rt_rtmp_adapter *pAd = NULL;
1566 struct iw_mlme *pMlme = (struct iw_mlme *)wrqu->data.pointer;
1567 struct rt_mlme_queue_elem MsgElem;
1568 struct rt_mlme_disassoc_req DisAssocReq;
1569 struct rt_mlme_deauth_req DeAuthReq;
1571 GET_PAD_FROM_NET_DEV(pAd, dev);
1573 DBGPRINT(RT_DEBUG_TRACE, ("====> %s\n", __func__));
1575 if (pMlme == NULL)
1576 return -EINVAL;
1578 switch (pMlme->cmd) {
1579 #ifdef IW_MLME_DEAUTH
1580 case IW_MLME_DEAUTH:
1581 DBGPRINT(RT_DEBUG_TRACE,
1582 ("====> %s - IW_MLME_DEAUTH\n", __func__));
1583 COPY_MAC_ADDR(DeAuthReq.Addr, pAd->CommonCfg.Bssid);
1584 DeAuthReq.Reason = pMlme->reason_code;
1585 MsgElem.MsgLen = sizeof(struct rt_mlme_deauth_req);
1586 NdisMoveMemory(MsgElem.Msg, &DeAuthReq,
1587 sizeof(struct rt_mlme_deauth_req));
1588 MlmeDeauthReqAction(pAd, &MsgElem);
1589 if (INFRA_ON(pAd)) {
1590 LinkDown(pAd, FALSE);
1591 pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
1593 break;
1594 #endif /* IW_MLME_DEAUTH // */
1595 #ifdef IW_MLME_DISASSOC
1596 case IW_MLME_DISASSOC:
1597 DBGPRINT(RT_DEBUG_TRACE,
1598 ("====> %s - IW_MLME_DISASSOC\n", __func__));
1599 COPY_MAC_ADDR(DisAssocReq.Addr, pAd->CommonCfg.Bssid);
1600 DisAssocReq.Reason = pMlme->reason_code;
1602 MsgElem.Machine = ASSOC_STATE_MACHINE;
1603 MsgElem.MsgType = MT2_MLME_DISASSOC_REQ;
1604 MsgElem.MsgLen = sizeof(struct rt_mlme_disassoc_req);
1605 NdisMoveMemory(MsgElem.Msg, &DisAssocReq,
1606 sizeof(struct rt_mlme_disassoc_req));
1608 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_DISASSOC;
1609 MlmeDisassocReqAction(pAd, &MsgElem);
1610 break;
1611 #endif /* IW_MLME_DISASSOC // */
1612 default:
1613 DBGPRINT(RT_DEBUG_TRACE,
1614 ("====> %s - Unknow Command\n", __func__));
1615 break;
1618 return 0;
1621 int rt_ioctl_siwauth(struct net_device *dev,
1622 struct iw_request_info *info,
1623 union iwreq_data *wrqu, char *extra)
1625 struct rt_rtmp_adapter *pAdapter = NULL;
1626 struct iw_param *param = &wrqu->param;
1628 GET_PAD_FROM_NET_DEV(pAdapter, dev);
1630 /*check if the interface is down */
1631 if (!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE)) {
1632 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
1633 return -ENETDOWN;
1635 switch (param->flags & IW_AUTH_INDEX) {
1636 case IW_AUTH_WPA_VERSION:
1637 if (param->value == IW_AUTH_WPA_VERSION_WPA) {
1638 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPAPSK;
1639 if (pAdapter->StaCfg.BssType == BSS_ADHOC)
1640 pAdapter->StaCfg.AuthMode =
1641 Ndis802_11AuthModeWPANone;
1642 } else if (param->value == IW_AUTH_WPA_VERSION_WPA2)
1643 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPA2PSK;
1645 DBGPRINT(RT_DEBUG_TRACE,
1646 ("%s::IW_AUTH_WPA_VERSION - param->value = %d!\n",
1647 __func__, param->value));
1648 break;
1649 case IW_AUTH_CIPHER_PAIRWISE:
1650 if (param->value == IW_AUTH_CIPHER_NONE) {
1651 pAdapter->StaCfg.WepStatus = Ndis802_11WEPDisabled;
1652 pAdapter->StaCfg.OrigWepStatus =
1653 pAdapter->StaCfg.WepStatus;
1654 pAdapter->StaCfg.PairCipher = Ndis802_11WEPDisabled;
1655 } else if (param->value == IW_AUTH_CIPHER_WEP40 ||
1656 param->value == IW_AUTH_CIPHER_WEP104) {
1657 pAdapter->StaCfg.WepStatus = Ndis802_11WEPEnabled;
1658 pAdapter->StaCfg.OrigWepStatus =
1659 pAdapter->StaCfg.WepStatus;
1660 pAdapter->StaCfg.PairCipher = Ndis802_11WEPEnabled;
1661 pAdapter->StaCfg.IEEE8021X = FALSE;
1662 } else if (param->value == IW_AUTH_CIPHER_TKIP) {
1663 pAdapter->StaCfg.WepStatus =
1664 Ndis802_11Encryption2Enabled;
1665 pAdapter->StaCfg.OrigWepStatus =
1666 pAdapter->StaCfg.WepStatus;
1667 pAdapter->StaCfg.PairCipher =
1668 Ndis802_11Encryption2Enabled;
1669 } else if (param->value == IW_AUTH_CIPHER_CCMP) {
1670 pAdapter->StaCfg.WepStatus =
1671 Ndis802_11Encryption3Enabled;
1672 pAdapter->StaCfg.OrigWepStatus =
1673 pAdapter->StaCfg.WepStatus;
1674 pAdapter->StaCfg.PairCipher =
1675 Ndis802_11Encryption3Enabled;
1677 DBGPRINT(RT_DEBUG_TRACE,
1678 ("%s::IW_AUTH_CIPHER_PAIRWISE - param->value = %d!\n",
1679 __func__, param->value));
1680 break;
1681 case IW_AUTH_CIPHER_GROUP:
1682 if (param->value == IW_AUTH_CIPHER_NONE) {
1683 pAdapter->StaCfg.GroupCipher = Ndis802_11WEPDisabled;
1684 } else if (param->value == IW_AUTH_CIPHER_WEP40 ||
1685 param->value == IW_AUTH_CIPHER_WEP104) {
1686 pAdapter->StaCfg.GroupCipher = Ndis802_11WEPEnabled;
1687 } else if (param->value == IW_AUTH_CIPHER_TKIP) {
1688 pAdapter->StaCfg.GroupCipher =
1689 Ndis802_11Encryption2Enabled;
1690 } else if (param->value == IW_AUTH_CIPHER_CCMP) {
1691 pAdapter->StaCfg.GroupCipher =
1692 Ndis802_11Encryption3Enabled;
1694 DBGPRINT(RT_DEBUG_TRACE,
1695 ("%s::IW_AUTH_CIPHER_GROUP - param->value = %d!\n",
1696 __func__, param->value));
1697 break;
1698 case IW_AUTH_KEY_MGMT:
1699 if (param->value == IW_AUTH_KEY_MGMT_802_1X) {
1700 if (pAdapter->StaCfg.AuthMode ==
1701 Ndis802_11AuthModeWPAPSK) {
1702 pAdapter->StaCfg.AuthMode =
1703 Ndis802_11AuthModeWPA;
1704 pAdapter->StaCfg.IEEE8021X = FALSE;
1705 } else if (pAdapter->StaCfg.AuthMode ==
1706 Ndis802_11AuthModeWPA2PSK) {
1707 pAdapter->StaCfg.AuthMode =
1708 Ndis802_11AuthModeWPA2;
1709 pAdapter->StaCfg.IEEE8021X = FALSE;
1710 } else
1711 /* WEP 1x */
1712 pAdapter->StaCfg.IEEE8021X = TRUE;
1713 } else if (param->value == 0) {
1714 /*pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED; */
1715 STA_PORT_SECURED(pAdapter);
1717 DBGPRINT(RT_DEBUG_TRACE,
1718 ("%s::IW_AUTH_KEY_MGMT - param->value = %d!\n",
1719 __func__, param->value));
1720 break;
1721 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
1722 break;
1723 case IW_AUTH_PRIVACY_INVOKED:
1724 /*if (param->value == 0)
1726 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
1727 pAdapter->StaCfg.WepStatus = Ndis802_11WEPDisabled;
1728 pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
1729 pAdapter->StaCfg.PairCipher = Ndis802_11WEPDisabled;
1730 pAdapter->StaCfg.GroupCipher = Ndis802_11WEPDisabled;
1731 } */
1732 DBGPRINT(RT_DEBUG_TRACE,
1733 ("%s::IW_AUTH_PRIVACY_INVOKED - param->value = %d!\n",
1734 __func__, param->value));
1735 break;
1736 case IW_AUTH_DROP_UNENCRYPTED:
1737 if (param->value != 0)
1738 pAdapter->StaCfg.PortSecured =
1739 WPA_802_1X_PORT_NOT_SECURED;
1740 else {
1741 /*pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED; */
1742 STA_PORT_SECURED(pAdapter);
1744 DBGPRINT(RT_DEBUG_TRACE,
1745 ("%s::IW_AUTH_WPA_VERSION - param->value = %d!\n",
1746 __func__, param->value));
1747 break;
1748 case IW_AUTH_80211_AUTH_ALG:
1749 if (param->value & IW_AUTH_ALG_SHARED_KEY) {
1750 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeShared;
1751 } else if (param->value & IW_AUTH_ALG_OPEN_SYSTEM) {
1752 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
1753 } else
1754 return -EINVAL;
1755 DBGPRINT(RT_DEBUG_TRACE,
1756 ("%s::IW_AUTH_80211_AUTH_ALG - param->value = %d!\n",
1757 __func__, param->value));
1758 break;
1759 case IW_AUTH_WPA_ENABLED:
1760 DBGPRINT(RT_DEBUG_TRACE,
1761 ("%s::IW_AUTH_WPA_ENABLED - Driver supports WPA!(param->value = %d)\n",
1762 __func__, param->value));
1763 break;
1764 default:
1765 return -EOPNOTSUPP;
1768 return 0;
1771 int rt_ioctl_giwauth(struct net_device *dev,
1772 struct iw_request_info *info,
1773 union iwreq_data *wrqu, char *extra)
1775 struct rt_rtmp_adapter *pAdapter = NULL;
1776 struct iw_param *param = &wrqu->param;
1778 GET_PAD_FROM_NET_DEV(pAdapter, dev);
1780 /*check if the interface is down */
1781 if (!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE)) {
1782 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
1783 return -ENETDOWN;
1786 switch (param->flags & IW_AUTH_INDEX) {
1787 case IW_AUTH_DROP_UNENCRYPTED:
1788 param->value =
1789 (pAdapter->StaCfg.WepStatus ==
1790 Ndis802_11WEPDisabled) ? 0 : 1;
1791 break;
1793 case IW_AUTH_80211_AUTH_ALG:
1794 param->value =
1795 (pAdapter->StaCfg.AuthMode ==
1796 Ndis802_11AuthModeShared) ? IW_AUTH_ALG_SHARED_KEY :
1797 IW_AUTH_ALG_OPEN_SYSTEM;
1798 break;
1800 case IW_AUTH_WPA_ENABLED:
1801 param->value =
1802 (pAdapter->StaCfg.AuthMode >=
1803 Ndis802_11AuthModeWPA) ? 1 : 0;
1804 break;
1806 default:
1807 return -EOPNOTSUPP;
1809 DBGPRINT(RT_DEBUG_TRACE,
1810 ("rt_ioctl_giwauth::param->value = %d!\n", param->value));
1811 return 0;
1814 void fnSetCipherKey(struct rt_rtmp_adapter *pAdapter,
1815 int keyIdx,
1816 u8 CipherAlg,
1817 IN BOOLEAN bGTK, IN struct iw_encode_ext *ext)
1819 NdisZeroMemory(&pAdapter->SharedKey[BSS0][keyIdx], sizeof(struct rt_cipher_key));
1820 pAdapter->SharedKey[BSS0][keyIdx].KeyLen = LEN_TKIP_EK;
1821 NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].Key, ext->key,
1822 LEN_TKIP_EK);
1823 NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].TxMic,
1824 ext->key + LEN_TKIP_EK, LEN_TKIP_TXMICK);
1825 NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].RxMic,
1826 ext->key + LEN_TKIP_EK + LEN_TKIP_TXMICK,
1827 LEN_TKIP_RXMICK);
1828 pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = CipherAlg;
1830 /* Update group key information to ASIC Shared Key Table */
1831 AsicAddSharedKeyEntry(pAdapter,
1832 BSS0,
1833 keyIdx,
1834 pAdapter->SharedKey[BSS0][keyIdx].CipherAlg,
1835 pAdapter->SharedKey[BSS0][keyIdx].Key,
1836 pAdapter->SharedKey[BSS0][keyIdx].TxMic,
1837 pAdapter->SharedKey[BSS0][keyIdx].RxMic);
1839 if (bGTK)
1840 /* Update ASIC WCID attribute table and IVEIV table */
1841 RTMPAddWcidAttributeEntry(pAdapter,
1842 BSS0,
1843 keyIdx,
1844 pAdapter->SharedKey[BSS0][keyIdx].
1845 CipherAlg, NULL);
1846 else
1847 /* Update ASIC WCID attribute table and IVEIV table */
1848 RTMPAddWcidAttributeEntry(pAdapter,
1849 BSS0,
1850 keyIdx,
1851 pAdapter->SharedKey[BSS0][keyIdx].
1852 CipherAlg,
1853 &pAdapter->MacTab.
1854 Content[BSSID_WCID]);
1857 int rt_ioctl_siwencodeext(struct net_device *dev,
1858 struct iw_request_info *info,
1859 union iwreq_data *wrqu, char *extra)
1861 struct rt_rtmp_adapter *pAdapter = NULL;
1862 struct iw_point *encoding = &wrqu->encoding;
1863 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
1864 int keyIdx, alg = ext->alg;
1866 GET_PAD_FROM_NET_DEV(pAdapter, dev);
1868 /*check if the interface is down */
1869 if (!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE)) {
1870 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
1871 return -ENETDOWN;
1874 if (encoding->flags & IW_ENCODE_DISABLED) {
1875 keyIdx = (encoding->flags & IW_ENCODE_INDEX) - 1;
1876 /* set BSSID wcid entry of the Pair-wise Key table as no-security mode */
1877 AsicRemovePairwiseKeyEntry(pAdapter, BSS0, BSSID_WCID);
1878 pAdapter->SharedKey[BSS0][keyIdx].KeyLen = 0;
1879 pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = CIPHER_NONE;
1880 AsicRemoveSharedKeyEntry(pAdapter, 0, (u8)keyIdx);
1881 NdisZeroMemory(&pAdapter->SharedKey[BSS0][keyIdx],
1882 sizeof(struct rt_cipher_key));
1883 DBGPRINT(RT_DEBUG_TRACE,
1884 ("%s::Remove all keys!(encoding->flags = %x)\n",
1885 __func__, encoding->flags));
1886 } else {
1887 /* Get Key Index and convet to our own defined key index */
1888 keyIdx = (encoding->flags & IW_ENCODE_INDEX) - 1;
1889 if ((keyIdx < 0) || (keyIdx >= NR_WEP_KEYS))
1890 return -EINVAL;
1892 if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
1893 pAdapter->StaCfg.DefaultKeyId = keyIdx;
1894 DBGPRINT(RT_DEBUG_TRACE,
1895 ("%s::DefaultKeyId = %d\n", __func__,
1896 pAdapter->StaCfg.DefaultKeyId));
1899 switch (alg) {
1900 case IW_ENCODE_ALG_NONE:
1901 DBGPRINT(RT_DEBUG_TRACE,
1902 ("%s::IW_ENCODE_ALG_NONE\n", __func__));
1903 break;
1904 case IW_ENCODE_ALG_WEP:
1905 DBGPRINT(RT_DEBUG_TRACE,
1906 ("%s::IW_ENCODE_ALG_WEP - ext->key_len = %d, keyIdx = %d\n",
1907 __func__, ext->key_len, keyIdx));
1908 if (ext->key_len == MAX_WEP_KEY_SIZE) {
1909 pAdapter->SharedKey[BSS0][keyIdx].KeyLen =
1910 MAX_WEP_KEY_SIZE;
1911 pAdapter->SharedKey[BSS0][keyIdx].CipherAlg =
1912 CIPHER_WEP128;
1913 } else if (ext->key_len == MIN_WEP_KEY_SIZE) {
1914 pAdapter->SharedKey[BSS0][keyIdx].KeyLen =
1915 MIN_WEP_KEY_SIZE;
1916 pAdapter->SharedKey[BSS0][keyIdx].CipherAlg =
1917 CIPHER_WEP64;
1918 } else
1919 return -EINVAL;
1921 NdisZeroMemory(pAdapter->SharedKey[BSS0][keyIdx].Key,
1922 16);
1923 NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].Key,
1924 ext->key, ext->key_len);
1925 if (pAdapter->StaCfg.GroupCipher ==
1926 Ndis802_11GroupWEP40Enabled
1927 || pAdapter->StaCfg.GroupCipher ==
1928 Ndis802_11GroupWEP104Enabled) {
1929 /* Set Group key material to Asic */
1930 AsicAddSharedKeyEntry(pAdapter, BSS0, keyIdx,
1931 pAdapter->
1932 SharedKey[BSS0][keyIdx].
1933 CipherAlg,
1934 pAdapter->
1935 SharedKey[BSS0][keyIdx].
1936 Key, NULL, NULL);
1938 /* Update WCID attribute table and IVEIV table for this group key table */
1939 RTMPAddWcidAttributeEntry(pAdapter, BSS0,
1940 keyIdx,
1941 pAdapter->
1942 SharedKey[BSS0]
1943 [keyIdx].CipherAlg,
1944 NULL);
1946 STA_PORT_SECURED(pAdapter);
1948 /* Indicate Connected for GUI */
1949 pAdapter->IndicateMediaState =
1950 NdisMediaStateConnected;
1952 break;
1953 case IW_ENCODE_ALG_TKIP:
1954 DBGPRINT(RT_DEBUG_TRACE,
1955 ("%s::IW_ENCODE_ALG_TKIP - keyIdx = %d, ext->key_len = %d\n",
1956 __func__, keyIdx, ext->key_len));
1957 if (ext->key_len == 32) {
1958 if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
1959 fnSetCipherKey(pAdapter, keyIdx,
1960 CIPHER_TKIP, FALSE, ext);
1961 if (pAdapter->StaCfg.AuthMode >=
1962 Ndis802_11AuthModeWPA2) {
1963 /*pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED; */
1964 STA_PORT_SECURED(pAdapter);
1965 pAdapter->IndicateMediaState =
1966 NdisMediaStateConnected;
1968 } else if (ext->
1969 ext_flags & IW_ENCODE_EXT_GROUP_KEY)
1971 fnSetCipherKey(pAdapter, keyIdx,
1972 CIPHER_TKIP, TRUE, ext);
1974 /* set 802.1x port control */
1975 /*pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED; */
1976 STA_PORT_SECURED(pAdapter);
1977 pAdapter->IndicateMediaState =
1978 NdisMediaStateConnected;
1980 } else
1981 return -EINVAL;
1982 break;
1983 case IW_ENCODE_ALG_CCMP:
1984 if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
1985 fnSetCipherKey(pAdapter, keyIdx, CIPHER_AES,
1986 FALSE, ext);
1987 if (pAdapter->StaCfg.AuthMode >=
1988 Ndis802_11AuthModeWPA2)
1989 /*pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED; */
1990 STA_PORT_SECURED(pAdapter);
1991 pAdapter->IndicateMediaState =
1992 NdisMediaStateConnected;
1993 } else if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
1994 fnSetCipherKey(pAdapter, keyIdx, CIPHER_AES,
1995 TRUE, ext);
1997 /* set 802.1x port control */
1998 /*pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED; */
1999 STA_PORT_SECURED(pAdapter);
2000 pAdapter->IndicateMediaState =
2001 NdisMediaStateConnected;
2003 break;
2004 default:
2005 return -EINVAL;
2009 return 0;
2013 rt_ioctl_giwencodeext(struct net_device *dev,
2014 struct iw_request_info *info,
2015 union iwreq_data *wrqu, char *extra)
2017 struct rt_rtmp_adapter *pAd = NULL;
2018 char *pKey = NULL;
2019 struct iw_point *encoding = &wrqu->encoding;
2020 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
2021 int idx, max_key_len;
2023 GET_PAD_FROM_NET_DEV(pAd, dev);
2025 DBGPRINT(RT_DEBUG_TRACE, ("===> rt_ioctl_giwencodeext\n"));
2027 max_key_len = encoding->length - sizeof(*ext);
2028 if (max_key_len < 0)
2029 return -EINVAL;
2031 idx = encoding->flags & IW_ENCODE_INDEX;
2032 if (idx) {
2033 if (idx < 1 || idx > 4)
2034 return -EINVAL;
2035 idx--;
2037 if ((pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) ||
2038 (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)) {
2039 if (idx != pAd->StaCfg.DefaultKeyId) {
2040 ext->key_len = 0;
2041 return 0;
2044 } else
2045 idx = pAd->StaCfg.DefaultKeyId;
2047 encoding->flags = idx + 1;
2048 memset(ext, 0, sizeof(*ext));
2050 ext->key_len = 0;
2051 switch (pAd->StaCfg.WepStatus) {
2052 case Ndis802_11WEPDisabled:
2053 ext->alg = IW_ENCODE_ALG_NONE;
2054 encoding->flags |= IW_ENCODE_DISABLED;
2055 break;
2056 case Ndis802_11WEPEnabled:
2057 ext->alg = IW_ENCODE_ALG_WEP;
2058 if (pAd->SharedKey[BSS0][idx].KeyLen > max_key_len)
2059 return -E2BIG;
2060 else {
2061 ext->key_len = pAd->SharedKey[BSS0][idx].KeyLen;
2062 pKey = (char *)& (pAd->SharedKey[BSS0][idx].Key[0]);
2064 break;
2065 case Ndis802_11Encryption2Enabled:
2066 case Ndis802_11Encryption3Enabled:
2067 if (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled)
2068 ext->alg = IW_ENCODE_ALG_TKIP;
2069 else
2070 ext->alg = IW_ENCODE_ALG_CCMP;
2072 if (max_key_len < 32)
2073 return -E2BIG;
2074 else {
2075 ext->key_len = 32;
2076 pKey = (char *)& pAd->StaCfg.PMK[0];
2078 break;
2079 default:
2080 return -EINVAL;
2083 if (ext->key_len && pKey) {
2084 encoding->flags |= IW_ENCODE_ENABLED;
2085 memcpy(ext->key, pKey, ext->key_len);
2088 return 0;
2091 int rt_ioctl_siwgenie(struct net_device *dev,
2092 struct iw_request_info *info,
2093 union iwreq_data *wrqu, char *extra)
2095 struct rt_rtmp_adapter *pAd = NULL;
2097 GET_PAD_FROM_NET_DEV(pAd, dev);
2099 DBGPRINT(RT_DEBUG_TRACE, ("===> rt_ioctl_siwgenie\n"));
2100 pAd->StaCfg.bRSN_IE_FromWpaSupplicant = FALSE;
2101 if (wrqu->data.length > MAX_LEN_OF_RSNIE ||
2102 (wrqu->data.length && extra == NULL))
2103 return -EINVAL;
2105 if (wrqu->data.length) {
2106 pAd->StaCfg.RSNIE_Len = wrqu->data.length;
2107 NdisMoveMemory(&pAd->StaCfg.RSN_IE[0], extra,
2108 pAd->StaCfg.RSNIE_Len);
2109 pAd->StaCfg.bRSN_IE_FromWpaSupplicant = TRUE;
2110 } else {
2111 pAd->StaCfg.RSNIE_Len = 0;
2112 NdisZeroMemory(&pAd->StaCfg.RSN_IE[0], MAX_LEN_OF_RSNIE);
2115 return 0;
2118 int rt_ioctl_giwgenie(struct net_device *dev,
2119 struct iw_request_info *info,
2120 union iwreq_data *wrqu, char *extra)
2122 struct rt_rtmp_adapter *pAd = NULL;
2124 GET_PAD_FROM_NET_DEV(pAd, dev);
2126 if ((pAd->StaCfg.RSNIE_Len == 0) ||
2127 (pAd->StaCfg.AuthMode < Ndis802_11AuthModeWPA)) {
2128 wrqu->data.length = 0;
2129 return 0;
2132 if (pAd->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_ENABLE) {
2133 if (wrqu->data.length < pAd->StaCfg.RSNIE_Len)
2134 return -E2BIG;
2136 wrqu->data.length = pAd->StaCfg.RSNIE_Len;
2137 memcpy(extra, &pAd->StaCfg.RSN_IE[0], pAd->StaCfg.RSNIE_Len);
2138 } else {
2139 u8 RSNIe = IE_WPA;
2141 if (wrqu->data.length < (pAd->StaCfg.RSNIE_Len + 2)) /* ID, Len */
2142 return -E2BIG;
2143 wrqu->data.length = pAd->StaCfg.RSNIE_Len + 2;
2145 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK) ||
2146 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2))
2147 RSNIe = IE_RSN;
2149 extra[0] = (char)RSNIe;
2150 extra[1] = pAd->StaCfg.RSNIE_Len;
2151 memcpy(extra + 2, &pAd->StaCfg.RSN_IE[0],
2152 pAd->StaCfg.RSNIE_Len);
2155 return 0;
2158 int rt_ioctl_siwpmksa(struct net_device *dev,
2159 struct iw_request_info *info,
2160 union iwreq_data *wrqu, char *extra)
2162 struct rt_rtmp_adapter *pAd = NULL;
2163 struct iw_pmksa *pPmksa = (struct iw_pmksa *)wrqu->data.pointer;
2164 int CachedIdx = 0, idx = 0;
2166 GET_PAD_FROM_NET_DEV(pAd, dev);
2168 if (pPmksa == NULL)
2169 return -EINVAL;
2171 DBGPRINT(RT_DEBUG_TRACE, ("===> rt_ioctl_siwpmksa\n"));
2172 switch (pPmksa->cmd) {
2173 case IW_PMKSA_FLUSH:
2174 NdisZeroMemory(pAd->StaCfg.SavedPMK,
2175 sizeof(struct rt_bssid_info) * PMKID_NO);
2176 DBGPRINT(RT_DEBUG_TRACE,
2177 ("rt_ioctl_siwpmksa - IW_PMKSA_FLUSH\n"));
2178 break;
2179 case IW_PMKSA_REMOVE:
2180 for (CachedIdx = 0; CachedIdx < pAd->StaCfg.SavedPMKNum;
2181 CachedIdx++) {
2182 /* compare the BSSID */
2183 if (NdisEqualMemory
2184 (pPmksa->bssid.sa_data,
2185 pAd->StaCfg.SavedPMK[CachedIdx].BSSID,
2186 MAC_ADDR_LEN)) {
2187 NdisZeroMemory(pAd->StaCfg.SavedPMK[CachedIdx].
2188 BSSID, MAC_ADDR_LEN);
2189 NdisZeroMemory(pAd->StaCfg.SavedPMK[CachedIdx].
2190 PMKID, 16);
2191 for (idx = CachedIdx;
2192 idx < (pAd->StaCfg.SavedPMKNum - 1);
2193 idx++) {
2194 NdisMoveMemory(&pAd->StaCfg.
2195 SavedPMK[idx].BSSID[0],
2196 &pAd->StaCfg.
2197 SavedPMK[idx +
2198 1].BSSID[0],
2199 MAC_ADDR_LEN);
2200 NdisMoveMemory(&pAd->StaCfg.
2201 SavedPMK[idx].PMKID[0],
2202 &pAd->StaCfg.
2203 SavedPMK[idx +
2204 1].PMKID[0],
2205 16);
2207 pAd->StaCfg.SavedPMKNum--;
2208 break;
2212 DBGPRINT(RT_DEBUG_TRACE,
2213 ("rt_ioctl_siwpmksa - IW_PMKSA_REMOVE\n"));
2214 break;
2215 case IW_PMKSA_ADD:
2216 for (CachedIdx = 0; CachedIdx < pAd->StaCfg.SavedPMKNum;
2217 CachedIdx++) {
2218 /* compare the BSSID */
2219 if (NdisEqualMemory
2220 (pPmksa->bssid.sa_data,
2221 pAd->StaCfg.SavedPMK[CachedIdx].BSSID,
2222 MAC_ADDR_LEN))
2223 break;
2226 /* Found, replace it */
2227 if (CachedIdx < PMKID_NO) {
2228 DBGPRINT(RT_DEBUG_OFF,
2229 ("Update PMKID, idx = %d\n", CachedIdx));
2230 NdisMoveMemory(&pAd->StaCfg.SavedPMK[CachedIdx].
2231 BSSID[0], pPmksa->bssid.sa_data,
2232 MAC_ADDR_LEN);
2233 NdisMoveMemory(&pAd->StaCfg.SavedPMK[CachedIdx].
2234 PMKID[0], pPmksa->pmkid, 16);
2235 pAd->StaCfg.SavedPMKNum++;
2237 /* Not found, replace the last one */
2238 else {
2239 /* Randomly replace one */
2240 CachedIdx = (pPmksa->bssid.sa_data[5] % PMKID_NO);
2241 DBGPRINT(RT_DEBUG_OFF,
2242 ("Update PMKID, idx = %d\n", CachedIdx));
2243 NdisMoveMemory(&pAd->StaCfg.SavedPMK[CachedIdx].
2244 BSSID[0], pPmksa->bssid.sa_data,
2245 MAC_ADDR_LEN);
2246 NdisMoveMemory(&pAd->StaCfg.SavedPMK[CachedIdx].
2247 PMKID[0], pPmksa->pmkid, 16);
2250 DBGPRINT(RT_DEBUG_TRACE,
2251 ("rt_ioctl_siwpmksa - IW_PMKSA_ADD\n"));
2252 break;
2253 default:
2254 DBGPRINT(RT_DEBUG_TRACE,
2255 ("rt_ioctl_siwpmksa - Unknown Command!\n"));
2256 break;
2259 return 0;
2262 int rt_ioctl_siwrate(struct net_device *dev,
2263 struct iw_request_info *info,
2264 union iwreq_data *wrqu, char *extra)
2266 struct rt_rtmp_adapter *pAd = NULL;
2267 u32 rate = wrqu->bitrate.value, fixed = wrqu->bitrate.fixed;
2269 GET_PAD_FROM_NET_DEV(pAd, dev);
2271 /*check if the interface is down */
2272 if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE)) {
2273 DBGPRINT(RT_DEBUG_TRACE,
2274 ("rt_ioctl_siwrate::Network is down!\n"));
2275 return -ENETDOWN;
2278 DBGPRINT(RT_DEBUG_TRACE,
2279 ("rt_ioctl_siwrate::(rate = %d, fixed = %d)\n", rate, fixed));
2280 /* rate = -1 => auto rate
2281 rate = X, fixed = 1 => (fixed rate X)
2283 if (rate == -1) {
2284 /*Auto Rate */
2285 pAd->StaCfg.DesiredTransmitSetting.field.MCS = MCS_AUTO;
2286 pAd->StaCfg.bAutoTxRateSwitch = TRUE;
2287 if ((pAd->CommonCfg.PhyMode <= PHY_11G) ||
2288 (pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE <=
2289 MODE_OFDM))
2290 RTMPSetDesiredRates(pAd, -1);
2292 SetCommonHT(pAd);
2293 } else {
2294 if (fixed) {
2295 pAd->StaCfg.bAutoTxRateSwitch = FALSE;
2296 if ((pAd->CommonCfg.PhyMode <= PHY_11G) ||
2297 (pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.
2298 MODE <= MODE_OFDM))
2299 RTMPSetDesiredRates(pAd, rate);
2300 else {
2301 pAd->StaCfg.DesiredTransmitSetting.field.MCS =
2302 MCS_AUTO;
2303 SetCommonHT(pAd);
2305 DBGPRINT(RT_DEBUG_TRACE,
2306 ("rt_ioctl_siwrate::(HtMcs=%d)\n",
2307 pAd->StaCfg.DesiredTransmitSetting.field.
2308 MCS));
2309 } else {
2310 /* TODO: rate = X, fixed = 0 => (rates <= X) */
2311 return -EOPNOTSUPP;
2315 return 0;
2318 int rt_ioctl_giwrate(struct net_device *dev,
2319 struct iw_request_info *info,
2320 union iwreq_data *wrqu, char *extra)
2322 struct rt_rtmp_adapter *pAd = NULL;
2323 int rate_index = 0, rate_count = 0;
2324 HTTRANSMIT_SETTING ht_setting;
2325 /* Remove to global variable
2326 __s32 ralinkrate[] =
2327 {2, 4, 11, 22, // CCK
2328 12, 18, 24, 36, 48, 72, 96, 108, // OFDM
2329 13, 26, 39, 52, 78, 104, 117, 130, 26, 52, 78, 104, 156, 208, 234, 260, // 20MHz, 800ns GI, MCS: 0 ~ 15
2330 39, 78, 117, 156, 234, 312, 351, 390, // 20MHz, 800ns GI, MCS: 16 ~ 23
2331 27, 54, 81, 108, 162, 216, 243, 270, 54, 108, 162, 216, 324, 432, 486, 540, // 40MHz, 800ns GI, MCS: 0 ~ 15
2332 81, 162, 243, 324, 486, 648, 729, 810, // 40MHz, 800ns GI, MCS: 16 ~ 23
2333 14, 29, 43, 57, 87, 115, 130, 144, 29, 59, 87, 115, 173, 230, 260, 288, // 20MHz, 400ns GI, MCS: 0 ~ 15
2334 43, 87, 130, 173, 260, 317, 390, 433, // 20MHz, 400ns GI, MCS: 16 ~ 23
2335 30, 60, 90, 120, 180, 240, 270, 300, 60, 120, 180, 240, 360, 480, 540, 600, // 40MHz, 400ns GI, MCS: 0 ~ 15
2336 90, 180, 270, 360, 540, 720, 810, 900}; // 40MHz, 400ns GI, MCS: 16 ~ 23
2338 GET_PAD_FROM_NET_DEV(pAd, dev);
2340 rate_count = ARRAY_SIZE(ralinkrate);
2341 /*check if the interface is down */
2342 if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE)) {
2343 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
2344 return -ENETDOWN;
2347 if ((pAd->StaCfg.bAutoTxRateSwitch == FALSE) &&
2348 (INFRA_ON(pAd)) &&
2349 ((pAd->CommonCfg.PhyMode <= PHY_11G)
2350 || (pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE <=
2351 MODE_OFDM)))
2352 ht_setting.word = pAd->StaCfg.HTPhyMode.word;
2353 else
2354 ht_setting.word =
2355 pAd->MacTab.Content[BSSID_WCID].HTPhyMode.word;
2357 if (ht_setting.field.MODE >= MODE_HTMIX) {
2358 /* rate_index = 12 + ((u8)ht_setting.field.BW *16) + ((u8)ht_setting.field.ShortGI *32) + ((u8)ht_setting.field.MCS); */
2359 rate_index =
2360 12 + ((u8)ht_setting.field.BW * 24) +
2361 ((u8)ht_setting.field.ShortGI * 48) +
2362 ((u8)ht_setting.field.MCS);
2363 } else if (ht_setting.field.MODE == MODE_OFDM)
2364 rate_index = (u8)(ht_setting.field.MCS) + 4;
2365 else if (ht_setting.field.MODE == MODE_CCK)
2366 rate_index = (u8)(ht_setting.field.MCS);
2368 if (rate_index < 0)
2369 rate_index = 0;
2371 if (rate_index >= rate_count)
2372 rate_index = rate_count - 1;
2374 wrqu->bitrate.value = ralinkrate[rate_index] * 500000;
2375 wrqu->bitrate.disabled = 0;
2377 return 0;
2380 static const iw_handler rt_handler[] = {
2381 (iw_handler) NULL, /* SIOCSIWCOMMIT */
2382 (iw_handler) rt_ioctl_giwname, /* SIOCGIWNAME */
2383 (iw_handler) NULL, /* SIOCSIWNWID */
2384 (iw_handler) NULL, /* SIOCGIWNWID */
2385 (iw_handler) rt_ioctl_siwfreq, /* SIOCSIWFREQ */
2386 (iw_handler) rt_ioctl_giwfreq, /* SIOCGIWFREQ */
2387 (iw_handler) rt_ioctl_siwmode, /* SIOCSIWMODE */
2388 (iw_handler) rt_ioctl_giwmode, /* SIOCGIWMODE */
2389 (iw_handler) NULL, /* SIOCSIWSENS */
2390 (iw_handler) NULL, /* SIOCGIWSENS */
2391 (iw_handler) NULL /* not used */ , /* SIOCSIWRANGE */
2392 (iw_handler) rt_ioctl_giwrange, /* SIOCGIWRANGE */
2393 (iw_handler) NULL /* not used */ , /* SIOCSIWPRIV */
2394 (iw_handler) NULL /* kernel code */ , /* SIOCGIWPRIV */
2395 (iw_handler) NULL /* not used */ , /* SIOCSIWSTATS */
2396 (iw_handler) rt28xx_get_wireless_stats /* kernel code */ , /* SIOCGIWSTATS */
2397 (iw_handler) NULL, /* SIOCSIWSPY */
2398 (iw_handler) NULL, /* SIOCGIWSPY */
2399 (iw_handler) NULL, /* SIOCSIWTHRSPY */
2400 (iw_handler) NULL, /* SIOCGIWTHRSPY */
2401 (iw_handler) rt_ioctl_siwap, /* SIOCSIWAP */
2402 (iw_handler) rt_ioctl_giwap, /* SIOCGIWAP */
2403 (iw_handler) rt_ioctl_siwmlme, /* SIOCSIWMLME */
2404 (iw_handler) rt_ioctl_iwaplist, /* SIOCGIWAPLIST */
2405 (iw_handler) rt_ioctl_siwscan, /* SIOCSIWSCAN */
2406 (iw_handler) rt_ioctl_giwscan, /* SIOCGIWSCAN */
2407 (iw_handler) rt_ioctl_siwessid, /* SIOCSIWESSID */
2408 (iw_handler) rt_ioctl_giwessid, /* SIOCGIWESSID */
2409 (iw_handler) rt_ioctl_siwnickn, /* SIOCSIWNICKN */
2410 (iw_handler) rt_ioctl_giwnickn, /* SIOCGIWNICKN */
2411 (iw_handler) NULL, /* -- hole -- */
2412 (iw_handler) NULL, /* -- hole -- */
2413 (iw_handler) rt_ioctl_siwrate, /* SIOCSIWRATE */
2414 (iw_handler) rt_ioctl_giwrate, /* SIOCGIWRATE */
2415 (iw_handler) rt_ioctl_siwrts, /* SIOCSIWRTS */
2416 (iw_handler) rt_ioctl_giwrts, /* SIOCGIWRTS */
2417 (iw_handler) rt_ioctl_siwfrag, /* SIOCSIWFRAG */
2418 (iw_handler) rt_ioctl_giwfrag, /* SIOCGIWFRAG */
2419 (iw_handler) NULL, /* SIOCSIWTXPOW */
2420 (iw_handler) NULL, /* SIOCGIWTXPOW */
2421 (iw_handler) NULL, /* SIOCSIWRETRY */
2422 (iw_handler) NULL, /* SIOCGIWRETRY */
2423 (iw_handler) rt_ioctl_siwencode, /* SIOCSIWENCODE */
2424 (iw_handler) rt_ioctl_giwencode, /* SIOCGIWENCODE */
2425 (iw_handler) NULL, /* SIOCSIWPOWER */
2426 (iw_handler) NULL, /* SIOCGIWPOWER */
2427 (iw_handler) NULL, /* -- hole -- */
2428 (iw_handler) NULL, /* -- hole -- */
2429 (iw_handler) rt_ioctl_siwgenie, /* SIOCSIWGENIE */
2430 (iw_handler) rt_ioctl_giwgenie, /* SIOCGIWGENIE */
2431 (iw_handler) rt_ioctl_siwauth, /* SIOCSIWAUTH */
2432 (iw_handler) rt_ioctl_giwauth, /* SIOCGIWAUTH */
2433 (iw_handler) rt_ioctl_siwencodeext, /* SIOCSIWENCODEEXT */
2434 (iw_handler) rt_ioctl_giwencodeext, /* SIOCGIWENCODEEXT */
2435 (iw_handler) rt_ioctl_siwpmksa, /* SIOCSIWPMKSA */
2438 const struct iw_handler_def rt28xx_iw_handler_def = {
2439 .standard = (iw_handler *) rt_handler,
2440 .num_standard = sizeof(rt_handler) / sizeof(iw_handler),
2441 #if IW_HANDLER_VERSION >= 7
2442 .get_wireless_stats = rt28xx_get_wireless_stats,
2443 #endif
2446 int rt28xx_sta_ioctl(IN struct net_device *net_dev,
2447 IN OUT struct ifreq *rq, int cmd)
2449 struct os_cookie *pObj;
2450 struct rt_rtmp_adapter *pAd = NULL;
2451 struct iwreq *wrq = (struct iwreq *)rq;
2452 BOOLEAN StateMachineTouched = FALSE;
2453 int Status = NDIS_STATUS_SUCCESS;
2455 GET_PAD_FROM_NET_DEV(pAd, net_dev);
2457 pObj = (struct os_cookie *)pAd->OS_Cookie;
2459 /*check if the interface is down */
2460 if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE)) {
2462 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
2463 return -ENETDOWN;
2467 { /* determine this ioctl command is comming from which interface. */
2468 pObj->ioctl_if_type = INT_MAIN;
2469 pObj->ioctl_if = MAIN_MBSSID;
2472 switch (cmd) {
2473 case SIOCGIFHWADDR:
2474 DBGPRINT(RT_DEBUG_TRACE, ("IOCTL::SIOCGIFHWADDR\n"));
2475 memcpy(wrq->u.name, pAd->CurrentAddress, ETH_ALEN);
2476 break;
2477 case SIOCGIWNAME:
2479 char *name = &wrq->u.name[0];
2480 rt_ioctl_giwname(net_dev, NULL, name, NULL);
2481 break;
2483 case SIOCGIWESSID: /*Get ESSID */
2485 struct iw_point *essid = &wrq->u.essid;
2486 rt_ioctl_giwessid(net_dev, NULL, essid, essid->pointer);
2487 break;
2489 case SIOCSIWESSID: /*Set ESSID */
2491 struct iw_point *essid = &wrq->u.essid;
2492 rt_ioctl_siwessid(net_dev, NULL, essid, essid->pointer);
2493 break;
2495 case SIOCSIWNWID: /* set network id (the cell) */
2496 case SIOCGIWNWID: /* get network id */
2497 Status = -EOPNOTSUPP;
2498 break;
2499 case SIOCSIWFREQ: /*set channel/frequency (Hz) */
2501 struct iw_freq *freq = &wrq->u.freq;
2502 rt_ioctl_siwfreq(net_dev, NULL, freq, NULL);
2503 break;
2505 case SIOCGIWFREQ: /* get channel/frequency (Hz) */
2507 struct iw_freq *freq = &wrq->u.freq;
2508 rt_ioctl_giwfreq(net_dev, NULL, freq, NULL);
2509 break;
2511 case SIOCSIWNICKN: /*set node name/nickname */
2513 /*struct iw_point *data=&wrq->u.data; */
2514 /*rt_ioctl_siwnickn(net_dev, NULL, data, NULL); */
2515 break;
2517 case SIOCGIWNICKN: /*get node name/nickname */
2519 struct iw_point *erq = NULL;
2520 erq = &wrq->u.data;
2521 erq->length = strlen((char *)pAd->nickname);
2522 Status =
2523 copy_to_user(erq->pointer, pAd->nickname,
2524 erq->length);
2525 if (Status)
2526 Status = -EFAULT;
2527 break;
2529 case SIOCGIWRATE: /*get default bit rate (bps) */
2530 rt_ioctl_giwrate(net_dev, NULL, &wrq->u, NULL);
2531 break;
2532 case SIOCSIWRATE: /*set default bit rate (bps) */
2533 rt_ioctl_siwrate(net_dev, NULL, &wrq->u, NULL);
2534 break;
2535 case SIOCGIWRTS: /* get RTS/CTS threshold (bytes) */
2537 struct iw_param *rts = &wrq->u.rts;
2538 rt_ioctl_giwrts(net_dev, NULL, rts, NULL);
2539 break;
2541 case SIOCSIWRTS: /*set RTS/CTS threshold (bytes) */
2543 struct iw_param *rts = &wrq->u.rts;
2544 rt_ioctl_siwrts(net_dev, NULL, rts, NULL);
2545 break;
2547 case SIOCGIWFRAG: /*get fragmentation thr (bytes) */
2549 struct iw_param *frag = &wrq->u.frag;
2550 rt_ioctl_giwfrag(net_dev, NULL, frag, NULL);
2551 break;
2553 case SIOCSIWFRAG: /*set fragmentation thr (bytes) */
2555 struct iw_param *frag = &wrq->u.frag;
2556 rt_ioctl_siwfrag(net_dev, NULL, frag, NULL);
2557 break;
2559 case SIOCGIWENCODE: /*get encoding token & mode */
2561 struct iw_point *erq = &wrq->u.encoding;
2562 if (erq)
2563 rt_ioctl_giwencode(net_dev, NULL, erq,
2564 erq->pointer);
2565 break;
2567 case SIOCSIWENCODE: /*set encoding token & mode */
2569 struct iw_point *erq = &wrq->u.encoding;
2570 if (erq)
2571 rt_ioctl_siwencode(net_dev, NULL, erq,
2572 erq->pointer);
2573 break;
2575 case SIOCGIWAP: /*get access point MAC addresses */
2577 struct sockaddr *ap_addr = &wrq->u.ap_addr;
2578 rt_ioctl_giwap(net_dev, NULL, ap_addr,
2579 ap_addr->sa_data);
2580 break;
2582 case SIOCSIWAP: /*set access point MAC addresses */
2584 struct sockaddr *ap_addr = &wrq->u.ap_addr;
2585 rt_ioctl_siwap(net_dev, NULL, ap_addr,
2586 ap_addr->sa_data);
2587 break;
2589 case SIOCGIWMODE: /*get operation mode */
2591 __u32 *mode = &wrq->u.mode;
2592 rt_ioctl_giwmode(net_dev, NULL, mode, NULL);
2593 break;
2595 case SIOCSIWMODE: /*set operation mode */
2597 __u32 *mode = &wrq->u.mode;
2598 rt_ioctl_siwmode(net_dev, NULL, mode, NULL);
2599 break;
2601 case SIOCGIWSENS: /*get sensitivity (dBm) */
2602 case SIOCSIWSENS: /*set sensitivity (dBm) */
2603 case SIOCGIWPOWER: /*get Power Management settings */
2604 case SIOCSIWPOWER: /*set Power Management settings */
2605 case SIOCGIWTXPOW: /*get transmit power (dBm) */
2606 case SIOCSIWTXPOW: /*set transmit power (dBm) */
2607 case SIOCGIWRANGE: /*Get range of parameters */
2608 case SIOCGIWRETRY: /*get retry limits and lifetime */
2609 case SIOCSIWRETRY: /*set retry limits and lifetime */
2610 case RT_PRIV_IOCTL:
2611 case RT_PRIV_IOCTL_EXT:
2612 case RTPRIV_IOCTL_SET:
2613 case RTPRIV_IOCTL_GSITESURVEY:
2614 case SIOCGIWPRIV:
2615 Status = -EOPNOTSUPP;
2616 break;
2617 case SIOCETHTOOL:
2618 break;
2619 default:
2620 DBGPRINT(RT_DEBUG_ERROR,
2621 ("IOCTL::unknown IOCTL's cmd = 0x%08x\n", cmd));
2622 Status = -EOPNOTSUPP;
2623 break;
2626 if (StateMachineTouched) /* Upper layer sent a MLME-related operations */
2627 RTMP_MLME_HANDLER(pAd);
2629 return Status;
2633 ==========================================================================
2634 Description:
2635 Set SSID
2636 Return:
2637 TRUE if all parameters are OK, FALSE otherwise
2638 ==========================================================================
2640 int Set_SSID_Proc(struct rt_rtmp_adapter *pAdapter, char *arg)
2642 struct rt_ndis_802_11_ssid Ssid, *pSsid = NULL;
2643 BOOLEAN StateMachineTouched = FALSE;
2644 int success = TRUE;
2646 if (strlen(arg) <= MAX_LEN_OF_SSID) {
2647 NdisZeroMemory(&Ssid, sizeof(struct rt_ndis_802_11_ssid));
2648 if (strlen(arg) != 0) {
2649 NdisMoveMemory(Ssid.Ssid, arg, strlen(arg));
2650 Ssid.SsidLength = strlen(arg);
2651 } else /*ANY ssid */
2653 Ssid.SsidLength = 0;
2654 memcpy(Ssid.Ssid, "", 0);
2655 pAdapter->StaCfg.BssType = BSS_INFRA;
2656 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
2657 pAdapter->StaCfg.WepStatus =
2658 Ndis802_11EncryptionDisabled;
2660 pSsid = &Ssid;
2662 if (pAdapter->Mlme.CntlMachine.CurrState != CNTL_IDLE) {
2663 RTMP_MLME_RESET_STATE_MACHINE(pAdapter);
2664 DBGPRINT(RT_DEBUG_TRACE,
2665 ("MLME busy, reset MLME state machine!\n"));
2668 if ((pAdapter->StaCfg.WpaPassPhraseLen >= 8) &&
2669 (pAdapter->StaCfg.WpaPassPhraseLen <= 64)) {
2670 char passphrase_str[65] = { 0 };
2671 u8 keyMaterial[40];
2673 RTMPMoveMemory(passphrase_str,
2674 pAdapter->StaCfg.WpaPassPhrase,
2675 pAdapter->StaCfg.WpaPassPhraseLen);
2676 RTMPZeroMemory(pAdapter->StaCfg.PMK, 32);
2677 if (pAdapter->StaCfg.WpaPassPhraseLen == 64) {
2678 AtoH((char *)pAdapter->StaCfg.WpaPassPhrase,
2679 pAdapter->StaCfg.PMK, 32);
2680 } else {
2681 PasswordHash((char *)pAdapter->StaCfg.
2682 WpaPassPhrase, Ssid.Ssid,
2683 Ssid.SsidLength, keyMaterial);
2684 NdisMoveMemory(pAdapter->StaCfg.PMK,
2685 keyMaterial, 32);
2689 pAdapter->MlmeAux.CurrReqIsFromNdis = TRUE;
2690 pAdapter->StaCfg.bScanReqIsFromWebUI = FALSE;
2691 pAdapter->bConfigChanged = TRUE;
2693 MlmeEnqueue(pAdapter,
2694 MLME_CNTL_STATE_MACHINE,
2695 OID_802_11_SSID,
2696 sizeof(struct rt_ndis_802_11_ssid), (void *) pSsid);
2698 StateMachineTouched = TRUE;
2699 DBGPRINT(RT_DEBUG_TRACE,
2700 ("Set_SSID_Proc::(Len=%d,Ssid=%s)\n", Ssid.SsidLength,
2701 Ssid.Ssid));
2702 } else
2703 success = FALSE;
2705 if (StateMachineTouched) /* Upper layer sent a MLME-related operations */
2706 RTMP_MLME_HANDLER(pAdapter);
2708 return success;
2712 ==========================================================================
2713 Description:
2714 Set Network Type(Infrastructure/Adhoc mode)
2715 Return:
2716 TRUE if all parameters are OK, FALSE otherwise
2717 ==========================================================================
2719 int Set_NetworkType_Proc(struct rt_rtmp_adapter *pAdapter, char *arg)
2721 u32 Value = 0;
2723 if (strcmp(arg, "Adhoc") == 0) {
2724 if (pAdapter->StaCfg.BssType != BSS_ADHOC) {
2725 /* Config has changed */
2726 pAdapter->bConfigChanged = TRUE;
2727 if (MONITOR_ON(pAdapter)) {
2728 RTMP_IO_WRITE32(pAdapter, RX_FILTR_CFG,
2729 STANORMAL);
2730 RTMP_IO_READ32(pAdapter, MAC_SYS_CTRL, &Value);
2731 Value &= (~0x80);
2732 RTMP_IO_WRITE32(pAdapter, MAC_SYS_CTRL, Value);
2733 OPSTATUS_CLEAR_FLAG(pAdapter,
2734 fOP_STATUS_MEDIA_STATE_CONNECTED);
2735 pAdapter->StaCfg.bAutoReconnect = TRUE;
2736 LinkDown(pAdapter, FALSE);
2738 if (INFRA_ON(pAdapter)) {
2739 /*BOOLEAN Cancelled; */
2740 /* Set the AutoReconnectSsid to prevent it reconnect to old SSID */
2741 /* Since calling this indicate user don't want to connect to that SSID anymore. */
2742 pAdapter->MlmeAux.AutoReconnectSsidLen = 32;
2743 NdisZeroMemory(pAdapter->MlmeAux.
2744 AutoReconnectSsid,
2745 pAdapter->MlmeAux.
2746 AutoReconnectSsidLen);
2748 LinkDown(pAdapter, FALSE);
2750 DBGPRINT(RT_DEBUG_TRACE,
2751 ("NDIS_STATUS_MEDIA_DISCONNECT Event BB!\n"));
2754 pAdapter->StaCfg.BssType = BSS_ADHOC;
2755 pAdapter->net_dev->type = pAdapter->StaCfg.OriDevType;
2756 DBGPRINT(RT_DEBUG_TRACE,
2757 ("===>Set_NetworkType_Proc::(AD-HOC)\n"));
2758 } else if (strcmp(arg, "Infra") == 0) {
2759 if (pAdapter->StaCfg.BssType != BSS_INFRA) {
2760 /* Config has changed */
2761 pAdapter->bConfigChanged = TRUE;
2762 if (MONITOR_ON(pAdapter)) {
2763 RTMP_IO_WRITE32(pAdapter, RX_FILTR_CFG,
2764 STANORMAL);
2765 RTMP_IO_READ32(pAdapter, MAC_SYS_CTRL, &Value);
2766 Value &= (~0x80);
2767 RTMP_IO_WRITE32(pAdapter, MAC_SYS_CTRL, Value);
2768 OPSTATUS_CLEAR_FLAG(pAdapter,
2769 fOP_STATUS_MEDIA_STATE_CONNECTED);
2770 pAdapter->StaCfg.bAutoReconnect = TRUE;
2771 LinkDown(pAdapter, FALSE);
2773 if (ADHOC_ON(pAdapter)) {
2774 /* Set the AutoReconnectSsid to prevent it reconnect to old SSID */
2775 /* Since calling this indicate user don't want to connect to that SSID anymore. */
2776 pAdapter->MlmeAux.AutoReconnectSsidLen = 32;
2777 NdisZeroMemory(pAdapter->MlmeAux.
2778 AutoReconnectSsid,
2779 pAdapter->MlmeAux.
2780 AutoReconnectSsidLen);
2782 LinkDown(pAdapter, FALSE);
2785 pAdapter->StaCfg.BssType = BSS_INFRA;
2786 pAdapter->net_dev->type = pAdapter->StaCfg.OriDevType;
2787 DBGPRINT(RT_DEBUG_TRACE,
2788 ("===>Set_NetworkType_Proc::(INFRA)\n"));
2789 } else if (strcmp(arg, "Monitor") == 0) {
2790 u8 bbpValue = 0;
2791 BCN_TIME_CFG_STRUC csr;
2792 OPSTATUS_CLEAR_FLAG(pAdapter, fOP_STATUS_INFRA_ON);
2793 OPSTATUS_CLEAR_FLAG(pAdapter, fOP_STATUS_ADHOC_ON);
2794 OPSTATUS_SET_FLAG(pAdapter, fOP_STATUS_MEDIA_STATE_CONNECTED);
2795 /* disable all periodic state machine */
2796 pAdapter->StaCfg.bAutoReconnect = FALSE;
2797 /* reset all mlme state machine */
2798 RTMP_MLME_RESET_STATE_MACHINE(pAdapter);
2799 DBGPRINT(RT_DEBUG_TRACE,
2800 ("fOP_STATUS_MEDIA_STATE_CONNECTED \n"));
2801 if (pAdapter->CommonCfg.CentralChannel == 0) {
2802 if (pAdapter->CommonCfg.PhyMode == PHY_11AN_MIXED)
2803 pAdapter->CommonCfg.CentralChannel = 36;
2804 else
2805 pAdapter->CommonCfg.CentralChannel = 6;
2806 } else
2807 N_ChannelCheck(pAdapter);
2809 if (pAdapter->CommonCfg.PhyMode >= PHY_11ABGN_MIXED &&
2810 pAdapter->CommonCfg.RegTransmitSetting.field.BW == BW_40 &&
2811 pAdapter->CommonCfg.RegTransmitSetting.field.EXTCHA ==
2812 EXTCHA_ABOVE) {
2813 /* 40MHz ,control channel at lower */
2814 RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R4,
2815 &bbpValue);
2816 bbpValue &= (~0x18);
2817 bbpValue |= 0x10;
2818 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R4,
2819 bbpValue);
2820 pAdapter->CommonCfg.BBPCurrentBW = BW_40;
2821 /* RX : control channel at lower */
2822 RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R3,
2823 &bbpValue);
2824 bbpValue &= (~0x20);
2825 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R3,
2826 bbpValue);
2828 RTMP_IO_READ32(pAdapter, TX_BAND_CFG, &Value);
2829 Value &= 0xfffffffe;
2830 RTMP_IO_WRITE32(pAdapter, TX_BAND_CFG, Value);
2831 pAdapter->CommonCfg.CentralChannel =
2832 pAdapter->CommonCfg.Channel + 2;
2833 AsicSwitchChannel(pAdapter,
2834 pAdapter->CommonCfg.CentralChannel,
2835 FALSE);
2836 AsicLockChannel(pAdapter,
2837 pAdapter->CommonCfg.CentralChannel);
2838 DBGPRINT(RT_DEBUG_TRACE,
2839 ("BW_40 ,control_channel(%d), CentralChannel(%d) \n",
2840 pAdapter->CommonCfg.Channel,
2841 pAdapter->CommonCfg.CentralChannel));
2842 } else if (pAdapter->CommonCfg.PhyMode >= PHY_11ABGN_MIXED
2843 && pAdapter->CommonCfg.RegTransmitSetting.field.BW ==
2844 BW_40
2845 && pAdapter->CommonCfg.RegTransmitSetting.field.
2846 EXTCHA == EXTCHA_BELOW) {
2847 /* 40MHz ,control channel at upper */
2848 RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R4,
2849 &bbpValue);
2850 bbpValue &= (~0x18);
2851 bbpValue |= 0x10;
2852 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R4,
2853 bbpValue);
2854 pAdapter->CommonCfg.BBPCurrentBW = BW_40;
2855 RTMP_IO_READ32(pAdapter, TX_BAND_CFG, &Value);
2856 Value |= 0x1;
2857 RTMP_IO_WRITE32(pAdapter, TX_BAND_CFG, Value);
2859 RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R3,
2860 &bbpValue);
2861 bbpValue |= (0x20);
2862 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R3,
2863 bbpValue);
2864 pAdapter->CommonCfg.CentralChannel =
2865 pAdapter->CommonCfg.Channel - 2;
2866 AsicSwitchChannel(pAdapter,
2867 pAdapter->CommonCfg.CentralChannel,
2868 FALSE);
2869 AsicLockChannel(pAdapter,
2870 pAdapter->CommonCfg.CentralChannel);
2871 DBGPRINT(RT_DEBUG_TRACE,
2872 ("BW_40 ,control_channel(%d), CentralChannel(%d) \n",
2873 pAdapter->CommonCfg.Channel,
2874 pAdapter->CommonCfg.CentralChannel));
2875 } else {
2876 /* 20MHz */
2877 RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R4,
2878 &bbpValue);
2879 bbpValue &= (~0x18);
2880 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R4,
2881 bbpValue);
2882 pAdapter->CommonCfg.BBPCurrentBW = BW_20;
2883 AsicSwitchChannel(pAdapter, pAdapter->CommonCfg.Channel,
2884 FALSE);
2885 AsicLockChannel(pAdapter, pAdapter->CommonCfg.Channel);
2886 DBGPRINT(RT_DEBUG_TRACE,
2887 ("BW_20, Channel(%d)\n",
2888 pAdapter->CommonCfg.Channel));
2890 /* Enable Rx with promiscuous reception */
2891 RTMP_IO_WRITE32(pAdapter, RX_FILTR_CFG, 0x3);
2892 /* ASIC supporsts sniffer function with replacing RSSI with timestamp. */
2893 /*RTMP_IO_READ32(pAdapter, MAC_SYS_CTRL, &Value); */
2894 /*Value |= (0x80); */
2895 /*RTMP_IO_WRITE32(pAdapter, MAC_SYS_CTRL, Value); */
2896 /* disable sync */
2897 RTMP_IO_READ32(pAdapter, BCN_TIME_CFG, &csr.word);
2898 csr.field.bBeaconGen = 0;
2899 csr.field.bTBTTEnable = 0;
2900 csr.field.TsfSyncMode = 0;
2901 RTMP_IO_WRITE32(pAdapter, BCN_TIME_CFG, csr.word);
2903 pAdapter->StaCfg.BssType = BSS_MONITOR;
2904 pAdapter->net_dev->type = ARPHRD_IEEE80211_PRISM; /*ARPHRD_IEEE80211; // IEEE80211 */
2905 DBGPRINT(RT_DEBUG_TRACE,
2906 ("===>Set_NetworkType_Proc::(MONITOR)\n"));
2908 /* Reset Ralink supplicant to not use, it will be set to start when UI set PMK key */
2909 pAdapter->StaCfg.WpaState = SS_NOTUSE;
2911 DBGPRINT(RT_DEBUG_TRACE,
2912 ("Set_NetworkType_Proc::(NetworkType=%d)\n",
2913 pAdapter->StaCfg.BssType));
2915 return TRUE;