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,
104 &(param->u.crypt.key[16]), 8);
105 memcpy(psta->tkiprxmickey. skey,
106 &(param->u.crypt.key[24]), 8);
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 union Keytype *gk = padapter->securitypriv.XGrpKey;
118 union Keytype *gtk = padapter->securitypriv.XGrptxmickey;
119 union Keytype *grk = padapter->securitypriv.XGrprxmickey;
121 if (param->u.crypt.idx > 0 &&
122 param->u.crypt.idx < 3) {
123 /* group key idx is 1 or 2 */
124 memcpy(gk[param->u.crypt.idx - 1].skey,
126 (param->u.crypt.key_len > 16 ? 16 :
127 param->u.crypt.key_len));
128 memcpy(gtk[param->u.crypt.idx - 1].skey,
129 ¶m->u.crypt.key[16], 8);
130 memcpy(grk[param->u.crypt.idx - 1].skey,
131 ¶m->u.crypt.key[24], 8);
132 padapter->securitypriv.binstallGrpkey = true;
133 r8712_set_key(padapter, &padapter->securitypriv,
135 if (padapter->registrypriv.power_mgnt > PS_MODE_ACTIVE) {
136 if (padapter->registrypriv.power_mgnt !=
137 padapter->pwrctrlpriv.pwr_mode)
138 mod_timer(&padapter->mlmepriv.dhcp_timer,
139 jiffies + msecs_to_jiffies(60000));
144 static noinline_for_stack char *translate_scan_wpa(struct iw_request_info *info,
145 struct wlan_network *pnetwork,
146 struct iw_event *iwe,
147 char *start, char *stop)
149 /* parsing WPA/WPA2 IE */
150 u8 buf[MAX_WPA_IE_LEN];
151 u8 wpa_ie[255], rsn_ie[255];
152 u16 wpa_len = 0, rsn_len = 0;
155 r8712_get_sec_ie(pnetwork->network.IEs,
156 pnetwork->network.IELength, rsn_ie, &rsn_len,
159 memset(buf, 0, MAX_WPA_IE_LEN);
160 n = sprintf(buf, "wpa_ie=");
161 for (i = 0; i < wpa_len; i++) {
162 n += snprintf(buf + n, MAX_WPA_IE_LEN - n,
164 if (n >= MAX_WPA_IE_LEN)
167 memset(iwe, 0, sizeof(*iwe));
168 iwe->cmd = IWEVCUSTOM;
169 iwe->u.data.length = (u16)strlen(buf);
170 start = iwe_stream_add_point(info, start, stop,
172 memset(iwe, 0, sizeof(*iwe));
173 iwe->cmd = IWEVGENIE;
174 iwe->u.data.length = (u16)wpa_len;
175 start = iwe_stream_add_point(info, start, stop,
179 memset(buf, 0, MAX_WPA_IE_LEN);
180 n = sprintf(buf, "rsn_ie=");
181 for (i = 0; i < rsn_len; i++) {
182 n += snprintf(buf + n, MAX_WPA_IE_LEN - n,
184 if (n >= MAX_WPA_IE_LEN)
187 memset(iwe, 0, sizeof(*iwe));
188 iwe->cmd = IWEVCUSTOM;
189 iwe->u.data.length = strlen(buf);
190 start = iwe_stream_add_point(info, start, stop,
192 memset(iwe, 0, sizeof(*iwe));
193 iwe->cmd = IWEVGENIE;
194 iwe->u.data.length = rsn_len;
195 start = iwe_stream_add_point(info, start, stop, iwe,
202 static noinline_for_stack char *translate_scan_wps(struct iw_request_info *info,
203 struct wlan_network *pnetwork,
204 struct iw_event *iwe,
205 char *start, char *stop)
211 if (r8712_get_wps_ie(pnetwork->network.IEs,
212 pnetwork->network.IELength,
213 wps_ie, &wps_ielen)) {
215 iwe->cmd = IWEVGENIE;
216 iwe->u.data.length = (u16)wps_ielen;
217 start = iwe_stream_add_point(info, start, stop,
225 static char *translate_scan(struct _adapter *padapter,
226 struct iw_request_info *info,
227 struct wlan_network *pnetwork,
228 char *start, char *stop)
231 struct ieee80211_ht_cap *pht_capie;
234 u32 i = 0, ht_ielen = 0;
235 u16 cap, ht_cap = false, mcs_rate;
238 if ((pnetwork->network.Configuration.DSConfig < 1) ||
239 (pnetwork->network.Configuration.DSConfig > 14)) {
240 if (pnetwork->network.Configuration.DSConfig < 1)
241 pnetwork->network.Configuration.DSConfig = 1;
243 pnetwork->network.Configuration.DSConfig = 14;
247 iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
248 ether_addr_copy(iwe.u.ap_addr.sa_data, pnetwork->network.MacAddress);
249 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_ADDR_LEN);
251 iwe.cmd = SIOCGIWESSID;
252 iwe.u.data.flags = 1;
253 iwe.u.data.length = min_t(u32, pnetwork->network.Ssid.SsidLength, 32);
254 start = iwe_stream_add_point(info, start, stop, &iwe,
255 pnetwork->network.Ssid.Ssid);
256 /* parsing HT_CAP_IE */
257 p = r8712_get_ie(&pnetwork->network.IEs[12], _HT_CAPABILITY_IE_,
258 &ht_ielen, pnetwork->network.IELength - 12);
259 if (p && ht_ielen > 0) {
261 pht_capie = (struct ieee80211_ht_cap *)(p + 2);
262 memcpy(&mcs_rate, pht_capie->supp_mcs_set, 2);
264 /* Add the protocol name */
265 iwe.cmd = SIOCGIWNAME;
266 if (r8712_is_cckratesonly_included(pnetwork->network.rates)) {
268 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bn");
270 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11b");
271 } else if (r8712_is_cckrates_included(pnetwork->network.rates)) {
273 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bgn");
275 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bg");
278 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11gn");
280 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11g");
282 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_CHAR_LEN);
284 iwe.cmd = SIOCGIWMODE;
285 memcpy((u8 *)&cap, r8712_get_capability_from_ie(pnetwork->network.IEs),
288 if (cap & (WLAN_CAPABILITY_IBSS | WLAN_CAPABILITY_BSS)) {
289 if (cap & WLAN_CAPABILITY_BSS)
290 iwe.u.mode = (u32)IW_MODE_MASTER;
292 iwe.u.mode = (u32)IW_MODE_ADHOC;
293 start = iwe_stream_add_event(info, start, stop, &iwe,
296 /* Add frequency/channel */
297 iwe.cmd = SIOCGIWFREQ;
299 /* check legal index */
300 u8 dsconfig = pnetwork->network.Configuration.DSConfig;
302 if (dsconfig >= 1 && dsconfig <= sizeof(
303 ieee80211_wlan_frequencies) / sizeof(long))
305 (s32)(ieee80211_wlan_frequencies
306 [dsconfig - 1] * 100000);
310 iwe.u.freq.e = (s16)1;
311 iwe.u.freq.i = (u8)pnetwork->network.Configuration.DSConfig;
312 start = iwe_stream_add_event(info, start, stop, &iwe,
314 /* Add encryption capability */
315 iwe.cmd = SIOCGIWENCODE;
316 if (cap & WLAN_CAPABILITY_PRIVACY)
317 iwe.u.data.flags = (u16)(IW_ENCODE_ENABLED |
320 iwe.u.data.flags = (u16)(IW_ENCODE_DISABLED);
321 iwe.u.data.length = (u16)0;
322 start = iwe_stream_add_point(info, start, stop, &iwe,
323 pnetwork->network.Ssid.Ssid);
324 /*Add basic and extended rates */
325 current_val = start + iwe_stream_lcp_len(info);
326 iwe.cmd = SIOCGIWRATE;
327 iwe.u.bitrate.fixed = 0;
328 iwe.u.bitrate.disabled = 0;
329 iwe.u.bitrate.value = 0;
331 while (pnetwork->network.rates[i] != 0) {
332 /* Bit rate given in 500 kb/s units */
333 iwe.u.bitrate.value = (pnetwork->network.rates[i++] &
335 current_val = iwe_stream_add_value(info, start, current_val,
336 stop, &iwe, IW_EV_PARAM_LEN);
338 /* Check if we added any event */
339 if ((current_val - start) > iwe_stream_lcp_len(info))
342 start = translate_scan_wpa(info, pnetwork, &iwe, start, stop);
344 start = translate_scan_wps(info, pnetwork, &iwe, start, stop);
346 /* Add quality statistics */
348 rssi = r8712_signal_scale_mapping(pnetwork->network.Rssi);
349 /* we only update signal_level (signal strength) that is rssi. */
350 iwe.u.qual.updated = (u8)(IW_QUAL_QUAL_INVALID | IW_QUAL_LEVEL_UPDATED |
351 IW_QUAL_NOISE_INVALID);
352 iwe.u.qual.level = rssi; /* signal strength */
353 iwe.u.qual.qual = 0; /* signal quality */
354 iwe.u.qual.noise = 0; /* noise level */
355 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_QUAL_LEN);
356 /* how to translate rssi to ?% */
360 static int wpa_set_auth_algs(struct net_device *dev, u32 value)
362 struct _adapter *padapter = netdev_priv(dev);
365 if ((value & AUTH_ALG_SHARED_KEY) && (value & AUTH_ALG_OPEN_SYSTEM)) {
366 padapter->securitypriv.ndisencryptstatus =
367 Ndis802_11Encryption1Enabled;
368 padapter->securitypriv.ndisauthtype =
369 Ndis802_11AuthModeAutoSwitch;
370 padapter->securitypriv.AuthAlgrthm = 3;
371 } else if (value & AUTH_ALG_SHARED_KEY) {
372 padapter->securitypriv.ndisencryptstatus =
373 Ndis802_11Encryption1Enabled;
374 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeShared;
375 padapter->securitypriv.AuthAlgrthm = 1;
376 } else if (value & AUTH_ALG_OPEN_SYSTEM) {
377 if (padapter->securitypriv.ndisauthtype <
378 Ndis802_11AuthModeWPAPSK) {
379 padapter->securitypriv.ndisauthtype =
380 Ndis802_11AuthModeOpen;
381 padapter->securitypriv.AuthAlgrthm = 0;
389 static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param,
393 u32 wep_key_idx, wep_key_len = 0;
394 struct NDIS_802_11_WEP *pwep = NULL;
395 struct _adapter *padapter = netdev_priv(dev);
396 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
397 struct security_priv *psecuritypriv = &padapter->securitypriv;
399 param->u.crypt.err = 0;
400 param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
401 if (param_len != (u32)((u8 *) param->u.crypt.key - (u8 *)param) +
402 param->u.crypt.key_len)
404 if (!is_broadcast_ether_addr(param->sta_addr))
407 if (param->u.crypt.idx >= WEP_KEYS) {
408 /* for large key indices, set the default (0) */
409 param->u.crypt.idx = 0;
411 if (strcmp(param->u.crypt.alg, "WEP") == 0) {
412 netdev_info(dev, "r8712u: %s: crypt.alg = WEP\n", __func__);
413 padapter->securitypriv.ndisencryptstatus =
414 Ndis802_11Encryption1Enabled;
415 padapter->securitypriv.PrivacyAlgrthm = _WEP40_;
416 padapter->securitypriv.XGrpPrivacy = _WEP40_;
417 wep_key_idx = param->u.crypt.idx;
418 wep_key_len = param->u.crypt.key_len;
419 if (wep_key_idx >= WEP_KEYS)
421 if (wep_key_len <= 0)
424 wep_key_len = wep_key_len <= 5 ? 5 : 13;
425 pwep = kzalloc(sizeof(*pwep), GFP_ATOMIC);
428 pwep->KeyLength = wep_key_len;
429 pwep->Length = wep_key_len +
430 FIELD_OFFSET(struct NDIS_802_11_WEP, KeyMaterial);
431 if (wep_key_len == 13) {
432 padapter->securitypriv.PrivacyAlgrthm = _WEP104_;
433 padapter->securitypriv.XGrpPrivacy = _WEP104_;
435 pwep->KeyIndex = wep_key_idx;
436 pwep->KeyIndex |= 0x80000000;
437 memcpy(pwep->KeyMaterial, param->u.crypt.key, pwep->KeyLength);
438 if (param->u.crypt.set_tx) {
439 if (r8712_set_802_11_add_wep(padapter, pwep) ==
443 /* don't update "psecuritypriv->PrivacyAlgrthm" and
444 * "psecuritypriv->PrivacyKeyIndex=keyid", but can
445 * r8712_set_key to fw/cam
447 if (wep_key_idx >= WEP_KEYS) {
451 memcpy(&psecuritypriv->DefKey[wep_key_idx].skey[0],
454 psecuritypriv->DefKeylen[wep_key_idx] =
456 r8712_set_key(padapter, psecuritypriv, wep_key_idx);
460 if (padapter->securitypriv.AuthAlgrthm == 2) { /* 802_1x */
461 struct sta_info *psta, *pbcmc_sta;
462 struct sta_priv *pstapriv = &padapter->stapriv;
463 struct security_priv *spriv = &padapter->securitypriv;
465 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE |
466 WIFI_MP_STATE)) { /* sta mode */
467 psta = r8712_get_stainfo(pstapriv,
468 get_bssid(pmlmepriv));
470 psta->ieee8021x_blocked = false;
471 if (spriv->ndisencryptstatus ==
472 Ndis802_11Encryption2Enabled ||
473 spriv->ndisencryptstatus ==
474 Ndis802_11Encryption3Enabled)
475 psta->XPrivacy = spriv->PrivacyAlgrthm;
476 if (param->u.crypt.set_tx == 1)
477 handle_pairwise_key(psta, param,
480 handle_group_key(param, padapter);
482 pbcmc_sta = r8712_get_bcmc_stainfo(padapter);
484 pbcmc_sta->ieee8021x_blocked = false;
485 if (spriv->ndisencryptstatus ==
486 Ndis802_11Encryption2Enabled ||
487 spriv->ndisencryptstatus ==
488 Ndis802_11Encryption3Enabled)
489 pbcmc_sta->XPrivacy =
490 spriv->PrivacyAlgrthm;
499 static int r871x_set_wpa_ie(struct _adapter *padapter, char *pie,
500 unsigned short ielen)
503 int group_cipher = 0, pairwise_cipher = 0;
506 if ((ielen > MAX_WPA_IE_LEN) || (pie == NULL))
509 buf = kmemdup(pie, ielen, GFP_ATOMIC);
512 if (ielen < RSN_HEADER_LEN) {
516 if (r8712_parse_wpa_ie(buf, ielen, &group_cipher,
517 &pairwise_cipher) == _SUCCESS) {
518 padapter->securitypriv.AuthAlgrthm = 2;
519 padapter->securitypriv.ndisauthtype =
520 Ndis802_11AuthModeWPAPSK;
522 if (r8712_parse_wpa2_ie(buf, ielen, &group_cipher,
523 &pairwise_cipher) == _SUCCESS) {
524 padapter->securitypriv.AuthAlgrthm = 2;
525 padapter->securitypriv.ndisauthtype =
526 Ndis802_11AuthModeWPA2PSK;
528 switch (group_cipher) {
529 case WPA_CIPHER_NONE:
530 padapter->securitypriv.XGrpPrivacy =
532 padapter->securitypriv.ndisencryptstatus =
533 Ndis802_11EncryptionDisabled;
535 case WPA_CIPHER_WEP40:
536 padapter->securitypriv.XGrpPrivacy = _WEP40_;
537 padapter->securitypriv.ndisencryptstatus =
538 Ndis802_11Encryption1Enabled;
540 case WPA_CIPHER_TKIP:
541 padapter->securitypriv.XGrpPrivacy = _TKIP_;
542 padapter->securitypriv.ndisencryptstatus =
543 Ndis802_11Encryption2Enabled;
545 case WPA_CIPHER_CCMP:
546 padapter->securitypriv.XGrpPrivacy = _AES_;
547 padapter->securitypriv.ndisencryptstatus =
548 Ndis802_11Encryption3Enabled;
550 case WPA_CIPHER_WEP104:
551 padapter->securitypriv.XGrpPrivacy = _WEP104_;
552 padapter->securitypriv.ndisencryptstatus =
553 Ndis802_11Encryption1Enabled;
556 switch (pairwise_cipher) {
557 case WPA_CIPHER_NONE:
558 padapter->securitypriv.PrivacyAlgrthm =
560 padapter->securitypriv.ndisencryptstatus =
561 Ndis802_11EncryptionDisabled;
563 case WPA_CIPHER_WEP40:
564 padapter->securitypriv.PrivacyAlgrthm = _WEP40_;
565 padapter->securitypriv.ndisencryptstatus =
566 Ndis802_11Encryption1Enabled;
568 case WPA_CIPHER_TKIP:
569 padapter->securitypriv.PrivacyAlgrthm = _TKIP_;
570 padapter->securitypriv.ndisencryptstatus =
571 Ndis802_11Encryption2Enabled;
573 case WPA_CIPHER_CCMP:
574 padapter->securitypriv.PrivacyAlgrthm = _AES_;
575 padapter->securitypriv.ndisencryptstatus =
576 Ndis802_11Encryption3Enabled;
578 case WPA_CIPHER_WEP104:
579 padapter->securitypriv.PrivacyAlgrthm = _WEP104_;
580 padapter->securitypriv.ndisencryptstatus =
581 Ndis802_11Encryption1Enabled;
584 padapter->securitypriv.wps_phase = false;
587 u8 eid, wps_oui[4] = {0x0, 0x50, 0xf2, 0x04};
589 while (cnt < ielen) {
592 if ((eid == _VENDOR_SPECIFIC_IE_) &&
593 (!memcmp(&buf[cnt + 2], wps_oui, 4))) {
594 netdev_info(padapter->pnetdev, "r8712u: SET WPS_IE\n");
595 padapter->securitypriv.wps_ie_len =
596 ((buf[cnt + 1] + 2) <
597 (MAX_WPA_IE_LEN << 2)) ?
599 (MAX_WPA_IE_LEN << 2);
600 memcpy(padapter->securitypriv.wps_ie,
602 padapter->securitypriv.wps_ie_len);
603 padapter->securitypriv.wps_phase =
605 netdev_info(padapter->pnetdev, "r8712u: SET WPS_IE, wps_phase==true\n");
606 cnt += buf[cnt + 1] + 2;
610 cnt += buf[cnt + 1] + 2;
619 static int r8711_wx_get_name(struct net_device *dev,
620 struct iw_request_info *info,
621 union iwreq_data *wrqu, char *extra)
623 struct _adapter *padapter = netdev_priv(dev);
627 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
628 struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
631 if (check_fwstate(pmlmepriv, _FW_LINKED | WIFI_ADHOC_MASTER_STATE) ==
633 /* parsing HT_CAP_IE */
634 p = r8712_get_ie(&pcur_bss->IEs[12], _HT_CAPABILITY_IE_,
635 &ht_ielen, pcur_bss->IELength - 12);
636 if (p && ht_ielen > 0)
638 prates = pcur_bss->rates;
639 if (r8712_is_cckratesonly_included(prates)) {
641 snprintf(wrqu->name, IFNAMSIZ,
644 snprintf(wrqu->name, IFNAMSIZ,
646 } else if (r8712_is_cckrates_included(prates)) {
648 snprintf(wrqu->name, IFNAMSIZ,
651 snprintf(wrqu->name, IFNAMSIZ,
655 snprintf(wrqu->name, IFNAMSIZ,
658 snprintf(wrqu->name, IFNAMSIZ,
662 snprintf(wrqu->name, IFNAMSIZ, "unassociated");
667 static const long frequency_list[] = {
668 2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447, 2452, 2457, 2462,
669 2467, 2472, 2484, 4915, 4920, 4925, 4935, 4940, 4945, 4960, 4980,
670 5035, 5040, 5045, 5055, 5060, 5080, 5170, 5180, 5190, 5200, 5210,
671 5220, 5230, 5240, 5260, 5280, 5300, 5320, 5500, 5520, 5540, 5560,
672 5580, 5600, 5620, 5640, 5660, 5680, 5700, 5745, 5765, 5785, 5805,
676 static int r8711_wx_set_freq(struct net_device *dev,
677 struct iw_request_info *info,
678 union iwreq_data *wrqu, char *extra)
680 struct _adapter *padapter = netdev_priv(dev);
681 struct iw_freq *fwrq = &wrqu->freq;
684 /* If setting by frequency, convert to a channel */
685 if ((fwrq->e == 1) &&
686 (fwrq->m >= (int) 2.412e8) &&
687 (fwrq->m <= (int) 2.487e8)) {
688 int f = fwrq->m / 100000;
691 while ((c < 14) && (f != frequency_list[c]))
696 /* Setting by channel number */
697 if ((fwrq->m > 14) || (fwrq->e > 0)) {
700 int channel = fwrq->m;
702 if ((channel < 1) || (channel > 14)) {
705 /* Yes ! We can set it !!! */
706 padapter->registrypriv.channel = channel;
712 static int r8711_wx_get_freq(struct net_device *dev,
713 struct iw_request_info *info,
714 union iwreq_data *wrqu, char *extra)
716 struct _adapter *padapter = netdev_priv(dev);
717 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
718 struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
720 if (!check_fwstate(pmlmepriv, _FW_LINKED))
723 wrqu->freq.m = ieee80211_wlan_frequencies[
724 pcur_bss->Configuration.DSConfig - 1] * 100000;
726 wrqu->freq.i = pcur_bss->Configuration.DSConfig;
731 static int r8711_wx_set_mode(struct net_device *dev,
732 struct iw_request_info *a,
733 union iwreq_data *wrqu, char *b)
735 struct _adapter *padapter = netdev_priv(dev);
736 enum NDIS_802_11_NETWORK_INFRASTRUCTURE networkType;
738 switch (wrqu->mode) {
740 networkType = Ndis802_11AutoUnknown;
743 networkType = Ndis802_11IBSS;
746 networkType = Ndis802_11APMode;
749 networkType = Ndis802_11Infrastructure;
754 if (Ndis802_11APMode == networkType)
755 r8712_setopmode_cmd(padapter, networkType);
757 r8712_setopmode_cmd(padapter, Ndis802_11AutoUnknown);
759 r8712_set_802_11_infrastructure_mode(padapter, networkType);
763 static int r8711_wx_get_mode(struct net_device *dev, struct iw_request_info *a,
764 union iwreq_data *wrqu, char *b)
766 struct _adapter *padapter = netdev_priv(dev);
767 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
769 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE))
770 wrqu->mode = IW_MODE_INFRA;
771 else if (check_fwstate(pmlmepriv,
772 WIFI_ADHOC_MASTER_STATE | WIFI_ADHOC_STATE))
773 wrqu->mode = IW_MODE_ADHOC;
774 else if (check_fwstate(pmlmepriv, WIFI_AP_STATE))
775 wrqu->mode = IW_MODE_MASTER;
777 wrqu->mode = IW_MODE_AUTO;
781 static int r871x_wx_set_pmkid(struct net_device *dev,
782 struct iw_request_info *a,
783 union iwreq_data *wrqu, char *extra)
785 struct _adapter *padapter = netdev_priv(dev);
786 struct security_priv *psecuritypriv = &padapter->securitypriv;
787 struct iw_pmksa *pPMK = (struct iw_pmksa *) extra;
788 struct RT_PMKID_LIST *pl = psecuritypriv->PMKIDList;
789 u8 strZeroMacAddress[ETH_ALEN] = {0x00};
790 u8 strIssueBssid[ETH_ALEN] = {0x00};
791 u8 j, blInserted = false;
792 int intReturn = false;
795 * There are the BSSID information in the bssid.sa_data array.
796 * If cmd is IW_PMKSA_FLUSH, it means the wpa_supplicant wants to clear
797 * all the PMKID information. If cmd is IW_PMKSA_ADD, it means the
798 * wpa_supplicant wants to add a PMKID/BSSID to driver.
799 * If cmd is IW_PMKSA_REMOVE, it means the wpa_supplicant wants to
800 * remove a PMKID/BSSID from driver.
804 memcpy(strIssueBssid, pPMK->bssid.sa_data, ETH_ALEN);
807 if (!memcmp(strIssueBssid, strZeroMacAddress, ETH_ALEN))
811 /* overwrite PMKID */
812 for (j = 0; j < NUM_PMKID_CACHE; j++) {
813 if (!memcmp(pl[j].Bssid, strIssueBssid, ETH_ALEN)) {
814 /* BSSID is matched, the same AP => rewrite
817 netdev_info(dev, "r8712u: %s: BSSID exists in the PMKList.\n",
819 memcpy(pl[j].PMKID, pPMK->pmkid, IW_PMKID_LEN);
821 psecuritypriv->PMKIDIndex = j + 1;
827 /* Find a new entry */
828 netdev_info(dev, "r8712u: %s: Use the new entry index = %d for this PMKID.\n",
829 __func__, psecuritypriv->PMKIDIndex);
830 memcpy(pl[psecuritypriv->PMKIDIndex].Bssid,
831 strIssueBssid, ETH_ALEN);
832 memcpy(pl[psecuritypriv->PMKIDIndex].PMKID,
833 pPMK->pmkid, IW_PMKID_LEN);
834 pl[psecuritypriv->PMKIDIndex].bUsed = true;
835 psecuritypriv->PMKIDIndex++;
836 if (psecuritypriv->PMKIDIndex == NUM_PMKID_CACHE)
837 psecuritypriv->PMKIDIndex = 0;
840 case IW_PMKSA_REMOVE:
842 for (j = 0; j < NUM_PMKID_CACHE; j++) {
843 if (!memcmp(pl[j].Bssid, strIssueBssid, ETH_ALEN)) {
844 /* BSSID is matched, the same AP => Remove
845 * this PMKID information and reset it.
847 eth_zero_addr(pl[j].Bssid);
854 memset(psecuritypriv->PMKIDList, 0,
855 sizeof(struct RT_PMKID_LIST) * NUM_PMKID_CACHE);
856 psecuritypriv->PMKIDIndex = 0;
860 netdev_info(dev, "r8712u: %s: unknown Command\n", __func__);
867 static int r8711_wx_get_sens(struct net_device *dev,
868 struct iw_request_info *info,
869 union iwreq_data *wrqu, char *extra)
871 wrqu->sens.value = 0;
872 wrqu->sens.fixed = 0; /* no auto select */
873 wrqu->sens.disabled = 1;
877 static int r8711_wx_get_range(struct net_device *dev,
878 struct iw_request_info *info,
879 union iwreq_data *wrqu, char *extra)
881 struct iw_range *range = (struct iw_range *)extra;
885 wrqu->data.length = sizeof(*range);
886 memset(range, 0, sizeof(*range));
887 /* Let's try to keep this struct in the same order as in
888 * linux/include/wireless.h
891 /* TODO: See what values we can set, and remove the ones we can't
892 * set, or fill them with some default data.
894 /* ~5 Mb/s real (802.11b) */
895 range->throughput = 5 * 1000 * 1000;
896 /* TODO: 8711 sensitivity ? */
897 /* signal level threshold range */
898 /* percent values between 0 and 100. */
899 range->max_qual.qual = 100;
900 range->max_qual.level = 100;
901 range->max_qual.noise = 100;
902 range->max_qual.updated = 7; /* Updated all three */
903 range->avg_qual.qual = 92; /* > 8% missed beacons is 'bad' */
904 /* TODO: Find real 'good' to 'bad' threshold value for RSSI */
905 range->avg_qual.level = 0x100 - 78;
906 range->avg_qual.noise = 0;
907 range->avg_qual.updated = 7; /* Updated all three */
908 range->num_bitrates = RATE_COUNT;
909 for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++)
910 range->bitrate[i] = rtl8180_rates[i];
911 range->min_frag = MIN_FRAG_THRESHOLD;
912 range->max_frag = MAX_FRAG_THRESHOLD;
914 range->we_version_compiled = WIRELESS_EXT;
915 range->we_version_source = 16;
916 range->num_channels = 14;
917 for (i = 0, val = 0; i < 14; i++) {
918 /* Include only legal frequencies for some countries */
919 range->freq[val].i = i + 1;
920 range->freq[val].m = ieee80211_wlan_frequencies[i] * 100000;
921 range->freq[val].e = 1;
923 if (val == IW_MAX_FREQUENCIES)
926 range->num_frequency = val;
927 range->enc_capa = IW_ENC_CAPA_WPA |
929 IW_ENC_CAPA_CIPHER_TKIP |
930 IW_ENC_CAPA_CIPHER_CCMP;
934 static int r8711_wx_get_rate(struct net_device *dev,
935 struct iw_request_info *info,
936 union iwreq_data *wrqu, char *extra);
938 static int r871x_wx_set_priv(struct net_device *dev,
939 struct iw_request_info *info,
940 union iwreq_data *awrq,
943 int ret = 0, len = 0;
945 struct _adapter *padapter = netdev_priv(dev);
946 struct iw_point *dwrq = (struct iw_point *)awrq;
949 ext = strndup_user(dwrq->pointer, len);
953 if (!strcasecmp(ext, "RSSI")) {
954 /*Return received signal strength indicator in -db for */
957 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
958 struct wlan_network *pcur_network = &pmlmepriv->cur_network;
960 if (check_fwstate(pmlmepriv, _FW_LINKED)) {
961 sprintf(ext, "%s rssi %d",
962 pcur_network->network.Ssid.Ssid,
964 ((padapter->recvpriv.fw_rssi) >> 1) - 95
965 /*pcur_network->network.Rssi */
970 } else if (!strcasecmp(ext, "LINKSPEED")) {
971 /*Return link speed in MBPS */
973 union iwreq_data wrqd;
977 ret_inner = r8711_wx_get_rate(dev, info, &wrqd, extra);
981 mbps = wrqd.bitrate.value / 1000000;
982 sprintf(ext, "LINKSPEED %d", mbps);
983 } else if (!strcasecmp(ext, "MACADDR")) {
984 /*Return mac address of the station */
985 /* Macaddr = xx:xx:xx:xx:xx:xx */
986 sprintf(ext, "MACADDR = %pM", dev->dev_addr);
987 } else if (!strcasecmp(ext, "SCAN-ACTIVE")) {
988 /*Set scan type to active */
989 /*OK if successful */
990 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
992 pmlmepriv->passive_mode = 1;
994 } else if (!strcasecmp(ext, "SCAN-PASSIVE")) {
995 /*Set scan type to passive */
996 /*OK if successful */
997 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
999 pmlmepriv->passive_mode = 0;
1001 } else if (!strncmp(ext, "DCE-E", 5)) {
1002 /*Set scan type to passive */
1003 /*OK if successful */
1004 r8712_disconnectCtrlEx_cmd(padapter
1005 , 1 /*u32 enableDrvCtrl */
1006 , 5 /*u32 tryPktCnt */
1007 , 100 /*u32 tryPktInterval */
1008 , 5000 /*u32 firstStageTO */
1011 } else if (!strncmp(ext, "DCE-D", 5)) {
1012 /*Set scan type to passive */
1013 /*OK if successfu */
1014 r8712_disconnectCtrlEx_cmd(padapter
1015 , 0 /*u32 enableDrvCtrl */
1016 , 5 /*u32 tryPktCnt */
1017 , 100 /*u32 tryPktInterval */
1018 , 5000 /*u32 firstStageTO */
1022 netdev_info(dev, "r8712u: %s: unknown Command %s.\n",
1026 if (copy_to_user(dwrq->pointer, ext,
1027 min(dwrq->length, (__u16)(strlen(ext) + 1))))
1036 * s1. set_802_11_infrastructure_mode()
1037 * s2. set_802_11_authentication_mode()
1038 * s3. set_802_11_encryption_mode()
1039 * s4. set_802_11_bssid()
1041 * This function intends to handle the Set AP command, which specifies the
1042 * MAC# of a preferred Access Point.
1043 * Currently, the request comes via Wireless Extensions' SIOCSIWAP ioctl.
1045 * For this operation to succeed, there is no need for the interface to be up.
1048 static int r8711_wx_set_wap(struct net_device *dev,
1049 struct iw_request_info *info,
1050 union iwreq_data *awrq,
1053 int ret = -EINPROGRESS;
1054 struct _adapter *padapter = netdev_priv(dev);
1055 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1056 struct __queue *queue = &pmlmepriv->scanned_queue;
1057 struct sockaddr *temp = (struct sockaddr *)awrq;
1059 struct list_head *phead;
1061 struct wlan_network *pnetwork = NULL;
1062 enum NDIS_802_11_AUTHENTICATION_MODE authmode;
1064 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY))
1066 if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING))
1068 if (temp->sa_family != ARPHRD_ETHER)
1070 authmode = padapter->securitypriv.ndisauthtype;
1071 spin_lock_irqsave(&queue->lock, irqL);
1072 phead = &queue->queue;
1073 pmlmepriv->pscanned = phead->next;
1075 if (end_of_queue_search(phead, pmlmepriv->pscanned))
1077 pnetwork = container_of(pmlmepriv->pscanned,
1078 struct wlan_network, list);
1079 pmlmepriv->pscanned = pmlmepriv->pscanned->next;
1080 dst_bssid = pnetwork->network.MacAddress;
1081 if (!memcmp(dst_bssid, temp->sa_data, ETH_ALEN)) {
1082 r8712_set_802_11_infrastructure_mode(padapter,
1083 pnetwork->network.InfrastructureMode);
1087 spin_unlock_irqrestore(&queue->lock, irqL);
1089 if (!r8712_set_802_11_authentication_mode(padapter, authmode)) {
1092 if (!r8712_set_802_11_bssid(padapter, temp->sa_data))
1099 static int r8711_wx_get_wap(struct net_device *dev,
1100 struct iw_request_info *info,
1101 union iwreq_data *wrqu, char *extra)
1103 struct _adapter *padapter = netdev_priv(dev);
1104 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1105 struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
1107 wrqu->ap_addr.sa_family = ARPHRD_ETHER;
1108 if (check_fwstate(pmlmepriv, _FW_LINKED | WIFI_ADHOC_MASTER_STATE |
1110 ether_addr_copy(wrqu->ap_addr.sa_data, pcur_bss->MacAddress);
1112 eth_zero_addr(wrqu->ap_addr.sa_data);
1116 static int r871x_wx_set_mlme(struct net_device *dev,
1117 struct iw_request_info *info,
1118 union iwreq_data *wrqu, char *extra)
1121 struct _adapter *padapter = netdev_priv(dev);
1122 struct iw_mlme *mlme = (struct iw_mlme *) extra;
1126 switch (mlme->cmd) {
1127 case IW_MLME_DEAUTH:
1128 if (!r8712_set_802_11_disassociate(padapter))
1131 case IW_MLME_DISASSOC:
1132 if (!r8712_set_802_11_disassociate(padapter))
1143 * This function intends to handle the Set Scan command.
1144 * Currently, the request comes via Wireless Extensions' SIOCSIWSCAN ioctl.
1146 * For this operation to succeed, the interface is brought Up beforehand.
1149 static int r8711_wx_set_scan(struct net_device *dev,
1150 struct iw_request_info *a,
1151 union iwreq_data *wrqu, char *extra)
1153 struct _adapter *padapter = netdev_priv(dev);
1154 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1157 if (padapter->bDriverStopped) {
1158 netdev_info(dev, "In %s: bDriverStopped=%d\n",
1159 __func__, padapter->bDriverStopped);
1164 if (!padapter->hw_init_completed)
1166 if ((check_fwstate(pmlmepriv, _FW_UNDER_SURVEY | _FW_UNDER_LINKING)) ||
1167 (pmlmepriv->sitesurveyctrl.traffic_busy))
1169 if (wrqu->data.length == sizeof(struct iw_scan_req)) {
1170 struct iw_scan_req *req = (struct iw_scan_req *)extra;
1172 if (wrqu->data.flags & IW_SCAN_THIS_ESSID) {
1173 struct ndis_802_11_ssid ssid;
1175 u32 len = min_t(u8, req->essid_len, IW_ESSID_MAX_SIZE);
1177 memset((unsigned char *)&ssid, 0,
1178 sizeof(struct ndis_802_11_ssid));
1179 memcpy(ssid.Ssid, req->essid, len);
1180 ssid.SsidLength = len;
1181 spin_lock_irqsave(&pmlmepriv->lock, irqL);
1182 if ((check_fwstate(pmlmepriv, _FW_UNDER_SURVEY |
1183 _FW_UNDER_LINKING)) ||
1184 (pmlmepriv->sitesurveyctrl.traffic_busy)) {
1185 if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING))
1188 status = r8712_sitesurvey_cmd(padapter, &ssid);
1190 spin_unlock_irqrestore(&pmlmepriv->lock, irqL);
1193 status = r8712_set_802_11_bssid_list_scan(padapter);
1200 static int r8711_wx_get_scan(struct net_device *dev,
1201 struct iw_request_info *a,
1202 union iwreq_data *wrqu, char *extra)
1204 struct _adapter *padapter = netdev_priv(dev);
1205 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1206 struct __queue *queue = &pmlmepriv->scanned_queue;
1207 struct wlan_network *pnetwork = NULL;
1209 struct list_head *plist, *phead;
1211 char *stop = ev + wrqu->data.length;
1212 u32 ret = 0, cnt = 0;
1214 if (padapter->bDriverStopped)
1216 while (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY |
1217 _FW_UNDER_LINKING)) {
1223 spin_lock_irqsave(&queue->lock, irqL);
1224 phead = &queue->queue;
1225 plist = phead->next;
1227 if (end_of_queue_search(phead, plist))
1229 if ((stop - ev) < SCAN_ITEM_SIZE) {
1233 pnetwork = container_of(plist, struct wlan_network, list);
1234 ev = translate_scan(padapter, a, pnetwork, ev, stop);
1235 plist = plist->next;
1237 spin_unlock_irqrestore(&queue->lock, irqL);
1238 wrqu->data.length = ev - extra;
1239 wrqu->data.flags = 0;
1244 * s1. set_802_11_infrastructure_mode()
1245 * s2. set_802_11_authenticaion_mode()
1246 * s3. set_802_11_encryption_mode()
1247 * s4. set_802_11_ssid()
1249 * This function intends to handle the Set ESSID command.
1250 * Currently, the request comes via the Wireless Extensions' SIOCSIWESSID ioctl.
1252 * For this operation to succeed, there is no need for the interface to be Up.
1255 static int r8711_wx_set_essid(struct net_device *dev,
1256 struct iw_request_info *a,
1257 union iwreq_data *wrqu, char *extra)
1259 struct _adapter *padapter = netdev_priv(dev);
1260 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1261 struct __queue *queue = &pmlmepriv->scanned_queue;
1262 struct wlan_network *pnetwork = NULL;
1263 enum NDIS_802_11_AUTHENTICATION_MODE authmode;
1264 struct ndis_802_11_ssid ndis_ssid;
1265 u8 *dst_ssid, *src_ssid;
1266 struct list_head *phead;
1269 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY))
1271 if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING))
1273 if (wrqu->essid.length > IW_ESSID_MAX_SIZE)
1275 authmode = padapter->securitypriv.ndisauthtype;
1276 if (wrqu->essid.flags && wrqu->essid.length) {
1277 len = (wrqu->essid.length < IW_ESSID_MAX_SIZE) ?
1278 wrqu->essid.length : IW_ESSID_MAX_SIZE;
1279 memset(&ndis_ssid, 0, sizeof(struct ndis_802_11_ssid));
1280 ndis_ssid.SsidLength = len;
1281 memcpy(ndis_ssid.Ssid, extra, len);
1282 src_ssid = ndis_ssid.Ssid;
1283 phead = &queue->queue;
1284 pmlmepriv->pscanned = phead->next;
1286 if (end_of_queue_search(phead, pmlmepriv->pscanned))
1288 pnetwork = container_of(pmlmepriv->pscanned,
1289 struct wlan_network, list);
1290 pmlmepriv->pscanned = pmlmepriv->pscanned->next;
1291 dst_ssid = pnetwork->network.Ssid.Ssid;
1292 if ((!memcmp(dst_ssid, src_ssid, ndis_ssid.SsidLength))
1293 && (pnetwork->network.Ssid.SsidLength ==
1294 ndis_ssid.SsidLength)) {
1295 if (check_fwstate(pmlmepriv,
1296 WIFI_ADHOC_STATE)) {
1297 if (pnetwork->network.
1301 cur_network.network.
1306 r8712_set_802_11_infrastructure_mode(
1308 pnetwork->network.InfrastructureMode);
1312 r8712_set_802_11_authentication_mode(padapter, authmode);
1313 r8712_set_802_11_ssid(padapter, &ndis_ssid);
1315 return -EINPROGRESS;
1318 static int r8711_wx_get_essid(struct net_device *dev,
1319 struct iw_request_info *a,
1320 union iwreq_data *wrqu, char *extra)
1322 struct _adapter *padapter = netdev_priv(dev);
1323 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1324 struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
1327 if (check_fwstate(pmlmepriv, _FW_LINKED | WIFI_ADHOC_MASTER_STATE)) {
1328 len = pcur_bss->Ssid.SsidLength;
1329 wrqu->essid.length = len;
1330 memcpy(extra, pcur_bss->Ssid.Ssid, len);
1331 wrqu->essid.flags = 1;
1338 static int r8711_wx_set_rate(struct net_device *dev,
1339 struct iw_request_info *a,
1340 union iwreq_data *wrqu, char *extra)
1342 struct _adapter *padapter = netdev_priv(dev);
1343 u32 target_rate = wrqu->bitrate.value;
1344 u32 fixed = wrqu->bitrate.fixed;
1346 u8 datarates[NumRates];
1347 u8 mpdatarate[NumRates] = {11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0xff};
1350 if (target_rate == -1) {
1354 target_rate = target_rate / 100000;
1355 switch (target_rate) {
1397 for (i = 0; i < NumRates; i++) {
1398 if (ratevalue == mpdatarate[i]) {
1399 datarates[i] = mpdatarate[i];
1403 datarates[i] = 0xff;
1406 if (r8712_setdatarate_cmd(padapter, datarates) != _SUCCESS)
1411 static int r8711_wx_get_rate(struct net_device *dev,
1412 struct iw_request_info *info,
1413 union iwreq_data *wrqu, char *extra)
1415 struct _adapter *padapter = netdev_priv(dev);
1416 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1417 struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
1418 struct ieee80211_ht_cap *pht_capie;
1419 unsigned char rf_type = padapter->registrypriv.rf_config;
1422 u16 rate, max_rate = 0, ht_cap = false;
1424 u8 bw_40MHz = 0, short_GI = 0;
1428 if (!check_fwstate(pmlmepriv, _FW_LINKED | WIFI_ADHOC_MASTER_STATE))
1430 p = r8712_get_ie(&pcur_bss->IEs[12], _HT_CAPABILITY_IE_, &ht_ielen,
1431 pcur_bss->IELength - 12);
1432 if (p && ht_ielen > 0) {
1434 pht_capie = (struct ieee80211_ht_cap *)(p + 2);
1435 memcpy(&mcs_rate, pht_capie->supp_mcs_set, 2);
1436 bw_40MHz = (le16_to_cpu(pht_capie->cap_info) &
1437 IEEE80211_HT_CAP_SUP_WIDTH) ? 1 : 0;
1438 short_GI = (le16_to_cpu(pht_capie->cap_info) &
1439 (IEEE80211_HT_CAP_SGI_20 |
1440 IEEE80211_HT_CAP_SGI_40)) ? 1 : 0;
1442 while ((pcur_bss->rates[i] != 0) &&
1443 (pcur_bss->rates[i] != 0xFF)) {
1444 rate = pcur_bss->rates[i] & 0x7F;
1445 if (rate > max_rate)
1447 wrqu->bitrate.fixed = 0; /* no auto select */
1448 wrqu->bitrate.value = rate * 500000;
1452 if (mcs_rate & 0x8000 /* MCS15 */
1454 rf_type == RTL8712_RF_2T2R)
1455 max_rate = (bw_40MHz) ? ((short_GI) ? 300 : 270) :
1456 ((short_GI) ? 144 : 130);
1457 else /* default MCS7 */
1458 max_rate = (bw_40MHz) ? ((short_GI) ? 150 : 135) :
1459 ((short_GI) ? 72 : 65);
1460 max_rate *= 2; /* Mbps/2 */
1462 wrqu->bitrate.value = max_rate * 500000;
1466 static int r8711_wx_get_rts(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 wrqu->rts.value = padapter->registrypriv.rts_thresh;
1473 wrqu->rts.fixed = 0; /* no auto select */
1477 static int r8711_wx_set_frag(struct net_device *dev,
1478 struct iw_request_info *info,
1479 union iwreq_data *wrqu, char *extra)
1481 struct _adapter *padapter = netdev_priv(dev);
1483 if (wrqu->frag.disabled) {
1484 padapter->xmitpriv.frag_len = MAX_FRAG_THRESHOLD;
1486 if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
1487 wrqu->frag.value > MAX_FRAG_THRESHOLD)
1489 padapter->xmitpriv.frag_len = wrqu->frag.value & ~0x1;
1494 static int r8711_wx_get_frag(struct net_device *dev,
1495 struct iw_request_info *info,
1496 union iwreq_data *wrqu, char *extra)
1498 struct _adapter *padapter = netdev_priv(dev);
1500 wrqu->frag.value = padapter->xmitpriv.frag_len;
1501 wrqu->frag.fixed = 0; /* no auto select */
1505 static int r8711_wx_get_retry(struct net_device *dev,
1506 struct iw_request_info *info,
1507 union iwreq_data *wrqu, char *extra)
1509 wrqu->retry.value = 7;
1510 wrqu->retry.fixed = 0; /* no auto select */
1511 wrqu->retry.disabled = 1;
1515 static int r8711_wx_set_enc(struct net_device *dev,
1516 struct iw_request_info *info,
1517 union iwreq_data *wrqu, char *keybuf)
1520 u32 keyindex_provided;
1521 struct NDIS_802_11_WEP wep;
1522 enum NDIS_802_11_AUTHENTICATION_MODE authmode;
1523 struct iw_point *erq = &(wrqu->encoding);
1524 struct _adapter *padapter = netdev_priv(dev);
1526 key = erq->flags & IW_ENCODE_INDEX;
1527 memset(&wep, 0, sizeof(struct NDIS_802_11_WEP));
1528 if (erq->flags & IW_ENCODE_DISABLED) {
1529 netdev_info(dev, "r8712u: %s: EncryptionDisabled\n", __func__);
1530 padapter->securitypriv.ndisencryptstatus =
1531 Ndis802_11EncryptionDisabled;
1532 padapter->securitypriv.PrivacyAlgrthm = _NO_PRIVACY_;
1533 padapter->securitypriv.XGrpPrivacy = _NO_PRIVACY_;
1534 padapter->securitypriv.AuthAlgrthm = 0; /* open system */
1535 authmode = Ndis802_11AuthModeOpen;
1536 padapter->securitypriv.ndisauthtype = authmode;
1543 keyindex_provided = 1;
1545 keyindex_provided = 0;
1546 key = padapter->securitypriv.PrivacyKeyIndex;
1548 /* set authentication mode */
1549 if (erq->flags & IW_ENCODE_OPEN) {
1550 netdev_info(dev, "r8712u: %s: IW_ENCODE_OPEN\n", __func__);
1551 padapter->securitypriv.ndisencryptstatus =
1552 Ndis802_11Encryption1Enabled;
1553 padapter->securitypriv.AuthAlgrthm = 0; /* open system */
1554 padapter->securitypriv.PrivacyAlgrthm = _NO_PRIVACY_;
1555 padapter->securitypriv.XGrpPrivacy = _NO_PRIVACY_;
1556 authmode = Ndis802_11AuthModeOpen;
1557 padapter->securitypriv.ndisauthtype = authmode;
1558 } else if (erq->flags & IW_ENCODE_RESTRICTED) {
1560 "r8712u: %s: IW_ENCODE_RESTRICTED\n", __func__);
1561 padapter->securitypriv.ndisencryptstatus =
1562 Ndis802_11Encryption1Enabled;
1563 padapter->securitypriv.AuthAlgrthm = 1; /* shared system */
1564 padapter->securitypriv.PrivacyAlgrthm = _WEP40_;
1565 padapter->securitypriv.XGrpPrivacy = _WEP40_;
1566 authmode = Ndis802_11AuthModeShared;
1567 padapter->securitypriv.ndisauthtype = authmode;
1569 padapter->securitypriv.ndisencryptstatus =
1570 Ndis802_11Encryption1Enabled;
1571 padapter->securitypriv.AuthAlgrthm = 0; /* open system */
1572 padapter->securitypriv.PrivacyAlgrthm = _NO_PRIVACY_;
1573 padapter->securitypriv.XGrpPrivacy = _NO_PRIVACY_;
1574 authmode = Ndis802_11AuthModeOpen;
1575 padapter->securitypriv.ndisauthtype = authmode;
1578 if (erq->length > 0) {
1579 wep.KeyLength = erq->length <= 5 ? 5 : 13;
1580 wep.Length = wep.KeyLength +
1581 FIELD_OFFSET(struct NDIS_802_11_WEP, KeyMaterial);
1584 if (keyindex_provided == 1) { /* set key_id only, no given
1585 * KeyMaterial(erq->length==0).
1587 padapter->securitypriv.PrivacyKeyIndex = key;
1588 switch (padapter->securitypriv.DefKeylen[key]) {
1590 padapter->securitypriv.PrivacyAlgrthm =
1594 padapter->securitypriv.PrivacyAlgrthm =
1598 padapter->securitypriv.PrivacyAlgrthm =
1605 wep.KeyIndex |= 0x80000000; /* transmit key */
1606 memcpy(wep.KeyMaterial, keybuf, wep.KeyLength);
1607 if (r8712_set_802_11_add_wep(padapter, &wep) == _FAIL)
1612 static int r8711_wx_get_enc(struct net_device *dev,
1613 struct iw_request_info *info,
1614 union iwreq_data *wrqu, char *keybuf)
1617 struct _adapter *padapter = netdev_priv(dev);
1618 struct iw_point *erq = &(wrqu->encoding);
1619 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1620 union Keytype *dk = padapter->securitypriv.DefKey;
1622 if (!check_fwstate(pmlmepriv, _FW_LINKED)) {
1623 if (!check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) {
1625 erq->flags |= IW_ENCODE_DISABLED;
1629 key = erq->flags & IW_ENCODE_INDEX;
1635 key = padapter->securitypriv.PrivacyKeyIndex;
1637 erq->flags = key + 1;
1638 switch (padapter->securitypriv.ndisencryptstatus) {
1639 case Ndis802_11EncryptionNotSupported:
1640 case Ndis802_11EncryptionDisabled:
1642 erq->flags |= IW_ENCODE_DISABLED;
1644 case Ndis802_11Encryption1Enabled:
1645 erq->length = padapter->securitypriv.DefKeylen[key];
1647 memcpy(keybuf, dk[key].skey,
1648 padapter->securitypriv.DefKeylen[key]);
1649 erq->flags |= IW_ENCODE_ENABLED;
1650 if (padapter->securitypriv.ndisauthtype ==
1651 Ndis802_11AuthModeOpen)
1652 erq->flags |= IW_ENCODE_OPEN;
1653 else if (padapter->securitypriv.ndisauthtype ==
1654 Ndis802_11AuthModeShared)
1655 erq->flags |= IW_ENCODE_RESTRICTED;
1658 erq->flags |= IW_ENCODE_DISABLED;
1661 case Ndis802_11Encryption2Enabled:
1662 case Ndis802_11Encryption3Enabled:
1664 erq->flags |= (IW_ENCODE_ENABLED | IW_ENCODE_OPEN |
1669 erq->flags |= IW_ENCODE_DISABLED;
1675 static int r8711_wx_get_power(struct net_device *dev,
1676 struct iw_request_info *info,
1677 union iwreq_data *wrqu, char *extra)
1679 wrqu->power.value = 0;
1680 wrqu->power.fixed = 0; /* no auto select */
1681 wrqu->power.disabled = 1;
1685 static int r871x_wx_set_gen_ie(struct net_device *dev,
1686 struct iw_request_info *info,
1687 union iwreq_data *wrqu, char *extra)
1689 struct _adapter *padapter = netdev_priv(dev);
1691 return r871x_set_wpa_ie(padapter, extra, wrqu->data.length);
1694 static int r871x_wx_set_auth(struct net_device *dev,
1695 struct iw_request_info *info,
1696 union iwreq_data *wrqu, char *extra)
1698 struct _adapter *padapter = netdev_priv(dev);
1699 struct iw_param *param = (struct iw_param *)&(wrqu->param);
1704 paramid = param->flags & IW_AUTH_INDEX;
1705 paramval = param->value;
1707 case IW_AUTH_WPA_VERSION:
1709 case IW_AUTH_CIPHER_PAIRWISE:
1711 case IW_AUTH_CIPHER_GROUP:
1713 case IW_AUTH_KEY_MGMT:
1715 * ??? does not use these parameters
1718 case IW_AUTH_TKIP_COUNTERMEASURES:
1720 /* wpa_supplicant is enabling tkip countermeasure. */
1721 padapter->securitypriv.btkip_countermeasure = true;
1723 /* wpa_supplicant is disabling tkip countermeasure. */
1724 padapter->securitypriv.btkip_countermeasure = false;
1727 case IW_AUTH_DROP_UNENCRYPTED:
1730 * wpa_supplicant calls set_wpa_enabled when the driver
1731 * is loaded and unloaded, regardless of if WPA is being
1732 * used. No other calls are made which can be used to
1733 * determine if encryption will be used or not prior to
1734 * association being expected. If encryption is not being
1735 * used, drop_unencrypted is set to false, else true -- we
1736 * can use this to determine if the CAP_PRIVACY_ON bit should
1739 if (padapter->securitypriv.ndisencryptstatus ==
1740 Ndis802_11Encryption1Enabled) {
1741 /* it means init value, or using wep,
1742 * ndisencryptstatus =
1743 * Ndis802_11Encryption1Enabled,
1744 * then it needn't reset it;
1750 padapter->securitypriv.ndisencryptstatus =
1751 Ndis802_11EncryptionDisabled;
1752 padapter->securitypriv.PrivacyAlgrthm =
1754 padapter->securitypriv.XGrpPrivacy =
1756 padapter->securitypriv.AuthAlgrthm = 0;
1757 padapter->securitypriv.ndisauthtype =
1758 Ndis802_11AuthModeOpen;
1761 case IW_AUTH_80211_AUTH_ALG:
1762 ret = wpa_set_auth_algs(dev, (u32)paramval);
1764 case IW_AUTH_WPA_ENABLED:
1766 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
1768 case IW_AUTH_PRIVACY_INVOKED:
1777 static int r871x_wx_set_enc_ext(struct net_device *dev,
1778 struct iw_request_info *info,
1779 union iwreq_data *wrqu, char *extra)
1781 struct iw_point *pencoding = &wrqu->encoding;
1782 struct iw_encode_ext *pext = (struct iw_encode_ext *)extra;
1783 struct ieee_param *param = NULL;
1788 switch (pext->alg) {
1789 case IW_ENCODE_ALG_NONE:
1792 case IW_ENCODE_ALG_WEP:
1795 case IW_ENCODE_ALG_TKIP:
1798 case IW_ENCODE_ALG_CCMP:
1805 param_len = sizeof(struct ieee_param) + pext->key_len;
1806 param = kzalloc(param_len, GFP_ATOMIC);
1809 param->cmd = IEEE_CMD_SET_ENCRYPTION;
1810 eth_broadcast_addr(param->sta_addr);
1811 strncpy((char *)param->u.crypt.alg, alg_name, IEEE_CRYPT_ALG_NAME_LEN);
1812 if (pext->ext_flags & IW_ENCODE_EXT_GROUP_KEY)
1813 param->u.crypt.set_tx = 0;
1814 if (pext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
1815 param->u.crypt.set_tx = 1;
1816 param->u.crypt.idx = (pencoding->flags & 0x00FF) - 1;
1817 if (pext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID)
1818 memcpy(param->u.crypt.seq, pext->rx_seq, 8);
1819 if (pext->key_len) {
1820 param->u.crypt.key_len = pext->key_len;
1821 memcpy(param + 1, pext + 1, pext->key_len);
1823 ret = wpa_set_encryption(dev, param, param_len);
1828 static int r871x_wx_get_nick(struct net_device *dev,
1829 struct iw_request_info *info,
1830 union iwreq_data *wrqu, char *extra)
1833 wrqu->data.length = 8;
1834 wrqu->data.flags = 1;
1835 memcpy(extra, "rtl_wifi", 8);
1840 static int r8711_wx_read32(struct net_device *dev,
1841 struct iw_request_info *info,
1842 union iwreq_data *wrqu, char *keybuf)
1844 struct _adapter *padapter = netdev_priv(dev);
1848 get_user(addr, (u32 __user *)wrqu->data.pointer);
1849 data32 = r8712_read32(padapter, addr);
1850 put_user(data32, (u32 __user *)wrqu->data.pointer);
1851 wrqu->data.length = (data32 & 0xffff0000) >> 16;
1852 wrqu->data.flags = data32 & 0xffff;
1853 get_user(addr, (u32 __user *)wrqu->data.pointer);
1857 static int r8711_wx_write32(struct net_device *dev,
1858 struct iw_request_info *info,
1859 union iwreq_data *wrqu, char *keybuf)
1861 struct _adapter *padapter = netdev_priv(dev);
1865 get_user(addr, (u32 __user *)wrqu->data.pointer);
1866 data32 = ((u32)wrqu->data.length << 16) | (u32)wrqu->data.flags;
1867 r8712_write32(padapter, addr, data32);
1871 static int dummy(struct net_device *dev,
1872 struct iw_request_info *a,
1873 union iwreq_data *wrqu, char *b)
1878 static int r8711_drvext_hdl(struct net_device *dev,
1879 struct iw_request_info *info,
1880 union iwreq_data *wrqu, char *extra)
1885 static int r871x_mp_ioctl_hdl(struct net_device *dev,
1886 struct iw_request_info *info,
1887 union iwreq_data *wrqu, char *extra)
1889 struct _adapter *padapter = netdev_priv(dev);
1890 struct iw_point *p = &wrqu->data;
1891 struct oid_par_priv oid_par;
1892 struct mp_ioctl_handler *phandler;
1893 struct mp_ioctl_param *poidparam;
1894 unsigned long BytesRead, BytesWritten, BytesNeeded;
1900 if ((!p->length) || (!p->pointer))
1903 bset = (u8)(p->flags & 0xFFFF);
1905 pparmbuf = memdup_user(p->pointer, len);
1906 if (IS_ERR(pparmbuf))
1907 return PTR_ERR(pparmbuf);
1909 poidparam = (struct mp_ioctl_param *)pparmbuf;
1910 if (poidparam->subcode >= MAX_MP_IOCTL_SUBCODE) {
1912 goto _r871x_mp_ioctl_hdl_exit;
1914 phandler = mp_ioctl_hdl + poidparam->subcode;
1915 if ((phandler->paramsize != 0) &&
1916 (poidparam->len < phandler->paramsize)) {
1918 goto _r871x_mp_ioctl_hdl_exit;
1920 if (phandler->oid == 0 && phandler->handler) {
1921 status = phandler->handler(&oid_par);
1922 } else if (phandler->handler) {
1923 oid_par.adapter_context = padapter;
1924 oid_par.oid = phandler->oid;
1925 oid_par.information_buf = poidparam->data;
1926 oid_par.information_buf_len = poidparam->len;
1931 oid_par.bytes_rw = &BytesRead;
1932 oid_par.bytes_needed = &BytesNeeded;
1933 oid_par.type_of_oid = SET_OID;
1935 oid_par.bytes_rw = &BytesWritten;
1936 oid_par.bytes_needed = &BytesNeeded;
1937 oid_par.type_of_oid = QUERY_OID;
1939 status = phandler->handler(&oid_par);
1940 /* todo:check status, BytesNeeded, etc. */
1942 netdev_info(dev, "r8712u: %s: err!, subcode=%d, oid=%d, handler=%p\n",
1943 __func__, poidparam->subcode, phandler->oid,
1946 goto _r871x_mp_ioctl_hdl_exit;
1948 if (bset == 0x00) { /* query info */
1949 if (copy_to_user(p->pointer, pparmbuf, len))
1954 goto _r871x_mp_ioctl_hdl_exit;
1956 _r871x_mp_ioctl_hdl_exit:
1961 static int r871x_get_ap_info(struct net_device *dev,
1962 struct iw_request_info *info,
1963 union iwreq_data *wrqu, char *extra)
1965 struct _adapter *padapter = netdev_priv(dev);
1966 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1967 struct __queue *queue = &pmlmepriv->scanned_queue;
1968 struct iw_point *pdata = &wrqu->data;
1969 struct wlan_network *pnetwork = NULL;
1970 u32 cnt = 0, wpa_ielen;
1972 struct list_head *plist, *phead;
1973 unsigned char *pbuf;
1977 if (padapter->bDriverStopped || (pdata == NULL))
1979 while (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY |
1980 _FW_UNDER_LINKING)) {
1987 if (pdata->length < 32)
1989 if (copy_from_user(data, pdata->pointer, 32))
1993 spin_lock_irqsave(&(pmlmepriv->scanned_queue.lock), irqL);
1994 phead = &queue->queue;
1995 plist = phead->next;
1997 if (end_of_queue_search(phead, plist))
1999 pnetwork = container_of(plist, struct wlan_network, list);
2000 if (!mac_pton(data, bssid)) {
2001 netdev_info(dev, "r8712u: Invalid BSSID '%s'.\n",
2003 spin_unlock_irqrestore(&(pmlmepriv->scanned_queue.lock),
2007 netdev_info(dev, "r8712u: BSSID:%pM\n", bssid);
2008 if (ether_addr_equal(bssid, pnetwork->network.MacAddress)) {
2009 /* BSSID match, then check if supporting wpa/wpa2 */
2010 pbuf = r8712_get_wpa_ie(&pnetwork->network.IEs[12],
2011 &wpa_ielen, pnetwork->network.IELength - 12);
2012 if (pbuf && (wpa_ielen > 0)) {
2016 pbuf = r8712_get_wpa2_ie(&pnetwork->network.IEs[12],
2017 &wpa_ielen, pnetwork->network.IELength - 12);
2018 if (pbuf && (wpa_ielen > 0)) {
2023 plist = plist->next;
2025 spin_unlock_irqrestore(&(pmlmepriv->scanned_queue.lock), irqL);
2026 if (pdata->length >= 34) {
2027 if (copy_to_user((u8 __user *)pdata->pointer + 32,
2028 (u8 *)&pdata->flags, 1))
2034 static int r871x_set_pid(struct net_device *dev,
2035 struct iw_request_info *info,
2036 union iwreq_data *wrqu, char *extra)
2038 struct _adapter *padapter = netdev_priv(dev);
2039 struct iw_point *pdata = &wrqu->data;
2041 if ((padapter->bDriverStopped) || (pdata == NULL))
2043 if (copy_from_user(&padapter->pid, pdata->pointer, sizeof(int)))
2048 static int r871x_set_chplan(struct net_device *dev,
2049 struct iw_request_info *info,
2050 union iwreq_data *wrqu, char *extra)
2053 struct _adapter *padapter = netdev_priv(dev);
2054 struct iw_point *pdata = &wrqu->data;
2057 if ((padapter->bDriverStopped) || (pdata == NULL)) {
2061 ch_plan = (int)*extra;
2062 r8712_set_chplan_cmd(padapter, ch_plan);
2069 static int r871x_wps_start(struct net_device *dev,
2070 struct iw_request_info *info,
2071 union iwreq_data *wrqu, char *extra)
2073 struct _adapter *padapter = netdev_priv(dev);
2074 struct iw_point *pdata = &wrqu->data;
2075 u32 u32wps_start = 0;
2077 if ((padapter->bDriverStopped) || (pdata == NULL))
2079 if (copy_from_user((void *)&u32wps_start, pdata->pointer, 4))
2081 if (u32wps_start == 0)
2082 u32wps_start = *extra;
2083 if (u32wps_start == 1) /* WPS Start */
2084 padapter->ledpriv.LedControlHandler(padapter,
2086 else if (u32wps_start == 2) /* WPS Stop because of wps success */
2087 padapter->ledpriv.LedControlHandler(padapter,
2089 else if (u32wps_start == 3) /* WPS Stop because of wps fail */
2090 padapter->ledpriv.LedControlHandler(padapter,
2091 LED_CTL_STOP_WPS_FAIL);
2095 static int wpa_set_param(struct net_device *dev, u8 name, u32 value)
2097 struct _adapter *padapter = netdev_priv(dev);
2100 case IEEE_PARAM_WPA_ENABLED:
2101 padapter->securitypriv.AuthAlgrthm = 2; /* 802.1x */
2102 switch ((value) & 0xff) {
2104 padapter->securitypriv.ndisauthtype =
2105 Ndis802_11AuthModeWPAPSK; /* WPA_PSK */
2106 padapter->securitypriv.ndisencryptstatus =
2107 Ndis802_11Encryption2Enabled;
2110 padapter->securitypriv.ndisauthtype =
2111 Ndis802_11AuthModeWPA2PSK; /* WPA2_PSK */
2112 padapter->securitypriv.ndisencryptstatus =
2113 Ndis802_11Encryption3Enabled;
2117 case IEEE_PARAM_TKIP_COUNTERMEASURES:
2119 case IEEE_PARAM_DROP_UNENCRYPTED:
2122 * wpa_supplicant calls set_wpa_enabled when the driver
2123 * is loaded and unloaded, regardless of if WPA is being
2124 * used. No other calls are made which can be used to
2125 * determine if encryption will be used or not prior to
2126 * association being expected. If encryption is not being
2127 * used, drop_unencrypted is set to false, else true -- we
2128 * can use this to determine if the CAP_PRIVACY_ON bit should
2132 case IEEE_PARAM_PRIVACY_INVOKED:
2134 case IEEE_PARAM_AUTH_ALGS:
2135 return wpa_set_auth_algs(dev, value);
2136 case IEEE_PARAM_IEEE_802_1X:
2138 case IEEE_PARAM_WPAX_SELECT:
2139 /* added for WPA2 mixed mode */
2147 static int wpa_mlme(struct net_device *dev, u32 command, u32 reason)
2149 struct _adapter *padapter = netdev_priv(dev);
2152 case IEEE_MLME_STA_DEAUTH:
2153 if (!r8712_set_802_11_disassociate(padapter))
2156 case IEEE_MLME_STA_DISASSOC:
2157 if (!r8712_set_802_11_disassociate(padapter))
2166 static int wpa_supplicant_ioctl(struct net_device *dev, struct iw_point *p)
2168 struct ieee_param *param;
2170 struct _adapter *padapter = netdev_priv(dev);
2172 if (p->length < sizeof(struct ieee_param) || !p->pointer)
2174 param = memdup_user(p->pointer, p->length);
2176 return PTR_ERR(param);
2177 switch (param->cmd) {
2178 case IEEE_CMD_SET_WPA_PARAM:
2179 ret = wpa_set_param(dev, param->u.wpa_param.name,
2180 param->u.wpa_param.value);
2182 case IEEE_CMD_SET_WPA_IE:
2183 ret = r871x_set_wpa_ie(padapter, (char *)param->u.wpa_ie.data,
2184 (u16)param->u.wpa_ie.len);
2186 case IEEE_CMD_SET_ENCRYPTION:
2187 ret = wpa_set_encryption(dev, param, p->length);
2190 ret = wpa_mlme(dev, param->u.mlme.command,
2191 param->u.mlme.reason_code);
2197 if (ret == 0 && copy_to_user(p->pointer, param, p->length))
2203 /* based on "driver_ipw" and for hostapd */
2204 int r871x_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
2206 struct iwreq *wrq = (struct iwreq *)rq;
2209 case RTL_IOCTL_WPA_SUPPLICANT:
2210 return wpa_supplicant_ioctl(dev, &wrq->u.data);
2217 static iw_handler r8711_handlers[] = {
2218 NULL, /* SIOCSIWCOMMIT */
2219 r8711_wx_get_name, /* SIOCGIWNAME */
2220 dummy, /* SIOCSIWNWID */
2221 dummy, /* SIOCGIWNWID */
2222 r8711_wx_set_freq, /* SIOCSIWFREQ */
2223 r8711_wx_get_freq, /* SIOCGIWFREQ */
2224 r8711_wx_set_mode, /* SIOCSIWMODE */
2225 r8711_wx_get_mode, /* SIOCGIWMODE */
2226 dummy, /* SIOCSIWSENS */
2227 r8711_wx_get_sens, /* SIOCGIWSENS */
2228 NULL, /* SIOCSIWRANGE */
2229 r8711_wx_get_range, /* SIOCGIWRANGE */
2230 r871x_wx_set_priv, /* SIOCSIWPRIV */
2231 NULL, /* SIOCGIWPRIV */
2232 NULL, /* SIOCSIWSTATS */
2233 NULL, /* SIOCGIWSTATS */
2234 dummy, /* SIOCSIWSPY */
2235 dummy, /* SIOCGIWSPY */
2236 NULL, /* SIOCGIWTHRSPY */
2237 NULL, /* SIOCWIWTHRSPY */
2238 r8711_wx_set_wap, /* SIOCSIWAP */
2239 r8711_wx_get_wap, /* SIOCGIWAP */
2240 r871x_wx_set_mlme, /* request MLME operation;
2241 * uses struct iw_mlme
2243 dummy, /* SIOCGIWAPLIST -- deprecated */
2244 r8711_wx_set_scan, /* SIOCSIWSCAN */
2245 r8711_wx_get_scan, /* SIOCGIWSCAN */
2246 r8711_wx_set_essid, /* SIOCSIWESSID */
2247 r8711_wx_get_essid, /* SIOCGIWESSID */
2248 dummy, /* SIOCSIWNICKN */
2249 r871x_wx_get_nick, /* SIOCGIWNICKN */
2250 NULL, /* -- hole -- */
2251 NULL, /* -- hole -- */
2252 r8711_wx_set_rate, /* SIOCSIWRATE */
2253 r8711_wx_get_rate, /* SIOCGIWRATE */
2254 dummy, /* SIOCSIWRTS */
2255 r8711_wx_get_rts, /* SIOCGIWRTS */
2256 r8711_wx_set_frag, /* SIOCSIWFRAG */
2257 r8711_wx_get_frag, /* SIOCGIWFRAG */
2258 dummy, /* SIOCSIWTXPOW */
2259 dummy, /* SIOCGIWTXPOW */
2260 dummy, /* SIOCSIWRETRY */
2261 r8711_wx_get_retry, /* SIOCGIWRETRY */
2262 r8711_wx_set_enc, /* SIOCSIWENCODE */
2263 r8711_wx_get_enc, /* SIOCGIWENCODE */
2264 dummy, /* SIOCSIWPOWER */
2265 r8711_wx_get_power, /* SIOCGIWPOWER */
2266 NULL, /*---hole---*/
2267 NULL, /*---hole---*/
2268 r871x_wx_set_gen_ie, /* SIOCSIWGENIE */
2269 NULL, /* SIOCGIWGENIE */
2270 r871x_wx_set_auth, /* SIOCSIWAUTH */
2271 NULL, /* SIOCGIWAUTH */
2272 r871x_wx_set_enc_ext, /* SIOCSIWENCODEEXT */
2273 NULL, /* SIOCGIWENCODEEXT */
2274 r871x_wx_set_pmkid, /* SIOCSIWPMKSA */
2275 NULL, /*---hole---*/
2278 static const struct iw_priv_args r8711_private_args[] = {
2280 SIOCIWFIRSTPRIV + 0x0,
2281 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "read32"
2284 SIOCIWFIRSTPRIV + 0x1,
2285 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "write32"
2288 SIOCIWFIRSTPRIV + 0x2, 0, 0, "driver_ext"
2291 SIOCIWFIRSTPRIV + 0x3, 0, 0, "mp_ioctl"
2294 SIOCIWFIRSTPRIV + 0x4,
2295 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "apinfo"
2298 SIOCIWFIRSTPRIV + 0x5,
2299 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setpid"
2302 SIOCIWFIRSTPRIV + 0x6,
2303 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wps_start"
2306 SIOCIWFIRSTPRIV + 0x7,
2307 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "chplan"
2311 static iw_handler r8711_private_handler[] = {
2316 r871x_get_ap_info, /*for MM DTV platform*/
2322 static struct iw_statistics *r871x_get_wireless_stats(struct net_device *dev)
2324 struct _adapter *padapter = netdev_priv(dev);
2325 struct iw_statistics *piwstats = &padapter->iwstats;
2330 if (check_fwstate(&padapter->mlmepriv, _FW_LINKED) != true) {
2331 piwstats->qual.qual = 0;
2332 piwstats->qual.level = 0;
2333 piwstats->qual.noise = 0;
2335 /* show percentage, we need transfer dbm to original value. */
2336 tmp_level = padapter->recvpriv.fw_rssi;
2337 tmp_qual = padapter->recvpriv.signal;
2338 tmp_noise = padapter->recvpriv.noise;
2339 piwstats->qual.level = tmp_level;
2340 piwstats->qual.qual = tmp_qual;
2341 piwstats->qual.noise = tmp_noise;
2343 piwstats->qual.updated = IW_QUAL_ALL_UPDATED;
2344 return &padapter->iwstats;
2347 struct iw_handler_def r871x_handlers_def = {
2348 .standard = r8711_handlers,
2349 .num_standard = ARRAY_SIZE(r8711_handlers),
2350 .private = r8711_private_handler,
2351 .private_args = (struct iw_priv_args *)r8711_private_args,
2352 .num_private = ARRAY_SIZE(r8711_private_handler),
2353 .num_private_args = sizeof(r8711_private_args) /
2354 sizeof(struct iw_priv_args),
2355 .get_wireless_stats = r871x_get_wireless_stats