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,
291 memset(buf, 0, MAX_WPA_IE_LEN);
292 n = sprintf(buf, "wpa_ie=");
293 for (i = 0; i < wpa_len; i++) {
294 n += snprintf(buf + n, MAX_WPA_IE_LEN - n,
296 if (n >= MAX_WPA_IE_LEN)
299 memset(&iwe, 0, sizeof(iwe));
300 iwe.cmd = IWEVCUSTOM;
301 iwe.u.data.length = (u16)strlen(buf);
302 start = iwe_stream_add_point(info, start, stop,
304 memset(&iwe, 0, sizeof(iwe));
306 iwe.u.data.length = (u16)wpa_len;
307 start = iwe_stream_add_point(info, start, stop,
311 memset(buf, 0, MAX_WPA_IE_LEN);
312 n = sprintf(buf, "rsn_ie=");
313 for (i = 0; i < rsn_len; i++) {
314 n += snprintf(buf + n, MAX_WPA_IE_LEN - n,
316 if (n >= MAX_WPA_IE_LEN)
319 memset(&iwe, 0, sizeof(iwe));
320 iwe.cmd = IWEVCUSTOM;
321 iwe.u.data.length = strlen(buf);
322 start = iwe_stream_add_point(info, start, stop,
324 memset(&iwe, 0, sizeof(iwe));
326 iwe.u.data.length = rsn_len;
327 start = iwe_stream_add_point(info, start, stop, &iwe,
332 { /* parsing WPS IE */
335 if (r8712_get_wps_ie(pnetwork->network.IEs,
336 pnetwork->network.IELength,
337 wps_ie, &wps_ielen) == true) {
340 iwe.u.data.length = (u16)wps_ielen;
341 start = iwe_stream_add_point(info, start, stop,
346 /* Add quality statistics */
348 rssi = r8712_signal_scale_mapping(pnetwork->network.Rssi);
349 /* we only update signal_level (signal strength) that is rssi. */
350 iwe.u.qual.updated = (u8)(IW_QUAL_QUAL_INVALID | IW_QUAL_LEVEL_UPDATED |
351 IW_QUAL_NOISE_INVALID);
352 iwe.u.qual.level = rssi; /* signal strength */
353 iwe.u.qual.qual = 0; /* signal quality */
354 iwe.u.qual.noise = 0; /* noise level */
355 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_QUAL_LEN);
356 /* how to translate rssi to ?% */
364 static int wpa_set_auth_algs(struct net_device *dev, u32 value)
366 struct _adapter *padapter = (struct _adapter *) _netdev_priv(dev);
369 if ((value & AUTH_ALG_SHARED_KEY) && (value & AUTH_ALG_OPEN_SYSTEM)) {
370 padapter->securitypriv.ndisencryptstatus =
371 Ndis802_11Encryption1Enabled;
372 padapter->securitypriv.ndisauthtype =
373 Ndis802_11AuthModeAutoSwitch;
374 padapter->securitypriv.AuthAlgrthm = 3;
375 } else if (value & AUTH_ALG_SHARED_KEY) {
376 padapter->securitypriv.ndisencryptstatus =
377 Ndis802_11Encryption1Enabled;
378 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeShared;
379 padapter->securitypriv.AuthAlgrthm = 1;
380 } else if (value & AUTH_ALG_OPEN_SYSTEM) {
381 if (padapter->securitypriv.ndisauthtype <
382 Ndis802_11AuthModeWPAPSK) {
383 padapter->securitypriv.ndisauthtype =
384 Ndis802_11AuthModeOpen;
385 padapter->securitypriv.AuthAlgrthm = 0;
392 static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param,
396 u32 wep_key_idx, wep_key_len = 0;
397 struct NDIS_802_11_WEP *pwep = NULL;
398 struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
399 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
400 struct security_priv *psecuritypriv = &padapter->securitypriv;
402 param->u.crypt.err = 0;
403 param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
404 if (param_len != (u32)((u8 *) param->u.crypt.key - (u8 *)param) +
405 param->u.crypt.key_len)
407 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
408 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
409 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
410 if (param->u.crypt.idx >= WEP_KEYS) {
411 /* for large key indices, set the default (0) */
412 param->u.crypt.idx = 0;
416 if (strcmp(param->u.crypt.alg, "WEP") == 0) {
417 printk(KERN_INFO "r8712u: wpa_set_encryption, crypt.alg ="
419 padapter->securitypriv.ndisencryptstatus =
420 Ndis802_11Encryption1Enabled;
421 padapter->securitypriv.PrivacyAlgrthm = _WEP40_;
422 padapter->securitypriv.XGrpPrivacy = _WEP40_;
423 wep_key_idx = param->u.crypt.idx;
424 wep_key_len = param->u.crypt.key_len;
425 if (wep_key_idx >= WEP_KEYS)
427 if (wep_key_len > 0) {
428 wep_key_len = wep_key_len <= 5 ? 5 : 13;
429 pwep = (struct NDIS_802_11_WEP *)_malloc((u32)
431 FIELD_OFFSET(struct NDIS_802_11_WEP,
435 memset(pwep, 0, sizeof(struct NDIS_802_11_WEP));
436 pwep->KeyLength = wep_key_len;
437 pwep->Length = wep_key_len +
438 FIELD_OFFSET(struct NDIS_802_11_WEP,
440 if (wep_key_len == 13) {
441 padapter->securitypriv.PrivacyAlgrthm =
443 padapter->securitypriv.XGrpPrivacy =
448 pwep->KeyIndex = wep_key_idx;
449 pwep->KeyIndex |= 0x80000000;
450 memcpy(pwep->KeyMaterial, param->u.crypt.key, pwep->KeyLength);
451 if (param->u.crypt.set_tx) {
452 if (r8712_set_802_11_add_wep(padapter, pwep) ==
456 /* don't update "psecuritypriv->PrivacyAlgrthm" and
457 * "psecuritypriv->PrivacyKeyIndex=keyid", but can
458 * r8712_set_key to fw/cam
460 if (wep_key_idx >= WEP_KEYS) {
464 memcpy(&(psecuritypriv->DefKey[wep_key_idx].
465 skey[0]), pwep->KeyMaterial,
467 psecuritypriv->DefKeylen[wep_key_idx] =
469 r8712_set_key(padapter, psecuritypriv, wep_key_idx);
473 if (padapter->securitypriv.AuthAlgrthm == 2) { /* 802_1x */
474 struct sta_info *psta, *pbcmc_sta;
475 struct sta_priv *pstapriv = &padapter->stapriv;
477 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE |
478 WIFI_MP_STATE) == true) { /* sta mode */
479 psta = r8712_get_stainfo(pstapriv,
480 get_bssid(pmlmepriv));
482 psta->ieee8021x_blocked = false;
483 if ((padapter->securitypriv.ndisencryptstatus ==
484 Ndis802_11Encryption2Enabled) ||
485 (padapter->securitypriv.ndisencryptstatus ==
486 Ndis802_11Encryption3Enabled))
487 psta->XPrivacy = padapter->
488 securitypriv.PrivacyAlgrthm;
489 if (param->u.crypt.set_tx == 1)
490 handle_pairwise_key(psta, param,
493 handle_group_key(param, padapter);
495 pbcmc_sta = r8712_get_bcmc_stainfo(padapter);
497 pbcmc_sta->ieee8021x_blocked = false;
498 if ((padapter->securitypriv.ndisencryptstatus ==
499 Ndis802_11Encryption2Enabled) ||
500 (padapter->securitypriv.ndisencryptstatus ==
501 Ndis802_11Encryption3Enabled))
502 pbcmc_sta->XPrivacy =
503 padapter->securitypriv.
513 static int r871x_set_wpa_ie(struct _adapter *padapter, char *pie,
514 unsigned short ielen)
516 u8 *buf = NULL, *pos = NULL;
517 int group_cipher = 0, pairwise_cipher = 0;
520 if ((ielen > MAX_WPA_IE_LEN) || (pie == NULL))
523 buf = _malloc(ielen);
526 memcpy(buf, pie , ielen);
528 if (ielen < RSN_HEADER_LEN) {
532 if (r8712_parse_wpa_ie(buf, ielen, &group_cipher,
533 &pairwise_cipher) == _SUCCESS) {
534 padapter->securitypriv.AuthAlgrthm = 2;
535 padapter->securitypriv.ndisauthtype =
536 Ndis802_11AuthModeWPAPSK;
538 if (r8712_parse_wpa2_ie(buf, ielen, &group_cipher,
539 &pairwise_cipher) == _SUCCESS) {
540 padapter->securitypriv.AuthAlgrthm = 2;
541 padapter->securitypriv.ndisauthtype =
542 Ndis802_11AuthModeWPA2PSK;
544 switch (group_cipher) {
545 case WPA_CIPHER_NONE:
546 padapter->securitypriv.XGrpPrivacy =
548 padapter->securitypriv.ndisencryptstatus =
549 Ndis802_11EncryptionDisabled;
551 case WPA_CIPHER_WEP40:
552 padapter->securitypriv.XGrpPrivacy = _WEP40_;
553 padapter->securitypriv.ndisencryptstatus =
554 Ndis802_11Encryption1Enabled;
556 case WPA_CIPHER_TKIP:
557 padapter->securitypriv.XGrpPrivacy = _TKIP_;
558 padapter->securitypriv.ndisencryptstatus =
559 Ndis802_11Encryption2Enabled;
561 case WPA_CIPHER_CCMP:
562 padapter->securitypriv.XGrpPrivacy = _AES_;
563 padapter->securitypriv.ndisencryptstatus =
564 Ndis802_11Encryption3Enabled;
566 case WPA_CIPHER_WEP104:
567 padapter->securitypriv.XGrpPrivacy = _WEP104_;
568 padapter->securitypriv.ndisencryptstatus =
569 Ndis802_11Encryption1Enabled;
572 switch (pairwise_cipher) {
573 case WPA_CIPHER_NONE:
574 padapter->securitypriv.PrivacyAlgrthm =
576 padapter->securitypriv.ndisencryptstatus =
577 Ndis802_11EncryptionDisabled;
579 case WPA_CIPHER_WEP40:
580 padapter->securitypriv.PrivacyAlgrthm = _WEP40_;
581 padapter->securitypriv.ndisencryptstatus =
582 Ndis802_11Encryption1Enabled;
584 case WPA_CIPHER_TKIP:
585 padapter->securitypriv.PrivacyAlgrthm = _TKIP_;
586 padapter->securitypriv.ndisencryptstatus =
587 Ndis802_11Encryption2Enabled;
589 case WPA_CIPHER_CCMP:
590 padapter->securitypriv.PrivacyAlgrthm = _AES_;
591 padapter->securitypriv.ndisencryptstatus =
592 Ndis802_11Encryption3Enabled;
594 case WPA_CIPHER_WEP104:
595 padapter->securitypriv.PrivacyAlgrthm = _WEP104_;
596 padapter->securitypriv.ndisencryptstatus =
597 Ndis802_11Encryption1Enabled;
600 padapter->securitypriv.wps_phase = false;
603 u8 eid, wps_oui[4] = {0x0, 0x50, 0xf2, 0x04};
605 while (cnt < ielen) {
608 if ((eid == _VENDOR_SPECIFIC_IE_) &&
609 (!memcmp(&buf[cnt+2], wps_oui, 4))) {
610 printk(KERN_INFO "r8712u: "
612 padapter->securitypriv.wps_ie_len =
614 (MAX_WPA_IE_LEN << 2)) ?
616 (MAX_WPA_IE_LEN << 2);
617 memcpy(padapter->securitypriv.wps_ie,
619 padapter->securitypriv.wps_ie_len);
620 padapter->securitypriv.wps_phase =
622 printk(KERN_INFO "r8712u: SET WPS_IE,"
623 " wps_phase==true\n");
627 cnt += buf[cnt + 1] + 2;
636 static int r8711_wx_get_name(struct net_device *dev,
637 struct iw_request_info *info,
638 union iwreq_data *wrqu, char *extra)
640 struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
644 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
645 struct ndis_wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
646 NDIS_802_11_RATES_EX *prates = NULL;
648 if (check_fwstate(pmlmepriv, _FW_LINKED|WIFI_ADHOC_MASTER_STATE) ==
650 /* parsing HT_CAP_IE */
651 p = r8712_get_ie(&pcur_bss->IEs[12], _HT_CAPABILITY_IE_,
652 &ht_ielen, pcur_bss->IELength - 12);
653 if (p && ht_ielen > 0)
655 prates = &pcur_bss->SupportedRates;
656 if (r8712_is_cckratesonly_included((u8 *)prates) == true) {
658 snprintf(wrqu->name, IFNAMSIZ,
661 snprintf(wrqu->name, IFNAMSIZ,
663 } else if ((r8712_is_cckrates_included((u8 *)prates)) == true) {
665 snprintf(wrqu->name, IFNAMSIZ,
668 snprintf(wrqu->name, IFNAMSIZ,
672 snprintf(wrqu->name, IFNAMSIZ,
675 snprintf(wrqu->name, IFNAMSIZ,
679 snprintf(wrqu->name, IFNAMSIZ, "unassociated");
683 static const long frequency_list[] = {
684 2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447, 2452, 2457, 2462,
685 2467, 2472, 2484, 4915, 4920, 4925, 4935, 4940, 4945, 4960, 4980,
686 5035, 5040, 5045, 5055, 5060, 5080, 5170, 5180, 5190, 5200, 5210,
687 5220, 5230, 5240, 5260, 5280, 5300, 5320, 5500, 5520, 5540, 5560,
688 5580, 5600, 5620, 5640, 5660, 5680, 5700, 5745, 5765, 5785, 5805,
692 static int r8711_wx_set_freq(struct net_device *dev,
693 struct iw_request_info *info,
694 union iwreq_data *wrqu, char *extra)
696 struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
697 struct iw_freq *fwrq = &wrqu->freq;
700 /* If setting by frequency, convert to a channel */
701 if ((fwrq->e == 1) &&
702 (fwrq->m >= (int) 2.412e8) &&
703 (fwrq->m <= (int) 2.487e8)) {
704 int f = fwrq->m / 100000;
706 while ((c < 14) && (f != frequency_list[c]))
711 /* Setting by channel number */
712 if ((fwrq->m > 14) || (fwrq->e > 0))
715 int channel = fwrq->m;
716 if ((channel < 1) || (channel > 14))
719 /* Yes ! We can set it !!! */
720 padapter->registrypriv.channel = channel;
726 static int r8711_wx_get_freq(struct net_device *dev,
727 struct iw_request_info *info,
728 union iwreq_data *wrqu, char *extra)
730 struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
731 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
732 struct ndis_wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
734 if (check_fwstate(pmlmepriv, _FW_LINKED) == true) {
735 wrqu->freq.m = ieee80211_wlan_frequencies[
736 pcur_bss->Configuration.DSConfig-1] * 100000;
738 wrqu->freq.i = pcur_bss->Configuration.DSConfig;
744 static int r8711_wx_set_mode(struct net_device *dev,
745 struct iw_request_info *a,
746 union iwreq_data *wrqu, char *b)
748 struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
749 enum NDIS_802_11_NETWORK_INFRASTRUCTURE networkType;
751 switch (wrqu->mode) {
753 networkType = Ndis802_11AutoUnknown;
756 networkType = Ndis802_11IBSS;
759 networkType = Ndis802_11APMode;
762 networkType = Ndis802_11Infrastructure;
767 if (Ndis802_11APMode == networkType)
768 r8712_setopmode_cmd(padapter, networkType);
770 r8712_setopmode_cmd(padapter, Ndis802_11AutoUnknown);
771 if (!r8712_set_802_11_infrastructure_mode(padapter, networkType))
776 static int r8711_wx_get_mode(struct net_device *dev, struct iw_request_info *a,
777 union iwreq_data *wrqu, char *b)
779 struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
780 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
782 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == true)
783 wrqu->mode = IW_MODE_INFRA;
784 else if (check_fwstate(pmlmepriv,
785 WIFI_ADHOC_MASTER_STATE|WIFI_ADHOC_STATE) == true)
786 wrqu->mode = IW_MODE_ADHOC;
787 else if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == true)
788 wrqu->mode = IW_MODE_MASTER;
790 wrqu->mode = IW_MODE_AUTO;
794 static int r871x_wx_set_pmkid(struct net_device *dev,
795 struct iw_request_info *a,
796 union iwreq_data *wrqu, char *extra)
798 struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
799 struct security_priv *psecuritypriv = &padapter->securitypriv;
800 struct iw_pmksa *pPMK = (struct iw_pmksa *) extra;
801 u8 strZeroMacAddress[ETH_ALEN] = {0x00};
802 u8 strIssueBssid[ETH_ALEN] = {0x00};
803 u8 j, blInserted = false;
804 int intReturn = false;
807 There are the BSSID information in the bssid.sa_data array.
808 If cmd is IW_PMKSA_FLUSH, it means the wpa_suppplicant wants to clear
809 all the PMKID information. If cmd is IW_PMKSA_ADD, it means the
810 wpa_supplicant wants to add a PMKID/BSSID to driver.
811 If cmd is IW_PMKSA_REMOVE, it means the wpa_supplicant wants to
812 remove a PMKID/BSSID from driver.
816 memcpy(strIssueBssid, pPMK->bssid.sa_data, ETH_ALEN);
819 if (!memcmp(strIssueBssid, strZeroMacAddress, ETH_ALEN))
824 /* overwrite PMKID */
825 for (j = 0 ; j < NUM_PMKID_CACHE; j++) {
826 if (!memcmp(psecuritypriv->PMKIDList[j].Bssid,
827 strIssueBssid, ETH_ALEN)) {
828 /* BSSID is matched, the same AP => rewrite
830 printk(KERN_INFO "r8712u: r871x_wx_set_pmkid:"
831 " BSSID exists in the PMKList.\n");
832 memcpy(psecuritypriv->PMKIDList[j].PMKID,
833 pPMK->pmkid, IW_PMKID_LEN);
834 psecuritypriv->PMKIDList[j].bUsed = true;
835 psecuritypriv->PMKIDIndex = j + 1;
841 /* Find a new entry */
842 printk(KERN_INFO "r8712u: r871x_wx_set_pmkid: Use the"
843 " new entry index = %d for this PMKID.\n",
844 psecuritypriv->PMKIDIndex);
845 memcpy(psecuritypriv->PMKIDList[psecuritypriv->
846 PMKIDIndex].Bssid, strIssueBssid, ETH_ALEN);
847 memcpy(psecuritypriv->PMKIDList[psecuritypriv->
848 PMKIDIndex].PMKID, pPMK->pmkid, IW_PMKID_LEN);
849 psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].
851 psecuritypriv->PMKIDIndex++ ;
852 if (psecuritypriv->PMKIDIndex == NUM_PMKID_CACHE)
853 psecuritypriv->PMKIDIndex = 0;
856 case IW_PMKSA_REMOVE:
858 for (j = 0; j < NUM_PMKID_CACHE; j++) {
859 if (!memcmp(psecuritypriv->PMKIDList[j].Bssid,
860 strIssueBssid, ETH_ALEN)) {
861 /* BSSID is matched, the same AP => Remove
862 * this PMKID information and reset it. */
863 memset(psecuritypriv->PMKIDList[j].Bssid,
865 psecuritypriv->PMKIDList[j].bUsed = false;
871 memset(psecuritypriv->PMKIDList, 0,
872 sizeof(struct RT_PMKID_LIST) * NUM_PMKID_CACHE);
873 psecuritypriv->PMKIDIndex = 0;
877 printk(KERN_INFO "r8712u: r871x_wx_set_pmkid: "
878 "unknown Command\n");
885 static int r8711_wx_get_sens(struct net_device *dev,
886 struct iw_request_info *info,
887 union iwreq_data *wrqu, char *extra)
889 wrqu->sens.value = 0;
890 wrqu->sens.fixed = 0; /* no auto select */
891 wrqu->sens.disabled = 1;
895 static int r8711_wx_get_range(struct net_device *dev,
896 struct iw_request_info *info,
897 union iwreq_data *wrqu, char *extra)
899 struct iw_range *range = (struct iw_range *)extra;
903 wrqu->data.length = sizeof(*range);
904 memset(range, 0, sizeof(*range));
905 /* Let's try to keep this struct in the same order as in
906 * linux/include/wireless.h
909 /* TODO: See what values we can set, and remove the ones we can't
910 * set, or fill them with some default data.
912 /* ~5 Mb/s real (802.11b) */
913 range->throughput = 5 * 1000 * 1000;
914 /* TODO: 8711 sensitivity ? */
915 /* signal level threshold range */
916 /* percent values between 0 and 100. */
917 range->max_qual.qual = 100;
918 range->max_qual.level = 100;
919 range->max_qual.noise = 100;
920 range->max_qual.updated = 7; /* Updated all three */
921 range->avg_qual.qual = 92; /* > 8% missed beacons is 'bad' */
922 /* TODO: Find real 'good' to 'bad' threshol value for RSSI */
923 range->avg_qual.level = 20 + -98;
924 range->avg_qual.noise = 0;
925 range->avg_qual.updated = 7; /* Updated all three */
926 range->num_bitrates = RATE_COUNT;
927 for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++)
928 range->bitrate[i] = rtl8180_rates[i];
929 range->min_frag = MIN_FRAG_THRESHOLD;
930 range->max_frag = MAX_FRAG_THRESHOLD;
932 range->we_version_compiled = WIRELESS_EXT;
933 range->we_version_source = 16;
934 range->num_channels = 14;
935 for (i = 0, val = 0; i < 14; i++) {
936 /* Include only legal frequencies for some countries */
937 range->freq[val].i = i + 1;
938 range->freq[val].m = ieee80211_wlan_frequencies[i] * 100000;
939 range->freq[val].e = 1;
941 if (val == IW_MAX_FREQUENCIES)
944 range->num_frequency = val;
945 range->enc_capa = IW_ENC_CAPA_WPA |
947 IW_ENC_CAPA_CIPHER_TKIP |
948 IW_ENC_CAPA_CIPHER_CCMP;
952 static int r871x_wx_set_priv(struct net_device *dev,
953 struct iw_request_info *info,
954 union iwreq_data *awrq,
957 int ret = 0, len = 0;
959 struct iw_point *dwrq = (struct iw_point *)awrq;
965 if (copy_from_user(ext, dwrq->pointer, len)) {
974 * s1. set_802_11_infrastructure_mode()
975 * s2. set_802_11_authentication_mode()
976 * s3. set_802_11_encryption_mode()
977 * s4. set_802_11_bssid()
979 * This function intends to handle the Set AP command, which specifies the
980 * MAC# of a preferred Access Point.
981 * Currently, the request comes via Wireless Extensions' SIOCSIWAP ioctl.
983 * For this operation to succeed, there is no need for the interface to be Up.
986 static int r8711_wx_set_wap(struct net_device *dev,
987 struct iw_request_info *info,
988 union iwreq_data *awrq,
991 int ret = -EINPROGRESS;
992 struct _adapter *padapter = (struct _adapter *) _netdev_priv(dev);
993 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
994 struct __queue *queue = &pmlmepriv->scanned_queue;
995 struct sockaddr *temp = (struct sockaddr *)awrq;
997 struct list_head *phead;
999 struct wlan_network *pnetwork = NULL;
1000 enum NDIS_802_11_AUTHENTICATION_MODE authmode;
1002 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == true)
1004 if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == true)
1006 if (temp->sa_family != ARPHRD_ETHER)
1008 authmode = padapter->securitypriv.ndisauthtype;
1009 spin_lock_irqsave(&queue->lock, irqL);
1010 phead = get_list_head(queue);
1011 pmlmepriv->pscanned = get_next(phead);
1013 if (end_of_queue_search(phead, pmlmepriv->pscanned) == true)
1015 pnetwork = LIST_CONTAINOR(pmlmepriv->pscanned,
1016 struct wlan_network, list);
1017 pmlmepriv->pscanned = get_next(pmlmepriv->pscanned);
1018 dst_bssid = pnetwork->network.MacAddress;
1019 if (!memcmp(dst_bssid, temp->sa_data, ETH_ALEN)) {
1020 if (r8712_set_802_11_infrastructure_mode(padapter,
1021 pnetwork->network.InfrastructureMode) == false)
1026 spin_unlock_irqrestore(&queue->lock, irqL);
1028 if (!r8712_set_802_11_authentication_mode(padapter, authmode))
1031 if (!r8712_set_802_11_bssid(padapter, temp->sa_data))
1038 static int r8711_wx_get_wap(struct net_device *dev,
1039 struct iw_request_info *info,
1040 union iwreq_data *wrqu, char *extra)
1042 struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
1043 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1044 struct ndis_wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
1046 wrqu->ap_addr.sa_family = ARPHRD_ETHER;
1047 memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN);
1048 if (check_fwstate(pmlmepriv, _FW_LINKED |
1049 WIFI_ADHOC_MASTER_STATE|WIFI_AP_STATE)) {
1050 memcpy(wrqu->ap_addr.sa_data, pcur_bss->MacAddress, ETH_ALEN);
1055 static int r871x_wx_set_mlme(struct net_device *dev,
1056 struct iw_request_info *info,
1057 union iwreq_data *wrqu, char *extra)
1061 struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
1062 struct iw_mlme *mlme = (struct iw_mlme *) extra;
1066 reason = cpu_to_le16(mlme->reason_code);
1067 switch (mlme->cmd) {
1068 case IW_MLME_DEAUTH:
1069 if (!r8712_set_802_11_disassociate(padapter))
1072 case IW_MLME_DISASSOC:
1073 if (!r8712_set_802_11_disassociate(padapter))
1084 * This function intends to handle the Set Scan command.
1085 * Currently, the request comes via Wireless Extensions' SIOCSIWSCAN ioctl.
1087 * For this operation to succeed, the interface is brought Up beforehand.
1090 static int r8711_wx_set_scan(struct net_device *dev,
1091 struct iw_request_info *a,
1092 union iwreq_data *wrqu, char *extra)
1094 struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
1095 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1098 if (padapter->bDriverStopped == true) {
1099 printk(KERN_WARNING "r8712u: in r8711_wx_set_scan: "
1100 "bDriverStopped=%d\n", padapter->bDriverStopped);
1103 if (padapter->bup == false)
1105 if (padapter->hw_init_completed == false)
1107 if ((check_fwstate(pmlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING)) ||
1108 (pmlmepriv->sitesurveyctrl.traffic_busy == true))
1110 if (wrqu->data.length == sizeof(struct iw_scan_req)) {
1111 struct iw_scan_req *req = (struct iw_scan_req *)extra;
1112 if (wrqu->data.flags & IW_SCAN_THIS_ESSID) {
1113 struct ndis_802_11_ssid ssid;
1115 u32 len = (u32) min((u8)req->essid_len,
1116 (u8)IW_ESSID_MAX_SIZE);
1117 memset((unsigned char *)&ssid, 0,
1118 sizeof(struct ndis_802_11_ssid));
1119 memcpy(ssid.Ssid, req->essid, len);
1120 ssid.SsidLength = len;
1121 spin_lock_irqsave(&pmlmepriv->lock, irqL);
1122 if ((check_fwstate(pmlmepriv, _FW_UNDER_SURVEY |
1123 _FW_UNDER_LINKING)) ||
1124 (pmlmepriv->sitesurveyctrl.traffic_busy == true)) {
1125 if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING))
1128 status = r8712_sitesurvey_cmd(padapter, &ssid);
1129 spin_unlock_irqrestore(&pmlmepriv->lock, irqL);
1132 status = r8712_set_802_11_bssid_list_scan(padapter);
1133 if (status == false)
1138 static int r8711_wx_get_scan(struct net_device *dev,
1139 struct iw_request_info *a,
1140 union iwreq_data *wrqu, char *extra)
1142 struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
1143 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1144 struct __queue *queue = &pmlmepriv->scanned_queue;
1145 struct wlan_network *pnetwork = NULL;
1147 struct list_head *plist, *phead;
1149 char *stop = ev + wrqu->data.length;
1150 u32 ret = 0, cnt = 0;
1152 if (padapter->bDriverStopped)
1154 while (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING)) {
1160 spin_lock_irqsave(&queue->lock, irqL);
1161 phead = get_list_head(queue);
1162 plist = get_next(phead);
1164 if (end_of_queue_search(phead, plist) == true)
1166 if ((stop - ev) < SCAN_ITEM_SIZE) {
1170 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
1171 ev = translate_scan(padapter, a, pnetwork, ev, stop);
1172 plist = get_next(plist);
1174 spin_unlock_irqrestore(&queue->lock, irqL);
1175 wrqu->data.length = ev - extra;
1176 wrqu->data.flags = 0;
1181 * s1. set_802_11_infrastructure_mode()
1182 * s2. set_802_11_authenticaion_mode()
1183 * s3. set_802_11_encryption_mode()
1184 * s4. set_802_11_ssid()
1186 * This function intends to handle the Set ESSID command.
1187 * Currently, the request comes via the Wireless Extensions' SIOCSIWESSID ioctl.
1189 * For this operation to succeed, there is no need for the interface to be Up.
1192 static int r8711_wx_set_essid(struct net_device *dev,
1193 struct iw_request_info *a,
1194 union iwreq_data *wrqu, char *extra)
1196 struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
1197 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1198 struct __queue *queue = &pmlmepriv->scanned_queue;
1199 struct wlan_network *pnetwork = NULL;
1200 enum NDIS_802_11_AUTHENTICATION_MODE authmode;
1201 struct ndis_802_11_ssid ndis_ssid;
1202 u8 *dst_ssid, *src_ssid;
1203 struct list_head *phead;
1206 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY))
1208 if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING))
1210 if (wrqu->essid.length > IW_ESSID_MAX_SIZE)
1212 authmode = padapter->securitypriv.ndisauthtype;
1213 if (wrqu->essid.flags && wrqu->essid.length) {
1214 len = (wrqu->essid.length < IW_ESSID_MAX_SIZE) ?
1215 wrqu->essid.length : IW_ESSID_MAX_SIZE;
1216 memset(&ndis_ssid, 0, sizeof(struct ndis_802_11_ssid));
1217 ndis_ssid.SsidLength = len;
1218 memcpy(ndis_ssid.Ssid, extra, len);
1219 src_ssid = ndis_ssid.Ssid;
1220 phead = get_list_head(queue);
1221 pmlmepriv->pscanned = get_next(phead);
1223 if (end_of_queue_search(phead, pmlmepriv->pscanned))
1225 pnetwork = LIST_CONTAINOR(pmlmepriv->pscanned,
1226 struct wlan_network, list);
1227 pmlmepriv->pscanned = get_next(pmlmepriv->pscanned);
1228 dst_ssid = pnetwork->network.Ssid.Ssid;
1229 if ((!memcmp(dst_ssid, src_ssid, ndis_ssid.SsidLength))
1230 && (pnetwork->network.Ssid.SsidLength ==
1231 ndis_ssid.SsidLength)) {
1232 if (!r8712_set_802_11_infrastructure_mode(
1234 pnetwork->network.InfrastructureMode))
1239 r8712_set_802_11_authentication_mode(padapter, authmode);
1240 r8712_set_802_11_ssid(padapter, &ndis_ssid);
1242 return -EINPROGRESS;
1245 static int r8711_wx_get_essid(struct net_device *dev,
1246 struct iw_request_info *a,
1247 union iwreq_data *wrqu, char *extra)
1249 struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
1250 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1251 struct ndis_wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
1254 if (check_fwstate(pmlmepriv, _FW_LINKED|WIFI_ADHOC_MASTER_STATE)) {
1255 len = pcur_bss->Ssid.SsidLength;
1256 wrqu->essid.length = len;
1257 memcpy(extra, pcur_bss->Ssid.Ssid, len);
1258 wrqu->essid.flags = 1;
1264 static int r8711_wx_set_rate(struct net_device *dev,
1265 struct iw_request_info *a,
1266 union iwreq_data *wrqu, char *extra)
1268 struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
1269 u32 target_rate = wrqu->bitrate.value;
1270 u32 fixed = wrqu->bitrate.fixed;
1272 u8 datarates[NumRates];
1273 u8 mpdatarate[NumRates] = {11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0xff};
1276 if (target_rate == -1) {
1280 target_rate = target_rate / 100000;
1281 switch (target_rate) {
1323 for (i = 0; i < NumRates; i++) {
1324 if (ratevalue == mpdatarate[i]) {
1325 datarates[i] = mpdatarate[i];
1329 datarates[i] = 0xff;
1331 if (r8712_setdatarate_cmd(padapter, datarates) != _SUCCESS)
1336 static int r8711_wx_get_rate(struct net_device *dev,
1337 struct iw_request_info *info,
1338 union iwreq_data *wrqu, char *extra)
1340 struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
1341 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1342 struct ndis_wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
1343 struct ieee80211_ht_cap *pht_capie;
1346 u16 rate, max_rate = 0, ht_cap = false;
1348 u8 bw_40MHz = 0, short_GI = 0;
1352 if (check_fwstate(pmlmepriv, _FW_LINKED|WIFI_ADHOC_MASTER_STATE)) {
1353 p = r8712_get_ie(&pcur_bss->IEs[12],
1354 _HT_CAPABILITY_IE_, &ht_ielen,
1355 pcur_bss->IELength - 12);
1356 if (p && ht_ielen > 0) {
1358 pht_capie = (struct ieee80211_ht_cap *)(p + 2);
1359 memcpy(&mcs_rate , pht_capie->supp_mcs_set, 2);
1360 bw_40MHz = (pht_capie->cap_info &
1361 IEEE80211_HT_CAP_SUP_WIDTH) ? 1 : 0;
1362 short_GI = (pht_capie->cap_info &
1363 (IEEE80211_HT_CAP_SGI_20 |
1364 IEEE80211_HT_CAP_SGI_40)) ? 1 : 0;
1366 while ((pcur_bss->SupportedRates[i] != 0) &&
1367 (pcur_bss->SupportedRates[i] != 0xFF)) {
1368 rate = pcur_bss->SupportedRates[i] & 0x7F;
1369 if (rate > max_rate)
1371 wrqu->bitrate.fixed = 0; /* no auto select */
1372 wrqu->bitrate.value = rate*500000;
1375 if (ht_cap == true) {
1376 if (mcs_rate & 0x8000) /* MCS15 */
1377 max_rate = (bw_40MHz) ? ((short_GI) ? 300 :
1378 270) : ((short_GI) ? 144 : 130);
1379 else if (mcs_rate & 0x0080) /* MCS7 */
1380 max_rate = (bw_40MHz) ? ((short_GI) ? 150 :
1381 135) : ((short_GI) ? 72 : 65);
1382 else /* default MCS7 */
1383 max_rate = (bw_40MHz) ? ((short_GI) ? 150 :
1384 135) : ((short_GI) ? 72 : 65);
1385 max_rate *= 2; /* Mbps/2 */
1386 wrqu->bitrate.value = max_rate * 500000;
1388 wrqu->bitrate.value = max_rate * 500000;
1395 static int r8711_wx_get_rts(struct net_device *dev,
1396 struct iw_request_info *info,
1397 union iwreq_data *wrqu, char *extra)
1399 struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
1401 wrqu->rts.value = padapter->registrypriv.rts_thresh;
1402 wrqu->rts.fixed = 0; /* no auto select */
1406 static int r8711_wx_set_frag(struct net_device *dev,
1407 struct iw_request_info *info,
1408 union iwreq_data *wrqu, char *extra)
1410 struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
1412 if (wrqu->frag.disabled)
1413 padapter->xmitpriv.frag_len = MAX_FRAG_THRESHOLD;
1415 if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
1416 wrqu->frag.value > MAX_FRAG_THRESHOLD)
1418 padapter->xmitpriv.frag_len = wrqu->frag.value & ~0x1;
1423 static int r8711_wx_get_frag(struct net_device *dev,
1424 struct iw_request_info *info,
1425 union iwreq_data *wrqu, char *extra)
1427 struct _adapter *padapter = (struct _adapter *) _netdev_priv(dev);
1429 wrqu->frag.value = padapter->xmitpriv.frag_len;
1430 wrqu->frag.fixed = 0; /* no auto select */
1434 static int r8711_wx_get_retry(struct net_device *dev,
1435 struct iw_request_info *info,
1436 union iwreq_data *wrqu, char *extra)
1438 wrqu->retry.value = 7;
1439 wrqu->retry.fixed = 0; /* no auto select */
1440 wrqu->retry.disabled = 1;
1444 static int r8711_wx_set_enc(struct net_device *dev,
1445 struct iw_request_info *info,
1446 union iwreq_data *wrqu, char *keybuf)
1449 u32 keyindex_provided;
1450 struct NDIS_802_11_WEP wep;
1451 enum NDIS_802_11_AUTHENTICATION_MODE authmode;
1452 struct iw_point *erq = &(wrqu->encoding);
1453 struct _adapter *padapter = (struct _adapter *) _netdev_priv(dev);
1455 key = erq->flags & IW_ENCODE_INDEX;
1456 memset(&wep, 0, sizeof(struct NDIS_802_11_WEP));
1457 if (erq->flags & IW_ENCODE_DISABLED) {
1458 printk(KERN_INFO "r8712u: r8711_wx_set_enc: "
1459 "EncryptionDisabled\n");
1460 padapter->securitypriv.ndisencryptstatus =
1461 Ndis802_11EncryptionDisabled;
1462 padapter->securitypriv.PrivacyAlgrthm = _NO_PRIVACY_;
1463 padapter->securitypriv.XGrpPrivacy = _NO_PRIVACY_;
1464 padapter->securitypriv.AuthAlgrthm = 0; /* open system */
1465 authmode = Ndis802_11AuthModeOpen;
1466 padapter->securitypriv.ndisauthtype = authmode;
1473 keyindex_provided = 1;
1475 keyindex_provided = 0;
1476 key = padapter->securitypriv.PrivacyKeyIndex;
1478 /* set authentication mode */
1479 if (erq->flags & IW_ENCODE_OPEN) {
1480 printk(KERN_INFO "r8712u: r8711_wx_set_enc: "
1481 "IW_ENCODE_OPEN\n");
1482 padapter->securitypriv.ndisencryptstatus =
1483 Ndis802_11Encryption1Enabled;
1484 padapter->securitypriv.AuthAlgrthm = 0; /* open system */
1485 padapter->securitypriv.PrivacyAlgrthm = _NO_PRIVACY_;
1486 padapter->securitypriv.XGrpPrivacy = _NO_PRIVACY_;
1487 authmode = Ndis802_11AuthModeOpen;
1488 padapter->securitypriv.ndisauthtype = authmode;
1489 } else if (erq->flags & IW_ENCODE_RESTRICTED) {
1490 printk(KERN_INFO "r8712u: r8711_wx_set_enc: "
1491 "IW_ENCODE_RESTRICTED\n");
1492 padapter->securitypriv.ndisencryptstatus =
1493 Ndis802_11Encryption1Enabled;
1494 padapter->securitypriv.AuthAlgrthm = 1; /* shared system */
1495 padapter->securitypriv.PrivacyAlgrthm = _WEP40_;
1496 padapter->securitypriv.XGrpPrivacy = _WEP40_;
1497 authmode = Ndis802_11AuthModeShared;
1498 padapter->securitypriv.ndisauthtype = authmode;
1500 padapter->securitypriv.ndisencryptstatus =
1501 Ndis802_11Encryption1Enabled;
1502 padapter->securitypriv.AuthAlgrthm = 0; /* open system */
1503 padapter->securitypriv.PrivacyAlgrthm = _NO_PRIVACY_;
1504 padapter->securitypriv.XGrpPrivacy = _NO_PRIVACY_;
1505 authmode = Ndis802_11AuthModeOpen;
1506 padapter->securitypriv.ndisauthtype = authmode;
1509 if (erq->length > 0) {
1510 wep.KeyLength = erq->length <= 5 ? 5 : 13;
1511 wep.Length = wep.KeyLength +
1512 FIELD_OFFSET(struct NDIS_802_11_WEP, KeyMaterial);
1515 if (keyindex_provided == 1) { /* set key_id only, no given
1516 * KeyMaterial(erq->length==0).*/
1517 padapter->securitypriv.PrivacyKeyIndex = key;
1518 switch (padapter->securitypriv.DefKeylen[key]) {
1520 padapter->securitypriv.PrivacyAlgrthm =
1524 padapter->securitypriv.PrivacyAlgrthm =
1528 padapter->securitypriv.PrivacyAlgrthm =
1535 wep.KeyIndex |= 0x80000000; /* transmit key */
1536 memcpy(wep.KeyMaterial, keybuf, wep.KeyLength);
1537 if (r8712_set_802_11_add_wep(padapter, &wep) == _FAIL)
1542 static int r8711_wx_get_enc(struct net_device *dev,
1543 struct iw_request_info *info,
1544 union iwreq_data *wrqu, char *keybuf)
1547 struct _adapter *padapter = (struct _adapter *) _netdev_priv(dev);
1548 struct iw_point *erq = &(wrqu->encoding);
1549 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1551 if (check_fwstate(pmlmepriv, _FW_LINKED) == false) {
1552 if (!check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) {
1554 erq->flags |= IW_ENCODE_DISABLED;
1558 key = erq->flags & IW_ENCODE_INDEX;
1564 key = padapter->securitypriv.PrivacyKeyIndex;
1566 erq->flags = key + 1;
1567 switch (padapter->securitypriv.ndisencryptstatus) {
1568 case Ndis802_11EncryptionNotSupported:
1569 case Ndis802_11EncryptionDisabled:
1571 erq->flags |= IW_ENCODE_DISABLED;
1573 case Ndis802_11Encryption1Enabled:
1574 erq->length = padapter->securitypriv.DefKeylen[key];
1576 memcpy(keybuf, padapter->securitypriv.DefKey[
1577 key].skey, padapter->securitypriv.
1579 erq->flags |= IW_ENCODE_ENABLED;
1580 if (padapter->securitypriv.ndisauthtype ==
1581 Ndis802_11AuthModeOpen)
1582 erq->flags |= IW_ENCODE_OPEN;
1583 else if (padapter->securitypriv.ndisauthtype ==
1584 Ndis802_11AuthModeShared)
1585 erq->flags |= IW_ENCODE_RESTRICTED;
1588 erq->flags |= IW_ENCODE_DISABLED;
1591 case Ndis802_11Encryption2Enabled:
1592 case Ndis802_11Encryption3Enabled:
1594 erq->flags |= (IW_ENCODE_ENABLED | IW_ENCODE_OPEN |
1599 erq->flags |= IW_ENCODE_DISABLED;
1605 static int r8711_wx_get_power(struct net_device *dev,
1606 struct iw_request_info *info,
1607 union iwreq_data *wrqu, char *extra)
1609 wrqu->power.value = 0;
1610 wrqu->power.fixed = 0; /* no auto select */
1611 wrqu->power.disabled = 1;
1615 static int r871x_wx_set_gen_ie(struct net_device *dev,
1616 struct iw_request_info *info,
1617 union iwreq_data *wrqu, char *extra)
1619 struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
1621 return r871x_set_wpa_ie(padapter, extra, wrqu->data.length);
1624 static int r871x_wx_set_auth(struct net_device *dev,
1625 struct iw_request_info *info,
1626 union iwreq_data *wrqu, char *extra)
1628 struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
1629 struct iw_param *param = (struct iw_param *)&(wrqu->param);
1634 paramid = param->flags & IW_AUTH_INDEX;
1635 paramval = param->value;
1637 case IW_AUTH_WPA_VERSION:
1639 case IW_AUTH_CIPHER_PAIRWISE:
1641 case IW_AUTH_CIPHER_GROUP:
1643 case IW_AUTH_KEY_MGMT:
1645 * ??? does not use these parameters
1648 case IW_AUTH_TKIP_COUNTERMEASURES:
1650 /* wpa_supplicant is enabling tkip countermeasure. */
1651 padapter->securitypriv.btkip_countermeasure = true;
1653 /* wpa_supplicant is disabling tkip countermeasure. */
1654 padapter->securitypriv.btkip_countermeasure = false;
1657 case IW_AUTH_DROP_UNENCRYPTED:
1660 * wpa_supplicant calls set_wpa_enabled when the driver
1661 * is loaded and unloaded, regardless of if WPA is being
1662 * used. No other calls are made which can be used to
1663 * determine if encryption will be used or not prior to
1664 * association being expected. If encryption is not being
1665 * used, drop_unencrypted is set to false, else true -- we
1666 * can use this to determine if the CAP_PRIVACY_ON bit should
1669 if (padapter->securitypriv.ndisencryptstatus ==
1670 Ndis802_11Encryption1Enabled) {
1671 /* it means init value, or using wep,
1672 * ndisencryptstatus =
1673 * Ndis802_11Encryption1Enabled,
1674 * then it needn't reset it;
1680 padapter->securitypriv.ndisencryptstatus =
1681 Ndis802_11EncryptionDisabled;
1682 padapter->securitypriv.PrivacyAlgrthm =
1684 padapter->securitypriv.XGrpPrivacy =
1686 padapter->securitypriv.AuthAlgrthm = 0;
1687 padapter->securitypriv.ndisauthtype =
1688 Ndis802_11AuthModeOpen;
1691 case IW_AUTH_80211_AUTH_ALG:
1692 ret = wpa_set_auth_algs(dev, (u32)paramval);
1694 case IW_AUTH_WPA_ENABLED:
1696 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
1698 case IW_AUTH_PRIVACY_INVOKED:
1707 static int r871x_wx_set_enc_ext(struct net_device *dev,
1708 struct iw_request_info *info,
1709 union iwreq_data *wrqu, char *extra)
1711 struct iw_point *pencoding = &wrqu->encoding;
1712 struct iw_encode_ext *pext = (struct iw_encode_ext *)extra;
1713 struct ieee_param *param = NULL;
1718 param_len = sizeof(struct ieee_param) + pext->key_len;
1719 param = (struct ieee_param *)_malloc(param_len);
1722 memset(param, 0, param_len);
1723 param->cmd = IEEE_CMD_SET_ENCRYPTION;
1724 memset(param->sta_addr, 0xff, ETH_ALEN);
1725 switch (pext->alg) {
1726 case IW_ENCODE_ALG_NONE:
1729 case IW_ENCODE_ALG_WEP:
1732 case IW_ENCODE_ALG_TKIP:
1735 case IW_ENCODE_ALG_CCMP:
1741 strncpy((char *)param->u.crypt.alg, alg_name, IEEE_CRYPT_ALG_NAME_LEN);
1742 if (pext->ext_flags & IW_ENCODE_EXT_GROUP_KEY)
1743 param->u.crypt.set_tx = 0;
1744 if (pext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
1745 param->u.crypt.set_tx = 1;
1746 param->u.crypt.idx = (pencoding->flags & 0x00FF) - 1;
1747 if (pext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID)
1748 memcpy(param->u.crypt.seq, pext->rx_seq, 8);
1749 if (pext->key_len) {
1750 param->u.crypt.key_len = pext->key_len;
1751 memcpy(param + 1, pext + 1, pext->key_len);
1753 ret = wpa_set_encryption(dev, param, param_len);
1758 static int r871x_wx_get_nick(struct net_device *dev,
1759 struct iw_request_info *info,
1760 union iwreq_data *wrqu, char *extra)
1763 wrqu->data.length = 8;
1764 wrqu->data.flags = 1;
1765 memcpy(extra, "rtl_wifi", 8);
1770 static int r8711_wx_read32(struct net_device *dev,
1771 struct iw_request_info *info,
1772 union iwreq_data *wrqu, char *keybuf)
1774 struct _adapter *padapter = (struct _adapter *) _netdev_priv(dev);
1778 get_user(addr, (u32 __user *)wrqu->data.pointer);
1779 data32 = r8712_read32(padapter, addr);
1780 put_user(data32, (u32 __user *)wrqu->data.pointer);
1781 wrqu->data.length = (data32 & 0xffff0000) >> 16;
1782 wrqu->data.flags = data32 & 0xffff;
1783 get_user(addr, (u32 __user *)wrqu->data.pointer);
1787 static int r8711_wx_write32(struct net_device *dev,
1788 struct iw_request_info *info,
1789 union iwreq_data *wrqu, char *keybuf)
1791 struct _adapter *padapter = (struct _adapter *) _netdev_priv(dev);
1795 get_user(addr, (u32 __user *)wrqu->data.pointer);
1796 data32 = ((u32)wrqu->data.length<<16) | (u32)wrqu->data.flags ;
1797 r8712_write32(padapter, addr, data32);
1801 static int dummy(struct net_device *dev,
1802 struct iw_request_info *a,
1803 union iwreq_data *wrqu, char *b)
1808 static int r8711_drvext_hdl(struct net_device *dev,
1809 struct iw_request_info *info,
1810 union iwreq_data *wrqu, char *extra)
1815 static int r871x_mp_ioctl_hdl(struct net_device *dev,
1816 struct iw_request_info *info,
1817 union iwreq_data *wrqu, char *extra)
1819 struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
1820 struct iw_point *p = &wrqu->data;
1821 struct oid_par_priv oid_par;
1822 struct mp_ioctl_handler *phandler;
1823 struct mp_ioctl_param *poidparam;
1824 unsigned long BytesRead, BytesWritten, BytesNeeded;
1825 u8 *pparmbuf = NULL, bset;
1830 if ((!p->length) || (!p->pointer)) {
1832 goto _r871x_mp_ioctl_hdl_exit;
1834 bset = (u8)(p->flags & 0xFFFF);
1837 pparmbuf = (u8 *)_malloc(len);
1838 if (pparmbuf == NULL) {
1840 goto _r871x_mp_ioctl_hdl_exit;
1842 if (copy_from_user(pparmbuf, p->pointer, len)) {
1844 goto _r871x_mp_ioctl_hdl_exit;
1846 poidparam = (struct mp_ioctl_param *)pparmbuf;
1847 if (poidparam->subcode >= MAX_MP_IOCTL_SUBCODE) {
1849 goto _r871x_mp_ioctl_hdl_exit;
1851 phandler = mp_ioctl_hdl + poidparam->subcode;
1852 if ((phandler->paramsize != 0) &&
1853 (poidparam->len < phandler->paramsize)) {
1855 goto _r871x_mp_ioctl_hdl_exit;
1857 if (phandler->oid == 0 && phandler->handler)
1858 status = phandler->handler(&oid_par);
1859 else if (phandler->handler) {
1860 oid_par.adapter_context = padapter;
1861 oid_par.oid = phandler->oid;
1862 oid_par.information_buf = poidparam->data;
1863 oid_par.information_buf_len = poidparam->len;
1868 oid_par.bytes_rw = &BytesRead;
1869 oid_par.bytes_needed = &BytesNeeded;
1870 oid_par.type_of_oid = SET_OID;
1872 oid_par.bytes_rw = &BytesWritten;
1873 oid_par.bytes_needed = &BytesNeeded;
1874 oid_par.type_of_oid = QUERY_OID;
1876 status = phandler->handler(&oid_par);
1877 /* todo:check status, BytesNeeded, etc. */
1879 printk(KERN_INFO "r8712u: r871x_mp_ioctl_hdl(): err!,"
1880 " subcode=%d, oid=%d, handler=%p\n",
1881 poidparam->subcode, phandler->oid, phandler->handler);
1883 goto _r871x_mp_ioctl_hdl_exit;
1885 if (bset == 0x00) { /* query info */
1886 if (copy_to_user(p->pointer, pparmbuf, len))
1891 goto _r871x_mp_ioctl_hdl_exit;
1893 _r871x_mp_ioctl_hdl_exit:
1898 static int r871x_get_ap_info(struct net_device *dev,
1899 struct iw_request_info *info,
1900 union iwreq_data *wrqu, char *extra)
1902 struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
1903 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1904 struct __queue *queue = &pmlmepriv->scanned_queue;
1905 struct iw_point *pdata = &wrqu->data;
1906 struct wlan_network *pnetwork = NULL;
1907 u32 cnt = 0, wpa_ielen;
1909 struct list_head *plist, *phead;
1910 unsigned char *pbuf;
1914 if (padapter->bDriverStopped || (pdata == NULL))
1916 while (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING)) {
1923 if (pdata->length >= 32) {
1924 if (copy_from_user(data, pdata->pointer, 32))
1928 spin_lock_irqsave(&(pmlmepriv->scanned_queue.lock), irqL);
1929 phead = get_list_head(queue);
1930 plist = get_next(phead);
1932 if (end_of_queue_search(phead, plist) == true)
1934 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
1935 if (hwaddr_aton_i(data, bssid)) {
1936 printk(KERN_INFO "r8712u: Invalid BSSID '%s'.\n",
1938 spin_unlock_irqrestore(&(pmlmepriv->scanned_queue.lock),
1942 printk(KERN_INFO "r8712u: BSSID:%pM\n", bssid);
1943 if (!memcmp(bssid, pnetwork->network.MacAddress, ETH_ALEN)) {
1944 /* BSSID match, then check if supporting wpa/wpa2 */
1945 pbuf = r8712_get_wpa_ie(&pnetwork->network.IEs[12],
1946 &wpa_ielen, pnetwork->network.IELength-12);
1947 if (pbuf && (wpa_ielen > 0)) {
1951 pbuf = r8712_get_wpa2_ie(&pnetwork->network.IEs[12],
1952 &wpa_ielen, pnetwork->network.IELength-12);
1953 if (pbuf && (wpa_ielen > 0)) {
1958 plist = get_next(plist);
1960 spin_unlock_irqrestore(&(pmlmepriv->scanned_queue.lock), irqL);
1961 if (pdata->length >= 34) {
1962 if (copy_to_user((u8 __user *)pdata->pointer + 32,
1963 (u8 *)&pdata->flags, 1))
1969 static int r871x_set_pid(struct net_device *dev,
1970 struct iw_request_info *info,
1971 union iwreq_data *wrqu, char *extra)
1973 struct _adapter *padapter = (struct _adapter *) _netdev_priv(dev);
1974 struct iw_point *pdata = &wrqu->data;
1976 if ((padapter->bDriverStopped) || (pdata == NULL))
1978 if (copy_from_user(&padapter->pid, pdata->pointer, sizeof(int)))
1983 static int r871x_wps_start(struct net_device *dev,
1984 struct iw_request_info *info,
1985 union iwreq_data *wrqu, char *extra)
1987 struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
1988 struct iw_point *pdata = &wrqu->data;
1989 u32 u32wps_start = 0;
1991 if (copy_from_user((void *)&u32wps_start, pdata->pointer, 4))
1993 if ((padapter->bDriverStopped) || (pdata == NULL))
1995 if (u32wps_start == 0)
1996 u32wps_start = *extra;
1997 if (u32wps_start == 1) /* WPS Start */
1998 padapter->ledpriv.LedControlHandler(padapter,
2000 else if (u32wps_start == 2) /* WPS Stop because of wps success */
2001 padapter->ledpriv.LedControlHandler(padapter,
2003 else if (u32wps_start == 3) /* WPS Stop because of wps fail */
2004 padapter->ledpriv.LedControlHandler(padapter,
2005 LED_CTL_STOP_WPS_FAIL);
2009 static int wpa_set_param(struct net_device *dev, u8 name, u32 value)
2011 struct _adapter *padapter = (struct _adapter *) _netdev_priv(dev);
2014 case IEEE_PARAM_WPA_ENABLED:
2015 padapter->securitypriv.AuthAlgrthm = 2; /* 802.1x */
2016 switch ((value)&0xff) {
2018 padapter->securitypriv.ndisauthtype =
2019 Ndis802_11AuthModeWPAPSK; /* WPA_PSK */
2020 padapter->securitypriv.ndisencryptstatus =
2021 Ndis802_11Encryption2Enabled;
2024 padapter->securitypriv.ndisauthtype =
2025 Ndis802_11AuthModeWPA2PSK; /* WPA2_PSK */
2026 padapter->securitypriv.ndisencryptstatus =
2027 Ndis802_11Encryption3Enabled;
2031 case IEEE_PARAM_TKIP_COUNTERMEASURES:
2033 case IEEE_PARAM_DROP_UNENCRYPTED:
2036 * wpa_supplicant calls set_wpa_enabled when the driver
2037 * is loaded and unloaded, regardless of if WPA is being
2038 * used. No other calls are made which can be used to
2039 * determine if encryption will be used or not prior to
2040 * association being expected. If encryption is not being
2041 * used, drop_unencrypted is set to false, else true -- we
2042 * can use this to determine if the CAP_PRIVACY_ON bit should
2046 case IEEE_PARAM_PRIVACY_INVOKED:
2048 case IEEE_PARAM_AUTH_ALGS:
2049 return wpa_set_auth_algs(dev, value);
2051 case IEEE_PARAM_IEEE_802_1X:
2053 case IEEE_PARAM_WPAX_SELECT:
2054 /* added for WPA2 mixed mode */
2062 static int wpa_mlme(struct net_device *dev, u32 command, u32 reason)
2064 struct _adapter *padapter = (struct _adapter *) _netdev_priv(dev);
2067 case IEEE_MLME_STA_DEAUTH:
2068 if (!r8712_set_802_11_disassociate(padapter))
2071 case IEEE_MLME_STA_DISASSOC:
2072 if (!r8712_set_802_11_disassociate(padapter))
2081 static int wpa_supplicant_ioctl(struct net_device *dev, struct iw_point *p)
2083 struct ieee_param *param;
2085 struct _adapter *padapter = (struct _adapter *) _netdev_priv(dev);
2087 if (p->length < sizeof(struct ieee_param) || !p->pointer)
2089 param = (struct ieee_param *)_malloc(p->length);
2092 if (copy_from_user(param, p->pointer, p->length)) {
2096 switch (param->cmd) {
2097 case IEEE_CMD_SET_WPA_PARAM:
2098 ret = wpa_set_param(dev, param->u.wpa_param.name,
2099 param->u.wpa_param.value);
2101 case IEEE_CMD_SET_WPA_IE:
2102 ret = r871x_set_wpa_ie(padapter, (char *)param->u.wpa_ie.data,
2103 (u16)param->u.wpa_ie.len);
2105 case IEEE_CMD_SET_ENCRYPTION:
2106 ret = wpa_set_encryption(dev, param, p->length);
2109 ret = wpa_mlme(dev, param->u.mlme.command,
2110 param->u.mlme.reason_code);
2116 if (ret == 0 && copy_to_user(p->pointer, param, p->length))
2122 /* based on "driver_ipw" and for hostapd */
2123 int r871x_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
2125 struct iwreq *wrq = (struct iwreq *)rq;
2128 case RTL_IOCTL_WPA_SUPPLICANT:
2129 return wpa_supplicant_ioctl(dev, &wrq->u.data);
2136 static iw_handler r8711_handlers[] = {
2137 NULL, /* SIOCSIWCOMMIT */
2138 r8711_wx_get_name, /* SIOCGIWNAME */
2139 dummy, /* SIOCSIWNWID */
2140 dummy, /* SIOCGIWNWID */
2141 r8711_wx_set_freq, /* SIOCSIWFREQ */
2142 r8711_wx_get_freq, /* SIOCGIWFREQ */
2143 r8711_wx_set_mode, /* SIOCSIWMODE */
2144 r8711_wx_get_mode, /* SIOCGIWMODE */
2145 dummy, /* SIOCSIWSENS */
2146 r8711_wx_get_sens, /* SIOCGIWSENS */
2147 NULL, /* SIOCSIWRANGE */
2148 r8711_wx_get_range, /* SIOCGIWRANGE */
2149 r871x_wx_set_priv, /* SIOCSIWPRIV */
2150 NULL, /* SIOCGIWPRIV */
2151 NULL, /* SIOCSIWSTATS */
2152 NULL, /* SIOCGIWSTATS */
2153 dummy, /* SIOCSIWSPY */
2154 dummy, /* SIOCGIWSPY */
2155 NULL, /* SIOCGIWTHRSPY */
2156 NULL, /* SIOCWIWTHRSPY */
2157 r8711_wx_set_wap, /* SIOCSIWAP */
2158 r8711_wx_get_wap, /* SIOCGIWAP */
2159 r871x_wx_set_mlme, /* request MLME operation;
2160 * uses struct iw_mlme */
2161 dummy, /* SIOCGIWAPLIST -- deprecated */
2162 r8711_wx_set_scan, /* SIOCSIWSCAN */
2163 r8711_wx_get_scan, /* SIOCGIWSCAN */
2164 r8711_wx_set_essid, /* SIOCSIWESSID */
2165 r8711_wx_get_essid, /* SIOCGIWESSID */
2166 dummy, /* SIOCSIWNICKN */
2167 r871x_wx_get_nick, /* SIOCGIWNICKN */
2168 NULL, /* -- hole -- */
2169 NULL, /* -- hole -- */
2170 r8711_wx_set_rate, /* SIOCSIWRATE */
2171 r8711_wx_get_rate, /* SIOCGIWRATE */
2172 dummy, /* SIOCSIWRTS */
2173 r8711_wx_get_rts, /* SIOCGIWRTS */
2174 r8711_wx_set_frag, /* SIOCSIWFRAG */
2175 r8711_wx_get_frag, /* SIOCGIWFRAG */
2176 dummy, /* SIOCSIWTXPOW */
2177 dummy, /* SIOCGIWTXPOW */
2178 dummy, /* SIOCSIWRETRY */
2179 r8711_wx_get_retry, /* SIOCGIWRETRY */
2180 r8711_wx_set_enc, /* SIOCSIWENCODE */
2181 r8711_wx_get_enc, /* SIOCGIWENCODE */
2182 dummy, /* SIOCSIWPOWER */
2183 r8711_wx_get_power, /* SIOCGIWPOWER */
2184 NULL, /*---hole---*/
2185 NULL, /*---hole---*/
2186 r871x_wx_set_gen_ie, /* SIOCSIWGENIE */
2187 NULL, /* SIOCGIWGENIE */
2188 r871x_wx_set_auth, /* SIOCSIWAUTH */
2189 NULL, /* SIOCGIWAUTH */
2190 r871x_wx_set_enc_ext, /* SIOCSIWENCODEEXT */
2191 NULL, /* SIOCGIWENCODEEXT */
2192 r871x_wx_set_pmkid, /* SIOCSIWPMKSA */
2193 NULL, /*---hole---*/
2196 static const struct iw_priv_args r8711_private_args[] = {
2198 SIOCIWFIRSTPRIV + 0x0,
2199 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "read32"
2202 SIOCIWFIRSTPRIV + 0x1,
2203 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "write32"
2206 SIOCIWFIRSTPRIV + 0x2, 0, 0, "driver_ext"
2209 SIOCIWFIRSTPRIV + 0x3, 0, 0, "mp_ioctl"
2212 SIOCIWFIRSTPRIV + 0x4,
2213 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "apinfo"
2216 SIOCIWFIRSTPRIV + 0x5,
2217 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setpid"
2220 SIOCIWFIRSTPRIV + 0x6,
2221 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wps_start"
2225 static iw_handler r8711_private_handler[] = {
2230 r871x_get_ap_info, /*for MM DTV platform*/
2235 static struct iw_statistics *r871x_get_wireless_stats(struct net_device *dev)
2237 struct _adapter *padapter = (struct _adapter *) _netdev_priv(dev);
2238 struct iw_statistics *piwstats = &padapter->iwstats;
2243 if (check_fwstate(&padapter->mlmepriv, _FW_LINKED) != true) {
2244 piwstats->qual.qual = 0;
2245 piwstats->qual.level = 0;
2246 piwstats->qual.noise = 0;
2248 /* show percentage, we need transfer dbm to orignal value. */
2249 tmp_level = padapter->recvpriv.fw_rssi;
2250 tmp_qual = padapter->recvpriv.signal;
2251 tmp_noise = padapter->recvpriv.noise;
2252 piwstats->qual.level = tmp_level;
2253 piwstats->qual.qual = tmp_qual;
2254 piwstats->qual.noise = tmp_noise;
2256 piwstats->qual.updated = IW_QUAL_ALL_UPDATED;
2257 return &padapter->iwstats;
2260 struct iw_handler_def r871x_handlers_def = {
2261 .standard = r8711_handlers,
2262 .num_standard = sizeof(r8711_handlers) / sizeof(iw_handler),
2263 .private = r8711_private_handler,
2264 .private_args = (struct iw_priv_args *)r8711_private_args,
2265 .num_private = sizeof(r8711_private_handler) / sizeof(iw_handler),
2266 .num_private_args = sizeof(r8711_private_args) /
2267 sizeof(struct iw_priv_args),
2268 .get_wireless_stats = r871x_get_wireless_stats,