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",
76 * hwaddr_aton - Convert ASCII string to MAC address
77 * @txt: MAC address as a string (e.g., "00:11:22:33:44:55")
78 * @addr: Buffer for the MAC address (ETH_ALEN = 6 bytes)
79 * Returns: 0 on success, -1 on failure (e.g., string not a MAC address)
81 static int hwaddr_aton_i(const char *txt, u8 *addr)
85 for (i = 0; i < 6; i++) {
88 a = hex_to_bin(*txt++);
91 b = hex_to_bin(*txt++);
94 *addr++ = (a << 4) | b;
95 if (i < 5 && *txt++ != ':')
101 void r8712_indicate_wx_assoc_event(struct _adapter *padapter)
103 union iwreq_data wrqu;
104 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
106 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
107 memcpy(wrqu.ap_addr.sa_data, pmlmepriv->cur_network.network.MacAddress,
109 wireless_send_event(padapter->pnetdev, SIOCGIWAP, &wrqu, NULL);
112 void r8712_indicate_wx_disassoc_event(struct _adapter *padapter)
114 union iwreq_data wrqu;
116 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
117 eth_zero_addr(wrqu.ap_addr.sa_data);
118 wireless_send_event(padapter->pnetdev, SIOCGIWAP, &wrqu, NULL);
121 static inline void handle_pairwise_key(struct sta_info *psta,
122 struct ieee_param *param,
123 struct _adapter *padapter)
126 memcpy(psta->x_UncstKey.skey, param->u.crypt.key,
127 (param->u.crypt. key_len > 16 ? 16 : param->u.crypt.key_len));
128 if (strcmp(param->u.crypt.alg, "TKIP") == 0) { /* set mic key */
129 memcpy(psta->tkiptxmickey. skey, &(param->u.crypt.
131 memcpy(psta->tkiprxmickey. skey, &(param->u.crypt.
133 padapter->securitypriv. busetkipkey = false;
134 mod_timer(&padapter->securitypriv.tkip_timer,
135 jiffies + msecs_to_jiffies(50));
137 r8712_setstakey_cmd(padapter, (unsigned char *)psta, true);
140 static inline void handle_group_key(struct ieee_param *param,
141 struct _adapter *padapter)
143 if (0 < param->u.crypt.idx &&
144 param->u.crypt.idx < 3) {
145 /* group key idx is 1 or 2 */
146 memcpy(padapter->securitypriv.XGrpKey[param->u.crypt.
147 idx-1].skey, param->u.crypt.key, (param->u.crypt.key_len
148 > 16 ? 16 : param->u.crypt.key_len));
149 memcpy(padapter->securitypriv.XGrptxmickey[param->
150 u.crypt.idx-1].skey, &(param->u.crypt.key[16]), 8);
151 memcpy(padapter->securitypriv. XGrprxmickey[param->
152 u.crypt.idx-1].skey, &(param->u.crypt.key[24]), 8);
153 padapter->securitypriv.binstallGrpkey = true;
154 r8712_set_key(padapter, &padapter->securitypriv,
156 if (padapter->registrypriv.power_mgnt > PS_MODE_ACTIVE) {
157 if (padapter->registrypriv.power_mgnt != padapter->
158 pwrctrlpriv.pwr_mode)
159 mod_timer(&padapter->mlmepriv.dhcp_timer,
160 jiffies + msecs_to_jiffies(60000));
165 static inline char *translate_scan(struct _adapter *padapter,
166 struct iw_request_info *info,
167 struct wlan_network *pnetwork,
168 char *start, char *stop)
171 struct ieee80211_ht_cap *pht_capie;
174 u32 i = 0, ht_ielen = 0;
175 u16 cap, ht_cap = false, mcs_rate;
178 if ((pnetwork->network.Configuration.DSConfig < 1) ||
179 (pnetwork->network.Configuration.DSConfig > 14)) {
180 if (pnetwork->network.Configuration.DSConfig < 1)
181 pnetwork->network.Configuration.DSConfig = 1;
183 pnetwork->network.Configuration.DSConfig = 14;
187 iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
188 ether_addr_copy(iwe.u.ap_addr.sa_data, pnetwork->network.MacAddress);
189 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_ADDR_LEN);
191 iwe.cmd = SIOCGIWESSID;
192 iwe.u.data.flags = 1;
193 iwe.u.data.length = min_t(u32, pnetwork->network.Ssid.SsidLength, 32);
194 start = iwe_stream_add_point(info, start, stop, &iwe,
195 pnetwork->network.Ssid.Ssid);
196 /* parsing HT_CAP_IE */
197 p = r8712_get_ie(&pnetwork->network.IEs[12], _HT_CAPABILITY_IE_,
198 &ht_ielen, pnetwork->network.IELength - 12);
199 if (p && ht_ielen > 0) {
201 pht_capie = (struct ieee80211_ht_cap *)(p + 2);
202 memcpy(&mcs_rate, pht_capie->supp_mcs_set, 2);
204 /* Add the protocol name */
205 iwe.cmd = SIOCGIWNAME;
206 if ((r8712_is_cckratesonly_included((u8 *)&pnetwork->network.
207 SupportedRates)) == true) {
209 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bn");
211 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11b");
212 } else if ((r8712_is_cckrates_included((u8 *)&pnetwork->network.
213 SupportedRates)) == true) {
215 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bgn");
217 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bg");
220 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11gn");
222 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11g");
224 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_CHAR_LEN);
226 iwe.cmd = SIOCGIWMODE;
227 memcpy((u8 *)&cap, r8712_get_capability_from_ie(pnetwork->network.IEs),
229 cap = le16_to_cpu(cap);
230 if (cap & (WLAN_CAPABILITY_IBSS|WLAN_CAPABILITY_BSS)) {
231 if (cap & WLAN_CAPABILITY_BSS)
232 iwe.u.mode = (u32)IW_MODE_MASTER;
234 iwe.u.mode = (u32)IW_MODE_ADHOC;
235 start = iwe_stream_add_event(info, start, stop, &iwe,
238 /* Add frequency/channel */
239 iwe.cmd = SIOCGIWFREQ;
241 /* check legal index */
242 u8 dsconfig = pnetwork->network.Configuration.DSConfig;
244 if (dsconfig >= 1 && dsconfig <= sizeof(
245 ieee80211_wlan_frequencies) / sizeof(long))
246 iwe.u.freq.m = (s32)(ieee80211_wlan_frequencies[
247 pnetwork->network.Configuration.
248 DSConfig - 1] * 100000);
252 iwe.u.freq.e = (s16)1;
253 iwe.u.freq.i = (u8)pnetwork->network.Configuration.DSConfig;
254 start = iwe_stream_add_event(info, start, stop, &iwe,
256 /* Add encryption capability */
257 iwe.cmd = SIOCGIWENCODE;
258 if (cap & WLAN_CAPABILITY_PRIVACY)
259 iwe.u.data.flags = (u16)(IW_ENCODE_ENABLED |
262 iwe.u.data.flags = (u16)(IW_ENCODE_DISABLED);
263 iwe.u.data.length = (u16)0;
264 start = iwe_stream_add_point(info, start, stop, &iwe,
265 pnetwork->network.Ssid.Ssid);
266 /*Add basic and extended rates */
267 current_val = start + iwe_stream_lcp_len(info);
268 iwe.cmd = SIOCGIWRATE;
269 iwe.u.bitrate.fixed = 0;
270 iwe.u.bitrate.disabled = 0;
271 iwe.u.bitrate.value = 0;
273 while (pnetwork->network.SupportedRates[i] != 0) {
274 /* Bit rate given in 500 kb/s units */
275 iwe.u.bitrate.value = (pnetwork->network.SupportedRates[i++] &
277 current_val = iwe_stream_add_value(info, start, current_val,
278 stop, &iwe, IW_EV_PARAM_LEN);
280 /* Check if we added any event */
281 if ((current_val - start) > iwe_stream_lcp_len(info))
283 /* parsing WPA/WPA2 IE */
285 u8 buf[MAX_WPA_IE_LEN];
286 u8 wpa_ie[255], rsn_ie[255];
287 u16 wpa_len = 0, rsn_len = 0;
290 r8712_get_sec_ie(pnetwork->network.IEs,
291 pnetwork->network.IELength, rsn_ie, &rsn_len,
294 memset(buf, 0, MAX_WPA_IE_LEN);
295 n = sprintf(buf, "wpa_ie=");
296 for (i = 0; i < wpa_len; i++) {
297 n += snprintf(buf + n, MAX_WPA_IE_LEN - n,
299 if (n >= MAX_WPA_IE_LEN)
302 memset(&iwe, 0, sizeof(iwe));
303 iwe.cmd = IWEVCUSTOM;
304 iwe.u.data.length = (u16)strlen(buf);
305 start = iwe_stream_add_point(info, start, stop,
307 memset(&iwe, 0, sizeof(iwe));
309 iwe.u.data.length = (u16)wpa_len;
310 start = iwe_stream_add_point(info, start, stop,
314 memset(buf, 0, MAX_WPA_IE_LEN);
315 n = sprintf(buf, "rsn_ie=");
316 for (i = 0; i < rsn_len; i++) {
317 n += snprintf(buf + n, MAX_WPA_IE_LEN - n,
319 if (n >= MAX_WPA_IE_LEN)
322 memset(&iwe, 0, sizeof(iwe));
323 iwe.cmd = IWEVCUSTOM;
324 iwe.u.data.length = strlen(buf);
325 start = iwe_stream_add_point(info, start, stop,
327 memset(&iwe, 0, sizeof(iwe));
329 iwe.u.data.length = rsn_len;
330 start = iwe_stream_add_point(info, start, stop, &iwe,
335 { /* parsing WPS IE */
339 if (r8712_get_wps_ie(pnetwork->network.IEs,
340 pnetwork->network.IELength,
341 wps_ie, &wps_ielen) == true) {
344 iwe.u.data.length = (u16)wps_ielen;
345 start = iwe_stream_add_point(info, start, stop,
350 /* Add quality statistics */
352 rssi = r8712_signal_scale_mapping(pnetwork->network.Rssi);
353 /* we only update signal_level (signal strength) that is rssi. */
354 iwe.u.qual.updated = (u8)(IW_QUAL_QUAL_INVALID | IW_QUAL_LEVEL_UPDATED |
355 IW_QUAL_NOISE_INVALID);
356 iwe.u.qual.level = rssi; /* signal strength */
357 iwe.u.qual.qual = 0; /* signal quality */
358 iwe.u.qual.noise = 0; /* noise level */
359 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_QUAL_LEN);
360 /* how to translate rssi to ?% */
364 static int wpa_set_auth_algs(struct net_device *dev, u32 value)
366 struct _adapter *padapter = netdev_priv(dev);
369 if ((value & AUTH_ALG_SHARED_KEY) && (value & AUTH_ALG_OPEN_SYSTEM)) {
370 padapter->securitypriv.ndisencryptstatus =
371 Ndis802_11Encryption1Enabled;
372 padapter->securitypriv.ndisauthtype =
373 Ndis802_11AuthModeAutoSwitch;
374 padapter->securitypriv.AuthAlgrthm = 3;
375 } else if (value & AUTH_ALG_SHARED_KEY) {
376 padapter->securitypriv.ndisencryptstatus =
377 Ndis802_11Encryption1Enabled;
378 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeShared;
379 padapter->securitypriv.AuthAlgrthm = 1;
380 } else if (value & AUTH_ALG_OPEN_SYSTEM) {
381 if (padapter->securitypriv.ndisauthtype <
382 Ndis802_11AuthModeWPAPSK) {
383 padapter->securitypriv.ndisauthtype =
384 Ndis802_11AuthModeOpen;
385 padapter->securitypriv.AuthAlgrthm = 0;
392 static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param,
396 u32 wep_key_idx, wep_key_len = 0;
397 struct NDIS_802_11_WEP *pwep = NULL;
398 struct _adapter *padapter = netdev_priv(dev);
399 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
400 struct security_priv *psecuritypriv = &padapter->securitypriv;
402 param->u.crypt.err = 0;
403 param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
404 if (param_len != (u32)((u8 *) param->u.crypt.key - (u8 *)param) +
405 param->u.crypt.key_len)
407 if (is_broadcast_ether_addr(param->sta_addr)) {
408 if (param->u.crypt.idx >= WEP_KEYS) {
409 /* for large key indices, set the default (0) */
410 param->u.crypt.idx = 0;
414 if (strcmp(param->u.crypt.alg, "WEP") == 0) {
415 netdev_info(dev, "r8712u: %s: crypt.alg = WEP\n", __func__);
416 padapter->securitypriv.ndisencryptstatus =
417 Ndis802_11Encryption1Enabled;
418 padapter->securitypriv.PrivacyAlgrthm = _WEP40_;
419 padapter->securitypriv.XGrpPrivacy = _WEP40_;
420 wep_key_idx = param->u.crypt.idx;
421 wep_key_len = param->u.crypt.key_len;
422 if (wep_key_idx >= WEP_KEYS)
424 if (wep_key_len > 0) {
425 wep_key_len = wep_key_len <= 5 ? 5 : 13;
426 pwep = kmalloc((u32)(wep_key_len +
427 FIELD_OFFSET(struct NDIS_802_11_WEP,
428 KeyMaterial)), GFP_ATOMIC);
431 memset(pwep, 0, sizeof(struct NDIS_802_11_WEP));
432 pwep->KeyLength = wep_key_len;
433 pwep->Length = wep_key_len +
434 FIELD_OFFSET(struct NDIS_802_11_WEP,
436 if (wep_key_len == 13) {
437 padapter->securitypriv.PrivacyAlgrthm =
439 padapter->securitypriv.XGrpPrivacy =
444 pwep->KeyIndex = wep_key_idx;
445 pwep->KeyIndex |= 0x80000000;
446 memcpy(pwep->KeyMaterial, param->u.crypt.key, pwep->KeyLength);
447 if (param->u.crypt.set_tx) {
448 if (r8712_set_802_11_add_wep(padapter, pwep) ==
452 /* don't update "psecuritypriv->PrivacyAlgrthm" and
453 * "psecuritypriv->PrivacyKeyIndex=keyid", but can
454 * r8712_set_key to fw/cam
456 if (wep_key_idx >= WEP_KEYS) {
460 memcpy(&(psecuritypriv->DefKey[wep_key_idx].
461 skey[0]), pwep->KeyMaterial,
463 psecuritypriv->DefKeylen[wep_key_idx] =
465 r8712_set_key(padapter, psecuritypriv, wep_key_idx);
469 if (padapter->securitypriv.AuthAlgrthm == 2) { /* 802_1x */
470 struct sta_info *psta, *pbcmc_sta;
471 struct sta_priv *pstapriv = &padapter->stapriv;
473 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE |
474 WIFI_MP_STATE) == true) { /* sta mode */
475 psta = r8712_get_stainfo(pstapriv,
476 get_bssid(pmlmepriv));
478 psta->ieee8021x_blocked = false;
479 if ((padapter->securitypriv.ndisencryptstatus ==
480 Ndis802_11Encryption2Enabled) ||
481 (padapter->securitypriv.ndisencryptstatus ==
482 Ndis802_11Encryption3Enabled))
483 psta->XPrivacy = padapter->
484 securitypriv.PrivacyAlgrthm;
485 if (param->u.crypt.set_tx == 1)
486 handle_pairwise_key(psta, param,
489 handle_group_key(param, padapter);
491 pbcmc_sta = r8712_get_bcmc_stainfo(padapter);
493 pbcmc_sta->ieee8021x_blocked = false;
494 if ((padapter->securitypriv.ndisencryptstatus ==
495 Ndis802_11Encryption2Enabled) ||
496 (padapter->securitypriv.ndisencryptstatus ==
497 Ndis802_11Encryption3Enabled))
498 pbcmc_sta->XPrivacy =
499 padapter->securitypriv.
509 static int r871x_set_wpa_ie(struct _adapter *padapter, char *pie,
510 unsigned short ielen)
513 int group_cipher = 0, pairwise_cipher = 0;
516 if ((ielen > MAX_WPA_IE_LEN) || (pie == NULL))
519 buf = kmemdup(pie, ielen, GFP_ATOMIC);
522 if (ielen < RSN_HEADER_LEN) {
526 if (r8712_parse_wpa_ie(buf, ielen, &group_cipher,
527 &pairwise_cipher) == _SUCCESS) {
528 padapter->securitypriv.AuthAlgrthm = 2;
529 padapter->securitypriv.ndisauthtype =
530 Ndis802_11AuthModeWPAPSK;
532 if (r8712_parse_wpa2_ie(buf, ielen, &group_cipher,
533 &pairwise_cipher) == _SUCCESS) {
534 padapter->securitypriv.AuthAlgrthm = 2;
535 padapter->securitypriv.ndisauthtype =
536 Ndis802_11AuthModeWPA2PSK;
538 switch (group_cipher) {
539 case WPA_CIPHER_NONE:
540 padapter->securitypriv.XGrpPrivacy =
542 padapter->securitypriv.ndisencryptstatus =
543 Ndis802_11EncryptionDisabled;
545 case WPA_CIPHER_WEP40:
546 padapter->securitypriv.XGrpPrivacy = _WEP40_;
547 padapter->securitypriv.ndisencryptstatus =
548 Ndis802_11Encryption1Enabled;
550 case WPA_CIPHER_TKIP:
551 padapter->securitypriv.XGrpPrivacy = _TKIP_;
552 padapter->securitypriv.ndisencryptstatus =
553 Ndis802_11Encryption2Enabled;
555 case WPA_CIPHER_CCMP:
556 padapter->securitypriv.XGrpPrivacy = _AES_;
557 padapter->securitypriv.ndisencryptstatus =
558 Ndis802_11Encryption3Enabled;
560 case WPA_CIPHER_WEP104:
561 padapter->securitypriv.XGrpPrivacy = _WEP104_;
562 padapter->securitypriv.ndisencryptstatus =
563 Ndis802_11Encryption1Enabled;
566 switch (pairwise_cipher) {
567 case WPA_CIPHER_NONE:
568 padapter->securitypriv.PrivacyAlgrthm =
570 padapter->securitypriv.ndisencryptstatus =
571 Ndis802_11EncryptionDisabled;
573 case WPA_CIPHER_WEP40:
574 padapter->securitypriv.PrivacyAlgrthm = _WEP40_;
575 padapter->securitypriv.ndisencryptstatus =
576 Ndis802_11Encryption1Enabled;
578 case WPA_CIPHER_TKIP:
579 padapter->securitypriv.PrivacyAlgrthm = _TKIP_;
580 padapter->securitypriv.ndisencryptstatus =
581 Ndis802_11Encryption2Enabled;
583 case WPA_CIPHER_CCMP:
584 padapter->securitypriv.PrivacyAlgrthm = _AES_;
585 padapter->securitypriv.ndisencryptstatus =
586 Ndis802_11Encryption3Enabled;
588 case WPA_CIPHER_WEP104:
589 padapter->securitypriv.PrivacyAlgrthm = _WEP104_;
590 padapter->securitypriv.ndisencryptstatus =
591 Ndis802_11Encryption1Enabled;
594 padapter->securitypriv.wps_phase = false;
597 u8 eid, wps_oui[4] = {0x0, 0x50, 0xf2, 0x04};
599 while (cnt < ielen) {
602 if ((eid == _VENDOR_SPECIFIC_IE_) &&
603 (!memcmp(&buf[cnt+2], wps_oui, 4))) {
604 netdev_info(padapter->pnetdev, "r8712u: SET WPS_IE\n");
605 padapter->securitypriv.wps_ie_len =
607 (MAX_WPA_IE_LEN << 2)) ?
609 (MAX_WPA_IE_LEN << 2);
610 memcpy(padapter->securitypriv.wps_ie,
612 padapter->securitypriv.wps_ie_len);
613 padapter->securitypriv.wps_phase =
615 netdev_info(padapter->pnetdev, "r8712u: SET WPS_IE, wps_phase==true\n");
619 cnt += buf[cnt + 1] + 2;
628 static int r8711_wx_get_name(struct net_device *dev,
629 struct iw_request_info *info,
630 union iwreq_data *wrqu, char *extra)
632 struct _adapter *padapter = netdev_priv(dev);
636 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
637 struct ndis_wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
638 NDIS_802_11_RATES_EX *prates = NULL;
640 if (check_fwstate(pmlmepriv, _FW_LINKED|WIFI_ADHOC_MASTER_STATE) ==
642 /* parsing HT_CAP_IE */
643 p = r8712_get_ie(&pcur_bss->IEs[12], _HT_CAPABILITY_IE_,
644 &ht_ielen, pcur_bss->IELength - 12);
645 if (p && ht_ielen > 0)
647 prates = &pcur_bss->SupportedRates;
648 if (r8712_is_cckratesonly_included((u8 *)prates) == true) {
650 snprintf(wrqu->name, IFNAMSIZ,
653 snprintf(wrqu->name, IFNAMSIZ,
655 } else if ((r8712_is_cckrates_included((u8 *)prates)) == true) {
657 snprintf(wrqu->name, IFNAMSIZ,
660 snprintf(wrqu->name, IFNAMSIZ,
664 snprintf(wrqu->name, IFNAMSIZ,
667 snprintf(wrqu->name, IFNAMSIZ,
671 snprintf(wrqu->name, IFNAMSIZ, "unassociated");
675 static const long frequency_list[] = {
676 2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447, 2452, 2457, 2462,
677 2467, 2472, 2484, 4915, 4920, 4925, 4935, 4940, 4945, 4960, 4980,
678 5035, 5040, 5045, 5055, 5060, 5080, 5170, 5180, 5190, 5200, 5210,
679 5220, 5230, 5240, 5260, 5280, 5300, 5320, 5500, 5520, 5540, 5560,
680 5580, 5600, 5620, 5640, 5660, 5680, 5700, 5745, 5765, 5785, 5805,
684 static int r8711_wx_set_freq(struct net_device *dev,
685 struct iw_request_info *info,
686 union iwreq_data *wrqu, char *extra)
688 struct _adapter *padapter = netdev_priv(dev);
689 struct iw_freq *fwrq = &wrqu->freq;
692 /* If setting by frequency, convert to a channel */
693 if ((fwrq->e == 1) &&
694 (fwrq->m >= (int) 2.412e8) &&
695 (fwrq->m <= (int) 2.487e8)) {
696 int f = fwrq->m / 100000;
699 while ((c < 14) && (f != frequency_list[c]))
704 /* Setting by channel number */
705 if ((fwrq->m > 14) || (fwrq->e > 0))
708 int channel = fwrq->m;
710 if ((channel < 1) || (channel > 14))
713 /* Yes ! We can set it !!! */
714 padapter->registrypriv.channel = channel;
720 static int r8711_wx_get_freq(struct net_device *dev,
721 struct iw_request_info *info,
722 union iwreq_data *wrqu, char *extra)
724 struct _adapter *padapter = netdev_priv(dev);
725 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
726 struct ndis_wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
728 if (check_fwstate(pmlmepriv, _FW_LINKED) == true) {
729 wrqu->freq.m = ieee80211_wlan_frequencies[
730 pcur_bss->Configuration.DSConfig-1] * 100000;
732 wrqu->freq.i = pcur_bss->Configuration.DSConfig;
739 static int r8711_wx_set_mode(struct net_device *dev,
740 struct iw_request_info *a,
741 union iwreq_data *wrqu, char *b)
743 struct _adapter *padapter = netdev_priv(dev);
744 enum NDIS_802_11_NETWORK_INFRASTRUCTURE networkType;
746 switch (wrqu->mode) {
748 networkType = Ndis802_11AutoUnknown;
751 networkType = Ndis802_11IBSS;
754 networkType = Ndis802_11APMode;
757 networkType = Ndis802_11Infrastructure;
762 if (Ndis802_11APMode == networkType)
763 r8712_setopmode_cmd(padapter, networkType);
765 r8712_setopmode_cmd(padapter, Ndis802_11AutoUnknown);
767 r8712_set_802_11_infrastructure_mode(padapter, networkType);
771 static int r8711_wx_get_mode(struct net_device *dev, struct iw_request_info *a,
772 union iwreq_data *wrqu, char *b)
774 struct _adapter *padapter = netdev_priv(dev);
775 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
777 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == true)
778 wrqu->mode = IW_MODE_INFRA;
779 else if (check_fwstate(pmlmepriv,
780 WIFI_ADHOC_MASTER_STATE|WIFI_ADHOC_STATE) == true)
781 wrqu->mode = IW_MODE_ADHOC;
782 else if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == true)
783 wrqu->mode = IW_MODE_MASTER;
785 wrqu->mode = IW_MODE_AUTO;
789 static int r871x_wx_set_pmkid(struct net_device *dev,
790 struct iw_request_info *a,
791 union iwreq_data *wrqu, char *extra)
793 struct _adapter *padapter = netdev_priv(dev);
794 struct security_priv *psecuritypriv = &padapter->securitypriv;
795 struct iw_pmksa *pPMK = (struct iw_pmksa *) extra;
796 u8 strZeroMacAddress[ETH_ALEN] = {0x00};
797 u8 strIssueBssid[ETH_ALEN] = {0x00};
798 u8 j, blInserted = false;
799 int intReturn = false;
802 There are the BSSID information in the bssid.sa_data array.
803 If cmd is IW_PMKSA_FLUSH, it means the wpa_supplicant wants to clear
804 all the PMKID information. If cmd is IW_PMKSA_ADD, it means the
805 wpa_supplicant wants to add a PMKID/BSSID to driver.
806 If cmd is IW_PMKSA_REMOVE, it means the wpa_supplicant wants to
807 remove a PMKID/BSSID from driver.
811 memcpy(strIssueBssid, pPMK->bssid.sa_data, ETH_ALEN);
814 if (!memcmp(strIssueBssid, strZeroMacAddress, ETH_ALEN))
818 /* overwrite PMKID */
819 for (j = 0; j < NUM_PMKID_CACHE; j++) {
820 if (!memcmp(psecuritypriv->PMKIDList[j].Bssid,
821 strIssueBssid, ETH_ALEN)) {
822 /* BSSID is matched, the same AP => rewrite
824 netdev_info(dev, "r8712u: %s: BSSID exists in the PMKList.\n",
826 memcpy(psecuritypriv->PMKIDList[j].PMKID,
827 pPMK->pmkid, IW_PMKID_LEN);
828 psecuritypriv->PMKIDList[j].bUsed = true;
829 psecuritypriv->PMKIDIndex = j + 1;
835 /* Find a new entry */
836 netdev_info(dev, "r8712u: %s: Use the new entry index = %d for this PMKID.\n",
837 __func__, psecuritypriv->PMKIDIndex);
838 memcpy(psecuritypriv->PMKIDList[psecuritypriv->
839 PMKIDIndex].Bssid, strIssueBssid, ETH_ALEN);
840 memcpy(psecuritypriv->PMKIDList[psecuritypriv->
841 PMKIDIndex].PMKID, pPMK->pmkid, IW_PMKID_LEN);
842 psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].
844 psecuritypriv->PMKIDIndex++;
845 if (psecuritypriv->PMKIDIndex == NUM_PMKID_CACHE)
846 psecuritypriv->PMKIDIndex = 0;
849 case IW_PMKSA_REMOVE:
851 for (j = 0; j < NUM_PMKID_CACHE; j++) {
852 if (!memcmp(psecuritypriv->PMKIDList[j].Bssid,
853 strIssueBssid, ETH_ALEN)) {
854 /* BSSID is matched, the same AP => Remove
855 * this PMKID information and reset it. */
856 eth_zero_addr(psecuritypriv->PMKIDList[j].Bssid);
857 psecuritypriv->PMKIDList[j].bUsed = false;
863 memset(psecuritypriv->PMKIDList, 0,
864 sizeof(struct RT_PMKID_LIST) * NUM_PMKID_CACHE);
865 psecuritypriv->PMKIDIndex = 0;
869 netdev_info(dev, "r8712u: %s: unknown Command\n", __func__);
876 static int r8711_wx_get_sens(struct net_device *dev,
877 struct iw_request_info *info,
878 union iwreq_data *wrqu, char *extra)
880 wrqu->sens.value = 0;
881 wrqu->sens.fixed = 0; /* no auto select */
882 wrqu->sens.disabled = 1;
886 static int r8711_wx_get_range(struct net_device *dev,
887 struct iw_request_info *info,
888 union iwreq_data *wrqu, char *extra)
890 struct iw_range *range = (struct iw_range *)extra;
894 wrqu->data.length = sizeof(*range);
895 memset(range, 0, sizeof(*range));
896 /* Let's try to keep this struct in the same order as in
897 * linux/include/wireless.h
900 /* TODO: See what values we can set, and remove the ones we can't
901 * set, or fill them with some default data.
903 /* ~5 Mb/s real (802.11b) */
904 range->throughput = 5 * 1000 * 1000;
905 /* TODO: 8711 sensitivity ? */
906 /* signal level threshold range */
907 /* percent values between 0 and 100. */
908 range->max_qual.qual = 100;
909 range->max_qual.level = 100;
910 range->max_qual.noise = 100;
911 range->max_qual.updated = 7; /* Updated all three */
912 range->avg_qual.qual = 92; /* > 8% missed beacons is 'bad' */
913 /* TODO: Find real 'good' to 'bad' threshold value for RSSI */
914 range->avg_qual.level = 20 + -98;
915 range->avg_qual.noise = 0;
916 range->avg_qual.updated = 7; /* Updated all three */
917 range->num_bitrates = RATE_COUNT;
918 for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++)
919 range->bitrate[i] = rtl8180_rates[i];
920 range->min_frag = MIN_FRAG_THRESHOLD;
921 range->max_frag = MAX_FRAG_THRESHOLD;
923 range->we_version_compiled = WIRELESS_EXT;
924 range->we_version_source = 16;
925 range->num_channels = 14;
926 for (i = 0, val = 0; i < 14; i++) {
927 /* Include only legal frequencies for some countries */
928 range->freq[val].i = i + 1;
929 range->freq[val].m = ieee80211_wlan_frequencies[i] * 100000;
930 range->freq[val].e = 1;
932 if (val == IW_MAX_FREQUENCIES)
935 range->num_frequency = val;
936 range->enc_capa = IW_ENC_CAPA_WPA |
938 IW_ENC_CAPA_CIPHER_TKIP |
939 IW_ENC_CAPA_CIPHER_CCMP;
943 static int r8711_wx_get_rate(struct net_device *dev,
944 struct iw_request_info *info,
945 union iwreq_data *wrqu, char *extra);
947 static int r871x_wx_set_priv(struct net_device *dev,
948 struct iw_request_info *info,
949 union iwreq_data *awrq,
952 int ret = 0, len = 0;
954 struct _adapter *padapter = netdev_priv(dev);
955 struct iw_point *dwrq = (struct iw_point *)awrq;
958 ext = memdup_user(dwrq->pointer, len);
962 if (0 == strcasecmp(ext, "RSSI")) {
963 /*Return received signal strength indicator in -db for */
966 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
967 struct wlan_network *pcur_network = &pmlmepriv->cur_network;
969 if (check_fwstate(pmlmepriv, _FW_LINKED) == true) {
970 sprintf(ext, "%s rssi %d",
971 pcur_network->network.Ssid.Ssid,
973 ((padapter->recvpriv.fw_rssi)>>1)-95
974 /*pcur_network->network.Rssi */
979 } else if (0 == strcasecmp(ext, "LINKSPEED")) {
980 /*Return link speed in MBPS */
982 union iwreq_data wrqd;
986 ret_inner = r8711_wx_get_rate(dev, info, &wrqd, extra);
990 mbps = wrqd.bitrate.value / 1000000;
991 sprintf(ext, "LINKSPEED %d", mbps);
992 } else if (0 == strcasecmp(ext, "MACADDR")) {
993 /*Return mac address of the station */
994 /* Macaddr = xx:xx:xx:xx:xx:xx */
995 sprintf(ext, "MACADDR = %pM", dev->dev_addr);
996 } else if (0 == strcasecmp(ext, "SCAN-ACTIVE")) {
997 /*Set scan type to active */
998 /*OK if successful */
999 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1001 pmlmepriv->passive_mode = 1;
1003 } else if (0 == strcasecmp(ext, "SCAN-PASSIVE")) {
1004 /*Set scan type to passive */
1005 /*OK if successful */
1006 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1008 pmlmepriv->passive_mode = 0;
1010 } else if (0 == strncmp(ext, "DCE-E", 5)) {
1011 /*Set scan type to passive */
1012 /*OK if successful */
1013 r8712_disconnectCtrlEx_cmd(padapter
1014 , 1 /*u32 enableDrvCtrl */
1015 , 5 /*u32 tryPktCnt */
1016 , 100 /*u32 tryPktInterval */
1017 , 5000 /*u32 firstStageTO */
1020 } else if (0 == strncmp(ext, "DCE-D", 5)) {
1021 /*Set scan type to passive */
1022 /*OK if successfu */
1023 r8712_disconnectCtrlEx_cmd(padapter
1024 , 0 /*u32 enableDrvCtrl */
1025 , 5 /*u32 tryPktCnt */
1026 , 100 /*u32 tryPktInterval */
1027 , 5000 /*u32 firstStageTO */
1031 netdev_info(dev, "r8712u: %s: unknown Command %s.\n",
1035 if (copy_to_user(dwrq->pointer, ext,
1036 min(dwrq->length, (__u16)(strlen(ext)+1))))
1045 * s1. set_802_11_infrastructure_mode()
1046 * s2. set_802_11_authentication_mode()
1047 * s3. set_802_11_encryption_mode()
1048 * s4. set_802_11_bssid()
1050 * This function intends to handle the Set AP command, which specifies the
1051 * MAC# of a preferred Access Point.
1052 * Currently, the request comes via Wireless Extensions' SIOCSIWAP ioctl.
1054 * For this operation to succeed, there is no need for the interface to be up.
1057 static int r8711_wx_set_wap(struct net_device *dev,
1058 struct iw_request_info *info,
1059 union iwreq_data *awrq,
1062 int ret = -EINPROGRESS;
1063 struct _adapter *padapter = netdev_priv(dev);
1064 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1065 struct __queue *queue = &pmlmepriv->scanned_queue;
1066 struct sockaddr *temp = (struct sockaddr *)awrq;
1068 struct list_head *phead;
1070 struct wlan_network *pnetwork = NULL;
1071 enum NDIS_802_11_AUTHENTICATION_MODE authmode;
1073 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == true)
1075 if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == true)
1077 if (temp->sa_family != ARPHRD_ETHER)
1079 authmode = padapter->securitypriv.ndisauthtype;
1080 spin_lock_irqsave(&queue->lock, irqL);
1081 phead = &queue->queue;
1082 pmlmepriv->pscanned = phead->next;
1084 if (end_of_queue_search(phead, pmlmepriv->pscanned) == true)
1086 pnetwork = LIST_CONTAINOR(pmlmepriv->pscanned,
1087 struct wlan_network, list);
1088 pmlmepriv->pscanned = pmlmepriv->pscanned->next;
1089 dst_bssid = pnetwork->network.MacAddress;
1090 if (!memcmp(dst_bssid, temp->sa_data, ETH_ALEN)) {
1091 r8712_set_802_11_infrastructure_mode(padapter,
1092 pnetwork->network.InfrastructureMode);
1096 spin_unlock_irqrestore(&queue->lock, irqL);
1098 if (!r8712_set_802_11_authentication_mode(padapter, authmode))
1101 if (!r8712_set_802_11_bssid(padapter, temp->sa_data))
1108 static int r8711_wx_get_wap(struct net_device *dev,
1109 struct iw_request_info *info,
1110 union iwreq_data *wrqu, char *extra)
1112 struct _adapter *padapter = netdev_priv(dev);
1113 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1114 struct ndis_wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
1116 wrqu->ap_addr.sa_family = ARPHRD_ETHER;
1117 if (check_fwstate(pmlmepriv, _FW_LINKED | WIFI_ADHOC_MASTER_STATE |
1119 ether_addr_copy(wrqu->ap_addr.sa_data, pcur_bss->MacAddress);
1121 eth_zero_addr(wrqu->ap_addr.sa_data);
1125 static int r871x_wx_set_mlme(struct net_device *dev,
1126 struct iw_request_info *info,
1127 union iwreq_data *wrqu, char *extra)
1130 struct _adapter *padapter = netdev_priv(dev);
1131 struct iw_mlme *mlme = (struct iw_mlme *) extra;
1135 switch (mlme->cmd) {
1136 case IW_MLME_DEAUTH:
1137 if (!r8712_set_802_11_disassociate(padapter))
1140 case IW_MLME_DISASSOC:
1141 if (!r8712_set_802_11_disassociate(padapter))
1152 * This function intends to handle the Set Scan command.
1153 * Currently, the request comes via Wireless Extensions' SIOCSIWSCAN ioctl.
1155 * For this operation to succeed, the interface is brought Up beforehand.
1158 static int r8711_wx_set_scan(struct net_device *dev,
1159 struct iw_request_info *a,
1160 union iwreq_data *wrqu, char *extra)
1162 struct _adapter *padapter = netdev_priv(dev);
1163 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1166 if (padapter->bDriverStopped == true) {
1167 netdev_info(dev, "In %s: bDriverStopped=%d\n",
1168 __func__, padapter->bDriverStopped);
1171 if (padapter->bup == false)
1173 if (padapter->hw_init_completed == false)
1175 if ((check_fwstate(pmlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING)) ||
1176 (pmlmepriv->sitesurveyctrl.traffic_busy == true))
1178 if (wrqu->data.length == sizeof(struct iw_scan_req)) {
1179 struct iw_scan_req *req = (struct iw_scan_req *)extra;
1181 if (wrqu->data.flags & IW_SCAN_THIS_ESSID) {
1182 struct ndis_802_11_ssid ssid;
1184 u32 len = min_t(u8, req->essid_len, IW_ESSID_MAX_SIZE);
1186 memset((unsigned char *)&ssid, 0,
1187 sizeof(struct ndis_802_11_ssid));
1188 memcpy(ssid.Ssid, req->essid, len);
1189 ssid.SsidLength = len;
1190 spin_lock_irqsave(&pmlmepriv->lock, irqL);
1191 if ((check_fwstate(pmlmepriv, _FW_UNDER_SURVEY |
1192 _FW_UNDER_LINKING)) ||
1193 (pmlmepriv->sitesurveyctrl.traffic_busy == true)) {
1194 if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING))
1197 status = r8712_sitesurvey_cmd(padapter, &ssid);
1198 spin_unlock_irqrestore(&pmlmepriv->lock, irqL);
1201 status = r8712_set_802_11_bssid_list_scan(padapter);
1202 if (status == false)
1207 static int r8711_wx_get_scan(struct net_device *dev,
1208 struct iw_request_info *a,
1209 union iwreq_data *wrqu, char *extra)
1211 struct _adapter *padapter = netdev_priv(dev);
1212 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1213 struct __queue *queue = &pmlmepriv->scanned_queue;
1214 struct wlan_network *pnetwork = NULL;
1216 struct list_head *plist, *phead;
1218 char *stop = ev + wrqu->data.length;
1219 u32 ret = 0, cnt = 0;
1221 if (padapter->bDriverStopped)
1223 while (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING)) {
1229 spin_lock_irqsave(&queue->lock, irqL);
1230 phead = &queue->queue;
1231 plist = phead->next;
1233 if (end_of_queue_search(phead, plist) == true)
1235 if ((stop - ev) < SCAN_ITEM_SIZE) {
1239 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
1240 ev = translate_scan(padapter, a, pnetwork, ev, stop);
1241 plist = plist->next;
1243 spin_unlock_irqrestore(&queue->lock, irqL);
1244 wrqu->data.length = ev - extra;
1245 wrqu->data.flags = 0;
1250 * s1. set_802_11_infrastructure_mode()
1251 * s2. set_802_11_authenticaion_mode()
1252 * s3. set_802_11_encryption_mode()
1253 * s4. set_802_11_ssid()
1255 * This function intends to handle the Set ESSID command.
1256 * Currently, the request comes via the Wireless Extensions' SIOCSIWESSID ioctl.
1258 * For this operation to succeed, there is no need for the interface to be Up.
1261 static int r8711_wx_set_essid(struct net_device *dev,
1262 struct iw_request_info *a,
1263 union iwreq_data *wrqu, char *extra)
1265 struct _adapter *padapter = netdev_priv(dev);
1266 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1267 struct __queue *queue = &pmlmepriv->scanned_queue;
1268 struct wlan_network *pnetwork = NULL;
1269 enum NDIS_802_11_AUTHENTICATION_MODE authmode;
1270 struct ndis_802_11_ssid ndis_ssid;
1271 u8 *dst_ssid, *src_ssid;
1272 struct list_head *phead;
1275 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY))
1277 if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING))
1279 if (wrqu->essid.length > IW_ESSID_MAX_SIZE)
1281 authmode = padapter->securitypriv.ndisauthtype;
1282 if (wrqu->essid.flags && wrqu->essid.length) {
1283 len = (wrqu->essid.length < IW_ESSID_MAX_SIZE) ?
1284 wrqu->essid.length : IW_ESSID_MAX_SIZE;
1285 memset(&ndis_ssid, 0, sizeof(struct ndis_802_11_ssid));
1286 ndis_ssid.SsidLength = len;
1287 memcpy(ndis_ssid.Ssid, extra, len);
1288 src_ssid = ndis_ssid.Ssid;
1289 phead = &queue->queue;
1290 pmlmepriv->pscanned = phead->next;
1292 if (end_of_queue_search(phead, pmlmepriv->pscanned))
1294 pnetwork = LIST_CONTAINOR(pmlmepriv->pscanned,
1295 struct wlan_network, list);
1296 pmlmepriv->pscanned = pmlmepriv->pscanned->next;
1297 dst_ssid = pnetwork->network.Ssid.Ssid;
1298 if ((!memcmp(dst_ssid, src_ssid, ndis_ssid.SsidLength))
1299 && (pnetwork->network.Ssid.SsidLength ==
1300 ndis_ssid.SsidLength)) {
1301 if (check_fwstate(pmlmepriv,
1302 WIFI_ADHOC_STATE)) {
1303 if (pnetwork->network.
1307 cur_network.network.
1312 r8712_set_802_11_infrastructure_mode(
1314 pnetwork->network.InfrastructureMode);
1318 r8712_set_802_11_authentication_mode(padapter, authmode);
1319 r8712_set_802_11_ssid(padapter, &ndis_ssid);
1321 return -EINPROGRESS;
1324 static int r8711_wx_get_essid(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 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1330 struct ndis_wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
1333 if (check_fwstate(pmlmepriv, _FW_LINKED|WIFI_ADHOC_MASTER_STATE)) {
1334 len = pcur_bss->Ssid.SsidLength;
1335 wrqu->essid.length = len;
1336 memcpy(extra, pcur_bss->Ssid.Ssid, len);
1337 wrqu->essid.flags = 1;
1344 static int r8711_wx_set_rate(struct net_device *dev,
1345 struct iw_request_info *a,
1346 union iwreq_data *wrqu, char *extra)
1348 struct _adapter *padapter = netdev_priv(dev);
1349 u32 target_rate = wrqu->bitrate.value;
1350 u32 fixed = wrqu->bitrate.fixed;
1352 u8 datarates[NumRates];
1353 u8 mpdatarate[NumRates] = {11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0xff};
1356 if (target_rate == -1) {
1360 target_rate = target_rate / 100000;
1361 switch (target_rate) {
1403 for (i = 0; i < NumRates; i++) {
1404 if (ratevalue == mpdatarate[i]) {
1405 datarates[i] = mpdatarate[i];
1409 datarates[i] = 0xff;
1411 if (r8712_setdatarate_cmd(padapter, datarates) != _SUCCESS)
1416 static int r8711_wx_get_rate(struct net_device *dev,
1417 struct iw_request_info *info,
1418 union iwreq_data *wrqu, char *extra)
1420 struct _adapter *padapter = netdev_priv(dev);
1421 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1422 struct ndis_wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
1423 struct ieee80211_ht_cap *pht_capie;
1424 unsigned char rf_type = padapter->registrypriv.rf_config;
1427 u16 rate, max_rate = 0, ht_cap = false;
1429 u8 bw_40MHz = 0, short_GI = 0;
1433 if (check_fwstate(pmlmepriv, _FW_LINKED|WIFI_ADHOC_MASTER_STATE)) {
1434 p = r8712_get_ie(&pcur_bss->IEs[12],
1435 _HT_CAPABILITY_IE_, &ht_ielen,
1436 pcur_bss->IELength - 12);
1437 if (p && ht_ielen > 0) {
1439 pht_capie = (struct ieee80211_ht_cap *)(p + 2);
1440 memcpy(&mcs_rate, pht_capie->supp_mcs_set, 2);
1441 bw_40MHz = (pht_capie->cap_info &
1442 IEEE80211_HT_CAP_SUP_WIDTH) ? 1 : 0;
1443 short_GI = (pht_capie->cap_info &
1444 (IEEE80211_HT_CAP_SGI_20 |
1445 IEEE80211_HT_CAP_SGI_40)) ? 1 : 0;
1447 while ((pcur_bss->SupportedRates[i] != 0) &&
1448 (pcur_bss->SupportedRates[i] != 0xFF)) {
1449 rate = pcur_bss->SupportedRates[i] & 0x7F;
1450 if (rate > max_rate)
1452 wrqu->bitrate.fixed = 0; /* no auto select */
1453 wrqu->bitrate.value = rate*500000;
1456 if (ht_cap == true) {
1457 if (mcs_rate & 0x8000 /* MCS15 */
1459 RTL8712_RF_2T2R == rf_type)
1460 max_rate = (bw_40MHz) ? ((short_GI) ? 300 :
1461 270) : ((short_GI) ? 144 : 130);
1462 else /* default MCS7 */
1463 max_rate = (bw_40MHz) ? ((short_GI) ? 150 :
1464 135) : ((short_GI) ? 72 : 65);
1465 max_rate *= 2; /* Mbps/2 */
1467 wrqu->bitrate.value = max_rate * 500000;
1473 static int r8711_wx_get_rts(struct net_device *dev,
1474 struct iw_request_info *info,
1475 union iwreq_data *wrqu, char *extra)
1477 struct _adapter *padapter = netdev_priv(dev);
1479 wrqu->rts.value = padapter->registrypriv.rts_thresh;
1480 wrqu->rts.fixed = 0; /* no auto select */
1484 static int r8711_wx_set_frag(struct net_device *dev,
1485 struct iw_request_info *info,
1486 union iwreq_data *wrqu, char *extra)
1488 struct _adapter *padapter = netdev_priv(dev);
1490 if (wrqu->frag.disabled)
1491 padapter->xmitpriv.frag_len = MAX_FRAG_THRESHOLD;
1493 if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
1494 wrqu->frag.value > MAX_FRAG_THRESHOLD)
1496 padapter->xmitpriv.frag_len = wrqu->frag.value & ~0x1;
1501 static int r8711_wx_get_frag(struct net_device *dev,
1502 struct iw_request_info *info,
1503 union iwreq_data *wrqu, char *extra)
1505 struct _adapter *padapter = netdev_priv(dev);
1507 wrqu->frag.value = padapter->xmitpriv.frag_len;
1508 wrqu->frag.fixed = 0; /* no auto select */
1512 static int r8711_wx_get_retry(struct net_device *dev,
1513 struct iw_request_info *info,
1514 union iwreq_data *wrqu, char *extra)
1516 wrqu->retry.value = 7;
1517 wrqu->retry.fixed = 0; /* no auto select */
1518 wrqu->retry.disabled = 1;
1522 static int r8711_wx_set_enc(struct net_device *dev,
1523 struct iw_request_info *info,
1524 union iwreq_data *wrqu, char *keybuf)
1527 u32 keyindex_provided;
1528 struct NDIS_802_11_WEP wep;
1529 enum NDIS_802_11_AUTHENTICATION_MODE authmode;
1530 struct iw_point *erq = &(wrqu->encoding);
1531 struct _adapter *padapter = netdev_priv(dev);
1533 key = erq->flags & IW_ENCODE_INDEX;
1534 memset(&wep, 0, sizeof(struct NDIS_802_11_WEP));
1535 if (erq->flags & IW_ENCODE_DISABLED) {
1536 netdev_info(dev, "r8712u: %s: EncryptionDisabled\n", __func__);
1537 padapter->securitypriv.ndisencryptstatus =
1538 Ndis802_11EncryptionDisabled;
1539 padapter->securitypriv.PrivacyAlgrthm = _NO_PRIVACY_;
1540 padapter->securitypriv.XGrpPrivacy = _NO_PRIVACY_;
1541 padapter->securitypriv.AuthAlgrthm = 0; /* open system */
1542 authmode = Ndis802_11AuthModeOpen;
1543 padapter->securitypriv.ndisauthtype = authmode;
1550 keyindex_provided = 1;
1552 keyindex_provided = 0;
1553 key = padapter->securitypriv.PrivacyKeyIndex;
1555 /* set authentication mode */
1556 if (erq->flags & IW_ENCODE_OPEN) {
1557 netdev_info(dev, "r8712u: %s: IW_ENCODE_OPEN\n", __func__);
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;
1565 } else if (erq->flags & IW_ENCODE_RESTRICTED) {
1567 "r8712u: %s: IW_ENCODE_RESTRICTED\n", __func__);
1568 padapter->securitypriv.ndisencryptstatus =
1569 Ndis802_11Encryption1Enabled;
1570 padapter->securitypriv.AuthAlgrthm = 1; /* shared system */
1571 padapter->securitypriv.PrivacyAlgrthm = _WEP40_;
1572 padapter->securitypriv.XGrpPrivacy = _WEP40_;
1573 authmode = Ndis802_11AuthModeShared;
1574 padapter->securitypriv.ndisauthtype = authmode;
1576 padapter->securitypriv.ndisencryptstatus =
1577 Ndis802_11Encryption1Enabled;
1578 padapter->securitypriv.AuthAlgrthm = 0; /* open system */
1579 padapter->securitypriv.PrivacyAlgrthm = _NO_PRIVACY_;
1580 padapter->securitypriv.XGrpPrivacy = _NO_PRIVACY_;
1581 authmode = Ndis802_11AuthModeOpen;
1582 padapter->securitypriv.ndisauthtype = authmode;
1585 if (erq->length > 0) {
1586 wep.KeyLength = erq->length <= 5 ? 5 : 13;
1587 wep.Length = wep.KeyLength +
1588 FIELD_OFFSET(struct NDIS_802_11_WEP, KeyMaterial);
1591 if (keyindex_provided == 1) { /* set key_id only, no given
1592 * KeyMaterial(erq->length==0).*/
1593 padapter->securitypriv.PrivacyKeyIndex = key;
1594 switch (padapter->securitypriv.DefKeylen[key]) {
1596 padapter->securitypriv.PrivacyAlgrthm =
1600 padapter->securitypriv.PrivacyAlgrthm =
1604 padapter->securitypriv.PrivacyAlgrthm =
1611 wep.KeyIndex |= 0x80000000; /* transmit key */
1612 memcpy(wep.KeyMaterial, keybuf, wep.KeyLength);
1613 if (r8712_set_802_11_add_wep(padapter, &wep) == _FAIL)
1618 static int r8711_wx_get_enc(struct net_device *dev,
1619 struct iw_request_info *info,
1620 union iwreq_data *wrqu, char *keybuf)
1623 struct _adapter *padapter = netdev_priv(dev);
1624 struct iw_point *erq = &(wrqu->encoding);
1625 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1627 if (check_fwstate(pmlmepriv, _FW_LINKED) == false) {
1628 if (!check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) {
1630 erq->flags |= IW_ENCODE_DISABLED;
1634 key = erq->flags & IW_ENCODE_INDEX;
1640 key = padapter->securitypriv.PrivacyKeyIndex;
1642 erq->flags = key + 1;
1643 switch (padapter->securitypriv.ndisencryptstatus) {
1644 case Ndis802_11EncryptionNotSupported:
1645 case Ndis802_11EncryptionDisabled:
1647 erq->flags |= IW_ENCODE_DISABLED;
1649 case Ndis802_11Encryption1Enabled:
1650 erq->length = padapter->securitypriv.DefKeylen[key];
1652 memcpy(keybuf, padapter->securitypriv.DefKey[
1653 key].skey, padapter->securitypriv.
1655 erq->flags |= IW_ENCODE_ENABLED;
1656 if (padapter->securitypriv.ndisauthtype ==
1657 Ndis802_11AuthModeOpen)
1658 erq->flags |= IW_ENCODE_OPEN;
1659 else if (padapter->securitypriv.ndisauthtype ==
1660 Ndis802_11AuthModeShared)
1661 erq->flags |= IW_ENCODE_RESTRICTED;
1664 erq->flags |= IW_ENCODE_DISABLED;
1667 case Ndis802_11Encryption2Enabled:
1668 case Ndis802_11Encryption3Enabled:
1670 erq->flags |= (IW_ENCODE_ENABLED | IW_ENCODE_OPEN |
1675 erq->flags |= IW_ENCODE_DISABLED;
1681 static int r8711_wx_get_power(struct net_device *dev,
1682 struct iw_request_info *info,
1683 union iwreq_data *wrqu, char *extra)
1685 wrqu->power.value = 0;
1686 wrqu->power.fixed = 0; /* no auto select */
1687 wrqu->power.disabled = 1;
1691 static int r871x_wx_set_gen_ie(struct net_device *dev,
1692 struct iw_request_info *info,
1693 union iwreq_data *wrqu, char *extra)
1695 struct _adapter *padapter = netdev_priv(dev);
1697 return r871x_set_wpa_ie(padapter, extra, wrqu->data.length);
1700 static int r871x_wx_set_auth(struct net_device *dev,
1701 struct iw_request_info *info,
1702 union iwreq_data *wrqu, char *extra)
1704 struct _adapter *padapter = netdev_priv(dev);
1705 struct iw_param *param = (struct iw_param *)&(wrqu->param);
1710 paramid = param->flags & IW_AUTH_INDEX;
1711 paramval = param->value;
1713 case IW_AUTH_WPA_VERSION:
1715 case IW_AUTH_CIPHER_PAIRWISE:
1717 case IW_AUTH_CIPHER_GROUP:
1719 case IW_AUTH_KEY_MGMT:
1721 * ??? does not use these parameters
1724 case IW_AUTH_TKIP_COUNTERMEASURES:
1726 /* wpa_supplicant is enabling tkip countermeasure. */
1727 padapter->securitypriv.btkip_countermeasure = true;
1729 /* wpa_supplicant is disabling tkip countermeasure. */
1730 padapter->securitypriv.btkip_countermeasure = false;
1733 case IW_AUTH_DROP_UNENCRYPTED:
1736 * wpa_supplicant calls set_wpa_enabled when the driver
1737 * is loaded and unloaded, regardless of if WPA is being
1738 * used. No other calls are made which can be used to
1739 * determine if encryption will be used or not prior to
1740 * association being expected. If encryption is not being
1741 * used, drop_unencrypted is set to false, else true -- we
1742 * can use this to determine if the CAP_PRIVACY_ON bit should
1745 if (padapter->securitypriv.ndisencryptstatus ==
1746 Ndis802_11Encryption1Enabled) {
1747 /* it means init value, or using wep,
1748 * ndisencryptstatus =
1749 * Ndis802_11Encryption1Enabled,
1750 * then it needn't reset it;
1756 padapter->securitypriv.ndisencryptstatus =
1757 Ndis802_11EncryptionDisabled;
1758 padapter->securitypriv.PrivacyAlgrthm =
1760 padapter->securitypriv.XGrpPrivacy =
1762 padapter->securitypriv.AuthAlgrthm = 0;
1763 padapter->securitypriv.ndisauthtype =
1764 Ndis802_11AuthModeOpen;
1767 case IW_AUTH_80211_AUTH_ALG:
1768 ret = wpa_set_auth_algs(dev, (u32)paramval);
1770 case IW_AUTH_WPA_ENABLED:
1772 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
1774 case IW_AUTH_PRIVACY_INVOKED:
1783 static int r871x_wx_set_enc_ext(struct net_device *dev,
1784 struct iw_request_info *info,
1785 union iwreq_data *wrqu, char *extra)
1787 struct iw_point *pencoding = &wrqu->encoding;
1788 struct iw_encode_ext *pext = (struct iw_encode_ext *)extra;
1789 struct ieee_param *param = NULL;
1794 switch (pext->alg) {
1795 case IW_ENCODE_ALG_NONE:
1798 case IW_ENCODE_ALG_WEP:
1801 case IW_ENCODE_ALG_TKIP:
1804 case IW_ENCODE_ALG_CCMP:
1811 param_len = sizeof(struct ieee_param) + pext->key_len;
1812 param = kzalloc(param_len, GFP_ATOMIC);
1815 param->cmd = IEEE_CMD_SET_ENCRYPTION;
1816 memset(param->sta_addr, 0xff, ETH_ALEN);
1818 strncpy((char *)param->u.crypt.alg, alg_name, IEEE_CRYPT_ALG_NAME_LEN);
1819 if (pext->ext_flags & IW_ENCODE_EXT_GROUP_KEY)
1820 param->u.crypt.set_tx = 0;
1821 if (pext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
1822 param->u.crypt.set_tx = 1;
1823 param->u.crypt.idx = (pencoding->flags & 0x00FF) - 1;
1824 if (pext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID)
1825 memcpy(param->u.crypt.seq, pext->rx_seq, 8);
1826 if (pext->key_len) {
1827 param->u.crypt.key_len = pext->key_len;
1828 memcpy(param + 1, pext + 1, pext->key_len);
1830 ret = wpa_set_encryption(dev, param, param_len);
1835 static int r871x_wx_get_nick(struct net_device *dev,
1836 struct iw_request_info *info,
1837 union iwreq_data *wrqu, char *extra)
1840 wrqu->data.length = 8;
1841 wrqu->data.flags = 1;
1842 memcpy(extra, "rtl_wifi", 8);
1847 static int r8711_wx_read32(struct net_device *dev,
1848 struct iw_request_info *info,
1849 union iwreq_data *wrqu, char *keybuf)
1851 struct _adapter *padapter = netdev_priv(dev);
1855 get_user(addr, (u32 __user *)wrqu->data.pointer);
1856 data32 = r8712_read32(padapter, addr);
1857 put_user(data32, (u32 __user *)wrqu->data.pointer);
1858 wrqu->data.length = (data32 & 0xffff0000) >> 16;
1859 wrqu->data.flags = data32 & 0xffff;
1860 get_user(addr, (u32 __user *)wrqu->data.pointer);
1864 static int r8711_wx_write32(struct net_device *dev,
1865 struct iw_request_info *info,
1866 union iwreq_data *wrqu, char *keybuf)
1868 struct _adapter *padapter = netdev_priv(dev);
1872 get_user(addr, (u32 __user *)wrqu->data.pointer);
1873 data32 = ((u32)wrqu->data.length<<16) | (u32)wrqu->data.flags;
1874 r8712_write32(padapter, addr, data32);
1878 static int dummy(struct net_device *dev,
1879 struct iw_request_info *a,
1880 union iwreq_data *wrqu, char *b)
1885 static int r8711_drvext_hdl(struct net_device *dev,
1886 struct iw_request_info *info,
1887 union iwreq_data *wrqu, char *extra)
1892 static int r871x_mp_ioctl_hdl(struct net_device *dev,
1893 struct iw_request_info *info,
1894 union iwreq_data *wrqu, char *extra)
1896 struct _adapter *padapter = netdev_priv(dev);
1897 struct iw_point *p = &wrqu->data;
1898 struct oid_par_priv oid_par;
1899 struct mp_ioctl_handler *phandler;
1900 struct mp_ioctl_param *poidparam;
1901 unsigned long BytesRead, BytesWritten, BytesNeeded;
1907 if ((!p->length) || (!p->pointer))
1910 bset = (u8)(p->flags & 0xFFFF);
1912 pparmbuf = memdup_user(p->pointer, len);
1913 if (IS_ERR(pparmbuf))
1914 return PTR_ERR(pparmbuf);
1916 poidparam = (struct mp_ioctl_param *)pparmbuf;
1917 if (poidparam->subcode >= MAX_MP_IOCTL_SUBCODE) {
1919 goto _r871x_mp_ioctl_hdl_exit;
1921 phandler = mp_ioctl_hdl + poidparam->subcode;
1922 if ((phandler->paramsize != 0) &&
1923 (poidparam->len < phandler->paramsize)) {
1925 goto _r871x_mp_ioctl_hdl_exit;
1927 if (phandler->oid == 0 && phandler->handler)
1928 status = phandler->handler(&oid_par);
1929 else if (phandler->handler) {
1930 oid_par.adapter_context = padapter;
1931 oid_par.oid = phandler->oid;
1932 oid_par.information_buf = poidparam->data;
1933 oid_par.information_buf_len = poidparam->len;
1938 oid_par.bytes_rw = &BytesRead;
1939 oid_par.bytes_needed = &BytesNeeded;
1940 oid_par.type_of_oid = SET_OID;
1942 oid_par.bytes_rw = &BytesWritten;
1943 oid_par.bytes_needed = &BytesNeeded;
1944 oid_par.type_of_oid = QUERY_OID;
1946 status = phandler->handler(&oid_par);
1947 /* todo:check status, BytesNeeded, etc. */
1949 netdev_info(dev, "r8712u: %s: err!, subcode=%d, oid=%d, handler=%p\n",
1950 __func__, poidparam->subcode, phandler->oid,
1953 goto _r871x_mp_ioctl_hdl_exit;
1955 if (bset == 0x00) { /* query info */
1956 if (copy_to_user(p->pointer, pparmbuf, len))
1961 goto _r871x_mp_ioctl_hdl_exit;
1963 _r871x_mp_ioctl_hdl_exit:
1968 static int r871x_get_ap_info(struct net_device *dev,
1969 struct iw_request_info *info,
1970 union iwreq_data *wrqu, char *extra)
1972 struct _adapter *padapter = netdev_priv(dev);
1973 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1974 struct __queue *queue = &pmlmepriv->scanned_queue;
1975 struct iw_point *pdata = &wrqu->data;
1976 struct wlan_network *pnetwork = NULL;
1977 u32 cnt = 0, wpa_ielen;
1979 struct list_head *plist, *phead;
1980 unsigned char *pbuf;
1984 if (padapter->bDriverStopped || (pdata == NULL))
1986 while (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING)) {
1993 if (pdata->length >= 32) {
1994 if (copy_from_user(data, pdata->pointer, 32))
1998 spin_lock_irqsave(&(pmlmepriv->scanned_queue.lock), irqL);
1999 phead = &queue->queue;
2000 plist = phead->next;
2002 if (end_of_queue_search(phead, plist) == true)
2004 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
2005 if (hwaddr_aton_i(data, bssid)) {
2006 netdev_info(dev, "r8712u: Invalid BSSID '%s'.\n",
2008 spin_unlock_irqrestore(&(pmlmepriv->scanned_queue.lock),
2012 netdev_info(dev, "r8712u: BSSID:%pM\n", bssid);
2013 if (!memcmp(bssid, pnetwork->network.MacAddress, ETH_ALEN)) {
2014 /* BSSID match, then check if supporting wpa/wpa2 */
2015 pbuf = r8712_get_wpa_ie(&pnetwork->network.IEs[12],
2016 &wpa_ielen, pnetwork->network.IELength-12);
2017 if (pbuf && (wpa_ielen > 0)) {
2021 pbuf = r8712_get_wpa2_ie(&pnetwork->network.IEs[12],
2022 &wpa_ielen, pnetwork->network.IELength-12);
2023 if (pbuf && (wpa_ielen > 0)) {
2028 plist = plist->next;
2030 spin_unlock_irqrestore(&(pmlmepriv->scanned_queue.lock), irqL);
2031 if (pdata->length >= 34) {
2032 if (copy_to_user((u8 __user *)pdata->pointer + 32,
2033 (u8 *)&pdata->flags, 1))
2039 static int r871x_set_pid(struct net_device *dev,
2040 struct iw_request_info *info,
2041 union iwreq_data *wrqu, char *extra)
2043 struct _adapter *padapter = netdev_priv(dev);
2044 struct iw_point *pdata = &wrqu->data;
2046 if ((padapter->bDriverStopped) || (pdata == NULL))
2048 if (copy_from_user(&padapter->pid, pdata->pointer, sizeof(int)))
2053 static int r871x_set_chplan(struct net_device *dev,
2054 struct iw_request_info *info,
2055 union iwreq_data *wrqu, char *extra)
2058 struct _adapter *padapter = netdev_priv(dev);
2059 struct iw_point *pdata = &wrqu->data;
2062 if ((padapter->bDriverStopped) || (pdata == NULL)) {
2066 ch_plan = (int)*extra;
2067 r8712_set_chplan_cmd(padapter, ch_plan);
2074 static int r871x_wps_start(struct net_device *dev,
2075 struct iw_request_info *info,
2076 union iwreq_data *wrqu, char *extra)
2078 struct _adapter *padapter = netdev_priv(dev);
2079 struct iw_point *pdata = &wrqu->data;
2080 u32 u32wps_start = 0;
2082 if ((padapter->bDriverStopped) || (pdata == NULL))
2084 if (copy_from_user((void *)&u32wps_start, pdata->pointer, 4))
2086 if (u32wps_start == 0)
2087 u32wps_start = *extra;
2088 if (u32wps_start == 1) /* WPS Start */
2089 padapter->ledpriv.LedControlHandler(padapter,
2091 else if (u32wps_start == 2) /* WPS Stop because of wps success */
2092 padapter->ledpriv.LedControlHandler(padapter,
2094 else if (u32wps_start == 3) /* WPS Stop because of wps fail */
2095 padapter->ledpriv.LedControlHandler(padapter,
2096 LED_CTL_STOP_WPS_FAIL);
2100 static int wpa_set_param(struct net_device *dev, u8 name, u32 value)
2102 struct _adapter *padapter = netdev_priv(dev);
2105 case IEEE_PARAM_WPA_ENABLED:
2106 padapter->securitypriv.AuthAlgrthm = 2; /* 802.1x */
2107 switch ((value)&0xff) {
2109 padapter->securitypriv.ndisauthtype =
2110 Ndis802_11AuthModeWPAPSK; /* WPA_PSK */
2111 padapter->securitypriv.ndisencryptstatus =
2112 Ndis802_11Encryption2Enabled;
2115 padapter->securitypriv.ndisauthtype =
2116 Ndis802_11AuthModeWPA2PSK; /* WPA2_PSK */
2117 padapter->securitypriv.ndisencryptstatus =
2118 Ndis802_11Encryption3Enabled;
2122 case IEEE_PARAM_TKIP_COUNTERMEASURES:
2124 case IEEE_PARAM_DROP_UNENCRYPTED:
2127 * wpa_supplicant calls set_wpa_enabled when the driver
2128 * is loaded and unloaded, regardless of if WPA is being
2129 * used. No other calls are made which can be used to
2130 * determine if encryption will be used or not prior to
2131 * association being expected. If encryption is not being
2132 * used, drop_unencrypted is set to false, else true -- we
2133 * can use this to determine if the CAP_PRIVACY_ON bit should
2137 case IEEE_PARAM_PRIVACY_INVOKED:
2139 case IEEE_PARAM_AUTH_ALGS:
2140 return wpa_set_auth_algs(dev, value);
2141 case IEEE_PARAM_IEEE_802_1X:
2143 case IEEE_PARAM_WPAX_SELECT:
2144 /* added for WPA2 mixed mode */
2152 static int wpa_mlme(struct net_device *dev, u32 command, u32 reason)
2154 struct _adapter *padapter = netdev_priv(dev);
2157 case IEEE_MLME_STA_DEAUTH:
2158 if (!r8712_set_802_11_disassociate(padapter))
2161 case IEEE_MLME_STA_DISASSOC:
2162 if (!r8712_set_802_11_disassociate(padapter))
2171 static int wpa_supplicant_ioctl(struct net_device *dev, struct iw_point *p)
2173 struct ieee_param *param;
2175 struct _adapter *padapter = netdev_priv(dev);
2177 if (p->length < sizeof(struct ieee_param) || !p->pointer)
2179 param = memdup_user(p->pointer, p->length);
2181 return PTR_ERR(param);
2182 switch (param->cmd) {
2183 case IEEE_CMD_SET_WPA_PARAM:
2184 ret = wpa_set_param(dev, param->u.wpa_param.name,
2185 param->u.wpa_param.value);
2187 case IEEE_CMD_SET_WPA_IE:
2188 ret = r871x_set_wpa_ie(padapter, (char *)param->u.wpa_ie.data,
2189 (u16)param->u.wpa_ie.len);
2191 case IEEE_CMD_SET_ENCRYPTION:
2192 ret = wpa_set_encryption(dev, param, p->length);
2195 ret = wpa_mlme(dev, param->u.mlme.command,
2196 param->u.mlme.reason_code);
2202 if (ret == 0 && copy_to_user(p->pointer, param, p->length))
2208 /* based on "driver_ipw" and for hostapd */
2209 int r871x_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
2211 struct iwreq *wrq = (struct iwreq *)rq;
2214 case RTL_IOCTL_WPA_SUPPLICANT:
2215 return wpa_supplicant_ioctl(dev, &wrq->u.data);
2222 static iw_handler r8711_handlers[] = {
2223 NULL, /* SIOCSIWCOMMIT */
2224 r8711_wx_get_name, /* SIOCGIWNAME */
2225 dummy, /* SIOCSIWNWID */
2226 dummy, /* SIOCGIWNWID */
2227 r8711_wx_set_freq, /* SIOCSIWFREQ */
2228 r8711_wx_get_freq, /* SIOCGIWFREQ */
2229 r8711_wx_set_mode, /* SIOCSIWMODE */
2230 r8711_wx_get_mode, /* SIOCGIWMODE */
2231 dummy, /* SIOCSIWSENS */
2232 r8711_wx_get_sens, /* SIOCGIWSENS */
2233 NULL, /* SIOCSIWRANGE */
2234 r8711_wx_get_range, /* SIOCGIWRANGE */
2235 r871x_wx_set_priv, /* SIOCSIWPRIV */
2236 NULL, /* SIOCGIWPRIV */
2237 NULL, /* SIOCSIWSTATS */
2238 NULL, /* SIOCGIWSTATS */
2239 dummy, /* SIOCSIWSPY */
2240 dummy, /* SIOCGIWSPY */
2241 NULL, /* SIOCGIWTHRSPY */
2242 NULL, /* SIOCWIWTHRSPY */
2243 r8711_wx_set_wap, /* SIOCSIWAP */
2244 r8711_wx_get_wap, /* SIOCGIWAP */
2245 r871x_wx_set_mlme, /* request MLME operation;
2246 * uses struct iw_mlme */
2247 dummy, /* SIOCGIWAPLIST -- deprecated */
2248 r8711_wx_set_scan, /* SIOCSIWSCAN */
2249 r8711_wx_get_scan, /* SIOCGIWSCAN */
2250 r8711_wx_set_essid, /* SIOCSIWESSID */
2251 r8711_wx_get_essid, /* SIOCGIWESSID */
2252 dummy, /* SIOCSIWNICKN */
2253 r871x_wx_get_nick, /* SIOCGIWNICKN */
2254 NULL, /* -- hole -- */
2255 NULL, /* -- hole -- */
2256 r8711_wx_set_rate, /* SIOCSIWRATE */
2257 r8711_wx_get_rate, /* SIOCGIWRATE */
2258 dummy, /* SIOCSIWRTS */
2259 r8711_wx_get_rts, /* SIOCGIWRTS */
2260 r8711_wx_set_frag, /* SIOCSIWFRAG */
2261 r8711_wx_get_frag, /* SIOCGIWFRAG */
2262 dummy, /* SIOCSIWTXPOW */
2263 dummy, /* SIOCGIWTXPOW */
2264 dummy, /* SIOCSIWRETRY */
2265 r8711_wx_get_retry, /* SIOCGIWRETRY */
2266 r8711_wx_set_enc, /* SIOCSIWENCODE */
2267 r8711_wx_get_enc, /* SIOCGIWENCODE */
2268 dummy, /* SIOCSIWPOWER */
2269 r8711_wx_get_power, /* SIOCGIWPOWER */
2270 NULL, /*---hole---*/
2271 NULL, /*---hole---*/
2272 r871x_wx_set_gen_ie, /* SIOCSIWGENIE */
2273 NULL, /* SIOCGIWGENIE */
2274 r871x_wx_set_auth, /* SIOCSIWAUTH */
2275 NULL, /* SIOCGIWAUTH */
2276 r871x_wx_set_enc_ext, /* SIOCSIWENCODEEXT */
2277 NULL, /* SIOCGIWENCODEEXT */
2278 r871x_wx_set_pmkid, /* SIOCSIWPMKSA */
2279 NULL, /*---hole---*/
2282 static const struct iw_priv_args r8711_private_args[] = {
2284 SIOCIWFIRSTPRIV + 0x0,
2285 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "read32"
2288 SIOCIWFIRSTPRIV + 0x1,
2289 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "write32"
2292 SIOCIWFIRSTPRIV + 0x2, 0, 0, "driver_ext"
2295 SIOCIWFIRSTPRIV + 0x3, 0, 0, "mp_ioctl"
2298 SIOCIWFIRSTPRIV + 0x4,
2299 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "apinfo"
2302 SIOCIWFIRSTPRIV + 0x5,
2303 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setpid"
2306 SIOCIWFIRSTPRIV + 0x6,
2307 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wps_start"
2310 SIOCIWFIRSTPRIV + 0x7,
2311 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "chplan"
2315 static iw_handler r8711_private_handler[] = {
2320 r871x_get_ap_info, /*for MM DTV platform*/
2326 static struct iw_statistics *r871x_get_wireless_stats(struct net_device *dev)
2328 struct _adapter *padapter = netdev_priv(dev);
2329 struct iw_statistics *piwstats = &padapter->iwstats;
2334 if (check_fwstate(&padapter->mlmepriv, _FW_LINKED) != true) {
2335 piwstats->qual.qual = 0;
2336 piwstats->qual.level = 0;
2337 piwstats->qual.noise = 0;
2339 /* show percentage, we need transfer dbm to orignal value. */
2340 tmp_level = padapter->recvpriv.fw_rssi;
2341 tmp_qual = padapter->recvpriv.signal;
2342 tmp_noise = padapter->recvpriv.noise;
2343 piwstats->qual.level = tmp_level;
2344 piwstats->qual.qual = tmp_qual;
2345 piwstats->qual.noise = tmp_noise;
2347 piwstats->qual.updated = IW_QUAL_ALL_UPDATED;
2348 return &padapter->iwstats;
2351 struct iw_handler_def r871x_handlers_def = {
2352 .standard = r8711_handlers,
2353 .num_standard = ARRAY_SIZE(r8711_handlers),
2354 .private = r8711_private_handler,
2355 .private_args = (struct iw_priv_args *)r8711_private_args,
2356 .num_private = ARRAY_SIZE(r8711_private_handler),
2357 .num_private_args = sizeof(r8711_private_args) /
2358 sizeof(struct iw_priv_args),
2359 .get_wireless_stats = r871x_get_wireless_stats