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_
31 #include "osdep_service.h"
32 #include "drv_types.h"
33 #include "wlan_bssdef.h"
34 #include "rtl871x_debug.h"
36 #include "rtl871x_mlme.h"
37 #include "rtl871x_ioctl.h"
38 #include "rtl871x_ioctl_set.h"
39 #include "rtl871x_mp_ioctl.h"
40 #include "mlme_osdep.h"
42 #define RTL_IOCTL_WPA_SUPPLICANT (SIOCIWFIRSTPRIV + 30)
44 #define SCAN_ITEM_SIZE 768
45 #define MAX_CUSTOM_LEN 64
49 static const u32 rtl8180_rates[] = {1000000, 2000000, 5500000, 11000000,
50 6000000, 9000000, 12000000, 18000000,
51 24000000, 36000000, 48000000, 54000000};
53 static const long ieee80211_wlan_frequencies[] = {
54 2412, 2417, 2422, 2427,
55 2432, 2437, 2442, 2447,
56 2452, 2457, 2462, 2467,
60 static const char * const iw_operation_mode[] = {
61 "Auto", "Ad-Hoc", "Managed", "Master", "Repeater", "Secondary",
66 * hwaddr_aton - Convert ASCII string to MAC address
67 * @txt: MAC address as a string (e.g., "00:11:22:33:44:55")
68 * @addr: Buffer for the MAC address (ETH_ALEN = 6 bytes)
69 * Returns: 0 on success, -1 on failure (e.g., string not a MAC address)
71 static int hwaddr_aton_i(const char *txt, u8 *addr)
75 for (i = 0; i < 6; i++) {
78 a = hex_to_bin(*txt++);
81 b = hex_to_bin(*txt++);
84 *addr++ = (a << 4) | b;
85 if (i < 5 && *txt++ != ':')
91 void r8712_indicate_wx_assoc_event(struct _adapter *padapter)
93 union iwreq_data wrqu;
94 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
96 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
97 memcpy(wrqu.ap_addr.sa_data, pmlmepriv->cur_network.network.MacAddress,
99 wireless_send_event(padapter->pnetdev, SIOCGIWAP, &wrqu, NULL);
102 void r8712_indicate_wx_disassoc_event(struct _adapter *padapter)
104 union iwreq_data wrqu;
106 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
107 memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN);
108 wireless_send_event(padapter->pnetdev, SIOCGIWAP, &wrqu, NULL);
111 static inline void handle_pairwise_key(struct sta_info *psta,
112 struct ieee_param *param,
113 struct _adapter *padapter)
116 memcpy(psta->x_UncstKey.skey, param->u.crypt.key,
117 (param->u.crypt. key_len > 16 ? 16 : param->u.crypt.key_len));
118 if (strcmp(param->u.crypt.alg, "TKIP") == 0) { /* set mic key */
119 memcpy(psta->tkiptxmickey. skey, &(param->u.crypt.
121 memcpy(psta->tkiprxmickey. skey, &(param->u.crypt.
123 padapter->securitypriv. busetkipkey = false;
124 _set_timer(&padapter->securitypriv.tkip_timer, 50);
126 r8712_setstakey_cmd(padapter, (unsigned char *)psta, true);
129 static inline void handle_group_key(struct ieee_param *param,
130 struct _adapter *padapter)
132 if (0 < param->u.crypt.idx &&
133 param->u.crypt.idx < 3) {
134 /* group key idx is 1 or 2 */
135 memcpy(padapter->securitypriv.XGrpKey[param->u.crypt.
136 idx-1].skey, param->u.crypt.key, (param->u.crypt.key_len
137 > 16 ? 16 : param->u.crypt.key_len));
138 memcpy(padapter->securitypriv.XGrptxmickey[param->
139 u.crypt.idx-1].skey, &(param->u.crypt.key[16]), 8);
140 memcpy(padapter->securitypriv. XGrprxmickey[param->
141 u.crypt.idx-1].skey, &(param->u.crypt.key[24]), 8);
142 padapter->securitypriv.binstallGrpkey = true;
143 r8712_set_key(padapter, &padapter->securitypriv,
145 if (padapter->registrypriv.power_mgnt > PS_MODE_ACTIVE) {
146 if (padapter->registrypriv.power_mgnt != padapter->
147 pwrctrlpriv.pwr_mode)
148 _set_timer(&(padapter->mlmepriv.dhcp_timer),
154 static inline char *translate_scan(struct _adapter *padapter,
155 struct iw_request_info *info,
156 struct wlan_network *pnetwork,
157 char *start, char *stop)
160 struct ieee80211_ht_cap *pht_capie;
162 u8 *buf = (u8 *)_malloc(pnetwork->network.IELength * 2);
163 u8 *wpa_ie = (u8 *)_malloc(255);
164 u8 *rsn_ie = (u8 *)_malloc(255);
165 u8 *wps_ie = (u8 *)_malloc(MAX_WPS_IE_LEN);
167 u32 i = 0, ht_ielen = 0;
168 u16 cap, ht_cap = false, mcs_rate;
169 u8 rssi, bw_40MHz = 0, short_GI = 0;
171 if ((pnetwork->network.Configuration.DSConfig < 1) ||
172 (pnetwork->network.Configuration.DSConfig > 14)) {
173 if (pnetwork->network.Configuration.DSConfig < 1)
174 pnetwork->network.Configuration.DSConfig = 1;
176 pnetwork->network.Configuration.DSConfig = 14;
180 iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
181 memcpy(iwe.u.ap_addr.sa_data, pnetwork->network.MacAddress, ETH_ALEN);
182 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_ADDR_LEN);
184 iwe.cmd = SIOCGIWESSID;
185 iwe.u.data.flags = 1;
186 iwe.u.data.length = (u16)min((u16)pnetwork->network.Ssid.SsidLength,
188 start = iwe_stream_add_point(info, start, stop, &iwe,
189 pnetwork->network.Ssid.Ssid);
190 /* parsing HT_CAP_IE */
191 p = r8712_get_ie(&pnetwork->network.IEs[12], _HT_CAPABILITY_IE_,
192 &ht_ielen, pnetwork->network.IELength - 12);
193 if (p && ht_ielen > 0) {
195 pht_capie = (struct ieee80211_ht_cap *)(p + 2);
196 memcpy(&mcs_rate , pht_capie->supp_mcs_set, 2);
197 bw_40MHz = (pht_capie->cap_info&IEEE80211_HT_CAP_SUP_WIDTH)
199 short_GI = (pht_capie->cap_info&(IEEE80211_HT_CAP_SGI_20 |
200 IEEE80211_HT_CAP_SGI_40)) ? 1 : 0;
202 /* Add the protocol name */
203 iwe.cmd = SIOCGIWNAME;
204 if ((r8712_is_cckratesonly_included((u8 *)&pnetwork->network.
205 SupportedRates)) == true) {
207 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bn");
209 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11b");
210 } else if ((r8712_is_cckrates_included((u8 *)&pnetwork->network.
211 SupportedRates)) == true) {
213 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bgn");
215 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bg");
218 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11gn");
220 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11g");
222 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_CHAR_LEN);
224 iwe.cmd = SIOCGIWMODE;
225 memcpy((u8 *)&cap, r8712_get_capability_from_ie(pnetwork->network.IEs),
227 cap = le16_to_cpu(cap);
228 if (cap & (WLAN_CAPABILITY_IBSS|WLAN_CAPABILITY_BSS)) {
229 if (cap & WLAN_CAPABILITY_BSS)
230 iwe.u.mode = (u32)IW_MODE_MASTER;
232 iwe.u.mode = (u32)IW_MODE_ADHOC;
233 start = iwe_stream_add_event(info, start, stop, &iwe,
236 /* Add frequency/channel */
237 iwe.cmd = SIOCGIWFREQ;
239 /* check legel index */
240 u8 dsconfig = pnetwork->network.Configuration.DSConfig;
241 if (dsconfig >= 1 && dsconfig <= sizeof(
242 ieee80211_wlan_frequencies) / sizeof(long))
243 iwe.u.freq.m = (s32)(ieee80211_wlan_frequencies[
244 pnetwork->network.Configuration.
245 DSConfig - 1] * 100000);
249 iwe.u.freq.e = (s16)1;
250 iwe.u.freq.i = (u8)pnetwork->network.Configuration.DSConfig;
251 start = iwe_stream_add_event(info, start, stop, &iwe,
253 /* Add encryption capability */
254 iwe.cmd = SIOCGIWENCODE;
255 if (cap & WLAN_CAPABILITY_PRIVACY)
256 iwe.u.data.flags = (u16)(IW_ENCODE_ENABLED |
259 iwe.u.data.flags = (u16)(IW_ENCODE_DISABLED);
260 iwe.u.data.length = (u16)0;
261 start = iwe_stream_add_point(info, start, stop, &iwe,
262 pnetwork->network.Ssid.Ssid);
263 /*Add basic and extended rates */
264 current_val = start + iwe_stream_lcp_len(info);
265 iwe.cmd = SIOCGIWRATE;
266 iwe.u.bitrate.fixed = 0;
267 iwe.u.bitrate.disabled = 0;
268 iwe.u.bitrate.value = 0;
270 while (pnetwork->network.SupportedRates[i] != 0) {
271 /* Bit rate given in 500 kb/s units */
272 iwe.u.bitrate.value = (pnetwork->network.SupportedRates[i++] &
274 current_val = iwe_stream_add_value(info, start, current_val,
275 stop, &iwe, IW_EV_PARAM_LEN);
277 /* Check if we added any event */
278 if ((current_val - start) > iwe_stream_lcp_len(info))
280 /* parsing WPA/WPA2 IE */
282 u16 wpa_len = 0, rsn_len = 0;
285 out_len = r8712_get_sec_ie(pnetwork->network.IEs,
287 IELength, rsn_ie, &rsn_len,
291 memset(buf, 0, MAX_WPA_IE_LEN);
292 p += snprintf(p, 7, "wpa_ie=");
293 for (i = 0; i < wpa_len; i++)
294 p += snprintf(p, 2, "%02x", wpa_ie[i]);
295 memset(&iwe, 0, sizeof(iwe));
296 iwe.cmd = IWEVCUSTOM;
297 iwe.u.data.length = (u16)strlen(buf);
298 start = iwe_stream_add_point(info, start, stop,
300 memset(&iwe, 0, sizeof(iwe));
302 iwe.u.data.length = (u16)wpa_len;
303 start = iwe_stream_add_point(info, start, stop,
308 memset(buf, 0, MAX_WPA_IE_LEN);
309 p += snprintf(p, 7, "rsn_ie=");
310 for (i = 0; i < rsn_len; i++)
311 p += snprintf(p, 2, "%02x", rsn_ie[i]);
312 memset(&iwe, 0, sizeof(iwe));
313 iwe.cmd = IWEVCUSTOM;
314 iwe.u.data.length = strlen(buf);
315 start = iwe_stream_add_point(info, start, stop,
317 memset(&iwe, 0, sizeof(iwe));
319 iwe.u.data.length = rsn_len;
320 start = iwe_stream_add_point(info, start, stop, &iwe,
325 { /* parsing WPS IE */
328 if (r8712_get_wps_ie(pnetwork->network.IEs,
329 pnetwork->network.IELength,
330 wps_ie, &wps_ielen) == true) {
333 iwe.u.data.length = (u16)wps_ielen;
334 start = iwe_stream_add_point(info, start, stop,
339 /* Add quality statistics */
341 rssi = r8712_signal_scale_mapping(pnetwork->network.Rssi);
342 /* we only update signal_level (signal strength) that is rssi. */
343 iwe.u.qual.updated = (u8)(IW_QUAL_QUAL_INVALID | IW_QUAL_LEVEL_UPDATED |
344 IW_QUAL_NOISE_INVALID);
345 iwe.u.qual.level = rssi; /* signal strength */
346 iwe.u.qual.qual = 0; /* signal quality */
347 iwe.u.qual.noise = 0; /* noise level */
348 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_QUAL_LEN);
349 /* how to translate rssi to ?% */
357 static int wpa_set_auth_algs(struct net_device *dev, u32 value)
359 struct _adapter *padapter = (struct _adapter *) _netdev_priv(dev);
362 if ((value & AUTH_ALG_SHARED_KEY) && (value & AUTH_ALG_OPEN_SYSTEM)) {
363 padapter->securitypriv.ndisencryptstatus =
364 Ndis802_11Encryption1Enabled;
365 padapter->securitypriv.ndisauthtype =
366 Ndis802_11AuthModeAutoSwitch;
367 padapter->securitypriv.AuthAlgrthm = 3;
368 } else if (value & AUTH_ALG_SHARED_KEY) {
369 padapter->securitypriv.ndisencryptstatus =
370 Ndis802_11Encryption1Enabled;
371 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeShared;
372 padapter->securitypriv.AuthAlgrthm = 1;
373 } else if (value & AUTH_ALG_OPEN_SYSTEM) {
374 if (padapter->securitypriv.ndisauthtype <
375 Ndis802_11AuthModeWPAPSK) {
376 padapter->securitypriv.ndisauthtype =
377 Ndis802_11AuthModeOpen;
378 padapter->securitypriv.AuthAlgrthm = 0;
385 static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param,
389 u32 wep_key_idx, wep_key_len = 0;
390 struct NDIS_802_11_WEP *pwep = NULL;
391 struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
392 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
393 struct security_priv *psecuritypriv = &padapter->securitypriv;
395 param->u.crypt.err = 0;
396 param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
397 if (param_len != (u32)((u8 *) param->u.crypt.key - (u8 *)param) +
398 param->u.crypt.key_len)
400 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
401 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
402 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
403 if (param->u.crypt.idx >= WEP_KEYS) {
404 /* for large key indices, set the default (0) */
405 param->u.crypt.idx = 0;
409 if (strcmp(param->u.crypt.alg, "WEP") == 0) {
410 printk(KERN_INFO "r8712u: wpa_set_encryption, crypt.alg ="
412 padapter->securitypriv.ndisencryptstatus =
413 Ndis802_11Encryption1Enabled;
414 padapter->securitypriv.PrivacyAlgrthm = _WEP40_;
415 padapter->securitypriv.XGrpPrivacy = _WEP40_;
416 wep_key_idx = param->u.crypt.idx;
417 wep_key_len = param->u.crypt.key_len;
418 if (wep_key_idx >= WEP_KEYS)
420 if (wep_key_len > 0) {
421 wep_key_len = wep_key_len <= 5 ? 5 : 13;
422 pwep = (struct NDIS_802_11_WEP *)_malloc((u32)
424 FIELD_OFFSET(struct NDIS_802_11_WEP,
428 memset(pwep, 0, sizeof(struct NDIS_802_11_WEP));
429 pwep->KeyLength = wep_key_len;
430 pwep->Length = wep_key_len +
431 FIELD_OFFSET(struct NDIS_802_11_WEP,
433 if (wep_key_len == 13) {
434 padapter->securitypriv.PrivacyAlgrthm =
436 padapter->securitypriv.XGrpPrivacy =
441 pwep->KeyIndex = wep_key_idx;
442 pwep->KeyIndex |= 0x80000000;
443 memcpy(pwep->KeyMaterial, param->u.crypt.key, pwep->KeyLength);
444 if (param->u.crypt.set_tx) {
445 if (r8712_set_802_11_add_wep(padapter, pwep) ==
449 /* don't update "psecuritypriv->PrivacyAlgrthm" and
450 * "psecuritypriv->PrivacyKeyIndex=keyid", but can
451 * r8712_set_key to fw/cam
453 if (wep_key_idx >= WEP_KEYS) {
457 memcpy(&(psecuritypriv->DefKey[wep_key_idx].
458 skey[0]), pwep->KeyMaterial,
460 psecuritypriv->DefKeylen[wep_key_idx] =
462 r8712_set_key(padapter, psecuritypriv, wep_key_idx);
466 if (padapter->securitypriv.AuthAlgrthm == 2) { /* 802_1x */
467 struct sta_info *psta, *pbcmc_sta;
468 struct sta_priv *pstapriv = &padapter->stapriv;
470 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE |
471 WIFI_MP_STATE) == true) { /* sta mode */
472 psta = r8712_get_stainfo(pstapriv,
473 get_bssid(pmlmepriv));
475 psta->ieee8021x_blocked = false;
476 if ((padapter->securitypriv.ndisencryptstatus ==
477 Ndis802_11Encryption2Enabled) ||
478 (padapter->securitypriv.ndisencryptstatus ==
479 Ndis802_11Encryption3Enabled))
480 psta->XPrivacy = padapter->
481 securitypriv.PrivacyAlgrthm;
482 if (param->u.crypt.set_tx == 1)
483 handle_pairwise_key(psta, param,
486 handle_group_key(param, padapter);
488 pbcmc_sta = r8712_get_bcmc_stainfo(padapter);
490 pbcmc_sta->ieee8021x_blocked = false;
491 if ((padapter->securitypriv.ndisencryptstatus ==
492 Ndis802_11Encryption2Enabled) ||
493 (padapter->securitypriv.ndisencryptstatus ==
494 Ndis802_11Encryption3Enabled))
495 pbcmc_sta->XPrivacy =
496 padapter->securitypriv.
506 static int r871x_set_wpa_ie(struct _adapter *padapter, char *pie,
507 unsigned short ielen)
509 u8 *buf = NULL, *pos = NULL;
510 int group_cipher = 0, pairwise_cipher = 0;
513 if ((ielen > MAX_WPA_IE_LEN) || (pie == NULL))
516 buf = _malloc(ielen);
519 memcpy(buf, pie , ielen);
521 if (ielen < RSN_HEADER_LEN) {
525 if (r8712_parse_wpa_ie(buf, ielen, &group_cipher,
526 &pairwise_cipher) == _SUCCESS) {
527 padapter->securitypriv.AuthAlgrthm = 2;
528 padapter->securitypriv.ndisauthtype =
529 Ndis802_11AuthModeWPAPSK;
531 if (r8712_parse_wpa2_ie(buf, ielen, &group_cipher,
532 &pairwise_cipher) == _SUCCESS) {
533 padapter->securitypriv.AuthAlgrthm = 2;
534 padapter->securitypriv.ndisauthtype =
535 Ndis802_11AuthModeWPA2PSK;
537 switch (group_cipher) {
538 case WPA_CIPHER_NONE:
539 padapter->securitypriv.XGrpPrivacy =
541 padapter->securitypriv.ndisencryptstatus =
542 Ndis802_11EncryptionDisabled;
544 case WPA_CIPHER_WEP40:
545 padapter->securitypriv.XGrpPrivacy = _WEP40_;
546 padapter->securitypriv.ndisencryptstatus =
547 Ndis802_11Encryption1Enabled;
549 case WPA_CIPHER_TKIP:
550 padapter->securitypriv.XGrpPrivacy = _TKIP_;
551 padapter->securitypriv.ndisencryptstatus =
552 Ndis802_11Encryption2Enabled;
554 case WPA_CIPHER_CCMP:
555 padapter->securitypriv.XGrpPrivacy = _AES_;
556 padapter->securitypriv.ndisencryptstatus =
557 Ndis802_11Encryption3Enabled;
559 case WPA_CIPHER_WEP104:
560 padapter->securitypriv.XGrpPrivacy = _WEP104_;
561 padapter->securitypriv.ndisencryptstatus =
562 Ndis802_11Encryption1Enabled;
565 switch (pairwise_cipher) {
566 case WPA_CIPHER_NONE:
567 padapter->securitypriv.PrivacyAlgrthm =
569 padapter->securitypriv.ndisencryptstatus =
570 Ndis802_11EncryptionDisabled;
572 case WPA_CIPHER_WEP40:
573 padapter->securitypriv.PrivacyAlgrthm = _WEP40_;
574 padapter->securitypriv.ndisencryptstatus =
575 Ndis802_11Encryption1Enabled;
577 case WPA_CIPHER_TKIP:
578 padapter->securitypriv.PrivacyAlgrthm = _TKIP_;
579 padapter->securitypriv.ndisencryptstatus =
580 Ndis802_11Encryption2Enabled;
582 case WPA_CIPHER_CCMP:
583 padapter->securitypriv.PrivacyAlgrthm = _AES_;
584 padapter->securitypriv.ndisencryptstatus =
585 Ndis802_11Encryption3Enabled;
587 case WPA_CIPHER_WEP104:
588 padapter->securitypriv.PrivacyAlgrthm = _WEP104_;
589 padapter->securitypriv.ndisencryptstatus =
590 Ndis802_11Encryption1Enabled;
593 padapter->securitypriv.wps_phase = false;
596 u8 eid, wps_oui[4] = {0x0, 0x50, 0xf2, 0x04};
598 while (cnt < ielen) {
601 if ((eid == _VENDOR_SPECIFIC_IE_) &&
602 (!memcmp(&buf[cnt+2], wps_oui, 4))) {
603 printk(KERN_INFO "r8712u: "
605 padapter->securitypriv.wps_ie_len =
607 (MAX_WPA_IE_LEN << 2)) ?
609 (MAX_WPA_IE_LEN << 2);
610 memcpy(padapter->securitypriv.wps_ie,
612 padapter->securitypriv.wps_ie_len);
613 padapter->securitypriv.wps_phase =
615 printk(KERN_INFO "r8712u: SET WPS_IE,"
616 " wps_phase==true\n");
620 cnt += buf[cnt + 1] + 2;
629 static int r8711_wx_get_name(struct net_device *dev,
630 struct iw_request_info *info,
631 union iwreq_data *wrqu, char *extra)
633 struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
637 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
638 struct ndis_wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
639 NDIS_802_11_RATES_EX *prates = NULL;
641 if (check_fwstate(pmlmepriv, _FW_LINKED|WIFI_ADHOC_MASTER_STATE) ==
643 /* parsing HT_CAP_IE */
644 p = r8712_get_ie(&pcur_bss->IEs[12], _HT_CAPABILITY_IE_,
645 &ht_ielen, pcur_bss->IELength - 12);
646 if (p && ht_ielen > 0)
648 prates = &pcur_bss->SupportedRates;
649 if (r8712_is_cckratesonly_included((u8 *)prates) == true) {
651 snprintf(wrqu->name, IFNAMSIZ,
654 snprintf(wrqu->name, IFNAMSIZ,
656 } else if ((r8712_is_cckrates_included((u8 *)prates)) == true) {
658 snprintf(wrqu->name, IFNAMSIZ,
661 snprintf(wrqu->name, IFNAMSIZ,
665 snprintf(wrqu->name, IFNAMSIZ,
668 snprintf(wrqu->name, IFNAMSIZ,
672 snprintf(wrqu->name, IFNAMSIZ, "unassociated");
676 static const long frequency_list[] = {
677 2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447, 2452, 2457, 2462,
678 2467, 2472, 2484, 4915, 4920, 4925, 4935, 4940, 4945, 4960, 4980,
679 5035, 5040, 5045, 5055, 5060, 5080, 5170, 5180, 5190, 5200, 5210,
680 5220, 5230, 5240, 5260, 5280, 5300, 5320, 5500, 5520, 5540, 5560,
681 5580, 5600, 5620, 5640, 5660, 5680, 5700, 5745, 5765, 5785, 5805,
685 static int r8711_wx_set_freq(struct net_device *dev,
686 struct iw_request_info *info,
687 union iwreq_data *wrqu, char *extra)
689 struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
690 struct iw_freq *fwrq = &wrqu->freq;
693 /* If setting by frequency, convert to a channel */
694 if ((fwrq->e == 1) &&
695 (fwrq->m >= (int) 2.412e8) &&
696 (fwrq->m <= (int) 2.487e8)) {
697 int f = fwrq->m / 100000;
699 while ((c < 14) && (f != frequency_list[c]))
704 /* Setting by channel number */
705 if ((fwrq->m > 14) || (fwrq->e > 0))
708 int channel = fwrq->m;
709 if ((channel < 1) || (channel > 14))
712 /* Yes ! We can set it !!! */
713 padapter->registrypriv.channel = channel;
719 static int r8711_wx_get_freq(struct net_device *dev,
720 struct iw_request_info *info,
721 union iwreq_data *wrqu, char *extra)
723 struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
724 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
725 struct ndis_wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
727 if (check_fwstate(pmlmepriv, _FW_LINKED) == true) {
728 wrqu->freq.m = ieee80211_wlan_frequencies[
729 pcur_bss->Configuration.DSConfig-1] * 100000;
731 wrqu->freq.i = pcur_bss->Configuration.DSConfig;
737 static int r8711_wx_set_mode(struct net_device *dev,
738 struct iw_request_info *a,
739 union iwreq_data *wrqu, char *b)
741 struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
742 enum NDIS_802_11_NETWORK_INFRASTRUCTURE networkType;
744 switch (wrqu->mode) {
746 networkType = Ndis802_11AutoUnknown;
749 networkType = Ndis802_11IBSS;
752 networkType = Ndis802_11APMode;
755 networkType = Ndis802_11Infrastructure;
760 if (Ndis802_11APMode == networkType)
761 r8712_setopmode_cmd(padapter, networkType);
763 r8712_setopmode_cmd(padapter, Ndis802_11AutoUnknown);
764 if (!r8712_set_802_11_infrastructure_mode(padapter, networkType))
769 static int r8711_wx_get_mode(struct net_device *dev, struct iw_request_info *a,
770 union iwreq_data *wrqu, char *b)
772 struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
773 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
775 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == true)
776 wrqu->mode = IW_MODE_INFRA;
777 else if (check_fwstate(pmlmepriv,
778 WIFI_ADHOC_MASTER_STATE|WIFI_ADHOC_STATE) == true)
779 wrqu->mode = IW_MODE_ADHOC;
780 else if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == true)
781 wrqu->mode = IW_MODE_MASTER;
783 wrqu->mode = IW_MODE_AUTO;
787 static int r871x_wx_set_pmkid(struct net_device *dev,
788 struct iw_request_info *a,
789 union iwreq_data *wrqu, char *extra)
791 struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
792 struct security_priv *psecuritypriv = &padapter->securitypriv;
793 struct iw_pmksa *pPMK = (struct iw_pmksa *) extra;
794 u8 strZeroMacAddress[ETH_ALEN] = {0x00};
795 u8 strIssueBssid[ETH_ALEN] = {0x00};
796 u8 j, blInserted = false;
797 int intReturn = false;
800 There are the BSSID information in the bssid.sa_data array.
801 If cmd is IW_PMKSA_FLUSH, it means the wpa_suppplicant wants to clear
802 all the PMKID information. If cmd is IW_PMKSA_ADD, it means the
803 wpa_supplicant wants to add a PMKID/BSSID to driver.
804 If cmd is IW_PMKSA_REMOVE, it means the wpa_supplicant wants to
805 remove a PMKID/BSSID from driver.
809 memcpy(strIssueBssid, pPMK->bssid.sa_data, ETH_ALEN);
812 if (!memcmp(strIssueBssid, strZeroMacAddress, ETH_ALEN))
817 /* overwrite PMKID */
818 for (j = 0 ; j < NUM_PMKID_CACHE; j++) {
819 if (!memcmp(psecuritypriv->PMKIDList[j].Bssid,
820 strIssueBssid, ETH_ALEN)) {
821 /* BSSID is matched, the same AP => rewrite
823 printk(KERN_INFO "r8712u: r871x_wx_set_pmkid:"
824 " BSSID exists in the PMKList.\n");
825 memcpy(psecuritypriv->PMKIDList[j].PMKID,
826 pPMK->pmkid, IW_PMKID_LEN);
827 psecuritypriv->PMKIDList[j].bUsed = true;
828 psecuritypriv->PMKIDIndex = j + 1;
834 /* Find a new entry */
835 printk(KERN_INFO "r8712u: r871x_wx_set_pmkid: Use the"
836 " new entry index = %d for this PMKID.\n",
837 psecuritypriv->PMKIDIndex);
838 memcpy(psecuritypriv->PMKIDList[psecuritypriv->
839 PMKIDIndex].Bssid, strIssueBssid, ETH_ALEN);
840 memcpy(psecuritypriv->PMKIDList[psecuritypriv->
841 PMKIDIndex].PMKID, pPMK->pmkid, IW_PMKID_LEN);
842 psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].
844 psecuritypriv->PMKIDIndex++ ;
845 if (psecuritypriv->PMKIDIndex == NUM_PMKID_CACHE)
846 psecuritypriv->PMKIDIndex = 0;
849 case IW_PMKSA_REMOVE:
851 for (j = 0; j < NUM_PMKID_CACHE; j++) {
852 if (!memcmp(psecuritypriv->PMKIDList[j].Bssid,
853 strIssueBssid, ETH_ALEN)) {
854 /* BSSID is matched, the same AP => Remove
855 * this PMKID information and reset it. */
856 memset(psecuritypriv->PMKIDList[j].Bssid,
858 psecuritypriv->PMKIDList[j].bUsed = false;
864 memset(psecuritypriv->PMKIDList, 0,
865 sizeof(struct RT_PMKID_LIST) * NUM_PMKID_CACHE);
866 psecuritypriv->PMKIDIndex = 0;
870 printk(KERN_INFO "r8712u: r871x_wx_set_pmkid: "
871 "unknown Command\n");
878 static int r8711_wx_get_sens(struct net_device *dev,
879 struct iw_request_info *info,
880 union iwreq_data *wrqu, char *extra)
882 wrqu->sens.value = 0;
883 wrqu->sens.fixed = 0; /* no auto select */
884 wrqu->sens.disabled = 1;
888 static int r8711_wx_get_range(struct net_device *dev,
889 struct iw_request_info *info,
890 union iwreq_data *wrqu, char *extra)
892 struct iw_range *range = (struct iw_range *)extra;
896 wrqu->data.length = sizeof(*range);
897 memset(range, 0, sizeof(*range));
898 /* Let's try to keep this struct in the same order as in
899 * linux/include/wireless.h
902 /* TODO: See what values we can set, and remove the ones we can't
903 * set, or fill them with some default data.
905 /* ~5 Mb/s real (802.11b) */
906 range->throughput = 5 * 1000 * 1000;
907 /* TODO: 8711 sensitivity ? */
908 /* signal level threshold range */
909 /* percent values between 0 and 100. */
910 range->max_qual.qual = 100;
911 range->max_qual.level = 100;
912 range->max_qual.noise = 100;
913 range->max_qual.updated = 7; /* Updated all three */
914 range->avg_qual.qual = 92; /* > 8% missed beacons is 'bad' */
915 /* TODO: Find real 'good' to 'bad' threshol value for RSSI */
916 range->avg_qual.level = 20 + -98;
917 range->avg_qual.noise = 0;
918 range->avg_qual.updated = 7; /* Updated all three */
919 range->num_bitrates = RATE_COUNT;
920 for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++)
921 range->bitrate[i] = rtl8180_rates[i];
922 range->min_frag = MIN_FRAG_THRESHOLD;
923 range->max_frag = MAX_FRAG_THRESHOLD;
925 range->we_version_compiled = WIRELESS_EXT;
926 range->we_version_source = 16;
927 range->num_channels = 14;
928 for (i = 0, val = 0; i < 14; i++) {
929 /* Include only legal frequencies for some countries */
930 range->freq[val].i = i + 1;
931 range->freq[val].m = ieee80211_wlan_frequencies[i] * 100000;
932 range->freq[val].e = 1;
934 if (val == IW_MAX_FREQUENCIES)
937 range->num_frequency = val;
938 range->enc_capa = IW_ENC_CAPA_WPA |
940 IW_ENC_CAPA_CIPHER_TKIP |
941 IW_ENC_CAPA_CIPHER_CCMP;
945 static int r871x_wx_set_priv(struct net_device *dev,
946 struct iw_request_info *info,
947 union iwreq_data *awrq,
950 int ret = 0, len = 0;
952 struct iw_point *dwrq = (struct iw_point *)awrq;
958 if (copy_from_user(ext, dwrq->pointer, len)) {
967 * s1. set_802_11_infrastructure_mode()
968 * s2. set_802_11_authentication_mode()
969 * s3. set_802_11_encryption_mode()
970 * s4. set_802_11_bssid()
972 static int r8711_wx_set_wap(struct net_device *dev,
973 struct iw_request_info *info,
974 union iwreq_data *awrq,
977 int ret = -EINPROGRESS;
978 struct _adapter *padapter = (struct _adapter *) _netdev_priv(dev);
979 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
980 struct __queue *queue = &pmlmepriv->scanned_queue;
981 struct sockaddr *temp = (struct sockaddr *)awrq;
983 struct list_head *phead;
985 struct wlan_network *pnetwork = NULL;
986 enum NDIS_802_11_AUTHENTICATION_MODE authmode;
988 if (padapter->bup == false)
990 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == true)
992 if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == true)
994 if (temp->sa_family != ARPHRD_ETHER)
996 authmode = padapter->securitypriv.ndisauthtype;
997 spin_lock_irqsave(&queue->lock, irqL);
998 phead = get_list_head(queue);
999 pmlmepriv->pscanned = get_next(phead);
1001 if (end_of_queue_search(phead, pmlmepriv->pscanned) == true)
1003 pnetwork = LIST_CONTAINOR(pmlmepriv->pscanned,
1004 struct wlan_network, list);
1005 pmlmepriv->pscanned = get_next(pmlmepriv->pscanned);
1006 dst_bssid = pnetwork->network.MacAddress;
1007 if (!memcmp(dst_bssid, temp->sa_data, ETH_ALEN)) {
1008 if (r8712_set_802_11_infrastructure_mode(padapter,
1009 pnetwork->network.InfrastructureMode) == false)
1014 spin_unlock_irqrestore(&queue->lock, irqL);
1016 if (!r8712_set_802_11_authentication_mode(padapter, authmode))
1019 if (!r8712_set_802_11_bssid(padapter, temp->sa_data))
1026 static int r8711_wx_get_wap(struct net_device *dev,
1027 struct iw_request_info *info,
1028 union iwreq_data *wrqu, char *extra)
1030 struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
1031 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1032 struct ndis_wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
1034 wrqu->ap_addr.sa_family = ARPHRD_ETHER;
1035 memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN);
1036 if (check_fwstate(pmlmepriv, _FW_LINKED |
1037 WIFI_ADHOC_MASTER_STATE|WIFI_AP_STATE)) {
1038 memcpy(wrqu->ap_addr.sa_data, pcur_bss->MacAddress, ETH_ALEN);
1043 static int r871x_wx_set_mlme(struct net_device *dev,
1044 struct iw_request_info *info,
1045 union iwreq_data *wrqu, char *extra)
1049 struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
1050 struct iw_mlme *mlme = (struct iw_mlme *) extra;
1054 reason = cpu_to_le16(mlme->reason_code);
1055 switch (mlme->cmd) {
1056 case IW_MLME_DEAUTH:
1057 if (!r8712_set_802_11_disassociate(padapter))
1060 case IW_MLME_DISASSOC:
1061 if (!r8712_set_802_11_disassociate(padapter))
1070 static int r8711_wx_set_scan(struct net_device *dev,
1071 struct iw_request_info *a,
1072 union iwreq_data *wrqu, char *extra)
1074 struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
1075 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1078 if (padapter->bDriverStopped == true) {
1079 printk(KERN_WARNING "r8712u: in r8711_wx_set_scan: "
1080 "bDriverStopped=%d\n", padapter->bDriverStopped);
1083 if (padapter->bup == false)
1085 if (padapter->hw_init_completed == false)
1087 if ((check_fwstate(pmlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING)) ||
1088 (pmlmepriv->sitesurveyctrl.traffic_busy == true))
1090 if (wrqu->data.length == sizeof(struct iw_scan_req)) {
1091 struct iw_scan_req *req = (struct iw_scan_req *)extra;
1092 if (wrqu->data.flags & IW_SCAN_THIS_ESSID) {
1093 struct ndis_802_11_ssid ssid;
1095 u32 len = (u32) min((u8)req->essid_len,
1096 (u8)IW_ESSID_MAX_SIZE);
1097 memset((unsigned char *)&ssid, 0,
1098 sizeof(struct ndis_802_11_ssid));
1099 memcpy(ssid.Ssid, req->essid, len);
1100 ssid.SsidLength = len;
1101 spin_lock_irqsave(&pmlmepriv->lock, irqL);
1102 if ((check_fwstate(pmlmepriv, _FW_UNDER_SURVEY |
1103 _FW_UNDER_LINKING)) ||
1104 (pmlmepriv->sitesurveyctrl.traffic_busy == true)) {
1105 if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING))
1108 status = r8712_sitesurvey_cmd(padapter, &ssid);
1109 spin_unlock_irqrestore(&pmlmepriv->lock, irqL);
1112 status = r8712_set_802_11_bssid_list_scan(padapter);
1113 if (status == false)
1118 static int r8711_wx_get_scan(struct net_device *dev,
1119 struct iw_request_info *a,
1120 union iwreq_data *wrqu, char *extra)
1122 struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
1123 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1124 struct __queue *queue = &pmlmepriv->scanned_queue;
1125 struct wlan_network *pnetwork = NULL;
1127 struct list_head *plist, *phead;
1129 char *stop = ev + wrqu->data.length;
1130 u32 ret = 0, cnt = 0;
1132 if (padapter->bDriverStopped)
1134 while (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING)) {
1140 spin_lock_irqsave(&queue->lock, irqL);
1141 phead = get_list_head(queue);
1142 plist = get_next(phead);
1144 if (end_of_queue_search(phead, plist) == true)
1146 if ((stop - ev) < SCAN_ITEM_SIZE) {
1150 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
1151 ev = translate_scan(padapter, a, pnetwork, ev, stop);
1152 plist = get_next(plist);
1154 spin_unlock_irqrestore(&queue->lock, irqL);
1155 wrqu->data.length = ev - extra;
1156 wrqu->data.flags = 0;
1161 * s1. set_802_11_infrastructure_mode()
1162 * s2. set_802_11_authenticaion_mode()
1163 * s3. set_802_11_encryption_mode()
1164 * s4. set_802_11_ssid()
1166 static int r8711_wx_set_essid(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;
1172 struct __queue *queue = &pmlmepriv->scanned_queue;
1173 struct wlan_network *pnetwork = NULL;
1174 enum NDIS_802_11_AUTHENTICATION_MODE authmode;
1175 struct ndis_802_11_ssid ndis_ssid;
1176 u8 *dst_ssid, *src_ssid;
1177 struct list_head *phead;
1180 if (padapter->bup == false)
1182 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY))
1184 if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING))
1186 if (wrqu->essid.length > IW_ESSID_MAX_SIZE)
1188 authmode = padapter->securitypriv.ndisauthtype;
1189 if (wrqu->essid.flags && wrqu->essid.length) {
1190 len = (wrqu->essid.length < IW_ESSID_MAX_SIZE) ?
1191 wrqu->essid.length : IW_ESSID_MAX_SIZE;
1192 memset(&ndis_ssid, 0, sizeof(struct ndis_802_11_ssid));
1193 ndis_ssid.SsidLength = len;
1194 memcpy(ndis_ssid.Ssid, extra, len);
1195 src_ssid = ndis_ssid.Ssid;
1196 phead = get_list_head(queue);
1197 pmlmepriv->pscanned = get_next(phead);
1199 if (end_of_queue_search(phead, pmlmepriv->pscanned))
1201 pnetwork = LIST_CONTAINOR(pmlmepriv->pscanned,
1202 struct wlan_network, list);
1203 pmlmepriv->pscanned = get_next(pmlmepriv->pscanned);
1204 dst_ssid = pnetwork->network.Ssid.Ssid;
1205 if ((!memcmp(dst_ssid, src_ssid, ndis_ssid.SsidLength))
1206 && (pnetwork->network.Ssid.SsidLength ==
1207 ndis_ssid.SsidLength)) {
1208 if (!r8712_set_802_11_infrastructure_mode(
1210 pnetwork->network.InfrastructureMode))
1215 r8712_set_802_11_authentication_mode(padapter, authmode);
1216 r8712_set_802_11_ssid(padapter, &ndis_ssid);
1218 return -EINPROGRESS;
1221 static int r8711_wx_get_essid(struct net_device *dev,
1222 struct iw_request_info *a,
1223 union iwreq_data *wrqu, char *extra)
1225 struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
1226 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1227 struct ndis_wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
1230 if (check_fwstate(pmlmepriv, _FW_LINKED|WIFI_ADHOC_MASTER_STATE)) {
1231 len = pcur_bss->Ssid.SsidLength;
1232 wrqu->essid.length = len;
1233 memcpy(extra, pcur_bss->Ssid.Ssid, len);
1234 wrqu->essid.flags = 1;
1240 static int r8711_wx_set_rate(struct net_device *dev,
1241 struct iw_request_info *a,
1242 union iwreq_data *wrqu, char *extra)
1244 struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
1245 u32 target_rate = wrqu->bitrate.value;
1246 u32 fixed = wrqu->bitrate.fixed;
1248 u8 datarates[NumRates];
1249 u8 mpdatarate[NumRates] = {11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0xff};
1252 if (target_rate == -1) {
1256 target_rate = target_rate / 100000;
1257 switch (target_rate) {
1299 for (i = 0; i < NumRates; i++) {
1300 if (ratevalue == mpdatarate[i]) {
1301 datarates[i] = mpdatarate[i];
1305 datarates[i] = 0xff;
1307 if (r8712_setdatarate_cmd(padapter, datarates) != _SUCCESS)
1312 static int r8711_wx_get_rate(struct net_device *dev,
1313 struct iw_request_info *info,
1314 union iwreq_data *wrqu, char *extra)
1316 struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
1317 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1318 struct ndis_wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
1319 struct ieee80211_ht_cap *pht_capie;
1322 u16 rate, max_rate = 0, ht_cap = false;
1324 u8 bw_40MHz = 0, short_GI = 0;
1328 if (check_fwstate(pmlmepriv, _FW_LINKED|WIFI_ADHOC_MASTER_STATE)) {
1329 p = r8712_get_ie(&pcur_bss->IEs[12],
1330 _HT_CAPABILITY_IE_, &ht_ielen,
1331 pcur_bss->IELength - 12);
1332 if (p && ht_ielen > 0) {
1334 pht_capie = (struct ieee80211_ht_cap *)(p + 2);
1335 memcpy(&mcs_rate , pht_capie->supp_mcs_set, 2);
1336 bw_40MHz = (pht_capie->cap_info &
1337 IEEE80211_HT_CAP_SUP_WIDTH) ? 1 : 0;
1338 short_GI = (pht_capie->cap_info &
1339 (IEEE80211_HT_CAP_SGI_20 |
1340 IEEE80211_HT_CAP_SGI_40)) ? 1 : 0;
1342 while ((pcur_bss->SupportedRates[i] != 0) &&
1343 (pcur_bss->SupportedRates[i] != 0xFF)) {
1344 rate = pcur_bss->SupportedRates[i] & 0x7F;
1345 if (rate > max_rate)
1347 wrqu->bitrate.fixed = 0; /* no auto select */
1348 wrqu->bitrate.value = rate*500000;
1351 if (ht_cap == true) {
1352 if (mcs_rate & 0x8000) /* MCS15 */
1353 max_rate = (bw_40MHz) ? ((short_GI) ? 300 :
1354 270) : ((short_GI) ? 144 : 130);
1355 else if (mcs_rate & 0x0080) /* MCS7 */
1356 max_rate = (bw_40MHz) ? ((short_GI) ? 150 :
1357 135) : ((short_GI) ? 72 : 65);
1358 else /* default MCS7 */
1359 max_rate = (bw_40MHz) ? ((short_GI) ? 150 :
1360 135) : ((short_GI) ? 72 : 65);
1361 max_rate *= 2; /* Mbps/2 */
1362 wrqu->bitrate.value = max_rate * 500000;
1364 wrqu->bitrate.value = max_rate * 500000;
1371 static int r8711_wx_get_rts(struct net_device *dev,
1372 struct iw_request_info *info,
1373 union iwreq_data *wrqu, char *extra)
1375 struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
1377 wrqu->rts.value = padapter->registrypriv.rts_thresh;
1378 wrqu->rts.fixed = 0; /* no auto select */
1382 static int r8711_wx_set_frag(struct net_device *dev,
1383 struct iw_request_info *info,
1384 union iwreq_data *wrqu, char *extra)
1386 struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
1388 if (wrqu->frag.disabled)
1389 padapter->xmitpriv.frag_len = MAX_FRAG_THRESHOLD;
1391 if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
1392 wrqu->frag.value > MAX_FRAG_THRESHOLD)
1394 padapter->xmitpriv.frag_len = wrqu->frag.value & ~0x1;
1399 static int r8711_wx_get_frag(struct net_device *dev,
1400 struct iw_request_info *info,
1401 union iwreq_data *wrqu, char *extra)
1403 struct _adapter *padapter = (struct _adapter *) _netdev_priv(dev);
1405 wrqu->frag.value = padapter->xmitpriv.frag_len;
1406 wrqu->frag.fixed = 0; /* no auto select */
1410 static int r8711_wx_get_retry(struct net_device *dev,
1411 struct iw_request_info *info,
1412 union iwreq_data *wrqu, char *extra)
1414 wrqu->retry.value = 7;
1415 wrqu->retry.fixed = 0; /* no auto select */
1416 wrqu->retry.disabled = 1;
1420 static int r8711_wx_set_enc(struct net_device *dev,
1421 struct iw_request_info *info,
1422 union iwreq_data *wrqu, char *keybuf)
1425 u32 keyindex_provided;
1426 struct NDIS_802_11_WEP wep;
1427 enum NDIS_802_11_AUTHENTICATION_MODE authmode;
1428 struct iw_point *erq = &(wrqu->encoding);
1429 struct _adapter *padapter = (struct _adapter *) _netdev_priv(dev);
1431 key = erq->flags & IW_ENCODE_INDEX;
1432 memset(&wep, 0, sizeof(struct NDIS_802_11_WEP));
1433 if (erq->flags & IW_ENCODE_DISABLED) {
1434 printk(KERN_INFO "r8712u: r8711_wx_set_enc: "
1435 "EncryptionDisabled\n");
1436 padapter->securitypriv.ndisencryptstatus =
1437 Ndis802_11EncryptionDisabled;
1438 padapter->securitypriv.PrivacyAlgrthm = _NO_PRIVACY_;
1439 padapter->securitypriv.XGrpPrivacy = _NO_PRIVACY_;
1440 padapter->securitypriv.AuthAlgrthm = 0; /* open system */
1441 authmode = Ndis802_11AuthModeOpen;
1442 padapter->securitypriv.ndisauthtype = authmode;
1449 keyindex_provided = 1;
1451 keyindex_provided = 0;
1452 key = padapter->securitypriv.PrivacyKeyIndex;
1454 /* set authentication mode */
1455 if (erq->flags & IW_ENCODE_OPEN) {
1456 printk(KERN_INFO "r8712u: r8711_wx_set_enc: "
1457 "IW_ENCODE_OPEN\n");
1458 padapter->securitypriv.ndisencryptstatus =
1459 Ndis802_11Encryption1Enabled;
1460 padapter->securitypriv.AuthAlgrthm = 0; /* open system */
1461 padapter->securitypriv.PrivacyAlgrthm = _NO_PRIVACY_;
1462 padapter->securitypriv.XGrpPrivacy = _NO_PRIVACY_;
1463 authmode = Ndis802_11AuthModeOpen;
1464 padapter->securitypriv.ndisauthtype = authmode;
1465 } else if (erq->flags & IW_ENCODE_RESTRICTED) {
1466 printk(KERN_INFO "r8712u: r8711_wx_set_enc: "
1467 "IW_ENCODE_RESTRICTED\n");
1468 padapter->securitypriv.ndisencryptstatus =
1469 Ndis802_11Encryption1Enabled;
1470 padapter->securitypriv.AuthAlgrthm = 1; /* shared system */
1471 padapter->securitypriv.PrivacyAlgrthm = _WEP40_;
1472 padapter->securitypriv.XGrpPrivacy = _WEP40_;
1473 authmode = Ndis802_11AuthModeShared;
1474 padapter->securitypriv.ndisauthtype = authmode;
1476 padapter->securitypriv.ndisencryptstatus =
1477 Ndis802_11Encryption1Enabled;
1478 padapter->securitypriv.AuthAlgrthm = 0; /* open system */
1479 padapter->securitypriv.PrivacyAlgrthm = _NO_PRIVACY_;
1480 padapter->securitypriv.XGrpPrivacy = _NO_PRIVACY_;
1481 authmode = Ndis802_11AuthModeOpen;
1482 padapter->securitypriv.ndisauthtype = authmode;
1485 if (erq->length > 0) {
1486 wep.KeyLength = erq->length <= 5 ? 5 : 13;
1487 wep.Length = wep.KeyLength +
1488 FIELD_OFFSET(struct NDIS_802_11_WEP, KeyMaterial);
1491 if (keyindex_provided == 1) { /* set key_id only, no given
1492 * KeyMaterial(erq->length==0).*/
1493 padapter->securitypriv.PrivacyKeyIndex = key;
1494 switch (padapter->securitypriv.DefKeylen[key]) {
1496 padapter->securitypriv.PrivacyAlgrthm =
1500 padapter->securitypriv.PrivacyAlgrthm =
1504 padapter->securitypriv.PrivacyAlgrthm =
1511 wep.KeyIndex |= 0x80000000; /* transmit key */
1512 memcpy(wep.KeyMaterial, keybuf, wep.KeyLength);
1513 if (r8712_set_802_11_add_wep(padapter, &wep) == _FAIL)
1518 static int r8711_wx_get_enc(struct net_device *dev,
1519 struct iw_request_info *info,
1520 union iwreq_data *wrqu, char *keybuf)
1523 struct _adapter *padapter = (struct _adapter *) _netdev_priv(dev);
1524 struct iw_point *erq = &(wrqu->encoding);
1525 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1527 if (check_fwstate(pmlmepriv, _FW_LINKED) == false) {
1528 if (!check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) {
1530 erq->flags |= IW_ENCODE_DISABLED;
1534 key = erq->flags & IW_ENCODE_INDEX;
1540 key = padapter->securitypriv.PrivacyKeyIndex;
1542 erq->flags = key + 1;
1543 switch (padapter->securitypriv.ndisencryptstatus) {
1544 case Ndis802_11EncryptionNotSupported:
1545 case Ndis802_11EncryptionDisabled:
1547 erq->flags |= IW_ENCODE_DISABLED;
1549 case Ndis802_11Encryption1Enabled:
1550 erq->length = padapter->securitypriv.DefKeylen[key];
1552 memcpy(keybuf, padapter->securitypriv.DefKey[
1553 key].skey, padapter->securitypriv.
1555 erq->flags |= IW_ENCODE_ENABLED;
1556 if (padapter->securitypriv.ndisauthtype ==
1557 Ndis802_11AuthModeOpen)
1558 erq->flags |= IW_ENCODE_OPEN;
1559 else if (padapter->securitypriv.ndisauthtype ==
1560 Ndis802_11AuthModeShared)
1561 erq->flags |= IW_ENCODE_RESTRICTED;
1564 erq->flags |= IW_ENCODE_DISABLED;
1567 case Ndis802_11Encryption2Enabled:
1568 case Ndis802_11Encryption3Enabled:
1570 erq->flags |= (IW_ENCODE_ENABLED | IW_ENCODE_OPEN |
1575 erq->flags |= IW_ENCODE_DISABLED;
1581 static int r8711_wx_get_power(struct net_device *dev,
1582 struct iw_request_info *info,
1583 union iwreq_data *wrqu, char *extra)
1585 wrqu->power.value = 0;
1586 wrqu->power.fixed = 0; /* no auto select */
1587 wrqu->power.disabled = 1;
1591 static int r871x_wx_set_gen_ie(struct net_device *dev,
1592 struct iw_request_info *info,
1593 union iwreq_data *wrqu, char *extra)
1595 struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
1597 return r871x_set_wpa_ie(padapter, extra, wrqu->data.length);
1600 static int r871x_wx_set_auth(struct net_device *dev,
1601 struct iw_request_info *info,
1602 union iwreq_data *wrqu, char *extra)
1604 struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
1605 struct iw_param *param = (struct iw_param *)&(wrqu->param);
1610 paramid = param->flags & IW_AUTH_INDEX;
1611 paramval = param->value;
1613 case IW_AUTH_WPA_VERSION:
1615 case IW_AUTH_CIPHER_PAIRWISE:
1617 case IW_AUTH_CIPHER_GROUP:
1619 case IW_AUTH_KEY_MGMT:
1621 * ??? does not use these parameters
1624 case IW_AUTH_TKIP_COUNTERMEASURES:
1626 /* wpa_supplicant is enabling tkip countermeasure. */
1627 padapter->securitypriv.btkip_countermeasure = true;
1629 /* wpa_supplicant is disabling tkip countermeasure. */
1630 padapter->securitypriv.btkip_countermeasure = false;
1633 case IW_AUTH_DROP_UNENCRYPTED:
1636 * wpa_supplicant calls set_wpa_enabled when the driver
1637 * is loaded and unloaded, regardless of if WPA is being
1638 * used. No other calls are made which can be used to
1639 * determine if encryption will be used or not prior to
1640 * association being expected. If encryption is not being
1641 * used, drop_unencrypted is set to false, else true -- we
1642 * can use this to determine if the CAP_PRIVACY_ON bit should
1645 if (padapter->securitypriv.ndisencryptstatus ==
1646 Ndis802_11Encryption1Enabled) {
1647 /* it means init value, or using wep,
1648 * ndisencryptstatus =
1649 * Ndis802_11Encryption1Enabled,
1650 * then it needn't reset it;
1656 padapter->securitypriv.ndisencryptstatus =
1657 Ndis802_11EncryptionDisabled;
1658 padapter->securitypriv.PrivacyAlgrthm =
1660 padapter->securitypriv.XGrpPrivacy =
1662 padapter->securitypriv.AuthAlgrthm = 0;
1663 padapter->securitypriv.ndisauthtype =
1664 Ndis802_11AuthModeOpen;
1667 case IW_AUTH_80211_AUTH_ALG:
1668 ret = wpa_set_auth_algs(dev, (u32)paramval);
1670 case IW_AUTH_WPA_ENABLED:
1672 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
1674 case IW_AUTH_PRIVACY_INVOKED:
1683 static int r871x_wx_set_enc_ext(struct net_device *dev,
1684 struct iw_request_info *info,
1685 union iwreq_data *wrqu, char *extra)
1687 struct iw_point *pencoding = &wrqu->encoding;
1688 struct iw_encode_ext *pext = (struct iw_encode_ext *)extra;
1689 struct ieee_param *param = NULL;
1694 param_len = sizeof(struct ieee_param) + pext->key_len;
1695 param = (struct ieee_param *)_malloc(param_len);
1698 memset(param, 0, param_len);
1699 param->cmd = IEEE_CMD_SET_ENCRYPTION;
1700 memset(param->sta_addr, 0xff, ETH_ALEN);
1701 switch (pext->alg) {
1702 case IW_ENCODE_ALG_NONE:
1705 case IW_ENCODE_ALG_WEP:
1708 case IW_ENCODE_ALG_TKIP:
1711 case IW_ENCODE_ALG_CCMP:
1717 strncpy((char *)param->u.crypt.alg, alg_name, IEEE_CRYPT_ALG_NAME_LEN);
1718 if (pext->ext_flags & IW_ENCODE_EXT_GROUP_KEY)
1719 param->u.crypt.set_tx = 0;
1720 if (pext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
1721 param->u.crypt.set_tx = 1;
1722 param->u.crypt.idx = (pencoding->flags & 0x00FF) - 1;
1723 if (pext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID)
1724 memcpy(param->u.crypt.seq, pext->rx_seq, 8);
1725 if (pext->key_len) {
1726 param->u.crypt.key_len = pext->key_len;
1727 memcpy(param + 1, pext + 1, pext->key_len);
1729 ret = wpa_set_encryption(dev, param, param_len);
1735 static int r871x_wx_get_nick(struct net_device *dev,
1736 struct iw_request_info *info,
1737 union iwreq_data *wrqu, char *extra)
1740 wrqu->data.length = 8;
1741 wrqu->data.flags = 1;
1742 memcpy(extra, "rtl_wifi", 8);
1747 static int r8711_wx_read32(struct net_device *dev,
1748 struct iw_request_info *info,
1749 union iwreq_data *wrqu, char *keybuf)
1751 struct _adapter *padapter = (struct _adapter *) _netdev_priv(dev);
1755 get_user(addr, (u32 __user *)wrqu->data.pointer);
1756 data32 = r8712_read32(padapter, addr);
1757 put_user(data32, (u32 __user *)wrqu->data.pointer);
1758 wrqu->data.length = (data32 & 0xffff0000) >> 16;
1759 wrqu->data.flags = data32 & 0xffff;
1760 get_user(addr, (u32 __user *)wrqu->data.pointer);
1764 static int r8711_wx_write32(struct net_device *dev,
1765 struct iw_request_info *info,
1766 union iwreq_data *wrqu, char *keybuf)
1768 struct _adapter *padapter = (struct _adapter *) _netdev_priv(dev);
1772 get_user(addr, (u32 __user *)wrqu->data.pointer);
1773 data32 = ((u32)wrqu->data.length<<16) | (u32)wrqu->data.flags ;
1774 r8712_write32(padapter, addr, data32);
1778 static int dummy(struct net_device *dev,
1779 struct iw_request_info *a,
1780 union iwreq_data *wrqu, char *b)
1785 static int r8711_drvext_hdl(struct net_device *dev,
1786 struct iw_request_info *info,
1787 union iwreq_data *wrqu, char *extra)
1792 static int r871x_mp_ioctl_hdl(struct net_device *dev,
1793 struct iw_request_info *info,
1794 union iwreq_data *wrqu, char *extra)
1796 struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
1797 struct iw_point *p = &wrqu->data;
1798 struct oid_par_priv oid_par;
1799 struct mp_ioctl_handler *phandler;
1800 struct mp_ioctl_param *poidparam;
1801 unsigned long BytesRead, BytesWritten, BytesNeeded;
1802 u8 *pparmbuf = NULL, bset;
1807 if ((!p->length) || (!p->pointer)) {
1809 goto _r871x_mp_ioctl_hdl_exit;
1811 bset = (u8)(p->flags & 0xFFFF);
1814 pparmbuf = (u8 *)_malloc(len);
1815 if (pparmbuf == NULL) {
1817 goto _r871x_mp_ioctl_hdl_exit;
1819 if (copy_from_user(pparmbuf, p->pointer, len)) {
1821 goto _r871x_mp_ioctl_hdl_exit;
1823 poidparam = (struct mp_ioctl_param *)pparmbuf;
1824 if (poidparam->subcode >= MAX_MP_IOCTL_SUBCODE) {
1826 goto _r871x_mp_ioctl_hdl_exit;
1828 phandler = mp_ioctl_hdl + poidparam->subcode;
1829 if ((phandler->paramsize != 0) &&
1830 (poidparam->len < phandler->paramsize)) {
1832 goto _r871x_mp_ioctl_hdl_exit;
1834 if (phandler->oid == 0 && phandler->handler)
1835 status = phandler->handler(&oid_par);
1836 else if (phandler->handler) {
1837 oid_par.adapter_context = padapter;
1838 oid_par.oid = phandler->oid;
1839 oid_par.information_buf = poidparam->data;
1840 oid_par.information_buf_len = poidparam->len;
1845 oid_par.bytes_rw = &BytesRead;
1846 oid_par.bytes_needed = &BytesNeeded;
1847 oid_par.type_of_oid = SET_OID;
1849 oid_par.bytes_rw = &BytesWritten;
1850 oid_par.bytes_needed = &BytesNeeded;
1851 oid_par.type_of_oid = QUERY_OID;
1853 status = phandler->handler(&oid_par);
1854 /* todo:check status, BytesNeeded, etc. */
1856 printk(KERN_INFO "r8712u: r871x_mp_ioctl_hdl(): err!,"
1857 " subcode=%d, oid=%d, handler=%p\n",
1858 poidparam->subcode, phandler->oid, phandler->handler);
1860 goto _r871x_mp_ioctl_hdl_exit;
1862 if (bset == 0x00) { /* query info */
1863 if (copy_to_user(p->pointer, pparmbuf, len))
1868 goto _r871x_mp_ioctl_hdl_exit;
1870 _r871x_mp_ioctl_hdl_exit:
1871 if (pparmbuf != NULL)
1876 static int r871x_get_ap_info(struct net_device *dev,
1877 struct iw_request_info *info,
1878 union iwreq_data *wrqu, char *extra)
1880 struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
1881 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1882 struct __queue *queue = &pmlmepriv->scanned_queue;
1883 struct iw_point *pdata = &wrqu->data;
1884 struct wlan_network *pnetwork = NULL;
1885 u32 cnt = 0, wpa_ielen;
1887 struct list_head *plist, *phead;
1888 unsigned char *pbuf;
1892 if (padapter->bDriverStopped || (pdata == NULL))
1894 while (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING)) {
1901 if (pdata->length >= 32) {
1902 if (copy_from_user(data, pdata->pointer, 32))
1906 spin_lock_irqsave(&(pmlmepriv->scanned_queue.lock), irqL);
1907 phead = get_list_head(queue);
1908 plist = get_next(phead);
1910 if (end_of_queue_search(phead, plist) == true)
1912 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
1913 if (hwaddr_aton_i(data, bssid)) {
1914 printk(KERN_INFO "r8712u: Invalid BSSID '%s'.\n",
1916 spin_unlock_irqrestore(&(pmlmepriv->scanned_queue.lock),
1920 printk(KERN_INFO "r8712u: BSSID:%pM\n", bssid);
1921 if (!memcmp(bssid, pnetwork->network.MacAddress, ETH_ALEN)) {
1922 /* BSSID match, then check if supporting wpa/wpa2 */
1923 pbuf = r8712_get_wpa_ie(&pnetwork->network.IEs[12],
1924 &wpa_ielen, pnetwork->network.IELength-12);
1925 if (pbuf && (wpa_ielen > 0)) {
1929 pbuf = r8712_get_wpa2_ie(&pnetwork->network.IEs[12],
1930 &wpa_ielen, pnetwork->network.IELength-12);
1931 if (pbuf && (wpa_ielen > 0)) {
1936 plist = get_next(plist);
1938 spin_unlock_irqrestore(&(pmlmepriv->scanned_queue.lock), irqL);
1939 if (pdata->length >= 34) {
1940 if (copy_to_user((u8 __user *)pdata->pointer + 32,
1941 (u8 *)&pdata->flags, 1))
1947 static int r871x_set_pid(struct net_device *dev,
1948 struct iw_request_info *info,
1949 union iwreq_data *wrqu, char *extra)
1951 struct _adapter *padapter = (struct _adapter *) _netdev_priv(dev);
1952 struct iw_point *pdata = &wrqu->data;
1954 if ((padapter->bDriverStopped) || (pdata == NULL))
1956 if (copy_from_user(&padapter->pid, pdata->pointer, sizeof(int)))
1961 static int r871x_wps_start(struct net_device *dev,
1962 struct iw_request_info *info,
1963 union iwreq_data *wrqu, char *extra)
1965 struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
1966 struct iw_point *pdata = &wrqu->data;
1967 u32 u32wps_start = 0;
1968 unsigned int uintRet = 0;
1970 uintRet = copy_from_user((void *)&u32wps_start, pdata->pointer, 4);
1971 if ((padapter->bDriverStopped) || (pdata == NULL))
1973 if (u32wps_start == 0)
1974 u32wps_start = *extra;
1975 if (u32wps_start == 1) /* WPS Start */
1976 padapter->ledpriv.LedControlHandler(padapter,
1978 else if (u32wps_start == 2) /* WPS Stop because of wps success */
1979 padapter->ledpriv.LedControlHandler(padapter,
1981 else if (u32wps_start == 3) /* WPS Stop because of wps fail */
1982 padapter->ledpriv.LedControlHandler(padapter,
1983 LED_CTL_STOP_WPS_FAIL);
1987 static int wpa_set_param(struct net_device *dev, u8 name, u32 value)
1989 struct _adapter *padapter = (struct _adapter *) _netdev_priv(dev);
1992 case IEEE_PARAM_WPA_ENABLED:
1993 padapter->securitypriv.AuthAlgrthm = 2; /* 802.1x */
1994 switch ((value)&0xff) {
1996 padapter->securitypriv.ndisauthtype =
1997 Ndis802_11AuthModeWPAPSK; /* WPA_PSK */
1998 padapter->securitypriv.ndisencryptstatus =
1999 Ndis802_11Encryption2Enabled;
2002 padapter->securitypriv.ndisauthtype =
2003 Ndis802_11AuthModeWPA2PSK; /* WPA2_PSK */
2004 padapter->securitypriv.ndisencryptstatus =
2005 Ndis802_11Encryption3Enabled;
2009 case IEEE_PARAM_TKIP_COUNTERMEASURES:
2011 case IEEE_PARAM_DROP_UNENCRYPTED:
2014 * wpa_supplicant calls set_wpa_enabled when the driver
2015 * is loaded and unloaded, regardless of if WPA is being
2016 * used. No other calls are made which can be used to
2017 * determine if encryption will be used or not prior to
2018 * association being expected. If encryption is not being
2019 * used, drop_unencrypted is set to false, else true -- we
2020 * can use this to determine if the CAP_PRIVACY_ON bit should
2024 case IEEE_PARAM_PRIVACY_INVOKED:
2026 case IEEE_PARAM_AUTH_ALGS:
2027 return wpa_set_auth_algs(dev, value);
2029 case IEEE_PARAM_IEEE_802_1X:
2031 case IEEE_PARAM_WPAX_SELECT:
2032 /* added for WPA2 mixed mode */
2040 static int wpa_mlme(struct net_device *dev, u32 command, u32 reason)
2042 struct _adapter *padapter = (struct _adapter *) _netdev_priv(dev);
2045 case IEEE_MLME_STA_DEAUTH:
2046 if (!r8712_set_802_11_disassociate(padapter))
2049 case IEEE_MLME_STA_DISASSOC:
2050 if (!r8712_set_802_11_disassociate(padapter))
2059 static int wpa_supplicant_ioctl(struct net_device *dev, struct iw_point *p)
2061 struct ieee_param *param;
2063 struct _adapter *padapter = (struct _adapter *) _netdev_priv(dev);
2065 if (p->length < sizeof(struct ieee_param) || !p->pointer)
2067 param = (struct ieee_param *)_malloc(p->length);
2070 if (copy_from_user(param, p->pointer, p->length))
2073 switch (param->cmd) {
2074 case IEEE_CMD_SET_WPA_PARAM:
2075 ret = wpa_set_param(dev, param->u.wpa_param.name,
2076 param->u.wpa_param.value);
2078 case IEEE_CMD_SET_WPA_IE:
2079 ret = r871x_set_wpa_ie(padapter, (char *)param->u.wpa_ie.data,
2080 (u16)param->u.wpa_ie.len);
2082 case IEEE_CMD_SET_ENCRYPTION:
2083 ret = wpa_set_encryption(dev, param, p->length);
2086 ret = wpa_mlme(dev, param->u.mlme.command,
2087 param->u.mlme.reason_code);
2093 if (ret == 0 && copy_to_user(p->pointer, param, p->length))
2099 /* based on "driver_ipw" and for hostapd */
2100 int r871x_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
2102 struct iwreq *wrq = (struct iwreq *)rq;
2105 case RTL_IOCTL_WPA_SUPPLICANT:
2106 return wpa_supplicant_ioctl(dev, &wrq->u.data);
2113 static iw_handler r8711_handlers[] = {
2114 NULL, /* SIOCSIWCOMMIT */
2115 r8711_wx_get_name, /* SIOCGIWNAME */
2116 dummy, /* SIOCSIWNWID */
2117 dummy, /* SIOCGIWNWID */
2118 r8711_wx_set_freq, /* SIOCSIWFREQ */
2119 r8711_wx_get_freq, /* SIOCGIWFREQ */
2120 r8711_wx_set_mode, /* SIOCSIWMODE */
2121 r8711_wx_get_mode, /* SIOCGIWMODE */
2122 dummy, /* SIOCSIWSENS */
2123 r8711_wx_get_sens, /* SIOCGIWSENS */
2124 NULL, /* SIOCSIWRANGE */
2125 r8711_wx_get_range, /* SIOCGIWRANGE */
2126 r871x_wx_set_priv, /* SIOCSIWPRIV */
2127 NULL, /* SIOCGIWPRIV */
2128 NULL, /* SIOCSIWSTATS */
2129 NULL, /* SIOCGIWSTATS */
2130 dummy, /* SIOCSIWSPY */
2131 dummy, /* SIOCGIWSPY */
2132 NULL, /* SIOCGIWTHRSPY */
2133 NULL, /* SIOCWIWTHRSPY */
2134 r8711_wx_set_wap, /* SIOCSIWAP */
2135 r8711_wx_get_wap, /* SIOCGIWAP */
2136 r871x_wx_set_mlme, /* request MLME operation;
2137 * uses struct iw_mlme */
2138 dummy, /* SIOCGIWAPLIST -- deprecated */
2139 r8711_wx_set_scan, /* SIOCSIWSCAN */
2140 r8711_wx_get_scan, /* SIOCGIWSCAN */
2141 r8711_wx_set_essid, /* SIOCSIWESSID */
2142 r8711_wx_get_essid, /* SIOCGIWESSID */
2143 dummy, /* SIOCSIWNICKN */
2144 r871x_wx_get_nick, /* SIOCGIWNICKN */
2145 NULL, /* -- hole -- */
2146 NULL, /* -- hole -- */
2147 r8711_wx_set_rate, /* SIOCSIWRATE */
2148 r8711_wx_get_rate, /* SIOCGIWRATE */
2149 dummy, /* SIOCSIWRTS */
2150 r8711_wx_get_rts, /* SIOCGIWRTS */
2151 r8711_wx_set_frag, /* SIOCSIWFRAG */
2152 r8711_wx_get_frag, /* SIOCGIWFRAG */
2153 dummy, /* SIOCSIWTXPOW */
2154 dummy, /* SIOCGIWTXPOW */
2155 dummy, /* SIOCSIWRETRY */
2156 r8711_wx_get_retry, /* SIOCGIWRETRY */
2157 r8711_wx_set_enc, /* SIOCSIWENCODE */
2158 r8711_wx_get_enc, /* SIOCGIWENCODE */
2159 dummy, /* SIOCSIWPOWER */
2160 r8711_wx_get_power, /* SIOCGIWPOWER */
2161 NULL, /*---hole---*/
2162 NULL, /*---hole---*/
2163 r871x_wx_set_gen_ie, /* SIOCSIWGENIE */
2164 NULL, /* SIOCGIWGENIE */
2165 r871x_wx_set_auth, /* SIOCSIWAUTH */
2166 NULL, /* SIOCGIWAUTH */
2167 r871x_wx_set_enc_ext, /* SIOCSIWENCODEEXT */
2168 NULL, /* SIOCGIWENCODEEXT */
2169 r871x_wx_set_pmkid, /* SIOCSIWPMKSA */
2170 NULL, /*---hole---*/
2173 static const struct iw_priv_args r8711_private_args[] = {
2175 SIOCIWFIRSTPRIV + 0x0,
2176 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "read32"
2179 SIOCIWFIRSTPRIV + 0x1,
2180 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "write32"
2183 SIOCIWFIRSTPRIV + 0x2, 0, 0, "driver_ext"
2186 SIOCIWFIRSTPRIV + 0x3, 0, 0, "mp_ioctl"
2189 SIOCIWFIRSTPRIV + 0x4,
2190 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "apinfo"
2193 SIOCIWFIRSTPRIV + 0x5,
2194 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setpid"
2197 SIOCIWFIRSTPRIV + 0x6,
2198 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wps_start"
2202 static iw_handler r8711_private_handler[] = {
2207 r871x_get_ap_info, /*for MM DTV platform*/
2212 static struct iw_statistics *r871x_get_wireless_stats(struct net_device *dev)
2214 struct _adapter *padapter = (struct _adapter *) _netdev_priv(dev);
2215 struct iw_statistics *piwstats = &padapter->iwstats;
2220 if (check_fwstate(&padapter->mlmepriv, _FW_LINKED) != true) {
2221 piwstats->qual.qual = 0;
2222 piwstats->qual.level = 0;
2223 piwstats->qual.noise = 0;
2225 /* show percentage, we need transfer dbm to orignal value. */
2226 tmp_level = padapter->recvpriv.fw_rssi;
2227 tmp_qual = padapter->recvpriv.signal;
2228 tmp_noise = padapter->recvpriv.noise;
2229 piwstats->qual.level = tmp_level;
2230 piwstats->qual.qual = tmp_qual;
2231 piwstats->qual.noise = tmp_noise;
2233 piwstats->qual.updated = IW_QUAL_ALL_UPDATED;
2234 return &padapter->iwstats;
2237 struct iw_handler_def r871x_handlers_def = {
2238 .standard = r8711_handlers,
2239 .num_standard = sizeof(r8711_handlers) / sizeof(iw_handler),
2240 .private = r8711_private_handler,
2241 .private_args = (struct iw_priv_args *)r8711_private_args,
2242 .num_private = sizeof(r8711_private_handler) / sizeof(iw_handler),
2243 .num_private_args = sizeof(r8711_private_args) /
2244 sizeof(struct iw_priv_args),
2245 .get_wireless_stats = r871x_get_wireless_stats,