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