1 /******************************************************************************
2  * rtl871x_ioctl_linux.c
3  *
4  * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
5  * Linux device driver for RTL8192SU
6  *
7  * This program is free software; you can redistribute it and/or modify it
8  * under the terms of version 2 of the GNU General Public License as
9  * published by the Free Software Foundation.
10  *
11  * This program is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
14  * more details.
15  *
16  * You should have received a copy of the GNU General Public License along with
17  * this program; if not, write to the Free Software Foundation, Inc.,
18  * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19  *
20  * Modifications for inclusion into the Linux staging tree are
21  * Copyright(c) 2010 Larry Finger. All rights reserved.
22  *
23  * Contact information:
24  * WLAN FAE <wlanfae@realtek.com>
25  * Larry Finger <Larry.Finger@lwfinger.net>
26  *
27  ******************************************************************************/
28 
29 #define _RTL871X_IOCTL_LINUX_C_
30 #define _RTL871X_MP_IOCTL_C_
31 
32 #include "osdep_service.h"
33 #include "drv_types.h"
34 #include "wlan_bssdef.h"
35 #include "rtl871x_debug.h"
36 #include "wifi.h"
37 #include "rtl871x_mlme.h"
38 #include "rtl871x_ioctl.h"
39 #include "rtl871x_ioctl_set.h"
40 #include "rtl871x_mp_ioctl.h"
41 #include "mlme_osdep.h"
42 #include <linux/wireless.h>
43 #include <linux/module.h>
44 #include <linux/kernel.h>
45 #include <linux/io.h>
46 #include <linux/semaphore.h>
47 #include <net/iw_handler.h>
48 #include <linux/if_arp.h>
49 #include <linux/etherdevice.h>
50 
51 
52 #define RTL_IOCTL_WPA_SUPPLICANT	(SIOCIWFIRSTPRIV + 0x1E)
53 
54 #define SCAN_ITEM_SIZE 768
55 #define MAX_CUSTOM_LEN 64
56 #define RATE_COUNT 4
57 
58 
59 static const u32 rtl8180_rates[] = {1000000, 2000000, 5500000, 11000000,
60 		       6000000, 9000000, 12000000, 18000000,
61 		       24000000, 36000000, 48000000, 54000000};
62 
63 static const long ieee80211_wlan_frequencies[] = {
64 	2412, 2417, 2422, 2427,
65 	2432, 2437, 2442, 2447,
66 	2452, 2457, 2462, 2467,
67 	2472, 2484
68 };
69 
70 static const char * const iw_operation_mode[] = {
71 	"Auto", "Ad-Hoc", "Managed",  "Master", "Repeater", "Secondary",
72 	 "Monitor"
73 };
74 
r8712_indicate_wx_assoc_event(struct _adapter * padapter)75 void r8712_indicate_wx_assoc_event(struct _adapter *padapter)
76 {
77 	union iwreq_data wrqu;
78 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
79 
80 	wrqu.ap_addr.sa_family = ARPHRD_ETHER;
81 	memcpy(wrqu.ap_addr.sa_data, pmlmepriv->cur_network.network.MacAddress,
82 		ETH_ALEN);
83 	wireless_send_event(padapter->pnetdev, SIOCGIWAP, &wrqu, NULL);
84 }
85 
r8712_indicate_wx_disassoc_event(struct _adapter * padapter)86 void r8712_indicate_wx_disassoc_event(struct _adapter *padapter)
87 {
88 	union iwreq_data wrqu;
89 
90 	wrqu.ap_addr.sa_family = ARPHRD_ETHER;
91 	eth_zero_addr(wrqu.ap_addr.sa_data);
92 	wireless_send_event(padapter->pnetdev, SIOCGIWAP, &wrqu, NULL);
93 }
94 
handle_pairwise_key(struct sta_info * psta,struct ieee_param * param,struct _adapter * padapter)95 static inline void handle_pairwise_key(struct sta_info *psta,
96 				       struct ieee_param *param,
97 				       struct _adapter *padapter)
98 {
99 	/* pairwise key */
100 	memcpy(psta->x_UncstKey.skey, param->u.crypt.key,
101 	       (param->u.crypt. key_len > 16 ? 16 : param->u.crypt.key_len));
102 	if (strcmp(param->u.crypt.alg, "TKIP") == 0) { /* set mic key */
103 		memcpy(psta->tkiptxmickey. skey,
104 		       &(param->u.crypt.key[16]), 8);
105 		memcpy(psta->tkiprxmickey. skey,
106 		       &(param->u.crypt.key[24]), 8);
107 		padapter->securitypriv. busetkipkey = false;
108 		mod_timer(&padapter->securitypriv.tkip_timer,
109 			  jiffies + msecs_to_jiffies(50));
110 	}
111 	r8712_setstakey_cmd(padapter, (unsigned char *)psta, true);
112 }
113 
handle_group_key(struct ieee_param * param,struct _adapter * padapter)114 static inline void handle_group_key(struct ieee_param *param,
115 				    struct _adapter *padapter)
116 {
117 	union Keytype *gk = padapter->securitypriv.XGrpKey;
118 	union Keytype *gtk = padapter->securitypriv.XGrptxmickey;
119 	union Keytype *grk = padapter->securitypriv.XGrprxmickey;
120 
121 	if (param->u.crypt.idx > 0 &&
122 	    param->u.crypt.idx < 3) {
123 		/* group key idx is 1 or 2 */
124 		memcpy(gk[param->u.crypt.idx - 1].skey,
125 		       param->u.crypt.key,
126 		       (param->u.crypt.key_len > 16 ? 16 :
127 			param->u.crypt.key_len));
128 		memcpy(gtk[param->u.crypt.idx - 1].skey,
129 		       &param->u.crypt.key[16], 8);
130 		memcpy(grk[param->u.crypt.idx - 1].skey,
131 		       &param->u.crypt.key[24], 8);
132 		padapter->securitypriv.binstallGrpkey = true;
133 		r8712_set_key(padapter, &padapter->securitypriv,
134 			param->u.crypt.idx);
135 		if (padapter->registrypriv.power_mgnt > PS_MODE_ACTIVE) {
136 			if (padapter->registrypriv.power_mgnt !=
137 			    padapter->pwrctrlpriv.pwr_mode)
138 				mod_timer(&padapter->mlmepriv.dhcp_timer,
139 					  jiffies + msecs_to_jiffies(60000));
140 		}
141 	}
142 }
143 
translate_scan(struct _adapter * padapter,struct iw_request_info * info,struct wlan_network * pnetwork,char * start,char * stop)144 static noinline_for_stack char *translate_scan(struct _adapter *padapter,
145 				   struct iw_request_info *info,
146 				   struct wlan_network *pnetwork,
147 				   char *start, char *stop)
148 {
149 	struct iw_event iwe;
150 	struct ieee80211_ht_cap *pht_capie;
151 	char *current_val;
152 	s8 *p;
153 	u32 i = 0, ht_ielen = 0;
154 	u16	cap, ht_cap = false, mcs_rate;
155 	u8 rssi;
156 
157 	if ((pnetwork->network.Configuration.DSConfig < 1) ||
158 	    (pnetwork->network.Configuration.DSConfig > 14)) {
159 		if (pnetwork->network.Configuration.DSConfig < 1)
160 			pnetwork->network.Configuration.DSConfig = 1;
161 		else
162 			pnetwork->network.Configuration.DSConfig = 14;
163 	}
164 	/* AP MAC address */
165 	iwe.cmd = SIOCGIWAP;
166 	iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
167 	ether_addr_copy(iwe.u.ap_addr.sa_data, pnetwork->network.MacAddress);
168 	start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_ADDR_LEN);
169 	/* Add the ESSID */
170 	iwe.cmd = SIOCGIWESSID;
171 	iwe.u.data.flags = 1;
172 	iwe.u.data.length = min_t(u32, pnetwork->network.Ssid.SsidLength, 32);
173 	start = iwe_stream_add_point(info, start, stop, &iwe,
174 				     pnetwork->network.Ssid.Ssid);
175 	/* parsing HT_CAP_IE */
176 	p = r8712_get_ie(&pnetwork->network.IEs[12], _HT_CAPABILITY_IE_,
177 			 &ht_ielen, pnetwork->network.IELength - 12);
178 	if (p && ht_ielen > 0) {
179 		ht_cap = true;
180 		pht_capie = (struct ieee80211_ht_cap *)(p + 2);
181 		memcpy(&mcs_rate, pht_capie->supp_mcs_set, 2);
182 	}
183 	/* Add the protocol name */
184 	iwe.cmd = SIOCGIWNAME;
185 	if (r8712_is_cckratesonly_included(pnetwork->network.rates)) {
186 		if (ht_cap)
187 			snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bn");
188 		else
189 			snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11b");
190 	} else if (r8712_is_cckrates_included(pnetwork->network.rates)) {
191 		if (ht_cap)
192 			snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bgn");
193 		else
194 			snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bg");
195 	} else {
196 		if (ht_cap)
197 			snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11gn");
198 		else
199 			snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11g");
200 	}
201 	start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_CHAR_LEN);
202 	/* Add mode */
203 	iwe.cmd = SIOCGIWMODE;
204 	memcpy((u8 *)&cap, r8712_get_capability_from_ie(pnetwork->network.IEs),
205 		2);
206 	le16_to_cpus(&cap);
207 	if (cap & (WLAN_CAPABILITY_IBSS | WLAN_CAPABILITY_BSS)) {
208 		if (cap & WLAN_CAPABILITY_BSS)
209 			iwe.u.mode = (u32)IW_MODE_MASTER;
210 		else
211 			iwe.u.mode = (u32)IW_MODE_ADHOC;
212 		start = iwe_stream_add_event(info, start, stop, &iwe,
213 			IW_EV_UINT_LEN);
214 	}
215 	/* Add frequency/channel */
216 	iwe.cmd = SIOCGIWFREQ;
217 	{
218 		/*  check legal index */
219 		u8 dsconfig = pnetwork->network.Configuration.DSConfig;
220 
221 		if (dsconfig >= 1 && dsconfig <= sizeof(
222 		    ieee80211_wlan_frequencies) / sizeof(long))
223 			iwe.u.freq.m =
224 				(s32)(ieee80211_wlan_frequencies
225 				      [dsconfig - 1] * 100000);
226 		else
227 			iwe.u.freq.m = 0;
228 	}
229 	iwe.u.freq.e = (s16)1;
230 	iwe.u.freq.i = (u8)pnetwork->network.Configuration.DSConfig;
231 	start = iwe_stream_add_event(info, start, stop, &iwe,
232 		IW_EV_FREQ_LEN);
233 	/* Add encryption capability */
234 	iwe.cmd = SIOCGIWENCODE;
235 	if (cap & WLAN_CAPABILITY_PRIVACY)
236 		iwe.u.data.flags = (u16)(IW_ENCODE_ENABLED |
237 				    IW_ENCODE_NOKEY);
238 	else
239 		iwe.u.data.flags = (u16)(IW_ENCODE_DISABLED);
240 	iwe.u.data.length = (u16)0;
241 	start = iwe_stream_add_point(info, start, stop, &iwe,
242 		pnetwork->network.Ssid.Ssid);
243 	/*Add basic and extended rates */
244 	current_val = start + iwe_stream_lcp_len(info);
245 	iwe.cmd = SIOCGIWRATE;
246 	iwe.u.bitrate.fixed = 0;
247 	iwe.u.bitrate.disabled = 0;
248 	iwe.u.bitrate.value = 0;
249 	i = 0;
250 	while (pnetwork->network.rates[i] != 0) {
251 		/* Bit rate given in 500 kb/s units */
252 		iwe.u.bitrate.value = (pnetwork->network.rates[i++] &
253 				      0x7F) * 500000;
254 		current_val = iwe_stream_add_value(info, start, current_val,
255 			      stop, &iwe, IW_EV_PARAM_LEN);
256 	}
257 	/* Check if we added any event */
258 	if ((current_val - start) > iwe_stream_lcp_len(info))
259 		start = current_val;
260 	/* parsing WPA/WPA2 IE */
261 	{
262 		u8 buf[MAX_WPA_IE_LEN];
263 		u8 wpa_ie[255], rsn_ie[255];
264 		u16 wpa_len = 0, rsn_len = 0;
265 		int n;
266 
267 		r8712_get_sec_ie(pnetwork->network.IEs,
268 				 pnetwork->network.IELength, rsn_ie, &rsn_len,
269 				 wpa_ie, &wpa_len);
270 		if (wpa_len > 0) {
271 			memset(buf, 0, MAX_WPA_IE_LEN);
272 			n = sprintf(buf, "wpa_ie=");
273 			for (i = 0; i < wpa_len; i++) {
274 				n += snprintf(buf + n, MAX_WPA_IE_LEN - n,
275 							"%02x", wpa_ie[i]);
276 				if (n >= MAX_WPA_IE_LEN)
277 					break;
278 			}
279 			memset(&iwe, 0, sizeof(iwe));
280 			iwe.cmd = IWEVCUSTOM;
281 			iwe.u.data.length = (u16)strlen(buf);
282 			start = iwe_stream_add_point(info, start, stop,
283 				&iwe, buf);
284 			memset(&iwe, 0, sizeof(iwe));
285 			iwe.cmd = IWEVGENIE;
286 			iwe.u.data.length = (u16)wpa_len;
287 			start = iwe_stream_add_point(info, start, stop,
288 				&iwe, wpa_ie);
289 		}
290 		if (rsn_len > 0) {
291 			memset(buf, 0, MAX_WPA_IE_LEN);
292 			n = sprintf(buf, "rsn_ie=");
293 			for (i = 0; i < rsn_len; i++) {
294 				n += snprintf(buf + n, MAX_WPA_IE_LEN - n,
295 							"%02x", rsn_ie[i]);
296 				if (n >= MAX_WPA_IE_LEN)
297 					break;
298 			}
299 			memset(&iwe, 0, sizeof(iwe));
300 			iwe.cmd = IWEVCUSTOM;
301 			iwe.u.data.length = strlen(buf);
302 			start = iwe_stream_add_point(info, start, stop,
303 				&iwe, buf);
304 			memset(&iwe, 0, sizeof(iwe));
305 			iwe.cmd = IWEVGENIE;
306 			iwe.u.data.length = rsn_len;
307 			start = iwe_stream_add_point(info, start, stop, &iwe,
308 				rsn_ie);
309 		}
310 	}
311 
312 	{ /* parsing WPS IE */
313 		u8 wps_ie[512];
314 		uint wps_ielen;
315 
316 		if (r8712_get_wps_ie(pnetwork->network.IEs,
317 		    pnetwork->network.IELength,
318 		    wps_ie, &wps_ielen)) {
319 			if (wps_ielen > 2) {
320 				iwe.cmd = IWEVGENIE;
321 				iwe.u.data.length = (u16)wps_ielen;
322 				start = iwe_stream_add_point(info, start, stop,
323 					&iwe, wps_ie);
324 			}
325 		}
326 	}
327 	/* Add quality statistics */
328 	iwe.cmd = IWEVQUAL;
329 	rssi = r8712_signal_scale_mapping(pnetwork->network.Rssi);
330 	/* we only update signal_level (signal strength) that is rssi. */
331 	iwe.u.qual.updated = (u8)(IW_QUAL_QUAL_INVALID | IW_QUAL_LEVEL_UPDATED |
332 				  IW_QUAL_NOISE_INVALID);
333 	iwe.u.qual.level = rssi;  /* signal strength */
334 	iwe.u.qual.qual = 0; /* signal quality */
335 	iwe.u.qual.noise = 0; /* noise level */
336 	start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_QUAL_LEN);
337 	/* how to translate rssi to ?% */
338 	return start;
339 }
340 
wpa_set_auth_algs(struct net_device * dev,u32 value)341 static int wpa_set_auth_algs(struct net_device *dev, u32 value)
342 {
343 	struct _adapter *padapter = netdev_priv(dev);
344 	int ret = 0;
345 
346 	if ((value & AUTH_ALG_SHARED_KEY) && (value & AUTH_ALG_OPEN_SYSTEM)) {
347 		padapter->securitypriv.ndisencryptstatus =
348 						 Ndis802_11Encryption1Enabled;
349 		padapter->securitypriv.ndisauthtype =
350 						 Ndis802_11AuthModeAutoSwitch;
351 		padapter->securitypriv.AuthAlgrthm = 3;
352 	} else if (value & AUTH_ALG_SHARED_KEY) {
353 		padapter->securitypriv.ndisencryptstatus =
354 						 Ndis802_11Encryption1Enabled;
355 		padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeShared;
356 		padapter->securitypriv.AuthAlgrthm = 1;
357 	} else if (value & AUTH_ALG_OPEN_SYSTEM) {
358 		if (padapter->securitypriv.ndisauthtype <
359 						 Ndis802_11AuthModeWPAPSK) {
360 			padapter->securitypriv.ndisauthtype =
361 						 Ndis802_11AuthModeOpen;
362 			padapter->securitypriv.AuthAlgrthm = 0;
363 		}
364 	} else {
365 		ret = -EINVAL;
366 	}
367 	return ret;
368 }
369 
wpa_set_encryption(struct net_device * dev,struct ieee_param * param,u32 param_len)370 static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param,
371 			      u32 param_len)
372 {
373 	int ret = 0;
374 	u32 wep_key_idx, wep_key_len = 0;
375 	struct NDIS_802_11_WEP	 *pwep = NULL;
376 	struct _adapter *padapter = netdev_priv(dev);
377 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
378 	struct security_priv *psecuritypriv = &padapter->securitypriv;
379 
380 	param->u.crypt.err = 0;
381 	param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
382 	if (param_len != (u32)((u8 *) param->u.crypt.key - (u8 *)param) +
383 			 param->u.crypt.key_len)
384 		return -EINVAL;
385 	if (!is_broadcast_ether_addr(param->sta_addr))
386 		return -EINVAL;
387 
388 	if (param->u.crypt.idx >= WEP_KEYS) {
389 		/* for large key indices, set the default (0) */
390 		param->u.crypt.idx = 0;
391 	}
392 	if (strcmp(param->u.crypt.alg, "WEP") == 0) {
393 		netdev_info(dev, "r8712u: %s: crypt.alg = WEP\n", __func__);
394 		padapter->securitypriv.ndisencryptstatus =
395 			     Ndis802_11Encryption1Enabled;
396 		padapter->securitypriv.PrivacyAlgrthm = _WEP40_;
397 		padapter->securitypriv.XGrpPrivacy = _WEP40_;
398 		wep_key_idx = param->u.crypt.idx;
399 		wep_key_len = param->u.crypt.key_len;
400 		if (wep_key_idx >= WEP_KEYS)
401 			wep_key_idx = 0;
402 		if (wep_key_len <= 0)
403 			return -EINVAL;
404 
405 		wep_key_len = wep_key_len <= 5 ? 5 : 13;
406 		pwep = kzalloc(sizeof(*pwep), GFP_ATOMIC);
407 		if (!pwep)
408 			return -ENOMEM;
409 		pwep->KeyLength = wep_key_len;
410 		pwep->Length = wep_key_len +
411 			FIELD_OFFSET(struct NDIS_802_11_WEP, KeyMaterial);
412 		if (wep_key_len == 13) {
413 			padapter->securitypriv.PrivacyAlgrthm = _WEP104_;
414 			padapter->securitypriv.XGrpPrivacy = _WEP104_;
415 		}
416 		pwep->KeyIndex = wep_key_idx;
417 		pwep->KeyIndex |= 0x80000000;
418 		memcpy(pwep->KeyMaterial, param->u.crypt.key, pwep->KeyLength);
419 		if (param->u.crypt.set_tx) {
420 			if (r8712_set_802_11_add_wep(padapter, pwep) ==
421 			    (u8)_FAIL)
422 				ret = -EOPNOTSUPP;
423 		} else {
424 			/* don't update "psecuritypriv->PrivacyAlgrthm" and
425 			 * "psecuritypriv->PrivacyKeyIndex=keyid", but can
426 			 * r8712_set_key to fw/cam
427 			 */
428 			if (wep_key_idx >= WEP_KEYS) {
429 				ret = -EOPNOTSUPP;
430 				goto exit;
431 			}
432 			memcpy(&psecuritypriv->DefKey[wep_key_idx].skey[0],
433 			       pwep->KeyMaterial,
434 			       pwep->KeyLength);
435 			psecuritypriv->DefKeylen[wep_key_idx] =
436 				pwep->KeyLength;
437 			r8712_set_key(padapter, psecuritypriv, wep_key_idx);
438 		}
439 		goto exit;
440 	}
441 	if (padapter->securitypriv.AuthAlgrthm == 2) { /* 802_1x */
442 		struct sta_info *psta, *pbcmc_sta;
443 		struct sta_priv *pstapriv = &padapter->stapriv;
444 		struct security_priv *spriv = &padapter->securitypriv;
445 
446 		if (check_fwstate(pmlmepriv, WIFI_STATION_STATE |
447 		    WIFI_MP_STATE)) { /* sta mode */
448 			psta = r8712_get_stainfo(pstapriv,
449 						 get_bssid(pmlmepriv));
450 			if (psta) {
451 				psta->ieee8021x_blocked = false;
452 				if (spriv->ndisencryptstatus ==
453 				    Ndis802_11Encryption2Enabled ||
454 				    spriv->ndisencryptstatus ==
455 				    Ndis802_11Encryption3Enabled)
456 					psta->XPrivacy = spriv->PrivacyAlgrthm;
457 				if (param->u.crypt.set_tx == 1)
458 					handle_pairwise_key(psta, param,
459 							    padapter);
460 				else /* group key */
461 					handle_group_key(param, padapter);
462 			}
463 			pbcmc_sta = r8712_get_bcmc_stainfo(padapter);
464 			if (pbcmc_sta) {
465 				pbcmc_sta->ieee8021x_blocked = false;
466 				if (spriv->ndisencryptstatus ==
467 				    Ndis802_11Encryption2Enabled ||
468 				    spriv->ndisencryptstatus ==
469 				    Ndis802_11Encryption3Enabled)
470 					pbcmc_sta->XPrivacy =
471 						spriv->PrivacyAlgrthm;
472 			}
473 		}
474 	}
475 exit:
476 	kfree(pwep);
477 	return ret;
478 }
479 
r871x_set_wpa_ie(struct _adapter * padapter,char * pie,unsigned short ielen)480 static int r871x_set_wpa_ie(struct _adapter *padapter, char *pie,
481 			    unsigned short ielen)
482 {
483 	u8 *buf = NULL;
484 	int group_cipher = 0, pairwise_cipher = 0;
485 	int ret = 0;
486 
487 	if ((ielen > MAX_WPA_IE_LEN) || (pie == NULL))
488 		return -EINVAL;
489 	if (ielen) {
490 		buf = kmemdup(pie, ielen, GFP_ATOMIC);
491 		if (buf == NULL)
492 			return -ENOMEM;
493 		if (ielen < RSN_HEADER_LEN) {
494 			ret  = -EINVAL;
495 			goto exit;
496 		}
497 		if (r8712_parse_wpa_ie(buf, ielen, &group_cipher,
498 		    &pairwise_cipher) == _SUCCESS) {
499 			padapter->securitypriv.AuthAlgrthm = 2;
500 			padapter->securitypriv.ndisauthtype =
501 				  Ndis802_11AuthModeWPAPSK;
502 		}
503 		if (r8712_parse_wpa2_ie(buf, ielen, &group_cipher,
504 		    &pairwise_cipher) == _SUCCESS) {
505 			padapter->securitypriv.AuthAlgrthm = 2;
506 			padapter->securitypriv.ndisauthtype =
507 				  Ndis802_11AuthModeWPA2PSK;
508 		}
509 		switch (group_cipher) {
510 		case WPA_CIPHER_NONE:
511 			padapter->securitypriv.XGrpPrivacy =
512 				 _NO_PRIVACY_;
513 			padapter->securitypriv.ndisencryptstatus =
514 				 Ndis802_11EncryptionDisabled;
515 			break;
516 		case WPA_CIPHER_WEP40:
517 			padapter->securitypriv.XGrpPrivacy = _WEP40_;
518 			padapter->securitypriv.ndisencryptstatus =
519 				 Ndis802_11Encryption1Enabled;
520 			break;
521 		case WPA_CIPHER_TKIP:
522 			padapter->securitypriv.XGrpPrivacy = _TKIP_;
523 			padapter->securitypriv.ndisencryptstatus =
524 				 Ndis802_11Encryption2Enabled;
525 			break;
526 		case WPA_CIPHER_CCMP:
527 			padapter->securitypriv.XGrpPrivacy = _AES_;
528 			padapter->securitypriv.ndisencryptstatus =
529 				 Ndis802_11Encryption3Enabled;
530 			break;
531 		case WPA_CIPHER_WEP104:
532 			padapter->securitypriv.XGrpPrivacy = _WEP104_;
533 			padapter->securitypriv.ndisencryptstatus =
534 				 Ndis802_11Encryption1Enabled;
535 			break;
536 		}
537 		switch (pairwise_cipher) {
538 		case WPA_CIPHER_NONE:
539 			padapter->securitypriv.PrivacyAlgrthm =
540 				 _NO_PRIVACY_;
541 			padapter->securitypriv.ndisencryptstatus =
542 				 Ndis802_11EncryptionDisabled;
543 			break;
544 		case WPA_CIPHER_WEP40:
545 			padapter->securitypriv.PrivacyAlgrthm = _WEP40_;
546 			padapter->securitypriv.ndisencryptstatus =
547 				 Ndis802_11Encryption1Enabled;
548 			break;
549 		case WPA_CIPHER_TKIP:
550 			padapter->securitypriv.PrivacyAlgrthm = _TKIP_;
551 			padapter->securitypriv.ndisencryptstatus =
552 				 Ndis802_11Encryption2Enabled;
553 			break;
554 		case WPA_CIPHER_CCMP:
555 			padapter->securitypriv.PrivacyAlgrthm = _AES_;
556 			padapter->securitypriv.ndisencryptstatus =
557 				 Ndis802_11Encryption3Enabled;
558 			break;
559 		case WPA_CIPHER_WEP104:
560 			padapter->securitypriv.PrivacyAlgrthm = _WEP104_;
561 			padapter->securitypriv.ndisencryptstatus =
562 				 Ndis802_11Encryption1Enabled;
563 			break;
564 		}
565 		padapter->securitypriv.wps_phase = false;
566 		{/* set wps_ie */
567 			u16 cnt = 0;
568 			u8 eid, wps_oui[4] = {0x0, 0x50, 0xf2, 0x04};
569 
570 			while (cnt < ielen) {
571 				eid = buf[cnt];
572 
573 				if ((eid == _VENDOR_SPECIFIC_IE_) &&
574 				    (!memcmp(&buf[cnt + 2], wps_oui, 4))) {
575 					netdev_info(padapter->pnetdev, "r8712u: SET WPS_IE\n");
576 					padapter->securitypriv.wps_ie_len =
577 					    ((buf[cnt + 1] + 2) <
578 					    (MAX_WPA_IE_LEN << 2)) ?
579 					    (buf[cnt + 1] + 2) :
580 					    (MAX_WPA_IE_LEN << 2);
581 					memcpy(padapter->securitypriv.wps_ie,
582 					    &buf[cnt],
583 					    padapter->securitypriv.wps_ie_len);
584 					padapter->securitypriv.wps_phase =
585 								 true;
586 					netdev_info(padapter->pnetdev, "r8712u: SET WPS_IE, wps_phase==true\n");
587 					cnt += buf[cnt + 1] + 2;
588 					break;
589 				}
590 
591 				cnt += buf[cnt + 1] + 2;
592 			}
593 		}
594 	}
595 exit:
596 	kfree(buf);
597 	return ret;
598 }
599 
r8711_wx_get_name(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)600 static int r8711_wx_get_name(struct net_device *dev,
601 			     struct iw_request_info *info,
602 			     union iwreq_data *wrqu, char *extra)
603 {
604 	struct _adapter *padapter = netdev_priv(dev);
605 	u32 ht_ielen = 0;
606 	char *p;
607 	u8 ht_cap = false;
608 	struct	mlme_priv	*pmlmepriv = &(padapter->mlmepriv);
609 	struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
610 	u8 *prates;
611 
612 	if (check_fwstate(pmlmepriv, _FW_LINKED | WIFI_ADHOC_MASTER_STATE) ==
613 	    true) {
614 		/* parsing HT_CAP_IE */
615 		p = r8712_get_ie(&pcur_bss->IEs[12], _HT_CAPABILITY_IE_,
616 				 &ht_ielen, pcur_bss->IELength - 12);
617 		if (p && ht_ielen > 0)
618 			ht_cap = true;
619 		prates = pcur_bss->rates;
620 		if (r8712_is_cckratesonly_included(prates)) {
621 			if (ht_cap)
622 				snprintf(wrqu->name, IFNAMSIZ,
623 					 "IEEE 802.11bn");
624 			else
625 				snprintf(wrqu->name, IFNAMSIZ,
626 					 "IEEE 802.11b");
627 		} else if (r8712_is_cckrates_included(prates)) {
628 			if (ht_cap)
629 				snprintf(wrqu->name, IFNAMSIZ,
630 					 "IEEE 802.11bgn");
631 			else
632 				snprintf(wrqu->name, IFNAMSIZ,
633 					 "IEEE 802.11bg");
634 		} else {
635 			if (ht_cap)
636 				snprintf(wrqu->name, IFNAMSIZ,
637 					 "IEEE 802.11gn");
638 			else
639 				snprintf(wrqu->name, IFNAMSIZ,
640 					 "IEEE 802.11g");
641 		}
642 	} else {
643 		snprintf(wrqu->name, IFNAMSIZ, "unassociated");
644 	}
645 	return 0;
646 }
647 
648 static const long frequency_list[] = {
649 	2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447, 2452, 2457, 2462,
650 	2467, 2472, 2484, 4915, 4920, 4925, 4935, 4940, 4945, 4960, 4980,
651 	5035, 5040, 5045, 5055, 5060, 5080, 5170, 5180, 5190, 5200, 5210,
652 	5220, 5230, 5240, 5260, 5280, 5300, 5320, 5500, 5520, 5540, 5560,
653 	5580, 5600, 5620, 5640, 5660, 5680, 5700, 5745, 5765, 5785, 5805,
654 	5825
655 };
656 
r8711_wx_set_freq(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)657 static int r8711_wx_set_freq(struct net_device *dev,
658 			     struct iw_request_info *info,
659 			     union iwreq_data *wrqu, char *extra)
660 {
661 	struct _adapter *padapter = netdev_priv(dev);
662 	struct iw_freq *fwrq = &wrqu->freq;
663 	int rc = 0;
664 
665 /* If setting by frequency, convert to a channel */
666 	if ((fwrq->e == 1) &&
667 	  (fwrq->m >= (int) 2.412e8) &&
668 	  (fwrq->m <= (int) 2.487e8)) {
669 		int f = fwrq->m / 100000;
670 		int c = 0;
671 
672 		while ((c < 14) && (f != frequency_list[c]))
673 			c++;
674 		fwrq->e = 0;
675 		fwrq->m = c + 1;
676 	}
677 	/* Setting by channel number */
678 	if ((fwrq->m > 14) || (fwrq->e > 0)) {
679 		rc = -EOPNOTSUPP;
680 	} else {
681 		int channel = fwrq->m;
682 
683 		if ((channel < 1) || (channel > 14)) {
684 			rc = -EINVAL;
685 		} else {
686 			/* Yes ! We can set it !!! */
687 			padapter->registrypriv.channel = channel;
688 		}
689 	}
690 	return rc;
691 }
692 
r8711_wx_get_freq(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)693 static int r8711_wx_get_freq(struct net_device *dev,
694 			     struct iw_request_info *info,
695 			     union iwreq_data *wrqu, char *extra)
696 {
697 	struct _adapter *padapter = netdev_priv(dev);
698 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
699 	struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
700 
701 	if (!check_fwstate(pmlmepriv, _FW_LINKED))
702 		return -ENOLINK;
703 
704 	wrqu->freq.m = ieee80211_wlan_frequencies[
705 		       pcur_bss->Configuration.DSConfig - 1] * 100000;
706 	wrqu->freq.e = 1;
707 	wrqu->freq.i = pcur_bss->Configuration.DSConfig;
708 
709 	return 0;
710 }
711 
r8711_wx_set_mode(struct net_device * dev,struct iw_request_info * a,union iwreq_data * wrqu,char * b)712 static int r8711_wx_set_mode(struct net_device *dev,
713 			     struct iw_request_info *a,
714 			     union iwreq_data *wrqu, char *b)
715 {
716 	struct _adapter *padapter = netdev_priv(dev);
717 	enum NDIS_802_11_NETWORK_INFRASTRUCTURE networkType;
718 
719 	switch (wrqu->mode) {
720 	case IW_MODE_AUTO:
721 		networkType = Ndis802_11AutoUnknown;
722 		break;
723 	case IW_MODE_ADHOC:
724 		networkType = Ndis802_11IBSS;
725 		break;
726 	case IW_MODE_MASTER:
727 		networkType = Ndis802_11APMode;
728 		break;
729 	case IW_MODE_INFRA:
730 		networkType = Ndis802_11Infrastructure;
731 		break;
732 	default:
733 		return -EINVAL;
734 	}
735 	if (Ndis802_11APMode == networkType)
736 		r8712_setopmode_cmd(padapter, networkType);
737 	else
738 		r8712_setopmode_cmd(padapter, Ndis802_11AutoUnknown);
739 
740 	r8712_set_802_11_infrastructure_mode(padapter, networkType);
741 	return 0;
742 }
743 
r8711_wx_get_mode(struct net_device * dev,struct iw_request_info * a,union iwreq_data * wrqu,char * b)744 static int r8711_wx_get_mode(struct net_device *dev, struct iw_request_info *a,
745 			     union iwreq_data *wrqu, char *b)
746 {
747 	struct _adapter *padapter = netdev_priv(dev);
748 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
749 
750 	if (check_fwstate(pmlmepriv, WIFI_STATION_STATE))
751 		wrqu->mode = IW_MODE_INFRA;
752 	else if (check_fwstate(pmlmepriv,
753 		 WIFI_ADHOC_MASTER_STATE | WIFI_ADHOC_STATE))
754 		wrqu->mode = IW_MODE_ADHOC;
755 	else if (check_fwstate(pmlmepriv, WIFI_AP_STATE))
756 		wrqu->mode = IW_MODE_MASTER;
757 	else
758 		wrqu->mode = IW_MODE_AUTO;
759 	return 0;
760 }
761 
r871x_wx_set_pmkid(struct net_device * dev,struct iw_request_info * a,union iwreq_data * wrqu,char * extra)762 static int r871x_wx_set_pmkid(struct net_device *dev,
763 			     struct iw_request_info *a,
764 			     union iwreq_data *wrqu, char *extra)
765 {
766 	struct _adapter *padapter = netdev_priv(dev);
767 	struct security_priv *psecuritypriv = &padapter->securitypriv;
768 	struct iw_pmksa *pPMK = (struct iw_pmksa *) extra;
769 	struct RT_PMKID_LIST *pl = psecuritypriv->PMKIDList;
770 	u8 strZeroMacAddress[ETH_ALEN] = {0x00};
771 	u8 strIssueBssid[ETH_ALEN] = {0x00};
772 	u8 j, blInserted = false;
773 	int intReturn = false;
774 
775 /*
776  *	There are the BSSID information in the bssid.sa_data array.
777  *	If cmd is IW_PMKSA_FLUSH, it means the wpa_supplicant wants to clear
778  *	all the PMKID information. If cmd is IW_PMKSA_ADD, it means the
779  *	wpa_supplicant wants to add a PMKID/BSSID to driver.
780  *	If cmd is IW_PMKSA_REMOVE, it means the wpa_supplicant wants to
781  *	remove a PMKID/BSSID from driver.
782  */
783 	if (pPMK == NULL)
784 		return -EINVAL;
785 	memcpy(strIssueBssid, pPMK->bssid.sa_data, ETH_ALEN);
786 	switch (pPMK->cmd) {
787 	case IW_PMKSA_ADD:
788 		if (!memcmp(strIssueBssid, strZeroMacAddress, ETH_ALEN))
789 			return intReturn;
790 		intReturn = true;
791 		blInserted = false;
792 		/* overwrite PMKID */
793 		for (j = 0; j < NUM_PMKID_CACHE; j++) {
794 			if (!memcmp(pl[j].Bssid, strIssueBssid, ETH_ALEN)) {
795 				/* BSSID is matched, the same AP => rewrite
796 				 * with new PMKID.
797 				 */
798 				netdev_info(dev, "r8712u: %s: BSSID exists in the PMKList.\n",
799 					    __func__);
800 				memcpy(pl[j].PMKID, pPMK->pmkid, IW_PMKID_LEN);
801 				pl[j].bUsed = true;
802 				psecuritypriv->PMKIDIndex = j + 1;
803 				blInserted = true;
804 				break;
805 			}
806 		}
807 		if (!blInserted) {
808 			/* Find a new entry */
809 			netdev_info(dev, "r8712u: %s: Use the new entry index = %d for this PMKID.\n",
810 				    __func__, psecuritypriv->PMKIDIndex);
811 			memcpy(pl[psecuritypriv->PMKIDIndex].Bssid,
812 			       strIssueBssid, ETH_ALEN);
813 			memcpy(pl[psecuritypriv->PMKIDIndex].PMKID,
814 			       pPMK->pmkid, IW_PMKID_LEN);
815 			pl[psecuritypriv->PMKIDIndex].bUsed = true;
816 			psecuritypriv->PMKIDIndex++;
817 			if (psecuritypriv->PMKIDIndex == NUM_PMKID_CACHE)
818 				psecuritypriv->PMKIDIndex = 0;
819 		}
820 		break;
821 	case IW_PMKSA_REMOVE:
822 		intReturn = true;
823 		for (j = 0; j < NUM_PMKID_CACHE; j++) {
824 			if (!memcmp(pl[j].Bssid, strIssueBssid, ETH_ALEN)) {
825 				/* BSSID is matched, the same AP => Remove
826 				 * this PMKID information and reset it.
827 				 */
828 				eth_zero_addr(pl[j].Bssid);
829 				pl[j].bUsed = false;
830 				break;
831 			}
832 		}
833 		break;
834 	case IW_PMKSA_FLUSH:
835 		memset(psecuritypriv->PMKIDList, 0,
836 			sizeof(struct RT_PMKID_LIST) * NUM_PMKID_CACHE);
837 		psecuritypriv->PMKIDIndex = 0;
838 		intReturn = true;
839 		break;
840 	default:
841 		netdev_info(dev, "r8712u: %s: unknown Command\n", __func__);
842 		intReturn = false;
843 		break;
844 	}
845 	return intReturn;
846 }
847 
r8711_wx_get_sens(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)848 static int r8711_wx_get_sens(struct net_device *dev,
849 			     struct iw_request_info *info,
850 			     union iwreq_data *wrqu, char *extra)
851 {
852 	wrqu->sens.value = 0;
853 	wrqu->sens.fixed = 0;	/* no auto select */
854 	wrqu->sens.disabled = 1;
855 	return 0;
856 }
857 
r8711_wx_get_range(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)858 static int r8711_wx_get_range(struct net_device *dev,
859 				struct iw_request_info *info,
860 				union iwreq_data *wrqu, char *extra)
861 {
862 	struct iw_range *range = (struct iw_range *)extra;
863 	u16 val;
864 	int i;
865 
866 	wrqu->data.length = sizeof(*range);
867 	memset(range, 0, sizeof(*range));
868 	/* Let's try to keep this struct in the same order as in
869 	 * linux/include/wireless.h
870 	 */
871 
872 	/* TODO: See what values we can set, and remove the ones we can't
873 	 * set, or fill them with some default data.
874 	 */
875 	/* ~5 Mb/s real (802.11b) */
876 	range->throughput = 5 * 1000 * 1000;
877 	/* TODO: 8711 sensitivity ? */
878 	/* signal level threshold range */
879 	/* percent values between 0 and 100. */
880 	range->max_qual.qual = 100;
881 	range->max_qual.level = 100;
882 	range->max_qual.noise = 100;
883 	range->max_qual.updated = 7; /* Updated all three */
884 	range->avg_qual.qual = 92; /* > 8% missed beacons is 'bad' */
885 	/* TODO: Find real 'good' to 'bad' threshold value for RSSI */
886 	range->avg_qual.level = 0x100 - 78;
887 	range->avg_qual.noise = 0;
888 	range->avg_qual.updated = 7; /* Updated all three */
889 	range->num_bitrates = RATE_COUNT;
890 	for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++)
891 		range->bitrate[i] = rtl8180_rates[i];
892 	range->min_frag = MIN_FRAG_THRESHOLD;
893 	range->max_frag = MAX_FRAG_THRESHOLD;
894 	range->pm_capa = 0;
895 	range->we_version_compiled = WIRELESS_EXT;
896 	range->we_version_source = 16;
897 	range->num_channels = 14;
898 	for (i = 0, val = 0; i < 14; i++) {
899 		/* Include only legal frequencies for some countries */
900 		range->freq[val].i = i + 1;
901 		range->freq[val].m = ieee80211_wlan_frequencies[i] * 100000;
902 		range->freq[val].e = 1;
903 		val++;
904 		if (val == IW_MAX_FREQUENCIES)
905 			break;
906 	}
907 	range->num_frequency = val;
908 	range->enc_capa = IW_ENC_CAPA_WPA |
909 			  IW_ENC_CAPA_WPA2 |
910 			  IW_ENC_CAPA_CIPHER_TKIP |
911 			  IW_ENC_CAPA_CIPHER_CCMP;
912 	return 0;
913 }
914 
915 static int r8711_wx_get_rate(struct net_device *dev,
916 			     struct iw_request_info *info,
917 			     union iwreq_data *wrqu, char *extra);
918 
r871x_wx_set_priv(struct net_device * dev,struct iw_request_info * info,union iwreq_data * awrq,char * extra)919 static int r871x_wx_set_priv(struct net_device *dev,
920 				struct iw_request_info *info,
921 				union iwreq_data *awrq,
922 				char *extra)
923 {
924 	int ret = 0, len = 0;
925 	char *ext;
926 	struct _adapter *padapter = netdev_priv(dev);
927 	struct iw_point *dwrq = (struct iw_point *)awrq;
928 
929 	len = dwrq->length;
930 	ext = memdup_user(dwrq->pointer, len);
931 	if (IS_ERR(ext))
932 		return PTR_ERR(ext);
933 
934 	if (!strcasecmp(ext, "RSSI")) {
935 		/*Return received signal strength indicator in -db for */
936 		/* current AP */
937 		/*<ssid> Rssi xx */
938 		struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
939 		struct wlan_network *pcur_network = &pmlmepriv->cur_network;
940 		/*static u8 xxxx; */
941 		if (check_fwstate(pmlmepriv, _FW_LINKED)) {
942 			sprintf(ext, "%s rssi %d",
943 				pcur_network->network.Ssid.Ssid,
944 				/*(xxxx=xxxx+10) */
945 				((padapter->recvpriv.fw_rssi) >> 1) - 95
946 				/*pcur_network->network.Rssi */
947 				);
948 		} else {
949 			sprintf(ext, "OK");
950 		}
951 	} else if (!strcasecmp(ext, "LINKSPEED")) {
952 		/*Return link speed in MBPS */
953 		/*LinkSpeed xx */
954 		union iwreq_data wrqd;
955 		int ret_inner;
956 		int mbps;
957 
958 		ret_inner = r8711_wx_get_rate(dev, info, &wrqd, extra);
959 		if (ret_inner != 0)
960 			mbps = 0;
961 		else
962 			mbps = wrqd.bitrate.value / 1000000;
963 		sprintf(ext, "LINKSPEED %d", mbps);
964 	} else if (!strcasecmp(ext, "MACADDR")) {
965 		/*Return mac address of the station */
966 		/* Macaddr = xx:xx:xx:xx:xx:xx */
967 		sprintf(ext, "MACADDR = %pM", dev->dev_addr);
968 	} else if (!strcasecmp(ext, "SCAN-ACTIVE")) {
969 		/*Set scan type to active */
970 		/*OK if successful */
971 		struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
972 
973 		pmlmepriv->passive_mode = 1;
974 		sprintf(ext, "OK");
975 	} else if (!strcasecmp(ext, "SCAN-PASSIVE")) {
976 		/*Set scan type to passive */
977 		/*OK if successful */
978 		struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
979 
980 		pmlmepriv->passive_mode = 0;
981 		sprintf(ext, "OK");
982 	} else if (!strncmp(ext, "DCE-E", 5)) {
983 		/*Set scan type to passive */
984 		/*OK if successful */
985 		r8712_disconnectCtrlEx_cmd(padapter
986 			, 1 /*u32 enableDrvCtrl */
987 			, 5 /*u32 tryPktCnt */
988 			, 100 /*u32 tryPktInterval */
989 			, 5000 /*u32 firstStageTO */
990 		);
991 		sprintf(ext, "OK");
992 	} else if (!strncmp(ext, "DCE-D", 5)) {
993 		/*Set scan type to passive */
994 		/*OK if successfu */
995 		r8712_disconnectCtrlEx_cmd(padapter
996 			, 0 /*u32 enableDrvCtrl */
997 			, 5 /*u32 tryPktCnt */
998 			, 100 /*u32 tryPktInterval */
999 			, 5000 /*u32 firstStageTO */
1000 		);
1001 		sprintf(ext, "OK");
1002 	} else {
1003 		netdev_info(dev, "r8712u: %s: unknown Command %s.\n",
1004 			    __func__, ext);
1005 		goto FREE_EXT;
1006 	}
1007 	if (copy_to_user(dwrq->pointer, ext,
1008 				min(dwrq->length, (__u16)(strlen(ext) + 1))))
1009 		ret = -EFAULT;
1010 
1011 FREE_EXT:
1012 	kfree(ext);
1013 	return ret;
1014 }
1015 
1016 /* set bssid flow
1017  * s1. set_802_11_infrastructure_mode()
1018  * s2. set_802_11_authentication_mode()
1019  * s3. set_802_11_encryption_mode()
1020  * s4. set_802_11_bssid()
1021  *
1022  * This function intends to handle the Set AP command, which specifies the
1023  * MAC# of a preferred Access Point.
1024  * Currently, the request comes via Wireless Extensions' SIOCSIWAP ioctl.
1025  *
1026  * For this operation to succeed, there is no need for the interface to be up.
1027  *
1028  */
r8711_wx_set_wap(struct net_device * dev,struct iw_request_info * info,union iwreq_data * awrq,char * extra)1029 static int r8711_wx_set_wap(struct net_device *dev,
1030 			 struct iw_request_info *info,
1031 			 union iwreq_data *awrq,
1032 			 char *extra)
1033 {
1034 	int ret = -EINPROGRESS;
1035 	struct _adapter *padapter = netdev_priv(dev);
1036 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1037 	struct  __queue *queue = &pmlmepriv->scanned_queue;
1038 	struct sockaddr *temp = (struct sockaddr *)awrq;
1039 	unsigned long irqL;
1040 	struct list_head *phead;
1041 	u8 *dst_bssid;
1042 	struct wlan_network *pnetwork = NULL;
1043 	enum NDIS_802_11_AUTHENTICATION_MODE	authmode;
1044 
1045 	if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY))
1046 		return -EBUSY;
1047 	if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING))
1048 		return ret;
1049 	if (temp->sa_family != ARPHRD_ETHER)
1050 		return -EINVAL;
1051 	authmode = padapter->securitypriv.ndisauthtype;
1052 	spin_lock_irqsave(&queue->lock, irqL);
1053 	phead = &queue->queue;
1054 	pmlmepriv->pscanned = phead->next;
1055 	while (1) {
1056 		if (end_of_queue_search(phead, pmlmepriv->pscanned))
1057 			break;
1058 		pnetwork = container_of(pmlmepriv->pscanned,
1059 					struct wlan_network, list);
1060 		pmlmepriv->pscanned = pmlmepriv->pscanned->next;
1061 		dst_bssid = pnetwork->network.MacAddress;
1062 		if (!memcmp(dst_bssid, temp->sa_data, ETH_ALEN)) {
1063 			r8712_set_802_11_infrastructure_mode(padapter,
1064 			    pnetwork->network.InfrastructureMode);
1065 			break;
1066 		}
1067 	}
1068 	spin_unlock_irqrestore(&queue->lock, irqL);
1069 	if (!ret) {
1070 		if (!r8712_set_802_11_authentication_mode(padapter, authmode)) {
1071 			ret = -ENOMEM;
1072 		} else {
1073 			if (!r8712_set_802_11_bssid(padapter, temp->sa_data))
1074 				ret = -1;
1075 		}
1076 	}
1077 	return ret;
1078 }
1079 
r8711_wx_get_wap(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1080 static int r8711_wx_get_wap(struct net_device *dev,
1081 				struct iw_request_info *info,
1082 				union iwreq_data *wrqu, char *extra)
1083 {
1084 	struct _adapter *padapter = netdev_priv(dev);
1085 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1086 	struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
1087 
1088 	wrqu->ap_addr.sa_family = ARPHRD_ETHER;
1089 	if (check_fwstate(pmlmepriv, _FW_LINKED | WIFI_ADHOC_MASTER_STATE |
1090 				     WIFI_AP_STATE))
1091 		ether_addr_copy(wrqu->ap_addr.sa_data, pcur_bss->MacAddress);
1092 	else
1093 		eth_zero_addr(wrqu->ap_addr.sa_data);
1094 	return 0;
1095 }
1096 
r871x_wx_set_mlme(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1097 static int r871x_wx_set_mlme(struct net_device *dev,
1098 			     struct iw_request_info *info,
1099 			     union iwreq_data *wrqu, char *extra)
1100 {
1101 	int ret = 0;
1102 	struct _adapter *padapter = netdev_priv(dev);
1103 	struct iw_mlme *mlme = (struct iw_mlme *) extra;
1104 
1105 	if (mlme == NULL)
1106 		return -1;
1107 	switch (mlme->cmd) {
1108 	case IW_MLME_DEAUTH:
1109 		if (!r8712_set_802_11_disassociate(padapter))
1110 			ret = -1;
1111 		break;
1112 	case IW_MLME_DISASSOC:
1113 		if (!r8712_set_802_11_disassociate(padapter))
1114 			ret = -1;
1115 		break;
1116 	default:
1117 		return -EOPNOTSUPP;
1118 	}
1119 	return ret;
1120 }
1121 
1122 /**
1123  *
1124  * This function intends to handle the Set Scan command.
1125  * Currently, the request comes via Wireless Extensions' SIOCSIWSCAN ioctl.
1126  *
1127  * For this operation to succeed, the interface is brought Up beforehand.
1128  *
1129  */
r8711_wx_set_scan(struct net_device * dev,struct iw_request_info * a,union iwreq_data * wrqu,char * extra)1130 static int r8711_wx_set_scan(struct net_device *dev,
1131 			struct iw_request_info *a,
1132 			union iwreq_data *wrqu, char *extra)
1133 {
1134 	struct _adapter *padapter = netdev_priv(dev);
1135 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1136 	u8 status = true;
1137 
1138 	if (padapter->bDriverStopped) {
1139 		netdev_info(dev, "In %s: bDriverStopped=%d\n",
1140 			    __func__, padapter->bDriverStopped);
1141 		return -1;
1142 	}
1143 	if (!padapter->bup)
1144 		return -ENETDOWN;
1145 	if (!padapter->hw_init_completed)
1146 		return -1;
1147 	if ((check_fwstate(pmlmepriv, _FW_UNDER_SURVEY | _FW_UNDER_LINKING)) ||
1148 	    (pmlmepriv->sitesurveyctrl.traffic_busy))
1149 		return 0;
1150 	if (wrqu->data.length == sizeof(struct iw_scan_req)) {
1151 		struct iw_scan_req *req = (struct iw_scan_req *)extra;
1152 
1153 		if (wrqu->data.flags & IW_SCAN_THIS_ESSID) {
1154 			struct ndis_802_11_ssid ssid;
1155 			unsigned long irqL;
1156 			u32 len = min_t(u8, req->essid_len, IW_ESSID_MAX_SIZE);
1157 
1158 			memset((unsigned char *)&ssid, 0,
1159 				 sizeof(struct ndis_802_11_ssid));
1160 			memcpy(ssid.Ssid, req->essid, len);
1161 			ssid.SsidLength = len;
1162 			spin_lock_irqsave(&pmlmepriv->lock, irqL);
1163 			if ((check_fwstate(pmlmepriv, _FW_UNDER_SURVEY |
1164 			     _FW_UNDER_LINKING)) ||
1165 			    (pmlmepriv->sitesurveyctrl.traffic_busy)) {
1166 				if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING))
1167 					status = false;
1168 			} else {
1169 				status = r8712_sitesurvey_cmd(padapter, &ssid);
1170 			}
1171 			spin_unlock_irqrestore(&pmlmepriv->lock, irqL);
1172 		}
1173 	} else {
1174 		status = r8712_set_802_11_bssid_list_scan(padapter);
1175 	}
1176 	if (!status)
1177 		return -1;
1178 	return 0;
1179 }
1180 
r8711_wx_get_scan(struct net_device * dev,struct iw_request_info * a,union iwreq_data * wrqu,char * extra)1181 static int r8711_wx_get_scan(struct net_device *dev,
1182 				struct iw_request_info *a,
1183 				union iwreq_data *wrqu, char *extra)
1184 {
1185 	struct _adapter *padapter = netdev_priv(dev);
1186 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1187 	struct  __queue *queue = &pmlmepriv->scanned_queue;
1188 	struct wlan_network *pnetwork = NULL;
1189 	unsigned long irqL;
1190 	struct list_head *plist, *phead;
1191 	char *ev = extra;
1192 	char *stop = ev + wrqu->data.length;
1193 	u32 ret = 0, cnt = 0;
1194 
1195 	if (padapter->bDriverStopped)
1196 		return -EINVAL;
1197 	while (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY |
1198 			     _FW_UNDER_LINKING)) {
1199 		msleep(30);
1200 		cnt++;
1201 		if (cnt > 100)
1202 			break;
1203 	}
1204 	spin_lock_irqsave(&queue->lock, irqL);
1205 	phead = &queue->queue;
1206 	plist = phead->next;
1207 	while (1) {
1208 		if (end_of_queue_search(phead, plist))
1209 			break;
1210 		if ((stop - ev) < SCAN_ITEM_SIZE) {
1211 			ret = -E2BIG;
1212 			break;
1213 		}
1214 		pnetwork = container_of(plist, struct wlan_network, list);
1215 		ev = translate_scan(padapter, a, pnetwork, ev, stop);
1216 		plist = plist->next;
1217 	}
1218 	spin_unlock_irqrestore(&queue->lock, irqL);
1219 	wrqu->data.length = ev - extra;
1220 	wrqu->data.flags = 0;
1221 	return ret;
1222 }
1223 
1224 /* set ssid flow
1225  * s1. set_802_11_infrastructure_mode()
1226  * s2. set_802_11_authenticaion_mode()
1227  * s3. set_802_11_encryption_mode()
1228  * s4. set_802_11_ssid()
1229  *
1230  * This function intends to handle the Set ESSID command.
1231  * Currently, the request comes via the Wireless Extensions' SIOCSIWESSID ioctl.
1232  *
1233  * For this operation to succeed, there is no need for the interface to be Up.
1234  *
1235  */
r8711_wx_set_essid(struct net_device * dev,struct iw_request_info * a,union iwreq_data * wrqu,char * extra)1236 static int r8711_wx_set_essid(struct net_device *dev,
1237 				struct iw_request_info *a,
1238 				union iwreq_data *wrqu, char *extra)
1239 {
1240 	struct _adapter *padapter = netdev_priv(dev);
1241 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1242 	struct  __queue *queue = &pmlmepriv->scanned_queue;
1243 	struct wlan_network *pnetwork = NULL;
1244 	enum NDIS_802_11_AUTHENTICATION_MODE	authmode;
1245 	struct ndis_802_11_ssid ndis_ssid;
1246 	u8 *dst_ssid, *src_ssid;
1247 	struct list_head *phead;
1248 	u32 len;
1249 
1250 	if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY))
1251 		return -EBUSY;
1252 	if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING))
1253 		return 0;
1254 	if (wrqu->essid.length > IW_ESSID_MAX_SIZE)
1255 		return -E2BIG;
1256 	authmode = padapter->securitypriv.ndisauthtype;
1257 	if (wrqu->essid.flags && wrqu->essid.length) {
1258 		len = (wrqu->essid.length < IW_ESSID_MAX_SIZE) ?
1259 		       wrqu->essid.length : IW_ESSID_MAX_SIZE;
1260 		memset(&ndis_ssid, 0, sizeof(struct ndis_802_11_ssid));
1261 		ndis_ssid.SsidLength = len;
1262 		memcpy(ndis_ssid.Ssid, extra, len);
1263 		src_ssid = ndis_ssid.Ssid;
1264 		phead = &queue->queue;
1265 		pmlmepriv->pscanned = phead->next;
1266 		while (1) {
1267 			if (end_of_queue_search(phead, pmlmepriv->pscanned))
1268 				break;
1269 			pnetwork = container_of(pmlmepriv->pscanned,
1270 						struct wlan_network, list);
1271 			pmlmepriv->pscanned = pmlmepriv->pscanned->next;
1272 			dst_ssid = pnetwork->network.Ssid.Ssid;
1273 			if ((!memcmp(dst_ssid, src_ssid, ndis_ssid.SsidLength))
1274 			    && (pnetwork->network.Ssid.SsidLength ==
1275 			     ndis_ssid.SsidLength)) {
1276 				if (check_fwstate(pmlmepriv,
1277 							WIFI_ADHOC_STATE)) {
1278 					if (pnetwork->network.
1279 						InfrastructureMode
1280 						!=
1281 						padapter->mlmepriv.
1282 						cur_network.network.
1283 						InfrastructureMode)
1284 						continue;
1285 				}
1286 
1287 				r8712_set_802_11_infrastructure_mode(
1288 				     padapter,
1289 				     pnetwork->network.InfrastructureMode);
1290 				break;
1291 			}
1292 		}
1293 		r8712_set_802_11_authentication_mode(padapter, authmode);
1294 		r8712_set_802_11_ssid(padapter, &ndis_ssid);
1295 	}
1296 	return -EINPROGRESS;
1297 }
1298 
r8711_wx_get_essid(struct net_device * dev,struct iw_request_info * a,union iwreq_data * wrqu,char * extra)1299 static int r8711_wx_get_essid(struct net_device *dev,
1300 				struct iw_request_info *a,
1301 				union iwreq_data *wrqu, char *extra)
1302 {
1303 	struct _adapter *padapter = netdev_priv(dev);
1304 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1305 	struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
1306 	u32 len, ret = 0;
1307 
1308 	if (check_fwstate(pmlmepriv, _FW_LINKED | WIFI_ADHOC_MASTER_STATE)) {
1309 		len = pcur_bss->Ssid.SsidLength;
1310 		wrqu->essid.length = len;
1311 		memcpy(extra, pcur_bss->Ssid.Ssid, len);
1312 		wrqu->essid.flags = 1;
1313 	} else {
1314 		ret = -ENOLINK;
1315 	}
1316 	return ret;
1317 }
1318 
r8711_wx_set_rate(struct net_device * dev,struct iw_request_info * a,union iwreq_data * wrqu,char * extra)1319 static int r8711_wx_set_rate(struct net_device *dev,
1320 				struct iw_request_info *a,
1321 				union iwreq_data *wrqu, char *extra)
1322 {
1323 	struct _adapter *padapter = netdev_priv(dev);
1324 	u32 target_rate = wrqu->bitrate.value;
1325 	u32 fixed = wrqu->bitrate.fixed;
1326 	u32 ratevalue = 0;
1327 	u8 datarates[NumRates];
1328 	u8 mpdatarate[NumRates] = {11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0xff};
1329 	int i, ret = 0;
1330 
1331 	if (target_rate == -1) {
1332 		ratevalue = 11;
1333 		goto set_rate;
1334 	}
1335 	target_rate = target_rate / 100000;
1336 	switch (target_rate) {
1337 	case 10:
1338 		ratevalue = 0;
1339 		break;
1340 	case 20:
1341 		ratevalue = 1;
1342 		break;
1343 	case 55:
1344 		ratevalue = 2;
1345 		break;
1346 	case 60:
1347 		ratevalue = 3;
1348 		break;
1349 	case 90:
1350 		ratevalue = 4;
1351 		break;
1352 	case 110:
1353 		ratevalue = 5;
1354 		break;
1355 	case 120:
1356 		ratevalue = 6;
1357 		break;
1358 	case 180:
1359 		ratevalue = 7;
1360 		break;
1361 	case 240:
1362 		ratevalue = 8;
1363 		break;
1364 	case 360:
1365 		ratevalue = 9;
1366 		break;
1367 	case 480:
1368 		ratevalue = 10;
1369 		break;
1370 	case 540:
1371 		ratevalue = 11;
1372 		break;
1373 	default:
1374 		ratevalue = 11;
1375 		break;
1376 	}
1377 set_rate:
1378 	for (i = 0; i < NumRates; i++) {
1379 		if (ratevalue == mpdatarate[i]) {
1380 			datarates[i] = mpdatarate[i];
1381 			if (fixed == 0)
1382 				break;
1383 		} else {
1384 			datarates[i] = 0xff;
1385 		}
1386 	}
1387 	if (r8712_setdatarate_cmd(padapter, datarates) != _SUCCESS)
1388 		ret = -ENOMEM;
1389 	return ret;
1390 }
1391 
r8711_wx_get_rate(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1392 static int r8711_wx_get_rate(struct net_device *dev,
1393 			     struct iw_request_info *info,
1394 			     union iwreq_data *wrqu, char *extra)
1395 {
1396 	struct _adapter *padapter = netdev_priv(dev);
1397 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1398 	struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
1399 	struct ieee80211_ht_cap *pht_capie;
1400 	unsigned char rf_type = padapter->registrypriv.rf_config;
1401 	int i;
1402 	u8 *p;
1403 	u16 rate, max_rate = 0, ht_cap = false;
1404 	u32 ht_ielen = 0;
1405 	u8 bw_40MHz = 0, short_GI = 0;
1406 	u16 mcs_rate = 0;
1407 
1408 	i = 0;
1409 	if (!check_fwstate(pmlmepriv, _FW_LINKED | WIFI_ADHOC_MASTER_STATE))
1410 		return -ENOLINK;
1411 	p = r8712_get_ie(&pcur_bss->IEs[12], _HT_CAPABILITY_IE_, &ht_ielen,
1412 			 pcur_bss->IELength - 12);
1413 	if (p && ht_ielen > 0) {
1414 		ht_cap = true;
1415 		pht_capie = (struct ieee80211_ht_cap *)(p + 2);
1416 		memcpy(&mcs_rate, pht_capie->supp_mcs_set, 2);
1417 		bw_40MHz = (le16_to_cpu(pht_capie->cap_info) &
1418 			    IEEE80211_HT_CAP_SUP_WIDTH) ? 1 : 0;
1419 		short_GI = (le16_to_cpu(pht_capie->cap_info) &
1420 			    (IEEE80211_HT_CAP_SGI_20 |
1421 			    IEEE80211_HT_CAP_SGI_40)) ? 1 : 0;
1422 	}
1423 	while ((pcur_bss->rates[i] != 0) &&
1424 	       (pcur_bss->rates[i] != 0xFF)) {
1425 		rate = pcur_bss->rates[i] & 0x7F;
1426 		if (rate > max_rate)
1427 			max_rate = rate;
1428 		wrqu->bitrate.fixed = 0;	/* no auto select */
1429 		wrqu->bitrate.value = rate * 500000;
1430 		i++;
1431 	}
1432 	if (ht_cap) {
1433 		if (mcs_rate & 0x8000 /* MCS15 */
1434 		    &&
1435 		    rf_type == RTL8712_RF_2T2R)
1436 			max_rate = (bw_40MHz) ? ((short_GI) ? 300 : 270) :
1437 			((short_GI) ? 144 : 130);
1438 		else /* default MCS7 */
1439 			max_rate = (bw_40MHz) ? ((short_GI) ? 150 : 135) :
1440 			((short_GI) ? 72 : 65);
1441 		max_rate *= 2; /* Mbps/2 */
1442 	}
1443 	wrqu->bitrate.value = max_rate * 500000;
1444 	return 0;
1445 }
1446 
r8711_wx_get_rts(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1447 static int r8711_wx_get_rts(struct net_device *dev,
1448 				struct iw_request_info *info,
1449 				union iwreq_data *wrqu, char *extra)
1450 {
1451 	struct _adapter *padapter = netdev_priv(dev);
1452 
1453 	wrqu->rts.value = padapter->registrypriv.rts_thresh;
1454 	wrqu->rts.fixed = 0;	/* no auto select */
1455 	return 0;
1456 }
1457 
r8711_wx_set_frag(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1458 static int r8711_wx_set_frag(struct net_device *dev,
1459 				struct iw_request_info *info,
1460 				union iwreq_data *wrqu, char *extra)
1461 {
1462 	struct _adapter *padapter = netdev_priv(dev);
1463 
1464 	if (wrqu->frag.disabled) {
1465 		padapter->xmitpriv.frag_len = MAX_FRAG_THRESHOLD;
1466 	} else {
1467 		if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
1468 		    wrqu->frag.value > MAX_FRAG_THRESHOLD)
1469 			return -EINVAL;
1470 		padapter->xmitpriv.frag_len = wrqu->frag.value & ~0x1;
1471 	}
1472 	return 0;
1473 }
1474 
r8711_wx_get_frag(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1475 static int r8711_wx_get_frag(struct net_device *dev,
1476 				struct iw_request_info *info,
1477 				union iwreq_data *wrqu, char *extra)
1478 {
1479 	struct _adapter *padapter = netdev_priv(dev);
1480 
1481 	wrqu->frag.value = padapter->xmitpriv.frag_len;
1482 	wrqu->frag.fixed = 0;	/* no auto select */
1483 	return 0;
1484 }
1485 
r8711_wx_get_retry(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1486 static int r8711_wx_get_retry(struct net_device *dev,
1487 				struct iw_request_info *info,
1488 				union iwreq_data *wrqu, char *extra)
1489 {
1490 	wrqu->retry.value = 7;
1491 	wrqu->retry.fixed = 0;	/* no auto select */
1492 	wrqu->retry.disabled = 1;
1493 	return 0;
1494 }
1495 
r8711_wx_set_enc(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * keybuf)1496 static int r8711_wx_set_enc(struct net_device *dev,
1497 				struct iw_request_info *info,
1498 				union iwreq_data *wrqu, char *keybuf)
1499 {
1500 	u32 key;
1501 	u32 keyindex_provided;
1502 	struct NDIS_802_11_WEP	 wep;
1503 	enum NDIS_802_11_AUTHENTICATION_MODE authmode;
1504 	struct iw_point *erq = &(wrqu->encoding);
1505 	struct _adapter *padapter = netdev_priv(dev);
1506 
1507 	key = erq->flags & IW_ENCODE_INDEX;
1508 	memset(&wep, 0, sizeof(struct NDIS_802_11_WEP));
1509 	if (erq->flags & IW_ENCODE_DISABLED) {
1510 		netdev_info(dev, "r8712u: %s: EncryptionDisabled\n", __func__);
1511 		padapter->securitypriv.ndisencryptstatus =
1512 				 Ndis802_11EncryptionDisabled;
1513 		padapter->securitypriv.PrivacyAlgrthm = _NO_PRIVACY_;
1514 		padapter->securitypriv.XGrpPrivacy = _NO_PRIVACY_;
1515 		padapter->securitypriv.AuthAlgrthm = 0; /* open system */
1516 		authmode = Ndis802_11AuthModeOpen;
1517 		padapter->securitypriv.ndisauthtype = authmode;
1518 		return 0;
1519 	}
1520 	if (key) {
1521 		if (key > WEP_KEYS)
1522 			return -EINVAL;
1523 		key--;
1524 		keyindex_provided = 1;
1525 	} else {
1526 		keyindex_provided = 0;
1527 		key = padapter->securitypriv.PrivacyKeyIndex;
1528 	}
1529 	/* set authentication mode */
1530 	if (erq->flags & IW_ENCODE_OPEN) {
1531 		netdev_info(dev, "r8712u: %s: IW_ENCODE_OPEN\n", __func__);
1532 		padapter->securitypriv.ndisencryptstatus =
1533 				 Ndis802_11Encryption1Enabled;
1534 		padapter->securitypriv.AuthAlgrthm = 0; /* open system */
1535 		padapter->securitypriv.PrivacyAlgrthm = _NO_PRIVACY_;
1536 		padapter->securitypriv.XGrpPrivacy = _NO_PRIVACY_;
1537 		authmode = Ndis802_11AuthModeOpen;
1538 		padapter->securitypriv.ndisauthtype = authmode;
1539 	} else if (erq->flags & IW_ENCODE_RESTRICTED) {
1540 		netdev_info(dev,
1541 				"r8712u: %s: IW_ENCODE_RESTRICTED\n", __func__);
1542 		padapter->securitypriv.ndisencryptstatus =
1543 				 Ndis802_11Encryption1Enabled;
1544 		padapter->securitypriv.AuthAlgrthm = 1; /* shared system */
1545 		padapter->securitypriv.PrivacyAlgrthm = _WEP40_;
1546 		padapter->securitypriv.XGrpPrivacy = _WEP40_;
1547 		authmode = Ndis802_11AuthModeShared;
1548 		padapter->securitypriv.ndisauthtype = authmode;
1549 	} else {
1550 		padapter->securitypriv.ndisencryptstatus =
1551 				 Ndis802_11Encryption1Enabled;
1552 		padapter->securitypriv.AuthAlgrthm = 0; /* open system */
1553 		padapter->securitypriv.PrivacyAlgrthm = _NO_PRIVACY_;
1554 		padapter->securitypriv.XGrpPrivacy = _NO_PRIVACY_;
1555 		authmode = Ndis802_11AuthModeOpen;
1556 		padapter->securitypriv.ndisauthtype = authmode;
1557 	}
1558 	wep.KeyIndex = key;
1559 	if (erq->length > 0) {
1560 		wep.KeyLength = erq->length <= 5 ? 5 : 13;
1561 		wep.Length = wep.KeyLength +
1562 			     FIELD_OFFSET(struct NDIS_802_11_WEP, KeyMaterial);
1563 	} else {
1564 		wep.KeyLength = 0;
1565 		if (keyindex_provided == 1) { /* set key_id only, no given
1566 					       * KeyMaterial(erq->length==0).
1567 					       */
1568 			padapter->securitypriv.PrivacyKeyIndex = key;
1569 			switch (padapter->securitypriv.DefKeylen[key]) {
1570 			case 5:
1571 				padapter->securitypriv.PrivacyAlgrthm =
1572 						 _WEP40_;
1573 				break;
1574 			case 13:
1575 				padapter->securitypriv.PrivacyAlgrthm =
1576 						 _WEP104_;
1577 				break;
1578 			default:
1579 				padapter->securitypriv.PrivacyAlgrthm =
1580 						 _NO_PRIVACY_;
1581 				break;
1582 			}
1583 			return 0;
1584 		}
1585 	}
1586 	wep.KeyIndex |= 0x80000000;	/* transmit key */
1587 	memcpy(wep.KeyMaterial, keybuf, wep.KeyLength);
1588 	if (r8712_set_802_11_add_wep(padapter, &wep) == _FAIL)
1589 		return -EOPNOTSUPP;
1590 	return 0;
1591 }
1592 
r8711_wx_get_enc(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * keybuf)1593 static int r8711_wx_get_enc(struct net_device *dev,
1594 				struct iw_request_info *info,
1595 				union iwreq_data *wrqu, char *keybuf)
1596 {
1597 	uint key, ret = 0;
1598 	struct _adapter *padapter = netdev_priv(dev);
1599 	struct iw_point *erq = &(wrqu->encoding);
1600 	struct	mlme_priv	*pmlmepriv = &(padapter->mlmepriv);
1601 	union Keytype *dk = padapter->securitypriv.DefKey;
1602 
1603 	if (!check_fwstate(pmlmepriv, _FW_LINKED)) {
1604 		if (!check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) {
1605 			erq->length = 0;
1606 			erq->flags |= IW_ENCODE_DISABLED;
1607 			return 0;
1608 		}
1609 	}
1610 	key = erq->flags & IW_ENCODE_INDEX;
1611 	if (key) {
1612 		if (key > WEP_KEYS)
1613 			return -EINVAL;
1614 		key--;
1615 	} else {
1616 		key = padapter->securitypriv.PrivacyKeyIndex;
1617 	}
1618 	erq->flags = key + 1;
1619 	switch (padapter->securitypriv.ndisencryptstatus) {
1620 	case Ndis802_11EncryptionNotSupported:
1621 	case Ndis802_11EncryptionDisabled:
1622 		erq->length = 0;
1623 		erq->flags |= IW_ENCODE_DISABLED;
1624 		break;
1625 	case Ndis802_11Encryption1Enabled:
1626 		erq->length = padapter->securitypriv.DefKeylen[key];
1627 		if (erq->length) {
1628 			memcpy(keybuf, dk[key].skey,
1629 			       padapter->securitypriv.DefKeylen[key]);
1630 			erq->flags |= IW_ENCODE_ENABLED;
1631 			if (padapter->securitypriv.ndisauthtype ==
1632 			    Ndis802_11AuthModeOpen)
1633 				erq->flags |= IW_ENCODE_OPEN;
1634 			else if (padapter->securitypriv.ndisauthtype ==
1635 				 Ndis802_11AuthModeShared)
1636 				erq->flags |= IW_ENCODE_RESTRICTED;
1637 		} else {
1638 			erq->length = 0;
1639 			erq->flags |= IW_ENCODE_DISABLED;
1640 		}
1641 		break;
1642 	case Ndis802_11Encryption2Enabled:
1643 	case Ndis802_11Encryption3Enabled:
1644 		erq->length = 16;
1645 		erq->flags |= (IW_ENCODE_ENABLED | IW_ENCODE_OPEN |
1646 			       IW_ENCODE_NOKEY);
1647 		break;
1648 	default:
1649 		erq->length = 0;
1650 		erq->flags |= IW_ENCODE_DISABLED;
1651 		break;
1652 	}
1653 	return ret;
1654 }
1655 
r8711_wx_get_power(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1656 static int r8711_wx_get_power(struct net_device *dev,
1657 				struct iw_request_info *info,
1658 				union iwreq_data *wrqu, char *extra)
1659 {
1660 	wrqu->power.value = 0;
1661 	wrqu->power.fixed = 0;	/* no auto select */
1662 	wrqu->power.disabled = 1;
1663 	return 0;
1664 }
1665 
r871x_wx_set_gen_ie(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1666 static int r871x_wx_set_gen_ie(struct net_device *dev,
1667 				struct iw_request_info *info,
1668 				union iwreq_data *wrqu, char *extra)
1669 {
1670 	struct _adapter *padapter = netdev_priv(dev);
1671 
1672 	return r871x_set_wpa_ie(padapter, extra, wrqu->data.length);
1673 }
1674 
r871x_wx_set_auth(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1675 static int r871x_wx_set_auth(struct net_device *dev,
1676 				struct iw_request_info *info,
1677 				union iwreq_data *wrqu, char *extra)
1678 {
1679 	struct _adapter *padapter = netdev_priv(dev);
1680 	struct iw_param *param = (struct iw_param *)&(wrqu->param);
1681 	int paramid;
1682 	int paramval;
1683 	int ret = 0;
1684 
1685 	paramid = param->flags & IW_AUTH_INDEX;
1686 	paramval = param->value;
1687 	switch (paramid) {
1688 	case IW_AUTH_WPA_VERSION:
1689 		break;
1690 	case IW_AUTH_CIPHER_PAIRWISE:
1691 		break;
1692 	case IW_AUTH_CIPHER_GROUP:
1693 		break;
1694 	case IW_AUTH_KEY_MGMT:
1695 		/*
1696 		 *  ??? does not use these parameters
1697 		 */
1698 		break;
1699 	case IW_AUTH_TKIP_COUNTERMEASURES:
1700 		if (paramval) {
1701 			/* wpa_supplicant is enabling tkip countermeasure. */
1702 			padapter->securitypriv.btkip_countermeasure = true;
1703 		} else {
1704 			/* wpa_supplicant is disabling tkip countermeasure. */
1705 			padapter->securitypriv.btkip_countermeasure = false;
1706 		}
1707 		break;
1708 	case IW_AUTH_DROP_UNENCRYPTED:
1709 		/* HACK:
1710 		 *
1711 		 * wpa_supplicant calls set_wpa_enabled when the driver
1712 		 * is loaded and unloaded, regardless of if WPA is being
1713 		 * used.  No other calls are made which can be used to
1714 		 * determine if encryption will be used or not prior to
1715 		 * association being expected.  If encryption is not being
1716 		 * used, drop_unencrypted is set to false, else true -- we
1717 		 * can use this to determine if the CAP_PRIVACY_ON bit should
1718 		 * be set.
1719 		 */
1720 		if (padapter->securitypriv.ndisencryptstatus ==
1721 		    Ndis802_11Encryption1Enabled) {
1722 			/* it means init value, or using wep,
1723 			 * ndisencryptstatus =
1724 			 *	Ndis802_11Encryption1Enabled,
1725 			 * then it needn't reset it;
1726 			 */
1727 			break;
1728 		}
1729 
1730 		if (paramval) {
1731 			padapter->securitypriv.ndisencryptstatus =
1732 				   Ndis802_11EncryptionDisabled;
1733 			padapter->securitypriv.PrivacyAlgrthm =
1734 				  _NO_PRIVACY_;
1735 			padapter->securitypriv.XGrpPrivacy =
1736 				  _NO_PRIVACY_;
1737 			padapter->securitypriv.AuthAlgrthm = 0;
1738 			padapter->securitypriv.ndisauthtype =
1739 				  Ndis802_11AuthModeOpen;
1740 		}
1741 		break;
1742 	case IW_AUTH_80211_AUTH_ALG:
1743 		ret = wpa_set_auth_algs(dev, (u32)paramval);
1744 		break;
1745 	case IW_AUTH_WPA_ENABLED:
1746 		break;
1747 	case IW_AUTH_RX_UNENCRYPTED_EAPOL:
1748 		break;
1749 	case IW_AUTH_PRIVACY_INVOKED:
1750 		break;
1751 	default:
1752 		return -EOPNOTSUPP;
1753 	}
1754 
1755 	return ret;
1756 }
1757 
r871x_wx_set_enc_ext(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1758 static int r871x_wx_set_enc_ext(struct net_device *dev,
1759 			     struct iw_request_info *info,
1760 			     union iwreq_data *wrqu, char *extra)
1761 {
1762 	struct iw_point *pencoding = &wrqu->encoding;
1763 	struct iw_encode_ext *pext = (struct iw_encode_ext *)extra;
1764 	struct ieee_param *param = NULL;
1765 	char *alg_name;
1766 	u32 param_len;
1767 	int ret = 0;
1768 
1769 	switch (pext->alg) {
1770 	case IW_ENCODE_ALG_NONE:
1771 		alg_name = "none";
1772 		break;
1773 	case IW_ENCODE_ALG_WEP:
1774 		alg_name = "WEP";
1775 		break;
1776 	case IW_ENCODE_ALG_TKIP:
1777 		alg_name = "TKIP";
1778 		break;
1779 	case IW_ENCODE_ALG_CCMP:
1780 		alg_name = "CCMP";
1781 		break;
1782 	default:
1783 		return -EINVAL;
1784 	}
1785 
1786 	param_len = sizeof(struct ieee_param) + pext->key_len;
1787 	param = kzalloc(param_len, GFP_ATOMIC);
1788 	if (!param)
1789 		return -ENOMEM;
1790 	param->cmd = IEEE_CMD_SET_ENCRYPTION;
1791 	eth_broadcast_addr(param->sta_addr);
1792 	strncpy((char *)param->u.crypt.alg, alg_name, IEEE_CRYPT_ALG_NAME_LEN);
1793 	if (pext->ext_flags & IW_ENCODE_EXT_GROUP_KEY)
1794 		param->u.crypt.set_tx = 0;
1795 	if (pext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
1796 		param->u.crypt.set_tx = 1;
1797 	param->u.crypt.idx = (pencoding->flags & 0x00FF) - 1;
1798 	if (pext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID)
1799 		memcpy(param->u.crypt.seq, pext->rx_seq, 8);
1800 	if (pext->key_len) {
1801 		param->u.crypt.key_len = pext->key_len;
1802 		memcpy(param + 1, pext + 1, pext->key_len);
1803 	}
1804 	ret = wpa_set_encryption(dev, param, param_len);
1805 	kfree(param);
1806 	return ret;
1807 }
1808 
r871x_wx_get_nick(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1809 static int r871x_wx_get_nick(struct net_device *dev,
1810 			     struct iw_request_info *info,
1811 			     union iwreq_data *wrqu, char *extra)
1812 {
1813 	if (extra) {
1814 		wrqu->data.length = 8;
1815 		wrqu->data.flags = 1;
1816 		memcpy(extra, "rtl_wifi", 8);
1817 	}
1818 	return 0;
1819 }
1820 
r8711_wx_read32(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * keybuf)1821 static int r8711_wx_read32(struct net_device *dev,
1822 				struct iw_request_info *info,
1823 				union iwreq_data *wrqu, char *keybuf)
1824 {
1825 	struct _adapter *padapter = netdev_priv(dev);
1826 	u32 addr;
1827 	u32 data32;
1828 
1829 	get_user(addr, (u32 __user *)wrqu->data.pointer);
1830 	data32 = r8712_read32(padapter, addr);
1831 	put_user(data32, (u32 __user *)wrqu->data.pointer);
1832 	wrqu->data.length = (data32 & 0xffff0000) >> 16;
1833 	wrqu->data.flags = data32 & 0xffff;
1834 	get_user(addr, (u32 __user *)wrqu->data.pointer);
1835 	return 0;
1836 }
1837 
r8711_wx_write32(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * keybuf)1838 static int r8711_wx_write32(struct net_device *dev,
1839 				 struct iw_request_info *info,
1840 				 union iwreq_data *wrqu, char *keybuf)
1841 {
1842 	struct _adapter *padapter = netdev_priv(dev);
1843 	u32 addr;
1844 	u32 data32;
1845 
1846 	get_user(addr, (u32 __user *)wrqu->data.pointer);
1847 	data32 = ((u32)wrqu->data.length << 16) | (u32)wrqu->data.flags;
1848 	r8712_write32(padapter, addr, data32);
1849 	return 0;
1850 }
1851 
dummy(struct net_device * dev,struct iw_request_info * a,union iwreq_data * wrqu,char * b)1852 static int dummy(struct net_device *dev,
1853 		struct iw_request_info *a,
1854 		union iwreq_data *wrqu, char *b)
1855 {
1856 	return -EINVAL;
1857 }
1858 
r8711_drvext_hdl(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1859 static int r8711_drvext_hdl(struct net_device *dev,
1860 				struct iw_request_info *info,
1861 				union iwreq_data *wrqu, char *extra)
1862 {
1863 	return 0;
1864 }
1865 
r871x_mp_ioctl_hdl(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1866 static int r871x_mp_ioctl_hdl(struct net_device *dev,
1867 				struct iw_request_info *info,
1868 				union iwreq_data *wrqu, char *extra)
1869 {
1870 	struct _adapter *padapter = netdev_priv(dev);
1871 	struct iw_point *p = &wrqu->data;
1872 	struct oid_par_priv oid_par;
1873 	struct mp_ioctl_handler *phandler;
1874 	struct mp_ioctl_param *poidparam;
1875 	unsigned long BytesRead, BytesWritten, BytesNeeded;
1876 	u8 *pparmbuf, bset;
1877 	u16 len;
1878 	uint status;
1879 	int ret = 0;
1880 
1881 	if ((!p->length) || (!p->pointer))
1882 		return -EINVAL;
1883 
1884 	bset = (u8)(p->flags & 0xFFFF);
1885 	len = p->length;
1886 	pparmbuf = memdup_user(p->pointer, len);
1887 	if (IS_ERR(pparmbuf))
1888 		return PTR_ERR(pparmbuf);
1889 
1890 	poidparam = (struct mp_ioctl_param *)pparmbuf;
1891 	if (poidparam->subcode >= MAX_MP_IOCTL_SUBCODE) {
1892 		ret = -EINVAL;
1893 		goto _r871x_mp_ioctl_hdl_exit;
1894 	}
1895 	phandler = mp_ioctl_hdl + poidparam->subcode;
1896 	if ((phandler->paramsize != 0) &&
1897 	    (poidparam->len < phandler->paramsize)) {
1898 		ret = -EINVAL;
1899 		goto _r871x_mp_ioctl_hdl_exit;
1900 	}
1901 	if (phandler->oid == 0 && phandler->handler) {
1902 		status = phandler->handler(&oid_par);
1903 	} else if (phandler->handler) {
1904 		oid_par.adapter_context = padapter;
1905 		oid_par.oid = phandler->oid;
1906 		oid_par.information_buf = poidparam->data;
1907 		oid_par.information_buf_len = poidparam->len;
1908 		oid_par.dbg = 0;
1909 		BytesWritten = 0;
1910 		BytesNeeded = 0;
1911 		if (bset) {
1912 			oid_par.bytes_rw = &BytesRead;
1913 			oid_par.bytes_needed = &BytesNeeded;
1914 			oid_par.type_of_oid = SET_OID;
1915 		} else {
1916 			oid_par.bytes_rw = &BytesWritten;
1917 			oid_par.bytes_needed = &BytesNeeded;
1918 			oid_par.type_of_oid = QUERY_OID;
1919 		}
1920 		status = phandler->handler(&oid_par);
1921 		/* todo:check status, BytesNeeded, etc. */
1922 	} else {
1923 		netdev_info(dev, "r8712u: %s: err!, subcode=%d, oid=%d, handler=%p\n",
1924 			    __func__, poidparam->subcode, phandler->oid,
1925 			    phandler->handler);
1926 		ret = -EFAULT;
1927 		goto _r871x_mp_ioctl_hdl_exit;
1928 	}
1929 	if (bset == 0x00) { /* query info */
1930 		if (copy_to_user(p->pointer, pparmbuf, len))
1931 			ret = -EFAULT;
1932 	}
1933 	if (status) {
1934 		ret = -EFAULT;
1935 		goto _r871x_mp_ioctl_hdl_exit;
1936 	}
1937 _r871x_mp_ioctl_hdl_exit:
1938 	kfree(pparmbuf);
1939 	return ret;
1940 }
1941 
r871x_get_ap_info(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1942 static int r871x_get_ap_info(struct net_device *dev,
1943 				struct iw_request_info *info,
1944 				union iwreq_data *wrqu, char *extra)
1945 {
1946 	struct _adapter *padapter = netdev_priv(dev);
1947 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1948 	struct  __queue *queue = &pmlmepriv->scanned_queue;
1949 	struct iw_point *pdata = &wrqu->data;
1950 	struct wlan_network *pnetwork = NULL;
1951 	u32 cnt = 0, wpa_ielen;
1952 	unsigned long irqL;
1953 	struct list_head *plist, *phead;
1954 	unsigned char *pbuf;
1955 	u8 bssid[ETH_ALEN];
1956 	char data[33];
1957 
1958 	if (padapter->bDriverStopped || (pdata == NULL))
1959 		return -EINVAL;
1960 	while (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY |
1961 			     _FW_UNDER_LINKING)) {
1962 		msleep(30);
1963 		cnt++;
1964 		if (cnt > 100)
1965 			break;
1966 	}
1967 	pdata->flags = 0;
1968 	if (pdata->length < 32)
1969 		return -EINVAL;
1970 	if (copy_from_user(data, pdata->pointer, 32))
1971 		return -EINVAL;
1972 	data[32] = 0;
1973 
1974 	spin_lock_irqsave(&(pmlmepriv->scanned_queue.lock), irqL);
1975 	phead = &queue->queue;
1976 	plist = phead->next;
1977 	while (1) {
1978 		if (end_of_queue_search(phead, plist))
1979 			break;
1980 		pnetwork = container_of(plist, struct wlan_network, list);
1981 		if (!mac_pton(data, bssid)) {
1982 			netdev_info(dev, "r8712u: Invalid BSSID '%s'.\n",
1983 				    (u8 *)data);
1984 			spin_unlock_irqrestore(&(pmlmepriv->scanned_queue.lock),
1985 					       irqL);
1986 			return -EINVAL;
1987 		}
1988 		netdev_info(dev, "r8712u: BSSID:%pM\n", bssid);
1989 		if (ether_addr_equal(bssid, pnetwork->network.MacAddress)) {
1990 			/* BSSID match, then check if supporting wpa/wpa2 */
1991 			pbuf = r8712_get_wpa_ie(&pnetwork->network.IEs[12],
1992 			       &wpa_ielen, pnetwork->network.IELength - 12);
1993 			if (pbuf && (wpa_ielen > 0)) {
1994 				pdata->flags = 1;
1995 				break;
1996 			}
1997 			pbuf = r8712_get_wpa2_ie(&pnetwork->network.IEs[12],
1998 			       &wpa_ielen, pnetwork->network.IELength - 12);
1999 			if (pbuf && (wpa_ielen > 0)) {
2000 				pdata->flags = 2;
2001 				break;
2002 			}
2003 		}
2004 		plist = plist->next;
2005 	}
2006 	spin_unlock_irqrestore(&(pmlmepriv->scanned_queue.lock), irqL);
2007 	if (pdata->length >= 34) {
2008 		if (copy_to_user((u8 __user *)pdata->pointer + 32,
2009 		    (u8 *)&pdata->flags, 1))
2010 			return -EINVAL;
2011 	}
2012 	return 0;
2013 }
2014 
r871x_set_pid(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)2015 static int r871x_set_pid(struct net_device *dev,
2016 				struct iw_request_info *info,
2017 				union iwreq_data *wrqu, char *extra)
2018 {
2019 	struct _adapter *padapter = netdev_priv(dev);
2020 	struct iw_point *pdata = &wrqu->data;
2021 
2022 	if ((padapter->bDriverStopped) || (pdata == NULL))
2023 		return -EINVAL;
2024 	if (copy_from_user(&padapter->pid, pdata->pointer, sizeof(int)))
2025 		return -EINVAL;
2026 	return 0;
2027 }
2028 
r871x_set_chplan(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)2029 static int r871x_set_chplan(struct net_device *dev,
2030 				struct iw_request_info *info,
2031 				union iwreq_data *wrqu, char *extra)
2032 {
2033 	int ret = 0;
2034 	struct _adapter *padapter = netdev_priv(dev);
2035 	struct iw_point *pdata = &wrqu->data;
2036 	int ch_plan = -1;
2037 
2038 	if ((padapter->bDriverStopped) || (pdata == NULL)) {
2039 		ret = -EINVAL;
2040 		goto exit;
2041 	}
2042 	ch_plan = (int)*extra;
2043 	r8712_set_chplan_cmd(padapter, ch_plan);
2044 
2045 exit:
2046 
2047 	return ret;
2048 }
2049 
r871x_wps_start(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)2050 static int r871x_wps_start(struct net_device *dev,
2051 			   struct iw_request_info *info,
2052 			   union iwreq_data *wrqu, char *extra)
2053 {
2054 	struct _adapter *padapter = netdev_priv(dev);
2055 	struct iw_point *pdata = &wrqu->data;
2056 	u32   u32wps_start = 0;
2057 
2058 	if ((padapter->bDriverStopped) || (pdata == NULL))
2059 		return -EINVAL;
2060 	if (copy_from_user((void *)&u32wps_start, pdata->pointer, 4))
2061 		return -EFAULT;
2062 	if (u32wps_start == 0)
2063 		u32wps_start = *extra;
2064 	if (u32wps_start == 1) /* WPS Start */
2065 		padapter->ledpriv.LedControlHandler(padapter,
2066 			   LED_CTL_START_WPS);
2067 	else if (u32wps_start == 2) /* WPS Stop because of wps success */
2068 		padapter->ledpriv.LedControlHandler(padapter,
2069 			   LED_CTL_STOP_WPS);
2070 	else if (u32wps_start == 3) /* WPS Stop because of wps fail */
2071 		padapter->ledpriv.LedControlHandler(padapter,
2072 			   LED_CTL_STOP_WPS_FAIL);
2073 	return 0;
2074 }
2075 
wpa_set_param(struct net_device * dev,u8 name,u32 value)2076 static int wpa_set_param(struct net_device *dev, u8 name, u32 value)
2077 {
2078 	struct _adapter *padapter = netdev_priv(dev);
2079 
2080 	switch (name) {
2081 	case IEEE_PARAM_WPA_ENABLED:
2082 		padapter->securitypriv.AuthAlgrthm = 2; /* 802.1x */
2083 		switch ((value) & 0xff) {
2084 		case 1: /* WPA */
2085 			padapter->securitypriv.ndisauthtype =
2086 				Ndis802_11AuthModeWPAPSK; /* WPA_PSK */
2087 			padapter->securitypriv.ndisencryptstatus =
2088 				Ndis802_11Encryption2Enabled;
2089 			break;
2090 		case 2: /* WPA2 */
2091 			padapter->securitypriv.ndisauthtype =
2092 				Ndis802_11AuthModeWPA2PSK; /* WPA2_PSK */
2093 			padapter->securitypriv.ndisencryptstatus =
2094 				Ndis802_11Encryption3Enabled;
2095 			break;
2096 		}
2097 		break;
2098 	case IEEE_PARAM_TKIP_COUNTERMEASURES:
2099 		break;
2100 	case IEEE_PARAM_DROP_UNENCRYPTED:
2101 		/* HACK:
2102 		 *
2103 		 * wpa_supplicant calls set_wpa_enabled when the driver
2104 		 * is loaded and unloaded, regardless of if WPA is being
2105 		 * used.  No other calls are made which can be used to
2106 		 * determine if encryption will be used or not prior to
2107 		 * association being expected.  If encryption is not being
2108 		 * used, drop_unencrypted is set to false, else true -- we
2109 		 * can use this to determine if the CAP_PRIVACY_ON bit should
2110 		 * be set.
2111 		 */
2112 		break;
2113 	case IEEE_PARAM_PRIVACY_INVOKED:
2114 		break;
2115 	case IEEE_PARAM_AUTH_ALGS:
2116 		return wpa_set_auth_algs(dev, value);
2117 	case IEEE_PARAM_IEEE_802_1X:
2118 		break;
2119 	case IEEE_PARAM_WPAX_SELECT:
2120 		/* added for WPA2 mixed mode */
2121 		break;
2122 	default:
2123 		return -EOPNOTSUPP;
2124 	}
2125 	return 0;
2126 }
2127 
wpa_mlme(struct net_device * dev,u32 command,u32 reason)2128 static int wpa_mlme(struct net_device *dev, u32 command, u32 reason)
2129 {
2130 	struct _adapter *padapter = netdev_priv(dev);
2131 
2132 	switch (command) {
2133 	case IEEE_MLME_STA_DEAUTH:
2134 		if (!r8712_set_802_11_disassociate(padapter))
2135 			return -1;
2136 		break;
2137 	case IEEE_MLME_STA_DISASSOC:
2138 		if (!r8712_set_802_11_disassociate(padapter))
2139 			return -1;
2140 		break;
2141 	default:
2142 		return -EOPNOTSUPP;
2143 	}
2144 	return 0;
2145 }
2146 
wpa_supplicant_ioctl(struct net_device * dev,struct iw_point * p)2147 static int wpa_supplicant_ioctl(struct net_device *dev, struct iw_point *p)
2148 {
2149 	struct ieee_param *param;
2150 	int ret = 0;
2151 	struct _adapter *padapter = netdev_priv(dev);
2152 
2153 	if (p->length < sizeof(struct ieee_param) || !p->pointer)
2154 		return -EINVAL;
2155 	param = memdup_user(p->pointer, p->length);
2156 	if (IS_ERR(param))
2157 		return PTR_ERR(param);
2158 	switch (param->cmd) {
2159 	case IEEE_CMD_SET_WPA_PARAM:
2160 		ret = wpa_set_param(dev, param->u.wpa_param.name,
2161 		      param->u.wpa_param.value);
2162 		break;
2163 	case IEEE_CMD_SET_WPA_IE:
2164 		ret =  r871x_set_wpa_ie(padapter, (char *)param->u.wpa_ie.data,
2165 		       (u16)param->u.wpa_ie.len);
2166 		break;
2167 	case IEEE_CMD_SET_ENCRYPTION:
2168 		ret = wpa_set_encryption(dev, param, p->length);
2169 		break;
2170 	case IEEE_CMD_MLME:
2171 		ret = wpa_mlme(dev, param->u.mlme.command,
2172 		      param->u.mlme.reason_code);
2173 		break;
2174 	default:
2175 		ret = -EOPNOTSUPP;
2176 		break;
2177 	}
2178 	if (ret == 0 && copy_to_user(p->pointer, param, p->length))
2179 		ret = -EFAULT;
2180 	kfree(param);
2181 	return ret;
2182 }
2183 
2184 /* based on "driver_ipw" and for hostapd */
r871x_ioctl(struct net_device * dev,struct ifreq * rq,int cmd)2185 int r871x_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
2186 {
2187 	struct iwreq *wrq = (struct iwreq *)rq;
2188 
2189 	switch (cmd) {
2190 	case RTL_IOCTL_WPA_SUPPLICANT:
2191 		return wpa_supplicant_ioctl(dev, &wrq->u.data);
2192 	default:
2193 		return -EOPNOTSUPP;
2194 	}
2195 	return 0;
2196 }
2197 
2198 static iw_handler r8711_handlers[] = {
2199 	NULL,				/* SIOCSIWCOMMIT */
2200 	r8711_wx_get_name,		/* SIOCGIWNAME */
2201 	dummy,				/* SIOCSIWNWID */
2202 	dummy,				/* SIOCGIWNWID */
2203 	r8711_wx_set_freq,		/* SIOCSIWFREQ */
2204 	r8711_wx_get_freq,		/* SIOCGIWFREQ */
2205 	r8711_wx_set_mode,		/* SIOCSIWMODE */
2206 	r8711_wx_get_mode,		/* SIOCGIWMODE */
2207 	dummy,				/* SIOCSIWSENS */
2208 	r8711_wx_get_sens,		/* SIOCGIWSENS */
2209 	NULL,				/* SIOCSIWRANGE */
2210 	r8711_wx_get_range,		/* SIOCGIWRANGE */
2211 	r871x_wx_set_priv,		/* SIOCSIWPRIV */
2212 	NULL,				/* SIOCGIWPRIV */
2213 	NULL,				/* SIOCSIWSTATS */
2214 	NULL,				/* SIOCGIWSTATS */
2215 	dummy,				/* SIOCSIWSPY */
2216 	dummy,				/* SIOCGIWSPY */
2217 	NULL,				/* SIOCGIWTHRSPY */
2218 	NULL,				/* SIOCWIWTHRSPY */
2219 	r8711_wx_set_wap,		/* SIOCSIWAP */
2220 	r8711_wx_get_wap,		/* SIOCGIWAP */
2221 	r871x_wx_set_mlme,		/* request MLME operation;
2222 					 *  uses struct iw_mlme
2223 					 */
2224 	dummy,				/* SIOCGIWAPLIST -- deprecated */
2225 	r8711_wx_set_scan,		/* SIOCSIWSCAN */
2226 	r8711_wx_get_scan,		/* SIOCGIWSCAN */
2227 	r8711_wx_set_essid,		/* SIOCSIWESSID */
2228 	r8711_wx_get_essid,		/* SIOCGIWESSID */
2229 	dummy,				/* SIOCSIWNICKN */
2230 	r871x_wx_get_nick,		/* SIOCGIWNICKN */
2231 	NULL,				/* -- hole -- */
2232 	NULL,				/* -- hole -- */
2233 	r8711_wx_set_rate,		/* SIOCSIWRATE */
2234 	r8711_wx_get_rate,		/* SIOCGIWRATE */
2235 	dummy,				/* SIOCSIWRTS */
2236 	r8711_wx_get_rts,		/* SIOCGIWRTS */
2237 	r8711_wx_set_frag,		/* SIOCSIWFRAG */
2238 	r8711_wx_get_frag,		/* SIOCGIWFRAG */
2239 	dummy,				/* SIOCSIWTXPOW */
2240 	dummy,				/* SIOCGIWTXPOW */
2241 	dummy,				/* SIOCSIWRETRY */
2242 	r8711_wx_get_retry,		/* SIOCGIWRETRY */
2243 	r8711_wx_set_enc,		/* SIOCSIWENCODE */
2244 	r8711_wx_get_enc,		/* SIOCGIWENCODE */
2245 	dummy,				/* SIOCSIWPOWER */
2246 	r8711_wx_get_power,		/* SIOCGIWPOWER */
2247 	NULL,				/*---hole---*/
2248 	NULL,				/*---hole---*/
2249 	r871x_wx_set_gen_ie,		/* SIOCSIWGENIE */
2250 	NULL,				/* SIOCGIWGENIE */
2251 	r871x_wx_set_auth,		/* SIOCSIWAUTH */
2252 	NULL,				/* SIOCGIWAUTH */
2253 	r871x_wx_set_enc_ext,		/* SIOCSIWENCODEEXT */
2254 	NULL,				/* SIOCGIWENCODEEXT */
2255 	r871x_wx_set_pmkid,		/* SIOCSIWPMKSA */
2256 	NULL,				/*---hole---*/
2257 };
2258 
2259 static const struct iw_priv_args r8711_private_args[] = {
2260 	{
2261 		SIOCIWFIRSTPRIV + 0x0,
2262 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "read32"
2263 	},
2264 	{
2265 		SIOCIWFIRSTPRIV + 0x1,
2266 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "write32"
2267 	},
2268 	{
2269 		SIOCIWFIRSTPRIV + 0x2, 0, 0, "driver_ext"
2270 	},
2271 	{
2272 		SIOCIWFIRSTPRIV + 0x3, 0, 0, "mp_ioctl"
2273 	},
2274 	{
2275 		SIOCIWFIRSTPRIV + 0x4,
2276 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "apinfo"
2277 	},
2278 	{
2279 		SIOCIWFIRSTPRIV + 0x5,
2280 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setpid"
2281 	},
2282 	{
2283 		SIOCIWFIRSTPRIV + 0x6,
2284 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wps_start"
2285 	},
2286 	{
2287 		SIOCIWFIRSTPRIV + 0x7,
2288 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "chplan"
2289 	}
2290 };
2291 
2292 static iw_handler r8711_private_handler[] = {
2293 	r8711_wx_read32,
2294 	r8711_wx_write32,
2295 	r8711_drvext_hdl,
2296 	r871x_mp_ioctl_hdl,
2297 	r871x_get_ap_info, /*for MM DTV platform*/
2298 	r871x_set_pid,
2299 	r871x_wps_start,
2300 	r871x_set_chplan
2301 };
2302 
r871x_get_wireless_stats(struct net_device * dev)2303 static struct iw_statistics *r871x_get_wireless_stats(struct net_device *dev)
2304 {
2305 	struct _adapter *padapter = netdev_priv(dev);
2306 	struct iw_statistics *piwstats = &padapter->iwstats;
2307 	int tmp_level = 0;
2308 	int tmp_qual = 0;
2309 	int tmp_noise = 0;
2310 
2311 	if (check_fwstate(&padapter->mlmepriv, _FW_LINKED) != true) {
2312 		piwstats->qual.qual = 0;
2313 		piwstats->qual.level = 0;
2314 		piwstats->qual.noise = 0;
2315 	} else {
2316 		/* show percentage, we need transfer dbm to original value. */
2317 		tmp_level = padapter->recvpriv.fw_rssi;
2318 		tmp_qual = padapter->recvpriv.signal;
2319 		tmp_noise = padapter->recvpriv.noise;
2320 		piwstats->qual.level = tmp_level;
2321 		piwstats->qual.qual = tmp_qual;
2322 		piwstats->qual.noise = tmp_noise;
2323 	}
2324 	piwstats->qual.updated = IW_QUAL_ALL_UPDATED;
2325 	return &padapter->iwstats;
2326 }
2327 
2328 struct iw_handler_def r871x_handlers_def = {
2329 	.standard = r8711_handlers,
2330 	.num_standard = ARRAY_SIZE(r8711_handlers),
2331 	.private = r8711_private_handler,
2332 	.private_args = (struct iw_priv_args *)r8711_private_args,
2333 	.num_private = ARRAY_SIZE(r8711_private_handler),
2334 	.num_private_args = sizeof(r8711_private_args) /
2335 			    sizeof(struct iw_priv_args),
2336 	.get_wireless_stats = r871x_get_wireless_stats
2337 };
2338