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