1 /******************************************************************************
2 * rtl871x_ioctl_linux.c
4 * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
5 * Linux device driver for RTL8192SU
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of version 2 of the GNU General Public License as
9 * published by the Free Software Foundation.
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 * You should have received a copy of the GNU General Public License along with
17 * this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
20 * Modifications for inclusion into the Linux staging tree are
21 * Copyright(c) 2010 Larry Finger. All rights reserved.
23 * Contact information:
24 * WLAN FAE <wlanfae@realtek.com>
25 * Larry Finger <Larry.Finger@lwfinger.net>
27 ******************************************************************************/
29 #define _RTL871X_IOCTL_LINUX_C_
30 #define _RTL871X_MP_IOCTL_C_
32 #include "osdep_service.h"
33 #include "drv_types.h"
34 #include "wlan_bssdef.h"
35 #include "rtl871x_debug.h"
37 #include "rtl871x_mlme.h"
38 #include "rtl871x_ioctl.h"
39 #include "rtl871x_ioctl_set.h"
40 #include "rtl871x_mp_ioctl.h"
41 #include "mlme_osdep.h"
42 #include <linux/wireless.h>
43 #include <linux/module.h>
44 #include <linux/kernel.h>
46 #include <linux/semaphore.h>
47 #include <net/iw_handler.h>
48 #include <linux/if_arp.h>
49 #include <linux/etherdevice.h>
52 #define RTL_IOCTL_WPA_SUPPLICANT (SIOCIWFIRSTPRIV + 0x1E)
54 #define SCAN_ITEM_SIZE 768
55 #define MAX_CUSTOM_LEN 64
59 static const u32 rtl8180_rates[] = {1000000, 2000000, 5500000, 11000000,
60 6000000, 9000000, 12000000, 18000000,
61 24000000, 36000000, 48000000, 54000000};
63 static const long ieee80211_wlan_frequencies[] = {
64 2412, 2417, 2422, 2427,
65 2432, 2437, 2442, 2447,
66 2452, 2457, 2462, 2467,
70 static const char * const iw_operation_mode[] = {
71 "Auto", "Ad-Hoc", "Managed", "Master", "Repeater", "Secondary",
75 void r8712_indicate_wx_assoc_event(struct _adapter *padapter)
77 union iwreq_data wrqu;
78 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
80 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
81 memcpy(wrqu.ap_addr.sa_data, pmlmepriv->cur_network.network.MacAddress,
83 wireless_send_event(padapter->pnetdev, SIOCGIWAP, &wrqu, NULL);
86 void r8712_indicate_wx_disassoc_event(struct _adapter *padapter)
88 union iwreq_data wrqu;
90 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
91 eth_zero_addr(wrqu.ap_addr.sa_data);
92 wireless_send_event(padapter->pnetdev, SIOCGIWAP, &wrqu, NULL);
95 static inline void handle_pairwise_key(struct sta_info *psta,
96 struct ieee_param *param,
97 struct _adapter *padapter)
100 memcpy(psta->x_UncstKey.skey, param->u.crypt.key,
101 (param->u.crypt. key_len > 16 ? 16 : param->u.crypt.key_len));
102 if (strcmp(param->u.crypt.alg, "TKIP") == 0) { /* set mic key */
103 memcpy(psta->tkiptxmickey. skey, &(param->u.crypt.
105 memcpy(psta->tkiprxmickey. skey, &(param->u.crypt.
107 padapter->securitypriv. busetkipkey = false;
108 mod_timer(&padapter->securitypriv.tkip_timer,
109 jiffies + msecs_to_jiffies(50));
111 r8712_setstakey_cmd(padapter, (unsigned char *)psta, true);
114 static inline void handle_group_key(struct ieee_param *param,
115 struct _adapter *padapter)
117 if (param->u.crypt.idx > 0 &&
118 param->u.crypt.idx < 3) {
119 /* group key idx is 1 or 2 */
120 memcpy(padapter->securitypriv.XGrpKey[param->u.crypt.
121 idx-1].skey, param->u.crypt.key, (param->u.crypt.key_len
122 > 16 ? 16 : param->u.crypt.key_len));
123 memcpy(padapter->securitypriv.XGrptxmickey[param->
124 u.crypt.idx-1].skey, &(param->u.crypt.key[16]), 8);
125 memcpy(padapter->securitypriv. XGrprxmickey[param->
126 u.crypt.idx-1].skey, &(param->u.crypt.key[24]), 8);
127 padapter->securitypriv.binstallGrpkey = true;
128 r8712_set_key(padapter, &padapter->securitypriv,
130 if (padapter->registrypriv.power_mgnt > PS_MODE_ACTIVE) {
131 if (padapter->registrypriv.power_mgnt != padapter->
132 pwrctrlpriv.pwr_mode)
133 mod_timer(&padapter->mlmepriv.dhcp_timer,
134 jiffies + msecs_to_jiffies(60000));
139 static inline char *translate_scan(struct _adapter *padapter,
140 struct iw_request_info *info,
141 struct wlan_network *pnetwork,
142 char *start, char *stop)
145 struct ieee80211_ht_cap *pht_capie;
148 u32 i = 0, ht_ielen = 0;
149 u16 cap, ht_cap = false, mcs_rate;
152 if ((pnetwork->network.Configuration.DSConfig < 1) ||
153 (pnetwork->network.Configuration.DSConfig > 14)) {
154 if (pnetwork->network.Configuration.DSConfig < 1)
155 pnetwork->network.Configuration.DSConfig = 1;
157 pnetwork->network.Configuration.DSConfig = 14;
161 iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
162 ether_addr_copy(iwe.u.ap_addr.sa_data, pnetwork->network.MacAddress);
163 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_ADDR_LEN);
165 iwe.cmd = SIOCGIWESSID;
166 iwe.u.data.flags = 1;
167 iwe.u.data.length = min_t(u32, pnetwork->network.Ssid.SsidLength, 32);
168 start = iwe_stream_add_point(info, start, stop, &iwe,
169 pnetwork->network.Ssid.Ssid);
170 /* parsing HT_CAP_IE */
171 p = r8712_get_ie(&pnetwork->network.IEs[12], _HT_CAPABILITY_IE_,
172 &ht_ielen, pnetwork->network.IELength - 12);
173 if (p && ht_ielen > 0) {
175 pht_capie = (struct ieee80211_ht_cap *)(p + 2);
176 memcpy(&mcs_rate, pht_capie->supp_mcs_set, 2);
178 /* Add the protocol name */
179 iwe.cmd = SIOCGIWNAME;
180 if (r8712_is_cckratesonly_included(pnetwork->network.rates)) {
182 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bn");
184 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11b");
185 } else if (r8712_is_cckrates_included(pnetwork->network.rates)) {
187 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bgn");
189 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bg");
192 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11gn");
194 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11g");
196 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_CHAR_LEN);
198 iwe.cmd = SIOCGIWMODE;
199 memcpy((u8 *)&cap, r8712_get_capability_from_ie(pnetwork->network.IEs),
201 cap = le16_to_cpu(cap);
202 if (cap & (WLAN_CAPABILITY_IBSS|WLAN_CAPABILITY_BSS)) {
203 if (cap & WLAN_CAPABILITY_BSS)
204 iwe.u.mode = (u32)IW_MODE_MASTER;
206 iwe.u.mode = (u32)IW_MODE_ADHOC;
207 start = iwe_stream_add_event(info, start, stop, &iwe,
210 /* Add frequency/channel */
211 iwe.cmd = SIOCGIWFREQ;
213 /* check legal index */
214 u8 dsconfig = pnetwork->network.Configuration.DSConfig;
216 if (dsconfig >= 1 && dsconfig <= sizeof(
217 ieee80211_wlan_frequencies) / sizeof(long))
218 iwe.u.freq.m = (s32)(ieee80211_wlan_frequencies[
219 pnetwork->network.Configuration.
220 DSConfig - 1] * 100000);
224 iwe.u.freq.e = (s16)1;
225 iwe.u.freq.i = (u8)pnetwork->network.Configuration.DSConfig;
226 start = iwe_stream_add_event(info, start, stop, &iwe,
228 /* Add encryption capability */
229 iwe.cmd = SIOCGIWENCODE;
230 if (cap & WLAN_CAPABILITY_PRIVACY)
231 iwe.u.data.flags = (u16)(IW_ENCODE_ENABLED |
234 iwe.u.data.flags = (u16)(IW_ENCODE_DISABLED);
235 iwe.u.data.length = (u16)0;
236 start = iwe_stream_add_point(info, start, stop, &iwe,
237 pnetwork->network.Ssid.Ssid);
238 /*Add basic and extended rates */
239 current_val = start + iwe_stream_lcp_len(info);
240 iwe.cmd = SIOCGIWRATE;
241 iwe.u.bitrate.fixed = 0;
242 iwe.u.bitrate.disabled = 0;
243 iwe.u.bitrate.value = 0;
245 while (pnetwork->network.rates[i] != 0) {
246 /* Bit rate given in 500 kb/s units */
247 iwe.u.bitrate.value = (pnetwork->network.rates[i++] &
249 current_val = iwe_stream_add_value(info, start, current_val,
250 stop, &iwe, IW_EV_PARAM_LEN);
252 /* Check if we added any event */
253 if ((current_val - start) > iwe_stream_lcp_len(info))
255 /* parsing WPA/WPA2 IE */
257 u8 buf[MAX_WPA_IE_LEN];
258 u8 wpa_ie[255], rsn_ie[255];
259 u16 wpa_len = 0, rsn_len = 0;
262 r8712_get_sec_ie(pnetwork->network.IEs,
263 pnetwork->network.IELength, rsn_ie, &rsn_len,
266 memset(buf, 0, MAX_WPA_IE_LEN);
267 n = sprintf(buf, "wpa_ie=");
268 for (i = 0; i < wpa_len; i++) {
269 n += snprintf(buf + n, MAX_WPA_IE_LEN - n,
271 if (n >= MAX_WPA_IE_LEN)
274 memset(&iwe, 0, sizeof(iwe));
275 iwe.cmd = IWEVCUSTOM;
276 iwe.u.data.length = (u16)strlen(buf);
277 start = iwe_stream_add_point(info, start, stop,
279 memset(&iwe, 0, sizeof(iwe));
281 iwe.u.data.length = (u16)wpa_len;
282 start = iwe_stream_add_point(info, start, stop,
286 memset(buf, 0, MAX_WPA_IE_LEN);
287 n = sprintf(buf, "rsn_ie=");
288 for (i = 0; i < rsn_len; i++) {
289 n += snprintf(buf + n, MAX_WPA_IE_LEN - n,
291 if (n >= MAX_WPA_IE_LEN)
294 memset(&iwe, 0, sizeof(iwe));
295 iwe.cmd = IWEVCUSTOM;
296 iwe.u.data.length = strlen(buf);
297 start = iwe_stream_add_point(info, start, stop,
299 memset(&iwe, 0, sizeof(iwe));
301 iwe.u.data.length = rsn_len;
302 start = iwe_stream_add_point(info, start, stop, &iwe,
307 { /* parsing WPS IE */
311 if (r8712_get_wps_ie(pnetwork->network.IEs,
312 pnetwork->network.IELength,
313 wps_ie, &wps_ielen) == true) {
316 iwe.u.data.length = (u16)wps_ielen;
317 start = iwe_stream_add_point(info, start, stop,
322 /* Add quality statistics */
324 rssi = r8712_signal_scale_mapping(pnetwork->network.Rssi);
325 /* we only update signal_level (signal strength) that is rssi. */
326 iwe.u.qual.updated = (u8)(IW_QUAL_QUAL_INVALID | IW_QUAL_LEVEL_UPDATED |
327 IW_QUAL_NOISE_INVALID);
328 iwe.u.qual.level = rssi; /* signal strength */
329 iwe.u.qual.qual = 0; /* signal quality */
330 iwe.u.qual.noise = 0; /* noise level */
331 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_QUAL_LEN);
332 /* how to translate rssi to ?% */
336 static int wpa_set_auth_algs(struct net_device *dev, u32 value)
338 struct _adapter *padapter = netdev_priv(dev);
341 if ((value & AUTH_ALG_SHARED_KEY) && (value & AUTH_ALG_OPEN_SYSTEM)) {
342 padapter->securitypriv.ndisencryptstatus =
343 Ndis802_11Encryption1Enabled;
344 padapter->securitypriv.ndisauthtype =
345 Ndis802_11AuthModeAutoSwitch;
346 padapter->securitypriv.AuthAlgrthm = 3;
347 } else if (value & AUTH_ALG_SHARED_KEY) {
348 padapter->securitypriv.ndisencryptstatus =
349 Ndis802_11Encryption1Enabled;
350 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeShared;
351 padapter->securitypriv.AuthAlgrthm = 1;
352 } else if (value & AUTH_ALG_OPEN_SYSTEM) {
353 if (padapter->securitypriv.ndisauthtype <
354 Ndis802_11AuthModeWPAPSK) {
355 padapter->securitypriv.ndisauthtype =
356 Ndis802_11AuthModeOpen;
357 padapter->securitypriv.AuthAlgrthm = 0;
364 static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param,
368 u32 wep_key_idx, wep_key_len = 0;
369 struct NDIS_802_11_WEP *pwep = NULL;
370 struct _adapter *padapter = netdev_priv(dev);
371 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
372 struct security_priv *psecuritypriv = &padapter->securitypriv;
374 param->u.crypt.err = 0;
375 param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
376 if (param_len != (u32)((u8 *) param->u.crypt.key - (u8 *)param) +
377 param->u.crypt.key_len)
379 if (is_broadcast_ether_addr(param->sta_addr)) {
380 if (param->u.crypt.idx >= WEP_KEYS) {
381 /* for large key indices, set the default (0) */
382 param->u.crypt.idx = 0;
386 if (strcmp(param->u.crypt.alg, "WEP") == 0) {
387 netdev_info(dev, "r8712u: %s: crypt.alg = WEP\n", __func__);
388 padapter->securitypriv.ndisencryptstatus =
389 Ndis802_11Encryption1Enabled;
390 padapter->securitypriv.PrivacyAlgrthm = _WEP40_;
391 padapter->securitypriv.XGrpPrivacy = _WEP40_;
392 wep_key_idx = param->u.crypt.idx;
393 wep_key_len = param->u.crypt.key_len;
394 if (wep_key_idx >= WEP_KEYS)
396 if (wep_key_len > 0) {
397 wep_key_len = wep_key_len <= 5 ? 5 : 13;
398 pwep = kmalloc((u32)(wep_key_len +
399 FIELD_OFFSET(struct NDIS_802_11_WEP,
400 KeyMaterial)), GFP_ATOMIC);
403 memset(pwep, 0, sizeof(struct NDIS_802_11_WEP));
404 pwep->KeyLength = wep_key_len;
405 pwep->Length = wep_key_len +
406 FIELD_OFFSET(struct NDIS_802_11_WEP,
408 if (wep_key_len == 13) {
409 padapter->securitypriv.PrivacyAlgrthm =
411 padapter->securitypriv.XGrpPrivacy =
416 pwep->KeyIndex = wep_key_idx;
417 pwep->KeyIndex |= 0x80000000;
418 memcpy(pwep->KeyMaterial, param->u.crypt.key, pwep->KeyLength);
419 if (param->u.crypt.set_tx) {
420 if (r8712_set_802_11_add_wep(padapter, pwep) ==
424 /* don't update "psecuritypriv->PrivacyAlgrthm" and
425 * "psecuritypriv->PrivacyKeyIndex=keyid", but can
426 * r8712_set_key to fw/cam
428 if (wep_key_idx >= WEP_KEYS) {
432 memcpy(&(psecuritypriv->DefKey[wep_key_idx].
433 skey[0]), pwep->KeyMaterial,
435 psecuritypriv->DefKeylen[wep_key_idx] =
437 r8712_set_key(padapter, psecuritypriv, wep_key_idx);
441 if (padapter->securitypriv.AuthAlgrthm == 2) { /* 802_1x */
442 struct sta_info *psta, *pbcmc_sta;
443 struct sta_priv *pstapriv = &padapter->stapriv;
445 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE |
446 WIFI_MP_STATE) == true) { /* sta mode */
447 psta = r8712_get_stainfo(pstapriv,
448 get_bssid(pmlmepriv));
450 psta->ieee8021x_blocked = false;
451 if ((padapter->securitypriv.ndisencryptstatus ==
452 Ndis802_11Encryption2Enabled) ||
453 (padapter->securitypriv.ndisencryptstatus ==
454 Ndis802_11Encryption3Enabled))
455 psta->XPrivacy = padapter->
456 securitypriv.PrivacyAlgrthm;
457 if (param->u.crypt.set_tx == 1)
458 handle_pairwise_key(psta, param,
461 handle_group_key(param, padapter);
463 pbcmc_sta = r8712_get_bcmc_stainfo(padapter);
465 pbcmc_sta->ieee8021x_blocked = false;
466 if ((padapter->securitypriv.ndisencryptstatus ==
467 Ndis802_11Encryption2Enabled) ||
468 (padapter->securitypriv.ndisencryptstatus ==
469 Ndis802_11Encryption3Enabled))
470 pbcmc_sta->XPrivacy =
471 padapter->securitypriv.
481 static int r871x_set_wpa_ie(struct _adapter *padapter, char *pie,
482 unsigned short ielen)
485 int group_cipher = 0, pairwise_cipher = 0;
488 if ((ielen > MAX_WPA_IE_LEN) || (pie == NULL))
491 buf = kmemdup(pie, ielen, GFP_ATOMIC);
494 if (ielen < RSN_HEADER_LEN) {
498 if (r8712_parse_wpa_ie(buf, ielen, &group_cipher,
499 &pairwise_cipher) == _SUCCESS) {
500 padapter->securitypriv.AuthAlgrthm = 2;
501 padapter->securitypriv.ndisauthtype =
502 Ndis802_11AuthModeWPAPSK;
504 if (r8712_parse_wpa2_ie(buf, ielen, &group_cipher,
505 &pairwise_cipher) == _SUCCESS) {
506 padapter->securitypriv.AuthAlgrthm = 2;
507 padapter->securitypriv.ndisauthtype =
508 Ndis802_11AuthModeWPA2PSK;
510 switch (group_cipher) {
511 case WPA_CIPHER_NONE:
512 padapter->securitypriv.XGrpPrivacy =
514 padapter->securitypriv.ndisencryptstatus =
515 Ndis802_11EncryptionDisabled;
517 case WPA_CIPHER_WEP40:
518 padapter->securitypriv.XGrpPrivacy = _WEP40_;
519 padapter->securitypriv.ndisencryptstatus =
520 Ndis802_11Encryption1Enabled;
522 case WPA_CIPHER_TKIP:
523 padapter->securitypriv.XGrpPrivacy = _TKIP_;
524 padapter->securitypriv.ndisencryptstatus =
525 Ndis802_11Encryption2Enabled;
527 case WPA_CIPHER_CCMP:
528 padapter->securitypriv.XGrpPrivacy = _AES_;
529 padapter->securitypriv.ndisencryptstatus =
530 Ndis802_11Encryption3Enabled;
532 case WPA_CIPHER_WEP104:
533 padapter->securitypriv.XGrpPrivacy = _WEP104_;
534 padapter->securitypriv.ndisencryptstatus =
535 Ndis802_11Encryption1Enabled;
538 switch (pairwise_cipher) {
539 case WPA_CIPHER_NONE:
540 padapter->securitypriv.PrivacyAlgrthm =
542 padapter->securitypriv.ndisencryptstatus =
543 Ndis802_11EncryptionDisabled;
545 case WPA_CIPHER_WEP40:
546 padapter->securitypriv.PrivacyAlgrthm = _WEP40_;
547 padapter->securitypriv.ndisencryptstatus =
548 Ndis802_11Encryption1Enabled;
550 case WPA_CIPHER_TKIP:
551 padapter->securitypriv.PrivacyAlgrthm = _TKIP_;
552 padapter->securitypriv.ndisencryptstatus =
553 Ndis802_11Encryption2Enabled;
555 case WPA_CIPHER_CCMP:
556 padapter->securitypriv.PrivacyAlgrthm = _AES_;
557 padapter->securitypriv.ndisencryptstatus =
558 Ndis802_11Encryption3Enabled;
560 case WPA_CIPHER_WEP104:
561 padapter->securitypriv.PrivacyAlgrthm = _WEP104_;
562 padapter->securitypriv.ndisencryptstatus =
563 Ndis802_11Encryption1Enabled;
566 padapter->securitypriv.wps_phase = false;
569 u8 eid, wps_oui[4] = {0x0, 0x50, 0xf2, 0x04};
571 while (cnt < ielen) {
574 if ((eid == _VENDOR_SPECIFIC_IE_) &&
575 (!memcmp(&buf[cnt+2], wps_oui, 4))) {
576 netdev_info(padapter->pnetdev, "r8712u: SET WPS_IE\n");
577 padapter->securitypriv.wps_ie_len =
579 (MAX_WPA_IE_LEN << 2)) ?
581 (MAX_WPA_IE_LEN << 2);
582 memcpy(padapter->securitypriv.wps_ie,
584 padapter->securitypriv.wps_ie_len);
585 padapter->securitypriv.wps_phase =
587 netdev_info(padapter->pnetdev, "r8712u: SET WPS_IE, wps_phase==true\n");
591 cnt += buf[cnt + 1] + 2;
600 static int r8711_wx_get_name(struct net_device *dev,
601 struct iw_request_info *info,
602 union iwreq_data *wrqu, char *extra)
604 struct _adapter *padapter = netdev_priv(dev);
608 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
609 struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
612 if (check_fwstate(pmlmepriv, _FW_LINKED|WIFI_ADHOC_MASTER_STATE) ==
614 /* parsing HT_CAP_IE */
615 p = r8712_get_ie(&pcur_bss->IEs[12], _HT_CAPABILITY_IE_,
616 &ht_ielen, pcur_bss->IELength - 12);
617 if (p && ht_ielen > 0)
619 prates = pcur_bss->rates;
620 if (r8712_is_cckratesonly_included(prates) == true) {
622 snprintf(wrqu->name, IFNAMSIZ,
625 snprintf(wrqu->name, IFNAMSIZ,
627 } else if ((r8712_is_cckrates_included(prates)) == true) {
629 snprintf(wrqu->name, IFNAMSIZ,
632 snprintf(wrqu->name, IFNAMSIZ,
636 snprintf(wrqu->name, IFNAMSIZ,
639 snprintf(wrqu->name, IFNAMSIZ,
643 snprintf(wrqu->name, IFNAMSIZ, "unassociated");
647 static const long frequency_list[] = {
648 2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447, 2452, 2457, 2462,
649 2467, 2472, 2484, 4915, 4920, 4925, 4935, 4940, 4945, 4960, 4980,
650 5035, 5040, 5045, 5055, 5060, 5080, 5170, 5180, 5190, 5200, 5210,
651 5220, 5230, 5240, 5260, 5280, 5300, 5320, 5500, 5520, 5540, 5560,
652 5580, 5600, 5620, 5640, 5660, 5680, 5700, 5745, 5765, 5785, 5805,
656 static int r8711_wx_set_freq(struct net_device *dev,
657 struct iw_request_info *info,
658 union iwreq_data *wrqu, char *extra)
660 struct _adapter *padapter = netdev_priv(dev);
661 struct iw_freq *fwrq = &wrqu->freq;
664 /* If setting by frequency, convert to a channel */
665 if ((fwrq->e == 1) &&
666 (fwrq->m >= (int) 2.412e8) &&
667 (fwrq->m <= (int) 2.487e8)) {
668 int f = fwrq->m / 100000;
671 while ((c < 14) && (f != frequency_list[c]))
676 /* Setting by channel number */
677 if ((fwrq->m > 14) || (fwrq->e > 0))
680 int channel = fwrq->m;
682 if ((channel < 1) || (channel > 14))
685 /* Yes ! We can set it !!! */
686 padapter->registrypriv.channel = channel;
692 static int r8711_wx_get_freq(struct net_device *dev,
693 struct iw_request_info *info,
694 union iwreq_data *wrqu, char *extra)
696 struct _adapter *padapter = netdev_priv(dev);
697 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
698 struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
700 if (check_fwstate(pmlmepriv, _FW_LINKED) == true) {
701 wrqu->freq.m = ieee80211_wlan_frequencies[
702 pcur_bss->Configuration.DSConfig-1] * 100000;
704 wrqu->freq.i = pcur_bss->Configuration.DSConfig;
711 static int r8711_wx_set_mode(struct net_device *dev,
712 struct iw_request_info *a,
713 union iwreq_data *wrqu, char *b)
715 struct _adapter *padapter = netdev_priv(dev);
716 enum NDIS_802_11_NETWORK_INFRASTRUCTURE networkType;
718 switch (wrqu->mode) {
720 networkType = Ndis802_11AutoUnknown;
723 networkType = Ndis802_11IBSS;
726 networkType = Ndis802_11APMode;
729 networkType = Ndis802_11Infrastructure;
734 if (Ndis802_11APMode == networkType)
735 r8712_setopmode_cmd(padapter, networkType);
737 r8712_setopmode_cmd(padapter, Ndis802_11AutoUnknown);
739 r8712_set_802_11_infrastructure_mode(padapter, networkType);
743 static int r8711_wx_get_mode(struct net_device *dev, struct iw_request_info *a,
744 union iwreq_data *wrqu, char *b)
746 struct _adapter *padapter = netdev_priv(dev);
747 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
749 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == true)
750 wrqu->mode = IW_MODE_INFRA;
751 else if (check_fwstate(pmlmepriv,
752 WIFI_ADHOC_MASTER_STATE|WIFI_ADHOC_STATE) == true)
753 wrqu->mode = IW_MODE_ADHOC;
754 else if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == true)
755 wrqu->mode = IW_MODE_MASTER;
757 wrqu->mode = IW_MODE_AUTO;
761 static int r871x_wx_set_pmkid(struct net_device *dev,
762 struct iw_request_info *a,
763 union iwreq_data *wrqu, char *extra)
765 struct _adapter *padapter = netdev_priv(dev);
766 struct security_priv *psecuritypriv = &padapter->securitypriv;
767 struct iw_pmksa *pPMK = (struct iw_pmksa *) extra;
768 u8 strZeroMacAddress[ETH_ALEN] = {0x00};
769 u8 strIssueBssid[ETH_ALEN] = {0x00};
770 u8 j, blInserted = false;
771 int intReturn = false;
774 There are the BSSID information in the bssid.sa_data array.
775 If cmd is IW_PMKSA_FLUSH, it means the wpa_supplicant wants to clear
776 all the PMKID information. If cmd is IW_PMKSA_ADD, it means the
777 wpa_supplicant wants to add a PMKID/BSSID to driver.
778 If cmd is IW_PMKSA_REMOVE, it means the wpa_supplicant wants to
779 remove a PMKID/BSSID from driver.
783 memcpy(strIssueBssid, pPMK->bssid.sa_data, ETH_ALEN);
786 if (!memcmp(strIssueBssid, strZeroMacAddress, ETH_ALEN))
790 /* overwrite PMKID */
791 for (j = 0; j < NUM_PMKID_CACHE; j++) {
792 if (!memcmp(psecuritypriv->PMKIDList[j].Bssid,
793 strIssueBssid, ETH_ALEN)) {
794 /* BSSID is matched, the same AP => rewrite
796 netdev_info(dev, "r8712u: %s: BSSID exists in the PMKList.\n",
798 memcpy(psecuritypriv->PMKIDList[j].PMKID,
799 pPMK->pmkid, IW_PMKID_LEN);
800 psecuritypriv->PMKIDList[j].bUsed = true;
801 psecuritypriv->PMKIDIndex = j + 1;
807 /* Find a new entry */
808 netdev_info(dev, "r8712u: %s: Use the new entry index = %d for this PMKID.\n",
809 __func__, psecuritypriv->PMKIDIndex);
810 memcpy(psecuritypriv->PMKIDList[psecuritypriv->
811 PMKIDIndex].Bssid, strIssueBssid, ETH_ALEN);
812 memcpy(psecuritypriv->PMKIDList[psecuritypriv->
813 PMKIDIndex].PMKID, pPMK->pmkid, IW_PMKID_LEN);
814 psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].
816 psecuritypriv->PMKIDIndex++;
817 if (psecuritypriv->PMKIDIndex == NUM_PMKID_CACHE)
818 psecuritypriv->PMKIDIndex = 0;
821 case IW_PMKSA_REMOVE:
823 for (j = 0; j < NUM_PMKID_CACHE; j++) {
824 if (!memcmp(psecuritypriv->PMKIDList[j].Bssid,
825 strIssueBssid, ETH_ALEN)) {
826 /* BSSID is matched, the same AP => Remove
827 * this PMKID information and reset it. */
828 eth_zero_addr(psecuritypriv->PMKIDList[j].Bssid);
829 psecuritypriv->PMKIDList[j].bUsed = false;
835 memset(psecuritypriv->PMKIDList, 0,
836 sizeof(struct RT_PMKID_LIST) * NUM_PMKID_CACHE);
837 psecuritypriv->PMKIDIndex = 0;
841 netdev_info(dev, "r8712u: %s: unknown Command\n", __func__);
848 static int r8711_wx_get_sens(struct net_device *dev,
849 struct iw_request_info *info,
850 union iwreq_data *wrqu, char *extra)
852 wrqu->sens.value = 0;
853 wrqu->sens.fixed = 0; /* no auto select */
854 wrqu->sens.disabled = 1;
858 static int r8711_wx_get_range(struct net_device *dev,
859 struct iw_request_info *info,
860 union iwreq_data *wrqu, char *extra)
862 struct iw_range *range = (struct iw_range *)extra;
866 wrqu->data.length = sizeof(*range);
867 memset(range, 0, sizeof(*range));
868 /* Let's try to keep this struct in the same order as in
869 * linux/include/wireless.h
872 /* TODO: See what values we can set, and remove the ones we can't
873 * set, or fill them with some default data.
875 /* ~5 Mb/s real (802.11b) */
876 range->throughput = 5 * 1000 * 1000;
877 /* TODO: 8711 sensitivity ? */
878 /* signal level threshold range */
879 /* percent values between 0 and 100. */
880 range->max_qual.qual = 100;
881 range->max_qual.level = 100;
882 range->max_qual.noise = 100;
883 range->max_qual.updated = 7; /* Updated all three */
884 range->avg_qual.qual = 92; /* > 8% missed beacons is 'bad' */
885 /* TODO: Find real 'good' to 'bad' threshold value for RSSI */
886 range->avg_qual.level = 0x100 - 78;
887 range->avg_qual.noise = 0;
888 range->avg_qual.updated = 7; /* Updated all three */
889 range->num_bitrates = RATE_COUNT;
890 for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++)
891 range->bitrate[i] = rtl8180_rates[i];
892 range->min_frag = MIN_FRAG_THRESHOLD;
893 range->max_frag = MAX_FRAG_THRESHOLD;
895 range->we_version_compiled = WIRELESS_EXT;
896 range->we_version_source = 16;
897 range->num_channels = 14;
898 for (i = 0, val = 0; i < 14; i++) {
899 /* Include only legal frequencies for some countries */
900 range->freq[val].i = i + 1;
901 range->freq[val].m = ieee80211_wlan_frequencies[i] * 100000;
902 range->freq[val].e = 1;
904 if (val == IW_MAX_FREQUENCIES)
907 range->num_frequency = val;
908 range->enc_capa = IW_ENC_CAPA_WPA |
910 IW_ENC_CAPA_CIPHER_TKIP |
911 IW_ENC_CAPA_CIPHER_CCMP;
915 static int r8711_wx_get_rate(struct net_device *dev,
916 struct iw_request_info *info,
917 union iwreq_data *wrqu, char *extra);
919 static int r871x_wx_set_priv(struct net_device *dev,
920 struct iw_request_info *info,
921 union iwreq_data *awrq,
924 int ret = 0, len = 0;
926 struct _adapter *padapter = netdev_priv(dev);
927 struct iw_point *dwrq = (struct iw_point *)awrq;
930 ext = memdup_user(dwrq->pointer, len);
934 if (!strcasecmp(ext, "RSSI")) {
935 /*Return received signal strength indicator in -db for */
938 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
939 struct wlan_network *pcur_network = &pmlmepriv->cur_network;
941 if (check_fwstate(pmlmepriv, _FW_LINKED) == true) {
942 sprintf(ext, "%s rssi %d",
943 pcur_network->network.Ssid.Ssid,
945 ((padapter->recvpriv.fw_rssi)>>1)-95
946 /*pcur_network->network.Rssi */
951 } else if (!strcasecmp(ext, "LINKSPEED")) {
952 /*Return link speed in MBPS */
954 union iwreq_data wrqd;
958 ret_inner = r8711_wx_get_rate(dev, info, &wrqd, extra);
962 mbps = wrqd.bitrate.value / 1000000;
963 sprintf(ext, "LINKSPEED %d", mbps);
964 } else if (!strcasecmp(ext, "MACADDR")) {
965 /*Return mac address of the station */
966 /* Macaddr = xx:xx:xx:xx:xx:xx */
967 sprintf(ext, "MACADDR = %pM", dev->dev_addr);
968 } else if (!strcasecmp(ext, "SCAN-ACTIVE")) {
969 /*Set scan type to active */
970 /*OK if successful */
971 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
973 pmlmepriv->passive_mode = 1;
975 } else if (!strcasecmp(ext, "SCAN-PASSIVE")) {
976 /*Set scan type to passive */
977 /*OK if successful */
978 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
980 pmlmepriv->passive_mode = 0;
982 } else if (!strncmp(ext, "DCE-E", 5)) {
983 /*Set scan type to passive */
984 /*OK if successful */
985 r8712_disconnectCtrlEx_cmd(padapter
986 , 1 /*u32 enableDrvCtrl */
987 , 5 /*u32 tryPktCnt */
988 , 100 /*u32 tryPktInterval */
989 , 5000 /*u32 firstStageTO */
992 } else if (!strncmp(ext, "DCE-D", 5)) {
993 /*Set scan type to passive */
995 r8712_disconnectCtrlEx_cmd(padapter
996 , 0 /*u32 enableDrvCtrl */
997 , 5 /*u32 tryPktCnt */
998 , 100 /*u32 tryPktInterval */
999 , 5000 /*u32 firstStageTO */
1003 netdev_info(dev, "r8712u: %s: unknown Command %s.\n",
1007 if (copy_to_user(dwrq->pointer, ext,
1008 min(dwrq->length, (__u16)(strlen(ext)+1))))
1017 * s1. set_802_11_infrastructure_mode()
1018 * s2. set_802_11_authentication_mode()
1019 * s3. set_802_11_encryption_mode()
1020 * s4. set_802_11_bssid()
1022 * This function intends to handle the Set AP command, which specifies the
1023 * MAC# of a preferred Access Point.
1024 * Currently, the request comes via Wireless Extensions' SIOCSIWAP ioctl.
1026 * For this operation to succeed, there is no need for the interface to be up.
1029 static int r8711_wx_set_wap(struct net_device *dev,
1030 struct iw_request_info *info,
1031 union iwreq_data *awrq,
1034 int ret = -EINPROGRESS;
1035 struct _adapter *padapter = netdev_priv(dev);
1036 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1037 struct __queue *queue = &pmlmepriv->scanned_queue;
1038 struct sockaddr *temp = (struct sockaddr *)awrq;
1040 struct list_head *phead;
1042 struct wlan_network *pnetwork = NULL;
1043 enum NDIS_802_11_AUTHENTICATION_MODE authmode;
1045 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == true)
1047 if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == true)
1049 if (temp->sa_family != ARPHRD_ETHER)
1051 authmode = padapter->securitypriv.ndisauthtype;
1052 spin_lock_irqsave(&queue->lock, irqL);
1053 phead = &queue->queue;
1054 pmlmepriv->pscanned = phead->next;
1056 if (end_of_queue_search(phead, pmlmepriv->pscanned) == true)
1058 pnetwork = LIST_CONTAINOR(pmlmepriv->pscanned,
1059 struct wlan_network, list);
1060 pmlmepriv->pscanned = pmlmepriv->pscanned->next;
1061 dst_bssid = pnetwork->network.MacAddress;
1062 if (!memcmp(dst_bssid, temp->sa_data, ETH_ALEN)) {
1063 r8712_set_802_11_infrastructure_mode(padapter,
1064 pnetwork->network.InfrastructureMode);
1068 spin_unlock_irqrestore(&queue->lock, irqL);
1070 if (!r8712_set_802_11_authentication_mode(padapter, authmode))
1073 if (!r8712_set_802_11_bssid(padapter, temp->sa_data))
1080 static int r8711_wx_get_wap(struct net_device *dev,
1081 struct iw_request_info *info,
1082 union iwreq_data *wrqu, char *extra)
1084 struct _adapter *padapter = netdev_priv(dev);
1085 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1086 struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
1088 wrqu->ap_addr.sa_family = ARPHRD_ETHER;
1089 if (check_fwstate(pmlmepriv, _FW_LINKED | WIFI_ADHOC_MASTER_STATE |
1091 ether_addr_copy(wrqu->ap_addr.sa_data, pcur_bss->MacAddress);
1093 eth_zero_addr(wrqu->ap_addr.sa_data);
1097 static int r871x_wx_set_mlme(struct net_device *dev,
1098 struct iw_request_info *info,
1099 union iwreq_data *wrqu, char *extra)
1102 struct _adapter *padapter = netdev_priv(dev);
1103 struct iw_mlme *mlme = (struct iw_mlme *) extra;
1107 switch (mlme->cmd) {
1108 case IW_MLME_DEAUTH:
1109 if (!r8712_set_802_11_disassociate(padapter))
1112 case IW_MLME_DISASSOC:
1113 if (!r8712_set_802_11_disassociate(padapter))
1124 * This function intends to handle the Set Scan command.
1125 * Currently, the request comes via Wireless Extensions' SIOCSIWSCAN ioctl.
1127 * For this operation to succeed, the interface is brought Up beforehand.
1130 static int r8711_wx_set_scan(struct net_device *dev,
1131 struct iw_request_info *a,
1132 union iwreq_data *wrqu, char *extra)
1134 struct _adapter *padapter = netdev_priv(dev);
1135 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1138 if (padapter->bDriverStopped == true) {
1139 netdev_info(dev, "In %s: bDriverStopped=%d\n",
1140 __func__, padapter->bDriverStopped);
1143 if (padapter->bup == false)
1145 if (padapter->hw_init_completed == false)
1147 if ((check_fwstate(pmlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING)) ||
1148 (pmlmepriv->sitesurveyctrl.traffic_busy == true))
1150 if (wrqu->data.length == sizeof(struct iw_scan_req)) {
1151 struct iw_scan_req *req = (struct iw_scan_req *)extra;
1153 if (wrqu->data.flags & IW_SCAN_THIS_ESSID) {
1154 struct ndis_802_11_ssid ssid;
1156 u32 len = min_t(u8, req->essid_len, IW_ESSID_MAX_SIZE);
1158 memset((unsigned char *)&ssid, 0,
1159 sizeof(struct ndis_802_11_ssid));
1160 memcpy(ssid.Ssid, req->essid, len);
1161 ssid.SsidLength = len;
1162 spin_lock_irqsave(&pmlmepriv->lock, irqL);
1163 if ((check_fwstate(pmlmepriv, _FW_UNDER_SURVEY |
1164 _FW_UNDER_LINKING)) ||
1165 (pmlmepriv->sitesurveyctrl.traffic_busy == true)) {
1166 if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING))
1169 status = r8712_sitesurvey_cmd(padapter, &ssid);
1170 spin_unlock_irqrestore(&pmlmepriv->lock, irqL);
1173 status = r8712_set_802_11_bssid_list_scan(padapter);
1174 if (status == false)
1179 static int r8711_wx_get_scan(struct net_device *dev,
1180 struct iw_request_info *a,
1181 union iwreq_data *wrqu, char *extra)
1183 struct _adapter *padapter = netdev_priv(dev);
1184 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1185 struct __queue *queue = &pmlmepriv->scanned_queue;
1186 struct wlan_network *pnetwork = NULL;
1188 struct list_head *plist, *phead;
1190 char *stop = ev + wrqu->data.length;
1191 u32 ret = 0, cnt = 0;
1193 if (padapter->bDriverStopped)
1195 while (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING)) {
1201 spin_lock_irqsave(&queue->lock, irqL);
1202 phead = &queue->queue;
1203 plist = phead->next;
1205 if (end_of_queue_search(phead, plist) == true)
1207 if ((stop - ev) < SCAN_ITEM_SIZE) {
1211 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
1212 ev = translate_scan(padapter, a, pnetwork, ev, stop);
1213 plist = plist->next;
1215 spin_unlock_irqrestore(&queue->lock, irqL);
1216 wrqu->data.length = ev - extra;
1217 wrqu->data.flags = 0;
1222 * s1. set_802_11_infrastructure_mode()
1223 * s2. set_802_11_authenticaion_mode()
1224 * s3. set_802_11_encryption_mode()
1225 * s4. set_802_11_ssid()
1227 * This function intends to handle the Set ESSID command.
1228 * Currently, the request comes via the Wireless Extensions' SIOCSIWESSID ioctl.
1230 * For this operation to succeed, there is no need for the interface to be Up.
1233 static int r8711_wx_set_essid(struct net_device *dev,
1234 struct iw_request_info *a,
1235 union iwreq_data *wrqu, char *extra)
1237 struct _adapter *padapter = netdev_priv(dev);
1238 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1239 struct __queue *queue = &pmlmepriv->scanned_queue;
1240 struct wlan_network *pnetwork = NULL;
1241 enum NDIS_802_11_AUTHENTICATION_MODE authmode;
1242 struct ndis_802_11_ssid ndis_ssid;
1243 u8 *dst_ssid, *src_ssid;
1244 struct list_head *phead;
1247 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY))
1249 if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING))
1251 if (wrqu->essid.length > IW_ESSID_MAX_SIZE)
1253 authmode = padapter->securitypriv.ndisauthtype;
1254 if (wrqu->essid.flags && wrqu->essid.length) {
1255 len = (wrqu->essid.length < IW_ESSID_MAX_SIZE) ?
1256 wrqu->essid.length : IW_ESSID_MAX_SIZE;
1257 memset(&ndis_ssid, 0, sizeof(struct ndis_802_11_ssid));
1258 ndis_ssid.SsidLength = len;
1259 memcpy(ndis_ssid.Ssid, extra, len);
1260 src_ssid = ndis_ssid.Ssid;
1261 phead = &queue->queue;
1262 pmlmepriv->pscanned = phead->next;
1264 if (end_of_queue_search(phead, pmlmepriv->pscanned))
1266 pnetwork = LIST_CONTAINOR(pmlmepriv->pscanned,
1267 struct wlan_network, list);
1268 pmlmepriv->pscanned = pmlmepriv->pscanned->next;
1269 dst_ssid = pnetwork->network.Ssid.Ssid;
1270 if ((!memcmp(dst_ssid, src_ssid, ndis_ssid.SsidLength))
1271 && (pnetwork->network.Ssid.SsidLength ==
1272 ndis_ssid.SsidLength)) {
1273 if (check_fwstate(pmlmepriv,
1274 WIFI_ADHOC_STATE)) {
1275 if (pnetwork->network.
1279 cur_network.network.
1284 r8712_set_802_11_infrastructure_mode(
1286 pnetwork->network.InfrastructureMode);
1290 r8712_set_802_11_authentication_mode(padapter, authmode);
1291 r8712_set_802_11_ssid(padapter, &ndis_ssid);
1293 return -EINPROGRESS;
1296 static int r8711_wx_get_essid(struct net_device *dev,
1297 struct iw_request_info *a,
1298 union iwreq_data *wrqu, char *extra)
1300 struct _adapter *padapter = netdev_priv(dev);
1301 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1302 struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
1305 if (check_fwstate(pmlmepriv, _FW_LINKED|WIFI_ADHOC_MASTER_STATE)) {
1306 len = pcur_bss->Ssid.SsidLength;
1307 wrqu->essid.length = len;
1308 memcpy(extra, pcur_bss->Ssid.Ssid, len);
1309 wrqu->essid.flags = 1;
1316 static int r8711_wx_set_rate(struct net_device *dev,
1317 struct iw_request_info *a,
1318 union iwreq_data *wrqu, char *extra)
1320 struct _adapter *padapter = netdev_priv(dev);
1321 u32 target_rate = wrqu->bitrate.value;
1322 u32 fixed = wrqu->bitrate.fixed;
1324 u8 datarates[NumRates];
1325 u8 mpdatarate[NumRates] = {11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0xff};
1328 if (target_rate == -1) {
1332 target_rate = target_rate / 100000;
1333 switch (target_rate) {
1375 for (i = 0; i < NumRates; i++) {
1376 if (ratevalue == mpdatarate[i]) {
1377 datarates[i] = mpdatarate[i];
1381 datarates[i] = 0xff;
1383 if (r8712_setdatarate_cmd(padapter, datarates) != _SUCCESS)
1388 static int r8711_wx_get_rate(struct net_device *dev,
1389 struct iw_request_info *info,
1390 union iwreq_data *wrqu, char *extra)
1392 struct _adapter *padapter = netdev_priv(dev);
1393 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1394 struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
1395 struct ieee80211_ht_cap *pht_capie;
1396 unsigned char rf_type = padapter->registrypriv.rf_config;
1399 u16 rate, max_rate = 0, ht_cap = false;
1401 u8 bw_40MHz = 0, short_GI = 0;
1405 if (check_fwstate(pmlmepriv, _FW_LINKED|WIFI_ADHOC_MASTER_STATE)) {
1406 p = r8712_get_ie(&pcur_bss->IEs[12],
1407 _HT_CAPABILITY_IE_, &ht_ielen,
1408 pcur_bss->IELength - 12);
1409 if (p && ht_ielen > 0) {
1411 pht_capie = (struct ieee80211_ht_cap *)(p + 2);
1412 memcpy(&mcs_rate, pht_capie->supp_mcs_set, 2);
1413 bw_40MHz = (pht_capie->cap_info &
1414 IEEE80211_HT_CAP_SUP_WIDTH) ? 1 : 0;
1415 short_GI = (pht_capie->cap_info &
1416 (IEEE80211_HT_CAP_SGI_20 |
1417 IEEE80211_HT_CAP_SGI_40)) ? 1 : 0;
1419 while ((pcur_bss->rates[i] != 0) &&
1420 (pcur_bss->rates[i] != 0xFF)) {
1421 rate = pcur_bss->rates[i] & 0x7F;
1422 if (rate > max_rate)
1424 wrqu->bitrate.fixed = 0; /* no auto select */
1425 wrqu->bitrate.value = rate*500000;
1428 if (ht_cap == true) {
1429 if (mcs_rate & 0x8000 /* MCS15 */
1431 rf_type == RTL8712_RF_2T2R)
1432 max_rate = (bw_40MHz) ? ((short_GI) ? 300 :
1433 270) : ((short_GI) ? 144 : 130);
1434 else /* default MCS7 */
1435 max_rate = (bw_40MHz) ? ((short_GI) ? 150 :
1436 135) : ((short_GI) ? 72 : 65);
1437 max_rate *= 2; /* Mbps/2 */
1439 wrqu->bitrate.value = max_rate * 500000;
1445 static int r8711_wx_get_rts(struct net_device *dev,
1446 struct iw_request_info *info,
1447 union iwreq_data *wrqu, char *extra)
1449 struct _adapter *padapter = netdev_priv(dev);
1451 wrqu->rts.value = padapter->registrypriv.rts_thresh;
1452 wrqu->rts.fixed = 0; /* no auto select */
1456 static int r8711_wx_set_frag(struct net_device *dev,
1457 struct iw_request_info *info,
1458 union iwreq_data *wrqu, char *extra)
1460 struct _adapter *padapter = netdev_priv(dev);
1462 if (wrqu->frag.disabled)
1463 padapter->xmitpriv.frag_len = MAX_FRAG_THRESHOLD;
1465 if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
1466 wrqu->frag.value > MAX_FRAG_THRESHOLD)
1468 padapter->xmitpriv.frag_len = wrqu->frag.value & ~0x1;
1473 static int r8711_wx_get_frag(struct net_device *dev,
1474 struct iw_request_info *info,
1475 union iwreq_data *wrqu, char *extra)
1477 struct _adapter *padapter = netdev_priv(dev);
1479 wrqu->frag.value = padapter->xmitpriv.frag_len;
1480 wrqu->frag.fixed = 0; /* no auto select */
1484 static int r8711_wx_get_retry(struct net_device *dev,
1485 struct iw_request_info *info,
1486 union iwreq_data *wrqu, char *extra)
1488 wrqu->retry.value = 7;
1489 wrqu->retry.fixed = 0; /* no auto select */
1490 wrqu->retry.disabled = 1;
1494 static int r8711_wx_set_enc(struct net_device *dev,
1495 struct iw_request_info *info,
1496 union iwreq_data *wrqu, char *keybuf)
1499 u32 keyindex_provided;
1500 struct NDIS_802_11_WEP wep;
1501 enum NDIS_802_11_AUTHENTICATION_MODE authmode;
1502 struct iw_point *erq = &(wrqu->encoding);
1503 struct _adapter *padapter = netdev_priv(dev);
1505 key = erq->flags & IW_ENCODE_INDEX;
1506 memset(&wep, 0, sizeof(struct NDIS_802_11_WEP));
1507 if (erq->flags & IW_ENCODE_DISABLED) {
1508 netdev_info(dev, "r8712u: %s: EncryptionDisabled\n", __func__);
1509 padapter->securitypriv.ndisencryptstatus =
1510 Ndis802_11EncryptionDisabled;
1511 padapter->securitypriv.PrivacyAlgrthm = _NO_PRIVACY_;
1512 padapter->securitypriv.XGrpPrivacy = _NO_PRIVACY_;
1513 padapter->securitypriv.AuthAlgrthm = 0; /* open system */
1514 authmode = Ndis802_11AuthModeOpen;
1515 padapter->securitypriv.ndisauthtype = authmode;
1522 keyindex_provided = 1;
1524 keyindex_provided = 0;
1525 key = padapter->securitypriv.PrivacyKeyIndex;
1527 /* set authentication mode */
1528 if (erq->flags & IW_ENCODE_OPEN) {
1529 netdev_info(dev, "r8712u: %s: IW_ENCODE_OPEN\n", __func__);
1530 padapter->securitypriv.ndisencryptstatus =
1531 Ndis802_11Encryption1Enabled;
1532 padapter->securitypriv.AuthAlgrthm = 0; /* open system */
1533 padapter->securitypriv.PrivacyAlgrthm = _NO_PRIVACY_;
1534 padapter->securitypriv.XGrpPrivacy = _NO_PRIVACY_;
1535 authmode = Ndis802_11AuthModeOpen;
1536 padapter->securitypriv.ndisauthtype = authmode;
1537 } else if (erq->flags & IW_ENCODE_RESTRICTED) {
1539 "r8712u: %s: IW_ENCODE_RESTRICTED\n", __func__);
1540 padapter->securitypriv.ndisencryptstatus =
1541 Ndis802_11Encryption1Enabled;
1542 padapter->securitypriv.AuthAlgrthm = 1; /* shared system */
1543 padapter->securitypriv.PrivacyAlgrthm = _WEP40_;
1544 padapter->securitypriv.XGrpPrivacy = _WEP40_;
1545 authmode = Ndis802_11AuthModeShared;
1546 padapter->securitypriv.ndisauthtype = authmode;
1548 padapter->securitypriv.ndisencryptstatus =
1549 Ndis802_11Encryption1Enabled;
1550 padapter->securitypriv.AuthAlgrthm = 0; /* open system */
1551 padapter->securitypriv.PrivacyAlgrthm = _NO_PRIVACY_;
1552 padapter->securitypriv.XGrpPrivacy = _NO_PRIVACY_;
1553 authmode = Ndis802_11AuthModeOpen;
1554 padapter->securitypriv.ndisauthtype = authmode;
1557 if (erq->length > 0) {
1558 wep.KeyLength = erq->length <= 5 ? 5 : 13;
1559 wep.Length = wep.KeyLength +
1560 FIELD_OFFSET(struct NDIS_802_11_WEP, KeyMaterial);
1563 if (keyindex_provided == 1) { /* set key_id only, no given
1564 * KeyMaterial(erq->length==0).*/
1565 padapter->securitypriv.PrivacyKeyIndex = key;
1566 switch (padapter->securitypriv.DefKeylen[key]) {
1568 padapter->securitypriv.PrivacyAlgrthm =
1572 padapter->securitypriv.PrivacyAlgrthm =
1576 padapter->securitypriv.PrivacyAlgrthm =
1583 wep.KeyIndex |= 0x80000000; /* transmit key */
1584 memcpy(wep.KeyMaterial, keybuf, wep.KeyLength);
1585 if (r8712_set_802_11_add_wep(padapter, &wep) == _FAIL)
1590 static int r8711_wx_get_enc(struct net_device *dev,
1591 struct iw_request_info *info,
1592 union iwreq_data *wrqu, char *keybuf)
1595 struct _adapter *padapter = netdev_priv(dev);
1596 struct iw_point *erq = &(wrqu->encoding);
1597 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1599 if (check_fwstate(pmlmepriv, _FW_LINKED) == false) {
1600 if (!check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) {
1602 erq->flags |= IW_ENCODE_DISABLED;
1606 key = erq->flags & IW_ENCODE_INDEX;
1612 key = padapter->securitypriv.PrivacyKeyIndex;
1614 erq->flags = key + 1;
1615 switch (padapter->securitypriv.ndisencryptstatus) {
1616 case Ndis802_11EncryptionNotSupported:
1617 case Ndis802_11EncryptionDisabled:
1619 erq->flags |= IW_ENCODE_DISABLED;
1621 case Ndis802_11Encryption1Enabled:
1622 erq->length = padapter->securitypriv.DefKeylen[key];
1624 memcpy(keybuf, padapter->securitypriv.DefKey[
1625 key].skey, padapter->securitypriv.
1627 erq->flags |= IW_ENCODE_ENABLED;
1628 if (padapter->securitypriv.ndisauthtype ==
1629 Ndis802_11AuthModeOpen)
1630 erq->flags |= IW_ENCODE_OPEN;
1631 else if (padapter->securitypriv.ndisauthtype ==
1632 Ndis802_11AuthModeShared)
1633 erq->flags |= IW_ENCODE_RESTRICTED;
1636 erq->flags |= IW_ENCODE_DISABLED;
1639 case Ndis802_11Encryption2Enabled:
1640 case Ndis802_11Encryption3Enabled:
1642 erq->flags |= (IW_ENCODE_ENABLED | IW_ENCODE_OPEN |
1647 erq->flags |= IW_ENCODE_DISABLED;
1653 static int r8711_wx_get_power(struct net_device *dev,
1654 struct iw_request_info *info,
1655 union iwreq_data *wrqu, char *extra)
1657 wrqu->power.value = 0;
1658 wrqu->power.fixed = 0; /* no auto select */
1659 wrqu->power.disabled = 1;
1663 static int r871x_wx_set_gen_ie(struct net_device *dev,
1664 struct iw_request_info *info,
1665 union iwreq_data *wrqu, char *extra)
1667 struct _adapter *padapter = netdev_priv(dev);
1669 return r871x_set_wpa_ie(padapter, extra, wrqu->data.length);
1672 static int r871x_wx_set_auth(struct net_device *dev,
1673 struct iw_request_info *info,
1674 union iwreq_data *wrqu, char *extra)
1676 struct _adapter *padapter = netdev_priv(dev);
1677 struct iw_param *param = (struct iw_param *)&(wrqu->param);
1682 paramid = param->flags & IW_AUTH_INDEX;
1683 paramval = param->value;
1685 case IW_AUTH_WPA_VERSION:
1687 case IW_AUTH_CIPHER_PAIRWISE:
1689 case IW_AUTH_CIPHER_GROUP:
1691 case IW_AUTH_KEY_MGMT:
1693 * ??? does not use these parameters
1696 case IW_AUTH_TKIP_COUNTERMEASURES:
1698 /* wpa_supplicant is enabling tkip countermeasure. */
1699 padapter->securitypriv.btkip_countermeasure = true;
1701 /* wpa_supplicant is disabling tkip countermeasure. */
1702 padapter->securitypriv.btkip_countermeasure = false;
1705 case IW_AUTH_DROP_UNENCRYPTED:
1708 * wpa_supplicant calls set_wpa_enabled when the driver
1709 * is loaded and unloaded, regardless of if WPA is being
1710 * used. No other calls are made which can be used to
1711 * determine if encryption will be used or not prior to
1712 * association being expected. If encryption is not being
1713 * used, drop_unencrypted is set to false, else true -- we
1714 * can use this to determine if the CAP_PRIVACY_ON bit should
1717 if (padapter->securitypriv.ndisencryptstatus ==
1718 Ndis802_11Encryption1Enabled) {
1719 /* it means init value, or using wep,
1720 * ndisencryptstatus =
1721 * Ndis802_11Encryption1Enabled,
1722 * then it needn't reset it;
1728 padapter->securitypriv.ndisencryptstatus =
1729 Ndis802_11EncryptionDisabled;
1730 padapter->securitypriv.PrivacyAlgrthm =
1732 padapter->securitypriv.XGrpPrivacy =
1734 padapter->securitypriv.AuthAlgrthm = 0;
1735 padapter->securitypriv.ndisauthtype =
1736 Ndis802_11AuthModeOpen;
1739 case IW_AUTH_80211_AUTH_ALG:
1740 ret = wpa_set_auth_algs(dev, (u32)paramval);
1742 case IW_AUTH_WPA_ENABLED:
1744 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
1746 case IW_AUTH_PRIVACY_INVOKED:
1755 static int r871x_wx_set_enc_ext(struct net_device *dev,
1756 struct iw_request_info *info,
1757 union iwreq_data *wrqu, char *extra)
1759 struct iw_point *pencoding = &wrqu->encoding;
1760 struct iw_encode_ext *pext = (struct iw_encode_ext *)extra;
1761 struct ieee_param *param = NULL;
1766 switch (pext->alg) {
1767 case IW_ENCODE_ALG_NONE:
1770 case IW_ENCODE_ALG_WEP:
1773 case IW_ENCODE_ALG_TKIP:
1776 case IW_ENCODE_ALG_CCMP:
1783 param_len = sizeof(struct ieee_param) + pext->key_len;
1784 param = kzalloc(param_len, GFP_ATOMIC);
1787 param->cmd = IEEE_CMD_SET_ENCRYPTION;
1788 memset(param->sta_addr, 0xff, ETH_ALEN);
1790 strncpy((char *)param->u.crypt.alg, alg_name, IEEE_CRYPT_ALG_NAME_LEN);
1791 if (pext->ext_flags & IW_ENCODE_EXT_GROUP_KEY)
1792 param->u.crypt.set_tx = 0;
1793 if (pext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
1794 param->u.crypt.set_tx = 1;
1795 param->u.crypt.idx = (pencoding->flags & 0x00FF) - 1;
1796 if (pext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID)
1797 memcpy(param->u.crypt.seq, pext->rx_seq, 8);
1798 if (pext->key_len) {
1799 param->u.crypt.key_len = pext->key_len;
1800 memcpy(param + 1, pext + 1, pext->key_len);
1802 ret = wpa_set_encryption(dev, param, param_len);
1807 static int r871x_wx_get_nick(struct net_device *dev,
1808 struct iw_request_info *info,
1809 union iwreq_data *wrqu, char *extra)
1812 wrqu->data.length = 8;
1813 wrqu->data.flags = 1;
1814 memcpy(extra, "rtl_wifi", 8);
1819 static int r8711_wx_read32(struct net_device *dev,
1820 struct iw_request_info *info,
1821 union iwreq_data *wrqu, char *keybuf)
1823 struct _adapter *padapter = netdev_priv(dev);
1827 get_user(addr, (u32 __user *)wrqu->data.pointer);
1828 data32 = r8712_read32(padapter, addr);
1829 put_user(data32, (u32 __user *)wrqu->data.pointer);
1830 wrqu->data.length = (data32 & 0xffff0000) >> 16;
1831 wrqu->data.flags = data32 & 0xffff;
1832 get_user(addr, (u32 __user *)wrqu->data.pointer);
1836 static int r8711_wx_write32(struct net_device *dev,
1837 struct iw_request_info *info,
1838 union iwreq_data *wrqu, char *keybuf)
1840 struct _adapter *padapter = netdev_priv(dev);
1844 get_user(addr, (u32 __user *)wrqu->data.pointer);
1845 data32 = ((u32)wrqu->data.length<<16) | (u32)wrqu->data.flags;
1846 r8712_write32(padapter, addr, data32);
1850 static int dummy(struct net_device *dev,
1851 struct iw_request_info *a,
1852 union iwreq_data *wrqu, char *b)
1857 static int r8711_drvext_hdl(struct net_device *dev,
1858 struct iw_request_info *info,
1859 union iwreq_data *wrqu, char *extra)
1864 static int r871x_mp_ioctl_hdl(struct net_device *dev,
1865 struct iw_request_info *info,
1866 union iwreq_data *wrqu, char *extra)
1868 struct _adapter *padapter = netdev_priv(dev);
1869 struct iw_point *p = &wrqu->data;
1870 struct oid_par_priv oid_par;
1871 struct mp_ioctl_handler *phandler;
1872 struct mp_ioctl_param *poidparam;
1873 unsigned long BytesRead, BytesWritten, BytesNeeded;
1879 if ((!p->length) || (!p->pointer))
1882 bset = (u8)(p->flags & 0xFFFF);
1884 pparmbuf = memdup_user(p->pointer, len);
1885 if (IS_ERR(pparmbuf))
1886 return PTR_ERR(pparmbuf);
1888 poidparam = (struct mp_ioctl_param *)pparmbuf;
1889 if (poidparam->subcode >= MAX_MP_IOCTL_SUBCODE) {
1891 goto _r871x_mp_ioctl_hdl_exit;
1893 phandler = mp_ioctl_hdl + poidparam->subcode;
1894 if ((phandler->paramsize != 0) &&
1895 (poidparam->len < phandler->paramsize)) {
1897 goto _r871x_mp_ioctl_hdl_exit;
1899 if (phandler->oid == 0 && phandler->handler)
1900 status = phandler->handler(&oid_par);
1901 else if (phandler->handler) {
1902 oid_par.adapter_context = padapter;
1903 oid_par.oid = phandler->oid;
1904 oid_par.information_buf = poidparam->data;
1905 oid_par.information_buf_len = poidparam->len;
1910 oid_par.bytes_rw = &BytesRead;
1911 oid_par.bytes_needed = &BytesNeeded;
1912 oid_par.type_of_oid = SET_OID;
1914 oid_par.bytes_rw = &BytesWritten;
1915 oid_par.bytes_needed = &BytesNeeded;
1916 oid_par.type_of_oid = QUERY_OID;
1918 status = phandler->handler(&oid_par);
1919 /* todo:check status, BytesNeeded, etc. */
1921 netdev_info(dev, "r8712u: %s: err!, subcode=%d, oid=%d, handler=%p\n",
1922 __func__, poidparam->subcode, phandler->oid,
1925 goto _r871x_mp_ioctl_hdl_exit;
1927 if (bset == 0x00) { /* query info */
1928 if (copy_to_user(p->pointer, pparmbuf, len))
1933 goto _r871x_mp_ioctl_hdl_exit;
1935 _r871x_mp_ioctl_hdl_exit:
1940 static int r871x_get_ap_info(struct net_device *dev,
1941 struct iw_request_info *info,
1942 union iwreq_data *wrqu, char *extra)
1944 struct _adapter *padapter = netdev_priv(dev);
1945 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1946 struct __queue *queue = &pmlmepriv->scanned_queue;
1947 struct iw_point *pdata = &wrqu->data;
1948 struct wlan_network *pnetwork = NULL;
1949 u32 cnt = 0, wpa_ielen;
1951 struct list_head *plist, *phead;
1952 unsigned char *pbuf;
1956 if (padapter->bDriverStopped || (pdata == NULL))
1958 while (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING)) {
1965 if (pdata->length >= 32) {
1966 if (copy_from_user(data, pdata->pointer, 32))
1970 spin_lock_irqsave(&(pmlmepriv->scanned_queue.lock), irqL);
1971 phead = &queue->queue;
1972 plist = phead->next;
1974 if (end_of_queue_search(phead, plist) == true)
1976 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
1977 if (!mac_pton(data, bssid)) {
1978 netdev_info(dev, "r8712u: Invalid BSSID '%s'.\n",
1980 spin_unlock_irqrestore(&(pmlmepriv->scanned_queue.lock),
1984 netdev_info(dev, "r8712u: BSSID:%pM\n", bssid);
1985 if (!memcmp(bssid, pnetwork->network.MacAddress, ETH_ALEN)) {
1986 /* BSSID match, then check if supporting wpa/wpa2 */
1987 pbuf = r8712_get_wpa_ie(&pnetwork->network.IEs[12],
1988 &wpa_ielen, pnetwork->network.IELength-12);
1989 if (pbuf && (wpa_ielen > 0)) {
1993 pbuf = r8712_get_wpa2_ie(&pnetwork->network.IEs[12],
1994 &wpa_ielen, pnetwork->network.IELength-12);
1995 if (pbuf && (wpa_ielen > 0)) {
2000 plist = plist->next;
2002 spin_unlock_irqrestore(&(pmlmepriv->scanned_queue.lock), irqL);
2003 if (pdata->length >= 34) {
2004 if (copy_to_user((u8 __user *)pdata->pointer + 32,
2005 (u8 *)&pdata->flags, 1))
2011 static int r871x_set_pid(struct net_device *dev,
2012 struct iw_request_info *info,
2013 union iwreq_data *wrqu, char *extra)
2015 struct _adapter *padapter = netdev_priv(dev);
2016 struct iw_point *pdata = &wrqu->data;
2018 if ((padapter->bDriverStopped) || (pdata == NULL))
2020 if (copy_from_user(&padapter->pid, pdata->pointer, sizeof(int)))
2025 static int r871x_set_chplan(struct net_device *dev,
2026 struct iw_request_info *info,
2027 union iwreq_data *wrqu, char *extra)
2030 struct _adapter *padapter = netdev_priv(dev);
2031 struct iw_point *pdata = &wrqu->data;
2034 if ((padapter->bDriverStopped) || (pdata == NULL)) {
2038 ch_plan = (int)*extra;
2039 r8712_set_chplan_cmd(padapter, ch_plan);
2046 static int r871x_wps_start(struct net_device *dev,
2047 struct iw_request_info *info,
2048 union iwreq_data *wrqu, char *extra)
2050 struct _adapter *padapter = netdev_priv(dev);
2051 struct iw_point *pdata = &wrqu->data;
2052 u32 u32wps_start = 0;
2054 if ((padapter->bDriverStopped) || (pdata == NULL))
2056 if (copy_from_user((void *)&u32wps_start, pdata->pointer, 4))
2058 if (u32wps_start == 0)
2059 u32wps_start = *extra;
2060 if (u32wps_start == 1) /* WPS Start */
2061 padapter->ledpriv.LedControlHandler(padapter,
2063 else if (u32wps_start == 2) /* WPS Stop because of wps success */
2064 padapter->ledpriv.LedControlHandler(padapter,
2066 else if (u32wps_start == 3) /* WPS Stop because of wps fail */
2067 padapter->ledpriv.LedControlHandler(padapter,
2068 LED_CTL_STOP_WPS_FAIL);
2072 static int wpa_set_param(struct net_device *dev, u8 name, u32 value)
2074 struct _adapter *padapter = netdev_priv(dev);
2077 case IEEE_PARAM_WPA_ENABLED:
2078 padapter->securitypriv.AuthAlgrthm = 2; /* 802.1x */
2079 switch ((value)&0xff) {
2081 padapter->securitypriv.ndisauthtype =
2082 Ndis802_11AuthModeWPAPSK; /* WPA_PSK */
2083 padapter->securitypriv.ndisencryptstatus =
2084 Ndis802_11Encryption2Enabled;
2087 padapter->securitypriv.ndisauthtype =
2088 Ndis802_11AuthModeWPA2PSK; /* WPA2_PSK */
2089 padapter->securitypriv.ndisencryptstatus =
2090 Ndis802_11Encryption3Enabled;
2094 case IEEE_PARAM_TKIP_COUNTERMEASURES:
2096 case IEEE_PARAM_DROP_UNENCRYPTED:
2099 * wpa_supplicant calls set_wpa_enabled when the driver
2100 * is loaded and unloaded, regardless of if WPA is being
2101 * used. No other calls are made which can be used to
2102 * determine if encryption will be used or not prior to
2103 * association being expected. If encryption is not being
2104 * used, drop_unencrypted is set to false, else true -- we
2105 * can use this to determine if the CAP_PRIVACY_ON bit should
2109 case IEEE_PARAM_PRIVACY_INVOKED:
2111 case IEEE_PARAM_AUTH_ALGS:
2112 return wpa_set_auth_algs(dev, value);
2113 case IEEE_PARAM_IEEE_802_1X:
2115 case IEEE_PARAM_WPAX_SELECT:
2116 /* added for WPA2 mixed mode */
2124 static int wpa_mlme(struct net_device *dev, u32 command, u32 reason)
2126 struct _adapter *padapter = netdev_priv(dev);
2129 case IEEE_MLME_STA_DEAUTH:
2130 if (!r8712_set_802_11_disassociate(padapter))
2133 case IEEE_MLME_STA_DISASSOC:
2134 if (!r8712_set_802_11_disassociate(padapter))
2143 static int wpa_supplicant_ioctl(struct net_device *dev, struct iw_point *p)
2145 struct ieee_param *param;
2147 struct _adapter *padapter = netdev_priv(dev);
2149 if (p->length < sizeof(struct ieee_param) || !p->pointer)
2151 param = memdup_user(p->pointer, p->length);
2153 return PTR_ERR(param);
2154 switch (param->cmd) {
2155 case IEEE_CMD_SET_WPA_PARAM:
2156 ret = wpa_set_param(dev, param->u.wpa_param.name,
2157 param->u.wpa_param.value);
2159 case IEEE_CMD_SET_WPA_IE:
2160 ret = r871x_set_wpa_ie(padapter, (char *)param->u.wpa_ie.data,
2161 (u16)param->u.wpa_ie.len);
2163 case IEEE_CMD_SET_ENCRYPTION:
2164 ret = wpa_set_encryption(dev, param, p->length);
2167 ret = wpa_mlme(dev, param->u.mlme.command,
2168 param->u.mlme.reason_code);
2174 if (ret == 0 && copy_to_user(p->pointer, param, p->length))
2180 /* based on "driver_ipw" and for hostapd */
2181 int r871x_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
2183 struct iwreq *wrq = (struct iwreq *)rq;
2186 case RTL_IOCTL_WPA_SUPPLICANT:
2187 return wpa_supplicant_ioctl(dev, &wrq->u.data);
2194 static iw_handler r8711_handlers[] = {
2195 NULL, /* SIOCSIWCOMMIT */
2196 r8711_wx_get_name, /* SIOCGIWNAME */
2197 dummy, /* SIOCSIWNWID */
2198 dummy, /* SIOCGIWNWID */
2199 r8711_wx_set_freq, /* SIOCSIWFREQ */
2200 r8711_wx_get_freq, /* SIOCGIWFREQ */
2201 r8711_wx_set_mode, /* SIOCSIWMODE */
2202 r8711_wx_get_mode, /* SIOCGIWMODE */
2203 dummy, /* SIOCSIWSENS */
2204 r8711_wx_get_sens, /* SIOCGIWSENS */
2205 NULL, /* SIOCSIWRANGE */
2206 r8711_wx_get_range, /* SIOCGIWRANGE */
2207 r871x_wx_set_priv, /* SIOCSIWPRIV */
2208 NULL, /* SIOCGIWPRIV */
2209 NULL, /* SIOCSIWSTATS */
2210 NULL, /* SIOCGIWSTATS */
2211 dummy, /* SIOCSIWSPY */
2212 dummy, /* SIOCGIWSPY */
2213 NULL, /* SIOCGIWTHRSPY */
2214 NULL, /* SIOCWIWTHRSPY */
2215 r8711_wx_set_wap, /* SIOCSIWAP */
2216 r8711_wx_get_wap, /* SIOCGIWAP */
2217 r871x_wx_set_mlme, /* request MLME operation;
2218 * uses struct iw_mlme */
2219 dummy, /* SIOCGIWAPLIST -- deprecated */
2220 r8711_wx_set_scan, /* SIOCSIWSCAN */
2221 r8711_wx_get_scan, /* SIOCGIWSCAN */
2222 r8711_wx_set_essid, /* SIOCSIWESSID */
2223 r8711_wx_get_essid, /* SIOCGIWESSID */
2224 dummy, /* SIOCSIWNICKN */
2225 r871x_wx_get_nick, /* SIOCGIWNICKN */
2226 NULL, /* -- hole -- */
2227 NULL, /* -- hole -- */
2228 r8711_wx_set_rate, /* SIOCSIWRATE */
2229 r8711_wx_get_rate, /* SIOCGIWRATE */
2230 dummy, /* SIOCSIWRTS */
2231 r8711_wx_get_rts, /* SIOCGIWRTS */
2232 r8711_wx_set_frag, /* SIOCSIWFRAG */
2233 r8711_wx_get_frag, /* SIOCGIWFRAG */
2234 dummy, /* SIOCSIWTXPOW */
2235 dummy, /* SIOCGIWTXPOW */
2236 dummy, /* SIOCSIWRETRY */
2237 r8711_wx_get_retry, /* SIOCGIWRETRY */
2238 r8711_wx_set_enc, /* SIOCSIWENCODE */
2239 r8711_wx_get_enc, /* SIOCGIWENCODE */
2240 dummy, /* SIOCSIWPOWER */
2241 r8711_wx_get_power, /* SIOCGIWPOWER */
2242 NULL, /*---hole---*/
2243 NULL, /*---hole---*/
2244 r871x_wx_set_gen_ie, /* SIOCSIWGENIE */
2245 NULL, /* SIOCGIWGENIE */
2246 r871x_wx_set_auth, /* SIOCSIWAUTH */
2247 NULL, /* SIOCGIWAUTH */
2248 r871x_wx_set_enc_ext, /* SIOCSIWENCODEEXT */
2249 NULL, /* SIOCGIWENCODEEXT */
2250 r871x_wx_set_pmkid, /* SIOCSIWPMKSA */
2251 NULL, /*---hole---*/
2254 static const struct iw_priv_args r8711_private_args[] = {
2256 SIOCIWFIRSTPRIV + 0x0,
2257 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "read32"
2260 SIOCIWFIRSTPRIV + 0x1,
2261 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "write32"
2264 SIOCIWFIRSTPRIV + 0x2, 0, 0, "driver_ext"
2267 SIOCIWFIRSTPRIV + 0x3, 0, 0, "mp_ioctl"
2270 SIOCIWFIRSTPRIV + 0x4,
2271 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "apinfo"
2274 SIOCIWFIRSTPRIV + 0x5,
2275 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setpid"
2278 SIOCIWFIRSTPRIV + 0x6,
2279 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wps_start"
2282 SIOCIWFIRSTPRIV + 0x7,
2283 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "chplan"
2287 static iw_handler r8711_private_handler[] = {
2292 r871x_get_ap_info, /*for MM DTV platform*/
2298 static struct iw_statistics *r871x_get_wireless_stats(struct net_device *dev)
2300 struct _adapter *padapter = netdev_priv(dev);
2301 struct iw_statistics *piwstats = &padapter->iwstats;
2306 if (check_fwstate(&padapter->mlmepriv, _FW_LINKED) != true) {
2307 piwstats->qual.qual = 0;
2308 piwstats->qual.level = 0;
2309 piwstats->qual.noise = 0;
2311 /* show percentage, we need transfer dbm to orignal value. */
2312 tmp_level = padapter->recvpriv.fw_rssi;
2313 tmp_qual = padapter->recvpriv.signal;
2314 tmp_noise = padapter->recvpriv.noise;
2315 piwstats->qual.level = tmp_level;
2316 piwstats->qual.qual = tmp_qual;
2317 piwstats->qual.noise = tmp_noise;
2319 piwstats->qual.updated = IW_QUAL_ALL_UPDATED;
2320 return &padapter->iwstats;
2323 struct iw_handler_def r871x_handlers_def = {
2324 .standard = r8711_handlers,
2325 .num_standard = ARRAY_SIZE(r8711_handlers),
2326 .private = r8711_private_handler,
2327 .private_args = (struct iw_priv_args *)r8711_private_args,
2328 .num_private = ARRAY_SIZE(r8711_private_handler),
2329 .num_private_args = sizeof(r8711_private_args) /
2330 sizeof(struct iw_priv_args),
2331 .get_wireless_stats = r871x_get_wireless_stats