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,
122 (param->u.crypt.key_len > 16 ? 16 :
123 param->u.crypt.key_len));
124 memcpy(padapter->securitypriv.XGrptxmickey[param->
125 u.crypt.idx - 1].skey, &(param->u.crypt.key[16]), 8);
126 memcpy(padapter->securitypriv. XGrprxmickey[param->
127 u.crypt.idx - 1].skey, &(param->u.crypt.key[24]), 8);
128 padapter->securitypriv.binstallGrpkey = true;
129 r8712_set_key(padapter, &padapter->securitypriv,
131 if (padapter->registrypriv.power_mgnt > PS_MODE_ACTIVE) {
132 if (padapter->registrypriv.power_mgnt != padapter->
133 pwrctrlpriv.pwr_mode)
134 mod_timer(&padapter->mlmepriv.dhcp_timer,
135 jiffies + msecs_to_jiffies(60000));
140 static noinline_for_stack char *translate_scan(struct _adapter *padapter,
141 struct iw_request_info *info,
142 struct wlan_network *pnetwork,
143 char *start, char *stop)
146 struct ieee80211_ht_cap *pht_capie;
149 u32 i = 0, ht_ielen = 0;
150 u16 cap, ht_cap = false, mcs_rate;
153 if ((pnetwork->network.Configuration.DSConfig < 1) ||
154 (pnetwork->network.Configuration.DSConfig > 14)) {
155 if (pnetwork->network.Configuration.DSConfig < 1)
156 pnetwork->network.Configuration.DSConfig = 1;
158 pnetwork->network.Configuration.DSConfig = 14;
162 iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
163 ether_addr_copy(iwe.u.ap_addr.sa_data, pnetwork->network.MacAddress);
164 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_ADDR_LEN);
166 iwe.cmd = SIOCGIWESSID;
167 iwe.u.data.flags = 1;
168 iwe.u.data.length = min_t(u32, pnetwork->network.Ssid.SsidLength, 32);
169 start = iwe_stream_add_point(info, start, stop, &iwe,
170 pnetwork->network.Ssid.Ssid);
171 /* parsing HT_CAP_IE */
172 p = r8712_get_ie(&pnetwork->network.IEs[12], _HT_CAPABILITY_IE_,
173 &ht_ielen, pnetwork->network.IELength - 12);
174 if (p && ht_ielen > 0) {
176 pht_capie = (struct ieee80211_ht_cap *)(p + 2);
177 memcpy(&mcs_rate, pht_capie->supp_mcs_set, 2);
179 /* Add the protocol name */
180 iwe.cmd = SIOCGIWNAME;
181 if (r8712_is_cckratesonly_included(pnetwork->network.rates)) {
183 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bn");
185 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11b");
186 } else if (r8712_is_cckrates_included(pnetwork->network.rates)) {
188 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bgn");
190 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bg");
193 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11gn");
195 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11g");
197 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_CHAR_LEN);
199 iwe.cmd = SIOCGIWMODE;
200 memcpy((u8 *)&cap, r8712_get_capability_from_ie(pnetwork->network.IEs),
202 cap = le16_to_cpu(cap);
203 if (cap & (WLAN_CAPABILITY_IBSS | WLAN_CAPABILITY_BSS)) {
204 if (cap & WLAN_CAPABILITY_BSS)
205 iwe.u.mode = (u32)IW_MODE_MASTER;
207 iwe.u.mode = (u32)IW_MODE_ADHOC;
208 start = iwe_stream_add_event(info, start, stop, &iwe,
211 /* Add frequency/channel */
212 iwe.cmd = SIOCGIWFREQ;
214 /* check legal index */
215 u8 dsconfig = pnetwork->network.Configuration.DSConfig;
217 if (dsconfig >= 1 && dsconfig <= sizeof(
218 ieee80211_wlan_frequencies) / sizeof(long))
219 iwe.u.freq.m = (s32)(ieee80211_wlan_frequencies[
220 pnetwork->network.Configuration.
221 DSConfig - 1] * 100000);
225 iwe.u.freq.e = (s16)1;
226 iwe.u.freq.i = (u8)pnetwork->network.Configuration.DSConfig;
227 start = iwe_stream_add_event(info, start, stop, &iwe,
229 /* Add encryption capability */
230 iwe.cmd = SIOCGIWENCODE;
231 if (cap & WLAN_CAPABILITY_PRIVACY)
232 iwe.u.data.flags = (u16)(IW_ENCODE_ENABLED |
235 iwe.u.data.flags = (u16)(IW_ENCODE_DISABLED);
236 iwe.u.data.length = (u16)0;
237 start = iwe_stream_add_point(info, start, stop, &iwe,
238 pnetwork->network.Ssid.Ssid);
239 /*Add basic and extended rates */
240 current_val = start + iwe_stream_lcp_len(info);
241 iwe.cmd = SIOCGIWRATE;
242 iwe.u.bitrate.fixed = 0;
243 iwe.u.bitrate.disabled = 0;
244 iwe.u.bitrate.value = 0;
246 while (pnetwork->network.rates[i] != 0) {
247 /* Bit rate given in 500 kb/s units */
248 iwe.u.bitrate.value = (pnetwork->network.rates[i++] &
250 current_val = iwe_stream_add_value(info, start, current_val,
251 stop, &iwe, IW_EV_PARAM_LEN);
253 /* Check if we added any event */
254 if ((current_val - start) > iwe_stream_lcp_len(info))
256 /* parsing WPA/WPA2 IE */
258 u8 buf[MAX_WPA_IE_LEN];
259 u8 wpa_ie[255], rsn_ie[255];
260 u16 wpa_len = 0, rsn_len = 0;
263 r8712_get_sec_ie(pnetwork->network.IEs,
264 pnetwork->network.IELength, rsn_ie, &rsn_len,
267 memset(buf, 0, MAX_WPA_IE_LEN);
268 n = sprintf(buf, "wpa_ie=");
269 for (i = 0; i < wpa_len; i++) {
270 n += snprintf(buf + n, MAX_WPA_IE_LEN - n,
272 if (n >= MAX_WPA_IE_LEN)
275 memset(&iwe, 0, sizeof(iwe));
276 iwe.cmd = IWEVCUSTOM;
277 iwe.u.data.length = (u16)strlen(buf);
278 start = iwe_stream_add_point(info, start, stop,
280 memset(&iwe, 0, sizeof(iwe));
282 iwe.u.data.length = (u16)wpa_len;
283 start = iwe_stream_add_point(info, start, stop,
287 memset(buf, 0, MAX_WPA_IE_LEN);
288 n = sprintf(buf, "rsn_ie=");
289 for (i = 0; i < rsn_len; i++) {
290 n += snprintf(buf + n, MAX_WPA_IE_LEN - n,
292 if (n >= MAX_WPA_IE_LEN)
295 memset(&iwe, 0, sizeof(iwe));
296 iwe.cmd = IWEVCUSTOM;
297 iwe.u.data.length = strlen(buf);
298 start = iwe_stream_add_point(info, start, stop,
300 memset(&iwe, 0, sizeof(iwe));
302 iwe.u.data.length = rsn_len;
303 start = iwe_stream_add_point(info, start, stop, &iwe,
308 { /* parsing WPS IE */
312 if (r8712_get_wps_ie(pnetwork->network.IEs,
313 pnetwork->network.IELength,
314 wps_ie, &wps_ielen)) {
317 iwe.u.data.length = (u16)wps_ielen;
318 start = iwe_stream_add_point(info, 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)) {
382 if (param->u.crypt.idx >= WEP_KEYS) {
383 /* for large key indices, set the default (0) */
384 param->u.crypt.idx = 0;
389 if (strcmp(param->u.crypt.alg, "WEP") == 0) {
390 netdev_info(dev, "r8712u: %s: crypt.alg = WEP\n", __func__);
391 padapter->securitypriv.ndisencryptstatus =
392 Ndis802_11Encryption1Enabled;
393 padapter->securitypriv.PrivacyAlgrthm = _WEP40_;
394 padapter->securitypriv.XGrpPrivacy = _WEP40_;
395 wep_key_idx = param->u.crypt.idx;
396 wep_key_len = param->u.crypt.key_len;
397 if (wep_key_idx >= WEP_KEYS)
399 if (wep_key_len > 0) {
400 wep_key_len = wep_key_len <= 5 ? 5 : 13;
401 pwep = kzalloc(sizeof(*pwep), GFP_ATOMIC);
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 =
417 pwep->KeyIndex = wep_key_idx;
418 pwep->KeyIndex |= 0x80000000;
419 memcpy(pwep->KeyMaterial, param->u.crypt.key, pwep->KeyLength);
420 if (param->u.crypt.set_tx) {
421 if (r8712_set_802_11_add_wep(padapter, pwep) ==
425 /* don't update "psecuritypriv->PrivacyAlgrthm" and
426 * "psecuritypriv->PrivacyKeyIndex=keyid", but can
427 * r8712_set_key to fw/cam
429 if (wep_key_idx >= WEP_KEYS) {
433 memcpy(&(psecuritypriv->DefKey[wep_key_idx].
434 skey[0]), pwep->KeyMaterial,
436 psecuritypriv->DefKeylen[wep_key_idx] =
438 r8712_set_key(padapter, psecuritypriv, wep_key_idx);
442 if (padapter->securitypriv.AuthAlgrthm == 2) { /* 802_1x */
443 struct sta_info *psta, *pbcmc_sta;
444 struct sta_priv *pstapriv = &padapter->stapriv;
446 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE |
447 WIFI_MP_STATE)) { /* sta mode */
448 psta = r8712_get_stainfo(pstapriv,
449 get_bssid(pmlmepriv));
451 psta->ieee8021x_blocked = false;
452 if ((padapter->securitypriv.ndisencryptstatus ==
453 Ndis802_11Encryption2Enabled) ||
454 (padapter->securitypriv.ndisencryptstatus ==
455 Ndis802_11Encryption3Enabled))
456 psta->XPrivacy = padapter->
457 securitypriv.PrivacyAlgrthm;
458 if (param->u.crypt.set_tx == 1)
459 handle_pairwise_key(psta, param,
462 handle_group_key(param, padapter);
464 pbcmc_sta = r8712_get_bcmc_stainfo(padapter);
466 pbcmc_sta->ieee8021x_blocked = false;
467 if ((padapter->securitypriv.ndisencryptstatus ==
468 Ndis802_11Encryption2Enabled) ||
469 (padapter->securitypriv.ndisencryptstatus ==
470 Ndis802_11Encryption3Enabled))
471 pbcmc_sta->XPrivacy =
472 padapter->securitypriv.
482 static int r871x_set_wpa_ie(struct _adapter *padapter, char *pie,
483 unsigned short ielen)
486 int group_cipher = 0, pairwise_cipher = 0;
489 if ((ielen > MAX_WPA_IE_LEN) || (pie == NULL))
492 buf = kmemdup(pie, ielen, GFP_ATOMIC);
495 if (ielen < RSN_HEADER_LEN) {
499 if (r8712_parse_wpa_ie(buf, ielen, &group_cipher,
500 &pairwise_cipher) == _SUCCESS) {
501 padapter->securitypriv.AuthAlgrthm = 2;
502 padapter->securitypriv.ndisauthtype =
503 Ndis802_11AuthModeWPAPSK;
505 if (r8712_parse_wpa2_ie(buf, ielen, &group_cipher,
506 &pairwise_cipher) == _SUCCESS) {
507 padapter->securitypriv.AuthAlgrthm = 2;
508 padapter->securitypriv.ndisauthtype =
509 Ndis802_11AuthModeWPA2PSK;
511 switch (group_cipher) {
512 case WPA_CIPHER_NONE:
513 padapter->securitypriv.XGrpPrivacy =
515 padapter->securitypriv.ndisencryptstatus =
516 Ndis802_11EncryptionDisabled;
518 case WPA_CIPHER_WEP40:
519 padapter->securitypriv.XGrpPrivacy = _WEP40_;
520 padapter->securitypriv.ndisencryptstatus =
521 Ndis802_11Encryption1Enabled;
523 case WPA_CIPHER_TKIP:
524 padapter->securitypriv.XGrpPrivacy = _TKIP_;
525 padapter->securitypriv.ndisencryptstatus =
526 Ndis802_11Encryption2Enabled;
528 case WPA_CIPHER_CCMP:
529 padapter->securitypriv.XGrpPrivacy = _AES_;
530 padapter->securitypriv.ndisencryptstatus =
531 Ndis802_11Encryption3Enabled;
533 case WPA_CIPHER_WEP104:
534 padapter->securitypriv.XGrpPrivacy = _WEP104_;
535 padapter->securitypriv.ndisencryptstatus =
536 Ndis802_11Encryption1Enabled;
539 switch (pairwise_cipher) {
540 case WPA_CIPHER_NONE:
541 padapter->securitypriv.PrivacyAlgrthm =
543 padapter->securitypriv.ndisencryptstatus =
544 Ndis802_11EncryptionDisabled;
546 case WPA_CIPHER_WEP40:
547 padapter->securitypriv.PrivacyAlgrthm = _WEP40_;
548 padapter->securitypriv.ndisencryptstatus =
549 Ndis802_11Encryption1Enabled;
551 case WPA_CIPHER_TKIP:
552 padapter->securitypriv.PrivacyAlgrthm = _TKIP_;
553 padapter->securitypriv.ndisencryptstatus =
554 Ndis802_11Encryption2Enabled;
556 case WPA_CIPHER_CCMP:
557 padapter->securitypriv.PrivacyAlgrthm = _AES_;
558 padapter->securitypriv.ndisencryptstatus =
559 Ndis802_11Encryption3Enabled;
561 case WPA_CIPHER_WEP104:
562 padapter->securitypriv.PrivacyAlgrthm = _WEP104_;
563 padapter->securitypriv.ndisencryptstatus =
564 Ndis802_11Encryption1Enabled;
567 padapter->securitypriv.wps_phase = false;
570 u8 eid, wps_oui[4] = {0x0, 0x50, 0xf2, 0x04};
572 while (cnt < ielen) {
575 if ((eid == _VENDOR_SPECIFIC_IE_) &&
576 (!memcmp(&buf[cnt + 2], wps_oui, 4))) {
577 netdev_info(padapter->pnetdev, "r8712u: SET WPS_IE\n");
578 padapter->securitypriv.wps_ie_len =
579 ((buf[cnt + 1] + 2) <
580 (MAX_WPA_IE_LEN << 2)) ?
582 (MAX_WPA_IE_LEN << 2);
583 memcpy(padapter->securitypriv.wps_ie,
585 padapter->securitypriv.wps_ie_len);
586 padapter->securitypriv.wps_phase =
588 netdev_info(padapter->pnetdev, "r8712u: SET WPS_IE, wps_phase==true\n");
589 cnt += buf[cnt + 1] + 2;
592 cnt += buf[cnt + 1] + 2;
602 static int r8711_wx_get_name(struct net_device *dev,
603 struct iw_request_info *info,
604 union iwreq_data *wrqu, char *extra)
606 struct _adapter *padapter = netdev_priv(dev);
610 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
611 struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
614 if (check_fwstate(pmlmepriv, _FW_LINKED | WIFI_ADHOC_MASTER_STATE) ==
616 /* parsing HT_CAP_IE */
617 p = r8712_get_ie(&pcur_bss->IEs[12], _HT_CAPABILITY_IE_,
618 &ht_ielen, pcur_bss->IELength - 12);
619 if (p && ht_ielen > 0)
621 prates = pcur_bss->rates;
622 if (r8712_is_cckratesonly_included(prates)) {
624 snprintf(wrqu->name, IFNAMSIZ,
627 snprintf(wrqu->name, IFNAMSIZ,
629 } else if (r8712_is_cckrates_included(prates)) {
631 snprintf(wrqu->name, IFNAMSIZ,
634 snprintf(wrqu->name, IFNAMSIZ,
638 snprintf(wrqu->name, IFNAMSIZ,
641 snprintf(wrqu->name, IFNAMSIZ,
645 snprintf(wrqu->name, IFNAMSIZ, "unassociated");
650 static const long frequency_list[] = {
651 2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447, 2452, 2457, 2462,
652 2467, 2472, 2484, 4915, 4920, 4925, 4935, 4940, 4945, 4960, 4980,
653 5035, 5040, 5045, 5055, 5060, 5080, 5170, 5180, 5190, 5200, 5210,
654 5220, 5230, 5240, 5260, 5280, 5300, 5320, 5500, 5520, 5540, 5560,
655 5580, 5600, 5620, 5640, 5660, 5680, 5700, 5745, 5765, 5785, 5805,
659 static int r8711_wx_set_freq(struct net_device *dev,
660 struct iw_request_info *info,
661 union iwreq_data *wrqu, char *extra)
663 struct _adapter *padapter = netdev_priv(dev);
664 struct iw_freq *fwrq = &wrqu->freq;
667 /* If setting by frequency, convert to a channel */
668 if ((fwrq->e == 1) &&
669 (fwrq->m >= (int) 2.412e8) &&
670 (fwrq->m <= (int) 2.487e8)) {
671 int f = fwrq->m / 100000;
674 while ((c < 14) && (f != frequency_list[c]))
679 /* Setting by channel number */
680 if ((fwrq->m > 14) || (fwrq->e > 0)) {
683 int channel = fwrq->m;
685 if ((channel < 1) || (channel > 14)) {
688 /* Yes ! We can set it !!! */
689 padapter->registrypriv.channel = channel;
695 static int r8711_wx_get_freq(struct net_device *dev,
696 struct iw_request_info *info,
697 union iwreq_data *wrqu, char *extra)
699 struct _adapter *padapter = netdev_priv(dev);
700 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
701 struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
703 if (check_fwstate(pmlmepriv, _FW_LINKED)) {
704 wrqu->freq.m = ieee80211_wlan_frequencies[
705 pcur_bss->Configuration.DSConfig - 1] * 100000;
707 wrqu->freq.i = pcur_bss->Configuration.DSConfig;
714 static int r8711_wx_set_mode(struct net_device *dev,
715 struct iw_request_info *a,
716 union iwreq_data *wrqu, char *b)
718 struct _adapter *padapter = netdev_priv(dev);
719 enum NDIS_802_11_NETWORK_INFRASTRUCTURE networkType;
721 switch (wrqu->mode) {
723 networkType = Ndis802_11AutoUnknown;
726 networkType = Ndis802_11IBSS;
729 networkType = Ndis802_11APMode;
732 networkType = Ndis802_11Infrastructure;
737 if (Ndis802_11APMode == networkType)
738 r8712_setopmode_cmd(padapter, networkType);
740 r8712_setopmode_cmd(padapter, Ndis802_11AutoUnknown);
742 r8712_set_802_11_infrastructure_mode(padapter, networkType);
746 static int r8711_wx_get_mode(struct net_device *dev, struct iw_request_info *a,
747 union iwreq_data *wrqu, char *b)
749 struct _adapter *padapter = netdev_priv(dev);
750 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
752 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE))
753 wrqu->mode = IW_MODE_INFRA;
754 else if (check_fwstate(pmlmepriv,
755 WIFI_ADHOC_MASTER_STATE | WIFI_ADHOC_STATE))
756 wrqu->mode = IW_MODE_ADHOC;
757 else if (check_fwstate(pmlmepriv, WIFI_AP_STATE))
758 wrqu->mode = IW_MODE_MASTER;
760 wrqu->mode = IW_MODE_AUTO;
764 static int r871x_wx_set_pmkid(struct net_device *dev,
765 struct iw_request_info *a,
766 union iwreq_data *wrqu, char *extra)
768 struct _adapter *padapter = netdev_priv(dev);
769 struct security_priv *psecuritypriv = &padapter->securitypriv;
770 struct iw_pmksa *pPMK = (struct iw_pmksa *) extra;
771 u8 strZeroMacAddress[ETH_ALEN] = {0x00};
772 u8 strIssueBssid[ETH_ALEN] = {0x00};
773 u8 j, blInserted = false;
774 int intReturn = false;
777 * There are the BSSID information in the bssid.sa_data array.
778 * If cmd is IW_PMKSA_FLUSH, it means the wpa_supplicant wants to clear
779 * all the PMKID information. If cmd is IW_PMKSA_ADD, it means the
780 * wpa_supplicant wants to add a PMKID/BSSID to driver.
781 * If cmd is IW_PMKSA_REMOVE, it means the wpa_supplicant wants to
782 * remove a PMKID/BSSID from driver.
786 memcpy(strIssueBssid, pPMK->bssid.sa_data, ETH_ALEN);
789 if (!memcmp(strIssueBssid, strZeroMacAddress, ETH_ALEN))
793 /* overwrite PMKID */
794 for (j = 0; j < NUM_PMKID_CACHE; j++) {
795 if (!memcmp(psecuritypriv->PMKIDList[j].Bssid,
796 strIssueBssid, ETH_ALEN)) {
797 /* BSSID is matched, the same AP => rewrite
800 netdev_info(dev, "r8712u: %s: BSSID exists in the PMKList.\n",
802 memcpy(psecuritypriv->PMKIDList[j].PMKID,
803 pPMK->pmkid, IW_PMKID_LEN);
804 psecuritypriv->PMKIDList[j].bUsed = true;
805 psecuritypriv->PMKIDIndex = j + 1;
811 /* Find a new entry */
812 netdev_info(dev, "r8712u: %s: Use the new entry index = %d for this PMKID.\n",
813 __func__, psecuritypriv->PMKIDIndex);
814 memcpy(psecuritypriv->PMKIDList[psecuritypriv->
815 PMKIDIndex].Bssid, strIssueBssid, ETH_ALEN);
816 memcpy(psecuritypriv->PMKIDList[psecuritypriv->
817 PMKIDIndex].PMKID, pPMK->pmkid, IW_PMKID_LEN);
818 psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].
820 psecuritypriv->PMKIDIndex++;
821 if (psecuritypriv->PMKIDIndex == NUM_PMKID_CACHE)
822 psecuritypriv->PMKIDIndex = 0;
825 case IW_PMKSA_REMOVE:
827 for (j = 0; j < NUM_PMKID_CACHE; j++) {
828 if (!memcmp(psecuritypriv->PMKIDList[j].Bssid,
829 strIssueBssid, ETH_ALEN)) {
830 /* BSSID is matched, the same AP => Remove
831 * this PMKID information and reset it.
833 eth_zero_addr(psecuritypriv->PMKIDList[j].Bssid);
834 psecuritypriv->PMKIDList[j].bUsed = false;
840 memset(psecuritypriv->PMKIDList, 0,
841 sizeof(struct RT_PMKID_LIST) * NUM_PMKID_CACHE);
842 psecuritypriv->PMKIDIndex = 0;
846 netdev_info(dev, "r8712u: %s: unknown Command\n", __func__);
853 static int r8711_wx_get_sens(struct net_device *dev,
854 struct iw_request_info *info,
855 union iwreq_data *wrqu, char *extra)
857 wrqu->sens.value = 0;
858 wrqu->sens.fixed = 0; /* no auto select */
859 wrqu->sens.disabled = 1;
863 static int r8711_wx_get_range(struct net_device *dev,
864 struct iw_request_info *info,
865 union iwreq_data *wrqu, char *extra)
867 struct iw_range *range = (struct iw_range *)extra;
871 wrqu->data.length = sizeof(*range);
872 memset(range, 0, sizeof(*range));
873 /* Let's try to keep this struct in the same order as in
874 * linux/include/wireless.h
877 /* TODO: See what values we can set, and remove the ones we can't
878 * set, or fill them with some default data.
880 /* ~5 Mb/s real (802.11b) */
881 range->throughput = 5 * 1000 * 1000;
882 /* TODO: 8711 sensitivity ? */
883 /* signal level threshold range */
884 /* percent values between 0 and 100. */
885 range->max_qual.qual = 100;
886 range->max_qual.level = 100;
887 range->max_qual.noise = 100;
888 range->max_qual.updated = 7; /* Updated all three */
889 range->avg_qual.qual = 92; /* > 8% missed beacons is 'bad' */
890 /* TODO: Find real 'good' to 'bad' threshold value for RSSI */
891 range->avg_qual.level = 0x100 - 78;
892 range->avg_qual.noise = 0;
893 range->avg_qual.updated = 7; /* Updated all three */
894 range->num_bitrates = RATE_COUNT;
895 for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++)
896 range->bitrate[i] = rtl8180_rates[i];
897 range->min_frag = MIN_FRAG_THRESHOLD;
898 range->max_frag = MAX_FRAG_THRESHOLD;
900 range->we_version_compiled = WIRELESS_EXT;
901 range->we_version_source = 16;
902 range->num_channels = 14;
903 for (i = 0, val = 0; i < 14; i++) {
904 /* Include only legal frequencies for some countries */
905 range->freq[val].i = i + 1;
906 range->freq[val].m = ieee80211_wlan_frequencies[i] * 100000;
907 range->freq[val].e = 1;
909 if (val == IW_MAX_FREQUENCIES)
912 range->num_frequency = val;
913 range->enc_capa = IW_ENC_CAPA_WPA |
915 IW_ENC_CAPA_CIPHER_TKIP |
916 IW_ENC_CAPA_CIPHER_CCMP;
920 static int r8711_wx_get_rate(struct net_device *dev,
921 struct iw_request_info *info,
922 union iwreq_data *wrqu, char *extra);
924 static int r871x_wx_set_priv(struct net_device *dev,
925 struct iw_request_info *info,
926 union iwreq_data *awrq,
929 int ret = 0, len = 0;
931 struct _adapter *padapter = netdev_priv(dev);
932 struct iw_point *dwrq = (struct iw_point *)awrq;
935 ext = memdup_user(dwrq->pointer, len);
939 if (!strcasecmp(ext, "RSSI")) {
940 /*Return received signal strength indicator in -db for */
943 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
944 struct wlan_network *pcur_network = &pmlmepriv->cur_network;
946 if (check_fwstate(pmlmepriv, _FW_LINKED)) {
947 sprintf(ext, "%s rssi %d",
948 pcur_network->network.Ssid.Ssid,
950 ((padapter->recvpriv.fw_rssi) >> 1) - 95
951 /*pcur_network->network.Rssi */
956 } else if (!strcasecmp(ext, "LINKSPEED")) {
957 /*Return link speed in MBPS */
959 union iwreq_data wrqd;
963 ret_inner = r8711_wx_get_rate(dev, info, &wrqd, extra);
967 mbps = wrqd.bitrate.value / 1000000;
968 sprintf(ext, "LINKSPEED %d", mbps);
969 } else if (!strcasecmp(ext, "MACADDR")) {
970 /*Return mac address of the station */
971 /* Macaddr = xx:xx:xx:xx:xx:xx */
972 sprintf(ext, "MACADDR = %pM", dev->dev_addr);
973 } else if (!strcasecmp(ext, "SCAN-ACTIVE")) {
974 /*Set scan type to active */
975 /*OK if successful */
976 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
978 pmlmepriv->passive_mode = 1;
980 } else if (!strcasecmp(ext, "SCAN-PASSIVE")) {
981 /*Set scan type to passive */
982 /*OK if successful */
983 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
985 pmlmepriv->passive_mode = 0;
987 } else if (!strncmp(ext, "DCE-E", 5)) {
988 /*Set scan type to passive */
989 /*OK if successful */
990 r8712_disconnectCtrlEx_cmd(padapter
991 , 1 /*u32 enableDrvCtrl */
992 , 5 /*u32 tryPktCnt */
993 , 100 /*u32 tryPktInterval */
994 , 5000 /*u32 firstStageTO */
997 } else if (!strncmp(ext, "DCE-D", 5)) {
998 /*Set scan type to passive */
1000 r8712_disconnectCtrlEx_cmd(padapter
1001 , 0 /*u32 enableDrvCtrl */
1002 , 5 /*u32 tryPktCnt */
1003 , 100 /*u32 tryPktInterval */
1004 , 5000 /*u32 firstStageTO */
1008 netdev_info(dev, "r8712u: %s: unknown Command %s.\n",
1012 if (copy_to_user(dwrq->pointer, ext,
1013 min(dwrq->length, (__u16)(strlen(ext) + 1))))
1022 * s1. set_802_11_infrastructure_mode()
1023 * s2. set_802_11_authentication_mode()
1024 * s3. set_802_11_encryption_mode()
1025 * s4. set_802_11_bssid()
1027 * This function intends to handle the Set AP command, which specifies the
1028 * MAC# of a preferred Access Point.
1029 * Currently, the request comes via Wireless Extensions' SIOCSIWAP ioctl.
1031 * For this operation to succeed, there is no need for the interface to be up.
1034 static int r8711_wx_set_wap(struct net_device *dev,
1035 struct iw_request_info *info,
1036 union iwreq_data *awrq,
1039 int ret = -EINPROGRESS;
1040 struct _adapter *padapter = netdev_priv(dev);
1041 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1042 struct __queue *queue = &pmlmepriv->scanned_queue;
1043 struct sockaddr *temp = (struct sockaddr *)awrq;
1045 struct list_head *phead;
1047 struct wlan_network *pnetwork = NULL;
1048 enum NDIS_802_11_AUTHENTICATION_MODE authmode;
1050 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY))
1052 if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING))
1054 if (temp->sa_family != ARPHRD_ETHER)
1056 authmode = padapter->securitypriv.ndisauthtype;
1057 spin_lock_irqsave(&queue->lock, irqL);
1058 phead = &queue->queue;
1059 pmlmepriv->pscanned = phead->next;
1061 if (end_of_queue_search(phead, pmlmepriv->pscanned))
1063 pnetwork = container_of(pmlmepriv->pscanned,
1064 struct wlan_network, list);
1065 pmlmepriv->pscanned = pmlmepriv->pscanned->next;
1066 dst_bssid = pnetwork->network.MacAddress;
1067 if (!memcmp(dst_bssid, temp->sa_data, ETH_ALEN)) {
1068 r8712_set_802_11_infrastructure_mode(padapter,
1069 pnetwork->network.InfrastructureMode);
1073 spin_unlock_irqrestore(&queue->lock, irqL);
1075 if (!r8712_set_802_11_authentication_mode(padapter, authmode)) {
1078 if (!r8712_set_802_11_bssid(padapter, temp->sa_data))
1085 static int r8711_wx_get_wap(struct net_device *dev,
1086 struct iw_request_info *info,
1087 union iwreq_data *wrqu, char *extra)
1089 struct _adapter *padapter = netdev_priv(dev);
1090 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1091 struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
1093 wrqu->ap_addr.sa_family = ARPHRD_ETHER;
1094 if (check_fwstate(pmlmepriv, _FW_LINKED | WIFI_ADHOC_MASTER_STATE |
1096 ether_addr_copy(wrqu->ap_addr.sa_data, pcur_bss->MacAddress);
1098 eth_zero_addr(wrqu->ap_addr.sa_data);
1102 static int r871x_wx_set_mlme(struct net_device *dev,
1103 struct iw_request_info *info,
1104 union iwreq_data *wrqu, char *extra)
1107 struct _adapter *padapter = netdev_priv(dev);
1108 struct iw_mlme *mlme = (struct iw_mlme *) extra;
1112 switch (mlme->cmd) {
1113 case IW_MLME_DEAUTH:
1114 if (!r8712_set_802_11_disassociate(padapter))
1117 case IW_MLME_DISASSOC:
1118 if (!r8712_set_802_11_disassociate(padapter))
1129 * This function intends to handle the Set Scan command.
1130 * Currently, the request comes via Wireless Extensions' SIOCSIWSCAN ioctl.
1132 * For this operation to succeed, the interface is brought Up beforehand.
1135 static int r8711_wx_set_scan(struct net_device *dev,
1136 struct iw_request_info *a,
1137 union iwreq_data *wrqu, char *extra)
1139 struct _adapter *padapter = netdev_priv(dev);
1140 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1143 if (padapter->bDriverStopped) {
1144 netdev_info(dev, "In %s: bDriverStopped=%d\n",
1145 __func__, padapter->bDriverStopped);
1150 if (!padapter->hw_init_completed)
1152 if ((check_fwstate(pmlmepriv, _FW_UNDER_SURVEY | _FW_UNDER_LINKING)) ||
1153 (pmlmepriv->sitesurveyctrl.traffic_busy))
1155 if (wrqu->data.length == sizeof(struct iw_scan_req)) {
1156 struct iw_scan_req *req = (struct iw_scan_req *)extra;
1158 if (wrqu->data.flags & IW_SCAN_THIS_ESSID) {
1159 struct ndis_802_11_ssid ssid;
1161 u32 len = min_t(u8, req->essid_len, IW_ESSID_MAX_SIZE);
1163 memset((unsigned char *)&ssid, 0,
1164 sizeof(struct ndis_802_11_ssid));
1165 memcpy(ssid.Ssid, req->essid, len);
1166 ssid.SsidLength = len;
1167 spin_lock_irqsave(&pmlmepriv->lock, irqL);
1168 if ((check_fwstate(pmlmepriv, _FW_UNDER_SURVEY |
1169 _FW_UNDER_LINKING)) ||
1170 (pmlmepriv->sitesurveyctrl.traffic_busy)) {
1171 if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING))
1174 status = r8712_sitesurvey_cmd(padapter, &ssid);
1176 spin_unlock_irqrestore(&pmlmepriv->lock, irqL);
1179 status = r8712_set_802_11_bssid_list_scan(padapter);
1186 static int r8711_wx_get_scan(struct net_device *dev,
1187 struct iw_request_info *a,
1188 union iwreq_data *wrqu, char *extra)
1190 struct _adapter *padapter = netdev_priv(dev);
1191 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1192 struct __queue *queue = &pmlmepriv->scanned_queue;
1193 struct wlan_network *pnetwork = NULL;
1195 struct list_head *plist, *phead;
1197 char *stop = ev + wrqu->data.length;
1198 u32 ret = 0, cnt = 0;
1200 if (padapter->bDriverStopped)
1202 while (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY |
1203 _FW_UNDER_LINKING)) {
1209 spin_lock_irqsave(&queue->lock, irqL);
1210 phead = &queue->queue;
1211 plist = phead->next;
1213 if (end_of_queue_search(phead, plist))
1215 if ((stop - ev) < SCAN_ITEM_SIZE) {
1219 pnetwork = container_of(plist, struct wlan_network, list);
1220 ev = translate_scan(padapter, a, pnetwork, ev, stop);
1221 plist = plist->next;
1223 spin_unlock_irqrestore(&queue->lock, irqL);
1224 wrqu->data.length = ev - extra;
1225 wrqu->data.flags = 0;
1230 * s1. set_802_11_infrastructure_mode()
1231 * s2. set_802_11_authenticaion_mode()
1232 * s3. set_802_11_encryption_mode()
1233 * s4. set_802_11_ssid()
1235 * This function intends to handle the Set ESSID command.
1236 * Currently, the request comes via the Wireless Extensions' SIOCSIWESSID ioctl.
1238 * For this operation to succeed, there is no need for the interface to be Up.
1241 static int r8711_wx_set_essid(struct net_device *dev,
1242 struct iw_request_info *a,
1243 union iwreq_data *wrqu, char *extra)
1245 struct _adapter *padapter = netdev_priv(dev);
1246 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1247 struct __queue *queue = &pmlmepriv->scanned_queue;
1248 struct wlan_network *pnetwork = NULL;
1249 enum NDIS_802_11_AUTHENTICATION_MODE authmode;
1250 struct ndis_802_11_ssid ndis_ssid;
1251 u8 *dst_ssid, *src_ssid;
1252 struct list_head *phead;
1255 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY))
1257 if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING))
1259 if (wrqu->essid.length > IW_ESSID_MAX_SIZE)
1261 authmode = padapter->securitypriv.ndisauthtype;
1262 if (wrqu->essid.flags && wrqu->essid.length) {
1263 len = (wrqu->essid.length < IW_ESSID_MAX_SIZE) ?
1264 wrqu->essid.length : IW_ESSID_MAX_SIZE;
1265 memset(&ndis_ssid, 0, sizeof(struct ndis_802_11_ssid));
1266 ndis_ssid.SsidLength = len;
1267 memcpy(ndis_ssid.Ssid, extra, len);
1268 src_ssid = ndis_ssid.Ssid;
1269 phead = &queue->queue;
1270 pmlmepriv->pscanned = phead->next;
1272 if (end_of_queue_search(phead, pmlmepriv->pscanned))
1274 pnetwork = container_of(pmlmepriv->pscanned,
1275 struct wlan_network, list);
1276 pmlmepriv->pscanned = pmlmepriv->pscanned->next;
1277 dst_ssid = pnetwork->network.Ssid.Ssid;
1278 if ((!memcmp(dst_ssid, src_ssid, ndis_ssid.SsidLength))
1279 && (pnetwork->network.Ssid.SsidLength ==
1280 ndis_ssid.SsidLength)) {
1281 if (check_fwstate(pmlmepriv,
1282 WIFI_ADHOC_STATE)) {
1283 if (pnetwork->network.
1287 cur_network.network.
1292 r8712_set_802_11_infrastructure_mode(
1294 pnetwork->network.InfrastructureMode);
1298 r8712_set_802_11_authentication_mode(padapter, authmode);
1299 r8712_set_802_11_ssid(padapter, &ndis_ssid);
1301 return -EINPROGRESS;
1304 static int r8711_wx_get_essid(struct net_device *dev,
1305 struct iw_request_info *a,
1306 union iwreq_data *wrqu, char *extra)
1308 struct _adapter *padapter = netdev_priv(dev);
1309 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1310 struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
1313 if (check_fwstate(pmlmepriv, _FW_LINKED | WIFI_ADHOC_MASTER_STATE)) {
1314 len = pcur_bss->Ssid.SsidLength;
1315 wrqu->essid.length = len;
1316 memcpy(extra, pcur_bss->Ssid.Ssid, len);
1317 wrqu->essid.flags = 1;
1324 static int r8711_wx_set_rate(struct net_device *dev,
1325 struct iw_request_info *a,
1326 union iwreq_data *wrqu, char *extra)
1328 struct _adapter *padapter = netdev_priv(dev);
1329 u32 target_rate = wrqu->bitrate.value;
1330 u32 fixed = wrqu->bitrate.fixed;
1332 u8 datarates[NumRates];
1333 u8 mpdatarate[NumRates] = {11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0xff};
1336 if (target_rate == -1) {
1340 target_rate = target_rate / 100000;
1341 switch (target_rate) {
1383 for (i = 0; i < NumRates; i++) {
1384 if (ratevalue == mpdatarate[i]) {
1385 datarates[i] = mpdatarate[i];
1389 datarates[i] = 0xff;
1392 if (r8712_setdatarate_cmd(padapter, datarates) != _SUCCESS)
1397 static int r8711_wx_get_rate(struct net_device *dev,
1398 struct iw_request_info *info,
1399 union iwreq_data *wrqu, char *extra)
1401 struct _adapter *padapter = netdev_priv(dev);
1402 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1403 struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
1404 struct ieee80211_ht_cap *pht_capie;
1405 unsigned char rf_type = padapter->registrypriv.rf_config;
1408 u16 rate, max_rate = 0, ht_cap = false;
1410 u8 bw_40MHz = 0, short_GI = 0;
1414 if (check_fwstate(pmlmepriv, _FW_LINKED | WIFI_ADHOC_MASTER_STATE)) {
1415 p = r8712_get_ie(&pcur_bss->IEs[12],
1416 _HT_CAPABILITY_IE_, &ht_ielen,
1417 pcur_bss->IELength - 12);
1418 if (p && ht_ielen > 0) {
1420 pht_capie = (struct ieee80211_ht_cap *)(p + 2);
1421 memcpy(&mcs_rate, pht_capie->supp_mcs_set, 2);
1422 bw_40MHz = (pht_capie->cap_info &
1423 IEEE80211_HT_CAP_SUP_WIDTH) ? 1 : 0;
1424 short_GI = (pht_capie->cap_info &
1425 (IEEE80211_HT_CAP_SGI_20 |
1426 IEEE80211_HT_CAP_SGI_40)) ? 1 : 0;
1428 while ((pcur_bss->rates[i] != 0) &&
1429 (pcur_bss->rates[i] != 0xFF)) {
1430 rate = pcur_bss->rates[i] & 0x7F;
1431 if (rate > max_rate)
1433 wrqu->bitrate.fixed = 0; /* no auto select */
1434 wrqu->bitrate.value = rate * 500000;
1438 if (mcs_rate & 0x8000 /* MCS15 */
1440 rf_type == RTL8712_RF_2T2R)
1441 max_rate = (bw_40MHz) ? ((short_GI) ? 300 :
1442 270) : ((short_GI) ? 144 : 130);
1443 else /* default MCS7 */
1444 max_rate = (bw_40MHz) ? ((short_GI) ? 150 :
1445 135) : ((short_GI) ? 72 : 65);
1446 max_rate *= 2; /* Mbps/2 */
1448 wrqu->bitrate.value = max_rate * 500000;
1455 static int r8711_wx_get_rts(struct net_device *dev,
1456 struct iw_request_info *info,
1457 union iwreq_data *wrqu, char *extra)
1459 struct _adapter *padapter = netdev_priv(dev);
1461 wrqu->rts.value = padapter->registrypriv.rts_thresh;
1462 wrqu->rts.fixed = 0; /* no auto select */
1466 static int r8711_wx_set_frag(struct net_device *dev,
1467 struct iw_request_info *info,
1468 union iwreq_data *wrqu, char *extra)
1470 struct _adapter *padapter = netdev_priv(dev);
1472 if (wrqu->frag.disabled) {
1473 padapter->xmitpriv.frag_len = MAX_FRAG_THRESHOLD;
1475 if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
1476 wrqu->frag.value > MAX_FRAG_THRESHOLD)
1478 padapter->xmitpriv.frag_len = wrqu->frag.value & ~0x1;
1483 static int r8711_wx_get_frag(struct net_device *dev,
1484 struct iw_request_info *info,
1485 union iwreq_data *wrqu, char *extra)
1487 struct _adapter *padapter = netdev_priv(dev);
1489 wrqu->frag.value = padapter->xmitpriv.frag_len;
1490 wrqu->frag.fixed = 0; /* no auto select */
1494 static int r8711_wx_get_retry(struct net_device *dev,
1495 struct iw_request_info *info,
1496 union iwreq_data *wrqu, char *extra)
1498 wrqu->retry.value = 7;
1499 wrqu->retry.fixed = 0; /* no auto select */
1500 wrqu->retry.disabled = 1;
1504 static int r8711_wx_set_enc(struct net_device *dev,
1505 struct iw_request_info *info,
1506 union iwreq_data *wrqu, char *keybuf)
1509 u32 keyindex_provided;
1510 struct NDIS_802_11_WEP wep;
1511 enum NDIS_802_11_AUTHENTICATION_MODE authmode;
1512 struct iw_point *erq = &(wrqu->encoding);
1513 struct _adapter *padapter = netdev_priv(dev);
1515 key = erq->flags & IW_ENCODE_INDEX;
1516 memset(&wep, 0, sizeof(struct NDIS_802_11_WEP));
1517 if (erq->flags & IW_ENCODE_DISABLED) {
1518 netdev_info(dev, "r8712u: %s: EncryptionDisabled\n", __func__);
1519 padapter->securitypriv.ndisencryptstatus =
1520 Ndis802_11EncryptionDisabled;
1521 padapter->securitypriv.PrivacyAlgrthm = _NO_PRIVACY_;
1522 padapter->securitypriv.XGrpPrivacy = _NO_PRIVACY_;
1523 padapter->securitypriv.AuthAlgrthm = 0; /* open system */
1524 authmode = Ndis802_11AuthModeOpen;
1525 padapter->securitypriv.ndisauthtype = authmode;
1532 keyindex_provided = 1;
1534 keyindex_provided = 0;
1535 key = padapter->securitypriv.PrivacyKeyIndex;
1537 /* set authentication mode */
1538 if (erq->flags & IW_ENCODE_OPEN) {
1539 netdev_info(dev, "r8712u: %s: IW_ENCODE_OPEN\n", __func__);
1540 padapter->securitypriv.ndisencryptstatus =
1541 Ndis802_11Encryption1Enabled;
1542 padapter->securitypriv.AuthAlgrthm = 0; /* open system */
1543 padapter->securitypriv.PrivacyAlgrthm = _NO_PRIVACY_;
1544 padapter->securitypriv.XGrpPrivacy = _NO_PRIVACY_;
1545 authmode = Ndis802_11AuthModeOpen;
1546 padapter->securitypriv.ndisauthtype = authmode;
1547 } else if (erq->flags & IW_ENCODE_RESTRICTED) {
1549 "r8712u: %s: IW_ENCODE_RESTRICTED\n", __func__);
1550 padapter->securitypriv.ndisencryptstatus =
1551 Ndis802_11Encryption1Enabled;
1552 padapter->securitypriv.AuthAlgrthm = 1; /* shared system */
1553 padapter->securitypriv.PrivacyAlgrthm = _WEP40_;
1554 padapter->securitypriv.XGrpPrivacy = _WEP40_;
1555 authmode = Ndis802_11AuthModeShared;
1556 padapter->securitypriv.ndisauthtype = authmode;
1558 padapter->securitypriv.ndisencryptstatus =
1559 Ndis802_11Encryption1Enabled;
1560 padapter->securitypriv.AuthAlgrthm = 0; /* open system */
1561 padapter->securitypriv.PrivacyAlgrthm = _NO_PRIVACY_;
1562 padapter->securitypriv.XGrpPrivacy = _NO_PRIVACY_;
1563 authmode = Ndis802_11AuthModeOpen;
1564 padapter->securitypriv.ndisauthtype = authmode;
1567 if (erq->length > 0) {
1568 wep.KeyLength = erq->length <= 5 ? 5 : 13;
1569 wep.Length = wep.KeyLength +
1570 FIELD_OFFSET(struct NDIS_802_11_WEP, KeyMaterial);
1573 if (keyindex_provided == 1) { /* set key_id only, no given
1574 * KeyMaterial(erq->length==0).
1576 padapter->securitypriv.PrivacyKeyIndex = key;
1577 switch (padapter->securitypriv.DefKeylen[key]) {
1579 padapter->securitypriv.PrivacyAlgrthm =
1583 padapter->securitypriv.PrivacyAlgrthm =
1587 padapter->securitypriv.PrivacyAlgrthm =
1594 wep.KeyIndex |= 0x80000000; /* transmit key */
1595 memcpy(wep.KeyMaterial, keybuf, wep.KeyLength);
1596 if (r8712_set_802_11_add_wep(padapter, &wep) == _FAIL)
1601 static int r8711_wx_get_enc(struct net_device *dev,
1602 struct iw_request_info *info,
1603 union iwreq_data *wrqu, char *keybuf)
1606 struct _adapter *padapter = netdev_priv(dev);
1607 struct iw_point *erq = &(wrqu->encoding);
1608 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1610 if (!check_fwstate(pmlmepriv, _FW_LINKED)) {
1611 if (!check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) {
1613 erq->flags |= IW_ENCODE_DISABLED;
1617 key = erq->flags & IW_ENCODE_INDEX;
1623 key = padapter->securitypriv.PrivacyKeyIndex;
1625 erq->flags = key + 1;
1626 switch (padapter->securitypriv.ndisencryptstatus) {
1627 case Ndis802_11EncryptionNotSupported:
1628 case Ndis802_11EncryptionDisabled:
1630 erq->flags |= IW_ENCODE_DISABLED;
1632 case Ndis802_11Encryption1Enabled:
1633 erq->length = padapter->securitypriv.DefKeylen[key];
1635 memcpy(keybuf, padapter->securitypriv.DefKey[
1636 key].skey, padapter->securitypriv.
1638 erq->flags |= IW_ENCODE_ENABLED;
1639 if (padapter->securitypriv.ndisauthtype ==
1640 Ndis802_11AuthModeOpen)
1641 erq->flags |= IW_ENCODE_OPEN;
1642 else if (padapter->securitypriv.ndisauthtype ==
1643 Ndis802_11AuthModeShared)
1644 erq->flags |= IW_ENCODE_RESTRICTED;
1647 erq->flags |= IW_ENCODE_DISABLED;
1650 case Ndis802_11Encryption2Enabled:
1651 case Ndis802_11Encryption3Enabled:
1653 erq->flags |= (IW_ENCODE_ENABLED | IW_ENCODE_OPEN |
1658 erq->flags |= IW_ENCODE_DISABLED;
1664 static int r8711_wx_get_power(struct net_device *dev,
1665 struct iw_request_info *info,
1666 union iwreq_data *wrqu, char *extra)
1668 wrqu->power.value = 0;
1669 wrqu->power.fixed = 0; /* no auto select */
1670 wrqu->power.disabled = 1;
1674 static int r871x_wx_set_gen_ie(struct net_device *dev,
1675 struct iw_request_info *info,
1676 union iwreq_data *wrqu, char *extra)
1678 struct _adapter *padapter = netdev_priv(dev);
1680 return r871x_set_wpa_ie(padapter, extra, wrqu->data.length);
1683 static int r871x_wx_set_auth(struct net_device *dev,
1684 struct iw_request_info *info,
1685 union iwreq_data *wrqu, char *extra)
1687 struct _adapter *padapter = netdev_priv(dev);
1688 struct iw_param *param = (struct iw_param *)&(wrqu->param);
1693 paramid = param->flags & IW_AUTH_INDEX;
1694 paramval = param->value;
1696 case IW_AUTH_WPA_VERSION:
1698 case IW_AUTH_CIPHER_PAIRWISE:
1700 case IW_AUTH_CIPHER_GROUP:
1702 case IW_AUTH_KEY_MGMT:
1704 * ??? does not use these parameters
1707 case IW_AUTH_TKIP_COUNTERMEASURES:
1709 /* wpa_supplicant is enabling tkip countermeasure. */
1710 padapter->securitypriv.btkip_countermeasure = true;
1712 /* wpa_supplicant is disabling tkip countermeasure. */
1713 padapter->securitypriv.btkip_countermeasure = false;
1716 case IW_AUTH_DROP_UNENCRYPTED:
1719 * wpa_supplicant calls set_wpa_enabled when the driver
1720 * is loaded and unloaded, regardless of if WPA is being
1721 * used. No other calls are made which can be used to
1722 * determine if encryption will be used or not prior to
1723 * association being expected. If encryption is not being
1724 * used, drop_unencrypted is set to false, else true -- we
1725 * can use this to determine if the CAP_PRIVACY_ON bit should
1728 if (padapter->securitypriv.ndisencryptstatus ==
1729 Ndis802_11Encryption1Enabled) {
1730 /* it means init value, or using wep,
1731 * ndisencryptstatus =
1732 * Ndis802_11Encryption1Enabled,
1733 * then it needn't reset it;
1739 padapter->securitypriv.ndisencryptstatus =
1740 Ndis802_11EncryptionDisabled;
1741 padapter->securitypriv.PrivacyAlgrthm =
1743 padapter->securitypriv.XGrpPrivacy =
1745 padapter->securitypriv.AuthAlgrthm = 0;
1746 padapter->securitypriv.ndisauthtype =
1747 Ndis802_11AuthModeOpen;
1750 case IW_AUTH_80211_AUTH_ALG:
1751 ret = wpa_set_auth_algs(dev, (u32)paramval);
1753 case IW_AUTH_WPA_ENABLED:
1755 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
1757 case IW_AUTH_PRIVACY_INVOKED:
1766 static int r871x_wx_set_enc_ext(struct net_device *dev,
1767 struct iw_request_info *info,
1768 union iwreq_data *wrqu, char *extra)
1770 struct iw_point *pencoding = &wrqu->encoding;
1771 struct iw_encode_ext *pext = (struct iw_encode_ext *)extra;
1772 struct ieee_param *param = NULL;
1777 switch (pext->alg) {
1778 case IW_ENCODE_ALG_NONE:
1781 case IW_ENCODE_ALG_WEP:
1784 case IW_ENCODE_ALG_TKIP:
1787 case IW_ENCODE_ALG_CCMP:
1794 param_len = sizeof(struct ieee_param) + pext->key_len;
1795 param = kzalloc(param_len, GFP_ATOMIC);
1798 param->cmd = IEEE_CMD_SET_ENCRYPTION;
1799 eth_broadcast_addr(param->sta_addr);
1800 strncpy((char *)param->u.crypt.alg, alg_name, IEEE_CRYPT_ALG_NAME_LEN);
1801 if (pext->ext_flags & IW_ENCODE_EXT_GROUP_KEY)
1802 param->u.crypt.set_tx = 0;
1803 if (pext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
1804 param->u.crypt.set_tx = 1;
1805 param->u.crypt.idx = (pencoding->flags & 0x00FF) - 1;
1806 if (pext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID)
1807 memcpy(param->u.crypt.seq, pext->rx_seq, 8);
1808 if (pext->key_len) {
1809 param->u.crypt.key_len = pext->key_len;
1810 memcpy(param + 1, pext + 1, pext->key_len);
1812 ret = wpa_set_encryption(dev, param, param_len);
1817 static int r871x_wx_get_nick(struct net_device *dev,
1818 struct iw_request_info *info,
1819 union iwreq_data *wrqu, char *extra)
1822 wrqu->data.length = 8;
1823 wrqu->data.flags = 1;
1824 memcpy(extra, "rtl_wifi", 8);
1829 static int r8711_wx_read32(struct net_device *dev,
1830 struct iw_request_info *info,
1831 union iwreq_data *wrqu, char *keybuf)
1833 struct _adapter *padapter = netdev_priv(dev);
1837 get_user(addr, (u32 __user *)wrqu->data.pointer);
1838 data32 = r8712_read32(padapter, addr);
1839 put_user(data32, (u32 __user *)wrqu->data.pointer);
1840 wrqu->data.length = (data32 & 0xffff0000) >> 16;
1841 wrqu->data.flags = data32 & 0xffff;
1842 get_user(addr, (u32 __user *)wrqu->data.pointer);
1846 static int r8711_wx_write32(struct net_device *dev,
1847 struct iw_request_info *info,
1848 union iwreq_data *wrqu, char *keybuf)
1850 struct _adapter *padapter = netdev_priv(dev);
1854 get_user(addr, (u32 __user *)wrqu->data.pointer);
1855 data32 = ((u32)wrqu->data.length << 16) | (u32)wrqu->data.flags;
1856 r8712_write32(padapter, addr, data32);
1860 static int dummy(struct net_device *dev,
1861 struct iw_request_info *a,
1862 union iwreq_data *wrqu, char *b)
1867 static int r8711_drvext_hdl(struct net_device *dev,
1868 struct iw_request_info *info,
1869 union iwreq_data *wrqu, char *extra)
1874 static int r871x_mp_ioctl_hdl(struct net_device *dev,
1875 struct iw_request_info *info,
1876 union iwreq_data *wrqu, char *extra)
1878 struct _adapter *padapter = netdev_priv(dev);
1879 struct iw_point *p = &wrqu->data;
1880 struct oid_par_priv oid_par;
1881 struct mp_ioctl_handler *phandler;
1882 struct mp_ioctl_param *poidparam;
1883 unsigned long BytesRead, BytesWritten, BytesNeeded;
1889 if ((!p->length) || (!p->pointer))
1892 bset = (u8)(p->flags & 0xFFFF);
1894 pparmbuf = memdup_user(p->pointer, len);
1895 if (IS_ERR(pparmbuf))
1896 return PTR_ERR(pparmbuf);
1898 poidparam = (struct mp_ioctl_param *)pparmbuf;
1899 if (poidparam->subcode >= MAX_MP_IOCTL_SUBCODE) {
1901 goto _r871x_mp_ioctl_hdl_exit;
1903 phandler = mp_ioctl_hdl + poidparam->subcode;
1904 if ((phandler->paramsize != 0) &&
1905 (poidparam->len < phandler->paramsize)) {
1907 goto _r871x_mp_ioctl_hdl_exit;
1909 if (phandler->oid == 0 && phandler->handler) {
1910 status = phandler->handler(&oid_par);
1911 } else if (phandler->handler) {
1912 oid_par.adapter_context = padapter;
1913 oid_par.oid = phandler->oid;
1914 oid_par.information_buf = poidparam->data;
1915 oid_par.information_buf_len = poidparam->len;
1920 oid_par.bytes_rw = &BytesRead;
1921 oid_par.bytes_needed = &BytesNeeded;
1922 oid_par.type_of_oid = SET_OID;
1924 oid_par.bytes_rw = &BytesWritten;
1925 oid_par.bytes_needed = &BytesNeeded;
1926 oid_par.type_of_oid = QUERY_OID;
1928 status = phandler->handler(&oid_par);
1929 /* todo:check status, BytesNeeded, etc. */
1931 netdev_info(dev, "r8712u: %s: err!, subcode=%d, oid=%d, handler=%p\n",
1932 __func__, poidparam->subcode, phandler->oid,
1935 goto _r871x_mp_ioctl_hdl_exit;
1937 if (bset == 0x00) { /* query info */
1938 if (copy_to_user(p->pointer, pparmbuf, len))
1943 goto _r871x_mp_ioctl_hdl_exit;
1945 _r871x_mp_ioctl_hdl_exit:
1950 static int r871x_get_ap_info(struct net_device *dev,
1951 struct iw_request_info *info,
1952 union iwreq_data *wrqu, char *extra)
1954 struct _adapter *padapter = netdev_priv(dev);
1955 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1956 struct __queue *queue = &pmlmepriv->scanned_queue;
1957 struct iw_point *pdata = &wrqu->data;
1958 struct wlan_network *pnetwork = NULL;
1959 u32 cnt = 0, wpa_ielen;
1961 struct list_head *plist, *phead;
1962 unsigned char *pbuf;
1966 if (padapter->bDriverStopped || (pdata == NULL))
1968 while (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY |
1969 _FW_UNDER_LINKING)) {
1976 if (pdata->length >= 32) {
1977 if (copy_from_user(data, pdata->pointer, 32))
1983 spin_lock_irqsave(&(pmlmepriv->scanned_queue.lock), irqL);
1984 phead = &queue->queue;
1985 plist = phead->next;
1987 if (end_of_queue_search(phead, plist))
1989 pnetwork = container_of(plist, struct wlan_network, list);
1990 if (!mac_pton(data, bssid)) {
1991 netdev_info(dev, "r8712u: Invalid BSSID '%s'.\n",
1993 spin_unlock_irqrestore(&(pmlmepriv->scanned_queue.lock),
1997 netdev_info(dev, "r8712u: BSSID:%pM\n", bssid);
1998 if (ether_addr_equal(bssid, pnetwork->network.MacAddress)) {
1999 /* BSSID match, then check if supporting wpa/wpa2 */
2000 pbuf = r8712_get_wpa_ie(&pnetwork->network.IEs[12],
2001 &wpa_ielen, pnetwork->network.IELength - 12);
2002 if (pbuf && (wpa_ielen > 0)) {
2006 pbuf = r8712_get_wpa2_ie(&pnetwork->network.IEs[12],
2007 &wpa_ielen, pnetwork->network.IELength - 12);
2008 if (pbuf && (wpa_ielen > 0)) {
2013 plist = plist->next;
2015 spin_unlock_irqrestore(&(pmlmepriv->scanned_queue.lock), irqL);
2016 if (pdata->length >= 34) {
2017 if (copy_to_user((u8 __user *)pdata->pointer + 32,
2018 (u8 *)&pdata->flags, 1))
2024 static int r871x_set_pid(struct net_device *dev,
2025 struct iw_request_info *info,
2026 union iwreq_data *wrqu, char *extra)
2028 struct _adapter *padapter = netdev_priv(dev);
2029 struct iw_point *pdata = &wrqu->data;
2031 if ((padapter->bDriverStopped) || (pdata == NULL))
2033 if (copy_from_user(&padapter->pid, pdata->pointer, sizeof(int)))
2038 static int r871x_set_chplan(struct net_device *dev,
2039 struct iw_request_info *info,
2040 union iwreq_data *wrqu, char *extra)
2043 struct _adapter *padapter = netdev_priv(dev);
2044 struct iw_point *pdata = &wrqu->data;
2047 if ((padapter->bDriverStopped) || (pdata == NULL)) {
2051 ch_plan = (int)*extra;
2052 r8712_set_chplan_cmd(padapter, ch_plan);
2059 static int r871x_wps_start(struct net_device *dev,
2060 struct iw_request_info *info,
2061 union iwreq_data *wrqu, char *extra)
2063 struct _adapter *padapter = netdev_priv(dev);
2064 struct iw_point *pdata = &wrqu->data;
2065 u32 u32wps_start = 0;
2067 if ((padapter->bDriverStopped) || (pdata == NULL))
2069 if (copy_from_user((void *)&u32wps_start, pdata->pointer, 4))
2071 if (u32wps_start == 0)
2072 u32wps_start = *extra;
2073 if (u32wps_start == 1) /* WPS Start */
2074 padapter->ledpriv.LedControlHandler(padapter,
2076 else if (u32wps_start == 2) /* WPS Stop because of wps success */
2077 padapter->ledpriv.LedControlHandler(padapter,
2079 else if (u32wps_start == 3) /* WPS Stop because of wps fail */
2080 padapter->ledpriv.LedControlHandler(padapter,
2081 LED_CTL_STOP_WPS_FAIL);
2085 static int wpa_set_param(struct net_device *dev, u8 name, u32 value)
2087 struct _adapter *padapter = netdev_priv(dev);
2090 case IEEE_PARAM_WPA_ENABLED:
2091 padapter->securitypriv.AuthAlgrthm = 2; /* 802.1x */
2092 switch ((value) & 0xff) {
2094 padapter->securitypriv.ndisauthtype =
2095 Ndis802_11AuthModeWPAPSK; /* WPA_PSK */
2096 padapter->securitypriv.ndisencryptstatus =
2097 Ndis802_11Encryption2Enabled;
2100 padapter->securitypriv.ndisauthtype =
2101 Ndis802_11AuthModeWPA2PSK; /* WPA2_PSK */
2102 padapter->securitypriv.ndisencryptstatus =
2103 Ndis802_11Encryption3Enabled;
2107 case IEEE_PARAM_TKIP_COUNTERMEASURES:
2109 case IEEE_PARAM_DROP_UNENCRYPTED:
2112 * wpa_supplicant calls set_wpa_enabled when the driver
2113 * is loaded and unloaded, regardless of if WPA is being
2114 * used. No other calls are made which can be used to
2115 * determine if encryption will be used or not prior to
2116 * association being expected. If encryption is not being
2117 * used, drop_unencrypted is set to false, else true -- we
2118 * can use this to determine if the CAP_PRIVACY_ON bit should
2122 case IEEE_PARAM_PRIVACY_INVOKED:
2124 case IEEE_PARAM_AUTH_ALGS:
2125 return wpa_set_auth_algs(dev, value);
2126 case IEEE_PARAM_IEEE_802_1X:
2128 case IEEE_PARAM_WPAX_SELECT:
2129 /* added for WPA2 mixed mode */
2137 static int wpa_mlme(struct net_device *dev, u32 command, u32 reason)
2139 struct _adapter *padapter = netdev_priv(dev);
2142 case IEEE_MLME_STA_DEAUTH:
2143 if (!r8712_set_802_11_disassociate(padapter))
2146 case IEEE_MLME_STA_DISASSOC:
2147 if (!r8712_set_802_11_disassociate(padapter))
2156 static int wpa_supplicant_ioctl(struct net_device *dev, struct iw_point *p)
2158 struct ieee_param *param;
2160 struct _adapter *padapter = netdev_priv(dev);
2162 if (p->length < sizeof(struct ieee_param) || !p->pointer)
2164 param = memdup_user(p->pointer, p->length);
2166 return PTR_ERR(param);
2167 switch (param->cmd) {
2168 case IEEE_CMD_SET_WPA_PARAM:
2169 ret = wpa_set_param(dev, param->u.wpa_param.name,
2170 param->u.wpa_param.value);
2172 case IEEE_CMD_SET_WPA_IE:
2173 ret = r871x_set_wpa_ie(padapter, (char *)param->u.wpa_ie.data,
2174 (u16)param->u.wpa_ie.len);
2176 case IEEE_CMD_SET_ENCRYPTION:
2177 ret = wpa_set_encryption(dev, param, p->length);
2180 ret = wpa_mlme(dev, param->u.mlme.command,
2181 param->u.mlme.reason_code);
2187 if (ret == 0 && copy_to_user(p->pointer, param, p->length))
2193 /* based on "driver_ipw" and for hostapd */
2194 int r871x_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
2196 struct iwreq *wrq = (struct iwreq *)rq;
2199 case RTL_IOCTL_WPA_SUPPLICANT:
2200 return wpa_supplicant_ioctl(dev, &wrq->u.data);
2207 static iw_handler r8711_handlers[] = {
2208 NULL, /* SIOCSIWCOMMIT */
2209 r8711_wx_get_name, /* SIOCGIWNAME */
2210 dummy, /* SIOCSIWNWID */
2211 dummy, /* SIOCGIWNWID */
2212 r8711_wx_set_freq, /* SIOCSIWFREQ */
2213 r8711_wx_get_freq, /* SIOCGIWFREQ */
2214 r8711_wx_set_mode, /* SIOCSIWMODE */
2215 r8711_wx_get_mode, /* SIOCGIWMODE */
2216 dummy, /* SIOCSIWSENS */
2217 r8711_wx_get_sens, /* SIOCGIWSENS */
2218 NULL, /* SIOCSIWRANGE */
2219 r8711_wx_get_range, /* SIOCGIWRANGE */
2220 r871x_wx_set_priv, /* SIOCSIWPRIV */
2221 NULL, /* SIOCGIWPRIV */
2222 NULL, /* SIOCSIWSTATS */
2223 NULL, /* SIOCGIWSTATS */
2224 dummy, /* SIOCSIWSPY */
2225 dummy, /* SIOCGIWSPY */
2226 NULL, /* SIOCGIWTHRSPY */
2227 NULL, /* SIOCWIWTHRSPY */
2228 r8711_wx_set_wap, /* SIOCSIWAP */
2229 r8711_wx_get_wap, /* SIOCGIWAP */
2230 r871x_wx_set_mlme, /* request MLME operation;
2231 * uses struct iw_mlme
2233 dummy, /* SIOCGIWAPLIST -- deprecated */
2234 r8711_wx_set_scan, /* SIOCSIWSCAN */
2235 r8711_wx_get_scan, /* SIOCGIWSCAN */
2236 r8711_wx_set_essid, /* SIOCSIWESSID */
2237 r8711_wx_get_essid, /* SIOCGIWESSID */
2238 dummy, /* SIOCSIWNICKN */
2239 r871x_wx_get_nick, /* SIOCGIWNICKN */
2240 NULL, /* -- hole -- */
2241 NULL, /* -- hole -- */
2242 r8711_wx_set_rate, /* SIOCSIWRATE */
2243 r8711_wx_get_rate, /* SIOCGIWRATE */
2244 dummy, /* SIOCSIWRTS */
2245 r8711_wx_get_rts, /* SIOCGIWRTS */
2246 r8711_wx_set_frag, /* SIOCSIWFRAG */
2247 r8711_wx_get_frag, /* SIOCGIWFRAG */
2248 dummy, /* SIOCSIWTXPOW */
2249 dummy, /* SIOCGIWTXPOW */
2250 dummy, /* SIOCSIWRETRY */
2251 r8711_wx_get_retry, /* SIOCGIWRETRY */
2252 r8711_wx_set_enc, /* SIOCSIWENCODE */
2253 r8711_wx_get_enc, /* SIOCGIWENCODE */
2254 dummy, /* SIOCSIWPOWER */
2255 r8711_wx_get_power, /* SIOCGIWPOWER */
2256 NULL, /*---hole---*/
2257 NULL, /*---hole---*/
2258 r871x_wx_set_gen_ie, /* SIOCSIWGENIE */
2259 NULL, /* SIOCGIWGENIE */
2260 r871x_wx_set_auth, /* SIOCSIWAUTH */
2261 NULL, /* SIOCGIWAUTH */
2262 r871x_wx_set_enc_ext, /* SIOCSIWENCODEEXT */
2263 NULL, /* SIOCGIWENCODEEXT */
2264 r871x_wx_set_pmkid, /* SIOCSIWPMKSA */
2265 NULL, /*---hole---*/
2268 static const struct iw_priv_args r8711_private_args[] = {
2270 SIOCIWFIRSTPRIV + 0x0,
2271 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "read32"
2274 SIOCIWFIRSTPRIV + 0x1,
2275 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "write32"
2278 SIOCIWFIRSTPRIV + 0x2, 0, 0, "driver_ext"
2281 SIOCIWFIRSTPRIV + 0x3, 0, 0, "mp_ioctl"
2284 SIOCIWFIRSTPRIV + 0x4,
2285 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "apinfo"
2288 SIOCIWFIRSTPRIV + 0x5,
2289 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setpid"
2292 SIOCIWFIRSTPRIV + 0x6,
2293 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wps_start"
2296 SIOCIWFIRSTPRIV + 0x7,
2297 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "chplan"
2301 static iw_handler r8711_private_handler[] = {
2306 r871x_get_ap_info, /*for MM DTV platform*/
2312 static struct iw_statistics *r871x_get_wireless_stats(struct net_device *dev)
2314 struct _adapter *padapter = netdev_priv(dev);
2315 struct iw_statistics *piwstats = &padapter->iwstats;
2320 if (check_fwstate(&padapter->mlmepriv, _FW_LINKED) != true) {
2321 piwstats->qual.qual = 0;
2322 piwstats->qual.level = 0;
2323 piwstats->qual.noise = 0;
2325 /* show percentage, we need transfer dbm to orignal value. */
2326 tmp_level = padapter->recvpriv.fw_rssi;
2327 tmp_qual = padapter->recvpriv.signal;
2328 tmp_noise = padapter->recvpriv.noise;
2329 piwstats->qual.level = tmp_level;
2330 piwstats->qual.qual = tmp_qual;
2331 piwstats->qual.noise = tmp_noise;
2333 piwstats->qual.updated = IW_QUAL_ALL_UPDATED;
2334 return &padapter->iwstats;
2337 struct iw_handler_def r871x_handlers_def = {
2338 .standard = r8711_handlers,
2339 .num_standard = ARRAY_SIZE(r8711_handlers),
2340 .private = r8711_private_handler,
2341 .private_args = (struct iw_priv_args *)r8711_private_args,
2342 .num_private = ARRAY_SIZE(r8711_private_handler),
2343 .num_private_args = sizeof(r8711_private_args) /
2344 sizeof(struct iw_priv_args),
2345 .get_wireless_stats = r871x_get_wireless_stats