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