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