1 // SPDX-License-Identifier: GPL-2.0 2 /****************************************************************************** 3 * rtl871x_ioctl_linux.c 4 * 5 * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. 6 * Linux device driver for RTL8192SU 7 * 8 * Modifications for inclusion into the Linux staging tree are 9 * Copyright(c) 2010 Larry Finger. All rights reserved. 10 * 11 * Contact information: 12 * WLAN FAE <wlanfae@realtek.com> 13 * Larry Finger <Larry.Finger@lwfinger.net> 14 * 15 ******************************************************************************/ 16 17 #define _RTL871X_IOCTL_LINUX_C_ 18 #define _RTL871X_MP_IOCTL_C_ 19 20 #include "osdep_service.h" 21 #include "drv_types.h" 22 #include "wlan_bssdef.h" 23 #include "rtl871x_debug.h" 24 #include "wifi.h" 25 #include "rtl871x_mlme.h" 26 #include "rtl871x_ioctl.h" 27 #include "rtl871x_ioctl_set.h" 28 #include "rtl871x_mp_ioctl.h" 29 #include "mlme_osdep.h" 30 #include <linux/wireless.h> 31 #include <linux/module.h> 32 #include <linux/kernel.h> 33 #include <linux/io.h> 34 #include <linux/semaphore.h> 35 #include <net/iw_handler.h> 36 #include <linux/if_arp.h> 37 #include <linux/etherdevice.h> 38 39 40 #define RTL_IOCTL_WPA_SUPPLICANT (SIOCIWFIRSTPRIV + 0x1E) 41 42 #define SCAN_ITEM_SIZE 768 43 #define MAX_CUSTOM_LEN 64 44 #define RATE_COUNT 4 45 46 47 static const u32 rtl8180_rates[] = {1000000, 2000000, 5500000, 11000000, 48 6000000, 9000000, 12000000, 18000000, 49 24000000, 36000000, 48000000, 54000000}; 50 51 static const long ieee80211_wlan_frequencies[] = { 52 2412, 2417, 2422, 2427, 53 2432, 2437, 2442, 2447, 54 2452, 2457, 2462, 2467, 55 2472, 2484 56 }; 57 58 void r8712_indicate_wx_assoc_event(struct _adapter *padapter) 59 { 60 union iwreq_data wrqu; 61 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 62 63 wrqu.ap_addr.sa_family = ARPHRD_ETHER; 64 memcpy(wrqu.ap_addr.sa_data, pmlmepriv->cur_network.network.MacAddress, 65 ETH_ALEN); 66 wireless_send_event(padapter->pnetdev, SIOCGIWAP, &wrqu, NULL); 67 } 68 69 void r8712_indicate_wx_disassoc_event(struct _adapter *padapter) 70 { 71 union iwreq_data wrqu; 72 73 wrqu.ap_addr.sa_family = ARPHRD_ETHER; 74 eth_zero_addr(wrqu.ap_addr.sa_data); 75 wireless_send_event(padapter->pnetdev, SIOCGIWAP, &wrqu, NULL); 76 } 77 78 static inline void handle_pairwise_key(struct sta_info *psta, 79 struct ieee_param *param, 80 struct _adapter *padapter) 81 { 82 /* pairwise key */ 83 memcpy(psta->x_UncstKey.skey, param->u.crypt.key, 84 (param->u.crypt. key_len > 16 ? 16 : param->u.crypt.key_len)); 85 if (strcmp(param->u.crypt.alg, "TKIP") == 0) { /* set mic key */ 86 memcpy(psta->tkiptxmickey. skey, 87 &(param->u.crypt.key[16]), 8); 88 memcpy(psta->tkiprxmickey. skey, 89 &(param->u.crypt.key[24]), 8); 90 padapter->securitypriv. busetkipkey = false; 91 mod_timer(&padapter->securitypriv.tkip_timer, 92 jiffies + msecs_to_jiffies(50)); 93 } 94 r8712_setstakey_cmd(padapter, (unsigned char *)psta, true); 95 } 96 97 static inline void handle_group_key(struct ieee_param *param, 98 struct _adapter *padapter) 99 { 100 union Keytype *gk = padapter->securitypriv.XGrpKey; 101 union Keytype *gtk = padapter->securitypriv.XGrptxmickey; 102 union Keytype *grk = padapter->securitypriv.XGrprxmickey; 103 104 if (param->u.crypt.idx > 0 && 105 param->u.crypt.idx < 3) { 106 /* group key idx is 1 or 2 */ 107 memcpy(gk[param->u.crypt.idx - 1].skey, 108 param->u.crypt.key, 109 (param->u.crypt.key_len > 16 ? 16 : 110 param->u.crypt.key_len)); 111 memcpy(gtk[param->u.crypt.idx - 1].skey, 112 ¶m->u.crypt.key[16], 8); 113 memcpy(grk[param->u.crypt.idx - 1].skey, 114 ¶m->u.crypt.key[24], 8); 115 padapter->securitypriv.binstallGrpkey = true; 116 r8712_set_key(padapter, &padapter->securitypriv, 117 param->u.crypt.idx); 118 if (padapter->registrypriv.power_mgnt > PS_MODE_ACTIVE) { 119 if (padapter->registrypriv.power_mgnt != 120 padapter->pwrctrlpriv.pwr_mode) 121 mod_timer(&padapter->mlmepriv.dhcp_timer, 122 jiffies + msecs_to_jiffies(60000)); 123 } 124 } 125 } 126 127 static noinline_for_stack char *translate_scan(struct _adapter *padapter, 128 struct iw_request_info *info, 129 struct wlan_network *pnetwork, 130 char *start, char *stop) 131 { 132 struct iw_event iwe; 133 struct ieee80211_ht_cap *pht_capie; 134 char *current_val; 135 s8 *p; 136 u32 i = 0, ht_ielen = 0; 137 u16 cap, ht_cap = false, mcs_rate; 138 u8 rssi; 139 140 if ((pnetwork->network.Configuration.DSConfig < 1) || 141 (pnetwork->network.Configuration.DSConfig > 14)) { 142 if (pnetwork->network.Configuration.DSConfig < 1) 143 pnetwork->network.Configuration.DSConfig = 1; 144 else 145 pnetwork->network.Configuration.DSConfig = 14; 146 } 147 /* AP MAC address */ 148 iwe.cmd = SIOCGIWAP; 149 iwe.u.ap_addr.sa_family = ARPHRD_ETHER; 150 ether_addr_copy(iwe.u.ap_addr.sa_data, pnetwork->network.MacAddress); 151 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_ADDR_LEN); 152 /* Add the ESSID */ 153 iwe.cmd = SIOCGIWESSID; 154 iwe.u.data.flags = 1; 155 iwe.u.data.length = min_t(u32, pnetwork->network.Ssid.SsidLength, 32); 156 start = iwe_stream_add_point(info, start, stop, &iwe, 157 pnetwork->network.Ssid.Ssid); 158 /* parsing HT_CAP_IE */ 159 p = r8712_get_ie(&pnetwork->network.IEs[12], _HT_CAPABILITY_IE_, 160 &ht_ielen, pnetwork->network.IELength - 12); 161 if (p && ht_ielen > 0) { 162 ht_cap = true; 163 pht_capie = (struct ieee80211_ht_cap *)(p + 2); 164 memcpy(&mcs_rate, pht_capie->supp_mcs_set, 2); 165 } 166 /* Add the protocol name */ 167 iwe.cmd = SIOCGIWNAME; 168 if (r8712_is_cckratesonly_included(pnetwork->network.rates)) { 169 if (ht_cap) 170 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bn"); 171 else 172 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11b"); 173 } else if (r8712_is_cckrates_included(pnetwork->network.rates)) { 174 if (ht_cap) 175 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bgn"); 176 else 177 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bg"); 178 } else { 179 if (ht_cap) 180 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11gn"); 181 else 182 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11g"); 183 } 184 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_CHAR_LEN); 185 /* Add mode */ 186 iwe.cmd = SIOCGIWMODE; 187 memcpy((u8 *)&cap, r8712_get_capability_from_ie(pnetwork->network.IEs), 188 2); 189 le16_to_cpus(&cap); 190 if (cap & (WLAN_CAPABILITY_IBSS | WLAN_CAPABILITY_BSS)) { 191 if (cap & WLAN_CAPABILITY_BSS) 192 iwe.u.mode = (u32)IW_MODE_MASTER; 193 else 194 iwe.u.mode = (u32)IW_MODE_ADHOC; 195 start = iwe_stream_add_event(info, start, stop, &iwe, 196 IW_EV_UINT_LEN); 197 } 198 /* Add frequency/channel */ 199 iwe.cmd = SIOCGIWFREQ; 200 { 201 /* check legal index */ 202 u8 dsconfig = pnetwork->network.Configuration.DSConfig; 203 204 if (dsconfig >= 1 && dsconfig <= sizeof( 205 ieee80211_wlan_frequencies) / sizeof(long)) 206 iwe.u.freq.m = 207 (s32)(ieee80211_wlan_frequencies 208 [dsconfig - 1] * 100000); 209 else 210 iwe.u.freq.m = 0; 211 } 212 iwe.u.freq.e = (s16)1; 213 iwe.u.freq.i = (u8)pnetwork->network.Configuration.DSConfig; 214 start = iwe_stream_add_event(info, start, stop, &iwe, 215 IW_EV_FREQ_LEN); 216 /* Add encryption capability */ 217 iwe.cmd = SIOCGIWENCODE; 218 if (cap & WLAN_CAPABILITY_PRIVACY) 219 iwe.u.data.flags = (u16)(IW_ENCODE_ENABLED | 220 IW_ENCODE_NOKEY); 221 else 222 iwe.u.data.flags = (u16)(IW_ENCODE_DISABLED); 223 iwe.u.data.length = (u16)0; 224 start = iwe_stream_add_point(info, start, stop, &iwe, 225 pnetwork->network.Ssid.Ssid); 226 /*Add basic and extended rates */ 227 current_val = start + iwe_stream_lcp_len(info); 228 iwe.cmd = SIOCGIWRATE; 229 iwe.u.bitrate.fixed = 0; 230 iwe.u.bitrate.disabled = 0; 231 iwe.u.bitrate.value = 0; 232 i = 0; 233 while (pnetwork->network.rates[i] != 0) { 234 /* Bit rate given in 500 kb/s units */ 235 iwe.u.bitrate.value = (pnetwork->network.rates[i++] & 236 0x7F) * 500000; 237 current_val = iwe_stream_add_value(info, start, current_val, 238 stop, &iwe, IW_EV_PARAM_LEN); 239 } 240 /* Check if we added any event */ 241 if ((current_val - start) > iwe_stream_lcp_len(info)) 242 start = current_val; 243 /* parsing WPA/WPA2 IE */ 244 { 245 u8 buf[MAX_WPA_IE_LEN]; 246 u8 wpa_ie[255], rsn_ie[255]; 247 u16 wpa_len = 0, rsn_len = 0; 248 int n; 249 250 r8712_get_sec_ie(pnetwork->network.IEs, 251 pnetwork->network.IELength, rsn_ie, &rsn_len, 252 wpa_ie, &wpa_len); 253 if (wpa_len > 0) { 254 memset(buf, 0, MAX_WPA_IE_LEN); 255 n = sprintf(buf, "wpa_ie="); 256 for (i = 0; i < wpa_len; i++) { 257 n += snprintf(buf + n, MAX_WPA_IE_LEN - n, 258 "%02x", wpa_ie[i]); 259 if (n >= MAX_WPA_IE_LEN) 260 break; 261 } 262 memset(&iwe, 0, sizeof(iwe)); 263 iwe.cmd = IWEVCUSTOM; 264 iwe.u.data.length = (u16)strlen(buf); 265 start = iwe_stream_add_point(info, start, stop, 266 &iwe, buf); 267 memset(&iwe, 0, sizeof(iwe)); 268 iwe.cmd = IWEVGENIE; 269 iwe.u.data.length = (u16)wpa_len; 270 start = iwe_stream_add_point(info, start, stop, 271 &iwe, wpa_ie); 272 } 273 if (rsn_len > 0) { 274 memset(buf, 0, MAX_WPA_IE_LEN); 275 n = sprintf(buf, "rsn_ie="); 276 for (i = 0; i < rsn_len; i++) { 277 n += snprintf(buf + n, MAX_WPA_IE_LEN - n, 278 "%02x", rsn_ie[i]); 279 if (n >= MAX_WPA_IE_LEN) 280 break; 281 } 282 memset(&iwe, 0, sizeof(iwe)); 283 iwe.cmd = IWEVCUSTOM; 284 iwe.u.data.length = strlen(buf); 285 start = iwe_stream_add_point(info, start, stop, 286 &iwe, buf); 287 memset(&iwe, 0, sizeof(iwe)); 288 iwe.cmd = IWEVGENIE; 289 iwe.u.data.length = rsn_len; 290 start = iwe_stream_add_point(info, start, stop, &iwe, 291 rsn_ie); 292 } 293 } 294 295 { /* parsing WPS IE */ 296 u8 wps_ie[512]; 297 uint wps_ielen; 298 299 if (r8712_get_wps_ie(pnetwork->network.IEs, 300 pnetwork->network.IELength, 301 wps_ie, &wps_ielen)) { 302 if (wps_ielen > 2) { 303 iwe.cmd = IWEVGENIE; 304 iwe.u.data.length = (u16)wps_ielen; 305 start = iwe_stream_add_point(info, start, stop, 306 &iwe, wps_ie); 307 } 308 } 309 } 310 /* Add quality statistics */ 311 iwe.cmd = IWEVQUAL; 312 rssi = r8712_signal_scale_mapping(pnetwork->network.Rssi); 313 /* we only update signal_level (signal strength) that is rssi. */ 314 iwe.u.qual.updated = (u8)(IW_QUAL_QUAL_INVALID | IW_QUAL_LEVEL_UPDATED | 315 IW_QUAL_NOISE_INVALID); 316 iwe.u.qual.level = rssi; /* signal strength */ 317 iwe.u.qual.qual = 0; /* signal quality */ 318 iwe.u.qual.noise = 0; /* noise level */ 319 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_QUAL_LEN); 320 /* how to translate rssi to ?% */ 321 return start; 322 } 323 324 static int wpa_set_auth_algs(struct net_device *dev, u32 value) 325 { 326 struct _adapter *padapter = netdev_priv(dev); 327 int ret = 0; 328 329 if ((value & AUTH_ALG_SHARED_KEY) && (value & AUTH_ALG_OPEN_SYSTEM)) { 330 padapter->securitypriv.ndisencryptstatus = 331 Ndis802_11Encryption1Enabled; 332 padapter->securitypriv.ndisauthtype = 333 Ndis802_11AuthModeAutoSwitch; 334 padapter->securitypriv.AuthAlgrthm = 3; 335 } else if (value & AUTH_ALG_SHARED_KEY) { 336 padapter->securitypriv.ndisencryptstatus = 337 Ndis802_11Encryption1Enabled; 338 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeShared; 339 padapter->securitypriv.AuthAlgrthm = 1; 340 } else if (value & AUTH_ALG_OPEN_SYSTEM) { 341 if (padapter->securitypriv.ndisauthtype < 342 Ndis802_11AuthModeWPAPSK) { 343 padapter->securitypriv.ndisauthtype = 344 Ndis802_11AuthModeOpen; 345 padapter->securitypriv.AuthAlgrthm = 0; 346 } 347 } else { 348 ret = -EINVAL; 349 } 350 return ret; 351 } 352 353 static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param, 354 u32 param_len) 355 { 356 int ret = 0; 357 u32 wep_key_idx, wep_key_len = 0; 358 struct NDIS_802_11_WEP *pwep = NULL; 359 struct _adapter *padapter = netdev_priv(dev); 360 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 361 struct security_priv *psecuritypriv = &padapter->securitypriv; 362 363 param->u.crypt.err = 0; 364 param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0'; 365 if (param_len != (u32)((u8 *) param->u.crypt.key - (u8 *)param) + 366 param->u.crypt.key_len) 367 return -EINVAL; 368 if (!is_broadcast_ether_addr(param->sta_addr)) 369 return -EINVAL; 370 371 if (param->u.crypt.idx >= WEP_KEYS) { 372 /* for large key indices, set the default (0) */ 373 param->u.crypt.idx = 0; 374 } 375 if (strcmp(param->u.crypt.alg, "WEP") == 0) { 376 netdev_info(dev, "r8712u: %s: crypt.alg = WEP\n", __func__); 377 padapter->securitypriv.ndisencryptstatus = 378 Ndis802_11Encryption1Enabled; 379 padapter->securitypriv.PrivacyAlgrthm = _WEP40_; 380 padapter->securitypriv.XGrpPrivacy = _WEP40_; 381 wep_key_idx = param->u.crypt.idx; 382 wep_key_len = param->u.crypt.key_len; 383 if (wep_key_idx >= WEP_KEYS) 384 wep_key_idx = 0; 385 if (wep_key_len <= 0) 386 return -EINVAL; 387 388 wep_key_len = wep_key_len <= 5 ? 5 : 13; 389 pwep = kzalloc(sizeof(*pwep), GFP_ATOMIC); 390 if (!pwep) 391 return -ENOMEM; 392 pwep->KeyLength = wep_key_len; 393 pwep->Length = wep_key_len + 394 FIELD_OFFSET(struct NDIS_802_11_WEP, KeyMaterial); 395 if (wep_key_len == 13) { 396 padapter->securitypriv.PrivacyAlgrthm = _WEP104_; 397 padapter->securitypriv.XGrpPrivacy = _WEP104_; 398 } 399 pwep->KeyIndex = wep_key_idx; 400 pwep->KeyIndex |= 0x80000000; 401 memcpy(pwep->KeyMaterial, param->u.crypt.key, pwep->KeyLength); 402 if (param->u.crypt.set_tx) { 403 if (r8712_set_802_11_add_wep(padapter, pwep) == 404 (u8)_FAIL) 405 ret = -EOPNOTSUPP; 406 } else { 407 /* don't update "psecuritypriv->PrivacyAlgrthm" and 408 * "psecuritypriv->PrivacyKeyIndex=keyid", but can 409 * r8712_set_key to fw/cam 410 */ 411 if (wep_key_idx >= WEP_KEYS) { 412 ret = -EOPNOTSUPP; 413 goto exit; 414 } 415 memcpy(&psecuritypriv->DefKey[wep_key_idx].skey[0], 416 pwep->KeyMaterial, 417 pwep->KeyLength); 418 psecuritypriv->DefKeylen[wep_key_idx] = 419 pwep->KeyLength; 420 r8712_set_key(padapter, psecuritypriv, wep_key_idx); 421 } 422 goto exit; 423 } 424 if (padapter->securitypriv.AuthAlgrthm == 2) { /* 802_1x */ 425 struct sta_info *psta, *pbcmc_sta; 426 struct sta_priv *pstapriv = &padapter->stapriv; 427 struct security_priv *spriv = &padapter->securitypriv; 428 429 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE | 430 WIFI_MP_STATE)) { /* sta mode */ 431 psta = r8712_get_stainfo(pstapriv, 432 get_bssid(pmlmepriv)); 433 if (psta) { 434 psta->ieee8021x_blocked = false; 435 if (spriv->ndisencryptstatus == 436 Ndis802_11Encryption2Enabled || 437 spriv->ndisencryptstatus == 438 Ndis802_11Encryption3Enabled) 439 psta->XPrivacy = spriv->PrivacyAlgrthm; 440 if (param->u.crypt.set_tx == 1) 441 handle_pairwise_key(psta, param, 442 padapter); 443 else /* group key */ 444 handle_group_key(param, padapter); 445 } 446 pbcmc_sta = r8712_get_bcmc_stainfo(padapter); 447 if (pbcmc_sta) { 448 pbcmc_sta->ieee8021x_blocked = false; 449 if (spriv->ndisencryptstatus == 450 Ndis802_11Encryption2Enabled || 451 spriv->ndisencryptstatus == 452 Ndis802_11Encryption3Enabled) 453 pbcmc_sta->XPrivacy = 454 spriv->PrivacyAlgrthm; 455 } 456 } 457 } 458 exit: 459 kfree(pwep); 460 return ret; 461 } 462 463 static int r871x_set_wpa_ie(struct _adapter *padapter, char *pie, 464 unsigned short ielen) 465 { 466 u8 *buf = NULL; 467 int group_cipher = 0, pairwise_cipher = 0; 468 int ret = 0; 469 470 if ((ielen > MAX_WPA_IE_LEN) || (pie == NULL)) 471 return -EINVAL; 472 if (ielen) { 473 buf = kmemdup(pie, ielen, GFP_ATOMIC); 474 if (buf == NULL) 475 return -ENOMEM; 476 if (ielen < RSN_HEADER_LEN) { 477 ret = -EINVAL; 478 goto exit; 479 } 480 if (r8712_parse_wpa_ie(buf, ielen, &group_cipher, 481 &pairwise_cipher) == _SUCCESS) { 482 padapter->securitypriv.AuthAlgrthm = 2; 483 padapter->securitypriv.ndisauthtype = 484 Ndis802_11AuthModeWPAPSK; 485 } 486 if (r8712_parse_wpa2_ie(buf, ielen, &group_cipher, 487 &pairwise_cipher) == _SUCCESS) { 488 padapter->securitypriv.AuthAlgrthm = 2; 489 padapter->securitypriv.ndisauthtype = 490 Ndis802_11AuthModeWPA2PSK; 491 } 492 switch (group_cipher) { 493 case WPA_CIPHER_NONE: 494 padapter->securitypriv.XGrpPrivacy = 495 _NO_PRIVACY_; 496 padapter->securitypriv.ndisencryptstatus = 497 Ndis802_11EncryptionDisabled; 498 break; 499 case WPA_CIPHER_WEP40: 500 padapter->securitypriv.XGrpPrivacy = _WEP40_; 501 padapter->securitypriv.ndisencryptstatus = 502 Ndis802_11Encryption1Enabled; 503 break; 504 case WPA_CIPHER_TKIP: 505 padapter->securitypriv.XGrpPrivacy = _TKIP_; 506 padapter->securitypriv.ndisencryptstatus = 507 Ndis802_11Encryption2Enabled; 508 break; 509 case WPA_CIPHER_CCMP: 510 padapter->securitypriv.XGrpPrivacy = _AES_; 511 padapter->securitypriv.ndisencryptstatus = 512 Ndis802_11Encryption3Enabled; 513 break; 514 case WPA_CIPHER_WEP104: 515 padapter->securitypriv.XGrpPrivacy = _WEP104_; 516 padapter->securitypriv.ndisencryptstatus = 517 Ndis802_11Encryption1Enabled; 518 break; 519 } 520 switch (pairwise_cipher) { 521 case WPA_CIPHER_NONE: 522 padapter->securitypriv.PrivacyAlgrthm = 523 _NO_PRIVACY_; 524 padapter->securitypriv.ndisencryptstatus = 525 Ndis802_11EncryptionDisabled; 526 break; 527 case WPA_CIPHER_WEP40: 528 padapter->securitypriv.PrivacyAlgrthm = _WEP40_; 529 padapter->securitypriv.ndisencryptstatus = 530 Ndis802_11Encryption1Enabled; 531 break; 532 case WPA_CIPHER_TKIP: 533 padapter->securitypriv.PrivacyAlgrthm = _TKIP_; 534 padapter->securitypriv.ndisencryptstatus = 535 Ndis802_11Encryption2Enabled; 536 break; 537 case WPA_CIPHER_CCMP: 538 padapter->securitypriv.PrivacyAlgrthm = _AES_; 539 padapter->securitypriv.ndisencryptstatus = 540 Ndis802_11Encryption3Enabled; 541 break; 542 case WPA_CIPHER_WEP104: 543 padapter->securitypriv.PrivacyAlgrthm = _WEP104_; 544 padapter->securitypriv.ndisencryptstatus = 545 Ndis802_11Encryption1Enabled; 546 break; 547 } 548 padapter->securitypriv.wps_phase = false; 549 {/* set wps_ie */ 550 u16 cnt = 0; 551 u8 eid, wps_oui[4] = {0x0, 0x50, 0xf2, 0x04}; 552 553 while (cnt < ielen) { 554 eid = buf[cnt]; 555 556 if ((eid == _VENDOR_SPECIFIC_IE_) && 557 (!memcmp(&buf[cnt + 2], wps_oui, 4))) { 558 netdev_info(padapter->pnetdev, "r8712u: SET WPS_IE\n"); 559 padapter->securitypriv.wps_ie_len = 560 ((buf[cnt + 1] + 2) < 561 (MAX_WPA_IE_LEN << 2)) ? 562 (buf[cnt + 1] + 2) : 563 (MAX_WPA_IE_LEN << 2); 564 memcpy(padapter->securitypriv.wps_ie, 565 &buf[cnt], 566 padapter->securitypriv.wps_ie_len); 567 padapter->securitypriv.wps_phase = 568 true; 569 netdev_info(padapter->pnetdev, "r8712u: SET WPS_IE, wps_phase==true\n"); 570 cnt += buf[cnt + 1] + 2; 571 break; 572 } 573 574 cnt += buf[cnt + 1] + 2; 575 } 576 } 577 } 578 exit: 579 kfree(buf); 580 return ret; 581 } 582 583 static int r8711_wx_get_name(struct net_device *dev, 584 struct iw_request_info *info, 585 union iwreq_data *wrqu, char *extra) 586 { 587 struct _adapter *padapter = netdev_priv(dev); 588 u32 ht_ielen = 0; 589 char *p; 590 u8 ht_cap = false; 591 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); 592 struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network; 593 u8 *prates; 594 595 if (check_fwstate(pmlmepriv, _FW_LINKED | WIFI_ADHOC_MASTER_STATE) == 596 true) { 597 /* parsing HT_CAP_IE */ 598 p = r8712_get_ie(&pcur_bss->IEs[12], _HT_CAPABILITY_IE_, 599 &ht_ielen, pcur_bss->IELength - 12); 600 if (p && ht_ielen > 0) 601 ht_cap = true; 602 prates = pcur_bss->rates; 603 if (r8712_is_cckratesonly_included(prates)) { 604 if (ht_cap) 605 snprintf(wrqu->name, IFNAMSIZ, 606 "IEEE 802.11bn"); 607 else 608 snprintf(wrqu->name, IFNAMSIZ, 609 "IEEE 802.11b"); 610 } else if (r8712_is_cckrates_included(prates)) { 611 if (ht_cap) 612 snprintf(wrqu->name, IFNAMSIZ, 613 "IEEE 802.11bgn"); 614 else 615 snprintf(wrqu->name, IFNAMSIZ, 616 "IEEE 802.11bg"); 617 } else { 618 if (ht_cap) 619 snprintf(wrqu->name, IFNAMSIZ, 620 "IEEE 802.11gn"); 621 else 622 snprintf(wrqu->name, IFNAMSIZ, 623 "IEEE 802.11g"); 624 } 625 } else { 626 snprintf(wrqu->name, IFNAMSIZ, "unassociated"); 627 } 628 return 0; 629 } 630 631 static const long frequency_list[] = { 632 2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447, 2452, 2457, 2462, 633 2467, 2472, 2484, 4915, 4920, 4925, 4935, 4940, 4945, 4960, 4980, 634 5035, 5040, 5045, 5055, 5060, 5080, 5170, 5180, 5190, 5200, 5210, 635 5220, 5230, 5240, 5260, 5280, 5300, 5320, 5500, 5520, 5540, 5560, 636 5580, 5600, 5620, 5640, 5660, 5680, 5700, 5745, 5765, 5785, 5805, 637 5825 638 }; 639 640 static int r8711_wx_set_freq(struct net_device *dev, 641 struct iw_request_info *info, 642 union iwreq_data *wrqu, char *extra) 643 { 644 struct _adapter *padapter = netdev_priv(dev); 645 struct iw_freq *fwrq = &wrqu->freq; 646 int rc = 0; 647 648 /* If setting by frequency, convert to a channel */ 649 if ((fwrq->e == 1) && 650 (fwrq->m >= (int) 2.412e8) && 651 (fwrq->m <= (int) 2.487e8)) { 652 int f = fwrq->m / 100000; 653 int c = 0; 654 655 while ((c < 14) && (f != frequency_list[c])) 656 c++; 657 fwrq->e = 0; 658 fwrq->m = c + 1; 659 } 660 /* Setting by channel number */ 661 if ((fwrq->m > 14) || (fwrq->e > 0)) { 662 rc = -EOPNOTSUPP; 663 } else { 664 int channel = fwrq->m; 665 666 if ((channel < 1) || (channel > 14)) { 667 rc = -EINVAL; 668 } else { 669 /* Yes ! We can set it !!! */ 670 padapter->registrypriv.channel = channel; 671 } 672 } 673 return rc; 674 } 675 676 static int r8711_wx_get_freq(struct net_device *dev, 677 struct iw_request_info *info, 678 union iwreq_data *wrqu, char *extra) 679 { 680 struct _adapter *padapter = netdev_priv(dev); 681 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 682 struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network; 683 684 if (!check_fwstate(pmlmepriv, _FW_LINKED)) 685 return -ENOLINK; 686 687 wrqu->freq.m = ieee80211_wlan_frequencies[ 688 pcur_bss->Configuration.DSConfig - 1] * 100000; 689 wrqu->freq.e = 1; 690 wrqu->freq.i = pcur_bss->Configuration.DSConfig; 691 692 return 0; 693 } 694 695 static int r8711_wx_set_mode(struct net_device *dev, 696 struct iw_request_info *a, 697 union iwreq_data *wrqu, char *b) 698 { 699 struct _adapter *padapter = netdev_priv(dev); 700 enum NDIS_802_11_NETWORK_INFRASTRUCTURE networkType; 701 702 switch (wrqu->mode) { 703 case IW_MODE_AUTO: 704 networkType = Ndis802_11AutoUnknown; 705 break; 706 case IW_MODE_ADHOC: 707 networkType = Ndis802_11IBSS; 708 break; 709 case IW_MODE_MASTER: 710 networkType = Ndis802_11APMode; 711 break; 712 case IW_MODE_INFRA: 713 networkType = Ndis802_11Infrastructure; 714 break; 715 default: 716 return -EINVAL; 717 } 718 if (Ndis802_11APMode == networkType) 719 r8712_setopmode_cmd(padapter, networkType); 720 else 721 r8712_setopmode_cmd(padapter, Ndis802_11AutoUnknown); 722 723 r8712_set_802_11_infrastructure_mode(padapter, networkType); 724 return 0; 725 } 726 727 static int r8711_wx_get_mode(struct net_device *dev, struct iw_request_info *a, 728 union iwreq_data *wrqu, char *b) 729 { 730 struct _adapter *padapter = netdev_priv(dev); 731 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 732 733 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) 734 wrqu->mode = IW_MODE_INFRA; 735 else if (check_fwstate(pmlmepriv, 736 WIFI_ADHOC_MASTER_STATE | WIFI_ADHOC_STATE)) 737 wrqu->mode = IW_MODE_ADHOC; 738 else if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) 739 wrqu->mode = IW_MODE_MASTER; 740 else 741 wrqu->mode = IW_MODE_AUTO; 742 return 0; 743 } 744 745 static int r871x_wx_set_pmkid(struct net_device *dev, 746 struct iw_request_info *a, 747 union iwreq_data *wrqu, char *extra) 748 { 749 struct _adapter *padapter = netdev_priv(dev); 750 struct security_priv *psecuritypriv = &padapter->securitypriv; 751 struct iw_pmksa *pPMK = (struct iw_pmksa *) extra; 752 struct RT_PMKID_LIST *pl = psecuritypriv->PMKIDList; 753 u8 strZeroMacAddress[ETH_ALEN] = {0x00}; 754 u8 strIssueBssid[ETH_ALEN] = {0x00}; 755 u8 j, blInserted = false; 756 int intReturn = false; 757 758 /* 759 * There are the BSSID information in the bssid.sa_data array. 760 * If cmd is IW_PMKSA_FLUSH, it means the wpa_supplicant wants to clear 761 * all the PMKID information. If cmd is IW_PMKSA_ADD, it means the 762 * wpa_supplicant wants to add a PMKID/BSSID to driver. 763 * If cmd is IW_PMKSA_REMOVE, it means the wpa_supplicant wants to 764 * remove a PMKID/BSSID from driver. 765 */ 766 if (pPMK == NULL) 767 return -EINVAL; 768 memcpy(strIssueBssid, pPMK->bssid.sa_data, ETH_ALEN); 769 switch (pPMK->cmd) { 770 case IW_PMKSA_ADD: 771 if (!memcmp(strIssueBssid, strZeroMacAddress, ETH_ALEN)) 772 return intReturn; 773 intReturn = true; 774 blInserted = false; 775 /* overwrite PMKID */ 776 for (j = 0; j < NUM_PMKID_CACHE; j++) { 777 if (!memcmp(pl[j].Bssid, strIssueBssid, ETH_ALEN)) { 778 /* BSSID is matched, the same AP => rewrite 779 * with new PMKID. 780 */ 781 netdev_info(dev, "r8712u: %s: BSSID exists in the PMKList.\n", 782 __func__); 783 memcpy(pl[j].PMKID, pPMK->pmkid, IW_PMKID_LEN); 784 pl[j].bUsed = true; 785 psecuritypriv->PMKIDIndex = j + 1; 786 blInserted = true; 787 break; 788 } 789 } 790 if (!blInserted) { 791 /* Find a new entry */ 792 netdev_info(dev, "r8712u: %s: Use the new entry index = %d for this PMKID.\n", 793 __func__, psecuritypriv->PMKIDIndex); 794 memcpy(pl[psecuritypriv->PMKIDIndex].Bssid, 795 strIssueBssid, ETH_ALEN); 796 memcpy(pl[psecuritypriv->PMKIDIndex].PMKID, 797 pPMK->pmkid, IW_PMKID_LEN); 798 pl[psecuritypriv->PMKIDIndex].bUsed = true; 799 psecuritypriv->PMKIDIndex++; 800 if (psecuritypriv->PMKIDIndex == NUM_PMKID_CACHE) 801 psecuritypriv->PMKIDIndex = 0; 802 } 803 break; 804 case IW_PMKSA_REMOVE: 805 intReturn = true; 806 for (j = 0; j < NUM_PMKID_CACHE; j++) { 807 if (!memcmp(pl[j].Bssid, strIssueBssid, ETH_ALEN)) { 808 /* BSSID is matched, the same AP => Remove 809 * this PMKID information and reset it. 810 */ 811 eth_zero_addr(pl[j].Bssid); 812 pl[j].bUsed = false; 813 break; 814 } 815 } 816 break; 817 case IW_PMKSA_FLUSH: 818 memset(psecuritypriv->PMKIDList, 0, 819 sizeof(struct RT_PMKID_LIST) * NUM_PMKID_CACHE); 820 psecuritypriv->PMKIDIndex = 0; 821 intReturn = true; 822 break; 823 default: 824 netdev_info(dev, "r8712u: %s: unknown Command\n", __func__); 825 intReturn = false; 826 break; 827 } 828 return intReturn; 829 } 830 831 static int r8711_wx_get_sens(struct net_device *dev, 832 struct iw_request_info *info, 833 union iwreq_data *wrqu, char *extra) 834 { 835 wrqu->sens.value = 0; 836 wrqu->sens.fixed = 0; /* no auto select */ 837 wrqu->sens.disabled = 1; 838 return 0; 839 } 840 841 static int r8711_wx_get_range(struct net_device *dev, 842 struct iw_request_info *info, 843 union iwreq_data *wrqu, char *extra) 844 { 845 struct iw_range *range = (struct iw_range *)extra; 846 u16 val; 847 int i; 848 849 wrqu->data.length = sizeof(*range); 850 memset(range, 0, sizeof(*range)); 851 /* Let's try to keep this struct in the same order as in 852 * linux/include/wireless.h 853 */ 854 855 /* TODO: See what values we can set, and remove the ones we can't 856 * set, or fill them with some default data. 857 */ 858 /* ~5 Mb/s real (802.11b) */ 859 range->throughput = 5 * 1000 * 1000; 860 /* TODO: 8711 sensitivity ? */ 861 /* signal level threshold range */ 862 /* percent values between 0 and 100. */ 863 range->max_qual.qual = 100; 864 range->max_qual.level = 100; 865 range->max_qual.noise = 100; 866 range->max_qual.updated = 7; /* Updated all three */ 867 range->avg_qual.qual = 92; /* > 8% missed beacons is 'bad' */ 868 /* TODO: Find real 'good' to 'bad' threshold value for RSSI */ 869 range->avg_qual.level = 0x100 - 78; 870 range->avg_qual.noise = 0; 871 range->avg_qual.updated = 7; /* Updated all three */ 872 range->num_bitrates = RATE_COUNT; 873 for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++) 874 range->bitrate[i] = rtl8180_rates[i]; 875 range->min_frag = MIN_FRAG_THRESHOLD; 876 range->max_frag = MAX_FRAG_THRESHOLD; 877 range->pm_capa = 0; 878 range->we_version_compiled = WIRELESS_EXT; 879 range->we_version_source = 16; 880 range->num_channels = 14; 881 for (i = 0, val = 0; i < 14; i++) { 882 /* Include only legal frequencies for some countries */ 883 range->freq[val].i = i + 1; 884 range->freq[val].m = ieee80211_wlan_frequencies[i] * 100000; 885 range->freq[val].e = 1; 886 val++; 887 if (val == IW_MAX_FREQUENCIES) 888 break; 889 } 890 range->num_frequency = val; 891 range->enc_capa = IW_ENC_CAPA_WPA | 892 IW_ENC_CAPA_WPA2 | 893 IW_ENC_CAPA_CIPHER_TKIP | 894 IW_ENC_CAPA_CIPHER_CCMP; 895 return 0; 896 } 897 898 static int r8711_wx_get_rate(struct net_device *dev, 899 struct iw_request_info *info, 900 union iwreq_data *wrqu, char *extra); 901 902 static int r871x_wx_set_priv(struct net_device *dev, 903 struct iw_request_info *info, 904 union iwreq_data *awrq, 905 char *extra) 906 { 907 int ret = 0, len = 0; 908 char *ext; 909 struct _adapter *padapter = netdev_priv(dev); 910 struct iw_point *dwrq = (struct iw_point *)awrq; 911 912 len = dwrq->length; 913 ext = memdup_user(dwrq->pointer, len); 914 if (IS_ERR(ext)) 915 return PTR_ERR(ext); 916 917 if (!strcasecmp(ext, "RSSI")) { 918 /*Return received signal strength indicator in -db for */ 919 /* current AP */ 920 /*<ssid> Rssi xx */ 921 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); 922 struct wlan_network *pcur_network = &pmlmepriv->cur_network; 923 /*static u8 xxxx; */ 924 if (check_fwstate(pmlmepriv, _FW_LINKED)) { 925 sprintf(ext, "%s rssi %d", 926 pcur_network->network.Ssid.Ssid, 927 /*(xxxx=xxxx+10) */ 928 ((padapter->recvpriv.fw_rssi) >> 1) - 95 929 /*pcur_network->network.Rssi */ 930 ); 931 } else { 932 sprintf(ext, "OK"); 933 } 934 } else if (!strcasecmp(ext, "LINKSPEED")) { 935 /*Return link speed in MBPS */ 936 /*LinkSpeed xx */ 937 union iwreq_data wrqd; 938 int ret_inner; 939 int mbps; 940 941 ret_inner = r8711_wx_get_rate(dev, info, &wrqd, extra); 942 if (ret_inner != 0) 943 mbps = 0; 944 else 945 mbps = wrqd.bitrate.value / 1000000; 946 sprintf(ext, "LINKSPEED %d", mbps); 947 } else if (!strcasecmp(ext, "MACADDR")) { 948 /*Return mac address of the station */ 949 /* Macaddr = xx:xx:xx:xx:xx:xx */ 950 sprintf(ext, "MACADDR = %pM", dev->dev_addr); 951 } else if (!strcasecmp(ext, "SCAN-ACTIVE")) { 952 /*Set scan type to active */ 953 /*OK if successful */ 954 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 955 956 pmlmepriv->passive_mode = 1; 957 sprintf(ext, "OK"); 958 } else if (!strcasecmp(ext, "SCAN-PASSIVE")) { 959 /*Set scan type to passive */ 960 /*OK if successful */ 961 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 962 963 pmlmepriv->passive_mode = 0; 964 sprintf(ext, "OK"); 965 } else if (!strncmp(ext, "DCE-E", 5)) { 966 /*Set scan type to passive */ 967 /*OK if successful */ 968 r8712_disconnectCtrlEx_cmd(padapter 969 , 1 /*u32 enableDrvCtrl */ 970 , 5 /*u32 tryPktCnt */ 971 , 100 /*u32 tryPktInterval */ 972 , 5000 /*u32 firstStageTO */ 973 ); 974 sprintf(ext, "OK"); 975 } else if (!strncmp(ext, "DCE-D", 5)) { 976 /*Set scan type to passive */ 977 /*OK if successfu */ 978 r8712_disconnectCtrlEx_cmd(padapter 979 , 0 /*u32 enableDrvCtrl */ 980 , 5 /*u32 tryPktCnt */ 981 , 100 /*u32 tryPktInterval */ 982 , 5000 /*u32 firstStageTO */ 983 ); 984 sprintf(ext, "OK"); 985 } else { 986 netdev_info(dev, "r8712u: %s: unknown Command %s.\n", 987 __func__, ext); 988 goto FREE_EXT; 989 } 990 if (copy_to_user(dwrq->pointer, ext, 991 min(dwrq->length, (__u16)(strlen(ext) + 1)))) 992 ret = -EFAULT; 993 994 FREE_EXT: 995 kfree(ext); 996 return ret; 997 } 998 999 /* set bssid flow 1000 * s1. set_802_11_infrastructure_mode() 1001 * s2. set_802_11_authentication_mode() 1002 * s3. set_802_11_encryption_mode() 1003 * s4. set_802_11_bssid() 1004 * 1005 * This function intends to handle the Set AP command, which specifies the 1006 * MAC# of a preferred Access Point. 1007 * Currently, the request comes via Wireless Extensions' SIOCSIWAP ioctl. 1008 * 1009 * For this operation to succeed, there is no need for the interface to be up. 1010 * 1011 */ 1012 static int r8711_wx_set_wap(struct net_device *dev, 1013 struct iw_request_info *info, 1014 union iwreq_data *awrq, 1015 char *extra) 1016 { 1017 int ret = -EINPROGRESS; 1018 struct _adapter *padapter = netdev_priv(dev); 1019 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 1020 struct __queue *queue = &pmlmepriv->scanned_queue; 1021 struct sockaddr *temp = (struct sockaddr *)awrq; 1022 unsigned long irqL; 1023 struct list_head *phead; 1024 u8 *dst_bssid; 1025 struct wlan_network *pnetwork = NULL; 1026 enum NDIS_802_11_AUTHENTICATION_MODE authmode; 1027 1028 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) 1029 return -EBUSY; 1030 if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) 1031 return ret; 1032 if (temp->sa_family != ARPHRD_ETHER) 1033 return -EINVAL; 1034 authmode = padapter->securitypriv.ndisauthtype; 1035 spin_lock_irqsave(&queue->lock, irqL); 1036 phead = &queue->queue; 1037 pmlmepriv->pscanned = phead->next; 1038 while (1) { 1039 if (end_of_queue_search(phead, pmlmepriv->pscanned)) 1040 break; 1041 pnetwork = container_of(pmlmepriv->pscanned, 1042 struct wlan_network, list); 1043 pmlmepriv->pscanned = pmlmepriv->pscanned->next; 1044 dst_bssid = pnetwork->network.MacAddress; 1045 if (!memcmp(dst_bssid, temp->sa_data, ETH_ALEN)) { 1046 r8712_set_802_11_infrastructure_mode(padapter, 1047 pnetwork->network.InfrastructureMode); 1048 break; 1049 } 1050 } 1051 spin_unlock_irqrestore(&queue->lock, irqL); 1052 if (!ret) { 1053 if (!r8712_set_802_11_authentication_mode(padapter, authmode)) { 1054 ret = -ENOMEM; 1055 } else { 1056 if (!r8712_set_802_11_bssid(padapter, temp->sa_data)) 1057 ret = -1; 1058 } 1059 } 1060 return ret; 1061 } 1062 1063 static int r8711_wx_get_wap(struct net_device *dev, 1064 struct iw_request_info *info, 1065 union iwreq_data *wrqu, char *extra) 1066 { 1067 struct _adapter *padapter = netdev_priv(dev); 1068 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 1069 struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network; 1070 1071 wrqu->ap_addr.sa_family = ARPHRD_ETHER; 1072 if (check_fwstate(pmlmepriv, _FW_LINKED | WIFI_ADHOC_MASTER_STATE | 1073 WIFI_AP_STATE)) 1074 ether_addr_copy(wrqu->ap_addr.sa_data, pcur_bss->MacAddress); 1075 else 1076 eth_zero_addr(wrqu->ap_addr.sa_data); 1077 return 0; 1078 } 1079 1080 static int r871x_wx_set_mlme(struct net_device *dev, 1081 struct iw_request_info *info, 1082 union iwreq_data *wrqu, char *extra) 1083 { 1084 int ret = 0; 1085 struct _adapter *padapter = netdev_priv(dev); 1086 struct iw_mlme *mlme = (struct iw_mlme *) extra; 1087 1088 if (mlme == NULL) 1089 return -1; 1090 switch (mlme->cmd) { 1091 case IW_MLME_DEAUTH: 1092 if (!r8712_set_802_11_disassociate(padapter)) 1093 ret = -1; 1094 break; 1095 case IW_MLME_DISASSOC: 1096 if (!r8712_set_802_11_disassociate(padapter)) 1097 ret = -1; 1098 break; 1099 default: 1100 return -EOPNOTSUPP; 1101 } 1102 return ret; 1103 } 1104 1105 /* 1106 * 1107 * This function intends to handle the Set Scan command. 1108 * Currently, the request comes via Wireless Extensions' SIOCSIWSCAN ioctl. 1109 * 1110 * For this operation to succeed, the interface is brought Up beforehand. 1111 * 1112 */ 1113 static int r8711_wx_set_scan(struct net_device *dev, 1114 struct iw_request_info *a, 1115 union iwreq_data *wrqu, char *extra) 1116 { 1117 struct _adapter *padapter = netdev_priv(dev); 1118 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 1119 u8 status = true; 1120 1121 if (padapter->driver_stopped) { 1122 netdev_info(dev, "In %s: driver_stopped=%d\n", 1123 __func__, padapter->driver_stopped); 1124 return -1; 1125 } 1126 if (!padapter->bup) 1127 return -ENETDOWN; 1128 if (!padapter->hw_init_completed) 1129 return -1; 1130 if ((check_fwstate(pmlmepriv, _FW_UNDER_SURVEY | _FW_UNDER_LINKING)) || 1131 (pmlmepriv->sitesurveyctrl.traffic_busy)) 1132 return 0; 1133 if (wrqu->data.length == sizeof(struct iw_scan_req)) { 1134 struct iw_scan_req *req = (struct iw_scan_req *)extra; 1135 1136 if (wrqu->data.flags & IW_SCAN_THIS_ESSID) { 1137 struct ndis_802_11_ssid ssid; 1138 unsigned long irqL; 1139 u32 len = min_t(u8, req->essid_len, IW_ESSID_MAX_SIZE); 1140 1141 memset((unsigned char *)&ssid, 0, 1142 sizeof(struct ndis_802_11_ssid)); 1143 memcpy(ssid.Ssid, req->essid, len); 1144 ssid.SsidLength = len; 1145 spin_lock_irqsave(&pmlmepriv->lock, irqL); 1146 if ((check_fwstate(pmlmepriv, _FW_UNDER_SURVEY | 1147 _FW_UNDER_LINKING)) || 1148 (pmlmepriv->sitesurveyctrl.traffic_busy)) { 1149 if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) 1150 status = false; 1151 } else { 1152 status = r8712_sitesurvey_cmd(padapter, &ssid); 1153 } 1154 spin_unlock_irqrestore(&pmlmepriv->lock, irqL); 1155 } 1156 } else { 1157 status = r8712_set_802_11_bssid_list_scan(padapter); 1158 } 1159 if (!status) 1160 return -1; 1161 return 0; 1162 } 1163 1164 static int r8711_wx_get_scan(struct net_device *dev, 1165 struct iw_request_info *a, 1166 union iwreq_data *wrqu, char *extra) 1167 { 1168 struct _adapter *padapter = netdev_priv(dev); 1169 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 1170 struct __queue *queue = &pmlmepriv->scanned_queue; 1171 struct wlan_network *pnetwork = NULL; 1172 unsigned long irqL; 1173 struct list_head *plist, *phead; 1174 char *ev = extra; 1175 char *stop = ev + wrqu->data.length; 1176 u32 ret = 0, cnt = 0; 1177 1178 if (padapter->driver_stopped) 1179 return -EINVAL; 1180 while (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY | 1181 _FW_UNDER_LINKING)) { 1182 msleep(30); 1183 cnt++; 1184 if (cnt > 100) 1185 break; 1186 } 1187 spin_lock_irqsave(&queue->lock, irqL); 1188 phead = &queue->queue; 1189 plist = phead->next; 1190 while (1) { 1191 if (end_of_queue_search(phead, plist)) 1192 break; 1193 if ((stop - ev) < SCAN_ITEM_SIZE) { 1194 ret = -E2BIG; 1195 break; 1196 } 1197 pnetwork = container_of(plist, struct wlan_network, list); 1198 ev = translate_scan(padapter, a, pnetwork, ev, stop); 1199 plist = plist->next; 1200 } 1201 spin_unlock_irqrestore(&queue->lock, irqL); 1202 wrqu->data.length = ev - extra; 1203 wrqu->data.flags = 0; 1204 return ret; 1205 } 1206 1207 /* set ssid flow 1208 * s1. set_802_11_infrastructure_mode() 1209 * s2. set_802_11_authenticaion_mode() 1210 * s3. set_802_11_encryption_mode() 1211 * s4. set_802_11_ssid() 1212 * 1213 * This function intends to handle the Set ESSID command. 1214 * Currently, the request comes via the Wireless Extensions' SIOCSIWESSID ioctl. 1215 * 1216 * For this operation to succeed, there is no need for the interface to be Up. 1217 * 1218 */ 1219 static int r8711_wx_set_essid(struct net_device *dev, 1220 struct iw_request_info *a, 1221 union iwreq_data *wrqu, char *extra) 1222 { 1223 struct _adapter *padapter = netdev_priv(dev); 1224 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 1225 struct __queue *queue = &pmlmepriv->scanned_queue; 1226 struct wlan_network *pnetwork = NULL; 1227 enum NDIS_802_11_AUTHENTICATION_MODE authmode; 1228 struct ndis_802_11_ssid ndis_ssid; 1229 u8 *dst_ssid, *src_ssid; 1230 struct list_head *phead; 1231 u32 len; 1232 1233 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) 1234 return -EBUSY; 1235 if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) 1236 return 0; 1237 if (wrqu->essid.length > IW_ESSID_MAX_SIZE) 1238 return -E2BIG; 1239 authmode = padapter->securitypriv.ndisauthtype; 1240 if (wrqu->essid.flags && wrqu->essid.length) { 1241 len = (wrqu->essid.length < IW_ESSID_MAX_SIZE) ? 1242 wrqu->essid.length : IW_ESSID_MAX_SIZE; 1243 memset(&ndis_ssid, 0, sizeof(struct ndis_802_11_ssid)); 1244 ndis_ssid.SsidLength = len; 1245 memcpy(ndis_ssid.Ssid, extra, len); 1246 src_ssid = ndis_ssid.Ssid; 1247 phead = &queue->queue; 1248 pmlmepriv->pscanned = phead->next; 1249 while (1) { 1250 if (end_of_queue_search(phead, pmlmepriv->pscanned)) 1251 break; 1252 pnetwork = container_of(pmlmepriv->pscanned, 1253 struct wlan_network, list); 1254 pmlmepriv->pscanned = pmlmepriv->pscanned->next; 1255 dst_ssid = pnetwork->network.Ssid.Ssid; 1256 if ((!memcmp(dst_ssid, src_ssid, ndis_ssid.SsidLength)) 1257 && (pnetwork->network.Ssid.SsidLength == 1258 ndis_ssid.SsidLength)) { 1259 if (check_fwstate(pmlmepriv, 1260 WIFI_ADHOC_STATE)) { 1261 if (pnetwork->network. 1262 InfrastructureMode 1263 != 1264 padapter->mlmepriv. 1265 cur_network.network. 1266 InfrastructureMode) 1267 continue; 1268 } 1269 1270 r8712_set_802_11_infrastructure_mode( 1271 padapter, 1272 pnetwork->network.InfrastructureMode); 1273 break; 1274 } 1275 } 1276 r8712_set_802_11_authentication_mode(padapter, authmode); 1277 r8712_set_802_11_ssid(padapter, &ndis_ssid); 1278 } 1279 return -EINPROGRESS; 1280 } 1281 1282 static int r8711_wx_get_essid(struct net_device *dev, 1283 struct iw_request_info *a, 1284 union iwreq_data *wrqu, char *extra) 1285 { 1286 struct _adapter *padapter = netdev_priv(dev); 1287 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 1288 struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network; 1289 u32 len, ret = 0; 1290 1291 if (check_fwstate(pmlmepriv, _FW_LINKED | WIFI_ADHOC_MASTER_STATE)) { 1292 len = pcur_bss->Ssid.SsidLength; 1293 wrqu->essid.length = len; 1294 memcpy(extra, pcur_bss->Ssid.Ssid, len); 1295 wrqu->essid.flags = 1; 1296 } else { 1297 ret = -ENOLINK; 1298 } 1299 return ret; 1300 } 1301 1302 static int r8711_wx_set_rate(struct net_device *dev, 1303 struct iw_request_info *a, 1304 union iwreq_data *wrqu, char *extra) 1305 { 1306 struct _adapter *padapter = netdev_priv(dev); 1307 u32 target_rate = wrqu->bitrate.value; 1308 u32 fixed = wrqu->bitrate.fixed; 1309 u32 ratevalue = 0; 1310 u8 datarates[NumRates]; 1311 u8 mpdatarate[NumRates] = {11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0xff}; 1312 int i, ret = 0; 1313 1314 if (target_rate == -1) { 1315 ratevalue = 11; 1316 goto set_rate; 1317 } 1318 target_rate = target_rate / 100000; 1319 switch (target_rate) { 1320 case 10: 1321 ratevalue = 0; 1322 break; 1323 case 20: 1324 ratevalue = 1; 1325 break; 1326 case 55: 1327 ratevalue = 2; 1328 break; 1329 case 60: 1330 ratevalue = 3; 1331 break; 1332 case 90: 1333 ratevalue = 4; 1334 break; 1335 case 110: 1336 ratevalue = 5; 1337 break; 1338 case 120: 1339 ratevalue = 6; 1340 break; 1341 case 180: 1342 ratevalue = 7; 1343 break; 1344 case 240: 1345 ratevalue = 8; 1346 break; 1347 case 360: 1348 ratevalue = 9; 1349 break; 1350 case 480: 1351 ratevalue = 10; 1352 break; 1353 case 540: 1354 ratevalue = 11; 1355 break; 1356 default: 1357 ratevalue = 11; 1358 break; 1359 } 1360 set_rate: 1361 for (i = 0; i < NumRates; i++) { 1362 if (ratevalue == mpdatarate[i]) { 1363 datarates[i] = mpdatarate[i]; 1364 if (fixed == 0) 1365 break; 1366 } else { 1367 datarates[i] = 0xff; 1368 } 1369 } 1370 if (r8712_setdatarate_cmd(padapter, datarates) != _SUCCESS) 1371 ret = -ENOMEM; 1372 return ret; 1373 } 1374 1375 static int r8711_wx_get_rate(struct net_device *dev, 1376 struct iw_request_info *info, 1377 union iwreq_data *wrqu, char *extra) 1378 { 1379 struct _adapter *padapter = netdev_priv(dev); 1380 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 1381 struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network; 1382 struct ieee80211_ht_cap *pht_capie; 1383 unsigned char rf_type = padapter->registrypriv.rf_config; 1384 int i; 1385 u8 *p; 1386 u16 rate, max_rate = 0, ht_cap = false; 1387 u32 ht_ielen = 0; 1388 u8 bw_40MHz = 0, short_GI = 0; 1389 u16 mcs_rate = 0; 1390 1391 i = 0; 1392 if (!check_fwstate(pmlmepriv, _FW_LINKED | WIFI_ADHOC_MASTER_STATE)) 1393 return -ENOLINK; 1394 p = r8712_get_ie(&pcur_bss->IEs[12], _HT_CAPABILITY_IE_, &ht_ielen, 1395 pcur_bss->IELength - 12); 1396 if (p && ht_ielen > 0) { 1397 ht_cap = true; 1398 pht_capie = (struct ieee80211_ht_cap *)(p + 2); 1399 memcpy(&mcs_rate, pht_capie->supp_mcs_set, 2); 1400 bw_40MHz = (le16_to_cpu(pht_capie->cap_info) & 1401 IEEE80211_HT_CAP_SUP_WIDTH) ? 1 : 0; 1402 short_GI = (le16_to_cpu(pht_capie->cap_info) & 1403 (IEEE80211_HT_CAP_SGI_20 | 1404 IEEE80211_HT_CAP_SGI_40)) ? 1 : 0; 1405 } 1406 while ((pcur_bss->rates[i] != 0) && 1407 (pcur_bss->rates[i] != 0xFF)) { 1408 rate = pcur_bss->rates[i] & 0x7F; 1409 if (rate > max_rate) 1410 max_rate = rate; 1411 wrqu->bitrate.fixed = 0; /* no auto select */ 1412 wrqu->bitrate.value = rate * 500000; 1413 i++; 1414 } 1415 if (ht_cap) { 1416 if (mcs_rate & 0x8000 /* MCS15 */ 1417 && 1418 rf_type == RTL8712_RF_2T2R) 1419 max_rate = (bw_40MHz) ? ((short_GI) ? 300 : 270) : 1420 ((short_GI) ? 144 : 130); 1421 else /* default MCS7 */ 1422 max_rate = (bw_40MHz) ? ((short_GI) ? 150 : 135) : 1423 ((short_GI) ? 72 : 65); 1424 max_rate *= 2; /* Mbps/2 */ 1425 } 1426 wrqu->bitrate.value = max_rate * 500000; 1427 return 0; 1428 } 1429 1430 static int r8711_wx_get_rts(struct net_device *dev, 1431 struct iw_request_info *info, 1432 union iwreq_data *wrqu, char *extra) 1433 { 1434 struct _adapter *padapter = netdev_priv(dev); 1435 1436 wrqu->rts.value = padapter->registrypriv.rts_thresh; 1437 wrqu->rts.fixed = 0; /* no auto select */ 1438 return 0; 1439 } 1440 1441 static int r8711_wx_set_frag(struct net_device *dev, 1442 struct iw_request_info *info, 1443 union iwreq_data *wrqu, char *extra) 1444 { 1445 struct _adapter *padapter = netdev_priv(dev); 1446 1447 if (wrqu->frag.disabled) { 1448 padapter->xmitpriv.frag_len = MAX_FRAG_THRESHOLD; 1449 } else { 1450 if (wrqu->frag.value < MIN_FRAG_THRESHOLD || 1451 wrqu->frag.value > MAX_FRAG_THRESHOLD) 1452 return -EINVAL; 1453 padapter->xmitpriv.frag_len = wrqu->frag.value & ~0x1; 1454 } 1455 return 0; 1456 } 1457 1458 static int r8711_wx_get_frag(struct net_device *dev, 1459 struct iw_request_info *info, 1460 union iwreq_data *wrqu, char *extra) 1461 { 1462 struct _adapter *padapter = netdev_priv(dev); 1463 1464 wrqu->frag.value = padapter->xmitpriv.frag_len; 1465 wrqu->frag.fixed = 0; /* no auto select */ 1466 return 0; 1467 } 1468 1469 static int r8711_wx_get_retry(struct net_device *dev, 1470 struct iw_request_info *info, 1471 union iwreq_data *wrqu, char *extra) 1472 { 1473 wrqu->retry.value = 7; 1474 wrqu->retry.fixed = 0; /* no auto select */ 1475 wrqu->retry.disabled = 1; 1476 return 0; 1477 } 1478 1479 static int r8711_wx_set_enc(struct net_device *dev, 1480 struct iw_request_info *info, 1481 union iwreq_data *wrqu, char *keybuf) 1482 { 1483 u32 key; 1484 u32 keyindex_provided; 1485 struct NDIS_802_11_WEP wep; 1486 enum NDIS_802_11_AUTHENTICATION_MODE authmode; 1487 struct iw_point *erq = &(wrqu->encoding); 1488 struct _adapter *padapter = netdev_priv(dev); 1489 1490 key = erq->flags & IW_ENCODE_INDEX; 1491 memset(&wep, 0, sizeof(struct NDIS_802_11_WEP)); 1492 if (erq->flags & IW_ENCODE_DISABLED) { 1493 netdev_info(dev, "r8712u: %s: EncryptionDisabled\n", __func__); 1494 padapter->securitypriv.ndisencryptstatus = 1495 Ndis802_11EncryptionDisabled; 1496 padapter->securitypriv.PrivacyAlgrthm = _NO_PRIVACY_; 1497 padapter->securitypriv.XGrpPrivacy = _NO_PRIVACY_; 1498 padapter->securitypriv.AuthAlgrthm = 0; /* open system */ 1499 authmode = Ndis802_11AuthModeOpen; 1500 padapter->securitypriv.ndisauthtype = authmode; 1501 return 0; 1502 } 1503 if (key) { 1504 if (key > WEP_KEYS) 1505 return -EINVAL; 1506 key--; 1507 keyindex_provided = 1; 1508 } else { 1509 keyindex_provided = 0; 1510 key = padapter->securitypriv.PrivacyKeyIndex; 1511 } 1512 /* set authentication mode */ 1513 if (erq->flags & IW_ENCODE_OPEN) { 1514 netdev_info(dev, "r8712u: %s: IW_ENCODE_OPEN\n", __func__); 1515 padapter->securitypriv.ndisencryptstatus = 1516 Ndis802_11Encryption1Enabled; 1517 padapter->securitypriv.AuthAlgrthm = 0; /* open system */ 1518 padapter->securitypriv.PrivacyAlgrthm = _NO_PRIVACY_; 1519 padapter->securitypriv.XGrpPrivacy = _NO_PRIVACY_; 1520 authmode = Ndis802_11AuthModeOpen; 1521 padapter->securitypriv.ndisauthtype = authmode; 1522 } else if (erq->flags & IW_ENCODE_RESTRICTED) { 1523 netdev_info(dev, 1524 "r8712u: %s: IW_ENCODE_RESTRICTED\n", __func__); 1525 padapter->securitypriv.ndisencryptstatus = 1526 Ndis802_11Encryption1Enabled; 1527 padapter->securitypriv.AuthAlgrthm = 1; /* shared system */ 1528 padapter->securitypriv.PrivacyAlgrthm = _WEP40_; 1529 padapter->securitypriv.XGrpPrivacy = _WEP40_; 1530 authmode = Ndis802_11AuthModeShared; 1531 padapter->securitypriv.ndisauthtype = authmode; 1532 } else { 1533 padapter->securitypriv.ndisencryptstatus = 1534 Ndis802_11Encryption1Enabled; 1535 padapter->securitypriv.AuthAlgrthm = 0; /* open system */ 1536 padapter->securitypriv.PrivacyAlgrthm = _NO_PRIVACY_; 1537 padapter->securitypriv.XGrpPrivacy = _NO_PRIVACY_; 1538 authmode = Ndis802_11AuthModeOpen; 1539 padapter->securitypriv.ndisauthtype = authmode; 1540 } 1541 wep.KeyIndex = key; 1542 if (erq->length > 0) { 1543 wep.KeyLength = erq->length <= 5 ? 5 : 13; 1544 wep.Length = wep.KeyLength + 1545 FIELD_OFFSET(struct NDIS_802_11_WEP, KeyMaterial); 1546 } else { 1547 wep.KeyLength = 0; 1548 if (keyindex_provided == 1) { /* set key_id only, no given 1549 * KeyMaterial(erq->length==0). 1550 */ 1551 padapter->securitypriv.PrivacyKeyIndex = key; 1552 switch (padapter->securitypriv.DefKeylen[key]) { 1553 case 5: 1554 padapter->securitypriv.PrivacyAlgrthm = 1555 _WEP40_; 1556 break; 1557 case 13: 1558 padapter->securitypriv.PrivacyAlgrthm = 1559 _WEP104_; 1560 break; 1561 default: 1562 padapter->securitypriv.PrivacyAlgrthm = 1563 _NO_PRIVACY_; 1564 break; 1565 } 1566 return 0; 1567 } 1568 } 1569 wep.KeyIndex |= 0x80000000; /* transmit key */ 1570 memcpy(wep.KeyMaterial, keybuf, wep.KeyLength); 1571 if (r8712_set_802_11_add_wep(padapter, &wep) == _FAIL) 1572 return -EOPNOTSUPP; 1573 return 0; 1574 } 1575 1576 static int r8711_wx_get_enc(struct net_device *dev, 1577 struct iw_request_info *info, 1578 union iwreq_data *wrqu, char *keybuf) 1579 { 1580 uint key, ret = 0; 1581 struct _adapter *padapter = netdev_priv(dev); 1582 struct iw_point *erq = &(wrqu->encoding); 1583 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); 1584 union Keytype *dk = padapter->securitypriv.DefKey; 1585 1586 if (!check_fwstate(pmlmepriv, _FW_LINKED)) { 1587 if (!check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) { 1588 erq->length = 0; 1589 erq->flags |= IW_ENCODE_DISABLED; 1590 return 0; 1591 } 1592 } 1593 key = erq->flags & IW_ENCODE_INDEX; 1594 if (key) { 1595 if (key > WEP_KEYS) 1596 return -EINVAL; 1597 key--; 1598 } else { 1599 key = padapter->securitypriv.PrivacyKeyIndex; 1600 } 1601 erq->flags = key + 1; 1602 switch (padapter->securitypriv.ndisencryptstatus) { 1603 case Ndis802_11EncryptionNotSupported: 1604 case Ndis802_11EncryptionDisabled: 1605 erq->length = 0; 1606 erq->flags |= IW_ENCODE_DISABLED; 1607 break; 1608 case Ndis802_11Encryption1Enabled: 1609 erq->length = padapter->securitypriv.DefKeylen[key]; 1610 if (erq->length) { 1611 memcpy(keybuf, dk[key].skey, 1612 padapter->securitypriv.DefKeylen[key]); 1613 erq->flags |= IW_ENCODE_ENABLED; 1614 if (padapter->securitypriv.ndisauthtype == 1615 Ndis802_11AuthModeOpen) 1616 erq->flags |= IW_ENCODE_OPEN; 1617 else if (padapter->securitypriv.ndisauthtype == 1618 Ndis802_11AuthModeShared) 1619 erq->flags |= IW_ENCODE_RESTRICTED; 1620 } else { 1621 erq->length = 0; 1622 erq->flags |= IW_ENCODE_DISABLED; 1623 } 1624 break; 1625 case Ndis802_11Encryption2Enabled: 1626 case Ndis802_11Encryption3Enabled: 1627 erq->length = 16; 1628 erq->flags |= (IW_ENCODE_ENABLED | IW_ENCODE_OPEN | 1629 IW_ENCODE_NOKEY); 1630 break; 1631 default: 1632 erq->length = 0; 1633 erq->flags |= IW_ENCODE_DISABLED; 1634 break; 1635 } 1636 return ret; 1637 } 1638 1639 static int r8711_wx_get_power(struct net_device *dev, 1640 struct iw_request_info *info, 1641 union iwreq_data *wrqu, char *extra) 1642 { 1643 wrqu->power.value = 0; 1644 wrqu->power.fixed = 0; /* no auto select */ 1645 wrqu->power.disabled = 1; 1646 return 0; 1647 } 1648 1649 static int r871x_wx_set_gen_ie(struct net_device *dev, 1650 struct iw_request_info *info, 1651 union iwreq_data *wrqu, char *extra) 1652 { 1653 struct _adapter *padapter = netdev_priv(dev); 1654 1655 return r871x_set_wpa_ie(padapter, extra, wrqu->data.length); 1656 } 1657 1658 static int r871x_wx_set_auth(struct net_device *dev, 1659 struct iw_request_info *info, 1660 union iwreq_data *wrqu, char *extra) 1661 { 1662 struct _adapter *padapter = netdev_priv(dev); 1663 struct iw_param *param = (struct iw_param *)&(wrqu->param); 1664 int paramid; 1665 int paramval; 1666 int ret = 0; 1667 1668 paramid = param->flags & IW_AUTH_INDEX; 1669 paramval = param->value; 1670 switch (paramid) { 1671 case IW_AUTH_WPA_VERSION: 1672 break; 1673 case IW_AUTH_CIPHER_PAIRWISE: 1674 break; 1675 case IW_AUTH_CIPHER_GROUP: 1676 break; 1677 case IW_AUTH_KEY_MGMT: 1678 /* 1679 * ??? does not use these parameters 1680 */ 1681 break; 1682 case IW_AUTH_TKIP_COUNTERMEASURES: 1683 if (paramval) { 1684 /* wpa_supplicant is enabling tkip countermeasure. */ 1685 padapter->securitypriv.btkip_countermeasure = true; 1686 } else { 1687 /* wpa_supplicant is disabling tkip countermeasure. */ 1688 padapter->securitypriv.btkip_countermeasure = false; 1689 } 1690 break; 1691 case IW_AUTH_DROP_UNENCRYPTED: 1692 /* HACK: 1693 * 1694 * wpa_supplicant calls set_wpa_enabled when the driver 1695 * is loaded and unloaded, regardless of if WPA is being 1696 * used. No other calls are made which can be used to 1697 * determine if encryption will be used or not prior to 1698 * association being expected. If encryption is not being 1699 * used, drop_unencrypted is set to false, else true -- we 1700 * can use this to determine if the CAP_PRIVACY_ON bit should 1701 * be set. 1702 */ 1703 if (padapter->securitypriv.ndisencryptstatus == 1704 Ndis802_11Encryption1Enabled) { 1705 /* it means init value, or using wep, 1706 * ndisencryptstatus = 1707 * Ndis802_11Encryption1Enabled, 1708 * then it needn't reset it; 1709 */ 1710 break; 1711 } 1712 1713 if (paramval) { 1714 padapter->securitypriv.ndisencryptstatus = 1715 Ndis802_11EncryptionDisabled; 1716 padapter->securitypriv.PrivacyAlgrthm = 1717 _NO_PRIVACY_; 1718 padapter->securitypriv.XGrpPrivacy = 1719 _NO_PRIVACY_; 1720 padapter->securitypriv.AuthAlgrthm = 0; 1721 padapter->securitypriv.ndisauthtype = 1722 Ndis802_11AuthModeOpen; 1723 } 1724 break; 1725 case IW_AUTH_80211_AUTH_ALG: 1726 ret = wpa_set_auth_algs(dev, (u32)paramval); 1727 break; 1728 case IW_AUTH_WPA_ENABLED: 1729 break; 1730 case IW_AUTH_RX_UNENCRYPTED_EAPOL: 1731 break; 1732 case IW_AUTH_PRIVACY_INVOKED: 1733 break; 1734 default: 1735 return -EOPNOTSUPP; 1736 } 1737 1738 return ret; 1739 } 1740 1741 static int r871x_wx_set_enc_ext(struct net_device *dev, 1742 struct iw_request_info *info, 1743 union iwreq_data *wrqu, char *extra) 1744 { 1745 struct iw_point *pencoding = &wrqu->encoding; 1746 struct iw_encode_ext *pext = (struct iw_encode_ext *)extra; 1747 struct ieee_param *param = NULL; 1748 char *alg_name; 1749 u32 param_len; 1750 int ret = 0; 1751 1752 switch (pext->alg) { 1753 case IW_ENCODE_ALG_NONE: 1754 alg_name = "none"; 1755 break; 1756 case IW_ENCODE_ALG_WEP: 1757 alg_name = "WEP"; 1758 break; 1759 case IW_ENCODE_ALG_TKIP: 1760 alg_name = "TKIP"; 1761 break; 1762 case IW_ENCODE_ALG_CCMP: 1763 alg_name = "CCMP"; 1764 break; 1765 default: 1766 return -EINVAL; 1767 } 1768 1769 param_len = sizeof(struct ieee_param) + pext->key_len; 1770 param = kzalloc(param_len, GFP_ATOMIC); 1771 if (!param) 1772 return -ENOMEM; 1773 param->cmd = IEEE_CMD_SET_ENCRYPTION; 1774 eth_broadcast_addr(param->sta_addr); 1775 strlcpy((char *)param->u.crypt.alg, alg_name, IEEE_CRYPT_ALG_NAME_LEN); 1776 if (pext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) 1777 param->u.crypt.set_tx = 0; 1778 if (pext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) 1779 param->u.crypt.set_tx = 1; 1780 param->u.crypt.idx = (pencoding->flags & 0x00FF) - 1; 1781 if (pext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) 1782 memcpy(param->u.crypt.seq, pext->rx_seq, 8); 1783 if (pext->key_len) { 1784 param->u.crypt.key_len = pext->key_len; 1785 memcpy(param + 1, pext + 1, pext->key_len); 1786 } 1787 ret = wpa_set_encryption(dev, param, param_len); 1788 kfree(param); 1789 return ret; 1790 } 1791 1792 static int r871x_wx_get_nick(struct net_device *dev, 1793 struct iw_request_info *info, 1794 union iwreq_data *wrqu, char *extra) 1795 { 1796 if (extra) { 1797 wrqu->data.length = 8; 1798 wrqu->data.flags = 1; 1799 memcpy(extra, "rtl_wifi", 8); 1800 } 1801 return 0; 1802 } 1803 1804 static int r8711_wx_read32(struct net_device *dev, 1805 struct iw_request_info *info, 1806 union iwreq_data *wrqu, char *keybuf) 1807 { 1808 struct _adapter *padapter = netdev_priv(dev); 1809 u32 addr; 1810 u32 data32; 1811 1812 get_user(addr, (u32 __user *)wrqu->data.pointer); 1813 data32 = r8712_read32(padapter, addr); 1814 put_user(data32, (u32 __user *)wrqu->data.pointer); 1815 wrqu->data.length = (data32 & 0xffff0000) >> 16; 1816 wrqu->data.flags = data32 & 0xffff; 1817 get_user(addr, (u32 __user *)wrqu->data.pointer); 1818 return 0; 1819 } 1820 1821 static int r8711_wx_write32(struct net_device *dev, 1822 struct iw_request_info *info, 1823 union iwreq_data *wrqu, char *keybuf) 1824 { 1825 struct _adapter *padapter = netdev_priv(dev); 1826 u32 addr; 1827 u32 data32; 1828 1829 get_user(addr, (u32 __user *)wrqu->data.pointer); 1830 data32 = ((u32)wrqu->data.length << 16) | (u32)wrqu->data.flags; 1831 r8712_write32(padapter, addr, data32); 1832 return 0; 1833 } 1834 1835 static int dummy(struct net_device *dev, 1836 struct iw_request_info *a, 1837 union iwreq_data *wrqu, char *b) 1838 { 1839 return -EINVAL; 1840 } 1841 1842 static int r8711_drvext_hdl(struct net_device *dev, 1843 struct iw_request_info *info, 1844 union iwreq_data *wrqu, char *extra) 1845 { 1846 return 0; 1847 } 1848 1849 static int r871x_mp_ioctl_hdl(struct net_device *dev, 1850 struct iw_request_info *info, 1851 union iwreq_data *wrqu, char *extra) 1852 { 1853 struct _adapter *padapter = netdev_priv(dev); 1854 struct iw_point *p = &wrqu->data; 1855 struct oid_par_priv oid_par; 1856 struct mp_ioctl_handler *phandler; 1857 struct mp_ioctl_param *poidparam; 1858 unsigned long BytesRead, BytesWritten, BytesNeeded; 1859 u8 *pparmbuf, bset; 1860 u16 len; 1861 uint status; 1862 int ret = 0; 1863 1864 if ((!p->length) || (!p->pointer)) 1865 return -EINVAL; 1866 1867 bset = (u8)(p->flags & 0xFFFF); 1868 len = p->length; 1869 pparmbuf = memdup_user(p->pointer, len); 1870 if (IS_ERR(pparmbuf)) 1871 return PTR_ERR(pparmbuf); 1872 1873 poidparam = (struct mp_ioctl_param *)pparmbuf; 1874 if (poidparam->subcode >= MAX_MP_IOCTL_SUBCODE) { 1875 ret = -EINVAL; 1876 goto _r871x_mp_ioctl_hdl_exit; 1877 } 1878 phandler = mp_ioctl_hdl + poidparam->subcode; 1879 if ((phandler->paramsize != 0) && 1880 (poidparam->len < phandler->paramsize)) { 1881 ret = -EINVAL; 1882 goto _r871x_mp_ioctl_hdl_exit; 1883 } 1884 if (phandler->oid == 0 && phandler->handler) { 1885 status = phandler->handler(&oid_par); 1886 } else if (phandler->handler) { 1887 oid_par.adapter_context = padapter; 1888 oid_par.oid = phandler->oid; 1889 oid_par.information_buf = poidparam->data; 1890 oid_par.information_buf_len = poidparam->len; 1891 oid_par.dbg = 0; 1892 BytesWritten = 0; 1893 BytesNeeded = 0; 1894 if (bset) { 1895 oid_par.bytes_rw = &BytesRead; 1896 oid_par.bytes_needed = &BytesNeeded; 1897 oid_par.type_of_oid = SET_OID; 1898 } else { 1899 oid_par.bytes_rw = &BytesWritten; 1900 oid_par.bytes_needed = &BytesNeeded; 1901 oid_par.type_of_oid = QUERY_OID; 1902 } 1903 status = phandler->handler(&oid_par); 1904 /* todo:check status, BytesNeeded, etc. */ 1905 } else { 1906 netdev_info(dev, "r8712u: %s: err!, subcode=%d, oid=%d, handler=%p\n", 1907 __func__, poidparam->subcode, phandler->oid, 1908 phandler->handler); 1909 ret = -EFAULT; 1910 goto _r871x_mp_ioctl_hdl_exit; 1911 } 1912 if (bset == 0x00) { /* query info */ 1913 if (copy_to_user(p->pointer, pparmbuf, len)) 1914 ret = -EFAULT; 1915 } 1916 if (status) { 1917 ret = -EFAULT; 1918 goto _r871x_mp_ioctl_hdl_exit; 1919 } 1920 _r871x_mp_ioctl_hdl_exit: 1921 kfree(pparmbuf); 1922 return ret; 1923 } 1924 1925 static int r871x_get_ap_info(struct net_device *dev, 1926 struct iw_request_info *info, 1927 union iwreq_data *wrqu, char *extra) 1928 { 1929 struct _adapter *padapter = netdev_priv(dev); 1930 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 1931 struct __queue *queue = &pmlmepriv->scanned_queue; 1932 struct iw_point *pdata = &wrqu->data; 1933 struct wlan_network *pnetwork = NULL; 1934 u32 cnt = 0, wpa_ielen; 1935 unsigned long irqL; 1936 struct list_head *plist, *phead; 1937 unsigned char *pbuf; 1938 u8 bssid[ETH_ALEN]; 1939 char data[33]; 1940 1941 if (padapter->driver_stopped || (pdata == NULL)) 1942 return -EINVAL; 1943 while (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY | 1944 _FW_UNDER_LINKING)) { 1945 msleep(30); 1946 cnt++; 1947 if (cnt > 100) 1948 break; 1949 } 1950 pdata->flags = 0; 1951 if (pdata->length < 32) 1952 return -EINVAL; 1953 if (copy_from_user(data, pdata->pointer, 32)) 1954 return -EINVAL; 1955 data[32] = 0; 1956 1957 spin_lock_irqsave(&(pmlmepriv->scanned_queue.lock), irqL); 1958 phead = &queue->queue; 1959 plist = phead->next; 1960 while (1) { 1961 if (end_of_queue_search(phead, plist)) 1962 break; 1963 pnetwork = container_of(plist, struct wlan_network, list); 1964 if (!mac_pton(data, bssid)) { 1965 netdev_info(dev, "r8712u: Invalid BSSID '%s'.\n", 1966 (u8 *)data); 1967 spin_unlock_irqrestore(&(pmlmepriv->scanned_queue.lock), 1968 irqL); 1969 return -EINVAL; 1970 } 1971 netdev_info(dev, "r8712u: BSSID:%pM\n", bssid); 1972 if (ether_addr_equal(bssid, pnetwork->network.MacAddress)) { 1973 /* BSSID match, then check if supporting wpa/wpa2 */ 1974 pbuf = r8712_get_wpa_ie(&pnetwork->network.IEs[12], 1975 &wpa_ielen, pnetwork->network.IELength - 12); 1976 if (pbuf && (wpa_ielen > 0)) { 1977 pdata->flags = 1; 1978 break; 1979 } 1980 pbuf = r8712_get_wpa2_ie(&pnetwork->network.IEs[12], 1981 &wpa_ielen, pnetwork->network.IELength - 12); 1982 if (pbuf && (wpa_ielen > 0)) { 1983 pdata->flags = 2; 1984 break; 1985 } 1986 } 1987 plist = plist->next; 1988 } 1989 spin_unlock_irqrestore(&(pmlmepriv->scanned_queue.lock), irqL); 1990 if (pdata->length >= 34) { 1991 if (copy_to_user((u8 __user *)pdata->pointer + 32, 1992 (u8 *)&pdata->flags, 1)) 1993 return -EINVAL; 1994 } 1995 return 0; 1996 } 1997 1998 static int r871x_set_pid(struct net_device *dev, 1999 struct iw_request_info *info, 2000 union iwreq_data *wrqu, char *extra) 2001 { 2002 struct _adapter *padapter = netdev_priv(dev); 2003 struct iw_point *pdata = &wrqu->data; 2004 2005 if ((padapter->driver_stopped) || (pdata == NULL)) 2006 return -EINVAL; 2007 if (copy_from_user(&padapter->pid, pdata->pointer, sizeof(int))) 2008 return -EINVAL; 2009 return 0; 2010 } 2011 2012 static int r871x_set_chplan(struct net_device *dev, 2013 struct iw_request_info *info, 2014 union iwreq_data *wrqu, char *extra) 2015 { 2016 int ret = 0; 2017 struct _adapter *padapter = netdev_priv(dev); 2018 struct iw_point *pdata = &wrqu->data; 2019 int ch_plan = -1; 2020 2021 if ((padapter->driver_stopped) || (pdata == NULL)) { 2022 ret = -EINVAL; 2023 goto exit; 2024 } 2025 ch_plan = (int)*extra; 2026 r8712_set_chplan_cmd(padapter, ch_plan); 2027 2028 exit: 2029 2030 return ret; 2031 } 2032 2033 static int r871x_wps_start(struct net_device *dev, 2034 struct iw_request_info *info, 2035 union iwreq_data *wrqu, char *extra) 2036 { 2037 struct _adapter *padapter = netdev_priv(dev); 2038 struct iw_point *pdata = &wrqu->data; 2039 u32 u32wps_start = 0; 2040 2041 if ((padapter->driver_stopped) || (pdata == NULL)) 2042 return -EINVAL; 2043 if (copy_from_user((void *)&u32wps_start, pdata->pointer, 4)) 2044 return -EFAULT; 2045 if (u32wps_start == 0) 2046 u32wps_start = *extra; 2047 if (u32wps_start == 1) /* WPS Start */ 2048 padapter->ledpriv.LedControlHandler(padapter, 2049 LED_CTL_START_WPS); 2050 else if (u32wps_start == 2) /* WPS Stop because of wps success */ 2051 padapter->ledpriv.LedControlHandler(padapter, 2052 LED_CTL_STOP_WPS); 2053 else if (u32wps_start == 3) /* WPS Stop because of wps fail */ 2054 padapter->ledpriv.LedControlHandler(padapter, 2055 LED_CTL_STOP_WPS_FAIL); 2056 return 0; 2057 } 2058 2059 static int wpa_set_param(struct net_device *dev, u8 name, u32 value) 2060 { 2061 struct _adapter *padapter = netdev_priv(dev); 2062 2063 switch (name) { 2064 case IEEE_PARAM_WPA_ENABLED: 2065 padapter->securitypriv.AuthAlgrthm = 2; /* 802.1x */ 2066 switch ((value) & 0xff) { 2067 case 1: /* WPA */ 2068 padapter->securitypriv.ndisauthtype = 2069 Ndis802_11AuthModeWPAPSK; /* WPA_PSK */ 2070 padapter->securitypriv.ndisencryptstatus = 2071 Ndis802_11Encryption2Enabled; 2072 break; 2073 case 2: /* WPA2 */ 2074 padapter->securitypriv.ndisauthtype = 2075 Ndis802_11AuthModeWPA2PSK; /* WPA2_PSK */ 2076 padapter->securitypriv.ndisencryptstatus = 2077 Ndis802_11Encryption3Enabled; 2078 break; 2079 } 2080 break; 2081 case IEEE_PARAM_TKIP_COUNTERMEASURES: 2082 break; 2083 case IEEE_PARAM_DROP_UNENCRYPTED: 2084 /* HACK: 2085 * 2086 * wpa_supplicant calls set_wpa_enabled when the driver 2087 * is loaded and unloaded, regardless of if WPA is being 2088 * used. No other calls are made which can be used to 2089 * determine if encryption will be used or not prior to 2090 * association being expected. If encryption is not being 2091 * used, drop_unencrypted is set to false, else true -- we 2092 * can use this to determine if the CAP_PRIVACY_ON bit should 2093 * be set. 2094 */ 2095 break; 2096 case IEEE_PARAM_PRIVACY_INVOKED: 2097 break; 2098 case IEEE_PARAM_AUTH_ALGS: 2099 return wpa_set_auth_algs(dev, value); 2100 case IEEE_PARAM_IEEE_802_1X: 2101 break; 2102 case IEEE_PARAM_WPAX_SELECT: 2103 /* added for WPA2 mixed mode */ 2104 break; 2105 default: 2106 return -EOPNOTSUPP; 2107 } 2108 return 0; 2109 } 2110 2111 static int wpa_mlme(struct net_device *dev, u32 command, u32 reason) 2112 { 2113 struct _adapter *padapter = netdev_priv(dev); 2114 2115 switch (command) { 2116 case IEEE_MLME_STA_DEAUTH: 2117 if (!r8712_set_802_11_disassociate(padapter)) 2118 return -1; 2119 break; 2120 case IEEE_MLME_STA_DISASSOC: 2121 if (!r8712_set_802_11_disassociate(padapter)) 2122 return -1; 2123 break; 2124 default: 2125 return -EOPNOTSUPP; 2126 } 2127 return 0; 2128 } 2129 2130 static int wpa_supplicant_ioctl(struct net_device *dev, struct iw_point *p) 2131 { 2132 struct ieee_param *param; 2133 int ret = 0; 2134 struct _adapter *padapter = netdev_priv(dev); 2135 2136 if (p->length < sizeof(struct ieee_param) || !p->pointer) 2137 return -EINVAL; 2138 param = memdup_user(p->pointer, p->length); 2139 if (IS_ERR(param)) 2140 return PTR_ERR(param); 2141 switch (param->cmd) { 2142 case IEEE_CMD_SET_WPA_PARAM: 2143 ret = wpa_set_param(dev, param->u.wpa_param.name, 2144 param->u.wpa_param.value); 2145 break; 2146 case IEEE_CMD_SET_WPA_IE: 2147 ret = r871x_set_wpa_ie(padapter, (char *)param->u.wpa_ie.data, 2148 (u16)param->u.wpa_ie.len); 2149 break; 2150 case IEEE_CMD_SET_ENCRYPTION: 2151 ret = wpa_set_encryption(dev, param, p->length); 2152 break; 2153 case IEEE_CMD_MLME: 2154 ret = wpa_mlme(dev, param->u.mlme.command, 2155 param->u.mlme.reason_code); 2156 break; 2157 default: 2158 ret = -EOPNOTSUPP; 2159 break; 2160 } 2161 if (ret == 0 && copy_to_user(p->pointer, param, p->length)) 2162 ret = -EFAULT; 2163 kfree(param); 2164 return ret; 2165 } 2166 2167 /* based on "driver_ipw" and for hostapd */ 2168 int r871x_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) 2169 { 2170 struct iwreq *wrq = (struct iwreq *)rq; 2171 2172 switch (cmd) { 2173 case RTL_IOCTL_WPA_SUPPLICANT: 2174 return wpa_supplicant_ioctl(dev, &wrq->u.data); 2175 default: 2176 return -EOPNOTSUPP; 2177 } 2178 return 0; 2179 } 2180 2181 static iw_handler r8711_handlers[] = { 2182 NULL, /* SIOCSIWCOMMIT */ 2183 r8711_wx_get_name, /* SIOCGIWNAME */ 2184 dummy, /* SIOCSIWNWID */ 2185 dummy, /* SIOCGIWNWID */ 2186 r8711_wx_set_freq, /* SIOCSIWFREQ */ 2187 r8711_wx_get_freq, /* SIOCGIWFREQ */ 2188 r8711_wx_set_mode, /* SIOCSIWMODE */ 2189 r8711_wx_get_mode, /* SIOCGIWMODE */ 2190 dummy, /* SIOCSIWSENS */ 2191 r8711_wx_get_sens, /* SIOCGIWSENS */ 2192 NULL, /* SIOCSIWRANGE */ 2193 r8711_wx_get_range, /* SIOCGIWRANGE */ 2194 r871x_wx_set_priv, /* SIOCSIWPRIV */ 2195 NULL, /* SIOCGIWPRIV */ 2196 NULL, /* SIOCSIWSTATS */ 2197 NULL, /* SIOCGIWSTATS */ 2198 dummy, /* SIOCSIWSPY */ 2199 dummy, /* SIOCGIWSPY */ 2200 NULL, /* SIOCGIWTHRSPY */ 2201 NULL, /* SIOCWIWTHRSPY */ 2202 r8711_wx_set_wap, /* SIOCSIWAP */ 2203 r8711_wx_get_wap, /* SIOCGIWAP */ 2204 r871x_wx_set_mlme, /* request MLME operation; 2205 * uses struct iw_mlme 2206 */ 2207 dummy, /* SIOCGIWAPLIST -- deprecated */ 2208 r8711_wx_set_scan, /* SIOCSIWSCAN */ 2209 r8711_wx_get_scan, /* SIOCGIWSCAN */ 2210 r8711_wx_set_essid, /* SIOCSIWESSID */ 2211 r8711_wx_get_essid, /* SIOCGIWESSID */ 2212 dummy, /* SIOCSIWNICKN */ 2213 r871x_wx_get_nick, /* SIOCGIWNICKN */ 2214 NULL, /* -- hole -- */ 2215 NULL, /* -- hole -- */ 2216 r8711_wx_set_rate, /* SIOCSIWRATE */ 2217 r8711_wx_get_rate, /* SIOCGIWRATE */ 2218 dummy, /* SIOCSIWRTS */ 2219 r8711_wx_get_rts, /* SIOCGIWRTS */ 2220 r8711_wx_set_frag, /* SIOCSIWFRAG */ 2221 r8711_wx_get_frag, /* SIOCGIWFRAG */ 2222 dummy, /* SIOCSIWTXPOW */ 2223 dummy, /* SIOCGIWTXPOW */ 2224 dummy, /* SIOCSIWRETRY */ 2225 r8711_wx_get_retry, /* SIOCGIWRETRY */ 2226 r8711_wx_set_enc, /* SIOCSIWENCODE */ 2227 r8711_wx_get_enc, /* SIOCGIWENCODE */ 2228 dummy, /* SIOCSIWPOWER */ 2229 r8711_wx_get_power, /* SIOCGIWPOWER */ 2230 NULL, /*---hole---*/ 2231 NULL, /*---hole---*/ 2232 r871x_wx_set_gen_ie, /* SIOCSIWGENIE */ 2233 NULL, /* SIOCGIWGENIE */ 2234 r871x_wx_set_auth, /* SIOCSIWAUTH */ 2235 NULL, /* SIOCGIWAUTH */ 2236 r871x_wx_set_enc_ext, /* SIOCSIWENCODEEXT */ 2237 NULL, /* SIOCGIWENCODEEXT */ 2238 r871x_wx_set_pmkid, /* SIOCSIWPMKSA */ 2239 NULL, /*---hole---*/ 2240 }; 2241 2242 static const struct iw_priv_args r8711_private_args[] = { 2243 { 2244 SIOCIWFIRSTPRIV + 0x0, 2245 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "read32" 2246 }, 2247 { 2248 SIOCIWFIRSTPRIV + 0x1, 2249 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "write32" 2250 }, 2251 { 2252 SIOCIWFIRSTPRIV + 0x2, 0, 0, "driver_ext" 2253 }, 2254 { 2255 SIOCIWFIRSTPRIV + 0x3, 0, 0, "mp_ioctl" 2256 }, 2257 { 2258 SIOCIWFIRSTPRIV + 0x4, 2259 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "apinfo" 2260 }, 2261 { 2262 SIOCIWFIRSTPRIV + 0x5, 2263 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setpid" 2264 }, 2265 { 2266 SIOCIWFIRSTPRIV + 0x6, 2267 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wps_start" 2268 }, 2269 { 2270 SIOCIWFIRSTPRIV + 0x7, 2271 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "chplan" 2272 } 2273 }; 2274 2275 static iw_handler r8711_private_handler[] = { 2276 r8711_wx_read32, 2277 r8711_wx_write32, 2278 r8711_drvext_hdl, 2279 r871x_mp_ioctl_hdl, 2280 r871x_get_ap_info, /*for MM DTV platform*/ 2281 r871x_set_pid, 2282 r871x_wps_start, 2283 r871x_set_chplan 2284 }; 2285 2286 static struct iw_statistics *r871x_get_wireless_stats(struct net_device *dev) 2287 { 2288 struct _adapter *padapter = netdev_priv(dev); 2289 struct iw_statistics *piwstats = &padapter->iwstats; 2290 int tmp_level = 0; 2291 int tmp_qual = 0; 2292 int tmp_noise = 0; 2293 2294 if (check_fwstate(&padapter->mlmepriv, _FW_LINKED) != true) { 2295 piwstats->qual.qual = 0; 2296 piwstats->qual.level = 0; 2297 piwstats->qual.noise = 0; 2298 } else { 2299 /* show percentage, we need transfer dbm to original value. */ 2300 tmp_level = padapter->recvpriv.fw_rssi; 2301 tmp_qual = padapter->recvpriv.signal; 2302 tmp_noise = padapter->recvpriv.noise; 2303 piwstats->qual.level = tmp_level; 2304 piwstats->qual.qual = tmp_qual; 2305 piwstats->qual.noise = tmp_noise; 2306 } 2307 piwstats->qual.updated = IW_QUAL_ALL_UPDATED; 2308 return &padapter->iwstats; 2309 } 2310 2311 struct iw_handler_def r871x_handlers_def = { 2312 .standard = r8711_handlers, 2313 .num_standard = ARRAY_SIZE(r8711_handlers), 2314 .private = r8711_private_handler, 2315 .private_args = (struct iw_priv_args *)r8711_private_args, 2316 .num_private = ARRAY_SIZE(r8711_private_handler), 2317 .num_private_args = sizeof(r8711_private_args) / 2318 sizeof(struct iw_priv_args), 2319 .get_wireless_stats = r871x_get_wireless_stats 2320 }; 2321