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 static int r8711_wx_set_wap(struct net_device *dev,
980 struct iw_request_info *info,
981 union iwreq_data *awrq,
984 int ret = -EINPROGRESS;
985 struct _adapter *padapter = (struct _adapter *) _netdev_priv(dev);
986 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
987 struct __queue *queue = &pmlmepriv->scanned_queue;
988 struct sockaddr *temp = (struct sockaddr *)awrq;
990 struct list_head *phead;
992 struct wlan_network *pnetwork = NULL;
993 enum NDIS_802_11_AUTHENTICATION_MODE authmode;
995 if (padapter->bup == false)
997 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == true)
999 if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == true)
1001 if (temp->sa_family != ARPHRD_ETHER)
1003 authmode = padapter->securitypriv.ndisauthtype;
1004 spin_lock_irqsave(&queue->lock, irqL);
1005 phead = get_list_head(queue);
1006 pmlmepriv->pscanned = get_next(phead);
1008 if (end_of_queue_search(phead, pmlmepriv->pscanned) == true)
1010 pnetwork = LIST_CONTAINOR(pmlmepriv->pscanned,
1011 struct wlan_network, list);
1012 pmlmepriv->pscanned = get_next(pmlmepriv->pscanned);
1013 dst_bssid = pnetwork->network.MacAddress;
1014 if (!memcmp(dst_bssid, temp->sa_data, ETH_ALEN)) {
1015 if (r8712_set_802_11_infrastructure_mode(padapter,
1016 pnetwork->network.InfrastructureMode) == false)
1021 spin_unlock_irqrestore(&queue->lock, irqL);
1023 if (!r8712_set_802_11_authentication_mode(padapter, authmode))
1026 if (!r8712_set_802_11_bssid(padapter, temp->sa_data))
1033 static int r8711_wx_get_wap(struct net_device *dev,
1034 struct iw_request_info *info,
1035 union iwreq_data *wrqu, char *extra)
1037 struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
1038 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1039 struct ndis_wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
1041 wrqu->ap_addr.sa_family = ARPHRD_ETHER;
1042 memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN);
1043 if (check_fwstate(pmlmepriv, _FW_LINKED |
1044 WIFI_ADHOC_MASTER_STATE|WIFI_AP_STATE)) {
1045 memcpy(wrqu->ap_addr.sa_data, pcur_bss->MacAddress, ETH_ALEN);
1050 static int r871x_wx_set_mlme(struct net_device *dev,
1051 struct iw_request_info *info,
1052 union iwreq_data *wrqu, char *extra)
1056 struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
1057 struct iw_mlme *mlme = (struct iw_mlme *) extra;
1061 reason = cpu_to_le16(mlme->reason_code);
1062 switch (mlme->cmd) {
1063 case IW_MLME_DEAUTH:
1064 if (!r8712_set_802_11_disassociate(padapter))
1067 case IW_MLME_DISASSOC:
1068 if (!r8712_set_802_11_disassociate(padapter))
1077 static int r8711_wx_set_scan(struct net_device *dev,
1078 struct iw_request_info *a,
1079 union iwreq_data *wrqu, char *extra)
1081 struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
1082 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1085 if (padapter->bDriverStopped == true) {
1086 printk(KERN_WARNING "r8712u: in r8711_wx_set_scan: "
1087 "bDriverStopped=%d\n", padapter->bDriverStopped);
1090 if (padapter->bup == false)
1092 if (padapter->hw_init_completed == false)
1094 if ((check_fwstate(pmlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING)) ||
1095 (pmlmepriv->sitesurveyctrl.traffic_busy == true))
1097 if (wrqu->data.length == sizeof(struct iw_scan_req)) {
1098 struct iw_scan_req *req = (struct iw_scan_req *)extra;
1099 if (wrqu->data.flags & IW_SCAN_THIS_ESSID) {
1100 struct ndis_802_11_ssid ssid;
1102 u32 len = (u32) min((u8)req->essid_len,
1103 (u8)IW_ESSID_MAX_SIZE);
1104 memset((unsigned char *)&ssid, 0,
1105 sizeof(struct ndis_802_11_ssid));
1106 memcpy(ssid.Ssid, req->essid, len);
1107 ssid.SsidLength = len;
1108 spin_lock_irqsave(&pmlmepriv->lock, irqL);
1109 if ((check_fwstate(pmlmepriv, _FW_UNDER_SURVEY |
1110 _FW_UNDER_LINKING)) ||
1111 (pmlmepriv->sitesurveyctrl.traffic_busy == true)) {
1112 if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING))
1115 status = r8712_sitesurvey_cmd(padapter, &ssid);
1116 spin_unlock_irqrestore(&pmlmepriv->lock, irqL);
1119 status = r8712_set_802_11_bssid_list_scan(padapter);
1120 if (status == false)
1125 static int r8711_wx_get_scan(struct net_device *dev,
1126 struct iw_request_info *a,
1127 union iwreq_data *wrqu, char *extra)
1129 struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
1130 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1131 struct __queue *queue = &pmlmepriv->scanned_queue;
1132 struct wlan_network *pnetwork = NULL;
1134 struct list_head *plist, *phead;
1136 char *stop = ev + wrqu->data.length;
1137 u32 ret = 0, cnt = 0;
1139 if (padapter->bDriverStopped)
1141 while (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING)) {
1147 spin_lock_irqsave(&queue->lock, irqL);
1148 phead = get_list_head(queue);
1149 plist = get_next(phead);
1151 if (end_of_queue_search(phead, plist) == true)
1153 if ((stop - ev) < SCAN_ITEM_SIZE) {
1157 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
1158 ev = translate_scan(padapter, a, pnetwork, ev, stop);
1159 plist = get_next(plist);
1161 spin_unlock_irqrestore(&queue->lock, irqL);
1162 wrqu->data.length = ev - extra;
1163 wrqu->data.flags = 0;
1168 * s1. set_802_11_infrastructure_mode()
1169 * s2. set_802_11_authenticaion_mode()
1170 * s3. set_802_11_encryption_mode()
1171 * s4. set_802_11_ssid()
1173 static int r8711_wx_set_essid(struct net_device *dev,
1174 struct iw_request_info *a,
1175 union iwreq_data *wrqu, char *extra)
1177 struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
1178 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1179 struct __queue *queue = &pmlmepriv->scanned_queue;
1180 struct wlan_network *pnetwork = NULL;
1181 enum NDIS_802_11_AUTHENTICATION_MODE authmode;
1182 struct ndis_802_11_ssid ndis_ssid;
1183 u8 *dst_ssid, *src_ssid;
1184 struct list_head *phead;
1187 if (padapter->bup == false)
1189 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY))
1191 if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING))
1193 if (wrqu->essid.length > IW_ESSID_MAX_SIZE)
1195 authmode = padapter->securitypriv.ndisauthtype;
1196 if (wrqu->essid.flags && wrqu->essid.length) {
1197 len = (wrqu->essid.length < IW_ESSID_MAX_SIZE) ?
1198 wrqu->essid.length : IW_ESSID_MAX_SIZE;
1199 memset(&ndis_ssid, 0, sizeof(struct ndis_802_11_ssid));
1200 ndis_ssid.SsidLength = len;
1201 memcpy(ndis_ssid.Ssid, extra, len);
1202 src_ssid = ndis_ssid.Ssid;
1203 phead = get_list_head(queue);
1204 pmlmepriv->pscanned = get_next(phead);
1206 if (end_of_queue_search(phead, pmlmepriv->pscanned))
1208 pnetwork = LIST_CONTAINOR(pmlmepriv->pscanned,
1209 struct wlan_network, list);
1210 pmlmepriv->pscanned = get_next(pmlmepriv->pscanned);
1211 dst_ssid = pnetwork->network.Ssid.Ssid;
1212 if ((!memcmp(dst_ssid, src_ssid, ndis_ssid.SsidLength))
1213 && (pnetwork->network.Ssid.SsidLength ==
1214 ndis_ssid.SsidLength)) {
1215 if (!r8712_set_802_11_infrastructure_mode(
1217 pnetwork->network.InfrastructureMode))
1222 r8712_set_802_11_authentication_mode(padapter, authmode);
1223 r8712_set_802_11_ssid(padapter, &ndis_ssid);
1225 return -EINPROGRESS;
1228 static int r8711_wx_get_essid(struct net_device *dev,
1229 struct iw_request_info *a,
1230 union iwreq_data *wrqu, char *extra)
1232 struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
1233 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1234 struct ndis_wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
1237 if (check_fwstate(pmlmepriv, _FW_LINKED|WIFI_ADHOC_MASTER_STATE)) {
1238 len = pcur_bss->Ssid.SsidLength;
1239 wrqu->essid.length = len;
1240 memcpy(extra, pcur_bss->Ssid.Ssid, len);
1241 wrqu->essid.flags = 1;
1247 static int r8711_wx_set_rate(struct net_device *dev,
1248 struct iw_request_info *a,
1249 union iwreq_data *wrqu, char *extra)
1251 struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
1252 u32 target_rate = wrqu->bitrate.value;
1253 u32 fixed = wrqu->bitrate.fixed;
1255 u8 datarates[NumRates];
1256 u8 mpdatarate[NumRates] = {11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0xff};
1259 if (target_rate == -1) {
1263 target_rate = target_rate / 100000;
1264 switch (target_rate) {
1306 for (i = 0; i < NumRates; i++) {
1307 if (ratevalue == mpdatarate[i]) {
1308 datarates[i] = mpdatarate[i];
1312 datarates[i] = 0xff;
1314 if (r8712_setdatarate_cmd(padapter, datarates) != _SUCCESS)
1319 static int r8711_wx_get_rate(struct net_device *dev,
1320 struct iw_request_info *info,
1321 union iwreq_data *wrqu, char *extra)
1323 struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
1324 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1325 struct ndis_wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
1326 struct ieee80211_ht_cap *pht_capie;
1329 u16 rate, max_rate = 0, ht_cap = false;
1331 u8 bw_40MHz = 0, short_GI = 0;
1335 if (check_fwstate(pmlmepriv, _FW_LINKED|WIFI_ADHOC_MASTER_STATE)) {
1336 p = r8712_get_ie(&pcur_bss->IEs[12],
1337 _HT_CAPABILITY_IE_, &ht_ielen,
1338 pcur_bss->IELength - 12);
1339 if (p && ht_ielen > 0) {
1341 pht_capie = (struct ieee80211_ht_cap *)(p + 2);
1342 memcpy(&mcs_rate , pht_capie->supp_mcs_set, 2);
1343 bw_40MHz = (pht_capie->cap_info &
1344 IEEE80211_HT_CAP_SUP_WIDTH) ? 1 : 0;
1345 short_GI = (pht_capie->cap_info &
1346 (IEEE80211_HT_CAP_SGI_20 |
1347 IEEE80211_HT_CAP_SGI_40)) ? 1 : 0;
1349 while ((pcur_bss->SupportedRates[i] != 0) &&
1350 (pcur_bss->SupportedRates[i] != 0xFF)) {
1351 rate = pcur_bss->SupportedRates[i] & 0x7F;
1352 if (rate > max_rate)
1354 wrqu->bitrate.fixed = 0; /* no auto select */
1355 wrqu->bitrate.value = rate*500000;
1358 if (ht_cap == true) {
1359 if (mcs_rate & 0x8000) /* MCS15 */
1360 max_rate = (bw_40MHz) ? ((short_GI) ? 300 :
1361 270) : ((short_GI) ? 144 : 130);
1362 else if (mcs_rate & 0x0080) /* MCS7 */
1363 max_rate = (bw_40MHz) ? ((short_GI) ? 150 :
1364 135) : ((short_GI) ? 72 : 65);
1365 else /* default MCS7 */
1366 max_rate = (bw_40MHz) ? ((short_GI) ? 150 :
1367 135) : ((short_GI) ? 72 : 65);
1368 max_rate *= 2; /* Mbps/2 */
1369 wrqu->bitrate.value = max_rate * 500000;
1371 wrqu->bitrate.value = max_rate * 500000;
1378 static int r8711_wx_get_rts(struct net_device *dev,
1379 struct iw_request_info *info,
1380 union iwreq_data *wrqu, char *extra)
1382 struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
1384 wrqu->rts.value = padapter->registrypriv.rts_thresh;
1385 wrqu->rts.fixed = 0; /* no auto select */
1389 static int r8711_wx_set_frag(struct net_device *dev,
1390 struct iw_request_info *info,
1391 union iwreq_data *wrqu, char *extra)
1393 struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
1395 if (wrqu->frag.disabled)
1396 padapter->xmitpriv.frag_len = MAX_FRAG_THRESHOLD;
1398 if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
1399 wrqu->frag.value > MAX_FRAG_THRESHOLD)
1401 padapter->xmitpriv.frag_len = wrqu->frag.value & ~0x1;
1406 static int r8711_wx_get_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 wrqu->frag.value = padapter->xmitpriv.frag_len;
1413 wrqu->frag.fixed = 0; /* no auto select */
1417 static int r8711_wx_get_retry(struct net_device *dev,
1418 struct iw_request_info *info,
1419 union iwreq_data *wrqu, char *extra)
1421 wrqu->retry.value = 7;
1422 wrqu->retry.fixed = 0; /* no auto select */
1423 wrqu->retry.disabled = 1;
1427 static int r8711_wx_set_enc(struct net_device *dev,
1428 struct iw_request_info *info,
1429 union iwreq_data *wrqu, char *keybuf)
1432 u32 keyindex_provided;
1433 struct NDIS_802_11_WEP wep;
1434 enum NDIS_802_11_AUTHENTICATION_MODE authmode;
1435 struct iw_point *erq = &(wrqu->encoding);
1436 struct _adapter *padapter = (struct _adapter *) _netdev_priv(dev);
1438 key = erq->flags & IW_ENCODE_INDEX;
1439 memset(&wep, 0, sizeof(struct NDIS_802_11_WEP));
1440 if (erq->flags & IW_ENCODE_DISABLED) {
1441 printk(KERN_INFO "r8712u: r8711_wx_set_enc: "
1442 "EncryptionDisabled\n");
1443 padapter->securitypriv.ndisencryptstatus =
1444 Ndis802_11EncryptionDisabled;
1445 padapter->securitypriv.PrivacyAlgrthm = _NO_PRIVACY_;
1446 padapter->securitypriv.XGrpPrivacy = _NO_PRIVACY_;
1447 padapter->securitypriv.AuthAlgrthm = 0; /* open system */
1448 authmode = Ndis802_11AuthModeOpen;
1449 padapter->securitypriv.ndisauthtype = authmode;
1456 keyindex_provided = 1;
1458 keyindex_provided = 0;
1459 key = padapter->securitypriv.PrivacyKeyIndex;
1461 /* set authentication mode */
1462 if (erq->flags & IW_ENCODE_OPEN) {
1463 printk(KERN_INFO "r8712u: r8711_wx_set_enc: "
1464 "IW_ENCODE_OPEN\n");
1465 padapter->securitypriv.ndisencryptstatus =
1466 Ndis802_11Encryption1Enabled;
1467 padapter->securitypriv.AuthAlgrthm = 0; /* open system */
1468 padapter->securitypriv.PrivacyAlgrthm = _NO_PRIVACY_;
1469 padapter->securitypriv.XGrpPrivacy = _NO_PRIVACY_;
1470 authmode = Ndis802_11AuthModeOpen;
1471 padapter->securitypriv.ndisauthtype = authmode;
1472 } else if (erq->flags & IW_ENCODE_RESTRICTED) {
1473 printk(KERN_INFO "r8712u: r8711_wx_set_enc: "
1474 "IW_ENCODE_RESTRICTED\n");
1475 padapter->securitypriv.ndisencryptstatus =
1476 Ndis802_11Encryption1Enabled;
1477 padapter->securitypriv.AuthAlgrthm = 1; /* shared system */
1478 padapter->securitypriv.PrivacyAlgrthm = _WEP40_;
1479 padapter->securitypriv.XGrpPrivacy = _WEP40_;
1480 authmode = Ndis802_11AuthModeShared;
1481 padapter->securitypriv.ndisauthtype = authmode;
1483 padapter->securitypriv.ndisencryptstatus =
1484 Ndis802_11Encryption1Enabled;
1485 padapter->securitypriv.AuthAlgrthm = 0; /* open system */
1486 padapter->securitypriv.PrivacyAlgrthm = _NO_PRIVACY_;
1487 padapter->securitypriv.XGrpPrivacy = _NO_PRIVACY_;
1488 authmode = Ndis802_11AuthModeOpen;
1489 padapter->securitypriv.ndisauthtype = authmode;
1492 if (erq->length > 0) {
1493 wep.KeyLength = erq->length <= 5 ? 5 : 13;
1494 wep.Length = wep.KeyLength +
1495 FIELD_OFFSET(struct NDIS_802_11_WEP, KeyMaterial);
1498 if (keyindex_provided == 1) { /* set key_id only, no given
1499 * KeyMaterial(erq->length==0).*/
1500 padapter->securitypriv.PrivacyKeyIndex = key;
1501 switch (padapter->securitypriv.DefKeylen[key]) {
1503 padapter->securitypriv.PrivacyAlgrthm =
1507 padapter->securitypriv.PrivacyAlgrthm =
1511 padapter->securitypriv.PrivacyAlgrthm =
1518 wep.KeyIndex |= 0x80000000; /* transmit key */
1519 memcpy(wep.KeyMaterial, keybuf, wep.KeyLength);
1520 if (r8712_set_802_11_add_wep(padapter, &wep) == _FAIL)
1525 static int r8711_wx_get_enc(struct net_device *dev,
1526 struct iw_request_info *info,
1527 union iwreq_data *wrqu, char *keybuf)
1530 struct _adapter *padapter = (struct _adapter *) _netdev_priv(dev);
1531 struct iw_point *erq = &(wrqu->encoding);
1532 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1534 if (check_fwstate(pmlmepriv, _FW_LINKED) == false) {
1535 if (!check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) {
1537 erq->flags |= IW_ENCODE_DISABLED;
1541 key = erq->flags & IW_ENCODE_INDEX;
1547 key = padapter->securitypriv.PrivacyKeyIndex;
1549 erq->flags = key + 1;
1550 switch (padapter->securitypriv.ndisencryptstatus) {
1551 case Ndis802_11EncryptionNotSupported:
1552 case Ndis802_11EncryptionDisabled:
1554 erq->flags |= IW_ENCODE_DISABLED;
1556 case Ndis802_11Encryption1Enabled:
1557 erq->length = padapter->securitypriv.DefKeylen[key];
1559 memcpy(keybuf, padapter->securitypriv.DefKey[
1560 key].skey, padapter->securitypriv.
1562 erq->flags |= IW_ENCODE_ENABLED;
1563 if (padapter->securitypriv.ndisauthtype ==
1564 Ndis802_11AuthModeOpen)
1565 erq->flags |= IW_ENCODE_OPEN;
1566 else if (padapter->securitypriv.ndisauthtype ==
1567 Ndis802_11AuthModeShared)
1568 erq->flags |= IW_ENCODE_RESTRICTED;
1571 erq->flags |= IW_ENCODE_DISABLED;
1574 case Ndis802_11Encryption2Enabled:
1575 case Ndis802_11Encryption3Enabled:
1577 erq->flags |= (IW_ENCODE_ENABLED | IW_ENCODE_OPEN |
1582 erq->flags |= IW_ENCODE_DISABLED;
1588 static int r8711_wx_get_power(struct net_device *dev,
1589 struct iw_request_info *info,
1590 union iwreq_data *wrqu, char *extra)
1592 wrqu->power.value = 0;
1593 wrqu->power.fixed = 0; /* no auto select */
1594 wrqu->power.disabled = 1;
1598 static int r871x_wx_set_gen_ie(struct net_device *dev,
1599 struct iw_request_info *info,
1600 union iwreq_data *wrqu, char *extra)
1602 struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
1604 return r871x_set_wpa_ie(padapter, extra, wrqu->data.length);
1607 static int r871x_wx_set_auth(struct net_device *dev,
1608 struct iw_request_info *info,
1609 union iwreq_data *wrqu, char *extra)
1611 struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
1612 struct iw_param *param = (struct iw_param *)&(wrqu->param);
1617 paramid = param->flags & IW_AUTH_INDEX;
1618 paramval = param->value;
1620 case IW_AUTH_WPA_VERSION:
1622 case IW_AUTH_CIPHER_PAIRWISE:
1624 case IW_AUTH_CIPHER_GROUP:
1626 case IW_AUTH_KEY_MGMT:
1628 * ??? does not use these parameters
1631 case IW_AUTH_TKIP_COUNTERMEASURES:
1633 /* wpa_supplicant is enabling tkip countermeasure. */
1634 padapter->securitypriv.btkip_countermeasure = true;
1636 /* wpa_supplicant is disabling tkip countermeasure. */
1637 padapter->securitypriv.btkip_countermeasure = false;
1640 case IW_AUTH_DROP_UNENCRYPTED:
1643 * wpa_supplicant calls set_wpa_enabled when the driver
1644 * is loaded and unloaded, regardless of if WPA is being
1645 * used. No other calls are made which can be used to
1646 * determine if encryption will be used or not prior to
1647 * association being expected. If encryption is not being
1648 * used, drop_unencrypted is set to false, else true -- we
1649 * can use this to determine if the CAP_PRIVACY_ON bit should
1652 if (padapter->securitypriv.ndisencryptstatus ==
1653 Ndis802_11Encryption1Enabled) {
1654 /* it means init value, or using wep,
1655 * ndisencryptstatus =
1656 * Ndis802_11Encryption1Enabled,
1657 * then it needn't reset it;
1663 padapter->securitypriv.ndisencryptstatus =
1664 Ndis802_11EncryptionDisabled;
1665 padapter->securitypriv.PrivacyAlgrthm =
1667 padapter->securitypriv.XGrpPrivacy =
1669 padapter->securitypriv.AuthAlgrthm = 0;
1670 padapter->securitypriv.ndisauthtype =
1671 Ndis802_11AuthModeOpen;
1674 case IW_AUTH_80211_AUTH_ALG:
1675 ret = wpa_set_auth_algs(dev, (u32)paramval);
1677 case IW_AUTH_WPA_ENABLED:
1679 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
1681 case IW_AUTH_PRIVACY_INVOKED:
1690 static int r871x_wx_set_enc_ext(struct net_device *dev,
1691 struct iw_request_info *info,
1692 union iwreq_data *wrqu, char *extra)
1694 struct iw_point *pencoding = &wrqu->encoding;
1695 struct iw_encode_ext *pext = (struct iw_encode_ext *)extra;
1696 struct ieee_param *param = NULL;
1701 param_len = sizeof(struct ieee_param) + pext->key_len;
1702 param = (struct ieee_param *)_malloc(param_len);
1705 memset(param, 0, param_len);
1706 param->cmd = IEEE_CMD_SET_ENCRYPTION;
1707 memset(param->sta_addr, 0xff, ETH_ALEN);
1708 switch (pext->alg) {
1709 case IW_ENCODE_ALG_NONE:
1712 case IW_ENCODE_ALG_WEP:
1715 case IW_ENCODE_ALG_TKIP:
1718 case IW_ENCODE_ALG_CCMP:
1724 strncpy((char *)param->u.crypt.alg, alg_name, IEEE_CRYPT_ALG_NAME_LEN);
1725 if (pext->ext_flags & IW_ENCODE_EXT_GROUP_KEY)
1726 param->u.crypt.set_tx = 0;
1727 if (pext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
1728 param->u.crypt.set_tx = 1;
1729 param->u.crypt.idx = (pencoding->flags & 0x00FF) - 1;
1730 if (pext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID)
1731 memcpy(param->u.crypt.seq, pext->rx_seq, 8);
1732 if (pext->key_len) {
1733 param->u.crypt.key_len = pext->key_len;
1734 memcpy(param + 1, pext + 1, pext->key_len);
1736 ret = wpa_set_encryption(dev, param, param_len);
1741 static int r871x_wx_get_nick(struct net_device *dev,
1742 struct iw_request_info *info,
1743 union iwreq_data *wrqu, char *extra)
1746 wrqu->data.length = 8;
1747 wrqu->data.flags = 1;
1748 memcpy(extra, "rtl_wifi", 8);
1753 static int r8711_wx_read32(struct net_device *dev,
1754 struct iw_request_info *info,
1755 union iwreq_data *wrqu, char *keybuf)
1757 struct _adapter *padapter = (struct _adapter *) _netdev_priv(dev);
1761 get_user(addr, (u32 __user *)wrqu->data.pointer);
1762 data32 = r8712_read32(padapter, addr);
1763 put_user(data32, (u32 __user *)wrqu->data.pointer);
1764 wrqu->data.length = (data32 & 0xffff0000) >> 16;
1765 wrqu->data.flags = data32 & 0xffff;
1766 get_user(addr, (u32 __user *)wrqu->data.pointer);
1770 static int r8711_wx_write32(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 = ((u32)wrqu->data.length<<16) | (u32)wrqu->data.flags ;
1780 r8712_write32(padapter, addr, data32);
1784 static int dummy(struct net_device *dev,
1785 struct iw_request_info *a,
1786 union iwreq_data *wrqu, char *b)
1791 static int r8711_drvext_hdl(struct net_device *dev,
1792 struct iw_request_info *info,
1793 union iwreq_data *wrqu, char *extra)
1798 static int r871x_mp_ioctl_hdl(struct net_device *dev,
1799 struct iw_request_info *info,
1800 union iwreq_data *wrqu, char *extra)
1802 struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
1803 struct iw_point *p = &wrqu->data;
1804 struct oid_par_priv oid_par;
1805 struct mp_ioctl_handler *phandler;
1806 struct mp_ioctl_param *poidparam;
1807 unsigned long BytesRead, BytesWritten, BytesNeeded;
1808 u8 *pparmbuf = NULL, bset;
1813 if ((!p->length) || (!p->pointer)) {
1815 goto _r871x_mp_ioctl_hdl_exit;
1817 bset = (u8)(p->flags & 0xFFFF);
1820 pparmbuf = (u8 *)_malloc(len);
1821 if (pparmbuf == NULL) {
1823 goto _r871x_mp_ioctl_hdl_exit;
1825 if (copy_from_user(pparmbuf, p->pointer, len)) {
1827 goto _r871x_mp_ioctl_hdl_exit;
1829 poidparam = (struct mp_ioctl_param *)pparmbuf;
1830 if (poidparam->subcode >= MAX_MP_IOCTL_SUBCODE) {
1832 goto _r871x_mp_ioctl_hdl_exit;
1834 phandler = mp_ioctl_hdl + poidparam->subcode;
1835 if ((phandler->paramsize != 0) &&
1836 (poidparam->len < phandler->paramsize)) {
1838 goto _r871x_mp_ioctl_hdl_exit;
1840 if (phandler->oid == 0 && phandler->handler)
1841 status = phandler->handler(&oid_par);
1842 else if (phandler->handler) {
1843 oid_par.adapter_context = padapter;
1844 oid_par.oid = phandler->oid;
1845 oid_par.information_buf = poidparam->data;
1846 oid_par.information_buf_len = poidparam->len;
1851 oid_par.bytes_rw = &BytesRead;
1852 oid_par.bytes_needed = &BytesNeeded;
1853 oid_par.type_of_oid = SET_OID;
1855 oid_par.bytes_rw = &BytesWritten;
1856 oid_par.bytes_needed = &BytesNeeded;
1857 oid_par.type_of_oid = QUERY_OID;
1859 status = phandler->handler(&oid_par);
1860 /* todo:check status, BytesNeeded, etc. */
1862 printk(KERN_INFO "r8712u: r871x_mp_ioctl_hdl(): err!,"
1863 " subcode=%d, oid=%d, handler=%p\n",
1864 poidparam->subcode, phandler->oid, phandler->handler);
1866 goto _r871x_mp_ioctl_hdl_exit;
1868 if (bset == 0x00) { /* query info */
1869 if (copy_to_user(p->pointer, pparmbuf, len))
1874 goto _r871x_mp_ioctl_hdl_exit;
1876 _r871x_mp_ioctl_hdl_exit:
1881 static int r871x_get_ap_info(struct net_device *dev,
1882 struct iw_request_info *info,
1883 union iwreq_data *wrqu, char *extra)
1885 struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
1886 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1887 struct __queue *queue = &pmlmepriv->scanned_queue;
1888 struct iw_point *pdata = &wrqu->data;
1889 struct wlan_network *pnetwork = NULL;
1890 u32 cnt = 0, wpa_ielen;
1892 struct list_head *plist, *phead;
1893 unsigned char *pbuf;
1897 if (padapter->bDriverStopped || (pdata == NULL))
1899 while (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING)) {
1906 if (pdata->length >= 32) {
1907 if (copy_from_user(data, pdata->pointer, 32))
1911 spin_lock_irqsave(&(pmlmepriv->scanned_queue.lock), irqL);
1912 phead = get_list_head(queue);
1913 plist = get_next(phead);
1915 if (end_of_queue_search(phead, plist) == true)
1917 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
1918 if (hwaddr_aton_i(data, bssid)) {
1919 printk(KERN_INFO "r8712u: Invalid BSSID '%s'.\n",
1921 spin_unlock_irqrestore(&(pmlmepriv->scanned_queue.lock),
1925 printk(KERN_INFO "r8712u: BSSID:%pM\n", bssid);
1926 if (!memcmp(bssid, pnetwork->network.MacAddress, ETH_ALEN)) {
1927 /* BSSID match, then check if supporting wpa/wpa2 */
1928 pbuf = r8712_get_wpa_ie(&pnetwork->network.IEs[12],
1929 &wpa_ielen, pnetwork->network.IELength-12);
1930 if (pbuf && (wpa_ielen > 0)) {
1934 pbuf = r8712_get_wpa2_ie(&pnetwork->network.IEs[12],
1935 &wpa_ielen, pnetwork->network.IELength-12);
1936 if (pbuf && (wpa_ielen > 0)) {
1941 plist = get_next(plist);
1943 spin_unlock_irqrestore(&(pmlmepriv->scanned_queue.lock), irqL);
1944 if (pdata->length >= 34) {
1945 if (copy_to_user((u8 __user *)pdata->pointer + 32,
1946 (u8 *)&pdata->flags, 1))
1952 static int r871x_set_pid(struct net_device *dev,
1953 struct iw_request_info *info,
1954 union iwreq_data *wrqu, char *extra)
1956 struct _adapter *padapter = (struct _adapter *) _netdev_priv(dev);
1957 struct iw_point *pdata = &wrqu->data;
1959 if ((padapter->bDriverStopped) || (pdata == NULL))
1961 if (copy_from_user(&padapter->pid, pdata->pointer, sizeof(int)))
1966 static int r871x_wps_start(struct net_device *dev,
1967 struct iw_request_info *info,
1968 union iwreq_data *wrqu, char *extra)
1970 struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
1971 struct iw_point *pdata = &wrqu->data;
1972 u32 u32wps_start = 0;
1974 if (copy_from_user((void *)&u32wps_start, pdata->pointer, 4))
1976 if ((padapter->bDriverStopped) || (pdata == NULL))
1978 if (u32wps_start == 0)
1979 u32wps_start = *extra;
1980 if (u32wps_start == 1) /* WPS Start */
1981 padapter->ledpriv.LedControlHandler(padapter,
1983 else if (u32wps_start == 2) /* WPS Stop because of wps success */
1984 padapter->ledpriv.LedControlHandler(padapter,
1986 else if (u32wps_start == 3) /* WPS Stop because of wps fail */
1987 padapter->ledpriv.LedControlHandler(padapter,
1988 LED_CTL_STOP_WPS_FAIL);
1992 static int wpa_set_param(struct net_device *dev, u8 name, u32 value)
1994 struct _adapter *padapter = (struct _adapter *) _netdev_priv(dev);
1997 case IEEE_PARAM_WPA_ENABLED:
1998 padapter->securitypriv.AuthAlgrthm = 2; /* 802.1x */
1999 switch ((value)&0xff) {
2001 padapter->securitypriv.ndisauthtype =
2002 Ndis802_11AuthModeWPAPSK; /* WPA_PSK */
2003 padapter->securitypriv.ndisencryptstatus =
2004 Ndis802_11Encryption2Enabled;
2007 padapter->securitypriv.ndisauthtype =
2008 Ndis802_11AuthModeWPA2PSK; /* WPA2_PSK */
2009 padapter->securitypriv.ndisencryptstatus =
2010 Ndis802_11Encryption3Enabled;
2014 case IEEE_PARAM_TKIP_COUNTERMEASURES:
2016 case IEEE_PARAM_DROP_UNENCRYPTED:
2019 * wpa_supplicant calls set_wpa_enabled when the driver
2020 * is loaded and unloaded, regardless of if WPA is being
2021 * used. No other calls are made which can be used to
2022 * determine if encryption will be used or not prior to
2023 * association being expected. If encryption is not being
2024 * used, drop_unencrypted is set to false, else true -- we
2025 * can use this to determine if the CAP_PRIVACY_ON bit should
2029 case IEEE_PARAM_PRIVACY_INVOKED:
2031 case IEEE_PARAM_AUTH_ALGS:
2032 return wpa_set_auth_algs(dev, value);
2034 case IEEE_PARAM_IEEE_802_1X:
2036 case IEEE_PARAM_WPAX_SELECT:
2037 /* added for WPA2 mixed mode */
2045 static int wpa_mlme(struct net_device *dev, u32 command, u32 reason)
2047 struct _adapter *padapter = (struct _adapter *) _netdev_priv(dev);
2050 case IEEE_MLME_STA_DEAUTH:
2051 if (!r8712_set_802_11_disassociate(padapter))
2054 case IEEE_MLME_STA_DISASSOC:
2055 if (!r8712_set_802_11_disassociate(padapter))
2064 static int wpa_supplicant_ioctl(struct net_device *dev, struct iw_point *p)
2066 struct ieee_param *param;
2068 struct _adapter *padapter = (struct _adapter *) _netdev_priv(dev);
2070 if (p->length < sizeof(struct ieee_param) || !p->pointer)
2072 param = (struct ieee_param *)_malloc(p->length);
2075 if (copy_from_user(param, p->pointer, p->length))
2078 switch (param->cmd) {
2079 case IEEE_CMD_SET_WPA_PARAM:
2080 ret = wpa_set_param(dev, param->u.wpa_param.name,
2081 param->u.wpa_param.value);
2083 case IEEE_CMD_SET_WPA_IE:
2084 ret = r871x_set_wpa_ie(padapter, (char *)param->u.wpa_ie.data,
2085 (u16)param->u.wpa_ie.len);
2087 case IEEE_CMD_SET_ENCRYPTION:
2088 ret = wpa_set_encryption(dev, param, p->length);
2091 ret = wpa_mlme(dev, param->u.mlme.command,
2092 param->u.mlme.reason_code);
2098 if (ret == 0 && copy_to_user(p->pointer, param, p->length))
2104 /* based on "driver_ipw" and for hostapd */
2105 int r871x_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
2107 struct iwreq *wrq = (struct iwreq *)rq;
2110 case RTL_IOCTL_WPA_SUPPLICANT:
2111 return wpa_supplicant_ioctl(dev, &wrq->u.data);
2118 static iw_handler r8711_handlers[] = {
2119 NULL, /* SIOCSIWCOMMIT */
2120 r8711_wx_get_name, /* SIOCGIWNAME */
2121 dummy, /* SIOCSIWNWID */
2122 dummy, /* SIOCGIWNWID */
2123 r8711_wx_set_freq, /* SIOCSIWFREQ */
2124 r8711_wx_get_freq, /* SIOCGIWFREQ */
2125 r8711_wx_set_mode, /* SIOCSIWMODE */
2126 r8711_wx_get_mode, /* SIOCGIWMODE */
2127 dummy, /* SIOCSIWSENS */
2128 r8711_wx_get_sens, /* SIOCGIWSENS */
2129 NULL, /* SIOCSIWRANGE */
2130 r8711_wx_get_range, /* SIOCGIWRANGE */
2131 r871x_wx_set_priv, /* SIOCSIWPRIV */
2132 NULL, /* SIOCGIWPRIV */
2133 NULL, /* SIOCSIWSTATS */
2134 NULL, /* SIOCGIWSTATS */
2135 dummy, /* SIOCSIWSPY */
2136 dummy, /* SIOCGIWSPY */
2137 NULL, /* SIOCGIWTHRSPY */
2138 NULL, /* SIOCWIWTHRSPY */
2139 r8711_wx_set_wap, /* SIOCSIWAP */
2140 r8711_wx_get_wap, /* SIOCGIWAP */
2141 r871x_wx_set_mlme, /* request MLME operation;
2142 * uses struct iw_mlme */
2143 dummy, /* SIOCGIWAPLIST -- deprecated */
2144 r8711_wx_set_scan, /* SIOCSIWSCAN */
2145 r8711_wx_get_scan, /* SIOCGIWSCAN */
2146 r8711_wx_set_essid, /* SIOCSIWESSID */
2147 r8711_wx_get_essid, /* SIOCGIWESSID */
2148 dummy, /* SIOCSIWNICKN */
2149 r871x_wx_get_nick, /* SIOCGIWNICKN */
2150 NULL, /* -- hole -- */
2151 NULL, /* -- hole -- */
2152 r8711_wx_set_rate, /* SIOCSIWRATE */
2153 r8711_wx_get_rate, /* SIOCGIWRATE */
2154 dummy, /* SIOCSIWRTS */
2155 r8711_wx_get_rts, /* SIOCGIWRTS */
2156 r8711_wx_set_frag, /* SIOCSIWFRAG */
2157 r8711_wx_get_frag, /* SIOCGIWFRAG */
2158 dummy, /* SIOCSIWTXPOW */
2159 dummy, /* SIOCGIWTXPOW */
2160 dummy, /* SIOCSIWRETRY */
2161 r8711_wx_get_retry, /* SIOCGIWRETRY */
2162 r8711_wx_set_enc, /* SIOCSIWENCODE */
2163 r8711_wx_get_enc, /* SIOCGIWENCODE */
2164 dummy, /* SIOCSIWPOWER */
2165 r8711_wx_get_power, /* SIOCGIWPOWER */
2166 NULL, /*---hole---*/
2167 NULL, /*---hole---*/
2168 r871x_wx_set_gen_ie, /* SIOCSIWGENIE */
2169 NULL, /* SIOCGIWGENIE */
2170 r871x_wx_set_auth, /* SIOCSIWAUTH */
2171 NULL, /* SIOCGIWAUTH */
2172 r871x_wx_set_enc_ext, /* SIOCSIWENCODEEXT */
2173 NULL, /* SIOCGIWENCODEEXT */
2174 r871x_wx_set_pmkid, /* SIOCSIWPMKSA */
2175 NULL, /*---hole---*/
2178 static const struct iw_priv_args r8711_private_args[] = {
2180 SIOCIWFIRSTPRIV + 0x0,
2181 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "read32"
2184 SIOCIWFIRSTPRIV + 0x1,
2185 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "write32"
2188 SIOCIWFIRSTPRIV + 0x2, 0, 0, "driver_ext"
2191 SIOCIWFIRSTPRIV + 0x3, 0, 0, "mp_ioctl"
2194 SIOCIWFIRSTPRIV + 0x4,
2195 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "apinfo"
2198 SIOCIWFIRSTPRIV + 0x5,
2199 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setpid"
2202 SIOCIWFIRSTPRIV + 0x6,
2203 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wps_start"
2207 static iw_handler r8711_private_handler[] = {
2212 r871x_get_ap_info, /*for MM DTV platform*/
2217 static struct iw_statistics *r871x_get_wireless_stats(struct net_device *dev)
2219 struct _adapter *padapter = (struct _adapter *) _netdev_priv(dev);
2220 struct iw_statistics *piwstats = &padapter->iwstats;
2225 if (check_fwstate(&padapter->mlmepriv, _FW_LINKED) != true) {
2226 piwstats->qual.qual = 0;
2227 piwstats->qual.level = 0;
2228 piwstats->qual.noise = 0;
2230 /* show percentage, we need transfer dbm to orignal value. */
2231 tmp_level = padapter->recvpriv.fw_rssi;
2232 tmp_qual = padapter->recvpriv.signal;
2233 tmp_noise = padapter->recvpriv.noise;
2234 piwstats->qual.level = tmp_level;
2235 piwstats->qual.qual = tmp_qual;
2236 piwstats->qual.noise = tmp_noise;
2238 piwstats->qual.updated = IW_QUAL_ALL_UPDATED;
2239 return &padapter->iwstats;
2242 struct iw_handler_def r871x_handlers_def = {
2243 .standard = r8711_handlers,
2244 .num_standard = sizeof(r8711_handlers) / sizeof(iw_handler),
2245 .private = r8711_private_handler,
2246 .private_args = (struct iw_priv_args *)r8711_private_args,
2247 .num_private = sizeof(r8711_private_handler) / sizeof(iw_handler),
2248 .num_private_args = sizeof(r8711_private_args) /
2249 sizeof(struct iw_priv_args),
2250 .get_wireless_stats = r871x_get_wireless_stats,