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