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"
43 #define RTL_IOCTL_WPA_SUPPLICANT (SIOCIWFIRSTPRIV + 30)
45 #define SCAN_ITEM_SIZE 768
46 #define MAX_CUSTOM_LEN 64
50 static const u32 rtl8180_rates[] = {1000000, 2000000, 5500000, 11000000,
51 6000000, 9000000, 12000000, 18000000,
52 24000000, 36000000, 48000000, 54000000};
54 static const long ieee80211_wlan_frequencies[] = {
55 2412, 2417, 2422, 2427,
56 2432, 2437, 2442, 2447,
57 2452, 2457, 2462, 2467,
61 static const char * const iw_operation_mode[] = {
62 "Auto", "Ad-Hoc", "Managed", "Master", "Repeater", "Secondary",
67 * hwaddr_aton - Convert ASCII string to MAC address
68 * @txt: MAC address as a string (e.g., "00:11:22:33:44:55")
69 * @addr: Buffer for the MAC address (ETH_ALEN = 6 bytes)
70 * Returns: 0 on success, -1 on failure (e.g., string not a MAC address)
72 static int hwaddr_aton_i(const char *txt, u8 *addr)
76 for (i = 0; i < 6; i++) {
79 a = hex_to_bin(*txt++);
82 b = hex_to_bin(*txt++);
85 *addr++ = (a << 4) | b;
86 if (i < 5 && *txt++ != ':')
92 void r8712_indicate_wx_assoc_event(struct _adapter *padapter)
94 union iwreq_data wrqu;
95 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
97 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
98 memcpy(wrqu.ap_addr.sa_data, pmlmepriv->cur_network.network.MacAddress,
100 wireless_send_event(padapter->pnetdev, SIOCGIWAP, &wrqu, NULL);
103 void r8712_indicate_wx_disassoc_event(struct _adapter *padapter)
105 union iwreq_data wrqu;
107 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
108 memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN);
109 wireless_send_event(padapter->pnetdev, SIOCGIWAP, &wrqu, NULL);
112 static inline void handle_pairwise_key(struct sta_info *psta,
113 struct ieee_param *param,
114 struct _adapter *padapter)
117 memcpy(psta->x_UncstKey.skey, param->u.crypt.key,
118 (param->u.crypt. key_len > 16 ? 16 : param->u.crypt.key_len));
119 if (strcmp(param->u.crypt.alg, "TKIP") == 0) { /* set mic key */
120 memcpy(psta->tkiptxmickey. skey, &(param->u.crypt.
122 memcpy(psta->tkiprxmickey. skey, &(param->u.crypt.
124 padapter->securitypriv. busetkipkey = false;
125 _set_timer(&padapter->securitypriv.tkip_timer, 50);
127 r8712_setstakey_cmd(padapter, (unsigned char *)psta, true);
130 static inline void handle_group_key(struct ieee_param *param,
131 struct _adapter *padapter)
133 if (0 < param->u.crypt.idx &&
134 param->u.crypt.idx < 3) {
135 /* group key idx is 1 or 2 */
136 memcpy(padapter->securitypriv.XGrpKey[param->u.crypt.
137 idx-1].skey, param->u.crypt.key, (param->u.crypt.key_len
138 > 16 ? 16 : param->u.crypt.key_len));
139 memcpy(padapter->securitypriv.XGrptxmickey[param->
140 u.crypt.idx-1].skey, &(param->u.crypt.key[16]), 8);
141 memcpy(padapter->securitypriv. XGrprxmickey[param->
142 u.crypt.idx-1].skey, &(param->u.crypt.key[24]), 8);
143 padapter->securitypriv.binstallGrpkey = true;
144 r8712_set_key(padapter, &padapter->securitypriv,
146 if (padapter->registrypriv.power_mgnt > PS_MODE_ACTIVE) {
147 if (padapter->registrypriv.power_mgnt != padapter->
148 pwrctrlpriv.pwr_mode)
149 _set_timer(&(padapter->mlmepriv.dhcp_timer),
155 static inline char *translate_scan(struct _adapter *padapter,
156 struct iw_request_info *info,
157 struct wlan_network *pnetwork,
158 char *start, char *stop)
161 struct ieee80211_ht_cap *pht_capie;
163 u8 *buf = (u8 *)_malloc(pnetwork->network.IELength * 2);
164 u8 *wpa_ie = (u8 *)_malloc(255);
165 u8 *rsn_ie = (u8 *)_malloc(255);
166 u8 *wps_ie = (u8 *)_malloc(MAX_WPS_IE_LEN);
168 u32 i = 0, ht_ielen = 0;
169 u16 cap, ht_cap = false, mcs_rate;
170 u8 rssi, bw_40MHz = 0, short_GI = 0;
172 if ((pnetwork->network.Configuration.DSConfig < 1) ||
173 (pnetwork->network.Configuration.DSConfig > 14)) {
174 if (pnetwork->network.Configuration.DSConfig < 1)
175 pnetwork->network.Configuration.DSConfig = 1;
177 pnetwork->network.Configuration.DSConfig = 14;
181 iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
182 memcpy(iwe.u.ap_addr.sa_data, pnetwork->network.MacAddress, ETH_ALEN);
183 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_ADDR_LEN);
185 iwe.cmd = SIOCGIWESSID;
186 iwe.u.data.flags = 1;
187 iwe.u.data.length = (u16)min((u16)pnetwork->network.Ssid.SsidLength,
189 start = iwe_stream_add_point(info, start, stop, &iwe,
190 pnetwork->network.Ssid.Ssid);
191 /* parsing HT_CAP_IE */
192 p = r8712_get_ie(&pnetwork->network.IEs[12], _HT_CAPABILITY_IE_,
193 &ht_ielen, pnetwork->network.IELength - 12);
194 if (p && ht_ielen > 0) {
196 pht_capie = (struct ieee80211_ht_cap *)(p + 2);
197 memcpy(&mcs_rate , pht_capie->supp_mcs_set, 2);
198 bw_40MHz = (pht_capie->cap_info&IEEE80211_HT_CAP_SUP_WIDTH)
200 short_GI = (pht_capie->cap_info&(IEEE80211_HT_CAP_SGI_20 |
201 IEEE80211_HT_CAP_SGI_40)) ? 1 : 0;
203 /* Add the protocol name */
204 iwe.cmd = SIOCGIWNAME;
205 if ((r8712_is_cckratesonly_included((u8 *)&pnetwork->network.
206 SupportedRates)) == true) {
208 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bn");
210 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11b");
211 } else if ((r8712_is_cckrates_included((u8 *)&pnetwork->network.
212 SupportedRates)) == true) {
214 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bgn");
216 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bg");
219 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11gn");
221 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11g");
223 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_CHAR_LEN);
225 iwe.cmd = SIOCGIWMODE;
226 memcpy((u8 *)&cap, r8712_get_capability_from_ie(pnetwork->network.IEs),
228 cap = le16_to_cpu(cap);
229 if (cap & (WLAN_CAPABILITY_IBSS|WLAN_CAPABILITY_BSS)) {
230 if (cap & WLAN_CAPABILITY_BSS)
231 iwe.u.mode = (u32)IW_MODE_MASTER;
233 iwe.u.mode = (u32)IW_MODE_ADHOC;
234 start = iwe_stream_add_event(info, start, stop, &iwe,
237 /* Add frequency/channel */
238 iwe.cmd = SIOCGIWFREQ;
240 /* check legel index */
241 u8 dsconfig = pnetwork->network.Configuration.DSConfig;
242 if (dsconfig >= 1 && dsconfig <= sizeof(
243 ieee80211_wlan_frequencies) / sizeof(long))
244 iwe.u.freq.m = (s32)(ieee80211_wlan_frequencies[
245 pnetwork->network.Configuration.
246 DSConfig - 1] * 100000);
250 iwe.u.freq.e = (s16)1;
251 iwe.u.freq.i = (u8)pnetwork->network.Configuration.DSConfig;
252 start = iwe_stream_add_event(info, start, stop, &iwe,
254 /* Add encryption capability */
255 iwe.cmd = SIOCGIWENCODE;
256 if (cap & WLAN_CAPABILITY_PRIVACY)
257 iwe.u.data.flags = (u16)(IW_ENCODE_ENABLED |
260 iwe.u.data.flags = (u16)(IW_ENCODE_DISABLED);
261 iwe.u.data.length = (u16)0;
262 start = iwe_stream_add_point(info, start, stop, &iwe,
263 pnetwork->network.Ssid.Ssid);
264 /*Add basic and extended rates */
265 current_val = start + iwe_stream_lcp_len(info);
266 iwe.cmd = SIOCGIWRATE;
267 iwe.u.bitrate.fixed = 0;
268 iwe.u.bitrate.disabled = 0;
269 iwe.u.bitrate.value = 0;
271 while (pnetwork->network.SupportedRates[i] != 0) {
272 /* Bit rate given in 500 kb/s units */
273 iwe.u.bitrate.value = (pnetwork->network.SupportedRates[i++] &
275 current_val = iwe_stream_add_value(info, start, current_val,
276 stop, &iwe, IW_EV_PARAM_LEN);
278 /* Check if we added any event */
279 if ((current_val - start) > iwe_stream_lcp_len(info))
281 /* parsing WPA/WPA2 IE */
283 u16 wpa_len = 0, rsn_len = 0;
286 out_len = r8712_get_sec_ie(pnetwork->network.IEs,
288 IELength, rsn_ie, &rsn_len,
292 memset(buf, 0, MAX_WPA_IE_LEN);
293 p += snprintf(p, 7, "wpa_ie=");
294 for (i = 0; i < wpa_len; i++)
295 p += snprintf(p, 2, "%02x", wpa_ie[i]);
296 memset(&iwe, 0, sizeof(iwe));
297 iwe.cmd = IWEVCUSTOM;
298 iwe.u.data.length = (u16)strlen(buf);
299 start = iwe_stream_add_point(info, start, stop,
301 memset(&iwe, 0, sizeof(iwe));
303 iwe.u.data.length = (u16)wpa_len;
304 start = iwe_stream_add_point(info, start, stop,
309 memset(buf, 0, MAX_WPA_IE_LEN);
310 p += snprintf(p, 7, "rsn_ie=");
311 for (i = 0; i < rsn_len; i++)
312 p += snprintf(p, 2, "%02x", rsn_ie[i]);
313 memset(&iwe, 0, sizeof(iwe));
314 iwe.cmd = IWEVCUSTOM;
315 iwe.u.data.length = strlen(buf);
316 start = iwe_stream_add_point(info, start, stop,
318 memset(&iwe, 0, sizeof(iwe));
320 iwe.u.data.length = rsn_len;
321 start = iwe_stream_add_point(info, start, stop, &iwe,
326 { /* parsing WPS IE */
329 if (r8712_get_wps_ie(pnetwork->network.IEs,
330 pnetwork->network.IELength,
331 wps_ie, &wps_ielen) == true) {
334 iwe.u.data.length = (u16)wps_ielen;
335 start = iwe_stream_add_point(info, start, stop,
340 /* Add quality statistics */
342 rssi = r8712_signal_scale_mapping(pnetwork->network.Rssi);
343 /* we only update signal_level (signal strength) that is rssi. */
344 iwe.u.qual.updated = (u8)(IW_QUAL_QUAL_INVALID | IW_QUAL_LEVEL_UPDATED |
345 IW_QUAL_NOISE_INVALID);
346 iwe.u.qual.level = rssi; /* signal strength */
347 iwe.u.qual.qual = 0; /* signal quality */
348 iwe.u.qual.noise = 0; /* noise level */
349 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_QUAL_LEN);
350 /* how to translate rssi to ?% */
358 static int wpa_set_auth_algs(struct net_device *dev, u32 value)
360 struct _adapter *padapter = (struct _adapter *) _netdev_priv(dev);
363 if ((value & AUTH_ALG_SHARED_KEY) && (value & AUTH_ALG_OPEN_SYSTEM)) {
364 padapter->securitypriv.ndisencryptstatus =
365 Ndis802_11Encryption1Enabled;
366 padapter->securitypriv.ndisauthtype =
367 Ndis802_11AuthModeAutoSwitch;
368 padapter->securitypriv.AuthAlgrthm = 3;
369 } else if (value & AUTH_ALG_SHARED_KEY) {
370 padapter->securitypriv.ndisencryptstatus =
371 Ndis802_11Encryption1Enabled;
372 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeShared;
373 padapter->securitypriv.AuthAlgrthm = 1;
374 } else if (value & AUTH_ALG_OPEN_SYSTEM) {
375 if (padapter->securitypriv.ndisauthtype <
376 Ndis802_11AuthModeWPAPSK) {
377 padapter->securitypriv.ndisauthtype =
378 Ndis802_11AuthModeOpen;
379 padapter->securitypriv.AuthAlgrthm = 0;
386 static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param,
390 u32 wep_key_idx, wep_key_len = 0;
391 struct NDIS_802_11_WEP *pwep = NULL;
392 struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
393 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
394 struct security_priv *psecuritypriv = &padapter->securitypriv;
396 param->u.crypt.err = 0;
397 param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
398 if (param_len != (u32)((u8 *) param->u.crypt.key - (u8 *)param) +
399 param->u.crypt.key_len)
401 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
402 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
403 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
404 if (param->u.crypt.idx >= WEP_KEYS) {
405 /* for large key indices, set the default (0) */
406 param->u.crypt.idx = 0;
410 if (strcmp(param->u.crypt.alg, "WEP") == 0) {
411 printk(KERN_INFO "r8712u: wpa_set_encryption, crypt.alg ="
413 padapter->securitypriv.ndisencryptstatus =
414 Ndis802_11Encryption1Enabled;
415 padapter->securitypriv.PrivacyAlgrthm = _WEP40_;
416 padapter->securitypriv.XGrpPrivacy = _WEP40_;
417 wep_key_idx = param->u.crypt.idx;
418 wep_key_len = param->u.crypt.key_len;
419 if (wep_key_idx >= WEP_KEYS)
421 if (wep_key_len > 0) {
422 wep_key_len = wep_key_len <= 5 ? 5 : 13;
423 pwep = (struct NDIS_802_11_WEP *)_malloc((u32)
425 FIELD_OFFSET(struct NDIS_802_11_WEP,
429 memset(pwep, 0, sizeof(struct NDIS_802_11_WEP));
430 pwep->KeyLength = wep_key_len;
431 pwep->Length = wep_key_len +
432 FIELD_OFFSET(struct NDIS_802_11_WEP,
434 if (wep_key_len == 13) {
435 padapter->securitypriv.PrivacyAlgrthm =
437 padapter->securitypriv.XGrpPrivacy =
442 pwep->KeyIndex = wep_key_idx;
443 pwep->KeyIndex |= 0x80000000;
444 memcpy(pwep->KeyMaterial, param->u.crypt.key, pwep->KeyLength);
445 if (param->u.crypt.set_tx) {
446 if (r8712_set_802_11_add_wep(padapter, pwep) ==
450 /* don't update "psecuritypriv->PrivacyAlgrthm" and
451 * "psecuritypriv->PrivacyKeyIndex=keyid", but can
452 * r8712_set_key to fw/cam
454 if (wep_key_idx >= WEP_KEYS) {
458 memcpy(&(psecuritypriv->DefKey[wep_key_idx].
459 skey[0]), pwep->KeyMaterial,
461 psecuritypriv->DefKeylen[wep_key_idx] =
463 r8712_set_key(padapter, psecuritypriv, wep_key_idx);
467 if (padapter->securitypriv.AuthAlgrthm == 2) { /* 802_1x */
468 struct sta_info *psta, *pbcmc_sta;
469 struct sta_priv *pstapriv = &padapter->stapriv;
471 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE |
472 WIFI_MP_STATE) == true) { /* sta mode */
473 psta = r8712_get_stainfo(pstapriv,
474 get_bssid(pmlmepriv));
476 psta->ieee8021x_blocked = false;
477 if ((padapter->securitypriv.ndisencryptstatus ==
478 Ndis802_11Encryption2Enabled) ||
479 (padapter->securitypriv.ndisencryptstatus ==
480 Ndis802_11Encryption3Enabled))
481 psta->XPrivacy = padapter->
482 securitypriv.PrivacyAlgrthm;
483 if (param->u.crypt.set_tx == 1)
484 handle_pairwise_key(psta, param,
487 handle_group_key(param, padapter);
489 pbcmc_sta = r8712_get_bcmc_stainfo(padapter);
491 pbcmc_sta->ieee8021x_blocked = false;
492 if ((padapter->securitypriv.ndisencryptstatus ==
493 Ndis802_11Encryption2Enabled) ||
494 (padapter->securitypriv.ndisencryptstatus ==
495 Ndis802_11Encryption3Enabled))
496 pbcmc_sta->XPrivacy =
497 padapter->securitypriv.
507 static int r871x_set_wpa_ie(struct _adapter *padapter, char *pie,
508 unsigned short ielen)
510 u8 *buf = NULL, *pos = NULL;
511 int group_cipher = 0, pairwise_cipher = 0;
514 if ((ielen > MAX_WPA_IE_LEN) || (pie == NULL))
517 buf = _malloc(ielen);
520 memcpy(buf, pie , ielen);
522 if (ielen < RSN_HEADER_LEN) {
526 if (r8712_parse_wpa_ie(buf, ielen, &group_cipher,
527 &pairwise_cipher) == _SUCCESS) {
528 padapter->securitypriv.AuthAlgrthm = 2;
529 padapter->securitypriv.ndisauthtype =
530 Ndis802_11AuthModeWPAPSK;
532 if (r8712_parse_wpa2_ie(buf, ielen, &group_cipher,
533 &pairwise_cipher) == _SUCCESS) {
534 padapter->securitypriv.AuthAlgrthm = 2;
535 padapter->securitypriv.ndisauthtype =
536 Ndis802_11AuthModeWPA2PSK;
538 switch (group_cipher) {
539 case WPA_CIPHER_NONE:
540 padapter->securitypriv.XGrpPrivacy =
542 padapter->securitypriv.ndisencryptstatus =
543 Ndis802_11EncryptionDisabled;
545 case WPA_CIPHER_WEP40:
546 padapter->securitypriv.XGrpPrivacy = _WEP40_;
547 padapter->securitypriv.ndisencryptstatus =
548 Ndis802_11Encryption1Enabled;
550 case WPA_CIPHER_TKIP:
551 padapter->securitypriv.XGrpPrivacy = _TKIP_;
552 padapter->securitypriv.ndisencryptstatus =
553 Ndis802_11Encryption2Enabled;
555 case WPA_CIPHER_CCMP:
556 padapter->securitypriv.XGrpPrivacy = _AES_;
557 padapter->securitypriv.ndisencryptstatus =
558 Ndis802_11Encryption3Enabled;
560 case WPA_CIPHER_WEP104:
561 padapter->securitypriv.XGrpPrivacy = _WEP104_;
562 padapter->securitypriv.ndisencryptstatus =
563 Ndis802_11Encryption1Enabled;
566 switch (pairwise_cipher) {
567 case WPA_CIPHER_NONE:
568 padapter->securitypriv.PrivacyAlgrthm =
570 padapter->securitypriv.ndisencryptstatus =
571 Ndis802_11EncryptionDisabled;
573 case WPA_CIPHER_WEP40:
574 padapter->securitypriv.PrivacyAlgrthm = _WEP40_;
575 padapter->securitypriv.ndisencryptstatus =
576 Ndis802_11Encryption1Enabled;
578 case WPA_CIPHER_TKIP:
579 padapter->securitypriv.PrivacyAlgrthm = _TKIP_;
580 padapter->securitypriv.ndisencryptstatus =
581 Ndis802_11Encryption2Enabled;
583 case WPA_CIPHER_CCMP:
584 padapter->securitypriv.PrivacyAlgrthm = _AES_;
585 padapter->securitypriv.ndisencryptstatus =
586 Ndis802_11Encryption3Enabled;
588 case WPA_CIPHER_WEP104:
589 padapter->securitypriv.PrivacyAlgrthm = _WEP104_;
590 padapter->securitypriv.ndisencryptstatus =
591 Ndis802_11Encryption1Enabled;
594 padapter->securitypriv.wps_phase = false;
597 u8 eid, wps_oui[4] = {0x0, 0x50, 0xf2, 0x04};
599 while (cnt < ielen) {
602 if ((eid == _VENDOR_SPECIFIC_IE_) &&
603 (!memcmp(&buf[cnt+2], wps_oui, 4))) {
604 printk(KERN_INFO "r8712u: "
606 padapter->securitypriv.wps_ie_len =
608 (MAX_WPA_IE_LEN << 2)) ?
610 (MAX_WPA_IE_LEN << 2);
611 memcpy(padapter->securitypriv.wps_ie,
613 padapter->securitypriv.wps_ie_len);
614 padapter->securitypriv.wps_phase =
616 printk(KERN_INFO "r8712u: SET WPS_IE,"
617 " wps_phase==true\n");
621 cnt += buf[cnt + 1] + 2;
630 static int r8711_wx_get_name(struct net_device *dev,
631 struct iw_request_info *info,
632 union iwreq_data *wrqu, char *extra)
634 struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
638 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
639 struct ndis_wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
640 NDIS_802_11_RATES_EX *prates = NULL;
642 if (check_fwstate(pmlmepriv, _FW_LINKED|WIFI_ADHOC_MASTER_STATE) ==
644 /* parsing HT_CAP_IE */
645 p = r8712_get_ie(&pcur_bss->IEs[12], _HT_CAPABILITY_IE_,
646 &ht_ielen, pcur_bss->IELength - 12);
647 if (p && ht_ielen > 0)
649 prates = &pcur_bss->SupportedRates;
650 if (r8712_is_cckratesonly_included((u8 *)prates) == true) {
652 snprintf(wrqu->name, IFNAMSIZ,
655 snprintf(wrqu->name, IFNAMSIZ,
657 } else if ((r8712_is_cckrates_included((u8 *)prates)) == true) {
659 snprintf(wrqu->name, IFNAMSIZ,
662 snprintf(wrqu->name, IFNAMSIZ,
666 snprintf(wrqu->name, IFNAMSIZ,
669 snprintf(wrqu->name, IFNAMSIZ,
673 snprintf(wrqu->name, IFNAMSIZ, "unassociated");
677 static const long frequency_list[] = {
678 2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447, 2452, 2457, 2462,
679 2467, 2472, 2484, 4915, 4920, 4925, 4935, 4940, 4945, 4960, 4980,
680 5035, 5040, 5045, 5055, 5060, 5080, 5170, 5180, 5190, 5200, 5210,
681 5220, 5230, 5240, 5260, 5280, 5300, 5320, 5500, 5520, 5540, 5560,
682 5580, 5600, 5620, 5640, 5660, 5680, 5700, 5745, 5765, 5785, 5805,
686 static int r8711_wx_set_freq(struct net_device *dev,
687 struct iw_request_info *info,
688 union iwreq_data *wrqu, char *extra)
690 struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
691 struct iw_freq *fwrq = &wrqu->freq;
694 /* If setting by frequency, convert to a channel */
695 if ((fwrq->e == 1) &&
696 (fwrq->m >= (int) 2.412e8) &&
697 (fwrq->m <= (int) 2.487e8)) {
698 int f = fwrq->m / 100000;
700 while ((c < 14) && (f != frequency_list[c]))
705 /* Setting by channel number */
706 if ((fwrq->m > 14) || (fwrq->e > 0))
709 int channel = fwrq->m;
710 if ((channel < 1) || (channel > 14))
713 /* Yes ! We can set it !!! */
714 padapter->registrypriv.channel = channel;
720 static int r8711_wx_get_freq(struct net_device *dev,
721 struct iw_request_info *info,
722 union iwreq_data *wrqu, char *extra)
724 struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
725 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
726 struct ndis_wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
728 if (check_fwstate(pmlmepriv, _FW_LINKED) == true) {
729 wrqu->freq.m = ieee80211_wlan_frequencies[
730 pcur_bss->Configuration.DSConfig-1] * 100000;
732 wrqu->freq.i = pcur_bss->Configuration.DSConfig;
738 static int r8711_wx_set_mode(struct net_device *dev,
739 struct iw_request_info *a,
740 union iwreq_data *wrqu, char *b)
742 struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
743 enum NDIS_802_11_NETWORK_INFRASTRUCTURE networkType;
745 switch (wrqu->mode) {
747 networkType = Ndis802_11AutoUnknown;
750 networkType = Ndis802_11IBSS;
753 networkType = Ndis802_11APMode;
756 networkType = Ndis802_11Infrastructure;
761 if (Ndis802_11APMode == networkType)
762 r8712_setopmode_cmd(padapter, networkType);
764 r8712_setopmode_cmd(padapter, Ndis802_11AutoUnknown);
765 if (!r8712_set_802_11_infrastructure_mode(padapter, networkType))
770 static int r8711_wx_get_mode(struct net_device *dev, struct iw_request_info *a,
771 union iwreq_data *wrqu, char *b)
773 struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
774 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
776 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == true)
777 wrqu->mode = IW_MODE_INFRA;
778 else if (check_fwstate(pmlmepriv,
779 WIFI_ADHOC_MASTER_STATE|WIFI_ADHOC_STATE) == true)
780 wrqu->mode = IW_MODE_ADHOC;
781 else if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == true)
782 wrqu->mode = IW_MODE_MASTER;
784 wrqu->mode = IW_MODE_AUTO;
788 static int r871x_wx_set_pmkid(struct net_device *dev,
789 struct iw_request_info *a,
790 union iwreq_data *wrqu, char *extra)
792 struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
793 struct security_priv *psecuritypriv = &padapter->securitypriv;
794 struct iw_pmksa *pPMK = (struct iw_pmksa *) extra;
795 u8 strZeroMacAddress[ETH_ALEN] = {0x00};
796 u8 strIssueBssid[ETH_ALEN] = {0x00};
797 u8 j, blInserted = false;
798 int intReturn = false;
801 There are the BSSID information in the bssid.sa_data array.
802 If cmd is IW_PMKSA_FLUSH, it means the wpa_suppplicant wants to clear
803 all the PMKID information. If cmd is IW_PMKSA_ADD, it means the
804 wpa_supplicant wants to add a PMKID/BSSID to driver.
805 If cmd is IW_PMKSA_REMOVE, it means the wpa_supplicant wants to
806 remove a PMKID/BSSID from driver.
810 memcpy(strIssueBssid, pPMK->bssid.sa_data, ETH_ALEN);
813 if (!memcmp(strIssueBssid, strZeroMacAddress, ETH_ALEN))
818 /* overwrite PMKID */
819 for (j = 0 ; j < NUM_PMKID_CACHE; j++) {
820 if (!memcmp(psecuritypriv->PMKIDList[j].Bssid,
821 strIssueBssid, ETH_ALEN)) {
822 /* BSSID is matched, the same AP => rewrite
824 printk(KERN_INFO "r8712u: r871x_wx_set_pmkid:"
825 " BSSID exists in the PMKList.\n");
826 memcpy(psecuritypriv->PMKIDList[j].PMKID,
827 pPMK->pmkid, IW_PMKID_LEN);
828 psecuritypriv->PMKIDList[j].bUsed = true;
829 psecuritypriv->PMKIDIndex = j + 1;
835 /* Find a new entry */
836 printk(KERN_INFO "r8712u: r871x_wx_set_pmkid: Use the"
837 " new entry index = %d for this PMKID.\n",
838 psecuritypriv->PMKIDIndex);
839 memcpy(psecuritypriv->PMKIDList[psecuritypriv->
840 PMKIDIndex].Bssid, strIssueBssid, ETH_ALEN);
841 memcpy(psecuritypriv->PMKIDList[psecuritypriv->
842 PMKIDIndex].PMKID, pPMK->pmkid, IW_PMKID_LEN);
843 psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].
845 psecuritypriv->PMKIDIndex++ ;
846 if (psecuritypriv->PMKIDIndex == NUM_PMKID_CACHE)
847 psecuritypriv->PMKIDIndex = 0;
850 case IW_PMKSA_REMOVE:
852 for (j = 0; j < NUM_PMKID_CACHE; j++) {
853 if (!memcmp(psecuritypriv->PMKIDList[j].Bssid,
854 strIssueBssid, ETH_ALEN)) {
855 /* BSSID is matched, the same AP => Remove
856 * this PMKID information and reset it. */
857 memset(psecuritypriv->PMKIDList[j].Bssid,
859 psecuritypriv->PMKIDList[j].bUsed = false;
865 memset(psecuritypriv->PMKIDList, 0,
866 sizeof(struct RT_PMKID_LIST) * NUM_PMKID_CACHE);
867 psecuritypriv->PMKIDIndex = 0;
871 printk(KERN_INFO "r8712u: r871x_wx_set_pmkid: "
872 "unknown Command\n");
879 static int r8711_wx_get_sens(struct net_device *dev,
880 struct iw_request_info *info,
881 union iwreq_data *wrqu, char *extra)
883 wrqu->sens.value = 0;
884 wrqu->sens.fixed = 0; /* no auto select */
885 wrqu->sens.disabled = 1;
889 static int r8711_wx_get_range(struct net_device *dev,
890 struct iw_request_info *info,
891 union iwreq_data *wrqu, char *extra)
893 struct iw_range *range = (struct iw_range *)extra;
897 wrqu->data.length = sizeof(*range);
898 memset(range, 0, sizeof(*range));
899 /* Let's try to keep this struct in the same order as in
900 * linux/include/wireless.h
903 /* TODO: See what values we can set, and remove the ones we can't
904 * set, or fill them with some default data.
906 /* ~5 Mb/s real (802.11b) */
907 range->throughput = 5 * 1000 * 1000;
908 /* TODO: 8711 sensitivity ? */
909 /* signal level threshold range */
910 /* percent values between 0 and 100. */
911 range->max_qual.qual = 100;
912 range->max_qual.level = 100;
913 range->max_qual.noise = 100;
914 range->max_qual.updated = 7; /* Updated all three */
915 range->avg_qual.qual = 92; /* > 8% missed beacons is 'bad' */
916 /* TODO: Find real 'good' to 'bad' threshol value for RSSI */
917 range->avg_qual.level = 20 + -98;
918 range->avg_qual.noise = 0;
919 range->avg_qual.updated = 7; /* Updated all three */
920 range->num_bitrates = RATE_COUNT;
921 for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++)
922 range->bitrate[i] = rtl8180_rates[i];
923 range->min_frag = MIN_FRAG_THRESHOLD;
924 range->max_frag = MAX_FRAG_THRESHOLD;
926 range->we_version_compiled = WIRELESS_EXT;
927 range->we_version_source = 16;
928 range->num_channels = 14;
929 for (i = 0, val = 0; i < 14; i++) {
930 /* Include only legal frequencies for some countries */
931 range->freq[val].i = i + 1;
932 range->freq[val].m = ieee80211_wlan_frequencies[i] * 100000;
933 range->freq[val].e = 1;
935 if (val == IW_MAX_FREQUENCIES)
938 range->num_frequency = val;
939 range->enc_capa = IW_ENC_CAPA_WPA |
941 IW_ENC_CAPA_CIPHER_TKIP |
942 IW_ENC_CAPA_CIPHER_CCMP;
946 static int r871x_wx_set_priv(struct net_device *dev,
947 struct iw_request_info *info,
948 union iwreq_data *awrq,
951 int ret = 0, len = 0;
953 struct iw_point *dwrq = (struct iw_point *)awrq;
959 if (copy_from_user(ext, dwrq->pointer, len)) {
968 * s1. set_802_11_infrastructure_mode()
969 * s2. set_802_11_authentication_mode()
970 * s3. set_802_11_encryption_mode()
971 * s4. set_802_11_bssid()
973 static int r8711_wx_set_wap(struct net_device *dev,
974 struct iw_request_info *info,
975 union iwreq_data *awrq,
978 int ret = -EINPROGRESS;
979 struct _adapter *padapter = (struct _adapter *) _netdev_priv(dev);
980 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
981 struct __queue *queue = &pmlmepriv->scanned_queue;
982 struct sockaddr *temp = (struct sockaddr *)awrq;
984 struct list_head *phead;
986 struct wlan_network *pnetwork = NULL;
987 enum NDIS_802_11_AUTHENTICATION_MODE authmode;
989 if (padapter->bup == false)
991 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == true)
993 if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == true)
995 if (temp->sa_family != ARPHRD_ETHER)
997 authmode = padapter->securitypriv.ndisauthtype;
998 spin_lock_irqsave(&queue->lock, irqL);
999 phead = get_list_head(queue);
1000 pmlmepriv->pscanned = get_next(phead);
1002 if (end_of_queue_search(phead, pmlmepriv->pscanned) == true)
1004 pnetwork = LIST_CONTAINOR(pmlmepriv->pscanned,
1005 struct wlan_network, list);
1006 pmlmepriv->pscanned = get_next(pmlmepriv->pscanned);
1007 dst_bssid = pnetwork->network.MacAddress;
1008 if (!memcmp(dst_bssid, temp->sa_data, ETH_ALEN)) {
1009 if (r8712_set_802_11_infrastructure_mode(padapter,
1010 pnetwork->network.InfrastructureMode) == false)
1015 spin_unlock_irqrestore(&queue->lock, irqL);
1017 if (!r8712_set_802_11_authentication_mode(padapter, authmode))
1020 if (!r8712_set_802_11_bssid(padapter, temp->sa_data))
1027 static int r8711_wx_get_wap(struct net_device *dev,
1028 struct iw_request_info *info,
1029 union iwreq_data *wrqu, char *extra)
1031 struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
1032 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1033 struct ndis_wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
1035 wrqu->ap_addr.sa_family = ARPHRD_ETHER;
1036 memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN);
1037 if (check_fwstate(pmlmepriv, _FW_LINKED |
1038 WIFI_ADHOC_MASTER_STATE|WIFI_AP_STATE)) {
1039 memcpy(wrqu->ap_addr.sa_data, pcur_bss->MacAddress, ETH_ALEN);
1044 static int r871x_wx_set_mlme(struct net_device *dev,
1045 struct iw_request_info *info,
1046 union iwreq_data *wrqu, char *extra)
1050 struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
1051 struct iw_mlme *mlme = (struct iw_mlme *) extra;
1055 reason = cpu_to_le16(mlme->reason_code);
1056 switch (mlme->cmd) {
1057 case IW_MLME_DEAUTH:
1058 if (!r8712_set_802_11_disassociate(padapter))
1061 case IW_MLME_DISASSOC:
1062 if (!r8712_set_802_11_disassociate(padapter))
1071 static int r8711_wx_set_scan(struct net_device *dev,
1072 struct iw_request_info *a,
1073 union iwreq_data *wrqu, char *extra)
1075 struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
1076 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1079 if (padapter->bDriverStopped == true) {
1080 printk(KERN_WARNING "r8712u: in r8711_wx_set_scan: "
1081 "bDriverStopped=%d\n", padapter->bDriverStopped);
1084 if (padapter->bup == false)
1086 if (padapter->hw_init_completed == false)
1088 if ((check_fwstate(pmlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING)) ||
1089 (pmlmepriv->sitesurveyctrl.traffic_busy == true))
1091 if (wrqu->data.length == sizeof(struct iw_scan_req)) {
1092 struct iw_scan_req *req = (struct iw_scan_req *)extra;
1093 if (wrqu->data.flags & IW_SCAN_THIS_ESSID) {
1094 struct ndis_802_11_ssid ssid;
1096 u32 len = (u32) min((u8)req->essid_len,
1097 (u8)IW_ESSID_MAX_SIZE);
1098 memset((unsigned char *)&ssid, 0,
1099 sizeof(struct ndis_802_11_ssid));
1100 memcpy(ssid.Ssid, req->essid, len);
1101 ssid.SsidLength = len;
1102 spin_lock_irqsave(&pmlmepriv->lock, irqL);
1103 if ((check_fwstate(pmlmepriv, _FW_UNDER_SURVEY |
1104 _FW_UNDER_LINKING)) ||
1105 (pmlmepriv->sitesurveyctrl.traffic_busy == true)) {
1106 if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING))
1109 status = r8712_sitesurvey_cmd(padapter, &ssid);
1110 spin_unlock_irqrestore(&pmlmepriv->lock, irqL);
1113 status = r8712_set_802_11_bssid_list_scan(padapter);
1114 if (status == false)
1119 static int r8711_wx_get_scan(struct net_device *dev,
1120 struct iw_request_info *a,
1121 union iwreq_data *wrqu, char *extra)
1123 struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
1124 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1125 struct __queue *queue = &pmlmepriv->scanned_queue;
1126 struct wlan_network *pnetwork = NULL;
1128 struct list_head *plist, *phead;
1130 char *stop = ev + wrqu->data.length;
1131 u32 ret = 0, cnt = 0;
1133 if (padapter->bDriverStopped)
1135 while (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING)) {
1141 spin_lock_irqsave(&queue->lock, irqL);
1142 phead = get_list_head(queue);
1143 plist = get_next(phead);
1145 if (end_of_queue_search(phead, plist) == true)
1147 if ((stop - ev) < SCAN_ITEM_SIZE) {
1151 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
1152 ev = translate_scan(padapter, a, pnetwork, ev, stop);
1153 plist = get_next(plist);
1155 spin_unlock_irqrestore(&queue->lock, irqL);
1156 wrqu->data.length = ev - extra;
1157 wrqu->data.flags = 0;
1162 * s1. set_802_11_infrastructure_mode()
1163 * s2. set_802_11_authenticaion_mode()
1164 * s3. set_802_11_encryption_mode()
1165 * s4. set_802_11_ssid()
1167 static int r8711_wx_set_essid(struct net_device *dev,
1168 struct iw_request_info *a,
1169 union iwreq_data *wrqu, char *extra)
1171 struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
1172 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1173 struct __queue *queue = &pmlmepriv->scanned_queue;
1174 struct wlan_network *pnetwork = NULL;
1175 enum NDIS_802_11_AUTHENTICATION_MODE authmode;
1176 struct ndis_802_11_ssid ndis_ssid;
1177 u8 *dst_ssid, *src_ssid;
1178 struct list_head *phead;
1181 if (padapter->bup == false)
1183 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY))
1185 if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING))
1187 if (wrqu->essid.length > IW_ESSID_MAX_SIZE)
1189 authmode = padapter->securitypriv.ndisauthtype;
1190 if (wrqu->essid.flags && wrqu->essid.length) {
1191 len = (wrqu->essid.length < IW_ESSID_MAX_SIZE) ?
1192 wrqu->essid.length : IW_ESSID_MAX_SIZE;
1193 memset(&ndis_ssid, 0, sizeof(struct ndis_802_11_ssid));
1194 ndis_ssid.SsidLength = len;
1195 memcpy(ndis_ssid.Ssid, extra, len);
1196 src_ssid = ndis_ssid.Ssid;
1197 phead = get_list_head(queue);
1198 pmlmepriv->pscanned = get_next(phead);
1200 if (end_of_queue_search(phead, pmlmepriv->pscanned))
1202 pnetwork = LIST_CONTAINOR(pmlmepriv->pscanned,
1203 struct wlan_network, list);
1204 pmlmepriv->pscanned = get_next(pmlmepriv->pscanned);
1205 dst_ssid = pnetwork->network.Ssid.Ssid;
1206 if ((!memcmp(dst_ssid, src_ssid, ndis_ssid.SsidLength))
1207 && (pnetwork->network.Ssid.SsidLength ==
1208 ndis_ssid.SsidLength)) {
1209 if (!r8712_set_802_11_infrastructure_mode(
1211 pnetwork->network.InfrastructureMode))
1216 r8712_set_802_11_authentication_mode(padapter, authmode);
1217 r8712_set_802_11_ssid(padapter, &ndis_ssid);
1219 return -EINPROGRESS;
1222 static int r8711_wx_get_essid(struct net_device *dev,
1223 struct iw_request_info *a,
1224 union iwreq_data *wrqu, char *extra)
1226 struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
1227 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1228 struct ndis_wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
1231 if (check_fwstate(pmlmepriv, _FW_LINKED|WIFI_ADHOC_MASTER_STATE)) {
1232 len = pcur_bss->Ssid.SsidLength;
1233 wrqu->essid.length = len;
1234 memcpy(extra, pcur_bss->Ssid.Ssid, len);
1235 wrqu->essid.flags = 1;
1241 static int r8711_wx_set_rate(struct net_device *dev,
1242 struct iw_request_info *a,
1243 union iwreq_data *wrqu, char *extra)
1245 struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
1246 u32 target_rate = wrqu->bitrate.value;
1247 u32 fixed = wrqu->bitrate.fixed;
1249 u8 datarates[NumRates];
1250 u8 mpdatarate[NumRates] = {11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0xff};
1253 if (target_rate == -1) {
1257 target_rate = target_rate / 100000;
1258 switch (target_rate) {
1300 for (i = 0; i < NumRates; i++) {
1301 if (ratevalue == mpdatarate[i]) {
1302 datarates[i] = mpdatarate[i];
1306 datarates[i] = 0xff;
1308 if (r8712_setdatarate_cmd(padapter, datarates) != _SUCCESS)
1313 static int r8711_wx_get_rate(struct net_device *dev,
1314 struct iw_request_info *info,
1315 union iwreq_data *wrqu, char *extra)
1317 struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
1318 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1319 struct ndis_wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
1320 struct ieee80211_ht_cap *pht_capie;
1323 u16 rate, max_rate = 0, ht_cap = false;
1325 u8 bw_40MHz = 0, short_GI = 0;
1329 if (check_fwstate(pmlmepriv, _FW_LINKED|WIFI_ADHOC_MASTER_STATE)) {
1330 p = r8712_get_ie(&pcur_bss->IEs[12],
1331 _HT_CAPABILITY_IE_, &ht_ielen,
1332 pcur_bss->IELength - 12);
1333 if (p && ht_ielen > 0) {
1335 pht_capie = (struct ieee80211_ht_cap *)(p + 2);
1336 memcpy(&mcs_rate , pht_capie->supp_mcs_set, 2);
1337 bw_40MHz = (pht_capie->cap_info &
1338 IEEE80211_HT_CAP_SUP_WIDTH) ? 1 : 0;
1339 short_GI = (pht_capie->cap_info &
1340 (IEEE80211_HT_CAP_SGI_20 |
1341 IEEE80211_HT_CAP_SGI_40)) ? 1 : 0;
1343 while ((pcur_bss->SupportedRates[i] != 0) &&
1344 (pcur_bss->SupportedRates[i] != 0xFF)) {
1345 rate = pcur_bss->SupportedRates[i] & 0x7F;
1346 if (rate > max_rate)
1348 wrqu->bitrate.fixed = 0; /* no auto select */
1349 wrqu->bitrate.value = rate*500000;
1352 if (ht_cap == true) {
1353 if (mcs_rate & 0x8000) /* MCS15 */
1354 max_rate = (bw_40MHz) ? ((short_GI) ? 300 :
1355 270) : ((short_GI) ? 144 : 130);
1356 else if (mcs_rate & 0x0080) /* MCS7 */
1357 max_rate = (bw_40MHz) ? ((short_GI) ? 150 :
1358 135) : ((short_GI) ? 72 : 65);
1359 else /* default MCS7 */
1360 max_rate = (bw_40MHz) ? ((short_GI) ? 150 :
1361 135) : ((short_GI) ? 72 : 65);
1362 max_rate *= 2; /* Mbps/2 */
1363 wrqu->bitrate.value = max_rate * 500000;
1365 wrqu->bitrate.value = max_rate * 500000;
1372 static int r8711_wx_get_rts(struct net_device *dev,
1373 struct iw_request_info *info,
1374 union iwreq_data *wrqu, char *extra)
1376 struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
1378 wrqu->rts.value = padapter->registrypriv.rts_thresh;
1379 wrqu->rts.fixed = 0; /* no auto select */
1383 static int r8711_wx_set_frag(struct net_device *dev,
1384 struct iw_request_info *info,
1385 union iwreq_data *wrqu, char *extra)
1387 struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
1389 if (wrqu->frag.disabled)
1390 padapter->xmitpriv.frag_len = MAX_FRAG_THRESHOLD;
1392 if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
1393 wrqu->frag.value > MAX_FRAG_THRESHOLD)
1395 padapter->xmitpriv.frag_len = wrqu->frag.value & ~0x1;
1400 static int r8711_wx_get_frag(struct net_device *dev,
1401 struct iw_request_info *info,
1402 union iwreq_data *wrqu, char *extra)
1404 struct _adapter *padapter = (struct _adapter *) _netdev_priv(dev);
1406 wrqu->frag.value = padapter->xmitpriv.frag_len;
1407 wrqu->frag.fixed = 0; /* no auto select */
1411 static int r8711_wx_get_retry(struct net_device *dev,
1412 struct iw_request_info *info,
1413 union iwreq_data *wrqu, char *extra)
1415 wrqu->retry.value = 7;
1416 wrqu->retry.fixed = 0; /* no auto select */
1417 wrqu->retry.disabled = 1;
1421 static int r8711_wx_set_enc(struct net_device *dev,
1422 struct iw_request_info *info,
1423 union iwreq_data *wrqu, char *keybuf)
1426 u32 keyindex_provided;
1427 struct NDIS_802_11_WEP wep;
1428 enum NDIS_802_11_AUTHENTICATION_MODE authmode;
1429 struct iw_point *erq = &(wrqu->encoding);
1430 struct _adapter *padapter = (struct _adapter *) _netdev_priv(dev);
1432 key = erq->flags & IW_ENCODE_INDEX;
1433 memset(&wep, 0, sizeof(struct NDIS_802_11_WEP));
1434 if (erq->flags & IW_ENCODE_DISABLED) {
1435 printk(KERN_INFO "r8712u: r8711_wx_set_enc: "
1436 "EncryptionDisabled\n");
1437 padapter->securitypriv.ndisencryptstatus =
1438 Ndis802_11EncryptionDisabled;
1439 padapter->securitypriv.PrivacyAlgrthm = _NO_PRIVACY_;
1440 padapter->securitypriv.XGrpPrivacy = _NO_PRIVACY_;
1441 padapter->securitypriv.AuthAlgrthm = 0; /* open system */
1442 authmode = Ndis802_11AuthModeOpen;
1443 padapter->securitypriv.ndisauthtype = authmode;
1450 keyindex_provided = 1;
1452 keyindex_provided = 0;
1453 key = padapter->securitypriv.PrivacyKeyIndex;
1455 /* set authentication mode */
1456 if (erq->flags & IW_ENCODE_OPEN) {
1457 printk(KERN_INFO "r8712u: r8711_wx_set_enc: "
1458 "IW_ENCODE_OPEN\n");
1459 padapter->securitypriv.ndisencryptstatus =
1460 Ndis802_11Encryption1Enabled;
1461 padapter->securitypriv.AuthAlgrthm = 0; /* open system */
1462 padapter->securitypriv.PrivacyAlgrthm = _NO_PRIVACY_;
1463 padapter->securitypriv.XGrpPrivacy = _NO_PRIVACY_;
1464 authmode = Ndis802_11AuthModeOpen;
1465 padapter->securitypriv.ndisauthtype = authmode;
1466 } else if (erq->flags & IW_ENCODE_RESTRICTED) {
1467 printk(KERN_INFO "r8712u: r8711_wx_set_enc: "
1468 "IW_ENCODE_RESTRICTED\n");
1469 padapter->securitypriv.ndisencryptstatus =
1470 Ndis802_11Encryption1Enabled;
1471 padapter->securitypriv.AuthAlgrthm = 1; /* shared system */
1472 padapter->securitypriv.PrivacyAlgrthm = _WEP40_;
1473 padapter->securitypriv.XGrpPrivacy = _WEP40_;
1474 authmode = Ndis802_11AuthModeShared;
1475 padapter->securitypriv.ndisauthtype = authmode;
1477 padapter->securitypriv.ndisencryptstatus =
1478 Ndis802_11Encryption1Enabled;
1479 padapter->securitypriv.AuthAlgrthm = 0; /* open system */
1480 padapter->securitypriv.PrivacyAlgrthm = _NO_PRIVACY_;
1481 padapter->securitypriv.XGrpPrivacy = _NO_PRIVACY_;
1482 authmode = Ndis802_11AuthModeOpen;
1483 padapter->securitypriv.ndisauthtype = authmode;
1486 if (erq->length > 0) {
1487 wep.KeyLength = erq->length <= 5 ? 5 : 13;
1488 wep.Length = wep.KeyLength +
1489 FIELD_OFFSET(struct NDIS_802_11_WEP, KeyMaterial);
1492 if (keyindex_provided == 1) { /* set key_id only, no given
1493 * KeyMaterial(erq->length==0).*/
1494 padapter->securitypriv.PrivacyKeyIndex = key;
1495 switch (padapter->securitypriv.DefKeylen[key]) {
1497 padapter->securitypriv.PrivacyAlgrthm =
1501 padapter->securitypriv.PrivacyAlgrthm =
1505 padapter->securitypriv.PrivacyAlgrthm =
1512 wep.KeyIndex |= 0x80000000; /* transmit key */
1513 memcpy(wep.KeyMaterial, keybuf, wep.KeyLength);
1514 if (r8712_set_802_11_add_wep(padapter, &wep) == _FAIL)
1519 static int r8711_wx_get_enc(struct net_device *dev,
1520 struct iw_request_info *info,
1521 union iwreq_data *wrqu, char *keybuf)
1524 struct _adapter *padapter = (struct _adapter *) _netdev_priv(dev);
1525 struct iw_point *erq = &(wrqu->encoding);
1526 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1528 if (check_fwstate(pmlmepriv, _FW_LINKED) == false) {
1529 if (!check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) {
1531 erq->flags |= IW_ENCODE_DISABLED;
1535 key = erq->flags & IW_ENCODE_INDEX;
1541 key = padapter->securitypriv.PrivacyKeyIndex;
1543 erq->flags = key + 1;
1544 switch (padapter->securitypriv.ndisencryptstatus) {
1545 case Ndis802_11EncryptionNotSupported:
1546 case Ndis802_11EncryptionDisabled:
1548 erq->flags |= IW_ENCODE_DISABLED;
1550 case Ndis802_11Encryption1Enabled:
1551 erq->length = padapter->securitypriv.DefKeylen[key];
1553 memcpy(keybuf, padapter->securitypriv.DefKey[
1554 key].skey, padapter->securitypriv.
1556 erq->flags |= IW_ENCODE_ENABLED;
1557 if (padapter->securitypriv.ndisauthtype ==
1558 Ndis802_11AuthModeOpen)
1559 erq->flags |= IW_ENCODE_OPEN;
1560 else if (padapter->securitypriv.ndisauthtype ==
1561 Ndis802_11AuthModeShared)
1562 erq->flags |= IW_ENCODE_RESTRICTED;
1565 erq->flags |= IW_ENCODE_DISABLED;
1568 case Ndis802_11Encryption2Enabled:
1569 case Ndis802_11Encryption3Enabled:
1571 erq->flags |= (IW_ENCODE_ENABLED | IW_ENCODE_OPEN |
1576 erq->flags |= IW_ENCODE_DISABLED;
1582 static int r8711_wx_get_power(struct net_device *dev,
1583 struct iw_request_info *info,
1584 union iwreq_data *wrqu, char *extra)
1586 wrqu->power.value = 0;
1587 wrqu->power.fixed = 0; /* no auto select */
1588 wrqu->power.disabled = 1;
1592 static int r871x_wx_set_gen_ie(struct net_device *dev,
1593 struct iw_request_info *info,
1594 union iwreq_data *wrqu, char *extra)
1596 struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
1598 return r871x_set_wpa_ie(padapter, extra, wrqu->data.length);
1601 static int r871x_wx_set_auth(struct net_device *dev,
1602 struct iw_request_info *info,
1603 union iwreq_data *wrqu, char *extra)
1605 struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
1606 struct iw_param *param = (struct iw_param *)&(wrqu->param);
1611 paramid = param->flags & IW_AUTH_INDEX;
1612 paramval = param->value;
1614 case IW_AUTH_WPA_VERSION:
1616 case IW_AUTH_CIPHER_PAIRWISE:
1618 case IW_AUTH_CIPHER_GROUP:
1620 case IW_AUTH_KEY_MGMT:
1622 * ??? does not use these parameters
1625 case IW_AUTH_TKIP_COUNTERMEASURES:
1627 /* wpa_supplicant is enabling tkip countermeasure. */
1628 padapter->securitypriv.btkip_countermeasure = true;
1630 /* wpa_supplicant is disabling tkip countermeasure. */
1631 padapter->securitypriv.btkip_countermeasure = false;
1634 case IW_AUTH_DROP_UNENCRYPTED:
1637 * wpa_supplicant calls set_wpa_enabled when the driver
1638 * is loaded and unloaded, regardless of if WPA is being
1639 * used. No other calls are made which can be used to
1640 * determine if encryption will be used or not prior to
1641 * association being expected. If encryption is not being
1642 * used, drop_unencrypted is set to false, else true -- we
1643 * can use this to determine if the CAP_PRIVACY_ON bit should
1646 if (padapter->securitypriv.ndisencryptstatus ==
1647 Ndis802_11Encryption1Enabled) {
1648 /* it means init value, or using wep,
1649 * ndisencryptstatus =
1650 * Ndis802_11Encryption1Enabled,
1651 * then it needn't reset it;
1657 padapter->securitypriv.ndisencryptstatus =
1658 Ndis802_11EncryptionDisabled;
1659 padapter->securitypriv.PrivacyAlgrthm =
1661 padapter->securitypriv.XGrpPrivacy =
1663 padapter->securitypriv.AuthAlgrthm = 0;
1664 padapter->securitypriv.ndisauthtype =
1665 Ndis802_11AuthModeOpen;
1668 case IW_AUTH_80211_AUTH_ALG:
1669 ret = wpa_set_auth_algs(dev, (u32)paramval);
1671 case IW_AUTH_WPA_ENABLED:
1673 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
1675 case IW_AUTH_PRIVACY_INVOKED:
1684 static int r871x_wx_set_enc_ext(struct net_device *dev,
1685 struct iw_request_info *info,
1686 union iwreq_data *wrqu, char *extra)
1688 struct iw_point *pencoding = &wrqu->encoding;
1689 struct iw_encode_ext *pext = (struct iw_encode_ext *)extra;
1690 struct ieee_param *param = NULL;
1695 param_len = sizeof(struct ieee_param) + pext->key_len;
1696 param = (struct ieee_param *)_malloc(param_len);
1699 memset(param, 0, param_len);
1700 param->cmd = IEEE_CMD_SET_ENCRYPTION;
1701 memset(param->sta_addr, 0xff, ETH_ALEN);
1702 switch (pext->alg) {
1703 case IW_ENCODE_ALG_NONE:
1706 case IW_ENCODE_ALG_WEP:
1709 case IW_ENCODE_ALG_TKIP:
1712 case IW_ENCODE_ALG_CCMP:
1718 strncpy((char *)param->u.crypt.alg, alg_name, IEEE_CRYPT_ALG_NAME_LEN);
1719 if (pext->ext_flags & IW_ENCODE_EXT_GROUP_KEY)
1720 param->u.crypt.set_tx = 0;
1721 if (pext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
1722 param->u.crypt.set_tx = 1;
1723 param->u.crypt.idx = (pencoding->flags & 0x00FF) - 1;
1724 if (pext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID)
1725 memcpy(param->u.crypt.seq, pext->rx_seq, 8);
1726 if (pext->key_len) {
1727 param->u.crypt.key_len = pext->key_len;
1728 memcpy(param + 1, pext + 1, pext->key_len);
1730 ret = wpa_set_encryption(dev, param, param_len);
1736 static int r871x_wx_get_nick(struct net_device *dev,
1737 struct iw_request_info *info,
1738 union iwreq_data *wrqu, char *extra)
1741 wrqu->data.length = 8;
1742 wrqu->data.flags = 1;
1743 memcpy(extra, "rtl_wifi", 8);
1748 static int r8711_wx_read32(struct net_device *dev,
1749 struct iw_request_info *info,
1750 union iwreq_data *wrqu, char *keybuf)
1752 struct _adapter *padapter = (struct _adapter *) _netdev_priv(dev);
1756 get_user(addr, (u32 __user *)wrqu->data.pointer);
1757 data32 = r8712_read32(padapter, addr);
1758 put_user(data32, (u32 __user *)wrqu->data.pointer);
1759 wrqu->data.length = (data32 & 0xffff0000) >> 16;
1760 wrqu->data.flags = data32 & 0xffff;
1761 get_user(addr, (u32 __user *)wrqu->data.pointer);
1765 static int r8711_wx_write32(struct net_device *dev,
1766 struct iw_request_info *info,
1767 union iwreq_data *wrqu, char *keybuf)
1769 struct _adapter *padapter = (struct _adapter *) _netdev_priv(dev);
1773 get_user(addr, (u32 __user *)wrqu->data.pointer);
1774 data32 = ((u32)wrqu->data.length<<16) | (u32)wrqu->data.flags ;
1775 r8712_write32(padapter, addr, data32);
1779 static int dummy(struct net_device *dev,
1780 struct iw_request_info *a,
1781 union iwreq_data *wrqu, char *b)
1786 static int r8711_drvext_hdl(struct net_device *dev,
1787 struct iw_request_info *info,
1788 union iwreq_data *wrqu, char *extra)
1793 static int r871x_mp_ioctl_hdl(struct net_device *dev,
1794 struct iw_request_info *info,
1795 union iwreq_data *wrqu, char *extra)
1797 struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
1798 struct iw_point *p = &wrqu->data;
1799 struct oid_par_priv oid_par;
1800 struct mp_ioctl_handler *phandler;
1801 struct mp_ioctl_param *poidparam;
1802 unsigned long BytesRead, BytesWritten, BytesNeeded;
1803 u8 *pparmbuf = NULL, bset;
1808 if ((!p->length) || (!p->pointer)) {
1810 goto _r871x_mp_ioctl_hdl_exit;
1812 bset = (u8)(p->flags & 0xFFFF);
1815 pparmbuf = (u8 *)_malloc(len);
1816 if (pparmbuf == NULL) {
1818 goto _r871x_mp_ioctl_hdl_exit;
1820 if (copy_from_user(pparmbuf, p->pointer, len)) {
1822 goto _r871x_mp_ioctl_hdl_exit;
1824 poidparam = (struct mp_ioctl_param *)pparmbuf;
1825 if (poidparam->subcode >= MAX_MP_IOCTL_SUBCODE) {
1827 goto _r871x_mp_ioctl_hdl_exit;
1829 phandler = mp_ioctl_hdl + poidparam->subcode;
1830 if ((phandler->paramsize != 0) &&
1831 (poidparam->len < phandler->paramsize)) {
1833 goto _r871x_mp_ioctl_hdl_exit;
1835 if (phandler->oid == 0 && phandler->handler)
1836 status = phandler->handler(&oid_par);
1837 else if (phandler->handler) {
1838 oid_par.adapter_context = padapter;
1839 oid_par.oid = phandler->oid;
1840 oid_par.information_buf = poidparam->data;
1841 oid_par.information_buf_len = poidparam->len;
1846 oid_par.bytes_rw = &BytesRead;
1847 oid_par.bytes_needed = &BytesNeeded;
1848 oid_par.type_of_oid = SET_OID;
1850 oid_par.bytes_rw = &BytesWritten;
1851 oid_par.bytes_needed = &BytesNeeded;
1852 oid_par.type_of_oid = QUERY_OID;
1854 status = phandler->handler(&oid_par);
1855 /* todo:check status, BytesNeeded, etc. */
1857 printk(KERN_INFO "r8712u: r871x_mp_ioctl_hdl(): err!,"
1858 " subcode=%d, oid=%d, handler=%p\n",
1859 poidparam->subcode, phandler->oid, phandler->handler);
1861 goto _r871x_mp_ioctl_hdl_exit;
1863 if (bset == 0x00) { /* query info */
1864 if (copy_to_user(p->pointer, pparmbuf, len))
1869 goto _r871x_mp_ioctl_hdl_exit;
1871 _r871x_mp_ioctl_hdl_exit:
1872 if (pparmbuf != NULL)
1877 static int r871x_get_ap_info(struct net_device *dev,
1878 struct iw_request_info *info,
1879 union iwreq_data *wrqu, char *extra)
1881 struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
1882 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1883 struct __queue *queue = &pmlmepriv->scanned_queue;
1884 struct iw_point *pdata = &wrqu->data;
1885 struct wlan_network *pnetwork = NULL;
1886 u32 cnt = 0, wpa_ielen;
1888 struct list_head *plist, *phead;
1889 unsigned char *pbuf;
1893 if (padapter->bDriverStopped || (pdata == NULL))
1895 while (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING)) {
1902 if (pdata->length >= 32) {
1903 if (copy_from_user(data, pdata->pointer, 32))
1907 spin_lock_irqsave(&(pmlmepriv->scanned_queue.lock), irqL);
1908 phead = get_list_head(queue);
1909 plist = get_next(phead);
1911 if (end_of_queue_search(phead, plist) == true)
1913 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
1914 if (hwaddr_aton_i(data, bssid)) {
1915 printk(KERN_INFO "r8712u: Invalid BSSID '%s'.\n",
1917 spin_unlock_irqrestore(&(pmlmepriv->scanned_queue.lock),
1921 printk(KERN_INFO "r8712u: BSSID:%pM\n", bssid);
1922 if (!memcmp(bssid, pnetwork->network.MacAddress, ETH_ALEN)) {
1923 /* BSSID match, then check if supporting wpa/wpa2 */
1924 pbuf = r8712_get_wpa_ie(&pnetwork->network.IEs[12],
1925 &wpa_ielen, pnetwork->network.IELength-12);
1926 if (pbuf && (wpa_ielen > 0)) {
1930 pbuf = r8712_get_wpa2_ie(&pnetwork->network.IEs[12],
1931 &wpa_ielen, pnetwork->network.IELength-12);
1932 if (pbuf && (wpa_ielen > 0)) {
1937 plist = get_next(plist);
1939 spin_unlock_irqrestore(&(pmlmepriv->scanned_queue.lock), irqL);
1940 if (pdata->length >= 34) {
1941 if (copy_to_user((u8 __user *)pdata->pointer + 32,
1942 (u8 *)&pdata->flags, 1))
1948 static int r871x_set_pid(struct net_device *dev,
1949 struct iw_request_info *info,
1950 union iwreq_data *wrqu, char *extra)
1952 struct _adapter *padapter = (struct _adapter *) _netdev_priv(dev);
1953 struct iw_point *pdata = &wrqu->data;
1955 if ((padapter->bDriverStopped) || (pdata == NULL))
1957 if (copy_from_user(&padapter->pid, pdata->pointer, sizeof(int)))
1962 static int r871x_wps_start(struct net_device *dev,
1963 struct iw_request_info *info,
1964 union iwreq_data *wrqu, char *extra)
1966 struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
1967 struct iw_point *pdata = &wrqu->data;
1968 u32 u32wps_start = 0;
1969 unsigned int uintRet = 0;
1971 uintRet = copy_from_user((void *)&u32wps_start, pdata->pointer, 4);
1972 if ((padapter->bDriverStopped) || (pdata == NULL))
1974 if (u32wps_start == 0)
1975 u32wps_start = *extra;
1976 if (u32wps_start == 1) /* WPS Start */
1977 padapter->ledpriv.LedControlHandler(padapter,
1979 else if (u32wps_start == 2) /* WPS Stop because of wps success */
1980 padapter->ledpriv.LedControlHandler(padapter,
1982 else if (u32wps_start == 3) /* WPS Stop because of wps fail */
1983 padapter->ledpriv.LedControlHandler(padapter,
1984 LED_CTL_STOP_WPS_FAIL);
1988 static int wpa_set_param(struct net_device *dev, u8 name, u32 value)
1990 struct _adapter *padapter = (struct _adapter *) _netdev_priv(dev);
1993 case IEEE_PARAM_WPA_ENABLED:
1994 padapter->securitypriv.AuthAlgrthm = 2; /* 802.1x */
1995 switch ((value)&0xff) {
1997 padapter->securitypriv.ndisauthtype =
1998 Ndis802_11AuthModeWPAPSK; /* WPA_PSK */
1999 padapter->securitypriv.ndisencryptstatus =
2000 Ndis802_11Encryption2Enabled;
2003 padapter->securitypriv.ndisauthtype =
2004 Ndis802_11AuthModeWPA2PSK; /* WPA2_PSK */
2005 padapter->securitypriv.ndisencryptstatus =
2006 Ndis802_11Encryption3Enabled;
2010 case IEEE_PARAM_TKIP_COUNTERMEASURES:
2012 case IEEE_PARAM_DROP_UNENCRYPTED:
2015 * wpa_supplicant calls set_wpa_enabled when the driver
2016 * is loaded and unloaded, regardless of if WPA is being
2017 * used. No other calls are made which can be used to
2018 * determine if encryption will be used or not prior to
2019 * association being expected. If encryption is not being
2020 * used, drop_unencrypted is set to false, else true -- we
2021 * can use this to determine if the CAP_PRIVACY_ON bit should
2025 case IEEE_PARAM_PRIVACY_INVOKED:
2027 case IEEE_PARAM_AUTH_ALGS:
2028 return wpa_set_auth_algs(dev, value);
2030 case IEEE_PARAM_IEEE_802_1X:
2032 case IEEE_PARAM_WPAX_SELECT:
2033 /* added for WPA2 mixed mode */
2041 static int wpa_mlme(struct net_device *dev, u32 command, u32 reason)
2043 struct _adapter *padapter = (struct _adapter *) _netdev_priv(dev);
2046 case IEEE_MLME_STA_DEAUTH:
2047 if (!r8712_set_802_11_disassociate(padapter))
2050 case IEEE_MLME_STA_DISASSOC:
2051 if (!r8712_set_802_11_disassociate(padapter))
2060 static int wpa_supplicant_ioctl(struct net_device *dev, struct iw_point *p)
2062 struct ieee_param *param;
2064 struct _adapter *padapter = (struct _adapter *) _netdev_priv(dev);
2066 if (p->length < sizeof(struct ieee_param) || !p->pointer)
2068 param = (struct ieee_param *)_malloc(p->length);
2071 if (copy_from_user(param, p->pointer, p->length))
2074 switch (param->cmd) {
2075 case IEEE_CMD_SET_WPA_PARAM:
2076 ret = wpa_set_param(dev, param->u.wpa_param.name,
2077 param->u.wpa_param.value);
2079 case IEEE_CMD_SET_WPA_IE:
2080 ret = r871x_set_wpa_ie(padapter, (char *)param->u.wpa_ie.data,
2081 (u16)param->u.wpa_ie.len);
2083 case IEEE_CMD_SET_ENCRYPTION:
2084 ret = wpa_set_encryption(dev, param, p->length);
2087 ret = wpa_mlme(dev, param->u.mlme.command,
2088 param->u.mlme.reason_code);
2094 if (ret == 0 && copy_to_user(p->pointer, param, p->length))
2100 /* based on "driver_ipw" and for hostapd */
2101 int r871x_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
2103 struct iwreq *wrq = (struct iwreq *)rq;
2106 case RTL_IOCTL_WPA_SUPPLICANT:
2107 return wpa_supplicant_ioctl(dev, &wrq->u.data);
2114 static iw_handler r8711_handlers[] = {
2115 NULL, /* SIOCSIWCOMMIT */
2116 r8711_wx_get_name, /* SIOCGIWNAME */
2117 dummy, /* SIOCSIWNWID */
2118 dummy, /* SIOCGIWNWID */
2119 r8711_wx_set_freq, /* SIOCSIWFREQ */
2120 r8711_wx_get_freq, /* SIOCGIWFREQ */
2121 r8711_wx_set_mode, /* SIOCSIWMODE */
2122 r8711_wx_get_mode, /* SIOCGIWMODE */
2123 dummy, /* SIOCSIWSENS */
2124 r8711_wx_get_sens, /* SIOCGIWSENS */
2125 NULL, /* SIOCSIWRANGE */
2126 r8711_wx_get_range, /* SIOCGIWRANGE */
2127 r871x_wx_set_priv, /* SIOCSIWPRIV */
2128 NULL, /* SIOCGIWPRIV */
2129 NULL, /* SIOCSIWSTATS */
2130 NULL, /* SIOCGIWSTATS */
2131 dummy, /* SIOCSIWSPY */
2132 dummy, /* SIOCGIWSPY */
2133 NULL, /* SIOCGIWTHRSPY */
2134 NULL, /* SIOCWIWTHRSPY */
2135 r8711_wx_set_wap, /* SIOCSIWAP */
2136 r8711_wx_get_wap, /* SIOCGIWAP */
2137 r871x_wx_set_mlme, /* request MLME operation;
2138 * uses struct iw_mlme */
2139 dummy, /* SIOCGIWAPLIST -- deprecated */
2140 r8711_wx_set_scan, /* SIOCSIWSCAN */
2141 r8711_wx_get_scan, /* SIOCGIWSCAN */
2142 r8711_wx_set_essid, /* SIOCSIWESSID */
2143 r8711_wx_get_essid, /* SIOCGIWESSID */
2144 dummy, /* SIOCSIWNICKN */
2145 r871x_wx_get_nick, /* SIOCGIWNICKN */
2146 NULL, /* -- hole -- */
2147 NULL, /* -- hole -- */
2148 r8711_wx_set_rate, /* SIOCSIWRATE */
2149 r8711_wx_get_rate, /* SIOCGIWRATE */
2150 dummy, /* SIOCSIWRTS */
2151 r8711_wx_get_rts, /* SIOCGIWRTS */
2152 r8711_wx_set_frag, /* SIOCSIWFRAG */
2153 r8711_wx_get_frag, /* SIOCGIWFRAG */
2154 dummy, /* SIOCSIWTXPOW */
2155 dummy, /* SIOCGIWTXPOW */
2156 dummy, /* SIOCSIWRETRY */
2157 r8711_wx_get_retry, /* SIOCGIWRETRY */
2158 r8711_wx_set_enc, /* SIOCSIWENCODE */
2159 r8711_wx_get_enc, /* SIOCGIWENCODE */
2160 dummy, /* SIOCSIWPOWER */
2161 r8711_wx_get_power, /* SIOCGIWPOWER */
2162 NULL, /*---hole---*/
2163 NULL, /*---hole---*/
2164 r871x_wx_set_gen_ie, /* SIOCSIWGENIE */
2165 NULL, /* SIOCGIWGENIE */
2166 r871x_wx_set_auth, /* SIOCSIWAUTH */
2167 NULL, /* SIOCGIWAUTH */
2168 r871x_wx_set_enc_ext, /* SIOCSIWENCODEEXT */
2169 NULL, /* SIOCGIWENCODEEXT */
2170 r871x_wx_set_pmkid, /* SIOCSIWPMKSA */
2171 NULL, /*---hole---*/
2174 static const struct iw_priv_args r8711_private_args[] = {
2176 SIOCIWFIRSTPRIV + 0x0,
2177 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "read32"
2180 SIOCIWFIRSTPRIV + 0x1,
2181 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "write32"
2184 SIOCIWFIRSTPRIV + 0x2, 0, 0, "driver_ext"
2187 SIOCIWFIRSTPRIV + 0x3, 0, 0, "mp_ioctl"
2190 SIOCIWFIRSTPRIV + 0x4,
2191 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "apinfo"
2194 SIOCIWFIRSTPRIV + 0x5,
2195 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setpid"
2198 SIOCIWFIRSTPRIV + 0x6,
2199 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wps_start"
2203 static iw_handler r8711_private_handler[] = {
2208 r871x_get_ap_info, /*for MM DTV platform*/
2213 static struct iw_statistics *r871x_get_wireless_stats(struct net_device *dev)
2215 struct _adapter *padapter = (struct _adapter *) _netdev_priv(dev);
2216 struct iw_statistics *piwstats = &padapter->iwstats;
2221 if (check_fwstate(&padapter->mlmepriv, _FW_LINKED) != true) {
2222 piwstats->qual.qual = 0;
2223 piwstats->qual.level = 0;
2224 piwstats->qual.noise = 0;
2226 /* show percentage, we need transfer dbm to orignal value. */
2227 tmp_level = padapter->recvpriv.fw_rssi;
2228 tmp_qual = padapter->recvpriv.signal;
2229 tmp_noise = padapter->recvpriv.noise;
2230 piwstats->qual.level = tmp_level;
2231 piwstats->qual.qual = tmp_qual;
2232 piwstats->qual.noise = tmp_noise;
2234 piwstats->qual.updated = IW_QUAL_ALL_UPDATED;
2235 return &padapter->iwstats;
2238 struct iw_handler_def r871x_handlers_def = {
2239 .standard = r8711_handlers,
2240 .num_standard = sizeof(r8711_handlers) / sizeof(iw_handler),
2241 .private = r8711_private_handler,
2242 .private_args = (struct iw_priv_args *)r8711_private_args,
2243 .num_private = sizeof(r8711_private_handler) / sizeof(iw_handler),
2244 .num_private_args = sizeof(r8711_private_args) /
2245 sizeof(struct iw_priv_args),
2246 .get_wireless_stats = r871x_get_wireless_stats,