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