1 /******************************************************************************
2 * rtl871x_ioctl_linux.c
4 * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
5 * Linux device driver for RTL8192SU
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of version 2 of the GNU General Public License as
9 * published by the Free Software Foundation.
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 * You should have received a copy of the GNU General Public License along with
17 * this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
20 * Modifications for inclusion into the Linux staging tree are
21 * Copyright(c) 2010 Larry Finger. All rights reserved.
23 * Contact information:
24 * WLAN FAE <wlanfae@realtek.com>
25 * Larry Finger <Larry.Finger@lwfinger.net>
27 ******************************************************************************/
29 #define _RTL871X_IOCTL_LINUX_C_
30 #define _RTL871X_MP_IOCTL_C_
32 #include "osdep_service.h"
33 #include "drv_types.h"
34 #include "wlan_bssdef.h"
35 #include "rtl871x_debug.h"
37 #include "rtl871x_mlme.h"
38 #include "rtl871x_ioctl.h"
39 #include "rtl871x_ioctl_set.h"
40 #include "rtl871x_mp_ioctl.h"
41 #include "mlme_osdep.h"
42 #include <linux/wireless.h>
43 #include <linux/module.h>
44 #include <linux/kernel.h>
46 #include <linux/semaphore.h>
47 #include <net/iw_handler.h>
48 #include <linux/if_arp.h>
49 #include <linux/etherdevice.h>
52 #define RTL_IOCTL_WPA_SUPPLICANT (SIOCIWFIRSTPRIV + 0x1E)
54 #define SCAN_ITEM_SIZE 768
55 #define MAX_CUSTOM_LEN 64
59 static const u32 rtl8180_rates[] = {1000000, 2000000, 5500000, 11000000,
60 6000000, 9000000, 12000000, 18000000,
61 24000000, 36000000, 48000000, 54000000};
63 static const long ieee80211_wlan_frequencies[] = {
64 2412, 2417, 2422, 2427,
65 2432, 2437, 2442, 2447,
66 2452, 2457, 2462, 2467,
70 static const char * const iw_operation_mode[] = {
71 "Auto", "Ad-Hoc", "Managed", "Master", "Repeater", "Secondary",
75 void r8712_indicate_wx_assoc_event(struct _adapter *padapter)
77 union iwreq_data wrqu;
78 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
80 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
81 memcpy(wrqu.ap_addr.sa_data, pmlmepriv->cur_network.network.MacAddress,
83 wireless_send_event(padapter->pnetdev, SIOCGIWAP, &wrqu, NULL);
86 void r8712_indicate_wx_disassoc_event(struct _adapter *padapter)
88 union iwreq_data wrqu;
90 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
91 eth_zero_addr(wrqu.ap_addr.sa_data);
92 wireless_send_event(padapter->pnetdev, SIOCGIWAP, &wrqu, NULL);
95 static inline void handle_pairwise_key(struct sta_info *psta,
96 struct ieee_param *param,
97 struct _adapter *padapter)
100 memcpy(psta->x_UncstKey.skey, param->u.crypt.key,
101 (param->u.crypt. key_len > 16 ? 16 : param->u.crypt.key_len));
102 if (strcmp(param->u.crypt.alg, "TKIP") == 0) { /* set mic key */
103 memcpy(psta->tkiptxmickey. skey, &(param->u.crypt.
105 memcpy(psta->tkiprxmickey. skey, &(param->u.crypt.
107 padapter->securitypriv. busetkipkey = false;
108 mod_timer(&padapter->securitypriv.tkip_timer,
109 jiffies + msecs_to_jiffies(50));
111 r8712_setstakey_cmd(padapter, (unsigned char *)psta, true);
114 static inline void handle_group_key(struct ieee_param *param,
115 struct _adapter *padapter)
117 if (param->u.crypt.idx > 0 &&
118 param->u.crypt.idx < 3) {
119 /* group key idx is 1 or 2 */
120 memcpy(padapter->securitypriv.XGrpKey[param->u.crypt.
121 idx - 1].skey, param->u.crypt.key,
122 (param->u.crypt.key_len > 16 ? 16 :
123 param->u.crypt.key_len));
124 memcpy(padapter->securitypriv.XGrptxmickey[param->
125 u.crypt.idx - 1].skey, &(param->u.crypt.key[16]), 8);
126 memcpy(padapter->securitypriv. XGrprxmickey[param->
127 u.crypt.idx - 1].skey, &(param->u.crypt.key[24]), 8);
128 padapter->securitypriv.binstallGrpkey = true;
129 r8712_set_key(padapter, &padapter->securitypriv,
131 if (padapter->registrypriv.power_mgnt > PS_MODE_ACTIVE) {
132 if (padapter->registrypriv.power_mgnt != padapter->
133 pwrctrlpriv.pwr_mode)
134 mod_timer(&padapter->mlmepriv.dhcp_timer,
135 jiffies + msecs_to_jiffies(60000));
140 static inline char *translate_scan(struct _adapter *padapter,
141 struct iw_request_info *info,
142 struct wlan_network *pnetwork,
143 char *start, char *stop)
146 struct ieee80211_ht_cap *pht_capie;
149 u32 i = 0, ht_ielen = 0;
150 u16 cap, ht_cap = false, mcs_rate;
153 if ((pnetwork->network.Configuration.DSConfig < 1) ||
154 (pnetwork->network.Configuration.DSConfig > 14)) {
155 if (pnetwork->network.Configuration.DSConfig < 1)
156 pnetwork->network.Configuration.DSConfig = 1;
158 pnetwork->network.Configuration.DSConfig = 14;
162 iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
163 ether_addr_copy(iwe.u.ap_addr.sa_data, pnetwork->network.MacAddress);
164 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_ADDR_LEN);
166 iwe.cmd = SIOCGIWESSID;
167 iwe.u.data.flags = 1;
168 iwe.u.data.length = min_t(u32, pnetwork->network.Ssid.SsidLength, 32);
169 start = iwe_stream_add_point(info, start, stop, &iwe,
170 pnetwork->network.Ssid.Ssid);
171 /* parsing HT_CAP_IE */
172 p = r8712_get_ie(&pnetwork->network.IEs[12], _HT_CAPABILITY_IE_,
173 &ht_ielen, pnetwork->network.IELength - 12);
174 if (p && ht_ielen > 0) {
176 pht_capie = (struct ieee80211_ht_cap *)(p + 2);
177 memcpy(&mcs_rate, pht_capie->supp_mcs_set, 2);
179 /* Add the protocol name */
180 iwe.cmd = SIOCGIWNAME;
181 if (r8712_is_cckratesonly_included(pnetwork->network.rates)) {
183 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bn");
185 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11b");
186 } else if (r8712_is_cckrates_included(pnetwork->network.rates)) {
188 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bgn");
190 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bg");
193 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11gn");
195 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11g");
197 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_CHAR_LEN);
199 iwe.cmd = SIOCGIWMODE;
200 memcpy((u8 *)&cap, r8712_get_capability_from_ie(pnetwork->network.IEs),
202 cap = le16_to_cpu(cap);
203 if (cap & (WLAN_CAPABILITY_IBSS | WLAN_CAPABILITY_BSS)) {
204 if (cap & WLAN_CAPABILITY_BSS)
205 iwe.u.mode = (u32)IW_MODE_MASTER;
207 iwe.u.mode = (u32)IW_MODE_ADHOC;
208 start = iwe_stream_add_event(info, start, stop, &iwe,
211 /* Add frequency/channel */
212 iwe.cmd = SIOCGIWFREQ;
214 /* check legal index */
215 u8 dsconfig = pnetwork->network.Configuration.DSConfig;
217 if (dsconfig >= 1 && dsconfig <= sizeof(
218 ieee80211_wlan_frequencies) / sizeof(long))
219 iwe.u.freq.m = (s32)(ieee80211_wlan_frequencies[
220 pnetwork->network.Configuration.
221 DSConfig - 1] * 100000);
225 iwe.u.freq.e = (s16)1;
226 iwe.u.freq.i = (u8)pnetwork->network.Configuration.DSConfig;
227 start = iwe_stream_add_event(info, start, stop, &iwe,
229 /* Add encryption capability */
230 iwe.cmd = SIOCGIWENCODE;
231 if (cap & WLAN_CAPABILITY_PRIVACY)
232 iwe.u.data.flags = (u16)(IW_ENCODE_ENABLED |
235 iwe.u.data.flags = (u16)(IW_ENCODE_DISABLED);
236 iwe.u.data.length = (u16)0;
237 start = iwe_stream_add_point(info, start, stop, &iwe,
238 pnetwork->network.Ssid.Ssid);
239 /*Add basic and extended rates */
240 current_val = start + iwe_stream_lcp_len(info);
241 iwe.cmd = SIOCGIWRATE;
242 iwe.u.bitrate.fixed = 0;
243 iwe.u.bitrate.disabled = 0;
244 iwe.u.bitrate.value = 0;
246 while (pnetwork->network.rates[i] != 0) {
247 /* Bit rate given in 500 kb/s units */
248 iwe.u.bitrate.value = (pnetwork->network.rates[i++] &
250 current_val = iwe_stream_add_value(info, start, current_val,
251 stop, &iwe, IW_EV_PARAM_LEN);
253 /* Check if we added any event */
254 if ((current_val - start) > iwe_stream_lcp_len(info))
256 /* parsing WPA/WPA2 IE */
258 u8 buf[MAX_WPA_IE_LEN];
259 u8 wpa_ie[255], rsn_ie[255];
260 u16 wpa_len = 0, rsn_len = 0;
263 r8712_get_sec_ie(pnetwork->network.IEs,
264 pnetwork->network.IELength, rsn_ie, &rsn_len,
267 memset(buf, 0, MAX_WPA_IE_LEN);
268 n = sprintf(buf, "wpa_ie=");
269 for (i = 0; i < wpa_len; i++) {
270 n += snprintf(buf + n, MAX_WPA_IE_LEN - n,
272 if (n >= MAX_WPA_IE_LEN)
275 memset(&iwe, 0, sizeof(iwe));
276 iwe.cmd = IWEVCUSTOM;
277 iwe.u.data.length = (u16)strlen(buf);
278 start = iwe_stream_add_point(info, start, stop,
280 memset(&iwe, 0, sizeof(iwe));
282 iwe.u.data.length = (u16)wpa_len;
283 start = iwe_stream_add_point(info, start, stop,
287 memset(buf, 0, MAX_WPA_IE_LEN);
288 n = sprintf(buf, "rsn_ie=");
289 for (i = 0; i < rsn_len; i++) {
290 n += snprintf(buf + n, MAX_WPA_IE_LEN - n,
292 if (n >= MAX_WPA_IE_LEN)
295 memset(&iwe, 0, sizeof(iwe));
296 iwe.cmd = IWEVCUSTOM;
297 iwe.u.data.length = strlen(buf);
298 start = iwe_stream_add_point(info, start, stop,
300 memset(&iwe, 0, sizeof(iwe));
302 iwe.u.data.length = rsn_len;
303 start = iwe_stream_add_point(info, start, stop, &iwe,
308 { /* parsing WPS IE */
312 if (r8712_get_wps_ie(pnetwork->network.IEs,
313 pnetwork->network.IELength,
314 wps_ie, &wps_ielen)) {
317 iwe.u.data.length = (u16)wps_ielen;
318 start = iwe_stream_add_point(info, start, stop,
323 /* Add quality statistics */
325 rssi = r8712_signal_scale_mapping(pnetwork->network.Rssi);
326 /* we only update signal_level (signal strength) that is rssi. */
327 iwe.u.qual.updated = (u8)(IW_QUAL_QUAL_INVALID | IW_QUAL_LEVEL_UPDATED |
328 IW_QUAL_NOISE_INVALID);
329 iwe.u.qual.level = rssi; /* signal strength */
330 iwe.u.qual.qual = 0; /* signal quality */
331 iwe.u.qual.noise = 0; /* noise level */
332 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_QUAL_LEN);
333 /* how to translate rssi to ?% */
337 static int wpa_set_auth_algs(struct net_device *dev, u32 value)
339 struct _adapter *padapter = netdev_priv(dev);
342 if ((value & AUTH_ALG_SHARED_KEY) && (value & AUTH_ALG_OPEN_SYSTEM)) {
343 padapter->securitypriv.ndisencryptstatus =
344 Ndis802_11Encryption1Enabled;
345 padapter->securitypriv.ndisauthtype =
346 Ndis802_11AuthModeAutoSwitch;
347 padapter->securitypriv.AuthAlgrthm = 3;
348 } else if (value & AUTH_ALG_SHARED_KEY) {
349 padapter->securitypriv.ndisencryptstatus =
350 Ndis802_11Encryption1Enabled;
351 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeShared;
352 padapter->securitypriv.AuthAlgrthm = 1;
353 } else if (value & AUTH_ALG_OPEN_SYSTEM) {
354 if (padapter->securitypriv.ndisauthtype <
355 Ndis802_11AuthModeWPAPSK) {
356 padapter->securitypriv.ndisauthtype =
357 Ndis802_11AuthModeOpen;
358 padapter->securitypriv.AuthAlgrthm = 0;
366 static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param,
370 u32 wep_key_idx, wep_key_len = 0;
371 struct NDIS_802_11_WEP *pwep = NULL;
372 struct _adapter *padapter = netdev_priv(dev);
373 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
374 struct security_priv *psecuritypriv = &padapter->securitypriv;
376 param->u.crypt.err = 0;
377 param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
378 if (param_len != (u32)((u8 *) param->u.crypt.key - (u8 *)param) +
379 param->u.crypt.key_len)
381 if (is_broadcast_ether_addr(param->sta_addr)) {
382 if (param->u.crypt.idx >= WEP_KEYS) {
383 /* for large key indices, set the default (0) */
384 param->u.crypt.idx = 0;
389 if (strcmp(param->u.crypt.alg, "WEP") == 0) {
390 netdev_info(dev, "r8712u: %s: crypt.alg = WEP\n", __func__);
391 padapter->securitypriv.ndisencryptstatus =
392 Ndis802_11Encryption1Enabled;
393 padapter->securitypriv.PrivacyAlgrthm = _WEP40_;
394 padapter->securitypriv.XGrpPrivacy = _WEP40_;
395 wep_key_idx = param->u.crypt.idx;
396 wep_key_len = param->u.crypt.key_len;
397 if (wep_key_idx >= WEP_KEYS)
399 if (wep_key_len > 0) {
400 wep_key_len = wep_key_len <= 5 ? 5 : 13;
401 pwep = kmalloc((u32)(wep_key_len +
402 FIELD_OFFSET(struct NDIS_802_11_WEP,
403 KeyMaterial)), GFP_ATOMIC);
406 memset(pwep, 0, sizeof(struct NDIS_802_11_WEP));
407 pwep->KeyLength = wep_key_len;
408 pwep->Length = wep_key_len +
409 FIELD_OFFSET(struct NDIS_802_11_WEP,
411 if (wep_key_len == 13) {
412 padapter->securitypriv.PrivacyAlgrthm =
414 padapter->securitypriv.XGrpPrivacy =
420 pwep->KeyIndex = wep_key_idx;
421 pwep->KeyIndex |= 0x80000000;
422 memcpy(pwep->KeyMaterial, param->u.crypt.key, pwep->KeyLength);
423 if (param->u.crypt.set_tx) {
424 if (r8712_set_802_11_add_wep(padapter, pwep) ==
428 /* don't update "psecuritypriv->PrivacyAlgrthm" and
429 * "psecuritypriv->PrivacyKeyIndex=keyid", but can
430 * r8712_set_key to fw/cam
432 if (wep_key_idx >= WEP_KEYS) {
436 memcpy(&(psecuritypriv->DefKey[wep_key_idx].
437 skey[0]), pwep->KeyMaterial,
439 psecuritypriv->DefKeylen[wep_key_idx] =
441 r8712_set_key(padapter, psecuritypriv, wep_key_idx);
445 if (padapter->securitypriv.AuthAlgrthm == 2) { /* 802_1x */
446 struct sta_info *psta, *pbcmc_sta;
447 struct sta_priv *pstapriv = &padapter->stapriv;
449 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE |
450 WIFI_MP_STATE)) { /* sta mode */
451 psta = r8712_get_stainfo(pstapriv,
452 get_bssid(pmlmepriv));
454 psta->ieee8021x_blocked = false;
455 if ((padapter->securitypriv.ndisencryptstatus ==
456 Ndis802_11Encryption2Enabled) ||
457 (padapter->securitypriv.ndisencryptstatus ==
458 Ndis802_11Encryption3Enabled))
459 psta->XPrivacy = padapter->
460 securitypriv.PrivacyAlgrthm;
461 if (param->u.crypt.set_tx == 1)
462 handle_pairwise_key(psta, param,
465 handle_group_key(param, padapter);
467 pbcmc_sta = r8712_get_bcmc_stainfo(padapter);
469 pbcmc_sta->ieee8021x_blocked = false;
470 if ((padapter->securitypriv.ndisencryptstatus ==
471 Ndis802_11Encryption2Enabled) ||
472 (padapter->securitypriv.ndisencryptstatus ==
473 Ndis802_11Encryption3Enabled))
474 pbcmc_sta->XPrivacy =
475 padapter->securitypriv.
485 static int r871x_set_wpa_ie(struct _adapter *padapter, char *pie,
486 unsigned short ielen)
489 int group_cipher = 0, pairwise_cipher = 0;
492 if ((ielen > MAX_WPA_IE_LEN) || (pie == NULL))
495 buf = kmemdup(pie, ielen, GFP_ATOMIC);
498 if (ielen < RSN_HEADER_LEN) {
502 if (r8712_parse_wpa_ie(buf, ielen, &group_cipher,
503 &pairwise_cipher) == _SUCCESS) {
504 padapter->securitypriv.AuthAlgrthm = 2;
505 padapter->securitypriv.ndisauthtype =
506 Ndis802_11AuthModeWPAPSK;
508 if (r8712_parse_wpa2_ie(buf, ielen, &group_cipher,
509 &pairwise_cipher) == _SUCCESS) {
510 padapter->securitypriv.AuthAlgrthm = 2;
511 padapter->securitypriv.ndisauthtype =
512 Ndis802_11AuthModeWPA2PSK;
514 switch (group_cipher) {
515 case WPA_CIPHER_NONE:
516 padapter->securitypriv.XGrpPrivacy =
518 padapter->securitypriv.ndisencryptstatus =
519 Ndis802_11EncryptionDisabled;
521 case WPA_CIPHER_WEP40:
522 padapter->securitypriv.XGrpPrivacy = _WEP40_;
523 padapter->securitypriv.ndisencryptstatus =
524 Ndis802_11Encryption1Enabled;
526 case WPA_CIPHER_TKIP:
527 padapter->securitypriv.XGrpPrivacy = _TKIP_;
528 padapter->securitypriv.ndisencryptstatus =
529 Ndis802_11Encryption2Enabled;
531 case WPA_CIPHER_CCMP:
532 padapter->securitypriv.XGrpPrivacy = _AES_;
533 padapter->securitypriv.ndisencryptstatus =
534 Ndis802_11Encryption3Enabled;
536 case WPA_CIPHER_WEP104:
537 padapter->securitypriv.XGrpPrivacy = _WEP104_;
538 padapter->securitypriv.ndisencryptstatus =
539 Ndis802_11Encryption1Enabled;
542 switch (pairwise_cipher) {
543 case WPA_CIPHER_NONE:
544 padapter->securitypriv.PrivacyAlgrthm =
546 padapter->securitypriv.ndisencryptstatus =
547 Ndis802_11EncryptionDisabled;
549 case WPA_CIPHER_WEP40:
550 padapter->securitypriv.PrivacyAlgrthm = _WEP40_;
551 padapter->securitypriv.ndisencryptstatus =
552 Ndis802_11Encryption1Enabled;
554 case WPA_CIPHER_TKIP:
555 padapter->securitypriv.PrivacyAlgrthm = _TKIP_;
556 padapter->securitypriv.ndisencryptstatus =
557 Ndis802_11Encryption2Enabled;
559 case WPA_CIPHER_CCMP:
560 padapter->securitypriv.PrivacyAlgrthm = _AES_;
561 padapter->securitypriv.ndisencryptstatus =
562 Ndis802_11Encryption3Enabled;
564 case WPA_CIPHER_WEP104:
565 padapter->securitypriv.PrivacyAlgrthm = _WEP104_;
566 padapter->securitypriv.ndisencryptstatus =
567 Ndis802_11Encryption1Enabled;
570 padapter->securitypriv.wps_phase = false;
573 u8 eid, wps_oui[4] = {0x0, 0x50, 0xf2, 0x04};
575 while (cnt < ielen) {
578 if ((eid == _VENDOR_SPECIFIC_IE_) &&
579 (!memcmp(&buf[cnt + 2], wps_oui, 4))) {
580 netdev_info(padapter->pnetdev, "r8712u: SET WPS_IE\n");
581 padapter->securitypriv.wps_ie_len =
582 ((buf[cnt + 1] + 2) <
583 (MAX_WPA_IE_LEN << 2)) ?
585 (MAX_WPA_IE_LEN << 2);
586 memcpy(padapter->securitypriv.wps_ie,
588 padapter->securitypriv.wps_ie_len);
589 padapter->securitypriv.wps_phase =
591 netdev_info(padapter->pnetdev, "r8712u: SET WPS_IE, wps_phase==true\n");
592 cnt += buf[cnt + 1] + 2;
595 cnt += buf[cnt + 1] + 2;
605 static int r8711_wx_get_name(struct net_device *dev,
606 struct iw_request_info *info,
607 union iwreq_data *wrqu, char *extra)
609 struct _adapter *padapter = netdev_priv(dev);
613 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
614 struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
617 if (check_fwstate(pmlmepriv, _FW_LINKED | WIFI_ADHOC_MASTER_STATE) ==
619 /* parsing HT_CAP_IE */
620 p = r8712_get_ie(&pcur_bss->IEs[12], _HT_CAPABILITY_IE_,
621 &ht_ielen, pcur_bss->IELength - 12);
622 if (p && ht_ielen > 0)
624 prates = pcur_bss->rates;
625 if (r8712_is_cckratesonly_included(prates)) {
627 snprintf(wrqu->name, IFNAMSIZ,
630 snprintf(wrqu->name, IFNAMSIZ,
632 } else if (r8712_is_cckrates_included(prates)) {
634 snprintf(wrqu->name, IFNAMSIZ,
637 snprintf(wrqu->name, IFNAMSIZ,
641 snprintf(wrqu->name, IFNAMSIZ,
644 snprintf(wrqu->name, IFNAMSIZ,
648 snprintf(wrqu->name, IFNAMSIZ, "unassociated");
653 static const long frequency_list[] = {
654 2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447, 2452, 2457, 2462,
655 2467, 2472, 2484, 4915, 4920, 4925, 4935, 4940, 4945, 4960, 4980,
656 5035, 5040, 5045, 5055, 5060, 5080, 5170, 5180, 5190, 5200, 5210,
657 5220, 5230, 5240, 5260, 5280, 5300, 5320, 5500, 5520, 5540, 5560,
658 5580, 5600, 5620, 5640, 5660, 5680, 5700, 5745, 5765, 5785, 5805,
662 static int r8711_wx_set_freq(struct net_device *dev,
663 struct iw_request_info *info,
664 union iwreq_data *wrqu, char *extra)
666 struct _adapter *padapter = netdev_priv(dev);
667 struct iw_freq *fwrq = &wrqu->freq;
670 /* If setting by frequency, convert to a channel */
671 if ((fwrq->e == 1) &&
672 (fwrq->m >= (int) 2.412e8) &&
673 (fwrq->m <= (int) 2.487e8)) {
674 int f = fwrq->m / 100000;
677 while ((c < 14) && (f != frequency_list[c]))
682 /* Setting by channel number */
683 if ((fwrq->m > 14) || (fwrq->e > 0)) {
686 int channel = fwrq->m;
688 if ((channel < 1) || (channel > 14)) {
691 /* Yes ! We can set it !!! */
692 padapter->registrypriv.channel = channel;
698 static int r8711_wx_get_freq(struct net_device *dev,
699 struct iw_request_info *info,
700 union iwreq_data *wrqu, char *extra)
702 struct _adapter *padapter = netdev_priv(dev);
703 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
704 struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
706 if (check_fwstate(pmlmepriv, _FW_LINKED)) {
707 wrqu->freq.m = ieee80211_wlan_frequencies[
708 pcur_bss->Configuration.DSConfig - 1] * 100000;
710 wrqu->freq.i = pcur_bss->Configuration.DSConfig;
717 static int r8711_wx_set_mode(struct net_device *dev,
718 struct iw_request_info *a,
719 union iwreq_data *wrqu, char *b)
721 struct _adapter *padapter = netdev_priv(dev);
722 enum NDIS_802_11_NETWORK_INFRASTRUCTURE networkType;
724 switch (wrqu->mode) {
726 networkType = Ndis802_11AutoUnknown;
729 networkType = Ndis802_11IBSS;
732 networkType = Ndis802_11APMode;
735 networkType = Ndis802_11Infrastructure;
740 if (Ndis802_11APMode == networkType)
741 r8712_setopmode_cmd(padapter, networkType);
743 r8712_setopmode_cmd(padapter, Ndis802_11AutoUnknown);
745 r8712_set_802_11_infrastructure_mode(padapter, networkType);
749 static int r8711_wx_get_mode(struct net_device *dev, struct iw_request_info *a,
750 union iwreq_data *wrqu, char *b)
752 struct _adapter *padapter = netdev_priv(dev);
753 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
755 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE))
756 wrqu->mode = IW_MODE_INFRA;
757 else if (check_fwstate(pmlmepriv,
758 WIFI_ADHOC_MASTER_STATE | WIFI_ADHOC_STATE))
759 wrqu->mode = IW_MODE_ADHOC;
760 else if (check_fwstate(pmlmepriv, WIFI_AP_STATE))
761 wrqu->mode = IW_MODE_MASTER;
763 wrqu->mode = IW_MODE_AUTO;
767 static int r871x_wx_set_pmkid(struct net_device *dev,
768 struct iw_request_info *a,
769 union iwreq_data *wrqu, char *extra)
771 struct _adapter *padapter = netdev_priv(dev);
772 struct security_priv *psecuritypriv = &padapter->securitypriv;
773 struct iw_pmksa *pPMK = (struct iw_pmksa *) extra;
774 u8 strZeroMacAddress[ETH_ALEN] = {0x00};
775 u8 strIssueBssid[ETH_ALEN] = {0x00};
776 u8 j, blInserted = false;
777 int intReturn = false;
780 * There are the BSSID information in the bssid.sa_data array.
781 * If cmd is IW_PMKSA_FLUSH, it means the wpa_supplicant wants to clear
782 * all the PMKID information. If cmd is IW_PMKSA_ADD, it means the
783 * wpa_supplicant wants to add a PMKID/BSSID to driver.
784 * If cmd is IW_PMKSA_REMOVE, it means the wpa_supplicant wants to
785 * remove a PMKID/BSSID from driver.
789 memcpy(strIssueBssid, pPMK->bssid.sa_data, ETH_ALEN);
792 if (!memcmp(strIssueBssid, strZeroMacAddress, ETH_ALEN))
796 /* overwrite PMKID */
797 for (j = 0; j < NUM_PMKID_CACHE; j++) {
798 if (!memcmp(psecuritypriv->PMKIDList[j].Bssid,
799 strIssueBssid, ETH_ALEN)) {
800 /* BSSID is matched, the same AP => rewrite
803 netdev_info(dev, "r8712u: %s: BSSID exists in the PMKList.\n",
805 memcpy(psecuritypriv->PMKIDList[j].PMKID,
806 pPMK->pmkid, IW_PMKID_LEN);
807 psecuritypriv->PMKIDList[j].bUsed = true;
808 psecuritypriv->PMKIDIndex = j + 1;
814 /* Find a new entry */
815 netdev_info(dev, "r8712u: %s: Use the new entry index = %d for this PMKID.\n",
816 __func__, psecuritypriv->PMKIDIndex);
817 memcpy(psecuritypriv->PMKIDList[psecuritypriv->
818 PMKIDIndex].Bssid, strIssueBssid, ETH_ALEN);
819 memcpy(psecuritypriv->PMKIDList[psecuritypriv->
820 PMKIDIndex].PMKID, pPMK->pmkid, IW_PMKID_LEN);
821 psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].
823 psecuritypriv->PMKIDIndex++;
824 if (psecuritypriv->PMKIDIndex == NUM_PMKID_CACHE)
825 psecuritypriv->PMKIDIndex = 0;
828 case IW_PMKSA_REMOVE:
830 for (j = 0; j < NUM_PMKID_CACHE; j++) {
831 if (!memcmp(psecuritypriv->PMKIDList[j].Bssid,
832 strIssueBssid, ETH_ALEN)) {
833 /* BSSID is matched, the same AP => Remove
834 * this PMKID information and reset it.
836 eth_zero_addr(psecuritypriv->PMKIDList[j].Bssid);
837 psecuritypriv->PMKIDList[j].bUsed = false;
843 memset(psecuritypriv->PMKIDList, 0,
844 sizeof(struct RT_PMKID_LIST) * NUM_PMKID_CACHE);
845 psecuritypriv->PMKIDIndex = 0;
849 netdev_info(dev, "r8712u: %s: unknown Command\n", __func__);
856 static int r8711_wx_get_sens(struct net_device *dev,
857 struct iw_request_info *info,
858 union iwreq_data *wrqu, char *extra)
860 wrqu->sens.value = 0;
861 wrqu->sens.fixed = 0; /* no auto select */
862 wrqu->sens.disabled = 1;
866 static int r8711_wx_get_range(struct net_device *dev,
867 struct iw_request_info *info,
868 union iwreq_data *wrqu, char *extra)
870 struct iw_range *range = (struct iw_range *)extra;
874 wrqu->data.length = sizeof(*range);
875 memset(range, 0, sizeof(*range));
876 /* Let's try to keep this struct in the same order as in
877 * linux/include/wireless.h
880 /* TODO: See what values we can set, and remove the ones we can't
881 * set, or fill them with some default data.
883 /* ~5 Mb/s real (802.11b) */
884 range->throughput = 5 * 1000 * 1000;
885 /* TODO: 8711 sensitivity ? */
886 /* signal level threshold range */
887 /* percent values between 0 and 100. */
888 range->max_qual.qual = 100;
889 range->max_qual.level = 100;
890 range->max_qual.noise = 100;
891 range->max_qual.updated = 7; /* Updated all three */
892 range->avg_qual.qual = 92; /* > 8% missed beacons is 'bad' */
893 /* TODO: Find real 'good' to 'bad' threshold value for RSSI */
894 range->avg_qual.level = 0x100 - 78;
895 range->avg_qual.noise = 0;
896 range->avg_qual.updated = 7; /* Updated all three */
897 range->num_bitrates = RATE_COUNT;
898 for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++)
899 range->bitrate[i] = rtl8180_rates[i];
900 range->min_frag = MIN_FRAG_THRESHOLD;
901 range->max_frag = MAX_FRAG_THRESHOLD;
903 range->we_version_compiled = WIRELESS_EXT;
904 range->we_version_source = 16;
905 range->num_channels = 14;
906 for (i = 0, val = 0; i < 14; i++) {
907 /* Include only legal frequencies for some countries */
908 range->freq[val].i = i + 1;
909 range->freq[val].m = ieee80211_wlan_frequencies[i] * 100000;
910 range->freq[val].e = 1;
912 if (val == IW_MAX_FREQUENCIES)
915 range->num_frequency = val;
916 range->enc_capa = IW_ENC_CAPA_WPA |
918 IW_ENC_CAPA_CIPHER_TKIP |
919 IW_ENC_CAPA_CIPHER_CCMP;
923 static int r8711_wx_get_rate(struct net_device *dev,
924 struct iw_request_info *info,
925 union iwreq_data *wrqu, char *extra);
927 static int r871x_wx_set_priv(struct net_device *dev,
928 struct iw_request_info *info,
929 union iwreq_data *awrq,
932 int ret = 0, len = 0;
934 struct _adapter *padapter = netdev_priv(dev);
935 struct iw_point *dwrq = (struct iw_point *)awrq;
938 ext = memdup_user(dwrq->pointer, len);
942 if (!strcasecmp(ext, "RSSI")) {
943 /*Return received signal strength indicator in -db for */
946 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
947 struct wlan_network *pcur_network = &pmlmepriv->cur_network;
949 if (check_fwstate(pmlmepriv, _FW_LINKED)) {
950 sprintf(ext, "%s rssi %d",
951 pcur_network->network.Ssid.Ssid,
953 ((padapter->recvpriv.fw_rssi) >> 1) - 95
954 /*pcur_network->network.Rssi */
959 } else if (!strcasecmp(ext, "LINKSPEED")) {
960 /*Return link speed in MBPS */
962 union iwreq_data wrqd;
966 ret_inner = r8711_wx_get_rate(dev, info, &wrqd, extra);
970 mbps = wrqd.bitrate.value / 1000000;
971 sprintf(ext, "LINKSPEED %d", mbps);
972 } else if (!strcasecmp(ext, "MACADDR")) {
973 /*Return mac address of the station */
974 /* Macaddr = xx:xx:xx:xx:xx:xx */
975 sprintf(ext, "MACADDR = %pM", dev->dev_addr);
976 } else if (!strcasecmp(ext, "SCAN-ACTIVE")) {
977 /*Set scan type to active */
978 /*OK if successful */
979 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
981 pmlmepriv->passive_mode = 1;
983 } else if (!strcasecmp(ext, "SCAN-PASSIVE")) {
984 /*Set scan type to passive */
985 /*OK if successful */
986 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
988 pmlmepriv->passive_mode = 0;
990 } else if (!strncmp(ext, "DCE-E", 5)) {
991 /*Set scan type to passive */
992 /*OK if successful */
993 r8712_disconnectCtrlEx_cmd(padapter
994 , 1 /*u32 enableDrvCtrl */
995 , 5 /*u32 tryPktCnt */
996 , 100 /*u32 tryPktInterval */
997 , 5000 /*u32 firstStageTO */
1000 } else if (!strncmp(ext, "DCE-D", 5)) {
1001 /*Set scan type to passive */
1002 /*OK if successfu */
1003 r8712_disconnectCtrlEx_cmd(padapter
1004 , 0 /*u32 enableDrvCtrl */
1005 , 5 /*u32 tryPktCnt */
1006 , 100 /*u32 tryPktInterval */
1007 , 5000 /*u32 firstStageTO */
1011 netdev_info(dev, "r8712u: %s: unknown Command %s.\n",
1015 if (copy_to_user(dwrq->pointer, ext,
1016 min(dwrq->length, (__u16)(strlen(ext) + 1))))
1025 * s1. set_802_11_infrastructure_mode()
1026 * s2. set_802_11_authentication_mode()
1027 * s3. set_802_11_encryption_mode()
1028 * s4. set_802_11_bssid()
1030 * This function intends to handle the Set AP command, which specifies the
1031 * MAC# of a preferred Access Point.
1032 * Currently, the request comes via Wireless Extensions' SIOCSIWAP ioctl.
1034 * For this operation to succeed, there is no need for the interface to be up.
1037 static int r8711_wx_set_wap(struct net_device *dev,
1038 struct iw_request_info *info,
1039 union iwreq_data *awrq,
1042 int ret = -EINPROGRESS;
1043 struct _adapter *padapter = netdev_priv(dev);
1044 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1045 struct __queue *queue = &pmlmepriv->scanned_queue;
1046 struct sockaddr *temp = (struct sockaddr *)awrq;
1048 struct list_head *phead;
1050 struct wlan_network *pnetwork = NULL;
1051 enum NDIS_802_11_AUTHENTICATION_MODE authmode;
1053 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY))
1055 if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING))
1057 if (temp->sa_family != ARPHRD_ETHER)
1059 authmode = padapter->securitypriv.ndisauthtype;
1060 spin_lock_irqsave(&queue->lock, irqL);
1061 phead = &queue->queue;
1062 pmlmepriv->pscanned = phead->next;
1064 if (end_of_queue_search(phead, pmlmepriv->pscanned))
1066 pnetwork = LIST_CONTAINOR(pmlmepriv->pscanned,
1067 struct wlan_network, list);
1068 pmlmepriv->pscanned = pmlmepriv->pscanned->next;
1069 dst_bssid = pnetwork->network.MacAddress;
1070 if (!memcmp(dst_bssid, temp->sa_data, ETH_ALEN)) {
1071 r8712_set_802_11_infrastructure_mode(padapter,
1072 pnetwork->network.InfrastructureMode);
1076 spin_unlock_irqrestore(&queue->lock, irqL);
1078 if (!r8712_set_802_11_authentication_mode(padapter, authmode)) {
1081 if (!r8712_set_802_11_bssid(padapter, temp->sa_data))
1088 static int r8711_wx_get_wap(struct net_device *dev,
1089 struct iw_request_info *info,
1090 union iwreq_data *wrqu, char *extra)
1092 struct _adapter *padapter = netdev_priv(dev);
1093 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1094 struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
1096 wrqu->ap_addr.sa_family = ARPHRD_ETHER;
1097 if (check_fwstate(pmlmepriv, _FW_LINKED | WIFI_ADHOC_MASTER_STATE |
1099 ether_addr_copy(wrqu->ap_addr.sa_data, pcur_bss->MacAddress);
1101 eth_zero_addr(wrqu->ap_addr.sa_data);
1105 static int r871x_wx_set_mlme(struct net_device *dev,
1106 struct iw_request_info *info,
1107 union iwreq_data *wrqu, char *extra)
1110 struct _adapter *padapter = netdev_priv(dev);
1111 struct iw_mlme *mlme = (struct iw_mlme *) extra;
1115 switch (mlme->cmd) {
1116 case IW_MLME_DEAUTH:
1117 if (!r8712_set_802_11_disassociate(padapter))
1120 case IW_MLME_DISASSOC:
1121 if (!r8712_set_802_11_disassociate(padapter))
1132 * This function intends to handle the Set Scan command.
1133 * Currently, the request comes via Wireless Extensions' SIOCSIWSCAN ioctl.
1135 * For this operation to succeed, the interface is brought Up beforehand.
1138 static int r8711_wx_set_scan(struct net_device *dev,
1139 struct iw_request_info *a,
1140 union iwreq_data *wrqu, char *extra)
1142 struct _adapter *padapter = netdev_priv(dev);
1143 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1146 if (padapter->bDriverStopped) {
1147 netdev_info(dev, "In %s: bDriverStopped=%d\n",
1148 __func__, padapter->bDriverStopped);
1153 if (!padapter->hw_init_completed)
1155 if ((check_fwstate(pmlmepriv, _FW_UNDER_SURVEY | _FW_UNDER_LINKING)) ||
1156 (pmlmepriv->sitesurveyctrl.traffic_busy))
1158 if (wrqu->data.length == sizeof(struct iw_scan_req)) {
1159 struct iw_scan_req *req = (struct iw_scan_req *)extra;
1161 if (wrqu->data.flags & IW_SCAN_THIS_ESSID) {
1162 struct ndis_802_11_ssid ssid;
1164 u32 len = min_t(u8, req->essid_len, IW_ESSID_MAX_SIZE);
1166 memset((unsigned char *)&ssid, 0,
1167 sizeof(struct ndis_802_11_ssid));
1168 memcpy(ssid.Ssid, req->essid, len);
1169 ssid.SsidLength = len;
1170 spin_lock_irqsave(&pmlmepriv->lock, irqL);
1171 if ((check_fwstate(pmlmepriv, _FW_UNDER_SURVEY |
1172 _FW_UNDER_LINKING)) ||
1173 (pmlmepriv->sitesurveyctrl.traffic_busy)) {
1174 if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING))
1177 status = r8712_sitesurvey_cmd(padapter, &ssid);
1179 spin_unlock_irqrestore(&pmlmepriv->lock, irqL);
1182 status = r8712_set_802_11_bssid_list_scan(padapter);
1189 static int r8711_wx_get_scan(struct net_device *dev,
1190 struct iw_request_info *a,
1191 union iwreq_data *wrqu, char *extra)
1193 struct _adapter *padapter = netdev_priv(dev);
1194 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1195 struct __queue *queue = &pmlmepriv->scanned_queue;
1196 struct wlan_network *pnetwork = NULL;
1198 struct list_head *plist, *phead;
1200 char *stop = ev + wrqu->data.length;
1201 u32 ret = 0, cnt = 0;
1203 if (padapter->bDriverStopped)
1205 while (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY |
1206 _FW_UNDER_LINKING)) {
1212 spin_lock_irqsave(&queue->lock, irqL);
1213 phead = &queue->queue;
1214 plist = phead->next;
1216 if (end_of_queue_search(phead, plist))
1218 if ((stop - ev) < SCAN_ITEM_SIZE) {
1222 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
1223 ev = translate_scan(padapter, a, pnetwork, ev, stop);
1224 plist = plist->next;
1226 spin_unlock_irqrestore(&queue->lock, irqL);
1227 wrqu->data.length = ev - extra;
1228 wrqu->data.flags = 0;
1233 * s1. set_802_11_infrastructure_mode()
1234 * s2. set_802_11_authenticaion_mode()
1235 * s3. set_802_11_encryption_mode()
1236 * s4. set_802_11_ssid()
1238 * This function intends to handle the Set ESSID command.
1239 * Currently, the request comes via the Wireless Extensions' SIOCSIWESSID ioctl.
1241 * For this operation to succeed, there is no need for the interface to be Up.
1244 static int r8711_wx_set_essid(struct net_device *dev,
1245 struct iw_request_info *a,
1246 union iwreq_data *wrqu, char *extra)
1248 struct _adapter *padapter = netdev_priv(dev);
1249 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1250 struct __queue *queue = &pmlmepriv->scanned_queue;
1251 struct wlan_network *pnetwork = NULL;
1252 enum NDIS_802_11_AUTHENTICATION_MODE authmode;
1253 struct ndis_802_11_ssid ndis_ssid;
1254 u8 *dst_ssid, *src_ssid;
1255 struct list_head *phead;
1258 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY))
1260 if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING))
1262 if (wrqu->essid.length > IW_ESSID_MAX_SIZE)
1264 authmode = padapter->securitypriv.ndisauthtype;
1265 if (wrqu->essid.flags && wrqu->essid.length) {
1266 len = (wrqu->essid.length < IW_ESSID_MAX_SIZE) ?
1267 wrqu->essid.length : IW_ESSID_MAX_SIZE;
1268 memset(&ndis_ssid, 0, sizeof(struct ndis_802_11_ssid));
1269 ndis_ssid.SsidLength = len;
1270 memcpy(ndis_ssid.Ssid, extra, len);
1271 src_ssid = ndis_ssid.Ssid;
1272 phead = &queue->queue;
1273 pmlmepriv->pscanned = phead->next;
1275 if (end_of_queue_search(phead, pmlmepriv->pscanned))
1277 pnetwork = LIST_CONTAINOR(pmlmepriv->pscanned,
1278 struct wlan_network, list);
1279 pmlmepriv->pscanned = pmlmepriv->pscanned->next;
1280 dst_ssid = pnetwork->network.Ssid.Ssid;
1281 if ((!memcmp(dst_ssid, src_ssid, ndis_ssid.SsidLength))
1282 && (pnetwork->network.Ssid.SsidLength ==
1283 ndis_ssid.SsidLength)) {
1284 if (check_fwstate(pmlmepriv,
1285 WIFI_ADHOC_STATE)) {
1286 if (pnetwork->network.
1290 cur_network.network.
1295 r8712_set_802_11_infrastructure_mode(
1297 pnetwork->network.InfrastructureMode);
1301 r8712_set_802_11_authentication_mode(padapter, authmode);
1302 r8712_set_802_11_ssid(padapter, &ndis_ssid);
1304 return -EINPROGRESS;
1307 static int r8711_wx_get_essid(struct net_device *dev,
1308 struct iw_request_info *a,
1309 union iwreq_data *wrqu, char *extra)
1311 struct _adapter *padapter = netdev_priv(dev);
1312 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1313 struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
1316 if (check_fwstate(pmlmepriv, _FW_LINKED | WIFI_ADHOC_MASTER_STATE)) {
1317 len = pcur_bss->Ssid.SsidLength;
1318 wrqu->essid.length = len;
1319 memcpy(extra, pcur_bss->Ssid.Ssid, len);
1320 wrqu->essid.flags = 1;
1327 static int r8711_wx_set_rate(struct net_device *dev,
1328 struct iw_request_info *a,
1329 union iwreq_data *wrqu, char *extra)
1331 struct _adapter *padapter = netdev_priv(dev);
1332 u32 target_rate = wrqu->bitrate.value;
1333 u32 fixed = wrqu->bitrate.fixed;
1335 u8 datarates[NumRates];
1336 u8 mpdatarate[NumRates] = {11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0xff};
1339 if (target_rate == -1) {
1343 target_rate = target_rate / 100000;
1344 switch (target_rate) {
1386 for (i = 0; i < NumRates; i++) {
1387 if (ratevalue == mpdatarate[i]) {
1388 datarates[i] = mpdatarate[i];
1392 datarates[i] = 0xff;
1395 if (r8712_setdatarate_cmd(padapter, datarates) != _SUCCESS)
1400 static int r8711_wx_get_rate(struct net_device *dev,
1401 struct iw_request_info *info,
1402 union iwreq_data *wrqu, char *extra)
1404 struct _adapter *padapter = netdev_priv(dev);
1405 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1406 struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
1407 struct ieee80211_ht_cap *pht_capie;
1408 unsigned char rf_type = padapter->registrypriv.rf_config;
1411 u16 rate, max_rate = 0, ht_cap = false;
1413 u8 bw_40MHz = 0, short_GI = 0;
1417 if (check_fwstate(pmlmepriv, _FW_LINKED | WIFI_ADHOC_MASTER_STATE)) {
1418 p = r8712_get_ie(&pcur_bss->IEs[12],
1419 _HT_CAPABILITY_IE_, &ht_ielen,
1420 pcur_bss->IELength - 12);
1421 if (p && ht_ielen > 0) {
1423 pht_capie = (struct ieee80211_ht_cap *)(p + 2);
1424 memcpy(&mcs_rate, pht_capie->supp_mcs_set, 2);
1425 bw_40MHz = (pht_capie->cap_info &
1426 IEEE80211_HT_CAP_SUP_WIDTH) ? 1 : 0;
1427 short_GI = (pht_capie->cap_info &
1428 (IEEE80211_HT_CAP_SGI_20 |
1429 IEEE80211_HT_CAP_SGI_40)) ? 1 : 0;
1431 while ((pcur_bss->rates[i] != 0) &&
1432 (pcur_bss->rates[i] != 0xFF)) {
1433 rate = pcur_bss->rates[i] & 0x7F;
1434 if (rate > max_rate)
1436 wrqu->bitrate.fixed = 0; /* no auto select */
1437 wrqu->bitrate.value = rate * 500000;
1441 if (mcs_rate & 0x8000 /* MCS15 */
1443 rf_type == RTL8712_RF_2T2R)
1444 max_rate = (bw_40MHz) ? ((short_GI) ? 300 :
1445 270) : ((short_GI) ? 144 : 130);
1446 else /* default MCS7 */
1447 max_rate = (bw_40MHz) ? ((short_GI) ? 150 :
1448 135) : ((short_GI) ? 72 : 65);
1449 max_rate *= 2; /* Mbps/2 */
1451 wrqu->bitrate.value = max_rate * 500000;
1458 static int r8711_wx_get_rts(struct net_device *dev,
1459 struct iw_request_info *info,
1460 union iwreq_data *wrqu, char *extra)
1462 struct _adapter *padapter = netdev_priv(dev);
1464 wrqu->rts.value = padapter->registrypriv.rts_thresh;
1465 wrqu->rts.fixed = 0; /* no auto select */
1469 static int r8711_wx_set_frag(struct net_device *dev,
1470 struct iw_request_info *info,
1471 union iwreq_data *wrqu, char *extra)
1473 struct _adapter *padapter = netdev_priv(dev);
1475 if (wrqu->frag.disabled) {
1476 padapter->xmitpriv.frag_len = MAX_FRAG_THRESHOLD;
1478 if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
1479 wrqu->frag.value > MAX_FRAG_THRESHOLD)
1481 padapter->xmitpriv.frag_len = wrqu->frag.value & ~0x1;
1486 static int r8711_wx_get_frag(struct net_device *dev,
1487 struct iw_request_info *info,
1488 union iwreq_data *wrqu, char *extra)
1490 struct _adapter *padapter = netdev_priv(dev);
1492 wrqu->frag.value = padapter->xmitpriv.frag_len;
1493 wrqu->frag.fixed = 0; /* no auto select */
1497 static int r8711_wx_get_retry(struct net_device *dev,
1498 struct iw_request_info *info,
1499 union iwreq_data *wrqu, char *extra)
1501 wrqu->retry.value = 7;
1502 wrqu->retry.fixed = 0; /* no auto select */
1503 wrqu->retry.disabled = 1;
1507 static int r8711_wx_set_enc(struct net_device *dev,
1508 struct iw_request_info *info,
1509 union iwreq_data *wrqu, char *keybuf)
1512 u32 keyindex_provided;
1513 struct NDIS_802_11_WEP wep;
1514 enum NDIS_802_11_AUTHENTICATION_MODE authmode;
1515 struct iw_point *erq = &(wrqu->encoding);
1516 struct _adapter *padapter = netdev_priv(dev);
1518 key = erq->flags & IW_ENCODE_INDEX;
1519 memset(&wep, 0, sizeof(struct NDIS_802_11_WEP));
1520 if (erq->flags & IW_ENCODE_DISABLED) {
1521 netdev_info(dev, "r8712u: %s: EncryptionDisabled\n", __func__);
1522 padapter->securitypriv.ndisencryptstatus =
1523 Ndis802_11EncryptionDisabled;
1524 padapter->securitypriv.PrivacyAlgrthm = _NO_PRIVACY_;
1525 padapter->securitypriv.XGrpPrivacy = _NO_PRIVACY_;
1526 padapter->securitypriv.AuthAlgrthm = 0; /* open system */
1527 authmode = Ndis802_11AuthModeOpen;
1528 padapter->securitypriv.ndisauthtype = authmode;
1535 keyindex_provided = 1;
1537 keyindex_provided = 0;
1538 key = padapter->securitypriv.PrivacyKeyIndex;
1540 /* set authentication mode */
1541 if (erq->flags & IW_ENCODE_OPEN) {
1542 netdev_info(dev, "r8712u: %s: IW_ENCODE_OPEN\n", __func__);
1543 padapter->securitypriv.ndisencryptstatus =
1544 Ndis802_11Encryption1Enabled;
1545 padapter->securitypriv.AuthAlgrthm = 0; /* open system */
1546 padapter->securitypriv.PrivacyAlgrthm = _NO_PRIVACY_;
1547 padapter->securitypriv.XGrpPrivacy = _NO_PRIVACY_;
1548 authmode = Ndis802_11AuthModeOpen;
1549 padapter->securitypriv.ndisauthtype = authmode;
1550 } else if (erq->flags & IW_ENCODE_RESTRICTED) {
1552 "r8712u: %s: IW_ENCODE_RESTRICTED\n", __func__);
1553 padapter->securitypriv.ndisencryptstatus =
1554 Ndis802_11Encryption1Enabled;
1555 padapter->securitypriv.AuthAlgrthm = 1; /* shared system */
1556 padapter->securitypriv.PrivacyAlgrthm = _WEP40_;
1557 padapter->securitypriv.XGrpPrivacy = _WEP40_;
1558 authmode = Ndis802_11AuthModeShared;
1559 padapter->securitypriv.ndisauthtype = authmode;
1561 padapter->securitypriv.ndisencryptstatus =
1562 Ndis802_11Encryption1Enabled;
1563 padapter->securitypriv.AuthAlgrthm = 0; /* open system */
1564 padapter->securitypriv.PrivacyAlgrthm = _NO_PRIVACY_;
1565 padapter->securitypriv.XGrpPrivacy = _NO_PRIVACY_;
1566 authmode = Ndis802_11AuthModeOpen;
1567 padapter->securitypriv.ndisauthtype = authmode;
1570 if (erq->length > 0) {
1571 wep.KeyLength = erq->length <= 5 ? 5 : 13;
1572 wep.Length = wep.KeyLength +
1573 FIELD_OFFSET(struct NDIS_802_11_WEP, KeyMaterial);
1576 if (keyindex_provided == 1) { /* set key_id only, no given
1577 * KeyMaterial(erq->length==0).
1579 padapter->securitypriv.PrivacyKeyIndex = key;
1580 switch (padapter->securitypriv.DefKeylen[key]) {
1582 padapter->securitypriv.PrivacyAlgrthm =
1586 padapter->securitypriv.PrivacyAlgrthm =
1590 padapter->securitypriv.PrivacyAlgrthm =
1597 wep.KeyIndex |= 0x80000000; /* transmit key */
1598 memcpy(wep.KeyMaterial, keybuf, wep.KeyLength);
1599 if (r8712_set_802_11_add_wep(padapter, &wep) == _FAIL)
1604 static int r8711_wx_get_enc(struct net_device *dev,
1605 struct iw_request_info *info,
1606 union iwreq_data *wrqu, char *keybuf)
1609 struct _adapter *padapter = netdev_priv(dev);
1610 struct iw_point *erq = &(wrqu->encoding);
1611 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1613 if (!check_fwstate(pmlmepriv, _FW_LINKED)) {
1614 if (!check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) {
1616 erq->flags |= IW_ENCODE_DISABLED;
1620 key = erq->flags & IW_ENCODE_INDEX;
1626 key = padapter->securitypriv.PrivacyKeyIndex;
1628 erq->flags = key + 1;
1629 switch (padapter->securitypriv.ndisencryptstatus) {
1630 case Ndis802_11EncryptionNotSupported:
1631 case Ndis802_11EncryptionDisabled:
1633 erq->flags |= IW_ENCODE_DISABLED;
1635 case Ndis802_11Encryption1Enabled:
1636 erq->length = padapter->securitypriv.DefKeylen[key];
1638 memcpy(keybuf, padapter->securitypriv.DefKey[
1639 key].skey, padapter->securitypriv.
1641 erq->flags |= IW_ENCODE_ENABLED;
1642 if (padapter->securitypriv.ndisauthtype ==
1643 Ndis802_11AuthModeOpen)
1644 erq->flags |= IW_ENCODE_OPEN;
1645 else if (padapter->securitypriv.ndisauthtype ==
1646 Ndis802_11AuthModeShared)
1647 erq->flags |= IW_ENCODE_RESTRICTED;
1650 erq->flags |= IW_ENCODE_DISABLED;
1653 case Ndis802_11Encryption2Enabled:
1654 case Ndis802_11Encryption3Enabled:
1656 erq->flags |= (IW_ENCODE_ENABLED | IW_ENCODE_OPEN |
1661 erq->flags |= IW_ENCODE_DISABLED;
1667 static int r8711_wx_get_power(struct net_device *dev,
1668 struct iw_request_info *info,
1669 union iwreq_data *wrqu, char *extra)
1671 wrqu->power.value = 0;
1672 wrqu->power.fixed = 0; /* no auto select */
1673 wrqu->power.disabled = 1;
1677 static int r871x_wx_set_gen_ie(struct net_device *dev,
1678 struct iw_request_info *info,
1679 union iwreq_data *wrqu, char *extra)
1681 struct _adapter *padapter = netdev_priv(dev);
1683 return r871x_set_wpa_ie(padapter, extra, wrqu->data.length);
1686 static int r871x_wx_set_auth(struct net_device *dev,
1687 struct iw_request_info *info,
1688 union iwreq_data *wrqu, char *extra)
1690 struct _adapter *padapter = netdev_priv(dev);
1691 struct iw_param *param = (struct iw_param *)&(wrqu->param);
1696 paramid = param->flags & IW_AUTH_INDEX;
1697 paramval = param->value;
1699 case IW_AUTH_WPA_VERSION:
1701 case IW_AUTH_CIPHER_PAIRWISE:
1703 case IW_AUTH_CIPHER_GROUP:
1705 case IW_AUTH_KEY_MGMT:
1707 * ??? does not use these parameters
1710 case IW_AUTH_TKIP_COUNTERMEASURES:
1712 /* wpa_supplicant is enabling tkip countermeasure. */
1713 padapter->securitypriv.btkip_countermeasure = true;
1715 /* wpa_supplicant is disabling tkip countermeasure. */
1716 padapter->securitypriv.btkip_countermeasure = false;
1719 case IW_AUTH_DROP_UNENCRYPTED:
1722 * wpa_supplicant calls set_wpa_enabled when the driver
1723 * is loaded and unloaded, regardless of if WPA is being
1724 * used. No other calls are made which can be used to
1725 * determine if encryption will be used or not prior to
1726 * association being expected. If encryption is not being
1727 * used, drop_unencrypted is set to false, else true -- we
1728 * can use this to determine if the CAP_PRIVACY_ON bit should
1731 if (padapter->securitypriv.ndisencryptstatus ==
1732 Ndis802_11Encryption1Enabled) {
1733 /* it means init value, or using wep,
1734 * ndisencryptstatus =
1735 * Ndis802_11Encryption1Enabled,
1736 * then it needn't reset it;
1742 padapter->securitypriv.ndisencryptstatus =
1743 Ndis802_11EncryptionDisabled;
1744 padapter->securitypriv.PrivacyAlgrthm =
1746 padapter->securitypriv.XGrpPrivacy =
1748 padapter->securitypriv.AuthAlgrthm = 0;
1749 padapter->securitypriv.ndisauthtype =
1750 Ndis802_11AuthModeOpen;
1753 case IW_AUTH_80211_AUTH_ALG:
1754 ret = wpa_set_auth_algs(dev, (u32)paramval);
1756 case IW_AUTH_WPA_ENABLED:
1758 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
1760 case IW_AUTH_PRIVACY_INVOKED:
1769 static int r871x_wx_set_enc_ext(struct net_device *dev,
1770 struct iw_request_info *info,
1771 union iwreq_data *wrqu, char *extra)
1773 struct iw_point *pencoding = &wrqu->encoding;
1774 struct iw_encode_ext *pext = (struct iw_encode_ext *)extra;
1775 struct ieee_param *param = NULL;
1780 switch (pext->alg) {
1781 case IW_ENCODE_ALG_NONE:
1784 case IW_ENCODE_ALG_WEP:
1787 case IW_ENCODE_ALG_TKIP:
1790 case IW_ENCODE_ALG_CCMP:
1797 param_len = sizeof(struct ieee_param) + pext->key_len;
1798 param = kzalloc(param_len, GFP_ATOMIC);
1801 param->cmd = IEEE_CMD_SET_ENCRYPTION;
1802 eth_broadcast_addr(param->sta_addr);
1803 strncpy((char *)param->u.crypt.alg, alg_name, IEEE_CRYPT_ALG_NAME_LEN);
1804 if (pext->ext_flags & IW_ENCODE_EXT_GROUP_KEY)
1805 param->u.crypt.set_tx = 0;
1806 if (pext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
1807 param->u.crypt.set_tx = 1;
1808 param->u.crypt.idx = (pencoding->flags & 0x00FF) - 1;
1809 if (pext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID)
1810 memcpy(param->u.crypt.seq, pext->rx_seq, 8);
1811 if (pext->key_len) {
1812 param->u.crypt.key_len = pext->key_len;
1813 memcpy(param + 1, pext + 1, pext->key_len);
1815 ret = wpa_set_encryption(dev, param, param_len);
1820 static int r871x_wx_get_nick(struct net_device *dev,
1821 struct iw_request_info *info,
1822 union iwreq_data *wrqu, char *extra)
1825 wrqu->data.length = 8;
1826 wrqu->data.flags = 1;
1827 memcpy(extra, "rtl_wifi", 8);
1832 static int r8711_wx_read32(struct net_device *dev,
1833 struct iw_request_info *info,
1834 union iwreq_data *wrqu, char *keybuf)
1836 struct _adapter *padapter = netdev_priv(dev);
1840 get_user(addr, (u32 __user *)wrqu->data.pointer);
1841 data32 = r8712_read32(padapter, addr);
1842 put_user(data32, (u32 __user *)wrqu->data.pointer);
1843 wrqu->data.length = (data32 & 0xffff0000) >> 16;
1844 wrqu->data.flags = data32 & 0xffff;
1845 get_user(addr, (u32 __user *)wrqu->data.pointer);
1849 static int r8711_wx_write32(struct net_device *dev,
1850 struct iw_request_info *info,
1851 union iwreq_data *wrqu, char *keybuf)
1853 struct _adapter *padapter = netdev_priv(dev);
1857 get_user(addr, (u32 __user *)wrqu->data.pointer);
1858 data32 = ((u32)wrqu->data.length << 16) | (u32)wrqu->data.flags;
1859 r8712_write32(padapter, addr, data32);
1863 static int dummy(struct net_device *dev,
1864 struct iw_request_info *a,
1865 union iwreq_data *wrqu, char *b)
1870 static int r8711_drvext_hdl(struct net_device *dev,
1871 struct iw_request_info *info,
1872 union iwreq_data *wrqu, char *extra)
1877 static int r871x_mp_ioctl_hdl(struct net_device *dev,
1878 struct iw_request_info *info,
1879 union iwreq_data *wrqu, char *extra)
1881 struct _adapter *padapter = netdev_priv(dev);
1882 struct iw_point *p = &wrqu->data;
1883 struct oid_par_priv oid_par;
1884 struct mp_ioctl_handler *phandler;
1885 struct mp_ioctl_param *poidparam;
1886 unsigned long BytesRead, BytesWritten, BytesNeeded;
1892 if ((!p->length) || (!p->pointer))
1895 bset = (u8)(p->flags & 0xFFFF);
1897 pparmbuf = memdup_user(p->pointer, len);
1898 if (IS_ERR(pparmbuf))
1899 return PTR_ERR(pparmbuf);
1901 poidparam = (struct mp_ioctl_param *)pparmbuf;
1902 if (poidparam->subcode >= MAX_MP_IOCTL_SUBCODE) {
1904 goto _r871x_mp_ioctl_hdl_exit;
1906 phandler = mp_ioctl_hdl + poidparam->subcode;
1907 if ((phandler->paramsize != 0) &&
1908 (poidparam->len < phandler->paramsize)) {
1910 goto _r871x_mp_ioctl_hdl_exit;
1912 if (phandler->oid == 0 && phandler->handler) {
1913 status = phandler->handler(&oid_par);
1914 } else if (phandler->handler) {
1915 oid_par.adapter_context = padapter;
1916 oid_par.oid = phandler->oid;
1917 oid_par.information_buf = poidparam->data;
1918 oid_par.information_buf_len = poidparam->len;
1923 oid_par.bytes_rw = &BytesRead;
1924 oid_par.bytes_needed = &BytesNeeded;
1925 oid_par.type_of_oid = SET_OID;
1927 oid_par.bytes_rw = &BytesWritten;
1928 oid_par.bytes_needed = &BytesNeeded;
1929 oid_par.type_of_oid = QUERY_OID;
1931 status = phandler->handler(&oid_par);
1932 /* todo:check status, BytesNeeded, etc. */
1934 netdev_info(dev, "r8712u: %s: err!, subcode=%d, oid=%d, handler=%p\n",
1935 __func__, poidparam->subcode, phandler->oid,
1938 goto _r871x_mp_ioctl_hdl_exit;
1940 if (bset == 0x00) { /* query info */
1941 if (copy_to_user(p->pointer, pparmbuf, len))
1946 goto _r871x_mp_ioctl_hdl_exit;
1948 _r871x_mp_ioctl_hdl_exit:
1953 static int r871x_get_ap_info(struct net_device *dev,
1954 struct iw_request_info *info,
1955 union iwreq_data *wrqu, char *extra)
1957 struct _adapter *padapter = netdev_priv(dev);
1958 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1959 struct __queue *queue = &pmlmepriv->scanned_queue;
1960 struct iw_point *pdata = &wrqu->data;
1961 struct wlan_network *pnetwork = NULL;
1962 u32 cnt = 0, wpa_ielen;
1964 struct list_head *plist, *phead;
1965 unsigned char *pbuf;
1969 if (padapter->bDriverStopped || (pdata == NULL))
1971 while (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY |
1972 _FW_UNDER_LINKING)) {
1979 if (pdata->length >= 32) {
1980 if (copy_from_user(data, pdata->pointer, 32))
1985 spin_lock_irqsave(&(pmlmepriv->scanned_queue.lock), irqL);
1986 phead = &queue->queue;
1987 plist = phead->next;
1989 if (end_of_queue_search(phead, plist))
1991 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
1992 if (!mac_pton(data, bssid)) {
1993 netdev_info(dev, "r8712u: Invalid BSSID '%s'.\n",
1995 spin_unlock_irqrestore(&(pmlmepriv->scanned_queue.lock),
1999 netdev_info(dev, "r8712u: BSSID:%pM\n", bssid);
2000 if (ether_addr_equal(bssid, pnetwork->network.MacAddress)) {
2001 /* BSSID match, then check if supporting wpa/wpa2 */
2002 pbuf = r8712_get_wpa_ie(&pnetwork->network.IEs[12],
2003 &wpa_ielen, pnetwork->network.IELength - 12);
2004 if (pbuf && (wpa_ielen > 0)) {
2008 pbuf = r8712_get_wpa2_ie(&pnetwork->network.IEs[12],
2009 &wpa_ielen, pnetwork->network.IELength - 12);
2010 if (pbuf && (wpa_ielen > 0)) {
2015 plist = plist->next;
2017 spin_unlock_irqrestore(&(pmlmepriv->scanned_queue.lock), irqL);
2018 if (pdata->length >= 34) {
2019 if (copy_to_user((u8 __user *)pdata->pointer + 32,
2020 (u8 *)&pdata->flags, 1))
2026 static int r871x_set_pid(struct net_device *dev,
2027 struct iw_request_info *info,
2028 union iwreq_data *wrqu, char *extra)
2030 struct _adapter *padapter = netdev_priv(dev);
2031 struct iw_point *pdata = &wrqu->data;
2033 if ((padapter->bDriverStopped) || (pdata == NULL))
2035 if (copy_from_user(&padapter->pid, pdata->pointer, sizeof(int)))
2040 static int r871x_set_chplan(struct net_device *dev,
2041 struct iw_request_info *info,
2042 union iwreq_data *wrqu, char *extra)
2045 struct _adapter *padapter = netdev_priv(dev);
2046 struct iw_point *pdata = &wrqu->data;
2049 if ((padapter->bDriverStopped) || (pdata == NULL)) {
2053 ch_plan = (int)*extra;
2054 r8712_set_chplan_cmd(padapter, ch_plan);
2061 static int r871x_wps_start(struct net_device *dev,
2062 struct iw_request_info *info,
2063 union iwreq_data *wrqu, char *extra)
2065 struct _adapter *padapter = netdev_priv(dev);
2066 struct iw_point *pdata = &wrqu->data;
2067 u32 u32wps_start = 0;
2069 if ((padapter->bDriverStopped) || (pdata == NULL))
2071 if (copy_from_user((void *)&u32wps_start, pdata->pointer, 4))
2073 if (u32wps_start == 0)
2074 u32wps_start = *extra;
2075 if (u32wps_start == 1) /* WPS Start */
2076 padapter->ledpriv.LedControlHandler(padapter,
2078 else if (u32wps_start == 2) /* WPS Stop because of wps success */
2079 padapter->ledpriv.LedControlHandler(padapter,
2081 else if (u32wps_start == 3) /* WPS Stop because of wps fail */
2082 padapter->ledpriv.LedControlHandler(padapter,
2083 LED_CTL_STOP_WPS_FAIL);
2087 static int wpa_set_param(struct net_device *dev, u8 name, u32 value)
2089 struct _adapter *padapter = netdev_priv(dev);
2092 case IEEE_PARAM_WPA_ENABLED:
2093 padapter->securitypriv.AuthAlgrthm = 2; /* 802.1x */
2094 switch ((value) & 0xff) {
2096 padapter->securitypriv.ndisauthtype =
2097 Ndis802_11AuthModeWPAPSK; /* WPA_PSK */
2098 padapter->securitypriv.ndisencryptstatus =
2099 Ndis802_11Encryption2Enabled;
2102 padapter->securitypriv.ndisauthtype =
2103 Ndis802_11AuthModeWPA2PSK; /* WPA2_PSK */
2104 padapter->securitypriv.ndisencryptstatus =
2105 Ndis802_11Encryption3Enabled;
2109 case IEEE_PARAM_TKIP_COUNTERMEASURES:
2111 case IEEE_PARAM_DROP_UNENCRYPTED:
2114 * wpa_supplicant calls set_wpa_enabled when the driver
2115 * is loaded and unloaded, regardless of if WPA is being
2116 * used. No other calls are made which can be used to
2117 * determine if encryption will be used or not prior to
2118 * association being expected. If encryption is not being
2119 * used, drop_unencrypted is set to false, else true -- we
2120 * can use this to determine if the CAP_PRIVACY_ON bit should
2124 case IEEE_PARAM_PRIVACY_INVOKED:
2126 case IEEE_PARAM_AUTH_ALGS:
2127 return wpa_set_auth_algs(dev, value);
2128 case IEEE_PARAM_IEEE_802_1X:
2130 case IEEE_PARAM_WPAX_SELECT:
2131 /* added for WPA2 mixed mode */
2139 static int wpa_mlme(struct net_device *dev, u32 command, u32 reason)
2141 struct _adapter *padapter = netdev_priv(dev);
2144 case IEEE_MLME_STA_DEAUTH:
2145 if (!r8712_set_802_11_disassociate(padapter))
2148 case IEEE_MLME_STA_DISASSOC:
2149 if (!r8712_set_802_11_disassociate(padapter))
2158 static int wpa_supplicant_ioctl(struct net_device *dev, struct iw_point *p)
2160 struct ieee_param *param;
2162 struct _adapter *padapter = netdev_priv(dev);
2164 if (p->length < sizeof(struct ieee_param) || !p->pointer)
2166 param = memdup_user(p->pointer, p->length);
2168 return PTR_ERR(param);
2169 switch (param->cmd) {
2170 case IEEE_CMD_SET_WPA_PARAM:
2171 ret = wpa_set_param(dev, param->u.wpa_param.name,
2172 param->u.wpa_param.value);
2174 case IEEE_CMD_SET_WPA_IE:
2175 ret = r871x_set_wpa_ie(padapter, (char *)param->u.wpa_ie.data,
2176 (u16)param->u.wpa_ie.len);
2178 case IEEE_CMD_SET_ENCRYPTION:
2179 ret = wpa_set_encryption(dev, param, p->length);
2182 ret = wpa_mlme(dev, param->u.mlme.command,
2183 param->u.mlme.reason_code);
2189 if (ret == 0 && copy_to_user(p->pointer, param, p->length))
2195 /* based on "driver_ipw" and for hostapd */
2196 int r871x_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
2198 struct iwreq *wrq = (struct iwreq *)rq;
2201 case RTL_IOCTL_WPA_SUPPLICANT:
2202 return wpa_supplicant_ioctl(dev, &wrq->u.data);
2209 static iw_handler r8711_handlers[] = {
2210 NULL, /* SIOCSIWCOMMIT */
2211 r8711_wx_get_name, /* SIOCGIWNAME */
2212 dummy, /* SIOCSIWNWID */
2213 dummy, /* SIOCGIWNWID */
2214 r8711_wx_set_freq, /* SIOCSIWFREQ */
2215 r8711_wx_get_freq, /* SIOCGIWFREQ */
2216 r8711_wx_set_mode, /* SIOCSIWMODE */
2217 r8711_wx_get_mode, /* SIOCGIWMODE */
2218 dummy, /* SIOCSIWSENS */
2219 r8711_wx_get_sens, /* SIOCGIWSENS */
2220 NULL, /* SIOCSIWRANGE */
2221 r8711_wx_get_range, /* SIOCGIWRANGE */
2222 r871x_wx_set_priv, /* SIOCSIWPRIV */
2223 NULL, /* SIOCGIWPRIV */
2224 NULL, /* SIOCSIWSTATS */
2225 NULL, /* SIOCGIWSTATS */
2226 dummy, /* SIOCSIWSPY */
2227 dummy, /* SIOCGIWSPY */
2228 NULL, /* SIOCGIWTHRSPY */
2229 NULL, /* SIOCWIWTHRSPY */
2230 r8711_wx_set_wap, /* SIOCSIWAP */
2231 r8711_wx_get_wap, /* SIOCGIWAP */
2232 r871x_wx_set_mlme, /* request MLME operation;
2233 * uses struct iw_mlme
2235 dummy, /* SIOCGIWAPLIST -- deprecated */
2236 r8711_wx_set_scan, /* SIOCSIWSCAN */
2237 r8711_wx_get_scan, /* SIOCGIWSCAN */
2238 r8711_wx_set_essid, /* SIOCSIWESSID */
2239 r8711_wx_get_essid, /* SIOCGIWESSID */
2240 dummy, /* SIOCSIWNICKN */
2241 r871x_wx_get_nick, /* SIOCGIWNICKN */
2242 NULL, /* -- hole -- */
2243 NULL, /* -- hole -- */
2244 r8711_wx_set_rate, /* SIOCSIWRATE */
2245 r8711_wx_get_rate, /* SIOCGIWRATE */
2246 dummy, /* SIOCSIWRTS */
2247 r8711_wx_get_rts, /* SIOCGIWRTS */
2248 r8711_wx_set_frag, /* SIOCSIWFRAG */
2249 r8711_wx_get_frag, /* SIOCGIWFRAG */
2250 dummy, /* SIOCSIWTXPOW */
2251 dummy, /* SIOCGIWTXPOW */
2252 dummy, /* SIOCSIWRETRY */
2253 r8711_wx_get_retry, /* SIOCGIWRETRY */
2254 r8711_wx_set_enc, /* SIOCSIWENCODE */
2255 r8711_wx_get_enc, /* SIOCGIWENCODE */
2256 dummy, /* SIOCSIWPOWER */
2257 r8711_wx_get_power, /* SIOCGIWPOWER */
2258 NULL, /*---hole---*/
2259 NULL, /*---hole---*/
2260 r871x_wx_set_gen_ie, /* SIOCSIWGENIE */
2261 NULL, /* SIOCGIWGENIE */
2262 r871x_wx_set_auth, /* SIOCSIWAUTH */
2263 NULL, /* SIOCGIWAUTH */
2264 r871x_wx_set_enc_ext, /* SIOCSIWENCODEEXT */
2265 NULL, /* SIOCGIWENCODEEXT */
2266 r871x_wx_set_pmkid, /* SIOCSIWPMKSA */
2267 NULL, /*---hole---*/
2270 static const struct iw_priv_args r8711_private_args[] = {
2272 SIOCIWFIRSTPRIV + 0x0,
2273 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "read32"
2276 SIOCIWFIRSTPRIV + 0x1,
2277 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "write32"
2280 SIOCIWFIRSTPRIV + 0x2, 0, 0, "driver_ext"
2283 SIOCIWFIRSTPRIV + 0x3, 0, 0, "mp_ioctl"
2286 SIOCIWFIRSTPRIV + 0x4,
2287 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "apinfo"
2290 SIOCIWFIRSTPRIV + 0x5,
2291 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setpid"
2294 SIOCIWFIRSTPRIV + 0x6,
2295 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wps_start"
2298 SIOCIWFIRSTPRIV + 0x7,
2299 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "chplan"
2303 static iw_handler r8711_private_handler[] = {
2308 r871x_get_ap_info, /*for MM DTV platform*/
2314 static struct iw_statistics *r871x_get_wireless_stats(struct net_device *dev)
2316 struct _adapter *padapter = netdev_priv(dev);
2317 struct iw_statistics *piwstats = &padapter->iwstats;
2322 if (check_fwstate(&padapter->mlmepriv, _FW_LINKED) != true) {
2323 piwstats->qual.qual = 0;
2324 piwstats->qual.level = 0;
2325 piwstats->qual.noise = 0;
2327 /* show percentage, we need transfer dbm to orignal value. */
2328 tmp_level = padapter->recvpriv.fw_rssi;
2329 tmp_qual = padapter->recvpriv.signal;
2330 tmp_noise = padapter->recvpriv.noise;
2331 piwstats->qual.level = tmp_level;
2332 piwstats->qual.qual = tmp_qual;
2333 piwstats->qual.noise = tmp_noise;
2335 piwstats->qual.updated = IW_QUAL_ALL_UPDATED;
2336 return &padapter->iwstats;
2339 struct iw_handler_def r871x_handlers_def = {
2340 .standard = r8711_handlers,
2341 .num_standard = ARRAY_SIZE(r8711_handlers),
2342 .private = r8711_private_handler,
2343 .private_args = (struct iw_priv_args *)r8711_private_args,
2344 .num_private = ARRAY_SIZE(r8711_private_handler),
2345 .num_private_args = sizeof(r8711_private_args) /
2346 sizeof(struct iw_priv_args),
2347 .get_wireless_stats = r871x_get_wireless_stats