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