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,
64 wireless_send_event(padapter->pnetdev, SIOCGIWAP, &wrqu, NULL);
67 void r8712_indicate_wx_disassoc_event(struct _adapter *padapter)
69 union iwreq_data wrqu;
71 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
72 eth_zero_addr(wrqu.ap_addr.sa_data);
73 wireless_send_event(padapter->pnetdev, SIOCGIWAP, &wrqu, NULL);
76 static inline void handle_pairwise_key(struct sta_info *psta,
77 struct ieee_param *param,
78 struct _adapter *padapter)
81 memcpy(psta->x_UncstKey.skey, param->u.crypt.key,
82 (param->u.crypt. key_len > 16 ? 16 : param->u.crypt.key_len));
83 if (strcmp(param->u.crypt.alg, "TKIP") == 0) { /* set mic key */
84 memcpy(psta->tkiptxmickey. skey,
85 &(param->u.crypt.key[16]), 8);
86 memcpy(psta->tkiprxmickey. skey,
87 &(param->u.crypt.key[24]), 8);
88 padapter->securitypriv. busetkipkey = false;
89 mod_timer(&padapter->securitypriv.tkip_timer,
90 jiffies + msecs_to_jiffies(50));
92 r8712_setstakey_cmd(padapter, (unsigned char *)psta, true);
95 static inline void handle_group_key(struct ieee_param *param,
96 struct _adapter *padapter)
98 union Keytype *gk = padapter->securitypriv.XGrpKey;
99 union Keytype *gtk = padapter->securitypriv.XGrptxmickey;
100 union Keytype *grk = padapter->securitypriv.XGrprxmickey;
102 if (param->u.crypt.idx > 0 &&
103 param->u.crypt.idx < 3) {
104 /* group key idx is 1 or 2 */
105 memcpy(gk[param->u.crypt.idx - 1].skey,
107 (param->u.crypt.key_len > 16 ? 16 :
108 param->u.crypt.key_len));
109 memcpy(gtk[param->u.crypt.idx - 1].skey,
110 ¶m->u.crypt.key[16], 8);
111 memcpy(grk[param->u.crypt.idx - 1].skey,
112 ¶m->u.crypt.key[24], 8);
113 padapter->securitypriv.binstallGrpkey = true;
114 r8712_set_key(padapter, &padapter->securitypriv,
116 if (padapter->registrypriv.power_mgnt > PS_MODE_ACTIVE) {
117 if (padapter->registrypriv.power_mgnt !=
118 padapter->pwrctrlpriv.pwr_mode)
119 mod_timer(&padapter->mlmepriv.dhcp_timer,
120 jiffies + msecs_to_jiffies(60000));
125 static noinline_for_stack char *translate_scan_wpa(struct iw_request_info *info,
126 struct wlan_network *pnetwork,
127 struct iw_event *iwe,
128 char *start, char *stop)
130 /* parsing WPA/WPA2 IE */
131 u8 buf[MAX_WPA_IE_LEN];
132 u8 wpa_ie[255], rsn_ie[255];
133 u16 wpa_len = 0, rsn_len = 0;
136 r8712_get_sec_ie(pnetwork->network.IEs,
137 pnetwork->network.IELength, rsn_ie, &rsn_len,
140 memset(buf, 0, MAX_WPA_IE_LEN);
141 n = sprintf(buf, "wpa_ie=");
142 for (i = 0; i < wpa_len; i++) {
143 n += scnprintf(buf + n, MAX_WPA_IE_LEN - n,
145 if (n == MAX_WPA_IE_LEN - 1)
148 memset(iwe, 0, sizeof(*iwe));
149 iwe->cmd = IWEVCUSTOM;
150 iwe->u.data.length = (u16)strlen(buf);
151 start = iwe_stream_add_point(info, start, stop,
153 memset(iwe, 0, sizeof(*iwe));
154 iwe->cmd = IWEVGENIE;
155 iwe->u.data.length = (u16)wpa_len;
156 start = iwe_stream_add_point(info, start, stop,
160 memset(buf, 0, MAX_WPA_IE_LEN);
161 n = sprintf(buf, "rsn_ie=");
162 for (i = 0; i < rsn_len; i++) {
163 n += scnprintf(buf + n, MAX_WPA_IE_LEN - n,
165 if (n == MAX_WPA_IE_LEN - 1)
168 memset(iwe, 0, sizeof(*iwe));
169 iwe->cmd = IWEVCUSTOM;
170 iwe->u.data.length = strlen(buf);
171 start = iwe_stream_add_point(info, start, stop,
173 memset(iwe, 0, sizeof(*iwe));
174 iwe->cmd = IWEVGENIE;
175 iwe->u.data.length = rsn_len;
176 start = iwe_stream_add_point(info, start, stop, iwe,
183 static noinline_for_stack char *translate_scan_wps(struct iw_request_info *info,
184 struct wlan_network *pnetwork,
185 struct iw_event *iwe,
186 char *start, char *stop)
192 if (r8712_get_wps_ie(pnetwork->network.IEs,
193 pnetwork->network.IELength,
194 wps_ie, &wps_ielen)) {
196 iwe->cmd = IWEVGENIE;
197 iwe->u.data.length = (u16)wps_ielen;
198 start = iwe_stream_add_point(info, start, stop,
206 static char *translate_scan(struct _adapter *padapter,
207 struct iw_request_info *info,
208 struct wlan_network *pnetwork,
209 char *start, char *stop)
214 u32 i = 0, ht_ielen = 0;
215 u16 cap, ht_cap = false;
218 if ((pnetwork->network.Configuration.DSConfig < 1) ||
219 (pnetwork->network.Configuration.DSConfig > 14)) {
220 if (pnetwork->network.Configuration.DSConfig < 1)
221 pnetwork->network.Configuration.DSConfig = 1;
223 pnetwork->network.Configuration.DSConfig = 14;
227 iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
228 ether_addr_copy(iwe.u.ap_addr.sa_data, pnetwork->network.MacAddress);
229 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_ADDR_LEN);
231 iwe.cmd = SIOCGIWESSID;
232 iwe.u.data.flags = 1;
233 iwe.u.data.length = min_t(u32, pnetwork->network.Ssid.SsidLength, 32);
234 start = iwe_stream_add_point(info, start, stop, &iwe,
235 pnetwork->network.Ssid.Ssid);
236 /* parsing HT_CAP_IE */
237 p = r8712_get_ie(&pnetwork->network.IEs[12], WLAN_EID_HT_CAPABILITY,
238 &ht_ielen, pnetwork->network.IELength - 12);
239 if (p && ht_ielen > 0)
241 /* Add the protocol name */
242 iwe.cmd = SIOCGIWNAME;
243 if (r8712_is_cckratesonly_included(pnetwork->network.rates)) {
245 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bn");
247 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11b");
248 } else if (r8712_is_cckrates_included(pnetwork->network.rates)) {
250 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bgn");
252 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bg");
255 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11gn");
257 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11g");
259 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_CHAR_LEN);
261 iwe.cmd = SIOCGIWMODE;
262 memcpy((u8 *)&cap, r8712_get_capability_from_ie(pnetwork->network.IEs),
265 if (cap & (WLAN_CAPABILITY_IBSS | WLAN_CAPABILITY_ESS)) {
266 if (cap & WLAN_CAPABILITY_ESS)
267 iwe.u.mode = (u32)IW_MODE_MASTER;
269 iwe.u.mode = (u32)IW_MODE_ADHOC;
270 start = iwe_stream_add_event(info, start, stop, &iwe,
273 /* Add frequency/channel */
274 iwe.cmd = SIOCGIWFREQ;
276 /* check legal index */
277 u8 dsconfig = pnetwork->network.Configuration.DSConfig;
279 if (dsconfig >= 1 && dsconfig <= sizeof(
280 ieee80211_wlan_frequencies) / sizeof(long))
282 (s32)(ieee80211_wlan_frequencies
283 [dsconfig - 1] * 100000);
287 iwe.u.freq.e = (s16)1;
288 iwe.u.freq.i = (u8)pnetwork->network.Configuration.DSConfig;
289 start = iwe_stream_add_event(info, start, stop, &iwe,
291 /* Add encryption capability */
292 iwe.cmd = SIOCGIWENCODE;
293 if (cap & WLAN_CAPABILITY_PRIVACY)
294 iwe.u.data.flags = (u16)(IW_ENCODE_ENABLED |
297 iwe.u.data.flags = (u16)(IW_ENCODE_DISABLED);
298 iwe.u.data.length = (u16)0;
299 start = iwe_stream_add_point(info, start, stop, &iwe,
300 pnetwork->network.Ssid.Ssid);
301 /*Add basic and extended rates */
302 current_val = start + iwe_stream_lcp_len(info);
303 iwe.cmd = SIOCGIWRATE;
304 iwe.u.bitrate.fixed = 0;
305 iwe.u.bitrate.disabled = 0;
306 iwe.u.bitrate.value = 0;
308 while (pnetwork->network.rates[i] != 0) {
309 /* Bit rate given in 500 kb/s units */
310 iwe.u.bitrate.value = (pnetwork->network.rates[i++] &
312 current_val = iwe_stream_add_value(info, start, current_val,
313 stop, &iwe, IW_EV_PARAM_LEN);
315 /* Check if we added any event */
316 if ((current_val - start) > iwe_stream_lcp_len(info))
319 start = translate_scan_wpa(info, pnetwork, &iwe, start, stop);
321 start = translate_scan_wps(info, pnetwork, &iwe, start, stop);
323 /* Add quality statistics */
325 rssi = r8712_signal_scale_mapping(pnetwork->network.Rssi);
326 /* we only update signal_level (signal strength) that is rssi. */
327 iwe.u.qual.updated = (u8)(IW_QUAL_QUAL_INVALID | IW_QUAL_LEVEL_UPDATED |
328 IW_QUAL_NOISE_INVALID);
329 iwe.u.qual.level = rssi; /* signal strength */
330 iwe.u.qual.qual = 0; /* signal quality */
331 iwe.u.qual.noise = 0; /* noise level */
332 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_QUAL_LEN);
333 /* how to translate rssi to ?% */
337 static int wpa_set_auth_algs(struct net_device *dev, u32 value)
339 struct _adapter *padapter = netdev_priv(dev);
342 if ((value & AUTH_ALG_SHARED_KEY) && (value & AUTH_ALG_OPEN_SYSTEM)) {
343 padapter->securitypriv.ndisencryptstatus =
344 Ndis802_11Encryption1Enabled;
345 padapter->securitypriv.ndisauthtype =
346 Ndis802_11AuthModeAutoSwitch;
347 padapter->securitypriv.AuthAlgrthm = 3;
348 } else if (value & AUTH_ALG_SHARED_KEY) {
349 padapter->securitypriv.ndisencryptstatus =
350 Ndis802_11Encryption1Enabled;
351 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeShared;
352 padapter->securitypriv.AuthAlgrthm = 1;
353 } else if (value & AUTH_ALG_OPEN_SYSTEM) {
354 if (padapter->securitypriv.ndisauthtype <
355 Ndis802_11AuthModeWPAPSK) {
356 padapter->securitypriv.ndisauthtype =
357 Ndis802_11AuthModeOpen;
358 padapter->securitypriv.AuthAlgrthm = 0;
366 static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param,
370 u32 wep_key_idx, wep_key_len = 0;
371 struct NDIS_802_11_WEP *pwep = NULL;
372 struct _adapter *padapter = netdev_priv(dev);
373 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
374 struct security_priv *psecuritypriv = &padapter->securitypriv;
376 param->u.crypt.err = 0;
377 param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
378 if (param_len != (u32)((u8 *) param->u.crypt.key - (u8 *)param) +
379 param->u.crypt.key_len)
381 if (!is_broadcast_ether_addr(param->sta_addr))
384 if (param->u.crypt.idx >= WEP_KEYS) {
385 /* for large key indices, set the default (0) */
386 param->u.crypt.idx = 0;
388 if (strcmp(param->u.crypt.alg, "WEP") == 0) {
389 netdev_info(dev, "r8712u: %s: crypt.alg = WEP\n", __func__);
390 padapter->securitypriv.ndisencryptstatus =
391 Ndis802_11Encryption1Enabled;
392 padapter->securitypriv.PrivacyAlgrthm = _WEP40_;
393 padapter->securitypriv.XGrpPrivacy = _WEP40_;
394 wep_key_idx = param->u.crypt.idx;
395 wep_key_len = param->u.crypt.key_len;
396 if (wep_key_idx >= WEP_KEYS)
398 if (wep_key_len <= 0)
401 wep_key_len = wep_key_len <= 5 ? 5 : 13;
402 pwep = kzalloc(sizeof(*pwep), GFP_ATOMIC);
405 pwep->KeyLength = wep_key_len;
406 pwep->Length = wep_key_len +
407 offsetof(struct NDIS_802_11_WEP, KeyMaterial);
408 if (wep_key_len == 13) {
409 padapter->securitypriv.PrivacyAlgrthm = _WEP104_;
410 padapter->securitypriv.XGrpPrivacy = _WEP104_;
412 pwep->KeyIndex = wep_key_idx;
413 pwep->KeyIndex |= 0x80000000;
414 memcpy(pwep->KeyMaterial, param->u.crypt.key, pwep->KeyLength);
415 if (param->u.crypt.set_tx) {
416 if (r8712_set_802_11_add_wep(padapter, pwep))
419 /* don't update "psecuritypriv->PrivacyAlgrthm" and
420 * "psecuritypriv->PrivacyKeyIndex=keyid", but can
421 * r8712_set_key to fw/cam
423 if (wep_key_idx >= WEP_KEYS) {
427 memcpy(&psecuritypriv->DefKey[wep_key_idx].skey[0],
430 psecuritypriv->DefKeylen[wep_key_idx] =
432 r8712_set_key(padapter, psecuritypriv, wep_key_idx);
436 if (padapter->securitypriv.AuthAlgrthm == 2) { /* 802_1x */
437 struct sta_info *psta, *pbcmc_sta;
438 struct sta_priv *pstapriv = &padapter->stapriv;
439 struct security_priv *spriv = &padapter->securitypriv;
441 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE |
442 WIFI_MP_STATE)) { /* sta mode */
443 psta = r8712_get_stainfo(pstapriv,
444 get_bssid(pmlmepriv));
446 psta->ieee8021x_blocked = false;
447 if (spriv->ndisencryptstatus ==
448 Ndis802_11Encryption2Enabled ||
449 spriv->ndisencryptstatus ==
450 Ndis802_11Encryption3Enabled)
451 psta->XPrivacy = spriv->PrivacyAlgrthm;
452 if (param->u.crypt.set_tx == 1)
453 handle_pairwise_key(psta, param,
456 handle_group_key(param, padapter);
458 pbcmc_sta = r8712_get_bcmc_stainfo(padapter);
460 pbcmc_sta->ieee8021x_blocked = false;
461 if (spriv->ndisencryptstatus ==
462 Ndis802_11Encryption2Enabled ||
463 spriv->ndisencryptstatus ==
464 Ndis802_11Encryption3Enabled)
465 pbcmc_sta->XPrivacy =
466 spriv->PrivacyAlgrthm;
475 static int r871x_set_wpa_ie(struct _adapter *padapter, char *pie,
476 unsigned short ielen)
479 int group_cipher = 0, pairwise_cipher = 0;
482 if (ielen > MAX_WPA_IE_LEN || !pie)
485 buf = kmemdup(pie, ielen, GFP_ATOMIC);
488 if (ielen < RSN_HEADER_LEN) {
492 if (r8712_parse_wpa_ie(buf, ielen, &group_cipher,
493 &pairwise_cipher) == 0) {
494 padapter->securitypriv.AuthAlgrthm = 2;
495 padapter->securitypriv.ndisauthtype =
496 Ndis802_11AuthModeWPAPSK;
498 if (r8712_parse_wpa2_ie(buf, ielen, &group_cipher,
499 &pairwise_cipher) == 0) {
500 padapter->securitypriv.AuthAlgrthm = 2;
501 padapter->securitypriv.ndisauthtype =
502 Ndis802_11AuthModeWPA2PSK;
504 switch (group_cipher) {
505 case WPA_CIPHER_NONE:
506 padapter->securitypriv.XGrpPrivacy =
508 padapter->securitypriv.ndisencryptstatus =
509 Ndis802_11EncryptionDisabled;
511 case WPA_CIPHER_WEP40:
512 padapter->securitypriv.XGrpPrivacy = _WEP40_;
513 padapter->securitypriv.ndisencryptstatus =
514 Ndis802_11Encryption1Enabled;
516 case WPA_CIPHER_TKIP:
517 padapter->securitypriv.XGrpPrivacy = _TKIP_;
518 padapter->securitypriv.ndisencryptstatus =
519 Ndis802_11Encryption2Enabled;
521 case WPA_CIPHER_CCMP:
522 padapter->securitypriv.XGrpPrivacy = _AES_;
523 padapter->securitypriv.ndisencryptstatus =
524 Ndis802_11Encryption3Enabled;
526 case WPA_CIPHER_WEP104:
527 padapter->securitypriv.XGrpPrivacy = _WEP104_;
528 padapter->securitypriv.ndisencryptstatus =
529 Ndis802_11Encryption1Enabled;
532 switch (pairwise_cipher) {
533 case WPA_CIPHER_NONE:
534 padapter->securitypriv.PrivacyAlgrthm =
536 padapter->securitypriv.ndisencryptstatus =
537 Ndis802_11EncryptionDisabled;
539 case WPA_CIPHER_WEP40:
540 padapter->securitypriv.PrivacyAlgrthm = _WEP40_;
541 padapter->securitypriv.ndisencryptstatus =
542 Ndis802_11Encryption1Enabled;
544 case WPA_CIPHER_TKIP:
545 padapter->securitypriv.PrivacyAlgrthm = _TKIP_;
546 padapter->securitypriv.ndisencryptstatus =
547 Ndis802_11Encryption2Enabled;
549 case WPA_CIPHER_CCMP:
550 padapter->securitypriv.PrivacyAlgrthm = _AES_;
551 padapter->securitypriv.ndisencryptstatus =
552 Ndis802_11Encryption3Enabled;
554 case WPA_CIPHER_WEP104:
555 padapter->securitypriv.PrivacyAlgrthm = _WEP104_;
556 padapter->securitypriv.ndisencryptstatus =
557 Ndis802_11Encryption1Enabled;
560 padapter->securitypriv.wps_phase = false;
563 u8 eid, wps_oui[4] = {0x0, 0x50, 0xf2, 0x04};
565 while (cnt < ielen) {
568 if ((eid == WLAN_EID_VENDOR_SPECIFIC) &&
569 (!memcmp(&buf[cnt + 2], wps_oui, 4))) {
570 netdev_info(padapter->pnetdev, "r8712u: SET WPS_IE\n");
571 padapter->securitypriv.wps_ie_len =
572 ((buf[cnt + 1] + 2) <
573 (MAX_WPA_IE_LEN << 2)) ?
575 (MAX_WPA_IE_LEN << 2);
576 memcpy(padapter->securitypriv.wps_ie,
578 padapter->securitypriv.wps_ie_len);
579 padapter->securitypriv.wps_phase =
581 netdev_info(padapter->pnetdev, "r8712u: SET WPS_IE, wps_phase==true\n");
582 cnt += buf[cnt + 1] + 2;
586 cnt += buf[cnt + 1] + 2;
595 static int r8711_wx_get_name(struct net_device *dev,
596 struct iw_request_info *info,
597 union iwreq_data *wrqu, char *extra)
599 struct _adapter *padapter = netdev_priv(dev);
603 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
604 struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
607 if (check_fwstate(pmlmepriv, _FW_LINKED | WIFI_ADHOC_MASTER_STATE) ==
609 /* parsing HT_CAP_IE */
610 p = r8712_get_ie(&pcur_bss->IEs[12], WLAN_EID_HT_CAPABILITY,
611 &ht_ielen, pcur_bss->IELength - 12);
612 if (p && ht_ielen > 0)
614 prates = pcur_bss->rates;
615 if (r8712_is_cckratesonly_included(prates)) {
617 snprintf(wrqu->name, IFNAMSIZ,
620 snprintf(wrqu->name, IFNAMSIZ,
622 } else if (r8712_is_cckrates_included(prates)) {
624 snprintf(wrqu->name, IFNAMSIZ,
627 snprintf(wrqu->name, IFNAMSIZ,
631 snprintf(wrqu->name, IFNAMSIZ,
634 snprintf(wrqu->name, IFNAMSIZ,
638 snprintf(wrqu->name, IFNAMSIZ, "unassociated");
643 static const long frequency_list[] = {
644 2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447, 2452, 2457, 2462,
645 2467, 2472, 2484, 4915, 4920, 4925, 4935, 4940, 4945, 4960, 4980,
646 5035, 5040, 5045, 5055, 5060, 5080, 5170, 5180, 5190, 5200, 5210,
647 5220, 5230, 5240, 5260, 5280, 5300, 5320, 5500, 5520, 5540, 5560,
648 5580, 5600, 5620, 5640, 5660, 5680, 5700, 5745, 5765, 5785, 5805,
652 static int r8711_wx_set_freq(struct net_device *dev,
653 struct iw_request_info *info,
654 union iwreq_data *wrqu, char *extra)
656 struct _adapter *padapter = netdev_priv(dev);
657 struct iw_freq *fwrq = &wrqu->freq;
660 /* If setting by frequency, convert to a channel */
661 if ((fwrq->e == 1) &&
662 (fwrq->m >= (int) 2.412e8) &&
663 (fwrq->m <= (int) 2.487e8)) {
664 int f = fwrq->m / 100000;
667 while ((c < 14) && (f != frequency_list[c]))
672 /* Setting by channel number */
673 if ((fwrq->m > 14) || (fwrq->e > 0)) {
676 int channel = fwrq->m;
678 if ((channel < 1) || (channel > 14)) {
681 /* Yes ! We can set it !!! */
682 padapter->registrypriv.channel = channel;
688 static int r8711_wx_get_freq(struct net_device *dev,
689 struct iw_request_info *info,
690 union iwreq_data *wrqu, char *extra)
692 struct _adapter *padapter = netdev_priv(dev);
693 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
694 struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
696 if (!check_fwstate(pmlmepriv, _FW_LINKED))
699 wrqu->freq.m = ieee80211_wlan_frequencies[
700 pcur_bss->Configuration.DSConfig - 1] * 100000;
702 wrqu->freq.i = pcur_bss->Configuration.DSConfig;
707 static int r8711_wx_set_mode(struct net_device *dev,
708 struct iw_request_info *a,
709 union iwreq_data *wrqu, char *b)
711 struct _adapter *padapter = netdev_priv(dev);
712 enum NDIS_802_11_NETWORK_INFRASTRUCTURE networkType;
714 switch (wrqu->mode) {
716 networkType = Ndis802_11AutoUnknown;
719 networkType = Ndis802_11IBSS;
722 networkType = Ndis802_11APMode;
725 networkType = Ndis802_11Infrastructure;
730 if (Ndis802_11APMode == networkType)
731 r8712_setopmode_cmd(padapter, networkType);
733 r8712_setopmode_cmd(padapter, Ndis802_11AutoUnknown);
735 r8712_set_802_11_infrastructure_mode(padapter, networkType);
739 static int r8711_wx_get_mode(struct net_device *dev, struct iw_request_info *a,
740 union iwreq_data *wrqu, char *b)
742 struct _adapter *padapter = netdev_priv(dev);
743 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
745 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE))
746 wrqu->mode = IW_MODE_INFRA;
747 else if (check_fwstate(pmlmepriv,
748 WIFI_ADHOC_MASTER_STATE | WIFI_ADHOC_STATE))
749 wrqu->mode = IW_MODE_ADHOC;
750 else if (check_fwstate(pmlmepriv, WIFI_AP_STATE))
751 wrqu->mode = IW_MODE_MASTER;
753 wrqu->mode = IW_MODE_AUTO;
757 static int r871x_wx_set_pmkid(struct net_device *dev,
758 struct iw_request_info *a,
759 union iwreq_data *wrqu, char *extra)
761 struct _adapter *padapter = netdev_priv(dev);
762 struct security_priv *psecuritypriv = &padapter->securitypriv;
763 struct iw_pmksa *pPMK = (struct iw_pmksa *) extra;
764 struct RT_PMKID_LIST *pl = psecuritypriv->PMKIDList;
765 u8 strZeroMacAddress[ETH_ALEN] = {0x00};
766 u8 strIssueBssid[ETH_ALEN] = {0x00};
767 u8 j, blInserted = false;
768 int intReturn = false;
771 * There are the BSSID information in the bssid.sa_data array.
772 * If cmd is IW_PMKSA_FLUSH, it means the wpa_supplicant wants to clear
773 * all the PMKID information. If cmd is IW_PMKSA_ADD, it means the
774 * wpa_supplicant wants to add a PMKID/BSSID to driver.
775 * If cmd is IW_PMKSA_REMOVE, it means the wpa_supplicant wants to
776 * remove a PMKID/BSSID from driver.
780 memcpy(strIssueBssid, pPMK->bssid.sa_data, ETH_ALEN);
783 if (!memcmp(strIssueBssid, strZeroMacAddress, ETH_ALEN))
787 /* overwrite PMKID */
788 for (j = 0; j < NUM_PMKID_CACHE; j++) {
789 if (!memcmp(pl[j].Bssid, strIssueBssid, ETH_ALEN)) {
790 /* BSSID is matched, the same AP => rewrite
793 netdev_info(dev, "r8712u: %s: BSSID exists in the PMKList.\n",
795 memcpy(pl[j].PMKID, pPMK->pmkid, IW_PMKID_LEN);
797 psecuritypriv->PMKIDIndex = j + 1;
803 /* Find a new entry */
804 netdev_info(dev, "r8712u: %s: Use the new entry index = %d for this PMKID.\n",
805 __func__, psecuritypriv->PMKIDIndex);
806 memcpy(pl[psecuritypriv->PMKIDIndex].Bssid,
807 strIssueBssid, ETH_ALEN);
808 memcpy(pl[psecuritypriv->PMKIDIndex].PMKID,
809 pPMK->pmkid, IW_PMKID_LEN);
810 pl[psecuritypriv->PMKIDIndex].bUsed = true;
811 psecuritypriv->PMKIDIndex++;
812 if (psecuritypriv->PMKIDIndex == NUM_PMKID_CACHE)
813 psecuritypriv->PMKIDIndex = 0;
816 case IW_PMKSA_REMOVE:
818 for (j = 0; j < NUM_PMKID_CACHE; j++) {
819 if (!memcmp(pl[j].Bssid, strIssueBssid, ETH_ALEN)) {
820 /* BSSID is matched, the same AP => Remove
821 * this PMKID information and reset it.
823 eth_zero_addr(pl[j].Bssid);
830 memset(psecuritypriv->PMKIDList, 0,
831 sizeof(struct RT_PMKID_LIST) * NUM_PMKID_CACHE);
832 psecuritypriv->PMKIDIndex = 0;
836 netdev_info(dev, "r8712u: %s: unknown Command\n", __func__);
843 static int r8711_wx_get_sens(struct net_device *dev,
844 struct iw_request_info *info,
845 union iwreq_data *wrqu, char *extra)
847 wrqu->sens.value = 0;
848 wrqu->sens.fixed = 0; /* no auto select */
849 wrqu->sens.disabled = 1;
853 static int r8711_wx_get_range(struct net_device *dev,
854 struct iw_request_info *info,
855 union iwreq_data *wrqu, char *extra)
857 struct iw_range *range = (struct iw_range *)extra;
861 wrqu->data.length = sizeof(*range);
862 memset(range, 0, sizeof(*range));
863 /* Let's try to keep this struct in the same order as in
864 * linux/include/wireless.h
867 /* TODO: See what values we can set, and remove the ones we can't
868 * set, or fill them with some default data.
870 /* ~5 Mb/s real (802.11b) */
871 range->throughput = 5 * 1000 * 1000;
872 /* TODO: 8711 sensitivity ? */
873 /* signal level threshold range */
874 /* percent values between 0 and 100. */
875 range->max_qual.qual = 100;
876 range->max_qual.level = 100;
877 range->max_qual.noise = 100;
878 range->max_qual.updated = 7; /* Updated all three */
879 range->avg_qual.qual = 92; /* > 8% missed beacons is 'bad' */
880 /* TODO: Find real 'good' to 'bad' threshold value for RSSI */
881 range->avg_qual.level = 0x100 - 78;
882 range->avg_qual.noise = 0;
883 range->avg_qual.updated = 7; /* Updated all three */
884 range->num_bitrates = RATE_COUNT;
885 for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++)
886 range->bitrate[i] = rtl8180_rates[i];
887 range->min_frag = MIN_FRAG_THRESHOLD;
888 range->max_frag = MAX_FRAG_THRESHOLD;
890 range->we_version_compiled = WIRELESS_EXT;
891 range->we_version_source = 16;
892 range->num_channels = 14;
893 for (i = 0, val = 0; i < 14; i++) {
894 /* Include only legal frequencies for some countries */
895 range->freq[val].i = i + 1;
896 range->freq[val].m = ieee80211_wlan_frequencies[i] * 100000;
897 range->freq[val].e = 1;
899 if (val == IW_MAX_FREQUENCIES)
902 range->num_frequency = val;
903 range->enc_capa = IW_ENC_CAPA_WPA |
905 IW_ENC_CAPA_CIPHER_TKIP |
906 IW_ENC_CAPA_CIPHER_CCMP;
910 static int r8711_wx_get_rate(struct net_device *dev,
911 struct iw_request_info *info,
912 union iwreq_data *wrqu, char *extra);
914 static int r871x_wx_set_priv(struct net_device *dev,
915 struct iw_request_info *info,
916 union iwreq_data *awrq,
919 int ret = 0, len = 0;
921 struct _adapter *padapter = netdev_priv(dev);
922 struct iw_point *dwrq = (struct iw_point *)awrq;
925 ext = strndup_user(dwrq->pointer, len);
929 if (!strcasecmp(ext, "RSSI")) {
930 /*Return received signal strength indicator in -db for */
933 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
934 struct wlan_network *pcur_network = &pmlmepriv->cur_network;
936 if (check_fwstate(pmlmepriv, _FW_LINKED)) {
937 sprintf(ext, "%s rssi %d",
938 pcur_network->network.Ssid.Ssid,
940 ((padapter->recvpriv.fw_rssi) >> 1) - 95
941 /*pcur_network->network.Rssi */
946 } else if (!strcasecmp(ext, "LINKSPEED")) {
947 /*Return link speed in MBPS */
949 union iwreq_data wrqd;
953 ret_inner = r8711_wx_get_rate(dev, info, &wrqd, extra);
957 mbps = wrqd.bitrate.value / 1000000;
958 sprintf(ext, "LINKSPEED %d", mbps);
959 } else if (!strcasecmp(ext, "MACADDR")) {
960 /*Return mac address of the station */
961 /* Macaddr = xx:xx:xx:xx:xx:xx */
962 sprintf(ext, "MACADDR = %pM", dev->dev_addr);
963 } else if (!strcasecmp(ext, "SCAN-ACTIVE")) {
964 /*Set scan type to active */
965 /*OK if successful */
966 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
968 pmlmepriv->passive_mode = 1;
970 } else if (!strcasecmp(ext, "SCAN-PASSIVE")) {
971 /*Set scan type to passive */
972 /*OK if successful */
973 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
975 pmlmepriv->passive_mode = 0;
977 } else if (!strncmp(ext, "DCE-E", 5)) {
978 /*Set scan type to passive */
979 /*OK if successful */
980 r8712_disconnectCtrlEx_cmd(padapter
981 , 1 /*u32 enableDrvCtrl */
982 , 5 /*u32 tryPktCnt */
983 , 100 /*u32 tryPktInterval */
984 , 5000 /*u32 firstStageTO */
987 } else if (!strncmp(ext, "DCE-D", 5)) {
988 /*Set scan type to passive */
990 r8712_disconnectCtrlEx_cmd(padapter
991 , 0 /*u32 enableDrvCtrl */
992 , 5 /*u32 tryPktCnt */
993 , 100 /*u32 tryPktInterval */
994 , 5000 /*u32 firstStageTO */
998 netdev_info(dev, "r8712u: %s: unknown Command %s.\n",
1002 if (copy_to_user(dwrq->pointer, ext,
1003 min(dwrq->length, (__u16)(strlen(ext) + 1))))
1012 * s1. set_802_11_infrastructure_mode()
1013 * s2. set_802_11_authentication_mode()
1014 * s3. set_802_11_encryption_mode()
1015 * s4. set_802_11_bssid()
1017 * This function intends to handle the Set AP command, which specifies the
1018 * MAC# of a preferred Access Point.
1019 * Currently, the request comes via Wireless Extensions' SIOCSIWAP ioctl.
1021 * For this operation to succeed, there is no need for the interface to be up.
1024 static int r8711_wx_set_wap(struct net_device *dev,
1025 struct iw_request_info *info,
1026 union iwreq_data *awrq,
1029 int ret = -EINPROGRESS;
1030 struct _adapter *padapter = netdev_priv(dev);
1031 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1032 struct __queue *queue = &pmlmepriv->scanned_queue;
1033 struct sockaddr *temp = (struct sockaddr *)awrq;
1035 struct list_head *phead;
1037 struct wlan_network *pnetwork = NULL;
1038 enum NDIS_802_11_AUTHENTICATION_MODE authmode;
1040 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY))
1042 if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING))
1044 if (temp->sa_family != ARPHRD_ETHER)
1046 authmode = padapter->securitypriv.ndisauthtype;
1047 spin_lock_irqsave(&queue->lock, irqL);
1048 phead = &queue->queue;
1049 pmlmepriv->pscanned = phead->next;
1051 if (end_of_queue_search(phead, pmlmepriv->pscanned))
1053 pnetwork = container_of(pmlmepriv->pscanned,
1054 struct wlan_network, list);
1055 pmlmepriv->pscanned = pmlmepriv->pscanned->next;
1056 dst_bssid = pnetwork->network.MacAddress;
1057 if (!memcmp(dst_bssid, temp->sa_data, ETH_ALEN)) {
1058 r8712_set_802_11_infrastructure_mode(padapter,
1059 pnetwork->network.InfrastructureMode);
1063 spin_unlock_irqrestore(&queue->lock, irqL);
1065 if (!r8712_set_802_11_authentication_mode(padapter, authmode)) {
1068 if (!r8712_set_802_11_bssid(padapter, temp->sa_data))
1075 static int r8711_wx_get_wap(struct net_device *dev,
1076 struct iw_request_info *info,
1077 union iwreq_data *wrqu, char *extra)
1079 struct _adapter *padapter = netdev_priv(dev);
1080 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1081 struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
1083 wrqu->ap_addr.sa_family = ARPHRD_ETHER;
1084 if (check_fwstate(pmlmepriv, _FW_LINKED | WIFI_ADHOC_MASTER_STATE |
1086 ether_addr_copy(wrqu->ap_addr.sa_data, pcur_bss->MacAddress);
1088 eth_zero_addr(wrqu->ap_addr.sa_data);
1092 static int r871x_wx_set_mlme(struct net_device *dev,
1093 struct iw_request_info *info,
1094 union iwreq_data *wrqu, char *extra)
1097 struct _adapter *padapter = netdev_priv(dev);
1098 struct iw_mlme *mlme = (struct iw_mlme *) extra;
1102 switch (mlme->cmd) {
1103 case IW_MLME_DEAUTH:
1104 if (!r8712_set_802_11_disassociate(padapter))
1107 case IW_MLME_DISASSOC:
1108 if (!r8712_set_802_11_disassociate(padapter))
1119 * This function intends to handle the Set Scan command.
1120 * Currently, the request comes via Wireless Extensions' SIOCSIWSCAN ioctl.
1122 * For this operation to succeed, the interface is brought Up beforehand.
1125 static int r8711_wx_set_scan(struct net_device *dev,
1126 struct iw_request_info *a,
1127 union iwreq_data *wrqu, char *extra)
1129 struct _adapter *padapter = netdev_priv(dev);
1130 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1133 if (padapter->driver_stopped) {
1134 netdev_info(dev, "In %s: driver_stopped=%d\n",
1135 __func__, padapter->driver_stopped);
1140 if (!padapter->hw_init_completed)
1142 if ((check_fwstate(pmlmepriv, _FW_UNDER_SURVEY | _FW_UNDER_LINKING)) ||
1143 (pmlmepriv->sitesurveyctrl.traffic_busy))
1145 if (wrqu->data.length == sizeof(struct iw_scan_req)) {
1146 struct iw_scan_req *req = (struct iw_scan_req *)extra;
1148 if (wrqu->data.flags & IW_SCAN_THIS_ESSID) {
1149 struct ndis_802_11_ssid ssid;
1151 u32 len = min_t(u8, req->essid_len, IW_ESSID_MAX_SIZE);
1153 memset((unsigned char *)&ssid, 0,
1154 sizeof(struct ndis_802_11_ssid));
1155 memcpy(ssid.Ssid, req->essid, len);
1156 ssid.SsidLength = len;
1157 spin_lock_irqsave(&pmlmepriv->lock, irqL);
1158 if ((check_fwstate(pmlmepriv, _FW_UNDER_SURVEY |
1159 _FW_UNDER_LINKING)) ||
1160 (pmlmepriv->sitesurveyctrl.traffic_busy)) {
1161 if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING))
1164 status = r8712_sitesurvey_cmd(padapter, &ssid);
1166 spin_unlock_irqrestore(&pmlmepriv->lock, irqL);
1169 status = r8712_set_802_11_bssid_list_scan(padapter);
1176 static int r8711_wx_get_scan(struct net_device *dev,
1177 struct iw_request_info *a,
1178 union iwreq_data *wrqu, char *extra)
1180 struct _adapter *padapter = netdev_priv(dev);
1181 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1182 struct __queue *queue = &pmlmepriv->scanned_queue;
1183 struct wlan_network *pnetwork = NULL;
1185 struct list_head *plist, *phead;
1187 char *stop = ev + wrqu->data.length;
1188 u32 ret = 0, cnt = 0;
1190 if (padapter->driver_stopped)
1192 while (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY |
1193 _FW_UNDER_LINKING)) {
1199 spin_lock_irqsave(&queue->lock, irqL);
1200 phead = &queue->queue;
1201 plist = phead->next;
1203 if (end_of_queue_search(phead, plist))
1205 if ((stop - ev) < SCAN_ITEM_SIZE) {
1209 pnetwork = container_of(plist, struct wlan_network, list);
1210 ev = translate_scan(padapter, a, pnetwork, ev, stop);
1211 plist = plist->next;
1213 spin_unlock_irqrestore(&queue->lock, irqL);
1214 wrqu->data.length = ev - extra;
1215 wrqu->data.flags = 0;
1220 * s1. set_802_11_infrastructure_mode()
1221 * s2. set_802_11_authenticaion_mode()
1222 * s3. set_802_11_encryption_mode()
1223 * s4. set_802_11_ssid()
1225 * This function intends to handle the Set ESSID command.
1226 * Currently, the request comes via the Wireless Extensions' SIOCSIWESSID ioctl.
1228 * For this operation to succeed, there is no need for the interface to be Up.
1231 static int r8711_wx_set_essid(struct net_device *dev,
1232 struct iw_request_info *a,
1233 union iwreq_data *wrqu, char *extra)
1235 struct _adapter *padapter = netdev_priv(dev);
1236 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1237 struct __queue *queue = &pmlmepriv->scanned_queue;
1238 struct wlan_network *pnetwork = NULL;
1239 enum NDIS_802_11_AUTHENTICATION_MODE authmode;
1240 struct ndis_802_11_ssid ndis_ssid;
1241 u8 *dst_ssid, *src_ssid;
1242 struct list_head *phead;
1245 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY))
1247 if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING))
1249 if (wrqu->essid.length > IW_ESSID_MAX_SIZE)
1251 authmode = padapter->securitypriv.ndisauthtype;
1252 if (wrqu->essid.flags && wrqu->essid.length) {
1253 len = (wrqu->essid.length < IW_ESSID_MAX_SIZE) ?
1254 wrqu->essid.length : IW_ESSID_MAX_SIZE;
1255 memset(&ndis_ssid, 0, sizeof(struct ndis_802_11_ssid));
1256 ndis_ssid.SsidLength = len;
1257 memcpy(ndis_ssid.Ssid, extra, len);
1258 src_ssid = ndis_ssid.Ssid;
1259 phead = &queue->queue;
1260 pmlmepriv->pscanned = phead->next;
1262 if (end_of_queue_search(phead, pmlmepriv->pscanned))
1264 pnetwork = container_of(pmlmepriv->pscanned,
1265 struct wlan_network, list);
1266 pmlmepriv->pscanned = pmlmepriv->pscanned->next;
1267 dst_ssid = pnetwork->network.Ssid.Ssid;
1268 if ((!memcmp(dst_ssid, src_ssid, ndis_ssid.SsidLength))
1269 && (pnetwork->network.Ssid.SsidLength ==
1270 ndis_ssid.SsidLength)) {
1271 if (check_fwstate(pmlmepriv,
1272 WIFI_ADHOC_STATE)) {
1273 if (pnetwork->network.
1277 cur_network.network.
1282 r8712_set_802_11_infrastructure_mode(
1284 pnetwork->network.InfrastructureMode);
1288 r8712_set_802_11_authentication_mode(padapter, authmode);
1289 r8712_set_802_11_ssid(padapter, &ndis_ssid);
1291 return -EINPROGRESS;
1294 static int r8711_wx_get_essid(struct net_device *dev,
1295 struct iw_request_info *a,
1296 union iwreq_data *wrqu, char *extra)
1298 struct _adapter *padapter = netdev_priv(dev);
1299 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1300 struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
1303 if (check_fwstate(pmlmepriv, _FW_LINKED | WIFI_ADHOC_MASTER_STATE)) {
1304 len = pcur_bss->Ssid.SsidLength;
1305 wrqu->essid.length = len;
1306 memcpy(extra, pcur_bss->Ssid.Ssid, len);
1307 wrqu->essid.flags = 1;
1314 static int r8711_wx_set_rate(struct net_device *dev,
1315 struct iw_request_info *a,
1316 union iwreq_data *wrqu, char *extra)
1318 struct _adapter *padapter = netdev_priv(dev);
1319 u32 target_rate = wrqu->bitrate.value;
1320 u32 fixed = wrqu->bitrate.fixed;
1322 u8 datarates[NumRates];
1323 u8 mpdatarate[NumRates] = {11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0xff};
1326 if (target_rate == -1) {
1330 target_rate = target_rate / 100000;
1331 switch (target_rate) {
1373 for (i = 0; i < NumRates; i++) {
1374 if (ratevalue == mpdatarate[i]) {
1375 datarates[i] = mpdatarate[i];
1379 datarates[i] = 0xff;
1382 return r8712_setdatarate_cmd(padapter, datarates);
1385 static int r8711_wx_get_rate(struct net_device *dev,
1386 struct iw_request_info *info,
1387 union iwreq_data *wrqu, char *extra)
1389 struct _adapter *padapter = netdev_priv(dev);
1390 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1391 struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
1392 struct ieee80211_ht_cap *pht_capie;
1393 unsigned char rf_type = padapter->registrypriv.rf_config;
1396 u16 rate, max_rate = 0, ht_cap = false;
1398 u8 bw_40MHz = 0, short_GI = 0;
1402 if (!check_fwstate(pmlmepriv, _FW_LINKED | WIFI_ADHOC_MASTER_STATE))
1404 p = r8712_get_ie(&pcur_bss->IEs[12], WLAN_EID_HT_CAPABILITY, &ht_ielen,
1405 pcur_bss->IELength - 12);
1406 if (p && ht_ielen > 0) {
1408 pht_capie = (struct ieee80211_ht_cap *)(p + 2);
1409 memcpy(&mcs_rate, &pht_capie->mcs, 2);
1410 bw_40MHz = (le16_to_cpu(pht_capie->cap_info) &
1411 IEEE80211_HT_CAP_SUP_WIDTH_20_40) ? 1 : 0;
1412 short_GI = (le16_to_cpu(pht_capie->cap_info) &
1413 (IEEE80211_HT_CAP_SGI_20 |
1414 IEEE80211_HT_CAP_SGI_40)) ? 1 : 0;
1416 while ((pcur_bss->rates[i] != 0) &&
1417 (pcur_bss->rates[i] != 0xFF)) {
1418 rate = pcur_bss->rates[i] & 0x7F;
1419 if (rate > max_rate)
1421 wrqu->bitrate.fixed = 0; /* no auto select */
1422 wrqu->bitrate.value = rate * 500000;
1426 if (mcs_rate & 0x8000 /* MCS15 */
1428 rf_type == RTL8712_RF_2T2R)
1429 max_rate = (bw_40MHz) ? ((short_GI) ? 300 : 270) :
1430 ((short_GI) ? 144 : 130);
1431 else /* default MCS7 */
1432 max_rate = (bw_40MHz) ? ((short_GI) ? 150 : 135) :
1433 ((short_GI) ? 72 : 65);
1434 max_rate *= 2; /* Mbps/2 */
1436 wrqu->bitrate.value = max_rate * 500000;
1440 static int r8711_wx_get_rts(struct net_device *dev,
1441 struct iw_request_info *info,
1442 union iwreq_data *wrqu, char *extra)
1444 struct _adapter *padapter = netdev_priv(dev);
1446 wrqu->rts.value = padapter->registrypriv.rts_thresh;
1447 wrqu->rts.fixed = 0; /* no auto select */
1451 static int r8711_wx_set_frag(struct net_device *dev,
1452 struct iw_request_info *info,
1453 union iwreq_data *wrqu, char *extra)
1455 struct _adapter *padapter = netdev_priv(dev);
1457 if (wrqu->frag.disabled) {
1458 padapter->xmitpriv.frag_len = MAX_FRAG_THRESHOLD;
1460 if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
1461 wrqu->frag.value > MAX_FRAG_THRESHOLD)
1463 padapter->xmitpriv.frag_len = wrqu->frag.value & ~0x1;
1468 static int r8711_wx_get_frag(struct net_device *dev,
1469 struct iw_request_info *info,
1470 union iwreq_data *wrqu, char *extra)
1472 struct _adapter *padapter = netdev_priv(dev);
1474 wrqu->frag.value = padapter->xmitpriv.frag_len;
1475 wrqu->frag.fixed = 0; /* no auto select */
1479 static int r8711_wx_get_retry(struct net_device *dev,
1480 struct iw_request_info *info,
1481 union iwreq_data *wrqu, char *extra)
1483 wrqu->retry.value = 7;
1484 wrqu->retry.fixed = 0; /* no auto select */
1485 wrqu->retry.disabled = 1;
1489 static int r8711_wx_set_enc(struct net_device *dev,
1490 struct iw_request_info *info,
1491 union iwreq_data *wrqu, char *keybuf)
1494 u32 keyindex_provided;
1495 struct NDIS_802_11_WEP wep;
1496 enum NDIS_802_11_AUTHENTICATION_MODE authmode;
1497 struct iw_point *erq = &(wrqu->encoding);
1498 struct _adapter *padapter = netdev_priv(dev);
1500 key = erq->flags & IW_ENCODE_INDEX;
1501 memset(&wep, 0, sizeof(struct NDIS_802_11_WEP));
1502 if (erq->flags & IW_ENCODE_DISABLED) {
1503 netdev_info(dev, "r8712u: %s: EncryptionDisabled\n", __func__);
1504 padapter->securitypriv.ndisencryptstatus =
1505 Ndis802_11EncryptionDisabled;
1506 padapter->securitypriv.PrivacyAlgrthm = _NO_PRIVACY_;
1507 padapter->securitypriv.XGrpPrivacy = _NO_PRIVACY_;
1508 padapter->securitypriv.AuthAlgrthm = 0; /* open system */
1509 authmode = Ndis802_11AuthModeOpen;
1510 padapter->securitypriv.ndisauthtype = authmode;
1517 keyindex_provided = 1;
1519 keyindex_provided = 0;
1520 key = padapter->securitypriv.PrivacyKeyIndex;
1522 /* set authentication mode */
1523 if (erq->flags & IW_ENCODE_OPEN) {
1524 netdev_info(dev, "r8712u: %s: IW_ENCODE_OPEN\n", __func__);
1525 padapter->securitypriv.ndisencryptstatus =
1526 Ndis802_11Encryption1Enabled;
1527 padapter->securitypriv.AuthAlgrthm = 0; /* open system */
1528 padapter->securitypriv.PrivacyAlgrthm = _NO_PRIVACY_;
1529 padapter->securitypriv.XGrpPrivacy = _NO_PRIVACY_;
1530 authmode = Ndis802_11AuthModeOpen;
1531 padapter->securitypriv.ndisauthtype = authmode;
1532 } else if (erq->flags & IW_ENCODE_RESTRICTED) {
1534 "r8712u: %s: IW_ENCODE_RESTRICTED\n", __func__);
1535 padapter->securitypriv.ndisencryptstatus =
1536 Ndis802_11Encryption1Enabled;
1537 padapter->securitypriv.AuthAlgrthm = 1; /* shared system */
1538 padapter->securitypriv.PrivacyAlgrthm = _WEP40_;
1539 padapter->securitypriv.XGrpPrivacy = _WEP40_;
1540 authmode = Ndis802_11AuthModeShared;
1541 padapter->securitypriv.ndisauthtype = authmode;
1543 padapter->securitypriv.ndisencryptstatus =
1544 Ndis802_11Encryption1Enabled;
1545 padapter->securitypriv.AuthAlgrthm = 0; /* open system */
1546 padapter->securitypriv.PrivacyAlgrthm = _NO_PRIVACY_;
1547 padapter->securitypriv.XGrpPrivacy = _NO_PRIVACY_;
1548 authmode = Ndis802_11AuthModeOpen;
1549 padapter->securitypriv.ndisauthtype = authmode;
1552 if (erq->length > 0) {
1553 wep.KeyLength = erq->length <= 5 ? 5 : 13;
1554 wep.Length = wep.KeyLength +
1555 offsetof(struct NDIS_802_11_WEP, KeyMaterial);
1558 if (keyindex_provided == 1) { /* set key_id only, no given
1559 * KeyMaterial(erq->length==0).
1561 padapter->securitypriv.PrivacyKeyIndex = key;
1562 switch (padapter->securitypriv.DefKeylen[key]) {
1564 padapter->securitypriv.PrivacyAlgrthm =
1568 padapter->securitypriv.PrivacyAlgrthm =
1572 padapter->securitypriv.PrivacyAlgrthm =
1579 wep.KeyIndex |= 0x80000000; /* transmit key */
1580 memcpy(wep.KeyMaterial, keybuf, wep.KeyLength);
1581 if (r8712_set_802_11_add_wep(padapter, &wep))
1586 static int r8711_wx_get_enc(struct net_device *dev,
1587 struct iw_request_info *info,
1588 union iwreq_data *wrqu, char *keybuf)
1591 struct _adapter *padapter = netdev_priv(dev);
1592 struct iw_point *erq = &(wrqu->encoding);
1593 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1594 union Keytype *dk = padapter->securitypriv.DefKey;
1596 if (!check_fwstate(pmlmepriv, _FW_LINKED)) {
1597 if (!check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) {
1599 erq->flags |= IW_ENCODE_DISABLED;
1603 key = erq->flags & IW_ENCODE_INDEX;
1609 key = padapter->securitypriv.PrivacyKeyIndex;
1611 erq->flags = key + 1;
1612 switch (padapter->securitypriv.ndisencryptstatus) {
1613 case Ndis802_11EncryptionNotSupported:
1614 case Ndis802_11EncryptionDisabled:
1616 erq->flags |= IW_ENCODE_DISABLED;
1618 case Ndis802_11Encryption1Enabled:
1619 erq->length = padapter->securitypriv.DefKeylen[key];
1621 memcpy(keybuf, dk[key].skey,
1622 padapter->securitypriv.DefKeylen[key]);
1623 erq->flags |= IW_ENCODE_ENABLED;
1624 if (padapter->securitypriv.ndisauthtype ==
1625 Ndis802_11AuthModeOpen)
1626 erq->flags |= IW_ENCODE_OPEN;
1627 else if (padapter->securitypriv.ndisauthtype ==
1628 Ndis802_11AuthModeShared)
1629 erq->flags |= IW_ENCODE_RESTRICTED;
1632 erq->flags |= IW_ENCODE_DISABLED;
1635 case Ndis802_11Encryption2Enabled:
1636 case Ndis802_11Encryption3Enabled:
1638 erq->flags |= (IW_ENCODE_ENABLED | IW_ENCODE_OPEN |
1643 erq->flags |= IW_ENCODE_DISABLED;
1649 static int r8711_wx_get_power(struct net_device *dev,
1650 struct iw_request_info *info,
1651 union iwreq_data *wrqu, char *extra)
1653 wrqu->power.value = 0;
1654 wrqu->power.fixed = 0; /* no auto select */
1655 wrqu->power.disabled = 1;
1659 static int r871x_wx_set_gen_ie(struct net_device *dev,
1660 struct iw_request_info *info,
1661 union iwreq_data *wrqu, char *extra)
1663 struct _adapter *padapter = netdev_priv(dev);
1665 return r871x_set_wpa_ie(padapter, extra, wrqu->data.length);
1668 static int r871x_wx_set_auth(struct net_device *dev,
1669 struct iw_request_info *info,
1670 union iwreq_data *wrqu, char *extra)
1672 struct _adapter *padapter = netdev_priv(dev);
1673 struct iw_param *param = (struct iw_param *)&(wrqu->param);
1678 paramid = param->flags & IW_AUTH_INDEX;
1679 paramval = param->value;
1681 case IW_AUTH_WPA_VERSION:
1683 case IW_AUTH_CIPHER_PAIRWISE:
1685 case IW_AUTH_CIPHER_GROUP:
1687 case IW_AUTH_KEY_MGMT:
1689 * ??? does not use these parameters
1692 case IW_AUTH_TKIP_COUNTERMEASURES:
1694 /* wpa_supplicant is enabling tkip countermeasure. */
1695 padapter->securitypriv.btkip_countermeasure = true;
1697 /* wpa_supplicant is disabling tkip countermeasure. */
1698 padapter->securitypriv.btkip_countermeasure = false;
1701 case IW_AUTH_DROP_UNENCRYPTED:
1704 * wpa_supplicant calls set_wpa_enabled when the driver
1705 * is loaded and unloaded, regardless of if WPA is being
1706 * used. No other calls are made which can be used to
1707 * determine if encryption will be used or not prior to
1708 * association being expected. If encryption is not being
1709 * used, drop_unencrypted is set to false, else true -- we
1710 * can use this to determine if the CAP_PRIVACY_ON bit should
1713 if (padapter->securitypriv.ndisencryptstatus ==
1714 Ndis802_11Encryption1Enabled) {
1715 /* it means init value, or using wep,
1716 * ndisencryptstatus =
1717 * Ndis802_11Encryption1Enabled,
1718 * then it needn't reset it;
1724 padapter->securitypriv.ndisencryptstatus =
1725 Ndis802_11EncryptionDisabled;
1726 padapter->securitypriv.PrivacyAlgrthm =
1728 padapter->securitypriv.XGrpPrivacy =
1730 padapter->securitypriv.AuthAlgrthm = 0;
1731 padapter->securitypriv.ndisauthtype =
1732 Ndis802_11AuthModeOpen;
1735 case IW_AUTH_80211_AUTH_ALG:
1736 ret = wpa_set_auth_algs(dev, (u32)paramval);
1738 case IW_AUTH_WPA_ENABLED:
1740 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
1742 case IW_AUTH_PRIVACY_INVOKED:
1751 static int r871x_wx_set_enc_ext(struct net_device *dev,
1752 struct iw_request_info *info,
1753 union iwreq_data *wrqu, char *extra)
1755 struct iw_point *pencoding = &wrqu->encoding;
1756 struct iw_encode_ext *pext = (struct iw_encode_ext *)extra;
1757 struct ieee_param *param = NULL;
1762 switch (pext->alg) {
1763 case IW_ENCODE_ALG_NONE:
1766 case IW_ENCODE_ALG_WEP:
1769 case IW_ENCODE_ALG_TKIP:
1772 case IW_ENCODE_ALG_CCMP:
1779 param_len = sizeof(struct ieee_param) + pext->key_len;
1780 param = kzalloc(param_len, GFP_ATOMIC);
1783 param->cmd = IEEE_CMD_SET_ENCRYPTION;
1784 eth_broadcast_addr(param->sta_addr);
1785 strscpy((char *)param->u.crypt.alg, alg_name, IEEE_CRYPT_ALG_NAME_LEN);
1786 if (pext->ext_flags & IW_ENCODE_EXT_GROUP_KEY)
1787 param->u.crypt.set_tx = 0;
1788 if (pext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
1789 param->u.crypt.set_tx = 1;
1790 param->u.crypt.idx = (pencoding->flags & 0x00FF) - 1;
1791 if (pext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID)
1792 memcpy(param->u.crypt.seq, pext->rx_seq, 8);
1793 if (pext->key_len) {
1794 param->u.crypt.key_len = pext->key_len;
1795 memcpy(param + 1, pext + 1, pext->key_len);
1797 ret = wpa_set_encryption(dev, param, param_len);
1802 static int r871x_wx_get_nick(struct net_device *dev,
1803 struct iw_request_info *info,
1804 union iwreq_data *wrqu, char *extra)
1807 wrqu->data.length = 8;
1808 wrqu->data.flags = 1;
1809 memcpy(extra, "rtl_wifi", 8);
1814 static int r8711_wx_read32(struct net_device *dev,
1815 struct iw_request_info *info,
1816 union iwreq_data *wrqu, char *keybuf)
1818 struct _adapter *padapter = netdev_priv(dev);
1822 get_user(addr, (u32 __user *)wrqu->data.pointer);
1823 data32 = r8712_read32(padapter, addr);
1824 put_user(data32, (u32 __user *)wrqu->data.pointer);
1825 wrqu->data.length = (data32 & 0xffff0000) >> 16;
1826 wrqu->data.flags = data32 & 0xffff;
1827 get_user(addr, (u32 __user *)wrqu->data.pointer);
1831 static int r8711_wx_write32(struct net_device *dev,
1832 struct iw_request_info *info,
1833 union iwreq_data *wrqu, char *keybuf)
1835 struct _adapter *padapter = netdev_priv(dev);
1839 get_user(addr, (u32 __user *)wrqu->data.pointer);
1840 data32 = ((u32)wrqu->data.length << 16) | (u32)wrqu->data.flags;
1841 r8712_write32(padapter, addr, data32);
1845 static int dummy(struct net_device *dev,
1846 struct iw_request_info *a,
1847 union iwreq_data *wrqu, char *b)
1852 static int r8711_drvext_hdl(struct net_device *dev,
1853 struct iw_request_info *info,
1854 union iwreq_data *wrqu, char *extra)
1859 static int r871x_mp_ioctl_hdl(struct net_device *dev,
1860 struct iw_request_info *info,
1861 union iwreq_data *wrqu, char *extra)
1863 struct _adapter *padapter = netdev_priv(dev);
1864 struct iw_point *p = &wrqu->data;
1865 struct oid_par_priv oid_par;
1866 struct mp_ioctl_handler *phandler;
1867 struct mp_ioctl_param *poidparam;
1868 unsigned long BytesRead, BytesWritten, BytesNeeded;
1874 if ((!p->length) || (!p->pointer))
1877 bset = (u8)(p->flags & 0xFFFF);
1879 pparmbuf = memdup_user(p->pointer, len);
1880 if (IS_ERR(pparmbuf))
1881 return PTR_ERR(pparmbuf);
1883 poidparam = (struct mp_ioctl_param *)pparmbuf;
1884 if (poidparam->subcode >= MAX_MP_IOCTL_SUBCODE) {
1886 goto _r871x_mp_ioctl_hdl_exit;
1888 phandler = mp_ioctl_hdl + poidparam->subcode;
1889 if ((phandler->paramsize != 0) &&
1890 (poidparam->len < phandler->paramsize)) {
1892 goto _r871x_mp_ioctl_hdl_exit;
1894 if (phandler->oid == 0 && phandler->handler) {
1895 status = phandler->handler(&oid_par);
1896 } else if (phandler->handler) {
1897 oid_par.adapter_context = padapter;
1898 oid_par.oid = phandler->oid;
1899 oid_par.information_buf = poidparam->data;
1900 oid_par.information_buf_len = poidparam->len;
1905 oid_par.bytes_rw = &BytesRead;
1906 oid_par.bytes_needed = &BytesNeeded;
1907 oid_par.type_of_oid = SET_OID;
1909 oid_par.bytes_rw = &BytesWritten;
1910 oid_par.bytes_needed = &BytesNeeded;
1911 oid_par.type_of_oid = QUERY_OID;
1913 status = phandler->handler(&oid_par);
1914 /* todo:check status, BytesNeeded, etc. */
1916 netdev_info(dev, "r8712u: %s: err!, subcode=%d, oid=%d, handler=%p\n",
1917 __func__, poidparam->subcode, phandler->oid,
1920 goto _r871x_mp_ioctl_hdl_exit;
1922 if (bset == 0x00) { /* query info */
1923 if (copy_to_user(p->pointer, pparmbuf, len))
1928 goto _r871x_mp_ioctl_hdl_exit;
1930 _r871x_mp_ioctl_hdl_exit:
1935 static int r871x_get_ap_info(struct net_device *dev,
1936 struct iw_request_info *info,
1937 union iwreq_data *wrqu, char *extra)
1939 struct _adapter *padapter = netdev_priv(dev);
1940 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1941 struct __queue *queue = &pmlmepriv->scanned_queue;
1942 struct iw_point *pdata = &wrqu->data;
1943 struct wlan_network *pnetwork = NULL;
1944 u32 cnt = 0, wpa_ielen;
1946 struct list_head *plist, *phead;
1947 unsigned char *pbuf;
1951 if (padapter->driver_stopped || !pdata)
1953 while (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY |
1954 _FW_UNDER_LINKING)) {
1961 if (pdata->length < 32)
1963 if (copy_from_user(data, pdata->pointer, 32))
1967 spin_lock_irqsave(&(pmlmepriv->scanned_queue.lock), irqL);
1968 phead = &queue->queue;
1969 plist = phead->next;
1971 if (end_of_queue_search(phead, plist))
1973 pnetwork = container_of(plist, struct wlan_network, list);
1974 if (!mac_pton(data, bssid)) {
1975 netdev_info(dev, "r8712u: Invalid BSSID '%s'.\n",
1977 spin_unlock_irqrestore(&(pmlmepriv->scanned_queue.lock),
1981 netdev_info(dev, "r8712u: BSSID:%pM\n", bssid);
1982 if (ether_addr_equal(bssid, pnetwork->network.MacAddress)) {
1983 /* BSSID match, then check if supporting wpa/wpa2 */
1984 pbuf = r8712_get_wpa_ie(&pnetwork->network.IEs[12],
1985 &wpa_ielen, pnetwork->network.IELength - 12);
1986 if (pbuf && (wpa_ielen > 0)) {
1990 pbuf = r8712_get_wpa2_ie(&pnetwork->network.IEs[12],
1991 &wpa_ielen, pnetwork->network.IELength - 12);
1992 if (pbuf && (wpa_ielen > 0)) {
1997 plist = plist->next;
1999 spin_unlock_irqrestore(&(pmlmepriv->scanned_queue.lock), irqL);
2000 if (pdata->length >= 34) {
2001 if (copy_to_user((u8 __user *)pdata->pointer + 32,
2002 (u8 *)&pdata->flags, 1))
2008 static int r871x_set_pid(struct net_device *dev,
2009 struct iw_request_info *info,
2010 union iwreq_data *wrqu, char *extra)
2012 struct _adapter *padapter = netdev_priv(dev);
2013 struct iw_point *pdata = &wrqu->data;
2015 if (padapter->driver_stopped || !pdata)
2017 if (copy_from_user(&padapter->pid, pdata->pointer, sizeof(int)))
2022 static int r871x_set_chplan(struct net_device *dev,
2023 struct iw_request_info *info,
2024 union iwreq_data *wrqu, char *extra)
2027 struct _adapter *padapter = netdev_priv(dev);
2028 struct iw_point *pdata = &wrqu->data;
2031 if (padapter->driver_stopped || !pdata) {
2035 ch_plan = (int)*extra;
2036 r8712_set_chplan_cmd(padapter, ch_plan);
2043 static int r871x_wps_start(struct net_device *dev,
2044 struct iw_request_info *info,
2045 union iwreq_data *wrqu, char *extra)
2047 struct _adapter *padapter = netdev_priv(dev);
2048 struct iw_point *pdata = &wrqu->data;
2049 u32 u32wps_start = 0;
2051 if (padapter->driver_stopped || !pdata)
2053 if (copy_from_user((void *)&u32wps_start, pdata->pointer, 4))
2055 if (u32wps_start == 0)
2056 u32wps_start = *extra;
2057 if (u32wps_start == 1) /* WPS Start */
2058 padapter->ledpriv.LedControlHandler(padapter,
2060 else if (u32wps_start == 2) /* WPS Stop because of wps success */
2061 padapter->ledpriv.LedControlHandler(padapter,
2063 else if (u32wps_start == 3) /* WPS Stop because of wps fail */
2064 padapter->ledpriv.LedControlHandler(padapter,
2065 LED_CTL_STOP_WPS_FAIL);
2069 static int wpa_set_param(struct net_device *dev, u8 name, u32 value)
2071 struct _adapter *padapter = netdev_priv(dev);
2074 case IEEE_PARAM_WPA_ENABLED:
2075 padapter->securitypriv.AuthAlgrthm = 2; /* 802.1x */
2076 switch ((value) & 0xff) {
2078 padapter->securitypriv.ndisauthtype =
2079 Ndis802_11AuthModeWPAPSK; /* WPA_PSK */
2080 padapter->securitypriv.ndisencryptstatus =
2081 Ndis802_11Encryption2Enabled;
2084 padapter->securitypriv.ndisauthtype =
2085 Ndis802_11AuthModeWPA2PSK; /* WPA2_PSK */
2086 padapter->securitypriv.ndisencryptstatus =
2087 Ndis802_11Encryption3Enabled;
2091 case IEEE_PARAM_TKIP_COUNTERMEASURES:
2093 case IEEE_PARAM_DROP_UNENCRYPTED:
2096 * wpa_supplicant calls set_wpa_enabled when the driver
2097 * is loaded and unloaded, regardless of if WPA is being
2098 * used. No other calls are made which can be used to
2099 * determine if encryption will be used or not prior to
2100 * association being expected. If encryption is not being
2101 * used, drop_unencrypted is set to false, else true -- we
2102 * can use this to determine if the CAP_PRIVACY_ON bit should
2106 case IEEE_PARAM_PRIVACY_INVOKED:
2108 case IEEE_PARAM_AUTH_ALGS:
2109 return wpa_set_auth_algs(dev, value);
2110 case IEEE_PARAM_IEEE_802_1X:
2112 case IEEE_PARAM_WPAX_SELECT:
2113 /* added for WPA2 mixed mode */
2121 static int wpa_mlme(struct net_device *dev, u32 command, u32 reason)
2123 struct _adapter *padapter = netdev_priv(dev);
2126 case IEEE_MLME_STA_DEAUTH:
2127 if (!r8712_set_802_11_disassociate(padapter))
2130 case IEEE_MLME_STA_DISASSOC:
2131 if (!r8712_set_802_11_disassociate(padapter))
2140 static int wpa_supplicant_ioctl(struct net_device *dev, struct iw_point *p)
2142 struct ieee_param *param;
2144 struct _adapter *padapter = netdev_priv(dev);
2146 if (p->length < sizeof(struct ieee_param) || !p->pointer)
2148 param = memdup_user(p->pointer, p->length);
2150 return PTR_ERR(param);
2151 switch (param->cmd) {
2152 case IEEE_CMD_SET_WPA_PARAM:
2153 ret = wpa_set_param(dev, param->u.wpa_param.name,
2154 param->u.wpa_param.value);
2156 case IEEE_CMD_SET_WPA_IE:
2157 ret = r871x_set_wpa_ie(padapter, (char *)param->u.wpa_ie.data,
2158 (u16)param->u.wpa_ie.len);
2160 case IEEE_CMD_SET_ENCRYPTION:
2161 ret = wpa_set_encryption(dev, param, p->length);
2164 ret = wpa_mlme(dev, param->u.mlme.command,
2165 param->u.mlme.reason_code);
2171 if (ret == 0 && copy_to_user(p->pointer, param, p->length))
2177 /* based on "driver_ipw" and for hostapd */
2178 int r871x_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
2180 struct iwreq *wrq = (struct iwreq *)rq;
2183 case RTL_IOCTL_WPA_SUPPLICANT:
2184 return wpa_supplicant_ioctl(dev, &wrq->u.data);
2191 static iw_handler r8711_handlers[] = {
2192 NULL, /* SIOCSIWCOMMIT */
2193 r8711_wx_get_name, /* SIOCGIWNAME */
2194 dummy, /* SIOCSIWNWID */
2195 dummy, /* SIOCGIWNWID */
2196 r8711_wx_set_freq, /* SIOCSIWFREQ */
2197 r8711_wx_get_freq, /* SIOCGIWFREQ */
2198 r8711_wx_set_mode, /* SIOCSIWMODE */
2199 r8711_wx_get_mode, /* SIOCGIWMODE */
2200 dummy, /* SIOCSIWSENS */
2201 r8711_wx_get_sens, /* SIOCGIWSENS */
2202 NULL, /* SIOCSIWRANGE */
2203 r8711_wx_get_range, /* SIOCGIWRANGE */
2204 r871x_wx_set_priv, /* SIOCSIWPRIV */
2205 NULL, /* SIOCGIWPRIV */
2206 NULL, /* SIOCSIWSTATS */
2207 NULL, /* SIOCGIWSTATS */
2208 dummy, /* SIOCSIWSPY */
2209 dummy, /* SIOCGIWSPY */
2210 NULL, /* SIOCGIWTHRSPY */
2211 NULL, /* SIOCWIWTHRSPY */
2212 r8711_wx_set_wap, /* SIOCSIWAP */
2213 r8711_wx_get_wap, /* SIOCGIWAP */
2214 r871x_wx_set_mlme, /* request MLME operation;
2215 * uses struct iw_mlme
2217 dummy, /* SIOCGIWAPLIST -- deprecated */
2218 r8711_wx_set_scan, /* SIOCSIWSCAN */
2219 r8711_wx_get_scan, /* SIOCGIWSCAN */
2220 r8711_wx_set_essid, /* SIOCSIWESSID */
2221 r8711_wx_get_essid, /* SIOCGIWESSID */
2222 dummy, /* SIOCSIWNICKN */
2223 r871x_wx_get_nick, /* SIOCGIWNICKN */
2224 NULL, /* -- hole -- */
2225 NULL, /* -- hole -- */
2226 r8711_wx_set_rate, /* SIOCSIWRATE */
2227 r8711_wx_get_rate, /* SIOCGIWRATE */
2228 dummy, /* SIOCSIWRTS */
2229 r8711_wx_get_rts, /* SIOCGIWRTS */
2230 r8711_wx_set_frag, /* SIOCSIWFRAG */
2231 r8711_wx_get_frag, /* SIOCGIWFRAG */
2232 dummy, /* SIOCSIWTXPOW */
2233 dummy, /* SIOCGIWTXPOW */
2234 dummy, /* SIOCSIWRETRY */
2235 r8711_wx_get_retry, /* SIOCGIWRETRY */
2236 r8711_wx_set_enc, /* SIOCSIWENCODE */
2237 r8711_wx_get_enc, /* SIOCGIWENCODE */
2238 dummy, /* SIOCSIWPOWER */
2239 r8711_wx_get_power, /* SIOCGIWPOWER */
2240 NULL, /*---hole---*/
2241 NULL, /*---hole---*/
2242 r871x_wx_set_gen_ie, /* SIOCSIWGENIE */
2243 NULL, /* SIOCGIWGENIE */
2244 r871x_wx_set_auth, /* SIOCSIWAUTH */
2245 NULL, /* SIOCGIWAUTH */
2246 r871x_wx_set_enc_ext, /* SIOCSIWENCODEEXT */
2247 NULL, /* SIOCGIWENCODEEXT */
2248 r871x_wx_set_pmkid, /* SIOCSIWPMKSA */
2249 NULL, /*---hole---*/
2252 static const struct iw_priv_args r8711_private_args[] = {
2254 SIOCIWFIRSTPRIV + 0x0,
2255 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "read32"
2258 SIOCIWFIRSTPRIV + 0x1,
2259 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "write32"
2262 SIOCIWFIRSTPRIV + 0x2, 0, 0, "driver_ext"
2265 SIOCIWFIRSTPRIV + 0x3, 0, 0, "mp_ioctl"
2268 SIOCIWFIRSTPRIV + 0x4,
2269 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "apinfo"
2272 SIOCIWFIRSTPRIV + 0x5,
2273 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setpid"
2276 SIOCIWFIRSTPRIV + 0x6,
2277 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wps_start"
2280 SIOCIWFIRSTPRIV + 0x7,
2281 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "chplan"
2285 static iw_handler r8711_private_handler[] = {
2290 r871x_get_ap_info, /*for MM DTV platform*/
2296 static struct iw_statistics *r871x_get_wireless_stats(struct net_device *dev)
2298 struct _adapter *padapter = netdev_priv(dev);
2299 struct iw_statistics *piwstats = &padapter->iwstats;
2304 if (check_fwstate(&padapter->mlmepriv, _FW_LINKED) != true) {
2305 piwstats->qual.qual = 0;
2306 piwstats->qual.level = 0;
2307 piwstats->qual.noise = 0;
2309 /* show percentage, we need transfer dbm to original value. */
2310 tmp_level = padapter->recvpriv.fw_rssi;
2311 tmp_qual = padapter->recvpriv.signal;
2312 tmp_noise = padapter->recvpriv.noise;
2313 piwstats->qual.level = tmp_level;
2314 piwstats->qual.qual = tmp_qual;
2315 piwstats->qual.noise = tmp_noise;
2317 piwstats->qual.updated = IW_QUAL_ALL_UPDATED;
2318 return &padapter->iwstats;
2321 struct iw_handler_def r871x_handlers_def = {
2322 .standard = r8711_handlers,
2323 .num_standard = ARRAY_SIZE(r8711_handlers),
2324 .private = r8711_private_handler,
2325 .private_args = (struct iw_priv_args *)r8711_private_args,
2326 .num_private = ARRAY_SIZE(r8711_private_handler),
2327 .num_private_args = sizeof(r8711_private_args) /
2328 sizeof(struct iw_priv_args),
2329 .get_wireless_stats = r871x_get_wireless_stats