1 // SPDX-License-Identifier: GPL-2.0
2 /******************************************************************************
3 * rtl871x_ioctl_linux.c
5 * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
6 * Linux device driver for RTL8192SU
8 * Modifications for inclusion into the Linux staging tree are
9 * Copyright(c) 2010 Larry Finger. All rights reserved.
11 * Contact information:
12 * WLAN FAE <wlanfae@realtek.com>
13 * Larry Finger <Larry.Finger@lwfinger.net>
15 ******************************************************************************/
17 #define _RTL871X_IOCTL_LINUX_C_
18 #define _RTL871X_MP_IOCTL_C_
20 #include "osdep_service.h"
21 #include "drv_types.h"
22 #include "wlan_bssdef.h"
23 #include "rtl871x_debug.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>
34 #include <linux/semaphore.h>
35 #include <net/iw_handler.h>
36 #include <linux/if_arp.h>
37 #include <linux/etherdevice.h>
40 #define RTL_IOCTL_WPA_SUPPLICANT (SIOCIWFIRSTPRIV + 0x1E)
42 #define SCAN_ITEM_SIZE 768
43 #define MAX_CUSTOM_LEN 64
47 static const u32 rtl8180_rates[] = {1000000, 2000000, 5500000, 11000000,
48 6000000, 9000000, 12000000, 18000000,
49 24000000, 36000000, 48000000, 54000000};
51 static const long ieee80211_wlan_frequencies[] = {
52 2412, 2417, 2422, 2427,
53 2432, 2437, 2442, 2447,
54 2452, 2457, 2462, 2467,
58 void r8712_indicate_wx_assoc_event(struct _adapter *padapter)
60 union iwreq_data wrqu;
61 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
63 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
64 memcpy(wrqu.ap_addr.sa_data, pmlmepriv->cur_network.network.MacAddress,
66 wireless_send_event(padapter->pnetdev, SIOCGIWAP, &wrqu, NULL);
69 void r8712_indicate_wx_disassoc_event(struct _adapter *padapter)
71 union iwreq_data wrqu;
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);
78 static inline void handle_pairwise_key(struct sta_info *psta,
79 struct ieee_param *param,
80 struct _adapter *padapter)
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));
94 r8712_setstakey_cmd(padapter, (unsigned char *)psta, true);
97 static inline void handle_group_key(struct ieee_param *param,
98 struct _adapter *padapter)
100 union Keytype *gk = padapter->securitypriv.XGrpKey;
101 union Keytype *gtk = padapter->securitypriv.XGrptxmickey;
102 union Keytype *grk = padapter->securitypriv.XGrprxmickey;
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,
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,
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));
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)
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;
138 r8712_get_sec_ie(pnetwork->network.IEs,
139 pnetwork->network.IELength, rsn_ie, &rsn_len,
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,
147 if (n == MAX_WPA_IE_LEN-1)
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,
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,
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,
167 if (n == MAX_WPA_IE_LEN-1)
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,
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,
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)
194 if (r8712_get_wps_ie(pnetwork->network.IEs,
195 pnetwork->network.IELength,
196 wps_ie, &wps_ielen)) {
198 iwe->cmd = IWEVGENIE;
199 iwe->u.data.length = (u16)wps_ielen;
200 start = iwe_stream_add_point(info, start, 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)
214 struct ieee80211_ht_cap *pht_capie;
217 u32 i = 0, ht_ielen = 0;
218 u16 cap, ht_cap = false, mcs_rate;
221 if ((pnetwork->network.Configuration.DSConfig < 1) ||
222 (pnetwork->network.Configuration.DSConfig > 14)) {
223 if (pnetwork->network.Configuration.DSConfig < 1)
224 pnetwork->network.Configuration.DSConfig = 1;
226 pnetwork->network.Configuration.DSConfig = 14;
230 iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
231 ether_addr_copy(iwe.u.ap_addr.sa_data, pnetwork->network.MacAddress);
232 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_ADDR_LEN);
234 iwe.cmd = SIOCGIWESSID;
235 iwe.u.data.flags = 1;
236 iwe.u.data.length = min_t(u32, pnetwork->network.Ssid.SsidLength, 32);
237 start = iwe_stream_add_point(info, start, stop, &iwe,
238 pnetwork->network.Ssid.Ssid);
239 /* parsing HT_CAP_IE */
240 p = r8712_get_ie(&pnetwork->network.IEs[12], _HT_CAPABILITY_IE_,
241 &ht_ielen, pnetwork->network.IELength - 12);
242 if (p && ht_ielen > 0) {
244 pht_capie = (struct ieee80211_ht_cap *)(p + 2);
245 memcpy(&mcs_rate, pht_capie->supp_mcs_set, 2);
247 /* Add the protocol name */
248 iwe.cmd = SIOCGIWNAME;
249 if (r8712_is_cckratesonly_included(pnetwork->network.rates)) {
251 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bn");
253 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11b");
254 } else if (r8712_is_cckrates_included(pnetwork->network.rates)) {
256 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bgn");
258 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bg");
261 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11gn");
263 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11g");
265 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_CHAR_LEN);
267 iwe.cmd = SIOCGIWMODE;
268 memcpy((u8 *)&cap, r8712_get_capability_from_ie(pnetwork->network.IEs),
271 if (cap & (WLAN_CAPABILITY_IBSS | WLAN_CAPABILITY_BSS)) {
272 if (cap & WLAN_CAPABILITY_BSS)
273 iwe.u.mode = (u32)IW_MODE_MASTER;
275 iwe.u.mode = (u32)IW_MODE_ADHOC;
276 start = iwe_stream_add_event(info, start, stop, &iwe,
279 /* Add frequency/channel */
280 iwe.cmd = SIOCGIWFREQ;
282 /* check legal index */
283 u8 dsconfig = pnetwork->network.Configuration.DSConfig;
285 if (dsconfig >= 1 && dsconfig <= sizeof(
286 ieee80211_wlan_frequencies) / sizeof(long))
288 (s32)(ieee80211_wlan_frequencies
289 [dsconfig - 1] * 100000);
293 iwe.u.freq.e = (s16)1;
294 iwe.u.freq.i = (u8)pnetwork->network.Configuration.DSConfig;
295 start = iwe_stream_add_event(info, start, stop, &iwe,
297 /* Add encryption capability */
298 iwe.cmd = SIOCGIWENCODE;
299 if (cap & WLAN_CAPABILITY_PRIVACY)
300 iwe.u.data.flags = (u16)(IW_ENCODE_ENABLED |
303 iwe.u.data.flags = (u16)(IW_ENCODE_DISABLED);
304 iwe.u.data.length = (u16)0;
305 start = iwe_stream_add_point(info, start, stop, &iwe,
306 pnetwork->network.Ssid.Ssid);
307 /*Add basic and extended rates */
308 current_val = start + iwe_stream_lcp_len(info);
309 iwe.cmd = SIOCGIWRATE;
310 iwe.u.bitrate.fixed = 0;
311 iwe.u.bitrate.disabled = 0;
312 iwe.u.bitrate.value = 0;
314 while (pnetwork->network.rates[i] != 0) {
315 /* Bit rate given in 500 kb/s units */
316 iwe.u.bitrate.value = (pnetwork->network.rates[i++] &
318 current_val = iwe_stream_add_value(info, start, current_val,
319 stop, &iwe, IW_EV_PARAM_LEN);
321 /* Check if we added any event */
322 if ((current_val - start) > iwe_stream_lcp_len(info))
325 start = translate_scan_wpa(info, pnetwork, &iwe, start, stop);
327 start = translate_scan_wps(info, pnetwork, &iwe, start, stop);
329 /* Add quality statistics */
331 rssi = r8712_signal_scale_mapping(pnetwork->network.Rssi);
332 /* we only update signal_level (signal strength) that is rssi. */
333 iwe.u.qual.updated = (u8)(IW_QUAL_QUAL_INVALID | IW_QUAL_LEVEL_UPDATED |
334 IW_QUAL_NOISE_INVALID);
335 iwe.u.qual.level = rssi; /* signal strength */
336 iwe.u.qual.qual = 0; /* signal quality */
337 iwe.u.qual.noise = 0; /* noise level */
338 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_QUAL_LEN);
339 /* how to translate rssi to ?% */
343 static int wpa_set_auth_algs(struct net_device *dev, u32 value)
345 struct _adapter *padapter = netdev_priv(dev);
348 if ((value & AUTH_ALG_SHARED_KEY) && (value & AUTH_ALG_OPEN_SYSTEM)) {
349 padapter->securitypriv.ndisencryptstatus =
350 Ndis802_11Encryption1Enabled;
351 padapter->securitypriv.ndisauthtype =
352 Ndis802_11AuthModeAutoSwitch;
353 padapter->securitypriv.AuthAlgrthm = 3;
354 } else if (value & AUTH_ALG_SHARED_KEY) {
355 padapter->securitypriv.ndisencryptstatus =
356 Ndis802_11Encryption1Enabled;
357 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeShared;
358 padapter->securitypriv.AuthAlgrthm = 1;
359 } else if (value & AUTH_ALG_OPEN_SYSTEM) {
360 if (padapter->securitypriv.ndisauthtype <
361 Ndis802_11AuthModeWPAPSK) {
362 padapter->securitypriv.ndisauthtype =
363 Ndis802_11AuthModeOpen;
364 padapter->securitypriv.AuthAlgrthm = 0;
372 static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param,
376 u32 wep_key_idx, wep_key_len = 0;
377 struct NDIS_802_11_WEP *pwep = NULL;
378 struct _adapter *padapter = netdev_priv(dev);
379 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
380 struct security_priv *psecuritypriv = &padapter->securitypriv;
382 param->u.crypt.err = 0;
383 param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
384 if (param_len != (u32)((u8 *) param->u.crypt.key - (u8 *)param) +
385 param->u.crypt.key_len)
387 if (!is_broadcast_ether_addr(param->sta_addr))
390 if (param->u.crypt.idx >= WEP_KEYS) {
391 /* for large key indices, set the default (0) */
392 param->u.crypt.idx = 0;
394 if (strcmp(param->u.crypt.alg, "WEP") == 0) {
395 netdev_info(dev, "r8712u: %s: crypt.alg = WEP\n", __func__);
396 padapter->securitypriv.ndisencryptstatus =
397 Ndis802_11Encryption1Enabled;
398 padapter->securitypriv.PrivacyAlgrthm = _WEP40_;
399 padapter->securitypriv.XGrpPrivacy = _WEP40_;
400 wep_key_idx = param->u.crypt.idx;
401 wep_key_len = param->u.crypt.key_len;
402 if (wep_key_idx >= WEP_KEYS)
404 if (wep_key_len <= 0)
407 wep_key_len = wep_key_len <= 5 ? 5 : 13;
408 pwep = kzalloc(sizeof(*pwep), GFP_ATOMIC);
411 pwep->KeyLength = wep_key_len;
412 pwep->Length = wep_key_len +
413 FIELD_OFFSET(struct NDIS_802_11_WEP, KeyMaterial);
414 if (wep_key_len == 13) {
415 padapter->securitypriv.PrivacyAlgrthm = _WEP104_;
416 padapter->securitypriv.XGrpPrivacy = _WEP104_;
418 pwep->KeyIndex = wep_key_idx;
419 pwep->KeyIndex |= 0x80000000;
420 memcpy(pwep->KeyMaterial, param->u.crypt.key, pwep->KeyLength);
421 if (param->u.crypt.set_tx) {
422 if (r8712_set_802_11_add_wep(padapter, pwep))
425 /* don't update "psecuritypriv->PrivacyAlgrthm" and
426 * "psecuritypriv->PrivacyKeyIndex=keyid", but can
427 * r8712_set_key to fw/cam
429 if (wep_key_idx >= WEP_KEYS) {
433 memcpy(&psecuritypriv->DefKey[wep_key_idx].skey[0],
436 psecuritypriv->DefKeylen[wep_key_idx] =
438 r8712_set_key(padapter, psecuritypriv, wep_key_idx);
442 if (padapter->securitypriv.AuthAlgrthm == 2) { /* 802_1x */
443 struct sta_info *psta, *pbcmc_sta;
444 struct sta_priv *pstapriv = &padapter->stapriv;
445 struct security_priv *spriv = &padapter->securitypriv;
447 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE |
448 WIFI_MP_STATE)) { /* sta mode */
449 psta = r8712_get_stainfo(pstapriv,
450 get_bssid(pmlmepriv));
452 psta->ieee8021x_blocked = false;
453 if (spriv->ndisencryptstatus ==
454 Ndis802_11Encryption2Enabled ||
455 spriv->ndisencryptstatus ==
456 Ndis802_11Encryption3Enabled)
457 psta->XPrivacy = spriv->PrivacyAlgrthm;
458 if (param->u.crypt.set_tx == 1)
459 handle_pairwise_key(psta, param,
462 handle_group_key(param, padapter);
464 pbcmc_sta = r8712_get_bcmc_stainfo(padapter);
466 pbcmc_sta->ieee8021x_blocked = false;
467 if (spriv->ndisencryptstatus ==
468 Ndis802_11Encryption2Enabled ||
469 spriv->ndisencryptstatus ==
470 Ndis802_11Encryption3Enabled)
471 pbcmc_sta->XPrivacy =
472 spriv->PrivacyAlgrthm;
481 static int r871x_set_wpa_ie(struct _adapter *padapter, char *pie,
482 unsigned short ielen)
485 int group_cipher = 0, pairwise_cipher = 0;
488 if ((ielen > MAX_WPA_IE_LEN) || (pie == NULL))
491 buf = kmemdup(pie, ielen, GFP_ATOMIC);
494 if (ielen < RSN_HEADER_LEN) {
498 if (r8712_parse_wpa_ie(buf, ielen, &group_cipher,
499 &pairwise_cipher) == 0) {
500 padapter->securitypriv.AuthAlgrthm = 2;
501 padapter->securitypriv.ndisauthtype =
502 Ndis802_11AuthModeWPAPSK;
504 if (r8712_parse_wpa2_ie(buf, ielen, &group_cipher,
505 &pairwise_cipher) == 0) {
506 padapter->securitypriv.AuthAlgrthm = 2;
507 padapter->securitypriv.ndisauthtype =
508 Ndis802_11AuthModeWPA2PSK;
510 switch (group_cipher) {
511 case WPA_CIPHER_NONE:
512 padapter->securitypriv.XGrpPrivacy =
514 padapter->securitypriv.ndisencryptstatus =
515 Ndis802_11EncryptionDisabled;
517 case WPA_CIPHER_WEP40:
518 padapter->securitypriv.XGrpPrivacy = _WEP40_;
519 padapter->securitypriv.ndisencryptstatus =
520 Ndis802_11Encryption1Enabled;
522 case WPA_CIPHER_TKIP:
523 padapter->securitypriv.XGrpPrivacy = _TKIP_;
524 padapter->securitypriv.ndisencryptstatus =
525 Ndis802_11Encryption2Enabled;
527 case WPA_CIPHER_CCMP:
528 padapter->securitypriv.XGrpPrivacy = _AES_;
529 padapter->securitypriv.ndisencryptstatus =
530 Ndis802_11Encryption3Enabled;
532 case WPA_CIPHER_WEP104:
533 padapter->securitypriv.XGrpPrivacy = _WEP104_;
534 padapter->securitypriv.ndisencryptstatus =
535 Ndis802_11Encryption1Enabled;
538 switch (pairwise_cipher) {
539 case WPA_CIPHER_NONE:
540 padapter->securitypriv.PrivacyAlgrthm =
542 padapter->securitypriv.ndisencryptstatus =
543 Ndis802_11EncryptionDisabled;
545 case WPA_CIPHER_WEP40:
546 padapter->securitypriv.PrivacyAlgrthm = _WEP40_;
547 padapter->securitypriv.ndisencryptstatus =
548 Ndis802_11Encryption1Enabled;
550 case WPA_CIPHER_TKIP:
551 padapter->securitypriv.PrivacyAlgrthm = _TKIP_;
552 padapter->securitypriv.ndisencryptstatus =
553 Ndis802_11Encryption2Enabled;
555 case WPA_CIPHER_CCMP:
556 padapter->securitypriv.PrivacyAlgrthm = _AES_;
557 padapter->securitypriv.ndisencryptstatus =
558 Ndis802_11Encryption3Enabled;
560 case WPA_CIPHER_WEP104:
561 padapter->securitypriv.PrivacyAlgrthm = _WEP104_;
562 padapter->securitypriv.ndisencryptstatus =
563 Ndis802_11Encryption1Enabled;
566 padapter->securitypriv.wps_phase = false;
569 u8 eid, wps_oui[4] = {0x0, 0x50, 0xf2, 0x04};
571 while (cnt < ielen) {
574 if ((eid == _VENDOR_SPECIFIC_IE_) &&
575 (!memcmp(&buf[cnt + 2], wps_oui, 4))) {
576 netdev_info(padapter->pnetdev, "r8712u: SET WPS_IE\n");
577 padapter->securitypriv.wps_ie_len =
578 ((buf[cnt + 1] + 2) <
579 (MAX_WPA_IE_LEN << 2)) ?
581 (MAX_WPA_IE_LEN << 2);
582 memcpy(padapter->securitypriv.wps_ie,
584 padapter->securitypriv.wps_ie_len);
585 padapter->securitypriv.wps_phase =
587 netdev_info(padapter->pnetdev, "r8712u: SET WPS_IE, wps_phase==true\n");
588 cnt += buf[cnt + 1] + 2;
592 cnt += buf[cnt + 1] + 2;
601 static int r8711_wx_get_name(struct net_device *dev,
602 struct iw_request_info *info,
603 union iwreq_data *wrqu, char *extra)
605 struct _adapter *padapter = netdev_priv(dev);
609 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
610 struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
613 if (check_fwstate(pmlmepriv, _FW_LINKED | WIFI_ADHOC_MASTER_STATE) ==
615 /* parsing HT_CAP_IE */
616 p = r8712_get_ie(&pcur_bss->IEs[12], _HT_CAPABILITY_IE_,
617 &ht_ielen, pcur_bss->IELength - 12);
618 if (p && ht_ielen > 0)
620 prates = pcur_bss->rates;
621 if (r8712_is_cckratesonly_included(prates)) {
623 snprintf(wrqu->name, IFNAMSIZ,
626 snprintf(wrqu->name, IFNAMSIZ,
628 } else if (r8712_is_cckrates_included(prates)) {
630 snprintf(wrqu->name, IFNAMSIZ,
633 snprintf(wrqu->name, IFNAMSIZ,
637 snprintf(wrqu->name, IFNAMSIZ,
640 snprintf(wrqu->name, IFNAMSIZ,
644 snprintf(wrqu->name, IFNAMSIZ, "unassociated");
649 static const long frequency_list[] = {
650 2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447, 2452, 2457, 2462,
651 2467, 2472, 2484, 4915, 4920, 4925, 4935, 4940, 4945, 4960, 4980,
652 5035, 5040, 5045, 5055, 5060, 5080, 5170, 5180, 5190, 5200, 5210,
653 5220, 5230, 5240, 5260, 5280, 5300, 5320, 5500, 5520, 5540, 5560,
654 5580, 5600, 5620, 5640, 5660, 5680, 5700, 5745, 5765, 5785, 5805,
658 static int r8711_wx_set_freq(struct net_device *dev,
659 struct iw_request_info *info,
660 union iwreq_data *wrqu, char *extra)
662 struct _adapter *padapter = netdev_priv(dev);
663 struct iw_freq *fwrq = &wrqu->freq;
666 /* If setting by frequency, convert to a channel */
667 if ((fwrq->e == 1) &&
668 (fwrq->m >= (int) 2.412e8) &&
669 (fwrq->m <= (int) 2.487e8)) {
670 int f = fwrq->m / 100000;
673 while ((c < 14) && (f != frequency_list[c]))
678 /* Setting by channel number */
679 if ((fwrq->m > 14) || (fwrq->e > 0)) {
682 int channel = fwrq->m;
684 if ((channel < 1) || (channel > 14)) {
687 /* Yes ! We can set it !!! */
688 padapter->registrypriv.channel = channel;
694 static int r8711_wx_get_freq(struct net_device *dev,
695 struct iw_request_info *info,
696 union iwreq_data *wrqu, char *extra)
698 struct _adapter *padapter = netdev_priv(dev);
699 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
700 struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
702 if (!check_fwstate(pmlmepriv, _FW_LINKED))
705 wrqu->freq.m = ieee80211_wlan_frequencies[
706 pcur_bss->Configuration.DSConfig - 1] * 100000;
708 wrqu->freq.i = pcur_bss->Configuration.DSConfig;
713 static int r8711_wx_set_mode(struct net_device *dev,
714 struct iw_request_info *a,
715 union iwreq_data *wrqu, char *b)
717 struct _adapter *padapter = netdev_priv(dev);
718 enum NDIS_802_11_NETWORK_INFRASTRUCTURE networkType;
720 switch (wrqu->mode) {
722 networkType = Ndis802_11AutoUnknown;
725 networkType = Ndis802_11IBSS;
728 networkType = Ndis802_11APMode;
731 networkType = Ndis802_11Infrastructure;
736 if (Ndis802_11APMode == networkType)
737 r8712_setopmode_cmd(padapter, networkType);
739 r8712_setopmode_cmd(padapter, Ndis802_11AutoUnknown);
741 r8712_set_802_11_infrastructure_mode(padapter, networkType);
745 static int r8711_wx_get_mode(struct net_device *dev, struct iw_request_info *a,
746 union iwreq_data *wrqu, char *b)
748 struct _adapter *padapter = netdev_priv(dev);
749 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
751 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE))
752 wrqu->mode = IW_MODE_INFRA;
753 else if (check_fwstate(pmlmepriv,
754 WIFI_ADHOC_MASTER_STATE | WIFI_ADHOC_STATE))
755 wrqu->mode = IW_MODE_ADHOC;
756 else if (check_fwstate(pmlmepriv, WIFI_AP_STATE))
757 wrqu->mode = IW_MODE_MASTER;
759 wrqu->mode = IW_MODE_AUTO;
763 static int r871x_wx_set_pmkid(struct net_device *dev,
764 struct iw_request_info *a,
765 union iwreq_data *wrqu, char *extra)
767 struct _adapter *padapter = netdev_priv(dev);
768 struct security_priv *psecuritypriv = &padapter->securitypriv;
769 struct iw_pmksa *pPMK = (struct iw_pmksa *) extra;
770 struct RT_PMKID_LIST *pl = psecuritypriv->PMKIDList;
771 u8 strZeroMacAddress[ETH_ALEN] = {0x00};
772 u8 strIssueBssid[ETH_ALEN] = {0x00};
773 u8 j, blInserted = false;
774 int intReturn = false;
777 * There are the BSSID information in the bssid.sa_data array.
778 * If cmd is IW_PMKSA_FLUSH, it means the wpa_supplicant wants to clear
779 * all the PMKID information. If cmd is IW_PMKSA_ADD, it means the
780 * wpa_supplicant wants to add a PMKID/BSSID to driver.
781 * If cmd is IW_PMKSA_REMOVE, it means the wpa_supplicant wants to
782 * remove a PMKID/BSSID from driver.
786 memcpy(strIssueBssid, pPMK->bssid.sa_data, ETH_ALEN);
789 if (!memcmp(strIssueBssid, strZeroMacAddress, ETH_ALEN))
793 /* overwrite PMKID */
794 for (j = 0; j < NUM_PMKID_CACHE; j++) {
795 if (!memcmp(pl[j].Bssid, strIssueBssid, ETH_ALEN)) {
796 /* BSSID is matched, the same AP => rewrite
799 netdev_info(dev, "r8712u: %s: BSSID exists in the PMKList.\n",
801 memcpy(pl[j].PMKID, pPMK->pmkid, IW_PMKID_LEN);
803 psecuritypriv->PMKIDIndex = j + 1;
809 /* Find a new entry */
810 netdev_info(dev, "r8712u: %s: Use the new entry index = %d for this PMKID.\n",
811 __func__, psecuritypriv->PMKIDIndex);
812 memcpy(pl[psecuritypriv->PMKIDIndex].Bssid,
813 strIssueBssid, ETH_ALEN);
814 memcpy(pl[psecuritypriv->PMKIDIndex].PMKID,
815 pPMK->pmkid, IW_PMKID_LEN);
816 pl[psecuritypriv->PMKIDIndex].bUsed = true;
817 psecuritypriv->PMKIDIndex++;
818 if (psecuritypriv->PMKIDIndex == NUM_PMKID_CACHE)
819 psecuritypriv->PMKIDIndex = 0;
822 case IW_PMKSA_REMOVE:
824 for (j = 0; j < NUM_PMKID_CACHE; j++) {
825 if (!memcmp(pl[j].Bssid, strIssueBssid, ETH_ALEN)) {
826 /* BSSID is matched, the same AP => Remove
827 * this PMKID information and reset it.
829 eth_zero_addr(pl[j].Bssid);
836 memset(psecuritypriv->PMKIDList, 0,
837 sizeof(struct RT_PMKID_LIST) * NUM_PMKID_CACHE);
838 psecuritypriv->PMKIDIndex = 0;
842 netdev_info(dev, "r8712u: %s: unknown Command\n", __func__);
849 static int r8711_wx_get_sens(struct net_device *dev,
850 struct iw_request_info *info,
851 union iwreq_data *wrqu, char *extra)
853 wrqu->sens.value = 0;
854 wrqu->sens.fixed = 0; /* no auto select */
855 wrqu->sens.disabled = 1;
859 static int r8711_wx_get_range(struct net_device *dev,
860 struct iw_request_info *info,
861 union iwreq_data *wrqu, char *extra)
863 struct iw_range *range = (struct iw_range *)extra;
867 wrqu->data.length = sizeof(*range);
868 memset(range, 0, sizeof(*range));
869 /* Let's try to keep this struct in the same order as in
870 * linux/include/wireless.h
873 /* TODO: See what values we can set, and remove the ones we can't
874 * set, or fill them with some default data.
876 /* ~5 Mb/s real (802.11b) */
877 range->throughput = 5 * 1000 * 1000;
878 /* TODO: 8711 sensitivity ? */
879 /* signal level threshold range */
880 /* percent values between 0 and 100. */
881 range->max_qual.qual = 100;
882 range->max_qual.level = 100;
883 range->max_qual.noise = 100;
884 range->max_qual.updated = 7; /* Updated all three */
885 range->avg_qual.qual = 92; /* > 8% missed beacons is 'bad' */
886 /* TODO: Find real 'good' to 'bad' threshold value for RSSI */
887 range->avg_qual.level = 0x100 - 78;
888 range->avg_qual.noise = 0;
889 range->avg_qual.updated = 7; /* Updated all three */
890 range->num_bitrates = RATE_COUNT;
891 for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++)
892 range->bitrate[i] = rtl8180_rates[i];
893 range->min_frag = MIN_FRAG_THRESHOLD;
894 range->max_frag = MAX_FRAG_THRESHOLD;
896 range->we_version_compiled = WIRELESS_EXT;
897 range->we_version_source = 16;
898 range->num_channels = 14;
899 for (i = 0, val = 0; i < 14; i++) {
900 /* Include only legal frequencies for some countries */
901 range->freq[val].i = i + 1;
902 range->freq[val].m = ieee80211_wlan_frequencies[i] * 100000;
903 range->freq[val].e = 1;
905 if (val == IW_MAX_FREQUENCIES)
908 range->num_frequency = val;
909 range->enc_capa = IW_ENC_CAPA_WPA |
911 IW_ENC_CAPA_CIPHER_TKIP |
912 IW_ENC_CAPA_CIPHER_CCMP;
916 static int r8711_wx_get_rate(struct net_device *dev,
917 struct iw_request_info *info,
918 union iwreq_data *wrqu, char *extra);
920 static int r871x_wx_set_priv(struct net_device *dev,
921 struct iw_request_info *info,
922 union iwreq_data *awrq,
925 int ret = 0, len = 0;
927 struct _adapter *padapter = netdev_priv(dev);
928 struct iw_point *dwrq = (struct iw_point *)awrq;
931 ext = memdup_user(dwrq->pointer, len);
935 if (!strcasecmp(ext, "RSSI")) {
936 /*Return received signal strength indicator in -db for */
939 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
940 struct wlan_network *pcur_network = &pmlmepriv->cur_network;
942 if (check_fwstate(pmlmepriv, _FW_LINKED)) {
943 sprintf(ext, "%s rssi %d",
944 pcur_network->network.Ssid.Ssid,
946 ((padapter->recvpriv.fw_rssi) >> 1) - 95
947 /*pcur_network->network.Rssi */
952 } else if (!strcasecmp(ext, "LINKSPEED")) {
953 /*Return link speed in MBPS */
955 union iwreq_data wrqd;
959 ret_inner = r8711_wx_get_rate(dev, info, &wrqd, extra);
963 mbps = wrqd.bitrate.value / 1000000;
964 sprintf(ext, "LINKSPEED %d", mbps);
965 } else if (!strcasecmp(ext, "MACADDR")) {
966 /*Return mac address of the station */
967 /* Macaddr = xx:xx:xx:xx:xx:xx */
968 sprintf(ext, "MACADDR = %pM", dev->dev_addr);
969 } else if (!strcasecmp(ext, "SCAN-ACTIVE")) {
970 /*Set scan type to active */
971 /*OK if successful */
972 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
974 pmlmepriv->passive_mode = 1;
976 } else if (!strcasecmp(ext, "SCAN-PASSIVE")) {
977 /*Set scan type to passive */
978 /*OK if successful */
979 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
981 pmlmepriv->passive_mode = 0;
983 } else if (!strncmp(ext, "DCE-E", 5)) {
984 /*Set scan type to passive */
985 /*OK if successful */
986 r8712_disconnectCtrlEx_cmd(padapter
987 , 1 /*u32 enableDrvCtrl */
988 , 5 /*u32 tryPktCnt */
989 , 100 /*u32 tryPktInterval */
990 , 5000 /*u32 firstStageTO */
993 } else if (!strncmp(ext, "DCE-D", 5)) {
994 /*Set scan type to passive */
996 r8712_disconnectCtrlEx_cmd(padapter
997 , 0 /*u32 enableDrvCtrl */
998 , 5 /*u32 tryPktCnt */
999 , 100 /*u32 tryPktInterval */
1000 , 5000 /*u32 firstStageTO */
1004 netdev_info(dev, "r8712u: %s: unknown Command %s.\n",
1008 if (copy_to_user(dwrq->pointer, ext,
1009 min(dwrq->length, (__u16)(strlen(ext) + 1))))
1018 * s1. set_802_11_infrastructure_mode()
1019 * s2. set_802_11_authentication_mode()
1020 * s3. set_802_11_encryption_mode()
1021 * s4. set_802_11_bssid()
1023 * This function intends to handle the Set AP command, which specifies the
1024 * MAC# of a preferred Access Point.
1025 * Currently, the request comes via Wireless Extensions' SIOCSIWAP ioctl.
1027 * For this operation to succeed, there is no need for the interface to be up.
1030 static int r8711_wx_set_wap(struct net_device *dev,
1031 struct iw_request_info *info,
1032 union iwreq_data *awrq,
1035 int ret = -EINPROGRESS;
1036 struct _adapter *padapter = netdev_priv(dev);
1037 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1038 struct __queue *queue = &pmlmepriv->scanned_queue;
1039 struct sockaddr *temp = (struct sockaddr *)awrq;
1041 struct list_head *phead;
1043 struct wlan_network *pnetwork = NULL;
1044 enum NDIS_802_11_AUTHENTICATION_MODE authmode;
1046 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY))
1048 if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING))
1050 if (temp->sa_family != ARPHRD_ETHER)
1052 authmode = padapter->securitypriv.ndisauthtype;
1053 spin_lock_irqsave(&queue->lock, irqL);
1054 phead = &queue->queue;
1055 pmlmepriv->pscanned = phead->next;
1057 if (end_of_queue_search(phead, pmlmepriv->pscanned))
1059 pnetwork = container_of(pmlmepriv->pscanned,
1060 struct wlan_network, list);
1061 pmlmepriv->pscanned = pmlmepriv->pscanned->next;
1062 dst_bssid = pnetwork->network.MacAddress;
1063 if (!memcmp(dst_bssid, temp->sa_data, ETH_ALEN)) {
1064 r8712_set_802_11_infrastructure_mode(padapter,
1065 pnetwork->network.InfrastructureMode);
1069 spin_unlock_irqrestore(&queue->lock, irqL);
1071 if (!r8712_set_802_11_authentication_mode(padapter, authmode)) {
1074 if (!r8712_set_802_11_bssid(padapter, temp->sa_data))
1081 static int r8711_wx_get_wap(struct net_device *dev,
1082 struct iw_request_info *info,
1083 union iwreq_data *wrqu, char *extra)
1085 struct _adapter *padapter = netdev_priv(dev);
1086 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1087 struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
1089 wrqu->ap_addr.sa_family = ARPHRD_ETHER;
1090 if (check_fwstate(pmlmepriv, _FW_LINKED | WIFI_ADHOC_MASTER_STATE |
1092 ether_addr_copy(wrqu->ap_addr.sa_data, pcur_bss->MacAddress);
1094 eth_zero_addr(wrqu->ap_addr.sa_data);
1098 static int r871x_wx_set_mlme(struct net_device *dev,
1099 struct iw_request_info *info,
1100 union iwreq_data *wrqu, char *extra)
1103 struct _adapter *padapter = netdev_priv(dev);
1104 struct iw_mlme *mlme = (struct iw_mlme *) extra;
1108 switch (mlme->cmd) {
1109 case IW_MLME_DEAUTH:
1110 if (!r8712_set_802_11_disassociate(padapter))
1113 case IW_MLME_DISASSOC:
1114 if (!r8712_set_802_11_disassociate(padapter))
1125 * This function intends to handle the Set Scan command.
1126 * Currently, the request comes via Wireless Extensions' SIOCSIWSCAN ioctl.
1128 * For this operation to succeed, the interface is brought Up beforehand.
1131 static int r8711_wx_set_scan(struct net_device *dev,
1132 struct iw_request_info *a,
1133 union iwreq_data *wrqu, char *extra)
1135 struct _adapter *padapter = netdev_priv(dev);
1136 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1139 if (padapter->driver_stopped) {
1140 netdev_info(dev, "In %s: driver_stopped=%d\n",
1141 __func__, padapter->driver_stopped);
1146 if (!padapter->hw_init_completed)
1148 if ((check_fwstate(pmlmepriv, _FW_UNDER_SURVEY | _FW_UNDER_LINKING)) ||
1149 (pmlmepriv->sitesurveyctrl.traffic_busy))
1151 if (wrqu->data.length == sizeof(struct iw_scan_req)) {
1152 struct iw_scan_req *req = (struct iw_scan_req *)extra;
1154 if (wrqu->data.flags & IW_SCAN_THIS_ESSID) {
1155 struct ndis_802_11_ssid ssid;
1157 u32 len = min_t(u8, req->essid_len, IW_ESSID_MAX_SIZE);
1159 memset((unsigned char *)&ssid, 0,
1160 sizeof(struct ndis_802_11_ssid));
1161 memcpy(ssid.Ssid, req->essid, len);
1162 ssid.SsidLength = len;
1163 spin_lock_irqsave(&pmlmepriv->lock, irqL);
1164 if ((check_fwstate(pmlmepriv, _FW_UNDER_SURVEY |
1165 _FW_UNDER_LINKING)) ||
1166 (pmlmepriv->sitesurveyctrl.traffic_busy)) {
1167 if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING))
1170 status = r8712_sitesurvey_cmd(padapter, &ssid);
1172 spin_unlock_irqrestore(&pmlmepriv->lock, irqL);
1175 status = r8712_set_802_11_bssid_list_scan(padapter);
1182 static int r8711_wx_get_scan(struct net_device *dev,
1183 struct iw_request_info *a,
1184 union iwreq_data *wrqu, char *extra)
1186 struct _adapter *padapter = netdev_priv(dev);
1187 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1188 struct __queue *queue = &pmlmepriv->scanned_queue;
1189 struct wlan_network *pnetwork = NULL;
1191 struct list_head *plist, *phead;
1193 char *stop = ev + wrqu->data.length;
1194 u32 ret = 0, cnt = 0;
1196 if (padapter->driver_stopped)
1198 while (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY |
1199 _FW_UNDER_LINKING)) {
1205 spin_lock_irqsave(&queue->lock, irqL);
1206 phead = &queue->queue;
1207 plist = phead->next;
1209 if (end_of_queue_search(phead, plist))
1211 if ((stop - ev) < SCAN_ITEM_SIZE) {
1215 pnetwork = container_of(plist, struct wlan_network, list);
1216 ev = translate_scan(padapter, a, pnetwork, ev, stop);
1217 plist = plist->next;
1219 spin_unlock_irqrestore(&queue->lock, irqL);
1220 wrqu->data.length = ev - extra;
1221 wrqu->data.flags = 0;
1226 * s1. set_802_11_infrastructure_mode()
1227 * s2. set_802_11_authenticaion_mode()
1228 * s3. set_802_11_encryption_mode()
1229 * s4. set_802_11_ssid()
1231 * This function intends to handle the Set ESSID command.
1232 * Currently, the request comes via the Wireless Extensions' SIOCSIWESSID ioctl.
1234 * For this operation to succeed, there is no need for the interface to be Up.
1237 static int r8711_wx_set_essid(struct net_device *dev,
1238 struct iw_request_info *a,
1239 union iwreq_data *wrqu, char *extra)
1241 struct _adapter *padapter = netdev_priv(dev);
1242 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1243 struct __queue *queue = &pmlmepriv->scanned_queue;
1244 struct wlan_network *pnetwork = NULL;
1245 enum NDIS_802_11_AUTHENTICATION_MODE authmode;
1246 struct ndis_802_11_ssid ndis_ssid;
1247 u8 *dst_ssid, *src_ssid;
1248 struct list_head *phead;
1251 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY))
1253 if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING))
1255 if (wrqu->essid.length > IW_ESSID_MAX_SIZE)
1257 authmode = padapter->securitypriv.ndisauthtype;
1258 if (wrqu->essid.flags && wrqu->essid.length) {
1259 len = (wrqu->essid.length < IW_ESSID_MAX_SIZE) ?
1260 wrqu->essid.length : IW_ESSID_MAX_SIZE;
1261 memset(&ndis_ssid, 0, sizeof(struct ndis_802_11_ssid));
1262 ndis_ssid.SsidLength = len;
1263 memcpy(ndis_ssid.Ssid, extra, len);
1264 src_ssid = ndis_ssid.Ssid;
1265 phead = &queue->queue;
1266 pmlmepriv->pscanned = phead->next;
1268 if (end_of_queue_search(phead, pmlmepriv->pscanned))
1270 pnetwork = container_of(pmlmepriv->pscanned,
1271 struct wlan_network, list);
1272 pmlmepriv->pscanned = pmlmepriv->pscanned->next;
1273 dst_ssid = pnetwork->network.Ssid.Ssid;
1274 if ((!memcmp(dst_ssid, src_ssid, ndis_ssid.SsidLength))
1275 && (pnetwork->network.Ssid.SsidLength ==
1276 ndis_ssid.SsidLength)) {
1277 if (check_fwstate(pmlmepriv,
1278 WIFI_ADHOC_STATE)) {
1279 if (pnetwork->network.
1283 cur_network.network.
1288 r8712_set_802_11_infrastructure_mode(
1290 pnetwork->network.InfrastructureMode);
1294 r8712_set_802_11_authentication_mode(padapter, authmode);
1295 r8712_set_802_11_ssid(padapter, &ndis_ssid);
1297 return -EINPROGRESS;
1300 static int r8711_wx_get_essid(struct net_device *dev,
1301 struct iw_request_info *a,
1302 union iwreq_data *wrqu, char *extra)
1304 struct _adapter *padapter = netdev_priv(dev);
1305 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1306 struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
1309 if (check_fwstate(pmlmepriv, _FW_LINKED | WIFI_ADHOC_MASTER_STATE)) {
1310 len = pcur_bss->Ssid.SsidLength;
1311 wrqu->essid.length = len;
1312 memcpy(extra, pcur_bss->Ssid.Ssid, len);
1313 wrqu->essid.flags = 1;
1320 static int r8711_wx_set_rate(struct net_device *dev,
1321 struct iw_request_info *a,
1322 union iwreq_data *wrqu, char *extra)
1324 struct _adapter *padapter = netdev_priv(dev);
1325 u32 target_rate = wrqu->bitrate.value;
1326 u32 fixed = wrqu->bitrate.fixed;
1328 u8 datarates[NumRates];
1329 u8 mpdatarate[NumRates] = {11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0xff};
1332 if (target_rate == -1) {
1336 target_rate = target_rate / 100000;
1337 switch (target_rate) {
1379 for (i = 0; i < NumRates; i++) {
1380 if (ratevalue == mpdatarate[i]) {
1381 datarates[i] = mpdatarate[i];
1385 datarates[i] = 0xff;
1388 return r8712_setdatarate_cmd(padapter, datarates);
1391 static int r8711_wx_get_rate(struct net_device *dev,
1392 struct iw_request_info *info,
1393 union iwreq_data *wrqu, char *extra)
1395 struct _adapter *padapter = netdev_priv(dev);
1396 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1397 struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
1398 struct ieee80211_ht_cap *pht_capie;
1399 unsigned char rf_type = padapter->registrypriv.rf_config;
1402 u16 rate, max_rate = 0, ht_cap = false;
1404 u8 bw_40MHz = 0, short_GI = 0;
1408 if (!check_fwstate(pmlmepriv, _FW_LINKED | WIFI_ADHOC_MASTER_STATE))
1410 p = r8712_get_ie(&pcur_bss->IEs[12], _HT_CAPABILITY_IE_, &ht_ielen,
1411 pcur_bss->IELength - 12);
1412 if (p && ht_ielen > 0) {
1414 pht_capie = (struct ieee80211_ht_cap *)(p + 2);
1415 memcpy(&mcs_rate, pht_capie->supp_mcs_set, 2);
1416 bw_40MHz = (le16_to_cpu(pht_capie->cap_info) &
1417 IEEE80211_HT_CAP_SUP_WIDTH) ? 1 : 0;
1418 short_GI = (le16_to_cpu(pht_capie->cap_info) &
1419 (IEEE80211_HT_CAP_SGI_20 |
1420 IEEE80211_HT_CAP_SGI_40)) ? 1 : 0;
1422 while ((pcur_bss->rates[i] != 0) &&
1423 (pcur_bss->rates[i] != 0xFF)) {
1424 rate = pcur_bss->rates[i] & 0x7F;
1425 if (rate > max_rate)
1427 wrqu->bitrate.fixed = 0; /* no auto select */
1428 wrqu->bitrate.value = rate * 500000;
1432 if (mcs_rate & 0x8000 /* MCS15 */
1434 rf_type == RTL8712_RF_2T2R)
1435 max_rate = (bw_40MHz) ? ((short_GI) ? 300 : 270) :
1436 ((short_GI) ? 144 : 130);
1437 else /* default MCS7 */
1438 max_rate = (bw_40MHz) ? ((short_GI) ? 150 : 135) :
1439 ((short_GI) ? 72 : 65);
1440 max_rate *= 2; /* Mbps/2 */
1442 wrqu->bitrate.value = max_rate * 500000;
1446 static int r8711_wx_get_rts(struct net_device *dev,
1447 struct iw_request_info *info,
1448 union iwreq_data *wrqu, char *extra)
1450 struct _adapter *padapter = netdev_priv(dev);
1452 wrqu->rts.value = padapter->registrypriv.rts_thresh;
1453 wrqu->rts.fixed = 0; /* no auto select */
1457 static int r8711_wx_set_frag(struct net_device *dev,
1458 struct iw_request_info *info,
1459 union iwreq_data *wrqu, char *extra)
1461 struct _adapter *padapter = netdev_priv(dev);
1463 if (wrqu->frag.disabled) {
1464 padapter->xmitpriv.frag_len = MAX_FRAG_THRESHOLD;
1466 if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
1467 wrqu->frag.value > MAX_FRAG_THRESHOLD)
1469 padapter->xmitpriv.frag_len = wrqu->frag.value & ~0x1;
1474 static int r8711_wx_get_frag(struct net_device *dev,
1475 struct iw_request_info *info,
1476 union iwreq_data *wrqu, char *extra)
1478 struct _adapter *padapter = netdev_priv(dev);
1480 wrqu->frag.value = padapter->xmitpriv.frag_len;
1481 wrqu->frag.fixed = 0; /* no auto select */
1485 static int r8711_wx_get_retry(struct net_device *dev,
1486 struct iw_request_info *info,
1487 union iwreq_data *wrqu, char *extra)
1489 wrqu->retry.value = 7;
1490 wrqu->retry.fixed = 0; /* no auto select */
1491 wrqu->retry.disabled = 1;
1495 static int r8711_wx_set_enc(struct net_device *dev,
1496 struct iw_request_info *info,
1497 union iwreq_data *wrqu, char *keybuf)
1500 u32 keyindex_provided;
1501 struct NDIS_802_11_WEP wep;
1502 enum NDIS_802_11_AUTHENTICATION_MODE authmode;
1503 struct iw_point *erq = &(wrqu->encoding);
1504 struct _adapter *padapter = netdev_priv(dev);
1506 key = erq->flags & IW_ENCODE_INDEX;
1507 memset(&wep, 0, sizeof(struct NDIS_802_11_WEP));
1508 if (erq->flags & IW_ENCODE_DISABLED) {
1509 netdev_info(dev, "r8712u: %s: EncryptionDisabled\n", __func__);
1510 padapter->securitypriv.ndisencryptstatus =
1511 Ndis802_11EncryptionDisabled;
1512 padapter->securitypriv.PrivacyAlgrthm = _NO_PRIVACY_;
1513 padapter->securitypriv.XGrpPrivacy = _NO_PRIVACY_;
1514 padapter->securitypriv.AuthAlgrthm = 0; /* open system */
1515 authmode = Ndis802_11AuthModeOpen;
1516 padapter->securitypriv.ndisauthtype = authmode;
1523 keyindex_provided = 1;
1525 keyindex_provided = 0;
1526 key = padapter->securitypriv.PrivacyKeyIndex;
1528 /* set authentication mode */
1529 if (erq->flags & IW_ENCODE_OPEN) {
1530 netdev_info(dev, "r8712u: %s: IW_ENCODE_OPEN\n", __func__);
1531 padapter->securitypriv.ndisencryptstatus =
1532 Ndis802_11Encryption1Enabled;
1533 padapter->securitypriv.AuthAlgrthm = 0; /* open system */
1534 padapter->securitypriv.PrivacyAlgrthm = _NO_PRIVACY_;
1535 padapter->securitypriv.XGrpPrivacy = _NO_PRIVACY_;
1536 authmode = Ndis802_11AuthModeOpen;
1537 padapter->securitypriv.ndisauthtype = authmode;
1538 } else if (erq->flags & IW_ENCODE_RESTRICTED) {
1540 "r8712u: %s: IW_ENCODE_RESTRICTED\n", __func__);
1541 padapter->securitypriv.ndisencryptstatus =
1542 Ndis802_11Encryption1Enabled;
1543 padapter->securitypriv.AuthAlgrthm = 1; /* shared system */
1544 padapter->securitypriv.PrivacyAlgrthm = _WEP40_;
1545 padapter->securitypriv.XGrpPrivacy = _WEP40_;
1546 authmode = Ndis802_11AuthModeShared;
1547 padapter->securitypriv.ndisauthtype = authmode;
1549 padapter->securitypriv.ndisencryptstatus =
1550 Ndis802_11Encryption1Enabled;
1551 padapter->securitypriv.AuthAlgrthm = 0; /* open system */
1552 padapter->securitypriv.PrivacyAlgrthm = _NO_PRIVACY_;
1553 padapter->securitypriv.XGrpPrivacy = _NO_PRIVACY_;
1554 authmode = Ndis802_11AuthModeOpen;
1555 padapter->securitypriv.ndisauthtype = authmode;
1558 if (erq->length > 0) {
1559 wep.KeyLength = erq->length <= 5 ? 5 : 13;
1560 wep.Length = wep.KeyLength +
1561 FIELD_OFFSET(struct NDIS_802_11_WEP, KeyMaterial);
1564 if (keyindex_provided == 1) { /* set key_id only, no given
1565 * KeyMaterial(erq->length==0).
1567 padapter->securitypriv.PrivacyKeyIndex = key;
1568 switch (padapter->securitypriv.DefKeylen[key]) {
1570 padapter->securitypriv.PrivacyAlgrthm =
1574 padapter->securitypriv.PrivacyAlgrthm =
1578 padapter->securitypriv.PrivacyAlgrthm =
1585 wep.KeyIndex |= 0x80000000; /* transmit key */
1586 memcpy(wep.KeyMaterial, keybuf, wep.KeyLength);
1587 if (r8712_set_802_11_add_wep(padapter, &wep))
1592 static int r8711_wx_get_enc(struct net_device *dev,
1593 struct iw_request_info *info,
1594 union iwreq_data *wrqu, char *keybuf)
1597 struct _adapter *padapter = netdev_priv(dev);
1598 struct iw_point *erq = &(wrqu->encoding);
1599 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1600 union Keytype *dk = padapter->securitypriv.DefKey;
1602 if (!check_fwstate(pmlmepriv, _FW_LINKED)) {
1603 if (!check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) {
1605 erq->flags |= IW_ENCODE_DISABLED;
1609 key = erq->flags & IW_ENCODE_INDEX;
1615 key = padapter->securitypriv.PrivacyKeyIndex;
1617 erq->flags = key + 1;
1618 switch (padapter->securitypriv.ndisencryptstatus) {
1619 case Ndis802_11EncryptionNotSupported:
1620 case Ndis802_11EncryptionDisabled:
1622 erq->flags |= IW_ENCODE_DISABLED;
1624 case Ndis802_11Encryption1Enabled:
1625 erq->length = padapter->securitypriv.DefKeylen[key];
1627 memcpy(keybuf, dk[key].skey,
1628 padapter->securitypriv.DefKeylen[key]);
1629 erq->flags |= IW_ENCODE_ENABLED;
1630 if (padapter->securitypriv.ndisauthtype ==
1631 Ndis802_11AuthModeOpen)
1632 erq->flags |= IW_ENCODE_OPEN;
1633 else if (padapter->securitypriv.ndisauthtype ==
1634 Ndis802_11AuthModeShared)
1635 erq->flags |= IW_ENCODE_RESTRICTED;
1638 erq->flags |= IW_ENCODE_DISABLED;
1641 case Ndis802_11Encryption2Enabled:
1642 case Ndis802_11Encryption3Enabled:
1644 erq->flags |= (IW_ENCODE_ENABLED | IW_ENCODE_OPEN |
1649 erq->flags |= IW_ENCODE_DISABLED;
1655 static int r8711_wx_get_power(struct net_device *dev,
1656 struct iw_request_info *info,
1657 union iwreq_data *wrqu, char *extra)
1659 wrqu->power.value = 0;
1660 wrqu->power.fixed = 0; /* no auto select */
1661 wrqu->power.disabled = 1;
1665 static int r871x_wx_set_gen_ie(struct net_device *dev,
1666 struct iw_request_info *info,
1667 union iwreq_data *wrqu, char *extra)
1669 struct _adapter *padapter = netdev_priv(dev);
1671 return r871x_set_wpa_ie(padapter, extra, wrqu->data.length);
1674 static int r871x_wx_set_auth(struct net_device *dev,
1675 struct iw_request_info *info,
1676 union iwreq_data *wrqu, char *extra)
1678 struct _adapter *padapter = netdev_priv(dev);
1679 struct iw_param *param = (struct iw_param *)&(wrqu->param);
1684 paramid = param->flags & IW_AUTH_INDEX;
1685 paramval = param->value;
1687 case IW_AUTH_WPA_VERSION:
1689 case IW_AUTH_CIPHER_PAIRWISE:
1691 case IW_AUTH_CIPHER_GROUP:
1693 case IW_AUTH_KEY_MGMT:
1695 * ??? does not use these parameters
1698 case IW_AUTH_TKIP_COUNTERMEASURES:
1700 /* wpa_supplicant is enabling tkip countermeasure. */
1701 padapter->securitypriv.btkip_countermeasure = true;
1703 /* wpa_supplicant is disabling tkip countermeasure. */
1704 padapter->securitypriv.btkip_countermeasure = false;
1707 case IW_AUTH_DROP_UNENCRYPTED:
1710 * wpa_supplicant calls set_wpa_enabled when the driver
1711 * is loaded and unloaded, regardless of if WPA is being
1712 * used. No other calls are made which can be used to
1713 * determine if encryption will be used or not prior to
1714 * association being expected. If encryption is not being
1715 * used, drop_unencrypted is set to false, else true -- we
1716 * can use this to determine if the CAP_PRIVACY_ON bit should
1719 if (padapter->securitypriv.ndisencryptstatus ==
1720 Ndis802_11Encryption1Enabled) {
1721 /* it means init value, or using wep,
1722 * ndisencryptstatus =
1723 * Ndis802_11Encryption1Enabled,
1724 * then it needn't reset it;
1730 padapter->securitypriv.ndisencryptstatus =
1731 Ndis802_11EncryptionDisabled;
1732 padapter->securitypriv.PrivacyAlgrthm =
1734 padapter->securitypriv.XGrpPrivacy =
1736 padapter->securitypriv.AuthAlgrthm = 0;
1737 padapter->securitypriv.ndisauthtype =
1738 Ndis802_11AuthModeOpen;
1741 case IW_AUTH_80211_AUTH_ALG:
1742 ret = wpa_set_auth_algs(dev, (u32)paramval);
1744 case IW_AUTH_WPA_ENABLED:
1746 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
1748 case IW_AUTH_PRIVACY_INVOKED:
1757 static int r871x_wx_set_enc_ext(struct net_device *dev,
1758 struct iw_request_info *info,
1759 union iwreq_data *wrqu, char *extra)
1761 struct iw_point *pencoding = &wrqu->encoding;
1762 struct iw_encode_ext *pext = (struct iw_encode_ext *)extra;
1763 struct ieee_param *param = NULL;
1768 switch (pext->alg) {
1769 case IW_ENCODE_ALG_NONE:
1772 case IW_ENCODE_ALG_WEP:
1775 case IW_ENCODE_ALG_TKIP:
1778 case IW_ENCODE_ALG_CCMP:
1785 param_len = sizeof(struct ieee_param) + pext->key_len;
1786 param = kzalloc(param_len, GFP_ATOMIC);
1789 param->cmd = IEEE_CMD_SET_ENCRYPTION;
1790 eth_broadcast_addr(param->sta_addr);
1791 strlcpy((char *)param->u.crypt.alg, alg_name, IEEE_CRYPT_ALG_NAME_LEN);
1792 if (pext->ext_flags & IW_ENCODE_EXT_GROUP_KEY)
1793 param->u.crypt.set_tx = 0;
1794 if (pext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
1795 param->u.crypt.set_tx = 1;
1796 param->u.crypt.idx = (pencoding->flags & 0x00FF) - 1;
1797 if (pext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID)
1798 memcpy(param->u.crypt.seq, pext->rx_seq, 8);
1799 if (pext->key_len) {
1800 param->u.crypt.key_len = pext->key_len;
1801 memcpy(param + 1, pext + 1, pext->key_len);
1803 ret = wpa_set_encryption(dev, param, param_len);
1808 static int r871x_wx_get_nick(struct net_device *dev,
1809 struct iw_request_info *info,
1810 union iwreq_data *wrqu, char *extra)
1813 wrqu->data.length = 8;
1814 wrqu->data.flags = 1;
1815 memcpy(extra, "rtl_wifi", 8);
1820 static int r8711_wx_read32(struct net_device *dev,
1821 struct iw_request_info *info,
1822 union iwreq_data *wrqu, char *keybuf)
1824 struct _adapter *padapter = netdev_priv(dev);
1828 get_user(addr, (u32 __user *)wrqu->data.pointer);
1829 data32 = r8712_read32(padapter, addr);
1830 put_user(data32, (u32 __user *)wrqu->data.pointer);
1831 wrqu->data.length = (data32 & 0xffff0000) >> 16;
1832 wrqu->data.flags = data32 & 0xffff;
1833 get_user(addr, (u32 __user *)wrqu->data.pointer);
1837 static int r8711_wx_write32(struct net_device *dev,
1838 struct iw_request_info *info,
1839 union iwreq_data *wrqu, char *keybuf)
1841 struct _adapter *padapter = netdev_priv(dev);
1845 get_user(addr, (u32 __user *)wrqu->data.pointer);
1846 data32 = ((u32)wrqu->data.length << 16) | (u32)wrqu->data.flags;
1847 r8712_write32(padapter, addr, data32);
1851 static int dummy(struct net_device *dev,
1852 struct iw_request_info *a,
1853 union iwreq_data *wrqu, char *b)
1858 static int r8711_drvext_hdl(struct net_device *dev,
1859 struct iw_request_info *info,
1860 union iwreq_data *wrqu, char *extra)
1865 static int r871x_mp_ioctl_hdl(struct net_device *dev,
1866 struct iw_request_info *info,
1867 union iwreq_data *wrqu, char *extra)
1869 struct _adapter *padapter = netdev_priv(dev);
1870 struct iw_point *p = &wrqu->data;
1871 struct oid_par_priv oid_par;
1872 struct mp_ioctl_handler *phandler;
1873 struct mp_ioctl_param *poidparam;
1874 unsigned long BytesRead, BytesWritten, BytesNeeded;
1880 if ((!p->length) || (!p->pointer))
1883 bset = (u8)(p->flags & 0xFFFF);
1885 pparmbuf = memdup_user(p->pointer, len);
1886 if (IS_ERR(pparmbuf))
1887 return PTR_ERR(pparmbuf);
1889 poidparam = (struct mp_ioctl_param *)pparmbuf;
1890 if (poidparam->subcode >= MAX_MP_IOCTL_SUBCODE) {
1892 goto _r871x_mp_ioctl_hdl_exit;
1894 phandler = mp_ioctl_hdl + poidparam->subcode;
1895 if ((phandler->paramsize != 0) &&
1896 (poidparam->len < phandler->paramsize)) {
1898 goto _r871x_mp_ioctl_hdl_exit;
1900 if (phandler->oid == 0 && phandler->handler) {
1901 status = phandler->handler(&oid_par);
1902 } else if (phandler->handler) {
1903 oid_par.adapter_context = padapter;
1904 oid_par.oid = phandler->oid;
1905 oid_par.information_buf = poidparam->data;
1906 oid_par.information_buf_len = poidparam->len;
1911 oid_par.bytes_rw = &BytesRead;
1912 oid_par.bytes_needed = &BytesNeeded;
1913 oid_par.type_of_oid = SET_OID;
1915 oid_par.bytes_rw = &BytesWritten;
1916 oid_par.bytes_needed = &BytesNeeded;
1917 oid_par.type_of_oid = QUERY_OID;
1919 status = phandler->handler(&oid_par);
1920 /* todo:check status, BytesNeeded, etc. */
1922 netdev_info(dev, "r8712u: %s: err!, subcode=%d, oid=%d, handler=%p\n",
1923 __func__, poidparam->subcode, phandler->oid,
1926 goto _r871x_mp_ioctl_hdl_exit;
1928 if (bset == 0x00) { /* query info */
1929 if (copy_to_user(p->pointer, pparmbuf, len))
1934 goto _r871x_mp_ioctl_hdl_exit;
1936 _r871x_mp_ioctl_hdl_exit:
1941 static int r871x_get_ap_info(struct net_device *dev,
1942 struct iw_request_info *info,
1943 union iwreq_data *wrqu, char *extra)
1945 struct _adapter *padapter = netdev_priv(dev);
1946 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1947 struct __queue *queue = &pmlmepriv->scanned_queue;
1948 struct iw_point *pdata = &wrqu->data;
1949 struct wlan_network *pnetwork = NULL;
1950 u32 cnt = 0, wpa_ielen;
1952 struct list_head *plist, *phead;
1953 unsigned char *pbuf;
1957 if (padapter->driver_stopped || (pdata == NULL))
1959 while (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY |
1960 _FW_UNDER_LINKING)) {
1967 if (pdata->length < 32)
1969 if (copy_from_user(data, pdata->pointer, 32))
1973 spin_lock_irqsave(&(pmlmepriv->scanned_queue.lock), irqL);
1974 phead = &queue->queue;
1975 plist = phead->next;
1977 if (end_of_queue_search(phead, plist))
1979 pnetwork = container_of(plist, struct wlan_network, list);
1980 if (!mac_pton(data, bssid)) {
1981 netdev_info(dev, "r8712u: Invalid BSSID '%s'.\n",
1983 spin_unlock_irqrestore(&(pmlmepriv->scanned_queue.lock),
1987 netdev_info(dev, "r8712u: BSSID:%pM\n", bssid);
1988 if (ether_addr_equal(bssid, pnetwork->network.MacAddress)) {
1989 /* BSSID match, then check if supporting wpa/wpa2 */
1990 pbuf = r8712_get_wpa_ie(&pnetwork->network.IEs[12],
1991 &wpa_ielen, pnetwork->network.IELength - 12);
1992 if (pbuf && (wpa_ielen > 0)) {
1996 pbuf = r8712_get_wpa2_ie(&pnetwork->network.IEs[12],
1997 &wpa_ielen, pnetwork->network.IELength - 12);
1998 if (pbuf && (wpa_ielen > 0)) {
2003 plist = plist->next;
2005 spin_unlock_irqrestore(&(pmlmepriv->scanned_queue.lock), irqL);
2006 if (pdata->length >= 34) {
2007 if (copy_to_user((u8 __user *)pdata->pointer + 32,
2008 (u8 *)&pdata->flags, 1))
2014 static int r871x_set_pid(struct net_device *dev,
2015 struct iw_request_info *info,
2016 union iwreq_data *wrqu, char *extra)
2018 struct _adapter *padapter = netdev_priv(dev);
2019 struct iw_point *pdata = &wrqu->data;
2021 if ((padapter->driver_stopped) || (pdata == NULL))
2023 if (copy_from_user(&padapter->pid, pdata->pointer, sizeof(int)))
2028 static int r871x_set_chplan(struct net_device *dev,
2029 struct iw_request_info *info,
2030 union iwreq_data *wrqu, char *extra)
2033 struct _adapter *padapter = netdev_priv(dev);
2034 struct iw_point *pdata = &wrqu->data;
2037 if ((padapter->driver_stopped) || (pdata == NULL)) {
2041 ch_plan = (int)*extra;
2042 r8712_set_chplan_cmd(padapter, ch_plan);
2049 static int r871x_wps_start(struct net_device *dev,
2050 struct iw_request_info *info,
2051 union iwreq_data *wrqu, char *extra)
2053 struct _adapter *padapter = netdev_priv(dev);
2054 struct iw_point *pdata = &wrqu->data;
2055 u32 u32wps_start = 0;
2057 if ((padapter->driver_stopped) || (pdata == NULL))
2059 if (copy_from_user((void *)&u32wps_start, pdata->pointer, 4))
2061 if (u32wps_start == 0)
2062 u32wps_start = *extra;
2063 if (u32wps_start == 1) /* WPS Start */
2064 padapter->ledpriv.LedControlHandler(padapter,
2066 else if (u32wps_start == 2) /* WPS Stop because of wps success */
2067 padapter->ledpriv.LedControlHandler(padapter,
2069 else if (u32wps_start == 3) /* WPS Stop because of wps fail */
2070 padapter->ledpriv.LedControlHandler(padapter,
2071 LED_CTL_STOP_WPS_FAIL);
2075 static int wpa_set_param(struct net_device *dev, u8 name, u32 value)
2077 struct _adapter *padapter = netdev_priv(dev);
2080 case IEEE_PARAM_WPA_ENABLED:
2081 padapter->securitypriv.AuthAlgrthm = 2; /* 802.1x */
2082 switch ((value) & 0xff) {
2084 padapter->securitypriv.ndisauthtype =
2085 Ndis802_11AuthModeWPAPSK; /* WPA_PSK */
2086 padapter->securitypriv.ndisencryptstatus =
2087 Ndis802_11Encryption2Enabled;
2090 padapter->securitypriv.ndisauthtype =
2091 Ndis802_11AuthModeWPA2PSK; /* WPA2_PSK */
2092 padapter->securitypriv.ndisencryptstatus =
2093 Ndis802_11Encryption3Enabled;
2097 case IEEE_PARAM_TKIP_COUNTERMEASURES:
2099 case IEEE_PARAM_DROP_UNENCRYPTED:
2102 * wpa_supplicant calls set_wpa_enabled when the driver
2103 * is loaded and unloaded, regardless of if WPA is being
2104 * used. No other calls are made which can be used to
2105 * determine if encryption will be used or not prior to
2106 * association being expected. If encryption is not being
2107 * used, drop_unencrypted is set to false, else true -- we
2108 * can use this to determine if the CAP_PRIVACY_ON bit should
2112 case IEEE_PARAM_PRIVACY_INVOKED:
2114 case IEEE_PARAM_AUTH_ALGS:
2115 return wpa_set_auth_algs(dev, value);
2116 case IEEE_PARAM_IEEE_802_1X:
2118 case IEEE_PARAM_WPAX_SELECT:
2119 /* added for WPA2 mixed mode */
2127 static int wpa_mlme(struct net_device *dev, u32 command, u32 reason)
2129 struct _adapter *padapter = netdev_priv(dev);
2132 case IEEE_MLME_STA_DEAUTH:
2133 if (!r8712_set_802_11_disassociate(padapter))
2136 case IEEE_MLME_STA_DISASSOC:
2137 if (!r8712_set_802_11_disassociate(padapter))
2146 static int wpa_supplicant_ioctl(struct net_device *dev, struct iw_point *p)
2148 struct ieee_param *param;
2150 struct _adapter *padapter = netdev_priv(dev);
2152 if (p->length < sizeof(struct ieee_param) || !p->pointer)
2154 param = memdup_user(p->pointer, p->length);
2156 return PTR_ERR(param);
2157 switch (param->cmd) {
2158 case IEEE_CMD_SET_WPA_PARAM:
2159 ret = wpa_set_param(dev, param->u.wpa_param.name,
2160 param->u.wpa_param.value);
2162 case IEEE_CMD_SET_WPA_IE:
2163 ret = r871x_set_wpa_ie(padapter, (char *)param->u.wpa_ie.data,
2164 (u16)param->u.wpa_ie.len);
2166 case IEEE_CMD_SET_ENCRYPTION:
2167 ret = wpa_set_encryption(dev, param, p->length);
2170 ret = wpa_mlme(dev, param->u.mlme.command,
2171 param->u.mlme.reason_code);
2177 if (ret == 0 && copy_to_user(p->pointer, param, p->length))
2183 /* based on "driver_ipw" and for hostapd */
2184 int r871x_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
2186 struct iwreq *wrq = (struct iwreq *)rq;
2189 case RTL_IOCTL_WPA_SUPPLICANT:
2190 return wpa_supplicant_ioctl(dev, &wrq->u.data);
2197 static iw_handler r8711_handlers[] = {
2198 NULL, /* SIOCSIWCOMMIT */
2199 r8711_wx_get_name, /* SIOCGIWNAME */
2200 dummy, /* SIOCSIWNWID */
2201 dummy, /* SIOCGIWNWID */
2202 r8711_wx_set_freq, /* SIOCSIWFREQ */
2203 r8711_wx_get_freq, /* SIOCGIWFREQ */
2204 r8711_wx_set_mode, /* SIOCSIWMODE */
2205 r8711_wx_get_mode, /* SIOCGIWMODE */
2206 dummy, /* SIOCSIWSENS */
2207 r8711_wx_get_sens, /* SIOCGIWSENS */
2208 NULL, /* SIOCSIWRANGE */
2209 r8711_wx_get_range, /* SIOCGIWRANGE */
2210 r871x_wx_set_priv, /* SIOCSIWPRIV */
2211 NULL, /* SIOCGIWPRIV */
2212 NULL, /* SIOCSIWSTATS */
2213 NULL, /* SIOCGIWSTATS */
2214 dummy, /* SIOCSIWSPY */
2215 dummy, /* SIOCGIWSPY */
2216 NULL, /* SIOCGIWTHRSPY */
2217 NULL, /* SIOCWIWTHRSPY */
2218 r8711_wx_set_wap, /* SIOCSIWAP */
2219 r8711_wx_get_wap, /* SIOCGIWAP */
2220 r871x_wx_set_mlme, /* request MLME operation;
2221 * uses struct iw_mlme
2223 dummy, /* SIOCGIWAPLIST -- deprecated */
2224 r8711_wx_set_scan, /* SIOCSIWSCAN */
2225 r8711_wx_get_scan, /* SIOCGIWSCAN */
2226 r8711_wx_set_essid, /* SIOCSIWESSID */
2227 r8711_wx_get_essid, /* SIOCGIWESSID */
2228 dummy, /* SIOCSIWNICKN */
2229 r871x_wx_get_nick, /* SIOCGIWNICKN */
2230 NULL, /* -- hole -- */
2231 NULL, /* -- hole -- */
2232 r8711_wx_set_rate, /* SIOCSIWRATE */
2233 r8711_wx_get_rate, /* SIOCGIWRATE */
2234 dummy, /* SIOCSIWRTS */
2235 r8711_wx_get_rts, /* SIOCGIWRTS */
2236 r8711_wx_set_frag, /* SIOCSIWFRAG */
2237 r8711_wx_get_frag, /* SIOCGIWFRAG */
2238 dummy, /* SIOCSIWTXPOW */
2239 dummy, /* SIOCGIWTXPOW */
2240 dummy, /* SIOCSIWRETRY */
2241 r8711_wx_get_retry, /* SIOCGIWRETRY */
2242 r8711_wx_set_enc, /* SIOCSIWENCODE */
2243 r8711_wx_get_enc, /* SIOCGIWENCODE */
2244 dummy, /* SIOCSIWPOWER */
2245 r8711_wx_get_power, /* SIOCGIWPOWER */
2246 NULL, /*---hole---*/
2247 NULL, /*---hole---*/
2248 r871x_wx_set_gen_ie, /* SIOCSIWGENIE */
2249 NULL, /* SIOCGIWGENIE */
2250 r871x_wx_set_auth, /* SIOCSIWAUTH */
2251 NULL, /* SIOCGIWAUTH */
2252 r871x_wx_set_enc_ext, /* SIOCSIWENCODEEXT */
2253 NULL, /* SIOCGIWENCODEEXT */
2254 r871x_wx_set_pmkid, /* SIOCSIWPMKSA */
2255 NULL, /*---hole---*/
2258 static const struct iw_priv_args r8711_private_args[] = {
2260 SIOCIWFIRSTPRIV + 0x0,
2261 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "read32"
2264 SIOCIWFIRSTPRIV + 0x1,
2265 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "write32"
2268 SIOCIWFIRSTPRIV + 0x2, 0, 0, "driver_ext"
2271 SIOCIWFIRSTPRIV + 0x3, 0, 0, "mp_ioctl"
2274 SIOCIWFIRSTPRIV + 0x4,
2275 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "apinfo"
2278 SIOCIWFIRSTPRIV + 0x5,
2279 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setpid"
2282 SIOCIWFIRSTPRIV + 0x6,
2283 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wps_start"
2286 SIOCIWFIRSTPRIV + 0x7,
2287 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "chplan"
2291 static iw_handler r8711_private_handler[] = {
2296 r871x_get_ap_info, /*for MM DTV platform*/
2302 static struct iw_statistics *r871x_get_wireless_stats(struct net_device *dev)
2304 struct _adapter *padapter = netdev_priv(dev);
2305 struct iw_statistics *piwstats = &padapter->iwstats;
2310 if (check_fwstate(&padapter->mlmepriv, _FW_LINKED) != true) {
2311 piwstats->qual.qual = 0;
2312 piwstats->qual.level = 0;
2313 piwstats->qual.noise = 0;
2315 /* show percentage, we need transfer dbm to original value. */
2316 tmp_level = padapter->recvpriv.fw_rssi;
2317 tmp_qual = padapter->recvpriv.signal;
2318 tmp_noise = padapter->recvpriv.noise;
2319 piwstats->qual.level = tmp_level;
2320 piwstats->qual.qual = tmp_qual;
2321 piwstats->qual.noise = tmp_noise;
2323 piwstats->qual.updated = IW_QUAL_ALL_UPDATED;
2324 return &padapter->iwstats;
2327 struct iw_handler_def r871x_handlers_def = {
2328 .standard = r8711_handlers,
2329 .num_standard = ARRAY_SIZE(r8711_handlers),
2330 .private = r8711_private_handler,
2331 .private_args = (struct iw_priv_args *)r8711_private_args,
2332 .num_private = ARRAY_SIZE(r8711_private_handler),
2333 .num_private_args = sizeof(r8711_private_args) /
2334 sizeof(struct iw_priv_args),
2335 .get_wireless_stats = r871x_get_wireless_stats