• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /******************************************************************************
2  *
3  * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of version 2 of the GNU General Public License as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12  * more details.
13  *
14  * You should have received a copy of the GNU General Public License along with
15  * this program; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17  *
18  *
19  ******************************************************************************/
20 #define _IOCTL_LINUX_C_
21 
22 #include <osdep_service.h>
23 #include <drv_types.h>
24 #include <wlan_bssdef.h>
25 #include <rtw_debug.h>
26 #include <wifi.h>
27 #include <rtw_mlme.h>
28 #include <rtw_mlme_ext.h>
29 #include <rtw_ioctl.h>
30 #include <rtw_ioctl_set.h>
31 #include <rtl8188e_hal.h>
32 
33 #include <rtw_iol.h>
34 #include <linux/vmalloc.h>
35 #include "osdep_intf.h"
36 
37 #define RTL_IOCTL_WPA_SUPPLICANT	(SIOCIWFIRSTPRIV + 30)
38 
39 #define SCAN_ITEM_SIZE 768
40 #define MAX_CUSTOM_LEN 64
41 #define RATE_COUNT 4
42 
43 /*  combo scan */
44 #define WEXT_CSCAN_AMOUNT 9
45 #define WEXT_CSCAN_BUF_LEN		360
46 #define WEXT_CSCAN_HEADER		"CSCAN S\x01\x00\x00S\x00"
47 #define WEXT_CSCAN_HEADER_SIZE		12
48 #define WEXT_CSCAN_SSID_SECTION		'S'
49 #define WEXT_CSCAN_CHANNEL_SECTION	'C'
50 #define WEXT_CSCAN_NPROBE_SECTION	'N'
51 #define WEXT_CSCAN_ACTV_DWELL_SECTION	'A'
52 #define WEXT_CSCAN_PASV_DWELL_SECTION	'P'
53 #define WEXT_CSCAN_HOME_DWELL_SECTION	'H'
54 #define WEXT_CSCAN_TYPE_SECTION		'T'
55 
56 static u32 rtw_rates[] = {1000000, 2000000, 5500000, 11000000,
57 	6000000, 9000000, 12000000, 18000000, 24000000, 36000000,
58 	48000000, 54000000};
59 
60 static const char * const iw_operation_mode[] = {
61 	"Auto", "Ad-Hoc", "Managed",  "Master", "Repeater",
62 	"Secondary", "Monitor"
63 };
64 
indicate_wx_scan_complete_event(struct adapter * padapter)65 void indicate_wx_scan_complete_event(struct adapter *padapter)
66 {
67 	union iwreq_data wrqu;
68 
69 	memset(&wrqu, 0, sizeof(union iwreq_data));
70 	wireless_send_event(padapter->pnetdev, SIOCGIWSCAN, &wrqu, NULL);
71 }
72 
rtw_indicate_wx_assoc_event(struct adapter * padapter)73 void rtw_indicate_wx_assoc_event(struct adapter *padapter)
74 {
75 	union iwreq_data wrqu;
76 	struct	mlme_priv *pmlmepriv = &padapter->mlmepriv;
77 
78 	memset(&wrqu, 0, sizeof(union iwreq_data));
79 
80 	wrqu.ap_addr.sa_family = ARPHRD_ETHER;
81 
82 	memcpy(wrqu.ap_addr.sa_data, pmlmepriv->cur_network.network.MacAddress, ETH_ALEN);
83 
84 	DBG_88E_LEVEL(_drv_always_, "assoc success\n");
85 	wireless_send_event(padapter->pnetdev, SIOCGIWAP, &wrqu, NULL);
86 }
87 
rtw_indicate_wx_disassoc_event(struct adapter * padapter)88 void rtw_indicate_wx_disassoc_event(struct adapter *padapter)
89 {
90 	union iwreq_data wrqu;
91 
92 	memset(&wrqu, 0, sizeof(union iwreq_data));
93 
94 	wrqu.ap_addr.sa_family = ARPHRD_ETHER;
95 	memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN);
96 
97 	DBG_88E_LEVEL(_drv_always_, "indicate disassoc\n");
98 	wireless_send_event(padapter->pnetdev, SIOCGIWAP, &wrqu, NULL);
99 }
100 
translate_scan(struct adapter * padapter,struct iw_request_info * info,struct wlan_network * pnetwork,char * start,char * stop)101 static char *translate_scan(struct adapter *padapter,
102 			    struct iw_request_info *info,
103 			    struct wlan_network *pnetwork,
104 			    char *start, char *stop)
105 {
106 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
107 	struct iw_event iwe;
108 	u16 cap;
109 	__le16 le_tmp;
110 	u32 ht_ielen = 0;
111 	char custom[MAX_CUSTOM_LEN];
112 	char *p;
113 	u16 max_rate = 0, rate, ht_cap = false;
114 	u32 i = 0;
115 	u8 bw_40MHz = 0, short_GI = 0;
116 	u16 mcs_rate = 0;
117 	u8 ss, sq;
118 
119 	/*  AP MAC address  */
120 	iwe.cmd = SIOCGIWAP;
121 	iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
122 
123 	memcpy(iwe.u.ap_addr.sa_data, pnetwork->network.MacAddress, ETH_ALEN);
124 	start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_ADDR_LEN);
125 
126 	/* Add the ESSID */
127 	iwe.cmd = SIOCGIWESSID;
128 	iwe.u.data.flags = 1;
129 	iwe.u.data.length = min_t(u16, pnetwork->network.Ssid.SsidLength, 32);
130 	start = iwe_stream_add_point(info, start, stop, &iwe, pnetwork->network.Ssid.Ssid);
131 
132 	/* parsing HT_CAP_IE */
133 	p = rtw_get_ie(&pnetwork->network.IEs[12], _HT_CAPABILITY_IE_, &ht_ielen, pnetwork->network.IELength-12);
134 
135 	if (p && ht_ielen > 0) {
136 		struct rtw_ieee80211_ht_cap *pht_capie;
137 		ht_cap = true;
138 		pht_capie = (struct rtw_ieee80211_ht_cap *)(p+2);
139 		memcpy(&mcs_rate, pht_capie->supp_mcs_set, 2);
140 		bw_40MHz = (pht_capie->cap_info&IEEE80211_HT_CAP_SUP_WIDTH) ? 1 : 0;
141 		short_GI = (pht_capie->cap_info&(IEEE80211_HT_CAP_SGI_20|IEEE80211_HT_CAP_SGI_40)) ? 1 : 0;
142 	}
143 
144 	/* Add the protocol name */
145 	iwe.cmd = SIOCGIWNAME;
146 	if ((rtw_is_cckratesonly_included((u8 *)&pnetwork->network.SupportedRates))) {
147 		if (ht_cap)
148 			snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bn");
149 		else
150 		snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11b");
151 	} else if ((rtw_is_cckrates_included((u8 *)&pnetwork->network.SupportedRates))) {
152 		if (ht_cap)
153 			snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bgn");
154 		else
155 			snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bg");
156 	} else {
157 		if (pnetwork->network.Configuration.DSConfig > 14) {
158 			if (ht_cap)
159 				snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11an");
160 			else
161 				snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11a");
162 		} else {
163 			if (ht_cap)
164 				snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11gn");
165 			else
166 				snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11g");
167 		}
168 	}
169 
170 	start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_CHAR_LEN);
171 
172 	  /* Add mode */
173 	iwe.cmd = SIOCGIWMODE;
174 	memcpy(&le_tmp, rtw_get_capability_from_ie(pnetwork->network.IEs), 2);
175 
176 	cap = le16_to_cpu(le_tmp);
177 
178 	if (cap & (WLAN_CAPABILITY_IBSS | WLAN_CAPABILITY_BSS)) {
179 		if (cap & WLAN_CAPABILITY_BSS)
180 			iwe.u.mode = IW_MODE_MASTER;
181 		else
182 			iwe.u.mode = IW_MODE_ADHOC;
183 
184 		start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_UINT_LEN);
185 	}
186 
187 	if (pnetwork->network.Configuration.DSConfig < 1)
188 		pnetwork->network.Configuration.DSConfig = 1;
189 
190 	 /* Add frequency/channel */
191 	iwe.cmd = SIOCGIWFREQ;
192 	iwe.u.freq.m = rtw_ch2freq(pnetwork->network.Configuration.DSConfig) * 100000;
193 	iwe.u.freq.e = 1;
194 	iwe.u.freq.i = pnetwork->network.Configuration.DSConfig;
195 	start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_FREQ_LEN);
196 
197 	/* Add encryption capability */
198 	iwe.cmd = SIOCGIWENCODE;
199 	if (cap & WLAN_CAPABILITY_PRIVACY)
200 		iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
201 	else
202 		iwe.u.data.flags = IW_ENCODE_DISABLED;
203 	iwe.u.data.length = 0;
204 	start = iwe_stream_add_point(info, start, stop, &iwe, pnetwork->network.Ssid.Ssid);
205 
206 	/*Add basic and extended rates */
207 	max_rate = 0;
208 	p = custom;
209 	p += snprintf(p, MAX_CUSTOM_LEN - (p - custom), " Rates (Mb/s): ");
210 	while (pnetwork->network.SupportedRates[i] != 0) {
211 		rate = pnetwork->network.SupportedRates[i]&0x7F;
212 		if (rate > max_rate)
213 			max_rate = rate;
214 		p += snprintf(p, MAX_CUSTOM_LEN - (p - custom),
215 			      "%d%s ", rate >> 1, (rate & 1) ? ".5" : "");
216 		i++;
217 	}
218 
219 	if (ht_cap) {
220 		if (mcs_rate&0x8000)/* MCS15 */
221 			max_rate = (bw_40MHz) ? ((short_GI) ? 300 : 270) : ((short_GI) ? 144 : 130);
222 		else if (mcs_rate&0x0080)/* MCS7 */
223 			;
224 		else/* default MCS7 */
225 			max_rate = (bw_40MHz) ? ((short_GI) ? 150 : 135) : ((short_GI) ? 72 : 65);
226 
227 		max_rate = max_rate*2;/* Mbps/2; */
228 	}
229 
230 	iwe.cmd = SIOCGIWRATE;
231 	iwe.u.bitrate.fixed = 0;
232 	iwe.u.bitrate.disabled = 0;
233 	iwe.u.bitrate.value = max_rate * 500000;
234 	start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_PARAM_LEN);
235 
236 	/* parsing WPA/WPA2 IE */
237 	{
238 		u8 buf[MAX_WPA_IE_LEN];
239 		u8 wpa_ie[255], rsn_ie[255];
240 		u16 wpa_len = 0, rsn_len = 0;
241 		u8 *p;
242 
243 		rtw_get_sec_ie(pnetwork->network.IEs, pnetwork->network.IELength, rsn_ie, &rsn_len, wpa_ie, &wpa_len);
244 		RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("rtw_wx_get_scan: ssid =%s\n", pnetwork->network.Ssid.Ssid));
245 		RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("rtw_wx_get_scan: wpa_len =%d rsn_len =%d\n", wpa_len, rsn_len));
246 
247 		if (wpa_len > 0) {
248 			p = buf;
249 			memset(buf, 0, MAX_WPA_IE_LEN);
250 			p += sprintf(p, "wpa_ie=");
251 			for (i = 0; i < wpa_len; i++)
252 				p += sprintf(p, "%02x", wpa_ie[i]);
253 
254 			memset(&iwe, 0, sizeof(iwe));
255 			iwe.cmd = IWEVCUSTOM;
256 			iwe.u.data.length = strlen(buf);
257 			start = iwe_stream_add_point(info, start, stop, &iwe, buf);
258 
259 			memset(&iwe, 0, sizeof(iwe));
260 			iwe.cmd = IWEVGENIE;
261 			iwe.u.data.length = wpa_len;
262 			start = iwe_stream_add_point(info, start, stop, &iwe, wpa_ie);
263 		}
264 		if (rsn_len > 0) {
265 			p = buf;
266 			memset(buf, 0, MAX_WPA_IE_LEN);
267 			p += sprintf(p, "rsn_ie=");
268 			for (i = 0; i < rsn_len; i++)
269 				p += sprintf(p, "%02x", rsn_ie[i]);
270 			memset(&iwe, 0, sizeof(iwe));
271 			iwe.cmd = IWEVCUSTOM;
272 			iwe.u.data.length = strlen(buf);
273 			start = iwe_stream_add_point(info, start, stop, &iwe, buf);
274 
275 			memset(&iwe, 0, sizeof(iwe));
276 			iwe.cmd = IWEVGENIE;
277 			iwe.u.data.length = rsn_len;
278 			start = iwe_stream_add_point(info, start, stop, &iwe, rsn_ie);
279 		}
280 	}
281 
282 	{/* parsing WPS IE */
283 		uint cnt = 0, total_ielen;
284 		u8 *wpsie_ptr = NULL;
285 		uint wps_ielen = 0;
286 
287 		u8 *ie_ptr = pnetwork->network.IEs + _FIXED_IE_LENGTH_;
288 		total_ielen = pnetwork->network.IELength - _FIXED_IE_LENGTH_;
289 
290 		while (cnt < total_ielen) {
291 			if (rtw_is_wps_ie(&ie_ptr[cnt], &wps_ielen) && (wps_ielen > 2)) {
292 				wpsie_ptr = &ie_ptr[cnt];
293 				iwe.cmd = IWEVGENIE;
294 				iwe.u.data.length = (u16)wps_ielen;
295 				start = iwe_stream_add_point(info, start, stop, &iwe, wpsie_ptr);
296 			}
297 			cnt += ie_ptr[cnt+1]+2; /* goto next */
298 		}
299 	}
300 
301 	/* Add quality statistics */
302 	iwe.cmd = IWEVQUAL;
303 	iwe.u.qual.updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_LEVEL_UPDATED | IW_QUAL_NOISE_INVALID;
304 
305 	if (check_fwstate(pmlmepriv, _FW_LINKED) == true &&
306 	    is_same_network(&pmlmepriv->cur_network.network, &pnetwork->network)) {
307 		ss = padapter->recvpriv.signal_strength;
308 		sq = padapter->recvpriv.signal_qual;
309 	} else {
310 		ss = pnetwork->network.PhyInfo.SignalStrength;
311 		sq = pnetwork->network.PhyInfo.SignalQuality;
312 	}
313 
314 	iwe.u.qual.level = (u8)ss;
315 	iwe.u.qual.qual = (u8)sq;   /*  signal quality */
316 	iwe.u.qual.noise = 0; /*  noise level */
317 	start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_QUAL_LEN);
318 	return start;
319 }
320 
wpa_set_auth_algs(struct net_device * dev,u32 value)321 static int wpa_set_auth_algs(struct net_device *dev, u32 value)
322 {
323 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
324 	int ret = 0;
325 
326 	if ((value & AUTH_ALG_SHARED_KEY) && (value & AUTH_ALG_OPEN_SYSTEM)) {
327 		DBG_88E("wpa_set_auth_algs, AUTH_ALG_SHARED_KEY and  AUTH_ALG_OPEN_SYSTEM [value:0x%x]\n", value);
328 		padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
329 		padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeAutoSwitch;
330 		padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Auto;
331 	} else if (value & AUTH_ALG_SHARED_KEY) {
332 		DBG_88E("wpa_set_auth_algs, AUTH_ALG_SHARED_KEY  [value:0x%x]\n", value);
333 		padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
334 
335 		padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeShared;
336 		padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Shared;
337 	} else if (value & AUTH_ALG_OPEN_SYSTEM) {
338 		DBG_88E("wpa_set_auth_algs, AUTH_ALG_OPEN_SYSTEM\n");
339 		if (padapter->securitypriv.ndisauthtype < Ndis802_11AuthModeWPAPSK) {
340 			padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeOpen;
341 			padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
342 		}
343 	} else if (value & AUTH_ALG_LEAP) {
344 		DBG_88E("wpa_set_auth_algs, AUTH_ALG_LEAP\n");
345 	} else {
346 		DBG_88E("wpa_set_auth_algs, error!\n");
347 		ret = -EINVAL;
348 	}
349 	return ret;
350 }
351 
wpa_set_encryption(struct net_device * dev,struct ieee_param * param,u32 param_len)352 static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param, u32 param_len)
353 {
354 	int ret = 0;
355 	u32 wep_key_idx, wep_key_len, wep_total_len;
356 	struct ndis_802_11_wep	 *pwep = NULL;
357 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
358 	struct mlme_priv	*pmlmepriv = &padapter->mlmepriv;
359 	struct security_priv *psecuritypriv = &padapter->securitypriv;
360 
361 	param->u.crypt.err = 0;
362 	param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
363 
364 	if (param_len < (u32) ((u8 *)param->u.crypt.key - (u8 *)param) + param->u.crypt.key_len) {
365 		ret =  -EINVAL;
366 		goto exit;
367 	}
368 
369 	if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
370 	    param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
371 	    param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
372 		if (param->u.crypt.idx >= WEP_KEYS) {
373 			ret = -EINVAL;
374 			goto exit;
375 		}
376 	} else {
377 		ret = -EINVAL;
378 		goto exit;
379 	}
380 
381 	if (strcmp(param->u.crypt.alg, "WEP") == 0) {
382 		RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_err_, ("wpa_set_encryption, crypt.alg = WEP\n"));
383 		DBG_88E("wpa_set_encryption, crypt.alg = WEP\n");
384 
385 		padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
386 		padapter->securitypriv.dot11PrivacyAlgrthm = _WEP40_;
387 		padapter->securitypriv.dot118021XGrpPrivacy = _WEP40_;
388 
389 		wep_key_idx = param->u.crypt.idx;
390 		wep_key_len = param->u.crypt.key_len;
391 
392 		RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_, ("(1)wep_key_idx =%d\n", wep_key_idx));
393 		DBG_88E("(1)wep_key_idx =%d\n", wep_key_idx);
394 
395 		if (wep_key_idx > WEP_KEYS)
396 			return -EINVAL;
397 
398 		RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_, ("(2)wep_key_idx =%d\n", wep_key_idx));
399 
400 		if (wep_key_len > 0) {
401 			wep_key_len = wep_key_len <= 5 ? 5 : 13;
402 			wep_total_len = wep_key_len + FIELD_OFFSET(struct ndis_802_11_wep, KeyMaterial);
403 			pwep = (struct ndis_802_11_wep *)rtw_malloc(wep_total_len);
404 			if (pwep == NULL) {
405 				RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_err_, (" wpa_set_encryption: pwep allocate fail !!!\n"));
406 				goto exit;
407 			}
408 			memset(pwep, 0, wep_total_len);
409 			pwep->KeyLength = wep_key_len;
410 			pwep->Length = wep_total_len;
411 			if (wep_key_len == 13) {
412 				padapter->securitypriv.dot11PrivacyAlgrthm = _WEP104_;
413 				padapter->securitypriv.dot118021XGrpPrivacy = _WEP104_;
414 			}
415 		} else {
416 			ret = -EINVAL;
417 			goto exit;
418 		}
419 		pwep->KeyIndex = wep_key_idx;
420 		pwep->KeyIndex |= 0x80000000;
421 		memcpy(pwep->KeyMaterial,  param->u.crypt.key, pwep->KeyLength);
422 		if (param->u.crypt.set_tx) {
423 			DBG_88E("wep, set_tx = 1\n");
424 			if (rtw_set_802_11_add_wep(padapter, pwep) == (u8)_FAIL)
425 				ret = -EOPNOTSUPP;
426 		} else {
427 			DBG_88E("wep, set_tx = 0\n");
428 			if (wep_key_idx >= WEP_KEYS) {
429 				ret = -EOPNOTSUPP;
430 				goto exit;
431 			}
432 		      memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]), pwep->KeyMaterial, pwep->KeyLength);
433 			psecuritypriv->dot11DefKeylen[wep_key_idx] = pwep->KeyLength;
434 			rtw_set_key(padapter, psecuritypriv, wep_key_idx, 0);
435 		}
436 		goto exit;
437 	}
438 
439 	if (padapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) { /*  802_1x */
440 		struct sta_info *psta, *pbcmc_sta;
441 		struct sta_priv *pstapriv = &padapter->stapriv;
442 
443 		if (check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_MP_STATE)) { /* sta mode */
444 			psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv));
445 			if (psta == NULL) {
446 				;
447 			} else {
448 				if (strcmp(param->u.crypt.alg, "none") != 0)
449 					psta->ieee8021x_blocked = false;
450 
451 				if ((padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption2Enabled) ||
452 				    (padapter->securitypriv.ndisencryptstatus ==  Ndis802_11Encryption3Enabled))
453 					psta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm;
454 
455 				if (param->u.crypt.set_tx == 1) { /* pairwise key */
456 					memcpy(psta->dot118021x_UncstKey.skey,  param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
457 
458 					if (strcmp(param->u.crypt.alg, "TKIP") == 0) { /* set mic key */
459 						memcpy(psta->dot11tkiptxmickey.skey, &(param->u.crypt.key[16]), 8);
460 						memcpy(psta->dot11tkiprxmickey.skey, &(param->u.crypt.key[24]), 8);
461 						padapter->securitypriv.busetkipkey = false;
462 					}
463 
464 					DBG_88E(" ~~~~set sta key:unicastkey\n");
465 
466 					rtw_setstakey_cmd(padapter, (unsigned char *)psta, true);
467 				} else { /* group key */
468 					memcpy(padapter->securitypriv.dot118021XGrpKey[param->u.crypt.idx].skey,  param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
469 					memcpy(padapter->securitypriv.dot118021XGrptxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[16]), 8);
470 					memcpy(padapter->securitypriv.dot118021XGrprxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[24]), 8);
471 					padapter->securitypriv.binstallGrpkey = true;
472 					DBG_88E(" ~~~~set sta key:groupkey\n");
473 
474 					padapter->securitypriv.dot118021XGrpKeyid = param->u.crypt.idx;
475 
476 					rtw_set_key(padapter, &padapter->securitypriv, param->u.crypt.idx, 1);
477 				}
478 			}
479 			pbcmc_sta = rtw_get_bcmc_stainfo(padapter);
480 			if (pbcmc_sta == NULL) {
481 				;
482 			} else {
483 				/* Jeff: don't disable ieee8021x_blocked while clearing key */
484 				if (strcmp(param->u.crypt.alg, "none") != 0)
485 					pbcmc_sta->ieee8021x_blocked = false;
486 
487 				if ((padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption2Enabled) ||
488 				    (padapter->securitypriv.ndisencryptstatus ==  Ndis802_11Encryption3Enabled))
489 					pbcmc_sta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm;
490 			}
491 		}
492 	}
493 
494 exit:
495 
496 	kfree(pwep);
497 	return ret;
498 }
499 
rtw_set_wpa_ie(struct adapter * padapter,char * pie,unsigned short ielen)500 static int rtw_set_wpa_ie(struct adapter *padapter, char *pie, unsigned short ielen)
501 {
502 	u8 *buf = NULL;
503 	int group_cipher = 0, pairwise_cipher = 0;
504 	int ret = 0;
505 
506 	if ((ielen > MAX_WPA_IE_LEN) || (pie == NULL)) {
507 		_clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
508 		if (pie == NULL)
509 			return ret;
510 		else
511 			return -EINVAL;
512 	}
513 
514 	if (ielen) {
515 		buf = kzalloc(ielen, GFP_KERNEL);
516 		if (buf == NULL) {
517 			ret =  -ENOMEM;
518 			goto exit;
519 		}
520 
521 		memcpy(buf, pie, ielen);
522 
523 		/* dump */
524 		{
525 			int i;
526 			DBG_88E("\n wpa_ie(length:%d):\n", ielen);
527 			for (i = 0; i < ielen; i += 8)
528 				DBG_88E("0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x\n", buf[i], buf[i+1], buf[i+2], buf[i+3], buf[i+4], buf[i+5], buf[i+6], buf[i+7]);
529 		}
530 
531 		if (ielen < RSN_HEADER_LEN) {
532 			RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_err_, ("Ie len too short %d\n", ielen));
533 			ret  = -1;
534 			goto exit;
535 		}
536 
537 		if (rtw_parse_wpa_ie(buf, ielen, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) {
538 			padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
539 			padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeWPAPSK;
540 			memcpy(padapter->securitypriv.supplicant_ie, &buf[0], ielen);
541 		}
542 
543 		if (rtw_parse_wpa2_ie(buf, ielen, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) {
544 			padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
545 			padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeWPA2PSK;
546 			memcpy(padapter->securitypriv.supplicant_ie, &buf[0], ielen);
547 		}
548 
549 		switch (group_cipher) {
550 		case WPA_CIPHER_NONE:
551 			padapter->securitypriv.dot118021XGrpPrivacy = _NO_PRIVACY_;
552 			padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled;
553 			break;
554 		case WPA_CIPHER_WEP40:
555 			padapter->securitypriv.dot118021XGrpPrivacy = _WEP40_;
556 			padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
557 			break;
558 		case WPA_CIPHER_TKIP:
559 			padapter->securitypriv.dot118021XGrpPrivacy = _TKIP_;
560 			padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled;
561 			break;
562 		case WPA_CIPHER_CCMP:
563 			padapter->securitypriv.dot118021XGrpPrivacy = _AES_;
564 			padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled;
565 			break;
566 		case WPA_CIPHER_WEP104:
567 			padapter->securitypriv.dot118021XGrpPrivacy = _WEP104_;
568 			padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
569 			break;
570 		}
571 
572 		switch (pairwise_cipher) {
573 		case WPA_CIPHER_NONE:
574 			padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_;
575 			padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled;
576 			break;
577 		case WPA_CIPHER_WEP40:
578 			padapter->securitypriv.dot11PrivacyAlgrthm = _WEP40_;
579 			padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
580 			break;
581 		case WPA_CIPHER_TKIP:
582 			padapter->securitypriv.dot11PrivacyAlgrthm = _TKIP_;
583 			padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled;
584 			break;
585 		case WPA_CIPHER_CCMP:
586 			padapter->securitypriv.dot11PrivacyAlgrthm = _AES_;
587 			padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled;
588 			break;
589 		case WPA_CIPHER_WEP104:
590 			padapter->securitypriv.dot11PrivacyAlgrthm = _WEP104_;
591 			padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
592 			break;
593 		}
594 
595 		_clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
596 		{/* set wps_ie */
597 			u16 cnt = 0;
598 			u8 eid, wps_oui[4] = {0x0, 0x50, 0xf2, 0x04};
599 
600 			while (cnt < ielen) {
601 				eid = buf[cnt];
602 				if ((eid == _VENDOR_SPECIFIC_IE_) && (!memcmp(&buf[cnt+2], wps_oui, 4))) {
603 					DBG_88E("SET WPS_IE\n");
604 
605 					padapter->securitypriv.wps_ie_len = ((buf[cnt+1]+2) < (MAX_WPA_IE_LEN<<2)) ? (buf[cnt+1]+2) : (MAX_WPA_IE_LEN<<2);
606 
607 					memcpy(padapter->securitypriv.wps_ie, &buf[cnt], padapter->securitypriv.wps_ie_len);
608 
609 					set_fwstate(&padapter->mlmepriv, WIFI_UNDER_WPS);
610 					cnt += buf[cnt+1]+2;
611 					break;
612 				} else {
613 					cnt += buf[cnt+1]+2; /* goto next */
614 				}
615 			}
616 		}
617 	}
618 
619 	RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_,
620 		 ("rtw_set_wpa_ie: pairwise_cipher = 0x%08x padapter->securitypriv.ndisencryptstatus =%d padapter->securitypriv.ndisauthtype =%d\n",
621 		 pairwise_cipher, padapter->securitypriv.ndisencryptstatus, padapter->securitypriv.ndisauthtype));
622 exit:
623 	kfree(buf);
624 	return ret;
625 }
626 
627 typedef unsigned char   NDIS_802_11_RATES_EX[NDIS_802_11_LENGTH_RATES_EX];
628 
rtw_wx_get_name(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)629 static int rtw_wx_get_name(struct net_device *dev,
630 			     struct iw_request_info *info,
631 			     union iwreq_data *wrqu, char *extra)
632 {
633 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
634 	u32 ht_ielen = 0;
635 	char *p;
636 	u8 ht_cap = false;
637 	struct	mlme_priv	*pmlmepriv = &(padapter->mlmepriv);
638 	struct wlan_bssid_ex  *pcur_bss = &pmlmepriv->cur_network.network;
639 	NDIS_802_11_RATES_EX *prates = NULL;
640 
641 	RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("cmd_code =%x\n", info->cmd));
642 
643 	if (check_fwstate(pmlmepriv, _FW_LINKED|WIFI_ADHOC_MASTER_STATE) == true) {
644 		/* parsing HT_CAP_IE */
645 		p = rtw_get_ie(&pcur_bss->IEs[12], _HT_CAPABILITY_IE_, &ht_ielen, pcur_bss->IELength-12);
646 		if (p && ht_ielen > 0)
647 			ht_cap = true;
648 
649 		prates = &pcur_bss->SupportedRates;
650 
651 		if (rtw_is_cckratesonly_included((u8 *)prates) == true) {
652 			if (ht_cap)
653 				snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11bn");
654 			else
655 				snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11b");
656 		} else if ((rtw_is_cckrates_included((u8 *)prates)) == true) {
657 			if (ht_cap)
658 				snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11bgn");
659 			else
660 				snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11bg");
661 		} else {
662 			if (pcur_bss->Configuration.DSConfig > 14) {
663 				if (ht_cap)
664 					snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11an");
665 				else
666 					snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11a");
667 			} else {
668 				if (ht_cap)
669 					snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11gn");
670 				else
671 					snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11g");
672 			}
673 		}
674 	} else {
675 		snprintf(wrqu->name, IFNAMSIZ, "unassociated");
676 	}
677 	return 0;
678 }
679 
rtw_wx_set_freq(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)680 static int rtw_wx_set_freq(struct net_device *dev,
681 			     struct iw_request_info *info,
682 			     union iwreq_data *wrqu, char *extra)
683 {
684 	RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_, ("+rtw_wx_set_freq\n"));
685 	return 0;
686 }
687 
rtw_wx_get_freq(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)688 static int rtw_wx_get_freq(struct net_device *dev,
689 			     struct iw_request_info *info,
690 			     union iwreq_data *wrqu, char *extra)
691 {
692 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
693 	struct	mlme_priv	*pmlmepriv = &(padapter->mlmepriv);
694 	struct wlan_bssid_ex  *pcur_bss = &pmlmepriv->cur_network.network;
695 
696 	if (check_fwstate(pmlmepriv, _FW_LINKED)) {
697 		/* wrqu->freq.m = ieee80211_wlan_frequencies[pcur_bss->Configuration.DSConfig-1] * 100000; */
698 		wrqu->freq.m = rtw_ch2freq(pcur_bss->Configuration.DSConfig) * 100000;
699 		wrqu->freq.e = 1;
700 		wrqu->freq.i = pcur_bss->Configuration.DSConfig;
701 	} else {
702 		wrqu->freq.m = rtw_ch2freq(padapter->mlmeextpriv.cur_channel) * 100000;
703 		wrqu->freq.e = 1;
704 		wrqu->freq.i = padapter->mlmeextpriv.cur_channel;
705 	}
706 
707 	return 0;
708 }
709 
rtw_wx_set_mode(struct net_device * dev,struct iw_request_info * a,union iwreq_data * wrqu,char * b)710 static int rtw_wx_set_mode(struct net_device *dev, struct iw_request_info *a,
711 			     union iwreq_data *wrqu, char *b)
712 {
713 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
714 	enum ndis_802_11_network_infra networkType;
715 	int ret = 0;
716 
717 	if (_FAIL == rtw_pwr_wakeup(padapter)) {
718 		ret = -EPERM;
719 		goto exit;
720 	}
721 
722 	if (!padapter->hw_init_completed) {
723 		ret = -EPERM;
724 		goto exit;
725 	}
726 
727 	switch (wrqu->mode) {
728 	case IW_MODE_AUTO:
729 		networkType = Ndis802_11AutoUnknown;
730 		DBG_88E("set_mode = IW_MODE_AUTO\n");
731 		break;
732 	case IW_MODE_ADHOC:
733 		networkType = Ndis802_11IBSS;
734 		DBG_88E("set_mode = IW_MODE_ADHOC\n");
735 		break;
736 	case IW_MODE_MASTER:
737 		networkType = Ndis802_11APMode;
738 		DBG_88E("set_mode = IW_MODE_MASTER\n");
739 		break;
740 	case IW_MODE_INFRA:
741 		networkType = Ndis802_11Infrastructure;
742 		DBG_88E("set_mode = IW_MODE_INFRA\n");
743 		break;
744 	default:
745 		ret = -EINVAL;
746 		RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_err_, ("\n Mode: %s is not supported\n", iw_operation_mode[wrqu->mode]));
747 		goto exit;
748 	}
749 	if (rtw_set_802_11_infrastructure_mode(padapter, networkType) == false) {
750 		ret = -EPERM;
751 		goto exit;
752 	}
753 	rtw_setopmode_cmd(padapter, networkType);
754 exit:
755 	return ret;
756 }
757 
rtw_wx_get_mode(struct net_device * dev,struct iw_request_info * a,union iwreq_data * wrqu,char * b)758 static int rtw_wx_get_mode(struct net_device *dev, struct iw_request_info *a,
759 			     union iwreq_data *wrqu, char *b)
760 {
761 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
762 	struct	mlme_priv	*pmlmepriv = &(padapter->mlmepriv);
763 
764 	RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, (" rtw_wx_get_mode\n"));
765 
766 	if (check_fwstate(pmlmepriv, WIFI_STATION_STATE))
767 		wrqu->mode = IW_MODE_INFRA;
768 	else if  ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) ||
769 		  (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)))
770 		wrqu->mode = IW_MODE_ADHOC;
771 	else if (check_fwstate(pmlmepriv, WIFI_AP_STATE))
772 		wrqu->mode = IW_MODE_MASTER;
773 	else
774 		wrqu->mode = IW_MODE_AUTO;
775 
776 	return 0;
777 }
778 
rtw_wx_set_pmkid(struct net_device * dev,struct iw_request_info * a,union iwreq_data * wrqu,char * extra)779 static int rtw_wx_set_pmkid(struct net_device *dev,
780 			    struct iw_request_info *a,
781 			    union iwreq_data *wrqu, char *extra)
782 {
783 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
784 	u8   j, blInserted = false;
785 	int  ret = false;
786 	struct security_priv *psecuritypriv = &padapter->securitypriv;
787 	struct iw_pmksa *pPMK = (struct iw_pmksa *)extra;
788 	u8     strZeroMacAddress[ETH_ALEN] = {0x00};
789 	u8     strIssueBssid[ETH_ALEN] = {0x00};
790 
791 	memcpy(strIssueBssid, pPMK->bssid.sa_data, ETH_ALEN);
792 	if (pPMK->cmd == IW_PMKSA_ADD) {
793 		DBG_88E("[rtw_wx_set_pmkid] IW_PMKSA_ADD!\n");
794 		if (!memcmp(strIssueBssid, strZeroMacAddress, ETH_ALEN))
795 			return ret;
796 		else
797 			ret = true;
798 		blInserted = false;
799 
800 		/* overwrite PMKID */
801 		for (j = 0; j < NUM_PMKID_CACHE; j++) {
802 			if (!memcmp(psecuritypriv->PMKIDList[j].Bssid, strIssueBssid, ETH_ALEN)) {
803 				/*  BSSID is matched, the same AP => rewrite with new PMKID. */
804 				DBG_88E("[rtw_wx_set_pmkid] BSSID exists in the PMKList.\n");
805 				memcpy(psecuritypriv->PMKIDList[j].PMKID, pPMK->pmkid, IW_PMKID_LEN);
806 				psecuritypriv->PMKIDList[j].bUsed = true;
807 				psecuritypriv->PMKIDIndex = j+1;
808 				blInserted = true;
809 				break;
810 			}
811 		}
812 
813 		if (!blInserted) {
814 			/*  Find a new entry */
815 			DBG_88E("[rtw_wx_set_pmkid] Use the new entry index = %d for this PMKID.\n",
816 				psecuritypriv->PMKIDIndex);
817 
818 			memcpy(psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].Bssid, strIssueBssid, ETH_ALEN);
819 			memcpy(psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].PMKID, pPMK->pmkid, IW_PMKID_LEN);
820 
821 			psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].bUsed = true;
822 			psecuritypriv->PMKIDIndex++;
823 			if (psecuritypriv->PMKIDIndex == 16)
824 				psecuritypriv->PMKIDIndex = 0;
825 		}
826 	} else if (pPMK->cmd == IW_PMKSA_REMOVE) {
827 		DBG_88E("[rtw_wx_set_pmkid] IW_PMKSA_REMOVE!\n");
828 		ret = true;
829 		for (j = 0; j < NUM_PMKID_CACHE; j++) {
830 			if (!memcmp(psecuritypriv->PMKIDList[j].Bssid, strIssueBssid, ETH_ALEN)) {
831 				/*  BSSID is matched, the same AP => Remove this PMKID information and reset it. */
832 				memset(psecuritypriv->PMKIDList[j].Bssid, 0x00, ETH_ALEN);
833 				psecuritypriv->PMKIDList[j].bUsed = false;
834 				break;
835 			}
836 	       }
837 	} else if (pPMK->cmd == IW_PMKSA_FLUSH) {
838 		DBG_88E("[rtw_wx_set_pmkid] IW_PMKSA_FLUSH!\n");
839 		memset(&psecuritypriv->PMKIDList[0], 0x00, sizeof(struct rt_pmkid_list) * NUM_PMKID_CACHE);
840 		psecuritypriv->PMKIDIndex = 0;
841 		ret = true;
842 	}
843 	return ret;
844 }
845 
rtw_wx_get_sens(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)846 static int rtw_wx_get_sens(struct net_device *dev,
847 			     struct iw_request_info *info,
848 			     union iwreq_data *wrqu, char *extra)
849 {
850 	wrqu->sens.value = 0;
851 	wrqu->sens.fixed = 0;	/* no auto select */
852 	wrqu->sens.disabled = 1;
853 	return 0;
854 }
855 
rtw_wx_get_range(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)856 static int rtw_wx_get_range(struct net_device *dev,
857 				struct iw_request_info *info,
858 				union iwreq_data *wrqu, char *extra)
859 {
860 	struct iw_range *range = (struct iw_range *)extra;
861 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
862 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
863 
864 	u16 val;
865 	int i;
866 
867 	RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("rtw_wx_get_range. cmd_code =%x\n", info->cmd));
868 
869 	wrqu->data.length = sizeof(*range);
870 	memset(range, 0, sizeof(*range));
871 
872 	/* Let's try to keep this struct in the same order as in
873 	 * linux/include/wireless.h
874 	 */
875 
876 	/* TODO: See what values we can set, and remove the ones we can't
877 	 * set, or fill them with some default data.
878 	 */
879 
880 	/* ~5 Mb/s real (802.11b) */
881 	range->throughput = 5 * 1000 * 1000;
882 
883 	/* signal level threshold range */
884 
885 	/* percent values between 0 and 100. */
886 	range->max_qual.qual = 100;
887 	range->max_qual.level = 100;
888 	range->max_qual.noise = 100;
889 	range->max_qual.updated = 7; /* Updated all three */
890 
891 	range->avg_qual.qual = 92; /* > 8% missed beacons is 'bad' */
892 	/* TODO: Find real 'good' to 'bad' threshol value for RSSI */
893 	range->avg_qual.level = 178; /* -78 dBm */
894 	range->avg_qual.noise = 0;
895 	range->avg_qual.updated = 7; /* Updated all three */
896 
897 	range->num_bitrates = RATE_COUNT;
898 
899 	for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++)
900 		range->bitrate[i] = rtw_rates[i];
901 
902 	range->min_frag = MIN_FRAG_THRESHOLD;
903 	range->max_frag = MAX_FRAG_THRESHOLD;
904 
905 	range->pm_capa = 0;
906 
907 	range->we_version_compiled = WIRELESS_EXT;
908 	range->we_version_source = 16;
909 
910 	for (i = 0, val = 0; i < MAX_CHANNEL_NUM; i++) {
911 		/*  Include only legal frequencies for some countries */
912 		if (pmlmeext->channel_set[i].ChannelNum != 0) {
913 			range->freq[val].i = pmlmeext->channel_set[i].ChannelNum;
914 			range->freq[val].m = rtw_ch2freq(pmlmeext->channel_set[i].ChannelNum) * 100000;
915 			range->freq[val].e = 1;
916 			val++;
917 		}
918 
919 		if (val == IW_MAX_FREQUENCIES)
920 			break;
921 	}
922 
923 	range->num_channels = val;
924 	range->num_frequency = val;
925 
926 /*  The following code will proivde the security capability to network manager. */
927 /*  If the driver doesn't provide this capability to network manager, */
928 /*  the WPA/WPA2 routers can't be chosen in the network manager. */
929 
930 /*
931 #define IW_SCAN_CAPA_NONE		0x00
932 #define IW_SCAN_CAPA_ESSID		0x01
933 #define IW_SCAN_CAPA_BSSID		0x02
934 #define IW_SCAN_CAPA_CHANNEL		0x04
935 #define IW_SCAN_CAPA_MODE		0x08
936 #define IW_SCAN_CAPA_RATE		0x10
937 #define IW_SCAN_CAPA_TYPE		0x20
938 #define IW_SCAN_CAPA_TIME		0x40
939 */
940 
941 	range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
942 			  IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
943 
944 	range->scan_capa = IW_SCAN_CAPA_ESSID | IW_SCAN_CAPA_TYPE |
945 			   IW_SCAN_CAPA_BSSID | IW_SCAN_CAPA_CHANNEL |
946 			   IW_SCAN_CAPA_MODE | IW_SCAN_CAPA_RATE;
947 	return 0;
948 }
949 
950 /* set bssid flow */
951 /* s1. rtw_set_802_11_infrastructure_mode() */
952 /* s2. rtw_set_802_11_authentication_mode() */
953 /* s3. set_802_11_encryption_mode() */
954 /* s4. rtw_set_802_11_bssid() */
rtw_wx_set_wap(struct net_device * dev,struct iw_request_info * info,union iwreq_data * awrq,char * extra)955 static int rtw_wx_set_wap(struct net_device *dev,
956 			 struct iw_request_info *info,
957 			 union iwreq_data *awrq,
958 			 char *extra)
959 {
960 	uint ret = 0;
961 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
962 	struct sockaddr *temp = (struct sockaddr *)awrq;
963 	struct	mlme_priv	*pmlmepriv = &(padapter->mlmepriv);
964 	struct list_head *phead;
965 	u8 *dst_bssid, *src_bssid;
966 	struct __queue *queue	= &(pmlmepriv->scanned_queue);
967 	struct	wlan_network	*pnetwork = NULL;
968 	enum ndis_802_11_auth_mode	authmode;
969 
970 	if (_FAIL == rtw_pwr_wakeup(padapter)) {
971 		ret = -1;
972 		goto exit;
973 	}
974 
975 	if (!padapter->bup) {
976 		ret = -1;
977 		goto exit;
978 	}
979 
980 	if (temp->sa_family != ARPHRD_ETHER) {
981 		ret = -EINVAL;
982 		goto exit;
983 	}
984 
985 	authmode = padapter->securitypriv.ndisauthtype;
986 	spin_lock_bh(&queue->lock);
987 	phead = get_list_head(queue);
988 	pmlmepriv->pscanned = phead->next;
989 
990 	while (phead != pmlmepriv->pscanned) {
991 		pnetwork = container_of(pmlmepriv->pscanned, struct wlan_network, list);
992 
993 		pmlmepriv->pscanned = pmlmepriv->pscanned->next;
994 
995 		dst_bssid = pnetwork->network.MacAddress;
996 
997 		src_bssid = temp->sa_data;
998 
999 		if ((!memcmp(dst_bssid, src_bssid, ETH_ALEN))) {
1000 			if (!rtw_set_802_11_infrastructure_mode(padapter, pnetwork->network.InfrastructureMode)) {
1001 				ret = -1;
1002 				spin_unlock_bh(&queue->lock);
1003 				goto exit;
1004 			}
1005 
1006 				break;
1007 		}
1008 	}
1009 	spin_unlock_bh(&queue->lock);
1010 
1011 	rtw_set_802_11_authentication_mode(padapter, authmode);
1012 	/* set_802_11_encryption_mode(padapter, padapter->securitypriv.ndisencryptstatus); */
1013 	if (rtw_set_802_11_bssid(padapter, temp->sa_data) == false) {
1014 		ret = -1;
1015 		goto exit;
1016 	}
1017 
1018 exit:
1019 
1020 	return ret;
1021 }
1022 
rtw_wx_get_wap(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1023 static int rtw_wx_get_wap(struct net_device *dev,
1024 			    struct iw_request_info *info,
1025 			    union iwreq_data *wrqu, char *extra)
1026 {
1027 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
1028 	struct	mlme_priv	*pmlmepriv = &(padapter->mlmepriv);
1029 	struct wlan_bssid_ex  *pcur_bss = &pmlmepriv->cur_network.network;
1030 
1031 	wrqu->ap_addr.sa_family = ARPHRD_ETHER;
1032 
1033 	memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN);
1034 
1035 	RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("rtw_wx_get_wap\n"));
1036 
1037 	if (((check_fwstate(pmlmepriv, _FW_LINKED)) == true) ||
1038 	    ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) == true) ||
1039 	    ((check_fwstate(pmlmepriv, WIFI_AP_STATE)) == true))
1040 		memcpy(wrqu->ap_addr.sa_data, pcur_bss->MacAddress, ETH_ALEN);
1041 	else
1042 		memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN);
1043 	return 0;
1044 }
1045 
rtw_wx_set_mlme(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1046 static int rtw_wx_set_mlme(struct net_device *dev,
1047 			     struct iw_request_info *info,
1048 			     union iwreq_data *wrqu, char *extra)
1049 {
1050 	int ret = 0;
1051 	u16 reason;
1052 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
1053 	struct iw_mlme *mlme = (struct iw_mlme *)extra;
1054 
1055 	if (mlme == NULL)
1056 		return -1;
1057 
1058 	DBG_88E("%s\n", __func__);
1059 
1060 	reason = mlme->reason_code;
1061 
1062 	DBG_88E("%s, cmd =%d, reason =%d\n", __func__, mlme->cmd, reason);
1063 
1064 	switch (mlme->cmd) {
1065 	case IW_MLME_DEAUTH:
1066 		if (!rtw_set_802_11_disassociate(padapter))
1067 			ret = -1;
1068 		break;
1069 	case IW_MLME_DISASSOC:
1070 		if (!rtw_set_802_11_disassociate(padapter))
1071 			ret = -1;
1072 		break;
1073 	default:
1074 		return -EOPNOTSUPP;
1075 	}
1076 	return ret;
1077 }
1078 
rtw_wx_set_scan(struct net_device * dev,struct iw_request_info * a,union iwreq_data * wrqu,char * extra)1079 static int rtw_wx_set_scan(struct net_device *dev, struct iw_request_info *a,
1080 			     union iwreq_data *wrqu, char *extra)
1081 {
1082 	u8 _status = false;
1083 	int ret = 0;
1084 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
1085 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1086 	struct ndis_802_11_ssid ssid[RTW_SSID_SCAN_AMOUNT];
1087 	RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("rtw_wx_set_scan\n"));
1088 
1089 	if (padapter->registrypriv.mp_mode == 1) {
1090 		if (check_fwstate(pmlmepriv, WIFI_MP_STATE)) {
1091 			ret = -1;
1092 			goto exit;
1093 		}
1094 	}
1095 	if (_FAIL == rtw_pwr_wakeup(padapter)) {
1096 		ret = -1;
1097 		goto exit;
1098 	}
1099 
1100 	if (padapter->bDriverStopped) {
1101 		DBG_88E("bDriverStopped =%d\n", padapter->bDriverStopped);
1102 		ret = -1;
1103 		goto exit;
1104 	}
1105 
1106 	if (!padapter->bup) {
1107 		ret = -1;
1108 		goto exit;
1109 	}
1110 
1111 	if (!padapter->hw_init_completed) {
1112 		ret = -1;
1113 		goto exit;
1114 	}
1115 
1116 	/*  When Busy Traffic, driver do not site survey. So driver return success. */
1117 	/*  wpa_supplicant will not issue SIOCSIWSCAN cmd again after scan timeout. */
1118 	/*  modify by thomas 2011-02-22. */
1119 	if (pmlmepriv->LinkDetectInfo.bBusyTraffic) {
1120 		indicate_wx_scan_complete_event(padapter);
1121 		goto exit;
1122 	}
1123 
1124 	if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING)) {
1125 		indicate_wx_scan_complete_event(padapter);
1126 		goto exit;
1127 	}
1128 
1129 /*	For the DMP WiFi Display project, the driver won't to scan because */
1130 /*	the pmlmepriv->scan_interval is always equal to 3. */
1131 /*	So, the wpa_supplicant won't find out the WPS SoftAP. */
1132 
1133 	memset(ssid, 0, sizeof(struct ndis_802_11_ssid)*RTW_SSID_SCAN_AMOUNT);
1134 
1135 	if (wrqu->data.length == sizeof(struct iw_scan_req)) {
1136 		struct iw_scan_req *req = (struct iw_scan_req *)extra;
1137 
1138 		if (wrqu->data.flags & IW_SCAN_THIS_ESSID) {
1139 			int len = min((int)req->essid_len, IW_ESSID_MAX_SIZE);
1140 
1141 			memcpy(ssid[0].Ssid, req->essid, len);
1142 			ssid[0].SsidLength = len;
1143 
1144 			DBG_88E("IW_SCAN_THIS_ESSID, ssid =%s, len =%d\n", req->essid, req->essid_len);
1145 
1146 			spin_lock_bh(&pmlmepriv->lock);
1147 
1148 			_status = rtw_sitesurvey_cmd(padapter, ssid, 1, NULL, 0);
1149 
1150 			spin_unlock_bh(&pmlmepriv->lock);
1151 		} else if (req->scan_type == IW_SCAN_TYPE_PASSIVE) {
1152 			DBG_88E("rtw_wx_set_scan, req->scan_type == IW_SCAN_TYPE_PASSIVE\n");
1153 		}
1154 	} else {
1155 		if (wrqu->data.length >= WEXT_CSCAN_HEADER_SIZE &&
1156 		    !memcmp(extra, WEXT_CSCAN_HEADER, WEXT_CSCAN_HEADER_SIZE)) {
1157 			int len = wrqu->data.length - WEXT_CSCAN_HEADER_SIZE;
1158 			char *pos = extra+WEXT_CSCAN_HEADER_SIZE;
1159 			char section;
1160 			char sec_len;
1161 			int ssid_index = 0;
1162 
1163 			while (len >= 1) {
1164 				section = *(pos++);
1165 				len -= 1;
1166 
1167 				switch (section) {
1168 				case WEXT_CSCAN_SSID_SECTION:
1169 					if (len < 1) {
1170 						len = 0;
1171 						break;
1172 					}
1173 					sec_len = *(pos++); len -= 1;
1174 					if (sec_len > 0 && sec_len <= len) {
1175 						ssid[ssid_index].SsidLength = sec_len;
1176 						memcpy(ssid[ssid_index].Ssid, pos, ssid[ssid_index].SsidLength);
1177 						ssid_index++;
1178 					}
1179 					pos += sec_len;
1180 					len -= sec_len;
1181 					break;
1182 				case WEXT_CSCAN_TYPE_SECTION:
1183 				case WEXT_CSCAN_CHANNEL_SECTION:
1184 					pos += 1;
1185 					len -= 1;
1186 					break;
1187 				case WEXT_CSCAN_PASV_DWELL_SECTION:
1188 				case WEXT_CSCAN_HOME_DWELL_SECTION:
1189 				case WEXT_CSCAN_ACTV_DWELL_SECTION:
1190 					pos += 2;
1191 					len -= 2;
1192 					break;
1193 				default:
1194 					len = 0; /*  stop parsing */
1195 				}
1196 			}
1197 
1198 			/* it has still some scan parameter to parse, we only do this now... */
1199 			_status = rtw_set_802_11_bssid_list_scan(padapter, ssid, RTW_SSID_SCAN_AMOUNT);
1200 		} else {
1201 			_status = rtw_set_802_11_bssid_list_scan(padapter, NULL, 0);
1202 		}
1203 	}
1204 
1205 	if (!_status)
1206 		ret = -1;
1207 
1208 exit:
1209 
1210 	return ret;
1211 }
1212 
rtw_wx_get_scan(struct net_device * dev,struct iw_request_info * a,union iwreq_data * wrqu,char * extra)1213 static int rtw_wx_get_scan(struct net_device *dev, struct iw_request_info *a,
1214 			     union iwreq_data *wrqu, char *extra)
1215 {
1216 	struct list_head *plist, *phead;
1217 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
1218 	struct	mlme_priv	*pmlmepriv = &(padapter->mlmepriv);
1219 	struct __queue *queue	= &(pmlmepriv->scanned_queue);
1220 	struct	wlan_network	*pnetwork = NULL;
1221 	char *ev = extra;
1222 	char *stop = ev + wrqu->data.length;
1223 	u32 ret = 0;
1224 	u32 cnt = 0;
1225 	u32 wait_for_surveydone;
1226 	int wait_status;
1227 	RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("rtw_wx_get_scan\n"));
1228 	RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_, (" Start of Query SIOCGIWSCAN .\n"));
1229 
1230 	if (padapter->pwrctrlpriv.brfoffbyhw && padapter->bDriverStopped) {
1231 		ret = -EINVAL;
1232 		goto exit;
1233 	}
1234 
1235 	wait_for_surveydone = 100;
1236 
1237 	wait_status = _FW_UNDER_SURVEY | _FW_UNDER_LINKING;
1238 
1239 	while (check_fwstate(pmlmepriv, wait_status)) {
1240 		msleep(30);
1241 		cnt++;
1242 		if (cnt > wait_for_surveydone)
1243 			break;
1244 	}
1245 
1246 	spin_lock_bh(&(pmlmepriv->scanned_queue.lock));
1247 
1248 	phead = get_list_head(queue);
1249 	plist = phead->next;
1250 
1251 	while (phead != plist) {
1252 		if ((stop - ev) < SCAN_ITEM_SIZE) {
1253 			ret = -E2BIG;
1254 			break;
1255 		}
1256 
1257 		pnetwork = container_of(plist, struct wlan_network, list);
1258 
1259 		/* report network only if the current channel set contains the channel to which this network belongs */
1260 		if (rtw_ch_set_search_ch(padapter->mlmeextpriv.channel_set, pnetwork->network.Configuration.DSConfig) >= 0)
1261 			ev = translate_scan(padapter, a, pnetwork, ev, stop);
1262 
1263 		plist = plist->next;
1264 	}
1265 
1266 	spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
1267 
1268 	wrqu->data.length = ev-extra;
1269 	wrqu->data.flags = 0;
1270 
1271 exit:
1272 	return ret;
1273 }
1274 
1275 /* set ssid flow */
1276 /* s1. rtw_set_802_11_infrastructure_mode() */
1277 /* s2. set_802_11_authenticaion_mode() */
1278 /* s3. set_802_11_encryption_mode() */
1279 /* s4. rtw_set_802_11_ssid() */
rtw_wx_set_essid(struct net_device * dev,struct iw_request_info * a,union iwreq_data * wrqu,char * extra)1280 static int rtw_wx_set_essid(struct net_device *dev,
1281 			      struct iw_request_info *a,
1282 			      union iwreq_data *wrqu, char *extra)
1283 {
1284 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
1285 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1286 	struct __queue *queue = &pmlmepriv->scanned_queue;
1287 	struct list_head *phead;
1288 	struct wlan_network *pnetwork = NULL;
1289 	enum ndis_802_11_auth_mode authmode;
1290 	struct ndis_802_11_ssid ndis_ssid;
1291 	u8 *dst_ssid, *src_ssid;
1292 
1293 	uint ret = 0, len;
1294 
1295 
1296 	RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_,
1297 		 ("+rtw_wx_set_essid: fw_state = 0x%08x\n", get_fwstate(pmlmepriv)));
1298 	if (_FAIL == rtw_pwr_wakeup(padapter)) {
1299 		ret = -1;
1300 		goto exit;
1301 	}
1302 
1303 	if (!padapter->bup) {
1304 		ret = -1;
1305 		goto exit;
1306 	}
1307 
1308 	if (wrqu->essid.length > IW_ESSID_MAX_SIZE) {
1309 		ret = -E2BIG;
1310 		goto exit;
1311 	}
1312 
1313 	if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
1314 		ret = -1;
1315 		goto exit;
1316 	}
1317 
1318 	authmode = padapter->securitypriv.ndisauthtype;
1319 	DBG_88E("=>%s\n", __func__);
1320 	if (wrqu->essid.flags && wrqu->essid.length) {
1321 		len = (wrqu->essid.length < IW_ESSID_MAX_SIZE) ? wrqu->essid.length : IW_ESSID_MAX_SIZE;
1322 
1323 		if (wrqu->essid.length != 33)
1324 			DBG_88E("ssid =%s, len =%d\n", extra, wrqu->essid.length);
1325 
1326 		memset(&ndis_ssid, 0, sizeof(struct ndis_802_11_ssid));
1327 		ndis_ssid.SsidLength = len;
1328 		memcpy(ndis_ssid.Ssid, extra, len);
1329 		src_ssid = ndis_ssid.Ssid;
1330 
1331 		RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_, ("rtw_wx_set_essid: ssid =[%s]\n", src_ssid));
1332 		spin_lock_bh(&queue->lock);
1333 	       phead = get_list_head(queue);
1334 	      pmlmepriv->pscanned = phead->next;
1335 
1336 		while (phead != pmlmepriv->pscanned) {
1337 			pnetwork = container_of(pmlmepriv->pscanned, struct wlan_network, list);
1338 
1339 			pmlmepriv->pscanned = pmlmepriv->pscanned->next;
1340 
1341 			dst_ssid = pnetwork->network.Ssid.Ssid;
1342 
1343 			RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_,
1344 				 ("rtw_wx_set_essid: dst_ssid =%s\n",
1345 				  pnetwork->network.Ssid.Ssid));
1346 
1347 			if ((!memcmp(dst_ssid, src_ssid, ndis_ssid.SsidLength)) &&
1348 			    (pnetwork->network.Ssid.SsidLength == ndis_ssid.SsidLength)) {
1349 				RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_,
1350 					 ("rtw_wx_set_essid: find match, set infra mode\n"));
1351 
1352 				if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == true) {
1353 					if (pnetwork->network.InfrastructureMode != pmlmepriv->cur_network.network.InfrastructureMode)
1354 						continue;
1355 				}
1356 
1357 				if (!rtw_set_802_11_infrastructure_mode(padapter, pnetwork->network.InfrastructureMode)) {
1358 					ret = -1;
1359 					spin_unlock_bh(&queue->lock);
1360 					goto exit;
1361 				}
1362 
1363 				break;
1364 			}
1365 		}
1366 		spin_unlock_bh(&queue->lock);
1367 		RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_,
1368 			 ("set ssid: set_802_11_auth. mode =%d\n", authmode));
1369 		rtw_set_802_11_authentication_mode(padapter, authmode);
1370 		if (rtw_set_802_11_ssid(padapter, &ndis_ssid) == false) {
1371 			ret = -1;
1372 			goto exit;
1373 		}
1374 	}
1375 
1376 exit:
1377 
1378 	DBG_88E("<=%s, ret %d\n", __func__, ret);
1379 
1380 
1381 	return ret;
1382 }
1383 
rtw_wx_get_essid(struct net_device * dev,struct iw_request_info * a,union iwreq_data * wrqu,char * extra)1384 static int rtw_wx_get_essid(struct net_device *dev,
1385 			      struct iw_request_info *a,
1386 			      union iwreq_data *wrqu, char *extra)
1387 {
1388 	u32 len, ret = 0;
1389 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
1390 	struct	mlme_priv	*pmlmepriv = &(padapter->mlmepriv);
1391 	struct wlan_bssid_ex  *pcur_bss = &pmlmepriv->cur_network.network;
1392 
1393 	RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("rtw_wx_get_essid\n"));
1394 
1395 
1396 	if ((check_fwstate(pmlmepriv, _FW_LINKED)) ||
1397 	    (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE))) {
1398 		len = pcur_bss->Ssid.SsidLength;
1399 		memcpy(extra, pcur_bss->Ssid.Ssid, len);
1400 	} else {
1401 		len = 0;
1402 		*extra = 0;
1403 	}
1404 	wrqu->essid.length = len;
1405 	wrqu->essid.flags = 1;
1406 
1407 	return ret;
1408 }
1409 
rtw_wx_set_rate(struct net_device * dev,struct iw_request_info * a,union iwreq_data * wrqu,char * extra)1410 static int rtw_wx_set_rate(struct net_device *dev,
1411 			      struct iw_request_info *a,
1412 			      union iwreq_data *wrqu, char *extra)
1413 {
1414 	int i, ret = 0;
1415 	u8 datarates[NumRates];
1416 	u32	target_rate = wrqu->bitrate.value;
1417 	u32	fixed = wrqu->bitrate.fixed;
1418 	u32	ratevalue = 0;
1419 	 u8 mpdatarate[NumRates] = {11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0xff};
1420 
1421 
1422 	RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, (" rtw_wx_set_rate\n"));
1423 	RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_, ("target_rate = %d, fixed = %d\n", target_rate, fixed));
1424 
1425 	if (target_rate == -1) {
1426 		ratevalue = 11;
1427 		goto set_rate;
1428 	}
1429 	target_rate = target_rate/100000;
1430 
1431 	switch (target_rate) {
1432 	case 10:
1433 		ratevalue = 0;
1434 		break;
1435 	case 20:
1436 		ratevalue = 1;
1437 		break;
1438 	case 55:
1439 		ratevalue = 2;
1440 		break;
1441 	case 60:
1442 		ratevalue = 3;
1443 		break;
1444 	case 90:
1445 		ratevalue = 4;
1446 		break;
1447 	case 110:
1448 		ratevalue = 5;
1449 		break;
1450 	case 120:
1451 		ratevalue = 6;
1452 		break;
1453 	case 180:
1454 		ratevalue = 7;
1455 		break;
1456 	case 240:
1457 		ratevalue = 8;
1458 		break;
1459 	case 360:
1460 		ratevalue = 9;
1461 		break;
1462 	case 480:
1463 		ratevalue = 10;
1464 		break;
1465 	case 540:
1466 		ratevalue = 11;
1467 		break;
1468 	default:
1469 		ratevalue = 11;
1470 		break;
1471 	}
1472 
1473 set_rate:
1474 
1475 	for (i = 0; i < NumRates; i++) {
1476 		if (ratevalue == mpdatarate[i]) {
1477 			datarates[i] = mpdatarate[i];
1478 			if (fixed == 0)
1479 				break;
1480 		} else {
1481 			datarates[i] = 0xff;
1482 		}
1483 
1484 		RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_, ("datarate_inx =%d\n", datarates[i]));
1485 	}
1486 
1487 	return ret;
1488 }
1489 
rtw_wx_get_rate(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1490 static int rtw_wx_get_rate(struct net_device *dev,
1491 			     struct iw_request_info *info,
1492 			     union iwreq_data *wrqu, char *extra)
1493 {
1494 	u16 max_rate = 0;
1495 
1496 	max_rate = rtw_get_cur_max_rate((struct adapter *)rtw_netdev_priv(dev));
1497 
1498 	if (max_rate == 0)
1499 		return -EPERM;
1500 
1501 	wrqu->bitrate.fixed = 0;	/* no auto select */
1502 	wrqu->bitrate.value = max_rate * 100000;
1503 
1504 	return 0;
1505 }
1506 
rtw_wx_set_rts(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1507 static int rtw_wx_set_rts(struct net_device *dev,
1508 			     struct iw_request_info *info,
1509 			     union iwreq_data *wrqu, char *extra)
1510 {
1511 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
1512 
1513 
1514 	if (wrqu->rts.disabled) {
1515 		padapter->registrypriv.rts_thresh = 2347;
1516 	} else {
1517 		if (wrqu->rts.value < 0 ||
1518 		    wrqu->rts.value > 2347)
1519 			return -EINVAL;
1520 
1521 		padapter->registrypriv.rts_thresh = wrqu->rts.value;
1522 	}
1523 
1524 	DBG_88E("%s, rts_thresh =%d\n", __func__, padapter->registrypriv.rts_thresh);
1525 
1526 
1527 	return 0;
1528 }
1529 
rtw_wx_get_rts(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1530 static int rtw_wx_get_rts(struct net_device *dev,
1531 			     struct iw_request_info *info,
1532 			     union iwreq_data *wrqu, char *extra)
1533 {
1534 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
1535 
1536 
1537 	DBG_88E("%s, rts_thresh =%d\n", __func__, padapter->registrypriv.rts_thresh);
1538 
1539 	wrqu->rts.value = padapter->registrypriv.rts_thresh;
1540 	wrqu->rts.fixed = 0;	/* no auto select */
1541 	/* wrqu->rts.disabled = (wrqu->rts.value == DEFAULT_RTS_THRESHOLD); */
1542 
1543 
1544 	return 0;
1545 }
1546 
rtw_wx_set_frag(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1547 static int rtw_wx_set_frag(struct net_device *dev,
1548 			     struct iw_request_info *info,
1549 			     union iwreq_data *wrqu, char *extra)
1550 {
1551 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
1552 
1553 
1554 	if (wrqu->frag.disabled) {
1555 		padapter->xmitpriv.frag_len = MAX_FRAG_THRESHOLD;
1556 	} else {
1557 		if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
1558 		    wrqu->frag.value > MAX_FRAG_THRESHOLD)
1559 			return -EINVAL;
1560 
1561 		padapter->xmitpriv.frag_len = wrqu->frag.value & ~0x1;
1562 	}
1563 
1564 	DBG_88E("%s, frag_len =%d\n", __func__, padapter->xmitpriv.frag_len);
1565 
1566 
1567 	return 0;
1568 }
1569 
rtw_wx_get_frag(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1570 static int rtw_wx_get_frag(struct net_device *dev,
1571 			     struct iw_request_info *info,
1572 			     union iwreq_data *wrqu, char *extra)
1573 {
1574 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
1575 
1576 
1577 	DBG_88E("%s, frag_len =%d\n", __func__, padapter->xmitpriv.frag_len);
1578 
1579 	wrqu->frag.value = padapter->xmitpriv.frag_len;
1580 	wrqu->frag.fixed = 0;	/* no auto select */
1581 
1582 
1583 	return 0;
1584 }
1585 
rtw_wx_get_retry(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1586 static int rtw_wx_get_retry(struct net_device *dev,
1587 			     struct iw_request_info *info,
1588 			     union iwreq_data *wrqu, char *extra)
1589 {
1590 	wrqu->retry.value = 7;
1591 	wrqu->retry.fixed = 0;	/* no auto select */
1592 	wrqu->retry.disabled = 1;
1593 
1594 	return 0;
1595 }
1596 
rtw_wx_set_enc(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * keybuf)1597 static int rtw_wx_set_enc(struct net_device *dev,
1598 			    struct iw_request_info *info,
1599 			    union iwreq_data *wrqu, char *keybuf)
1600 {
1601 	u32 key, ret = 0;
1602 	u32 keyindex_provided;
1603 	struct ndis_802_11_wep	 wep;
1604 	enum ndis_802_11_auth_mode authmode;
1605 
1606 	struct iw_point *erq = &(wrqu->encoding);
1607 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
1608 	struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
1609 	DBG_88E("+rtw_wx_set_enc, flags = 0x%x\n", erq->flags);
1610 
1611 	memset(&wep, 0, sizeof(struct ndis_802_11_wep));
1612 
1613 	key = erq->flags & IW_ENCODE_INDEX;
1614 
1615 
1616 	if (erq->flags & IW_ENCODE_DISABLED) {
1617 		DBG_88E("EncryptionDisabled\n");
1618 		padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled;
1619 		padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_;
1620 		padapter->securitypriv.dot118021XGrpPrivacy = _NO_PRIVACY_;
1621 		padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open; /* open system */
1622 		authmode = Ndis802_11AuthModeOpen;
1623 		padapter->securitypriv.ndisauthtype = authmode;
1624 
1625 		goto exit;
1626 	}
1627 
1628 	if (key) {
1629 		if (key > WEP_KEYS)
1630 			return -EINVAL;
1631 		key--;
1632 		keyindex_provided = 1;
1633 	} else {
1634 		keyindex_provided = 0;
1635 		key = padapter->securitypriv.dot11PrivacyKeyIndex;
1636 		DBG_88E("rtw_wx_set_enc, key =%d\n", key);
1637 	}
1638 
1639 	/* set authentication mode */
1640 	if (erq->flags & IW_ENCODE_OPEN) {
1641 		DBG_88E("rtw_wx_set_enc():IW_ENCODE_OPEN\n");
1642 		padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;/* Ndis802_11EncryptionDisabled; */
1643 		padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
1644 		padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_;
1645 		padapter->securitypriv.dot118021XGrpPrivacy = _NO_PRIVACY_;
1646 		authmode = Ndis802_11AuthModeOpen;
1647 		padapter->securitypriv.ndisauthtype = authmode;
1648 	} else if (erq->flags & IW_ENCODE_RESTRICTED) {
1649 		DBG_88E("rtw_wx_set_enc():IW_ENCODE_RESTRICTED\n");
1650 		padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
1651 		padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Shared;
1652 		padapter->securitypriv.dot11PrivacyAlgrthm = _WEP40_;
1653 		padapter->securitypriv.dot118021XGrpPrivacy = _WEP40_;
1654 		authmode = Ndis802_11AuthModeShared;
1655 		padapter->securitypriv.ndisauthtype = authmode;
1656 	} else {
1657 		DBG_88E("rtw_wx_set_enc():erq->flags = 0x%x\n", erq->flags);
1658 
1659 		padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;/* Ndis802_11EncryptionDisabled; */
1660 		padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open; /* open system */
1661 		padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_;
1662 		padapter->securitypriv.dot118021XGrpPrivacy = _NO_PRIVACY_;
1663 		authmode = Ndis802_11AuthModeOpen;
1664 		padapter->securitypriv.ndisauthtype = authmode;
1665 	}
1666 
1667 	wep.KeyIndex = key;
1668 	if (erq->length > 0) {
1669 		wep.KeyLength = erq->length <= 5 ? 5 : 13;
1670 
1671 		wep.Length = wep.KeyLength + FIELD_OFFSET(struct ndis_802_11_wep, KeyMaterial);
1672 	} else {
1673 		wep.KeyLength = 0;
1674 
1675 		if (keyindex_provided == 1) {
1676 			/*  set key_id only, no given KeyMaterial(erq->length == 0). */
1677 			padapter->securitypriv.dot11PrivacyKeyIndex = key;
1678 
1679 			DBG_88E("(keyindex_provided == 1), keyid =%d, key_len =%d\n", key, padapter->securitypriv.dot11DefKeylen[key]);
1680 
1681 			switch (padapter->securitypriv.dot11DefKeylen[key]) {
1682 			case 5:
1683 				padapter->securitypriv.dot11PrivacyAlgrthm = _WEP40_;
1684 				break;
1685 			case 13:
1686 				padapter->securitypriv.dot11PrivacyAlgrthm = _WEP104_;
1687 				break;
1688 			default:
1689 				padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_;
1690 				break;
1691 			}
1692 
1693 			goto exit;
1694 		}
1695 	}
1696 
1697 	wep.KeyIndex |= 0x80000000;
1698 
1699 	memcpy(wep.KeyMaterial, keybuf, wep.KeyLength);
1700 
1701 	if (rtw_set_802_11_add_wep(padapter, &wep) == false) {
1702 		if (rf_on == pwrpriv->rf_pwrstate)
1703 			ret = -EOPNOTSUPP;
1704 		goto exit;
1705 	}
1706 
1707 exit:
1708 
1709 
1710 	return ret;
1711 }
1712 
rtw_wx_get_enc(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * keybuf)1713 static int rtw_wx_get_enc(struct net_device *dev,
1714 			    struct iw_request_info *info,
1715 			    union iwreq_data *wrqu, char *keybuf)
1716 {
1717 	uint key, ret = 0;
1718 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
1719 	struct iw_point *erq = &(wrqu->encoding);
1720 	struct	mlme_priv	*pmlmepriv = &(padapter->mlmepriv);
1721 
1722 
1723 	if (check_fwstate(pmlmepriv, _FW_LINKED) != true) {
1724 		if (!check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) {
1725 			erq->length = 0;
1726 			erq->flags |= IW_ENCODE_DISABLED;
1727 			return 0;
1728 		}
1729 	}
1730 
1731 	key = erq->flags & IW_ENCODE_INDEX;
1732 
1733 	if (key) {
1734 		if (key > WEP_KEYS)
1735 			return -EINVAL;
1736 		key--;
1737 	} else {
1738 		key = padapter->securitypriv.dot11PrivacyKeyIndex;
1739 	}
1740 
1741 	erq->flags = key + 1;
1742 
1743 	switch (padapter->securitypriv.ndisencryptstatus) {
1744 	case Ndis802_11EncryptionNotSupported:
1745 	case Ndis802_11EncryptionDisabled:
1746 		erq->length = 0;
1747 		erq->flags |= IW_ENCODE_DISABLED;
1748 		break;
1749 	case Ndis802_11Encryption1Enabled:
1750 		erq->length = padapter->securitypriv.dot11DefKeylen[key];
1751 		if (erq->length) {
1752 			memcpy(keybuf, padapter->securitypriv.dot11DefKey[key].skey, padapter->securitypriv.dot11DefKeylen[key]);
1753 
1754 			erq->flags |= IW_ENCODE_ENABLED;
1755 
1756 			if (padapter->securitypriv.ndisauthtype == Ndis802_11AuthModeOpen)
1757 				erq->flags |= IW_ENCODE_OPEN;
1758 			else if (padapter->securitypriv.ndisauthtype == Ndis802_11AuthModeShared)
1759 				erq->flags |= IW_ENCODE_RESTRICTED;
1760 		} else {
1761 			erq->length = 0;
1762 			erq->flags |= IW_ENCODE_DISABLED;
1763 		}
1764 		break;
1765 	case Ndis802_11Encryption2Enabled:
1766 	case Ndis802_11Encryption3Enabled:
1767 		erq->length = 16;
1768 		erq->flags |= (IW_ENCODE_ENABLED | IW_ENCODE_OPEN | IW_ENCODE_NOKEY);
1769 		break;
1770 	default:
1771 		erq->length = 0;
1772 		erq->flags |= IW_ENCODE_DISABLED;
1773 		break;
1774 	}
1775 
1776 	return ret;
1777 }
1778 
rtw_wx_get_power(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1779 static int rtw_wx_get_power(struct net_device *dev,
1780 			     struct iw_request_info *info,
1781 			     union iwreq_data *wrqu, char *extra)
1782 {
1783 	wrqu->power.value = 0;
1784 	wrqu->power.fixed = 0;	/* no auto select */
1785 	wrqu->power.disabled = 1;
1786 
1787 	return 0;
1788 }
1789 
rtw_wx_set_gen_ie(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1790 static int rtw_wx_set_gen_ie(struct net_device *dev,
1791 			     struct iw_request_info *info,
1792 			     union iwreq_data *wrqu, char *extra)
1793 {
1794 	int ret;
1795 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
1796 
1797 	ret = rtw_set_wpa_ie(padapter, extra, wrqu->data.length);
1798 	return ret;
1799 }
1800 
rtw_wx_set_auth(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1801 static int rtw_wx_set_auth(struct net_device *dev,
1802 			     struct iw_request_info *info,
1803 			     union iwreq_data *wrqu, char *extra)
1804 {
1805 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
1806 	struct iw_param *param = (struct iw_param *)&(wrqu->param);
1807 	int ret = 0;
1808 
1809 	switch (param->flags & IW_AUTH_INDEX) {
1810 	case IW_AUTH_WPA_VERSION:
1811 		break;
1812 	case IW_AUTH_CIPHER_PAIRWISE:
1813 
1814 		break;
1815 	case IW_AUTH_CIPHER_GROUP:
1816 
1817 		break;
1818 	case IW_AUTH_KEY_MGMT:
1819 		/*
1820 		 *  ??? does not use these parameters
1821 		 */
1822 		break;
1823 	case IW_AUTH_TKIP_COUNTERMEASURES:
1824 		if (param->value) {
1825 			/*  wpa_supplicant is enabling the tkip countermeasure. */
1826 			padapter->securitypriv.btkip_countermeasure = true;
1827 		} else {
1828 			/*  wpa_supplicant is disabling the tkip countermeasure. */
1829 			padapter->securitypriv.btkip_countermeasure = false;
1830 		}
1831 		break;
1832 	case IW_AUTH_DROP_UNENCRYPTED:
1833 		/* HACK:
1834 		 *
1835 		 * wpa_supplicant calls set_wpa_enabled when the driver
1836 		 * is loaded and unloaded, regardless of if WPA is being
1837 		 * used.  No other calls are made which can be used to
1838 		 * determine if encryption will be used or not prior to
1839 		 * association being expected.  If encryption is not being
1840 		 * used, drop_unencrypted is set to false, else true -- we
1841 		 * can use this to determine if the CAP_PRIVACY_ON bit should
1842 		 * be set.
1843 		 */
1844 
1845 		if (padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption1Enabled)
1846 			break;/* it means init value, or using wep, ndisencryptstatus = Ndis802_11Encryption1Enabled, */
1847 					/*  then it needn't reset it; */
1848 
1849 		if (param->value) {
1850 			padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled;
1851 			padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_;
1852 			padapter->securitypriv.dot118021XGrpPrivacy = _NO_PRIVACY_;
1853 			padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open; /* open system */
1854 			padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeOpen;
1855 		}
1856 
1857 		break;
1858 	case IW_AUTH_80211_AUTH_ALG:
1859 		/*
1860 		 *  It's the starting point of a link layer connection using wpa_supplicant
1861 		*/
1862 		if (check_fwstate(&padapter->mlmepriv, _FW_LINKED)) {
1863 			LeaveAllPowerSaveMode(padapter);
1864 			rtw_disassoc_cmd(padapter, 500, false);
1865 			DBG_88E("%s...call rtw_indicate_disconnect\n ", __func__);
1866 			rtw_indicate_disconnect(padapter);
1867 			rtw_free_assoc_resources(padapter, 1);
1868 		}
1869 		ret = wpa_set_auth_algs(dev, (u32)param->value);
1870 		break;
1871 	case IW_AUTH_WPA_ENABLED:
1872 		break;
1873 	case IW_AUTH_RX_UNENCRYPTED_EAPOL:
1874 		break;
1875 	case IW_AUTH_PRIVACY_INVOKED:
1876 		break;
1877 	default:
1878 		return -EOPNOTSUPP;
1879 	}
1880 
1881 	return ret;
1882 }
1883 
rtw_wx_set_enc_ext(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1884 static int rtw_wx_set_enc_ext(struct net_device *dev,
1885 			     struct iw_request_info *info,
1886 			     union iwreq_data *wrqu, char *extra)
1887 {
1888 	char *alg_name;
1889 	u32 param_len;
1890 	struct ieee_param *param = NULL;
1891 	struct iw_point *pencoding = &wrqu->encoding;
1892 	struct iw_encode_ext *pext = (struct iw_encode_ext *)extra;
1893 	int ret = 0;
1894 
1895 	param_len = sizeof(struct ieee_param) + pext->key_len;
1896 	param = (struct ieee_param *)rtw_malloc(param_len);
1897 	if (param == NULL)
1898 		return -1;
1899 
1900 	memset(param, 0, param_len);
1901 
1902 	param->cmd = IEEE_CMD_SET_ENCRYPTION;
1903 	memset(param->sta_addr, 0xff, ETH_ALEN);
1904 
1905 	switch (pext->alg) {
1906 	case IW_ENCODE_ALG_NONE:
1907 		/* todo: remove key */
1908 		/* remove = 1; */
1909 		alg_name = "none";
1910 		break;
1911 	case IW_ENCODE_ALG_WEP:
1912 		alg_name = "WEP";
1913 		break;
1914 	case IW_ENCODE_ALG_TKIP:
1915 		alg_name = "TKIP";
1916 		break;
1917 	case IW_ENCODE_ALG_CCMP:
1918 		alg_name = "CCMP";
1919 		break;
1920 	default:
1921 		ret = -1;
1922 		goto exit;
1923 	}
1924 
1925 	strncpy((char *)param->u.crypt.alg, alg_name, IEEE_CRYPT_ALG_NAME_LEN);
1926 
1927 	if (pext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
1928 		param->u.crypt.set_tx = 1;
1929 
1930 	/* cliW: WEP does not have group key
1931 	 * just not checking GROUP key setting
1932 	 */
1933 	if ((pext->alg != IW_ENCODE_ALG_WEP) &&
1934 	    (pext->ext_flags & IW_ENCODE_EXT_GROUP_KEY))
1935 		param->u.crypt.set_tx = 0;
1936 
1937 	param->u.crypt.idx = (pencoding->flags&0x00FF) - 1;
1938 
1939 	if (pext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID)
1940 		memcpy(param->u.crypt.seq, pext->rx_seq, 8);
1941 
1942 	if (pext->key_len) {
1943 		param->u.crypt.key_len = pext->key_len;
1944 		memcpy(param->u.crypt.key, pext + 1, pext->key_len);
1945 	}
1946 
1947 	ret =  wpa_set_encryption(dev, param, param_len);
1948 
1949 exit:
1950 	kfree(param);
1951 	return ret;
1952 }
1953 
rtw_wx_get_nick(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1954 static int rtw_wx_get_nick(struct net_device *dev,
1955 			   struct iw_request_info *info,
1956 			   union iwreq_data *wrqu, char *extra)
1957 {
1958 	if (extra) {
1959 		wrqu->data.length = 14;
1960 		wrqu->data.flags = 1;
1961 		memcpy(extra, "<WIFI@REALTEK>", 14);
1962 	}
1963 
1964 	/* dump debug info here */
1965 	return 0;
1966 }
1967 
dummy(struct net_device * dev,struct iw_request_info * a,union iwreq_data * wrqu,char * b)1968 static int dummy(struct net_device *dev, struct iw_request_info *a,
1969 		 union iwreq_data *wrqu, char *b)
1970 {
1971 	return -1;
1972 }
1973 
wpa_set_param(struct net_device * dev,u8 name,u32 value)1974 static int wpa_set_param(struct net_device *dev, u8 name, u32 value)
1975 {
1976 	uint ret = 0;
1977 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
1978 
1979 	switch (name) {
1980 	case IEEE_PARAM_WPA_ENABLED:
1981 		padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_8021X; /* 802.1x */
1982 		switch ((value)&0xff) {
1983 		case 1: /* WPA */
1984 			padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeWPAPSK; /* WPA_PSK */
1985 			padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled;
1986 			break;
1987 		case 2: /* WPA2 */
1988 			padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeWPA2PSK; /* WPA2_PSK */
1989 			padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled;
1990 			break;
1991 		}
1992 		RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_,
1993 			 ("wpa_set_param:padapter->securitypriv.ndisauthtype =%d\n", padapter->securitypriv.ndisauthtype));
1994 		break;
1995 	case IEEE_PARAM_TKIP_COUNTERMEASURES:
1996 		break;
1997 	case IEEE_PARAM_DROP_UNENCRYPTED: {
1998 		/* HACK:
1999 		 *
2000 		 * wpa_supplicant calls set_wpa_enabled when the driver
2001 		 * is loaded and unloaded, regardless of if WPA is being
2002 		 * used.  No other calls are made which can be used to
2003 		 * determine if encryption will be used or not prior to
2004 		 * association being expected.  If encryption is not being
2005 		 * used, drop_unencrypted is set to false, else true -- we
2006 		 * can use this to determine if the CAP_PRIVACY_ON bit should
2007 		 * be set.
2008 		 */
2009 
2010 		break;
2011 	}
2012 	case IEEE_PARAM_PRIVACY_INVOKED:
2013 		break;
2014 
2015 	case IEEE_PARAM_AUTH_ALGS:
2016 		ret = wpa_set_auth_algs(dev, value);
2017 		break;
2018 	case IEEE_PARAM_IEEE_802_1X:
2019 		break;
2020 	case IEEE_PARAM_WPAX_SELECT:
2021 		break;
2022 	default:
2023 		ret = -EOPNOTSUPP;
2024 		break;
2025 	}
2026 	return ret;
2027 }
2028 
wpa_mlme(struct net_device * dev,u32 command,u32 reason)2029 static int wpa_mlme(struct net_device *dev, u32 command, u32 reason)
2030 {
2031 	int ret = 0;
2032 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
2033 
2034 	switch (command) {
2035 	case IEEE_MLME_STA_DEAUTH:
2036 		if (!rtw_set_802_11_disassociate(padapter))
2037 			ret = -1;
2038 		break;
2039 	case IEEE_MLME_STA_DISASSOC:
2040 		if (!rtw_set_802_11_disassociate(padapter))
2041 			ret = -1;
2042 		break;
2043 	default:
2044 		ret = -EOPNOTSUPP;
2045 		break;
2046 	}
2047 
2048 	return ret;
2049 }
2050 
wpa_supplicant_ioctl(struct net_device * dev,struct iw_point * p)2051 static int wpa_supplicant_ioctl(struct net_device *dev, struct iw_point *p)
2052 {
2053 	struct ieee_param *param;
2054 	uint ret = 0;
2055 
2056 	if (p->length < sizeof(struct ieee_param) || !p->pointer) {
2057 		ret = -EINVAL;
2058 		goto out;
2059 	}
2060 
2061 	param = (struct ieee_param *)rtw_malloc(p->length);
2062 	if (param == NULL) {
2063 		ret = -ENOMEM;
2064 		goto out;
2065 	}
2066 
2067 	if (copy_from_user(param, p->pointer, p->length)) {
2068 		kfree(param);
2069 		ret = -EFAULT;
2070 		goto out;
2071 	}
2072 
2073 	switch (param->cmd) {
2074 	case IEEE_CMD_SET_WPA_PARAM:
2075 		ret = wpa_set_param(dev, param->u.wpa_param.name, param->u.wpa_param.value);
2076 		break;
2077 
2078 	case IEEE_CMD_SET_WPA_IE:
2079 		ret =  rtw_set_wpa_ie((struct adapter *)rtw_netdev_priv(dev),
2080 				      (char *)param->u.wpa_ie.data, (u16)param->u.wpa_ie.len);
2081 		break;
2082 
2083 	case IEEE_CMD_SET_ENCRYPTION:
2084 		ret = wpa_set_encryption(dev, param, p->length);
2085 		break;
2086 
2087 	case IEEE_CMD_MLME:
2088 		ret = wpa_mlme(dev, param->u.mlme.command, param->u.mlme.reason_code);
2089 		break;
2090 
2091 	default:
2092 		DBG_88E("Unknown WPA supplicant request: %d\n", param->cmd);
2093 		ret = -EOPNOTSUPP;
2094 		break;
2095 	}
2096 
2097 	if (ret == 0 && copy_to_user(p->pointer, param, p->length))
2098 		ret = -EFAULT;
2099 
2100 	kfree(param);
2101 
2102 out:
2103 
2104 	return ret;
2105 }
2106 
2107 #ifdef CONFIG_88EU_AP_MODE
set_pairwise_key(struct adapter * padapter,struct sta_info * psta)2108 static u8 set_pairwise_key(struct adapter *padapter, struct sta_info *psta)
2109 {
2110 	struct cmd_obj *ph2c;
2111 	struct set_stakey_parm	*psetstakey_para;
2112 	struct cmd_priv	*pcmdpriv = &padapter->cmdpriv;
2113 	u8 res = _SUCCESS;
2114 
2115 	ph2c = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
2116 	if (ph2c == NULL) {
2117 		res = _FAIL;
2118 		goto exit;
2119 	}
2120 
2121 	psetstakey_para = kzalloc(sizeof(struct set_stakey_parm), GFP_KERNEL);
2122 	if (psetstakey_para == NULL) {
2123 		kfree(ph2c);
2124 		res = _FAIL;
2125 		goto exit;
2126 	}
2127 
2128 	init_h2fwcmd_w_parm_no_rsp(ph2c, psetstakey_para, _SetStaKey_CMD_);
2129 
2130 	psetstakey_para->algorithm = (u8)psta->dot118021XPrivacy;
2131 
2132 	memcpy(psetstakey_para->addr, psta->hwaddr, ETH_ALEN);
2133 
2134 	memcpy(psetstakey_para->key, &psta->dot118021x_UncstKey, 16);
2135 
2136 	res = rtw_enqueue_cmd(pcmdpriv, ph2c);
2137 
2138 exit:
2139 
2140 	return res;
2141 }
2142 
set_group_key(struct adapter * padapter,u8 * key,u8 alg,int keyid)2143 static int set_group_key(struct adapter *padapter, u8 *key, u8 alg, int keyid)
2144 {
2145 	u8 keylen;
2146 	struct cmd_obj *pcmd;
2147 	struct setkey_parm *psetkeyparm;
2148 	struct cmd_priv	*pcmdpriv = &(padapter->cmdpriv);
2149 	int res = _SUCCESS;
2150 
2151 	DBG_88E("%s\n", __func__);
2152 
2153 	pcmd = kzalloc(sizeof(struct	cmd_obj), GFP_KERNEL);
2154 	if (pcmd == NULL) {
2155 		res = _FAIL;
2156 		goto exit;
2157 	}
2158 	psetkeyparm = kzalloc(sizeof(struct setkey_parm), GFP_KERNEL);
2159 	if (psetkeyparm == NULL) {
2160 		kfree(pcmd);
2161 		res = _FAIL;
2162 		goto exit;
2163 	}
2164 
2165 	memset(psetkeyparm, 0, sizeof(struct setkey_parm));
2166 
2167 	psetkeyparm->keyid = (u8)keyid;
2168 
2169 	psetkeyparm->algorithm = alg;
2170 
2171 	psetkeyparm->set_tx = 1;
2172 
2173 	switch (alg) {
2174 	case _WEP40_:
2175 		keylen = 5;
2176 		break;
2177 	case _WEP104_:
2178 		keylen = 13;
2179 		break;
2180 	case _TKIP_:
2181 	case _TKIP_WTMIC_:
2182 	case _AES_:
2183 	default:
2184 		keylen = 16;
2185 	}
2186 
2187 	memcpy(&(psetkeyparm->key[0]), key, keylen);
2188 
2189 	pcmd->cmdcode = _SetKey_CMD_;
2190 	pcmd->parmbuf = (u8 *)psetkeyparm;
2191 	pcmd->cmdsz =  (sizeof(struct setkey_parm));
2192 	pcmd->rsp = NULL;
2193 	pcmd->rspsz = 0;
2194 
2195 	INIT_LIST_HEAD(&pcmd->list);
2196 
2197 	res = rtw_enqueue_cmd(pcmdpriv, pcmd);
2198 
2199 exit:
2200 
2201 	return res;
2202 }
2203 
set_wep_key(struct adapter * padapter,u8 * key,u8 keylen,int keyid)2204 static int set_wep_key(struct adapter *padapter, u8 *key, u8 keylen, int keyid)
2205 {
2206 	u8 alg;
2207 
2208 	switch (keylen) {
2209 	case 5:
2210 		alg = _WEP40_;
2211 		break;
2212 	case 13:
2213 		alg = _WEP104_;
2214 		break;
2215 	default:
2216 		alg = _NO_PRIVACY_;
2217 	}
2218 
2219 	return set_group_key(padapter, key, alg, keyid);
2220 }
2221 
rtw_set_encryption(struct net_device * dev,struct ieee_param * param,u32 param_len)2222 static int rtw_set_encryption(struct net_device *dev, struct ieee_param *param, u32 param_len)
2223 {
2224 	int ret = 0;
2225 	u32 wep_key_idx, wep_key_len, wep_total_len;
2226 	struct ndis_802_11_wep	 *pwep = NULL;
2227 	struct sta_info *psta = NULL, *pbcmc_sta = NULL;
2228 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
2229 	struct mlme_priv	*pmlmepriv = &padapter->mlmepriv;
2230 	struct security_priv *psecuritypriv = &(padapter->securitypriv);
2231 	struct sta_priv *pstapriv = &padapter->stapriv;
2232 
2233 	DBG_88E("%s\n", __func__);
2234 	param->u.crypt.err = 0;
2235 	param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
2236 	if (param_len !=  sizeof(struct ieee_param) + param->u.crypt.key_len) {
2237 		ret =  -EINVAL;
2238 		goto exit;
2239 	}
2240 	if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
2241 	    param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
2242 	    param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
2243 		if (param->u.crypt.idx >= WEP_KEYS) {
2244 			ret = -EINVAL;
2245 			goto exit;
2246 		}
2247 	} else {
2248 		psta = rtw_get_stainfo(pstapriv, param->sta_addr);
2249 		if (!psta) {
2250 			DBG_88E("rtw_set_encryption(), sta has already been removed or never been added\n");
2251 			goto exit;
2252 		}
2253 	}
2254 
2255 	if (strcmp(param->u.crypt.alg, "none") == 0 && (psta == NULL)) {
2256 		/* todo:clear default encryption keys */
2257 
2258 		DBG_88E("clear default encryption keys, keyid =%d\n", param->u.crypt.idx);
2259 		goto exit;
2260 	}
2261 	if (strcmp(param->u.crypt.alg, "WEP") == 0 && (psta == NULL)) {
2262 		DBG_88E("r871x_set_encryption, crypt.alg = WEP\n");
2263 		wep_key_idx = param->u.crypt.idx;
2264 		wep_key_len = param->u.crypt.key_len;
2265 		DBG_88E("r871x_set_encryption, wep_key_idx=%d, len=%d\n", wep_key_idx, wep_key_len);
2266 		if ((wep_key_idx >= WEP_KEYS) || (wep_key_len <= 0)) {
2267 			ret = -EINVAL;
2268 			goto exit;
2269 		}
2270 
2271 		if (wep_key_len > 0) {
2272 			wep_key_len = wep_key_len <= 5 ? 5 : 13;
2273 			wep_total_len = wep_key_len + FIELD_OFFSET(struct ndis_802_11_wep, KeyMaterial);
2274 			pwep = (struct ndis_802_11_wep *)rtw_malloc(wep_total_len);
2275 			if (pwep == NULL) {
2276 				DBG_88E(" r871x_set_encryption: pwep allocate fail !!!\n");
2277 				goto exit;
2278 			}
2279 
2280 			memset(pwep, 0, wep_total_len);
2281 
2282 			pwep->KeyLength = wep_key_len;
2283 			pwep->Length = wep_total_len;
2284 		}
2285 
2286 		pwep->KeyIndex = wep_key_idx;
2287 
2288 		memcpy(pwep->KeyMaterial,  param->u.crypt.key, pwep->KeyLength);
2289 
2290 		if (param->u.crypt.set_tx) {
2291 			DBG_88E("wep, set_tx = 1\n");
2292 
2293 			psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled;
2294 			psecuritypriv->dot11PrivacyAlgrthm = _WEP40_;
2295 			psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
2296 
2297 			if (pwep->KeyLength == 13) {
2298 				psecuritypriv->dot11PrivacyAlgrthm = _WEP104_;
2299 				psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
2300 			}
2301 
2302 			psecuritypriv->dot11PrivacyKeyIndex = wep_key_idx;
2303 
2304 			memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]), pwep->KeyMaterial, pwep->KeyLength);
2305 
2306 			psecuritypriv->dot11DefKeylen[wep_key_idx] = pwep->KeyLength;
2307 
2308 			set_wep_key(padapter, pwep->KeyMaterial, pwep->KeyLength, wep_key_idx);
2309 		} else {
2310 			DBG_88E("wep, set_tx = 0\n");
2311 
2312 			/* don't update "psecuritypriv->dot11PrivacyAlgrthm" and */
2313 			/* psecuritypriv->dot11PrivacyKeyIndex = keyid", but can rtw_set_key to cam */
2314 
2315 		      memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]), pwep->KeyMaterial, pwep->KeyLength);
2316 
2317 			psecuritypriv->dot11DefKeylen[wep_key_idx] = pwep->KeyLength;
2318 
2319 			set_wep_key(padapter, pwep->KeyMaterial, pwep->KeyLength, wep_key_idx);
2320 		}
2321 
2322 		goto exit;
2323 	}
2324 
2325 	if (!psta && check_fwstate(pmlmepriv, WIFI_AP_STATE)) { /*  group key */
2326 		if (param->u.crypt.set_tx == 1) {
2327 			if (strcmp(param->u.crypt.alg, "WEP") == 0) {
2328 				DBG_88E("%s, set group_key, WEP\n", __func__);
2329 
2330 				memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey,
2331 					    param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
2332 
2333 				psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
2334 				if (param->u.crypt.key_len == 13)
2335 						psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
2336 			} else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
2337 				DBG_88E("%s, set group_key, TKIP\n", __func__);
2338 				psecuritypriv->dot118021XGrpPrivacy = _TKIP_;
2339 				memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey,
2340 					    param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
2341 				/* set mic key */
2342 				memcpy(psecuritypriv->dot118021XGrptxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[16]), 8);
2343 				memcpy(psecuritypriv->dot118021XGrprxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[24]), 8);
2344 
2345 				psecuritypriv->busetkipkey = true;
2346 			} else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
2347 				DBG_88E("%s, set group_key, CCMP\n", __func__);
2348 				psecuritypriv->dot118021XGrpPrivacy = _AES_;
2349 				memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey,
2350 					    param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
2351 			} else {
2352 				DBG_88E("%s, set group_key, none\n", __func__);
2353 				psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
2354 			}
2355 			psecuritypriv->dot118021XGrpKeyid = param->u.crypt.idx;
2356 			psecuritypriv->binstallGrpkey = true;
2357 			psecuritypriv->dot11PrivacyAlgrthm = psecuritypriv->dot118021XGrpPrivacy;/*  */
2358 			set_group_key(padapter, param->u.crypt.key, psecuritypriv->dot118021XGrpPrivacy, param->u.crypt.idx);
2359 			pbcmc_sta = rtw_get_bcmc_stainfo(padapter);
2360 			if (pbcmc_sta) {
2361 				pbcmc_sta->ieee8021x_blocked = false;
2362 				pbcmc_sta->dot118021XPrivacy = psecuritypriv->dot118021XGrpPrivacy;/* rx will use bmc_sta's dot118021XPrivacy */
2363 			}
2364 		}
2365 		goto exit;
2366 	}
2367 
2368 	if (psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X && psta) { /*  psk/802_1x */
2369 		if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
2370 			if (param->u.crypt.set_tx == 1) {
2371 				memcpy(psta->dot118021x_UncstKey.skey,  param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
2372 
2373 				if (strcmp(param->u.crypt.alg, "WEP") == 0) {
2374 					DBG_88E("%s, set pairwise key, WEP\n", __func__);
2375 
2376 					psta->dot118021XPrivacy = _WEP40_;
2377 					if (param->u.crypt.key_len == 13)
2378 						psta->dot118021XPrivacy = _WEP104_;
2379 				} else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
2380 					DBG_88E("%s, set pairwise key, TKIP\n", __func__);
2381 
2382 					psta->dot118021XPrivacy = _TKIP_;
2383 
2384 					/* set mic key */
2385 					memcpy(psta->dot11tkiptxmickey.skey, &(param->u.crypt.key[16]), 8);
2386 					memcpy(psta->dot11tkiprxmickey.skey, &(param->u.crypt.key[24]), 8);
2387 
2388 					psecuritypriv->busetkipkey = true;
2389 				} else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
2390 					DBG_88E("%s, set pairwise key, CCMP\n", __func__);
2391 
2392 					psta->dot118021XPrivacy = _AES_;
2393 				} else {
2394 					DBG_88E("%s, set pairwise key, none\n", __func__);
2395 
2396 					psta->dot118021XPrivacy = _NO_PRIVACY_;
2397 				}
2398 
2399 				set_pairwise_key(padapter, psta);
2400 
2401 				psta->ieee8021x_blocked = false;
2402 			} else { /* group key??? */
2403 				if (strcmp(param->u.crypt.alg, "WEP") == 0) {
2404 					memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey,
2405 						    param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
2406 					psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
2407 					if (param->u.crypt.key_len == 13)
2408 						psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
2409 				} else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
2410 					psecuritypriv->dot118021XGrpPrivacy = _TKIP_;
2411 
2412 					memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey,
2413 						    param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
2414 
2415 					/* set mic key */
2416 					memcpy(psecuritypriv->dot118021XGrptxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[16]), 8);
2417 					memcpy(psecuritypriv->dot118021XGrprxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[24]), 8);
2418 
2419 					psecuritypriv->busetkipkey = true;
2420 				} else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
2421 					psecuritypriv->dot118021XGrpPrivacy = _AES_;
2422 
2423 					memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey,
2424 						    param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
2425 				} else {
2426 					psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
2427 				}
2428 
2429 				psecuritypriv->dot118021XGrpKeyid = param->u.crypt.idx;
2430 
2431 				psecuritypriv->binstallGrpkey = true;
2432 
2433 				psecuritypriv->dot11PrivacyAlgrthm = psecuritypriv->dot118021XGrpPrivacy;/*  */
2434 
2435 				set_group_key(padapter, param->u.crypt.key, psecuritypriv->dot118021XGrpPrivacy, param->u.crypt.idx);
2436 
2437 				pbcmc_sta = rtw_get_bcmc_stainfo(padapter);
2438 				if (pbcmc_sta) {
2439 					pbcmc_sta->ieee8021x_blocked = false;
2440 					pbcmc_sta->dot118021XPrivacy = psecuritypriv->dot118021XGrpPrivacy;/* rx will use bmc_sta's dot118021XPrivacy */
2441 				}
2442 			}
2443 		}
2444 	}
2445 
2446 exit:
2447 
2448 	kfree(pwep);
2449 
2450 	return ret;
2451 }
2452 
rtw_set_beacon(struct net_device * dev,struct ieee_param * param,int len)2453 static int rtw_set_beacon(struct net_device *dev, struct ieee_param *param, int len)
2454 {
2455 	int ret = 0;
2456 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
2457 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
2458 	struct sta_priv *pstapriv = &padapter->stapriv;
2459 	unsigned char *pbuf = param->u.bcn_ie.buf;
2460 
2461 	DBG_88E("%s, len =%d\n", __func__, len);
2462 
2463 	if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true)
2464 		return -EINVAL;
2465 
2466 	memcpy(&pstapriv->max_num_sta, param->u.bcn_ie.reserved, 2);
2467 
2468 	if ((pstapriv->max_num_sta > NUM_STA) || (pstapriv->max_num_sta <= 0))
2469 		pstapriv->max_num_sta = NUM_STA;
2470 
2471 	if (rtw_check_beacon_data(padapter, pbuf,  (len-12-2)) == _SUCCESS)/*  12 = param header, 2:no packed */
2472 		ret = 0;
2473 	else
2474 		ret = -EINVAL;
2475 
2476 	return ret;
2477 }
2478 
rtw_hostapd_sta_flush(struct net_device * dev)2479 static int rtw_hostapd_sta_flush(struct net_device *dev)
2480 {
2481 	int ret = 0;
2482 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
2483 
2484 	DBG_88E("%s\n", __func__);
2485 
2486 	flush_all_cam_entry(padapter);	/* clear CAM */
2487 
2488 	ret = rtw_sta_flush(padapter);
2489 
2490 	return ret;
2491 }
2492 
rtw_add_sta(struct net_device * dev,struct ieee_param * param)2493 static int rtw_add_sta(struct net_device *dev, struct ieee_param *param)
2494 {
2495 	int ret = 0;
2496 	struct sta_info *psta = NULL;
2497 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
2498 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
2499 	struct sta_priv *pstapriv = &padapter->stapriv;
2500 
2501 	DBG_88E("rtw_add_sta(aid =%d) =%pM\n", param->u.add_sta.aid, (param->sta_addr));
2502 
2503 	if (!check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)))
2504 		return -EINVAL;
2505 
2506 	if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
2507 	    param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
2508 	    param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff)
2509 		return -EINVAL;
2510 
2511 	psta = rtw_get_stainfo(pstapriv, param->sta_addr);
2512 	if (psta) {
2513 		int flags = param->u.add_sta.flags;
2514 
2515 		psta->aid = param->u.add_sta.aid;/* aid = 1~2007 */
2516 
2517 		memcpy(psta->bssrateset, param->u.add_sta.tx_supp_rates, 16);
2518 
2519 		/* check wmm cap. */
2520 		if (WLAN_STA_WME&flags)
2521 			psta->qos_option = 1;
2522 		else
2523 			psta->qos_option = 0;
2524 
2525 		if (pmlmepriv->qospriv.qos_option == 0)
2526 			psta->qos_option = 0;
2527 
2528 		/* chec 802.11n ht cap. */
2529 		if (WLAN_STA_HT&flags) {
2530 			psta->htpriv.ht_option = true;
2531 			psta->qos_option = 1;
2532 			memcpy((void *)&psta->htpriv.ht_cap, (void *)&param->u.add_sta.ht_cap, sizeof(struct rtw_ieee80211_ht_cap));
2533 		} else {
2534 			psta->htpriv.ht_option = false;
2535 		}
2536 
2537 		if (pmlmepriv->htpriv.ht_option == false)
2538 			psta->htpriv.ht_option = false;
2539 
2540 		update_sta_info_apmode(padapter, psta);
2541 	} else {
2542 		ret = -ENOMEM;
2543 	}
2544 
2545 	return ret;
2546 }
2547 
rtw_del_sta(struct net_device * dev,struct ieee_param * param)2548 static int rtw_del_sta(struct net_device *dev, struct ieee_param *param)
2549 {
2550 	int ret = 0;
2551 	struct sta_info *psta = NULL;
2552 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
2553 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
2554 	struct sta_priv *pstapriv = &padapter->stapriv;
2555 	int updated = 0;
2556 
2557 	DBG_88E("rtw_del_sta =%pM\n", (param->sta_addr));
2558 
2559 	if (check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)) != true)
2560 		return -EINVAL;
2561 
2562 	if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
2563 	    param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
2564 	    param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff)
2565 		return -EINVAL;
2566 
2567 	psta = rtw_get_stainfo(pstapriv, param->sta_addr);
2568 	if (psta) {
2569 		spin_lock_bh(&pstapriv->asoc_list_lock);
2570 		if (!list_empty(&psta->asoc_list)) {
2571 			list_del_init(&psta->asoc_list);
2572 			pstapriv->asoc_list_cnt--;
2573 			updated = ap_free_sta(padapter, psta, true, WLAN_REASON_DEAUTH_LEAVING);
2574 		}
2575 		spin_unlock_bh(&pstapriv->asoc_list_lock);
2576 		associated_clients_update(padapter, updated);
2577 		psta = NULL;
2578 	} else {
2579 		DBG_88E("rtw_del_sta(), sta has already been removed or never been added\n");
2580 	}
2581 
2582 	return ret;
2583 }
2584 
rtw_ioctl_get_sta_data(struct net_device * dev,struct ieee_param * param,int len)2585 static int rtw_ioctl_get_sta_data(struct net_device *dev, struct ieee_param *param, int len)
2586 {
2587 	int ret = 0;
2588 	struct sta_info *psta = NULL;
2589 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
2590 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
2591 	struct sta_priv *pstapriv = &padapter->stapriv;
2592 	struct ieee_param_ex *param_ex = (struct ieee_param_ex *)param;
2593 	struct sta_data *psta_data = (struct sta_data *)param_ex->data;
2594 
2595 	DBG_88E("rtw_ioctl_get_sta_info, sta_addr: %pM\n", (param_ex->sta_addr));
2596 
2597 	if (check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)) != true)
2598 		return -EINVAL;
2599 
2600 	if (param_ex->sta_addr[0] == 0xff && param_ex->sta_addr[1] == 0xff &&
2601 	    param_ex->sta_addr[2] == 0xff && param_ex->sta_addr[3] == 0xff &&
2602 	    param_ex->sta_addr[4] == 0xff && param_ex->sta_addr[5] == 0xff)
2603 		return -EINVAL;
2604 
2605 	psta = rtw_get_stainfo(pstapriv, param_ex->sta_addr);
2606 	if (psta) {
2607 		psta_data->aid = (u16)psta->aid;
2608 		psta_data->capability = psta->capability;
2609 		psta_data->flags = psta->flags;
2610 
2611 /*
2612 		nonerp_set : BIT(0)
2613 		no_short_slot_time_set : BIT(1)
2614 		no_short_preamble_set : BIT(2)
2615 		no_ht_gf_set : BIT(3)
2616 		no_ht_set : BIT(4)
2617 		ht_20mhz_set : BIT(5)
2618 */
2619 
2620 		psta_data->sta_set = ((psta->nonerp_set) |
2621 				      (psta->no_short_slot_time_set << 1) |
2622 				      (psta->no_short_preamble_set << 2) |
2623 				      (psta->no_ht_gf_set << 3) |
2624 				      (psta->no_ht_set << 4) |
2625 				      (psta->ht_20mhz_set << 5));
2626 		psta_data->tx_supp_rates_len =  psta->bssratelen;
2627 		memcpy(psta_data->tx_supp_rates, psta->bssrateset, psta->bssratelen);
2628 		memcpy(&psta_data->ht_cap, &psta->htpriv.ht_cap, sizeof(struct rtw_ieee80211_ht_cap));
2629 		psta_data->rx_pkts = psta->sta_stats.rx_data_pkts;
2630 		psta_data->rx_bytes = psta->sta_stats.rx_bytes;
2631 		psta_data->rx_drops = psta->sta_stats.rx_drops;
2632 		psta_data->tx_pkts = psta->sta_stats.tx_pkts;
2633 		psta_data->tx_bytes = psta->sta_stats.tx_bytes;
2634 		psta_data->tx_drops = psta->sta_stats.tx_drops;
2635 	} else {
2636 		ret = -1;
2637 	}
2638 
2639 	return ret;
2640 }
2641 
rtw_get_sta_wpaie(struct net_device * dev,struct ieee_param * param)2642 static int rtw_get_sta_wpaie(struct net_device *dev, struct ieee_param *param)
2643 {
2644 	int ret = 0;
2645 	struct sta_info *psta = NULL;
2646 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
2647 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
2648 	struct sta_priv *pstapriv = &padapter->stapriv;
2649 
2650 	DBG_88E("rtw_get_sta_wpaie, sta_addr: %pM\n", (param->sta_addr));
2651 
2652 	if (check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)) != true)
2653 		return -EINVAL;
2654 
2655 	if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
2656 	    param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
2657 	    param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff)
2658 		return -EINVAL;
2659 
2660 	psta = rtw_get_stainfo(pstapriv, param->sta_addr);
2661 	if (psta) {
2662 		if ((psta->wpa_ie[0] == WLAN_EID_RSN) || (psta->wpa_ie[0] == WLAN_EID_GENERIC)) {
2663 			int wpa_ie_len;
2664 			int copy_len;
2665 
2666 			wpa_ie_len = psta->wpa_ie[1];
2667 			copy_len = ((wpa_ie_len+2) > sizeof(psta->wpa_ie)) ? (sizeof(psta->wpa_ie)) : (wpa_ie_len+2);
2668 			param->u.wpa_ie.len = copy_len;
2669 			memcpy(param->u.wpa_ie.reserved, psta->wpa_ie, copy_len);
2670 		} else {
2671 			DBG_88E("sta's wpa_ie is NONE\n");
2672 		}
2673 	} else {
2674 		ret = -1;
2675 	}
2676 
2677 	return ret;
2678 }
2679 
rtw_set_wps_beacon(struct net_device * dev,struct ieee_param * param,int len)2680 static int rtw_set_wps_beacon(struct net_device *dev, struct ieee_param *param, int len)
2681 {
2682 	int ret = 0;
2683 	unsigned char wps_oui[4] = {0x0, 0x50, 0xf2, 0x04};
2684 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
2685 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
2686 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
2687 	int ie_len;
2688 
2689 	DBG_88E("%s, len =%d\n", __func__, len);
2690 
2691 	if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true)
2692 		return -EINVAL;
2693 
2694 	ie_len = len-12-2;/*  12 = param header, 2:no packed */
2695 
2696 	if (pmlmepriv->wps_beacon_ie) {
2697 		kfree(pmlmepriv->wps_beacon_ie);
2698 		pmlmepriv->wps_beacon_ie = NULL;
2699 	}
2700 
2701 	if (ie_len > 0) {
2702 		pmlmepriv->wps_beacon_ie = rtw_malloc(ie_len);
2703 		pmlmepriv->wps_beacon_ie_len = ie_len;
2704 		if (pmlmepriv->wps_beacon_ie == NULL) {
2705 			DBG_88E("%s()-%d: rtw_malloc() ERROR!\n", __func__, __LINE__);
2706 			return -EINVAL;
2707 		}
2708 
2709 		memcpy(pmlmepriv->wps_beacon_ie, param->u.bcn_ie.buf, ie_len);
2710 
2711 		update_beacon(padapter, _VENDOR_SPECIFIC_IE_, wps_oui, true);
2712 
2713 		pmlmeext->bstart_bss = true;
2714 	}
2715 
2716 	return ret;
2717 }
2718 
rtw_set_wps_probe_resp(struct net_device * dev,struct ieee_param * param,int len)2719 static int rtw_set_wps_probe_resp(struct net_device *dev, struct ieee_param *param, int len)
2720 {
2721 	int ret = 0;
2722 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
2723 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
2724 	int ie_len;
2725 
2726 	DBG_88E("%s, len =%d\n", __func__, len);
2727 
2728 	if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true)
2729 		return -EINVAL;
2730 
2731 	ie_len = len-12-2;/*  12 = param header, 2:no packed */
2732 
2733 	if (pmlmepriv->wps_probe_resp_ie) {
2734 		kfree(pmlmepriv->wps_probe_resp_ie);
2735 		pmlmepriv->wps_probe_resp_ie = NULL;
2736 	}
2737 
2738 	if (ie_len > 0) {
2739 		pmlmepriv->wps_probe_resp_ie = rtw_malloc(ie_len);
2740 		pmlmepriv->wps_probe_resp_ie_len = ie_len;
2741 		if (pmlmepriv->wps_probe_resp_ie == NULL) {
2742 			DBG_88E("%s()-%d: rtw_malloc() ERROR!\n", __func__, __LINE__);
2743 			return -EINVAL;
2744 		}
2745 		memcpy(pmlmepriv->wps_probe_resp_ie, param->u.bcn_ie.buf, ie_len);
2746 	}
2747 
2748 	return ret;
2749 }
2750 
rtw_set_wps_assoc_resp(struct net_device * dev,struct ieee_param * param,int len)2751 static int rtw_set_wps_assoc_resp(struct net_device *dev, struct ieee_param *param, int len)
2752 {
2753 	int ret = 0;
2754 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
2755 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
2756 	int ie_len;
2757 
2758 	DBG_88E("%s, len =%d\n", __func__, len);
2759 
2760 	if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true)
2761 		return -EINVAL;
2762 
2763 	ie_len = len-12-2;/*  12 = param header, 2:no packed */
2764 
2765 	if (pmlmepriv->wps_assoc_resp_ie) {
2766 		kfree(pmlmepriv->wps_assoc_resp_ie);
2767 		pmlmepriv->wps_assoc_resp_ie = NULL;
2768 	}
2769 
2770 	if (ie_len > 0) {
2771 		pmlmepriv->wps_assoc_resp_ie = rtw_malloc(ie_len);
2772 		pmlmepriv->wps_assoc_resp_ie_len = ie_len;
2773 		if (pmlmepriv->wps_assoc_resp_ie == NULL) {
2774 			DBG_88E("%s()-%d: rtw_malloc() ERROR!\n", __func__, __LINE__);
2775 			return -EINVAL;
2776 		}
2777 
2778 		memcpy(pmlmepriv->wps_assoc_resp_ie, param->u.bcn_ie.buf, ie_len);
2779 	}
2780 
2781 	return ret;
2782 }
2783 
rtw_set_hidden_ssid(struct net_device * dev,struct ieee_param * param,int len)2784 static int rtw_set_hidden_ssid(struct net_device *dev, struct ieee_param *param, int len)
2785 {
2786 	int ret = 0;
2787 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
2788 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
2789 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
2790 	struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
2791 
2792 	u8 value;
2793 
2794 	if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true)
2795 		return -EINVAL;
2796 
2797 	if (param->u.wpa_param.name != 0) /* dummy test... */
2798 		DBG_88E("%s name(%u) != 0\n", __func__, param->u.wpa_param.name);
2799 	value = param->u.wpa_param.value;
2800 
2801 	/* use the same definition of hostapd's ignore_broadcast_ssid */
2802 	if (value != 1 && value != 2)
2803 		value = 0;
2804 	DBG_88E("%s value(%u)\n", __func__, value);
2805 	pmlmeinfo->hidden_ssid_mode = value;
2806 	return ret;
2807 }
2808 
rtw_ioctl_acl_remove_sta(struct net_device * dev,struct ieee_param * param,int len)2809 static int rtw_ioctl_acl_remove_sta(struct net_device *dev, struct ieee_param *param, int len)
2810 {
2811 	int ret = 0;
2812 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
2813 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
2814 
2815 	if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true)
2816 		return -EINVAL;
2817 
2818 	if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
2819 	    param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
2820 	    param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff)
2821 		return -EINVAL;
2822 	ret = rtw_acl_remove_sta(padapter, param->sta_addr);
2823 	return ret;
2824 }
2825 
rtw_ioctl_acl_add_sta(struct net_device * dev,struct ieee_param * param,int len)2826 static int rtw_ioctl_acl_add_sta(struct net_device *dev, struct ieee_param *param, int len)
2827 {
2828 	int ret = 0;
2829 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
2830 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
2831 
2832 	if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true)
2833 		return -EINVAL;
2834 
2835 	if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
2836 	    param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
2837 	    param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff)
2838 		return -EINVAL;
2839 	ret = rtw_acl_add_sta(padapter, param->sta_addr);
2840 	return ret;
2841 }
2842 
rtw_ioctl_set_macaddr_acl(struct net_device * dev,struct ieee_param * param,int len)2843 static int rtw_ioctl_set_macaddr_acl(struct net_device *dev, struct ieee_param *param, int len)
2844 {
2845 	int ret = 0;
2846 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
2847 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
2848 
2849 	if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true)
2850 		return -EINVAL;
2851 
2852 	rtw_set_macaddr_acl(padapter, param->u.mlme.command);
2853 
2854 	return ret;
2855 }
2856 
rtw_hostapd_ioctl(struct net_device * dev,struct iw_point * p)2857 static int rtw_hostapd_ioctl(struct net_device *dev, struct iw_point *p)
2858 {
2859 	struct ieee_param *param;
2860 	int ret = 0;
2861 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
2862 
2863 	/*
2864 	* this function is expect to call in master mode, which allows no power saving
2865 	* so, we just check hw_init_completed
2866 	*/
2867 
2868 	if (!padapter->hw_init_completed) {
2869 		ret = -EPERM;
2870 		goto out;
2871 	}
2872 
2873 	if (!p->pointer) {
2874 		ret = -EINVAL;
2875 		goto out;
2876 	}
2877 
2878 	param = (struct ieee_param *)rtw_malloc(p->length);
2879 	if (param == NULL) {
2880 		ret = -ENOMEM;
2881 		goto out;
2882 	}
2883 
2884 	if (copy_from_user(param, p->pointer, p->length)) {
2885 		kfree(param);
2886 		ret = -EFAULT;
2887 		goto out;
2888 	}
2889 
2890 	switch (param->cmd) {
2891 	case RTL871X_HOSTAPD_FLUSH:
2892 		ret = rtw_hostapd_sta_flush(dev);
2893 		break;
2894 	case RTL871X_HOSTAPD_ADD_STA:
2895 		ret = rtw_add_sta(dev, param);
2896 		break;
2897 	case RTL871X_HOSTAPD_REMOVE_STA:
2898 		ret = rtw_del_sta(dev, param);
2899 		break;
2900 	case RTL871X_HOSTAPD_SET_BEACON:
2901 		ret = rtw_set_beacon(dev, param, p->length);
2902 		break;
2903 	case RTL871X_SET_ENCRYPTION:
2904 		ret = rtw_set_encryption(dev, param, p->length);
2905 		break;
2906 	case RTL871X_HOSTAPD_GET_WPAIE_STA:
2907 		ret = rtw_get_sta_wpaie(dev, param);
2908 		break;
2909 	case RTL871X_HOSTAPD_SET_WPS_BEACON:
2910 		ret = rtw_set_wps_beacon(dev, param, p->length);
2911 		break;
2912 	case RTL871X_HOSTAPD_SET_WPS_PROBE_RESP:
2913 		ret = rtw_set_wps_probe_resp(dev, param, p->length);
2914 		break;
2915 	case RTL871X_HOSTAPD_SET_WPS_ASSOC_RESP:
2916 		ret = rtw_set_wps_assoc_resp(dev, param, p->length);
2917 		break;
2918 	case RTL871X_HOSTAPD_SET_HIDDEN_SSID:
2919 		ret = rtw_set_hidden_ssid(dev, param, p->length);
2920 		break;
2921 	case RTL871X_HOSTAPD_GET_INFO_STA:
2922 		ret = rtw_ioctl_get_sta_data(dev, param, p->length);
2923 		break;
2924 	case RTL871X_HOSTAPD_SET_MACADDR_ACL:
2925 		ret = rtw_ioctl_set_macaddr_acl(dev, param, p->length);
2926 		break;
2927 	case RTL871X_HOSTAPD_ACL_ADD_STA:
2928 		ret = rtw_ioctl_acl_add_sta(dev, param, p->length);
2929 		break;
2930 	case RTL871X_HOSTAPD_ACL_REMOVE_STA:
2931 		ret = rtw_ioctl_acl_remove_sta(dev, param, p->length);
2932 		break;
2933 	default:
2934 		DBG_88E("Unknown hostapd request: %d\n", param->cmd);
2935 		ret = -EOPNOTSUPP;
2936 		break;
2937 	}
2938 
2939 	if (ret == 0 && copy_to_user(p->pointer, param, p->length))
2940 		ret = -EFAULT;
2941 	kfree(param);
2942 out:
2943 	return ret;
2944 }
2945 #endif
2946 
2947 #include <rtw_android.h>
rtw_wx_set_priv(struct net_device * dev,struct iw_request_info * info,union iwreq_data * awrq,char * extra)2948 static int rtw_wx_set_priv(struct net_device *dev,
2949 				struct iw_request_info *info,
2950 				union iwreq_data *awrq,
2951 				char *extra)
2952 {
2953 	int ret = 0;
2954 	int len = 0;
2955 	char *ext;
2956 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
2957 	struct iw_point *dwrq = (struct iw_point *)awrq;
2958 
2959 	if (dwrq->length == 0)
2960 		return -EFAULT;
2961 
2962 	len = dwrq->length;
2963 	ext = vmalloc(len);
2964 	if (!ext)
2965 		return -ENOMEM;
2966 
2967 	if (copy_from_user(ext, dwrq->pointer, len)) {
2968 		vfree(ext);
2969 		return -EFAULT;
2970 	}
2971 
2972 	/* added for wps2.0 @20110524 */
2973 	if (dwrq->flags == 0x8766 && len > 8) {
2974 		u32 cp_sz;
2975 		struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
2976 		u8 *probereq_wpsie = ext;
2977 		int probereq_wpsie_len = len;
2978 		u8 wps_oui[4] = {0x0, 0x50, 0xf2, 0x04};
2979 
2980 		if ((_VENDOR_SPECIFIC_IE_ == probereq_wpsie[0]) &&
2981 		    (!memcmp(&probereq_wpsie[2], wps_oui, 4))) {
2982 			cp_sz = probereq_wpsie_len > MAX_WPS_IE_LEN ? MAX_WPS_IE_LEN : probereq_wpsie_len;
2983 
2984 			pmlmepriv->wps_probe_req_ie_len = 0;
2985 			kfree(pmlmepriv->wps_probe_req_ie);
2986 			pmlmepriv->wps_probe_req_ie = NULL;
2987 
2988 			pmlmepriv->wps_probe_req_ie = rtw_malloc(cp_sz);
2989 			if (pmlmepriv->wps_probe_req_ie == NULL) {
2990 				pr_info("%s()-%d: rtw_malloc() ERROR!\n", __func__, __LINE__);
2991 				ret =  -EINVAL;
2992 				goto FREE_EXT;
2993 			}
2994 			memcpy(pmlmepriv->wps_probe_req_ie, probereq_wpsie, cp_sz);
2995 			pmlmepriv->wps_probe_req_ie_len = cp_sz;
2996 		}
2997 		goto FREE_EXT;
2998 	}
2999 
3000 	if (len >= WEXT_CSCAN_HEADER_SIZE &&
3001 	    !memcmp(ext, WEXT_CSCAN_HEADER, WEXT_CSCAN_HEADER_SIZE)) {
3002 		ret = rtw_wx_set_scan(dev, info, awrq, ext);
3003 		goto FREE_EXT;
3004 	}
3005 
3006 FREE_EXT:
3007 
3008 	vfree(ext);
3009 
3010 	return ret;
3011 }
3012 
3013 static iw_handler rtw_handlers[] = {
3014 	NULL,					/* SIOCSIWCOMMIT */
3015 	rtw_wx_get_name,		/* SIOCGIWNAME */
3016 	dummy,					/* SIOCSIWNWID */
3017 	dummy,					/* SIOCGIWNWID */
3018 	rtw_wx_set_freq,		/* SIOCSIWFREQ */
3019 	rtw_wx_get_freq,		/* SIOCGIWFREQ */
3020 	rtw_wx_set_mode,		/* SIOCSIWMODE */
3021 	rtw_wx_get_mode,		/* SIOCGIWMODE */
3022 	dummy,					/* SIOCSIWSENS */
3023 	rtw_wx_get_sens,		/* SIOCGIWSENS */
3024 	NULL,					/* SIOCSIWRANGE */
3025 	rtw_wx_get_range,		/* SIOCGIWRANGE */
3026 	rtw_wx_set_priv,		/* SIOCSIWPRIV */
3027 	NULL,					/* SIOCGIWPRIV */
3028 	NULL,					/* SIOCSIWSTATS */
3029 	NULL,					/* SIOCGIWSTATS */
3030 	dummy,					/* SIOCSIWSPY */
3031 	dummy,					/* SIOCGIWSPY */
3032 	NULL,					/* SIOCGIWTHRSPY */
3033 	NULL,					/* SIOCWIWTHRSPY */
3034 	rtw_wx_set_wap,		/* SIOCSIWAP */
3035 	rtw_wx_get_wap,		/* SIOCGIWAP */
3036 	rtw_wx_set_mlme,		/* request MLME operation; uses struct iw_mlme */
3037 	dummy,					/* SIOCGIWAPLIST -- depricated */
3038 	rtw_wx_set_scan,		/* SIOCSIWSCAN */
3039 	rtw_wx_get_scan,		/* SIOCGIWSCAN */
3040 	rtw_wx_set_essid,		/* SIOCSIWESSID */
3041 	rtw_wx_get_essid,		/* SIOCGIWESSID */
3042 	dummy,					/* SIOCSIWNICKN */
3043 	rtw_wx_get_nick,		/* SIOCGIWNICKN */
3044 	NULL,					/* -- hole -- */
3045 	NULL,					/* -- hole -- */
3046 	rtw_wx_set_rate,		/* SIOCSIWRATE */
3047 	rtw_wx_get_rate,		/* SIOCGIWRATE */
3048 	rtw_wx_set_rts,			/* SIOCSIWRTS */
3049 	rtw_wx_get_rts,			/* SIOCGIWRTS */
3050 	rtw_wx_set_frag,		/* SIOCSIWFRAG */
3051 	rtw_wx_get_frag,		/* SIOCGIWFRAG */
3052 	dummy,					/* SIOCSIWTXPOW */
3053 	dummy,					/* SIOCGIWTXPOW */
3054 	dummy,					/* SIOCSIWRETRY */
3055 	rtw_wx_get_retry,		/* SIOCGIWRETRY */
3056 	rtw_wx_set_enc,			/* SIOCSIWENCODE */
3057 	rtw_wx_get_enc,			/* SIOCGIWENCODE */
3058 	dummy,					/* SIOCSIWPOWER */
3059 	rtw_wx_get_power,		/* SIOCGIWPOWER */
3060 	NULL,					/*---hole---*/
3061 	NULL,					/*---hole---*/
3062 	rtw_wx_set_gen_ie,		/* SIOCSIWGENIE */
3063 	NULL,					/* SIOCGWGENIE */
3064 	rtw_wx_set_auth,		/* SIOCSIWAUTH */
3065 	NULL,					/* SIOCGIWAUTH */
3066 	rtw_wx_set_enc_ext,		/* SIOCSIWENCODEEXT */
3067 	NULL,					/* SIOCGIWENCODEEXT */
3068 	rtw_wx_set_pmkid,		/* SIOCSIWPMKSA */
3069 	NULL,					/*---hole---*/
3070 };
3071 
rtw_get_wireless_stats(struct net_device * dev)3072 static struct iw_statistics *rtw_get_wireless_stats(struct net_device *dev)
3073 {
3074 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
3075 	struct iw_statistics *piwstats = &padapter->iwstats;
3076 	int tmp_level = 0;
3077 	int tmp_qual = 0;
3078 	int tmp_noise = 0;
3079 
3080 	if (!check_fwstate(&padapter->mlmepriv, _FW_LINKED)) {
3081 		piwstats->qual.qual = 0;
3082 		piwstats->qual.level = 0;
3083 		piwstats->qual.noise = 0;
3084 	} else {
3085 		tmp_level = padapter->recvpriv.signal_strength;
3086 		tmp_qual = padapter->recvpriv.signal_qual;
3087 		tmp_noise = padapter->recvpriv.noise;
3088 
3089 		piwstats->qual.level = tmp_level;
3090 		piwstats->qual.qual = tmp_qual;
3091 		piwstats->qual.noise = tmp_noise;
3092 	}
3093 	piwstats->qual.updated = IW_QUAL_ALL_UPDATED;/* IW_QUAL_DBM; */
3094 	return &padapter->iwstats;
3095 }
3096 
3097 struct iw_handler_def rtw_handlers_def = {
3098 	.standard = rtw_handlers,
3099 	.num_standard = sizeof(rtw_handlers) / sizeof(iw_handler),
3100 	.get_wireless_stats = rtw_get_wireless_stats,
3101 };
3102 
3103 #include <rtw_android.h>
rtw_ioctl(struct net_device * dev,struct ifreq * rq,int cmd)3104 int rtw_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
3105 {
3106 	struct iwreq *wrq = (struct iwreq *)rq;
3107 	int ret = 0;
3108 
3109 	switch (cmd) {
3110 	case RTL_IOCTL_WPA_SUPPLICANT:
3111 		ret = wpa_supplicant_ioctl(dev, &wrq->u.data);
3112 		break;
3113 #ifdef CONFIG_88EU_AP_MODE
3114 	case RTL_IOCTL_HOSTAPD:
3115 		ret = rtw_hostapd_ioctl(dev, &wrq->u.data);
3116 		break;
3117 #endif /*  CONFIG_88EU_AP_MODE */
3118 	case (SIOCDEVPRIVATE+1):
3119 		ret = rtw_android_priv_cmd(dev, rq, cmd);
3120 		break;
3121 	default:
3122 		ret = -EOPNOTSUPP;
3123 		break;
3124 	}
3125 	return ret;
3126 }
3127