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>
39 #define RTL_IOCTL_WPA_SUPPLICANT (SIOCIWFIRSTPRIV + 0x1E)
41 #define SCAN_ITEM_SIZE 768
42 #define MAX_CUSTOM_LEN 64
45 static const u32 rtl8180_rates[] = {1000000, 2000000, 5500000, 11000000,
46 6000000, 9000000, 12000000, 18000000,
47 24000000, 36000000, 48000000, 54000000};
49 static const long ieee80211_wlan_frequencies[] = {
50 2412, 2417, 2422, 2427,
51 2432, 2437, 2442, 2447,
52 2452, 2457, 2462, 2467,
56 void r8712_indicate_wx_assoc_event(struct _adapter *padapter)
58 union iwreq_data wrqu;
59 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
61 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
62 memcpy(wrqu.ap_addr.sa_data, pmlmepriv->cur_network.network.MacAddress, ETH_ALEN);
63 wireless_send_event(padapter->pnetdev, SIOCGIWAP, &wrqu, NULL);
66 void r8712_indicate_wx_disassoc_event(struct _adapter *padapter)
68 union iwreq_data wrqu;
70 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
71 eth_zero_addr(wrqu.ap_addr.sa_data);
72 wireless_send_event(padapter->pnetdev, SIOCGIWAP, &wrqu, NULL);
75 static inline void handle_pairwise_key(struct sta_info *psta,
76 struct ieee_param *param,
77 struct _adapter *padapter)
80 memcpy(psta->x_UncstKey.skey, param->u.crypt.key,
81 (param->u.crypt. key_len > 16 ? 16 : param->u.crypt.key_len));
82 if (strcmp(param->u.crypt.alg, "TKIP") == 0) { /* set mic key */
83 memcpy(psta->tkiptxmickey. skey,
84 ¶m->u.crypt.key[16], 8);
85 memcpy(psta->tkiprxmickey. skey,
86 ¶m->u.crypt.key[24], 8);
87 padapter->securitypriv. busetkipkey = false;
88 mod_timer(&padapter->securitypriv.tkip_timer,
89 jiffies + msecs_to_jiffies(50));
91 r8712_setstakey_cmd(padapter, (unsigned char *)psta, true);
94 static inline void handle_group_key(struct ieee_param *param,
95 struct _adapter *padapter)
97 union Keytype *gk = padapter->securitypriv.XGrpKey;
98 union Keytype *gtk = padapter->securitypriv.XGrptxmickey;
99 union Keytype *grk = padapter->securitypriv.XGrprxmickey;
101 if (param->u.crypt.idx > 0 &&
102 param->u.crypt.idx < 3) {
103 /* group key idx is 1 or 2 */
104 memcpy(gk[param->u.crypt.idx - 1].skey,
106 (param->u.crypt.key_len > 16 ? 16 :
107 param->u.crypt.key_len));
108 memcpy(gtk[param->u.crypt.idx - 1].skey,
109 ¶m->u.crypt.key[16], 8);
110 memcpy(grk[param->u.crypt.idx - 1].skey,
111 ¶m->u.crypt.key[24], 8);
112 padapter->securitypriv.binstallGrpkey = true;
113 r8712_set_key(padapter, &padapter->securitypriv, param->u.crypt.idx);
114 if (padapter->registrypriv.power_mgnt > PS_MODE_ACTIVE) {
115 if (padapter->registrypriv.power_mgnt != padapter->pwrctrlpriv.pwr_mode)
116 mod_timer(&padapter->mlmepriv.dhcp_timer,
117 jiffies + msecs_to_jiffies(60000));
122 static noinline_for_stack char *translate_scan_wpa(struct iw_request_info *info,
123 struct wlan_network *pnetwork,
124 struct iw_event *iwe,
125 char *start, char *stop)
127 /* parsing WPA/WPA2 IE */
128 u8 buf[MAX_WPA_IE_LEN];
129 u8 wpa_ie[255], rsn_ie[255];
130 u16 wpa_len = 0, rsn_len = 0;
133 r8712_get_sec_ie(pnetwork->network.IEs,
134 pnetwork->network.IELength, rsn_ie, &rsn_len,
137 memset(buf, 0, MAX_WPA_IE_LEN);
138 n = sprintf(buf, "wpa_ie=");
139 for (i = 0; i < wpa_len; i++) {
140 n += scnprintf(buf + n, MAX_WPA_IE_LEN - n,
142 if (n == MAX_WPA_IE_LEN - 1)
145 memset(iwe, 0, sizeof(*iwe));
146 iwe->cmd = IWEVCUSTOM;
147 iwe->u.data.length = (u16)strlen(buf);
148 start = iwe_stream_add_point(info, start, stop, iwe, buf);
149 memset(iwe, 0, sizeof(*iwe));
150 iwe->cmd = IWEVGENIE;
151 iwe->u.data.length = (u16)wpa_len;
152 start = iwe_stream_add_point(info, start, stop, iwe, wpa_ie);
155 memset(buf, 0, MAX_WPA_IE_LEN);
156 n = sprintf(buf, "rsn_ie=");
157 for (i = 0; i < rsn_len; i++) {
158 n += scnprintf(buf + n, MAX_WPA_IE_LEN - n,
160 if (n == MAX_WPA_IE_LEN - 1)
163 memset(iwe, 0, sizeof(*iwe));
164 iwe->cmd = IWEVCUSTOM;
165 iwe->u.data.length = strlen(buf);
166 start = iwe_stream_add_point(info, start, stop, iwe, buf);
167 memset(iwe, 0, sizeof(*iwe));
168 iwe->cmd = IWEVGENIE;
169 iwe->u.data.length = rsn_len;
170 start = iwe_stream_add_point(info, start, stop, iwe, rsn_ie);
176 static noinline_for_stack char *translate_scan_wps(struct iw_request_info *info,
177 struct wlan_network *pnetwork,
178 struct iw_event *iwe,
179 char *start, char *stop)
185 if (r8712_get_wps_ie(pnetwork->network.IEs, pnetwork->network.IELength, wps_ie, &wps_ielen)) {
187 iwe->cmd = IWEVGENIE;
188 iwe->u.data.length = (u16)wps_ielen;
189 start = iwe_stream_add_point(info, start, stop, iwe, wps_ie);
196 static char *translate_scan(struct _adapter *padapter,
197 struct iw_request_info *info,
198 struct wlan_network *pnetwork,
199 char *start, char *stop)
204 u32 i = 0, ht_ielen = 0;
205 u16 cap, ht_cap = false;
208 if ((pnetwork->network.Configuration.DSConfig < 1) ||
209 (pnetwork->network.Configuration.DSConfig > 14)) {
210 if (pnetwork->network.Configuration.DSConfig < 1)
211 pnetwork->network.Configuration.DSConfig = 1;
213 pnetwork->network.Configuration.DSConfig = 14;
217 iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
218 ether_addr_copy(iwe.u.ap_addr.sa_data, pnetwork->network.MacAddress);
219 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_ADDR_LEN);
221 iwe.cmd = SIOCGIWESSID;
222 iwe.u.data.flags = 1;
223 iwe.u.data.length = min_t(u32, pnetwork->network.Ssid.SsidLength, 32);
224 start = iwe_stream_add_point(info, start, stop, &iwe,
225 pnetwork->network.Ssid.Ssid);
226 /* parsing HT_CAP_IE */
227 p = r8712_get_ie(&pnetwork->network.IEs[12], WLAN_EID_HT_CAPABILITY,
228 &ht_ielen, pnetwork->network.IELength - 12);
229 if (p && ht_ielen > 0)
231 /* Add the protocol name */
232 iwe.cmd = SIOCGIWNAME;
233 if (r8712_is_cckratesonly_included(pnetwork->network.rates)) {
235 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bn");
237 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11b");
238 } else if (r8712_is_cckrates_included(pnetwork->network.rates)) {
240 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bgn");
242 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bg");
245 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11gn");
247 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11g");
249 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_CHAR_LEN);
251 iwe.cmd = SIOCGIWMODE;
252 memcpy((u8 *)&cap, r8712_get_capability_from_ie(pnetwork->network.IEs), 2);
254 if (cap & (WLAN_CAPABILITY_IBSS | WLAN_CAPABILITY_ESS)) {
255 if (cap & WLAN_CAPABILITY_ESS)
256 iwe.u.mode = (u32)IW_MODE_MASTER;
258 iwe.u.mode = (u32)IW_MODE_ADHOC;
259 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_UINT_LEN);
261 /* Add frequency/channel */
262 iwe.cmd = SIOCGIWFREQ;
264 /* check legal index */
265 u8 dsconfig = pnetwork->network.Configuration.DSConfig;
267 if (dsconfig >= 1 && dsconfig <= sizeof(ieee80211_wlan_frequencies) / sizeof(long))
268 iwe.u.freq.m = (s32)(ieee80211_wlan_frequencies[dsconfig - 1] * 100000);
272 iwe.u.freq.e = (s16)1;
273 iwe.u.freq.i = (u8)pnetwork->network.Configuration.DSConfig;
274 start = iwe_stream_add_event(info, start, stop, &iwe,
276 /* Add encryption capability */
277 iwe.cmd = SIOCGIWENCODE;
278 if (cap & WLAN_CAPABILITY_PRIVACY)
279 iwe.u.data.flags = (u16)(IW_ENCODE_ENABLED | IW_ENCODE_NOKEY);
281 iwe.u.data.flags = (u16)(IW_ENCODE_DISABLED);
282 iwe.u.data.length = (u16)0;
283 start = iwe_stream_add_point(info, start, stop, &iwe, pnetwork->network.Ssid.Ssid);
284 /*Add basic and extended rates */
285 current_val = start + iwe_stream_lcp_len(info);
286 iwe.cmd = SIOCGIWRATE;
287 iwe.u.bitrate.fixed = 0;
288 iwe.u.bitrate.disabled = 0;
289 iwe.u.bitrate.value = 0;
291 while (pnetwork->network.rates[i] != 0) {
292 /* Bit rate given in 500 kb/s units */
293 iwe.u.bitrate.value = (pnetwork->network.rates[i++] & 0x7F) * 500000;
294 current_val = iwe_stream_add_value(info, start, current_val, stop, &iwe,
297 /* Check if we added any event */
298 if ((current_val - start) > iwe_stream_lcp_len(info))
301 start = translate_scan_wpa(info, pnetwork, &iwe, start, stop);
303 start = translate_scan_wps(info, pnetwork, &iwe, start, stop);
305 /* Add quality statistics */
307 rssi = r8712_signal_scale_mapping(pnetwork->network.Rssi);
308 /* we only update signal_level (signal strength) that is rssi. */
309 iwe.u.qual.updated = (u8)(IW_QUAL_QUAL_INVALID | IW_QUAL_LEVEL_UPDATED | IW_QUAL_NOISE_INVALID);
310 iwe.u.qual.level = rssi; /* signal strength */
311 iwe.u.qual.qual = 0; /* signal quality */
312 iwe.u.qual.noise = 0; /* noise level */
313 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_QUAL_LEN);
314 /* how to translate rssi to ?% */
318 static int wpa_set_auth_algs(struct net_device *dev, u32 value)
320 struct _adapter *padapter = netdev_priv(dev);
323 if ((value & AUTH_ALG_SHARED_KEY) && (value & AUTH_ALG_OPEN_SYSTEM)) {
324 padapter->securitypriv.ndisencryptstatus =
325 Ndis802_11Encryption1Enabled;
326 padapter->securitypriv.ndisauthtype =
327 Ndis802_11AuthModeAutoSwitch;
328 padapter->securitypriv.AuthAlgrthm = 3;
329 } else if (value & AUTH_ALG_SHARED_KEY) {
330 padapter->securitypriv.ndisencryptstatus =
331 Ndis802_11Encryption1Enabled;
332 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeShared;
333 padapter->securitypriv.AuthAlgrthm = 1;
334 } else if (value & AUTH_ALG_OPEN_SYSTEM) {
335 if (padapter->securitypriv.ndisauthtype <
336 Ndis802_11AuthModeWPAPSK) {
337 padapter->securitypriv.ndisauthtype =
338 Ndis802_11AuthModeOpen;
339 padapter->securitypriv.AuthAlgrthm = 0;
347 static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param,
351 u32 wep_key_idx, wep_key_len = 0;
352 struct NDIS_802_11_WEP *pwep = NULL;
353 struct _adapter *padapter = netdev_priv(dev);
354 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
355 struct security_priv *psecuritypriv = &padapter->securitypriv;
357 param->u.crypt.err = 0;
358 param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
359 if (param_len != (u32)((u8 *) param->u.crypt.key - (u8 *)param) +
360 param->u.crypt.key_len)
362 if (!is_broadcast_ether_addr(param->sta_addr))
365 if (param->u.crypt.idx >= WEP_KEYS) {
366 /* for large key indices, set the default (0) */
367 param->u.crypt.idx = 0;
369 if (strcmp(param->u.crypt.alg, "WEP") == 0) {
370 netdev_info(dev, "r8712u: %s: crypt.alg = WEP\n", __func__);
371 padapter->securitypriv.ndisencryptstatus =
372 Ndis802_11Encryption1Enabled;
373 padapter->securitypriv.PrivacyAlgrthm = _WEP40_;
374 padapter->securitypriv.XGrpPrivacy = _WEP40_;
375 wep_key_idx = param->u.crypt.idx;
376 wep_key_len = param->u.crypt.key_len;
377 if (wep_key_idx >= WEP_KEYS)
379 if (wep_key_len <= 0)
382 wep_key_len = wep_key_len <= 5 ? 5 : 13;
383 pwep = kzalloc(sizeof(*pwep), GFP_ATOMIC);
386 pwep->KeyLength = wep_key_len;
387 pwep->Length = wep_key_len +
388 offsetof(struct NDIS_802_11_WEP, KeyMaterial);
389 if (wep_key_len == 13) {
390 padapter->securitypriv.PrivacyAlgrthm = _WEP104_;
391 padapter->securitypriv.XGrpPrivacy = _WEP104_;
393 pwep->KeyIndex = wep_key_idx;
394 pwep->KeyIndex |= 0x80000000;
395 memcpy(pwep->KeyMaterial, param->u.crypt.key, pwep->KeyLength);
396 if (param->u.crypt.set_tx) {
397 if (r8712_set_802_11_add_wep(padapter, pwep))
400 /* don't update "psecuritypriv->PrivacyAlgrthm" and
401 * "psecuritypriv->PrivacyKeyIndex=keyid", but can
402 * r8712_set_key to fw/cam
404 if (wep_key_idx >= WEP_KEYS) {
408 memcpy(&psecuritypriv->DefKey[wep_key_idx].skey[0],
411 psecuritypriv->DefKeylen[wep_key_idx] =
413 r8712_set_key(padapter, psecuritypriv, wep_key_idx);
417 if (padapter->securitypriv.AuthAlgrthm == 2) { /* 802_1x */
418 struct sta_info *psta, *pbcmc_sta;
419 struct sta_priv *pstapriv = &padapter->stapriv;
420 struct security_priv *spriv = &padapter->securitypriv;
422 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE |
423 WIFI_MP_STATE)) { /* sta mode */
424 psta = r8712_get_stainfo(pstapriv,
425 get_bssid(pmlmepriv));
427 psta->ieee8021x_blocked = false;
428 if (spriv->ndisencryptstatus ==
429 Ndis802_11Encryption2Enabled ||
430 spriv->ndisencryptstatus ==
431 Ndis802_11Encryption3Enabled)
432 psta->XPrivacy = spriv->PrivacyAlgrthm;
433 if (param->u.crypt.set_tx == 1)
434 handle_pairwise_key(psta, param,
437 handle_group_key(param, padapter);
439 pbcmc_sta = r8712_get_bcmc_stainfo(padapter);
441 pbcmc_sta->ieee8021x_blocked = false;
442 if (spriv->ndisencryptstatus ==
443 Ndis802_11Encryption2Enabled ||
444 spriv->ndisencryptstatus ==
445 Ndis802_11Encryption3Enabled)
446 pbcmc_sta->XPrivacy =
447 spriv->PrivacyAlgrthm;
456 static int r871x_set_wpa_ie(struct _adapter *padapter, char *pie,
457 unsigned short ielen)
460 int group_cipher = 0, pairwise_cipher = 0;
463 if (ielen > MAX_WPA_IE_LEN || !pie)
466 buf = kmemdup(pie, ielen, GFP_ATOMIC);
469 if (ielen < RSN_HEADER_LEN) {
473 if (r8712_parse_wpa_ie(buf, ielen, &group_cipher,
474 &pairwise_cipher) == 0) {
475 padapter->securitypriv.AuthAlgrthm = 2;
476 padapter->securitypriv.ndisauthtype =
477 Ndis802_11AuthModeWPAPSK;
479 if (r8712_parse_wpa2_ie(buf, ielen, &group_cipher,
480 &pairwise_cipher) == 0) {
481 padapter->securitypriv.AuthAlgrthm = 2;
482 padapter->securitypriv.ndisauthtype =
483 Ndis802_11AuthModeWPA2PSK;
485 switch (group_cipher) {
486 case WPA_CIPHER_NONE:
487 padapter->securitypriv.XGrpPrivacy = _NO_PRIVACY_;
488 padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled;
490 case WPA_CIPHER_WEP40:
491 padapter->securitypriv.XGrpPrivacy = _WEP40_;
492 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
494 case WPA_CIPHER_TKIP:
495 padapter->securitypriv.XGrpPrivacy = _TKIP_;
496 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled;
498 case WPA_CIPHER_CCMP:
499 padapter->securitypriv.XGrpPrivacy = _AES_;
500 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled;
502 case WPA_CIPHER_WEP104:
503 padapter->securitypriv.XGrpPrivacy = _WEP104_;
504 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
507 switch (pairwise_cipher) {
508 case WPA_CIPHER_NONE:
509 padapter->securitypriv.PrivacyAlgrthm = _NO_PRIVACY_;
510 padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled;
512 case WPA_CIPHER_WEP40:
513 padapter->securitypriv.PrivacyAlgrthm = _WEP40_;
514 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
516 case WPA_CIPHER_TKIP:
517 padapter->securitypriv.PrivacyAlgrthm = _TKIP_;
518 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled;
520 case WPA_CIPHER_CCMP:
521 padapter->securitypriv.PrivacyAlgrthm = _AES_;
522 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled;
524 case WPA_CIPHER_WEP104:
525 padapter->securitypriv.PrivacyAlgrthm = _WEP104_;
526 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
529 padapter->securitypriv.wps_phase = false;
532 u8 eid, wps_oui[4] = {0x0, 0x50, 0xf2, 0x04};
534 while (cnt < ielen) {
537 if ((eid == WLAN_EID_VENDOR_SPECIFIC) &&
538 (!memcmp(&buf[cnt + 2], wps_oui, 4))) {
539 netdev_info(padapter->pnetdev, "r8712u: SET WPS_IE\n");
540 padapter->securitypriv.wps_ie_len =
541 ((buf[cnt + 1] + 2) <
542 (MAX_WPA_IE_LEN << 2)) ?
544 (MAX_WPA_IE_LEN << 2);
545 memcpy(padapter->securitypriv.wps_ie,
547 padapter->securitypriv.wps_ie_len);
548 padapter->securitypriv.wps_phase =
550 netdev_info(padapter->pnetdev, "r8712u: SET WPS_IE, wps_phase==true\n");
551 cnt += buf[cnt + 1] + 2;
555 cnt += buf[cnt + 1] + 2;
564 static int r8711_wx_get_name(struct net_device *dev, struct iw_request_info *info,
565 union iwreq_data *wrqu, char *extra)
567 struct _adapter *padapter = netdev_priv(dev);
571 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
572 struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
575 if (check_fwstate(pmlmepriv, _FW_LINKED | WIFI_ADHOC_MASTER_STATE) == true) {
576 /* parsing HT_CAP_IE */
577 p = r8712_get_ie(&pcur_bss->IEs[12], WLAN_EID_HT_CAPABILITY,
578 &ht_ielen, pcur_bss->IELength - 12);
579 if (p && ht_ielen > 0)
581 prates = pcur_bss->rates;
582 if (r8712_is_cckratesonly_included(prates)) {
584 snprintf(wrqu->name, IFNAMSIZ,
587 snprintf(wrqu->name, IFNAMSIZ,
589 } else if (r8712_is_cckrates_included(prates)) {
591 snprintf(wrqu->name, IFNAMSIZ,
594 snprintf(wrqu->name, IFNAMSIZ,
598 snprintf(wrqu->name, IFNAMSIZ,
601 snprintf(wrqu->name, IFNAMSIZ,
605 snprintf(wrqu->name, IFNAMSIZ, "unassociated");
610 static const long frequency_list[] = {
611 2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447, 2452, 2457, 2462,
612 2467, 2472, 2484, 4915, 4920, 4925, 4935, 4940, 4945, 4960, 4980,
613 5035, 5040, 5045, 5055, 5060, 5080, 5170, 5180, 5190, 5200, 5210,
614 5220, 5230, 5240, 5260, 5280, 5300, 5320, 5500, 5520, 5540, 5560,
615 5580, 5600, 5620, 5640, 5660, 5680, 5700, 5745, 5765, 5785, 5805,
619 static int r8711_wx_set_freq(struct net_device *dev,
620 struct iw_request_info *info,
621 union iwreq_data *wrqu, char *extra)
623 struct _adapter *padapter = netdev_priv(dev);
624 struct iw_freq *fwrq = &wrqu->freq;
627 /* If setting by frequency, convert to a channel */
628 if ((fwrq->e == 1) && (fwrq->m >= 241200000) && (fwrq->m <= 248700000)) {
629 int f = fwrq->m / 100000;
632 while ((c < 14) && (f != frequency_list[c]))
637 /* Setting by channel number */
638 if ((fwrq->m > 14) || (fwrq->e > 0)) {
641 int channel = fwrq->m;
643 if ((channel < 1) || (channel > 14)) {
646 /* Yes ! We can set it !!! */
647 padapter->registrypriv.channel = channel;
653 static int r8711_wx_get_freq(struct net_device *dev, struct iw_request_info *info,
654 union iwreq_data *wrqu, char *extra)
656 struct _adapter *padapter = netdev_priv(dev);
657 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
658 struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
660 if (!check_fwstate(pmlmepriv, _FW_LINKED))
663 wrqu->freq.m = ieee80211_wlan_frequencies[
664 pcur_bss->Configuration.DSConfig - 1] * 100000;
666 wrqu->freq.i = pcur_bss->Configuration.DSConfig;
671 static int r8711_wx_set_mode(struct net_device *dev,
672 struct iw_request_info *a,
673 union iwreq_data *wrqu, char *b)
675 struct _adapter *padapter = netdev_priv(dev);
676 enum NDIS_802_11_NETWORK_INFRASTRUCTURE networkType;
678 switch (wrqu->mode) {
680 networkType = Ndis802_11AutoUnknown;
683 networkType = Ndis802_11IBSS;
686 networkType = Ndis802_11APMode;
689 networkType = Ndis802_11Infrastructure;
694 if (Ndis802_11APMode == networkType)
695 r8712_setopmode_cmd(padapter, networkType);
697 r8712_setopmode_cmd(padapter, Ndis802_11AutoUnknown);
699 r8712_set_802_11_infrastructure_mode(padapter, networkType);
703 static int r8711_wx_get_mode(struct net_device *dev, struct iw_request_info *a,
704 union iwreq_data *wrqu, char *b)
706 struct _adapter *padapter = netdev_priv(dev);
707 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
709 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE))
710 wrqu->mode = IW_MODE_INFRA;
711 else if (check_fwstate(pmlmepriv,
712 WIFI_ADHOC_MASTER_STATE | WIFI_ADHOC_STATE))
713 wrqu->mode = IW_MODE_ADHOC;
714 else if (check_fwstate(pmlmepriv, WIFI_AP_STATE))
715 wrqu->mode = IW_MODE_MASTER;
717 wrqu->mode = IW_MODE_AUTO;
721 static int r871x_wx_set_pmkid(struct net_device *dev, struct iw_request_info *a,
722 union iwreq_data *wrqu, char *extra)
724 struct _adapter *padapter = netdev_priv(dev);
725 struct security_priv *psecuritypriv = &padapter->securitypriv;
726 struct iw_pmksa *pPMK = (struct iw_pmksa *) extra;
727 struct RT_PMKID_LIST *pl = psecuritypriv->PMKIDList;
728 u8 strZeroMacAddress[ETH_ALEN] = {0x00};
729 u8 strIssueBssid[ETH_ALEN] = {0x00};
730 u8 j, blInserted = false;
731 int intReturn = false;
734 * There are the BSSID information in the bssid.sa_data array.
735 * If cmd is IW_PMKSA_FLUSH, it means the wpa_supplicant wants to clear
736 * all the PMKID information. If cmd is IW_PMKSA_ADD, it means the
737 * wpa_supplicant wants to add a PMKID/BSSID to driver.
738 * If cmd is IW_PMKSA_REMOVE, it means the wpa_supplicant wants to
739 * remove a PMKID/BSSID from driver.
743 memcpy(strIssueBssid, pPMK->bssid.sa_data, ETH_ALEN);
746 if (!memcmp(strIssueBssid, strZeroMacAddress, ETH_ALEN))
750 /* overwrite PMKID */
751 for (j = 0; j < NUM_PMKID_CACHE; j++) {
752 if (!memcmp(pl[j].Bssid, strIssueBssid, ETH_ALEN)) {
753 /* BSSID is matched, the same AP => rewrite
756 netdev_info(dev, "r8712u: %s: BSSID exists in the PMKList.\n",
758 memcpy(pl[j].PMKID, pPMK->pmkid, IW_PMKID_LEN);
760 psecuritypriv->PMKIDIndex = j + 1;
766 /* Find a new entry */
767 netdev_info(dev, "r8712u: %s: Use the new entry index = %d for this PMKID.\n",
768 __func__, psecuritypriv->PMKIDIndex);
769 memcpy(pl[psecuritypriv->PMKIDIndex].Bssid,
770 strIssueBssid, ETH_ALEN);
771 memcpy(pl[psecuritypriv->PMKIDIndex].PMKID,
772 pPMK->pmkid, IW_PMKID_LEN);
773 pl[psecuritypriv->PMKIDIndex].bUsed = true;
774 psecuritypriv->PMKIDIndex++;
775 if (psecuritypriv->PMKIDIndex == NUM_PMKID_CACHE)
776 psecuritypriv->PMKIDIndex = 0;
779 case IW_PMKSA_REMOVE:
781 for (j = 0; j < NUM_PMKID_CACHE; j++) {
782 if (!memcmp(pl[j].Bssid, strIssueBssid, ETH_ALEN)) {
783 /* BSSID is matched, the same AP => Remove
784 * this PMKID information and reset it.
786 eth_zero_addr(pl[j].Bssid);
793 memset(psecuritypriv->PMKIDList, 0,
794 sizeof(struct RT_PMKID_LIST) * NUM_PMKID_CACHE);
795 psecuritypriv->PMKIDIndex = 0;
799 netdev_info(dev, "r8712u: %s: unknown Command\n", __func__);
806 static int r8711_wx_get_sens(struct net_device *dev,
807 struct iw_request_info *info,
808 union iwreq_data *wrqu, char *extra)
810 wrqu->sens.value = 0;
811 wrqu->sens.fixed = 0; /* no auto select */
812 wrqu->sens.disabled = 1;
816 static int r8711_wx_get_range(struct net_device *dev, struct iw_request_info *info,
817 union iwreq_data *wrqu, char *extra)
819 struct iw_range *range = (struct iw_range *)extra;
823 wrqu->data.length = sizeof(*range);
824 memset(range, 0, sizeof(*range));
825 /* Let's try to keep this struct in the same order as in
826 * linux/include/wireless.h
829 /* TODO: See what values we can set, and remove the ones we can't
830 * set, or fill them with some default data.
832 /* ~5 Mb/s real (802.11b) */
833 range->throughput = 5 * 1000 * 1000;
834 /* TODO: 8711 sensitivity ? */
835 /* signal level threshold range */
836 /* percent values between 0 and 100. */
837 range->max_qual.qual = 100;
838 range->max_qual.level = 100;
839 range->max_qual.noise = 100;
840 range->max_qual.updated = 7; /* Updated all three */
841 range->avg_qual.qual = 92; /* > 8% missed beacons is 'bad' */
842 /* TODO: Find real 'good' to 'bad' threshold value for RSSI */
843 range->avg_qual.level = 0x100 - 78;
844 range->avg_qual.noise = 0;
845 range->avg_qual.updated = 7; /* Updated all three */
846 range->num_bitrates = RATE_COUNT;
847 for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++)
848 range->bitrate[i] = rtl8180_rates[i];
849 range->min_frag = MIN_FRAG_THRESHOLD;
850 range->max_frag = MAX_FRAG_THRESHOLD;
852 range->we_version_compiled = WIRELESS_EXT;
853 range->we_version_source = 16;
854 range->num_channels = 14;
855 for (i = 0, val = 0; i < 14; i++) {
856 /* Include only legal frequencies for some countries */
857 range->freq[val].i = i + 1;
858 range->freq[val].m = ieee80211_wlan_frequencies[i] * 100000;
859 range->freq[val].e = 1;
861 if (val == IW_MAX_FREQUENCIES)
864 range->num_frequency = val;
865 range->enc_capa = IW_ENC_CAPA_WPA |
867 IW_ENC_CAPA_CIPHER_TKIP |
868 IW_ENC_CAPA_CIPHER_CCMP;
872 static int r8711_wx_get_rate(struct net_device *dev,
873 struct iw_request_info *info,
874 union iwreq_data *wrqu, char *extra);
876 static int r871x_wx_set_priv(struct net_device *dev,
877 struct iw_request_info *info,
878 union iwreq_data *awrq,
881 int ret = 0, len = 0;
883 struct _adapter *padapter = netdev_priv(dev);
884 struct iw_point *dwrq = (struct iw_point *)awrq;
887 ext = strndup_user(dwrq->pointer, len);
891 if (!strcasecmp(ext, "RSSI")) {
892 /*Return received signal strength indicator in -db for */
895 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
896 struct wlan_network *pcur_network = &pmlmepriv->cur_network;
898 if (check_fwstate(pmlmepriv, _FW_LINKED)) {
899 sprintf(ext, "%s rssi %d",
900 pcur_network->network.Ssid.Ssid,
902 ((padapter->recvpriv.fw_rssi) >> 1) - 95
903 /*pcur_network->network.Rssi */
908 } else if (!strcasecmp(ext, "LINKSPEED")) {
909 /*Return link speed in MBPS */
911 union iwreq_data wrqd;
915 ret_inner = r8711_wx_get_rate(dev, info, &wrqd, extra);
919 mbps = wrqd.bitrate.value / 1000000;
920 sprintf(ext, "LINKSPEED %d", mbps);
921 } else if (!strcasecmp(ext, "MACADDR")) {
922 /*Return mac address of the station */
923 /* Macaddr = xx:xx:xx:xx:xx:xx */
924 sprintf(ext, "MACADDR = %pM", dev->dev_addr);
925 } else if (!strcasecmp(ext, "SCAN-ACTIVE")) {
926 /*Set scan type to active */
927 /*OK if successful */
928 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
930 pmlmepriv->passive_mode = 1;
932 } else if (!strcasecmp(ext, "SCAN-PASSIVE")) {
933 /*Set scan type to passive */
934 /*OK if successful */
935 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
937 pmlmepriv->passive_mode = 0;
939 } else if (!strncmp(ext, "DCE-E", 5)) {
940 /*Set scan type to passive */
941 /*OK if successful */
942 r8712_disconnectCtrlEx_cmd(padapter
943 , 1 /*u32 enableDrvCtrl */
944 , 5 /*u32 tryPktCnt */
945 , 100 /*u32 tryPktInterval */
946 , 5000 /*u32 firstStageTO */
949 } else if (!strncmp(ext, "DCE-D", 5)) {
950 /*Set scan type to passive */
952 r8712_disconnectCtrlEx_cmd(padapter
953 , 0 /*u32 enableDrvCtrl */
954 , 5 /*u32 tryPktCnt */
955 , 100 /*u32 tryPktInterval */
956 , 5000 /*u32 firstStageTO */
960 netdev_info(dev, "r8712u: %s: unknown Command %s.\n", __func__, ext);
963 if (copy_to_user(dwrq->pointer, ext, min(dwrq->length, (__u16)(strlen(ext) + 1))))
972 * s1. set_802_11_infrastructure_mode()
973 * s2. set_802_11_authentication_mode()
974 * s3. set_802_11_encryption_mode()
975 * s4. set_802_11_bssid()
977 * This function intends to handle the Set AP command, which specifies the
978 * MAC# of a preferred Access Point.
979 * Currently, the request comes via Wireless Extensions' SIOCSIWAP ioctl.
981 * For this operation to succeed, there is no need for the interface to be up.
984 static int r8711_wx_set_wap(struct net_device *dev, struct iw_request_info *info,
985 union iwreq_data *awrq, char *extra)
987 int ret = -EINPROGRESS;
988 struct _adapter *padapter = netdev_priv(dev);
989 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
990 struct __queue *queue = &pmlmepriv->scanned_queue;
991 struct sockaddr *temp = (struct sockaddr *)awrq;
993 struct list_head *phead;
995 struct wlan_network *pnetwork = NULL;
996 enum NDIS_802_11_AUTHENTICATION_MODE authmode;
998 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY))
1000 if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING))
1002 if (temp->sa_family != ARPHRD_ETHER)
1004 authmode = padapter->securitypriv.ndisauthtype;
1005 spin_lock_irqsave(&queue->lock, irqL);
1006 phead = &queue->queue;
1007 pmlmepriv->pscanned = phead->next;
1009 if (end_of_queue_search(phead, pmlmepriv->pscanned))
1011 pnetwork = container_of(pmlmepriv->pscanned,
1012 struct wlan_network, list);
1013 pmlmepriv->pscanned = pmlmepriv->pscanned->next;
1014 dst_bssid = pnetwork->network.MacAddress;
1015 if (!memcmp(dst_bssid, temp->sa_data, ETH_ALEN)) {
1016 r8712_set_802_11_infrastructure_mode(padapter,
1017 pnetwork->network.InfrastructureMode);
1021 spin_unlock_irqrestore(&queue->lock, irqL);
1023 if (!r8712_set_802_11_authentication_mode(padapter, authmode)) {
1026 if (!r8712_set_802_11_bssid(padapter, temp->sa_data))
1033 static int r8711_wx_get_wap(struct net_device *dev, struct iw_request_info *info,
1034 union iwreq_data *wrqu, char *extra)
1036 struct _adapter *padapter = netdev_priv(dev);
1037 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1038 struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
1040 wrqu->ap_addr.sa_family = ARPHRD_ETHER;
1041 if (check_fwstate(pmlmepriv, _FW_LINKED | WIFI_ADHOC_MASTER_STATE | WIFI_AP_STATE))
1042 ether_addr_copy(wrqu->ap_addr.sa_data, pcur_bss->MacAddress);
1044 eth_zero_addr(wrqu->ap_addr.sa_data);
1048 static int r871x_wx_set_mlme(struct net_device *dev,
1049 struct iw_request_info *info,
1050 union iwreq_data *wrqu, char *extra)
1053 struct _adapter *padapter = netdev_priv(dev);
1054 struct iw_mlme *mlme = (struct iw_mlme *) extra;
1058 switch (mlme->cmd) {
1059 case IW_MLME_DEAUTH:
1060 if (!r8712_set_802_11_disassociate(padapter))
1063 case IW_MLME_DISASSOC:
1064 if (!r8712_set_802_11_disassociate(padapter))
1075 * This function intends to handle the Set Scan command.
1076 * Currently, the request comes via Wireless Extensions' SIOCSIWSCAN ioctl.
1078 * For this operation to succeed, the interface is brought Up beforehand.
1081 static int r8711_wx_set_scan(struct net_device *dev, struct iw_request_info *a,
1082 union iwreq_data *wrqu, char *extra)
1084 struct _adapter *padapter = netdev_priv(dev);
1085 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1088 if (padapter->driver_stopped) {
1089 netdev_info(dev, "In %s: driver_stopped=%d\n",
1090 __func__, padapter->driver_stopped);
1095 if (!padapter->hw_init_completed)
1097 if ((check_fwstate(pmlmepriv, _FW_UNDER_SURVEY | _FW_UNDER_LINKING)) ||
1098 (pmlmepriv->sitesurveyctrl.traffic_busy))
1100 if (wrqu->data.length == sizeof(struct iw_scan_req)) {
1101 struct iw_scan_req *req = (struct iw_scan_req *)extra;
1103 if (wrqu->data.flags & IW_SCAN_THIS_ESSID) {
1104 struct ndis_802_11_ssid ssid;
1106 u32 len = min_t(u8, req->essid_len, IW_ESSID_MAX_SIZE);
1108 memset((unsigned char *)&ssid, 0, sizeof(struct ndis_802_11_ssid));
1109 memcpy(ssid.Ssid, req->essid, len);
1110 ssid.SsidLength = len;
1111 spin_lock_irqsave(&pmlmepriv->lock, irqL);
1112 if ((check_fwstate(pmlmepriv, _FW_UNDER_SURVEY |
1113 _FW_UNDER_LINKING)) ||
1114 (pmlmepriv->sitesurveyctrl.traffic_busy)) {
1115 if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING))
1118 status = r8712_sitesurvey_cmd(padapter, &ssid);
1120 spin_unlock_irqrestore(&pmlmepriv->lock, irqL);
1123 status = r8712_set_802_11_bssid_list_scan(padapter);
1130 static int r8711_wx_get_scan(struct net_device *dev, struct iw_request_info *a,
1131 union iwreq_data *wrqu, char *extra)
1133 struct _adapter *padapter = netdev_priv(dev);
1134 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1135 struct __queue *queue = &pmlmepriv->scanned_queue;
1136 struct wlan_network *pnetwork = NULL;
1138 struct list_head *plist, *phead;
1140 char *stop = ev + wrqu->data.length;
1141 u32 ret = 0, cnt = 0;
1143 if (padapter->driver_stopped)
1145 while (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY | _FW_UNDER_LINKING)) {
1151 spin_lock_irqsave(&queue->lock, irqL);
1152 phead = &queue->queue;
1153 plist = phead->next;
1155 if (end_of_queue_search(phead, plist))
1157 if ((stop - ev) < SCAN_ITEM_SIZE) {
1161 pnetwork = container_of(plist, struct wlan_network, list);
1162 ev = translate_scan(padapter, a, pnetwork, ev, stop);
1163 plist = plist->next;
1165 spin_unlock_irqrestore(&queue->lock, irqL);
1166 wrqu->data.length = ev - extra;
1167 wrqu->data.flags = 0;
1172 * s1. set_802_11_infrastructure_mode()
1173 * s2. set_802_11_authenticaion_mode()
1174 * s3. set_802_11_encryption_mode()
1175 * s4. set_802_11_ssid()
1177 * This function intends to handle the Set ESSID command.
1178 * Currently, the request comes via the Wireless Extensions' SIOCSIWESSID ioctl.
1180 * For this operation to succeed, there is no need for the interface to be Up.
1183 static int r8711_wx_set_essid(struct net_device *dev, 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;
1190 enum NDIS_802_11_AUTHENTICATION_MODE authmode;
1191 struct ndis_802_11_ssid ndis_ssid;
1192 u8 *dst_ssid, *src_ssid;
1193 struct list_head *phead;
1196 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY))
1198 if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING))
1200 if (wrqu->essid.length > IW_ESSID_MAX_SIZE)
1202 authmode = padapter->securitypriv.ndisauthtype;
1203 if (wrqu->essid.flags && wrqu->essid.length) {
1204 len = (wrqu->essid.length < IW_ESSID_MAX_SIZE) ?
1205 wrqu->essid.length : IW_ESSID_MAX_SIZE;
1206 memset(&ndis_ssid, 0, sizeof(struct ndis_802_11_ssid));
1207 ndis_ssid.SsidLength = len;
1208 memcpy(ndis_ssid.Ssid, extra, len);
1209 src_ssid = ndis_ssid.Ssid;
1210 phead = &queue->queue;
1211 pmlmepriv->pscanned = phead->next;
1213 if (end_of_queue_search(phead, pmlmepriv->pscanned))
1215 pnetwork = container_of(pmlmepriv->pscanned,
1216 struct wlan_network, list);
1217 pmlmepriv->pscanned = pmlmepriv->pscanned->next;
1218 dst_ssid = pnetwork->network.Ssid.Ssid;
1219 if ((!memcmp(dst_ssid, src_ssid, ndis_ssid.SsidLength))
1220 && (pnetwork->network.Ssid.SsidLength ==
1221 ndis_ssid.SsidLength)) {
1222 if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) {
1223 if (pnetwork->network.
1227 cur_network.network.
1232 r8712_set_802_11_infrastructure_mode(
1234 pnetwork->network.InfrastructureMode);
1238 r8712_set_802_11_authentication_mode(padapter, authmode);
1239 r8712_set_802_11_ssid(padapter, &ndis_ssid);
1241 return -EINPROGRESS;
1244 static int r8711_wx_get_essid(struct net_device *dev, struct iw_request_info *a,
1245 union iwreq_data *wrqu, char *extra)
1247 struct _adapter *padapter = netdev_priv(dev);
1248 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1249 struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
1252 if (check_fwstate(pmlmepriv, _FW_LINKED | WIFI_ADHOC_MASTER_STATE)) {
1253 len = pcur_bss->Ssid.SsidLength;
1254 wrqu->essid.length = len;
1255 memcpy(extra, pcur_bss->Ssid.Ssid, len);
1256 wrqu->essid.flags = 1;
1263 static int r8711_wx_set_rate(struct net_device *dev, struct iw_request_info *a,
1264 union iwreq_data *wrqu, char *extra)
1266 struct _adapter *padapter = netdev_priv(dev);
1267 u32 target_rate = wrqu->bitrate.value;
1268 u32 fixed = wrqu->bitrate.fixed;
1270 u8 datarates[NumRates];
1271 u8 mpdatarate[NumRates] = {11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0xff};
1274 if (target_rate == -1) {
1278 target_rate = target_rate / 100000;
1279 switch (target_rate) {
1321 for (i = 0; i < NumRates; i++) {
1322 if (ratevalue == mpdatarate[i]) {
1323 datarates[i] = mpdatarate[i];
1327 datarates[i] = 0xff;
1330 return r8712_setdatarate_cmd(padapter, datarates);
1333 static int r8711_wx_get_rate(struct net_device *dev, struct iw_request_info *info,
1334 union iwreq_data *wrqu, char *extra)
1336 struct _adapter *padapter = netdev_priv(dev);
1337 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1338 struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
1339 struct ieee80211_ht_cap *pht_capie;
1340 unsigned char rf_type = padapter->registrypriv.rf_config;
1343 u16 rate, max_rate = 0, ht_cap = false;
1345 u8 bw_40MHz = 0, short_GI = 0;
1349 if (!check_fwstate(pmlmepriv, _FW_LINKED | WIFI_ADHOC_MASTER_STATE))
1351 p = r8712_get_ie(&pcur_bss->IEs[12], WLAN_EID_HT_CAPABILITY, &ht_ielen,
1352 pcur_bss->IELength - 12);
1353 if (p && ht_ielen > 0) {
1355 pht_capie = (struct ieee80211_ht_cap *)(p + 2);
1356 memcpy(&mcs_rate, &pht_capie->mcs, 2);
1357 bw_40MHz = (le16_to_cpu(pht_capie->cap_info) &
1358 IEEE80211_HT_CAP_SUP_WIDTH_20_40) ? 1 : 0;
1359 short_GI = (le16_to_cpu(pht_capie->cap_info) &
1360 (IEEE80211_HT_CAP_SGI_20 |
1361 IEEE80211_HT_CAP_SGI_40)) ? 1 : 0;
1363 while ((pcur_bss->rates[i] != 0) &&
1364 (pcur_bss->rates[i] != 0xFF)) {
1365 rate = pcur_bss->rates[i] & 0x7F;
1366 if (rate > max_rate)
1368 wrqu->bitrate.fixed = 0; /* no auto select */
1369 wrqu->bitrate.value = rate * 500000;
1373 if (mcs_rate & 0x8000 /* MCS15 */
1375 rf_type == RTL8712_RF_2T2R)
1376 max_rate = (bw_40MHz) ? ((short_GI) ? 300 : 270) :
1377 ((short_GI) ? 144 : 130);
1378 else /* default MCS7 */
1379 max_rate = (bw_40MHz) ? ((short_GI) ? 150 : 135) :
1380 ((short_GI) ? 72 : 65);
1381 max_rate *= 2; /* Mbps/2 */
1383 wrqu->bitrate.value = max_rate * 500000;
1387 static int r8711_wx_get_rts(struct net_device *dev, struct iw_request_info *info,
1388 union iwreq_data *wrqu, char *extra)
1390 struct _adapter *padapter = netdev_priv(dev);
1392 wrqu->rts.value = padapter->registrypriv.rts_thresh;
1393 wrqu->rts.fixed = 0; /* no auto select */
1397 static int r8711_wx_set_frag(struct net_device *dev, struct iw_request_info *info,
1398 union iwreq_data *wrqu, char *extra)
1400 struct _adapter *padapter = netdev_priv(dev);
1402 if (wrqu->frag.disabled) {
1403 padapter->xmitpriv.frag_len = MAX_FRAG_THRESHOLD;
1405 if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
1406 wrqu->frag.value > MAX_FRAG_THRESHOLD)
1408 padapter->xmitpriv.frag_len = wrqu->frag.value & ~0x1;
1413 static int r8711_wx_get_frag(struct net_device *dev,
1414 struct iw_request_info *info,
1415 union iwreq_data *wrqu, char *extra)
1417 struct _adapter *padapter = netdev_priv(dev);
1419 wrqu->frag.value = padapter->xmitpriv.frag_len;
1420 wrqu->frag.fixed = 0; /* no auto select */
1424 static int r8711_wx_get_retry(struct net_device *dev,
1425 struct iw_request_info *info,
1426 union iwreq_data *wrqu, char *extra)
1428 wrqu->retry.value = 7;
1429 wrqu->retry.fixed = 0; /* no auto select */
1430 wrqu->retry.disabled = 1;
1434 static int r8711_wx_set_enc(struct net_device *dev,
1435 struct iw_request_info *info,
1436 union iwreq_data *wrqu, char *keybuf)
1439 u32 keyindex_provided;
1440 struct NDIS_802_11_WEP wep;
1441 enum NDIS_802_11_AUTHENTICATION_MODE authmode;
1442 struct iw_point *erq = &wrqu->encoding;
1443 struct _adapter *padapter = netdev_priv(dev);
1445 key = erq->flags & IW_ENCODE_INDEX;
1446 memset(&wep, 0, sizeof(struct NDIS_802_11_WEP));
1447 if (erq->flags & IW_ENCODE_DISABLED) {
1448 netdev_info(dev, "r8712u: %s: EncryptionDisabled\n", __func__);
1449 padapter->securitypriv.ndisencryptstatus =
1450 Ndis802_11EncryptionDisabled;
1451 padapter->securitypriv.PrivacyAlgrthm = _NO_PRIVACY_;
1452 padapter->securitypriv.XGrpPrivacy = _NO_PRIVACY_;
1453 padapter->securitypriv.AuthAlgrthm = 0; /* open system */
1454 authmode = Ndis802_11AuthModeOpen;
1455 padapter->securitypriv.ndisauthtype = authmode;
1462 keyindex_provided = 1;
1464 keyindex_provided = 0;
1465 key = padapter->securitypriv.PrivacyKeyIndex;
1467 /* set authentication mode */
1468 if (erq->flags & IW_ENCODE_OPEN) {
1469 netdev_info(dev, "r8712u: %s: IW_ENCODE_OPEN\n", __func__);
1470 padapter->securitypriv.ndisencryptstatus =
1471 Ndis802_11Encryption1Enabled;
1472 padapter->securitypriv.AuthAlgrthm = 0; /* open system */
1473 padapter->securitypriv.PrivacyAlgrthm = _NO_PRIVACY_;
1474 padapter->securitypriv.XGrpPrivacy = _NO_PRIVACY_;
1475 authmode = Ndis802_11AuthModeOpen;
1476 padapter->securitypriv.ndisauthtype = authmode;
1477 } else if (erq->flags & IW_ENCODE_RESTRICTED) {
1479 "r8712u: %s: IW_ENCODE_RESTRICTED\n", __func__);
1480 padapter->securitypriv.ndisencryptstatus =
1481 Ndis802_11Encryption1Enabled;
1482 padapter->securitypriv.AuthAlgrthm = 1; /* shared system */
1483 padapter->securitypriv.PrivacyAlgrthm = _WEP40_;
1484 padapter->securitypriv.XGrpPrivacy = _WEP40_;
1485 authmode = Ndis802_11AuthModeShared;
1486 padapter->securitypriv.ndisauthtype = authmode;
1488 padapter->securitypriv.ndisencryptstatus =
1489 Ndis802_11Encryption1Enabled;
1490 padapter->securitypriv.AuthAlgrthm = 0; /* open system */
1491 padapter->securitypriv.PrivacyAlgrthm = _NO_PRIVACY_;
1492 padapter->securitypriv.XGrpPrivacy = _NO_PRIVACY_;
1493 authmode = Ndis802_11AuthModeOpen;
1494 padapter->securitypriv.ndisauthtype = authmode;
1497 if (erq->length > 0) {
1498 wep.KeyLength = erq->length <= 5 ? 5 : 13;
1499 wep.Length = wep.KeyLength +
1500 offsetof(struct NDIS_802_11_WEP, KeyMaterial);
1503 if (keyindex_provided == 1) { /* set key_id only, no given
1504 * KeyMaterial(erq->length==0).
1506 padapter->securitypriv.PrivacyKeyIndex = key;
1507 switch (padapter->securitypriv.DefKeylen[key]) {
1509 padapter->securitypriv.PrivacyAlgrthm =
1513 padapter->securitypriv.PrivacyAlgrthm =
1517 padapter->securitypriv.PrivacyAlgrthm =
1524 wep.KeyIndex |= 0x80000000; /* transmit key */
1525 memcpy(wep.KeyMaterial, keybuf, wep.KeyLength);
1526 if (r8712_set_802_11_add_wep(padapter, &wep))
1531 static int r8711_wx_get_enc(struct net_device *dev,
1532 struct iw_request_info *info,
1533 union iwreq_data *wrqu, char *keybuf)
1536 struct _adapter *padapter = netdev_priv(dev);
1537 struct iw_point *erq = &wrqu->encoding;
1538 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1539 union Keytype *dk = padapter->securitypriv.DefKey;
1541 if (!check_fwstate(pmlmepriv, _FW_LINKED)) {
1542 if (!check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) {
1544 erq->flags |= IW_ENCODE_DISABLED;
1548 key = erq->flags & IW_ENCODE_INDEX;
1554 key = padapter->securitypriv.PrivacyKeyIndex;
1556 erq->flags = key + 1;
1557 switch (padapter->securitypriv.ndisencryptstatus) {
1558 case Ndis802_11EncryptionNotSupported:
1559 case Ndis802_11EncryptionDisabled:
1561 erq->flags |= IW_ENCODE_DISABLED;
1563 case Ndis802_11Encryption1Enabled:
1564 erq->length = padapter->securitypriv.DefKeylen[key];
1566 memcpy(keybuf, dk[key].skey,
1567 padapter->securitypriv.DefKeylen[key]);
1568 erq->flags |= IW_ENCODE_ENABLED;
1569 if (padapter->securitypriv.ndisauthtype ==
1570 Ndis802_11AuthModeOpen)
1571 erq->flags |= IW_ENCODE_OPEN;
1572 else if (padapter->securitypriv.ndisauthtype ==
1573 Ndis802_11AuthModeShared)
1574 erq->flags |= IW_ENCODE_RESTRICTED;
1577 erq->flags |= IW_ENCODE_DISABLED;
1580 case Ndis802_11Encryption2Enabled:
1581 case Ndis802_11Encryption3Enabled:
1583 erq->flags |= (IW_ENCODE_ENABLED | IW_ENCODE_OPEN |
1588 erq->flags |= IW_ENCODE_DISABLED;
1594 static int r8711_wx_get_power(struct net_device *dev,
1595 struct iw_request_info *info,
1596 union iwreq_data *wrqu, char *extra)
1598 wrqu->power.value = 0;
1599 wrqu->power.fixed = 0; /* no auto select */
1600 wrqu->power.disabled = 1;
1604 static int r871x_wx_set_gen_ie(struct net_device *dev,
1605 struct iw_request_info *info,
1606 union iwreq_data *wrqu, char *extra)
1608 struct _adapter *padapter = netdev_priv(dev);
1610 return r871x_set_wpa_ie(padapter, extra, wrqu->data.length);
1613 static int r871x_wx_set_auth(struct net_device *dev,
1614 struct iw_request_info *info,
1615 union iwreq_data *wrqu, char *extra)
1617 struct _adapter *padapter = netdev_priv(dev);
1618 struct iw_param *param = (struct iw_param *)&wrqu->param;
1623 paramid = param->flags & IW_AUTH_INDEX;
1624 paramval = param->value;
1626 case IW_AUTH_WPA_VERSION:
1628 case IW_AUTH_CIPHER_PAIRWISE:
1630 case IW_AUTH_CIPHER_GROUP:
1632 case IW_AUTH_KEY_MGMT:
1634 * ??? does not use these parameters
1637 case IW_AUTH_TKIP_COUNTERMEASURES:
1639 /* wpa_supplicant is enabling tkip countermeasure. */
1640 padapter->securitypriv.btkip_countermeasure = true;
1642 /* wpa_supplicant is disabling tkip countermeasure. */
1643 padapter->securitypriv.btkip_countermeasure = false;
1646 case IW_AUTH_DROP_UNENCRYPTED:
1649 * wpa_supplicant calls set_wpa_enabled when the driver
1650 * is loaded and unloaded, regardless of if WPA is being
1651 * used. No other calls are made which can be used to
1652 * determine if encryption will be used or not prior to
1653 * association being expected. If encryption is not being
1654 * used, drop_unencrypted is set to false, else true -- we
1655 * can use this to determine if the CAP_PRIVACY_ON bit should
1658 if (padapter->securitypriv.ndisencryptstatus ==
1659 Ndis802_11Encryption1Enabled) {
1660 /* it means init value, or using wep,
1661 * ndisencryptstatus =
1662 * Ndis802_11Encryption1Enabled,
1663 * then it needn't reset it;
1669 padapter->securitypriv.ndisencryptstatus =
1670 Ndis802_11EncryptionDisabled;
1671 padapter->securitypriv.PrivacyAlgrthm =
1673 padapter->securitypriv.XGrpPrivacy =
1675 padapter->securitypriv.AuthAlgrthm = 0;
1676 padapter->securitypriv.ndisauthtype =
1677 Ndis802_11AuthModeOpen;
1680 case IW_AUTH_80211_AUTH_ALG:
1681 ret = wpa_set_auth_algs(dev, (u32)paramval);
1683 case IW_AUTH_WPA_ENABLED:
1685 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
1687 case IW_AUTH_PRIVACY_INVOKED:
1696 static int r871x_wx_set_enc_ext(struct net_device *dev,
1697 struct iw_request_info *info,
1698 union iwreq_data *wrqu, char *extra)
1700 struct iw_point *pencoding = &wrqu->encoding;
1701 struct iw_encode_ext *pext = (struct iw_encode_ext *)extra;
1702 struct ieee_param *param = NULL;
1707 switch (pext->alg) {
1708 case IW_ENCODE_ALG_NONE:
1711 case IW_ENCODE_ALG_WEP:
1714 case IW_ENCODE_ALG_TKIP:
1717 case IW_ENCODE_ALG_CCMP:
1724 param_len = sizeof(struct ieee_param) + pext->key_len;
1725 param = kzalloc(param_len, GFP_ATOMIC);
1728 param->cmd = IEEE_CMD_SET_ENCRYPTION;
1729 eth_broadcast_addr(param->sta_addr);
1730 strscpy((char *)param->u.crypt.alg, alg_name, IEEE_CRYPT_ALG_NAME_LEN);
1731 if (pext->ext_flags & IW_ENCODE_EXT_GROUP_KEY)
1732 param->u.crypt.set_tx = 0;
1733 if (pext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
1734 param->u.crypt.set_tx = 1;
1735 param->u.crypt.idx = (pencoding->flags & 0x00FF) - 1;
1736 if (pext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID)
1737 memcpy(param->u.crypt.seq, pext->rx_seq, 8);
1738 if (pext->key_len) {
1739 param->u.crypt.key_len = pext->key_len;
1740 memcpy(param + 1, pext + 1, pext->key_len);
1742 ret = wpa_set_encryption(dev, param, param_len);
1747 static int r871x_wx_get_nick(struct net_device *dev,
1748 struct iw_request_info *info,
1749 union iwreq_data *wrqu, char *extra)
1752 wrqu->data.length = 8;
1753 wrqu->data.flags = 1;
1754 memcpy(extra, "rtl_wifi", 8);
1759 static int r8711_wx_read32(struct net_device *dev,
1760 struct iw_request_info *info,
1761 union iwreq_data *wrqu, char *keybuf)
1763 struct _adapter *padapter = netdev_priv(dev);
1767 get_user(addr, (u32 __user *)wrqu->data.pointer);
1768 data32 = r8712_read32(padapter, addr);
1769 put_user(data32, (u32 __user *)wrqu->data.pointer);
1770 wrqu->data.length = (data32 & 0xffff0000) >> 16;
1771 wrqu->data.flags = data32 & 0xffff;
1772 get_user(addr, (u32 __user *)wrqu->data.pointer);
1776 static int r8711_wx_write32(struct net_device *dev,
1777 struct iw_request_info *info,
1778 union iwreq_data *wrqu, char *keybuf)
1780 struct _adapter *padapter = netdev_priv(dev);
1784 get_user(addr, (u32 __user *)wrqu->data.pointer);
1785 data32 = ((u32)wrqu->data.length << 16) | (u32)wrqu->data.flags;
1786 r8712_write32(padapter, addr, data32);
1790 static int dummy(struct net_device *dev,
1791 struct iw_request_info *a,
1792 union iwreq_data *wrqu, char *b)
1797 static int r8711_drvext_hdl(struct net_device *dev,
1798 struct iw_request_info *info,
1799 union iwreq_data *wrqu, char *extra)
1804 static int r871x_mp_ioctl_hdl(struct net_device *dev,
1805 struct iw_request_info *info,
1806 union iwreq_data *wrqu, char *extra)
1808 struct _adapter *padapter = netdev_priv(dev);
1809 struct iw_point *p = &wrqu->data;
1810 struct oid_par_priv oid_par;
1811 struct mp_ioctl_handler *phandler;
1812 struct mp_ioctl_param *poidparam;
1813 unsigned long BytesRead, BytesWritten, BytesNeeded;
1819 if ((!p->length) || (!p->pointer))
1822 bset = (u8)(p->flags & 0xFFFF);
1824 pparmbuf = memdup_user(p->pointer, len);
1825 if (IS_ERR(pparmbuf))
1826 return PTR_ERR(pparmbuf);
1828 poidparam = (struct mp_ioctl_param *)pparmbuf;
1829 if (poidparam->subcode >= MAX_MP_IOCTL_SUBCODE) {
1831 goto _r871x_mp_ioctl_hdl_exit;
1833 phandler = mp_ioctl_hdl + poidparam->subcode;
1834 if ((phandler->paramsize != 0) &&
1835 (poidparam->len < phandler->paramsize)) {
1837 goto _r871x_mp_ioctl_hdl_exit;
1839 if (phandler->oid == 0 && phandler->handler) {
1840 status = phandler->handler(&oid_par);
1841 } else if (phandler->handler) {
1842 oid_par.adapter_context = padapter;
1843 oid_par.oid = phandler->oid;
1844 oid_par.information_buf = poidparam->data;
1845 oid_par.information_buf_len = poidparam->len;
1850 oid_par.bytes_rw = &BytesRead;
1851 oid_par.bytes_needed = &BytesNeeded;
1852 oid_par.type_of_oid = SET_OID;
1854 oid_par.bytes_rw = &BytesWritten;
1855 oid_par.bytes_needed = &BytesNeeded;
1856 oid_par.type_of_oid = QUERY_OID;
1858 status = phandler->handler(&oid_par);
1859 /* todo:check status, BytesNeeded, etc. */
1861 netdev_info(dev, "r8712u: %s: err!, subcode=%d, oid=%d, handler=%p\n",
1862 __func__, poidparam->subcode, phandler->oid,
1865 goto _r871x_mp_ioctl_hdl_exit;
1867 if (bset == 0x00) { /* query info */
1868 if (copy_to_user(p->pointer, pparmbuf, len))
1873 goto _r871x_mp_ioctl_hdl_exit;
1875 _r871x_mp_ioctl_hdl_exit:
1880 static int r871x_get_ap_info(struct net_device *dev,
1881 struct iw_request_info *info,
1882 union iwreq_data *wrqu, char *extra)
1884 struct _adapter *padapter = netdev_priv(dev);
1885 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1886 struct __queue *queue = &pmlmepriv->scanned_queue;
1887 struct iw_point *pdata = &wrqu->data;
1888 struct wlan_network *pnetwork = NULL;
1889 u32 cnt = 0, wpa_ielen;
1891 struct list_head *plist, *phead;
1892 unsigned char *pbuf;
1896 if (padapter->driver_stopped || !pdata)
1898 while (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY |
1899 _FW_UNDER_LINKING)) {
1906 if (pdata->length < 32)
1908 if (copy_from_user(data, pdata->pointer, 32))
1912 spin_lock_irqsave(&pmlmepriv->scanned_queue.lock, irqL);
1913 phead = &queue->queue;
1914 plist = phead->next;
1916 if (end_of_queue_search(phead, plist))
1918 pnetwork = container_of(plist, struct wlan_network, list);
1919 if (!mac_pton(data, bssid)) {
1920 netdev_info(dev, "r8712u: Invalid BSSID '%s'.\n",
1922 spin_unlock_irqrestore(&pmlmepriv->scanned_queue.lock,
1926 netdev_info(dev, "r8712u: BSSID:%pM\n", bssid);
1927 if (ether_addr_equal(bssid, pnetwork->network.MacAddress)) {
1928 /* BSSID match, then check if supporting wpa/wpa2 */
1929 pbuf = r8712_get_wpa_ie(&pnetwork->network.IEs[12],
1930 &wpa_ielen, pnetwork->network.IELength - 12);
1931 if (pbuf && (wpa_ielen > 0)) {
1935 pbuf = r8712_get_wpa2_ie(&pnetwork->network.IEs[12],
1936 &wpa_ielen, pnetwork->network.IELength - 12);
1937 if (pbuf && (wpa_ielen > 0)) {
1942 plist = plist->next;
1944 spin_unlock_irqrestore(&pmlmepriv->scanned_queue.lock, irqL);
1945 if (pdata->length >= 34) {
1946 if (copy_to_user((u8 __user *)pdata->pointer + 32,
1947 (u8 *)&pdata->flags, 1))
1953 static int r871x_set_pid(struct net_device *dev,
1954 struct iw_request_info *info,
1955 union iwreq_data *wrqu, char *extra)
1957 struct _adapter *padapter = netdev_priv(dev);
1958 struct iw_point *pdata = &wrqu->data;
1960 if (padapter->driver_stopped || !pdata)
1962 if (copy_from_user(&padapter->pid, pdata->pointer, sizeof(int)))
1967 static int r871x_set_chplan(struct net_device *dev,
1968 struct iw_request_info *info,
1969 union iwreq_data *wrqu, char *extra)
1972 struct _adapter *padapter = netdev_priv(dev);
1973 struct iw_point *pdata = &wrqu->data;
1976 if (padapter->driver_stopped || !pdata) {
1980 ch_plan = (int)*extra;
1981 r8712_set_chplan_cmd(padapter, ch_plan);
1988 static int r871x_wps_start(struct net_device *dev,
1989 struct iw_request_info *info,
1990 union iwreq_data *wrqu, char *extra)
1992 struct _adapter *padapter = netdev_priv(dev);
1993 struct iw_point *pdata = &wrqu->data;
1994 u32 u32wps_start = 0;
1996 if (padapter->driver_stopped || !pdata)
1998 if (copy_from_user((void *)&u32wps_start, pdata->pointer, 4))
2000 if (u32wps_start == 0)
2001 u32wps_start = *extra;
2002 if (u32wps_start == 1) /* WPS Start */
2003 padapter->ledpriv.LedControlHandler(padapter,
2005 else if (u32wps_start == 2) /* WPS Stop because of wps success */
2006 padapter->ledpriv.LedControlHandler(padapter,
2008 else if (u32wps_start == 3) /* WPS Stop because of wps fail */
2009 padapter->ledpriv.LedControlHandler(padapter,
2010 LED_CTL_STOP_WPS_FAIL);
2014 static int wpa_set_param(struct net_device *dev, u8 name, u32 value)
2016 struct _adapter *padapter = netdev_priv(dev);
2019 case IEEE_PARAM_WPA_ENABLED:
2020 padapter->securitypriv.AuthAlgrthm = 2; /* 802.1x */
2021 switch ((value) & 0xff) {
2023 padapter->securitypriv.ndisauthtype =
2024 Ndis802_11AuthModeWPAPSK; /* WPA_PSK */
2025 padapter->securitypriv.ndisencryptstatus =
2026 Ndis802_11Encryption2Enabled;
2029 padapter->securitypriv.ndisauthtype =
2030 Ndis802_11AuthModeWPA2PSK; /* WPA2_PSK */
2031 padapter->securitypriv.ndisencryptstatus =
2032 Ndis802_11Encryption3Enabled;
2036 case IEEE_PARAM_TKIP_COUNTERMEASURES:
2038 case IEEE_PARAM_DROP_UNENCRYPTED:
2041 * wpa_supplicant calls set_wpa_enabled when the driver
2042 * is loaded and unloaded, regardless of if WPA is being
2043 * used. No other calls are made which can be used to
2044 * determine if encryption will be used or not prior to
2045 * association being expected. If encryption is not being
2046 * used, drop_unencrypted is set to false, else true -- we
2047 * can use this to determine if the CAP_PRIVACY_ON bit should
2051 case IEEE_PARAM_PRIVACY_INVOKED:
2053 case IEEE_PARAM_AUTH_ALGS:
2054 return wpa_set_auth_algs(dev, value);
2055 case IEEE_PARAM_IEEE_802_1X:
2057 case IEEE_PARAM_WPAX_SELECT:
2058 /* added for WPA2 mixed mode */
2066 static int wpa_mlme(struct net_device *dev, u32 command, u32 reason)
2068 struct _adapter *padapter = netdev_priv(dev);
2071 case IEEE_MLME_STA_DEAUTH:
2072 if (!r8712_set_802_11_disassociate(padapter))
2075 case IEEE_MLME_STA_DISASSOC:
2076 if (!r8712_set_802_11_disassociate(padapter))
2085 static int wpa_supplicant_ioctl(struct net_device *dev, struct iw_point *p)
2087 struct ieee_param *param;
2089 struct _adapter *padapter = netdev_priv(dev);
2091 if (p->length < sizeof(struct ieee_param) || !p->pointer)
2093 param = memdup_user(p->pointer, p->length);
2095 return PTR_ERR(param);
2096 switch (param->cmd) {
2097 case IEEE_CMD_SET_WPA_PARAM:
2098 ret = wpa_set_param(dev, param->u.wpa_param.name,
2099 param->u.wpa_param.value);
2101 case IEEE_CMD_SET_WPA_IE:
2102 ret = r871x_set_wpa_ie(padapter, (char *)param->u.wpa_ie.data,
2103 (u16)param->u.wpa_ie.len);
2105 case IEEE_CMD_SET_ENCRYPTION:
2106 ret = wpa_set_encryption(dev, param, p->length);
2109 ret = wpa_mlme(dev, param->u.mlme.command,
2110 param->u.mlme.reason_code);
2116 if (ret == 0 && copy_to_user(p->pointer, param, p->length))
2122 /* based on "driver_ipw" and for hostapd */
2123 int r871x_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
2125 struct iwreq *wrq = (struct iwreq *)rq;
2128 case RTL_IOCTL_WPA_SUPPLICANT:
2129 return wpa_supplicant_ioctl(dev, &wrq->u.data);
2136 static iw_handler r8711_handlers[] = {
2137 NULL, /* SIOCSIWCOMMIT */
2138 r8711_wx_get_name, /* SIOCGIWNAME */
2139 dummy, /* SIOCSIWNWID */
2140 dummy, /* SIOCGIWNWID */
2141 r8711_wx_set_freq, /* SIOCSIWFREQ */
2142 r8711_wx_get_freq, /* SIOCGIWFREQ */
2143 r8711_wx_set_mode, /* SIOCSIWMODE */
2144 r8711_wx_get_mode, /* SIOCGIWMODE */
2145 dummy, /* SIOCSIWSENS */
2146 r8711_wx_get_sens, /* SIOCGIWSENS */
2147 NULL, /* SIOCSIWRANGE */
2148 r8711_wx_get_range, /* SIOCGIWRANGE */
2149 r871x_wx_set_priv, /* SIOCSIWPRIV */
2150 NULL, /* SIOCGIWPRIV */
2151 NULL, /* SIOCSIWSTATS */
2152 NULL, /* SIOCGIWSTATS */
2153 dummy, /* SIOCSIWSPY */
2154 dummy, /* SIOCGIWSPY */
2155 NULL, /* SIOCGIWTHRSPY */
2156 NULL, /* SIOCWIWTHRSPY */
2157 r8711_wx_set_wap, /* SIOCSIWAP */
2158 r8711_wx_get_wap, /* SIOCGIWAP */
2159 r871x_wx_set_mlme, /* request MLME operation;
2160 * uses struct iw_mlme
2162 dummy, /* SIOCGIWAPLIST -- deprecated */
2163 r8711_wx_set_scan, /* SIOCSIWSCAN */
2164 r8711_wx_get_scan, /* SIOCGIWSCAN */
2165 r8711_wx_set_essid, /* SIOCSIWESSID */
2166 r8711_wx_get_essid, /* SIOCGIWESSID */
2167 dummy, /* SIOCSIWNICKN */
2168 r871x_wx_get_nick, /* SIOCGIWNICKN */
2169 NULL, /* -- hole -- */
2170 NULL, /* -- hole -- */
2171 r8711_wx_set_rate, /* SIOCSIWRATE */
2172 r8711_wx_get_rate, /* SIOCGIWRATE */
2173 dummy, /* SIOCSIWRTS */
2174 r8711_wx_get_rts, /* SIOCGIWRTS */
2175 r8711_wx_set_frag, /* SIOCSIWFRAG */
2176 r8711_wx_get_frag, /* SIOCGIWFRAG */
2177 dummy, /* SIOCSIWTXPOW */
2178 dummy, /* SIOCGIWTXPOW */
2179 dummy, /* SIOCSIWRETRY */
2180 r8711_wx_get_retry, /* SIOCGIWRETRY */
2181 r8711_wx_set_enc, /* SIOCSIWENCODE */
2182 r8711_wx_get_enc, /* SIOCGIWENCODE */
2183 dummy, /* SIOCSIWPOWER */
2184 r8711_wx_get_power, /* SIOCGIWPOWER */
2185 NULL, /*---hole---*/
2186 NULL, /*---hole---*/
2187 r871x_wx_set_gen_ie, /* SIOCSIWGENIE */
2188 NULL, /* SIOCGIWGENIE */
2189 r871x_wx_set_auth, /* SIOCSIWAUTH */
2190 NULL, /* SIOCGIWAUTH */
2191 r871x_wx_set_enc_ext, /* SIOCSIWENCODEEXT */
2192 NULL, /* SIOCGIWENCODEEXT */
2193 r871x_wx_set_pmkid, /* SIOCSIWPMKSA */
2194 NULL, /*---hole---*/
2197 static const struct iw_priv_args r8711_private_args[] = {
2199 SIOCIWFIRSTPRIV + 0x0,
2200 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "read32"
2203 SIOCIWFIRSTPRIV + 0x1,
2204 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "write32"
2207 SIOCIWFIRSTPRIV + 0x2, 0, 0, "driver_ext"
2210 SIOCIWFIRSTPRIV + 0x3, 0, 0, "mp_ioctl"
2213 SIOCIWFIRSTPRIV + 0x4,
2214 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "apinfo"
2217 SIOCIWFIRSTPRIV + 0x5,
2218 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setpid"
2221 SIOCIWFIRSTPRIV + 0x6,
2222 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wps_start"
2225 SIOCIWFIRSTPRIV + 0x7,
2226 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "chplan"
2230 static iw_handler r8711_private_handler[] = {
2235 r871x_get_ap_info, /*for MM DTV platform*/
2241 static struct iw_statistics *r871x_get_wireless_stats(struct net_device *dev)
2243 struct _adapter *padapter = netdev_priv(dev);
2244 struct iw_statistics *piwstats = &padapter->iwstats;
2249 if (check_fwstate(&padapter->mlmepriv, _FW_LINKED) != true) {
2250 piwstats->qual.qual = 0;
2251 piwstats->qual.level = 0;
2252 piwstats->qual.noise = 0;
2254 /* show percentage, we need transfer dbm to original value. */
2255 tmp_level = padapter->recvpriv.fw_rssi;
2256 tmp_qual = padapter->recvpriv.signal;
2257 tmp_noise = padapter->recvpriv.noise;
2258 piwstats->qual.level = tmp_level;
2259 piwstats->qual.qual = tmp_qual;
2260 piwstats->qual.noise = tmp_noise;
2262 piwstats->qual.updated = IW_QUAL_ALL_UPDATED;
2263 return &padapter->iwstats;
2266 struct iw_handler_def r871x_handlers_def = {
2267 .standard = r8711_handlers,
2268 .num_standard = ARRAY_SIZE(r8711_handlers),
2269 .private = r8711_private_handler,
2270 .private_args = (struct iw_priv_args *)r8711_private_args,
2271 .num_private = ARRAY_SIZE(r8711_private_handler),
2272 .num_private_args = sizeof(r8711_private_args) /
2273 sizeof(struct iw_priv_args),
2274 .get_wireless_stats = r871x_get_wireless_stats