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