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>
50 #define RTL_IOCTL_WPA_SUPPLICANT (SIOCIWFIRSTPRIV + 0x1E)
52 #define SCAN_ITEM_SIZE 768
53 #define MAX_CUSTOM_LEN 64
57 static const u32 rtl8180_rates[] = {1000000, 2000000, 5500000, 11000000,
58 6000000, 9000000, 12000000, 18000000,
59 24000000, 36000000, 48000000, 54000000};
61 static const long ieee80211_wlan_frequencies[] = {
62 2412, 2417, 2422, 2427,
63 2432, 2437, 2442, 2447,
64 2452, 2457, 2462, 2467,
68 static const char * const iw_operation_mode[] = {
69 "Auto", "Ad-Hoc", "Managed", "Master", "Repeater", "Secondary",
74 * hwaddr_aton - Convert ASCII string to MAC address
75 * @txt: MAC address as a string (e.g., "00:11:22:33:44:55")
76 * @addr: Buffer for the MAC address (ETH_ALEN = 6 bytes)
77 * Returns: 0 on success, -1 on failure (e.g., string not a MAC address)
79 static int hwaddr_aton_i(const char *txt, u8 *addr)
83 for (i = 0; i < 6; i++) {
86 a = hex_to_bin(*txt++);
89 b = hex_to_bin(*txt++);
92 *addr++ = (a << 4) | b;
93 if (i < 5 && *txt++ != ':')
99 void r8712_indicate_wx_assoc_event(struct _adapter *padapter)
101 union iwreq_data wrqu;
102 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
104 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
105 memcpy(wrqu.ap_addr.sa_data, pmlmepriv->cur_network.network.MacAddress,
107 wireless_send_event(padapter->pnetdev, SIOCGIWAP, &wrqu, NULL);
110 void r8712_indicate_wx_disassoc_event(struct _adapter *padapter)
112 union iwreq_data wrqu;
114 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
115 memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN);
116 wireless_send_event(padapter->pnetdev, SIOCGIWAP, &wrqu, NULL);
119 static inline void handle_pairwise_key(struct sta_info *psta,
120 struct ieee_param *param,
121 struct _adapter *padapter)
124 memcpy(psta->x_UncstKey.skey, param->u.crypt.key,
125 (param->u.crypt. key_len > 16 ? 16 : param->u.crypt.key_len));
126 if (strcmp(param->u.crypt.alg, "TKIP") == 0) { /* set mic key */
127 memcpy(psta->tkiptxmickey. skey, &(param->u.crypt.
129 memcpy(psta->tkiprxmickey. skey, &(param->u.crypt.
131 padapter->securitypriv. busetkipkey = false;
132 _set_timer(&padapter->securitypriv.tkip_timer, 50);
134 r8712_setstakey_cmd(padapter, (unsigned char *)psta, true);
137 static inline void handle_group_key(struct ieee_param *param,
138 struct _adapter *padapter)
140 if (0 < param->u.crypt.idx &&
141 param->u.crypt.idx < 3) {
142 /* group key idx is 1 or 2 */
143 memcpy(padapter->securitypriv.XGrpKey[param->u.crypt.
144 idx-1].skey, param->u.crypt.key, (param->u.crypt.key_len
145 > 16 ? 16 : param->u.crypt.key_len));
146 memcpy(padapter->securitypriv.XGrptxmickey[param->
147 u.crypt.idx-1].skey, &(param->u.crypt.key[16]), 8);
148 memcpy(padapter->securitypriv. XGrprxmickey[param->
149 u.crypt.idx-1].skey, &(param->u.crypt.key[24]), 8);
150 padapter->securitypriv.binstallGrpkey = true;
151 r8712_set_key(padapter, &padapter->securitypriv,
153 if (padapter->registrypriv.power_mgnt > PS_MODE_ACTIVE) {
154 if (padapter->registrypriv.power_mgnt != padapter->
155 pwrctrlpriv.pwr_mode)
156 _set_timer(&(padapter->mlmepriv.dhcp_timer),
162 static inline char *translate_scan(struct _adapter *padapter,
163 struct iw_request_info *info,
164 struct wlan_network *pnetwork,
165 char *start, char *stop)
168 struct ieee80211_ht_cap *pht_capie;
171 u32 i = 0, ht_ielen = 0;
172 u16 cap, ht_cap = false, mcs_rate;
173 u8 rssi, bw_40MHz = 0, short_GI = 0;
175 if ((pnetwork->network.Configuration.DSConfig < 1) ||
176 (pnetwork->network.Configuration.DSConfig > 14)) {
177 if (pnetwork->network.Configuration.DSConfig < 1)
178 pnetwork->network.Configuration.DSConfig = 1;
180 pnetwork->network.Configuration.DSConfig = 14;
184 iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
185 memcpy(iwe.u.ap_addr.sa_data, pnetwork->network.MacAddress, ETH_ALEN);
186 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_ADDR_LEN);
188 iwe.cmd = SIOCGIWESSID;
189 iwe.u.data.flags = 1;
190 iwe.u.data.length = min_t(u32, pnetwork->network.Ssid.SsidLength, 32);
191 start = iwe_stream_add_point(info, start, stop, &iwe,
192 pnetwork->network.Ssid.Ssid);
193 /* parsing HT_CAP_IE */
194 p = r8712_get_ie(&pnetwork->network.IEs[12], _HT_CAPABILITY_IE_,
195 &ht_ielen, pnetwork->network.IELength - 12);
196 if (p && ht_ielen > 0) {
198 pht_capie = (struct ieee80211_ht_cap *)(p + 2);
199 memcpy(&mcs_rate , pht_capie->supp_mcs_set, 2);
200 bw_40MHz = (pht_capie->cap_info&IEEE80211_HT_CAP_SUP_WIDTH)
202 short_GI = (pht_capie->cap_info&(IEEE80211_HT_CAP_SGI_20 |
203 IEEE80211_HT_CAP_SGI_40)) ? 1 : 0;
205 /* Add the protocol name */
206 iwe.cmd = SIOCGIWNAME;
207 if ((r8712_is_cckratesonly_included((u8 *)&pnetwork->network.
208 SupportedRates)) == true) {
210 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bn");
212 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11b");
213 } else if ((r8712_is_cckrates_included((u8 *)&pnetwork->network.
214 SupportedRates)) == true) {
216 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bgn");
218 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bg");
221 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11gn");
223 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11g");
225 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_CHAR_LEN);
227 iwe.cmd = SIOCGIWMODE;
228 memcpy((u8 *)&cap, r8712_get_capability_from_ie(pnetwork->network.IEs),
230 cap = le16_to_cpu(cap);
231 if (cap & (WLAN_CAPABILITY_IBSS|WLAN_CAPABILITY_BSS)) {
232 if (cap & WLAN_CAPABILITY_BSS)
233 iwe.u.mode = (u32)IW_MODE_MASTER;
235 iwe.u.mode = (u32)IW_MODE_ADHOC;
236 start = iwe_stream_add_event(info, start, stop, &iwe,
239 /* Add frequency/channel */
240 iwe.cmd = SIOCGIWFREQ;
242 /* check legal index */
243 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 out_len = r8712_get_sec_ie(pnetwork->network.IEs,
292 IELength, rsn_ie, &rsn_len,
295 memset(buf, 0, MAX_WPA_IE_LEN);
296 n = sprintf(buf, "wpa_ie=");
297 for (i = 0; i < wpa_len; i++) {
298 n += snprintf(buf + n, MAX_WPA_IE_LEN - n,
300 if (n >= MAX_WPA_IE_LEN)
303 memset(&iwe, 0, sizeof(iwe));
304 iwe.cmd = IWEVCUSTOM;
305 iwe.u.data.length = (u16)strlen(buf);
306 start = iwe_stream_add_point(info, start, stop,
308 memset(&iwe, 0, sizeof(iwe));
310 iwe.u.data.length = (u16)wpa_len;
311 start = iwe_stream_add_point(info, start, stop,
315 memset(buf, 0, MAX_WPA_IE_LEN);
316 n = sprintf(buf, "rsn_ie=");
317 for (i = 0; i < rsn_len; i++) {
318 n += snprintf(buf + n, MAX_WPA_IE_LEN - n,
320 if (n >= MAX_WPA_IE_LEN)
323 memset(&iwe, 0, sizeof(iwe));
324 iwe.cmd = IWEVCUSTOM;
325 iwe.u.data.length = strlen(buf);
326 start = iwe_stream_add_point(info, start, stop,
328 memset(&iwe, 0, sizeof(iwe));
330 iwe.u.data.length = rsn_len;
331 start = iwe_stream_add_point(info, start, stop, &iwe,
336 { /* parsing WPS IE */
340 if (r8712_get_wps_ie(pnetwork->network.IEs,
341 pnetwork->network.IELength,
342 wps_ie, &wps_ielen) == true) {
345 iwe.u.data.length = (u16)wps_ielen;
346 start = iwe_stream_add_point(info, start, stop,
351 /* Add quality statistics */
353 rssi = r8712_signal_scale_mapping(pnetwork->network.Rssi);
354 /* we only update signal_level (signal strength) that is rssi. */
355 iwe.u.qual.updated = (u8)(IW_QUAL_QUAL_INVALID | IW_QUAL_LEVEL_UPDATED |
356 IW_QUAL_NOISE_INVALID);
357 iwe.u.qual.level = rssi; /* signal strength */
358 iwe.u.qual.qual = 0; /* signal quality */
359 iwe.u.qual.noise = 0; /* noise level */
360 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_QUAL_LEN);
361 /* how to translate rssi to ?% */
365 static int wpa_set_auth_algs(struct net_device *dev, u32 value)
367 struct _adapter *padapter = (struct _adapter *) netdev_priv(dev);
370 if ((value & AUTH_ALG_SHARED_KEY) && (value & AUTH_ALG_OPEN_SYSTEM)) {
371 padapter->securitypriv.ndisencryptstatus =
372 Ndis802_11Encryption1Enabled;
373 padapter->securitypriv.ndisauthtype =
374 Ndis802_11AuthModeAutoSwitch;
375 padapter->securitypriv.AuthAlgrthm = 3;
376 } else if (value & AUTH_ALG_SHARED_KEY) {
377 padapter->securitypriv.ndisencryptstatus =
378 Ndis802_11Encryption1Enabled;
379 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeShared;
380 padapter->securitypriv.AuthAlgrthm = 1;
381 } else if (value & AUTH_ALG_OPEN_SYSTEM) {
382 if (padapter->securitypriv.ndisauthtype <
383 Ndis802_11AuthModeWPAPSK) {
384 padapter->securitypriv.ndisauthtype =
385 Ndis802_11AuthModeOpen;
386 padapter->securitypriv.AuthAlgrthm = 0;
393 static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param,
397 u32 wep_key_idx, wep_key_len = 0;
398 struct NDIS_802_11_WEP *pwep = NULL;
399 struct _adapter *padapter = (struct _adapter *)netdev_priv(dev);
400 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
401 struct security_priv *psecuritypriv = &padapter->securitypriv;
403 param->u.crypt.err = 0;
404 param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
405 if (param_len != (u32)((u8 *) param->u.crypt.key - (u8 *)param) +
406 param->u.crypt.key_len)
408 if (is_broadcast_ether_addr(param->sta_addr)) {
409 if (param->u.crypt.idx >= WEP_KEYS) {
410 /* for large key indices, set the default (0) */
411 param->u.crypt.idx = 0;
415 if (strcmp(param->u.crypt.alg, "WEP") == 0) {
416 netdev_info(dev, "r8712u: %s: crypt.alg = WEP\n", __func__);
417 padapter->securitypriv.ndisencryptstatus =
418 Ndis802_11Encryption1Enabled;
419 padapter->securitypriv.PrivacyAlgrthm = _WEP40_;
420 padapter->securitypriv.XGrpPrivacy = _WEP40_;
421 wep_key_idx = param->u.crypt.idx;
422 wep_key_len = param->u.crypt.key_len;
423 if (wep_key_idx >= WEP_KEYS)
425 if (wep_key_len > 0) {
426 wep_key_len = wep_key_len <= 5 ? 5 : 13;
427 pwep = (struct NDIS_802_11_WEP *)_malloc((u32)
429 FIELD_OFFSET(struct NDIS_802_11_WEP,
433 memset(pwep, 0, sizeof(struct NDIS_802_11_WEP));
434 pwep->KeyLength = wep_key_len;
435 pwep->Length = wep_key_len +
436 FIELD_OFFSET(struct NDIS_802_11_WEP,
438 if (wep_key_len == 13) {
439 padapter->securitypriv.PrivacyAlgrthm =
441 padapter->securitypriv.XGrpPrivacy =
446 pwep->KeyIndex = wep_key_idx;
447 pwep->KeyIndex |= 0x80000000;
448 memcpy(pwep->KeyMaterial, param->u.crypt.key, pwep->KeyLength);
449 if (param->u.crypt.set_tx) {
450 if (r8712_set_802_11_add_wep(padapter, pwep) ==
454 /* don't update "psecuritypriv->PrivacyAlgrthm" and
455 * "psecuritypriv->PrivacyKeyIndex=keyid", but can
456 * r8712_set_key to fw/cam
458 if (wep_key_idx >= WEP_KEYS) {
462 memcpy(&(psecuritypriv->DefKey[wep_key_idx].
463 skey[0]), pwep->KeyMaterial,
465 psecuritypriv->DefKeylen[wep_key_idx] =
467 r8712_set_key(padapter, psecuritypriv, wep_key_idx);
471 if (padapter->securitypriv.AuthAlgrthm == 2) { /* 802_1x */
472 struct sta_info *psta, *pbcmc_sta;
473 struct sta_priv *pstapriv = &padapter->stapriv;
475 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE |
476 WIFI_MP_STATE) == true) { /* sta mode */
477 psta = r8712_get_stainfo(pstapriv,
478 get_bssid(pmlmepriv));
480 psta->ieee8021x_blocked = false;
481 if ((padapter->securitypriv.ndisencryptstatus ==
482 Ndis802_11Encryption2Enabled) ||
483 (padapter->securitypriv.ndisencryptstatus ==
484 Ndis802_11Encryption3Enabled))
485 psta->XPrivacy = padapter->
486 securitypriv.PrivacyAlgrthm;
487 if (param->u.crypt.set_tx == 1)
488 handle_pairwise_key(psta, param,
491 handle_group_key(param, padapter);
493 pbcmc_sta = r8712_get_bcmc_stainfo(padapter);
495 pbcmc_sta->ieee8021x_blocked = false;
496 if ((padapter->securitypriv.ndisencryptstatus ==
497 Ndis802_11Encryption2Enabled) ||
498 (padapter->securitypriv.ndisencryptstatus ==
499 Ndis802_11Encryption3Enabled))
500 pbcmc_sta->XPrivacy =
501 padapter->securitypriv.
511 static int r871x_set_wpa_ie(struct _adapter *padapter, char *pie,
512 unsigned short ielen)
514 u8 *buf = NULL, *pos = NULL;
515 int group_cipher = 0, pairwise_cipher = 0;
518 if ((ielen > MAX_WPA_IE_LEN) || (pie == NULL))
521 buf = _malloc(ielen);
524 memcpy(buf, pie , ielen);
526 if (ielen < RSN_HEADER_LEN) {
530 if (r8712_parse_wpa_ie(buf, ielen, &group_cipher,
531 &pairwise_cipher) == _SUCCESS) {
532 padapter->securitypriv.AuthAlgrthm = 2;
533 padapter->securitypriv.ndisauthtype =
534 Ndis802_11AuthModeWPAPSK;
536 if (r8712_parse_wpa2_ie(buf, ielen, &group_cipher,
537 &pairwise_cipher) == _SUCCESS) {
538 padapter->securitypriv.AuthAlgrthm = 2;
539 padapter->securitypriv.ndisauthtype =
540 Ndis802_11AuthModeWPA2PSK;
542 switch (group_cipher) {
543 case WPA_CIPHER_NONE:
544 padapter->securitypriv.XGrpPrivacy =
546 padapter->securitypriv.ndisencryptstatus =
547 Ndis802_11EncryptionDisabled;
549 case WPA_CIPHER_WEP40:
550 padapter->securitypriv.XGrpPrivacy = _WEP40_;
551 padapter->securitypriv.ndisencryptstatus =
552 Ndis802_11Encryption1Enabled;
554 case WPA_CIPHER_TKIP:
555 padapter->securitypriv.XGrpPrivacy = _TKIP_;
556 padapter->securitypriv.ndisencryptstatus =
557 Ndis802_11Encryption2Enabled;
559 case WPA_CIPHER_CCMP:
560 padapter->securitypriv.XGrpPrivacy = _AES_;
561 padapter->securitypriv.ndisencryptstatus =
562 Ndis802_11Encryption3Enabled;
564 case WPA_CIPHER_WEP104:
565 padapter->securitypriv.XGrpPrivacy = _WEP104_;
566 padapter->securitypriv.ndisencryptstatus =
567 Ndis802_11Encryption1Enabled;
570 switch (pairwise_cipher) {
571 case WPA_CIPHER_NONE:
572 padapter->securitypriv.PrivacyAlgrthm =
574 padapter->securitypriv.ndisencryptstatus =
575 Ndis802_11EncryptionDisabled;
577 case WPA_CIPHER_WEP40:
578 padapter->securitypriv.PrivacyAlgrthm = _WEP40_;
579 padapter->securitypriv.ndisencryptstatus =
580 Ndis802_11Encryption1Enabled;
582 case WPA_CIPHER_TKIP:
583 padapter->securitypriv.PrivacyAlgrthm = _TKIP_;
584 padapter->securitypriv.ndisencryptstatus =
585 Ndis802_11Encryption2Enabled;
587 case WPA_CIPHER_CCMP:
588 padapter->securitypriv.PrivacyAlgrthm = _AES_;
589 padapter->securitypriv.ndisencryptstatus =
590 Ndis802_11Encryption3Enabled;
592 case WPA_CIPHER_WEP104:
593 padapter->securitypriv.PrivacyAlgrthm = _WEP104_;
594 padapter->securitypriv.ndisencryptstatus =
595 Ndis802_11Encryption1Enabled;
598 padapter->securitypriv.wps_phase = false;
601 u8 eid, wps_oui[4] = {0x0, 0x50, 0xf2, 0x04};
603 while (cnt < ielen) {
606 if ((eid == _VENDOR_SPECIFIC_IE_) &&
607 (!memcmp(&buf[cnt+2], wps_oui, 4))) {
608 netdev_info(padapter->pnetdev, "r8712u: SET WPS_IE\n");
609 padapter->securitypriv.wps_ie_len =
611 (MAX_WPA_IE_LEN << 2)) ?
613 (MAX_WPA_IE_LEN << 2);
614 memcpy(padapter->securitypriv.wps_ie,
616 padapter->securitypriv.wps_ie_len);
617 padapter->securitypriv.wps_phase =
619 netdev_info(padapter->pnetdev, "r8712u: SET WPS_IE, wps_phase==true\n");
623 cnt += buf[cnt + 1] + 2;
632 static int r8711_wx_get_name(struct net_device *dev,
633 struct iw_request_info *info,
634 union iwreq_data *wrqu, char *extra)
636 struct _adapter *padapter = (struct _adapter *)netdev_priv(dev);
640 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
641 struct ndis_wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
642 NDIS_802_11_RATES_EX *prates = NULL;
644 if (check_fwstate(pmlmepriv, _FW_LINKED|WIFI_ADHOC_MASTER_STATE) ==
646 /* parsing HT_CAP_IE */
647 p = r8712_get_ie(&pcur_bss->IEs[12], _HT_CAPABILITY_IE_,
648 &ht_ielen, pcur_bss->IELength - 12);
649 if (p && ht_ielen > 0)
651 prates = &pcur_bss->SupportedRates;
652 if (r8712_is_cckratesonly_included((u8 *)prates) == true) {
654 snprintf(wrqu->name, IFNAMSIZ,
657 snprintf(wrqu->name, IFNAMSIZ,
659 } else if ((r8712_is_cckrates_included((u8 *)prates)) == true) {
661 snprintf(wrqu->name, IFNAMSIZ,
664 snprintf(wrqu->name, IFNAMSIZ,
668 snprintf(wrqu->name, IFNAMSIZ,
671 snprintf(wrqu->name, IFNAMSIZ,
675 snprintf(wrqu->name, IFNAMSIZ, "unassociated");
679 static const long frequency_list[] = {
680 2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447, 2452, 2457, 2462,
681 2467, 2472, 2484, 4915, 4920, 4925, 4935, 4940, 4945, 4960, 4980,
682 5035, 5040, 5045, 5055, 5060, 5080, 5170, 5180, 5190, 5200, 5210,
683 5220, 5230, 5240, 5260, 5280, 5300, 5320, 5500, 5520, 5540, 5560,
684 5580, 5600, 5620, 5640, 5660, 5680, 5700, 5745, 5765, 5785, 5805,
688 static int r8711_wx_set_freq(struct net_device *dev,
689 struct iw_request_info *info,
690 union iwreq_data *wrqu, char *extra)
692 struct _adapter *padapter = (struct _adapter *)netdev_priv(dev);
693 struct iw_freq *fwrq = &wrqu->freq;
696 /* If setting by frequency, convert to a channel */
697 if ((fwrq->e == 1) &&
698 (fwrq->m >= (int) 2.412e8) &&
699 (fwrq->m <= (int) 2.487e8)) {
700 int f = fwrq->m / 100000;
702 while ((c < 14) && (f != frequency_list[c]))
707 /* Setting by channel number */
708 if ((fwrq->m > 14) || (fwrq->e > 0))
711 int channel = fwrq->m;
712 if ((channel < 1) || (channel > 14))
715 /* Yes ! We can set it !!! */
716 padapter->registrypriv.channel = channel;
722 static int r8711_wx_get_freq(struct net_device *dev,
723 struct iw_request_info *info,
724 union iwreq_data *wrqu, char *extra)
726 struct _adapter *padapter = (struct _adapter *)netdev_priv(dev);
727 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
728 struct ndis_wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
730 if (check_fwstate(pmlmepriv, _FW_LINKED) == true) {
731 wrqu->freq.m = ieee80211_wlan_frequencies[
732 pcur_bss->Configuration.DSConfig-1] * 100000;
734 wrqu->freq.i = pcur_bss->Configuration.DSConfig;
741 static int r8711_wx_set_mode(struct net_device *dev,
742 struct iw_request_info *a,
743 union iwreq_data *wrqu, char *b)
745 struct _adapter *padapter = (struct _adapter *)netdev_priv(dev);
746 enum NDIS_802_11_NETWORK_INFRASTRUCTURE networkType;
748 switch (wrqu->mode) {
750 networkType = Ndis802_11AutoUnknown;
753 networkType = Ndis802_11IBSS;
756 networkType = Ndis802_11APMode;
759 networkType = Ndis802_11Infrastructure;
764 if (Ndis802_11APMode == networkType)
765 r8712_setopmode_cmd(padapter, networkType);
767 r8712_setopmode_cmd(padapter, Ndis802_11AutoUnknown);
769 r8712_set_802_11_infrastructure_mode(padapter, networkType);
773 static int r8711_wx_get_mode(struct net_device *dev, struct iw_request_info *a,
774 union iwreq_data *wrqu, char *b)
776 struct _adapter *padapter = (struct _adapter *)netdev_priv(dev);
777 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
779 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == true)
780 wrqu->mode = IW_MODE_INFRA;
781 else if (check_fwstate(pmlmepriv,
782 WIFI_ADHOC_MASTER_STATE|WIFI_ADHOC_STATE) == true)
783 wrqu->mode = IW_MODE_ADHOC;
784 else if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == true)
785 wrqu->mode = IW_MODE_MASTER;
787 wrqu->mode = IW_MODE_AUTO;
791 static int r871x_wx_set_pmkid(struct net_device *dev,
792 struct iw_request_info *a,
793 union iwreq_data *wrqu, char *extra)
795 struct _adapter *padapter = (struct _adapter *)netdev_priv(dev);
796 struct security_priv *psecuritypriv = &padapter->securitypriv;
797 struct iw_pmksa *pPMK = (struct iw_pmksa *) extra;
798 u8 strZeroMacAddress[ETH_ALEN] = {0x00};
799 u8 strIssueBssid[ETH_ALEN] = {0x00};
800 u8 j, blInserted = false;
801 int intReturn = false;
804 There are the BSSID information in the bssid.sa_data array.
805 If cmd is IW_PMKSA_FLUSH, it means the wpa_supplicant wants to clear
806 all the PMKID information. If cmd is IW_PMKSA_ADD, it means the
807 wpa_supplicant wants to add a PMKID/BSSID to driver.
808 If cmd is IW_PMKSA_REMOVE, it means the wpa_supplicant wants to
809 remove a PMKID/BSSID from driver.
813 memcpy(strIssueBssid, pPMK->bssid.sa_data, ETH_ALEN);
816 if (!memcmp(strIssueBssid, strZeroMacAddress, ETH_ALEN))
821 /* overwrite PMKID */
822 for (j = 0; j < NUM_PMKID_CACHE; j++) {
823 if (!memcmp(psecuritypriv->PMKIDList[j].Bssid,
824 strIssueBssid, ETH_ALEN)) {
825 /* BSSID is matched, the same AP => rewrite
827 netdev_info(dev, "r8712u: %s: BSSID exists in the PMKList.\n",
829 memcpy(psecuritypriv->PMKIDList[j].PMKID,
830 pPMK->pmkid, IW_PMKID_LEN);
831 psecuritypriv->PMKIDList[j].bUsed = true;
832 psecuritypriv->PMKIDIndex = j + 1;
838 /* Find a new entry */
839 netdev_info(dev, "r8712u: %s: Use the new entry index = %d for this PMKID.\n",
840 __func__, psecuritypriv->PMKIDIndex);
841 memcpy(psecuritypriv->PMKIDList[psecuritypriv->
842 PMKIDIndex].Bssid, strIssueBssid, ETH_ALEN);
843 memcpy(psecuritypriv->PMKIDList[psecuritypriv->
844 PMKIDIndex].PMKID, pPMK->pmkid, IW_PMKID_LEN);
845 psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].
847 psecuritypriv->PMKIDIndex++;
848 if (psecuritypriv->PMKIDIndex == NUM_PMKID_CACHE)
849 psecuritypriv->PMKIDIndex = 0;
852 case IW_PMKSA_REMOVE:
854 for (j = 0; j < NUM_PMKID_CACHE; j++) {
855 if (!memcmp(psecuritypriv->PMKIDList[j].Bssid,
856 strIssueBssid, ETH_ALEN)) {
857 /* BSSID is matched, the same AP => Remove
858 * this PMKID information and reset it. */
859 memset(psecuritypriv->PMKIDList[j].Bssid,
861 psecuritypriv->PMKIDList[j].bUsed = false;
867 memset(psecuritypriv->PMKIDList, 0,
868 sizeof(struct RT_PMKID_LIST) * NUM_PMKID_CACHE);
869 psecuritypriv->PMKIDIndex = 0;
873 netdev_info(dev, "r8712u: %s: unknown Command\n", __func__);
880 static int r8711_wx_get_sens(struct net_device *dev,
881 struct iw_request_info *info,
882 union iwreq_data *wrqu, char *extra)
884 wrqu->sens.value = 0;
885 wrqu->sens.fixed = 0; /* no auto select */
886 wrqu->sens.disabled = 1;
890 static int r8711_wx_get_range(struct net_device *dev,
891 struct iw_request_info *info,
892 union iwreq_data *wrqu, char *extra)
894 struct iw_range *range = (struct iw_range *)extra;
898 wrqu->data.length = sizeof(*range);
899 memset(range, 0, sizeof(*range));
900 /* Let's try to keep this struct in the same order as in
901 * linux/include/wireless.h
904 /* TODO: See what values we can set, and remove the ones we can't
905 * set, or fill them with some default data.
907 /* ~5 Mb/s real (802.11b) */
908 range->throughput = 5 * 1000 * 1000;
909 /* TODO: 8711 sensitivity ? */
910 /* signal level threshold range */
911 /* percent values between 0 and 100. */
912 range->max_qual.qual = 100;
913 range->max_qual.level = 100;
914 range->max_qual.noise = 100;
915 range->max_qual.updated = 7; /* Updated all three */
916 range->avg_qual.qual = 92; /* > 8% missed beacons is 'bad' */
917 /* TODO: Find real 'good' to 'bad' threshold value for RSSI */
918 range->avg_qual.level = 20 + -98;
919 range->avg_qual.noise = 0;
920 range->avg_qual.updated = 7; /* Updated all three */
921 range->num_bitrates = RATE_COUNT;
922 for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++)
923 range->bitrate[i] = rtl8180_rates[i];
924 range->min_frag = MIN_FRAG_THRESHOLD;
925 range->max_frag = MAX_FRAG_THRESHOLD;
927 range->we_version_compiled = WIRELESS_EXT;
928 range->we_version_source = 16;
929 range->num_channels = 14;
930 for (i = 0, val = 0; i < 14; i++) {
931 /* Include only legal frequencies for some countries */
932 range->freq[val].i = i + 1;
933 range->freq[val].m = ieee80211_wlan_frequencies[i] * 100000;
934 range->freq[val].e = 1;
936 if (val == IW_MAX_FREQUENCIES)
939 range->num_frequency = val;
940 range->enc_capa = IW_ENC_CAPA_WPA |
942 IW_ENC_CAPA_CIPHER_TKIP |
943 IW_ENC_CAPA_CIPHER_CCMP;
947 static int r8711_wx_get_rate(struct net_device *dev,
948 struct iw_request_info *info,
949 union iwreq_data *wrqu, char *extra);
951 static int r871x_wx_set_priv(struct net_device *dev,
952 struct iw_request_info *info,
953 union iwreq_data *awrq,
956 int ret = 0, len = 0;
958 struct _adapter *padapter = netdev_priv(dev);
959 struct iw_point *dwrq = (struct iw_point *)awrq;
965 if (copy_from_user(ext, dwrq->pointer, len)) {
970 if (0 == strcasecmp(ext, "RSSI")) {
971 /*Return received signal strength indicator in -db for */
974 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
975 struct wlan_network *pcur_network = &pmlmepriv->cur_network;
977 if (check_fwstate(pmlmepriv, _FW_LINKED) == true) {
978 sprintf(ext, "%s rssi %d",
979 pcur_network->network.Ssid.Ssid,
981 ((padapter->recvpriv.fw_rssi)>>1)-95
982 /*pcur_network->network.Rssi */
987 } else if (0 == strcasecmp(ext, "LINKSPEED")) {
988 /*Return link speed in MBPS */
990 union iwreq_data wrqd;
994 ret_inner = r8711_wx_get_rate(dev, info, &wrqd, extra);
998 mbps = wrqd.bitrate.value / 1000000;
999 sprintf(ext, "LINKSPEED %d", mbps);
1000 } else if (0 == strcasecmp(ext, "MACADDR")) {
1001 /*Return mac address of the station */
1002 /* Macaddr = xx:xx:xx:xx:xx:xx */
1003 sprintf(ext, "MACADDR = %pM", dev->dev_addr);
1004 } else if (0 == strcasecmp(ext, "SCAN-ACTIVE")) {
1005 /*Set scan type to active */
1006 /*OK if successful */
1007 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1008 pmlmepriv->passive_mode = 1;
1010 } else if (0 == strcasecmp(ext, "SCAN-PASSIVE")) {
1011 /*Set scan type to passive */
1012 /*OK if successful */
1013 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1014 pmlmepriv->passive_mode = 0;
1016 } else if (0 == strncmp(ext, "DCE-E", 5)) {
1017 /*Set scan type to passive */
1018 /*OK if successful */
1019 r8712_disconnectCtrlEx_cmd(padapter
1020 , 1 /*u32 enableDrvCtrl */
1021 , 5 /*u32 tryPktCnt */
1022 , 100 /*u32 tryPktInterval */
1023 , 5000 /*u32 firstStageTO */
1026 } else if (0 == strncmp(ext, "DCE-D", 5)) {
1027 /*Set scan type to passive */
1028 /*OK if successfu */
1029 r8712_disconnectCtrlEx_cmd(padapter
1030 , 0 /*u32 enableDrvCtrl */
1031 , 5 /*u32 tryPktCnt */
1032 , 100 /*u32 tryPktInterval */
1033 , 5000 /*u32 firstStageTO */
1037 netdev_info(dev, "r8712u: %s: unknown Command %s.\n",
1041 if (copy_to_user(dwrq->pointer, ext,
1042 min(dwrq->length, (__u16)(strlen(ext)+1))))
1051 * s1. set_802_11_infrastructure_mode()
1052 * s2. set_802_11_authentication_mode()
1053 * s3. set_802_11_encryption_mode()
1054 * s4. set_802_11_bssid()
1056 * This function intends to handle the Set AP command, which specifies the
1057 * MAC# of a preferred Access Point.
1058 * Currently, the request comes via Wireless Extensions' SIOCSIWAP ioctl.
1060 * For this operation to succeed, there is no need for the interface to be up.
1063 static int r8711_wx_set_wap(struct net_device *dev,
1064 struct iw_request_info *info,
1065 union iwreq_data *awrq,
1068 int ret = -EINPROGRESS;
1069 struct _adapter *padapter = (struct _adapter *) netdev_priv(dev);
1070 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1071 struct __queue *queue = &pmlmepriv->scanned_queue;
1072 struct sockaddr *temp = (struct sockaddr *)awrq;
1074 struct list_head *phead;
1076 struct wlan_network *pnetwork = NULL;
1077 enum NDIS_802_11_AUTHENTICATION_MODE authmode;
1079 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == true)
1081 if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == true)
1083 if (temp->sa_family != ARPHRD_ETHER)
1085 authmode = padapter->securitypriv.ndisauthtype;
1086 spin_lock_irqsave(&queue->lock, irqL);
1087 phead = get_list_head(queue);
1088 pmlmepriv->pscanned = get_next(phead);
1090 if (end_of_queue_search(phead, pmlmepriv->pscanned) == true)
1092 pnetwork = LIST_CONTAINOR(pmlmepriv->pscanned,
1093 struct wlan_network, list);
1094 pmlmepriv->pscanned = get_next(pmlmepriv->pscanned);
1095 dst_bssid = pnetwork->network.MacAddress;
1096 if (!memcmp(dst_bssid, temp->sa_data, ETH_ALEN)) {
1097 r8712_set_802_11_infrastructure_mode(padapter,
1098 pnetwork->network.InfrastructureMode);
1102 spin_unlock_irqrestore(&queue->lock, irqL);
1104 if (!r8712_set_802_11_authentication_mode(padapter, authmode))
1107 if (!r8712_set_802_11_bssid(padapter, temp->sa_data))
1114 static int r8711_wx_get_wap(struct net_device *dev,
1115 struct iw_request_info *info,
1116 union iwreq_data *wrqu, char *extra)
1118 struct _adapter *padapter = (struct _adapter *)netdev_priv(dev);
1119 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1120 struct ndis_wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
1122 wrqu->ap_addr.sa_family = ARPHRD_ETHER;
1123 if (check_fwstate(pmlmepriv, _FW_LINKED | WIFI_ADHOC_MASTER_STATE |
1125 memcpy(wrqu->ap_addr.sa_data, pcur_bss->MacAddress, ETH_ALEN);
1127 memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN);
1131 static int r871x_wx_set_mlme(struct net_device *dev,
1132 struct iw_request_info *info,
1133 union iwreq_data *wrqu, char *extra)
1137 struct _adapter *padapter = (struct _adapter *)netdev_priv(dev);
1138 struct iw_mlme *mlme = (struct iw_mlme *) extra;
1142 reason = cpu_to_le16(mlme->reason_code);
1143 switch (mlme->cmd) {
1144 case IW_MLME_DEAUTH:
1145 if (!r8712_set_802_11_disassociate(padapter))
1148 case IW_MLME_DISASSOC:
1149 if (!r8712_set_802_11_disassociate(padapter))
1160 * This function intends to handle the Set Scan command.
1161 * Currently, the request comes via Wireless Extensions' SIOCSIWSCAN ioctl.
1163 * For this operation to succeed, the interface is brought Up beforehand.
1166 static int r8711_wx_set_scan(struct net_device *dev,
1167 struct iw_request_info *a,
1168 union iwreq_data *wrqu, char *extra)
1170 struct _adapter *padapter = (struct _adapter *)netdev_priv(dev);
1171 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1174 if (padapter->bDriverStopped == true) {
1175 netdev_info(dev, "In %s: bDriverStopped=%d\n",
1176 __func__, padapter->bDriverStopped);
1179 if (padapter->bup == false)
1181 if (padapter->hw_init_completed == false)
1183 if ((check_fwstate(pmlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING)) ||
1184 (pmlmepriv->sitesurveyctrl.traffic_busy == true))
1186 if (wrqu->data.length == sizeof(struct iw_scan_req)) {
1187 struct iw_scan_req *req = (struct iw_scan_req *)extra;
1188 if (wrqu->data.flags & IW_SCAN_THIS_ESSID) {
1189 struct ndis_802_11_ssid ssid;
1191 u32 len = min_t(u8, req->essid_len, IW_ESSID_MAX_SIZE);
1192 memset((unsigned char *)&ssid, 0,
1193 sizeof(struct ndis_802_11_ssid));
1194 memcpy(ssid.Ssid, req->essid, len);
1195 ssid.SsidLength = len;
1196 spin_lock_irqsave(&pmlmepriv->lock, irqL);
1197 if ((check_fwstate(pmlmepriv, _FW_UNDER_SURVEY |
1198 _FW_UNDER_LINKING)) ||
1199 (pmlmepriv->sitesurveyctrl.traffic_busy == true)) {
1200 if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING))
1203 status = r8712_sitesurvey_cmd(padapter, &ssid);
1204 spin_unlock_irqrestore(&pmlmepriv->lock, irqL);
1207 status = r8712_set_802_11_bssid_list_scan(padapter);
1208 if (status == false)
1213 static int r8711_wx_get_scan(struct net_device *dev,
1214 struct iw_request_info *a,
1215 union iwreq_data *wrqu, char *extra)
1217 struct _adapter *padapter = (struct _adapter *)netdev_priv(dev);
1218 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1219 struct __queue *queue = &pmlmepriv->scanned_queue;
1220 struct wlan_network *pnetwork = NULL;
1222 struct list_head *plist, *phead;
1224 char *stop = ev + wrqu->data.length;
1225 u32 ret = 0, cnt = 0;
1227 if (padapter->bDriverStopped)
1229 while (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING)) {
1235 spin_lock_irqsave(&queue->lock, irqL);
1236 phead = get_list_head(queue);
1237 plist = get_next(phead);
1239 if (end_of_queue_search(phead, plist) == true)
1241 if ((stop - ev) < SCAN_ITEM_SIZE) {
1245 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
1246 ev = translate_scan(padapter, a, pnetwork, ev, stop);
1247 plist = get_next(plist);
1249 spin_unlock_irqrestore(&queue->lock, irqL);
1250 wrqu->data.length = ev - extra;
1251 wrqu->data.flags = 0;
1256 * s1. set_802_11_infrastructure_mode()
1257 * s2. set_802_11_authenticaion_mode()
1258 * s3. set_802_11_encryption_mode()
1259 * s4. set_802_11_ssid()
1261 * This function intends to handle the Set ESSID command.
1262 * Currently, the request comes via the Wireless Extensions' SIOCSIWESSID ioctl.
1264 * For this operation to succeed, there is no need for the interface to be Up.
1267 static int r8711_wx_set_essid(struct net_device *dev,
1268 struct iw_request_info *a,
1269 union iwreq_data *wrqu, char *extra)
1271 struct _adapter *padapter = (struct _adapter *)netdev_priv(dev);
1272 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1273 struct __queue *queue = &pmlmepriv->scanned_queue;
1274 struct wlan_network *pnetwork = NULL;
1275 enum NDIS_802_11_AUTHENTICATION_MODE authmode;
1276 struct ndis_802_11_ssid ndis_ssid;
1277 u8 *dst_ssid, *src_ssid;
1278 struct list_head *phead;
1281 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY))
1283 if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING))
1285 if (wrqu->essid.length > IW_ESSID_MAX_SIZE)
1287 authmode = padapter->securitypriv.ndisauthtype;
1288 if (wrqu->essid.flags && wrqu->essid.length) {
1289 len = (wrqu->essid.length < IW_ESSID_MAX_SIZE) ?
1290 wrqu->essid.length : IW_ESSID_MAX_SIZE;
1291 memset(&ndis_ssid, 0, sizeof(struct ndis_802_11_ssid));
1292 ndis_ssid.SsidLength = len;
1293 memcpy(ndis_ssid.Ssid, extra, len);
1294 src_ssid = ndis_ssid.Ssid;
1295 phead = get_list_head(queue);
1296 pmlmepriv->pscanned = get_next(phead);
1298 if (end_of_queue_search(phead, pmlmepriv->pscanned))
1300 pnetwork = LIST_CONTAINOR(pmlmepriv->pscanned,
1301 struct wlan_network, list);
1302 pmlmepriv->pscanned = get_next(pmlmepriv->pscanned);
1303 dst_ssid = pnetwork->network.Ssid.Ssid;
1304 if ((!memcmp(dst_ssid, src_ssid, ndis_ssid.SsidLength))
1305 && (pnetwork->network.Ssid.SsidLength ==
1306 ndis_ssid.SsidLength)) {
1307 if (check_fwstate(pmlmepriv,
1308 WIFI_ADHOC_STATE)) {
1309 if (pnetwork->network.
1313 cur_network.network.
1318 r8712_set_802_11_infrastructure_mode(
1320 pnetwork->network.InfrastructureMode);
1324 r8712_set_802_11_authentication_mode(padapter, authmode);
1325 r8712_set_802_11_ssid(padapter, &ndis_ssid);
1327 return -EINPROGRESS;
1330 static int r8711_wx_get_essid(struct net_device *dev,
1331 struct iw_request_info *a,
1332 union iwreq_data *wrqu, char *extra)
1334 struct _adapter *padapter = (struct _adapter *)netdev_priv(dev);
1335 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1336 struct ndis_wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
1339 if (check_fwstate(pmlmepriv, _FW_LINKED|WIFI_ADHOC_MASTER_STATE)) {
1340 len = pcur_bss->Ssid.SsidLength;
1341 wrqu->essid.length = len;
1342 memcpy(extra, pcur_bss->Ssid.Ssid, len);
1343 wrqu->essid.flags = 1;
1350 static int r8711_wx_set_rate(struct net_device *dev,
1351 struct iw_request_info *a,
1352 union iwreq_data *wrqu, char *extra)
1354 struct _adapter *padapter = (struct _adapter *)netdev_priv(dev);
1355 u32 target_rate = wrqu->bitrate.value;
1356 u32 fixed = wrqu->bitrate.fixed;
1358 u8 datarates[NumRates];
1359 u8 mpdatarate[NumRates] = {11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0xff};
1362 if (target_rate == -1) {
1366 target_rate = target_rate / 100000;
1367 switch (target_rate) {
1409 for (i = 0; i < NumRates; i++) {
1410 if (ratevalue == mpdatarate[i]) {
1411 datarates[i] = mpdatarate[i];
1415 datarates[i] = 0xff;
1417 if (r8712_setdatarate_cmd(padapter, datarates) != _SUCCESS)
1422 static int r8711_wx_get_rate(struct net_device *dev,
1423 struct iw_request_info *info,
1424 union iwreq_data *wrqu, char *extra)
1426 struct _adapter *padapter = (struct _adapter *)netdev_priv(dev);
1427 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1428 struct ndis_wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
1429 struct ieee80211_ht_cap *pht_capie;
1430 unsigned char rf_type = padapter->registrypriv.rf_config;
1433 u16 rate, max_rate = 0, ht_cap = false;
1435 u8 bw_40MHz = 0, short_GI = 0;
1439 if (check_fwstate(pmlmepriv, _FW_LINKED|WIFI_ADHOC_MASTER_STATE)) {
1440 p = r8712_get_ie(&pcur_bss->IEs[12],
1441 _HT_CAPABILITY_IE_, &ht_ielen,
1442 pcur_bss->IELength - 12);
1443 if (p && ht_ielen > 0) {
1445 pht_capie = (struct ieee80211_ht_cap *)(p + 2);
1446 memcpy(&mcs_rate , pht_capie->supp_mcs_set, 2);
1447 bw_40MHz = (pht_capie->cap_info &
1448 IEEE80211_HT_CAP_SUP_WIDTH) ? 1 : 0;
1449 short_GI = (pht_capie->cap_info &
1450 (IEEE80211_HT_CAP_SGI_20 |
1451 IEEE80211_HT_CAP_SGI_40)) ? 1 : 0;
1453 while ((pcur_bss->SupportedRates[i] != 0) &&
1454 (pcur_bss->SupportedRates[i] != 0xFF)) {
1455 rate = pcur_bss->SupportedRates[i] & 0x7F;
1456 if (rate > max_rate)
1458 wrqu->bitrate.fixed = 0; /* no auto select */
1459 wrqu->bitrate.value = rate*500000;
1462 if (ht_cap == true) {
1463 if (mcs_rate & 0x8000 /* MCS15 */
1465 RTL8712_RF_2T2R == rf_type)
1466 max_rate = (bw_40MHz) ? ((short_GI) ? 300 :
1467 270) : ((short_GI) ? 144 : 130);
1468 else if (mcs_rate & 0x0080) /* MCS7 */
1469 max_rate = (bw_40MHz) ? ((short_GI) ? 150 :
1470 135) : ((short_GI) ? 72 : 65);
1471 else /* default MCS7 */
1472 max_rate = (bw_40MHz) ? ((short_GI) ? 150 :
1473 135) : ((short_GI) ? 72 : 65);
1474 max_rate *= 2; /* Mbps/2 */
1475 wrqu->bitrate.value = max_rate * 500000;
1477 wrqu->bitrate.value = max_rate * 500000;
1484 static int r8711_wx_get_rts(struct net_device *dev,
1485 struct iw_request_info *info,
1486 union iwreq_data *wrqu, char *extra)
1488 struct _adapter *padapter = (struct _adapter *)netdev_priv(dev);
1490 wrqu->rts.value = padapter->registrypriv.rts_thresh;
1491 wrqu->rts.fixed = 0; /* no auto select */
1495 static int r8711_wx_set_frag(struct net_device *dev,
1496 struct iw_request_info *info,
1497 union iwreq_data *wrqu, char *extra)
1499 struct _adapter *padapter = (struct _adapter *)netdev_priv(dev);
1501 if (wrqu->frag.disabled)
1502 padapter->xmitpriv.frag_len = MAX_FRAG_THRESHOLD;
1504 if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
1505 wrqu->frag.value > MAX_FRAG_THRESHOLD)
1507 padapter->xmitpriv.frag_len = wrqu->frag.value & ~0x1;
1512 static int r8711_wx_get_frag(struct net_device *dev,
1513 struct iw_request_info *info,
1514 union iwreq_data *wrqu, char *extra)
1516 struct _adapter *padapter = (struct _adapter *) netdev_priv(dev);
1518 wrqu->frag.value = padapter->xmitpriv.frag_len;
1519 wrqu->frag.fixed = 0; /* no auto select */
1523 static int r8711_wx_get_retry(struct net_device *dev,
1524 struct iw_request_info *info,
1525 union iwreq_data *wrqu, char *extra)
1527 wrqu->retry.value = 7;
1528 wrqu->retry.fixed = 0; /* no auto select */
1529 wrqu->retry.disabled = 1;
1533 static int r8711_wx_set_enc(struct net_device *dev,
1534 struct iw_request_info *info,
1535 union iwreq_data *wrqu, char *keybuf)
1538 u32 keyindex_provided;
1539 struct NDIS_802_11_WEP wep;
1540 enum NDIS_802_11_AUTHENTICATION_MODE authmode;
1541 struct iw_point *erq = &(wrqu->encoding);
1542 struct _adapter *padapter = (struct _adapter *) netdev_priv(dev);
1544 key = erq->flags & IW_ENCODE_INDEX;
1545 memset(&wep, 0, sizeof(struct NDIS_802_11_WEP));
1546 if (erq->flags & IW_ENCODE_DISABLED) {
1547 netdev_info(dev, "r8712u: %s: EncryptionDisabled\n", __func__);
1548 padapter->securitypriv.ndisencryptstatus =
1549 Ndis802_11EncryptionDisabled;
1550 padapter->securitypriv.PrivacyAlgrthm = _NO_PRIVACY_;
1551 padapter->securitypriv.XGrpPrivacy = _NO_PRIVACY_;
1552 padapter->securitypriv.AuthAlgrthm = 0; /* open system */
1553 authmode = Ndis802_11AuthModeOpen;
1554 padapter->securitypriv.ndisauthtype = authmode;
1561 keyindex_provided = 1;
1563 keyindex_provided = 0;
1564 key = padapter->securitypriv.PrivacyKeyIndex;
1566 /* set authentication mode */
1567 if (erq->flags & IW_ENCODE_OPEN) {
1568 netdev_info(dev, "r8712u: %s: IW_ENCODE_OPEN\n", __func__);
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;
1576 } else if (erq->flags & IW_ENCODE_RESTRICTED) {
1577 netdev_info(dev, "r8712u: %s: IW_ENCODE_RESTRICTED\n", __func__);
1578 padapter->securitypriv.ndisencryptstatus =
1579 Ndis802_11Encryption1Enabled;
1580 padapter->securitypriv.AuthAlgrthm = 1; /* shared system */
1581 padapter->securitypriv.PrivacyAlgrthm = _WEP40_;
1582 padapter->securitypriv.XGrpPrivacy = _WEP40_;
1583 authmode = Ndis802_11AuthModeShared;
1584 padapter->securitypriv.ndisauthtype = authmode;
1586 padapter->securitypriv.ndisencryptstatus =
1587 Ndis802_11Encryption1Enabled;
1588 padapter->securitypriv.AuthAlgrthm = 0; /* open system */
1589 padapter->securitypriv.PrivacyAlgrthm = _NO_PRIVACY_;
1590 padapter->securitypriv.XGrpPrivacy = _NO_PRIVACY_;
1591 authmode = Ndis802_11AuthModeOpen;
1592 padapter->securitypriv.ndisauthtype = authmode;
1595 if (erq->length > 0) {
1596 wep.KeyLength = erq->length <= 5 ? 5 : 13;
1597 wep.Length = wep.KeyLength +
1598 FIELD_OFFSET(struct NDIS_802_11_WEP, KeyMaterial);
1601 if (keyindex_provided == 1) { /* set key_id only, no given
1602 * KeyMaterial(erq->length==0).*/
1603 padapter->securitypriv.PrivacyKeyIndex = key;
1604 switch (padapter->securitypriv.DefKeylen[key]) {
1606 padapter->securitypriv.PrivacyAlgrthm =
1610 padapter->securitypriv.PrivacyAlgrthm =
1614 padapter->securitypriv.PrivacyAlgrthm =
1621 wep.KeyIndex |= 0x80000000; /* transmit key */
1622 memcpy(wep.KeyMaterial, keybuf, wep.KeyLength);
1623 if (r8712_set_802_11_add_wep(padapter, &wep) == _FAIL)
1628 static int r8711_wx_get_enc(struct net_device *dev,
1629 struct iw_request_info *info,
1630 union iwreq_data *wrqu, char *keybuf)
1633 struct _adapter *padapter = (struct _adapter *) netdev_priv(dev);
1634 struct iw_point *erq = &(wrqu->encoding);
1635 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1637 if (check_fwstate(pmlmepriv, _FW_LINKED) == false) {
1638 if (!check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) {
1640 erq->flags |= IW_ENCODE_DISABLED;
1644 key = erq->flags & IW_ENCODE_INDEX;
1650 key = padapter->securitypriv.PrivacyKeyIndex;
1652 erq->flags = key + 1;
1653 switch (padapter->securitypriv.ndisencryptstatus) {
1654 case Ndis802_11EncryptionNotSupported:
1655 case Ndis802_11EncryptionDisabled:
1657 erq->flags |= IW_ENCODE_DISABLED;
1659 case Ndis802_11Encryption1Enabled:
1660 erq->length = padapter->securitypriv.DefKeylen[key];
1662 memcpy(keybuf, padapter->securitypriv.DefKey[
1663 key].skey, padapter->securitypriv.
1665 erq->flags |= IW_ENCODE_ENABLED;
1666 if (padapter->securitypriv.ndisauthtype ==
1667 Ndis802_11AuthModeOpen)
1668 erq->flags |= IW_ENCODE_OPEN;
1669 else if (padapter->securitypriv.ndisauthtype ==
1670 Ndis802_11AuthModeShared)
1671 erq->flags |= IW_ENCODE_RESTRICTED;
1674 erq->flags |= IW_ENCODE_DISABLED;
1677 case Ndis802_11Encryption2Enabled:
1678 case Ndis802_11Encryption3Enabled:
1680 erq->flags |= (IW_ENCODE_ENABLED | IW_ENCODE_OPEN |
1685 erq->flags |= IW_ENCODE_DISABLED;
1691 static int r8711_wx_get_power(struct net_device *dev,
1692 struct iw_request_info *info,
1693 union iwreq_data *wrqu, char *extra)
1695 wrqu->power.value = 0;
1696 wrqu->power.fixed = 0; /* no auto select */
1697 wrqu->power.disabled = 1;
1701 static int r871x_wx_set_gen_ie(struct net_device *dev,
1702 struct iw_request_info *info,
1703 union iwreq_data *wrqu, char *extra)
1705 struct _adapter *padapter = (struct _adapter *)netdev_priv(dev);
1707 return r871x_set_wpa_ie(padapter, extra, wrqu->data.length);
1710 static int r871x_wx_set_auth(struct net_device *dev,
1711 struct iw_request_info *info,
1712 union iwreq_data *wrqu, char *extra)
1714 struct _adapter *padapter = (struct _adapter *)netdev_priv(dev);
1715 struct iw_param *param = (struct iw_param *)&(wrqu->param);
1720 paramid = param->flags & IW_AUTH_INDEX;
1721 paramval = param->value;
1723 case IW_AUTH_WPA_VERSION:
1725 case IW_AUTH_CIPHER_PAIRWISE:
1727 case IW_AUTH_CIPHER_GROUP:
1729 case IW_AUTH_KEY_MGMT:
1731 * ??? does not use these parameters
1734 case IW_AUTH_TKIP_COUNTERMEASURES:
1736 /* wpa_supplicant is enabling tkip countermeasure. */
1737 padapter->securitypriv.btkip_countermeasure = true;
1739 /* wpa_supplicant is disabling tkip countermeasure. */
1740 padapter->securitypriv.btkip_countermeasure = false;
1743 case IW_AUTH_DROP_UNENCRYPTED:
1746 * wpa_supplicant calls set_wpa_enabled when the driver
1747 * is loaded and unloaded, regardless of if WPA is being
1748 * used. No other calls are made which can be used to
1749 * determine if encryption will be used or not prior to
1750 * association being expected. If encryption is not being
1751 * used, drop_unencrypted is set to false, else true -- we
1752 * can use this to determine if the CAP_PRIVACY_ON bit should
1755 if (padapter->securitypriv.ndisencryptstatus ==
1756 Ndis802_11Encryption1Enabled) {
1757 /* it means init value, or using wep,
1758 * ndisencryptstatus =
1759 * Ndis802_11Encryption1Enabled,
1760 * then it needn't reset it;
1766 padapter->securitypriv.ndisencryptstatus =
1767 Ndis802_11EncryptionDisabled;
1768 padapter->securitypriv.PrivacyAlgrthm =
1770 padapter->securitypriv.XGrpPrivacy =
1772 padapter->securitypriv.AuthAlgrthm = 0;
1773 padapter->securitypriv.ndisauthtype =
1774 Ndis802_11AuthModeOpen;
1777 case IW_AUTH_80211_AUTH_ALG:
1778 ret = wpa_set_auth_algs(dev, (u32)paramval);
1780 case IW_AUTH_WPA_ENABLED:
1782 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
1784 case IW_AUTH_PRIVACY_INVOKED:
1793 static int r871x_wx_set_enc_ext(struct net_device *dev,
1794 struct iw_request_info *info,
1795 union iwreq_data *wrqu, char *extra)
1797 struct iw_point *pencoding = &wrqu->encoding;
1798 struct iw_encode_ext *pext = (struct iw_encode_ext *)extra;
1799 struct ieee_param *param = NULL;
1804 param_len = sizeof(struct ieee_param) + pext->key_len;
1805 param = (struct ieee_param *)_malloc(param_len);
1808 memset(param, 0, param_len);
1809 param->cmd = IEEE_CMD_SET_ENCRYPTION;
1810 memset(param->sta_addr, 0xff, ETH_ALEN);
1811 switch (pext->alg) {
1812 case IW_ENCODE_ALG_NONE:
1815 case IW_ENCODE_ALG_WEP:
1818 case IW_ENCODE_ALG_TKIP:
1821 case IW_ENCODE_ALG_CCMP:
1827 strncpy((char *)param->u.crypt.alg, alg_name, IEEE_CRYPT_ALG_NAME_LEN);
1828 if (pext->ext_flags & IW_ENCODE_EXT_GROUP_KEY)
1829 param->u.crypt.set_tx = 0;
1830 if (pext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
1831 param->u.crypt.set_tx = 1;
1832 param->u.crypt.idx = (pencoding->flags & 0x00FF) - 1;
1833 if (pext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID)
1834 memcpy(param->u.crypt.seq, pext->rx_seq, 8);
1835 if (pext->key_len) {
1836 param->u.crypt.key_len = pext->key_len;
1837 memcpy(param + 1, pext + 1, pext->key_len);
1839 ret = wpa_set_encryption(dev, param, param_len);
1844 static int r871x_wx_get_nick(struct net_device *dev,
1845 struct iw_request_info *info,
1846 union iwreq_data *wrqu, char *extra)
1849 wrqu->data.length = 8;
1850 wrqu->data.flags = 1;
1851 memcpy(extra, "rtl_wifi", 8);
1856 static int r8711_wx_read32(struct net_device *dev,
1857 struct iw_request_info *info,
1858 union iwreq_data *wrqu, char *keybuf)
1860 struct _adapter *padapter = (struct _adapter *) netdev_priv(dev);
1864 get_user(addr, (u32 __user *)wrqu->data.pointer);
1865 data32 = r8712_read32(padapter, addr);
1866 put_user(data32, (u32 __user *)wrqu->data.pointer);
1867 wrqu->data.length = (data32 & 0xffff0000) >> 16;
1868 wrqu->data.flags = data32 & 0xffff;
1869 get_user(addr, (u32 __user *)wrqu->data.pointer);
1873 static int r8711_wx_write32(struct net_device *dev,
1874 struct iw_request_info *info,
1875 union iwreq_data *wrqu, char *keybuf)
1877 struct _adapter *padapter = (struct _adapter *) netdev_priv(dev);
1881 get_user(addr, (u32 __user *)wrqu->data.pointer);
1882 data32 = ((u32)wrqu->data.length<<16) | (u32)wrqu->data.flags;
1883 r8712_write32(padapter, addr, data32);
1887 static int dummy(struct net_device *dev,
1888 struct iw_request_info *a,
1889 union iwreq_data *wrqu, char *b)
1894 static int r8711_drvext_hdl(struct net_device *dev,
1895 struct iw_request_info *info,
1896 union iwreq_data *wrqu, char *extra)
1901 static int r871x_mp_ioctl_hdl(struct net_device *dev,
1902 struct iw_request_info *info,
1903 union iwreq_data *wrqu, char *extra)
1905 struct _adapter *padapter = (struct _adapter *)netdev_priv(dev);
1906 struct iw_point *p = &wrqu->data;
1907 struct oid_par_priv oid_par;
1908 struct mp_ioctl_handler *phandler;
1909 struct mp_ioctl_param *poidparam;
1910 unsigned long BytesRead, BytesWritten, BytesNeeded;
1911 u8 *pparmbuf = NULL, bset;
1916 if ((!p->length) || (!p->pointer)) {
1918 goto _r871x_mp_ioctl_hdl_exit;
1920 bset = (u8)(p->flags & 0xFFFF);
1923 pparmbuf = (u8 *)_malloc(len);
1924 if (pparmbuf == NULL) {
1926 goto _r871x_mp_ioctl_hdl_exit;
1928 if (copy_from_user(pparmbuf, p->pointer, len)) {
1930 goto _r871x_mp_ioctl_hdl_exit;
1932 poidparam = (struct mp_ioctl_param *)pparmbuf;
1933 if (poidparam->subcode >= MAX_MP_IOCTL_SUBCODE) {
1935 goto _r871x_mp_ioctl_hdl_exit;
1937 phandler = mp_ioctl_hdl + poidparam->subcode;
1938 if ((phandler->paramsize != 0) &&
1939 (poidparam->len < phandler->paramsize)) {
1941 goto _r871x_mp_ioctl_hdl_exit;
1943 if (phandler->oid == 0 && phandler->handler)
1944 status = phandler->handler(&oid_par);
1945 else if (phandler->handler) {
1946 oid_par.adapter_context = padapter;
1947 oid_par.oid = phandler->oid;
1948 oid_par.information_buf = poidparam->data;
1949 oid_par.information_buf_len = poidparam->len;
1954 oid_par.bytes_rw = &BytesRead;
1955 oid_par.bytes_needed = &BytesNeeded;
1956 oid_par.type_of_oid = SET_OID;
1958 oid_par.bytes_rw = &BytesWritten;
1959 oid_par.bytes_needed = &BytesNeeded;
1960 oid_par.type_of_oid = QUERY_OID;
1962 status = phandler->handler(&oid_par);
1963 /* todo:check status, BytesNeeded, etc. */
1965 netdev_info(dev, "r8712u: %s: err!, subcode=%d, oid=%d, handler=%p\n",
1966 __func__, poidparam->subcode, phandler->oid,
1969 goto _r871x_mp_ioctl_hdl_exit;
1971 if (bset == 0x00) { /* query info */
1972 if (copy_to_user(p->pointer, pparmbuf, len))
1977 goto _r871x_mp_ioctl_hdl_exit;
1979 _r871x_mp_ioctl_hdl_exit:
1984 static int r871x_get_ap_info(struct net_device *dev,
1985 struct iw_request_info *info,
1986 union iwreq_data *wrqu, char *extra)
1988 struct _adapter *padapter = (struct _adapter *)netdev_priv(dev);
1989 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1990 struct __queue *queue = &pmlmepriv->scanned_queue;
1991 struct iw_point *pdata = &wrqu->data;
1992 struct wlan_network *pnetwork = NULL;
1993 u32 cnt = 0, wpa_ielen;
1995 struct list_head *plist, *phead;
1996 unsigned char *pbuf;
2000 if (padapter->bDriverStopped || (pdata == NULL))
2002 while (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING)) {
2009 if (pdata->length >= 32) {
2010 if (copy_from_user(data, pdata->pointer, 32))
2014 spin_lock_irqsave(&(pmlmepriv->scanned_queue.lock), irqL);
2015 phead = get_list_head(queue);
2016 plist = get_next(phead);
2018 if (end_of_queue_search(phead, plist) == true)
2020 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
2021 if (hwaddr_aton_i(data, bssid)) {
2022 netdev_info(dev, "r8712u: Invalid BSSID '%s'.\n",
2024 spin_unlock_irqrestore(&(pmlmepriv->scanned_queue.lock),
2028 netdev_info(dev, "r8712u: BSSID:%pM\n", bssid);
2029 if (!memcmp(bssid, pnetwork->network.MacAddress, ETH_ALEN)) {
2030 /* BSSID match, then check if supporting wpa/wpa2 */
2031 pbuf = r8712_get_wpa_ie(&pnetwork->network.IEs[12],
2032 &wpa_ielen, pnetwork->network.IELength-12);
2033 if (pbuf && (wpa_ielen > 0)) {
2037 pbuf = r8712_get_wpa2_ie(&pnetwork->network.IEs[12],
2038 &wpa_ielen, pnetwork->network.IELength-12);
2039 if (pbuf && (wpa_ielen > 0)) {
2044 plist = get_next(plist);
2046 spin_unlock_irqrestore(&(pmlmepriv->scanned_queue.lock), irqL);
2047 if (pdata->length >= 34) {
2048 if (copy_to_user((u8 __user *)pdata->pointer + 32,
2049 (u8 *)&pdata->flags, 1))
2055 static int r871x_set_pid(struct net_device *dev,
2056 struct iw_request_info *info,
2057 union iwreq_data *wrqu, char *extra)
2059 struct _adapter *padapter = (struct _adapter *) netdev_priv(dev);
2060 struct iw_point *pdata = &wrqu->data;
2062 if ((padapter->bDriverStopped) || (pdata == NULL))
2064 if (copy_from_user(&padapter->pid, pdata->pointer, sizeof(int)))
2069 static int r871x_set_chplan(struct net_device *dev,
2070 struct iw_request_info *info,
2071 union iwreq_data *wrqu, char *extra)
2074 struct _adapter *padapter = (struct _adapter *) netdev_priv(dev);
2075 struct iw_point *pdata = &wrqu->data;
2078 if ((padapter->bDriverStopped) || (pdata == NULL)) {
2082 ch_plan = (int)*extra;
2083 r8712_set_chplan_cmd(padapter, ch_plan);
2090 static int r871x_wps_start(struct net_device *dev,
2091 struct iw_request_info *info,
2092 union iwreq_data *wrqu, char *extra)
2094 struct _adapter *padapter = (struct _adapter *)netdev_priv(dev);
2095 struct iw_point *pdata = &wrqu->data;
2096 u32 u32wps_start = 0;
2098 if ((padapter->bDriverStopped) || (pdata == NULL))
2100 if (copy_from_user((void *)&u32wps_start, pdata->pointer, 4))
2102 if (u32wps_start == 0)
2103 u32wps_start = *extra;
2104 if (u32wps_start == 1) /* WPS Start */
2105 padapter->ledpriv.LedControlHandler(padapter,
2107 else if (u32wps_start == 2) /* WPS Stop because of wps success */
2108 padapter->ledpriv.LedControlHandler(padapter,
2110 else if (u32wps_start == 3) /* WPS Stop because of wps fail */
2111 padapter->ledpriv.LedControlHandler(padapter,
2112 LED_CTL_STOP_WPS_FAIL);
2116 static int wpa_set_param(struct net_device *dev, u8 name, u32 value)
2118 struct _adapter *padapter = (struct _adapter *) netdev_priv(dev);
2121 case IEEE_PARAM_WPA_ENABLED:
2122 padapter->securitypriv.AuthAlgrthm = 2; /* 802.1x */
2123 switch ((value)&0xff) {
2125 padapter->securitypriv.ndisauthtype =
2126 Ndis802_11AuthModeWPAPSK; /* WPA_PSK */
2127 padapter->securitypriv.ndisencryptstatus =
2128 Ndis802_11Encryption2Enabled;
2131 padapter->securitypriv.ndisauthtype =
2132 Ndis802_11AuthModeWPA2PSK; /* WPA2_PSK */
2133 padapter->securitypriv.ndisencryptstatus =
2134 Ndis802_11Encryption3Enabled;
2138 case IEEE_PARAM_TKIP_COUNTERMEASURES:
2140 case IEEE_PARAM_DROP_UNENCRYPTED:
2143 * wpa_supplicant calls set_wpa_enabled when the driver
2144 * is loaded and unloaded, regardless of if WPA is being
2145 * used. No other calls are made which can be used to
2146 * determine if encryption will be used or not prior to
2147 * association being expected. If encryption is not being
2148 * used, drop_unencrypted is set to false, else true -- we
2149 * can use this to determine if the CAP_PRIVACY_ON bit should
2153 case IEEE_PARAM_PRIVACY_INVOKED:
2155 case IEEE_PARAM_AUTH_ALGS:
2156 return wpa_set_auth_algs(dev, value);
2158 case IEEE_PARAM_IEEE_802_1X:
2160 case IEEE_PARAM_WPAX_SELECT:
2161 /* added for WPA2 mixed mode */
2169 static int wpa_mlme(struct net_device *dev, u32 command, u32 reason)
2171 struct _adapter *padapter = (struct _adapter *) netdev_priv(dev);
2174 case IEEE_MLME_STA_DEAUTH:
2175 if (!r8712_set_802_11_disassociate(padapter))
2178 case IEEE_MLME_STA_DISASSOC:
2179 if (!r8712_set_802_11_disassociate(padapter))
2188 static int wpa_supplicant_ioctl(struct net_device *dev, struct iw_point *p)
2190 struct ieee_param *param;
2192 struct _adapter *padapter = (struct _adapter *) netdev_priv(dev);
2194 if (p->length < sizeof(struct ieee_param) || !p->pointer)
2196 param = (struct ieee_param *)_malloc(p->length);
2199 if (copy_from_user(param, p->pointer, p->length)) {
2203 switch (param->cmd) {
2204 case IEEE_CMD_SET_WPA_PARAM:
2205 ret = wpa_set_param(dev, param->u.wpa_param.name,
2206 param->u.wpa_param.value);
2208 case IEEE_CMD_SET_WPA_IE:
2209 ret = r871x_set_wpa_ie(padapter, (char *)param->u.wpa_ie.data,
2210 (u16)param->u.wpa_ie.len);
2212 case IEEE_CMD_SET_ENCRYPTION:
2213 ret = wpa_set_encryption(dev, param, p->length);
2216 ret = wpa_mlme(dev, param->u.mlme.command,
2217 param->u.mlme.reason_code);
2223 if (ret == 0 && copy_to_user(p->pointer, param, p->length))
2229 /* based on "driver_ipw" and for hostapd */
2230 int r871x_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
2232 struct iwreq *wrq = (struct iwreq *)rq;
2235 case RTL_IOCTL_WPA_SUPPLICANT:
2236 return wpa_supplicant_ioctl(dev, &wrq->u.data);
2243 static iw_handler r8711_handlers[] = {
2244 NULL, /* SIOCSIWCOMMIT */
2245 r8711_wx_get_name, /* SIOCGIWNAME */
2246 dummy, /* SIOCSIWNWID */
2247 dummy, /* SIOCGIWNWID */
2248 r8711_wx_set_freq, /* SIOCSIWFREQ */
2249 r8711_wx_get_freq, /* SIOCGIWFREQ */
2250 r8711_wx_set_mode, /* SIOCSIWMODE */
2251 r8711_wx_get_mode, /* SIOCGIWMODE */
2252 dummy, /* SIOCSIWSENS */
2253 r8711_wx_get_sens, /* SIOCGIWSENS */
2254 NULL, /* SIOCSIWRANGE */
2255 r8711_wx_get_range, /* SIOCGIWRANGE */
2256 r871x_wx_set_priv, /* SIOCSIWPRIV */
2257 NULL, /* SIOCGIWPRIV */
2258 NULL, /* SIOCSIWSTATS */
2259 NULL, /* SIOCGIWSTATS */
2260 dummy, /* SIOCSIWSPY */
2261 dummy, /* SIOCGIWSPY */
2262 NULL, /* SIOCGIWTHRSPY */
2263 NULL, /* SIOCWIWTHRSPY */
2264 r8711_wx_set_wap, /* SIOCSIWAP */
2265 r8711_wx_get_wap, /* SIOCGIWAP */
2266 r871x_wx_set_mlme, /* request MLME operation;
2267 * uses struct iw_mlme */
2268 dummy, /* SIOCGIWAPLIST -- deprecated */
2269 r8711_wx_set_scan, /* SIOCSIWSCAN */
2270 r8711_wx_get_scan, /* SIOCGIWSCAN */
2271 r8711_wx_set_essid, /* SIOCSIWESSID */
2272 r8711_wx_get_essid, /* SIOCGIWESSID */
2273 dummy, /* SIOCSIWNICKN */
2274 r871x_wx_get_nick, /* SIOCGIWNICKN */
2275 NULL, /* -- hole -- */
2276 NULL, /* -- hole -- */
2277 r8711_wx_set_rate, /* SIOCSIWRATE */
2278 r8711_wx_get_rate, /* SIOCGIWRATE */
2279 dummy, /* SIOCSIWRTS */
2280 r8711_wx_get_rts, /* SIOCGIWRTS */
2281 r8711_wx_set_frag, /* SIOCSIWFRAG */
2282 r8711_wx_get_frag, /* SIOCGIWFRAG */
2283 dummy, /* SIOCSIWTXPOW */
2284 dummy, /* SIOCGIWTXPOW */
2285 dummy, /* SIOCSIWRETRY */
2286 r8711_wx_get_retry, /* SIOCGIWRETRY */
2287 r8711_wx_set_enc, /* SIOCSIWENCODE */
2288 r8711_wx_get_enc, /* SIOCGIWENCODE */
2289 dummy, /* SIOCSIWPOWER */
2290 r8711_wx_get_power, /* SIOCGIWPOWER */
2291 NULL, /*---hole---*/
2292 NULL, /*---hole---*/
2293 r871x_wx_set_gen_ie, /* SIOCSIWGENIE */
2294 NULL, /* SIOCGIWGENIE */
2295 r871x_wx_set_auth, /* SIOCSIWAUTH */
2296 NULL, /* SIOCGIWAUTH */
2297 r871x_wx_set_enc_ext, /* SIOCSIWENCODEEXT */
2298 NULL, /* SIOCGIWENCODEEXT */
2299 r871x_wx_set_pmkid, /* SIOCSIWPMKSA */
2300 NULL, /*---hole---*/
2303 static const struct iw_priv_args r8711_private_args[] = {
2305 SIOCIWFIRSTPRIV + 0x0,
2306 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "read32"
2309 SIOCIWFIRSTPRIV + 0x1,
2310 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "write32"
2313 SIOCIWFIRSTPRIV + 0x2, 0, 0, "driver_ext"
2316 SIOCIWFIRSTPRIV + 0x3, 0, 0, "mp_ioctl"
2319 SIOCIWFIRSTPRIV + 0x4,
2320 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "apinfo"
2323 SIOCIWFIRSTPRIV + 0x5,
2324 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setpid"
2327 SIOCIWFIRSTPRIV + 0x6,
2328 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wps_start"
2331 SIOCIWFIRSTPRIV + 0x7,
2332 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "chplan"
2336 static iw_handler r8711_private_handler[] = {
2341 r871x_get_ap_info, /*for MM DTV platform*/
2347 static struct iw_statistics *r871x_get_wireless_stats(struct net_device *dev)
2349 struct _adapter *padapter = (struct _adapter *) netdev_priv(dev);
2350 struct iw_statistics *piwstats = &padapter->iwstats;
2355 if (check_fwstate(&padapter->mlmepriv, _FW_LINKED) != true) {
2356 piwstats->qual.qual = 0;
2357 piwstats->qual.level = 0;
2358 piwstats->qual.noise = 0;
2360 /* show percentage, we need transfer dbm to orignal value. */
2361 tmp_level = padapter->recvpriv.fw_rssi;
2362 tmp_qual = padapter->recvpriv.signal;
2363 tmp_noise = padapter->recvpriv.noise;
2364 piwstats->qual.level = tmp_level;
2365 piwstats->qual.qual = tmp_qual;
2366 piwstats->qual.noise = tmp_noise;
2368 piwstats->qual.updated = IW_QUAL_ALL_UPDATED;
2369 return &padapter->iwstats;
2372 struct iw_handler_def r871x_handlers_def = {
2373 .standard = r8711_handlers,
2374 .num_standard = ARRAY_SIZE(r8711_handlers),
2375 .private = r8711_private_handler,
2376 .private_args = (struct iw_priv_args *)r8711_private_args,
2377 .num_private = ARRAY_SIZE(r8711_private_handler),
2378 .num_private_args = sizeof(r8711_private_args) /
2379 sizeof(struct iw_priv_args),
2380 .get_wireless_stats = r871x_get_wireless_stats