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