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