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